@eifi1/ui-kit 0.33.0 → 0.34.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 +445 -283
- package/dist/account/account-parts.d.ts +6 -8
- package/dist/account/account-parts.js +1 -2
- package/dist/account/account-parts.js.map +1 -1
- package/dist/{components → account}/account-settings-labels.d.ts +16 -10
- package/dist/{components → account}/account-settings-labels.js +3 -1
- package/dist/account/account-settings-labels.js.map +1 -0
- package/dist/{components → account}/account-settings.d.ts +53 -23
- package/dist/{components → account}/account-settings.js +97 -26
- package/dist/account/account-settings.js.map +1 -0
- package/dist/account/data-export-setting-labels.d.ts +2 -0
- package/dist/account/data-export-setting-labels.js +15 -0
- package/dist/account/data-export-setting-labels.js.map +1 -0
- package/dist/account/data-export-setting.d.ts +9 -11
- package/dist/account/data-export-setting.js +11 -27
- package/dist/account/data-export-setting.js.map +1 -1
- package/dist/account/delete-account-setting-labels.d.ts +2 -0
- package/dist/account/delete-account-setting-labels.js +23 -0
- package/dist/account/delete-account-setting-labels.js.map +1 -0
- package/dist/account/delete-account-setting.d.ts +132 -100
- package/dist/account/delete-account-setting.js +7 -23
- package/dist/account/delete-account-setting.js.map +1 -1
- package/dist/account/email-change-setting-labels.d.ts +2 -0
- package/dist/account/email-change-setting-labels.js +28 -0
- package/dist/account/email-change-setting-labels.js.map +1 -0
- package/dist/account/email-change-setting.d.ts +10 -12
- package/dist/account/email-change-setting.js +11 -30
- package/dist/account/email-change-setting.js.map +1 -1
- package/dist/{components → account}/passkeys-setting.d.ts +9 -12
- package/dist/{components → account}/passkeys-setting.js +10 -7
- package/dist/account/passkeys-setting.js.map +1 -0
- package/dist/account/sessions-setting-labels.d.ts +2 -0
- package/dist/account/sessions-setting-labels.js +22 -0
- package/dist/account/sessions-setting-labels.js.map +1 -0
- package/dist/account/sessions-setting.d.ts +12 -14
- package/dist/account/sessions-setting.js +8 -23
- package/dist/account/sessions-setting.js.map +1 -1
- package/dist/admin/admin-action-confirm-labels.d.ts +2 -0
- package/dist/admin/admin-action-confirm-labels.js +16 -0
- package/dist/admin/admin-action-confirm-labels.js.map +1 -0
- package/dist/admin/admin-action-confirm.d.ts +156 -100
- package/dist/admin/admin-action-confirm.js +17 -22
- package/dist/admin/admin-action-confirm.js.map +1 -1
- package/dist/admin/admin-action-log-labels.d.ts +2 -0
- package/dist/admin/admin-action-log-labels.js +73 -0
- package/dist/admin/admin-action-log-labels.js.map +1 -0
- package/dist/admin/admin-action-log.d.ts +98 -22
- package/dist/admin/admin-action-log.js +48 -45
- package/dist/admin/admin-action-log.js.map +1 -1
- package/dist/admin/admin-parts.d.ts +7 -14
- package/dist/admin/admin-parts.js +0 -4
- package/dist/admin/admin-parts.js.map +1 -1
- package/dist/admin/invitations-panel-labels.d.ts +2 -0
- package/dist/admin/invitations-panel-labels.js +29 -0
- package/dist/admin/invitations-panel-labels.js.map +1 -0
- package/dist/admin/invitations-panel.d.ts +167 -100
- package/dist/admin/invitations-panel.js +12 -31
- package/dist/admin/invitations-panel.js.map +1 -1
- package/dist/admin/plan-change-labels.d.ts +2 -0
- package/dist/admin/plan-change-labels.js +22 -0
- package/dist/admin/plan-change-labels.js.map +1 -0
- package/dist/admin/plan-change.d.ts +244 -100
- package/dist/admin/plan-change.js +17 -23
- package/dist/admin/plan-change.js.map +1 -1
- package/dist/admin/reviewer-scope-editor-labels.d.ts +2 -0
- package/dist/admin/reviewer-scope-editor-labels.js +14 -0
- package/dist/admin/reviewer-scope-editor-labels.js.map +1 -0
- package/dist/admin/reviewer-scope-editor.d.ts +95 -100
- package/dist/admin/reviewer-scope-editor.js +5 -13
- package/dist/admin/reviewer-scope-editor.js.map +1 -1
- package/dist/admin/role-select-labels.d.ts +2 -0
- package/dist/admin/role-select-labels.js +15 -0
- package/dist/admin/role-select-labels.js.map +1 -0
- package/dist/admin/role-select.d.ts +136 -100
- package/dist/admin/role-select.js +7 -18
- package/dist/admin/role-select.js.map +1 -1
- package/dist/admin/transfer-ownership-dialog-labels.d.ts +2 -0
- package/dist/admin/transfer-ownership-dialog-labels.js +18 -0
- package/dist/admin/transfer-ownership-dialog-labels.js.map +1 -0
- package/dist/admin/transfer-ownership-dialog.d.ts +81 -100
- package/dist/admin/transfer-ownership-dialog.js +3 -15
- package/dist/admin/transfer-ownership-dialog.js.map +1 -1
- package/dist/admin/user-roster-labels.d.ts +2 -0
- package/dist/admin/user-roster-labels.js +16 -0
- package/dist/admin/user-roster-labels.js.map +1 -0
- package/dist/admin/user-roster.d.ts +225 -100
- package/dist/admin/user-roster.js +4 -14
- package/dist/admin/user-roster.js.map +1 -1
- package/dist/auth/accept-invitation-labels.d.ts +2 -0
- package/dist/auth/accept-invitation-labels.js +20 -0
- package/dist/auth/accept-invitation-labels.js.map +1 -0
- package/dist/auth/accept-invitation.d.ts +11 -13
- package/dist/auth/accept-invitation.js +3 -16
- package/dist/auth/accept-invitation.js.map +1 -1
- package/dist/auth/auth-errors.d.ts +34 -23
- package/dist/auth/auth-errors.js +8 -4
- package/dist/auth/auth-errors.js.map +1 -1
- package/dist/auth/complete-name-dialog-labels.d.ts +2 -0
- package/dist/auth/complete-name-dialog-labels.js +14 -0
- package/dist/auth/complete-name-dialog-labels.js.map +1 -0
- package/dist/auth/complete-name-dialog.d.ts +9 -11
- package/dist/auth/complete-name-dialog.js +4 -11
- package/dist/auth/complete-name-dialog.js.map +1 -1
- package/dist/auth/email-tag.d.ts +2 -4
- package/dist/auth/forgot-password-form-labels.d.ts +3 -0
- package/dist/auth/forgot-password-form-labels.js +17 -0
- package/dist/auth/forgot-password-form-labels.js.map +1 -0
- package/dist/auth/forgot-password-form.d.ts +9 -12
- package/dist/auth/forgot-password-form.js +6 -15
- package/dist/auth/forgot-password-form.js.map +1 -1
- package/dist/auth/form-rules.d.ts +5 -7
- package/dist/auth/new-password-fields.d.ts +4 -8
- package/dist/auth/new-password-fields.js +1 -1
- package/dist/auth/new-password-fields.js.map +1 -1
- package/dist/auth/not-found-page-labels.d.ts +2 -0
- package/dist/auth/not-found-page-labels.js +11 -0
- package/dist/auth/not-found-page-labels.js.map +1 -0
- package/dist/auth/not-found-page.d.ts +9 -11
- package/dist/auth/not-found-page.js +5 -10
- package/dist/auth/not-found-page.js.map +1 -1
- package/dist/auth/register-form-labels.d.ts +3 -0
- package/dist/auth/register-form-labels.js +28 -0
- package/dist/auth/register-form-labels.js.map +1 -0
- package/dist/auth/register-form.d.ts +174 -100
- package/dist/auth/register-form.js +11 -31
- package/dist/auth/register-form.js.map +1 -1
- package/dist/auth/reset-password-form-labels.d.ts +3 -0
- package/dist/auth/reset-password-form-labels.js +24 -0
- package/dist/auth/reset-password-form-labels.js.map +1 -0
- package/dist/auth/reset-password-form.d.ts +12 -15
- package/dist/auth/reset-password-form.js +6 -22
- package/dist/auth/reset-password-form.js.map +1 -1
- package/dist/auth/sign-in-form-labels.d.ts +3 -0
- package/dist/auth/sign-in-form-labels.js +42 -0
- package/dist/auth/sign-in-form-labels.js.map +1 -0
- package/dist/auth/sign-in-form.d.ts +15 -19
- package/dist/auth/sign-in-form.js +12 -46
- package/dist/auth/sign-in-form.js.map +1 -1
- package/dist/auth/status-parts.d.ts +13 -17
- package/dist/auth/status-parts.js +3 -3
- package/dist/auth/status-parts.js.map +1 -1
- package/dist/auth/verify-email-labels.d.ts +2 -0
- package/dist/auth/verify-email-labels.js +25 -0
- package/dist/auth/verify-email-labels.js.map +1 -0
- package/dist/auth/verify-email.d.ts +15 -17
- package/dist/auth/verify-email.js +4 -21
- package/dist/auth/verify-email.js.map +1 -1
- package/dist/billing/billing-banner.d.ts +8 -108
- package/dist/billing/billing-banner.js +2 -1
- package/dist/billing/billing-banner.js.map +1 -1
- package/dist/billing/billing-labels.d.ts +168 -100
- package/dist/billing/billing-labels.js.map +1 -1
- package/dist/billing/billing-lock.d.ts +10 -109
- package/dist/billing/billing-overview.d.ts +7 -108
- package/dist/billing/billing-standing.d.ts +6 -107
- package/dist/billing/checkout-processing.d.ts +8 -110
- package/dist/billing/checkout-processing.js +2 -9
- package/dist/billing/checkout-processing.js.map +1 -1
- package/dist/billing/checkout-return.d.ts +5 -7
- package/dist/billing/pay-page.d.ts +22 -119
- package/dist/billing/pay-page.js.map +1 -1
- package/dist/billing/plan-card.d.ts +14 -114
- package/dist/billing/plan-card.js +15 -13
- package/dist/billing/plan-card.js.map +1 -1
- package/dist/billing/plan-limit-notice.d.ts +8 -108
- package/dist/billing/plan-limit-notice.js +1 -1
- package/dist/billing/plan-limit-notice.js.map +1 -1
- package/dist/billing/plan-limit-toast.d.ts +6 -106
- package/dist/billing/plan-limit.d.ts +2 -4
- package/dist/billing/plan-price.d.ts +10 -12
- package/dist/billing/subscription-actions.d.ts +6 -108
- package/dist/billing/subscription-actions.js +2 -2
- package/dist/billing/subscription-actions.js.map +1 -1
- package/dist/billing/subscription-status-chip.d.ts +7 -107
- package/dist/chart.d.ts +12 -112
- package/dist/chart.js +4 -0
- package/dist/chart.js.map +1 -1
- package/dist/components/account-chips-labels.d.ts +10 -0
- package/dist/components/account-chips-labels.js +15 -0
- package/dist/components/account-chips-labels.js.map +1 -0
- package/dist/components/account-chips.d.ts +22 -44
- package/dist/components/account-chips.js +9 -14
- package/dist/components/account-chips.js.map +1 -1
- package/dist/components/alert-banner.d.ts +15 -11
- package/dist/components/alert-banner.js +28 -18
- package/dist/components/alert-banner.js.map +1 -1
- package/dist/components/amount-input.d.ts +66 -109
- package/dist/components/amount-input.js +259 -283
- package/dist/components/amount-input.js.map +1 -1
- package/dist/components/appearance-labels.d.ts +6 -10
- package/dist/components/appearance-labels.js.map +1 -1
- package/dist/components/authed-image-labels.d.ts +2 -0
- package/dist/components/authed-image-labels.js +10 -0
- package/dist/components/authed-image-labels.js.map +1 -0
- package/dist/components/authed-image.d.ts +11 -13
- package/dist/components/authed-image.js +2 -6
- package/dist/components/authed-image.js.map +1 -1
- package/dist/components/autocomplete.d.ts +13 -11
- package/dist/components/autocomplete.js +35 -30
- package/dist/components/autocomplete.js.map +1 -1
- package/dist/components/breadcrumbs-labels.d.ts +2 -0
- package/dist/components/breadcrumbs-labels.js +9 -0
- package/dist/components/breadcrumbs-labels.js.map +1 -0
- package/dist/components/breadcrumbs.d.ts +10 -12
- package/dist/components/breadcrumbs.js +7 -10
- package/dist/components/breadcrumbs.js.map +1 -1
- package/dist/components/bulk-action-bar-labels.d.ts +2 -0
- package/dist/components/bulk-action-bar-labels.js +10 -0
- package/dist/components/bulk-action-bar-labels.js.map +1 -0
- package/dist/components/bulk-action-bar.d.ts +10 -12
- package/dist/components/bulk-action-bar.js +9 -12
- package/dist/components/bulk-action-bar.js.map +1 -1
- package/dist/components/button-group.d.ts +7 -109
- package/dist/components/button-group.js +5 -5
- package/dist/components/button-group.js.map +1 -1
- package/dist/components/button-look.d.ts +88 -0
- package/dist/components/button-look.js +91 -0
- package/dist/components/button-look.js.map +1 -0
- package/dist/components/button.d.ts +153 -0
- package/dist/components/button.js +165 -0
- package/dist/components/button.js.map +1 -0
- package/dist/components/calculator.d.ts +8 -106
- package/dist/components/calculator.js +10 -7
- package/dist/components/calculator.js.map +1 -1
- package/dist/components/calendar-heatmap-labels.d.ts +3 -0
- package/dist/components/calendar-heatmap-labels.js +12 -0
- package/dist/components/calendar-heatmap-labels.js.map +1 -0
- package/dist/components/calendar-heatmap.d.ts +13 -16
- package/dist/components/calendar-heatmap.js +7 -13
- package/dist/components/calendar-heatmap.js.map +1 -1
- package/dist/components/card.d.ts +145 -0
- package/dist/components/card.js +186 -0
- package/dist/components/card.js.map +1 -0
- package/dist/components/chart-height.d.ts +4 -7
- package/dist/components/chart-zoom-core.d.ts +202 -0
- package/dist/components/chart-zoom-core.js +334 -0
- package/dist/components/chart-zoom-core.js.map +1 -0
- package/dist/components/chart-zoom.d.ts +39 -205
- package/dist/components/chart-zoom.js +15 -316
- package/dist/components/chart-zoom.js.map +1 -1
- package/dist/components/chart.d.ts +11 -15
- package/dist/components/chart.js +11 -11
- package/dist/components/chart.js.map +1 -1
- package/dist/components/checkbox-group.d.ts +6 -10
- package/dist/components/checkbox-group.js +10 -9
- package/dist/components/checkbox-group.js.map +1 -1
- package/dist/components/checkbox.d.ts +8 -12
- package/dist/components/checkbox.js +20 -18
- package/dist/components/checkbox.js.map +1 -1
- package/dist/components/chip-input.d.ts +73 -0
- package/dist/components/chip-input.js +224 -0
- package/dist/components/chip-input.js.map +1 -0
- package/dist/components/chip-labels.d.ts +2 -0
- package/dist/components/chip-labels.js +12 -0
- package/dist/components/chip-labels.js.map +1 -0
- package/dist/components/chip.d.ts +18 -93
- package/dist/components/chip.js +74 -426
- package/dist/components/chip.js.map +1 -1
- package/dist/components/choice-card.d.ts +21 -18
- package/dist/components/choice-card.js +45 -45
- package/dist/components/choice-card.js.map +1 -1
- package/dist/components/column-mapper-labels.d.ts +5 -0
- package/dist/components/column-mapper-labels.js +34 -0
- package/dist/components/column-mapper-labels.js.map +1 -0
- package/dist/components/column-mapper.d.ts +15 -17
- package/dist/components/column-mapper.js +11 -37
- package/dist/components/column-mapper.js.map +1 -1
- package/dist/components/combobox-core.d.ts +79 -40
- package/dist/components/combobox-core.js +189 -122
- package/dist/components/combobox-core.js.map +1 -1
- package/dist/components/combobox-suggestions.d.ts +76 -0
- package/dist/components/combobox-suggestions.js +56 -0
- package/dist/components/combobox-suggestions.js.map +1 -0
- package/dist/components/combobox.d.ts +14 -159
- package/dist/components/combobox.js +40 -507
- package/dist/components/combobox.js.map +1 -1
- package/dist/components/confirm-dialog-labels.d.ts +7 -0
- package/dist/components/confirm-dialog-labels.js +10 -0
- package/dist/components/confirm-dialog-labels.js.map +1 -0
- package/dist/components/confirm-dialog.d.ts +165 -100
- package/dist/components/confirm-dialog.js +2 -6
- package/dist/components/confirm-dialog.js.map +1 -1
- package/dist/components/copy-button-labels.d.ts +2 -0
- package/dist/components/copy-button-labels.js +12 -0
- package/dist/components/copy-button-labels.js.map +1 -0
- package/dist/components/copy-button.d.ts +70 -100
- package/dist/components/copy-button.js +4 -9
- package/dist/components/copy-button.js.map +1 -1
- package/dist/components/country-select-labels.d.ts +2 -0
- package/dist/components/country-select-labels.js +10 -0
- package/dist/components/country-select-labels.js.map +1 -0
- package/dist/components/country-select.d.ts +18 -15
- package/dist/components/country-select.js +49 -64
- package/dist/components/country-select.js.map +1 -1
- package/dist/components/currency-option-list.d.ts +63 -0
- package/dist/components/currency-option-list.js +135 -0
- package/dist/components/currency-option-list.js.map +1 -0
- package/dist/components/currency-select.d.ts +10 -30
- package/dist/components/currency-select.js +50 -133
- package/dist/components/currency-select.js.map +1 -1
- package/dist/components/danger-confirm-labels.d.ts +14 -0
- package/dist/components/danger-confirm-labels.js +17 -0
- package/dist/components/danger-confirm-labels.js.map +1 -0
- package/dist/components/danger-confirm.d.ts +448 -100
- package/dist/components/danger-confirm.js +40 -46
- package/dist/components/danger-confirm.js.map +1 -1
- package/dist/components/data-table-cells.d.ts +9 -24
- package/dist/components/data-table-cells.js +1 -1
- package/dist/components/data-table-cells.js.map +1 -1
- package/dist/components/data-table-column-settings.d.ts +16 -0
- package/dist/components/data-table-column-settings.js +119 -0
- package/dist/components/data-table-column-settings.js.map +1 -0
- package/dist/components/data-table-filter-popover.d.ts +5 -19
- package/dist/components/data-table-filter-popover.js +39 -22
- package/dist/components/data-table-filter-popover.js.map +1 -1
- package/dist/components/data-table-filters.d.ts +93 -15
- package/dist/components/data-table-filters.js +22 -7
- package/dist/components/data-table-filters.js.map +1 -1
- package/dist/components/data-table-head.d.ts +36 -0
- package/dist/components/data-table-head.js +190 -0
- package/dist/components/data-table-head.js.map +1 -0
- package/dist/components/data-table-labels.d.ts +124 -15
- package/dist/components/data-table-labels.js +9 -5
- package/dist/components/data-table-labels.js.map +1 -1
- package/dist/components/data-table-mobile.d.ts +106 -0
- package/dist/components/data-table-mobile.js +412 -0
- package/dist/components/data-table-mobile.js.map +1 -0
- package/dist/components/data-table-pagination.d.ts +6 -21
- package/dist/components/data-table-pagination.js +7 -7
- package/dist/components/data-table-pagination.js.map +1 -1
- package/dist/components/data-table-resize.d.ts +37 -0
- package/dist/components/data-table-resize.js +103 -0
- package/dist/components/data-table-resize.js.map +1 -0
- package/dist/components/data-table-row-actions.d.ts +24 -0
- package/dist/components/data-table-row-actions.js +95 -0
- package/dist/components/data-table-row-actions.js.map +1 -0
- package/dist/components/data-table-selection.d.ts +21 -0
- package/dist/components/data-table-selection.js +30 -0
- package/dist/components/data-table-selection.js.map +1 -0
- package/dist/components/data-table-shared.d.ts +77 -0
- package/dist/components/data-table-shared.js +77 -0
- package/dist/components/data-table-shared.js.map +1 -0
- package/dist/components/data-table-sort.d.ts +8 -10
- package/dist/components/data-table.d.ts +603 -15
- package/dist/components/data-table.js +134 -927
- package/dist/components/data-table.js.map +1 -1
- package/dist/components/date-field.d.ts +203 -0
- package/dist/components/date-field.js +270 -0
- package/dist/components/date-field.js.map +1 -0
- package/dist/components/date-picker.d.ts +6 -261
- package/dist/components/date-picker.js +24 -760
- package/dist/components/date-picker.js.map +1 -1
- package/dist/components/date-range-picker.d.ts +125 -0
- package/dist/components/date-range-picker.js +261 -0
- package/dist/components/date-range-picker.js.map +1 -0
- package/dist/components/description-list-labels.d.ts +2 -0
- package/dist/components/description-list-labels.js +8 -0
- package/dist/components/description-list-labels.js.map +1 -0
- package/dist/components/description-list.d.ts +13 -15
- package/dist/components/description-list.js +17 -11
- package/dist/components/description-list.js.map +1 -1
- package/dist/components/dialog-frame-labels.d.ts +2 -0
- package/dist/components/dialog-frame-labels.js +6 -0
- package/dist/components/dialog-frame-labels.js.map +1 -0
- package/dist/components/dialog-frame.d.ts +7 -11
- package/dist/components/dialog-frame.js +6 -6
- package/dist/components/dialog-frame.js.map +1 -1
- package/dist/components/disclosure.d.ts +6 -10
- package/dist/components/disclosure.js +11 -11
- package/dist/components/disclosure.js.map +1 -1
- package/dist/components/dropdown.d.ts +55 -27
- package/dist/components/dropdown.js +62 -31
- package/dist/components/dropdown.js.map +1 -1
- package/dist/components/empty-state.d.ts +64 -0
- package/dist/components/empty-state.js +70 -0
- package/dist/components/empty-state.js.map +1 -0
- package/dist/components/entity-combobox.d.ts +10 -11
- package/dist/components/entity-combobox.js +14 -13
- package/dist/components/entity-combobox.js.map +1 -1
- package/dist/components/error-boundary-labels.d.ts +2 -0
- package/dist/components/error-boundary-labels.js +19 -0
- package/dist/components/error-boundary-labels.js.map +1 -0
- package/dist/components/error-boundary.d.ts +17 -17
- package/dist/components/error-boundary.js +5 -17
- package/dist/components/error-boundary.js.map +1 -1
- package/dist/components/facing-pair.d.ts +7 -115
- package/dist/components/facing-pair.js +1 -1
- package/dist/components/facing-pair.js.map +1 -1
- package/dist/components/field-base.d.ts +260 -0
- package/dist/components/field-base.js +228 -0
- package/dist/components/field-base.js.map +1 -0
- package/dist/components/field-parts.d.ts +188 -87
- package/dist/components/field-parts.js +60 -33
- package/dist/components/field-parts.js.map +1 -1
- package/dist/components/field-strip.d.ts +19 -28
- package/dist/components/field-strip.js +2 -2
- package/dist/components/field-strip.js.map +1 -1
- package/dist/components/field-sync-labels.d.ts +2 -0
- package/dist/components/field-sync-labels.js +12 -0
- package/dist/components/field-sync-labels.js.map +1 -0
- package/dist/components/field-sync.d.ts +20 -19
- package/dist/components/field-sync.js +4 -10
- package/dist/components/field-sync.js.map +1 -1
- package/dist/components/field.d.ts +45 -10
- package/dist/components/field.js +10 -8
- package/dist/components/field.js.map +1 -1
- package/dist/components/file-button.d.ts +85 -100
- package/dist/components/file-button.js +23 -169
- package/dist/components/file-button.js.map +1 -1
- package/dist/components/file-dropzone.d.ts +9 -109
- package/dist/components/file-dropzone.js +22 -22
- package/dist/components/file-dropzone.js.map +1 -1
- package/dist/components/floating-panel-labels.d.ts +2 -0
- package/dist/components/floating-panel-labels.js +9 -0
- package/dist/components/floating-panel-labels.js.map +1 -0
- package/dist/components/floating-panel.d.ts +17 -21
- package/dist/components/floating-panel.js +19 -18
- package/dist/components/floating-panel.js.map +1 -1
- package/dist/components/focus-ring.d.ts +9 -6
- package/dist/components/focus-ring.js +2 -2
- package/dist/components/focus-ring.js.map +1 -1
- package/dist/components/form-actions-labels.d.ts +2 -0
- package/dist/components/form-actions-labels.js +10 -0
- package/dist/components/form-actions-labels.js.map +1 -0
- package/dist/components/form-actions.d.ts +280 -100
- package/dist/components/form-actions.js +10 -20
- package/dist/components/form-actions.js.map +1 -1
- package/dist/components/full-bleed-dialog.d.ts +7 -8
- package/dist/components/full-bleed-dialog.js +14 -13
- package/dist/components/full-bleed-dialog.js.map +1 -1
- package/dist/components/grouped-picker.d.ts +21 -16
- package/dist/components/grouped-picker.js +76 -62
- package/dist/components/grouped-picker.js.map +1 -1
- package/dist/components/help-popover.d.ts +60 -0
- package/dist/components/help-popover.js +48 -0
- package/dist/components/help-popover.js.map +1 -0
- package/dist/components/hover-menu.d.ts +17 -16
- package/dist/components/hover-menu.js +18 -17
- package/dist/components/hover-menu.js.map +1 -1
- package/dist/components/iban-input-labels.d.ts +2 -0
- package/dist/components/iban-input-labels.js +13 -0
- package/dist/components/iban-input-labels.js.map +1 -0
- package/dist/components/iban-input.d.ts +73 -100
- package/dist/components/iban-input.js +22 -15
- package/dist/components/iban-input.js.map +1 -1
- package/dist/components/icon-button.d.ts +300 -0
- package/dist/components/icon-button.js +465 -0
- package/dist/components/icon-button.js.map +1 -0
- package/dist/components/icon-picker-labels.d.ts +2 -0
- package/dist/components/icon-picker-labels.js +12 -0
- package/dist/components/icon-picker-labels.js.map +1 -0
- package/dist/components/icon-picker.d.ts +13 -13
- package/dist/components/icon-picker.js +18 -17
- package/dist/components/icon-picker.js.map +1 -1
- package/dist/components/image-grid-labels.d.ts +2 -0
- package/dist/components/image-grid-labels.js +10 -0
- package/dist/components/image-grid-labels.js.map +1 -0
- package/dist/components/image-grid.d.ts +12 -14
- package/dist/components/image-grid.js +6 -10
- package/dist/components/image-grid.js.map +1 -1
- package/dist/components/inline-edit-field-labels.d.ts +2 -0
- package/dist/components/inline-edit-field-labels.js +10 -0
- package/dist/components/inline-edit-field-labels.js.map +1 -0
- package/dist/components/inline-edit-field.d.ts +11 -13
- package/dist/components/inline-edit-field.js +11 -13
- package/dist/components/inline-edit-field.js.map +1 -1
- package/dist/components/inline-entity-combobox.d.ts +155 -0
- package/dist/components/inline-entity-combobox.js +467 -0
- package/dist/components/inline-entity-combobox.js.map +1 -0
- package/dist/components/input.d.ts +98 -0
- package/dist/components/input.js +219 -0
- package/dist/components/input.js.map +1 -0
- package/dist/components/jump-calendar.d.ts +8 -0
- package/dist/components/jump-calendar.js +274 -0
- package/dist/components/jump-calendar.js.map +1 -0
- package/dist/components/language-select.d.ts +20 -110
- package/dist/components/language-select.js +12 -7
- package/dist/components/language-select.js.map +1 -1
- package/dist/components/legal-labels.d.ts +2 -0
- package/dist/components/legal-labels.js +100 -0
- package/dist/components/legal-labels.js.map +1 -0
- package/dist/components/legal-page.d.ts +17 -117
- package/dist/components/legal-page.js +2 -2
- package/dist/components/legal-page.js.map +1 -1
- package/dist/components/legal.d.ts +353 -100
- package/dist/components/legal.js +7 -101
- package/dist/components/legal.js.map +1 -1
- package/dist/components/lightbox-labels.d.ts +2 -0
- package/dist/components/lightbox-labels.js +17 -0
- package/dist/components/lightbox-labels.js.map +1 -0
- package/dist/components/lightbox.d.ts +12 -14
- package/dist/components/lightbox.js +9 -19
- package/dist/components/lightbox.js.map +1 -1
- package/dist/components/line-items-labels.d.ts +2 -0
- package/dist/components/line-items-labels.js +13 -0
- package/dist/components/line-items-labels.js.map +1 -0
- package/dist/components/line-items.d.ts +16 -18
- package/dist/components/line-items.js +18 -26
- package/dist/components/line-items.js.map +1 -1
- package/dist/components/list-labels.d.ts +2 -0
- package/dist/components/list-labels.js +9 -0
- package/dist/components/list-labels.js.map +1 -0
- package/dist/components/list.d.ts +32 -21
- package/dist/components/list.js +41 -25
- package/dist/components/list.js.map +1 -1
- package/dist/components/loading-state.d.ts +5 -9
- package/dist/components/loading-state.js +2 -2
- package/dist/components/loading-state.js.map +1 -1
- package/dist/components/measured-grid-labels.d.ts +4 -0
- package/dist/components/measured-grid-labels.js +21 -0
- package/dist/components/measured-grid-labels.js.map +1 -0
- package/dist/components/measured-grid.d.ts +13 -17
- package/dist/components/measured-grid.js +31 -50
- package/dist/components/measured-grid.js.map +1 -1
- package/dist/components/menu-item.d.ts +10 -10
- package/dist/components/menu-item.js +9 -9
- package/dist/components/menu-item.js.map +1 -1
- package/dist/components/mini-calendar-labels.d.ts +4 -0
- package/dist/components/mini-calendar-labels.js +14 -0
- package/dist/components/mini-calendar-labels.js.map +1 -0
- package/dist/components/mini-calendar.d.ts +10 -14
- package/dist/components/mini-calendar.js +22 -29
- package/dist/components/mini-calendar.js.map +1 -1
- package/dist/components/modal.d.ts +26 -18
- package/dist/components/modal.js +8 -11
- package/dist/components/modal.js.map +1 -1
- package/dist/components/money-draft.d.ts +34 -0
- package/dist/components/money-draft.js +39 -0
- package/dist/components/money-draft.js.map +1 -0
- package/dist/components/money-field.d.ts +13 -110
- package/dist/components/money-field.js +6 -22
- package/dist/components/money-field.js.map +1 -1
- package/dist/components/month-picker-labels.d.ts +5 -0
- package/dist/components/month-picker-labels.js +18 -0
- package/dist/components/month-picker-labels.js.map +1 -0
- package/dist/components/month-picker.d.ts +15 -13
- package/dist/components/month-picker.js +34 -32
- package/dist/components/month-picker.js.map +1 -1
- package/dist/components/multi-entity-combobox.d.ts +9 -11
- package/dist/components/multi-entity-combobox.js +14 -13
- package/dist/components/multi-entity-combobox.js.map +1 -1
- package/dist/components/multi-select.d.ts +81 -21
- package/dist/components/multi-select.js +171 -197
- package/dist/components/multi-select.js.map +1 -1
- package/dist/components/nav-pills.d.ts +9 -10
- package/dist/components/nav-pills.js +53 -42
- package/dist/components/nav-pills.js.map +1 -1
- package/dist/components/number-field.d.ts +13 -110
- package/dist/components/number-field.js +2 -3
- package/dist/components/number-field.js.map +1 -1
- package/dist/components/number-input.d.ts +55 -109
- package/dist/components/number-input.js +50 -67
- package/dist/components/number-input.js.map +1 -1
- package/dist/components/numeric-field.d.ts +85 -0
- package/dist/components/numeric-field.js +71 -0
- package/dist/components/numeric-field.js.map +1 -0
- package/dist/components/numpad-sheet.d.ts +5 -107
- package/dist/components/numpad-sheet.js +7 -7
- package/dist/components/numpad-sheet.js.map +1 -1
- package/dist/components/one-time-code-input.d.ts +6 -7
- package/dist/components/one-time-code-input.js +119 -124
- package/dist/components/one-time-code-input.js.map +1 -1
- package/dist/components/page-contents-labels.d.ts +2 -0
- package/dist/components/page-contents-labels.js +8 -0
- package/dist/components/page-contents-labels.js.map +1 -0
- package/dist/components/page-contents.d.ts +13 -15
- package/dist/components/page-contents.js +7 -9
- package/dist/components/page-contents.js.map +1 -1
- package/dist/components/page-header.d.ts +10 -10
- package/dist/components/page-header.js +3 -3
- package/dist/components/page-header.js.map +1 -1
- package/dist/components/password-strength-labels.d.ts +2 -0
- package/dist/components/password-strength-labels.js +21 -0
- package/dist/components/password-strength-labels.js.map +1 -0
- package/dist/components/password-strength.d.ts +15 -17
- package/dist/components/password-strength.js +7 -22
- package/dist/components/password-strength.js.map +1 -1
- package/dist/components/phone-input-labels.d.ts +2 -0
- package/dist/components/phone-input-labels.js +9 -0
- package/dist/components/phone-input-labels.js.map +1 -0
- package/dist/components/phone-input.d.ts +75 -100
- package/dist/components/phone-input.js +20 -23
- package/dist/components/phone-input.js.map +1 -1
- package/dist/components/picker-sheet.d.ts +20 -8
- package/dist/components/picker-sheet.js +22 -11
- package/dist/components/picker-sheet.js.map +1 -1
- package/dist/components/pie-chart-labels.d.ts +2 -4
- package/dist/components/pie-chart.d.ts +8 -11
- package/dist/components/pie-chart.js +5 -5
- package/dist/components/pie-chart.js.map +1 -1
- package/dist/components/popover-labels.d.ts +2 -0
- package/dist/components/popover-labels.js +11 -0
- package/dist/components/popover-labels.js.map +1 -0
- package/dist/components/popover.d.ts +13 -11
- package/dist/components/popover.js +21 -23
- package/dist/components/popover.js.map +1 -1
- package/dist/components/progress-bar-labels.d.ts +2 -0
- package/dist/components/progress-bar-labels.js +9 -0
- package/dist/components/progress-bar-labels.js.map +1 -0
- package/dist/components/progress-bar.d.ts +16 -15
- package/dist/components/progress-bar.js +22 -20
- package/dist/components/progress-bar.js.map +1 -1
- package/dist/components/qr-code.d.ts +4 -8
- package/dist/components/qr-code.js.map +1 -1
- package/dist/components/reauth-dialog-labels.d.ts +2 -0
- package/dist/components/reauth-dialog-labels.js +12 -0
- package/dist/components/reauth-dialog-labels.js.map +1 -0
- package/dist/components/reauth-dialog.d.ts +8 -10
- package/dist/components/reauth-dialog.js +3 -8
- package/dist/components/reauth-dialog.js.map +1 -1
- package/dist/components/row-actions-labels.d.ts +2 -0
- package/dist/components/row-actions-labels.js +9 -0
- package/dist/components/row-actions-labels.js.map +1 -0
- package/dist/components/row-actions.d.ts +224 -100
- package/dist/components/row-actions.js +4 -5
- package/dist/components/row-actions.js.map +1 -1
- package/dist/components/scroll-area.d.ts +6 -9
- package/dist/components/scroll-area.js +4 -10
- package/dist/components/scroll-area.js.map +1 -1
- package/dist/components/search-field.d.ts +12 -27
- package/dist/components/search-field.js +13 -16
- package/dist/components/search-field.js.map +1 -1
- package/dist/components/select.d.ts +69 -0
- package/dist/components/select.js +164 -0
- package/dist/components/select.js.map +1 -0
- package/dist/components/separator.d.ts +3 -7
- package/dist/components/separator.js.map +1 -1
- package/dist/components/series-chart-axes.d.ts +120 -0
- package/dist/components/series-chart-axes.js +164 -0
- package/dist/components/series-chart-axes.js.map +1 -0
- package/dist/components/series-chart-budget.d.ts +8 -9
- package/dist/components/series-chart-labels.d.ts +2 -4
- package/dist/components/series-chart-thin.d.ts +34 -0
- package/dist/components/series-chart-thin.js +103 -0
- package/dist/components/series-chart-thin.js.map +1 -0
- package/dist/components/series-chart-ticks.d.ts +9 -11
- package/dist/components/series-chart.d.ts +64 -213
- package/dist/components/series-chart.js +69 -160
- package/dist/components/series-chart.js.map +1 -1
- package/dist/components/server-wake-labels.d.ts +2 -0
- package/dist/components/server-wake-labels.js +9 -0
- package/dist/components/server-wake-labels.js.map +1 -0
- package/dist/components/server-wake.d.ts +32 -23
- package/dist/components/server-wake.js +15 -35
- package/dist/components/server-wake.js.map +1 -1
- package/dist/components/settings-fields.d.ts +46 -117
- package/dist/components/settings-fields.js +13 -3
- package/dist/components/settings-fields.js.map +1 -1
- package/dist/components/share-card-labels.d.ts +2 -0
- package/dist/components/share-card-labels.js +29 -0
- package/dist/components/share-card-labels.js.map +1 -0
- package/dist/components/share-card.d.ts +188 -100
- package/dist/components/share-card.js +16 -34
- package/dist/components/share-card.js.map +1 -1
- package/dist/components/sign-chip-labels.d.ts +2 -0
- package/dist/components/sign-chip-labels.js +11 -0
- package/dist/components/sign-chip-labels.js.map +1 -0
- package/dist/components/sign-chip.d.ts +7 -9
- package/dist/components/sign-chip.js +2 -7
- package/dist/components/sign-chip.js.map +1 -1
- package/dist/components/signature-pad-labels.d.ts +2 -0
- package/dist/components/signature-pad-labels.js +23 -0
- package/dist/components/signature-pad-labels.js.map +1 -0
- package/dist/components/signature-pad.d.ts +16 -15
- package/dist/components/signature-pad.js +22 -35
- package/dist/components/signature-pad.js.map +1 -1
- package/dist/components/signed-amount-labels.d.ts +2 -0
- package/dist/components/signed-amount-labels.js +9 -0
- package/dist/components/signed-amount-labels.js.map +1 -0
- package/dist/components/signed-amount.d.ts +19 -21
- package/dist/components/signed-amount.js +12 -15
- package/dist/components/signed-amount.js.map +1 -1
- package/dist/components/skeleton.d.ts +13 -9
- package/dist/components/skeleton.js +1 -1
- package/dist/components/skeleton.js.map +1 -1
- package/dist/components/slider.d.ts +16 -11
- package/dist/components/slider.js +23 -18
- package/dist/components/slider.js.map +1 -1
- package/dist/components/sparkline-labels.d.ts +2 -0
- package/dist/components/sparkline-labels.js +13 -0
- package/dist/components/sparkline-labels.js.map +1 -0
- package/dist/components/sparkline.d.ts +10 -12
- package/dist/components/sparkline.js +10 -17
- package/dist/components/sparkline.js.map +1 -1
- package/dist/components/spinner.d.ts +45 -0
- package/dist/components/spinner.js +39 -0
- package/dist/components/spinner.js.map +1 -0
- package/dist/components/stat-tile-labels.d.ts +2 -0
- package/dist/components/stat-tile-labels.js +14 -0
- package/dist/components/stat-tile-labels.js.map +1 -0
- package/dist/components/stat-tile.d.ts +15 -17
- package/dist/components/stat-tile.js +25 -32
- package/dist/components/stat-tile.js.map +1 -1
- package/dist/components/status-dot.d.ts +8 -20
- package/dist/components/status-dot.js +13 -12
- package/dist/components/status-dot.js.map +1 -1
- package/dist/components/swatch-picker-labels.d.ts +2 -0
- package/dist/components/swatch-picker-labels.js +9 -0
- package/dist/components/swatch-picker-labels.js.map +1 -0
- package/dist/components/swatch-picker.d.ts +14 -14
- package/dist/components/swatch-picker.js +14 -8
- package/dist/components/swatch-picker.js.map +1 -1
- package/dist/components/swipeable-row.d.ts +14 -27
- package/dist/components/swipeable-row.js +2 -2
- package/dist/components/swipeable-row.js.map +1 -1
- package/dist/components/switch.d.ts +10 -13
- package/dist/components/switch.js +13 -12
- package/dist/components/switch.js.map +1 -1
- package/dist/components/table.d.ts +28 -31
- package/dist/components/table.js +15 -15
- package/dist/components/table.js.map +1 -1
- package/dist/components/tabs.d.ts +182 -0
- package/dist/components/tabs.js +312 -0
- package/dist/components/tabs.js.map +1 -0
- package/dist/components/text-link.d.ts +17 -118
- package/dist/components/text-link.js +7 -7
- package/dist/components/text-link.js.map +1 -1
- package/dist/components/text.d.ts +14 -13
- package/dist/components/text.js +5 -5
- package/dist/components/text.js.map +1 -1
- package/dist/components/textarea.d.ts +20 -0
- package/dist/components/textarea.js +161 -0
- package/dist/components/textarea.js.map +1 -0
- package/dist/components/tile-radio.d.ts +6 -10
- package/dist/components/tile-radio.js +6 -6
- package/dist/components/tile-radio.js.map +1 -1
- package/dist/components/time-input.d.ts +5 -107
- package/dist/components/time-input.js +14 -5
- package/dist/components/time-input.js.map +1 -1
- package/dist/components/toast-labels.d.ts +2 -0
- package/dist/components/toast-labels.js +11 -0
- package/dist/components/toast-labels.js.map +1 -0
- package/dist/components/toast.d.ts +21 -23
- package/dist/components/toast.js +1 -6
- package/dist/components/toast.js.map +1 -1
- package/dist/components/toggle-group.d.ts +26 -26
- package/dist/components/toggle-group.js +43 -19
- package/dist/components/toggle-group.js.map +1 -1
- package/dist/components/toggle-legend.d.ts +18 -21
- package/dist/components/toggle-legend.js +3 -3
- package/dist/components/toggle-legend.js.map +1 -1
- package/dist/components/tooltip.d.ts +16 -15
- package/dist/components/tooltip.js +4 -9
- package/dist/components/tooltip.js.map +1 -1
- package/dist/components/translation-review-editor.d.ts +8 -10
- package/dist/components/translation-review-editor.js +6 -5
- package/dist/components/translation-review-editor.js.map +1 -1
- package/dist/components/translation-review-labels.d.ts +4 -7
- package/dist/components/translation-review-parts.d.ts +19 -28
- package/dist/components/translation-review-parts.js +4 -7
- package/dist/components/translation-review-parts.js.map +1 -1
- package/dist/components/translation-review.d.ts +26 -24
- package/dist/components/translation-review.js +13 -10
- package/dist/components/translation-review.js.map +1 -1
- package/dist/components/tree-view.d.ts +7 -11
- package/dist/components/tree-view.js +8 -8
- package/dist/components/tree-view.js.map +1 -1
- package/dist/components/treemap.d.ts +9 -13
- package/dist/components/trigger-aria.d.ts +2 -4
- package/dist/components/ui-labels.d.ts +5 -0
- package/dist/components/ui-labels.js +20 -0
- package/dist/components/ui-labels.js.map +1 -0
- package/dist/components/use-anchor-dir.d.ts +3 -6
- package/dist/components/use-mobile-reveal.d.ts +2 -6
- package/dist/components/use-table-state.d.ts +154 -15
- package/dist/components/user-avatar.d.ts +8 -21
- package/dist/components/user-avatar.js +1 -1
- package/dist/components/user-avatar.js.map +1 -1
- package/dist/components/wizard-stepper.d.ts +6 -6
- package/dist/components/wizard-stepper.js +4 -3
- package/dist/components/wizard-stepper.js.map +1 -1
- package/dist/components/write-lock-labels.d.ts +2 -0
- package/dist/components/write-lock-labels.js +8 -0
- package/dist/components/write-lock-labels.js.map +1 -0
- package/dist/components/write-lock.d.ts +16 -18
- package/dist/components/write-lock.js +4 -8
- package/dist/components/write-lock.js.map +1 -1
- package/dist/data-table.d.ts +10 -18
- package/dist/data-table.js.map +1 -1
- package/dist/demo/demo-banner.d.ts +10 -13
- package/dist/demo/demo-banner.js +5 -19
- package/dist/demo/demo-banner.js.map +1 -1
- package/dist/demo/demo-countdown.d.ts +7 -9
- package/dist/demo/demo-ended.d.ts +10 -13
- package/dist/demo/demo-ended.js +4 -4
- package/dist/demo/demo-ended.js.map +1 -1
- package/dist/demo/demo-labels.d.ts +4 -5
- package/dist/demo/demo-labels.js.map +1 -1
- package/dist/demo/demo-session.d.ts +3 -5
- package/dist/demo/demo-start.d.ts +8 -11
- package/dist/demo/demo-start.js +3 -2
- package/dist/demo/demo-start.js.map +1 -1
- package/dist/feedback/feedback-attachment-labels.d.ts +16 -0
- package/dist/feedback/feedback-attachment-labels.js +17 -0
- package/dist/feedback/feedback-attachment-labels.js.map +1 -0
- package/dist/feedback/feedback-attachment.d.ts +312 -100
- package/dist/feedback/feedback-attachment.js +31 -42
- package/dist/feedback/feedback-attachment.js.map +1 -1
- package/dist/feedback/feedback-capture.d.ts +2 -4
- package/dist/feedback/feedback-context-labels.d.ts +2 -0
- package/dist/feedback/feedback-context-labels.js +9 -0
- package/dist/feedback/feedback-context-labels.js.map +1 -0
- package/dist/feedback/feedback-context.d.ts +110 -100
- package/dist/feedback/feedback-context.js +4 -7
- package/dist/feedback/feedback-context.js.map +1 -1
- package/dist/feedback/feedback-crash.d.ts +8 -109
- package/dist/feedback/feedback-dialog-labels.d.ts +12 -0
- package/dist/feedback/feedback-dialog-labels.js +17 -0
- package/dist/feedback/feedback-dialog-labels.js.map +1 -0
- package/dist/feedback/feedback-dialog.d.ts +186 -100
- package/dist/feedback/feedback-dialog.js +8 -18
- package/dist/feedback/feedback-dialog.js.map +1 -1
- package/dist/feedback/feedback-inbox.d.ts +236 -100
- package/dist/feedback/feedback-inbox.js +31 -141
- package/dist/feedback/feedback-inbox.js.map +1 -1
- package/dist/feedback/feedback-labels.d.ts +83 -100
- package/dist/feedback/feedback-labels.js.map +1 -1
- package/dist/feedback/feedback-menu-labels.d.ts +2 -0
- package/dist/feedback/feedback-menu-labels.js +10 -0
- package/dist/feedback/feedback-menu-labels.js.map +1 -0
- package/dist/feedback/feedback-menu.d.ts +83 -100
- package/dist/feedback/feedback-menu.js +3 -7
- package/dist/feedback/feedback-menu.js.map +1 -1
- package/dist/feedback/feedback-record.d.ts +239 -100
- package/dist/feedback/feedback-record.js +7 -2
- package/dist/feedback/feedback-record.js.map +1 -1
- package/dist/feedback/feedback-row-detail-labels.d.ts +2 -0
- package/dist/feedback/feedback-row-detail-labels.js +31 -0
- package/dist/feedback/feedback-row-detail-labels.js.map +1 -0
- package/dist/feedback/feedback-row-detail.d.ts +315 -100
- package/dist/feedback/feedback-row-detail.js +11 -37
- package/dist/feedback/feedback-row-detail.js.map +1 -1
- package/dist/feedback/feedback-status-undo.d.ts +66 -100
- package/dist/feedback/feedback-status-undo.js.map +1 -1
- package/dist/feedback/feedback-submit-dialog.d.ts +39 -0
- package/dist/feedback/feedback-submit-dialog.js +66 -0
- package/dist/feedback/feedback-submit-dialog.js.map +1 -0
- package/dist/feedback/feedback-submit.d.ts +13 -108
- package/dist/feedback/feedback-submit.js +19 -40
- package/dist/feedback/feedback-submit.js.map +1 -1
- package/dist/feedback/feedback-swipe.d.ts +9 -109
- package/dist/feedback/feedback-swipe.js +1 -1
- package/dist/feedback/feedback-swipe.js.map +1 -1
- package/dist/feedback/feedback-table-labels.d.ts +2 -0
- package/dist/feedback/feedback-table-labels.js +26 -0
- package/dist/feedback/feedback-table-labels.js.map +1 -0
- package/dist/feedback/feedback-table.d.ts +314 -100
- package/dist/feedback/feedback-table.js +11 -31
- package/dist/feedback/feedback-table.js.map +1 -1
- package/dist/feedback/feedback-thread-labels.d.ts +3 -0
- package/dist/feedback/feedback-thread-labels.js +21 -0
- package/dist/feedback/feedback-thread-labels.js.map +1 -0
- package/dist/feedback/feedback-thread.d.ts +378 -100
- package/dist/feedback/feedback-thread.js +32 -35
- package/dist/feedback/feedback-thread.js.map +1 -1
- package/dist/feedback/feedback-vocabulary.d.ts +98 -0
- package/dist/feedback/feedback-vocabulary.js +143 -0
- package/dist/feedback/feedback-vocabulary.js.map +1 -0
- package/dist/feedback.d.ts +15 -104
- package/dist/hooks/use-anchored-panel.d.ts +109 -17
- package/dist/hooks/use-anchored-panel.js +38 -6
- package/dist/hooks/use-anchored-panel.js.map +1 -1
- package/dist/hooks/use-anchored-rect.d.ts +15 -6
- package/dist/hooks/use-anchored-rect.js +2 -1
- package/dist/hooks/use-anchored-rect.js.map +1 -1
- package/dist/hooks/use-announce.d.ts +4 -6
- package/dist/hooks/use-authed-src.d.ts +5 -7
- package/dist/hooks/use-authed-src.js +3 -7
- package/dist/hooks/use-authed-src.js.map +1 -1
- package/dist/hooks/use-body-scroll-lock.d.ts +1 -3
- package/dist/hooks/use-breakpoint.d.ts +16 -17
- package/dist/hooks/use-breakpoint.js.map +1 -1
- package/dist/hooks/use-close-transition.d.ts +8 -8
- package/dist/hooks/use-close-transition.js +5 -4
- package/dist/hooks/use-close-transition.js.map +1 -1
- package/dist/hooks/use-copy-to-clipboard.d.ts +5 -7
- package/dist/hooks/use-debounce.d.ts +13 -6
- package/dist/hooks/use-debounce.js.map +1 -1
- package/dist/hooks/use-dismiss.d.ts +37 -11
- package/dist/hooks/use-dismiss.js +69 -10
- package/dist/hooks/use-dismiss.js.map +1 -1
- package/dist/hooks/use-file-drop.d.ts +8 -109
- package/dist/hooks/use-file-drop.js +1 -1
- package/dist/hooks/use-file-drop.js.map +1 -1
- package/dist/hooks/use-file-picker-labels.d.ts +2 -0
- package/dist/hooks/use-file-picker-labels.js +25 -0
- package/dist/hooks/use-file-picker-labels.js.map +1 -0
- package/dist/hooks/use-file-picker.d.ts +164 -0
- package/dist/hooks/use-file-picker.js +149 -0
- package/dist/hooks/use-file-picker.js.map +1 -0
- package/dist/hooks/use-focus-trap.d.ts +10 -4
- package/dist/hooks/use-focus-trap.js +19 -12
- package/dist/hooks/use-focus-trap.js.map +1 -1
- package/dist/hooks/use-hotkey.d.ts +7 -9
- package/dist/hooks/use-large-text.d.ts +3 -5
- package/dist/hooks/use-media-query.d.ts +1 -3
- package/dist/hooks/use-noindex.d.ts +1 -3
- package/dist/hooks/use-overlay-history.d.ts +1 -3
- package/dist/hooks/use-row-swipe.d.ts +5 -8
- package/dist/hooks/use-search-param-state.d.ts +10 -11
- package/dist/hooks/use-windowed-rows.d.ts +4 -7
- package/dist/i18n/defaults.d.ts +11 -104
- package/dist/i18n/defaults.js +82 -82
- package/dist/i18n/defaults.js.map +1 -1
- package/dist/i18n/german.d.ts +2 -104
- package/dist/i18n/german.js +56 -9
- package/dist/i18n/german.js.map +1 -1
- package/dist/i18n/kit-labels.d.ts +609 -100
- package/dist/i18n/kit-labels.js +22 -97
- package/dist/i18n/kit-labels.js.map +1 -1
- package/dist/i18n/languages.d.ts +197 -100
- package/dist/i18n/locales/de-CH.d.ts +3 -105
- package/dist/i18n/locales/en.d.ts +4 -104
- package/dist/i18n/locales/en.js +1834 -4
- package/dist/i18n/locales/en.js.map +7 -1
- package/dist/i18n/locales/es.d.ts +3 -105
- package/dist/i18n/locales/es.js +54 -9
- package/dist/i18n/locales/es.js.map +1 -1
- package/dist/i18n/locales/fr.d.ts +3 -105
- package/dist/i18n/locales/fr.js +56 -9
- package/dist/i18n/locales/fr.js.map +1 -1
- package/dist/i18n/locales/hu.d.ts +3 -105
- package/dist/i18n/locales/hu.js +56 -10
- package/dist/i18n/locales/hu.js.map +1 -1
- package/dist/i18n/locales/it.d.ts +3 -105
- package/dist/i18n/locales/it.js +55 -9
- package/dist/i18n/locales/it.js.map +1 -1
- package/dist/i18n/locales/zh.d.ts +3 -105
- package/dist/i18n/locales/zh.js +52 -8
- package/dist/i18n/locales/zh.js.map +1 -1
- package/dist/i18n/plurals.d.ts +20 -3
- package/dist/i18n/plurals.js +11 -0
- package/dist/i18n/plurals.js.map +1 -1
- package/dist/i18n/review.d.ts +5 -106
- package/dist/i18n/review.js +4 -0
- package/dist/i18n/review.js.map +1 -1
- package/dist/i18n/shared-labels.d.ts +17 -0
- package/dist/i18n/shared-labels.js +111 -0
- package/dist/i18n/shared-labels.js.map +1 -0
- package/dist/i18n/swiss.d.ts +1 -3
- package/dist/index.d.ts +329 -249
- package/dist/index.js +188 -215
- package/dist/index.js.map +1 -1
- package/dist/landing/access.d.ts +7 -9
- package/dist/landing/access.js.map +1 -1
- package/dist/landing/landing-actions.d.ts +9 -108
- package/dist/landing/landing-actions.js +1 -1
- package/dist/landing/landing-actions.js.map +1 -1
- package/dist/landing/landing-labels.d.ts +4 -5
- package/dist/landing/landing-labels.js.map +1 -1
- package/dist/landing/landing-sections.d.ts +21 -120
- package/dist/landing/landing-sections.js +15 -15
- package/dist/landing/landing-sections.js.map +1 -1
- package/dist/landing/page-seo.d.ts +7 -9
- package/dist/landing/public-header.d.ts +10 -110
- package/dist/landing/public-header.js +1 -1
- package/dist/landing/public-header.js.map +1 -1
- package/dist/landing/routing.d.ts +16 -119
- package/dist/landing/routing.js +2 -6
- package/dist/landing/routing.js.map +1 -1
- package/dist/lib/calc.d.ts +7 -9
- package/dist/lib/chip-edge-snap.d.ts +10 -0
- package/dist/lib/chip-edge-snap.js +131 -0
- package/dist/lib/chip-edge-snap.js.map +1 -0
- package/dist/lib/clipping.d.ts +2 -4
- package/dist/lib/cn.d.ts +2 -5
- package/dist/lib/cn.js +6 -1
- package/dist/lib/cn.js.map +1 -1
- package/dist/lib/column-mapping.d.ts +10 -13
- package/dist/lib/countries.d.ts +3 -5
- package/dist/lib/dates.d.ts +25 -25
- package/dist/lib/dates.js.map +1 -1
- package/dist/lib/decimal-marks.d.ts +8 -8
- package/dist/lib/decimal-marks.js +1 -1
- package/dist/lib/decimal-marks.js.map +1 -1
- package/dist/lib/direction.d.ts +4 -6
- package/dist/lib/document-navigation.d.ts +1 -3
- package/dist/lib/download.d.ts +67 -0
- package/dist/lib/download.js +89 -0
- package/dist/lib/download.js.map +1 -0
- package/dist/lib/floating-stack.d.ts +8 -6
- package/dist/lib/floating-stack.js.map +1 -1
- package/dist/lib/format.d.ts +24 -23
- package/dist/lib/format.js +3 -3
- package/dist/lib/format.js.map +1 -1
- package/dist/lib/iban.d.ts +9 -11
- package/dist/lib/ime.d.ts +17 -0
- package/dist/lib/ime.js +13 -0
- package/dist/lib/ime.js.map +1 -0
- package/dist/lib/isin.d.ts +3 -5
- package/dist/lib/logger.d.ts +4 -6
- package/dist/lib/person-name.d.ts +3 -5
- package/dist/lib/phone.d.ts +9 -11
- package/dist/lib/presence.d.ts +15 -0
- package/dist/lib/presence.js +8 -0
- package/dist/lib/presence.js.map +1 -0
- package/dist/lib/qr-encode.d.ts +4 -6
- package/dist/lib/reduced-motion.d.ts +18 -0
- package/dist/lib/reduced-motion.js +9 -0
- package/dist/lib/reduced-motion.js.map +1 -0
- package/dist/lib/round.d.ts +22 -0
- package/dist/lib/round.js +15 -0
- package/dist/lib/round.js.map +1 -0
- package/dist/lib/safe-storage.d.ts +14 -4
- package/dist/lib/safe-storage.js +24 -9
- package/dist/lib/safe-storage.js.map +1 -1
- package/dist/lib/server-wake.d.ts +13 -14
- package/dist/lib/session-refresh.d.ts +200 -0
- package/dist/lib/session-refresh.js +187 -0
- package/dist/lib/session-refresh.js.map +1 -0
- package/dist/lib/strip-fade.d.ts +10 -13
- package/dist/lib/table-text.d.ts +14 -16
- package/dist/lib/text-match.d.ts +41 -0
- package/dist/lib/text-match.js +23 -0
- package/dist/lib/text-match.js.map +1 -0
- package/dist/lib/translation-review.d.ts +44 -45
- package/dist/lib/translation-review.js +3 -2
- package/dist/lib/translation-review.js.map +1 -1
- package/dist/rhf/fields.d.ts +123 -188
- package/dist/rhf/fields.js +46 -54
- package/dist/rhf/fields.js.map +1 -1
- package/dist/rhf/form-core.d.ts +153 -0
- package/dist/rhf/form-core.js +143 -0
- package/dist/rhf/form-core.js.map +1 -0
- package/dist/rhf/form.d.ts +38 -174
- package/dist/rhf/form.js +9 -131
- package/dist/rhf/form.js.map +1 -1
- package/dist/rhf/line-items.d.ts +40 -11
- package/dist/rhf/line-items.js.map +1 -1
- package/dist/rhf/use-rhf-wizard-step.d.ts +3 -6
- package/dist/rhf.d.ts +4 -117
- package/dist/rhf.js.map +1 -1
- package/dist/search/command-palette-labels.d.ts +2 -0
- package/dist/search/command-palette-labels.js +15 -0
- package/dist/search/command-palette-labels.js.map +1 -0
- package/dist/search/command-palette.d.ts +10 -13
- package/dist/search/command-palette.js +25 -44
- package/dist/search/command-palette.js.map +1 -1
- package/dist/search/global-search-labels.d.ts +2 -0
- package/dist/search/global-search-labels.js +12 -0
- package/dist/search/global-search-labels.js.map +1 -0
- package/dist/search/global-search.d.ts +17 -16
- package/dist/search/global-search.js +12 -12
- package/dist/search/global-search.js.map +1 -1
- package/dist/search/search-index.d.ts +13 -14
- package/dist/search/search-index.js +2 -1
- package/dist/search/search-index.js.map +1 -1
- package/dist/search/use-command-key.d.ts +9 -0
- package/dist/search/use-command-key.js +18 -0
- package/dist/search/use-command-key.js.map +1 -0
- package/dist/search.d.ts +3 -4
- package/dist/settings/settings-card-classes.d.ts +11 -0
- package/dist/settings/settings-card-classes.js +8 -0
- package/dist/settings/settings-card-classes.js.map +1 -0
- package/dist/settings/settings-catalogue.d.ts +11 -14
- package/dist/settings/settings-context.d.ts +4 -8
- package/dist/settings/settings-heading.d.ts +8 -12
- package/dist/settings/settings-heading.js +1 -1
- package/dist/settings/settings-heading.js.map +1 -1
- package/dist/settings/settings-labels.d.ts +6 -7
- package/dist/settings/settings-labels.js.map +1 -1
- package/dist/settings/settings-layout.d.ts +36 -13
- package/dist/settings/settings-layout.js +25 -4
- package/dist/settings/settings-layout.js.map +1 -1
- package/dist/settings/settings-section.d.ts +4 -106
- package/dist/settings/settings-section.js +2 -2
- package/dist/settings/settings-section.js.map +1 -1
- package/dist/settings/use-account-appearance.d.ts +11 -16
- package/dist/settings/use-account-language.d.ts +8 -10
- package/dist/settings/use-settings-focus.d.ts +3 -5
- package/dist/settings/use-settings-focus.js +2 -4
- package/dist/settings/use-settings-focus.js.map +1 -1
- package/dist/settings/use-settings-route.d.ts +11 -16
- package/dist/shell/app-shell-labels.d.ts +2 -0
- package/dist/shell/app-shell-labels.js +9 -0
- package/dist/shell/app-shell-labels.js.map +1 -0
- package/dist/shell/app-shell.d.ts +216 -100
- package/dist/shell/app-shell.js +51 -35
- package/dist/shell/app-shell.js.map +1 -1
- package/dist/shell/auth-layout.d.ts +6 -9
- package/dist/shell/auth-layout.js +6 -6
- package/dist/shell/auth-layout.js.map +1 -1
- package/dist/shell/company-switcher-labels.d.ts +2 -0
- package/dist/shell/company-switcher-labels.js +12 -0
- package/dist/shell/company-switcher-labels.js.map +1 -0
- package/dist/shell/company-switcher.d.ts +9 -11
- package/dist/shell/company-switcher.js +3 -9
- package/dist/shell/company-switcher.js.map +1 -1
- package/dist/shell/option-switcher-menu.d.ts +19 -9
- package/dist/shell/option-switcher-menu.js +6 -4
- package/dist/shell/option-switcher-menu.js.map +1 -1
- package/dist/shell/role-switcher.d.ts +5 -6
- package/dist/shell/role-switcher.js +4 -3
- package/dist/shell/role-switcher.js.map +1 -1
- package/dist/shell/top-bar-brand.d.ts +4 -106
- package/dist/shell/top-bar-brand.js +1 -1
- package/dist/shell/top-bar-brand.js.map +1 -1
- package/dist/shell/top-bar.d.ts +6 -9
- package/dist/shell/top-bar.js +1 -1
- package/dist/shell/top-bar.js.map +1 -1
- package/dist/shell/topbar-action-menu.d.ts +30 -31
- package/dist/shell/topbar-action-menu.js +12 -10
- package/dist/shell/topbar-action-menu.js.map +1 -1
- package/dist/shell/topbar-controls.d.ts +20 -18
- package/dist/shell/topbar-controls.js +14 -11
- package/dist/shell/topbar-controls.js.map +1 -1
- package/dist/shell.d.ts +25 -115
- package/dist/shell.js.map +1 -1
- package/dist/table-text.d.ts +1 -1
- package/dist/testing/css-variables.d.ts +4 -6
- package/dist/testing/css-variables.generated.d.ts +2 -4
- package/dist/testing/index.d.ts +2 -1
- package/dist/testing/index.js +9 -1
- package/dist/testing/index.js.map +1 -1
- package/dist/testing/viewport.d.ts +93 -0
- package/dist/testing/viewport.js +152 -0
- package/dist/testing/viewport.js.map +1 -0
- package/dist/theme/chart-palette.d.ts +7 -9
- package/dist/theme/color.d.ts +14 -16
- package/dist/theme/color.js +2 -1
- package/dist/theme/color.js.map +1 -1
- package/dist/theme/contrast-tokens.d.ts +13 -17
- package/dist/theme/contrast.d.ts +22 -27
- package/dist/theme/palette-derive.d.ts +16 -22
- package/dist/theme/palette-derive.js +15 -7
- package/dist/theme/palette-derive.js.map +1 -1
- package/dist/theme/palette-presets.d.ts +25 -15
- package/dist/theme/palette-presets.js +66 -66
- package/dist/theme/palette-presets.js.map +1 -1
- package/dist/theme/palette-store.d.ts +10 -13
- package/dist/theme/text-size.d.ts +21 -26
- package/dist/theme/theme-store.d.ts +9 -14
- package/dist/tour/tour-labels.d.ts +2 -0
- package/dist/tour/tour-labels.js +13 -0
- package/dist/tour/tour-labels.js.map +1 -0
- package/dist/tour/tour.d.ts +12 -14
- package/dist/tour/tour.js +9 -20
- package/dist/tour/tour.js.map +1 -1
- package/dist/tour.d.ts +1 -2
- package/dist/wizard/stepper-nav.d.ts +8 -107
- package/dist/wizard/stepper-nav.js +15 -14
- package/dist/wizard/stepper-nav.js.map +1 -1
- package/dist/wizard/types.d.ts +18 -18
- package/dist/wizard/types.js +1 -19
- package/dist/wizard/types.js.map +1 -1
- package/dist/wizard/use-wizard.d.ts +2 -6
- package/dist/wizard/validation.d.ts +3 -7
- package/dist/wizard/wizard-context.d.ts +7 -11
- package/dist/wizard/wizard-labels.d.ts +4 -0
- package/dist/wizard/wizard-labels.js +24 -0
- package/dist/wizard/wizard-labels.js.map +1 -0
- package/dist/wizard/wizard-step.d.ts +3 -7
- package/dist/wizard/wizard-step.js +2 -2
- package/dist/wizard/wizard-step.js.map +1 -1
- package/dist/wizard/wizard-summary.d.ts +5 -8
- package/dist/wizard/wizard-summary.js +6 -5
- package/dist/wizard/wizard-summary.js.map +1 -1
- package/dist/wizard.d.ts +7 -106
- package/package.json +9 -6
- package/src/account/account-parts.ts +3 -3
- package/src/{components → account}/account-settings-labels.ts +11 -1
- package/src/{components → account}/account-settings.tsx +145 -34
- package/src/account/data-export-setting-labels.ts +20 -0
- package/src/account/data-export-setting.tsx +19 -38
- package/src/account/delete-account-setting-labels.ts +33 -0
- package/src/account/delete-account-setting.tsx +13 -35
- package/src/account/email-change-setting-labels.ts +32 -0
- package/src/account/email-change-setting.tsx +17 -36
- package/src/{components → account}/passkeys-setting.tsx +14 -9
- package/src/account/sessions-setting-labels.ts +24 -0
- package/src/account/sessions-setting.tsx +14 -28
- package/src/admin/admin-action-confirm-labels.ts +19 -0
- package/src/admin/admin-action-confirm.tsx +59 -38
- package/src/admin/admin-action-log-labels.ts +74 -0
- package/src/admin/admin-action-log.tsx +180 -54
- package/src/admin/admin-parts.ts +0 -7
- package/src/admin/invitations-panel-labels.ts +31 -0
- package/src/admin/invitations-panel.tsx +16 -34
- package/src/admin/plan-change-labels.ts +23 -0
- package/src/admin/plan-change.tsx +89 -37
- package/src/admin/reviewer-scope-editor-labels.ts +16 -0
- package/src/admin/reviewer-scope-editor.tsx +9 -15
- package/src/admin/role-select-labels.ts +16 -0
- package/src/admin/role-select.tsx +13 -23
- package/src/admin/transfer-ownership-dialog-labels.ts +20 -0
- package/src/admin/transfer-ownership-dialog.tsx +7 -17
- package/src/admin/user-roster-labels.ts +17 -0
- package/src/admin/user-roster.tsx +9 -17
- package/src/auth/accept-invitation-labels.ts +21 -0
- package/src/auth/accept-invitation.tsx +9 -20
- package/src/auth/auth-errors.ts +29 -13
- package/src/auth/complete-name-dialog-labels.ts +16 -0
- package/src/auth/complete-name-dialog.tsx +8 -13
- package/src/auth/forgot-password-form-labels.ts +20 -0
- package/src/auth/forgot-password-form.tsx +12 -20
- package/src/auth/new-password-fields.tsx +1 -1
- package/src/auth/not-found-page-labels.ts +12 -0
- package/src/auth/not-found-page.tsx +11 -14
- package/src/auth/register-form-labels.ts +31 -0
- package/src/auth/register-form.tsx +18 -38
- package/src/auth/reset-password-form-labels.ts +27 -0
- package/src/auth/reset-password-form.tsx +12 -27
- package/src/auth/sign-in-form-labels.ts +44 -0
- package/src/auth/sign-in-form.tsx +18 -51
- package/src/auth/status-parts.tsx +3 -3
- package/src/auth/verify-email-labels.ts +26 -0
- package/src/auth/verify-email.tsx +15 -30
- package/src/billing/billing-banner.tsx +2 -1
- package/src/billing/billing-labels.ts +1 -1
- package/src/billing/checkout-processing.ts +2 -12
- package/src/billing/pay-page.ts +9 -5
- package/src/billing/plan-card.tsx +26 -27
- package/src/billing/plan-limit-notice.tsx +1 -1
- package/src/billing/subscription-actions.tsx +4 -4
- package/src/chart.ts +7 -1
- package/src/components/account-chips-labels.ts +16 -0
- package/src/components/account-chips.tsx +13 -16
- package/src/components/alert-banner.tsx +39 -19
- package/src/components/amount-input.tsx +461 -405
- package/src/components/appearance-labels.ts +2 -2
- package/src/components/authed-image-labels.ts +11 -0
- package/src/components/authed-image.tsx +6 -8
- package/src/components/autocomplete.tsx +84 -80
- package/src/components/breadcrumbs-labels.ts +10 -0
- package/src/components/breadcrumbs.tsx +17 -14
- package/src/components/bulk-action-bar-labels.ts +11 -0
- package/src/components/bulk-action-bar.tsx +15 -16
- package/src/components/button-group.tsx +7 -7
- package/src/components/button-look.ts +230 -0
- package/src/components/button.tsx +339 -0
- package/src/components/calculator.tsx +18 -11
- package/src/components/calendar-heatmap-labels.ts +15 -0
- package/src/components/calendar-heatmap.tsx +13 -19
- package/src/components/card.tsx +381 -0
- package/src/components/chart-zoom-core.tsx +653 -0
- package/src/components/chart-zoom.tsx +64 -648
- package/src/components/chart.tsx +11 -11
- package/src/components/checkbox-group.tsx +13 -10
- package/src/components/checkbox.tsx +43 -42
- package/src/components/chip-input.tsx +377 -0
- package/src/components/chip-labels.ts +13 -0
- package/src/components/chip.tsx +115 -711
- package/src/components/choice-card.tsx +83 -85
- package/src/components/column-mapper-labels.ts +45 -0
- package/src/components/column-mapper.tsx +16 -51
- package/src/components/combobox-core.tsx +351 -196
- package/src/components/combobox-suggestions.tsx +129 -0
- package/src/components/combobox.tsx +69 -893
- package/src/components/confirm-dialog-labels.ts +13 -0
- package/src/components/confirm-dialog.tsx +4 -8
- package/src/components/copy-button-labels.ts +13 -0
- package/src/components/copy-button.tsx +10 -12
- package/src/components/country-select-labels.ts +11 -0
- package/src/components/country-select.tsx +74 -89
- package/src/components/currency-option-list.tsx +216 -0
- package/src/components/currency-select.tsx +85 -196
- package/src/components/danger-confirm-labels.ts +20 -0
- package/src/components/danger-confirm.tsx +69 -77
- package/src/components/data-table-cells.tsx +5 -5
- package/src/components/data-table-column-settings.tsx +137 -0
- package/src/components/data-table-filter-popover.tsx +49 -24
- package/src/components/data-table-filters.ts +48 -11
- package/src/components/data-table-head.tsx +258 -0
- package/src/components/data-table-labels.ts +43 -11
- package/src/components/data-table-mobile.tsx +594 -0
- package/src/components/data-table-pagination.tsx +11 -10
- package/src/components/data-table-resize.ts +187 -0
- package/src/components/data-table-row-actions.tsx +152 -0
- package/src/components/data-table-selection.ts +55 -0
- package/src/components/data-table-shared.tsx +172 -0
- package/src/components/data-table.tsx +178 -1300
- package/src/components/date-field.tsx +627 -0
- package/src/components/date-picker.tsx +58 -1446
- package/src/components/date-range-picker.tsx +490 -0
- package/src/components/description-list-labels.ts +9 -0
- package/src/components/description-list.tsx +31 -15
- package/src/components/dialog-frame-labels.ts +7 -0
- package/src/components/dialog-frame.tsx +8 -6
- package/src/components/disclosure.tsx +14 -14
- package/src/components/dropdown.tsx +114 -42
- package/src/components/empty-state.tsx +137 -0
- package/src/components/entity-combobox.tsx +17 -12
- package/src/components/error-boundary-labels.ts +20 -0
- package/src/components/error-boundary.tsx +10 -20
- package/src/components/facing-pair.ts +1 -1
- package/src/components/field-base.tsx +615 -0
- package/src/components/field-parts.tsx +206 -77
- package/src/components/field-strip.tsx +16 -21
- package/src/components/field-sync-labels.ts +13 -0
- package/src/components/field-sync.tsx +11 -12
- package/src/components/field.tsx +13 -11
- package/src/components/file-button.tsx +64 -412
- package/src/components/file-dropzone.tsx +36 -33
- package/src/components/floating-panel-labels.ts +10 -0
- package/src/components/floating-panel.tsx +32 -21
- package/src/components/focus-ring.ts +9 -4
- package/src/components/form-actions-labels.ts +11 -0
- package/src/components/form-actions.tsx +17 -21
- package/src/components/full-bleed-dialog.tsx +33 -25
- package/src/components/grouped-picker.tsx +118 -96
- package/src/components/help-popover.tsx +115 -0
- package/src/components/hover-menu.tsx +46 -35
- package/src/components/iban-input-labels.ts +15 -0
- package/src/components/iban-input.tsx +25 -20
- package/src/components/icon-button.tsx +945 -0
- package/src/components/icon-picker-labels.ts +13 -0
- package/src/components/icon-picker.tsx +27 -24
- package/src/components/image-grid-labels.ts +11 -0
- package/src/components/image-grid.tsx +13 -15
- package/src/components/inline-edit-field-labels.ts +11 -0
- package/src/components/inline-edit-field.tsx +20 -19
- package/src/components/inline-entity-combobox.tsx +789 -0
- package/src/components/input.tsx +380 -0
- package/src/components/jump-calendar.tsx +385 -0
- package/src/components/language-select.tsx +31 -16
- package/src/components/legal-labels.ts +99 -0
- package/src/components/legal-page.tsx +2 -2
- package/src/components/legal.tsx +11 -101
- package/src/components/lightbox-labels.ts +18 -0
- package/src/components/lightbox.tsx +13 -21
- package/src/components/line-items-labels.ts +14 -0
- package/src/components/line-items.tsx +24 -31
- package/src/components/list-labels.ts +10 -0
- package/src/components/list.tsx +98 -75
- package/src/components/loading-state.tsx +4 -4
- package/src/components/measured-grid-labels.ts +25 -0
- package/src/components/measured-grid.tsx +39 -62
- package/src/components/menu-item.tsx +29 -26
- package/src/components/mini-calendar-labels.ts +17 -0
- package/src/components/mini-calendar.tsx +38 -45
- package/src/components/modal.tsx +36 -18
- package/src/components/money-draft.ts +72 -0
- package/src/components/money-field.tsx +16 -30
- package/src/components/month-picker-labels.ts +22 -0
- package/src/components/month-picker.tsx +59 -45
- package/src/components/multi-entity-combobox.tsx +17 -12
- package/src/components/multi-select.tsx +313 -288
- package/src/components/nav-pills.tsx +19 -8
- package/src/components/number-field.tsx +14 -5
- package/src/components/number-input.tsx +125 -90
- package/src/components/numeric-field.ts +161 -0
- package/src/components/numpad-sheet.tsx +16 -16
- package/src/components/one-time-code-input.tsx +154 -169
- package/src/components/page-contents-labels.ts +9 -0
- package/src/components/page-contents.tsx +15 -15
- package/src/components/page-header.tsx +9 -5
- package/src/components/password-strength-labels.ts +23 -0
- package/src/components/password-strength.tsx +13 -27
- package/src/components/phone-input-labels.ts +10 -0
- package/src/components/phone-input.tsx +42 -57
- package/src/components/picker-sheet.tsx +47 -18
- package/src/components/pie-chart.tsx +11 -9
- package/src/components/popover-labels.ts +14 -0
- package/src/components/popover.tsx +40 -39
- package/src/components/progress-bar-labels.ts +10 -0
- package/src/components/progress-bar.tsx +32 -23
- package/src/components/qr-code.tsx +2 -2
- package/src/components/reauth-dialog-labels.ts +13 -0
- package/src/components/reauth-dialog.tsx +7 -10
- package/src/components/row-actions-labels.ts +10 -0
- package/src/components/row-actions.tsx +11 -10
- package/src/components/scroll-area.tsx +4 -10
- package/src/components/search-field.tsx +35 -49
- package/src/components/select.tsx +302 -0
- package/src/components/separator.tsx +2 -2
- package/src/components/series-chart-axes.ts +329 -0
- package/src/components/series-chart-thin.ts +180 -0
- package/src/components/series-chart.tsx +124 -325
- package/src/components/server-wake-labels.ts +11 -0
- package/src/components/server-wake.tsx +42 -63
- package/src/components/settings-fields.tsx +46 -17
- package/src/components/share-card-labels.ts +30 -0
- package/src/components/share-card.tsx +22 -37
- package/src/components/sign-chip-labels.ts +12 -0
- package/src/components/sign-chip.tsx +6 -9
- package/src/components/signature-pad-labels.ts +24 -0
- package/src/components/signature-pad.tsx +48 -57
- package/src/components/signed-amount-labels.ts +10 -0
- package/src/components/signed-amount.tsx +21 -22
- package/src/components/skeleton.tsx +11 -3
- package/src/components/slider.tsx +51 -39
- package/src/components/sparkline-labels.ts +14 -0
- package/src/components/sparkline.tsx +16 -21
- package/src/components/spinner.tsx +81 -0
- package/src/components/stat-tile-labels.ts +15 -0
- package/src/components/stat-tile.tsx +32 -37
- package/src/components/status-dot.tsx +17 -14
- package/src/components/swatch-picker-labels.ts +10 -0
- package/src/components/swatch-picker.tsx +23 -16
- package/src/components/swipeable-row.tsx +7 -7
- package/src/components/switch.tsx +33 -32
- package/src/components/table.tsx +15 -15
- package/src/components/tabs.tsx +660 -0
- package/src/components/text-link.tsx +7 -7
- package/src/components/text.tsx +10 -6
- package/src/components/textarea.tsx +323 -0
- package/src/components/tile-radio.tsx +6 -6
- package/src/components/time-input.tsx +15 -7
- package/src/components/toast-labels.ts +12 -0
- package/src/components/toast.tsx +5 -8
- package/src/components/toggle-group.tsx +105 -42
- package/src/components/toggle-legend.tsx +6 -6
- package/src/components/tooltip.tsx +10 -21
- package/src/components/translation-review-editor.tsx +8 -7
- package/src/components/translation-review-parts.tsx +9 -13
- package/src/components/translation-review.tsx +26 -14
- package/src/components/tree-view.tsx +14 -12
- package/src/components/ui-labels.ts +22 -0
- package/src/components/user-avatar.tsx +3 -3
- package/src/components/wizard-stepper.tsx +10 -5
- package/src/components/write-lock-labels.ts +9 -0
- package/src/components/write-lock.tsx +10 -12
- package/src/data-table.ts +4 -0
- package/src/demo/demo-banner.tsx +9 -25
- package/src/demo/demo-ended.tsx +8 -7
- package/src/demo/demo-labels.ts +2 -2
- package/src/demo/demo-start.tsx +7 -5
- package/src/feedback/feedback-attachment-labels.ts +36 -0
- package/src/feedback/feedback-attachment.tsx +42 -66
- package/src/feedback/feedback-context-labels.ts +10 -0
- package/src/feedback/feedback-context.tsx +8 -9
- package/src/feedback/feedback-dialog-labels.ts +28 -0
- package/src/feedback/feedback-dialog.tsx +14 -44
- package/src/feedback/feedback-inbox.tsx +49 -252
- package/src/feedback/feedback-labels.ts +5 -5
- package/src/feedback/feedback-menu-labels.ts +11 -0
- package/src/feedback/feedback-menu.tsx +13 -11
- package/src/feedback/feedback-record.ts +21 -7
- package/src/feedback/feedback-row-detail-labels.ts +33 -0
- package/src/feedback/feedback-row-detail.tsx +30 -43
- package/src/feedback/feedback-status-undo.ts +3 -2
- package/src/feedback/feedback-submit-dialog.tsx +109 -0
- package/src/feedback/feedback-submit.tsx +45 -55
- package/src/feedback/feedback-swipe.tsx +1 -1
- package/src/feedback/feedback-table-labels.ts +27 -0
- package/src/feedback/feedback-table.tsx +24 -40
- package/src/feedback/feedback-thread-labels.ts +22 -0
- package/src/feedback/feedback-thread.tsx +68 -48
- package/src/feedback/feedback-vocabulary.ts +252 -0
- package/src/hooks/use-anchored-panel.ts +155 -9
- package/src/hooks/use-anchored-rect.ts +11 -9
- package/src/hooks/use-authed-src.ts +13 -7
- package/src/hooks/use-breakpoint.ts +5 -4
- package/src/hooks/use-close-transition.ts +9 -10
- package/src/hooks/use-debounce.ts +9 -0
- package/src/hooks/use-dismiss.ts +176 -19
- package/src/hooks/use-file-drop.ts +2 -2
- package/src/hooks/use-file-picker-labels.ts +29 -0
- package/src/hooks/use-file-picker.tsx +363 -0
- package/src/hooks/use-focus-trap.ts +74 -18
- package/src/i18n/defaults.ts +91 -82
- package/src/i18n/german.ts +54 -7
- package/src/i18n/kit-labels.tsx +70 -119
- package/src/i18n/locales/en.ts +46 -0
- package/src/i18n/locales/es.ts +52 -7
- package/src/i18n/locales/fr.ts +55 -8
- package/src/i18n/locales/hu.ts +54 -8
- package/src/i18n/locales/it.ts +53 -7
- package/src/i18n/locales/zh.ts +50 -6
- package/src/i18n/plurals.ts +29 -0
- package/src/i18n/review.ts +4 -0
- package/src/i18n/shared-labels.ts +135 -0
- package/src/index.ts +412 -402
- package/src/landing/access.ts +2 -1
- package/src/landing/landing-actions.tsx +6 -5
- package/src/landing/landing-labels.ts +2 -2
- package/src/landing/landing-sections.tsx +24 -23
- package/src/landing/public-header.tsx +3 -2
- package/src/landing/routing.tsx +2 -7
- package/src/lib/chip-edge-snap.ts +212 -0
- package/src/lib/cn.ts +13 -1
- package/src/lib/dates.ts +4 -2
- package/src/lib/decimal-marks.ts +4 -2
- package/src/lib/download.ts +172 -0
- package/src/lib/floating-stack.ts +5 -1
- package/src/lib/format.ts +5 -3
- package/src/lib/ime.ts +24 -0
- package/src/lib/presence.ts +18 -0
- package/src/lib/reduced-motion.ts +21 -0
- package/src/lib/round.ts +38 -0
- package/src/lib/safe-storage.ts +35 -11
- package/src/lib/session-refresh.ts +473 -0
- package/src/lib/text-match.ts +60 -0
- package/src/lib/translation-review.ts +7 -6
- package/src/rhf/fields.tsx +131 -179
- package/src/rhf/form-core.tsx +327 -0
- package/src/rhf/form.tsx +46 -321
- package/src/rhf/line-items.tsx +1 -1
- package/src/rhf.ts +3 -2
- package/src/search/command-palette-labels.ts +16 -0
- package/src/search/command-palette.tsx +37 -50
- package/src/search/global-search-labels.ts +13 -0
- package/src/search/global-search.tsx +50 -24
- package/src/search/search-index.ts +5 -6
- package/src/search/use-command-key.ts +22 -0
- package/src/settings/settings-card-classes.ts +11 -0
- package/src/settings/settings-heading.tsx +1 -1
- package/src/settings/settings-labels.ts +2 -2
- package/src/settings/settings-layout.tsx +65 -6
- package/src/settings/settings-section.tsx +5 -5
- package/src/settings/use-settings-focus.ts +2 -5
- package/src/shell/app-shell-labels.ts +10 -0
- package/src/shell/app-shell.tsx +79 -53
- package/src/shell/auth-layout.tsx +11 -10
- package/src/shell/company-switcher-labels.ts +13 -0
- package/src/shell/company-switcher.tsx +7 -11
- package/src/shell/option-switcher-menu.tsx +25 -6
- package/src/shell/role-switcher.tsx +7 -3
- package/src/shell/top-bar-brand.tsx +1 -1
- package/src/shell/top-bar.tsx +6 -5
- package/src/shell/topbar-action-menu.tsx +39 -20
- package/src/shell/topbar-controls.tsx +24 -12
- package/src/shell.ts +1 -1
- package/src/testing/index.ts +11 -0
- package/src/testing/viewport.ts +251 -0
- package/src/theme/color.ts +7 -1
- package/src/theme/palette-derive.ts +29 -7
- package/src/theme/palette-presets.ts +81 -68
- package/src/tour/tour-labels.ts +14 -0
- package/src/tour/tour.tsx +13 -23
- package/src/wizard/stepper-nav.tsx +19 -18
- package/src/wizard/types.ts +7 -22
- package/src/wizard/wizard-labels.ts +29 -0
- package/src/wizard/wizard-step.tsx +2 -2
- package/src/wizard/wizard-summary.tsx +8 -7
- package/tokens.css +63 -14
- package/dist/components/account-settings-labels.js.map +0 -1
- package/dist/components/account-settings.js.map +0 -1
- package/dist/components/choice-parts.d.ts +0 -24
- package/dist/components/choice-parts.js +0 -18
- package/dist/components/choice-parts.js.map +0 -1
- package/dist/components/passkeys-setting.js.map +0 -1
- package/dist/components/ui.d.ts +0 -100
- package/dist/components/ui.js +0 -1955
- package/dist/components/ui.js.map +0 -1
- package/dist/data-table-labels-BJ5JE_X2.d.ts +0 -923
- package/dist/delete-account-setting-DiPX4Vue.d.ts +0 -8130
- package/src/components/choice-parts.ts +0 -33
- package/src/components/ui.tsx +0 -4233
|
@@ -4,38 +4,19 @@ import { useCallback, useEffect, useId, useMemo, useRef, useState } from "react"
|
|
|
4
4
|
import { ClipboardPaste, Eraser, Plus, Trash2 } from "lucide-react";
|
|
5
5
|
import { cn } from "../lib/cn.js";
|
|
6
6
|
import { horizontalStep } from "../lib/direction.js";
|
|
7
|
+
import { decimalMark } from "../lib/decimal-marks.js";
|
|
7
8
|
import { cellNumber, isCellNumber, parseRows, splitRow } from "../lib/table-text.js";
|
|
8
9
|
import { useKitLabels, useKitLocale } from "../i18n/kit-labels.js";
|
|
9
10
|
import { useWindowedRows, WINDOWED_ROW_INDEX } from "../hooks/use-windowed-rows.js";
|
|
10
11
|
import { ToggleGroup } from "./toggle-group.js";
|
|
11
|
-
import { Button
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
addRow: "Add row",
|
|
17
|
-
removeRow: (row) => `Remove row ${row}`,
|
|
18
|
-
clear: "Clear table",
|
|
19
|
-
pasteHint: "Paste a block from a spreadsheet into any cell",
|
|
20
|
-
cell: (column, row) => `${column}, row ${row}`,
|
|
21
|
-
rowNumber: "Row",
|
|
22
|
-
rowActions: "Row actions",
|
|
23
|
-
keyboardHint: "Arrow keys move between cells. Type to replace a cell, F2 to edit it, Escape to undo the edit. Enter moves down and adds a row at the end.",
|
|
24
|
-
lineError: (line) => `Line ${line} could not be read`,
|
|
25
|
-
points: (count) => count === 1 ? "1 point" : `${count} points`,
|
|
26
|
-
problems: (count) => count === 1 ? "1 cell is not a number" : `${count} cells are not numbers`
|
|
27
|
-
};
|
|
12
|
+
import { Button } from "./button.js";
|
|
13
|
+
import { FIELD_INVALID, FIELD_TOUCH_TEXT } from "./field-base.js";
|
|
14
|
+
import { FOCUS_RING } from "./focus-ring.js";
|
|
15
|
+
import { Textarea } from "./textarea.js";
|
|
16
|
+
import { DEFAULT_MEASURED_GRID_LABELS } from "./measured-grid-labels.js";
|
|
28
17
|
const BLANK = "";
|
|
29
18
|
const DEFAULT_ROW_HEIGHT = 28;
|
|
30
19
|
const ALL_VIEWS = ["cells", "text"];
|
|
31
|
-
function decimalMark(locale) {
|
|
32
|
-
try {
|
|
33
|
-
const part = new Intl.NumberFormat(locale).formatToParts(1.5).find((p) => p.type === "decimal");
|
|
34
|
-
return part?.value === "," ? "," : ".";
|
|
35
|
-
} catch {
|
|
36
|
-
return ".";
|
|
37
|
-
}
|
|
38
|
-
}
|
|
39
20
|
const withMark = (cell, mark) => mark === "," && isCellNumber(cell) ? cell.replace(".", ",") : cell;
|
|
40
21
|
const formatCell = (value, digits, mark) => withMark(String(Number(value.toFixed(digits))), mark);
|
|
41
22
|
const hasContent = (row) => row.some((cell) => cell.trim() !== "");
|
|
@@ -92,7 +73,7 @@ function MeasuredGrid({
|
|
|
92
73
|
// to the initial containing block (see sr-only-containment.test).
|
|
93
74
|
/* @__PURE__ */ jsxs("div", { ...rest, className: cn("relative", className), children: [
|
|
94
75
|
/* @__PURE__ */ jsxs("div", { className: "mb-1 flex flex-wrap items-center justify-between gap-2", children: [
|
|
95
|
-
/* @__PURE__ */ jsx("span", { id: labelId, className: "text-caption font-medium text-
|
|
76
|
+
/* @__PURE__ */ jsx("span", { id: labelId, className: "text-caption font-medium text-muted", children: label }),
|
|
96
77
|
offered.length > 1 && /* @__PURE__ */ jsx(
|
|
97
78
|
ToggleGroup,
|
|
98
79
|
{
|
|
@@ -134,7 +115,7 @@ function MeasuredGrid({
|
|
|
134
115
|
describedBy: hint ? hintId : void 0
|
|
135
116
|
}
|
|
136
117
|
),
|
|
137
|
-
hint && /* @__PURE__ */ jsx("p", { id: hintId, className: "mt-1 px-1 text-caption text-
|
|
118
|
+
hint && /* @__PURE__ */ jsx("p", { id: hintId, className: "mt-1 px-1 text-caption text-muted", children: hint }),
|
|
138
119
|
view === "cells" && /* @__PURE__ */ jsx("span", { id: keysId, className: "sr-only", children: labels.keyboardHint })
|
|
139
120
|
] })
|
|
140
121
|
);
|
|
@@ -300,7 +281,7 @@ function CellGrid({
|
|
|
300
281
|
if (at.row < first || at.row >= last) mounted.push(at.row);
|
|
301
282
|
const filled = cells.filter(hasContent);
|
|
302
283
|
const problems = filled.flat().filter((cell) => cell.trim() !== "" && !isCellNumber(cell)).length;
|
|
303
|
-
return /* @__PURE__ */ jsxs("div", { className: "rounded-md border border-
|
|
284
|
+
return /* @__PURE__ */ jsxs("div", { className: "rounded-md border border-subtle bg-surface", children: [
|
|
304
285
|
/* @__PURE__ */ jsx("div", { ref: scrollRef, className: "max-h-72 overflow-auto", children: /* @__PURE__ */ jsxs(
|
|
305
286
|
"div",
|
|
306
287
|
{
|
|
@@ -313,12 +294,12 @@ function CellGrid({
|
|
|
313
294
|
className: "text-xs",
|
|
314
295
|
style: { minWidth: `calc(4.5rem + ${width} * 5.5rem)` },
|
|
315
296
|
children: [
|
|
316
|
-
/* @__PURE__ */ jsx("div", { ref: headRef, role: "rowgroup", className: "sticky top-0 z-10 bg-
|
|
297
|
+
/* @__PURE__ */ jsx("div", { ref: headRef, role: "rowgroup", className: "sticky top-0 z-10 bg-surface-2", children: /* @__PURE__ */ jsxs(
|
|
317
298
|
"div",
|
|
318
299
|
{
|
|
319
300
|
role: "row",
|
|
320
301
|
"aria-rowindex": 1,
|
|
321
|
-
className: "grid border-b border-
|
|
302
|
+
className: "grid border-b border-subtle",
|
|
322
303
|
style: { gridTemplateColumns: template },
|
|
323
304
|
children: [
|
|
324
305
|
/* @__PURE__ */ jsx(
|
|
@@ -326,7 +307,7 @@ function CellGrid({
|
|
|
326
307
|
{
|
|
327
308
|
role: "columnheader",
|
|
328
309
|
"aria-label": labels.rowNumber,
|
|
329
|
-
className: "flex items-end justify-end px-1 py-1 text-micro text-
|
|
310
|
+
className: "flex items-end justify-end px-1 py-1 text-micro text-placeholder",
|
|
330
311
|
children: "#"
|
|
331
312
|
}
|
|
332
313
|
),
|
|
@@ -334,10 +315,10 @@ function CellGrid({
|
|
|
334
315
|
"div",
|
|
335
316
|
{
|
|
336
317
|
role: "columnheader",
|
|
337
|
-
className: "min-w-0 border-s border-
|
|
318
|
+
className: "min-w-0 border-s border-subtle px-2 py-1 text-end",
|
|
338
319
|
children: [
|
|
339
|
-
/* @__PURE__ */ jsx("span", { className: "block truncate font-medium text-
|
|
340
|
-
column.unit && /* @__PURE__ */ jsx("span", { className: "block truncate text-micro text-
|
|
320
|
+
/* @__PURE__ */ jsx("span", { className: "block truncate font-medium text-primary", children: column.label }),
|
|
321
|
+
column.unit && /* @__PURE__ */ jsx("span", { className: "block truncate text-micro text-muted", children: column.unit })
|
|
341
322
|
]
|
|
342
323
|
},
|
|
343
324
|
index
|
|
@@ -347,7 +328,7 @@ function CellGrid({
|
|
|
347
328
|
{
|
|
348
329
|
role: "columnheader",
|
|
349
330
|
"aria-label": labels.rowActions,
|
|
350
|
-
className: "border-s border-
|
|
331
|
+
className: "border-s border-subtle"
|
|
351
332
|
}
|
|
352
333
|
)
|
|
353
334
|
]
|
|
@@ -362,14 +343,14 @@ function CellGrid({
|
|
|
362
343
|
...{ [WINDOWED_ROW_INDEX]: index },
|
|
363
344
|
role: "row",
|
|
364
345
|
"aria-rowindex": index + 2,
|
|
365
|
-
className: "absolute inset-x-0 grid hover:bg-
|
|
346
|
+
className: "absolute inset-x-0 grid hover:bg-hover",
|
|
366
347
|
style: { top: offsetOf(index), minHeight: estimate, gridTemplateColumns: template },
|
|
367
348
|
children: [
|
|
368
349
|
/* @__PURE__ */ jsx(
|
|
369
350
|
"div",
|
|
370
351
|
{
|
|
371
352
|
role: "rowheader",
|
|
372
|
-
className: "flex items-center justify-end px-1 text-micro tabular-nums text-
|
|
353
|
+
className: "flex items-center justify-end px-1 text-micro tabular-nums text-placeholder",
|
|
373
354
|
children: rowNumber.format(index + 1)
|
|
374
355
|
}
|
|
375
356
|
),
|
|
@@ -377,7 +358,7 @@ function CellGrid({
|
|
|
377
358
|
const value = row[columnIndex] ?? BLANK;
|
|
378
359
|
const bad = value.trim() !== "" && !isCellNumber(value);
|
|
379
360
|
const isCaret = at.row === index && at.column === columnIndex;
|
|
380
|
-
return /* @__PURE__ */ jsx("div", { role: "gridcell", className: "min-w-0 border-s border-
|
|
361
|
+
return /* @__PURE__ */ jsx("div", { role: "gridcell", className: "min-w-0 border-s border-subtle", children: /* @__PURE__ */ jsx(
|
|
381
362
|
"input",
|
|
382
363
|
{
|
|
383
364
|
"data-cell": `${index}:${columnIndex}`,
|
|
@@ -390,7 +371,7 @@ function CellGrid({
|
|
|
390
371
|
"aria-label": labels.cell(column.label, index + 1),
|
|
391
372
|
"aria-invalid": bad || void 0,
|
|
392
373
|
className: cn(
|
|
393
|
-
"block size-full bg-transparent px-2 text-end tabular-nums text-
|
|
374
|
+
"block size-full bg-transparent px-2 text-end tabular-nums text-primary outline-none",
|
|
394
375
|
// A cell is a field: 16 px on touch, or iOS zooms on focus (§10.1).
|
|
395
376
|
FIELD_TOUCH_TEXT,
|
|
396
377
|
// Arriving selects the text (typing replaces it); editing
|
|
@@ -398,11 +379,11 @@ function CellGrid({
|
|
|
398
379
|
// The kit's focus frame (§5), inset so the next cell's
|
|
399
380
|
// border does not paint over it. A text input is
|
|
400
381
|
// `:focus-visible` however it was focused.
|
|
401
|
-
"focus:bg-
|
|
382
|
+
"focus:bg-brand-soft",
|
|
402
383
|
FOCUS_RING,
|
|
403
384
|
"focus-visible:ring-inset",
|
|
404
|
-
isCaret && editing && "focus:bg-
|
|
405
|
-
disabled && "text-
|
|
385
|
+
isCaret && editing && "focus:bg-surface",
|
|
386
|
+
disabled && "text-muted",
|
|
406
387
|
bad && cn(FIELD_INVALID, "ring-inset")
|
|
407
388
|
),
|
|
408
389
|
onMouseDown: (event) => {
|
|
@@ -437,7 +418,7 @@ function CellGrid({
|
|
|
437
418
|
"div",
|
|
438
419
|
{
|
|
439
420
|
role: "gridcell",
|
|
440
|
-
className: "flex items-center justify-center border-s border-
|
|
421
|
+
className: "flex items-center justify-center border-s border-subtle",
|
|
441
422
|
children: /* @__PURE__ */ jsx(
|
|
442
423
|
"button",
|
|
443
424
|
{
|
|
@@ -447,7 +428,7 @@ function CellGrid({
|
|
|
447
428
|
tabIndex: at.row === index && at.column === width ? 0 : -1,
|
|
448
429
|
"aria-label": labels.removeRow(index + 1),
|
|
449
430
|
className: cn(
|
|
450
|
-
"rounded p-1 text-
|
|
431
|
+
"rounded p-1 text-placeholder outline-none hover:text-danger disabled:cursor-default disabled:hover:text-placeholder",
|
|
451
432
|
FOCUS_RING
|
|
452
433
|
),
|
|
453
434
|
onKeyDown: (event) => onCellKeyDown(event, index, width),
|
|
@@ -473,7 +454,7 @@ function CellGrid({
|
|
|
473
454
|
]
|
|
474
455
|
}
|
|
475
456
|
) }),
|
|
476
|
-
/* @__PURE__ */ jsxs("div", { className: "flex flex-wrap items-center gap-x-2 gap-y-1 border-t border-
|
|
457
|
+
/* @__PURE__ */ jsxs("div", { className: "flex flex-wrap items-center gap-x-2 gap-y-1 border-t border-subtle px-2 py-1.5", children: [
|
|
477
458
|
/* @__PURE__ */ jsxs(
|
|
478
459
|
Button,
|
|
479
460
|
{
|
|
@@ -496,7 +477,7 @@ function CellGrid({
|
|
|
496
477
|
{
|
|
497
478
|
variant: "ghost",
|
|
498
479
|
size: "sm",
|
|
499
|
-
className: "text-
|
|
480
|
+
className: "text-muted",
|
|
500
481
|
disabled: disabled || !cells.length,
|
|
501
482
|
onClick: () => {
|
|
502
483
|
onCells([]);
|
|
@@ -509,9 +490,9 @@ function CellGrid({
|
|
|
509
490
|
]
|
|
510
491
|
}
|
|
511
492
|
),
|
|
512
|
-
/* @__PURE__ */ jsx("span", { className: "text-caption tabular-nums text-
|
|
513
|
-
problems > 0 && /* @__PURE__ */ jsx("span", { className: "text-caption text-
|
|
514
|
-
/* @__PURE__ */ jsxs("span", { className: "ms-auto flex items-center gap-1 text-caption text-
|
|
493
|
+
/* @__PURE__ */ jsx("span", { className: "text-caption tabular-nums text-muted", children: /* @__PURE__ */ jsx("bdi", { children: labels.points(filled.length) }) }),
|
|
494
|
+
problems > 0 && /* @__PURE__ */ jsx("span", { className: "text-caption text-danger", children: labels.problems(problems) }),
|
|
495
|
+
/* @__PURE__ */ jsxs("span", { className: "ms-auto flex items-center gap-1 text-caption text-muted", children: [
|
|
515
496
|
/* @__PURE__ */ jsx(ClipboardPaste, { "aria-hidden": true, className: "size-3.5" }),
|
|
516
497
|
" ",
|
|
517
498
|
labels.pasteHint
|
|
@@ -562,7 +543,7 @@ function TextView({ columns, cells, onCells, disabled, mark, labels, labelledBy,
|
|
|
562
543
|
onBlur: commit
|
|
563
544
|
}
|
|
564
545
|
),
|
|
565
|
-
/* @__PURE__ */ jsxs("p", { className: "mt-1 px-1 text-caption text-
|
|
546
|
+
/* @__PURE__ */ jsxs("p", { className: "mt-1 px-1 text-caption text-muted", children: [
|
|
566
547
|
columns.map((column) => column.label).join(" \xB7 "),
|
|
567
548
|
" \u2014 ",
|
|
568
549
|
/* @__PURE__ */ jsx("bdi", { children: labels.points(lines) })
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../../src/components/measured-grid.tsx"],"sourcesContent":["import { useCallback, useEffect, useId, useMemo, useRef, useState } from \"react\";\nimport type { ComponentPropsWithoutRef, KeyboardEvent, ReactNode } from \"react\";\nimport { ClipboardPaste, Eraser, Plus, Trash2 } from \"lucide-react\";\nimport { cn } from \"../lib/cn\";\nimport { horizontalStep } from \"../lib/direction\";\n// The cell pair reads ONE cell, where a comma has no columns to separate and so is\n// always a decimal mark; `splitRow` and `parseRows` read a pasted table, where it may\n// be either and the line decides. See the three named rules at the top of table-text.\nimport { cellNumber, isCellNumber, parseRows, splitRow } from \"../lib/table-text\";\nimport { useKitLabels, useKitLocale } from \"../i18n/kit-labels\";\nimport { useWindowedRows, WINDOWED_ROW_INDEX } from \"../hooks/use-windowed-rows\";\nimport { ToggleGroup } from \"./toggle-group\";\nimport { Button, FIELD_INVALID, FIELD_TOUCH_TEXT, FOCUS_RING, Textarea } from \"./ui\";\n\n/**\n * A measured table: a fixed set of numeric columns, typed cell by cell or pasted as a\n * block out of a spreadsheet — and the hook that holds it as a draft.\n *\n * Moved from Lenkbank (`shared/ui/measured-grid.tsx`), where four gear editors and a\n * setpoint dialog type rig measurements into it. Nothing in it knows what a column\n * holds: the caller passes `{ label, unit }[]`, and the vocabulary of this file is\n * cells, rows, a caret and a paste. The lexing under it is `@eifi1/ui-kit/table-text`.\n *\n * What it is NOT: a `DataTable` mode (that one finds rows among many; this one types\n * numbers into columns), a spreadsheet (no formulas, no multi-cell selection, no undo\n * beyond the browser's per-input one), or typed columns — every cell is a string that\n * should read as a number.\n */\n\n/**\n * Every string the grid can speak — the `measuredGrid` namespace of\n * `<UiKitProvider labels>`, overridable per instance through the `labels` prop. The\n * ones that carry a number are functions of it, for the reason `DataTableLabels` gives:\n * the grammar around a count moves with it in most languages.\n */\nexport interface MeasuredGridLabels {\n /** Accessible name of the cells/text toggle. */\n view: string;\n cellsView: string;\n textView: string;\n addRow: string;\n /** The row's remove button, given its 1-based number. */\n removeRow: (row: number) => string;\n /** Empties the whole table. */\n clear: string;\n /** The footer's standing note that a block can be pasted into any cell. */\n pasteHint: string;\n /**\n * Accessible name of one cell's input, given its column's label and 1-based row.\n * A screen reader in a grid announces the headers on its own when the caret crosses\n * one; this is what it reads when the caret lands on an input with no crossing — and\n * what a voice-control user says to reach it.\n */\n cell: (column: string, row: number) => string;\n /** The row-number column's header, which shows only \"#\". */\n rowNumber: string;\n /** The remove-button column's header, which shows nothing. */\n rowActions: string;\n /** The grid's description: how its keyboard works. Read once, on entry. */\n keyboardHint: string;\n /** The text view could not read this 1-based line of what was typed or pasted. */\n lineError: (line: number) => string;\n /** How many filled rows (measured points) the table holds. */\n points: (count: number) => string;\n /** How many cells are typed but are not numbers. */\n problems: (count: number) => string;\n}\n\n/** English defaults. Exported as the `measuredGrid` namespace of `UiKitLabels`\n * (src/i18n), the complete reference a translation is written against. */\nexport const DEFAULT_MEASURED_GRID_LABELS: MeasuredGridLabels = {\n view: \"Table view\",\n cellsView: \"Cells\",\n textView: \"Text\",\n addRow: \"Add row\",\n removeRow: (row) => `Remove row ${row}`,\n clear: \"Clear table\",\n pasteHint: \"Paste a block from a spreadsheet into any cell\",\n cell: (column, row) => `${column}, row ${row}`,\n rowNumber: \"Row\",\n rowActions: \"Row actions\",\n keyboardHint:\n \"Arrow keys move between cells. Type to replace a cell, F2 to edit it, Escape to undo the edit. Enter moves down and adds a row at the end.\",\n lineError: (line) => `Line ${line} could not be read`,\n points: (count) => (count === 1 ? \"1 point\" : `${count} points`),\n problems: (count) => (count === 1 ? \"1 cell is not a number\" : `${count} cells are not numbers`),\n};\n\n/** One column of a measured table: what it holds and what it is measured in. The unit\n * is separate from the name because the header shows it small and underneath, and\n * because a column with no unit (a count, an index) should not render empty brackets. */\nexport interface MeasuredGridColumn {\n label: string;\n unit?: string;\n}\n\n/** The two ways to look at the same table. */\nexport type MeasuredGridView = \"cells\" | \"text\";\n\n/** A cell that has not been typed into yet. Distinguished from `\"0\"` on purpose: an\n * empty cell is a hole in the measurement, and a table with a hole is not one to save. */\nconst BLANK = \"\";\n\n/** Height of one grid row at Normal text size, in px — the windowing's ESTIMATE since\n * 0.32 (docs/text-size-harmonization.md §10.9): `useWindowedRows` multiplies it by the\n * text size's scale (35 px at Large, 42 at Extra large) and then measures the rows it\n * renders, so a row is never cut to a height the type has outgrown. */\nconst DEFAULT_ROW_HEIGHT = 28;\n\nconst ALL_VIEWS: readonly MeasuredGridView[] = [\"cells\", \"text\"];\n\n/** The locale's decimal mark, as far as a cell can hold it: \",\" or \".\". A mark outside\n * those two (Arabic's \"٫\") is not one `cellNumber` reads, so those locales keep the\n * dot. The same answer `NumberField` gives, for the same reason. */\nfunction decimalMark(locale: string | undefined): \",\" | \".\" {\n try {\n const part = new Intl.NumberFormat(locale).formatToParts(1.5).find((p) => p.type === \"decimal\");\n return part?.value === \",\" ? \",\" : \".\";\n } catch {\n // An invalid tag throws a RangeError; a typo in a locale must not take the grid down.\n return \".\";\n }\n}\n\n/** A number-shaped cell written with the locale's mark. The lexer hands back points;\n * a German user typed commas and should read commas back. Anything that is not a\n * number is left exactly as it was, so the mistake stays visible where it was made. */\nconst withMark = (cell: string, mark: \",\" | \".\") =>\n mark === \",\" && isCellNumber(cell) ? cell.replace(\".\", \",\") : cell;\n\n/** A computed number as a draft cell: rounded to `digits`, with no trailing zeros. */\nconst formatCell = (value: number, digits: number, mark: \",\" | \".\") =>\n withMark(String(Number(value.toFixed(digits))), mark);\n\nconst hasContent = (row: readonly string[]) => row.some((cell) => cell.trim() !== \"\");\n\nexport interface UseMeasuredRowsOptions {\n /** Decimals a computed number is rounded to on its way into a cell. Default 4. */\n digits?: number;\n /** BCP 47 tag whose decimal mark the cells are written with, else the\n * `<UiKitProvider locale>`, else the runtime's. */\n locale?: string;\n}\n\nexport interface MeasuredRows {\n /** The draft, as text — what the grid shows and edits. */\n cells: string[][];\n setCells: (next: string[][]) => void;\n /** The filled rows as numbers — EMPTY until the table is `ready`. */\n rows: number[][];\n /** Replace the whole table with computed numbers (a generated shape, say). */\n setRows: (next: number[][]) => void;\n /** At least two filled rows, and every cell in them is a number. */\n ready: boolean;\n /** How many cells are typed but are not numbers — what the grid marks invalid. */\n problems: number;\n /** Everything `MeasuredGrid` needs, so a caller spreads it in one line. */\n props: { cells: string[][]; onCells: (next: string[][]) => void };\n}\n\n/**\n * The draft a measured table is edited as.\n *\n * **Strings, not numbers.** A cell is text while it is being typed — `\"-\"`, `\"1.\"` and\n * `\"1e\"` are all states a number passes through on its way to being one, and a grid\n * that parses on every keystroke turns each of them into a `NaN` and then into a `0`.\n * So the draft is text, and the numbers are what falls out when every cell is one.\n *\n * **\"Whole\" is a question this answers**, because every editor asks it before it\n * offers to save: `ready` wants at least two filled rows with a number in every cell.\n * An empty cell is a hole in the measurement, not a zero; a wholly empty row is not a\n * row at all (it is what walking off the bottom of the grid leaves behind).\n *\n * `initial` is read once, like `useState`'s.\n */\nexport function useMeasuredRows(\n initial: number[][] | (() => number[][]),\n options: UseMeasuredRowsOptions = {},\n): MeasuredRows {\n const { digits = 4 } = options;\n const mark = decimalMark(useKitLocale(options.locale));\n const [cells, setCells] = useState<string[][]>(() =>\n (typeof initial === \"function\" ? initial() : initial).map((row) =>\n row.map((value) => formatCell(value, digits, mark)),\n ),\n );\n\n const { rows, ready, problems } = useMemo(() => {\n const filled = cells.filter(hasContent);\n const whole = filled.length >= 2 && filled.every((row) => row.every(isCellNumber));\n return {\n rows: whole ? filled.map((row) => row.map(cellNumber)) : [],\n ready: whole,\n problems: filled.flat().filter((cell) => cell.trim() !== \"\" && !isCellNumber(cell)).length,\n };\n }, [cells]);\n\n const setRows = useCallback(\n (next: number[][]) => setCells(next.map((row) => row.map((value) => formatCell(value, digits, mark)))),\n [digits, mark],\n );\n const props = useMemo(() => ({ cells, onCells: setCells }), [cells]);\n\n return { cells, setCells, rows, setRows, ready, problems, props };\n}\n\nexport interface MeasuredGridProps\n extends Omit<ComponentPropsWithoutRef<\"div\">, \"children\" | \"onChange\"> {\n /** What the table is — shown above it, and the grid's accessible name. */\n label: string;\n /** A note under the table (which columns a layout expects, say). Also the grid's\n * description. */\n hint?: ReactNode;\n columns: MeasuredGridColumn[];\n /** The draft — typically `useMeasuredRows().props`. */\n cells: string[][];\n onCells: (next: string[][]) => void;\n /** Read-only: the cells can still be walked and read, nothing can be changed. */\n disabled?: boolean;\n /** Which views the toggle offers, the first being where it opens. Default both;\n * one view hides the toggle. */\n views?: ReadonlyArray<MeasuredGridView>;\n /** A row's height at Normal text size, in px. Default 28. Since 0.32 it is the\n * windowing's estimate and each row's minimum, multiplied by the text size's scale;\n * the rendered rows are measured (docs/text-size-harmonization.md §10.9). */\n rowHeight?: number;\n /** BCP 47 tag for the decimal mark of cells written by a paste or the text view,\n * and for the row numbers; else the `<UiKitProvider locale>`. */\n locale?: string;\n labels?: Partial<MeasuredGridLabels>;\n}\n\n/**\n * A measured table as a grid of cells, one number each, with a text view beside it.\n *\n * The grid is the primary form because a linkage typed off a drawing arrives as\n * numbers somebody reads out loud, and a textarea made that an exercise in counting\n * tab characters. The paste still works: a block pasted into any cell fills from that\n * cell outwards, growing the table to fit. The text view is kept for what a grid is\n * worst at — reading a thousand-row export back in one piece.\n *\n * **It is a grid in the APG sense**, which the Lenkbank original was not (a `<table>`\n * of inputs, fifteen tab stops per row). One tab stop — the roving tabindex — and the\n * keyboard inside it, as a spreadsheet has it:\n *\n * - **Arrows** move between cells. Left/Right flip under `dir=\"rtl\"`.\n * - **Home/End** go to the first/last column; with Ctrl (or ⌘), to the first/last\n * cell of the table. **PageUp/PageDown** move a screenful.\n * - **Enter** (and ArrowDown) move down a column, and past the last row ADD one —\n * typing down a column is how measured data is entered, and stopping at the last\n * row to reach for a button is what makes people paste instead. Shift+Enter moves up.\n * - **Typing** replaces the cell: arriving by keyboard selects its text, so the first\n * key overwrites it. That is the edit mode data entry wants, entered without a key.\n * **F2** edits in place instead (caret at the end). Either way the cell is then\n * *editing*: Left/Right move the caret, and cross to the next cell only at the edge\n * of the text; Home/End stay in the text. **Escape** puts back what the cell held\n * when the caret arrived, and leaves editing.\n *\n * APG's grid pattern pairs Enter with F2 as the keys that start editing. Enter is\n * spent on \"next row\" here on purpose — it is the one key a person typing a column of\n * numbers presses between every one of them, and every spreadsheet spends it the same\n * way — and typing-to-replace makes an explicit \"start editing\" key unnecessary for\n * the common case. F2 remains for the uncommon one.\n */\nexport function MeasuredGrid({\n label,\n hint,\n columns,\n cells,\n onCells,\n disabled,\n views = ALL_VIEWS,\n rowHeight = DEFAULT_ROW_HEIGHT,\n locale: localeProp,\n labels: labelsProp,\n className,\n ...rest\n}: MeasuredGridProps) {\n const labels = useKitLabels(\"measuredGrid\", DEFAULT_MEASURED_GRID_LABELS, labelsProp);\n const locale = useKitLocale(localeProp);\n const mark = decimalMark(locale);\n const id = useId();\n const labelId = `${id}-label`;\n const hintId = `${id}-hint`;\n const keysId = `${id}-keys`;\n const offered = views.length ? views : ALL_VIEWS;\n const [chosen, setChosen] = useState<MeasuredGridView>(offered[0]);\n const view = offered.includes(chosen) ? chosen : offered[0];\n\n return (\n // `relative` so the keyboard description below can be `sr-only` without escaping\n // to the initial containing block (see sr-only-containment.test).\n <div {...rest} className={cn(\"relative\", className)}>\n <div className=\"mb-1 flex flex-wrap items-center justify-between gap-2\">\n <span id={labelId} className=\"text-caption font-medium text-[var(--text-muted)]\">\n {label}\n </span>\n {offered.length > 1 && (\n <ToggleGroup\n className=\"w-auto\"\n aria-label={labels.view}\n value={view}\n onChange={setChosen}\n options={offered.map((value) => ({\n value,\n label: value === \"cells\" ? labels.cellsView : labels.textView,\n }))}\n />\n )}\n </div>\n {view === \"cells\" ? (\n <CellGrid\n columns={columns}\n cells={cells}\n onCells={onCells}\n disabled={disabled}\n rowHeight={rowHeight}\n locale={locale}\n mark={mark}\n labels={labels}\n labelledBy={labelId}\n describedBy={hint ? `${keysId} ${hintId}` : keysId}\n />\n ) : (\n <TextView\n columns={columns}\n cells={cells}\n onCells={onCells}\n disabled={disabled}\n mark={mark}\n labels={labels}\n labelledBy={labelId}\n describedBy={hint ? hintId : undefined}\n />\n )}\n {hint && (\n <p id={hintId} className=\"mt-1 px-1 text-caption text-[var(--text-muted)]\">\n {hint}\n </p>\n )}\n {view === \"cells\" && (\n <span id={keysId} className=\"sr-only\">\n {labels.keyboardHint}\n </span>\n )}\n </div>\n );\n}\n\n/** Where the caret is. Held in state rather than read off `document`, because a\n * windowed grid unmounts the cell being walked towards: the move is decided first and\n * focused after the row it lands on has been rendered. */\ninterface Caret {\n row: number;\n column: number;\n}\n\ninterface ViewProps {\n columns: MeasuredGridColumn[];\n cells: string[][];\n onCells: (next: string[][]) => void;\n disabled?: boolean;\n mark: \",\" | \".\";\n labels: MeasuredGridLabels;\n labelledBy: string;\n describedBy?: string;\n}\n\nfunction CellGrid({\n columns,\n cells,\n onCells,\n disabled,\n rowHeight,\n locale,\n mark,\n labels,\n labelledBy,\n describedBy,\n}: ViewProps & { rowHeight: number; locale: string | undefined }) {\n const scrollRef = useRef<HTMLDivElement>(null);\n const headRef = useRef<HTMLDivElement>(null);\n const width = columns.length;\n const blankRow = () => columns.map(() => BLANK);\n // At least one row to type into: a grid with nothing in it has nowhere to put the\n // first number, and \"add a row\" is not the first thing to ask of someone who has\n // just opened an empty table. It is not written back until something is typed.\n const grid = cells.length ? cells : [blankRow()];\n const { first, last, totalHeight, offsetOf, heightOf, estimate, measureRef } = useWindowedRows(\n grid.length,\n rowHeight,\n scrollRef,\n );\n const rowNumber = useMemo(() => new Intl.NumberFormat(locale), [locale]);\n\n // The remove buttons are the last column of the grid, reachable by the arrows like\n // any cell — except where they are disabled (a read-only grid, or the placeholder\n // row of an empty one), because a disabled button cannot hold the tab stop.\n const removable = !disabled && cells.length > 0;\n const lastColumn = removable ? width : width - 1;\n\n const [caret, setCaret] = useState<Caret>({ row: 0, column: 0 });\n // Clamped on read, not corrected in an effect: rows removed or columns changed from\n // outside must never leave the tab stop on a cell that is not there.\n const at = { row: Math.min(caret.row, grid.length - 1), column: Math.min(caret.column, lastColumn) };\n /** Whether the caret cell is being edited in place (see the component note). */\n const [editing, setEditing] = useState(false);\n /** A cell that has to take focus once it exists — one commit away when the move\n * crossed the edge of the window. `select` is arrival by keyboard. */\n const pending = useRef<(Caret & { select: boolean }) | null>(null);\n /** What the caret cell held when the caret arrived: what Escape puts back. */\n const origin = useRef(BLANK);\n /** The next focus was a pointer's: place the caret where it was clicked, edit. */\n const pointer = useRef(false);\n\n useEffect(() => {\n const target = pending.current;\n if (!target) return;\n const element = scrollRef.current?.querySelector<HTMLElement>(\n `[data-cell=\"${target.row}:${target.column}\"]`,\n );\n if (!element) return;\n pending.current = null;\n // `preventScroll`: `reveal` already scrolled the row clear of the sticky header,\n // which the browser's own scroll-into-view does not know is there.\n element.focus({ preventScroll: true });\n if (target.select && element instanceof HTMLInputElement) element.select();\n });\n\n const pad = (row: readonly string[] | undefined) =>\n Array.from({ length: width }, (_, index) => row?.[index] ?? BLANK);\n\n const setCell = (row: number, column: number, value: string) => {\n const next = grid.map(pad);\n next[row][column] = value;\n onCells(next);\n };\n\n /** Scroll `row` into the band below the sticky header. */\n const reveal = (row: number) => {\n const element = scrollRef.current;\n if (!element) return;\n const room = element.clientHeight - (headRef.current?.offsetHeight ?? 0);\n if (room <= 0) return;\n // Measured where the row has been rendered, the scaled estimate where not (§10.9).\n const top = offsetOf(row);\n const height = heightOf(row);\n if (top < element.scrollTop) element.scrollTop = top;\n else if (top + height > element.scrollTop + room) element.scrollTop = top + height - room;\n };\n\n const focusCell = (row: number, column: number) => {\n reveal(row);\n pending.current = { row, column, select: true };\n setCaret({ row, column });\n setEditing(false);\n };\n\n const go = (row: number, column: number) => {\n const target = {\n row: Math.max(0, Math.min(row, grid.length - 1)),\n column: Math.max(0, Math.min(column, lastColumn)),\n };\n if (target.row === at.row && target.column === at.column) return;\n focusCell(target.row, target.column);\n };\n\n /** Down a column — and off the bottom, a new row, unless the last one is still\n * empty: holding ArrowDown should not leave a trail of blank rows behind it. */\n const down = (row: number, column: number) => {\n if (row + 1 < grid.length) return go(row + 1, column);\n if (disabled || !hasContent(grid[row])) return;\n onCells([...grid.map(pad), blankRow()]);\n focusCell(row + 1, Math.min(column, width - 1));\n };\n\n const page = () => {\n const element = scrollRef.current;\n const room = element ? element.clientHeight - (headRef.current?.offsetHeight ?? 0) : 0;\n // No layout (a hidden pane, jsdom): a fixed ten rather than one row at a time.\n return room > 0 ? Math.max(1, Math.floor(room / estimate) - 1) : 10;\n };\n\n /**\n * On each cell rather than once on the grid, for the reason `MiniCalendar` gives:\n * the cell is where focus is, and a container listening for keys it cannot receive\n * is the shape `jsx-a11y/interactive-supports-focus` objects to.\n */\n const onCellKeyDown = (event: KeyboardEvent<HTMLElement>, row: number, column: number) => {\n const input = event.currentTarget instanceof HTMLInputElement ? event.currentTarget : null;\n const inText = Boolean(input) && editing;\n const modified = event.ctrlKey || event.metaKey;\n switch (event.key) {\n case \"ArrowUp\":\n event.preventDefault();\n return go(row - 1, column);\n case \"ArrowDown\":\n event.preventDefault();\n return down(row, column);\n case \"Enter\":\n // On the remove button Enter is the button's own.\n if (!input) return;\n event.preventDefault();\n return event.shiftKey ? go(row - 1, column) : down(row, column);\n case \"ArrowLeft\":\n case \"ArrowRight\": {\n // Along the reading direction: ArrowLeft is \"next column\" in RTL.\n const forward = horizontalStep(event.key, event.currentTarget) === 1;\n if (inText && input) {\n const edge = forward ? input.value.length : 0;\n // Inside the text the caret moves; only at its edge does it leave the cell.\n if (input.selectionStart !== edge || input.selectionEnd !== edge) return;\n }\n event.preventDefault();\n return go(row, column + (forward ? 1 : -1));\n }\n case \"Home\":\n case \"End\": {\n if (inText && !modified) return;\n event.preventDefault();\n const home = event.key === \"Home\";\n if (modified) return go(home ? 0 : grid.length - 1, home ? 0 : width - 1);\n return go(row, home ? 0 : width - 1);\n }\n case \"PageUp\":\n event.preventDefault();\n return go(row - page(), column);\n case \"PageDown\":\n event.preventDefault();\n return go(row + page(), column);\n case \"F2\":\n if (!input || disabled) return;\n event.preventDefault();\n setEditing(true);\n input.setSelectionRange(input.value.length, input.value.length);\n return;\n case \"Escape\":\n // Not editing: nothing of ours to undo, so the key belongs to whatever the\n // grid sits in — the dialog it is in closes, as it should.\n if (!input || !editing) return;\n event.preventDefault();\n event.stopPropagation();\n if (input.value !== origin.current) setCell(row, column, origin.current);\n pending.current = { row, column, select: true };\n setEditing(false);\n return;\n }\n };\n\n /**\n * A pasted block, written in from the cell it was pasted into.\n *\n * Rows past the end grow the table; columns past the last are dropped, because a\n * paste wider than the measurement is a paste with a trailing timestamp column and\n * not an error worth refusing. One header line is skipped — pasted data almost\n * always has one. Each line is read on its own evidence (`splitRow`, the per-line\n * comma rule), so one line cannot change what another means.\n */\n const paste = (row: number, column: number, text: string) => {\n const lines = text.split(/\\r?\\n/).filter((line) => line.trim() !== \"\");\n if (!lines.length) return;\n const block = lines.map(splitRow);\n if (block.length > 1 && block[0].some((cell) => !isCellNumber(cell))) block.shift();\n\n const height = Math.max(grid.length, row + block.length);\n const next = Array.from({ length: height }, (_, index) => pad(grid[index]));\n block.forEach((line, downwards) => {\n line.forEach((cell, across) => {\n const target = column + across;\n if (target < width) next[row + downwards][target] = withMark(cell.trim(), mark);\n });\n });\n onCells(next);\n pending.current = { row, column, select: true };\n setEditing(false);\n };\n\n const template = `2.5rem repeat(${width}, minmax(5.5rem, 1fr)) 2rem`;\n // The caret's row is mounted even when it has been scrolled out of the window: it\n // holds the grid's only tab stop, and a tab stop that is not in the DOM is a grid\n // Tab walks straight past.\n const mounted: number[] = [];\n for (let index = first; index < last; index += 1) mounted.push(index);\n if (at.row < first || at.row >= last) mounted.push(at.row);\n\n const filled = cells.filter(hasContent);\n const problems = filled.flat().filter((cell) => cell.trim() !== \"\" && !isCellNumber(cell)).length;\n\n return (\n <div className=\"rounded-md border border-[var(--border)] bg-[var(--bg-surface)]\">\n <div ref={scrollRef} className=\"max-h-72 overflow-auto\">\n <div\n role=\"grid\"\n aria-labelledby={labelledBy}\n aria-describedby={describedBy}\n // The true size, not the mounted one: a screen reader otherwise reports the\n // thirty rows in the window as the whole table.\n aria-rowcount={grid.length + 1}\n aria-colcount={width + 2}\n aria-readonly={disabled || undefined}\n className=\"text-xs\"\n style={{ minWidth: `calc(4.5rem + ${width} * 5.5rem)` }}\n >\n {/* The header stays put vertically and scrolls sideways with the body, so a\n fifteen-column linkage can be read without losing which column is which. */}\n <div ref={headRef} role=\"rowgroup\" className=\"sticky top-0 z-10 bg-[var(--bg-surface-2)]\">\n <div\n role=\"row\"\n aria-rowindex={1}\n className=\"grid border-b border-[var(--border)]\"\n style={{ gridTemplateColumns: template }}\n >\n <div\n role=\"columnheader\"\n aria-label={labels.rowNumber}\n className=\"flex items-end justify-end px-1 py-1 text-micro text-[var(--text-placeholder)]\"\n >\n #\n </div>\n {columns.map((column, index) => (\n <div\n key={index}\n role=\"columnheader\"\n className=\"min-w-0 border-s border-[var(--border)] px-2 py-1 text-end\"\n >\n <span className=\"block truncate font-medium text-[var(--text-primary)]\">\n {column.label}\n </span>\n {column.unit && (\n <span className=\"block truncate text-micro text-[var(--text-muted)]\">\n {column.unit}\n </span>\n )}\n </div>\n ))}\n <div\n role=\"columnheader\"\n aria-label={labels.rowActions}\n className=\"border-s border-[var(--border)]\"\n />\n </div>\n </div>\n {/* Only the rows in the window are mounted — a swept linkage is thousands of\n them across fifteen inputs — each placed at its own offset, so mounting\n one more (the caret's) costs nothing in the arithmetic. Since 0.32 a row\n is at least the scaled estimate tall and measured as it renders (§10.9):\n `minHeight`, not `height`, so the type at Extra large is never cut. */}\n <div role=\"rowgroup\" className=\"relative\" style={{ height: totalHeight }}>\n {mounted.map((index) => {\n const row = grid[index];\n return (\n <div\n key={index}\n ref={measureRef}\n {...{ [WINDOWED_ROW_INDEX]: index }}\n role=\"row\"\n aria-rowindex={index + 2}\n className=\"absolute inset-x-0 grid hover:bg-[var(--bg-hover)]\"\n style={{ top: offsetOf(index), minHeight: estimate, gridTemplateColumns: template }}\n >\n <div\n role=\"rowheader\"\n className=\"flex items-center justify-end px-1 text-micro tabular-nums text-[var(--text-placeholder)]\"\n >\n {rowNumber.format(index + 1)}\n </div>\n {columns.map((column, columnIndex) => {\n const value = row[columnIndex] ?? BLANK;\n const bad = value.trim() !== \"\" && !isCellNumber(value);\n const isCaret = at.row === index && at.column === columnIndex;\n return (\n <div key={columnIndex} role=\"gridcell\" className=\"min-w-0 border-s border-[var(--border)]\">\n <input\n data-cell={`${index}:${columnIndex}`}\n value={value}\n // `readOnly`, not `disabled`: a disabled input cannot take\n // focus, and a read-only table should still be walkable.\n readOnly={disabled}\n tabIndex={isCaret ? 0 : -1}\n inputMode=\"decimal\"\n spellCheck={false}\n autoComplete=\"off\"\n aria-label={labels.cell(column.label, index + 1)}\n // Said, not only painted: the ring is what a sighted user\n // sees, `aria-invalid` is what a screen reader reads.\n aria-invalid={bad || undefined}\n className={cn(\n \"block size-full bg-transparent px-2 text-end tabular-nums text-[var(--text-primary)] outline-none\",\n // A cell is a field: 16 px on touch, or iOS zooms on focus (§10.1).\n FIELD_TOUCH_TEXT,\n // Arriving selects the text (typing replaces it); editing\n // in place is the plain surface with a caret in it.\n // The kit's focus frame (§5), inset so the next cell's\n // border does not paint over it. A text input is\n // `:focus-visible` however it was focused.\n \"focus:bg-[var(--brand-bg)]\",\n FOCUS_RING,\n \"focus-visible:ring-inset\",\n isCaret && editing && \"focus:bg-[var(--bg-surface)]\",\n disabled && \"text-[var(--text-muted)]\",\n bad && cn(FIELD_INVALID, \"ring-inset\"),\n )}\n onMouseDown={(event) => {\n // A click places a caret, which is editing. On the cell\n // already focused there is no focus event to say so.\n if (document.activeElement === event.currentTarget) setEditing(!disabled);\n else pointer.current = true;\n }}\n onFocus={(event) => {\n origin.current = event.currentTarget.value;\n if (!isCaret) setCaret({ row: index, column: columnIndex });\n const byPointer = pointer.current;\n pointer.current = false;\n setEditing(byPointer && !disabled);\n if (!byPointer) event.currentTarget.select();\n }}\n onBlur={() => setEditing(false)}\n onChange={(event) => {\n setCell(index, columnIndex, event.target.value);\n setEditing(true);\n }}\n onPaste={(event) => {\n if (disabled) return;\n const text = event.clipboardData.getData(\"text/plain\");\n // One cell's worth of text is an ordinary paste, and the\n // browser does it better than this would; only a block is\n // the grid's business.\n if (!/[\\t\\n;]/.test(text)) return;\n event.preventDefault();\n paste(index, columnIndex, text);\n }}\n onKeyDown={(event) => onCellKeyDown(event, index, columnIndex)}\n />\n </div>\n );\n })}\n <div\n role=\"gridcell\"\n className=\"flex items-center justify-center border-s border-[var(--border)]\"\n >\n <button\n type=\"button\"\n data-cell={`${index}:${width}`}\n disabled={!removable}\n tabIndex={at.row === index && at.column === width ? 0 : -1}\n aria-label={labels.removeRow(index + 1)}\n className={cn(\n \"rounded p-1 text-[var(--text-placeholder)] outline-none hover:text-[var(--danger)] disabled:cursor-default disabled:hover:text-[var(--text-placeholder)]\",\n FOCUS_RING,\n )}\n onKeyDown={(event) => onCellKeyDown(event, index, width)}\n onFocus={() => {\n if (at.row !== index || at.column !== width) setCaret({ row: index, column: width });\n }}\n onClick={() => {\n const next = grid.filter((_, other) => other !== index);\n onCells(next);\n // Focus stays in the column, on the row that moved up into\n // this one; an emptied table sends it to the first cell.\n if (next.length) focusCell(Math.min(index, next.length - 1), width);\n else focusCell(0, 0);\n }}\n >\n <Trash2 aria-hidden className=\"size-3.5\" />\n </button>\n </div>\n </div>\n );\n })}\n </div>\n </div>\n </div>\n <div className=\"flex flex-wrap items-center gap-x-2 gap-y-1 border-t border-[var(--border)] px-2 py-1.5\">\n <Button\n variant=\"ghost\"\n size=\"sm\"\n disabled={disabled}\n onClick={() => {\n onCells([...grid.map(pad), blankRow()]);\n focusCell(grid.length, 0);\n }}\n >\n <Plus aria-hidden className=\"size-3.5\" /> {labels.addRow}\n </Button>\n <Button\n variant=\"ghost\"\n size=\"sm\"\n className=\"text-[var(--text-muted)]\"\n disabled={disabled || !cells.length}\n onClick={() => {\n onCells([]);\n // The button is about to disable itself; focus must not go down with it.\n focusCell(0, 0);\n }}\n >\n <Eraser aria-hidden className=\"size-3.5\" /> {labels.clear}\n </Button>\n <span className=\"text-caption tabular-nums text-[var(--text-muted)]\">\n {/* bdi: an LTR label (\"3 points\") in an RTL grid would reorder to \"points 3\". */}\n <bdi>{labels.points(filled.length)}</bdi>\n </span>\n {problems > 0 && (\n <span className=\"text-caption text-[var(--danger)]\">{labels.problems(problems)}</span>\n )}\n <span className=\"ms-auto flex items-center gap-1 text-caption text-[var(--text-muted)]\">\n <ClipboardPaste aria-hidden className=\"size-3.5\" /> {labels.pasteHint}\n </span>\n </div>\n </div>\n );\n}\n\nconst textOf = (cells: string[][]) => cells.map((row) => row.join(\"\\t\")).join(\"\\n\");\n\n/**\n * The same table as text.\n *\n * Kept because the grid is worst at exactly what a textarea is best at: reading a long\n * export back in one piece. It commits on blur — through `parseRows`, the paste door —\n * and a line it cannot read is NAMED rather than dropped: half a sweep saved as a\n * measurement is worse than a refusal.\n */\nfunction TextView({ columns, cells, onCells, disabled, mark, labels, labelledBy, describedBy }: ViewProps) {\n const text = textOf(cells);\n const [draft, setDraft] = useState(text);\n const [errorLine, setErrorLine] = useState<number | null>(null);\n // Follow the table when it changes from outside (a generated shape, a cleared form).\n // Compared as text, so a caller that rebuilds the same cells every render does not\n // wipe what is being typed.\n const [seen, setSeen] = useState(text);\n if (seen !== text) {\n setSeen(text);\n setDraft(text);\n setErrorLine(null);\n }\n\n const commit = () => {\n // Untouched: nothing to read back, and re-reading would rewrite every cell in the\n // lexer's spelling of it.\n if (draft === text) return;\n if (!draft.trim()) {\n setErrorLine(null);\n onCells([]);\n return;\n }\n const parsed = parseRows(draft, columns.length);\n if (\"error\" in parsed) {\n setErrorLine(parsed.error);\n return;\n }\n setErrorLine(null);\n onCells(parsed.rows.map((row) => row.map((value) => withMark(String(value), mark))));\n };\n\n const lines = draft.split(\"\\n\").filter((line) => line.trim()).length;\n\n return (\n <div>\n <Textarea\n aria-labelledby={labelledBy}\n aria-describedby={describedBy}\n rows={10}\n value={draft}\n readOnly={disabled}\n spellCheck={false}\n className=\"font-mono text-xs\"\n error={errorLine !== null ? labels.lineError(errorLine) : undefined}\n onChange={(event) => setDraft(event.target.value)}\n onBlur={commit}\n />\n <p className=\"mt-1 px-1 text-caption text-[var(--text-muted)]\">\n {columns.map((column) => column.label).join(\" · \")}\n {\" — \"}\n <bdi>{labels.points(lines)}</bdi>\n </p>\n </div>\n );\n}\n"],"mappings":"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","names":[]}
|
|
1
|
+
{"version":3,"sources":["../../src/components/measured-grid.tsx"],"sourcesContent":["import { useCallback, useEffect, useId, useMemo, useRef, useState } from \"react\";\nimport type { ComponentPropsWithRef, KeyboardEvent, ReactNode } from \"react\";\nimport { ClipboardPaste, Eraser, Plus, Trash2 } from \"lucide-react\";\nimport { cn } from \"../lib/cn\";\nimport { horizontalStep } from \"../lib/direction\";\n// The locale's mark as far as a cell can hold it — the fields' answer, the same reason\n// (DUP-11, refactor audit 2026-10: a verbatim copy lived here).\nimport { decimalMark } from \"../lib/decimal-marks\";\n// The cell pair reads ONE cell, where a comma has no columns to separate and so is\n// always a decimal mark; `splitRow` and `parseRows` read a pasted table, where it may\n// be either and the line decides. See the three named rules at the top of table-text.\nimport { cellNumber, isCellNumber, parseRows, splitRow } from \"../lib/table-text\";\nimport { useKitLabels, useKitLocale, type LabelOverride } from \"../i18n/kit-labels\";\nimport { useWindowedRows, WINDOWED_ROW_INDEX } from \"../hooks/use-windowed-rows\";\nimport { ToggleGroup } from \"./toggle-group\";\nimport { Button } from \"./button\";\nimport { FIELD_INVALID, FIELD_TOUCH_TEXT } from \"./field-base\";\nimport { FOCUS_RING } from \"./focus-ring\";\nimport { Textarea } from \"./textarea\";\nimport { DEFAULT_MEASURED_GRID_LABELS } from \"./measured-grid-labels\";\n\n/**\n * A measured table: a fixed set of numeric columns, typed cell by cell or pasted as a\n * block out of a spreadsheet — and the hook that holds it as a draft.\n *\n * Moved from Lenkbank (`shared/ui/measured-grid.tsx`), where four gear editors and a\n * setpoint dialog type rig measurements into it. Nothing in it knows what a column\n * holds: the caller passes `{ label, unit }[]`, and the vocabulary of this file is\n * cells, rows, a caret and a paste. The lexing under it is `@eifi1/ui-kit/table-text`.\n *\n * What it is NOT: a `DataTable` mode (that one finds rows among many; this one types\n * numbers into columns), a spreadsheet (no formulas, no multi-cell selection, no undo\n * beyond the browser's per-input one), or typed columns — every cell is a string that\n * should read as a number.\n */\n\n/**\n * Every string the grid can speak — the `measuredGrid` namespace of\n * `<UiKitProvider labels>`, overridable per instance through the `labels` prop. The\n * ones that carry a number are functions of it, for the reason `DataTableLabels` gives:\n * the grammar around a count moves with it in most languages.\n */\nexport interface MeasuredGridLabels {\n /** Accessible name of the cells/text toggle. */\n view: string;\n cellsView: string;\n textView: string;\n addRow: string;\n /** The row's remove button, given its 1-based number. */\n removeRow: (row: number) => string;\n /** Empties the whole table. */\n clear: string;\n /** The footer's standing note that a block can be pasted into any cell. */\n pasteHint: string;\n /**\n * Accessible name of one cell's input, given its column's label and 1-based row.\n * A screen reader in a grid announces the headers on its own when the caret crosses\n * one; this is what it reads when the caret lands on an input with no crossing — and\n * what a voice-control user says to reach it.\n */\n cell: (column: string, row: number) => string;\n /** The row-number column's header, which shows only \"#\". */\n rowNumber: string;\n /** The remove-button column's header, which shows nothing. */\n rowActions: string;\n /** The grid's description: how its keyboard works. Read once, on entry. */\n keyboardHint: string;\n /** The text view could not read this 1-based line of what was typed or pasted. */\n lineError: (line: number) => string;\n /** How many filled rows (measured points) the table holds. */\n points: (count: number) => string;\n /** How many cells are typed but are not numbers. */\n problems: (count: number) => string;\n}\n\n// Defined in ./measured-grid-labels, which holds no component code (0.34, KS U8).\nexport { DEFAULT_MEASURED_GRID_LABELS };\n\n/** One column of a measured table: what it holds and what it is measured in. The unit\n * is separate from the name because the header shows it small and underneath, and\n * because a column with no unit (a count, an index) should not render empty brackets. */\nexport interface MeasuredGridColumn {\n label: string;\n unit?: string;\n}\n\n/** The two ways to look at the same table. */\nexport type MeasuredGridView = \"cells\" | \"text\";\n\n/** A cell that has not been typed into yet. Distinguished from `\"0\"` on purpose: an\n * empty cell is a hole in the measurement, and a table with a hole is not one to save. */\nconst BLANK = \"\";\n\n/** Height of one grid row at Normal text size, in px — the windowing's ESTIMATE since\n * 0.32 (docs/text-size-harmonization.md §10.9): `useWindowedRows` multiplies it by the\n * text size's scale (35 px at Large, 42 at Extra large) and then measures the rows it\n * renders, so a row is never cut to a height the type has outgrown. */\nconst DEFAULT_ROW_HEIGHT = 28;\n\nconst ALL_VIEWS: readonly MeasuredGridView[] = [\"cells\", \"text\"];\n\n/** A number-shaped cell written with the locale's mark. The lexer hands back points;\n * a German user typed commas and should read commas back. Anything that is not a\n * number is left exactly as it was, so the mistake stays visible where it was made. */\nconst withMark = (cell: string, mark: \",\" | \".\") =>\n mark === \",\" && isCellNumber(cell) ? cell.replace(\".\", \",\") : cell;\n\n/** A computed number as a draft cell: rounded to `digits`, with no trailing zeros. */\nconst formatCell = (value: number, digits: number, mark: \",\" | \".\") =>\n withMark(String(Number(value.toFixed(digits))), mark);\n\nconst hasContent = (row: readonly string[]) => row.some((cell) => cell.trim() !== \"\");\n\nexport interface UseMeasuredRowsOptions {\n /** Decimals a computed number is rounded to on its way into a cell. Default 4. */\n digits?: number;\n /** BCP 47 tag whose decimal mark the cells are written with, else the\n * `<UiKitProvider locale>`, else the runtime's. */\n locale?: string;\n}\n\nexport interface MeasuredRows {\n /** The draft, as text — what the grid shows and edits. */\n cells: string[][];\n setCells: (next: string[][]) => void;\n /** The filled rows as numbers — EMPTY until the table is `ready`. */\n rows: number[][];\n /** Replace the whole table with computed numbers (a generated shape, say). */\n setRows: (next: number[][]) => void;\n /** At least two filled rows, and every cell in them is a number. */\n ready: boolean;\n /** How many cells are typed but are not numbers — what the grid marks invalid. */\n problems: number;\n /** Everything `MeasuredGrid` needs, so a caller spreads it in one line. */\n props: { cells: string[][]; onCells: (next: string[][]) => void };\n}\n\n/**\n * The draft a measured table is edited as.\n *\n * **Strings, not numbers.** A cell is text while it is being typed — `\"-\"`, `\"1.\"` and\n * `\"1e\"` are all states a number passes through on its way to being one, and a grid\n * that parses on every keystroke turns each of them into a `NaN` and then into a `0`.\n * So the draft is text, and the numbers are what falls out when every cell is one.\n *\n * **\"Whole\" is a question this answers**, because every editor asks it before it\n * offers to save: `ready` wants at least two filled rows with a number in every cell.\n * An empty cell is a hole in the measurement, not a zero; a wholly empty row is not a\n * row at all (it is what walking off the bottom of the grid leaves behind).\n *\n * `initial` is read once, like `useState`'s.\n */\nexport function useMeasuredRows(\n initial: number[][] | (() => number[][]),\n options: UseMeasuredRowsOptions = {},\n): MeasuredRows {\n const { digits = 4 } = options;\n const mark = decimalMark(useKitLocale(options.locale));\n const [cells, setCells] = useState<string[][]>(() =>\n (typeof initial === \"function\" ? initial() : initial).map((row) =>\n row.map((value) => formatCell(value, digits, mark)),\n ),\n );\n\n const { rows, ready, problems } = useMemo(() => {\n const filled = cells.filter(hasContent);\n const whole = filled.length >= 2 && filled.every((row) => row.every(isCellNumber));\n return {\n rows: whole ? filled.map((row) => row.map(cellNumber)) : [],\n ready: whole,\n problems: filled.flat().filter((cell) => cell.trim() !== \"\" && !isCellNumber(cell)).length,\n };\n }, [cells]);\n\n const setRows = useCallback(\n (next: number[][]) => setCells(next.map((row) => row.map((value) => formatCell(value, digits, mark)))),\n [digits, mark],\n );\n const props = useMemo(() => ({ cells, onCells: setCells }), [cells]);\n\n return { cells, setCells, rows, setRows, ready, problems, props };\n}\n\nexport interface MeasuredGridProps\n extends Omit<ComponentPropsWithRef<\"div\">, \"children\" | \"onChange\"> {\n /** What the table is — shown above it, and the grid's accessible name. */\n label: string;\n /** A note under the table (which columns a layout expects, say). Also the grid's\n * description. */\n hint?: ReactNode;\n columns: MeasuredGridColumn[];\n /** The draft — typically `useMeasuredRows().props`. */\n cells: string[][];\n onCells: (next: string[][]) => void;\n /** Read-only: the cells can still be walked and read, nothing can be changed. */\n disabled?: boolean;\n /** Which views the toggle offers, the first being where it opens. Default both;\n * one view hides the toggle. */\n views?: ReadonlyArray<MeasuredGridView>;\n /** A row's height at Normal text size, in px. Default 28. Since 0.32 it is the\n * windowing's estimate and each row's minimum, multiplied by the text size's scale;\n * the rendered rows are measured (docs/text-size-harmonization.md §10.9). */\n rowHeight?: number;\n /** BCP 47 tag for the decimal mark of cells written by a paste or the text view,\n * and for the row numbers; else the `<UiKitProvider locale>`. */\n locale?: string;\n labels?: LabelOverride<MeasuredGridLabels>;\n}\n\n/**\n * A measured table as a grid of cells, one number each, with a text view beside it.\n *\n * The grid is the primary form because a linkage typed off a drawing arrives as\n * numbers somebody reads out loud, and a textarea made that an exercise in counting\n * tab characters. The paste still works: a block pasted into any cell fills from that\n * cell outwards, growing the table to fit. The text view is kept for what a grid is\n * worst at — reading a thousand-row export back in one piece.\n *\n * **It is a grid in the APG sense**, which the Lenkbank original was not (a `<table>`\n * of inputs, fifteen tab stops per row). One tab stop — the roving tabindex — and the\n * keyboard inside it, as a spreadsheet has it:\n *\n * - **Arrows** move between cells. Left/Right flip under `dir=\"rtl\"`.\n * - **Home/End** go to the first/last column; with Ctrl (or ⌘), to the first/last\n * cell of the table. **PageUp/PageDown** move a screenful.\n * - **Enter** (and ArrowDown) move down a column, and past the last row ADD one —\n * typing down a column is how measured data is entered, and stopping at the last\n * row to reach for a button is what makes people paste instead. Shift+Enter moves up.\n * - **Typing** replaces the cell: arriving by keyboard selects its text, so the first\n * key overwrites it. That is the edit mode data entry wants, entered without a key.\n * **F2** edits in place instead (caret at the end). Either way the cell is then\n * *editing*: Left/Right move the caret, and cross to the next cell only at the edge\n * of the text; Home/End stay in the text. **Escape** puts back what the cell held\n * when the caret arrived, and leaves editing.\n *\n * APG's grid pattern pairs Enter with F2 as the keys that start editing. Enter is\n * spent on \"next row\" here on purpose — it is the one key a person typing a column of\n * numbers presses between every one of them, and every spreadsheet spends it the same\n * way — and typing-to-replace makes an explicit \"start editing\" key unnecessary for\n * the common case. F2 remains for the uncommon one.\n */\nexport function MeasuredGrid({\n label,\n hint,\n columns,\n cells,\n onCells,\n disabled,\n views = ALL_VIEWS,\n rowHeight = DEFAULT_ROW_HEIGHT,\n locale: localeProp,\n labels: labelsProp,\n className,\n ...rest\n}: MeasuredGridProps) {\n const labels = useKitLabels(\"measuredGrid\", DEFAULT_MEASURED_GRID_LABELS, labelsProp);\n const locale = useKitLocale(localeProp);\n const mark = decimalMark(locale);\n const id = useId();\n const labelId = `${id}-label`;\n const hintId = `${id}-hint`;\n const keysId = `${id}-keys`;\n const offered = views.length ? views : ALL_VIEWS;\n const [chosen, setChosen] = useState<MeasuredGridView>(offered[0]);\n const view = offered.includes(chosen) ? chosen : offered[0];\n\n return (\n // `relative` so the keyboard description below can be `sr-only` without escaping\n // to the initial containing block (see sr-only-containment.test).\n <div {...rest} className={cn(\"relative\", className)}>\n <div className=\"mb-1 flex flex-wrap items-center justify-between gap-2\">\n <span id={labelId} className=\"text-caption font-medium text-muted\">\n {label}\n </span>\n {offered.length > 1 && (\n <ToggleGroup\n className=\"w-auto\"\n aria-label={labels.view}\n value={view}\n onChange={setChosen}\n options={offered.map((value) => ({\n value,\n label: value === \"cells\" ? labels.cellsView : labels.textView,\n }))}\n />\n )}\n </div>\n {view === \"cells\" ? (\n <CellGrid\n columns={columns}\n cells={cells}\n onCells={onCells}\n disabled={disabled}\n rowHeight={rowHeight}\n locale={locale}\n mark={mark}\n labels={labels}\n labelledBy={labelId}\n describedBy={hint ? `${keysId} ${hintId}` : keysId}\n />\n ) : (\n <TextView\n columns={columns}\n cells={cells}\n onCells={onCells}\n disabled={disabled}\n mark={mark}\n labels={labels}\n labelledBy={labelId}\n describedBy={hint ? hintId : undefined}\n />\n )}\n {hint && (\n <p id={hintId} className=\"mt-1 px-1 text-caption text-muted\">\n {hint}\n </p>\n )}\n {view === \"cells\" && (\n <span id={keysId} className=\"sr-only\">\n {labels.keyboardHint}\n </span>\n )}\n </div>\n );\n}\n\n/** Where the caret is. Held in state rather than read off `document`, because a\n * windowed grid unmounts the cell being walked towards: the move is decided first and\n * focused after the row it lands on has been rendered. */\ninterface Caret {\n row: number;\n column: number;\n}\n\ninterface ViewProps {\n columns: MeasuredGridColumn[];\n cells: string[][];\n onCells: (next: string[][]) => void;\n disabled?: boolean;\n mark: \",\" | \".\";\n labels: MeasuredGridLabels;\n labelledBy: string;\n describedBy?: string;\n}\n\nfunction CellGrid({\n columns,\n cells,\n onCells,\n disabled,\n rowHeight,\n locale,\n mark,\n labels,\n labelledBy,\n describedBy,\n}: ViewProps & { rowHeight: number; locale: string | undefined }) {\n const scrollRef = useRef<HTMLDivElement>(null);\n const headRef = useRef<HTMLDivElement>(null);\n const width = columns.length;\n const blankRow = () => columns.map(() => BLANK);\n // At least one row to type into: a grid with nothing in it has nowhere to put the\n // first number, and \"add a row\" is not the first thing to ask of someone who has\n // just opened an empty table. It is not written back until something is typed.\n const grid = cells.length ? cells : [blankRow()];\n const { first, last, totalHeight, offsetOf, heightOf, estimate, measureRef } = useWindowedRows(\n grid.length,\n rowHeight,\n scrollRef,\n );\n const rowNumber = useMemo(() => new Intl.NumberFormat(locale), [locale]);\n\n // The remove buttons are the last column of the grid, reachable by the arrows like\n // any cell — except where they are disabled (a read-only grid, or the placeholder\n // row of an empty one), because a disabled button cannot hold the tab stop.\n const removable = !disabled && cells.length > 0;\n const lastColumn = removable ? width : width - 1;\n\n const [caret, setCaret] = useState<Caret>({ row: 0, column: 0 });\n // Clamped on read, not corrected in an effect: rows removed or columns changed from\n // outside must never leave the tab stop on a cell that is not there.\n const at = { row: Math.min(caret.row, grid.length - 1), column: Math.min(caret.column, lastColumn) };\n /** Whether the caret cell is being edited in place (see the component note). */\n const [editing, setEditing] = useState(false);\n /** A cell that has to take focus once it exists — one commit away when the move\n * crossed the edge of the window. `select` is arrival by keyboard. */\n const pending = useRef<(Caret & { select: boolean }) | null>(null);\n /** What the caret cell held when the caret arrived: what Escape puts back. */\n const origin = useRef(BLANK);\n /** The next focus was a pointer's: place the caret where it was clicked, edit. */\n const pointer = useRef(false);\n\n useEffect(() => {\n const target = pending.current;\n if (!target) return;\n const element = scrollRef.current?.querySelector<HTMLElement>(\n `[data-cell=\"${target.row}:${target.column}\"]`,\n );\n if (!element) return;\n pending.current = null;\n // `preventScroll`: `reveal` already scrolled the row clear of the sticky header,\n // which the browser's own scroll-into-view does not know is there.\n element.focus({ preventScroll: true });\n if (target.select && element instanceof HTMLInputElement) element.select();\n });\n\n const pad = (row: readonly string[] | undefined) =>\n Array.from({ length: width }, (_, index) => row?.[index] ?? BLANK);\n\n const setCell = (row: number, column: number, value: string) => {\n const next = grid.map(pad);\n next[row][column] = value;\n onCells(next);\n };\n\n /** Scroll `row` into the band below the sticky header. */\n const reveal = (row: number) => {\n const element = scrollRef.current;\n if (!element) return;\n const room = element.clientHeight - (headRef.current?.offsetHeight ?? 0);\n if (room <= 0) return;\n // Measured where the row has been rendered, the scaled estimate where not (§10.9).\n const top = offsetOf(row);\n const height = heightOf(row);\n if (top < element.scrollTop) element.scrollTop = top;\n else if (top + height > element.scrollTop + room) element.scrollTop = top + height - room;\n };\n\n const focusCell = (row: number, column: number) => {\n reveal(row);\n pending.current = { row, column, select: true };\n setCaret({ row, column });\n setEditing(false);\n };\n\n const go = (row: number, column: number) => {\n const target = {\n row: Math.max(0, Math.min(row, grid.length - 1)),\n column: Math.max(0, Math.min(column, lastColumn)),\n };\n if (target.row === at.row && target.column === at.column) return;\n focusCell(target.row, target.column);\n };\n\n /** Down a column — and off the bottom, a new row, unless the last one is still\n * empty: holding ArrowDown should not leave a trail of blank rows behind it. */\n const down = (row: number, column: number) => {\n if (row + 1 < grid.length) return go(row + 1, column);\n if (disabled || !hasContent(grid[row])) return;\n onCells([...grid.map(pad), blankRow()]);\n focusCell(row + 1, Math.min(column, width - 1));\n };\n\n const page = () => {\n const element = scrollRef.current;\n const room = element ? element.clientHeight - (headRef.current?.offsetHeight ?? 0) : 0;\n // No layout (a hidden pane, jsdom): a fixed ten rather than one row at a time.\n return room > 0 ? Math.max(1, Math.floor(room / estimate) - 1) : 10;\n };\n\n /**\n * On each cell rather than once on the grid, for the reason `MiniCalendar` gives:\n * the cell is where focus is, and a container listening for keys it cannot receive\n * is the shape `jsx-a11y/interactive-supports-focus` objects to.\n */\n const onCellKeyDown = (event: KeyboardEvent<HTMLElement>, row: number, column: number) => {\n const input = event.currentTarget instanceof HTMLInputElement ? event.currentTarget : null;\n const inText = Boolean(input) && editing;\n const modified = event.ctrlKey || event.metaKey;\n switch (event.key) {\n case \"ArrowUp\":\n event.preventDefault();\n return go(row - 1, column);\n case \"ArrowDown\":\n event.preventDefault();\n return down(row, column);\n case \"Enter\":\n // On the remove button Enter is the button's own.\n if (!input) return;\n event.preventDefault();\n return event.shiftKey ? go(row - 1, column) : down(row, column);\n case \"ArrowLeft\":\n case \"ArrowRight\": {\n // Along the reading direction: ArrowLeft is \"next column\" in RTL.\n const forward = horizontalStep(event.key, event.currentTarget) === 1;\n if (inText && input) {\n const edge = forward ? input.value.length : 0;\n // Inside the text the caret moves; only at its edge does it leave the cell.\n if (input.selectionStart !== edge || input.selectionEnd !== edge) return;\n }\n event.preventDefault();\n return go(row, column + (forward ? 1 : -1));\n }\n case \"Home\":\n case \"End\": {\n if (inText && !modified) return;\n event.preventDefault();\n const home = event.key === \"Home\";\n if (modified) return go(home ? 0 : grid.length - 1, home ? 0 : width - 1);\n return go(row, home ? 0 : width - 1);\n }\n case \"PageUp\":\n event.preventDefault();\n return go(row - page(), column);\n case \"PageDown\":\n event.preventDefault();\n return go(row + page(), column);\n case \"F2\":\n if (!input || disabled) return;\n event.preventDefault();\n setEditing(true);\n input.setSelectionRange(input.value.length, input.value.length);\n return;\n case \"Escape\":\n // Not editing: nothing of ours to undo, so the key belongs to whatever the\n // grid sits in — the dialog it is in closes, as it should.\n if (!input || !editing) return;\n event.preventDefault();\n event.stopPropagation();\n if (input.value !== origin.current) setCell(row, column, origin.current);\n pending.current = { row, column, select: true };\n setEditing(false);\n return;\n }\n };\n\n /**\n * A pasted block, written in from the cell it was pasted into.\n *\n * Rows past the end grow the table; columns past the last are dropped, because a\n * paste wider than the measurement is a paste with a trailing timestamp column and\n * not an error worth refusing. One header line is skipped — pasted data almost\n * always has one. Each line is read on its own evidence (`splitRow`, the per-line\n * comma rule), so one line cannot change what another means.\n */\n const paste = (row: number, column: number, text: string) => {\n const lines = text.split(/\\r?\\n/).filter((line) => line.trim() !== \"\");\n if (!lines.length) return;\n const block = lines.map(splitRow);\n if (block.length > 1 && block[0].some((cell) => !isCellNumber(cell))) block.shift();\n\n const height = Math.max(grid.length, row + block.length);\n const next = Array.from({ length: height }, (_, index) => pad(grid[index]));\n block.forEach((line, downwards) => {\n line.forEach((cell, across) => {\n const target = column + across;\n if (target < width) next[row + downwards][target] = withMark(cell.trim(), mark);\n });\n });\n onCells(next);\n pending.current = { row, column, select: true };\n setEditing(false);\n };\n\n const template = `2.5rem repeat(${width}, minmax(5.5rem, 1fr)) 2rem`;\n // The caret's row is mounted even when it has been scrolled out of the window: it\n // holds the grid's only tab stop, and a tab stop that is not in the DOM is a grid\n // Tab walks straight past.\n const mounted: number[] = [];\n for (let index = first; index < last; index += 1) mounted.push(index);\n if (at.row < first || at.row >= last) mounted.push(at.row);\n\n const filled = cells.filter(hasContent);\n const problems = filled.flat().filter((cell) => cell.trim() !== \"\" && !isCellNumber(cell)).length;\n\n return (\n <div className=\"rounded-md border border-subtle bg-surface\">\n <div ref={scrollRef} className=\"max-h-72 overflow-auto\">\n <div\n role=\"grid\"\n aria-labelledby={labelledBy}\n aria-describedby={describedBy}\n // The true size, not the mounted one: a screen reader otherwise reports the\n // thirty rows in the window as the whole table.\n aria-rowcount={grid.length + 1}\n aria-colcount={width + 2}\n aria-readonly={disabled || undefined}\n className=\"text-xs\"\n style={{ minWidth: `calc(4.5rem + ${width} * 5.5rem)` }}\n >\n {/* The header stays put vertically and scrolls sideways with the body, so a\n fifteen-column linkage can be read without losing which column is which. */}\n <div ref={headRef} role=\"rowgroup\" className=\"sticky top-0 z-10 bg-surface-2\">\n <div\n role=\"row\"\n aria-rowindex={1}\n className=\"grid border-b border-subtle\"\n style={{ gridTemplateColumns: template }}\n >\n <div\n role=\"columnheader\"\n aria-label={labels.rowNumber}\n className=\"flex items-end justify-end px-1 py-1 text-micro text-placeholder\"\n >\n #\n </div>\n {columns.map((column, index) => (\n <div\n key={index}\n role=\"columnheader\"\n className=\"min-w-0 border-s border-subtle px-2 py-1 text-end\"\n >\n <span className=\"block truncate font-medium text-primary\">\n {column.label}\n </span>\n {column.unit && (\n <span className=\"block truncate text-micro text-muted\">\n {column.unit}\n </span>\n )}\n </div>\n ))}\n <div\n role=\"columnheader\"\n aria-label={labels.rowActions}\n className=\"border-s border-subtle\"\n />\n </div>\n </div>\n {/* Only the rows in the window are mounted — a swept linkage is thousands of\n them across fifteen inputs — each placed at its own offset, so mounting\n one more (the caret's) costs nothing in the arithmetic. Since 0.32 a row\n is at least the scaled estimate tall and measured as it renders (§10.9):\n `minHeight`, not `height`, so the type at Extra large is never cut. */}\n <div role=\"rowgroup\" className=\"relative\" style={{ height: totalHeight }}>\n {mounted.map((index) => {\n const row = grid[index];\n return (\n <div\n key={index}\n ref={measureRef}\n {...{ [WINDOWED_ROW_INDEX]: index }}\n role=\"row\"\n aria-rowindex={index + 2}\n className=\"absolute inset-x-0 grid hover:bg-hover\"\n style={{ top: offsetOf(index), minHeight: estimate, gridTemplateColumns: template }}\n >\n <div\n role=\"rowheader\"\n className=\"flex items-center justify-end px-1 text-micro tabular-nums text-placeholder\"\n >\n {rowNumber.format(index + 1)}\n </div>\n {columns.map((column, columnIndex) => {\n const value = row[columnIndex] ?? BLANK;\n const bad = value.trim() !== \"\" && !isCellNumber(value);\n const isCaret = at.row === index && at.column === columnIndex;\n return (\n <div key={columnIndex} role=\"gridcell\" className=\"min-w-0 border-s border-subtle\">\n <input\n data-cell={`${index}:${columnIndex}`}\n value={value}\n // `readOnly`, not `disabled`: a disabled input cannot take\n // focus, and a read-only table should still be walkable.\n readOnly={disabled}\n tabIndex={isCaret ? 0 : -1}\n inputMode=\"decimal\"\n spellCheck={false}\n autoComplete=\"off\"\n aria-label={labels.cell(column.label, index + 1)}\n // Said, not only painted: the ring is what a sighted user\n // sees, `aria-invalid` is what a screen reader reads.\n aria-invalid={bad || undefined}\n className={cn(\n \"block size-full bg-transparent px-2 text-end tabular-nums text-primary outline-none\",\n // A cell is a field: 16 px on touch, or iOS zooms on focus (§10.1).\n FIELD_TOUCH_TEXT,\n // Arriving selects the text (typing replaces it); editing\n // in place is the plain surface with a caret in it.\n // The kit's focus frame (§5), inset so the next cell's\n // border does not paint over it. A text input is\n // `:focus-visible` however it was focused.\n \"focus:bg-brand-soft\",\n FOCUS_RING,\n \"focus-visible:ring-inset\",\n isCaret && editing && \"focus:bg-surface\",\n disabled && \"text-muted\",\n bad && cn(FIELD_INVALID, \"ring-inset\"),\n )}\n onMouseDown={(event) => {\n // A click places a caret, which is editing. On the cell\n // already focused there is no focus event to say so.\n if (document.activeElement === event.currentTarget) setEditing(!disabled);\n else pointer.current = true;\n }}\n onFocus={(event) => {\n origin.current = event.currentTarget.value;\n if (!isCaret) setCaret({ row: index, column: columnIndex });\n const byPointer = pointer.current;\n pointer.current = false;\n setEditing(byPointer && !disabled);\n if (!byPointer) event.currentTarget.select();\n }}\n onBlur={() => setEditing(false)}\n onChange={(event) => {\n setCell(index, columnIndex, event.target.value);\n setEditing(true);\n }}\n onPaste={(event) => {\n if (disabled) return;\n const text = event.clipboardData.getData(\"text/plain\");\n // One cell's worth of text is an ordinary paste, and the\n // browser does it better than this would; only a block is\n // the grid's business.\n if (!/[\\t\\n;]/.test(text)) return;\n event.preventDefault();\n paste(index, columnIndex, text);\n }}\n onKeyDown={(event) => onCellKeyDown(event, index, columnIndex)}\n />\n </div>\n );\n })}\n <div\n role=\"gridcell\"\n className=\"flex items-center justify-center border-s border-subtle\"\n >\n <button\n type=\"button\"\n data-cell={`${index}:${width}`}\n disabled={!removable}\n tabIndex={at.row === index && at.column === width ? 0 : -1}\n aria-label={labels.removeRow(index + 1)}\n className={cn(\n \"rounded p-1 text-placeholder outline-none hover:text-danger disabled:cursor-default disabled:hover:text-placeholder\",\n FOCUS_RING,\n )}\n onKeyDown={(event) => onCellKeyDown(event, index, width)}\n onFocus={() => {\n if (at.row !== index || at.column !== width) setCaret({ row: index, column: width });\n }}\n onClick={() => {\n const next = grid.filter((_, other) => other !== index);\n onCells(next);\n // Focus stays in the column, on the row that moved up into\n // this one; an emptied table sends it to the first cell.\n if (next.length) focusCell(Math.min(index, next.length - 1), width);\n else focusCell(0, 0);\n }}\n >\n <Trash2 aria-hidden className=\"size-3.5\" />\n </button>\n </div>\n </div>\n );\n })}\n </div>\n </div>\n </div>\n <div className=\"flex flex-wrap items-center gap-x-2 gap-y-1 border-t border-subtle px-2 py-1.5\">\n <Button\n variant=\"ghost\"\n size=\"sm\"\n disabled={disabled}\n onClick={() => {\n onCells([...grid.map(pad), blankRow()]);\n focusCell(grid.length, 0);\n }}\n >\n <Plus aria-hidden className=\"size-3.5\" /> {labels.addRow}\n </Button>\n <Button\n variant=\"ghost\"\n size=\"sm\"\n className=\"text-muted\"\n disabled={disabled || !cells.length}\n onClick={() => {\n onCells([]);\n // The button is about to disable itself; focus must not go down with it.\n focusCell(0, 0);\n }}\n >\n <Eraser aria-hidden className=\"size-3.5\" /> {labels.clear}\n </Button>\n <span className=\"text-caption tabular-nums text-muted\">\n {/* bdi: an LTR label (\"3 points\") in an RTL grid would reorder to \"points 3\". */}\n <bdi>{labels.points(filled.length)}</bdi>\n </span>\n {problems > 0 && (\n <span className=\"text-caption text-danger\">{labels.problems(problems)}</span>\n )}\n <span className=\"ms-auto flex items-center gap-1 text-caption text-muted\">\n <ClipboardPaste aria-hidden className=\"size-3.5\" /> {labels.pasteHint}\n </span>\n </div>\n </div>\n );\n}\n\nconst textOf = (cells: string[][]) => cells.map((row) => row.join(\"\\t\")).join(\"\\n\");\n\n/**\n * The same table as text.\n *\n * Kept because the grid is worst at exactly what a textarea is best at: reading a long\n * export back in one piece. It commits on blur — through `parseRows`, the paste door —\n * and a line it cannot read is NAMED rather than dropped: half a sweep saved as a\n * measurement is worse than a refusal.\n */\nfunction TextView({ columns, cells, onCells, disabled, mark, labels, labelledBy, describedBy }: ViewProps) {\n const text = textOf(cells);\n const [draft, setDraft] = useState(text);\n const [errorLine, setErrorLine] = useState<number | null>(null);\n // Follow the table when it changes from outside (a generated shape, a cleared form).\n // Compared as text, so a caller that rebuilds the same cells every render does not\n // wipe what is being typed.\n const [seen, setSeen] = useState(text);\n if (seen !== text) {\n setSeen(text);\n setDraft(text);\n setErrorLine(null);\n }\n\n const commit = () => {\n // Untouched: nothing to read back, and re-reading would rewrite every cell in the\n // lexer's spelling of it.\n if (draft === text) return;\n if (!draft.trim()) {\n setErrorLine(null);\n onCells([]);\n return;\n }\n const parsed = parseRows(draft, columns.length);\n if (\"error\" in parsed) {\n setErrorLine(parsed.error);\n return;\n }\n setErrorLine(null);\n onCells(parsed.rows.map((row) => row.map((value) => withMark(String(value), mark))));\n };\n\n const lines = draft.split(\"\\n\").filter((line) => line.trim()).length;\n\n return (\n <div>\n <Textarea\n aria-labelledby={labelledBy}\n aria-describedby={describedBy}\n rows={10}\n value={draft}\n readOnly={disabled}\n spellCheck={false}\n className=\"font-mono text-xs\"\n error={errorLine !== null ? labels.lineError(errorLine) : undefined}\n onChange={(event) => setDraft(event.target.value)}\n onBlur={commit}\n />\n <p className=\"mt-1 px-1 text-caption text-muted\">\n {columns.map((column) => column.label).join(\" · \")}\n {\" — \"}\n <bdi>{labels.points(lines)}</bdi>\n </p>\n </div>\n );\n}\n"],"mappings":";AA8QM,SACE,KADF;AA9QN,SAAS,aAAa,WAAW,OAAO,SAAS,QAAQ,gBAAgB;AAEzE,SAAS,gBAAgB,QAAQ,MAAM,cAAc;AACrD,SAAS,UAAU;AACnB,SAAS,sBAAsB;AAG/B,SAAS,mBAAmB;AAI5B,SAAS,YAAY,cAAc,WAAW,gBAAgB;AAC9D,SAAS,cAAc,oBAAwC;AAC/D,SAAS,iBAAiB,0BAA0B;AACpD,SAAS,mBAAmB;AAC5B,SAAS,cAAc;AACvB,SAAS,eAAe,wBAAwB;AAChD,SAAS,kBAAkB;AAC3B,SAAS,gBAAgB;AACzB,SAAS,oCAAoC;AAwE7C,MAAM,QAAQ;AAMd,MAAM,qBAAqB;AAE3B,MAAM,YAAyC,CAAC,SAAS,MAAM;AAK/D,MAAM,WAAW,CAAC,MAAc,SAC9B,SAAS,OAAO,aAAa,IAAI,IAAI,KAAK,QAAQ,KAAK,GAAG,IAAI;AAGhE,MAAM,aAAa,CAAC,OAAe,QAAgB,SACjD,SAAS,OAAO,OAAO,MAAM,QAAQ,MAAM,CAAC,CAAC,GAAG,IAAI;AAEtD,MAAM,aAAa,CAAC,QAA2B,IAAI,KAAK,CAAC,SAAS,KAAK,KAAK,MAAM,EAAE;AAyC7E,SAAS,gBACd,SACA,UAAkC,CAAC,GACrB;AACd,QAAM,EAAE,SAAS,EAAE,IAAI;AACvB,QAAM,OAAO,YAAY,aAAa,QAAQ,MAAM,CAAC;AACrD,QAAM,CAAC,OAAO,QAAQ,IAAI;AAAA,IAAqB,OAC5C,OAAO,YAAY,aAAa,QAAQ,IAAI,SAAS;AAAA,MAAI,CAAC,QACzD,IAAI,IAAI,CAAC,UAAU,WAAW,OAAO,QAAQ,IAAI,CAAC;AAAA,IACpD;AAAA,EACF;AAEA,QAAM,EAAE,MAAM,OAAO,SAAS,IAAI,QAAQ,MAAM;AAC9C,UAAM,SAAS,MAAM,OAAO,UAAU;AACtC,UAAM,QAAQ,OAAO,UAAU,KAAK,OAAO,MAAM,CAAC,QAAQ,IAAI,MAAM,YAAY,CAAC;AACjF,WAAO;AAAA,MACL,MAAM,QAAQ,OAAO,IAAI,CAAC,QAAQ,IAAI,IAAI,UAAU,CAAC,IAAI,CAAC;AAAA,MAC1D,OAAO;AAAA,MACP,UAAU,OAAO,KAAK,EAAE,OAAO,CAAC,SAAS,KAAK,KAAK,MAAM,MAAM,CAAC,aAAa,IAAI,CAAC,EAAE;AAAA,IACtF;AAAA,EACF,GAAG,CAAC,KAAK,CAAC;AAEV,QAAM,UAAU;AAAA,IACd,CAAC,SAAqB,SAAS,KAAK,IAAI,CAAC,QAAQ,IAAI,IAAI,CAAC,UAAU,WAAW,OAAO,QAAQ,IAAI,CAAC,CAAC,CAAC;AAAA,IACrG,CAAC,QAAQ,IAAI;AAAA,EACf;AACA,QAAM,QAAQ,QAAQ,OAAO,EAAE,OAAO,SAAS,SAAS,IAAI,CAAC,KAAK,CAAC;AAEnE,SAAO,EAAE,OAAO,UAAU,MAAM,SAAS,OAAO,UAAU,MAAM;AAClE;AA4DO,SAAS,aAAa;AAAA,EAC3B;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA,QAAQ;AAAA,EACR,YAAY;AAAA,EACZ,QAAQ;AAAA,EACR,QAAQ;AAAA,EACR;AAAA,EACA,GAAG;AACL,GAAsB;AACpB,QAAM,SAAS,aAAa,gBAAgB,8BAA8B,UAAU;AACpF,QAAM,SAAS,aAAa,UAAU;AACtC,QAAM,OAAO,YAAY,MAAM;AAC/B,QAAM,KAAK,MAAM;AACjB,QAAM,UAAU,GAAG,EAAE;AACrB,QAAM,SAAS,GAAG,EAAE;AACpB,QAAM,SAAS,GAAG,EAAE;AACpB,QAAM,UAAU,MAAM,SAAS,QAAQ;AACvC,QAAM,CAAC,QAAQ,SAAS,IAAI,SAA2B,QAAQ,CAAC,CAAC;AACjE,QAAM,OAAO,QAAQ,SAAS,MAAM,IAAI,SAAS,QAAQ,CAAC;AAE1D;AAAA;AAAA;AAAA,IAGE,qBAAC,SAAK,GAAG,MAAM,WAAW,GAAG,YAAY,SAAS,GAChD;AAAA,2BAAC,SAAI,WAAU,0DACb;AAAA,4BAAC,UAAK,IAAI,SAAS,WAAU,uCAC1B,iBACH;AAAA,QACC,QAAQ,SAAS,KAChB;AAAA,UAAC;AAAA;AAAA,YACC,WAAU;AAAA,YACV,cAAY,OAAO;AAAA,YACnB,OAAO;AAAA,YACP,UAAU;AAAA,YACV,SAAS,QAAQ,IAAI,CAAC,WAAW;AAAA,cAC/B;AAAA,cACA,OAAO,UAAU,UAAU,OAAO,YAAY,OAAO;AAAA,YACvD,EAAE;AAAA;AAAA,QACJ;AAAA,SAEJ;AAAA,MACC,SAAS,UACR;AAAA,QAAC;AAAA;AAAA,UACC;AAAA,UACA;AAAA,UACA;AAAA,UACA;AAAA,UACA;AAAA,UACA;AAAA,UACA;AAAA,UACA;AAAA,UACA,YAAY;AAAA,UACZ,aAAa,OAAO,GAAG,MAAM,IAAI,MAAM,KAAK;AAAA;AAAA,MAC9C,IAEA;AAAA,QAAC;AAAA;AAAA,UACC;AAAA,UACA;AAAA,UACA;AAAA,UACA;AAAA,UACA;AAAA,UACA;AAAA,UACA,YAAY;AAAA,UACZ,aAAa,OAAO,SAAS;AAAA;AAAA,MAC/B;AAAA,MAED,QACC,oBAAC,OAAE,IAAI,QAAQ,WAAU,qCACtB,gBACH;AAAA,MAED,SAAS,WACR,oBAAC,UAAK,IAAI,QAAQ,WAAU,WACzB,iBAAO,cACV;AAAA,OAEJ;AAAA;AAEJ;AAqBA,SAAS,SAAS;AAAA,EAChB;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AACF,GAAkE;AAChE,QAAM,YAAY,OAAuB,IAAI;AAC7C,QAAM,UAAU,OAAuB,IAAI;AAC3C,QAAM,QAAQ,QAAQ;AACtB,QAAM,WAAW,MAAM,QAAQ,IAAI,MAAM,KAAK;AAI9C,QAAM,OAAO,MAAM,SAAS,QAAQ,CAAC,SAAS,CAAC;AAC/C,QAAM,EAAE,OAAO,MAAM,aAAa,UAAU,UAAU,UAAU,WAAW,IAAI;AAAA,IAC7E,KAAK;AAAA,IACL;AAAA,IACA;AAAA,EACF;AACA,QAAM,YAAY,QAAQ,MAAM,IAAI,KAAK,aAAa,MAAM,GAAG,CAAC,MAAM,CAAC;AAKvE,QAAM,YAAY,CAAC,YAAY,MAAM,SAAS;AAC9C,QAAM,aAAa,YAAY,QAAQ,QAAQ;AAE/C,QAAM,CAAC,OAAO,QAAQ,IAAI,SAAgB,EAAE,KAAK,GAAG,QAAQ,EAAE,CAAC;AAG/D,QAAM,KAAK,EAAE,KAAK,KAAK,IAAI,MAAM,KAAK,KAAK,SAAS,CAAC,GAAG,QAAQ,KAAK,IAAI,MAAM,QAAQ,UAAU,EAAE;AAEnG,QAAM,CAAC,SAAS,UAAU,IAAI,SAAS,KAAK;AAG5C,QAAM,UAAU,OAA6C,IAAI;AAEjE,QAAM,SAAS,OAAO,KAAK;AAE3B,QAAM,UAAU,OAAO,KAAK;AAE5B,YAAU,MAAM;AACd,UAAM,SAAS,QAAQ;AACvB,QAAI,CAAC,OAAQ;AACb,UAAM,UAAU,UAAU,SAAS;AAAA,MACjC,eAAe,OAAO,GAAG,IAAI,OAAO,MAAM;AAAA,IAC5C;AACA,QAAI,CAAC,QAAS;AACd,YAAQ,UAAU;AAGlB,YAAQ,MAAM,EAAE,eAAe,KAAK,CAAC;AACrC,QAAI,OAAO,UAAU,mBAAmB,iBAAkB,SAAQ,OAAO;AAAA,EAC3E,CAAC;AAED,QAAM,MAAM,CAAC,QACX,MAAM,KAAK,EAAE,QAAQ,MAAM,GAAG,CAAC,GAAG,UAAU,MAAM,KAAK,KAAK,KAAK;AAEnE,QAAM,UAAU,CAAC,KAAa,QAAgB,UAAkB;AAC9D,UAAM,OAAO,KAAK,IAAI,GAAG;AACzB,SAAK,GAAG,EAAE,MAAM,IAAI;AACpB,YAAQ,IAAI;AAAA,EACd;AAGA,QAAM,SAAS,CAAC,QAAgB;AAC9B,UAAM,UAAU,UAAU;AAC1B,QAAI,CAAC,QAAS;AACd,UAAM,OAAO,QAAQ,gBAAgB,QAAQ,SAAS,gBAAgB;AACtE,QAAI,QAAQ,EAAG;AAEf,UAAM,MAAM,SAAS,GAAG;AACxB,UAAM,SAAS,SAAS,GAAG;AAC3B,QAAI,MAAM,QAAQ,UAAW,SAAQ,YAAY;AAAA,aACxC,MAAM,SAAS,QAAQ,YAAY,KAAM,SAAQ,YAAY,MAAM,SAAS;AAAA,EACvF;AAEA,QAAM,YAAY,CAAC,KAAa,WAAmB;AACjD,WAAO,GAAG;AACV,YAAQ,UAAU,EAAE,KAAK,QAAQ,QAAQ,KAAK;AAC9C,aAAS,EAAE,KAAK,OAAO,CAAC;AACxB,eAAW,KAAK;AAAA,EAClB;AAEA,QAAM,KAAK,CAAC,KAAa,WAAmB;AAC1C,UAAM,SAAS;AAAA,MACb,KAAK,KAAK,IAAI,GAAG,KAAK,IAAI,KAAK,KAAK,SAAS,CAAC,CAAC;AAAA,MAC/C,QAAQ,KAAK,IAAI,GAAG,KAAK,IAAI,QAAQ,UAAU,CAAC;AAAA,IAClD;AACA,QAAI,OAAO,QAAQ,GAAG,OAAO,OAAO,WAAW,GAAG,OAAQ;AAC1D,cAAU,OAAO,KAAK,OAAO,MAAM;AAAA,EACrC;AAIA,QAAM,OAAO,CAAC,KAAa,WAAmB;AAC5C,QAAI,MAAM,IAAI,KAAK,OAAQ,QAAO,GAAG,MAAM,GAAG,MAAM;AACpD,QAAI,YAAY,CAAC,WAAW,KAAK,GAAG,CAAC,EAAG;AACxC,YAAQ,CAAC,GAAG,KAAK,IAAI,GAAG,GAAG,SAAS,CAAC,CAAC;AACtC,cAAU,MAAM,GAAG,KAAK,IAAI,QAAQ,QAAQ,CAAC,CAAC;AAAA,EAChD;AAEA,QAAM,OAAO,MAAM;AACjB,UAAM,UAAU,UAAU;AAC1B,UAAM,OAAO,UAAU,QAAQ,gBAAgB,QAAQ,SAAS,gBAAgB,KAAK;AAErF,WAAO,OAAO,IAAI,KAAK,IAAI,GAAG,KAAK,MAAM,OAAO,QAAQ,IAAI,CAAC,IAAI;AAAA,EACnE;AAOA,QAAM,gBAAgB,CAAC,OAAmC,KAAa,WAAmB;AACxF,UAAM,QAAQ,MAAM,yBAAyB,mBAAmB,MAAM,gBAAgB;AACtF,UAAM,SAAS,QAAQ,KAAK,KAAK;AACjC,UAAM,WAAW,MAAM,WAAW,MAAM;AACxC,YAAQ,MAAM,KAAK;AAAA,MACjB,KAAK;AACH,cAAM,eAAe;AACrB,eAAO,GAAG,MAAM,GAAG,MAAM;AAAA,MAC3B,KAAK;AACH,cAAM,eAAe;AACrB,eAAO,KAAK,KAAK,MAAM;AAAA,MACzB,KAAK;AAEH,YAAI,CAAC,MAAO;AACZ,cAAM,eAAe;AACrB,eAAO,MAAM,WAAW,GAAG,MAAM,GAAG,MAAM,IAAI,KAAK,KAAK,MAAM;AAAA,MAChE,KAAK;AAAA,MACL,KAAK,cAAc;AAEjB,cAAM,UAAU,eAAe,MAAM,KAAK,MAAM,aAAa,MAAM;AACnE,YAAI,UAAU,OAAO;AACnB,gBAAM,OAAO,UAAU,MAAM,MAAM,SAAS;AAE5C,cAAI,MAAM,mBAAmB,QAAQ,MAAM,iBAAiB,KAAM;AAAA,QACpE;AACA,cAAM,eAAe;AACrB,eAAO,GAAG,KAAK,UAAU,UAAU,IAAI,GAAG;AAAA,MAC5C;AAAA,MACA,KAAK;AAAA,MACL,KAAK,OAAO;AACV,YAAI,UAAU,CAAC,SAAU;AACzB,cAAM,eAAe;AACrB,cAAM,OAAO,MAAM,QAAQ;AAC3B,YAAI,SAAU,QAAO,GAAG,OAAO,IAAI,KAAK,SAAS,GAAG,OAAO,IAAI,QAAQ,CAAC;AACxE,eAAO,GAAG,KAAK,OAAO,IAAI,QAAQ,CAAC;AAAA,MACrC;AAAA,MACA,KAAK;AACH,cAAM,eAAe;AACrB,eAAO,GAAG,MAAM,KAAK,GAAG,MAAM;AAAA,MAChC,KAAK;AACH,cAAM,eAAe;AACrB,eAAO,GAAG,MAAM,KAAK,GAAG,MAAM;AAAA,MAChC,KAAK;AACH,YAAI,CAAC,SAAS,SAAU;AACxB,cAAM,eAAe;AACrB,mBAAW,IAAI;AACf,cAAM,kBAAkB,MAAM,MAAM,QAAQ,MAAM,MAAM,MAAM;AAC9D;AAAA,MACF,KAAK;AAGH,YAAI,CAAC,SAAS,CAAC,QAAS;AACxB,cAAM,eAAe;AACrB,cAAM,gBAAgB;AACtB,YAAI,MAAM,UAAU,OAAO,QAAS,SAAQ,KAAK,QAAQ,OAAO,OAAO;AACvE,gBAAQ,UAAU,EAAE,KAAK,QAAQ,QAAQ,KAAK;AAC9C,mBAAW,KAAK;AAChB;AAAA,IACJ;AAAA,EACF;AAWA,QAAM,QAAQ,CAAC,KAAa,QAAgB,SAAiB;AAC3D,UAAM,QAAQ,KAAK,MAAM,OAAO,EAAE,OAAO,CAAC,SAAS,KAAK,KAAK,MAAM,EAAE;AACrE,QAAI,CAAC,MAAM,OAAQ;AACnB,UAAM,QAAQ,MAAM,IAAI,QAAQ;AAChC,QAAI,MAAM,SAAS,KAAK,MAAM,CAAC,EAAE,KAAK,CAAC,SAAS,CAAC,aAAa,IAAI,CAAC,EAAG,OAAM,MAAM;AAElF,UAAM,SAAS,KAAK,IAAI,KAAK,QAAQ,MAAM,MAAM,MAAM;AACvD,UAAM,OAAO,MAAM,KAAK,EAAE,QAAQ,OAAO,GAAG,CAAC,GAAG,UAAU,IAAI,KAAK,KAAK,CAAC,CAAC;AAC1E,UAAM,QAAQ,CAAC,MAAM,cAAc;AACjC,WAAK,QAAQ,CAAC,MAAM,WAAW;AAC7B,cAAM,SAAS,SAAS;AACxB,YAAI,SAAS,MAAO,MAAK,MAAM,SAAS,EAAE,MAAM,IAAI,SAAS,KAAK,KAAK,GAAG,IAAI;AAAA,MAChF,CAAC;AAAA,IACH,CAAC;AACD,YAAQ,IAAI;AACZ,YAAQ,UAAU,EAAE,KAAK,QAAQ,QAAQ,KAAK;AAC9C,eAAW,KAAK;AAAA,EAClB;AAEA,QAAM,WAAW,iBAAiB,KAAK;AAIvC,QAAM,UAAoB,CAAC;AAC3B,WAAS,QAAQ,OAAO,QAAQ,MAAM,SAAS,EAAG,SAAQ,KAAK,KAAK;AACpE,MAAI,GAAG,MAAM,SAAS,GAAG,OAAO,KAAM,SAAQ,KAAK,GAAG,GAAG;AAEzD,QAAM,SAAS,MAAM,OAAO,UAAU;AACtC,QAAM,WAAW,OAAO,KAAK,EAAE,OAAO,CAAC,SAAS,KAAK,KAAK,MAAM,MAAM,CAAC,aAAa,IAAI,CAAC,EAAE;AAE3F,SACE,qBAAC,SAAI,WAAU,8CACb;AAAA,wBAAC,SAAI,KAAK,WAAW,WAAU,0BAC7B;AAAA,MAAC;AAAA;AAAA,QACC,MAAK;AAAA,QACL,mBAAiB;AAAA,QACjB,oBAAkB;AAAA,QAGlB,iBAAe,KAAK,SAAS;AAAA,QAC7B,iBAAe,QAAQ;AAAA,QACvB,iBAAe,YAAY;AAAA,QAC3B,WAAU;AAAA,QACV,OAAO,EAAE,UAAU,iBAAiB,KAAK,aAAa;AAAA,QAItD;AAAA,8BAAC,SAAI,KAAK,SAAS,MAAK,YAAW,WAAU,kCAC3C;AAAA,YAAC;AAAA;AAAA,cACC,MAAK;AAAA,cACL,iBAAe;AAAA,cACf,WAAU;AAAA,cACV,OAAO,EAAE,qBAAqB,SAAS;AAAA,cAEvC;AAAA;AAAA,kBAAC;AAAA;AAAA,oBACC,MAAK;AAAA,oBACL,cAAY,OAAO;AAAA,oBACnB,WAAU;AAAA,oBACX;AAAA;AAAA,gBAED;AAAA,gBACC,QAAQ,IAAI,CAAC,QAAQ,UACpB;AAAA,kBAAC;AAAA;AAAA,oBAEC,MAAK;AAAA,oBACL,WAAU;AAAA,oBAEV;AAAA,0CAAC,UAAK,WAAU,2CACb,iBAAO,OACV;AAAA,sBACC,OAAO,QACN,oBAAC,UAAK,WAAU,wCACb,iBAAO,MACV;AAAA;AAAA;AAAA,kBAVG;AAAA,gBAYP,CACD;AAAA,gBACD;AAAA,kBAAC;AAAA;AAAA,oBACC,MAAK;AAAA,oBACL,cAAY,OAAO;AAAA,oBACnB,WAAU;AAAA;AAAA,gBACZ;AAAA;AAAA;AAAA,UACF,GACF;AAAA,UAMA,oBAAC,SAAI,MAAK,YAAW,WAAU,YAAW,OAAO,EAAE,QAAQ,YAAY,GACpE,kBAAQ,IAAI,CAAC,UAAU;AACtB,kBAAM,MAAM,KAAK,KAAK;AACtB,mBACE;AAAA,cAAC;AAAA;AAAA,gBAEC,KAAK;AAAA,gBACJ,GAAG,EAAE,CAAC,kBAAkB,GAAG,MAAM;AAAA,gBAClC,MAAK;AAAA,gBACL,iBAAe,QAAQ;AAAA,gBACvB,WAAU;AAAA,gBACV,OAAO,EAAE,KAAK,SAAS,KAAK,GAAG,WAAW,UAAU,qBAAqB,SAAS;AAAA,gBAElF;AAAA;AAAA,oBAAC;AAAA;AAAA,sBACC,MAAK;AAAA,sBACL,WAAU;AAAA,sBAET,oBAAU,OAAO,QAAQ,CAAC;AAAA;AAAA,kBAC7B;AAAA,kBACC,QAAQ,IAAI,CAAC,QAAQ,gBAAgB;AACpC,0BAAM,QAAQ,IAAI,WAAW,KAAK;AAClC,0BAAM,MAAM,MAAM,KAAK,MAAM,MAAM,CAAC,aAAa,KAAK;AACtD,0BAAM,UAAU,GAAG,QAAQ,SAAS,GAAG,WAAW;AAClD,2BACE,oBAAC,SAAsB,MAAK,YAAW,WAAU,kCAC/C;AAAA,sBAAC;AAAA;AAAA,wBACC,aAAW,GAAG,KAAK,IAAI,WAAW;AAAA,wBAClC;AAAA,wBAGA,UAAU;AAAA,wBACV,UAAU,UAAU,IAAI;AAAA,wBACxB,WAAU;AAAA,wBACV,YAAY;AAAA,wBACZ,cAAa;AAAA,wBACb,cAAY,OAAO,KAAK,OAAO,OAAO,QAAQ,CAAC;AAAA,wBAG/C,gBAAc,OAAO;AAAA,wBACrB,WAAW;AAAA,0BACT;AAAA;AAAA,0BAEA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,0BAMA;AAAA,0BACA;AAAA,0BACA;AAAA,0BACA,WAAW,WAAW;AAAA,0BACtB,YAAY;AAAA,0BACZ,OAAO,GAAG,eAAe,YAAY;AAAA,wBACvC;AAAA,wBACA,aAAa,CAAC,UAAU;AAGtB,8BAAI,SAAS,kBAAkB,MAAM,cAAe,YAAW,CAAC,QAAQ;AAAA,8BACnE,SAAQ,UAAU;AAAA,wBACzB;AAAA,wBACA,SAAS,CAAC,UAAU;AAClB,iCAAO,UAAU,MAAM,cAAc;AACrC,8BAAI,CAAC,QAAS,UAAS,EAAE,KAAK,OAAO,QAAQ,YAAY,CAAC;AAC1D,gCAAM,YAAY,QAAQ;AAC1B,kCAAQ,UAAU;AAClB,qCAAW,aAAa,CAAC,QAAQ;AACjC,8BAAI,CAAC,UAAW,OAAM,cAAc,OAAO;AAAA,wBAC7C;AAAA,wBACA,QAAQ,MAAM,WAAW,KAAK;AAAA,wBAC9B,UAAU,CAAC,UAAU;AACnB,kCAAQ,OAAO,aAAa,MAAM,OAAO,KAAK;AAC9C,qCAAW,IAAI;AAAA,wBACjB;AAAA,wBACA,SAAS,CAAC,UAAU;AAClB,8BAAI,SAAU;AACd,gCAAM,OAAO,MAAM,cAAc,QAAQ,YAAY;AAIrD,8BAAI,CAAC,UAAU,KAAK,IAAI,EAAG;AAC3B,gCAAM,eAAe;AACrB,gCAAM,OAAO,aAAa,IAAI;AAAA,wBAChC;AAAA,wBACA,WAAW,CAAC,UAAU,cAAc,OAAO,OAAO,WAAW;AAAA;AAAA,oBAC/D,KA7DQ,WA8DV;AAAA,kBAEJ,CAAC;AAAA,kBACD;AAAA,oBAAC;AAAA;AAAA,sBACC,MAAK;AAAA,sBACL,WAAU;AAAA,sBAEV;AAAA,wBAAC;AAAA;AAAA,0BACC,MAAK;AAAA,0BACL,aAAW,GAAG,KAAK,IAAI,KAAK;AAAA,0BAC5B,UAAU,CAAC;AAAA,0BACX,UAAU,GAAG,QAAQ,SAAS,GAAG,WAAW,QAAQ,IAAI;AAAA,0BACxD,cAAY,OAAO,UAAU,QAAQ,CAAC;AAAA,0BACtC,WAAW;AAAA,4BACT;AAAA,4BACA;AAAA,0BACF;AAAA,0BACA,WAAW,CAAC,UAAU,cAAc,OAAO,OAAO,KAAK;AAAA,0BACvD,SAAS,MAAM;AACb,gCAAI,GAAG,QAAQ,SAAS,GAAG,WAAW,MAAO,UAAS,EAAE,KAAK,OAAO,QAAQ,MAAM,CAAC;AAAA,0BACrF;AAAA,0BACA,SAAS,MAAM;AACb,kCAAM,OAAO,KAAK,OAAO,CAAC,GAAG,UAAU,UAAU,KAAK;AACtD,oCAAQ,IAAI;AAGZ,gCAAI,KAAK,OAAQ,WAAU,KAAK,IAAI,OAAO,KAAK,SAAS,CAAC,GAAG,KAAK;AAAA,gCAC7D,WAAU,GAAG,CAAC;AAAA,0BACrB;AAAA,0BAEA,8BAAC,UAAO,eAAW,MAAC,WAAU,YAAW;AAAA;AAAA,sBAC3C;AAAA;AAAA,kBACF;AAAA;AAAA;AAAA,cAjHK;AAAA,YAkHP;AAAA,UAEJ,CAAC,GACH;AAAA;AAAA;AAAA,IACF,GACF;AAAA,IACA,qBAAC,SAAI,WAAU,kFACb;AAAA;AAAA,QAAC;AAAA;AAAA,UACC,SAAQ;AAAA,UACR,MAAK;AAAA,UACL;AAAA,UACA,SAAS,MAAM;AACb,oBAAQ,CAAC,GAAG,KAAK,IAAI,GAAG,GAAG,SAAS,CAAC,CAAC;AACtC,sBAAU,KAAK,QAAQ,CAAC;AAAA,UAC1B;AAAA,UAEA;AAAA,gCAAC,QAAK,eAAW,MAAC,WAAU,YAAW;AAAA,YAAE;AAAA,YAAE,OAAO;AAAA;AAAA;AAAA,MACpD;AAAA,MACA;AAAA,QAAC;AAAA;AAAA,UACC,SAAQ;AAAA,UACR,MAAK;AAAA,UACL,WAAU;AAAA,UACV,UAAU,YAAY,CAAC,MAAM;AAAA,UAC7B,SAAS,MAAM;AACb,oBAAQ,CAAC,CAAC;AAEV,sBAAU,GAAG,CAAC;AAAA,UAChB;AAAA,UAEA;AAAA,gCAAC,UAAO,eAAW,MAAC,WAAU,YAAW;AAAA,YAAE;AAAA,YAAE,OAAO;AAAA;AAAA;AAAA,MACtD;AAAA,MACA,oBAAC,UAAK,WAAU,wCAEd,8BAAC,SAAK,iBAAO,OAAO,OAAO,MAAM,GAAE,GACrC;AAAA,MACC,WAAW,KACV,oBAAC,UAAK,WAAU,4BAA4B,iBAAO,SAAS,QAAQ,GAAE;AAAA,MAExE,qBAAC,UAAK,WAAU,2DACd;AAAA,4BAAC,kBAAe,eAAW,MAAC,WAAU,YAAW;AAAA,QAAE;AAAA,QAAE,OAAO;AAAA,SAC9D;AAAA,OACF;AAAA,KACF;AAEJ;AAEA,MAAM,SAAS,CAAC,UAAsB,MAAM,IAAI,CAAC,QAAQ,IAAI,KAAK,GAAI,CAAC,EAAE,KAAK,IAAI;AAUlF,SAAS,SAAS,EAAE,SAAS,OAAO,SAAS,UAAU,MAAM,QAAQ,YAAY,YAAY,GAAc;AACzG,QAAM,OAAO,OAAO,KAAK;AACzB,QAAM,CAAC,OAAO,QAAQ,IAAI,SAAS,IAAI;AACvC,QAAM,CAAC,WAAW,YAAY,IAAI,SAAwB,IAAI;AAI9D,QAAM,CAAC,MAAM,OAAO,IAAI,SAAS,IAAI;AACrC,MAAI,SAAS,MAAM;AACjB,YAAQ,IAAI;AACZ,aAAS,IAAI;AACb,iBAAa,IAAI;AAAA,EACnB;AAEA,QAAM,SAAS,MAAM;AAGnB,QAAI,UAAU,KAAM;AACpB,QAAI,CAAC,MAAM,KAAK,GAAG;AACjB,mBAAa,IAAI;AACjB,cAAQ,CAAC,CAAC;AACV;AAAA,IACF;AACA,UAAM,SAAS,UAAU,OAAO,QAAQ,MAAM;AAC9C,QAAI,WAAW,QAAQ;AACrB,mBAAa,OAAO,KAAK;AACzB;AAAA,IACF;AACA,iBAAa,IAAI;AACjB,YAAQ,OAAO,KAAK,IAAI,CAAC,QAAQ,IAAI,IAAI,CAAC,UAAU,SAAS,OAAO,KAAK,GAAG,IAAI,CAAC,CAAC,CAAC;AAAA,EACrF;AAEA,QAAM,QAAQ,MAAM,MAAM,IAAI,EAAE,OAAO,CAAC,SAAS,KAAK,KAAK,CAAC,EAAE;AAE9D,SACE,qBAAC,SACC;AAAA;AAAA,MAAC;AAAA;AAAA,QACC,mBAAiB;AAAA,QACjB,oBAAkB;AAAA,QAClB,MAAM;AAAA,QACN,OAAO;AAAA,QACP,UAAU;AAAA,QACV,YAAY;AAAA,QACZ,WAAU;AAAA,QACV,OAAO,cAAc,OAAO,OAAO,UAAU,SAAS,IAAI;AAAA,QAC1D,UAAU,CAAC,UAAU,SAAS,MAAM,OAAO,KAAK;AAAA,QAChD,QAAQ;AAAA;AAAA,IACV;AAAA,IACA,qBAAC,OAAE,WAAU,qCACV;AAAA,cAAQ,IAAI,CAAC,WAAW,OAAO,KAAK,EAAE,KAAK,QAAK;AAAA,MAChD;AAAA,MACD,oBAAC,SAAK,iBAAO,OAAO,KAAK,GAAE;AAAA,OAC7B;AAAA,KACF;AAEJ;","names":[]}
|
|
@@ -1,12 +1,10 @@
|
|
|
1
|
-
import
|
|
2
|
-
import {
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
type MenuItemTone = "default" | "danger";
|
|
1
|
+
import type { MouseEvent, ReactElement, ReactNode, Ref } from "react";
|
|
2
|
+
import type { LucideIcon } from "lucide-react";
|
|
3
|
+
export type MenuItemTone = "default" | "danger";
|
|
6
4
|
/** What {@link MenuItemProps.renderLink} is handed. Spread it onto your router's link,
|
|
7
5
|
* mapping `href` to what the link calls it —
|
|
8
6
|
* `renderLink={({ href, ...p }) => <Link to={href} {...p} />}`. */
|
|
9
|
-
interface MenuItemLinkProps {
|
|
7
|
+
export interface MenuItemLinkProps {
|
|
10
8
|
href: string;
|
|
11
9
|
className: string;
|
|
12
10
|
children: ReactNode;
|
|
@@ -45,12 +43,15 @@ interface MenuItemBaseProps {
|
|
|
45
43
|
id?: string;
|
|
46
44
|
[key: `aria-${string}`]: string | boolean | number | undefined;
|
|
47
45
|
[key: `data-${string}`]: unknown;
|
|
46
|
+
/** The row — the `<button>`, or the `<a>` with `href`. A React 19 ref prop since 0.34
|
|
47
|
+
* (MOD-4, refactor audit 2026-10); it was `forwardRef`. */
|
|
48
|
+
ref?: Ref<HTMLElement>;
|
|
48
49
|
}
|
|
49
50
|
/**
|
|
50
51
|
* A menu row is a button OR a link, and only the button can be CHECKED: a checked link
|
|
51
52
|
* is a link to where you already are, which is `current`, not a selection.
|
|
52
53
|
*/
|
|
53
|
-
type MenuItemProps = MenuItemBaseProps & ({
|
|
54
|
+
export type MenuItemProps = MenuItemBaseProps & ({
|
|
54
55
|
href?: never;
|
|
55
56
|
renderLink?: never;
|
|
56
57
|
current?: never;
|
|
@@ -105,6 +106,5 @@ type MenuItemProps = MenuItemBaseProps & ({
|
|
|
105
106
|
* with the rest. Render it inside an `<li>` like the shell's own rows; `HoverMenu`
|
|
106
107
|
* turns the list markup into `role="none"`.
|
|
107
108
|
*/
|
|
108
|
-
declare
|
|
109
|
-
|
|
110
|
-
export { MenuItem, type MenuItemLinkProps, type MenuItemProps, type MenuItemTone };
|
|
109
|
+
export declare function MenuItem({ ref, children, icon: Icon, leading, badge, trailing, tone, disabled, className, href, renderLink, onClick, checked, checkable, current, ...rest }: MenuItemProps): import("react").JSX.Element;
|
|
110
|
+
export {};
|
|
@@ -1,14 +1,14 @@
|
|
|
1
1
|
"use client";
|
|
2
2
|
import { Fragment, jsx, jsxs } from "react/jsx-runtime";
|
|
3
|
-
import { forwardRef } from "react";
|
|
4
3
|
import { Check } from "lucide-react";
|
|
5
4
|
import { cn } from "../lib/cn.js";
|
|
6
5
|
import { FOCUS_RING } from "./focus-ring.js";
|
|
7
6
|
import { useKitLink } from "../i18n/kit-labels.js";
|
|
8
7
|
import { pickLinkRenderer } from "./text-link.js";
|
|
9
|
-
const MENU_ITEM_ROW = "flex w-full items-center justify-between gap-3 px-3 py-2 text-sm text-start text-
|
|
10
|
-
const MENU_ITEM_FOCUS = `${FOCUS_RING} focus-visible:bg-
|
|
11
|
-
|
|
8
|
+
const MENU_ITEM_ROW = "flex w-full items-center justify-between gap-3 px-3 py-2 text-sm text-start text-secondary hover:bg-hover";
|
|
9
|
+
const MENU_ITEM_FOCUS = `${FOCUS_RING} focus-visible:bg-hover focus-visible:ring-inset`;
|
|
10
|
+
function MenuItem({
|
|
11
|
+
ref,
|
|
12
12
|
children,
|
|
13
13
|
icon: Icon,
|
|
14
14
|
leading,
|
|
@@ -24,13 +24,13 @@ const MenuItem = forwardRef(function MenuItem2({
|
|
|
24
24
|
checkable,
|
|
25
25
|
current,
|
|
26
26
|
...rest
|
|
27
|
-
}
|
|
27
|
+
}) {
|
|
28
28
|
const kitLink = useKitLink();
|
|
29
29
|
const on = href !== void 0 ? !!current : !!checked;
|
|
30
30
|
const look = cn(
|
|
31
31
|
MENU_ITEM_ROW,
|
|
32
32
|
MENU_ITEM_FOCUS,
|
|
33
|
-
tone === "danger" && "text-
|
|
33
|
+
tone === "danger" && "text-danger hover:bg-danger-soft focus-visible:bg-danger-soft",
|
|
34
34
|
disabled && "cursor-default opacity-50 hover:bg-transparent",
|
|
35
35
|
className
|
|
36
36
|
);
|
|
@@ -38,7 +38,7 @@ const MenuItem = forwardRef(function MenuItem2({
|
|
|
38
38
|
/* @__PURE__ */ jsxs("span", { className: "flex min-w-0 items-center gap-2", children: [
|
|
39
39
|
Icon && /* @__PURE__ */ jsx(Icon, { className: "size-4 shrink-0", "aria-hidden": true }),
|
|
40
40
|
leading,
|
|
41
|
-
/* @__PURE__ */ jsx("span", { className: "min-w-0 truncate", children }),
|
|
41
|
+
/* @__PURE__ */ jsx("span", { className: "min-w-0 truncate-until-large", children }),
|
|
42
42
|
badge != null && badge !== false && /* @__PURE__ */ jsxs(Fragment, { children: [
|
|
43
43
|
" ",
|
|
44
44
|
/* @__PURE__ */ jsx("span", { "data-menu-item-badge": "", className: "flex shrink-0 items-center", children: badge })
|
|
@@ -46,7 +46,7 @@ const MenuItem = forwardRef(function MenuItem2({
|
|
|
46
46
|
] }),
|
|
47
47
|
(trailing != null || on) && /* @__PURE__ */ jsxs("span", { className: "flex shrink-0 items-center gap-2", children: [
|
|
48
48
|
trailing,
|
|
49
|
-
on && /* @__PURE__ */ jsx(Check, { className: "size-4 text-
|
|
49
|
+
on && /* @__PURE__ */ jsx(Check, { className: "size-4 text-secondary", "aria-hidden": true })
|
|
50
50
|
] })
|
|
51
51
|
] });
|
|
52
52
|
if (href !== void 0 && !disabled) {
|
|
@@ -80,7 +80,7 @@ const MenuItem = forwardRef(function MenuItem2({
|
|
|
80
80
|
children: body
|
|
81
81
|
}
|
|
82
82
|
);
|
|
83
|
-
}
|
|
83
|
+
}
|
|
84
84
|
function RenderedLink({
|
|
85
85
|
render,
|
|
86
86
|
...props
|