@eifi1/ui-kit 0.53.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 +96 -82
- package/dist/account/delete-account-setting.d.ts +3 -2
- package/dist/account/delete-account-setting.js.map +1 -1
- 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/auth/auth-errors.d.ts +36 -0
- package/dist/auth/auth-errors.js +20 -0
- package/dist/auth/auth-errors.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.d.ts +2 -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 +6 -4
- 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-option-list.d.ts +2 -1
- package/dist/components/currency-option-list.js +10 -3
- package/dist/components/currency-option-list.js.map +1 -1
- package/dist/components/currency-select.d.ts +3 -1
- package/dist/components/currency-select.js +2 -2
- package/dist/components/currency-select.js.map +1 -1
- package/dist/components/danger-confirm.d.ts +22 -1
- package/dist/components/danger-confirm.js +52 -30
- 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-filter-popover.d.ts +2 -1
- package/dist/components/data-table-filter-popover.js +3 -2
- package/dist/components/data-table-filter-popover.js.map +1 -1
- package/dist/components/data-table-filters.d.ts +33 -3
- package/dist/components/data-table-filters.js +6 -4
- package/dist/components/data-table-filters.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 +5 -1
- package/dist/components/dialog-frame.js +6 -2
- 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 +16 -7
- package/dist/components/mini-calendar.js.map +1 -1
- package/dist/components/modal.d.ts +48 -0
- package/dist/components/modal.js +26 -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/stat-tile.d.ts +21 -2
- package/dist/components/stat-tile.js +4 -2
- package/dist/components/stat-tile.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/currencies.d.ts +16 -2
- package/dist/currencies.js +2 -1
- package/dist/currencies.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-context-labels.js +2 -1
- package/dist/feedback/feedback-context-labels.js.map +1 -1
- package/dist/feedback/feedback-context.d.ts +19 -3
- package/dist/feedback/feedback-context.js +12 -1
- package/dist/feedback/feedback-context.js.map +1 -1
- package/dist/feedback/feedback-diagnostics.d.ts +17 -0
- package/dist/feedback/feedback-diagnostics.js +27 -0
- package/dist/feedback/feedback-diagnostics.js.map +1 -0
- package/dist/feedback/feedback-dialog.d.ts +10 -0
- package/dist/feedback/feedback-dialog.js +6 -4
- package/dist/feedback/feedback-dialog.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-record.d.ts +5 -0
- package/dist/feedback/feedback-record.js.map +1 -1
- package/dist/feedback/feedback-row-detail-labels.js +1 -0
- package/dist/feedback/feedback-row-detail-labels.js.map +1 -1
- package/dist/feedback/feedback-row-detail.d.ts +3 -0
- package/dist/feedback/feedback-row-detail.js +3 -0
- package/dist/feedback/feedback-row-detail.js.map +1 -1
- package/dist/feedback/feedback-submit-dialog.d.ts +5 -1
- package/dist/feedback/feedback-submit-dialog.js +15 -3
- package/dist/feedback/feedback-submit-dialog.js.map +1 -1
- package/dist/feedback/feedback-submit.d.ts +30 -2
- package/dist/feedback/feedback-submit.js +5 -2
- package/dist/feedback/feedback-submit.js.map +1 -1
- 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 +2 -1
- 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 +78 -4
- 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 +95 -5
- package/dist/i18n/locales/en.js.map +3 -3
- package/dist/i18n/locales/es.js +74 -4
- package/dist/i18n/locales/es.js.map +1 -1
- package/dist/i18n/locales/fr.js +75 -3
- package/dist/i18n/locales/fr.js.map +1 -1
- package/dist/i18n/locales/hu.js +77 -4
- package/dist/i18n/locales/hu.js.map +1 -1
- package/dist/i18n/locales/it.js +77 -4
- package/dist/i18n/locales/it.js.map +1 -1
- package/dist/i18n/locales/zh.js +74 -4
- 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 +27 -8
- package/dist/index.js +41 -2
- 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 +36 -4
- package/dist/lib/dates.js +49 -13
- 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/format.d.ts +37 -2
- package/dist/lib/format.js +25 -1
- package/dist/lib/format.js.map +1 -1
- package/dist/lib/intl-cache.d.ts +4 -2
- package/dist/lib/intl-cache.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/lib/translation-review.d.ts +26 -0
- package/dist/lib/translation-review.js +14 -0
- package/dist/lib/translation-review.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 -341
- 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 -370
- 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 -815
- 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 -594
- 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 -180
- package/src/components/currency-select.tsx +0 -341
- package/src/components/danger-confirm-labels.ts +0 -20
- package/src/components/danger-confirm.tsx +0 -934
- 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 -281
- package/src/components/data-table-filters.ts +0 -287
- 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 -276
- 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 -789
- package/src/components/modal.tsx +0 -505
- 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 -558
- 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 -725
- 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 -70
- 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 -10
- package/src/feedback/feedback-context.tsx +0 -213
- package/src/feedback/feedback-crash.ts +0 -547
- package/src/feedback/feedback-dialog-labels.ts +0 -29
- package/src/feedback/feedback-dialog.tsx +0 -440
- 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 -423
- 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 -30
- package/src/feedback/feedback-row-detail.tsx +0 -858
- package/src/feedback/feedback-status-undo.ts +0 -109
- package/src/feedback/feedback-submit-dialog.tsx +0 -118
- package/src/feedback/feedback-submit.tsx +0 -237
- 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 -189
- 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 -2057
- 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 -1997
- package/src/i18n/locales/fr.ts +0 -2035
- package/src/i18n/locales/hu.ts +0 -2002
- package/src/i18n/locales/it.ts +0 -2012
- package/src/i18n/locales/zh.ts +0 -1910
- 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 -1179
- 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 -266
- 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 -522
- 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 -25
- 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 -717
- 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,298 +0,0 @@
|
|
|
1
|
-
import { useLayoutEffect, useRef, useState } from "react";
|
|
2
|
-
import type { ComponentPropsWithRef, ElementType, ReactNode } from "react";
|
|
3
|
-
import { cn } from "../lib/cn";
|
|
4
|
-
import { SECTION_LABEL_CLASS } from "./text";
|
|
5
|
-
import { useDocumentTitle } from "../hooks/use-document-title";
|
|
6
|
-
import { PageHeaderTrailContext } from "./page-header-context";
|
|
7
|
-
|
|
8
|
-
/**
|
|
9
|
-
* `md` (default) is kastlan's `text-2xl` page title from `sm` up, a step smaller on a
|
|
10
|
-
* phone; `sm` is lenkbank's `text-lg` title on a dense tool page (projects-page.tsx).
|
|
11
|
-
*
|
|
12
|
-
* `compact` (0.13) is keksdose's page title (keksdose F4): `text-xl font-semibold` at
|
|
13
|
-
* EVERY width — budgets, rules, accounts, transactions and budget pages all write
|
|
14
|
-
* exactly that `<h1>` by hand. It is `md`'s phone size without `md`'s step up to
|
|
15
|
-
* `text-2xl` on a wider screen, and without its `tracking-tight`, which keksdose's
|
|
16
|
-
* titles never had. A word and not a letter for the reason `ProgressBar`'s `slim` is
|
|
17
|
-
* one: the letters are taken in order, and there is none between `sm` and `md` — an
|
|
18
|
-
* `lg` or `xl` at `text-xl` would read as LARGER than `md`, which from `sm` up it is
|
|
19
|
-
* not.
|
|
20
|
-
*/
|
|
21
|
-
export type PageHeaderSize = "sm" | "compact" | "md";
|
|
22
|
-
|
|
23
|
-
const TITLE: Record<PageHeaderSize, string> = {
|
|
24
|
-
sm: "text-lg font-semibold",
|
|
25
|
-
compact: "text-xl font-semibold",
|
|
26
|
-
md: "text-xl font-semibold tracking-tight sm:text-2xl",
|
|
27
|
-
};
|
|
28
|
-
|
|
29
|
-
/**
|
|
30
|
-
* How the title block and the actions sit below the `sm` breakpoint. From `sm` up both
|
|
31
|
-
* layouts are one row: title block at the start, actions at the end.
|
|
32
|
-
*/
|
|
33
|
-
export type PageHeaderMobileLayout = "stacked" | "inline";
|
|
34
|
-
|
|
35
|
-
/**
|
|
36
|
-
* `stacked` at Large and Extra large on a phone (0.32.2, kastlan's 0.32.1 report;
|
|
37
|
-
* docs/text-size-harmonization.md §4, as FormActions does): the actions take the full
|
|
38
|
-
* width, one under the other. Side by side in 240 px of layout, two buttons each wrapped
|
|
39
|
-
* their label onto three lines. `large:max-sm:`, the scaled phone width, so Normal and
|
|
40
|
-
* every wider screen keep their row; `inline` is for actions known to fit, and stays.
|
|
41
|
-
*/
|
|
42
|
-
const STACK_ACTIONS_AT_LARGE = "large:max-sm:flex-col large:max-sm:items-stretch large:max-sm:[&>*]:w-full";
|
|
43
|
-
|
|
44
|
-
const ROW: Record<PageHeaderMobileLayout, string> = {
|
|
45
|
-
stacked: "flex-col gap-3 sm:flex-row sm:items-start sm:justify-between sm:gap-4",
|
|
46
|
-
inline: "flex-row items-center justify-between gap-2 sm:gap-4",
|
|
47
|
-
};
|
|
48
|
-
|
|
49
|
-
/**
|
|
50
|
-
* Where the actions sit on the title block's height, in the one row the header is from
|
|
51
|
-
* `sm` up (and on a phone too when {@link PageHeaderMobileLayout} is `inline`, the only
|
|
52
|
-
* layout that has a row there). Unset keeps each layout's own: `start` for `stacked`,
|
|
53
|
-
* `center` for `inline`.
|
|
54
|
-
*/
|
|
55
|
-
export type PageHeaderActionsAlign = "start" | "center" | "end";
|
|
56
|
-
|
|
57
|
-
/** Applied to the ROW, so the title block and the actions are aligned against each
|
|
58
|
-
* other on one cross axis. 0.14.0 put `self-*` on the actions box alone, which moved
|
|
59
|
-
* nothing when the actions were the taller item — they already filled the row, and
|
|
60
|
-
* the title stayed at the top (keksdose H2, reports-page's two-line labelled
|
|
61
|
-
* CurrencySelect). Per layout, because `stacked` is a column on a phone, where
|
|
62
|
-
* `items-center` would centre everything HORIZONTALLY — so it aligns from `sm` up. */
|
|
63
|
-
const ROW_ALIGN: Record<PageHeaderMobileLayout, Record<PageHeaderActionsAlign, string>> = {
|
|
64
|
-
stacked: { start: "sm:items-start", center: "sm:items-center", end: "sm:items-end" },
|
|
65
|
-
inline: { start: "items-start", center: "items-center", end: "items-end" },
|
|
66
|
-
};
|
|
67
|
-
|
|
68
|
-
export interface PageHeaderProps extends Omit<ComponentPropsWithRef<"div">, "title"> {
|
|
69
|
-
title: ReactNode;
|
|
70
|
-
/** A sentence under the title. */
|
|
71
|
-
description?: ReactNode;
|
|
72
|
-
/** Buttons for the page — "New", "Export". At the title's end from `sm` up; under it,
|
|
73
|
-
* wrapping, on a phone — unless {@link mobileLayout} is `inline`. */
|
|
74
|
-
actions?: ReactNode;
|
|
75
|
-
/** A `Breadcrumbs` trail, drawn above everything else. Inside a header with a title
|
|
76
|
-
* it hides its current entry (the title names it) and is drawn only when an entry
|
|
77
|
-
* other than home is left — `Breadcrumbs.hideCurrent` (0.49 KIT-9). */
|
|
78
|
-
breadcrumbs?: ReactNode;
|
|
79
|
-
/**
|
|
80
|
-
* The window's title (`document.title`) while the header is mounted (0.49 KIT-9),
|
|
81
|
-
* through `useDocumentTitle` and the provider's format ("{page} · {section} · {app}",
|
|
82
|
-
* `appName` as the app). A string is the page; an array is `[page, section]` (or
|
|
83
|
-
* `[page, section, app]`); `false` leaves the window's title alone.
|
|
84
|
-
*
|
|
85
|
-
* Default: the `title` when it is a string, and only for the page's own header
|
|
86
|
-
* (`as="h1"`) — a tab's `h2` header does not rename the window.
|
|
87
|
-
*/
|
|
88
|
-
documentTitle?: string | ReadonlyArray<string | null | undefined> | false;
|
|
89
|
-
/** A small uppercase line above the title — the section or the kind of record
|
|
90
|
-
* ("Building", "Settings"). The section-label type. */
|
|
91
|
-
eyebrow?: ReactNode;
|
|
92
|
-
/** The title's element. Default `h1`: a page has one, and this is it. `h2` for a
|
|
93
|
-
* header inside a page that already has its `h1` (a tab's own header). */
|
|
94
|
-
as?: "h1" | "h2" | "h3";
|
|
95
|
-
size?: PageHeaderSize;
|
|
96
|
-
/**
|
|
97
|
-
* `stacked` (default): on a phone the actions drop under the title and wrap, so a
|
|
98
|
-
* row of three buttons never pushes the title off the screen.
|
|
99
|
-
*
|
|
100
|
-
* `inline`: the actions stay beside the title on a phone too, vertically centred on
|
|
101
|
-
* it — keksdose's headers (transactions-page.tsx:515, `flex items-center
|
|
102
|
-
* justify-between gap-2`), which carry one or two icon-sized controls and were tuned
|
|
103
|
-
* for the phone in live #263. Adopting `PageHeader` must not undo that tuning, so the
|
|
104
|
-
* row stays a row (keksdose F4). The actions do NOT wrap or shrink here: `inline` is
|
|
105
|
-
* for a header whose actions are known to fit beside a phone-width title (an icon
|
|
106
|
-
* button, a month picker); a long title wraps to make room for them instead.
|
|
107
|
-
*/
|
|
108
|
-
mobileLayout?: PageHeaderMobileLayout;
|
|
109
|
-
/**
|
|
110
|
-
* A second group of actions that gets its OWN full-width row under the header on a
|
|
111
|
-
* phone, and joins the actions' row from `sm` up, between the title and
|
|
112
|
-
* {@link actions}.
|
|
113
|
-
*
|
|
114
|
-
* keksdose's budget page (budget-page.tsx, feedback #60) is the case: title and month
|
|
115
|
-
* navigation on row 1, the fold/unfold toggles on row 2 on a phone — "two tidy rows
|
|
116
|
-
* instead of the old ragged justify-between overflow" — and one row, title | toggles |
|
|
117
|
-
* month nav, on a wider screen. It builds that by hand with a wrapping flex row and
|
|
118
|
-
* swapped order utilities; adopting `PageHeader` (keksdose G6b) must not lose it.
|
|
119
|
-
* There: `actions` is the month navigation, this is the toggles.
|
|
120
|
-
*
|
|
121
|
-
* The DOM order is title, `actions`, `secondaryActions` — the phone's visual order,
|
|
122
|
-
* and the one a screen reader and the Tab key follow at every width. From `sm` up the
|
|
123
|
-
* two groups swap places visually only, which keeps the page's primary control (the
|
|
124
|
-
* month) at the row's end, where keksdose had it, and first in reading order. The
|
|
125
|
-
* breakpoint is `sm`, the one {@link mobileLayout} switches at, not keksdose's `md`:
|
|
126
|
-
* one header, one breakpoint.
|
|
127
|
-
*/
|
|
128
|
-
secondaryActions?: ReactNode;
|
|
129
|
-
/**
|
|
130
|
-
* The actions' vertical alignment against the title block — see
|
|
131
|
-
* {@link PageHeaderActionsAlign}. Unset keeps the layout's own.
|
|
132
|
-
*
|
|
133
|
-
* keksdose's reports page (reports-page.tsx, keksdose G8) carries a LABELLED
|
|
134
|
-
* `CurrencySelect` as its action: a field with its label on top is taller than the
|
|
135
|
-
* title, and `stacked`'s default top alignment hangs it from the title's cap height
|
|
136
|
-
* with its control well below the title's line. `center` sets it on the title's
|
|
137
|
-
* middle, as that page's hand-written `items-center` row did. It aligns the whole row
|
|
138
|
-
* (title block and actions against each other), since 0.14.1: 0.14.0 moved only the
|
|
139
|
-
* actions box, which did nothing when the actions were the taller item (keksdose H2).
|
|
140
|
-
*/
|
|
141
|
-
actionsAlign?: PageHeaderActionsAlign;
|
|
142
|
-
/**
|
|
143
|
-
* One line, cut with an ellipsis, instead of the default breaking of a long word onto
|
|
144
|
-
* as many lines as it needs.
|
|
145
|
-
*
|
|
146
|
-
* keksdose's payees page (payees-page.tsx, live #263, keksdose G6a) wraps its title in
|
|
147
|
-
* its own truncating span so a long name gives way to the `inline` header's actions
|
|
148
|
-
* instead of pushing them. This is that span's behaviour on the heading itself; the
|
|
149
|
-
* title block is already allowed to shrink below its content, which is what lets the
|
|
150
|
-
* cut happen inside a flex row.
|
|
151
|
-
*
|
|
152
|
-
* The full title stays in the DOM as the heading's text, so a screen reader and the
|
|
153
|
-
* document outline read all of it. There is deliberately no native `title` tooltip:
|
|
154
|
-
* the kit does not use them (not on touch, not on keyboard focus, not styled).
|
|
155
|
-
*
|
|
156
|
-
* At Normal only: from Large up the title wraps (`truncate-until-large`, text size
|
|
157
|
-
* §10.17; round 0.34 T1), as nothing is cut at Large — the actions then share the row
|
|
158
|
-
* with a taller title block.
|
|
159
|
-
*/
|
|
160
|
-
truncateTitle?: boolean;
|
|
161
|
-
}
|
|
162
|
-
|
|
163
|
-
const TITLED = { titled: true };
|
|
164
|
-
const UNTITLED = { titled: false };
|
|
165
|
-
|
|
166
|
-
/**
|
|
167
|
-
* A page's head: optional breadcrumbs, an eyebrow, the title, a description, and the
|
|
168
|
-
* page's actions.
|
|
169
|
-
*
|
|
170
|
-
* kastlan's (shared/components/display/page-header.tsx) is the model — title and
|
|
171
|
-
* description on one side, actions on the other, stacked on a phone — and this adds
|
|
172
|
-
* what its pages kept writing around it: a trail above, an eyebrow, a `ReactNode`
|
|
173
|
-
* title (a status chip beside the name), and actions that WRAP when there are more
|
|
174
|
-
* than fit a phone's width, instead of running off it. No outer margin: the page's
|
|
175
|
-
* own rhythm (`space-y-*`, a grid gap) places it.
|
|
176
|
-
*/
|
|
177
|
-
export function PageHeader({
|
|
178
|
-
title,
|
|
179
|
-
description,
|
|
180
|
-
actions,
|
|
181
|
-
breadcrumbs,
|
|
182
|
-
eyebrow,
|
|
183
|
-
as = "h1",
|
|
184
|
-
size = "md",
|
|
185
|
-
mobileLayout = "stacked",
|
|
186
|
-
secondaryActions,
|
|
187
|
-
actionsAlign,
|
|
188
|
-
truncateTitle = false,
|
|
189
|
-
documentTitle,
|
|
190
|
-
className,
|
|
191
|
-
...rest
|
|
192
|
-
}: PageHeaderProps) {
|
|
193
|
-
const Heading = as as ElementType;
|
|
194
|
-
useDocumentTitle(
|
|
195
|
-
documentTitle === false
|
|
196
|
-
? []
|
|
197
|
-
: documentTitle === undefined
|
|
198
|
-
? as === "h1" && typeof title === "string"
|
|
199
|
-
? [title]
|
|
200
|
-
: []
|
|
201
|
-
: typeof documentTitle === "string"
|
|
202
|
-
? [documentTitle]
|
|
203
|
-
: documentTitle,
|
|
204
|
-
);
|
|
205
|
-
const titled = title != null && title !== false && title !== "";
|
|
206
|
-
const hasSecondary = secondaryActions != null;
|
|
207
|
-
const wrapsSecondary = hasSecondary && mobileLayout === "inline";
|
|
208
|
-
const align = actionsAlign != null ? ROW_ALIGN[mobileLayout][actionsAlign] : undefined;
|
|
209
|
-
// keksdose H1: in `inline` the title block could shrink below its longest word, and
|
|
210
|
-
// `break-words` then split "Monatsbudget" into "Monatsbudg" / "et" beside the actions.
|
|
211
|
-
// Unless it truncates, the title keeps its longest word (min-content) and the ROW
|
|
212
|
-
// wraps instead: actions that do not fit go to a line of their own, as the app's old
|
|
213
|
-
// `flex-wrap` header did.
|
|
214
|
-
const keepsWords = mobileLayout === "inline" && !truncateTitle;
|
|
215
|
-
// keksdose, after H1: once the actions have wrapped below the title, the phone's
|
|
216
|
-
// header was THREE rows — title / actions / secondary — where the app's old header
|
|
217
|
-
// shared the second row between the month nav and the toggles (~48px of phone
|
|
218
|
-
// height). So the secondary group's full-width basis (G6b: a row of its own) is
|
|
219
|
-
// dropped exactly when the actions already sit below the title; then it joins their
|
|
220
|
-
// row if it fits, and wraps under them if not. While the actions share the title's
|
|
221
|
-
// row, nothing changes: the secondary group never climbs onto the title's row.
|
|
222
|
-
//
|
|
223
|
-
// CSS cannot see "the previous item wrapped", so it is measured — by a
|
|
224
|
-
// ResizeObserver, whose first callback runs on `observe`. It is stable: the
|
|
225
|
-
// secondary group comes after the actions, so its basis cannot move them. No
|
|
226
|
-
// ResizeObserver (jsdom) or no layout keeps the basis, the 0.14.0 layout.
|
|
227
|
-
const measuresWrap = keepsWords && hasSecondary && actions != null;
|
|
228
|
-
const titleRef = useRef<HTMLDivElement>(null);
|
|
229
|
-
const actionsRef = useRef<HTMLDivElement>(null);
|
|
230
|
-
const [actionsWrapped, setActionsWrapped] = useState(false);
|
|
231
|
-
useLayoutEffect(() => {
|
|
232
|
-
const titleBox = titleRef.current;
|
|
233
|
-
const actionsBox = actionsRef.current;
|
|
234
|
-
if (!measuresWrap || !titleBox || !actionsBox || typeof ResizeObserver === "undefined") return;
|
|
235
|
-
const observer = new ResizeObserver(() => {
|
|
236
|
-
const t = titleBox.getBoundingClientRect();
|
|
237
|
-
const a = actionsBox.getBoundingClientRect();
|
|
238
|
-
// Unmeasured (display: none, no layout): keep the full-width basis.
|
|
239
|
-
setActionsWrapped(t.height > 0 && a.height > 0 && a.top >= t.bottom - 1);
|
|
240
|
-
});
|
|
241
|
-
observer.observe(titleBox);
|
|
242
|
-
observer.observe(actionsBox);
|
|
243
|
-
if (titleBox.parentElement) observer.observe(titleBox.parentElement);
|
|
244
|
-
return () => observer.disconnect();
|
|
245
|
-
}, [measuresWrap]);
|
|
246
|
-
return (
|
|
247
|
-
<div {...rest} className={cn("flex min-w-0 flex-col gap-2", className)}>
|
|
248
|
-
{breadcrumbs != null && (
|
|
249
|
-
<PageHeaderTrailContext.Provider value={titled ? TITLED : UNTITLED}>
|
|
250
|
-
{breadcrumbs}
|
|
251
|
-
</PageHeaderTrailContext.Provider>
|
|
252
|
-
)}
|
|
253
|
-
{/* With a second group, `inline` wraps so that group's full-width basis puts it
|
|
254
|
-
on a row of its own on a phone (`stacked` is a column there already, and a
|
|
255
|
-
basis would size a column item's HEIGHT); from `sm` up the row stops wrapping
|
|
256
|
-
and the order utilities seat it between the title and the actions. Without
|
|
257
|
-
one, nothing changes. */}
|
|
258
|
-
<div
|
|
259
|
-
className={cn(
|
|
260
|
-
"flex min-w-0",
|
|
261
|
-
ROW[mobileLayout],
|
|
262
|
-
keepsWords ? "flex-wrap" : wrapsSecondary && "flex-wrap sm:flex-nowrap",
|
|
263
|
-
align,
|
|
264
|
-
)}
|
|
265
|
-
>
|
|
266
|
-
<div ref={titleRef} className={cn("flex-1", keepsWords ? "min-w-min" : "min-w-0")}>
|
|
267
|
-
{eyebrow != null && <p className={cn(SECTION_LABEL_CLASS.xs, "mb-1")}>{eyebrow}</p>}
|
|
268
|
-
<Heading className={cn(truncateTitle ? "truncate-until-large" : "break-words", "text-primary", TITLE[size])}>
|
|
269
|
-
{title}
|
|
270
|
-
</Heading>
|
|
271
|
-
{description != null && <p className="mt-1 text-sm text-muted">{description}</p>}
|
|
272
|
-
</div>
|
|
273
|
-
{actions != null && (
|
|
274
|
-
<div
|
|
275
|
-
ref={actionsRef}
|
|
276
|
-
className={cn(
|
|
277
|
-
"flex shrink-0 flex-wrap items-center gap-2",
|
|
278
|
-
hasSecondary && "sm:order-2",
|
|
279
|
-
mobileLayout === "stacked" && STACK_ACTIONS_AT_LARGE,
|
|
280
|
-
)}
|
|
281
|
-
>
|
|
282
|
-
{actions}
|
|
283
|
-
</div>
|
|
284
|
-
)}
|
|
285
|
-
{hasSecondary && (
|
|
286
|
-
<div
|
|
287
|
-
className={cn(
|
|
288
|
-
"flex flex-wrap items-center gap-2 sm:order-1 sm:shrink-0",
|
|
289
|
-
wrapsSecondary && (measuresWrap && actionsWrapped ? "sm:basis-auto" : "basis-full sm:basis-auto"),
|
|
290
|
-
)}
|
|
291
|
-
>
|
|
292
|
-
{secondaryActions}
|
|
293
|
-
</div>
|
|
294
|
-
)}
|
|
295
|
-
</div>
|
|
296
|
-
</div>
|
|
297
|
-
);
|
|
298
|
-
}
|
|
@@ -1,22 +0,0 @@
|
|
|
1
|
-
// The English words of ./password-strength, in a module with no component code: the English
|
|
2
|
-
// catalogue (src/i18n/defaults.ts) imports them without the component, so `en` loads as one
|
|
3
|
-
// chunk like the other languages (0.34, KS U8). ./password-strength re-exports them.
|
|
4
|
-
|
|
5
|
-
import type { PasswordStrengthLabels } from "./password-strength";
|
|
6
|
-
|
|
7
|
-
export const DEFAULT_PASSWORD_STRENGTH_LABELS: PasswordStrengthLabels = {
|
|
8
|
-
tooShort: "Too short",
|
|
9
|
-
weak: "Weak",
|
|
10
|
-
fair: "Fair",
|
|
11
|
-
good: "Good",
|
|
12
|
-
strong: "Strong",
|
|
13
|
-
announcement: (level) => `Password strength: ${level}`,
|
|
14
|
-
ruleLength: (minLength) => `At least ${minLength} characters`,
|
|
15
|
-
ruleCase: "Upper and lower case",
|
|
16
|
-
ruleDigit: "A number",
|
|
17
|
-
ruleSymbol: "A symbol",
|
|
18
|
-
optional: (rule) => `${rule} (optional)`,
|
|
19
|
-
met: "Met:",
|
|
20
|
-
notMet: "Not met:",
|
|
21
|
-
tooLong: (maxBytes) => `At most ${maxBytes} characters (accents and emoji count for more than one).`,
|
|
22
|
-
};
|
|
@@ -1,241 +0,0 @@
|
|
|
1
|
-
import { useEffect, useRef } from "react";
|
|
2
|
-
import type { ComponentPropsWithRef } from "react";
|
|
3
|
-
import { cn } from "../lib/cn";
|
|
4
|
-
import { useAnnounce } from "../hooks/use-announce";
|
|
5
|
-
import { useKitLabels, type LabelOverride } from "../i18n/kit-labels";
|
|
6
|
-
import { DEFAULT_PASSWORD_STRENGTH_LABELS } from "./password-strength-labels";
|
|
7
|
-
|
|
8
|
-
/**
|
|
9
|
-
* The bar, the word and the advisory checklist under a field where someone is
|
|
10
|
-
* CHOOSING a secret.
|
|
11
|
-
*
|
|
12
|
-
* Ported from Keksdose (`features/auth/password-strength-meter.tsx`), where one meter
|
|
13
|
-
* sits under the sign-in password and the encryption passphrase alike — a copy per
|
|
14
|
-
* form is what had let the passphrase dialogs ship with no meter at all. Three things
|
|
15
|
-
* changed on the way in:
|
|
16
|
-
*
|
|
17
|
-
* 1. **Tokens, not palette.** The four fills were red/amber/lime/emerald utilities;
|
|
18
|
-
* they are `--danger` → `--warning` → `--success` now, so a consumer re-pointing
|
|
19
|
-
* those families re-skins the meter with them.
|
|
20
|
-
* 2. **Not colour alone.** The level is always written out beside the bar, and each
|
|
21
|
-
* checklist item says "met" / "not met" to a screen reader — the ✓/○ glyphs are
|
|
22
|
-
* decoration and hidden.
|
|
23
|
-
* 3. **Announced.** A level change is spoken through a polite live region
|
|
24
|
-
* ({@link useAnnounce}); the bar itself is `aria-hidden`, because four coloured
|
|
25
|
-
* strips read out as four empty groups.
|
|
26
|
-
*
|
|
27
|
-
* Advisory only, as in Keksdose: nothing here blocks a submit. The caller decides what
|
|
28
|
-
* is required — {@link passwordRules} marks `length` as the one rule that usually is,
|
|
29
|
-
* so a form can gate on it with the same function the checklist draws from.
|
|
30
|
-
*
|
|
31
|
-
* Dependency-free on purpose. zxcvbn is ~400 kB of dictionaries, and neither consumer
|
|
32
|
-
* ships it; a host that does can pass its scorer as `score` and keep the rest.
|
|
33
|
-
*/
|
|
34
|
-
|
|
35
|
-
/* ── The scorer ──────────────────────────────────────────────────────────── */
|
|
36
|
-
|
|
37
|
-
/** 0 = too short (or empty), 4 = strong. */
|
|
38
|
-
export type PasswordStrengthScore = 0 | 1 | 2 | 3 | 4;
|
|
39
|
-
|
|
40
|
-
export type PasswordRuleId = "length" | "case" | "digit" | "symbol";
|
|
41
|
-
|
|
42
|
-
export interface PasswordRule {
|
|
43
|
-
id: PasswordRuleId;
|
|
44
|
-
met: boolean;
|
|
45
|
-
/** Only `length` is required; the rest are suggestions. */
|
|
46
|
-
required: boolean;
|
|
47
|
-
}
|
|
48
|
-
|
|
49
|
-
export interface PasswordScoreOptions {
|
|
50
|
-
/** The length below which a secret is "too short", whatever else it has. Keep it
|
|
51
|
-
* in step with the server's own minimum. Default 8. */
|
|
52
|
-
minLength?: number;
|
|
53
|
-
}
|
|
54
|
-
|
|
55
|
-
const DEFAULT_MIN_LENGTH = 8;
|
|
56
|
-
|
|
57
|
-
/** The checklist's rules, evaluated. Pure; the order is the order they are shown in. */
|
|
58
|
-
export function passwordRules(
|
|
59
|
-
value: string,
|
|
60
|
-
{ minLength = DEFAULT_MIN_LENGTH }: PasswordScoreOptions = {},
|
|
61
|
-
): PasswordRule[] {
|
|
62
|
-
return [
|
|
63
|
-
// Code points, not UTF-16 units: an emoji is one character to the person typing it.
|
|
64
|
-
{ id: "length", met: [...value].length >= minLength, required: true },
|
|
65
|
-
{ id: "case", met: /\p{Ll}/u.test(value) && /\p{Lu}/u.test(value), required: false },
|
|
66
|
-
{ id: "digit", met: /\p{Nd}/u.test(value), required: false },
|
|
67
|
-
{ id: "symbol", met: /[^\p{L}\p{N}\s]/u.test(value), required: false },
|
|
68
|
-
];
|
|
69
|
-
}
|
|
70
|
-
|
|
71
|
-
/**
|
|
72
|
-
* A 0–4 strength bucket. Length dominates, because it genuinely dominates real-world
|
|
73
|
-
* guessing cost: one step each at `minLength`, `minLength + 4` and `minLength + 8`,
|
|
74
|
-
* and one more for at least two of the three variety rules.
|
|
75
|
-
*
|
|
76
|
-
* One addition over Keksdose's curve: a secret with fewer than four DISTINCT
|
|
77
|
-
* characters caps at 1. Sixteen `a`s are long, and nothing about them is strong.
|
|
78
|
-
*/
|
|
79
|
-
export function scorePassword(value: string, options: PasswordScoreOptions = {}): PasswordStrengthScore {
|
|
80
|
-
const minLength = options.minLength ?? DEFAULT_MIN_LENGTH;
|
|
81
|
-
const chars = [...value];
|
|
82
|
-
// Under the minimum is never anything but "too short", however varied.
|
|
83
|
-
if (chars.length === 0 || chars.length < minLength) return 0;
|
|
84
|
-
let score = 1;
|
|
85
|
-
if (chars.length >= minLength + 4) score += 1;
|
|
86
|
-
if (chars.length >= minLength + 8) score += 1;
|
|
87
|
-
const variety = passwordRules(value, { minLength }).filter((r) => !r.required && r.met).length;
|
|
88
|
-
if (variety >= 2) score += 1;
|
|
89
|
-
if (new Set(chars).size < 4) score = 1;
|
|
90
|
-
return Math.min(score, 4) as PasswordStrengthScore;
|
|
91
|
-
}
|
|
92
|
-
|
|
93
|
-
/** UTF-8 byte length — what a bcrypt-style ceiling counts. "ü" is two, an emoji four. */
|
|
94
|
-
export function passwordByteLength(value: string): number {
|
|
95
|
-
return new TextEncoder().encode(value).length;
|
|
96
|
-
}
|
|
97
|
-
|
|
98
|
-
/* ── Labels ──────────────────────────────────────────────────────────────── */
|
|
99
|
-
|
|
100
|
-
/** Every string the meter renders or speaks. */
|
|
101
|
-
export interface PasswordStrengthLabels {
|
|
102
|
-
/** The five level names, shown beside the bar. Score 0 … 4. */
|
|
103
|
-
tooShort: string;
|
|
104
|
-
weak: string;
|
|
105
|
-
fair: string;
|
|
106
|
-
good: string;
|
|
107
|
-
strong: string;
|
|
108
|
-
/** What the live region says when the level changes, given the level's name. */
|
|
109
|
-
announcement: (level: string) => string;
|
|
110
|
-
/** The length rule, given the minimum. */
|
|
111
|
-
ruleLength: (minLength: number) => string;
|
|
112
|
-
ruleCase: string;
|
|
113
|
-
ruleDigit: string;
|
|
114
|
-
ruleSymbol: string;
|
|
115
|
-
/** A suggestion rather than a requirement, given the rule's text. */
|
|
116
|
-
optional: (rule: string) => string;
|
|
117
|
-
/** Screen-reader-only state before each checklist item — the ✓/○ are hidden. */
|
|
118
|
-
met: string;
|
|
119
|
-
notMet: string;
|
|
120
|
-
/** Shown when the value is over `maxBytes`, given that ceiling. */
|
|
121
|
-
tooLong: (maxBytes: number) => string;
|
|
122
|
-
}
|
|
123
|
-
|
|
124
|
-
// Defined in ./password-strength-labels, which holds no component code (0.34, KS U8).
|
|
125
|
-
export { DEFAULT_PASSWORD_STRENGTH_LABELS };
|
|
126
|
-
|
|
127
|
-
const LEVEL_KEYS = ["tooShort", "weak", "fair", "good", "strong"] as const;
|
|
128
|
-
|
|
129
|
-
/* ── The meter ───────────────────────────────────────────────────────────── */
|
|
130
|
-
|
|
131
|
-
// The filled segments' colour per score. "Good" sits between the warning and the
|
|
132
|
-
// success hue rather than borrowing either, so 3 and 4 differ in colour as well as in
|
|
133
|
-
// segment count. Index 0 is never drawn — a too-short secret fills no segment.
|
|
134
|
-
const FILL: Record<PasswordStrengthScore, string> = {
|
|
135
|
-
0: "",
|
|
136
|
-
1: "bg-danger",
|
|
137
|
-
2: "bg-warning",
|
|
138
|
-
3: "bg-[color-mix(in_oklab,var(--success)_60%,var(--warning))]",
|
|
139
|
-
4: "bg-success",
|
|
140
|
-
};
|
|
141
|
-
|
|
142
|
-
export interface PasswordStrengthMeterProps extends ComponentPropsWithRef<"div"> {
|
|
143
|
-
/** The secret being chosen. Nothing visible renders while it is empty. */
|
|
144
|
-
value: string;
|
|
145
|
-
/** Replace the built-in scorer (e.g. with zxcvbn's `score`). Must be pure. */
|
|
146
|
-
score?: (value: string) => PasswordStrengthScore;
|
|
147
|
-
/** See {@link PasswordScoreOptions.minLength}. Drives the built-in scorer and the
|
|
148
|
-
* length rule's text. */
|
|
149
|
-
minLength?: number;
|
|
150
|
-
/** Show the checklist under the bar. Default `true`. */
|
|
151
|
-
showRequirements?: boolean;
|
|
152
|
-
/**
|
|
153
|
-
* A byte ceiling to warn about, if the secret has one — bcrypt reads at most 72
|
|
154
|
-
* BYTES. Leave it unset for a secret that has none (a passphrase stretched in the
|
|
155
|
-
* browser): inventing one talks people out of the long passphrase they chose.
|
|
156
|
-
*/
|
|
157
|
-
maxBytes?: number;
|
|
158
|
-
/** User-facing strings; see {@link PasswordStrengthLabels}. */
|
|
159
|
-
labels?: LabelOverride<PasswordStrengthLabels>;
|
|
160
|
-
}
|
|
161
|
-
|
|
162
|
-
/**
|
|
163
|
-
* Render directly under the password field. To have the field itself describe its
|
|
164
|
-
* strength, give this an `id` and point the input's `aria-describedby` at it.
|
|
165
|
-
*/
|
|
166
|
-
export function PasswordStrengthMeter({
|
|
167
|
-
value,
|
|
168
|
-
score: scoreProp,
|
|
169
|
-
minLength = DEFAULT_MIN_LENGTH,
|
|
170
|
-
showRequirements = true,
|
|
171
|
-
maxBytes,
|
|
172
|
-
labels: labelsProp,
|
|
173
|
-
className,
|
|
174
|
-
...rest
|
|
175
|
-
}: PasswordStrengthMeterProps) {
|
|
176
|
-
// Prop > <UiKitProvider> > English, like every labelled component in the kit.
|
|
177
|
-
const labels = useKitLabels("passwordStrength", DEFAULT_PASSWORD_STRENGTH_LABELS, labelsProp);
|
|
178
|
-
const { announce, regionProps } = useAnnounce();
|
|
179
|
-
|
|
180
|
-
const empty = value.length === 0;
|
|
181
|
-
const score = empty ? 0 : scoreProp ? scoreProp(value) : scorePassword(value, { minLength });
|
|
182
|
-
const level = labels[LEVEL_KEYS[score]];
|
|
183
|
-
|
|
184
|
-
// Speak on a CHANGE of level only — not on every keystroke, and not on mount (a
|
|
185
|
-
// prefilled field has not changed anything). Clearing the field says nothing: the
|
|
186
|
-
// user did that on purpose and the meter disappearing is the whole news.
|
|
187
|
-
const previous = useRef(score);
|
|
188
|
-
useEffect(() => {
|
|
189
|
-
if (previous.current === score) return;
|
|
190
|
-
previous.current = score;
|
|
191
|
-
if (!empty) announce(labels.announcement(level));
|
|
192
|
-
}, [score, empty, level, labels, announce]);
|
|
193
|
-
|
|
194
|
-
const rules = passwordRules(value, { minLength });
|
|
195
|
-
const ruleText: Record<PasswordRuleId, string> = {
|
|
196
|
-
length: labels.ruleLength(minLength),
|
|
197
|
-
case: labels.ruleCase,
|
|
198
|
-
digit: labels.ruleDigit,
|
|
199
|
-
symbol: labels.ruleSymbol,
|
|
200
|
-
};
|
|
201
|
-
const tooLong = maxBytes !== undefined && passwordByteLength(value) > maxBytes;
|
|
202
|
-
|
|
203
|
-
return (
|
|
204
|
-
<div {...rest} className={cn("mt-1.5 space-y-1", className)}>
|
|
205
|
-
{/* Rendered from the start and never unmounted — see useAnnounce. */}
|
|
206
|
-
<div {...regionProps} />
|
|
207
|
-
{!empty && (
|
|
208
|
-
<>
|
|
209
|
-
<div className="flex items-center gap-2">
|
|
210
|
-
<div className="flex flex-1 gap-1" aria-hidden="true" data-score={score}>
|
|
211
|
-
{[1, 2, 3, 4].map((step) => (
|
|
212
|
-
<div
|
|
213
|
-
key={step}
|
|
214
|
-
className={cn("h-1 flex-1 rounded-full", step <= score ? FILL[score] : "bg-[var(--border)]")}
|
|
215
|
-
/>
|
|
216
|
-
))}
|
|
217
|
-
</div>
|
|
218
|
-
<p className="min-w-[4.5rem] text-end text-xs text-secondary">{level}</p>
|
|
219
|
-
</div>
|
|
220
|
-
{showRequirements && (
|
|
221
|
-
<ul className="flex flex-wrap gap-x-3 gap-y-0.5 text-xs">
|
|
222
|
-
{rules.map((r) => (
|
|
223
|
-
<li
|
|
224
|
-
key={r.id}
|
|
225
|
-
// `relative`: the sr-only state needs a local containing block.
|
|
226
|
-
className={cn("relative", r.met ? "text-success" : "text-muted")}
|
|
227
|
-
data-met={r.met}
|
|
228
|
-
>
|
|
229
|
-
<span className="sr-only">{r.met ? labels.met : labels.notMet} </span>
|
|
230
|
-
<span aria-hidden="true">{r.met ? "✓" : "○"}</span>{" "}
|
|
231
|
-
{r.required ? ruleText[r.id] : labels.optional(ruleText[r.id])}
|
|
232
|
-
</li>
|
|
233
|
-
))}
|
|
234
|
-
</ul>
|
|
235
|
-
)}
|
|
236
|
-
{tooLong && <p className="text-xs text-danger">{labels.tooLong(maxBytes)}</p>}
|
|
237
|
-
</>
|
|
238
|
-
)}
|
|
239
|
-
</div>
|
|
240
|
-
);
|
|
241
|
-
}
|
|
@@ -1,10 +0,0 @@
|
|
|
1
|
-
// The English words of ./phone-input, in a module with no component code: the English
|
|
2
|
-
// catalogue (src/i18n/defaults.ts) imports them without the component, so `en` loads as one
|
|
3
|
-
// chunk like the other languages (0.34, KS U8). ./phone-input re-exports them.
|
|
4
|
-
|
|
5
|
-
import type { PhoneInputLabels } from "./phone-input";
|
|
6
|
-
|
|
7
|
-
export const DEFAULT_PHONE_INPUT_LABELS: PhoneInputLabels = {
|
|
8
|
-
countryCode: "Country code",
|
|
9
|
-
other: "Other",
|
|
10
|
-
};
|