Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

refactor: use component classes for component #437

Open
elevatebart opened this issue May 3, 2024 · 0 comments
Open

refactor: use component classes for component #437

elevatebart opened this issue May 3, 2024 · 0 comments
Labels
enhancement New feature or request

Comments

@elevatebart
Copy link
Collaborator

elevatebart commented May 3, 2024

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?

  1. replace all build process for constants with rollup
  2. add a plugin to generate the plugin from the code
    1. Look for all exports ending in ...classes using acorn
    2. If they contain a string, use that string
    3. If they contain an object redo the same process with each of the member
    4. Once all classes gathered, generate the code
  3. make a plugin to replace the classes in the generated bundle after TypeScript transpilation.
    1. Look for all exports ending in ...classes using acorn
    2. if they contain a string generate the class name and replace
    3. if contain an object, redo the work for each member
@elevatebart elevatebart added the enhancement New feature or request label May 3, 2024
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
enhancement New feature or request
Projects
None yet
Development

When branches are created from issues, their pull requests are automatically linked.

1 participant