Aller au contenu

Styling

DS folders, tokens, theming, Tailwind + cva for @bricks-common/bo and bricksoffice-* consumers. Keep in sync: changing tokens, theme vars, DS topical folders, the cva convention, or tokens.css / tokens.ts → update this file in the same PR.

Hard rules

  • No hardcoded hex / px. Missing token → add to tokens.css + tokens.ts first, then use it.
  • cva only, never tailwind-variants. See feedback_cva_over_tailwind_variants.
  • Unified radix-ui package (import { Slot } from 'radix-ui'), not per-primitive @radix-ui/react-*.
  • Topical DS folders are mandatory — never dump everything in components/. See feedback_ds_topical_folders.
  • No app-specific DS in consumers. If you'd add it in bricksoffice-projects/src/..., add it to @bricks-common/bo instead.

Topical DS folders

Inside projects/common/back-office/src/design-system/:

Folder What goes here
components/ Primitives the user doesn't enter a value into (button, tabs, dropdown, popover, sheet, tooltip, brand visuals)
inputs/ Value-input controls (input, textarea, select, checkbox, toggle, calendar, command, date-picker, label)
layouts/ Composed shells (sidebar + topical sub-folders like layouts/nav/)
modals/ Dialogs, drawers, alert dialogs
tables/ DataTable building blocks
text-editor/ Rich text (Tiptap/Lexical when added)
forms/ <Form /> wrapper + helpers
styles/ Tokens, theme, global CSS entry

Adding a new component

  1. Pick the right topical folder; if torn, prefer the most specific.
  2. Generate via shadcn from projects/common/back-office: pnpm dlx shadcn@latest add <name>. Move into the right folder.
  3. Use cva + radix-ui unified.
  4. Internal imports via #-aliases (see ./@bricks-common-bo.mdc).
  5. Re-export from the topical barrel + the top-level design-system/index.ts if public.

Disabled affordance

Two patterns, both token-driven:

  • Text fields (Input, Textarea, Select, Checkbox, DatePicker, RichTextEditor): disabled = cursor-not-allowed + bg-(--disabled-bg) + text-(--disabled-text). Dark --disabled-bg is lighter than card — a darker fill would vanish against near-black.
  • Buttons / toggles / tabs / command items / calendar days / sidebar buttons: disabled = opacity-(--disabled-opacity). Don't opacity-fade text fields — they disappear on the dark card.

Tokens: --input-bg, --input-border-val, --disabled-bg, --disabled-opacity in tokens.css. bg-(--var) / text-(--var) / opacity-(--var) are Tailwind v4 arbitrary-property utilities.

Tokens (src/design-system/styles/)

  • Colors: semantic shadcn (--primary, --muted, --destructive, --ring, --sidebar-*) mapped to brand. Light/dark via :root + @custom-variant dark (&:is(.dark *)).
  • Radius: scaled off --radius (sm 0.6× → 4xl 2.6×).
  • Spacing: none / 3xs / 2xs / … / 8xl in tokens.ts. Use p-xl, gap-md, never raw px.
  • Containers: sm 480 / lg 800 / xl 1000 / 2xl 1200.
  • Status badges (--badge-<tone>-bg/fg): saturated in light, pastel-on-tinted in dark. Tones in styles/badges.css@utility status-badge-tone-<tone>. <Badge variant="status"> lets the tone class own colors.
  • Cell highlights (--cell-highlight-<tone>-fg): bg is color-mix(..., transparent), only fg flips per mode. See tables.css.

Topical CSS files in design-system/styles/ are @import'd once from styles.css.

bg-background vs bg-card: in BO theme bg-background is cream #f9f5f1, not white. Use bg-card / bg-popover for white surfaces (Dialog, popover, sheet).

Component stories (dev)

Dev-only DS gallery at @bricks-common/bo/modules/component-stories. One category per page. Author at stories/<category>/<name>.story.tsx, register in registry.ts. Categories: Tokens, Components, Forms, Modals, Layouts. Gate consumer routes on AppConfig.isDevEnv.

Theming

ThemeProvider, useTheme, ThemeToggle in design-system/styles/theme/. Token flow: tokens.cssstyles.css (@theme inline) → Tailwind utilities + cva. Consumer pulls everything via one @import '@bricks-common/bo/styles.css'.

What NOT to do

  • ❌ Modify a shared component spec to fix a local layout issue — fix the consumer. See feedback_no_change_shared_component_specs.
  • bg-background for what should be a white surface — that's cream. Use bg-card / bg-popover.
  • ❌ Opacity-fade a disabled text field — it vanishes on dark.