@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
|
@@ -3,6 +3,7 @@ import { Chip } from "./chip";
|
|
|
3
3
|
import { Tooltip } from "./tooltip";
|
|
4
4
|
import { cn } from "../lib/cn";
|
|
5
5
|
import { useKitLabels } from "../i18n/kit-labels";
|
|
6
|
+
import { useLargeText } from "../hooks/use-large-text";
|
|
6
7
|
|
|
7
8
|
// ── Labels ────────────────────────────────────────────────────────────────────
|
|
8
9
|
|
|
@@ -17,12 +18,17 @@ export interface SignChipLabels {
|
|
|
17
18
|
* turns it into — `current` and `next` are the two words above. The other option is
|
|
18
19
|
* nowhere on screen to be read, so the name has to say both. */
|
|
19
20
|
direction: (current: string, next: string) => string;
|
|
21
|
+
/** 0.32: what a press does, in words under the chip at Large and Extra large —
|
|
22
|
+
* `next` is the other direction's word ("Switch to Inflow"). The tooltip's half of
|
|
23
|
+
* `direction`, shown, since a fact may not live only in a tooltip there (§4). */
|
|
24
|
+
switchTo: (next: string) => string;
|
|
20
25
|
}
|
|
21
26
|
|
|
22
27
|
export const DEFAULT_SIGN_CHIP_LABELS: SignChipLabels = {
|
|
23
28
|
outflow: "Outflow",
|
|
24
29
|
inflow: "Inflow",
|
|
25
30
|
direction: (current, next) => `Direction: ${current} — switch to ${next}`,
|
|
31
|
+
switchTo: (next) => `Switch to ${next}`,
|
|
26
32
|
};
|
|
27
33
|
|
|
28
34
|
export interface SignChipProps {
|
|
@@ -79,8 +85,10 @@ export function SignChip({ negative, onNegativeChange, disabled, labels: labelsP
|
|
|
79
85
|
const current = negative ? labels.outflow : labels.inflow;
|
|
80
86
|
const next = negative ? labels.inflow : labels.outflow;
|
|
81
87
|
const name = labels.direction(current, next);
|
|
82
|
-
|
|
83
|
-
|
|
88
|
+
// §4: at Large the chip's word is joined by what a press does, as a line under it —
|
|
89
|
+
// and the bubble that said only that goes.
|
|
90
|
+
const large = useLargeText();
|
|
91
|
+
const chip = (
|
|
84
92
|
<Chip
|
|
85
93
|
size="lg"
|
|
86
94
|
tone={negative ? "expense" : "income"}
|
|
@@ -91,13 +99,29 @@ export function SignChip({ negative, onNegativeChange, disabled, labels: labelsP
|
|
|
91
99
|
// `gap-1.5 px-3`: the chip's narrower body, because on a 375px screen every
|
|
92
100
|
// pixel of it is taken from the figure beside it (#430). `md:py-2.5` with the
|
|
93
101
|
// hairline border is the 42px a labelled field measures (#431).
|
|
94
|
-
className={cn("shrink-0 gap-1.5 whitespace-nowrap px-3 font-medium md:min-h-0 md:py-2.5", className)}
|
|
102
|
+
className={cn("shrink-0 gap-1.5 whitespace-nowrap px-3 font-medium md:min-h-0 md:py-2.5", !large && className)}
|
|
95
103
|
>
|
|
96
104
|
{current}
|
|
97
105
|
{/* The swap arrows after the word, in the label's own row: decoration (the
|
|
98
106
|
name already says what a press does), set a little apart from the word. */}
|
|
99
107
|
<ArrowUpDown className="ms-1.5 inline size-3.5 align-[-0.2em] opacity-60" aria-hidden />
|
|
100
108
|
</Chip>
|
|
101
|
-
|
|
109
|
+
);
|
|
110
|
+
if (!large) {
|
|
111
|
+
return (
|
|
112
|
+
<Tooltip label={name} lazy>
|
|
113
|
+
{chip}
|
|
114
|
+
</Tooltip>
|
|
115
|
+
);
|
|
116
|
+
}
|
|
117
|
+
return (
|
|
118
|
+
// The caller's placement (`self-end`…) moves to the pair, which is now the row's item.
|
|
119
|
+
<span data-slot="sign-chip" className={cn("inline-flex shrink-0 flex-col items-start gap-0.5", className)}>
|
|
120
|
+
{chip}
|
|
121
|
+
{/* Hidden from the accessibility tree: the chip's name already says it. */}
|
|
122
|
+
<span aria-hidden className="text-xs text-[var(--text-muted)]">
|
|
123
|
+
{labels.switchTo(next)}
|
|
124
|
+
</span>
|
|
125
|
+
</span>
|
|
102
126
|
);
|
|
103
127
|
}
|
|
@@ -4,6 +4,7 @@ import { Eraser, Keyboard, PenLine, Undo2 } from "lucide-react";
|
|
|
4
4
|
import { cn } from "../lib/cn";
|
|
5
5
|
import { useAnnounce } from "../hooks/use-announce";
|
|
6
6
|
import { useKitLabels } from "../i18n/kit-labels";
|
|
7
|
+
import { useTextSize } from "../theme/text-size";
|
|
7
8
|
import { Button, FIELD_INVALID, Input } from "./ui";
|
|
8
9
|
|
|
9
10
|
/**
|
|
@@ -144,7 +145,9 @@ export interface SignaturePadProps extends Omit<ComponentPropsWithoutRef<"div">,
|
|
|
144
145
|
exportInk?: string;
|
|
145
146
|
/** Fill behind the exported PNG. Default transparent. */
|
|
146
147
|
exportBackground?: string;
|
|
147
|
-
/** Base stroke width in CSS pixels. Default 2.5.
|
|
148
|
+
/** Base stroke width in CSS pixels at Normal text size. Default 2.5. It grows with the
|
|
149
|
+
* text size (× 1.25 / × 1.5, docs/text-size-harmonization.md §10.11), as the pad's
|
|
150
|
+
* rem height does, so a signature keeps its weight on a larger pad. */
|
|
148
151
|
lineWidth?: number;
|
|
149
152
|
/** Classes for the canvas — its height, chiefly (default `h-40`). */
|
|
150
153
|
canvasClassName?: string;
|
|
@@ -291,10 +294,13 @@ export const SignaturePad = forwardRef<SignaturePadHandle, SignaturePadProps>(fu
|
|
|
291
294
|
|
|
292
295
|
// Everything the paint and export paths read that can change between renders, so
|
|
293
296
|
// the observers below subscribe once instead of on every keystroke.
|
|
294
|
-
|
|
297
|
+
// The stroke follows the text size like everything in rem around it (§10.11).
|
|
298
|
+
const { scale: textScale } = useTextSize();
|
|
299
|
+
const strokeWidth = lineWidth * textScale;
|
|
300
|
+
const opts = useRef({ lineWidth: strokeWidth, exportInk, exportBackground });
|
|
295
301
|
useEffect(() => {
|
|
296
|
-
opts.current = { lineWidth, exportInk, exportBackground };
|
|
297
|
-
}, [
|
|
302
|
+
opts.current = { lineWidth: strokeWidth, exportInk, exportBackground };
|
|
303
|
+
}, [strokeWidth, exportInk, exportBackground]);
|
|
298
304
|
|
|
299
305
|
const sceneEmpty = () => {
|
|
300
306
|
const s = scene.current;
|
|
@@ -356,10 +362,10 @@ export const SignaturePad = forwardRef<SignaturePadHandle, SignaturePadProps>(fu
|
|
|
356
362
|
resize();
|
|
357
363
|
}, [resize]);
|
|
358
364
|
|
|
359
|
-
// A changed base width redraws what is already there.
|
|
365
|
+
// A changed base width — or text size — redraws what is already there.
|
|
360
366
|
useEffect(() => {
|
|
361
367
|
repaint();
|
|
362
|
-
}, [
|
|
368
|
+
}, [strokeWidth, repaint]);
|
|
363
369
|
|
|
364
370
|
useEffect(() => {
|
|
365
371
|
const canvas = canvasRef.current;
|
|
@@ -627,7 +633,7 @@ export const SignaturePad = forwardRef<SignaturePadHandle, SignaturePadProps>(fu
|
|
|
627
633
|
</div>
|
|
628
634
|
|
|
629
635
|
{hasError && (
|
|
630
|
-
<p id={errorId} className="mt-1 text-
|
|
636
|
+
<p id={errorId} className="mt-1 text-caption leading-tight text-[var(--danger)]">
|
|
631
637
|
{error}
|
|
632
638
|
</p>
|
|
633
639
|
)}
|
|
@@ -70,32 +70,45 @@ export function fromLogPosition(position: number, min: number, max: number, zero
|
|
|
70
70
|
// runs the other way too. Firefox draws the fill itself with `::-moz-range-progress`,
|
|
71
71
|
// which follows the direction on its own.
|
|
72
72
|
//
|
|
73
|
-
// The thumb's `-mt-[
|
|
74
|
-
//
|
|
73
|
+
// The thumb's `-mt-[0.3125rem]` centres a 1rem thumb on a 0.375rem track — half the
|
|
74
|
+
// difference — in rem since 0.32 (§3.2): the thumb and track grow with the text, and the
|
|
75
|
+
// 5px it was left the thumb low of the track at 125 % and further at 150 %. WebKit lays
|
|
76
|
+
// the thumb out from the track's top edge, Firefox centres it, so only one carries the
|
|
77
|
+
// offset.
|
|
75
78
|
//
|
|
76
79
|
// The focus ring goes on the THUMB, not the box: the box is the full width of the
|
|
77
80
|
// row, and a ring round all of it says "this row is focused" rather than "the handle
|
|
78
81
|
// you are about to move is". Offset in the surface colour, because the thumb is
|
|
79
|
-
// --brand and a --brand ring touching it would be invisible.
|
|
82
|
+
// --brand and a --brand ring touching it would be invisible. Its width is the kit's
|
|
83
|
+
// focus frame (`--focus-ring-width`, §5) — spelt out per engine, since `FOCUS_RING`'s
|
|
84
|
+
// classes cannot carry the pseudo-element.
|
|
85
|
+
//
|
|
86
|
+
// At Large the box is the 48 px touch target (§4) — the track stays centred in it, and
|
|
87
|
+
// the marks row below is pulled up by as much (see `MARKS_LARGE`).
|
|
80
88
|
const TRACK = [
|
|
81
|
-
"block h-6 w-full cursor-pointer appearance-none bg-transparent focus:outline-none disabled:cursor-not-allowed",
|
|
89
|
+
"block h-6 large:h-[48px] w-full cursor-pointer appearance-none bg-transparent focus:outline-none disabled:cursor-not-allowed",
|
|
82
90
|
// WebKit / Blink
|
|
83
91
|
"[&::-webkit-slider-runnable-track]:h-1.5 [&::-webkit-slider-runnable-track]:rounded-full",
|
|
84
92
|
"[&::-webkit-slider-runnable-track]:bg-[linear-gradient(to_right,var(--brand)_var(--slider-fill),var(--border-strong)_var(--slider-fill))]",
|
|
85
93
|
"rtl:[&::-webkit-slider-runnable-track]:bg-[linear-gradient(to_left,var(--brand)_var(--slider-fill),var(--border-strong)_var(--slider-fill))]",
|
|
86
|
-
"[&::-webkit-slider-thumb]:-mt-[
|
|
94
|
+
"[&::-webkit-slider-thumb]:-mt-[0.3125rem] [&::-webkit-slider-thumb]:size-4 [&::-webkit-slider-thumb]:appearance-none",
|
|
87
95
|
"[&::-webkit-slider-thumb]:rounded-full [&::-webkit-slider-thumb]:bg-[var(--brand)] [&::-webkit-slider-thumb]:shadow",
|
|
88
|
-
"focus-visible:[&::-webkit-slider-thumb]:ring-
|
|
96
|
+
"focus-visible:[&::-webkit-slider-thumb]:ring-[length:var(--focus-ring-width)] focus-visible:[&::-webkit-slider-thumb]:ring-[var(--brand)]",
|
|
89
97
|
"focus-visible:[&::-webkit-slider-thumb]:ring-offset-2 focus-visible:[&::-webkit-slider-thumb]:ring-offset-[var(--bg-surface)]",
|
|
90
98
|
// Firefox
|
|
91
99
|
"[&::-moz-range-track]:h-1.5 [&::-moz-range-track]:rounded-full [&::-moz-range-track]:bg-[var(--border-strong)]",
|
|
92
100
|
"[&::-moz-range-progress]:h-1.5 [&::-moz-range-progress]:rounded-full [&::-moz-range-progress]:bg-[var(--brand)]",
|
|
93
101
|
"[&::-moz-range-thumb]:size-4 [&::-moz-range-thumb]:rounded-full [&::-moz-range-thumb]:border-0",
|
|
94
102
|
"[&::-moz-range-thumb]:bg-[var(--brand)] [&::-moz-range-thumb]:shadow",
|
|
95
|
-
"focus-visible:[&::-moz-range-thumb]:ring-
|
|
103
|
+
"focus-visible:[&::-moz-range-thumb]:ring-[length:var(--focus-ring-width)] focus-visible:[&::-moz-range-thumb]:ring-[var(--brand)]",
|
|
96
104
|
"focus-visible:[&::-moz-range-thumb]:ring-offset-2 focus-visible:[&::-moz-range-thumb]:ring-offset-[var(--bg-surface)]",
|
|
97
105
|
].join(" ");
|
|
98
106
|
|
|
107
|
+
// The marks row sits `-mt-1.5` under a 1.5rem box, tucked against the track. In the 48 px
|
|
108
|
+
// box at Large the track's lower edge is `(48px + 0.375rem) / 2` down, so the row comes
|
|
109
|
+
// up by `(48px − 0.375rem) / 2` less the same 0.1875rem gap: `24px − 0.375rem`.
|
|
110
|
+
const MARKS_LARGE = "large:-mt-[calc(24px-0.375rem)]";
|
|
111
|
+
|
|
99
112
|
/** A tick under the track. A bare number is a tick with no words. */
|
|
100
113
|
export interface SliderMark {
|
|
101
114
|
value: number;
|
|
@@ -293,7 +306,7 @@ export const Slider = forwardRef<HTMLInputElement, SliderProps>(function Slider(
|
|
|
293
306
|
// without a `translate` that would need flipping for right-to-left.
|
|
294
307
|
<div
|
|
295
308
|
aria-hidden
|
|
296
|
-
className={cn("relative mx-2 -mt-1.5", hasMarkLabels ? "h-5" : "h-1.5")}
|
|
309
|
+
className={cn("relative mx-2 -mt-1.5", MARKS_LARGE, hasMarkLabels ? "h-5" : "h-1.5")}
|
|
297
310
|
>
|
|
298
311
|
{normalizedMarks.map((m) => (
|
|
299
312
|
<span
|
|
@@ -303,7 +316,7 @@ export const Slider = forwardRef<HTMLInputElement, SliderProps>(function Slider(
|
|
|
303
316
|
>
|
|
304
317
|
<span className="h-1.5 w-px shrink-0 bg-[var(--border-strong)]" />
|
|
305
318
|
{m.label !== undefined && (
|
|
306
|
-
<span className="mt-0.5 select-none whitespace-nowrap text-
|
|
319
|
+
<span className="mt-0.5 select-none whitespace-nowrap text-caption leading-tight text-[var(--text-muted)]">
|
|
307
320
|
{m.label}
|
|
308
321
|
</span>
|
|
309
322
|
)}
|
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
import type { ComponentPropsWithoutRef } from "react";
|
|
2
2
|
import { cn } from "../lib/cn";
|
|
3
3
|
import { useKitLabels, useKitLocale } from "../i18n/kit-labels";
|
|
4
|
+
import { useTextSize } from "../theme/text-size";
|
|
4
5
|
|
|
5
6
|
/**
|
|
6
7
|
* The words a sparkline speaks. It has no axes, no tooltip and no legend, so its
|
|
@@ -78,8 +79,12 @@ export interface SparklineProps
|
|
|
78
79
|
/** The series, oldest first. `null`/`undefined`/`NaN` is a GAP — the line breaks
|
|
79
80
|
* there rather than drawing a zero or bridging across the missing point. */
|
|
80
81
|
data: ReadonlyArray<number | null | undefined>;
|
|
81
|
-
/** Width in px. Ignored under `fluid`.
|
|
82
|
+
/** Width in px at Normal. Ignored under `fluid`. The drawn box is this × the text
|
|
83
|
+
* size's scale (0.32, docs/text-size-harmonization.md §3.2): a sparkline stands beside
|
|
84
|
+
* a figure, and a 72 × 24 trend under a 150 % number reads as a speck. The strokes
|
|
85
|
+
* stay px (`non-scaling-stroke`), as every chart's do. */
|
|
82
86
|
width?: number;
|
|
87
|
+
/** Height in px at Normal, × the scale likewise. */
|
|
83
88
|
height?: number;
|
|
84
89
|
/** Fill the container's width instead of a fixed one (the height stays fixed). */
|
|
85
90
|
fluid?: boolean;
|
|
@@ -182,6 +187,7 @@ export function Sparkline({
|
|
|
182
187
|
...rest
|
|
183
188
|
}: SparklineProps) {
|
|
184
189
|
const text = useKitLabels("sparkline", DEFAULT_SPARKLINE_LABELS, labels);
|
|
190
|
+
const { scale } = useTextSize();
|
|
185
191
|
const kitLocale = useKitLocale(locale);
|
|
186
192
|
const format = formatValue ?? defaultFormat(kitLocale);
|
|
187
193
|
|
|
@@ -252,8 +258,10 @@ export function Sparkline({
|
|
|
252
258
|
role="img"
|
|
253
259
|
aria-label={name}
|
|
254
260
|
{...rest}
|
|
255
|
-
|
|
256
|
-
|
|
261
|
+
// The drawing stays in its own units (the viewBox); only the box it is shown in
|
|
262
|
+
// grows, uniformly, so nothing is distorted and the strokes keep their px width.
|
|
263
|
+
width={fluid ? "100%" : W * scale}
|
|
264
|
+
height={H * scale}
|
|
257
265
|
viewBox={`0 0 ${W} ${H}`}
|
|
258
266
|
preserveAspectRatio="none"
|
|
259
267
|
className={cn(fluid ? "block w-full" : "inline-block shrink-0 align-middle", "overflow-visible", className)}
|
|
@@ -5,6 +5,7 @@ import { cn } from "../lib/cn";
|
|
|
5
5
|
import { useKitLabels, useKitLink, useKitLocale } from "../i18n/kit-labels";
|
|
6
6
|
import { pickLinkRenderer, RenderedKitLink } from "./text-link";
|
|
7
7
|
import { Card, FieldHint } from "./ui";
|
|
8
|
+
import { useInlineFacts, useLargeText } from "../hooks/use-large-text";
|
|
8
9
|
import { Sparkline } from "./sparkline";
|
|
9
10
|
import { Tooltip } from "./tooltip";
|
|
10
11
|
// The kit's one placeholder look, so a loading tile and the Skeleton list beside it
|
|
@@ -151,7 +152,11 @@ export interface StatTileProps
|
|
|
151
152
|
/** The explanation behind a "?" beside the label (a {@link FieldHint}) — hidden
|
|
152
153
|
* until asked for, so it is for what a reader MIGHT want to know ("excludes
|
|
153
154
|
* transfers between your own accounts"). For a line everyone should read, use
|
|
154
|
-
* {@link StatTileProps.description} instead.
|
|
155
|
+
* {@link StatTileProps.description} instead.
|
|
156
|
+
*
|
|
157
|
+
* 0.32 (docs/text-size-harmonization.md §4 "No fact only in a tooltip"): at Large
|
|
158
|
+
* and Extra large, and on a touch screen, the words are shown under the label
|
|
159
|
+
* instead of behind the "?". */
|
|
155
160
|
hint?: string;
|
|
156
161
|
/**
|
|
157
162
|
* Keep the label to ONE line, cut with an ellipsis, and show the whole of it in a
|
|
@@ -169,6 +174,9 @@ export interface StatTileProps
|
|
|
169
174
|
* your own `<Tooltip>` for the full text (keksdose's admin metrics-panel.tsx:134
|
|
170
175
|
* does, from before this prop). A wrapped label shows a bubble even when nothing is
|
|
171
176
|
* cut, and nests its trigger inside this one's.
|
|
177
|
+
*
|
|
178
|
+
* Ignored at Large and Extra large (0.32, §4): nothing truncates there, and the full
|
|
179
|
+
* label would otherwise be a fact only in a tooltip.
|
|
172
180
|
*/
|
|
173
181
|
truncateLabel?: boolean;
|
|
174
182
|
/**
|
|
@@ -199,6 +207,15 @@ export interface StatTileProps
|
|
|
199
207
|
* Withheld while `loading`, like the sub-values.
|
|
200
208
|
*/
|
|
201
209
|
projection?: StatTileSubValue;
|
|
210
|
+
/**
|
|
211
|
+
* Smaller figures under the headline, label left and figure right.
|
|
212
|
+
*
|
|
213
|
+
* At Large and Extra large (0.32, §4 "StatTile shows its one big number; the sparkline
|
|
214
|
+
* and sub-values move below"): the tile leads with the headline and its delta, and the
|
|
215
|
+
* projection, these rows and the sparkline follow beneath the description, each row's
|
|
216
|
+
* label over its figure — a 2-up tile at 150 % is 120 px of text wide, and a label
|
|
217
|
+
* beside a figure there squeezed both.
|
|
218
|
+
*/
|
|
202
219
|
subValues?: StatTileSubValue[];
|
|
203
220
|
/** Shorthand for a fluid {@link Sparkline} named after the tile and speaking in
|
|
204
221
|
* the tile's number format. The name is the label's text; see
|
|
@@ -310,6 +327,11 @@ export function StatTile({
|
|
|
310
327
|
...rest
|
|
311
328
|
}: StatTileProps) {
|
|
312
329
|
const text = useKitLabels("statTile", DEFAULT_STAT_TILE_LABELS, labels);
|
|
330
|
+
// §4: at Large the one big number leads and the rest follows below it; the label
|
|
331
|
+
// never truncates; on touch or at Large the hint is words, not a "?".
|
|
332
|
+
const large = useLargeText();
|
|
333
|
+
const inlineHint = useInlineFacts() && !!hint;
|
|
334
|
+
if (large) truncateLabel = false;
|
|
313
335
|
// A loading StatTileGrid puts every tile in it into the loading state and says
|
|
314
336
|
// "Loading…" ONCE for all of them; the tile then keeps its own sentence to itself
|
|
315
337
|
// (see StatTileGrid's `loading`).
|
|
@@ -342,7 +364,9 @@ export function StatTile({
|
|
|
342
364
|
const stretched = cn(
|
|
343
365
|
"text-start uppercase tracking-wide",
|
|
344
366
|
"after:absolute after:inset-0 after:rounded-lg after:content-['']",
|
|
345
|
-
|
|
367
|
+
// The kit's focus frame (0.32, §5), on the overlay — `FOCUS_RING`'s classes cannot
|
|
368
|
+
// carry the `after:`, so its width is spelt out.
|
|
369
|
+
"focus-visible:outline-none focus-visible:after:ring-[length:var(--focus-ring-width)] focus-visible:after:ring-inset focus-visible:after:ring-[var(--brand)]",
|
|
346
370
|
);
|
|
347
371
|
const describedBy = d ? `${valueId} ${deltaId}` : valueId;
|
|
348
372
|
let labelNode: ReactNode = label;
|
|
@@ -417,7 +441,7 @@ export function StatTile({
|
|
|
417
441
|
{!gridLoading && <span className="sr-only">{text.loading}</span>}
|
|
418
442
|
</span>
|
|
419
443
|
) : hasValue ? (
|
|
420
|
-
<span id={valueId} data-private={priv} className={cn(valueClass, valueLabel != null && "ms-auto")}>
|
|
444
|
+
<span id={valueId} data-private={priv} className={cn(valueClass, valueLabel != null && !large && "ms-auto")}>
|
|
421
445
|
{show(value)}
|
|
422
446
|
{unit != null && (
|
|
423
447
|
<span className="ms-1 text-[0.7em] font-medium text-[var(--text-muted)]">{unit}</span>
|
|
@@ -480,7 +504,7 @@ export function StatTile({
|
|
|
480
504
|
</span>
|
|
481
505
|
)}
|
|
482
506
|
{/* Above the stretched link's overlay, so it stays hoverable and focusable. */}
|
|
483
|
-
{hint && <FieldHint label={hint} side="top" className="relative z-10 shrink-0" />}
|
|
507
|
+
{hint && !inlineHint && <FieldHint label={hint} side="top" className="relative z-10 shrink-0" />}
|
|
484
508
|
</div>
|
|
485
509
|
{icon != null && (
|
|
486
510
|
<span aria-hidden className="shrink-0 text-[var(--text-muted)] [&_svg]:size-4">
|
|
@@ -489,10 +513,19 @@ export function StatTile({
|
|
|
489
513
|
)}
|
|
490
514
|
</div>
|
|
491
515
|
|
|
516
|
+
{inlineHint && (
|
|
517
|
+
// §4: the hint as words under the label — the same muted type as `description`,
|
|
518
|
+
// in the reading case of a sentence rather than the label's capitals.
|
|
519
|
+
<p data-slot="stat-tile-hint" className="mt-0.5 text-xs text-[var(--text-muted)]">
|
|
520
|
+
{hint}
|
|
521
|
+
</p>
|
|
522
|
+
)}
|
|
523
|
+
|
|
492
524
|
{valueLabel != null ? (
|
|
493
525
|
// Period-left / value-right, matching the sub-rows below it. flex-wrap lets a
|
|
494
|
-
// too-long amount drop to its own end-aligned line instead of overflowing.
|
|
495
|
-
|
|
526
|
+
// too-long amount drop to its own end-aligned line instead of overflowing. At
|
|
527
|
+
// Large the period goes over the figure, which then has the tile's width.
|
|
528
|
+
<div className={cn("mt-1 flex items-baseline gap-x-1.5", large ? "flex-col items-start" : "flex-wrap")}>
|
|
496
529
|
<span className="shrink-0 text-xs uppercase tracking-wide text-[var(--text-muted)]">{valueLabel}</span>
|
|
497
530
|
{headline}
|
|
498
531
|
</div>
|
|
@@ -500,7 +533,9 @@ export function StatTile({
|
|
|
500
533
|
<div className="mt-1">{headline}</div>
|
|
501
534
|
)}
|
|
502
535
|
|
|
503
|
-
{
|
|
536
|
+
{/* At Large the delta and description follow the figure at once, and the
|
|
537
|
+
projection moves down with the other figures (see `subValues`). */}
|
|
538
|
+
{!large && !loading && projection && (
|
|
504
539
|
<dl className="mt-0.5">
|
|
505
540
|
<FigureRow figure={projection} tileTone={tone} show={show} priv={priv} />
|
|
506
541
|
</dl>
|
|
@@ -508,16 +543,25 @@ export function StatTile({
|
|
|
508
543
|
|
|
509
544
|
{deltaNode}
|
|
510
545
|
{description != null && <div className="mt-1 text-xs text-[var(--text-muted)]">{description}</div>}
|
|
511
|
-
{graphic && <div className="mt-2">{graphic}</div>}
|
|
546
|
+
{!large && graphic && <div className="mt-2">{graphic}</div>}
|
|
512
547
|
|
|
513
|
-
{!loading && subValues && subValues.length > 0 && (
|
|
514
|
-
<dl className="mt-1.5 space-y-0.5">
|
|
515
|
-
{
|
|
516
|
-
<FigureRow
|
|
548
|
+
{!loading && ((large && projection) || (subValues && subValues.length > 0)) && (
|
|
549
|
+
<dl data-slot="stat-tile-figures" className={cn("mt-1.5", large ? "space-y-1.5" : "space-y-0.5")}>
|
|
550
|
+
{large && projection && (
|
|
551
|
+
<FigureRow figure={projection} tileTone={tone} show={show} priv={priv} stacked />
|
|
552
|
+
)}
|
|
553
|
+
{subValues?.map((sv, i) => (
|
|
554
|
+
<FigureRow key={i} figure={sv} tileTone={tone} show={show} priv={priv} stacked={large} />
|
|
517
555
|
))}
|
|
518
556
|
</dl>
|
|
519
557
|
)}
|
|
520
558
|
|
|
559
|
+
{large && graphic && (
|
|
560
|
+
<div data-slot="stat-tile-graphic" className="mt-2">
|
|
561
|
+
{graphic}
|
|
562
|
+
</div>
|
|
563
|
+
)}
|
|
564
|
+
|
|
521
565
|
{footer != null && <div className="mt-2">{footer}</div>}
|
|
522
566
|
</Card>
|
|
523
567
|
);
|
|
@@ -529,11 +573,14 @@ function FigureRow({
|
|
|
529
573
|
tileTone,
|
|
530
574
|
show,
|
|
531
575
|
priv,
|
|
576
|
+
stacked = false,
|
|
532
577
|
}: {
|
|
533
578
|
figure: StatTileSubValue;
|
|
534
579
|
tileTone: StatTileTone;
|
|
535
580
|
show: (v: ReactNode) => ReactNode;
|
|
536
581
|
priv: "" | undefined;
|
|
582
|
+
/** The label over the figure (Large, §4) instead of beside it. */
|
|
583
|
+
stacked?: boolean;
|
|
537
584
|
}) {
|
|
538
585
|
const own = figure.tone ?? (tileTone === "neutral" ? undefined : tileTone);
|
|
539
586
|
const svTone = own === "none" ? undefined : own;
|
|
@@ -543,11 +590,20 @@ function FigureRow({
|
|
|
543
590
|
// the period it belongs to. Now the label breaks within itself and the amount stays
|
|
544
591
|
// on the label's first line, end-aligned like every other row.
|
|
545
592
|
return (
|
|
546
|
-
<div
|
|
593
|
+
<div
|
|
594
|
+
className={cn(
|
|
595
|
+
"flex text-xs tabular-nums text-[var(--text-muted)]",
|
|
596
|
+
stacked ? "flex-col items-start" : "items-baseline gap-x-2",
|
|
597
|
+
)}
|
|
598
|
+
>
|
|
547
599
|
<dt className="min-w-0 uppercase tracking-wide [overflow-wrap:anywhere]">{figure.label}</dt>
|
|
548
600
|
<dd
|
|
549
601
|
data-private={priv}
|
|
550
|
-
className={cn(
|
|
602
|
+
className={cn(
|
|
603
|
+
"shrink-0 whitespace-nowrap",
|
|
604
|
+
!stacked && "ms-auto",
|
|
605
|
+
svTone && [toneClass(svTone, figure.value), "opacity-75"],
|
|
606
|
+
)}
|
|
551
607
|
>
|
|
552
608
|
{show(figure.value)}
|
|
553
609
|
</dd>
|
|
@@ -66,6 +66,28 @@ export function statusDotColor(tone: StatusDotTone): string {
|
|
|
66
66
|
|
|
67
67
|
const SIZE: Record<StatusDotSize, string> = { sm: "size-2", md: "size-2.5", lg: "size-3" };
|
|
68
68
|
|
|
69
|
+
/**
|
|
70
|
+
* A labelled dot at Large and Extra large (0.32.1, keksdose's 0.32 report;
|
|
71
|
+
* docs/text-size-harmonization.md §4 "nothing truncates"): the label wraps instead of
|
|
72
|
+
* ending in "…", so a legend entry or a status keeps its last word, the one that tells
|
|
73
|
+
* two states apart. The dot then sits on the label's FIRST line rather than halfway down
|
|
74
|
+
* the block: the row aligns to the top and the dot moves down by half of what one line
|
|
75
|
+
* (`1lh`, the label's own line height, which the dot inherits) leaves around it.
|
|
76
|
+
* `large:` classes, so Normal keeps its one centred line.
|
|
77
|
+
*
|
|
78
|
+
* `break-words`, not `[overflow-wrap:anywhere]`: a legend often sits in a table, and
|
|
79
|
+
* `anywhere` lowers the label's min-content width to one letter, so an auto-sized column
|
|
80
|
+
* squeezed it to a letter per line (the showcase's tone table at 360 px, Extra large).
|
|
81
|
+
* `break-word` keeps each word whole wherever the width is the content's to choose, and
|
|
82
|
+
* still breaks one that cannot fit its line at all.
|
|
83
|
+
*/
|
|
84
|
+
const LABEL_WRAP_AT_LARGE = "large:whitespace-normal large:break-words";
|
|
85
|
+
const DOT_ON_FIRST_LINE: Record<StatusDotSize, string> = {
|
|
86
|
+
sm: "large:mt-[calc((1lh_-_0.5rem)/2)]",
|
|
87
|
+
md: "large:mt-[calc((1lh_-_0.625rem)/2)]",
|
|
88
|
+
lg: "large:mt-[calc((1lh_-_0.75rem)/2)]",
|
|
89
|
+
};
|
|
90
|
+
|
|
69
91
|
export interface StatusDotProps extends Omit<ComponentPropsWithoutRef<"span">, "children"> {
|
|
70
92
|
tone?: StatusDotTone;
|
|
71
93
|
size?: StatusDotSize;
|
|
@@ -116,6 +138,7 @@ export function StatusDot({
|
|
|
116
138
|
SIZE[size],
|
|
117
139
|
FILL[tone],
|
|
118
140
|
ring && "ring-2 ring-[var(--bg-surface)]",
|
|
141
|
+
label != null && DOT_ON_FIRST_LINE[size],
|
|
119
142
|
label == null && className,
|
|
120
143
|
dotClassName,
|
|
121
144
|
)}
|
|
@@ -130,9 +153,9 @@ export function StatusDot({
|
|
|
130
153
|
return (
|
|
131
154
|
// No `aria-label` here: the visible label is the text, and a name on a role-less
|
|
132
155
|
// span is one ARIA forbids and screen readers ignore.
|
|
133
|
-
<span {...rest} className={cn("inline-flex min-w-0 items-center gap-1.5 text-sm", className)}>
|
|
156
|
+
<span {...rest} className={cn("inline-flex min-w-0 items-center gap-1.5 text-sm large:items-start", className)}>
|
|
134
157
|
{dot}
|
|
135
|
-
<span className="min-w-0 truncate">{label}</span>
|
|
158
|
+
<span className={cn("min-w-0 truncate", LABEL_WRAP_AT_LARGE)}>{label}</span>
|
|
136
159
|
</span>
|
|
137
160
|
);
|
|
138
161
|
}
|
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
import { useEffect, useRef, useState } from "react";
|
|
2
2
|
import type { ReactNode } from "react";
|
|
3
3
|
import { cn } from "../lib/cn";
|
|
4
|
+
import { FOCUS_RING } from "./focus-ring";
|
|
4
5
|
import { useRowSwipe, type SwipeStage } from "../hooks/use-row-swipe";
|
|
5
6
|
import { DEFAULT_SWIPEABLE_ROW_LABELS, useKitLabels } from "../i18n/kit-labels";
|
|
6
7
|
|
|
@@ -268,9 +269,16 @@ export function SwipeableRow({
|
|
|
268
269
|
type="button"
|
|
269
270
|
onClick={action.onCommit}
|
|
270
271
|
className={cn(
|
|
271
|
-
"sr-only whitespace-nowrap rounded-md border
|
|
272
|
+
"sr-only whitespace-nowrap rounded-md border-[var(--border)] bg-[var(--bg-surface)] text-xs font-medium text-[var(--text-primary)] shadow-sm",
|
|
272
273
|
"focus:not-sr-only focus:pointer-events-auto focus:inline-flex focus:items-center focus:gap-1.5",
|
|
273
|
-
|
|
274
|
+
// The box's padding and border only once it shows (0.32.1, keksdose's
|
|
275
|
+
// 0.32 report). Unconditional, `px-2` and `border` beat `sr-only`'s
|
|
276
|
+
// `padding: 0` and `border-width: 0`, so the hidden button was a 1 px
|
|
277
|
+
// box with 2 × 0.5rem of padding round it: 26 px at Extra large, running
|
|
278
|
+
// past the row's end from the strip's start — invisible under its clip,
|
|
279
|
+
// but counted in the page's scroll width (§4: nothing overflows).
|
|
280
|
+
"focus:border focus:px-2 focus:py-1",
|
|
281
|
+
FOCUS_RING,
|
|
274
282
|
)}
|
|
275
283
|
>
|
|
276
284
|
{/* The label is the button's accessible name, so the caller's icon is
|