@eifi1/ui-kit 0.51.7 → 0.53.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 +178 -67
- 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 +10 -7
- package/dist/billing/cancel-subscription.js +6 -6
- package/dist/billing/cancel-subscription.js.map +1 -1
- package/dist/billing/plan-card.d.ts +5 -3
- package/dist/billing/plan-card.js +7 -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 +9 -6
- package/dist/billing/plan-switch.js +7 -5
- package/dist/billing/plan-switch.js.map +1 -1
- package/dist/chart.d.ts +4 -3
- package/dist/chart.js +72 -4
- 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 +25 -3
- package/dist/components/date-field.js +33 -8
- package/dist/components/date-field.js.map +1 -1
- package/dist/components/date-picker.d.ts +16 -3
- 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 +38 -24
- 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/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/nav-pills.d.ts +1 -1
- package/dist/components/nav-pills.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/series-chart-axes.d.ts +4 -4
- 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 +92 -23
- package/dist/components/series-chart.js +74 -30
- 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/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 +31 -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 +167 -19
- package/dist/components/treemap.js +340 -100
- 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 +1 -2
- package/dist/data-table.js +1 -4
- package/dist/data-table.js.map +1 -1
- package/dist/demo/demo-countdown.d.ts +0 -5
- package/dist/demo/demo-countdown.js +0 -4
- package/dist/demo/demo-countdown.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 +18 -0
- package/dist/feedback/feedback-mutation.js +8 -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 +8 -4
- package/dist/feedback/feedback-public-list.js +2 -2
- 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 +0 -3
- package/dist/feedback/feedback-row-detail-labels.js.map +1 -1
- package/dist/feedback/feedback-row-detail.d.ts +33 -44
- package/dist/feedback/feedback-row-detail.js +28 -34
- package/dist/feedback/feedback-row-detail.js.map +1 -1
- package/dist/feedback/feedback-status-undo.d.ts +17 -14
- 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 +15 -23
- package/dist/feedback/feedback-thread.js +2 -1
- package/dist/feedback/feedback-thread.js.map +1 -1
- package/dist/feedback.d.ts +6 -6
- package/dist/feedback.js +90 -6
- 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 -9
- package/dist/i18n/defaults.js.map +1 -1
- package/dist/i18n/german.js +7 -18
- package/dist/i18n/german.js.map +1 -1
- package/dist/i18n/kit-labels.d.ts +9 -11
- package/dist/i18n/kit-labels.js.map +1 -1
- package/dist/i18n/locales/en.js +15 -64
- package/dist/i18n/locales/en.js.map +3 -3
- package/dist/i18n/locales/es.js +7 -18
- package/dist/i18n/locales/es.js.map +1 -1
- package/dist/i18n/locales/fr.js +20 -27
- package/dist/i18n/locales/fr.js.map +1 -1
- package/dist/i18n/locales/hu.js +9 -18
- package/dist/i18n/locales/hu.js.map +1 -1
- package/dist/i18n/locales/it.js +7 -19
- package/dist/i18n/locales/it.js.map +1 -1
- package/dist/i18n/locales/zh.js +8 -18
- package/dist/i18n/locales/zh.js.map +1 -1
- package/dist/i18n/review.js +12 -2
- package/dist/i18n/review.js.map +1 -1
- package/dist/i18n/shared-labels.js +0 -1
- package/dist/i18n/shared-labels.js.map +1 -1
- package/dist/index.d.ts +21 -23
- package/dist/index.js +50 -65
- 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/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/search-index.d.ts +0 -6
- package/dist/search/search-index.js +0 -4
- package/dist/search/search-index.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 +1 -1
- package/dist/search.js +6 -1
- 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 +5 -3
- package/dist/shell/account-menu-language.js +2 -2
- package/dist/shell/account-menu-language.js.map +1 -1
- package/dist/shell/account-menu-text-size.d.ts +9 -6
- package/dist/shell/account-menu-text-size.js +2 -2
- package/dist/shell/account-menu-text-size.js.map +1 -1
- package/dist/shell/app-shell.d.ts +0 -10
- package/dist/shell/app-shell.js +1 -7
- package/dist/shell/app-shell.js.map +1 -1
- package/dist/shell/company-switcher.d.ts +1 -1
- package/dist/shell/company-switcher.js.map +1 -1
- package/dist/shell/dev-menu.d.ts +1 -1
- package/dist/shell/dev-menu.js +5 -18
- package/dist/shell/dev-menu.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 +1 -3
- 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 +7 -10
- package/dist/shell.js +14 -23
- 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 +2 -2
- package/dist/sync.js +2 -10
- 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/chart-palette.d.ts +0 -5
- package/dist/theme/chart-palette.js +0 -2
- package/dist/theme/chart-palette.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 +15 -12
- package/src/billing/plan-card.tsx +18 -10
- package/src/billing/plan-change-labels.ts +66 -0
- package/src/billing/plan-switch.tsx +15 -12
- package/src/chart.ts +73 -6
- 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 +66 -9
- package/src/components/date-picker.tsx +125 -49
- package/src/components/date-range-picker.tsx +71 -36
- 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/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/nav-pills.tsx +1 -1
- 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/series-chart-axes.ts +9 -4
- package/src/components/series-chart-labels.ts +7 -4
- package/src/components/series-chart.tsx +253 -87
- package/src/components/share-card.tsx +6 -6
- 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 +47 -0
- package/src/components/treemap-layout.ts +210 -0
- package/src/components/treemap.tsx +780 -138
- package/src/components/use-table-state.ts +12 -9
- package/src/data-table.ts +1 -4
- package/src/demo/demo-countdown.ts +3 -8
- package/src/eslint/role-utilities.ts +97 -19
- package/src/feedback/feedback-dialog.tsx +30 -19
- package/src/feedback/feedback-mutation.ts +20 -0
- package/src/feedback/feedback-page-link.ts +90 -0
- package/src/feedback/feedback-public-list.tsx +13 -7
- package/src/feedback/feedback-replies.tsx +13 -6
- package/src/feedback/feedback-row-detail-labels.ts +0 -3
- package/src/feedback/feedback-row-detail.tsx +70 -84
- package/src/feedback/feedback-status-undo.ts +28 -28
- 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 +18 -26
- package/src/feedback.ts +89 -6
- 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 -9
- package/src/i18n/german.ts +8 -19
- package/src/i18n/kit-labels.tsx +9 -11
- package/src/i18n/locales/es.ts +8 -19
- package/src/i18n/locales/fr.ts +21 -30
- package/src/i18n/locales/hu.ts +10 -19
- package/src/i18n/locales/it.ts +8 -20
- package/src/i18n/locales/zh.ts +9 -19
- package/src/i18n/review.ts +12 -2
- package/src/i18n/shared-labels.ts +0 -1
- package/src/index.ts +57 -49
- 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/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/search-index.ts +0 -15
- package/src/search/use-command-key.ts +13 -12
- package/src/search.ts +10 -1
- package/src/settings/use-settings-focus.ts +3 -0
- package/src/shell/account-menu-language.tsx +6 -4
- package/src/shell/account-menu-text-size.tsx +10 -7
- package/src/shell/app-shell.tsx +0 -13
- package/src/shell/company-switcher.tsx +1 -1
- package/src/shell/dev-menu.tsx +8 -22
- package/src/shell/top-bar-actions.tsx +1 -1
- package/src/shell/top-bar-parts-labels.ts +1 -4
- package/src/shell.ts +21 -17
- package/src/sync/engine.ts +339 -61
- package/src/sync.ts +2 -8
- package/src/testing/css-variables.ts +8 -9
- package/src/theme/chart-palette.ts +0 -2
- 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 +6 -5
- package/dist/components/field-sync-labels.d.ts +0 -2
- package/dist/components/field-sync-labels.js +0 -12
- package/dist/components/field-sync-labels.js.map +0 -1
- package/dist/components/field-sync.d.ts +0 -164
- package/dist/components/field-sync.js +0 -269
- package/dist/components/field-sync.js.map +0 -1
- package/dist/components/section-nav.d.ts +0 -37
- package/dist/components/section-nav.js +0 -33
- package/dist/components/section-nav.js.map +0 -1
- package/dist/components/sign-chip-labels.d.ts +0 -2
- package/dist/components/sign-chip-labels.js +0 -11
- package/dist/components/sign-chip-labels.js.map +0 -1
- package/dist/components/sign-chip.d.ts +0 -68
- package/dist/components/sign-chip.js +0 -47
- package/dist/components/sign-chip.js.map +0 -1
- package/dist/components/ui-labels.js.map +0 -1
- package/dist/lib/isin.d.ts +0 -28
- package/dist/lib/isin.js +0 -36
- package/dist/lib/isin.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/dist/shell/role-switcher.d.ts +0 -21
- package/dist/shell/role-switcher.js +0 -31
- package/dist/shell/role-switcher.js.map +0 -1
- package/src/components/field-sync-labels.ts +0 -13
- package/src/components/field-sync.tsx +0 -482
- package/src/components/section-nav.tsx +0 -65
- package/src/components/sign-chip-labels.ts +0 -12
- package/src/components/sign-chip.tsx +0 -124
- package/src/components/ui-labels.ts +0 -24
- package/src/lib/isin.ts +0 -62
- package/src/shell/dev-switchers.tsx +0 -18
- package/src/shell/role-switcher.tsx +0 -46
|
@@ -16,7 +16,7 @@ import type { DataTableColumn, FilterState, ServerPagination } from "./data-tabl
|
|
|
16
16
|
interface PersistedState {
|
|
17
17
|
// Multi-sort array; blobs from before the upgrade hold a single {key, dir}
|
|
18
18
|
// object (or null) — read back through normalizeSorts.
|
|
19
|
-
sort: SortState[] | { key: string; dir: string } | null;
|
|
19
|
+
sort: readonly SortState[] | { key: string; dir: string } | null;
|
|
20
20
|
filters: FilterState;
|
|
21
21
|
pageSize: number | "all";
|
|
22
22
|
widths?: Record<string, number>;
|
|
@@ -190,7 +190,7 @@ export interface TableUrlState {
|
|
|
190
190
|
*/
|
|
191
191
|
export function readTableUrlState<T>(
|
|
192
192
|
sp: URLSearchParams,
|
|
193
|
-
columns: DataTableColumn<T>[],
|
|
193
|
+
columns: readonly DataTableColumn<T>[],
|
|
194
194
|
prefix?: string,
|
|
195
195
|
): TableUrlState {
|
|
196
196
|
const keys = urlKeys(prefix);
|
|
@@ -232,8 +232,8 @@ export function readTableUrlState<T>(
|
|
|
232
232
|
* produces a different one.
|
|
233
233
|
*/
|
|
234
234
|
function urlSignature<T>(
|
|
235
|
-
columns: DataTableColumn<T>[],
|
|
236
|
-
sorts: SortState[],
|
|
235
|
+
columns: readonly DataTableColumn<T>[],
|
|
236
|
+
sorts: readonly SortState[],
|
|
237
237
|
filters: FilterState,
|
|
238
238
|
pageSize: number,
|
|
239
239
|
page: number,
|
|
@@ -257,8 +257,8 @@ function urlSignature<T>(
|
|
|
257
257
|
|
|
258
258
|
function writeUrlState<T>(
|
|
259
259
|
setSearchParams: ReturnType<typeof useSearchParams>[1],
|
|
260
|
-
columns: DataTableColumn<T>[],
|
|
261
|
-
sorts: SortState[],
|
|
260
|
+
columns: readonly DataTableColumn<T>[],
|
|
261
|
+
sorts: readonly SortState[],
|
|
262
262
|
filters: FilterState,
|
|
263
263
|
pageSize: number,
|
|
264
264
|
page: number,
|
|
@@ -334,12 +334,12 @@ export function useTableState<T>({
|
|
|
334
334
|
filtersProp,
|
|
335
335
|
pageSizeProp,
|
|
336
336
|
}: {
|
|
337
|
-
columns: DataTableColumn<T>[];
|
|
337
|
+
columns: readonly DataTableColumn<T>[];
|
|
338
338
|
storageKey?: string;
|
|
339
339
|
storageKeyPrefix: string;
|
|
340
340
|
urlSync?: TableUrlSync;
|
|
341
341
|
defaultPageSize: number;
|
|
342
|
-
sortsProp?: SortState[];
|
|
342
|
+
sortsProp?: readonly SortState[];
|
|
343
343
|
filtersProp?: FilterState;
|
|
344
344
|
pageSizeProp?: number;
|
|
345
345
|
}) {
|
|
@@ -574,6 +574,9 @@ export function useSharedTableView({
|
|
|
574
574
|
pageSize: next.pageSize === Infinity ? "all" : next.pageSize,
|
|
575
575
|
widths: stored.widths,
|
|
576
576
|
hidden: stored.hidden,
|
|
577
|
+
// The `defaultHidden` columns the single table's user ticked back on (0.48): left
|
|
578
|
+
// out, a sort changed here hid them again there (refactor audit 2026-10-30, DSP-23 c).
|
|
579
|
+
...(stored.shown ? { shown: stored.shown } : {}),
|
|
577
580
|
};
|
|
578
581
|
writeStored(prefix + storageKey, serializePersisted(blob));
|
|
579
582
|
};
|
|
@@ -589,7 +592,7 @@ export function useSharedTableView({
|
|
|
589
592
|
|
|
590
593
|
export interface UseTableUrlStateOptions<T> {
|
|
591
594
|
/** The table's columns — read for their keys and filter types only. */
|
|
592
|
-
columns: DataTableColumn<T>[];
|
|
595
|
+
columns: readonly DataTableColumn<T>[];
|
|
593
596
|
/** Default 25. A page size equal to it is left out of the URL. */
|
|
594
597
|
defaultPageSize?: number;
|
|
595
598
|
/** Mirror the state into the URL and seed it from there on mount. Default true.
|
package/src/data-table.ts
CHANGED
|
@@ -27,15 +27,12 @@ export type {
|
|
|
27
27
|
DataTableRowAction,
|
|
28
28
|
DataTableDesktopSwipeActions,
|
|
29
29
|
} from "./components/data-table";
|
|
30
|
-
// 0.46.1 (keksdose N3): a swipe plan as `RowActions`' actions — the desktop column's own
|
|
31
|
-
// derivation, for an app's hand-built actions column.
|
|
32
|
-
export { swipePlanRowActions } from "./components/data-table-row-actions";
|
|
33
30
|
// 0.48 (keksdose dev #605): a `groupBy` level (also `mobileGroupBy`'s) and the `loadMore` footer.
|
|
34
31
|
export type { DataTableGroupBy, DataTableLoadMore } from "./components/data-table-groups";
|
|
35
32
|
// 0.48.2 (keksdose dev #632): `virtualize`'s options.
|
|
36
33
|
export type { DataTableVirtualize } from "./components/data-table-virtual";
|
|
37
34
|
export * from "./components/data-table-cells";
|
|
38
|
-
export { useTableUrlState
|
|
35
|
+
export { useTableUrlState } from "./components/use-table-state";
|
|
39
36
|
export type {
|
|
40
37
|
TableUrlState,
|
|
41
38
|
TableUrlSync,
|
|
@@ -50,14 +50,9 @@ function minutesAt(expiry: number, now: number): number | null {
|
|
|
50
50
|
return Math.max(0, Math.ceil((expiry - now) / MINUTE));
|
|
51
51
|
}
|
|
52
52
|
|
|
53
|
-
/**
|
|
54
|
-
*
|
|
55
|
-
*
|
|
56
|
-
*/
|
|
57
|
-
export function demoCountdown(expiresAt: DemoExpiry | null | undefined, now: number): DemoCountdown {
|
|
58
|
-
return countdownOf(minutesAt(expiryMs(expiresAt), now));
|
|
59
|
-
}
|
|
60
|
-
|
|
53
|
+
/** The countdown for `minutesLeft` — see {@link DemoCountdown} for the rounding and the
|
|
54
|
+
* thresholds. (Public as `demoCountdown(expiresAt, now)` until 0.53, deprecated in 0.52,
|
|
55
|
+
* API-4: `useDemoCountdown` with its `now` option is the same countdown.) */
|
|
61
56
|
function countdownOf(minutesLeft: number | null): DemoCountdown {
|
|
62
57
|
if (minutesLeft === null) {
|
|
63
58
|
return { minutesLeft, hours: 0, minutes: 0, lastHour: false, warning: false, ended: false };
|
|
@@ -63,9 +63,12 @@ export interface ThemeInlineDeclaration {
|
|
|
63
63
|
|
|
64
64
|
/** The `@theme inline` block: where it stands, and every declaration in it in block order. */
|
|
65
65
|
export interface ThemeInlineBlock {
|
|
66
|
-
/** Its first and one-past-last offset in `stripCssComments(css)`, not in `css`.
|
|
66
|
+
/** Its first and one-past-last offset in `stripCssComments(css)`, not in `css`. With
|
|
67
|
+
* several `@theme inline` blocks, the first one's; `ranges` holds each. */
|
|
67
68
|
start: number;
|
|
68
69
|
end: number;
|
|
70
|
+
ranges: { start: number; end: number }[];
|
|
71
|
+
/** Every block's, in stylesheet order. */
|
|
69
72
|
declarations: ThemeInlineDeclaration[];
|
|
70
73
|
}
|
|
71
74
|
|
|
@@ -74,19 +77,60 @@ export function stripCssComments(css: string): string {
|
|
|
74
77
|
return css.replace(/\/\*[\s\S]*?\*\//g, "");
|
|
75
78
|
}
|
|
76
79
|
|
|
80
|
+
/** One `@theme … { … }` block: its first and one-past-last offset, and what its braces hold. */
|
|
81
|
+
export interface ThemeBlock {
|
|
82
|
+
start: number;
|
|
83
|
+
end: number;
|
|
84
|
+
body: string;
|
|
85
|
+
}
|
|
86
|
+
|
|
87
|
+
/**
|
|
88
|
+
* Every `@theme` block of `css` (comments already stripped) whose prelude names `inline`
|
|
89
|
+
* (`@theme inline`, `@theme inline reference`) — or, with `inline: false`, every other
|
|
90
|
+
* one (`@theme {`, Tailwind's `@theme default {`). Counted brace by brace, so a nested
|
|
91
|
+
* block does not end it early.
|
|
92
|
+
*
|
|
93
|
+
* The one block finder (refactor audit 2026-10-30, DUP-13): this parser read only the
|
|
94
|
+
* first `@theme inline {…}` up to its first `}`, the testing guard's
|
|
95
|
+
* `declaredCustomProperties` every inline block brace-aware, and the README's inventory a
|
|
96
|
+
* plain `@theme {` by a regex of its own — three readers that disagreed on what one block
|
|
97
|
+
* is. It lives here because this module imports nothing, so the scripts load it from
|
|
98
|
+
* source under Node.
|
|
99
|
+
*/
|
|
100
|
+
export function themeBlocks(css: string, { inline }: { inline: boolean }): ThemeBlock[] {
|
|
101
|
+
const blocks: ThemeBlock[] = [];
|
|
102
|
+
for (const m of css.matchAll(/@theme\b([^{;]*)\{/g)) {
|
|
103
|
+
if (/\binline\b/.test(m[1]) !== inline) continue;
|
|
104
|
+
const open = m.index + m[0].length - 1;
|
|
105
|
+
let depth = 0;
|
|
106
|
+
let close = open;
|
|
107
|
+
for (; close < css.length; close++) {
|
|
108
|
+
if (css[close] === "{") depth++;
|
|
109
|
+
else if (css[close] === "}" && --depth === 0) break;
|
|
110
|
+
}
|
|
111
|
+
blocks.push({ start: m.index, end: close + 1, body: css.slice(open + 1, close) });
|
|
112
|
+
}
|
|
113
|
+
return blocks;
|
|
114
|
+
}
|
|
115
|
+
|
|
77
116
|
const PROPERTIES = Object.keys(ROLE_NAMESPACES) as RoleProperty[];
|
|
78
117
|
|
|
79
118
|
/**
|
|
80
|
-
* tokens.css's `@theme inline` block
|
|
81
|
-
* the README's (scripts/gen-styling-inventory.mjs),
|
|
82
|
-
* where the table leaves it out. `null` when there is
|
|
83
|
-
* are gone, or this parser is.
|
|
84
|
-
*
|
|
119
|
+
* tokens.css's `@theme inline` block (every one, should there be several), read once for
|
|
120
|
+
* every reader: the table below, and the README's (scripts/gen-styling-inventory.mjs),
|
|
121
|
+
* which fails on a `property: null` where the table leaves it out. `null` when there is
|
|
122
|
+
* no such block — the role utilities are gone, or this parser is. No namespace is
|
|
123
|
+
* another's prefix, so the first that fits is the one.
|
|
85
124
|
*/
|
|
86
125
|
export function parseThemeInline(css: string): ThemeInlineBlock | null {
|
|
87
|
-
const
|
|
88
|
-
if (
|
|
89
|
-
const declarations = [
|
|
126
|
+
const blocks = themeBlocks(stripCssComments(css), { inline: true });
|
|
127
|
+
if (blocks.length === 0) return null;
|
|
128
|
+
const declarations = [
|
|
129
|
+
...blocks
|
|
130
|
+
.map((b) => b.body)
|
|
131
|
+
.join("\n")
|
|
132
|
+
.matchAll(/--([a-z0-9-]+)\s*:\s*([^;]+);/g),
|
|
133
|
+
].map(([, variable, raw]) => {
|
|
90
134
|
const value = raw.trim();
|
|
91
135
|
const property = PROPERTIES.find((p) => variable.startsWith(`${ROLE_NAMESPACES[p]}-`)) ?? null;
|
|
92
136
|
const name = property && variable.slice(ROLE_NAMESPACES[property].length + 1);
|
|
@@ -99,7 +143,8 @@ export function parseThemeInline(css: string): ThemeInlineBlock | null {
|
|
|
99
143
|
value,
|
|
100
144
|
};
|
|
101
145
|
});
|
|
102
|
-
|
|
146
|
+
const ranges = blocks.map(({ start, end }) => ({ start, end }));
|
|
147
|
+
return { start: ranges[0].start, end: ranges[0].end, ranges, declarations };
|
|
103
148
|
}
|
|
104
149
|
|
|
105
150
|
/**
|
|
@@ -120,12 +165,36 @@ export function roleUtilitiesFromCss(css: string): RoleUtilityTable | null {
|
|
|
120
165
|
/**
|
|
121
166
|
* `text-[var(--text-muted)]`, `hover:bg-[var(--bg-hover)]`, `border-t-[var(--border)]`,
|
|
122
167
|
* `focus-visible:ring-[var(--brand)]/40`, `ring-offset-[var(--bg-surface)]`,
|
|
123
|
-
* `ring-[length:var(--focus-ring-width)]
|
|
124
|
-
*
|
|
125
|
-
*
|
|
168
|
+
* `ring-[length:var(--focus-ring-width)]` — and, since 0.52, Tailwind v4's own spellings
|
|
169
|
+
* of the same: the shorthand `text-(--text-muted)`, a type hint `text-[color:var(--x)]` /
|
|
170
|
+
* `text-(color:--x)` / `ring-(length:--x)`, and the arbitrary property
|
|
171
|
+
* `[color:var(--text-muted)]`, which is `text-muted` (refactor audit 2026-10-30, DOC-1:
|
|
172
|
+
* all of them passed the check and every app's lint). Preceded by a start, a space, a
|
|
173
|
+
* quote or a variant's colon, which the match does not include — nor the variants before
|
|
174
|
+
* it or an opacity or `!` after it — so replacing the match keeps all of them.
|
|
175
|
+
*
|
|
176
|
+
* Groups: 1 the property; then 2 the hint and 3 the token of `-[…var()]`, or 4 and 5 of
|
|
177
|
+
* `-(…)`; or 6 the CSS property and 7 the token of `[property:var()]`.
|
|
126
178
|
*/
|
|
127
|
-
const
|
|
128
|
-
|
|
179
|
+
const TOKEN = "(--[a-zA-Z0-9-]+)";
|
|
180
|
+
const ROLE_CLASS = new RegExp(
|
|
181
|
+
"(?<=^|[\\s\"'`:])(?:" +
|
|
182
|
+
"(text|bg|border(?:-[xytrblse])?|divide|ring-offset|ring|outline|fill|stroke)-" +
|
|
183
|
+
`(?:\\[(?:(length|color):)?var\\(${TOKEN}\\)\\]|\\((?:(length|color):)?${TOKEN}\\))` +
|
|
184
|
+
`|\\[(color|background-color|border-color|outline-color|fill|stroke):var\\(${TOKEN}\\)\\]` +
|
|
185
|
+
")",
|
|
186
|
+
"g",
|
|
187
|
+
);
|
|
188
|
+
|
|
189
|
+
/** The utility prefix an arbitrary property `[property:var(--x)]` is written as. */
|
|
190
|
+
const ARBITRARY_PROPERTY: Record<string, string> = {
|
|
191
|
+
color: "text",
|
|
192
|
+
"background-color": "bg",
|
|
193
|
+
"border-color": "border",
|
|
194
|
+
"outline-color": "outline",
|
|
195
|
+
fill: "fill",
|
|
196
|
+
stroke: "stroke",
|
|
197
|
+
};
|
|
129
198
|
|
|
130
199
|
export interface RoleClassHit {
|
|
131
200
|
/** Where the class starts in the scanned text, after its variants. */
|
|
@@ -137,17 +206,26 @@ export interface RoleClassHit {
|
|
|
137
206
|
}
|
|
138
207
|
|
|
139
208
|
/**
|
|
140
|
-
* Every `[var(--token)]` class in `text`
|
|
209
|
+
* Every `[var(--token)]` class in `text` (or one of v4's spellings of it, above) whose
|
|
210
|
+
* token has a role utility on that property.
|
|
141
211
|
* A token with no utility there (`text-[var(--chart-1)]`, `--status-*`,
|
|
142
212
|
* `bg-[var(--border)]` as a divider's fill) is not a hit: `[var(--…)]` is right for it.
|
|
143
213
|
*/
|
|
144
214
|
export function findRoleClasses(text: string, table: RoleUtilityTable): RoleClassHit[] {
|
|
145
|
-
|
|
215
|
+
// Every form names a token: `var(--x)`, or `(--x)` in v4's shorthand.
|
|
216
|
+
if (!text.includes("--")) return [];
|
|
146
217
|
const hits: RoleClassHit[] = [];
|
|
147
218
|
for (const m of text.matchAll(ROLE_CLASS)) {
|
|
148
|
-
const [found,
|
|
219
|
+
const [found, utility, bracketHint, bracketToken, parenHint, parenToken, cssProperty, propertyToken] = m;
|
|
220
|
+
const prop = utility ?? ARBITRARY_PROPERTY[cssProperty];
|
|
221
|
+
const token = bracketToken ?? parenToken ?? propertyToken;
|
|
149
222
|
// `border-t` and `divide` read `border`'s names; a `length:` hint reads the widths.
|
|
150
|
-
const key =
|
|
223
|
+
const key =
|
|
224
|
+
(bracketHint ?? parenHint) === "length"
|
|
225
|
+
? `${prop}-width`
|
|
226
|
+
: prop.startsWith("border-") || prop === "divide"
|
|
227
|
+
? "border"
|
|
228
|
+
: prop;
|
|
151
229
|
const names = (table as Partial<Record<string, Readonly<Record<string, readonly string[]>>>>)[key]?.[token];
|
|
152
230
|
if (names?.length) hits.push({ index: m.index, found, utilities: names.map((name) => `${prop}-${name}`) });
|
|
153
231
|
}
|
|
@@ -9,6 +9,7 @@ import { Modal } from "../components/modal";
|
|
|
9
9
|
import { isApplePlatform } from "../hooks/use-hotkey";
|
|
10
10
|
import { usePhoneLayout } from "../hooks/use-breakpoint";
|
|
11
11
|
import { useKitLabels, type LabelOverride } from "../i18n/kit-labels";
|
|
12
|
+
import { hasContent } from "../lib/presence";
|
|
12
13
|
import {
|
|
13
14
|
DEFAULT_ATTACHMENT_ACCEPT,
|
|
14
15
|
DEFAULT_FEEDBACK_ATTACHMENT_LABELS,
|
|
@@ -19,8 +20,10 @@ import {
|
|
|
19
20
|
} from "./feedback-attachment";
|
|
20
21
|
import { DEFAULT_FEEDBACK_DIALOG_LABELS } from "./feedback-dialog-labels";
|
|
21
22
|
|
|
22
|
-
|
|
23
|
-
|
|
23
|
+
/** One category the dialog offers. `C` (0.52): the app's category type — the kit's
|
|
24
|
+
* `FeedbackCategory`, or `string` (the default) for a vocabulary of the app's own. */
|
|
25
|
+
export interface FeedbackCategoryOption<C extends string = string> {
|
|
26
|
+
value: C;
|
|
24
27
|
label: string;
|
|
25
28
|
}
|
|
26
29
|
|
|
@@ -103,10 +106,10 @@ export interface FeedbackDialogTextLabels {
|
|
|
103
106
|
// Defined in ./feedback-dialog-labels, which holds no component code (0.34, KS U8).
|
|
104
107
|
export { DEFAULT_FEEDBACK_DIALOG_LABELS };
|
|
105
108
|
|
|
106
|
-
export interface FeedbackSubmission {
|
|
109
|
+
export interface FeedbackSubmission<C extends string = string> {
|
|
107
110
|
title: string;
|
|
108
111
|
body: string;
|
|
109
|
-
category:
|
|
112
|
+
category: C;
|
|
110
113
|
attachment: File | null;
|
|
111
114
|
}
|
|
112
115
|
|
|
@@ -116,22 +119,29 @@ export interface FeedbackSubmission {
|
|
|
116
119
|
* attaches the screenshot to the report and the photos as its evidence list. No
|
|
117
120
|
* `attachment`: there is no one file it could name.
|
|
118
121
|
*/
|
|
119
|
-
export interface FeedbackMultipleSubmission {
|
|
122
|
+
export interface FeedbackMultipleSubmission<C extends string = string> {
|
|
120
123
|
title: string;
|
|
121
124
|
body: string;
|
|
122
|
-
category:
|
|
125
|
+
category: C;
|
|
123
126
|
/** What `onCaptureScreenshot` returned, or `null` — at most one. */
|
|
124
127
|
screenshot: File | null;
|
|
125
128
|
/** Picked and pasted files, in the order they were added; at most `maxAttachments`. */
|
|
126
129
|
attachments: File[];
|
|
127
130
|
}
|
|
128
131
|
|
|
129
|
-
|
|
132
|
+
/**
|
|
133
|
+
* `C` (0.52, refactor audit 2026-10-30, API-7): the category type, inferred from
|
|
134
|
+
* `categories` and `category` — `FeedbackCategory` hands `onCategoryChange` and
|
|
135
|
+
* `onSubmit` a `FeedbackCategory` back, where a plain `string` had to be cast (the kit's
|
|
136
|
+
* own `useFeedbackSubmit` did). `string` by default, so an app's own vocabulary fits.
|
|
137
|
+
*/
|
|
138
|
+
interface FeedbackDialogBaseProps<C extends string = string> {
|
|
130
139
|
open: boolean;
|
|
131
140
|
onClose: () => void;
|
|
132
|
-
|
|
133
|
-
|
|
134
|
-
|
|
141
|
+
/** `readonly` since 0.52: the dialog never changes it. */
|
|
142
|
+
categories: readonly FeedbackCategoryOption<C>[];
|
|
143
|
+
category: C;
|
|
144
|
+
onCategoryChange: (value: C) => void;
|
|
135
145
|
/** Prop > `<UiKitProvider labels={{ feedbackDialog, feedbackAttachment }}>` >
|
|
136
146
|
* English. Optional since 0.12.0; a whole `FeedbackDialogLabels` still fits. */
|
|
137
147
|
labels?: LabelOverride<FeedbackDialogLabels>;
|
|
@@ -178,9 +188,9 @@ interface FeedbackDialogBaseProps {
|
|
|
178
188
|
|
|
179
189
|
/** One attachment — a screenshot, a picked or a pasted image; a second replaces
|
|
180
190
|
* nothing, it has to wait for the first to be removed. The default. */
|
|
181
|
-
export interface FeedbackDialogSingleProps extends FeedbackDialogBaseProps {
|
|
191
|
+
export interface FeedbackDialogSingleProps<C extends string = string> extends FeedbackDialogBaseProps<C> {
|
|
182
192
|
attachments?: "single";
|
|
183
|
-
onSubmit: (data: FeedbackSubmission) => void | Promise<void>;
|
|
193
|
+
onSubmit: (data: FeedbackSubmission<C>) => void | Promise<void>;
|
|
184
194
|
/** `info` (0.23.0) names the refused file and the limit — see
|
|
185
195
|
* {@link FeedbackAttachmentErrorInfo}. */
|
|
186
196
|
onAttachmentError?: (kind: "type" | "size", info: FeedbackAttachmentErrorInfo) => void;
|
|
@@ -193,17 +203,18 @@ export interface FeedbackDialogSingleProps extends FeedbackDialogBaseProps {
|
|
|
193
203
|
* dev#578: "pasted two photos, the second overwrote the first"). The capture button is
|
|
194
204
|
* offered while there is no screenshot yet; the add button while there is room.
|
|
195
205
|
*/
|
|
196
|
-
export interface FeedbackDialogMultipleProps extends FeedbackDialogBaseProps {
|
|
206
|
+
export interface FeedbackDialogMultipleProps<C extends string = string> extends FeedbackDialogBaseProps<C> {
|
|
197
207
|
attachments: "multiple";
|
|
198
208
|
/** Default `DEFAULT_MAX_ATTACHMENTS` (5). The screenshot does not count. */
|
|
199
209
|
maxAttachments?: number;
|
|
200
|
-
onSubmit: (data: FeedbackMultipleSubmission) => void | Promise<void>;
|
|
210
|
+
onSubmit: (data: FeedbackMultipleSubmission<C>) => void | Promise<void>;
|
|
201
211
|
/** `"count"`: more files arrived at once than there was room for; the surplus was
|
|
202
212
|
* dropped. `info` (0.23.0) names the refused file(s) and the limit. */
|
|
203
213
|
onAttachmentError?: (kind: FeedbackAttachmentError, info: FeedbackAttachmentErrorInfo) => void;
|
|
204
214
|
}
|
|
205
215
|
|
|
206
|
-
export type FeedbackDialogProps =
|
|
216
|
+
export type FeedbackDialogProps<C extends string = string> =
|
|
217
|
+
FeedbackDialogSingleProps<C> | FeedbackDialogMultipleProps<C>;
|
|
207
218
|
|
|
208
219
|
/**
|
|
209
220
|
* The generic feedback form dialog: category + subject + body + an optional image
|
|
@@ -225,7 +236,7 @@ export type FeedbackDialogProps = FeedbackDialogSingleProps | FeedbackDialogMult
|
|
|
225
236
|
* FeedbackMultipleSubmission}) instead of `attachment`. Opt-in, so a caller typed
|
|
226
237
|
* against the one-file submission keeps compiling and behaving as before.
|
|
227
238
|
*/
|
|
228
|
-
export function FeedbackDialog(props: FeedbackDialogProps) {
|
|
239
|
+
export function FeedbackDialog<C extends string = string>(props: FeedbackDialogProps<C>) {
|
|
229
240
|
const {
|
|
230
241
|
open,
|
|
231
242
|
onClose,
|
|
@@ -251,8 +262,7 @@ export function FeedbackDialog(props: FeedbackDialogProps) {
|
|
|
251
262
|
const [files, setFiles] = useState<File[]>([]);
|
|
252
263
|
const isMobile = usePhoneLayout();
|
|
253
264
|
const noticeId = useId();
|
|
254
|
-
const hasNotice =
|
|
255
|
-
publicNotice !== undefined && publicNotice !== null && publicNotice !== false && publicNotice !== "";
|
|
265
|
+
const hasNotice = hasContent(publicNotice);
|
|
256
266
|
const labels = useKitLabels("feedbackDialog", DEFAULT_FEEDBACK_DIALOG_LABELS, labelsProp);
|
|
257
267
|
const attachmentText = useKitLabels("feedbackAttachment", DEFAULT_FEEDBACK_ATTACHMENT_LABELS, labelsProp);
|
|
258
268
|
// Under `multiple` the heading is `attachmentList` — a screenshot AND photos — which
|
|
@@ -296,7 +306,8 @@ export function FeedbackDialog(props: FeedbackDialogProps) {
|
|
|
296
306
|
if (!open) return null;
|
|
297
307
|
|
|
298
308
|
const categoryField = (
|
|
299
|
-
|
|
309
|
+
// The select offers exactly `categories`' values, so what it answers is one of them.
|
|
310
|
+
<Select label={labels.category} value={category} onChange={(e) => onCategoryChange(e.target.value as C)}>
|
|
300
311
|
{categories.map((c) => (
|
|
301
312
|
<option key={c.value} value={c.value}>
|
|
302
313
|
{c.label}
|
|
@@ -0,0 +1,20 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* A page's mutation, run once (refactor audit 2026-10-30, FLW-3): TanStack Query's
|
|
3
|
+
* `mutateAsync`, or any `(patch) => Promise` that resolves once the PATCH has landed.
|
|
4
|
+
*
|
|
5
|
+
* The parts took TanStack Query's `mutate` with a per-call `onSuccess` until 0.53
|
|
6
|
+
* (deprecated in 0.52). TanStack v5 calls per-call callbacks for the LATEST `mutate()` on
|
|
7
|
+
* an observer only — it overwrites the options and detaches from the earlier mutation —
|
|
8
|
+
* so a second change sent before the first PATCH answered (another swipe, another pill,
|
|
9
|
+
* the Undo itself) lost the first change's Undo toast, and the detail's editor stayed
|
|
10
|
+
* open. The promise `mutateAsync` returns settles for every call, whatever the observer
|
|
11
|
+
* does next.
|
|
12
|
+
*
|
|
13
|
+
* A rejected promise is the mutation's own to report (its `onError`), so it is caught here
|
|
14
|
+
* and nothing more happens.
|
|
15
|
+
*
|
|
16
|
+
* @internal Not part of `/feedback` or the barrel.
|
|
17
|
+
*/
|
|
18
|
+
export function runMutation<P>(call: (patch: P) => Promise<unknown>, patch: P, landed: () => void): void {
|
|
19
|
+
call(patch).then(landed, () => undefined);
|
|
20
|
+
}
|
|
@@ -0,0 +1,90 @@
|
|
|
1
|
+
import type { PathPattern } from "../landing/routing";
|
|
2
|
+
import { matchesPathPattern, routerPathname } from "../lib/path-pattern";
|
|
3
|
+
import type { FeedbackContext } from "./feedback-record";
|
|
4
|
+
|
|
5
|
+
/**
|
|
6
|
+
* The page a report was filed on, and which of it the feedback parts link (refactor audit
|
|
7
|
+
* 2026-10-30, FLW-7).
|
|
8
|
+
*
|
|
9
|
+
* The page comes from the REPORTER's client context: its origin is always this app's
|
|
10
|
+
* (only the path is ever linked), but its path and query are whatever the row says. A
|
|
11
|
+
* signed-in user could file a report whose link takes the admin to a route that acts on
|
|
12
|
+
* load — keksdose's `/join?token=` accepts an invitation through `AcceptInvitation`,
|
|
13
|
+
* kastlan's and Kurvenschmiede's `/register?invite=` likewise.
|
|
14
|
+
*
|
|
15
|
+
* **Only the PATH is linked** (0.52 code review, this file). The tokens and the forward
|
|
16
|
+
* targets travel in the query: a guard on the path alone let `/login?next=%2Fjoin%3Ftoken%3D…`
|
|
17
|
+
* through as a link, and `RedirectIfAuthed` sent the signed-in admin on to the invitation —
|
|
18
|
+
* as `/forgot-password`, `/demo` and `/welcome` would, and whatever forwarder an app adds
|
|
19
|
+
* next (`?returnTo=`, a share target). No list of forwarders can know them all; a link
|
|
20
|
+
* without a query reaches none. The query and hash are shown as text beside it, and "Copy
|
|
21
|
+
* URL" copies the whole address, for whoever wants that exact state and opens it knowingly.
|
|
22
|
+
*
|
|
23
|
+
* **A one-shot PATH is not linked at all** — the kit's `/join`, `/register`,
|
|
24
|
+
* `/verify-email`, `/reset-password` (`/reset-password/<token>` carries it in the path),
|
|
25
|
+
* and the app's `pageLinkExclude` on top: shown as text with Copy.
|
|
26
|
+
*
|
|
27
|
+
* @internal Not part of `/feedback` or the barrel.
|
|
28
|
+
*/
|
|
29
|
+
|
|
30
|
+
/** The kit's one-shot routes: the invitation accepts and the two token pages. */
|
|
31
|
+
export const FEEDBACK_ONE_SHOT_PAGES: readonly PathPattern[] = Object.freeze([
|
|
32
|
+
"/join",
|
|
33
|
+
"/register",
|
|
34
|
+
"/verify-email",
|
|
35
|
+
"/reset-password",
|
|
36
|
+
]);
|
|
37
|
+
|
|
38
|
+
/** Whether `href` (a path, with or without its query) names a one-shot route — the kit's,
|
|
39
|
+
* or one of the app's `exclude` on top. Read as the ROUTER reads it, decoded and
|
|
40
|
+
* case-insensitive: `/Join?token=` and `/j%6Fin?token=` render `/join` too (0.52 code
|
|
41
|
+
* review, this file). */
|
|
42
|
+
export function isOneShotPage(href: string, exclude: readonly PathPattern[] = []): boolean {
|
|
43
|
+
const pathname = routerPathname(href);
|
|
44
|
+
const named = (pattern: PathPattern) => matchesPathPattern(pathname, pattern);
|
|
45
|
+
return FEEDBACK_ONE_SHOT_PAGES.some(named) || exclude.some(named);
|
|
46
|
+
}
|
|
47
|
+
|
|
48
|
+
/** The page a report was filed on, read once — the URL cell and the detail each parsed it
|
|
49
|
+
* three times, once per part (0.52 code review, feedback-table.tsx: 810 `URL`s per render
|
|
50
|
+
* of a 270-row inbox, for one column). */
|
|
51
|
+
export interface FeedbackPage {
|
|
52
|
+
/** The path: what the URL column shows, and the only part ever linked. */
|
|
53
|
+
path: string;
|
|
54
|
+
/** Path + query + hash: the page as the reporter had it (keksdose `localHref`: the query
|
|
55
|
+
* and hash carry the state, `?tab=import`, a drill-down) — shown, never followed. */
|
|
56
|
+
href: string;
|
|
57
|
+
/** What "Copy URL" copies: the FULL `context.url` as the reporter's browser had it —
|
|
58
|
+
* origin included, the one part that says which copy of the app it was (feedback
|
|
59
|
+
* #278) — else `context.route`. */
|
|
60
|
+
url: string;
|
|
61
|
+
}
|
|
62
|
+
|
|
63
|
+
/** Collapses a leading `//` run: `/\/\/evil.example/` as a path would be a
|
|
64
|
+
* protocol-relative link off the app. */
|
|
65
|
+
const localPath = (pathname: string) => pathname.replace(/^\/{2,}/, "/");
|
|
66
|
+
|
|
67
|
+
/** `context.url`, else `context.route`, parsed — or null when neither is set or the value
|
|
68
|
+
* is no http(s) address or path (a `javascript:` value is not a page). */
|
|
69
|
+
export function feedbackPage(context: FeedbackContext | null | undefined): FeedbackPage | null {
|
|
70
|
+
const raw = (context?.url || context?.route || "").trim();
|
|
71
|
+
if (!raw) return null;
|
|
72
|
+
let url: URL;
|
|
73
|
+
try {
|
|
74
|
+
// A base, so a PATH-ONLY value parses too: Kurvenschmiede backfills its old rows
|
|
75
|
+
// with `url = page_path + search` (§3.2), and keksdose's `new URL(raw)` threw on
|
|
76
|
+
// those and dropped the section.
|
|
77
|
+
url = new URL(raw, "http://localhost");
|
|
78
|
+
} catch {
|
|
79
|
+
return null;
|
|
80
|
+
}
|
|
81
|
+
if (url.protocol !== "http:" && url.protocol !== "https:") return null;
|
|
82
|
+
const path = localPath(url.pathname);
|
|
83
|
+
return { path, href: `${path}${url.search}${url.hash}`, url: raw };
|
|
84
|
+
}
|
|
85
|
+
|
|
86
|
+
/** Where a click on the page goes: its path, or `null` — show it as text — when that path
|
|
87
|
+
* is one-shot. */
|
|
88
|
+
export function feedbackPageLinkTarget(page: FeedbackPage, exclude: readonly PathPattern[] = []): string | null {
|
|
89
|
+
return isOneShotPage(page.path, exclude) ? null : page.path;
|
|
90
|
+
}
|
|
@@ -143,8 +143,9 @@ function PublicPager({
|
|
|
143
143
|
/* ── The list ─────────────────────────────────────────────────────────────── */
|
|
144
144
|
|
|
145
145
|
export interface FeedbackPublicListProps<T extends FeedbackPublicListItem = FeedbackPublicListItem> {
|
|
146
|
-
/** `GET /feedback/public?sort=&q=` — the server's page, in the server's order.
|
|
147
|
-
|
|
146
|
+
/** `GET /feedback/public?sort=&q=` — the server's page, in the server's order.
|
|
147
|
+
* `readonly` since 0.52 (refactor audit 2026-10-30, API-7): the list never changes it. */
|
|
148
|
+
rows: readonly T[];
|
|
148
149
|
/** How many the query has in all — the line beside the sort. Left out, no line. */
|
|
149
150
|
total?: number;
|
|
150
151
|
/** The server sorts (§9.6): the toggle only says which way. */
|
|
@@ -169,7 +170,10 @@ export interface FeedbackPublicListProps<T extends FeedbackPublicListItem = Feed
|
|
|
169
170
|
/** The opened row's id, when the app keeps it (a `?row=` param). Left out, the list
|
|
170
171
|
* keeps it itself. */
|
|
171
172
|
openId?: number | null;
|
|
172
|
-
|
|
173
|
+
/** 0.52: a row was opened (its id) or closed (`null`) — `openId`'s pair. Named for
|
|
174
|
+
* what it carries: every other `onOpenChange` in the kit is a boolean (refactor audit
|
|
175
|
+
* 2026-10-30, API-5). */
|
|
176
|
+
onOpenIdChange?: (id: number | null) => void;
|
|
173
177
|
/**
|
|
174
178
|
* 0.38.1: the opened report when it is NOT on this page — a `?row=` link to an older
|
|
175
179
|
* one (Kurvenschmiede). The app fetches it (`GET /feedback/public/{id}`, a list item's
|
|
@@ -239,7 +243,7 @@ export function FeedbackPublicList<T extends FeedbackPublicListItem = FeedbackPu
|
|
|
239
243
|
onVote,
|
|
240
244
|
loading = false,
|
|
241
245
|
openId: openIdProp,
|
|
242
|
-
|
|
246
|
+
onOpenIdChange,
|
|
243
247
|
openRow,
|
|
244
248
|
page: pageIndex = 0,
|
|
245
249
|
hasMore = false,
|
|
@@ -259,12 +263,14 @@ export function FeedbackPublicList<T extends FeedbackPublicListItem = FeedbackPu
|
|
|
259
263
|
const openId = openIdProp !== undefined ? openIdProp : ownOpenId;
|
|
260
264
|
const setOpen = (id: number | null) => {
|
|
261
265
|
if (openIdProp === undefined) setOwnOpenId(id);
|
|
262
|
-
|
|
266
|
+
onOpenIdChange?.(id);
|
|
263
267
|
};
|
|
264
268
|
// A `?row=` report from another page: first, while it is the open one, and only when
|
|
265
269
|
// the page does not have it itself.
|
|
266
|
-
|
|
267
|
-
|
|
270
|
+
// `as T[]`: DataTable's `rows` is still mutable in its type (API-7), and never mutated.
|
|
271
|
+
const shownRows = (
|
|
272
|
+
openRow && openId === openRow.id && !rows.some((row) => row.id === openRow.id) ? [openRow, ...rows] : rows
|
|
273
|
+
) as T[];
|
|
268
274
|
|
|
269
275
|
const columns = useMemo<DataTableColumn<T>[]>(
|
|
270
276
|
() => [
|
|
@@ -4,9 +4,9 @@ import { BellOff } from "lucide-react";
|
|
|
4
4
|
import { Select } from "../components/select";
|
|
5
5
|
import type { CommitScope } from "../components/write-lock";
|
|
6
6
|
import type { AuthedFetcher } from "../hooks/use-authed-src";
|
|
7
|
-
import { useKitLabels,
|
|
7
|
+
import { useKitLabels, type LabelOverride } from "../i18n/kit-labels";
|
|
8
8
|
import { cn } from "../lib/cn";
|
|
9
|
-
import {
|
|
9
|
+
import { useDayFormatter } from "../lib/day-format";
|
|
10
10
|
import { FeedbackStatusBadge, selectableFeedbackStatuses, type FeedbackStatus } from "./feedback-inbox";
|
|
11
11
|
import { useFeedbackStatusLabels } from "./feedback-labels";
|
|
12
12
|
import type { FeedbackReply } from "./feedback-public-types";
|
|
@@ -77,10 +77,15 @@ export function feedbackReplyNudge(row: {
|
|
|
77
77
|
|
|
78
78
|
/* ── The timeline ─────────────────────────────────────────────────────────── */
|
|
79
79
|
|
|
80
|
+
/** A reply's time, the kit's own: the medium date and the short clock. */
|
|
81
|
+
const REPLY_TIME_STYLE: Intl.DateTimeFormatOptions = { dateStyle: "medium", timeStyle: "short" };
|
|
82
|
+
|
|
80
83
|
export interface FeedbackReplyTimelineProps {
|
|
81
84
|
/** Oldest first, as the server sends them. */
|
|
82
85
|
replies: readonly FeedbackReply[];
|
|
83
|
-
/** How a reply's time reads. Default: the
|
|
86
|
+
/** How a reply's time reads. Default (0.52): the `<UiKitProvider formatDate>`'s day
|
|
87
|
+
* with the language's clock when the app set one, else the date and time in the
|
|
88
|
+
* provider's locale and time zone. */
|
|
84
89
|
renderDate?: (iso: string) => string;
|
|
85
90
|
/** Tag bodies and names `data-private` (a host's screen-share blur). Default true. */
|
|
86
91
|
redact?: boolean;
|
|
@@ -142,13 +147,15 @@ export function FeedbackReplyTimeline({
|
|
|
142
147
|
}: FeedbackReplyTimelineProps) {
|
|
143
148
|
const labels = useFeedbackRepliesLabels(labelsProp);
|
|
144
149
|
const anonymous = useKitLabels("feedbackPublic", DEFAULT_FEEDBACK_PUBLIC_LABELS).anonymous;
|
|
145
|
-
|
|
150
|
+
// `renderDate` when it answers, else the provider's `formatDate` for the day with the
|
|
151
|
+
// language's clock, else the kit's date and time in the provider's locale and time zone
|
|
152
|
+
// (0.52, refactor audit 2026-10-30, DUP-2: the provider never reached this one).
|
|
153
|
+
const day = useDayFormatter<string>(renderDate);
|
|
146
154
|
const priv = redact ? "" : undefined;
|
|
147
155
|
if (replies.length === 0) {
|
|
148
156
|
return <p className={cn("text-sm text-placeholder", className)}>{labels.empty}</p>;
|
|
149
157
|
}
|
|
150
|
-
const dateText = (iso: string) =>
|
|
151
|
-
renderDate ? renderDate(iso) : formatDate(iso, { dateStyle: "medium", timeStyle: "short" }, { locale });
|
|
158
|
+
const dateText = (iso: string) => day(iso, { time: true, style: REPLY_TIME_STYLE });
|
|
152
159
|
return (
|
|
153
160
|
<ol aria-label={labels.replies} className={cn("space-y-3 border-s-2 border-subtle ps-3", className)}>
|
|
154
161
|
{replies.map((reply) => {
|
|
@@ -20,9 +20,6 @@ export const DEFAULT_FEEDBACK_DETAIL_LABELS: FeedbackDetailLabels = {
|
|
|
20
20
|
outcome: "Outcome",
|
|
21
21
|
replies: "Replies",
|
|
22
22
|
resolvedAt: (date) => `Resolved: ${date}`,
|
|
23
|
-
outcomeAdd: "Add outcome",
|
|
24
|
-
outcomeUpdate: "Update",
|
|
25
|
-
outcomePlaceholder: "What was done, decided, or why this won't be addressed.",
|
|
26
23
|
rework: "Rework",
|
|
27
24
|
reworkTitle: "Send for rework",
|
|
28
25
|
reworkSend: "Send rework",
|