Guides
Contribution
As we’re in a ramp up phase of our design system we want to clarify how contributions work for now.
I found a bug 🐞
If you’ve found a bug and the fix is small and contained, go ahead and open a PR. These are usually quick to review and merge, and they help us move fast together.
If you’ve found a bug but aren’t sure what the right fix is, or you don’t have capacity to work on it yourself, please open a GitHub issue instead. A rough write-up is totally fine — we’ll pick it up from there.
I want to request a new component or pattern
Please open a GitHub issue to request it. Tracking needs as issues helps us:
- spot recurring themes
- identify priorities
- keep context and decisions in one place over time
Bigger changes like new components or patterns need:
- alignment with system standards
- accessibility review
- design review
- API and long-term maintenance consideration
- coordination across teams
Supporting this level of work requires more hands-on involvement than we can realistically offer right now. In many cases, it’s more effective for us to own and build these changes ourselves, with input from you along the way — so an issue is the best place to start the conversation.
I want to make a small improvement
Because we’re currently a small team, we’re happily accepting small, contained PRs — for example:
- documentation
- small visual or a11y improvements
- adding an icon
- adding an illustration
These are usually quick to review and merge.
I want to add an icon
-
Obtain the icon file in SVG format from your designer.
-
Place the SVG in the
icons_rawdirectory. Use kebab-case for SVG filenames.If the icon represents a toggleable or secondary state (e.g. locked/unlocked, filled/unfilled), add both versions. Use
-altin the filename to indicate the alternate or toggled version — e.g.bookmark.svgandbookmark-alt.svg. -
Run
pnpm generate:iconsto process the raw SVG and generate the Icon component.index.tsxandiconList.tsxinsrc/iconswill also be updated. -
Start Astro locally to preview the new icon.
Confirm that the icon appears and looks as expected. If needed, you can fine-tune the generated icon component directly in
src/icons. -
Add search keywords for the icon (recommended).
The icon gallery search is powered by
apps/astro/src/components/icons/iconTags.ts. Add an entry for your icon with related terms so people can find it by synonym — e.g.bin: ['delete', 'trash', 'remove']. Without it the icon still appears in the gallery, but is only findable by its exact name. -
Run
pnpm changesetto add a changeset — a new icon is a new public export and is user-visible, so it requires one.
I want to add an illustration
-
Obtain the illustration file in SVG format from your designer.
-
Place the SVG in the
illustrations_rawdirectory. Use kebab-case for the filename. -
Run
pnpm generate:illustrationsto process the raw SVG and generate the illustration component.index.tsxandillustrationList.tsxinsrc/illustrationswill also be updated. If the SVG uses a color outside the blue scale, the generator throws and tells you which value and element to fix. -
Start Astro locally to preview the new illustration at
/media/illustrations.Confirm it looks correct in both the primary and neutral tone (you can override the SVG width/height props to spot-check different sizes).
-
Add search keywords for the illustration (recommended).
The illustration gallery search is powered by
apps/astro/src/components/illustrations/illustrationTags.ts. Add an entry with related terms so people can find it by synonym. -
Run
pnpm changesetto add a changeset — a new illustration is a new public export and is user-visible, so it requires one.
I want to change tokens
Token layers
Token sources live in four JSON files under packages/design/tokens/:
primitive.json— raw values (colors, font sizes, radii, shadows). These are the lowest-level building blocks. You’ll rarely edit these unless adding a new color scale or adjusting a base value.semantic.json— reference primitive tokens. Contextual aliases that adapt to theming.component.json— per-component overrides for when semantic tokens aren’t specific enough (e.g.badge.text.color.critical). Only add here if a component needs a value that doesn’t map cleanly to an existing semantic token.typography-presets.json— composite typography tokens that bundlefontSize,lineHeight, andfontWeightinto named presets (e.g.body.lg,title.md,label.sm).
All JSON files use the DTCG (Design Tokens Community Group) format:
primitive.json
"blue": {
"500": {
"$value": "oklch(0.6388 0.1952 257.61)"
}
}semantic.json
"text": {
"color": {
"primary": {
"$value": "{color.blue.500}"
}
}
}How it works
Running pnpm --filter @staffbase/design generate:tokens executes two scripts in sequence:
tokens/sd.config.ts— runs Style Dictionary to convert the JSON tokens into CSS variables (one CSS file per layer).scripts/generateTheme.ts— generates a Tailwind v4 theme file (@theme inline) that bridges--sb-*custom properties to Tailwind utility namespaces. It also maps typography presets into Tailwind’s--text-*namespace.
This produces the following generated files (do not edit these directly):
src/foundation/tokens/primitive.csssrc/foundation/tokens/semantic.csssrc/foundation/tokens/component.csssrc/foundation/theme.css
Workflow
-
Edit the appropriate JSON source file in
packages/design/tokens/. -
Run
pnpm --filter @staffbase/design generate:tokensto regenerate the CSS output. -
Start the docs
pnpm dev:astrolocally to verify affected components still look correct. -
Run
pnpm changesetto add a changeset — token changes are always user-visible and require one.