Shared/NewsThumb
All Variants
Default
Detail
Grid
List
Single Digit
Triple Digit
news-thumb.tsx
import type { FunctionComponent } from 'preact';
interface NewsThumbProps {
volume: number;
type: 'grid' | 'list' | 'detail';
}
/**
* NewsThumb component for newsletter article thumbnails
* Displays a stylized "NEWS {volume}" thumbnail with diagonal lines
*/
export const NewsThumb: FunctionComponent<NewsThumbProps> = ({ volume, type }) => {
// Base styles for all variants
const baseStyles =
'relative overflow-hidden bg-zd-literal-black text-zd-literal-white flex flex-col items-center justify-center w-full aspect-square';
// Type-specific text sizes - volume number DOMINATES 80-90% of space
const textSizes = {
grid: {
news: 'text-[1rem] xl:text-[1.3rem] 2xl:text-[1.8rem]',
volume: 'text-[3rem] md:text-[2rem] lg:text-[4.5rem] xl:text-[6rem]',
},
list: {
news: 'text-[0.6rem] md:text-[1rem]',
volume: 'text-[2rem] md:text-[3rem]',
},
detail: {
news: 'text-[3rem]',
volume: 'text-[5rem] sm:text-[10rem] md:text-[13rem] lg:text-[8rem] xl:text-[14rem]',
},
};
const sizes = textSizes[type];
return (
<div className={baseStyles}>
<div className={'absolute inset-0 border-[2px] border-zd-white'} />
{/* inside text bg */}
<div
className={
'absolute top-[20%] bottom-[20%] right-[10%] left-[10%] select-none z-10 bg-zd-literal-black'
}
/>
{/* news + volume */}
<div className={'select-none z-20 text-center'}>
<div
className={`${sizes.news} tracking-[0.2rem] font-normal uppercase pl-[.6rem] pb-[.1rem]`}
>
News
</div>
<div className={`${sizes.volume} font-medium leading-none pb-[.6rem]`}>{volume}</div>
</div>
{/* Bold diagonal line 1 (top-left to bottom-right) */}
<div className={'absolute top-0 left-0 w-[141%] transform rotate-45 origin-top-left'}>
<div className={'w-full h-0 border-t-[2px] border-zd-white mt-[-1px]'} />
</div>
{/* Bold diagonal line 2 (top-right to bottom-left) */}
<div className={'absolute top-0 right-0 w-[141%] transform -rotate-45 origin-top-right'}>
<div className={'w-full h-0 border-t-[2px] border-zd-white mt-[-1px]'} />
</div>
</div>
);
};
news-thumb.stories.tsx
import { NewsThumb } from './news-thumb';
import type { ControlsMap } from '../../sub-packages/styleguide-v2/src/data/control-types';
/**
* NewsThumb Component
*
* Stylized thumbnail for newsletter articles displaying
* "NEWS" with a volume number and diagonal line decorations.
*
* Features:
* - Three size variants: grid, list, detail
* - Bold diagonal lines for visual interest
* - Responsive typography
*/
export const meta = {
title: 'Shared/NewsThumb',
};
export const controls: ControlsMap = {
volume: { type: 'number', default: 42, min: 1, max: 999 },
type: { type: 'select', default: 'grid', options: ['grid', 'list', 'detail'] },
};
/**
* Default - controllable via props panel
*/
export const Default = {
args: { volume: 42, type: 'grid' },
render: ({ volume, type }: { volume: number; type: 'grid' | 'list' | 'detail' }) => (
<div className="w-[200px]">
<NewsThumb volume={volume} type={type} />
</div>
),
};
/**
* Grid variant - used in article grids
*/
export const Grid = () => (
<div className="w-[200px]">
<NewsThumb volume={42} type="grid" />
</div>
);
/**
* List variant - used in article lists
*/
export const List = () => (
<div className="w-[100px]">
<NewsThumb volume={42} type="list" />
</div>
);
/**
* Detail variant - used on article detail pages
*/
export const Detail = () => (
<div className="w-[300px]">
<NewsThumb volume={42} type="detail" />
</div>
);
/**
* Single digit volume
*/
export const SingleDigit = () => (
<div className="w-[200px]">
<NewsThumb volume={5} type="grid" />
</div>
);
/**
* Triple digit volume
*/
export const TripleDigit = () => (
<div className="w-[200px]">
<NewsThumb volume={123} type="grid" />
</div>
);
/**
* All variants side by side
*/
export const AllVariants = () => (
<div className="flex items-end gap-hgap-md">
<div className="w-[100px]">
<p className="text-muted text-xs mb-vgap-xs text-center">List</p>
<NewsThumb volume={42} type="list" />
</div>
<div className="w-[200px]">
<p className="text-muted text-xs mb-vgap-xs text-center">Grid</p>
<NewsThumb volume={42} type="grid" />
</div>
<div className="w-[300px]">
<p className="text-muted text-xs mb-vgap-xs text-center">Detail</p>
<NewsThumb volume={42} type="detail" />
</div>
</div>
);