@eifi1/ui-kit 0.51.7 → 0.52.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +141 -23
- package/dist/account/account-parts.d.ts +10 -8
- package/dist/account/account-parts.js +1 -18
- package/dist/account/account-parts.js.map +1 -1
- package/dist/account/data-export-setting-labels.js +1 -1
- package/dist/account/data-export-setting-labels.js.map +1 -1
- package/dist/account/delete-account-setting-labels.js +1 -1
- package/dist/account/delete-account-setting-labels.js.map +1 -1
- package/dist/account/email-change-setting-labels.js +1 -1
- package/dist/account/email-change-setting-labels.js.map +1 -1
- package/dist/account/passkeys-setting.d.ts +9 -2
- package/dist/account/passkeys-setting.js +41 -29
- package/dist/account/passkeys-setting.js.map +1 -1
- package/dist/account/sessions-setting.d.ts +3 -2
- package/dist/account/sessions-setting.js +10 -8
- package/dist/account/sessions-setting.js.map +1 -1
- package/dist/admin/admin-action-confirm.js +1 -3
- package/dist/admin/admin-action-confirm.js.map +1 -1
- package/dist/admin/admin-parts.d.ts +6 -3
- package/dist/admin/admin-parts.js +6 -21
- package/dist/admin/admin-parts.js.map +1 -1
- package/dist/admin/mail-test-card-labels.js +1 -1
- package/dist/admin/mail-test-card-labels.js.map +1 -1
- package/dist/admin/plan-change-labels.d.ts +2 -2
- package/dist/admin/plan-change-labels.js +1 -17
- package/dist/admin/plan-change-labels.js.map +1 -1
- package/dist/admin/plan-change.d.ts +3 -42
- package/dist/admin/plan-change.js +1 -1
- package/dist/admin/plan-change.js.map +1 -1
- package/dist/admin/reviewer-scope-editor.js +3 -3
- package/dist/admin/reviewer-scope-editor.js.map +1 -1
- package/dist/auth/auth-errors-labels.d.ts +11 -0
- package/dist/auth/auth-errors-labels.js +13 -0
- package/dist/auth/auth-errors-labels.js.map +1 -0
- package/dist/auth/auth-errors.d.ts +7 -23
- package/dist/auth/auth-errors.js +2 -15
- package/dist/auth/auth-errors.js.map +1 -1
- package/dist/auth/complete-name-dialog.js +2 -1
- package/dist/auth/complete-name-dialog.js.map +1 -1
- package/dist/auth/forgot-password-form-labels.js +1 -1
- package/dist/auth/forgot-password-form-labels.js.map +1 -1
- package/dist/auth/forgot-password-form.js +7 -2
- package/dist/auth/forgot-password-form.js.map +1 -1
- package/dist/auth/register-form-labels.js +1 -1
- package/dist/auth/register-form-labels.js.map +1 -1
- package/dist/auth/reset-password-form-labels.js +1 -1
- package/dist/auth/reset-password-form-labels.js.map +1 -1
- package/dist/auth/reset-password-form.js +5 -1
- package/dist/auth/reset-password-form.js.map +1 -1
- package/dist/auth/sign-in-form-labels.js +1 -1
- package/dist/auth/sign-in-form-labels.js.map +1 -1
- package/dist/auth/status-parts.d.ts +0 -3
- package/dist/auth/status-parts.js +0 -4
- package/dist/auth/status-parts.js.map +1 -1
- package/dist/auth/verify-email-labels.js +1 -1
- package/dist/auth/verify-email-labels.js.map +1 -1
- package/dist/auth/verify-email.js +7 -2
- package/dist/auth/verify-email.js.map +1 -1
- package/dist/billing/cancel-subscription.d.ts +20 -8
- package/dist/billing/cancel-subscription.js +7 -5
- package/dist/billing/cancel-subscription.js.map +1 -1
- package/dist/billing/dialog-close.d.ts +29 -0
- package/dist/billing/dialog-close.js +8 -0
- package/dist/billing/dialog-close.js.map +1 -0
- package/dist/billing/plan-card.d.ts +14 -4
- package/dist/billing/plan-card.js +15 -8
- package/dist/billing/plan-card.js.map +1 -1
- package/dist/billing/plan-change-labels.d.ts +42 -0
- package/dist/billing/plan-change-labels.js +22 -0
- package/dist/billing/plan-change-labels.js.map +1 -0
- package/dist/billing/plan-switch.d.ts +19 -7
- package/dist/billing/plan-switch.js +8 -4
- package/dist/billing/plan-switch.js.map +1 -1
- package/dist/chart.d.ts +12 -0
- package/dist/chart.js +16 -1
- package/dist/chart.js.map +1 -1
- package/dist/components/account-chips.d.ts +5 -5
- package/dist/components/account-chips.js +11 -13
- package/dist/components/account-chips.js.map +1 -1
- package/dist/components/alert-banner.d.ts +16 -5
- package/dist/components/alert-banner.js +46 -1
- package/dist/components/alert-banner.js.map +1 -1
- package/dist/components/amount-input.d.ts +13 -0
- package/dist/components/amount-input.js +1 -0
- package/dist/components/amount-input.js.map +1 -1
- package/dist/components/autocomplete.js +57 -65
- package/dist/components/autocomplete.js.map +1 -1
- package/dist/components/bulk-action-bar.d.ts +12 -2
- package/dist/components/bulk-action-bar.js +65 -21
- package/dist/components/bulk-action-bar.js.map +1 -1
- package/dist/components/button-look.d.ts +5 -5
- package/dist/components/button-look.js.map +1 -1
- package/dist/components/button.d.ts +2 -2
- package/dist/components/button.js.map +1 -1
- package/dist/components/chart-edge.d.ts +16 -0
- package/dist/components/chart-edge.js +14 -1
- package/dist/components/chart-edge.js.map +1 -1
- package/dist/components/chart-figure.d.ts +13 -0
- package/dist/components/chart-figure.js +15 -0
- package/dist/components/chart-figure.js.map +1 -0
- package/dist/components/chart-zoom-core.js +1 -4
- package/dist/components/chart-zoom-core.js.map +1 -1
- package/dist/components/chart.d.ts +8 -1
- package/dist/components/chart.js +19 -10
- package/dist/components/chart.js.map +1 -1
- package/dist/components/combobox-core.d.ts +111 -2
- package/dist/components/combobox-core.js +148 -42
- package/dist/components/combobox-core.js.map +1 -1
- package/dist/components/combobox.d.ts +1 -1
- package/dist/components/combobox.js +141 -130
- package/dist/components/combobox.js.map +1 -1
- package/dist/components/copy-button.d.ts +6 -5
- package/dist/components/copy-button.js +5 -3
- package/dist/components/copy-button.js.map +1 -1
- package/dist/components/country-select.js +2 -2
- package/dist/components/country-select.js.map +1 -1
- package/dist/components/data-table-column-settings.d.ts +1 -1
- package/dist/components/data-table-column-settings.js +33 -7
- package/dist/components/data-table-column-settings.js.map +1 -1
- package/dist/components/data-table-filters.d.ts +4 -2
- package/dist/components/data-table-filters.js +2 -2
- package/dist/components/data-table-filters.js.map +1 -1
- package/dist/components/data-table-fit.d.ts +6 -4
- package/dist/components/data-table-fit.js +4 -1
- package/dist/components/data-table-fit.js.map +1 -1
- package/dist/components/data-table-groups.d.ts +1 -1
- package/dist/components/data-table-groups.js.map +1 -1
- package/dist/components/data-table-head.d.ts +1 -1
- package/dist/components/data-table-head.js +15 -12
- package/dist/components/data-table-head.js.map +1 -1
- package/dist/components/data-table-mobile.d.ts +12 -7
- package/dist/components/data-table-mobile.js +43 -30
- package/dist/components/data-table-mobile.js.map +1 -1
- package/dist/components/data-table-pagination.js +11 -6
- package/dist/components/data-table-pagination.js.map +1 -1
- package/dist/components/data-table-resize.d.ts +1 -1
- package/dist/components/data-table-resize.js.map +1 -1
- package/dist/components/data-table-row-actions.d.ts +2 -2
- package/dist/components/data-table-row-actions.js.map +1 -1
- package/dist/components/data-table-row.d.ts +6 -2
- package/dist/components/data-table-row.js +17 -10
- package/dist/components/data-table-row.js.map +1 -1
- package/dist/components/data-table-selection.d.ts +1 -1
- package/dist/components/data-table-selection.js.map +1 -1
- package/dist/components/data-table-shared.d.ts +10 -2
- package/dist/components/data-table-shared.js +18 -0
- package/dist/components/data-table-shared.js.map +1 -1
- package/dist/components/data-table-sort.d.ts +21 -2
- package/dist/components/data-table-sort.js +24 -0
- package/dist/components/data-table-sort.js.map +1 -1
- package/dist/components/data-table-virtual.d.ts +1 -1
- package/dist/components/data-table-virtual.js +18 -6
- package/dist/components/data-table-virtual.js.map +1 -1
- package/dist/components/data-table.d.ts +13 -4
- package/dist/components/data-table.js +139 -36
- package/dist/components/data-table.js.map +1 -1
- package/dist/components/date-field.d.ts +24 -2
- package/dist/components/date-field.js +33 -8
- package/dist/components/date-field.js.map +1 -1
- package/dist/components/date-picker.d.ts +15 -2
- package/dist/components/date-picker.js +55 -26
- package/dist/components/date-picker.js.map +1 -1
- package/dist/components/date-range-picker.d.ts +47 -20
- package/dist/components/date-range-picker.js +23 -7
- package/dist/components/date-range-picker.js.map +1 -1
- package/dist/components/error-boundary.js +37 -30
- package/dist/components/error-boundary.js.map +1 -1
- package/dist/components/{ui-labels.d.ts → field-base-labels.d.ts} +0 -2
- package/dist/components/{ui-labels.js → field-base-labels.js} +2 -9
- package/dist/components/field-base-labels.js.map +1 -0
- package/dist/components/field-base.d.ts +4 -3
- package/dist/components/field-base.js +3 -3
- package/dist/components/field-base.js.map +1 -1
- package/dist/components/field-sync-labels.d.ts +1 -0
- package/dist/components/field-sync-labels.js.map +1 -1
- package/dist/components/field-sync.d.ts +23 -1
- package/dist/components/field-sync.js.map +1 -1
- package/dist/components/form-actions.js +11 -5
- package/dist/components/form-actions.js.map +1 -1
- package/dist/components/hover-menu.d.ts +3 -0
- package/dist/components/hover-menu.js +5 -3
- package/dist/components/hover-menu.js.map +1 -1
- package/dist/components/icon-button.js +14 -9
- package/dist/components/icon-button.js.map +1 -1
- package/dist/components/inline-confirm.d.ts +43 -0
- package/dist/components/inline-confirm.js +67 -0
- package/dist/components/inline-confirm.js.map +1 -0
- package/dist/components/inline-entity-combobox.d.ts +4 -3
- package/dist/components/inline-entity-combobox.js +148 -140
- package/dist/components/inline-entity-combobox.js.map +1 -1
- package/dist/components/input.js +1 -1
- package/dist/components/input.js.map +1 -1
- package/dist/components/jump-calendar.js +28 -112
- package/dist/components/jump-calendar.js.map +1 -1
- package/dist/components/legal-page.d.ts +3 -1
- package/dist/components/legal-page.js +3 -2
- package/dist/components/legal-page.js.map +1 -1
- package/dist/components/legal.d.ts +4 -2
- package/dist/components/legal.js.map +1 -1
- package/dist/components/lightbox.d.ts +2 -2
- package/dist/components/lightbox.js +17 -6
- package/dist/components/lightbox.js.map +1 -1
- package/dist/components/list.d.ts +6 -2
- package/dist/components/list.js +3 -2
- package/dist/components/list.js.map +1 -1
- package/dist/components/measured-grid.d.ts +1 -1
- package/dist/components/measured-grid.js +2 -1
- package/dist/components/measured-grid.js.map +1 -1
- package/dist/components/mini-calendar.js +3 -5
- package/dist/components/mini-calendar.js.map +1 -1
- package/dist/components/modal.js +3 -1
- package/dist/components/modal.js.map +1 -1
- package/dist/components/month-grid.d.ts +55 -0
- package/dist/components/month-grid.js +148 -0
- package/dist/components/month-grid.js.map +1 -0
- package/dist/components/month-picker.d.ts +36 -4
- package/dist/components/month-picker.js +123 -146
- package/dist/components/month-picker.js.map +1 -1
- package/dist/components/multi-select.d.ts +2 -2
- package/dist/components/multi-select.js +11 -6
- package/dist/components/multi-select.js.map +1 -1
- package/dist/components/picker-sheet.js +2 -1
- package/dist/components/picker-sheet.js.map +1 -1
- package/dist/components/pie-chart-labels.d.ts +7 -0
- package/dist/components/pie-chart-labels.js +1 -0
- package/dist/components/pie-chart-labels.js.map +1 -1
- package/dist/components/pie-chart.d.ts +5 -3
- package/dist/components/pie-chart.js +7 -22
- package/dist/components/pie-chart.js.map +1 -1
- package/dist/components/popover.d.ts +3 -0
- package/dist/components/popover.js +7 -1
- package/dist/components/popover.js.map +1 -1
- package/dist/components/row-actions.js +2 -1
- package/dist/components/row-actions.js.map +1 -1
- package/dist/components/section-nav.d.ts +7 -0
- package/dist/components/section-nav.js.map +1 -1
- package/dist/components/series-chart-axes.d.ts +3 -3
- package/dist/components/series-chart-axes.js.map +1 -1
- package/dist/components/series-chart-labels.d.ts +7 -4
- package/dist/components/series-chart-labels.js.map +1 -1
- package/dist/components/series-chart.d.ts +31 -7
- package/dist/components/series-chart.js +72 -29
- package/dist/components/series-chart.js.map +1 -1
- package/dist/components/share-card.js +3 -3
- package/dist/components/share-card.js.map +1 -1
- package/dist/components/sign-chip-labels.d.ts +1 -0
- package/dist/components/sign-chip-labels.js.map +1 -1
- package/dist/components/sign-chip.d.ts +10 -1
- package/dist/components/sign-chip.js.map +1 -1
- package/dist/components/tabs-labels.d.ts +2 -0
- package/dist/components/tabs-labels.js +11 -0
- package/dist/components/tabs-labels.js.map +1 -0
- package/dist/components/tabs.d.ts +1 -1
- package/dist/components/tabs.js +1 -1
- package/dist/components/tabs.js.map +1 -1
- package/dist/components/toggle-legend.d.ts +2 -2
- package/dist/components/toggle-legend.js +6 -6
- package/dist/components/toggle-legend.js.map +1 -1
- package/dist/components/translation-review-editor.d.ts +4 -2
- package/dist/components/translation-review-editor.js +2 -3
- package/dist/components/translation-review-editor.js.map +1 -1
- package/dist/components/translation-review.d.ts +2 -1
- package/dist/components/translation-review.js +2 -2
- package/dist/components/translation-review.js.map +1 -1
- package/dist/components/treemap-labels.d.ts +26 -0
- package/dist/components/treemap-labels.js +10 -0
- package/dist/components/treemap-labels.js.map +1 -0
- package/dist/components/treemap-layout.d.ts +62 -0
- package/dist/components/treemap-layout.js +126 -0
- package/dist/components/treemap-layout.js.map +1 -0
- package/dist/components/treemap.d.ts +140 -17
- package/dist/components/treemap.js +324 -97
- package/dist/components/treemap.js.map +1 -1
- package/dist/components/use-table-state.d.ts +5 -5
- package/dist/components/use-table-state.js +4 -1
- package/dist/components/use-table-state.js.map +1 -1
- package/dist/data-table.d.ts +6 -2
- package/dist/data-table.js +7 -2
- package/dist/data-table.js.map +1 -1
- package/dist/eslint/index.js +1 -1
- package/dist/eslint/role-utilities.d.ts +36 -7
- package/dist/eslint/role-utilities.js +42 -9
- package/dist/eslint/role-utilities.js.map +1 -1
- package/dist/feedback/feedback-dialog.d.ts +25 -16
- package/dist/feedback/feedback-dialog.js +6 -2
- package/dist/feedback/feedback-dialog.js.map +1 -1
- package/dist/feedback/feedback-mutation.d.ts +30 -0
- package/dist/feedback/feedback-mutation.js +16 -0
- package/dist/feedback/feedback-mutation.js.map +1 -0
- package/dist/feedback/feedback-page-link.d.ts +53 -0
- package/dist/feedback/feedback-page-link.js +37 -0
- package/dist/feedback/feedback-page-link.js.map +1 -0
- package/dist/feedback/feedback-public-list.d.ts +12 -3
- package/dist/feedback/feedback-public-list.js +2 -1
- package/dist/feedback/feedback-public-list.js.map +1 -1
- package/dist/feedback/feedback-replies.d.ts +3 -1
- package/dist/feedback/feedback-replies.js +5 -4
- package/dist/feedback/feedback-replies.js.map +1 -1
- package/dist/feedback/feedback-row-detail-labels.js +5 -0
- package/dist/feedback/feedback-row-detail-labels.js.map +1 -1
- package/dist/feedback/feedback-row-detail.d.ts +64 -28
- package/dist/feedback/feedback-row-detail.js +30 -28
- package/dist/feedback/feedback-row-detail.js.map +1 -1
- package/dist/feedback/feedback-status-undo.d.ts +30 -11
- package/dist/feedback/feedback-status-undo.js +10 -15
- package/dist/feedback/feedback-status-undo.js.map +1 -1
- package/dist/feedback/feedback-submit-dialog.d.ts +1 -1
- package/dist/feedback/feedback-submit-dialog.js +1 -1
- package/dist/feedback/feedback-submit-dialog.js.map +1 -1
- package/dist/feedback/feedback-submit.js +9 -3
- package/dist/feedback/feedback-submit.js.map +1 -1
- package/dist/feedback/feedback-swipe.d.ts +1 -1
- package/dist/feedback/feedback-swipe.js.map +1 -1
- package/dist/feedback/feedback-table.d.ts +21 -9
- package/dist/feedback/feedback-table.js +45 -25
- package/dist/feedback/feedback-table.js.map +1 -1
- package/dist/feedback/feedback-thread-labels.d.ts +2 -2
- package/dist/feedback/feedback-thread-labels.js.map +1 -1
- package/dist/feedback/feedback-thread.d.ts +24 -23
- package/dist/feedback/feedback-thread.js +2 -1
- package/dist/feedback/feedback-thread.js.map +1 -1
- package/dist/feedback.d.ts +34 -0
- package/dist/feedback.js +42 -0
- package/dist/feedback.js.map +1 -1
- package/dist/hooks/use-focus-trap.d.ts +35 -0
- package/dist/hooks/use-focus-trap.js +6 -4
- package/dist/hooks/use-focus-trap.js.map +1 -1
- package/dist/hooks/use-hotkey.d.ts +5 -2
- package/dist/hooks/use-hotkey.js +5 -4
- package/dist/hooks/use-hotkey.js.map +1 -1
- package/dist/hooks/use-long-press.d.ts +7 -4
- package/dist/hooks/use-long-press.js +3 -0
- package/dist/hooks/use-long-press.js.map +1 -1
- package/dist/hooks/use-media-query.js +12 -4
- package/dist/hooks/use-media-query.js.map +1 -1
- package/dist/hooks/use-mounted.d.ts +22 -0
- package/dist/hooks/use-mounted.js +24 -0
- package/dist/hooks/use-mounted.js.map +1 -0
- package/dist/hooks/use-overlay-history.js +19 -3
- package/dist/hooks/use-overlay-history.js.map +1 -1
- package/dist/i18n/defaults.js +4 -5
- package/dist/i18n/defaults.js.map +1 -1
- package/dist/i18n/german.js +7 -1
- package/dist/i18n/german.js.map +1 -1
- package/dist/i18n/kit-labels.d.ts +9 -2
- package/dist/i18n/kit-labels.js.map +1 -1
- package/dist/i18n/locales/en.js +20 -41
- package/dist/i18n/locales/en.js.map +3 -3
- package/dist/i18n/locales/es.js +7 -1
- package/dist/i18n/locales/es.js.map +1 -1
- package/dist/i18n/locales/fr.js +20 -10
- package/dist/i18n/locales/fr.js.map +1 -1
- package/dist/i18n/locales/hu.js +9 -1
- package/dist/i18n/locales/hu.js.map +1 -1
- package/dist/i18n/locales/it.js +7 -1
- package/dist/i18n/locales/it.js.map +1 -1
- package/dist/i18n/locales/zh.js +8 -1
- package/dist/i18n/locales/zh.js.map +1 -1
- package/dist/i18n/review.js +5 -0
- package/dist/i18n/review.js.map +1 -1
- package/dist/index.d.ts +64 -17
- package/dist/index.js +77 -12
- package/dist/index.js.map +1 -1
- package/dist/landing/routing.d.ts +3 -1
- package/dist/landing/routing.js +4 -7
- package/dist/landing/routing.js.map +1 -1
- package/dist/lib/broadcast.d.ts +17 -0
- package/dist/lib/broadcast.js +30 -0
- package/dist/lib/broadcast.js.map +1 -0
- package/dist/lib/date-format.d.ts +37 -2
- package/dist/lib/date-format.js +34 -8
- package/dist/lib/date-format.js.map +1 -1
- package/dist/lib/day-format.d.ts +46 -0
- package/dist/lib/day-format.js +46 -0
- package/dist/lib/day-format.js.map +1 -0
- package/dist/lib/describe-failure.d.ts +14 -0
- package/dist/lib/describe-failure.js +9 -0
- package/dist/lib/describe-failure.js.map +1 -0
- package/dist/lib/direction.d.ts +16 -0
- package/dist/lib/direction.js +9 -1
- package/dist/lib/direction.js.map +1 -1
- package/dist/lib/focus-left.d.ts +63 -0
- package/dist/lib/focus-left.js +67 -0
- package/dist/lib/focus-left.js.map +1 -0
- package/dist/lib/format.js +5 -14
- package/dist/lib/format.js.map +1 -1
- package/dist/lib/http-status.d.ts +24 -0
- package/dist/lib/http-status.js +14 -0
- package/dist/lib/http-status.js.map +1 -0
- package/dist/lib/intl-cache.d.ts +14 -0
- package/dist/lib/intl-cache.js +15 -0
- package/dist/lib/intl-cache.js.map +1 -0
- package/dist/lib/isin.d.ts +10 -0
- package/dist/lib/isin.js.map +1 -1
- package/dist/lib/iso-day.d.ts +11 -0
- package/dist/lib/iso-day.js +8 -0
- package/dist/lib/iso-day.js.map +1 -0
- package/dist/lib/lazy-with-fallback.d.ts +31 -0
- package/dist/lib/lazy-with-fallback.js +40 -0
- package/dist/lib/lazy-with-fallback.js.map +1 -0
- package/dist/lib/path-pattern.d.ts +34 -0
- package/dist/lib/path-pattern.js +24 -0
- package/dist/lib/path-pattern.js.map +1 -0
- package/dist/lib/reduced-motion.d.ts +2 -1
- package/dist/lib/reduced-motion.js.map +1 -1
- package/dist/lib/round.d.ts +2 -1
- package/dist/lib/round.js +2 -1
- package/dist/lib/round.js.map +1 -1
- package/dist/lib/safe-storage.d.ts +24 -5
- package/dist/lib/safe-storage.js +27 -2
- package/dist/lib/safe-storage.js.map +1 -1
- package/dist/lib/session-refresh.js +1 -1
- package/dist/lib/session-refresh.js.map +1 -1
- package/dist/lib/share-format.d.ts +13 -0
- package/dist/lib/share-format.js +10 -0
- package/dist/lib/share-format.js.map +1 -0
- package/dist/lib/text-case.d.ts +17 -0
- package/dist/lib/text-case.js +8 -0
- package/dist/lib/text-case.js.map +1 -0
- package/dist/lib/text-match.d.ts +29 -0
- package/dist/lib/text-match.js +20 -2
- package/dist/lib/text-match.js.map +1 -1
- package/dist/lib/thenable.d.ts +13 -0
- package/dist/lib/thenable.js +8 -0
- package/dist/lib/thenable.js.map +1 -0
- package/dist/lib/translation-review.d.ts +7 -2
- package/dist/lib/translation-review.js +4 -4
- package/dist/lib/translation-review.js.map +1 -1
- package/dist/notifications/device-zone-report.js +1 -1
- package/dist/notifications/device-zone-report.js.map +1 -1
- package/dist/notifications/notification-bell.d.ts +2 -1
- package/dist/notifications/notification-bell.js +3 -3
- package/dist/notifications/notification-bell.js.map +1 -1
- package/dist/notifications/notification-inbox.d.ts +10 -6
- package/dist/notifications/notification-inbox.js +26 -48
- package/dist/notifications/notification-inbox.js.map +1 -1
- package/dist/notifications/notification-parts.d.ts +3 -2
- package/dist/notifications/notification-parts.js +1 -3
- package/dist/notifications/notification-parts.js.map +1 -1
- package/dist/notifications/notification-types-setting.js +1 -1
- package/dist/notifications/notification-types-setting.js.map +1 -1
- package/dist/notifications/notifications-labels.d.ts +6 -0
- package/dist/notifications/notifications-labels.js +1 -0
- package/dist/notifications/notifications-labels.js.map +1 -1
- package/dist/notifications/push-device-setting.js +1 -1
- package/dist/notifications/push-device-setting.js.map +1 -1
- package/dist/notifications/push-devices-setting.d.ts +2 -1
- package/dist/notifications/push-devices-setting.js +27 -49
- package/dist/notifications/push-devices-setting.js.map +1 -1
- package/dist/notifications/quiet-hours-setting.d.ts +10 -3
- package/dist/notifications/quiet-hours-setting.js +65 -26
- package/dist/notifications/quiet-hours-setting.js.map +1 -1
- package/dist/notifications/unsubscribe-panel.js +4 -7
- package/dist/notifications/unsubscribe-panel.js.map +1 -1
- package/dist/notifications/use-push-device.d.ts +39 -1
- package/dist/notifications/use-push-device.js +28 -7
- package/dist/notifications/use-push-device.js.map +1 -1
- package/dist/offline/query-persistence.d.ts +3 -1
- package/dist/offline/query-persistence.js +19 -2
- package/dist/offline/query-persistence.js.map +1 -1
- package/dist/rhf/fields.d.ts +11 -4
- package/dist/rhf/fields.js.map +1 -1
- package/dist/search/command-palette.js +1 -1
- package/dist/search/command-palette.js.map +1 -1
- package/dist/search/global-search.js +19 -9
- package/dist/search/global-search.js.map +1 -1
- package/dist/search/use-command-key.d.ts +12 -1
- package/dist/search/use-command-key.js +3 -12
- package/dist/search/use-command-key.js.map +1 -1
- package/dist/search.d.ts +7 -0
- package/dist/search.js +10 -0
- package/dist/search.js.map +1 -1
- package/dist/settings/use-settings-focus.js +1 -0
- package/dist/settings/use-settings-focus.js.map +1 -1
- package/dist/shell/account-menu-language.d.ts +21 -5
- package/dist/shell/account-menu-language.js +3 -1
- package/dist/shell/account-menu-language.js.map +1 -1
- package/dist/shell/account-menu-text-size.d.ts +26 -9
- package/dist/shell/account-menu-text-size.js +3 -2
- package/dist/shell/account-menu-text-size.js.map +1 -1
- package/dist/shell/dev-menu.js +5 -18
- package/dist/shell/dev-menu.js.map +1 -1
- package/dist/shell/role-switcher.d.ts +7 -0
- package/dist/shell/role-switcher.js.map +1 -1
- package/dist/shell/top-bar-actions.d.ts +1 -1
- package/dist/shell/top-bar-actions.js.map +1 -1
- package/dist/shell/top-bar-parts-labels.d.ts +0 -2
- package/dist/shell/top-bar-parts-labels.js +0 -1
- package/dist/shell/top-bar-parts-labels.js.map +1 -1
- package/dist/shell.d.ts +27 -8
- package/dist/shell.js +28 -7
- package/dist/shell.js.map +1 -1
- package/dist/sync/engine.d.ts +30 -4
- package/dist/sync/engine.js +172 -52
- package/dist/sync/engine.js.map +1 -1
- package/dist/sync.d.ts +6 -2
- package/dist/sync.js +6 -1
- package/dist/sync.js.map +1 -1
- package/dist/testing/css-variables.js +3 -8
- package/dist/testing/css-variables.js.map +1 -1
- package/dist/theme/contrast.d.ts +2 -1
- package/dist/theme/contrast.js +3 -8
- package/dist/theme/contrast.js.map +1 -1
- package/dist/theme/palette-store.js +6 -6
- package/dist/theme/palette-store.js.map +1 -1
- package/dist/theme/text-size.js +3 -8
- package/dist/theme/text-size.js.map +1 -1
- package/dist/theme/theme-store.js +3 -6
- package/dist/theme/theme-store.js.map +1 -1
- package/dist/tour/tour-catalogue.d.ts +7 -4
- package/dist/tour/tour-catalogue.js +12 -10
- package/dist/tour/tour-catalogue.js.map +1 -1
- package/dist/tour/tour-dock.d.ts +0 -2
- package/dist/tour/tour-dock.js +0 -2
- package/dist/tour/tour-dock.js.map +1 -1
- package/dist/tour/tour-gates.d.ts +4 -0
- package/dist/tour/tour-gates.js +14 -0
- package/dist/tour/tour-gates.js.map +1 -1
- package/dist/tour/tour-overlay.d.ts +27 -0
- package/dist/tour/tour-overlay.js +741 -0
- package/dist/tour/tour-overlay.js.map +1 -0
- package/dist/tour/tour.d.ts +13 -3
- package/dist/tour/tour.js +59 -781
- package/dist/tour/tour.js.map +1 -1
- package/dist/tour/use-tour-progress.js +1 -1
- package/dist/tour/use-tour-progress.js.map +1 -1
- package/dist/wizard/stepper-nav.d.ts +5 -1
- package/dist/wizard/stepper-nav.js.map +1 -1
- package/dist/wizard/types.d.ts +6 -2
- package/dist/wizard/types.js.map +1 -1
- package/dist/wizard/use-wizard.d.ts +3 -1
- package/dist/wizard/use-wizard.js.map +1 -1
- package/dist/wizard/validation.d.ts +3 -1
- package/dist/wizard/validation.js.map +1 -1
- package/package.json +10 -6
- package/src/account/account-parts.ts +5 -25
- package/src/account/data-export-setting-labels.ts +1 -1
- package/src/account/delete-account-setting-labels.ts +1 -1
- package/src/account/email-change-setting-labels.ts +1 -1
- package/src/account/passkeys-setting.tsx +60 -38
- package/src/account/sessions-setting.tsx +18 -12
- package/src/admin/admin-action-confirm.tsx +1 -5
- package/src/admin/admin-parts.ts +11 -25
- package/src/admin/mail-test-card-labels.ts +1 -1
- package/src/admin/plan-change-labels.ts +5 -23
- package/src/admin/plan-change.tsx +7 -44
- package/src/admin/reviewer-scope-editor.tsx +3 -3
- package/src/auth/auth-errors-labels.ts +23 -0
- package/src/auth/auth-errors.ts +11 -38
- package/src/auth/complete-name-dialog.tsx +4 -1
- package/src/auth/forgot-password-form-labels.ts +1 -1
- package/src/auth/forgot-password-form.tsx +11 -6
- package/src/auth/register-form-labels.ts +1 -1
- package/src/auth/reset-password-form-labels.ts +1 -1
- package/src/auth/reset-password-form.tsx +8 -4
- package/src/auth/sign-in-form-labels.ts +1 -1
- package/src/auth/status-parts.tsx +0 -6
- package/src/auth/verify-email-labels.ts +1 -1
- package/src/auth/verify-email.tsx +11 -6
- package/src/billing/cancel-subscription.tsx +26 -12
- package/src/billing/dialog-close.ts +34 -0
- package/src/billing/plan-card.tsx +36 -11
- package/src/billing/plan-change-labels.ts +66 -0
- package/src/billing/plan-switch.tsx +26 -12
- package/src/chart.ts +21 -3
- package/src/components/account-chips.tsx +20 -23
- package/src/components/alert-banner.tsx +82 -5
- package/src/components/amount-input.tsx +18 -7
- package/src/components/autocomplete.tsx +64 -70
- package/src/components/bulk-action-bar.tsx +70 -2
- package/src/components/button-look.ts +5 -5
- package/src/components/button.tsx +2 -2
- package/src/components/chart-edge.ts +34 -1
- package/src/components/chart-figure.tsx +35 -0
- package/src/components/chart-zoom-core.tsx +6 -5
- package/src/components/chart.tsx +26 -5
- package/src/components/combobox-core.tsx +293 -62
- package/src/components/combobox.tsx +183 -153
- package/src/components/copy-button.tsx +34 -23
- package/src/components/country-select.tsx +16 -11
- package/src/components/data-table-column-settings.tsx +52 -10
- package/src/components/data-table-filters.ts +6 -4
- package/src/components/data-table-fit.ts +19 -5
- package/src/components/data-table-groups.tsx +1 -1
- package/src/components/data-table-head.tsx +32 -22
- package/src/components/data-table-mobile.tsx +61 -26
- package/src/components/data-table-pagination.tsx +21 -6
- package/src/components/data-table-resize.ts +1 -1
- package/src/components/data-table-row-actions.tsx +3 -3
- package/src/components/data-table-row.tsx +25 -14
- package/src/components/data-table-selection.ts +1 -1
- package/src/components/data-table-shared.tsx +33 -1
- package/src/components/data-table-sort.ts +57 -2
- package/src/components/data-table-virtual.ts +32 -8
- package/src/components/data-table.tsx +239 -68
- package/src/components/date-field.tsx +65 -8
- package/src/components/date-picker.tsx +125 -48
- package/src/components/date-range-picker.tsx +82 -31
- package/src/components/error-boundary.tsx +53 -39
- package/src/components/field-base-labels.ts +20 -0
- package/src/components/field-base.tsx +13 -7
- package/src/components/field-sync-labels.ts +1 -0
- package/src/components/field-sync.tsx +23 -1
- package/src/components/form-actions.tsx +20 -5
- package/src/components/hover-menu.tsx +18 -8
- package/src/components/icon-button.tsx +14 -9
- package/src/components/inline-confirm.tsx +116 -0
- package/src/components/inline-entity-combobox.tsx +197 -153
- package/src/components/input.tsx +1 -1
- package/src/components/jump-calendar.tsx +30 -146
- package/src/components/legal-page.tsx +10 -7
- package/src/components/legal.tsx +4 -2
- package/src/components/lightbox.tsx +21 -8
- package/src/components/list.tsx +10 -4
- package/src/components/measured-grid.tsx +8 -4
- package/src/components/mini-calendar.tsx +6 -5
- package/src/components/modal.tsx +6 -1
- package/src/components/month-grid.tsx +229 -0
- package/src/components/month-picker.tsx +192 -200
- package/src/components/multi-select.tsx +21 -9
- package/src/components/picker-sheet.tsx +12 -9
- package/src/components/pie-chart-labels.ts +8 -0
- package/src/components/pie-chart.tsx +22 -28
- package/src/components/popover.tsx +18 -1
- package/src/components/row-actions.tsx +2 -1
- package/src/components/section-nav.tsx +7 -0
- package/src/components/series-chart-axes.ts +3 -3
- package/src/components/series-chart-labels.ts +7 -4
- package/src/components/series-chart.tsx +178 -69
- package/src/components/share-card.tsx +6 -6
- package/src/components/sign-chip-labels.ts +1 -0
- package/src/components/sign-chip.tsx +10 -1
- package/src/components/tabs-labels.ts +13 -0
- package/src/components/tabs.tsx +2 -2
- package/src/components/toggle-legend.tsx +16 -11
- package/src/components/translation-review-editor.tsx +6 -5
- package/src/components/translation-review.tsx +4 -3
- package/src/components/treemap-labels.ts +39 -0
- package/src/components/treemap-layout.ts +210 -0
- package/src/components/treemap.tsx +722 -133
- package/src/components/use-table-state.ts +12 -9
- package/src/data-table.ts +9 -2
- package/src/eslint/role-utilities.ts +97 -19
- package/src/feedback/feedback-dialog.tsx +30 -19
- package/src/feedback/feedback-mutation.ts +41 -0
- package/src/feedback/feedback-page-link.ts +90 -0
- package/src/feedback/feedback-public-list.tsx +17 -5
- package/src/feedback/feedback-replies.tsx +13 -6
- package/src/feedback/feedback-row-detail-labels.ts +5 -0
- package/src/feedback/feedback-row-detail.tsx +103 -67
- package/src/feedback/feedback-status-undo.ts +41 -27
- package/src/feedback/feedback-submit-dialog.tsx +2 -2
- package/src/feedback/feedback-submit.tsx +21 -7
- package/src/feedback/feedback-swipe.tsx +1 -1
- package/src/feedback/feedback-table.tsx +86 -38
- package/src/feedback/feedback-thread-labels.ts +2 -2
- package/src/feedback/feedback-thread.tsx +27 -25
- package/src/feedback.ts +42 -0
- package/src/hooks/use-focus-trap.ts +8 -24
- package/src/hooks/use-hotkey.ts +24 -7
- package/src/hooks/use-long-press.ts +16 -2
- package/src/hooks/use-media-query.ts +20 -4
- package/src/hooks/use-mounted.ts +39 -0
- package/src/hooks/use-overlay-history.ts +32 -3
- package/src/i18n/defaults.ts +4 -5
- package/src/i18n/german.ts +8 -2
- package/src/i18n/kit-labels.tsx +9 -2
- package/src/i18n/locales/es.ts +8 -2
- package/src/i18n/locales/fr.ts +21 -13
- package/src/i18n/locales/hu.ts +10 -2
- package/src/i18n/locales/it.ts +8 -2
- package/src/i18n/locales/zh.ts +9 -2
- package/src/i18n/review.ts +5 -0
- package/src/index.ts +103 -13
- package/src/landing/routing.tsx +14 -10
- package/src/lib/broadcast.ts +52 -0
- package/src/lib/date-format.ts +89 -13
- package/src/lib/day-format.ts +96 -0
- package/src/lib/describe-failure.ts +18 -0
- package/src/lib/direction.ts +39 -0
- package/src/lib/focus-left.ts +156 -0
- package/src/lib/format.ts +5 -17
- package/src/lib/http-status.ts +38 -0
- package/src/lib/intl-cache.ts +25 -0
- package/src/lib/isin.ts +10 -0
- package/src/lib/iso-day.ts +13 -0
- package/src/lib/lazy-with-fallback.ts +82 -0
- package/src/lib/path-pattern.ts +55 -0
- package/src/lib/reduced-motion.ts +2 -1
- package/src/lib/round.ts +7 -2
- package/src/lib/safe-storage.ts +48 -6
- package/src/lib/session-refresh.ts +1 -1
- package/src/lib/share-format.ts +18 -0
- package/src/lib/text-case.ts +19 -0
- package/src/lib/text-match.ts +57 -2
- package/src/lib/thenable.ts +19 -0
- package/src/lib/translation-review.ts +13 -5
- package/src/notifications/device-zone-report.ts +1 -1
- package/src/notifications/notification-bell.tsx +7 -4
- package/src/notifications/notification-inbox.tsx +40 -58
- package/src/notifications/notification-parts.tsx +3 -4
- package/src/notifications/notification-types-setting.tsx +1 -1
- package/src/notifications/notifications-labels.ts +7 -0
- package/src/notifications/push-device-setting.tsx +1 -1
- package/src/notifications/push-devices-setting.tsx +30 -55
- package/src/notifications/quiet-hours-setting.tsx +93 -31
- package/src/notifications/unsubscribe-panel.tsx +4 -7
- package/src/notifications/use-push-device.ts +76 -10
- package/src/offline/query-persistence.ts +35 -3
- package/src/rhf/fields.tsx +11 -4
- package/src/search/command-palette.tsx +2 -4
- package/src/search/global-search.tsx +36 -15
- package/src/search/use-command-key.ts +13 -12
- package/src/search.ts +9 -0
- package/src/settings/use-settings-focus.ts +3 -0
- package/src/shell/account-menu-language.tsx +27 -5
- package/src/shell/account-menu-text-size.tsx +32 -10
- package/src/shell/dev-menu.tsx +7 -21
- package/src/shell/role-switcher.tsx +7 -0
- package/src/shell/top-bar-actions.tsx +1 -1
- package/src/shell/top-bar-parts-labels.ts +0 -3
- package/src/shell.ts +40 -9
- package/src/sync/engine.ts +339 -61
- package/src/sync.ts +8 -1
- package/src/testing/css-variables.ts +8 -9
- package/src/theme/contrast.ts +8 -9
- package/src/theme/palette-store.ts +9 -9
- package/src/theme/text-size.ts +6 -8
- package/src/theme/theme-store.ts +7 -9
- package/src/tour/tour-catalogue.tsx +26 -15
- package/src/tour/tour-dock.ts +0 -2
- package/src/tour/tour-gates.ts +23 -0
- package/src/tour/tour-overlay.tsx +1170 -0
- package/src/tour/tour.tsx +108 -1202
- package/src/tour/use-tour-progress.ts +1 -1
- package/src/wizard/stepper-nav.tsx +3 -1
- package/src/wizard/types.ts +11 -2
- package/src/wizard/use-wizard.ts +2 -1
- package/src/wizard/validation.ts +8 -2
- package/tokens.css +2 -1
- package/dist/components/ui-labels.js.map +0 -1
- package/dist/shell/dev-switchers.d.ts +0 -6
- package/dist/shell/dev-switchers.js +0 -12
- package/dist/shell/dev-switchers.js.map +0 -1
- package/src/components/ui-labels.ts +0 -24
- package/src/shell/dev-switchers.tsx +0 -18
|
@@ -1,12 +1,14 @@
|
|
|
1
|
-
import { useMemo } from "react";
|
|
1
|
+
import { useCallback, useMemo } from "react";
|
|
2
2
|
import type { MouseEvent, ReactElement, ReactNode } from "react";
|
|
3
3
|
import { ExternalLink, ThumbsUp } from "lucide-react";
|
|
4
4
|
import { cn } from "../lib/cn";
|
|
5
|
-
import {
|
|
6
|
-
import { EMPTY_FORMATTED_VALUE
|
|
7
|
-
import {
|
|
5
|
+
import { useDayFormatter } from "../lib/day-format";
|
|
6
|
+
import { EMPTY_FORMATTED_VALUE } from "../lib/format";
|
|
7
|
+
import { useKitLabels, useKitLink, type LabelOverride } from "../i18n/kit-labels";
|
|
8
8
|
import type { KitLinkProps } from "../i18n/kit-labels";
|
|
9
|
+
import type { PathPattern } from "../landing/routing";
|
|
9
10
|
import { Chip } from "../components/chip";
|
|
11
|
+
import { CopyButton } from "../components/copy-button";
|
|
10
12
|
import { Tooltip } from "../components/tooltip";
|
|
11
13
|
import { FloatingAction, FloatingActionGroup } from "../components/floating-panel";
|
|
12
14
|
import type { FloatingCorner } from "../components/floating-panel";
|
|
@@ -36,7 +38,8 @@ import {
|
|
|
36
38
|
type FeedbackRecord,
|
|
37
39
|
} from "./feedback-record";
|
|
38
40
|
import type { FeedbackStatusChange } from "./feedback-status-undo";
|
|
39
|
-
import {
|
|
41
|
+
import { feedbackPagePath, useFeedbackDetailLabels } from "./feedback-row-detail";
|
|
42
|
+
import { feedbackPage, feedbackPageLinkTarget } from "./feedback-page-link";
|
|
40
43
|
import type { CommitScope } from "../components/write-lock";
|
|
41
44
|
import { DEFAULT_FEEDBACK_PAGE_LABELS } from "./feedback-table-labels";
|
|
42
45
|
import { DEFAULT_FEEDBACK_PUBLIC_LABELS } from "./feedback-public-labels";
|
|
@@ -235,25 +238,16 @@ const FEEDBACK_DATE_STYLE: Intl.DateTimeFormatOptions = {
|
|
|
235
238
|
};
|
|
236
239
|
|
|
237
240
|
/**
|
|
238
|
-
* `renderDate` when the app gave one, else the kit's: the
|
|
239
|
-
* when the app set one (called with the
|
|
240
|
-
* `DateMark` calls it), else `Intl` in the provider's locale
|
|
241
|
-
* unparseable value is passed through rather than
|
|
241
|
+
* `renderDate` when the app gave one (and it answers), else the kit's: the
|
|
242
|
+
* `<UiKitProvider formatDate>` when the app set one (called with the calendar day and
|
|
243
|
+
* `weekday: true`, as `DateMark` calls it), else `Intl` in the provider's locale and
|
|
244
|
+
* (0.52) time zone, with the weekday. An unparseable value is passed through rather than
|
|
245
|
+
* hidden. The kit's one day ladder since 0.52 (refactor audit 2026-10-30, DUP-2), which
|
|
246
|
+
* every date a kit component prints goes down.
|
|
242
247
|
*/
|
|
243
248
|
export function useFeedbackRenderDate(renderDate?: FeedbackRenderDate, locale?: string): FeedbackRenderDate {
|
|
244
|
-
const
|
|
245
|
-
|
|
246
|
-
return useMemo<FeedbackRenderDate>(() => {
|
|
247
|
-
if (renderDate) return renderDate;
|
|
248
|
-
return (iso) => {
|
|
249
|
-
const date = toDate(iso);
|
|
250
|
-
if (!date) return iso || EMPTY_FORMATTED_VALUE;
|
|
251
|
-
const own = fromProvider
|
|
252
|
-
? fromProvider(toLocalIso(date), { unit: "day", source: "dateMark", locale: kitLocale, weekday: true })
|
|
253
|
-
: "";
|
|
254
|
-
return own || formatDate(date, FEEDBACK_DATE_STYLE, { locale: kitLocale });
|
|
255
|
-
};
|
|
256
|
-
}, [renderDate, fromProvider, kitLocale]);
|
|
249
|
+
const day = useDayFormatter<string>(renderDate, locale);
|
|
250
|
+
return useCallback<FeedbackRenderDate>((iso) => day(iso, { weekday: true, style: FEEDBACK_DATE_STYLE }), [day]);
|
|
257
251
|
}
|
|
258
252
|
|
|
259
253
|
/** A date in a cell: `<time>`, nowrap, tabular figures; "—" when there is none. */
|
|
@@ -339,29 +333,44 @@ export function FeedbackSubject({ row, wrap = false, labels: labelsProp, classNa
|
|
|
339
333
|
|
|
340
334
|
/**
|
|
341
335
|
* The page a report was filed from, as a link — the cell keksdose's column 7 draws
|
|
342
|
-
* (:850): the path as text
|
|
343
|
-
*
|
|
344
|
-
*
|
|
345
|
-
*
|
|
346
|
-
*
|
|
347
|
-
*
|
|
336
|
+
* (:850): the path as text and as the `href`, read from `context.url` else
|
|
337
|
+
* `context.route` by the row detail's own reader (`feedbackPage`, feedback-page-link.ts),
|
|
338
|
+
* so the column and the detail link the same page the same way. A real link through the
|
|
339
|
+
* `<UiKitProvider linkComponent>` (the app's router, so it does not reload the app;
|
|
340
|
+
* keksdose's plain `<a>` did), and its click stops at the cell so the row does not open
|
|
341
|
+
* as well.
|
|
348
342
|
*
|
|
349
343
|
* Its name is the path, as on screen, with "Open page" said before it — keksdose's
|
|
350
344
|
* `aria-label="Open page"` replaced the path, so a screen reader heard forty identical
|
|
351
345
|
* links down the column.
|
|
346
|
+
*
|
|
347
|
+
* The PATH alone (0.52 code review, feedback-page-link.ts): the query is the reporter's to
|
|
348
|
+
* write, and `/login?next=%2Fjoin%3Ftoken%3D…` forwarded the admin's click to an
|
|
349
|
+
* invitation. A one-shot route — `/join`, `/register`, `/verify-email`, `/reset-password`
|
|
350
|
+
* and the app's `pageLinkExclude` — is the path as text with Copy, never a link (0.52,
|
|
351
|
+
* refactor audit 2026-10-30, FLW-7): those routes act on load.
|
|
352
352
|
*/
|
|
353
|
-
function FeedbackPageLinkCell({
|
|
353
|
+
function FeedbackPageLinkCell({
|
|
354
|
+
context,
|
|
355
|
+
openPage,
|
|
356
|
+
exclude,
|
|
357
|
+
}: {
|
|
358
|
+
context: FeedbackContext | null;
|
|
359
|
+
openPage: string;
|
|
360
|
+
exclude: readonly PathPattern[] | undefined;
|
|
361
|
+
}) {
|
|
354
362
|
const kitLink = useKitLink();
|
|
355
|
-
const
|
|
356
|
-
|
|
357
|
-
|
|
363
|
+
const page = feedbackPage(context);
|
|
364
|
+
if (!page) return <span className="text-placeholder">{EMPTY_FORMATTED_VALUE}</span>;
|
|
365
|
+
const href = feedbackPageLinkTarget(page, exclude);
|
|
366
|
+
if (!href) return <FeedbackPageText path={page.path} url={page.url} />;
|
|
358
367
|
const className =
|
|
359
368
|
"inline-flex min-w-0 max-w-full items-center gap-1 text-secondary hover:text-primary hover:underline";
|
|
360
369
|
const children = (
|
|
361
370
|
<>
|
|
362
371
|
{/* The space outside the hidden span: a flex container drops it from the layout,
|
|
363
372
|
and the accessible name keeps it ("Open page /accounts"). */}
|
|
364
|
-
<span className="sr-only">{openPage}</span> <code className="min-w-0 truncate text-xs">{path}</code>
|
|
373
|
+
<span className="sr-only">{openPage}</span> <code className="min-w-0 truncate text-xs">{page.path}</code>
|
|
365
374
|
<ExternalLink className="size-3 shrink-0" aria-hidden />
|
|
366
375
|
</>
|
|
367
376
|
);
|
|
@@ -378,6 +387,19 @@ function FeedbackPageLinkCell({ context, openPage }: { context: FeedbackContext
|
|
|
378
387
|
);
|
|
379
388
|
}
|
|
380
389
|
|
|
390
|
+
/** A one-shot page in the URL column: its path to read, and Copy. A component of its own
|
|
391
|
+
* so only such a row resolves the `feedbackDetail` words — every cell of a 270-row inbox
|
|
392
|
+
* did, for a button only a one-shot row shows (0.52 code review, efficiency). */
|
|
393
|
+
function FeedbackPageText({ path, url }: { path: string; url: string }) {
|
|
394
|
+
const { copyUrl } = useFeedbackDetailLabels();
|
|
395
|
+
return (
|
|
396
|
+
<span className="inline-flex min-w-0 max-w-full items-center gap-1 text-secondary" data-feedback-page-unlinked="">
|
|
397
|
+
<code className="min-w-0 truncate text-xs">{path}</code>
|
|
398
|
+
<CopyButton size="xs" className="shrink-0" text={url} label={copyUrl} stopPropagation />
|
|
399
|
+
</span>
|
|
400
|
+
);
|
|
401
|
+
}
|
|
402
|
+
|
|
381
403
|
/** The provider's link, drawn by a component declared once (as FloatingAction's). */
|
|
382
404
|
function RenderedLink({ render, ...props }: KitLinkProps & { render: (props: KitLinkProps) => ReactElement }) {
|
|
383
405
|
return render(props);
|
|
@@ -395,8 +417,8 @@ export interface FeedbackColumnsOptions {
|
|
|
395
417
|
/** The admin on `/feedback` — the status cell offers its steps. Otherwise it shows them
|
|
396
418
|
* read-only. */
|
|
397
419
|
canEdit: boolean;
|
|
398
|
-
/** The undoable status change, `useFeedbackStatusUndo(update.
|
|
399
|
-
* same one the row detail and the swipes use. */
|
|
420
|
+
/** The undoable status change, `useFeedbackStatusUndo(update.mutateAsync)` (§4.5) —
|
|
421
|
+
* the same one the row detail and the swipes use. */
|
|
400
422
|
onStatus: FeedbackStatusChange;
|
|
401
423
|
/** See {@link FeedbackRenderDate}. */
|
|
402
424
|
renderDate: FeedbackRenderDate;
|
|
@@ -414,6 +436,15 @@ export interface FeedbackColumnsOptions {
|
|
|
414
436
|
/** The Votes header — `feedbackPublic.columnVotes`, so the inbox and the public list
|
|
415
437
|
* say the same ({@link useFeedbackColumns} reads it). Default "Votes". */
|
|
416
438
|
votesHeader?: string;
|
|
439
|
+
/**
|
|
440
|
+
* 0.52 (FLW-7): the app's one-shot routes, ON TOP of the kit's — `/join`, `/register`,
|
|
441
|
+
* `/verify-email`, `/reset-password` (a string is that path and everything under it, a
|
|
442
|
+
* RegExp is tested on the path, as `useLastVisitedPage`'s `exclude`). The URL cell
|
|
443
|
+
* shows such a page as text with Copy, never as a link; any other page links its path
|
|
444
|
+
* alone. Keep it stable (module scope): it is a dependency of {@link useFeedbackColumns}'
|
|
445
|
+
* memo.
|
|
446
|
+
*/
|
|
447
|
+
pageLinkExclude?: readonly PathPattern[];
|
|
417
448
|
}
|
|
418
449
|
|
|
419
450
|
/** The vote count, a quiet chip with the thumb (§9.6) — the Votes cell and the card's. */
|
|
@@ -479,6 +510,7 @@ export function feedbackColumns<T extends FeedbackTableRow>({
|
|
|
479
510
|
categoryLabels,
|
|
480
511
|
votes = false,
|
|
481
512
|
votesHeader = DEFAULT_FEEDBACK_PUBLIC_LABELS.columnVotes,
|
|
513
|
+
pageLinkExclude,
|
|
482
514
|
}: FeedbackColumnsOptions): DataTableColumn<T>[] {
|
|
483
515
|
const editable = canEdit && !mine;
|
|
484
516
|
const votesColumn: DataTableColumn<T>[] = votes
|
|
@@ -608,7 +640,9 @@ export function feedbackColumns<T extends FeedbackTableRow>({
|
|
|
608
640
|
// The cell IS a link, so the row's own permalink must never wrap it (keksdose
|
|
609
641
|
// feedback #451: <a> in <a>, and "open the page" silently did nothing).
|
|
610
642
|
noRowLink: true,
|
|
611
|
-
cell: (row) =>
|
|
643
|
+
cell: (row) => (
|
|
644
|
+
<FeedbackPageLinkCell context={row.context} openPage={labels.openPage} exclude={pageLinkExclude} />
|
|
645
|
+
),
|
|
612
646
|
sortBy: (row) => feedbackPagePath(row.context) ?? "",
|
|
613
647
|
filterBy: (row) => feedbackPagePath(row.context) ?? "",
|
|
614
648
|
mobileHidden: true,
|
|
@@ -670,7 +704,7 @@ export interface UseFeedbackColumnsOptions extends Omit<
|
|
|
670
704
|
/**
|
|
671
705
|
* {@link feedbackColumns} with the `feedbackPage`, `feedbackStatus` and
|
|
672
706
|
* `feedbackCategory` words from the provider, memoised on what it reads — pass
|
|
673
|
-
* `update.
|
|
707
|
+
* `update.mutateAsync` through `useFeedbackStatusUndo` (stable) rather than a fresh function
|
|
674
708
|
* per render, or every row's columns are rebuilt on each render (keksdose :667).
|
|
675
709
|
*/
|
|
676
710
|
export function useFeedbackColumns<T extends FeedbackTableRow>({
|
|
@@ -680,6 +714,7 @@ export function useFeedbackColumns<T extends FeedbackTableRow>({
|
|
|
680
714
|
renderDate: renderDateProp,
|
|
681
715
|
commit,
|
|
682
716
|
votes,
|
|
717
|
+
pageLinkExclude,
|
|
683
718
|
labels: labelsProp,
|
|
684
719
|
}: UseFeedbackColumnsOptions): DataTableColumn<T>[] {
|
|
685
720
|
const labels = useFeedbackPageLabels(labelsProp);
|
|
@@ -700,8 +735,21 @@ export function useFeedbackColumns<T extends FeedbackTableRow>({
|
|
|
700
735
|
categoryLabels,
|
|
701
736
|
votes,
|
|
702
737
|
votesHeader,
|
|
738
|
+
pageLinkExclude,
|
|
703
739
|
}),
|
|
704
|
-
[
|
|
740
|
+
[
|
|
741
|
+
mine,
|
|
742
|
+
canEdit,
|
|
743
|
+
onStatus,
|
|
744
|
+
renderDate,
|
|
745
|
+
commit,
|
|
746
|
+
labels,
|
|
747
|
+
statusLabels,
|
|
748
|
+
categoryLabels,
|
|
749
|
+
votes,
|
|
750
|
+
votesHeader,
|
|
751
|
+
pageLinkExclude,
|
|
752
|
+
],
|
|
705
753
|
);
|
|
706
754
|
}
|
|
707
755
|
|
|
@@ -2,7 +2,7 @@
|
|
|
2
2
|
// catalogue (src/i18n/defaults.ts) imports them without the component, so `en` loads as one
|
|
3
3
|
// chunk like the other languages (0.34, KS U8). ./feedback-thread re-exports them.
|
|
4
4
|
|
|
5
|
-
import type {
|
|
5
|
+
import type { ChatComposerLabels, FeedbackThreadLabels } from "./feedback-thread";
|
|
6
6
|
|
|
7
7
|
export const DEFAULT_FEEDBACK_THREAD_LABELS: FeedbackThreadLabels = {
|
|
8
8
|
thread: "Comments",
|
|
@@ -13,7 +13,7 @@ export const DEFAULT_FEEDBACK_THREAD_LABELS: FeedbackThreadLabels = {
|
|
|
13
13
|
attachments: "Attachments",
|
|
14
14
|
};
|
|
15
15
|
|
|
16
|
-
export const DEFAULT_FEEDBACK_COMPOSER_LABELS:
|
|
16
|
+
export const DEFAULT_FEEDBACK_COMPOSER_LABELS: ChatComposerLabels = {
|
|
17
17
|
field: "Write a comment",
|
|
18
18
|
placeholder: "Write a comment…",
|
|
19
19
|
send: "Send",
|
|
@@ -3,6 +3,7 @@ import type { ReactNode, Ref, RefObject } from "react";
|
|
|
3
3
|
import { ImageIcon, ImageOff, Paperclip, Send } from "lucide-react";
|
|
4
4
|
import { cn } from "../lib/cn";
|
|
5
5
|
import { formatDate, formatRelativeTime } from "../lib/format";
|
|
6
|
+
import { upperFirst } from "../lib/text-case";
|
|
6
7
|
import { hasContent } from "../lib/presence";
|
|
7
8
|
import { Button } from "../components/button";
|
|
8
9
|
import { EmptyState } from "../components/empty-state";
|
|
@@ -74,7 +75,7 @@ export { DEFAULT_FEEDBACK_THREAD_LABELS };
|
|
|
74
75
|
|
|
75
76
|
/** The `feedbackComposer` namespace of `<UiKitProvider labels>`. The attach buttons'
|
|
76
77
|
* words are `feedbackAttachment`'s, shared with the dialog and the note editor. */
|
|
77
|
-
export interface
|
|
78
|
+
export interface ChatComposerLabels {
|
|
78
79
|
/** Accessible name of the text box. */
|
|
79
80
|
field: string;
|
|
80
81
|
placeholder: string;
|
|
@@ -436,7 +437,7 @@ function DaySeparator({ date, now, locale }: { date: Date; now: number; locale:
|
|
|
436
437
|
let label: string;
|
|
437
438
|
if (days === 0 || days === -1) {
|
|
438
439
|
const word = new Intl.RelativeTimeFormat(locale, { numeric: "auto" }).format(days + 0, "day");
|
|
439
|
-
label = word
|
|
440
|
+
label = upperFirst(word, locale);
|
|
440
441
|
} else {
|
|
441
442
|
label = formatDate(
|
|
442
443
|
date,
|
|
@@ -482,7 +483,7 @@ export type FeedbackComposerAttachment = Omit<FeedbackNoteAttachment, "labels" |
|
|
|
482
483
|
} & Pick<FeedbackAttachmentFieldSingleProps, "buttonVariant" | "buttonSize">;
|
|
483
484
|
|
|
484
485
|
/**
|
|
485
|
-
* What a render-prop {@link
|
|
486
|
+
* What a render-prop {@link ChatComposerProps.attachmentSlot} is handed (0.24.0,
|
|
486
487
|
* keksdose).
|
|
487
488
|
*
|
|
488
489
|
* keksdose's support chat put `<FeedbackAttachmentField refs>` in the slot and a
|
|
@@ -492,7 +493,7 @@ export type FeedbackComposerAttachment = Omit<FeedbackNoteAttachment, "labels" |
|
|
|
492
493
|
* to itself, so keksdose wrapped the whole composer in a ref'd `<div>` of its own just
|
|
493
494
|
* to have an element to hand over.
|
|
494
495
|
*/
|
|
495
|
-
export interface
|
|
496
|
+
export interface ChatComposerSlotContext {
|
|
496
497
|
/**
|
|
497
498
|
* The composer's root, round the text box and this slot — the field's `pasteFrom`,
|
|
498
499
|
* as it is: `pasteFrom={slot.root}`.
|
|
@@ -514,7 +515,7 @@ export interface FeedbackComposerSlotContext {
|
|
|
514
515
|
pending: boolean;
|
|
515
516
|
}
|
|
516
517
|
|
|
517
|
-
export interface
|
|
518
|
+
export interface ChatComposerProps {
|
|
518
519
|
/**
|
|
519
520
|
* Send the comment. Return the promise: the box clears when it RESOLVES, and only of
|
|
520
521
|
* what was sent — text typed while it was in flight stays. A rejection keeps
|
|
@@ -538,7 +539,7 @@ export interface FeedbackComposerProps {
|
|
|
538
539
|
* refs and clearing them once `onSend` resolves stay with the host. Pair it with
|
|
539
540
|
* `canSend`.
|
|
540
541
|
*
|
|
541
|
-
* A node, or (0.24.0) a function of {@link
|
|
542
|
+
* A node, or (0.24.0) a function of {@link ChatComposerSlotContext} that returns
|
|
542
543
|
* one — for a field that wants the composer's root as its `pasteFrom`, so a
|
|
543
544
|
* screenshot pasted into the box reaches it, and `pending` for its `disabled`:
|
|
544
545
|
*
|
|
@@ -551,7 +552,7 @@ export interface FeedbackComposerProps {
|
|
|
551
552
|
* Called once per render of the composer, and not at all while `disabledReason`
|
|
552
553
|
* stands in for it.
|
|
553
554
|
*/
|
|
554
|
-
attachmentSlot?: ReactNode | ((slot:
|
|
555
|
+
attachmentSlot?: ReactNode | ((slot: ChatComposerSlotContext) => ReactNode);
|
|
555
556
|
/**
|
|
556
557
|
* Whether Send is enabled, over the composer's own rule (some text in the box) —
|
|
557
558
|
* for state the composer cannot see, i.e. `attachmentSlot`'s (keksdose G5): `true`
|
|
@@ -592,7 +593,7 @@ export interface FeedbackComposerProps {
|
|
|
592
593
|
* Textarea's `maxLength` + `showCount` since 0.22; the reply box, a composer, could
|
|
593
594
|
* not). The box's own `maxLength`, so typing and pasting stop at it.
|
|
594
595
|
*
|
|
595
|
-
* {@link
|
|
596
|
+
* {@link ChatComposerHandle.insertText} is not stopped by it — the browser limits
|
|
596
597
|
* typing, not a script — and a canned reply is not cut mid-sentence to fit. A draft
|
|
597
598
|
* past the limit therefore holds Send back (whatever `canSend` says, as `pending`
|
|
598
599
|
* does) until it is trimmed; with `showCount` the counter, red at the limit, says by
|
|
@@ -623,13 +624,13 @@ export interface FeedbackComposerProps {
|
|
|
623
624
|
* is still the one that went out.
|
|
624
625
|
*/
|
|
625
626
|
value?: string;
|
|
626
|
-
/** Every change to the draft — typing, {@link
|
|
627
|
+
/** Every change to the draft — typing, {@link ChatComposerHandle.insertText}, the
|
|
627
628
|
* clear after a send. Required to change a controlled `value`. */
|
|
628
629
|
onValueChange?: (value: string) => void;
|
|
629
|
-
/** {@link
|
|
630
|
+
/** {@link ChatComposerHandle}: put text into the draft from outside (canned-reply
|
|
630
631
|
* chips) or focus the box. */
|
|
631
|
-
ref?: Ref<
|
|
632
|
-
labels?: LabelOverride<
|
|
632
|
+
ref?: Ref<ChatComposerHandle>;
|
|
633
|
+
labels?: LabelOverride<ChatComposerLabels>;
|
|
633
634
|
className?: string;
|
|
634
635
|
/**
|
|
635
636
|
* `"sm"` for a narrow host — keksdose's assistant launcher, a small floating panel
|
|
@@ -659,7 +660,7 @@ export interface FeedbackComposerProps {
|
|
|
659
660
|
* the string, not the caret, so it could only append — so the composer, which owns
|
|
660
661
|
* the textarea, does the splice.
|
|
661
662
|
*/
|
|
662
|
-
export interface
|
|
663
|
+
export interface ChatComposerHandle {
|
|
663
664
|
/**
|
|
664
665
|
* Insert `text` at the caret, replacing any selection (the caret the box last had:
|
|
665
666
|
* a click on a chip blurs it, and the selection survives the blur), then focus the
|
|
@@ -685,7 +686,8 @@ const isApple = () =>
|
|
|
685
686
|
* feedback-specific — a textarea, an optional picture or a host's upload slot, Send,
|
|
686
687
|
* `sendOn="enter"` for the chat way — and keksdose's assistant and support chat are
|
|
687
688
|
* chats, not reports. `FeedbackComposer`, its old name, was removed in 0.35 (refactor
|
|
688
|
-
* audit 2026-10, API-6d; deprecated in 0.34); its types
|
|
689
|
+
* audit 2026-10, API-6d; deprecated in 0.34); its types are `ChatComposer*` too since 0.52
|
|
690
|
+
* (refactor audit 2026-10-30, API-6), the `FeedbackComposer*` names deprecated aliases.
|
|
689
691
|
*/
|
|
690
692
|
export function ChatComposer({
|
|
691
693
|
onSend,
|
|
@@ -709,7 +711,7 @@ export function ChatComposer({
|
|
|
709
711
|
id,
|
|
710
712
|
size = "md",
|
|
711
713
|
...rest
|
|
712
|
-
}:
|
|
714
|
+
}: ChatComposerProps) {
|
|
713
715
|
const labels = useKitLabels("feedbackComposer", DEFAULT_FEEDBACK_COMPOSER_LABELS, labelsProp);
|
|
714
716
|
// The lock as Send sees it, with its scope (§12.36). Send's Button reads the same
|
|
715
717
|
// through its own `commit`; this holds the keyboard's send back with it.
|
|
@@ -797,7 +799,7 @@ export function ChatComposer({
|
|
|
797
799
|
const config = attachment === true ? {} : attachment || null;
|
|
798
800
|
// The slot is handed the ref OBJECT, for a field's `pasteFrom`, which reads `.current`
|
|
799
801
|
// in an effect once the root is attached — nothing reads it during this render (see
|
|
800
|
-
//
|
|
802
|
+
// ChatComposerSlotContext.root).
|
|
801
803
|
const slot =
|
|
802
804
|
typeof attachmentSlot === "function"
|
|
803
805
|
? // eslint-disable-next-line react-hooks/refs -- handed on for an effect, not read here
|
|
@@ -902,12 +904,12 @@ function dataAttributes(props: object): Record<string, unknown> {
|
|
|
902
904
|
return out;
|
|
903
905
|
}
|
|
904
906
|
|
|
905
|
-
/** {@link
|
|
906
|
-
export type
|
|
907
|
-
/** {@link
|
|
908
|
-
export type
|
|
909
|
-
/**
|
|
910
|
-
* namespace
|
|
911
|
-
export type
|
|
912
|
-
/**
|
|
913
|
-
export type
|
|
907
|
+
/** @deprecated 0.52 — {@link ChatComposerProps}, the same type; removed in 0.53 */
|
|
908
|
+
export type FeedbackComposerProps = ChatComposerProps;
|
|
909
|
+
/** @deprecated 0.52 — {@link ChatComposerHandle}, the same type; removed in 0.53 */
|
|
910
|
+
export type FeedbackComposerHandle = ChatComposerHandle;
|
|
911
|
+
/** @deprecated 0.52 — {@link ChatComposerLabels}, the same type (still the provider's
|
|
912
|
+
* `feedbackComposer` namespace); removed in 0.53 */
|
|
913
|
+
export type FeedbackComposerLabels = ChatComposerLabels;
|
|
914
|
+
/** @deprecated 0.52 — {@link ChatComposerSlotContext}, the same type; removed in 0.53 */
|
|
915
|
+
export type FeedbackComposerSlotContext = ChatComposerSlotContext;
|
package/src/feedback.ts
CHANGED
|
@@ -31,3 +31,45 @@ export * from "./feedback/feedback-vote-button";
|
|
|
31
31
|
export * from "./feedback/feedback-comment-thread";
|
|
32
32
|
export * from "./feedback/feedback-replies";
|
|
33
33
|
export * from "./feedback/feedback-entry-file";
|
|
34
|
+
// 0.52: the slice's share of the 55 names no app reads (refactor audit 2026-10-30, API-4,
|
|
35
|
+
// decision 4), tagged on their specifiers as the barrel's are — the modules keep them.
|
|
36
|
+
export {
|
|
37
|
+
/** @deprecated 0.52 — `appendRework`, which writes the line (API-4); removed in 0.53 */
|
|
38
|
+
feedbackAttachmentLine,
|
|
39
|
+
} from "./feedback/feedback-record";
|
|
40
|
+
export {
|
|
41
|
+
/** @deprecated 0.52 — `useFeedbackStatusUndo`, which keeps its Undo that long (API-4); removed in 0.53 */
|
|
42
|
+
FEEDBACK_UNDO_DURATION,
|
|
43
|
+
} from "./feedback/feedback-status-undo";
|
|
44
|
+
export {
|
|
45
|
+
/** @deprecated 0.52 — `DEFAULT_FEEDBACK_SWIPE` and `feedbackSwipePlan`, which name the actions (API-4); removed in 0.53 */
|
|
46
|
+
FEEDBACK_SWIPE_ACTIONS,
|
|
47
|
+
} from "./feedback/feedback-swipe";
|
|
48
|
+
export {
|
|
49
|
+
/** @deprecated 0.52 — `useFeedbackColumns`, the same columns in the provider's words (API-4); removed in 0.53 */
|
|
50
|
+
feedbackColumns,
|
|
51
|
+
/** @deprecated 0.52 — `useFeedbackColumns`, whose submitter cell reads it (API-4); removed in 0.53 */
|
|
52
|
+
feedbackSubmitter,
|
|
53
|
+
/** @deprecated 0.52 — `useFeedbackColumns`, whose submitter cell reads it (API-4); removed in 0.53 */
|
|
54
|
+
feedbackSubmitterEmail,
|
|
55
|
+
/** @deprecated 0.52 — `useFeedbackColumns`, whose environment cell reads it (API-4); removed in 0.53 */
|
|
56
|
+
feedbackEnvironment,
|
|
57
|
+
} from "./feedback/feedback-table";
|
|
58
|
+
export {
|
|
59
|
+
/** @deprecated 0.52 — `FeedbackRowDetail`, which links the page itself (API-4); removed in 0.53 */
|
|
60
|
+
feedbackPageUrl,
|
|
61
|
+
/** @deprecated 0.52 — `FeedbackRowDetail` and the table's URL cell, which link only a page's path and keep one-shot pages as text (the 0.52 code review's guard, which an app has no helper for); removed in 0.53 */
|
|
62
|
+
feedbackPageHref,
|
|
63
|
+
/** @deprecated 0.52 — `FeedbackRowDetail` and the table's URL cell, which show the page themselves; removed in 0.53 */
|
|
64
|
+
feedbackPagePath,
|
|
65
|
+
/** @deprecated 0.52 — `FeedbackRowDetail`, which lists the attachments itself (API-4); removed in 0.53 */
|
|
66
|
+
feedbackAttachmentUrls,
|
|
67
|
+
/** @deprecated 0.52 — `FeedbackRowDetail`, which decides who may edit what (API-4); removed in 0.53 */
|
|
68
|
+
feedbackRowAccess,
|
|
69
|
+
/** @deprecated 0.52 — `FeedbackRowDetail`, which resolves its words itself (API-4); removed in 0.53 */
|
|
70
|
+
useFeedbackDetailLabels,
|
|
71
|
+
} from "./feedback/feedback-row-detail";
|
|
72
|
+
export {
|
|
73
|
+
/** @deprecated 0.52 — `FeedbackPublicSwitch`, which asks it (API-4); removed in 0.53 */
|
|
74
|
+
feedbackPublicSwitchAllowed,
|
|
75
|
+
} from "./feedback/feedback-public-switch";
|
|
@@ -1,4 +1,5 @@
|
|
|
1
1
|
import { useEffect, useLayoutEffect, useRef, useState } from "react";
|
|
2
|
+
import { tabStops } from "../lib/focus-left";
|
|
2
3
|
|
|
3
4
|
/**
|
|
4
5
|
* Keep keyboard focus inside an open overlay, and give it back when it closes.
|
|
@@ -35,28 +36,11 @@ import { useEffect, useLayoutEffect, useRef, useState } from "react";
|
|
|
35
36
|
* button; this is the focus half of it.
|
|
36
37
|
*/
|
|
37
38
|
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
* BUG-4): only the bare `[tabindex]` clause excluded `-1`, so a `button`, an `input` or
|
|
44
|
-
* a link taken out of the tab order still counted. A panel that ends in a roving grid —
|
|
45
|
-
* the calendar's days, the month grid, the picker sheet's rows, every one of them `-1`
|
|
46
|
-
* but the active cell — then had a "last" stop no Tab ever reaches: Tab from the real
|
|
47
|
-
* last stop was not wrapped and walked out of the open panel, and Shift+Tab from the
|
|
48
|
-
* first landed on a cell that is not a stop at all.
|
|
49
|
-
*/
|
|
50
|
-
const FOCUSABLE =
|
|
51
|
-
'a[href],button:not([disabled]),textarea:not([disabled]),input:not([disabled]),select:not([disabled]),[tabindex]:not([tabindex="-1"])';
|
|
52
|
-
|
|
53
|
-
/**
|
|
54
|
-
* A stop the browser's own Tab would land on: in the tab order (`tabIndex` ≥ 0) and not
|
|
55
|
-
* inside something `hidden` or `inert`. Removes only elements a native Tab never
|
|
56
|
-
* reaches, so no correct order changes. `visibility: hidden` and closed `<details>` are
|
|
57
|
-
* still not walked — they need layout, which this list has never read.
|
|
58
|
-
*/
|
|
59
|
-
const isTabStop = (el: HTMLElement): boolean => el.tabIndex >= 0 && !el.closest("[hidden],[inert]");
|
|
39
|
+
// The trap's reading of "a Tab lands here" is lib/focus-left's `tabStops` — the kit's one
|
|
40
|
+
// copy of the rule since the 0.52 code review (round 0.34 BUG-4's history is there).
|
|
41
|
+
// Re-exported where refactor audit 2026-10-30, DUP-9 put them, for a part that walks Tab
|
|
42
|
+
// over something that is not a trap (the tour's field + card ring).
|
|
43
|
+
export { firstTabStop, tabStops } from "../lib/focus-left";
|
|
60
44
|
|
|
61
45
|
/**
|
|
62
46
|
* Marks a container whose trap is currently active.
|
|
@@ -146,11 +130,11 @@ export function useFocusTrap(
|
|
|
146
130
|
};
|
|
147
131
|
|
|
148
132
|
const tabbables = () =>
|
|
149
|
-
|
|
133
|
+
tabStops(container, { includeSelf: false }).filter(
|
|
150
134
|
// A tabbable inside a NESTED open overlay belongs to that overlay's trap, not
|
|
151
135
|
// to this one — otherwise the outer list spans both panels and Tab from the
|
|
152
136
|
// inner panel's last control wraps to the OUTER panel's first.
|
|
153
|
-
(el) =>
|
|
137
|
+
(el) => !inNestedTrap(el),
|
|
154
138
|
);
|
|
155
139
|
|
|
156
140
|
const { initialFocus: how } = optsRef.current;
|
package/src/hooks/use-hotkey.ts
CHANGED
|
@@ -94,18 +94,28 @@ const KEY_ALIASES: Record<string, string> = {
|
|
|
94
94
|
right: "arrowright",
|
|
95
95
|
};
|
|
96
96
|
|
|
97
|
+
/** One letter of a script other than Latin: what a Russian, Greek or Hebrew layout's letter keys type. */
|
|
98
|
+
const NON_LATIN_LETTER = /^(?!\p{Script=Latin})\p{L}$/u;
|
|
99
|
+
|
|
97
100
|
/** Whether `e` is `combo` — every modifier as named (no more, no fewer), and the key. */
|
|
98
101
|
export function matchesHotkey(e: KeyboardEvent, combo: ParsedHotkey): boolean {
|
|
99
102
|
if (e.ctrlKey !== combo.ctrl || e.metaKey !== combo.meta || e.altKey !== combo.alt) return false;
|
|
100
103
|
const want = KEY_ALIASES[combo.key.toLowerCase()] ?? combo.key.toLowerCase();
|
|
101
104
|
const key = (e.key ?? "").toLowerCase();
|
|
102
105
|
const code = (e.code ?? "").toLowerCase();
|
|
103
|
-
|
|
104
|
-
|
|
106
|
+
// On a non-Latin layout `key` is the local letter — Ctrl+K types "л" on a Russian one —
|
|
107
|
+
// so a letter chord never fired there, ⌘K included (0.52 code review, use-hotkey.ts; the
|
|
108
|
+
// hand-written ⌘K listener before 0.52 compared `key` alone and missed it too). The
|
|
109
|
+
// physical key stands in for the letter there, and only there: a Latin layout's letter
|
|
110
|
+
// is wherever it types (Dvorak's K is on QWERTY's V).
|
|
111
|
+
const physical = /^[a-z]$/.test(want) && NON_LATIN_LETTER.test(e.key ?? "") && code === `key${want}`;
|
|
112
|
+
if (key !== want && code !== want && !physical) return false;
|
|
105
113
|
// Shift must match exactly for a letter or a named key; for a symbol it is how the
|
|
106
114
|
// symbol is typed ("?" is Shift+/ on a US layout, a plain key on others), so an
|
|
107
|
-
// unnamed Shift is not held against it.
|
|
108
|
-
|
|
115
|
+
// unnamed Shift is not held against it. Space is a named key, not a symbol, though its
|
|
116
|
+
// alias is one character: "Space" fired on Shift+Space, the browser's page-up, and
|
|
117
|
+
// cancelled it (0.52 code review, use-hotkey.ts).
|
|
118
|
+
const symbol = want.length === 1 && !/[a-z0-9 ]/.test(want);
|
|
109
119
|
return symbol && !combo.shift ? true : e.shiftKey === combo.shift;
|
|
110
120
|
}
|
|
111
121
|
|
|
@@ -128,10 +138,13 @@ function isTypingTarget(target: EventTarget | null): boolean {
|
|
|
128
138
|
* - Modifiers match EXACTLY: `"Ctrl+K"` does not fire on Ctrl+Shift+K.
|
|
129
139
|
* - Typing in a field is left alone unless `allowInInputs`, except for a combo with
|
|
130
140
|
* Ctrl / Meta / Alt, which no one types as text.
|
|
131
|
-
* - A key held down fires once, not on every repeat
|
|
141
|
+
* - A key held down fires once, not on every repeat — and its repeats are cancelled as
|
|
142
|
+
* the first press was, or the browser acts on them.
|
|
132
143
|
* - The newest `handler` is always called; changing it does not re-attach the listener.
|
|
133
144
|
*
|
|
134
|
-
* `useCommandKey` (the ⌘K palette hook) is
|
|
145
|
+
* `useCommandKey` (the ⌘K palette hook) is this with `"Mod+K"` and `allowInInputs`
|
|
146
|
+
* since 0.52, and FormActions' Ctrl/Cmd+Enter is {@link matchesHotkey} (refactor audit
|
|
147
|
+
* 2026-10-30, DUP-12): one reading of a chord.
|
|
135
148
|
*/
|
|
136
149
|
export function useHotkey(
|
|
137
150
|
combo: Hotkey | ReadonlyArray<Hotkey>,
|
|
@@ -156,7 +169,6 @@ export function useHotkey(
|
|
|
156
169
|
const parsed = key.split("\u0000").map((c) => parseHotkey(c, apple));
|
|
157
170
|
const listener = (raw: Event) => {
|
|
158
171
|
const e = raw as KeyboardEvent;
|
|
159
|
-
if (e.repeat) return;
|
|
160
172
|
const hit = parsed.find((p) => matchesHotkey(e, p));
|
|
161
173
|
if (!hit) return;
|
|
162
174
|
if (allowInInputs !== true && isTypingTarget(e.target)) {
|
|
@@ -164,6 +176,11 @@ export function useHotkey(
|
|
|
164
176
|
if (allowInInputs === "never" || !chorded) return;
|
|
165
177
|
}
|
|
166
178
|
if (preventDefault) e.preventDefault();
|
|
179
|
+
// A held key's repeats are cancelled like its first press, and call nothing. They
|
|
180
|
+
// returned before the `preventDefault` once, so a held Ctrl+K's repeats reached the
|
|
181
|
+
// browser's own Ctrl+K and took the focus out of the palette ⌘K had just opened
|
|
182
|
+
// (0.52 code review, use-hotkey.ts; the hand-written ⌘K listener cancelled them).
|
|
183
|
+
if (e.repeat) return;
|
|
167
184
|
handlerRef.current(e);
|
|
168
185
|
};
|
|
169
186
|
node.addEventListener(event, listener);
|
|
@@ -4,7 +4,8 @@ import { useCallback, useEffect, useRef, type PointerEvent as ReactPointerEvent
|
|
|
4
4
|
// keksdose live #421). Taken over from keksdose's register list
|
|
5
5
|
// (frontend/src/shared/hooks/use-long-press.ts, its feedback #153) so the kit's cards
|
|
6
6
|
// and kk's register answer the same gesture the same way: 500 ms, an 8 px dead zone,
|
|
7
|
-
// cancelled by a scroll, the trailing click swallowed.
|
|
7
|
+
// cancelled by a scroll, the trailing click swallowed. Public since 0.52 (DUP-8, refactor
|
|
8
|
+
// audit 2026-10-30): private, it left keksdose keeping the original beside the copy.
|
|
8
9
|
|
|
9
10
|
const LONG_PRESS_MS = 500;
|
|
10
11
|
/** The same 8 px dead zone `useRowSwipe` locks its axis at: the press is dead by the
|
|
@@ -14,6 +15,13 @@ const SLOP_PX = 8;
|
|
|
14
15
|
const movedBeyondSlop = (from: { x: number; y: number }, x: number, y: number) =>
|
|
15
16
|
Math.hypot(x - from.x, y - from.y) > SLOP_PX;
|
|
16
17
|
|
|
18
|
+
export interface LongPressOptions {
|
|
19
|
+
/** Default `true`. Off, a press does nothing and the context menu is the browser's. */
|
|
20
|
+
enabled?: boolean;
|
|
21
|
+
/** How long a press is held, in ms. Default 500. */
|
|
22
|
+
delay?: number;
|
|
23
|
+
}
|
|
24
|
+
|
|
17
25
|
export interface LongPressResult {
|
|
18
26
|
handlers: {
|
|
19
27
|
onPointerDown: (e: ReactPointerEvent) => void;
|
|
@@ -40,7 +48,7 @@ export interface LongPressResult {
|
|
|
40
48
|
*/
|
|
41
49
|
export function useLongPress(
|
|
42
50
|
onLongPress: () => void,
|
|
43
|
-
{ enabled = true, delay = LONG_PRESS_MS }:
|
|
51
|
+
{ enabled = true, delay = LONG_PRESS_MS }: LongPressOptions = {},
|
|
44
52
|
): LongPressResult {
|
|
45
53
|
const timer = useRef<number | null>(null);
|
|
46
54
|
const start = useRef({ x: 0, y: 0 });
|
|
@@ -120,6 +128,12 @@ export function useLongPress(
|
|
|
120
128
|
return true;
|
|
121
129
|
}, []);
|
|
122
130
|
|
|
131
|
+
// Turned off mid-press: the armed timer still fired, entering selection mode against the
|
|
132
|
+
// caller's wish and arming `consumeClick` for the next click (0.52 code review).
|
|
133
|
+
useEffect(() => {
|
|
134
|
+
if (!enabled) cancel();
|
|
135
|
+
}, [enabled, cancel]);
|
|
136
|
+
|
|
123
137
|
useEffect(() => cancel, [cancel]);
|
|
124
138
|
|
|
125
139
|
return { handlers: { onPointerDown, onPointerMove, onContextMenu }, consumeClick };
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { useEffect, useState } from "react";
|
|
1
|
+
import { useEffect, useEffectEvent, useState } from "react";
|
|
2
2
|
|
|
3
3
|
/**
|
|
4
4
|
* Subscribe to a CSS media query, returning whether it currently matches and
|
|
@@ -10,12 +10,28 @@ export function useMediaQuery(query: string, fallback: boolean): boolean {
|
|
|
10
10
|
typeof window !== "undefined" && typeof window.matchMedia === "function"
|
|
11
11
|
? window.matchMedia(query).matches
|
|
12
12
|
: fallback;
|
|
13
|
-
|
|
13
|
+
// The answer is kept with the query it answers, and a new query is asked during the
|
|
14
|
+
// render that brings it. Read at mount only, the first commit after a new query still
|
|
15
|
+
// answered the OLD one, until the effect corrected it: `useBreakpoint` asks a new query
|
|
16
|
+
// when the text size changes, and at Large in a 700 px window the tour card was drawn
|
|
17
|
+
// un-docked for a frame before it docked (0.52 code review, use-breakpoint.ts).
|
|
18
|
+
const [state, setState] = useState(() => ({ query, matches: get() }));
|
|
19
|
+
let matches = state.matches;
|
|
20
|
+
if (state.query !== query) {
|
|
21
|
+
matches = get();
|
|
22
|
+
setState({ query, matches });
|
|
23
|
+
}
|
|
24
|
+
const answered = useEffectEvent(() => matches);
|
|
14
25
|
useEffect(() => {
|
|
15
26
|
if (typeof window === "undefined" || typeof window.matchMedia !== "function") return;
|
|
16
27
|
const mql = window.matchMedia(query);
|
|
17
|
-
const update = () =>
|
|
18
|
-
|
|
28
|
+
const update = () =>
|
|
29
|
+
setState((prev) =>
|
|
30
|
+
prev.query === query && prev.matches === mql.matches ? prev : { query, matches: mql.matches },
|
|
31
|
+
);
|
|
32
|
+
// A change between the render and this subscription. Only then: an update that
|
|
33
|
+
// changes nothing still costs a render (and a commit) right after a new query.
|
|
34
|
+
if (mql.matches !== answered()) update();
|
|
19
35
|
mql.addEventListener("change", update);
|
|
20
36
|
return () => mql.removeEventListener("change", update);
|
|
21
37
|
}, [query]);
|