@sableui/react 0.9.1 → 0.11.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/AGENTS.md +1 -1
- package/CHANGELOG.md +109 -0
- package/CONTRIBUTING.md +2 -2
- package/DESIGN.md +55 -16
- package/README.md +12 -0
- package/dist/{_contract-C2M1SjBf.d.ts → _contract-CkqXDVww.d.ts} +25 -2
- package/dist/blocks/danger-zone-block.js +3 -3
- package/dist/blocks/danger-zone-block.meta.js +1 -1
- package/dist/blocks/faq-block.js +3 -3
- package/dist/blocks/goal-progress-block.js +1 -1
- package/dist/blocks/notification-list-block.js +1 -1
- package/dist/blocks/pricing-table-block.js +12 -12
- package/dist/blocks/product-card-block.js +3 -3
- package/dist/blocks/product-card-block.meta.js +3 -3
- package/dist/blocks/profile-card-block.js +1 -1
- package/dist/blocks/profile-form-block.js +3 -3
- package/dist/blocks/revenue-breakdown-block.js +5 -5
- package/dist/blocks/stat-row-block.js +3 -3
- package/dist/blocks/task-list-block.js +2 -2
- package/dist/blocks/team-members-block.js +1 -1
- package/dist/blocks/wallet-block.js +4 -4
- package/dist/blocks/wallet-block.meta.js +3 -3
- package/dist/components/accordion/accordion.meta.js +2 -2
- package/dist/components/app-header/app-header.meta.js +1 -1
- package/dist/components/app-shell/app-shell.meta.js +2 -2
- package/dist/components/area-chart/area-chart.meta.js +3 -3
- package/dist/components/badge/badge.js +13 -4
- package/dist/components/badge/badge.meta.js +24 -13
- package/dist/components/badge/badge.variants.js +37 -23
- package/dist/components/banner/banner.meta.js +8 -8
- package/dist/components/banner/banner.variants.js +3 -3
- package/dist/components/bar-chart/bar-chart.meta.js +4 -4
- package/dist/components/breadcrumbs/breadcrumbs.meta.js +1 -1
- package/dist/components/button/button.meta.js +3 -3
- package/dist/components/card/card.js +16 -7
- package/dist/components/card/card.meta.js +4 -4
- package/dist/components/checkbox-card/checkbox-card.meta.js +10 -10
- package/dist/components/checkbox-card/checkbox-card.variants.js +15 -15
- package/dist/components/code-block/code-block.meta.js +1 -1
- package/dist/components/command-menu/command-menu.meta.js +1 -1
- package/dist/components/context-card/context-card.meta.js +2 -2
- package/dist/components/destructive-action-modal/destructive-action-modal.meta.js +1 -1
- package/dist/components/dialog/dialog.meta.js +2 -2
- package/dist/components/disclosure-picker/disclosure-picker.js +48 -2
- package/dist/components/disclosure-picker/disclosure-picker.meta.js +3 -2
- package/dist/components/empty-state/empty-state.meta.js +4 -4
- package/dist/components/gradient-art/gradient-art.meta.js +3 -3
- package/dist/components/label/label.meta.js +1 -1
- package/dist/components/line-chart/line-chart.meta.js +3 -3
- package/dist/components/meter/meter.js +1 -1
- package/dist/components/meter/meter.meta.js +2 -2
- package/dist/components/meter/meter.variants.js +1 -1
- package/dist/components/middle-truncate/middle-truncate.meta.js +4 -4
- package/dist/components/note/note.meta.js +3 -3
- package/dist/components/page-header/page-header.js +1 -1
- package/dist/components/pagination/pagination.meta.js +2 -2
- package/dist/components/panel-section/index.js +2 -1
- package/dist/components/panel-section/panel-section.js +15 -0
- package/dist/components/panel-section/panel-section.meta.js +32 -0
- package/dist/components/phone/phone.meta.js +1 -1
- package/dist/components/pie-chart/pie-chart.meta.js +3 -3
- package/dist/components/pill/pill.js +4 -2
- package/dist/components/pill/pill.meta.js +19 -2
- package/dist/components/pill/pill.variants.js +23 -2
- package/dist/components/popover/popover.meta.js +2 -2
- package/dist/components/radar-chart/radar-chart.meta.js +3 -3
- package/dist/components/radial-chart/radial-chart.meta.js +3 -3
- package/dist/components/radio/radio.meta.js +2 -2
- package/dist/components/radio-card/radio-card.meta.js +6 -6
- package/dist/components/radio-card/radio-card.variants.js +15 -15
- package/dist/components/scroller/scroller.meta.js +1 -1
- package/dist/components/search-input/search-input.meta.js +1 -1
- package/dist/components/section-header/section-header.js +1 -1
- package/dist/components/segmented-bar/segmented-bar.js +1 -1
- package/dist/components/segmented-bar/segmented-bar.meta.js +6 -6
- package/dist/components/segmented-bar/segmented-bar.variants.js +4 -4
- package/dist/components/select/select.meta.js +2 -2
- package/dist/components/sheet/sheet.meta.js +1 -1
- package/dist/components/side-nav/side-nav.meta.js +1 -1
- package/dist/components/sidebar/sidebar.meta.js +1 -1
- package/dist/components/sparkline/sparkline.meta.js +4 -4
- package/dist/components/spinner/spinner.meta.js +1 -1
- package/dist/components/status-dot/status-dot.js +4 -1
- package/dist/components/status-dot/status-dot.meta.js +8 -16
- package/dist/components/status-dot/status-dot.variants.js +13 -4
- package/dist/components/table/table.meta.js +4 -4
- package/dist/components/tabs/tabs.meta.js +1 -1
- package/dist/components/textarea/textarea.meta.js +2 -2
- package/dist/components/toast/toast.meta.js +1 -1
- package/dist/components/tooltip/tooltip.meta.js +2 -2
- package/dist/file-hashes.json +123 -121
- package/dist/foundations/spacing.js +8 -8
- package/dist/index.d.ts +171 -76
- package/dist/index.js +12 -1
- package/dist/lib/chart/types.js +3 -3
- package/dist/lib/palette.js +103 -0
- package/dist/lib/selection-card.js +4 -4
- package/dist/palette.css +669 -0
- package/dist/patterns/auth-page.js +6 -6
- package/dist/patterns/auth-page.meta.js +3 -3
- package/dist/patterns/brand-landing-page.js +2 -2
- package/dist/patterns/chat-panel.js +2 -2
- package/dist/patterns/dashboard-page.js +71 -71
- package/dist/patterns/dashboard-page.meta.js +5 -5
- package/dist/patterns/feed-page.js +25 -25
- package/dist/patterns/feed-page.meta.js +3 -3
- package/dist/patterns/landing-page.js +1 -1
- package/dist/patterns/list-detail-page.js +17 -17
- package/dist/patterns/settings-page.js +17 -17
- package/dist/presets/index.d.ts +1 -1
- package/dist/presets/index.js +17 -2
- package/dist/styles.css +115 -50
- package/dist/{theme-provider-S0NVJs2Y.d.ts → theme-provider-CdSicAad.d.ts} +1 -1
- package/dist/themes/_contract.js +22 -8
- package/dist/themes/atelier/atelier.css +13 -13
- package/dist/themes/atelier/index.d.ts +1 -1
- package/dist/themes/ember/ember.css +13 -13
- package/dist/themes/ember/index.d.ts +1 -1
- package/dist/themes/index.d.ts +2 -2
- package/dist/themes/meridian/index.d.ts +1 -1
- package/dist/themes/meridian/meridian.css +13 -13
- package/dist/themes/poppy/index.d.ts +1 -1
- package/dist/themes/poppy/poppy.css +19 -16
- package/dist/themes/prism/index.d.ts +1 -1
- package/dist/themes/prism/prism.css +18 -15
- package/dist/themes/sable/index.d.ts +1 -1
- package/dist/themes/sable/sable.css +18 -22
- package/dist/themes/verdant/index.d.ts +1 -1
- package/dist/themes/verdant/verdant.css +15 -15
- package/llms/blocks/danger-zone-block.md +4 -4
- package/llms/blocks/faq-block.md +3 -3
- package/llms/blocks/goal-progress-block.md +1 -1
- package/llms/blocks/notification-list-block.md +1 -1
- package/llms/blocks/pricing-table-block.md +12 -12
- package/llms/blocks/product-card-block.md +6 -6
- package/llms/blocks/profile-card-block.md +1 -1
- package/llms/blocks/profile-form-block.md +3 -3
- package/llms/blocks/revenue-breakdown-block.md +5 -5
- package/llms/blocks/stat-row-block.md +3 -3
- package/llms/blocks/task-list-block.md +2 -2
- package/llms/blocks/team-members-block.md +1 -1
- package/llms/blocks/wallet-block.md +7 -7
- package/llms/components/accordion.md +2 -2
- package/llms/components/app-header.md +1 -1
- package/llms/components/app-shell.md +2 -2
- package/llms/components/area-chart.md +1 -1
- package/llms/components/badge.md +15 -7
- package/llms/components/banner.md +6 -6
- package/llms/components/bar-chart.md +2 -2
- package/llms/components/breadcrumbs.md +1 -1
- package/llms/components/button.md +3 -3
- package/llms/components/card.md +4 -4
- package/llms/components/checkbox-card.md +5 -5
- package/llms/components/code-block.md +1 -1
- package/llms/components/command-menu.md +1 -1
- package/llms/components/context-card.md +2 -2
- package/llms/components/destructive-action-modal.md +1 -1
- package/llms/components/dialog.md +2 -2
- package/llms/components/disclosure-picker.md +2 -1
- package/llms/components/empty-state.md +4 -4
- package/llms/components/gradient-art.md +3 -3
- package/llms/components/label.md +1 -1
- package/llms/components/line-chart.md +1 -1
- package/llms/components/meter.md +2 -2
- package/llms/components/middle-truncate.md +5 -5
- package/llms/components/note.md +3 -3
- package/llms/components/pagination.md +2 -2
- package/llms/components/panel-section.md +28 -0
- package/llms/components/phone.md +1 -1
- package/llms/components/pie-chart.md +1 -1
- package/llms/components/pill.md +12 -2
- package/llms/components/popover.md +2 -2
- package/llms/components/radar-chart.md +1 -1
- package/llms/components/radial-chart.md +1 -1
- package/llms/components/radio-card.md +4 -4
- package/llms/components/radio.md +2 -2
- package/llms/components/scroller.md +1 -1
- package/llms/components/search-input.md +1 -1
- package/llms/components/segmented-bar.md +7 -7
- package/llms/components/select.md +2 -2
- package/llms/components/sheet.md +1 -1
- package/llms/components/side-nav.md +1 -1
- package/llms/components/sidebar.md +1 -1
- package/llms/components/sparkline.md +2 -2
- package/llms/components/spinner.md +1 -1
- package/llms/components/status-dot.md +4 -4
- package/llms/components/table.md +8 -8
- package/llms/components/tabs.md +1 -1
- package/llms/components/textarea.md +2 -2
- package/llms/components/toast.md +1 -1
- package/llms/components/tooltip.md +2 -2
- package/llms/foundations/spacing.md +7 -7
- package/llms/layout/grid.md +1 -1
- package/llms/layout/page.md +1 -1
- package/llms/layout/region.md +1 -1
- package/llms/layout/split-pane.md +1 -1
- package/llms/patterns/auth-page.md +11 -11
- package/llms/patterns/brand-landing-page.md +2 -2
- package/llms/patterns/chat-panel.md +2 -2
- package/llms/patterns/dashboard-page.md +78 -78
- package/llms/patterns/feed-page.md +31 -31
- package/llms/patterns/landing-page.md +1 -1
- package/llms/patterns/list-detail-page.md +18 -18
- package/llms/patterns/settings-page.md +18 -18
- package/llms/reference/token-intent.md +25 -11
- package/llms/reference/utilities.md +1 -1
- package/llms/tasks/adding-a-component.md +4 -1
- package/llms/tasks/building-a-page.md +40 -0
- package/llms/tasks/converting-an-app.md +3 -1
- package/llms/tasks/using-presets.md +4 -0
- package/llms-full.txt +457 -347
- package/llms.txt +8 -8
- package/package.json +4 -4
- package/registry.json +397 -233
- package/scripts/lint-rules.mjs +26 -5
- package/skills/sable/SKILL.md +14 -3
|
@@ -25,9 +25,9 @@ import { Badge, Card, CardContent, CardDescription, CardHeader, CardTitle, cn, G
|
|
|
25
25
|
|
|
26
26
|
const stats = [
|
|
27
27
|
{ label: "Revenue", value: "$18,240", delta: "+8.2%", up: true, note: "vs. $16,857" },
|
|
28
|
-
{ label: "
|
|
29
|
-
{ label: "
|
|
30
|
-
{ label: "
|
|
28
|
+
{ label: "Orders", value: "1,284", delta: "+3.1%", up: true, note: "182 first-time" },
|
|
29
|
+
{ label: "New customers", value: "312", delta: "+12.4%", up: true, note: "Best month yet" },
|
|
30
|
+
{ label: "Conversion", value: "3.4%", delta: "−0.2%", up: false, note: "6 open trials" },
|
|
31
31
|
]
|
|
32
32
|
|
|
33
33
|
export interface StatRowBlockProps {
|
|
@@ -24,9 +24,9 @@ import { useState, useId } from "react"
|
|
|
24
24
|
import { Badge, Button, Card, CardAction, CardContent, CardFooter, CardHeader, CardTitle, Checkbox, cn, Icon, Label } from "@sableui/react"
|
|
25
25
|
|
|
26
26
|
const tasks = [
|
|
27
|
-
{ title: "Pick the cover type", tag: "Design", tone: "
|
|
27
|
+
{ title: "Pick the cover type", tag: "Design", tone: "2", done: true },
|
|
28
28
|
{ title: "Wire up checkout", tag: "Engineering", tone: "info", done: false },
|
|
29
|
-
{ title: "Draft launch post", tag: "Launch", tone: "
|
|
29
|
+
{ title: "Draft launch post", tag: "Launch", tone: "1", done: false },
|
|
30
30
|
] as const
|
|
31
31
|
|
|
32
32
|
export interface TaskListBlockProps {
|
|
@@ -59,7 +59,7 @@ export function TeamMembersBlock({ className, framed = true, onInvite, onMemberA
|
|
|
59
59
|
subtitle={m.email}
|
|
60
60
|
action={
|
|
61
61
|
<div className="flex items-center gap-2">
|
|
62
|
-
<Badge appearance={m.role === "Pending" ? "outline" : "plain"} tone={m.role === "Owner" ? "
|
|
62
|
+
<Badge appearance={m.role === "Pending" ? "outline" : "plain"} tone={m.role === "Owner" ? "1" : "neutral"} size="sm">
|
|
63
63
|
{m.role}
|
|
64
64
|
</Badge>
|
|
65
65
|
{/* The owner is not managed from here; a placeholder keeps the column aligned. */}
|
|
@@ -2,7 +2,7 @@
|
|
|
2
2
|
|
|
3
3
|
A balance card: the balance in the metric mono tier, Send and Receive as an equal pair, and recent activity as Entity rows with signed amounts.
|
|
4
4
|
|
|
5
|
-
**Intent:** Reach for this for
|
|
5
|
+
**Intent:** Reach for this for an account balance, store credit or credits summary with its latest movements. For a full transaction history with filters, use a DataTable.
|
|
6
6
|
|
|
7
7
|
**Block:** Commerce · card · designed for 18rem–20rem wide (fills its container up to the max)
|
|
8
8
|
|
|
@@ -10,24 +10,24 @@ A balance card: the balance in the metric mono tier, Send and Receive as an equa
|
|
|
10
10
|
|
|
11
11
|
- The balance is CardTitle at `text-mono-xl` — tabular figures, never a heading tier — under its label as CardDescription.
|
|
12
12
|
- Send is primary and Receive secondary, side by side at equal width: two directions of one action, with sending the riskier and more frequent.
|
|
13
|
-
- Incoming amounts are `text-success`; outgoing stay muted rather than red, because a
|
|
13
|
+
- Incoming amounts are `text-success`; outgoing stay muted rather than red, because a payout or refund is not an error.
|
|
14
14
|
|
|
15
15
|
## Accessibility
|
|
16
16
|
|
|
17
17
|
- Each activity row's leading swatch is aria-hidden; the title and detail carry the meaning.
|
|
18
|
-
- Amounts keep their sign in text (+
|
|
18
|
+
- Amounts keep their sign in text (+49.00 / -850.00), so the direction does not depend on colour.
|
|
19
19
|
|
|
20
20
|
## Source
|
|
21
21
|
|
|
22
22
|
```tsx
|
|
23
23
|
import { Button, Card, CardContent, CardDescription, CardHeader, CardTitle, cn, Entity, Icon } from "@sableui/react"
|
|
24
24
|
|
|
25
|
-
const balance = "
|
|
25
|
+
const balance = "$2,418.50"
|
|
26
26
|
|
|
27
27
|
const activity = [
|
|
28
|
-
{ title: "
|
|
29
|
-
{ title: "
|
|
30
|
-
{ title: "
|
|
28
|
+
{ title: "Subscription", detail: "Team plan · 2h ago", amount: "+49.00", tone: "1" },
|
|
29
|
+
{ title: "Refund", detail: "Order 1042 · Yesterday", amount: "-24.00", tone: "2" },
|
|
30
|
+
{ title: "Payout", detail: "To checking · Mon", amount: "-850.00", tone: "3" },
|
|
31
31
|
]
|
|
32
32
|
|
|
33
33
|
export interface WalletBlockProps {
|
|
@@ -73,7 +73,7 @@ Use Accordion to reveal a vertical set of related sections while keeping the sur
|
|
|
73
73
|
```tsx
|
|
74
74
|
import { Accordion, AccordionItem, AccordionPanel, AccordionTrigger } from "@sableui/react"
|
|
75
75
|
|
|
76
|
-
<Accordion defaultValue={["a"]}><AccordionItem value="a"><AccordionTrigger>
|
|
76
|
+
<Accordion defaultValue={["a"]}><AccordionItem value="a"><AccordionTrigger>Can I cancel anytime?</AccordionTrigger><AccordionPanel>Yes — from billing settings.</AccordionPanel></AccordionItem><AccordionItem value="b"><AccordionTrigger>How much?</AccordionTrigger><AccordionPanel>$16 per seat each month.</AccordionPanel></AccordionItem></Accordion>
|
|
77
77
|
```
|
|
78
78
|
|
|
79
79
|
### Multiple open
|
|
@@ -89,5 +89,5 @@ import { Accordion, AccordionItem, AccordionPanel, AccordionTrigger } from "@sab
|
|
|
89
89
|
```tsx
|
|
90
90
|
import { Accordion, AccordionItem, AccordionPanel, AccordionTrigger, Icon } from "@sableui/react"
|
|
91
91
|
|
|
92
|
-
<Accordion defaultValue={["a"]}><AccordionItem value="a"><AccordionTrigger indicator={<Icon name="plus" className="text-xs text-muted-foreground transition-transform [[data-panel-open]_&]:rotate-45" />}>
|
|
92
|
+
<Accordion defaultValue={["a"]}><AccordionItem value="a"><AccordionTrigger indicator={<Icon name="plus" className="text-xs text-muted-foreground transition-transform [[data-panel-open]_&]:rotate-45" />}>Can I cancel anytime?</AccordionTrigger><AccordionPanel>Yes — from billing settings.</AccordionPanel></AccordionItem></Accordion>
|
|
93
93
|
```
|
|
@@ -23,7 +23,7 @@ Use AppHeader for compact application chrome at the top of a screen, usually wit
|
|
|
23
23
|
| --- | --- | --- | --- |
|
|
24
24
|
| leading | ReactNode | — | Leading slot — back button, create action, or menu trigger. |
|
|
25
25
|
| title | ReactNode | — | Center slot — brand wordmark or contextual page title. |
|
|
26
|
-
| actions | ReactNode | — | Trailing slot —
|
|
26
|
+
| actions | ReactNode | — | Trailing slot — account menu, action buttons. |
|
|
27
27
|
|
|
28
28
|
## Tokens used
|
|
29
29
|
|
|
@@ -72,7 +72,7 @@ import { AppHeader, AppShell, Banner, BottomNav, BottomNavItem, Icon, PageHeader
|
|
|
72
72
|
// <Link> = your router's link (react-router, next/link, @tanstack/router, …)
|
|
73
73
|
|
|
74
74
|
<AppShell
|
|
75
|
-
banners={<Banner tone="warning">
|
|
75
|
+
banners={<Banner tone="warning">Sync is delayed — changes may be slow to appear.</Banner>}
|
|
76
76
|
header={<AppHeader title="Studio" />}
|
|
77
77
|
sidebar={
|
|
78
78
|
<Sidebar>
|
|
@@ -91,7 +91,7 @@ import { AppHeader, AppShell, Banner, BottomNav, BottomNavItem, Icon, PageHeader
|
|
|
91
91
|
}
|
|
92
92
|
>
|
|
93
93
|
<Region max="feed">
|
|
94
|
-
<PageHeader title="Home" description="Latest posts from
|
|
94
|
+
<PageHeader title="Home" description="Latest posts from people you follow." />
|
|
95
95
|
</Region>
|
|
96
96
|
</AppShell>
|
|
97
97
|
```
|
|
@@ -44,7 +44,7 @@ Use AreaChart for volume over time — visitors, revenue, usage — where the fi
|
|
|
44
44
|
|
|
45
45
|
## Tokens used
|
|
46
46
|
|
|
47
|
-
`tone-
|
|
47
|
+
`tone-1`, `tone-2`, `tone-3`, `tone-info`, `tone-warning`, `primary`, `muted-foreground`, `border`, `popover`, `popover-foreground`, `foreground`, `background`
|
|
48
48
|
|
|
49
49
|
## Motion
|
|
50
50
|
|
package/llms/components/badge.md
CHANGED
|
@@ -2,7 +2,7 @@
|
|
|
2
2
|
|
|
3
3
|
**Status:** stable
|
|
4
4
|
|
|
5
|
-
Compact static label, set on two axes: appearance (soft, outline, solid, overlay on media, plain text) and tone (neutral or a
|
|
5
|
+
Compact static label, set on two axes: appearance (soft, outline, solid, overlay on media, plain text) and tone (neutral, a semantic tone, or a palette family like blue for a category with no meaning attached). An optional leading icon, or a status dot (with pulse) for state.
|
|
6
6
|
|
|
7
7
|
**Keywords:** badge, tag, label, status, metadata, chip, pill, tone, category
|
|
8
8
|
|
|
@@ -13,7 +13,7 @@ Use Badge for any short static label: metadata, categories, tone-coded labels, a
|
|
|
13
13
|
### Best practices
|
|
14
14
|
|
|
15
15
|
- Do: Keep badge text short: one to three words or a compact count.
|
|
16
|
-
- Do: Use tone variants when the badge carries meaning, such as success, warning
|
|
16
|
+
- Do: Use tone variants when the badge carries meaning, such as success, warning or destructive, or a decorative tone for a category or plan.
|
|
17
17
|
- Do: Pair icons with text; the icon reinforces meaning but should not be the only cue.
|
|
18
18
|
- Do: Choose appearance and tone separately: appearance is how loud it is (soft by default, solid for emphasis, overlay on images, plain for a status line); tone is what it means.
|
|
19
19
|
- Don't: Use a Badge as a button. If it triggers an action, use Button, Toggle, or a menu item.
|
|
@@ -32,7 +32,7 @@ Use Badge for any short static label: metadata, categories, tone-coded labels, a
|
|
|
32
32
|
| Name | Type | Default | Description |
|
|
33
33
|
| --- | --- | --- | --- |
|
|
34
34
|
| appearance | "soft" \| "outline" \| "solid" \| "overlay" \| "plain" | "soft" | How it is drawn. soft: a tinted fill (neutral is the secondary surface). outline: a hairline. solid: the tone at full strength (neutral is the inverted chip). overlay: legible on images — a dark scrim, or the solid tone. plain: no fill or padding, a status line. |
|
|
35
|
-
| tone | "neutral" \| "
|
|
35
|
+
| tone | "neutral" \| "1" \| "2" \| "3" \| "info" \| "success" \| "warning" \| "destructive" \| "red" \| "orange" \| "yellow" \| "green" \| "teal" \| "blue" \| "purple" \| "pink" | "neutral" | What it means. Every appearance takes every tone. The palette families (red … pink) are categories with no meaning attached — tags, labels, project colours — painted from the theme's generated palette, so they lean toward the brand and read in both modes. |
|
|
36
36
|
| size | "sm" \| "md" | "md" | "sm" uses tighter padding + text-label-sm; "md" is the default look. |
|
|
37
37
|
| icon | ReactNode | — | Optional leading glyph (e.g. <Icon name="lock" />), rendered before the children with the base gap. Ignored when dot is set. |
|
|
38
38
|
| dot | boolean | false | A leading status dot in the badge's tone. With appearance="plain" it is a status line (● Ready). |
|
|
@@ -41,12 +41,12 @@ Use Badge for any short static label: metadata, categories, tone-coded labels, a
|
|
|
41
41
|
## Variants
|
|
42
42
|
|
|
43
43
|
- **appearance**: soft, outline, solid, overlay, plain
|
|
44
|
-
- **tone**: neutral,
|
|
44
|
+
- **tone**: neutral, 1, 2, 3, info, success, warning, destructive, red, orange, yellow, green, teal, blue, purple, pink
|
|
45
45
|
- **size**: sm, md
|
|
46
46
|
|
|
47
47
|
## Tokens used
|
|
48
48
|
|
|
49
|
-
`secondary`, `secondary-foreground`, `border`, `foreground`, `background`, `muted`, `muted-foreground`, `tone-
|
|
49
|
+
`palette-wash`, `palette-wash-strong`, `palette-edge`, `palette-dot`, `palette-solid`, `palette-text`, `palette-solid-ink`, `secondary`, `secondary-foreground`, `border`, `foreground`, `background`, `muted`, `muted-foreground`, `tone-1`, `tone-2`, `tone-3`, `tone-info`, `success`, `tone-warning`, `destructive`, `overlay`, `overlay-foreground`, `tone-1-foreground`, `tone-2-foreground`, `tone-3-foreground`, `tone-info-foreground`, `success-foreground`, `tone-warning-foreground`, `destructive-foreground`
|
|
50
50
|
|
|
51
51
|
## Accessibility
|
|
52
52
|
|
|
@@ -65,7 +65,15 @@ Use Badge for any short static label: metadata, categories, tone-coded labels, a
|
|
|
65
65
|
```tsx
|
|
66
66
|
import { Badge, Row } from "@sableui/react"
|
|
67
67
|
|
|
68
|
-
<Row gap={1}><Badge tone="
|
|
68
|
+
<Row gap={1}><Badge tone="1">Business</Badge><Badge tone="2">Studio</Badge><Badge tone="3">Starter</Badge></Row>
|
|
69
|
+
```
|
|
70
|
+
|
|
71
|
+
### Palette colours (categories)
|
|
72
|
+
|
|
73
|
+
```tsx
|
|
74
|
+
import { Badge, Row } from "@sableui/react"
|
|
75
|
+
|
|
76
|
+
<Row gap={1}><Badge tone="blue">Design</Badge><Badge tone="teal">Research</Badge><Badge tone="orange">Marketing</Badge><Badge tone="pink" appearance="outline">Ops</Badge><Badge tone="purple" appearance="solid">Launch</Badge></Row>
|
|
69
77
|
```
|
|
70
78
|
|
|
71
79
|
### Solid
|
|
@@ -105,7 +113,7 @@ import { Badge } from "@sableui/react"
|
|
|
105
113
|
```tsx
|
|
106
114
|
import { Badge, Icon, Row } from "@sableui/react"
|
|
107
115
|
|
|
108
|
-
<Row gap={1}><Badge>12
|
|
116
|
+
<Row gap={1}><Badge>12 projects</Badge><Badge appearance="outline">Draft</Badge><Badge tone="info" icon={<Icon name="info" />}>Curated</Badge></Row>
|
|
109
117
|
```
|
|
110
118
|
|
|
111
119
|
### Semantic state
|
|
@@ -2,7 +2,7 @@
|
|
|
2
2
|
|
|
3
3
|
**Status:** stable
|
|
4
4
|
|
|
5
|
-
Full-width, page-level announcement bar. A tone (neutral, info, success, warning,
|
|
5
|
+
Full-width, page-level announcement bar. A tone (neutral, info, success, warning, the decorative 1, destructive) × an appearance (soft tint or loud solid fill), and an optional leading scope label. Centers its message, or — with a trailing action — switches to a leading-text + trailing-button layout. Optionally sticky and dismissible.
|
|
6
6
|
|
|
7
7
|
**Keywords:** banner, announcement, alert, status, message, warning, success, offline, sticky
|
|
8
8
|
|
|
@@ -31,7 +31,7 @@ Use Banner for page-level or app-level messages that affect the current experien
|
|
|
31
31
|
|
|
32
32
|
| Name | Type | Default | Description |
|
|
33
33
|
| --- | --- | --- | --- |
|
|
34
|
-
| tone | "neutral" \| "info" \| "success" \| "warning" \| "
|
|
34
|
+
| tone | "neutral" \| "info" \| "success" \| "warning" \| "1" \| "destructive" | "neutral" | Neutral surface or a tone that encodes the announcement's intent (info / success / warning / the decorative 1 / destructive). |
|
|
35
35
|
| appearance | "soft" \| "solid" | "soft" | "soft" is a quiet tinted fill; "solid" is the full tone with its paired ink — for loud, can't-miss states (offline, chain-down, RPC errors). |
|
|
36
36
|
| label | ReactNode | — | A short scope label ("Preview", "Staging", a project name) in a leading chip — a Badge that reads on soft and solid fills. |
|
|
37
37
|
| action | ReactNode | — | A trailing action (e.g. a Button). Switches the bar to leading text + trailing action instead of centered text. |
|
|
@@ -42,12 +42,12 @@ Use Banner for page-level or app-level messages that affect the current experien
|
|
|
42
42
|
|
|
43
43
|
## Variants
|
|
44
44
|
|
|
45
|
-
- **tone**: neutral, info, success, warning,
|
|
45
|
+
- **tone**: neutral, info, success, warning, 1, destructive
|
|
46
46
|
- **appearance**: soft, solid
|
|
47
47
|
|
|
48
48
|
## Tokens used
|
|
49
49
|
|
|
50
|
-
`secondary`, `secondary-foreground`, `foreground`, `background`, `tone-info`, `tone-info-foreground`, `success`, `success-foreground`, `tone-warning`, `tone-warning-foreground`, `tone-
|
|
50
|
+
`secondary`, `secondary-foreground`, `foreground`, `background`, `tone-info`, `tone-info-foreground`, `success`, `success-foreground`, `tone-warning`, `tone-warning-foreground`, `tone-1`, `tone-1-foreground`, `destructive`, `destructive-foreground`
|
|
51
51
|
|
|
52
52
|
## Accessibility
|
|
53
53
|
|
|
@@ -75,7 +75,7 @@ import { Banner } from "@sableui/react"
|
|
|
75
75
|
```tsx
|
|
76
76
|
import { Banner } from "@sableui/react"
|
|
77
77
|
|
|
78
|
-
<Banner tone="destructive" appearance="solid" live="assertive">
|
|
78
|
+
<Banner tone="destructive" appearance="solid" live="assertive">Payments are down. Checkout and upgrades are temporarily disabled.</Banner>
|
|
79
79
|
```
|
|
80
80
|
|
|
81
81
|
### Success
|
|
@@ -107,7 +107,7 @@ import { Banner } from "@sableui/react"
|
|
|
107
107
|
```tsx
|
|
108
108
|
import { Banner, Button } from "@sableui/react"
|
|
109
109
|
|
|
110
|
-
<Banner tone="warning" action={<Button variant="outline" size="sm">Reconnect</Button>}>
|
|
110
|
+
<Banner tone="warning" action={<Button variant="outline" size="sm">Reconnect</Button>}>Calendar sync paused.</Banner>
|
|
111
111
|
```
|
|
112
112
|
|
|
113
113
|
### App-shell outage
|
|
@@ -42,13 +42,13 @@ Use BarChart to compare amounts across categories — the default chart for "how
|
|
|
42
42
|
| stacked | boolean \| "expand" | false | Stack the series in one bar, or `"expand"` to show each category as 100%. Unstacked series sit side by side. |
|
|
43
43
|
| labels | boolean \| "inside" | false | Print each bar's value at its end, or (`"inside"`, horizontal) the category name inside the bar as well. |
|
|
44
44
|
| colorBy | "series" \| "index" | "series" | Colour by series, or give each category its own tone (one series). |
|
|
45
|
-
| negativeTone | "
|
|
45
|
+
| negativeTone | "1" \| "2" \| "3" \| "info" \| "warning" \| "primary" \| "neutral" \| "success" \| "destructive" | — | Colour negative values with this tone. |
|
|
46
46
|
| radius | number | 4 | Corner radius of each bar's far end, in px. Stacks round only the outer segment. |
|
|
47
47
|
| barWidth | number | 24 | Maximum thickness of a bar, in px: the band's leftover is air, not a fatter bar. Raise it for a bolder presentation look. |
|
|
48
48
|
|
|
49
49
|
## Tokens used
|
|
50
50
|
|
|
51
|
-
`tone-
|
|
51
|
+
`tone-1`, `tone-2`, `tone-3`, `tone-info`, `tone-warning`, `primary`, `muted-foreground`, `border`, `popover`, `popover-foreground`, `foreground`, `background`
|
|
52
52
|
|
|
53
53
|
## Motion
|
|
54
54
|
|
|
@@ -63,7 +63,7 @@ Use Breadcrumbs to show the user's location inside a hierarchy and provide light
|
|
|
63
63
|
```tsx
|
|
64
64
|
import { BreadcrumbItem, BreadcrumbLink, BreadcrumbPage, Breadcrumbs, BreadcrumbSeparator } from "@sableui/react"
|
|
65
65
|
|
|
66
|
-
<Breadcrumbs><BreadcrumbItem><BreadcrumbLink href="/">Home</BreadcrumbLink></BreadcrumbItem><BreadcrumbSeparator /><BreadcrumbItem><BreadcrumbLink href="/library">Library</BreadcrumbLink></BreadcrumbItem><BreadcrumbSeparator /><BreadcrumbItem><BreadcrumbPage>
|
|
66
|
+
<Breadcrumbs><BreadcrumbItem><BreadcrumbLink href="/">Home</BreadcrumbLink></BreadcrumbItem><BreadcrumbSeparator /><BreadcrumbItem><BreadcrumbLink href="/library">Library</BreadcrumbLink></BreadcrumbItem><BreadcrumbSeparator /><BreadcrumbItem><BreadcrumbPage>Reports</BreadcrumbPage></BreadcrumbItem></Breadcrumbs>
|
|
67
67
|
```
|
|
68
68
|
|
|
69
69
|
### Custom separator
|
|
@@ -88,7 +88,7 @@ Use Button when the user commits an action, submits a form, opens UI, or confirm
|
|
|
88
88
|
```tsx
|
|
89
89
|
import { Button } from "@sableui/react"
|
|
90
90
|
|
|
91
|
-
<Button>
|
|
91
|
+
<Button>Save changes</Button>
|
|
92
92
|
```
|
|
93
93
|
|
|
94
94
|
### Secondary + ghost
|
|
@@ -145,7 +145,7 @@ import { Button, Row } from "@sableui/react"
|
|
|
145
145
|
```tsx
|
|
146
146
|
import { Button, Row } from "@sableui/react"
|
|
147
147
|
|
|
148
|
-
<Row gap={1}><Button variant="secondary">Cancel</Button><Button variant="destructive">Delete
|
|
148
|
+
<Row gap={1}><Button variant="secondary">Cancel</Button><Button variant="destructive">Delete project</Button></Row>
|
|
149
149
|
```
|
|
150
150
|
|
|
151
151
|
### Leading icon
|
|
@@ -228,5 +228,5 @@ import { Button } from "@sableui/react"
|
|
|
228
228
|
```tsx
|
|
229
229
|
import { Banner, Button } from "@sableui/react"
|
|
230
230
|
|
|
231
|
-
<Banner tone="warning" appearance="solid" action={<Button variant="on-color" size="sm">Reconnect</Button>}>
|
|
231
|
+
<Banner tone="warning" appearance="solid" action={<Button variant="on-color" size="sm">Reconnect</Button>}>Calendar sync paused.</Banner>
|
|
232
232
|
```
|
package/llms/components/card.md
CHANGED
|
@@ -83,7 +83,7 @@ Use Card for a discrete thing with its own boundary, such as one product, one no
|
|
|
83
83
|
```tsx
|
|
84
84
|
import { Card, CardContent, CardDescription, CardHeader, CardTitle } from "@sableui/react"
|
|
85
85
|
|
|
86
|
-
<Card><CardHeader><CardTitle>
|
|
86
|
+
<Card><CardHeader><CardTitle>Studio plan</CardTitle><CardDescription>Up to 10 seats.</CardDescription></CardHeader><CardContent><p className="text-body-md">Every seat gets unlimited projects and shared reports.</p></CardContent></Card>
|
|
87
87
|
```
|
|
88
88
|
|
|
89
89
|
### With a header action
|
|
@@ -91,7 +91,7 @@ import { Card, CardContent, CardDescription, CardHeader, CardTitle } from "@sabl
|
|
|
91
91
|
```tsx
|
|
92
92
|
import { Button, Card, CardAction, CardContent, CardHeader, CardTitle, Icon } from "@sableui/react"
|
|
93
93
|
|
|
94
|
-
<Card><CardHeader><CardTitle>
|
|
94
|
+
<Card><CardHeader><CardTitle>Seats</CardTitle><CardAction><Button variant="ghost" size="icon-sm" aria-label="More"><Icon name="ellipsis" /></Button></CardAction></CardHeader><CardContent><p className="text-body-md text-muted-foreground">24 of 100 seats in use.</p></CardContent></Card>
|
|
95
95
|
```
|
|
96
96
|
|
|
97
97
|
### Compact section panel
|
|
@@ -107,7 +107,7 @@ import { Card, CardContent, CardHeader, CardTitle } from "@sableui/react"
|
|
|
107
107
|
```tsx
|
|
108
108
|
import { Badge, Button, Card, CardAction, CardContent, CardDescription, CardFooter, CardHeader, CardTitle } from "@sableui/react"
|
|
109
109
|
|
|
110
|
-
<Card><CardHeader><CardTitle>Midnight Archive</CardTitle><CardDescription>
|
|
110
|
+
<Card><CardHeader><CardTitle>Midnight Archive</CardTitle><CardDescription>Template · 24 pages</CardDescription><CardAction><Badge tone="1">New</Badge></CardAction></CardHeader><CardContent><p className="text-body-sm text-muted-foreground">A project template with a brief, a timeline and a review board.</p></CardContent><CardFooter><Button size="sm">Use template</Button><Button size="sm" variant="ghost">Preview</Button></CardFooter></Card>
|
|
111
111
|
```
|
|
112
112
|
|
|
113
113
|
### Whole card as a link
|
|
@@ -123,7 +123,7 @@ import { Card, CardContent, CardDescription, CardTitle, Icon } from "@sableui/re
|
|
|
123
123
|
```tsx
|
|
124
124
|
import { Card, CardContent, CardDescription, CardHeader, CardTitle } from "@sableui/react"
|
|
125
125
|
|
|
126
|
-
<Card density="compact"><CardHeader><CardTitle>Revenue</CardTitle><CardDescription>Last 30 days</CardDescription></CardHeader><CardContent><p className="text-heading-3"
|
|
126
|
+
<Card density="compact"><CardHeader><CardTitle>Revenue</CardTitle><CardDescription>Last 30 days</CardDescription></CardHeader><CardContent><p className="text-heading-3">$12,840</p><p className="text-body-sm text-success">+12.8% from previous period</p></CardContent></Card>
|
|
127
127
|
```
|
|
128
128
|
|
|
129
129
|
### List card
|
|
@@ -40,17 +40,17 @@ Use CheckboxCard when an option needs more visual weight, supporting text, or ic
|
|
|
40
40
|
| title | ReactNode | — | The card's primary label (text-title-sm). |
|
|
41
41
|
| description | ReactNode | — | Optional supporting copy beneath the title (text-body-sm, muted). |
|
|
42
42
|
| icon | ReactNode | — | Optional glyph (a solid <Icon>) in the tone colour. Its presence switches to the two-dimensional card RadioCard uses — icon top-left, checkbox top-right, copy below — so the two cards match in one form. |
|
|
43
|
-
| tone | "neutral" \| "
|
|
43
|
+
| tone | "neutral" \| "3" \| "2" \| "1" \| "info" \| "warning" | "neutral" | Semantic colour the checked state carries across the border, checkbox box, and icon. |
|
|
44
44
|
| value | string | — | Names the card inside a group-owned CheckboxGroup: the card is checked when the group's value array includes it. Also the value submitted with a form. Inside a CheckboxGroup, `name` stands in for `value` when `value` is omitted. |
|
|
45
45
|
| checked / onCheckedChange / defaultChecked / disabled | Base UI Checkbox.Root props | — | Standard checkbox state. Without a group-owned value, each card is independent — drive checked/onCheckedChange per item for multi-select. |
|
|
46
46
|
|
|
47
47
|
## Variants
|
|
48
48
|
|
|
49
|
-
- **tone**: neutral,
|
|
49
|
+
- **tone**: neutral, 3, 2, 1, info, warning
|
|
50
50
|
|
|
51
51
|
## Tokens used
|
|
52
52
|
|
|
53
|
-
`input`, `card`, `ring`, `primary`, `primary-foreground`, `accent`, `foreground`, `muted-foreground`, `tone-
|
|
53
|
+
`input`, `card`, `ring`, `primary`, `primary-foreground`, `accent`, `foreground`, `muted-foreground`, `tone-3`, `tone-3-foreground`, `tone-2`, `tone-2-foreground`, `tone-1`, `tone-1-foreground`, `tone-info`, `tone-info-foreground`, `tone-warning`, `tone-warning-foreground`
|
|
54
54
|
|
|
55
55
|
## Accessibility
|
|
56
56
|
|
|
@@ -86,7 +86,7 @@ import { Checkbox, CheckboxCard, CheckboxGroup, Field } from "@sableui/react"
|
|
|
86
86
|
```tsx
|
|
87
87
|
import { CheckboxCard } from "@sableui/react"
|
|
88
88
|
|
|
89
|
-
<CheckboxCard title="Email me a receipt" description="Sent when the
|
|
89
|
+
<CheckboxCard title="Email me a receipt" description="Sent when the payment settles" checked={receipt} onCheckedChange={setReceipt} />
|
|
90
90
|
```
|
|
91
91
|
|
|
92
92
|
### Toned with description
|
|
@@ -94,5 +94,5 @@ import { CheckboxCard } from "@sableui/react"
|
|
|
94
94
|
```tsx
|
|
95
95
|
import { CheckboxCard } from "@sableui/react"
|
|
96
96
|
|
|
97
|
-
<CheckboxCard tone="
|
|
97
|
+
<CheckboxCard tone="1" title="Reports" description="Weekly usage reports by email" defaultChecked />
|
|
98
98
|
```
|
|
@@ -14,7 +14,7 @@ Use CodeBlock for multiline code samples that users may read, inspect, or copy.
|
|
|
14
14
|
|
|
15
15
|
- Do: Give the snippet a filename, or a sentence of surrounding copy, when it helps readers and agents place it.
|
|
16
16
|
- Do: Keep examples complete enough to teach the intended pattern.
|
|
17
|
-
- Do: Wire highlighting once with CodeHighlightProvider and map token colors to semantic tone tokens (keywords → tone-
|
|
17
|
+
- Do: Wire highlighting once with CodeHighlightProvider and map token colors to semantic tone tokens (keywords → tone-1, strings → success, comments → muted-foreground), so code follows the theme instead of a fixed palette.
|
|
18
18
|
- Don't: Do not put short inline identifiers in a CodeBlock; use Code for those.
|
|
19
19
|
- Don't: Do not paste code with the indentation the surrounding file had. A block indented to sit inside your JSX shows the reader leading whitespace that is not part of the example.
|
|
20
20
|
|
|
@@ -112,7 +112,7 @@ import { CommandMenu, CommandMenuGroup, CommandMenuItem } from "@sableui/react"
|
|
|
112
112
|
```tsx
|
|
113
113
|
import { CommandMenu, CommandMenuGroup, CommandMenuItem } from "@sableui/react"
|
|
114
114
|
|
|
115
|
-
<CommandMenu open={open} onOpenChange={setOpen}><CommandMenuGroup label="Create"><CommandMenuItem icon="plus" onSelect={() => createPost()}>New post</CommandMenuItem><CommandMenuItem icon="sparkles" onSelect={() =>
|
|
115
|
+
<CommandMenu open={open} onOpenChange={setOpen}><CommandMenuGroup label="Create"><CommandMenuItem icon="plus" onSelect={() => createPost()}>New post</CommandMenuItem><CommandMenuItem icon="sparkles" onSelect={() => createProject()}>New project</CommandMenuItem></CommandMenuGroup><CommandMenuGroup label="Navigation"><CommandMenuItem icon="home" onSelect={() => navigate("/")}>Home</CommandMenuItem><CommandMenuItem icon="gear" onSelect={() => navigate("/settings")}>Settings</CommandMenuItem></CommandMenuGroup></CommandMenu>
|
|
116
116
|
```
|
|
117
117
|
|
|
118
118
|
### Consumer-owned ranking
|
|
@@ -2,7 +2,7 @@
|
|
|
2
2
|
|
|
3
3
|
**Status:** stable
|
|
4
4
|
|
|
5
|
-
Hover/focus-triggered rich preview card over Base UI PreviewCard. Reveals contextual content (a profile,
|
|
5
|
+
Hover/focus-triggered rich preview card over Base UI PreviewCard. Reveals contextual content (a profile, a project summary) from an inline anchor; 20rem-wide surface with delayed open and collision-aware positioning.
|
|
6
6
|
|
|
7
7
|
**Keywords:** context card, rich tooltip, hover card, preview
|
|
8
8
|
|
|
@@ -61,7 +61,7 @@ Use ContextCard to show richer contextual content near a trigger without taking
|
|
|
61
61
|
```tsx
|
|
62
62
|
import { Avatar, ContextCard, ContextCardContent, ContextCardTrigger, Entity } from "@sableui/react"
|
|
63
63
|
|
|
64
|
-
<ContextCard><ContextCardTrigger render={<a href='/u/ada' className='text-title-sm underline-offset-2 hover:underline'>@ada</a>} /><ContextCardContent><Entity className='[--entity-px:0] [--entity-py:0]' leading={<Avatar fallback='AL' size='lg' />} title='Ada Lovelace' subtitle='@ada' /><p className='mt-3 text-body-sm text-muted-foreground'>
|
|
64
|
+
<ContextCard><ContextCardTrigger render={<a href='/u/ada' className='text-title-sm underline-offset-2 hover:underline'>@ada</a>} /><ContextCardContent><Entity className='[--entity-px:0] [--entity-py:0]' leading={<Avatar fallback='AL' size='lg' />} title='Ada Lovelace' subtitle='@ada' /><p className='mt-3 text-body-sm text-muted-foreground'>Product designer. Building tools for small teams.</p></ContextCardContent></ContextCard>
|
|
65
65
|
```
|
|
66
66
|
|
|
67
67
|
### With stat row
|
|
@@ -72,5 +72,5 @@ import { DestructiveActionModal } from "@sableui/react"
|
|
|
72
72
|
```tsx
|
|
73
73
|
import { DestructiveActionModal, Note } from "@sableui/react"
|
|
74
74
|
|
|
75
|
-
<DestructiveActionModal open={open} onOpenChange={setOpen} title='Delete this post?' confirmText='gold rush' confirmLabel='Delete forever' onConfirm={handleDelete}><Note tone='warning'>
|
|
75
|
+
<DestructiveActionModal open={open} onOpenChange={setOpen} title='Delete this post?' confirmText='gold rush' confirmLabel='Delete forever' onConfirm={handleDelete}><Note tone='warning'>People you shared this post with lose access to it.</Note></DestructiveActionModal>
|
|
76
76
|
```
|
|
@@ -107,7 +107,7 @@ import { Button, Carousel, Dialog, DialogContent, DialogTrigger } from "@sableui
|
|
|
107
107
|
```tsx
|
|
108
108
|
import { Button, Dialog, DialogClose, DialogContent, DialogDescription, DialogFooter, DialogHeader, DialogTitle, DialogTrigger } from "@sableui/react"
|
|
109
109
|
|
|
110
|
-
<Dialog><DialogTrigger render={<Button>Open</Button>} /><DialogContent><DialogHeader><DialogTitle>
|
|
110
|
+
<Dialog><DialogTrigger render={<Button>Open</Button>} /><DialogContent><DialogHeader><DialogTitle>Plan details</DialogTitle><DialogDescription>Up to 10 seats, billed monthly per seat.</DialogDescription></DialogHeader><DialogFooter><DialogClose render={<Button variant="secondary">Close</Button>} /><DialogClose render={<Button>Upgrade</Button>} /></DialogFooter></DialogContent></Dialog>
|
|
111
111
|
```
|
|
112
112
|
|
|
113
113
|
### Settings form
|
|
@@ -123,5 +123,5 @@ import { Button, Dialog, DialogClose, DialogContent, DialogDescription, DialogFo
|
|
|
123
123
|
```tsx
|
|
124
124
|
import { AlertDialog, AlertDialogClose, AlertDialogContent, AlertDialogDescription, AlertDialogFooter, AlertDialogHeader, AlertDialogTitle, AlertDialogTrigger, Button } from "@sableui/react"
|
|
125
125
|
|
|
126
|
-
<AlertDialog><AlertDialogTrigger render={<Button variant="destructive">Delete
|
|
126
|
+
<AlertDialog><AlertDialogTrigger render={<Button variant="destructive">Delete project</Button>} /><AlertDialogContent><AlertDialogHeader><AlertDialogTitle>Delete project?</AlertDialogTitle><AlertDialogDescription>This removes the project and cannot be undone.</AlertDialogDescription></AlertDialogHeader><AlertDialogFooter><AlertDialogClose render={<Button variant="secondary">Cancel</Button>} /><Button variant="destructive" onClick={deleteProject}>Delete project</Button></AlertDialogFooter></AlertDialogContent></AlertDialog>
|
|
127
127
|
```
|
|
@@ -41,7 +41,7 @@ Use DisclosurePicker for one-of-many choices in a docked panel or inspector wher
|
|
|
41
41
|
| DisclosurePickerTrigger | { label?: ReactNode; media?: ReactNode; children?: ReactNode } + Base UI Collapsible.Trigger props | The row. `label` is a muted leading caption on a fixed column so stacked rows align; `media` a leading visual (a ThemePreview tile); children the value, truncated on one line. ArrowDown opens it, and steps into the list once open. |
|
|
42
42
|
| DisclosurePickerPanel | { search?: { value: string; onValueChange(value: string): void; placeholder?: string; label?: string } } + Collapsible.Panel props | Opens beneath the row. `search` opts in to a SearchInput above the list (off by default); it is controlled because the consumer filters, and it is cleared when the row closes. Escape clears a query first, then closes; ArrowDown in the field steps into the list. |
|
|
43
43
|
| DisclosurePickerList | { value: string; onValueChange(value: string): void; aria-label?: string } + div props | A listbox. ArrowUp/ArrowDown, Home/End and type-ahead move focus without applying anything (ArrowUp from the first option returns to the search field); Enter, Space or a click picks the focused option — onValueChange fires once, only when it differs from `value` — and closes the row. Escape closes without a pick. |
|
|
44
|
-
| DisclosurePickerOption | { value: string; children?: ReactNode; media?: ReactNode; note?: ReactNode; disabled?: boolean; textValue?: string } | One option row. `media` is a leading visual (a ThemePreview tile); `note` a muted trailing annotation — options without one show a check when chosen. `disabled` skips it for the keyboard and refuses the pick; `textValue` is what type-ahead matches when the name is not plain text. |
|
|
44
|
+
| DisclosurePickerOption | { value: string; children?: ReactNode; media?: ReactNode; note?: ReactNode; disabled?: boolean; textValue?: string; onRemove?: () => void; removeLabel?: string } | One option row. `media` is a leading visual (a ThemePreview tile); `note` a muted trailing annotation — options without one show a check when chosen. `disabled` skips it for the keyboard and refuses the pick; `textValue` is what type-ahead matches when the name is not plain text. `onRemove` makes the option removable — for entries the person added (an imported preset, a saved font): a trash glyph at the row's end on hover or focus (always on touch), and Delete or Backspace on the focused row; removing never picks, and focus moves to a neighbour first. `removeLabel` is the glyph's tooltip. |
|
|
45
45
|
| DisclosurePickerEmpty | { children?: ReactNode } | The no-match line, rendered in place of the list. |
|
|
46
46
|
| useDisclosurePicker | () => { open: boolean; close(): void; size: "md" \| "xs" } | For a list the picker does not own (a Tree) that should close the row when something is picked. |
|
|
47
47
|
|
|
@@ -73,6 +73,7 @@ Use DisclosurePicker for one-of-many choices in a docked panel or inspector wher
|
|
|
73
73
|
- Why a listbox and not a radio group: a radio group's checked state follows focus, so every arrow press would be a pick — wrong for a choice that opens a confirm, loads a font or resets settings. Base UI ships no standalone listbox (Select is popup-only, Combobox's inline list is focus-in-the-input, Composite is internal), so the keyboard model lives here.
|
|
74
74
|
- Opening from the keyboard (Enter, Space, ArrowDown) moves focus into the panel: the search field when there is one, otherwise the chosen option (or the first). A pointer open focuses the search field on a fine pointer only, so touch does not raise the on-screen keyboard.
|
|
75
75
|
- Escape closes the row without changing the value (clearing a query first) and returns focus to the trigger; a pick does the same. Focus is not pulled back when it has already moved on, e.g. to a confirm dialog the pick opened.
|
|
76
|
+
- A removable option (onRemove) announces aria-keyshortcuts="Delete"; Delete or Backspace removes it and focus moves to the next option (or the previous). The trash glyph is a pointer target only (aria-hidden, not focusable): an option's children are presentational, so a nested button would be unreachable by assistive tech anyway.
|
|
76
77
|
- The panel animates with motion-disclosure, which is static under prefers-reduced-motion or MotionProvider off; the scroll that keeps the row in view is instant, never smooth.
|
|
77
78
|
|
|
78
79
|
## Related
|
|
@@ -12,7 +12,7 @@ Use EmptyState when a content area has no items, no search results, or no first-
|
|
|
12
12
|
|
|
13
13
|
### Best practices
|
|
14
14
|
|
|
15
|
-
- Do: Explain what is empty in plain language, such as "No posts yet" or "No matching
|
|
15
|
+
- Do: Explain what is empty in plain language, such as "No posts yet" or "No matching customers".
|
|
16
16
|
- Do: Offer one next step when the user can recover, create, clear filters, or start setup.
|
|
17
17
|
- Do: Keep the icon decorative and make the title carry the meaning.
|
|
18
18
|
- Do: For a search or filter result, name the query back to the user and offer the way out, such as "No results for 'quarterly'" with a Clear filters action. An empty result that does not say what was searched leaves the user unsure whether the query or the data was wrong.
|
|
@@ -85,7 +85,7 @@ import { Button, EmptyState, Icon } from "@sableui/react"
|
|
|
85
85
|
```tsx
|
|
86
86
|
import { Button, EmptyState, Icon, Row } from "@sableui/react"
|
|
87
87
|
|
|
88
|
-
<EmptyState surface="card" icon={<Icon name="sparkles" />} title="Start your
|
|
88
|
+
<EmptyState surface="card" icon={<Icon name="sparkles" />} title="Start your first project" description="Create a project, import one from a file, or invite collaborators." action={<Row gap={1}><Button>Create project</Button><Button variant="ghost">Import</Button></Row>} />
|
|
89
89
|
```
|
|
90
90
|
|
|
91
91
|
### Page-level error
|
|
@@ -101,7 +101,7 @@ import { Button, EmptyState } from "@sableui/react"
|
|
|
101
101
|
```tsx
|
|
102
102
|
import { Button, EmptyState } from "@sableui/react"
|
|
103
103
|
|
|
104
|
-
<EmptyState tone="destructive" surface="card" title="Could not load this
|
|
104
|
+
<EmptyState tone="destructive" surface="card" title="Could not load this project" description="Check your connection and try again." action={<Button variant="secondary">Retry</Button>} />
|
|
105
105
|
```
|
|
106
106
|
|
|
107
107
|
### Empty table body
|
|
@@ -109,5 +109,5 @@ import { Button, EmptyState } from "@sableui/react"
|
|
|
109
109
|
```tsx
|
|
110
110
|
import { DataTable, EmptyState } from "@sableui/react"
|
|
111
111
|
|
|
112
|
-
<DataTable data={[]} columns={[{ key: "name", header: "
|
|
112
|
+
<DataTable data={[]} columns={[{ key: "name", header: "Customer" }, { key: "status", header: "Status" }]} empty={<EmptyState title="No customers yet" description="Customers appear here after the first order." />} />
|
|
113
113
|
```
|
|
@@ -24,7 +24,7 @@ Use GradientArt where a real image belongs but none exists yet, or where the ima
|
|
|
24
24
|
| Name | Type | Default | Description |
|
|
25
25
|
| --- | --- | --- | --- |
|
|
26
26
|
| variant | "mesh" \| "grain" | "mesh" | mesh: soft spots of colour pulled together by gentle waves. grain: glowing light over deep corners with a printed texture. |
|
|
27
|
-
| tones | ("info" \| "
|
|
27
|
+
| tones | ("info" \| "3" \| "2" \| "1" \| "warning")[] | — | Paint these `--tone-*` colours instead of the preset's art palette. Leave unset to follow the preset's art direction. |
|
|
28
28
|
| seed | string \| number | — | Fixes the composition: the same seed paints the same art in every theme. Pass a stable id. |
|
|
29
29
|
| children | ReactNode | — | Rendered above the art — initials, a glyph, a short label. |
|
|
30
30
|
| className | string | — | Size and shape: aspect, height, rounding. |
|
|
@@ -35,7 +35,7 @@ Use GradientArt where a real image belongs but none exists yet, or where the ima
|
|
|
35
35
|
|
|
36
36
|
## Tokens used
|
|
37
37
|
|
|
38
|
-
`art-1`, `art-2`, `art-3`, `art-4`, `art-5`, `art-6`, `art-ground`, `art-warp`, `art-softness`, `art-grain`, `primary`, `tone-info`, `tone-
|
|
38
|
+
`art-1`, `art-2`, `art-3`, `art-4`, `art-5`, `art-6`, `art-ground`, `art-warp`, `art-softness`, `art-grain`, `primary`, `tone-info`, `tone-3`, `tone-2`, `tone-1`, `tone-warning`
|
|
39
39
|
|
|
40
40
|
## Motion
|
|
41
41
|
|
|
@@ -68,7 +68,7 @@ import { GradientArt } from "@sableui/react"
|
|
|
68
68
|
```tsx
|
|
69
69
|
import { GradientArt } from "@sableui/react"
|
|
70
70
|
|
|
71
|
-
<GradientArt variant="grain" seed="juno" tones={["info", "
|
|
71
|
+
<GradientArt variant="grain" seed="juno" tones={["info", "1"]} className="h-20 rounded-md" />
|
|
72
72
|
```
|
|
73
73
|
|
|
74
74
|
### Avatar with initials
|
package/llms/components/label.md
CHANGED
|
@@ -69,5 +69,5 @@ import { Field, Input } from "@sableui/react"
|
|
|
69
69
|
```tsx
|
|
70
70
|
import { Label } from "@sableui/react"
|
|
71
71
|
|
|
72
|
-
<Label htmlFor="
|
|
72
|
+
<Label htmlFor="discount" hint="Taken off every order this code is used on.">Discount</Label>
|
|
73
73
|
```
|
|
@@ -45,7 +45,7 @@ Use LineChart to compare how two or more measures change over the same sequence,
|
|
|
45
45
|
|
|
46
46
|
## Tokens used
|
|
47
47
|
|
|
48
|
-
`tone-
|
|
48
|
+
`tone-1`, `tone-2`, `tone-3`, `tone-info`, `tone-warning`, `primary`, `muted-foreground`, `border`, `popover`, `popover-foreground`, `foreground`, `background`
|
|
49
49
|
|
|
50
50
|
## Motion
|
|
51
51
|
|
package/llms/components/meter.md
CHANGED
|
@@ -43,7 +43,7 @@ Use Meter to show a static measurement against a known maximum — storage used,
|
|
|
43
43
|
| value | number | — | The current reading, between min and max. Required. |
|
|
44
44
|
| min | number | 0 | The bottom of the range. |
|
|
45
45
|
| max | number | 100 | The top of the range. |
|
|
46
|
-
| tone | "primary" \| "
|
|
46
|
+
| tone | "primary" \| "3" \| "success" \| "warning" \| "destructive" | "primary" | Fill colour, mapped to a semantic token. Choose it from your own thresholds. |
|
|
47
47
|
| shape | "bar" \| "ring" | "bar" | bar is a horizontal track; ring is a circular gauge for a small, glanceable reading — the same value, min, max and tones. |
|
|
48
48
|
| size | "sm" \| "md" \| "lg" | "md" | Ring diameter (40 / 64 / 96px at the default spacing; the centre value steps with it), or bar thickness on the same sm / md / lg rails as Progress. |
|
|
49
49
|
| showValue | boolean | — | Print the value in the ring's centre (formatted like MeterValue). |
|
|
@@ -54,7 +54,7 @@ Use Meter to show a static measurement against a known maximum — storage used,
|
|
|
54
54
|
|
|
55
55
|
## Variants
|
|
56
56
|
|
|
57
|
-
- **tone**: primary,
|
|
57
|
+
- **tone**: primary, 3, success, warning, destructive
|
|
58
58
|
- **shape**: bar, ring
|
|
59
59
|
- **size**: sm, md, lg
|
|
60
60
|
|