@eifi1/ui-kit 0.54.0 → 0.55.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 +90 -76
- package/dist/admin/plan-change.js +2 -2
- package/dist/admin/plan-change.js.map +1 -1
- package/dist/admin/user-roster.d.ts +6 -0
- package/dist/admin/user-roster.js +4 -0
- package/dist/admin/user-roster.js.map +1 -1
- package/dist/billing/billing-labels.d.ts +26 -0
- package/dist/billing/billing-labels.js +9 -0
- package/dist/billing/billing-labels.js.map +1 -1
- package/dist/billing/subscription-standing.d.ts +61 -0
- package/dist/billing/subscription-standing.js +51 -0
- package/dist/billing/subscription-standing.js.map +1 -0
- package/dist/billing/usage-meter.d.ts +52 -0
- package/dist/billing/usage-meter.js +52 -0
- package/dist/billing/usage-meter.js.map +1 -0
- package/dist/chart.d.ts +1 -0
- package/dist/chart.js +4 -0
- package/dist/chart.js.map +1 -1
- package/dist/components/alert-banner.js +2 -3
- package/dist/components/alert-banner.js.map +1 -1
- package/dist/components/amount-input.js +3 -15
- package/dist/components/amount-input.js.map +1 -1
- package/dist/components/autocomplete.js +2 -2
- package/dist/components/autocomplete.js.map +1 -1
- package/dist/components/bulk-action-bar.js +2 -1
- package/dist/components/bulk-action-bar.js.map +1 -1
- package/dist/components/button.d.ts +35 -1
- package/dist/components/button.js +5 -9
- package/dist/components/button.js.map +1 -1
- package/dist/components/calendar-heatmap.js +2 -2
- package/dist/components/calendar-heatmap.js.map +1 -1
- package/dist/components/camera-button.d.ts +89 -0
- package/dist/components/camera-button.js +122 -0
- package/dist/components/camera-button.js.map +1 -0
- package/dist/components/camera-capture.d.ts +66 -0
- package/dist/components/camera-capture.js +190 -0
- package/dist/components/camera-capture.js.map +1 -0
- package/dist/components/camera-labels.d.ts +20 -0
- package/dist/components/camera-labels.js +15 -0
- package/dist/components/camera-labels.js.map +1 -0
- package/dist/components/chart-edge.d.ts +9 -0
- package/dist/components/chart-edge.js +14 -3
- package/dist/components/chart-edge.js.map +1 -1
- package/dist/components/chart-zoom-core.js +34 -29
- package/dist/components/chart-zoom-core.js.map +1 -1
- package/dist/components/checkbox-group.js +1 -1
- package/dist/components/checkbox-group.js.map +1 -1
- package/dist/components/combobox-core.js +3 -2
- package/dist/components/combobox-core.js.map +1 -1
- package/dist/components/combobox.js +2 -2
- package/dist/components/combobox.js.map +1 -1
- package/dist/components/consent-again-notice-labels.d.ts +25 -0
- package/dist/components/consent-again-notice-labels.js +15 -0
- package/dist/components/consent-again-notice-labels.js.map +1 -0
- package/dist/components/consent-again-notice.d.ts +85 -0
- package/dist/components/consent-again-notice.js +94 -0
- package/dist/components/consent-again-notice.js.map +1 -0
- package/dist/components/country-select.js +2 -7
- package/dist/components/country-select.js.map +1 -1
- package/dist/components/currency-select.js +2 -2
- package/dist/components/currency-select.js.map +1 -1
- package/dist/components/danger-confirm.js +2 -2
- package/dist/components/danger-confirm.js.map +1 -1
- package/dist/components/data-table-column-settings.js +2 -2
- package/dist/components/data-table-column-settings.js.map +1 -1
- package/dist/components/data-table-fit.js.map +1 -1
- package/dist/components/data-table-virtual.js +13 -3
- package/dist/components/data-table-virtual.js.map +1 -1
- package/dist/components/date-field.js +2 -2
- package/dist/components/date-field.js.map +1 -1
- package/dist/components/date-picker.js +2 -2
- package/dist/components/date-picker.js.map +1 -1
- package/dist/components/date-range-picker.js +2 -6
- package/dist/components/date-range-picker.js.map +1 -1
- package/dist/components/dialog-frame.d.ts +3 -1
- package/dist/components/dialog-frame.js.map +1 -1
- package/dist/components/dropdown.js +7 -3
- package/dist/components/dropdown.js.map +1 -1
- package/dist/components/entity-combobox.js +2 -2
- package/dist/components/entity-combobox.js.map +1 -1
- package/dist/components/field-parts.d.ts +108 -6
- package/dist/components/field-parts.js +59 -6
- package/dist/components/field-parts.js.map +1 -1
- package/dist/components/field-suggestion-labels.d.ts +2 -0
- package/dist/components/field-suggestion-labels.js +10 -0
- package/dist/components/field-suggestion-labels.js.map +1 -0
- package/dist/components/field.js +1 -1
- package/dist/components/field.js.map +1 -1
- package/dist/components/file-button.d.ts +1 -1
- package/dist/components/file-button.js.map +1 -1
- package/dist/components/floating-panel.d.ts +7 -6
- package/dist/components/floating-panel.js +3 -17
- package/dist/components/floating-panel.js.map +1 -1
- package/dist/components/form-actions.d.ts +3 -2
- package/dist/components/form-actions.js.map +1 -1
- package/dist/components/hover-menu.js +3 -2
- package/dist/components/hover-menu.js.map +1 -1
- package/dist/components/icon-button.d.ts +23 -5
- package/dist/components/icon-button.js +6 -8
- package/dist/components/icon-button.js.map +1 -1
- package/dist/components/inline-confirm.js +2 -1
- package/dist/components/inline-confirm.js.map +1 -1
- package/dist/components/inline-entity-combobox.js +2 -2
- package/dist/components/inline-entity-combobox.js.map +1 -1
- package/dist/components/input.js +2 -2
- package/dist/components/input.js.map +1 -1
- package/dist/components/jump-calendar.js +3 -3
- package/dist/components/jump-calendar.js.map +1 -1
- package/dist/components/legal.d.ts +13 -1
- package/dist/components/legal.js +12 -0
- package/dist/components/legal.js.map +1 -1
- package/dist/components/legended-series-chart.d.ts +80 -0
- package/dist/components/legended-series-chart.js +70 -0
- package/dist/components/legended-series-chart.js.map +1 -0
- package/dist/components/lightbox.js +2 -1
- package/dist/components/lightbox.js.map +1 -1
- package/dist/components/mini-calendar.js +13 -5
- package/dist/components/mini-calendar.js.map +1 -1
- package/dist/components/modal.d.ts +23 -2
- package/dist/components/modal.js +24 -6
- package/dist/components/modal.js.map +1 -1
- package/dist/components/month-picker.d.ts +1 -1
- package/dist/components/month-picker.js +6 -6
- package/dist/components/month-picker.js.map +1 -1
- package/dist/components/multi-entity-combobox.js +2 -2
- package/dist/components/multi-entity-combobox.js.map +1 -1
- package/dist/components/multi-select.js +2 -6
- package/dist/components/multi-select.js.map +1 -1
- package/dist/components/number-input.js +2 -2
- package/dist/components/number-input.js.map +1 -1
- package/dist/components/page-header-layout.d.ts +18 -0
- package/dist/components/page-header-layout.js +23 -0
- package/dist/components/page-header-layout.js.map +1 -0
- package/dist/components/page-header-skeleton.d.ts +41 -0
- package/dist/components/page-header-skeleton.js +52 -0
- package/dist/components/page-header-skeleton.js.map +1 -0
- package/dist/components/page-header.js +4 -17
- package/dist/components/page-header.js.map +1 -1
- package/dist/components/popover.js +7 -2
- package/dist/components/popover.js.map +1 -1
- package/dist/components/release-notes-labels.d.ts +16 -0
- package/dist/components/release-notes-labels.js +18 -0
- package/dist/components/release-notes-labels.js.map +1 -0
- package/dist/components/release-notes.d.ts +65 -0
- package/dist/components/release-notes.js +65 -0
- package/dist/components/release-notes.js.map +1 -0
- package/dist/components/select.js +2 -2
- package/dist/components/select.js.map +1 -1
- package/dist/components/series-chart-labels.d.ts +9 -0
- package/dist/components/series-chart-labels.js +3 -1
- package/dist/components/series-chart-labels.js.map +1 -1
- package/dist/components/series-chart.d.ts +5 -0
- package/dist/components/series-chart.js +89 -36
- package/dist/components/series-chart.js.map +1 -1
- package/dist/components/toggle-group.js +3 -2
- package/dist/components/toggle-group.js.map +1 -1
- package/dist/components/treemap-layout.js.map +1 -1
- package/dist/components/treemap.d.ts +17 -15
- package/dist/components/treemap.js +167 -85
- package/dist/components/treemap.js.map +1 -1
- package/dist/eslint/index.js +1 -1
- package/dist/eslint/role-utilities.d.ts +2 -2
- package/dist/eslint/role-utilities.js.map +1 -1
- package/dist/feedback/feedback-inbox-page.d.ts +260 -0
- package/dist/feedback/feedback-inbox-page.js +207 -0
- package/dist/feedback/feedback-inbox-page.js.map +1 -0
- package/dist/feedback/feedback-vocabulary.js +2 -2
- package/dist/feedback/feedback-vocabulary.js.map +1 -1
- package/dist/feedback.d.ts +1 -0
- package/dist/feedback.js +6 -0
- package/dist/feedback.js.map +1 -1
- package/dist/hooks/use-debounce.d.ts +32 -5
- package/dist/hooks/use-debounce.js +6 -5
- package/dist/hooks/use-debounce.js.map +1 -1
- package/dist/hooks/use-file-picker.d.ts +3 -1
- package/dist/hooks/use-file-picker.js.map +1 -1
- package/dist/hooks/use-focus-trap.d.ts +19 -3
- package/dist/hooks/use-focus-trap.js +15 -5
- package/dist/hooks/use-focus-trap.js.map +1 -1
- package/dist/hooks/use-has-camera.d.ts +36 -0
- package/dist/hooks/use-has-camera.js +53 -0
- package/dist/hooks/use-has-camera.js.map +1 -0
- package/dist/hooks/use-hotkey.js +1 -10
- package/dist/hooks/use-hotkey.js.map +1 -1
- package/dist/hooks/use-overlay-history.d.ts +6 -1
- package/dist/hooks/use-overlay-history.js +10 -2
- package/dist/hooks/use-overlay-history.js.map +1 -1
- package/dist/i18n/defaults.js +11 -1
- package/dist/i18n/defaults.js.map +1 -1
- package/dist/i18n/german.js +75 -3
- package/dist/i18n/german.js.map +1 -1
- package/dist/i18n/kit-labels.d.ts +20 -0
- package/dist/i18n/kit-labels.js.map +1 -1
- package/dist/i18n/locales/en.js +92 -4
- package/dist/i18n/locales/en.js.map +3 -3
- package/dist/i18n/locales/es.js +71 -3
- package/dist/i18n/locales/es.js.map +1 -1
- package/dist/i18n/locales/fr.js +72 -2
- package/dist/i18n/locales/fr.js.map +1 -1
- package/dist/i18n/locales/hu.js +74 -3
- package/dist/i18n/locales/hu.js.map +1 -1
- package/dist/i18n/locales/it.js +74 -3
- package/dist/i18n/locales/it.js.map +1 -1
- package/dist/i18n/locales/zh.js +71 -3
- package/dist/i18n/locales/zh.js.map +1 -1
- package/dist/i18n/review.js +22 -1
- package/dist/i18n/review.js.map +1 -1
- package/dist/index.d.ts +24 -5
- package/dist/index.js +35 -1
- package/dist/index.js.map +1 -1
- package/dist/landing/landing-labels.d.ts +8 -0
- package/dist/landing/landing-labels.js +2 -1
- package/dist/landing/landing-labels.js.map +1 -1
- package/dist/lib/changelog.d.ts +130 -0
- package/dist/lib/changelog.js +137 -0
- package/dist/lib/changelog.js.map +1 -0
- package/dist/lib/clipboard-minus.js +2 -2
- package/dist/lib/clipboard-minus.js.map +1 -1
- package/dist/lib/dates.d.ts +29 -3
- package/dist/lib/dates.js +41 -12
- package/dist/lib/dates.js.map +1 -1
- package/dist/lib/editable-content.d.ts +33 -0
- package/dist/lib/editable-content.js +15 -0
- package/dist/lib/editable-content.js.map +1 -0
- package/dist/lib/focus-left.d.ts +47 -1
- package/dist/lib/focus-left.js +11 -2
- package/dist/lib/focus-left.js.map +1 -1
- package/dist/lib/server-wake.d.ts +49 -9
- package/dist/lib/server-wake.js +25 -14
- package/dist/lib/server-wake.js.map +1 -1
- package/dist/lib/session-refresh.d.ts +53 -0
- package/dist/lib/session-refresh.js +27 -1
- package/dist/lib/session-refresh.js.map +1 -1
- package/dist/rhf/fields.js +3 -3
- package/dist/rhf/fields.js.map +1 -1
- package/dist/shell/app-shell.d.ts +25 -1
- package/dist/shell/app-shell.js +3 -1
- package/dist/shell/app-shell.js.map +1 -1
- package/dist/shell/dev-menu.d.ts +3 -0
- package/dist/shell/dev-menu.js +4 -2
- package/dist/shell/dev-menu.js.map +1 -1
- package/dist/shell/held-changes-banner-labels.d.ts +23 -0
- package/dist/shell/held-changes-banner-labels.js +14 -0
- package/dist/shell/held-changes-banner-labels.js.map +1 -0
- package/dist/shell/held-changes-banner.d.ts +75 -0
- package/dist/shell/held-changes-banner.js +106 -0
- package/dist/shell/held-changes-banner.js.map +1 -0
- package/dist/shell/sync-status-indicator.d.ts +27 -12
- package/dist/shell/sync-status-indicator.js +13 -4
- package/dist/shell/sync-status-indicator.js.map +1 -1
- package/dist/shell/top-bar-parts-labels.d.ts +5 -0
- package/dist/shell/top-bar-parts-labels.js +3 -1
- package/dist/shell/top-bar-parts-labels.js.map +1 -1
- package/dist/shell.d.ts +2 -0
- package/dist/shell.js +3 -0
- package/dist/shell.js.map +1 -1
- package/dist/sync/engine.d.ts +11 -2
- package/dist/sync/engine.js +13 -5
- package/dist/sync/engine.js.map +1 -1
- package/dist/sync/hooks.d.ts +3 -2
- package/dist/sync/hooks.js +4 -2
- package/dist/sync/hooks.js.map +1 -1
- package/dist/testing/css-variables.generated.d.ts +2 -2
- package/dist/testing/css-variables.generated.js +1 -1
- package/dist/testing/css-variables.generated.js.map +1 -1
- package/dist/theme/chart-palette.d.ts +18 -0
- package/dist/theme/chart-palette.js +17 -1
- package/dist/theme/chart-palette.js.map +1 -1
- package/dist/theme/contrast-tokens.d.ts +3 -3
- package/dist/theme/contrast-tokens.js.map +1 -1
- package/dist/theme/contrast.d.ts +4 -4
- package/dist/theme/contrast.js.map +1 -1
- package/dist/tour/tour-overlay.js +2 -1
- package/dist/tour/tour-overlay.js.map +1 -1
- package/package.json +5 -9
- package/tokens.css +19 -54
- package/src/account/account-parts.ts +0 -47
- package/src/account/account-settings-labels.ts +0 -240
- package/src/account/account-settings.tsx +0 -698
- package/src/account/data-export-setting-labels.ts +0 -20
- package/src/account/data-export-setting.tsx +0 -200
- package/src/account/delete-account-setting-labels.ts +0 -33
- package/src/account/delete-account-setting.tsx +0 -342
- package/src/account/email-change-setting-labels.ts +0 -31
- package/src/account/email-change-setting.tsx +0 -443
- package/src/account/passkeys-setting.tsx +0 -445
- package/src/account/sessions-setting-labels.ts +0 -24
- package/src/account/sessions-setting.tsx +0 -283
- package/src/admin/admin-action-confirm-labels.ts +0 -19
- package/src/admin/admin-action-confirm.tsx +0 -509
- package/src/admin/admin-action-log-labels.ts +0 -83
- package/src/admin/admin-action-log.tsx +0 -464
- package/src/admin/admin-area-labels.ts +0 -114
- package/src/admin/admin-forbidden.tsx +0 -75
- package/src/admin/admin-overview.tsx +0 -258
- package/src/admin/admin-parts.ts +0 -68
- package/src/admin/admin-sections.tsx +0 -208
- package/src/admin/admin-tool-links.tsx +0 -90
- package/src/admin/invitations-panel-labels.ts +0 -31
- package/src/admin/invitations-panel.tsx +0 -516
- package/src/admin/mail-test-card-labels.ts +0 -19
- package/src/admin/mail-test-card.tsx +0 -189
- package/src/admin/plan-change-labels.ts +0 -5
- package/src/admin/plan-change.tsx +0 -474
- package/src/admin/reviewer-scope-editor-labels.ts +0 -16
- package/src/admin/reviewer-scope-editor.tsx +0 -224
- package/src/admin/role-select-labels.ts +0 -16
- package/src/admin/role-select.tsx +0 -282
- package/src/admin/transfer-ownership-dialog-labels.ts +0 -20
- package/src/admin/transfer-ownership-dialog.tsx +0 -162
- package/src/admin/user-roster-labels.ts +0 -17
- package/src/admin/user-roster.tsx +0 -559
- package/src/auth/accept-invitation-labels.ts +0 -21
- package/src/auth/accept-invitation.tsx +0 -210
- package/src/auth/auth-errors-labels.ts +0 -23
- package/src/auth/auth-errors.ts +0 -439
- package/src/auth/complete-name-dialog-labels.ts +0 -16
- package/src/auth/complete-name-dialog.tsx +0 -253
- package/src/auth/email-tag.ts +0 -75
- package/src/auth/forgot-password-form-labels.ts +0 -20
- package/src/auth/forgot-password-form.tsx +0 -221
- package/src/auth/form-rules.ts +0 -40
- package/src/auth/new-password-fields.tsx +0 -85
- package/src/auth/not-found-page-labels.ts +0 -12
- package/src/auth/not-found-page.tsx +0 -95
- package/src/auth/register-form-labels.ts +0 -31
- package/src/auth/register-form.tsx +0 -456
- package/src/auth/reset-password-form-labels.ts +0 -27
- package/src/auth/reset-password-form.tsx +0 -341
- package/src/auth/sign-in-form-labels.ts +0 -44
- package/src/auth/sign-in-form.tsx +0 -858
- package/src/auth/status-parts.tsx +0 -132
- package/src/auth/verify-email-labels.ts +0 -26
- package/src/auth/verify-email.tsx +0 -445
- package/src/billing/billing-banner.tsx +0 -258
- package/src/billing/billing-labels.ts +0 -381
- package/src/billing/billing-lock.ts +0 -108
- package/src/billing/billing-overview.ts +0 -157
- package/src/billing/billing-standing.ts +0 -80
- package/src/billing/cancel-request.ts +0 -97
- package/src/billing/cancel-subscription.tsx +0 -98
- package/src/billing/checkout-processing.ts +0 -394
- package/src/billing/checkout-return.ts +0 -90
- package/src/billing/pay-page.ts +0 -330
- package/src/billing/plan-card.tsx +0 -562
- package/src/billing/plan-change-labels.ts +0 -66
- package/src/billing/plan-limit-notice.tsx +0 -148
- package/src/billing/plan-limit-toast.tsx +0 -90
- package/src/billing/plan-limit.ts +0 -52
- package/src/billing/plan-price.ts +0 -98
- package/src/billing/plan-switch.tsx +0 -216
- package/src/billing/provider-page.ts +0 -84
- package/src/billing/subscription-actions.tsx +0 -247
- package/src/billing/subscription-status-chip.tsx +0 -95
- package/src/chart.ts +0 -103
- package/src/components/account-chips-labels.ts +0 -16
- package/src/components/account-chips.tsx +0 -474
- package/src/components/alert-banner.tsx +0 -670
- package/src/components/amount-input.tsx +0 -816
- package/src/components/appearance-labels.ts +0 -63
- package/src/components/authed-image-labels.ts +0 -11
- package/src/components/authed-image.tsx +0 -209
- package/src/components/autocomplete.tsx +0 -645
- package/src/components/breadcrumbs-labels.ts +0 -10
- package/src/components/breadcrumbs.tsx +0 -205
- package/src/components/bulk-action-bar-labels.ts +0 -11
- package/src/components/bulk-action-bar.tsx +0 -443
- package/src/components/button-group.tsx +0 -223
- package/src/components/button-look.ts +0 -256
- package/src/components/button.tsx +0 -339
- package/src/components/calculator.tsx +0 -341
- package/src/components/calendar-heatmap-labels.ts +0 -15
- package/src/components/calendar-heatmap.tsx +0 -600
- package/src/components/card.tsx +0 -377
- package/src/components/chart-edge.ts +0 -106
- package/src/components/chart-figure.tsx +0 -35
- package/src/components/chart-height.ts +0 -30
- package/src/components/chart-zoom-core.tsx +0 -627
- package/src/components/chart-zoom.tsx +0 -22
- package/src/components/chart.tsx +0 -554
- package/src/components/checkbox-group.tsx +0 -247
- package/src/components/checkbox.tsx +0 -346
- package/src/components/chip-input.tsx +0 -370
- package/src/components/chip-labels.ts +0 -13
- package/src/components/chip.tsx +0 -843
- package/src/components/choice-card.tsx +0 -544
- package/src/components/column-mapper-labels.ts +0 -38
- package/src/components/column-mapper.tsx +0 -655
- package/src/components/combobox-core.tsx +0 -1321
- package/src/components/combobox-suggestions.tsx +0 -131
- package/src/components/combobox.tsx +0 -716
- package/src/components/confirm-context.ts +0 -7
- package/src/components/confirm-dialog-labels.ts +0 -13
- package/src/components/confirm-dialog.tsx +0 -341
- package/src/components/copy-button-labels.ts +0 -13
- package/src/components/copy-button.tsx +0 -192
- package/src/components/country-select-labels.ts +0 -11
- package/src/components/country-select.tsx +0 -539
- package/src/components/currency-option-list.tsx +0 -188
- package/src/components/currency-select.tsx +0 -343
- package/src/components/danger-confirm-labels.ts +0 -20
- package/src/components/danger-confirm.tsx +0 -987
- package/src/components/data-table-cells.tsx +0 -118
- package/src/components/data-table-column-settings.tsx +0 -198
- package/src/components/data-table-filter-popover.tsx +0 -289
- package/src/components/data-table-filters.ts +0 -315
- package/src/components/data-table-fit.ts +0 -301
- package/src/components/data-table-groups.tsx +0 -288
- package/src/components/data-table-head.tsx +0 -280
- package/src/components/data-table-labels.ts +0 -198
- package/src/components/data-table-leading-row.tsx +0 -58
- package/src/components/data-table-mobile.tsx +0 -1117
- package/src/components/data-table-pagination.tsx +0 -202
- package/src/components/data-table-resize.ts +0 -188
- package/src/components/data-table-row-actions.tsx +0 -302
- package/src/components/data-table-row.tsx +0 -496
- package/src/components/data-table-selection.ts +0 -71
- package/src/components/data-table-shared.tsx +0 -287
- package/src/components/data-table-sort.ts +0 -163
- package/src/components/data-table-virtual.ts +0 -576
- package/src/components/data-table.tsx +0 -2598
- package/src/components/date-field.tsx +0 -684
- package/src/components/date-format-setting.tsx +0 -64
- package/src/components/date-picker.tsx +0 -404
- package/src/components/date-range-picker.tsx +0 -518
- package/src/components/description-list-labels.ts +0 -9
- package/src/components/description-list.tsx +0 -386
- package/src/components/dialog-frame-labels.ts +0 -7
- package/src/components/dialog-frame.tsx +0 -284
- package/src/components/disclosure.tsx +0 -476
- package/src/components/dropdown.tsx +0 -461
- package/src/components/empty-state.tsx +0 -136
- package/src/components/entity-combobox.tsx +0 -422
- package/src/components/error-boundary-labels.ts +0 -20
- package/src/components/error-boundary.tsx +0 -675
- package/src/components/facing-pair.ts +0 -93
- package/src/components/field-base-labels.ts +0 -20
- package/src/components/field-base.tsx +0 -656
- package/src/components/field-parts.tsx +0 -825
- package/src/components/field-strip.tsx +0 -129
- package/src/components/field.tsx +0 -206
- package/src/components/file-button.tsx +0 -295
- package/src/components/file-dropzone.tsx +0 -559
- package/src/components/floating-panel-labels.ts +0 -10
- package/src/components/floating-panel.tsx +0 -828
- package/src/components/focus-ring.ts +0 -16
- package/src/components/form-actions-labels.ts +0 -11
- package/src/components/form-actions.tsx +0 -578
- package/src/components/full-bleed-dialog.tsx +0 -294
- package/src/components/grouped-picker.tsx +0 -184
- package/src/components/help-popover.tsx +0 -117
- package/src/components/hover-menu.tsx +0 -343
- package/src/components/iban-input-labels.ts +0 -14
- package/src/components/iban-input.tsx +0 -236
- package/src/components/icon-button.tsx +0 -959
- package/src/components/icon-picker-labels.ts +0 -13
- package/src/components/icon-picker.tsx +0 -232
- package/src/components/image-grid-labels.ts +0 -11
- package/src/components/image-grid.tsx +0 -202
- package/src/components/inline-confirm.tsx +0 -116
- package/src/components/inline-edit-field-labels.ts +0 -11
- package/src/components/inline-edit-field.tsx +0 -552
- package/src/components/inline-entity-combobox.tsx +0 -849
- package/src/components/input.tsx +0 -394
- package/src/components/jump-calendar.tsx +0 -265
- package/src/components/language-select.tsx +0 -93
- package/src/components/legal-labels.ts +0 -105
- package/src/components/legal-page.tsx +0 -711
- package/src/components/legal.tsx +0 -668
- package/src/components/lightbox-labels.ts +0 -18
- package/src/components/lightbox.tsx +0 -399
- package/src/components/line-items-labels.ts +0 -14
- package/src/components/line-items.tsx +0 -602
- package/src/components/list-labels.ts +0 -12
- package/src/components/list.tsx +0 -870
- package/src/components/loading-state.tsx +0 -78
- package/src/components/measured-grid-labels.ts +0 -25
- package/src/components/measured-grid.tsx +0 -837
- package/src/components/menu-item.tsx +0 -241
- package/src/components/mini-calendar-labels.ts +0 -17
- package/src/components/mini-calendar.tsx +0 -792
- package/src/components/modal.tsx +0 -534
- package/src/components/money-draft.ts +0 -83
- package/src/components/money-field.tsx +0 -76
- package/src/components/month-grid.tsx +0 -229
- package/src/components/month-picker-labels.ts +0 -22
- package/src/components/month-picker.tsx +0 -1087
- package/src/components/multi-entity-combobox.tsx +0 -369
- package/src/components/multi-select.tsx +0 -376
- package/src/components/nav-pills.tsx +0 -198
- package/src/components/number-field.tsx +0 -327
- package/src/components/number-input.tsx +0 -559
- package/src/components/numeric-field.ts +0 -169
- package/src/components/numpad-sheet.tsx +0 -285
- package/src/components/one-time-code-input.tsx +0 -270
- package/src/components/page-contents-labels.ts +0 -9
- package/src/components/page-contents.tsx +0 -282
- package/src/components/page-header-context.ts +0 -8
- package/src/components/page-header.tsx +0 -298
- package/src/components/password-strength-labels.ts +0 -22
- package/src/components/password-strength.tsx +0 -241
- package/src/components/phone-input-labels.ts +0 -10
- package/src/components/phone-input.tsx +0 -282
- package/src/components/picker-sheet.tsx +0 -330
- package/src/components/pie-chart-labels.ts +0 -40
- package/src/components/pie-chart.tsx +0 -480
- package/src/components/popover-labels.ts +0 -14
- package/src/components/popover.tsx +0 -268
- package/src/components/progress-bar-labels.ts +0 -10
- package/src/components/progress-bar.tsx +0 -479
- package/src/components/qr-code.tsx +0 -76
- package/src/components/reauth-dialog-labels.ts +0 -13
- package/src/components/reauth-dialog.tsx +0 -265
- package/src/components/row-actions-labels.ts +0 -12
- package/src/components/row-actions.tsx +0 -795
- package/src/components/scroll-area.tsx +0 -123
- package/src/components/search-field.tsx +0 -192
- package/src/components/select.tsx +0 -294
- package/src/components/separator.tsx +0 -33
- package/src/components/series-chart-axes.ts +0 -342
- package/src/components/series-chart-budget.ts +0 -150
- package/src/components/series-chart-labels.ts +0 -33
- package/src/components/series-chart-thin.ts +0 -180
- package/src/components/series-chart-ticks.ts +0 -194
- package/src/components/series-chart.tsx +0 -1906
- package/src/components/server-wake-labels.ts +0 -11
- package/src/components/server-wake.tsx +0 -129
- package/src/components/settings-fields.tsx +0 -237
- package/src/components/share-card-labels.ts +0 -30
- package/src/components/share-card.tsx +0 -675
- package/src/components/signature-pad-labels.ts +0 -24
- package/src/components/signature-pad.tsx +0 -747
- package/src/components/signed-amount-labels.ts +0 -10
- package/src/components/signed-amount.tsx +0 -336
- package/src/components/skeleton.tsx +0 -80
- package/src/components/slider.tsx +0 -338
- package/src/components/sparkline-labels.ts +0 -14
- package/src/components/sparkline.tsx +0 -322
- package/src/components/spinner.tsx +0 -81
- package/src/components/stat-tile-labels.ts +0 -15
- package/src/components/stat-tile.tsx +0 -754
- package/src/components/status-dot.tsx +0 -170
- package/src/components/swatch-picker-labels.ts +0 -10
- package/src/components/swatch-picker.tsx +0 -283
- package/src/components/swipeable-row.tsx +0 -386
- package/src/components/switch.tsx +0 -273
- package/src/components/table-skeleton.tsx +0 -136
- package/src/components/table.tsx +0 -647
- package/src/components/tabs-labels.ts +0 -13
- package/src/components/tabs.tsx +0 -693
- package/src/components/text-link.tsx +0 -359
- package/src/components/text.tsx +0 -150
- package/src/components/textarea.tsx +0 -330
- package/src/components/tile-radio.tsx +0 -332
- package/src/components/time-input.tsx +0 -121
- package/src/components/toast-labels.ts +0 -12
- package/src/components/toast.tsx +0 -519
- package/src/components/toggle-group.tsx +0 -752
- package/src/components/toggle-legend.tsx +0 -394
- package/src/components/tooltip.tsx +0 -1149
- package/src/components/translation-review-editor.tsx +0 -290
- package/src/components/translation-review-labels.ts +0 -181
- package/src/components/translation-review-parts.tsx +0 -272
- package/src/components/translation-review.tsx +0 -1240
- package/src/components/tree-view.tsx +0 -589
- package/src/components/treemap-labels.ts +0 -47
- package/src/components/treemap-layout.ts +0 -210
- package/src/components/treemap.tsx +0 -1184
- package/src/components/trigger-aria.ts +0 -44
- package/src/components/use-anchor-dir.ts +0 -20
- package/src/components/use-mobile-reveal.ts +0 -62
- package/src/components/use-table-state.ts +0 -753
- package/src/components/user-avatar.tsx +0 -116
- package/src/components/wizard-stepper.tsx +0 -42
- package/src/components/write-lock-labels.ts +0 -10
- package/src/components/write-lock.tsx +0 -253
- package/src/currencies.ts +0 -90
- package/src/data-table.ts +0 -42
- package/src/demo/demo-banner.tsx +0 -153
- package/src/demo/demo-countdown.ts +0 -136
- package/src/demo/demo-ended.tsx +0 -90
- package/src/demo/demo-labels.ts +0 -78
- package/src/demo/demo-session.ts +0 -32
- package/src/demo/demo-start.tsx +0 -156
- package/src/eslint/index.ts +0 -161
- package/src/eslint/role-utilities.generated.ts +0 -146
- package/src/eslint/role-utilities.ts +0 -233
- package/src/feedback/feedback-attachment-download.tsx +0 -77
- package/src/feedback/feedback-attachment-labels.ts +0 -37
- package/src/feedback/feedback-attachment.tsx +0 -1239
- package/src/feedback/feedback-capture.ts +0 -287
- package/src/feedback/feedback-comment-thread.tsx +0 -353
- package/src/feedback/feedback-context-labels.ts +0 -11
- package/src/feedback/feedback-context.tsx +0 -245
- package/src/feedback/feedback-crash.ts +0 -547
- package/src/feedback/feedback-diagnostics.tsx +0 -41
- package/src/feedback/feedback-dialog-labels.ts +0 -29
- package/src/feedback/feedback-dialog.tsx +0 -452
- package/src/feedback/feedback-entry-file.tsx +0 -150
- package/src/feedback/feedback-inbox.tsx +0 -552
- package/src/feedback/feedback-labels.ts +0 -144
- package/src/feedback/feedback-menu-labels.ts +0 -12
- package/src/feedback/feedback-menu.tsx +0 -177
- package/src/feedback/feedback-mutation.ts +0 -20
- package/src/feedback/feedback-page-link.ts +0 -90
- package/src/feedback/feedback-public-labels.ts +0 -81
- package/src/feedback/feedback-public-list.tsx +0 -524
- package/src/feedback/feedback-public-switch.tsx +0 -102
- package/src/feedback/feedback-public-types.ts +0 -101
- package/src/feedback/feedback-record.ts +0 -428
- package/src/feedback/feedback-replies-context.ts +0 -9
- package/src/feedback/feedback-replies.tsx +0 -343
- package/src/feedback/feedback-rework-entry-chip.tsx +0 -18
- package/src/feedback/feedback-row-detail-labels.ts +0 -31
- package/src/feedback/feedback-row-detail.tsx +0 -871
- package/src/feedback/feedback-status-undo.ts +0 -109
- package/src/feedback/feedback-submit-dialog.tsx +0 -131
- package/src/feedback/feedback-submit.tsx +0 -270
- package/src/feedback/feedback-swipe.tsx +0 -192
- package/src/feedback/feedback-table-labels.ts +0 -27
- package/src/feedback/feedback-table.tsx +0 -912
- package/src/feedback/feedback-thread-labels.ts +0 -22
- package/src/feedback/feedback-thread-parts-labels.ts +0 -41
- package/src/feedback/feedback-thread.tsx +0 -905
- package/src/feedback/feedback-vocabulary.ts +0 -263
- package/src/feedback/feedback-vote-button.tsx +0 -124
- package/src/feedback.ts +0 -116
- package/src/hooks/use-anchored-panel.ts +0 -396
- package/src/hooks/use-anchored-rect.ts +0 -77
- package/src/hooks/use-announce.ts +0 -85
- package/src/hooks/use-authed-src.ts +0 -167
- package/src/hooks/use-body-scroll-lock.ts +0 -119
- package/src/hooks/use-breakpoint.ts +0 -133
- package/src/hooks/use-close-transition.ts +0 -107
- package/src/hooks/use-copy-to-clipboard.ts +0 -122
- package/src/hooks/use-debounce.ts +0 -114
- package/src/hooks/use-dismiss.ts +0 -371
- package/src/hooks/use-document-title.ts +0 -33
- package/src/hooks/use-file-drop.ts +0 -121
- package/src/hooks/use-file-picker-labels.ts +0 -28
- package/src/hooks/use-file-picker.tsx +0 -359
- package/src/hooks/use-focus-trap.ts +0 -199
- package/src/hooks/use-hotkey.ts +0 -212
- package/src/hooks/use-large-text.ts +0 -41
- package/src/hooks/use-long-press.ts +0 -140
- package/src/hooks/use-media-query.ts +0 -39
- package/src/hooks/use-mounted.ts +0 -39
- package/src/hooks/use-noindex.ts +0 -37
- package/src/hooks/use-overlay-history.ts +0 -714
- package/src/hooks/use-row-swipe.ts +0 -207
- package/src/hooks/use-search-param-state.ts +0 -434
- package/src/hooks/use-windowed-rows.ts +0 -225
- package/src/i18n/defaults.ts +0 -267
- package/src/i18n/german.ts +0 -2059
- package/src/i18n/kit-labels.tsx +0 -1003
- package/src/i18n/languages.ts +0 -349
- package/src/i18n/locales/de-CH.ts +0 -24
- package/src/i18n/locales/en.ts +0 -267
- package/src/i18n/locales/es.ts +0 -1999
- package/src/i18n/locales/fr.ts +0 -2037
- package/src/i18n/locales/hu.ts +0 -2004
- package/src/i18n/locales/it.ts +0 -2014
- package/src/i18n/locales/zh.ts +0 -1912
- package/src/i18n/plurals.ts +0 -86
- package/src/i18n/review.ts +0 -475
- package/src/i18n/shared-labels.ts +0 -138
- package/src/i18n/swiss.ts +0 -29
- package/src/index.ts +0 -1191
- package/src/landing/access.ts +0 -93
- package/src/landing/landing-actions.tsx +0 -97
- package/src/landing/landing-labels.ts +0 -59
- package/src/landing/landing-sections.tsx +0 -341
- package/src/landing/page-seo.ts +0 -261
- package/src/landing/public-header.tsx +0 -121
- package/src/landing/public-page.tsx +0 -106
- package/src/landing/routing.tsx +0 -225
- package/src/lib/broadcast.ts +0 -52
- package/src/lib/calc.ts +0 -323
- package/src/lib/chip-edge-snap.ts +0 -212
- package/src/lib/clipboard-minus.ts +0 -107
- package/src/lib/clipping.ts +0 -34
- package/src/lib/cn.ts +0 -28
- package/src/lib/column-mapping.ts +0 -234
- package/src/lib/countries.ts +0 -91
- package/src/lib/data-attributes.ts +0 -14
- package/src/lib/date-format.ts +0 -227
- package/src/lib/dates.ts +0 -288
- package/src/lib/day-format.ts +0 -96
- package/src/lib/decimal-marks.ts +0 -108
- package/src/lib/describe-failure.ts +0 -18
- package/src/lib/device-settings.ts +0 -147
- package/src/lib/direction.ts +0 -74
- package/src/lib/document-navigation.ts +0 -17
- package/src/lib/document-title.ts +0 -41
- package/src/lib/download.ts +0 -172
- package/src/lib/float-clearance.ts +0 -70
- package/src/lib/floating-stack.ts +0 -70
- package/src/lib/focus-left.ts +0 -156
- package/src/lib/format.ts +0 -585
- package/src/lib/http-status.ts +0 -38
- package/src/lib/iban.ts +0 -251
- package/src/lib/ime.ts +0 -24
- package/src/lib/intl-cache.ts +0 -27
- package/src/lib/iso-day.ts +0 -13
- package/src/lib/lazy-with-fallback.ts +0 -82
- package/src/lib/logger.ts +0 -69
- package/src/lib/minus.ts +0 -50
- package/src/lib/path-pattern.ts +0 -55
- package/src/lib/person-name.ts +0 -155
- package/src/lib/phone.ts +0 -208
- package/src/lib/plain-text.ts +0 -22
- package/src/lib/presence.ts +0 -18
- package/src/lib/qr-encode.ts +0 -444
- package/src/lib/quiet-focus.ts +0 -32
- package/src/lib/reduced-motion.ts +0 -22
- package/src/lib/refs.ts +0 -22
- package/src/lib/round.ts +0 -43
- package/src/lib/safe-storage.ts +0 -119
- package/src/lib/server-wake.ts +0 -315
- package/src/lib/session-refresh.ts +0 -472
- package/src/lib/share-format.ts +0 -18
- package/src/lib/status-tone.ts +0 -43
- package/src/lib/strip-fade.ts +0 -287
- package/src/lib/table-text.ts +0 -554
- package/src/lib/text-case.ts +0 -19
- package/src/lib/text-match.ts +0 -169
- package/src/lib/thenable.ts +0 -19
- package/src/lib/translation-review.ts +0 -769
- package/src/notifications/device-zone-report.ts +0 -67
- package/src/notifications/feedback-notification-types-labels.ts +0 -33
- package/src/notifications/feedback-notification-types.ts +0 -71
- package/src/notifications/notification-bell.tsx +0 -119
- package/src/notifications/notification-inbox.tsx +0 -309
- package/src/notifications/notification-parts.tsx +0 -81
- package/src/notifications/notification-types-setting.tsx +0 -406
- package/src/notifications/notification-types.ts +0 -89
- package/src/notifications/notifications-labels.ts +0 -287
- package/src/notifications/push-device-setting.tsx +0 -230
- package/src/notifications/push-devices-setting.tsx +0 -374
- package/src/notifications/push-worker.ts +0 -168
- package/src/notifications/quiet-hours-setting.tsx +0 -238
- package/src/notifications/unsubscribe-panel.tsx +0 -200
- package/src/notifications/use-push-device.ts +0 -448
- package/src/offline/local-first.ts +0 -100
- package/src/offline/pwa-update-prompt-labels.ts +0 -9
- package/src/offline/pwa-update-prompt.tsx +0 -78
- package/src/offline/query-persistence.ts +0 -391
- package/src/offline/service-worker-updates.ts +0 -81
- package/src/offline/shared-computer-labels.ts +0 -8
- package/src/offline/shared-computer.tsx +0 -87
- package/src/offline/sign-out-pending-dialog-labels.ts +0 -21
- package/src/offline/sign-out-pending-dialog.tsx +0 -135
- package/src/offline.ts +0 -37
- package/src/push-worker.ts +0 -25
- package/src/rhf/fields.tsx +0 -2187
- package/src/rhf/form-core.tsx +0 -324
- package/src/rhf/form.tsx +0 -12
- package/src/rhf/line-items.tsx +0 -135
- package/src/rhf/use-rhf-wizard-step.ts +0 -104
- package/src/rhf.ts +0 -21
- package/src/search/command-palette-labels.ts +0 -16
- package/src/search/command-palette.tsx +0 -624
- package/src/search/global-search-labels.ts +0 -13
- package/src/search/global-search.tsx +0 -660
- package/src/search/search-index.ts +0 -283
- package/src/search/use-command-key.ts +0 -23
- package/src/search.ts +0 -14
- package/src/settings/device-reset-setting-labels.ts +0 -20
- package/src/settings/device-reset-setting.tsx +0 -116
- package/src/settings/settings-card-classes.ts +0 -11
- package/src/settings/settings-catalogue.ts +0 -150
- package/src/settings/settings-context.ts +0 -33
- package/src/settings/settings-heading.tsx +0 -67
- package/src/settings/settings-labels.ts +0 -87
- package/src/settings/settings-layout.tsx +0 -471
- package/src/settings/settings-section.tsx +0 -108
- package/src/settings/use-account-appearance.ts +0 -148
- package/src/settings/use-account-language.ts +0 -146
- package/src/settings/use-settings-focus.ts +0 -128
- package/src/settings/use-settings-route.ts +0 -258
- package/src/shell/account-menu-language.tsx +0 -130
- package/src/shell/account-menu-text-size.tsx +0 -80
- package/src/shell/admin-menu.tsx +0 -183
- package/src/shell/app-shell-labels.ts +0 -11
- package/src/shell/app-shell.tsx +0 -1560
- package/src/shell/auth-layout.tsx +0 -186
- package/src/shell/company-switcher-labels.ts +0 -13
- package/src/shell/company-switcher.tsx +0 -136
- package/src/shell/dev-menu.tsx +0 -257
- package/src/shell/fill-height.tsx +0 -45
- package/src/shell/language-code.ts +0 -5
- package/src/shell/option-switcher-menu.tsx +0 -84
- package/src/shell/sync-status-indicator.tsx +0 -303
- package/src/shell/top-bar-actions.tsx +0 -87
- package/src/shell/top-bar-brand.tsx +0 -78
- package/src/shell/top-bar-parts-labels.ts +0 -148
- package/src/shell/top-bar.tsx +0 -40
- package/src/shell/topbar-action-menu.tsx +0 -567
- package/src/shell/topbar-controls.tsx +0 -269
- package/src/shell/tour-menu.tsx +0 -187
- package/src/shell.ts +0 -108
- package/src/sync/db.ts +0 -129
- package/src/sync/engine.ts +0 -1011
- package/src/sync/hooks.ts +0 -98
- package/src/sync/testing.ts +0 -73
- package/src/sync/wire.ts +0 -61
- package/src/sync.ts +0 -37
- package/src/table-text.ts +0 -8
- package/src/testing/css-variables.generated.ts +0 -112
- package/src/testing/css-variables.ts +0 -189
- package/src/testing/index.ts +0 -29
- package/src/testing/react.ts +0 -58
- package/src/testing/tour.ts +0 -41
- package/src/testing/viewport.ts +0 -357
- package/src/theme/chart-palette.ts +0 -232
- package/src/theme/color.ts +0 -272
- package/src/theme/contrast-tokens.ts +0 -268
- package/src/theme/contrast.ts +0 -250
- package/src/theme/palette-derive.ts +0 -825
- package/src/theme/palette-presets.ts +0 -544
- package/src/theme/palette-store.ts +0 -108
- package/src/theme/text-size.ts +0 -289
- package/src/theme/theme-store.ts +0 -157
- package/src/tour/tour-catalogue-labels.ts +0 -75
- package/src/tour/tour-catalogue.tsx +0 -335
- package/src/tour/tour-dock.ts +0 -134
- package/src/tour/tour-engine.ts +0 -37
- package/src/tour/tour-gates.ts +0 -218
- package/src/tour/tour-guide-button.tsx +0 -64
- package/src/tour/tour-guide-labels.ts +0 -15
- package/src/tour/tour-info.ts +0 -144
- package/src/tour/tour-labels.ts +0 -23
- package/src/tour/tour-overlay.tsx +0 -1170
- package/src/tour/tour.tsx +0 -750
- package/src/tour/use-tour-progress.ts +0 -671
- package/src/tour/use-tour-url-sync.ts +0 -266
- package/src/tour.ts +0 -21
- package/src/vite-env.d.ts +0 -23
- package/src/wizard/stepper-nav.tsx +0 -360
- package/src/wizard/types.ts +0 -275
- package/src/wizard/use-wizard.ts +0 -560
- package/src/wizard/validation.ts +0 -39
- package/src/wizard/wizard-context.tsx +0 -74
- package/src/wizard/wizard-labels.ts +0 -29
- package/src/wizard/wizard-step.tsx +0 -76
- package/src/wizard/wizard-summary.tsx +0 -84
- package/src/wizard.ts +0 -15
|
@@ -1,283 +0,0 @@
|
|
|
1
|
-
import type { ReactNode } from "react";
|
|
2
|
-
import { foldForSearch } from "../lib/text-match";
|
|
3
|
-
|
|
4
|
-
/**
|
|
5
|
-
* The matcher behind {@link GlobalSearch} — pure, React-free, testable on its own.
|
|
6
|
-
*
|
|
7
|
-
* WHY IT EXISTS. `CommandPalette` is deliberately domain-free: it shows whatever a
|
|
8
|
-
* `search(query)` provider returns. So every app wrote that provider, and every app wrote
|
|
9
|
-
* the same one — `label.toLowerCase().includes(q)` over its pages and actions (kastlan's
|
|
10
|
-
* command palette, keksdose's global search) plus a second copy with keywords for the
|
|
11
|
-
* settings catalogue (keksdose's `matchSettingsEntries`). A substring test answers "does
|
|
12
|
-
* this string contain that one", which is not what a search box is asked:
|
|
13
|
-
*
|
|
14
|
-
* - "range date" finds nothing, because the words are in the other order;
|
|
15
|
-
* - "Uberweisung" misses "Überweisung", and "Tooltp" misses "Tooltip";
|
|
16
|
-
* - "del" matches "model" as happily as "delete", and every hit ranks the same, so the
|
|
17
|
-
* exact page name can sit under six unrelated rows.
|
|
18
|
-
*
|
|
19
|
-
* What it does instead, per entry:
|
|
20
|
-
*
|
|
21
|
-
* - NORMALISES both sides: lower case, accents stripped (NFD minus combining marks),
|
|
22
|
-
* `ß` → `ss`, punctuation as a word break, and camelCase split so `DateRangePicker`
|
|
23
|
-
* is also the words date, range, picker.
|
|
24
|
-
* - Requires EVERY query word to match SOMEWHERE in the entry — title, keywords or
|
|
25
|
-
* description, in any order.
|
|
26
|
-
* - A word matches a word of the entry exactly, as its prefix, inside it (four letters or
|
|
27
|
-
* more, for compounds: "bereich" in "Datumsbereich"), or — for words of five letters
|
|
28
|
-
* or more — at edit distance one, transpositions included ("tooltp", "calender").
|
|
29
|
-
* - RANKS in tiers: exact title > title prefix > all words in the title > some word only
|
|
30
|
-
* in the keywords > some word only in the description. Within a tier, better word
|
|
31
|
-
* matches (exact over prefix over infix over typo) score higher, and `weight` is added
|
|
32
|
-
* last. The tiers are {@link SEARCH_TIER_POINTS} points apart, so a weight below that reorders within
|
|
33
|
-
* a tier and never across one.
|
|
34
|
-
* - Caps each group (`groupLimit`, default 8) after ranking, so one broad group cannot
|
|
35
|
-
* push every other group off the list.
|
|
36
|
-
*/
|
|
37
|
-
|
|
38
|
-
/** One searchable thing: a page, an action, a record, a settings row. */
|
|
39
|
-
export interface SearchEntry {
|
|
40
|
-
/** Unique across the entries handed to one index. */
|
|
41
|
-
id: string;
|
|
42
|
-
/** What the row says, and what ranks highest. */
|
|
43
|
-
title: string;
|
|
44
|
-
/** Other words or phrases that should find it — synonyms, a translated name, tags.
|
|
45
|
-
* Matched like the title, ranked below it. */
|
|
46
|
-
keywords?: readonly string[];
|
|
47
|
-
/** Longer text, matched last and ranked lowest. Not shown in the row. */
|
|
48
|
-
description?: string;
|
|
49
|
-
/** Heading the row is grouped under in the palette. */
|
|
50
|
-
group?: string;
|
|
51
|
-
/** Secondary text on the row's trailing side (the page it lives on, an amount). */
|
|
52
|
-
hint?: string;
|
|
53
|
-
/** Leading icon. */
|
|
54
|
-
icon?: ReactNode;
|
|
55
|
-
/** Where it leads — the app's own path, handed to `GlobalSearch`'s `navigate`. */
|
|
56
|
-
href?: string;
|
|
57
|
-
/** Run instead of navigating. Wins over `href` for a plain click and ↵; `href` still
|
|
58
|
-
* makes the row a real link for a middle-/⌘-click. */
|
|
59
|
-
onSelect?: () => void;
|
|
60
|
-
/** Added to the score. Below {@link SEARCH_TIER_POINTS} it reorders within a tier. */
|
|
61
|
-
weight?: number;
|
|
62
|
-
/** Masks the row for session replay (see `CommandItem.redact`). */
|
|
63
|
-
redact?: boolean;
|
|
64
|
-
}
|
|
65
|
-
|
|
66
|
-
export type SearchMatchField = "title" | "keywords" | "description";
|
|
67
|
-
|
|
68
|
-
export interface SearchHit<E extends SearchEntry = SearchEntry> {
|
|
69
|
-
entry: E;
|
|
70
|
-
score: number;
|
|
71
|
-
/** The weakest field any query word had to be found in. */
|
|
72
|
-
field: SearchMatchField;
|
|
73
|
-
}
|
|
74
|
-
|
|
75
|
-
export interface SearchIndexOptions {
|
|
76
|
-
/** Hits kept per `group` after ranking. Default 8; `Infinity` for no cap. */
|
|
77
|
-
groupLimit?: number;
|
|
78
|
-
/** Hits kept in total. Default: no cap beyond `groupLimit`. */
|
|
79
|
-
limit?: number;
|
|
80
|
-
/** Shortest query word allowed an edit-distance-1 match. Default 5 — below that a
|
|
81
|
-
* single typo is a different word ("cat" / "car"). */
|
|
82
|
-
typoMinLength?: number;
|
|
83
|
-
/** Shortest query word matched INSIDE an entry word. Default 4. */
|
|
84
|
-
infixMinLength?: number;
|
|
85
|
-
}
|
|
86
|
-
|
|
87
|
-
export interface SearchIndex<E extends SearchEntry = SearchEntry> {
|
|
88
|
-
/** Ranked hits for `query`; an empty query returns none. */
|
|
89
|
-
search: (query: string) => SearchHit<E>[];
|
|
90
|
-
readonly entries: readonly E[];
|
|
91
|
-
}
|
|
92
|
-
|
|
93
|
-
/** Points between two ranking tiers. */
|
|
94
|
-
export const SEARCH_TIER_POINTS = 1000;
|
|
95
|
-
|
|
96
|
-
const TIERS = {
|
|
97
|
-
exact: 5,
|
|
98
|
-
prefix: 4,
|
|
99
|
-
title: 3,
|
|
100
|
-
keywords: 2,
|
|
101
|
-
description: 1,
|
|
102
|
-
} as const;
|
|
103
|
-
|
|
104
|
-
/** How well one query word matched one entry word — higher is better. */
|
|
105
|
-
const WORD_SCORE = { exact: 40, prefix: 30, infix: 15, typo: 10 } as const;
|
|
106
|
-
/** How much the field a word matched in is worth, multiplied with the above. */
|
|
107
|
-
const FIELD_FACTOR: Record<SearchMatchField, number> = { title: 3, keywords: 2, description: 1 };
|
|
108
|
-
|
|
109
|
-
/**
|
|
110
|
-
* Lower case, accents off, punctuation to spaces — the form both sides are compared in.
|
|
111
|
-
* Exported so an app can normalise its own keys the same way. The fold is every kit
|
|
112
|
-
* list's {@link foldForSearch} (DUP-5, refactor audit 2026-10); the index adds the
|
|
113
|
-
* punctuation-to-space step its word split needs.
|
|
114
|
-
*/
|
|
115
|
-
export function normalizeSearchText(text: string): string {
|
|
116
|
-
return foldForSearch(text)
|
|
117
|
-
.replace(/[^\p{L}\p{N}]+/gu, " ")
|
|
118
|
-
.trim();
|
|
119
|
-
}
|
|
120
|
-
|
|
121
|
-
/** The words of a text, camelCase split too: "DateRangePicker" → daterangepicker, date,
|
|
122
|
-
* range, picker. The joined word stays so "daterange" still prefixes it. */
|
|
123
|
-
function words(text: string): string[] {
|
|
124
|
-
const out = new Set<string>();
|
|
125
|
-
// Split camelCase BEFORE lower-casing, or the boundaries are gone.
|
|
126
|
-
const spaced = text.replace(/(\p{Ll}|\p{N})(\p{Lu})/gu, "$1 $2").replace(/(\p{Lu})(\p{Lu}\p{Ll})/gu, "$1 $2");
|
|
127
|
-
for (const w of normalizeSearchText(text).split(" ")) if (w) out.add(w);
|
|
128
|
-
for (const w of normalizeSearchText(spaced).split(" ")) if (w) out.add(w);
|
|
129
|
-
return [...out];
|
|
130
|
-
}
|
|
131
|
-
|
|
132
|
-
/** Restricted Damerau–Levenshtein distance, early-exiting once it must exceed `max`. */
|
|
133
|
-
function withinDistance(a: string, b: string, max: number): boolean {
|
|
134
|
-
if (Math.abs(a.length - b.length) > max) return false;
|
|
135
|
-
if (a === b) return true;
|
|
136
|
-
const n = a.length;
|
|
137
|
-
const m = b.length;
|
|
138
|
-
let prev2: number[] = [];
|
|
139
|
-
let prev = Array.from({ length: m + 1 }, (_, j) => j);
|
|
140
|
-
for (let i = 1; i <= n; i++) {
|
|
141
|
-
const cur = [i];
|
|
142
|
-
let rowMin = i;
|
|
143
|
-
for (let j = 1; j <= m; j++) {
|
|
144
|
-
const cost = a[i - 1] === b[j - 1] ? 0 : 1;
|
|
145
|
-
let v = Math.min(prev[j] + 1, cur[j - 1] + 1, prev[j - 1] + cost);
|
|
146
|
-
if (i > 1 && j > 1 && a[i - 1] === b[j - 2] && a[i - 2] === b[j - 1]) {
|
|
147
|
-
v = Math.min(v, prev2[j - 2] + 1);
|
|
148
|
-
}
|
|
149
|
-
cur.push(v);
|
|
150
|
-
if (v < rowMin) rowMin = v;
|
|
151
|
-
}
|
|
152
|
-
if (rowMin > max) return false;
|
|
153
|
-
prev2 = prev;
|
|
154
|
-
prev = cur;
|
|
155
|
-
}
|
|
156
|
-
return prev[m] <= max;
|
|
157
|
-
}
|
|
158
|
-
|
|
159
|
-
type WordKind = keyof typeof WORD_SCORE;
|
|
160
|
-
|
|
161
|
-
function matchWord(
|
|
162
|
-
q: string,
|
|
163
|
-
word: string,
|
|
164
|
-
opts: Required<Pick<SearchIndexOptions, "typoMinLength" | "infixMinLength">>,
|
|
165
|
-
): WordKind | null {
|
|
166
|
-
if (word === q) return "exact";
|
|
167
|
-
if (word.startsWith(q)) return "prefix";
|
|
168
|
-
if (q.length >= opts.infixMinLength && word.includes(q)) return "infix";
|
|
169
|
-
if (q.length >= opts.typoMinLength) {
|
|
170
|
-
// The whole word, or the word's start as long as the query (a typo in a prefix:
|
|
171
|
-
// "calender" is one edit from "calendar", the start of "calendars").
|
|
172
|
-
if (withinDistance(q, word, 1)) return "typo";
|
|
173
|
-
if (word.length > q.length && withinDistance(q, word.slice(0, q.length), 1)) return "typo";
|
|
174
|
-
}
|
|
175
|
-
return null;
|
|
176
|
-
}
|
|
177
|
-
|
|
178
|
-
interface Prepared<E> {
|
|
179
|
-
entry: E;
|
|
180
|
-
title: string;
|
|
181
|
-
titleCompact: string;
|
|
182
|
-
fields: Array<[SearchMatchField, string[]]>;
|
|
183
|
-
}
|
|
184
|
-
|
|
185
|
-
/**
|
|
186
|
-
* Build an index over `entries`. Normalisation happens once here, so `search` is a scan
|
|
187
|
-
* over prepared words — a few thousand entries per keystroke is nothing.
|
|
188
|
-
*/
|
|
189
|
-
export function createSearchIndex<E extends SearchEntry>(
|
|
190
|
-
entries: readonly E[],
|
|
191
|
-
options: SearchIndexOptions = {},
|
|
192
|
-
): SearchIndex<E> {
|
|
193
|
-
const { groupLimit = 8, limit = Infinity, typoMinLength = 5, infixMinLength = 4 } = options;
|
|
194
|
-
const wordOpts = { typoMinLength, infixMinLength };
|
|
195
|
-
const prepared: Prepared<E>[] = entries.map((entry) => {
|
|
196
|
-
const title = normalizeSearchText(entry.title);
|
|
197
|
-
return {
|
|
198
|
-
entry,
|
|
199
|
-
title,
|
|
200
|
-
titleCompact: title.replace(/ /g, ""),
|
|
201
|
-
fields: [
|
|
202
|
-
["title", words(entry.title)],
|
|
203
|
-
["keywords", (entry.keywords ?? []).flatMap(words)],
|
|
204
|
-
["description", entry.description ? words(entry.description) : []],
|
|
205
|
-
],
|
|
206
|
-
};
|
|
207
|
-
});
|
|
208
|
-
|
|
209
|
-
const search = (query: string): SearchHit<E>[] => {
|
|
210
|
-
const q = normalizeSearchText(query);
|
|
211
|
-
if (!q) return [];
|
|
212
|
-
const qWords = [...new Set(q.split(" "))];
|
|
213
|
-
const qCompact = q.replace(/ /g, "");
|
|
214
|
-
const hits: SearchHit<E>[] = [];
|
|
215
|
-
|
|
216
|
-
for (const p of prepared) {
|
|
217
|
-
let quality = 0;
|
|
218
|
-
let weakest: SearchMatchField = "title";
|
|
219
|
-
let ok = true;
|
|
220
|
-
for (const qw of qWords) {
|
|
221
|
-
let best = 0;
|
|
222
|
-
let bestField: SearchMatchField | null = null;
|
|
223
|
-
for (const [field, fieldWords] of p.fields) {
|
|
224
|
-
for (const w of fieldWords) {
|
|
225
|
-
const kind = matchWord(qw, w, wordOpts);
|
|
226
|
-
if (!kind) continue;
|
|
227
|
-
const s = WORD_SCORE[kind] * FIELD_FACTOR[field];
|
|
228
|
-
if (s > best) {
|
|
229
|
-
best = s;
|
|
230
|
-
bestField = field;
|
|
231
|
-
}
|
|
232
|
-
}
|
|
233
|
-
}
|
|
234
|
-
if (!bestField) {
|
|
235
|
-
ok = false;
|
|
236
|
-
break;
|
|
237
|
-
}
|
|
238
|
-
quality += best;
|
|
239
|
-
if (FIELD_FACTOR[bestField] < FIELD_FACTOR[weakest]) weakest = bestField;
|
|
240
|
-
}
|
|
241
|
-
if (!ok) continue;
|
|
242
|
-
|
|
243
|
-
let tier: number = TIERS[weakest];
|
|
244
|
-
if (p.title === q || p.titleCompact === qCompact) tier = TIERS.exact;
|
|
245
|
-
else if (
|
|
246
|
-
p.title.startsWith(q) ||
|
|
247
|
-
p.titleCompact.startsWith(qCompact) ||
|
|
248
|
-
// The whole title, mistyped once ("Tooltp") — as good as a prefix, not exact.
|
|
249
|
-
(qCompact.length >= typoMinLength && withinDistance(qCompact, p.titleCompact, 1))
|
|
250
|
-
) {
|
|
251
|
-
tier = TIERS.prefix;
|
|
252
|
-
}
|
|
253
|
-
// Within a tier: how well the words matched (≤ 120 each, averaged so a long query
|
|
254
|
-
// cannot climb by word count), and how much of the title the query covers — so
|
|
255
|
-
// "Tooltip" beats "Popovers, menus & tooltips" for the same one-word match.
|
|
256
|
-
const coverage = Math.min(1, qCompact.length / Math.max(1, p.titleCompact.length)) * 40;
|
|
257
|
-
const score =
|
|
258
|
-
tier * SEARCH_TIER_POINTS +
|
|
259
|
-
Math.min(quality / qWords.length + coverage, SEARCH_TIER_POINTS / 2 - 1) +
|
|
260
|
-
(p.entry.weight ?? 0);
|
|
261
|
-
hits.push({ entry: p.entry, score, field: weakest });
|
|
262
|
-
}
|
|
263
|
-
|
|
264
|
-
hits.sort((a, b) => b.score - a.score || a.entry.title.localeCompare(b.entry.title));
|
|
265
|
-
return capByGroup(hits, groupLimit, limit);
|
|
266
|
-
};
|
|
267
|
-
|
|
268
|
-
return { search, entries };
|
|
269
|
-
}
|
|
270
|
-
|
|
271
|
-
function capByGroup<E extends SearchEntry>(hits: SearchHit<E>[], groupLimit: number, limit: number): SearchHit<E>[] {
|
|
272
|
-
const perGroup = new Map<string, number>();
|
|
273
|
-
const out: SearchHit<E>[] = [];
|
|
274
|
-
for (const hit of hits) {
|
|
275
|
-
if (out.length >= limit) break;
|
|
276
|
-
const g = hit.entry.group ?? "";
|
|
277
|
-
const n = perGroup.get(g) ?? 0;
|
|
278
|
-
if (n >= groupLimit) continue;
|
|
279
|
-
perGroup.set(g, n + 1);
|
|
280
|
-
out.push(hit);
|
|
281
|
-
}
|
|
282
|
-
return out;
|
|
283
|
-
}
|
|
@@ -1,23 +0,0 @@
|
|
|
1
|
-
import { useHotkey, type UseHotkeyOptions } from "../hooks/use-hotkey";
|
|
2
|
-
|
|
3
|
-
/**
|
|
4
|
-
* Registers a global ⌘K / Ctrl-K shortcut that calls `onOpen`.
|
|
5
|
-
*
|
|
6
|
-
* Its own module since 0.34 (MOD-1, refactor audit 2026-10): `GlobalSearch` listens for
|
|
7
|
-
* the shortcut from the moment the top bar mounts but loads the palette only when it is
|
|
8
|
-
* first opened, and a hook imported from command-palette.tsx would have brought the
|
|
9
|
-
* palette along with it. Still exported from command-palette.tsx, where it always was.
|
|
10
|
-
*
|
|
11
|
-
* `useHotkey("Mod+K")` since 0.52 (refactor audit 2026-10-30, DUP-12): Cmd+K on a Mac,
|
|
12
|
-
* Ctrl+K elsewhere, with no other modifier, once per press. Hand-rolled, it took Ctrl+K
|
|
13
|
-
* on a Mac as well — a text field's kill-line there — and Ctrl+Shift+K, Cmd+Alt+K and
|
|
14
|
-
* every repeat of a held key. It still fires from inside a text field: the palette is
|
|
15
|
-
* where a search starts, whatever has focus.
|
|
16
|
-
*
|
|
17
|
-
* `enabled: false` lets Mod+K go (0.52 code review, global-search.tsx): `GlobalSearch
|
|
18
|
-
* shortcut={false}` passed a no-op, and the listener still cancelled every Mod+K — the
|
|
19
|
-
* browser's own Ctrl+K and any other handler on the page that checks `defaultPrevented`.
|
|
20
|
-
*/
|
|
21
|
-
export function useCommandKey(onOpen: () => void, options: Pick<UseHotkeyOptions, "enabled"> = {}): void {
|
|
22
|
-
useHotkey("Mod+K", () => onOpen(), { allowInInputs: true, enabled: options.enabled });
|
|
23
|
-
}
|
package/src/search.ts
DELETED
|
@@ -1,14 +0,0 @@
|
|
|
1
|
-
// `@eifi1/ui-kit/search` — the command palette / global search.
|
|
2
|
-
// A re-slicing of the main barrel, not a new API.
|
|
3
|
-
export * from "./search/command-palette";
|
|
4
|
-
// Named, not `*`: 0.53 took `SEARCH_TIER_POINTS` and `normalizeSearchText` off the surface
|
|
5
|
-
// (deprecated in 0.52, refactor audit 2026-10-30, API-4); the index keeps them.
|
|
6
|
-
export {
|
|
7
|
-
createSearchIndex,
|
|
8
|
-
type SearchEntry,
|
|
9
|
-
type SearchMatchField,
|
|
10
|
-
type SearchHit,
|
|
11
|
-
type SearchIndexOptions,
|
|
12
|
-
type SearchIndex,
|
|
13
|
-
} from "./search/search-index";
|
|
14
|
-
export * from "./search/global-search";
|
|
@@ -1,20 +0,0 @@
|
|
|
1
|
-
// The English words of ./device-reset-setting, in a module with no component code: the
|
|
2
|
-
// English catalogue (src/i18n/defaults.ts) imports them without the component, so `en`
|
|
3
|
-
// loads as one chunk like the other languages (0.34, KS U8). ./device-reset-setting
|
|
4
|
-
// re-exports them.
|
|
5
|
-
|
|
6
|
-
import type { DeviceResetLabels } from "./device-reset-setting";
|
|
7
|
-
|
|
8
|
-
/** docs/settings-harmonization.md §11.3, word for word. */
|
|
9
|
-
export const DEFAULT_DEVICE_RESET_LABELS: DeviceResetLabels = {
|
|
10
|
-
title: "Reset this device",
|
|
11
|
-
description:
|
|
12
|
-
"Puts this device's appearance, and the way its tables and panels were left, back to the defaults. Your account, your data and your sign-in are not touched.",
|
|
13
|
-
action: "Reset this device's settings",
|
|
14
|
-
confirmTitle: "Reset this device's settings?",
|
|
15
|
-
confirmBody:
|
|
16
|
-
"Theme, colours, text size, contrast and language go back to their defaults here, and tables and panels open as they first did. Where your account has a language, a text size or a contrast, this device follows it again. Your account and your other devices stay as they are.",
|
|
17
|
-
confirmAction: "Reset",
|
|
18
|
-
done: "This device's settings are back to their defaults.",
|
|
19
|
-
keywords: "reset defaults device restore appearance tables layout",
|
|
20
|
-
};
|
|
@@ -1,116 +0,0 @@
|
|
|
1
|
-
import type { ReactNode } from "react";
|
|
2
|
-
|
|
3
|
-
import { useKitLabels, type LabelOverride } from "../i18n/kit-labels";
|
|
4
|
-
import { resetDeviceSettings } from "../lib/device-settings";
|
|
5
|
-
import { Button } from "../components/button";
|
|
6
|
-
import { useConfirm } from "../components/confirm-dialog";
|
|
7
|
-
import { toast } from "../components/toast";
|
|
8
|
-
import { SettingsSection, type SettingsSectionProps } from "./settings-section";
|
|
9
|
-
import { DEFAULT_DEVICE_RESET_LABELS } from "./device-reset-setting-labels";
|
|
10
|
-
|
|
11
|
-
/* ── Labels ──────────────────────────────────────────────────────────────── */
|
|
12
|
-
|
|
13
|
-
/** Every string {@link DeviceResetSetting} renders — the `deviceReset` namespace of
|
|
14
|
-
* `<UiKitProvider labels>`, overridable per instance through `labels`
|
|
15
|
-
* (docs/settings-harmonization.md §11.3). The confirm's Cancel is `confirmDialog.cancel`. */
|
|
16
|
-
export interface DeviceResetLabels {
|
|
17
|
-
/** The card's title, and the app's catalogue entry's. */
|
|
18
|
-
title: string;
|
|
19
|
-
/** The line under it: what goes back, and that the account is not touched. */
|
|
20
|
-
description: string;
|
|
21
|
-
/** The button that asks first. */
|
|
22
|
-
action: string;
|
|
23
|
-
/** The question it asks. */
|
|
24
|
-
confirmTitle: string;
|
|
25
|
-
/** What goes, what follows the account again, and what stays. */
|
|
26
|
-
confirmBody: string;
|
|
27
|
-
/** The button that answers it. */
|
|
28
|
-
confirmAction: string;
|
|
29
|
-
/** The toast once it is done. */
|
|
30
|
-
done: string;
|
|
31
|
-
/** For the app's catalogue entry (`keywords`); the card never reads it. */
|
|
32
|
-
keywords: string;
|
|
33
|
-
}
|
|
34
|
-
|
|
35
|
-
// Defined in ./device-reset-setting-labels, which holds no component code.
|
|
36
|
-
export { DEFAULT_DEVICE_RESET_LABELS };
|
|
37
|
-
|
|
38
|
-
/* ── The card ────────────────────────────────────────────────────────────── */
|
|
39
|
-
|
|
40
|
-
/** The card's DOM id: its catalogue entry's `anchor`, the `?focus=` target. */
|
|
41
|
-
export const DEVICE_RESET_ANCHOR = "settings-device-reset";
|
|
42
|
-
|
|
43
|
-
// `onReset` is the card's own: the DOM's form-reset handler never fires on a div.
|
|
44
|
-
export interface DeviceResetSettingProps extends Omit<
|
|
45
|
-
SettingsSectionProps,
|
|
46
|
-
"anchor" | "title" | "description" | "children" | "onReset"
|
|
47
|
-
> {
|
|
48
|
-
/** The app's sentence after the kit's description: what of its own goes back, and what
|
|
49
|
-
* stays (keksdose: the date format, the feature set and the gestures go; presentation
|
|
50
|
-
* mode and the home position stay). */
|
|
51
|
-
description?: ReactNode;
|
|
52
|
-
labels?: LabelOverride<DeviceResetLabels>;
|
|
53
|
-
/** Runs after the reset and before the toast, with the keys reset or removed. */
|
|
54
|
-
onReset?: (keys: string[]) => void;
|
|
55
|
-
}
|
|
56
|
-
|
|
57
|
-
/**
|
|
58
|
-
* "Reset this device's settings" (docs/settings-harmonization.md §11): the LAST card of
|
|
59
|
-
* the appearance group. It puts this device's appearance — theme, palette, language, text
|
|
60
|
-
* size, contrast and the app's own appearance choices — and its views — table views, the
|
|
61
|
-
* sidebar, folded groups, saved filters — back to what a new device gets, through
|
|
62
|
-
* {@link resetDeviceSettings}. The account, the sign-in, the session and anything waiting
|
|
63
|
-
* to be sent are never touched: they never join the registry.
|
|
64
|
-
*
|
|
65
|
-
* - **A confirm, not an undo** (§11.2 decision 9): `useConfirm` in the neutral tone,
|
|
66
|
-
* then a toast. An app mounts a `ConfirmProvider` and a `Toaster` already.
|
|
67
|
-
* - **Not a commit**: nothing is written to the account, so a demo or a lapsed plan's
|
|
68
|
-
* write lock does not disable it (decision 3).
|
|
69
|
-
* - **Live, no reload** (decision 10): each registered store resets through its own
|
|
70
|
-
* setter; the card stays where it is.
|
|
71
|
-
*
|
|
72
|
-
* The app adds the catalogue entry, `{ id, group: "appearance", anchor: DEVICE_RESET_ANCHOR,
|
|
73
|
-
* title, keywords }` (the id in its catalogue's own style, e.g. `device_reset` or
|
|
74
|
-
* `deviceReset`; `title` and `keywords` from these labels), last in its appearance group:
|
|
75
|
-
* inside a `SettingsLayout`, `SettingsSection` throws in development without it.
|
|
76
|
-
*/
|
|
77
|
-
export function DeviceResetSetting({ description, labels: labelsProp, onReset, ...rest }: DeviceResetSettingProps) {
|
|
78
|
-
const labels = useKitLabels("deviceReset", DEFAULT_DEVICE_RESET_LABELS, labelsProp);
|
|
79
|
-
const confirm = useConfirm();
|
|
80
|
-
|
|
81
|
-
const reset = async () => {
|
|
82
|
-
const ok = await confirm({
|
|
83
|
-
title: labels.confirmTitle,
|
|
84
|
-
body: labels.confirmBody,
|
|
85
|
-
confirmLabel: labels.confirmAction,
|
|
86
|
-
tone: "neutral",
|
|
87
|
-
});
|
|
88
|
-
if (!ok) return;
|
|
89
|
-
const keys = resetDeviceSettings();
|
|
90
|
-
onReset?.(keys);
|
|
91
|
-
toast.success(labels.done);
|
|
92
|
-
};
|
|
93
|
-
|
|
94
|
-
return (
|
|
95
|
-
<SettingsSection
|
|
96
|
-
{...rest}
|
|
97
|
-
anchor={DEVICE_RESET_ANCHOR}
|
|
98
|
-
title={labels.title}
|
|
99
|
-
description={
|
|
100
|
-
description != null ? (
|
|
101
|
-
<>
|
|
102
|
-
{labels.description} {description}
|
|
103
|
-
</>
|
|
104
|
-
) : (
|
|
105
|
-
labels.description
|
|
106
|
-
)
|
|
107
|
-
}
|
|
108
|
-
>
|
|
109
|
-
<div>
|
|
110
|
-
<Button variant="secondary" onClick={() => void reset()}>
|
|
111
|
-
{labels.action}
|
|
112
|
-
</Button>
|
|
113
|
-
</div>
|
|
114
|
-
</SettingsSection>
|
|
115
|
-
);
|
|
116
|
-
}
|
|
@@ -1,11 +0,0 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* The settings cards' type scale, PasskeysSetting's: a small title and a muted line.
|
|
3
|
-
* Every kit setting card draws it — the account cards, `SettingsSection` and the
|
|
4
|
-
* `SettingsCardTitle` they share — so it lives with the card look, in settings/. It was in
|
|
5
|
-
* account/account-parts.ts, which made settings/ import account/ and account/ import
|
|
6
|
-
* settings/ (MOD-8, refactor audit 2026-10); account-parts re-exports it.
|
|
7
|
-
*
|
|
8
|
-
* @internal Not part of the barrel.
|
|
9
|
-
*/
|
|
10
|
-
export const CARD_TITLE_CLASS = "text-sm font-medium";
|
|
11
|
-
export const CARD_DESCRIPTION_CLASS = "text-xs text-muted";
|
|
@@ -1,150 +0,0 @@
|
|
|
1
|
-
import type { ReactNode } from "react";
|
|
2
|
-
import type { SearchEntry } from "../search/search-index";
|
|
3
|
-
|
|
4
|
-
/**
|
|
5
|
-
* The settings catalogue (docs/settings-harmonization.md §4.1), lifted from keksdose's
|
|
6
|
-
* `settings-index.ts`: the groups a settings page is split into, and one entry per
|
|
7
|
-
* SETTING — not per card — so a search for "quiet hours" finds the field inside the
|
|
8
|
-
* notifications card. One list feeds the sidebar, the phone list, the in-page search and
|
|
9
|
-
* ⌘K ({@link settingsSearchEntries}); keksdose's page and its palette drifted when they
|
|
10
|
-
* had one each.
|
|
11
|
-
*
|
|
12
|
-
* The kit resolves no words: `title`, `help` and `keywords` arrive translated (an app's
|
|
13
|
-
* own, or the core groups' from `DEFAULT_SETTINGS_LABELS.groups`).
|
|
14
|
-
*/
|
|
15
|
-
|
|
16
|
-
/** One group of the page: a sidebar row on a desktop, a list row on a phone (§3.2, §3.3). */
|
|
17
|
-
export interface SettingsGroup<G extends string = string> {
|
|
18
|
-
/** The path segment, `/settings/<id>`: lowercase, a–z and "-". */
|
|
19
|
-
id: G;
|
|
20
|
-
/** The row's icon — a lucide icon at the row's size is sized by the row. */
|
|
21
|
-
icon: ReactNode;
|
|
22
|
-
/** The group's name: the sidebar row, the heading over its cards, the phone list. */
|
|
23
|
-
title: string;
|
|
24
|
-
/** One line under the heading and in the phone list, where it is cut to one line. */
|
|
25
|
-
help: string;
|
|
26
|
-
/**
|
|
27
|
-
* 0.48 (keksdose live #450): a count or a mark drawn on the group's ROW — at the end of
|
|
28
|
-
* its desktop sidebar row and before the chevron of its phone list row — never on the
|
|
29
|
-
* heading over its cards. The admin area's waiting work: `<AdminWaitingBadge count={n} />`
|
|
30
|
-
* (nothing for 0), so the account menu's badge leads to the section that holds it. It
|
|
31
|
-
* sits inside the row's link and is read with its name, so say what the number is (the
|
|
32
|
-
* waiting pill does: "3, 3 waiting"). While the page is searched the sidebar shows the
|
|
33
|
-
* hit count in its place. Default: none.
|
|
34
|
-
*/
|
|
35
|
-
badge?: ReactNode;
|
|
36
|
-
/**
|
|
37
|
-
* `false` hides the group: no row, no hits, and its path acts as an unknown one — it
|
|
38
|
-
* lands on the default group (desktop) or the list (phone), never on a 404 (§3.1).
|
|
39
|
-
* kastlan's `/admin/billing` while billing is off. Default: visible.
|
|
40
|
-
*/
|
|
41
|
-
visible?: boolean;
|
|
42
|
-
/**
|
|
43
|
-
* 0.43: the group shows with no visible entry — a page of its own rather than of setting
|
|
44
|
-
* cards (the admin area's Overview, whose tiles are no settings; `adminSections` sets
|
|
45
|
-
* it). `visible: false` still hides it. Default: a group shows only with an entry once
|
|
46
|
-
* `entries` are given (§4.1).
|
|
47
|
-
*/
|
|
48
|
-
standalone?: boolean;
|
|
49
|
-
}
|
|
50
|
-
|
|
51
|
-
/** One setting, and the card that holds it (§4.1). */
|
|
52
|
-
export interface SettingsEntry<G extends string = string> {
|
|
53
|
-
/** Unique within the catalogue. */
|
|
54
|
-
id: string;
|
|
55
|
-
/** The group whose page shows the card. */
|
|
56
|
-
group: G;
|
|
57
|
-
/** The card's DOM id, unique on the page — the `?focus=` target. Several entries may
|
|
58
|
-
* share one: a card that holds four settings has four entries. */
|
|
59
|
-
anchor: string;
|
|
60
|
-
/** What a search hit says. */
|
|
61
|
-
title: string;
|
|
62
|
-
/** Localized, space-separated words people type that the title does not contain
|
|
63
|
-
* ("dark night" for the theme, "2fa totp" for two-factor). Never shown. */
|
|
64
|
-
keywords?: string;
|
|
65
|
-
/**
|
|
66
|
-
* `false` drops the entry from the page's search and ⌘K. A group whose entries are
|
|
67
|
-
* ALL hidden is hidden with them (§4.1): a demo session marks every card it is refused
|
|
68
|
-
* (passkeys, 2FA, export, deletion …) and so never sees a page of cards that each
|
|
69
|
-
* answer 403. Default: visible.
|
|
70
|
-
*/
|
|
71
|
-
visible?: boolean;
|
|
72
|
-
}
|
|
73
|
-
|
|
74
|
-
/**
|
|
75
|
-
* The groups that show, in their order: not `visible: false`, and — when `entries` is
|
|
76
|
-
* given — holding at least one visible entry (§4.1: Kurvenschmiede's notifications group
|
|
77
|
-
* stays hidden until it has a card) or `standalone` (0.43). Without `entries` only the
|
|
78
|
-
* groups' own flag counts.
|
|
79
|
-
*/
|
|
80
|
-
export function visibleSettingsGroups<G extends string>(
|
|
81
|
-
groups: readonly SettingsGroup<G>[],
|
|
82
|
-
entries?: readonly SettingsEntry<G>[],
|
|
83
|
-
): SettingsGroup<G>[] {
|
|
84
|
-
if (!entries) return groups.filter((g) => g.visible !== false);
|
|
85
|
-
const filled = new Set<G>();
|
|
86
|
-
for (const e of entries) if (e.visible !== false) filled.add(e.group);
|
|
87
|
-
return groups.filter((g) => g.visible !== false && (g.standalone === true || filled.has(g.id)));
|
|
88
|
-
}
|
|
89
|
-
|
|
90
|
-
/** The visible entries of the visible groups — what search may find. */
|
|
91
|
-
export function visibleSettingsEntries<G extends string>(
|
|
92
|
-
groups: readonly SettingsGroup<G>[],
|
|
93
|
-
entries: readonly SettingsEntry<G>[],
|
|
94
|
-
): SettingsEntry<G>[] {
|
|
95
|
-
const shown = new Set(visibleSettingsGroups(groups, entries).map((g) => g.id));
|
|
96
|
-
return entries.filter((e) => e.visible !== false && shown.has(e.group));
|
|
97
|
-
}
|
|
98
|
-
|
|
99
|
-
/** `basePath` without a trailing slash: "/settings/" and "/settings" are one page. */
|
|
100
|
-
export function normalizeSettingsBase(basePath: string): string {
|
|
101
|
-
const trimmed = basePath.replace(/\/+$/, "");
|
|
102
|
-
return trimmed.startsWith("/") || trimmed === "" ? trimmed : `/${trimmed}`;
|
|
103
|
-
}
|
|
104
|
-
|
|
105
|
-
/** `/settings/<group>`, and `?focus=<anchor>` when a card is named (§3.4). */
|
|
106
|
-
export function settingsHref(basePath: string, group: string, anchor?: string): string {
|
|
107
|
-
const path = `${normalizeSettingsBase(basePath)}/${group}`;
|
|
108
|
-
return anchor ? `${path}?focus=${encodeURIComponent(anchor)}` : path;
|
|
109
|
-
}
|
|
110
|
-
|
|
111
|
-
/** "dark night" → ["dark", "night"]. */
|
|
112
|
-
export function settingsKeywords(keywords: string | undefined): string[] {
|
|
113
|
-
return keywords ? keywords.split(/\s+/).filter(Boolean) : [];
|
|
114
|
-
}
|
|
115
|
-
|
|
116
|
-
export interface SettingsSearchEntriesOptions {
|
|
117
|
-
/** `/settings` or `/admin` — the hits link to `<basePath>/<group>?focus=<anchor>`. */
|
|
118
|
-
basePath: string;
|
|
119
|
-
}
|
|
120
|
-
|
|
121
|
-
/**
|
|
122
|
-
* The catalogue as {@link GlobalSearch} entries (§3.4): each visible setting, under its
|
|
123
|
-
* group's name as the palette's section, linking to `/settings/<group>?focus=<anchor>` —
|
|
124
|
-
* the same link the page's own search hit is, so ⌘K, a tour and a mail all land the
|
|
125
|
-
* same way (§3.5). The group's name is a keyword too, as on the page: "security" lists
|
|
126
|
-
* the security group's settings.
|
|
127
|
-
*
|
|
128
|
-
* Ids are prefixed with the base path ("settings:theme", "admin:users") so a palette
|
|
129
|
-
* that also holds pages and actions keeps them unique.
|
|
130
|
-
*/
|
|
131
|
-
export function settingsSearchEntries<G extends string>(
|
|
132
|
-
groups: readonly SettingsGroup<G>[],
|
|
133
|
-
entries: readonly SettingsEntry<G>[],
|
|
134
|
-
options: SettingsSearchEntriesOptions,
|
|
135
|
-
): SearchEntry[] {
|
|
136
|
-
const base = normalizeSettingsBase(options.basePath);
|
|
137
|
-
const prefix = base.replace(/^\//, "").replace(/\//g, ":") || "settings";
|
|
138
|
-
const byId = new Map(visibleSettingsGroups(groups, entries).map((g) => [g.id, g]));
|
|
139
|
-
return visibleSettingsEntries(groups, entries).map((e) => {
|
|
140
|
-
const group = byId.get(e.group)!;
|
|
141
|
-
return {
|
|
142
|
-
id: `${prefix}:${e.id}`,
|
|
143
|
-
title: e.title,
|
|
144
|
-
keywords: [group.title, ...settingsKeywords(e.keywords)],
|
|
145
|
-
group: group.title,
|
|
146
|
-
icon: group.icon,
|
|
147
|
-
href: settingsHref(base, e.group, e.anchor),
|
|
148
|
-
};
|
|
149
|
-
});
|
|
150
|
-
}
|
|
@@ -1,33 +0,0 @@
|
|
|
1
|
-
import { createContext, useContext } from "react";
|
|
2
|
-
import type { SettingsHeadingTag } from "./settings-heading";
|
|
3
|
-
|
|
4
|
-
/**
|
|
5
|
-
* What {@link SettingsLayout} hands the cards it renders (docs/settings-harmonization.md
|
|
6
|
-
* §3.1, §3.7). Router-free on purpose, so `SettingsSection` and an app's cards can read
|
|
7
|
-
* it without importing the layout.
|
|
8
|
-
*/
|
|
9
|
-
export interface SettingsLayoutContextValue {
|
|
10
|
-
/** `/settings` or `/admin`, without a trailing slash. */
|
|
11
|
-
basePath: string;
|
|
12
|
-
/** The group on screen; `null` on a phone's list. */
|
|
13
|
-
group: string | null;
|
|
14
|
-
/** The path segment after the group — the surface a card owns (keksdose's swipe card). */
|
|
15
|
-
sub: string | null;
|
|
16
|
-
/**
|
|
17
|
-
* Select the card's sub-surface: `/settings/<group>/<sub>`, or the group alone with
|
|
18
|
-
* `null`. A replace, keeping the query and the history marker: switching a tab inside a
|
|
19
|
-
* card is not a place to go back to. The card never builds the path itself (§3.1).
|
|
20
|
-
*/
|
|
21
|
-
selectSub: (sub: string | null) => void;
|
|
22
|
-
/** The level the cards' titles are at: `h3` on a desktop, `h2` on a phone. */
|
|
23
|
-
headingLevel: SettingsHeadingTag;
|
|
24
|
-
/** Whether the catalogue has an entry with this anchor — `SettingsSection`'s check. */
|
|
25
|
-
hasAnchor: (anchor: string) => boolean;
|
|
26
|
-
}
|
|
27
|
-
|
|
28
|
-
export const SettingsLayoutContext = createContext<SettingsLayoutContextValue | null>(null);
|
|
29
|
-
|
|
30
|
-
/** The {@link SettingsLayout} around this card, or `null` outside one. */
|
|
31
|
-
export function useSettingsLayout(): SettingsLayoutContextValue | null {
|
|
32
|
-
return useContext(SettingsLayoutContext);
|
|
33
|
-
}
|