@nadicodeai/ui 12.1.102 → 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.js +2 -2
- 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/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 +18 -1
- package/dist/components/theme-mode-switcher.d.ts.map +1 -1
- package/dist/components/theme-mode-switcher.js +20 -2
- 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 -17
- 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 +632 -544
- 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
|
@@ -15,13 +15,19 @@ const ToggleGroupContext = React.createContext({
|
|
|
15
15
|
* Pressed buttons that belong together.
|
|
16
16
|
*
|
|
17
17
|
* @family Choices
|
|
18
|
-
* @when Pressed buttons that belong together:
|
|
19
|
-
* @instead A
|
|
20
|
-
*
|
|
18
|
+
* @when Pressed buttons that belong together: which details a chat shows, the marks on a toolbar.
|
|
19
|
+
* @instead A value that is always exactly one of two or three, such as a list or grid view, is a
|
|
20
|
+
* `SegmentedControl`: its options are radios, so pressing the chosen one never clears it. The
|
|
21
|
+
* theme is `ThemeModeSwitcher`. Panels of one object are `Tabs`.
|
|
21
22
|
* @behaviour Spacing 0 joins the members into one outline with one seam; spacing 2 keeps them 8 px
|
|
22
|
-
* apart.
|
|
23
|
-
*
|
|
24
|
-
*
|
|
23
|
+
* apart. With `multiple`, members are pressed independently and any number may be pressed, none
|
|
24
|
+
* included. Without it, at most one is pressed and pressing it again clears it; a value that is
|
|
25
|
+
* always one of two or three is a `SegmentedControl`. The group is named with `aria-label`
|
|
26
|
+
* or `aria-labelledby`, and a member is either a word as its children or carries an `aria-label`;
|
|
27
|
+
* a group or an icon member without a name does not compile. Colour: a pressed member takes the
|
|
28
|
+
* accent grey and nothing takes a hue. Arrow keys move between members; Space presses.
|
|
29
|
+
* @words Text members are short words of equal weight. Icon members always carry a name: *Tools*,
|
|
30
|
+
* *Reasoning*.
|
|
25
31
|
* @access `role="group"` with a name; each member a button with `aria-pressed`.
|
|
26
32
|
*/
|
|
27
33
|
function ToggleGroup({ className, variant, size, spacing = 2, orientation = "horizontal", style, children, ...props }) {
|
|
@@ -11,9 +11,12 @@ declare const toggleVariants: (props?: ({
|
|
|
11
11
|
* @when A button that stays pressed, where pressing is the action: pin a chat, mute a thread, show
|
|
12
12
|
* hidden rows in a toolbar.
|
|
13
13
|
* @instead A setting saved with its section is a `Switch`. Choosing one value of several is a
|
|
14
|
-
* `RadioGroup`,
|
|
15
|
-
* @behaviour Space or Enter flips `aria-pressed`.
|
|
16
|
-
*
|
|
14
|
+
* `RadioGroup`, or a `SegmentedControl` when it is two or three views of one surface.
|
|
15
|
+
* @behaviour Space or Enter flips `aria-pressed`. Sizes, type, corners and the text inset are
|
|
16
|
+
* `Button`'s (32, 36 and 40 px; 12, 16 and 20 px), and the padding does not change with an icon; an icon-only toggle is square.
|
|
17
|
+
* Pressed takes the accent fill and weight 600, a neutral fill with no hue; the label does not
|
|
18
|
+
* change. Hover is the muted fill. Disable it only when pressing is impossible, and say why beside
|
|
19
|
+
* it.
|
|
17
20
|
* @words The label is the action and stays the same in both states: *Pin*, never *Pinned* or
|
|
18
21
|
* *Unpin*.
|
|
19
22
|
* @access A `button` with `aria-pressed`. An icon-only toggle names what it does: *Pin chat*.
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"toggle.d.ts","sourceRoot":"","sources":["../../src/components/toggle.tsx"],"names":[],"mappings":"AAEA,OAAO,EAAE,MAAM,IAAI,eAAe,EAAE,MAAM,uBAAuB,CAAC;AAClE,OAAO,EAAO,KAAK,YAAY,EAAE,MAAM,0BAA0B,CAAC;AAIlE,QAAA,MAAM,cAAc;;;
|
|
1
|
+
{"version":3,"file":"toggle.d.ts","sourceRoot":"","sources":["../../src/components/toggle.tsx"],"names":[],"mappings":"AAEA,OAAO,EAAE,MAAM,IAAI,eAAe,EAAE,MAAM,uBAAuB,CAAC;AAClE,OAAO,EAAO,KAAK,YAAY,EAAE,MAAM,0BAA0B,CAAC;AAIlE,QAAA,MAAM,cAAc;;;8EAmBnB,CAAC;AAEF;;;;;;;;;;;;;;;;GAgBG;AACH,iBAAS,MAAM,CAAC,EACd,SAAS,EACT,OAAmB,EACnB,IAAgB,EAChB,GAAG,KAAK,EACT,EAAE,eAAe,CAAC,KAAK,GAAG,YAAY,CAAC,OAAO,cAAc,CAAC,+BAQ7D;AAED,OAAO,EAAE,MAAM,EAAE,cAAc,EAAE,CAAC"}
|
|
@@ -3,16 +3,16 @@ import { jsx as _jsx } from "react/jsx-runtime";
|
|
|
3
3
|
import { Toggle as TogglePrimitive } from "@base-ui/react/toggle";
|
|
4
4
|
import { cva } from "class-variance-authority";
|
|
5
5
|
import { cn } from "../lib/utils.js";
|
|
6
|
-
const toggleVariants = cva("group/toggle inline-flex min-h-touch-target min-w-touch-target items-center justify-center gap-1 rounded-sm border border-transparent text-
|
|
6
|
+
const toggleVariants = cva("group/toggle inline-flex has-[>svg:only-child]:aspect-square has-[>svg:only-child]:px-0 min-h-touch-target min-w-touch-target items-center justify-center gap-1 rounded-sm border border-transparent text-button font-medium whitespace-nowrap transition-[background-color,border-color,color,opacity] duration-[var(--nc-duration-confirm)] ease-[var(--nc-ease-out-strong)] hover:bg-muted hover:text-foreground disabled:pointer-events-none disabled:opacity-50 aria-invalid:border-destructive aria-pressed:bg-accent aria-pressed:font-semibold aria-pressed:text-accent-foreground data-pressed:bg-accent data-pressed:font-semibold data-pressed:text-accent-foreground [@media(hover:hover)_and_(pointer:fine)]:min-h-0 [@media(hover:hover)_and_(pointer:fine)]:min-w-0 [&_svg]:pointer-events-none [&_svg]:shrink-0 [&_svg:not([class*='size-'])]:size-4", {
|
|
7
7
|
variants: {
|
|
8
8
|
variant: {
|
|
9
9
|
default: "bg-transparent",
|
|
10
10
|
outline: "border-input bg-transparent hover:bg-muted",
|
|
11
11
|
},
|
|
12
12
|
size: {
|
|
13
|
-
default: "h-control-height px-
|
|
14
|
-
sm: "h-nadicode-control-height-sm px-
|
|
15
|
-
lg: "h-nadicode-control-height-lg
|
|
13
|
+
default: "h-control-height px-4",
|
|
14
|
+
sm: "h-nadicode-control-height-sm px-3 [&_svg:not([class*='size-'])]:size-3.5",
|
|
15
|
+
lg: "h-nadicode-control-height-lg rounded-md px-5 text-button-lg",
|
|
16
16
|
},
|
|
17
17
|
},
|
|
18
18
|
defaultVariants: {
|
|
@@ -27,9 +27,12 @@ const toggleVariants = cva("group/toggle inline-flex min-h-touch-target min-w-to
|
|
|
27
27
|
* @when A button that stays pressed, where pressing is the action: pin a chat, mute a thread, show
|
|
28
28
|
* hidden rows in a toolbar.
|
|
29
29
|
* @instead A setting saved with its section is a `Switch`. Choosing one value of several is a
|
|
30
|
-
* `RadioGroup`,
|
|
31
|
-
* @behaviour Space or Enter flips `aria-pressed`.
|
|
32
|
-
*
|
|
30
|
+
* `RadioGroup`, or a `SegmentedControl` when it is two or three views of one surface.
|
|
31
|
+
* @behaviour Space or Enter flips `aria-pressed`. Sizes, type, corners and the text inset are
|
|
32
|
+
* `Button`'s (32, 36 and 40 px; 12, 16 and 20 px), and the padding does not change with an icon; an icon-only toggle is square.
|
|
33
|
+
* Pressed takes the accent fill and weight 600, a neutral fill with no hue; the label does not
|
|
34
|
+
* change. Hover is the muted fill. Disable it only when pressing is impossible, and say why beside
|
|
35
|
+
* it.
|
|
33
36
|
* @words The label is the action and stays the same in both states: *Pin*, never *Pinned* or
|
|
34
37
|
* *Unpin*.
|
|
35
38
|
* @access A `button` with `aria-pressed`. An icon-only toggle names what it does: *Pin chat*.
|
|
@@ -1,22 +1,53 @@
|
|
|
1
1
|
import { Tooltip as TooltipPrimitive } from "@base-ui/react/tooltip";
|
|
2
|
+
import type { PresentContent } from "../internal/present-content.js";
|
|
2
3
|
declare function TooltipProvider({ delay, ...props }: TooltipPrimitive.Provider.Props): import("react").JSX.Element;
|
|
3
4
|
/**
|
|
4
5
|
* A short, optional fact about its trigger.
|
|
5
6
|
*
|
|
6
7
|
* @family Feedback
|
|
7
|
-
* @when
|
|
8
|
-
*
|
|
9
|
-
*
|
|
10
|
-
*
|
|
11
|
-
*
|
|
12
|
-
*
|
|
13
|
-
* @
|
|
14
|
-
*
|
|
15
|
-
*
|
|
16
|
-
* `
|
|
8
|
+
* @when "Use a Tooltip to explain **why** something exists, not **what** it is." "The visible label
|
|
9
|
+
* names the thing; the tooltip adds the constraint, scope, or limit."
|
|
10
|
+
* (https://vercel.com/geist/tooltip)
|
|
11
|
+
* "Use lifecycle Tooltips (`Alpha`, `Experimental`, `Beta`, `Early Access`) to name the limits that
|
|
12
|
+
* apply: API stability, SLA, support, pricing, retention." (https://vercel.com/geist/tooltip)
|
|
13
|
+
* Ours: a shortcut is shown in a tooltip only when one is bound.
|
|
14
|
+
* @instead "For an entity preview with metadata rows (avatar, identifier, 2–4 facts, optional
|
|
15
|
+
* action), use `Context Card`." "For long-form content or actions that need persistence, route to a
|
|
16
|
+
* `Drawer` or page navigation." (https://vercel.com/geist/tooltip)
|
|
17
|
+
* Ours: `Context Card` is `HoverCard` and `Drawer` is `Sheet`. A disabled command's reason is
|
|
18
|
+
* written under it, never only in a tooltip.
|
|
19
|
+
* @behaviour "Tooltips open on hover and on keyboard focus." "Keep the default ~150ms entry delay so
|
|
20
|
+
* the tooltip doesn’t flicker on a sweeping mouse." "Don’t wrap a labelled `Input` in a Tooltip."
|
|
21
|
+
* "The trigger lands on the `<label>`, not the field, and the tooltip text becomes a second
|
|
22
|
+
* invisible label for screen readers." "Put help on a sibling icon button." "Keep primary actions
|
|
23
|
+
* outside the Tooltip; touch users can’t reach a hover-revealed control."
|
|
24
|
+
* (https://vercel.com/geist/tooltip)
|
|
25
|
+
* Ours: the pointer wait is 150 ms and keyboard focus opens it at once; `delay={0}` on the trigger
|
|
26
|
+
* or a `TooltipProvider` removes the wait. Above by default, 10 px from the trigger, at most 250 px
|
|
27
|
+
* wide, 13 px text balanced over its lines. Never interactive. `arrow={false}` drops the stem;
|
|
28
|
+
* `centerText={false}` left-aligns a tooltip that wraps. `TooltipContent` requires its text as
|
|
29
|
+
* children. Colour: one inverted neutral, the page's ink as the fill and its surface as the
|
|
30
|
+
* text, with a stem of the same fill and no hue, in both themes; a shortcut is a `Kbd` after the
|
|
31
|
+
* text, drawn 20 px high.
|
|
32
|
+
* @words "One sentence or fragment in `text`." "Sentence case, no period for a single fragment."
|
|
33
|
+
* "Skip tooltips that repeat the visible label (`text="Rate Limit"` on a `Rate Limit` button) or
|
|
34
|
+
* describe the interaction (`text="Click to override"`)." "Lifecycle Tooltips follow `{Label}:
|
|
35
|
+
* {one-line meaning}. {Specific limit}.`" "For a paid Beta feature, combine the lifecycle and
|
|
36
|
+
* pricing in one Tooltip rather than stacking two badges." (https://vercel.com/geist/tooltip)
|
|
37
|
+
* Ours: the text is `TooltipContent`'s children, for example *Resets on 1 November*.
|
|
38
|
+
* @access "An icon-only trigger needs an `aria-label` that names the action; the Tooltip body adds
|
|
39
|
+
* context, it doesn’t replace the label." "Escape closes the tooltip and returns focus to the
|
|
40
|
+
* trigger." (https://vercel.com/geist/tooltip)
|
|
17
41
|
*/
|
|
18
42
|
declare function Tooltip({ ...props }: TooltipPrimitive.Root.Props): import("react").JSX.Element;
|
|
19
|
-
declare function TooltipTrigger({ ...props }: TooltipPrimitive.Trigger.Props): import("react").JSX.Element;
|
|
20
|
-
declare function TooltipContent({ className, side, sideOffset, align, alignOffset, children, ...props }: TooltipPrimitive.Popup.Props & Pick<TooltipPrimitive.Positioner.Props, "align" | "alignOffset" | "side" | "sideOffset">
|
|
43
|
+
declare function TooltipTrigger({ delay, ...props }: TooltipPrimitive.Trigger.Props): import("react").JSX.Element;
|
|
44
|
+
declare function TooltipContent({ className, side, sideOffset, align, alignOffset, arrow, centerText, children, ...props }: TooltipPrimitive.Popup.Props & Pick<TooltipPrimitive.Positioner.Props, "align" | "alignOffset" | "side" | "sideOffset"> & {
|
|
45
|
+
/** The text of the tooltip; a tooltip without one does not compile. */
|
|
46
|
+
children: PresentContent;
|
|
47
|
+
/** The stem pointing at the trigger; `false` for a tooltip that sits against it. */
|
|
48
|
+
arrow?: boolean;
|
|
49
|
+
/** Centres the text of a tooltip that wraps; `false` left-aligns it. */
|
|
50
|
+
centerText?: boolean;
|
|
51
|
+
}): import("react").JSX.Element;
|
|
21
52
|
export { Tooltip, TooltipTrigger, TooltipContent, TooltipProvider };
|
|
22
53
|
//# sourceMappingURL=tooltip.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"tooltip.d.ts","sourceRoot":"","sources":["../../src/components/tooltip.tsx"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"tooltip.d.ts","sourceRoot":"","sources":["../../src/components/tooltip.tsx"],"names":[],"mappings":"AAEA,OAAO,EAAE,OAAO,IAAI,gBAAgB,EAAE,MAAM,wBAAwB,CAAC;AAIrE,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,4BAA4B,CAAC;AAQjE,iBAAS,eAAe,CAAC,EAAE,KAAqB,EAAE,GAAG,KAAK,EAAE,EAAE,gBAAgB,CAAC,QAAQ,CAAC,KAAK,+BAM5F;AAED;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GAqCG;AACH,iBAAS,OAAO,CAAC,EAAE,GAAG,KAAK,EAAE,EAAE,gBAAgB,CAAC,IAAI,CAAC,KAAK,+BAEzD;AAED,iBAAS,cAAc,CAAC,EAAE,KAAK,EAAE,GAAG,KAAK,EAAE,EAAE,gBAAgB,CAAC,OAAO,CAAC,KAAK,+BAS1E;AAED,iBAAS,cAAc,CAAC,EACtB,SAAS,EACT,IAAY,EACZ,UAAe,EACf,KAAgB,EAChB,WAAe,EACf,KAAY,EACZ,UAAiB,EACjB,QAAQ,EACR,GAAG,KAAK,EACT,EAAE,gBAAgB,CAAC,KAAK,CAAC,KAAK,GAC7B,IAAI,CAAC,gBAAgB,CAAC,UAAU,CAAC,KAAK,EAAE,OAAO,GAAG,aAAa,GAAG,MAAM,GAAG,YAAY,CAAC,GAAG;IACzF,uEAAuE;IACvE,QAAQ,EAAE,cAAc,CAAC;IACzB,oFAAoF;IACpF,KAAK,CAAC,EAAE,OAAO,CAAC;IAChB,wEAAwE;IACxE,UAAU,CAAC,EAAE,OAAO,CAAC;CACtB,+BA8BF;AAED,OAAO,EAAE,OAAO,EAAE,cAAc,EAAE,cAAc,EAAE,eAAe,EAAE,CAAC"}
|
|
@@ -1,32 +1,61 @@
|
|
|
1
|
+
"use client";
|
|
1
2
|
import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
|
|
2
3
|
import { Tooltip as TooltipPrimitive } from "@base-ui/react/tooltip";
|
|
4
|
+
import { createContext, useContext } from "react";
|
|
5
|
+
import { overlayStem, OverlayStemShape } from "../internal/overlay-stem.js";
|
|
3
6
|
import { cn } from "../lib/utils.js";
|
|
4
7
|
import { anchoredOverlayMotion } from "../lib/motion.js";
|
|
5
|
-
|
|
6
|
-
|
|
8
|
+
const TOOLTIP_DELAY = 150;
|
|
9
|
+
const TooltipDelay = createContext(TOOLTIP_DELAY);
|
|
10
|
+
function TooltipProvider({ delay = TOOLTIP_DELAY, ...props }) {
|
|
11
|
+
return (_jsx(TooltipDelay.Provider, { value: delay, children: _jsx(TooltipPrimitive.Provider, { "data-slot": "tooltip-provider", delay: delay, ...props }) }));
|
|
7
12
|
}
|
|
8
13
|
/**
|
|
9
14
|
* A short, optional fact about its trigger.
|
|
10
15
|
*
|
|
11
16
|
* @family Feedback
|
|
12
|
-
* @when
|
|
13
|
-
*
|
|
14
|
-
*
|
|
15
|
-
*
|
|
16
|
-
*
|
|
17
|
-
*
|
|
18
|
-
* @
|
|
19
|
-
*
|
|
20
|
-
*
|
|
21
|
-
* `
|
|
17
|
+
* @when "Use a Tooltip to explain **why** something exists, not **what** it is." "The visible label
|
|
18
|
+
* names the thing; the tooltip adds the constraint, scope, or limit."
|
|
19
|
+
* (https://vercel.com/geist/tooltip)
|
|
20
|
+
* "Use lifecycle Tooltips (`Alpha`, `Experimental`, `Beta`, `Early Access`) to name the limits that
|
|
21
|
+
* apply: API stability, SLA, support, pricing, retention." (https://vercel.com/geist/tooltip)
|
|
22
|
+
* Ours: a shortcut is shown in a tooltip only when one is bound.
|
|
23
|
+
* @instead "For an entity preview with metadata rows (avatar, identifier, 2–4 facts, optional
|
|
24
|
+
* action), use `Context Card`." "For long-form content or actions that need persistence, route to a
|
|
25
|
+
* `Drawer` or page navigation." (https://vercel.com/geist/tooltip)
|
|
26
|
+
* Ours: `Context Card` is `HoverCard` and `Drawer` is `Sheet`. A disabled command's reason is
|
|
27
|
+
* written under it, never only in a tooltip.
|
|
28
|
+
* @behaviour "Tooltips open on hover and on keyboard focus." "Keep the default ~150ms entry delay so
|
|
29
|
+
* the tooltip doesn’t flicker on a sweeping mouse." "Don’t wrap a labelled `Input` in a Tooltip."
|
|
30
|
+
* "The trigger lands on the `<label>`, not the field, and the tooltip text becomes a second
|
|
31
|
+
* invisible label for screen readers." "Put help on a sibling icon button." "Keep primary actions
|
|
32
|
+
* outside the Tooltip; touch users can’t reach a hover-revealed control."
|
|
33
|
+
* (https://vercel.com/geist/tooltip)
|
|
34
|
+
* Ours: the pointer wait is 150 ms and keyboard focus opens it at once; `delay={0}` on the trigger
|
|
35
|
+
* or a `TooltipProvider` removes the wait. Above by default, 10 px from the trigger, at most 250 px
|
|
36
|
+
* wide, 13 px text balanced over its lines. Never interactive. `arrow={false}` drops the stem;
|
|
37
|
+
* `centerText={false}` left-aligns a tooltip that wraps. `TooltipContent` requires its text as
|
|
38
|
+
* children. Colour: one inverted neutral, the page's ink as the fill and its surface as the
|
|
39
|
+
* text, with a stem of the same fill and no hue, in both themes; a shortcut is a `Kbd` after the
|
|
40
|
+
* text, drawn 20 px high.
|
|
41
|
+
* @words "One sentence or fragment in `text`." "Sentence case, no period for a single fragment."
|
|
42
|
+
* "Skip tooltips that repeat the visible label (`text="Rate Limit"` on a `Rate Limit` button) or
|
|
43
|
+
* describe the interaction (`text="Click to override"`)." "Lifecycle Tooltips follow `{Label}:
|
|
44
|
+
* {one-line meaning}. {Specific limit}.`" "For a paid Beta feature, combine the lifecycle and
|
|
45
|
+
* pricing in one Tooltip rather than stacking two badges." (https://vercel.com/geist/tooltip)
|
|
46
|
+
* Ours: the text is `TooltipContent`'s children, for example *Resets on 1 November*.
|
|
47
|
+
* @access "An icon-only trigger needs an `aria-label` that names the action; the Tooltip body adds
|
|
48
|
+
* context, it doesn’t replace the label." "Escape closes the tooltip and returns focus to the
|
|
49
|
+
* trigger." (https://vercel.com/geist/tooltip)
|
|
22
50
|
*/
|
|
23
51
|
function Tooltip({ ...props }) {
|
|
24
52
|
return _jsx(TooltipPrimitive.Root, { "data-slot": "tooltip", ...props });
|
|
25
53
|
}
|
|
26
|
-
function TooltipTrigger({ ...props }) {
|
|
27
|
-
|
|
54
|
+
function TooltipTrigger({ delay, ...props }) {
|
|
55
|
+
const inheritedDelay = useContext(TooltipDelay);
|
|
56
|
+
return (_jsx(TooltipPrimitive.Trigger, { "data-slot": "tooltip-trigger", delay: delay ?? inheritedDelay, ...props }));
|
|
28
57
|
}
|
|
29
|
-
function TooltipContent({ className, side = "top", sideOffset =
|
|
30
|
-
return (_jsx(TooltipPrimitive.Portal, { children: _jsx(TooltipPrimitive.Positioner, { align: align, alignOffset: alignOffset, side: side, sideOffset: sideOffset, className: "isolate z-50", children: _jsxs(TooltipPrimitive.Popup, { "data-slot": "tooltip-content", className: cn("z-50
|
|
58
|
+
function TooltipContent({ className, side = "top", sideOffset = 10, align = "center", alignOffset = 0, arrow = true, centerText = true, children, ...props }) {
|
|
59
|
+
return (_jsx(TooltipPrimitive.Portal, { children: _jsx(TooltipPrimitive.Positioner, { align: align, alignOffset: alignOffset, side: side, sideOffset: sideOffset, className: "isolate z-50", children: _jsxs(TooltipPrimitive.Popup, { "data-slot": "tooltip-content", className: cn("z-50 w-fit max-w-62.5 rounded-md border-0 bg-foreground px-nadicode-xs py-1.5 text-body-compact text-balance text-background nc-elevation-floating has-data-[slot=kbd]:inline-flex has-data-[slot=kbd]:items-center has-data-[slot=kbd]:gap-1 has-data-[slot=kbd]:pr-1.5 **:data-[slot=kbd]:relative **:data-[slot=kbd]:isolate **:data-[slot=kbd]:z-50 **:data-[slot=kbd]:h-5 **:data-[slot=kbd]:min-w-5 **:data-[slot=kbd]:text-caption **:data-[slot=kbd]:leading-5", centerText ? "text-center" : "text-left", anchoredOverlayMotion, className), ...props, children: [children, arrow ? (_jsx(TooltipPrimitive.Arrow, { className: cn(overlayStem, "[&_path]:fill-foreground"), children: _jsx(OverlayStemShape, {}) })) : null] }) }) }));
|
|
31
60
|
}
|
|
32
61
|
export { Tooltip, TooltipTrigger, TooltipContent, TooltipProvider };
|
|
@@ -34,6 +34,6 @@ function trendTone(direction, upIsGood = true, neutral = false) {
|
|
|
34
34
|
*/
|
|
35
35
|
function TrendBadge({ value, direction, tone, directionLabel, }) {
|
|
36
36
|
const Icon = TREND_ICONS[direction];
|
|
37
|
-
return (_jsxs(Badge, { "data-slot": "trend-badge", "data-direction": direction, "data-tone": tone, variant: "outline", className: "tabular-nums",
|
|
37
|
+
return (_jsxs(Badge, { "data-slot": "trend-badge", "data-direction": direction, "data-tone": tone, variant: "outline", className: "tabular-nums", icon: _jsx(Icon, { "aria-hidden": "true", className: TREND_TONE_CLASS[tone] }), children: [_jsx("span", { className: "sr-only", children: directionLabel }), value] }));
|
|
38
38
|
}
|
|
39
39
|
export { TrendBadge, trendTone };
|
|
@@ -21,7 +21,7 @@ export function UpdateCard(props) {
|
|
|
21
21
|
return (_jsxs(Card, { "aria-label": props.title, className: "mx-1 mb-1", "data-state": props.state, render: _jsx("section", {}), size: "sm", surface: "outlined", children: [_jsxs(CardHeader, { children: [_jsx(CardTitle, { children: props.title }), _jsx(CardDescription, { children: props.version }), props.state === "updated" ? (_jsx(CardAction, { children: _jsx(Button, { "aria-label": props.dismiss.label, onClick: props.dismiss.onClick, size: "icon-sm", type: "button", variant: "ghost", children: _jsx(X, { "aria-hidden": "true" }) }) })) : null] }), props.state === "available" ? (_jsx(CardContent, { className: "grid *:w-full", children: _jsx(PageCommandButton, { command: props.action, variant: "default" }) })) : null] }));
|
|
22
22
|
}
|
|
23
23
|
function NarrowUpdate(props) {
|
|
24
|
-
const button = props.state === "available" ? (_jsx(Button, { "aria-
|
|
24
|
+
const button = props.state === "available" ? (_jsx(Button, { "aria-label": `${props.action.pending ? (props.action.pendingLabel ?? props.action.label) : props.action.label}: ${props.version}`, disabled: props.action.disabled, loading: props.action.pending, size: "icon", variant: "ghost", ...(props.action.render
|
|
25
25
|
? { render: props.action.render, nativeButton: false }
|
|
26
26
|
: { onClick: props.action.onClick, type: "button" }), children: _jsx(ArrowDownToLine, { "aria-hidden": "true" }) })) : (_jsx(Button, { "aria-label": `${props.dismiss.label}: ${props.title}`, onClick: props.dismiss.onClick, size: "icon", type: "button", variant: "ghost", children: _jsx(CircleCheck, { "aria-hidden": "true" }) }));
|
|
27
27
|
return (_jsxs(Tooltip, { children: [_jsx(TooltipTrigger, { render: button }), _jsxs(TooltipContent, { side: "right", children: [props.title, ", ", props.version] })] }));
|
package/dist/eslint/index.js
CHANGED
|
@@ -3,20 +3,61 @@ import { readdirSync, readFileSync } from "node:fs";
|
|
|
3
3
|
|
|
4
4
|
import { builtinRules } from "eslint/use-at-your-own-risk";
|
|
5
5
|
|
|
6
|
+
import { badgeIsStaticLabel } from "./rules/badge-is-static-label.js";
|
|
7
|
+
import { buttonIconSlot } from "./rules/button-icon-slot.js";
|
|
8
|
+
import { buttonLinkForNavigation } from "./rules/button-link-for-navigation.js";
|
|
9
|
+
import { buttonNoAriaLabelWithText } from "./rules/button-no-aria-label-with-text.js";
|
|
10
|
+
import { buttonTypeRolesOnlyInButtons } from "./rules/button-type-roles-only-in-buttons.js";
|
|
11
|
+
import { choiceControlHasAName } from "./rules/choice-control-has-a-name.js";
|
|
12
|
+
import { choiceGroupInFieldset } from "./rules/choice-group-in-fieldset.js";
|
|
13
|
+
import { commandShortcutSingleOwner } from "./rules/command-shortcut-single-owner.js";
|
|
14
|
+
import { confirmDialogWords } from "./rules/confirm-dialog-words.js";
|
|
15
|
+
import { dataTableOneUnsizedColumn } from "./rules/data-table-one-unsized-column.js";
|
|
16
|
+
import { destructiveActionPlacement } from "./rules/destructive-action-placement.js";
|
|
17
|
+
import { disabledChoiceSaysWhy } from "./rules/disabled-choice-says-why.js";
|
|
18
|
+
import { settingsLimitInFooter } from "./rules/settings-limit-in-footer.js";
|
|
19
|
+
import { ellipsisOpensADialog } from "./rules/ellipsis-opens-a-dialog.js";
|
|
6
20
|
import { emptyStateOwner } from "./rules/empty-state-owner.js";
|
|
21
|
+
import { inputGroupOwners } from "./rules/input-group-owners.js";
|
|
22
|
+
import { kbdChildrenNoModifierText } from "./rules/kbd-children-no-modifier-text.js";
|
|
7
23
|
import { menuOwner } from "./rules/menu-owner.js";
|
|
24
|
+
import { middleTruncatePlacement } from "./rules/middle-truncate-placement.js";
|
|
8
25
|
import { noAppFeatureComponent } from "./rules/no-app-feature-component.js";
|
|
26
|
+
import { noBareButtonLabel } from "./rules/no-bare-button-label.js";
|
|
9
27
|
import { noChoiceControlWrapper } from "./rules/no-choice-control-wrapper.js";
|
|
10
28
|
import { noComment } from "./rules/no-comment.js";
|
|
29
|
+
import { noControlInReadOnlySurface } from "./rules/no-control-in-read-only-surface.js";
|
|
11
30
|
import { noDecorativeIcon } from "./rules/no-decorative-icon.js";
|
|
12
31
|
import { noDeprecatedZodApi } from "./rules/no-deprecated-zod-api.js";
|
|
13
32
|
import { noGlobalPatch } from "./rules/no-global-patch.js";
|
|
33
|
+
import { noHandBuiltBusy } from "./rules/no-hand-built-busy.js";
|
|
34
|
+
import { noHandBuiltThemePicker } from "./rules/no-hand-built-theme-picker.js";
|
|
35
|
+
import { noHandBuiltTile } from "./rules/no-hand-built-tile.js";
|
|
36
|
+
import { noHandFormattedDate } from "./rules/no-hand-formatted-date.js";
|
|
37
|
+
import { noHandStackedAvatars } from "./rules/no-hand-stacked-avatars.js";
|
|
38
|
+
import { noNestedCollapse } from "./rules/no-nested-collapse.js";
|
|
14
39
|
import { noPackageComponentRedefinition } from "./rules/no-package-component-redefinition.js";
|
|
40
|
+
import { noSearchInForm } from "./rules/no-search-in-form.js";
|
|
15
41
|
import { noShadcnAppearanceOverride } from "./rules/no-shadcn-appearance-override.js";
|
|
42
|
+
import { noShellPromptInSnippet } from "./rules/no-shell-prompt-in-snippet.js";
|
|
43
|
+
import { noStockErrorWords } from "./rules/no-stock-error-words.js";
|
|
16
44
|
import { noSubjectDerivedExpectation } from "./rules/no-subject-derived-expectation.js";
|
|
45
|
+
import { noTooltipAroundLabelledField } from "./rules/no-tooltip-around-labelled-field.js";
|
|
46
|
+
import { noWeightClassOnStrongInTypeRole } from "./rules/no-weight-class-on-strong-in-type-role.js";
|
|
17
47
|
import { noWriteInSubscription } from "./rules/no-write-in-subscription.js";
|
|
48
|
+
import { oneSubmenuLevel } from "./rules/one-submenu-level.js";
|
|
49
|
+
import { oneToastPerFlow } from "./rules/one-toast-per-flow.js";
|
|
50
|
+
import { optionCount } from "./rules/option-count.js";
|
|
51
|
+
import { pageCommandLinkNotRender } from "./rules/page-command-link-not-render.js";
|
|
18
52
|
import { pageComposition } from "./rules/page-composition.js";
|
|
53
|
+
import { progressNeedsName } from "./rules/progress-needs-name.js";
|
|
19
54
|
import { serverActionDiscipline } from "./rules/server-action-discipline.js";
|
|
55
|
+
import { skeletonInRegion } from "./rules/skeleton-in-region.js";
|
|
56
|
+
import { sortableHeadingUsesSort } from "./rules/sortable-heading-uses-sort.js";
|
|
57
|
+
import { tableCellInsetOwner } from "./rules/table-cell-inset-owner.js";
|
|
58
|
+
import { tabsSelectionIsControlled } from "./rules/tabs-selection-is-controlled.js";
|
|
59
|
+
import { tooltipOnlyArrow } from "./rules/tooltip-only-arrow.js";
|
|
60
|
+
import { tooltipTriggerAccessibleName } from "./rules/tooltip-trigger-accessible-name.js";
|
|
20
61
|
import { strictDesignSystemSelectors } from "./strict-design-system.js";
|
|
21
62
|
|
|
22
63
|
/**
|
|
@@ -106,20 +147,61 @@ const plugin = {
|
|
|
106
147
|
configs: {},
|
|
107
148
|
rules: {
|
|
108
149
|
...strictSelectorRules,
|
|
150
|
+
"badge-is-static-label": badgeIsStaticLabel,
|
|
151
|
+
"button-icon-slot": buttonIconSlot,
|
|
152
|
+
"button-link-for-navigation": buttonLinkForNavigation,
|
|
153
|
+
"button-no-aria-label-with-text": buttonNoAriaLabelWithText,
|
|
154
|
+
"button-type-roles-only-in-buttons": buttonTypeRolesOnlyInButtons,
|
|
155
|
+
"choice-control-has-a-name": choiceControlHasAName,
|
|
156
|
+
"choice-group-in-fieldset": choiceGroupInFieldset,
|
|
157
|
+
"command-shortcut-single-owner": commandShortcutSingleOwner,
|
|
158
|
+
"confirm-dialog-words": confirmDialogWords,
|
|
159
|
+
"data-table-one-unsized-column": dataTableOneUnsizedColumn,
|
|
160
|
+
"destructive-action-placement": destructiveActionPlacement,
|
|
161
|
+
"disabled-choice-says-why": disabledChoiceSaysWhy,
|
|
162
|
+
"settings-limit-in-footer": settingsLimitInFooter,
|
|
163
|
+
"ellipsis-opens-a-dialog": ellipsisOpensADialog,
|
|
109
164
|
"empty-state-owner": emptyStateOwner,
|
|
165
|
+
"input-group-owners": inputGroupOwners,
|
|
166
|
+
"kbd-children-no-modifier-text": kbdChildrenNoModifierText,
|
|
110
167
|
"menu-owner": menuOwner,
|
|
168
|
+
"middle-truncate-placement": middleTruncatePlacement,
|
|
111
169
|
"no-app-feature-component": noAppFeatureComponent,
|
|
170
|
+
"no-bare-button-label": noBareButtonLabel,
|
|
112
171
|
"no-choice-control-wrapper": noChoiceControlWrapper,
|
|
113
172
|
"no-comment": noComment,
|
|
173
|
+
"no-control-in-read-only-surface": noControlInReadOnlySurface,
|
|
114
174
|
"no-decorative-icon": noDecorativeIcon,
|
|
115
175
|
"no-deprecated-zod-api": noDeprecatedZodApi,
|
|
116
176
|
"no-global-patch": noGlobalPatch,
|
|
177
|
+
"no-hand-built-busy": noHandBuiltBusy,
|
|
178
|
+
"no-hand-built-theme-picker": noHandBuiltThemePicker,
|
|
179
|
+
"no-hand-built-tile": noHandBuiltTile,
|
|
180
|
+
"no-hand-formatted-date": noHandFormattedDate,
|
|
181
|
+
"no-hand-stacked-avatars": noHandStackedAvatars,
|
|
182
|
+
"no-nested-collapse": noNestedCollapse,
|
|
117
183
|
"no-package-component-redefinition": noPackageComponentRedefinition,
|
|
184
|
+
"no-search-in-form": noSearchInForm,
|
|
118
185
|
"no-shadcn-appearance-override": noShadcnAppearanceOverride,
|
|
186
|
+
"no-shell-prompt-in-snippet": noShellPromptInSnippet,
|
|
187
|
+
"no-stock-error-words": noStockErrorWords,
|
|
119
188
|
"no-subject-derived-expectation": noSubjectDerivedExpectation,
|
|
189
|
+
"no-tooltip-around-labelled-field": noTooltipAroundLabelledField,
|
|
190
|
+
"no-weight-class-on-strong-in-type-role": noWeightClassOnStrongInTypeRole,
|
|
120
191
|
"no-write-in-subscription": noWriteInSubscription,
|
|
192
|
+
"one-submenu-level": oneSubmenuLevel,
|
|
193
|
+
"one-toast-per-flow": oneToastPerFlow,
|
|
194
|
+
"option-count": optionCount,
|
|
195
|
+
"page-command-link-not-render": pageCommandLinkNotRender,
|
|
121
196
|
"page-composition": pageComposition,
|
|
197
|
+
"progress-needs-name": progressNeedsName,
|
|
122
198
|
"server-action-discipline": serverActionDiscipline,
|
|
199
|
+
"skeleton-in-region": skeletonInRegion,
|
|
200
|
+
"sortable-heading-uses-sort": sortableHeadingUsesSort,
|
|
201
|
+
"table-cell-inset-owner": tableCellInsetOwner,
|
|
202
|
+
"tabs-selection-is-controlled": tabsSelectionIsControlled,
|
|
203
|
+
"tooltip-only-arrow": tooltipOnlyArrow,
|
|
204
|
+
"tooltip-trigger-accessible-name": tooltipTriggerAccessibleName,
|
|
123
205
|
},
|
|
124
206
|
};
|
|
125
207
|
|
|
@@ -0,0 +1,93 @@
|
|
|
1
|
+
/*
|
|
2
|
+
* Standard tool checked first: a `no-restricted-syntax` selector such as
|
|
3
|
+
* `Badge Badge` matches a name written in the file, not the element bound to
|
|
4
|
+
* the package's Badge, so it misses a renamed import and flags a product's own
|
|
5
|
+
* `Badge`; and `Badge[icon]` cannot tell a label inside the `icon` prop from
|
|
6
|
+
* an icon. This rule joins each element to its import first.
|
|
7
|
+
*/
|
|
8
|
+
import { partOf, renderedImports, staticAttribute } from "./rendered-import.js";
|
|
9
|
+
|
|
10
|
+
const exportedBy = (module) => [
|
|
11
|
+
{ from: `@nadicodeai/ui/components/${module}`, part: module },
|
|
12
|
+
{ from: "@nadicodeai/ui", part: module },
|
|
13
|
+
{ from: `@/components/${module}`, part: module },
|
|
14
|
+
];
|
|
15
|
+
|
|
16
|
+
const PARTS = new Map([
|
|
17
|
+
["Badge", exportedBy("badge")],
|
|
18
|
+
[
|
|
19
|
+
"StatusBadge",
|
|
20
|
+
[
|
|
21
|
+
...exportedBy("status-badge"),
|
|
22
|
+
{ from: "@/components/kit/status-badge", part: "status-badge" },
|
|
23
|
+
],
|
|
24
|
+
],
|
|
25
|
+
["Tag", exportedBy("tag")],
|
|
26
|
+
["TrendBadge", exportedBy("trend-badge")],
|
|
27
|
+
]);
|
|
28
|
+
|
|
29
|
+
const HOSTS = new Set(["badge", "status-badge"]);
|
|
30
|
+
const BUTTON_ATTRIBUTES = new Set(["tabIndex", "aria-pressed", "onKeyDown", "onKeyUp"]);
|
|
31
|
+
|
|
32
|
+
const attributeName = (attribute) =>
|
|
33
|
+
attribute.type === "JSXAttribute" && attribute.name.type === "JSXIdentifier"
|
|
34
|
+
? attribute.name.name
|
|
35
|
+
: null;
|
|
36
|
+
|
|
37
|
+
export const badgeIsStaticLabel = {
|
|
38
|
+
meta: {
|
|
39
|
+
type: "problem",
|
|
40
|
+
docs: {
|
|
41
|
+
description:
|
|
42
|
+
"A Badge or StatusBadge is a static label: no label inside it, no button behaviour on it.",
|
|
43
|
+
},
|
|
44
|
+
schema: [],
|
|
45
|
+
messages: {
|
|
46
|
+
"static-label":
|
|
47
|
+
'A badge is a static label of text, or one icon and text. Put a second label beside it; a value that can be acted on is a Button, or a link with <Badge render={<a href=... />} variant="pill">.',
|
|
48
|
+
},
|
|
49
|
+
},
|
|
50
|
+
create(context) {
|
|
51
|
+
const importOf = renderedImports(context);
|
|
52
|
+
const partOfElement = (element) =>
|
|
53
|
+
partOf(importOf(element.openingElement.name), PARTS, context.filename);
|
|
54
|
+
const isHost = (opening) => HOSTS.has(partOf(importOf(opening.name), PARTS, context.filename));
|
|
55
|
+
|
|
56
|
+
function holdingHost(label) {
|
|
57
|
+
let child = label;
|
|
58
|
+
for (let current = label.parent; current; child = current, current = current.parent) {
|
|
59
|
+
const holdsAsChild =
|
|
60
|
+
current.type === "JSXElement" &&
|
|
61
|
+
current.children.includes(child) &&
|
|
62
|
+
isHost(current.openingElement);
|
|
63
|
+
if (holdsAsChild) return current;
|
|
64
|
+
if (
|
|
65
|
+
current.type === "JSXAttribute" &&
|
|
66
|
+
attributeName(current) === "icon" &&
|
|
67
|
+
isHost(current.parent)
|
|
68
|
+
) {
|
|
69
|
+
return current.parent;
|
|
70
|
+
}
|
|
71
|
+
}
|
|
72
|
+
return null;
|
|
73
|
+
}
|
|
74
|
+
|
|
75
|
+
return {
|
|
76
|
+
JSXElement(node) {
|
|
77
|
+
if (partOfElement(node) && holdingHost(node)) {
|
|
78
|
+
context.report({ node, messageId: "static-label" });
|
|
79
|
+
}
|
|
80
|
+
},
|
|
81
|
+
JSXOpeningElement(node) {
|
|
82
|
+
if (!isHost(node)) return;
|
|
83
|
+
for (const attribute of node.attributes) {
|
|
84
|
+
const name = attributeName(attribute);
|
|
85
|
+
const refused =
|
|
86
|
+
BUTTON_ATTRIBUTES.has(name) ||
|
|
87
|
+
(name === "role" && staticAttribute(node, "role") === "button");
|
|
88
|
+
if (refused) context.report({ node: attribute, messageId: "static-label" });
|
|
89
|
+
}
|
|
90
|
+
},
|
|
91
|
+
};
|
|
92
|
+
},
|
|
93
|
+
};
|
|
@@ -0,0 +1,102 @@
|
|
|
1
|
+
/*
|
|
2
|
+
* Standard tool checked first: the `repo/shadcn-composition` selector in the
|
|
3
|
+
* root config (`Button JSXOpeningElement[name.name=/Icon$/]` without
|
|
4
|
+
* `data-icon`) matches by element name under any `Button`, so it cannot tell a
|
|
5
|
+
* text Button from an icon-only one (the size decides where an icon goes), nor
|
|
6
|
+
* a `Button` imported from `@nadicodeai/ui` from a local one, nor an icon bound
|
|
7
|
+
* to an icon module from a component that only ends in `Icon`.
|
|
8
|
+
*/
|
|
9
|
+
import {
|
|
10
|
+
PACKAGE_BARREL,
|
|
11
|
+
partOf,
|
|
12
|
+
renderedImports,
|
|
13
|
+
sourceMatches,
|
|
14
|
+
staticAttribute,
|
|
15
|
+
writtenName,
|
|
16
|
+
} from "./rendered-import.js";
|
|
17
|
+
|
|
18
|
+
const BUTTONS = new Map(
|
|
19
|
+
["Button", "ButtonLink"].map((name) => [
|
|
20
|
+
name,
|
|
21
|
+
["@nadicodeai/ui/components/button", PACKAGE_BARREL].map((from) => ({ from, part: name })),
|
|
22
|
+
]),
|
|
23
|
+
);
|
|
24
|
+
|
|
25
|
+
const TEXT_SIZES = new Set(["default", "xs", "sm", "lg"]);
|
|
26
|
+
|
|
27
|
+
const isAttribute = (attribute, name) =>
|
|
28
|
+
attribute.type === "JSXAttribute" && attribute.name.name === name;
|
|
29
|
+
|
|
30
|
+
export const buttonIconSlot = {
|
|
31
|
+
meta: {
|
|
32
|
+
type: "problem",
|
|
33
|
+
docs: {
|
|
34
|
+
description:
|
|
35
|
+
"A text Button takes its icon as prefix or suffix; an icon-only Button takes the icon as its child with no data-icon.",
|
|
36
|
+
},
|
|
37
|
+
schema: [
|
|
38
|
+
{
|
|
39
|
+
type: "object",
|
|
40
|
+
properties: {
|
|
41
|
+
iconModules: { type: "array", items: { type: "string" }, uniqueItems: true },
|
|
42
|
+
},
|
|
43
|
+
additionalProperties: false,
|
|
44
|
+
},
|
|
45
|
+
],
|
|
46
|
+
defaultOptions: [{ iconModules: ["lucide-react", "@nadicodeai/ui/components/house-icons"] }],
|
|
47
|
+
messages: {
|
|
48
|
+
"icon-slot":
|
|
49
|
+
'Pass an icon in a text Button as prefix={<Icon />} or suffix={<Icon />}; an icon-only Button (size="icon") takes the icon as its child.',
|
|
50
|
+
},
|
|
51
|
+
},
|
|
52
|
+
create(context) {
|
|
53
|
+
const [{ iconModules }] = context.options;
|
|
54
|
+
const importOf = renderedImports(context);
|
|
55
|
+
const isButton = (openingElement) =>
|
|
56
|
+
partOf(importOf(openingElement.name), BUTTONS, context.filename) !== null;
|
|
57
|
+
|
|
58
|
+
const isIcon = (openingElement) => {
|
|
59
|
+
const imported = importOf(openingElement.name);
|
|
60
|
+
if (
|
|
61
|
+
imported &&
|
|
62
|
+
iconModules.some((module) => sourceMatches(imported.source, module, context.filename))
|
|
63
|
+
) {
|
|
64
|
+
return true;
|
|
65
|
+
}
|
|
66
|
+
return /Icon$/.test(writtenName(openingElement.name) ?? "");
|
|
67
|
+
};
|
|
68
|
+
|
|
69
|
+
function enclosingButton(node) {
|
|
70
|
+
for (let current = node.parent.parent; current; current = current.parent) {
|
|
71
|
+
if (current.type === "JSXAttribute") return null;
|
|
72
|
+
if (current.type === "JSXElement" && isButton(current.openingElement)) {
|
|
73
|
+
return current.openingElement;
|
|
74
|
+
}
|
|
75
|
+
}
|
|
76
|
+
return null;
|
|
77
|
+
}
|
|
78
|
+
|
|
79
|
+
function takesTextSize(button) {
|
|
80
|
+
if (button.attributes.some((attribute) => attribute.type === "JSXSpreadAttribute")) {
|
|
81
|
+
return false;
|
|
82
|
+
}
|
|
83
|
+
if (!button.attributes.some((attribute) => isAttribute(attribute, "size"))) return true;
|
|
84
|
+
return TEXT_SIZES.has(staticAttribute(button, "size"));
|
|
85
|
+
}
|
|
86
|
+
|
|
87
|
+
return {
|
|
88
|
+
JSXOpeningElement(node) {
|
|
89
|
+
if (node.parent.type !== "JSXElement") return;
|
|
90
|
+
const carriesDataIcon = node.attributes.some((attribute) =>
|
|
91
|
+
isAttribute(attribute, "data-icon"),
|
|
92
|
+
);
|
|
93
|
+
if (!carriesDataIcon && !isIcon(node)) return;
|
|
94
|
+
const button = enclosingButton(node);
|
|
95
|
+
if (!button) return;
|
|
96
|
+
if (carriesDataIcon || takesTextSize(button)) {
|
|
97
|
+
context.report({ node, messageId: "icon-slot" });
|
|
98
|
+
}
|
|
99
|
+
},
|
|
100
|
+
};
|
|
101
|
+
},
|
|
102
|
+
};
|