@nadicodeai/ui 12.1.111 → 12.1.112
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 +11 -9
- package/README.md +3 -2
- package/dist/components/account-menu.d.ts +1 -1
- package/dist/components/account-menu.js +1 -1
- package/dist/components/action-menu.d.ts +2 -2
- package/dist/components/action-menu.js +2 -2
- package/dist/components/activity-feed.d.ts +1 -1
- package/dist/components/activity-feed.js +1 -1
- package/dist/components/agent-card.d.ts +5 -3
- package/dist/components/agent-card.d.ts.map +1 -1
- package/dist/components/agent-card.js +5 -3
- package/dist/components/agent-list-row.d.ts +2 -2
- package/dist/components/agent-list-row.js +2 -2
- package/dist/components/agent-orb.d.ts +31 -7
- package/dist/components/agent-orb.d.ts.map +1 -1
- package/dist/components/agent-orb.js +29 -5
- package/dist/components/agent-profile.d.ts +6 -2
- package/dist/components/agent-profile.d.ts.map +1 -1
- package/dist/components/agent-profile.js +6 -2
- package/dist/components/aspect-ratio.d.ts +7 -3
- package/dist/components/aspect-ratio.d.ts.map +1 -1
- package/dist/components/aspect-ratio.js +7 -3
- package/dist/components/avatar.d.ts +11 -5
- package/dist/components/avatar.d.ts.map +1 -1
- package/dist/components/avatar.js +11 -5
- package/dist/components/breadcrumb.d.ts +1 -1
- package/dist/components/breadcrumb.js +1 -1
- package/dist/components/button.d.ts +23 -10
- package/dist/components/button.d.ts.map +1 -1
- package/dist/components/button.js +23 -10
- package/dist/components/card-row.d.ts +4 -2
- package/dist/components/card-row.d.ts.map +1 -1
- package/dist/components/card-row.js +4 -2
- package/dist/components/card.d.ts +1 -1
- package/dist/components/card.js +1 -1
- package/dist/components/carousel.d.ts +9 -4
- package/dist/components/carousel.d.ts.map +1 -1
- package/dist/components/carousel.js +9 -4
- package/dist/components/catalog-drawer.d.ts +1 -1
- package/dist/components/catalog-drawer.js +1 -1
- package/dist/components/chart-card.d.ts +1 -1
- package/dist/components/chart-card.js +1 -1
- package/dist/components/checkbox.d.ts +2 -1
- package/dist/components/checkbox.d.ts.map +1 -1
- package/dist/components/checkbox.js +2 -1
- package/dist/components/choicebox.d.ts +9 -5
- package/dist/components/choicebox.d.ts.map +1 -1
- package/dist/components/choicebox.js +9 -5
- package/dist/components/clearable-input.d.ts +2 -1
- package/dist/components/clearable-input.d.ts.map +1 -1
- package/dist/components/clearable-input.js +2 -1
- package/dist/components/code-block.d.ts +13 -10
- package/dist/components/code-block.d.ts.map +1 -1
- package/dist/components/code-block.js +13 -10
- package/dist/components/collection-filters.d.ts +1 -1
- package/dist/components/collection-filters.js +1 -1
- package/dist/components/collection-search.d.ts +11 -7
- package/dist/components/collection-search.d.ts.map +1 -1
- package/dist/components/collection-search.js +11 -7
- package/dist/components/combobox.d.ts +4 -1
- package/dist/components/combobox.d.ts.map +1 -1
- package/dist/components/combobox.js +4 -1
- package/dist/components/command.d.ts +1 -1
- package/dist/components/command.js +1 -1
- package/dist/components/company-card.d.ts +28 -5
- package/dist/components/company-card.d.ts.map +1 -1
- package/dist/components/company-card.js +28 -5
- package/dist/components/confirm-dialog.d.ts +3 -2
- package/dist/components/confirm-dialog.d.ts.map +1 -1
- package/dist/components/confirm-dialog.js +2 -2
- package/dist/components/copy-button.d.ts +2 -2
- package/dist/components/copy-button.js +2 -2
- package/dist/components/data-table.d.ts +2 -2
- package/dist/components/data-table.js +2 -2
- package/dist/components/drawer.d.ts +4 -4
- package/dist/components/drawer.d.ts.map +1 -1
- package/dist/components/drawer.js +3 -3
- package/dist/components/dropdown-menu.d.ts +2 -2
- package/dist/components/dropdown-menu.js +2 -2
- package/dist/components/empty-state.d.ts +2 -2
- package/dist/components/empty-state.js +2 -2
- package/dist/components/field.d.ts +4 -0
- package/dist/components/field.d.ts.map +1 -1
- package/dist/components/field.js +4 -0
- package/dist/components/file-diff.d.ts +5 -2
- package/dist/components/file-diff.d.ts.map +1 -1
- package/dist/components/file-diff.js +5 -2
- package/dist/components/form-dialog.d.ts +1 -1
- package/dist/components/form-dialog.js +1 -1
- package/dist/components/form-drawer.d.ts +1 -1
- package/dist/components/form-drawer.js +1 -1
- package/dist/components/gauge.d.ts +9 -7
- package/dist/components/gauge.d.ts.map +1 -1
- package/dist/components/gauge.js +9 -7
- package/dist/components/hover-card.d.ts +5 -2
- package/dist/components/hover-card.d.ts.map +1 -1
- package/dist/components/hover-card.js +5 -2
- package/dist/components/identity-mark.d.ts +3 -3
- package/dist/components/identity-mark.js +3 -3
- package/dist/components/input-group.d.ts +1 -0
- package/dist/components/input-group.d.ts.map +1 -1
- package/dist/components/input-group.js +1 -0
- package/dist/components/input-otp.d.ts +5 -3
- package/dist/components/input-otp.d.ts.map +1 -1
- package/dist/components/input-otp.js +5 -3
- package/dist/components/input.d.ts +4 -2
- package/dist/components/input.d.ts.map +1 -1
- package/dist/components/input.js +4 -2
- package/dist/components/item.d.ts +1 -1
- package/dist/components/item.js +1 -1
- package/dist/components/kbd.d.ts +4 -2
- package/dist/components/kbd.d.ts.map +1 -1
- package/dist/components/kbd.js +4 -2
- package/dist/components/label.d.ts +8 -3
- package/dist/components/label.d.ts.map +1 -1
- package/dist/components/label.js +8 -3
- package/dist/components/load-more-button.d.ts +3 -2
- package/dist/components/load-more-button.d.ts.map +1 -1
- package/dist/components/load-more-button.js +3 -2
- package/dist/components/message-notice.d.ts +1 -1
- package/dist/components/message-notice.js +1 -1
- package/dist/components/multi-select.d.ts +6 -4
- package/dist/components/multi-select.d.ts.map +1 -1
- package/dist/components/multi-select.js +6 -4
- package/dist/components/notice-banner.d.ts +2 -2
- package/dist/components/notice-banner.js +2 -2
- package/dist/components/object-workspace.d.ts +3 -3
- package/dist/components/object-workspace.d.ts.map +1 -1
- package/dist/components/object-workspace.js +2 -2
- package/dist/components/pairing-code.d.ts +2 -2
- package/dist/components/pairing-code.js +2 -2
- package/dist/components/picture-label.d.ts +3 -2
- package/dist/components/picture-label.d.ts.map +1 -1
- package/dist/components/picture-label.js +3 -2
- package/dist/components/popover.d.ts +7 -3
- package/dist/components/popover.d.ts.map +1 -1
- package/dist/components/popover.js +7 -3
- package/dist/components/progress-checklist.d.ts +1 -1
- package/dist/components/progress-checklist.js +1 -1
- package/dist/components/progress.d.ts +4 -2
- package/dist/components/progress.d.ts.map +1 -1
- package/dist/components/progress.js +4 -2
- package/dist/components/qr-code.d.ts +5 -2
- package/dist/components/qr-code.d.ts.map +1 -1
- package/dist/components/qr-code.js +5 -2
- package/dist/components/radio-group.d.ts +8 -5
- package/dist/components/radio-group.d.ts.map +1 -1
- package/dist/components/radio-group.js +8 -5
- package/dist/components/record-identity.d.ts +1 -1
- package/dist/components/record-identity.js +1 -1
- package/dist/components/record-list.d.ts +2 -2
- package/dist/components/record-list.js +2 -2
- package/dist/components/record-sheet.d.ts +2 -2
- package/dist/components/record-sheet.js +2 -2
- package/dist/components/record-time.d.ts +1 -1
- package/dist/components/record-time.js +1 -1
- package/dist/components/resizable.d.ts +2 -2
- package/dist/components/resizable.js +2 -2
- package/dist/components/row-edit-form.d.ts +1 -1
- package/dist/components/row-edit-form.js +1 -1
- package/dist/components/run-timeline.d.ts +2 -2
- package/dist/components/run-timeline.js +2 -2
- package/dist/components/scroll-area.d.ts +5 -3
- package/dist/components/scroll-area.d.ts.map +1 -1
- package/dist/components/scroll-area.js +5 -3
- package/dist/components/segmented-control.d.ts +1 -1
- package/dist/components/segmented-control.js +1 -1
- package/dist/components/select.d.ts +5 -3
- package/dist/components/select.d.ts.map +1 -1
- package/dist/components/select.js +5 -3
- package/dist/components/separator.d.ts +4 -2
- package/dist/components/separator.d.ts.map +1 -1
- package/dist/components/separator.js +4 -2
- package/dist/components/settings-facts.d.ts +3 -2
- package/dist/components/settings-facts.d.ts.map +1 -1
- package/dist/components/settings-facts.js +3 -2
- package/dist/components/settings-section.d.ts +1 -1
- package/dist/components/settings-section.js +1 -1
- package/dist/components/sheet.d.ts +6 -3
- package/dist/components/sheet.d.ts.map +1 -1
- package/dist/components/sheet.js +6 -3
- package/dist/components/skeleton.d.ts +1 -1
- package/dist/components/skeleton.js +1 -1
- package/dist/components/slider.d.ts +2 -1
- package/dist/components/slider.d.ts.map +1 -1
- package/dist/components/slider.js +2 -1
- package/dist/components/snippet.d.ts +3 -1
- package/dist/components/snippet.d.ts.map +1 -1
- package/dist/components/snippet.js +3 -1
- package/dist/components/sonner.d.ts +2 -2
- package/dist/components/sonner.js +2 -2
- package/dist/components/status-badge.d.ts +5 -2
- package/dist/components/status-badge.d.ts.map +1 -1
- package/dist/components/status-badge.js +5 -2
- package/dist/components/status-dot.d.ts +2 -1
- package/dist/components/status-dot.d.ts.map +1 -1
- package/dist/components/status-dot.js +2 -1
- package/dist/components/switch.d.ts +7 -6
- package/dist/components/switch.d.ts.map +1 -1
- package/dist/components/switch.js +7 -6
- package/dist/components/table.d.ts +18 -11
- package/dist/components/table.d.ts.map +1 -1
- package/dist/components/table.js +18 -11
- package/dist/components/tabs.d.ts +19 -13
- package/dist/components/tabs.d.ts.map +1 -1
- package/dist/components/tabs.js +19 -13
- package/dist/components/text-link.d.ts +9 -4
- package/dist/components/text-link.d.ts.map +1 -1
- package/dist/components/text-link.js +9 -4
- package/dist/components/text-with-copy-button.d.ts +2 -2
- package/dist/components/text-with-copy-button.js +2 -2
- package/dist/components/textarea.d.ts +4 -3
- package/dist/components/textarea.d.ts.map +1 -1
- package/dist/components/textarea.js +4 -3
- package/dist/components/tooltip.d.ts +5 -3
- package/dist/components/tooltip.d.ts.map +1 -1
- package/dist/components/tooltip.js +5 -3
- package/dist/components/usage-meter.d.ts +2 -2
- package/dist/components/usage-meter.js +2 -2
- package/dist/components/waiting-line.d.ts +1 -1
- package/dist/components/waiting-line.js +1 -1
- package/dist/showcase/usage.generated.d.ts.map +1 -1
- package/dist/showcase/usage.generated.js +147 -147
- package/package.json +2 -2
|
@@ -22,7 +22,7 @@ const ACTIONS_ON_TITLE_ROW_WHEN_NARROW = "@max-md/settings-section:[&>[data-slot
|
|
|
22
22
|
* @family Compositions
|
|
23
23
|
* @when One setting a person changes on a SettingsPage or as a section of an ObjectPage: Personal details, Company identity, Notifications. A typed value takes `save`; a switch or a short reversible choice applies at once through its own control's change, with no Save. Also a plan-gated feature, a delete card, one read-only value (an ID in a read-only mono InputGroup with its copy button, no Save), and a paid quantity (its stepper field, the price as the description, a two-fact summary under it).
|
|
24
24
|
* @instead Read-only facts of an object are a SettingsFactsSection; a table or a list of records is a TableCard; Theme and Language live in the account menu; a record's edit in a list is a RowEditForm.
|
|
25
|
-
* @behaviour "Groups related form controls inside a bordered card with optional footer actions." (https://vercel.com/geist/fieldset) Ours: one setting per card: a single SettingsField, the description its only help. One more shape exists, declared by a part and never by classes at the call site. A card of several settings holds SettingsRows, label left and control right, only when every row is a switch or every row is a select. "Use Toggle for a single boolean setting where ON takes effect immediately, like `Password Protection` or `Auto-Cancel Builds`." (https://vercel.com/geist/toggle) "Pair with a form footer only when the setting needs an explicit `Save` step." (https://vercel.com/geist/toggle) "Disable Toggle only when the action is impossible (missing plan, locked policy); pair with helper text or a `Tooltip` that names the resolver." (https://vercel.com/geist/toggle) Ours: that switch is `headerSwitch`: at the title's right, named by the title, the footer holding only its line, no Save; a switch blocked from above is shown off and disabled, the footer saying why and never a tooltip. Required: the title and the description. The header's actions stand at the title's right; on a card narrower than 28 rem they keep the title's row and the description runs under both, as Vercel's cards read on a phone. The footer's left line (`footerHint`, `save.hint`) is optional and specific to the card, never a generic line repeated on every card: a limit, what a value is for, a plan it needs, a link; absent, it is nothing, and a card with neither a line nor a button has no footer. Ours: `save`: a typed value, one card with Save. Save stays disabled until a field differs from what is saved and says `pendingLabel` while saving with Cancel beside it; a completed save calls `saved`, and the product raises one toast from its catalogue ("Completion toasts follow `{Noun} {past-participle}`: `Blob deleted`, `Domain added`, `Environment variable saved`. Never include `successfully`; the action name implies it." https://vercel.com/geist/toast), and Save returns to disabled. Ours: the section never raises a toast itself. A failed save keeps every value and shows under its field, or above the footer when no field owns it. `tone` marks a state with a command (a failed payment, a trial ending): a 1px border and a footer tinted in the hue with its line in it; title, line, fields and buttons stay neutral, an outline secondary then a default primary. A button takes the hue of its command, not of the card: `destructive` for a permanent loss, `warning` for a disruptive command that can be undone. A delete card is `tone="error"` with the object's summary as its body; an archive card is neutral with a `warning` button in the footer. "Use a Note for inline contextual feedback next to the field, card, or section it describes: a region change warning above a region picker, a rate-limit notice next to a usage gauge." (https://vercel.com/geist/note) "One Note per concept." (https://vercel.com/geist/note) Ours: a message about the fields inside is a MessageNotice in the body, the card staying neutral. "Disabled checkboxes still need a Tooltip naming the reason; a greyed box with no explanation reads as a bug." (https://vercel.com/geist/checkbox) Ours: `lockedReason` is the reason,
|
|
25
|
+
* @behaviour "Groups related form controls inside a bordered card with optional footer actions." (https://vercel.com/geist/fieldset) Ours: one setting per card: a single SettingsField, the description its only help. A typed value (a name, a URL, a server, a port, a key) gets its own card. A semantic subgroup of related controls inside a field, such as radios or checkboxes, is a `FieldSet` with a `FieldLegend`. One more shape exists, declared by a part and never by classes at the call site. A card of several settings holds SettingsRows, label left and control right, only when every row is a switch or every row is a select. "Use Toggle for a single boolean setting where ON takes effect immediately, like `Password Protection` or `Auto-Cancel Builds`." (https://vercel.com/geist/toggle) "Pair with a form footer only when the setting needs an explicit `Save` step." (https://vercel.com/geist/toggle) "Disable Toggle only when the action is impossible (missing plan, locked policy); pair with helper text or a `Tooltip` that names the resolver." (https://vercel.com/geist/toggle) Ours: that switch is `headerSwitch`: at the title's right, named by the title, the footer holding only its line, no Save; a switch blocked from above is shown off and disabled, the footer saying why and never a tooltip. Required: the title and the description. The header's actions stand at the title's right; on a card narrower than 28 rem they keep the title's row and the description runs under both, as Vercel's cards read on a phone. The footer's left line (`footerHint`, `save.hint`) is optional and specific to the card, never a generic line repeated on every card: a limit, what a value is for, a plan it needs, a link; absent, it is nothing, and a card with neither a line nor a button has no footer. Ours: `save`: a typed value, one card with its own Save in the footer, always visible. The section owns the changed state: Save stays disabled until a field differs from what is saved and says `pendingLabel` while saving with Cancel beside it; a completed save calls `saved`, and the product raises one toast from its catalogue ("Completion toasts follow `{Noun} {past-participle}`: `Blob deleted`, `Domain added`, `Environment variable saved`. Never include `successfully`; the action name implies it." https://vercel.com/geist/toast), and Save returns to disabled, with no saved state in the footer. Ours: the section never raises a toast itself. A failed save keeps every value and shows under its field, or above the footer when no field owns it. `tone` marks a state with a command (a failed payment, a trial ending): a 1px border and a footer tinted in the hue with its line in it, the line saying the condition in words; title, line, fields and buttons stay neutral, an outline secondary then a default primary. A button takes the hue of its command, not of the card: `destructive` (red) for a permanent loss (Delete), `warning` (amber) for a disruptive command that can be undone (Pause, Archive). A delete card is `tone="error"` with the object's summary as its body; an archive card is neutral with a `warning` button in the footer. "Use a Note for inline contextual feedback next to the field, card, or section it describes: a region change warning above a region picker, a rate-limit notice next to a usage gauge." (https://vercel.com/geist/note) "One Note per concept." (https://vercel.com/geist/note) Ours: a message about the fields inside is a MessageNotice in the body, the card staying neutral. "Disabled checkboxes still need a Tooltip naming the reason; a greyed box with no explanation reads as a bug." (https://vercel.com/geist/checkbox) Ours: `lockedReason` (Geist's disabled wall) is the reason, written as the footer's line, not in a tooltip; it keeps the fields in view, inert with muted text, under a not-allowed cursor, the title and line unchanged; `unlock` is the way to get access, left out when nothing the person does unlocks it. A locked section has no `save` and no header `actions`.
|
|
26
26
|
* @words "Helper text is sentence case, one sentence with a trailing period, on a sibling element wired through `aria-describedby`." (https://vercel.com/geist/input) Ours: the description is that helper text for the whole card, and no field has its own. "Render an optional one-sentence description as a sibling under the label that explains ON only. Don’t describe OFF; it’s the negation." (https://vercel.com/geist/toggle) Ours: a header-switch card's description says what turning it on does. The title names the values ("Personal details"); the description says what changing them does, in one line; the footer line is a Learn more link, a limit ("Use 32 characters at most."), what stays unaffected, or what is blocked and why ("Ask an owner to change this."); Save and Saving come from the product's catalogue, and so does the toast a `saved` callback raises; a delete card's description opens "Permanently delete".
|
|
27
27
|
* @access "Provide an accessible name through `children`, `aria-label`, or `aria-labelledby`." (https://vercel.com/geist/toggle) Ours: the title is the section's h2 and names the form that saves it, and the header switch. The footer's line is one status, announced politely; a failure under a field marks the control invalid and describes it. Locked fields are inert, so the section's title, description and reason are what a screen reader meets.
|
|
28
28
|
*/
|
|
@@ -20,14 +20,17 @@ type SheetProps = Omit<SheetPrimitive.Root.Props, "modal" | "disablePointerDismi
|
|
|
20
20
|
* Ours: also the product's navigation when the window is too narrow for the sidebar.
|
|
21
21
|
* @instead "For a blocking decision, use `Modal`. For a mobile-only bottom sheet, use `Drawer`." (https://vercel.com/geist/sheet)
|
|
22
22
|
* "Don’t use Sheet to confirm destructive actions. The default `modal=false` keeps the page interactive, which weakens severity for a delete or revoke." (https://vercel.com/geist/sheet)
|
|
23
|
-
* Ours: a blocking decision is `ConfirmDialog` or `Dialog`. A catalogue
|
|
24
|
-
*
|
|
23
|
+
* Ours: a blocking decision is `ConfirmDialog` or `Dialog`. A catalogue is `CatalogDrawer` and
|
|
24
|
+
* a setup in steps is `FormDrawer` with `job="steps"`, the modal sheets built on this; one record
|
|
25
|
+
* looked at from a list is `RecordSheet`, which leaves the page usable. A sheet is never chosen
|
|
26
|
+
* because an action takes input. For editing use the row or the record's page.
|
|
25
27
|
* @behaviour "Sheet defaults to `modal=false` so toasts and other high-z elements stay reachable. Keep that default unless the sheet owns the screen." (https://vercel.com/geist/sheet)
|
|
26
28
|
* "Pick `side` from the trigger location: a row inspector slides from `right`, a global filter from `left`. Don’t change sides mid-session." (https://vercel.com/geist/sheet)
|
|
27
29
|
* "Outside-click does not auto-close, so always render an explicit close affordance and honor Escape." (https://vercel.com/geist/sheet)
|
|
28
30
|
* Ours: `modal` dims the page and blocks it, for a sheet that owns the screen, and `noOverlay` on
|
|
29
31
|
* its content drops the scrim again. An inset card with 16 px corners, 12 px from the window's
|
|
30
|
-
* edges; a side panel
|
|
32
|
+
* edges; a side panel owns its width, 512 px from 1024 px and the window less its margins
|
|
33
|
+
* below it, and only `RecordSheet` narrows it to 420 px between 640 and 1024 px. A given kind of sheet always opens on the
|
|
31
34
|
* same side. A press outside never closes it, Escape does, except the phone navigation, which
|
|
32
35
|
* `closesOnScrimPress` closes on a press on its scrim. The body scrolls between a header and a
|
|
33
36
|
* footer with its actions at the trailing edge, as Vercel's drawers (Production Checklist): the
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"sheet.d.ts","sourceRoot":"","sources":["../../src/components/sheet.tsx"],"names":[],"mappings":"AAEA,OAAO,KAAK,KAAK,MAAM,OAAO,CAAC;AAC/B,OAAO,EAAE,MAAM,IAAI,cAAc,EAAE,MAAM,uBAAuB,CAAC;AAUjE,KAAK,UAAU,GAAG,IAAI,CAAC,cAAc,CAAC,IAAI,CAAC,KAAK,EAAE,OAAO,GAAG,yBAAyB,CAAC,GAAG;IACvF;;;OAGG;IACH,KAAK,CAAC,EAAE,OAAO,CAAC;IAChB;;;OAGG;IACH,kBAAkB,CAAC,EAAE,OAAO,CAAC;CAC9B,CAAC;AAEF
|
|
1
|
+
{"version":3,"file":"sheet.d.ts","sourceRoot":"","sources":["../../src/components/sheet.tsx"],"names":[],"mappings":"AAEA,OAAO,KAAK,KAAK,MAAM,OAAO,CAAC;AAC/B,OAAO,EAAE,MAAM,IAAI,cAAc,EAAE,MAAM,uBAAuB,CAAC;AAUjE,KAAK,UAAU,GAAG,IAAI,CAAC,cAAc,CAAC,IAAI,CAAC,KAAK,EAAE,OAAO,GAAG,yBAAyB,CAAC,GAAG;IACvF;;;OAGG;IACH,KAAK,CAAC,EAAE,OAAO,CAAC;IAChB;;;OAGG;IACH,kBAAkB,CAAC,EAAE,OAAO,CAAC;CAC9B,CAAC;AAEF;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GAmCG;AACH,iBAAS,KAAK,CAAC,EAAE,KAAa,EAAE,kBAA0B,EAAE,GAAG,KAAK,EAAE,EAAE,UAAU,qBAWjF;AAED,iBAAS,YAAY,CAAC,EAAE,GAAG,KAAK,EAAE,EAAE,cAAc,CAAC,OAAO,CAAC,KAAK,qBAE/D;AAED,iBAAS,UAAU,CAAC,EAAE,GAAG,KAAK,EAAE,EAAE,cAAc,CAAC,KAAK,CAAC,KAAK,qBAE3D;AAqBD,KAAK,iBAAiB,GAAG,cAAc,CAAC,KAAK,CAAC,KAAK,GAAG;IACpD,IAAI,CAAC,EAAE,KAAK,GAAG,OAAO,GAAG,QAAQ,GAAG,MAAM,CAAC;IAC3C,mDAAmD;IACnD,SAAS,CAAC,EAAE,OAAO,CAAC;IACpB,yEAAyE;IACzE,UAAU,EAAE,MAAM,CAAC;CACpB,CAAC;AAEF,iBAAS,YAAY,CAAC,EACpB,SAAS,EACT,QAAQ,EACR,IAAc,EACd,SAAiB,EACjB,UAAU,EACV,UAAqC,EACrC,GAAG,KAAK,EACT,EAAE,iBAAiB,qBAiCnB;AAED,iBAAS,WAAW,CAAC,EAAE,SAAS,EAAE,GAAG,KAAK,EAAE,EAAE,KAAK,CAAC,cAAc,CAAC,KAAK,CAAC,qBAQxE;AAED,iBAAS,WAAW,CAAC,EAAE,SAAS,EAAE,GAAG,KAAK,EAAE,EAAE,KAAK,CAAC,cAAc,CAAC,KAAK,CAAC,qBAWxE;AAED,iBAAS,UAAU,CAAC,EAAE,SAAS,EAAE,GAAG,KAAK,EAAE,EAAE,cAAc,CAAC,KAAK,CAAC,KAAK,qBAQtE;AAED,iBAAS,gBAAgB,CAAC,EAAE,SAAS,EAAE,GAAG,KAAK,EAAE,EAAE,cAAc,CAAC,WAAW,CAAC,KAAK,qBAQlF;AAED,OAAO,EACL,KAAK,EACL,YAAY,EACZ,UAAU,EACV,YAAY,EACZ,WAAW,EACX,WAAW,EACX,UAAU,EACV,gBAAgB,GACjB,CAAC"}
|
package/dist/components/sheet.js
CHANGED
|
@@ -16,14 +16,17 @@ const SheetModalContext = React.createContext(false);
|
|
|
16
16
|
* Ours: also the product's navigation when the window is too narrow for the sidebar.
|
|
17
17
|
* @instead "For a blocking decision, use `Modal`. For a mobile-only bottom sheet, use `Drawer`." (https://vercel.com/geist/sheet)
|
|
18
18
|
* "Don’t use Sheet to confirm destructive actions. The default `modal=false` keeps the page interactive, which weakens severity for a delete or revoke." (https://vercel.com/geist/sheet)
|
|
19
|
-
* Ours: a blocking decision is `ConfirmDialog` or `Dialog`. A catalogue
|
|
20
|
-
*
|
|
19
|
+
* Ours: a blocking decision is `ConfirmDialog` or `Dialog`. A catalogue is `CatalogDrawer` and
|
|
20
|
+
* a setup in steps is `FormDrawer` with `job="steps"`, the modal sheets built on this; one record
|
|
21
|
+
* looked at from a list is `RecordSheet`, which leaves the page usable. A sheet is never chosen
|
|
22
|
+
* because an action takes input. For editing use the row or the record's page.
|
|
21
23
|
* @behaviour "Sheet defaults to `modal=false` so toasts and other high-z elements stay reachable. Keep that default unless the sheet owns the screen." (https://vercel.com/geist/sheet)
|
|
22
24
|
* "Pick `side` from the trigger location: a row inspector slides from `right`, a global filter from `left`. Don’t change sides mid-session." (https://vercel.com/geist/sheet)
|
|
23
25
|
* "Outside-click does not auto-close, so always render an explicit close affordance and honor Escape." (https://vercel.com/geist/sheet)
|
|
24
26
|
* Ours: `modal` dims the page and blocks it, for a sheet that owns the screen, and `noOverlay` on
|
|
25
27
|
* its content drops the scrim again. An inset card with 16 px corners, 12 px from the window's
|
|
26
|
-
* edges; a side panel
|
|
28
|
+
* edges; a side panel owns its width, 512 px from 1024 px and the window less its margins
|
|
29
|
+
* below it, and only `RecordSheet` narrows it to 420 px between 640 and 1024 px. A given kind of sheet always opens on the
|
|
27
30
|
* same side. A press outside never closes it, Escape does, except the phone navigation, which
|
|
28
31
|
* `closesOnScrimPress` closes on a press on its scrim. The body scrolls between a header and a
|
|
29
32
|
* footer with its actions at the trailing edge, as Vercel's drawers (Production Checklist): the
|
|
@@ -37,7 +37,7 @@ type SkeletonProps = Omit<React.ComponentProps<"div">, "children"> & SkeletonSiz
|
|
|
37
37
|
* @instead "For a single in-flight action, use `Spinner`; for an indeterminate inline wait, use `LoadingDots`; for known progress, use `Progress`." "Don’t use Skeleton as permanent decoration or as a placeholder for empty states." "When there’s no data to load, render an `EmptyState`." (https://vercel.com/geist/skeleton)
|
|
38
38
|
* Ours: there is no spinner and no loading dots: a wait on something the person pressed is `PendingLabel` and `WaitingLine`. An unknown layout shows nothing until the data arrives.
|
|
39
39
|
* @behaviour "Set `width` and `height` to match the final content so the layout doesn’t shift when data resolves." "A 200×20 block becoming an 80×16 string reads as a glitch." "Pick `pill`, `rounded`, or `squared` to mirror the eventual element’s shape (avatars `pill`, buttons and chips `rounded`, image tiles `squared`)." "When the skeleton wraps children, keep dimensions stable so the reveal swap doesn’t reflow surrounding content." "If you do not pass a fixed size, it will be calculated automatically." "The skeleton will hide when children are not null, but the size is retained." (https://vercel.com/geist/skeleton)
|
|
40
|
-
* Ours: `pill` is `circle` and `rounded` is `rectangle`. A skeleton with neither a size nor a child does not compile: `height` with `width`, or `className` for a size a token sets (`h-4 w-full`; the type cannot check that it holds one), or `boxHeight` with `height` for a text line, where the bar sits at the top of the box and the rest is space below it. Given a size, pass the content as children, `null` until it arrives: the bar shows, then the content replaces it in the same box. Without a size, wrap the real control and `show` covers it, `show={false}` reveals it, rather than drawing a twin of it. Still: it never pulses or shimmers. It resolves to data, an absence or a failure.
|
|
40
|
+
* Ours: `pill` is `circle` and `rounded` is `rectangle`. A skeleton with neither a size nor a child does not compile: `height` with `width`, or `className` for a size a token sets (`h-4 w-full`; the type cannot check that it holds one), or `boxHeight` with `height` for a text line, where the bar sits at the top of the box and the rest is space below it. Given a size, pass the content as children, `null` until it arrives: the bar shows, then the content replaces it in the same box. Without a size, wrap the real control and `show` covers it, `show={false}` reveals it, rather than drawing a twin of it. Still: it never pulses or shimmers, and Geist's `animated` option is not taken. It resolves to data, an absence or a failure.
|
|
41
41
|
* @words Ours: none. No "Loading" text beside it.
|
|
42
42
|
* @access "Skeletons are decorative; avoid placing focusable controls inside them while loading." "Disable the shimmer with the `no animation` variant on low-power surfaces and respect `prefers-reduced-motion`." (https://vercel.com/geist/skeleton)
|
|
43
43
|
* Ours: hidden from assistive technology and never focusable; an unsized wrapper covers its children inert and is `aria-busy` while it covers them. There is no shimmer to disable, so the placeholder is the same under `prefers-reduced-motion`. A group of bare placeholders needs a `SkeletonRegion`.
|
|
@@ -17,7 +17,7 @@ function hasNoContent(children) {
|
|
|
17
17
|
* @instead "For a single in-flight action, use `Spinner`; for an indeterminate inline wait, use `LoadingDots`; for known progress, use `Progress`." "Don’t use Skeleton as permanent decoration or as a placeholder for empty states." "When there’s no data to load, render an `EmptyState`." (https://vercel.com/geist/skeleton)
|
|
18
18
|
* Ours: there is no spinner and no loading dots: a wait on something the person pressed is `PendingLabel` and `WaitingLine`. An unknown layout shows nothing until the data arrives.
|
|
19
19
|
* @behaviour "Set `width` and `height` to match the final content so the layout doesn’t shift when data resolves." "A 200×20 block becoming an 80×16 string reads as a glitch." "Pick `pill`, `rounded`, or `squared` to mirror the eventual element’s shape (avatars `pill`, buttons and chips `rounded`, image tiles `squared`)." "When the skeleton wraps children, keep dimensions stable so the reveal swap doesn’t reflow surrounding content." "If you do not pass a fixed size, it will be calculated automatically." "The skeleton will hide when children are not null, but the size is retained." (https://vercel.com/geist/skeleton)
|
|
20
|
-
* Ours: `pill` is `circle` and `rounded` is `rectangle`. A skeleton with neither a size nor a child does not compile: `height` with `width`, or `className` for a size a token sets (`h-4 w-full`; the type cannot check that it holds one), or `boxHeight` with `height` for a text line, where the bar sits at the top of the box and the rest is space below it. Given a size, pass the content as children, `null` until it arrives: the bar shows, then the content replaces it in the same box. Without a size, wrap the real control and `show` covers it, `show={false}` reveals it, rather than drawing a twin of it. Still: it never pulses or shimmers. It resolves to data, an absence or a failure.
|
|
20
|
+
* Ours: `pill` is `circle` and `rounded` is `rectangle`. A skeleton with neither a size nor a child does not compile: `height` with `width`, or `className` for a size a token sets (`h-4 w-full`; the type cannot check that it holds one), or `boxHeight` with `height` for a text line, where the bar sits at the top of the box and the rest is space below it. Given a size, pass the content as children, `null` until it arrives: the bar shows, then the content replaces it in the same box. Without a size, wrap the real control and `show` covers it, `show={false}` reveals it, rather than drawing a twin of it. Still: it never pulses or shimmers, and Geist's `animated` option is not taken. It resolves to data, an absence or a failure.
|
|
21
21
|
* @words Ours: none. No "Loading" text beside it.
|
|
22
22
|
* @access "Skeletons are decorative; avoid placing focusable controls inside them while loading." "Disable the shimmer with the `no animation` variant on low-power surfaces and respect `prefers-reduced-motion`." (https://vercel.com/geist/skeleton)
|
|
23
23
|
* Ours: hidden from assistive technology and never focusable; an unsized wrapper covers its children inert and is `aria-busy` while it covers them. There is no shimmer to disable, so the placeholder is the same under `prefers-reduced-motion`. A group of bare placeholders needs a `SkeletonRegion`.
|
|
@@ -39,7 +39,8 @@ export type SliderProps<Values extends SliderValues = readonly [number]> = Omit<
|
|
|
39
39
|
* (https://vercel.com/geist/slider) "Threshold colors (warning, error tints past a limit) should
|
|
40
40
|
* match the same numeric breakpoint surfaced elsewhere in the UI; don’t invent a slider-only
|
|
41
41
|
* threshold." (https://vercel.com/geist/slider) Ours: `label`, `min`, `max` and `step` are
|
|
42
|
-
* required.
|
|
42
|
+
* required. Values are arrays, one number per thumb, and the start and end boxes are `Input` `sm`.
|
|
43
|
+
* The label sits above the track at 13 px in the secondary grey, with the live value
|
|
43
44
|
* beside it. The track is 8 px high and grey, the filled part is blue, and the thumb is a 6 by 14
|
|
44
45
|
* px white bar; a disabled slider turns the filled part grey and leaves the rest. Colour: blue is
|
|
45
46
|
* the one hue, the filled part and nothing else. The thumb grows by a fifth while it is dragged
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"slider.d.ts","sourceRoot":"","sources":["../../src/components/slider.tsx"],"names":[],"mappings":"AAEA,OAAO,KAAK,KAAK,MAAM,OAAO,CAAC;AAC/B,OAAO,EAAE,MAAM,IAAI,eAAe,EAAE,MAAM,uBAAuB,CAAC;AAKlE,MAAM,MAAM,YAAY,GAAG,SAAS,CAAC,MAAM,CAAC,GAAG,SAAS,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;AAEzE,MAAM,MAAM,WAAW,CAAC,MAAM,SAAS,YAAY,GAAG,SAAS,CAAC,MAAM,CAAC,IAAI,IAAI,CAC7E,eAAe,CAAC,IAAI,CAAC,KAAK,CAAC,SAAS,MAAM,EAAE,CAAC,EAC3C,YAAY,GACZ,iBAAiB,GACjB,UAAU,GACV,cAAc,GACd,KAAK,GACL,KAAK,GACL,eAAe,GACf,kBAAkB,GAClB,aAAa,GACb,QAAQ,GACR,MAAM,GACN,gBAAgB,GAChB,OAAO,CACV,GAAG;IACF,sEAAsE;IACtE,GAAG,EAAE,MAAM,CAAC;IACZ,4CAA4C;IAC5C,GAAG,EAAE,MAAM,CAAC;IACZ,6EAA6E;IAC7E,IAAI,EAAE,MAAM,CAAC;IACb,kFAAkF;IAClF,KAAK,EAAE,MAAM,CAAC;IACd,2EAA2E;IAC3E,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,YAAY,CAAC,EAAE,MAAM,CAAC;IACtB,aAAa,CAAC,EAAE,CAAC,KAAK,EAAE,MAAM,KAAK,IAAI,CAAC;IACxC,uFAAuF;IACvF,gBAAgB,CAAC,EAAE,CAAC,KAAK,EAAE,MAAM,KAAK,IAAI,CAAC;IAC3C,4FAA4F;IAC5F,cAAc,CAAC,EAAE,MAAM,SAAS,SAAS,CAAC,MAAM,CAAC,GAAG,KAAK,GAAG,OAAO,CAAC;IACpE,sDAAsD;IACtD,YAAY,CAAC,EAAE,OAAO,CAAC;CACxB,CAAC;AAwDF
|
|
1
|
+
{"version":3,"file":"slider.d.ts","sourceRoot":"","sources":["../../src/components/slider.tsx"],"names":[],"mappings":"AAEA,OAAO,KAAK,KAAK,MAAM,OAAO,CAAC;AAC/B,OAAO,EAAE,MAAM,IAAI,eAAe,EAAE,MAAM,uBAAuB,CAAC;AAKlE,MAAM,MAAM,YAAY,GAAG,SAAS,CAAC,MAAM,CAAC,GAAG,SAAS,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;AAEzE,MAAM,MAAM,WAAW,CAAC,MAAM,SAAS,YAAY,GAAG,SAAS,CAAC,MAAM,CAAC,IAAI,IAAI,CAC7E,eAAe,CAAC,IAAI,CAAC,KAAK,CAAC,SAAS,MAAM,EAAE,CAAC,EAC3C,YAAY,GACZ,iBAAiB,GACjB,UAAU,GACV,cAAc,GACd,KAAK,GACL,KAAK,GACL,eAAe,GACf,kBAAkB,GAClB,aAAa,GACb,QAAQ,GACR,MAAM,GACN,gBAAgB,GAChB,OAAO,CACV,GAAG;IACF,sEAAsE;IACtE,GAAG,EAAE,MAAM,CAAC;IACZ,4CAA4C;IAC5C,GAAG,EAAE,MAAM,CAAC;IACZ,6EAA6E;IAC7E,IAAI,EAAE,MAAM,CAAC;IACb,kFAAkF;IAClF,KAAK,EAAE,MAAM,CAAC;IACd,2EAA2E;IAC3E,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,YAAY,CAAC,EAAE,MAAM,CAAC;IACtB,aAAa,CAAC,EAAE,CAAC,KAAK,EAAE,MAAM,KAAK,IAAI,CAAC;IACxC,uFAAuF;IACvF,gBAAgB,CAAC,EAAE,CAAC,KAAK,EAAE,MAAM,KAAK,IAAI,CAAC;IAC3C,4FAA4F;IAC5F,cAAc,CAAC,EAAE,MAAM,SAAS,SAAS,CAAC,MAAM,CAAC,GAAG,KAAK,GAAG,OAAO,CAAC;IACpE,sDAAsD;IACtD,YAAY,CAAC,EAAE,OAAO,CAAC;CACxB,CAAC;AAwDF;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GAkCG;AACH,iBAAS,MAAM,CAAC,MAAM,SAAS,YAAY,GAAG,SAAS,CAAC,MAAM,CAAC,EAAE,EAC/D,KAAK,EACL,KAAK,EACL,YAAY,EACZ,aAAa,EACb,gBAAgB,EAChB,cAAc,EACd,YAAY,EACZ,SAAS,EACT,GAAG,EACH,GAAG,EACH,IAAI,EACJ,QAAQ,EACR,GAAG,KAAK,EACT,EAAE,WAAW,CAAC,MAAM,CAAC,qBAkFrB;AAED,OAAO,EAAE,MAAM,EAAE,CAAC"}
|
|
@@ -42,7 +42,8 @@ function SliderValueInput({ label, value, lower, upper, min, max, step, disabled
|
|
|
42
42
|
* (https://vercel.com/geist/slider) "Threshold colors (warning, error tints past a limit) should
|
|
43
43
|
* match the same numeric breakpoint surfaced elsewhere in the UI; don’t invent a slider-only
|
|
44
44
|
* threshold." (https://vercel.com/geist/slider) Ours: `label`, `min`, `max` and `step` are
|
|
45
|
-
* required.
|
|
45
|
+
* required. Values are arrays, one number per thumb, and the start and end boxes are `Input` `sm`.
|
|
46
|
+
* The label sits above the track at 13 px in the secondary grey, with the live value
|
|
46
47
|
* beside it. The track is 8 px high and grey, the filled part is blue, and the thumb is a 6 by 14
|
|
47
48
|
* px white bar; a disabled slider turns the filled part grey and leaves the rest. Colour: blue is
|
|
48
49
|
* the one hue, the filled part and nothing else. The thumb grows by a fifth while it is dragged
|
|
@@ -36,7 +36,9 @@ type SnippetProps = SnippetContent & {
|
|
|
36
36
|
* “Use `copyText` only when `text` contains rich nodes (`<span>` highlights, conditional fragments) and the clipboard payload should be plain text. For a string `text`, `copyText` is redundant.” (https://vercel.com/geist/snippet)
|
|
37
37
|
* “Use the `copied` prop to control the copy button animation externally. This lets you copy different text (e.g. from a context card) while reusing the snippet's checkmark feedback.” (https://vercel.com/geist/snippet)
|
|
38
38
|
* “Use `copied` plus an `onCopy` callback when a parent surface (a card, a tooltip) needs to show the same checkmark feedback while copying different text.” (https://vercel.com/geist/snippet)
|
|
39
|
-
* Ours:
|
|
39
|
+
* Ours: Geist's `dark`, `type` and `width` props are not ours: `variant` sets the colour and the
|
|
40
|
+
* shell sizes itself to its text. The copy mark is a `CopyButton`; `copied` and `onCopy` let a
|
|
41
|
+
* parent show its checkmark. An array of strings is copied joined by line breaks, one row each after its own prompt; the
|
|
40
42
|
* prompt is never copied. The shell is as wide as its text, up to its row (`className="w-full"`
|
|
41
43
|
* fills the row); a longer line scrolls sideways with no scrollbar. `text=""` with a `placeholder`
|
|
42
44
|
* shows the placeholder, copies nothing and has no button. `text` that is an element needs
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"snippet.d.ts","sourceRoot":"","sources":["../../src/components/snippet.tsx"],"names":[],"mappings":"AAEA,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,OAAO,CAAC;AAE1C,OAAO,EAAc,KAAK,eAAe,EAAE,MAAM,0BAA0B,CAAC;AAG5E,KAAK,cAAc,GACf;IACE,IAAI,EAAE,MAAM,GAAG,SAAS,MAAM,EAAE,CAAC;IACjC,QAAQ,CAAC,EAAE,SAAS,CAAC;IACrB,WAAW,CAAC,EAAE,SAAS,CAAC;CACzB,GACD;IACE,IAAI,EAAE,YAAY,CAAC;IACnB,QAAQ,EAAE,MAAM,CAAC;IACjB,WAAW,CAAC,EAAE,SAAS,CAAC;CACzB,GACD;IACE,IAAI,EAAE,EAAE,CAAC;IACT,WAAW,EAAE,MAAM,CAAC;IACpB,QAAQ,CAAC,EAAE,SAAS,CAAC;CACtB,CAAC;AAEN,KAAK,cAAc,GAAG,SAAS,GAAG,UAAU,GAAG,MAAM,GAAG,SAAS,GAAG,aAAa,CAAC;AAElF,KAAK,YAAY,GAAG,cAAc,GAAG;IACnC,OAAO,CAAC,EAAE,cAAc,GAAG,SAAS,CAAC;IACrC,MAAM,CAAC,EAAE,OAAO,GAAG,SAAS,CAAC;IAC7B,MAAM,CAAC,EAAE,OAAO,GAAG,SAAS,CAAC;IAC7B,MAAM,CAAC,EAAE,CAAC,MAAM,IAAI,CAAC,GAAG,SAAS,CAAC;IAClC,SAAS,CAAC,EAAE,MAAM,GAAG,SAAS,CAAC;CAChC,GAAG,IAAI,CAAC,eAAe,EAAE,WAAW,GAAG,aAAa,GAAG,iBAAiB,CAAC,CAAC;AAuB3E
|
|
1
|
+
{"version":3,"file":"snippet.d.ts","sourceRoot":"","sources":["../../src/components/snippet.tsx"],"names":[],"mappings":"AAEA,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,OAAO,CAAC;AAE1C,OAAO,EAAc,KAAK,eAAe,EAAE,MAAM,0BAA0B,CAAC;AAG5E,KAAK,cAAc,GACf;IACE,IAAI,EAAE,MAAM,GAAG,SAAS,MAAM,EAAE,CAAC;IACjC,QAAQ,CAAC,EAAE,SAAS,CAAC;IACrB,WAAW,CAAC,EAAE,SAAS,CAAC;CACzB,GACD;IACE,IAAI,EAAE,YAAY,CAAC;IACnB,QAAQ,EAAE,MAAM,CAAC;IACjB,WAAW,CAAC,EAAE,SAAS,CAAC;CACzB,GACD;IACE,IAAI,EAAE,EAAE,CAAC;IACT,WAAW,EAAE,MAAM,CAAC;IACpB,QAAQ,CAAC,EAAE,SAAS,CAAC;CACtB,CAAC;AAEN,KAAK,cAAc,GAAG,SAAS,GAAG,UAAU,GAAG,MAAM,GAAG,SAAS,GAAG,aAAa,CAAC;AAElF,KAAK,YAAY,GAAG,cAAc,GAAG;IACnC,OAAO,CAAC,EAAE,cAAc,GAAG,SAAS,CAAC;IACrC,MAAM,CAAC,EAAE,OAAO,GAAG,SAAS,CAAC;IAC7B,MAAM,CAAC,EAAE,OAAO,GAAG,SAAS,CAAC;IAC7B,MAAM,CAAC,EAAE,CAAC,MAAM,IAAI,CAAC,GAAG,SAAS,CAAC;IAClC,SAAS,CAAC,EAAE,MAAM,GAAG,SAAS,CAAC;CAChC,GAAG,IAAI,CAAC,eAAe,EAAE,WAAW,GAAG,aAAa,GAAG,iBAAiB,CAAC,CAAC;AAuB3E;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GAgCG;AACH,iBAAS,OAAO,CAAC,KAAK,EAAE,YAAY,+BA8DnC;AAED,OAAO,EAAE,OAAO,EAAE,KAAK,YAAY,EAAE,CAAC"}
|
|
@@ -35,7 +35,9 @@ function linesOf(content) {
|
|
|
35
35
|
* “Use `copyText` only when `text` contains rich nodes (`<span>` highlights, conditional fragments) and the clipboard payload should be plain text. For a string `text`, `copyText` is redundant.” (https://vercel.com/geist/snippet)
|
|
36
36
|
* “Use the `copied` prop to control the copy button animation externally. This lets you copy different text (e.g. from a context card) while reusing the snippet's checkmark feedback.” (https://vercel.com/geist/snippet)
|
|
37
37
|
* “Use `copied` plus an `onCopy` callback when a parent surface (a card, a tooltip) needs to show the same checkmark feedback while copying different text.” (https://vercel.com/geist/snippet)
|
|
38
|
-
* Ours:
|
|
38
|
+
* Ours: Geist's `dark`, `type` and `width` props are not ours: `variant` sets the colour and the
|
|
39
|
+
* shell sizes itself to its text. The copy mark is a `CopyButton`; `copied` and `onCopy` let a
|
|
40
|
+
* parent show its checkmark. An array of strings is copied joined by line breaks, one row each after its own prompt; the
|
|
39
41
|
* prompt is never copied. The shell is as wide as its text, up to its row (`className="w-full"`
|
|
40
42
|
* fills the row); a longer line scrolls sideways with no scrollbar. `text=""` with a `placeholder`
|
|
41
43
|
* shows the placeholder, copies nothing and has no button. `text` that is an element needs
|
|
@@ -10,9 +10,9 @@ type ToasterOwnProps = Omit<ToasterProps, "closeButton" | "containerAriaLabel" |
|
|
|
10
10
|
* The one place toasts appear, mounted once per product.
|
|
11
11
|
*
|
|
12
12
|
* @family Feedback
|
|
13
|
-
* @when "A succinct message that is displayed temporarily." (https://vercel.com/geist/toast) "Use a toast for non-blocking acknowledgments of user-initiated actions: `Domain added`, `Project archived`, `Deployment canceled`." (https://vercel.com/geist/toast) "Pick the method by how the user experienced the event, not by HTTP status. A user-canceled deploy is `toasts.message('Deployment canceled')`, not `success`. A partial deploy with skipped routes is `toasts.warning(...)`." (https://vercel.com/geist/toast) Ours: mount it once and raise toasts through `showMessageToast`. `toasts.message` is the tone `info`, and `success`, `warning` and `error` keep their names.
|
|
13
|
+
* @when "A succinct message that is displayed temporarily." (https://vercel.com/geist/toast) "Use a toast for non-blocking acknowledgments of user-initiated actions: `Domain added`, `Project archived`, `Deployment canceled`." (https://vercel.com/geist/toast) "Pick the method by how the user experienced the event, not by HTTP status. A user-canceled deploy is `toasts.message('Deployment canceled')`, not `success`. A partial deploy with skipped routes is `toasts.warning(...)`." (https://vercel.com/geist/toast) Ours: mount it once and raise toasts through `showMessageToast` from `@nadicodeai/ui/components/toast`. `toasts.message` is the tone `info`, and `success`, `warning` and `error` keep their names.
|
|
14
14
|
* @instead "Don’t use a toast alone for billing failures, permission denials, or build failures the user has to triage. Pair a ≤6-word toast (`Build failed`) with a persistent row carrying the recovery step and a stable identifier." (https://vercel.com/geist/toast) "Field-level validation belongs on the `Input`, not in a toast. Persistent configuration warnings belong in `Note` or `Banner`." (https://vercel.com/geist/toast) Ours: the persistent row is a `MessageNotice`, a field's wrong value stays on the field (`FieldError`), and a lasting condition is a `NoticeBanner`.
|
|
15
|
-
* @behaviour "Default toasts auto-dismiss; pass `preserve` only when the user must read or act on the message before it disappears." (https://vercel.com/geist/toast) "Undo snackbars stay on screen for 5–10 seconds and pair the past-tense toast with a single `Undo` action button." (https://vercel.com/geist/toast) "Don’t stack toasts to narrate one async flow; emit the success or error toast at the terminal step." (https://vercel.com/geist/toast) Ours: `showMessageToast` takes no `preserve`, so every toast leaves after 6 s, which is also the Undo window; the first action with a handler becomes the toast's one button. Colour sits on the whole toast: `success` fills it with the accent blue (Geist's blue success, the same hue as an `info` note), `warning` and `error` with their solid colour, each with that colour's text; `info` stays the solid floating surface, never glass. The tone's mark stays, because a tone must read without colour and the hidden tone word Geist uses would need a word in the product's language that `showMessageToast` does not take. A toast is 420 px wide at most, 16 px padded, with a close button of 32 px at its trailing edge. A toast that stays up shows the waiting line, not a spinner. Required: `closeLabel` and `regionLabel`, because the close button and the region need a name in the product's language.
|
|
15
|
+
* @behaviour "Default toasts auto-dismiss; pass `preserve` only when the user must read or act on the message before it disappears." (https://vercel.com/geist/toast) "Undo snackbars stay on screen for 5–10 seconds and pair the past-tense toast with a single `Undo` action button." (https://vercel.com/geist/toast) "Don’t stack toasts to narrate one async flow; emit the success or error toast at the terminal step." (https://vercel.com/geist/toast) Ours: `showMessageToast` takes no `preserve`, so every toast leaves after 6 s, which is also the Undo window; the first action with a handler becomes the toast's one button, and its label is the catalogue's, so a literal `Undo` is not enforced. A toast always has a tone, so there is no neutral toast without a mark: `info` is the nearest. Colour sits on the whole toast: `success` fills it with the accent blue (Geist's blue success, the same hue as an `info` note), `warning` and `error` with their solid colour, each with that colour's text; `info` stays the solid floating surface, never glass. The tone's mark stays, because a tone must read without colour and the hidden tone word Geist uses would need a word in the product's language that `showMessageToast` does not take. A toast is 420 px wide at most, 16 px padded, with a close button of 32 px at its trailing edge. A toast that stays up shows the waiting line, not a spinner. Required: `closeLabel` and `regionLabel`, because the close button and the region need a name in the product's language.
|
|
16
16
|
* @words "One sentence, sentence case, no trailing period when the toast is a single sentence." (https://vercel.com/geist/toast) "Completion toasts follow `{Noun} {past-participle}`: `Blob deleted`, `Domain added`, `Environment variable saved`. Never include `successfully`; the action name implies it." (https://vercel.com/geist/toast) "Error toasts are two sentences with periods and end with a recovery step: `Couldn’t verify domain. Try again.` Use `Couldn’t` for user-state errors and `Failed to` for system or infra errors; match adjacent shipped copy and don’t flip mid-flow." (https://vercel.com/geist/toast) "Pair the toast verb 1:1 with the destructive button verb (`Delete Project` then `Project deleted`, never `Project removed`)." (https://vercel.com/geist/toast) "Undo snackbars use the literal label `Undo`, never `Restore`, `Bring Back`, or `Cancel`. Only use the pattern when the rollback is safe." (https://vercel.com/geist/toast) Ours: the words come from the catalogue; *Mailbox removed* pairs with its button *Remove mailbox*.
|
|
17
17
|
* @access "The toast region announces with `aria-live="polite"`; reserve `assertive` for blocking errors that interrupt a flow." (https://vercel.com/geist/toast) "Don’t put primary navigation inside a toast; transient surfaces vanish before keyboard users can reach them." (https://vercel.com/geist/toast) Ours: the toaster's live region is named by `regionLabel` and the close button by `closeLabel`. Navigation is never the only route to recovery: the record's own row keeps its controls. Undo is reachable by keyboard (Alt+T moves focus to the toasts) while it shows.
|
|
18
18
|
*/
|
|
@@ -10,9 +10,9 @@ const TOAST_DURATION_MS = 6000;
|
|
|
10
10
|
* The one place toasts appear, mounted once per product.
|
|
11
11
|
*
|
|
12
12
|
* @family Feedback
|
|
13
|
-
* @when "A succinct message that is displayed temporarily." (https://vercel.com/geist/toast) "Use a toast for non-blocking acknowledgments of user-initiated actions: `Domain added`, `Project archived`, `Deployment canceled`." (https://vercel.com/geist/toast) "Pick the method by how the user experienced the event, not by HTTP status. A user-canceled deploy is `toasts.message('Deployment canceled')`, not `success`. A partial deploy with skipped routes is `toasts.warning(...)`." (https://vercel.com/geist/toast) Ours: mount it once and raise toasts through `showMessageToast`. `toasts.message` is the tone `info`, and `success`, `warning` and `error` keep their names.
|
|
13
|
+
* @when "A succinct message that is displayed temporarily." (https://vercel.com/geist/toast) "Use a toast for non-blocking acknowledgments of user-initiated actions: `Domain added`, `Project archived`, `Deployment canceled`." (https://vercel.com/geist/toast) "Pick the method by how the user experienced the event, not by HTTP status. A user-canceled deploy is `toasts.message('Deployment canceled')`, not `success`. A partial deploy with skipped routes is `toasts.warning(...)`." (https://vercel.com/geist/toast) Ours: mount it once and raise toasts through `showMessageToast` from `@nadicodeai/ui/components/toast`. `toasts.message` is the tone `info`, and `success`, `warning` and `error` keep their names.
|
|
14
14
|
* @instead "Don’t use a toast alone for billing failures, permission denials, or build failures the user has to triage. Pair a ≤6-word toast (`Build failed`) with a persistent row carrying the recovery step and a stable identifier." (https://vercel.com/geist/toast) "Field-level validation belongs on the `Input`, not in a toast. Persistent configuration warnings belong in `Note` or `Banner`." (https://vercel.com/geist/toast) Ours: the persistent row is a `MessageNotice`, a field's wrong value stays on the field (`FieldError`), and a lasting condition is a `NoticeBanner`.
|
|
15
|
-
* @behaviour "Default toasts auto-dismiss; pass `preserve` only when the user must read or act on the message before it disappears." (https://vercel.com/geist/toast) "Undo snackbars stay on screen for 5–10 seconds and pair the past-tense toast with a single `Undo` action button." (https://vercel.com/geist/toast) "Don’t stack toasts to narrate one async flow; emit the success or error toast at the terminal step." (https://vercel.com/geist/toast) Ours: `showMessageToast` takes no `preserve`, so every toast leaves after 6 s, which is also the Undo window; the first action with a handler becomes the toast's one button. Colour sits on the whole toast: `success` fills it with the accent blue (Geist's blue success, the same hue as an `info` note), `warning` and `error` with their solid colour, each with that colour's text; `info` stays the solid floating surface, never glass. The tone's mark stays, because a tone must read without colour and the hidden tone word Geist uses would need a word in the product's language that `showMessageToast` does not take. A toast is 420 px wide at most, 16 px padded, with a close button of 32 px at its trailing edge. A toast that stays up shows the waiting line, not a spinner. Required: `closeLabel` and `regionLabel`, because the close button and the region need a name in the product's language.
|
|
15
|
+
* @behaviour "Default toasts auto-dismiss; pass `preserve` only when the user must read or act on the message before it disappears." (https://vercel.com/geist/toast) "Undo snackbars stay on screen for 5–10 seconds and pair the past-tense toast with a single `Undo` action button." (https://vercel.com/geist/toast) "Don’t stack toasts to narrate one async flow; emit the success or error toast at the terminal step." (https://vercel.com/geist/toast) Ours: `showMessageToast` takes no `preserve`, so every toast leaves after 6 s, which is also the Undo window; the first action with a handler becomes the toast's one button, and its label is the catalogue's, so a literal `Undo` is not enforced. A toast always has a tone, so there is no neutral toast without a mark: `info` is the nearest. Colour sits on the whole toast: `success` fills it with the accent blue (Geist's blue success, the same hue as an `info` note), `warning` and `error` with their solid colour, each with that colour's text; `info` stays the solid floating surface, never glass. The tone's mark stays, because a tone must read without colour and the hidden tone word Geist uses would need a word in the product's language that `showMessageToast` does not take. A toast is 420 px wide at most, 16 px padded, with a close button of 32 px at its trailing edge. A toast that stays up shows the waiting line, not a spinner. Required: `closeLabel` and `regionLabel`, because the close button and the region need a name in the product's language.
|
|
16
16
|
* @words "One sentence, sentence case, no trailing period when the toast is a single sentence." (https://vercel.com/geist/toast) "Completion toasts follow `{Noun} {past-participle}`: `Blob deleted`, `Domain added`, `Environment variable saved`. Never include `successfully`; the action name implies it." (https://vercel.com/geist/toast) "Error toasts are two sentences with periods and end with a recovery step: `Couldn’t verify domain. Try again.` Use `Couldn’t` for user-state errors and `Failed to` for system or infra errors; match adjacent shipped copy and don’t flip mid-flow." (https://vercel.com/geist/toast) "Pair the toast verb 1:1 with the destructive button verb (`Delete Project` then `Project deleted`, never `Project removed`)." (https://vercel.com/geist/toast) "Undo snackbars use the literal label `Undo`, never `Restore`, `Bring Back`, or `Cancel`. Only use the pattern when the rollback is safe." (https://vercel.com/geist/toast) Ours: the words come from the catalogue; *Mailbox removed* pairs with its button *Remove mailbox*.
|
|
17
17
|
* @access "The toast region announces with `aria-live="polite"`; reserve `assertive` for blocking errors that interrupt a flow." (https://vercel.com/geist/toast) "Don’t put primary navigation inside a toast; transient surfaces vanish before keyboard users can reach them." (https://vercel.com/geist/toast) Ours: the toaster's live region is named by `regionLabel` and the close button by `closeLabel`. Navigation is never the only route to recovery: the record's own row keeps its controls. Undo is reachable by keyboard (Alt+T moves focus to the toasts) while it shows.
|
|
18
18
|
*/
|
|
@@ -17,7 +17,9 @@ type StatusBadgeProps = Omit<ComponentProps<"span">, "children" | "onClick"> & {
|
|
|
17
17
|
* @family Status
|
|
18
18
|
* @when "Use Badge for short, scannable metadata that sits next to the thing it describes: status, plan tier, environment, or role." (https://vercel.com/geist/badge)
|
|
19
19
|
* Ours: a record's state, when it sets the row apart: failed, waiting on a person, a step in
|
|
20
|
-
* motion, paused, connected. Gray is every terminal state that needs no action
|
|
20
|
+
* motion, paused, connected. Gray is the default and every terminal state that needs no action;
|
|
21
|
+
* green is healthy or complete; red is unusable or failed; amber is waiting on a person's
|
|
22
|
+
* decision; blue is a step in motion.
|
|
21
23
|
* "Map meaning to color: `green` for healthy, `red` for error, `amber` for warning, `blue` for informational or production, `gray` for neutral." (https://vercel.com/geist/badge)
|
|
22
24
|
* Ours: success is green, danger red, warning amber, info blue, neutral gray, whatever the state's
|
|
23
25
|
* name, in our colour values. The tone and the word are required, and the type asks for both.
|
|
@@ -33,7 +35,8 @@ type StatusBadgeProps = Omit<ComponentProps<"span">, "children" | "onClick"> & {
|
|
|
33
35
|
* tone's soft ground and sets the mark and the word in its strong shade; gray takes the foreground
|
|
34
36
|
* colour, never a muted one. `solid` is for a status that stands on its own, such as an object's
|
|
35
37
|
* page header or a card title: it fills the pill with the tone's strong colour and sets the mark
|
|
36
|
-
* and the word on it. No border and no ring either way.
|
|
38
|
+
* and the word on it. No border and no ring either way. The `subtle` pairs are the tone's soft
|
|
39
|
+
* ground with its deep shade (gray: `canvas-soft-2` with the foreground colour).
|
|
37
40
|
* "Don’t add a checkmark icon for success states or an X for errors; the variant carries that signal." (https://vercel.com/geist/badge)
|
|
38
41
|
* Ours: it always draws its tone's mark, even for success and error: the mark repeats the tone as a
|
|
39
42
|
* shape so a status reads without colour. Each app keeps one value-to-tone map in one module;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"status-badge.d.ts","sourceRoot":"","sources":["../../src/components/status-badge.tsx"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,OAAO,CAAC;AAG5C,OAAO,EAAS,KAAK,SAAS,EAAE,MAAM,oBAAoB,CAAC;AAG3D,KAAK,eAAe,GAAG,SAAS,GAAG,SAAS,GAAG,QAAQ,GAAG,MAAM,GAAG,SAAS,CAAC;AAE7E,KAAK,mBAAmB,GAAG,QAAQ,GAAG,OAAO,CAAC;AAgD9C,KAAK,gBAAgB,GAAG,IAAI,CAAC,cAAc,CAAC,MAAM,CAAC,EAAE,UAAU,GAAG,SAAS,CAAC,GAAG;IAC7E,IAAI,EAAE,eAAe,CAAC;IACtB,KAAK,EAAE,MAAM,CAAC;IACd,IAAI,CAAC,EAAE,SAAS,CAAC;IACjB,6FAA6F;IAC7F,QAAQ,CAAC,EAAE,mBAAmB,CAAC;IAC/B,2EAA2E;IAC3E,KAAK,CAAC,EAAE,MAAM,CAAC;CAChB,CAAC;AAEF
|
|
1
|
+
{"version":3,"file":"status-badge.d.ts","sourceRoot":"","sources":["../../src/components/status-badge.tsx"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,OAAO,CAAC;AAG5C,OAAO,EAAS,KAAK,SAAS,EAAE,MAAM,oBAAoB,CAAC;AAG3D,KAAK,eAAe,GAAG,SAAS,GAAG,SAAS,GAAG,QAAQ,GAAG,MAAM,GAAG,SAAS,CAAC;AAE7E,KAAK,mBAAmB,GAAG,QAAQ,GAAG,OAAO,CAAC;AAgD9C,KAAK,gBAAgB,GAAG,IAAI,CAAC,cAAc,CAAC,MAAM,CAAC,EAAE,UAAU,GAAG,SAAS,CAAC,GAAG;IAC7E,IAAI,EAAE,eAAe,CAAC;IACtB,KAAK,EAAE,MAAM,CAAC;IACd,IAAI,CAAC,EAAE,SAAS,CAAC;IACjB,6FAA6F;IAC7F,QAAQ,CAAC,EAAE,mBAAmB,CAAC;IAC/B,2EAA2E;IAC3E,KAAK,CAAC,EAAE,MAAM,CAAC;CAChB,CAAC;AAEF;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GAsCG;AACH,iBAAS,WAAW,CAAC,EACnB,IAAI,EACJ,KAAK,EACL,KAAK,EACL,SAAS,EACT,IAAW,EACX,QAAmB,EACnB,GAAG,KAAK,EACT,EAAE,gBAAgB,+BAqBlB;AAED,OAAO,EAAE,WAAW,EAAE,KAAK,mBAAmB,EAAE,KAAK,gBAAgB,EAAE,KAAK,eAAe,EAAE,CAAC"}
|
|
@@ -51,7 +51,9 @@ const CIRCLE_MARK_INSET = {
|
|
|
51
51
|
* @family Status
|
|
52
52
|
* @when "Use Badge for short, scannable metadata that sits next to the thing it describes: status, plan tier, environment, or role." (https://vercel.com/geist/badge)
|
|
53
53
|
* Ours: a record's state, when it sets the row apart: failed, waiting on a person, a step in
|
|
54
|
-
* motion, paused, connected. Gray is every terminal state that needs no action
|
|
54
|
+
* motion, paused, connected. Gray is the default and every terminal state that needs no action;
|
|
55
|
+
* green is healthy or complete; red is unusable or failed; amber is waiting on a person's
|
|
56
|
+
* decision; blue is a step in motion.
|
|
55
57
|
* "Map meaning to color: `green` for healthy, `red` for error, `amber` for warning, `blue` for informational or production, `gray` for neutral." (https://vercel.com/geist/badge)
|
|
56
58
|
* Ours: success is green, danger red, warning amber, info blue, neutral gray, whatever the state's
|
|
57
59
|
* name, in our colour values. The tone and the word are required, and the type asks for both.
|
|
@@ -67,7 +69,8 @@ const CIRCLE_MARK_INSET = {
|
|
|
67
69
|
* tone's soft ground and sets the mark and the word in its strong shade; gray takes the foreground
|
|
68
70
|
* colour, never a muted one. `solid` is for a status that stands on its own, such as an object's
|
|
69
71
|
* page header or a card title: it fills the pill with the tone's strong colour and sets the mark
|
|
70
|
-
* and the word on it. No border and no ring either way.
|
|
72
|
+
* and the word on it. No border and no ring either way. The `subtle` pairs are the tone's soft
|
|
73
|
+
* ground with its deep shade (gray: `canvas-soft-2` with the foreground colour).
|
|
71
74
|
* "Don’t add a checkmark icon for success states or an X for errors; the variant carries that signal." (https://vercel.com/geist/badge)
|
|
72
75
|
* Ours: it always draws its tone's mark, even for success and error: the mark repeats the tone as a
|
|
73
76
|
* shape so a status reads without colour. Each app keeps one value-to-tone map in one module;
|
|
@@ -29,7 +29,8 @@ type StatusDotProps = Omit<ComponentProps<"span">, "children" | "role" | "title"
|
|
|
29
29
|
* Ours: something in motion is the waiting line or an Agent's orb; the dot has no info tone.
|
|
30
30
|
* @behaviour "The dot animates while `BUILDING` or `QUEUED` and goes static once the deployment reaches a terminal state." (https://vercel.com/geist/status-dot)
|
|
31
31
|
* "Don’t add a separate spinner alongside it." (https://vercel.com/geist/status-dot) Ours: still,
|
|
32
|
-
* even while a state is in progress: it never pulses.
|
|
32
|
+
* even while a state is in progress: it never pulses. It has no deployment states and no `state`
|
|
33
|
+
* prop, only four generic tones. A 10 px dot; tones are `good`, `muted`,
|
|
33
34
|
* `warn`, `bad`, at full strength. Colour sits on the dot alone: with `showLabel` the word beside
|
|
34
35
|
* it is 14 px and neutral, never in the tone's colour. `label` alone draws the dot with the word as
|
|
35
36
|
* its name and tooltip; `showLabel` draws the word 8 px after it, for a dot with no other text
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"status-dot.d.ts","sourceRoot":"","sources":["../../src/components/status-dot.tsx"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,OAAO,CAAC;AAG5C,KAAK,UAAU,GAAG,MAAM,GAAG,OAAO,GAAG,MAAM,GAAG,KAAK,CAAC;AAUpD,KAAK,aAAa,GACd;IAAE,KAAK,EAAE,MAAM,CAAC;IAAC,SAAS,CAAC,EAAE,OAAO,CAAC;IAAC,UAAU,CAAC,EAAE,KAAK,CAAA;CAAE,GAC1D;IAAE,UAAU,EAAE,IAAI,CAAC;IAAC,KAAK,CAAC,EAAE,KAAK,CAAC;IAAC,SAAS,CAAC,EAAE,KAAK,CAAA;CAAE,CAAC;AAE3D,KAAK,cAAc,GAAG,IAAI,CACxB,cAAc,CAAC,MAAM,CAAC,EACtB,UAAU,GAAG,MAAM,GAAG,OAAO,GAAG,aAAa,GAAG,YAAY,GAAG,iBAAiB,CACjF,GAAG;IACF,IAAI,EAAE,UAAU,CAAC;CAClB,GAAG,aAAa,CAAC;AAElB
|
|
1
|
+
{"version":3,"file":"status-dot.d.ts","sourceRoot":"","sources":["../../src/components/status-dot.tsx"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,OAAO,CAAC;AAG5C,KAAK,UAAU,GAAG,MAAM,GAAG,OAAO,GAAG,MAAM,GAAG,KAAK,CAAC;AAUpD,KAAK,aAAa,GACd;IAAE,KAAK,EAAE,MAAM,CAAC;IAAC,SAAS,CAAC,EAAE,OAAO,CAAC;IAAC,UAAU,CAAC,EAAE,KAAK,CAAA;CAAE,GAC1D;IAAE,UAAU,EAAE,IAAI,CAAC;IAAC,KAAK,CAAC,EAAE,KAAK,CAAC;IAAC,SAAS,CAAC,EAAE,KAAK,CAAA;CAAE,CAAC;AAE3D,KAAK,cAAc,GAAG,IAAI,CACxB,cAAc,CAAC,MAAM,CAAC,EACtB,UAAU,GAAG,MAAM,GAAG,OAAO,GAAG,aAAa,GAAG,YAAY,GAAG,iBAAiB,CACjF,GAAG;IACF,IAAI,EAAE,UAAU,CAAC;CAClB,GAAG,aAAa,CAAC;AAElB;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GAkCG;AACH,iBAAS,SAAS,CAAC,EACjB,SAAS,EACT,IAAI,EACJ,KAAK,EACL,SAAiB,EACjB,UAAU,EACV,GAAG,KAAK,EACT,EAAE,cAAc,+BAuChB;AACD,OAAO,EAAE,SAAS,EAAE,CAAC;AACrB,YAAY,EAAE,UAAU,EAAE,CAAC"}
|
|
@@ -24,7 +24,8 @@ const DOT_CLASS = "inline-block size-2.5 shrink-0 rounded-full";
|
|
|
24
24
|
* Ours: something in motion is the waiting line or an Agent's orb; the dot has no info tone.
|
|
25
25
|
* @behaviour "The dot animates while `BUILDING` or `QUEUED` and goes static once the deployment reaches a terminal state." (https://vercel.com/geist/status-dot)
|
|
26
26
|
* "Don’t add a separate spinner alongside it." (https://vercel.com/geist/status-dot) Ours: still,
|
|
27
|
-
* even while a state is in progress: it never pulses.
|
|
27
|
+
* even while a state is in progress: it never pulses. It has no deployment states and no `state`
|
|
28
|
+
* prop, only four generic tones. A 10 px dot; tones are `good`, `muted`,
|
|
28
29
|
* `warn`, `bad`, at full strength. Colour sits on the dot alone: with `showLabel` the word beside
|
|
29
30
|
* it is 14 px and neutral, never in the tone's colour. `label` alone draws the dot with the word as
|
|
30
31
|
* its name and tooltip; `showLabel` draws the word 8 px after it, for a dot with no other text
|
|
@@ -8,9 +8,9 @@ import { type ControlName } from "../internal/control-name.js";
|
|
|
8
8
|
* Protection` or `Auto-Cancel Builds`." (https://vercel.com/geist/toggle) Ours: Geist's `Toggle` is
|
|
9
9
|
* our `Switch`, inside a settings section.
|
|
10
10
|
* @instead "Switch to `Checkbox` for a multi-select list, or to `Switch` for 2–3 mutually exclusive
|
|
11
|
-
* views." (https://vercel.com/geist/toggle) Ours: Geist's `Switch` is our `SegmentedControl`.
|
|
12
|
-
*
|
|
13
|
-
* `RadioGroup`.
|
|
11
|
+
* views." (https://vercel.com/geist/toggle) Ours: Geist's `Switch` is our `SegmentedControl`. Our
|
|
12
|
+
* `Toggle` is a button that stays pressed, and several of them are a `ToggleGroup`. Choosing
|
|
13
|
+
* between named values is a `RadioGroup`.
|
|
14
14
|
* @behaviour "`checked` is required and the component is controlled. Own the state and update it
|
|
15
15
|
* from `onChange`." (https://vercel.com/geist/toggle) "Persist on change and surface the result in
|
|
16
16
|
* a `useToasts().success(…)` toast (`Password protection enabled`); don’t leave the user wondering
|
|
@@ -24,9 +24,10 @@ import { type ControlName } from "../internal/control-name.js";
|
|
|
24
24
|
* and a switch with none of them does not compile. A bare `Switch` is the 28 by 14 px track with an
|
|
25
25
|
* 11 px thumb; `md` is 36 by 20 px and `lg` 40 by 24 px. Colour: off is the input grey, on is
|
|
26
26
|
* ink, and a disabled switch turns grey, on or off, with a greyer thumb and no shadow. Space flips
|
|
27
|
-
* it. On a settings page it applies at once and the product's toast confirms it, in one of
|
|
28
|
-
* places: in the card's
|
|
29
|
-
*
|
|
27
|
+
* it. On a settings page it applies at once and the product's toast confirms it, in one of three
|
|
28
|
+
* places: in the card's body under its label, its state word after it (`SettingsField`'s
|
|
29
|
+
* `control="switch"`); in the card's header at the right of the title when the switch is the whole card, the
|
|
30
|
+
* footer holding only its line; or at the end of a row of a card of several settings, the label to
|
|
30
31
|
* its left. A failed change leaves the switch showing the true state.
|
|
31
32
|
* @words "The label is `children`, not a `label` prop. Title Case noun phrase, 1–4 words, naming
|
|
32
33
|
* what is true when ON: `Password Protection`, not `Enable Password Protection`."
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"switch.d.ts","sourceRoot":"","sources":["../../src/components/switch.tsx"],"names":[],"mappings":"AAAA,OAAO,EAAE,MAAM,IAAI,eAAe,EAAE,MAAM,uBAAuB,CAAC;AAGlE,OAAO,EAAE,KAAK,WAAW,EAAE,MAAM,yBAAyB,CAAC;AAE3D
|
|
1
|
+
{"version":3,"file":"switch.d.ts","sourceRoot":"","sources":["../../src/components/switch.tsx"],"names":[],"mappings":"AAAA,OAAO,EAAE,MAAM,IAAI,eAAe,EAAE,MAAM,uBAAuB,CAAC;AAGlE,OAAO,EAAE,KAAK,WAAW,EAAE,MAAM,yBAAyB,CAAC;AAE3D;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GA6CG;AACH,iBAAS,MAAM,CAAC,EACd,SAAS,EACT,IAAW,EACX,GAAG,KAAK,EACT,EAAE,eAAe,CAAC,IAAI,CAAC,KAAK,GAC3B,WAAW,GAAG;IACZ,IAAI,CAAC,EAAE,IAAI,GAAG,IAAI,GAAG,IAAI,CAAC;CAC3B,+BAiBF;AAED,OAAO,EAAE,MAAM,EAAE,CAAC"}
|
|
@@ -9,9 +9,9 @@ import { cn } from "../lib/utils.js";
|
|
|
9
9
|
* Protection` or `Auto-Cancel Builds`." (https://vercel.com/geist/toggle) Ours: Geist's `Toggle` is
|
|
10
10
|
* our `Switch`, inside a settings section.
|
|
11
11
|
* @instead "Switch to `Checkbox` for a multi-select list, or to `Switch` for 2–3 mutually exclusive
|
|
12
|
-
* views." (https://vercel.com/geist/toggle) Ours: Geist's `Switch` is our `SegmentedControl`.
|
|
13
|
-
*
|
|
14
|
-
* `RadioGroup`.
|
|
12
|
+
* views." (https://vercel.com/geist/toggle) Ours: Geist's `Switch` is our `SegmentedControl`. Our
|
|
13
|
+
* `Toggle` is a button that stays pressed, and several of them are a `ToggleGroup`. Choosing
|
|
14
|
+
* between named values is a `RadioGroup`.
|
|
15
15
|
* @behaviour "`checked` is required and the component is controlled. Own the state and update it
|
|
16
16
|
* from `onChange`." (https://vercel.com/geist/toggle) "Persist on change and surface the result in
|
|
17
17
|
* a `useToasts().success(…)` toast (`Password protection enabled`); don’t leave the user wondering
|
|
@@ -25,9 +25,10 @@ import { cn } from "../lib/utils.js";
|
|
|
25
25
|
* and a switch with none of them does not compile. A bare `Switch` is the 28 by 14 px track with an
|
|
26
26
|
* 11 px thumb; `md` is 36 by 20 px and `lg` 40 by 24 px. Colour: off is the input grey, on is
|
|
27
27
|
* ink, and a disabled switch turns grey, on or off, with a greyer thumb and no shadow. Space flips
|
|
28
|
-
* it. On a settings page it applies at once and the product's toast confirms it, in one of
|
|
29
|
-
* places: in the card's
|
|
30
|
-
*
|
|
28
|
+
* it. On a settings page it applies at once and the product's toast confirms it, in one of three
|
|
29
|
+
* places: in the card's body under its label, its state word after it (`SettingsField`'s
|
|
30
|
+
* `control="switch"`); in the card's header at the right of the title when the switch is the whole card, the
|
|
31
|
+
* footer holding only its line; or at the end of a row of a card of several settings, the label to
|
|
31
32
|
* its left. A failed change leaves the switch showing the true state.
|
|
32
33
|
* @words "The label is `children`, not a `label` prop. Title Case noun phrase, 1–4 words, naming
|
|
33
34
|
* what is true when ON: `Password Protection`, not `Enable Password Protection`."
|
|
@@ -12,22 +12,29 @@ type TableName = AccessibleName | {
|
|
|
12
12
|
*
|
|
13
13
|
* @family Data
|
|
14
14
|
* @when “Use `<Table>` for tabular data where rows share the same shape and at least one column is sortable or comparable across rows.” (https://vercel.com/geist/table)
|
|
15
|
-
* Ours: a fixed table a composition draws itself: a summary inside a card, a list of plan limits, figures compared down a column. A table of records is `DataTable`, which draws this one.
|
|
15
|
+
* Ours: a fixed table a composition draws itself: a summary inside a card, a list of plan limits, figures compared down a column. A table of records is `DataTable`, which draws this one, inside a `TableCard`. It does not virtualize its rows; that is a separate capability.
|
|
16
16
|
* @instead “For a row of descriptive content paired with a single action (membership row, integration row), use `Entity` instead.” (https://vercel.com/geist/table)
|
|
17
17
|
* “For a key/value metadata block on a detail page, use `Description`, not a two-column table.” (https://vercel.com/geist/table)
|
|
18
18
|
* “When the underlying list is empty (filter cleared, never created), render `Empty State` outside the table rather than an empty `<Table.Body>`.” (https://vercel.com/geist/table)
|
|
19
19
|
* Ours: Geist's `Entity` is `Item`, or `RecordList` when the row names a record; its `Description` is `ObjectFacts`; its `Empty State` is `EmptyState`. Records with sorting, paging and an empty state are `DataTable`.
|
|
20
|
-
* @behaviour A head row
|
|
21
|
-
* rows 40 px
|
|
22
|
-
*
|
|
23
|
-
*
|
|
24
|
-
*
|
|
25
|
-
*
|
|
20
|
+
* @behaviour A head row 48 px high, with 12 px of room under its labels and then a 1 px rule, so the first row starts at the rule like every other; body
|
|
21
|
+
* rows 40 px (a cell that holds a control, such as the three dots, is padded just enough to keep the
|
|
22
|
+
* row at 40), every cell padded 8 px sideways and 10 px above and below in the body, and headings
|
|
23
|
+
* at 14 px / 20 px, weight 500, visible because people compare by them. Body rows have no rule
|
|
24
|
+
* between them unless the body is `bordered`, which draws it straight across the row. In a body
|
|
25
|
+
* that is not `bordered`, the first and last cell of a row take a 6 px corner, so a stripe or a
|
|
26
|
+
* highlight reads as a rounded bar; a `bordered` row keeps square corners, so its rule meets the
|
|
27
|
+
* edge. The last column, its heading and its cells, aligns to the trailing edge; any other
|
|
28
|
+
* numeric column takes `text-right` and `tabular-nums` to match. `striped`, `bordered` and
|
|
29
|
+
* `interactive` belong to `TableBody`: stripes fill the odd rows with `muted` (a selected row there takes `accent`), `bordered` draws a rule between rows (not
|
|
26
30
|
* after the last) and no frame, and an interactive row takes `accent` on hover, on focus within and
|
|
27
31
|
* while its menu is open, over a stripe; a row that opens nothing is not `interactive`. Headers and
|
|
28
|
-
* footers never highlight and carry no fill
|
|
29
|
-
* column's width is a `TableCol` in a
|
|
30
|
-
*
|
|
32
|
+
* footers never highlight and carry no fill, and a selected row (`data-state="selected"`) takes
|
|
33
|
+
* `muted`; a footer has a rule above it and ink, medium text. A column's width is a `TableCol` in a
|
|
34
|
+
* `TableColgroup`. The table has no fill or edge of its own: it takes its enclosing surface, whose
|
|
35
|
+
* `Card` owns the outer edge, and a visible header and every record but the last end in a quiet 1 px
|
|
36
|
+
* `border` rule. A table that opens nothing implies no action on hover. `density="comfortable"` is
|
|
37
|
+
* the entity row of a record that names itself. On a card narrower than its `compactDetails` layout a row never scrolls
|
|
31
38
|
* sideways: its secondary columns leave the row and their values stand in the `TableDetailRow` under
|
|
32
39
|
* it, one muted line joined by a middle dot that ends in an ellipsis, their labels read by assistive
|
|
33
40
|
* technology only, as Vercel's lists read on a phone; a `Tag` there reads as its plain text, and a
|
|
@@ -37,7 +44,7 @@ type TableName = AccessibleName | {
|
|
|
37
44
|
* the body grey and a heading differs by weight, the footer is ink, and the hue of a state lives in
|
|
38
45
|
* the `StatusBadge` of a cell, never in the row.
|
|
39
46
|
* “Sortable column headers are buttons. The visible label stays Title Case; the sort-direction arrow is decorative and the button announces the next sort state to assistive tech.” (https://vercel.com/geist/table)
|
|
40
|
-
* Ours: no heading sorts the rows; the order is the page's, through a `CollectionSort` above the list.
|
|
47
|
+
* Ours: no heading sorts the rows, so no heading is a button; the order is the page's, through a `CollectionSort` above the list, and only `aria-sort` marks the column it follows.
|
|
41
48
|
* “Apply `tabular-nums` (or Geist Mono) to numeric columns so digits align across rows for comparison.” (https://vercel.com/geist/table)
|
|
42
49
|
* Ours: `DataTable` sets it on a numeric column; in a `Table` a figure's cell takes `tabular-nums`.
|
|
43
50
|
* @words “Column headers (`<Table.Head>`) are Title Case nouns or noun phrases: `Last Used`, `Requests (7d)`, `Created`, `Status`. Never sentences.” (https://vercel.com/geist/table)
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"table.d.ts","sourceRoot":"","sources":["../../src/components/table.tsx"],"names":[],"mappings":"AAEA,OAAO,KAAK,KAAK,MAAM,OAAO,CAAC;AAI/B,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,qBAAqB,CAAC;AAC1D,OAAO,EAAe,KAAK,eAAe,EAAE,MAAM,+BAA+B,CAAC;AAClF,OAAO,EAAE,mBAAmB,EAAE,KAAK,kBAAkB,EAAE,MAAM,4BAA4B,CAAC;AAG1F,uGAAuG;AACvG,KAAK,SAAS,GAAG,cAAc,GAAG;IAAE,aAAa,EAAE,IAAI,CAAA;CAAE,CAAC;AAE1D
|
|
1
|
+
{"version":3,"file":"table.d.ts","sourceRoot":"","sources":["../../src/components/table.tsx"],"names":[],"mappings":"AAEA,OAAO,KAAK,KAAK,MAAM,OAAO,CAAC;AAI/B,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,qBAAqB,CAAC;AAC1D,OAAO,EAAe,KAAK,eAAe,EAAE,MAAM,+BAA+B,CAAC;AAClF,OAAO,EAAE,mBAAmB,EAAE,KAAK,kBAAkB,EAAE,MAAM,4BAA4B,CAAC;AAG1F,uGAAuG;AACvG,KAAK,SAAS,GAAG,cAAc,GAAG;IAAE,aAAa,EAAE,IAAI,CAAA;CAAE,CAAC;AAE1D;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GAgDG;AACH,iBAAS,KAAK,CAAC,EACb,SAAS,EACT,cAAc,EACd,OAAmB,EACnB,GAAG,KAAK,EACT,EAAE,KAAK,CAAC,cAAc,CAAC,OAAO,CAAC,GAC9B,SAAS,GAAG;IACV,cAAc,CAAC,EAAE,kBAAkB,CAAC;IACpC,OAAO,CAAC,EAAE,SAAS,GAAG,aAAa,CAAC;CACrC,qBAmBF;AAED,iBAAS,aAAa,CAAC,KAAK,EAAE,KAAK,CAAC,cAAc,CAAC,UAAU,CAAC,qBAE7D;AAED,iBAAS,QAAQ,CAAC,KAAK,EAAE,KAAK,CAAC,cAAc,CAAC,KAAK,CAAC,qBAEnD;AAED,iBAAS,WAAW,CAAC,EAAE,SAAS,EAAE,GAAG,KAAK,EAAE,EAAE,KAAK,CAAC,cAAc,CAAC,OAAO,CAAC,qBAQ1E;AAID,iBAAS,SAAS,CAAC,EACjB,SAAS,EACT,OAAe,EACf,QAAgB,EAChB,WAAmB,EACnB,GAAG,KAAK,EACT,EAAE,KAAK,CAAC,cAAc,CAAC,OAAO,CAAC,GAAG;IACjC,uEAAuE;IACvE,OAAO,CAAC,EAAE,OAAO,CAAC;IAClB,uHAAuH;IACvH,QAAQ,CAAC,EAAE,OAAO,CAAC;IACnB,iFAAiF;IACjF,WAAW,CAAC,EAAE,OAAO,CAAC;CACvB,qBAeA;AAED,iBAAS,gBAAgB,CAAC,EACxB,SAAS,EACT,WAAmB,EACnB,GAAG,KAAK,EACT,EAAE,KAAK,CAAC,cAAc,CAAC,OAAO,CAAC,GAAG;IACjC,sFAAsF;IACtF,WAAW,CAAC,EAAE,OAAO,CAAC;CACvB,qBAcA;AAED,iBAAS,WAAW,CAAC,EAAE,SAAS,EAAE,GAAG,KAAK,EAAE,EAAE,KAAK,CAAC,cAAc,CAAC,OAAO,CAAC,qBAW1E;AAED,iBAAS,QAAQ,CAAC,EAChB,SAAS,EACT,YAAY,EACZ,GAAG,KAAK,EACT,EAAE,KAAK,CAAC,cAAc,CAAC,IAAI,CAAC,GAAG;IAC9B,2HAA2H;IAC3H,YAAY,CAAC,EAAE,kBAAkB,CAAC;CACnC,qBAYA;AAED,iBAAS,SAAS,CAAC,EAAE,SAAS,EAAE,GAAG,KAAK,EAAE,EAAE,KAAK,CAAC,cAAc,CAAC,IAAI,CAAC,qBAWrE;AAED,iBAAS,SAAS,CAAC,EAAE,SAAS,EAAE,GAAG,KAAK,EAAE,EAAE,KAAK,CAAC,cAAc,CAAC,IAAI,CAAC,qBAWrE;AAED,iBAAS,cAAc,CAAC,EACtB,OAAO,EACP,KAAK,EACL,MAAmB,GACpB,EAAE;IACD,OAAO,EAAE,MAAM,CAAC;IAChB,MAAM,CAAC,EAAE,kBAAkB,CAAC;IAC5B,KAAK,EAAE,SAAS,eAAe,EAAE,CAAC;CACnC,qBAyBA;AAED,iBAAS,YAAY,CAAC,EAAE,SAAS,EAAE,GAAG,KAAK,EAAE,EAAE,KAAK,CAAC,cAAc,CAAC,SAAS,CAAC,qBAQ7E;AAED,OAAO,EACL,KAAK,EACL,aAAa,EACb,QAAQ,EACR,WAAW,EACX,SAAS,EACT,gBAAgB,EAChB,WAAW,EACX,SAAS,EACT,QAAQ,EACR,SAAS,EACT,YAAY,EACZ,cAAc,EACd,mBAAmB,EACnB,KAAK,kBAAkB,GACxB,CAAC"}
|
package/dist/components/table.js
CHANGED
|
@@ -10,22 +10,29 @@ import { titleWhenCut } from "../internal/title-when-cut.js";
|
|
|
10
10
|
*
|
|
11
11
|
* @family Data
|
|
12
12
|
* @when “Use `<Table>` for tabular data where rows share the same shape and at least one column is sortable or comparable across rows.” (https://vercel.com/geist/table)
|
|
13
|
-
* Ours: a fixed table a composition draws itself: a summary inside a card, a list of plan limits, figures compared down a column. A table of records is `DataTable`, which draws this one.
|
|
13
|
+
* Ours: a fixed table a composition draws itself: a summary inside a card, a list of plan limits, figures compared down a column. A table of records is `DataTable`, which draws this one, inside a `TableCard`. It does not virtualize its rows; that is a separate capability.
|
|
14
14
|
* @instead “For a row of descriptive content paired with a single action (membership row, integration row), use `Entity` instead.” (https://vercel.com/geist/table)
|
|
15
15
|
* “For a key/value metadata block on a detail page, use `Description`, not a two-column table.” (https://vercel.com/geist/table)
|
|
16
16
|
* “When the underlying list is empty (filter cleared, never created), render `Empty State` outside the table rather than an empty `<Table.Body>`.” (https://vercel.com/geist/table)
|
|
17
17
|
* Ours: Geist's `Entity` is `Item`, or `RecordList` when the row names a record; its `Description` is `ObjectFacts`; its `Empty State` is `EmptyState`. Records with sorting, paging and an empty state are `DataTable`.
|
|
18
|
-
* @behaviour A head row
|
|
19
|
-
* rows 40 px
|
|
20
|
-
*
|
|
21
|
-
*
|
|
22
|
-
*
|
|
23
|
-
*
|
|
18
|
+
* @behaviour A head row 48 px high, with 12 px of room under its labels and then a 1 px rule, so the first row starts at the rule like every other; body
|
|
19
|
+
* rows 40 px (a cell that holds a control, such as the three dots, is padded just enough to keep the
|
|
20
|
+
* row at 40), every cell padded 8 px sideways and 10 px above and below in the body, and headings
|
|
21
|
+
* at 14 px / 20 px, weight 500, visible because people compare by them. Body rows have no rule
|
|
22
|
+
* between them unless the body is `bordered`, which draws it straight across the row. In a body
|
|
23
|
+
* that is not `bordered`, the first and last cell of a row take a 6 px corner, so a stripe or a
|
|
24
|
+
* highlight reads as a rounded bar; a `bordered` row keeps square corners, so its rule meets the
|
|
25
|
+
* edge. The last column, its heading and its cells, aligns to the trailing edge; any other
|
|
26
|
+
* numeric column takes `text-right` and `tabular-nums` to match. `striped`, `bordered` and
|
|
27
|
+
* `interactive` belong to `TableBody`: stripes fill the odd rows with `muted` (a selected row there takes `accent`), `bordered` draws a rule between rows (not
|
|
24
28
|
* after the last) and no frame, and an interactive row takes `accent` on hover, on focus within and
|
|
25
29
|
* while its menu is open, over a stripe; a row that opens nothing is not `interactive`. Headers and
|
|
26
|
-
* footers never highlight and carry no fill
|
|
27
|
-
* column's width is a `TableCol` in a
|
|
28
|
-
*
|
|
30
|
+
* footers never highlight and carry no fill, and a selected row (`data-state="selected"`) takes
|
|
31
|
+
* `muted`; a footer has a rule above it and ink, medium text. A column's width is a `TableCol` in a
|
|
32
|
+
* `TableColgroup`. The table has no fill or edge of its own: it takes its enclosing surface, whose
|
|
33
|
+
* `Card` owns the outer edge, and a visible header and every record but the last end in a quiet 1 px
|
|
34
|
+
* `border` rule. A table that opens nothing implies no action on hover. `density="comfortable"` is
|
|
35
|
+
* the entity row of a record that names itself. On a card narrower than its `compactDetails` layout a row never scrolls
|
|
29
36
|
* sideways: its secondary columns leave the row and their values stand in the `TableDetailRow` under
|
|
30
37
|
* it, one muted line joined by a middle dot that ends in an ellipsis, their labels read by assistive
|
|
31
38
|
* technology only, as Vercel's lists read on a phone; a `Tag` there reads as its plain text, and a
|
|
@@ -35,7 +42,7 @@ import { titleWhenCut } from "../internal/title-when-cut.js";
|
|
|
35
42
|
* the body grey and a heading differs by weight, the footer is ink, and the hue of a state lives in
|
|
36
43
|
* the `StatusBadge` of a cell, never in the row.
|
|
37
44
|
* “Sortable column headers are buttons. The visible label stays Title Case; the sort-direction arrow is decorative and the button announces the next sort state to assistive tech.” (https://vercel.com/geist/table)
|
|
38
|
-
* Ours: no heading sorts the rows; the order is the page's, through a `CollectionSort` above the list.
|
|
45
|
+
* Ours: no heading sorts the rows, so no heading is a button; the order is the page's, through a `CollectionSort` above the list, and only `aria-sort` marks the column it follows.
|
|
39
46
|
* “Apply `tabular-nums` (or Geist Mono) to numeric columns so digits align across rows for comparison.” (https://vercel.com/geist/table)
|
|
40
47
|
* Ours: `DataTable` sets it on a numeric column; in a `Table` a figure's cell takes `tabular-nums`.
|
|
41
48
|
* @words “Column headers (`<Table.Head>`) are Title Case nouns or noun phrases: `Last Used`, `Requests (7d)`, `Created`, `Status`. Never sentences.” (https://vercel.com/geist/table)
|