Last active
September 11, 2022 17:56
-
-
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
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
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