The extend keyword
What is and how to to use the extend keyword
The extend keyword allows you to extend the default Bamboo configuration. It is useful when you want to add your own
customizations to Bamboo, without erasing the default presets values (conditions, tokens, utilities, etc).
It will (deeply) merge your customizations with the default ones, instead of replacing them.
The extend keyword allows you to extend the following parts of Bamboo:
- conditions
- theme
- recipes (included in theme)
- patterns
- utilities
- global.css, and the other
global.*keys (vars,fontface,positionTry) —extendsits on each sub-key, not onglobalitself - staticCss
These keys are all allowed in presets.
Example
After running the bamboo init command you should see something similar to this:
import { defineConfig } from '@bamboocss/dev'
export default defineConfig({
// ...
// Useful for theme customization
theme: {
extend: {}, // 👈 it's already there! perfect, now you just need to add your customizations in this object
},
// ...
})
Let's say you want to add a new color to the default theme. You can do it like this:
import { defineConfig } from '@bamboocss/dev'
export default defineConfig({
theme: {
extend: {
colors: {
primary: { value: '#ff0000' },
},
},
},
})
This will add a new color to the default theme, without erasing the other ones.
Now, let's say we want to create new property br that applies a border radius to an element.
import { defineConfig } from '@bamboocss/dev'
export default defineConfig({
utilities: {
extend: {
br: {
className: 'rounded', // css({ br: "sm" }) => rounded-sm
values: 'radii', // connect values to the radii tokens
transform(value) {
return { borderRadius: value }
},
},
},
},
})
What if this utility was coming from a preset (@acme/my-preset) ? You can extend any specific part, as it will be
deeply merged with the existing one:
import { defineConfig } from '@bamboocss/dev'
export default defineConfig({
presets: ['@acme/my-preset'],
utilities: {
extend: {
br: {
className: 'br', // css({ br: "sm" }) => br-sm
},
},
},
})
Removing something from a preset
Destructure away the part you don't want and spread the rest. To drop the br utility from @acme/my-preset:
import { defineConfig } from '@bamboocss/dev'
import myPreset from '@acme/my-preset'
const { br, ...utilities } = myPreset.utilities
export default defineConfig({
presets: ['@acme/my-preset'],
utilities: {
extend: {
...utilities, // 👈 we still want the other utilities from this preset
// your customizations here
},
},
})
The base presets work the same way — here, dropping the float pattern from @bamboocss/preset-base:
import bambooBasePreset from '@bamboocss/preset-base'
// omitting float here
const { float, ...bambooBasePresetPatterns } = bambooBasePreset.patterns
export default defineConfig({
presets: ['@bamboocss/preset-bamboo'], // 👈 we still want the tokens, breakpoints and mixins from this preset
presets: [],
patterns: {
extend: {
...bambooBasePresetPatterns,
// your customizations here
},
},
})
⚠️ presets: [] is required in that second case: with anything else listed, @bamboocss/preset-base is loaded only
if you list it, and it puts float back. See
which presets are included.
Minimal setup
If you want to use Bamboo with the bare minimum, without any of the defaults, you can read more about it here
FAQ
Why is my preset overriding the base one, even after adding it to the array?
You might have forgotten to include the extend keyword in your config. Without extend, your preset will completely
replace the base one, instead of merging with it.