@bubble-design-system/ui 1.0.1 → 1.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.
- package/README.md +607 -303
- package/dist/index.cjs +1252 -181
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.cts +131 -10
- package/dist/index.d.ts +131 -10
- package/dist/index.js +1246 -183
- package/dist/index.js.map +1 -1
- package/dist/styles.css +1900 -577
- package/dist/tokens.css +472 -382
- package/package.json +9 -8
package/README.md
CHANGED
|
@@ -18,7 +18,7 @@ Every visual decision — tone, color, brand, gray family, radius, density, typo
|
|
|
18
18
|
>
|
|
19
19
|
```
|
|
20
20
|
|
|
21
|
-
- **
|
|
21
|
+
- **25 components** — Button, Input, Textarea, Checkbox, Radio, Switch, Select, Badge, Avatar, Divider, Modal, Toast, Tooltip, Tabs, Alert, DropdownMenu, Skeleton, Card, StatusPill, Segmented, Popover, DataTable, CommandPalette, Chat (plus Container + Grid layout primitives). Each wraps an [`@base-ui/react`](https://base-ui.com/) primitive where one exists — accessible by construction, styled with a single shipped stylesheet.
|
|
22
22
|
- **A 3-layer, multi-theme token system** spanning color (light/dark · 3 gray families · 6 brand palettes including teal), **3 tones** (vivid · pastel · soft — soft is the signature look), radius (4 scales), density (3 scales), typography (2 font pairs), layered shadows, and motion.
|
|
23
23
|
- **Live theme switching** via seven `data-*` attributes on any ancestor. Every CSS rule reads `var(--…)` at use-site, so swapping `data-tone="vivid"` for `data-tone="soft"` reflows the UI without re-rendering or rebuilding.
|
|
24
24
|
- **No build dependency in consumer apps.** One CSS import. No PostCSS, no Tailwind, no preprocessor required.
|
|
@@ -37,8 +37,38 @@ The five rules every decision in Bubble traces back to:
|
|
|
37
37
|
|
|
38
38
|
---
|
|
39
39
|
|
|
40
|
+
## Common UI Patterns
|
|
41
|
+
|
|
42
|
+
Before writing custom CSS against `var(--color-bg-*)`, `var(--radius-*)`, or `var(--shadow-*)` to build a surface, pill, menu, or banner — check this table. There is very likely already a component for it.
|
|
43
|
+
|
|
44
|
+
| You're building... | Use | Not... |
|
|
45
|
+
| ------------------------------------------------------------------------------------------- | ---------------------------------------------------------------------------------------------------------------------------------------------------------------- | --------------------------------------------------------------------------------------- |
|
|
46
|
+
| A floating card / panel / content surface | [`Card`](#card) (`variant="elevated"` or `"muted"`) | a `<div>` styled with `--color-bg-secondary` + `--radius-lg` + `--shadow-md` |
|
|
47
|
+
| A chat message thread (bubbles, avatars, timestamps, read receipts, reactions, compose bar) | [`Chat`](#chat) — `ChatThread` / `ChatMessage` / `ChatCompose` | a custom flex layout styled from raw tokens, with hand-rolled grouping and scroll logic |
|
|
48
|
+
| A notification / toast / status banner | [`Toast`](#toast) + `useToast()` | a custom `toast-container` + `setTimeout` store |
|
|
49
|
+
| A status indicator (online, connected, error dot) | [`StatusPill`](#statuspill) + `StatusPill.Indicator` | a `::after` pseudo-element colored with `--color-bg-success-strong` |
|
|
50
|
+
| A small tag, count, or label pill | [`Badge`](#badge) | a custom pill `<div>` with `--radius-full` |
|
|
51
|
+
| A dropdown / context menu / select-from-list | [`DropdownMenu`](#dropdownmenu) | an absolutely-positioned custom `<div>` list |
|
|
52
|
+
| A command palette / "/" slash-command menu / ⌘K launcher | [`CommandPalette`](#commandpalette) + `useCommandPalette()` | a custom filtered dropdown with arrow-key handling |
|
|
53
|
+
| A popover anchored to a trigger (info panel, form, menu) | [`Popover`](#popover) | a custom absolutely-positioned `<div>` + manual outside-click handling |
|
|
54
|
+
| A hover tooltip | [`Tooltip`](#tooltip) | the native `title` attribute or a custom hover `<div>` |
|
|
55
|
+
| A loading placeholder | [`Skeleton`](#skeleton) | a custom `@keyframes pulse` `<div>` |
|
|
56
|
+
| A view switcher / segmented toggle | [`Segmented`](#segmented) | a custom button group with manual active-state CSS |
|
|
57
|
+
| A confirm dialog / modal | [`Modal`](#modal) | a custom backdrop + centered `<div>` |
|
|
58
|
+
| A responsive page section / 12-col grid | [`Container`](#container--grid) + [`Grid`](#container--grid) | custom `max-width` + flex/grid CSS |
|
|
59
|
+
| A tabbed interface | [`Tabs`](#tabs) | a custom button row + conditional render |
|
|
60
|
+
| A sortable / searchable / paginated table | [`DataTable`](#datatable) | a custom `<table>` + manual sort/filter/page state |
|
|
61
|
+
| A horizontal or vertical rule | [`Divider`](#divider) | `border-top: 1px solid var(--color-border-*)` |
|
|
62
|
+
| A user/avatar icon with fallback initials | [`Avatar`](#avatar) | a circular `<div>` + `<img>` with manual error handling |
|
|
63
|
+
| Form fields (text, multiline, checkbox, radio, switch, select) | [`Input`](#input) / [`Textarea`](#textarea) / [`Checkbox`](#checkbox) / [`Radio` / `RadioGroup`](#radio--radiogroup) / [`Switch`](#switch) / [`Select`](#select) | native elements styled from scratch |
|
|
64
|
+
|
|
65
|
+
**If nothing in this table fits**, that's a real gap — reach for tokens directly, and consider [opening an issue](https://github.com/mushroomgead/bubble-design-system/issues) so the pattern can become component #26.
|
|
66
|
+
|
|
67
|
+
---
|
|
68
|
+
|
|
40
69
|
## Table of contents
|
|
41
70
|
|
|
71
|
+
- [Common UI Patterns](#common-ui-patterns)
|
|
42
72
|
- [Tech stack](#tech-stack)
|
|
43
73
|
- [Installation](#installation)
|
|
44
74
|
- [Setup](#setup)
|
|
@@ -54,16 +84,16 @@ The five rules every decision in Bubble traces back to:
|
|
|
54
84
|
|
|
55
85
|
## Tech stack
|
|
56
86
|
|
|
57
|
-
| Concern
|
|
58
|
-
|
|
59
|
-
| Framework
|
|
60
|
-
| Primitives
|
|
61
|
-
| Styling
|
|
62
|
-
| Class composition | `clsx` (re-exported as `cn()`)
|
|
63
|
-
| Build tool
|
|
64
|
-
| Language
|
|
65
|
-
| Package manager
|
|
66
|
-
| Node
|
|
87
|
+
| Concern | Tool |
|
|
88
|
+
| ----------------- | --------------------------------------------------------------------------------- |
|
|
89
|
+
| Framework | React 19 (works with ≥ 18.2) |
|
|
90
|
+
| Primitives | `@base-ui/react` ≥ 1.0 (the post-rename successor to `@base-ui-components/react`) |
|
|
91
|
+
| Styling | Plain CSS — one shipped stylesheet, hand-authored per component |
|
|
92
|
+
| Class composition | `clsx` (re-exported as `cn()`) |
|
|
93
|
+
| Build tool | `tsup` (ESM + CJS + dual `.d.ts`) + a 50-line Node script for CSS bundling |
|
|
94
|
+
| Language | TypeScript 6 |
|
|
95
|
+
| Package manager | `pnpm@10.33.0` |
|
|
96
|
+
| Node | ≥ 20 |
|
|
67
97
|
|
|
68
98
|
---
|
|
69
99
|
|
|
@@ -86,11 +116,11 @@ Then install the peer dependencies your app must have:
|
|
|
86
116
|
npm install react react-dom @base-ui/react
|
|
87
117
|
```
|
|
88
118
|
|
|
89
|
-
| Peer dependency
|
|
90
|
-
|
|
91
|
-
| `react`
|
|
92
|
-
| `react-dom`
|
|
93
|
-
| `@base-ui/react` | ≥ 1.0.0
|
|
119
|
+
| Peer dependency | Required version |
|
|
120
|
+
| ---------------- | ---------------- |
|
|
121
|
+
| `react` | ≥ 18.2 |
|
|
122
|
+
| `react-dom` | ≥ 18.2 |
|
|
123
|
+
| `@base-ui/react` | ≥ 1.0.0 |
|
|
94
124
|
|
|
95
125
|
---
|
|
96
126
|
|
|
@@ -121,7 +151,11 @@ If you only want the raw CSS custom properties (no component rules), import the
|
|
|
121
151
|
|
|
122
152
|
```tsx
|
|
123
153
|
// app/layout.tsx (Next.js App Router example)
|
|
124
|
-
export default function RootLayout({
|
|
154
|
+
export default function RootLayout({
|
|
155
|
+
children,
|
|
156
|
+
}: {
|
|
157
|
+
children: React.ReactNode;
|
|
158
|
+
}) {
|
|
125
159
|
return (
|
|
126
160
|
<html
|
|
127
161
|
lang="en"
|
|
@@ -152,7 +186,9 @@ export function Example() {
|
|
|
152
186
|
<Button variant="primary">Save</Button>
|
|
153
187
|
<Divider />
|
|
154
188
|
<Modal.Root>
|
|
155
|
-
<Modal.Trigger render={<Button variant="secondary" />}>
|
|
189
|
+
<Modal.Trigger render={<Button variant="secondary" />}>
|
|
190
|
+
Open
|
|
191
|
+
</Modal.Trigger>
|
|
156
192
|
<Modal.Content>
|
|
157
193
|
<Modal.Title>Confirm</Modal.Title>
|
|
158
194
|
<Modal.Description>Are you sure?</Modal.Description>
|
|
@@ -169,15 +205,15 @@ export function Example() {
|
|
|
169
205
|
|
|
170
206
|
Seven `data-*` attributes on any ancestor element (typically `<html>` or `<body>`) re-skin every descendant at runtime, with no rebuild.
|
|
171
207
|
|
|
172
|
-
| Attribute
|
|
173
|
-
|
|
174
|
-
| `data-theme`
|
|
175
|
-
| `data-tone`
|
|
176
|
-
| `data-gray`
|
|
177
|
-
| `data-brand`
|
|
178
|
-
| `data-radius`
|
|
179
|
-
| `data-density` | `default` · `compact` · `comfortable`
|
|
180
|
-
| `data-font`
|
|
208
|
+
| Attribute | Values | Default | What it controls |
|
|
209
|
+
| -------------- | ---------------------------------------------------------- | --------- | -------------------------------------------------------------------------------- |
|
|
210
|
+
| `data-theme` | `light` · `dark` | `light` | Semantic color mapping (background, text, border, shadow). |
|
|
211
|
+
| `data-tone` | `vivid` · `pastel` · `soft` | `soft` | Surface model, palette saturation, control radius. `soft` is the signature look. |
|
|
212
|
+
| `data-gray` | `slate` · `neutral` · `stone` | `slate` | The gray family used for surfaces and text. |
|
|
213
|
+
| `data-brand` | `blue` · `violet` · `emerald` · `orange` · `mono` · `teal` | `teal` | The brand palette (`--brand-50` through `--brand-950`). |
|
|
214
|
+
| `data-radius` | `default` · `sharp` · `soft` · `pill` | `default` | The corner radius scale (`--radius-xs` through `--radius-2xl`). |
|
|
215
|
+
| `data-density` | `default` · `compact` · `comfortable` | `default` | Control heights and padding (`--control-h-*`, `--control-px-*`). |
|
|
216
|
+
| `data-font` | `roboto` · `system` | `roboto` | The font pair (`--font-sans` / `--font-mono`). |
|
|
181
217
|
|
|
182
218
|
Toggle them with any approach you like — `setAttribute`, React state, a media-query listener, a server cookie:
|
|
183
219
|
|
|
@@ -196,10 +232,39 @@ Every component is exported from the package root:
|
|
|
196
232
|
|
|
197
233
|
```tsx
|
|
198
234
|
import {
|
|
199
|
-
Alert,
|
|
200
|
-
|
|
201
|
-
|
|
202
|
-
|
|
235
|
+
Alert,
|
|
236
|
+
Avatar,
|
|
237
|
+
Badge,
|
|
238
|
+
Button,
|
|
239
|
+
Card,
|
|
240
|
+
ChatCompose,
|
|
241
|
+
ChatDateDivider,
|
|
242
|
+
ChatMessage,
|
|
243
|
+
ChatThread,
|
|
244
|
+
Checkbox,
|
|
245
|
+
CommandPalette,
|
|
246
|
+
Container,
|
|
247
|
+
DataTable,
|
|
248
|
+
Divider,
|
|
249
|
+
DropdownMenu,
|
|
250
|
+
Grid,
|
|
251
|
+
Input,
|
|
252
|
+
Modal,
|
|
253
|
+
Popover,
|
|
254
|
+
Radio,
|
|
255
|
+
RadioGroup,
|
|
256
|
+
Segmented,
|
|
257
|
+
Select,
|
|
258
|
+
Skeleton,
|
|
259
|
+
StatusPill,
|
|
260
|
+
Switch,
|
|
261
|
+
Tabs,
|
|
262
|
+
Textarea,
|
|
263
|
+
Toast,
|
|
264
|
+
Tooltip,
|
|
265
|
+
useCommandPalette,
|
|
266
|
+
useToast,
|
|
267
|
+
cn,
|
|
203
268
|
} from "@bubble-design-system/ui";
|
|
204
269
|
```
|
|
205
270
|
|
|
@@ -217,14 +282,14 @@ Conventions shared by all components:
|
|
|
217
282
|
|
|
218
283
|
A static informational banner with a variant-specific icon, title, and body.
|
|
219
284
|
|
|
220
|
-
| Prop
|
|
221
|
-
|
|
222
|
-
| `variant`
|
|
223
|
-
| `icon`
|
|
224
|
-
| `title`
|
|
225
|
-
| `children`
|
|
226
|
-
| `className` | `string`
|
|
227
|
-
| `...props`
|
|
285
|
+
| Prop | Type | Default | Description |
|
|
286
|
+
| ----------- | ------------------------------------------------ | ---------------- | ------------------------------------------------------ |
|
|
287
|
+
| `variant` | `"info" \| "success" \| "warning" \| "danger"` | `"info"` | Visual tone and default icon. |
|
|
288
|
+
| `icon` | `ReactNode \| false` | variant-specific | Override the default icon, or pass `false` to hide it. |
|
|
289
|
+
| `title` | `ReactNode` | — | Optional bold header line. |
|
|
290
|
+
| `children` | `ReactNode` | — | The body copy, rendered in the secondary text color. |
|
|
291
|
+
| `className` | `string` | — | Extra classes (appended after the library's). |
|
|
292
|
+
| `...props` | `HTMLAttributes<HTMLDivElement>` (minus `title`) | — | All native div attributes. |
|
|
228
293
|
|
|
229
294
|
```tsx
|
|
230
295
|
<Alert variant="success" title="Saved">Your changes are live.</Alert>
|
|
@@ -239,19 +304,19 @@ A static informational banner with a variant-specific icon, title, and body.
|
|
|
239
304
|
|
|
240
305
|
Compound component built on `@base-ui/react/avatar` — handles image load failure with a fallback.
|
|
241
306
|
|
|
242
|
-
| Sub-component
|
|
243
|
-
|
|
244
|
-
| `Avatar` (root)
|
|
245
|
-
| `Avatar.Image`
|
|
307
|
+
| Sub-component | Description |
|
|
308
|
+
| ----------------- | --------------------------------------------------- |
|
|
309
|
+
| `Avatar` (root) | Sized circular surface. |
|
|
310
|
+
| `Avatar.Image` | The image element. |
|
|
246
311
|
| `Avatar.Fallback` | Shown while the image is loading or after it fails. |
|
|
247
312
|
|
|
248
313
|
**`Avatar` props:**
|
|
249
314
|
|
|
250
|
-
| Prop
|
|
251
|
-
|
|
252
|
-
| `size`
|
|
253
|
-
| `className` | `string`
|
|
254
|
-
| `...props`
|
|
315
|
+
| Prop | Type | Default | Description |
|
|
316
|
+
| ----------- | ------------------------------ | ------- | --------------------- |
|
|
317
|
+
| `size` | `"sm" \| "md" \| "lg" \| "xl"` | `"md"` | 24 / 32 / 40 / 48 px. |
|
|
318
|
+
| `className` | `string` | — | Extra classes. |
|
|
319
|
+
| `...props` | Base UI `Avatar.Root` props | — | Spread to the root. |
|
|
255
320
|
|
|
256
321
|
`Avatar.Image` and `Avatar.Fallback` accept their Base UI props plus `className`.
|
|
257
322
|
|
|
@@ -268,12 +333,12 @@ Compound component built on `@base-ui/react/avatar` — handles image load failu
|
|
|
268
333
|
|
|
269
334
|
Small inline pill for status, counts, or labels.
|
|
270
335
|
|
|
271
|
-
| Prop
|
|
272
|
-
|
|
273
|
-
| `variant`
|
|
274
|
-
| `size`
|
|
275
|
-
| `className` | `string`
|
|
276
|
-
| `...props`
|
|
336
|
+
| Prop | Type | Default | Description |
|
|
337
|
+
| ----------- | ------------------------------------------------------------ | ----------- | -------------------------- |
|
|
338
|
+
| `variant` | `"neutral" \| "brand" \| "success" \| "warning" \| "danger"` | `"neutral"` | Background and text color. |
|
|
339
|
+
| `size` | `"sm" \| "md" \| "lg"` | `"md"` | Pill height and padding. |
|
|
340
|
+
| `className` | `string` | — | Extra classes. |
|
|
341
|
+
| `...props` | `HTMLAttributes<HTMLSpanElement>` | — | Native span attributes. |
|
|
277
342
|
|
|
278
343
|
```tsx
|
|
279
344
|
<Badge variant="success">Active</Badge>
|
|
@@ -286,12 +351,12 @@ Small inline pill for status, counts, or labels.
|
|
|
286
351
|
|
|
287
352
|
Wraps `@base-ui/react/button`.
|
|
288
353
|
|
|
289
|
-
| Prop
|
|
290
|
-
|
|
291
|
-
| `variant`
|
|
292
|
-
| `size`
|
|
293
|
-
| `className` | `string`
|
|
294
|
-
| `...props`
|
|
354
|
+
| Prop | Type | Default | Description |
|
|
355
|
+
| ----------- | ------------------------------------------------------ | ----------- | --------------------------------------------------------------------------- |
|
|
356
|
+
| `variant` | `"primary" \| "secondary" \| "destructive" \| "ghost"` | `"primary"` | Visual style. |
|
|
357
|
+
| `size` | `"sm" \| "md" \| "lg"` | `"md"` | Maps to `--control-h-*` / `--control-px-*` so density attribute affects it. |
|
|
358
|
+
| `className` | `string` | — | Extra classes. |
|
|
359
|
+
| `...props` | Base UI `Button` props | — | Includes `disabled`, `type`, `onClick`, etc. |
|
|
295
360
|
|
|
296
361
|
```tsx
|
|
297
362
|
<Button variant="primary" size="lg" onClick={save}>Save</Button>
|
|
@@ -305,22 +370,22 @@ Wraps `@base-ui/react/button`.
|
|
|
305
370
|
|
|
306
371
|
Compound component for floating-pill surface content.
|
|
307
372
|
|
|
308
|
-
| Sub-component
|
|
309
|
-
|
|
310
|
-
| `Card` (root)
|
|
311
|
-
| `Card.Header`
|
|
312
|
-
| `Card.Title`
|
|
313
|
-
| `Card.Description` | Supporting paragraph.
|
|
314
|
-
| `Card.Action`
|
|
315
|
-
| `Card.Body`
|
|
316
|
-
| `Card.Footer`
|
|
373
|
+
| Sub-component | Description |
|
|
374
|
+
| ------------------ | ----------------------------------------------------- |
|
|
375
|
+
| `Card` (root) | The floating surface. Variant controls fill + shadow. |
|
|
376
|
+
| `Card.Header` | Row with title + optional action. |
|
|
377
|
+
| `Card.Title` | `<h3>` heading. |
|
|
378
|
+
| `Card.Description` | Supporting paragraph. |
|
|
379
|
+
| `Card.Action` | Right-aligned controls inside the header. |
|
|
380
|
+
| `Card.Body` | Main content area. |
|
|
381
|
+
| `Card.Footer` | Bordered footer row with right-aligned controls. |
|
|
317
382
|
|
|
318
383
|
**`Card` props:**
|
|
319
384
|
|
|
320
|
-
| Prop
|
|
321
|
-
|
|
322
|
-
| `variant`
|
|
323
|
-
| `className` | `string`
|
|
385
|
+
| Prop | Type | Default | Description |
|
|
386
|
+
| ----------- | ----------------------- | ------------ | ---------------------------------------------------------------------------- |
|
|
387
|
+
| `variant` | `"elevated" \| "muted"` | `"elevated"` | `elevated` = white surface with shadow. `muted` = `bg-secondary`, no shadow. |
|
|
388
|
+
| `className` | `string` | — | Extra classes. |
|
|
324
389
|
|
|
325
390
|
```tsx
|
|
326
391
|
<Card>
|
|
@@ -330,12 +395,16 @@ Compound component for floating-pill surface content.
|
|
|
330
395
|
<Card.Description>White card floating on a gray page.</Card.Description>
|
|
331
396
|
</div>
|
|
332
397
|
<Card.Action>
|
|
333
|
-
<Button size="sm" variant="ghost">
|
|
398
|
+
<Button size="sm" variant="ghost">
|
|
399
|
+
Manage
|
|
400
|
+
</Button>
|
|
334
401
|
</Card.Action>
|
|
335
402
|
</Card.Header>
|
|
336
403
|
<Card.Body>…</Card.Body>
|
|
337
404
|
<Card.Footer>
|
|
338
|
-
<Button size="sm" variant="ghost">
|
|
405
|
+
<Button size="sm" variant="ghost">
|
|
406
|
+
Cancel
|
|
407
|
+
</Button>
|
|
339
408
|
<Button size="sm">Save</Button>
|
|
340
409
|
</Card.Footer>
|
|
341
410
|
</Card>
|
|
@@ -343,15 +412,86 @@ Compound component for floating-pill surface content.
|
|
|
343
412
|
|
|
344
413
|
---
|
|
345
414
|
|
|
415
|
+
### Chat
|
|
416
|
+
|
|
417
|
+
Four standalone components for assembling a chat thread — no Base UI primitive needed, just plain markup. `ChatThread` is the scroll container, `ChatDateDivider` renders a centered separator label, `ChatMessage` is a single message bubble (with grouping, avatar, meta, reactions, and delivery status), and `ChatCompose` is an auto-growing input bar.
|
|
418
|
+
|
|
419
|
+
| Component | Description |
|
|
420
|
+
| ----------------- | ---------------------------------------------------------------- |
|
|
421
|
+
| `ChatThread` | Scrollable message-list container. |
|
|
422
|
+
| `ChatDateDivider` | Centered separator label (e.g. "Today"). |
|
|
423
|
+
| `ChatMessage` | A single message bubble — grouping/avatar/meta/reactions/status. |
|
|
424
|
+
| `ChatCompose` | Auto-growing textarea + send button, controlled or uncontrolled. |
|
|
425
|
+
|
|
426
|
+
**`ChatMessage` props:**
|
|
427
|
+
|
|
428
|
+
| Prop | Type | Default | Description |
|
|
429
|
+
| ----------- | ----------------------------------------------------- | ------------ | ----------------------------------------------------------------------------------------------------------------- |
|
|
430
|
+
| `side` | `"sent" \| "received"` | `"received"` | Which side of the thread the bubble renders on. |
|
|
431
|
+
| `position` | `"solo" \| "first" \| "middle" \| "last"` | `"solo"` | Position within a consecutive group — controls bubble-corner rounding and which messages show meta/avatar/status. |
|
|
432
|
+
| `avatar` | `ReactNode` | — | Avatar slot, shown for `received` messages at `solo`/`last`. |
|
|
433
|
+
| `name` | `string` | — | Sender name, shown at `solo`/`first` for received messages. |
|
|
434
|
+
| `time` | `string` | — | Timestamp, shown at `solo`/`first`. |
|
|
435
|
+
| `status` | `"sending" \| "sent" \| "delivered" \| "read"` | — | Delivery-status row, shown for `sent` messages at `solo`/`last`. |
|
|
436
|
+
| `reactions` | `{ emoji: string; count?: number; mine?: boolean }[]` | — | Reaction pills rendered under the bubble. |
|
|
437
|
+
| `className` | `string` | — | Extra classes. |
|
|
438
|
+
|
|
439
|
+
**`ChatCompose` props:**
|
|
440
|
+
|
|
441
|
+
| Prop | Type | Default | Description |
|
|
442
|
+
| ------------- | ----------------------------------------------- | -------------------- | ---------------------------------------------------------------- |
|
|
443
|
+
| `value` | `string` | — | Controlled value. Omit for uncontrolled (internal state). |
|
|
444
|
+
| `onChange` | `(e: ChangeEvent<HTMLTextAreaElement>) => void` | — | Change handler (controlled mode). |
|
|
445
|
+
| `onSend` | `(value: string) => void` | — | Called with the trimmed text on send (Enter or the send button). |
|
|
446
|
+
| `placeholder` | `string` | `"Write a message…"` | Textarea placeholder. |
|
|
447
|
+
| `avatar` | `ReactNode` | — | Avatar slot rendered before the input. |
|
|
448
|
+
| `disabled` | `boolean` | `false` | Disables the textarea and send button. |
|
|
449
|
+
| `className` | `string` | — | Extra classes. |
|
|
450
|
+
|
|
451
|
+
```tsx
|
|
452
|
+
<ChatThread>
|
|
453
|
+
<ChatDateDivider>Today</ChatDateDivider>
|
|
454
|
+
|
|
455
|
+
<ChatMessage
|
|
456
|
+
side="received"
|
|
457
|
+
name="Lena Torres"
|
|
458
|
+
time="9:41 AM"
|
|
459
|
+
avatar={
|
|
460
|
+
<Avatar>
|
|
461
|
+
<Avatar.Fallback>LT</Avatar.Fallback>
|
|
462
|
+
</Avatar>
|
|
463
|
+
}
|
|
464
|
+
reactions={[{ emoji: "👍", count: 2, mine: true }]}
|
|
465
|
+
>
|
|
466
|
+
Hey — got a minute to look at the new Card variants?
|
|
467
|
+
</ChatMessage>
|
|
468
|
+
|
|
469
|
+
<ChatMessage side="sent" status="read">
|
|
470
|
+
Sure, pulling them up now.
|
|
471
|
+
</ChatMessage>
|
|
472
|
+
</ChatThread>
|
|
473
|
+
|
|
474
|
+
<ChatCompose
|
|
475
|
+
avatar={
|
|
476
|
+
<Avatar>
|
|
477
|
+
<Avatar.Fallback>AK</Avatar.Fallback>
|
|
478
|
+
</Avatar>
|
|
479
|
+
}
|
|
480
|
+
onSend={(text) => sendMessage(text)}
|
|
481
|
+
/>
|
|
482
|
+
```
|
|
483
|
+
|
|
484
|
+
---
|
|
485
|
+
|
|
346
486
|
### Checkbox
|
|
347
487
|
|
|
348
488
|
Wraps `@base-ui/react/checkbox`. Supports checked, unchecked, and indeterminate states with built-in SVG indicators.
|
|
349
489
|
|
|
350
|
-
| Prop
|
|
351
|
-
|
|
352
|
-
| `size`
|
|
353
|
-
| `className` | `string`
|
|
354
|
-
| `...props`
|
|
490
|
+
| Prop | Type | Default | Description |
|
|
491
|
+
| ----------- | ----------------------------- | ------- | --------------------------------------------------------------------- |
|
|
492
|
+
| `size` | `"sm" \| "md" \| "lg"` | `"md"` | 16 / 18 / 20 px. |
|
|
493
|
+
| `className` | `string` | — | Extra classes on the root button. |
|
|
494
|
+
| `...props` | Base UI `Checkbox.Root` props | — | `checked`, `defaultChecked`, `indeterminate`, `onCheckedChange`, etc. |
|
|
355
495
|
|
|
356
496
|
```tsx
|
|
357
497
|
<Checkbox defaultChecked />
|
|
@@ -361,6 +501,50 @@ Wraps `@base-ui/react/checkbox`. Supports checked, unchecked, and indeterminate
|
|
|
361
501
|
|
|
362
502
|
---
|
|
363
503
|
|
|
504
|
+
### CommandPalette
|
|
505
|
+
|
|
506
|
+
Built on `@base-ui/react/dialog`. A fuzzy-searchable, grouped command list with arrow-key navigation and Enter-to-select — the "/" or ⌘K menu pattern. Pair it with `useCommandPalette()`, a small hook that owns `open` state and registers a global `⌘K` / `Ctrl+K` listener.
|
|
507
|
+
|
|
508
|
+
**`CommandPalette` props:**
|
|
509
|
+
|
|
510
|
+
| Prop | Type | Default | Description |
|
|
511
|
+
| -------------- | ------------------------------------ | ------------------ | -------------------------------------------------------------------------------- |
|
|
512
|
+
| `open` | `boolean` | — | Whether the palette is open. |
|
|
513
|
+
| `onOpenChange` | `(open: boolean) => void` | — | Called when the palette should open or close. |
|
|
514
|
+
| `groups` | `CommandPaletteGroup[]` | `[]` | Grouped, filterable command items. |
|
|
515
|
+
| `placeholder` | `string` | `"Type to search"` | Search input placeholder. |
|
|
516
|
+
| `onSelect` | `(item: CommandPaletteItem) => void` | — | Called when an item is chosen (Enter or click), after the item's own `onSelect`. |
|
|
517
|
+
| `className` | `string` | — | Extra classes on the popup. |
|
|
518
|
+
|
|
519
|
+
**`CommandPaletteGroup`** — `{ label?: string; items: CommandPaletteItem[] }`
|
|
520
|
+
|
|
521
|
+
**`CommandPaletteItem`** — `{ id: string; label: string; description?: string; icon?: ReactNode; shortcut?: string; keywords?: string[]; onSelect?: () => void }`
|
|
522
|
+
|
|
523
|
+
```tsx
|
|
524
|
+
const palette = useCommandPalette(); // owns `open` + ⌘K/Ctrl+K toggle
|
|
525
|
+
|
|
526
|
+
<CommandPalette
|
|
527
|
+
open={palette.open}
|
|
528
|
+
onOpenChange={palette.setOpen}
|
|
529
|
+
groups={[
|
|
530
|
+
{
|
|
531
|
+
label: "Navigation",
|
|
532
|
+
items: [
|
|
533
|
+
{ id: "home", label: "Go home", shortcut: "G H" },
|
|
534
|
+
{ id: "settings", label: "Settings", keywords: ["preferences"] },
|
|
535
|
+
],
|
|
536
|
+
},
|
|
537
|
+
{
|
|
538
|
+
label: "Actions",
|
|
539
|
+
items: [{ id: "new", label: "New item", onSelect: () => createItem() }],
|
|
540
|
+
},
|
|
541
|
+
]}
|
|
542
|
+
onSelect={(item) => console.log("selected", item.id)}
|
|
543
|
+
/>;
|
|
544
|
+
```
|
|
545
|
+
|
|
546
|
+
---
|
|
547
|
+
|
|
364
548
|
### Container + Grid
|
|
365
549
|
|
|
366
550
|
Layout primitives. `Container` centers content and applies page margins. `Grid` is a 12-column grid; `Grid.Col` spans columns with optional responsive overrides.
|
|
@@ -369,9 +553,15 @@ Layout primitives. `Container` centers content and applies page margins. `Grid`
|
|
|
369
553
|
<Container size="lg">
|
|
370
554
|
<Grid>
|
|
371
555
|
<Grid.Col span={12}>full row</Grid.Col>
|
|
372
|
-
<Grid.Col span={6} lgSpan={4}>
|
|
373
|
-
|
|
374
|
-
|
|
556
|
+
<Grid.Col span={6} lgSpan={4}>
|
|
557
|
+
half on mobile, third on lg
|
|
558
|
+
</Grid.Col>
|
|
559
|
+
<Grid.Col span={6} lgSpan={4}>
|
|
560
|
+
…
|
|
561
|
+
</Grid.Col>
|
|
562
|
+
<Grid.Col span={12} lgSpan={4}>
|
|
563
|
+
…
|
|
564
|
+
</Grid.Col>
|
|
375
565
|
</Grid>
|
|
376
566
|
</Container>
|
|
377
567
|
```
|
|
@@ -384,15 +574,64 @@ Layout primitives. `Container` centers content and applies page margins. `Grid`
|
|
|
384
574
|
|
|
385
575
|
---
|
|
386
576
|
|
|
577
|
+
### DataTable
|
|
578
|
+
|
|
579
|
+
Generic, client-side `DataTable<T extends { id: string | number }>` — search across all columns, sortable columns, row selection (header select-all + per-row, reusing `Checkbox`), and pagination.
|
|
580
|
+
|
|
581
|
+
**Props:**
|
|
582
|
+
|
|
583
|
+
| Prop | Type | Default | Description |
|
|
584
|
+
| ------------ | ---------------------- | ------- | ------------------------------------------------------- |
|
|
585
|
+
| `columns` | `DataTableColumn<T>[]` | — | Column definitions, rendered in order. |
|
|
586
|
+
| `data` | `T[]` | — | Rows. Each row must have an `id: string \| number`. |
|
|
587
|
+
| `selectable` | `boolean` | `true` | Shows the select-all / per-row checkboxes. |
|
|
588
|
+
| `searchable` | `boolean` | `true` | Shows the search input; filters across all column keys. |
|
|
589
|
+
| `pageSize` | `number` | `10` | Rows per page. |
|
|
590
|
+
| `actions` | `ReactNode` | — | Right-aligned toolbar content (e.g. a "New" button). |
|
|
591
|
+
| `className` | `string` | — | Extra classes. |
|
|
592
|
+
|
|
593
|
+
**`DataTableColumn<T>`:**
|
|
594
|
+
|
|
595
|
+
| Field | Type | Description |
|
|
596
|
+
| ---------------- | --------------------------------------- | ---------------------------------------------- |
|
|
597
|
+
| `key` | `string` | Property name read off each row. |
|
|
598
|
+
| `label` | `string` | Column header text. |
|
|
599
|
+
| `sortable` | `boolean` | Default `true` — click the header to sort. |
|
|
600
|
+
| `render` | `(value: unknown, row: T) => ReactNode` | Custom cell renderer. |
|
|
601
|
+
| `width` | `string` | CSS width for the `<th>` / `<td>`. |
|
|
602
|
+
| `muted` / `mono` | `boolean` | Styles the cell text as secondary / monospace. |
|
|
603
|
+
|
|
604
|
+
```tsx
|
|
605
|
+
<DataTable
|
|
606
|
+
columns={[
|
|
607
|
+
{ key: "name", label: "Name" },
|
|
608
|
+
{ key: "email", label: "Email", muted: true },
|
|
609
|
+
{
|
|
610
|
+
key: "status",
|
|
611
|
+
label: "Status",
|
|
612
|
+
render: (value) => (
|
|
613
|
+
<StatusPill intent={value === "active" ? "success" : "neutral"}>
|
|
614
|
+
{String(value)}
|
|
615
|
+
</StatusPill>
|
|
616
|
+
),
|
|
617
|
+
},
|
|
618
|
+
]}
|
|
619
|
+
data={users}
|
|
620
|
+
actions={<Button size="sm">Invite</Button>}
|
|
621
|
+
/>
|
|
622
|
+
```
|
|
623
|
+
|
|
624
|
+
---
|
|
625
|
+
|
|
387
626
|
### Divider
|
|
388
627
|
|
|
389
628
|
Horizontal or vertical separator with a semantic role from `@base-ui/react/separator`.
|
|
390
629
|
|
|
391
|
-
| Prop
|
|
392
|
-
|
|
393
|
-
| `orientation` | `"horizontal" \| "vertical"` | `"horizontal"` | Layout direction.
|
|
394
|
-
| `className`
|
|
395
|
-
| `...props`
|
|
630
|
+
| Prop | Type | Default | Description |
|
|
631
|
+
| ------------- | ---------------------------- | -------------- | --------------------------------- |
|
|
632
|
+
| `orientation` | `"horizontal" \| "vertical"` | `"horizontal"` | Layout direction. |
|
|
633
|
+
| `className` | `string` | — | Extra classes. |
|
|
634
|
+
| `...props` | Base UI `Separator` props | — | Spread to the underlying element. |
|
|
396
635
|
|
|
397
636
|
```tsx
|
|
398
637
|
<Divider />
|
|
@@ -407,27 +646,27 @@ Horizontal or vertical separator with a semantic role from `@base-ui/react/separ
|
|
|
407
646
|
|
|
408
647
|
Compound component built on `@base-ui/react/menu`. Supports items, checkbox items, radio groups, labels, and separators.
|
|
409
648
|
|
|
410
|
-
| Sub-component
|
|
411
|
-
|
|
412
|
-
| `DropdownMenu.Root`
|
|
413
|
-
| `DropdownMenu.Trigger`
|
|
414
|
-
| `DropdownMenu.Content`
|
|
415
|
-
| `DropdownMenu.Item`
|
|
649
|
+
| Sub-component | Description |
|
|
650
|
+
| --------------------------- | ---------------------------------------- |
|
|
651
|
+
| `DropdownMenu.Root` | The state container. |
|
|
652
|
+
| `DropdownMenu.Trigger` | The element that opens the menu. |
|
|
653
|
+
| `DropdownMenu.Content` | The portalled popup. |
|
|
654
|
+
| `DropdownMenu.Item` | A selectable row. |
|
|
416
655
|
| `DropdownMenu.CheckboxItem` | A toggleable row with a check indicator. |
|
|
417
|
-
| `DropdownMenu.RadioGroup`
|
|
418
|
-
| `DropdownMenu.RadioItem`
|
|
419
|
-
| `DropdownMenu.Group`
|
|
420
|
-
| `DropdownMenu.Label`
|
|
421
|
-
| `DropdownMenu.Separator`
|
|
656
|
+
| `DropdownMenu.RadioGroup` | Wrapper for radio items. |
|
|
657
|
+
| `DropdownMenu.RadioItem` | A single radio choice. |
|
|
658
|
+
| `DropdownMenu.Group` | Logical group of items. |
|
|
659
|
+
| `DropdownMenu.Label` | Uppercase group label. |
|
|
660
|
+
| `DropdownMenu.Separator` | Thin horizontal divider. |
|
|
422
661
|
|
|
423
662
|
**`DropdownMenu.Content` props:**
|
|
424
663
|
|
|
425
|
-
| Prop
|
|
426
|
-
|
|
427
|
-
| `sideOffset` | `number`
|
|
428
|
-
| `align`
|
|
429
|
-
| `className`
|
|
430
|
-
| `...props`
|
|
664
|
+
| Prop | Type | Default | Description |
|
|
665
|
+
| ------------ | ------------------------------ | --------- | ---------------------------------- |
|
|
666
|
+
| `sideOffset` | `number` | `6` | Distance in px from the trigger. |
|
|
667
|
+
| `align` | `"start" \| "center" \| "end"` | `"start"` | Alignment relative to the trigger. |
|
|
668
|
+
| `className` | `string` | — | Extra classes on the popup. |
|
|
669
|
+
| `...props` | Base UI `Menu.Popup` props | — | Spread to the popup. |
|
|
431
670
|
|
|
432
671
|
```tsx
|
|
433
672
|
<DropdownMenu.Root>
|
|
@@ -448,12 +687,12 @@ Compound component built on `@base-ui/react/menu`. Supports items, checkbox item
|
|
|
448
687
|
|
|
449
688
|
Wraps `@base-ui/react/input`. Includes built-in invalid styling via `aria-invalid`.
|
|
450
689
|
|
|
451
|
-
| Prop
|
|
452
|
-
|
|
453
|
-
| `size`
|
|
454
|
-
| `invalid`
|
|
455
|
-
| `className` | `string`
|
|
456
|
-
| `...props`
|
|
690
|
+
| Prop | Type | Default | Description |
|
|
691
|
+
| ----------- | ------------------------------------ | ------- | ----------------------------------------------------------------------------------------- |
|
|
692
|
+
| `size` | `"sm" \| "md" \| "lg"` | `"md"` | Density-aware control height. |
|
|
693
|
+
| `invalid` | `boolean` | — | Sets `aria-invalid` and applies the danger border + focus ring. |
|
|
694
|
+
| `className` | `string` | — | Extra classes. |
|
|
695
|
+
| `...props` | Base UI `Input` props (minus `size`) | — | All native input attributes: `value`, `placeholder`, `type`, `onChange`, `disabled`, etc. |
|
|
457
696
|
|
|
458
697
|
```tsx
|
|
459
698
|
<Input placeholder="Email" />
|
|
@@ -466,22 +705,22 @@ Wraps `@base-ui/react/input`. Includes built-in invalid styling via `aria-invali
|
|
|
466
705
|
|
|
467
706
|
Compound component built on `@base-ui/react/dialog`. Renders into a portal, with backdrop blur and scale-in animation.
|
|
468
707
|
|
|
469
|
-
| Sub-component
|
|
470
|
-
|
|
471
|
-
| `Modal.Root`
|
|
472
|
-
| `Modal.Trigger`
|
|
473
|
-
| `Modal.Close`
|
|
474
|
-
| `Modal.Content`
|
|
475
|
-
| `Modal.Title`
|
|
476
|
-
| `Modal.Description` | Sub-text under the title.
|
|
708
|
+
| Sub-component | Description |
|
|
709
|
+
| ------------------- | ---------------------------------- |
|
|
710
|
+
| `Modal.Root` | Open-state container. |
|
|
711
|
+
| `Modal.Trigger` | Element that opens the modal. |
|
|
712
|
+
| `Modal.Close` | Element that closes the modal. |
|
|
713
|
+
| `Modal.Content` | The portalled popup with backdrop. |
|
|
714
|
+
| `Modal.Title` | Heading text. |
|
|
715
|
+
| `Modal.Description` | Sub-text under the title. |
|
|
477
716
|
|
|
478
717
|
**`Modal.Content` props:**
|
|
479
718
|
|
|
480
|
-
| Prop
|
|
481
|
-
|
|
482
|
-
| `className`
|
|
483
|
-
| `backdropClassName` | `string`
|
|
484
|
-
| `...props`
|
|
719
|
+
| Prop | Type | Default | Description |
|
|
720
|
+
| ------------------- | ---------------------------- | ------- | ------------------------------ |
|
|
721
|
+
| `className` | `string` | — | Extra classes on the popup. |
|
|
722
|
+
| `backdropClassName` | `string` | — | Extra classes on the backdrop. |
|
|
723
|
+
| `...props` | Base UI `Dialog.Popup` props | — | Spread to the popup. |
|
|
485
724
|
|
|
486
725
|
`Modal.Title` and `Modal.Description` accept their Base UI props plus `className`.
|
|
487
726
|
|
|
@@ -491,7 +730,14 @@ Compound component built on `@base-ui/react/dialog`. Renders into a portal, with
|
|
|
491
730
|
<Modal.Content>
|
|
492
731
|
<Modal.Title>Delete project?</Modal.Title>
|
|
493
732
|
<Modal.Description>This action cannot be undone.</Modal.Description>
|
|
494
|
-
<div
|
|
733
|
+
<div
|
|
734
|
+
style={{
|
|
735
|
+
marginTop: "1rem",
|
|
736
|
+
display: "flex",
|
|
737
|
+
justifyContent: "flex-end",
|
|
738
|
+
gap: "0.5rem",
|
|
739
|
+
}}
|
|
740
|
+
>
|
|
495
741
|
<Modal.Close render={<Button variant="secondary">Cancel</Button>} />
|
|
496
742
|
<Button variant="destructive">Delete</Button>
|
|
497
743
|
</div>
|
|
@@ -501,29 +747,80 @@ Compound component built on `@base-ui/react/dialog`. Renders into a portal, with
|
|
|
501
747
|
|
|
502
748
|
---
|
|
503
749
|
|
|
750
|
+
### Popover
|
|
751
|
+
|
|
752
|
+
Compound component built on `@base-ui/react/popover`. Like `Tooltip`, but for richer content (forms, lists, multi-element panels) that stays open until dismissed.
|
|
753
|
+
|
|
754
|
+
| Sub-component | Description |
|
|
755
|
+
| ---------------------------------------------------- | ------------------------------------------------------------------------------------ |
|
|
756
|
+
| `Popover.Root` | State container. |
|
|
757
|
+
| `Popover.Trigger` | The element that opens the popover. |
|
|
758
|
+
| `Popover.Content` | The portalled popup — pre-wires Portal → Positioner → Popup, plus an optional arrow. |
|
|
759
|
+
| `Popover.Title` / `Popover.Description` | Accessible heading / description, wired to ARIA via Base UI. |
|
|
760
|
+
| `Popover.Close` | Closes the popover when clicked. |
|
|
761
|
+
| `Popover.Header` / `Popover.Body` / `Popover.Footer` | Layout slots for `Content`'s children. |
|
|
762
|
+
|
|
763
|
+
**`Popover.Content` props:**
|
|
764
|
+
|
|
765
|
+
| Prop | Type | Default | Description |
|
|
766
|
+
| ------------ | ---------------------------------------- | ---------- | ---------------------------------------- |
|
|
767
|
+
| `side` | `"top" \| "right" \| "bottom" \| "left"` | `"bottom"` | Preferred side. |
|
|
768
|
+
| `align` | `"start" \| "center" \| "end"` | `"center"` | Alignment along the side. |
|
|
769
|
+
| `sideOffset` | `number` | `10` | Distance from the trigger. |
|
|
770
|
+
| `showArrow` | `boolean` | `true` | Renders a caret pointing at the trigger. |
|
|
771
|
+
| `className` | `string` | — | Extra classes on the popup. |
|
|
772
|
+
|
|
773
|
+
```tsx
|
|
774
|
+
<Popover.Root>
|
|
775
|
+
<Popover.Trigger render={<Button variant="secondary">Filters</Button>} />
|
|
776
|
+
<Popover.Content>
|
|
777
|
+
<Popover.Header>
|
|
778
|
+
<Popover.Title>Column visibility</Popover.Title>
|
|
779
|
+
</Popover.Header>
|
|
780
|
+
<Popover.Body>…</Popover.Body>
|
|
781
|
+
<Popover.Footer>
|
|
782
|
+
<Popover.Close
|
|
783
|
+
render={
|
|
784
|
+
<Button size="sm" variant="ghost">
|
|
785
|
+
Reset
|
|
786
|
+
</Button>
|
|
787
|
+
}
|
|
788
|
+
/>
|
|
789
|
+
<Button size="sm">Apply</Button>
|
|
790
|
+
</Popover.Footer>
|
|
791
|
+
</Popover.Content>
|
|
792
|
+
</Popover.Root>
|
|
793
|
+
```
|
|
794
|
+
|
|
795
|
+
---
|
|
796
|
+
|
|
504
797
|
### Radio / RadioGroup
|
|
505
798
|
|
|
506
799
|
Wraps `@base-ui/react/radio` and `@base-ui/react/radio-group`.
|
|
507
800
|
|
|
508
801
|
**`Radio` props:**
|
|
509
802
|
|
|
510
|
-
| Prop
|
|
511
|
-
|
|
512
|
-
| `size`
|
|
513
|
-
| `className` | `string`
|
|
514
|
-
| `...props`
|
|
803
|
+
| Prop | Type | Default | Description |
|
|
804
|
+
| ----------- | -------------------------- | ------- | ------------------------- |
|
|
805
|
+
| `size` | `"sm" \| "md" \| "lg"` | `"md"` | 16 / 18 / 20 px. |
|
|
806
|
+
| `className` | `string` | — | Extra classes. |
|
|
807
|
+
| `...props` | Base UI `Radio.Root` props | — | `value`, `disabled`, etc. |
|
|
515
808
|
|
|
516
809
|
**`RadioGroup` props:**
|
|
517
810
|
|
|
518
|
-
| Prop
|
|
519
|
-
|
|
520
|
-
| `className` | `string`
|
|
521
|
-
| `...props`
|
|
811
|
+
| Prop | Type | Default | Description |
|
|
812
|
+
| ----------- | -------------------------- | ------- | ----------------------------------------- |
|
|
813
|
+
| `className` | `string` | — | Override the default vertical stack. |
|
|
814
|
+
| `...props` | Base UI `RadioGroup` props | — | `value`, `defaultValue`, `onValueChange`. |
|
|
522
815
|
|
|
523
816
|
```tsx
|
|
524
817
|
<RadioGroup defaultValue="email">
|
|
525
|
-
<label
|
|
526
|
-
|
|
818
|
+
<label>
|
|
819
|
+
<Radio value="email" /> Email
|
|
820
|
+
</label>
|
|
821
|
+
<label>
|
|
822
|
+
<Radio value="sms" /> SMS
|
|
823
|
+
</label>
|
|
527
824
|
</RadioGroup>
|
|
528
825
|
```
|
|
529
826
|
|
|
@@ -533,19 +830,19 @@ Wraps `@base-ui/react/radio` and `@base-ui/react/radio-group`.
|
|
|
533
830
|
|
|
534
831
|
Compound component built on `@base-ui/react/toggle-group` (single-select). The selected item rises as a white floating pill.
|
|
535
832
|
|
|
536
|
-
| Sub-component
|
|
537
|
-
|
|
833
|
+
| Sub-component | Description |
|
|
834
|
+
| ------------------ | ----------------- |
|
|
538
835
|
| `Segmented` (root) | The toggle group. |
|
|
539
|
-
| `Segmented.Item`
|
|
836
|
+
| `Segmented.Item` | A single segment. |
|
|
540
837
|
|
|
541
838
|
**`Segmented` props:**
|
|
542
839
|
|
|
543
|
-
| Prop
|
|
544
|
-
|
|
545
|
-
| `value`
|
|
546
|
-
| `defaultValue`
|
|
547
|
-
| `onValueChange` | `(value: string) => void` | —
|
|
548
|
-
| `size`
|
|
840
|
+
| Prop | Type | Default | Description |
|
|
841
|
+
| --------------- | ------------------------- | ------- | --------------------------- |
|
|
842
|
+
| `value` | `string` | — | Controlled selected value. |
|
|
843
|
+
| `defaultValue` | `string` | — | Uncontrolled initial value. |
|
|
844
|
+
| `onValueChange` | `(value: string) => void` | — | Fired with the new value. |
|
|
845
|
+
| `size` | `"sm" \| "md" \| "lg"` | `"md"` | 24 / 28 / 32 px. |
|
|
549
846
|
|
|
550
847
|
```tsx
|
|
551
848
|
<Segmented value={range} onValueChange={setRange}>
|
|
@@ -561,13 +858,13 @@ Compound component built on `@base-ui/react/toggle-group` (single-select). The s
|
|
|
561
858
|
|
|
562
859
|
Compound component built on `@base-ui/react/select`.
|
|
563
860
|
|
|
564
|
-
| Sub-component
|
|
565
|
-
|
|
566
|
-
| `Select.Root`
|
|
567
|
-
| `Select.Trigger` | The clickable trigger; renders a chevron icon.
|
|
568
|
-
| `Select.Value`
|
|
569
|
-
| `Select.Content` | The portalled popup.
|
|
570
|
-
| `Select.Item`
|
|
861
|
+
| Sub-component | Description |
|
|
862
|
+
| ---------------- | ------------------------------------------------------ |
|
|
863
|
+
| `Select.Root` | State container (`value`, `onValueChange`). |
|
|
864
|
+
| `Select.Trigger` | The clickable trigger; renders a chevron icon. |
|
|
865
|
+
| `Select.Value` | The selected value's display. |
|
|
866
|
+
| `Select.Content` | The portalled popup. |
|
|
867
|
+
| `Select.Item` | A selectable row with a check indicator when selected. |
|
|
571
868
|
|
|
572
869
|
**`Select.Trigger` props:** `size` = `"sm" | "md" | "lg"` (default `"md"`), plus `className`.
|
|
573
870
|
|
|
@@ -594,11 +891,11 @@ Compound component built on `@base-ui/react/select`.
|
|
|
594
891
|
|
|
595
892
|
Loading placeholder with a pulse animation.
|
|
596
893
|
|
|
597
|
-
| Prop
|
|
598
|
-
|
|
599
|
-
| `shape`
|
|
600
|
-
| `className` | `string`
|
|
601
|
-
| `...props`
|
|
894
|
+
| Prop | Type | Default | Description |
|
|
895
|
+
| ----------- | -------------------------------- | -------- | ---------------------------------------------- |
|
|
896
|
+
| `shape` | `"line" \| "circle" \| "block"` | `"line"` | Default dimensions and radius. |
|
|
897
|
+
| `className` | `string` | — | Override width/height/radius via your own CSS. |
|
|
898
|
+
| `...props` | `HTMLAttributes<HTMLDivElement>` | — | Native div attributes. |
|
|
602
899
|
|
|
603
900
|
```tsx
|
|
604
901
|
<Skeleton />
|
|
@@ -612,11 +909,11 @@ Loading placeholder with a pulse animation.
|
|
|
612
909
|
|
|
613
910
|
Compound floating-pill component for status indicators. Intent drives chip + label color via CSS custom properties.
|
|
614
911
|
|
|
615
|
-
| Sub-component
|
|
616
|
-
|
|
617
|
-
| `StatusPill` (root)
|
|
912
|
+
| Sub-component | Description |
|
|
913
|
+
| ---------------------- | ----------------------------------------------------------- |
|
|
914
|
+
| `StatusPill` (root) | The pill surface. |
|
|
618
915
|
| `StatusPill.Indicator` | The leading colored chip. Children render an optional icon. |
|
|
619
|
-
| `StatusPill.Label`
|
|
916
|
+
| `StatusPill.Label` | The colored text label. |
|
|
620
917
|
|
|
621
918
|
**`StatusPill` props:** `intent` = `"neutral" | "success" | "warning" | "danger" | "info"` (default `"neutral"`).
|
|
622
919
|
|
|
@@ -633,11 +930,11 @@ Compound floating-pill component for status indicators. Intent drives chip + lab
|
|
|
633
930
|
|
|
634
931
|
Wraps `@base-ui/react/switch` — a thumb that slides on `data-[checked]`.
|
|
635
932
|
|
|
636
|
-
| Prop
|
|
637
|
-
|
|
638
|
-
| `size`
|
|
639
|
-
| `className` | `string`
|
|
640
|
-
| `...props`
|
|
933
|
+
| Prop | Type | Default | Description |
|
|
934
|
+
| ----------- | --------------------------- | ------- | ----------------------------------------------------------- |
|
|
935
|
+
| `size` | `"sm" \| "md" \| "lg"` | `"md"` | 16 / 20 / 24 px tall. |
|
|
936
|
+
| `className` | `string` | — | Extra classes on the root. |
|
|
937
|
+
| `...props` | Base UI `Switch.Root` props | — | `checked`, `defaultChecked`, `onCheckedChange`, `disabled`. |
|
|
641
938
|
|
|
642
939
|
```tsx
|
|
643
940
|
<Switch defaultChecked />
|
|
@@ -650,12 +947,12 @@ Wraps `@base-ui/react/switch` — a thumb that slides on `data-[checked]`.
|
|
|
650
947
|
|
|
651
948
|
Compound component built on `@base-ui/react/tabs`. The list renders an animated indicator that slides between active tabs.
|
|
652
949
|
|
|
653
|
-
| Sub-component | Description
|
|
654
|
-
|
|
950
|
+
| Sub-component | Description |
|
|
951
|
+
| ------------- | --------------------------------------------------------------- |
|
|
655
952
|
| `Tabs` (root) | State container; pass `value`, `defaultValue`, `onValueChange`. |
|
|
656
|
-
| `Tabs.List`
|
|
657
|
-
| `Tabs.Tab`
|
|
658
|
-
| `Tabs.Panel`
|
|
953
|
+
| `Tabs.List` | Horizontal tab strip with a sliding indicator. |
|
|
954
|
+
| `Tabs.Tab` | A single tab button. |
|
|
955
|
+
| `Tabs.Panel` | The panel paired with a tab `value`. |
|
|
659
956
|
|
|
660
957
|
All sub-components accept their Base UI props plus `className`.
|
|
661
958
|
|
|
@@ -678,12 +975,12 @@ All sub-components accept their Base UI props plus `className`.
|
|
|
678
975
|
|
|
679
976
|
A thin styled `<textarea>` mirroring Input's API.
|
|
680
977
|
|
|
681
|
-
| Prop
|
|
682
|
-
|
|
683
|
-
| `size`
|
|
684
|
-
| `invalid`
|
|
685
|
-
| `className` | `string`
|
|
686
|
-
| `...props`
|
|
978
|
+
| Prop | Type | Default | Description |
|
|
979
|
+
| ----------- | --------------------------------------- | ------- | --------------------------------------------------------------- |
|
|
980
|
+
| `size` | `"sm" \| "md" \| "lg"` | `"md"` | Density-aware control padding. |
|
|
981
|
+
| `invalid` | `boolean` | — | Sets `aria-invalid` and applies the danger border + focus ring. |
|
|
982
|
+
| `className` | `string` | — | Extra classes. |
|
|
983
|
+
| `...props` | `TextareaHTMLAttributes` (minus `size`) | — | All native textarea attributes. |
|
|
687
984
|
|
|
688
985
|
```tsx
|
|
689
986
|
<Textarea placeholder="Notes" rows={4} />
|
|
@@ -696,12 +993,12 @@ A thin styled `<textarea>` mirroring Input's API.
|
|
|
696
993
|
|
|
697
994
|
Built on `@base-ui/react/toast`. Provides a `<Toast.Provider>` boundary, a `<Toast.Viewport>` for positioning, a pre-built `<Toast.Toaster>` that renders the queue, and the `useToast()` hook to push toasts.
|
|
698
995
|
|
|
699
|
-
| Sub-component
|
|
700
|
-
|
|
701
|
-
| `Toast.Provider` | Wrap your app to enable toasts.
|
|
702
|
-
| `Toast.Viewport` | Positioned region where toasts mount (bottom-right by default).
|
|
703
|
-
| `Toast.Toaster`
|
|
704
|
-
| `useToast()`
|
|
996
|
+
| Sub-component | Description |
|
|
997
|
+
| ---------------- | ------------------------------------------------------------------------ |
|
|
998
|
+
| `Toast.Provider` | Wrap your app to enable toasts. |
|
|
999
|
+
| `Toast.Viewport` | Positioned region where toasts mount (bottom-right by default). |
|
|
1000
|
+
| `Toast.Toaster` | Pre-styled queue renderer — drop this inside `Provider`. |
|
|
1001
|
+
| `useToast()` | Hook returning Base UI's toast manager (`.add({ title, description })`). |
|
|
705
1002
|
|
|
706
1003
|
```tsx
|
|
707
1004
|
import { Toast, useToast, Button } from "@bubble-design-system/ui";
|
|
@@ -718,7 +1015,11 @@ function Root({ children }) {
|
|
|
718
1015
|
function SaveButton() {
|
|
719
1016
|
const toast = useToast();
|
|
720
1017
|
return (
|
|
721
|
-
<Button
|
|
1018
|
+
<Button
|
|
1019
|
+
onClick={() =>
|
|
1020
|
+
toast.add({ title: "Saved", description: "Changes are live." })
|
|
1021
|
+
}
|
|
1022
|
+
>
|
|
722
1023
|
Save
|
|
723
1024
|
</Button>
|
|
724
1025
|
);
|
|
@@ -731,21 +1032,21 @@ function SaveButton() {
|
|
|
731
1032
|
|
|
732
1033
|
Compound component built on `@base-ui/react/tooltip`. Requires a `Tooltip.Provider` ancestor (typically once at the app root).
|
|
733
1034
|
|
|
734
|
-
| Sub-component
|
|
735
|
-
|
|
736
|
-
| `Tooltip.Provider` | App-level provider.
|
|
737
|
-
| `Tooltip.Root`
|
|
738
|
-
| `Tooltip.Trigger`
|
|
739
|
-
| `Tooltip.Content`
|
|
1035
|
+
| Sub-component | Description |
|
|
1036
|
+
| ------------------ | ------------------------------- |
|
|
1037
|
+
| `Tooltip.Provider` | App-level provider. |
|
|
1038
|
+
| `Tooltip.Root` | Single tooltip state container. |
|
|
1039
|
+
| `Tooltip.Trigger` | The hovered/focused element. |
|
|
1040
|
+
| `Tooltip.Content` | The portalled popup. |
|
|
740
1041
|
|
|
741
1042
|
**`Tooltip.Content` props:**
|
|
742
1043
|
|
|
743
|
-
| Prop
|
|
744
|
-
|
|
745
|
-
| `side`
|
|
746
|
-
| `align`
|
|
747
|
-
| `sideOffset` | `number`
|
|
748
|
-
| `className`
|
|
1044
|
+
| Prop | Type | Default | Description |
|
|
1045
|
+
| ------------ | ---------------------------------------- | ---------- | --------------------------- |
|
|
1046
|
+
| `side` | `"top" \| "bottom" \| "left" \| "right"` | `"top"` | Preferred side. |
|
|
1047
|
+
| `align` | `"start" \| "center" \| "end"` | `"center"` | Alignment along the side. |
|
|
1048
|
+
| `sideOffset` | `number` | `6` | Distance from the trigger. |
|
|
1049
|
+
| `className` | `string` | — | Extra classes on the popup. |
|
|
749
1050
|
|
|
750
1051
|
```tsx
|
|
751
1052
|
<Tooltip.Provider>
|
|
@@ -773,71 +1074,74 @@ cn("my-card", isActive && "my-card--active", className);
|
|
|
773
1074
|
|
|
774
1075
|
## Design tokens
|
|
775
1076
|
|
|
1077
|
+
> **About to write `var(--color-bg-*)` / `var(--radius-*)` / `var(--shadow-*)` on a hand-authored `<div>`?**
|
|
1078
|
+
> Tokens are how you _theme_ Bubble's components and the escape hatch for genuine gaps — they are not a second, parallel "build it yourself" API. Check [Common UI Patterns](#common-ui-patterns) first; the surface/pill/menu/banner you're about to build very likely already exists as a themed, accessible component.
|
|
1079
|
+
|
|
776
1080
|
All tokens are CSS custom properties defined in `src/tokens.css`. Reference them directly in your CSS with `var(--…)`. The semantic tokens (those prefixed `--color-bg-*`, `--color-text-*`, `--color-border-*`) re-resolve automatically when an ancestor `data-*` attribute changes.
|
|
777
1081
|
|
|
778
1082
|
### Color tokens
|
|
779
1083
|
|
|
780
1084
|
Semantic colors map to primitive palettes and are remapped by `[data-theme]`, `[data-gray]`, and `[data-brand]`.
|
|
781
1085
|
|
|
782
|
-
| Token
|
|
783
|
-
|
|
784
|
-
| `--color-bg-primary`
|
|
785
|
-
| `--color-bg-secondary`
|
|
786
|
-
| `--color-bg-tertiary`
|
|
787
|
-
| `--color-bg-inverse`
|
|
788
|
-
| `--color-bg-brand`
|
|
789
|
-
| `--color-bg-brand-hover`
|
|
790
|
-
| `--color-bg-brand-active`
|
|
791
|
-
| `--color-bg-brand-subtle`
|
|
792
|
-
| `--color-bg-success`
|
|
793
|
-
| `--color-bg-success-strong` | Solid success fill.
|
|
794
|
-
| `--color-bg-warning`
|
|
795
|
-
| `--color-bg-warning-strong` | Solid warning fill.
|
|
796
|
-
| `--color-bg-danger`
|
|
797
|
-
| `--color-bg-danger-strong`
|
|
798
|
-
| `--color-bg-danger-hover`
|
|
799
|
-
| `--color-bg-info`
|
|
800
|
-
| `--color-bg-hover`
|
|
801
|
-
| `--color-bg-pressed`
|
|
802
|
-
| `--color-bg-disabled`
|
|
803
|
-
| `--color-text-primary`
|
|
804
|
-
| `--color-text-secondary`
|
|
805
|
-
| `--color-text-tertiary`
|
|
806
|
-
| `--color-text-disabled`
|
|
807
|
-
| `--color-text-inverse`
|
|
808
|
-
| `--color-text-brand`
|
|
809
|
-
| `--color-text-success`
|
|
810
|
-
| `--color-text-warning`
|
|
811
|
-
| `--color-text-danger`
|
|
812
|
-
| `--color-text-on-brand`
|
|
813
|
-
| `--color-text-on-danger`
|
|
814
|
-
| `--color-text-on-success`
|
|
815
|
-
| `--color-border-primary`
|
|
816
|
-
| `--color-border-secondary`
|
|
817
|
-
| `--color-border-tertiary`
|
|
818
|
-
| `--color-border-brand`
|
|
819
|
-
| `--color-border-success`
|
|
820
|
-
| `--color-border-warning`
|
|
821
|
-
| `--color-border-danger`
|
|
822
|
-
| `--color-border-focus`
|
|
1086
|
+
| Token | Purpose |
|
|
1087
|
+
| --------------------------- | ------------------------------------------------ |
|
|
1088
|
+
| `--color-bg-primary` | Page background. |
|
|
1089
|
+
| `--color-bg-secondary` | Secondary surface (cards on page). |
|
|
1090
|
+
| `--color-bg-tertiary` | Tertiary surface (inset wells). |
|
|
1091
|
+
| `--color-bg-inverse` | Inverted surface (tooltip, toast). |
|
|
1092
|
+
| `--color-bg-brand` | Brand primary fill. |
|
|
1093
|
+
| `--color-bg-brand-hover` | Brand hover state. |
|
|
1094
|
+
| `--color-bg-brand-active` | Brand pressed state. |
|
|
1095
|
+
| `--color-bg-brand-subtle` | Tinted brand surface (info backgrounds, badges). |
|
|
1096
|
+
| `--color-bg-success` | Soft success surface. |
|
|
1097
|
+
| `--color-bg-success-strong` | Solid success fill. |
|
|
1098
|
+
| `--color-bg-warning` | Soft warning surface. |
|
|
1099
|
+
| `--color-bg-warning-strong` | Solid warning fill. |
|
|
1100
|
+
| `--color-bg-danger` | Soft danger surface. |
|
|
1101
|
+
| `--color-bg-danger-strong` | Solid danger fill (destructive buttons). |
|
|
1102
|
+
| `--color-bg-danger-hover` | Danger hover state. |
|
|
1103
|
+
| `--color-bg-info` | Info alert surface. |
|
|
1104
|
+
| `--color-bg-hover` | Neutral hover. |
|
|
1105
|
+
| `--color-bg-pressed` | Neutral pressed. |
|
|
1106
|
+
| `--color-bg-disabled` | Disabled surface. |
|
|
1107
|
+
| `--color-text-primary` | Body text. |
|
|
1108
|
+
| `--color-text-secondary` | Supporting text. |
|
|
1109
|
+
| `--color-text-tertiary` | Placeholder, hints. |
|
|
1110
|
+
| `--color-text-disabled` | Disabled text. |
|
|
1111
|
+
| `--color-text-inverse` | Text on `bg-inverse`. |
|
|
1112
|
+
| `--color-text-brand` | Brand-colored text (links). |
|
|
1113
|
+
| `--color-text-success` | Success copy. |
|
|
1114
|
+
| `--color-text-warning` | Warning copy. |
|
|
1115
|
+
| `--color-text-danger` | Error copy. |
|
|
1116
|
+
| `--color-text-on-brand` | Text on `bg-brand`. |
|
|
1117
|
+
| `--color-text-on-danger` | Text on `bg-danger-strong`. |
|
|
1118
|
+
| `--color-text-on-success` | Text on `bg-success-strong`. |
|
|
1119
|
+
| `--color-border-primary` | Default form/control border. |
|
|
1120
|
+
| `--color-border-secondary` | Section dividers, cards. |
|
|
1121
|
+
| `--color-border-tertiary` | Subtle inner dividers. |
|
|
1122
|
+
| `--color-border-brand` | Selected/active accent. |
|
|
1123
|
+
| `--color-border-success` | Success accent. |
|
|
1124
|
+
| `--color-border-warning` | Warning accent. |
|
|
1125
|
+
| `--color-border-danger` | Error accent (invalid inputs). |
|
|
1126
|
+
| `--color-border-focus` | Focus ring color. |
|
|
823
1127
|
|
|
824
1128
|
### Primitive palettes
|
|
825
1129
|
|
|
826
1130
|
These are the raw color swatches that the semantic tokens reference. You usually shouldn't touch them directly, but they're exposed if you need to.
|
|
827
1131
|
|
|
828
|
-
| Family
|
|
829
|
-
|
|
830
|
-
| `--slate-*`
|
|
831
|
-
| `--neutral-*`
|
|
832
|
-
| `--stone-*`
|
|
833
|
-
| `--blue-*`
|
|
834
|
-
| `--violet-*`
|
|
835
|
-
| `--emerald-*`
|
|
836
|
-
| `--orange-*`
|
|
837
|
-
| `--green-*`
|
|
838
|
-
| `--amber-*`
|
|
839
|
-
| `--red-*`
|
|
840
|
-
| `--white`, `--black` | —
|
|
1132
|
+
| Family | Stops | Notes |
|
|
1133
|
+
| -------------------- | ------ | ------------------------------ |
|
|
1134
|
+
| `--slate-*` | 50–950 | Default gray family. |
|
|
1135
|
+
| `--neutral-*` | 50–950 | True neutral (no temperature). |
|
|
1136
|
+
| `--stone-*` | 50–950 | Warm gray. |
|
|
1137
|
+
| `--blue-*` | 50–950 | Brand option. |
|
|
1138
|
+
| `--violet-*` | 50–950 | Brand option. |
|
|
1139
|
+
| `--emerald-*` | 50–950 | Brand option. |
|
|
1140
|
+
| `--orange-*` | 50–950 | Brand option. |
|
|
1141
|
+
| `--green-*` | 50–950 | Success palette. |
|
|
1142
|
+
| `--amber-*` | 50–950 | Warning palette. |
|
|
1143
|
+
| `--red-*` | 50–950 | Danger palette. |
|
|
1144
|
+
| `--white`, `--black` | — | Pure values. |
|
|
841
1145
|
|
|
842
1146
|
Aliases follow the active `data-*` attribute: `--gray-*` resolves to whichever gray family is selected, `--brand-*` to whichever brand. The `mono` and `teal` brands have special-case treatment for contrast on light/dark themes.
|
|
843
1147
|
|
|
@@ -845,15 +1149,15 @@ Aliases follow the active `data-*` attribute: `--gray-*` resolves to whichever g
|
|
|
845
1149
|
|
|
846
1150
|
Selected by `[data-radius]`. Each scale rewrites the same custom properties.
|
|
847
1151
|
|
|
848
|
-
| Token
|
|
849
|
-
|
|
850
|
-
| `--radius-xs` | 2px
|
|
851
|
-
| `--radius-sm` | 4px
|
|
852
|
-
| `--radius-md` | 6px
|
|
853
|
-
| `--radius-lg` | 8px
|
|
854
|
-
| `--radius-xl` | 12px
|
|
855
|
-
| `--radius-2xl` | 16px
|
|
856
|
-
| `--radius-full` | 9999px
|
|
1152
|
+
| Token | default | sharp | soft | pill |
|
|
1153
|
+
| --------------- | ------- | ------ | ------ | ------ |
|
|
1154
|
+
| `--radius-xs` | 2px | 0px | 4px | 4px |
|
|
1155
|
+
| `--radius-sm` | 4px | 1px | 8px | 9999px |
|
|
1156
|
+
| `--radius-md` | 6px | 2px | 12px | 9999px |
|
|
1157
|
+
| `--radius-lg` | 8px | 3px | 14px | 9999px |
|
|
1158
|
+
| `--radius-xl` | 12px | 4px | 18px | 18px |
|
|
1159
|
+
| `--radius-2xl` | 16px | 6px | 24px | 22px |
|
|
1160
|
+
| `--radius-full` | 9999px | 9999px | 9999px | 9999px |
|
|
857
1161
|
|
|
858
1162
|
Plus `--ctrl-radius` — the control radius used by Button/Input/Select. Pills under `[data-tone="soft"]`, `--radius-md` elsewhere.
|
|
859
1163
|
|
|
@@ -861,33 +1165,33 @@ Plus `--ctrl-radius` — the control radius used by Button/Input/Select. Pills u
|
|
|
861
1165
|
|
|
862
1166
|
Light theme uses cool slate tints; dark theme uses opaque black. The `soft` tone adds an inset white top-highlight on md/lg/xl. The focus ring tracks the brand color.
|
|
863
1167
|
|
|
864
|
-
| Token
|
|
865
|
-
|
|
866
|
-
| `--shadow-xs`
|
|
867
|
-
| `--shadow-sm`
|
|
868
|
-
| `--shadow-md`
|
|
869
|
-
| `--shadow-lg`
|
|
870
|
-
| `--shadow-xl`
|
|
1168
|
+
| Token | Purpose |
|
|
1169
|
+
| ---------------- | -------------------------------- |
|
|
1170
|
+
| `--shadow-xs` | Hairline lift. |
|
|
1171
|
+
| `--shadow-sm` | Subtle card. |
|
|
1172
|
+
| `--shadow-md` | Standard card. |
|
|
1173
|
+
| `--shadow-lg` | Popover, dropdown. |
|
|
1174
|
+
| `--shadow-xl` | Modal. |
|
|
871
1175
|
| `--shadow-focus` | Focus ring (3–4px brand-tinted). |
|
|
872
1176
|
|
|
873
1177
|
### Typography
|
|
874
1178
|
|
|
875
|
-
| Token
|
|
876
|
-
|
|
877
|
-
| `--font-size-xs`
|
|
878
|
-
| `--font-size-sm`
|
|
879
|
-
| `--font-size-md`
|
|
880
|
-
| `--font-size-lg`
|
|
881
|
-
| `--font-size-xl`
|
|
882
|
-
| `--font-size-2xl`
|
|
883
|
-
| `--font-size-3xl`
|
|
884
|
-
| `--font-size-4xl`
|
|
885
|
-
| `--font-size-5xl`
|
|
886
|
-
| `--font-size-6xl`
|
|
887
|
-
| `--line-height-tight` / `snug` / `normal` / `relaxed`
|
|
888
|
-
| `--letter-tight` / `snug` / `normal` / `wide`
|
|
889
|
-
| `--font-weight-regular` / `medium` / `semibold` / `bold` | 400 / 500 / 600 / 700
|
|
890
|
-
| `--font-sans` / `--font-mono`
|
|
1179
|
+
| Token | Value |
|
|
1180
|
+
| -------------------------------------------------------- | -------------------------------- |
|
|
1181
|
+
| `--font-size-xs` | 0.75rem |
|
|
1182
|
+
| `--font-size-sm` | 0.875rem |
|
|
1183
|
+
| `--font-size-md` | 1rem |
|
|
1184
|
+
| `--font-size-lg` | 1.125rem |
|
|
1185
|
+
| `--font-size-xl` | 1.25rem |
|
|
1186
|
+
| `--font-size-2xl` | 1.5rem |
|
|
1187
|
+
| `--font-size-3xl` | 1.875rem |
|
|
1188
|
+
| `--font-size-4xl` | 2.25rem |
|
|
1189
|
+
| `--font-size-5xl` | 3rem |
|
|
1190
|
+
| `--font-size-6xl` | 3.75rem |
|
|
1191
|
+
| `--line-height-tight` / `snug` / `normal` / `relaxed` | 1.15 / 1.3 / 1.5 / 1.65 |
|
|
1192
|
+
| `--letter-tight` / `snug` / `normal` / `wide` | -0.022em / -0.012em / 0 / 0.04em |
|
|
1193
|
+
| `--font-weight-regular` / `medium` / `semibold` / `bold` | 400 / 500 / 600 / 700 |
|
|
1194
|
+
| `--font-sans` / `--font-mono` | Set by `[data-font]` |
|
|
891
1195
|
|
|
892
1196
|
### Spacing
|
|
893
1197
|
|
|
@@ -897,30 +1201,30 @@ Light theme uses cool slate tints; dark theme uses opaque black. The `soft` tone
|
|
|
897
1201
|
|
|
898
1202
|
Selected by `[data-density]`.
|
|
899
1203
|
|
|
900
|
-
| Token
|
|
901
|
-
|
|
902
|
-
| `--control-h-sm` | 28px
|
|
903
|
-
| `--control-h-md` | 36px
|
|
904
|
-
| `--control-h-lg` | 44px
|
|
905
|
-
| `--control-px-sm` | 10px
|
|
906
|
-
| `--control-px-md` | 14px
|
|
907
|
-
| `--control-px-lg` | 18px
|
|
908
|
-
| `--card-p` | 24px
|
|
909
|
-
| `--row-gap` | 16px
|
|
1204
|
+
| Token | default | compact | comfortable |
|
|
1205
|
+
| ----------------- | ------- | ------- | ----------- |
|
|
1206
|
+
| `--control-h-sm` | 28px | 24px | 32px |
|
|
1207
|
+
| `--control-h-md` | 36px | 30px | 42px |
|
|
1208
|
+
| `--control-h-lg` | 44px | 38px | 52px |
|
|
1209
|
+
| `--control-px-sm` | 10px | 8px | 12px |
|
|
1210
|
+
| `--control-px-md` | 14px | 12px | 18px |
|
|
1211
|
+
| `--control-px-lg` | 18px | 16px | 22px |
|
|
1212
|
+
| `--card-p` | 24px | 16px | 32px |
|
|
1213
|
+
| `--row-gap` | 16px | 12px | 20px |
|
|
910
1214
|
|
|
911
1215
|
### Motion
|
|
912
1216
|
|
|
913
|
-
| Token
|
|
914
|
-
|
|
915
|
-
| `--duration-instant` | 50ms
|
|
916
|
-
| `--duration-fast` | 120ms
|
|
917
|
-
| `--duration-normal` | 200ms
|
|
918
|
-
| `--duration-slow` | 320ms
|
|
919
|
-
| `--duration-slower` | 500ms
|
|
920
|
-
| `--ease-linear`
|
|
921
|
-
| `--ease-out`
|
|
922
|
-
| `--ease-in-out`
|
|
923
|
-
| `--ease-spring`
|
|
1217
|
+
| Token | Value |
|
|
1218
|
+
| -------------------- | ----------------------------------- |
|
|
1219
|
+
| `--duration-instant` | 50ms |
|
|
1220
|
+
| `--duration-fast` | 120ms |
|
|
1221
|
+
| `--duration-normal` | 200ms |
|
|
1222
|
+
| `--duration-slow` | 320ms |
|
|
1223
|
+
| `--duration-slower` | 500ms |
|
|
1224
|
+
| `--ease-linear` | `linear` |
|
|
1225
|
+
| `--ease-out` | `cubic-bezier(0.16, 1, 0.3, 1)` |
|
|
1226
|
+
| `--ease-in-out` | `cubic-bezier(0.65, 0, 0.35, 1)` |
|
|
1227
|
+
| `--ease-spring` | `cubic-bezier(0.34, 1.56, 0.64, 1)` |
|
|
924
1228
|
|
|
925
1229
|
### Browsing tokens visually
|
|
926
1230
|
|