Using Tokens
There are various ways to consume Bamboo tokens depending on your need at that point in time.
Learn the various ways to consume Bamboo tokens in your project.
Style Properties
The recommended way to consume your tokens is in the css function.
import { css } from '../styled-system/css'
const App = () => (
<div
className={css({
color: 'green.400',
background: 'gray.200',
})}
/>
)
Composite values
Some CSS properties like border, box-shadow allow you to specify multiple properties in its value. Reference a token
inside one with token(path.to.token) ā the same spelling used for semantic token values.
import { css } from '../styled-system/css'
const className = css({ border: '1px solid token(colors.red.400)' })
You can also use it in media queries or any other CSS at-rule.
import { css } from '../styled-system/css'
const className = css({
'@media screen and (min-width: token(sizes.4xl))': {
color: 'green.400',
},
})
Earlier versions also accepted a curly form, {'{colors.red.400}'}, which meant exactly the same thing. It has been
removed so there is one way to write a reference, and so was the second fallback argument. Both are errors rather
than silent fallbacks: a retired reference in a token value fails the build naming the token and its replacement, and
one in a style value throws where it is used. A value that may not name a token is resolved where that can be answered
ā PatternHelpers.token(path, fallback) inside a pattern ā rather than deferred into a string.
Vanilla JS
Use the generated token function to query design tokens in your project. This is useful if you need direct access to
your design tokens in the style attribute or when using CSS-in-JS libraries like styled-components or
@emotion/styled
This approach is useful for incrementally adopting Bamboo in existing projects or dynamic styling
Style Attribute
src/App.tsx
import { token } from '../styled-system/tokens'
function App() {
return (
<div
style={{
background: token('colors.blue.200'),
}}
/>
)
}Each of your design tokens will be available in the generated /tokens folder. It looks like this:
styled-system/tokens/index.mjs
const tokens = {
// ...
'colors.blue.200': {
value: '#bfdbfe',
variable: 'var(--colors-blue-200)',
},
// ...
}- The
token()function returns the CSS custom property that references the token ā the same for every token. - The
token.value()function returns the resolved raw value.
Both are typesafe and expect a known dot-separated token path. Neither takes a fallback argument: a path that names no
token returns undefined, so token('colors.brand') ?? '#fff' supplies one in the language.
Using the example above, token('colors.blue.200') returns var(--colors-blue-200) and
token.value('colors.blue.200') returns #bfdbfe.
Which one to reach for
Prefer token(). A variable reference keeps responding to whatever the cascade decides, so a value read through it
still changes when the theme does.
Reach for token.value() only where a CSS variable cannot be resolved ā a <canvas> fill, a charting library, or a
<meta name="theme-color"> tag. It is a snapshot: it stops tracking the theme.
It also only accepts a token that has a literal. A conditional token has no single value to snapshot, a virtual one
none of its own, and a negative one resolves to a calc() over its counterpart ā so token.value('colors.primary') is
a type error rather than a variable reference handed to a canvas that cannot resolve it. Those are what token() is
for.
Before Bamboo 2, token() returned the raw value for a plain token and the variable reference for a conditional one ā
so which kind you got was decided by the theme rather than by the call, and adding a _dark variant to a token
silently changed what every caller received. token() now always returns the reference. If you were relying on the
literal, rename those calls to token.value(). token.var() and the second fallback argument are both gone ā
token() is the reference, and ?? fallback is the fallback.
The extractor follows a path built from a constant or a template literal, so token(KEY) is seen by the reachability
analysis behind prune.tokens as well as a path spelled out at the call. A template
with a substitution is bounded rather than lost: token(`colors.${shade}`) keeps the colors category, because that
is what its static head can reach.
A path with no static head ā token(key), token('colors.' + shade) ā is the one the build cannot follow. Name the
category those land in with prune.keepTokens, or set
prune: { tokens: false }.
Styled Components
import styled from 'styled-components'
const Button = styled.button`
background: ${token('colors.blue.200')};
`
Emotion
import styled from '@emotion/styled'
const Button = styled.button`
background: ${token('colors.blue.200')};
`