@vegastack/design 0.7.2 → 0.7.4
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/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@vegastack/design",
|
|
3
|
-
"version": "0.7.
|
|
3
|
+
"version": "0.7.4",
|
|
4
4
|
"description": "VegaStack design system — cn utility, icon runtime, Tailwind v4 preset, and the vegastack-design CLI (tokens ship separately as @vegastack/design-tokens)",
|
|
5
5
|
"license": "MIT",
|
|
6
6
|
"repository": {
|
|
@@ -23,7 +23,7 @@ writes:
|
|
|
23
23
|
`CheckboxGroup` → `FieldSet` + `Checkbox` ·
|
|
24
24
|
`FieldInline` → `EditableCell` · `Segmented` → a joined `ToggleGroup` · `SplitButton` → a
|
|
25
25
|
`ButtonGroup` composition · `ProgressIndicator` → `Progress` + `Spinner` · `OnboardingChecklist` →
|
|
26
|
-
|
|
26
|
+
an `ItemGroup` of `Item` rows under a `Progress`. The ten marketing components were deleted outright.
|
|
27
27
|
- **Gone from the token layer:** the surface ladder (`surface-1/2/3`), every `--alpha-*` and
|
|
28
28
|
`--opacity-*`, `--size-*`, `--icon-*`, `--z-*`, `--shadow-overlay`, and the role type scale
|
|
29
29
|
(`text-h1`, `text-label`, `text-code`, `text-mono-label`, `text-display-*`).
|
|
@@ -58,26 +58,81 @@ link` (upstream's set, verbatim). `destructive` is a soft tint, not a solid red
|
|
|
58
58
|
control height — `Chip` (`sm`/`md`, the inline and control pill scales), `StatusIcon`, `Stat` and
|
|
59
59
|
`Image`'s corner — and they say so on their own pages.
|
|
60
60
|
- **Compose `app-shell`** for a sidebar + header + main layout — never hand-roll the landmark trio.
|
|
61
|
+
- **Space a page with the page-rhythm recipe** — gutters `px-4 py-6` / `md:px-8 md:py-8`,
|
|
62
|
+
`gap-6` under `PageHeader`, `gap-8` between sections, `gap-3` from a section heading or a list
|
|
63
|
+
toolbar to its content, `--card-spacing` inside a card, and `FieldGroup`'s own gaps in a form
|
|
64
|
+
(<https://design.vegastack.com/docs/foundations/spacing#page-rhythm>).
|
|
61
65
|
- **`select`** for a short fixed option set; **`searchable-select`** when the list is long enough to
|
|
62
66
|
need a search field (it is the preset `country-select` and `region-select` are built from — reach
|
|
63
67
|
for it before composing `combobox` by hand); **`combobox`** directly only for free text,
|
|
64
68
|
suggestions or multi-select chips.
|
|
65
|
-
-
|
|
66
|
-
|
|
69
|
+
- **One view-switch rule.** A form value is a **`radio-group`**. An immediate view or scope switch
|
|
70
|
+
over the same content (Mine | Team, All | Unread, Grid | List) is a single-select
|
|
71
|
+
**`toggle-group`** that always keeps one item pressed — ignore the empty value in
|
|
72
|
+
`onValueChange` — with `spacing={0}` for 2–5 options inline. Swapping in-page regions is
|
|
73
|
+
**`tabs`**; moving between URLs is navigation — links, not `tabs` (a route-tabs recipe is
|
|
74
|
+
not shipped yet).
|
|
75
|
+
- **Empty is tiered** — nothing yet, no matches ("Clear filters"), couldn't load (`role="alert"`,
|
|
76
|
+
"Try again"), blocked. Pick the tier from the empty-state foundation
|
|
77
|
+
(<https://design.vegastack.com/docs/foundations/empty-states>); never leave a region blank.
|
|
67
78
|
- **`alert`** for an in-content notice — `variant` is `default · destructive · success · warning ·
|
|
68
79
|
info`, each an ink on the `card` surface with a required icon; **`announcement-banner`** only for
|
|
69
80
|
the full-width inverse strip at the very top of the page.
|
|
70
81
|
- **`chip` is the ONE pill** — `hue` × `size` (`sm` inline · `md` control-scale) × `active`, with
|
|
71
|
-
`onRemove` giving a real 24×24 remove control. `Tag
|
|
72
|
-
|
|
73
|
-
sub-24px `×`. A **`badge`** is the different job: status, never removable, never a selection.
|
|
82
|
+
`onRemove` giving a real 24×24 remove control. `Tag` and `FilterChip` wrap that primitive; `ComboboxChip` is Base UI's own chip and does not share its geometry
|
|
83
|
+
yet. Never hand-roll a pill with its own height, radius, or a sub-24px `×`. A **`badge`** is the different job: status, never removable, never a selection.
|
|
74
84
|
- **`useAnnouncer` is the one live region** — destructure `announce` and `Announcer` from it and
|
|
75
85
|
render ONE `Announcer` element per component, mounted for its life. It keeps the region observed from first paint
|
|
76
86
|
and re-keys it per call, so repeating an identical string still announces. Do not hand-roll a
|
|
77
87
|
`role="status"` node with a `{text, seq}` counter.
|
|
88
|
+
- **Theme choice lives in the user menu** — a `DropdownMenuRadioGroup` of Light, Dark and System
|
|
89
|
+
bound to `theme` and `setTheme` from `useVegaStackTheme()`. There is no `theme-toggle` registry
|
|
90
|
+
item yet (a known gap); do not hand-roll a local toggle button.
|
|
78
91
|
- **`code-block`** for static syntax-highlighted source; **`terminal`** for command sessions.
|
|
79
92
|
- **`navigation-menu`** is top-level site navigation with panels, not a menu inside a page.
|
|
80
93
|
|
|
94
|
+
### Names hide abilities
|
|
95
|
+
|
|
96
|
+
A component's name undersells it. Before composing something by hand, check this list:
|
|
97
|
+
|
|
98
|
+
| Component | What it already does |
|
|
99
|
+
| ------------------------------------------------------ | ----------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
|
|
100
|
+
| `Command` | Renders inline as well as in `CommandDialog`. An item's check mark is `data-checked` — visual only, so it is not a form value. |
|
|
101
|
+
| `Combobox` | `multiple` with `ComboboxChips`; `filter={null}` hands filtering to your server. |
|
|
102
|
+
| `SearchableSelect` | The Select-shaped search picker, with `clearable`. Single-select today. |
|
|
103
|
+
| `Item` | A link tile with `render={<a />}`; `ItemGroup` gives a set of items list semantics. |
|
|
104
|
+
| `DialogContent` | `size`: `sm · default · lg · xl`. Never a width class. |
|
|
105
|
+
| `DataList` | Per-column `mobile` (`merge` · `visible` · `hidden`) and `minWidth`. `DataGrid` adds editing, multi-key sort and a column picker; `Table` is static markup. |
|
|
106
|
+
| `FilterBar` / `FilterBuilder` | `FilterBar` is a flat chip row with search; `FilterBuilder` (the `filter-bar-managed` item) edits a nested and/or tree over your field vocabulary. Both are controlled. |
|
|
107
|
+
| `Stat` | `StatDelta` for change, `StatEmpty` for nothing to report. |
|
|
108
|
+
| `PropertyList` · `DataList` · `SettingsRow` | A record's facts · many records · one setting with its control. |
|
|
109
|
+
| `ActionBar` | The docked bar for bulk selection ("5 selected"), unsaved changes and batch progress. |
|
|
110
|
+
| `TruncatedText` · `IconText` · `TableCellText` | Overflow detection, hover and keyboard reveal, and tap-to-toggle on touch. |
|
|
111
|
+
| `RelativeTime` | `mode="ago"` ("3 minutes ago") or `mode="day"` ("Yesterday"). |
|
|
112
|
+
| `EditableCell` · `AutoSaveInput` · `useInlineEdit` | Click-to-edit in a table · a field that saves as you type, with its status · the hook `EditableCell` is built on. |
|
|
113
|
+
| `AttachmentGroup` · `Dropzone` · `useFileDrop` | A file list with per-file state · a drop target · the drop and paste engine. |
|
|
114
|
+
| `PageHeader` | Title, description, `breadcrumb`, a back link (`backHref`) and `actions`. |
|
|
115
|
+
| `MultiStepForm` · `Stepper` · `Questionnaire` · `Tabs` | A form in steps · progress display (`navigable` on request) · one question at a time · peer regions. |
|
|
116
|
+
| `NativeSelect` | The platform `<select>`, so a touch device opens its own picker. |
|
|
117
|
+
| `Board` | A column's `lockedReason` explains why it cannot take a card. |
|
|
118
|
+
| `AudioPlayer` | `mediaRef` to drive playback, a transcript button and a waveform. |
|
|
119
|
+
| `Tabs` | `TabsList variant="line"` and `Tabs orientation="vertical"`. |
|
|
120
|
+
| `MessageScroller` | `defaultScrollPosition` (`start` · `end` · `last-anchor`), `scrollToMessage` from `useMessageScroller()`, and `useMessageScrollerVisibility()`. |
|
|
121
|
+
|
|
122
|
+
### Which component for X
|
|
123
|
+
|
|
124
|
+
- **A page** → `AppShell` › `AppShellContent` › `PageHeader` › `FilterBar` › `DataList` (or
|
|
125
|
+
`DataGrid`) › the `Empty` tier that fits. The spacing between them is the page-rhythm recipe
|
|
126
|
+
(<https://design.vegastack.com/docs/foundations/spacing#page-rhythm>).
|
|
127
|
+
- **A record's details** → `PropertyList`, in `Card` sections titled with an `h2` in `CardTitle`.
|
|
128
|
+
- **Settings** → `SettingsSection` › `SettingsCard` › `SettingsRow`.
|
|
129
|
+
- **A button that navigates** → `<Link className={buttonVariants()}>` (see Composition patterns).
|
|
130
|
+
- **A status** → `Badge` with a status `variant`; an in-content notice → `Alert`.
|
|
131
|
+
- **A metric** → `Stat`.
|
|
132
|
+
- **A confirmation that interrupts** → `AlertDialog`; a form or detail in an overlay → `Dialog` or
|
|
133
|
+
`Sheet`.
|
|
134
|
+
- **Feedback after an action** → `toast.add({ title })`.
|
|
135
|
+
|
|
81
136
|
## Tokens
|
|
82
137
|
|
|
83
138
|
Semantic CSS custom properties from `@vegastack/design-tokens/theme.css` (OKLCH, `:root` + `.dark`),
|
|
@@ -174,12 +229,14 @@ contract.
|
|
|
174
229
|
inside a portal + positioner. Theme, toast, tooltip, and direction providers all come from
|
|
175
230
|
`<VegaStackProvider>`; your app root needs `isolation: isolate` or portaled popups can render under
|
|
176
231
|
page chrome.
|
|
177
|
-
- **Compound parts
|
|
178
|
-
|
|
179
|
-
|
|
180
|
-
- **
|
|
181
|
-
|
|
182
|
-
`nativeButton={false}
|
|
232
|
+
- **Compound parts are flat exports** — `import { DialogTrigger, DialogContent }`. There is no
|
|
233
|
+
`Dialog.Trigger`: the parts are separate named exports, never sub-properties of the root.
|
|
234
|
+
- **Polymorphism** uses Base UI's `render` prop, never Radix's `asChild`.
|
|
235
|
+
- **A link that looks like a button is a link** — one recipe:
|
|
236
|
+
`<Link href="…" className={buttonVariants({ variant, size })}>`. Never
|
|
237
|
+
`Button render={<Link/>} nativeButton={false}`: Base UI sets `role="button"` on a non-native
|
|
238
|
+
element, so navigation announces as an action. `buttonVariants` comes from a module with no
|
|
239
|
+
`'use client'`, so a Server Component uses it directly.
|
|
183
240
|
|
|
184
241
|
## Do / Don't
|
|
185
242
|
|
|
@@ -192,6 +249,10 @@ contract.
|
|
|
192
249
|
- Implement every applicable state: default, hover, focus, loading, empty, error, success, disabled.
|
|
193
250
|
- Put `truncate` on an inner span, with `min-w-0` on the flex container.
|
|
194
251
|
- Let the parent decide a form control's width — every control is `w-full`.
|
|
252
|
+
- Set numbers — counts, dates, amounts, quantities — in the regular font with `tabular-nums`, and
|
|
253
|
+
right-align a numeric column. `font-mono` is for code and identifiers (`SYS-1042`) only.
|
|
254
|
+
- Title a page with `PageHeader` (`font-heading text-2xl font-semibold`); a section heading is
|
|
255
|
+
`font-heading text-base font-medium`, a group label `text-xs font-medium text-muted-foreground`.
|
|
195
256
|
- Reach for a plain Tailwind utility for size, radius, shadow, z-index, alpha, weight and motion:
|
|
196
257
|
`h-8`, `size-4`, `rounded-xl`, `shadow-md`, `z-50`, `bg-foreground/10`, `opacity-50`,
|
|
197
258
|
`font-semibold`, `transition-colors duration-100 ease-in-out` are all on-system now.
|
|
@@ -219,19 +280,19 @@ contract.
|
|
|
219
280
|
silently renders as body text. `vegastack-design doctor` scans your source and lists every
|
|
220
281
|
occurrence with `file:line`; run it after any upgrade or generated change.
|
|
221
282
|
|
|
222
|
-
| Retired | Write instead
|
|
223
|
-
| ---------------------------------------------------------- |
|
|
224
|
-
| `text-h1` · `text-h2` · `text-h3` · `text-h4` | `
|
|
225
|
-
| `text-label` · `text-label-sm` · `text-strong` | `text-sm font-medium` · `text-xs font-medium` · `text-sm font-semibold`
|
|
226
|
-
| `text-mono-label` · `text-code` · `text-code-sm` | `text-xs font-medium` (a label is sans) · `font-mono text-sm` · `font-mono text-xs`
|
|
227
|
-
| `text-display-{sm,md,lg,xl}` | `text-4xl` · `text-5xl` · `text-6xl` · `text-7xl`
|
|
228
|
-
| `bg-{destructive,success,warning,info}-subtle` | `bg-destructive/10` (the family at `/10`), `-text` ink on it
|
|
229
|
-
| `--alpha-*` · `--opacity-*` | the literal: `bg-foreground/10`, `opacity-50`
|
|
230
|
-
| `--z-*` | `z-10` (raised) · `z-50` (every overlay; DOM order decides)
|
|
231
|
-
| `shadow-overlay` · `backdrop-blur-glass` | `shadow-md` (popover)
|
|
232
|
-
| `icon-button` · `segmented` | `Button size="icon"` + `aria-label` · joined `ToggleGroup`
|
|
233
|
-
| `progress-indicator` · `field-inline` · `floating-surface` | `Progress` / `Spinner` · `EditableCell` · `Popover`
|
|
234
|
-
| `section-header` · `sonner` | your own heading markup · `toast` (`toast.add({ title })`)
|
|
283
|
+
| Retired | Write instead |
|
|
284
|
+
| ---------------------------------------------------------- | ----------------------------------------------------------------------------------------------------------------------- |
|
|
285
|
+
| `text-h1` · `text-h2` · `text-h3` · `text-h4` | `PageHeader` (page) · `font-heading text-base font-medium` (section) · `text-lg font-semibold`; `text-base font-medium` |
|
|
286
|
+
| `text-label` · `text-label-sm` · `text-strong` | `text-sm font-medium` · `text-xs font-medium` · `text-sm font-semibold` |
|
|
287
|
+
| `text-mono-label` · `text-code` · `text-code-sm` | `text-xs font-medium` (a label is sans) · `font-mono text-sm` · `font-mono text-xs` |
|
|
288
|
+
| `text-display-{sm,md,lg,xl}` | `text-4xl` · `text-5xl` · `text-6xl` · `text-7xl` |
|
|
289
|
+
| `bg-{destructive,success,warning,info}-subtle` | `bg-destructive/10` (the family at `/10`), `-text` ink on it |
|
|
290
|
+
| `--alpha-*` · `--opacity-*` | the literal: `bg-foreground/10`, `opacity-50` |
|
|
291
|
+
| `--z-*` | `z-10` (raised) · `z-50` (every overlay; DOM order decides) |
|
|
292
|
+
| `shadow-overlay` · `backdrop-blur-glass` | `shadow-md` (popover, menu) · `shadow-lg` (sheet, submenu, toast) · none on a dialog · delete it |
|
|
293
|
+
| `icon-button` · `segmented` | `Button size="icon"` + `aria-label` · joined `ToggleGroup` |
|
|
294
|
+
| `progress-indicator` · `field-inline` · `floating-surface` | `Progress` / `Spinner` · `EditableCell` · `Popover` |
|
|
295
|
+
| `section-header` · `sonner` | your own heading markup · `toast` (`toast.add({ title })`) |
|
|
235
296
|
|
|
236
297
|
## Reference
|
|
237
298
|
|
|
@@ -3,7 +3,7 @@
|
|
|
3
3
|
<!-- GENERATED — do not hand-edit. Regenerated from the design system's component contract,
|
|
4
4
|
which is the authority for membership and counts. -->
|
|
5
5
|
|
|
6
|
-
**112 components**, plus 467 animated-icon items, 11 hooks (`use-animation-replay`, `use-announcer`, `use-drag-reorder`, `use-file-drop`, `use-inline-edit`, `use-list-nav`, `use-media-query`, `use-mobile`, `use-modal-inert`, `use-overflow`, `use-platform`),
|
|
6
|
+
**112 components**, plus 467 animated-icon items, 11 hooks (`use-animation-replay`, `use-announcer`, `use-drag-reorder`, `use-file-drop`, `use-inline-edit`, `use-list-nav`, `use-media-query`, `use-mobile`, `use-modal-inert`, `use-overflow`, `use-platform`), 4 starter blocks (`app-shell-01`, `board-01`, `login-01`, `settings-01`), 68 chart blocks across 7 families, and 2 data libs (`geo-data`, `drag-item`) — 664 registry items in total.
|
|
7
7
|
|
|
8
8
|
Install any of them with `shadcn add @vegastack/<name>`. Animated icons install as
|
|
9
9
|
`@vegastack/icon-<name>`; the bare name is reserved for components, so a component whose name
|
|
@@ -22,14 +22,14 @@ starts with `icon-` is a component and never an icon.
|
|
|
22
22
|
- **`auto-save-input`** — An input that debounces edits and persists them via an async onSave, with an inline idle/saving/saved/error status.
|
|
23
23
|
- **`calendar`** — A date-field calendar on React DayPicker — single, multiple and range selection.
|
|
24
24
|
- **`checkbox`** — A binary (or indeterminate) toggle on Base UI Checkbox, with a 24px invisible hit area (A11Y-2).
|
|
25
|
-
- **`chip-input`** — Free-token entry field — Enter/comma/paste commits chips, Backspace removes, per-chip validation marks invalid entries instead of dropping them.
|
|
25
|
+
- **`chip-input`** — Free-token entry field — Enter/comma/paste commits chips, Backspace removes, per-chip validation marks invalid entries instead of dropping them. InputGroup field chrome + real Tag chips.
|
|
26
26
|
- **`color-picker`** — A swatch-triggered popover presenting a grid of preset colors — pick one, fire onValueChange, mark the selection.
|
|
27
27
|
- **`combobox`** — A filterable listbox behind a text input — grouped items, an announced empty state and a chips mode.
|
|
28
28
|
- **`country-select`** — A searchable country picker returning the ISO 3166-1 alpha-2 code, with flag + name. A thin wrapper over SearchableSelect fed by the geo-data item.
|
|
29
29
|
- **`date-picker`** — Pick a single date or a date range from a calendar popover — token-styled, keyboard-navigable, with optional quick presets.
|
|
30
30
|
- **`dropzone`** — File acquisition surface — drop, click-to-browse, and paste — as a thin shell over use-file-drop; the surface is the named focusable control over a hidden picker-bridge input; data-dragging/data-drag-invalid styling flags.
|
|
31
31
|
- **`editable-cell`** — Inline-editable value with an async commit lifecycle — optimistic display, saving/saved/error status, revert on a rejected write, and a typed text/select/custom editor registry.
|
|
32
|
-
- **`emoji-picker`** — A popover with a searchable, category-grouped grid of emoji that returns the selected character via
|
|
32
|
+
- **`emoji-picker`** — A popover with a searchable, category-grouped grid of emoji that returns the selected character via onValueChange (curated set, not full Unicode).
|
|
33
33
|
- **`field`** — The form-field scaffold — label, description, error, legend, separator and choice-card layouts.
|
|
34
34
|
- **`input`** — A styled Base UI input for every text-entry type, with the text-entry focus border tint (FOC-3).
|
|
35
35
|
- **`input-group`** — An input or textarea with addons — icons, text, buttons, kbd hints and spinners on one surface.
|
|
@@ -49,7 +49,7 @@ starts with `icon-` is a component and never an icon.
|
|
|
49
49
|
|
|
50
50
|
## Display
|
|
51
51
|
|
|
52
|
-
- **`chip`** — The one labelled pill primitive — 10 decorative hues, two tiers, an optional selection rung, and a real 24x24 remove control. Behind Tag
|
|
52
|
+
- **`chip`** — The one labelled pill primitive — 10 decorative hues, two tiers, an optional selection rung, and a real 24x24 remove control. Behind Tag and FilterChip; ComboboxChip is Base UI's own chip, not this primitive.
|
|
53
53
|
- **`code-block`** — A code panel with a language header and copy affordance — the shared code surface for chat transcripts, docs, and examples.
|
|
54
54
|
- **`stat`** — A labelled value block — muted label over a value, honest faint empty state, optional delta line. Two scales.
|
|
55
55
|
- **`tag-group`** — Hue-tinted label chips on the 10-hue tag palette, with +N overflow collapsing and removable tags.
|
|
@@ -81,7 +81,7 @@ starts with `icon-` is a component and never an icon.
|
|
|
81
81
|
- **`data-list-pager`** — A controlled paging footer for DataList — a tabular-numeral range summary, a rows-per-page Select, and a windowed Pagination that hides on a single page.
|
|
82
82
|
- **`data-table-parts`** — The chrome DataList and DataGrid share — sort header, selection cells, skeleton rows, the empty row, column class rules, and the selection/sort/controlled-state hooks.
|
|
83
83
|
- **`filter-bar`** — A row of removable filter chips, an "Add filter" dropdown, and an optional search input — for list and table filter toolbars.
|
|
84
|
-
- **`filter-bar-managed`** — The
|
|
84
|
+
- **`filter-bar-managed`** — The controlled nested and/or filter builder — host-injected field grammar (vocabulary + per-type value editors), depth and condition caps, focus-managed removal, and a removable FilterChip summary.
|
|
85
85
|
- **`property-list`** — Record-facts rows: an icon+label column beside a value column, as an accessible definition list.
|
|
86
86
|
- **`sortable-list`** — Reorderable rows on ItemGroup/Item via use-drag-reorder — pointer drag with drop indicators, keyboard move mode, a lossless Move menu, and server-refusable moves. Controlled; the host owns the order.
|
|
87
87
|
|
|
@@ -155,7 +155,7 @@ starts with `icon-` is a component and never an icon.
|
|
|
155
155
|
- **`bubble`** — A chat speech bubble - 7 token-driven variants (incl. brand-tinted), start/end alignment, interactive content, and a floating reactions chip.
|
|
156
156
|
- **`marker`** — An inline conversation marker - status lines, system notes, and labelled dividers. 3 variants, Base UI render-polymorphic.
|
|
157
157
|
- **`message`** — Layout primitives for a conversation row - avatar anchoring, content column, header/footer slots, start/end alignment. Server-safe.
|
|
158
|
-
- **`message-scroller`** —
|
|
158
|
+
- **`message-scroller`** — An auto-scrolling conversation viewport (not virtualised) - pins to the latest message, preserves position on prepend, tracks the anchor, and a floating scroll-to-end button.
|
|
159
159
|
- **`questionnaire`** — A guided one-question-at-a-time form — choices, freeform answers, skip, shortcuts, validation, resume and conditional items, built on the @shadcn/react questionnaire state machine.
|
|
160
160
|
|
|
161
161
|
## Marketing
|