@eifi1/ui-kit 0.31.1 → 0.32.1
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/README.md +51 -28
- package/dist/account/delete-account-setting.d.ts +8 -3
- package/dist/admin/admin-action-confirm.d.ts +8 -3
- package/dist/admin/admin-action-log.d.ts +1 -1
- package/dist/admin/admin-action-log.js +4 -2
- package/dist/admin/admin-action-log.js.map +1 -1
- package/dist/admin/invitations-panel.d.ts +8 -3
- package/dist/admin/invitations-panel.js +29 -26
- package/dist/admin/invitations-panel.js.map +1 -1
- package/dist/admin/reviewer-scope-editor.d.ts +8 -3
- package/dist/admin/role-select.d.ts +10 -5
- package/dist/admin/transfer-ownership-dialog.d.ts +8 -3
- package/dist/admin/user-roster.d.ts +10 -5
- package/dist/admin/user-roster.js +8 -47
- package/dist/admin/user-roster.js.map +1 -1
- package/dist/auth/auth-errors.d.ts +43 -8
- package/dist/auth/auth-errors.js +24 -1
- package/dist/auth/auth-errors.js.map +1 -1
- package/dist/auth/register-form.d.ts +8 -3
- package/dist/billing/billing-banner.d.ts +184 -0
- package/dist/billing/billing-banner.js +98 -0
- package/dist/billing/billing-banner.js.map +1 -0
- package/dist/billing/billing-labels.d.ts +100 -0
- package/dist/billing/billing-labels.js +76 -0
- package/dist/billing/billing-labels.js.map +1 -0
- package/dist/billing/billing-lock.d.ts +158 -0
- package/dist/billing/billing-lock.js +17 -0
- package/dist/billing/billing-lock.js.map +1 -0
- package/dist/billing/billing-standing.d.ts +149 -0
- package/dist/billing/billing-standing.js +28 -0
- package/dist/billing/billing-standing.js.map +1 -0
- package/dist/billing/plan-card.d.ts +248 -0
- package/dist/billing/plan-card.js +248 -0
- package/dist/billing/plan-card.js.map +1 -0
- package/dist/billing/plan-limit-notice.d.ts +156 -0
- package/dist/billing/plan-limit-notice.js +76 -0
- package/dist/billing/plan-limit-notice.js.map +1 -0
- package/dist/billing/plan-limit.d.ts +34 -0
- package/dist/billing/plan-limit.js +20 -0
- package/dist/billing/plan-limit.js.map +1 -0
- package/dist/billing/plan-price.d.ts +61 -0
- package/dist/billing/plan-price.js +45 -0
- package/dist/billing/plan-price.js.map +1 -0
- package/dist/billing/subscription-actions.d.ts +133 -0
- package/dist/billing/subscription-actions.js +28 -0
- package/dist/billing/subscription-actions.js.map +1 -0
- package/dist/billing/subscription-status-chip.d.ts +149 -0
- package/dist/billing/subscription-status-chip.js +48 -0
- package/dist/billing/subscription-status-chip.js.map +1 -0
- package/dist/chart.d.ts +9 -3
- package/dist/chart.js.map +1 -1
- package/dist/components/account-chips.d.ts +16 -4
- package/dist/components/account-chips.js +21 -3
- package/dist/components/account-chips.js.map +1 -1
- package/dist/components/alert-banner.d.ts +6 -1
- package/dist/components/alert-banner.js +5 -4
- package/dist/components/alert-banner.js.map +1 -1
- package/dist/components/amount-input.d.ts +8 -3
- package/dist/components/amount-input.js +5 -5
- package/dist/components/amount-input.js.map +1 -1
- package/dist/components/appearance-labels.d.ts +38 -0
- package/dist/components/appearance-labels.js +19 -0
- package/dist/components/appearance-labels.js.map +1 -0
- package/dist/components/autocomplete.js +2 -2
- package/dist/components/autocomplete.js.map +1 -1
- package/dist/components/breadcrumbs.js +3 -2
- package/dist/components/breadcrumbs.js.map +1 -1
- package/dist/components/bulk-action-bar.d.ts +2 -2
- package/dist/components/bulk-action-bar.js +7 -12
- package/dist/components/bulk-action-bar.js.map +1 -1
- package/dist/components/button-group.d.ts +8 -3
- package/dist/components/button-group.js +7 -1
- package/dist/components/button-group.js.map +1 -1
- package/dist/components/calculator.d.ts +8 -3
- package/dist/components/calculator.js +4 -3
- package/dist/components/calculator.js.map +1 -1
- package/dist/components/calendar-heatmap.js +5 -5
- package/dist/components/calendar-heatmap.js.map +1 -1
- package/dist/components/chart-height.d.ts +23 -0
- package/dist/components/chart-height.js +15 -0
- package/dist/components/chart-height.js.map +1 -0
- package/dist/components/chart-zoom.js +6 -1
- package/dist/components/chart-zoom.js.map +1 -1
- package/dist/components/checkbox-group.js +2 -2
- package/dist/components/checkbox-group.js.map +1 -1
- package/dist/components/checkbox.d.ts +10 -0
- package/dist/components/checkbox.js +25 -10
- package/dist/components/checkbox.js.map +1 -1
- package/dist/components/chip.d.ts +19 -3
- package/dist/components/chip.js +54 -23
- package/dist/components/chip.js.map +1 -1
- package/dist/components/choice-card.d.ts +1 -1
- package/dist/components/choice-card.js +9 -8
- package/dist/components/choice-card.js.map +1 -1
- package/dist/components/column-mapper.js +1 -1
- package/dist/components/column-mapper.js.map +1 -1
- package/dist/components/combobox-core.js +8 -7
- package/dist/components/combobox-core.js.map +1 -1
- package/dist/components/combobox.js +8 -8
- package/dist/components/combobox.js.map +1 -1
- package/dist/components/confirm-dialog.d.ts +8 -3
- package/dist/components/copy-button.d.ts +10 -5
- package/dist/components/country-select.js +1 -1
- package/dist/components/country-select.js.map +1 -1
- package/dist/components/currency-select.js +3 -3
- package/dist/components/currency-select.js.map +1 -1
- package/dist/components/danger-confirm.d.ts +8 -3
- package/dist/components/data-table-cells.d.ts +1 -1
- package/dist/components/data-table-filter-popover.d.ts +1 -1
- package/dist/components/data-table-filter-popover.js +4 -1
- package/dist/components/data-table-filter-popover.js.map +1 -1
- package/dist/components/data-table-filters.d.ts +1 -1
- package/dist/components/data-table-labels.d.ts +1 -1
- package/dist/components/data-table-pagination.d.ts +3 -2
- package/dist/components/data-table-pagination.js +15 -6
- package/dist/components/data-table-pagination.js.map +1 -1
- package/dist/components/data-table.d.ts +1 -1
- package/dist/components/data-table.js +123 -52
- package/dist/components/data-table.js.map +1 -1
- package/dist/components/date-picker.d.ts +1 -1
- package/dist/components/date-picker.js +18 -6
- package/dist/components/date-picker.js.map +1 -1
- package/dist/components/description-list.js +2 -2
- package/dist/components/description-list.js.map +1 -1
- package/dist/components/dialog-frame.js +2 -1
- package/dist/components/dialog-frame.js.map +1 -1
- package/dist/components/disclosure.js +3 -2
- package/dist/components/disclosure.js.map +1 -1
- package/dist/components/dropdown.d.ts +1 -1
- package/dist/components/dropdown.js +7 -1
- package/dist/components/dropdown.js.map +1 -1
- package/dist/components/facing-pair.d.ts +19 -6
- package/dist/components/facing-pair.js +3 -2
- package/dist/components/facing-pair.js.map +1 -1
- package/dist/components/field-parts.d.ts +102 -6
- package/dist/components/field-parts.js +81 -6
- package/dist/components/field-parts.js.map +1 -1
- package/dist/components/field-sync.d.ts +4 -1
- package/dist/components/field-sync.js +12 -2
- package/dist/components/field-sync.js.map +1 -1
- package/dist/components/field.js +2 -2
- package/dist/components/field.js.map +1 -1
- package/dist/components/file-button.d.ts +8 -3
- package/dist/components/file-dropzone.d.ts +8 -3
- package/dist/components/floating-panel.js +7 -4
- package/dist/components/floating-panel.js.map +1 -1
- package/dist/components/focus-ring.d.ts +12 -0
- package/dist/components/focus-ring.js +8 -0
- package/dist/components/focus-ring.js.map +1 -0
- package/dist/components/form-actions.d.ts +8 -3
- package/dist/components/form-actions.js +33 -19
- package/dist/components/form-actions.js.map +1 -1
- package/dist/components/full-bleed-dialog.d.ts +11 -1
- package/dist/components/full-bleed-dialog.js +3 -1
- package/dist/components/full-bleed-dialog.js.map +1 -1
- package/dist/components/iban-input.d.ts +8 -3
- package/dist/components/image-grid.js +1 -1
- package/dist/components/image-grid.js.map +1 -1
- package/dist/components/inline-edit-field.js +10 -4
- package/dist/components/inline-edit-field.js.map +1 -1
- package/dist/components/language-select.d.ts +8 -3
- package/dist/components/legal-page.d.ts +26 -5
- package/dist/components/legal-page.js +3 -1
- package/dist/components/legal-page.js.map +1 -1
- package/dist/components/legal.d.ts +8 -3
- package/dist/components/legal.js +2 -1
- package/dist/components/legal.js.map +1 -1
- package/dist/components/lightbox.js +24 -2
- package/dist/components/lightbox.js.map +1 -1
- package/dist/components/line-items.js +2 -1
- package/dist/components/line-items.js.map +1 -1
- package/dist/components/list.d.ts +5 -0
- package/dist/components/list.js +13 -9
- package/dist/components/list.js.map +1 -1
- package/dist/components/measured-grid.d.ts +3 -1
- package/dist/components/measured-grid.js +38 -20
- package/dist/components/measured-grid.js.map +1 -1
- package/dist/components/menu-item.js +2 -1
- package/dist/components/menu-item.js.map +1 -1
- package/dist/components/mini-calendar.js +8 -4
- package/dist/components/mini-calendar.js.map +1 -1
- package/dist/components/money-field.d.ts +8 -3
- package/dist/components/month-picker.js +50 -39
- package/dist/components/month-picker.js.map +1 -1
- package/dist/components/nav-pills.js +1 -1
- package/dist/components/nav-pills.js.map +1 -1
- package/dist/components/number-field.d.ts +8 -3
- package/dist/components/number-input.d.ts +11 -4
- package/dist/components/number-input.js +8 -6
- package/dist/components/number-input.js.map +1 -1
- package/dist/components/numpad-sheet.d.ts +8 -3
- package/dist/components/numpad-sheet.js +2 -1
- package/dist/components/numpad-sheet.js.map +1 -1
- package/dist/components/one-time-code-input.js +2 -2
- package/dist/components/one-time-code-input.js.map +1 -1
- package/dist/components/page-contents.js +2 -2
- package/dist/components/page-contents.js.map +1 -1
- package/dist/components/phone-input.d.ts +8 -3
- package/dist/components/phone-input.js +4 -4
- package/dist/components/phone-input.js.map +1 -1
- package/dist/components/pie-chart.d.ts +8 -2
- package/dist/components/pie-chart.js +11 -7
- package/dist/components/pie-chart.js.map +1 -1
- package/dist/components/popover.d.ts +9 -1
- package/dist/components/popover.js +8 -4
- package/dist/components/popover.js.map +1 -1
- package/dist/components/row-actions.d.ts +100 -0
- package/dist/components/row-actions.js +231 -0
- package/dist/components/row-actions.js.map +1 -0
- package/dist/components/scroll-area.js +1 -1
- package/dist/components/scroll-area.js.map +1 -1
- package/dist/components/search-field.js +3 -2
- package/dist/components/search-field.js.map +1 -1
- package/dist/components/series-chart-budget.d.ts +30 -7
- package/dist/components/series-chart-budget.js +12 -4
- package/dist/components/series-chart-budget.js.map +1 -1
- package/dist/components/series-chart-ticks.d.ts +7 -1
- package/dist/components/series-chart-ticks.js +6 -0
- package/dist/components/series-chart-ticks.js.map +1 -1
- package/dist/components/series-chart.d.ts +58 -28
- package/dist/components/series-chart.js +42 -32
- package/dist/components/series-chart.js.map +1 -1
- package/dist/components/settings-fields.d.ts +57 -8
- package/dist/components/settings-fields.js +39 -1
- package/dist/components/settings-fields.js.map +1 -1
- package/dist/components/share-card.d.ts +11 -6
- package/dist/components/share-card.js +8 -2
- package/dist/components/share-card.js.map +1 -1
- package/dist/components/sign-chip.d.ts +4 -0
- package/dist/components/sign-chip.js +17 -4
- package/dist/components/sign-chip.js.map +1 -1
- package/dist/components/signature-pad.d.ts +3 -1
- package/dist/components/signature-pad.js +8 -5
- package/dist/components/signature-pad.js.map +1 -1
- package/dist/components/slider.js +7 -6
- package/dist/components/slider.js.map +1 -1
- package/dist/components/sparkline.d.ts +5 -1
- package/dist/components/sparkline.js +4 -2
- package/dist/components/sparkline.js.map +1 -1
- package/dist/components/stat-tile.d.ts +17 -1
- package/dist/components/stat-tile.js +48 -20
- package/dist/components/stat-tile.js.map +1 -1
- package/dist/components/status-dot.d.ts +4 -0
- package/dist/components/status-dot.js +9 -2
- package/dist/components/status-dot.js.map +1 -1
- package/dist/components/swipeable-row.js +10 -2
- package/dist/components/swipeable-row.js.map +1 -1
- package/dist/components/switch.d.ts +21 -7
- package/dist/components/switch.js +24 -11
- package/dist/components/switch.js.map +1 -1
- package/dist/components/table.js +2 -2
- package/dist/components/table.js.map +1 -1
- package/dist/components/text-link.d.ts +8 -3
- package/dist/components/text-link.js +1 -1
- package/dist/components/text-link.js.map +1 -1
- package/dist/components/text.d.ts +7 -2
- package/dist/components/text.js +5 -5
- package/dist/components/text.js.map +1 -1
- package/dist/components/tile-radio.js +2 -1
- package/dist/components/tile-radio.js.map +1 -1
- package/dist/components/time-input.d.ts +8 -3
- package/dist/components/toast.d.ts +18 -2
- package/dist/components/toast.js +8 -5
- package/dist/components/toast.js.map +1 -1
- package/dist/components/toggle-group.d.ts +25 -3
- package/dist/components/toggle-group.js +40 -11
- package/dist/components/toggle-group.js.map +1 -1
- package/dist/components/toggle-legend.d.ts +10 -1
- package/dist/components/toggle-legend.js +21 -7
- package/dist/components/toggle-legend.js.map +1 -1
- package/dist/components/translation-review-editor.js +1 -1
- package/dist/components/translation-review-editor.js.map +1 -1
- package/dist/components/translation-review-parts.d.ts +4 -0
- package/dist/components/translation-review.d.ts +4 -0
- package/dist/components/translation-review.js +3 -3
- package/dist/components/translation-review.js.map +1 -1
- package/dist/components/tree-view.js +3 -2
- package/dist/components/tree-view.js.map +1 -1
- package/dist/components/treemap.d.ts +5 -2
- package/dist/components/treemap.js +33 -16
- package/dist/components/treemap.js.map +1 -1
- package/dist/components/ui.d.ts +8 -3
- package/dist/components/ui.js +207 -119
- package/dist/components/ui.js.map +1 -1
- package/dist/components/use-table-state.d.ts +1 -1
- package/dist/components/user-avatar.d.ts +5 -1
- package/dist/components/user-avatar.js +1 -1
- package/dist/components/user-avatar.js.map +1 -1
- package/dist/components/wizard-stepper.js +20 -14
- package/dist/components/wizard-stepper.js.map +1 -1
- package/dist/{data-table-labels-DUELeXpa.d.ts → data-table-labels-kpAAVi6g.d.ts} +26 -2
- package/dist/data-table.d.ts +1 -1
- package/dist/{delete-account-setting-CpIhzxxZ.d.ts → delete-account-setting-FLyJf-kZ.d.ts} +642 -60
- package/dist/demo/demo-banner.js +1 -0
- package/dist/demo/demo-banner.js.map +1 -1
- package/dist/feedback/feedback-attachment.d.ts +8 -3
- package/dist/feedback/feedback-context.d.ts +8 -3
- package/dist/feedback/feedback-crash.d.ts +8 -3
- package/dist/feedback/feedback-dialog.d.ts +8 -3
- package/dist/feedback/feedback-dialog.js +3 -3
- package/dist/feedback/feedback-dialog.js.map +1 -1
- package/dist/feedback/feedback-inbox.d.ts +8 -3
- package/dist/feedback/feedback-inbox.js +2 -2
- package/dist/feedback/feedback-inbox.js.map +1 -1
- package/dist/feedback/feedback-labels.d.ts +8 -3
- package/dist/feedback/feedback-menu.d.ts +9 -4
- package/dist/feedback/feedback-record.d.ts +8 -3
- package/dist/feedback/feedback-row-detail.d.ts +8 -3
- package/dist/feedback/feedback-status-undo.d.ts +8 -3
- package/dist/feedback/feedback-submit.d.ts +8 -3
- package/dist/feedback/feedback-swipe.d.ts +8 -3
- package/dist/feedback/feedback-table.d.ts +8 -3
- package/dist/feedback/feedback-thread.d.ts +8 -3
- package/dist/feedback/feedback-thread.js +3 -3
- package/dist/feedback/feedback-thread.js.map +1 -1
- package/dist/feedback.d.ts +8 -3
- package/dist/hooks/use-anchored-panel.d.ts +32 -3
- package/dist/hooks/use-anchored-panel.js +21 -3
- package/dist/hooks/use-anchored-panel.js.map +1 -1
- package/dist/hooks/use-breakpoint.d.ts +88 -0
- package/dist/hooks/use-breakpoint.js +50 -0
- package/dist/hooks/use-breakpoint.js.map +1 -0
- package/dist/hooks/use-file-drop.d.ts +8 -3
- package/dist/hooks/use-large-text.d.ts +29 -0
- package/dist/hooks/use-large-text.js +20 -0
- package/dist/hooks/use-large-text.js.map +1 -0
- package/dist/hooks/use-windowed-rows.d.ts +52 -8
- package/dist/hooks/use-windowed-rows.js +94 -5
- package/dist/hooks/use-windowed-rows.js.map +1 -1
- package/dist/i18n/defaults.d.ts +8 -3
- package/dist/i18n/defaults.js +8 -0
- package/dist/i18n/defaults.js.map +1 -1
- package/dist/i18n/german.d.ts +8 -3
- package/dist/i18n/german.js +94 -3
- package/dist/i18n/german.js.map +1 -1
- package/dist/i18n/kit-labels.d.ts +8 -3
- package/dist/i18n/kit-labels.js.map +1 -1
- package/dist/i18n/languages.d.ts +10 -5
- package/dist/i18n/locales/de-CH.d.ts +8 -3
- package/dist/i18n/locales/en.d.ts +8 -3
- package/dist/i18n/locales/es.d.ts +8 -3
- package/dist/i18n/locales/es.js +89 -3
- package/dist/i18n/locales/es.js.map +1 -1
- package/dist/i18n/locales/fr.d.ts +8 -3
- package/dist/i18n/locales/fr.js +91 -3
- package/dist/i18n/locales/fr.js.map +1 -1
- package/dist/i18n/locales/hu.d.ts +8 -3
- package/dist/i18n/locales/hu.js +91 -3
- package/dist/i18n/locales/hu.js.map +1 -1
- package/dist/i18n/locales/it.d.ts +8 -3
- package/dist/i18n/locales/it.js +92 -3
- package/dist/i18n/locales/it.js.map +1 -1
- package/dist/i18n/locales/zh.d.ts +8 -3
- package/dist/i18n/locales/zh.js +89 -3
- package/dist/i18n/locales/zh.js.map +1 -1
- package/dist/i18n/review.d.ts +8 -3
- package/dist/i18n/review.js +15 -1
- package/dist/i18n/review.js.map +1 -1
- package/dist/index.d.ts +27 -11
- package/dist/index.js +77 -4
- package/dist/index.js.map +1 -1
- package/dist/landing/landing-actions.d.ts +8 -3
- package/dist/landing/landing-sections.d.ts +8 -3
- package/dist/landing/landing-sections.js +7 -3
- package/dist/landing/landing-sections.js.map +1 -1
- package/dist/landing/public-header.d.ts +9 -4
- package/dist/landing/public-header.js +3 -3
- package/dist/landing/public-header.js.map +1 -1
- package/dist/landing/routing.d.ts +8 -3
- package/dist/lib/cn.js +3 -2
- package/dist/lib/cn.js.map +1 -1
- package/dist/rhf/fields.d.ts +8 -3
- package/dist/rhf/fields.js +1 -1
- package/dist/rhf/fields.js.map +1 -1
- package/dist/rhf/form.d.ts +8 -3
- package/dist/rhf/form.js +2 -2
- package/dist/rhf/form.js.map +1 -1
- package/dist/rhf.d.ts +8 -3
- package/dist/search/command-palette.d.ts +1 -1
- package/dist/search/command-palette.js +9 -8
- package/dist/search/command-palette.js.map +1 -1
- package/dist/settings/settings-layout.js +2 -1
- package/dist/settings/settings-layout.js.map +1 -1
- package/dist/settings/settings-section.d.ts +8 -3
- package/dist/settings/use-account-appearance.d.ts +92 -0
- package/dist/settings/use-account-appearance.js +63 -0
- package/dist/settings/use-account-appearance.js.map +1 -0
- package/dist/settings/use-settings-route.d.ts +1 -1
- package/dist/settings/use-settings-route.js +2 -3
- package/dist/settings/use-settings-route.js.map +1 -1
- package/dist/shell/app-shell.d.ts +12 -171
- package/dist/shell/app-shell.js +144 -28
- package/dist/shell/app-shell.js.map +1 -1
- package/dist/shell/auth-layout.js +1 -1
- package/dist/shell/auth-layout.js.map +1 -1
- package/dist/shell/option-switcher-menu.js +1 -1
- package/dist/shell/option-switcher-menu.js.map +1 -1
- package/dist/shell/top-bar-brand.d.ts +8 -3
- package/dist/shell/top-bar-brand.js +3 -1
- package/dist/shell/top-bar-brand.js.map +1 -1
- package/dist/shell/topbar-action-menu.d.ts +4 -0
- package/dist/shell/topbar-action-menu.js +3 -3
- package/dist/shell/topbar-action-menu.js.map +1 -1
- package/dist/shell/topbar-controls.js +4 -4
- package/dist/shell/topbar-controls.js.map +1 -1
- package/dist/shell.d.ts +9 -5
- package/dist/theme/contrast-tokens.d.ts +41 -0
- package/dist/theme/contrast-tokens.js +59 -0
- package/dist/theme/contrast-tokens.js.map +1 -0
- package/dist/theme/contrast.d.ts +110 -0
- package/dist/theme/contrast.js +128 -0
- package/dist/theme/contrast.js.map +1 -0
- package/dist/theme/palette-presets.d.ts +12 -1
- package/dist/theme/palette-presets.js +9 -4
- package/dist/theme/palette-presets.js.map +1 -1
- package/dist/theme/palette-store.js.map +1 -1
- package/dist/theme/text-size.d.ts +173 -0
- package/dist/theme/text-size.js +121 -0
- package/dist/theme/text-size.js.map +1 -0
- package/dist/wizard/stepper-nav.d.ts +8 -3
- package/dist/wizard/wizard-summary.js +1 -1
- package/dist/wizard/wizard-summary.js.map +1 -1
- package/dist/wizard.d.ts +8 -3
- package/package.json +1 -1
- package/src/admin/admin-action-log.tsx +6 -1
- package/src/admin/invitations-panel.tsx +36 -29
- package/src/admin/user-roster.tsx +17 -72
- package/src/auth/auth-errors.ts +68 -7
- package/src/billing/billing-banner.tsx +205 -0
- package/src/billing/billing-labels.ts +240 -0
- package/src/billing/billing-lock.ts +75 -0
- package/src/billing/billing-standing.ts +72 -0
- package/src/billing/plan-card.tsx +458 -0
- package/src/billing/plan-limit-notice.tsx +145 -0
- package/src/billing/plan-limit.ts +53 -0
- package/src/billing/plan-price.ts +101 -0
- package/src/billing/subscription-actions.tsx +76 -0
- package/src/billing/subscription-status-chip.tsx +95 -0
- package/src/chart.ts +2 -0
- package/src/components/account-chips.tsx +36 -10
- package/src/components/alert-banner.tsx +16 -7
- package/src/components/amount-input.tsx +5 -5
- package/src/components/appearance-labels.ts +47 -0
- package/src/components/autocomplete.tsx +2 -2
- package/src/components/breadcrumbs.tsx +3 -3
- package/src/components/bulk-action-bar.tsx +11 -14
- package/src/components/button-group.tsx +21 -0
- package/src/components/calculator.tsx +4 -3
- package/src/components/calendar-heatmap.tsx +5 -5
- package/src/components/chart-height.ts +30 -0
- package/src/components/chart-zoom.tsx +6 -1
- package/src/components/checkbox-group.tsx +2 -2
- package/src/components/checkbox.tsx +62 -20
- package/src/components/chip.tsx +139 -30
- package/src/components/choice-card.tsx +16 -11
- package/src/components/column-mapper.tsx +1 -1
- package/src/components/combobox-core.tsx +8 -7
- package/src/components/combobox.tsx +8 -8
- package/src/components/country-select.tsx +1 -1
- package/src/components/currency-select.tsx +3 -3
- package/src/components/data-table-filter-popover.tsx +7 -1
- package/src/components/data-table-pagination.tsx +60 -31
- package/src/components/data-table.tsx +164 -43
- package/src/components/date-picker.tsx +44 -10
- package/src/components/description-list.tsx +2 -2
- package/src/components/dialog-frame.tsx +2 -1
- package/src/components/disclosure.tsx +3 -2
- package/src/components/dropdown.tsx +10 -2
- package/src/components/facing-pair.ts +12 -5
- package/src/components/field-parts.tsx +190 -7
- package/src/components/field-sync.tsx +17 -3
- package/src/components/field.tsx +2 -2
- package/src/components/floating-panel.tsx +7 -4
- package/src/components/focus-ring.ts +12 -0
- package/src/components/form-actions.tsx +55 -18
- package/src/components/full-bleed-dialog.tsx +18 -4
- package/src/components/image-grid.tsx +1 -1
- package/src/components/inline-edit-field.tsx +26 -4
- package/src/components/legal-page.tsx +28 -2
- package/src/components/legal.tsx +19 -1
- package/src/components/lightbox.tsx +24 -2
- package/src/components/line-items.tsx +7 -1
- package/src/components/list.tsx +36 -10
- package/src/components/measured-grid.tsx +49 -24
- package/src/components/menu-item.tsx +2 -2
- package/src/components/mini-calendar.tsx +8 -4
- package/src/components/month-picker.tsx +15 -6
- package/src/components/nav-pills.tsx +1 -1
- package/src/components/number-input.tsx +14 -7
- package/src/components/numpad-sheet.tsx +2 -2
- package/src/components/one-time-code-input.tsx +2 -2
- package/src/components/page-contents.tsx +2 -2
- package/src/components/phone-input.tsx +9 -4
- package/src/components/pie-chart.tsx +19 -9
- package/src/components/popover.tsx +22 -5
- package/src/components/row-actions.tsx +450 -0
- package/src/components/scroll-area.tsx +1 -1
- package/src/components/search-field.tsx +4 -2
- package/src/components/series-chart-budget.ts +40 -8
- package/src/components/series-chart-ticks.ts +10 -0
- package/src/components/series-chart.tsx +123 -72
- package/src/components/settings-fields.tsx +89 -5
- package/src/components/share-card.tsx +31 -2
- package/src/components/sign-chip.tsx +28 -4
- package/src/components/signature-pad.tsx +13 -7
- package/src/components/slider.tsx +22 -9
- package/src/components/sparkline.tsx +11 -3
- package/src/components/stat-tile.tsx +70 -14
- package/src/components/status-dot.tsx +25 -2
- package/src/components/swipeable-row.tsx +10 -2
- package/src/components/switch.tsx +57 -23
- package/src/components/table.tsx +2 -2
- package/src/components/text-link.tsx +1 -1
- package/src/components/text.tsx +11 -6
- package/src/components/tile-radio.tsx +4 -1
- package/src/components/toast.tsx +27 -7
- package/src/components/toggle-group.tsx +115 -14
- package/src/components/toggle-legend.tsx +53 -8
- package/src/components/translation-review-editor.tsx +1 -1
- package/src/components/translation-review.tsx +11 -5
- package/src/components/tree-view.tsx +3 -2
- package/src/components/treemap.tsx +27 -10
- package/src/components/ui.tsx +353 -153
- package/src/components/user-avatar.tsx +1 -1
- package/src/components/wizard-stepper.tsx +5 -1
- package/src/demo/demo-banner.tsx +5 -0
- package/src/feedback/feedback-dialog.tsx +3 -3
- package/src/feedback/feedback-inbox.tsx +2 -2
- package/src/feedback/feedback-thread.tsx +3 -3
- package/src/hooks/use-anchored-panel.ts +67 -5
- package/src/hooks/use-breakpoint.ts +132 -0
- package/src/hooks/use-large-text.ts +41 -0
- package/src/hooks/use-windowed-rows.ts +168 -12
- package/src/i18n/defaults.ts +8 -0
- package/src/i18n/german.ts +107 -0
- package/src/i18n/kit-labels.tsx +12 -0
- package/src/i18n/locales/es.ts +98 -0
- package/src/i18n/locales/fr.ts +102 -0
- package/src/i18n/locales/hu.ts +100 -0
- package/src/i18n/locales/it.ts +103 -0
- package/src/i18n/locales/zh.ts +94 -0
- package/src/i18n/review.ts +14 -0
- package/src/index.ts +76 -6
- package/src/landing/landing-sections.tsx +7 -3
- package/src/landing/public-header.tsx +4 -4
- package/src/lib/cn.ts +13 -2
- package/src/rhf/fields.tsx +1 -1
- package/src/rhf/form.tsx +2 -2
- package/src/search/command-palette.tsx +10 -9
- package/src/settings/settings-layout.tsx +2 -1
- package/src/settings/use-account-appearance.ts +148 -0
- package/src/settings/use-settings-route.ts +3 -4
- package/src/shell/app-shell.tsx +278 -54
- package/src/shell/auth-layout.tsx +1 -1
- package/src/shell/option-switcher-menu.tsx +1 -1
- package/src/shell/top-bar-brand.tsx +3 -1
- package/src/shell/topbar-action-menu.tsx +3 -3
- package/src/shell/topbar-controls.tsx +4 -4
- package/src/theme/contrast-tokens.ts +112 -0
- package/src/theme/contrast.ts +225 -0
- package/src/theme/palette-presets.ts +24 -4
- package/src/theme/palette-store.ts +6 -1
- package/src/theme/text-size.ts +283 -0
- package/src/wizard/wizard-summary.tsx +4 -2
- package/tokens.css +158 -8
|
@@ -0,0 +1,450 @@
|
|
|
1
|
+
import { isValidElement } from "react";
|
|
2
|
+
import type { KeyboardEvent, MouseEvent, ReactElement, ReactNode } from "react";
|
|
3
|
+
import { MoreHorizontal } from "lucide-react";
|
|
4
|
+
import type { LucideIcon } from "lucide-react";
|
|
5
|
+
import { cn } from "../lib/cn";
|
|
6
|
+
import { useLargeText } from "../hooks/use-large-text";
|
|
7
|
+
import { useKitLabels } from "../i18n/kit-labels";
|
|
8
|
+
import { Popover } from "./popover";
|
|
9
|
+
import { Button, CompactControls, IconButton } from "./ui";
|
|
10
|
+
import { useCommitReason } from "./write-lock";
|
|
11
|
+
import type { IconButtonSize } from "./ui";
|
|
12
|
+
import type { DataTableColumn } from "./data-table";
|
|
13
|
+
|
|
14
|
+
/**
|
|
15
|
+
* A row's actions — inline icons at Normal, one "⋯" menu at Large and above
|
|
16
|
+
* (docs/text-size-harmonization.md §10.8).
|
|
17
|
+
*
|
|
18
|
+
* At Large an IconButton shows its label as text (§4). In a dense row — a register's
|
|
19
|
+
* action column, a list row's end — every label at once does not fit: Kurvenschmiede
|
|
20
|
+
* has 44 IconButtons in rows, kastlan 119. So a row's actions collapse instead, into
|
|
21
|
+
* the menu the user roster has used since 0.31 (`UserRowActions`, now built on this):
|
|
22
|
+
* one "⋯" button, and a menu with each action's icon AND words, where a locked one stays
|
|
23
|
+
* listed and says why.
|
|
24
|
+
*
|
|
25
|
+
* The data is the roster's `UserRowActionList`, generalised: entries, and `false` /
|
|
26
|
+
* `null` for the ones a condition left out (`row.locked || {…}`).
|
|
27
|
+
*/
|
|
28
|
+
|
|
29
|
+
/** One action of a row. */
|
|
30
|
+
export interface RowAction {
|
|
31
|
+
/** React key. Default: the label. */
|
|
32
|
+
key?: string;
|
|
33
|
+
/** The action's name: the inline icon's name and tooltip, the menu entry's words. */
|
|
34
|
+
label: string;
|
|
35
|
+
/**
|
|
36
|
+
* Runs it. The kit sends nothing — the app opens its confirmation or calls its API.
|
|
37
|
+
* Optional only beside `href`; an action has one or the other (or both: `onSelect`
|
|
38
|
+
* then runs as the link is followed).
|
|
39
|
+
*/
|
|
40
|
+
onSelect?: () => void;
|
|
41
|
+
/**
|
|
42
|
+
* The action NAVIGATES — an edit page, a mail to compose (0.32.1, kastlan's 0.32
|
|
43
|
+
* report): a real link inline and in the menu, so open in a new tab, a middle click
|
|
44
|
+
* and the URL on hover work, which `onSelect` + `navigate` lost. The kit's link rule
|
|
45
|
+
* applies ({@link Button}'s `href`): in-app through the provider's `linkComponent`, an
|
|
46
|
+
* external or `#anchor` one a plain `<a>`, `mailto:` included.
|
|
47
|
+
*
|
|
48
|
+
* A link cannot carry a reason or a spinner, so an action with a `disabledReason`
|
|
49
|
+
* (or under a write lock, with `commit`) or `pending` stays a button and says why.
|
|
50
|
+
*/
|
|
51
|
+
href?: string;
|
|
52
|
+
/** With `href`: leaves the app — a new tab, and a screen reader is told so. */
|
|
53
|
+
external?: boolean;
|
|
54
|
+
/**
|
|
55
|
+
* The glyph: a Lucide icon (`Pencil`), or an element (`<Pencil />`, an app's own
|
|
56
|
+
* svg) — DataTable's `rowActions` hand their `icon` node through. Inline, an action
|
|
57
|
+
* without one is a small text button; in the menu it is the words alone.
|
|
58
|
+
*/
|
|
59
|
+
icon?: LucideIcon | ReactElement;
|
|
60
|
+
/** `danger` for delete, revoke, erase: the quiet red of IconButton's `tone="danger"`
|
|
61
|
+
* inline, the danger text tone in the menu. */
|
|
62
|
+
tone?: "default" | "danger";
|
|
63
|
+
/** Why it is not available for this row. It stays listed, focusable, and says so — an
|
|
64
|
+
* action that silently vanished would leave the reader looking for it. */
|
|
65
|
+
disabledReason?: ReactNode;
|
|
66
|
+
/**
|
|
67
|
+
* This action COMMITS — it saves, sends, deletes: under a locked
|
|
68
|
+
* {@link WriteLockProvider} it is refused with the lock's reason, as {@link Button}'s
|
|
69
|
+
* `commit` is, inline and in the menu alike. No provider, or an unlocked one: no effect.
|
|
70
|
+
*/
|
|
71
|
+
commit?: boolean;
|
|
72
|
+
/**
|
|
73
|
+
* In flight — the request it started has not answered. Inline, the icon turns into
|
|
74
|
+
* IconButton's spinner (`pending`); collapsed, the "⋯" button does, since the menu
|
|
75
|
+
* closed when the action was chosen. Either way nothing in the row can be pressed again
|
|
76
|
+
* until it settles: the "⋯" opens no menu while busy.
|
|
77
|
+
*/
|
|
78
|
+
pending?: boolean;
|
|
79
|
+
/**
|
|
80
|
+
* Not available for a moment, with nothing to explain — another action of the list
|
|
81
|
+
* is in flight (an admin panel's `busy`). The plain `disabled`; a lasting refusal is a
|
|
82
|
+
* `disabledReason`, which says why.
|
|
83
|
+
*/
|
|
84
|
+
disabled?: boolean;
|
|
85
|
+
/** Leave it out for this row. */
|
|
86
|
+
hidden?: boolean;
|
|
87
|
+
}
|
|
88
|
+
|
|
89
|
+
/** What a row's actions may be: entries, and `false` / `null` / `undefined` for the ones
|
|
90
|
+
* a condition left out. */
|
|
91
|
+
export type RowActionList = readonly (RowAction | false | null | undefined)[];
|
|
92
|
+
|
|
93
|
+
export interface RowActionsLabels {
|
|
94
|
+
/** The menu button's name when the row has no name of its own; also the actions
|
|
95
|
+
* column's (hidden) header in {@link rowActionsColumn}. */
|
|
96
|
+
actions: string;
|
|
97
|
+
/** The menu button's name, given the row's: "Actions for Ada Example". */
|
|
98
|
+
actionsFor: (name: string) => string;
|
|
99
|
+
}
|
|
100
|
+
|
|
101
|
+
export const DEFAULT_ROW_ACTIONS_LABELS: RowActionsLabels = {
|
|
102
|
+
actions: "Actions",
|
|
103
|
+
actionsFor: (name) => `Actions for ${name}`,
|
|
104
|
+
};
|
|
105
|
+
|
|
106
|
+
/**
|
|
107
|
+
* - `"auto"` (default): the icons inline at Normal; the "⋯" menu at Large and Extra
|
|
108
|
+
* large once there are two or more (§10.8). A single action stays inline at every
|
|
109
|
+
* size, with its label as text at Large — one label fits a row, and a menu of one is
|
|
110
|
+
* a detour.
|
|
111
|
+
* - `"menu"`: the menu at every size — the roster's choice, whose actions grow (§2.4
|
|
112
|
+
* there) and do not fit a phone card as a strip.
|
|
113
|
+
* - `"inline"`: the icons at every size — for a row the app knows has room; at Large
|
|
114
|
+
* each then shows its label (IconButton's `labelVisible`).
|
|
115
|
+
*/
|
|
116
|
+
export type RowActionsCollapse = "auto" | "menu" | "inline";
|
|
117
|
+
|
|
118
|
+
/** The sizes a row action comes in: IconButton's row steps. `2xs` is DataTable's
|
|
119
|
+
* compact density. At Large every one is at least a 48 px target (IconButton). */
|
|
120
|
+
export type RowActionsSize = Extract<IconButtonSize, "md" | "sm" | "xs" | "2xs">;
|
|
121
|
+
|
|
122
|
+
export interface RowActionsProps {
|
|
123
|
+
actions: RowActionList;
|
|
124
|
+
/** The row's name, for the menu button's name — "Actions for Ada Example". Without it
|
|
125
|
+
* (or `null`, as API fields often are) the button is "Actions". */
|
|
126
|
+
name?: string | null;
|
|
127
|
+
/** When the actions collapse into the menu — see {@link RowActionsCollapse}. */
|
|
128
|
+
collapse?: RowActionsCollapse;
|
|
129
|
+
/** The inline icons' and the "⋯" button's size. Default `xs`, a list row's action. */
|
|
130
|
+
size?: RowActionsSize;
|
|
131
|
+
/** The menu's width. Default `"15rem"`, in rem so it grows with the words (§3.2). */
|
|
132
|
+
menuWidth?: `${number}rem`;
|
|
133
|
+
/** On the wrapper: the inline strip, or the "⋯" button's box. */
|
|
134
|
+
className?: string;
|
|
135
|
+
labels?: Partial<RowActionsLabels>;
|
|
136
|
+
}
|
|
137
|
+
|
|
138
|
+
function visibleActions(actions: RowActionList): RowAction[] {
|
|
139
|
+
return actions.filter((a): a is RowAction => Boolean(a) && !(a as RowAction).hidden);
|
|
140
|
+
}
|
|
141
|
+
|
|
142
|
+
/** An action's glyph as a node: a component is rendered, an element is used as is. */
|
|
143
|
+
function glyphOf(icon: RowAction["icon"]): ReactNode {
|
|
144
|
+
if (icon === undefined) return null;
|
|
145
|
+
if (isValidElement(icon)) return icon;
|
|
146
|
+
const Icon = icon as LucideIcon;
|
|
147
|
+
return <Icon />;
|
|
148
|
+
}
|
|
149
|
+
|
|
150
|
+
/**
|
|
151
|
+
* A row's actions, inline or as a "⋯" menu — see {@link RowActionsCollapse}. Every
|
|
152
|
+
* control stops its click (and the Enter/Space it stands for) from reaching the row, so
|
|
153
|
+
* a clickable row or a DataTable `rowLink` does not open as well; in a DataTable column
|
|
154
|
+
* also set `noRowLink: true`, as {@link rowActionsColumn} does.
|
|
155
|
+
*
|
|
156
|
+
* Inline, the icons sit in a {@link CompactControls} region at Normal: their labels
|
|
157
|
+
* stay the names and the tooltips, and a locked one keeps its reason in the tooltip — a
|
|
158
|
+
* line under one icon of a row would break the row. In the menu a locked action's
|
|
159
|
+
* reason is a line under its words at Large and on touch (Button's
|
|
160
|
+
* `disabledReasonDisplay`).
|
|
161
|
+
*
|
|
162
|
+
* The menu is portalled, so a table's scroller cannot clip it; Escape and an outside
|
|
163
|
+
* press close it, and focus goes back to the "⋯" button, which is where a confirmation
|
|
164
|
+
* dialog then returns it.
|
|
165
|
+
*/
|
|
166
|
+
export function RowActions({
|
|
167
|
+
actions,
|
|
168
|
+
name,
|
|
169
|
+
collapse = "auto",
|
|
170
|
+
size = "xs",
|
|
171
|
+
menuWidth = "15rem",
|
|
172
|
+
className,
|
|
173
|
+
labels: labelsProp,
|
|
174
|
+
}: RowActionsProps) {
|
|
175
|
+
const labels = useKitLabels("rowActions", DEFAULT_ROW_ACTIONS_LABELS, labelsProp);
|
|
176
|
+
const large = useLargeText();
|
|
177
|
+
const entries = visibleActions(actions);
|
|
178
|
+
if (entries.length === 0) return null;
|
|
179
|
+
const asMenu = collapse === "menu" || (collapse === "auto" && large && entries.length > 1);
|
|
180
|
+
if (!asMenu) {
|
|
181
|
+
const strip = (
|
|
182
|
+
<div data-slot="row-actions" className={cn("inline-flex items-center gap-0.5", className)}>
|
|
183
|
+
{entries.map((action) => (
|
|
184
|
+
<InlineAction key={action.key ?? action.label} action={action} size={size} />
|
|
185
|
+
))}
|
|
186
|
+
</div>
|
|
187
|
+
);
|
|
188
|
+
// Compact at Normal (no room for a reason line in a row); at Large an inline action
|
|
189
|
+
// is the app's choice ("inline") or the row's only one, and shows its words.
|
|
190
|
+
return large ? strip : <CompactControls>{strip}</CompactControls>;
|
|
191
|
+
}
|
|
192
|
+
const title = name ? labels.actionsFor(name) : labels.actions;
|
|
193
|
+
// The menu closed when the action was chosen, so what is in flight shows on "⋯".
|
|
194
|
+
const busy = entries.some((action) => action.pending);
|
|
195
|
+
return (
|
|
196
|
+
<Popover
|
|
197
|
+
width={menuWidth}
|
|
198
|
+
aria-label={title}
|
|
199
|
+
className="p-1"
|
|
200
|
+
trigger={({ open, toggle, ref }) => (
|
|
201
|
+
<IconButton
|
|
202
|
+
ref={ref}
|
|
203
|
+
size={size}
|
|
204
|
+
label={title}
|
|
205
|
+
// "⋯" is read by everyone as "more actions"; the menu it opens is the words.
|
|
206
|
+
labelVisible={false}
|
|
207
|
+
aria-haspopup="dialog"
|
|
208
|
+
aria-expanded={open}
|
|
209
|
+
pending={busy}
|
|
210
|
+
stopPropagation
|
|
211
|
+
onClick={toggle}
|
|
212
|
+
className={className}
|
|
213
|
+
>
|
|
214
|
+
<MoreHorizontal />
|
|
215
|
+
</IconButton>
|
|
216
|
+
)}
|
|
217
|
+
>
|
|
218
|
+
{(close) => (
|
|
219
|
+
// React carries an event out of a portal along the COMPONENT tree, so a click on
|
|
220
|
+
// an entry (or between two) reached a clickable row or a DataTable `onRowClick`
|
|
221
|
+
// the menu was opened from, though the panel is nowhere near it in the page —
|
|
222
|
+
// only the "⋯" trigger stopped its own (0.32.1, keksdose's 0.32 report). Stopped
|
|
223
|
+
// here for the whole panel: clicks, and the Enter / Space a row also listens for.
|
|
224
|
+
// Escape goes on, to the popover that closes on it.
|
|
225
|
+
<div role="presentation" onClick={stopClick} onKeyDown={stopActivationKeys}>
|
|
226
|
+
<ul data-slot="row-actions-menu" className="space-y-0.5">
|
|
227
|
+
{entries.map((action) => (
|
|
228
|
+
<li key={action.key ?? action.label}>
|
|
229
|
+
<MenuAction action={action} close={close} />
|
|
230
|
+
</li>
|
|
231
|
+
))}
|
|
232
|
+
</ul>
|
|
233
|
+
</div>
|
|
234
|
+
)}
|
|
235
|
+
</Popover>
|
|
236
|
+
);
|
|
237
|
+
}
|
|
238
|
+
|
|
239
|
+
function stopClick(e: MouseEvent) {
|
|
240
|
+
e.stopPropagation();
|
|
241
|
+
}
|
|
242
|
+
|
|
243
|
+
function stopActivationKeys(e: KeyboardEvent) {
|
|
244
|
+
if (e.key === "Enter" || e.key === " ") e.stopPropagation();
|
|
245
|
+
}
|
|
246
|
+
|
|
247
|
+
/**
|
|
248
|
+
* The `href` an action renders as a link with, or `undefined` for a button: a link
|
|
249
|
+
* cannot carry a reason or a spinner (Button's link form has neither), so a refused
|
|
250
|
+
* action — its own `disabledReason`, or a write lock on a `commit` — and a pending one
|
|
251
|
+
* stay buttons and say so.
|
|
252
|
+
*/
|
|
253
|
+
function useActionHref(action: RowAction): string | undefined {
|
|
254
|
+
const reason = useCommitReason(action.commit, action.disabledReason);
|
|
255
|
+
const refused = reason !== undefined && reason !== null && reason !== false && reason !== "";
|
|
256
|
+
return action.href !== undefined && !action.pending && !refused ? action.href : undefined;
|
|
257
|
+
}
|
|
258
|
+
|
|
259
|
+
/** One entry of the "⋯" menu: the words, as a link for an `href`, else a button. */
|
|
260
|
+
function MenuAction({ action, close }: { action: RowAction; close: () => void }) {
|
|
261
|
+
const href = useActionHref(action);
|
|
262
|
+
const glyph = glyphOf(action.icon);
|
|
263
|
+
const words = (
|
|
264
|
+
<>
|
|
265
|
+
{glyph && (
|
|
266
|
+
<span aria-hidden className="flex shrink-0 [&_svg]:size-4">
|
|
267
|
+
{glyph}
|
|
268
|
+
</span>
|
|
269
|
+
)}
|
|
270
|
+
{action.label}
|
|
271
|
+
</>
|
|
272
|
+
);
|
|
273
|
+
const tone = action.tone === "danger" ? "danger" : undefined;
|
|
274
|
+
const select = () => {
|
|
275
|
+
close();
|
|
276
|
+
action.onSelect?.();
|
|
277
|
+
};
|
|
278
|
+
if (href !== undefined) {
|
|
279
|
+
return (
|
|
280
|
+
<Button
|
|
281
|
+
href={href}
|
|
282
|
+
external={action.external}
|
|
283
|
+
variant="ghost"
|
|
284
|
+
size="sm"
|
|
285
|
+
stretch
|
|
286
|
+
tone={tone}
|
|
287
|
+
disabled={action.disabled}
|
|
288
|
+
className="w-full justify-start text-start"
|
|
289
|
+
onClick={select}
|
|
290
|
+
>
|
|
291
|
+
{words}
|
|
292
|
+
</Button>
|
|
293
|
+
);
|
|
294
|
+
}
|
|
295
|
+
return (
|
|
296
|
+
<Button
|
|
297
|
+
type="button"
|
|
298
|
+
variant="ghost"
|
|
299
|
+
size="sm"
|
|
300
|
+
stretch
|
|
301
|
+
tone={tone}
|
|
302
|
+
disabledReason={action.disabledReason}
|
|
303
|
+
commit={action.commit}
|
|
304
|
+
pending={action.pending}
|
|
305
|
+
disabled={action.disabled}
|
|
306
|
+
className="w-full justify-start text-start"
|
|
307
|
+
onClick={select}
|
|
308
|
+
>
|
|
309
|
+
{words}
|
|
310
|
+
</Button>
|
|
311
|
+
);
|
|
312
|
+
}
|
|
313
|
+
|
|
314
|
+
/** One inline action: an IconButton with its icon, else a small text button — each a
|
|
315
|
+
* link for an `href` (see {@link useActionHref}). */
|
|
316
|
+
function InlineAction({ action, size }: { action: RowAction; size: RowActionsSize }) {
|
|
317
|
+
const href = useActionHref(action);
|
|
318
|
+
const glyph = glyphOf(action.icon);
|
|
319
|
+
const tone = action.tone === "danger" ? "danger" : undefined;
|
|
320
|
+
if (glyph) {
|
|
321
|
+
if (href !== undefined) {
|
|
322
|
+
return (
|
|
323
|
+
<IconButton
|
|
324
|
+
href={href}
|
|
325
|
+
external={action.external}
|
|
326
|
+
size={size}
|
|
327
|
+
label={action.label}
|
|
328
|
+
tone={tone}
|
|
329
|
+
disabled={action.disabled}
|
|
330
|
+
stopPropagation
|
|
331
|
+
onClick={() => action.onSelect?.()}
|
|
332
|
+
>
|
|
333
|
+
{glyph}
|
|
334
|
+
</IconButton>
|
|
335
|
+
);
|
|
336
|
+
}
|
|
337
|
+
return (
|
|
338
|
+
<IconButton
|
|
339
|
+
size={size}
|
|
340
|
+
label={action.label}
|
|
341
|
+
tone={tone}
|
|
342
|
+
disabledReason={action.disabledReason}
|
|
343
|
+
commit={action.commit}
|
|
344
|
+
pending={action.pending}
|
|
345
|
+
disabled={action.disabled}
|
|
346
|
+
stopPropagation
|
|
347
|
+
onClick={() => action.onSelect?.()}
|
|
348
|
+
>
|
|
349
|
+
{glyph}
|
|
350
|
+
</IconButton>
|
|
351
|
+
);
|
|
352
|
+
}
|
|
353
|
+
// A row listening for clicks must not open as well (IconButton's stopPropagation).
|
|
354
|
+
const stop = {
|
|
355
|
+
onClick: (e: MouseEvent) => {
|
|
356
|
+
e.stopPropagation();
|
|
357
|
+
action.onSelect?.();
|
|
358
|
+
},
|
|
359
|
+
onKeyDown: (e: KeyboardEvent) => {
|
|
360
|
+
if (e.key === "Enter" || e.key === " ") e.stopPropagation();
|
|
361
|
+
},
|
|
362
|
+
};
|
|
363
|
+
if (href !== undefined) {
|
|
364
|
+
return (
|
|
365
|
+
<Button href={href} external={action.external} variant="ghost" size="sm" tone={tone} disabled={action.disabled} {...stop}>
|
|
366
|
+
{action.label}
|
|
367
|
+
</Button>
|
|
368
|
+
);
|
|
369
|
+
}
|
|
370
|
+
return (
|
|
371
|
+
<Button
|
|
372
|
+
type="button"
|
|
373
|
+
variant="ghost"
|
|
374
|
+
size="sm"
|
|
375
|
+
tone={tone}
|
|
376
|
+
disabledReason={action.disabledReason}
|
|
377
|
+
commit={action.commit}
|
|
378
|
+
pending={action.pending}
|
|
379
|
+
disabled={action.disabled}
|
|
380
|
+
{...stop}
|
|
381
|
+
>
|
|
382
|
+
{action.label}
|
|
383
|
+
</Button>
|
|
384
|
+
);
|
|
385
|
+
}
|
|
386
|
+
|
|
387
|
+
/** The actions column's hidden header, in the provider's words. */
|
|
388
|
+
function RowActionsHeader({ text, labels }: { text?: string; labels?: Partial<RowActionsLabels> }) {
|
|
389
|
+
const resolved = useKitLabels("rowActions", DEFAULT_ROW_ACTIONS_LABELS, labels);
|
|
390
|
+
return <span className="sr-only">{text ?? resolved.actions}</span>;
|
|
391
|
+
}
|
|
392
|
+
|
|
393
|
+
export interface RowActionsColumnOptions<T> {
|
|
394
|
+
/** The column's key. Default `"actions"`. */
|
|
395
|
+
key?: string;
|
|
396
|
+
/** The row's actions — `false` / `null` for the ones a condition leaves out. */
|
|
397
|
+
actions: (row: T) => RowActionList;
|
|
398
|
+
/** The row's name, for the "⋯" button's name ("Actions for Ada Example"). `null` and
|
|
399
|
+
* `undefined` both mean "Actions". */
|
|
400
|
+
name?: (row: T) => string | null | undefined;
|
|
401
|
+
collapse?: RowActionsCollapse;
|
|
402
|
+
/** Default `xs`. */
|
|
403
|
+
size?: RowActionsSize;
|
|
404
|
+
/**
|
|
405
|
+
* The column's name as plain text — the column-settings checklist and the phone
|
|
406
|
+
* card's label read it (`DataTableColumn.headerText`). Pass the app's own word; left
|
|
407
|
+
* out, the header shows the provider's `rowActions.actions` to a screen reader and
|
|
408
|
+
* the plain-text places fall back to the column's `key`.
|
|
409
|
+
*/
|
|
410
|
+
headerText?: string;
|
|
411
|
+
labels?: Partial<RowActionsLabels>;
|
|
412
|
+
/** Anything else for the column (`mobileHidden`, `cellProps`…), merged last. */
|
|
413
|
+
column?: Partial<DataTableColumn<T>>;
|
|
414
|
+
}
|
|
415
|
+
|
|
416
|
+
/**
|
|
417
|
+
* A DataTable column of {@link RowActions} — an app's action column in one line
|
|
418
|
+
* (§10.8): inline icons at Normal, the "⋯" menu at Large with two or more actions.
|
|
419
|
+
*
|
|
420
|
+
* columns={[...columns, rowActionsColumn({ actions: (r) => [...], name: (r) => r.name })]}
|
|
421
|
+
*
|
|
422
|
+
* The header is visually hidden (the icons say what the column is), the column hugs its
|
|
423
|
+
* content at the row's end, and `noRowLink` keeps a `rowHref` anchor off it, so the
|
|
424
|
+
* buttons keep their own clicks. On a phone it is a line of the card like any column;
|
|
425
|
+
* set `column: { mobileHidden: true }` to drop it there (with `mobileDetailsInRow` it
|
|
426
|
+
* then shows in the opened row instead).
|
|
427
|
+
*/
|
|
428
|
+
export function rowActionsColumn<T>({
|
|
429
|
+
key = "actions",
|
|
430
|
+
actions,
|
|
431
|
+
name,
|
|
432
|
+
collapse,
|
|
433
|
+
size,
|
|
434
|
+
headerText,
|
|
435
|
+
labels,
|
|
436
|
+
column,
|
|
437
|
+
}: RowActionsColumnOptions<T>): DataTableColumn<T> {
|
|
438
|
+
return {
|
|
439
|
+
key,
|
|
440
|
+
header: <RowActionsHeader text={headerText} labels={labels} />,
|
|
441
|
+
headerText,
|
|
442
|
+
cell: (row) => (
|
|
443
|
+
<RowActions actions={actions(row)} name={name?.(row)} collapse={collapse} size={size} labels={labels} />
|
|
444
|
+
),
|
|
445
|
+
className: "w-px whitespace-nowrap text-end",
|
|
446
|
+
headClassName: "w-px",
|
|
447
|
+
noRowLink: true,
|
|
448
|
+
...column,
|
|
449
|
+
};
|
|
450
|
+
}
|
|
@@ -121,7 +121,7 @@ export function ScrollArea({
|
|
|
121
121
|
// a row with its own background would cover exactly the part of the ring that
|
|
122
122
|
// says where focus is. An outline paints above it, and the negative offset
|
|
123
123
|
// keeps it inside a parent that clips.
|
|
124
|
-
"focus-visible:outline-
|
|
124
|
+
"focus-visible:outline-[length:var(--focus-ring-width)] focus-visible:-outline-offset-2 focus-visible:outline-[var(--brand)]",
|
|
125
125
|
className,
|
|
126
126
|
)}
|
|
127
127
|
/>
|
|
@@ -2,7 +2,7 @@ import { forwardRef, useRef } from "react";
|
|
|
2
2
|
import type { InputHTMLAttributes } from "react";
|
|
3
3
|
import { Search, X } from "lucide-react";
|
|
4
4
|
import { cn } from "../lib/cn";
|
|
5
|
-
import { FIELD_BASE } from "./ui";
|
|
5
|
+
import { FIELD_BASE, FIELD_TOUCH_TEXT } from "./ui";
|
|
6
6
|
import { DEFAULT_COMMON_LABELS, useKitLabels } from "../i18n/kit-labels";
|
|
7
7
|
|
|
8
8
|
interface SearchFieldOwnProps
|
|
@@ -62,7 +62,9 @@ interface SearchFieldOwnProps
|
|
|
62
62
|
// itself) without even its baseline, because the header it sits in already draws
|
|
63
63
|
// the line. No `text-*` size, on purpose — the input inherits the caller's.
|
|
64
64
|
const SEARCH_INLINE =
|
|
65
|
-
"block w-full min-w-0 border-0 bg-transparent py-1 text-[var(--text-primary)] shadow-none placeholder:text-[var(--text-placeholder)] focus:outline-none focus:ring-0"
|
|
65
|
+
"block w-full min-w-0 border-0 bg-transparent py-1 text-[var(--text-primary)] shadow-none placeholder:text-[var(--text-placeholder)] focus:outline-none focus:ring-0 " +
|
|
66
|
+
// FIELD_BASE carries the 16 px touch floor (§10.1); the inline look needs it too.
|
|
67
|
+
FIELD_TOUCH_TEXT;
|
|
66
68
|
|
|
67
69
|
/**
|
|
68
70
|
* One of the two spellings is REQUIRED, and the union is how that survives the
|
|
@@ -26,7 +26,8 @@ interface BudgetAxis {
|
|
|
26
26
|
}
|
|
27
27
|
|
|
28
28
|
/**
|
|
29
|
-
* The narrowest the plot may get before the automatic budget steps in, in px
|
|
29
|
+
* The narrowest the plot may get before the automatic budget steps in, in px at Normal —
|
|
30
|
+
* × the text size's scale since 0.32 (see {@link autoAxisBudget}).
|
|
30
31
|
*
|
|
31
32
|
* About a phone's plot with one axis a side (390 px viewport, card padding, two bands
|
|
32
33
|
* of 48 + 16), where a curve's shape still reads. It is the point below which the chart
|
|
@@ -38,6 +39,12 @@ export const MIN_PLOT_WIDTH = 160;
|
|
|
38
39
|
/** The budget the automatic rule applies: one axis a side. */
|
|
39
40
|
export const NARROW_AXIS_BUDGET: SeriesChartAxisBudget = { left: 1, right: 1 };
|
|
40
41
|
|
|
42
|
+
/**
|
|
43
|
+
* The automatic rule's second step: the left axis alone — for a chart with an axis on
|
|
44
|
+
* each side that even one a side leaves too little plot (0.32, see {@link autoAxisBudget}).
|
|
45
|
+
*/
|
|
46
|
+
export const LEFT_AXIS_BUDGET: SeriesChartAxisBudget = { left: 1, right: 0 };
|
|
47
|
+
|
|
41
48
|
/** The plot's margin on a side no axis band covers — `SeriesPlot`'s own. */
|
|
42
49
|
const BARE_SIDE_MARGIN = 10;
|
|
43
50
|
|
|
@@ -85,10 +92,27 @@ export function budgetedAxes(
|
|
|
85
92
|
}
|
|
86
93
|
|
|
87
94
|
/**
|
|
88
|
-
* The automatic budget for a chart `width` px wide
|
|
89
|
-
*
|
|
90
|
-
*
|
|
91
|
-
*
|
|
95
|
+
* The automatic budget for a chart `width` px wide, in two steps — each taken only when
|
|
96
|
+
* the plot would otherwise be narrower than {@link MIN_PLOT_WIDTH} × `scale`:
|
|
97
|
+
*
|
|
98
|
+
* 1. {@link NARROW_AXIS_BUDGET}, one axis a side, when some side draws more than one
|
|
99
|
+
* (lenkbank's four-axis curve plot on a phone);
|
|
100
|
+
* 2. {@link LEFT_AXIS_BUDGET}, the left axis alone, when the chart has an axis on EACH
|
|
101
|
+
* side and one a side still leaves the plot too narrow (0.32,
|
|
102
|
+
* docs/text-size-harmonization.md §4, §10.10). At 150 % a 390 px phone's two bands
|
|
103
|
+
* are 96 px each and the plot kept about 80 px. The right-hand axis is the secondary
|
|
104
|
+
* one — the grid hangs its rules off the left — so it goes: its lines keep their own
|
|
105
|
+
* scale, and its unit moves into the tooltip, the readout and the legend
|
|
106
|
+
* ({@link axisUnit}, `seriesLegendEntries`), where its values stay readable.
|
|
107
|
+
*
|
|
108
|
+
* `scale` is the text size's (`useTextSize().scale`): the bands grow with the type
|
|
109
|
+
* (`bandWidth` is handed the scaled ones), and so does the floor (§3.2, "a chart's axis
|
|
110
|
+
* width and tick spacing are multiplied by `scale`") — the room a curve needs between
|
|
111
|
+
* labels grows with the labels.
|
|
112
|
+
*
|
|
113
|
+
* `undefined` when neither step is needed, for a single-axis chart (a facing pair's two
|
|
114
|
+
* charts each have one) and for a width that is not known (no layout, no
|
|
115
|
+
* `ResizeObserver`).
|
|
92
116
|
*
|
|
93
117
|
* Decided on the CHART's width and the axes as declared, never on the plot the budget
|
|
94
118
|
* produced, so hiding an axis cannot widen the plot back over the line and bring it
|
|
@@ -98,15 +122,23 @@ export function autoAxisBudget(
|
|
|
98
122
|
axes: readonly BudgetAxis[],
|
|
99
123
|
width: number | undefined,
|
|
100
124
|
bandWidth: (axis: BudgetAxis) => number,
|
|
125
|
+
scale = 1,
|
|
101
126
|
): SeriesChartAxisBudget | undefined {
|
|
102
127
|
if (width === undefined || !(width > 0)) return undefined;
|
|
103
128
|
const visible = axes.filter((axis) => !axis.hide);
|
|
104
129
|
const left = visible.filter((axis) => sideOf(axis) === "left");
|
|
105
130
|
const right = visible.filter((axis) => sideOf(axis) === "right");
|
|
131
|
+
const floor = MIN_PLOT_WIDTH * scale;
|
|
132
|
+
/** The plot's width with `drawn` axes drawn: what their bands and the bare sides leave. */
|
|
133
|
+
const plot = (drawn: readonly BudgetAxis[]) => {
|
|
134
|
+
const onLeft = drawn.some((axis) => sideOf(axis) === "left");
|
|
135
|
+
const onRight = drawn.some((axis) => sideOf(axis) === "right");
|
|
136
|
+
const bands = drawn.reduce((sum, axis) => sum + bandWidth(axis), 0);
|
|
137
|
+
return width - bands - (onLeft ? 0 : BARE_SIDE_MARGIN) - (onRight ? 0 : BARE_SIDE_MARGIN);
|
|
138
|
+
};
|
|
139
|
+
if (left.length && right.length && plot([left[0], right[0]]) < floor) return LEFT_AXIS_BUDGET;
|
|
106
140
|
if (left.length <= 1 && right.length <= 1) return undefined;
|
|
107
|
-
|
|
108
|
-
const margins = (left.length ? 0 : BARE_SIDE_MARGIN) + (right.length ? 0 : BARE_SIDE_MARGIN);
|
|
109
|
-
return width - bands - margins < MIN_PLOT_WIDTH ? NARROW_AXIS_BUDGET : undefined;
|
|
141
|
+
return plot(visible) < floor ? NARROW_AXIS_BUDGET : undefined;
|
|
110
142
|
}
|
|
111
143
|
|
|
112
144
|
/**
|
|
@@ -12,6 +12,16 @@
|
|
|
12
12
|
* to about twice this, which is the price of every tick being a round number. */
|
|
13
13
|
const TARGET_TICKS = 5;
|
|
14
14
|
|
|
15
|
+
/** The aim at Large and Extra large (docs/text-size-harmonization.md §4): the labels are
|
|
16
|
+
* 25–50 % wider and taller, so five of them crowd an axis that holds them at Normal. */
|
|
17
|
+
export const LARGE_TEXT_TARGET_TICKS = 3;
|
|
18
|
+
|
|
19
|
+
/** How many ticks to aim for at a text `scale` (`useTextSize().scale`): five at Normal,
|
|
20
|
+
* three from Large up. */
|
|
21
|
+
export function tickTarget(scale = 1): number {
|
|
22
|
+
return scale > 1 ? LARGE_TEXT_TARGET_TICKS : TARGET_TICKS;
|
|
23
|
+
}
|
|
24
|
+
|
|
15
25
|
/** The round step closest to `span / target`: 1, 2 or 5 times a power of ten. */
|
|
16
26
|
export function niceStep(span: number, target: number = TARGET_TICKS): number {
|
|
17
27
|
const rough = span / Math.max(1, target);
|