@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
|
@@ -2,7 +2,14 @@ import { forwardRef, useId } from "react";
|
|
|
2
2
|
import type { ChangeEvent, InputHTMLAttributes, ReactNode } from "react";
|
|
3
3
|
import { cn } from "../lib/cn";
|
|
4
4
|
import { hasMessage, mergeDescribedBy } from "./choice-parts";
|
|
5
|
-
import {
|
|
5
|
+
import {
|
|
6
|
+
DISABLED_REASON_LINE_CLASS,
|
|
7
|
+
LockedReason,
|
|
8
|
+
useDisabledReasonLine,
|
|
9
|
+
useLockReason,
|
|
10
|
+
type DisabledReasonDisplay,
|
|
11
|
+
} from "./field-parts";
|
|
12
|
+
import { FOCUS_RING } from "./focus-ring";
|
|
6
13
|
|
|
7
14
|
/**
|
|
8
15
|
* An on/off switch that is still `<input type="checkbox">`, with `role="switch"`.
|
|
@@ -14,16 +21,20 @@ import { LockedReason, useLockReason } from "./field-parts";
|
|
|
14
21
|
* the moment it is flipped; a choice that waits for a Save button is a checkbox.
|
|
15
22
|
*/
|
|
16
23
|
|
|
17
|
-
/** Geometry per size. The thumb sits `
|
|
18
|
-
* checked offset is `track width − thumb −
|
|
19
|
-
*
|
|
20
|
-
*
|
|
21
|
-
*
|
|
24
|
+
/** Geometry per size. The thumb sits `start-0.5` (0.125rem, 2 px at Normal) in from
|
|
25
|
+
* each end of the track, so its checked offset is `track width − thumb − 0.125rem`.
|
|
26
|
+
* All of it in rem since 0.32 (docs/text-size-harmonization.md §3.2, §4): the track
|
|
27
|
+
* and thumb already grew with the text, and a checked offset left in px (14 / 18) put
|
|
28
|
+
* the thumb short of the end at 125 % and in the middle at 150 %. `start-*`, never
|
|
29
|
+
* `left-*` or a `translate-x`: an inline-start offset follows the writing direction,
|
|
30
|
+
* so in a right-to-left form the thumb travels right-to-left with no `rtl:` override
|
|
31
|
+
* to keep in step. */
|
|
22
32
|
const SIZES = {
|
|
23
|
-
//
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
33
|
+
// 1.75 × 1rem track, 0.75rem thumb (28×16 / 12 at Normal): the dense setting rows in
|
|
34
|
+
// Kastlan's tables. Checked: 1.75 − 0.75 − 0.125 = 0.875rem.
|
|
35
|
+
sm: { track: "h-4 w-7", thumb: "size-3 peer-checked:start-3.5" },
|
|
36
|
+
// 2.25 × 1.25rem track, 1rem thumb (36×20 / 16). Checked: 2.25 − 1 − 0.125 = 1.125rem.
|
|
37
|
+
md: { track: "h-5 w-9", thumb: "size-4 peer-checked:start-4.5" },
|
|
27
38
|
} as const;
|
|
28
39
|
|
|
29
40
|
export type SwitchSize = keyof typeof SIZES;
|
|
@@ -38,7 +49,8 @@ export type SwitchSize = keyof typeof SIZES;
|
|
|
38
49
|
const TRACK =
|
|
39
50
|
"peer block shrink-0 cursor-pointer appearance-none rounded-full bg-[var(--border-strong)] transition-colors " +
|
|
40
51
|
"checked:bg-[var(--brand)] " +
|
|
41
|
-
|
|
52
|
+
// The kit's focus frame (§5), stood off the track so it never merges with the fill.
|
|
53
|
+
`focus:outline-none ${FOCUS_RING} focus-visible:ring-offset-2 focus-visible:ring-offset-[var(--bg-surface)] ` +
|
|
42
54
|
"disabled:cursor-not-allowed";
|
|
43
55
|
|
|
44
56
|
// The thumb, laid over the input and ignoring the pointer so every click still reaches
|
|
@@ -93,6 +105,13 @@ export interface SwitchProps extends Omit<InputHTMLAttributes<HTMLInputElement>,
|
|
|
93
105
|
* switch anew (it moves in or out of the Tooltip), as a locked Button is.
|
|
94
106
|
*/
|
|
95
107
|
disabledReason?: ReactNode;
|
|
108
|
+
/**
|
|
109
|
+
* Where `disabledReason` shows (0.32, §4 "No fact only in a tooltip"): by default, at
|
|
110
|
+
* Large and on a touch screen, as a line in the words column under the description (a
|
|
111
|
+
* bare switch: under the track), and in the tooltip otherwise. See
|
|
112
|
+
* {@link DisabledReasonDisplay}.
|
|
113
|
+
*/
|
|
114
|
+
disabledReasonDisplay?: DisabledReasonDisplay;
|
|
96
115
|
/**
|
|
97
116
|
* This switch COMMITS — flipping it saves. Under a locked {@link WriteLockProvider} it
|
|
98
117
|
* is locked the `disabledReason` way with the lock's reason (which wins over its
|
|
@@ -122,6 +141,7 @@ export const Switch = forwardRef<HTMLInputElement, SwitchProps>(function Switch(
|
|
|
122
141
|
disabled,
|
|
123
142
|
required,
|
|
124
143
|
disabledReason,
|
|
144
|
+
disabledReasonDisplay,
|
|
125
145
|
commit,
|
|
126
146
|
onClick,
|
|
127
147
|
...rest
|
|
@@ -132,6 +152,7 @@ export const Switch = forwardRef<HTMLInputElement, SwitchProps>(function Switch(
|
|
|
132
152
|
const inputId = id ?? generated;
|
|
133
153
|
const lock = useLockReason(commit, disabledReason);
|
|
134
154
|
const locked = lock.locked;
|
|
155
|
+
const reasonLine = useDisabledReasonLine(disabledReasonDisplay);
|
|
135
156
|
// Locked is disabled the focusable way — the row fades and the words stop inviting a
|
|
136
157
|
// click, as for `disabled`.
|
|
137
158
|
const looksDisabled = Boolean(disabled) || locked;
|
|
@@ -177,21 +198,28 @@ export const Switch = forwardRef<HTMLInputElement, SwitchProps>(function Switch(
|
|
|
177
198
|
</span>
|
|
178
199
|
);
|
|
179
200
|
// The Tooltip goes round the track, not the row — the row is the caller's layout. A
|
|
180
|
-
// bare switch hands its `className` to the wrapper, then the outermost element.
|
|
181
|
-
|
|
182
|
-
|
|
183
|
-
|
|
184
|
-
|
|
185
|
-
|
|
186
|
-
|
|
187
|
-
|
|
201
|
+
// bare switch hands its `className` to the wrapper, then the outermost element. With
|
|
202
|
+
// words beside it, the reason LINE goes under them instead (below), so the track
|
|
203
|
+
// stays where the row puts it.
|
|
204
|
+
const lineInWords = locked && reasonLine && !bare;
|
|
205
|
+
const control =
|
|
206
|
+
locked && !lineInWords ? (
|
|
207
|
+
<LockedReason lock={lock} line={reasonLine} className={cn("shrink-0", bare && className)}>
|
|
208
|
+
{track}
|
|
209
|
+
</LockedReason>
|
|
210
|
+
) : (
|
|
211
|
+
track
|
|
212
|
+
);
|
|
188
213
|
|
|
189
214
|
if (bare) return control;
|
|
190
215
|
|
|
191
|
-
// The switch's cell is one label line tall (text-sm,
|
|
216
|
+
// The switch's cell is one label line tall (text-sm, 1.25rem) so it centres on the
|
|
192
217
|
// FIRST line of a label that wraps, and a description underneath does not drag it
|
|
193
218
|
// down to the middle of the paragraph.
|
|
194
|
-
|
|
219
|
+
// With the reason line in the words, the row's fade moves onto its parts: the line is
|
|
220
|
+
// the one thing on the row still to be read, and at 60 % it would not be.
|
|
221
|
+
const dimParts = lineInWords;
|
|
222
|
+
const cell = <span className={cn("flex h-5 shrink-0 items-center", dimParts && "opacity-60")}>{control}</span>;
|
|
195
223
|
const words = (
|
|
196
224
|
<span className="min-w-0 flex-1">
|
|
197
225
|
{label !== undefined && (
|
|
@@ -200,6 +228,7 @@ export const Switch = forwardRef<HTMLInputElement, SwitchProps>(function Switch(
|
|
|
200
228
|
className={cn(
|
|
201
229
|
"block text-sm leading-5 text-[var(--text-primary)]",
|
|
202
230
|
looksDisabled ? "cursor-not-allowed" : "cursor-pointer select-none",
|
|
231
|
+
dimParts && "opacity-60",
|
|
203
232
|
)}
|
|
204
233
|
>
|
|
205
234
|
{label}
|
|
@@ -211,15 +240,20 @@ export const Switch = forwardRef<HTMLInputElement, SwitchProps>(function Switch(
|
|
|
211
240
|
</label>
|
|
212
241
|
)}
|
|
213
242
|
{showDescription && (
|
|
214
|
-
<span id={descriptionId} className="mt-0.5 block text-xs text-[var(--text-muted)]">
|
|
243
|
+
<span id={descriptionId} className={cn("mt-0.5 block text-xs text-[var(--text-muted)]", dimParts && "opacity-60")}>
|
|
215
244
|
{description}
|
|
216
245
|
</span>
|
|
217
246
|
)}
|
|
247
|
+
{lineInWords && (
|
|
248
|
+
<span id={lock.reasonId} className={DISABLED_REASON_LINE_CLASS}>
|
|
249
|
+
{lock.reason}
|
|
250
|
+
</span>
|
|
251
|
+
)}
|
|
218
252
|
</span>
|
|
219
253
|
);
|
|
220
254
|
|
|
221
255
|
return (
|
|
222
|
-
<div className={cn("flex items-start gap-3", looksDisabled && "opacity-60", className)}>
|
|
256
|
+
<div className={cn("flex items-start gap-3", looksDisabled && !dimParts && "opacity-60", className)}>
|
|
223
257
|
{switchPosition === "end" ? (
|
|
224
258
|
<>
|
|
225
259
|
{words}
|
package/src/components/table.tsx
CHANGED
|
@@ -242,7 +242,7 @@ const STACK_PHONE_CLASSES = cn(
|
|
|
242
242
|
"max-sm:[&_tbody_td]:block max-sm:[&_tbody_td]:px-0 max-sm:[&_tbody_td]:py-0.5 max-sm:[&_tbody_td]:text-start",
|
|
243
243
|
"max-sm:[&_tfoot_td]:block max-sm:[&_tfoot_td]:px-0 max-sm:[&_tfoot_td]:py-0.5",
|
|
244
244
|
"max-sm:[&_tbody_td:first-child]:font-medium",
|
|
245
|
-
"max-sm:[&_td[data-label]]:before:block max-sm:[&_td[data-label]]:before:text-
|
|
245
|
+
"max-sm:[&_td[data-label]]:before:block max-sm:[&_td[data-label]]:before:text-caption max-sm:[&_td[data-label]]:before:font-medium max-sm:[&_td[data-label]]:before:text-[var(--text-muted)] max-sm:[&_td[data-label]]:before:content-[attr(data-label)]",
|
|
246
246
|
);
|
|
247
247
|
|
|
248
248
|
/**
|
|
@@ -353,7 +353,7 @@ export function Table({
|
|
|
353
353
|
// rounded corners.
|
|
354
354
|
framed && "rounded-md border border-[var(--border)]",
|
|
355
355
|
THIN_SCROLLBAR_CLASS,
|
|
356
|
-
"focus-visible:outline-
|
|
356
|
+
"focus-visible:outline-[length:var(--focus-ring-width)] focus-visible:-outline-offset-2 focus-visible:outline-[var(--brand)]",
|
|
357
357
|
wrapperClassName,
|
|
358
358
|
)}
|
|
359
359
|
>
|
|
@@ -288,7 +288,7 @@ export function TextLink({
|
|
|
288
288
|
|
|
289
289
|
const look = cn(
|
|
290
290
|
"rounded-sm underline-offset-2 transition-colors",
|
|
291
|
-
"focus-visible:outline-
|
|
291
|
+
"focus-visible:outline-[length:var(--focus-ring-width)] focus-visible:outline-offset-2 focus-visible:outline-[var(--brand)]",
|
|
292
292
|
TONE[tone],
|
|
293
293
|
UNDERLINE[underline],
|
|
294
294
|
ariaCurrent && "font-semibold",
|
package/src/components/text.tsx
CHANGED
|
@@ -35,10 +35,14 @@ export type SectionLabelSize = "xs" | "md" | "sm";
|
|
|
35
35
|
* reached as a string than wrapped in a component that only takes a `className`. The
|
|
36
36
|
* uppercase is CSS, so a screen reader reads the text as written: write it in normal
|
|
37
37
|
* case.
|
|
38
|
+
*
|
|
39
|
+
* The sizes are the kit's named rem steps since 0.32 (`text-micro` 0.625rem,
|
|
40
|
+
* `text-caption` 0.6875rem — 10 and 11 px at Normal), so a label grows with the text
|
|
41
|
+
* size like everything around it (docs/text-size-harmonization.md §3.2).
|
|
38
42
|
*/
|
|
39
43
|
export const SECTION_LABEL_CLASS: Record<SectionLabelSize, string> = {
|
|
40
|
-
xs: "text-
|
|
41
|
-
md: "text-
|
|
44
|
+
xs: "text-micro font-semibold uppercase tracking-wide text-[var(--text-muted)]",
|
|
45
|
+
md: "text-caption font-semibold uppercase tracking-wide text-[var(--text-muted)]",
|
|
42
46
|
sm: "text-xs font-semibold uppercase tracking-wide text-[var(--text-muted)]",
|
|
43
47
|
};
|
|
44
48
|
|
|
@@ -61,8 +65,8 @@ export type SectionLabelVariant = "plain" | "band";
|
|
|
61
65
|
* a font-size arbitrary `text-` value from a colour one. (Not spelt out as class
|
|
62
66
|
* names here: Tailwind scans comments, and a literal one broke the showcase CSS.) */
|
|
63
67
|
const SECTION_LABEL_BAND_CLASS: Record<SectionLabelSize, string> = {
|
|
64
|
-
xs: "text-
|
|
65
|
-
md: "text-
|
|
68
|
+
xs: "text-micro",
|
|
69
|
+
md: "text-caption",
|
|
66
70
|
sm: "text-xs",
|
|
67
71
|
};
|
|
68
72
|
const BAND =
|
|
@@ -112,14 +116,15 @@ export function SectionLabel({
|
|
|
112
116
|
/* ── Caption ──────────────────────────────────────────────────────────────── */
|
|
113
117
|
|
|
114
118
|
/**
|
|
115
|
-
* The caption type as a class string:
|
|
119
|
+
* The caption type as a class string: `text-caption` (0.6875rem, 11 px at Normal, §3.2),
|
|
120
|
+
* snug, muted. lenkbank's `CAPTION`
|
|
116
121
|
* (shared/ui/caption.ts:23) — written out 31 times before it was a constant — as a
|
|
117
122
|
* token colour rather than `slate-500 dark:slate-400`, so it follows the palette.
|
|
118
123
|
* Exported for the same reason lenkbank's is a string: every caller positions it
|
|
119
124
|
* differently (`mt-1`, `self-end pb-2`, `border-t`), and what must be one thing is the
|
|
120
125
|
* type, not the box.
|
|
121
126
|
*/
|
|
122
|
-
export const CAPTION_CLASS = "text-
|
|
127
|
+
export const CAPTION_CLASS = "text-caption leading-snug text-[var(--text-muted)]";
|
|
123
128
|
|
|
124
129
|
export interface CaptionProps extends ComponentPropsWithoutRef<"p"> {
|
|
125
130
|
/** Default `p`; `span` for a caption inside a line of other content. */
|
|
@@ -2,6 +2,7 @@ import { useId, useRef } from "react";
|
|
|
2
2
|
import type { KeyboardEvent, ReactNode } from "react";
|
|
3
3
|
import { Ban, Check } from "lucide-react";
|
|
4
4
|
import { cn } from "../lib/cn";
|
|
5
|
+
import { FOCUS_RING } from "./focus-ring";
|
|
5
6
|
import { horizontalStep } from "../lib/direction";
|
|
6
7
|
import { Tooltip } from "./tooltip";
|
|
7
8
|
|
|
@@ -133,7 +134,9 @@ export interface TileRadioGroupProps<T extends string> {
|
|
|
133
134
|
*/
|
|
134
135
|
const TILE_BASE =
|
|
135
136
|
"relative inline-flex shrink-0 items-center justify-center rounded-md border transition-colors " +
|
|
136
|
-
"focus:outline-none
|
|
137
|
+
"focus:outline-none " +
|
|
138
|
+
FOCUS_RING +
|
|
139
|
+
" focus-visible:ring-offset-2 focus-visible:ring-offset-[var(--bg-surface)] " +
|
|
137
140
|
"disabled:cursor-not-allowed disabled:opacity-50";
|
|
138
141
|
const TILE_IDLE =
|
|
139
142
|
"border-[var(--border)] bg-[var(--bg-surface)] hover:border-[var(--border-strong)] hover:bg-[var(--bg-hover)]";
|
package/src/components/toast.tsx
CHANGED
|
@@ -1,8 +1,7 @@
|
|
|
1
1
|
import { useEffect, useState, useSyncExternalStore } from "react";
|
|
2
2
|
import type { CSSProperties, MouseEvent, ReactElement, ReactNode } from "react";
|
|
3
3
|
import { useKitLabels } from "../i18n/kit-labels";
|
|
4
|
-
import {
|
|
5
|
-
import { PHONE_QUERY } from "./ui";
|
|
4
|
+
import { usePhoneLayout } from "../hooks/use-breakpoint";
|
|
6
5
|
|
|
7
6
|
/**
|
|
8
7
|
* The kit's toast layer: a `toast` API and a `<Toaster>`, over sonner.
|
|
@@ -298,7 +297,9 @@ export type ToastPosition =
|
|
|
298
297
|
|
|
299
298
|
export type ToastSwipeDirection = "top" | "right" | "bottom" | "left";
|
|
300
299
|
|
|
301
|
-
/** sonner's offset: one value for every edge, or per edge. Numbers are px
|
|
300
|
+
/** sonner's offset: one value for every edge, or per edge. Numbers are px, which do not
|
|
301
|
+
* follow the text size — prefer a CSS length (rem, or a `calc()` on
|
|
302
|
+
* {@link TOASTER_OFFSET_TOP} / {@link TOASTER_OFFSET_BOTTOM}). */
|
|
302
303
|
export type ToasterOffset =
|
|
303
304
|
| string
|
|
304
305
|
| number
|
|
@@ -397,6 +398,22 @@ function subscribeDocumentTheme(onChange: () => void): () => void {
|
|
|
397
398
|
|
|
398
399
|
const px = (v: string | number) => (typeof v === "number" ? `${v}px` : v);
|
|
399
400
|
|
|
401
|
+
/**
|
|
402
|
+
* The Toaster's default distance from the top edge (desktop), as a CSS length (0.32,
|
|
403
|
+
* docs/text-size-harmonization.md §10.11): below a 3rem top bar with 1rem to spare, and
|
|
404
|
+
* the safe area. In rem, so it moves with the text size along with the top bar — an
|
|
405
|
+
* app's `offset={{ top: 64 }}` (keksdose) did not. Pass it, or a `calc()` built on it,
|
|
406
|
+
* instead of a px number.
|
|
407
|
+
*/
|
|
408
|
+
export const TOASTER_OFFSET_TOP = "calc(env(safe-area-inset-top, 0px) + 4rem)";
|
|
409
|
+
|
|
410
|
+
/**
|
|
411
|
+
* The Toaster's default distance from the bottom edge (phone), as a CSS length: above
|
|
412
|
+
* AppShell's measured bottom nav (`--app-nav-h`) or the home indicator, whichever is
|
|
413
|
+
* taller, with 0.75rem to spare.
|
|
414
|
+
*/
|
|
415
|
+
export const TOASTER_OFFSET_BOTTOM = "calc(max(var(--app-nav-h, 0px), env(safe-area-inset-bottom, 0px)) + 0.75rem)";
|
|
416
|
+
|
|
400
417
|
/**
|
|
401
418
|
* Where the toasts appear, with the kit's defaults — mount ONE, near the root and
|
|
402
419
|
* inside `<UiKitProvider>` (it reads the `toast` labels) and inside the router if a
|
|
@@ -480,14 +497,17 @@ export function Toaster({
|
|
|
480
497
|
}, [dismissOnMiddleClick, mod]);
|
|
481
498
|
|
|
482
499
|
const documentTheme = useSyncExternalStore(subscribeDocumentTheme, readDocumentTheme, () => "light" as const);
|
|
483
|
-
const phone =
|
|
500
|
+
const phone = usePhoneLayout();
|
|
484
501
|
const resolved: ToastPosition = position ?? (phone ? "bottom-center" : "top-center");
|
|
485
502
|
|
|
486
503
|
// Above the bottom nav and the home indicator: whichever is taller, since the nav
|
|
487
504
|
// already pads itself by the safe area (the same sum BulkActionBar floats on).
|
|
488
|
-
const bottom =
|
|
489
|
-
|
|
490
|
-
|
|
505
|
+
const bottom =
|
|
506
|
+
navOffset === undefined
|
|
507
|
+
? TOASTER_OFFSET_BOTTOM
|
|
508
|
+
: `calc(max(${px(navOffset)}, env(safe-area-inset-bottom, 0px)) + 0.75rem)`;
|
|
509
|
+
// Below a 3rem TopBar with the same 1rem clearance.
|
|
510
|
+
const top = TOASTER_OFFSET_TOP;
|
|
491
511
|
const computed = resolved.startsWith("bottom") ? { bottom } : { top };
|
|
492
512
|
|
|
493
513
|
if (!mod) return null;
|
|
@@ -5,7 +5,17 @@ import { horizontalStep } from "../lib/direction";
|
|
|
5
5
|
import { FIELD_INVALID, FloatingField, Label } from "./ui";
|
|
6
6
|
import { Tooltip } from "./tooltip";
|
|
7
7
|
import { useCommitReason } from "./write-lock";
|
|
8
|
-
import {
|
|
8
|
+
import {
|
|
9
|
+
DISABLED_REASON_LINE_CLASS,
|
|
10
|
+
FIELD_CAPTION_CLASS,
|
|
11
|
+
hasContent,
|
|
12
|
+
isTextHint,
|
|
13
|
+
LabelStrip,
|
|
14
|
+
useDisabledReasonLine,
|
|
15
|
+
useInlineHint,
|
|
16
|
+
type DisabledReasonDisplay,
|
|
17
|
+
} from "./field-parts";
|
|
18
|
+
import { FOCUS_RING_WIDTH } from "./focus-ring";
|
|
9
19
|
|
|
10
20
|
export interface ToggleOption<T extends string> {
|
|
11
21
|
value: T;
|
|
@@ -36,6 +46,11 @@ export interface ToggleGroupBaseProps<T extends string>
|
|
|
36
46
|
* whole ("Bewegung", not "Beweg…"), at the price of a taller group on a narrow
|
|
37
47
|
* screen (lenkbank L4: five signal types on a 390px control page). From the width
|
|
38
48
|
* where they fit, both look the same.
|
|
49
|
+
*
|
|
50
|
+
* Since 0.32 a group in the field chrome (`label`, the default placement) with four or
|
|
51
|
+
* more options wraps at Large and Extra large under `"truncate"` too, inside its frame:
|
|
52
|
+
* the type is bigger there and the field would otherwise run past a phone's edge
|
|
53
|
+
* (docs/text-size-harmonization.md §4). The keyboard is the same either way.
|
|
39
54
|
*/
|
|
40
55
|
overflow?: "truncate" | "wrap";
|
|
41
56
|
/**
|
|
@@ -116,8 +131,15 @@ export interface ToggleGroupBaseProps<T extends string>
|
|
|
116
131
|
* two stack and both keep their corners.
|
|
117
132
|
*/
|
|
118
133
|
chromeClassName?: string;
|
|
119
|
-
/**
|
|
120
|
-
*
|
|
134
|
+
/**
|
|
135
|
+
* As on a labelled {@link Select}: a {@link FieldHint} "?" on the label line, and plain
|
|
136
|
+
* text (a string) as a caption under the group. Only with `label`.
|
|
137
|
+
*
|
|
138
|
+
* 0.32.1 (keksdose's 0.32 report): text went on the label line in every placement, so
|
|
139
|
+
* `TextSizeSetting`'s hint with `labelPlacement="above"` sat beside the label in body
|
|
140
|
+
* type, and at Extra large became a column one word wide — on the setting a reader who
|
|
141
|
+
* needs large text opens first. The label line holds the "?" only (`isTextHint`).
|
|
142
|
+
*/
|
|
121
143
|
hint?: ReactNode;
|
|
122
144
|
/** The message under the field when it is wrong: paints the field's border with
|
|
123
145
|
* `--danger`, marks the group `aria-invalid` and describes it with the message, as
|
|
@@ -136,6 +158,12 @@ export interface ToggleGroupBaseProps<T extends string>
|
|
|
136
158
|
* Wins over `disabled`, as on Button: passing both keeps the group reachable.
|
|
137
159
|
*/
|
|
138
160
|
disabledReason?: ReactNode;
|
|
161
|
+
/**
|
|
162
|
+
* Where `disabledReason` shows (0.32, §4 "No fact only in a tooltip"): by default, at
|
|
163
|
+
* Large and on a touch screen, as a line under the group (where its caption goes), and
|
|
164
|
+
* in the tooltip over the segments otherwise. See {@link DisabledReasonDisplay}.
|
|
165
|
+
*/
|
|
166
|
+
disabledReasonDisplay?: DisabledReasonDisplay;
|
|
139
167
|
/**
|
|
140
168
|
* This group COMMITS — choosing an option saves it. Under a locked
|
|
141
169
|
* {@link WriteLockProvider} it takes the `disabledReason` path with the lock's
|
|
@@ -151,6 +179,11 @@ export interface ToggleGroupBaseProps<T extends string>
|
|
|
151
179
|
* The field chrome's vertical geometry — keksdose K1, the kit reintroducing feedback
|
|
152
180
|
* #117 that keksdose's hand-built chrome had fixed.
|
|
153
181
|
*
|
|
182
|
+
* In px at Normal, as measured; since 0.32 every term but the two borders is rem
|
|
183
|
+
* (§3.2), so the sum stays a labelled Select's at 125 and 150 % too — the Select's own
|
|
184
|
+
* `pt-4 pb-1` and 1.25rem line grow by the same factor (52 px at Large, 62 at Extra
|
|
185
|
+
* large). The md line was `leading-[18px]` and is `leading-[1.125rem]`.
|
|
186
|
+
*
|
|
154
187
|
* The label is the field's static label: `top-1` and 11px in a `leading-tight` line, so
|
|
155
188
|
* its line box runs from 4px to 17.75px. Until 0.22 the chrome was `pt-4` over a 20px
|
|
156
189
|
* (`leading-5`) segment, so the ACTIVE segment's fill — painted from the top of the
|
|
@@ -168,7 +201,35 @@ export interface ToggleGroupBaseProps<T extends string>
|
|
|
168
201
|
* md: 1 + 20 + 18 + 2 + 1 = 42 sm: 1 + 20 + 16 + 4 + 1 = 42
|
|
169
202
|
*/
|
|
170
203
|
const CHROME_PAD: Record<"sm" | "md", string> = { md: "pt-5 pb-0.5", sm: "pt-5 pb-1" };
|
|
171
|
-
const CHROME_SEGMENT: Record<"sm" | "md", string> = { md: "py-0 leading-[
|
|
204
|
+
const CHROME_SEGMENT: Record<"sm" | "md", string> = { md: "py-0 leading-[1.125rem]", sm: "py-0 leading-4" };
|
|
205
|
+
|
|
206
|
+
/**
|
|
207
|
+
* A group at Large and Extra large (0.32,
|
|
208
|
+
* docs/text-size-harmonization.md §4 "nothing truncates", §3.3): the segments flow onto a
|
|
209
|
+
* second row inside the group's frame instead of overflowing it. At 125 % a 390 px phone
|
|
210
|
+
* is 312 px of Normal type, and "Month / Quarter / Half-year / Year" in one row of the
|
|
211
|
+
* field ran 7 px past it: a one-row flex group is as wide as all its labels end to end
|
|
212
|
+
* when a grid or a stretched column asks how small it can get, however its segments
|
|
213
|
+
* truncate. Wrapped, it is as wide as its longest label.
|
|
214
|
+
*
|
|
215
|
+
* Wrap, not a stacked select-like list: a wrapped radio group is the same radio group —
|
|
216
|
+
* one Tab stop, and the arrow keys walk the options in reading order whichever row
|
|
217
|
+
* they are on (←/↑ back, →/↓ on, Home/End) — so nothing about the keyboard changes with
|
|
218
|
+
* the text size. A list in its place would be a second widget with its own keys.
|
|
219
|
+
*
|
|
220
|
+
* Only where it has to: `flex-wrap` breaks a row only when the segments do not fit, so
|
|
221
|
+
* a wide field at Large stays one row, and a segment shares out what its row leaves
|
|
222
|
+
* (`flex-1`); a label wider than the whole row still truncates as the last resort.
|
|
223
|
+
* A `large:` class, so it costs no render and is right on the first paint.
|
|
224
|
+
* `overflow="wrap"` wraps at every size already.
|
|
225
|
+
*
|
|
226
|
+
* 0.32.1 (Kurvenschmiede's 0.32 report): every count and every placement but the
|
|
227
|
+
* strip, not only a field of four or more. Since a row breaks only where its labels do
|
|
228
|
+
* not fit, a wrap only ever replaces a truncation — and three options in a card at
|
|
229
|
+
* Extra large on a 360 px phone read "Syst… Li… D…". The strip keeps one row: its
|
|
230
|
+
* 26 px group is what lines it up with the 42 px fields beside it (`STRIP_SEGMENT`).
|
|
231
|
+
*/
|
|
232
|
+
const WRAP_AT_LARGE = "large:flex-wrap";
|
|
172
233
|
|
|
173
234
|
/**
|
|
174
235
|
* The strip placement's segments: a 26px group (1 + 2 + 20 + 2 + 1) under the 16px
|
|
@@ -185,7 +246,7 @@ const STRIP_SEGMENT: Record<"sm" | "md", string> = { md: "py-0", sm: "py-0.5" };
|
|
|
185
246
|
* region, because a description is read when the group is entered and not again when
|
|
186
247
|
* an arrow key changes the choice underneath it.
|
|
187
248
|
*
|
|
188
|
-
* In muted
|
|
249
|
+
* In muted caption-size text under the field (or the bare group), above an `error`.
|
|
189
250
|
*/
|
|
190
251
|
type ToggleGroupCaption<V> = ReactNode | ((value: V) => ReactNode);
|
|
191
252
|
|
|
@@ -272,6 +333,7 @@ export function ToggleGroup<T extends string>(props: ToggleGroupProps<T>): React
|
|
|
272
333
|
hint,
|
|
273
334
|
error,
|
|
274
335
|
disabledReason: ownDisabledReason,
|
|
336
|
+
disabledReasonDisplay,
|
|
275
337
|
commit,
|
|
276
338
|
"aria-label": ariaLabelAttr,
|
|
277
339
|
...restWithMode
|
|
@@ -279,9 +341,17 @@ export function ToggleGroup<T extends string>(props: ToggleGroupProps<T>): React
|
|
|
279
341
|
const labelId = useId();
|
|
280
342
|
const errorId = useId();
|
|
281
343
|
const reasonId = useId();
|
|
344
|
+
const hintCaptionId = useId();
|
|
282
345
|
// The lock's reason under a locked provider (with `commit`), else the group's own.
|
|
283
346
|
const disabledReason = useCommitReason(commit, ownDisabledReason);
|
|
284
347
|
const locked = hasContent(disabledReason);
|
|
348
|
+
// §4: at Large and on touch the reason is a line under the group, not a bubble.
|
|
349
|
+
const reasonLine = useDisabledReasonLine(disabledReasonDisplay) && locked;
|
|
350
|
+
// §4: likewise a FieldHint "?" on the label line becomes a caption under the group at
|
|
351
|
+
// Large and on touch; text is a caption at every size, as Select's (see `hint`).
|
|
352
|
+
const inlineHint = useInlineHint(hint);
|
|
353
|
+
const hintAsCaption = isTextHint(hint) ? hint : inlineHint !== hint ? inlineHint : undefined;
|
|
354
|
+
const labelHint = hintAsCaption === undefined ? hint : undefined;
|
|
285
355
|
// Locked looks disabled — the dimmed group, the not-allowed cursor, no hover offer —
|
|
286
356
|
// but stays focusable; `disabled` alone also takes the segments out of the tab order.
|
|
287
357
|
const dimmed = disabled || locked;
|
|
@@ -291,6 +361,9 @@ export function ToggleGroup<T extends string>(props: ToggleGroupProps<T>): React
|
|
|
291
361
|
const field = labelled && labelPlacement === "field";
|
|
292
362
|
const above = labelled && labelPlacement === "above";
|
|
293
363
|
const strip = labelled && labelPlacement === "strip";
|
|
364
|
+
// At Large and Extra large a truncating group wraps instead, the strip excepted (see
|
|
365
|
+
// WRAP_AT_LARGE).
|
|
366
|
+
const wrapAtLarge = overflow === "truncate" && !strip;
|
|
294
367
|
const hasError = labelled && hasContent(error);
|
|
295
368
|
// Taken off the rest so neither reaches the DOM; `props` keeps them paired, which is
|
|
296
369
|
// what lets the `onChange` below be called with `null` only in the mode that allows it.
|
|
@@ -377,8 +450,11 @@ export function ToggleGroup<T extends string>(props: ToggleGroupProps<T>): React
|
|
|
377
450
|
// overlaying the selected segment's boundary. Inset keeps the ring
|
|
378
451
|
// inside the segment it belongs to; focus-visible keeps it for the
|
|
379
452
|
// keyboard, which is the only input that needs it.
|
|
453
|
+
//
|
|
454
|
+
// The ring is the kit's focus frame (0.32, §5): `--focus-ring-width` wide.
|
|
380
455
|
overflow === "wrap" ? "whitespace-nowrap" : "min-w-0 truncate",
|
|
381
|
-
"flex-1 basis-auto rounded px-3 py-1.5 text-sm font-medium transition-colors focus:outline-none focus-visible:ring-
|
|
456
|
+
"flex-1 basis-auto rounded px-3 py-1.5 text-sm font-medium transition-colors focus:outline-none focus-visible:ring-inset focus-visible:ring-[var(--border-strong)]",
|
|
457
|
+
FOCUS_RING_WIDTH,
|
|
382
458
|
size === "sm" && "px-2 py-1 text-xs",
|
|
383
459
|
// In the field chrome: no vertical padding, and the line that makes the
|
|
384
460
|
// field 42px under a strip that clears the label — see CHROME_PAD. `sm`
|
|
@@ -423,7 +499,9 @@ export function ToggleGroup<T extends string>(props: ToggleGroupProps<T>): React
|
|
|
423
499
|
aria-labelledby={labelled && ariaLabelAttr === undefined && ariaLabel === undefined ? labelId : rest["aria-labelledby"]}
|
|
424
500
|
aria-invalid={hasError || rest["aria-invalid"] || undefined}
|
|
425
501
|
aria-describedby={
|
|
426
|
-
[rest["aria-describedby"], hasCaption && captionId, hasError && errorId]
|
|
502
|
+
[rest["aria-describedby"], hintAsCaption !== undefined && hintCaptionId, hasCaption && captionId, hasError && errorId]
|
|
503
|
+
.filter(Boolean)
|
|
504
|
+
.join(" ") || undefined
|
|
427
505
|
}
|
|
428
506
|
// `aria-disabled` on the group as well as on (or `disabled` on) each button: a
|
|
429
507
|
// radio group is what the user is being refused, and a screen reader announcing
|
|
@@ -444,6 +522,7 @@ export function ToggleGroup<T extends string>(props: ToggleGroupProps<T>): React
|
|
|
444
522
|
// phone does see is the focus ring — see the segment's own note below.)
|
|
445
523
|
"inline-flex w-full gap-0.5 rounded-md border border-[var(--border-strong)] bg-[var(--bg-surface)] p-0.5 shadow-sm",
|
|
446
524
|
overflow === "wrap" && "flex-wrap",
|
|
525
|
+
wrapAtLarge && WRAP_AT_LARGE,
|
|
447
526
|
// The whole group fades, the way every other disabled control in this
|
|
448
527
|
// package does; `cursor-not-allowed` is on the buttons, which is what a
|
|
449
528
|
// pointer is actually over.
|
|
@@ -456,7 +535,7 @@ export function ToggleGroup<T extends string>(props: ToggleGroupProps<T>): React
|
|
|
456
535
|
!labelled && className,
|
|
457
536
|
)}
|
|
458
537
|
>
|
|
459
|
-
{locked ? (
|
|
538
|
+
{locked && !reasonLine ? (
|
|
460
539
|
// The reason's bubble wraps the SEGMENTS, inside the group, not the group: a
|
|
461
540
|
// wrapper outside it would become the flex or grid item in the caller's row in
|
|
462
541
|
// the group's place, and a `w-full` / `md:w-auto` on the group would size the
|
|
@@ -487,16 +566,34 @@ export function ToggleGroup<T extends string>(props: ToggleGroupProps<T>): React
|
|
|
487
566
|
<p
|
|
488
567
|
id={captionId}
|
|
489
568
|
aria-live={captionIsLive ? "polite" : undefined}
|
|
490
|
-
className={cn("text-
|
|
569
|
+
className={cn("text-caption leading-snug text-[var(--text-muted)]", hasCaption && "mt-1")}
|
|
491
570
|
>
|
|
492
571
|
{hasCaption ? captionNode : null}
|
|
493
572
|
</p>
|
|
494
573
|
) : null;
|
|
495
574
|
const errorEl = hasError ? (
|
|
496
|
-
<p id={errorId} className="mt-1 text-
|
|
575
|
+
<p id={errorId} className="mt-1 text-caption leading-tight text-[var(--danger)]">
|
|
497
576
|
{error}
|
|
498
577
|
</p>
|
|
499
578
|
) : null;
|
|
579
|
+
// §4: the FieldHint's words and the lock's reason, under the group, before the caption
|
|
580
|
+
// (standing advice first) and the error (the news). The reason line IS what each
|
|
581
|
+
// segment's `aria-describedby` names.
|
|
582
|
+
const belowEl =
|
|
583
|
+
hintAsCaption !== undefined || reasonLine ? (
|
|
584
|
+
<>
|
|
585
|
+
{hintAsCaption !== undefined && (
|
|
586
|
+
<p id={hintCaptionId} className={FIELD_CAPTION_CLASS}>
|
|
587
|
+
{hintAsCaption}
|
|
588
|
+
</p>
|
|
589
|
+
)}
|
|
590
|
+
{reasonLine && (
|
|
591
|
+
<p id={reasonId} className={DISABLED_REASON_LINE_CLASS}>
|
|
592
|
+
{disabledReason}
|
|
593
|
+
</p>
|
|
594
|
+
)}
|
|
595
|
+
</>
|
|
596
|
+
) : null;
|
|
500
597
|
if (above) {
|
|
501
598
|
// `relative` so a caller's `sr-only` label cannot escape (sr-only-containment).
|
|
502
599
|
return (
|
|
@@ -512,10 +609,11 @@ export function ToggleGroup<T extends string>(props: ToggleGroupProps<T>): React
|
|
|
512
609
|
>
|
|
513
610
|
{label}
|
|
514
611
|
</Label>
|
|
515
|
-
{
|
|
612
|
+
{labelHint}
|
|
516
613
|
</div>
|
|
517
614
|
<div className="min-w-0">
|
|
518
615
|
{group}
|
|
616
|
+
{belowEl}
|
|
519
617
|
{captionEl}
|
|
520
618
|
{errorEl}
|
|
521
619
|
</div>
|
|
@@ -524,19 +622,21 @@ export function ToggleGroup<T extends string>(props: ToggleGroupProps<T>): React
|
|
|
524
622
|
}
|
|
525
623
|
if (strip) {
|
|
526
624
|
return (
|
|
527
|
-
<LabelStrip labelId={labelId} label={label} hint={
|
|
625
|
+
<LabelStrip labelId={labelId} label={label} hint={labelHint} disabled={dimmed} pad="field" className={className}>
|
|
528
626
|
{group}
|
|
627
|
+
{belowEl}
|
|
529
628
|
{captionEl}
|
|
530
629
|
{errorEl}
|
|
531
630
|
</LabelStrip>
|
|
532
631
|
);
|
|
533
632
|
}
|
|
534
633
|
if (!field) {
|
|
535
|
-
if (!captionEl) return group;
|
|
634
|
+
if (!captionEl && !belowEl) return group;
|
|
536
635
|
// The group keeps its `className`, as without a caption; the wrapper only stacks.
|
|
537
636
|
return (
|
|
538
637
|
<div className="min-w-0">
|
|
539
638
|
{group}
|
|
639
|
+
{belowEl}
|
|
540
640
|
{captionEl}
|
|
541
641
|
</div>
|
|
542
642
|
);
|
|
@@ -549,7 +649,7 @@ export function ToggleGroup<T extends string>(props: ToggleGroupProps<T>): React
|
|
|
549
649
|
className="flex flex-1 flex-col"
|
|
550
650
|
label={<span id={labelId}>{label}</span>}
|
|
551
651
|
staticLabel
|
|
552
|
-
hint={
|
|
652
|
+
hint={labelHint}
|
|
553
653
|
>
|
|
554
654
|
<div
|
|
555
655
|
className={cn(
|
|
@@ -563,6 +663,7 @@ export function ToggleGroup<T extends string>(props: ToggleGroupProps<T>): React
|
|
|
563
663
|
{group}
|
|
564
664
|
</div>
|
|
565
665
|
</FloatingField>
|
|
666
|
+
{belowEl}
|
|
566
667
|
{captionEl}
|
|
567
668
|
{errorEl}
|
|
568
669
|
</div>
|