@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
|
@@ -60,6 +60,11 @@ var panelSectionMeta = {
|
|
|
60
60
|
name: "PropertyPair",
|
|
61
61
|
required: false,
|
|
62
62
|
description: "Two controls side by side, with optional captions above each."
|
|
63
|
+
},
|
|
64
|
+
{
|
|
65
|
+
name: "PropertyGroup",
|
|
66
|
+
required: false,
|
|
67
|
+
description: "A set of properties folded behind one row that names the group and summarises its value, opening with +/\u2212 to the controls beneath."
|
|
63
68
|
}
|
|
64
69
|
]
|
|
65
70
|
},
|
|
@@ -89,9 +94,15 @@ var panelSectionMeta = {
|
|
|
89
94
|
name: "PropertyPair",
|
|
90
95
|
type: "{ labels?: [ReactNode, ReactNode] }",
|
|
91
96
|
description: "Two controls side by side in a 2-up grid, with optional captions above each."
|
|
97
|
+
},
|
|
98
|
+
{
|
|
99
|
+
name: "PropertyGroup",
|
|
100
|
+
type: "{ label: ReactNode; summary?: ReactNode; defaultOpen?: boolean; open?: boolean; onOpenChange?: (open: boolean) => void }",
|
|
101
|
+
description: "A collapsible set of properties inside a section, at the panel's scale (an Accordion is page furniture). The row shows the label, then the summary (the group's value, readable while closed: a word, a few swatches, or both), then a + that turns to \u2212 when open. Groups open independently and stack with a hairline between them. Built on Collapsible."
|
|
92
102
|
}
|
|
93
103
|
],
|
|
94
104
|
a11y: [
|
|
105
|
+
"PropertyGroup's row is a real button with aria-expanded (Collapsible); its summary is part of the button's name, so a closed group still announces its value.",
|
|
95
106
|
"PropertyRow renders a real <label>; pass htmlFor with the control's id so clicking the label focuses it.",
|
|
96
107
|
"The section title is an h3, so panels contribute a real heading outline rather than styled divs.",
|
|
97
108
|
"`hint` is exposed as the label's title attribute \u2014 keep the essential meaning in the label itself, since title text is not reliably announced.",
|
|
@@ -99,6 +110,27 @@ var panelSectionMeta = {
|
|
|
99
110
|
],
|
|
100
111
|
tokensUsed: ["foreground", "muted-foreground", "hairline"],
|
|
101
112
|
examples: [
|
|
113
|
+
{
|
|
114
|
+
label: "Groups that fold behind their value",
|
|
115
|
+
code: `<PanelSection title="Color">
|
|
116
|
+
<PropertyGroup label="Tones" summary="Brand only">
|
|
117
|
+
<PropertyRow label="Scheme">
|
|
118
|
+
<Select value="brand">
|
|
119
|
+
<SelectTrigger size="xs" />
|
|
120
|
+
<SelectContent>
|
|
121
|
+
<SelectItem value="brand">Brand only</SelectItem>
|
|
122
|
+
<SelectItem value="harmonize">Harmonize</SelectItem>
|
|
123
|
+
</SelectContent>
|
|
124
|
+
</Select>
|
|
125
|
+
</PropertyRow>
|
|
126
|
+
</PropertyGroup>
|
|
127
|
+
<PropertyGroup label="Grid" summary="8px">
|
|
128
|
+
<PropertyRow label="Size">
|
|
129
|
+
<ScrubField label="Grid size" value={8} min={1} max={64} suffix="px" />
|
|
130
|
+
</PropertyRow>
|
|
131
|
+
</PropertyGroup>
|
|
132
|
+
</PanelSection>`
|
|
133
|
+
},
|
|
102
134
|
{
|
|
103
135
|
label: "Blending section, 2-up",
|
|
104
136
|
code: `<PanelSection title="Blending">
|
|
@@ -67,7 +67,7 @@ var phoneMeta = {
|
|
|
67
67
|
examples: [
|
|
68
68
|
{
|
|
69
69
|
label: "Framing a mobile layout",
|
|
70
|
-
code: '<Phone><div className="p-4"><h2 className="text-title-lg">Activity</h2><p className="text-body-sm text-muted-foreground">3 new
|
|
70
|
+
code: '<Phone><div className="p-4"><h2 className="text-title-lg">Activity</h2><p className="text-body-sm text-muted-foreground">3 new orders today.</p></div></Phone>'
|
|
71
71
|
},
|
|
72
72
|
{
|
|
73
73
|
label: "Mockup, not a responsive preview",
|
|
@@ -1,15 +1,17 @@
|
|
|
1
1
|
// src/components/pill/pill.tsx
|
|
2
2
|
import { cn } from "../../lib/cn.js";
|
|
3
|
+
import { isPaletteColor } from "../../lib/palette.js";
|
|
3
4
|
import { trimLabel } from "../../lib/trim-label.js";
|
|
4
5
|
import { pillVariants } from "./pill.variants.js";
|
|
5
6
|
import { jsxs } from "react/jsx-runtime";
|
|
6
|
-
function Pill({ selected = false, appearance, size, icon, className, children, type, ...props }) {
|
|
7
|
+
function Pill({ selected = false, appearance, size, tone, icon, className, children, type, ...props }) {
|
|
7
8
|
return /* @__PURE__ */ jsxs(
|
|
8
9
|
"button",
|
|
9
10
|
{
|
|
10
11
|
type: type ?? "button",
|
|
11
12
|
"aria-pressed": selected,
|
|
12
|
-
|
|
13
|
+
"data-palette": isPaletteColor(tone) ? tone : void 0,
|
|
14
|
+
className: cn(pillVariants({ appearance, size, selected, tone }), className),
|
|
13
15
|
...props,
|
|
14
16
|
children: [
|
|
15
17
|
icon,
|
|
@@ -61,6 +61,12 @@ var pillMeta = {
|
|
|
61
61
|
default: '"md"',
|
|
62
62
|
description: "md sits on the density ladder's xs control height (28px); sm is 24px, for chips under or inside other content."
|
|
63
63
|
},
|
|
64
|
+
{
|
|
65
|
+
name: "tone",
|
|
66
|
+
type: '"neutral" | "red" | "orange" | "yellow" | "green" | "teal" | "blue" | "purple" | "pink"',
|
|
67
|
+
default: '"neutral"',
|
|
68
|
+
description: "neutral is the chip as described. A palette family colours it as a category, like the choices in a tag picker: a wash at rest, the solid family colour when selected. Painted from the theme's generated palette."
|
|
69
|
+
},
|
|
64
70
|
{
|
|
65
71
|
name: "icon",
|
|
66
72
|
type: "ReactNode",
|
|
@@ -70,9 +76,16 @@ var pillMeta = {
|
|
|
70
76
|
variants: {
|
|
71
77
|
appearance: ["solid", "outline"],
|
|
72
78
|
size: ["md", "sm"],
|
|
73
|
-
selected: ["true", "false"]
|
|
79
|
+
selected: ["true", "false"],
|
|
80
|
+
tone: ["neutral", "red", "orange", "yellow", "green", "teal", "blue", "purple", "pink"]
|
|
74
81
|
},
|
|
75
82
|
tokensUsed: [
|
|
83
|
+
"palette-wash",
|
|
84
|
+
"palette-wash-strong",
|
|
85
|
+
"palette-edge",
|
|
86
|
+
"palette-solid",
|
|
87
|
+
"palette-text",
|
|
88
|
+
"palette-solid-ink",
|
|
76
89
|
"secondary",
|
|
77
90
|
"secondary-foreground",
|
|
78
91
|
"accent",
|
|
@@ -89,9 +102,13 @@ var pillMeta = {
|
|
|
89
102
|
"Selected state is exposed via aria-pressed."
|
|
90
103
|
],
|
|
91
104
|
examples: [
|
|
105
|
+
{
|
|
106
|
+
label: "Tag picker",
|
|
107
|
+
code: '<Row gap={1}><Pill tone="blue" selected onClick={() => {}}>Design</Pill><Pill tone="teal" onClick={() => {}}>Research</Pill><Pill tone="orange" onClick={() => {}}>Marketing</Pill></Row>'
|
|
108
|
+
},
|
|
92
109
|
{
|
|
93
110
|
label: "Filter row",
|
|
94
|
-
code: "<Row gap={1}><Pill selected onClick={() => {}}>All</Pill><Pill onClick={() => {}}>
|
|
111
|
+
code: "<Row gap={1}><Pill selected onClick={() => {}}>All</Pill><Pill onClick={() => {}}>Projects</Pill><Pill onClick={() => {}}>Reports</Pill></Row>"
|
|
95
112
|
},
|
|
96
113
|
{
|
|
97
114
|
label: "Outline, small (reactions)",
|
|
@@ -1,5 +1,6 @@
|
|
|
1
1
|
// src/components/pill/pill.variants.ts
|
|
2
2
|
import { cva } from "class-variance-authority";
|
|
3
|
+
import { PALETTE_COLORS } from "../../lib/palette.js";
|
|
3
4
|
var pillVariants = cva(
|
|
4
5
|
/*
|
|
5
6
|
* The asymmetric `pt-[0.23em] pb-[0.1em]` is the LEGACY optical correction: a
|
|
@@ -31,6 +32,20 @@ var pillVariants = cva(
|
|
|
31
32
|
selected: {
|
|
32
33
|
true: "",
|
|
33
34
|
false: ""
|
|
35
|
+
},
|
|
36
|
+
// `neutral` is the chip as described above. A palette family is a
|
|
37
|
+
// category colour (a tag someone picks): the chip paints from the slots
|
|
38
|
+
// its data-palette scope fills, so no step is named here.
|
|
39
|
+
tone: {
|
|
40
|
+
neutral: "",
|
|
41
|
+
red: "",
|
|
42
|
+
orange: "",
|
|
43
|
+
yellow: "",
|
|
44
|
+
green: "",
|
|
45
|
+
teal: "",
|
|
46
|
+
blue: "",
|
|
47
|
+
purple: "",
|
|
48
|
+
pink: ""
|
|
34
49
|
}
|
|
35
50
|
},
|
|
36
51
|
compoundVariants: [
|
|
@@ -51,12 +66,18 @@ var pillVariants = cva(
|
|
|
51
66
|
// Transparent on whatever it sits on; the hover is derived from that
|
|
52
67
|
// surface (sable-surface-interactive), not a fixed accent fill.
|
|
53
68
|
class: "border-border text-muted-foreground sable-surface-interactive"
|
|
54
|
-
}
|
|
69
|
+
},
|
|
70
|
+
// After the neutral looks, so cn's merge lets these win.
|
|
71
|
+
{ appearance: "solid", selected: false, tone: [...PALETTE_COLORS], class: "bg-palette-wash text-palette-text hover:bg-palette-wash-strong hover:text-palette-text" },
|
|
72
|
+
{ appearance: "solid", selected: true, tone: [...PALETTE_COLORS], class: "bg-palette-solid text-palette-solid-ink hover:bg-palette-solid" },
|
|
73
|
+
{ appearance: "outline", selected: false, tone: [...PALETTE_COLORS], class: "border-palette-edge text-palette-text" },
|
|
74
|
+
{ appearance: "outline", selected: true, tone: [...PALETTE_COLORS], class: "border-palette-edge bg-palette-wash text-palette-text hover:bg-palette-wash-strong" }
|
|
55
75
|
],
|
|
56
76
|
defaultVariants: {
|
|
57
77
|
appearance: "solid",
|
|
58
78
|
size: "md",
|
|
59
|
-
selected: false
|
|
79
|
+
selected: false,
|
|
80
|
+
tone: "neutral"
|
|
60
81
|
}
|
|
61
82
|
}
|
|
62
83
|
);
|
|
@@ -123,11 +123,11 @@ var popoverMeta = {
|
|
|
123
123
|
examples: [
|
|
124
124
|
{
|
|
125
125
|
label: "Basic",
|
|
126
|
-
code: '<Popover><PopoverTrigger render={<Button variant="secondary">Details</Button>} /><PopoverContent><PopoverTitle>
|
|
126
|
+
code: '<Popover><PopoverTrigger render={<Button variant="secondary">Details</Button>} /><PopoverContent><PopoverTitle>Plan details</PopoverTitle><PopoverDescription>Up to 10 seats, billed monthly per seat.</PopoverDescription></PopoverContent></Popover>'
|
|
127
127
|
},
|
|
128
128
|
{
|
|
129
129
|
label: "With close",
|
|
130
|
-
code: '<Popover><PopoverTrigger render={<Button variant="secondary">Open</Button>} /><PopoverContent><PopoverTitle>Heads up</PopoverTitle><PopoverDescription>
|
|
130
|
+
code: '<Popover><PopoverTrigger render={<Button variant="secondary">Open</Button>} /><PopoverContent><PopoverTitle>Heads up</PopoverTitle><PopoverDescription>Upgrading starts a new billing period today.</PopoverDescription><PopoverClose render={<Button size="sm">Got it</Button>} /></PopoverContent></Popover>'
|
|
131
131
|
}
|
|
132
132
|
]
|
|
133
133
|
};
|
|
@@ -80,7 +80,7 @@ var radioMeta = {
|
|
|
80
80
|
<FieldsetContent>
|
|
81
81
|
<RadioGroup defaultValue="standard">
|
|
82
82
|
<Field label="Standard" orientation="horizontal"><Radio value="standard" /></Field>
|
|
83
|
-
<Field label="
|
|
83
|
+
<Field label="Poll" orientation="horizontal"><Radio value="poll" /></Field>
|
|
84
84
|
</RadioGroup>
|
|
85
85
|
</FieldsetContent>
|
|
86
86
|
</Fieldset>`
|
|
@@ -92,7 +92,7 @@ var radioMeta = {
|
|
|
92
92
|
<FieldsetContent>
|
|
93
93
|
<RadioGroup defaultValue="standard">
|
|
94
94
|
<Field label="Standard" orientation="horizontal"><Radio value="standard" /></Field>
|
|
95
|
-
<Field label="
|
|
95
|
+
<Field label="Poll" orientation="horizontal" disabled><Radio value="poll" /></Field>
|
|
96
96
|
</RadioGroup>
|
|
97
97
|
</FieldsetContent>
|
|
98
98
|
</Fieldset>`
|
|
@@ -77,7 +77,7 @@ var radioCardMeta = {
|
|
|
77
77
|
},
|
|
78
78
|
{
|
|
79
79
|
name: "tone",
|
|
80
|
-
type: '"neutral" | "
|
|
80
|
+
type: '"neutral" | "3" | "2" | "1" | "info" | "warning"',
|
|
81
81
|
default: '"neutral"',
|
|
82
82
|
description: "Semantic colour the selected state carries across the border, radio, and icon glyph. Neutral uses the primary ring with a muted wash."
|
|
83
83
|
},
|
|
@@ -106,7 +106,7 @@ var radioCardMeta = {
|
|
|
106
106
|
}
|
|
107
107
|
],
|
|
108
108
|
variants: {
|
|
109
|
-
tone: ["neutral", "
|
|
109
|
+
tone: ["neutral", "3", "2", "1", "info", "warning"]
|
|
110
110
|
},
|
|
111
111
|
tokensUsed: [
|
|
112
112
|
"input",
|
|
@@ -116,9 +116,9 @@ var radioCardMeta = {
|
|
|
116
116
|
"muted",
|
|
117
117
|
"ring",
|
|
118
118
|
"muted-foreground",
|
|
119
|
-
"tone-
|
|
120
|
-
"tone-
|
|
121
|
-
"tone-
|
|
119
|
+
"tone-3",
|
|
120
|
+
"tone-2",
|
|
121
|
+
"tone-1",
|
|
122
122
|
"tone-info",
|
|
123
123
|
"tone-warning"
|
|
124
124
|
],
|
|
@@ -132,7 +132,7 @@ var radioCardMeta = {
|
|
|
132
132
|
examples: [
|
|
133
133
|
{
|
|
134
134
|
label: "Post type (tone + icon)",
|
|
135
|
-
code: '<RadioGroup defaultValue="
|
|
135
|
+
code: '<RadioGroup defaultValue="starter" className="grid sm:grid-cols-3"><RadioCard value="starter" tone="3" icon={<Icon name="plus" />} title="Starter" description="Free for one person" /><RadioCard value="studio" tone="2" icon={<Icon name="gem" />} title="Studio" description="For small teams" /><RadioCard value="business" tone="1" icon={<Icon name="image-stack" />} title="Business" description="SSO and audit log" /></RadioGroup>'
|
|
136
136
|
},
|
|
137
137
|
{
|
|
138
138
|
label: "Plan picker (plain)",
|
|
@@ -7,23 +7,23 @@ var radioCardToneClasses = {
|
|
|
7
7
|
dot: "bg-primary",
|
|
8
8
|
glyph: "text-foreground"
|
|
9
9
|
},
|
|
10
|
-
|
|
11
|
-
card: SELECTION_CARD_CHECKED
|
|
12
|
-
marker: "group-data-[checked]:border-tone-
|
|
13
|
-
dot: "bg-tone-
|
|
14
|
-
glyph: "text-tone-
|
|
10
|
+
"3": {
|
|
11
|
+
card: SELECTION_CARD_CHECKED["3"],
|
|
12
|
+
marker: "group-data-[checked]:border-tone-3",
|
|
13
|
+
dot: "bg-tone-3",
|
|
14
|
+
glyph: "text-tone-3"
|
|
15
15
|
},
|
|
16
|
-
|
|
17
|
-
card: SELECTION_CARD_CHECKED
|
|
18
|
-
marker: "group-data-[checked]:border-tone-
|
|
19
|
-
dot: "bg-tone-
|
|
20
|
-
glyph: "text-tone-
|
|
16
|
+
"2": {
|
|
17
|
+
card: SELECTION_CARD_CHECKED["2"],
|
|
18
|
+
marker: "group-data-[checked]:border-tone-2",
|
|
19
|
+
dot: "bg-tone-2",
|
|
20
|
+
glyph: "text-tone-2"
|
|
21
21
|
},
|
|
22
|
-
|
|
23
|
-
card: SELECTION_CARD_CHECKED
|
|
24
|
-
marker: "group-data-[checked]:border-tone-
|
|
25
|
-
dot: "bg-tone-
|
|
26
|
-
glyph: "text-tone-
|
|
22
|
+
"1": {
|
|
23
|
+
card: SELECTION_CARD_CHECKED["1"],
|
|
24
|
+
marker: "group-data-[checked]:border-tone-1",
|
|
25
|
+
dot: "bg-tone-1",
|
|
26
|
+
glyph: "text-tone-1"
|
|
27
27
|
},
|
|
28
28
|
info: {
|
|
29
29
|
card: SELECTION_CARD_CHECKED.info,
|
|
@@ -97,7 +97,7 @@ var scrollerMeta = {
|
|
|
97
97
|
examples: [
|
|
98
98
|
{
|
|
99
99
|
label: "Vertical with overflow",
|
|
100
|
-
code: '<Scroller label="
|
|
100
|
+
code: '<Scroller label="Projects" className="h-64"><ul className="space-y-2 p-4">{items.map((item) => (<li key={item.id} className="text-body-sm">{item.title}</li>))}</ul></Scroller>'
|
|
101
101
|
},
|
|
102
102
|
{
|
|
103
103
|
label: "Capped, scrolls past the cap",
|
|
@@ -116,7 +116,7 @@ var searchInputMeta = {
|
|
|
116
116
|
},
|
|
117
117
|
{
|
|
118
118
|
label: "Uncontrolled, sized as a whole",
|
|
119
|
-
code: '<Field label="Search posts"><SearchInput defaultValue="
|
|
119
|
+
code: '<Field label="Search posts"><SearchInput defaultValue="roadmap" className="max-w-80" /></Field>'
|
|
120
120
|
},
|
|
121
121
|
{
|
|
122
122
|
label: "Disabled",
|
|
@@ -18,7 +18,7 @@ function SectionHeader({
|
|
|
18
18
|
...props
|
|
19
19
|
}) {
|
|
20
20
|
const generatedId = useId();
|
|
21
|
-
return /* @__PURE__ */ jsxs("div", { "data-slot": "section-header", className: cn("flex flex-col gap-
|
|
21
|
+
return /* @__PURE__ */ jsxs("div", { "data-slot": "section-header", className: cn("flex flex-col gap-2", className), ...props, children: [
|
|
22
22
|
/* @__PURE__ */ jsx(
|
|
23
23
|
HeadingRow,
|
|
24
24
|
{
|
|
@@ -2,7 +2,7 @@
|
|
|
2
2
|
import { cn } from "../../lib/cn.js";
|
|
3
3
|
import { segmentedBarSegmentVariants, segmentedBarVariants } from "./segmented-bar.variants.js";
|
|
4
4
|
import { jsx } from "react/jsx-runtime";
|
|
5
|
-
var SEGMENTED_BAR_TONES = ["
|
|
5
|
+
var SEGMENTED_BAR_TONES = ["1", "2", "3", "info", "primary", "neutral"];
|
|
6
6
|
function SegmentedBar({ segments, label, locale, size, className, ...props }) {
|
|
7
7
|
const total = segments.reduce((sum, s) => sum + Math.max(0, s.value), 0);
|
|
8
8
|
const percent = new Intl.NumberFormat(locale, { style: "percent", maximumFractionDigits: 0 });
|
|
@@ -59,12 +59,12 @@ var segmentedBarMeta = {
|
|
|
59
59
|
],
|
|
60
60
|
variants: {
|
|
61
61
|
size: ["sm", "md", "lg"],
|
|
62
|
-
tone: ["
|
|
62
|
+
tone: ["1", "2", "3", "info", "primary", "neutral", "success", "warning", "destructive"]
|
|
63
63
|
},
|
|
64
64
|
tokensUsed: [
|
|
65
|
-
"tone-
|
|
66
|
-
"tone-
|
|
67
|
-
"tone-
|
|
65
|
+
"tone-1",
|
|
66
|
+
"tone-2",
|
|
67
|
+
"tone-3",
|
|
68
68
|
"tone-info",
|
|
69
69
|
"primary",
|
|
70
70
|
"muted-foreground",
|
|
@@ -89,13 +89,13 @@ var segmentedBarMeta = {
|
|
|
89
89
|
{ slot: "activity", recipe: "none", part: "SegmentedBar", why: "No indeterminate state \u2014 an unknown breakdown is not drawn." }
|
|
90
90
|
],
|
|
91
91
|
a11y: [
|
|
92
|
-
'Rendered role=img with an aria-label built from `label` and each segment\'s share ("Revenue by
|
|
92
|
+
'Rendered role=img with an aria-label built from `label` and each segment\'s share ("Revenue by channel: Direct 42%, Partners 27%"), so the whole breakdown is read in one stop.',
|
|
93
93
|
"Colour alone does not identify a segment: always show a legend with each segment's label beside the bar."
|
|
94
94
|
],
|
|
95
95
|
examples: [
|
|
96
96
|
{
|
|
97
97
|
label: "With a legend",
|
|
98
|
-
code: 'const sales = [\n { label: "
|
|
98
|
+
code: 'const sales = [\n { label: "Direct", value: 42, tone: "1" },\n { label: "Partners", value: 27, tone: "2" },\n { label: "Referrals", value: 19, tone: "3" },\n] as const\n\n<Stack gap={3}>\n <SegmentedBar label="Revenue by channel" segments={[...sales]} size="lg" />\n <ul className="flex flex-col gap-1.5">\n {sales.map((s) => (\n <li key={s.label} className="flex items-center gap-2 text-body-sm">\n <StatusDot tone={s.tone} />\n <span className="flex-1 text-muted-foreground">{s.label}</span>\n <span className="text-mono-caption">{s.value}%</span>\n </li>\n ))}\n </ul>\n</Stack>'
|
|
99
99
|
},
|
|
100
100
|
{
|
|
101
101
|
label: "Test results \u2014 status tones",
|
|
@@ -5,9 +5,9 @@ var segmentedBarSegmentVariants = cva(
|
|
|
5
5
|
{
|
|
6
6
|
variants: {
|
|
7
7
|
tone: {
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
8
|
+
"1": "bg-tone-1",
|
|
9
|
+
"2": "bg-tone-2",
|
|
10
|
+
"3": "bg-tone-3",
|
|
11
11
|
info: "bg-tone-info",
|
|
12
12
|
primary: "bg-primary",
|
|
13
13
|
neutral: "bg-muted-foreground",
|
|
@@ -17,7 +17,7 @@ var segmentedBarSegmentVariants = cva(
|
|
|
17
17
|
}
|
|
18
18
|
},
|
|
19
19
|
defaultVariants: {
|
|
20
|
-
tone: "
|
|
20
|
+
tone: "3"
|
|
21
21
|
}
|
|
22
22
|
}
|
|
23
23
|
);
|
|
@@ -176,11 +176,11 @@ var selectMeta = {
|
|
|
176
176
|
},
|
|
177
177
|
{
|
|
178
178
|
label: "Inside Field",
|
|
179
|
-
code: '<Field label="Default visibility" description="Controls how new
|
|
179
|
+
code: '<Field label="Default visibility" description="Controls how new projects appear."><Select defaultValue="public"><SelectTrigger placeholder="Choose visibility" /><SelectContent><SelectItem value="public">Public</SelectItem><SelectItem value="private">Private</SelectItem><SelectItem value="unlisted">Unlisted</SelectItem></SelectContent></Select></Field>'
|
|
180
180
|
},
|
|
181
181
|
{
|
|
182
182
|
label: "Rich item labels",
|
|
183
|
-
code: '<Select defaultValue="
|
|
183
|
+
code: '<Select defaultValue="business" items={[{ value: "business", label: "Business" }, { value: "studio", label: "Studio" }]}><SelectTrigger /><SelectContent><SelectItem value="business" label="Business"><span className="flex items-center gap-2"><Badge tone="1">Business</Badge><span>Business plan</span></span></SelectItem><SelectItem value="studio" label="Studio"><span className="flex items-center gap-2"><Badge tone="2">Studio</Badge><span>Studio</span></span></SelectItem></SelectContent></Select>'
|
|
184
184
|
}
|
|
185
185
|
]
|
|
186
186
|
};
|
|
@@ -158,7 +158,7 @@ var sheetMeta = {
|
|
|
158
158
|
},
|
|
159
159
|
{
|
|
160
160
|
label: "Bottom side",
|
|
161
|
-
code: '<Sheet><SheetTrigger render={<Button variant="secondary">Details</Button>} /><SheetContent side="bottom"><SheetHeader><SheetTitle>
|
|
161
|
+
code: '<Sheet><SheetTrigger render={<Button variant="secondary">Details</Button>} /><SheetContent side="bottom"><SheetHeader><SheetTitle>Order details</SheetTitle></SheetHeader><SheetFooter><SheetClose render={<Button variant="secondary">Close</Button>} /></SheetFooter></SheetContent></Sheet>'
|
|
162
162
|
}
|
|
163
163
|
]
|
|
164
164
|
};
|
|
@@ -122,7 +122,7 @@ var sideNavMeta = {
|
|
|
122
122
|
},
|
|
123
123
|
{
|
|
124
124
|
label: "Chrome-weight rail (size=lg)",
|
|
125
|
-
code: '<SideNav size="lg"><SideNavItem label="Profile" active render={<Link to="/settings/profile" />} /><SideNavItem label="
|
|
125
|
+
code: '<SideNav size="lg"><SideNavItem label="Profile" active render={<Link to="/settings/profile" />} /><SideNavItem label="Billing" render={<Link to="/settings/billing" />} /><SideNavItem label="Security" render={<Link to="/settings/security" />} /></SideNav>'
|
|
126
126
|
},
|
|
127
127
|
{
|
|
128
128
|
label: "Inside Sidebar chrome",
|
|
@@ -106,7 +106,7 @@ var sidebarMeta = {
|
|
|
106
106
|
examples: [
|
|
107
107
|
{
|
|
108
108
|
label: "Rail with nav",
|
|
109
|
-
code: '<Sidebar><SidebarHeader><SidebarBrand mark={<Icon name="music" variant="solid" />} label="Undertow" render={<Link to="/" />} /></SidebarHeader><SidebarNav><SidebarItem icon={<Icon name="bell" />} label="Notifications" badge={<NotificationBadge count={3} />} render={<Link to="/notifications" />} /></SidebarNav><SidebarFooter>{
|
|
109
|
+
code: '<Sidebar><SidebarHeader><SidebarBrand mark={<Icon name="music" variant="solid" />} label="Undertow" render={<Link to="/" />} /></SidebarHeader><SidebarNav><SidebarItem icon={<Icon name="bell" />} label="Notifications" badge={<NotificationBadge count={3} />} render={<Link to="/notifications" />} /></SidebarNav><SidebarFooter>{account}</SidebarFooter></Sidebar>'
|
|
110
110
|
},
|
|
111
111
|
{
|
|
112
112
|
label: "Collapsible (icon rail)",
|
|
@@ -60,7 +60,7 @@ var sparklineMeta = {
|
|
|
60
60
|
},
|
|
61
61
|
{
|
|
62
62
|
name: "tone",
|
|
63
|
-
type: '"
|
|
63
|
+
type: '"1" | "2" | "3" | "info" | "warning" | "primary" | "neutral" | "success" | "destructive"',
|
|
64
64
|
default: '"primary"',
|
|
65
65
|
description: "Colour by role."
|
|
66
66
|
},
|
|
@@ -92,9 +92,9 @@ var sparklineMeta = {
|
|
|
92
92
|
},
|
|
93
93
|
tokensUsed: [
|
|
94
94
|
"primary",
|
|
95
|
-
"tone-
|
|
96
|
-
"tone-
|
|
97
|
-
"tone-
|
|
95
|
+
"tone-1",
|
|
96
|
+
"tone-2",
|
|
97
|
+
"tone-3",
|
|
98
98
|
"tone-info",
|
|
99
99
|
"tone-warning",
|
|
100
100
|
"muted-foreground",
|
|
@@ -1,5 +1,6 @@
|
|
|
1
1
|
// src/components/status-dot/status-dot.tsx
|
|
2
2
|
import { cn } from "../../lib/cn.js";
|
|
3
|
+
import { isPaletteColor } from "../../lib/palette.js";
|
|
3
4
|
import { statusDotVariants } from "./status-dot.variants.js";
|
|
4
5
|
import { jsx, jsxs } from "react/jsx-runtime";
|
|
5
6
|
function StatusDot({
|
|
@@ -10,11 +11,13 @@ function StatusDot({
|
|
|
10
11
|
...props
|
|
11
12
|
}) {
|
|
12
13
|
const dot = statusDotVariants({ tone, size });
|
|
14
|
+
const palette = isPaletteColor(tone) ? tone : void 0;
|
|
13
15
|
if (pulse) {
|
|
14
16
|
return /* @__PURE__ */ jsxs(
|
|
15
17
|
"span",
|
|
16
18
|
{
|
|
17
19
|
"aria-hidden": "true",
|
|
20
|
+
"data-palette": palette,
|
|
18
21
|
className: cn("relative inline-flex shrink-0", className),
|
|
19
22
|
...props,
|
|
20
23
|
children: [
|
|
@@ -32,7 +35,7 @@ function StatusDot({
|
|
|
32
35
|
}
|
|
33
36
|
);
|
|
34
37
|
}
|
|
35
|
-
return /* @__PURE__ */ jsx("span", { "aria-hidden": "true", className: cn(dot, className), ...props });
|
|
38
|
+
return /* @__PURE__ */ jsx("span", { "aria-hidden": "true", "data-palette": palette, className: cn(dot, className), ...props });
|
|
36
39
|
}
|
|
37
40
|
StatusDot.displayName = "StatusDot";
|
|
38
41
|
export {
|
|
@@ -53,9 +53,9 @@ var statusDotMeta = {
|
|
|
53
53
|
props: [
|
|
54
54
|
{
|
|
55
55
|
name: "tone",
|
|
56
|
-
type: '"neutral" | "
|
|
56
|
+
type: '"neutral" | "1" | "2" | "3" | "success" | "warning" | "info" | "destructive" | "red" | "orange" | "yellow" | "green" | "teal" | "blue" | "purple" | "pink"',
|
|
57
57
|
default: '"neutral"',
|
|
58
|
-
description: "Semantic color of the dot."
|
|
58
|
+
description: "Semantic color of the dot, or a palette family (red \u2026 pink) for a category legend."
|
|
59
59
|
},
|
|
60
60
|
{
|
|
61
61
|
name: "size",
|
|
@@ -71,26 +71,18 @@ var statusDotMeta = {
|
|
|
71
71
|
}
|
|
72
72
|
],
|
|
73
73
|
variants: {
|
|
74
|
-
tone: [
|
|
75
|
-
"neutral",
|
|
76
|
-
"standard",
|
|
77
|
-
"success",
|
|
78
|
-
"warning",
|
|
79
|
-
"info",
|
|
80
|
-
"edition",
|
|
81
|
-
"collectible",
|
|
82
|
-
"destructive"
|
|
83
|
-
],
|
|
74
|
+
tone: ["neutral", "1", "2", "3", "success", "warning", "info", "destructive", "red", "orange", "yellow", "green", "teal", "blue", "purple", "pink"],
|
|
84
75
|
size: ["sm", "md", "lg"]
|
|
85
76
|
},
|
|
86
77
|
tokensUsed: [
|
|
78
|
+
"palette-dot",
|
|
87
79
|
"muted-foreground",
|
|
88
|
-
"tone-
|
|
80
|
+
"tone-3",
|
|
89
81
|
"success",
|
|
90
82
|
"tone-warning",
|
|
91
83
|
"tone-info",
|
|
92
|
-
"tone-
|
|
93
|
-
"tone-
|
|
84
|
+
"tone-1",
|
|
85
|
+
"tone-2",
|
|
94
86
|
"destructive"
|
|
95
87
|
],
|
|
96
88
|
a11y: [
|
|
@@ -100,7 +92,7 @@ var statusDotMeta = {
|
|
|
100
92
|
examples: [
|
|
101
93
|
{
|
|
102
94
|
label: "Tones",
|
|
103
|
-
code: '<Row gap={2}><StatusDot tone="
|
|
95
|
+
code: '<Row gap={2}><StatusDot tone="3" /><StatusDot tone="info" /><StatusDot tone="warning" /><StatusDot tone="destructive" /></Row>'
|
|
104
96
|
},
|
|
105
97
|
{
|
|
106
98
|
label: "With label \u2014 use Badge",
|