refactor: use component classes for component
Closed this issue · 0 comments
elevatebart commented
Description
The current CSS model using tailwind poses two issues:
- When components are server side rendered, their html is made heavy by the amount of repeated classes there is. The weight of the page augments exponentially when adding new properties.
- Overriding a property for one component (margin, size, white-space, ...) often requires the use of
!
to bypass priorities. This does not leave room for later re-override when hacking.
We could solve both those issues by using classes placed in the @components
layer of tailwind. The best automated way I could see to do that without changing our dev process would be to generate a tailwind plugin in each constants
package along with the current bundle. This plugin would register the current classes as component classes like this:
// written code
export const alertSizesClasses = {
xs: 'py-[4px] px-[8px] leading-[22px] text-[14px]',
sm: 'py-[8px] px-[12px] leading-[22px] text-[14px]',
md: 'py-[12px] px-[16px] leading-[24px] text-[16px]',
lg: 'p-[16px] leading-[24px] text-[16px]',
} as const
// compiled code
export const alertSizesClasses = {
xs: "cy-ds-alert-alertSizes-xs",
sm: "cy-ds-alert-alertSizes-sm",
md: "cy-ds-alert-alertSizes-md",
lg: "cy-ds-alert-alertSizes-lg",
}
// tailwind plugin
export default function plugin({ addComponents }) {
addComponents({
".cy-ds-alert-alertSizes-xs": {
"@apply py-[4px] px-[8px] leading-[22px] text-[14px]" : {},
},
".cy-ds-alert-alertSizes-sm": {
"@apply py-[8px] px-[12px] leading-[22px] text-[14px]": {},
},
".cy-ds-alert-alertSizes-md": {
"@apply py-[12px] px-[16px] leading-[24px] text-[16px]": {},
},
".cy-ds-alert-alertSizes-lg": {
"@apply p-[16px] leading-[24px] text-[16px]": {},
},
})
}
How do we do it?
- replace all build process for constants with rollup
- add a plugin to generate the plugin from the code
- Look for all exports ending in
...classes
using acorn - If they contain a string, use that string
- If they contain an object redo the same process with each of the member
- Once all classes gathered, generate the code
- Look for all exports ending in
- make a plugin to replace the classes in the generated bundle after TypeScript transpilation.
- Look for all exports ending in
...classes
using acorn - if they contain a string generate the class name and replace
- if contain an object, redo the work for each member
- Look for all exports ending in