@eifi1/ui-kit 0.51.7 → 0.52.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 +141 -23
- package/dist/account/account-parts.d.ts +10 -8
- package/dist/account/account-parts.js +1 -18
- package/dist/account/account-parts.js.map +1 -1
- package/dist/account/data-export-setting-labels.js +1 -1
- package/dist/account/data-export-setting-labels.js.map +1 -1
- package/dist/account/delete-account-setting-labels.js +1 -1
- package/dist/account/delete-account-setting-labels.js.map +1 -1
- package/dist/account/email-change-setting-labels.js +1 -1
- package/dist/account/email-change-setting-labels.js.map +1 -1
- package/dist/account/passkeys-setting.d.ts +9 -2
- package/dist/account/passkeys-setting.js +41 -29
- package/dist/account/passkeys-setting.js.map +1 -1
- package/dist/account/sessions-setting.d.ts +3 -2
- package/dist/account/sessions-setting.js +10 -8
- package/dist/account/sessions-setting.js.map +1 -1
- package/dist/admin/admin-action-confirm.js +1 -3
- package/dist/admin/admin-action-confirm.js.map +1 -1
- package/dist/admin/admin-parts.d.ts +6 -3
- package/dist/admin/admin-parts.js +6 -21
- package/dist/admin/admin-parts.js.map +1 -1
- package/dist/admin/mail-test-card-labels.js +1 -1
- package/dist/admin/mail-test-card-labels.js.map +1 -1
- package/dist/admin/plan-change-labels.d.ts +2 -2
- package/dist/admin/plan-change-labels.js +1 -17
- package/dist/admin/plan-change-labels.js.map +1 -1
- package/dist/admin/plan-change.d.ts +3 -42
- package/dist/admin/plan-change.js +1 -1
- package/dist/admin/plan-change.js.map +1 -1
- package/dist/admin/reviewer-scope-editor.js +3 -3
- package/dist/admin/reviewer-scope-editor.js.map +1 -1
- package/dist/auth/auth-errors-labels.d.ts +11 -0
- package/dist/auth/auth-errors-labels.js +13 -0
- package/dist/auth/auth-errors-labels.js.map +1 -0
- package/dist/auth/auth-errors.d.ts +7 -23
- package/dist/auth/auth-errors.js +2 -15
- package/dist/auth/auth-errors.js.map +1 -1
- package/dist/auth/complete-name-dialog.js +2 -1
- package/dist/auth/complete-name-dialog.js.map +1 -1
- package/dist/auth/forgot-password-form-labels.js +1 -1
- package/dist/auth/forgot-password-form-labels.js.map +1 -1
- package/dist/auth/forgot-password-form.js +7 -2
- package/dist/auth/forgot-password-form.js.map +1 -1
- package/dist/auth/register-form-labels.js +1 -1
- package/dist/auth/register-form-labels.js.map +1 -1
- package/dist/auth/reset-password-form-labels.js +1 -1
- package/dist/auth/reset-password-form-labels.js.map +1 -1
- package/dist/auth/reset-password-form.js +5 -1
- package/dist/auth/reset-password-form.js.map +1 -1
- package/dist/auth/sign-in-form-labels.js +1 -1
- package/dist/auth/sign-in-form-labels.js.map +1 -1
- package/dist/auth/status-parts.d.ts +0 -3
- package/dist/auth/status-parts.js +0 -4
- package/dist/auth/status-parts.js.map +1 -1
- package/dist/auth/verify-email-labels.js +1 -1
- package/dist/auth/verify-email-labels.js.map +1 -1
- package/dist/auth/verify-email.js +7 -2
- package/dist/auth/verify-email.js.map +1 -1
- package/dist/billing/cancel-subscription.d.ts +20 -8
- package/dist/billing/cancel-subscription.js +7 -5
- package/dist/billing/cancel-subscription.js.map +1 -1
- package/dist/billing/dialog-close.d.ts +29 -0
- package/dist/billing/dialog-close.js +8 -0
- package/dist/billing/dialog-close.js.map +1 -0
- package/dist/billing/plan-card.d.ts +14 -4
- package/dist/billing/plan-card.js +15 -8
- package/dist/billing/plan-card.js.map +1 -1
- package/dist/billing/plan-change-labels.d.ts +42 -0
- package/dist/billing/plan-change-labels.js +22 -0
- package/dist/billing/plan-change-labels.js.map +1 -0
- package/dist/billing/plan-switch.d.ts +19 -7
- package/dist/billing/plan-switch.js +8 -4
- package/dist/billing/plan-switch.js.map +1 -1
- package/dist/chart.d.ts +12 -0
- package/dist/chart.js +16 -1
- package/dist/chart.js.map +1 -1
- package/dist/components/account-chips.d.ts +5 -5
- package/dist/components/account-chips.js +11 -13
- package/dist/components/account-chips.js.map +1 -1
- package/dist/components/alert-banner.d.ts +16 -5
- package/dist/components/alert-banner.js +46 -1
- package/dist/components/alert-banner.js.map +1 -1
- package/dist/components/amount-input.d.ts +13 -0
- package/dist/components/amount-input.js +1 -0
- package/dist/components/amount-input.js.map +1 -1
- package/dist/components/autocomplete.js +57 -65
- package/dist/components/autocomplete.js.map +1 -1
- package/dist/components/bulk-action-bar.d.ts +12 -2
- package/dist/components/bulk-action-bar.js +65 -21
- package/dist/components/bulk-action-bar.js.map +1 -1
- package/dist/components/button-look.d.ts +5 -5
- package/dist/components/button-look.js.map +1 -1
- package/dist/components/button.d.ts +2 -2
- package/dist/components/button.js.map +1 -1
- package/dist/components/chart-edge.d.ts +16 -0
- package/dist/components/chart-edge.js +14 -1
- package/dist/components/chart-edge.js.map +1 -1
- package/dist/components/chart-figure.d.ts +13 -0
- package/dist/components/chart-figure.js +15 -0
- package/dist/components/chart-figure.js.map +1 -0
- package/dist/components/chart-zoom-core.js +1 -4
- package/dist/components/chart-zoom-core.js.map +1 -1
- package/dist/components/chart.d.ts +8 -1
- package/dist/components/chart.js +19 -10
- package/dist/components/chart.js.map +1 -1
- package/dist/components/combobox-core.d.ts +111 -2
- package/dist/components/combobox-core.js +148 -42
- package/dist/components/combobox-core.js.map +1 -1
- package/dist/components/combobox.d.ts +1 -1
- package/dist/components/combobox.js +141 -130
- package/dist/components/combobox.js.map +1 -1
- package/dist/components/copy-button.d.ts +6 -5
- package/dist/components/copy-button.js +5 -3
- package/dist/components/copy-button.js.map +1 -1
- package/dist/components/country-select.js +2 -2
- package/dist/components/country-select.js.map +1 -1
- package/dist/components/data-table-column-settings.d.ts +1 -1
- package/dist/components/data-table-column-settings.js +33 -7
- package/dist/components/data-table-column-settings.js.map +1 -1
- package/dist/components/data-table-filters.d.ts +4 -2
- package/dist/components/data-table-filters.js +2 -2
- package/dist/components/data-table-filters.js.map +1 -1
- package/dist/components/data-table-fit.d.ts +6 -4
- package/dist/components/data-table-fit.js +4 -1
- package/dist/components/data-table-fit.js.map +1 -1
- package/dist/components/data-table-groups.d.ts +1 -1
- package/dist/components/data-table-groups.js.map +1 -1
- package/dist/components/data-table-head.d.ts +1 -1
- package/dist/components/data-table-head.js +15 -12
- package/dist/components/data-table-head.js.map +1 -1
- package/dist/components/data-table-mobile.d.ts +12 -7
- package/dist/components/data-table-mobile.js +43 -30
- package/dist/components/data-table-mobile.js.map +1 -1
- package/dist/components/data-table-pagination.js +11 -6
- package/dist/components/data-table-pagination.js.map +1 -1
- package/dist/components/data-table-resize.d.ts +1 -1
- package/dist/components/data-table-resize.js.map +1 -1
- package/dist/components/data-table-row-actions.d.ts +2 -2
- package/dist/components/data-table-row-actions.js.map +1 -1
- package/dist/components/data-table-row.d.ts +6 -2
- package/dist/components/data-table-row.js +17 -10
- package/dist/components/data-table-row.js.map +1 -1
- package/dist/components/data-table-selection.d.ts +1 -1
- package/dist/components/data-table-selection.js.map +1 -1
- package/dist/components/data-table-shared.d.ts +10 -2
- package/dist/components/data-table-shared.js +18 -0
- package/dist/components/data-table-shared.js.map +1 -1
- package/dist/components/data-table-sort.d.ts +21 -2
- package/dist/components/data-table-sort.js +24 -0
- package/dist/components/data-table-sort.js.map +1 -1
- package/dist/components/data-table-virtual.d.ts +1 -1
- package/dist/components/data-table-virtual.js +18 -6
- package/dist/components/data-table-virtual.js.map +1 -1
- package/dist/components/data-table.d.ts +13 -4
- package/dist/components/data-table.js +139 -36
- package/dist/components/data-table.js.map +1 -1
- package/dist/components/date-field.d.ts +24 -2
- package/dist/components/date-field.js +33 -8
- package/dist/components/date-field.js.map +1 -1
- package/dist/components/date-picker.d.ts +15 -2
- package/dist/components/date-picker.js +55 -26
- package/dist/components/date-picker.js.map +1 -1
- package/dist/components/date-range-picker.d.ts +47 -20
- package/dist/components/date-range-picker.js +23 -7
- package/dist/components/date-range-picker.js.map +1 -1
- package/dist/components/error-boundary.js +37 -30
- package/dist/components/error-boundary.js.map +1 -1
- package/dist/components/{ui-labels.d.ts → field-base-labels.d.ts} +0 -2
- package/dist/components/{ui-labels.js → field-base-labels.js} +2 -9
- package/dist/components/field-base-labels.js.map +1 -0
- package/dist/components/field-base.d.ts +4 -3
- package/dist/components/field-base.js +3 -3
- package/dist/components/field-base.js.map +1 -1
- package/dist/components/field-sync-labels.d.ts +1 -0
- package/dist/components/field-sync-labels.js.map +1 -1
- package/dist/components/field-sync.d.ts +23 -1
- package/dist/components/field-sync.js.map +1 -1
- package/dist/components/form-actions.js +11 -5
- package/dist/components/form-actions.js.map +1 -1
- package/dist/components/hover-menu.d.ts +3 -0
- package/dist/components/hover-menu.js +5 -3
- package/dist/components/hover-menu.js.map +1 -1
- package/dist/components/icon-button.js +14 -9
- package/dist/components/icon-button.js.map +1 -1
- package/dist/components/inline-confirm.d.ts +43 -0
- package/dist/components/inline-confirm.js +67 -0
- package/dist/components/inline-confirm.js.map +1 -0
- package/dist/components/inline-entity-combobox.d.ts +4 -3
- package/dist/components/inline-entity-combobox.js +148 -140
- package/dist/components/inline-entity-combobox.js.map +1 -1
- package/dist/components/input.js +1 -1
- package/dist/components/input.js.map +1 -1
- package/dist/components/jump-calendar.js +28 -112
- package/dist/components/jump-calendar.js.map +1 -1
- package/dist/components/legal-page.d.ts +3 -1
- package/dist/components/legal-page.js +3 -2
- package/dist/components/legal-page.js.map +1 -1
- package/dist/components/legal.d.ts +4 -2
- package/dist/components/legal.js.map +1 -1
- package/dist/components/lightbox.d.ts +2 -2
- package/dist/components/lightbox.js +17 -6
- package/dist/components/lightbox.js.map +1 -1
- package/dist/components/list.d.ts +6 -2
- package/dist/components/list.js +3 -2
- package/dist/components/list.js.map +1 -1
- package/dist/components/measured-grid.d.ts +1 -1
- package/dist/components/measured-grid.js +2 -1
- package/dist/components/measured-grid.js.map +1 -1
- package/dist/components/mini-calendar.js +3 -5
- package/dist/components/mini-calendar.js.map +1 -1
- package/dist/components/modal.js +3 -1
- package/dist/components/modal.js.map +1 -1
- package/dist/components/month-grid.d.ts +55 -0
- package/dist/components/month-grid.js +148 -0
- package/dist/components/month-grid.js.map +1 -0
- package/dist/components/month-picker.d.ts +36 -4
- package/dist/components/month-picker.js +123 -146
- package/dist/components/month-picker.js.map +1 -1
- package/dist/components/multi-select.d.ts +2 -2
- package/dist/components/multi-select.js +11 -6
- package/dist/components/multi-select.js.map +1 -1
- package/dist/components/picker-sheet.js +2 -1
- package/dist/components/picker-sheet.js.map +1 -1
- package/dist/components/pie-chart-labels.d.ts +7 -0
- package/dist/components/pie-chart-labels.js +1 -0
- package/dist/components/pie-chart-labels.js.map +1 -1
- package/dist/components/pie-chart.d.ts +5 -3
- package/dist/components/pie-chart.js +7 -22
- package/dist/components/pie-chart.js.map +1 -1
- package/dist/components/popover.d.ts +3 -0
- package/dist/components/popover.js +7 -1
- package/dist/components/popover.js.map +1 -1
- package/dist/components/row-actions.js +2 -1
- package/dist/components/row-actions.js.map +1 -1
- package/dist/components/section-nav.d.ts +7 -0
- package/dist/components/section-nav.js.map +1 -1
- package/dist/components/series-chart-axes.d.ts +3 -3
- package/dist/components/series-chart-axes.js.map +1 -1
- package/dist/components/series-chart-labels.d.ts +7 -4
- package/dist/components/series-chart-labels.js.map +1 -1
- package/dist/components/series-chart.d.ts +31 -7
- package/dist/components/series-chart.js +72 -29
- package/dist/components/series-chart.js.map +1 -1
- package/dist/components/share-card.js +3 -3
- package/dist/components/share-card.js.map +1 -1
- package/dist/components/sign-chip-labels.d.ts +1 -0
- package/dist/components/sign-chip-labels.js.map +1 -1
- package/dist/components/sign-chip.d.ts +10 -1
- package/dist/components/sign-chip.js.map +1 -1
- package/dist/components/tabs-labels.d.ts +2 -0
- package/dist/components/tabs-labels.js +11 -0
- package/dist/components/tabs-labels.js.map +1 -0
- package/dist/components/tabs.d.ts +1 -1
- package/dist/components/tabs.js +1 -1
- package/dist/components/tabs.js.map +1 -1
- package/dist/components/toggle-legend.d.ts +2 -2
- package/dist/components/toggle-legend.js +6 -6
- package/dist/components/toggle-legend.js.map +1 -1
- package/dist/components/translation-review-editor.d.ts +4 -2
- package/dist/components/translation-review-editor.js +2 -3
- package/dist/components/translation-review-editor.js.map +1 -1
- package/dist/components/translation-review.d.ts +2 -1
- package/dist/components/translation-review.js +2 -2
- package/dist/components/translation-review.js.map +1 -1
- package/dist/components/treemap-labels.d.ts +26 -0
- package/dist/components/treemap-labels.js +10 -0
- package/dist/components/treemap-labels.js.map +1 -0
- package/dist/components/treemap-layout.d.ts +62 -0
- package/dist/components/treemap-layout.js +126 -0
- package/dist/components/treemap-layout.js.map +1 -0
- package/dist/components/treemap.d.ts +140 -17
- package/dist/components/treemap.js +324 -97
- package/dist/components/treemap.js.map +1 -1
- package/dist/components/use-table-state.d.ts +5 -5
- package/dist/components/use-table-state.js +4 -1
- package/dist/components/use-table-state.js.map +1 -1
- package/dist/data-table.d.ts +6 -2
- package/dist/data-table.js +7 -2
- package/dist/data-table.js.map +1 -1
- package/dist/eslint/index.js +1 -1
- package/dist/eslint/role-utilities.d.ts +36 -7
- package/dist/eslint/role-utilities.js +42 -9
- package/dist/eslint/role-utilities.js.map +1 -1
- package/dist/feedback/feedback-dialog.d.ts +25 -16
- package/dist/feedback/feedback-dialog.js +6 -2
- package/dist/feedback/feedback-dialog.js.map +1 -1
- package/dist/feedback/feedback-mutation.d.ts +30 -0
- package/dist/feedback/feedback-mutation.js +16 -0
- package/dist/feedback/feedback-mutation.js.map +1 -0
- package/dist/feedback/feedback-page-link.d.ts +53 -0
- package/dist/feedback/feedback-page-link.js +37 -0
- package/dist/feedback/feedback-page-link.js.map +1 -0
- package/dist/feedback/feedback-public-list.d.ts +12 -3
- package/dist/feedback/feedback-public-list.js +2 -1
- package/dist/feedback/feedback-public-list.js.map +1 -1
- package/dist/feedback/feedback-replies.d.ts +3 -1
- package/dist/feedback/feedback-replies.js +5 -4
- package/dist/feedback/feedback-replies.js.map +1 -1
- package/dist/feedback/feedback-row-detail-labels.js +5 -0
- package/dist/feedback/feedback-row-detail-labels.js.map +1 -1
- package/dist/feedback/feedback-row-detail.d.ts +64 -28
- package/dist/feedback/feedback-row-detail.js +30 -28
- package/dist/feedback/feedback-row-detail.js.map +1 -1
- package/dist/feedback/feedback-status-undo.d.ts +30 -11
- package/dist/feedback/feedback-status-undo.js +10 -15
- package/dist/feedback/feedback-status-undo.js.map +1 -1
- package/dist/feedback/feedback-submit-dialog.d.ts +1 -1
- package/dist/feedback/feedback-submit-dialog.js +1 -1
- package/dist/feedback/feedback-submit-dialog.js.map +1 -1
- package/dist/feedback/feedback-submit.js +9 -3
- package/dist/feedback/feedback-submit.js.map +1 -1
- package/dist/feedback/feedback-swipe.d.ts +1 -1
- package/dist/feedback/feedback-swipe.js.map +1 -1
- package/dist/feedback/feedback-table.d.ts +21 -9
- package/dist/feedback/feedback-table.js +45 -25
- package/dist/feedback/feedback-table.js.map +1 -1
- package/dist/feedback/feedback-thread-labels.d.ts +2 -2
- package/dist/feedback/feedback-thread-labels.js.map +1 -1
- package/dist/feedback/feedback-thread.d.ts +24 -23
- package/dist/feedback/feedback-thread.js +2 -1
- package/dist/feedback/feedback-thread.js.map +1 -1
- package/dist/feedback.d.ts +34 -0
- package/dist/feedback.js +42 -0
- package/dist/feedback.js.map +1 -1
- package/dist/hooks/use-focus-trap.d.ts +35 -0
- package/dist/hooks/use-focus-trap.js +6 -4
- package/dist/hooks/use-focus-trap.js.map +1 -1
- package/dist/hooks/use-hotkey.d.ts +5 -2
- package/dist/hooks/use-hotkey.js +5 -4
- package/dist/hooks/use-hotkey.js.map +1 -1
- package/dist/hooks/use-long-press.d.ts +7 -4
- package/dist/hooks/use-long-press.js +3 -0
- package/dist/hooks/use-long-press.js.map +1 -1
- package/dist/hooks/use-media-query.js +12 -4
- package/dist/hooks/use-media-query.js.map +1 -1
- package/dist/hooks/use-mounted.d.ts +22 -0
- package/dist/hooks/use-mounted.js +24 -0
- package/dist/hooks/use-mounted.js.map +1 -0
- package/dist/hooks/use-overlay-history.js +19 -3
- package/dist/hooks/use-overlay-history.js.map +1 -1
- package/dist/i18n/defaults.js +4 -5
- package/dist/i18n/defaults.js.map +1 -1
- package/dist/i18n/german.js +7 -1
- package/dist/i18n/german.js.map +1 -1
- package/dist/i18n/kit-labels.d.ts +9 -2
- package/dist/i18n/kit-labels.js.map +1 -1
- package/dist/i18n/locales/en.js +20 -41
- package/dist/i18n/locales/en.js.map +3 -3
- package/dist/i18n/locales/es.js +7 -1
- package/dist/i18n/locales/es.js.map +1 -1
- package/dist/i18n/locales/fr.js +20 -10
- package/dist/i18n/locales/fr.js.map +1 -1
- package/dist/i18n/locales/hu.js +9 -1
- package/dist/i18n/locales/hu.js.map +1 -1
- package/dist/i18n/locales/it.js +7 -1
- package/dist/i18n/locales/it.js.map +1 -1
- package/dist/i18n/locales/zh.js +8 -1
- package/dist/i18n/locales/zh.js.map +1 -1
- package/dist/i18n/review.js +5 -0
- package/dist/i18n/review.js.map +1 -1
- package/dist/index.d.ts +64 -17
- package/dist/index.js +77 -12
- package/dist/index.js.map +1 -1
- package/dist/landing/routing.d.ts +3 -1
- package/dist/landing/routing.js +4 -7
- package/dist/landing/routing.js.map +1 -1
- package/dist/lib/broadcast.d.ts +17 -0
- package/dist/lib/broadcast.js +30 -0
- package/dist/lib/broadcast.js.map +1 -0
- package/dist/lib/date-format.d.ts +37 -2
- package/dist/lib/date-format.js +34 -8
- package/dist/lib/date-format.js.map +1 -1
- package/dist/lib/day-format.d.ts +46 -0
- package/dist/lib/day-format.js +46 -0
- package/dist/lib/day-format.js.map +1 -0
- package/dist/lib/describe-failure.d.ts +14 -0
- package/dist/lib/describe-failure.js +9 -0
- package/dist/lib/describe-failure.js.map +1 -0
- package/dist/lib/direction.d.ts +16 -0
- package/dist/lib/direction.js +9 -1
- package/dist/lib/direction.js.map +1 -1
- package/dist/lib/focus-left.d.ts +63 -0
- package/dist/lib/focus-left.js +67 -0
- package/dist/lib/focus-left.js.map +1 -0
- package/dist/lib/format.js +5 -14
- package/dist/lib/format.js.map +1 -1
- package/dist/lib/http-status.d.ts +24 -0
- package/dist/lib/http-status.js +14 -0
- package/dist/lib/http-status.js.map +1 -0
- package/dist/lib/intl-cache.d.ts +14 -0
- package/dist/lib/intl-cache.js +15 -0
- package/dist/lib/intl-cache.js.map +1 -0
- package/dist/lib/isin.d.ts +10 -0
- package/dist/lib/isin.js.map +1 -1
- package/dist/lib/iso-day.d.ts +11 -0
- package/dist/lib/iso-day.js +8 -0
- package/dist/lib/iso-day.js.map +1 -0
- package/dist/lib/lazy-with-fallback.d.ts +31 -0
- package/dist/lib/lazy-with-fallback.js +40 -0
- package/dist/lib/lazy-with-fallback.js.map +1 -0
- package/dist/lib/path-pattern.d.ts +34 -0
- package/dist/lib/path-pattern.js +24 -0
- package/dist/lib/path-pattern.js.map +1 -0
- package/dist/lib/reduced-motion.d.ts +2 -1
- package/dist/lib/reduced-motion.js.map +1 -1
- package/dist/lib/round.d.ts +2 -1
- package/dist/lib/round.js +2 -1
- package/dist/lib/round.js.map +1 -1
- package/dist/lib/safe-storage.d.ts +24 -5
- package/dist/lib/safe-storage.js +27 -2
- package/dist/lib/safe-storage.js.map +1 -1
- package/dist/lib/session-refresh.js +1 -1
- package/dist/lib/session-refresh.js.map +1 -1
- package/dist/lib/share-format.d.ts +13 -0
- package/dist/lib/share-format.js +10 -0
- package/dist/lib/share-format.js.map +1 -0
- package/dist/lib/text-case.d.ts +17 -0
- package/dist/lib/text-case.js +8 -0
- package/dist/lib/text-case.js.map +1 -0
- package/dist/lib/text-match.d.ts +29 -0
- package/dist/lib/text-match.js +20 -2
- package/dist/lib/text-match.js.map +1 -1
- package/dist/lib/thenable.d.ts +13 -0
- package/dist/lib/thenable.js +8 -0
- package/dist/lib/thenable.js.map +1 -0
- package/dist/lib/translation-review.d.ts +7 -2
- package/dist/lib/translation-review.js +4 -4
- package/dist/lib/translation-review.js.map +1 -1
- package/dist/notifications/device-zone-report.js +1 -1
- package/dist/notifications/device-zone-report.js.map +1 -1
- package/dist/notifications/notification-bell.d.ts +2 -1
- package/dist/notifications/notification-bell.js +3 -3
- package/dist/notifications/notification-bell.js.map +1 -1
- package/dist/notifications/notification-inbox.d.ts +10 -6
- package/dist/notifications/notification-inbox.js +26 -48
- package/dist/notifications/notification-inbox.js.map +1 -1
- package/dist/notifications/notification-parts.d.ts +3 -2
- package/dist/notifications/notification-parts.js +1 -3
- package/dist/notifications/notification-parts.js.map +1 -1
- package/dist/notifications/notification-types-setting.js +1 -1
- package/dist/notifications/notification-types-setting.js.map +1 -1
- package/dist/notifications/notifications-labels.d.ts +6 -0
- package/dist/notifications/notifications-labels.js +1 -0
- package/dist/notifications/notifications-labels.js.map +1 -1
- package/dist/notifications/push-device-setting.js +1 -1
- package/dist/notifications/push-device-setting.js.map +1 -1
- package/dist/notifications/push-devices-setting.d.ts +2 -1
- package/dist/notifications/push-devices-setting.js +27 -49
- package/dist/notifications/push-devices-setting.js.map +1 -1
- package/dist/notifications/quiet-hours-setting.d.ts +10 -3
- package/dist/notifications/quiet-hours-setting.js +65 -26
- package/dist/notifications/quiet-hours-setting.js.map +1 -1
- package/dist/notifications/unsubscribe-panel.js +4 -7
- package/dist/notifications/unsubscribe-panel.js.map +1 -1
- package/dist/notifications/use-push-device.d.ts +39 -1
- package/dist/notifications/use-push-device.js +28 -7
- package/dist/notifications/use-push-device.js.map +1 -1
- package/dist/offline/query-persistence.d.ts +3 -1
- package/dist/offline/query-persistence.js +19 -2
- package/dist/offline/query-persistence.js.map +1 -1
- package/dist/rhf/fields.d.ts +11 -4
- package/dist/rhf/fields.js.map +1 -1
- package/dist/search/command-palette.js +1 -1
- package/dist/search/command-palette.js.map +1 -1
- package/dist/search/global-search.js +19 -9
- package/dist/search/global-search.js.map +1 -1
- package/dist/search/use-command-key.d.ts +12 -1
- package/dist/search/use-command-key.js +3 -12
- package/dist/search/use-command-key.js.map +1 -1
- package/dist/search.d.ts +7 -0
- package/dist/search.js +10 -0
- package/dist/search.js.map +1 -1
- package/dist/settings/use-settings-focus.js +1 -0
- package/dist/settings/use-settings-focus.js.map +1 -1
- package/dist/shell/account-menu-language.d.ts +21 -5
- package/dist/shell/account-menu-language.js +3 -1
- package/dist/shell/account-menu-language.js.map +1 -1
- package/dist/shell/account-menu-text-size.d.ts +26 -9
- package/dist/shell/account-menu-text-size.js +3 -2
- package/dist/shell/account-menu-text-size.js.map +1 -1
- package/dist/shell/dev-menu.js +5 -18
- package/dist/shell/dev-menu.js.map +1 -1
- package/dist/shell/role-switcher.d.ts +7 -0
- package/dist/shell/role-switcher.js.map +1 -1
- package/dist/shell/top-bar-actions.d.ts +1 -1
- package/dist/shell/top-bar-actions.js.map +1 -1
- package/dist/shell/top-bar-parts-labels.d.ts +0 -2
- package/dist/shell/top-bar-parts-labels.js +0 -1
- package/dist/shell/top-bar-parts-labels.js.map +1 -1
- package/dist/shell.d.ts +27 -8
- package/dist/shell.js +28 -7
- package/dist/shell.js.map +1 -1
- package/dist/sync/engine.d.ts +30 -4
- package/dist/sync/engine.js +172 -52
- package/dist/sync/engine.js.map +1 -1
- package/dist/sync.d.ts +6 -2
- package/dist/sync.js +6 -1
- package/dist/sync.js.map +1 -1
- package/dist/testing/css-variables.js +3 -8
- package/dist/testing/css-variables.js.map +1 -1
- package/dist/theme/contrast.d.ts +2 -1
- package/dist/theme/contrast.js +3 -8
- package/dist/theme/contrast.js.map +1 -1
- package/dist/theme/palette-store.js +6 -6
- package/dist/theme/palette-store.js.map +1 -1
- package/dist/theme/text-size.js +3 -8
- package/dist/theme/text-size.js.map +1 -1
- package/dist/theme/theme-store.js +3 -6
- package/dist/theme/theme-store.js.map +1 -1
- package/dist/tour/tour-catalogue.d.ts +7 -4
- package/dist/tour/tour-catalogue.js +12 -10
- package/dist/tour/tour-catalogue.js.map +1 -1
- package/dist/tour/tour-dock.d.ts +0 -2
- package/dist/tour/tour-dock.js +0 -2
- package/dist/tour/tour-dock.js.map +1 -1
- package/dist/tour/tour-gates.d.ts +4 -0
- package/dist/tour/tour-gates.js +14 -0
- package/dist/tour/tour-gates.js.map +1 -1
- package/dist/tour/tour-overlay.d.ts +27 -0
- package/dist/tour/tour-overlay.js +741 -0
- package/dist/tour/tour-overlay.js.map +1 -0
- package/dist/tour/tour.d.ts +13 -3
- package/dist/tour/tour.js +59 -781
- package/dist/tour/tour.js.map +1 -1
- package/dist/tour/use-tour-progress.js +1 -1
- package/dist/tour/use-tour-progress.js.map +1 -1
- package/dist/wizard/stepper-nav.d.ts +5 -1
- package/dist/wizard/stepper-nav.js.map +1 -1
- package/dist/wizard/types.d.ts +6 -2
- package/dist/wizard/types.js.map +1 -1
- package/dist/wizard/use-wizard.d.ts +3 -1
- package/dist/wizard/use-wizard.js.map +1 -1
- package/dist/wizard/validation.d.ts +3 -1
- package/dist/wizard/validation.js.map +1 -1
- package/package.json +10 -6
- package/src/account/account-parts.ts +5 -25
- package/src/account/data-export-setting-labels.ts +1 -1
- package/src/account/delete-account-setting-labels.ts +1 -1
- package/src/account/email-change-setting-labels.ts +1 -1
- package/src/account/passkeys-setting.tsx +60 -38
- package/src/account/sessions-setting.tsx +18 -12
- package/src/admin/admin-action-confirm.tsx +1 -5
- package/src/admin/admin-parts.ts +11 -25
- package/src/admin/mail-test-card-labels.ts +1 -1
- package/src/admin/plan-change-labels.ts +5 -23
- package/src/admin/plan-change.tsx +7 -44
- package/src/admin/reviewer-scope-editor.tsx +3 -3
- package/src/auth/auth-errors-labels.ts +23 -0
- package/src/auth/auth-errors.ts +11 -38
- package/src/auth/complete-name-dialog.tsx +4 -1
- package/src/auth/forgot-password-form-labels.ts +1 -1
- package/src/auth/forgot-password-form.tsx +11 -6
- package/src/auth/register-form-labels.ts +1 -1
- package/src/auth/reset-password-form-labels.ts +1 -1
- package/src/auth/reset-password-form.tsx +8 -4
- package/src/auth/sign-in-form-labels.ts +1 -1
- package/src/auth/status-parts.tsx +0 -6
- package/src/auth/verify-email-labels.ts +1 -1
- package/src/auth/verify-email.tsx +11 -6
- package/src/billing/cancel-subscription.tsx +26 -12
- package/src/billing/dialog-close.ts +34 -0
- package/src/billing/plan-card.tsx +36 -11
- package/src/billing/plan-change-labels.ts +66 -0
- package/src/billing/plan-switch.tsx +26 -12
- package/src/chart.ts +21 -3
- package/src/components/account-chips.tsx +20 -23
- package/src/components/alert-banner.tsx +82 -5
- package/src/components/amount-input.tsx +18 -7
- package/src/components/autocomplete.tsx +64 -70
- package/src/components/bulk-action-bar.tsx +70 -2
- package/src/components/button-look.ts +5 -5
- package/src/components/button.tsx +2 -2
- package/src/components/chart-edge.ts +34 -1
- package/src/components/chart-figure.tsx +35 -0
- package/src/components/chart-zoom-core.tsx +6 -5
- package/src/components/chart.tsx +26 -5
- package/src/components/combobox-core.tsx +293 -62
- package/src/components/combobox.tsx +183 -153
- package/src/components/copy-button.tsx +34 -23
- package/src/components/country-select.tsx +16 -11
- package/src/components/data-table-column-settings.tsx +52 -10
- package/src/components/data-table-filters.ts +6 -4
- package/src/components/data-table-fit.ts +19 -5
- package/src/components/data-table-groups.tsx +1 -1
- package/src/components/data-table-head.tsx +32 -22
- package/src/components/data-table-mobile.tsx +61 -26
- package/src/components/data-table-pagination.tsx +21 -6
- package/src/components/data-table-resize.ts +1 -1
- package/src/components/data-table-row-actions.tsx +3 -3
- package/src/components/data-table-row.tsx +25 -14
- package/src/components/data-table-selection.ts +1 -1
- package/src/components/data-table-shared.tsx +33 -1
- package/src/components/data-table-sort.ts +57 -2
- package/src/components/data-table-virtual.ts +32 -8
- package/src/components/data-table.tsx +239 -68
- package/src/components/date-field.tsx +65 -8
- package/src/components/date-picker.tsx +125 -48
- package/src/components/date-range-picker.tsx +82 -31
- package/src/components/error-boundary.tsx +53 -39
- package/src/components/field-base-labels.ts +20 -0
- package/src/components/field-base.tsx +13 -7
- package/src/components/field-sync-labels.ts +1 -0
- package/src/components/field-sync.tsx +23 -1
- package/src/components/form-actions.tsx +20 -5
- package/src/components/hover-menu.tsx +18 -8
- package/src/components/icon-button.tsx +14 -9
- package/src/components/inline-confirm.tsx +116 -0
- package/src/components/inline-entity-combobox.tsx +197 -153
- package/src/components/input.tsx +1 -1
- package/src/components/jump-calendar.tsx +30 -146
- package/src/components/legal-page.tsx +10 -7
- package/src/components/legal.tsx +4 -2
- package/src/components/lightbox.tsx +21 -8
- package/src/components/list.tsx +10 -4
- package/src/components/measured-grid.tsx +8 -4
- package/src/components/mini-calendar.tsx +6 -5
- package/src/components/modal.tsx +6 -1
- package/src/components/month-grid.tsx +229 -0
- package/src/components/month-picker.tsx +192 -200
- package/src/components/multi-select.tsx +21 -9
- package/src/components/picker-sheet.tsx +12 -9
- package/src/components/pie-chart-labels.ts +8 -0
- package/src/components/pie-chart.tsx +22 -28
- package/src/components/popover.tsx +18 -1
- package/src/components/row-actions.tsx +2 -1
- package/src/components/section-nav.tsx +7 -0
- package/src/components/series-chart-axes.ts +3 -3
- package/src/components/series-chart-labels.ts +7 -4
- package/src/components/series-chart.tsx +178 -69
- package/src/components/share-card.tsx +6 -6
- package/src/components/sign-chip-labels.ts +1 -0
- package/src/components/sign-chip.tsx +10 -1
- package/src/components/tabs-labels.ts +13 -0
- package/src/components/tabs.tsx +2 -2
- package/src/components/toggle-legend.tsx +16 -11
- package/src/components/translation-review-editor.tsx +6 -5
- package/src/components/translation-review.tsx +4 -3
- package/src/components/treemap-labels.ts +39 -0
- package/src/components/treemap-layout.ts +210 -0
- package/src/components/treemap.tsx +722 -133
- package/src/components/use-table-state.ts +12 -9
- package/src/data-table.ts +9 -2
- package/src/eslint/role-utilities.ts +97 -19
- package/src/feedback/feedback-dialog.tsx +30 -19
- package/src/feedback/feedback-mutation.ts +41 -0
- package/src/feedback/feedback-page-link.ts +90 -0
- package/src/feedback/feedback-public-list.tsx +17 -5
- package/src/feedback/feedback-replies.tsx +13 -6
- package/src/feedback/feedback-row-detail-labels.ts +5 -0
- package/src/feedback/feedback-row-detail.tsx +103 -67
- package/src/feedback/feedback-status-undo.ts +41 -27
- package/src/feedback/feedback-submit-dialog.tsx +2 -2
- package/src/feedback/feedback-submit.tsx +21 -7
- package/src/feedback/feedback-swipe.tsx +1 -1
- package/src/feedback/feedback-table.tsx +86 -38
- package/src/feedback/feedback-thread-labels.ts +2 -2
- package/src/feedback/feedback-thread.tsx +27 -25
- package/src/feedback.ts +42 -0
- package/src/hooks/use-focus-trap.ts +8 -24
- package/src/hooks/use-hotkey.ts +24 -7
- package/src/hooks/use-long-press.ts +16 -2
- package/src/hooks/use-media-query.ts +20 -4
- package/src/hooks/use-mounted.ts +39 -0
- package/src/hooks/use-overlay-history.ts +32 -3
- package/src/i18n/defaults.ts +4 -5
- package/src/i18n/german.ts +8 -2
- package/src/i18n/kit-labels.tsx +9 -2
- package/src/i18n/locales/es.ts +8 -2
- package/src/i18n/locales/fr.ts +21 -13
- package/src/i18n/locales/hu.ts +10 -2
- package/src/i18n/locales/it.ts +8 -2
- package/src/i18n/locales/zh.ts +9 -2
- package/src/i18n/review.ts +5 -0
- package/src/index.ts +103 -13
- package/src/landing/routing.tsx +14 -10
- package/src/lib/broadcast.ts +52 -0
- package/src/lib/date-format.ts +89 -13
- package/src/lib/day-format.ts +96 -0
- package/src/lib/describe-failure.ts +18 -0
- package/src/lib/direction.ts +39 -0
- package/src/lib/focus-left.ts +156 -0
- package/src/lib/format.ts +5 -17
- package/src/lib/http-status.ts +38 -0
- package/src/lib/intl-cache.ts +25 -0
- package/src/lib/isin.ts +10 -0
- package/src/lib/iso-day.ts +13 -0
- package/src/lib/lazy-with-fallback.ts +82 -0
- package/src/lib/path-pattern.ts +55 -0
- package/src/lib/reduced-motion.ts +2 -1
- package/src/lib/round.ts +7 -2
- package/src/lib/safe-storage.ts +48 -6
- package/src/lib/session-refresh.ts +1 -1
- package/src/lib/share-format.ts +18 -0
- package/src/lib/text-case.ts +19 -0
- package/src/lib/text-match.ts +57 -2
- package/src/lib/thenable.ts +19 -0
- package/src/lib/translation-review.ts +13 -5
- package/src/notifications/device-zone-report.ts +1 -1
- package/src/notifications/notification-bell.tsx +7 -4
- package/src/notifications/notification-inbox.tsx +40 -58
- package/src/notifications/notification-parts.tsx +3 -4
- package/src/notifications/notification-types-setting.tsx +1 -1
- package/src/notifications/notifications-labels.ts +7 -0
- package/src/notifications/push-device-setting.tsx +1 -1
- package/src/notifications/push-devices-setting.tsx +30 -55
- package/src/notifications/quiet-hours-setting.tsx +93 -31
- package/src/notifications/unsubscribe-panel.tsx +4 -7
- package/src/notifications/use-push-device.ts +76 -10
- package/src/offline/query-persistence.ts +35 -3
- package/src/rhf/fields.tsx +11 -4
- package/src/search/command-palette.tsx +2 -4
- package/src/search/global-search.tsx +36 -15
- package/src/search/use-command-key.ts +13 -12
- package/src/search.ts +9 -0
- package/src/settings/use-settings-focus.ts +3 -0
- package/src/shell/account-menu-language.tsx +27 -5
- package/src/shell/account-menu-text-size.tsx +32 -10
- package/src/shell/dev-menu.tsx +7 -21
- package/src/shell/role-switcher.tsx +7 -0
- package/src/shell/top-bar-actions.tsx +1 -1
- package/src/shell/top-bar-parts-labels.ts +0 -3
- package/src/shell.ts +40 -9
- package/src/sync/engine.ts +339 -61
- package/src/sync.ts +8 -1
- package/src/testing/css-variables.ts +8 -9
- package/src/theme/contrast.ts +8 -9
- package/src/theme/palette-store.ts +9 -9
- package/src/theme/text-size.ts +6 -8
- package/src/theme/theme-store.ts +7 -9
- package/src/tour/tour-catalogue.tsx +26 -15
- package/src/tour/tour-dock.ts +0 -2
- package/src/tour/tour-gates.ts +23 -0
- package/src/tour/tour-overlay.tsx +1170 -0
- package/src/tour/tour.tsx +108 -1202
- package/src/tour/use-tour-progress.ts +1 -1
- package/src/wizard/stepper-nav.tsx +3 -1
- package/src/wizard/types.ts +11 -2
- package/src/wizard/use-wizard.ts +2 -1
- package/src/wizard/validation.ts +8 -2
- package/tokens.css +2 -1
- package/dist/components/ui-labels.js.map +0 -1
- package/dist/shell/dev-switchers.d.ts +0 -6
- package/dist/shell/dev-switchers.js +0 -12
- package/dist/shell/dev-switchers.js.map +0 -1
- package/src/components/ui-labels.ts +0 -24
- package/src/shell/dev-switchers.tsx +0 -18
|
@@ -1,9 +1,10 @@
|
|
|
1
1
|
import type { ReactElement, ReactNode } from "react";
|
|
2
2
|
import type { LucideIcon } from "lucide-react";
|
|
3
3
|
import { cn } from "../lib/cn";
|
|
4
|
-
import {
|
|
4
|
+
import { toDate, useKitFormat, EMPTY_FORMATTED_VALUE } from "../lib/format";
|
|
5
5
|
import type { DateInput, FormatDateStyle, FormatRelativeTimeOptions } from "../lib/format";
|
|
6
|
-
import {
|
|
6
|
+
import { useDayFormatter } from "../lib/day-format";
|
|
7
|
+
import { useKitLabels, type LabelOverride } from "../i18n/kit-labels";
|
|
7
8
|
import { toLocalIso } from "../lib/dates";
|
|
8
9
|
import { Chip } from "./chip";
|
|
9
10
|
import type { ChipLinkProps, ChipShape, ChipSize, ChipTone, ChipVariant } from "./chip";
|
|
@@ -292,17 +293,15 @@ export function AccountStateChip({
|
|
|
292
293
|
// An `undefined` in the prop is skipped (the provider's merge does that), so an
|
|
293
294
|
// optional value cannot blank a default.
|
|
294
295
|
const labels = useKitLabels("accountState", DEFAULT_ACCOUNT_STATE_LABELS, labelsProp);
|
|
295
|
-
|
|
296
|
-
|
|
296
|
+
// The kit's one day ladder: the provider's `formatDate`, else `Intl` in the provider's
|
|
297
|
+
// locale and `timeZone` (refactor audit 2026-10-30, DUP-2).
|
|
298
|
+
const day = useDayFormatter(null, localeProp);
|
|
297
299
|
const when = state === "deletion" ? toDate(date ?? null) : null;
|
|
298
300
|
let text: ReactNode;
|
|
299
301
|
if (state !== "deletion") text = labels[state];
|
|
300
302
|
else if (when) {
|
|
301
303
|
// A date in a SENTENCE, so no weekday (keksdose's rule, KitDateFormatContext).
|
|
302
|
-
|
|
303
|
-
(fromProvider && fromProvider(toLocalIso(when), { unit: "day", source: "dateMark", locale, weekday: false })) ||
|
|
304
|
-
formatDate(when, "medium", { locale });
|
|
305
|
-
text = (labels.deletionOn ?? DEFAULT_ACCOUNT_STATE_LABELS.deletionOn)(day);
|
|
304
|
+
text = (labels.deletionOn ?? DEFAULT_ACCOUNT_STATE_LABELS.deletionOn)(day(date));
|
|
306
305
|
} else text = labels.deletion ?? DEFAULT_ACCOUNT_STATE_LABELS.deletion;
|
|
307
306
|
return (
|
|
308
307
|
<Chip
|
|
@@ -355,14 +354,14 @@ export interface DateMarkProps {
|
|
|
355
354
|
|
|
356
355
|
/**
|
|
357
356
|
* A date in a table cell: a `<time>` with a machine-readable `dateTime`, nowrap and
|
|
358
|
-
* tabular figures, in the provider's locale — or `empty` when there is none.
|
|
357
|
+
* tabular figures, in the provider's locale and `timeZone` — or `empty` when there is none.
|
|
359
358
|
*
|
|
360
359
|
* `display="date"` without a `dateStyle` is written by `<UiKitProvider formatDate>` when
|
|
361
360
|
* the app set one (keksdose K12: its `DateCell` exists to put every column's date in the
|
|
362
|
-
* app's date-format preference, weekday and all — dev#546), called with the
|
|
363
|
-
*
|
|
364
|
-
* an empty answer, it is `Intl`'s `medium` date as
|
|
365
|
-
* a calendar day and keeps `formatRelativeTime`.
|
|
361
|
+
* app's date-format preference, weekday and all — dev#546), called with the calendar day
|
|
362
|
+
* of the value as `"YYYY-MM-DD"` (in the provider's `timeZone`, else the device's) and
|
|
363
|
+
* `weekday: true`. Without one, or for an empty answer, it is `Intl`'s `medium` date as
|
|
364
|
+
* before. The relative display is not a calendar day and keeps `formatRelativeTime`.
|
|
366
365
|
*/
|
|
367
366
|
export function DateMark({
|
|
368
367
|
value,
|
|
@@ -374,27 +373,25 @@ export function DateMark({
|
|
|
374
373
|
locale: localeProp,
|
|
375
374
|
className,
|
|
376
375
|
}: DateMarkProps) {
|
|
377
|
-
|
|
378
|
-
|
|
376
|
+
// The provider's `timeZone` (0.46) as well as its locale, also for the relative words
|
|
377
|
+
// and the exact line (refactor audit 2026-10-30, DUP-2: the raw formatters ignored it).
|
|
378
|
+
const { formatDate, formatRelativeTime } = useKitFormat(localeProp);
|
|
379
|
+
const day = useDayFormatter(null, localeProp);
|
|
379
380
|
const date = toDate(value);
|
|
380
381
|
const cls = cn("whitespace-nowrap tabular-nums", className);
|
|
381
382
|
if (!date) return <span className={cn(cls, "text-muted")}>{empty}</span>;
|
|
382
383
|
if (display === "date") {
|
|
383
|
-
const own =
|
|
384
|
-
dateStyle === undefined && fromProvider
|
|
385
|
-
? fromProvider(toLocalIso(date), { unit: "day", source: "dateMark", locale, weekday: true })
|
|
386
|
-
: "";
|
|
387
384
|
return (
|
|
388
385
|
<time dateTime={date.toISOString()} className={cls}>
|
|
389
|
-
{
|
|
386
|
+
{day(value, { weekday: true, style: dateStyle ?? "medium", preference: dateStyle === undefined })}
|
|
390
387
|
</time>
|
|
391
388
|
);
|
|
392
389
|
}
|
|
393
|
-
const text = formatRelativeTime(date, { ...relative,
|
|
394
|
-
const exact = formatDate(date, dateStyle ?? "dateTime"
|
|
390
|
+
const text = formatRelativeTime(date, { ...relative, absoluteStyle: dateStyle ?? "medium" });
|
|
391
|
+
const exact = formatDate(date, dateStyle ?? "dateTime");
|
|
395
392
|
// Past `absoluteAfterDays` the relative words already ARE the date; then the exact
|
|
396
393
|
// line alone, rather than the same day twice.
|
|
397
|
-
const sameDay = text === formatDate(date, dateStyle ?? "medium"
|
|
394
|
+
const sameDay = text === formatDate(date, dateStyle ?? "medium");
|
|
398
395
|
const iso = date.toISOString();
|
|
399
396
|
if (sameDay) {
|
|
400
397
|
return (
|
|
@@ -1,9 +1,10 @@
|
|
|
1
|
-
import { useId, useLayoutEffect, useRef, useState } from "react";
|
|
2
|
-
import type { ComponentPropsWithoutRef, MouseEvent, ReactNode, Ref } from "react";
|
|
1
|
+
import { useEffect, useId, useLayoutEffect, useRef, useState } from "react";
|
|
2
|
+
import type { ComponentPropsWithoutRef, MouseEvent, ReactNode, Ref, RefObject } from "react";
|
|
3
3
|
import { AlertTriangle, CheckCircle2, ChevronRight, Info, X } from "lucide-react";
|
|
4
4
|
import { cn } from "../lib/cn";
|
|
5
5
|
import { FOCUS_RING } from "./focus-ring";
|
|
6
6
|
import { DEFAULT_COMMON_LABELS, useKitLabels } from "../i18n/kit-labels";
|
|
7
|
+
import { focusFirst, focusIsLost, tabStopsAround, whenFocusLeftForNothing } from "../lib/focus-left";
|
|
7
8
|
|
|
8
9
|
/** `info` (0.8.0) is the sky family, for news that is neither good nor bad: keksdose's
|
|
9
10
|
* preview and beta-performance banners, which borrowed `warning` for want of it and
|
|
@@ -185,10 +186,21 @@ interface AlertBannerBaseProps extends Omit<ComponentPropsWithoutRef<"div">, "on
|
|
|
185
186
|
/** Replaces the tone's glyph — a `<Spinner label={null} />` for "Solving…", say.
|
|
186
187
|
* `null` draws none. Always decorative; the text carries the message. */
|
|
187
188
|
icon?: ReactNode;
|
|
188
|
-
/**
|
|
189
|
-
*
|
|
190
|
-
*
|
|
189
|
+
/**
|
|
190
|
+
* Renders an × at the end that calls this. The banner does not hide itself — the
|
|
191
|
+
* caller removes it (and remembers that it did), as with every other kit control
|
|
192
|
+
* whose state is app state.
|
|
193
|
+
*
|
|
194
|
+
* The focus (0.52, refactor audit 2026-10-30, DSP-15): the × that held it goes with the
|
|
195
|
+
* banner, and it fell to `<body>`. When the banner unmounts after its × was pressed and
|
|
196
|
+
* the focus has nowhere else, it moves on to the next control after the banner — where
|
|
197
|
+
* Tab from the × would have gone — or, at the end of the page, the one before it; to
|
|
198
|
+
* {@link dismissFocusRef} when given. A banner the caller keeps keeps its ×'s focus.
|
|
199
|
+
*/
|
|
191
200
|
onDismiss?: () => void;
|
|
201
|
+
/** Where the focus goes once the × has removed the banner (DSP-15) — a heading, the
|
|
202
|
+
* control the banner was about. Default: the next control after the banner. */
|
|
203
|
+
dismissFocusRef?: RefObject<HTMLElement | null>;
|
|
192
204
|
/** Accessible name of the ×. Default: `common.dismiss` from the
|
|
193
205
|
* {@link UiKitProvider}, else "Dismiss". */
|
|
194
206
|
dismissLabel?: string;
|
|
@@ -278,6 +290,7 @@ export function AlertBanner({
|
|
|
278
290
|
action,
|
|
279
291
|
icon,
|
|
280
292
|
onDismiss,
|
|
293
|
+
dismissFocusRef,
|
|
281
294
|
dismissLabel,
|
|
282
295
|
clampMobile = false,
|
|
283
296
|
actionPlacement = "own-line",
|
|
@@ -318,6 +331,36 @@ export function AlertBanner({
|
|
|
318
331
|
return () => ro?.disconnect();
|
|
319
332
|
}, [clamp, expanded, children]);
|
|
320
333
|
|
|
334
|
+
// The ×'s focus, once the caller has removed the banner (DSP-15). Where it can go is read
|
|
335
|
+
// at the press, while the banner still has a place in the page to measure from; whether
|
|
336
|
+
// it must is decided at the unmount, in the cleanup of a passive effect — after React has
|
|
337
|
+
// taken the banner's DOM away, when a focus that fell with it is on <body>.
|
|
338
|
+
const dismissedFrom = useRef<HTMLElement[] | null>(null);
|
|
339
|
+
const dismissTarget = useRef(dismissFocusRef);
|
|
340
|
+
useLayoutEffect(() => {
|
|
341
|
+
dismissTarget.current = dismissFocusRef;
|
|
342
|
+
});
|
|
343
|
+
// The note lives until the focus lands outside the banner (0.52 code review,
|
|
344
|
+
// alert-banner.tsx). A caller that keeps the banner — an async dismiss that failed, a
|
|
345
|
+
// snooze — left it standing, and the banner's unmount long after, a route change with
|
|
346
|
+
// the focus on <body>, sent the focus to a stop noted at the press, over the app's own
|
|
347
|
+
// handling of a new page. A `focusin` on the document, not a `focusout` on the banner:
|
|
348
|
+
// a browser that blurs a removed node would drop the note at the very removal it is for.
|
|
349
|
+
// The one `focusout` heard is a move to nothing — a click on the page — and only once a
|
|
350
|
+
// microtask has shown the × still in place (`whenFocusLeftForNothing`). A focus that
|
|
351
|
+
// stays on the × keeps the note, however late the removal: that is DSP-15's own case,
|
|
352
|
+
// an async dismiss whose request resolves.
|
|
353
|
+
const unwatchFocus = useRef<(() => void) | null>(null);
|
|
354
|
+
useEffect(
|
|
355
|
+
() => () => {
|
|
356
|
+
unwatchFocus.current?.();
|
|
357
|
+
const around = dismissedFrom.current;
|
|
358
|
+
if (!around || !focusIsLost()) return;
|
|
359
|
+
focusFirst([dismissTarget.current?.current, ...around]);
|
|
360
|
+
},
|
|
361
|
+
[],
|
|
362
|
+
);
|
|
363
|
+
|
|
321
364
|
const Glyph = TONE_GLYPH[tone];
|
|
322
365
|
// Onto the first line of a box's text: 2px at 14px/20px, 1px at 12px/16px.
|
|
323
366
|
const nudge = inlineRow || strip ? undefined : sm ? "mt-px" : "mt-0.5";
|
|
@@ -448,6 +491,40 @@ export function AlertBanner({
|
|
|
448
491
|
// A dismiss inside a whole-row banner must not also follow the row.
|
|
449
492
|
e.preventDefault();
|
|
450
493
|
e.stopPropagation();
|
|
494
|
+
const frame = e.currentTarget.parentElement;
|
|
495
|
+
// Only a × that holds the focus has one to lose (0.52 code review, alert-banner.tsx):
|
|
496
|
+
// Safari focuses no button on a click, nor on an iOS tap, and with the focus on
|
|
497
|
+
// <body> already the removal sent it on — a ring, on a form field the on-screen
|
|
498
|
+
// keyboard, on a page the user was reading with the pointer.
|
|
499
|
+
if (frame && e.currentTarget.ownerDocument.activeElement === e.currentTarget) {
|
|
500
|
+
const { after, before } = tabStopsAround(frame);
|
|
501
|
+
dismissedFrom.current = [...after, ...before];
|
|
502
|
+
unwatchFocus.current?.();
|
|
503
|
+
const doc = frame.ownerDocument;
|
|
504
|
+
const forget = () => {
|
|
505
|
+
dismissedFrom.current = null;
|
|
506
|
+
unwatch();
|
|
507
|
+
};
|
|
508
|
+
const onFocusIn = (event: FocusEvent) => {
|
|
509
|
+
if (event.target instanceof Node && frame.contains(event.target)) return;
|
|
510
|
+
forget();
|
|
511
|
+
};
|
|
512
|
+
// Focus that left for nothing — a click on the page — took no `focusin` with it
|
|
513
|
+
// (0.52 code review): the user moved on all the same.
|
|
514
|
+
const onFocusOut = (event: FocusEvent) => {
|
|
515
|
+
whenFocusLeftForNothing(event, () => {
|
|
516
|
+
if (unwatchFocus.current === unwatch) forget();
|
|
517
|
+
});
|
|
518
|
+
};
|
|
519
|
+
const unwatch = () => {
|
|
520
|
+
doc.removeEventListener("focusin", onFocusIn, true);
|
|
521
|
+
frame.removeEventListener("focusout", onFocusOut);
|
|
522
|
+
unwatchFocus.current = null;
|
|
523
|
+
};
|
|
524
|
+
doc.addEventListener("focusin", onFocusIn, true);
|
|
525
|
+
frame.addEventListener("focusout", onFocusOut);
|
|
526
|
+
unwatchFocus.current = unwatch;
|
|
527
|
+
}
|
|
451
528
|
onDismiss();
|
|
452
529
|
}}
|
|
453
530
|
className={cn(
|
|
@@ -338,17 +338,28 @@ function settleAmount(text: string, digits: number | undefined, min?: number, ma
|
|
|
338
338
|
// `lib/decimal-marks.ts`, read through the engine NumberInput and this field share
|
|
339
339
|
// (`numeric-field.ts`, DUP-10).
|
|
340
340
|
|
|
341
|
-
|
|
342
|
-
|
|
343
|
-
|
|
344
|
-
|
|
345
|
-
|
|
346
|
-
|
|
347
|
-
|
|
341
|
+
/**
|
|
342
|
+
* The figure's colour per {@link AmountInputProps.tone} — public as `AMOUNT_TONE_CLASS`,
|
|
343
|
+
* for a table cell or a test that must paint the same figure the same way (keksdose's
|
|
344
|
+
* receipt lines, dev#556).
|
|
345
|
+
*
|
|
346
|
+
* The consuming app's ONE money palette (`--money-expense` / `--money-income`), not a
|
|
347
|
+
* bespoke rose/emerald pairing: a figure being typed has to wear the same colour the same
|
|
348
|
+
* figure will wear once it is a row in the table behind the form (Keksdose dev#434). The
|
|
349
|
+
* utilities are unlayered and theme-aware, so no `dark:` variant is needed and they win
|
|
350
|
+
* over the field's own text colour regardless of where `cn` puts them.
|
|
351
|
+
*/
|
|
352
|
+
const TONE_CLASS: Readonly<Record<NonNullable<AmountInputProps["tone"]>, string>> = {
|
|
348
353
|
neutral: "",
|
|
349
354
|
outflow: "text-money-neg",
|
|
350
355
|
inflow: "text-money-pos",
|
|
351
356
|
};
|
|
357
|
+
// Exported in 0.52 because keksdose's tests read it out of dist/components/amount-input.js
|
|
358
|
+
// with a regex for `const TONE_CLASS` — the one reach into the kit's dist in three apps,
|
|
359
|
+
// which a rename or a moved module breaks with no public change (MOD-8, refactor audit
|
|
360
|
+
// 2026-10-30; 0.34's move failed 91 of keksdose's test files that way). The local name
|
|
361
|
+
// stays until keksdose imports the export, so the bump itself breaks nothing.
|
|
362
|
+
export { TONE_CLASS as AMOUNT_TONE_CLASS };
|
|
352
363
|
|
|
353
364
|
// The shared chrome-less treatment at money size. `tabular-nums` so digits don't
|
|
354
365
|
// reflow the figure as they are typed; FIELD_DISPLAY's own muted placeholder
|
|
@@ -1,7 +1,8 @@
|
|
|
1
|
-
import {
|
|
1
|
+
import { useId, useRef, useState } from "react";
|
|
2
2
|
import type { ComponentPropsWithoutRef, ReactNode, Ref } from "react";
|
|
3
3
|
import { createPortal } from "react-dom";
|
|
4
4
|
import { cn } from "../lib/cn";
|
|
5
|
+
import { hasContent } from "../lib/presence";
|
|
5
6
|
import { FIELD_BASE, FIELD_FLOATING_PAD, FIELD_INVALID } from "./field-base";
|
|
6
7
|
import { Spinner } from "./spinner";
|
|
7
8
|
import { useAnchoredPanel } from "../hooks/use-anchored-panel";
|
|
@@ -10,10 +11,12 @@ import { isImeEnter } from "../lib/ime";
|
|
|
10
11
|
import { isQuietFocus } from "../lib/quiet-focus";
|
|
11
12
|
import { useAnchorDir } from "./use-anchor-dir";
|
|
12
13
|
import {
|
|
14
|
+
anchoredHeadingClass,
|
|
13
15
|
ComboboxFieldLabel,
|
|
14
16
|
DISABLED_ROW_CLASS,
|
|
15
17
|
endHintRowProps,
|
|
16
|
-
|
|
18
|
+
GroupedOptions,
|
|
19
|
+
groupRuns,
|
|
17
20
|
isOptionEnabled,
|
|
18
21
|
stepEnabled,
|
|
19
22
|
SUGGESTION_LIST_CLASS,
|
|
@@ -293,7 +296,7 @@ export function Autocomplete<V extends string | number = string>(props: Autocomp
|
|
|
293
296
|
active: live,
|
|
294
297
|
});
|
|
295
298
|
|
|
296
|
-
const hasStatus = status
|
|
299
|
+
const hasStatus = hasContent(status);
|
|
297
300
|
// The visible line under the rows. Nothing below `minChars` unless the caller has
|
|
298
301
|
// something to say — an empty field opening a box that says "type more" is noise.
|
|
299
302
|
const statusLine: ReactNode = hasStatus
|
|
@@ -559,75 +562,66 @@ export function Autocomplete<V extends string | number = string>(props: Autocomp
|
|
|
559
562
|
aria-labelledby={labelledBy}
|
|
560
563
|
className="min-h-0 flex-1 overflow-y-auto py-1"
|
|
561
564
|
>
|
|
562
|
-
{
|
|
563
|
-
|
|
564
|
-
|
|
565
|
-
|
|
566
|
-
|
|
567
|
-
|
|
568
|
-
|
|
569
|
-
|
|
570
|
-
|
|
571
|
-
|
|
572
|
-
|
|
573
|
-
|
|
574
|
-
|
|
575
|
-
|
|
576
|
-
|
|
577
|
-
|
|
578
|
-
|
|
579
|
-
|
|
580
|
-
|
|
581
|
-
|
|
582
|
-
|
|
583
|
-
|
|
584
|
-
|
|
585
|
-
|
|
586
|
-
|
|
587
|
-
|
|
588
|
-
|
|
589
|
-
//
|
|
590
|
-
|
|
591
|
-
|
|
592
|
-
|
|
593
|
-
|
|
594
|
-
|
|
595
|
-
|
|
596
|
-
|
|
597
|
-
|
|
598
|
-
|
|
599
|
-
|
|
600
|
-
|
|
601
|
-
|
|
602
|
-
|
|
603
|
-
|
|
604
|
-
|
|
605
|
-
|
|
606
|
-
|
|
607
|
-
|
|
608
|
-
|
|
609
|
-
|
|
610
|
-
|
|
565
|
+
{/* One heading per group, a `role="group"` it names, as in the core panel
|
|
566
|
+
(refactor audit 2026-10-30, INP-8), drawn by the same renderer: an
|
|
567
|
+
option may appear once per group. */}
|
|
568
|
+
<GroupedOptions
|
|
569
|
+
runs={groupRuns(results, (o) => o.group)}
|
|
570
|
+
listboxId={listboxId}
|
|
571
|
+
rowKey={(o) => String(o.value)}
|
|
572
|
+
headingClassName={(run) => anchoredHeadingClass(run)}
|
|
573
|
+
row={(o, i) => (
|
|
574
|
+
<li role="presentation">
|
|
575
|
+
<button
|
|
576
|
+
type="button"
|
|
577
|
+
id={optionId(i)}
|
|
578
|
+
role="option"
|
|
579
|
+
// CHOSEN, never "highlighted" — the family's rule. This
|
|
580
|
+
// field holds no value, so the only row that can be chosen
|
|
581
|
+
// is the one whose label the text already is.
|
|
582
|
+
aria-selected={fillOnSelect && o.label === value}
|
|
583
|
+
// Listed, announced as unavailable, never taken: `take`
|
|
584
|
+
// refuses it and the arrows pass it over.
|
|
585
|
+
aria-disabled={o.disabled || undefined}
|
|
586
|
+
tabIndex={-1}
|
|
587
|
+
onClick={() => take(o)}
|
|
588
|
+
onMouseEnter={() => {
|
|
589
|
+
if (!o.disabled) setActive(i);
|
|
590
|
+
}}
|
|
591
|
+
className={cn(
|
|
592
|
+
// The family's suggestion row (DUP-4): it hand-rolled its
|
|
593
|
+
// own with a plain `truncate`, so a long address was cut at
|
|
594
|
+
// Large, where Combobox's rows wrap (text size §10.17, T1).
|
|
595
|
+
// A flex row here, for the icon and the two lines.
|
|
596
|
+
suggestionRowClass(i === active && !o.disabled),
|
|
597
|
+
"flex items-center gap-2",
|
|
598
|
+
small && "py-1 text-xs",
|
|
599
|
+
o.disabled && DISABLED_ROW_CLASS,
|
|
600
|
+
o.group && "ps-6",
|
|
601
|
+
)}
|
|
602
|
+
>
|
|
603
|
+
{o.icon && (
|
|
604
|
+
<span aria-hidden className="shrink-0 text-muted">
|
|
605
|
+
{o.icon}
|
|
606
|
+
</span>
|
|
607
|
+
)}
|
|
608
|
+
<span className="min-w-0 flex-1">
|
|
609
|
+
<span className="block truncate-until-large text-primary">{o.label}</span>
|
|
610
|
+
{o.sublabel && (
|
|
611
|
+
<span
|
|
612
|
+
className={cn(
|
|
613
|
+
"block truncate-until-large text-placeholder",
|
|
614
|
+
small ? "text-caption" : "text-xs",
|
|
615
|
+
)}
|
|
616
|
+
>
|
|
617
|
+
{o.sublabel}
|
|
611
618
|
</span>
|
|
612
619
|
)}
|
|
613
|
-
|
|
614
|
-
|
|
615
|
-
|
|
616
|
-
|
|
617
|
-
|
|
618
|
-
"block truncate-until-large text-placeholder",
|
|
619
|
-
small ? "text-caption" : "text-xs",
|
|
620
|
-
)}
|
|
621
|
-
>
|
|
622
|
-
{o.sublabel}
|
|
623
|
-
</span>
|
|
624
|
-
)}
|
|
625
|
-
</span>
|
|
626
|
-
</button>
|
|
627
|
-
</li>
|
|
628
|
-
</Fragment>
|
|
629
|
-
);
|
|
630
|
-
})}
|
|
620
|
+
</span>
|
|
621
|
+
</button>
|
|
622
|
+
</li>
|
|
623
|
+
)}
|
|
624
|
+
/>
|
|
631
625
|
</ul>
|
|
632
626
|
)}
|
|
633
627
|
{statusLine !== null && (
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import { useEffect, useLayoutEffect, useRef, useState } from "react";
|
|
2
|
-
import type { ComponentPropsWithRef, CSSProperties, KeyboardEvent, ReactNode } from "react";
|
|
2
|
+
import type { ComponentPropsWithRef, CSSProperties, FocusEvent, KeyboardEvent, ReactNode, RefObject } from "react";
|
|
3
3
|
import { X } from "lucide-react";
|
|
4
4
|
|
|
5
5
|
import { cn } from "../lib/cn";
|
|
@@ -8,6 +8,8 @@ import { useKitLabels, type LabelOverride } from "../i18n/kit-labels";
|
|
|
8
8
|
import { useAnnounce } from "../hooks/use-announce";
|
|
9
9
|
import { useBreakpoint } from "../hooks/use-breakpoint";
|
|
10
10
|
import { OVERLAY_EXIT_MS, skipsExitAnimation } from "../hooks/use-close-transition";
|
|
11
|
+
import { focusFirst, focusIsLost, whenFocusLeftForNothing } from "../lib/focus-left";
|
|
12
|
+
import { hasContent } from "../lib/presence";
|
|
11
13
|
import { Button } from "./button";
|
|
12
14
|
import { IconButton } from "./icon-button";
|
|
13
15
|
import { DEFAULT_BULK_ACTION_BAR_LABELS } from "./bulk-action-bar-labels";
|
|
@@ -124,6 +126,16 @@ export interface BulkActionBarProps extends Omit<ComponentPropsWithRef<"div">, "
|
|
|
124
126
|
panel?: ReactNode;
|
|
125
127
|
/** Default: `bulkActionBar` from the {@link UiKitProvider}, else English. */
|
|
126
128
|
labels?: LabelOverride<BulkActionBarLabels>;
|
|
129
|
+
/**
|
|
130
|
+
* Where the focus goes when the bar leaves while it holds it — after Clear, or an action
|
|
131
|
+
* that empties the selection (0.52, refactor audit 2026-10-30, DSP-15). Without it, the
|
|
132
|
+
* control the focus came into the bar from (the row's box, say), if that is still on the
|
|
133
|
+
* page; with it, this first. Pass one where the selection takes that control with it — a
|
|
134
|
+
* bulk delete removes the rows whose boxes were ticked: the table, the list's heading,
|
|
135
|
+
* the "Select" button that entered selection mode. A bar that leaves without the focus
|
|
136
|
+
* in it moves nothing.
|
|
137
|
+
*/
|
|
138
|
+
returnFocusRef?: RefObject<HTMLElement | null>;
|
|
127
139
|
}
|
|
128
140
|
|
|
129
141
|
/** Where the floating bar sits: clear of the phone nav and of the home indicator,
|
|
@@ -192,10 +204,12 @@ export function BulkActionBar({
|
|
|
192
204
|
open,
|
|
193
205
|
panel,
|
|
194
206
|
labels: labelsProp,
|
|
207
|
+
returnFocusRef,
|
|
195
208
|
className,
|
|
196
209
|
style,
|
|
197
210
|
onKeyDown,
|
|
198
211
|
onFocus,
|
|
212
|
+
onBlur,
|
|
199
213
|
...rest
|
|
200
214
|
}: BulkActionBarProps) {
|
|
201
215
|
const labels = useKitLabels("bulkActionBar", DEFAULT_BULK_ACTION_BAR_LABELS, labelsProp);
|
|
@@ -245,6 +259,51 @@ export function BulkActionBar({
|
|
|
245
259
|
rove(barRef.current, active);
|
|
246
260
|
});
|
|
247
261
|
|
|
262
|
+
// Leaving with the focus in it (refactor audit 2026-10-30, DSP-15): the bar goes `inert`,
|
|
263
|
+
// which blurs the control it holds, then unmounts — and the focus fell to <body>; on a
|
|
264
|
+
// phone VoiceOver's cursor jumped to the top of the page (keksdose's register). Noted on
|
|
265
|
+
// the bar's outermost element, so the `panel`'s fields count: where the focus came in
|
|
266
|
+
// from (the first entry since the bar showed, replaced once that control is gone), and
|
|
267
|
+
// whether it is in the bar. Focus that leaves for nothing because the page took it —
|
|
268
|
+
// inert, a removal — still counts as in it; a real element elsewhere takes it out, and
|
|
269
|
+
// so does a click on the page that left it nowhere (0.52 code review,
|
|
270
|
+
// bulk-action-bar.tsx: the note outlived it, and the bar's hide long after — the last row
|
|
271
|
+
// unticked with the pointer — pulled the focus and the scroll back to the row's box).
|
|
272
|
+
const cameFrom = useRef<HTMLElement | null>(null);
|
|
273
|
+
const holdsFocus = useRef(false);
|
|
274
|
+
const trackFocus = {
|
|
275
|
+
onFocus: (e: FocusEvent<HTMLDivElement>) => {
|
|
276
|
+
holdsFocus.current = true;
|
|
277
|
+
const from = e.relatedTarget;
|
|
278
|
+
if (from instanceof HTMLElement && !e.currentTarget.contains(from) && !cameFrom.current?.isConnected)
|
|
279
|
+
cameFrom.current = from;
|
|
280
|
+
},
|
|
281
|
+
onBlur: (e: FocusEvent<HTMLDivElement>) => {
|
|
282
|
+
onBlur?.(e);
|
|
283
|
+
const to = e.relatedTarget;
|
|
284
|
+
if (to instanceof Element && !e.currentTarget.contains(to)) holdsFocus.current = false;
|
|
285
|
+
whenFocusLeftForNothing(e, () => {
|
|
286
|
+
holdsFocus.current = false;
|
|
287
|
+
});
|
|
288
|
+
},
|
|
289
|
+
};
|
|
290
|
+
// The commit that hides the bar: the focus goes back while the control holding it is
|
|
291
|
+
// still in place — before `inert` takes it, or, with no exit to play, before <body> does.
|
|
292
|
+
const wasShown = useRef(shown);
|
|
293
|
+
useLayoutEffect(() => {
|
|
294
|
+
if (wasShown.current === shown) return;
|
|
295
|
+
wasShown.current = shown;
|
|
296
|
+
const from = cameFrom.current;
|
|
297
|
+
const held = holdsFocus.current;
|
|
298
|
+
cameFrom.current = null;
|
|
299
|
+
holdsFocus.current = false;
|
|
300
|
+
if (shown) return;
|
|
301
|
+
// The outermost element: the toolbar, or with a `panel` the surface round both.
|
|
302
|
+
const surface = barRef.current?.closest("[data-bulk-action-bar]");
|
|
303
|
+
const inBar = !!surface && surface.contains(document.activeElement);
|
|
304
|
+
if (inBar || (held && focusIsLost())) focusFirst([returnFocusRef?.current, from]);
|
|
305
|
+
}, [shown, returnFocusRef]);
|
|
306
|
+
|
|
248
307
|
const handleKeyDown = (e: KeyboardEvent<HTMLDivElement>) => {
|
|
249
308
|
onKeyDown?.(e);
|
|
250
309
|
if (e.defaultPrevented || ownsArrows(e.target as Element)) return;
|
|
@@ -279,7 +338,9 @@ export function BulkActionBar({
|
|
|
279
338
|
</Button>
|
|
280
339
|
);
|
|
281
340
|
|
|
282
|
-
|
|
341
|
+
// `hasContent` (refactor audit 2026-10-30, DUP-14): an empty-string panel drew an empty
|
|
342
|
+
// bordered strip under the bar.
|
|
343
|
+
const hasPanel = hasContent(panel);
|
|
283
344
|
// The surface — where the bar sits and what it looks like — and the toolbar row's
|
|
284
345
|
// own layout. Without a panel they are one element, exactly as before 0.11.0; with
|
|
285
346
|
// one the surface wraps the row and the panel, so both share its tint and position.
|
|
@@ -314,6 +375,7 @@ export function BulkActionBar({
|
|
|
314
375
|
onKeyDown={handleKeyDown}
|
|
315
376
|
onFocus={(e) => {
|
|
316
377
|
onFocus?.(e);
|
|
378
|
+
if (!hasPanel) trackFocus.onFocus(e);
|
|
317
379
|
// Clicking a control is using it: the stop follows the pointer too.
|
|
318
380
|
const hit = itemsOf(barRef.current).find((el) => el === e.target);
|
|
319
381
|
if (hit) {
|
|
@@ -321,6 +383,7 @@ export function BulkActionBar({
|
|
|
321
383
|
rove(barRef.current, active);
|
|
322
384
|
}
|
|
323
385
|
}}
|
|
386
|
+
onBlur={hasPanel ? undefined : trackFocus.onBlur}
|
|
324
387
|
style={hasPanel ? undefined : surfaceStyle}
|
|
325
388
|
className={hasPanel ? rowClass : cn(rowClass, surfaceClass, className)}
|
|
326
389
|
>
|
|
@@ -340,8 +403,13 @@ export function BulkActionBar({
|
|
|
340
403
|
<>
|
|
341
404
|
<span {...regionProps} />
|
|
342
405
|
{hasPanel ? (
|
|
406
|
+
/* eslint-disable-next-line jsx-a11y/no-static-element-interactions -- the focus is
|
|
407
|
+
only noted here (DSP-15): where it came from, whether it is in the bar; the
|
|
408
|
+
controls are the toolbar's and the panel's own. */
|
|
343
409
|
<div
|
|
344
410
|
{...rest}
|
|
411
|
+
onFocus={trackFocus.onFocus}
|
|
412
|
+
onBlur={trackFocus.onBlur}
|
|
345
413
|
data-bulk-action-bar={variant}
|
|
346
414
|
inert={!shown || undefined}
|
|
347
415
|
style={surfaceStyle}
|
|
@@ -9,8 +9,8 @@ import type { KitLinkComponent, KitLinkProps } from "../i18n/kit-labels";
|
|
|
9
9
|
* and its router link. Both now draw from this module, which renders nothing, so neither
|
|
10
10
|
* imports the other.
|
|
11
11
|
*
|
|
12
|
-
* Public through
|
|
13
|
-
* The other exports are the two buttons' shared parts (`@internal`).
|
|
12
|
+
* Public through the barrel (src/index.ts) by name: `buttonClasses`, `TOUCH_TARGET_LARGE`
|
|
13
|
+
* and the four types. The other exports are the two buttons' shared parts (`@internal`).
|
|
14
14
|
*/
|
|
15
15
|
|
|
16
16
|
/**
|
|
@@ -24,9 +24,9 @@ import type { KitLinkComponent, KitLinkProps } from "../i18n/kit-labels";
|
|
|
24
24
|
* (theme/palette-derive.ts), which no button paints.
|
|
25
25
|
* - `secondary`: an outline. `ghost`: text or glyph only. `danger`: solid `--danger`,
|
|
26
26
|
* for an action that destroys something. `link`: a text link that acts (a `<button>`).
|
|
27
|
-
*
|
|
28
|
-
*
|
|
29
|
-
*
|
|
27
|
+
*
|
|
28
|
+
* 0.49's `primary` and `brand` (aliases of `default` and `accent`) were removed in 0.51;
|
|
29
|
+
* `primary` will not come back with another meaning.
|
|
30
30
|
*/
|
|
31
31
|
export type ButtonVariant = "default" | "accent" | "secondary" | "ghost" | "danger" | "link";
|
|
32
32
|
|
|
@@ -25,8 +25,8 @@ import type { ButtonSize, ButtonTone, ButtonVariant } from "./button-look";
|
|
|
25
25
|
*/
|
|
26
26
|
export interface ButtonProps extends ButtonHTMLAttributes<HTMLButtonElement> {
|
|
27
27
|
/** `default` (the quiet action, what a Button without `variant` draws), `accent` (the
|
|
28
|
-
* strong call to action, solid brand), `secondary`, `ghost`, `danger` or `link`.
|
|
29
|
-
*
|
|
28
|
+
* strong call to action, solid brand), `secondary`, `ghost`, `danger` or `link`. See
|
|
29
|
+
* {@link ButtonVariant}. */
|
|
30
30
|
variant?: ButtonVariant;
|
|
31
31
|
/** `md` (default) is the page's action button. `sm` is the compact one — 12px text
|
|
32
32
|
* and `px-2 py-1` — for the secondary actions in a toolbar, a card header or a
|
|
@@ -1,7 +1,8 @@
|
|
|
1
1
|
// The live side of `chartEdge` (theme/chart-palette.ts): which colours a FILLED mark is
|
|
2
2
|
// painted with and which grounds it sits on, read off <html> as the page resolves them —
|
|
3
3
|
// so the 1px ink edge follows a theme toggle and a palette switch without the chart
|
|
4
|
-
// knowing either store.
|
|
4
|
+
// knowing either store. And WHETHER a mark gets one: `useEdgesInForce`, the contrast
|
|
5
|
+
// setting's switch. Shared by SeriesChart (bars, areas) and Treemap (tiles).
|
|
5
6
|
import { useCallback, useSyncExternalStore } from "react";
|
|
6
7
|
import { chartEdge } from "../theme/chart-palette";
|
|
7
8
|
import { parseHex } from "../theme/color";
|
|
@@ -71,3 +72,35 @@ export function useChartEdge(): (fill: string | undefined) => string | undefined
|
|
|
71
72
|
[snapshot],
|
|
72
73
|
);
|
|
73
74
|
}
|
|
75
|
+
|
|
76
|
+
/**
|
|
77
|
+
* How filled marks are parted — see `TreemapProps.edges` (0.51.6, keksdose dev #642).
|
|
78
|
+
* `"auto"`: `"uniform"` at Standard contrast, `"contrast"` while More contrast is in force.
|
|
79
|
+
*/
|
|
80
|
+
export type ChartEdges = "auto" | "uniform" | "contrast";
|
|
81
|
+
|
|
82
|
+
// `<html data-contrast>`, followed live: what `"auto"` keys on. Read here rather than
|
|
83
|
+
// through theme/contrast, whose store would come into the chart entry with it.
|
|
84
|
+
function subscribeContrast(onChange: () => void): () => void {
|
|
85
|
+
if (typeof MutationObserver === "undefined" || typeof document === "undefined") return () => {};
|
|
86
|
+
const observer = new MutationObserver(onChange);
|
|
87
|
+
observer.observe(document.documentElement, { attributes: true, attributeFilter: ["data-contrast"] });
|
|
88
|
+
return () => observer.disconnect();
|
|
89
|
+
}
|
|
90
|
+
const readMoreContrast = () =>
|
|
91
|
+
typeof document !== "undefined" && document.documentElement.getAttribute("data-contrast") === "more";
|
|
92
|
+
|
|
93
|
+
/**
|
|
94
|
+
* The edges a filled mark draws: `"auto"` resolved against the contrast in force, live.
|
|
95
|
+
*
|
|
96
|
+
* Under `"contrast"` a mark whose hue is under 3:1 against the ground gets the 1px ink
|
|
97
|
+
* edge ({@link useChartEdge}); under `"uniform"` none does. The tiles took this rule in
|
|
98
|
+
* 0.51.6 (#642: "The borders do not look nice when changing from tile to tile"), and
|
|
99
|
+
* SeriesChart's bars and areas in 0.52 (refactor audit 2026-10-30, DSP-18, Marcel's
|
|
100
|
+
* decision 3): at Standard contrast the edge fell on 5 of 8 hues in light, and in dark on
|
|
101
|
+
* chart-5 and chart-7 alone — the same unevenness, in a bar chart.
|
|
102
|
+
*/
|
|
103
|
+
export function useEdgesInForce(edges: ChartEdges = "auto"): "uniform" | "contrast" {
|
|
104
|
+
const more = useSyncExternalStore(subscribeContrast, readMoreContrast, () => false);
|
|
105
|
+
return edges === "auto" ? (more ? "contrast" : "uniform") : edges;
|
|
106
|
+
}
|