@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
|
@@ -4,6 +4,7 @@ import { cn } from "../lib/cn";
|
|
|
4
4
|
import { useAnnounce } from "../hooks/use-announce";
|
|
5
5
|
import { useKitLabels } from "../i18n/kit-labels";
|
|
6
6
|
import { Input, Spinner } from "./ui";
|
|
7
|
+
import { FOCUS_RING } from "./focus-ring";
|
|
7
8
|
import { Tooltip } from "./tooltip";
|
|
8
9
|
import { useCommitReason } from "./write-lock";
|
|
9
10
|
|
|
@@ -154,6 +155,23 @@ function RenderEditor<T>({ render, ...props }: InlineEditorProps<T> & { render:
|
|
|
154
155
|
return render(props);
|
|
155
156
|
}
|
|
156
157
|
|
|
158
|
+
/**
|
|
159
|
+
* The value at Large and Extra large (0.32.1, keksdose's 0.32 report;
|
|
160
|
+
* docs/text-size-harmonization.md §4 "nothing truncates"): the display button, the
|
|
161
|
+
* locked one and the read-only text wrap instead of ending in "…", and break a word too
|
|
162
|
+
* long for the cell, so an IBAN or an e-mail address shows to its last character. The
|
|
163
|
+
* value IS the button's accessible name and the thing being edited: a reader who needs
|
|
164
|
+
* big type cannot recover a cut-off end by squinting. A `large:` class, so a table of
|
|
165
|
+
* these keeps its one-line cells at Normal.
|
|
166
|
+
*
|
|
167
|
+
* `break-words`, not `[overflow-wrap:anywhere]`: these live in table cells (keksdose's
|
|
168
|
+
* budget and invoice lines), and `anywhere` lowers the value's min-content width to one
|
|
169
|
+
* letter, so an auto-sized column could squeeze an amount to a digit per line. With
|
|
170
|
+
* `break-word` a column keeps each word whole; the button is `w-full`, so a word wider
|
|
171
|
+
* than a sized cell still breaks.
|
|
172
|
+
*/
|
|
173
|
+
const VALUE_WRAP_AT_LARGE = "large:whitespace-normal large:break-words";
|
|
174
|
+
|
|
157
175
|
/** `onCommit`'s result, if it is a promise. */
|
|
158
176
|
function asPromise(result: unknown): Promise<unknown> | null {
|
|
159
177
|
return result && typeof (result as Promise<unknown>).then === "function" ? (result as Promise<unknown>) : null;
|
|
@@ -414,7 +432,7 @@ export function InlineEditField<T = string>(props: InlineEditFieldProps<T>) {
|
|
|
414
432
|
let body: ReactNode;
|
|
415
433
|
if (readOnly) {
|
|
416
434
|
body = (
|
|
417
|
-
<span {...private_} className={cn("block min-w-0 truncate", alignClass)}>
|
|
435
|
+
<span {...private_} className={cn("block min-w-0 truncate", VALUE_WRAP_AT_LARGE, alignClass)}>
|
|
418
436
|
{content}
|
|
419
437
|
</span>
|
|
420
438
|
);
|
|
@@ -467,7 +485,7 @@ export function InlineEditField<T = string>(props: InlineEditFieldProps<T>) {
|
|
|
467
485
|
{pending && <Spinner label={null} className="size-4 shrink-0" />}
|
|
468
486
|
</div>
|
|
469
487
|
{failed && (
|
|
470
|
-
<p id={errorId} className="mt-1 text-
|
|
488
|
+
<p id={errorId} className="mt-1 text-caption leading-tight text-[var(--danger)]">
|
|
471
489
|
{failure}
|
|
472
490
|
</p>
|
|
473
491
|
)}
|
|
@@ -490,7 +508,9 @@ export function InlineEditField<T = string>(props: InlineEditFieldProps<T>) {
|
|
|
490
508
|
aria-describedby={reasonId}
|
|
491
509
|
onClick={(e) => e.preventDefault()}
|
|
492
510
|
className={cn(
|
|
493
|
-
"block w-full min-w-0 cursor-not-allowed truncate rounded-sm focus:outline-none
|
|
511
|
+
"block w-full min-w-0 cursor-not-allowed truncate rounded-sm focus:outline-none",
|
|
512
|
+
VALUE_WRAP_AT_LARGE,
|
|
513
|
+
FOCUS_RING,
|
|
494
514
|
alignClass,
|
|
495
515
|
)}
|
|
496
516
|
>
|
|
@@ -513,7 +533,9 @@ export function InlineEditField<T = string>(props: InlineEditFieldProps<T>) {
|
|
|
513
533
|
{...private_}
|
|
514
534
|
onClick={() => setOpen(true)}
|
|
515
535
|
className={cn(
|
|
516
|
-
"block w-full min-w-0 truncate rounded-sm underline-offset-2 hover:underline focus:outline-none
|
|
536
|
+
"block w-full min-w-0 truncate rounded-sm underline-offset-2 hover:underline focus:outline-none",
|
|
537
|
+
VALUE_WRAP_AT_LARGE,
|
|
538
|
+
FOCUS_RING,
|
|
517
539
|
alignClass,
|
|
518
540
|
)}
|
|
519
541
|
>
|
|
@@ -9,6 +9,7 @@ import { cn } from "../lib/cn";
|
|
|
9
9
|
import { Checkbox } from "./checkbox";
|
|
10
10
|
import type { CheckboxProps } from "./checkbox";
|
|
11
11
|
import {
|
|
12
|
+
DEFAULT_LEGAL_LABELS,
|
|
12
13
|
LEGAL_HREFS,
|
|
13
14
|
baseLanguage,
|
|
14
15
|
LegalFooter,
|
|
@@ -22,6 +23,7 @@ import {
|
|
|
22
23
|
warnLegalOnce,
|
|
23
24
|
} from "./legal";
|
|
24
25
|
import type {
|
|
26
|
+
LegalDisclaimerSectionLabels,
|
|
25
27
|
LegalFramedSectionLabels,
|
|
26
28
|
LegalLabels,
|
|
27
29
|
LegalOperator,
|
|
@@ -163,6 +165,7 @@ export type LegalKitSectionProps = LegalKitSectionBase &
|
|
|
163
165
|
(
|
|
164
166
|
| {
|
|
165
167
|
section: "browser";
|
|
168
|
+
variant?: never;
|
|
166
169
|
/** What this app keeps in the browser, one entry per item — rendered as a `<ul>`
|
|
167
170
|
* between the kit's two sentences. The app's words, in every language it serves. */
|
|
168
171
|
entries: readonly string[];
|
|
@@ -171,6 +174,7 @@ export type LegalKitSectionProps = LegalKitSectionBase &
|
|
|
171
174
|
}
|
|
172
175
|
| {
|
|
173
176
|
section: "legal_basis" | "rights";
|
|
177
|
+
variant?: never;
|
|
174
178
|
entries?: never;
|
|
175
179
|
/** `legal_basis`: after the kit's paragraph (consent, where an app relies on
|
|
176
180
|
* it). `rights`: between the list of rights and the supervisory authorities
|
|
@@ -179,12 +183,28 @@ export type LegalKitSectionProps = LegalKitSectionBase &
|
|
|
179
183
|
children?: ReactNode;
|
|
180
184
|
}
|
|
181
185
|
| {
|
|
182
|
-
section:
|
|
186
|
+
section: "disclaimer";
|
|
187
|
+
/**
|
|
188
|
+
* 0.32.0 (docs/billing-harmonization.md §8, legal decision 7): which disclaimer.
|
|
189
|
+
* `non-commercial` (default) is the beta's "private, non-commercial project";
|
|
190
|
+
* `commercial` is for an app that charges, sold through a Merchant of Record —
|
|
191
|
+
* chosen per app, in the release that turns its billing on.
|
|
192
|
+
*/
|
|
193
|
+
variant?: LegalDisclaimerVariant;
|
|
194
|
+
entries?: never;
|
|
195
|
+
children?: never;
|
|
196
|
+
}
|
|
197
|
+
| {
|
|
198
|
+
section: Exclude<LegalKitSectionKey, "browser" | "legal_basis" | "rights" | "disclaimer">;
|
|
199
|
+
variant?: never;
|
|
183
200
|
entries?: never;
|
|
184
201
|
children?: never;
|
|
185
202
|
}
|
|
186
203
|
);
|
|
187
204
|
|
|
205
|
+
/** 0.32.0: the imprint disclaimer's two texts — see {@link LegalKitSectionProps}. */
|
|
206
|
+
export type LegalDisclaimerVariant = "non-commercial" | "commercial";
|
|
207
|
+
|
|
188
208
|
/** The app's paragraph: a plain string as running text (line breaks kept, refs
|
|
189
209
|
* resolved), anything else as it is. */
|
|
190
210
|
function appPart(children: ReactNode): ReactNode {
|
|
@@ -261,7 +281,13 @@ export function LegalKitSection(props: LegalKitSectionProps) {
|
|
|
261
281
|
parts = [lead, app, tail];
|
|
262
282
|
}
|
|
263
283
|
} else {
|
|
264
|
-
|
|
284
|
+
// The imprint's commercial disclaimer (0.32.0): its own body under the same title.
|
|
285
|
+
const commercial =
|
|
286
|
+
props.section === "disclaimer" && props.variant === "commercial"
|
|
287
|
+
? ((entry as LegalDisclaimerSectionLabels).commercial ??
|
|
288
|
+
DEFAULT_LEGAL_LABELS.sections.impressum.disclaimer.commercial)
|
|
289
|
+
: undefined;
|
|
290
|
+
parts = [<LegalText key="body" text={commercial ?? fill(entry.body)} />, app];
|
|
265
291
|
}
|
|
266
292
|
|
|
267
293
|
return (
|
package/src/components/legal.tsx
CHANGED
|
@@ -132,6 +132,21 @@ export interface LegalTextSectionLabels {
|
|
|
132
132
|
body: string;
|
|
133
133
|
}
|
|
134
134
|
|
|
135
|
+
/**
|
|
136
|
+
* 0.32.0: the imprint's disclaimer, with the body of its COMMERCIAL variant
|
|
137
|
+
* (docs/billing-harmonization.md §8; legal decision 7). The title is the same in both:
|
|
138
|
+
* liability for content and links is the subject either way.
|
|
139
|
+
*/
|
|
140
|
+
export interface LegalDisclaimerSectionLabels extends LegalTextSectionLabels {
|
|
141
|
+
/**
|
|
142
|
+
* The body for `<LegalKitSection section="disclaimer" variant="commercial">`: a paid
|
|
143
|
+
* service sold through a Merchant of Record, which sells in its own name (§2.2), so the
|
|
144
|
+
* "private, non-commercial … closed beta" of `body` would be untrue. OPTIONAL, as every
|
|
145
|
+
* key added to a namespace an app may annotate: left out, the provider's, then English.
|
|
146
|
+
*/
|
|
147
|
+
commercial?: string;
|
|
148
|
+
}
|
|
149
|
+
|
|
135
150
|
/** A kit section whose text names the operator (§4.3 `{name}`, `{email}`, …). */
|
|
136
151
|
export interface LegalOperatorSectionLabels {
|
|
137
152
|
title: string;
|
|
@@ -197,7 +212,8 @@ export interface LegalLabels {
|
|
|
197
212
|
impressum: {
|
|
198
213
|
operator: LegalOperatorSectionLabels;
|
|
199
214
|
contact: LegalOperatorSectionLabels;
|
|
200
|
-
|
|
215
|
+
/** `body` is the default, non-commercial text; `commercial` the 0.32 variant. */
|
|
216
|
+
disclaimer: LegalDisclaimerSectionLabels;
|
|
201
217
|
};
|
|
202
218
|
privacy: {
|
|
203
219
|
controller: LegalOperatorSectionLabels;
|
|
@@ -260,6 +276,8 @@ export const DEFAULT_LEGAL_LABELS: LegalLabels = {
|
|
|
260
276
|
disclaimer: {
|
|
261
277
|
title: "Liability for content and links",
|
|
262
278
|
body: "This is a private, non-commercial project offered during a closed beta, without warranty. External sites we link to are the responsibility of their respective operators; we have no control over their content.",
|
|
279
|
+
commercial:
|
|
280
|
+
"This is a commercial service. Paid plans are sold by our reseller, which acts as the Merchant of Record: it sells the subscription in its own name, takes the payment, issues the invoice and handles VAT, and its terms of sale apply to the purchase. We take care that the content of this service is accurate, but cannot guarantee that it is complete or up to date. External sites we link to are the responsibility of their respective operators; we have no control over their content.",
|
|
263
281
|
},
|
|
264
282
|
},
|
|
265
283
|
privacy: {
|
|
@@ -6,6 +6,7 @@ import { cn } from "../lib/cn";
|
|
|
6
6
|
import { horizontalStep } from "../lib/direction";
|
|
7
7
|
import { useKitLabels } from "../i18n/kit-labels";
|
|
8
8
|
import { useAuthedSrc } from "../hooks/use-authed-src";
|
|
9
|
+
import { useBreakpoint } from "../hooks/use-breakpoint";
|
|
9
10
|
import type { AuthedFetcher } from "../hooks/use-authed-src";
|
|
10
11
|
import { FullBleedDialog } from "./full-bleed-dialog";
|
|
11
12
|
import { IconButton, buttonClasses } from "./ui";
|
|
@@ -169,6 +170,16 @@ export function Lightbox({
|
|
|
169
170
|
const anchorRef = useRef<HTMLSpanElement>(null);
|
|
170
171
|
const dir = useAnchorDir(anchorRef, open);
|
|
171
172
|
|
|
173
|
+
// The toolbar's words (docs/text-size-harmonization.md §4, §10.8). At Large an
|
|
174
|
+
// IconButton shows its label beside the glyph; on a narrow screen the viewer's header —
|
|
175
|
+
// the counter, Zoom, Download and the dialog's close — has no room for two words at
|
|
176
|
+
// 150 % (a 390 px phone is 260 px of Normal type), so below `sm` the toolbar keeps its
|
|
177
|
+
// icons, as the plain download link hides its word there (`max-sm:sr-only`). From `sm`
|
|
178
|
+
// up, at the same breakpoint the CSS uses, the words show. Each name stays the
|
|
179
|
+
// accessible name and the tooltip either way.
|
|
180
|
+
const narrow = useBreakpoint("max-sm");
|
|
181
|
+
const toolbarLabelVisible = narrow ? false : undefined;
|
|
182
|
+
|
|
172
183
|
const fetched = useAuthedSrc(item?.src, { fetcher, enabled: open });
|
|
173
184
|
const kind = item ? imageItemKind(item, fetched.type) : "image";
|
|
174
185
|
|
|
@@ -236,7 +247,12 @@ export function Lightbox({
|
|
|
236
247
|
const downloadControl =
|
|
237
248
|
download && item ? (
|
|
238
249
|
onDownload ? (
|
|
239
|
-
<IconButton
|
|
250
|
+
<IconButton
|
|
251
|
+
size="sm"
|
|
252
|
+
label={labels.download}
|
|
253
|
+
labelVisible={toolbarLabelVisible}
|
|
254
|
+
onClick={() => onDownload(item, index)}
|
|
255
|
+
>
|
|
240
256
|
<Download />
|
|
241
257
|
</IconButton>
|
|
242
258
|
) : downloadHref ? (
|
|
@@ -264,7 +280,13 @@ export function Lightbox({
|
|
|
264
280
|
</span>
|
|
265
281
|
<span className="min-w-0 flex-1" />
|
|
266
282
|
{zoomEnabled && kind === "image" && (
|
|
267
|
-
<IconButton
|
|
283
|
+
<IconButton
|
|
284
|
+
size="sm"
|
|
285
|
+
label={labels.zoom}
|
|
286
|
+
labelVisible={toolbarLabelVisible}
|
|
287
|
+
pressed={zoomed}
|
|
288
|
+
onClick={toggleZoom}
|
|
289
|
+
>
|
|
268
290
|
<ZoomIn />
|
|
269
291
|
</IconButton>
|
|
270
292
|
)}
|
|
@@ -384,6 +384,12 @@ export function LineItems<T>({
|
|
|
384
384
|
variant={isConfirming ? "danger" : "ghost"}
|
|
385
385
|
tone={isConfirming ? undefined : "danger"}
|
|
386
386
|
label={isConfirming ? labels.confirmRemove(row) : labels.remove(row)}
|
|
387
|
+
// The icon alone at every text size (docs/text-size-harmonization.md §10.8): the
|
|
388
|
+
// row's one control, in a grid column sized for an icon, whose name becomes a
|
|
389
|
+
// sentence while it waits ("Remove row 3? Press again to confirm") — as text at
|
|
390
|
+
// Large it would push the row's fields aside and change width between the two
|
|
391
|
+
// presses. The name stays the accessible name; the red fill says "confirm".
|
|
392
|
+
labelVisible={false}
|
|
387
393
|
disabled={!canRemove}
|
|
388
394
|
onClick={() => void removeAt(index)}
|
|
389
395
|
onBlur={() => {
|
|
@@ -588,7 +594,7 @@ export function LineItems<T>({
|
|
|
588
594
|
)}
|
|
589
595
|
|
|
590
596
|
{hasError && (
|
|
591
|
-
<p className="text-
|
|
597
|
+
<p className="text-caption leading-tight text-[var(--danger)]">
|
|
592
598
|
{error}
|
|
593
599
|
</p>
|
|
594
600
|
)}
|
package/src/components/list.tsx
CHANGED
|
@@ -3,7 +3,7 @@ import type { ComponentPropsWithoutRef, HTMLAttributes, MouseEvent, ReactElement
|
|
|
3
3
|
import { ChevronDown, ExternalLink } from "lucide-react";
|
|
4
4
|
import type { LucideIcon } from "lucide-react";
|
|
5
5
|
import { cn } from "../lib/cn";
|
|
6
|
-
import { Spinner } from "./ui";
|
|
6
|
+
import { FOCUS_RING, Spinner } from "./ui";
|
|
7
7
|
import { StatusDot } from "./status-dot";
|
|
8
8
|
import { Collapse } from "./disclosure";
|
|
9
9
|
import { toneTextClass } from "./signed-amount";
|
|
@@ -114,8 +114,20 @@ const PAD: Record<
|
|
|
114
114
|
* colour of the slot's own, so an element's colour (or the row's) stands. */
|
|
115
115
|
export type ListItemTrailingTone = TextTone | "inherit";
|
|
116
116
|
|
|
117
|
-
|
|
118
|
-
|
|
117
|
+
// The kit's focus frame (§5), inset so the row's own border and its neighbours do not
|
|
118
|
+
// clip it.
|
|
119
|
+
const TARGET_RING = cn(FOCUS_RING, "focus-visible:ring-inset");
|
|
120
|
+
|
|
121
|
+
/**
|
|
122
|
+
* §4 "ListItem: title, subtitle and meta wrap instead of truncating" at Large and Extra
|
|
123
|
+
* large (docs/text-size-harmonization.md). `large:` variants over the Normal look, so
|
|
124
|
+
* a list keeps its one-height rows at Normal and costs no render to switch: a one-line
|
|
125
|
+
* `truncate` wraps (and breaks a word too long for the row), a `line-clamp-2` lets go.
|
|
126
|
+
* An ellipsis hides the end of a name, which is the part a reader who needs big type
|
|
127
|
+
* cannot recover by squinting.
|
|
128
|
+
*/
|
|
129
|
+
const WRAP_AT_LARGE = "large:whitespace-normal large:[overflow-wrap:anywhere]";
|
|
130
|
+
const UNCLAMP_AT_LARGE = "large:line-clamp-none";
|
|
119
131
|
|
|
120
132
|
interface ListItemBaseProps {
|
|
121
133
|
/** The row's name: one line, truncated — unless {@link titleLines} says otherwise. */
|
|
@@ -410,6 +422,11 @@ interface NotExpandable {
|
|
|
410
422
|
* One row of a {@link List}: leading icon or avatar, title and subtitle (both
|
|
411
423
|
* truncating by default), a trailing slot, and — beside the row, not inside it — its actions.
|
|
412
424
|
*
|
|
425
|
+
* At Large and Extra large (0.32, docs/text-size-harmonization.md §4) nothing in it
|
|
426
|
+
* truncates: the overline, title, subtitle and meta wrap, a two-line clamp lets go, and
|
|
427
|
+
* a trailing slot drops under the text when the two no longer fit side by side. The
|
|
428
|
+
* rows lose their one height there; that is the trade the reader asked for.
|
|
429
|
+
*
|
|
413
430
|
* All three apps draw this row by hand, a dozen times: kastlan's units
|
|
414
431
|
* (building-detail-page.tsx:402), open tickets (group-overview-page.tsx:160), activity
|
|
415
432
|
* feed (activity-feed.tsx:53), company users (platform-company-detail-page.tsx:140)
|
|
@@ -506,9 +523,12 @@ export const ListItem = forwardRef<HTMLElement, ListItemProps>(function ListItem
|
|
|
506
523
|
/>
|
|
507
524
|
)}
|
|
508
525
|
{leading}
|
|
509
|
-
|
|
526
|
+
{/* With a trailing slot, a basis at Large: below it the trailing chip or figure
|
|
527
|
+
wraps under the text (the target wraps, see `target`) rather than squeezing the
|
|
528
|
+
now-wrapping title into a column one word wide (§4, 240 px effective width). */}
|
|
529
|
+
<span className={cn("flex min-w-0 flex-1 flex-col", trailing != null && "large:basis-40")}>
|
|
510
530
|
{overline != null && (
|
|
511
|
-
<span className="block truncate text-
|
|
531
|
+
<span className={cn("block truncate text-caption font-medium leading-snug text-[var(--text-muted)]", WRAP_AT_LARGE)}>
|
|
512
532
|
{overline}
|
|
513
533
|
</span>
|
|
514
534
|
)}
|
|
@@ -517,7 +537,11 @@ export const ListItem = forwardRef<HTMLElement, ListItemProps>(function ListItem
|
|
|
517
537
|
id={stacked ? titleId : undefined}
|
|
518
538
|
className={cn(
|
|
519
539
|
"block text-sm text-[var(--text-primary)]",
|
|
520
|
-
titleLines === 1
|
|
540
|
+
titleLines === 1
|
|
541
|
+
? cn("truncate", WRAP_AT_LARGE)
|
|
542
|
+
: titleLines === 2
|
|
543
|
+
? cn("line-clamp-2 break-words", UNCLAMP_AT_LARGE)
|
|
544
|
+
: "break-words",
|
|
521
545
|
unread ? "font-semibold" : "font-medium",
|
|
522
546
|
)}
|
|
523
547
|
>
|
|
@@ -529,7 +553,7 @@ export const ListItem = forwardRef<HTMLElement, ListItemProps>(function ListItem
|
|
|
529
553
|
<span
|
|
530
554
|
className={cn(
|
|
531
555
|
"block text-xs text-[var(--text-muted)]",
|
|
532
|
-
subtitleLines === 2 ? "line-clamp-2" : "truncate",
|
|
556
|
+
subtitleLines === 2 ? cn("line-clamp-2 break-words", UNCLAMP_AT_LARGE) : cn("truncate", WRAP_AT_LARGE),
|
|
533
557
|
)}
|
|
534
558
|
>
|
|
535
559
|
{subtitle}
|
|
@@ -538,8 +562,8 @@ export const ListItem = forwardRef<HTMLElement, ListItemProps>(function ListItem
|
|
|
538
562
|
{meta != null && (
|
|
539
563
|
<span
|
|
540
564
|
className={cn(
|
|
541
|
-
"mt-0.5 text-
|
|
542
|
-
metaWrap ? "flex flex-wrap items-center gap-1" : "block truncate",
|
|
565
|
+
"mt-0.5 text-caption leading-snug text-[var(--text-muted)]",
|
|
566
|
+
metaWrap ? "flex flex-wrap items-center gap-1" : cn("block truncate", WRAP_AT_LARGE),
|
|
543
567
|
)}
|
|
544
568
|
>
|
|
545
569
|
{meta}
|
|
@@ -550,7 +574,7 @@ export const ListItem = forwardRef<HTMLElement, ListItemProps>(function ListItem
|
|
|
550
574
|
{trailing != null && (
|
|
551
575
|
<span
|
|
552
576
|
className={cn(
|
|
553
|
-
"flex shrink-0 items-center gap-2 text-xs",
|
|
577
|
+
"flex shrink-0 items-center gap-2 text-xs large:ms-auto",
|
|
554
578
|
trailingTone !== "inherit" && toneTextClass(trailingTone),
|
|
555
579
|
)}
|
|
556
580
|
>
|
|
@@ -582,6 +606,8 @@ export const ListItem = forwardRef<HTMLElement, ListItemProps>(function ListItem
|
|
|
582
606
|
|
|
583
607
|
const target = cn(
|
|
584
608
|
"flex min-w-0 flex-1 text-start",
|
|
609
|
+
// §4 at Large: the trailing slot drops under the text when both no longer fit.
|
|
610
|
+
trailing != null && "large:flex-wrap",
|
|
585
611
|
align === "start" ? "items-start" : "items-center",
|
|
586
612
|
pad.target,
|
|
587
613
|
// When stacked the target is the top of the box, not all of it, so it takes its
|
|
@@ -8,9 +8,9 @@ import { horizontalStep } from "../lib/direction";
|
|
|
8
8
|
// be either and the line decides. See the three named rules at the top of table-text.
|
|
9
9
|
import { cellNumber, isCellNumber, parseRows, splitRow } from "../lib/table-text";
|
|
10
10
|
import { useKitLabels, useKitLocale } from "../i18n/kit-labels";
|
|
11
|
-
import { useWindowedRows } from "../hooks/use-windowed-rows";
|
|
11
|
+
import { useWindowedRows, WINDOWED_ROW_INDEX } from "../hooks/use-windowed-rows";
|
|
12
12
|
import { ToggleGroup } from "./toggle-group";
|
|
13
|
-
import { Button, FIELD_INVALID, Textarea } from "./ui";
|
|
13
|
+
import { Button, FIELD_INVALID, FIELD_TOUCH_TEXT, FOCUS_RING, Textarea } from "./ui";
|
|
14
14
|
|
|
15
15
|
/**
|
|
16
16
|
* A measured table: a fixed set of numeric columns, typed cell by cell or pasted as a
|
|
@@ -101,8 +101,10 @@ export type MeasuredGridView = "cells" | "text";
|
|
|
101
101
|
* empty cell is a hole in the measurement, and a table with a hole is not one to save. */
|
|
102
102
|
const BLANK = "";
|
|
103
103
|
|
|
104
|
-
/** Height of one grid row
|
|
105
|
-
*
|
|
104
|
+
/** Height of one grid row at Normal text size, in px — the windowing's ESTIMATE since
|
|
105
|
+
* 0.32 (docs/text-size-harmonization.md §10.9): `useWindowedRows` multiplies it by the
|
|
106
|
+
* text size's scale (35 px at Large, 42 at Extra large) and then measures the rows it
|
|
107
|
+
* renders, so a row is never cut to a height the type has outgrown. */
|
|
106
108
|
const DEFAULT_ROW_HEIGHT = 28;
|
|
107
109
|
|
|
108
110
|
const ALL_VIEWS: readonly MeasuredGridView[] = ["cells", "text"];
|
|
@@ -218,7 +220,9 @@ export interface MeasuredGridProps
|
|
|
218
220
|
/** Which views the toggle offers, the first being where it opens. Default both;
|
|
219
221
|
* one view hides the toggle. */
|
|
220
222
|
views?: ReadonlyArray<MeasuredGridView>;
|
|
221
|
-
/**
|
|
223
|
+
/** A row's height at Normal text size, in px. Default 28. Since 0.32 it is the
|
|
224
|
+
* windowing's estimate and each row's minimum, multiplied by the text size's scale;
|
|
225
|
+
* the rendered rows are measured (docs/text-size-harmonization.md §10.9). */
|
|
222
226
|
rowHeight?: number;
|
|
223
227
|
/** BCP 47 tag for the decimal mark of cells written by a paste or the text view,
|
|
224
228
|
* and for the row numbers; else the `<UiKitProvider locale>`. */
|
|
@@ -288,7 +292,7 @@ export function MeasuredGrid({
|
|
|
288
292
|
// to the initial containing block (see sr-only-containment.test).
|
|
289
293
|
<div {...rest} className={cn("relative", className)}>
|
|
290
294
|
<div className="mb-1 flex flex-wrap items-center justify-between gap-2">
|
|
291
|
-
<span id={labelId} className="text-
|
|
295
|
+
<span id={labelId} className="text-caption font-medium text-[var(--text-muted)]">
|
|
292
296
|
{label}
|
|
293
297
|
</span>
|
|
294
298
|
{offered.length > 1 && (
|
|
@@ -330,7 +334,7 @@ export function MeasuredGrid({
|
|
|
330
334
|
/>
|
|
331
335
|
)}
|
|
332
336
|
{hint && (
|
|
333
|
-
<p id={hintId} className="mt-1 px-1 text-
|
|
337
|
+
<p id={hintId} className="mt-1 px-1 text-caption text-[var(--text-muted)]">
|
|
334
338
|
{hint}
|
|
335
339
|
</p>
|
|
336
340
|
)}
|
|
@@ -382,7 +386,11 @@ function CellGrid({
|
|
|
382
386
|
// first number, and "add a row" is not the first thing to ask of someone who has
|
|
383
387
|
// just opened an empty table. It is not written back until something is typed.
|
|
384
388
|
const grid = cells.length ? cells : [blankRow()];
|
|
385
|
-
const { first, last, totalHeight } = useWindowedRows(
|
|
389
|
+
const { first, last, totalHeight, offsetOf, heightOf, estimate, measureRef } = useWindowedRows(
|
|
390
|
+
grid.length,
|
|
391
|
+
rowHeight,
|
|
392
|
+
scrollRef,
|
|
393
|
+
);
|
|
386
394
|
const rowNumber = useMemo(() => new Intl.NumberFormat(locale), [locale]);
|
|
387
395
|
|
|
388
396
|
// The remove buttons are the last column of the grid, reachable by the arrows like
|
|
@@ -434,9 +442,11 @@ function CellGrid({
|
|
|
434
442
|
if (!element) return;
|
|
435
443
|
const room = element.clientHeight - (headRef.current?.offsetHeight ?? 0);
|
|
436
444
|
if (room <= 0) return;
|
|
437
|
-
|
|
445
|
+
// Measured where the row has been rendered, the scaled estimate where not (§10.9).
|
|
446
|
+
const top = offsetOf(row);
|
|
447
|
+
const height = heightOf(row);
|
|
438
448
|
if (top < element.scrollTop) element.scrollTop = top;
|
|
439
|
-
else if (top +
|
|
449
|
+
else if (top + height > element.scrollTop + room) element.scrollTop = top + height - room;
|
|
440
450
|
};
|
|
441
451
|
|
|
442
452
|
const focusCell = (row: number, column: number) => {
|
|
@@ -468,7 +478,7 @@ function CellGrid({
|
|
|
468
478
|
const element = scrollRef.current;
|
|
469
479
|
const room = element ? element.clientHeight - (headRef.current?.offsetHeight ?? 0) : 0;
|
|
470
480
|
// No layout (a hidden pane, jsdom): a fixed ten rather than one row at a time.
|
|
471
|
-
return room > 0 ? Math.max(1, Math.floor(room /
|
|
481
|
+
return room > 0 ? Math.max(1, Math.floor(room / estimate) - 1) : 10;
|
|
472
482
|
};
|
|
473
483
|
|
|
474
484
|
/**
|
|
@@ -603,7 +613,7 @@ function CellGrid({
|
|
|
603
613
|
<div
|
|
604
614
|
role="columnheader"
|
|
605
615
|
aria-label={labels.rowNumber}
|
|
606
|
-
className="flex items-end justify-end px-1 py-1 text-
|
|
616
|
+
className="flex items-end justify-end px-1 py-1 text-micro text-[var(--text-placeholder)]"
|
|
607
617
|
>
|
|
608
618
|
#
|
|
609
619
|
</div>
|
|
@@ -617,7 +627,7 @@ function CellGrid({
|
|
|
617
627
|
{column.label}
|
|
618
628
|
</span>
|
|
619
629
|
{column.unit && (
|
|
620
|
-
<span className="block truncate text-
|
|
630
|
+
<span className="block truncate text-micro text-[var(--text-muted)]">
|
|
621
631
|
{column.unit}
|
|
622
632
|
</span>
|
|
623
633
|
)}
|
|
@@ -632,21 +642,25 @@ function CellGrid({
|
|
|
632
642
|
</div>
|
|
633
643
|
{/* Only the rows in the window are mounted — a swept linkage is thousands of
|
|
634
644
|
them across fifteen inputs — each placed at its own offset, so mounting
|
|
635
|
-
one more (the caret's) costs nothing in the arithmetic.
|
|
645
|
+
one more (the caret's) costs nothing in the arithmetic. Since 0.32 a row
|
|
646
|
+
is at least the scaled estimate tall and measured as it renders (§10.9):
|
|
647
|
+
`minHeight`, not `height`, so the type at Extra large is never cut. */}
|
|
636
648
|
<div role="rowgroup" className="relative" style={{ height: totalHeight }}>
|
|
637
649
|
{mounted.map((index) => {
|
|
638
650
|
const row = grid[index];
|
|
639
651
|
return (
|
|
640
652
|
<div
|
|
641
653
|
key={index}
|
|
654
|
+
ref={measureRef}
|
|
655
|
+
{...{ [WINDOWED_ROW_INDEX]: index }}
|
|
642
656
|
role="row"
|
|
643
657
|
aria-rowindex={index + 2}
|
|
644
658
|
className="absolute inset-x-0 grid hover:bg-[var(--bg-hover)]"
|
|
645
|
-
style={{ top: index
|
|
659
|
+
style={{ top: offsetOf(index), minHeight: estimate, gridTemplateColumns: template }}
|
|
646
660
|
>
|
|
647
661
|
<div
|
|
648
662
|
role="rowheader"
|
|
649
|
-
className="flex items-center justify-end px-1 text-
|
|
663
|
+
className="flex items-center justify-end px-1 text-micro tabular-nums text-[var(--text-placeholder)]"
|
|
650
664
|
>
|
|
651
665
|
{rowNumber.format(index + 1)}
|
|
652
666
|
</div>
|
|
@@ -672,9 +686,16 @@ function CellGrid({
|
|
|
672
686
|
aria-invalid={bad || undefined}
|
|
673
687
|
className={cn(
|
|
674
688
|
"block size-full bg-transparent px-2 text-end tabular-nums text-[var(--text-primary)] outline-none",
|
|
689
|
+
// A cell is a field: 16 px on touch, or iOS zooms on focus (§10.1).
|
|
690
|
+
FIELD_TOUCH_TEXT,
|
|
675
691
|
// Arriving selects the text (typing replaces it); editing
|
|
676
692
|
// in place is the plain surface with a caret in it.
|
|
677
|
-
|
|
693
|
+
// The kit's focus frame (§5), inset so the next cell's
|
|
694
|
+
// border does not paint over it. A text input is
|
|
695
|
+
// `:focus-visible` however it was focused.
|
|
696
|
+
"focus:bg-[var(--brand-bg)]",
|
|
697
|
+
FOCUS_RING,
|
|
698
|
+
"focus-visible:ring-inset",
|
|
678
699
|
isCaret && editing && "focus:bg-[var(--bg-surface)]",
|
|
679
700
|
disabled && "text-[var(--text-muted)]",
|
|
680
701
|
bad && cn(FIELD_INVALID, "ring-inset"),
|
|
@@ -723,7 +744,10 @@ function CellGrid({
|
|
|
723
744
|
disabled={!removable}
|
|
724
745
|
tabIndex={at.row === index && at.column === width ? 0 : -1}
|
|
725
746
|
aria-label={labels.removeRow(index + 1)}
|
|
726
|
-
className=
|
|
747
|
+
className={cn(
|
|
748
|
+
"rounded p-1 text-[var(--text-placeholder)] outline-none hover:text-[var(--danger)] disabled:cursor-default disabled:hover:text-[var(--text-placeholder)]",
|
|
749
|
+
FOCUS_RING,
|
|
750
|
+
)}
|
|
727
751
|
onKeyDown={(event) => onCellKeyDown(event, index, width)}
|
|
728
752
|
onFocus={() => {
|
|
729
753
|
if (at.row !== index || at.column !== width) setCaret({ row: index, column: width });
|
|
@@ -749,7 +773,7 @@ function CellGrid({
|
|
|
749
773
|
<div className="flex flex-wrap items-center gap-x-2 gap-y-1 border-t border-[var(--border)] px-2 py-1.5">
|
|
750
774
|
<Button
|
|
751
775
|
variant="ghost"
|
|
752
|
-
|
|
776
|
+
size="sm"
|
|
753
777
|
disabled={disabled}
|
|
754
778
|
onClick={() => {
|
|
755
779
|
onCells([...grid.map(pad), blankRow()]);
|
|
@@ -760,7 +784,8 @@ function CellGrid({
|
|
|
760
784
|
</Button>
|
|
761
785
|
<Button
|
|
762
786
|
variant="ghost"
|
|
763
|
-
|
|
787
|
+
size="sm"
|
|
788
|
+
className="text-[var(--text-muted)]"
|
|
764
789
|
disabled={disabled || !cells.length}
|
|
765
790
|
onClick={() => {
|
|
766
791
|
onCells([]);
|
|
@@ -770,14 +795,14 @@ function CellGrid({
|
|
|
770
795
|
>
|
|
771
796
|
<Eraser aria-hidden className="size-3.5" /> {labels.clear}
|
|
772
797
|
</Button>
|
|
773
|
-
<span className="text-
|
|
798
|
+
<span className="text-caption tabular-nums text-[var(--text-muted)]">
|
|
774
799
|
{/* bdi: an LTR label ("3 points") in an RTL grid would reorder to "points 3". */}
|
|
775
800
|
<bdi>{labels.points(filled.length)}</bdi>
|
|
776
801
|
</span>
|
|
777
802
|
{problems > 0 && (
|
|
778
|
-
<span className="text-
|
|
803
|
+
<span className="text-caption text-[var(--danger)]">{labels.problems(problems)}</span>
|
|
779
804
|
)}
|
|
780
|
-
<span className="ms-auto flex items-center gap-1 text-
|
|
805
|
+
<span className="ms-auto flex items-center gap-1 text-caption text-[var(--text-muted)]">
|
|
781
806
|
<ClipboardPaste aria-hidden className="size-3.5" /> {labels.pasteHint}
|
|
782
807
|
</span>
|
|
783
808
|
</div>
|
|
@@ -843,7 +868,7 @@ function TextView({ columns, cells, onCells, disabled, mark, labels, labelledBy,
|
|
|
843
868
|
onChange={(event) => setDraft(event.target.value)}
|
|
844
869
|
onBlur={commit}
|
|
845
870
|
/>
|
|
846
|
-
<p className="mt-1 px-1 text-
|
|
871
|
+
<p className="mt-1 px-1 text-caption text-[var(--text-muted)]">
|
|
847
872
|
{columns.map((column) => column.label).join(" · ")}
|
|
848
873
|
{" — "}
|
|
849
874
|
<bdi>{labels.points(lines)}</bdi>
|
|
@@ -3,6 +3,7 @@ import type { MouseEvent, ReactElement, ReactNode, Ref } from "react";
|
|
|
3
3
|
import { Check } from "lucide-react";
|
|
4
4
|
import type { LucideIcon } from "lucide-react";
|
|
5
5
|
import { cn } from "../lib/cn";
|
|
6
|
+
import { FOCUS_RING } from "./focus-ring";
|
|
6
7
|
import { useKitLink } from "../i18n/kit-labels";
|
|
7
8
|
import { pickLinkRenderer } from "./text-link";
|
|
8
9
|
|
|
@@ -17,8 +18,7 @@ const MENU_ITEM_ROW =
|
|
|
17
18
|
|
|
18
19
|
/** HoverMenu moves focus onto items with the arrow keys; a pointer user never sees the
|
|
19
20
|
* ring, a keyboard user always does. Inset, because the panel clips its children. */
|
|
20
|
-
const MENU_ITEM_FOCUS =
|
|
21
|
-
"focus-visible:outline-none focus-visible:bg-[var(--bg-hover)] focus-visible:ring-2 focus-visible:ring-inset focus-visible:ring-[var(--brand)]";
|
|
21
|
+
const MENU_ITEM_FOCUS = `${FOCUS_RING} focus-visible:bg-[var(--bg-hover)] focus-visible:ring-inset`;
|
|
22
22
|
|
|
23
23
|
export type MenuItemTone = "default" | "danger";
|
|
24
24
|
|
|
@@ -2,6 +2,7 @@ import { useEffect, useId, useMemo, useRef, useState } from "react";
|
|
|
2
2
|
import type { ComponentPropsWithoutRef, KeyboardEvent, ReactNode } from "react";
|
|
3
3
|
import { ChevronLeft, ChevronRight } from "lucide-react";
|
|
4
4
|
import { cn } from "../lib/cn";
|
|
5
|
+
import { FOCUS_RING, FOCUS_RING_WIDTH } from "./focus-ring";
|
|
5
6
|
import { horizontalStep } from "../lib/direction";
|
|
6
7
|
import { useAnnounce } from "../hooks/use-announce";
|
|
7
8
|
import {
|
|
@@ -576,7 +577,7 @@ export function MiniCalendar({
|
|
|
576
577
|
"grid grid-cols-7 text-center font-medium",
|
|
577
578
|
lg
|
|
578
579
|
? "gap-px text-xs text-[var(--text-muted)]"
|
|
579
|
-
: "text-
|
|
580
|
+
: "text-micro uppercase text-[var(--text-placeholder)]",
|
|
580
581
|
)}
|
|
581
582
|
>
|
|
582
583
|
{weekdayLabels.map((w, i) => (
|
|
@@ -639,7 +640,8 @@ export function MiniCalendar({
|
|
|
639
640
|
onKeyDown={onDayKeyDown}
|
|
640
641
|
className={cn(
|
|
641
642
|
"text-xs tabular-nums text-[var(--text-placeholder)] transition-colors",
|
|
642
|
-
|
|
643
|
+
FOCUS_RING,
|
|
644
|
+
"focus-visible:ring-inset",
|
|
643
645
|
disabled ? "cursor-not-allowed opacity-60" : "hover:bg-[var(--bg-hover)]",
|
|
644
646
|
lg
|
|
645
647
|
? cn("flex w-full min-w-0 items-start bg-[var(--bg-surface-2)] p-1.5", LG_CELL_HEIGHT)
|
|
@@ -730,7 +732,8 @@ export function MiniCalendar({
|
|
|
730
732
|
? cn(
|
|
731
733
|
"flex w-full min-w-0 flex-col items-stretch gap-1 overflow-hidden p-1.5 text-start text-xs transition-colors",
|
|
732
734
|
LG_CELL_HEIGHT,
|
|
733
|
-
|
|
735
|
+
FOCUS_RING,
|
|
736
|
+
"focus-visible:ring-inset",
|
|
734
737
|
disabled
|
|
735
738
|
? "cursor-not-allowed bg-[var(--bg-surface)] text-[var(--text-placeholder)]"
|
|
736
739
|
: isSelected
|
|
@@ -745,7 +748,8 @@ export function MiniCalendar({
|
|
|
745
748
|
// colour flips on the selected days for the reason the numpad's
|
|
746
749
|
// "Done" key does — a --brand ring on a --brand fill is a ring
|
|
747
750
|
// that exists only in the DOM.
|
|
748
|
-
|
|
751
|
+
FOCUS_RING_WIDTH,
|
|
752
|
+
"focus-visible:outline-none focus-visible:ring-inset",
|
|
749
753
|
isStart || isEnd
|
|
750
754
|
? "focus-visible:ring-[var(--brand-contrast)]"
|
|
751
755
|
: "focus-visible:ring-[var(--brand)]",
|