@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
|
@@ -5,25 +5,34 @@ import { type DataTableRowLinkProps } from "./data-table.js";
|
|
|
5
5
|
import { type EmptyStateKind } from "./empty-state.js";
|
|
6
6
|
import type { IdentityMarkProps } from "./identity-mark.js";
|
|
7
7
|
import { type PageCommand } from "./page-actions.js";
|
|
8
|
+
import { type ProgressChecklistProps } from "./progress-checklist.js";
|
|
8
9
|
import { type StatusBadgeTone } from "./status-badge.js";
|
|
10
|
+
import type { CollectionNote } from "../internal/collection-note.js";
|
|
9
11
|
import { type RowMessage } from "../internal/row-message.js";
|
|
10
12
|
export type { RowMessage };
|
|
11
13
|
export type RecordName = {
|
|
12
14
|
/** One line, ending in an ellipsis and whole in its title, unless the list `wraps`. */
|
|
13
15
|
name: string;
|
|
14
|
-
/**
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
16
|
+
/**
|
|
17
|
+
* The muted line under the name: what it is or where it comes from. Every row has one; a record
|
|
18
|
+
* with nothing to say passes `<TableValue missingLabel="…" value={null} />`, the dash.
|
|
19
|
+
*/
|
|
20
|
+
detail: NonNullable<ReactNode>;
|
|
21
|
+
/** Its identity mark, drawn at 32. Every row has one: an initials mark when the record has no picture. */
|
|
22
|
+
mark: IdentityMarkProps;
|
|
18
23
|
};
|
|
19
24
|
export type RecordFact<TRecord> = {
|
|
20
25
|
id: string;
|
|
21
26
|
/** The column's name for assistive technology. */
|
|
22
27
|
label: string;
|
|
23
28
|
of: (record: TRecord) => ReactNode;
|
|
24
|
-
/**
|
|
25
|
-
|
|
29
|
+
/** Its column's width in pixels, for its longest value in every language the product ships. */
|
|
30
|
+
size: number;
|
|
31
|
+
/** The value is more than one line, such as a disclosure: it wraps in full instead of ending in an ellipsis. */
|
|
32
|
+
wraps?: true;
|
|
26
33
|
};
|
|
34
|
+
/** At most three. A list that needs more columns compares its records, which is a `DataTable`. */
|
|
35
|
+
export type RecordFacts<TRecord> = readonly [] | readonly [RecordFact<TRecord>] | readonly [RecordFact<TRecord>, RecordFact<TRecord>] | readonly [RecordFact<TRecord>, RecordFact<TRecord>, RecordFact<TRecord>];
|
|
27
36
|
export type RecordStatus = {
|
|
28
37
|
label: string;
|
|
29
38
|
tone: StatusBadgeTone;
|
|
@@ -36,36 +45,73 @@ export type RecordTimeColumn<TRecord> = {
|
|
|
36
45
|
/** What a screen reader hears beside the muted dash where a record has no time. */
|
|
37
46
|
missing: string;
|
|
38
47
|
locale?: string;
|
|
48
|
+
/** Its column's width in pixels, for its longest sentence in every language the product ships. */
|
|
49
|
+
size: number;
|
|
50
|
+
};
|
|
51
|
+
export type RecordSelection<TRecord> = {
|
|
52
|
+
/** Names the selection column for assistive technology: "Select". */
|
|
53
|
+
header: string;
|
|
54
|
+
/** Names one record's box: "Select client-onboarding". */
|
|
55
|
+
label: (record: TRecord) => string;
|
|
56
|
+
checked: (record: TRecord) => boolean;
|
|
57
|
+
onCheckedChange: (record: TRecord, checked: boolean) => void;
|
|
39
58
|
};
|
|
40
59
|
export type RecordListFooter = {
|
|
41
60
|
/** "5 Agents" */
|
|
42
61
|
count?: ReactNode;
|
|
43
|
-
/**
|
|
62
|
+
/**
|
|
63
|
+
* A bounded server page: "Page 1 of 6" and Previous and Next. A side with no handler has no page,
|
|
64
|
+
* so its button is disabled; with neither, there is one page and no pager.
|
|
65
|
+
*/
|
|
44
66
|
pages?: {
|
|
45
|
-
label
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
67
|
+
label?: ReactNode;
|
|
68
|
+
previousLabel: string;
|
|
69
|
+
nextLabel: string;
|
|
70
|
+
onPrevious?: (() => void) | undefined;
|
|
71
|
+
onNext?: (() => void) | undefined;
|
|
72
|
+
pending?: boolean | undefined;
|
|
49
73
|
};
|
|
74
|
+
/** One muted line about the whole list, with Learn more and one secondary action, in a strip of its own under the count and the paging. */
|
|
75
|
+
note?: CollectionNote;
|
|
50
76
|
};
|
|
51
|
-
|
|
77
|
+
type RecordListBase<TRecord extends RowData> = {
|
|
52
78
|
/** Names the list for assistive technology: "Skills". */
|
|
53
79
|
label: string;
|
|
54
80
|
/** Already searched, filtered and ordered; undefined while they load. */
|
|
55
81
|
records: readonly TRecord[] | undefined;
|
|
56
82
|
getId: (record: TRecord) => string;
|
|
83
|
+
/** What the row is called: required, because every row is an entity with a mark, a name and a line under it. */
|
|
57
84
|
name: (record: TRecord) => RecordName;
|
|
58
85
|
/** The name is the record's whole text, such as a memory: it wraps in full. */
|
|
59
86
|
wraps?: boolean;
|
|
60
|
-
|
|
87
|
+
/** A box before each record, so a person can pick several. */
|
|
88
|
+
select?: RecordSelection<TRecord>;
|
|
89
|
+
/**
|
|
90
|
+
* `line` draws Vercel's project row: the facts and the status share one muted line between the
|
|
91
|
+
* name and the time, and the row ends in the ring and the three dots even for one command, so it
|
|
92
|
+
* stays one line on any card wider than a phone's; `columns`, the
|
|
93
|
+
* default, gives each fact its own column. A `CollectionPage` with a `rail` sets it.
|
|
94
|
+
*/
|
|
95
|
+
layout?: "columns" | "line";
|
|
96
|
+
facts?: RecordFacts<TRecord>;
|
|
61
97
|
/** Only for the exception: null for the usual record. */
|
|
62
98
|
status?: {
|
|
63
99
|
label: string;
|
|
64
100
|
of: (record: TRecord) => RecordStatus | null;
|
|
101
|
+
/** Its column's width in pixels, for its longest status in every language the product ships. */
|
|
102
|
+
size: number;
|
|
65
103
|
};
|
|
66
104
|
time?: RecordTimeColumn<TRecord>;
|
|
67
|
-
/**
|
|
68
|
-
|
|
105
|
+
/**
|
|
106
|
+
* How far the record is through the steps that make it ready: the ring before the row's
|
|
107
|
+
* commands, as Vercel ends a project's row with its Production Checklist. Null for a record
|
|
108
|
+
* with no checklist.
|
|
109
|
+
*/
|
|
110
|
+
checklist?: {
|
|
111
|
+
/** Names the column for assistive technology: "Setup". */
|
|
112
|
+
label: string;
|
|
113
|
+
of: (record: TRecord) => ProgressChecklistProps | null;
|
|
114
|
+
};
|
|
69
115
|
/** The row's three dots; its first line is `name(record).name`. */
|
|
70
116
|
menu?: (record: TRecord) => {
|
|
71
117
|
label: string;
|
|
@@ -79,9 +125,11 @@ export type RecordListProps<TRecord extends RowData> = {
|
|
|
79
125
|
label: (record: TRecord) => string;
|
|
80
126
|
renderLink?: (props: DataTableRowLinkProps) => ReactNode;
|
|
81
127
|
};
|
|
82
|
-
/**
|
|
83
|
-
|
|
84
|
-
|
|
128
|
+
/**
|
|
129
|
+
* Values edited in place: the row of the record being edited expands into its `RowEditForm`,
|
|
130
|
+
* under the record's line, and the rows around it stay. The way in is the row's "Edit" command
|
|
131
|
+
* or a line of its menu.
|
|
132
|
+
*/
|
|
85
133
|
editor?: {
|
|
86
134
|
id: string;
|
|
87
135
|
render: (record: TRecord) => ReactNode;
|
|
@@ -89,7 +137,11 @@ export type RecordListProps<TRecord extends RowData> = {
|
|
|
89
137
|
/** Names the rows while they load; `label` when left out. */
|
|
90
138
|
loadingLabel?: string;
|
|
91
139
|
failed?: EmptyStateKind<"failed">;
|
|
92
|
-
|
|
140
|
+
/**
|
|
141
|
+
* What the list says with no records. `null` leaves the list out until it has some, for a section
|
|
142
|
+
* that appears only when something needs a person, such as an Overview's exceptions.
|
|
143
|
+
*/
|
|
144
|
+
empty: EmptyStateKind<"firstUse"> | EmptyStateKind<"nothingYet"> | null;
|
|
93
145
|
/** Given only while a search or filter is set. */
|
|
94
146
|
noMatch?: Omit<EmptyStateKind<"noResults">, "kind">;
|
|
95
147
|
/**
|
|
@@ -103,17 +155,55 @@ export type RecordListProps<TRecord extends RowData> = {
|
|
|
103
155
|
};
|
|
104
156
|
footer?: RecordListFooter;
|
|
105
157
|
};
|
|
158
|
+
type RecordListCommands<TRecord extends RowData> = {
|
|
159
|
+
command?: never;
|
|
160
|
+
state?: never;
|
|
161
|
+
commandsSize?: number;
|
|
162
|
+
} | {
|
|
163
|
+
/**
|
|
164
|
+
* The row's visible commands, one or two outline buttons of 32 px before the three dots:
|
|
165
|
+
* "Connect account", "Open report". A third goes in the menu.
|
|
166
|
+
*/
|
|
167
|
+
command?: (record: TRecord) => PageCommand | readonly [PageCommand, PageCommand] | null;
|
|
168
|
+
/** The record's own action failed or was refused: its message inside its row. */
|
|
169
|
+
state?: (record: TRecord) => RowMessage | null;
|
|
170
|
+
/**
|
|
171
|
+
* The commands column's width in pixels, for the row command or a failed action's next
|
|
172
|
+
* steps beside the three dots; a list with neither, or whose failed action shows on no row,
|
|
173
|
+
* keeps the width of the three dots alone, so the name keeps the room.
|
|
174
|
+
*/
|
|
175
|
+
commandsSize: number;
|
|
176
|
+
};
|
|
177
|
+
export type RecordListProps<TRecord extends RowData> = RecordListBase<TRecord> & RecordListCommands<TRecord>;
|
|
178
|
+
type WithoutKeys<List, Key extends PropertyKey> = List extends unknown ? Omit<List, Key> : never;
|
|
179
|
+
/** The list's props without some keys, keeping a row command and its `commandsSize` together. */
|
|
180
|
+
export type RecordListWithout<TRecord extends RowData, Key extends PropertyKey> = WithoutKeys<RecordListProps<TRecord>, Key>;
|
|
106
181
|
/**
|
|
107
|
-
*
|
|
108
|
-
* what it is, a few
|
|
109
|
-
*
|
|
182
|
+
* Entity rows: objects a person opens or acts on, one line each on one resting card: the
|
|
183
|
+
* identity mark and name over what it is, a few facts, a status only for the exception, when it
|
|
184
|
+
* happened, at most two row commands, and the three dots last.
|
|
110
185
|
*
|
|
111
186
|
* @family Compositions
|
|
112
|
-
* @when
|
|
113
|
-
*
|
|
114
|
-
* @
|
|
115
|
-
*
|
|
116
|
-
*
|
|
187
|
+
* @when “Use `<Entity>` for a row of descriptive content paired with one or two controls (member rows, integration rows, domain rows).” (https://vercel.com/geist/entity)
|
|
188
|
+
* Ours: the records are things a person opens or acts on and that name themselves: projects, deployments, domains, members, integrations, Agents, Skills, mailboxes. A list inside another page: an Overview's exceptions, an object page's "Needs attention". A page whose whole job is the list is a `CollectionPage`, which draws this. Values edited in place (a domain, an environment variable) are the same rows with an `editor`: the row expands into its form. Of the three kinds of list, entity rows and rows edited in place are this; records compared across columns are a `DataTable`.
|
|
189
|
+
* @instead “For tabular data with sortable columns and shared row shape, use `Table` instead.” (https://vercel.com/geist/entity)
|
|
190
|
+
* “For a static key/value metadata block on a detail page, use `Description`.” (https://vercel.com/geist/entity)
|
|
191
|
+
* Ours: Geist's `Table` is a `DataTable`: this list has no visible headings and at most three facts, so a fourth fact is a table. Its `Description` is `ObjectFacts`. Events in time are an `ActivityFeed`. Reusable things a person adds from a catalogue are a `LibraryShelf`. A descriptive row with prose is an `Item`.
|
|
192
|
+
* @behaviour One bordered card, a 1 px rule between records and none after the last. A `checklist` puts the record's `ProgressChecklist` ring just before its commands, where Vercel ends a project's row with its Production Checklist; the ring opens its own drawer, never the row. Every row has its 32 px mark, its name and, under it, one muted line; `name` is required and so are the mark and the line, and a record with nothing to say passes the dash. Give every column a `size` in pixels; the name takes the rest. With `layout="line"`, as on Vercel's Projects page, the facts and the status share one muted line, joined by a middle dot, in a column as wide as the name's, and the row stays one line (mark, name over its line, that summary, the time, the ring, the three dots) on a card from 448 px, and on a narrower card the summary and the time move under the name as one muted line joined by a middle dot, in the same row, their labels read by assistive technology only. Rows of `columns` follow the same rule once the card is narrower than their columns: the facts, the status and the time leave the row for that one line, ending in an ellipsis, never a labelled list. `facts` takes at most three. A menu of one command that is not destructive, with no row command, is that command's button, except in a `line` row, which keeps it in the three dots as Vercel's project row does; without a `commandsSize` the column is as wide as the widest such button, so its label is never cut. Status is only for the exception, empty for the usual record, and its column stands only while a record in the list shows one, so the name and its line keep the room; the commands column likewise stands only while a record has a command, a menu or a message, or the rows open. A `line` row's summary joins only the facts the record has, so it never ends in a dot. A failed or refused action of the record replaces its detail line, with its next steps beside its commands, or under the message on a card too narrow for the row's columns. With `open` the whole row is one target and takes the `accent` hover; a row that opens nothing never reacts to hover. With `editor` the record's row opens its form under its line. `empty` is required: `null` is the choice to draw nothing for a list with no records, and any other value is the state it draws. A note about the whole list is `footer.note`: one muted line, an optional *Learn more* after it at the left and one secondary action at the right, in a strip of its own under the count and the paging, as Vercel ends its deployments list ("Deployment retention is enabled. Learn more", *View recently deleted*). Colour is neutral, the name in ink and every other cell in the body grey, except the status badge and a failed action's message.
|
|
193
|
+
* “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)
|
|
194
|
+
* Ours: `failed`, `noMatch` and `empty` are those variants, drawn inside the card.
|
|
195
|
+
* “The right column holds at most one or two controls. If the row needs more, move secondary actions into a `Dots Menu`.” (https://vercel.com/geist/entity)
|
|
196
|
+
* Ours: one or two row commands (outline buttons of 32 px) stand before the three dots (36 px), the Dots Menu.
|
|
197
|
+
* “Render the Skeleton variant (`entity-with-skeleton`) during load instead of an empty row, and swap to real content once data resolves.” (https://vercel.com/geist/entity)
|
|
198
|
+
* Ours: three still skeleton rows hold the place, in a region that announces what replaces them; then the first that holds: the failed read, no match, the empty state, the rows.
|
|
199
|
+
* @words “Lead the left column with a scannable identifier: an `Avatar` or icon, a Title Case label, then sentence-case secondary metadata (`Member since Mar 14, 2026`).” (https://vercel.com/geist/entity)
|
|
200
|
+
* Ours: the name is the record's own and the labels around it are sentence case, not Title Case.
|
|
201
|
+
* “Keep right-column buttons Verb + Noun (`Remove Member`, `Resend Invite`). Bare verbs like `Remove` or `Confirm` lose context once the row scrolls offscreen.” (https://vercel.com/geist/entity)
|
|
202
|
+
* Ours: every string is the product's: `label` names the list, a time's `phrase` writes its sentence ("Updated {when}"), `missing` is what a screen reader hears for a record with no time, the menu's `label` reads "More for {record}". A row command names its result in sentence case ("Edit domain"). A status is the exception's word ("Needs attention"), never "Active" on every row.
|
|
203
|
+
* @access “Wrap the loading region in `aria-busy="true"` and announce completion with `aria-live="polite"` on the destination container, not the skeleton itself.” (https://vercel.com/geist/skeleton)
|
|
204
|
+
* Ours: the loading rows sit in one `SkeletonRegion` that is busy while they stand and announces what replaces them. A table named by `label`, its column headings read by assistive technology only. The row link carries `open.label`; the three dots carry the menu's `label`, and the menu's first line names the record. The loading rows are a status named by `loadingLabel`, inside the one live region that announces what replaces them.
|
|
205
|
+
* “For multi-select rows, the leading `Checkbox` carries `aria-label="Select {entity name}"` so the row is selectable without relying on the visual label.” (https://vercel.com/geist/entity)
|
|
206
|
+
* Ours: each box is named by `select.label`, which reads "Select {record}".
|
|
117
207
|
*/
|
|
118
208
|
export declare function RecordList<TRecord extends RowData>(props: RecordListProps<TRecord>): import("react").JSX.Element | null;
|
|
119
209
|
//# sourceMappingURL=record-list.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"record-list.d.ts","sourceRoot":"","sources":["../../src/components/record-list.tsx"],"names":[],"mappings":"AAEA,OAAO,KAAK,EAAE,OAAO,EAAE,MAAM,uBAAuB,CAAC;AAErD,OAAO,EAAiB,KAAK,SAAS,
|
|
1
|
+
{"version":3,"file":"record-list.d.ts","sourceRoot":"","sources":["../../src/components/record-list.tsx"],"names":[],"mappings":"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"}
|
|
@@ -1,19 +1,57 @@
|
|
|
1
1
|
"use client";
|
|
2
|
-
import { jsx as _jsx,
|
|
2
|
+
import { jsx as _jsx, jsxs as _jsxs, Fragment as _Fragment } from "react/jsx-runtime";
|
|
3
3
|
import { ChevronRight } from "lucide-react";
|
|
4
|
-
import { createContext, useContext } from "react";
|
|
4
|
+
import { createContext, useContext, useId } from "react";
|
|
5
5
|
import { ActionMenu } from "./action-menu.js";
|
|
6
|
-
import {
|
|
6
|
+
import { Checkbox } from "./checkbox.js";
|
|
7
|
+
import { EntityTable, } from "./data-table.js";
|
|
7
8
|
import { EmptyState } from "./empty-state.js";
|
|
8
9
|
import { PageCommandButton } from "./page-actions.js";
|
|
10
|
+
import { ProgressChecklist } from "./progress-checklist.js";
|
|
9
11
|
import { RecordIdentity } from "./record-identity.js";
|
|
10
12
|
import { RecordTime, recordDate } from "./record-time.js";
|
|
11
|
-
import { Skeleton } from "./skeleton.js";
|
|
13
|
+
import { Skeleton, SkeletonRegion } from "./skeleton.js";
|
|
12
14
|
import { StatusBadge } from "./status-badge.js";
|
|
13
15
|
import { TableCard } from "./table-card.js";
|
|
14
16
|
import { TableValue } from "./table-value.js";
|
|
15
17
|
import { soleMenuButton } from "../internal/record-menu-items.js";
|
|
16
18
|
import { RowMessageActions, RowMessageLine } from "../internal/row-message.js";
|
|
19
|
+
import { useTableLaidOutCompact } from "../internal/table-compact-line.js";
|
|
20
|
+
/** The width of the commands column when it holds only the three dots or the chevron. */
|
|
21
|
+
const ICON_COMMANDS_SIZE = 64;
|
|
22
|
+
/**
|
|
23
|
+
* A 32 px outline button with its icon, as a lone menu command draws it: the cell's 8 px before it
|
|
24
|
+
* and 20 px after it at the card's edge, the button's edges and 6 px padding, the 14 px icon and
|
|
25
|
+
* its gap, 8 px to spare, and each character of a 14 px medium label at most 8 px wide, so the
|
|
26
|
+
* label is never cut.
|
|
27
|
+
*/
|
|
28
|
+
const SOLE_BUTTON_FRAME = 72;
|
|
29
|
+
const SOLE_BUTTON_CHARACTER = 8;
|
|
30
|
+
/**
|
|
31
|
+
* The commands column's width when the caller gives none: the three dots alone, or the widest
|
|
32
|
+
* lone menu command any record turns into a button, so a button is never cut to its icon.
|
|
33
|
+
*/
|
|
34
|
+
function defaultCommandsSize(props, records) {
|
|
35
|
+
if (props.layout === "line" || !props.menu)
|
|
36
|
+
return ICON_COMMANDS_SIZE;
|
|
37
|
+
const menu = props.menu;
|
|
38
|
+
return records.reduce((widest, record) => {
|
|
39
|
+
const sole = soleMenuButton(menu(record)?.commands ?? []);
|
|
40
|
+
if (!sole)
|
|
41
|
+
return widest;
|
|
42
|
+
return Math.max(widest, SOLE_BUTTON_FRAME + sole.label.length * SOLE_BUTTON_CHARACTER);
|
|
43
|
+
}, ICON_COMMANDS_SIZE);
|
|
44
|
+
}
|
|
45
|
+
function commandsColumnSize(props) {
|
|
46
|
+
const state = props.state;
|
|
47
|
+
const roomUnused = state !== undefined && !props.command && !props.records.some((record) => state(record));
|
|
48
|
+
return roomUnused || props.commandsSize === undefined
|
|
49
|
+
? defaultCommandsSize(props, props.records)
|
|
50
|
+
: props.commandsSize;
|
|
51
|
+
}
|
|
52
|
+
/** The checklist's ring: one 36 px button and the cell's padding. */
|
|
53
|
+
const CHECKLIST_SIZE = 52;
|
|
54
|
+
const SELECT_SIZE = 40;
|
|
17
55
|
const ShownList = createContext(undefined);
|
|
18
56
|
function useShownList() {
|
|
19
57
|
// SAFETY: only RecordList provides ShownList, with its own props, around the rows of that same RecordList<TRecord>.
|
|
@@ -29,15 +67,33 @@ function NameCell({ row }) {
|
|
|
29
67
|
const list = useShownList();
|
|
30
68
|
const shown = list.name(row.original);
|
|
31
69
|
const state = list.state?.(row.original);
|
|
32
|
-
|
|
70
|
+
const nextStepsUnder = useTableLaidOutCompact() && state?.message.actions.length;
|
|
71
|
+
return (_jsx(RecordIdentity, { detail: state ? (_jsxs("span", { className: "block break-words whitespace-normal", children: [_jsx(RowMessageLine, { state: state }), nextStepsUnder ? (_jsx("span", { className: "flex flex-wrap gap-2 pt-2", children: _jsx(RowMessageActions, { state: state }) })) : null] })) : (shown.detail), mark: shown.mark, name: shown.name, wraps: list.wraps }));
|
|
72
|
+
}
|
|
73
|
+
function SelectCell({ row }) {
|
|
74
|
+
const select = useShownList().select;
|
|
75
|
+
if (!select)
|
|
76
|
+
return null;
|
|
77
|
+
const record = row.original;
|
|
78
|
+
return (_jsx(Checkbox, { "aria-label": select.label(record), checked: select.checked(record), onCheckedChange: (checked) => select.onCheckedChange(record, checked) }));
|
|
33
79
|
}
|
|
34
80
|
function FactCell({ column, row }) {
|
|
35
|
-
const
|
|
36
|
-
return _jsx(_Fragment, { children:
|
|
81
|
+
const facts = useShownList().facts ?? [];
|
|
82
|
+
return _jsx(_Fragment, { children: facts.find((each) => each.id === column.id)?.of(row.original) });
|
|
83
|
+
}
|
|
84
|
+
function SummaryCell({ row }) {
|
|
85
|
+
const list = useShownList();
|
|
86
|
+
const facts = list.facts ?? [];
|
|
87
|
+
const status = list.status?.of(row.original);
|
|
88
|
+
const said = facts.flatMap((fact) => {
|
|
89
|
+
const value = fact.of(row.original);
|
|
90
|
+
return value === null || value === undefined || value === "" ? [] : [{ id: fact.id, value }];
|
|
91
|
+
});
|
|
92
|
+
return (_jsxs("div", { className: "flex min-w-0 items-center gap-2", "data-slot": "record-summary", children: [status ? _jsx(StatusBadge, { label: status.label, tone: status.tone }) : null, _jsx("span", { className: "min-w-0 truncate", children: said.map(({ id, value }, index) => (_jsxs("span", { children: [index > 0 ? _jsx("span", { "aria-hidden": "true", children: " \u00B7 " }) : null, value] }, id))) })] }));
|
|
37
93
|
}
|
|
38
94
|
function StatusCell({ row }) {
|
|
39
95
|
const shown = useShownList().status?.of(row.original);
|
|
40
|
-
return
|
|
96
|
+
return shown ? _jsx(StatusBadge, { label: shown.label, tone: shown.tone }) : null;
|
|
41
97
|
}
|
|
42
98
|
function TimeCell({ row }) {
|
|
43
99
|
const time = useShownList().time;
|
|
@@ -45,7 +101,11 @@ function TimeCell({ row }) {
|
|
|
45
101
|
return null;
|
|
46
102
|
const record = row.original;
|
|
47
103
|
const at = recordDate(time.of(record));
|
|
48
|
-
return (_jsx("div", { className: "
|
|
104
|
+
return (_jsx("div", { className: "truncate text-right tabular-nums", children: _jsx(TableValue, { missingLabel: time.missing, value: at ? (_jsx(RecordTime, { at: at, locale: time.locale, phrase: (when) => time.phrase(when, record) })) : null }) }));
|
|
105
|
+
}
|
|
106
|
+
function ChecklistCell({ row }) {
|
|
107
|
+
const shown = useShownList().checklist?.of(row.original);
|
|
108
|
+
return shown ? (_jsx("div", { className: "flex justify-end", children: _jsx(ProgressChecklist, { ...shown }) })) : null;
|
|
49
109
|
}
|
|
50
110
|
function CommandsCell({ row }) {
|
|
51
111
|
const list = useShownList();
|
|
@@ -53,55 +113,101 @@ function CommandsCell({ row }) {
|
|
|
53
113
|
const state = list.state?.(record);
|
|
54
114
|
const menu = list.menu?.(record);
|
|
55
115
|
const commands = menu?.commands ?? [];
|
|
56
|
-
const
|
|
57
|
-
const
|
|
116
|
+
const own = list.command?.(record);
|
|
117
|
+
const menuButton = own || list.layout === "line" ? undefined : soleMenuButton(commands);
|
|
118
|
+
// On a card too narrow for the row's columns the next steps stand under the message instead.
|
|
119
|
+
const laidOutCompact = useTableLaidOutCompact();
|
|
120
|
+
const buttons = own ? [own].flat() : menuButton ? [menuButton] : [];
|
|
58
121
|
const end = menu && commands.length > 0 && !menuButton ? (_jsx(ActionMenu, { commands: commands, label: menu.label, record: list.name(record).name })) : list.open?.href(record) && !state ? (_jsx(ChevronRight, { "aria-hidden": "true", className: "size-4 text-muted-foreground" })) : null;
|
|
59
|
-
if (
|
|
122
|
+
if (buttons.length === 0 && !state && !end)
|
|
60
123
|
return null;
|
|
61
|
-
return (_jsxs("div", { className: "flex items-center justify-end gap-2", children: [
|
|
124
|
+
return (_jsxs("div", { className: "flex items-center justify-end gap-2", children: [buttons.length > 0 ? (_jsx("div", { className: "flex min-w-0 justify-end gap-2 [&>*]:max-w-full [&>*]:min-w-0 [&>*]:shrink [&>*>span:not([data-icon])]:truncate", children: buttons.map((command) => (_jsx(PageCommandButton, { command: command, size: "sm", variant: "outline" }, command.label))) })) : null, state && !laidOutCompact ? _jsx(RowMessageActions, { state: state }) : null, end] }));
|
|
62
125
|
}
|
|
63
126
|
function LoadingRecords({ label }) {
|
|
64
|
-
return (_jsx("div", { "aria-busy": "true", "aria-label": label, className: "divide-y divide-border", role: "status", children: Array.from({ length: 3 }, (_, index) => (_jsxs("div", { className: "flex
|
|
127
|
+
return (_jsx("div", { "aria-busy": "true", "aria-label": label, className: "divide-y divide-border", role: "status", children: Array.from({ length: 3 }, (_, index) => (_jsxs("div", { className: "flex items-center gap-4 px-2 py-4", children: [_jsx(Skeleton, { className: "shrink-0", height: 32, width: 32 }), _jsxs("div", { className: "grid min-w-0 gap-2", children: [_jsx(Skeleton, { className: "max-w-full", height: 16, width: 160 }), _jsx(Skeleton, { className: "max-w-full", height: 16, width: 224 })] }), _jsx(Skeleton, { className: "ml-auto", height: 16, width: 92 })] }, index))) }));
|
|
65
128
|
}
|
|
66
129
|
function Pages({ pages }) {
|
|
67
|
-
const
|
|
68
|
-
|
|
130
|
+
const side = (label, onClick) => ({
|
|
131
|
+
label,
|
|
132
|
+
onClick: onClick ?? (() => undefined),
|
|
133
|
+
disabled: pages.pending === true || onClick === undefined,
|
|
134
|
+
});
|
|
135
|
+
const labelId = useId();
|
|
136
|
+
return (_jsxs("div", { "aria-busy": pages.pending ? true : undefined, "aria-labelledby": pages.label ? labelId : undefined, className: "flex items-center gap-3", role: "group", children: [pages.label ? (_jsx("span", { className: "tabular-nums", id: labelId, children: pages.label })) : null, _jsxs("div", { className: "flex items-center gap-2", children: [_jsx(PageCommandButton, { command: side(pages.previousLabel, pages.onPrevious), variant: "outline" }), _jsx(PageCommandButton, { command: side(pages.nextLabel, pages.onNext), variant: "outline" })] })] }));
|
|
69
137
|
}
|
|
70
138
|
function recordColumns(props) {
|
|
71
|
-
const columns = [
|
|
72
|
-
|
|
73
|
-
id: "name",
|
|
74
|
-
header: props.label,
|
|
75
|
-
meta: props.wraps ? { wraps: true } : undefined,
|
|
76
|
-
cell: NameCell,
|
|
77
|
-
},
|
|
78
|
-
];
|
|
79
|
-
for (const fact of props.facts ?? []) {
|
|
139
|
+
const columns = [];
|
|
140
|
+
if (props.select) {
|
|
80
141
|
columns.push({
|
|
81
|
-
id:
|
|
82
|
-
header:
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
cell: FactCell,
|
|
142
|
+
id: "select",
|
|
143
|
+
header: props.select.header,
|
|
144
|
+
size: SELECT_SIZE,
|
|
145
|
+
cell: SelectCell,
|
|
86
146
|
});
|
|
87
147
|
}
|
|
88
|
-
|
|
148
|
+
columns.push({
|
|
149
|
+
id: "name",
|
|
150
|
+
header: props.label,
|
|
151
|
+
meta: props.wraps ? { wraps: true } : undefined,
|
|
152
|
+
cell: NameCell,
|
|
153
|
+
});
|
|
154
|
+
const facts = props.facts ?? [];
|
|
155
|
+
if (props.layout === "line") {
|
|
156
|
+
const summary = facts.length > 0 ? facts.map((fact) => fact.label).join(" · ") : props.status?.label;
|
|
157
|
+
if (summary) {
|
|
158
|
+
columns.push({
|
|
159
|
+
id: "summary",
|
|
160
|
+
header: summary,
|
|
161
|
+
cell: SummaryCell,
|
|
162
|
+
});
|
|
163
|
+
}
|
|
164
|
+
}
|
|
165
|
+
else {
|
|
166
|
+
for (const fact of facts) {
|
|
167
|
+
columns.push({
|
|
168
|
+
id: fact.id,
|
|
169
|
+
header: fact.label,
|
|
170
|
+
accessorFn: fact.of,
|
|
171
|
+
size: fact.size,
|
|
172
|
+
meta: { optional: true, wraps: fact.wraps ?? false },
|
|
173
|
+
cell: FactCell,
|
|
174
|
+
});
|
|
175
|
+
}
|
|
176
|
+
const status = props.status;
|
|
177
|
+
if (status && props.records.some((record) => status.of(record))) {
|
|
178
|
+
columns.push({
|
|
179
|
+
id: "status",
|
|
180
|
+
header: status.label,
|
|
181
|
+
accessorFn: status.of,
|
|
182
|
+
size: status.size,
|
|
183
|
+
meta: { optional: true },
|
|
184
|
+
cell: StatusCell,
|
|
185
|
+
});
|
|
186
|
+
}
|
|
187
|
+
}
|
|
188
|
+
if (props.time) {
|
|
89
189
|
columns.push({
|
|
90
|
-
id: "
|
|
91
|
-
header: props.
|
|
92
|
-
|
|
93
|
-
|
|
94
|
-
cell: StatusCell,
|
|
190
|
+
id: "time",
|
|
191
|
+
header: props.time.label,
|
|
192
|
+
size: props.time.size,
|
|
193
|
+
cell: TimeCell,
|
|
95
194
|
});
|
|
96
195
|
}
|
|
97
|
-
if (props.
|
|
98
|
-
columns.push({
|
|
196
|
+
if (props.checklist) {
|
|
197
|
+
columns.push({
|
|
198
|
+
id: "checklist",
|
|
199
|
+
header: props.checklist.label,
|
|
200
|
+
size: CHECKLIST_SIZE,
|
|
201
|
+
cell: ChecklistCell,
|
|
202
|
+
});
|
|
99
203
|
}
|
|
100
|
-
|
|
204
|
+
const { menu, command, state } = props;
|
|
205
|
+
const someRecordHasCommands = props.records.some((record) => menu?.(record) || command?.(record) || state?.(record));
|
|
206
|
+
if (props.open || someRecordHasCommands) {
|
|
101
207
|
columns.push({
|
|
102
208
|
id: "commands",
|
|
103
209
|
header: props.commandsHeader ?? props.label,
|
|
104
|
-
|
|
210
|
+
size: commandsColumnSize(props),
|
|
105
211
|
cell: CommandsCell,
|
|
106
212
|
});
|
|
107
213
|
}
|
|
@@ -109,36 +215,60 @@ function recordColumns(props) {
|
|
|
109
215
|
}
|
|
110
216
|
function RecordRows(props) {
|
|
111
217
|
const columns = recordColumns(props);
|
|
218
|
+
const layout = {};
|
|
219
|
+
if (props.layout === "line")
|
|
220
|
+
layout.compactLayout = "narrow";
|
|
221
|
+
const menu = props.menu;
|
|
112
222
|
const table = {
|
|
113
223
|
columns,
|
|
224
|
+
rowMenu: menu
|
|
225
|
+
? (record) => {
|
|
226
|
+
const shown = menu(record);
|
|
227
|
+
return shown ? { ...shown, record: props.name(record).name } : null;
|
|
228
|
+
}
|
|
229
|
+
: undefined,
|
|
114
230
|
data: [...props.records],
|
|
115
231
|
embedded: true,
|
|
116
232
|
empty: { kind: "nothingYet", message: props.label },
|
|
117
233
|
getRowId: props.getId,
|
|
118
|
-
|
|
119
|
-
|
|
120
|
-
|
|
121
|
-
primaryColumns: ["name", "commands"],
|
|
122
|
-
showColumnHeaders: false,
|
|
234
|
+
primaryColumnId: "name",
|
|
235
|
+
primaryColumns: ["select", "name", "checklist", "commands"],
|
|
236
|
+
...layout,
|
|
123
237
|
rowEditor: props.editor ? { rowId: props.editor.id, render: props.editor.render } : undefined,
|
|
124
238
|
tableLabel: props.label,
|
|
125
239
|
};
|
|
126
|
-
return props.open ? (_jsx(
|
|
240
|
+
return props.open ? (_jsx(EntityTable, { ...table, renderRowLink: props.open.renderLink, rowHref: props.open.href, rowLabel: props.open.label })) : (_jsx(EntityTable, { ...table }));
|
|
127
241
|
}
|
|
128
242
|
/**
|
|
129
|
-
*
|
|
130
|
-
* what it is, a few
|
|
131
|
-
*
|
|
243
|
+
* Entity rows: objects a person opens or acts on, one line each on one resting card: the
|
|
244
|
+
* identity mark and name over what it is, a few facts, a status only for the exception, when it
|
|
245
|
+
* happened, at most two row commands, and the three dots last.
|
|
132
246
|
*
|
|
133
247
|
* @family Compositions
|
|
134
|
-
* @when
|
|
135
|
-
*
|
|
136
|
-
* @
|
|
137
|
-
*
|
|
138
|
-
*
|
|
248
|
+
* @when “Use `<Entity>` for a row of descriptive content paired with one or two controls (member rows, integration rows, domain rows).” (https://vercel.com/geist/entity)
|
|
249
|
+
* Ours: the records are things a person opens or acts on and that name themselves: projects, deployments, domains, members, integrations, Agents, Skills, mailboxes. A list inside another page: an Overview's exceptions, an object page's "Needs attention". A page whose whole job is the list is a `CollectionPage`, which draws this. Values edited in place (a domain, an environment variable) are the same rows with an `editor`: the row expands into its form. Of the three kinds of list, entity rows and rows edited in place are this; records compared across columns are a `DataTable`.
|
|
250
|
+
* @instead “For tabular data with sortable columns and shared row shape, use `Table` instead.” (https://vercel.com/geist/entity)
|
|
251
|
+
* “For a static key/value metadata block on a detail page, use `Description`.” (https://vercel.com/geist/entity)
|
|
252
|
+
* Ours: Geist's `Table` is a `DataTable`: this list has no visible headings and at most three facts, so a fourth fact is a table. Its `Description` is `ObjectFacts`. Events in time are an `ActivityFeed`. Reusable things a person adds from a catalogue are a `LibraryShelf`. A descriptive row with prose is an `Item`.
|
|
253
|
+
* @behaviour One bordered card, a 1 px rule between records and none after the last. A `checklist` puts the record's `ProgressChecklist` ring just before its commands, where Vercel ends a project's row with its Production Checklist; the ring opens its own drawer, never the row. Every row has its 32 px mark, its name and, under it, one muted line; `name` is required and so are the mark and the line, and a record with nothing to say passes the dash. Give every column a `size` in pixels; the name takes the rest. With `layout="line"`, as on Vercel's Projects page, the facts and the status share one muted line, joined by a middle dot, in a column as wide as the name's, and the row stays one line (mark, name over its line, that summary, the time, the ring, the three dots) on a card from 448 px, and on a narrower card the summary and the time move under the name as one muted line joined by a middle dot, in the same row, their labels read by assistive technology only. Rows of `columns` follow the same rule once the card is narrower than their columns: the facts, the status and the time leave the row for that one line, ending in an ellipsis, never a labelled list. `facts` takes at most three. A menu of one command that is not destructive, with no row command, is that command's button, except in a `line` row, which keeps it in the three dots as Vercel's project row does; without a `commandsSize` the column is as wide as the widest such button, so its label is never cut. Status is only for the exception, empty for the usual record, and its column stands only while a record in the list shows one, so the name and its line keep the room; the commands column likewise stands only while a record has a command, a menu or a message, or the rows open. A `line` row's summary joins only the facts the record has, so it never ends in a dot. A failed or refused action of the record replaces its detail line, with its next steps beside its commands, or under the message on a card too narrow for the row's columns. With `open` the whole row is one target and takes the `accent` hover; a row that opens nothing never reacts to hover. With `editor` the record's row opens its form under its line. `empty` is required: `null` is the choice to draw nothing for a list with no records, and any other value is the state it draws. A note about the whole list is `footer.note`: one muted line, an optional *Learn more* after it at the left and one secondary action at the right, in a strip of its own under the count and the paging, as Vercel ends its deployments list ("Deployment retention is enabled. Learn more", *View recently deleted*). Colour is neutral, the name in ink and every other cell in the body grey, except the status badge and a failed action's message.
|
|
254
|
+
* “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)
|
|
255
|
+
* Ours: `failed`, `noMatch` and `empty` are those variants, drawn inside the card.
|
|
256
|
+
* “The right column holds at most one or two controls. If the row needs more, move secondary actions into a `Dots Menu`.” (https://vercel.com/geist/entity)
|
|
257
|
+
* Ours: one or two row commands (outline buttons of 32 px) stand before the three dots (36 px), the Dots Menu.
|
|
258
|
+
* “Render the Skeleton variant (`entity-with-skeleton`) during load instead of an empty row, and swap to real content once data resolves.” (https://vercel.com/geist/entity)
|
|
259
|
+
* Ours: three still skeleton rows hold the place, in a region that announces what replaces them; then the first that holds: the failed read, no match, the empty state, the rows.
|
|
260
|
+
* @words “Lead the left column with a scannable identifier: an `Avatar` or icon, a Title Case label, then sentence-case secondary metadata (`Member since Mar 14, 2026`).” (https://vercel.com/geist/entity)
|
|
261
|
+
* Ours: the name is the record's own and the labels around it are sentence case, not Title Case.
|
|
262
|
+
* “Keep right-column buttons Verb + Noun (`Remove Member`, `Resend Invite`). Bare verbs like `Remove` or `Confirm` lose context once the row scrolls offscreen.” (https://vercel.com/geist/entity)
|
|
263
|
+
* Ours: every string is the product's: `label` names the list, a time's `phrase` writes its sentence ("Updated {when}"), `missing` is what a screen reader hears for a record with no time, the menu's `label` reads "More for {record}". A row command names its result in sentence case ("Edit domain"). A status is the exception's word ("Needs attention"), never "Active" on every row.
|
|
264
|
+
* @access “Wrap the loading region in `aria-busy="true"` and announce completion with `aria-live="polite"` on the destination container, not the skeleton itself.” (https://vercel.com/geist/skeleton)
|
|
265
|
+
* Ours: the loading rows sit in one `SkeletonRegion` that is busy while they stand and announces what replaces them. A table named by `label`, its column headings read by assistive technology only. The row link carries `open.label`; the three dots carry the menu's `label`, and the menu's first line names the record. The loading rows are a status named by `loadingLabel`, inside the one live region that announces what replaces them.
|
|
266
|
+
* “For multi-select rows, the leading `Checkbox` carries `aria-label="Select {entity name}"` so the row is selectable without relying on the visual label.” (https://vercel.com/geist/entity)
|
|
267
|
+
* Ours: each box is named by `select.label`, which reads "Select {record}".
|
|
139
268
|
*/
|
|
140
269
|
export function RecordList(props) {
|
|
141
270
|
const { records, heading, footer } = props;
|
|
271
|
+
const loading = !props.failed && records === undefined;
|
|
142
272
|
let body;
|
|
143
273
|
if (props.failed) {
|
|
144
274
|
body = _jsx(EmptyState, { ...props.failed, scope: "card" });
|
|
@@ -157,5 +287,5 @@ export function RecordList(props) {
|
|
|
157
287
|
else {
|
|
158
288
|
body = _jsx(RecordRows, { ...props, records: records });
|
|
159
289
|
}
|
|
160
|
-
return (_jsx(TableCard, { actions: heading?.meta ? (_jsx("span", { className: "text-body-sm text-muted-foreground", children: heading.meta })) : undefined, footer: footer?.pages ? _jsx(Pages, { pages: footer.pages }) : undefined, footerHint: footer?.count, description: heading?.description, title: heading?.title, children: _jsx(ShownList.Provider, { value: props, children: body }) }));
|
|
290
|
+
return (_jsx(TableCard, { actions: heading?.meta ? (_jsx("span", { className: "text-body-sm text-muted-foreground", children: heading.meta })) : undefined, footer: footer?.pages && (footer.pages.onPrevious || footer.pages.onNext) ? (_jsx(Pages, { pages: footer.pages })) : undefined, footerHint: footer?.count, note: footer?.note, description: heading?.description, title: heading?.title, children: _jsx(ShownList.Provider, { value: props, children: _jsx(SkeletonRegion, { busy: loading, children: body }) }) }));
|
|
161
291
|
}
|