@nadicodeai/ui 12.1.101 → 12.1.103
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/dist/components/accordion.d.ts +38 -12
- package/dist/components/accordion.d.ts.map +1 -1
- package/dist/components/accordion.js +36 -15
- package/dist/components/account-menu.d.ts +18 -18
- package/dist/components/account-menu.d.ts.map +1 -1
- package/dist/components/account-menu.js +17 -13
- package/dist/components/action-menu.d.ts +20 -19
- package/dist/components/action-menu.d.ts.map +1 -1
- package/dist/components/action-menu.js +22 -15
- package/dist/components/action-status.d.ts +14 -10
- package/dist/components/action-status.d.ts.map +1 -1
- package/dist/components/action-status.js +14 -10
- package/dist/components/activity-calendar.d.ts +3 -1
- package/dist/components/activity-calendar.d.ts.map +1 -1
- package/dist/components/activity-calendar.js +16 -2
- package/dist/components/activity-feed.d.ts +2 -2
- package/dist/components/activity-feed.d.ts.map +1 -1
- package/dist/components/activity-feed.js +14 -5
- package/dist/components/agent-card.d.ts +11 -5
- package/dist/components/agent-card.d.ts.map +1 -1
- package/dist/components/agent-card.js +13 -7
- package/dist/components/agent-list-row.js +1 -1
- package/dist/components/agent-orb-appearance.d.ts +7 -1
- package/dist/components/agent-orb-appearance.d.ts.map +1 -1
- package/dist/components/agent-orb-appearance.js +26 -0
- package/dist/components/agent-profile.d.ts +8 -7
- package/dist/components/agent-profile.d.ts.map +1 -1
- package/dist/components/agent-profile.js +6 -6
- package/dist/components/alert-dialog.d.ts +25 -16
- package/dist/components/alert-dialog.d.ts.map +1 -1
- package/dist/components/alert-dialog.js +30 -18
- package/dist/components/alert.d.ts +1 -1
- package/dist/components/avatar.d.ts +83 -17
- package/dist/components/avatar.d.ts.map +1 -1
- package/dist/components/avatar.js +89 -23
- package/dist/components/badge.d.ts +59 -8
- package/dist/components/badge.d.ts.map +1 -1
- package/dist/components/badge.js +57 -14
- package/dist/components/breadcrumb.d.ts +18 -7
- package/dist/components/breadcrumb.d.ts.map +1 -1
- package/dist/components/breadcrumb.js +37 -13
- package/dist/components/button-group.d.ts +12 -15
- package/dist/components/button-group.d.ts.map +1 -1
- package/dist/components/button-group.js +13 -17
- package/dist/components/button.d.ts +126 -23
- package/dist/components/button.d.ts.map +1 -1
- package/dist/components/button.js +164 -39
- package/dist/components/calendar.d.ts +26 -15
- package/dist/components/calendar.d.ts.map +1 -1
- package/dist/components/calendar.js +60 -46
- package/dist/components/card-row.d.ts +13 -5
- package/dist/components/card-row.d.ts.map +1 -1
- package/dist/components/card-row.js +24 -10
- package/dist/components/card.d.ts +6 -12
- package/dist/components/card.d.ts.map +1 -1
- package/dist/components/card.js +11 -16
- package/dist/components/carousel.d.ts +3 -3
- package/dist/components/carousel.d.ts.map +1 -1
- package/dist/components/carousel.js +7 -7
- package/dist/components/catalog-drawer.d.ts +7 -7
- package/dist/components/catalog-drawer.d.ts.map +1 -1
- package/dist/components/catalog-drawer.js +6 -6
- package/dist/components/chart-area-stacked.d.ts +1 -1
- package/dist/components/chart-area-stacked.d.ts.map +1 -1
- package/dist/components/chart-area-stacked.js +4 -4
- package/dist/components/chart-axis.d.ts +14 -1
- package/dist/components/chart-axis.d.ts.map +1 -1
- package/dist/components/chart-axis.js +11 -1
- package/dist/components/chart-bar-horizontal.d.ts +2 -2
- package/dist/components/chart-bar-horizontal.d.ts.map +1 -1
- package/dist/components/chart-bar-horizontal.js +14 -5
- package/dist/components/chart-bar-multiple.d.ts +1 -1
- package/dist/components/chart-bar-multiple.d.ts.map +1 -1
- package/dist/components/chart-bar-multiple.js +3 -3
- package/dist/components/chart-bar-stacked.d.ts +1 -1
- package/dist/components/chart-bar-stacked.d.ts.map +1 -1
- package/dist/components/chart-bar-stacked.js +3 -3
- package/dist/components/chart-card.d.ts +17 -6
- package/dist/components/chart-card.d.ts.map +1 -1
- package/dist/components/chart-card.js +11 -4
- package/dist/components/chart-date-range-control.d.ts +18 -9
- package/dist/components/chart-date-range-control.d.ts.map +1 -1
- package/dist/components/chart-date-range-control.js +43 -47
- package/dist/components/chart-sparkline.d.ts +4 -3
- package/dist/components/chart-sparkline.d.ts.map +1 -1
- package/dist/components/chart-sparkline.js +6 -5
- package/dist/components/check-counts.d.ts +44 -0
- package/dist/components/check-counts.d.ts.map +1 -0
- package/dist/components/check-counts.js +51 -0
- package/dist/components/checkbox.d.ts +39 -11
- package/dist/components/checkbox.d.ts.map +1 -1
- package/dist/components/checkbox.js +38 -11
- package/dist/components/choicebox.d.ts +96 -0
- package/dist/components/choicebox.d.ts.map +1 -0
- package/dist/components/choicebox.js +113 -0
- package/dist/components/clearable-input.d.ts +57 -0
- package/dist/components/clearable-input.d.ts.map +1 -0
- package/dist/components/clearable-input.js +58 -0
- package/dist/components/code-block.d.ts +77 -17
- package/dist/components/code-block.d.ts.map +1 -1
- package/dist/components/code-block.js +85 -15
- package/dist/components/collapsible.d.ts +27 -10
- package/dist/components/collapsible.d.ts.map +1 -1
- package/dist/components/collapsible.js +24 -9
- package/dist/components/collection-filters.d.ts +3 -1
- package/dist/components/collection-filters.d.ts.map +1 -1
- package/dist/components/collection-filters.js +7 -9
- package/dist/components/collection-page.d.ts +31 -10
- package/dist/components/collection-page.d.ts.map +1 -1
- package/dist/components/collection-page.js +14 -13
- package/dist/components/collection-search.d.ts +32 -10
- package/dist/components/collection-search.d.ts.map +1 -1
- package/dist/components/collection-search.js +24 -13
- package/dist/components/collection-sort.d.ts.map +1 -1
- package/dist/components/collection-sort.js +2 -2
- package/dist/components/collection-toolbar.d.ts +5 -2
- package/dist/components/collection-toolbar.d.ts.map +1 -1
- package/dist/components/collection-toolbar.js +7 -4
- package/dist/components/combobox.d.ts +97 -22
- package/dist/components/combobox.d.ts.map +1 -1
- package/dist/components/combobox.js +80 -28
- package/dist/components/command.d.ts +34 -21
- package/dist/components/command.d.ts.map +1 -1
- package/dist/components/command.js +33 -25
- package/dist/components/confirm-dialog.d.ts +23 -6
- package/dist/components/confirm-dialog.d.ts.map +1 -1
- package/dist/components/confirm-dialog.js +32 -13
- package/dist/components/context-menu.d.ts +14 -10
- package/dist/components/context-menu.d.ts.map +1 -1
- package/dist/components/context-menu.js +17 -12
- package/dist/components/copy-button.d.ts +5 -2
- package/dist/components/copy-button.d.ts.map +1 -1
- package/dist/components/copy-button.js +16 -8
- package/dist/components/data-table.d.ts +120 -54
- package/dist/components/data-table.d.ts.map +1 -1
- package/dist/components/data-table.js +163 -92
- package/dist/components/desktop-shell.d.ts +4 -2
- package/dist/components/desktop-shell.d.ts.map +1 -1
- package/dist/components/desktop-shell.js +3 -3
- package/dist/components/dialog.d.ts +63 -24
- package/dist/components/dialog.d.ts.map +1 -1
- package/dist/components/dialog.js +52 -31
- package/dist/components/disclosure-row.d.ts +1 -2
- package/dist/components/disclosure-row.d.ts.map +1 -1
- package/dist/components/disclosure-row.js +1 -2
- package/dist/components/disclosure.d.ts +1 -1
- package/dist/components/disclosure.js +1 -1
- package/dist/components/drawer.d.ts +33 -12
- package/dist/components/drawer.d.ts.map +1 -1
- package/dist/components/drawer.js +47 -35
- package/dist/components/dropdown-menu.d.ts +59 -14
- package/dist/components/dropdown-menu.d.ts.map +1 -1
- package/dist/components/dropdown-menu.js +58 -26
- package/dist/components/empty-state.d.ts +35 -12
- package/dist/components/empty-state.d.ts.map +1 -1
- package/dist/components/empty-state.js +35 -17
- package/dist/components/entry-scene.d.ts +4 -4
- package/dist/components/entry-scene.d.ts.map +1 -1
- package/dist/components/entry-scene.js +2 -2
- package/dist/components/field.d.ts +44 -14
- package/dist/components/field.d.ts.map +1 -1
- package/dist/components/field.js +49 -20
- package/dist/components/file-diff.d.ts.map +1 -1
- package/dist/components/file-diff.js +3 -4
- package/dist/components/form-dialog.d.ts +7 -7
- package/dist/components/form-dialog.d.ts.map +1 -1
- package/dist/components/form-dialog.js +13 -11
- package/dist/components/form-drawer.d.ts +10 -7
- package/dist/components/form-drawer.d.ts.map +1 -1
- package/dist/components/form-drawer.js +11 -10
- package/dist/components/gauge.d.ts +64 -0
- package/dist/components/gauge.d.ts.map +1 -0
- package/dist/components/gauge.js +73 -0
- package/dist/components/hover-card.d.ts +72 -14
- package/dist/components/hover-card.d.ts.map +1 -1
- package/dist/components/hover-card.js +51 -17
- package/dist/components/identity-mark.d.ts +8 -1
- package/dist/components/identity-mark.d.ts.map +1 -1
- package/dist/components/identity-mark.js +31 -5
- package/dist/components/input-group.d.ts +44 -21
- package/dist/components/input-group.d.ts.map +1 -1
- package/dist/components/input-group.js +74 -27
- package/dist/components/input.d.ts +64 -12
- package/dist/components/input.d.ts.map +1 -1
- package/dist/components/input.js +51 -15
- package/dist/components/item.d.ts +37 -15
- package/dist/components/item.d.ts.map +1 -1
- package/dist/components/item.js +41 -22
- package/dist/components/kbd.d.ts +49 -13
- package/dist/components/kbd.d.ts.map +1 -1
- package/dist/components/kbd.js +115 -16
- package/dist/components/kpi-card.d.ts +12 -4
- package/dist/components/kpi-card.d.ts.map +1 -1
- package/dist/components/kpi-card.js +13 -4
- package/dist/components/label.d.ts +17 -10
- package/dist/components/label.d.ts.map +1 -1
- package/dist/components/label.js +18 -11
- package/dist/components/library-shelf.d.ts +6 -6
- package/dist/components/library-shelf.d.ts.map +1 -1
- package/dist/components/library-shelf.js +5 -5
- package/dist/components/load-more-button.d.ts +35 -0
- package/dist/components/load-more-button.d.ts.map +1 -0
- package/dist/components/load-more-button.js +26 -0
- package/dist/components/menu-choice-row.d.ts +6 -8
- package/dist/components/menu-choice-row.d.ts.map +1 -1
- package/dist/components/menu-choice-row.js +8 -8
- package/dist/components/message-notice.d.ts +8 -13
- package/dist/components/message-notice.d.ts.map +1 -1
- package/dist/components/message-notice.js +25 -22
- package/dist/components/middle-truncate.d.ts +33 -0
- package/dist/components/middle-truncate.d.ts.map +1 -0
- package/dist/components/middle-truncate.js +72 -0
- package/dist/components/multi-select.d.ts +94 -0
- package/dist/components/multi-select.d.ts.map +1 -0
- package/dist/components/multi-select.js +132 -0
- package/dist/components/native-select.d.ts +37 -13
- package/dist/components/native-select.d.ts.map +1 -1
- package/dist/components/native-select.js +27 -11
- package/dist/components/notice-banner.d.ts +17 -10
- package/dist/components/notice-banner.d.ts.map +1 -1
- package/dist/components/notice-banner.js +12 -11
- package/dist/components/numbered-steps.d.ts +10 -4
- package/dist/components/numbered-steps.d.ts.map +1 -1
- package/dist/components/numbered-steps.js +9 -7
- package/dist/components/object-page.d.ts +40 -14
- package/dist/components/object-page.d.ts.map +1 -1
- package/dist/components/object-page.js +12 -10
- package/dist/components/object-workspace.d.ts +29 -10
- package/dist/components/object-workspace.d.ts.map +1 -1
- package/dist/components/object-workspace.js +18 -8
- package/dist/components/overview-page.d.ts +2 -2
- package/dist/components/overview-page.d.ts.map +1 -1
- package/dist/components/overview-page.js +8 -7
- package/dist/components/page-actions.d.ts +28 -8
- package/dist/components/page-actions.d.ts.map +1 -1
- package/dist/components/page-actions.js +22 -25
- package/dist/components/page-header.d.ts +11 -4
- package/dist/components/page-header.d.ts.map +1 -1
- package/dist/components/page-header.js +10 -5
- package/dist/components/pending-label.d.ts +6 -5
- package/dist/components/pending-label.d.ts.map +1 -1
- package/dist/components/pending-label.js +14 -6
- package/dist/components/picture-label.d.ts +2 -2
- package/dist/components/picture-label.d.ts.map +1 -1
- package/dist/components/picture-label.js +3 -3
- package/dist/components/portal-sidebar-frame.d.ts +9 -21
- package/dist/components/portal-sidebar-frame.d.ts.map +1 -1
- package/dist/components/portal-sidebar-frame.js +13 -27
- package/dist/components/progress-checklist.d.ts +46 -0
- package/dist/components/progress-checklist.d.ts.map +1 -0
- package/dist/components/progress-checklist.js +46 -0
- package/dist/components/progress.d.ts +48 -8
- package/dist/components/progress.d.ts.map +1 -1
- package/dist/components/progress.js +92 -16
- package/dist/components/prose.d.ts +19 -0
- package/dist/components/prose.d.ts.map +1 -0
- package/dist/components/prose.js +29 -0
- package/dist/components/radio-group.d.ts +51 -12
- package/dist/components/radio-group.d.ts.map +1 -1
- package/dist/components/radio-group.js +42 -12
- package/dist/components/reading-column.js +1 -1
- package/dist/components/record-identity.d.ts +6 -5
- package/dist/components/record-identity.d.ts.map +1 -1
- package/dist/components/record-identity.js +12 -3
- package/dist/components/record-list.d.ts +117 -27
- package/dist/components/record-list.d.ts.map +1 -1
- package/dist/components/record-list.js +185 -55
- package/dist/components/record-time.d.ts +20 -7
- package/dist/components/record-time.d.ts.map +1 -1
- package/dist/components/record-time.js +38 -19
- package/dist/components/resizable.d.ts +7 -5
- package/dist/components/resizable.d.ts.map +1 -1
- package/dist/components/resizable.js +6 -6
- package/dist/components/scope-switcher.d.ts +2 -0
- package/dist/components/scope-switcher.d.ts.map +1 -1
- package/dist/components/scope-switcher.js +2 -2
- package/dist/components/scroll-area.d.ts +47 -11
- package/dist/components/scroll-area.d.ts.map +1 -1
- package/dist/components/scroll-area.js +72 -14
- package/dist/components/segmented-control.d.ts +82 -0
- package/dist/components/segmented-control.d.ts.map +1 -0
- package/dist/components/segmented-control.js +90 -0
- package/dist/components/select.d.ts +55 -15
- package/dist/components/select.d.ts.map +1 -1
- package/dist/components/select.js +62 -19
- package/dist/components/separator.d.ts +12 -5
- package/dist/components/separator.d.ts.map +1 -1
- package/dist/components/separator.js +11 -6
- package/dist/components/settings-facts.d.ts +34 -14
- package/dist/components/settings-facts.d.ts.map +1 -1
- package/dist/components/settings-facts.js +21 -12
- package/dist/components/settings-page.d.ts +4 -4
- package/dist/components/settings-page.js +5 -5
- package/dist/components/settings-section.d.ts +160 -34
- package/dist/components/settings-section.d.ts.map +1 -1
- package/dist/components/settings-section.js +92 -39
- package/dist/components/sheet.d.ts +47 -16
- package/dist/components/sheet.d.ts.map +1 -1
- package/dist/components/sheet.js +40 -19
- package/dist/components/sidebar-sections.d.ts +16 -12
- package/dist/components/sidebar-sections.d.ts.map +1 -1
- package/dist/components/sidebar-sections.js +30 -15
- package/dist/components/sidebar.d.ts +117 -21
- package/dist/components/sidebar.d.ts.map +1 -1
- package/dist/components/sidebar.js +180 -55
- package/dist/components/skeleton.d.ts +54 -8
- package/dist/components/skeleton.d.ts.map +1 -1
- package/dist/components/skeleton.js +44 -9
- package/dist/components/slider.d.ts +53 -11
- package/dist/components/slider.d.ts.map +1 -1
- package/dist/components/slider.js +71 -17
- package/dist/components/snippet.d.ts +57 -0
- package/dist/components/snippet.d.ts.map +1 -0
- package/dist/components/snippet.js +60 -0
- package/dist/components/sonner.d.ts +13 -14
- package/dist/components/sonner.d.ts.map +1 -1
- package/dist/components/sonner.js +25 -22
- package/dist/components/status-badge.d.ts +37 -11
- package/dist/components/status-badge.d.ts.map +1 -1
- package/dist/components/status-badge.js +63 -15
- package/dist/components/status-dot.d.ts +42 -11
- package/dist/components/status-dot.d.ts.map +1 -1
- package/dist/components/status-dot.js +40 -11
- package/dist/components/switch.d.ts +43 -12
- package/dist/components/switch.d.ts.map +1 -1
- package/dist/components/switch.js +42 -12
- package/dist/components/table-card.d.ts +21 -12
- package/dist/components/table-card.d.ts.map +1 -1
- package/dist/components/table-card.js +17 -9
- package/dist/components/table-layouts.d.ts +40 -8
- package/dist/components/table-layouts.d.ts.map +1 -1
- package/dist/components/table-layouts.js +52 -8
- package/dist/components/table-value.d.ts +4 -3
- package/dist/components/table-value.d.ts.map +1 -1
- package/dist/components/table-value.js +6 -5
- package/dist/components/table.d.ts +62 -25
- package/dist/components/table.d.ts.map +1 -1
- package/dist/components/table.js +62 -26
- package/dist/components/tabs.d.ts +86 -17
- package/dist/components/tabs.d.ts.map +1 -1
- package/dist/components/tabs.js +93 -22
- package/dist/components/text-link.d.ts +4 -1
- package/dist/components/text-link.d.ts.map +1 -1
- package/dist/components/text-link.js +4 -1
- package/dist/components/text-with-copy-button.d.ts +30 -0
- package/dist/components/text-with-copy-button.d.ts.map +1 -0
- package/dist/components/text-with-copy-button.js +32 -0
- package/dist/components/textarea.d.ts +40 -10
- package/dist/components/textarea.d.ts.map +1 -1
- package/dist/components/textarea.js +50 -11
- package/dist/components/theme-mode-switcher.d.ts +20 -3
- package/dist/components/theme-mode-switcher.d.ts.map +1 -1
- package/dist/components/theme-mode-switcher.js +23 -6
- package/dist/components/toggle-group.d.ts +28 -8
- package/dist/components/toggle-group.d.ts.map +1 -1
- package/dist/components/toggle-group.js +12 -6
- package/dist/components/toggle.d.ts +6 -3
- package/dist/components/toggle.d.ts.map +1 -1
- package/dist/components/toggle.js +10 -7
- package/dist/components/tooltip.d.ts +43 -12
- package/dist/components/tooltip.d.ts.map +1 -1
- package/dist/components/tooltip.js +45 -16
- package/dist/components/trend-badge.js +1 -1
- package/dist/components/update-card.js +1 -1
- package/dist/eslint/index.js +82 -0
- package/dist/eslint/rules/badge-is-static-label.js +93 -0
- package/dist/eslint/rules/button-icon-slot.js +102 -0
- package/dist/eslint/rules/button-link-for-navigation.js +146 -0
- package/dist/eslint/rules/button-no-aria-label-with-text.js +75 -0
- package/dist/eslint/rules/button-type-roles-only-in-buttons.js +83 -0
- package/dist/eslint/rules/choice-control-has-a-name.js +98 -0
- package/dist/eslint/rules/choice-group-in-fieldset.js +86 -0
- package/dist/eslint/rules/command-shortcut-single-owner.js +118 -0
- package/dist/eslint/rules/confirm-dialog-words.js +63 -0
- package/dist/eslint/rules/data-table-one-unsized-column.js +96 -0
- package/dist/eslint/rules/destructive-action-placement.js +69 -0
- package/dist/eslint/rules/disabled-choice-says-why.js +71 -0
- package/dist/eslint/rules/ellipsis-opens-a-dialog.js +110 -0
- package/dist/eslint/rules/input-group-owners.js +155 -0
- package/dist/eslint/rules/kbd-children-no-modifier-text.js +128 -0
- package/dist/eslint/rules/literal-text.js +41 -0
- package/dist/eslint/rules/middle-truncate-placement.js +69 -0
- package/dist/eslint/rules/no-bare-button-label.js +55 -0
- package/dist/eslint/rules/no-control-in-read-only-surface.js +106 -0
- package/dist/eslint/rules/no-hand-built-busy.js +104 -0
- package/dist/eslint/rules/no-hand-built-theme-picker.js +144 -0
- package/dist/eslint/rules/no-hand-built-tile.js +41 -0
- package/dist/eslint/rules/no-hand-formatted-date.js +87 -0
- package/dist/eslint/rules/no-hand-stacked-avatars.js +67 -0
- package/dist/eslint/rules/no-nested-collapse.js +60 -0
- package/dist/eslint/rules/no-search-in-form.js +47 -0
- package/dist/eslint/rules/no-shadcn-appearance-override.js +2 -16
- package/dist/eslint/rules/no-shell-prompt-in-snippet.js +74 -0
- package/dist/eslint/rules/no-stock-error-words.js +56 -0
- package/dist/eslint/rules/no-tooltip-around-labelled-field.js +72 -0
- package/dist/eslint/rules/no-weight-class-on-strong-in-type-role.js +57 -0
- package/dist/eslint/rules/one-submenu-level.js +43 -0
- package/dist/eslint/rules/one-toast-per-flow.js +91 -0
- package/dist/eslint/rules/option-count.js +167 -0
- package/dist/eslint/rules/page-command-link-not-render.js +43 -0
- package/dist/eslint/rules/progress-needs-name.js +57 -0
- package/dist/eslint/rules/settings-limit-in-footer.js +94 -0
- package/dist/eslint/rules/skeleton-in-region.js +80 -0
- package/dist/eslint/rules/sortable-heading-uses-sort.js +79 -0
- package/dist/eslint/rules/table-cell-inset-owner.js +107 -0
- package/dist/eslint/rules/tabs-selection-is-controlled.js +47 -0
- package/dist/eslint/rules/tooltip-only-arrow.js +38 -0
- package/dist/eslint/rules/tooltip-trigger-accessible-name.js +114 -0
- package/dist/eslint/strict-design-system.js +21 -7
- package/dist/index.d.ts +13 -13
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +12 -13
- package/dist/internal/assistant-ui/attachment.d.ts.map +1 -1
- package/dist/internal/assistant-ui/attachment.js +2 -2
- package/dist/internal/assistant-ui/reasoning.d.ts +1 -1
- package/dist/internal/assistant-ui/reasoning.d.ts.map +1 -1
- package/dist/internal/assistant-ui/tool-fallback.js +1 -1
- package/dist/internal/assistant-ui/tool-group.d.ts +1 -1
- package/dist/internal/assistant-ui/tool-group.d.ts.map +1 -1
- package/dist/internal/assistant-ui/tooltip-icon-button.d.ts +2 -3
- package/dist/internal/assistant-ui/tooltip-icon-button.d.ts.map +1 -1
- package/dist/internal/assistant-ui/tooltip-icon-button.js +1 -1
- package/dist/internal/catalog-list.js +2 -2
- package/dist/internal/collection-note.d.ts +23 -0
- package/dist/internal/collection-note.d.ts.map +1 -0
- package/dist/internal/collection-note.js +17 -0
- package/dist/internal/collection-rail.d.ts +57 -0
- package/dist/internal/collection-rail.d.ts.map +1 -0
- package/dist/internal/collection-rail.js +33 -0
- package/dist/internal/company-logo.d.ts +18 -0
- package/dist/internal/company-logo.d.ts.map +1 -0
- package/dist/internal/company-logo.js +14 -0
- package/dist/internal/control-name.d.ts +12 -0
- package/dist/internal/control-name.d.ts.map +1 -0
- package/dist/internal/control-name.js +1 -0
- package/dist/internal/diff-line.d.ts +9 -0
- package/dist/internal/diff-line.d.ts.map +1 -0
- package/dist/internal/diff-line.js +8 -0
- package/dist/internal/empty.d.ts +8 -4
- package/dist/internal/empty.d.ts.map +1 -1
- package/dist/internal/empty.js +14 -8
- package/dist/internal/field-frame.d.ts +33 -0
- package/dist/internal/field-frame.d.ts.map +1 -0
- package/dist/internal/field-frame.js +20 -0
- package/dist/internal/final-focus.d.ts +8 -0
- package/dist/internal/final-focus.d.ts.map +1 -0
- package/dist/internal/final-focus.js +10 -0
- package/dist/internal/footer-strip.d.ts.map +1 -1
- package/dist/internal/footer-strip.js +3 -1
- package/dist/internal/form-submit.d.ts +9 -5
- package/dist/internal/form-submit.d.ts.map +1 -1
- package/dist/internal/form-submit.js +31 -2
- package/dist/internal/input-box.d.ts +26 -0
- package/dist/internal/input-box.d.ts.map +1 -0
- package/dist/internal/input-box.js +59 -0
- package/dist/internal/menu-surface.d.ts +10 -3
- package/dist/internal/menu-surface.d.ts.map +1 -1
- package/dist/internal/menu-surface.js +10 -3
- package/dist/internal/notice.d.ts +25 -0
- package/dist/internal/notice.d.ts.map +1 -0
- package/dist/internal/notice.js +33 -0
- package/dist/internal/overlay-stem.d.ts +5 -0
- package/dist/internal/overlay-stem.d.ts.map +1 -0
- package/dist/internal/overlay-stem.js +7 -0
- package/dist/internal/phone-sheet.d.ts +4 -0
- package/dist/internal/phone-sheet.d.ts.map +1 -0
- package/dist/internal/phone-sheet.js +2 -0
- package/dist/internal/present-content.d.ts +3 -0
- package/dist/internal/present-content.d.ts.map +1 -0
- package/dist/internal/present-content.js +1 -0
- package/dist/internal/record-menu-items.d.ts +4 -3
- package/dist/internal/record-menu-items.d.ts.map +1 -1
- package/dist/internal/record-menu-items.js +21 -6
- package/dist/internal/settings-save.d.ts +9 -2
- package/dist/internal/settings-save.d.ts.map +1 -1
- package/dist/internal/settings-save.js +9 -6
- package/dist/internal/table-compact-line.d.ts +38 -0
- package/dist/internal/table-compact-line.d.ts.map +1 -0
- package/dist/internal/table-compact-line.js +35 -0
- package/dist/internal/title-when-cut.d.ts +8 -0
- package/dist/internal/title-when-cut.d.ts.map +1 -0
- package/dist/internal/title-when-cut.js +22 -0
- package/dist/internal/unsaved-guard.d.ts +18 -0
- package/dist/internal/unsaved-guard.d.ts.map +1 -0
- package/dist/internal/unsaved-guard.js +31 -0
- package/dist/lib/merge-tokens.generated.js +2 -2
- package/dist/showcase/foundations.d.ts.map +1 -1
- package/dist/showcase/foundations.js +10 -2
- package/dist/showcase/specimens/actions.d.ts +2 -0
- package/dist/showcase/specimens/actions.d.ts.map +1 -1
- package/dist/showcase/specimens/actions.js +30 -5
- package/dist/showcase/specimens/charts.d.ts.map +1 -1
- package/dist/showcase/specimens/charts.js +22 -13
- package/dist/showcase/specimens/choices.d.ts +14 -3
- package/dist/showcase/specimens/choices.d.ts.map +1 -1
- package/dist/showcase/specimens/choices.js +93 -13
- package/dist/showcase/specimens/compositions.d.ts.map +1 -1
- package/dist/showcase/specimens/compositions.js +136 -23
- package/dist/showcase/specimens/data.d.ts +12 -7
- package/dist/showcase/specimens/data.d.ts.map +1 -1
- package/dist/showcase/specimens/data.js +139 -35
- package/dist/showcase/specimens/feedback.d.ts +2 -0
- package/dist/showcase/specimens/feedback.d.ts.map +1 -1
- package/dist/showcase/specimens/feedback.js +39 -15
- package/dist/showcase/specimens/index.d.ts +20 -12
- package/dist/showcase/specimens/index.d.ts.map +1 -1
- package/dist/showcase/specimens/inputs.d.ts +4 -2
- package/dist/showcase/specimens/inputs.d.ts.map +1 -1
- package/dist/showcase/specimens/inputs.js +62 -19
- package/dist/showcase/specimens/menus.d.ts +0 -1
- package/dist/showcase/specimens/menus.d.ts.map +1 -1
- package/dist/showcase/specimens/menus.js +47 -18
- package/dist/showcase/specimens/navigation.d.ts +6 -4
- package/dist/showcase/specimens/navigation.d.ts.map +1 -1
- package/dist/showcase/specimens/navigation.js +61 -32
- package/dist/showcase/specimens/other.d.ts +1 -3
- package/dist/showcase/specimens/other.d.ts.map +1 -1
- package/dist/showcase/specimens/other.js +17 -13
- package/dist/showcase/specimens/status.d.ts +4 -1
- package/dist/showcase/specimens/status.d.ts.map +1 -1
- package/dist/showcase/specimens/status.js +64 -11
- package/dist/showcase/usage.generated.d.ts +1 -1
- package/dist/showcase/usage.generated.d.ts.map +1 -1
- package/dist/showcase/usage.generated.js +637 -549
- package/dist/standalone/index.js +1 -1
- package/dist/styles/components.css +13 -13
- package/dist/styles/globals.css +25 -0
- package/package.json +2 -3
- package/dist/components/approval-row.d.ts +0 -34
- package/dist/components/approval-row.d.ts.map +0 -1
- package/dist/components/approval-row.js +0 -27
- package/dist/components/channel-view.d.ts +0 -112
- package/dist/components/channel-view.d.ts.map +0 -1
- package/dist/components/channel-view.js +0 -84
- package/dist/components/dashboard-shell.d.ts +0 -51
- package/dist/components/dashboard-shell.d.ts.map +0 -1
- package/dist/components/dashboard-shell.js +0 -89
- package/dist/components/direction.d.ts +0 -2
- package/dist/components/direction.d.ts.map +0 -1
- package/dist/components/direction.js +0 -1
- package/dist/components/expandable-block.d.ts +0 -20
- package/dist/components/expandable-block.d.ts.map +0 -1
- package/dist/components/expandable-block.js +0 -32
- package/dist/components/form.d.ts +0 -42
- package/dist/components/form.d.ts.map +0 -1
- package/dist/components/form.js +0 -91
- package/dist/components/label-system.d.ts +0 -17
- package/dist/components/label-system.d.ts.map +0 -1
- package/dist/components/label-system.js +0 -21
- package/dist/components/memory-item.d.ts +0 -21
- package/dist/components/memory-item.d.ts.map +0 -1
- package/dist/components/memory-item.js +0 -18
- package/dist/components/menubar.d.ts +0 -43
- package/dist/components/menubar.d.ts.map +0 -1
- package/dist/components/menubar.js +0 -69
- package/dist/components/navigation-menu.d.ts +0 -26
- package/dist/components/navigation-menu.d.ts.map +0 -1
- package/dist/components/navigation-menu.js +0 -45
- package/dist/components/pagination.d.ts +0 -33
- package/dist/components/pagination.d.ts.map +0 -1
- package/dist/components/pagination.js +0 -41
- package/dist/components/plugin-slot-boundary.d.ts +0 -42
- package/dist/components/plugin-slot-boundary.d.ts.map +0 -1
- package/dist/components/plugin-slot-boundary.js +0 -41
- package/dist/components/status-row.d.ts +0 -32
- package/dist/components/status-row.d.ts.map +0 -1
- package/dist/components/status-row.js +0 -35
|
@@ -1,19 +1,20 @@
|
|
|
1
|
-
import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
|
|
1
|
+
import { jsx as _jsx, Fragment as _Fragment, jsxs as _jsxs } from "react/jsx-runtime";
|
|
2
2
|
import * as React from "react";
|
|
3
3
|
import { Menu as MenuPrimitive } from "@base-ui/react/menu";
|
|
4
|
+
import { PendingLabel } from "./pending-label.js";
|
|
4
5
|
import { cn } from "../lib/utils.js";
|
|
5
6
|
import { anchoredOverlayMotion } from "../lib/motion.js";
|
|
6
|
-
import { menuSurface } from "../internal/menu-surface.js";
|
|
7
|
-
import { ChevronRightIcon, CheckIcon } from "lucide-react";
|
|
7
|
+
import { menuRow, menuSurface } from "../internal/menu-surface.js";
|
|
8
|
+
import { ChevronRightIcon, CheckIcon, LockIcon } from "lucide-react";
|
|
8
9
|
/**
|
|
9
|
-
* A menu that floats from a visible trigger, built from its parts: the surface, labelled groups, commands, choices and dividers.
|
|
10
|
+
* A menu that floats from a visible trigger, built from its parts: the surface, labelled groups, commands, links, choices and dividers.
|
|
10
11
|
*
|
|
11
12
|
* @family Menus
|
|
12
|
-
* @when
|
|
13
|
-
* @instead A record's or a page's commands are `ActionMenu` or `PageActions`' menu, from data. The account's rows are `AccountMenu`. A value to choose in a form is `Select
|
|
14
|
-
* @behaviour
|
|
15
|
-
* @words
|
|
16
|
-
* @access `role="menu"
|
|
13
|
+
* @when "Use Menu for a discoverable trigger that opens a list of actions on a single resource (a dots menu on a row, a dropdown on a primary entity)." (https://vercel.com/geist/menu) Ours: a menu no composition draws: a column chooser, a sort, a product's own choices in a submenu.
|
|
14
|
+
* @instead "For right-click or long-press on a row, use `ContextMenu`. For global commands behind `⌘K`, use `CommandMenu`. For two related primary actions, use a split button rather than burying the secondary action." (https://vercel.com/geist/menu) Ours: those are `ContextMenu` and `CommandDialog`; two related primary actions stand side by side as buttons. A record's or a page's commands are `ActionMenu` or `PageActions`' menu, from data. The account's rows are `AccountMenu`. A value to choose in a form is `Select`.
|
|
15
|
+
* @behaviour "Dropdown menu opened via button. Supports typeahead and keyboard navigation." (https://vercel.com/geist/menu) "Open on click, not hover; hover-open menus collide with screen readers and trackpad scrolls." (https://vercel.com/geist/menu) "Position auto-flips based on window bounds; don’t hardcode a side that clips on narrow viewports." (https://vercel.com/geist/menu) "Close on item activation, Escape, and outside-click. Don’t auto-close on a hover-out." (https://vercel.com/geist/menu) "Use `MenuItemLocked` for permission-gated actions so the lock icon and disabled state explain why the row is inert." (https://vercel.com/geist/menu) Ours: that is `locked` with its `reason`. A solid floating surface, 200 px wide at least, 10 px from its trigger. A labelled trigger may end in a chevron; an icon trigger has none. Safe commands come first, each with its icon, groups split by a divider, the destructive command last. Colour sits on that command alone: its text is the error colour at rest and its row takes the soft error fill when highlighted; the panel, the other rows, a section title and the divider stay neutral, and a suffix or lock is muted, 12 px after the label. A command that cannot run stays in place with muted text, never dimmed, and says why in a muted line under its label, which a tap on a phone reads as well as a pointer, since a tooltip opens for the mouse only; a destructive one is muted, not red. Every row is 36 px (44 on touch) with the pointer cursor, or the default one when it cannot be chosen, a row with a reason growing by its line, and a section title is a muted row of that height. The highlight is the row's fill alone: no text inside a row changes colour with it, and a row that cannot be chosen takes no highlight.
|
|
16
|
+
* @words "Item children are Title Case `Verb + Noun` (`Rename Project`, `Duplicate Deployment`). Bare verbs like `Rename` or `Edit` are wrong outside obvious single-object context." (https://vercel.com/geist/menu) "End an item with `…` only when activating it opens a follow-up dialog (`Rename…`, `Transfer to Team…`)." (https://vercel.com/geist/menu) "Group destructive items at the bottom, separated by a divider, and keep the destructive copy as `Verb + Noun` (`Delete Project`, never bare `Delete`)." (https://vercel.com/geist/menu) "Section headers (`MenuSection title`) are Title Case, 1–2 words (`Workspace`, `Recent Projects`)." (https://vercel.com/geist/menu) "Cap a Menu around 10 items. Past that, group with `MenuSection` or move secondary actions to a settings page." (https://vercel.com/geist/menu) Ours: sentence case, not Title Case: "Remove mailbox", never a bare "Delete"; a section title is sentence case too. Italian runs a third longer; rows wrap, never truncate.
|
|
17
|
+
* @access "Up/Down arrows move focus through items, Home/End jump to first/last, Enter or Space activates." (https://vercel.com/geist/menu) "Typeahead jumps to the next item whose label starts with the typed character; keep the visible label first so typeahead matches what the user sees." (https://vercel.com/geist/menu) "Return focus to the trigger on close so keyboard users keep their place in the row." (https://vercel.com/geist/menu) Ours: `role="menu"` named by its trigger, items `menuitem`. Unlike Geist, which skips disabled rows, arrows land on a command that cannot run so its reason is read; it is still never highlighted and never runs. A command's icon is hidden; the value it acts on and its reason are its description. `DropdownMenuCommand` requires its `icon`; a command that cannot run takes `disabledReason`, and one a person may not run is `locked` with its `reason`, so nothing is greyed without saying why.
|
|
17
18
|
*/
|
|
18
19
|
function DropdownMenu({ ...props }) {
|
|
19
20
|
return _jsx(MenuPrimitive.Root, { "data-slot": "dropdown-menu", ...props });
|
|
@@ -24,55 +25,86 @@ function DropdownMenuPortal({ ...props }) {
|
|
|
24
25
|
function DropdownMenuTrigger({ ...props }) {
|
|
25
26
|
return _jsx(MenuPrimitive.Trigger, { "data-slot": "dropdown-menu-trigger", ...props });
|
|
26
27
|
}
|
|
27
|
-
function DropdownMenuContent({ align = "start", alignOffset = 0, density = "comfortable", side = "bottom", sideOffset =
|
|
28
|
+
function DropdownMenuContent({ align = "start", alignOffset = 0, density = "comfortable", side = "bottom", sideOffset = 10, className, ...props }) {
|
|
28
29
|
return (_jsx(MenuPrimitive.Portal, { children: _jsx(MenuPrimitive.Positioner, { className: "isolate z-50 outline-none", align: align, alignOffset: alignOffset, side: side, sideOffset: sideOffset, collisionPadding: 8, children: _jsx(MenuPrimitive.Popup, { "data-slot": "dropdown-menu-content", "data-density": density, className: cn("pointer-events-auto", menuSurface, anchoredOverlayMotion, className), ...props }) }) }));
|
|
29
30
|
}
|
|
30
31
|
function DropdownMenuGroup({ ...props }) {
|
|
31
32
|
return _jsx(MenuPrimitive.Group, { "data-slot": "dropdown-menu-group", ...props });
|
|
32
33
|
}
|
|
33
34
|
function DropdownMenuLabel({ className, inset, ...props }) {
|
|
34
|
-
return (_jsx(MenuPrimitive.GroupLabel, { "data-slot": "dropdown-menu-label", "data-inset": inset, className: cn("px-1.5 py-1 text-xs font-medium text-muted-foreground group-data-[density=comfortable]/menu:px-
|
|
35
|
+
return (_jsx(MenuPrimitive.GroupLabel, { "data-slot": "dropdown-menu-label", "data-inset": inset, className: cn("px-1.5 py-1 text-xs font-medium text-muted-foreground group-data-[density=comfortable]/menu:px-2 group-data-[density=comfortable]/menu:py-2 group-data-[density=comfortable]/menu:text-sm group-data-[density=comfortable]/menu:font-normal data-inset:pl-7", className), ...props }));
|
|
35
36
|
}
|
|
37
|
+
const itemRow = cn(menuRow, "data-[variant=destructive]:text-destructive-soft-foreground data-[variant=destructive]:not-data-disabled:focus:bg-destructive-soft data-[variant=destructive]:*:[svg]:text-destructive-soft-foreground data-[variant=destructive]:data-disabled:text-muted-foreground data-[variant=destructive]:data-disabled:*:[svg]:text-muted-foreground");
|
|
36
38
|
function DropdownMenuItem({ className, iconOnly = false, inset, variant = "default", ...props }) {
|
|
37
|
-
return (_jsx(MenuPrimitive.Item, { "data-slot": "dropdown-menu-item", "data-icon-only": iconOnly || undefined, "data-inset": inset, "data-variant": variant, className: cn(
|
|
39
|
+
return (_jsx(MenuPrimitive.Item, { "data-slot": "dropdown-menu-item", "data-icon-only": iconOnly || undefined, "data-inset": inset, "data-variant": variant, className: cn(itemRow, iconOnly &&
|
|
38
40
|
"size-8 min-w-touch-target shrink-0 justify-center rounded-sm p-0 group-data-[density=comfortable]/menu:p-0 [@media(hover:hover)_and_(pointer:fine)]:min-w-0", className), ...props }));
|
|
39
41
|
}
|
|
42
|
+
/** A row that goes to an address: an anchor that is a menu item, which closes the menu when chosen. */
|
|
43
|
+
function DropdownMenuLink({ className, closeOnClick = true, inset, ...props }) {
|
|
44
|
+
return (_jsx(MenuPrimitive.LinkItem, { "data-slot": "dropdown-menu-link", "data-inset": inset, closeOnClick: closeOnClick, className: cn(itemRow, className), ...props }));
|
|
45
|
+
}
|
|
40
46
|
/**
|
|
41
47
|
* A command in a record's, a page's or the account's menu: its decorative icon
|
|
42
|
-
* first
|
|
43
|
-
*
|
|
44
|
-
*
|
|
48
|
+
* first (at the end, after any `suffix`, with `iconEnd`), then its label, then
|
|
49
|
+
* the value it acts on in mono when it has one, and a `suffix` at the end. The
|
|
50
|
+
* icon takes the row's text colour; at the end it is muted, and red on a
|
|
51
|
+
* destructive command. A command that
|
|
52
|
+
* cannot run now takes `disabledReason` and stays in place with its text muted
|
|
53
|
+
* and the reason under its label, and a destructive one is muted too,
|
|
54
|
+
* not red. A command a person may not run is `locked`: inert, with a lock at
|
|
55
|
+
* the end and the `reason` it is inert, which a locked command must give. A
|
|
56
|
+
* command that starts work is `loading`: it says `loadingLabel` in its label's
|
|
57
|
+
* place, stays focusable and ignores a second press, with no dimming. A
|
|
58
|
+
* `link` is drawn as a link menu item, like `DropdownMenuLink`.
|
|
45
59
|
*/
|
|
46
|
-
function DropdownMenuCommand({ icon, children, className, detail, reason, "aria-label": accessibleName, ...props }) {
|
|
60
|
+
function DropdownMenuCommand({ icon, iconEnd = false, children, className, detail, disabledReason, link, locked, loading, loadingLabel, onClick, reason, suffix, "aria-label": accessibleName, ...props }) {
|
|
61
|
+
const busy = loading === true;
|
|
47
62
|
const id = React.useId();
|
|
48
|
-
const
|
|
63
|
+
const why = locked ? reason : disabledReason;
|
|
64
|
+
const inert = locked === true || disabledReason !== undefined;
|
|
65
|
+
const describedBy = [detail ? `${id}-detail` : null, why ? `${id}-reason` : null]
|
|
49
66
|
.filter(Boolean)
|
|
50
67
|
.join(" ");
|
|
51
|
-
|
|
68
|
+
const end = locked ? (_jsx(LockIcon, {})) : iconEnd ? (_jsxs(_Fragment, { children: [suffix, _jsx("span", { "aria-hidden": "true", className: "flex h-5 items-center justify-center in-data-[variant=destructive]:text-destructive-soft-foreground", children: icon })] })) : (suffix);
|
|
69
|
+
const hasLabelledParts = describedBy !== "" || Boolean(end);
|
|
70
|
+
const row = {
|
|
71
|
+
"aria-label": accessibleName,
|
|
72
|
+
"aria-labelledby": hasLabelledParts && !accessibleName ? `${id}-label` : undefined,
|
|
73
|
+
"aria-busy": busy || undefined,
|
|
74
|
+
"aria-describedby": describedBy || undefined,
|
|
75
|
+
"aria-disabled": busy || inert || undefined,
|
|
76
|
+
closeOnClick: busy ? false : props.closeOnClick,
|
|
77
|
+
className: cn(className, "h-auto w-full min-w-0 items-start justify-start gap-2 text-left font-normal whitespace-normal data-disabled:pointer-events-auto"),
|
|
78
|
+
children: (_jsxs(_Fragment, { children: [iconEnd ? null : (_jsx("span", { "aria-hidden": "true", className: "flex h-5 shrink-0 items-center justify-center text-current", children: icon })), _jsxs("span", { className: "grid min-w-0 flex-1 gap-0.5 break-words", children: [_jsx("span", { id: `${id}-label`, children: loadingLabel === undefined ? (children) : (_jsx(PendingLabel, { pending: busy, pendingLabel: loadingLabel, children: children })) }), detail ? (_jsx("span", { className: "font-label-mono text-label-mono text-muted-foreground", "data-slot": "dropdown-menu-detail", id: `${id}-detail`, children: detail })) : null, why ? (_jsx("span", { className: "text-body-sm text-muted-foreground", "data-slot": "dropdown-menu-reason", id: `${id}-reason`, children: why })) : null] }), end ? (_jsx("span", { "aria-hidden": locked || undefined, className: "ml-auto flex h-5 shrink-0 items-center gap-2 pl-3 text-muted-foreground", "data-slot": "dropdown-menu-suffix", children: end })) : null] })),
|
|
79
|
+
};
|
|
80
|
+
if (link !== undefined && !inert && !busy) {
|
|
81
|
+
return _jsx(DropdownMenuLink, { ...row, label: props.label, render: link });
|
|
82
|
+
}
|
|
83
|
+
return (_jsx(DropdownMenuItem, { "data-slot": "dropdown-menu-item", "data-locked": locked || undefined, ...props, ...row, disabled: inert, onClick: busy ? undefined : onClick }));
|
|
52
84
|
}
|
|
53
85
|
function DropdownMenuSub({ ...props }) {
|
|
54
86
|
return _jsx(MenuPrimitive.SubmenuRoot, { "data-slot": "dropdown-menu-sub", ...props });
|
|
55
87
|
}
|
|
56
88
|
function DropdownMenuSubTrigger({ className, inset, children, ...props }) {
|
|
57
|
-
return (_jsxs(MenuPrimitive.SubmenuTrigger, { "data-slot": "dropdown-menu-sub-trigger", "data-inset": inset, className: cn("
|
|
89
|
+
return (_jsxs(MenuPrimitive.SubmenuTrigger, { "data-slot": "dropdown-menu-sub-trigger", "data-inset": inset, className: cn(menuRow, "data-popup-open:bg-accent data-popup-open:text-accent-foreground data-open:bg-accent data-open:text-accent-foreground", className), ...props, children: [children, _jsx(ChevronRightIcon, { className: "ml-auto" })] }));
|
|
58
90
|
}
|
|
59
|
-
function DropdownMenuSubContent({ align = "start", alignOffset = -
|
|
91
|
+
function DropdownMenuSubContent({ align = "start", alignOffset = -6, side = "right", sideOffset = 0, className, ...props }) {
|
|
60
92
|
return (_jsx(DropdownMenuContent, { "data-slot": "dropdown-menu-sub-content", className: cn("w-auto min-w-24", className), align: align, alignOffset: alignOffset, side: side, sideOffset: sideOffset, ...props }));
|
|
61
93
|
}
|
|
62
94
|
function DropdownMenuCheckboxItem({ className, children, checked, inset, ...props }) {
|
|
63
|
-
return (_jsxs(MenuPrimitive.CheckboxItem, { "data-slot": "dropdown-menu-checkbox-item", "data-inset": inset, className: cn("
|
|
95
|
+
return (_jsxs(MenuPrimitive.CheckboxItem, { "data-slot": "dropdown-menu-checkbox-item", "data-inset": inset, className: cn(menuRow, "pr-8 group-data-[density=comfortable]/menu:pr-8", className), checked: checked, ...props, children: [_jsx("span", { className: "pointer-events-none absolute right-2 flex items-center justify-center", "data-slot": "dropdown-menu-checkbox-item-indicator", children: _jsx(MenuPrimitive.CheckboxItemIndicator, { children: _jsx(CheckIcon, {}) }) }), children] }));
|
|
64
96
|
}
|
|
65
97
|
function DropdownMenuRadioGroup({ ...props }) {
|
|
66
98
|
return _jsx(MenuPrimitive.RadioGroup, { "data-slot": "dropdown-menu-radio-group", ...props });
|
|
67
99
|
}
|
|
68
100
|
function DropdownMenuRadioItem({ className, iconOnly = false, children, inset, ...props }) {
|
|
69
|
-
return (_jsxs(MenuPrimitive.RadioItem, { "data-slot": "dropdown-menu-radio-item", "data-icon-only": iconOnly || undefined, "data-inset": inset, className: cn("
|
|
70
|
-
"size-8 min-w-touch-target justify-center rounded-sm p-0 [@media(hover:hover)_and_(pointer:fine)]:min-w-0 data-checked:bg-muted data-checked:text-foreground", className), ...props, children: [!iconOnly ? (_jsx("span", { className: "pointer-events-none absolute right-2 flex items-center justify-center", "data-slot": "dropdown-menu-radio-item-indicator", children: _jsx(MenuPrimitive.RadioItemIndicator, { children: _jsx(CheckIcon, {}) }) })) : null, children] }));
|
|
101
|
+
return (_jsxs(MenuPrimitive.RadioItem, { "data-slot": "dropdown-menu-radio-item", "data-icon-only": iconOnly || undefined, "data-inset": inset, className: cn(menuRow, "pr-8 group-data-[density=comfortable]/menu:pr-8", iconOnly &&
|
|
102
|
+
"size-8 min-w-touch-target justify-center rounded-sm p-0 group-data-[density=comfortable]/menu:p-0 [@media(hover:hover)_and_(pointer:fine)]:min-w-0 data-checked:bg-muted data-checked:text-foreground", className), ...props, children: [!iconOnly ? (_jsx("span", { className: "pointer-events-none absolute right-2 flex items-center justify-center", "data-slot": "dropdown-menu-radio-item-indicator", children: _jsx(MenuPrimitive.RadioItemIndicator, { children: _jsx(CheckIcon, {}) }) })) : null, children] }));
|
|
71
103
|
}
|
|
72
104
|
function DropdownMenuSeparator({ className, ...props }) {
|
|
73
|
-
return (_jsx(MenuPrimitive.Separator, { "data-slot": "dropdown-menu-separator", className: cn("-mx-1 my-1 h-px bg-border", className), ...props }));
|
|
105
|
+
return (_jsx(MenuPrimitive.Separator, { "data-slot": "dropdown-menu-separator", className: cn("-mx-1.5 my-1.5 h-px bg-border", className), ...props }));
|
|
74
106
|
}
|
|
75
107
|
function DropdownMenuShortcut({ className, ...props }) {
|
|
76
|
-
return (_jsx("span", { "data-slot": "dropdown-menu-shortcut", className: cn("ml-auto text-xs text-muted-foreground
|
|
108
|
+
return (_jsx("span", { "data-slot": "dropdown-menu-shortcut", className: cn("ml-auto text-xs text-muted-foreground", className), ...props }));
|
|
77
109
|
}
|
|
78
|
-
export { DropdownMenu, DropdownMenuPortal, DropdownMenuTrigger, DropdownMenuContent, DropdownMenuGroup, DropdownMenuLabel, DropdownMenuItem, DropdownMenuCommand, DropdownMenuCheckboxItem, DropdownMenuRadioGroup, DropdownMenuRadioItem, DropdownMenuSeparator, DropdownMenuShortcut, DropdownMenuSub, DropdownMenuSubTrigger, DropdownMenuSubContent, };
|
|
110
|
+
export { DropdownMenu, DropdownMenuPortal, DropdownMenuTrigger, DropdownMenuContent, DropdownMenuGroup, DropdownMenuLabel, DropdownMenuItem, DropdownMenuLink, DropdownMenuCommand, DropdownMenuCheckboxItem, DropdownMenuRadioGroup, DropdownMenuRadioItem, DropdownMenuSeparator, DropdownMenuShortcut, DropdownMenuSub, DropdownMenuSubTrigger, DropdownMenuSubContent, };
|
|
@@ -1,10 +1,21 @@
|
|
|
1
|
+
import { type ReactElement } from "react";
|
|
2
|
+
import { type EmptyScope } from "../internal/empty.js";
|
|
3
|
+
import { type CopyButtonProps } from "./copy-button.js";
|
|
1
4
|
import type { EmptyArt } from "./empty-art.js";
|
|
2
5
|
import { type PageCommand } from "./page-actions.js";
|
|
3
6
|
import { type ResolvedMessage } from "./product-message.js";
|
|
7
|
+
/** A link that leaves for the product's documentation: a command drawn from the product's router link, so it carries `link`, never `onClick`. */
|
|
8
|
+
export type EmptyStateDocsLink = Extract<PageCommand, {
|
|
9
|
+
link: ReactElement;
|
|
10
|
+
}>;
|
|
11
|
+
/** The identifier of a system failure, worded by the caller: "Request ID" and the three copy words. */
|
|
12
|
+
export type EmptyStateReference = {
|
|
13
|
+
label: string;
|
|
14
|
+
} & Pick<CopyButtonProps, "value" | "copyLabel" | "copiedLabel" | "copyFailedLabel">;
|
|
4
15
|
export type EmptyStateProps = {
|
|
5
16
|
/** The frame follows the container: page and region take a resting card with its own edge; card takes none. */
|
|
6
|
-
scope?:
|
|
7
|
-
/** The first use
|
|
17
|
+
scope?: EmptyScope;
|
|
18
|
+
/** The title level of a first use, a denial or a failure; 3 inside a titled section. */
|
|
8
19
|
headingLevel?: 2 | 3;
|
|
9
20
|
} & ({
|
|
10
21
|
kind: "firstUse";
|
|
@@ -13,8 +24,8 @@ export type EmptyStateProps = {
|
|
|
13
24
|
picture: EmptyArt;
|
|
14
25
|
/** The action that fills it, only when this viewer can add. */
|
|
15
26
|
action?: PageCommand;
|
|
16
|
-
/**
|
|
17
|
-
|
|
27
|
+
/** Where the product explains this section: the one muted link under the action. */
|
|
28
|
+
docs?: EmptyStateDocsLink;
|
|
18
29
|
} | {
|
|
19
30
|
kind: "nothingYet";
|
|
20
31
|
message: string;
|
|
@@ -22,25 +33,37 @@ export type EmptyStateProps = {
|
|
|
22
33
|
kind: "noResults";
|
|
23
34
|
message: string;
|
|
24
35
|
clear: PageCommand;
|
|
36
|
+
} | {
|
|
37
|
+
kind: "cleared";
|
|
38
|
+
message: string;
|
|
39
|
+
} | {
|
|
40
|
+
kind: "denied";
|
|
41
|
+
title: string;
|
|
42
|
+
description: string;
|
|
43
|
+
/** The way out this viewer has: ask for access, or change plan. */
|
|
44
|
+
action?: PageCommand;
|
|
45
|
+
/** A denial fills the route or its region; one gated tile inside an open page is a `MessageNotice`. */
|
|
46
|
+
scope?: Exclude<EmptyScope, "card" | "line">;
|
|
25
47
|
} | {
|
|
26
48
|
kind: "failed";
|
|
27
49
|
message: ResolvedMessage;
|
|
50
|
+
/** The identifier of a failure on our side, to paste into a support thread. Never on a denial or a wrong value. */
|
|
51
|
+
reference?: EmptyStateReference;
|
|
28
52
|
});
|
|
29
53
|
/** One kind of absence, as a composition takes it: the composition sets its frame. */
|
|
30
54
|
export type EmptyStateKind<K extends EmptyStateProps["kind"]> = Omit<Extract<EmptyStateProps, {
|
|
31
55
|
kind: K;
|
|
32
56
|
}>, "scope" | "headingLevel">;
|
|
33
57
|
/**
|
|
34
|
-
* What a place with nothing in it says:
|
|
35
|
-
*
|
|
36
|
-
* search that found nothing and a read that failed stay quiet.
|
|
58
|
+
* What a place with nothing in it says, by its cause: never created, empty at the moment, nothing
|
|
59
|
+
* matched, finished, not allowed, or failed to load.
|
|
37
60
|
*
|
|
38
61
|
* @family Feedback
|
|
39
|
-
* @when A
|
|
40
|
-
* @instead
|
|
41
|
-
* @behaviour The
|
|
42
|
-
* @words
|
|
43
|
-
* @access
|
|
62
|
+
* @when "Fill spaces when no content has been added yet, or is temporarily empty due to the nature of the feature and should be designed to prevent confusion." (https://vercel.com/geist/empty-state) "A card used to communicate an error state with a title and message." (https://vercel.com/geist/error-card) "Pick the variant by what the user needs: no-results for a filtered list that returned zero rows, blank slate or informational for a resource the user hasn’t created, cleared for completed work, permission for role or tier denials, error for a failed load." (https://vercel.com/geist/empty-state) "Render the permission and tier-denial variants full-page when the user lands on a route they can’t view. Use a `Note` only when one tile inside an otherwise-accessible page is gated." (https://vercel.com/geist/empty-state) "Use the Error component as a block surface when a section or page-level resource failed to load: a panel, a dashboard card, a route boundary." (https://vercel.com/geist/error) Ours: pick the `kind` by the cause. `firstUse` is the blank slate and the informational variant: no record was ever made. `nothingYet`: empty now and it fills by itself. `noResults`: the search or filter found nothing. `cleared`: the work is done. `denied`: this viewer's role or plan does not open it. `failed`: the read failed; it is the Error and the Error Card, a failure inside a card with `scope="card"` and one that stands alone as a block with `page` or `region`. There is no educational kind.
|
|
63
|
+
* @instead "Don’t put critical persistent warnings here. Empty states vanish when the list populates; persistent warnings belong in `Note` or the page header." (https://vercel.com/geist/empty-state) "Pick `toasts.error()` for transient action failures (`Couldn’t save settings. Try again.`) and the `error` prop on `Input` for field-level validation. Don’t replace either with this block." (https://vercel.com/geist/error) Ours: `Note` is `MessageNotice` or `NoticeBanner`, `toasts.error()` is `showMessageToast` with the tone `error`, and the `error` prop on `Input` is `FieldError`. Rows still loading are skeleton rows. A failure of one record's action is that record's row message. One gated tile on an open page is a `MessageNotice`, so `denied` takes `page` or `region`, never `card`.
|
|
64
|
+
* @behaviour "The CTA must be a real `Button` or `Link`, not an `onClick` div, so it joins the tab order and exposes a role." (https://vercel.com/geist/empty-state) "Cap at one primary CTA, plus one secondary when the first action could legitimately be one of two paths (`Import Repository` and `Deploy Template`). Three CTAs is a smell." (https://vercel.com/geist/empty-state) "Don’t auto-launch a tour from the educational variant; pair `Start Tour` with `Skip`." (https://vercel.com/geist/empty-state) "The recovery action must do something concrete: a `Try Again` button when the operation is retry-safe, a named verb (`Reconnect GitHub`, `Update Payment Method`) when it isn’t." (https://vercel.com/geist/error) "Don’t auto-retry in the background; the user came to this surface to decide." (https://vercel.com/geist/error) "For full-page route errors (`error.tsx`), return focus to the `Try Again` button on appearance so a keyboard user can retry without hunting for it." (https://vercel.com/geist/error) "Always pair platform or system errors with a stable identifier (request ID `x-vercel-id`, deployment ID `dpl_…`, run ID, trace ID). Validation and permission denials are user-state, not system, and don’t need an ID." (https://vercel.com/geist/error) "Render the stable ID on a monospace sub-line under a collapsed `<details>` so the user can copy-paste it into a support thread." (https://vercel.com/geist/error) Ours: `firstUse` has the one picture, one action and at most one docs link under it; there is no educational kind, so no tour. A failure shows at most two of its message's actions, Retry first, and moves focus to the first one when it fills a page (`scope="page"`); its `reference` is the collapsed Disclosure holding the monospace identifier and a copy button. A page or a region stands on a resting card, inside a card it takes none, and a collection always passes `card`; a card that lists a few items, as a collection's rail does, passes `line`, where `nothingYet` and `cleared` are one 44 px row like an item: the message at the left, after the cleared check at 16 px. Every kind that carries a title, `failed` excepted, draws it the same way: a mark or picture, a 16 px medium title, one or two muted 14 px lines, 24 px apart, centred, the lines no wider than 340 px. `cleared` and `denied` carry a bordered 54 px tile with a muted icon, never a hue; the picture is `firstUse`'s alone. The action is the filled primary button, as Vercel's Connect draws Create Connector in its empty card; the docs link is muted. A page or a region is padded 48 px above and below and 70 px at the sides (a first use narrows to 24 px under 640 px for its picture). `failed` is the one hued kind: on a page or a region its ground, line, mark and text are all in the error colour, with a 16 px regular title, 16 px padding and 8 px between its parts, and the buttons stay neutral; inside a card it takes the text and mark colour alone, because the card owns the edge and a second one would double it. Required: `firstUse` and `denied` take a title and a line, `firstUse` its picture, `failed` the catalogue message whose title is always drawn.
|
|
65
|
+
* @words "`title` is Title Case (`No Logs Match Your Filter`); `description` is sentence case and adds new information instead of restating the title." (https://vercel.com/geist/empty-state) Ours: a title is sentence case and names what is missing ("No mailboxes yet"), not Title Case; a quiet line is one sentence. "Quote a single typed query verbatim with curly quotes: `No logs match “${query}”. Clear the filter to see all logs.` For multi-facet filters use the plural template `No {Items} Match Your Filters` and suggest widening or clearing." (https://vercel.com/geist/empty-state) "Onboarding bodies name the next action that creates the first item: `Push to your Git repository to create your first one.` Tier-gated bodies follow `{Feature value} with the {Plan} plan.`" (https://vercel.com/geist/empty-state) "Error variant pairs the body with a copyable request ID and a `Try Again` button." (https://vercel.com/geist/empty-state) "CTA labels are Title Case `Verb + Noun`. Never `Get Started`, `Continue`, or `OK`." (https://vercel.com/geist/empty-state) Ours: an action label is sentence case, verb and noun ("Clear filters", "New Agent"), never "Get started" or "OK". "State what happened and what to do next, in that order. Cut apologetic preambles (`Unfortunately`, `Oops`, `We’re sorry`)." (https://vercel.com/geist/error) "Use `Couldn’t` or `Can’t` for user-state errors (`Couldn’t verify your passkey. Try again.`); use `Failed to` for system or infra errors that mirror CLI output (`Build failed. Bundle exceeds 50 MB.`). `Unable to` is banned." (https://vercel.com/geist/error) "Don’t fall back to `Something Went Wrong` as a title; name the resource that failed (`Couldn’t Load Page`, `Couldn’t Load Deployments`)." (https://vercel.com/geist/error) "Never humor an error. Users hitting an error are frustrated; insincere copy makes it worse." (https://vercel.com/geist/error) Ours: a failure is the catalogue's message, never a string of the component's own, and its title names what failed to load.
|
|
66
|
+
* @access "After an async filter change, wrap the region in `aria-live="polite"` so screen readers announce the new state." (https://vercel.com/geist/empty-state) "When the error appears asynchronously (after a failed fetch), wrap the region in `aria-live="polite"` so it’s announced. Reserve `aria-live="assertive"` for true blocking errors that interrupt input." (https://vercel.com/geist/error) Ours: a title, a failure's included, is a heading, level 2 or, inside a titled section, 3. The picture is decorative. A failure's message is a `role="status"` line, polite, never an assertive alert, because it arrives after a read, not in the middle of input. `nothingYet`, `noResults` and `cleared` are plain lines with no live role of their own: the wrapper that stays mounted while rows and absence swap (the `aria-live="polite"` region, such as `SkeletonRegion`) announces them, once.
|
|
44
67
|
*/
|
|
45
68
|
export declare function EmptyState(props: EmptyStateProps): import("react").JSX.Element;
|
|
46
69
|
//# sourceMappingURL=empty-state.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"empty-state.d.ts","sourceRoot":"","sources":["../../src/components/empty-state.tsx"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"empty-state.d.ts","sourceRoot":"","sources":["../../src/components/empty-state.tsx"],"names":[],"mappings":"AAGA,OAAO,EAAE,KAAK,YAAY,EAAqC,MAAM,OAAO,CAAC;AAE7E,OAAO,EAOL,KAAK,UAAU,EAEhB,MAAM,kBAAkB,CAAC;AAC1B,OAAO,EAAc,KAAK,eAAe,EAAE,MAAM,eAAe,CAAC;AAEjE,OAAO,KAAK,EAAE,QAAQ,EAAE,MAAM,aAAa,CAAC;AAC5C,OAAO,EAAE,KAAK,WAAW,EAAqB,MAAM,gBAAgB,CAAC;AACrE,OAAO,EAAmB,KAAK,eAAe,EAAE,MAAM,mBAAmB,CAAC;AAE1E,iJAAiJ;AACjJ,MAAM,MAAM,kBAAkB,GAAG,OAAO,CAAC,WAAW,EAAE;IAAE,IAAI,EAAE,YAAY,CAAA;CAAE,CAAC,CAAC;AAE9E,uGAAuG;AACvG,MAAM,MAAM,mBAAmB,GAAG;IAAE,KAAK,EAAE,MAAM,CAAA;CAAE,GAAG,IAAI,CACxD,eAAe,EACf,OAAO,GAAG,WAAW,GAAG,aAAa,GAAG,iBAAiB,CAC1D,CAAC;AAEF,MAAM,MAAM,eAAe,GAAG;IAC5B,+GAA+G;IAC/G,KAAK,CAAC,EAAE,UAAU,CAAC;IACnB,wFAAwF;IACxF,YAAY,CAAC,EAAE,CAAC,GAAG,CAAC,CAAC;CACtB,GAAG,CACA;IACE,IAAI,EAAE,UAAU,CAAC;IACjB,KAAK,EAAE,MAAM,CAAC;IACd,WAAW,EAAE,MAAM,CAAC;IACpB,OAAO,EAAE,QAAQ,CAAC;IAClB,+DAA+D;IAC/D,MAAM,CAAC,EAAE,WAAW,CAAC;IACrB,oFAAoF;IACpF,IAAI,CAAC,EAAE,kBAAkB,CAAC;CAC3B,GACD;IAAE,IAAI,EAAE,YAAY,CAAC;IAAC,OAAO,EAAE,MAAM,CAAA;CAAE,GACvC;IAAE,IAAI,EAAE,WAAW,CAAC;IAAC,OAAO,EAAE,MAAM,CAAC;IAAC,KAAK,EAAE,WAAW,CAAA;CAAE,GAC1D;IAAE,IAAI,EAAE,SAAS,CAAC;IAAC,OAAO,EAAE,MAAM,CAAA;CAAE,GACpC;IACE,IAAI,EAAE,QAAQ,CAAC;IACf,KAAK,EAAE,MAAM,CAAC;IACd,WAAW,EAAE,MAAM,CAAC;IACpB,mEAAmE;IACnE,MAAM,CAAC,EAAE,WAAW,CAAC;IACrB,uGAAuG;IACvG,KAAK,CAAC,EAAE,OAAO,CAAC,UAAU,EAAE,MAAM,GAAG,MAAM,CAAC,CAAC;CAC9C,GACD;IACE,IAAI,EAAE,QAAQ,CAAC;IACf,OAAO,EAAE,eAAe,CAAC;IACzB,mHAAmH;IACnH,SAAS,CAAC,EAAE,mBAAmB,CAAC;CACjC,CACJ,CAAC;AAEF,sFAAsF;AACtF,MAAM,MAAM,cAAc,CAAC,CAAC,SAAS,eAAe,CAAC,MAAM,CAAC,IAAI,IAAI,CAClE,OAAO,CAAC,eAAe,EAAE;IAAE,IAAI,EAAE,CAAC,CAAA;CAAE,CAAC,EACrC,OAAO,GAAG,cAAc,CACzB,CAAC;AAEF;;;;;;;;;;GAUG;AACH,wBAAgB,UAAU,CAAC,KAAK,EAAE,eAAe,+BAwFhD"}
|
|
@@ -1,36 +1,54 @@
|
|
|
1
1
|
"use client";
|
|
2
2
|
import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
|
|
3
|
-
import {
|
|
3
|
+
import { CheckIcon, LockKeyholeIcon, OctagonAlertIcon } from "lucide-react";
|
|
4
|
+
import { useEffect, useRef } from "react";
|
|
4
5
|
import { Empty, EmptyContent, EmptyDescription, EmptyHeader, EmptyMedia, EmptyPicture, EmptyTitle, } from "../internal/empty.js";
|
|
6
|
+
import { CopyButton } from "./copy-button.js";
|
|
7
|
+
import { Disclosure } from "./disclosure.js";
|
|
5
8
|
import { PageCommandButton } from "./page-actions.js";
|
|
6
9
|
import { bodyBeyondTitle } from "./product-message.js";
|
|
7
10
|
/**
|
|
8
|
-
* What a place with nothing in it says:
|
|
9
|
-
*
|
|
10
|
-
* search that found nothing and a read that failed stay quiet.
|
|
11
|
+
* What a place with nothing in it says, by its cause: never created, empty at the moment, nothing
|
|
12
|
+
* matched, finished, not allowed, or failed to load.
|
|
11
13
|
*
|
|
12
14
|
* @family Feedback
|
|
13
|
-
* @when A
|
|
14
|
-
* @instead
|
|
15
|
-
* @behaviour The
|
|
16
|
-
* @words
|
|
17
|
-
* @access
|
|
15
|
+
* @when "Fill spaces when no content has been added yet, or is temporarily empty due to the nature of the feature and should be designed to prevent confusion." (https://vercel.com/geist/empty-state) "A card used to communicate an error state with a title and message." (https://vercel.com/geist/error-card) "Pick the variant by what the user needs: no-results for a filtered list that returned zero rows, blank slate or informational for a resource the user hasn’t created, cleared for completed work, permission for role or tier denials, error for a failed load." (https://vercel.com/geist/empty-state) "Render the permission and tier-denial variants full-page when the user lands on a route they can’t view. Use a `Note` only when one tile inside an otherwise-accessible page is gated." (https://vercel.com/geist/empty-state) "Use the Error component as a block surface when a section or page-level resource failed to load: a panel, a dashboard card, a route boundary." (https://vercel.com/geist/error) Ours: pick the `kind` by the cause. `firstUse` is the blank slate and the informational variant: no record was ever made. `nothingYet`: empty now and it fills by itself. `noResults`: the search or filter found nothing. `cleared`: the work is done. `denied`: this viewer's role or plan does not open it. `failed`: the read failed; it is the Error and the Error Card, a failure inside a card with `scope="card"` and one that stands alone as a block with `page` or `region`. There is no educational kind.
|
|
16
|
+
* @instead "Don’t put critical persistent warnings here. Empty states vanish when the list populates; persistent warnings belong in `Note` or the page header." (https://vercel.com/geist/empty-state) "Pick `toasts.error()` for transient action failures (`Couldn’t save settings. Try again.`) and the `error` prop on `Input` for field-level validation. Don’t replace either with this block." (https://vercel.com/geist/error) Ours: `Note` is `MessageNotice` or `NoticeBanner`, `toasts.error()` is `showMessageToast` with the tone `error`, and the `error` prop on `Input` is `FieldError`. Rows still loading are skeleton rows. A failure of one record's action is that record's row message. One gated tile on an open page is a `MessageNotice`, so `denied` takes `page` or `region`, never `card`.
|
|
17
|
+
* @behaviour "The CTA must be a real `Button` or `Link`, not an `onClick` div, so it joins the tab order and exposes a role." (https://vercel.com/geist/empty-state) "Cap at one primary CTA, plus one secondary when the first action could legitimately be one of two paths (`Import Repository` and `Deploy Template`). Three CTAs is a smell." (https://vercel.com/geist/empty-state) "Don’t auto-launch a tour from the educational variant; pair `Start Tour` with `Skip`." (https://vercel.com/geist/empty-state) "The recovery action must do something concrete: a `Try Again` button when the operation is retry-safe, a named verb (`Reconnect GitHub`, `Update Payment Method`) when it isn’t." (https://vercel.com/geist/error) "Don’t auto-retry in the background; the user came to this surface to decide." (https://vercel.com/geist/error) "For full-page route errors (`error.tsx`), return focus to the `Try Again` button on appearance so a keyboard user can retry without hunting for it." (https://vercel.com/geist/error) "Always pair platform or system errors with a stable identifier (request ID `x-vercel-id`, deployment ID `dpl_…`, run ID, trace ID). Validation and permission denials are user-state, not system, and don’t need an ID." (https://vercel.com/geist/error) "Render the stable ID on a monospace sub-line under a collapsed `<details>` so the user can copy-paste it into a support thread." (https://vercel.com/geist/error) Ours: `firstUse` has the one picture, one action and at most one docs link under it; there is no educational kind, so no tour. A failure shows at most two of its message's actions, Retry first, and moves focus to the first one when it fills a page (`scope="page"`); its `reference` is the collapsed Disclosure holding the monospace identifier and a copy button. A page or a region stands on a resting card, inside a card it takes none, and a collection always passes `card`; a card that lists a few items, as a collection's rail does, passes `line`, where `nothingYet` and `cleared` are one 44 px row like an item: the message at the left, after the cleared check at 16 px. Every kind that carries a title, `failed` excepted, draws it the same way: a mark or picture, a 16 px medium title, one or two muted 14 px lines, 24 px apart, centred, the lines no wider than 340 px. `cleared` and `denied` carry a bordered 54 px tile with a muted icon, never a hue; the picture is `firstUse`'s alone. The action is the filled primary button, as Vercel's Connect draws Create Connector in its empty card; the docs link is muted. A page or a region is padded 48 px above and below and 70 px at the sides (a first use narrows to 24 px under 640 px for its picture). `failed` is the one hued kind: on a page or a region its ground, line, mark and text are all in the error colour, with a 16 px regular title, 16 px padding and 8 px between its parts, and the buttons stay neutral; inside a card it takes the text and mark colour alone, because the card owns the edge and a second one would double it. Required: `firstUse` and `denied` take a title and a line, `firstUse` its picture, `failed` the catalogue message whose title is always drawn.
|
|
18
|
+
* @words "`title` is Title Case (`No Logs Match Your Filter`); `description` is sentence case and adds new information instead of restating the title." (https://vercel.com/geist/empty-state) Ours: a title is sentence case and names what is missing ("No mailboxes yet"), not Title Case; a quiet line is one sentence. "Quote a single typed query verbatim with curly quotes: `No logs match “${query}”. Clear the filter to see all logs.` For multi-facet filters use the plural template `No {Items} Match Your Filters` and suggest widening or clearing." (https://vercel.com/geist/empty-state) "Onboarding bodies name the next action that creates the first item: `Push to your Git repository to create your first one.` Tier-gated bodies follow `{Feature value} with the {Plan} plan.`" (https://vercel.com/geist/empty-state) "Error variant pairs the body with a copyable request ID and a `Try Again` button." (https://vercel.com/geist/empty-state) "CTA labels are Title Case `Verb + Noun`. Never `Get Started`, `Continue`, or `OK`." (https://vercel.com/geist/empty-state) Ours: an action label is sentence case, verb and noun ("Clear filters", "New Agent"), never "Get started" or "OK". "State what happened and what to do next, in that order. Cut apologetic preambles (`Unfortunately`, `Oops`, `We’re sorry`)." (https://vercel.com/geist/error) "Use `Couldn’t` or `Can’t` for user-state errors (`Couldn’t verify your passkey. Try again.`); use `Failed to` for system or infra errors that mirror CLI output (`Build failed. Bundle exceeds 50 MB.`). `Unable to` is banned." (https://vercel.com/geist/error) "Don’t fall back to `Something Went Wrong` as a title; name the resource that failed (`Couldn’t Load Page`, `Couldn’t Load Deployments`)." (https://vercel.com/geist/error) "Never humor an error. Users hitting an error are frustrated; insincere copy makes it worse." (https://vercel.com/geist/error) Ours: a failure is the catalogue's message, never a string of the component's own, and its title names what failed to load.
|
|
19
|
+
* @access "After an async filter change, wrap the region in `aria-live="polite"` so screen readers announce the new state." (https://vercel.com/geist/empty-state) "When the error appears asynchronously (after a failed fetch), wrap the region in `aria-live="polite"` so it’s announced. Reserve `aria-live="assertive"` for true blocking errors that interrupt input." (https://vercel.com/geist/error) Ours: a title, a failure's included, is a heading, level 2 or, inside a titled section, 3. The picture is decorative. A failure's message is a `role="status"` line, polite, never an assertive alert, because it arrives after a read, not in the middle of input. `nothingYet`, `noResults` and `cleared` are plain lines with no live role of their own: the wrapper that stays mounted while rows and absence swap (the `aria-live="polite"` region, such as `SkeletonRegion`) announces them, once.
|
|
18
20
|
*/
|
|
19
21
|
export function EmptyState(props) {
|
|
20
22
|
const scope = props.scope ?? "region";
|
|
21
23
|
switch (props.kind) {
|
|
22
|
-
case "firstUse":
|
|
23
|
-
|
|
24
|
-
return (_jsxs(Empty, { "data-empty-state": props.kind, scope: scope, children: [_jsxs(EmptyHeader, { children: [_jsx(EmptyPicture, { size: scope === "page" ? "page" : "card", src: props.picture }), _jsxs("div", { className: "grid justify-items-center gap-1", children: [_jsx(EmptyTitle, { children: _jsx(Heading, { children: props.title }) }), _jsx(EmptyDescription, { children: props.description })] })] }), props.action ? (_jsx(EmptyContent, { className: "mt-5", "data-empty-state-action": true, children: _jsx(PageCommandButton, { command: props.action, variant: props.actionVariant ?? "default" }) })) : null] }));
|
|
25
|
-
}
|
|
24
|
+
case "firstUse":
|
|
25
|
+
return (_jsxs(Empty, { className: scope === "card" ? undefined : "px-6 sm:px-17.5", "data-empty-state": props.kind, scope: scope, children: [_jsxs(EmptyHeader, { children: [_jsx(EmptyPicture, { size: scope === "page" ? "page" : "card", src: props.picture }), _jsx(TitleAndLine, { description: props.description, headingLevel: props.headingLevel, title: props.title })] }), props.action || props.docs ? (_jsxs(EmptyContent, { className: "flex-col flex-nowrap gap-6", "data-empty-state-action": true, children: [props.action ? _jsx(PageCommandButton, { command: props.action, variant: "default" }) : null, props.docs ? _jsx(DocsLink, { command: props.docs }) : null] })) : null] }));
|
|
26
26
|
case "nothingYet":
|
|
27
27
|
case "noResults":
|
|
28
|
-
return (_jsxs(Empty, { className: "gap-3", "data-empty-state": props.kind, scope: scope, children: [_jsx(EmptyDescription, { className: "max-w-[40ch]", children: props.message }), props.kind === "noResults" ? (_jsx(EmptyContent, { "data-empty-state-action": true, children: _jsx(PageCommandButton, { command: props.clear, variant: "outline" }) })) : null] }));
|
|
28
|
+
return (_jsxs(Empty, { className: scope === "line" ? undefined : "gap-3 py-7", "data-empty-state": props.kind, scope: scope, children: [_jsx(EmptyDescription, { className: "max-w-[40ch]", children: props.message }), props.kind === "noResults" ? (_jsx(EmptyContent, { "data-empty-state-action": true, children: _jsx(PageCommandButton, { command: props.clear, variant: "outline" }) })) : null] }));
|
|
29
|
+
case "cleared":
|
|
30
|
+
return scope === "line" ? (_jsxs(Empty, { "data-empty-state": props.kind, scope: scope, children: [_jsx(CheckIcon, { "aria-hidden": "true", className: "size-4 shrink-0 text-muted-foreground" }), _jsx(EmptyDescription, { children: props.message })] })) : (_jsx(Empty, { "data-empty-state": props.kind, scope: scope, children: _jsxs(EmptyHeader, { children: [_jsx(EmptyMedia, { variant: "tile", children: _jsx(CheckIcon, { "aria-hidden": "true" }) }), _jsx(EmptyDescription, { children: props.message })] }) }));
|
|
31
|
+
case "denied":
|
|
32
|
+
return (_jsxs(Empty, { "data-empty-state": props.kind, scope: scope, children: [_jsxs(EmptyHeader, { children: [_jsx(EmptyMedia, { variant: "tile", children: _jsx(LockKeyholeIcon, { "aria-hidden": "true" }) }), _jsx(TitleAndLine, { description: props.description, headingLevel: props.headingLevel, title: props.title })] }), props.action ? (_jsx(EmptyContent, { "data-empty-state-action": true, children: _jsx(PageCommandButton, { command: props.action, variant: "default" }) })) : null] }));
|
|
29
33
|
case "failed":
|
|
30
|
-
return (
|
|
34
|
+
return (_jsx(FailedRead, { headingLevel: props.headingLevel, message: props.message, reference: props.reference, scope: scope }));
|
|
31
35
|
}
|
|
32
36
|
}
|
|
33
|
-
function
|
|
37
|
+
function SectionHeading({ children, level }) {
|
|
38
|
+
return level === 3 ? _jsx("h3", { children: children }) : _jsx("h2", { children: children });
|
|
39
|
+
}
|
|
40
|
+
function TitleAndLine({ description, headingLevel, title, }) {
|
|
41
|
+
return (_jsxs("div", { className: "grid justify-items-center gap-2", children: [_jsx(EmptyTitle, { children: _jsx(SectionHeading, { level: headingLevel, children: title }) }), _jsx(EmptyDescription, { children: description })] }));
|
|
42
|
+
}
|
|
43
|
+
function DocsLink({ command }) {
|
|
44
|
+
return (_jsx("div", { className: "text-muted-foreground [&_[data-slot=button]]:h-5 [&_[data-slot=button]]:gap-0.5 [&_[data-slot=button]]:px-0! [&_[data-slot=button]]:text-body-sm [&_[data-slot=button]]:font-normal [&_[data-slot=button]]:text-current [&_[data-slot=button]:hover]:text-foreground [&_[data-slot=button]_svg]:size-4!", children: _jsx(PageCommandButton, { command: command, size: "xs", variant: "link" }) }));
|
|
45
|
+
}
|
|
46
|
+
function FailedRead({ headingLevel, message, reference, scope, }) {
|
|
47
|
+
const actions = useRef(null);
|
|
48
|
+
useEffect(() => {
|
|
49
|
+
if (scope === "page")
|
|
50
|
+
actions.current?.querySelector("button, a[href]")?.focus();
|
|
51
|
+
}, [scope]);
|
|
34
52
|
const body = bodyBeyondTitle(message);
|
|
35
|
-
return (_jsxs("div", { className: "grid min-w-0 gap-
|
|
53
|
+
return (_jsxs(Empty, { "data-empty-state": "failed", scope: scope, tone: "error", children: [_jsxs(EmptyHeader, { className: "gap-2", children: [_jsx(EmptyMedia, { variant: "error", children: _jsx(OctagonAlertIcon, { "aria-hidden": "true" }) }), _jsxs("div", { className: "grid min-w-0 gap-2", "data-message-code": message.code, role: "status", children: [_jsx(EmptyTitle, { className: "font-normal break-words text-current", children: _jsx(SectionHeading, { level: headingLevel, children: message.title }) }), body ? (_jsx(EmptyDescription, { className: "break-words text-current", children: body })) : null] }), reference ? (_jsx(Disclosure, { className: "[&_summary]:text-current [&_summary:hover]:text-current", label: reference.label, children: _jsxs("div", { className: "flex min-w-0 items-center justify-center gap-1", "data-empty-reference": true, children: [_jsx("code", { className: "min-w-0 font-mono text-label-mono break-all", children: reference.value }), _jsx(CopyButton, { copiedLabel: reference.copiedLabel, copyFailedLabel: reference.copyFailedLabel, copyLabel: reference.copyLabel, size: "icon-xs", value: reference.value })] }) })) : null] }), message.actions.length > 0 ? (_jsx(EmptyContent, { "data-empty-state-action": true, ref: actions, children: message.actions.slice(0, 2).map((action) => (_jsx(PageCommandButton, { command: action, variant: "outline" }, action.label))) })) : null] }));
|
|
36
54
|
}
|
|
@@ -9,7 +9,7 @@ export type EntrySceneProps = {
|
|
|
9
9
|
/** The room the screen keeps once the shape would leave it too little. */
|
|
10
10
|
minHeight?: string;
|
|
11
11
|
/** The approved picture of this surface: one image serves every view. */
|
|
12
|
-
picture
|
|
12
|
+
picture: ReactNode;
|
|
13
13
|
/**
|
|
14
14
|
* The lowest visible row of that picture, of its 941, so the figure's feet
|
|
15
15
|
* stand on the floor of the window. 906 for the sign-in, 876 for the
|
|
@@ -17,9 +17,9 @@ export type EntrySceneProps = {
|
|
|
17
17
|
*/
|
|
18
18
|
pictureFeet?: number;
|
|
19
19
|
/** The nadicode wordmark, still at the upper left. */
|
|
20
|
-
wordmark
|
|
20
|
+
wordmark: ReactNode;
|
|
21
21
|
/** The screen's real heading. It names the surface and is never seen. */
|
|
22
|
-
title
|
|
22
|
+
title: string;
|
|
23
23
|
/** Nadia herself, centred: `NadiaPresence`. */
|
|
24
24
|
presence?: ReactNode;
|
|
25
25
|
/** Which view is open. A failure quiets the picture; it is never removed. */
|
|
@@ -36,7 +36,7 @@ export type EntrySceneProps = {
|
|
|
36
36
|
* @family Compositions
|
|
37
37
|
* @when Nadia's installer and the desktop's sign-in, start, update and failure screens, which paint the same screen; a page that shows that screen beside other things.
|
|
38
38
|
* @instead The Portal's entry pages are its funnel frame with the shared entry header; Alveare Server's entry is the HiveScene; a wait inside the product is a WaitingLine.
|
|
39
|
-
* @behaviour It holds no state and decides nothing: which view is open, the words and when the screen ends belong to whoever mounts it. It fills a box of the window's own shape (`aspectRatio`), so the picture's figure stands on the window's floor (`pictureFeet`). A failure quiets the picture and never removes it. Its children stand in order: the message, the actions, the progress line, the stage list.
|
|
39
|
+
* @behaviour It holds no state and decides nothing: which view is open, the words and when the screen ends belong to whoever mounts it. Required: the picture, the wordmark and the heading, because every entry screen has all three; a screen that leaves one out does not compile. It fills a box of the window's own shape (`aspectRatio`), so the picture's figure stands on the window's floor (`pictureFeet`). A failure quiets the picture and never removes it. Its children stand in order: the message, the actions, the progress line, the stage list.
|
|
40
40
|
* @words The heading names the surface and is never seen. Instructions and status are one plain sentence that changes only when the real stage changes ("Loading your tools").
|
|
41
41
|
* @access One level-1 heading for the screen, read but not shown; a message that reports work in progress is a status.
|
|
42
42
|
*/
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"entry-scene.d.ts","sourceRoot":"","sources":["../../src/components/entry-scene.tsx"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,cAAc,EAAiB,SAAS,EAAE,MAAM,OAAO,CAAC;AAItE,MAAM,MAAM,cAAc,GAAG,MAAM,GAAG,SAAS,GAAG,SAAS,CAAC;AAE5D,MAAM,MAAM,eAAe,GAAG;IAC5B;;;OAGG;IACH,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB,0EAA0E;IAC1E,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,yEAAyE;IACzE,OAAO,
|
|
1
|
+
{"version":3,"file":"entry-scene.d.ts","sourceRoot":"","sources":["../../src/components/entry-scene.tsx"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,cAAc,EAAiB,SAAS,EAAE,MAAM,OAAO,CAAC;AAItE,MAAM,MAAM,cAAc,GAAG,MAAM,GAAG,SAAS,GAAG,SAAS,CAAC;AAE5D,MAAM,MAAM,eAAe,GAAG;IAC5B;;;OAGG;IACH,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB,0EAA0E;IAC1E,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,yEAAyE;IACzE,OAAO,EAAE,SAAS,CAAC;IACnB;;;;OAIG;IACH,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB,sDAAsD;IACtD,QAAQ,EAAE,SAAS,CAAC;IACpB,yEAAyE;IACzE,KAAK,EAAE,MAAM,CAAC;IACd,+CAA+C;IAC/C,QAAQ,CAAC,EAAE,SAAS,CAAC;IACrB,6EAA6E;IAC7E,IAAI,CAAC,EAAE,MAAM,CAAC;IACd,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,sEAAsE;IACtE,QAAQ,CAAC,EAAE,SAAS,CAAC;CACtB,CAAC;AAEF;;;;;;;;;;;GAWG;AACH,wBAAgB,UAAU,CAAC,EACzB,WAA0B,EAC1B,SAAS,EACT,OAAO,EACP,WAAiB,EACjB,QAAQ,EACR,KAAK,EACL,QAAQ,EACR,IAAI,EACJ,SAAS,EACT,QAAQ,GACT,EAAE,eAAe,+BAuBjB;AAED;;;GAGG;AACH,wBAAgB,YAAY,CAAC,EAC3B,KAAK,EACL,IAAY,EACZ,SAAS,EACT,QAAQ,GACT,EAAE;IACD,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,oDAAoD;IACpD,IAAI,CAAC,EAAE,OAAO,CAAC;IACf,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,QAAQ,EAAE,SAAS,CAAC;CACrB,+BAWA;AAED,wBAAgB,YAAY,CAAC,EAAE,SAAS,EAAE,QAAQ,EAAE,EAAE;IAAE,SAAS,CAAC,EAAE,MAAM,CAAC;IAAC,QAAQ,EAAE,SAAS,CAAA;CAAE,+BAEhG;AAED;;;;;GAKG;AACH,wBAAgB,WAAW,CAAC,EAC1B,OAAmB,EACnB,OAAO,EACP,SAAS,EACT,QAAQ,EACR,GAAG,KAAK,EACT,EAAE,cAAc,CAAC,QAAQ,CAAC,GAAG;IAC5B,OAAO,CAAC,EAAE,SAAS,GAAG,WAAW,CAAC;IAClC,OAAO,CAAC,EAAE,OAAO,CAAC;CACnB,+BAYA;AAED;;;;;;;;;;GAUG;AACH,wBAAgB,aAAa,CAAC,EAC5B,QAAQ,EACR,KAAK,EACL,SAAS,GACV,EAAE;IACD,QAAQ,EAAE,MAAM,CAAC;IACjB,KAAK,EAAE,MAAM,CAAC;IACd,SAAS,CAAC,EAAE,MAAM,CAAC;CACpB,+BAaA;AAED;;;;;;;;;GASG;AACH,wBAAgB,cAAc,CAAC,EAC7B,MAAM,EACN,SAAS,GACV,EAAE;IACD,MAAM,EAAE,aAAa,CAAC;QAAE,EAAE,EAAE,MAAM,CAAC;QAAC,KAAK,EAAE,MAAM,CAAC;QAAC,IAAI,EAAE,cAAc,CAAA;KAAE,CAAC,CAAC;IAC3E,SAAS,CAAC,EAAE,MAAM,CAAC;CACpB,+BAeA"}
|
|
@@ -8,7 +8,7 @@ import { cn } from "../lib/utils.js";
|
|
|
8
8
|
* @family Compositions
|
|
9
9
|
* @when Nadia's installer and the desktop's sign-in, start, update and failure screens, which paint the same screen; a page that shows that screen beside other things.
|
|
10
10
|
* @instead The Portal's entry pages are its funnel frame with the shared entry header; Alveare Server's entry is the HiveScene; a wait inside the product is a WaitingLine.
|
|
11
|
-
* @behaviour It holds no state and decides nothing: which view is open, the words and when the screen ends belong to whoever mounts it. It fills a box of the window's own shape (`aspectRatio`), so the picture's figure stands on the window's floor (`pictureFeet`). A failure quiets the picture and never removes it. Its children stand in order: the message, the actions, the progress line, the stage list.
|
|
11
|
+
* @behaviour It holds no state and decides nothing: which view is open, the words and when the screen ends belong to whoever mounts it. Required: the picture, the wordmark and the heading, because every entry screen has all three; a screen that leaves one out does not compile. It fills a box of the window's own shape (`aspectRatio`), so the picture's figure stands on the window's floor (`pictureFeet`). A failure quiets the picture and never removes it. Its children stand in order: the message, the actions, the progress line, the stage list.
|
|
12
12
|
* @words The heading names the surface and is never seen. Instructions and status are one plain sentence that changes only when the real stage changes ("Loading your tools").
|
|
13
13
|
* @access One level-1 heading for the screen, read but not shown; a message that reports work in progress is a status.
|
|
14
14
|
*/
|
|
@@ -19,7 +19,7 @@ export function EntryScene({ aspectRatio = "1220 / 800", minHeight, picture, pic
|
|
|
19
19
|
aspectRatio,
|
|
20
20
|
minHeight,
|
|
21
21
|
"--entry-picture-feet": pictureFeet,
|
|
22
|
-
}, children: _jsxs("div", { className: "dark nc-entry-room", "data-view": view, children: [
|
|
22
|
+
}, children: _jsxs("div", { className: "dark nc-entry-room", "data-view": view, children: [_jsx("div", { className: "nc-entry-picture", children: picture }), _jsx("header", { className: "nc-entry-header", children: wordmark }), _jsx("h1", { className: "nc-entry-sr", children: title }), presence ? _jsx("div", { className: "nc-entry-figure", children: presence }) : null, _jsx("div", { className: "nc-entry-body", children: children })] }) }));
|
|
23
23
|
}
|
|
24
24
|
/**
|
|
25
25
|
* What the screen is doing, said plainly. `lines` reserves the room a longer
|
|
@@ -9,34 +9,64 @@ declare const fieldVariants: (props?: ({
|
|
|
9
9
|
orientation?: "horizontal" | "vertical" | "responsive" | null | undefined;
|
|
10
10
|
} & import("class-variance-authority/types").ClassProp) | undefined) => string;
|
|
11
11
|
/**
|
|
12
|
-
* A control with its label
|
|
12
|
+
* A control with its label and its error, tied together; a checkbox, a radio or a switch with the
|
|
13
|
+
* sentence beside it.
|
|
13
14
|
*
|
|
14
15
|
* @family Inputs
|
|
15
|
-
* @when
|
|
16
|
-
*
|
|
17
|
-
*
|
|
18
|
-
*
|
|
19
|
-
* is `
|
|
20
|
-
*
|
|
21
|
-
*
|
|
22
|
-
*
|
|
23
|
-
*
|
|
24
|
-
*
|
|
16
|
+
* @when A checkbox, a radio or a switch with its sentence, or a group of such rows. Inside a
|
|
17
|
+
* settings section `SettingsField` does it and hands the control its `controlProps`.
|
|
18
|
+
* @instead A text box, a textarea, a select, a combobox or a multi-select takes `label` and `error`
|
|
19
|
+
* as props and draws these same parts: wrapping one in `Field` with a `FieldLabel` is the same job
|
|
20
|
+
* done twice. A bordered tile that holds a radio or checkbox and a sentence is `ChoiceboxGroup`. A
|
|
21
|
+
* whole save group is `SettingsSection`. A group of radios or checkboxes is a `FieldSet` with a
|
|
22
|
+
* `FieldLegend`:
|
|
23
|
+
* "Wrap related radios in `<fieldset>` + `<legend>` so screen readers announce the group name before each option." (https://vercel.com/geist/radio)
|
|
24
|
+
* "Wrap related checkboxes in `<fieldset>` with a `<legend>` so screen readers announce the group name before each option." (https://vercel.com/geist/checkbox)
|
|
25
|
+
* @behaviour "Accessible text label for form controls." (https://vercel.com/geist/label) Label,
|
|
26
|
+
* then the control, then the error under it, 8 px apart, at regular weight; the fields of a
|
|
27
|
+
* `FieldGroup` stand 16 px apart. The label stays neutral when the control is invalid: red sits on
|
|
28
|
+
* the control's edge and on the message, the message with an alert mark before it at 13 px (16 px
|
|
29
|
+
* beside a large control). A control fills its field.
|
|
30
|
+
* "Helper text is sentence case, one sentence with a trailing period, on a sibling element wired through `aria-describedby`." (https://vercel.com/geist/input)
|
|
31
|
+
* Ours: help is the one-line description of the card or the form that holds the field, not a line
|
|
32
|
+
* under each field; a `FieldDescription` is for the sentence beside a checkbox, a radio or a
|
|
33
|
+
* switch.
|
|
34
|
+
* "Validate on blur, not on every keystroke; surface the message by passing a string to `error`." (https://vercel.com/geist/input)
|
|
35
|
+
* "Validate on blur and pass a string to `error` to render the inline message; the validation replaces helper text on failure." (https://vercel.com/geist/textarea)
|
|
36
|
+
* Ours: the message updates as the value is corrected.
|
|
37
|
+
* "Keep the field focusable while saving; pair `disabled` with a spinner only when input is impossible." (https://vercel.com/geist/input)
|
|
38
|
+
* Ours: no spinner, the loading state stays still.
|
|
39
|
+
* "Trim leading and trailing whitespace before submit so ` example.com` and `example.com` resolve to one value." (https://vercel.com/geist/input)
|
|
40
|
+
* Ours: the save of `FormDialog`, `FormDrawer`, `RowEditForm` and `SettingsSection` trims the ends
|
|
41
|
+
* of every text value; a bare `<form>` does not.
|
|
42
|
+
* "The click target already extends to the label. Don’t override the `<label>`/`htmlFor` association with a custom wrapper that breaks the click region." (https://vercel.com/geist/checkbox)
|
|
43
|
+
* "Disabled checkboxes still need a Tooltip naming the reason; a greyed box with no explanation reads as a bug." (https://vercel.com/geist/checkbox)
|
|
44
|
+
* Ours: a disabled field says why in the card's footer, never in a tooltip around the control.
|
|
45
|
+
* @words
|
|
46
|
+
* "Labels are short Title Case nouns: `Project Name`, `Domain`, `Environment Variable Name`." (https://vercel.com/geist/input)
|
|
47
|
+
* Ours: sentence case, a short noun (*Display name*); a field that may stay empty says so in its
|
|
48
|
+
* label (*Address line 2 (optional)*), never in its placeholder.
|
|
49
|
+
* "Placeholders show an example value (`my-awesome-project`, `example.com`), never instructions like `Enter your project name`." (https://vercel.com/geist/input)
|
|
50
|
+
* "Validation names the field and the constraint, ends in a period, and skips `please` (`Project name is required.`, `Code must be 6 digits.`)." (https://vercel.com/geist/input)
|
|
51
|
+
* Ours: *Enter a full address, like name@company.it.*
|
|
25
52
|
* @access `FieldError` is `role="alert"`. The control carries `id`, `aria-invalid`,
|
|
26
|
-
* `aria-describedby` (
|
|
53
|
+
* `aria-describedby` (the error), `disabled` and `required`.
|
|
54
|
+
* "Don’t wrap a labelled `<Input>` in a `Tooltip`; put the explainer on a sibling icon button so the label stays announced." (https://vercel.com/geist/input)
|
|
27
55
|
*/
|
|
28
56
|
declare function Field({ className, orientation, ...props }: React.ComponentProps<"div"> & VariantProps<typeof fieldVariants>): import("react").JSX.Element;
|
|
29
57
|
declare function FieldContent({ className, ...props }: React.ComponentProps<"div">): import("react").JSX.Element;
|
|
30
|
-
declare function FieldLabel({ className, ...props }: React.ComponentProps<typeof Label>): import("react").JSX.Element;
|
|
58
|
+
declare function FieldLabel({ className, htmlFor, ...props }: React.ComponentProps<typeof Label>): import("react").JSX.Element;
|
|
31
59
|
declare function FieldTitle({ className, ...props }: React.ComponentProps<"div">): import("react").JSX.Element;
|
|
32
60
|
declare function FieldDescription({ className, ...props }: React.ComponentProps<"p">): import("react").JSX.Element;
|
|
33
61
|
declare function FieldSeparator({ children, className, ...props }: React.ComponentProps<"div"> & {
|
|
34
62
|
children?: React.ReactNode;
|
|
35
63
|
}): import("react").JSX.Element;
|
|
36
|
-
declare function FieldError({ className, children, errors, ...props }: React.ComponentProps<"div"> & {
|
|
64
|
+
declare function FieldError({ className, children, errors, size, ...props }: React.ComponentProps<"div"> & {
|
|
37
65
|
errors?: Array<{
|
|
38
66
|
message?: string;
|
|
39
67
|
} | undefined>;
|
|
68
|
+
/** `lg` beside a large control: the message takes the control's 16 px type. */
|
|
69
|
+
size?: "default" | "lg";
|
|
40
70
|
}): import("react").JSX.Element | null;
|
|
41
71
|
export { Field, FieldLabel, FieldDescription, FieldError, FieldGroup, FieldLegend, FieldSeparator, FieldSet, FieldContent, FieldTitle, };
|
|
42
72
|
//# sourceMappingURL=field.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"field.d.ts","sourceRoot":"","sources":["../../src/components/field.tsx"],"names":[],"mappings":"AAGA,OAAO,EAAO,KAAK,YAAY,EAAE,MAAM,0BAA0B,CAAC;
|
|
1
|
+
{"version":3,"file":"field.d.ts","sourceRoot":"","sources":["../../src/components/field.tsx"],"names":[],"mappings":"AAGA,OAAO,EAAO,KAAK,YAAY,EAAE,MAAM,0BAA0B,CAAC;AAIlE,OAAO,EAAE,KAAK,EAAE,MAAM,oBAAoB,CAAC;AAG3C,iBAAS,QAAQ,CAAC,EAAE,SAAS,EAAE,GAAG,KAAK,EAAE,EAAE,KAAK,CAAC,cAAc,CAAC,UAAU,CAAC,+BAW1E;AAED,iBAAS,WAAW,CAAC,EACnB,SAAS,EACT,OAAkB,EAClB,GAAG,KAAK,EACT,EAAE,KAAK,CAAC,cAAc,CAAC,QAAQ,CAAC,GAAG;IAAE,OAAO,CAAC,EAAE,QAAQ,GAAG,OAAO,CAAA;CAAE,+BAYnE;AAED,iBAAS,UAAU,CAAC,EAAE,SAAS,EAAE,GAAG,KAAK,EAAE,EAAE,KAAK,CAAC,cAAc,CAAC,KAAK,CAAC,+BAWvE;AAED,QAAA,MAAM,aAAa;;8EAajB,CAAC;AAEH;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GA4CG;AACH,iBAAS,KAAK,CAAC,EACb,SAAS,EACT,WAAwB,EACxB,GAAG,KAAK,EACT,EAAE,KAAK,CAAC,cAAc,CAAC,KAAK,CAAC,GAAG,YAAY,CAAC,OAAO,aAAa,CAAC,+BAUlE;AAKD,iBAAS,YAAY,CAAC,EAAE,SAAS,EAAE,GAAG,KAAK,EAAE,EAAE,KAAK,CAAC,cAAc,CAAC,KAAK,CAAC,+BAWzE;AAED,iBAAS,UAAU,CAAC,EAAE,SAAS,EAAE,OAAO,EAAE,GAAG,KAAK,EAAE,EAAE,KAAK,CAAC,cAAc,CAAC,OAAO,KAAK,CAAC,+BAcvF;AAED,iBAAS,UAAU,CAAC,EAAE,SAAS,EAAE,GAAG,KAAK,EAAE,EAAE,KAAK,CAAC,cAAc,CAAC,KAAK,CAAC,+BAWvE;AAED,iBAAS,gBAAgB,CAAC,EAAE,SAAS,EAAE,GAAG,KAAK,EAAE,EAAE,KAAK,CAAC,cAAc,CAAC,GAAG,CAAC,+BAa3E;AAED,iBAAS,cAAc,CAAC,EACtB,QAAQ,EACR,SAAS,EACT,GAAG,KAAK,EACT,EAAE,KAAK,CAAC,cAAc,CAAC,KAAK,CAAC,GAAG;IAC/B,QAAQ,CAAC,EAAE,KAAK,CAAC,SAAS,CAAC;CAC5B,+BAsBA;AAED,iBAAS,UAAU,CAAC,EAClB,SAAS,EACT,QAAQ,EACR,MAAM,EACN,IAAgB,EAChB,GAAG,KAAK,EACT,EAAE,KAAK,CAAC,cAAc,CAAC,KAAK,CAAC,GAAG;IAC/B,MAAM,CAAC,EAAE,KAAK,CAAC;QAAE,OAAO,CAAC,EAAE,MAAM,CAAA;KAAE,GAAG,SAAS,CAAC,CAAC;IACjD,+EAA+E;IAC/E,IAAI,CAAC,EAAE,SAAS,GAAG,IAAI,CAAC;CACzB,sCAiDA;AAED,OAAO,EACL,KAAK,EACL,UAAU,EACV,gBAAgB,EAChB,UAAU,EACV,UAAU,EACV,WAAW,EACX,cAAc,EACd,QAAQ,EACR,YAAY,EACZ,UAAU,GACX,CAAC"}
|