@eifi1/ui-kit 0.31.0 → 0.32.0
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 +53 -30
- package/dist/account/delete-account-setting.d.ts +8 -3
- package/dist/admin/admin-action-confirm.d.ts +8 -3
- package/dist/admin/admin-parts.d.ts +8 -1
- package/dist/admin/admin-parts.js +1 -1
- package/dist/admin/admin-parts.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/auth/reset-password-form.d.ts +1 -1
- package/dist/auth/reset-password-form.js +2 -1
- package/dist/auth/reset-password-form.js.map +1 -1
- package/dist/auth/verify-email.d.ts +4 -0
- package/dist/auth/verify-email.js +3 -2
- package/dist/auth/verify-email.js.map +1 -1
- 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 +74 -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/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 +4 -3
- 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 +32 -0
- package/dist/components/appearance-labels.js +18 -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/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 +47 -21
- package/dist/components/chip.js.map +1 -1
- package/dist/components/choice-card.d.ts +1 -1
- package/dist/components/choice-card.js +8 -7
- 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/confirm-dialog.js +7 -1
- package/dist/components/confirm-dialog.js.map +1 -1
- 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 +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 +7 -5
- 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 +6 -3
- 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 +9 -5
- 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 +2 -2
- 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 +165 -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 +51 -6
- package/dist/components/settings-fields.js +37 -0
- package/dist/components/settings-fields.js.map +1 -1
- package/dist/components/share-card.d.ts +11 -6
- package/dist/components/share-card.js +2 -0
- 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/swipeable-row.js +2 -1
- 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 +16 -1
- 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-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 +202 -114
- 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/{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-DCFS5Vof.d.ts → delete-account-setting-BvdQdbv3.d.ts} +613 -58
- 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 +77 -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 +91 -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 +86 -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 +88 -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 +88 -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 +89 -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 +86 -3
- package/dist/i18n/locales/zh.js.map +1 -1
- package/dist/i18n/review.d.ts +8 -3
- package/dist/i18n/review.js +16 -1
- package/dist/i18n/review.js.map +1 -1
- package/dist/index.d.ts +29 -13
- package/dist/index.js +77 -5
- package/dist/index.js.map +1 -1
- package/dist/landing/landing-actions.d.ts +12 -5
- package/dist/landing/landing-actions.js +1 -1
- package/dist/landing/landing-actions.js.map +1 -1
- package/dist/landing/landing-sections.d.ts +8 -3
- 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 +27 -9
- package/dist/landing/routing.js +5 -2
- package/dist/landing/routing.js.map +1 -1
- 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-labels.d.ts +8 -1
- package/dist/settings/settings-labels.js +7 -2
- package/dist/settings/settings-labels.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 +10 -6
- package/dist/shell.js.map +1 -1
- 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 +109 -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 +157 -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.d.ts +8 -3
- package/package.json +1 -1
- package/src/admin/admin-parts.ts +9 -2
- 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/auth/reset-password-form.tsx +6 -2
- package/src/auth/verify-email.tsx +14 -2
- package/src/billing/billing-banner.tsx +205 -0
- package/src/billing/billing-labels.ts +224 -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/components/account-chips.tsx +36 -10
- package/src/components/alert-banner.tsx +11 -6
- package/src/components/amount-input.tsx +5 -5
- package/src/components/appearance-labels.ts +40 -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/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 +105 -24
- package/src/components/choice-card.tsx +15 -10
- 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/confirm-dialog.tsx +20 -1
- 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.tsx +160 -43
- package/src/components/date-picker.tsx +12 -9
- 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 +6 -3
- 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 +9 -5
- 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 +2 -2
- package/src/components/pie-chart.tsx +19 -9
- package/src/components/popover.tsx +22 -5
- package/src/components/row-actions.tsx +344 -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 +81 -2
- package/src/components/share-card.tsx +10 -0
- 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/swipeable-row.tsx +2 -1
- 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 +99 -12
- package/src/components/toggle-legend.tsx +53 -8
- package/src/components/translation-review.tsx +10 -5
- package/src/components/tree-view.tsx +3 -2
- package/src/components/treemap.tsx +27 -10
- package/src/components/ui.tsx +331 -145
- package/src/components/user-avatar.tsx +1 -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 +121 -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 +105 -1
- package/src/i18n/kit-labels.tsx +12 -0
- package/src/i18n/locales/es.ts +96 -1
- package/src/i18n/locales/fr.ts +100 -1
- package/src/i18n/locales/hu.ts +98 -1
- package/src/i18n/locales/it.ts +101 -1
- package/src/i18n/locales/zh.ts +92 -1
- package/src/i18n/review.ts +15 -0
- package/src/index.ts +82 -8
- package/src/landing/landing-actions.tsx +9 -5
- package/src/landing/public-header.tsx +4 -4
- package/src/landing/routing.tsx +22 -5
- 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-labels.ts +13 -1
- 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/shell.ts +7 -1
- package/src/theme/contrast-tokens.ts +112 -0
- package/src/theme/contrast.ts +224 -0
- package/src/theme/palette-presets.ts +24 -4
- package/src/theme/palette-store.ts +6 -1
- package/src/theme/text-size.ts +267 -0
- package/tokens.css +143 -1
|
@@ -5,7 +5,16 @@ 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
|
+
LabelStrip,
|
|
13
|
+
useDisabledReasonLine,
|
|
14
|
+
useInlineHint,
|
|
15
|
+
type DisabledReasonDisplay,
|
|
16
|
+
} from "./field-parts";
|
|
17
|
+
import { FOCUS_RING_WIDTH } from "./focus-ring";
|
|
9
18
|
|
|
10
19
|
export interface ToggleOption<T extends string> {
|
|
11
20
|
value: T;
|
|
@@ -36,6 +45,11 @@ export interface ToggleGroupBaseProps<T extends string>
|
|
|
36
45
|
* whole ("Bewegung", not "Beweg…"), at the price of a taller group on a narrow
|
|
37
46
|
* screen (lenkbank L4: five signal types on a 390px control page). From the width
|
|
38
47
|
* where they fit, both look the same.
|
|
48
|
+
*
|
|
49
|
+
* Since 0.32 a group in the field chrome (`label`, the default placement) with four or
|
|
50
|
+
* more options wraps at Large and Extra large under `"truncate"` too, inside its frame:
|
|
51
|
+
* the type is bigger there and the field would otherwise run past a phone's edge
|
|
52
|
+
* (docs/text-size-harmonization.md §4). The keyboard is the same either way.
|
|
39
53
|
*/
|
|
40
54
|
overflow?: "truncate" | "wrap";
|
|
41
55
|
/**
|
|
@@ -136,6 +150,12 @@ export interface ToggleGroupBaseProps<T extends string>
|
|
|
136
150
|
* Wins over `disabled`, as on Button: passing both keeps the group reachable.
|
|
137
151
|
*/
|
|
138
152
|
disabledReason?: ReactNode;
|
|
153
|
+
/**
|
|
154
|
+
* Where `disabledReason` shows (0.32, §4 "No fact only in a tooltip"): by default, at
|
|
155
|
+
* Large and on a touch screen, as a line under the group (where its caption goes), and
|
|
156
|
+
* in the tooltip over the segments otherwise. See {@link DisabledReasonDisplay}.
|
|
157
|
+
*/
|
|
158
|
+
disabledReasonDisplay?: DisabledReasonDisplay;
|
|
139
159
|
/**
|
|
140
160
|
* This group COMMITS — choosing an option saves it. Under a locked
|
|
141
161
|
* {@link WriteLockProvider} it takes the `disabledReason` path with the lock's
|
|
@@ -151,6 +171,11 @@ export interface ToggleGroupBaseProps<T extends string>
|
|
|
151
171
|
* The field chrome's vertical geometry — keksdose K1, the kit reintroducing feedback
|
|
152
172
|
* #117 that keksdose's hand-built chrome had fixed.
|
|
153
173
|
*
|
|
174
|
+
* In px at Normal, as measured; since 0.32 every term but the two borders is rem
|
|
175
|
+
* (§3.2), so the sum stays a labelled Select's at 125 and 150 % too — the Select's own
|
|
176
|
+
* `pt-4 pb-1` and 1.25rem line grow by the same factor (52 px at Large, 62 at Extra
|
|
177
|
+
* large). The md line was `leading-[18px]` and is `leading-[1.125rem]`.
|
|
178
|
+
*
|
|
154
179
|
* The label is the field's static label: `top-1` and 11px in a `leading-tight` line, so
|
|
155
180
|
* its line box runs from 4px to 17.75px. Until 0.22 the chrome was `pt-4` over a 20px
|
|
156
181
|
* (`leading-5`) segment, so the ACTIVE segment's fill — painted from the top of the
|
|
@@ -168,7 +193,31 @@ export interface ToggleGroupBaseProps<T extends string>
|
|
|
168
193
|
* md: 1 + 20 + 18 + 2 + 1 = 42 sm: 1 + 20 + 16 + 4 + 1 = 42
|
|
169
194
|
*/
|
|
170
195
|
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-[
|
|
196
|
+
const CHROME_SEGMENT: Record<"sm" | "md", string> = { md: "py-0 leading-[1.125rem]", sm: "py-0 leading-4" };
|
|
197
|
+
|
|
198
|
+
/**
|
|
199
|
+
* A field of four or more options at Large and Extra large (0.32,
|
|
200
|
+
* docs/text-size-harmonization.md §4 "nothing truncates", §3.3): the segments flow onto a
|
|
201
|
+
* second row inside the field's frame instead of overflowing it. At 125 % a 390 px phone
|
|
202
|
+
* is 312 px of Normal type, and "Month / Quarter / Half-year / Year" in one row of the
|
|
203
|
+
* field ran 7 px past it: a one-row flex group is as wide as all its labels end to end
|
|
204
|
+
* when a grid or a stretched column asks how small it can get, however its segments
|
|
205
|
+
* truncate. Wrapped, it is as wide as its longest label.
|
|
206
|
+
*
|
|
207
|
+
* Wrap, not a stacked select-like list: a wrapped radio group is the same radio group —
|
|
208
|
+
* one Tab stop, and the arrow keys walk the options in reading order whichever row
|
|
209
|
+
* they are on (←/↑ back, →/↓ on, Home/End) — so nothing about the keyboard changes with
|
|
210
|
+
* the text size. A list in its place would be a second widget with its own keys.
|
|
211
|
+
*
|
|
212
|
+
* Only where it has to: `flex-wrap` breaks a row only when the segments do not fit, so
|
|
213
|
+
* a wide field at Large stays one row, and a segment shares out what its row leaves
|
|
214
|
+
* (`flex-1`); a label wider than the whole row still truncates as the last resort.
|
|
215
|
+
* Three or fewer options keep one row: each holds a third of the field. A `large:`
|
|
216
|
+
* class, so it costs no render and is right on the first paint. `overflow="wrap"` wraps
|
|
217
|
+
* at every size already; outside the field the group keeps its `overflow`.
|
|
218
|
+
*/
|
|
219
|
+
const WRAP_AT_LARGE = "large:flex-wrap";
|
|
220
|
+
const WRAP_AT_LARGE_FROM = 4;
|
|
172
221
|
|
|
173
222
|
/**
|
|
174
223
|
* The strip placement's segments: a 26px group (1 + 2 + 20 + 2 + 1) under the 16px
|
|
@@ -185,7 +234,7 @@ const STRIP_SEGMENT: Record<"sm" | "md", string> = { md: "py-0", sm: "py-0.5" };
|
|
|
185
234
|
* region, because a description is read when the group is entered and not again when
|
|
186
235
|
* an arrow key changes the choice underneath it.
|
|
187
236
|
*
|
|
188
|
-
* In muted
|
|
237
|
+
* In muted caption-size text under the field (or the bare group), above an `error`.
|
|
189
238
|
*/
|
|
190
239
|
type ToggleGroupCaption<V> = ReactNode | ((value: V) => ReactNode);
|
|
191
240
|
|
|
@@ -272,6 +321,7 @@ export function ToggleGroup<T extends string>(props: ToggleGroupProps<T>): React
|
|
|
272
321
|
hint,
|
|
273
322
|
error,
|
|
274
323
|
disabledReason: ownDisabledReason,
|
|
324
|
+
disabledReasonDisplay,
|
|
275
325
|
commit,
|
|
276
326
|
"aria-label": ariaLabelAttr,
|
|
277
327
|
...restWithMode
|
|
@@ -279,9 +329,16 @@ export function ToggleGroup<T extends string>(props: ToggleGroupProps<T>): React
|
|
|
279
329
|
const labelId = useId();
|
|
280
330
|
const errorId = useId();
|
|
281
331
|
const reasonId = useId();
|
|
332
|
+
const hintCaptionId = useId();
|
|
282
333
|
// The lock's reason under a locked provider (with `commit`), else the group's own.
|
|
283
334
|
const disabledReason = useCommitReason(commit, ownDisabledReason);
|
|
284
335
|
const locked = hasContent(disabledReason);
|
|
336
|
+
// §4: at Large and on touch the reason is a line under the group, not a bubble.
|
|
337
|
+
const reasonLine = useDisabledReasonLine(disabledReasonDisplay) && locked;
|
|
338
|
+
// §4: likewise a FieldHint "?" on the label line becomes a caption under the group.
|
|
339
|
+
const inlineHint = useInlineHint(hint);
|
|
340
|
+
const hintAsCaption = inlineHint !== hint ? inlineHint : undefined;
|
|
341
|
+
const labelHint = hintAsCaption === undefined ? hint : undefined;
|
|
285
342
|
// Locked looks disabled — the dimmed group, the not-allowed cursor, no hover offer —
|
|
286
343
|
// but stays focusable; `disabled` alone also takes the segments out of the tab order.
|
|
287
344
|
const dimmed = disabled || locked;
|
|
@@ -289,6 +346,8 @@ export function ToggleGroup<T extends string>(props: ToggleGroupProps<T>): React
|
|
|
289
346
|
// `field` is the chrome; a label placed above or in a strip keeps the bare group's
|
|
290
347
|
// own box.
|
|
291
348
|
const field = labelled && labelPlacement === "field";
|
|
349
|
+
// At Large and Extra large a FIELD of four or more options wraps (see WRAP_AT_LARGE).
|
|
350
|
+
const wrapAtLarge = field && overflow === "truncate" && options.length >= WRAP_AT_LARGE_FROM;
|
|
292
351
|
const above = labelled && labelPlacement === "above";
|
|
293
352
|
const strip = labelled && labelPlacement === "strip";
|
|
294
353
|
const hasError = labelled && hasContent(error);
|
|
@@ -377,8 +436,11 @@ export function ToggleGroup<T extends string>(props: ToggleGroupProps<T>): React
|
|
|
377
436
|
// overlaying the selected segment's boundary. Inset keeps the ring
|
|
378
437
|
// inside the segment it belongs to; focus-visible keeps it for the
|
|
379
438
|
// keyboard, which is the only input that needs it.
|
|
439
|
+
//
|
|
440
|
+
// The ring is the kit's focus frame (0.32, §5): `--focus-ring-width` wide.
|
|
380
441
|
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-
|
|
442
|
+
"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)]",
|
|
443
|
+
FOCUS_RING_WIDTH,
|
|
382
444
|
size === "sm" && "px-2 py-1 text-xs",
|
|
383
445
|
// In the field chrome: no vertical padding, and the line that makes the
|
|
384
446
|
// field 42px under a strip that clears the label — see CHROME_PAD. `sm`
|
|
@@ -423,7 +485,9 @@ export function ToggleGroup<T extends string>(props: ToggleGroupProps<T>): React
|
|
|
423
485
|
aria-labelledby={labelled && ariaLabelAttr === undefined && ariaLabel === undefined ? labelId : rest["aria-labelledby"]}
|
|
424
486
|
aria-invalid={hasError || rest["aria-invalid"] || undefined}
|
|
425
487
|
aria-describedby={
|
|
426
|
-
[rest["aria-describedby"], hasCaption && captionId, hasError && errorId]
|
|
488
|
+
[rest["aria-describedby"], hintAsCaption !== undefined && hintCaptionId, hasCaption && captionId, hasError && errorId]
|
|
489
|
+
.filter(Boolean)
|
|
490
|
+
.join(" ") || undefined
|
|
427
491
|
}
|
|
428
492
|
// `aria-disabled` on the group as well as on (or `disabled` on) each button: a
|
|
429
493
|
// radio group is what the user is being refused, and a screen reader announcing
|
|
@@ -444,6 +508,7 @@ export function ToggleGroup<T extends string>(props: ToggleGroupProps<T>): React
|
|
|
444
508
|
// phone does see is the focus ring — see the segment's own note below.)
|
|
445
509
|
"inline-flex w-full gap-0.5 rounded-md border border-[var(--border-strong)] bg-[var(--bg-surface)] p-0.5 shadow-sm",
|
|
446
510
|
overflow === "wrap" && "flex-wrap",
|
|
511
|
+
wrapAtLarge && WRAP_AT_LARGE,
|
|
447
512
|
// The whole group fades, the way every other disabled control in this
|
|
448
513
|
// package does; `cursor-not-allowed` is on the buttons, which is what a
|
|
449
514
|
// pointer is actually over.
|
|
@@ -456,7 +521,7 @@ export function ToggleGroup<T extends string>(props: ToggleGroupProps<T>): React
|
|
|
456
521
|
!labelled && className,
|
|
457
522
|
)}
|
|
458
523
|
>
|
|
459
|
-
{locked ? (
|
|
524
|
+
{locked && !reasonLine ? (
|
|
460
525
|
// The reason's bubble wraps the SEGMENTS, inside the group, not the group: a
|
|
461
526
|
// wrapper outside it would become the flex or grid item in the caller's row in
|
|
462
527
|
// the group's place, and a `w-full` / `md:w-auto` on the group would size the
|
|
@@ -487,16 +552,34 @@ export function ToggleGroup<T extends string>(props: ToggleGroupProps<T>): React
|
|
|
487
552
|
<p
|
|
488
553
|
id={captionId}
|
|
489
554
|
aria-live={captionIsLive ? "polite" : undefined}
|
|
490
|
-
className={cn("text-
|
|
555
|
+
className={cn("text-caption leading-snug text-[var(--text-muted)]", hasCaption && "mt-1")}
|
|
491
556
|
>
|
|
492
557
|
{hasCaption ? captionNode : null}
|
|
493
558
|
</p>
|
|
494
559
|
) : null;
|
|
495
560
|
const errorEl = hasError ? (
|
|
496
|
-
<p id={errorId} className="mt-1 text-
|
|
561
|
+
<p id={errorId} className="mt-1 text-caption leading-tight text-[var(--danger)]">
|
|
497
562
|
{error}
|
|
498
563
|
</p>
|
|
499
564
|
) : null;
|
|
565
|
+
// §4: the FieldHint's words and the lock's reason, under the group, before the caption
|
|
566
|
+
// (standing advice first) and the error (the news). The reason line IS what each
|
|
567
|
+
// segment's `aria-describedby` names.
|
|
568
|
+
const belowEl =
|
|
569
|
+
hintAsCaption !== undefined || reasonLine ? (
|
|
570
|
+
<>
|
|
571
|
+
{hintAsCaption !== undefined && (
|
|
572
|
+
<p id={hintCaptionId} className={FIELD_CAPTION_CLASS}>
|
|
573
|
+
{hintAsCaption}
|
|
574
|
+
</p>
|
|
575
|
+
)}
|
|
576
|
+
{reasonLine && (
|
|
577
|
+
<p id={reasonId} className={DISABLED_REASON_LINE_CLASS}>
|
|
578
|
+
{disabledReason}
|
|
579
|
+
</p>
|
|
580
|
+
)}
|
|
581
|
+
</>
|
|
582
|
+
) : null;
|
|
500
583
|
if (above) {
|
|
501
584
|
// `relative` so a caller's `sr-only` label cannot escape (sr-only-containment).
|
|
502
585
|
return (
|
|
@@ -512,10 +595,11 @@ export function ToggleGroup<T extends string>(props: ToggleGroupProps<T>): React
|
|
|
512
595
|
>
|
|
513
596
|
{label}
|
|
514
597
|
</Label>
|
|
515
|
-
{
|
|
598
|
+
{labelHint}
|
|
516
599
|
</div>
|
|
517
600
|
<div className="min-w-0">
|
|
518
601
|
{group}
|
|
602
|
+
{belowEl}
|
|
519
603
|
{captionEl}
|
|
520
604
|
{errorEl}
|
|
521
605
|
</div>
|
|
@@ -524,19 +608,21 @@ export function ToggleGroup<T extends string>(props: ToggleGroupProps<T>): React
|
|
|
524
608
|
}
|
|
525
609
|
if (strip) {
|
|
526
610
|
return (
|
|
527
|
-
<LabelStrip labelId={labelId} label={label} hint={
|
|
611
|
+
<LabelStrip labelId={labelId} label={label} hint={labelHint} disabled={dimmed} pad="field" className={className}>
|
|
528
612
|
{group}
|
|
613
|
+
{belowEl}
|
|
529
614
|
{captionEl}
|
|
530
615
|
{errorEl}
|
|
531
616
|
</LabelStrip>
|
|
532
617
|
);
|
|
533
618
|
}
|
|
534
619
|
if (!field) {
|
|
535
|
-
if (!captionEl) return group;
|
|
620
|
+
if (!captionEl && !belowEl) return group;
|
|
536
621
|
// The group keeps its `className`, as without a caption; the wrapper only stacks.
|
|
537
622
|
return (
|
|
538
623
|
<div className="min-w-0">
|
|
539
624
|
{group}
|
|
625
|
+
{belowEl}
|
|
540
626
|
{captionEl}
|
|
541
627
|
</div>
|
|
542
628
|
);
|
|
@@ -549,7 +635,7 @@ export function ToggleGroup<T extends string>(props: ToggleGroupProps<T>): React
|
|
|
549
635
|
className="flex flex-1 flex-col"
|
|
550
636
|
label={<span id={labelId}>{label}</span>}
|
|
551
637
|
staticLabel
|
|
552
|
-
hint={
|
|
638
|
+
hint={labelHint}
|
|
553
639
|
>
|
|
554
640
|
<div
|
|
555
641
|
className={cn(
|
|
@@ -563,6 +649,7 @@ export function ToggleGroup<T extends string>(props: ToggleGroupProps<T>): React
|
|
|
563
649
|
{group}
|
|
564
650
|
</div>
|
|
565
651
|
</FloatingField>
|
|
652
|
+
{belowEl}
|
|
566
653
|
{captionEl}
|
|
567
654
|
{errorEl}
|
|
568
655
|
</div>
|
|
@@ -6,6 +6,7 @@
|
|
|
6
6
|
// useful under a chart the consumer drew by hand as under `SeriesChart`.
|
|
7
7
|
import type { ReactNode } from "react";
|
|
8
8
|
import { cn } from "../lib/cn";
|
|
9
|
+
import { FOCUS_RING } from "./focus-ring";
|
|
9
10
|
import { useKitLabels } from "../i18n/kit-labels";
|
|
10
11
|
import { DEFAULT_SERIES_CHART_LABELS, type SeriesChartLabels } from "./series-chart-labels";
|
|
11
12
|
|
|
@@ -60,6 +61,32 @@ export function toggleHidden(hidden: ReadonlySet<string>, key: string): Readonly
|
|
|
60
61
|
return next;
|
|
61
62
|
}
|
|
62
63
|
|
|
64
|
+
/**
|
|
65
|
+
* Where a legend that stands BESIDE a chart goes from Large up: UNDER it
|
|
66
|
+
* (docs/text-size-harmonization.md §4). Beside a chart, a legend column takes a third of
|
|
67
|
+
* a row whose plot needs all of it once the text is 25–50 % larger; under it, the row
|
|
68
|
+
* is the plot's and the legend wraps across the width.
|
|
69
|
+
*
|
|
70
|
+
* Pure CSS (`large:`), so a legend moves with the text size alone, whatever drew the
|
|
71
|
+
* row around it:
|
|
72
|
+
* - in a GRID it spans a row of its own (`col-span-full`) after the charts
|
|
73
|
+
* (`order-last`) — Kurvenschmiede's facing pairs;
|
|
74
|
+
* - in a FLEX row it takes a line of its own (`basis-full`), and its row is allowed to
|
|
75
|
+
* wrap for it (`[*:has(>&)]:flex-wrap` sets `flex-wrap` on the PARENT — the one rule
|
|
76
|
+
* here that reaches outside the legend, because a row that may not wrap would squeeze
|
|
77
|
+
* the chart to nothing beside a full-width legend) — Kurvenschmiede's chart rows.
|
|
78
|
+
*
|
|
79
|
+
* A caller that places its legend itself and wants it kept beside the chart at every
|
|
80
|
+
* size overrides with `large:col-auto large:basis-auto`.
|
|
81
|
+
*/
|
|
82
|
+
const UNDER_THE_CHART_AT_LARGE =
|
|
83
|
+
"large:order-last large:col-span-full large:basis-full large:[*:has(>&)]:flex-wrap";
|
|
84
|
+
|
|
85
|
+
/** A vertical legend's entries from Large up: across, wrapping — it is under the chart
|
|
86
|
+
* now (see {@link UNDER_THE_CHART_AT_LARGE}), where a column of entries would be a
|
|
87
|
+
* screenful of one-word lines. */
|
|
88
|
+
const VERTICAL_AT_LARGE = "large:flex-row large:flex-wrap large:items-center large:justify-start";
|
|
89
|
+
|
|
63
90
|
export interface LegendEntry {
|
|
64
91
|
key: string;
|
|
65
92
|
label: ReactNode;
|
|
@@ -109,7 +136,10 @@ export interface ToggleLegendProps {
|
|
|
109
136
|
onToggle: (key: string) => void;
|
|
110
137
|
/** `vertical` is for a legend standing BESIDE the charts rather than under them —
|
|
111
138
|
* what a row of charts sharing one legend wants, since under two charts there is
|
|
112
|
-
* no "under", and putting it under one says it belongs to that one.
|
|
139
|
+
* no "under", and putting it under one says it belongs to that one.
|
|
140
|
+
*
|
|
141
|
+
* From Large up a vertical legend moves under the charts and lays its entries
|
|
142
|
+
* across (0.32, docs/text-size-harmonization.md §4) — see {@link LegendColumn}. */
|
|
113
143
|
orientation?: "horizontal" | "vertical";
|
|
114
144
|
/**
|
|
115
145
|
* Draw a legend of ONE entry rather than nothing.
|
|
@@ -157,7 +187,7 @@ export function ToggleLegend({
|
|
|
157
187
|
className={cn(
|
|
158
188
|
"flex gap-x-3 gap-y-1",
|
|
159
189
|
orientation === "vertical"
|
|
160
|
-
? "flex-col items-start justify-center"
|
|
190
|
+
? cn("flex-col items-start justify-center", VERTICAL_AT_LARGE, UNDER_THE_CHART_AT_LARGE)
|
|
161
191
|
: "mt-2 flex-wrap items-center",
|
|
162
192
|
className,
|
|
163
193
|
)}
|
|
@@ -173,8 +203,8 @@ export function ToggleLegend({
|
|
|
173
203
|
aria-pressed={!off}
|
|
174
204
|
onClick={() => onToggle(entry.key)}
|
|
175
205
|
className={cn(
|
|
176
|
-
"flex items-center gap-1.5 rounded text-start text-
|
|
177
|
-
|
|
206
|
+
"flex items-center gap-1.5 rounded text-start text-caption text-[var(--text-secondary)] transition-opacity hover:opacity-80",
|
|
207
|
+
FOCUS_RING,
|
|
178
208
|
off && "opacity-35",
|
|
179
209
|
entry.align === "end" && "ms-auto",
|
|
180
210
|
)}
|
|
@@ -246,7 +276,7 @@ export function StaticLegend({
|
|
|
246
276
|
className={cn(
|
|
247
277
|
"m-0 flex list-none gap-x-3 gap-y-1 p-0",
|
|
248
278
|
orientation === "vertical"
|
|
249
|
-
? "flex-col items-start justify-center"
|
|
279
|
+
? cn("flex-col items-start justify-center", VERTICAL_AT_LARGE, UNDER_THE_CHART_AT_LARGE)
|
|
250
280
|
: "mt-2 flex-wrap items-center",
|
|
251
281
|
className,
|
|
252
282
|
)}
|
|
@@ -255,7 +285,7 @@ export function StaticLegend({
|
|
|
255
285
|
<Item
|
|
256
286
|
key={entry.key}
|
|
257
287
|
className={cn(
|
|
258
|
-
"flex items-center gap-1.5 text-
|
|
288
|
+
"flex items-center gap-1.5 text-caption text-[var(--text-secondary)]",
|
|
259
289
|
entry.align === "end" && "ms-auto",
|
|
260
290
|
)}
|
|
261
291
|
>
|
|
@@ -273,10 +303,25 @@ export function StaticLegend({
|
|
|
273
303
|
* that stretches it — and stacks whatever it is given, which is what a panel showing
|
|
274
304
|
* two legends at once needs. The width is the caller's: how wide a legend column is
|
|
275
305
|
* is a fact about that screen's layout.
|
|
306
|
+
*
|
|
307
|
+
* **From Large up it goes UNDER the charts** (0.32, docs/text-size-harmonization.md
|
|
308
|
+
* §4): a row of its own in a grid, a line of its own in a flex row (see
|
|
309
|
+
* `UNDER_THE_CHART_AT_LARGE`), with what it holds laid across and wrapping. A
|
|
310
|
+
* caller's own `max-sm:flex-row …` for the phone keeps working; the caller's width
|
|
311
|
+
* (`sm:w-40`) gives way to the full row, because a size wins over a breakpoint.
|
|
276
312
|
*/
|
|
277
313
|
export function LegendColumn({ children, className }: { children: ReactNode; className?: string }) {
|
|
278
314
|
return (
|
|
279
|
-
<div
|
|
315
|
+
<div
|
|
316
|
+
className={cn(
|
|
317
|
+
"flex h-full flex-col justify-center gap-3",
|
|
318
|
+
UNDER_THE_CHART_AT_LARGE,
|
|
319
|
+
"large:h-auto large:flex-row large:flex-wrap large:items-start large:justify-start large:gap-x-6",
|
|
320
|
+
className,
|
|
321
|
+
)}
|
|
322
|
+
>
|
|
323
|
+
{children}
|
|
324
|
+
</div>
|
|
280
325
|
);
|
|
281
326
|
}
|
|
282
327
|
|
|
@@ -290,7 +335,7 @@ export function LegendColumn({ children, className }: { children: ReactNode; cla
|
|
|
290
335
|
export function LegendGroup({ title, children }: { title: ReactNode; children: ReactNode }) {
|
|
291
336
|
return (
|
|
292
337
|
<div className="flex min-w-0 flex-col items-start gap-1">
|
|
293
|
-
<span className="text-
|
|
338
|
+
<span className="text-micro font-semibold uppercase tracking-wide text-[var(--text-muted)]">
|
|
294
339
|
{title}
|
|
295
340
|
</span>
|
|
296
341
|
<div className="flex flex-col items-start gap-y-0.5">{children}</div>
|
|
@@ -2,7 +2,7 @@ import { useEffect, useId, useMemo, useRef, useState } from "react";
|
|
|
2
2
|
import type { ReactNode } from "react";
|
|
3
3
|
import { Check, ListChecks, PencilLine, RotateCcw } from "lucide-react";
|
|
4
4
|
|
|
5
|
-
import {
|
|
5
|
+
import { useBreakpoint } from "../hooks/use-breakpoint";
|
|
6
6
|
import { useKitLabels, useKitLocale } from "../i18n/kit-labels";
|
|
7
7
|
import { cn } from "../lib/cn";
|
|
8
8
|
import {
|
|
@@ -293,9 +293,6 @@ export interface TranslationReviewPanelProps {
|
|
|
293
293
|
labels?: Partial<TranslationReviewLabels>;
|
|
294
294
|
}
|
|
295
295
|
|
|
296
|
-
/** The wide screen's query — the same one DataTable switches its layout on, so "a phone"
|
|
297
|
-
* means the same here as in the table. */
|
|
298
|
-
const MD_UP = "(min-width: 768px)";
|
|
299
296
|
|
|
300
297
|
/**
|
|
301
298
|
* How many rows the groups may render at once on a wide screen before they start folded
|
|
@@ -461,7 +458,9 @@ export function TranslationReviewPanel({
|
|
|
461
458
|
const labels = useKitLabels("translationReview", DEFAULT_TRANSLATION_REVIEW_LABELS, labelsProp);
|
|
462
459
|
const locale = useKitLocale();
|
|
463
460
|
const lock = useWriteLock();
|
|
464
|
-
|
|
461
|
+
// The wide screen's breakpoint — the one DataTable switches its layout on, so "a phone"
|
|
462
|
+
// means the same here as in the table, at every text size.
|
|
463
|
+
const phone = !useBreakpoint("md", true);
|
|
465
464
|
const baseId = useId();
|
|
466
465
|
const rootRef = useRef<HTMLDivElement>(null);
|
|
467
466
|
const editable = !readOnly && onSave !== undefined;
|
|
@@ -744,6 +743,12 @@ export function TranslationReviewPanel({
|
|
|
744
743
|
tone="muted"
|
|
745
744
|
commit
|
|
746
745
|
label={labels.approve}
|
|
746
|
+
// The icon alone at every text size (docs/text-size-harmonization.md §10.8):
|
|
747
|
+
// the row's one action, in a hugging column of a dense table beside the
|
|
748
|
+
// string under review, which "Approve" as text at Large would squeeze. A
|
|
749
|
+
// single action stays inline in `RowActions` too, so the menu would not help;
|
|
750
|
+
// the swipe and the editor say it in words.
|
|
751
|
+
labelVisible={false}
|
|
747
752
|
pending={isQueued(`row:${r.id}`)}
|
|
748
753
|
disabled={busy}
|
|
749
754
|
onClick={(event) => {
|
|
@@ -4,6 +4,7 @@ import { ChevronRight } from "lucide-react";
|
|
|
4
4
|
import { cn } from "../lib/cn";
|
|
5
5
|
import { horizontalStep } from "../lib/direction";
|
|
6
6
|
import { Spinner } from "./ui";
|
|
7
|
+
import { FOCUS_RING } from "./focus-ring";
|
|
7
8
|
|
|
8
9
|
/**
|
|
9
10
|
* A hierarchy you walk with the keyboard: kastlan's chart of accounts (Assets › Current
|
|
@@ -182,7 +183,7 @@ export function TreeRow({
|
|
|
182
183
|
e.stopPropagation();
|
|
183
184
|
onToggle();
|
|
184
185
|
}}
|
|
185
|
-
className="flex size-4 shrink-0 items-center justify-center rounded text-[var(--text-muted)] outline-none hover:text-[var(--text-primary)]
|
|
186
|
+
className={cn("flex size-4 shrink-0 items-center justify-center rounded text-[var(--text-muted)] outline-none hover:text-[var(--text-primary)]", FOCUS_RING)}
|
|
186
187
|
>
|
|
187
188
|
{chevron}
|
|
188
189
|
</button>
|
|
@@ -543,7 +544,7 @@ export function TreeView<T = unknown>({
|
|
|
543
544
|
}}
|
|
544
545
|
// The ring goes on this row's own box, not the <li>: the <li> contains the
|
|
545
546
|
// whole open branch below it, and ringing that would outline a subtree.
|
|
546
|
-
className="outline-none [&:focus-visible>[data-tree-row]]:ring-
|
|
547
|
+
className="outline-none [&:focus-visible>[data-tree-row]]:ring-[length:var(--focus-ring-width)] [&:focus-visible>[data-tree-row]]:ring-[var(--brand)]"
|
|
547
548
|
>
|
|
548
549
|
<TreeRow
|
|
549
550
|
id={rowId}
|
|
@@ -15,6 +15,9 @@ import { ChartContainer, ChartTooltip, ChartTooltipContent, type ChartConfig } f
|
|
|
15
15
|
import { PALETTE_HEX, textOn } from "../theme/chart-palette";
|
|
16
16
|
import { parseHex } from "../theme/color";
|
|
17
17
|
import { dirOf, type Direction } from "../lib/direction";
|
|
18
|
+
import { cn } from "../lib/cn";
|
|
19
|
+
import { useTextSize } from "../theme/text-size";
|
|
20
|
+
import { chartHeightProps, type ChartHeight } from "./chart-height";
|
|
18
21
|
|
|
19
22
|
/**
|
|
20
23
|
* One tile.
|
|
@@ -63,8 +66,10 @@ export interface TreemapProps extends Omit<ComponentPropsWithoutRef<"div">, "chi
|
|
|
63
66
|
* host that has a currency or a locale passes this — the kit knows neither.
|
|
64
67
|
*/
|
|
65
68
|
valueFormatter?: (value: number, share: number | undefined) => ReactNode;
|
|
66
|
-
/** Chart height
|
|
67
|
-
|
|
69
|
+
/** Chart height: a CSS length (`"20rem"`, `"min(20rem, 50dvh)"`), a Tailwind class,
|
|
70
|
+
* or px. Default `"20rem"` — 320 px at Normal, growing with the text size like the
|
|
71
|
+
* labels in the tiles (0.32, docs/text-size-harmonization.md §10.10). */
|
|
72
|
+
height?: ChartHeight;
|
|
68
73
|
/** A tile was activated — by click, or by Enter/Space on a focused tile. Setting
|
|
69
74
|
* this makes every tile a focusable `role="button"` named by its node name. */
|
|
70
75
|
onNodeClick?: (id: string, name: string) => void;
|
|
@@ -165,6 +170,8 @@ function measurableFill(fill: string, tokens: readonly string[]): string | null
|
|
|
165
170
|
|
|
166
171
|
// ── Tile ──────────────────────────────────────────────────────────────────
|
|
167
172
|
|
|
173
|
+
/** The name's size in px at Normal; a tile draws it × the text size's scale (§10.10), and
|
|
174
|
+
* every distance below that is measured in lines grows with it. */
|
|
168
175
|
const LABEL_FONT_SIZE = 12;
|
|
169
176
|
/** The optional second line, a step down from the name so the tile reads name-first. */
|
|
170
177
|
const NOTE_FONT_SIZE = 11;
|
|
@@ -233,6 +240,7 @@ export function TreemapCell({
|
|
|
233
240
|
}: TreemapCellProps) {
|
|
234
241
|
// Before the early return: a hook has to run on every render of the cell.
|
|
235
242
|
const tokenHex = useChartTokenHex();
|
|
243
|
+
const { scale } = useTextSize();
|
|
236
244
|
// Depth 0 is recharts' synthetic root, which spans the whole chart.
|
|
237
245
|
if (!depth) return null;
|
|
238
246
|
// Whole pixels: a rect on a half pixel renders its edge across two half-lit
|
|
@@ -251,14 +259,16 @@ export function TreemapCell({
|
|
|
251
259
|
const halo = measured ? tileFill : "none";
|
|
252
260
|
// Below ~44x20 there is no room for a readable word, so no label at all rather than
|
|
253
261
|
// a one-letter stub bleeding over the tile edge.
|
|
254
|
-
const
|
|
262
|
+
const labelSize = LABEL_FONT_SIZE * scale;
|
|
263
|
+
const noteSize = NOTE_FONT_SIZE * scale;
|
|
264
|
+
const label = pw >= 44 * scale && ph >= 20 * scale ? fitLabel(name ?? "", pw, labelSize) : null;
|
|
255
265
|
// Only under a label that is itself drawn — a stray "+12%" on an unnamed rectangle
|
|
256
266
|
// names nothing — and only where a second baseline fits: the note's baseline sits
|
|
257
267
|
// 29px down and an 11px glyph hangs ~2px below it, so 36 leaves the same ~5px under
|
|
258
268
|
// the note that the label keeps under itself at the 20px floor.
|
|
259
269
|
const rawNote = id != null && nodeNote ? nodeNote(id) : undefined;
|
|
260
270
|
const note =
|
|
261
|
-
label != null && rawNote != null && ph >= 36 ? fitLabel(rawNote, pw,
|
|
271
|
+
label != null && rawNote != null && ph >= 36 * scale ? fitLabel(rawNote, pw, noteSize) : null;
|
|
262
272
|
// The label's START edge, 6px in from the tile's. The tiles themselves are laid out
|
|
263
273
|
// physically (the plot is not mirrored, see `ChartContainer`) and the chart's SVG is
|
|
264
274
|
// pinned `ltr`, so the direction is set on each <text> explicitly: `start` is then
|
|
@@ -306,14 +316,14 @@ export function TreemapCell({
|
|
|
306
316
|
// <text> exactly as it reaches a table cell.
|
|
307
317
|
data-private={redactNames ? "" : undefined}
|
|
308
318
|
x={textX}
|
|
309
|
-
y={py + 15}
|
|
319
|
+
y={py + 15 * scale}
|
|
310
320
|
direction={dir}
|
|
311
321
|
fill={ink}
|
|
312
322
|
stroke={halo}
|
|
313
323
|
strokeWidth={2.5}
|
|
314
324
|
strokeLinejoin="round"
|
|
315
325
|
paintOrder="stroke"
|
|
316
|
-
fontSize={
|
|
326
|
+
fontSize={labelSize}
|
|
317
327
|
fontWeight={600}
|
|
318
328
|
style={{ pointerEvents: "none" }}
|
|
319
329
|
>
|
|
@@ -323,7 +333,7 @@ export function TreemapCell({
|
|
|
323
333
|
{note != null && (
|
|
324
334
|
<text
|
|
325
335
|
x={textX}
|
|
326
|
-
y={py + 29}
|
|
336
|
+
y={py + 29 * scale}
|
|
327
337
|
direction={dir}
|
|
328
338
|
fill={ink}
|
|
329
339
|
fillOpacity={0.85}
|
|
@@ -331,7 +341,7 @@ export function TreemapCell({
|
|
|
331
341
|
strokeWidth={2.5}
|
|
332
342
|
strokeLinejoin="round"
|
|
333
343
|
paintOrder="stroke"
|
|
334
|
-
fontSize={
|
|
344
|
+
fontSize={noteSize}
|
|
335
345
|
fontWeight={500}
|
|
336
346
|
style={{ pointerEvents: "none" }}
|
|
337
347
|
>
|
|
@@ -386,7 +396,7 @@ const DEFAULT_NUMBER = new Intl.NumberFormat();
|
|
|
386
396
|
export function Treemap({
|
|
387
397
|
data,
|
|
388
398
|
valueFormatter,
|
|
389
|
-
height =
|
|
399
|
+
height = "20rem",
|
|
390
400
|
onNodeClick,
|
|
391
401
|
redactNames = false,
|
|
392
402
|
nodeNote,
|
|
@@ -421,6 +431,7 @@ export function Treemap({
|
|
|
421
431
|
.filter((n) => Number.isFinite(n.size) && n.size > 0)
|
|
422
432
|
.slice(0, maxTiles ?? undefined);
|
|
423
433
|
if (nodes.length === 0) return null;
|
|
434
|
+
const box = chartHeightProps(height);
|
|
424
435
|
|
|
425
436
|
// The share is of what is DRAWN, so it always reads as "of this picture".
|
|
426
437
|
const total = nodes.reduce((acc, n) => acc + n.size, 0);
|
|
@@ -430,7 +441,13 @@ export function Treemap({
|
|
|
430
441
|
};
|
|
431
442
|
const Content = redactNames ? RedactedTooltipContent : ChartTooltipContent;
|
|
432
443
|
return (
|
|
433
|
-
<ChartContainer
|
|
444
|
+
<ChartContainer
|
|
445
|
+
{...rest}
|
|
446
|
+
ref={rootRef}
|
|
447
|
+
config={TREEMAP_CONFIG}
|
|
448
|
+
className={cn(box.className, rest.className)}
|
|
449
|
+
style={{ ...style, ...box.style }}
|
|
450
|
+
>
|
|
434
451
|
{/* No chart-level `stroke`: recharts spreads it onto the <svg> root, from where
|
|
435
452
|
it inherits into every label (see TreemapCell). Each cell strokes its own rect. */}
|
|
436
453
|
<RechartsTreemap
|