Feature Request

Component tokens, with option to "resolve" to semantic tokens at build time
Motivation 1: we want our design team to be able to push styling changes at a component attribute level directly from Figma to our UI library, without developer intervention. Motivation 2: we want to white-label our UI library for various clients. Current limitations: we can define semantic tokens for each component attribute: e.g. _button.color.border.primary . This token would link to a "real" semantic token like color.interactive.border or similar. In both of the scenarios above, the primary button border might need to point at a different semantic token at some point, either when switching to a different brand or in a future redesign. Defining tokens in this way is fine until we roll out the same concept to all the UI library components. We may end up with many thousand semantic tokens, each of which is included in the production runtime and static CSS. The many-to-one relationship results in a lot of duplication. We would like to be able to define component tokens so that they can be resolved to the linked semantic tokens at build time so that they are not included in the shipped code. For more detail please see the Discord discussion: https://discord.com/channels/1118988919804010566/1202629680273031230 Workaround: for now we have worked with our design team to implement real semantic tokens wherever possible and only use "component" tokens in highly unique components, and live with a little more developer intervention where we need to subdivide semantic tokens for better control.
0
Option to "shift-left" component styles to component level tokens
There is a very strong case to have component level tokens, the biggest reason we have found is it allows you to build more robust components when it comes to theming. With this feature we could have a bit more looser with base and semantic level tokens while the component level tokens are much stricter. There are a couple use cases but I find the most compelling is if your semantics slightly change from theme to theme. For example, using the component Alert from Chakra-UI. The original design calls for background color to tie back to their semantic versions, success = green, critical/error = red, info = blue, and warning = yellow. In another world or another brand, the design decisions may call for the background colors all to be the same. In the current implementation of Panda that would require us to add complexity to the recipe or styling to know which theme is loaded which then in turn decreases the flexibility and increases the maintenance time any time a new theme or brand is introduced. Ideally what this looks like today is in plain CSS: /* base.css */ :root { --color-bg-success: #c6f6d5; --color-bg-neutral: #e2e8f0; --Alert-color-bg-success: var(--colors-bg-success); } /* Brand-2.css */ :root { --Alert-color-bg-success: var(--color-bg-neutral); } /* no matter the brand, Alert doesn't care */ .Alert { background-color: var(--Alert-color-bg-success); } ## Today's solution The only way I can think of achieving this type of approach with Panda today is the following, however, I will not this feels a bit anti-pattern to Panda's recommendations today: const theme = { tokens: { colors: { green: { 200: { value: "#9AE6B4" }, }, gray: { 200: { value: "#E2E8F0" }, }, }, }, semanticTokens: { colors: { bg: { success: { value: { base: "{colors.green.200}", }, }, neutral: { value: { base: "{colors.gray.200}", }, }, }, Alert: { success: { bg: { base: "{colors.bg.success}", }, }, }, }, }, themes: { brand2: { semanticTokens: { colors: { Alert: { success: { bg: { base: "{colors.bg.neutral}", }, }, }, }, }, }, }, }; const alert = defineRecipe({ variants: { state: { success: { backgroundColor: "{colors.Alert.bg.success}", }, }, }, }); ## A proposed solution I'm honestly not sure what the correct API might look like but based on established conventions, something might look like the following syntax const theme = { tokens: { colors: { green: { 200: { value: "#9AE6B4" }, }, gray: { 200: { value: "#E2E8F0" }, }, }, }, semanticTokens: { colors: { bg: { success: { value: { base: "{colors.green.200}", }, }, neutral: { value: { base: "{colors.gray.200}", }, }, }, }, }, componentTokens: { Alert: { colors: { success: { bg: { base: "{colors.bg.success}", }, }, }, }, }, themes: { brand2: { componentTokens: { Alert: { colors: { success: { bg: { base: "{colors.bg.neutral}", }, }, }, }, }, }, }, }; const alert = defineRecipe({ variants: { state: { success: { backgroundColor: "{colors.Alert.bg.success}", }, }, }, });
1
Load More