Custom theme keys with typescript #145
Replies: 6 comments 1 reply
-
You should be writing the theme directly inside of makeTheme, rather than as a separate variable. that said, I don’t know if this is valid. I think you have to use the keys provided by the theme |
Beta Was this translation helpful? Give feedback.
-
Got it. Do you have recommendations on how you would handle variants for a Button component for example like primary, secondary, etc.? |
Beta Was this translation helpful? Give feedback.
-
I've been thinking about this in general: is Dripsy theming enough to be the backbone of a scalable design system? For example, take a card: const theme = {
cards: {
container: { bg: '$muted' },
content: { p: '$3', borderRadius: '$3' }
}
}
const Card = styled(View, { themeKey: 'cards' })({ variant: 'container' })
Card.Content = styled(View, { themeKey: 'cards' })({ variant: 'content' })
<Card>
<Card.Content></Card.Content>
</Card> I think that works pretty well. The issue is, Dripsy's variant system follows the theme-ui spec, which is a bit static. They want your theme represented as a JSON file. This has its benefits: what you see is what you get. But there are, of course, some limitations. From the outside, I think the Stitches approach to variants is better: you can have many variant options, such as A key example is a Say your color scheme looks like this: const theme = {
colors: {
primary: mauve.mauve9,
primaryText: mauve.mauve12,
secondary: crimson.crimson9,
secondaryText: crimson.crimson12
}
} Here we have a So, how do we compose a button from this color scheme, such that the label uses the A few options:
type Color = Theme['colors']
type Props = { color: Color }
const Button = styled(View)(({ color }: Props) => ({ bg: `${color}` }))
Button.Label = styled(Text)(({ color }: Props) => ({ color: `${color}Text` }))
<Button>
<Button.Label>Text here</Button.Label>
</Button> And, perhaps you'd wrap your button to pass the However, for a theme-based style system, I'm not sure if this is the optimal solution. Perhaps it is. But I wonder, could this logic, for such a reused component that literally every app needs, live in a theme instead? After all, every React Native button needs a container and a label. In the spirit of a theme-centric design system, I wonder if something more like this could work. It’s similar to the Card, except that it allows props to be passed to the theme… const theme = {
buttons: {
container: ({ color }: Props) => ({ color: `${color}Background` })
},
text: {
buttonLabel: ({ color }: Props) => ({ color: `${color}Text` })
}
}
type Color = Theme['colors']
type Props = { color: Color }
const Button = styled(View, { themeKey: 'buttons' })({ variant: 'container' })
Button.Label = styled(Text, { themeKey: 'text' })({ variant: 'buttonLabel' })
<Button color="primary">
<Button.Label color="primary"></Button.Label>
</Button> This would be more inspired by the Stitches variants option in Notice here that The difference with stitches being, you define these styles in theme, so you can port them from project to project easily. Now, I'm not sure if that's the best thing to optimize around or not. But maybe it is. I'm thinking out loud a bit here. I mentioned this idea to @axeldelafosse a bit back. I'll keep playing with it... |
Beta Was this translation helpful? Give feedback.
-
Yeah, this all makes sense to me. I'm running into this now more than ever because I'm finding it hard to make a component library on top of dripsy that's as extensible as possible. I'm a huge fan of the stitches approach. I definitely think if there's a way to incorporate something similar into a theme-based approach that would be ideal for my use case. |
Beta Was this translation helpful? Give feedback.
-
I'll give it some thought. Maybe I should convert this from an issue to a discussion? |
Beta Was this translation helpful? Give feedback.
-
@nandorojo did you have any more thoughts on the above? I'm attempting to implement a button as you describe in the first option, but it feels quite convoluted and brittle - would be very grateful if you could point me in the right direction! here's my implementation:
it works fine as is but to e.g. include disabled functionality or size or further composable variants it seems like it could get quite messy |
Beta Was this translation helpful? Give feedback.
-
Are custom theme keys currently supported with typescript?
Using the following code:
I get the error
{ Collapse: {} }
has no property in common w/ the theme.I thought I had it working in a separate project. Could the error be because of where I'm creating my custom components?
Beta Was this translation helpful? Give feedback.
All reactions