Skip to content

Instantly share code, notes, and snippets.

@mutewinter
Last active September 11, 2022 17:56
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save mutewinter/c43836db5cf60070052caf1880570492 to your computer and use it in GitHub Desktop.
Save mutewinter/c43836db5cf60070052caf1880570492 to your computer and use it in GitHub Desktop.
Utility to help generate image sizes for the Next Image component when using Tailwind via Twin.macro
import { theme } from 'twin.macro';
function minMediaCondition(minWidth: string, width: string) {
return `(min-width: ${minWidth}) ${width}`;
}
type Screens = 'sm' | 'md' | 'lg';
// We only do sizes in terms of view width
type SizeWithScreen<T extends Screens> = [screen: T, width: `${string}vw`];
type SizeWithoutScreen = string;
// Ensure sizes grow from smallest to largest
export type ImageSizes =
| [SizeWithoutScreen]
| [
SizeWithoutScreen,
SizeWithScreen<'sm'> | SizeWithScreen<'md'> | SizeWithScreen<'lg'>,
]
| [SizeWithoutScreen, SizeWithScreen<'sm'>, SizeWithScreen<'md'>]
| [SizeWithoutScreen, SizeWithScreen<'sm'>, SizeWithScreen<'lg'>]
| [SizeWithoutScreen, SizeWithScreen<'md'>, SizeWithScreen<'lg'>]
| [
SizeWithoutScreen,
SizeWithScreen<'sm'>,
SizeWithScreen<'md'>,
SizeWithScreen<'lg'>,
];
// Usage:
// imageSizes(['40vw', ['sm', '50vw'], ['md', '30vw'], ['lg', '20vw']]);
export default function imageSizes(sizes: ImageSizes) {
const sizeArray: string[] = [];
const [firstSize, ...restOfSizes] = sizes;
// We must reverse the sizes to ensure they flow from largest breakpoint to
// smallest
// eslint-disable-next-line no-restricted-syntax
for (const [screen, width] of restOfSizes.reverse()) {
switch (screen) {
case 'sm':
sizeArray.push(minMediaCondition(theme`screens.sm`, width));
break;
case 'md':
sizeArray.push(minMediaCondition(theme`screens.md`, width));
break;
case 'lg':
sizeArray.push(minMediaCondition(theme`screens.lg`, width));
break;
default:
throw new Error(`Missing screen: ${screen as unknown as string}`);
}
}
sizeArray.push(firstSize);
return sizeArray.join(', ');
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment