@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,85 +0,0 @@
|
|
|
1
|
-
import type { ReactNode, Ref } from "react";
|
|
2
|
-
import { PasswordStrengthMeter } from "../components/password-strength";
|
|
3
|
-
import { Input } from "../components/input";
|
|
4
|
-
import { PASSWORD_MAX_BYTES, PASSWORD_MIN_LENGTH } from "./form-rules";
|
|
5
|
-
|
|
6
|
-
/** @internal The words the fields show — the host form's own labels. */
|
|
7
|
-
export interface NewPasswordFieldsText {
|
|
8
|
-
password: ReactNode;
|
|
9
|
-
confirm: ReactNode;
|
|
10
|
-
mismatch: ReactNode;
|
|
11
|
-
}
|
|
12
|
-
|
|
13
|
-
/** @internal */
|
|
14
|
-
export interface NewPasswordFieldsProps {
|
|
15
|
-
password: string;
|
|
16
|
-
confirm: string;
|
|
17
|
-
onPasswordChange: (value: string) => void;
|
|
18
|
-
onConfirmChange: (value: string) => void;
|
|
19
|
-
text: NewPasswordFieldsText;
|
|
20
|
-
/** A request is running: both fields `readOnly` (not `disabled`, which would drop
|
|
21
|
-
* the focus of the one being typed in). */
|
|
22
|
-
busy?: boolean;
|
|
23
|
-
passwordRef?: Ref<HTMLInputElement>;
|
|
24
|
-
}
|
|
25
|
-
|
|
26
|
-
/**
|
|
27
|
-
* "Choose a password": the field, the strength meter with its advisory checklist, and
|
|
28
|
-
* the confirmation — keksdose's `PasswordFields`, which its register form, its reset
|
|
29
|
-
* page and its forced-change step share so that every screen choosing a password does
|
|
30
|
-
* it under the same rules and the same feedback. Here `RegisterForm` and
|
|
31
|
-
* `SignInForm`'s set-a-new-password step share it.
|
|
32
|
-
*
|
|
33
|
-
* Both fields are `new-password`: a password manager offers to generate one and never
|
|
34
|
-
* fills in the current one. The confirmation carries the mismatch as its own `error`,
|
|
35
|
-
* attached with `aria-describedby`; the key is always passed, so the message coming and
|
|
36
|
-
* going never remounts the field under the typist.
|
|
37
|
-
*
|
|
38
|
-
* @internal Not part of the barrel; the forms are.
|
|
39
|
-
*/
|
|
40
|
-
export function NewPasswordFields({
|
|
41
|
-
password,
|
|
42
|
-
confirm,
|
|
43
|
-
onPasswordChange,
|
|
44
|
-
onConfirmChange,
|
|
45
|
-
text,
|
|
46
|
-
busy = false,
|
|
47
|
-
passwordRef,
|
|
48
|
-
}: NewPasswordFieldsProps) {
|
|
49
|
-
const mismatch = confirm !== "" && confirm !== password;
|
|
50
|
-
return (
|
|
51
|
-
<>
|
|
52
|
-
<div>
|
|
53
|
-
<Input
|
|
54
|
-
ref={passwordRef}
|
|
55
|
-
type="password"
|
|
56
|
-
name="new-password"
|
|
57
|
-
autoComplete="new-password"
|
|
58
|
-
label={text.password}
|
|
59
|
-
value={password}
|
|
60
|
-
onChange={(e) => onPasswordChange(e.target.value)}
|
|
61
|
-
minLength={PASSWORD_MIN_LENGTH}
|
|
62
|
-
readOnly={busy}
|
|
63
|
-
required
|
|
64
|
-
/>
|
|
65
|
-
{/* The 72-byte cap is passed because a SIGN-IN password has one (bcrypt); the
|
|
66
|
-
minimum is passed rather than left to the meter's own default 8, so the two
|
|
67
|
-
cannot drift apart. */}
|
|
68
|
-
<PasswordStrengthMeter value={password} minLength={PASSWORD_MIN_LENGTH} maxBytes={PASSWORD_MAX_BYTES} />
|
|
69
|
-
</div>
|
|
70
|
-
{/* A typo'd password costs a reset mail — and under keksdose's end-to-end
|
|
71
|
-
encryption, data (feedback #124) — so it is typed twice. */}
|
|
72
|
-
<Input
|
|
73
|
-
type="password"
|
|
74
|
-
name="confirm-password"
|
|
75
|
-
autoComplete="new-password"
|
|
76
|
-
label={text.confirm}
|
|
77
|
-
value={confirm}
|
|
78
|
-
onChange={(e) => onConfirmChange(e.target.value)}
|
|
79
|
-
readOnly={busy}
|
|
80
|
-
error={mismatch ? text.mismatch : undefined}
|
|
81
|
-
required
|
|
82
|
-
/>
|
|
83
|
-
</>
|
|
84
|
-
);
|
|
85
|
-
}
|
|
@@ -1,12 +0,0 @@
|
|
|
1
|
-
// The English words of ./not-found-page, 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). ./not-found-page re-exports them.
|
|
4
|
-
|
|
5
|
-
import type { NotFoundLabels } from "./not-found-page";
|
|
6
|
-
|
|
7
|
-
export const DEFAULT_NOT_FOUND_LABELS: NotFoundLabels = {
|
|
8
|
-
title: "Page not found",
|
|
9
|
-
body: "This address doesn’t exist (any more). It may be a typo, or the page has moved.",
|
|
10
|
-
home: "Go to the start page",
|
|
11
|
-
app: "Back to the app",
|
|
12
|
-
};
|
|
@@ -1,95 +0,0 @@
|
|
|
1
|
-
import type { ComponentPropsWithRef, ReactNode } from "react";
|
|
2
|
-
import { cn } from "../lib/cn";
|
|
3
|
-
import { useKitLabels, type LabelOverride } from "../i18n/kit-labels";
|
|
4
|
-
import { useNoIndex } from "../hooks/use-noindex";
|
|
5
|
-
import { Button } from "../components/button";
|
|
6
|
-
import type { AuthHeadingLevel } from "./status-parts";
|
|
7
|
-
import { DEFAULT_NOT_FOUND_LABELS } from "./not-found-page-labels";
|
|
8
|
-
|
|
9
|
-
/** Every string the page renders — the `notFound` namespace. keksdose's words
|
|
10
|
-
* (`error.not_found_*`), which kastlan took over. */
|
|
11
|
-
export interface NotFoundLabels {
|
|
12
|
-
/** The heading. */
|
|
13
|
-
title: string;
|
|
14
|
-
/** Under it. */
|
|
15
|
-
body: string;
|
|
16
|
-
/** The way out for everyone — to `homeHref`. */
|
|
17
|
-
home: string;
|
|
18
|
-
/** The second way out for someone signed in — to `appHref`. */
|
|
19
|
-
app: string;
|
|
20
|
-
}
|
|
21
|
-
|
|
22
|
-
// Defined in ./not-found-page-labels, which holds no component code (0.34, KS U8).
|
|
23
|
-
export { DEFAULT_NOT_FOUND_LABELS };
|
|
24
|
-
|
|
25
|
-
export interface NotFoundPageProps extends Omit<ComponentPropsWithRef<"div">, "children" | "title"> {
|
|
26
|
-
/** "Go to the start page". Default `/`, which takes a signed-in user into the app and
|
|
27
|
-
* anyone else to sign-in in all three apps. */
|
|
28
|
-
homeHref?: string;
|
|
29
|
-
/**
|
|
30
|
-
* "Back to the app", beside it — pass it while someone is signed in. A LITERAL page
|
|
31
|
-
* (keksdose's `/budget`), never the "last visited page" an app restores on start: a
|
|
32
|
-
* stale one of those pointing at a route that is gone is the likeliest way a
|
|
33
|
-
* signed-in user lands here (keksdose's not-found-page.tsx).
|
|
34
|
-
*/
|
|
35
|
-
appHref?: string;
|
|
36
|
-
/** App content under the text — a search field, a support address. */
|
|
37
|
-
children?: ReactNode;
|
|
38
|
-
/** `false` adds no `noindex` — for a preview inside another page. Default `true`. */
|
|
39
|
-
noIndex?: boolean;
|
|
40
|
-
/** The heading's level. Default `h2`, under `AuthLayout`'s `h1`; `h1` where the page
|
|
41
|
-
* stands alone (inside the app shell). */
|
|
42
|
-
headingAs?: AuthHeadingLevel;
|
|
43
|
-
labels?: LabelOverride<NotFoundLabels>;
|
|
44
|
-
}
|
|
45
|
-
|
|
46
|
-
/**
|
|
47
|
-
* What an unknown address renders (the router's catch-all), signed out and signed in —
|
|
48
|
-
* keksdose's `NotFoundPage` (app/not-found-page.tsx, feedback #129), which kastlan took
|
|
49
|
-
* over on `AuthLayout` (docs/auth-harmonization.md §7).
|
|
50
|
-
*
|
|
51
|
-
* In place of the silent `<Navigate to="/">` keksdose had: bouncing every typo, dead link
|
|
52
|
-
* and fabricated URL to the start page is what Search Console reports as a soft 404, and
|
|
53
|
-
* it hid broken links. An SPA cannot send a real 404 status — the web server answers
|
|
54
|
-
* every path with index.html — so the page says it in words and calls
|
|
55
|
-
* {@link useNoIndex}, which makes a crawler drop it (the server's `X-Robots-Tag` is the
|
|
56
|
-
* authoritative half).
|
|
57
|
-
*
|
|
58
|
-
* It is the page's CONTENT, not a frame, so it sits in either: as `AuthLayout`'s child
|
|
59
|
-
* for a visitor (`headingAs` default `h2`, under the layout's title), or bare inside the
|
|
60
|
-
* app shell for someone signed in (`headingAs="h1"`, and `appHref`). The large "404" is
|
|
61
|
-
* decoration — the heading says it in words — and hidden from a screen reader.
|
|
62
|
-
*/
|
|
63
|
-
export function NotFoundPage({
|
|
64
|
-
homeHref = "/",
|
|
65
|
-
appHref,
|
|
66
|
-
children,
|
|
67
|
-
noIndex = true,
|
|
68
|
-
headingAs: Heading = "h2",
|
|
69
|
-
labels: labelsProp,
|
|
70
|
-
className,
|
|
71
|
-
...rest
|
|
72
|
-
}: NotFoundPageProps) {
|
|
73
|
-
const labels = useKitLabels("notFound", DEFAULT_NOT_FOUND_LABELS, labelsProp);
|
|
74
|
-
useNoIndex(noIndex);
|
|
75
|
-
return (
|
|
76
|
-
<div {...rest} className={cn("flex flex-col items-center gap-2 py-4 text-center", className)}>
|
|
77
|
-
<p aria-hidden className="text-6xl font-bold leading-none tracking-tight text-placeholder">
|
|
78
|
-
404
|
|
79
|
-
</p>
|
|
80
|
-
<Heading className="mt-2 text-xl font-semibold text-primary">{labels.title}</Heading>
|
|
81
|
-
<p className="max-w-prose text-sm text-secondary">{labels.body}</p>
|
|
82
|
-
{children}
|
|
83
|
-
<div className="mt-4 flex flex-wrap justify-center gap-3">
|
|
84
|
-
<Button href={homeHref} variant="accent">
|
|
85
|
-
{labels.home}
|
|
86
|
-
</Button>
|
|
87
|
-
{appHref !== undefined && (
|
|
88
|
-
<Button href={appHref} variant="secondary">
|
|
89
|
-
{labels.app}
|
|
90
|
-
</Button>
|
|
91
|
-
)}
|
|
92
|
-
</div>
|
|
93
|
-
</div>
|
|
94
|
-
);
|
|
95
|
-
}
|
|
@@ -1,31 +0,0 @@
|
|
|
1
|
-
// The English words of ./register-form, 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). ./register-form re-exports them.
|
|
4
|
-
|
|
5
|
-
import { englishRateLimited } from "./auth-errors-labels";
|
|
6
|
-
import type { RegisterLabels } from "./register-form";
|
|
7
|
-
|
|
8
|
-
/** `Required`: every key, the 0.30 one included, has its English here. */
|
|
9
|
-
export const DEFAULT_REGISTER_LABELS: Required<RegisterLabels> = {
|
|
10
|
-
firstName: "First name",
|
|
11
|
-
lastName: "Last name",
|
|
12
|
-
email: "Email",
|
|
13
|
-
emailTagUse: (address) => `Use ${address}`,
|
|
14
|
-
emailTagHint:
|
|
15
|
-
"Many providers deliver name+tag@… to the same inbox, so mail from this app is easy to filter and trace. Check yours does before you rely on it: you would sign in with the tagged address.",
|
|
16
|
-
invitedEmailHint: "The address your invitation was sent to.",
|
|
17
|
-
invitedTagNote: "The tagged address gets a confirmation mail of its own.",
|
|
18
|
-
password: "Password",
|
|
19
|
-
confirmPassword: "Repeat password",
|
|
20
|
-
passwordMismatch: "The passwords don't match.",
|
|
21
|
-
language: "Language",
|
|
22
|
-
submit: "Create account",
|
|
23
|
-
haveAccount: "Already have an account?",
|
|
24
|
-
signIn: "Sign in",
|
|
25
|
-
emailTaken: "An account with this email address already exists.",
|
|
26
|
-
registrationClosed: "New accounts are by invitation only. Ask the operator to invite your email address.",
|
|
27
|
-
invitationInvalid: "This invitation link is not valid.",
|
|
28
|
-
invitationExpired: "This invitation has expired. Ask for a new one.",
|
|
29
|
-
failed: "Registration failed. Please try again.",
|
|
30
|
-
rateLimited: englishRateLimited,
|
|
31
|
-
};
|
|
@@ -1,456 +0,0 @@
|
|
|
1
|
-
import { useEffect, useId, useRef, useState } from "react";
|
|
2
|
-
import type { ComponentPropsWithRef, FormEvent, ReactNode } from "react";
|
|
3
|
-
|
|
4
|
-
import { useKitLabels, useKitLocale, type LabelOverride } from "../i18n/kit-labels";
|
|
5
|
-
import { KIT_LANGUAGES, resolveLanguage } from "../i18n/languages";
|
|
6
|
-
import type { KitLanguageCode } from "../i18n/languages";
|
|
7
|
-
import { cn } from "../lib/cn";
|
|
8
|
-
import { AlertBanner } from "../components/alert-banner";
|
|
9
|
-
import { hasContent } from "../lib/presence";
|
|
10
|
-
import { LanguageSelect } from "../components/language-select";
|
|
11
|
-
import { LegalAcceptCheckbox } from "../components/legal-page";
|
|
12
|
-
import { TextLink } from "../components/text-link";
|
|
13
|
-
import { Button } from "../components/button";
|
|
14
|
-
import { Input } from "../components/input";
|
|
15
|
-
import { authErrorCode, isRateLimited, retryAfterSeconds } from "./auth-errors";
|
|
16
|
-
import { emailParts, taggedEmail } from "./email-tag";
|
|
17
|
-
import { newPasswordProblem, personNameOk, PERSON_NAME_MAX_LENGTH } from "./form-rules";
|
|
18
|
-
import { NewPasswordFields } from "./new-password-fields";
|
|
19
|
-
import { DEFAULT_REGISTER_LABELS } from "./register-form-labels";
|
|
20
|
-
|
|
21
|
-
/** What `RegisterForm` hands `onSubmit` — the core of `POST /auth/register` (§4.2). The
|
|
22
|
-
* app adds its own fields (kastlan's company, keksdose's currency) and the
|
|
23
|
-
* `invite_token` it read from the URL. */
|
|
24
|
-
export interface RegisterValues {
|
|
25
|
-
/** Trimmed, 1–120 characters. */
|
|
26
|
-
firstName: string;
|
|
27
|
-
/** Trimmed, 1–120 characters. */
|
|
28
|
-
lastName: string;
|
|
29
|
-
/** Trimmed. Lower-casing is the server's (§3.1); a tag is never stripped (§4.5). */
|
|
30
|
-
email: string;
|
|
31
|
-
/** As typed: at least 8 characters, at most 72 bytes. */
|
|
32
|
-
password: string;
|
|
33
|
-
/** The language picked — one of `languages` — for every mail to the user (§3.1). */
|
|
34
|
-
locale: KitLanguageCode;
|
|
35
|
-
}
|
|
36
|
-
|
|
37
|
-
/**
|
|
38
|
-
* Every string `RegisterForm` renders — the `register` namespace of `<UiKitProvider
|
|
39
|
-
* labels>`, overridable per instance through `labels`. keksdose's words where it has
|
|
40
|
-
* them. The terms checkbox speaks `legal.accept`, the strength meter `passwordStrength`.
|
|
41
|
-
*/
|
|
42
|
-
export interface RegisterLabels {
|
|
43
|
-
firstName: string;
|
|
44
|
-
lastName: string;
|
|
45
|
-
email: string;
|
|
46
|
-
/** The address-tag button (§4.5), given the exact address it would use — and, with an
|
|
47
|
-
* invitation, the button back to the invited address. */
|
|
48
|
-
emailTagUse: (address: string) => string;
|
|
49
|
-
/** The line after the address-tag button. */
|
|
50
|
-
emailTagHint: string;
|
|
51
|
-
/** Under an invited (read-only) email field. */
|
|
52
|
-
invitedEmailHint: string;
|
|
53
|
-
/** Once the invitee took the tagged address: it is not the invited one, so it is
|
|
54
|
-
* confirmed by a mail of its own (§4.3). */
|
|
55
|
-
invitedTagNote: string;
|
|
56
|
-
password: string;
|
|
57
|
-
confirmPassword: string;
|
|
58
|
-
passwordMismatch: string;
|
|
59
|
-
language: string;
|
|
60
|
-
/** The submit button. */
|
|
61
|
-
submit: string;
|
|
62
|
-
/** Before the link to `signInHref`. */
|
|
63
|
-
haveAccount: string;
|
|
64
|
-
/** The link to `signInHref`. */
|
|
65
|
-
signIn: string;
|
|
66
|
-
/** `email_taken`, under the email field. */
|
|
67
|
-
emailTaken: string;
|
|
68
|
-
/** `registration_closed` — the gate refused the address (§4.3). */
|
|
69
|
-
registrationClosed: string;
|
|
70
|
-
/** `invitation_invalid` — the invitation link is unknown or spent. */
|
|
71
|
-
invitationInvalid: string;
|
|
72
|
-
/** `invitation_expired`. */
|
|
73
|
-
invitationExpired: string;
|
|
74
|
-
/** Any other failure. */
|
|
75
|
-
failed: string;
|
|
76
|
-
/** 0.30.0: the request was throttled — HTTP 429 ({@link isRateLimited}) — given the
|
|
77
|
-
* `Retry-After` wait in seconds, or `undefined` without one. OPTIONAL, like every key
|
|
78
|
-
* added to a shipped interface (an annotated call site must keep compiling); the
|
|
79
|
-
* provider's `register`, then English, fill it. */
|
|
80
|
-
rateLimited?: (seconds?: number) => string;
|
|
81
|
-
}
|
|
82
|
-
|
|
83
|
-
// Defined in ./register-form-labels, which holds no component code (0.34, KS U8).
|
|
84
|
-
export { DEFAULT_REGISTER_LABELS };
|
|
85
|
-
|
|
86
|
-
export interface RegisterFormProps extends Omit<ComponentPropsWithRef<"div">, "onSubmit" | "children"> {
|
|
87
|
-
/**
|
|
88
|
-
* The form was submitted with everything filled in. Send it (`POST /auth/register`,
|
|
89
|
-
* §4.2) and resolve once the user is signed in, or reject with the client's error:
|
|
90
|
-
* `email_taken` shows under the email field, `registration_closed` and the
|
|
91
|
-
* invitation codes above the button, anything else as "Registration failed". The form
|
|
92
|
-
* never sends a request itself (§8): keksdose must see the password on its way.
|
|
93
|
-
*
|
|
94
|
-
* On resolve the form stays busy while the app navigates.
|
|
95
|
-
*/
|
|
96
|
-
onSubmit: (values: RegisterValues) => Promise<unknown>;
|
|
97
|
-
/**
|
|
98
|
-
* The app's address tag (`"kastlan"`, §4.5). Once the email is plausible, a button
|
|
99
|
-
* under it offers the tagged address — "Use ada+kastlan@example.com" — with a line on
|
|
100
|
-
* why; one click puts it in the field. Never applied on its own. Left out, no offer.
|
|
101
|
-
*/
|
|
102
|
-
emailTag?: string;
|
|
103
|
-
/**
|
|
104
|
-
* The address of the invitation this sign-up comes from (§4.4): the field starts with
|
|
105
|
-
* it and is read-only. With `emailTag`, the invitee may still take the tagged form of
|
|
106
|
-
* it — the server accepts exactly that variant — and go back.
|
|
107
|
-
*/
|
|
108
|
-
invitedEmail?: string;
|
|
109
|
-
/**
|
|
110
|
-
* 0.30.0: an address to start with that stays EDITABLE, with the `+tag` suggestion still
|
|
111
|
-
* offered — for a link anyone can build (keksdose's token-free `/register?email=…`
|
|
112
|
-
* beta link, kept while an app moves to invitations). Unlike `invitedEmail` it proves
|
|
113
|
-
* nothing, so it locks nothing. `invitedEmail` wins when both are given.
|
|
114
|
-
*/
|
|
115
|
-
defaultEmail?: string;
|
|
116
|
-
/**
|
|
117
|
-
* The language field's value — controlled. Pass the app's UI language
|
|
118
|
-
* (`i18n.resolvedLanguage`) with `onLocaleChange` switching it, and the field IS the
|
|
119
|
-
* app's language switch, with no copy of its own to drift from a second switcher on
|
|
120
|
-
* the page (keksdose's register page has one in its header). Any tag; it shows (and
|
|
121
|
-
* submits) the offered code it resolves to. Left out, the form keeps its own, starting
|
|
122
|
-
* from `defaultLocale`, else the provider's language, else the browser's.
|
|
123
|
-
*/
|
|
124
|
-
locale?: string;
|
|
125
|
-
/** The uncontrolled language field's start value. */
|
|
126
|
-
defaultLocale?: string;
|
|
127
|
-
/** A language was picked. */
|
|
128
|
-
onLocaleChange?: (code: KitLanguageCode) => void;
|
|
129
|
-
/** The languages to offer, in order. Default all seven. */
|
|
130
|
-
languages?: readonly KitLanguageCode[];
|
|
131
|
-
/**
|
|
132
|
-
* The app's own language field in place of the kit's select — keksdose's
|
|
133
|
-
* `LanguageSetting` bound to its i18n. `null` draws none (an app with one language);
|
|
134
|
-
* the submitted `locale` is then `locale`'s.
|
|
135
|
-
*/
|
|
136
|
-
languageField?: ReactNode;
|
|
137
|
-
/** Above the form — keksdose's closed-beta banner. */
|
|
138
|
-
aboveForm?: ReactNode;
|
|
139
|
-
/** Under the email field and its tag offer — an app's own hint. */
|
|
140
|
-
underEmail?: ReactNode;
|
|
141
|
-
/** The app's sign-up fields (§4.1 item 7): kastlan's Company, keksdose's reporting
|
|
142
|
-
* currency. Their values are the app's; say whether they are complete with
|
|
143
|
-
* `appFieldsComplete`. */
|
|
144
|
-
appFields?: ReactNode;
|
|
145
|
-
/** After the app fields, before the terms — keksdose's privacy-mode note. */
|
|
146
|
-
afterFields?: ReactNode;
|
|
147
|
-
/** Whether the app fields are filled in as required — kastlan's Company without an
|
|
148
|
-
* invitation. The submit waits for it. Default `true`. */
|
|
149
|
-
appFieldsComplete?: boolean;
|
|
150
|
-
/** The terms checkbox's links. Default `/terms` and `/privacy`. */
|
|
151
|
-
termsHref?: string;
|
|
152
|
-
privacyHref?: string;
|
|
153
|
-
/** "Already have an account? Sign in" goes here — `/login`. Left out, no line. */
|
|
154
|
-
signInHref?: string;
|
|
155
|
-
/** The app's own words for a failure the kit cannot know (the device offline, a
|
|
156
|
-
* throttle with its wait), or `undefined` for the kit's. Asked first, for every
|
|
157
|
-
* failure; a bare `429` needs none since 0.30.0 — the kit says `rateLimited`. */
|
|
158
|
-
describeError?: (error: unknown) => ReactNode | undefined;
|
|
159
|
-
labels?: LabelOverride<RegisterLabels>;
|
|
160
|
-
}
|
|
161
|
-
|
|
162
|
-
const ALL_CODES: readonly KitLanguageCode[] = KIT_LANGUAGES.map((language) => language.code);
|
|
163
|
-
|
|
164
|
-
/** The browser's languages, in its order — absent outside a browser. */
|
|
165
|
-
function browserLanguages(): readonly string[] {
|
|
166
|
-
if (typeof navigator === "undefined") return [];
|
|
167
|
-
return navigator.languages?.length ? navigator.languages : [navigator.language];
|
|
168
|
-
}
|
|
169
|
-
|
|
170
|
-
type Busy = "sending" | "done" | null;
|
|
171
|
-
|
|
172
|
-
/**
|
|
173
|
-
* Sign-up for every app (docs/auth-harmonization.md §4.1, §8): first and last name,
|
|
174
|
-
* email with the address-tag offer, password with the strength meter and its
|
|
175
|
-
* confirmation, language, the app's own fields in a slot, and the terms. keksdose's
|
|
176
|
-
* `RegisterPage` (features/auth/register-page.tsx) with its slots made props.
|
|
177
|
-
*
|
|
178
|
-
* **It never sends a request.** `onSubmit` gets the values; what the request carries
|
|
179
|
-
* besides them (kastlan's company, keksdose's currency, the `invite_token`) is the
|
|
180
|
-
* app's, as are the role and the associations, which never come from the form (§4.3).
|
|
181
|
-
*
|
|
182
|
-
* **The submit waits for a complete form**: both names (1–120 characters after
|
|
183
|
-
* trimming), a plausible address, a password of at least 8 characters and at most 72
|
|
184
|
-
* bytes, the same password again, the terms ticked, and `appFieldsComplete`. Nothing
|
|
185
|
-
* else is a rule — the strength checklist is advice (keksdose #124), and the kit adds
|
|
186
|
-
* none of its own (§8). So there is never a failed attempt for a missing field, and no
|
|
187
|
-
* field error to show for one.
|
|
188
|
-
*
|
|
189
|
-
* **The address tag** (§4.5) is offered under the email field as one click with the
|
|
190
|
-
* exact result on the button, never applied: sub-addressing is a convention the
|
|
191
|
-
* receiving server may or may not implement, and a silent rewrite would send the
|
|
192
|
-
* verification mail down a path nobody checked. With an invitation the field is fixed
|
|
193
|
-
* to the invited address; the invitee may still take its tagged form, and is told it
|
|
194
|
-
* will be confirmed by a mail of its own (§4.3).
|
|
195
|
-
*
|
|
196
|
-
* **Refusals** are read by code ({@link authErrorCode}): `email_taken` under the email
|
|
197
|
-
* field, which takes the focus; `registration_closed`, `invitation_invalid` and
|
|
198
|
-
* `invitation_expired` above the button; anything else as "Registration failed", unless
|
|
199
|
-
* `describeError` has the app's words.
|
|
200
|
-
*
|
|
201
|
-
* Laid out for a 390 px phone: the names sit side by side only where the form is at
|
|
202
|
-
* least 20rem wide (a container query), which the narrow `AuthLayout` card is on a
|
|
203
|
-
* desktop and a phone is not.
|
|
204
|
-
*/
|
|
205
|
-
export function RegisterForm({
|
|
206
|
-
onSubmit,
|
|
207
|
-
emailTag,
|
|
208
|
-
invitedEmail,
|
|
209
|
-
defaultEmail,
|
|
210
|
-
locale: localeProp,
|
|
211
|
-
defaultLocale,
|
|
212
|
-
onLocaleChange,
|
|
213
|
-
languages = ALL_CODES,
|
|
214
|
-
languageField,
|
|
215
|
-
aboveForm,
|
|
216
|
-
underEmail,
|
|
217
|
-
appFields,
|
|
218
|
-
afterFields,
|
|
219
|
-
appFieldsComplete = true,
|
|
220
|
-
termsHref,
|
|
221
|
-
privacyHref,
|
|
222
|
-
signInHref,
|
|
223
|
-
describeError,
|
|
224
|
-
labels: labelsProp,
|
|
225
|
-
className,
|
|
226
|
-
...rest
|
|
227
|
-
}: RegisterFormProps) {
|
|
228
|
-
const labels = useKitLabels("register", DEFAULT_REGISTER_LABELS, labelsProp);
|
|
229
|
-
const kitLocale = useKitLocale();
|
|
230
|
-
const invited = invitedEmail !== undefined;
|
|
231
|
-
const [firstName, setFirstName] = useState("");
|
|
232
|
-
const [lastName, setLastName] = useState("");
|
|
233
|
-
const [email, setEmail] = useState(invitedEmail ?? defaultEmail ?? "");
|
|
234
|
-
const [password, setPassword] = useState("");
|
|
235
|
-
const [confirm, setConfirm] = useState("");
|
|
236
|
-
const [ownLocale, setOwnLocale] = useState<string>(
|
|
237
|
-
() => defaultLocale ?? resolveLanguage([kitLocale, ...browserLanguages()], languages),
|
|
238
|
-
);
|
|
239
|
-
const [accepted, setAccepted] = useState(false);
|
|
240
|
-
const [busy, setBusy] = useState<Busy>(null);
|
|
241
|
-
// `email_taken` belongs to the address it was answered for; another one clears it.
|
|
242
|
-
const [taken, setTaken] = useState<string | null>(null);
|
|
243
|
-
const [failure, setFailure] = useState<ReactNode>(null);
|
|
244
|
-
const emailRef = useRef<HTMLInputElement>(null);
|
|
245
|
-
const tagHintId = useId();
|
|
246
|
-
|
|
247
|
-
const mounted = useRef(true);
|
|
248
|
-
useEffect(() => {
|
|
249
|
-
mounted.current = true;
|
|
250
|
-
return () => {
|
|
251
|
-
mounted.current = false;
|
|
252
|
-
};
|
|
253
|
-
}, []);
|
|
254
|
-
|
|
255
|
-
// What the field shows is what is submitted: the offered code the value resolves to.
|
|
256
|
-
const locale = resolveLanguage([localeProp ?? ownLocale], languages);
|
|
257
|
-
const changeLocale = (code: KitLanguageCode) => {
|
|
258
|
-
if (localeProp === undefined) setOwnLocale(code);
|
|
259
|
-
onLocaleChange?.(code);
|
|
260
|
-
};
|
|
261
|
-
|
|
262
|
-
const working = busy !== null;
|
|
263
|
-
const suggestion = emailTag ? taggedEmail(email, emailTag) : null;
|
|
264
|
-
// The invitee took the tagged address: offer the way back to the invited one.
|
|
265
|
-
const backToInvited = invitedEmail !== undefined && email.trim() !== invitedEmail.trim() ? invitedEmail.trim() : null;
|
|
266
|
-
const canSubmit =
|
|
267
|
-
personNameOk(firstName) &&
|
|
268
|
-
personNameOk(lastName) &&
|
|
269
|
-
emailParts(email) !== null &&
|
|
270
|
-
newPasswordProblem(password, confirm) === null &&
|
|
271
|
-
accepted &&
|
|
272
|
-
appFieldsComplete;
|
|
273
|
-
|
|
274
|
-
const submit = (e: FormEvent) => {
|
|
275
|
-
e.preventDefault();
|
|
276
|
-
if (!canSubmit || working) return;
|
|
277
|
-
const values: RegisterValues = {
|
|
278
|
-
firstName: firstName.trim(),
|
|
279
|
-
lastName: lastName.trim(),
|
|
280
|
-
email: email.trim(),
|
|
281
|
-
password,
|
|
282
|
-
locale,
|
|
283
|
-
};
|
|
284
|
-
setBusy("sending");
|
|
285
|
-
setFailure(null);
|
|
286
|
-
setTaken(null);
|
|
287
|
-
let result: Promise<unknown>;
|
|
288
|
-
try {
|
|
289
|
-
result = Promise.resolve(onSubmit(values));
|
|
290
|
-
} catch (error) {
|
|
291
|
-
result = Promise.reject(error);
|
|
292
|
-
}
|
|
293
|
-
result.then(
|
|
294
|
-
() => {
|
|
295
|
-
if (mounted.current) setBusy("done");
|
|
296
|
-
},
|
|
297
|
-
(error: unknown) => {
|
|
298
|
-
if (!mounted.current) return;
|
|
299
|
-
setBusy(null);
|
|
300
|
-
const own = describeError?.(error);
|
|
301
|
-
const code = authErrorCode(error);
|
|
302
|
-
if (code === "email_taken" && !hasContent(own)) {
|
|
303
|
-
setTaken(values.email);
|
|
304
|
-
emailRef.current?.focus();
|
|
305
|
-
return;
|
|
306
|
-
}
|
|
307
|
-
setFailure(
|
|
308
|
-
hasContent(own)
|
|
309
|
-
? own
|
|
310
|
-
: isRateLimited(error)
|
|
311
|
-
? (labels.rateLimited ?? DEFAULT_REGISTER_LABELS.rateLimited)(retryAfterSeconds(error))
|
|
312
|
-
: code === "registration_closed"
|
|
313
|
-
? labels.registrationClosed
|
|
314
|
-
: code === "invitation_invalid"
|
|
315
|
-
? labels.invitationInvalid
|
|
316
|
-
: code === "invitation_expired"
|
|
317
|
-
? labels.invitationExpired
|
|
318
|
-
: labels.failed,
|
|
319
|
-
);
|
|
320
|
-
},
|
|
321
|
-
);
|
|
322
|
-
};
|
|
323
|
-
|
|
324
|
-
return (
|
|
325
|
-
<div {...rest} className={cn("@container space-y-4", className)}>
|
|
326
|
-
{aboveForm}
|
|
327
|
-
<form className="space-y-3" noValidate onSubmit={submit}>
|
|
328
|
-
<div className="grid gap-3 @xs:grid-cols-2">
|
|
329
|
-
<Input
|
|
330
|
-
name="given-name"
|
|
331
|
-
autoComplete="given-name"
|
|
332
|
-
label={labels.firstName}
|
|
333
|
-
value={firstName}
|
|
334
|
-
onChange={(e) => setFirstName(e.target.value)}
|
|
335
|
-
maxLength={PERSON_NAME_MAX_LENGTH}
|
|
336
|
-
readOnly={working}
|
|
337
|
-
required
|
|
338
|
-
/>
|
|
339
|
-
<Input
|
|
340
|
-
name="family-name"
|
|
341
|
-
autoComplete="family-name"
|
|
342
|
-
label={labels.lastName}
|
|
343
|
-
value={lastName}
|
|
344
|
-
onChange={(e) => setLastName(e.target.value)}
|
|
345
|
-
maxLength={PERSON_NAME_MAX_LENGTH}
|
|
346
|
-
readOnly={working}
|
|
347
|
-
required
|
|
348
|
-
/>
|
|
349
|
-
</div>
|
|
350
|
-
|
|
351
|
-
<div>
|
|
352
|
-
<Input
|
|
353
|
-
ref={emailRef}
|
|
354
|
-
type="email"
|
|
355
|
-
name="email"
|
|
356
|
-
autoComplete="email"
|
|
357
|
-
label={labels.email}
|
|
358
|
-
value={email}
|
|
359
|
-
onChange={(e) => setEmail(e.target.value)}
|
|
360
|
-
readOnly={invited || working}
|
|
361
|
-
hint={invited ? labels.invitedEmailHint : undefined}
|
|
362
|
-
error={taken !== null && taken === email.trim() ? labels.emailTaken : undefined}
|
|
363
|
-
required
|
|
364
|
-
/>
|
|
365
|
-
{/* The tag, offered rather than applied (§4.5): one click, the exact address
|
|
366
|
-
on the button, reversible by typing — or, invited, by the button back. */}
|
|
367
|
-
{suggestion && (
|
|
368
|
-
<p className="mt-1 text-xs text-muted">
|
|
369
|
-
<Button
|
|
370
|
-
type="button"
|
|
371
|
-
variant="link"
|
|
372
|
-
size="sm"
|
|
373
|
-
className="h-auto p-0 align-baseline"
|
|
374
|
-
disabled={working}
|
|
375
|
-
aria-describedby={tagHintId}
|
|
376
|
-
onClick={() => setEmail(suggestion)}
|
|
377
|
-
>
|
|
378
|
-
{labels.emailTagUse(suggestion)}
|
|
379
|
-
</Button>{" "}
|
|
380
|
-
<span id={tagHintId}>{labels.emailTagHint}</span>
|
|
381
|
-
</p>
|
|
382
|
-
)}
|
|
383
|
-
{backToInvited !== null && (
|
|
384
|
-
<p className="mt-1 text-xs text-muted">
|
|
385
|
-
<span>{labels.invitedTagNote}</span>{" "}
|
|
386
|
-
<Button
|
|
387
|
-
type="button"
|
|
388
|
-
variant="link"
|
|
389
|
-
size="sm"
|
|
390
|
-
className="h-auto p-0 align-baseline"
|
|
391
|
-
disabled={working}
|
|
392
|
-
onClick={() => setEmail(backToInvited)}
|
|
393
|
-
>
|
|
394
|
-
{labels.emailTagUse(backToInvited)}
|
|
395
|
-
</Button>
|
|
396
|
-
</p>
|
|
397
|
-
)}
|
|
398
|
-
{underEmail}
|
|
399
|
-
</div>
|
|
400
|
-
|
|
401
|
-
<NewPasswordFields
|
|
402
|
-
password={password}
|
|
403
|
-
confirm={confirm}
|
|
404
|
-
onPasswordChange={setPassword}
|
|
405
|
-
onConfirmChange={setConfirm}
|
|
406
|
-
busy={working}
|
|
407
|
-
text={{ password: labels.password, confirm: labels.confirmPassword, mismatch: labels.passwordMismatch }}
|
|
408
|
-
/>
|
|
409
|
-
|
|
410
|
-
{languageField === undefined ? (
|
|
411
|
-
<LanguageSelect
|
|
412
|
-
name="locale"
|
|
413
|
-
label={labels.language}
|
|
414
|
-
value={locale}
|
|
415
|
-
codes={languages}
|
|
416
|
-
onChange={changeLocale}
|
|
417
|
-
disabled={working}
|
|
418
|
-
/>
|
|
419
|
-
) : (
|
|
420
|
-
languageField
|
|
421
|
-
)}
|
|
422
|
-
|
|
423
|
-
{appFields}
|
|
424
|
-
{afterFields}
|
|
425
|
-
|
|
426
|
-
{/* The kit's terms checkbox (legal contract §3.4). Never an error: an unticked
|
|
427
|
-
box keeps the submit disabled, so there is no failed attempt to explain. */}
|
|
428
|
-
<LegalAcceptCheckbox
|
|
429
|
-
checked={accepted}
|
|
430
|
-
onCheckedChange={setAccepted}
|
|
431
|
-
termsHref={termsHref}
|
|
432
|
-
privacyHref={privacyHref}
|
|
433
|
-
disabled={working}
|
|
434
|
-
/>
|
|
435
|
-
|
|
436
|
-
{hasContent(failure) && (
|
|
437
|
-
<AlertBanner tone="danger" size="sm" role="alert">
|
|
438
|
-
{failure}
|
|
439
|
-
</AlertBanner>
|
|
440
|
-
)}
|
|
441
|
-
|
|
442
|
-
<Button type="submit" className="w-full" disabled={!working && !canSubmit} pending={working}>
|
|
443
|
-
{labels.submit}
|
|
444
|
-
</Button>
|
|
445
|
-
</form>
|
|
446
|
-
{signInHref !== undefined && (
|
|
447
|
-
<p className="text-center text-sm text-secondary">
|
|
448
|
-
{labels.haveAccount}{" "}
|
|
449
|
-
<TextLink href={signInHref} tone="primary">
|
|
450
|
-
{labels.signIn}
|
|
451
|
-
</TextLink>
|
|
452
|
-
</p>
|
|
453
|
-
)}
|
|
454
|
-
</div>
|
|
455
|
-
);
|
|
456
|
-
}
|