A problem, I keep running into with Chakra Ui are "magic strings". Let's look at an example of muted text:
function Example() {
const color = useColorModeValue("gray.400", "gray.200");
return (
<Text color={color} />
)
}
What's the problem with this code: In my app, I want to share the muted color between many components. However, defining it explicitly as a string means that I have to remember that muted text has a value of "gray.400". If I have another component that wants to use muted text, I have to copy the string "gray.400" to all other components. I will end up with lots of strings that make it really hard to change things across the entire app. I explored two solutions so far:
Solution 1 - TextStyles API: Chakra comes with a textStyles
API out of the box but this doesn't work well for more complicated situations (what if I want to have a hover
and active
state with different colors?).
Solution 2 - Create a global object: I've created a hookuseConsistantStyles()
that returns a theme-like object with values, e. g.: {"borderLight": "gray.200"}
. However, this feels like I'm fighting the library.
I'd really love to have a better solution since I keep running into this.
This is probably late but for any new onlookers, since Styled System v1.17.0, chakra ui has semantic tokens. The changelog and docs have some details but the important bit is:
Semantic tokens provide the ability to create css variables which can change with a CSS condition.
CSS conditions would be states like dark mode or hover etc.
In this case, you would define a semantic token like so (with a better token name):
const customTheme = extendTheme({
semanticTokens: {
colors: {
nicelyNamedToken: {
default: 'gray.400',
_dark: 'gray.200',
},
},
},
})
import the theme however you currently do, and then anywhere the theme is present, you should be able to just use the token
function Example() {
return (
<Text color='nicelyNamedToken' />
)
}