@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
|
@@ -10,10 +10,27 @@ export type ConfirmDialogProps = {
|
|
|
10
10
|
description: ReactNode;
|
|
11
11
|
/** Repeats the verb and the noun: "Remove mailbox". */
|
|
12
12
|
confirmLabel: string;
|
|
13
|
+
/** The confirm's word while the action runs, its label in the -ing form: "Removing mailbox". */
|
|
13
14
|
confirmPendingLabel?: string;
|
|
14
15
|
cancelLabel: string;
|
|
15
16
|
destructive?: boolean;
|
|
17
|
+
/** The action is running: both buttons hold and the field turns read-only. */
|
|
16
18
|
loading?: boolean;
|
|
19
|
+
/**
|
|
20
|
+
* The person must type `phrase` exactly before the confirm enables. The phrase is the record's
|
|
21
|
+
* own name; `prompt` is the sentence that asks for it and names the field, with the phrase in
|
|
22
|
+
* it, which is set in bold: "To confirm, type the mailbox address pec@acme.it".
|
|
23
|
+
*/
|
|
24
|
+
verify?: {
|
|
25
|
+
phrase: string;
|
|
26
|
+
prompt: string;
|
|
27
|
+
};
|
|
28
|
+
/**
|
|
29
|
+
* What cannot be undone, as a sentence naming the action and the record and ending in
|
|
30
|
+
* "cannot be undone": "Removing pec@acme.it cannot be undone." Drawn as a red note above the
|
|
31
|
+
* field. Left out when the action can be reversed: its absence is what says so.
|
|
32
|
+
*/
|
|
33
|
+
irreversible?: string;
|
|
17
34
|
/**
|
|
18
35
|
* Why the confirmed action did not happen, from the product's catalogue,
|
|
19
36
|
* with the message's own actions, such as signing in, under it.
|
|
@@ -24,11 +41,11 @@ export type ConfirmDialogProps = {
|
|
|
24
41
|
* A consequence confirmed before it happens, in a blocking alert dialog.
|
|
25
42
|
*
|
|
26
43
|
* @family Compositions
|
|
27
|
-
* @when
|
|
28
|
-
* @instead
|
|
29
|
-
* @behaviour The
|
|
30
|
-
* @words
|
|
31
|
-
* @access `role="alertdialog"` named by its title and described by its consequence;
|
|
44
|
+
* @when "Reach for this over `Modal` when the action is destructive and warrants friction: delete, rotate, revoke, disconnect, downgrade, disable a security setting. The typed gate forces deliberate intent." (https://vercel.com/geist/destructive-action-modal) "Use it for reversible destructive actions too, when the consequence is serious enough to warrant a pause — disabling deployment protection, revoking a shared token. Keep the typed gate; drop `irreversibleDescription`." (https://vercel.com/geist/destructive-action-modal) "For high-stakes destructive actions (delete production resource, rotate signing key, downgrade plan), gate the primary button on a typed match of the resource name." (https://vercel.com/geist/modal) Ours: `ConfirmDialog` is Geist's DestructiveActionModal: remove a mailbox, delete an Agent, with `verify` as the typed gate.
|
|
45
|
+
* @instead "Don't use for routine confirmations (save draft, discard changes, close without saving). The typed gate reads as melodrama when the stakes are low — use a plain `Modal` instead." (https://vercel.com/geist/destructive-action-modal) "Confirm destructive actions in a Modal. `Drawer` and `Sheet` don’t fully dim the page, so they read as too soft for a delete or revoke." (https://vercel.com/geist/modal) Ours: an action that can be undone runs at once and offers its undo in a toast; a form of a few fields is a `FormDialog`; a choice from a catalogue is a `CatalogDrawer`.
|
|
46
|
+
* @behaviour "The verification input gets focus on open so the user can start typing immediately. Submit stays disabled until the value matches `verificationPhrase` exactly." (https://vercel.com/geist/destructive-action-modal) "Enter submits only when the gate is open; it's a no-op otherwise. Cancel, outside-click, and Escape all dismiss." (https://vercel.com/geist/destructive-action-modal) "`loading` disables both buttons. The caller owns `open` — do not self-dismiss from `onConfirm`. Close the modal after the API settles (success or error), or keep it open on error so the user can retry." (https://vercel.com/geist/destructive-action-modal) "Default focus to `Cancel` on any destructive Modal. Enter must never trigger the destructive action without a typed confirmation." (https://vercel.com/geist/modal) "Allow Escape and outside-click to dismiss non-destructive Modals; gate dismissal on destructive ones with unsaved input." (https://vercel.com/geist/modal) Ours: `title`, `description`, `confirmLabel` and `cancelLabel` are required; `irreversible` and `verify` are optional, and the absence of `irreversible` is what marks the action reversible. Geist's `irreversibleDescription` is `irreversible`, `verificationPhrase` and `verificationLabel` are `verify.phrase` and `verify.prompt`, and `error` is the catalogue's message. 480 px wide over a scrim. The title and the description, then the body in a 24 px column: the `irreversible` note, the `verify` field, the failure under it. `irreversible` is a flat red note with a red mark and red words, not a band over the footer; besides it the only red is the failure and the enabled destructive confirm. While `loading` the field turns read-only and keeps focus, Escape does not close it, and the confirm says `confirmPendingLabel`, which falls back to the confirm's label. A press outside does not close it, so a stray click never discards a typed phrase or an action in flight; Escape and Cancel do. The footer is a bar that stays at the bottom while a tall confirmation scrolls, and a row on a phone too.
|
|
47
|
+
* @words "`title` is Title Case, `Verb + Noun`, a statement — never a question. `Delete Project`, not `Delete this project?`." (https://vercel.com/geist/destructive-action-modal) "`description` is sentence case, names the consequence, and interpolates the specific resource when relevant. `<b>my-project</b> and all its deployments will be permanently deleted.` reads stronger than `This project and all its deployments will be deleted.`." (https://vercel.com/geist/destructive-action-modal) "`confirmLabel` matches the title 1:1. Never generic (`Confirm`, `OK`, `Continue`), never a bare verb (`Delete`)." (https://vercel.com/geist/destructive-action-modal) "`cancelLabel` defaults to `Cancel`. Override when Cancel is ambiguous, such as `Keep Turn Running` when the primary action is itself a cancellation." (https://vercel.com/geist/destructive-action-modal) "`verificationPhrase`: for entity deletes, type the **resource name itself** (`my-project`) and pair with `verificationLabel="project name"` so the prompt reads `To confirm, type the project name "my-project"`. That's the canonical signal that the user knows which thing they're acting on. Fall back to a lowercase verb phrase (`disable vercel authentication`) only when there's no entity to name." (https://vercel.com/geist/destructive-action-modal) "`irreversibleDescription` names the specific action and resource and ends with `cannot be undone.` — `Deleting my-project cannot be undone.` rather than the generic `This cannot be undone.`. Omit the prop entirely for reversible actions; the prop's absence is the signal, not a falsy value." (https://vercel.com/geist/destructive-action-modal) "`error` surfaces the API failure verbatim in Vercel voice: `Couldn't save settings. Try again.`. Never dump a raw error object." (https://vercel.com/geist/destructive-action-modal) "Pair the post-confirm success toast verb 1:1 with the primary button: `Delete Project` button, `Project deleted` toast. Never `Project removed`." (https://vercel.com/geist/destructive-action-modal) "Close irreversible bodies with `This cannot be undone.`; close cascade-only bodies with `Some effects cannot be undone.`. Don’t claim full irreversibility for a partial cascade." (https://vercel.com/geist/modal) Ours: the title is sentence case and names the record, "Remove pec@acme.it", and the confirm repeats the verb and the noun, "Remove mailbox", so the two share a verb and not every word; its success toast uses the same verb ("Mailbox removed"). The description names the record in medium weight.
|
|
48
|
+
* @access "The verification input is associated with its prompt via `aria-labelledby` + `htmlFor`. Screen readers announce the full prompt (`To confirm, type "delete my-project"`) on focus." (https://vercel.com/geist/destructive-action-modal) "The Warning icon in the irreversibility band is `aria-hidden`; the sentence carries the meaning so nothing is announced twice." (https://vercel.com/geist/destructive-action-modal) "Focus stays inside the modal across an `error` transition so the user can retry without losing context. After success, return focus to the trigger." (https://vercel.com/geist/destructive-action-modal) "Set `aria-labelledby` to the `Modal.Title` id so screen readers announce the title on open." (https://vercel.com/geist/modal) "Keep the Cancel button literally `Cancel` so screen-reader users hear a stable dismissal label across destructive flows." (https://vercel.com/geist/modal) Ours: `role="alertdialog"` named by its title and described by its consequence; the note is `role="note"` with its icon hidden. Focus starts on Cancel, or in the field with `verify`.
|
|
32
49
|
*/
|
|
33
|
-
export declare function ConfirmDialog({ open, onConfirm, onCancel, title, description, confirmLabel, confirmPendingLabel, cancelLabel, destructive, loading, error, }: ConfirmDialogProps): import("react").JSX.Element;
|
|
50
|
+
export declare function ConfirmDialog({ open, onConfirm, onCancel, title, description, confirmLabel, confirmPendingLabel, cancelLabel, destructive, loading, verify, irreversible, error, }: ConfirmDialogProps): import("react").JSX.Element;
|
|
34
51
|
//# sourceMappingURL=confirm-dialog.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"confirm-dialog.d.ts","sourceRoot":"","sources":["../../src/components/confirm-dialog.tsx"],"names":[],"mappings":"AAEA,OAAO,EAAE,KAAK,SAAS,
|
|
1
|
+
{"version":3,"file":"confirm-dialog.d.ts","sourceRoot":"","sources":["../../src/components/confirm-dialog.tsx"],"names":[],"mappings":"AAEA,OAAO,EAAE,KAAK,SAAS,EAA2C,MAAM,OAAO,CAAC;AAgBhF,OAAO,EAAmB,KAAK,eAAe,EAAE,MAAM,8BAA8B,CAAC;AAErF,MAAM,MAAM,kBAAkB,GAAG;IAC/B,IAAI,EAAE,OAAO,CAAC;IACd,SAAS,EAAE,MAAM,IAAI,CAAC;IACtB,QAAQ,EAAE,MAAM,IAAI,CAAC;IACrB,gFAAgF;IAChF,KAAK,EAAE,MAAM,CAAC;IACd,uBAAuB;IACvB,WAAW,EAAE,SAAS,CAAC;IACvB,uDAAuD;IACvD,YAAY,EAAE,MAAM,CAAC;IACrB,gGAAgG;IAChG,mBAAmB,CAAC,EAAE,MAAM,CAAC;IAC7B,WAAW,EAAE,MAAM,CAAC;IACpB,WAAW,CAAC,EAAE,OAAO,CAAC;IACtB,8EAA8E;IAC9E,OAAO,CAAC,EAAE,OAAO,CAAC;IAClB;;;;OAIG;IACH,MAAM,CAAC,EAAE;QAAE,MAAM,EAAE,MAAM,CAAC;QAAC,MAAM,EAAE,MAAM,CAAA;KAAE,CAAC;IAC5C;;;;OAIG;IACH,YAAY,CAAC,EAAE,MAAM,CAAC;IACtB;;;OAGG;IACH,KAAK,CAAC,EAAE,eAAe,GAAG,IAAI,CAAC;CAChC,CAAC;AAEF;;;;;;;;;GASG;AACH,wBAAgB,aAAa,CAAC,EAC5B,IAAI,EACJ,SAAS,EACT,QAAQ,EACR,KAAK,EACL,WAAW,EACX,YAAY,EACZ,mBAAmB,EACnB,WAAW,EACX,WAAmB,EACnB,OAAe,EACf,MAAM,EACN,YAAY,EACZ,KAAK,GACN,EAAE,kBAAkB,+BAgCpB"}
|
|
@@ -1,27 +1,46 @@
|
|
|
1
1
|
"use client";
|
|
2
|
-
import { jsx as _jsx,
|
|
3
|
-
import { useRef } from "react";
|
|
4
|
-
import {
|
|
2
|
+
import { jsx as _jsx, jsxs as _jsxs, Fragment as _Fragment } from "react/jsx-runtime";
|
|
3
|
+
import { useId, useRef, useState } from "react";
|
|
4
|
+
import { OctagonAlertIcon } from "lucide-react";
|
|
5
|
+
import { AlertDialog, AlertDialogBody, AlertDialogContent, AlertDialogDescription, AlertDialogFooter, AlertDialogHeader, AlertDialogTitle, } from "./alert-dialog.js";
|
|
5
6
|
import { Button } from "./button.js";
|
|
6
|
-
import { FieldError } from "./field.js";
|
|
7
|
+
import { Field, FieldError, FieldLabel } from "./field.js";
|
|
8
|
+
import { Input } from "./input.js";
|
|
7
9
|
import { PageCommandButton } from "./page-actions.js";
|
|
8
|
-
import { PendingLabel } from "./pending-label.js";
|
|
9
10
|
import { bodyBeyondTitle } from "./product-message.js";
|
|
10
11
|
/**
|
|
11
12
|
* A consequence confirmed before it happens, in a blocking alert dialog.
|
|
12
13
|
*
|
|
13
14
|
* @family Compositions
|
|
14
|
-
* @when
|
|
15
|
-
* @instead
|
|
16
|
-
* @behaviour The
|
|
17
|
-
* @words
|
|
18
|
-
* @access `role="alertdialog"` named by its title and described by its consequence;
|
|
15
|
+
* @when "Reach for this over `Modal` when the action is destructive and warrants friction: delete, rotate, revoke, disconnect, downgrade, disable a security setting. The typed gate forces deliberate intent." (https://vercel.com/geist/destructive-action-modal) "Use it for reversible destructive actions too, when the consequence is serious enough to warrant a pause — disabling deployment protection, revoking a shared token. Keep the typed gate; drop `irreversibleDescription`." (https://vercel.com/geist/destructive-action-modal) "For high-stakes destructive actions (delete production resource, rotate signing key, downgrade plan), gate the primary button on a typed match of the resource name." (https://vercel.com/geist/modal) Ours: `ConfirmDialog` is Geist's DestructiveActionModal: remove a mailbox, delete an Agent, with `verify` as the typed gate.
|
|
16
|
+
* @instead "Don't use for routine confirmations (save draft, discard changes, close without saving). The typed gate reads as melodrama when the stakes are low — use a plain `Modal` instead." (https://vercel.com/geist/destructive-action-modal) "Confirm destructive actions in a Modal. `Drawer` and `Sheet` don’t fully dim the page, so they read as too soft for a delete or revoke." (https://vercel.com/geist/modal) Ours: an action that can be undone runs at once and offers its undo in a toast; a form of a few fields is a `FormDialog`; a choice from a catalogue is a `CatalogDrawer`.
|
|
17
|
+
* @behaviour "The verification input gets focus on open so the user can start typing immediately. Submit stays disabled until the value matches `verificationPhrase` exactly." (https://vercel.com/geist/destructive-action-modal) "Enter submits only when the gate is open; it's a no-op otherwise. Cancel, outside-click, and Escape all dismiss." (https://vercel.com/geist/destructive-action-modal) "`loading` disables both buttons. The caller owns `open` — do not self-dismiss from `onConfirm`. Close the modal after the API settles (success or error), or keep it open on error so the user can retry." (https://vercel.com/geist/destructive-action-modal) "Default focus to `Cancel` on any destructive Modal. Enter must never trigger the destructive action without a typed confirmation." (https://vercel.com/geist/modal) "Allow Escape and outside-click to dismiss non-destructive Modals; gate dismissal on destructive ones with unsaved input." (https://vercel.com/geist/modal) Ours: `title`, `description`, `confirmLabel` and `cancelLabel` are required; `irreversible` and `verify` are optional, and the absence of `irreversible` is what marks the action reversible. Geist's `irreversibleDescription` is `irreversible`, `verificationPhrase` and `verificationLabel` are `verify.phrase` and `verify.prompt`, and `error` is the catalogue's message. 480 px wide over a scrim. The title and the description, then the body in a 24 px column: the `irreversible` note, the `verify` field, the failure under it. `irreversible` is a flat red note with a red mark and red words, not a band over the footer; besides it the only red is the failure and the enabled destructive confirm. While `loading` the field turns read-only and keeps focus, Escape does not close it, and the confirm says `confirmPendingLabel`, which falls back to the confirm's label. A press outside does not close it, so a stray click never discards a typed phrase or an action in flight; Escape and Cancel do. The footer is a bar that stays at the bottom while a tall confirmation scrolls, and a row on a phone too.
|
|
18
|
+
* @words "`title` is Title Case, `Verb + Noun`, a statement — never a question. `Delete Project`, not `Delete this project?`." (https://vercel.com/geist/destructive-action-modal) "`description` is sentence case, names the consequence, and interpolates the specific resource when relevant. `<b>my-project</b> and all its deployments will be permanently deleted.` reads stronger than `This project and all its deployments will be deleted.`." (https://vercel.com/geist/destructive-action-modal) "`confirmLabel` matches the title 1:1. Never generic (`Confirm`, `OK`, `Continue`), never a bare verb (`Delete`)." (https://vercel.com/geist/destructive-action-modal) "`cancelLabel` defaults to `Cancel`. Override when Cancel is ambiguous, such as `Keep Turn Running` when the primary action is itself a cancellation." (https://vercel.com/geist/destructive-action-modal) "`verificationPhrase`: for entity deletes, type the **resource name itself** (`my-project`) and pair with `verificationLabel="project name"` so the prompt reads `To confirm, type the project name "my-project"`. That's the canonical signal that the user knows which thing they're acting on. Fall back to a lowercase verb phrase (`disable vercel authentication`) only when there's no entity to name." (https://vercel.com/geist/destructive-action-modal) "`irreversibleDescription` names the specific action and resource and ends with `cannot be undone.` — `Deleting my-project cannot be undone.` rather than the generic `This cannot be undone.`. Omit the prop entirely for reversible actions; the prop's absence is the signal, not a falsy value." (https://vercel.com/geist/destructive-action-modal) "`error` surfaces the API failure verbatim in Vercel voice: `Couldn't save settings. Try again.`. Never dump a raw error object." (https://vercel.com/geist/destructive-action-modal) "Pair the post-confirm success toast verb 1:1 with the primary button: `Delete Project` button, `Project deleted` toast. Never `Project removed`." (https://vercel.com/geist/destructive-action-modal) "Close irreversible bodies with `This cannot be undone.`; close cascade-only bodies with `Some effects cannot be undone.`. Don’t claim full irreversibility for a partial cascade." (https://vercel.com/geist/modal) Ours: the title is sentence case and names the record, "Remove pec@acme.it", and the confirm repeats the verb and the noun, "Remove mailbox", so the two share a verb and not every word; its success toast uses the same verb ("Mailbox removed"). The description names the record in medium weight.
|
|
19
|
+
* @access "The verification input is associated with its prompt via `aria-labelledby` + `htmlFor`. Screen readers announce the full prompt (`To confirm, type "delete my-project"`) on focus." (https://vercel.com/geist/destructive-action-modal) "The Warning icon in the irreversibility band is `aria-hidden`; the sentence carries the meaning so nothing is announced twice." (https://vercel.com/geist/destructive-action-modal) "Focus stays inside the modal across an `error` transition so the user can retry without losing context. After success, return focus to the trigger." (https://vercel.com/geist/destructive-action-modal) "Set `aria-labelledby` to the `Modal.Title` id so screen readers announce the title on open." (https://vercel.com/geist/modal) "Keep the Cancel button literally `Cancel` so screen-reader users hear a stable dismissal label across destructive flows." (https://vercel.com/geist/modal) Ours: `role="alertdialog"` named by its title and described by its consequence; the note is `role="note"` with its icon hidden. Focus starts on Cancel, or in the field with `verify`.
|
|
19
20
|
*/
|
|
20
|
-
export function ConfirmDialog({ open, onConfirm, onCancel, title, description, confirmLabel, confirmPendingLabel, cancelLabel, destructive = false, loading = false, error, }) {
|
|
21
|
+
export function ConfirmDialog({ open, onConfirm, onCancel, title, description, confirmLabel, confirmPendingLabel, cancelLabel, destructive = false, loading = false, verify, irreversible, error, }) {
|
|
21
22
|
const cancel = useRef(null);
|
|
22
|
-
const
|
|
23
|
+
const phraseField = useRef(null);
|
|
23
24
|
return (_jsx(AlertDialog, { open: open, onOpenChange: (nextOpen) => {
|
|
24
25
|
if (!nextOpen && !loading)
|
|
25
26
|
onCancel();
|
|
26
|
-
}, children: _jsxs(AlertDialogContent, { initialFocus: cancel, children: [_jsxs(AlertDialogHeader, { children: [_jsx(AlertDialogTitle, { children: title }), _jsx(AlertDialogDescription, { children: description })
|
|
27
|
+
}, children: _jsxs(AlertDialogContent, { initialFocus: verify ? phraseField : cancel, children: [_jsxs(AlertDialogHeader, { children: [_jsx(AlertDialogTitle, { children: title }), _jsx(AlertDialogDescription, { children: description })] }), _jsx(ConfirmDialogPanel, { cancel: cancel, cancelLabel: cancelLabel, confirmLabel: confirmLabel, confirmPendingLabel: confirmPendingLabel, destructive: destructive, error: error, irreversible: irreversible, loading: loading, onCancel: onCancel, onConfirm: onConfirm, phraseField: phraseField, verify: verify })] }) }));
|
|
28
|
+
}
|
|
29
|
+
function ConfirmDialogPanel({ cancel, phraseField, onConfirm, onCancel, confirmLabel, confirmPendingLabel, cancelLabel, destructive = false, loading = false, verify, irreversible, error, }) {
|
|
30
|
+
const [typed, setTyped] = useState("");
|
|
31
|
+
const phraseId = useId();
|
|
32
|
+
const phraseLabelId = useId();
|
|
33
|
+
const errorBody = error ? bodyBeyondTitle(error) : null;
|
|
34
|
+
const confirmable = verify === undefined || typed === verify.phrase;
|
|
35
|
+
const hasBody = Boolean(irreversible || verify || error);
|
|
36
|
+
return (_jsxs(_Fragment, { children: [hasBody ? (_jsxs(AlertDialogBody, { children: [irreversible ? (_jsxs("p", { className: "flex items-start gap-3 rounded-sm border border-destructive/15 bg-destructive-soft px-nadicode-sm py-1.5 text-body-sm text-destructive-soft-foreground", "data-slot": "confirm-dialog-irreversible", role: "note", children: [_jsx(OctagonAlertIcon, { "aria-hidden": "true", className: "h-5 w-3.5 shrink-0" }), irreversible] })) : null, verify ? (_jsxs(Field, { children: [_jsx(FieldLabel, { className: "text-label leading-5 text-foreground", htmlFor: phraseId, id: phraseLabelId, children: _jsx(VerifyPrompt, { phrase: verify.phrase, prompt: verify.prompt }) }), _jsx(Input, { "aria-labelledby": phraseLabelId, autoCapitalize: "none", autoComplete: "off", id: phraseId, onChange: (event) => setTyped(event.target.value), onKeyDown: (event) => {
|
|
37
|
+
if (event.key === "Enter" && confirmable && !loading)
|
|
38
|
+
onConfirm();
|
|
39
|
+
}, readOnly: loading, ref: phraseField, spellCheck: false, value: typed })] })) : null, error ? (_jsxs(FieldError, { className: "text-body-sm break-words", "data-message-code": error.code, children: [_jsx("span", { className: "block", children: error.title }), errorBody ? (_jsxs(_Fragment, { children: [" ", _jsx("span", { className: "block", children: errorBody })] })) : null] })) : null, error?.actions.length ? (_jsx("div", { className: "flex flex-wrap items-center gap-2", "data-message-actions": true, children: error.actions.map((action) => (_jsx(PageCommandButton, { command: action, variant: "outline" }, action.label))) })) : null] })) : null, _jsxs(AlertDialogFooter, { children: [_jsx(Button, { disabled: loading, onClick: onCancel, ref: cancel, variant: "outline", children: cancelLabel }), _jsx(Button, { disabled: !confirmable, loading: loading, loadingLabel: confirmPendingLabel ?? confirmLabel, onClick: onConfirm, variant: destructive ? "destructive" : "default", children: confirmLabel })] })] }));
|
|
40
|
+
}
|
|
41
|
+
function VerifyPrompt({ phrase, prompt }) {
|
|
42
|
+
const at = prompt.indexOf(phrase);
|
|
43
|
+
if (at < 0)
|
|
44
|
+
return prompt;
|
|
45
|
+
return (_jsxs("span", { children: [prompt.slice(0, at), _jsx("strong", { className: "font-semibold", children: phrase }), prompt.slice(at + phrase.length)] }));
|
|
27
46
|
}
|
|
@@ -1,32 +1,36 @@
|
|
|
1
1
|
import * as React from "react";
|
|
2
2
|
import { ContextMenu as ContextMenuPrimitive } from "@base-ui/react/context-menu";
|
|
3
|
-
import { DropdownMenuCheckboxItem, DropdownMenuGroup, DropdownMenuItem, DropdownMenuLabel, DropdownMenuRadioGroup, DropdownMenuRadioItem, DropdownMenuSeparator, DropdownMenuShortcut, DropdownMenuSub, DropdownMenuSubTrigger } from "./dropdown-menu.js";
|
|
3
|
+
import { DropdownMenuCheckboxItem, DropdownMenuGroup, DropdownMenuItem, DropdownMenuLabel, DropdownMenuLink, DropdownMenuRadioGroup, DropdownMenuRadioItem, DropdownMenuSeparator, DropdownMenuShortcut, DropdownMenuSub, DropdownMenuSubTrigger } from "./dropdown-menu.js";
|
|
4
4
|
/**
|
|
5
|
-
* A menu that opens at the pointer on a right-click, from the dropdown's own parts.
|
|
5
|
+
* A menu that opens at the pointer on a right-click or a long press, from the dropdown's own parts.
|
|
6
6
|
*
|
|
7
7
|
* @family Menus
|
|
8
|
-
* @when
|
|
9
|
-
* @instead A record's right-click is `ActionContextMenu`, from the same data as its `ActionMenu`.
|
|
10
|
-
* @behaviour
|
|
11
|
-
* @words Identical to the visible menu's, in the same order; a command reached two ways reads the same both ways.
|
|
12
|
-
* @access
|
|
8
|
+
* @when "Use ContextMenu for power-user shortcuts on right-click or long-press over a row, file, or canvas object." (https://vercel.com/geist/context-menu) "ContextMenu must never be the only entry point for an action. Mirror every item in a visible `Menu` trigger or row button so mouse-only and keyboard-only users have parity." (https://vercel.com/geist/context-menu) Ours: a right-click on a canvas or a surface no record owns, whose commands are also reachable another way.
|
|
9
|
+
* @instead "For a global command palette, use `CommandMenu`; for a dropdown opened from a visible trigger, use `Menu`." (https://vercel.com/geist/context-menu) Ours: those are `CommandDialog` and `DropdownMenu`. A record's right-click is `ActionContextMenu`, from the same data as its `ActionMenu`.
|
|
10
|
+
* @behaviour "Bind to right-click on desktop and long-press on touch. Suppress the native browser menu only on the trigger area, not the whole page." (https://vercel.com/geist/context-menu) "Position the menu at the pointer; if it would overflow the viewport, flip horizontally then vertically before clipping." (https://vercel.com/geist/context-menu) "Close on activation, Escape, and outside-click. Don’t close on hover-out." (https://vercel.com/geist/context-menu) Ours: the dropdown's surface and rows exactly, 160 px wide at least, opening 2 px right of the pointer and appearing at once, with no entry motion. A row that cannot be chosen keeps its place with its text muted, never dimmed. Destructive last, after a divider.
|
|
11
|
+
* @words "Items follow the same rules as `Menu`: Title Case `Verb + Noun` (`Open in New Tab`, `Copy URL`, `Delete Deployment`). Bare verbs are wrong." (https://vercel.com/geist/context-menu) "End with `…` only when activating opens a follow-up dialog (`Rename…`, `Move to Folder…`)." (https://vercel.com/geist/context-menu) "Group destructive items at the bottom with a divider and keep the destructive label `Verb + Noun`. `Delete` alone never ships." (https://vercel.com/geist/context-menu) Ours: sentence case, "Copy address", not Title Case. Identical to the visible menu's, in the same order; a command reached two ways reads the same both ways.
|
|
12
|
+
* @access "Trigger the keyboard menu key (`Shift+F10` on Windows/Linux, the menu key, or platform equivalent) to open the same menu without right-click." (https://vercel.com/geist/context-menu) "Up/Down arrows move focus, Enter/Space activates, Escape closes and returns focus to the row." (https://vercel.com/geist/context-menu) "Don’t bury destructive items behind nested submenus. One level deep keeps keyboard navigation predictable." (https://vercel.com/geist/context-menu) Ours: the trigger must itself be focusable or hold something that is. The content requires an `aria-label` naming the menu, because nothing visible labels a menu opened at the pointer.
|
|
13
13
|
*/
|
|
14
14
|
declare function ContextMenu({ ...props }: ContextMenuPrimitive.Root.Props): React.JSX.Element;
|
|
15
15
|
declare function ContextMenuPortal({ ...props }: ContextMenuPrimitive.Portal.Props): React.JSX.Element;
|
|
16
16
|
declare function ContextMenuTrigger({ className, ...props }: ContextMenuPrimitive.Trigger.Props): React.JSX.Element;
|
|
17
|
-
|
|
17
|
+
type ContextMenuPopupProps = ContextMenuPrimitive.Popup.Props & Pick<ContextMenuPrimitive.Positioner.Props, "align" | "alignOffset" | "side" | "sideOffset"> & {
|
|
18
18
|
density?: "compact" | "comfortable";
|
|
19
|
+
};
|
|
20
|
+
declare function ContextMenuContent({ "aria-label": name, ...props }: Omit<ContextMenuPopupProps, "aria-label"> & {
|
|
21
|
+
"aria-label": string;
|
|
19
22
|
}): React.JSX.Element;
|
|
20
23
|
declare function ContextMenuGroup(props: React.ComponentProps<typeof DropdownMenuGroup>): React.JSX.Element;
|
|
21
24
|
declare function ContextMenuLabel(props: React.ComponentProps<typeof DropdownMenuLabel>): React.JSX.Element;
|
|
22
25
|
declare function ContextMenuItem(props: React.ComponentProps<typeof DropdownMenuItem>): React.JSX.Element;
|
|
26
|
+
declare function ContextMenuLink(props: React.ComponentProps<typeof DropdownMenuLink>): React.JSX.Element;
|
|
23
27
|
declare function ContextMenuSub(props: React.ComponentProps<typeof DropdownMenuSub>): React.JSX.Element;
|
|
24
28
|
declare function ContextMenuSubTrigger(props: React.ComponentProps<typeof DropdownMenuSubTrigger>): React.JSX.Element;
|
|
25
|
-
declare function ContextMenuSubContent({ className, ...props }:
|
|
29
|
+
declare function ContextMenuSubContent({ className, ...props }: ContextMenuPopupProps): React.JSX.Element;
|
|
26
30
|
declare function ContextMenuCheckboxItem(props: React.ComponentProps<typeof DropdownMenuCheckboxItem>): React.JSX.Element;
|
|
27
31
|
declare function ContextMenuRadioGroup(props: React.ComponentProps<typeof DropdownMenuRadioGroup>): React.JSX.Element;
|
|
28
32
|
declare function ContextMenuRadioItem(props: React.ComponentProps<typeof DropdownMenuRadioItem>): React.JSX.Element;
|
|
29
33
|
declare function ContextMenuSeparator(props: React.ComponentProps<typeof DropdownMenuSeparator>): React.JSX.Element;
|
|
30
34
|
declare function ContextMenuShortcut(props: React.ComponentProps<typeof DropdownMenuShortcut>): React.JSX.Element;
|
|
31
|
-
export { ContextMenu, ContextMenuTrigger, ContextMenuContent, ContextMenuItem, ContextMenuCheckboxItem, ContextMenuRadioItem, ContextMenuLabel, ContextMenuSeparator, ContextMenuShortcut, ContextMenuGroup, ContextMenuPortal, ContextMenuSub, ContextMenuSubContent, ContextMenuSubTrigger, ContextMenuRadioGroup, };
|
|
35
|
+
export { ContextMenu, ContextMenuTrigger, ContextMenuContent, ContextMenuItem, ContextMenuLink, ContextMenuCheckboxItem, ContextMenuRadioItem, ContextMenuLabel, ContextMenuSeparator, ContextMenuShortcut, ContextMenuGroup, ContextMenuPortal, ContextMenuSub, ContextMenuSubContent, ContextMenuSubTrigger, ContextMenuRadioGroup, };
|
|
32
36
|
//# sourceMappingURL=context-menu.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"context-menu.d.ts","sourceRoot":"","sources":["../../src/components/context-menu.tsx"],"names":[],"mappings":"AAEA,OAAO,KAAK,KAAK,MAAM,OAAO,CAAC;AAC/B,OAAO,EAAE,WAAW,IAAI,oBAAoB,EAAE,MAAM,6BAA6B,CAAC;
|
|
1
|
+
{"version":3,"file":"context-menu.d.ts","sourceRoot":"","sources":["../../src/components/context-menu.tsx"],"names":[],"mappings":"AAEA,OAAO,KAAK,KAAK,MAAM,OAAO,CAAC;AAC/B,OAAO,EAAE,WAAW,IAAI,oBAAoB,EAAE,MAAM,6BAA6B,CAAC;AAIlF,OAAO,EACL,wBAAwB,EACxB,iBAAiB,EACjB,gBAAgB,EAChB,iBAAiB,EACjB,gBAAgB,EAChB,sBAAsB,EACtB,qBAAqB,EACrB,qBAAqB,EACrB,oBAAoB,EACpB,eAAe,EACf,sBAAsB,EACvB,MAAM,4BAA4B,CAAC;AAKpC;;;;;;;;;GASG;AACH,iBAAS,WAAW,CAAC,EAAE,GAAG,KAAK,EAAE,EAAE,oBAAoB,CAAC,IAAI,CAAC,KAAK,qBAEjE;AAED,iBAAS,iBAAiB,CAAC,EAAE,GAAG,KAAK,EAAE,EAAE,oBAAoB,CAAC,MAAM,CAAC,KAAK,qBAEzE;AAED,iBAAS,kBAAkB,CAAC,EAAE,SAAS,EAAE,GAAG,KAAK,EAAE,EAAE,oBAAoB,CAAC,OAAO,CAAC,KAAK,qBAQtF;AAED,KAAK,qBAAqB,GAAG,oBAAoB,CAAC,KAAK,CAAC,KAAK,GAC3D,IAAI,CAAC,oBAAoB,CAAC,UAAU,CAAC,KAAK,EAAE,OAAO,GAAG,aAAa,GAAG,MAAM,GAAG,YAAY,CAAC,GAAG;IAC7F,OAAO,CAAC,EAAE,SAAS,GAAG,aAAa,CAAC;CACrC,CAAC;AAqCJ,iBAAS,kBAAkB,CAAC,EAC1B,YAAY,EAAE,IAAI,EAClB,GAAG,KAAK,EACT,EAAE,IAAI,CAAC,qBAAqB,EAAE,YAAY,CAAC,GAAG;IAAE,YAAY,EAAE,MAAM,CAAA;CAAE,qBAEtE;AAED,iBAAS,gBAAgB,CAAC,KAAK,EAAE,KAAK,CAAC,cAAc,CAAC,OAAO,iBAAiB,CAAC,qBAE9E;AAED,iBAAS,gBAAgB,CAAC,KAAK,EAAE,KAAK,CAAC,cAAc,CAAC,OAAO,iBAAiB,CAAC,qBAE9E;AAED,iBAAS,eAAe,CAAC,KAAK,EAAE,KAAK,CAAC,cAAc,CAAC,OAAO,gBAAgB,CAAC,qBAE5E;AAED,iBAAS,eAAe,CAAC,KAAK,EAAE,KAAK,CAAC,cAAc,CAAC,OAAO,gBAAgB,CAAC,qBAE5E;AAED,iBAAS,cAAc,CAAC,KAAK,EAAE,KAAK,CAAC,cAAc,CAAC,OAAO,eAAe,CAAC,qBAE1E;AAED,iBAAS,qBAAqB,CAAC,KAAK,EAAE,KAAK,CAAC,cAAc,CAAC,OAAO,sBAAsB,CAAC,qBAExF;AAED,iBAAS,qBAAqB,CAAC,EAAE,SAAS,EAAE,GAAG,KAAK,EAAE,EAAE,qBAAqB,qBAS5E;AAED,iBAAS,uBAAuB,CAAC,KAAK,EAAE,KAAK,CAAC,cAAc,CAAC,OAAO,wBAAwB,CAAC,qBAE5F;AAED,iBAAS,qBAAqB,CAAC,KAAK,EAAE,KAAK,CAAC,cAAc,CAAC,OAAO,sBAAsB,CAAC,qBAExF;AAED,iBAAS,oBAAoB,CAAC,KAAK,EAAE,KAAK,CAAC,cAAc,CAAC,OAAO,qBAAqB,CAAC,qBAEtF;AAED,iBAAS,oBAAoB,CAAC,KAAK,EAAE,KAAK,CAAC,cAAc,CAAC,OAAO,qBAAqB,CAAC,qBAEtF;AAED,iBAAS,mBAAmB,CAAC,KAAK,EAAE,KAAK,CAAC,cAAc,CAAC,OAAO,oBAAoB,CAAC,qBAEpF;AAED,OAAO,EACL,WAAW,EACX,kBAAkB,EAClB,kBAAkB,EAClB,eAAe,EACf,eAAe,EACf,uBAAuB,EACvB,oBAAoB,EACpB,gBAAgB,EAChB,oBAAoB,EACpB,mBAAmB,EACnB,gBAAgB,EAChB,iBAAiB,EACjB,cAAc,EACd,qBAAqB,EACrB,qBAAqB,EACrB,qBAAqB,GACtB,CAAC"}
|
|
@@ -2,20 +2,19 @@
|
|
|
2
2
|
import { jsx as _jsx } from "react/jsx-runtime";
|
|
3
3
|
import { ContextMenu as ContextMenuPrimitive } from "@base-ui/react/context-menu";
|
|
4
4
|
import { cn } from "../lib/utils.js";
|
|
5
|
-
import { anchoredOverlayMotion } from "../lib/motion.js";
|
|
6
5
|
import { menuSurface } from "../internal/menu-surface.js";
|
|
7
|
-
import { DropdownMenuCheckboxItem, DropdownMenuGroup, DropdownMenuItem, DropdownMenuLabel, DropdownMenuRadioGroup, DropdownMenuRadioItem, DropdownMenuSeparator, DropdownMenuShortcut, DropdownMenuSub, DropdownMenuSubTrigger, } from "./dropdown-menu.js";
|
|
6
|
+
import { DropdownMenuCheckboxItem, DropdownMenuGroup, DropdownMenuItem, DropdownMenuLabel, DropdownMenuLink, DropdownMenuRadioGroup, DropdownMenuRadioItem, DropdownMenuSeparator, DropdownMenuShortcut, DropdownMenuSub, DropdownMenuSubTrigger, } from "./dropdown-menu.js";
|
|
8
7
|
// A context menu's items are Base UI's menu items, so every part below the popup is the dropdown's own: the two
|
|
9
8
|
// menus cannot drift apart in their rows, only in how they open.
|
|
10
9
|
/**
|
|
11
|
-
* A menu that opens at the pointer on a right-click, from the dropdown's own parts.
|
|
10
|
+
* A menu that opens at the pointer on a right-click or a long press, from the dropdown's own parts.
|
|
12
11
|
*
|
|
13
12
|
* @family Menus
|
|
14
|
-
* @when
|
|
15
|
-
* @instead A record's right-click is `ActionContextMenu`, from the same data as its `ActionMenu`.
|
|
16
|
-
* @behaviour
|
|
17
|
-
* @words Identical to the visible menu's, in the same order; a command reached two ways reads the same both ways.
|
|
18
|
-
* @access
|
|
13
|
+
* @when "Use ContextMenu for power-user shortcuts on right-click or long-press over a row, file, or canvas object." (https://vercel.com/geist/context-menu) "ContextMenu must never be the only entry point for an action. Mirror every item in a visible `Menu` trigger or row button so mouse-only and keyboard-only users have parity." (https://vercel.com/geist/context-menu) Ours: a right-click on a canvas or a surface no record owns, whose commands are also reachable another way.
|
|
14
|
+
* @instead "For a global command palette, use `CommandMenu`; for a dropdown opened from a visible trigger, use `Menu`." (https://vercel.com/geist/context-menu) Ours: those are `CommandDialog` and `DropdownMenu`. A record's right-click is `ActionContextMenu`, from the same data as its `ActionMenu`.
|
|
15
|
+
* @behaviour "Bind to right-click on desktop and long-press on touch. Suppress the native browser menu only on the trigger area, not the whole page." (https://vercel.com/geist/context-menu) "Position the menu at the pointer; if it would overflow the viewport, flip horizontally then vertically before clipping." (https://vercel.com/geist/context-menu) "Close on activation, Escape, and outside-click. Don’t close on hover-out." (https://vercel.com/geist/context-menu) Ours: the dropdown's surface and rows exactly, 160 px wide at least, opening 2 px right of the pointer and appearing at once, with no entry motion. A row that cannot be chosen keeps its place with its text muted, never dimmed. Destructive last, after a divider.
|
|
16
|
+
* @words "Items follow the same rules as `Menu`: Title Case `Verb + Noun` (`Open in New Tab`, `Copy URL`, `Delete Deployment`). Bare verbs are wrong." (https://vercel.com/geist/context-menu) "End with `…` only when activating opens a follow-up dialog (`Rename…`, `Move to Folder…`)." (https://vercel.com/geist/context-menu) "Group destructive items at the bottom with a divider and keep the destructive label `Verb + Noun`. `Delete` alone never ships." (https://vercel.com/geist/context-menu) Ours: sentence case, "Copy address", not Title Case. Identical to the visible menu's, in the same order; a command reached two ways reads the same both ways.
|
|
17
|
+
* @access "Trigger the keyboard menu key (`Shift+F10` on Windows/Linux, the menu key, or platform equivalent) to open the same menu without right-click." (https://vercel.com/geist/context-menu) "Up/Down arrows move focus, Enter/Space activates, Escape closes and returns focus to the row." (https://vercel.com/geist/context-menu) "Don’t bury destructive items behind nested submenus. One level deep keeps keyboard navigation predictable." (https://vercel.com/geist/context-menu) Ours: the trigger must itself be focusable or hold something that is. The content requires an `aria-label` naming the menu, because nothing visible labels a menu opened at the pointer.
|
|
19
18
|
*/
|
|
20
19
|
function ContextMenu({ ...props }) {
|
|
21
20
|
return _jsx(ContextMenuPrimitive.Root, { "data-slot": "context-menu", ...props });
|
|
@@ -26,8 +25,11 @@ function ContextMenuPortal({ ...props }) {
|
|
|
26
25
|
function ContextMenuTrigger({ className, ...props }) {
|
|
27
26
|
return (_jsx(ContextMenuPrimitive.Trigger, { "data-slot": "context-menu-trigger", className: cn("select-none", className), ...props }));
|
|
28
27
|
}
|
|
29
|
-
function
|
|
30
|
-
return (_jsx(ContextMenuPrimitive.Portal, { children: _jsx(ContextMenuPrimitive.Positioner, { className: "isolate z-50 outline-none", align: align, alignOffset: alignOffset, side: side, sideOffset: sideOffset, collisionPadding: 8, children: _jsx(ContextMenuPrimitive.Popup, { "data-slot": "context-menu-content", "data-density": density, className: cn("pointer-events-auto", menuSurface,
|
|
28
|
+
function ContextMenuPopup({ className, align = "start", alignOffset = 0, density = "comfortable", side = "right", sideOffset = 2, ...props }) {
|
|
29
|
+
return (_jsx(ContextMenuPrimitive.Portal, { children: _jsx(ContextMenuPrimitive.Positioner, { className: "isolate z-50 outline-none", align: align, alignOffset: alignOffset, side: side, sideOffset: sideOffset, collisionPadding: 8, children: _jsx(ContextMenuPrimitive.Popup, { "data-slot": "context-menu-content", "data-density": density, className: cn("pointer-events-auto", menuSurface, "min-w-[min(10rem,var(--available-width))]", className), ...props }) }) }));
|
|
30
|
+
}
|
|
31
|
+
function ContextMenuContent({ "aria-label": name, ...props }) {
|
|
32
|
+
return _jsx(ContextMenuPopup, { "aria-label": name, ...props });
|
|
31
33
|
}
|
|
32
34
|
function ContextMenuGroup(props) {
|
|
33
35
|
return _jsx(DropdownMenuGroup, { "data-slot": "context-menu-group", ...props });
|
|
@@ -38,6 +40,9 @@ function ContextMenuLabel(props) {
|
|
|
38
40
|
function ContextMenuItem(props) {
|
|
39
41
|
return _jsx(DropdownMenuItem, { "data-slot": "context-menu-item", ...props });
|
|
40
42
|
}
|
|
43
|
+
function ContextMenuLink(props) {
|
|
44
|
+
return _jsx(DropdownMenuLink, { "data-slot": "context-menu-link", ...props });
|
|
45
|
+
}
|
|
41
46
|
function ContextMenuSub(props) {
|
|
42
47
|
return _jsx(DropdownMenuSub, { "data-slot": "context-menu-sub", ...props });
|
|
43
48
|
}
|
|
@@ -45,7 +50,7 @@ function ContextMenuSubTrigger(props) {
|
|
|
45
50
|
return _jsx(DropdownMenuSubTrigger, { "data-slot": "context-menu-sub-trigger", ...props });
|
|
46
51
|
}
|
|
47
52
|
function ContextMenuSubContent({ className, ...props }) {
|
|
48
|
-
return (_jsx(
|
|
53
|
+
return (_jsx(ContextMenuPopup, { "data-slot": "context-menu-sub-content", className: cn("w-auto min-w-24", className), side: "right", ...props }));
|
|
49
54
|
}
|
|
50
55
|
function ContextMenuCheckboxItem(props) {
|
|
51
56
|
return _jsx(DropdownMenuCheckboxItem, { "data-slot": "context-menu-checkbox-item", ...props });
|
|
@@ -62,4 +67,4 @@ function ContextMenuSeparator(props) {
|
|
|
62
67
|
function ContextMenuShortcut(props) {
|
|
63
68
|
return _jsx(DropdownMenuShortcut, { "data-slot": "context-menu-shortcut", ...props });
|
|
64
69
|
}
|
|
65
|
-
export { ContextMenu, ContextMenuTrigger, ContextMenuContent, ContextMenuItem, ContextMenuCheckboxItem, ContextMenuRadioItem, ContextMenuLabel, ContextMenuSeparator, ContextMenuShortcut, ContextMenuGroup, ContextMenuPortal, ContextMenuSub, ContextMenuSubContent, ContextMenuSubTrigger, ContextMenuRadioGroup, };
|
|
70
|
+
export { ContextMenu, ContextMenuTrigger, ContextMenuContent, ContextMenuItem, ContextMenuLink, ContextMenuCheckboxItem, ContextMenuRadioItem, ContextMenuLabel, ContextMenuSeparator, ContextMenuShortcut, ContextMenuGroup, ContextMenuPortal, ContextMenuSub, ContextMenuSubContent, ContextMenuSubTrigger, ContextMenuRadioGroup, };
|
|
@@ -4,6 +4,8 @@ export type CopyButtonProps = {
|
|
|
4
4
|
copiedLabel: string;
|
|
5
5
|
copyFailedLabel: string;
|
|
6
6
|
size?: "icon" | "icon-xs" | "icon-sm";
|
|
7
|
+
copied?: boolean | undefined;
|
|
8
|
+
onCopy?: (() => void) | undefined;
|
|
7
9
|
};
|
|
8
10
|
/**
|
|
9
11
|
* Copies an exact value someone will paste elsewhere.
|
|
@@ -11,9 +13,10 @@ export type CopyButtonProps = {
|
|
|
11
13
|
* @family Actions
|
|
12
14
|
* @when An exact value someone will paste elsewhere: an Agent ID, a server address, a command. A shell prompt shown before a command stays outside the copied value.
|
|
13
15
|
* @instead Several lines of code are a `CodeBlock`. Ordinary prose never gets copy chrome. A secret needs its reveal policy first.
|
|
14
|
-
* @behaviour
|
|
16
|
+
* @behaviour "A button that copies a given string to the clipboard and provides feedback when copied." (https://vercel.com/geist/copy-button)
|
|
17
|
+
* Ours: copies the full underlying value even when the shown one is shortened. The copy mark fades into the check for about a second, and only after the clipboard confirms; no colour changes. A failure shows the alert mark and the button stays for a retry. The standalone `icon` button is outlined; `icon-sm` sits after a value and `icon-xs` inside a field, both without chrome. `copied` shows the check from outside for a parent that copies other text, and `onCopy` runs once the clipboard confirms. While the clipboard works a second press is ignored and the button looks as it did, with no held look.
|
|
15
18
|
* @words Three catalogue strings: `copyLabel` names the target ("Copy Agent ID"), `copiedLabel` ("Copied"), `copyFailedLabel` ("Couldn't copy").
|
|
16
|
-
* @access `aria-label` is the copy label and does not change. The result is read once from a hidden `role="status"`.
|
|
19
|
+
* @access `aria-label` is the copy label and does not change. The result is read once from a hidden `role="status"`.
|
|
17
20
|
*/
|
|
18
21
|
export declare function CopyButton(props: CopyButtonProps): import("react").JSX.Element;
|
|
19
22
|
//# sourceMappingURL=copy-button.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"copy-button.d.ts","sourceRoot":"","sources":["../../src/components/copy-button.tsx"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"copy-button.d.ts","sourceRoot":"","sources":["../../src/components/copy-button.tsx"],"names":[],"mappings":"AASA,MAAM,MAAM,eAAe,GAAG;IAC5B,KAAK,EAAE,MAAM,CAAC;IACd,SAAS,EAAE,MAAM,CAAC;IAClB,WAAW,EAAE,MAAM,CAAC;IACpB,eAAe,EAAE,MAAM,CAAC;IACxB,IAAI,CAAC,EAAE,MAAM,GAAG,SAAS,GAAG,SAAS,CAAC;IACtC,MAAM,CAAC,EAAE,OAAO,GAAG,SAAS,CAAC;IAC7B,MAAM,CAAC,EAAE,CAAC,MAAM,IAAI,CAAC,GAAG,SAAS,CAAC;CACnC,CAAC;AAEF;;;;;;;;;;GAUG;AACH,wBAAgB,UAAU,CAAC,KAAK,EAAE,eAAe,+BAEhD"}
|
|
@@ -1,35 +1,43 @@
|
|
|
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 { useState, useTransition } from "react";
|
|
4
4
|
import { Check, CircleAlert, Copy } from "lucide-react";
|
|
5
5
|
import { Button } from "./button.js";
|
|
6
6
|
import { useCopyToClipboard } from "../lib/use-copy-to-clipboard.js";
|
|
7
|
+
import { cn } from "../lib/utils.js";
|
|
7
8
|
/**
|
|
8
9
|
* Copies an exact value someone will paste elsewhere.
|
|
9
10
|
*
|
|
10
11
|
* @family Actions
|
|
11
12
|
* @when An exact value someone will paste elsewhere: an Agent ID, a server address, a command. A shell prompt shown before a command stays outside the copied value.
|
|
12
13
|
* @instead Several lines of code are a `CodeBlock`. Ordinary prose never gets copy chrome. A secret needs its reveal policy first.
|
|
13
|
-
* @behaviour
|
|
14
|
+
* @behaviour "A button that copies a given string to the clipboard and provides feedback when copied." (https://vercel.com/geist/copy-button)
|
|
15
|
+
* Ours: copies the full underlying value even when the shown one is shortened. The copy mark fades into the check for about a second, and only after the clipboard confirms; no colour changes. A failure shows the alert mark and the button stays for a retry. The standalone `icon` button is outlined; `icon-sm` sits after a value and `icon-xs` inside a field, both without chrome. `copied` shows the check from outside for a parent that copies other text, and `onCopy` runs once the clipboard confirms. While the clipboard works a second press is ignored and the button looks as it did, with no held look.
|
|
14
16
|
* @words Three catalogue strings: `copyLabel` names the target ("Copy Agent ID"), `copiedLabel` ("Copied"), `copyFailedLabel` ("Couldn't copy").
|
|
15
|
-
* @access `aria-label` is the copy label and does not change. The result is read once from a hidden `role="status"`.
|
|
17
|
+
* @access `aria-label` is the copy label and does not change. The result is read once from a hidden `role="status"`.
|
|
16
18
|
*/
|
|
17
19
|
export function CopyButton(props) {
|
|
18
20
|
return _jsx(CopyValueButton, { ...props }, props.value);
|
|
19
21
|
}
|
|
20
|
-
function
|
|
22
|
+
function markClass(shown) {
|
|
23
|
+
return cn("col-start-1 row-start-1 transition-opacity duration-[var(--nc-duration-confirm)]", !shown && "opacity-0");
|
|
24
|
+
}
|
|
25
|
+
function CopyValueButton({ value, copyLabel, copiedLabel, copyFailedLabel, size = "icon", copied: copiedProp, onCopy, }) {
|
|
21
26
|
const [failed, setFailed] = useState(false);
|
|
22
27
|
const [pending, startTransition] = useTransition();
|
|
23
28
|
const { copyToClipboard, isCopied } = useCopyToClipboard({
|
|
24
29
|
text: value,
|
|
25
|
-
timeout:
|
|
30
|
+
timeout: 1000,
|
|
31
|
+
onCopy,
|
|
26
32
|
onError: () => setFailed(true),
|
|
27
33
|
});
|
|
28
|
-
const copied = isCopied && !failed && !pending;
|
|
29
|
-
return (_jsxs(_Fragment, { children: [_jsx(Button, { "aria-label": copyLabel,
|
|
34
|
+
const copied = (copiedProp ?? isCopied) && !failed && !pending;
|
|
35
|
+
return (_jsxs(_Fragment, { children: [_jsx(Button, { "aria-label": copyLabel, title: failed ? copyFailedLabel : copyLabel, onClick: () => {
|
|
36
|
+
if (pending)
|
|
37
|
+
return;
|
|
30
38
|
setFailed(false);
|
|
31
39
|
startTransition(async () => {
|
|
32
40
|
await copyToClipboard();
|
|
33
41
|
});
|
|
34
|
-
}, size: size, type: "button", variant: "ghost", children:
|
|
42
|
+
}, size: size, type: "button", variant: size === "icon" ? "outline" : "ghost", children: _jsxs("span", { className: "grid place-items-center", children: [_jsx(Copy, { className: markClass(!failed && !copied) }), _jsx(Check, { className: markClass(copied) }), _jsx(CircleAlert, { className: markClass(failed) })] }) }), _jsx("span", { className: "sr-only", role: "status", children: pending ? "" : failed ? copyFailedLabel : copied ? copiedLabel : "" })] }));
|
|
35
43
|
}
|