@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
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { Fragment, useCallback, useEffect, useId, useMemo, useRef, useState } from "react";
|
|
1
|
+
import { Fragment, isValidElement, useCallback, useEffect, useId, useMemo, useRef, useState } from "react";
|
|
2
2
|
import type { CSSProperties, ReactNode, TdHTMLAttributes, ThHTMLAttributes } from "react";
|
|
3
3
|
import { createPortal } from "react-dom";
|
|
4
4
|
import {
|
|
@@ -14,7 +14,9 @@ import {
|
|
|
14
14
|
Trash2,
|
|
15
15
|
X,
|
|
16
16
|
} from "lucide-react";
|
|
17
|
-
import { Card, IconButton, Select, Spinner } from "./ui";
|
|
17
|
+
import { Card, FOCUS_RING, IconButton, Select, Spinner } from "./ui";
|
|
18
|
+
import { RowActions, type RowAction } from "./row-actions";
|
|
19
|
+
import { useLargeText } from "../hooks/use-large-text";
|
|
18
20
|
import { cn } from "../lib/cn";
|
|
19
21
|
import {
|
|
20
22
|
defaultFilterState,
|
|
@@ -33,7 +35,7 @@ import { useBodyScrollLock } from "../hooks/use-body-scroll-lock";
|
|
|
33
35
|
import { useOverlayHistory } from "../hooks/use-overlay-history";
|
|
34
36
|
import { FullBleedDialog } from "./full-bleed-dialog";
|
|
35
37
|
import { Popover } from "./popover";
|
|
36
|
-
import {
|
|
38
|
+
import { usePhoneLayout } from "../hooks/use-breakpoint";
|
|
37
39
|
import { useAnnounce } from "../hooks/use-announce";
|
|
38
40
|
import { DEFAULT_DATA_TABLE_LABELS, resolveDataTableLabels, type DataTableLabels } from "./data-table-labels";
|
|
39
41
|
import { useKitLabelOverrides, useKitLocale } from "../i18n/kit-labels";
|
|
@@ -366,6 +368,27 @@ export interface DataTableProps<T> {
|
|
|
366
368
|
* of unfolding it inline (feedback #204). Desktop always uses inline expansion.
|
|
367
369
|
*/
|
|
368
370
|
mobileExpandAsDialog?: boolean;
|
|
371
|
+
/**
|
|
372
|
+
* Show the `mobileHidden` columns in the OPENED row on the phone layout — inline
|
|
373
|
+
* under the card, or in the `mobileExpandAsDialog` dialog — so a column dropped from
|
|
374
|
+
* the card to keep it short is not lost (0.32, docs/text-size-harmonization.md §4:
|
|
375
|
+
* "a new `mobileDetailsInRow` puts the `mobileHidden` columns into the opened row, so
|
|
376
|
+
* nothing is lost"). At Large a card holds fewer facts per screen, and dropping one
|
|
377
|
+
* from the card must not drop it from the phone.
|
|
378
|
+
*
|
|
379
|
+
* Each column is a label above its value, BEFORE what `expandedRow` renders: the
|
|
380
|
+
* row's own facts first, then the app's detail or editor. A row opens as it always
|
|
381
|
+
* does (`onRowClick` toggling `isExpanded`); with this set it may open without an
|
|
382
|
+
* `expandedRow` at all. `rowActions`' column is one of them — the actions, which the
|
|
383
|
+
* card otherwise offers only as swipes, reachable by a tap. Desktop is unaffected.
|
|
384
|
+
*/
|
|
385
|
+
mobileDetailsInRow?: boolean;
|
|
386
|
+
/**
|
|
387
|
+
* The row's name, as plain text — for the "⋯" menu its `rowActions` collapse into at
|
|
388
|
+
* Large ("Actions for Ada Example", §10.8). Without it every row's menu button is
|
|
389
|
+
* named "Actions", which a screen reader cannot tell apart down the list.
|
|
390
|
+
*/
|
|
391
|
+
rowName?: (row: T) => string | undefined;
|
|
369
392
|
/**
|
|
370
393
|
* The phone row dialog's `backCloses` ({@link FullBleedDialog}): whether it pushes
|
|
371
394
|
* its own history entry so Back dismisses it. On by default — right for a row whose
|
|
@@ -526,7 +549,10 @@ export interface DataTableProps<T> {
|
|
|
526
549
|
/**
|
|
527
550
|
* Per-row actions: an actions column of icon buttons at the row's end on desktop,
|
|
528
551
|
* and the same actions as swipe actions on a phone card (where the column is not
|
|
529
|
-
* shown
|
|
552
|
+
* shown; with `mobileDetailsInRow` also as buttons in the opened row). At Large and
|
|
553
|
+
* Extra large two or more collapse into one "⋯" menu with each action's words
|
|
554
|
+
* (0.32, §10.8, `RowActions`) — name the rows with `rowName` so each menu button is
|
|
555
|
+
* "Actions for …". kastlan's `ResourceListPage` appended this column by hand to every CRUD
|
|
530
556
|
* list — the edit pencil, the delete bin, a `useConfirm` before the delete, and a
|
|
531
557
|
* `stopPropagation` on each so a press did not also open the row.
|
|
532
558
|
*
|
|
@@ -637,6 +663,19 @@ async function runRowAction<T>(action: DataTableRowAction<T>, row: T): Promise<v
|
|
|
637
663
|
action.onAction(row);
|
|
638
664
|
}
|
|
639
665
|
|
|
666
|
+
/** A resolved row action as {@link RowActions} takes it. Its `icon` is any node; a
|
|
667
|
+
* non-element one (a string glyph) is wrapped, since RowAction wants an element. */
|
|
668
|
+
function toRowAction<T>(a: ResolvedRowAction<T>, row: T): RowAction {
|
|
669
|
+
return {
|
|
670
|
+
key: a.key,
|
|
671
|
+
label: a.label,
|
|
672
|
+
icon: isValidElement(a.icon) ? a.icon : a.icon != null && a.icon !== false ? <>{a.icon}</> : undefined,
|
|
673
|
+
tone: a.tone,
|
|
674
|
+
disabledReason: a.action.disabledReason?.(row),
|
|
675
|
+
onSelect: () => void runRowAction(a.action, row),
|
|
676
|
+
};
|
|
677
|
+
}
|
|
678
|
+
|
|
640
679
|
/** See {@link DataTableProps.chrome}. */
|
|
641
680
|
export type DataTableChrome = "full" | "minimal";
|
|
642
681
|
|
|
@@ -734,6 +773,46 @@ function columnLabel<T>(col: DataTableColumn<T>, labels?: DataTableLabels): stri
|
|
|
734
773
|
return col.headerText ?? (typeof col.header === "string" ? col.header : col.key);
|
|
735
774
|
}
|
|
736
775
|
|
|
776
|
+
// ---------- Phone card at Large (0.32) ----------
|
|
777
|
+
|
|
778
|
+
/**
|
|
779
|
+
* §4 "nothing truncates" in a phone card at Large and Extra large: a cell's own
|
|
780
|
+
* `truncate` (a kit cell, a chip, the app's span) wraps instead — and breaks inside a
|
|
781
|
+
* word too long for the card rather than running out of it. A descendant rule, so it
|
|
782
|
+
* reaches the cells without the table knowing what they render; `large:`, so Normal
|
|
783
|
+
* keeps every ellipsis it had.
|
|
784
|
+
*/
|
|
785
|
+
const CARD_NO_TRUNCATE =
|
|
786
|
+
"large:[&_.truncate]:whitespace-normal large:[&_.truncate]:[overflow-wrap:anywhere]";
|
|
787
|
+
|
|
788
|
+
/**
|
|
789
|
+
* Columns as label-above-value pairs: the phone card's fields at Large (§4), and the
|
|
790
|
+
* opened row's `mobileDetailsInRow` at every size. Each pair is a `<div>` in the
|
|
791
|
+
* `<dl>` — the grouping HTML allows — so a pair keeps together and the gap falls
|
|
792
|
+
* BETWEEN facts rather than between a label and its own value. `relative` holds a
|
|
793
|
+
* header's `sr-only` text (an actions column's), as every kit container must.
|
|
794
|
+
*/
|
|
795
|
+
function StackedFields<T>({ columns, row, compact }: { columns: DataTableColumn<T>[]; row: T; compact: boolean }) {
|
|
796
|
+
return (
|
|
797
|
+
<dl
|
|
798
|
+
data-card-fields="stacked"
|
|
799
|
+
className={cn("relative flex min-w-0 flex-col", compact ? "gap-1.5 text-xs" : "gap-2.5 text-sm", CARD_NO_TRUNCATE)}
|
|
800
|
+
>
|
|
801
|
+
{columns.map((col) => (
|
|
802
|
+
<div key={col.key} className="min-w-0">
|
|
803
|
+
<dt className="text-xs uppercase tracking-wide text-[var(--text-muted)]">{col.header}</dt>
|
|
804
|
+
<dd
|
|
805
|
+
{...dataAttrsOf(col.cellProps?.(row))}
|
|
806
|
+
className="mt-0.5 min-w-0 break-words text-[var(--text-secondary)]"
|
|
807
|
+
>
|
|
808
|
+
{col.cell(row)}
|
|
809
|
+
</dd>
|
|
810
|
+
</div>
|
|
811
|
+
))}
|
|
812
|
+
</dl>
|
|
813
|
+
);
|
|
814
|
+
}
|
|
815
|
+
|
|
737
816
|
// ---------- Phone sort control (keksdose K10) ----------
|
|
738
817
|
|
|
739
818
|
/**
|
|
@@ -813,7 +892,9 @@ function MobileSort<T>({
|
|
|
813
892
|
<div
|
|
814
893
|
data-table-mobile-sort=""
|
|
815
894
|
className={cn(
|
|
816
|
-
|
|
895
|
+
// At Large the direction button shows its words (IconButton's label, §4); the
|
|
896
|
+
// row wraps so the select keeps a usable width on a 240 px card.
|
|
897
|
+
"flex flex-wrap items-center gap-2 border-b border-[var(--border)]",
|
|
817
898
|
compact ? "px-3 py-1.5" : "px-4 py-2",
|
|
818
899
|
)}
|
|
819
900
|
>
|
|
@@ -823,7 +904,7 @@ function MobileSort<T>({
|
|
|
823
904
|
<Select
|
|
824
905
|
id={selectId}
|
|
825
906
|
size={compact ? "sm" : "md"}
|
|
826
|
-
className="min-w-0 flex-1"
|
|
907
|
+
className="min-w-0 flex-1 large:basis-40"
|
|
827
908
|
value={primary?.key ?? ""}
|
|
828
909
|
onChange={(e) => onPick(e.target.value || null)}
|
|
829
910
|
>
|
|
@@ -1014,6 +1095,8 @@ export function DataTable<T>({
|
|
|
1014
1095
|
locale: localeProp,
|
|
1015
1096
|
storageKeyPrefix = DEFAULT_PERSIST_PREFIX,
|
|
1016
1097
|
mobileExpandAsDialog = false,
|
|
1098
|
+
mobileDetailsInRow = false,
|
|
1099
|
+
rowName,
|
|
1017
1100
|
mobileDialogBackCloses = true,
|
|
1018
1101
|
mobileGroupBy,
|
|
1019
1102
|
mobileGroupLabel,
|
|
@@ -1085,24 +1168,19 @@ export function DataTable<T>({
|
|
|
1085
1168
|
{
|
|
1086
1169
|
key: ROW_ACTIONS_KEY,
|
|
1087
1170
|
header: <span className="sr-only">{labels.actions}</span>,
|
|
1171
|
+
// Through RowActions (0.32, §10.8): the icons inline at Normal, one "⋯"
|
|
1172
|
+
// menu at Large once there are two — every label at once does not fit a
|
|
1173
|
+
// row. Each control stops its own click: the row's handler already skips
|
|
1174
|
+
// its controls, and this is for the caller who wraps the table in a
|
|
1175
|
+
// clickable element of their own.
|
|
1088
1176
|
cell: (row) => (
|
|
1089
|
-
<
|
|
1090
|
-
{rowActionsFor(row).map((a) => (
|
|
1091
|
-
|
|
1092
|
-
|
|
1093
|
-
|
|
1094
|
-
|
|
1095
|
-
|
|
1096
|
-
disabledReason={a.action.disabledReason?.(row)}
|
|
1097
|
-
// The row's click handler already skips its own controls; this is for
|
|
1098
|
-
// the caller who wraps the table in a clickable element of their own.
|
|
1099
|
-
stopPropagation
|
|
1100
|
-
onClick={() => void runRowAction(a.action, row)}
|
|
1101
|
-
>
|
|
1102
|
-
{a.icon}
|
|
1103
|
-
</IconButton>
|
|
1104
|
-
))}
|
|
1105
|
-
</div>
|
|
1177
|
+
<RowActions
|
|
1178
|
+
actions={rowActionsFor(row).map((a) => toRowAction(a, row))}
|
|
1179
|
+
name={rowName?.(row)}
|
|
1180
|
+
size={density === "compact" ? "2xs" : "xs"}
|
|
1181
|
+
labels={{ actions: labels.actions }}
|
|
1182
|
+
className="justify-end"
|
|
1183
|
+
/>
|
|
1106
1184
|
),
|
|
1107
1185
|
className: "w-px whitespace-nowrap text-end",
|
|
1108
1186
|
headClassName: "w-px",
|
|
@@ -1112,7 +1190,7 @@ export function DataTable<T>({
|
|
|
1112
1190
|
},
|
|
1113
1191
|
]
|
|
1114
1192
|
: columnsProp,
|
|
1115
|
-
[columnsProp, rowActions, rowActionsFor, labels.actions, density],
|
|
1193
|
+
[columnsProp, rowActions, rowActionsFor, rowName, labels.actions, density],
|
|
1116
1194
|
);
|
|
1117
1195
|
const swipesFromActions = (row: T): MobileSwipeActions | null => {
|
|
1118
1196
|
const swipes = rowActionsFor(row).filter((a) => a.swipe && !a.action.disabledReason?.(row));
|
|
@@ -1575,10 +1653,15 @@ export function DataTable<T>({
|
|
|
1575
1653
|
const columnsCountLabel = rowActions
|
|
1576
1654
|
? labels.columnsCount(visibleCount - 1, totalCount - 1)
|
|
1577
1655
|
: labels.columnsCount(visibleCount, totalCount);
|
|
1578
|
-
// Match
|
|
1579
|
-
// list — never both — so we don't double up DOM nodes that screen readers and
|
|
1580
|
-
// integration tests would have to disambiguate.
|
|
1581
|
-
|
|
1656
|
+
// Match the `md:` breakpoint at the text size in force: we render either the table or
|
|
1657
|
+
// the card list — never both — so we don't double up DOM nodes that screen readers and
|
|
1658
|
+
// integration tests would have to disambiguate. `usePhoneLayout()` itself, not its twin
|
|
1659
|
+
// `useBreakpoint("md")`: the same query an app's own phone checks ask (keksdose's
|
|
1660
|
+
// sticky editor footer), so the card list and the full-screen row dialog switch with
|
|
1661
|
+
// them and never a frame apart (§10.4 "usePhoneLayout() is the single answer"; 0.32.1,
|
|
1662
|
+
// keksdose's 0.32 report, where `md` and `max-md` both missed at 767.5 px). Without
|
|
1663
|
+
// `matchMedia` (SSR, jsdom) it is the table, as before.
|
|
1664
|
+
const isMdUp = !usePhoneLayout();
|
|
1582
1665
|
// `edgeFade` (0.25) on the desktop scroller; the phone list never scrolls sideways.
|
|
1583
1666
|
const desktopScroller = useRef<HTMLDivElement | null>(null);
|
|
1584
1667
|
const edgeFadeProps = useEdgeFade(desktopScroller, edgeFade && isMdUp);
|
|
@@ -1592,6 +1675,26 @@ export function DataTable<T>({
|
|
|
1592
1675
|
const mobilePrimaryCol =
|
|
1593
1676
|
mobileColumns.find((c) => c.mobilePrimary) ?? mobileColumns[0] ?? null;
|
|
1594
1677
|
const mobileSecondaryColumns = mobileColumns.filter((c) => c !== mobilePrimaryCol);
|
|
1678
|
+
// The columns the card leaves out, for the opened row (`mobileDetailsInRow`).
|
|
1679
|
+
const mobileDetailColumns = mobileDetailsInRow ? visibleColumns.filter((c) => c.mobileHidden) : [];
|
|
1680
|
+
// Large and Extra large (§4 "DataTable phone card"): the card's labels go ABOVE their
|
|
1681
|
+
// values, nothing in it truncates, and the rows get more room. Most of it is a
|
|
1682
|
+
// `large:` class; the label/value grid needs a different STRUCTURE (each pair in a
|
|
1683
|
+
// box of its own), which a class cannot write.
|
|
1684
|
+
const large = useLargeText();
|
|
1685
|
+
// What an opened phone row shows: the card's left-out columns first (when asked
|
|
1686
|
+
// for), then the app's own `expandedRow`. Desktop keeps `expandedRow` alone.
|
|
1687
|
+
const opensRow = !!expandedRow || mobileDetailColumns.length > 0;
|
|
1688
|
+
const openedRowContent = (row: T): ReactNode => {
|
|
1689
|
+
const detail = expandedRow?.(row) ?? null;
|
|
1690
|
+
if (mobileDetailColumns.length === 0) return detail;
|
|
1691
|
+
return (
|
|
1692
|
+
<div data-row-details="" className={cn("flex flex-col", compact ? "gap-2" : "gap-3")}>
|
|
1693
|
+
<StackedFields columns={mobileDetailColumns} row={row} compact={compact} />
|
|
1694
|
+
{detail}
|
|
1695
|
+
</div>
|
|
1696
|
+
);
|
|
1697
|
+
};
|
|
1595
1698
|
// The phone card IS the anchor, so unlike the desktop table there is no other
|
|
1596
1699
|
// cell to move the row link into: if any cell the card renders owns a link, the
|
|
1597
1700
|
// card itself cannot be one (feedback #451 — same nesting rule as `linkColumn`
|
|
@@ -1679,7 +1782,7 @@ export function DataTable<T>({
|
|
|
1679
1782
|
// When dialog-mode is on, the expanded row's detail goes into a bottom-sheet
|
|
1680
1783
|
// modal instead of unfolding inline. Only one row is ever expanded at a time.
|
|
1681
1784
|
const mobileDialogRow = mobileExpandAsDialog && !isMdUp ? mobileSlice.find((r) => isExpanded?.(r)) : undefined;
|
|
1682
|
-
const mobileDialogContent = mobileDialogRow ?
|
|
1785
|
+
const mobileDialogContent = mobileDialogRow ? openedRowContent(mobileDialogRow) : null;
|
|
1683
1786
|
// The full-screen row dialog. Its panel, header, scroll lock and Back handling all
|
|
1684
1787
|
// live in {@link FullBleedDialog} now — this was the only copy of that shell until
|
|
1685
1788
|
// the transactions create card needed the same one (Keksdose live #307's follow-up),
|
|
@@ -1694,7 +1797,7 @@ export function DataTable<T>({
|
|
|
1694
1797
|
// share identical row markup.
|
|
1695
1798
|
const renderMobileRow = (row: T) => {
|
|
1696
1799
|
const expanded = isExpanded?.(row) ?? false;
|
|
1697
|
-
const expansion = expanded ?
|
|
1800
|
+
const expansion = expanded ? openedRowContent(row) : null;
|
|
1698
1801
|
const tint = rowClassName?.(row);
|
|
1699
1802
|
// Use div+role="button" rather than a real <button> so cells that
|
|
1700
1803
|
// contain their own interactive controls (status toggles, action
|
|
@@ -1706,7 +1809,7 @@ export function DataTable<T>({
|
|
|
1706
1809
|
// values are not editable". A chevron is the affordance every list on a phone
|
|
1707
1810
|
// uses for exactly this, and it points the way the row actually opens: right into
|
|
1708
1811
|
// a sheet, or down into an inline panel that flips it when expanded.
|
|
1709
|
-
const opensDetail = interactive &&
|
|
1812
|
+
const opensDetail = interactive && opensRow;
|
|
1710
1813
|
const swipeActions = swipeActionsFor?.(row);
|
|
1711
1814
|
const swipe = swipeActions ? physicalSwipe(swipeActions, mobileDir) : null;
|
|
1712
1815
|
// An expanded row never swipes: the editor below it owns the horizontal space,
|
|
@@ -1715,7 +1818,8 @@ export function DataTable<T>({
|
|
|
1715
1818
|
const href = mobileCardLinkable ? rowHref?.(row) : undefined;
|
|
1716
1819
|
const cardClass = cn(
|
|
1717
1820
|
"w-full text-start flex items-center",
|
|
1718
|
-
|
|
1821
|
+
// §4: more room per row at Large — a taller row is a bigger tap target too.
|
|
1822
|
+
compact ? "px-3 py-2 gap-2 text-sm large:py-3" : "px-4 py-3 gap-3 large:py-4",
|
|
1719
1823
|
// Live #320's other half: the card acknowledges the touch before the sheet
|
|
1720
1824
|
// arrives. On a cold route the data can take a beat, and an unacknowledged tap
|
|
1721
1825
|
// reads as "did that register?" — which is most of what "abrupt" means here.
|
|
@@ -1731,8 +1835,7 @@ export function DataTable<T>({
|
|
|
1731
1835
|
// AppShell main's `overflow-x-clip` — so the frame went missing on one side. A press
|
|
1732
1836
|
// keeps the fill and the squeeze above; an outline on every tap of a long list would
|
|
1733
1837
|
// be louder than the acknowledgement it replaces.
|
|
1734
|
-
interactive &&
|
|
1735
|
-
"[-webkit-tap-highlight-color:transparent] focus-visible:outline-2 focus-visible:-outline-offset-2 focus-visible:outline-[var(--brand)]",
|
|
1838
|
+
interactive && cn("[-webkit-tap-highlight-color:transparent] focus-visible:ring-inset", FOCUS_RING),
|
|
1736
1839
|
);
|
|
1737
1840
|
// The card's content is written once and worn by either tag below. Note that
|
|
1738
1841
|
// the primary cell is rendered RAW here, never through `linkColumn` — the card
|
|
@@ -1743,18 +1846,31 @@ export function DataTable<T>({
|
|
|
1743
1846
|
<>
|
|
1744
1847
|
{/* The card's own content keeps the column it always had; the chevron sits
|
|
1745
1848
|
beside it rather than inside, so a caller's `mobileCard` is untouched. */}
|
|
1746
|
-
<div
|
|
1849
|
+
<div
|
|
1850
|
+
className={cn(
|
|
1851
|
+
"flex min-w-0 flex-1 flex-col",
|
|
1852
|
+
compact ? "gap-1 large:gap-2" : "gap-2 large:gap-3",
|
|
1853
|
+
// §4 "nothing truncates": at Large a cell's own `truncate` wraps instead —
|
|
1854
|
+
// the reader who chose bigger type is the one an ellipsis fails. A caller's
|
|
1855
|
+
// `mobileCard` is its own layout and keeps what it chose.
|
|
1856
|
+
!mobileCard && CARD_NO_TRUNCATE,
|
|
1857
|
+
)}
|
|
1858
|
+
>
|
|
1747
1859
|
{mobileCard ? (
|
|
1748
1860
|
mobileCard(row)
|
|
1749
1861
|
) : (
|
|
1750
1862
|
<>
|
|
1751
1863
|
{/* Only the `data-*` half of `cellProps` — see its note. */}
|
|
1752
1864
|
{mobilePrimaryCol && (
|
|
1753
|
-
<div {...dataAttrsOf(mobilePrimaryCol.cellProps?.(row))} className="font-medium">
|
|
1865
|
+
<div {...dataAttrsOf(mobilePrimaryCol.cellProps?.(row))} className="min-w-0 break-words font-medium">
|
|
1754
1866
|
{mobilePrimaryCol.cell(row)}
|
|
1755
1867
|
</div>
|
|
1756
1868
|
)}
|
|
1757
|
-
{mobileSecondaryColumns.length > 0 && (
|
|
1869
|
+
{mobileSecondaryColumns.length > 0 && large ? (
|
|
1870
|
+
// §4: each label ABOVE its value at Large. Side by side, a label column
|
|
1871
|
+
// sized to the widest label leaves a value a sliver of a 240 px card.
|
|
1872
|
+
<StackedFields columns={mobileSecondaryColumns} row={row} compact={compact} />
|
|
1873
|
+
) : mobileSecondaryColumns.length > 0 && (
|
|
1758
1874
|
<dl
|
|
1759
1875
|
className={cn(
|
|
1760
1876
|
"grid grid-cols-[auto_1fr] gap-x-3",
|
|
@@ -1807,7 +1923,7 @@ export function DataTable<T>({
|
|
|
1807
1923
|
<RowLink
|
|
1808
1924
|
href={href}
|
|
1809
1925
|
onActivate={() => onRowClick!(row)}
|
|
1810
|
-
aria-expanded={
|
|
1926
|
+
aria-expanded={opensRow ? expanded : undefined}
|
|
1811
1927
|
className={cardClass}
|
|
1812
1928
|
// Enter already activates a link natively, and that routes through
|
|
1813
1929
|
// RowLink's own onClick — handling it here too would open the row twice.
|
|
@@ -1848,7 +1964,7 @@ export function DataTable<T>({
|
|
|
1848
1964
|
}
|
|
1849
1965
|
: undefined
|
|
1850
1966
|
}
|
|
1851
|
-
aria-expanded={
|
|
1967
|
+
aria-expanded={opensRow ? expanded : undefined}
|
|
1852
1968
|
className={cardClass}
|
|
1853
1969
|
>
|
|
1854
1970
|
{cardInner}
|
|
@@ -2238,7 +2354,7 @@ export function DataTable<T>({
|
|
|
2238
2354
|
)}
|
|
2239
2355
|
{/* Priority badge, only meaningful with 2+ sort keys */}
|
|
2240
2356
|
{active && sorts.length > 1 && (
|
|
2241
|
-
<span className="text-
|
|
2357
|
+
<span className="text-micro font-semibold leading-none text-brand">
|
|
2242
2358
|
{sortIdx + 1}
|
|
2243
2359
|
</span>
|
|
2244
2360
|
)}
|
|
@@ -2246,7 +2362,9 @@ export function DataTable<T>({
|
|
|
2246
2362
|
</Tooltip>
|
|
2247
2363
|
{filter && (
|
|
2248
2364
|
<Popover
|
|
2249
|
-
|
|
2365
|
+
// 420 px at Normal, in rem so the calendar grows with its
|
|
2366
|
+
// text (§3.2); Popover caps it at the viewport.
|
|
2367
|
+
width={filter.type === "date" ? "26.25rem" : undefined}
|
|
2250
2368
|
// The panel is the column's filter, and says so. Unnamed it
|
|
2251
2369
|
// was announced as the kit-wide fallback, "Popover".
|
|
2252
2370
|
labels={{ panel: labels.filter }}
|
|
@@ -2364,8 +2482,11 @@ export function DataTable<T>({
|
|
|
2364
2482
|
className={cn(
|
|
2365
2483
|
"border-t border-[var(--border)]",
|
|
2366
2484
|
rowInteractive && "cursor-pointer hover:bg-[var(--bg-hover)]",
|
|
2485
|
+
// The kit's focus frame width (§5, `--focus-ring-width`), drawn as an
|
|
2486
|
+
// OUTLINE rather than FOCUS_RING's box-shadow: a shadow on a `<tr>`
|
|
2487
|
+
// is not painted by every engine, an outline is.
|
|
2367
2488
|
rowsFocusable &&
|
|
2368
|
-
"focus-visible:bg-[var(--bg-hover)] focus-visible:outline-
|
|
2489
|
+
"focus-visible:bg-[var(--bg-hover)] focus-visible:outline-[length:var(--focus-ring-width)] focus-visible:-outline-offset-2 focus-visible:outline-[var(--brand)]",
|
|
2369
2490
|
rowClassName?.(row),
|
|
2370
2491
|
)}
|
|
2371
2492
|
onClick={
|
|
@@ -2787,7 +2908,7 @@ function MobileFilters<T>({
|
|
|
2787
2908
|
<Filter className="size-4" />
|
|
2788
2909
|
<span>{labels.filters}</span>
|
|
2789
2910
|
{activeCount > 0 && (
|
|
2790
|
-
<span className="inline-flex min-w-4 items-center justify-center rounded-full bg-[var(--info-bg)] px-1 text-
|
|
2911
|
+
<span className="inline-flex min-w-4 items-center justify-center rounded-full bg-[var(--info-bg)] px-1 text-caption font-semibold text-[var(--info)]">
|
|
2791
2912
|
{activeCount}
|
|
2792
2913
|
</span>
|
|
2793
2914
|
)}
|
|
@@ -15,10 +15,11 @@ import {
|
|
|
15
15
|
} from "../i18n/kit-labels";
|
|
16
16
|
import { splitTriggerAria } from "./trigger-aria";
|
|
17
17
|
import type { TriggerAria } from "./trigger-aria";
|
|
18
|
-
import { Button, FIELD_BASE, FIELD_TRIGGER, FIELD_FLOATING_PAD, FIELD_INVALID
|
|
18
|
+
import { Button, FIELD_BASE, FIELD_TRIGGER, FIELD_FLOATING_PAD, FIELD_INVALID } from "./ui";
|
|
19
|
+
import { FOCUS_RING_WIDTH } from "./focus-ring";
|
|
19
20
|
import { FieldBox, FieldLabelLine, useFieldMessages } from "./field-parts";
|
|
20
21
|
import { FullBleedDialog } from "./full-bleed-dialog";
|
|
21
|
-
import {
|
|
22
|
+
import { usePhoneLayout, type RemLength } from "../hooks/use-breakpoint";
|
|
22
23
|
import { DEFAULT_MINI_CALENDAR_LABELS, MiniCalendar, type MiniCalendarProps } from "./mini-calendar";
|
|
23
24
|
import { DEFAULT_MONTH_PICKER_LABELS } from "./month-picker";
|
|
24
25
|
import { Popover } from "./popover";
|
|
@@ -205,6 +206,16 @@ function CustomTrigger({
|
|
|
205
206
|
return render(attrs, valueId);
|
|
206
207
|
}
|
|
207
208
|
|
|
209
|
+
/**
|
|
210
|
+
* The trigger's value wraps instead of truncating at Large and Extra large (0.32.1, the
|
|
211
|
+
* 360 px Extra-large sweep; docs/text-size-harmonization.md §4 "nothing truncates"). A
|
|
212
|
+
* range ("01/09/2026 – 30/09/2026") is 312 px at 150 %, and on a 360 px phone it read
|
|
213
|
+
* "01/09/2026 – 30/…" — its end, the half a reader needs, was the half cut off. It breaks
|
|
214
|
+
* at its spaces; a single date breaks only where it cannot fit at all. A `large:` class,
|
|
215
|
+
* so Normal keeps its one-line field.
|
|
216
|
+
*/
|
|
217
|
+
const VALUE_WRAP_AT_LARGE = "large:whitespace-normal large:break-words";
|
|
218
|
+
|
|
208
219
|
/**
|
|
209
220
|
* The field-shaped button that opens the calendar.
|
|
210
221
|
*
|
|
@@ -319,7 +330,7 @@ function DateFieldTrigger({
|
|
|
319
330
|
|
|
320
331
|
return (
|
|
321
332
|
<button {...attrs}>
|
|
322
|
-
<span id={valueId} className={cn("truncate", !hasValue && "text-[var(--text-placeholder)]")}>
|
|
333
|
+
<span id={valueId} className={cn("truncate", VALUE_WRAP_AT_LARGE, !hasValue && "text-[var(--text-placeholder)]")}>
|
|
323
334
|
{/* `|| " "` (a NON-BREAKING space) — triggerText is "" when there is no value and no
|
|
324
335
|
placeholder was passed. An empty span has no line box, so the
|
|
325
336
|
trigger collapses to its padding and sits shorter than every
|
|
@@ -395,11 +406,12 @@ function DateField({
|
|
|
395
406
|
panelLabel: string;
|
|
396
407
|
invalid?: boolean;
|
|
397
408
|
className?: string;
|
|
398
|
-
/** Popover panel width; omit for the default (a bare calendar).
|
|
399
|
-
|
|
409
|
+
/** Popover panel width; omit for the default (a bare calendar). In rem so it grows
|
|
410
|
+
* with the text size, like the Popover's own default (§3.2). */
|
|
411
|
+
width?: number | RemLength;
|
|
400
412
|
onClear: () => void;
|
|
401
413
|
/** Open as a full-screen sheet instead of the popover — the picker decides when
|
|
402
|
-
* (
|
|
414
|
+
* (in the phone layout, `usePhoneLayout()`). */
|
|
403
415
|
sheet?: boolean;
|
|
404
416
|
/** The sheet's `FullBleedDialog backCloses`. */
|
|
405
417
|
sheetBackCloses?: boolean;
|
|
@@ -556,6 +568,23 @@ function DateField({
|
|
|
556
568
|
);
|
|
557
569
|
}
|
|
558
570
|
|
|
571
|
+
/**
|
|
572
|
+
* The ‹ date › (today) row on a phone at Large and Extra large (0.32.1, the 360 px
|
|
573
|
+
* Extra-large sweep; docs/text-size-harmonization.md §4): the field takes the first line
|
|
574
|
+
* on its own, whole and with all four corners, and the buttons share the line under it
|
|
575
|
+
* as one joined strip. Three 2.5rem buttons are 180 px at 150 %, and on a 360 px phone
|
|
576
|
+
* they left the field 84 px — "Book… 0" for "Booking date 07/09/2026" — where a 360 px
|
|
577
|
+
* row would hold the date only by cutting it. `large:max-sm:`, the scaled phone width,
|
|
578
|
+
* so a tablet or a desktop at Large keeps the one row, and Normal is unchanged.
|
|
579
|
+
*/
|
|
580
|
+
const STEP_ROW_STACK_AT_LARGE = cn(
|
|
581
|
+
"large:max-sm:flex-wrap large:max-sm:gap-y-2",
|
|
582
|
+
"large:max-sm:[&>[data-slot=date-step-field]]:order-first large:max-sm:[&>[data-slot=date-step-field]]:basis-full",
|
|
583
|
+
"large:max-sm:[&>[data-slot=date-step-field]]:ms-0 large:max-sm:[&_[role=combobox]]:rounded-md",
|
|
584
|
+
// The buttons (each in its tooltip's wrapper) share the line under the field.
|
|
585
|
+
"large:max-sm:[&>span]:flex-1 large:max-sm:[&>span>button]:w-full",
|
|
586
|
+
);
|
|
587
|
+
|
|
559
588
|
/** One ‹ / › day-step button, sized to sit flush beside the field. */
|
|
560
589
|
function StepButton({
|
|
561
590
|
icon: Icon,
|
|
@@ -943,7 +972,8 @@ function JumpCalendar({
|
|
|
943
972
|
// 44px rows: the touch-target size, and four of them stand as tall
|
|
944
973
|
// as a month of days, so the panel does not jump as the views swap.
|
|
945
974
|
"h-11 rounded px-1 text-sm tabular-nums transition-colors",
|
|
946
|
-
|
|
975
|
+
FOCUS_RING_WIDTH,
|
|
976
|
+
"focus-visible:outline-none focus-visible:ring-inset",
|
|
947
977
|
// A --brand ring on a --brand fill exists only in the DOM.
|
|
948
978
|
end && !disabled ? "focus-visible:ring-[var(--brand-contrast)]" : "focus-visible:ring-[var(--brand)]",
|
|
949
979
|
disabled
|
|
@@ -1102,6 +1132,9 @@ export function DatePicker(props: DatePickerProps) {
|
|
|
1102
1132
|
disabled={disabled}
|
|
1103
1133
|
invalid={messages.isInvalid}
|
|
1104
1134
|
className={step ? "min-w-0 flex-1" : className}
|
|
1135
|
+
// Named for STEP_ROW_STACK_AT_LARGE; only in the row, so a caller's own
|
|
1136
|
+
// `data-slot` on a bare field is left alone.
|
|
1137
|
+
{...(wrapped ? { "data-slot": "date-step-field" } : {})}
|
|
1105
1138
|
hasValue={Boolean(value)}
|
|
1106
1139
|
triggerText={value ? render(value) : (placeholder ?? "")}
|
|
1107
1140
|
onClear={() => onChange("")}
|
|
@@ -1170,6 +1203,7 @@ export function DatePicker(props: DatePickerProps) {
|
|
|
1170
1203
|
// the trigger, which raising the trigger alone covered. Hover raises nothing: it
|
|
1171
1204
|
// changes no border, and would let a hovered › cover a focused field's edge.
|
|
1172
1205
|
"[&>*:focus-within]:z-20 [&>*:active]:z-20 [&>*:has([aria-invalid=true])]:z-10",
|
|
1206
|
+
STEP_ROW_STACK_AT_LARGE,
|
|
1173
1207
|
className,
|
|
1174
1208
|
)}
|
|
1175
1209
|
>
|
|
@@ -1288,7 +1322,7 @@ export interface DateRangePickerProps extends DatePickerBaseProps {
|
|
|
1288
1322
|
*/
|
|
1289
1323
|
renderTrigger?: (props: DateRangeTriggerRenderProps) => ReactNode;
|
|
1290
1324
|
/**
|
|
1291
|
-
*
|
|
1325
|
+
* In the phone layout (`usePhoneLayout()`) the panel opens as a full-screen sheet (`FullBleedDialog`)
|
|
1292
1326
|
* with presets in a grid above the calendar and Apply pinned in the footer, instead
|
|
1293
1327
|
* of the 440px popover that hung off a 360px screen (keksdose's report range field,
|
|
1294
1328
|
* which hand-rolled exactly this). This is its `backCloses`: on by default, so Back
|
|
@@ -1615,7 +1649,7 @@ export function DateRangePicker(props: DateRangePickerProps) {
|
|
|
1615
1649
|
: `${a}${separator}…`
|
|
1616
1650
|
: (placeholder ?? "");
|
|
1617
1651
|
const hasPresets = Boolean(presets && presets.length > 0);
|
|
1618
|
-
const sheet =
|
|
1652
|
+
const sheet = usePhoneLayout();
|
|
1619
1653
|
const commitRange = (f: string, t: string, presetId: string | undefined) => {
|
|
1620
1654
|
setOwnPreset(presetId);
|
|
1621
1655
|
// Two arguments when no preset is involved — exactly the 0.7 call, so a caller's
|
|
@@ -1635,7 +1669,7 @@ export function DateRangePicker(props: DateRangePickerProps) {
|
|
|
1635
1669
|
disabled={disabled}
|
|
1636
1670
|
invalid={messages.isInvalid}
|
|
1637
1671
|
// Widen so the preset column sits beside the calendar (default otherwise).
|
|
1638
|
-
width={hasPresets ?
|
|
1672
|
+
width={hasPresets ? "27.5rem" : undefined}
|
|
1639
1673
|
hasValue={Boolean(from || to)}
|
|
1640
1674
|
triggerText={triggerText}
|
|
1641
1675
|
onClear={() => commitRange("", "", undefined)}
|
|
@@ -165,7 +165,7 @@ export function DescriptionList({
|
|
|
165
165
|
? { gridTemplateColumns: `repeat(auto-fill, minmax(min(100%, ${track}), 1fr))` }
|
|
166
166
|
: undefined;
|
|
167
167
|
const ctx: ListContextValue = { layout, numeric, prose, density, columns: columns ?? 2, placeholder };
|
|
168
|
-
const text = density === "tight" ? "text-
|
|
168
|
+
const text = density === "tight" ? "text-caption leading-4" : density === "compact" ? "text-xs" : "text-sm";
|
|
169
169
|
|
|
170
170
|
if (stacked) {
|
|
171
171
|
return (
|
|
@@ -299,7 +299,7 @@ export function DescriptionItem({
|
|
|
299
299
|
<dt
|
|
300
300
|
className={cn(
|
|
301
301
|
"flex min-w-0 items-center gap-1 text-[var(--text-muted)]",
|
|
302
|
-
cards && (density === "tight" ? "text-
|
|
302
|
+
cards && (density === "tight" ? "text-micro uppercase tracking-wide" : "text-xs uppercase tracking-wide"),
|
|
303
303
|
// Stacked terms are a step smaller than the detail, as kastlan's dialogs set
|
|
304
304
|
// them; in a list that is already small they stay the list's own size.
|
|
305
305
|
stacked && density === "comfortable" && "text-xs",
|
|
@@ -3,6 +3,7 @@ import type { ReactNode } from "react";
|
|
|
3
3
|
import { X } from "lucide-react";
|
|
4
4
|
|
|
5
5
|
import { cn } from "../lib/cn";
|
|
6
|
+
import { FOCUS_RING } from "./focus-ring";
|
|
6
7
|
import { Modal, ModalCloseContext } from "./modal";
|
|
7
8
|
import type { ModalProps } from "./modal";
|
|
8
9
|
import { useKitLabels } from "../i18n/kit-labels";
|
|
@@ -211,7 +212,7 @@ function FrameClose({ label, onClose }: { label?: string; onClose: () => void })
|
|
|
211
212
|
type="button"
|
|
212
213
|
onClick={close}
|
|
213
214
|
aria-label={labels.close}
|
|
214
|
-
className="-me-1.5 -mt-1 shrink-0 rounded p-1.5 text-[var(--text-muted)] outline-none hover:bg-[var(--bg-hover)] hover:text-[var(--text-secondary)]
|
|
215
|
+
className={cn("-me-1.5 -mt-1 shrink-0 rounded p-1.5 text-[var(--text-muted)] outline-none hover:bg-[var(--bg-hover)] hover:text-[var(--text-secondary)]", FOCUS_RING)}
|
|
215
216
|
>
|
|
216
217
|
<X aria-hidden className="size-5" />
|
|
217
218
|
</button>
|
|
@@ -3,6 +3,7 @@ import type { ComponentPropsWithoutRef, ReactNode } from "react";
|
|
|
3
3
|
import { ChevronDown } from "lucide-react";
|
|
4
4
|
|
|
5
5
|
import { cn } from "../lib/cn";
|
|
6
|
+
import { FOCUS_RING } from "./focus-ring";
|
|
6
7
|
// Read at the moment of closing, as `useCloseTransition` does: the setting can change
|
|
7
8
|
// under a long-lived page.
|
|
8
9
|
import { prefersReducedMotion } from "../hooks/use-close-transition";
|
|
@@ -345,10 +346,10 @@ export function Disclosure({
|
|
|
345
346
|
// card's hover paint on the stretched area / the row, not the text box.
|
|
346
347
|
cn(
|
|
347
348
|
"min-w-0 flex-1 after:absolute after:inset-0 after:content-['']",
|
|
348
|
-
"focus-visible:after:ring-
|
|
349
|
+
"focus-visible:after:ring-[length:var(--focus-ring-width)] focus-visible:after:ring-inset focus-visible:after:ring-[var(--brand)]",
|
|
349
350
|
card ? cn("after:rounded-lg", joined && "after:rounded-b-none") : !menu && "after:rounded-sm",
|
|
350
351
|
)
|
|
351
|
-
:
|
|
352
|
+
: FOCUS_RING,
|
|
352
353
|
card
|
|
353
354
|
? cn(
|
|
354
355
|
"items-center justify-between rounded-lg p-4",
|
|
@@ -11,6 +11,8 @@ import { useAnchoredPanel } from "../hooks/use-anchored-panel";
|
|
|
11
11
|
import { useEscapeKey, useOutsideClick } from "../hooks/use-dismiss";
|
|
12
12
|
import { useOverlayHistory } from "../hooks/use-overlay-history";
|
|
13
13
|
import { cn } from "../lib/cn";
|
|
14
|
+
import { FIELD_TOUCH_TEXT } from "./ui";
|
|
15
|
+
import { FOCUS_RING } from "./focus-ring";
|
|
14
16
|
import { useAnchorDir } from "./use-anchor-dir";
|
|
15
17
|
|
|
16
18
|
/**
|
|
@@ -34,7 +36,7 @@ import { useAnchorDir } from "./use-anchor-dir";
|
|
|
34
36
|
* while it is up, so the rule is the hook's rather than each caller's. `backCloses`
|
|
35
37
|
* is for the ONE case where a second entry would be wrong: a caller whose panel is
|
|
36
38
|
* itself a `PickerSheet`, which already registers one — both comboboxes swap shape at
|
|
37
|
-
*
|
|
39
|
+
* the phone layout (`usePhoneLayout()`), and two entries would cost two Back presses to close one sheet.
|
|
38
40
|
*
|
|
39
41
|
* ## One outside-click rule for the whole package
|
|
40
42
|
*
|
|
@@ -206,7 +208,13 @@ export function DropdownSearchHeader({
|
|
|
206
208
|
aria-controls={listboxId}
|
|
207
209
|
aria-activedescendant={activeId}
|
|
208
210
|
aria-autocomplete={listboxId ? "list" : undefined}
|
|
209
|
-
|
|
211
|
+
// FIELD_TOUCH_TEXT: a search box is a field — at least 16 px on touch, or iOS zooms
|
|
212
|
+
// the page the moment a picker opens and focuses it (§10.1).
|
|
213
|
+
className={cn(
|
|
214
|
+
"w-full rounded-sm bg-transparent text-sm outline-none placeholder:text-[var(--text-placeholder)] text-[var(--text-primary)]",
|
|
215
|
+
FOCUS_RING,
|
|
216
|
+
FIELD_TOUCH_TEXT,
|
|
217
|
+
)}
|
|
210
218
|
/>
|
|
211
219
|
</div>
|
|
212
220
|
);
|
|
@@ -28,7 +28,9 @@ export type FacingSide = "left" | "right";
|
|
|
28
28
|
export const FACING_SIDES: readonly FacingSide[] = ["left", "right"];
|
|
29
29
|
|
|
30
30
|
/** The whole band a facing y axis occupies: its ticks, and the strip the rotated title
|
|
31
|
-
* is drawn in — whether or not this chart is the one that spends it.
|
|
31
|
+
* is drawn in — whether or not this chart is the one that spends it. In px at Normal:
|
|
32
|
+
* it is also the right axis' declared `width`, which the chart scales with the text
|
|
33
|
+
* (see {@link facingHeadingPad} for a heading's). */
|
|
32
34
|
export function facingBand(tickWidth: number = AXIS_TICK_WIDTH): number {
|
|
33
35
|
return axisBandWidth(tickWidth, true);
|
|
34
36
|
}
|
|
@@ -75,12 +77,17 @@ export function facingAxes({
|
|
|
75
77
|
|
|
76
78
|
/** What a column heading is padded by to sit over the PLOT rather than the column: the
|
|
77
79
|
* axis band, on the side that column's axis stands on. Physical padding on purpose —
|
|
78
|
-
* the chart under it does not flip in RTL, so neither may the heading's offset.
|
|
80
|
+
* the chart under it does not flip in RTL, so neither may the heading's offset.
|
|
81
|
+
*
|
|
82
|
+
* `scale` is the text size's (`useTextSize().scale`): the chart draws its bands that
|
|
83
|
+
* many times wider from Large up (docs/text-size-harmonization.md §10.10), so a heading
|
|
84
|
+
* passes the same factor to stay over its plot. Both sides by the same factor, as the
|
|
85
|
+
* chart does. */
|
|
79
86
|
export function facingHeadingPad(
|
|
80
87
|
side: FacingSide,
|
|
81
88
|
tickWidth: number = AXIS_TICK_WIDTH,
|
|
89
|
+
scale = 1,
|
|
82
90
|
): Pick<CSSProperties, "paddingLeft" | "paddingRight"> {
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
: { paddingRight: facingBand(tickWidth) };
|
|
91
|
+
const band = axisBandWidth(tickWidth, true, scale);
|
|
92
|
+
return side === "left" ? { paddingLeft: band } : { paddingRight: band };
|
|
86
93
|
}
|