@eifi1/ui-kit 0.31.0 → 0.32.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +53 -30
- package/dist/account/delete-account-setting.d.ts +8 -3
- package/dist/admin/admin-action-confirm.d.ts +8 -3
- package/dist/admin/admin-parts.d.ts +8 -1
- package/dist/admin/admin-parts.js +1 -1
- package/dist/admin/admin-parts.js.map +1 -1
- package/dist/admin/invitations-panel.d.ts +8 -3
- package/dist/admin/invitations-panel.js +29 -26
- package/dist/admin/invitations-panel.js.map +1 -1
- package/dist/admin/reviewer-scope-editor.d.ts +8 -3
- package/dist/admin/role-select.d.ts +10 -5
- package/dist/admin/transfer-ownership-dialog.d.ts +8 -3
- package/dist/admin/user-roster.d.ts +10 -5
- package/dist/admin/user-roster.js +8 -47
- package/dist/admin/user-roster.js.map +1 -1
- package/dist/auth/auth-errors.d.ts +43 -8
- package/dist/auth/auth-errors.js +24 -1
- package/dist/auth/auth-errors.js.map +1 -1
- package/dist/auth/register-form.d.ts +8 -3
- package/dist/auth/reset-password-form.d.ts +1 -1
- package/dist/auth/reset-password-form.js +2 -1
- package/dist/auth/reset-password-form.js.map +1 -1
- package/dist/auth/verify-email.d.ts +4 -0
- package/dist/auth/verify-email.js +3 -2
- package/dist/auth/verify-email.js.map +1 -1
- package/dist/billing/billing-banner.d.ts +184 -0
- package/dist/billing/billing-banner.js +98 -0
- package/dist/billing/billing-banner.js.map +1 -0
- package/dist/billing/billing-labels.d.ts +100 -0
- package/dist/billing/billing-labels.js +74 -0
- package/dist/billing/billing-labels.js.map +1 -0
- package/dist/billing/billing-lock.d.ts +158 -0
- package/dist/billing/billing-lock.js +17 -0
- package/dist/billing/billing-lock.js.map +1 -0
- package/dist/billing/billing-standing.d.ts +149 -0
- package/dist/billing/billing-standing.js +28 -0
- package/dist/billing/billing-standing.js.map +1 -0
- package/dist/billing/plan-card.d.ts +248 -0
- package/dist/billing/plan-card.js +248 -0
- package/dist/billing/plan-card.js.map +1 -0
- package/dist/billing/plan-limit-notice.d.ts +156 -0
- package/dist/billing/plan-limit-notice.js +76 -0
- package/dist/billing/plan-limit-notice.js.map +1 -0
- package/dist/billing/plan-limit.d.ts +34 -0
- package/dist/billing/plan-limit.js +20 -0
- package/dist/billing/plan-limit.js.map +1 -0
- package/dist/billing/plan-price.d.ts +61 -0
- package/dist/billing/plan-price.js +45 -0
- package/dist/billing/plan-price.js.map +1 -0
- package/dist/billing/subscription-actions.d.ts +133 -0
- package/dist/billing/subscription-actions.js +28 -0
- package/dist/billing/subscription-actions.js.map +1 -0
- package/dist/billing/subscription-status-chip.d.ts +149 -0
- package/dist/billing/subscription-status-chip.js +48 -0
- package/dist/billing/subscription-status-chip.js.map +1 -0
- package/dist/chart.d.ts +9 -3
- package/dist/components/account-chips.d.ts +16 -4
- package/dist/components/account-chips.js +21 -3
- package/dist/components/account-chips.js.map +1 -1
- package/dist/components/alert-banner.d.ts +6 -1
- package/dist/components/alert-banner.js +4 -3
- package/dist/components/alert-banner.js.map +1 -1
- package/dist/components/amount-input.d.ts +8 -3
- package/dist/components/amount-input.js +5 -5
- package/dist/components/amount-input.js.map +1 -1
- package/dist/components/appearance-labels.d.ts +32 -0
- package/dist/components/appearance-labels.js +18 -0
- package/dist/components/appearance-labels.js.map +1 -0
- package/dist/components/autocomplete.js +2 -2
- package/dist/components/autocomplete.js.map +1 -1
- package/dist/components/breadcrumbs.js +3 -2
- package/dist/components/breadcrumbs.js.map +1 -1
- package/dist/components/bulk-action-bar.d.ts +2 -2
- package/dist/components/bulk-action-bar.js +7 -12
- package/dist/components/bulk-action-bar.js.map +1 -1
- package/dist/components/button-group.d.ts +8 -3
- package/dist/components/calculator.d.ts +8 -3
- package/dist/components/calculator.js +4 -3
- package/dist/components/calculator.js.map +1 -1
- package/dist/components/calendar-heatmap.js +5 -5
- package/dist/components/calendar-heatmap.js.map +1 -1
- package/dist/components/chart-height.d.ts +23 -0
- package/dist/components/chart-height.js +15 -0
- package/dist/components/chart-height.js.map +1 -0
- package/dist/components/chart-zoom.js +6 -1
- package/dist/components/chart-zoom.js.map +1 -1
- package/dist/components/checkbox-group.js +2 -2
- package/dist/components/checkbox-group.js.map +1 -1
- package/dist/components/checkbox.d.ts +10 -0
- package/dist/components/checkbox.js +25 -10
- package/dist/components/checkbox.js.map +1 -1
- package/dist/components/chip.d.ts +19 -3
- package/dist/components/chip.js +47 -21
- package/dist/components/chip.js.map +1 -1
- package/dist/components/choice-card.d.ts +1 -1
- package/dist/components/choice-card.js +8 -7
- package/dist/components/choice-card.js.map +1 -1
- package/dist/components/column-mapper.js +1 -1
- package/dist/components/column-mapper.js.map +1 -1
- package/dist/components/combobox-core.js +8 -7
- package/dist/components/combobox-core.js.map +1 -1
- package/dist/components/combobox.js +8 -8
- package/dist/components/combobox.js.map +1 -1
- package/dist/components/confirm-dialog.d.ts +8 -3
- package/dist/components/confirm-dialog.js +7 -1
- package/dist/components/confirm-dialog.js.map +1 -1
- package/dist/components/copy-button.d.ts +10 -5
- package/dist/components/country-select.js +1 -1
- package/dist/components/country-select.js.map +1 -1
- package/dist/components/currency-select.js +3 -3
- package/dist/components/currency-select.js.map +1 -1
- package/dist/components/danger-confirm.d.ts +8 -3
- package/dist/components/data-table-cells.d.ts +1 -1
- package/dist/components/data-table-filter-popover.d.ts +1 -1
- package/dist/components/data-table-filter-popover.js +4 -1
- package/dist/components/data-table-filter-popover.js.map +1 -1
- package/dist/components/data-table-filters.d.ts +1 -1
- package/dist/components/data-table-labels.d.ts +1 -1
- package/dist/components/data-table-pagination.d.ts +1 -1
- package/dist/components/data-table.d.ts +1 -1
- package/dist/components/data-table.js +123 -52
- package/dist/components/data-table.js.map +1 -1
- package/dist/components/date-picker.d.ts +1 -1
- package/dist/components/date-picker.js +7 -5
- package/dist/components/date-picker.js.map +1 -1
- package/dist/components/description-list.js +2 -2
- package/dist/components/description-list.js.map +1 -1
- package/dist/components/dialog-frame.js +2 -1
- package/dist/components/dialog-frame.js.map +1 -1
- package/dist/components/disclosure.js +3 -2
- package/dist/components/disclosure.js.map +1 -1
- package/dist/components/dropdown.d.ts +1 -1
- package/dist/components/dropdown.js +7 -1
- package/dist/components/dropdown.js.map +1 -1
- package/dist/components/facing-pair.d.ts +19 -6
- package/dist/components/facing-pair.js +3 -2
- package/dist/components/facing-pair.js.map +1 -1
- package/dist/components/field-parts.d.ts +102 -6
- package/dist/components/field-parts.js +81 -6
- package/dist/components/field-parts.js.map +1 -1
- package/dist/components/field-sync.d.ts +4 -1
- package/dist/components/field-sync.js +12 -2
- package/dist/components/field-sync.js.map +1 -1
- package/dist/components/field.js +2 -2
- package/dist/components/field.js.map +1 -1
- package/dist/components/file-button.d.ts +8 -3
- package/dist/components/file-dropzone.d.ts +8 -3
- package/dist/components/floating-panel.js +7 -4
- package/dist/components/floating-panel.js.map +1 -1
- package/dist/components/focus-ring.d.ts +12 -0
- package/dist/components/focus-ring.js +8 -0
- package/dist/components/focus-ring.js.map +1 -0
- package/dist/components/form-actions.d.ts +8 -3
- package/dist/components/form-actions.js +33 -19
- package/dist/components/form-actions.js.map +1 -1
- package/dist/components/full-bleed-dialog.d.ts +11 -1
- package/dist/components/full-bleed-dialog.js +3 -1
- package/dist/components/full-bleed-dialog.js.map +1 -1
- package/dist/components/iban-input.d.ts +8 -3
- package/dist/components/image-grid.js +1 -1
- package/dist/components/image-grid.js.map +1 -1
- package/dist/components/inline-edit-field.js +6 -3
- package/dist/components/inline-edit-field.js.map +1 -1
- package/dist/components/language-select.d.ts +8 -3
- package/dist/components/legal-page.d.ts +26 -5
- package/dist/components/legal-page.js +3 -1
- package/dist/components/legal-page.js.map +1 -1
- package/dist/components/legal.d.ts +8 -3
- package/dist/components/legal.js +2 -1
- package/dist/components/legal.js.map +1 -1
- package/dist/components/lightbox.js +24 -2
- package/dist/components/lightbox.js.map +1 -1
- package/dist/components/line-items.js +2 -1
- package/dist/components/line-items.js.map +1 -1
- package/dist/components/list.d.ts +5 -0
- package/dist/components/list.js +13 -9
- package/dist/components/list.js.map +1 -1
- package/dist/components/measured-grid.d.ts +3 -1
- package/dist/components/measured-grid.js +38 -20
- package/dist/components/measured-grid.js.map +1 -1
- package/dist/components/menu-item.js +2 -1
- package/dist/components/menu-item.js.map +1 -1
- package/dist/components/mini-calendar.js +8 -4
- package/dist/components/mini-calendar.js.map +1 -1
- package/dist/components/money-field.d.ts +8 -3
- package/dist/components/month-picker.js +9 -5
- package/dist/components/month-picker.js.map +1 -1
- package/dist/components/nav-pills.js +1 -1
- package/dist/components/nav-pills.js.map +1 -1
- package/dist/components/number-field.d.ts +8 -3
- package/dist/components/number-input.d.ts +11 -4
- package/dist/components/number-input.js +8 -6
- package/dist/components/number-input.js.map +1 -1
- package/dist/components/numpad-sheet.d.ts +8 -3
- package/dist/components/numpad-sheet.js +2 -1
- package/dist/components/numpad-sheet.js.map +1 -1
- package/dist/components/one-time-code-input.js +2 -2
- package/dist/components/one-time-code-input.js.map +1 -1
- package/dist/components/page-contents.js +2 -2
- package/dist/components/page-contents.js.map +1 -1
- package/dist/components/phone-input.d.ts +8 -3
- package/dist/components/phone-input.js +2 -2
- package/dist/components/phone-input.js.map +1 -1
- package/dist/components/pie-chart.d.ts +8 -2
- package/dist/components/pie-chart.js +11 -7
- package/dist/components/pie-chart.js.map +1 -1
- package/dist/components/popover.d.ts +9 -1
- package/dist/components/popover.js +8 -4
- package/dist/components/popover.js.map +1 -1
- package/dist/components/row-actions.d.ts +100 -0
- package/dist/components/row-actions.js +165 -0
- package/dist/components/row-actions.js.map +1 -0
- package/dist/components/scroll-area.js +1 -1
- package/dist/components/scroll-area.js.map +1 -1
- package/dist/components/search-field.js +3 -2
- package/dist/components/search-field.js.map +1 -1
- package/dist/components/series-chart-budget.d.ts +30 -7
- package/dist/components/series-chart-budget.js +12 -4
- package/dist/components/series-chart-budget.js.map +1 -1
- package/dist/components/series-chart-ticks.d.ts +7 -1
- package/dist/components/series-chart-ticks.js +6 -0
- package/dist/components/series-chart-ticks.js.map +1 -1
- package/dist/components/series-chart.d.ts +58 -28
- package/dist/components/series-chart.js +42 -32
- package/dist/components/series-chart.js.map +1 -1
- package/dist/components/settings-fields.d.ts +51 -6
- package/dist/components/settings-fields.js +37 -0
- package/dist/components/settings-fields.js.map +1 -1
- package/dist/components/share-card.d.ts +11 -6
- package/dist/components/share-card.js +2 -0
- package/dist/components/share-card.js.map +1 -1
- package/dist/components/sign-chip.d.ts +4 -0
- package/dist/components/sign-chip.js +17 -4
- package/dist/components/sign-chip.js.map +1 -1
- package/dist/components/signature-pad.d.ts +3 -1
- package/dist/components/signature-pad.js +8 -5
- package/dist/components/signature-pad.js.map +1 -1
- package/dist/components/slider.js +7 -6
- package/dist/components/slider.js.map +1 -1
- package/dist/components/sparkline.d.ts +5 -1
- package/dist/components/sparkline.js +4 -2
- package/dist/components/sparkline.js.map +1 -1
- package/dist/components/stat-tile.d.ts +17 -1
- package/dist/components/stat-tile.js +48 -20
- package/dist/components/stat-tile.js.map +1 -1
- package/dist/components/status-dot.d.ts +4 -0
- package/dist/components/swipeable-row.js +2 -1
- package/dist/components/swipeable-row.js.map +1 -1
- package/dist/components/switch.d.ts +21 -7
- package/dist/components/switch.js +24 -11
- package/dist/components/switch.js.map +1 -1
- package/dist/components/table.js +2 -2
- package/dist/components/table.js.map +1 -1
- package/dist/components/text-link.d.ts +8 -3
- package/dist/components/text-link.js +1 -1
- package/dist/components/text-link.js.map +1 -1
- package/dist/components/text.d.ts +7 -2
- package/dist/components/text.js +5 -5
- package/dist/components/text.js.map +1 -1
- package/dist/components/tile-radio.js +2 -1
- package/dist/components/tile-radio.js.map +1 -1
- package/dist/components/time-input.d.ts +8 -3
- package/dist/components/toast.d.ts +18 -2
- package/dist/components/toast.js +8 -5
- package/dist/components/toast.js.map +1 -1
- package/dist/components/toggle-group.d.ts +16 -1
- package/dist/components/toggle-group.js +40 -11
- package/dist/components/toggle-group.js.map +1 -1
- package/dist/components/toggle-legend.d.ts +10 -1
- package/dist/components/toggle-legend.js +21 -7
- package/dist/components/toggle-legend.js.map +1 -1
- package/dist/components/translation-review-parts.d.ts +4 -0
- package/dist/components/translation-review.d.ts +4 -0
- package/dist/components/translation-review.js +3 -3
- package/dist/components/translation-review.js.map +1 -1
- package/dist/components/tree-view.js +3 -2
- package/dist/components/tree-view.js.map +1 -1
- package/dist/components/treemap.d.ts +5 -2
- package/dist/components/treemap.js +33 -16
- package/dist/components/treemap.js.map +1 -1
- package/dist/components/ui.d.ts +8 -3
- package/dist/components/ui.js +202 -114
- package/dist/components/ui.js.map +1 -1
- package/dist/components/use-table-state.d.ts +1 -1
- package/dist/components/user-avatar.d.ts +5 -1
- package/dist/components/user-avatar.js +1 -1
- package/dist/components/user-avatar.js.map +1 -1
- package/dist/{data-table-labels-DUELeXpa.d.ts → data-table-labels-kpAAVi6g.d.ts} +26 -2
- package/dist/data-table.d.ts +1 -1
- package/dist/{delete-account-setting-DCFS5Vof.d.ts → delete-account-setting-BvdQdbv3.d.ts} +613 -58
- package/dist/demo/demo-banner.js +1 -0
- package/dist/demo/demo-banner.js.map +1 -1
- package/dist/feedback/feedback-attachment.d.ts +8 -3
- package/dist/feedback/feedback-context.d.ts +8 -3
- package/dist/feedback/feedback-crash.d.ts +8 -3
- package/dist/feedback/feedback-dialog.d.ts +8 -3
- package/dist/feedback/feedback-dialog.js +3 -3
- package/dist/feedback/feedback-dialog.js.map +1 -1
- package/dist/feedback/feedback-inbox.d.ts +8 -3
- package/dist/feedback/feedback-inbox.js +2 -2
- package/dist/feedback/feedback-inbox.js.map +1 -1
- package/dist/feedback/feedback-labels.d.ts +8 -3
- package/dist/feedback/feedback-menu.d.ts +9 -4
- package/dist/feedback/feedback-record.d.ts +8 -3
- package/dist/feedback/feedback-row-detail.d.ts +8 -3
- package/dist/feedback/feedback-status-undo.d.ts +8 -3
- package/dist/feedback/feedback-submit.d.ts +8 -3
- package/dist/feedback/feedback-swipe.d.ts +8 -3
- package/dist/feedback/feedback-table.d.ts +8 -3
- package/dist/feedback/feedback-thread.d.ts +8 -3
- package/dist/feedback/feedback-thread.js +3 -3
- package/dist/feedback/feedback-thread.js.map +1 -1
- package/dist/feedback.d.ts +8 -3
- package/dist/hooks/use-anchored-panel.d.ts +32 -3
- package/dist/hooks/use-anchored-panel.js +21 -3
- package/dist/hooks/use-anchored-panel.js.map +1 -1
- package/dist/hooks/use-breakpoint.d.ts +77 -0
- package/dist/hooks/use-breakpoint.js +50 -0
- package/dist/hooks/use-breakpoint.js.map +1 -0
- package/dist/hooks/use-file-drop.d.ts +8 -3
- package/dist/hooks/use-large-text.d.ts +29 -0
- package/dist/hooks/use-large-text.js +20 -0
- package/dist/hooks/use-large-text.js.map +1 -0
- package/dist/hooks/use-windowed-rows.d.ts +52 -8
- package/dist/hooks/use-windowed-rows.js +94 -5
- package/dist/hooks/use-windowed-rows.js.map +1 -1
- package/dist/i18n/defaults.d.ts +8 -3
- package/dist/i18n/defaults.js +8 -0
- package/dist/i18n/defaults.js.map +1 -1
- package/dist/i18n/german.d.ts +8 -3
- package/dist/i18n/german.js +91 -3
- package/dist/i18n/german.js.map +1 -1
- package/dist/i18n/kit-labels.d.ts +8 -3
- package/dist/i18n/kit-labels.js.map +1 -1
- package/dist/i18n/languages.d.ts +10 -5
- package/dist/i18n/locales/de-CH.d.ts +8 -3
- package/dist/i18n/locales/en.d.ts +8 -3
- package/dist/i18n/locales/es.d.ts +8 -3
- package/dist/i18n/locales/es.js +86 -3
- package/dist/i18n/locales/es.js.map +1 -1
- package/dist/i18n/locales/fr.d.ts +8 -3
- package/dist/i18n/locales/fr.js +88 -3
- package/dist/i18n/locales/fr.js.map +1 -1
- package/dist/i18n/locales/hu.d.ts +8 -3
- package/dist/i18n/locales/hu.js +88 -3
- package/dist/i18n/locales/hu.js.map +1 -1
- package/dist/i18n/locales/it.d.ts +8 -3
- package/dist/i18n/locales/it.js +89 -3
- package/dist/i18n/locales/it.js.map +1 -1
- package/dist/i18n/locales/zh.d.ts +8 -3
- package/dist/i18n/locales/zh.js +86 -3
- package/dist/i18n/locales/zh.js.map +1 -1
- package/dist/i18n/review.d.ts +8 -3
- package/dist/i18n/review.js +16 -1
- package/dist/i18n/review.js.map +1 -1
- package/dist/index.d.ts +29 -13
- package/dist/index.js +77 -5
- package/dist/index.js.map +1 -1
- package/dist/landing/landing-actions.d.ts +12 -5
- package/dist/landing/landing-actions.js +1 -1
- package/dist/landing/landing-actions.js.map +1 -1
- package/dist/landing/landing-sections.d.ts +8 -3
- package/dist/landing/public-header.d.ts +9 -4
- package/dist/landing/public-header.js +3 -3
- package/dist/landing/public-header.js.map +1 -1
- package/dist/landing/routing.d.ts +27 -9
- package/dist/landing/routing.js +5 -2
- package/dist/landing/routing.js.map +1 -1
- package/dist/lib/cn.js +3 -2
- package/dist/lib/cn.js.map +1 -1
- package/dist/rhf/fields.d.ts +8 -3
- package/dist/rhf/fields.js +1 -1
- package/dist/rhf/fields.js.map +1 -1
- package/dist/rhf/form.d.ts +8 -3
- package/dist/rhf/form.js +2 -2
- package/dist/rhf/form.js.map +1 -1
- package/dist/rhf.d.ts +8 -3
- package/dist/search/command-palette.d.ts +1 -1
- package/dist/search/command-palette.js +9 -8
- package/dist/search/command-palette.js.map +1 -1
- package/dist/settings/settings-labels.d.ts +8 -1
- package/dist/settings/settings-labels.js +7 -2
- package/dist/settings/settings-labels.js.map +1 -1
- package/dist/settings/settings-layout.js +2 -1
- package/dist/settings/settings-layout.js.map +1 -1
- package/dist/settings/settings-section.d.ts +8 -3
- package/dist/settings/use-account-appearance.d.ts +92 -0
- package/dist/settings/use-account-appearance.js +63 -0
- package/dist/settings/use-account-appearance.js.map +1 -0
- package/dist/settings/use-settings-route.d.ts +1 -1
- package/dist/settings/use-settings-route.js +2 -3
- package/dist/settings/use-settings-route.js.map +1 -1
- package/dist/shell/app-shell.d.ts +12 -171
- package/dist/shell/app-shell.js +144 -28
- package/dist/shell/app-shell.js.map +1 -1
- package/dist/shell/auth-layout.js +1 -1
- package/dist/shell/auth-layout.js.map +1 -1
- package/dist/shell/option-switcher-menu.js +1 -1
- package/dist/shell/option-switcher-menu.js.map +1 -1
- package/dist/shell/top-bar-brand.d.ts +8 -3
- package/dist/shell/top-bar-brand.js +3 -1
- package/dist/shell/top-bar-brand.js.map +1 -1
- package/dist/shell/topbar-action-menu.d.ts +4 -0
- package/dist/shell/topbar-action-menu.js +3 -3
- package/dist/shell/topbar-action-menu.js.map +1 -1
- package/dist/shell/topbar-controls.js +4 -4
- package/dist/shell/topbar-controls.js.map +1 -1
- package/dist/shell.d.ts +10 -6
- package/dist/shell.js.map +1 -1
- package/dist/theme/contrast-tokens.d.ts +41 -0
- package/dist/theme/contrast-tokens.js +59 -0
- package/dist/theme/contrast-tokens.js.map +1 -0
- package/dist/theme/contrast.d.ts +109 -0
- package/dist/theme/contrast.js +128 -0
- package/dist/theme/contrast.js.map +1 -0
- package/dist/theme/palette-presets.d.ts +12 -1
- package/dist/theme/palette-presets.js +9 -4
- package/dist/theme/palette-presets.js.map +1 -1
- package/dist/theme/palette-store.js.map +1 -1
- package/dist/theme/text-size.d.ts +157 -0
- package/dist/theme/text-size.js +121 -0
- package/dist/theme/text-size.js.map +1 -0
- package/dist/wizard/stepper-nav.d.ts +8 -3
- package/dist/wizard.d.ts +8 -3
- package/package.json +1 -1
- package/src/admin/admin-parts.ts +9 -2
- package/src/admin/invitations-panel.tsx +36 -29
- package/src/admin/user-roster.tsx +17 -72
- package/src/auth/auth-errors.ts +68 -7
- package/src/auth/reset-password-form.tsx +6 -2
- package/src/auth/verify-email.tsx +14 -2
- package/src/billing/billing-banner.tsx +205 -0
- package/src/billing/billing-labels.ts +224 -0
- package/src/billing/billing-lock.ts +75 -0
- package/src/billing/billing-standing.ts +72 -0
- package/src/billing/plan-card.tsx +458 -0
- package/src/billing/plan-limit-notice.tsx +145 -0
- package/src/billing/plan-limit.ts +53 -0
- package/src/billing/plan-price.ts +101 -0
- package/src/billing/subscription-actions.tsx +76 -0
- package/src/billing/subscription-status-chip.tsx +95 -0
- package/src/components/account-chips.tsx +36 -10
- package/src/components/alert-banner.tsx +11 -6
- package/src/components/amount-input.tsx +5 -5
- package/src/components/appearance-labels.ts +40 -0
- package/src/components/autocomplete.tsx +2 -2
- package/src/components/breadcrumbs.tsx +3 -3
- package/src/components/bulk-action-bar.tsx +11 -14
- package/src/components/calculator.tsx +4 -3
- package/src/components/calendar-heatmap.tsx +5 -5
- package/src/components/chart-height.ts +30 -0
- package/src/components/chart-zoom.tsx +6 -1
- package/src/components/checkbox-group.tsx +2 -2
- package/src/components/checkbox.tsx +62 -20
- package/src/components/chip.tsx +105 -24
- package/src/components/choice-card.tsx +15 -10
- package/src/components/column-mapper.tsx +1 -1
- package/src/components/combobox-core.tsx +8 -7
- package/src/components/combobox.tsx +8 -8
- package/src/components/confirm-dialog.tsx +20 -1
- package/src/components/country-select.tsx +1 -1
- package/src/components/currency-select.tsx +3 -3
- package/src/components/data-table-filter-popover.tsx +7 -1
- package/src/components/data-table.tsx +160 -43
- package/src/components/date-picker.tsx +12 -9
- package/src/components/description-list.tsx +2 -2
- package/src/components/dialog-frame.tsx +2 -1
- package/src/components/disclosure.tsx +3 -2
- package/src/components/dropdown.tsx +10 -2
- package/src/components/facing-pair.ts +12 -5
- package/src/components/field-parts.tsx +190 -7
- package/src/components/field-sync.tsx +17 -3
- package/src/components/field.tsx +2 -2
- package/src/components/floating-panel.tsx +7 -4
- package/src/components/focus-ring.ts +12 -0
- package/src/components/form-actions.tsx +55 -18
- package/src/components/full-bleed-dialog.tsx +18 -4
- package/src/components/image-grid.tsx +1 -1
- package/src/components/inline-edit-field.tsx +6 -3
- package/src/components/legal-page.tsx +28 -2
- package/src/components/legal.tsx +19 -1
- package/src/components/lightbox.tsx +24 -2
- package/src/components/line-items.tsx +7 -1
- package/src/components/list.tsx +36 -10
- package/src/components/measured-grid.tsx +49 -24
- package/src/components/menu-item.tsx +2 -2
- package/src/components/mini-calendar.tsx +8 -4
- package/src/components/month-picker.tsx +9 -5
- package/src/components/nav-pills.tsx +1 -1
- package/src/components/number-input.tsx +14 -7
- package/src/components/numpad-sheet.tsx +2 -2
- package/src/components/one-time-code-input.tsx +2 -2
- package/src/components/page-contents.tsx +2 -2
- package/src/components/phone-input.tsx +2 -2
- package/src/components/pie-chart.tsx +19 -9
- package/src/components/popover.tsx +22 -5
- package/src/components/row-actions.tsx +344 -0
- package/src/components/scroll-area.tsx +1 -1
- package/src/components/search-field.tsx +4 -2
- package/src/components/series-chart-budget.ts +40 -8
- package/src/components/series-chart-ticks.ts +10 -0
- package/src/components/series-chart.tsx +123 -72
- package/src/components/settings-fields.tsx +81 -2
- package/src/components/share-card.tsx +10 -0
- package/src/components/sign-chip.tsx +28 -4
- package/src/components/signature-pad.tsx +13 -7
- package/src/components/slider.tsx +22 -9
- package/src/components/sparkline.tsx +11 -3
- package/src/components/stat-tile.tsx +70 -14
- package/src/components/swipeable-row.tsx +2 -1
- package/src/components/switch.tsx +57 -23
- package/src/components/table.tsx +2 -2
- package/src/components/text-link.tsx +1 -1
- package/src/components/text.tsx +11 -6
- package/src/components/tile-radio.tsx +4 -1
- package/src/components/toast.tsx +27 -7
- package/src/components/toggle-group.tsx +99 -12
- package/src/components/toggle-legend.tsx +53 -8
- package/src/components/translation-review.tsx +10 -5
- package/src/components/tree-view.tsx +3 -2
- package/src/components/treemap.tsx +27 -10
- package/src/components/ui.tsx +331 -145
- package/src/components/user-avatar.tsx +1 -1
- package/src/demo/demo-banner.tsx +5 -0
- package/src/feedback/feedback-dialog.tsx +3 -3
- package/src/feedback/feedback-inbox.tsx +2 -2
- package/src/feedback/feedback-thread.tsx +3 -3
- package/src/hooks/use-anchored-panel.ts +67 -5
- package/src/hooks/use-breakpoint.ts +121 -0
- package/src/hooks/use-large-text.ts +41 -0
- package/src/hooks/use-windowed-rows.ts +168 -12
- package/src/i18n/defaults.ts +8 -0
- package/src/i18n/german.ts +105 -1
- package/src/i18n/kit-labels.tsx +12 -0
- package/src/i18n/locales/es.ts +96 -1
- package/src/i18n/locales/fr.ts +100 -1
- package/src/i18n/locales/hu.ts +98 -1
- package/src/i18n/locales/it.ts +101 -1
- package/src/i18n/locales/zh.ts +92 -1
- package/src/i18n/review.ts +15 -0
- package/src/index.ts +82 -8
- package/src/landing/landing-actions.tsx +9 -5
- package/src/landing/public-header.tsx +4 -4
- package/src/landing/routing.tsx +22 -5
- package/src/lib/cn.ts +13 -2
- package/src/rhf/fields.tsx +1 -1
- package/src/rhf/form.tsx +2 -2
- package/src/search/command-palette.tsx +10 -9
- package/src/settings/settings-labels.ts +13 -1
- package/src/settings/settings-layout.tsx +2 -1
- package/src/settings/use-account-appearance.ts +148 -0
- package/src/settings/use-settings-route.ts +3 -4
- package/src/shell/app-shell.tsx +278 -54
- package/src/shell/auth-layout.tsx +1 -1
- package/src/shell/option-switcher-menu.tsx +1 -1
- package/src/shell/top-bar-brand.tsx +3 -1
- package/src/shell/topbar-action-menu.tsx +3 -3
- package/src/shell/topbar-controls.tsx +4 -4
- package/src/shell.ts +7 -1
- package/src/theme/contrast-tokens.ts +112 -0
- package/src/theme/contrast.ts +224 -0
- package/src/theme/palette-presets.ts +24 -4
- package/src/theme/palette-store.ts +6 -1
- package/src/theme/text-size.ts +267 -0
- package/tokens.css +143 -1
|
@@ -2,12 +2,12 @@ import { Fragment, useId, useMemo, useRef, useState } from "react";
|
|
|
2
2
|
import type { ComponentPropsWithoutRef, ReactNode, Ref, RefObject } from "react";
|
|
3
3
|
import { createPortal } from "react-dom";
|
|
4
4
|
import { ChevronDown, Plus, X } from "lucide-react";
|
|
5
|
-
import { FIELD_BASE, FIELD_FLOATING_PAD, FIELD_INVALID
|
|
5
|
+
import { FIELD_BASE, FIELD_FLOATING_PAD, FIELD_INVALID } from "./ui";
|
|
6
6
|
import { cn } from "../lib/cn";
|
|
7
7
|
import { useDropdown } from "./dropdown";
|
|
8
8
|
import { useAnchoredPanel } from "../hooks/use-anchored-panel";
|
|
9
9
|
import { useAnchorDir } from "./use-anchor-dir";
|
|
10
|
-
import {
|
|
10
|
+
import { usePhoneLayout } from "../hooks/use-breakpoint";
|
|
11
11
|
import { PickerSheet, SHEET_ROW_CLASS } from "./picker-sheet";
|
|
12
12
|
import {
|
|
13
13
|
ComboboxFieldLabel,
|
|
@@ -339,7 +339,7 @@ export function Combobox(props: ComboboxProps) {
|
|
|
339
339
|
// `backCloses` is the desktop half of live #309: the phone's list IS a
|
|
340
340
|
// {@link PickerSheet}, which registers its own history entry, so registering a
|
|
341
341
|
// second one here would cost two Back presses to dismiss one sheet.
|
|
342
|
-
const isPhone =
|
|
342
|
+
const isPhone = usePhoneLayout();
|
|
343
343
|
const { open, setOpen, wrapperRef, panelRef } = useDropdown({ backCloses: !isPhone });
|
|
344
344
|
const primaryOnly = usePrimaryPressOnly();
|
|
345
345
|
const [active, setActive] = useState(-1);
|
|
@@ -673,7 +673,7 @@ export function Combobox(props: ComboboxProps) {
|
|
|
673
673
|
{group !== undefined && (
|
|
674
674
|
<li
|
|
675
675
|
role="presentation"
|
|
676
|
-
className="px-4 pb-0.5 pt-3 text-
|
|
676
|
+
className="px-4 pb-0.5 pt-3 text-caption font-semibold uppercase tracking-wide text-[var(--text-muted)]"
|
|
677
677
|
>
|
|
678
678
|
{group}
|
|
679
679
|
</li>
|
|
@@ -730,7 +730,7 @@ export function Combobox(props: ComboboxProps) {
|
|
|
730
730
|
{group !== undefined && (
|
|
731
731
|
<li
|
|
732
732
|
role="presentation"
|
|
733
|
-
className="px-3 pb-0.5 pt-2 text-
|
|
733
|
+
className="px-3 pb-0.5 pt-2 text-caption font-semibold uppercase tracking-wide text-[var(--text-muted)] first:pt-1"
|
|
734
734
|
>
|
|
735
735
|
{group}
|
|
736
736
|
</li>
|
|
@@ -978,7 +978,7 @@ export function InlineEntityCombobox<V extends string | number, C extends ComboC
|
|
|
978
978
|
// See the twin above on why these hang off the generated id.
|
|
979
979
|
const listboxId = `${generated}-listbox`;
|
|
980
980
|
const optionId = (index: number) => `${generated}-option-${index}`;
|
|
981
|
-
const isPhone =
|
|
981
|
+
const isPhone = usePhoneLayout();
|
|
982
982
|
// See the twin above: the phone sheet owns its own Back entry (live #309).
|
|
983
983
|
const { open, setOpen, wrapperRef, panelRef } = useDropdown({ backCloses: !isPhone });
|
|
984
984
|
const primaryOnly = usePrimaryPressOnly();
|
|
@@ -1357,7 +1357,7 @@ export function InlineEntityCombobox<V extends string | number, C extends ComboC
|
|
|
1357
1357
|
{o.group && o.group !== matches[i - 1]?.group && (
|
|
1358
1358
|
<li
|
|
1359
1359
|
role="presentation"
|
|
1360
|
-
className="px-4 pb-0.5 pt-3 text-
|
|
1360
|
+
className="px-4 pb-0.5 pt-3 text-caption font-semibold uppercase tracking-wide text-[var(--text-muted)]"
|
|
1361
1361
|
>
|
|
1362
1362
|
{o.group}
|
|
1363
1363
|
</li>
|
|
@@ -1420,7 +1420,7 @@ export function InlineEntityCombobox<V extends string | number, C extends ComboC
|
|
|
1420
1420
|
{o.group && o.group !== matches[i - 1]?.group && (
|
|
1421
1421
|
<li
|
|
1422
1422
|
role="presentation"
|
|
1423
|
-
className="px-3 pb-0.5 pt-2 text-
|
|
1423
|
+
className="px-3 pb-0.5 pt-2 text-caption font-semibold uppercase tracking-wide text-[var(--text-muted)] first:pt-1"
|
|
1424
1424
|
>
|
|
1425
1425
|
{o.group}
|
|
1426
1426
|
</li>
|
|
@@ -6,6 +6,7 @@ import { TypedConfirmField, typedMatches } from "./danger-confirm";
|
|
|
6
6
|
import type { TypedMatch } from "./danger-confirm";
|
|
7
7
|
import { DialogFrame } from "./dialog-frame";
|
|
8
8
|
import { Button } from "./ui";
|
|
9
|
+
import { useWriteLock } from "./write-lock";
|
|
9
10
|
|
|
10
11
|
/**
|
|
11
12
|
* The `confirmDialog` namespace of `<UiKitProvider labels>`: the two buttons' fallback
|
|
@@ -76,6 +77,14 @@ export interface ConfirmOptions {
|
|
|
76
77
|
* keeps spaces too — for a phrase like "DELETE" whose contract is "exactly this".
|
|
77
78
|
*/
|
|
78
79
|
typedMatch?: TypedMatch;
|
|
80
|
+
/**
|
|
81
|
+
* 0.31.1: the confirm button COMMITS, as `Button`'s `commit` does. Under a locked
|
|
82
|
+
* `WriteLockProvider` — read where `useConfirm` was called, not where the one dialog
|
|
83
|
+
* host sits — it is `aria-disabled` with the lock's reason, so a read-only page (a
|
|
84
|
+
* demo, a viewer's budget) can't confirm a delete through a dialog. One prop for the
|
|
85
|
+
* many confirm sites an app has (kastlan's 0.31 adoption counted ~23).
|
|
86
|
+
*/
|
|
87
|
+
commit?: boolean;
|
|
79
88
|
}
|
|
80
89
|
|
|
81
90
|
export type ConfirmFn = (options: ConfirmOptions) => Promise<boolean>;
|
|
@@ -97,12 +106,21 @@ export function useConfirm(): ConfirmFn {
|
|
|
97
106
|
if (!confirm) {
|
|
98
107
|
throw new Error("useConfirm() must be called below a <ConfirmProvider>.");
|
|
99
108
|
}
|
|
100
|
-
|
|
109
|
+
// The lock of the CALLER's place: the dialog host usually sits above the app's
|
|
110
|
+
// `WriteLockProvider`, so it could not read the lock itself.
|
|
111
|
+
const lock = useWriteLock();
|
|
112
|
+
return useCallback(
|
|
113
|
+
(options: ConfirmOptions) =>
|
|
114
|
+
confirm(options.commit && lock.locked ? ({ ...options, lockReason: lock.reason } as ConfirmOptions) : options),
|
|
115
|
+
[confirm, lock.locked, lock.reason],
|
|
116
|
+
);
|
|
101
117
|
}
|
|
102
118
|
|
|
103
119
|
interface Request extends ConfirmOptions {
|
|
104
120
|
id: number;
|
|
105
121
|
resolve: (answer: boolean) => void;
|
|
122
|
+
/** Set by {@link useConfirm} for a `commit` confirm under a locked provider. */
|
|
123
|
+
lockReason?: ReactNode;
|
|
106
124
|
}
|
|
107
125
|
|
|
108
126
|
export interface ConfirmProviderProps {
|
|
@@ -279,6 +297,7 @@ function ConfirmDialogView({
|
|
|
279
297
|
type="button"
|
|
280
298
|
variant={tone === "danger" ? "danger" : "primary"}
|
|
281
299
|
disabled={!matches}
|
|
300
|
+
disabledReason={request.lockReason}
|
|
282
301
|
onClick={() => {
|
|
283
302
|
accepted.current = true;
|
|
284
303
|
close();
|
|
@@ -532,7 +532,7 @@ export function CountrySelect<Clearable extends boolean = false>({
|
|
|
532
532
|
<div {...rest} className={className}>
|
|
533
533
|
{box}
|
|
534
534
|
{textHint && (
|
|
535
|
-
<p id={hintId} className="mt-1 text-
|
|
535
|
+
<p id={hintId} className="mt-1 text-caption leading-tight text-[var(--text-muted)]">
|
|
536
536
|
{hint}
|
|
537
537
|
</p>
|
|
538
538
|
)}
|
|
@@ -63,7 +63,7 @@ export function CurrencyFlag({ country, className, ...rest }: CurrencyFlagProps)
|
|
|
63
63
|
// code printed next to it, and a reader that met both would hear the currency
|
|
64
64
|
// twice.
|
|
65
65
|
aria-hidden
|
|
66
|
-
className={cn("fi inline-block w-5 h-[
|
|
66
|
+
className={cn("fi inline-block w-5 h-[0.9375rem] rounded-sm shadow-[0_0_0_1px_rgba(0,0,0,0.08)] shrink-0", `fi-${country}`, className)}
|
|
67
67
|
/>
|
|
68
68
|
);
|
|
69
69
|
}
|
|
@@ -341,7 +341,7 @@ export function CurrencySelect({
|
|
|
341
341
|
is `absolute` with no `top`, so it opens at its place in the flow — under the
|
|
342
342
|
caption, had the caption come first. */}
|
|
343
343
|
{textHint && (
|
|
344
|
-
<p id={hintId} className="mt-1 text-
|
|
344
|
+
<p id={hintId} className="mt-1 text-caption leading-tight text-[var(--text-muted)]">
|
|
345
345
|
{hint}
|
|
346
346
|
</p>
|
|
347
347
|
)}
|
|
@@ -356,4 +356,4 @@ export function CurrencySelect({
|
|
|
356
356
|
|
|
357
357
|
// The error line under a field — the type of `ui.tsx`'s (module-private) one, so a
|
|
358
358
|
// CurrencySelect's message is indistinguishable from an Input's.
|
|
359
|
-
const FIELD_ERROR_CLASS = "mt-1 text-
|
|
359
|
+
const FIELD_ERROR_CLASS = "mt-1 text-caption leading-tight text-[var(--danger)]";
|
|
@@ -1,6 +1,8 @@
|
|
|
1
1
|
import { useCallback } from "react";
|
|
2
2
|
import { X } from "lucide-react";
|
|
3
3
|
import { cn } from "../lib/cn";
|
|
4
|
+
import { FIELD_TOUCH_TEXT } from "./ui";
|
|
5
|
+
import { FOCUS_RING } from "./focus-ring";
|
|
4
6
|
import { MiniCalendar } from "./mini-calendar";
|
|
5
7
|
import { dateRangePresets } from "../lib/dates";
|
|
6
8
|
import { resolveFilter } from "./data-table-filters";
|
|
@@ -71,7 +73,11 @@ export function FilterPopover<T>({
|
|
|
71
73
|
// border going from --border to --border-strong is not a location. The ring is, and it
|
|
72
74
|
// is the package's brand focus colour, as on every field in ui.tsx.
|
|
73
75
|
const inputBase =
|
|
74
|
-
"block w-full rounded border border-[var(--border)] bg-[var(--bg-surface)] px-2 py-1.5 text-sm text-[var(--text-secondary)] placeholder:text-[var(--text-placeholder)] focus:border-[var(--border-strong)] focus:outline-none
|
|
76
|
+
"block w-full rounded border border-[var(--border)] bg-[var(--bg-surface)] px-2 py-1.5 text-sm text-[var(--text-secondary)] placeholder:text-[var(--text-placeholder)] focus:border-[var(--border-strong)] focus:outline-none " +
|
|
77
|
+
FOCUS_RING +
|
|
78
|
+
" " +
|
|
79
|
+
// §10.1: a filter field is a field — 16 px on touch, or iOS zooms on focus.
|
|
80
|
+
FIELD_TOUCH_TEXT;
|
|
75
81
|
const buttonBase =
|
|
76
82
|
"rounded border border-[var(--border)] bg-[var(--bg-surface)] px-2 py-1 text-xs text-[var(--text-secondary)] hover:bg-[var(--bg-hover)]";
|
|
77
83
|
|
|
@@ -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 { useBreakpoint } 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,11 @@ 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. The same answer as `usePhoneLayout()`
|
|
1659
|
+
// (inverted), which an app's own phone checks use (§10.4).
|
|
1660
|
+
const isMdUp = useBreakpoint("md", true);
|
|
1582
1661
|
// `edgeFade` (0.25) on the desktop scroller; the phone list never scrolls sideways.
|
|
1583
1662
|
const desktopScroller = useRef<HTMLDivElement | null>(null);
|
|
1584
1663
|
const edgeFadeProps = useEdgeFade(desktopScroller, edgeFade && isMdUp);
|
|
@@ -1592,6 +1671,26 @@ export function DataTable<T>({
|
|
|
1592
1671
|
const mobilePrimaryCol =
|
|
1593
1672
|
mobileColumns.find((c) => c.mobilePrimary) ?? mobileColumns[0] ?? null;
|
|
1594
1673
|
const mobileSecondaryColumns = mobileColumns.filter((c) => c !== mobilePrimaryCol);
|
|
1674
|
+
// The columns the card leaves out, for the opened row (`mobileDetailsInRow`).
|
|
1675
|
+
const mobileDetailColumns = mobileDetailsInRow ? visibleColumns.filter((c) => c.mobileHidden) : [];
|
|
1676
|
+
// Large and Extra large (§4 "DataTable phone card"): the card's labels go ABOVE their
|
|
1677
|
+
// values, nothing in it truncates, and the rows get more room. Most of it is a
|
|
1678
|
+
// `large:` class; the label/value grid needs a different STRUCTURE (each pair in a
|
|
1679
|
+
// box of its own), which a class cannot write.
|
|
1680
|
+
const large = useLargeText();
|
|
1681
|
+
// What an opened phone row shows: the card's left-out columns first (when asked
|
|
1682
|
+
// for), then the app's own `expandedRow`. Desktop keeps `expandedRow` alone.
|
|
1683
|
+
const opensRow = !!expandedRow || mobileDetailColumns.length > 0;
|
|
1684
|
+
const openedRowContent = (row: T): ReactNode => {
|
|
1685
|
+
const detail = expandedRow?.(row) ?? null;
|
|
1686
|
+
if (mobileDetailColumns.length === 0) return detail;
|
|
1687
|
+
return (
|
|
1688
|
+
<div data-row-details="" className={cn("flex flex-col", compact ? "gap-2" : "gap-3")}>
|
|
1689
|
+
<StackedFields columns={mobileDetailColumns} row={row} compact={compact} />
|
|
1690
|
+
{detail}
|
|
1691
|
+
</div>
|
|
1692
|
+
);
|
|
1693
|
+
};
|
|
1595
1694
|
// The phone card IS the anchor, so unlike the desktop table there is no other
|
|
1596
1695
|
// cell to move the row link into: if any cell the card renders owns a link, the
|
|
1597
1696
|
// card itself cannot be one (feedback #451 — same nesting rule as `linkColumn`
|
|
@@ -1679,7 +1778,7 @@ export function DataTable<T>({
|
|
|
1679
1778
|
// When dialog-mode is on, the expanded row's detail goes into a bottom-sheet
|
|
1680
1779
|
// modal instead of unfolding inline. Only one row is ever expanded at a time.
|
|
1681
1780
|
const mobileDialogRow = mobileExpandAsDialog && !isMdUp ? mobileSlice.find((r) => isExpanded?.(r)) : undefined;
|
|
1682
|
-
const mobileDialogContent = mobileDialogRow ?
|
|
1781
|
+
const mobileDialogContent = mobileDialogRow ? openedRowContent(mobileDialogRow) : null;
|
|
1683
1782
|
// The full-screen row dialog. Its panel, header, scroll lock and Back handling all
|
|
1684
1783
|
// live in {@link FullBleedDialog} now — this was the only copy of that shell until
|
|
1685
1784
|
// the transactions create card needed the same one (Keksdose live #307's follow-up),
|
|
@@ -1694,7 +1793,7 @@ export function DataTable<T>({
|
|
|
1694
1793
|
// share identical row markup.
|
|
1695
1794
|
const renderMobileRow = (row: T) => {
|
|
1696
1795
|
const expanded = isExpanded?.(row) ?? false;
|
|
1697
|
-
const expansion = expanded ?
|
|
1796
|
+
const expansion = expanded ? openedRowContent(row) : null;
|
|
1698
1797
|
const tint = rowClassName?.(row);
|
|
1699
1798
|
// Use div+role="button" rather than a real <button> so cells that
|
|
1700
1799
|
// contain their own interactive controls (status toggles, action
|
|
@@ -1706,7 +1805,7 @@ export function DataTable<T>({
|
|
|
1706
1805
|
// values are not editable". A chevron is the affordance every list on a phone
|
|
1707
1806
|
// uses for exactly this, and it points the way the row actually opens: right into
|
|
1708
1807
|
// a sheet, or down into an inline panel that flips it when expanded.
|
|
1709
|
-
const opensDetail = interactive &&
|
|
1808
|
+
const opensDetail = interactive && opensRow;
|
|
1710
1809
|
const swipeActions = swipeActionsFor?.(row);
|
|
1711
1810
|
const swipe = swipeActions ? physicalSwipe(swipeActions, mobileDir) : null;
|
|
1712
1811
|
// An expanded row never swipes: the editor below it owns the horizontal space,
|
|
@@ -1715,7 +1814,8 @@ export function DataTable<T>({
|
|
|
1715
1814
|
const href = mobileCardLinkable ? rowHref?.(row) : undefined;
|
|
1716
1815
|
const cardClass = cn(
|
|
1717
1816
|
"w-full text-start flex items-center",
|
|
1718
|
-
|
|
1817
|
+
// §4: more room per row at Large — a taller row is a bigger tap target too.
|
|
1818
|
+
compact ? "px-3 py-2 gap-2 text-sm large:py-3" : "px-4 py-3 gap-3 large:py-4",
|
|
1719
1819
|
// Live #320's other half: the card acknowledges the touch before the sheet
|
|
1720
1820
|
// arrives. On a cold route the data can take a beat, and an unacknowledged tap
|
|
1721
1821
|
// reads as "did that register?" — which is most of what "abrupt" means here.
|
|
@@ -1731,8 +1831,7 @@ export function DataTable<T>({
|
|
|
1731
1831
|
// AppShell main's `overflow-x-clip` — so the frame went missing on one side. A press
|
|
1732
1832
|
// keeps the fill and the squeeze above; an outline on every tap of a long list would
|
|
1733
1833
|
// 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)]",
|
|
1834
|
+
interactive && cn("[-webkit-tap-highlight-color:transparent] focus-visible:ring-inset", FOCUS_RING),
|
|
1736
1835
|
);
|
|
1737
1836
|
// The card's content is written once and worn by either tag below. Note that
|
|
1738
1837
|
// the primary cell is rendered RAW here, never through `linkColumn` — the card
|
|
@@ -1743,18 +1842,31 @@ export function DataTable<T>({
|
|
|
1743
1842
|
<>
|
|
1744
1843
|
{/* The card's own content keeps the column it always had; the chevron sits
|
|
1745
1844
|
beside it rather than inside, so a caller's `mobileCard` is untouched. */}
|
|
1746
|
-
<div
|
|
1845
|
+
<div
|
|
1846
|
+
className={cn(
|
|
1847
|
+
"flex min-w-0 flex-1 flex-col",
|
|
1848
|
+
compact ? "gap-1 large:gap-2" : "gap-2 large:gap-3",
|
|
1849
|
+
// §4 "nothing truncates": at Large a cell's own `truncate` wraps instead —
|
|
1850
|
+
// the reader who chose bigger type is the one an ellipsis fails. A caller's
|
|
1851
|
+
// `mobileCard` is its own layout and keeps what it chose.
|
|
1852
|
+
!mobileCard && CARD_NO_TRUNCATE,
|
|
1853
|
+
)}
|
|
1854
|
+
>
|
|
1747
1855
|
{mobileCard ? (
|
|
1748
1856
|
mobileCard(row)
|
|
1749
1857
|
) : (
|
|
1750
1858
|
<>
|
|
1751
1859
|
{/* Only the `data-*` half of `cellProps` — see its note. */}
|
|
1752
1860
|
{mobilePrimaryCol && (
|
|
1753
|
-
<div {...dataAttrsOf(mobilePrimaryCol.cellProps?.(row))} className="font-medium">
|
|
1861
|
+
<div {...dataAttrsOf(mobilePrimaryCol.cellProps?.(row))} className="min-w-0 break-words font-medium">
|
|
1754
1862
|
{mobilePrimaryCol.cell(row)}
|
|
1755
1863
|
</div>
|
|
1756
1864
|
)}
|
|
1757
|
-
{mobileSecondaryColumns.length > 0 && (
|
|
1865
|
+
{mobileSecondaryColumns.length > 0 && large ? (
|
|
1866
|
+
// §4: each label ABOVE its value at Large. Side by side, a label column
|
|
1867
|
+
// sized to the widest label leaves a value a sliver of a 240 px card.
|
|
1868
|
+
<StackedFields columns={mobileSecondaryColumns} row={row} compact={compact} />
|
|
1869
|
+
) : mobileSecondaryColumns.length > 0 && (
|
|
1758
1870
|
<dl
|
|
1759
1871
|
className={cn(
|
|
1760
1872
|
"grid grid-cols-[auto_1fr] gap-x-3",
|
|
@@ -1807,7 +1919,7 @@ export function DataTable<T>({
|
|
|
1807
1919
|
<RowLink
|
|
1808
1920
|
href={href}
|
|
1809
1921
|
onActivate={() => onRowClick!(row)}
|
|
1810
|
-
aria-expanded={
|
|
1922
|
+
aria-expanded={opensRow ? expanded : undefined}
|
|
1811
1923
|
className={cardClass}
|
|
1812
1924
|
// Enter already activates a link natively, and that routes through
|
|
1813
1925
|
// RowLink's own onClick — handling it here too would open the row twice.
|
|
@@ -1848,7 +1960,7 @@ export function DataTable<T>({
|
|
|
1848
1960
|
}
|
|
1849
1961
|
: undefined
|
|
1850
1962
|
}
|
|
1851
|
-
aria-expanded={
|
|
1963
|
+
aria-expanded={opensRow ? expanded : undefined}
|
|
1852
1964
|
className={cardClass}
|
|
1853
1965
|
>
|
|
1854
1966
|
{cardInner}
|
|
@@ -2238,7 +2350,7 @@ export function DataTable<T>({
|
|
|
2238
2350
|
)}
|
|
2239
2351
|
{/* Priority badge, only meaningful with 2+ sort keys */}
|
|
2240
2352
|
{active && sorts.length > 1 && (
|
|
2241
|
-
<span className="text-
|
|
2353
|
+
<span className="text-micro font-semibold leading-none text-brand">
|
|
2242
2354
|
{sortIdx + 1}
|
|
2243
2355
|
</span>
|
|
2244
2356
|
)}
|
|
@@ -2246,7 +2358,9 @@ export function DataTable<T>({
|
|
|
2246
2358
|
</Tooltip>
|
|
2247
2359
|
{filter && (
|
|
2248
2360
|
<Popover
|
|
2249
|
-
|
|
2361
|
+
// 420 px at Normal, in rem so the calendar grows with its
|
|
2362
|
+
// text (§3.2); Popover caps it at the viewport.
|
|
2363
|
+
width={filter.type === "date" ? "26.25rem" : undefined}
|
|
2250
2364
|
// The panel is the column's filter, and says so. Unnamed it
|
|
2251
2365
|
// was announced as the kit-wide fallback, "Popover".
|
|
2252
2366
|
labels={{ panel: labels.filter }}
|
|
@@ -2364,8 +2478,11 @@ export function DataTable<T>({
|
|
|
2364
2478
|
className={cn(
|
|
2365
2479
|
"border-t border-[var(--border)]",
|
|
2366
2480
|
rowInteractive && "cursor-pointer hover:bg-[var(--bg-hover)]",
|
|
2481
|
+
// The kit's focus frame width (§5, `--focus-ring-width`), drawn as an
|
|
2482
|
+
// OUTLINE rather than FOCUS_RING's box-shadow: a shadow on a `<tr>`
|
|
2483
|
+
// is not painted by every engine, an outline is.
|
|
2367
2484
|
rowsFocusable &&
|
|
2368
|
-
"focus-visible:bg-[var(--bg-hover)] focus-visible:outline-
|
|
2485
|
+
"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
2486
|
rowClassName?.(row),
|
|
2370
2487
|
)}
|
|
2371
2488
|
onClick={
|
|
@@ -2787,7 +2904,7 @@ function MobileFilters<T>({
|
|
|
2787
2904
|
<Filter className="size-4" />
|
|
2788
2905
|
<span>{labels.filters}</span>
|
|
2789
2906
|
{activeCount > 0 && (
|
|
2790
|
-
<span className="inline-flex min-w-4 items-center justify-center rounded-full bg-[var(--info-bg)] px-1 text-
|
|
2907
|
+
<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
2908
|
{activeCount}
|
|
2792
2909
|
</span>
|
|
2793
2910
|
)}
|
|
@@ -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";
|
|
@@ -395,11 +396,12 @@ function DateField({
|
|
|
395
396
|
panelLabel: string;
|
|
396
397
|
invalid?: boolean;
|
|
397
398
|
className?: string;
|
|
398
|
-
/** Popover panel width; omit for the default (a bare calendar).
|
|
399
|
-
|
|
399
|
+
/** Popover panel width; omit for the default (a bare calendar). In rem so it grows
|
|
400
|
+
* with the text size, like the Popover's own default (§3.2). */
|
|
401
|
+
width?: number | RemLength;
|
|
400
402
|
onClear: () => void;
|
|
401
403
|
/** Open as a full-screen sheet instead of the popover — the picker decides when
|
|
402
|
-
* (
|
|
404
|
+
* (in the phone layout, `usePhoneLayout()`). */
|
|
403
405
|
sheet?: boolean;
|
|
404
406
|
/** The sheet's `FullBleedDialog backCloses`. */
|
|
405
407
|
sheetBackCloses?: boolean;
|
|
@@ -943,7 +945,8 @@ function JumpCalendar({
|
|
|
943
945
|
// 44px rows: the touch-target size, and four of them stand as tall
|
|
944
946
|
// as a month of days, so the panel does not jump as the views swap.
|
|
945
947
|
"h-11 rounded px-1 text-sm tabular-nums transition-colors",
|
|
946
|
-
|
|
948
|
+
FOCUS_RING_WIDTH,
|
|
949
|
+
"focus-visible:outline-none focus-visible:ring-inset",
|
|
947
950
|
// A --brand ring on a --brand fill exists only in the DOM.
|
|
948
951
|
end && !disabled ? "focus-visible:ring-[var(--brand-contrast)]" : "focus-visible:ring-[var(--brand)]",
|
|
949
952
|
disabled
|
|
@@ -1288,7 +1291,7 @@ export interface DateRangePickerProps extends DatePickerBaseProps {
|
|
|
1288
1291
|
*/
|
|
1289
1292
|
renderTrigger?: (props: DateRangeTriggerRenderProps) => ReactNode;
|
|
1290
1293
|
/**
|
|
1291
|
-
*
|
|
1294
|
+
* In the phone layout (`usePhoneLayout()`) the panel opens as a full-screen sheet (`FullBleedDialog`)
|
|
1292
1295
|
* with presets in a grid above the calendar and Apply pinned in the footer, instead
|
|
1293
1296
|
* of the 440px popover that hung off a 360px screen (keksdose's report range field,
|
|
1294
1297
|
* which hand-rolled exactly this). This is its `backCloses`: on by default, so Back
|
|
@@ -1615,7 +1618,7 @@ export function DateRangePicker(props: DateRangePickerProps) {
|
|
|
1615
1618
|
: `${a}${separator}…`
|
|
1616
1619
|
: (placeholder ?? "");
|
|
1617
1620
|
const hasPresets = Boolean(presets && presets.length > 0);
|
|
1618
|
-
const sheet =
|
|
1621
|
+
const sheet = usePhoneLayout();
|
|
1619
1622
|
const commitRange = (f: string, t: string, presetId: string | undefined) => {
|
|
1620
1623
|
setOwnPreset(presetId);
|
|
1621
1624
|
// Two arguments when no preset is involved — exactly the 0.7 call, so a caller's
|
|
@@ -1635,7 +1638,7 @@ export function DateRangePicker(props: DateRangePickerProps) {
|
|
|
1635
1638
|
disabled={disabled}
|
|
1636
1639
|
invalid={messages.isInvalid}
|
|
1637
1640
|
// Widen so the preset column sits beside the calendar (default otherwise).
|
|
1638
|
-
width={hasPresets ?
|
|
1641
|
+
width={hasPresets ? "27.5rem" : undefined}
|
|
1639
1642
|
hasValue={Boolean(from || to)}
|
|
1640
1643
|
triggerText={triggerText}
|
|
1641
1644
|
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",
|