Last active
July 5, 2024 04:09
-
-
Save joshdavenport/3e6d7fed02fba0cf47b6f85d4e2faf40 to your computer and use it in GitHub Desktop.
Generate srcset sizes attribute from tailwind screens
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
/* | |
The main method here is processTailwindSrcsetSizes. You can generate a sizes attribute using it based on | |
tailwind style breakpointed sizes referencing your screens, such as: | |
"100vw md:500px" | |
"200px lg:100vw" | |
"200px md:300px xl:600px" | |
"100vw lg:50vw" | |
"100vw" | |
"400px" | |
Your full tailwind config is resolved and screens from it used, so you can use whatever you normally use. | |
Given the default tailwind screens the above becomes | |
"(min-width: 768px) 500px, 100vw" | |
"(min-width: 1024px), 200px" | |
"(min-width: 1280px) 600px, (min-width: 768px) 300px, 200px" | |
"(min-width: 1024px) 50vw, 100vw" | |
"100vw" | |
"400px" | |
I use it in a React component by taking a sizes prop on the component, then passing that value into processTailwindSrcsetSizes | |
then using that as the actual sizes attribute. | |
*/ | |
import resolveConfig from 'tailwindcss/resolveConfig'; | |
// Resolve correctly based on your codebase | |
import tailwindConfig from '@/../tailwind.config.js'; | |
const fullConfig = resolveConfig(tailwindConfig); | |
export function isTailwindScreen( | |
screen: string, | |
): screen is keyof typeof fullConfig.theme.screens { | |
return screen in fullConfig.theme.screens; | |
} | |
export function processTailwindSrcsetSizes(sizes: string) { | |
type TailwindSizesSize = { | |
size: number; | |
width: string; | |
}; | |
const convertedSizes = sizes | |
.split(' ') | |
.map((rule) => { | |
const [screenOrSoleWidth, width] = rule.split(':'); | |
if (screenOrSoleWidth && !width) { | |
return { | |
size: 0, | |
width: screenOrSoleWidth, | |
}; | |
} | |
if ( | |
!screenOrSoleWidth || | |
!width || | |
!isTailwindScreen(screenOrSoleWidth) | |
) { | |
return null; | |
} | |
return { | |
size: parseInt(fullConfig.theme.screens[screenOrSoleWidth]), | |
width: width, | |
}; | |
}) | |
.filter((rule) => rule !== null) as TailwindSizesSize[]; | |
if (!convertedSizes.length) { | |
return null; | |
} | |
return convertedSizes | |
.sort((a, b) => b.size - a.size) | |
.map(({ size, width }) => | |
size === 0 ? width : `(min-width: ${size}px) ${width}`, | |
) | |
.join(', '); | |
} | |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment