create-bestax 3.1.4 → 3.2.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -0,0 +1,395 @@
1
+ # Reference: building a component inside the bestax monorepo
2
+
3
+ You are inside the bestax monorepo — import helpers from relative paths
4
+ (`../helpers/classNames`), not from the package. This is the full contributor pipeline for a
5
+ custom "extra" component: React + TS, the Bulma v1 SCSS pattern, stories, tests, docs, and
6
+ wiring. For **form** components (Field/Control/Input/etc.) use the `bestax-form` skill instead.
7
+
8
+ ## File layout
9
+
10
+ Every custom component has five files. Mirror the existing names exactly (PascalCase TSX,
11
+ `_kebab.scss` partial):
12
+
13
+ ```
14
+ bulma-ui/src/components/MyComponent.tsx # React + TS component
15
+ bulma-ui/src/components/MyComponent.stories.tsx # Storybook stories
16
+ bulma-ui/src/components/__tests__/MyComponent.test.tsx # Jest + RTL tests
17
+ bulma-ui/src/scss/components/_mycomponent.scss # SCSS partial
18
+ docs/docs/api/components/mycomponent.md # Docusaurus docs page
19
+ ```
20
+
21
+ Then wire two index files (see **Wiring & build**).
22
+
23
+ ## Component template
24
+
25
+ Components accept Bulma helper props via `BulmaClassesProps`, run them through
26
+ `useBulmaClasses`, build their own classes with `usePrefixedClassNames`, and merge everything
27
+ with `classNames`. Spread `rest` (the non-helper props) onto the DOM node.
28
+
29
+ Use `forwardRef` when consumers need the DOM node (focus, measurement, observers) — typical
30
+ for interactive extras, so this template uses it. Simpler wrappers in the library are plain
31
+ function components; match the siblings in the target folder.
32
+
33
+ ```tsx
34
+ import React, { forwardRef } from 'react';
35
+ import { classNames, usePrefixedClassNames } from '../helpers/classNames';
36
+ import { useBulmaClasses, BulmaClassesProps } from '../helpers/useBulmaClasses';
37
+
38
+ export type MyComponentColor =
39
+ 'primary' | 'link' | 'info' | 'success' | 'warning' | 'danger';
40
+
41
+ /**
42
+ * Props for the MyComponent component.
43
+ *
44
+ * @property {MyComponentColor} [color] - Bulma color modifier.
45
+ * @property {'small' | 'medium' | 'large'} [size] - Size modifier.
46
+ * @property {boolean} [isActive] - Whether the component is active.
47
+ */
48
+ export interface MyComponentProps
49
+ extends
50
+ Omit<React.HTMLAttributes<HTMLDivElement>, 'color'>,
51
+ Omit<BulmaClassesProps, 'color'> {
52
+ color?: MyComponentColor;
53
+ size?: 'small' | 'medium' | 'large'; // element size union — never the spacing 'validSizes' constant ('0'…'6'|'auto')
54
+ isActive?: boolean;
55
+ }
56
+
57
+ /**
58
+ * MyComponent — short description of what it does.
59
+ *
60
+ * @example
61
+ * <MyComponent color="primary" size="large" isActive>Hello</MyComponent>
62
+ */
63
+ export const MyComponent = forwardRef<HTMLDivElement, MyComponentProps>(
64
+ ({ color, size, isActive, className, children, ...props }, ref) => {
65
+ // 1. Pull Bulma helper classes (m/p, text*, display, etc.) out of props.
66
+ const { bulmaHelperClasses, rest } = useBulmaClasses(props);
67
+
68
+ // 2. Build this component's own classes (respects the ConfigProvider classPrefix).
69
+ const mainClasses = usePrefixedClassNames('mycomponent', {
70
+ [`is-${color}`]: !!color,
71
+ [`is-${size}`]: !!size,
72
+ 'is-active': !!isActive,
73
+ });
74
+
75
+ // 3. Merge: own classes + helper classes + caller className.
76
+ const combined = classNames(mainClasses, bulmaHelperClasses, className);
77
+
78
+ return (
79
+ <div ref={ref} className={combined} {...rest}>
80
+ {children}
81
+ </div>
82
+ );
83
+ }
84
+ );
85
+
86
+ MyComponent.displayName = 'MyComponent';
87
+
88
+ export default MyComponent;
89
+ ```
90
+
91
+ Rules that keep components consistent:
92
+
93
+ - **Always `Omit<…, 'color'>`** from both `HTMLAttributes` and `BulmaClassesProps` when the
94
+ component exposes its own typed `color`, so the native/helper `color` doesn't collide.
95
+ - **Never hand-build class strings.** Use `usePrefixedClassNames(base, conditionalMap)` so the
96
+ optional `classPrefix` from `ConfigProvider` is honored, then `classNames(...)` to merge.
97
+ - **Spread `rest`, not `props`**, onto the DOM node — `useBulmaClasses` has already stripped the
98
+ helper props out of `rest`, so they don't leak to the DOM as invalid attributes.
99
+ - **Set `displayName`** on `forwardRef` components (needed for tests and Storybook autodocs).
100
+ - **Element sizing uses an inline `'small' | 'medium' | 'large'` union**, mapped to `is-small` /
101
+ `is-medium` / `is-large` (see `Tabs.tsx`, `Control.tsx`). Do **not** reach for the `validSizes`
102
+ constant — that one is `'0'…'6' | 'auto'` and exists for **spacing** helpers, not element size.
103
+ - **Format before you lint.** The repo enforces Prettier and ESLint fails on unformatted code.
104
+ Run `pnpm exec prettier --write` on your new files (or `pnpm format` from the repo root) before
105
+ `pnpm lint`. Copy snippets as a starting point, then let Prettier normalize them.
106
+
107
+ See `api.md` for the full helper API and `patterns.md` for the complete Dialog walkthrough.
108
+
109
+ ## SCSS pattern (required)
110
+
111
+ This is the library's house convention — **the Bulma v1 CSS-variable pattern**. Do not write
112
+ plain hard-coded CSS or homebrew `--mycomponent-*` variables. Import Bulma's utilities, declare
113
+ SCSS vars with `!default`, register them as `--bulma-*` custom properties on the root selector
114
+ with `cv.register-vars`, then consume them with `cv.getVar`. Prefix every selector with
115
+ `iv.$class-prefix`.
116
+
117
+ ```scss
118
+ // bulma-ui/src/scss/components/_mycomponent.scss
119
+ @use 'bulma/sass/utilities/initial-variables' as iv;
120
+ @use 'bulma/sass/utilities/css-variables' as cv;
121
+
122
+ // 1. SCSS variables, overridable, referencing Bulma vars via cv.getVar.
123
+ $mycomponent-radius: cv.getVar('radius') !default;
124
+ $mycomponent-background: cv.getVar('scheme-main') !default;
125
+ $mycomponent-color: cv.getVar('text') !default;
126
+ $mycomponent-padding: 1rem !default;
127
+
128
+ // 2. Register them as runtime --bulma-* custom properties on the root selector.
129
+ .#{iv.$class-prefix}mycomponent {
130
+ @include cv.register-vars(
131
+ (
132
+ 'mycomponent-radius': #{$mycomponent-radius},
133
+ 'mycomponent-background': #{$mycomponent-background},
134
+ 'mycomponent-color': #{$mycomponent-color},
135
+ 'mycomponent-padding': #{$mycomponent-padding},
136
+ )
137
+ );
138
+ }
139
+
140
+ // 3. Consume via cv.getVar. Prefix every selector with iv.$class-prefix.
141
+ .#{iv.$class-prefix}mycomponent {
142
+ background-color: cv.getVar('mycomponent-background');
143
+ border-radius: cv.getVar('mycomponent-radius');
144
+ color: cv.getVar('mycomponent-color');
145
+ padding: cv.getVar('mycomponent-padding');
146
+ }
147
+
148
+ // Color variants reuse Bulma's registered color vars.
149
+ .#{iv.$class-prefix}mycomponent.#{iv.$class-prefix}is-primary {
150
+ background-color: cv.getVar('primary');
151
+ color: cv.getVar('primary-invert');
152
+ }
153
+
154
+ // Respect reduced-motion if you animate.
155
+ @media (prefers-reduced-motion: reduce) {
156
+ .#{iv.$class-prefix}mycomponent {
157
+ animation: none;
158
+ }
159
+ }
160
+ ```
161
+
162
+ Why this matters: registering vars makes the component themeable at runtime (the docs site and
163
+ `Theme`/`ConfigProvider` providers override `--bulma-*` properties), and the `iv.$class-prefix` keeps
164
+ the component working when consumers opt into a class prefix to avoid collisions.
165
+
166
+ Register **all** themable values — durations and offsets included — and prefer Bulma tokens
167
+ (`cv.getVar('radius-rounded')`, never `9999px`); derive dark-mode-affected surfaces from scheme
168
+ tokens (`scheme-main`, `text`, `border`). When the component is themeable, add rows to
169
+ `skills/bestax-theming/references/themeable-components.md` and `css-variables.md` in the same PR.
170
+
171
+ The canonical reference file is `bulma-ui/src/scss/components/_dialog.scss`.
172
+
173
+ ## Stories
174
+
175
+ `MyComponent.stories.tsx` beside the component. Use `tags: ['autodocs']` so the JSDoc becomes
176
+ the docs page, declare `argTypes`, and write one named `function`-style render per variant.
177
+ Give every argType a `description` — enforced by a jest meta-test.
178
+
179
+ ```tsx
180
+ import type { Meta, StoryObj } from '@storybook/react-vite';
181
+ import { MyComponent } from './MyComponent';
182
+
183
+ const meta: Meta<typeof MyComponent> = {
184
+ title: 'Components/MyComponent',
185
+ component: MyComponent,
186
+ tags: ['autodocs'],
187
+ argTypes: {
188
+ color: {
189
+ control: 'select',
190
+ options: ['primary', 'link', 'info', 'success', 'warning', 'danger'],
191
+ description: 'Bulma color modifier applied to the component.',
192
+ },
193
+ isActive: {
194
+ control: 'boolean',
195
+ description: 'Whether the component renders in its active state.',
196
+ },
197
+ },
198
+ };
199
+ export default meta;
200
+ type Story = StoryObj<typeof MyComponent>;
201
+
202
+ export const Default: Story = {
203
+ render: function DefaultExample() {
204
+ return <MyComponent>Default</MyComponent>;
205
+ },
206
+ };
207
+
208
+ export const Colors: Story = {
209
+ render: function ColorsExample() {
210
+ return (
211
+ <>
212
+ <MyComponent color="primary">Primary</MyComponent>
213
+ <MyComponent color="danger">Danger</MyComponent>
214
+ </>
215
+ );
216
+ },
217
+ };
218
+ ```
219
+
220
+ ## Tests
221
+
222
+ `__tests__/MyComponent.test.tsx`, Jest + `@testing-library/react`. Cover render, each prop →
223
+ class mapping, the helper-prop passthrough, ref forwarding, the ConfigProvider prefix, and any
224
+ interaction/a11y.
225
+
226
+ ```tsx
227
+ import { render, screen } from '@testing-library/react';
228
+ import { createRef } from 'react';
229
+ import { MyComponent } from '../MyComponent';
230
+ import { ConfigProvider } from '../../helpers/Config';
231
+
232
+ describe('MyComponent', () => {
233
+ it('renders children', () => {
234
+ render(<MyComponent>Hello</MyComponent>);
235
+ expect(screen.getByText('Hello')).toBeInTheDocument();
236
+ });
237
+
238
+ it('applies the color modifier', () => {
239
+ render(<MyComponent color="primary">x</MyComponent>);
240
+ expect(screen.getByText('x')).toHaveClass('mycomponent', 'is-primary');
241
+ });
242
+
243
+ it('passes Bulma helper props through', () => {
244
+ render(<MyComponent m="3">x</MyComponent>);
245
+ expect(screen.getByText('x')).toHaveClass('m-3');
246
+ });
247
+
248
+ it('forwards the ref', () => {
249
+ const ref = createRef<HTMLDivElement>();
250
+ render(<MyComponent ref={ref}>x</MyComponent>);
251
+ expect(ref.current).toBeInstanceOf(HTMLDivElement);
252
+ });
253
+
254
+ it('applies classPrefix from ConfigProvider', () => {
255
+ const { container } = render(
256
+ <ConfigProvider classPrefix="bestax-">
257
+ <MyComponent>x</MyComponent>
258
+ </ConfigProvider>
259
+ );
260
+ const el = container.querySelector('.bestax-mycomponent');
261
+ expect(el).toBeInTheDocument();
262
+ expect(el).not.toHaveClass('mycomponent');
263
+ });
264
+ });
265
+ ```
266
+
267
+ ## Docs page
268
+
269
+ `docs/docs/api/components/mycomponent.md` — Overview, Import, a Props table, `Usage` with
270
+ live examples, then Accessibility, Related Components, and Additional Resources. Live code
271
+ blocks use the ` ```tsx live ` fence (Docusaurus live-codeblock). House rules:
272
+
273
+ - Frontmatter `title:` **must equal the exported component name** — `gen-component-catalog.mjs`
274
+ parses it to build the skill catalog.
275
+ - Headings are Title Case.
276
+ - Every example gets one prose sentence explaining what it shows.
277
+ - No inline `style={{}}` in examples — use helper props.
278
+
279
+ ````md
280
+ ---
281
+ title: MyComponent
282
+ sidebar_label: MyComponent
283
+ ---
284
+
285
+ # MyComponent
286
+
287
+ ## Overview
288
+
289
+ Short description of the component.
290
+
291
+ ## Import
292
+
293
+ ```tsx
294
+ import { MyComponent } from '@allxsmith/bestax-bulma';
295
+ ```
296
+
297
+ ## Props
298
+
299
+ | Prop | Type | Default | Description |
300
+ | ---------- | ---------------------------- | ------- | --------------------- |
301
+ | `color` | `'primary' \| 'link' \| ...` | — | Bulma color modifier. |
302
+ | `isActive` | `boolean` | `false` | Active state. |
303
+
304
+ ## Usage
305
+
306
+ ### Default
307
+
308
+ A basic MyComponent with default styling.
309
+
310
+ ```tsx live
311
+ <MyComponent>Hello</MyComponent>
312
+ ```
313
+
314
+ ## Accessibility
315
+
316
+ Note roles, keyboard behavior, and reduced-motion handling.
317
+
318
+ ## Related Components
319
+
320
+ - [`Tag`](../elements/tag.md) — for a small colored label instead.
321
+
322
+ ## Additional Resources
323
+
324
+ - [Bulma documentation](https://bulma.io/documentation/)
325
+ ````
326
+
327
+ > Note: the Docusaurus docs load the **built** dist CSS. After SCSS changes, run
328
+ > `cd bulma-ui && pnpm build` before the new styles show up in the docs site (Storybook
329
+ > compiles SCSS live and does not need this).
330
+
331
+ ## Wiring & build
332
+
333
+ Two index files must be updated or the component won't ship:
334
+
335
+ 1. **Package export** — add to `bulma-ui/src/index.ts`, in the **components** group (the file
336
+ groups exports by directory — keep yours next to the other `./components/*` lines):
337
+ ```ts
338
+ export * from './components/MyComponent';
339
+ ```
340
+ 2. **SCSS bundle** — add to `bulma-ui/src/scss/components/_index.scss`:
341
+ ```scss
342
+ @use 'mycomponent';
343
+ ```
344
+
345
+ Then build and verify:
346
+
347
+ ```sh
348
+ cd bulma-ui
349
+ pnpm exec prettier --write src/components/MyComponent.tsx src/scss/components/_mycomponent.scss
350
+ pnpm lint
351
+ pnpm test
352
+ pnpm build # compiles JS + the bestax/extras CSS bundles
353
+ ```
354
+
355
+ Finally run `pnpm gen:catalog` from the repo root — CI's `gen:catalog:check` fails if the skill
356
+ component catalog is stale.
357
+
358
+ ## Visually inspect it in a browser
359
+
360
+ Types and unit tests don't see layout. **Render the component and actually look at it** before
361
+ you call it done — spacing, padding, vertical centering, alignment, and every variant/state
362
+ (colors, sizes, hover/active, dark mode). Visual bugs hide from `tsc` and `@testing-library`.
363
+
364
+ 1. Run a surface that renders it: `pnpm storybook` (compiles SCSS live) or the docs dev server.
365
+ 2. Open the component and inspect it. If a browser-automation tool (claude-in-chrome, Playwright)
366
+ is available, drive the browser and screenshot each variant; otherwise open it yourself and
367
+ eyeball it.
368
+ 3. Check the usual offenders:
369
+ - **Vertical centering of inline text** — `display: inline-block` + `line-height: 1` makes
370
+ text sit low. For chips/labels/buttons use `display: inline-flex; align-items: center;
371
+ justify-content: center;` with a normal `line-height` (Bulma's `Tag` is the reference).
372
+ - Padding/gaps look balanced; nothing clips or overflows.
373
+ - Every color/size variant renders; dark mode is legible.
374
+
375
+ Fix what you see, then re-inspect. A green test suite with a misaligned component is not done.
376
+
377
+ ## Checklist
378
+
379
+ - [ ] **Checked the inventory first** — searched `src/index.ts` / docs / Storybook for an existing
380
+ match or synonym, and told the user (reuse/extend it, or confirm there's a genuine gap).
381
+ - [ ] `MyComponent.tsx` — `Omit<…, 'color'>`, `useBulmaClasses`, `usePrefixedClassNames`,
382
+ `classNames`, spread `rest`; `forwardRef` + `displayName` when consumers need the node.
383
+ - [ ] `_mycomponent.scss` — `@use` Bulma utilities, `$vars !default`, `cv.register-vars`,
384
+ `cv.getVar`, every selector prefixed with `iv.$class-prefix`.
385
+ - [ ] `MyComponent.stories.tsx` — `tags: ['autodocs']`, `argTypes` (each with a `description`),
386
+ one story per variant.
387
+ - [ ] `__tests__/MyComponent.test.tsx` — render, prop→class, helper passthrough, ref + ConfigProvider prefix test (required).
388
+ - [ ] `docs/docs/api/components/mycomponent.md` — Overview / Import / Props / `tsx live` /
389
+ Accessibility / Related Components / Additional Resources; frontmatter `title:` = export name.
390
+ - [ ] `src/index.ts` exports the component (in the `./components/*` group).
391
+ - [ ] `scss/components/_index.scss` `@use`s the partial.
392
+ - [ ] Themeable values registered; theming skill references updated in the same PR if applicable.
393
+ - [ ] Prettier-formatted, then `pnpm lint && pnpm test && pnpm build` pass; `pnpm gen:catalog` run.
394
+ - [ ] **Rendered and visually inspected in a browser** — centering/spacing/variants all look
395
+ right (not just green tests).
@@ -1,5 +1,8 @@
1
1
  # Reference: Dialog, the canonical worked example
2
2
 
3
+ **Library-contributor worked example** — the in-monorepo counterpart to `examples/stat-card.tsx`;
4
+ follow it together with `library-contributor.md`.
5
+
3
6
  `Dialog` is the library's reference implementation of the custom-component pattern. Read the
4
7
  real files alongside this:
5
8
 
@@ -121,8 +124,8 @@ Dialog also shows optional patterns you can borrow when relevant:
121
124
  - **Accessibility**: `role="alertdialog"`, Escape-to-cancel, and focus management on open.
122
125
  - **Body scroll lock** via a module-level ref count so chained/overlapping dialogs behave.
123
126
 
124
- These are not required for every component — start from the simple template in `SKILL.md` and
125
- add only what your component needs.
127
+ These are not required for every component — start from the simple template in
128
+ `library-contributor.md` and add only what your component needs.
126
129
 
127
130
  ## Other components worth reading for variety
128
131
 
@@ -96,6 +96,33 @@ and numeric shades `--bulma-<c>-00` … `--bulma-<c>-95`.
96
96
  | `--bulma-size-small` / `-normal` / `-medium` / `-large` | 0.75 / 1 / 1.25 / 1.5rem | via `bulmaVars` |
97
97
  | `--bulma-weight-light/normal/medium/semibold/bold/extrabold` | 300 / 400 / 500 / 600 / 700 / 800 | via `bulmaVars` |
98
98
 
99
+ ## Extras component variables (Avatar / Avatars / Badge)
100
+
101
+ These are registered on the component's **own selector** (`.avatar`, `.avatars`, `.badge` —
102
+ `.bestax-avatar` etc. with the prefixed CSS flavor), not on `:root`. A value set on a wrapping
103
+ ancestor — including `Theme`'s `bulmaVars` on a wrapping `Theme` — is only _inherited_ and
104
+ always loses to the component-level declaration, so it will NOT take effect. Working overrides
105
+ target the component's own element instead: redeclare on the component's own class in your CSS
106
+ (mind the class prefix), e.g. `.avatar { --bulma-avatar-size: 3.5rem; }`, or pass a
107
+ `className` and scope the override under it
108
+ (`.avatar.big-avatar { --bulma-avatar-size: 3.5rem; }`), or set it via the component's `style`
109
+ prop. Several default to core theme vars above, so they already flow through a custom theme.
110
+
111
+ | Variable | Default |
112
+ | ----------------------------------------------------------------- | -------------------------------- |
113
+ | `--bulma-avatar-size` | `48px` |
114
+ | `--bulma-avatar-background` / `--bulma-avatar-color` | `background` / `text` |
115
+ | `--bulma-avatar-weight` | `weight-semibold` |
116
+ | `--bulma-avatar-rounded-radius` | `radius-large` |
117
+ | `--bulma-avatars-ring-color` / `--bulma-avatars-ring-width` | `scheme-main` / `2px` |
118
+ | `--bulma-avatars-spacing` | `0.75rem` (`sm` 0.5 / `lg` 1rem) |
119
+ | `--bulma-badge-height` / `--bulma-badge-min-width` | `1.25em` / `1.25em` |
120
+ | `--bulma-badge-padding` / `--bulma-badge-font-size` | `0 0.4em` / `0.7rem` |
121
+ | `--bulma-badge-radius` | `radius-rounded` |
122
+ | `--bulma-badge-ring-color` / `--bulma-badge-ring-width` | `scheme-main` / `2px` |
123
+ | `--bulma-badge-dot-size` | `0.65em` |
124
+ | `--bulma-badge-inset-circle` / `--bulma-badge-animation-duration` | `12%` / `1.4s` |
125
+
99
126
  ## Dark mode (`Theme colorMode`)
100
127
 
101
128
  Drive the light/dark scheme with the `Theme` component's **`colorMode`** prop —
@@ -28,16 +28,18 @@ Shades (`colorShade` / `backgroundColorShade`): `00, 05, 10, … 95, invert, lig
28
28
 
29
29
  ## Component `color` / `size` props (verbatim unions)
30
30
 
31
- | Component | `color` accepts | `size` accepts | Notes |
32
- | -------------- | ------------------------------------------------------------------------------------------------------------- | ------------------------------------ | ----------------------------------------------------------------------------- |
33
- | `Button` | `primary \| link \| info \| success \| warning \| danger \| white \| light \| dark \| black \| text \| ghost` | `small \| normal \| medium \| large` | adds `text`, `ghost`; also `isLight`, `isOutlined`, `isInverted`, `isRounded` |
34
- | `Notification` | the 17 `validColors` | — | also `isLight` |
35
- | `Tag` | `primary \| link \| info \| success \| warning \| danger \| black \| dark \| light \| white` | `normal \| medium \| large` | also `isRounded`, `isDelete`, `isHoverable` |
36
- | `Box` | `primary \| link \| info \| success \| warning \| danger` | — | the 6 only; also `hasShadow` |
37
- | `Message` | `primary \| link \| info \| success \| warning \| danger` | — | the 6 only |
38
- | `Input` | `primary \| link \| info \| success \| warning \| danger \| black \| dark \| light \| white` | `small \| medium \| large` | also `isRounded`, `isStatic` |
39
- | `Title` | (no `color`; use `textColor`) | `1 \| 2 \| 3 \| 4 \| 5 \| 6` | also `isSpaced` |
40
- | `SubTitle` | (no `color`; use `textColor`) | `1 \| 2 \| 3 \| 4 \| 5 \| 6` | — |
31
+ | Component | `color` accepts | `size` accepts | Notes |
32
+ | -------------- | ------------------------------------------------------------------------------------------------------------- | ------------------------------------------------------------------------- | ----------------------------------------------------------------------------- |
33
+ | `Button` | `primary \| link \| info \| success \| warning \| danger \| white \| light \| dark \| black \| text \| ghost` | `small \| normal \| medium \| large` | adds `text`, `ghost`; also `isLight`, `isOutlined`, `isInverted`, `isRounded` |
34
+ | `Notification` | the 17 `validColors` | — | also `isLight` |
35
+ | `Tag` | `primary \| link \| info \| success \| warning \| danger \| black \| dark \| light \| white` | `normal \| medium \| large` | also `isRounded`, `isDelete`, `isHoverable` |
36
+ | `Box` | `primary \| link \| info \| success \| warning \| danger` | — | the 6 only; also `hasShadow` |
37
+ | `Message` | `primary \| link \| info \| success \| warning \| danger` | — | the 6 only |
38
+ | `Input` | `primary \| link \| info \| success \| warning \| danger \| black \| dark \| light \| white` | `small \| medium \| large` | also `isRounded`, `isStatic` |
39
+ | `Avatar` | `primary \| link \| info \| success \| warning \| danger \| black \| dark \| light \| white` | `16x16 \| 24x24 \| 32x32 \| 48x48 \| 64x64 \| 96x96 \| 128x128 \| number` | initials/icon background (auto-derived from `name` when unset); also `shape` |
40
+ | `Badge` | `primary \| link \| info \| success \| warning \| danger \| black \| dark \| light \| white` | — | pill background; default `danger` |
41
+ | `Title` | — (no `color`; use `textColor`) | `1 \| 2 \| 3 \| 4 \| 5 \| 6` | also `isSpaced` |
42
+ | `SubTitle` | — (no `color`; use `textColor`) | `1 \| 2 \| 3 \| 4 \| 5 \| 6` | — |
41
43
 
42
44
  The 6 brand colors (`primary, link, info, success, warning, danger`) are the ones a custom theme
43
45
  recolors via the HSL trios (see `css-variables.md`). The greyscale and `white`/`light`/`dark`