@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
|
@@ -1,5 +1,5 @@
|
|
|
1
|
-
import {
|
|
2
|
-
import type { ComponentPropsWithoutRef, ReactNode, Ref } from "react";
|
|
1
|
+
import { useId, useMemo, useRef, useState } from "react";
|
|
2
|
+
import type { ComponentPropsWithoutRef, KeyboardEvent, ReactNode, Ref } from "react";
|
|
3
3
|
import { ChevronDown } from "lucide-react";
|
|
4
4
|
import { FIELD_BASE, FIELD_FLOATING_PAD, FIELD_INVALID } from "./field-base";
|
|
5
5
|
import { cn } from "../lib/cn";
|
|
@@ -9,9 +9,18 @@ import { isImeEnter } from "../lib/ime";
|
|
|
9
9
|
import { isQuietFocus } from "../lib/quiet-focus";
|
|
10
10
|
import { usePhoneLayout } from "../hooks/use-breakpoint";
|
|
11
11
|
import { PickerSheet, SHEET_ROW_CLASS } from "./picker-sheet";
|
|
12
|
-
import {
|
|
13
|
-
|
|
14
|
-
|
|
12
|
+
import {
|
|
13
|
+
anchoredHeadingClass,
|
|
14
|
+
ComboboxFieldLabel,
|
|
15
|
+
endHintRowProps,
|
|
16
|
+
GroupedOptions,
|
|
17
|
+
groupRuns,
|
|
18
|
+
SHEET_HEADING_CLASS,
|
|
19
|
+
useTypedListStatus,
|
|
20
|
+
type GroupRun,
|
|
21
|
+
} from "./combobox-core";
|
|
22
|
+
import { DEFAULT_COMBOBOX_LABELS, useKitLabels, useKitLocale } from "../i18n/kit-labels";
|
|
23
|
+
import { sameName, searchRanked } from "../lib/text-match";
|
|
15
24
|
import {
|
|
16
25
|
EndHintRow,
|
|
17
26
|
FieldCaption,
|
|
@@ -44,7 +53,7 @@ export interface ComboboxProps
|
|
|
44
53
|
value: string;
|
|
45
54
|
onChange: (v: string) => void;
|
|
46
55
|
/** Suggestion pool (e.g. existing payee names). */
|
|
47
|
-
options: string[];
|
|
56
|
+
options: readonly string[];
|
|
48
57
|
/** The visible label, a `<label for>` above the field: a ReactNode, as on every kit
|
|
49
58
|
* field (a string until 0.34, refactor audit 2026-10, API-9). Without one, name the
|
|
50
59
|
* field with `aria-label`. */
|
|
@@ -223,6 +232,12 @@ export function Combobox(props: ComboboxProps) {
|
|
|
223
232
|
const { open, setOpen, wrapperRef, panelRef } = useDropdown({ backCloses: !isPhone, escapeLayer: false });
|
|
224
233
|
const primaryOnly = usePrimaryPressOnly();
|
|
225
234
|
const [active, setActive] = useState(-1);
|
|
235
|
+
// A closed list has no row the keyboard is on, however it closed — the sheet's X,
|
|
236
|
+
// Escape or Back, a press outside — adjusted while rendering. The arrows' row outlived
|
|
237
|
+
// it: the list reopens on the whole pool, so the row the arrows had put on "Migros"
|
|
238
|
+
// showed "Aldi" highlighted, and Enter took it over the typed value (0.52 code review,
|
|
239
|
+
// combobox.tsx). An ArrowDown that opens the list sets both at once, and keeps its row.
|
|
240
|
+
if (!open && active !== -1) setActive(-1);
|
|
226
241
|
// The lock (see `lockedKeyDown`): a lock arriving while the list is up closes it,
|
|
227
242
|
// adjusted while rendering so no frame offers a row that can no longer be taken.
|
|
228
243
|
const lock = useLockReason(commit, disabledReason);
|
|
@@ -264,6 +279,9 @@ export function Combobox(props: ComboboxProps) {
|
|
|
264
279
|
const query = typing ? value.trim() : "";
|
|
265
280
|
// Folded as every kit list folds (DUP-5): "zurich" finds Zürich, by the locale's case.
|
|
266
281
|
const locale = useKitLocale();
|
|
282
|
+
// The live status's words (INP-6): the result count and "No results", as the panel
|
|
283
|
+
// pickers say them.
|
|
284
|
+
const labels = useKitLabels("combobox", DEFAULT_COMBOBOX_LABELS);
|
|
267
285
|
const matches = useMemo(() => {
|
|
268
286
|
const seen = new Set<string>();
|
|
269
287
|
const uniq = options.filter((o) => o && !seen.has(o) && seen.add(o));
|
|
@@ -272,13 +290,14 @@ export function Combobox(props: ComboboxProps) {
|
|
|
272
290
|
if (!query) {
|
|
273
291
|
ranked = uniq.slice(0, cap);
|
|
274
292
|
} else {
|
|
275
|
-
//
|
|
276
|
-
//
|
|
277
|
-
|
|
278
|
-
|
|
279
|
-
|
|
293
|
+
// Every word of the query somewhere in the name (0.51.4's rule, which this list
|
|
294
|
+
// was said to have and did not: refactor audit 2026-10-30, DUP-4), ranked by the
|
|
295
|
+
// WHOLE query — the whole name, then prefix matches, then substring matches, then
|
|
296
|
+
// the names that hold the words apart (`searchRanked`, each name folded once). A
|
|
297
|
+
// stable sort keeps the pool's order within a rank.
|
|
298
|
+
ranked = searchRanked(uniq, query, (o) => [o], { locale })
|
|
280
299
|
.sort((a, b) => a.rank - b.rank)
|
|
281
|
-
.map((x) => x.
|
|
300
|
+
.map((x) => x.row)
|
|
282
301
|
.slice(0, cap);
|
|
283
302
|
}
|
|
284
303
|
if (!groupBy) return ranked;
|
|
@@ -296,27 +315,22 @@ export function Combobox(props: ComboboxProps) {
|
|
|
296
315
|
}, [options, query, groupBy, maxSuggestions, isPhone, locale]);
|
|
297
316
|
|
|
298
317
|
/**
|
|
299
|
-
*
|
|
318
|
+
* The rows cut into their groups — computed once for both lists, each run a
|
|
319
|
+
* `role="group"` its heading names (INP-8). Without `groupBy`, one bare run.
|
|
300
320
|
*
|
|
301
|
-
* The desktop list had
|
|
302
|
-
* `matches[matches.indexOf(o) - 1]`, which is a scan of the list per row and
|
|
303
|
-
* per heading test. That is quadratic in the sheet's own cap of 50, on the
|
|
304
|
-
* that runs on the slowest hardware we ship to — and it answers the wrong
|
|
305
|
-
* besides: `indexOf` finds the FIRST row with that string, so a duplicated
|
|
306
|
-
* would have compared against a neighbour it is not next to. (`matches`
|
|
307
|
-
* today; that is a property of the memo above, not of the row being
|
|
321
|
+
* The desktop list had the boundaries as `matches[i - 1]`, which is free; the sheet had
|
|
322
|
+
* them as `matches[matches.indexOf(o) - 1]`, which is a scan of the list per row and
|
|
323
|
+
* another per heading test. That is quadratic in the sheet's own cap of 50, on the
|
|
324
|
+
* branch that runs on the slowest hardware we ship to — and it answers the wrong
|
|
325
|
+
* question besides: `indexOf` finds the FIRST row with that string, so a duplicated
|
|
326
|
+
* option would have compared against a neighbour it is not next to. (`matches`
|
|
327
|
+
* de-duplicates today; that is a property of the memo above, not of the row being
|
|
328
|
+
* rendered.)
|
|
308
329
|
*/
|
|
309
|
-
const
|
|
310
|
-
|
|
311
|
-
|
|
312
|
-
|
|
313
|
-
matches.forEach((o, i) => {
|
|
314
|
-
const group = groupBy(o);
|
|
315
|
-
if (group != null && group !== prev) heads.set(i, group);
|
|
316
|
-
prev = group;
|
|
317
|
-
});
|
|
318
|
-
return heads;
|
|
319
|
-
}, [matches, groupBy]);
|
|
330
|
+
const runs = useMemo<GroupRun<string>[]>(
|
|
331
|
+
() => (groupBy ? groupRuns(matches, groupBy) : [{ group: null, start: 0, rows: matches }]),
|
|
332
|
+
[matches, groupBy],
|
|
333
|
+
);
|
|
320
334
|
|
|
321
335
|
const take = (v: string) => {
|
|
322
336
|
if (locked) return;
|
|
@@ -328,17 +342,6 @@ export function Combobox(props: ComboboxProps) {
|
|
|
328
342
|
setTyping(false);
|
|
329
343
|
};
|
|
330
344
|
|
|
331
|
-
// Offered only when the typed text is genuinely NOT in the pool: an exact
|
|
332
|
-
// (case-insensitive) match is an existing entry the list is already showing, and a
|
|
333
|
-
// second way to pick it would be noise. Compared against `options`, not `matches` —
|
|
334
|
-
// `matches` is capped, so a pool of 300 payees would otherwise offer to "add" one
|
|
335
|
-
// that exists but fell off the end of the list.
|
|
336
|
-
// What the field claims the keyboard is on. Only on a pointer device: the phone
|
|
337
|
-
// renders its rows in a {@link PickerSheet} whose own search box owns focus, and a
|
|
338
|
-
// field pointing at an id that is not there is worse than one pointing nowhere.
|
|
339
|
-
const activeId = !isPhone && active >= 0 && active < matches.length ? optionId(active) : undefined;
|
|
340
|
-
useActiveOptionScroll(activeId);
|
|
341
|
-
|
|
342
345
|
// While locked the field sits in the reason's Tooltip — in a fragment with a hidden
|
|
343
346
|
// copy of the reason, Button's anatomy; `block` so a full-width field stays full width.
|
|
344
347
|
const withLock = (box: ReactNode) =>
|
|
@@ -350,21 +353,81 @@ export function Combobox(props: ComboboxProps) {
|
|
|
350
353
|
box
|
|
351
354
|
);
|
|
352
355
|
|
|
356
|
+
// Offered only when the typed text is genuinely NOT in the pool: an exact match —
|
|
357
|
+
// folded as the list matches, so "cafe" is Café ({@link sameName}, DUP-5 in the
|
|
358
|
+
// 2026-10-30 refactor audit) — is an existing entry the list is already showing, and a
|
|
359
|
+
// second way to pick it would be noise. Compared against `options`, not `matches` —
|
|
360
|
+
// `matches` is capped, so a pool of 300 payees would otherwise offer to "add" one
|
|
361
|
+
// that exists but fell off the end of the list.
|
|
353
362
|
const typed = value.trim();
|
|
354
363
|
const createRow =
|
|
355
|
-
createLabel && typed.length > 0 && !options.some((o) => o
|
|
356
|
-
? createLabel(typed)
|
|
357
|
-
: null;
|
|
364
|
+
createLabel && typed.length > 0 && !options.some((o) => sameName(o, typed, locale)) ? createLabel(typed) : null;
|
|
358
365
|
|
|
366
|
+
// Whether a list shows, the row the keyboard is on — named by the field, or on a phone
|
|
367
|
+
// by the sheet's own search box, which takes the same keys (INP-6, 0.34's BUG-5 for
|
|
368
|
+
// this field) — and the live status: the family's one rule for a typed list.
|
|
369
|
+
const { showing, expanded, activeOption, statusRegion } = useTypedListStatus({
|
|
370
|
+
isPhone,
|
|
371
|
+
open,
|
|
372
|
+
inert,
|
|
373
|
+
rowCount: matches.length,
|
|
374
|
+
extraRow: Boolean(createRow),
|
|
375
|
+
query,
|
|
376
|
+
active: active < matches.length ? active : -1,
|
|
377
|
+
optionId,
|
|
378
|
+
labels,
|
|
379
|
+
});
|
|
359
380
|
// The list is a layer on the Escape stack while it SHOWS (Wave 2, DUP-1): an Escape
|
|
360
381
|
// over an empty "open" list is the dialog's, as it always was. On a phone the sheet
|
|
361
382
|
// is the layer.
|
|
362
|
-
const showing = !isPhone && open && !inert && (matches.length > 0 || Boolean(createRow));
|
|
363
383
|
useDismissLayer(showing, () => {
|
|
364
384
|
setOpen(false);
|
|
365
385
|
setActive(-1);
|
|
366
386
|
});
|
|
367
387
|
|
|
388
|
+
/** The list's keys — in the field and, on a phone, in the sheet's search box. Enter
|
|
389
|
+
* with no row highlighted is "I mean what I typed" in both. */
|
|
390
|
+
const listKeyDown = (e: KeyboardEvent<HTMLInputElement>) => {
|
|
391
|
+
if (e.key === "ArrowDown") {
|
|
392
|
+
e.preventDefault();
|
|
393
|
+
setOpen(true);
|
|
394
|
+
setActive((i) => Math.min(i + 1, matches.length - 1));
|
|
395
|
+
} else if (e.key === "ArrowUp") {
|
|
396
|
+
e.preventDefault();
|
|
397
|
+
setActive((i) => Math.max(i - 1, 0));
|
|
398
|
+
} else if (e.key === "Enter") {
|
|
399
|
+
// The Enter that confirms an IME composition is the IME's: it picks no row and
|
|
400
|
+
// submits nothing (BUG-9).
|
|
401
|
+
if (isImeEnter(e)) return;
|
|
402
|
+
if (open && active >= 0 && active < matches.length) {
|
|
403
|
+
e.preventDefault();
|
|
404
|
+
take(matches[active]);
|
|
405
|
+
} else {
|
|
406
|
+
// No row highlighted: the typed text is the answer. `preventDefault` only when a
|
|
407
|
+
// caller is taking Enter, so a plain form submit is otherwise left alone.
|
|
408
|
+
if (onSubmit) e.preventDefault();
|
|
409
|
+
setOpen(false);
|
|
410
|
+
onSubmit?.();
|
|
411
|
+
}
|
|
412
|
+
}
|
|
413
|
+
};
|
|
414
|
+
|
|
415
|
+
/** The rows in their runs — each group a `role="group"` its heading names (INP-8) —
|
|
416
|
+
* for the sheet or the anchored list; `row` draws one option, `grouped` when it
|
|
417
|
+
* stands under a heading. `matches` is group-contiguous, so the boundaries are a
|
|
418
|
+
* property of the list rather than of the branch drawing it (see `runs`). */
|
|
419
|
+
const groupedRows = (sheet: boolean, row: (o: string, i: number, grouped: boolean) => ReactNode) => (
|
|
420
|
+
<GroupedOptions
|
|
421
|
+
runs={runs}
|
|
422
|
+
listboxId={listboxId}
|
|
423
|
+
rowKey={(o) => o}
|
|
424
|
+
row={row}
|
|
425
|
+
// The list's first item sits closer to its top edge; the create row comes first
|
|
426
|
+
// when there is one.
|
|
427
|
+
headingClassName={(run) => (sheet ? SHEET_HEADING_CLASS : anchoredHeadingClass(run, !createRow))}
|
|
428
|
+
/>
|
|
429
|
+
);
|
|
430
|
+
|
|
368
431
|
return (
|
|
369
432
|
// `rest` dresses the outer box — a `data-tour` anchor, a test id. Not the NAME,
|
|
370
433
|
// description, invalid or required state: those belong on the <input> below,
|
|
@@ -401,13 +464,15 @@ export function Combobox(props: ComboboxProps) {
|
|
|
401
464
|
// field otherwise (dev#477: a field with neither announces only its text).
|
|
402
465
|
aria-label={ariaLabel}
|
|
403
466
|
role="combobox"
|
|
404
|
-
aria-expanded={
|
|
467
|
+
aria-expanded={expanded}
|
|
405
468
|
// The list this field is the mouth of. Required by the role, and the half
|
|
406
469
|
// that was missing: the field said it was expanded and never said what it
|
|
407
470
|
// had expanded, so a reader had no way from the box to the options
|
|
408
471
|
// (ESLint's `role-has-required-aria-props`, the audit's §a11y).
|
|
409
472
|
aria-controls={listboxId}
|
|
410
|
-
|
|
473
|
+
// Only on a pointer device: on a phone the sheet's own search box holds
|
|
474
|
+
// focus and names the row, and the field behind it says nothing.
|
|
475
|
+
aria-activedescendant={isPhone ? undefined : activeOption}
|
|
411
476
|
aria-autocomplete="list"
|
|
412
477
|
aria-invalid={field.isInvalid || undefined}
|
|
413
478
|
aria-describedby={mergeDescribedBy(field.describedBy, locked && lock.reasonId)}
|
|
@@ -431,6 +496,7 @@ export function Combobox(props: ComboboxProps) {
|
|
|
431
496
|
if (isQuietFocus(e.currentTarget)) return;
|
|
432
497
|
setOpen(true);
|
|
433
498
|
setTyping(false);
|
|
499
|
+
setActive(-1);
|
|
434
500
|
// The sheet carries its own input, so the field behind it must not also
|
|
435
501
|
// pull up the keyboard and scroll the page under the dialog.
|
|
436
502
|
if (isPhone) sheetInputRef.current?.focus();
|
|
@@ -443,7 +509,10 @@ export function Combobox(props: ComboboxProps) {
|
|
|
443
509
|
onClick={() => {
|
|
444
510
|
if (locked) return;
|
|
445
511
|
setOpen(true);
|
|
512
|
+
// The whole pool again, so no row of the typed list is the keyboard's
|
|
513
|
+
// (0.52 code review, combobox.tsx — see `active`).
|
|
446
514
|
setTyping(false);
|
|
515
|
+
setActive(-1);
|
|
447
516
|
}}
|
|
448
517
|
// `inputMode="none"` rather than readOnly: the field must not look
|
|
449
518
|
// uneditable (FIELD_BASE greys a read-only field since dev#468) and must
|
|
@@ -459,29 +528,8 @@ export function Combobox(props: ComboboxProps) {
|
|
|
459
528
|
}}
|
|
460
529
|
onKeyDown={(e) => {
|
|
461
530
|
if (locked) return lockedKeyDown(e);
|
|
462
|
-
|
|
463
|
-
|
|
464
|
-
setOpen(true);
|
|
465
|
-
setActive((i) => Math.min(i + 1, matches.length - 1));
|
|
466
|
-
} else if (e.key === "ArrowUp") {
|
|
467
|
-
e.preventDefault();
|
|
468
|
-
setActive((i) => Math.max(i - 1, 0));
|
|
469
|
-
} else if (e.key === "Enter") {
|
|
470
|
-
// The Enter that confirms an IME composition is the IME's: it picks no
|
|
471
|
-
// row and submits nothing (BUG-9).
|
|
472
|
-
if (isImeEnter(e)) return;
|
|
473
|
-
if (open && active >= 0 && active < matches.length) {
|
|
474
|
-
e.preventDefault();
|
|
475
|
-
take(matches[active]);
|
|
476
|
-
} else {
|
|
477
|
-
// No row highlighted: the typed text is the answer. `preventDefault`
|
|
478
|
-
// only when a caller is taking Enter, so a plain form submit is
|
|
479
|
-
// otherwise left alone.
|
|
480
|
-
if (onSubmit) e.preventDefault();
|
|
481
|
-
setOpen(false);
|
|
482
|
-
onSubmit?.();
|
|
483
|
-
}
|
|
484
|
-
} else if (e.key === "Escape") {
|
|
531
|
+
listKeyDown(e);
|
|
532
|
+
if (e.key === "Escape") {
|
|
485
533
|
// A list that is SHOWING is the top of the Escape stack, and the key
|
|
486
534
|
// closes it and stops here: a Modal or FullBleedDialog around the field
|
|
487
535
|
// otherwise closed with it, form and all (round 0.34 BUG-1). With no
|
|
@@ -536,6 +584,8 @@ export function Combobox(props: ComboboxProps) {
|
|
|
536
584
|
)}
|
|
537
585
|
<FieldCaption parts={hintParts} />
|
|
538
586
|
{field.errorEl}
|
|
587
|
+
{/* The live status — see `useTypedListStatus` for where it goes and why. */}
|
|
588
|
+
{!isPhone && statusRegion}
|
|
539
589
|
{isPhone && (
|
|
540
590
|
<PickerSheet
|
|
541
591
|
open={open && !inert}
|
|
@@ -547,11 +597,17 @@ export function Combobox(props: ComboboxProps) {
|
|
|
547
597
|
query={value}
|
|
548
598
|
onQueryChange={(v) => {
|
|
549
599
|
onChange(v);
|
|
600
|
+
setActive(-1);
|
|
550
601
|
setTyping(true);
|
|
551
602
|
}}
|
|
552
603
|
searchPlaceholder={searchPlaceholder ?? placeholder}
|
|
553
604
|
inputRef={sheetInputRef}
|
|
554
605
|
closeLabel={closeLabel}
|
|
606
|
+
// The field's own keys, in the box focus is in while the sheet is up: arrows
|
|
607
|
+
// and Enter there did nothing (INP-6, as BUG-5 gave the panel pickers).
|
|
608
|
+
onSearchKeyDown={listKeyDown}
|
|
609
|
+
listboxId={listboxId}
|
|
610
|
+
activeId={activeOption}
|
|
555
611
|
>
|
|
556
612
|
<ul id={listboxId} role="listbox">
|
|
557
613
|
{createRow && (
|
|
@@ -570,37 +626,28 @@ export function Combobox(props: ComboboxProps) {
|
|
|
570
626
|
</button>
|
|
571
627
|
</li>
|
|
572
628
|
)}
|
|
573
|
-
{
|
|
574
|
-
|
|
575
|
-
|
|
576
|
-
|
|
577
|
-
{
|
|
578
|
-
|
|
579
|
-
|
|
580
|
-
|
|
581
|
-
|
|
582
|
-
|
|
583
|
-
|
|
584
|
-
|
|
585
|
-
|
|
586
|
-
</li>
|
|
629
|
+
{groupedRows(true, (o, i) => (
|
|
630
|
+
<li role="presentation">
|
|
631
|
+
<button
|
|
632
|
+
type="button"
|
|
633
|
+
id={optionId(i)}
|
|
634
|
+
role="option"
|
|
635
|
+
aria-selected={o === value}
|
|
636
|
+
onClick={() => take(o)}
|
|
637
|
+
className={cn(
|
|
638
|
+
SHEET_ROW_CLASS,
|
|
639
|
+
// The row the sheet's arrows are on.
|
|
640
|
+
i === active && "bg-active",
|
|
641
|
+
optionAdornment && "flex items-center justify-between gap-2",
|
|
587
642
|
)}
|
|
588
|
-
|
|
589
|
-
|
|
590
|
-
|
|
591
|
-
|
|
592
|
-
|
|
593
|
-
|
|
594
|
-
className={cn(SHEET_ROW_CLASS, optionAdornment && "flex items-center justify-between gap-2")}
|
|
595
|
-
>
|
|
596
|
-
{optionAdornment ? <span className="truncate-until-large">{o}</span> : o}
|
|
597
|
-
{optionAdornment?.(o)}
|
|
598
|
-
</button>
|
|
599
|
-
</li>
|
|
600
|
-
</Fragment>
|
|
601
|
-
);
|
|
602
|
-
})}
|
|
643
|
+
>
|
|
644
|
+
{optionAdornment ? <span className="truncate-until-large">{o}</span> : o}
|
|
645
|
+
{optionAdornment?.(o)}
|
|
646
|
+
</button>
|
|
647
|
+
</li>
|
|
648
|
+
))}
|
|
603
649
|
</ul>
|
|
650
|
+
{statusRegion}
|
|
604
651
|
</PickerSheet>
|
|
605
652
|
)}
|
|
606
653
|
{showing && (
|
|
@@ -624,62 +671,44 @@ export function Combobox(props: ComboboxProps) {
|
|
|
624
671
|
</button>
|
|
625
672
|
</li>
|
|
626
673
|
)}
|
|
627
|
-
{
|
|
628
|
-
|
|
629
|
-
|
|
630
|
-
|
|
631
|
-
|
|
632
|
-
|
|
633
|
-
|
|
634
|
-
|
|
635
|
-
|
|
636
|
-
|
|
637
|
-
|
|
638
|
-
|
|
639
|
-
|
|
640
|
-
|
|
641
|
-
|
|
642
|
-
|
|
643
|
-
|
|
674
|
+
{groupedRows(false, (o, i, grouped) => (
|
|
675
|
+
<li role="presentation">
|
|
676
|
+
<button
|
|
677
|
+
type="button"
|
|
678
|
+
id={optionId(i)}
|
|
679
|
+
role="option"
|
|
680
|
+
// CHOSEN, not highlighted. The row the arrows are on is named by the
|
|
681
|
+
// field's `aria-activedescendant`; saying "selected" for it would tell a
|
|
682
|
+
// reader that the row they are passing over is already the answer.
|
|
683
|
+
aria-selected={o === value}
|
|
684
|
+
// Focus stays in the field — that is what `aria-activedescendant` is
|
|
685
|
+
// for — so the rows are not tab stops.
|
|
686
|
+
tabIndex={-1}
|
|
687
|
+
onMouseDown={(e) => {
|
|
688
|
+
// mousedown (not click) so the blur from the input firing first
|
|
689
|
+
// doesn't close the list before the selection registers.
|
|
690
|
+
e.preventDefault();
|
|
691
|
+
take(o);
|
|
692
|
+
}}
|
|
693
|
+
onMouseEnter={() => setActive(i)}
|
|
694
|
+
className={cn(
|
|
695
|
+
rowClass(i === active),
|
|
696
|
+
// Every row of a group indented under its heading — it was the first
|
|
697
|
+
// row of each group only.
|
|
698
|
+
grouped && "ps-6",
|
|
699
|
+
// A row with a badge is a flex row so the label truncates and the
|
|
700
|
+
// badge keeps its width; without one it stays the plain block the
|
|
701
|
+
// other lists render, so nothing shifts for callers that pass none.
|
|
702
|
+
// From Large up the label wraps instead (`truncate-until-large`,
|
|
703
|
+
// text size §10.17, round 0.34 T1), as the badge-less row does.
|
|
704
|
+
optionAdornment && "flex items-center justify-between gap-2",
|
|
644
705
|
)}
|
|
645
|
-
|
|
646
|
-
|
|
647
|
-
|
|
648
|
-
|
|
649
|
-
|
|
650
|
-
|
|
651
|
-
// the field's `aria-activedescendant`; saying "selected" for it
|
|
652
|
-
// would tell a reader that the row they are passing over is
|
|
653
|
-
// already the answer.
|
|
654
|
-
aria-selected={o === value}
|
|
655
|
-
// Focus stays in the field — that is what
|
|
656
|
-
// `aria-activedescendant` is for — so the rows are not tab stops.
|
|
657
|
-
tabIndex={-1}
|
|
658
|
-
onMouseDown={(e) => {
|
|
659
|
-
// mousedown (not click) so the blur from the input firing first
|
|
660
|
-
// doesn't close the list before the selection registers.
|
|
661
|
-
e.preventDefault();
|
|
662
|
-
take(o);
|
|
663
|
-
}}
|
|
664
|
-
onMouseEnter={() => setActive(i)}
|
|
665
|
-
className={cn(
|
|
666
|
-
rowClass(i === active),
|
|
667
|
-
group != null && "ps-6",
|
|
668
|
-
// A row with a badge is a flex row so the label truncates and the
|
|
669
|
-
// badge keeps its width; without one it stays the plain block the
|
|
670
|
-
// other lists render, so nothing shifts for callers that pass none.
|
|
671
|
-
// From Large up the label wraps instead (`truncate-until-large`,
|
|
672
|
-
// text size §10.17, round 0.34 T1), as the badge-less row does.
|
|
673
|
-
optionAdornment && "flex items-center justify-between gap-2",
|
|
674
|
-
)}
|
|
675
|
-
>
|
|
676
|
-
{optionAdornment ? <span className="truncate-until-large">{o}</span> : o}
|
|
677
|
-
{optionAdornment?.(o)}
|
|
678
|
-
</button>
|
|
679
|
-
</li>
|
|
680
|
-
</Fragment>
|
|
681
|
-
);
|
|
682
|
-
})}
|
|
706
|
+
>
|
|
707
|
+
{optionAdornment ? <span className="truncate-until-large">{o}</span> : o}
|
|
708
|
+
{optionAdornment?.(o)}
|
|
709
|
+
</button>
|
|
710
|
+
</li>
|
|
711
|
+
))}
|
|
683
712
|
</SuggestionList>
|
|
684
713
|
)}
|
|
685
714
|
</div>
|
|
@@ -9,7 +9,6 @@ import { Button } from "./button";
|
|
|
9
9
|
import { IconButton } from "./icon-button";
|
|
10
10
|
import type { ButtonSize, ButtonTone, ButtonVariant } from "./button-look";
|
|
11
11
|
import type { IconButtonSize, IconButtonTone } from "./icon-button";
|
|
12
|
-
import { Tooltip } from "./tooltip";
|
|
13
12
|
import type { TooltipSide } from "./tooltip";
|
|
14
13
|
import { DEFAULT_COPY_BUTTON_LABELS } from "./copy-button-labels";
|
|
15
14
|
|
|
@@ -31,8 +30,9 @@ export interface CopyButtonProps extends Omit<ButtonHTMLAttributes<HTMLButtonEle
|
|
|
31
30
|
/** What to copy. A function is read at click time — for a value that is expensive
|
|
32
31
|
* to build (a CSV of the table) or that changes under the button. */
|
|
33
32
|
text: string | (() => string);
|
|
34
|
-
/** `icon` (default): a square icon button whose
|
|
35
|
-
*
|
|
33
|
+
/** `icon` (default): a square icon button whose glyph and colour show the result — its
|
|
34
|
+
* words in a bubble, and from Large up beside the glyph, as every labelled IconButton
|
|
35
|
+
* shows them. `label`: a text button whose words change to the result. */
|
|
36
36
|
variant?: "icon" | "label";
|
|
37
37
|
/** The idle accessible name — and, in the `label` variant, the visible text:
|
|
38
38
|
* "Copy IBAN" says WHAT is copied, which a row of three copy icons needs. Default
|
|
@@ -82,9 +82,9 @@ const ICONS: Record<CopyState, typeof Copy> = { idle: Copy, copied: Check, faile
|
|
|
82
82
|
* failure goes through an ASSERTIVE region and a success through a polite one — the
|
|
83
83
|
* failure is the news that changes what they do next.
|
|
84
84
|
*
|
|
85
|
-
* The icon variant keeps the SAME accessible name in every state
|
|
86
|
-
* itself under the focus is announced inconsistently across
|
|
87
|
-
* is the channel that is actually heard.
|
|
85
|
+
* The icon variant keeps the SAME accessible name in every state, and the same words on
|
|
86
|
+
* screen. A button renaming itself under the focus is announced inconsistently across
|
|
87
|
+
* readers; the live region is the channel that is actually heard.
|
|
88
88
|
*/
|
|
89
89
|
export function CopyButton({
|
|
90
90
|
text,
|
|
@@ -156,25 +156,36 @@ export function CopyButton({
|
|
|
156
156
|
);
|
|
157
157
|
}
|
|
158
158
|
|
|
159
|
+
// IconButton names itself (0.52, refactor audit 2026-10-30, DSP-21): `label` is the
|
|
160
|
+
// bubble — and the text beside the glyph at Large, as on every labelled IconButton —
|
|
161
|
+
// and `aria-label` keeps the name steady. A Tooltip of our own round it cloned
|
|
162
|
+
// `aria-describedby` onto the button, which then read "Copy, button, Copy".
|
|
163
|
+
//
|
|
164
|
+
// The idle words, in every state (0.52 code review, deep, charts, finding 8). As the
|
|
165
|
+
// state, "Copied" stood at Large beside the glyph of a button named "Copy IBAN": the pill
|
|
166
|
+
// changed width on every copy, and the words on screen were not in the name a voice
|
|
167
|
+
// user says to press it (WCAG 2.5.3, label in name). The glyph and its colour show the
|
|
168
|
+
// result, and the live regions say it.
|
|
159
169
|
return (
|
|
160
170
|
<>
|
|
161
|
-
<
|
|
162
|
-
|
|
163
|
-
|
|
164
|
-
|
|
165
|
-
|
|
166
|
-
|
|
167
|
-
|
|
168
|
-
|
|
169
|
-
|
|
170
|
-
|
|
171
|
-
|
|
172
|
-
|
|
173
|
-
|
|
174
|
-
|
|
175
|
-
|
|
176
|
-
|
|
177
|
-
|
|
171
|
+
<IconButton
|
|
172
|
+
type="button"
|
|
173
|
+
{...rest}
|
|
174
|
+
disabled={disabled}
|
|
175
|
+
label={idleText}
|
|
176
|
+
aria-label={idleText}
|
|
177
|
+
tooltipSide={tooltipSide}
|
|
178
|
+
tooltipPortal={tooltipPortal}
|
|
179
|
+
variant={buttonVariant ?? "ghost"}
|
|
180
|
+
size={(size ?? "sm") as IconButtonSize}
|
|
181
|
+
tone={tone as IconButtonTone | undefined}
|
|
182
|
+
stopPropagation={stopPropagation}
|
|
183
|
+
data-state={state}
|
|
184
|
+
onClick={() => void onClick()}
|
|
185
|
+
className={cn(iconTone, className)}
|
|
186
|
+
>
|
|
187
|
+
<Icon aria-hidden />
|
|
188
|
+
</IconButton>
|
|
178
189
|
{regions}
|
|
179
190
|
</>
|
|
180
191
|
);
|
|
@@ -3,7 +3,7 @@ import type { ComponentPropsWithoutRef, ReactNode, Ref } from "react";
|
|
|
3
3
|
import { X } from "lucide-react";
|
|
4
4
|
import { cn } from "../lib/cn";
|
|
5
5
|
import { COUNTRY_CODES, countryName, normalizeCountryCode } from "../lib/countries";
|
|
6
|
-
import {
|
|
6
|
+
import { searchRanked } from "../lib/text-match";
|
|
7
7
|
import { FieldChevron, FIELD_FLOATING_PAD, FIELD_INVALID, FIELD_TRIGGER, FloatingField } from "./field-base";
|
|
8
8
|
import {
|
|
9
9
|
assignRef,
|
|
@@ -178,17 +178,22 @@ interface Entry {
|
|
|
178
178
|
name: string;
|
|
179
179
|
}
|
|
180
180
|
|
|
181
|
-
/**
|
|
182
|
-
*
|
|
183
|
-
*
|
|
184
|
-
*
|
|
185
|
-
*
|
|
181
|
+
/** Every word of the query in the name, or the whole code (0.51.4's rule: "kinshasa
|
|
182
|
+
* congo" finds Congo - Kinshasa; refactor audit 2026-10-30, DUP-4), best rank first; a
|
|
183
|
+
* stable sort, so equal ranks keep the collated (or preferred) order they came in. The
|
|
184
|
+
* rank is the kit's one, for the WHOLE query (`rankMatch`, DUP-5 — written here first):
|
|
185
|
+
* the code itself (a two-letter query "ch" means Switzerland before it means Chad), then
|
|
186
|
+
* the start of the name, then anywhere in it, then the words apart (`searchRanked`, each
|
|
187
|
+
* name and code folded once), with accents and case folded — "osterreich" finds
|
|
188
|
+
* Österreich, "cote" Côte d'Ivoire.
|
|
189
|
+
*
|
|
190
|
+
* A word is the code or it is not: searched INSIDE the code, as one more text, "w"
|
|
191
|
+
* listed Aruba (AW) and Samoa (WS) and "d" Germany (DE), names with nothing of the
|
|
192
|
+
* query in them (0.52 code review, country-select.tsx). */
|
|
186
193
|
function search(entries: Entry[], q: string, locale: string): Entry[] {
|
|
187
|
-
return entries
|
|
188
|
-
.
|
|
189
|
-
.
|
|
190
|
-
.sort((a, b) => a.r - b.r)
|
|
191
|
-
.map((x) => x.e);
|
|
194
|
+
return searchRanked(entries, q, (e) => [e.name], { code: (e) => e.code, locale })
|
|
195
|
+
.sort((a, b) => a.rank - b.rank)
|
|
196
|
+
.map((x) => x.row);
|
|
192
197
|
}
|
|
193
198
|
|
|
194
199
|
function toOption(e: Entry, flags: boolean, group?: string): ComboOption<string> {
|