Document full .json for Components for more precise style overriding
Is your feature request related to a problem? Please describe. I spent many hours trying to figure out how to build upon the styling for Components I saw in the documentation. For example, https://theme-ui.com/components/radio . It was non-trivial to replicate what I saw on the docs site.
Describe the solution you'd like Point to a .json object that will result in the same style shown in the docs. Extending on the radio example,
Describe alternatives you've considered In the "base" theme, replicate the exact .json object(s) that will result in what I see on the website, so that I can build off of what is there. Another alternative explored below.
Additional context I recognize that through theme-ui, I'm free to define whatever styles I want from scratch. Actually, I liked what I saw on the docs, but just wanted to change some colors. I tried to do so, but got ugly results because I didn't have the structure just right.
In other words, a naive developer (me) thought that this should be enough
radio: {
color: 'green',
bg: 'transparent'
}
But in reality, we needed to do something like this (which took me a frustratingly long time to find):
radio: {
color: 'green',
bg: 'transparent',
border: 'thin',
borderRadius: 'circle',
...{
'input:focus ~ &': {
bg: 'transparent',
border: 'thick',
},
'> path': {
fill: 'primary',
},
'input:checked ~ &': {
'> path': {
fill: 'primary',
},
},
},
}
Much time could have been saved, had the above .json object been provided in the docs, so devs have a clearer idea of what the starting point actually is.
Another alternative is if I could have done this, that would also have been helpful. Is there a way to do this?
radio: {
...themeUI.base.theme.forms.radio,
color: 'green',
bg: 'transparent'
}
I spent many hours trying to figure out how to build upon the styling for Components I saw in the documentation. For example, https://theme-ui.com/components/radio . It was non-trivial to replicate what I saw on the docs site.
I do agree that the docs should link to source code, but I'm a bit unsure if I understand you correctly.
I wouldn't call these component examples. These components are published as @theme-ui/components and reexported from theme-ui. You are importing the Radio and styling it through "radio" variant, right?
Yes, I am
@jayliu50
I'm also not sure I understand your use case, but you shouldn't need a hack like this.
Make sure that radio is nested in forms like so forms.radio. That way, your styling will be merged with the base for the components.
If you are talking about making it easier to style some components, in most cases playing around with the predefined keys (primary, highlight, ...) should suffice. If you need something more custom, there is no real getting around replicating the variant structure.
It should look like this:
Note that I have removed your object spread. All keys are different, so there is no need for it.
radio: {
color: 'green',
bg: 'transparent',
border: 'thin',
borderRadius: 'circle',
'input:focus ~ &': {
bg: 'transparent',
border: 'thick',
},
'> path': {
fill: 'primary',
},
'input:checked ~ &': {
'> path': {
fill: 'primary',
},
},
}
For custom components with complex structures, I like to use CSS variables. That way it becomes easier to style when merging if the theme is used as a base for other projects
customComponent: {
'--color': 'var(--theme-ui-colors-text)',
'--bg': 'var(--theme-ui-colors-primary)',
color: 'var(--color)'
'::after': {
content: '""',
bg: 'var(--bg)',
// ...
}
}
When merged, becomes:
customComponent: {
'--color': 'var(--theme-ui-colors-primary)',
'--bg': 'var(--theme-ui-colors-secondary)',
}
Hope this helps 👋