@eifi1/ui-kit 0.51.6 → 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 +146 -26
- 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 +3 -7
- 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.d.ts +3 -2
- package/dist/auth/complete-name-dialog.js +3 -5
- 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-request.d.ts +11 -2
- package/dist/billing/cancel-request.js +15 -3
- package/dist/billing/cancel-request.js.map +1 -1
- package/dist/billing/cancel-subscription.d.ts +22 -10
- package/dist/billing/cancel-subscription.js +8 -11
- 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 +21 -9
- package/dist/billing/plan-switch.js +10 -8
- 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 +22 -4
- package/dist/components/amount-input.js +3 -3
- 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/calculator.d.ts +21 -2
- package/dist/components/calculator.js +53 -14
- package/dist/components/calculator.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 +119 -7
- package/dist/components/combobox-core.js +151 -46
- package/dist/components/combobox-core.js.map +1 -1
- package/dist/components/combobox.d.ts +1 -1
- package/dist/components/combobox.js +142 -131
- 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 +36 -7
- package/dist/components/data-table-mobile.js +63 -31
- 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 +25 -8
- package/dist/components/data-table.js +154 -25
- 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/dialog-frame.d.ts +2 -1
- package/dist/components/dialog-frame.js.map +1 -1
- package/dist/components/entity-combobox.js +4 -2
- package/dist/components/entity-combobox.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 +150 -141
- 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 +4 -3
- 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.d.ts +24 -0
- package/dist/components/modal.js +12 -4
- package/dist/components/modal.js.map +1 -1
- package/dist/components/money-draft.js +7 -5
- package/dist/components/money-draft.js.map +1 -1
- package/dist/components/money-field.d.ts +2 -2
- package/dist/components/money-field.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-entity-combobox.js +2 -1
- package/dist/components/multi-entity-combobox.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/number-field.d.ts +6 -4
- package/dist/components/number-field.js +3 -2
- package/dist/components/number-field.js.map +1 -1
- package/dist/components/number-input.d.ts +4 -1
- package/dist/components/number-input.js +3 -2
- package/dist/components/number-input.js.map +1 -1
- package/dist/components/numpad-sheet.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/reauth-dialog.d.ts +4 -5
- package/dist/components/reauth-dialog.js +1 -4
- package/dist/components/reauth-dialog.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 +10 -3
- package/dist/components/series-chart-axes.js +1 -0
- 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 +13 -11
- 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-dismiss.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.d.ts +7 -1
- package/dist/hooks/use-overlay-history.js +35 -5
- 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/calc.d.ts +7 -1
- package/dist/lib/calc.js +3 -1
- package/dist/lib/calc.js.map +1 -1
- package/dist/lib/clipboard-minus.d.ts +2 -2
- package/dist/lib/clipboard-minus.js +1 -1
- package/dist/lib/clipboard-minus.js.map +1 -1
- 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/decimal-marks.d.ts +7 -1
- package/dist/lib/decimal-marks.js +5 -2
- package/dist/lib/decimal-marks.js.map +1 -1
- 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.d.ts +5 -3
- package/dist/lib/format.js +16 -13
- 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 +38 -0
- package/dist/lib/text-match.js +24 -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 +16 -4
- package/dist/tour/tour.js +62 -778
- 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/tour/use-tour-url-sync.js +2 -2
- package/dist/tour/use-tour-url-sync.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 +12 -8
- 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 +5 -10
- 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 +9 -8
- 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-request.ts +28 -6
- package/src/billing/cancel-subscription.tsx +29 -22
- 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 +31 -20
- 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 +32 -14
- 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/calculator.tsx +98 -17
- 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 +303 -69
- package/src/components/combobox.tsx +184 -155
- 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 +110 -27
- 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 +267 -41
- 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/dialog-frame.tsx +2 -1
- package/src/components/entity-combobox.tsx +4 -1
- 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 +198 -152
- 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 +14 -5
- package/src/components/measured-grid.tsx +8 -4
- package/src/components/mini-calendar.tsx +6 -5
- package/src/components/modal.tsx +45 -4
- package/src/components/money-draft.ts +16 -5
- package/src/components/money-field.tsx +2 -2
- package/src/components/month-grid.tsx +229 -0
- package/src/components/month-picker.tsx +192 -200
- package/src/components/multi-entity-combobox.tsx +1 -0
- package/src/components/multi-select.tsx +21 -9
- package/src/components/number-field.tsx +14 -7
- package/src/components/number-input.tsx +9 -3
- package/src/components/numpad-sheet.tsx +4 -3
- 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/reauth-dialog.tsx +6 -10
- package/src/components/row-actions.tsx +2 -1
- package/src/components/section-nav.tsx +7 -0
- package/src/components/series-chart-axes.ts +11 -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 +35 -19
- 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-dismiss.ts +3 -2
- 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 +70 -5
- 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/calc.ts +13 -2
- package/src/lib/clipboard-minus.ts +14 -4
- package/src/lib/date-format.ts +89 -13
- package/src/lib/day-format.ts +96 -0
- package/src/lib/decimal-marks.ts +12 -3
- 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 +34 -19
- 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 +69 -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 +116 -1193
- package/src/tour/use-tour-progress.ts +1 -1
- package/src/tour/use-tour-url-sync.ts +7 -3
- 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
package/src/components/chart.tsx
CHANGED
|
@@ -13,6 +13,7 @@ import type { ComponentProps, CSSProperties, ReactNode, RefObject } from "react"
|
|
|
13
13
|
import { Legend as RechartsLegend, ResponsiveContainer, Tooltip as RechartsTooltip } from "recharts";
|
|
14
14
|
import { cn } from "../lib/cn";
|
|
15
15
|
import { isRtl } from "../lib/direction";
|
|
16
|
+
import { useFigureDescription } from "./chart-figure";
|
|
16
17
|
import { TYPOGRAPHIC_MINUS } from "../lib/minus";
|
|
17
18
|
|
|
18
19
|
export interface ChartSeriesConfig {
|
|
@@ -33,6 +34,13 @@ export function useChart(): ChartConfig {
|
|
|
33
34
|
interface ChartContainerProps extends ComponentProps<"div"> {
|
|
34
35
|
config: ChartConfig;
|
|
35
36
|
children: ComponentProps<typeof ResponsiveContainer>["children"];
|
|
37
|
+
/**
|
|
38
|
+
* What the chart SHOWS, in a sentence, as its accessible description (0.52): read through
|
|
39
|
+
* `aria-describedby`, after a caller's own ids, and drawn nowhere. Inside the root, so
|
|
40
|
+
* the chart stays the one element its parent lays out. Pair it with `role="figure"` and
|
|
41
|
+
* an `aria-label`, as `Treemap` and `SeriesChart` do.
|
|
42
|
+
*/
|
|
43
|
+
description?: string;
|
|
36
44
|
}
|
|
37
45
|
|
|
38
46
|
/**
|
|
@@ -49,8 +57,9 @@ interface ChartContainerProps extends ComponentProps<"div"> {
|
|
|
49
57
|
* page's direction like any other markup. A consumer who does want a mirrored
|
|
50
58
|
* category axis passes `reversed` on its own `XAxis`.
|
|
51
59
|
*/
|
|
52
|
-
export function ChartContainer({ id, className, children, config, ...props }: ChartContainerProps) {
|
|
60
|
+
export function ChartContainer({ id, className, children, config, description, ...props }: ChartContainerProps) {
|
|
53
61
|
const uid = useId();
|
|
62
|
+
const about = useFigureDescription(description, props["aria-describedby"]);
|
|
54
63
|
// The id is pasted into an UNQUOTED `[data-chart=…]` selector below, so it has to be
|
|
55
64
|
// a CSS identifier: one stray space or `#` and the browser discards the whole rule,
|
|
56
65
|
// taking every series colour with it — silently, because an invalid rule is not an
|
|
@@ -81,11 +90,13 @@ export function ChartContainer({ id, className, children, config, ...props }: Ch
|
|
|
81
90
|
className,
|
|
82
91
|
)}
|
|
83
92
|
{...props}
|
|
93
|
+
aria-describedby={about.describedBy}
|
|
84
94
|
>
|
|
85
95
|
<ChartStyle id={chartId} config={config} />
|
|
86
96
|
<ResponsiveContainer width="100%" height="100%">
|
|
87
97
|
{children}
|
|
88
98
|
</ResponsiveContainer>
|
|
99
|
+
{about.node}
|
|
89
100
|
</div>
|
|
90
101
|
</ChartContext.Provider>
|
|
91
102
|
);
|
|
@@ -489,15 +500,22 @@ export function ChartLegendContent({ payload, onItemClick, hiddenKeys, activeKey
|
|
|
489
500
|
const label = series?.label ?? vv ?? cfgKey;
|
|
490
501
|
const off = hidden?.has(cfgKey) ?? false;
|
|
491
502
|
const dimmed = off || (activeKey != null && activeKey !== cfgKey);
|
|
503
|
+
// The label's cue, in a key and on a button alike: a hidden series struck through,
|
|
504
|
+
// and an entry an isolate legend dims in the muted ink — drawn still, so not struck.
|
|
505
|
+
// Only a toggle button had one, and a key or an isolate legend told an entry off by
|
|
506
|
+
// its 10px swatch at 40 % alone (0.52 code review, deep, charts, finding 9).
|
|
507
|
+
const cue = off ? "line-through" : dimmed ? "text-muted" : undefined;
|
|
492
508
|
const className = cn(
|
|
493
509
|
"flex items-center gap-1.5 text-secondary transition-opacity",
|
|
494
510
|
onItemClick ? "cursor-pointer hover:opacity-80" : "cursor-default",
|
|
495
|
-
dimmed && "opacity-40",
|
|
496
511
|
);
|
|
512
|
+
// Only the swatch fades; the label keeps an ink of AA contrast (0.52, refactor audit
|
|
513
|
+
// 2026-10-30, DSP-9). The whole entry at 40 % put a switched-off label under 2:1,
|
|
514
|
+
// on a button that brings its series back and is named by nothing else.
|
|
497
515
|
const swatch = (
|
|
498
516
|
<span
|
|
499
517
|
aria-hidden
|
|
500
|
-
className="h-2.5 w-2.5 shrink-0 rounded-[3px]"
|
|
518
|
+
className={cn("h-2.5 w-2.5 shrink-0 rounded-[3px]", dimmed && "opacity-40")}
|
|
501
519
|
style={{ backgroundColor: color } as CSSProperties}
|
|
502
520
|
/>
|
|
503
521
|
);
|
|
@@ -519,10 +537,13 @@ export function ChartLegendContent({ payload, onItemClick, hiddenKeys, activeKey
|
|
|
519
537
|
className={className}
|
|
520
538
|
>
|
|
521
539
|
{swatch}
|
|
522
|
-
<span className={
|
|
540
|
+
<span className={cue}>{label}</span>
|
|
523
541
|
</button>
|
|
524
542
|
) : (
|
|
525
|
-
|
|
543
|
+
// On the entry, not round the label: the text is its own, so the key's DOM is the
|
|
544
|
+
// same with a cue as without. A line-through reaches the text only (the swatch
|
|
545
|
+
// holds none), and the ink colours no swatch.
|
|
546
|
+
<span key={`${cfgKey}-${i}`} className={cn(className, cue)}>
|
|
526
547
|
{swatch}
|
|
527
548
|
{label}
|
|
528
549
|
</span>
|
|
@@ -11,6 +11,7 @@ import type {
|
|
|
11
11
|
import { Check, Plus } from "lucide-react";
|
|
12
12
|
import { cn } from "../lib/cn";
|
|
13
13
|
import { CLIPS_ATTRIBUTE } from "../lib/clipping";
|
|
14
|
+
import { tabStops } from "../lib/focus-left";
|
|
14
15
|
import { DropdownSearchHeader } from "./dropdown";
|
|
15
16
|
import { PickerSheet, SHEET_ROW_CLASS } from "./picker-sheet";
|
|
16
17
|
import { usePhoneLayout, useRemPx } from "../hooks/use-breakpoint";
|
|
@@ -22,7 +23,7 @@ import { anchoredInline, useAnchoredPanel, viewportSize, type AnchoredPanel } fr
|
|
|
22
23
|
import { pressInside, takeEscape, useDismissLayer, useOutsideClick } from "../hooks/use-dismiss";
|
|
23
24
|
import { useOverlayHistory } from "../hooks/use-overlay-history";
|
|
24
25
|
import { isImeEnter } from "../lib/ime";
|
|
25
|
-
import { matchesSearch, searchWords } from "../lib/text-match";
|
|
26
|
+
import { matchesSearch, sameName, searchWords } from "../lib/text-match";
|
|
26
27
|
import { DEFAULT_COMBOBOX_LABELS, useKitLabels, useKitLocale } from "../i18n/kit-labels";
|
|
27
28
|
import { hasContent } from "../lib/presence";
|
|
28
29
|
|
|
@@ -108,25 +109,28 @@ export const DISABLED_ROW_CLASS = "cursor-not-allowed opacity-50 hover:bg-transp
|
|
|
108
109
|
* Whether an entity picker offers its create row — one rule for
|
|
109
110
|
* {@link EntityCombobox}, {@link MultiEntityCombobox} and {@link InlineEntityCombobox}.
|
|
110
111
|
*
|
|
111
|
-
* With a query: while the trimmed query names no option exactly
|
|
112
|
-
*
|
|
113
|
-
*
|
|
112
|
+
* With a query: while the trimmed query names no option exactly — an exact hit is a
|
|
113
|
+
* record the list is already showing, and a second way to "make" it would mint a
|
|
114
|
+
* duplicate. "Exactly" as the list matches, folded by `locale` ({@link sameName}): with
|
|
115
|
+
* plain `toLowerCase`, "cafe" listed Café and offered "Create “cafe”" beside it (refactor
|
|
116
|
+
* audit 2026-10-30, DUP-5). With NO query: only when the caller named the row for that
|
|
114
117
|
* case (`createEmptyLabel`) — a row reading `Create “”` says nothing, and the kit cannot
|
|
115
118
|
* know the noun ("Create cash account") that would make it say something (keksdose G9).
|
|
116
119
|
*
|
|
117
120
|
* `names` is what the query is compared against: the loaded rows for a panel picker
|
|
118
|
-
* (its async list is all it knows), every option for the inline one.
|
|
121
|
+
* (its async list is all it knows), every option for the inline one. `locale`: the
|
|
122
|
+
* provider's, which the list's match folds by; left out, the runtime's.
|
|
119
123
|
*/
|
|
120
124
|
export function offersCreate(
|
|
121
125
|
onCreate: unknown,
|
|
122
126
|
query: string,
|
|
123
127
|
names: readonly string[],
|
|
124
128
|
createEmptyLabel: string | undefined,
|
|
129
|
+
locale?: string,
|
|
125
130
|
): boolean {
|
|
126
131
|
if (!onCreate) return false;
|
|
127
132
|
if (!query) return Boolean(createEmptyLabel);
|
|
128
|
-
|
|
129
|
-
return !names.some((n) => n.toLowerCase() === q);
|
|
133
|
+
return !names.some((n) => sameName(n, query, locale));
|
|
130
134
|
}
|
|
131
135
|
|
|
132
136
|
/**
|
|
@@ -468,10 +472,147 @@ export function useComboboxCore<V extends string | number>({
|
|
|
468
472
|
* heading is the one thing that says where in the alphabet the thumb is. Opaque — the
|
|
469
473
|
* list's own `bg-surface` — so the rows pass beneath it rather than through it. Shared
|
|
470
474
|
* by every list that heads groups (the panel and the sheet, `Combobox`, `Autocomplete`,
|
|
471
|
-
* `InlineEntityCombobox`).
|
|
475
|
+
* `InlineEntityCombobox`). Inside its {@link OptionGroup} since 0.52, it sticks while its
|
|
476
|
+
* own group is in view and the next group's heading pushes it out.
|
|
472
477
|
*/
|
|
473
478
|
export const GROUP_HEADING_STICKY = "sticky top-0 z-10 bg-surface";
|
|
474
479
|
|
|
480
|
+
/** One run of rows that share a group, as {@link groupRuns} finds them: `group` is
|
|
481
|
+
* `null` for rows filed under none, which stand bare in the list; `start` is the index
|
|
482
|
+
* of the run's first row in the whole list (the option ids and the arrows count by it). */
|
|
483
|
+
export interface GroupRun<T> {
|
|
484
|
+
group: string | null;
|
|
485
|
+
start: number;
|
|
486
|
+
rows: T[];
|
|
487
|
+
}
|
|
488
|
+
|
|
489
|
+
/**
|
|
490
|
+
* A list's rows, cut where the group changes — the runs {@link OptionGroup} wraps. The
|
|
491
|
+
* lists keep their rows group-contiguous (the panel's source order, or the ranked list
|
|
492
|
+
* regrouped by its best member), so a run is "the rows up to the next change of group".
|
|
493
|
+
* `groupOf` is asked once per row. An empty group name is no group: a heading of nothing
|
|
494
|
+
* names nothing.
|
|
495
|
+
*/
|
|
496
|
+
export function groupRuns<T>(rows: readonly T[], groupOf: (row: T) => string | null | undefined): GroupRun<T>[] {
|
|
497
|
+
const runs: GroupRun<T>[] = [];
|
|
498
|
+
rows.forEach((row, i) => {
|
|
499
|
+
const raw = groupOf(row);
|
|
500
|
+
const group = raw === undefined || raw === null || raw === "" ? null : raw;
|
|
501
|
+
const last = runs[runs.length - 1];
|
|
502
|
+
if (last && last.group === group) last.rows.push(row);
|
|
503
|
+
else runs.push({ group, start: i, rows: [row] });
|
|
504
|
+
});
|
|
505
|
+
return runs;
|
|
506
|
+
}
|
|
507
|
+
|
|
508
|
+
/**
|
|
509
|
+
* A group of options under its heading, inside a `role="listbox"`: a `role="group"`
|
|
510
|
+
* NAMED by the heading, so a reader moving through the list hears which group a row is
|
|
511
|
+
* in (refactor audit 2026-10-30, INP-8). The heading was loose text among the options,
|
|
512
|
+
* and focus stays in the search box with the row announced through
|
|
513
|
+
* `aria-activedescendant` — keksdose's "Groceries" under Recent and again under its own
|
|
514
|
+
* group were two identical names, and an account filed by its type never said the type.
|
|
515
|
+
* The heading stays a visible first item of the group (sticky within it); the columns of
|
|
516
|
+
* {@link ComboboxPanel} carry the same `role="group"`.
|
|
517
|
+
*
|
|
518
|
+
* `id` must be unique in the document (the list's id plus the run's start); `className`
|
|
519
|
+
* places the heading's text in its list.
|
|
520
|
+
*/
|
|
521
|
+
export function OptionGroup({
|
|
522
|
+
id,
|
|
523
|
+
heading,
|
|
524
|
+
className,
|
|
525
|
+
children,
|
|
526
|
+
}: {
|
|
527
|
+
id: string;
|
|
528
|
+
heading: ReactNode;
|
|
529
|
+
className?: string;
|
|
530
|
+
children: ReactNode;
|
|
531
|
+
}) {
|
|
532
|
+
return (
|
|
533
|
+
<li role="presentation">
|
|
534
|
+
<ul role="group" aria-labelledby={id}>
|
|
535
|
+
<li
|
|
536
|
+
role="presentation"
|
|
537
|
+
id={id}
|
|
538
|
+
className={cn(GROUP_HEADING_STICKY, "font-semibold uppercase tracking-wide text-muted", className)}
|
|
539
|
+
>
|
|
540
|
+
{heading}
|
|
541
|
+
</li>
|
|
542
|
+
{children}
|
|
543
|
+
</ul>
|
|
544
|
+
</li>
|
|
545
|
+
);
|
|
546
|
+
}
|
|
547
|
+
|
|
548
|
+
/**
|
|
549
|
+
* A list's rows in their {@link groupRuns}: a run filed under no group stands bare, any
|
|
550
|
+
* other is an {@link OptionGroup} under its heading. The one drawing of it for
|
|
551
|
+
* {@link ComboboxPanel}, {@link Combobox}, {@link InlineEntityCombobox} and
|
|
552
|
+
* {@link Autocomplete}, which had a copy each (0.52 code review, combobox-core.tsx).
|
|
553
|
+
*
|
|
554
|
+
* A run is keyed by its group and how many runs of that group came before it — NOT by
|
|
555
|
+
* the index of its first row, which every keystroke that drops a row from an earlier
|
|
556
|
+
* group moves: each later group was re-keyed and React rebuilt it, every row of it, per
|
|
557
|
+
* keystroke. A row is keyed by `rowKey` among the rows of its run; an option may stand
|
|
558
|
+
* in two groups (keksdose's "Recent", live #203), never twice in one.
|
|
559
|
+
*
|
|
560
|
+
* `row(o, i, grouped)`: `i` is the row's index in the whole list (the option ids and the
|
|
561
|
+
* arrows count by it), `grouped` whether it stands under a heading. `headingClassName`
|
|
562
|
+
* places a run's heading text in its list. The group's id is the list's id and the run's
|
|
563
|
+
* first row, unique in the document.
|
|
564
|
+
*/
|
|
565
|
+
export function GroupedOptions<T>({
|
|
566
|
+
runs,
|
|
567
|
+
listboxId,
|
|
568
|
+
rowKey,
|
|
569
|
+
row,
|
|
570
|
+
headingClassName,
|
|
571
|
+
}: {
|
|
572
|
+
runs: readonly GroupRun<T>[];
|
|
573
|
+
listboxId: string;
|
|
574
|
+
rowKey: (o: T) => string;
|
|
575
|
+
row: (o: T, index: number, grouped: boolean) => ReactNode;
|
|
576
|
+
headingClassName: (run: GroupRun<T>) => string;
|
|
577
|
+
}) {
|
|
578
|
+
return keyRuns(runs).map(({ run, key }) => {
|
|
579
|
+
const grouped = run.group !== null;
|
|
580
|
+
const rows = run.rows.map((o, k) => <Fragment key={rowKey(o)}>{row(o, run.start + k, grouped)}</Fragment>);
|
|
581
|
+
if (!grouped) return <Fragment key={key}>{rows}</Fragment>;
|
|
582
|
+
return (
|
|
583
|
+
<OptionGroup
|
|
584
|
+
key={key}
|
|
585
|
+
id={`${listboxId}-group-${run.start}`}
|
|
586
|
+
heading={run.group}
|
|
587
|
+
className={headingClassName(run)}
|
|
588
|
+
>
|
|
589
|
+
{rows}
|
|
590
|
+
</OptionGroup>
|
|
591
|
+
);
|
|
592
|
+
});
|
|
593
|
+
}
|
|
594
|
+
|
|
595
|
+
/** Each run with its key — see {@link GroupedOptions}: the group and how many runs of it
|
|
596
|
+
* came before, which a query narrowing an earlier group does not move. */
|
|
597
|
+
function keyRuns<T>(runs: readonly GroupRun<T>[]): { run: GroupRun<T>; key: string }[] {
|
|
598
|
+
const seen = new Map<string | null, number>();
|
|
599
|
+
return runs.map((run) => {
|
|
600
|
+
const nth = seen.get(run.group) ?? 0;
|
|
601
|
+
seen.set(run.group, nth + 1);
|
|
602
|
+
// The count first: it never holds a ":", so no group's name can make two keys equal.
|
|
603
|
+
return { run, key: run.group === null ? String(nth) : `${nth}:${run.group}` };
|
|
604
|
+
});
|
|
605
|
+
}
|
|
606
|
+
|
|
607
|
+
/** The anchored list's heading text: the first group's sits closer to the list's top
|
|
608
|
+
* edge, unless a row stands above it (`first: false`, Combobox's create row). */
|
|
609
|
+
export const anchoredHeadingClass = (run: GroupRun<unknown>, first = true) =>
|
|
610
|
+
cn("px-3 pb-0.5 text-caption", run.start === 0 && first ? "pt-1" : "pt-2");
|
|
611
|
+
|
|
612
|
+
/** The typed comboboxes' phone sheet's heading text ({@link Combobox},
|
|
613
|
+
* {@link InlineEntityCombobox}). */
|
|
614
|
+
export const SHEET_HEADING_CLASS = "px-4 pb-0.5 pt-3 text-caption";
|
|
615
|
+
|
|
475
616
|
export const SUGGESTION_LIST_CLASS =
|
|
476
617
|
"max-h-64 overflow-y-auto rounded-md border border-subtle bg-surface py-1 shadow-lg";
|
|
477
618
|
|
|
@@ -502,6 +643,63 @@ export function useActiveOptionScroll(activeId: string | undefined): void {
|
|
|
502
643
|
}, [activeId]);
|
|
503
644
|
}
|
|
504
645
|
|
|
646
|
+
/**
|
|
647
|
+
* What a TYPED combobox's list says — {@link Combobox} and {@link InlineEntityCombobox},
|
|
648
|
+
* which had a copy each, the second saying "see the twin" (0.52 code review,
|
|
649
|
+
* inline-entity-combobox.tsx; the rules are refactor audit 2026-10-30, INP-6):
|
|
650
|
+
*
|
|
651
|
+
* - `showing`: the anchored list is on screen — open, not inert, with a row to show (an
|
|
652
|
+
* option, or `extraRow`, the create row). The list is then a layer on the Escape stack
|
|
653
|
+
* (Wave 2, DUP-1). Never on a phone, where the sheet is the list and the layer.
|
|
654
|
+
* - `expanded`, the field's `aria-expanded`: a list on screen. An open list with nothing
|
|
655
|
+
* to show said "expanded" with no listbox in the document.
|
|
656
|
+
* - `activeOption`: the id of the row the keyboard is on — `active`, a TAKEABLE row's
|
|
657
|
+
* index, else -1 — in whichever list shows, kept scrolled into view.
|
|
658
|
+
* - `statusRegion`: a polite live region with the row count, or "No results" for a query
|
|
659
|
+
* that left nothing to show or do. Focus stays in the field, or in the sheet's search
|
|
660
|
+
* box, so a list changing under it was silent. A list opened on no query asked nothing.
|
|
661
|
+
* Render it outside the list, so the list going cannot take it along: on a phone inside
|
|
662
|
+
* the sheet, which hides from a reader what lies outside it. There it mounts with the
|
|
663
|
+
* sheet, so the count the sheet opens with is not announced — as a ComboboxPanel's is
|
|
664
|
+
* not, in either shell — and every change after it is.
|
|
665
|
+
*/
|
|
666
|
+
export function useTypedListStatus({
|
|
667
|
+
isPhone,
|
|
668
|
+
open,
|
|
669
|
+
inert,
|
|
670
|
+
rowCount,
|
|
671
|
+
extraRow,
|
|
672
|
+
query,
|
|
673
|
+
active,
|
|
674
|
+
optionId,
|
|
675
|
+
labels,
|
|
676
|
+
}: {
|
|
677
|
+
isPhone: boolean;
|
|
678
|
+
open: boolean;
|
|
679
|
+
inert: boolean;
|
|
680
|
+
/** The options the list shows. */
|
|
681
|
+
rowCount: number;
|
|
682
|
+
/** A create row shows: the list is not empty, it offers to fill itself. */
|
|
683
|
+
extraRow: boolean;
|
|
684
|
+
query: string;
|
|
685
|
+
active: number;
|
|
686
|
+
optionId: (index: number) => string;
|
|
687
|
+
labels: { resultCount: (count: number) => string; noResults: string };
|
|
688
|
+
}): { showing: boolean; expanded: boolean; activeOption: string | undefined; statusRegion: ReactNode } {
|
|
689
|
+
const showing = !isPhone && open && !inert && (rowCount > 0 || extraRow);
|
|
690
|
+
const expanded = isPhone ? open && !inert : showing;
|
|
691
|
+
const activeOption = expanded && active >= 0 ? optionId(active) : undefined;
|
|
692
|
+
useActiveOptionScroll(activeOption);
|
|
693
|
+
const status =
|
|
694
|
+
!open || inert ? null : rowCount > 0 ? labels.resultCount(rowCount) : query && !extraRow ? labels.noResults : null;
|
|
695
|
+
const statusRegion = (
|
|
696
|
+
<div role="status" aria-live="polite" className="sr-only">
|
|
697
|
+
{status}
|
|
698
|
+
</div>
|
|
699
|
+
);
|
|
700
|
+
return { showing, expanded, activeOption, statusRegion };
|
|
701
|
+
}
|
|
702
|
+
|
|
505
703
|
/** The anchored panel's least width, in rem: 220 px at Normal (§3.2). */
|
|
506
704
|
const PANEL_MIN_REM = 13.75;
|
|
507
705
|
|
|
@@ -567,7 +765,9 @@ export interface ComboboxPanelProps<V extends string | number> extends Component
|
|
|
567
765
|
*/
|
|
568
766
|
renderOption?: (o: ComboOption<V>) => ReactNode;
|
|
569
767
|
/** Controls between the search box and the list, in the anchored panel and the phone
|
|
570
|
-
* sheet alike — MultiSelect's "Select all" and "Clear".
|
|
768
|
+
* sheet alike — MultiSelect's "Select all" and "Clear". In the anchored panel Tab from
|
|
769
|
+
* the search box walks them before it leaves (0.52); keep them focusable when they
|
|
770
|
+
* have nothing to do (`aria-disabled`), or a press drops their focus to <body>. */
|
|
571
771
|
toolbar?: ReactNode;
|
|
572
772
|
/** See {@link ComboboxPanelWidth}. */
|
|
573
773
|
width?: ComboboxPanelWidth;
|
|
@@ -692,6 +892,44 @@ export function ComboboxPanel<V extends string | number>({
|
|
|
692
892
|
return () => observer.disconnect();
|
|
693
893
|
}, [fit, placed, panelRef]);
|
|
694
894
|
|
|
895
|
+
// The toolbar's own box, so the keyboard can tell its buttons from the search box.
|
|
896
|
+
const toolbarRef = useRef<HTMLDivElement>(null);
|
|
897
|
+
// The kit's one tab-stop rule (0.52 code review, lib/focus-left.ts): this had a third
|
|
898
|
+
// copy of the selector, without its `hidden`/`inert` half. An `aria-disabled` button
|
|
899
|
+
// stays a stop — it keeps its focus (INP-9).
|
|
900
|
+
const toolbarStops = () => (toolbarRef.current ? tabStops(toolbarRef.current, { includeSelf: false }) : []);
|
|
901
|
+
// A POINTER press on the toolbar leaves the focus in the search box, as a press on a
|
|
902
|
+
// row does: since a toolbar button's keys are its own (INP-9), a mouse press — which
|
|
903
|
+
// focuses a button in Chrome and Firefox — left the arrows on "Select all", where they
|
|
904
|
+
// did nothing; until 0.52 they moved the list's highlight (0.52 code review,
|
|
905
|
+
// combobox-core.tsx). Tab still reaches the buttons. A field in a toolbar keeps its
|
|
906
|
+
// press: it is there to be typed in.
|
|
907
|
+
const toolbarBox = hasContent(toolbar) && (
|
|
908
|
+
// eslint-disable-next-line jsx-a11y/no-static-element-interactions -- never focused itself: it only keeps a pointer press on its buttons from taking the focus out of the search box.
|
|
909
|
+
<div
|
|
910
|
+
ref={toolbarRef}
|
|
911
|
+
onMouseDown={(e) => {
|
|
912
|
+
if (!(e.target as Element).closest("input, select, textarea, [contenteditable]")) e.preventDefault();
|
|
913
|
+
}}
|
|
914
|
+
>
|
|
915
|
+
{toolbar}
|
|
916
|
+
</div>
|
|
917
|
+
);
|
|
918
|
+
/** Tab on a toolbar button in the anchored panel: Shift+Tab off the first goes back to
|
|
919
|
+
* the search box, Tab off the last leaves as the search box's Tab did; between two of
|
|
920
|
+
* them the browser's own Tab is right, as they stand next to each other. */
|
|
921
|
+
const tabInToolbar = (e: ReactKeyboardEvent) => {
|
|
922
|
+
const stops = toolbarStops();
|
|
923
|
+
const at = stops.indexOf(e.target as HTMLElement);
|
|
924
|
+
if (e.shiftKey && at === 0) {
|
|
925
|
+
e.preventDefault();
|
|
926
|
+
inputRef.current?.focus();
|
|
927
|
+
} else if (!e.shiftKey && at === stops.length - 1) {
|
|
928
|
+
e.preventDefault();
|
|
929
|
+
closeToTrigger();
|
|
930
|
+
}
|
|
931
|
+
};
|
|
932
|
+
|
|
695
933
|
// The WAI-ARIA APG's listbox keyboard, in full: Up/Down step, Home/End jump, Enter
|
|
696
934
|
// commits, Tab leaves, Escape closes. On the panel's search box — in the anchored
|
|
697
935
|
// panel and, through `onSearchKeyDown`, in the phone sheet's header (BUG-5).
|
|
@@ -701,6 +939,14 @@ export function ComboboxPanel<V extends string | number>({
|
|
|
701
939
|
// panel's events travel up the React tree through that dialog, portal or not, and
|
|
702
940
|
// one press used to close the dialog and throw the form away, list still open.
|
|
703
941
|
if (takeEscape(e)) return;
|
|
942
|
+
// A key on a toolbar button is the button's — Enter and Space press it — and not the
|
|
943
|
+
// list's: Enter there toggled the highlighted row instead of pressing "Select all".
|
|
944
|
+
// Only Tab is the panel's (refactor audit 2026-10-30, INP-9). The phone sheet hands
|
|
945
|
+
// this handler its search box's keys alone, and its trap keeps Tab.
|
|
946
|
+
if (toolbarRef.current?.contains(e.target as Node)) {
|
|
947
|
+
if (e.key === "Tab" && !isPhone) tabInToolbar(e);
|
|
948
|
+
return;
|
|
949
|
+
}
|
|
704
950
|
// The Enter that confirms an IME composition is the IME's (BUG-9).
|
|
705
951
|
if (isImeEnter(e)) return;
|
|
706
952
|
// Disabled rows are passed over (`stepEnabled`), and each step starts from the
|
|
@@ -728,8 +974,12 @@ export function ComboboxPanel<V extends string | number>({
|
|
|
728
974
|
// here to whatever follows the portal — i.e. off the end of the document. The
|
|
729
975
|
// trade is one extra Tab (trigger, then onward) against never stranding focus
|
|
730
976
|
// at the bottom of the page. The phone sheet is a dialog, and its trap keeps Tab.
|
|
977
|
+
// A panel with a toolbar is walked through it first: the rows are not tab stops,
|
|
978
|
+
// so MultiSelect's "Select all" and "Clear" were out of a keyboard's reach (INP-9).
|
|
731
979
|
e.preventDefault();
|
|
732
|
-
|
|
980
|
+
const first = e.shiftKey ? undefined : toolbarStops()[0];
|
|
981
|
+
if (first) first.focus();
|
|
982
|
+
else closeToTrigger();
|
|
733
983
|
}
|
|
734
984
|
};
|
|
735
985
|
|
|
@@ -888,17 +1138,9 @@ export function ComboboxPanel<V extends string | number>({
|
|
|
888
1138
|
</li>
|
|
889
1139
|
);
|
|
890
1140
|
|
|
891
|
-
//
|
|
892
|
-
//
|
|
893
|
-
const
|
|
894
|
-
if (columns && !isPhone) {
|
|
895
|
-
results.forEach((o, i) => {
|
|
896
|
-
const group = o.group ?? "";
|
|
897
|
-
const last = blocks[blocks.length - 1];
|
|
898
|
-
if (last && last.group === group) last.rows.push({ o, i });
|
|
899
|
-
else blocks.push({ group, rows: [{ o, i }] });
|
|
900
|
-
});
|
|
901
|
-
}
|
|
1141
|
+
// The rows' group runs — `results` keeps its source order, so a run is the rows up to
|
|
1142
|
+
// the next change of group. In columns, a block per run.
|
|
1143
|
+
const runs = groupRuns(results, (o) => o.group);
|
|
902
1144
|
|
|
903
1145
|
const list = (
|
|
904
1146
|
<ul
|
|
@@ -918,51 +1160,39 @@ export function ComboboxPanel<V extends string | number>({
|
|
|
918
1160
|
isPhone && "flex-none",
|
|
919
1161
|
)}
|
|
920
1162
|
>
|
|
921
|
-
{columns && !isPhone
|
|
922
|
-
|
|
923
|
-
|
|
924
|
-
|
|
925
|
-
|
|
926
|
-
|
|
927
|
-
|
|
928
|
-
|
|
929
|
-
|
|
930
|
-
|
|
931
|
-
|
|
932
|
-
|
|
933
|
-
|
|
934
|
-
|
|
935
|
-
))}
|
|
936
|
-
|
|
937
|
-
</
|
|
938
|
-
|
|
939
|
-
|
|
940
|
-
|
|
941
|
-
|
|
942
|
-
|
|
943
|
-
|
|
944
|
-
|
|
945
|
-
|
|
946
|
-
|
|
947
|
-
|
|
948
|
-
|
|
949
|
-
|
|
950
|
-
|
|
951
|
-
|
|
952
|
-
|
|
953
|
-
|
|
954
|
-
GROUP_HEADING_STICKY,
|
|
955
|
-
"font-semibold uppercase tracking-wide text-muted",
|
|
956
|
-
isPhone ? "px-4 pb-1 pt-3 text-xs" : "px-3 pb-0.5 pt-2 text-caption first:pt-1",
|
|
957
|
-
)}
|
|
958
|
-
>
|
|
959
|
-
{o.group}
|
|
960
|
-
</li>
|
|
961
|
-
)}
|
|
962
|
-
{optionRow(o, i)}
|
|
963
|
-
</Fragment>
|
|
964
|
-
);
|
|
965
|
-
})}
|
|
1163
|
+
{columns && !isPhone ? (
|
|
1164
|
+
keyRuns(runs).map(({ run, key }) => (
|
|
1165
|
+
// A column block: its heading is a picture of the group's name, which the
|
|
1166
|
+
// `role="group"` carries for a reader — the listbox may own options and
|
|
1167
|
+
// groups, and a heading of loose text in it is neither. Keyed as
|
|
1168
|
+
// GroupedOptions keys a run, so a filter does not rebuild the later columns.
|
|
1169
|
+
<li key={key} role="presentation" className="mb-3 break-inside-avoid">
|
|
1170
|
+
{run.group !== null && (
|
|
1171
|
+
<div aria-hidden className="mb-1 text-xs font-semibold uppercase tracking-wide text-muted">
|
|
1172
|
+
{run.group}
|
|
1173
|
+
</div>
|
|
1174
|
+
)}
|
|
1175
|
+
<ul role="group" aria-label={run.group ?? undefined} className="space-y-0.5">
|
|
1176
|
+
{run.rows.map((o, k) => (
|
|
1177
|
+
<Fragment key={String(o.value)}>{optionRow(o, run.start + k)}</Fragment>
|
|
1178
|
+
))}
|
|
1179
|
+
</ul>
|
|
1180
|
+
</li>
|
|
1181
|
+
))
|
|
1182
|
+
) : (
|
|
1183
|
+
// One heading per group rather than a grey suffix on every row (#136), and the
|
|
1184
|
+
// thing the native <select>'s <optgroup> used to give the account picker for
|
|
1185
|
+
// free (live #200) — a `role="group"` it names (INP-8). Keksdose repeats
|
|
1186
|
+
// recently-used categories in a "Recent" group at the top (live #203): a value
|
|
1187
|
+
// is a row's key within its group alone.
|
|
1188
|
+
<GroupedOptions
|
|
1189
|
+
runs={runs}
|
|
1190
|
+
listboxId={listboxId}
|
|
1191
|
+
rowKey={(o) => String(o.value)}
|
|
1192
|
+
row={optionRow}
|
|
1193
|
+
headingClassName={(run) => (isPhone ? "px-4 pb-1 pt-3 text-xs" : anchoredHeadingClass(run))}
|
|
1194
|
+
/>
|
|
1195
|
+
)}
|
|
966
1196
|
{createRow}
|
|
967
1197
|
</ul>
|
|
968
1198
|
);
|
|
@@ -983,7 +1213,11 @@ export function ComboboxPanel<V extends string | number>({
|
|
|
983
1213
|
className={className}
|
|
984
1214
|
style={style}
|
|
985
1215
|
open
|
|
986
|
-
|
|
1216
|
+
// The X, Done, Escape and Back hand focus to the trigger, as taking a row does:
|
|
1217
|
+
// these triggers open on a click, never on focus, so focusing one re-opens
|
|
1218
|
+
// nothing — and the sheet, which cannot know that, leaves focus on <body>
|
|
1219
|
+
// (refactor audit 2026-10-30, INP-7).
|
|
1220
|
+
onClose={closeToTrigger}
|
|
987
1221
|
title={sheetTitle}
|
|
988
1222
|
query={query}
|
|
989
1223
|
onQueryChange={setQuery}
|
|
@@ -1002,7 +1236,7 @@ export function ComboboxPanel<V extends string | number>({
|
|
|
1002
1236
|
// A single pick closes the sheet itself.
|
|
1003
1237
|
done={multi}
|
|
1004
1238
|
>
|
|
1005
|
-
{
|
|
1239
|
+
{toolbarBox}
|
|
1006
1240
|
<div className="relative">
|
|
1007
1241
|
{list}
|
|
1008
1242
|
{announcement}
|
|
@@ -1076,7 +1310,7 @@ export function ComboboxPanel<V extends string | number>({
|
|
|
1076
1310
|
listboxId={listboxId}
|
|
1077
1311
|
activeId={activeId}
|
|
1078
1312
|
/>
|
|
1079
|
-
{
|
|
1313
|
+
{toolbarBox}
|
|
1080
1314
|
{/* One list, two containers: the desktop panel and the phone sheet render
|
|
1081
1315
|
the same rows through the same handlers (live #200). */}
|
|
1082
1316
|
{list}
|