@eifi1/ui-kit 0.51.6 → 0.52.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +146 -26
- package/dist/account/account-parts.d.ts +10 -8
- package/dist/account/account-parts.js +1 -18
- package/dist/account/account-parts.js.map +1 -1
- package/dist/account/data-export-setting-labels.js +1 -1
- package/dist/account/data-export-setting-labels.js.map +1 -1
- package/dist/account/delete-account-setting-labels.js +1 -1
- package/dist/account/delete-account-setting-labels.js.map +1 -1
- package/dist/account/email-change-setting-labels.js +1 -1
- package/dist/account/email-change-setting-labels.js.map +1 -1
- package/dist/account/passkeys-setting.d.ts +9 -2
- package/dist/account/passkeys-setting.js +41 -29
- package/dist/account/passkeys-setting.js.map +1 -1
- package/dist/account/sessions-setting.d.ts +3 -2
- package/dist/account/sessions-setting.js +10 -8
- package/dist/account/sessions-setting.js.map +1 -1
- package/dist/admin/admin-action-confirm.js +3 -7
- package/dist/admin/admin-action-confirm.js.map +1 -1
- package/dist/admin/admin-parts.d.ts +6 -3
- package/dist/admin/admin-parts.js +6 -21
- package/dist/admin/admin-parts.js.map +1 -1
- package/dist/admin/mail-test-card-labels.js +1 -1
- package/dist/admin/mail-test-card-labels.js.map +1 -1
- package/dist/admin/plan-change-labels.d.ts +2 -2
- package/dist/admin/plan-change-labels.js +1 -17
- package/dist/admin/plan-change-labels.js.map +1 -1
- package/dist/admin/plan-change.d.ts +3 -42
- package/dist/admin/plan-change.js +1 -1
- package/dist/admin/plan-change.js.map +1 -1
- package/dist/admin/reviewer-scope-editor.js +3 -3
- package/dist/admin/reviewer-scope-editor.js.map +1 -1
- package/dist/auth/auth-errors-labels.d.ts +11 -0
- package/dist/auth/auth-errors-labels.js +13 -0
- package/dist/auth/auth-errors-labels.js.map +1 -0
- package/dist/auth/auth-errors.d.ts +7 -23
- package/dist/auth/auth-errors.js +2 -15
- package/dist/auth/auth-errors.js.map +1 -1
- package/dist/auth/complete-name-dialog.d.ts +3 -2
- package/dist/auth/complete-name-dialog.js +3 -5
- package/dist/auth/complete-name-dialog.js.map +1 -1
- package/dist/auth/forgot-password-form-labels.js +1 -1
- package/dist/auth/forgot-password-form-labels.js.map +1 -1
- package/dist/auth/forgot-password-form.js +7 -2
- package/dist/auth/forgot-password-form.js.map +1 -1
- package/dist/auth/register-form-labels.js +1 -1
- package/dist/auth/register-form-labels.js.map +1 -1
- package/dist/auth/reset-password-form-labels.js +1 -1
- package/dist/auth/reset-password-form-labels.js.map +1 -1
- package/dist/auth/reset-password-form.js +5 -1
- package/dist/auth/reset-password-form.js.map +1 -1
- package/dist/auth/sign-in-form-labels.js +1 -1
- package/dist/auth/sign-in-form-labels.js.map +1 -1
- package/dist/auth/status-parts.d.ts +0 -3
- package/dist/auth/status-parts.js +0 -4
- package/dist/auth/status-parts.js.map +1 -1
- package/dist/auth/verify-email-labels.js +1 -1
- package/dist/auth/verify-email-labels.js.map +1 -1
- package/dist/auth/verify-email.js +7 -2
- package/dist/auth/verify-email.js.map +1 -1
- package/dist/billing/cancel-request.d.ts +11 -2
- package/dist/billing/cancel-request.js +15 -3
- package/dist/billing/cancel-request.js.map +1 -1
- package/dist/billing/cancel-subscription.d.ts +22 -10
- package/dist/billing/cancel-subscription.js +8 -11
- package/dist/billing/cancel-subscription.js.map +1 -1
- package/dist/billing/dialog-close.d.ts +29 -0
- package/dist/billing/dialog-close.js +8 -0
- package/dist/billing/dialog-close.js.map +1 -0
- package/dist/billing/plan-card.d.ts +14 -4
- package/dist/billing/plan-card.js +15 -8
- package/dist/billing/plan-card.js.map +1 -1
- package/dist/billing/plan-change-labels.d.ts +42 -0
- package/dist/billing/plan-change-labels.js +22 -0
- package/dist/billing/plan-change-labels.js.map +1 -0
- package/dist/billing/plan-switch.d.ts +21 -9
- package/dist/billing/plan-switch.js +10 -8
- package/dist/billing/plan-switch.js.map +1 -1
- package/dist/chart.d.ts +12 -0
- package/dist/chart.js +16 -1
- package/dist/chart.js.map +1 -1
- package/dist/components/account-chips.d.ts +5 -5
- package/dist/components/account-chips.js +11 -13
- package/dist/components/account-chips.js.map +1 -1
- package/dist/components/alert-banner.d.ts +16 -5
- package/dist/components/alert-banner.js +46 -1
- package/dist/components/alert-banner.js.map +1 -1
- package/dist/components/amount-input.d.ts +22 -4
- package/dist/components/amount-input.js +3 -3
- package/dist/components/amount-input.js.map +1 -1
- package/dist/components/autocomplete.js +57 -65
- package/dist/components/autocomplete.js.map +1 -1
- package/dist/components/bulk-action-bar.d.ts +12 -2
- package/dist/components/bulk-action-bar.js +65 -21
- package/dist/components/bulk-action-bar.js.map +1 -1
- package/dist/components/button-look.d.ts +5 -5
- package/dist/components/button-look.js.map +1 -1
- package/dist/components/button.d.ts +2 -2
- package/dist/components/button.js.map +1 -1
- package/dist/components/calculator.d.ts +21 -2
- package/dist/components/calculator.js +53 -14
- package/dist/components/calculator.js.map +1 -1
- package/dist/components/chart-edge.d.ts +16 -0
- package/dist/components/chart-edge.js +14 -1
- package/dist/components/chart-edge.js.map +1 -1
- package/dist/components/chart-figure.d.ts +13 -0
- package/dist/components/chart-figure.js +15 -0
- package/dist/components/chart-figure.js.map +1 -0
- package/dist/components/chart-zoom-core.js +1 -4
- package/dist/components/chart-zoom-core.js.map +1 -1
- package/dist/components/chart.d.ts +8 -1
- package/dist/components/chart.js +19 -10
- package/dist/components/chart.js.map +1 -1
- package/dist/components/combobox-core.d.ts +119 -7
- package/dist/components/combobox-core.js +151 -46
- package/dist/components/combobox-core.js.map +1 -1
- package/dist/components/combobox.d.ts +1 -1
- package/dist/components/combobox.js +142 -131
- package/dist/components/combobox.js.map +1 -1
- package/dist/components/copy-button.d.ts +6 -5
- package/dist/components/copy-button.js +5 -3
- package/dist/components/copy-button.js.map +1 -1
- package/dist/components/country-select.js +2 -2
- package/dist/components/country-select.js.map +1 -1
- package/dist/components/data-table-column-settings.d.ts +1 -1
- package/dist/components/data-table-column-settings.js +33 -7
- package/dist/components/data-table-column-settings.js.map +1 -1
- package/dist/components/data-table-filters.d.ts +4 -2
- package/dist/components/data-table-filters.js +2 -2
- package/dist/components/data-table-filters.js.map +1 -1
- package/dist/components/data-table-fit.d.ts +6 -4
- package/dist/components/data-table-fit.js +4 -1
- package/dist/components/data-table-fit.js.map +1 -1
- package/dist/components/data-table-groups.d.ts +1 -1
- package/dist/components/data-table-groups.js.map +1 -1
- package/dist/components/data-table-head.d.ts +1 -1
- package/dist/components/data-table-head.js +15 -12
- package/dist/components/data-table-head.js.map +1 -1
- package/dist/components/data-table-mobile.d.ts +36 -7
- package/dist/components/data-table-mobile.js +63 -31
- package/dist/components/data-table-mobile.js.map +1 -1
- package/dist/components/data-table-pagination.js +11 -6
- package/dist/components/data-table-pagination.js.map +1 -1
- package/dist/components/data-table-resize.d.ts +1 -1
- package/dist/components/data-table-resize.js.map +1 -1
- package/dist/components/data-table-row-actions.d.ts +2 -2
- package/dist/components/data-table-row-actions.js.map +1 -1
- package/dist/components/data-table-row.d.ts +6 -2
- package/dist/components/data-table-row.js +17 -10
- package/dist/components/data-table-row.js.map +1 -1
- package/dist/components/data-table-selection.d.ts +1 -1
- package/dist/components/data-table-selection.js.map +1 -1
- package/dist/components/data-table-shared.d.ts +10 -2
- package/dist/components/data-table-shared.js +18 -0
- package/dist/components/data-table-shared.js.map +1 -1
- package/dist/components/data-table-sort.d.ts +21 -2
- package/dist/components/data-table-sort.js +24 -0
- package/dist/components/data-table-sort.js.map +1 -1
- package/dist/components/data-table-virtual.d.ts +1 -1
- package/dist/components/data-table-virtual.js +18 -6
- package/dist/components/data-table-virtual.js.map +1 -1
- package/dist/components/data-table.d.ts +25 -8
- package/dist/components/data-table.js +154 -25
- package/dist/components/data-table.js.map +1 -1
- package/dist/components/date-field.d.ts +24 -2
- package/dist/components/date-field.js +33 -8
- package/dist/components/date-field.js.map +1 -1
- package/dist/components/date-picker.d.ts +15 -2
- package/dist/components/date-picker.js +55 -26
- package/dist/components/date-picker.js.map +1 -1
- package/dist/components/date-range-picker.d.ts +47 -20
- package/dist/components/date-range-picker.js +23 -7
- package/dist/components/date-range-picker.js.map +1 -1
- package/dist/components/dialog-frame.d.ts +2 -1
- package/dist/components/dialog-frame.js.map +1 -1
- package/dist/components/entity-combobox.js +4 -2
- package/dist/components/entity-combobox.js.map +1 -1
- package/dist/components/error-boundary.js +37 -30
- package/dist/components/error-boundary.js.map +1 -1
- package/dist/components/{ui-labels.d.ts → field-base-labels.d.ts} +0 -2
- package/dist/components/{ui-labels.js → field-base-labels.js} +2 -9
- package/dist/components/field-base-labels.js.map +1 -0
- package/dist/components/field-base.d.ts +4 -3
- package/dist/components/field-base.js +3 -3
- package/dist/components/field-base.js.map +1 -1
- package/dist/components/field-sync-labels.d.ts +1 -0
- package/dist/components/field-sync-labels.js.map +1 -1
- package/dist/components/field-sync.d.ts +23 -1
- package/dist/components/field-sync.js.map +1 -1
- package/dist/components/form-actions.js +11 -5
- package/dist/components/form-actions.js.map +1 -1
- package/dist/components/hover-menu.d.ts +3 -0
- package/dist/components/hover-menu.js +5 -3
- package/dist/components/hover-menu.js.map +1 -1
- package/dist/components/icon-button.js +14 -9
- package/dist/components/icon-button.js.map +1 -1
- package/dist/components/inline-confirm.d.ts +43 -0
- package/dist/components/inline-confirm.js +67 -0
- package/dist/components/inline-confirm.js.map +1 -0
- package/dist/components/inline-entity-combobox.d.ts +4 -3
- package/dist/components/inline-entity-combobox.js +150 -141
- package/dist/components/inline-entity-combobox.js.map +1 -1
- package/dist/components/input.js +1 -1
- package/dist/components/input.js.map +1 -1
- package/dist/components/jump-calendar.js +28 -112
- package/dist/components/jump-calendar.js.map +1 -1
- package/dist/components/legal-page.d.ts +3 -1
- package/dist/components/legal-page.js +3 -2
- package/dist/components/legal-page.js.map +1 -1
- package/dist/components/legal.d.ts +4 -2
- package/dist/components/legal.js.map +1 -1
- package/dist/components/lightbox.d.ts +2 -2
- package/dist/components/lightbox.js +17 -6
- package/dist/components/lightbox.js.map +1 -1
- package/dist/components/list.d.ts +6 -2
- package/dist/components/list.js +4 -3
- package/dist/components/list.js.map +1 -1
- package/dist/components/measured-grid.d.ts +1 -1
- package/dist/components/measured-grid.js +2 -1
- package/dist/components/measured-grid.js.map +1 -1
- package/dist/components/mini-calendar.js +3 -5
- package/dist/components/mini-calendar.js.map +1 -1
- package/dist/components/modal.d.ts +24 -0
- package/dist/components/modal.js +12 -4
- package/dist/components/modal.js.map +1 -1
- package/dist/components/money-draft.js +7 -5
- package/dist/components/money-draft.js.map +1 -1
- package/dist/components/money-field.d.ts +2 -2
- package/dist/components/money-field.js.map +1 -1
- package/dist/components/month-grid.d.ts +55 -0
- package/dist/components/month-grid.js +148 -0
- package/dist/components/month-grid.js.map +1 -0
- package/dist/components/month-picker.d.ts +36 -4
- package/dist/components/month-picker.js +123 -146
- package/dist/components/month-picker.js.map +1 -1
- package/dist/components/multi-entity-combobox.js +2 -1
- package/dist/components/multi-entity-combobox.js.map +1 -1
- package/dist/components/multi-select.d.ts +2 -2
- package/dist/components/multi-select.js +11 -6
- package/dist/components/multi-select.js.map +1 -1
- package/dist/components/number-field.d.ts +6 -4
- package/dist/components/number-field.js +3 -2
- package/dist/components/number-field.js.map +1 -1
- package/dist/components/number-input.d.ts +4 -1
- package/dist/components/number-input.js +3 -2
- package/dist/components/number-input.js.map +1 -1
- package/dist/components/numpad-sheet.js.map +1 -1
- package/dist/components/picker-sheet.js +2 -1
- package/dist/components/picker-sheet.js.map +1 -1
- package/dist/components/pie-chart-labels.d.ts +7 -0
- package/dist/components/pie-chart-labels.js +1 -0
- package/dist/components/pie-chart-labels.js.map +1 -1
- package/dist/components/pie-chart.d.ts +5 -3
- package/dist/components/pie-chart.js +7 -22
- package/dist/components/pie-chart.js.map +1 -1
- package/dist/components/popover.d.ts +3 -0
- package/dist/components/popover.js +7 -1
- package/dist/components/popover.js.map +1 -1
- package/dist/components/reauth-dialog.d.ts +4 -5
- package/dist/components/reauth-dialog.js +1 -4
- package/dist/components/reauth-dialog.js.map +1 -1
- package/dist/components/row-actions.js +2 -1
- package/dist/components/row-actions.js.map +1 -1
- package/dist/components/section-nav.d.ts +7 -0
- package/dist/components/section-nav.js.map +1 -1
- package/dist/components/series-chart-axes.d.ts +10 -3
- package/dist/components/series-chart-axes.js +1 -0
- package/dist/components/series-chart-axes.js.map +1 -1
- package/dist/components/series-chart-labels.d.ts +7 -4
- package/dist/components/series-chart-labels.js.map +1 -1
- package/dist/components/series-chart.d.ts +31 -7
- package/dist/components/series-chart.js +72 -29
- package/dist/components/series-chart.js.map +1 -1
- package/dist/components/share-card.js +3 -3
- package/dist/components/share-card.js.map +1 -1
- package/dist/components/sign-chip-labels.d.ts +1 -0
- package/dist/components/sign-chip-labels.js.map +1 -1
- package/dist/components/sign-chip.d.ts +10 -1
- package/dist/components/sign-chip.js.map +1 -1
- package/dist/components/tabs-labels.d.ts +2 -0
- package/dist/components/tabs-labels.js +11 -0
- package/dist/components/tabs-labels.js.map +1 -0
- package/dist/components/tabs.d.ts +1 -1
- package/dist/components/tabs.js +13 -11
- package/dist/components/tabs.js.map +1 -1
- package/dist/components/toggle-legend.d.ts +2 -2
- package/dist/components/toggle-legend.js +6 -6
- package/dist/components/toggle-legend.js.map +1 -1
- package/dist/components/translation-review-editor.d.ts +4 -2
- package/dist/components/translation-review-editor.js +2 -3
- package/dist/components/translation-review-editor.js.map +1 -1
- package/dist/components/translation-review.d.ts +2 -1
- package/dist/components/translation-review.js +2 -2
- package/dist/components/translation-review.js.map +1 -1
- package/dist/components/treemap-labels.d.ts +26 -0
- package/dist/components/treemap-labels.js +10 -0
- package/dist/components/treemap-labels.js.map +1 -0
- package/dist/components/treemap-layout.d.ts +62 -0
- package/dist/components/treemap-layout.js +126 -0
- package/dist/components/treemap-layout.js.map +1 -0
- package/dist/components/treemap.d.ts +140 -17
- package/dist/components/treemap.js +324 -97
- package/dist/components/treemap.js.map +1 -1
- package/dist/components/use-table-state.d.ts +5 -5
- package/dist/components/use-table-state.js +4 -1
- package/dist/components/use-table-state.js.map +1 -1
- package/dist/data-table.d.ts +6 -2
- package/dist/data-table.js +7 -2
- package/dist/data-table.js.map +1 -1
- package/dist/eslint/index.js +1 -1
- package/dist/eslint/role-utilities.d.ts +36 -7
- package/dist/eslint/role-utilities.js +42 -9
- package/dist/eslint/role-utilities.js.map +1 -1
- package/dist/feedback/feedback-dialog.d.ts +25 -16
- package/dist/feedback/feedback-dialog.js +6 -2
- package/dist/feedback/feedback-dialog.js.map +1 -1
- package/dist/feedback/feedback-mutation.d.ts +30 -0
- package/dist/feedback/feedback-mutation.js +16 -0
- package/dist/feedback/feedback-mutation.js.map +1 -0
- package/dist/feedback/feedback-page-link.d.ts +53 -0
- package/dist/feedback/feedback-page-link.js +37 -0
- package/dist/feedback/feedback-page-link.js.map +1 -0
- package/dist/feedback/feedback-public-list.d.ts +12 -3
- package/dist/feedback/feedback-public-list.js +2 -1
- package/dist/feedback/feedback-public-list.js.map +1 -1
- package/dist/feedback/feedback-replies.d.ts +3 -1
- package/dist/feedback/feedback-replies.js +5 -4
- package/dist/feedback/feedback-replies.js.map +1 -1
- package/dist/feedback/feedback-row-detail-labels.js +5 -0
- package/dist/feedback/feedback-row-detail-labels.js.map +1 -1
- package/dist/feedback/feedback-row-detail.d.ts +64 -28
- package/dist/feedback/feedback-row-detail.js +30 -28
- package/dist/feedback/feedback-row-detail.js.map +1 -1
- package/dist/feedback/feedback-status-undo.d.ts +30 -11
- package/dist/feedback/feedback-status-undo.js +10 -15
- package/dist/feedback/feedback-status-undo.js.map +1 -1
- package/dist/feedback/feedback-submit-dialog.d.ts +1 -1
- package/dist/feedback/feedback-submit-dialog.js +1 -1
- package/dist/feedback/feedback-submit-dialog.js.map +1 -1
- package/dist/feedback/feedback-submit.js +9 -3
- package/dist/feedback/feedback-submit.js.map +1 -1
- package/dist/feedback/feedback-swipe.d.ts +1 -1
- package/dist/feedback/feedback-swipe.js.map +1 -1
- package/dist/feedback/feedback-table.d.ts +21 -9
- package/dist/feedback/feedback-table.js +45 -25
- package/dist/feedback/feedback-table.js.map +1 -1
- package/dist/feedback/feedback-thread-labels.d.ts +2 -2
- package/dist/feedback/feedback-thread-labels.js.map +1 -1
- package/dist/feedback/feedback-thread.d.ts +24 -23
- package/dist/feedback/feedback-thread.js +2 -1
- package/dist/feedback/feedback-thread.js.map +1 -1
- package/dist/feedback.d.ts +34 -0
- package/dist/feedback.js +42 -0
- package/dist/feedback.js.map +1 -1
- package/dist/hooks/use-dismiss.js.map +1 -1
- package/dist/hooks/use-focus-trap.d.ts +35 -0
- package/dist/hooks/use-focus-trap.js +6 -4
- package/dist/hooks/use-focus-trap.js.map +1 -1
- package/dist/hooks/use-hotkey.d.ts +5 -2
- package/dist/hooks/use-hotkey.js +5 -4
- package/dist/hooks/use-hotkey.js.map +1 -1
- package/dist/hooks/use-long-press.d.ts +7 -4
- package/dist/hooks/use-long-press.js +3 -0
- package/dist/hooks/use-long-press.js.map +1 -1
- package/dist/hooks/use-media-query.js +12 -4
- package/dist/hooks/use-media-query.js.map +1 -1
- package/dist/hooks/use-mounted.d.ts +22 -0
- package/dist/hooks/use-mounted.js +24 -0
- package/dist/hooks/use-mounted.js.map +1 -0
- package/dist/hooks/use-overlay-history.d.ts +7 -1
- package/dist/hooks/use-overlay-history.js +35 -5
- package/dist/hooks/use-overlay-history.js.map +1 -1
- package/dist/i18n/defaults.js +4 -5
- package/dist/i18n/defaults.js.map +1 -1
- package/dist/i18n/german.js +7 -1
- package/dist/i18n/german.js.map +1 -1
- package/dist/i18n/kit-labels.d.ts +9 -2
- package/dist/i18n/kit-labels.js.map +1 -1
- package/dist/i18n/locales/en.js +20 -41
- package/dist/i18n/locales/en.js.map +3 -3
- package/dist/i18n/locales/es.js +7 -1
- package/dist/i18n/locales/es.js.map +1 -1
- package/dist/i18n/locales/fr.js +20 -10
- package/dist/i18n/locales/fr.js.map +1 -1
- package/dist/i18n/locales/hu.js +9 -1
- package/dist/i18n/locales/hu.js.map +1 -1
- package/dist/i18n/locales/it.js +7 -1
- package/dist/i18n/locales/it.js.map +1 -1
- package/dist/i18n/locales/zh.js +8 -1
- package/dist/i18n/locales/zh.js.map +1 -1
- package/dist/i18n/review.js +5 -0
- package/dist/i18n/review.js.map +1 -1
- package/dist/index.d.ts +64 -17
- package/dist/index.js +77 -12
- package/dist/index.js.map +1 -1
- package/dist/landing/routing.d.ts +3 -1
- package/dist/landing/routing.js +4 -7
- package/dist/landing/routing.js.map +1 -1
- package/dist/lib/broadcast.d.ts +17 -0
- package/dist/lib/broadcast.js +30 -0
- package/dist/lib/broadcast.js.map +1 -0
- package/dist/lib/calc.d.ts +7 -1
- package/dist/lib/calc.js +3 -1
- package/dist/lib/calc.js.map +1 -1
- package/dist/lib/clipboard-minus.d.ts +2 -2
- package/dist/lib/clipboard-minus.js +1 -1
- package/dist/lib/clipboard-minus.js.map +1 -1
- package/dist/lib/date-format.d.ts +37 -2
- package/dist/lib/date-format.js +34 -8
- package/dist/lib/date-format.js.map +1 -1
- package/dist/lib/day-format.d.ts +46 -0
- package/dist/lib/day-format.js +46 -0
- package/dist/lib/day-format.js.map +1 -0
- package/dist/lib/decimal-marks.d.ts +7 -1
- package/dist/lib/decimal-marks.js +5 -2
- package/dist/lib/decimal-marks.js.map +1 -1
- package/dist/lib/describe-failure.d.ts +14 -0
- package/dist/lib/describe-failure.js +9 -0
- package/dist/lib/describe-failure.js.map +1 -0
- package/dist/lib/direction.d.ts +16 -0
- package/dist/lib/direction.js +9 -1
- package/dist/lib/direction.js.map +1 -1
- package/dist/lib/focus-left.d.ts +63 -0
- package/dist/lib/focus-left.js +67 -0
- package/dist/lib/focus-left.js.map +1 -0
- package/dist/lib/format.d.ts +5 -3
- package/dist/lib/format.js +16 -13
- package/dist/lib/format.js.map +1 -1
- package/dist/lib/http-status.d.ts +24 -0
- package/dist/lib/http-status.js +14 -0
- package/dist/lib/http-status.js.map +1 -0
- package/dist/lib/intl-cache.d.ts +14 -0
- package/dist/lib/intl-cache.js +15 -0
- package/dist/lib/intl-cache.js.map +1 -0
- package/dist/lib/isin.d.ts +10 -0
- package/dist/lib/isin.js.map +1 -1
- package/dist/lib/iso-day.d.ts +11 -0
- package/dist/lib/iso-day.js +8 -0
- package/dist/lib/iso-day.js.map +1 -0
- package/dist/lib/lazy-with-fallback.d.ts +31 -0
- package/dist/lib/lazy-with-fallback.js +40 -0
- package/dist/lib/lazy-with-fallback.js.map +1 -0
- package/dist/lib/path-pattern.d.ts +34 -0
- package/dist/lib/path-pattern.js +24 -0
- package/dist/lib/path-pattern.js.map +1 -0
- package/dist/lib/reduced-motion.d.ts +2 -1
- package/dist/lib/reduced-motion.js.map +1 -1
- package/dist/lib/round.d.ts +2 -1
- package/dist/lib/round.js +2 -1
- package/dist/lib/round.js.map +1 -1
- package/dist/lib/safe-storage.d.ts +24 -5
- package/dist/lib/safe-storage.js +27 -2
- package/dist/lib/safe-storage.js.map +1 -1
- package/dist/lib/session-refresh.js +1 -1
- package/dist/lib/session-refresh.js.map +1 -1
- package/dist/lib/share-format.d.ts +13 -0
- package/dist/lib/share-format.js +10 -0
- package/dist/lib/share-format.js.map +1 -0
- package/dist/lib/text-case.d.ts +17 -0
- package/dist/lib/text-case.js +8 -0
- package/dist/lib/text-case.js.map +1 -0
- package/dist/lib/text-match.d.ts +38 -0
- package/dist/lib/text-match.js +24 -2
- package/dist/lib/text-match.js.map +1 -1
- package/dist/lib/thenable.d.ts +13 -0
- package/dist/lib/thenable.js +8 -0
- package/dist/lib/thenable.js.map +1 -0
- package/dist/lib/translation-review.d.ts +7 -2
- package/dist/lib/translation-review.js +4 -4
- package/dist/lib/translation-review.js.map +1 -1
- package/dist/notifications/device-zone-report.js +1 -1
- package/dist/notifications/device-zone-report.js.map +1 -1
- package/dist/notifications/notification-bell.d.ts +2 -1
- package/dist/notifications/notification-bell.js +3 -3
- package/dist/notifications/notification-bell.js.map +1 -1
- package/dist/notifications/notification-inbox.d.ts +10 -6
- package/dist/notifications/notification-inbox.js +26 -48
- package/dist/notifications/notification-inbox.js.map +1 -1
- package/dist/notifications/notification-parts.d.ts +3 -2
- package/dist/notifications/notification-parts.js +1 -3
- package/dist/notifications/notification-parts.js.map +1 -1
- package/dist/notifications/notification-types-setting.js +1 -1
- package/dist/notifications/notification-types-setting.js.map +1 -1
- package/dist/notifications/notifications-labels.d.ts +6 -0
- package/dist/notifications/notifications-labels.js +1 -0
- package/dist/notifications/notifications-labels.js.map +1 -1
- package/dist/notifications/push-device-setting.js +1 -1
- package/dist/notifications/push-device-setting.js.map +1 -1
- package/dist/notifications/push-devices-setting.d.ts +2 -1
- package/dist/notifications/push-devices-setting.js +27 -49
- package/dist/notifications/push-devices-setting.js.map +1 -1
- package/dist/notifications/quiet-hours-setting.d.ts +10 -3
- package/dist/notifications/quiet-hours-setting.js +65 -26
- package/dist/notifications/quiet-hours-setting.js.map +1 -1
- package/dist/notifications/unsubscribe-panel.js +4 -7
- package/dist/notifications/unsubscribe-panel.js.map +1 -1
- package/dist/notifications/use-push-device.d.ts +39 -1
- package/dist/notifications/use-push-device.js +28 -7
- package/dist/notifications/use-push-device.js.map +1 -1
- package/dist/offline/query-persistence.d.ts +3 -1
- package/dist/offline/query-persistence.js +19 -2
- package/dist/offline/query-persistence.js.map +1 -1
- package/dist/rhf/fields.d.ts +11 -4
- package/dist/rhf/fields.js.map +1 -1
- package/dist/search/command-palette.js +1 -1
- package/dist/search/command-palette.js.map +1 -1
- package/dist/search/global-search.js +19 -9
- package/dist/search/global-search.js.map +1 -1
- package/dist/search/use-command-key.d.ts +12 -1
- package/dist/search/use-command-key.js +3 -12
- package/dist/search/use-command-key.js.map +1 -1
- package/dist/search.d.ts +7 -0
- package/dist/search.js +10 -0
- package/dist/search.js.map +1 -1
- package/dist/settings/use-settings-focus.js +1 -0
- package/dist/settings/use-settings-focus.js.map +1 -1
- package/dist/shell/account-menu-language.d.ts +21 -5
- package/dist/shell/account-menu-language.js +3 -1
- package/dist/shell/account-menu-language.js.map +1 -1
- package/dist/shell/account-menu-text-size.d.ts +26 -9
- package/dist/shell/account-menu-text-size.js +3 -2
- package/dist/shell/account-menu-text-size.js.map +1 -1
- package/dist/shell/dev-menu.js +5 -18
- package/dist/shell/dev-menu.js.map +1 -1
- package/dist/shell/role-switcher.d.ts +7 -0
- package/dist/shell/role-switcher.js.map +1 -1
- package/dist/shell/top-bar-actions.d.ts +1 -1
- package/dist/shell/top-bar-actions.js.map +1 -1
- package/dist/shell/top-bar-parts-labels.d.ts +0 -2
- package/dist/shell/top-bar-parts-labels.js +0 -1
- package/dist/shell/top-bar-parts-labels.js.map +1 -1
- package/dist/shell.d.ts +27 -8
- package/dist/shell.js +28 -7
- package/dist/shell.js.map +1 -1
- package/dist/sync/engine.d.ts +30 -4
- package/dist/sync/engine.js +172 -52
- package/dist/sync/engine.js.map +1 -1
- package/dist/sync.d.ts +6 -2
- package/dist/sync.js +6 -1
- package/dist/sync.js.map +1 -1
- package/dist/testing/css-variables.js +3 -8
- package/dist/testing/css-variables.js.map +1 -1
- package/dist/theme/contrast.d.ts +2 -1
- package/dist/theme/contrast.js +3 -8
- package/dist/theme/contrast.js.map +1 -1
- package/dist/theme/palette-store.js +6 -6
- package/dist/theme/palette-store.js.map +1 -1
- package/dist/theme/text-size.js +3 -8
- package/dist/theme/text-size.js.map +1 -1
- package/dist/theme/theme-store.js +3 -6
- package/dist/theme/theme-store.js.map +1 -1
- package/dist/tour/tour-catalogue.d.ts +7 -4
- package/dist/tour/tour-catalogue.js +12 -10
- package/dist/tour/tour-catalogue.js.map +1 -1
- package/dist/tour/tour-dock.d.ts +0 -2
- package/dist/tour/tour-dock.js +0 -2
- package/dist/tour/tour-dock.js.map +1 -1
- package/dist/tour/tour-gates.d.ts +4 -0
- package/dist/tour/tour-gates.js +14 -0
- package/dist/tour/tour-gates.js.map +1 -1
- package/dist/tour/tour-overlay.d.ts +27 -0
- package/dist/tour/tour-overlay.js +741 -0
- package/dist/tour/tour-overlay.js.map +1 -0
- package/dist/tour/tour.d.ts +16 -4
- package/dist/tour/tour.js +62 -778
- package/dist/tour/tour.js.map +1 -1
- package/dist/tour/use-tour-progress.js +1 -1
- package/dist/tour/use-tour-progress.js.map +1 -1
- package/dist/tour/use-tour-url-sync.js +2 -2
- package/dist/tour/use-tour-url-sync.js.map +1 -1
- package/dist/wizard/stepper-nav.d.ts +5 -1
- package/dist/wizard/stepper-nav.js.map +1 -1
- package/dist/wizard/types.d.ts +6 -2
- package/dist/wizard/types.js.map +1 -1
- package/dist/wizard/use-wizard.d.ts +3 -1
- package/dist/wizard/use-wizard.js.map +1 -1
- package/dist/wizard/validation.d.ts +3 -1
- package/dist/wizard/validation.js.map +1 -1
- package/package.json +12 -8
- package/src/account/account-parts.ts +5 -25
- package/src/account/data-export-setting-labels.ts +1 -1
- package/src/account/delete-account-setting-labels.ts +1 -1
- package/src/account/email-change-setting-labels.ts +1 -1
- package/src/account/passkeys-setting.tsx +60 -38
- package/src/account/sessions-setting.tsx +18 -12
- package/src/admin/admin-action-confirm.tsx +5 -10
- package/src/admin/admin-parts.ts +11 -25
- package/src/admin/mail-test-card-labels.ts +1 -1
- package/src/admin/plan-change-labels.ts +5 -23
- package/src/admin/plan-change.tsx +7 -44
- package/src/admin/reviewer-scope-editor.tsx +3 -3
- package/src/auth/auth-errors-labels.ts +23 -0
- package/src/auth/auth-errors.ts +11 -38
- package/src/auth/complete-name-dialog.tsx +9 -8
- package/src/auth/forgot-password-form-labels.ts +1 -1
- package/src/auth/forgot-password-form.tsx +11 -6
- package/src/auth/register-form-labels.ts +1 -1
- package/src/auth/reset-password-form-labels.ts +1 -1
- package/src/auth/reset-password-form.tsx +8 -4
- package/src/auth/sign-in-form-labels.ts +1 -1
- package/src/auth/status-parts.tsx +0 -6
- package/src/auth/verify-email-labels.ts +1 -1
- package/src/auth/verify-email.tsx +11 -6
- package/src/billing/cancel-request.ts +28 -6
- package/src/billing/cancel-subscription.tsx +29 -22
- package/src/billing/dialog-close.ts +34 -0
- package/src/billing/plan-card.tsx +36 -11
- package/src/billing/plan-change-labels.ts +66 -0
- package/src/billing/plan-switch.tsx +31 -20
- package/src/chart.ts +21 -3
- package/src/components/account-chips.tsx +20 -23
- package/src/components/alert-banner.tsx +82 -5
- package/src/components/amount-input.tsx +32 -14
- package/src/components/autocomplete.tsx +64 -70
- package/src/components/bulk-action-bar.tsx +70 -2
- package/src/components/button-look.ts +5 -5
- package/src/components/button.tsx +2 -2
- package/src/components/calculator.tsx +98 -17
- package/src/components/chart-edge.ts +34 -1
- package/src/components/chart-figure.tsx +35 -0
- package/src/components/chart-zoom-core.tsx +6 -5
- package/src/components/chart.tsx +26 -5
- package/src/components/combobox-core.tsx +303 -69
- package/src/components/combobox.tsx +184 -155
- package/src/components/copy-button.tsx +34 -23
- package/src/components/country-select.tsx +16 -11
- package/src/components/data-table-column-settings.tsx +52 -10
- package/src/components/data-table-filters.ts +6 -4
- package/src/components/data-table-fit.ts +19 -5
- package/src/components/data-table-groups.tsx +1 -1
- package/src/components/data-table-head.tsx +32 -22
- package/src/components/data-table-mobile.tsx +110 -27
- package/src/components/data-table-pagination.tsx +21 -6
- package/src/components/data-table-resize.ts +1 -1
- package/src/components/data-table-row-actions.tsx +3 -3
- package/src/components/data-table-row.tsx +25 -14
- package/src/components/data-table-selection.ts +1 -1
- package/src/components/data-table-shared.tsx +33 -1
- package/src/components/data-table-sort.ts +57 -2
- package/src/components/data-table-virtual.ts +32 -8
- package/src/components/data-table.tsx +267 -41
- package/src/components/date-field.tsx +65 -8
- package/src/components/date-picker.tsx +125 -48
- package/src/components/date-range-picker.tsx +82 -31
- package/src/components/dialog-frame.tsx +2 -1
- package/src/components/entity-combobox.tsx +4 -1
- package/src/components/error-boundary.tsx +53 -39
- package/src/components/field-base-labels.ts +20 -0
- package/src/components/field-base.tsx +13 -7
- package/src/components/field-sync-labels.ts +1 -0
- package/src/components/field-sync.tsx +23 -1
- package/src/components/form-actions.tsx +20 -5
- package/src/components/hover-menu.tsx +18 -8
- package/src/components/icon-button.tsx +14 -9
- package/src/components/inline-confirm.tsx +116 -0
- package/src/components/inline-entity-combobox.tsx +198 -152
- package/src/components/input.tsx +1 -1
- package/src/components/jump-calendar.tsx +30 -146
- package/src/components/legal-page.tsx +10 -7
- package/src/components/legal.tsx +4 -2
- package/src/components/lightbox.tsx +21 -8
- package/src/components/list.tsx +14 -5
- package/src/components/measured-grid.tsx +8 -4
- package/src/components/mini-calendar.tsx +6 -5
- package/src/components/modal.tsx +45 -4
- package/src/components/money-draft.ts +16 -5
- package/src/components/money-field.tsx +2 -2
- package/src/components/month-grid.tsx +229 -0
- package/src/components/month-picker.tsx +192 -200
- package/src/components/multi-entity-combobox.tsx +1 -0
- package/src/components/multi-select.tsx +21 -9
- package/src/components/number-field.tsx +14 -7
- package/src/components/number-input.tsx +9 -3
- package/src/components/numpad-sheet.tsx +4 -3
- package/src/components/picker-sheet.tsx +12 -9
- package/src/components/pie-chart-labels.ts +8 -0
- package/src/components/pie-chart.tsx +22 -28
- package/src/components/popover.tsx +18 -1
- package/src/components/reauth-dialog.tsx +6 -10
- package/src/components/row-actions.tsx +2 -1
- package/src/components/section-nav.tsx +7 -0
- package/src/components/series-chart-axes.ts +11 -3
- package/src/components/series-chart-labels.ts +7 -4
- package/src/components/series-chart.tsx +178 -69
- package/src/components/share-card.tsx +6 -6
- package/src/components/sign-chip-labels.ts +1 -0
- package/src/components/sign-chip.tsx +10 -1
- package/src/components/tabs-labels.ts +13 -0
- package/src/components/tabs.tsx +35 -19
- package/src/components/toggle-legend.tsx +16 -11
- package/src/components/translation-review-editor.tsx +6 -5
- package/src/components/translation-review.tsx +4 -3
- package/src/components/treemap-labels.ts +39 -0
- package/src/components/treemap-layout.ts +210 -0
- package/src/components/treemap.tsx +722 -133
- package/src/components/use-table-state.ts +12 -9
- package/src/data-table.ts +9 -2
- package/src/eslint/role-utilities.ts +97 -19
- package/src/feedback/feedback-dialog.tsx +30 -19
- package/src/feedback/feedback-mutation.ts +41 -0
- package/src/feedback/feedback-page-link.ts +90 -0
- package/src/feedback/feedback-public-list.tsx +17 -5
- package/src/feedback/feedback-replies.tsx +13 -6
- package/src/feedback/feedback-row-detail-labels.ts +5 -0
- package/src/feedback/feedback-row-detail.tsx +103 -67
- package/src/feedback/feedback-status-undo.ts +41 -27
- package/src/feedback/feedback-submit-dialog.tsx +2 -2
- package/src/feedback/feedback-submit.tsx +21 -7
- package/src/feedback/feedback-swipe.tsx +1 -1
- package/src/feedback/feedback-table.tsx +86 -38
- package/src/feedback/feedback-thread-labels.ts +2 -2
- package/src/feedback/feedback-thread.tsx +27 -25
- package/src/feedback.ts +42 -0
- package/src/hooks/use-dismiss.ts +3 -2
- package/src/hooks/use-focus-trap.ts +8 -24
- package/src/hooks/use-hotkey.ts +24 -7
- package/src/hooks/use-long-press.ts +16 -2
- package/src/hooks/use-media-query.ts +20 -4
- package/src/hooks/use-mounted.ts +39 -0
- package/src/hooks/use-overlay-history.ts +70 -5
- package/src/i18n/defaults.ts +4 -5
- package/src/i18n/german.ts +8 -2
- package/src/i18n/kit-labels.tsx +9 -2
- package/src/i18n/locales/es.ts +8 -2
- package/src/i18n/locales/fr.ts +21 -13
- package/src/i18n/locales/hu.ts +10 -2
- package/src/i18n/locales/it.ts +8 -2
- package/src/i18n/locales/zh.ts +9 -2
- package/src/i18n/review.ts +5 -0
- package/src/index.ts +103 -13
- package/src/landing/routing.tsx +14 -10
- package/src/lib/broadcast.ts +52 -0
- package/src/lib/calc.ts +13 -2
- package/src/lib/clipboard-minus.ts +14 -4
- package/src/lib/date-format.ts +89 -13
- package/src/lib/day-format.ts +96 -0
- package/src/lib/decimal-marks.ts +12 -3
- package/src/lib/describe-failure.ts +18 -0
- package/src/lib/direction.ts +39 -0
- package/src/lib/focus-left.ts +156 -0
- package/src/lib/format.ts +34 -19
- package/src/lib/http-status.ts +38 -0
- package/src/lib/intl-cache.ts +25 -0
- package/src/lib/isin.ts +10 -0
- package/src/lib/iso-day.ts +13 -0
- package/src/lib/lazy-with-fallback.ts +82 -0
- package/src/lib/path-pattern.ts +55 -0
- package/src/lib/reduced-motion.ts +2 -1
- package/src/lib/round.ts +7 -2
- package/src/lib/safe-storage.ts +48 -6
- package/src/lib/session-refresh.ts +1 -1
- package/src/lib/share-format.ts +18 -0
- package/src/lib/text-case.ts +19 -0
- package/src/lib/text-match.ts +69 -2
- package/src/lib/thenable.ts +19 -0
- package/src/lib/translation-review.ts +13 -5
- package/src/notifications/device-zone-report.ts +1 -1
- package/src/notifications/notification-bell.tsx +7 -4
- package/src/notifications/notification-inbox.tsx +40 -58
- package/src/notifications/notification-parts.tsx +3 -4
- package/src/notifications/notification-types-setting.tsx +1 -1
- package/src/notifications/notifications-labels.ts +7 -0
- package/src/notifications/push-device-setting.tsx +1 -1
- package/src/notifications/push-devices-setting.tsx +30 -55
- package/src/notifications/quiet-hours-setting.tsx +93 -31
- package/src/notifications/unsubscribe-panel.tsx +4 -7
- package/src/notifications/use-push-device.ts +76 -10
- package/src/offline/query-persistence.ts +35 -3
- package/src/rhf/fields.tsx +11 -4
- package/src/search/command-palette.tsx +2 -4
- package/src/search/global-search.tsx +36 -15
- package/src/search/use-command-key.ts +13 -12
- package/src/search.ts +9 -0
- package/src/settings/use-settings-focus.ts +3 -0
- package/src/shell/account-menu-language.tsx +27 -5
- package/src/shell/account-menu-text-size.tsx +32 -10
- package/src/shell/dev-menu.tsx +7 -21
- package/src/shell/role-switcher.tsx +7 -0
- package/src/shell/top-bar-actions.tsx +1 -1
- package/src/shell/top-bar-parts-labels.ts +0 -3
- package/src/shell.ts +40 -9
- package/src/sync/engine.ts +339 -61
- package/src/sync.ts +8 -1
- package/src/testing/css-variables.ts +8 -9
- package/src/theme/contrast.ts +8 -9
- package/src/theme/palette-store.ts +9 -9
- package/src/theme/text-size.ts +6 -8
- package/src/theme/theme-store.ts +7 -9
- package/src/tour/tour-catalogue.tsx +26 -15
- package/src/tour/tour-dock.ts +0 -2
- package/src/tour/tour-gates.ts +23 -0
- package/src/tour/tour-overlay.tsx +1170 -0
- package/src/tour/tour.tsx +116 -1193
- package/src/tour/use-tour-progress.ts +1 -1
- package/src/tour/use-tour-url-sync.ts +7 -3
- package/src/wizard/stepper-nav.tsx +3 -1
- package/src/wizard/types.ts +11 -2
- package/src/wizard/use-wizard.ts +2 -1
- package/src/wizard/validation.ts +8 -2
- package/tokens.css +2 -1
- package/dist/components/ui-labels.js.map +0 -1
- package/dist/shell/dev-switchers.d.ts +0 -6
- package/dist/shell/dev-switchers.js +0 -12
- package/dist/shell/dev-switchers.js.map +0 -1
- package/src/components/ui-labels.ts +0 -24
- package/src/shell/dev-switchers.tsx +0 -18
|
@@ -0,0 +1,96 @@
|
|
|
1
|
+
import { useCallback } from "react";
|
|
2
|
+
import { useKitDateFormatter, useKitLocale, useKitTimeZone } from "../i18n/kit-labels";
|
|
3
|
+
import { toLocalIso } from "./dates";
|
|
4
|
+
import { clockTime } from "./date-format";
|
|
5
|
+
import { EMPTY_FORMATTED_VALUE, formatDate, toDate, type DateInput, type FormatDateStyle } from "./format";
|
|
6
|
+
import { dateFormatter } from "./intl-cache";
|
|
7
|
+
import { isBareIsoDay } from "./iso-day";
|
|
8
|
+
|
|
9
|
+
/**
|
|
10
|
+
* How a kit component prints a day — ONE ladder (refactor audit 2026-10-30, DUP-2):
|
|
11
|
+
*
|
|
12
|
+
* 1. the component's own prop (`formatDate`, `renderDate`), when the app gave one and it
|
|
13
|
+
* answers;
|
|
14
|
+
* 2. else the `<UiKitProvider formatDate>` (keksdose K12: the app's date-format
|
|
15
|
+
* preference), asked for the calendar day with `source: "dateMark"`;
|
|
16
|
+
* 3. else the kit's `formatDate` in the provider's locale AND `timeZone` (0.46).
|
|
17
|
+
*
|
|
18
|
+
* 0.46's rule — "a label that identifies a day follows the preference" — held only where
|
|
19
|
+
* a component wrote that ladder itself: four copies (admin's `useDayText`, AccountStateChip,
|
|
20
|
+
* DateMark, the feedback table), while about twelve components took their own prop or
|
|
21
|
+
* nothing and went straight to `lib/format`. keksdose set the provider's `formatDate` and
|
|
22
|
+
* still passed it into six components by hand; and the 10 that imported the raw
|
|
23
|
+
* `formatDate` ignored the provider's `timeZone`.
|
|
24
|
+
*
|
|
25
|
+
* @internal Not part of the barrel: the components' props are the public way in.
|
|
26
|
+
*/
|
|
27
|
+
|
|
28
|
+
/** What a {@link DayFormatter} call may ask for. */
|
|
29
|
+
export interface DayTextOptions {
|
|
30
|
+
/**
|
|
31
|
+
* Name the day of the week — what the provider's formatter is told (its `weekday`).
|
|
32
|
+
* keksdose's rule: a date in a COLUMN carries it, a date in a SENTENCE does not
|
|
33
|
+
* (dev#546). Default `false`. The kit's own rendering follows `style`, not this.
|
|
34
|
+
*/
|
|
35
|
+
weekday?: boolean;
|
|
36
|
+
/** Add the clock time, in the language (date-format rule 3): a timestamp. Default false. */
|
|
37
|
+
time?: boolean;
|
|
38
|
+
/** The kit's own rendering (step 3). Default `"medium"`, `"dateTime"` with `time`. */
|
|
39
|
+
style?: FormatDateStyle | Intl.DateTimeFormatOptions;
|
|
40
|
+
/** `false`: skip the provider (step 2) — a component's explicit style wins over it,
|
|
41
|
+
* as `DateMark`'s `dateStyle` does. Default `true`. */
|
|
42
|
+
preference?: boolean;
|
|
43
|
+
/** Printed for no value. Default "—". */
|
|
44
|
+
empty?: string;
|
|
45
|
+
}
|
|
46
|
+
|
|
47
|
+
/** A component's day printer: a value in, its text out. */
|
|
48
|
+
export type DayFormatter<V extends DateInput = DateInput> = (value: V, options?: DayTextOptions) => string;
|
|
49
|
+
|
|
50
|
+
/** The calendar day `date` falls on in `timeZone`, as "YYYY-MM-DD" — so the day the
|
|
51
|
+
* provider is asked for is the day the kit's own rendering would print. */
|
|
52
|
+
function isoDayIn(date: Date, timeZone: string | undefined): string {
|
|
53
|
+
if (!timeZone) return toLocalIso(date);
|
|
54
|
+
try {
|
|
55
|
+
// `en-CA` writes YYYY-MM-DD with Latin digits.
|
|
56
|
+
const parts = dateFormatter("en-CA", { timeZone, year: "numeric", month: "2-digit", day: "2-digit" }).formatToParts(
|
|
57
|
+
date,
|
|
58
|
+
);
|
|
59
|
+
const part = (type: Intl.DateTimeFormatPartTypes) => parts.find((p) => p.type === type)?.value ?? "";
|
|
60
|
+
return `${part("year")}-${part("month")}-${part("day")}`;
|
|
61
|
+
} catch {
|
|
62
|
+
return toLocalIso(date);
|
|
63
|
+
}
|
|
64
|
+
}
|
|
65
|
+
|
|
66
|
+
/**
|
|
67
|
+
* The component's day printer, bound to its `prop`, the provider's `formatDate`, locale
|
|
68
|
+
* and `timeZone`. `prop` is called with the value as the component passed it, and wins
|
|
69
|
+
* whenever it answers non-empty. A value that does not parse is printed as it came
|
|
70
|
+
* (a bug upstream is better seen than hidden behind a dash).
|
|
71
|
+
*/
|
|
72
|
+
export function useDayFormatter<V extends DateInput = DateInput>(
|
|
73
|
+
prop?: ((value: V) => string) | null,
|
|
74
|
+
localeProp?: string,
|
|
75
|
+
): DayFormatter<V> {
|
|
76
|
+
const locale = useKitLocale(localeProp);
|
|
77
|
+
const timeZone = useKitTimeZone();
|
|
78
|
+
const fromProvider = useKitDateFormatter();
|
|
79
|
+
return useCallback<DayFormatter<V>>(
|
|
80
|
+
(value, options = {}) => {
|
|
81
|
+
const own = prop?.(value);
|
|
82
|
+
if (own) return own;
|
|
83
|
+
if (value === null || value === undefined || value === "") return options.empty ?? EMPTY_FORMATTED_VALUE;
|
|
84
|
+
const date = toDate(value);
|
|
85
|
+
if (!date) return String(value);
|
|
86
|
+
const bareDay = isBareIsoDay(value);
|
|
87
|
+
if (fromProvider && options.preference !== false) {
|
|
88
|
+
const iso = bareDay ? value : isoDayIn(date, timeZone);
|
|
89
|
+
const day = fromProvider(iso, { unit: "day", source: "dateMark", locale, weekday: options.weekday ?? false });
|
|
90
|
+
if (day) return options.time && !bareDay ? `${day}, ${clockTime(date, locale, timeZone)}` : day;
|
|
91
|
+
}
|
|
92
|
+
return formatDate(value, options.style ?? (options.time ? "dateTime" : "medium"), { locale, timeZone });
|
|
93
|
+
},
|
|
94
|
+
[prop, fromProvider, locale, timeZone],
|
|
95
|
+
);
|
|
96
|
+
}
|
package/src/lib/decimal-marks.ts
CHANGED
|
@@ -37,7 +37,13 @@ export function decimalMark(locale: string | undefined): "," | "." {
|
|
|
37
37
|
* field's settle then made that 1.23, final. This decides per operand, from the
|
|
38
38
|
* typist's own text, before that fold:
|
|
39
39
|
*
|
|
40
|
-
* - both marks present: the one
|
|
40
|
+
* - both marks present: the LAST one is the decimal mark, whichever the locale's is, and
|
|
41
|
+
* the other is grouping and goes. The order says the convention the figure was written
|
|
42
|
+
* in — "1.234,56" German, "1,234.56" English — and a figure pasted from another app or
|
|
43
|
+
* locale keeps it. Taking the non-locale mark as grouping wherever it stood read
|
|
44
|
+
* "1.234,56" in a "." locale (en, de-CH) as 1.23456, which a money field then settled
|
|
45
|
+
* to 1.23 (refactor audit 2026-10-30, INP-3). Typed in the locale's own convention, its
|
|
46
|
+
* mark comes last and nothing changes;
|
|
41
47
|
* - in a "," locale, only "." present: grouping when it cannot be a decimal as a
|
|
42
48
|
* German reader writes it — twice ("1.234.567"), or in thousands shape ("1.234",
|
|
43
49
|
* "12.500") — otherwise a decimal ("1.5", typed by a dot-decimal habit). A first
|
|
@@ -53,10 +59,13 @@ export function decimalMark(locale: string | undefined): "," | "." {
|
|
|
53
59
|
export function normalizeTypedMarks(raw: string, mark: "," | "."): string {
|
|
54
60
|
const other = mark === "," ? "." : ",";
|
|
55
61
|
return raw.replace(/[0-9.,]+/g, (operand) => {
|
|
56
|
-
const hasMark = operand.includes(mark);
|
|
57
62
|
const count = operand.split(other).length - 1;
|
|
58
63
|
if (count === 0) return operand;
|
|
59
|
-
|
|
64
|
+
if (operand.includes(mark)) {
|
|
65
|
+
const grouping = operand.lastIndexOf(mark) > operand.lastIndexOf(other) ? other : mark;
|
|
66
|
+
return operand.split(grouping).join("");
|
|
67
|
+
}
|
|
68
|
+
const grouping = count > 1 || (mark === "," && /^[1-9]\d{0,2}(\.\d{3})+$/.test(operand));
|
|
60
69
|
return grouping ? operand.split(other).join("") : operand;
|
|
61
70
|
});
|
|
62
71
|
}
|
|
@@ -0,0 +1,18 @@
|
|
|
1
|
+
import type { ReactNode } from "react";
|
|
2
|
+
import { hasContent } from "./presence";
|
|
3
|
+
|
|
4
|
+
/**
|
|
5
|
+
* The failure ladder, once: the app's words for a failure when it has any, else the
|
|
6
|
+
* kit's `fallback`.
|
|
7
|
+
*
|
|
8
|
+
* "Any" is {@link hasContent}, so an app's `describeError` answering `""` (nothing to say
|
|
9
|
+
* about this one) gets the kit's sentence. Written as `own ?? fallback` in the auth forms,
|
|
10
|
+
* where `""` printed an empty alert, and both ways within one file in the reviewer scope
|
|
11
|
+
* editor; it lived in the notification cards' parts only (refactor audit 2026-10-30,
|
|
12
|
+
* DUP-14).
|
|
13
|
+
*
|
|
14
|
+
* @internal Package-private — not re-exported from the barrel.
|
|
15
|
+
*/
|
|
16
|
+
export function describeFailure(own: ReactNode | undefined, fallback: ReactNode): ReactNode {
|
|
17
|
+
return hasContent(own) ? own : fallback;
|
|
18
|
+
}
|
package/src/lib/direction.ts
CHANGED
|
@@ -33,3 +33,42 @@ export function horizontalStep(key: string, el: Element | null | undefined): 1 |
|
|
|
33
33
|
const forward = (key === "ArrowRight") !== isRtl(el);
|
|
34
34
|
return forward ? 1 : -1;
|
|
35
35
|
}
|
|
36
|
+
|
|
37
|
+
/**
|
|
38
|
+
* Where a key moves the focus in a list with ONE tab stop (a roving tabindex): the index
|
|
39
|
+
* to focus from `at` among `count` items, or `undefined` for a key that moves nothing.
|
|
40
|
+
* ←/→ along `dir` — → is next in `ltr` and previous in `rtl` — ↓/↑ as next and previous,
|
|
41
|
+
* Home and End to the ends. With `wrap`, past the last is the first and before the first
|
|
42
|
+
* the last (a ring: PieChart's slices); without, the ends hold (a plane: Treemap's tiles).
|
|
43
|
+
*
|
|
44
|
+
* The charts each mapped the keys themselves, and differently at the ends (0.52 code
|
|
45
|
+
* review of treemap.tsx, finding 9); the end rule is now a word at the call.
|
|
46
|
+
*
|
|
47
|
+
* `dir` and not an element to read it off (0.52 code review, deep, charts, findings 1 and
|
|
48
|
+
* 14): a list in the page's flow takes the page's (`dirOf(el)`), but a plot is laid out
|
|
49
|
+
* left to right in any page (see `ChartContainer`) and passes `"ltr"` — read off the
|
|
50
|
+
* element, Treemap's → walked an RTL page's tiles backwards, against the picture.
|
|
51
|
+
*/
|
|
52
|
+
export function rovingTarget(
|
|
53
|
+
key: string,
|
|
54
|
+
dir: Direction,
|
|
55
|
+
at: number,
|
|
56
|
+
count: number,
|
|
57
|
+
wrap: boolean,
|
|
58
|
+
): number | undefined {
|
|
59
|
+
const physical = key === "ArrowRight" ? 1 : key === "ArrowLeft" ? -1 : 0;
|
|
60
|
+
const step = dir === "rtl" ? -physical : physical;
|
|
61
|
+
const to = step
|
|
62
|
+
? at + step
|
|
63
|
+
: key === "ArrowDown"
|
|
64
|
+
? at + 1
|
|
65
|
+
: key === "ArrowUp"
|
|
66
|
+
? at - 1
|
|
67
|
+
: key === "Home"
|
|
68
|
+
? 0
|
|
69
|
+
: key === "End"
|
|
70
|
+
? count - 1
|
|
71
|
+
: undefined;
|
|
72
|
+
if (to === undefined || count <= 0) return undefined;
|
|
73
|
+
return wrap ? ((to % count) + count) % count : Math.max(0, Math.min(count - 1, to));
|
|
74
|
+
}
|
|
@@ -0,0 +1,156 @@
|
|
|
1
|
+
// "The focused node left" (refactor audit 2026-10-30, Wave 1: DSP-4, DSP-15). When the
|
|
2
|
+
// element holding the keyboard's focus is removed — a table row deleted, filtered out or
|
|
3
|
+
// approved; a bulk bar gone with its Clear; a banner its × took away — the browser puts
|
|
4
|
+
// focus on <body> and says nothing: no blur in Chromium, none in jsdom. A keyboard or
|
|
5
|
+
// screen-reader user then starts again from the top of the page. The overlays give focus
|
|
6
|
+
// back to their opener (use-focus-trap); these helpers are for the controls that leave
|
|
7
|
+
// the page while the focus is IN them, and decide where it goes instead.
|
|
8
|
+
|
|
9
|
+
/**
|
|
10
|
+
* Candidate tab stops, in DOM order — narrowed by {@link isTabStop} to the ones a Tab
|
|
11
|
+
* really reaches. The kit's one copy of the rule (0.52 code review, lib/focus-left.ts):
|
|
12
|
+
* this file and use-focus-trap each had it, with an exported `firstTabStop` apiece that
|
|
13
|
+
* disagreed about the element itself, and a combobox panel's toolbar had a third
|
|
14
|
+
* selector. The trap, the focus a removed node drops (below), the tour's field ring and
|
|
15
|
+
* the toolbar all read it here, so "the next stop" is the same stop everywhere.
|
|
16
|
+
*
|
|
17
|
+
* The selector is the one `Modal` used. On its own it was not enough (round 0.34
|
|
18
|
+
* BUG-4): only the bare `[tabindex]` clause excluded `-1`, so a `button`, an `input` or
|
|
19
|
+
* a link taken out of the tab order still counted. A panel that ends in a roving grid —
|
|
20
|
+
* the calendar's days, the month grid, the picker sheet's rows, every one of them `-1`
|
|
21
|
+
* but the active cell — then had a "last" stop no Tab ever reaches: Tab from the real
|
|
22
|
+
* last stop was not wrapped and walked out of the open panel, and Shift+Tab from the
|
|
23
|
+
* first landed on a cell that is not a stop at all.
|
|
24
|
+
*/
|
|
25
|
+
// `input[type=hidden]` is no stop: a Tab never lands on it and focus() on it does nothing,
|
|
26
|
+
// but its tabIndex reads 0, so a trap could take a form's hidden field for its first or last
|
|
27
|
+
// stop and Shift+Tab left the dialog (0.52 code review).
|
|
28
|
+
const TAB_STOP =
|
|
29
|
+
'a[href],button:not([disabled]),textarea:not([disabled]),input:not([disabled]):not([type="hidden"]),select:not([disabled]),[tabindex]:not([tabindex="-1"])';
|
|
30
|
+
|
|
31
|
+
/**
|
|
32
|
+
* A stop the browser's own Tab would land on: in the tab order (`tabIndex` ≥ 0) and not
|
|
33
|
+
* inside something `hidden` or `inert`. Removes only elements a native Tab never
|
|
34
|
+
* reaches, so no correct order changes. `visibility: hidden` and closed `<details>` are
|
|
35
|
+
* still not walked — they need layout, which this rule has never read.
|
|
36
|
+
*/
|
|
37
|
+
function isTabStop(el: HTMLElement): boolean {
|
|
38
|
+
return el.tabIndex >= 0 && !el.closest("[hidden],[inert]");
|
|
39
|
+
}
|
|
40
|
+
|
|
41
|
+
export interface TabStopOptions {
|
|
42
|
+
/** Whether `el` itself counts, first, when it is a stop. Default true: the tour's
|
|
43
|
+
* target may BE the field (refactor audit 2026-10-30, DUP-9). False for "a control
|
|
44
|
+
* inside it" — a row, a drawer, a trap's container, a toolbar. */
|
|
45
|
+
includeSelf?: boolean;
|
|
46
|
+
}
|
|
47
|
+
|
|
48
|
+
/** The tab stops in `el`, in DOM order — `el` itself first when it is one, unless
|
|
49
|
+
* `includeSelf: false`. */
|
|
50
|
+
export function tabStops(el: Element, { includeSelf = true }: TabStopOptions = {}): HTMLElement[] {
|
|
51
|
+
const inside = Array.from(el.querySelectorAll<HTMLElement>(TAB_STOP)).filter(isTabStop);
|
|
52
|
+
const own = includeSelf && el instanceof HTMLElement && el.matches(TAB_STOP) && isTabStop(el);
|
|
53
|
+
return own ? [el, ...inside] : inside;
|
|
54
|
+
}
|
|
55
|
+
|
|
56
|
+
/** The first of {@link tabStops} — the control a person types into or presses — or null. */
|
|
57
|
+
export function firstTabStop(el: Element, options?: TabStopOptions): HTMLElement | null {
|
|
58
|
+
return tabStops(el, options)[0] ?? null;
|
|
59
|
+
}
|
|
60
|
+
|
|
61
|
+
/**
|
|
62
|
+
* Whether the focus has fallen out of the page: onto `<body>`, onto nothing, or onto a
|
|
63
|
+
* node no longer in the document. False on the server, where nothing has focus to lose.
|
|
64
|
+
* A recovery asks this first: focus that went somewhere real (a dialog, the next field,
|
|
65
|
+
* an app's own `focus()`) is the user's or the app's, and is left where it is.
|
|
66
|
+
*/
|
|
67
|
+
export function focusIsLost(): boolean {
|
|
68
|
+
if (typeof document === "undefined") return false;
|
|
69
|
+
const el = document.activeElement;
|
|
70
|
+
return !el || el === document.body || !el.isConnected;
|
|
71
|
+
}
|
|
72
|
+
|
|
73
|
+
/**
|
|
74
|
+
* Calls `then` when a `blur`/`focusout` was the user's own move to nothing — a click on
|
|
75
|
+
* the page's background, or a click Safari answers by focusing nothing (it focuses no
|
|
76
|
+
* button or link on a click, and blurs what had the focus) — after which a note of where
|
|
77
|
+
* the focus was is stale (0.52 code review: DataTable's row, BulkActionBar's and
|
|
78
|
+
* AlertBanner's notes outlived it, and a removal much later pulled the focus, and the
|
|
79
|
+
* scroll, back to them).
|
|
80
|
+
*
|
|
81
|
+
* No element took the focus, the document holds none, and the node that lost it could
|
|
82
|
+
* still hold it. Not when it was removed, hidden, made inert or disabled: that is the page
|
|
83
|
+
* taking the focus away — the very case those notes are kept for. Not a window losing the
|
|
84
|
+
* focus either, which leaves the node the document's active element. Decided a microtask
|
|
85
|
+
* later, once the event's own work is done: a browser that blurs a node it is removing
|
|
86
|
+
* (or hiding) may do it while the node is still in place, and only after it is gone is
|
|
87
|
+
* that told apart from a click.
|
|
88
|
+
*/
|
|
89
|
+
export function whenFocusLeftForNothing(
|
|
90
|
+
e: { target: EventTarget | null; relatedTarget: EventTarget | null },
|
|
91
|
+
then: () => void,
|
|
92
|
+
): void {
|
|
93
|
+
const el = e.target;
|
|
94
|
+
if (e.relatedTarget !== null || !(el instanceof Element)) return;
|
|
95
|
+
queueMicrotask(() => {
|
|
96
|
+
if (!el.isConnected || el.matches(":disabled") || el.closest("[hidden],[inert]")) return;
|
|
97
|
+
// `display: none`, where the browser can say (jsdom cannot).
|
|
98
|
+
if (typeof el.checkVisibility === "function" && !el.checkVisibility()) return;
|
|
99
|
+
if (focusIsLost()) then();
|
|
100
|
+
});
|
|
101
|
+
}
|
|
102
|
+
|
|
103
|
+
/**
|
|
104
|
+
* The tab stops around `frame`, outside it, nearest first on each side — where focus
|
|
105
|
+
* goes once `frame` is gone. Read BEFORE it goes: a removed node has no place in the
|
|
106
|
+
* document to measure from. `limit` per side keeps a long page's stops out of memory.
|
|
107
|
+
*
|
|
108
|
+
* Walked outwards from the frame, `limit` stops each way (0.52 code review,
|
|
109
|
+
* lib/focus-left.ts): read from every stop in the page, a banner under a 2000-row table
|
|
110
|
+
* read all 2000 to keep the nearest five before it.
|
|
111
|
+
*/
|
|
112
|
+
export function tabStopsAround(frame: Element, limit = 5): { after: HTMLElement[]; before: HTMLElement[] } {
|
|
113
|
+
const doc = frame.ownerDocument;
|
|
114
|
+
const walker = doc.createTreeWalker(doc.documentElement, NodeFilter.SHOW_ELEMENT);
|
|
115
|
+
const isStop = (node: Node): node is HTMLElement =>
|
|
116
|
+
node instanceof HTMLElement && node.matches(TAB_STOP) && isTabStop(node);
|
|
117
|
+
// After: from the first element past the frame's own subtree, in document order.
|
|
118
|
+
const after: HTMLElement[] = [];
|
|
119
|
+
walker.currentNode = frame;
|
|
120
|
+
let node: Node | null = walker.nextSibling();
|
|
121
|
+
while (!node && walker.parentNode()) node = walker.nextSibling();
|
|
122
|
+
for (; node && after.length < limit; node = walker.nextNode()) if (isStop(node)) after.push(node);
|
|
123
|
+
// Before: back from the frame, nearest first (its ancestors among them, as before).
|
|
124
|
+
const before: HTMLElement[] = [];
|
|
125
|
+
walker.currentNode = frame;
|
|
126
|
+
for (node = walker.previousNode(); node && before.length < limit; node = walker.previousNode())
|
|
127
|
+
if (isStop(node)) before.push(node);
|
|
128
|
+
return { after, before };
|
|
129
|
+
}
|
|
130
|
+
|
|
131
|
+
/**
|
|
132
|
+
* Focus the first of `candidates` that is still in the page and takes the focus; true
|
|
133
|
+
* when one did. Each is tried and checked, since `focus()` on a node that cannot hold it
|
|
134
|
+
* (detached, `display: none`, disabled since) fails without a word.
|
|
135
|
+
*/
|
|
136
|
+
export function focusFirst(candidates: Iterable<Element | null | undefined>): boolean {
|
|
137
|
+
for (const el of candidates) {
|
|
138
|
+
if (!(el instanceof HTMLElement) || !el.isConnected) continue;
|
|
139
|
+
el.focus();
|
|
140
|
+
if (document.activeElement === el) return true;
|
|
141
|
+
}
|
|
142
|
+
return false;
|
|
143
|
+
}
|
|
144
|
+
|
|
145
|
+
/**
|
|
146
|
+
* Focus a container that is not a tab stop of its own — a table, a list — as the place
|
|
147
|
+
* the user is in, without making it one: `tabindex="-1"` for as long as it holds the
|
|
148
|
+
* focus, unless it already carries a `tabindex` of its own.
|
|
149
|
+
*/
|
|
150
|
+
export function focusContainer(el: HTMLElement): void {
|
|
151
|
+
if (!el.hasAttribute("tabindex")) {
|
|
152
|
+
el.setAttribute("tabindex", "-1");
|
|
153
|
+
el.addEventListener("blur", () => el.removeAttribute("tabindex"), { once: true });
|
|
154
|
+
}
|
|
155
|
+
el.focus();
|
|
156
|
+
}
|
package/src/lib/format.ts
CHANGED
|
@@ -1,6 +1,8 @@
|
|
|
1
1
|
import { useMemo } from "react";
|
|
2
2
|
import { useKitLocale, useKitTimeZone } from "../i18n/kit-labels";
|
|
3
3
|
import { parseIsoDate } from "./dates";
|
|
4
|
+
import { dateFormatter } from "./intl-cache";
|
|
5
|
+
import { isBareIsoDay } from "./iso-day";
|
|
4
6
|
import { formatWithMinus, type MinusStyle } from "./minus";
|
|
5
7
|
import { roundHalfAway } from "./round";
|
|
6
8
|
|
|
@@ -278,9 +280,6 @@ export interface FormatDateOptions extends BaseOptions {
|
|
|
278
280
|
timeZone?: string;
|
|
279
281
|
}
|
|
280
282
|
|
|
281
|
-
/** A bare ISO calendar day, `"YYYY-MM-DD"`. */
|
|
282
|
-
const BARE_ISO_DAY = /^\d{4}-\d{2}-\d{2}$/;
|
|
283
|
-
|
|
284
283
|
/** What {@link formatDate} and {@link formatRelativeTime} accept. */
|
|
285
284
|
export type DateInput = string | number | Date | null | undefined;
|
|
286
285
|
|
|
@@ -292,22 +291,11 @@ export type DateInput = string | number | Date | null | undefined;
|
|
|
292
291
|
*/
|
|
293
292
|
export function toDate(value: DateInput): Date | null {
|
|
294
293
|
if (value === null || value === undefined || value === "") return null;
|
|
295
|
-
if (
|
|
294
|
+
if (isBareIsoDay(value)) return parseIsoDate(value);
|
|
296
295
|
const d = value instanceof Date ? value : new Date(value);
|
|
297
296
|
return Number.isNaN(d.getTime()) ? null : d;
|
|
298
297
|
}
|
|
299
298
|
|
|
300
|
-
const dateFormatters = new Map<string, Intl.DateTimeFormat>();
|
|
301
|
-
function dateFormatter(locale: string | undefined, options: Intl.DateTimeFormatOptions): Intl.DateTimeFormat {
|
|
302
|
-
const key = `${locale ?? ""}|${JSON.stringify(options)}`;
|
|
303
|
-
let f = dateFormatters.get(key);
|
|
304
|
-
if (!f) {
|
|
305
|
-
f = new Intl.DateTimeFormat(locale, options);
|
|
306
|
-
dateFormatters.set(key, f);
|
|
307
|
-
}
|
|
308
|
-
return f;
|
|
309
|
-
}
|
|
310
|
-
|
|
311
299
|
/**
|
|
312
300
|
* A date or timestamp in `locale`. Takes an ISO date ("2026-07-08", read on the local
|
|
313
301
|
* calendar), an ISO timestamp ("2026-07-08T14:05:00Z"), epoch milliseconds or a Date.
|
|
@@ -327,7 +315,7 @@ export function formatDate(
|
|
|
327
315
|
// A bare "YYYY-MM-DD" is a calendar day, which has no zone: it is the day it names
|
|
328
316
|
// wherever it is read, so a `timeZone` (in `options` or the style) never moves it — the
|
|
329
317
|
// device's local midnight shown in a zone west of it was the day before (round 0.45, N9).
|
|
330
|
-
if (
|
|
318
|
+
if (isBareIsoDay(value)) {
|
|
331
319
|
const day = new Date(Date.UTC(d.getFullYear(), d.getMonth(), d.getDate()));
|
|
332
320
|
return dateFormatter(options.locale, { ...base, timeZone: "UTC" }).format(day);
|
|
333
321
|
}
|
|
@@ -335,8 +323,8 @@ export function formatDate(
|
|
|
335
323
|
}
|
|
336
324
|
|
|
337
325
|
export interface FormatRelativeTimeOptions extends BaseOptions {
|
|
338
|
-
/** The zone of the date printed past `absoluteAfterDays` (0.46)
|
|
339
|
-
* device's. */
|
|
326
|
+
/** The zone of the date printed past `absoluteAfterDays` (0.46), and (0.51.7) the zone
|
|
327
|
+
* whose calendar days "yesterday" and "2 days ago" count. Left out: the device's. */
|
|
340
328
|
timeZone?: string;
|
|
341
329
|
/** The moment it is measured from. Default: now. */
|
|
342
330
|
now?: DateInput;
|
|
@@ -370,6 +358,20 @@ const RELATIVE_STEPS: Array<[number, Intl.RelativeTimeFormatUnit, number]> = [
|
|
|
370
358
|
[Infinity, "year", 365.25 * DAY],
|
|
371
359
|
];
|
|
372
360
|
|
|
361
|
+
/**
|
|
362
|
+
* `d`'s calendar day in `timeZone` (left out: the device's), as a whole number of days:
|
|
363
|
+
* that day's UTC midnight over a day's length. Two of them subtract to whole calendar
|
|
364
|
+
* days — a 23- or 25-hour DST day still counts one.
|
|
365
|
+
*/
|
|
366
|
+
function dayNumber(d: Date, timeZone: string | undefined): number {
|
|
367
|
+
if (!timeZone) return Date.UTC(d.getFullYear(), d.getMonth(), d.getDate()) / DAY;
|
|
368
|
+
// `en-US`: Gregorian, Latin digits — the parts are read back as numbers.
|
|
369
|
+
const fields: Intl.DateTimeFormatOptions = { timeZone, year: "numeric", month: "numeric", day: "numeric" };
|
|
370
|
+
const parts = dateFormatter("en-US", fields).formatToParts(d);
|
|
371
|
+
const part = (type: Intl.DateTimeFormatPartTypes) => Number(parts.find((p) => p.type === type)?.value);
|
|
372
|
+
return Date.UTC(part("year"), part("month") - 1, part("day")) / DAY;
|
|
373
|
+
}
|
|
374
|
+
|
|
373
375
|
const relativeFormatters = new Map<string, Intl.RelativeTimeFormat>();
|
|
374
376
|
function relativeFormatter(
|
|
375
377
|
locale: string | undefined,
|
|
@@ -389,7 +391,9 @@ function relativeFormatter(
|
|
|
389
391
|
* How long ago (or until) `value` is, in `locale`'s words, through
|
|
390
392
|
* `Intl.RelativeTimeFormat`: "3 hours ago", "vor 3 Stunden", "il y a 3 heures",
|
|
391
393
|
* "in 2 days", and under 45 seconds "now". The unit is picked by size — seconds,
|
|
392
|
-
* minutes, hours, days, weeks, months, years — and the count is rounded
|
|
394
|
+
* minutes, hours, days, weeks, months, years — and the count is rounded; days are
|
|
395
|
+
* CALENDAR days (0.51.7), in `timeZone` when given: "yesterday" is the day before today,
|
|
396
|
+
* however few hours ago that was.
|
|
393
397
|
*/
|
|
394
398
|
export function formatRelativeTime(value: DateInput, options: FormatRelativeTimeOptions = {}): string {
|
|
395
399
|
const d = toDate(value);
|
|
@@ -402,6 +406,17 @@ export function formatRelativeTime(value: DateInput, options: FormatRelativeTime
|
|
|
402
406
|
}
|
|
403
407
|
const rtf = relativeFormatter(options.locale, options.numeric ?? "auto", options.style ?? "long");
|
|
404
408
|
const [, unit, size] = RELATIVE_STEPS.find(([limit]) => abs < limit)!;
|
|
409
|
+
if (unit === "day") {
|
|
410
|
+
// By the calendar, not in 24-hour units (refactor audit 2026-10-30, DSP-7): rounded
|
|
411
|
+
// elapsed time made 00:10 seen at 23:50 "yesterday" and 01:00 yesterday seen at 23:30
|
|
412
|
+
// "2 days ago", beside an exact date (DateMark's second line, the feedback thread's
|
|
413
|
+
// tooltip) that said otherwise. Counted in `timeZone`, the zone that date is printed
|
|
414
|
+
// in; a bare "YYYY-MM-DD" is the day it names wherever it is read, as in formatDate.
|
|
415
|
+
// Still the same day (22 hours and more since just after midnight): in hours.
|
|
416
|
+
const bareDay = isBareIsoDay(value);
|
|
417
|
+
const days = dayNumber(d, bareDay ? undefined : options.timeZone) - dayNumber(now, options.timeZone);
|
|
418
|
+
return days === 0 ? rtf.format(Math.round(diff / HOUR), "hour") : rtf.format(days, "day");
|
|
419
|
+
}
|
|
405
420
|
// Under 45 seconds is "now" rather than "12 seconds ago": a feed that ticks through
|
|
406
421
|
// the seconds is noise, and nothing reads a timestamp to the second.
|
|
407
422
|
const count = unit === "second" ? 0 : Math.round(diff / size);
|
|
@@ -0,0 +1,38 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* The HTTP status of a thrown error, as one probe (DUP-11, refactor audit 2026-10: the
|
|
3
|
+
* session refresh carried its own copy).
|
|
4
|
+
*
|
|
5
|
+
* It lived in `auth/auth-errors.ts` until 0.52, which made `lib/session-refresh` and
|
|
6
|
+
* `/sync`'s engine import the auth folder — and put auth's English error words in the
|
|
7
|
+
* `/sync` entry's closure — for a three-line reader of `status` (refactor audit
|
|
8
|
+
* 2026-10-30, MOD-6). `auth-errors.ts` re-exports it, so nothing that imported it there
|
|
9
|
+
* moved.
|
|
10
|
+
*
|
|
11
|
+
* @internal Package-private — not re-exported from the barrel.
|
|
12
|
+
*/
|
|
13
|
+
|
|
14
|
+
type Bag = Record<string, unknown>;
|
|
15
|
+
|
|
16
|
+
const isBag = (value: unknown): value is Bag => typeof value === "object" && value !== null;
|
|
17
|
+
|
|
18
|
+
/** An HTTP status as a number, or undefined. */
|
|
19
|
+
function statusOf(value: unknown): number | undefined {
|
|
20
|
+
return typeof value === "number" && Number.isInteger(value) ? value : undefined;
|
|
21
|
+
}
|
|
22
|
+
|
|
23
|
+
/**
|
|
24
|
+
* The HTTP status a thrown error carries, wherever the apps' HTTP clients put it —
|
|
25
|
+
* without depending on any of them:
|
|
26
|
+
*
|
|
27
|
+
* 1. `err.response.status` — axios (all three apps' clients);
|
|
28
|
+
* 2. `err.status` — ofetch's `FetchError`, the generated OpenAPI clients' `ApiError`, and
|
|
29
|
+
* a `Response` thrown as it came;
|
|
30
|
+
* 3. `err.statusCode` — ofetch's alias, and Node-style errors.
|
|
31
|
+
*
|
|
32
|
+
* `undefined` when none is a whole number.
|
|
33
|
+
*/
|
|
34
|
+
export function httpStatusOf(err: unknown): number | undefined {
|
|
35
|
+
if (!isBag(err)) return undefined;
|
|
36
|
+
const response = err.response;
|
|
37
|
+
return (isBag(response) ? statusOf(response.status) : undefined) ?? statusOf(err.status) ?? statusOf(err.statusCode);
|
|
38
|
+
}
|
|
@@ -0,0 +1,25 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* One `Intl.DateTimeFormat` per locale and option set, for every date the kit prints.
|
|
3
|
+
*
|
|
4
|
+
* Constructing the formatter is the expensive part: keksdose measured 392 ms per click on
|
|
5
|
+
* a 270-row register when each cell built its own (dev#632), and kept its own renderer of
|
|
6
|
+
* the date-format preference because the kit's built one per call (refactor audit
|
|
7
|
+
* 2026-10-30, DUP-2). `lib/format` and `lib/date-format` both format through this one.
|
|
8
|
+
*
|
|
9
|
+
* @internal Not part of the barrel — `lib/format` is re-exported whole, so the cache
|
|
10
|
+
* lives apart from it.
|
|
11
|
+
*/
|
|
12
|
+
|
|
13
|
+
const dateFormatters = new Map<string, Intl.DateTimeFormat>();
|
|
14
|
+
|
|
15
|
+
/** The cached formatter for `locale` and `options`. Throws as `Intl.DateTimeFormat` does
|
|
16
|
+
* for a tag it refuses — and caches nothing then. */
|
|
17
|
+
export function dateFormatter(locale: string | undefined, options: Intl.DateTimeFormatOptions): Intl.DateTimeFormat {
|
|
18
|
+
const key = `${locale ?? ""}|${JSON.stringify(options)}`;
|
|
19
|
+
let f = dateFormatters.get(key);
|
|
20
|
+
if (!f) {
|
|
21
|
+
f = new Intl.DateTimeFormat(locale, options);
|
|
22
|
+
dateFormatters.set(key, f);
|
|
23
|
+
}
|
|
24
|
+
return f;
|
|
25
|
+
}
|
package/src/lib/isin.ts
CHANGED
|
@@ -9,6 +9,10 @@
|
|
|
9
9
|
* with every letter expanded to two digits (A = 10 … Z = 35) — which is all that is
|
|
10
10
|
* checked here. Whether the prefix is an assigned code, and whether the security
|
|
11
11
|
* exists, is a lookup, not a checksum.
|
|
12
|
+
*
|
|
13
|
+
* Deprecated in 0.52, removed in 0.53 (decision 4 of the refactor audit 2026-10-30,
|
|
14
|
+
* MOD-5): keksdose, which they were written for, never imported them, and no other app
|
|
15
|
+
* does.
|
|
12
16
|
*/
|
|
13
17
|
|
|
14
18
|
/** Letters to their two-digit numbers (A = 10 … Z = 35), digits as they are. */
|
|
@@ -36,6 +40,8 @@ function luhnSum(digits: string, doubleRightmost: boolean): number {
|
|
|
36
40
|
/**
|
|
37
41
|
* The ISIN as it is printed: upper case, unbroken (ISO 6166 has no grouping), with
|
|
38
42
|
* the spaces and hyphens a paste from a broker's statement carries dropped.
|
|
43
|
+
*
|
|
44
|
+
* @deprecated 0.52 — none: no app checks an ISIN with it; copy lib/isin.ts (MOD-5); removed in 0.53.
|
|
39
45
|
*/
|
|
40
46
|
export function formatIsin(value: string): string {
|
|
41
47
|
return value.replace(/[\s-]/g, "").toUpperCase();
|
|
@@ -44,6 +50,8 @@ export function formatIsin(value: string): string {
|
|
|
44
50
|
/**
|
|
45
51
|
* The check digit for the first eleven characters of an ISIN (prefix and national
|
|
46
52
|
* number). For BUILDING one — a test fixture, a demo — rather than checking it.
|
|
53
|
+
*
|
|
54
|
+
* @deprecated 0.52 — none: no app checks an ISIN with it; copy lib/isin.ts (MOD-5); removed in 0.53.
|
|
47
55
|
*/
|
|
48
56
|
export function isinCheckDigit(body: string): string {
|
|
49
57
|
const sum = luhnSum(expandLetters(formatIsin(body)), true);
|
|
@@ -54,6 +62,8 @@ export function isinCheckDigit(body: string): string {
|
|
|
54
62
|
* Whether `value` is a valid ISIN: two letters, nine letters or digits, one digit,
|
|
55
63
|
* and a matching Luhn check digit over the letter-expanded form. Spaces, hyphens and
|
|
56
64
|
* lower case are fine (see {@link formatIsin}).
|
|
65
|
+
*
|
|
66
|
+
* @deprecated 0.52 — none: no app checks an ISIN with it; copy lib/isin.ts (MOD-5); removed in 0.53.
|
|
57
67
|
*/
|
|
58
68
|
export function isValidIsin(value: string): boolean {
|
|
59
69
|
const isin = formatIsin(value);
|
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* The bare ISO calendar day, `"YYYY-MM-DD"` — no time, no zone: the day it names in every
|
|
3
|
+
* zone. `toDate` and `formatDate` (lib/format), the kit's day ladder (`useDayFormatter`,
|
|
4
|
+
* lib/day-format) and the preference's renderers (lib/date-format) each kept a copy of this
|
|
5
|
+
* pattern (0.52 code review, lib/day-format.ts). Were one to learn a new shape (say
|
|
6
|
+
* `YYYY-MM-DDT00:00`) alone, the ladder would ask the provider for a different day than the
|
|
7
|
+
* kit prints. One rule.
|
|
8
|
+
*
|
|
9
|
+
* @internal Not part of the barrel: `lib/format` is re-exported whole, so it lives apart.
|
|
10
|
+
*/
|
|
11
|
+
export function isBareIsoDay(value: unknown): value is string {
|
|
12
|
+
return typeof value === "string" && /^\d{4}-\d{2}-\d{2}$/.test(value);
|
|
13
|
+
}
|
|
@@ -0,0 +1,82 @@
|
|
|
1
|
+
import { createContext, createElement, lazy, useCallback, useContext, useLayoutEffect, useState } from "react";
|
|
2
|
+
import type { ComponentType, LazyExoticComponent } from "react";
|
|
3
|
+
|
|
4
|
+
/** What a {@link lazyWithFallback} fallback is given besides the component's own props. */
|
|
5
|
+
export interface LazyFallbackProps {
|
|
6
|
+
/** What the import rejected with. Already on `console.error`. */
|
|
7
|
+
error: unknown;
|
|
8
|
+
/** Fetch the module again and draw it here if it comes (back online, the deploy's
|
|
9
|
+
* new chunk). Call it on the person's next attempt, never at once: offline, a retry
|
|
10
|
+
* on mount would fetch in a loop. */
|
|
11
|
+
retry: () => void;
|
|
12
|
+
}
|
|
13
|
+
|
|
14
|
+
interface Attempt<P> {
|
|
15
|
+
Component: LazyExoticComponent<ComponentType<P>>;
|
|
16
|
+
/** Its import failed and its fallback was drawn: the next mount, or `retry`, takes a
|
|
17
|
+
* fresh attempt. Marked when the fallback COMMITS, not when the import rejects: a
|
|
18
|
+
* first mount that suspended is thrown away and rendered anew, and an attempt marked
|
|
19
|
+
* at the rejection would hand that re-render a fresh import — which fails, and so on. */
|
|
20
|
+
spent: boolean;
|
|
21
|
+
}
|
|
22
|
+
|
|
23
|
+
const RetryContext = createContext<() => void>(() => {});
|
|
24
|
+
|
|
25
|
+
/**
|
|
26
|
+
* `React.lazy` for a module the kit loads late (refactor audit 2026-10, MOD-1: the tour
|
|
27
|
+
* overlay, the search palette, the feedback dialog), where an import that fails — a tab
|
|
28
|
+
* left open across a deploy, a local-first app offline — draws `Fallback` instead of
|
|
29
|
+
* throwing.
|
|
30
|
+
*
|
|
31
|
+
* `React.lazy` keeps what its import settled to, so one failed fetch threw on every render
|
|
32
|
+
* for as long as the component stayed mounted, to the nearest error boundary. All three
|
|
33
|
+
* sit above the routes — in the provider every app mounts, in the top bar — where that
|
|
34
|
+
* boundary is the whole app's: a white page because somebody pressed ⌘K or "Take the
|
|
35
|
+
* tour" (0.52 code review, tour.tsx: the tour's own fix, written by hand with a module-level
|
|
36
|
+
* `let`, made shared here).
|
|
37
|
+
*
|
|
38
|
+
* A failure is logged and the next mount (or the fallback's `retry`) fetches again; a
|
|
39
|
+
* re-render of a mounted fallback does not. `load` resolves to the component itself,
|
|
40
|
+
* through a LITERAL relative dynamic import of its module (as feedback-submit's), so an
|
|
41
|
+
* app's bundler can split it off. Render the result under a `Suspense`, as a lazy
|
|
42
|
+
* component. (No import call is spelled out here: the build's fix-esm-extensions step
|
|
43
|
+
* reads specifiers in the .d.ts comments too, and would try to resolve an example.)
|
|
44
|
+
*/
|
|
45
|
+
export function lazyWithFallback<P extends object>(
|
|
46
|
+
load: () => Promise<ComponentType<P>>,
|
|
47
|
+
Fallback: ComponentType<P & LazyFallbackProps>,
|
|
48
|
+
): ComponentType<P> {
|
|
49
|
+
const attempt = (): Attempt<P> => {
|
|
50
|
+
const made: Attempt<P> = {
|
|
51
|
+
spent: false,
|
|
52
|
+
Component: lazy<ComponentType<P>>(() =>
|
|
53
|
+
load().then(
|
|
54
|
+
(Loaded) => ({ default: Loaded }),
|
|
55
|
+
(error: unknown) => {
|
|
56
|
+
console.error(error);
|
|
57
|
+
function Failed(props: P) {
|
|
58
|
+
const retry = useContext(RetryContext);
|
|
59
|
+
useLayoutEffect(() => {
|
|
60
|
+
made.spent = true;
|
|
61
|
+
}, []);
|
|
62
|
+
return createElement(Fallback, { ...props, error, retry });
|
|
63
|
+
}
|
|
64
|
+
return { default: Failed };
|
|
65
|
+
},
|
|
66
|
+
),
|
|
67
|
+
),
|
|
68
|
+
};
|
|
69
|
+
return made;
|
|
70
|
+
};
|
|
71
|
+
let latest = attempt();
|
|
72
|
+
/** The attempt a new mount takes: the latest, or a fresh one once that has failed. */
|
|
73
|
+
const take = () => (latest.spent ? (latest = attempt()) : latest);
|
|
74
|
+
|
|
75
|
+
function LazyWithFallback(props: P) {
|
|
76
|
+
// Fixed per mount, so a re-render of a mounted fallback fetches nothing.
|
|
77
|
+
const [current, setCurrent] = useState(take);
|
|
78
|
+
const retry = useCallback(() => setCurrent(take), []);
|
|
79
|
+
return createElement(RetryContext.Provider, { value: retry }, createElement(current.Component, props));
|
|
80
|
+
}
|
|
81
|
+
return LazyWithFallback;
|
|
82
|
+
}
|