Closed cmaycumber closed 2 years ago
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
Got it. Do you have recommendations on how you would handle variants for a Button component for example like primary, secondary, etc.?
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 size
, color
, etc.
A key example is a Button
, like @cmaycumber mentioned.
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 primary
and a secondary
. The palette I have in mind comes from Radix Colors.
So, how do we compose a button from this color scheme, such that the label uses the ${color}Text
, and the button uses the ${color}
.
A few options:
styled
API.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 color
prop to all of them together.
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 styled
.
Notice here that buttons.container
takes a function.
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...
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.
I'll give it some thought.
Maybe I should convert this from an issue to a discussion?
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?