@eifi1/ui-kit 0.54.0 → 0.55.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +90 -76
- package/dist/admin/plan-change.js +2 -2
- package/dist/admin/plan-change.js.map +1 -1
- package/dist/admin/user-roster.d.ts +6 -0
- package/dist/admin/user-roster.js +4 -0
- package/dist/admin/user-roster.js.map +1 -1
- package/dist/billing/billing-labels.d.ts +26 -0
- package/dist/billing/billing-labels.js +9 -0
- package/dist/billing/billing-labels.js.map +1 -1
- package/dist/billing/subscription-standing.d.ts +61 -0
- package/dist/billing/subscription-standing.js +51 -0
- package/dist/billing/subscription-standing.js.map +1 -0
- package/dist/billing/usage-meter.d.ts +52 -0
- package/dist/billing/usage-meter.js +52 -0
- package/dist/billing/usage-meter.js.map +1 -0
- package/dist/chart.d.ts +1 -0
- package/dist/chart.js +4 -0
- package/dist/chart.js.map +1 -1
- package/dist/components/alert-banner.js +2 -3
- package/dist/components/alert-banner.js.map +1 -1
- package/dist/components/amount-input.js +3 -15
- package/dist/components/amount-input.js.map +1 -1
- package/dist/components/autocomplete.js +2 -2
- package/dist/components/autocomplete.js.map +1 -1
- package/dist/components/bulk-action-bar.js +2 -1
- package/dist/components/bulk-action-bar.js.map +1 -1
- package/dist/components/button.d.ts +35 -1
- package/dist/components/button.js +5 -9
- package/dist/components/button.js.map +1 -1
- package/dist/components/calendar-heatmap.js +2 -2
- package/dist/components/calendar-heatmap.js.map +1 -1
- package/dist/components/camera-button.d.ts +89 -0
- package/dist/components/camera-button.js +122 -0
- package/dist/components/camera-button.js.map +1 -0
- package/dist/components/camera-capture.d.ts +66 -0
- package/dist/components/camera-capture.js +190 -0
- package/dist/components/camera-capture.js.map +1 -0
- package/dist/components/camera-labels.d.ts +20 -0
- package/dist/components/camera-labels.js +15 -0
- package/dist/components/camera-labels.js.map +1 -0
- package/dist/components/chart-edge.d.ts +9 -0
- package/dist/components/chart-edge.js +14 -3
- package/dist/components/chart-edge.js.map +1 -1
- package/dist/components/chart-zoom-core.js +34 -29
- package/dist/components/chart-zoom-core.js.map +1 -1
- package/dist/components/checkbox-group.js +1 -1
- package/dist/components/checkbox-group.js.map +1 -1
- package/dist/components/combobox-core.js +3 -2
- package/dist/components/combobox-core.js.map +1 -1
- package/dist/components/combobox.js +2 -2
- package/dist/components/combobox.js.map +1 -1
- package/dist/components/consent-again-notice-labels.d.ts +25 -0
- package/dist/components/consent-again-notice-labels.js +15 -0
- package/dist/components/consent-again-notice-labels.js.map +1 -0
- package/dist/components/consent-again-notice.d.ts +85 -0
- package/dist/components/consent-again-notice.js +94 -0
- package/dist/components/consent-again-notice.js.map +1 -0
- package/dist/components/country-select.js +2 -7
- package/dist/components/country-select.js.map +1 -1
- package/dist/components/currency-select.js +2 -2
- package/dist/components/currency-select.js.map +1 -1
- package/dist/components/danger-confirm.js +2 -2
- package/dist/components/danger-confirm.js.map +1 -1
- package/dist/components/data-table-column-settings.js +2 -2
- package/dist/components/data-table-column-settings.js.map +1 -1
- package/dist/components/data-table-fit.js.map +1 -1
- package/dist/components/data-table-virtual.js +13 -3
- package/dist/components/data-table-virtual.js.map +1 -1
- package/dist/components/date-field.js +2 -2
- package/dist/components/date-field.js.map +1 -1
- package/dist/components/date-picker.js +2 -2
- package/dist/components/date-picker.js.map +1 -1
- package/dist/components/date-range-picker.js +2 -6
- package/dist/components/date-range-picker.js.map +1 -1
- package/dist/components/dialog-frame.d.ts +3 -1
- package/dist/components/dialog-frame.js.map +1 -1
- package/dist/components/dropdown.js +7 -3
- package/dist/components/dropdown.js.map +1 -1
- package/dist/components/entity-combobox.js +2 -2
- package/dist/components/entity-combobox.js.map +1 -1
- package/dist/components/field-parts.d.ts +108 -6
- package/dist/components/field-parts.js +59 -6
- package/dist/components/field-parts.js.map +1 -1
- package/dist/components/field-suggestion-labels.d.ts +2 -0
- package/dist/components/field-suggestion-labels.js +10 -0
- package/dist/components/field-suggestion-labels.js.map +1 -0
- package/dist/components/field.js +1 -1
- package/dist/components/field.js.map +1 -1
- package/dist/components/file-button.d.ts +1 -1
- package/dist/components/file-button.js.map +1 -1
- package/dist/components/floating-panel.d.ts +7 -6
- package/dist/components/floating-panel.js +3 -17
- package/dist/components/floating-panel.js.map +1 -1
- package/dist/components/form-actions.d.ts +3 -2
- package/dist/components/form-actions.js.map +1 -1
- package/dist/components/hover-menu.js +3 -2
- package/dist/components/hover-menu.js.map +1 -1
- package/dist/components/icon-button.d.ts +23 -5
- package/dist/components/icon-button.js +6 -8
- package/dist/components/icon-button.js.map +1 -1
- package/dist/components/inline-confirm.js +2 -1
- package/dist/components/inline-confirm.js.map +1 -1
- package/dist/components/inline-entity-combobox.js +2 -2
- package/dist/components/inline-entity-combobox.js.map +1 -1
- package/dist/components/input.js +2 -2
- package/dist/components/input.js.map +1 -1
- package/dist/components/jump-calendar.js +3 -3
- package/dist/components/jump-calendar.js.map +1 -1
- package/dist/components/legal.d.ts +13 -1
- package/dist/components/legal.js +12 -0
- package/dist/components/legal.js.map +1 -1
- package/dist/components/legended-series-chart.d.ts +80 -0
- package/dist/components/legended-series-chart.js +70 -0
- package/dist/components/legended-series-chart.js.map +1 -0
- package/dist/components/lightbox.js +2 -1
- package/dist/components/lightbox.js.map +1 -1
- package/dist/components/mini-calendar.js +13 -5
- package/dist/components/mini-calendar.js.map +1 -1
- package/dist/components/modal.d.ts +23 -2
- package/dist/components/modal.js +24 -6
- package/dist/components/modal.js.map +1 -1
- package/dist/components/month-picker.d.ts +1 -1
- package/dist/components/month-picker.js +6 -6
- package/dist/components/month-picker.js.map +1 -1
- package/dist/components/multi-entity-combobox.js +2 -2
- package/dist/components/multi-entity-combobox.js.map +1 -1
- package/dist/components/multi-select.js +2 -6
- package/dist/components/multi-select.js.map +1 -1
- package/dist/components/number-input.js +2 -2
- package/dist/components/number-input.js.map +1 -1
- package/dist/components/page-header-layout.d.ts +18 -0
- package/dist/components/page-header-layout.js +23 -0
- package/dist/components/page-header-layout.js.map +1 -0
- package/dist/components/page-header-skeleton.d.ts +41 -0
- package/dist/components/page-header-skeleton.js +52 -0
- package/dist/components/page-header-skeleton.js.map +1 -0
- package/dist/components/page-header.js +4 -17
- package/dist/components/page-header.js.map +1 -1
- package/dist/components/popover.js +7 -2
- package/dist/components/popover.js.map +1 -1
- package/dist/components/release-notes-labels.d.ts +16 -0
- package/dist/components/release-notes-labels.js +18 -0
- package/dist/components/release-notes-labels.js.map +1 -0
- package/dist/components/release-notes.d.ts +65 -0
- package/dist/components/release-notes.js +65 -0
- package/dist/components/release-notes.js.map +1 -0
- package/dist/components/select.js +2 -2
- package/dist/components/select.js.map +1 -1
- package/dist/components/series-chart-labels.d.ts +9 -0
- package/dist/components/series-chart-labels.js +3 -1
- package/dist/components/series-chart-labels.js.map +1 -1
- package/dist/components/series-chart.d.ts +5 -0
- package/dist/components/series-chart.js +89 -36
- package/dist/components/series-chart.js.map +1 -1
- package/dist/components/toggle-group.js +3 -2
- package/dist/components/toggle-group.js.map +1 -1
- package/dist/components/treemap-layout.js.map +1 -1
- package/dist/components/treemap.d.ts +17 -15
- package/dist/components/treemap.js +167 -85
- package/dist/components/treemap.js.map +1 -1
- package/dist/eslint/index.js +1 -1
- package/dist/eslint/role-utilities.d.ts +2 -2
- package/dist/eslint/role-utilities.js.map +1 -1
- package/dist/feedback/feedback-inbox-page.d.ts +260 -0
- package/dist/feedback/feedback-inbox-page.js +207 -0
- package/dist/feedback/feedback-inbox-page.js.map +1 -0
- package/dist/feedback/feedback-vocabulary.js +2 -2
- package/dist/feedback/feedback-vocabulary.js.map +1 -1
- package/dist/feedback.d.ts +1 -0
- package/dist/feedback.js +6 -0
- package/dist/feedback.js.map +1 -1
- package/dist/hooks/use-debounce.d.ts +32 -5
- package/dist/hooks/use-debounce.js +6 -5
- package/dist/hooks/use-debounce.js.map +1 -1
- package/dist/hooks/use-file-picker.d.ts +3 -1
- package/dist/hooks/use-file-picker.js.map +1 -1
- package/dist/hooks/use-focus-trap.d.ts +19 -3
- package/dist/hooks/use-focus-trap.js +15 -5
- package/dist/hooks/use-focus-trap.js.map +1 -1
- package/dist/hooks/use-has-camera.d.ts +36 -0
- package/dist/hooks/use-has-camera.js +53 -0
- package/dist/hooks/use-has-camera.js.map +1 -0
- package/dist/hooks/use-hotkey.js +1 -10
- package/dist/hooks/use-hotkey.js.map +1 -1
- package/dist/hooks/use-overlay-history.d.ts +6 -1
- package/dist/hooks/use-overlay-history.js +10 -2
- package/dist/hooks/use-overlay-history.js.map +1 -1
- package/dist/i18n/defaults.js +11 -1
- package/dist/i18n/defaults.js.map +1 -1
- package/dist/i18n/german.js +75 -3
- package/dist/i18n/german.js.map +1 -1
- package/dist/i18n/kit-labels.d.ts +20 -0
- package/dist/i18n/kit-labels.js.map +1 -1
- package/dist/i18n/locales/en.js +92 -4
- package/dist/i18n/locales/en.js.map +3 -3
- package/dist/i18n/locales/es.js +71 -3
- package/dist/i18n/locales/es.js.map +1 -1
- package/dist/i18n/locales/fr.js +72 -2
- package/dist/i18n/locales/fr.js.map +1 -1
- package/dist/i18n/locales/hu.js +74 -3
- package/dist/i18n/locales/hu.js.map +1 -1
- package/dist/i18n/locales/it.js +74 -3
- package/dist/i18n/locales/it.js.map +1 -1
- package/dist/i18n/locales/zh.js +71 -3
- package/dist/i18n/locales/zh.js.map +1 -1
- package/dist/i18n/review.js +22 -1
- package/dist/i18n/review.js.map +1 -1
- package/dist/index.d.ts +24 -5
- package/dist/index.js +35 -1
- package/dist/index.js.map +1 -1
- package/dist/landing/landing-labels.d.ts +8 -0
- package/dist/landing/landing-labels.js +2 -1
- package/dist/landing/landing-labels.js.map +1 -1
- package/dist/lib/changelog.d.ts +130 -0
- package/dist/lib/changelog.js +137 -0
- package/dist/lib/changelog.js.map +1 -0
- package/dist/lib/clipboard-minus.js +2 -2
- package/dist/lib/clipboard-minus.js.map +1 -1
- package/dist/lib/dates.d.ts +29 -3
- package/dist/lib/dates.js +41 -12
- package/dist/lib/dates.js.map +1 -1
- package/dist/lib/editable-content.d.ts +33 -0
- package/dist/lib/editable-content.js +15 -0
- package/dist/lib/editable-content.js.map +1 -0
- package/dist/lib/focus-left.d.ts +47 -1
- package/dist/lib/focus-left.js +11 -2
- package/dist/lib/focus-left.js.map +1 -1
- package/dist/lib/server-wake.d.ts +49 -9
- package/dist/lib/server-wake.js +25 -14
- package/dist/lib/server-wake.js.map +1 -1
- package/dist/lib/session-refresh.d.ts +53 -0
- package/dist/lib/session-refresh.js +27 -1
- package/dist/lib/session-refresh.js.map +1 -1
- package/dist/rhf/fields.js +3 -3
- package/dist/rhf/fields.js.map +1 -1
- package/dist/shell/app-shell.d.ts +25 -1
- package/dist/shell/app-shell.js +3 -1
- package/dist/shell/app-shell.js.map +1 -1
- package/dist/shell/dev-menu.d.ts +3 -0
- package/dist/shell/dev-menu.js +4 -2
- package/dist/shell/dev-menu.js.map +1 -1
- package/dist/shell/held-changes-banner-labels.d.ts +23 -0
- package/dist/shell/held-changes-banner-labels.js +14 -0
- package/dist/shell/held-changes-banner-labels.js.map +1 -0
- package/dist/shell/held-changes-banner.d.ts +75 -0
- package/dist/shell/held-changes-banner.js +106 -0
- package/dist/shell/held-changes-banner.js.map +1 -0
- package/dist/shell/sync-status-indicator.d.ts +27 -12
- package/dist/shell/sync-status-indicator.js +13 -4
- package/dist/shell/sync-status-indicator.js.map +1 -1
- package/dist/shell/top-bar-parts-labels.d.ts +5 -0
- package/dist/shell/top-bar-parts-labels.js +3 -1
- package/dist/shell/top-bar-parts-labels.js.map +1 -1
- package/dist/shell.d.ts +2 -0
- package/dist/shell.js +3 -0
- package/dist/shell.js.map +1 -1
- package/dist/sync/engine.d.ts +11 -2
- package/dist/sync/engine.js +13 -5
- package/dist/sync/engine.js.map +1 -1
- package/dist/sync/hooks.d.ts +3 -2
- package/dist/sync/hooks.js +4 -2
- package/dist/sync/hooks.js.map +1 -1
- package/dist/testing/css-variables.generated.d.ts +2 -2
- package/dist/testing/css-variables.generated.js +1 -1
- package/dist/testing/css-variables.generated.js.map +1 -1
- package/dist/theme/chart-palette.d.ts +18 -0
- package/dist/theme/chart-palette.js +17 -1
- package/dist/theme/chart-palette.js.map +1 -1
- package/dist/theme/contrast-tokens.d.ts +3 -3
- package/dist/theme/contrast-tokens.js.map +1 -1
- package/dist/theme/contrast.d.ts +4 -4
- package/dist/theme/contrast.js.map +1 -1
- package/dist/tour/tour-overlay.js +2 -1
- package/dist/tour/tour-overlay.js.map +1 -1
- package/package.json +5 -9
- package/tokens.css +19 -54
- package/src/account/account-parts.ts +0 -47
- package/src/account/account-settings-labels.ts +0 -240
- package/src/account/account-settings.tsx +0 -698
- package/src/account/data-export-setting-labels.ts +0 -20
- package/src/account/data-export-setting.tsx +0 -200
- package/src/account/delete-account-setting-labels.ts +0 -33
- package/src/account/delete-account-setting.tsx +0 -342
- package/src/account/email-change-setting-labels.ts +0 -31
- package/src/account/email-change-setting.tsx +0 -443
- package/src/account/passkeys-setting.tsx +0 -445
- package/src/account/sessions-setting-labels.ts +0 -24
- package/src/account/sessions-setting.tsx +0 -283
- package/src/admin/admin-action-confirm-labels.ts +0 -19
- package/src/admin/admin-action-confirm.tsx +0 -509
- package/src/admin/admin-action-log-labels.ts +0 -83
- package/src/admin/admin-action-log.tsx +0 -464
- package/src/admin/admin-area-labels.ts +0 -114
- package/src/admin/admin-forbidden.tsx +0 -75
- package/src/admin/admin-overview.tsx +0 -258
- package/src/admin/admin-parts.ts +0 -68
- package/src/admin/admin-sections.tsx +0 -208
- package/src/admin/admin-tool-links.tsx +0 -90
- package/src/admin/invitations-panel-labels.ts +0 -31
- package/src/admin/invitations-panel.tsx +0 -516
- package/src/admin/mail-test-card-labels.ts +0 -19
- package/src/admin/mail-test-card.tsx +0 -189
- package/src/admin/plan-change-labels.ts +0 -5
- package/src/admin/plan-change.tsx +0 -474
- package/src/admin/reviewer-scope-editor-labels.ts +0 -16
- package/src/admin/reviewer-scope-editor.tsx +0 -224
- package/src/admin/role-select-labels.ts +0 -16
- package/src/admin/role-select.tsx +0 -282
- package/src/admin/transfer-ownership-dialog-labels.ts +0 -20
- package/src/admin/transfer-ownership-dialog.tsx +0 -162
- package/src/admin/user-roster-labels.ts +0 -17
- package/src/admin/user-roster.tsx +0 -559
- package/src/auth/accept-invitation-labels.ts +0 -21
- package/src/auth/accept-invitation.tsx +0 -210
- package/src/auth/auth-errors-labels.ts +0 -23
- package/src/auth/auth-errors.ts +0 -439
- package/src/auth/complete-name-dialog-labels.ts +0 -16
- package/src/auth/complete-name-dialog.tsx +0 -253
- package/src/auth/email-tag.ts +0 -75
- package/src/auth/forgot-password-form-labels.ts +0 -20
- package/src/auth/forgot-password-form.tsx +0 -221
- package/src/auth/form-rules.ts +0 -40
- package/src/auth/new-password-fields.tsx +0 -85
- package/src/auth/not-found-page-labels.ts +0 -12
- package/src/auth/not-found-page.tsx +0 -95
- package/src/auth/register-form-labels.ts +0 -31
- package/src/auth/register-form.tsx +0 -456
- package/src/auth/reset-password-form-labels.ts +0 -27
- package/src/auth/reset-password-form.tsx +0 -341
- package/src/auth/sign-in-form-labels.ts +0 -44
- package/src/auth/sign-in-form.tsx +0 -858
- package/src/auth/status-parts.tsx +0 -132
- package/src/auth/verify-email-labels.ts +0 -26
- package/src/auth/verify-email.tsx +0 -445
- package/src/billing/billing-banner.tsx +0 -258
- package/src/billing/billing-labels.ts +0 -381
- package/src/billing/billing-lock.ts +0 -108
- package/src/billing/billing-overview.ts +0 -157
- package/src/billing/billing-standing.ts +0 -80
- package/src/billing/cancel-request.ts +0 -97
- package/src/billing/cancel-subscription.tsx +0 -98
- package/src/billing/checkout-processing.ts +0 -394
- package/src/billing/checkout-return.ts +0 -90
- package/src/billing/pay-page.ts +0 -330
- package/src/billing/plan-card.tsx +0 -562
- package/src/billing/plan-change-labels.ts +0 -66
- package/src/billing/plan-limit-notice.tsx +0 -148
- package/src/billing/plan-limit-toast.tsx +0 -90
- package/src/billing/plan-limit.ts +0 -52
- package/src/billing/plan-price.ts +0 -98
- package/src/billing/plan-switch.tsx +0 -216
- package/src/billing/provider-page.ts +0 -84
- package/src/billing/subscription-actions.tsx +0 -247
- package/src/billing/subscription-status-chip.tsx +0 -95
- package/src/chart.ts +0 -103
- package/src/components/account-chips-labels.ts +0 -16
- package/src/components/account-chips.tsx +0 -474
- package/src/components/alert-banner.tsx +0 -670
- package/src/components/amount-input.tsx +0 -816
- package/src/components/appearance-labels.ts +0 -63
- package/src/components/authed-image-labels.ts +0 -11
- package/src/components/authed-image.tsx +0 -209
- package/src/components/autocomplete.tsx +0 -645
- package/src/components/breadcrumbs-labels.ts +0 -10
- package/src/components/breadcrumbs.tsx +0 -205
- package/src/components/bulk-action-bar-labels.ts +0 -11
- package/src/components/bulk-action-bar.tsx +0 -443
- package/src/components/button-group.tsx +0 -223
- package/src/components/button-look.ts +0 -256
- package/src/components/button.tsx +0 -339
- package/src/components/calculator.tsx +0 -341
- package/src/components/calendar-heatmap-labels.ts +0 -15
- package/src/components/calendar-heatmap.tsx +0 -600
- package/src/components/card.tsx +0 -377
- package/src/components/chart-edge.ts +0 -106
- package/src/components/chart-figure.tsx +0 -35
- package/src/components/chart-height.ts +0 -30
- package/src/components/chart-zoom-core.tsx +0 -627
- package/src/components/chart-zoom.tsx +0 -22
- package/src/components/chart.tsx +0 -554
- package/src/components/checkbox-group.tsx +0 -247
- package/src/components/checkbox.tsx +0 -346
- package/src/components/chip-input.tsx +0 -370
- package/src/components/chip-labels.ts +0 -13
- package/src/components/chip.tsx +0 -843
- package/src/components/choice-card.tsx +0 -544
- package/src/components/column-mapper-labels.ts +0 -38
- package/src/components/column-mapper.tsx +0 -655
- package/src/components/combobox-core.tsx +0 -1321
- package/src/components/combobox-suggestions.tsx +0 -131
- package/src/components/combobox.tsx +0 -716
- package/src/components/confirm-context.ts +0 -7
- package/src/components/confirm-dialog-labels.ts +0 -13
- package/src/components/confirm-dialog.tsx +0 -341
- package/src/components/copy-button-labels.ts +0 -13
- package/src/components/copy-button.tsx +0 -192
- package/src/components/country-select-labels.ts +0 -11
- package/src/components/country-select.tsx +0 -539
- package/src/components/currency-option-list.tsx +0 -188
- package/src/components/currency-select.tsx +0 -343
- package/src/components/danger-confirm-labels.ts +0 -20
- package/src/components/danger-confirm.tsx +0 -987
- package/src/components/data-table-cells.tsx +0 -118
- package/src/components/data-table-column-settings.tsx +0 -198
- package/src/components/data-table-filter-popover.tsx +0 -289
- package/src/components/data-table-filters.ts +0 -315
- package/src/components/data-table-fit.ts +0 -301
- package/src/components/data-table-groups.tsx +0 -288
- package/src/components/data-table-head.tsx +0 -280
- package/src/components/data-table-labels.ts +0 -198
- package/src/components/data-table-leading-row.tsx +0 -58
- package/src/components/data-table-mobile.tsx +0 -1117
- package/src/components/data-table-pagination.tsx +0 -202
- package/src/components/data-table-resize.ts +0 -188
- package/src/components/data-table-row-actions.tsx +0 -302
- package/src/components/data-table-row.tsx +0 -496
- package/src/components/data-table-selection.ts +0 -71
- package/src/components/data-table-shared.tsx +0 -287
- package/src/components/data-table-sort.ts +0 -163
- package/src/components/data-table-virtual.ts +0 -576
- package/src/components/data-table.tsx +0 -2598
- package/src/components/date-field.tsx +0 -684
- package/src/components/date-format-setting.tsx +0 -64
- package/src/components/date-picker.tsx +0 -404
- package/src/components/date-range-picker.tsx +0 -518
- package/src/components/description-list-labels.ts +0 -9
- package/src/components/description-list.tsx +0 -386
- package/src/components/dialog-frame-labels.ts +0 -7
- package/src/components/dialog-frame.tsx +0 -284
- package/src/components/disclosure.tsx +0 -476
- package/src/components/dropdown.tsx +0 -461
- package/src/components/empty-state.tsx +0 -136
- package/src/components/entity-combobox.tsx +0 -422
- package/src/components/error-boundary-labels.ts +0 -20
- package/src/components/error-boundary.tsx +0 -675
- package/src/components/facing-pair.ts +0 -93
- package/src/components/field-base-labels.ts +0 -20
- package/src/components/field-base.tsx +0 -656
- package/src/components/field-parts.tsx +0 -825
- package/src/components/field-strip.tsx +0 -129
- package/src/components/field.tsx +0 -206
- package/src/components/file-button.tsx +0 -295
- package/src/components/file-dropzone.tsx +0 -559
- package/src/components/floating-panel-labels.ts +0 -10
- package/src/components/floating-panel.tsx +0 -828
- package/src/components/focus-ring.ts +0 -16
- package/src/components/form-actions-labels.ts +0 -11
- package/src/components/form-actions.tsx +0 -578
- package/src/components/full-bleed-dialog.tsx +0 -294
- package/src/components/grouped-picker.tsx +0 -184
- package/src/components/help-popover.tsx +0 -117
- package/src/components/hover-menu.tsx +0 -343
- package/src/components/iban-input-labels.ts +0 -14
- package/src/components/iban-input.tsx +0 -236
- package/src/components/icon-button.tsx +0 -959
- package/src/components/icon-picker-labels.ts +0 -13
- package/src/components/icon-picker.tsx +0 -232
- package/src/components/image-grid-labels.ts +0 -11
- package/src/components/image-grid.tsx +0 -202
- package/src/components/inline-confirm.tsx +0 -116
- package/src/components/inline-edit-field-labels.ts +0 -11
- package/src/components/inline-edit-field.tsx +0 -552
- package/src/components/inline-entity-combobox.tsx +0 -849
- package/src/components/input.tsx +0 -394
- package/src/components/jump-calendar.tsx +0 -265
- package/src/components/language-select.tsx +0 -93
- package/src/components/legal-labels.ts +0 -105
- package/src/components/legal-page.tsx +0 -711
- package/src/components/legal.tsx +0 -668
- package/src/components/lightbox-labels.ts +0 -18
- package/src/components/lightbox.tsx +0 -399
- package/src/components/line-items-labels.ts +0 -14
- package/src/components/line-items.tsx +0 -602
- package/src/components/list-labels.ts +0 -12
- package/src/components/list.tsx +0 -870
- package/src/components/loading-state.tsx +0 -78
- package/src/components/measured-grid-labels.ts +0 -25
- package/src/components/measured-grid.tsx +0 -837
- package/src/components/menu-item.tsx +0 -241
- package/src/components/mini-calendar-labels.ts +0 -17
- package/src/components/mini-calendar.tsx +0 -792
- package/src/components/modal.tsx +0 -534
- package/src/components/money-draft.ts +0 -83
- package/src/components/money-field.tsx +0 -76
- package/src/components/month-grid.tsx +0 -229
- package/src/components/month-picker-labels.ts +0 -22
- package/src/components/month-picker.tsx +0 -1087
- package/src/components/multi-entity-combobox.tsx +0 -369
- package/src/components/multi-select.tsx +0 -376
- package/src/components/nav-pills.tsx +0 -198
- package/src/components/number-field.tsx +0 -327
- package/src/components/number-input.tsx +0 -559
- package/src/components/numeric-field.ts +0 -169
- package/src/components/numpad-sheet.tsx +0 -285
- package/src/components/one-time-code-input.tsx +0 -270
- package/src/components/page-contents-labels.ts +0 -9
- package/src/components/page-contents.tsx +0 -282
- package/src/components/page-header-context.ts +0 -8
- package/src/components/page-header.tsx +0 -298
- package/src/components/password-strength-labels.ts +0 -22
- package/src/components/password-strength.tsx +0 -241
- package/src/components/phone-input-labels.ts +0 -10
- package/src/components/phone-input.tsx +0 -282
- package/src/components/picker-sheet.tsx +0 -330
- package/src/components/pie-chart-labels.ts +0 -40
- package/src/components/pie-chart.tsx +0 -480
- package/src/components/popover-labels.ts +0 -14
- package/src/components/popover.tsx +0 -268
- package/src/components/progress-bar-labels.ts +0 -10
- package/src/components/progress-bar.tsx +0 -479
- package/src/components/qr-code.tsx +0 -76
- package/src/components/reauth-dialog-labels.ts +0 -13
- package/src/components/reauth-dialog.tsx +0 -265
- package/src/components/row-actions-labels.ts +0 -12
- package/src/components/row-actions.tsx +0 -795
- package/src/components/scroll-area.tsx +0 -123
- package/src/components/search-field.tsx +0 -192
- package/src/components/select.tsx +0 -294
- package/src/components/separator.tsx +0 -33
- package/src/components/series-chart-axes.ts +0 -342
- package/src/components/series-chart-budget.ts +0 -150
- package/src/components/series-chart-labels.ts +0 -33
- package/src/components/series-chart-thin.ts +0 -180
- package/src/components/series-chart-ticks.ts +0 -194
- package/src/components/series-chart.tsx +0 -1906
- package/src/components/server-wake-labels.ts +0 -11
- package/src/components/server-wake.tsx +0 -129
- package/src/components/settings-fields.tsx +0 -237
- package/src/components/share-card-labels.ts +0 -30
- package/src/components/share-card.tsx +0 -675
- package/src/components/signature-pad-labels.ts +0 -24
- package/src/components/signature-pad.tsx +0 -747
- package/src/components/signed-amount-labels.ts +0 -10
- package/src/components/signed-amount.tsx +0 -336
- package/src/components/skeleton.tsx +0 -80
- package/src/components/slider.tsx +0 -338
- package/src/components/sparkline-labels.ts +0 -14
- package/src/components/sparkline.tsx +0 -322
- package/src/components/spinner.tsx +0 -81
- package/src/components/stat-tile-labels.ts +0 -15
- package/src/components/stat-tile.tsx +0 -754
- package/src/components/status-dot.tsx +0 -170
- package/src/components/swatch-picker-labels.ts +0 -10
- package/src/components/swatch-picker.tsx +0 -283
- package/src/components/swipeable-row.tsx +0 -386
- package/src/components/switch.tsx +0 -273
- package/src/components/table-skeleton.tsx +0 -136
- package/src/components/table.tsx +0 -647
- package/src/components/tabs-labels.ts +0 -13
- package/src/components/tabs.tsx +0 -693
- package/src/components/text-link.tsx +0 -359
- package/src/components/text.tsx +0 -150
- package/src/components/textarea.tsx +0 -330
- package/src/components/tile-radio.tsx +0 -332
- package/src/components/time-input.tsx +0 -121
- package/src/components/toast-labels.ts +0 -12
- package/src/components/toast.tsx +0 -519
- package/src/components/toggle-group.tsx +0 -752
- package/src/components/toggle-legend.tsx +0 -394
- package/src/components/tooltip.tsx +0 -1149
- package/src/components/translation-review-editor.tsx +0 -290
- package/src/components/translation-review-labels.ts +0 -181
- package/src/components/translation-review-parts.tsx +0 -272
- package/src/components/translation-review.tsx +0 -1240
- package/src/components/tree-view.tsx +0 -589
- package/src/components/treemap-labels.ts +0 -47
- package/src/components/treemap-layout.ts +0 -210
- package/src/components/treemap.tsx +0 -1184
- package/src/components/trigger-aria.ts +0 -44
- package/src/components/use-anchor-dir.ts +0 -20
- package/src/components/use-mobile-reveal.ts +0 -62
- package/src/components/use-table-state.ts +0 -753
- package/src/components/user-avatar.tsx +0 -116
- package/src/components/wizard-stepper.tsx +0 -42
- package/src/components/write-lock-labels.ts +0 -10
- package/src/components/write-lock.tsx +0 -253
- package/src/currencies.ts +0 -90
- package/src/data-table.ts +0 -42
- package/src/demo/demo-banner.tsx +0 -153
- package/src/demo/demo-countdown.ts +0 -136
- package/src/demo/demo-ended.tsx +0 -90
- package/src/demo/demo-labels.ts +0 -78
- package/src/demo/demo-session.ts +0 -32
- package/src/demo/demo-start.tsx +0 -156
- package/src/eslint/index.ts +0 -161
- package/src/eslint/role-utilities.generated.ts +0 -146
- package/src/eslint/role-utilities.ts +0 -233
- package/src/feedback/feedback-attachment-download.tsx +0 -77
- package/src/feedback/feedback-attachment-labels.ts +0 -37
- package/src/feedback/feedback-attachment.tsx +0 -1239
- package/src/feedback/feedback-capture.ts +0 -287
- package/src/feedback/feedback-comment-thread.tsx +0 -353
- package/src/feedback/feedback-context-labels.ts +0 -11
- package/src/feedback/feedback-context.tsx +0 -245
- package/src/feedback/feedback-crash.ts +0 -547
- package/src/feedback/feedback-diagnostics.tsx +0 -41
- package/src/feedback/feedback-dialog-labels.ts +0 -29
- package/src/feedback/feedback-dialog.tsx +0 -452
- package/src/feedback/feedback-entry-file.tsx +0 -150
- package/src/feedback/feedback-inbox.tsx +0 -552
- package/src/feedback/feedback-labels.ts +0 -144
- package/src/feedback/feedback-menu-labels.ts +0 -12
- package/src/feedback/feedback-menu.tsx +0 -177
- package/src/feedback/feedback-mutation.ts +0 -20
- package/src/feedback/feedback-page-link.ts +0 -90
- package/src/feedback/feedback-public-labels.ts +0 -81
- package/src/feedback/feedback-public-list.tsx +0 -524
- package/src/feedback/feedback-public-switch.tsx +0 -102
- package/src/feedback/feedback-public-types.ts +0 -101
- package/src/feedback/feedback-record.ts +0 -428
- package/src/feedback/feedback-replies-context.ts +0 -9
- package/src/feedback/feedback-replies.tsx +0 -343
- package/src/feedback/feedback-rework-entry-chip.tsx +0 -18
- package/src/feedback/feedback-row-detail-labels.ts +0 -31
- package/src/feedback/feedback-row-detail.tsx +0 -871
- package/src/feedback/feedback-status-undo.ts +0 -109
- package/src/feedback/feedback-submit-dialog.tsx +0 -131
- package/src/feedback/feedback-submit.tsx +0 -270
- package/src/feedback/feedback-swipe.tsx +0 -192
- package/src/feedback/feedback-table-labels.ts +0 -27
- package/src/feedback/feedback-table.tsx +0 -912
- package/src/feedback/feedback-thread-labels.ts +0 -22
- package/src/feedback/feedback-thread-parts-labels.ts +0 -41
- package/src/feedback/feedback-thread.tsx +0 -905
- package/src/feedback/feedback-vocabulary.ts +0 -263
- package/src/feedback/feedback-vote-button.tsx +0 -124
- package/src/feedback.ts +0 -116
- package/src/hooks/use-anchored-panel.ts +0 -396
- package/src/hooks/use-anchored-rect.ts +0 -77
- package/src/hooks/use-announce.ts +0 -85
- package/src/hooks/use-authed-src.ts +0 -167
- package/src/hooks/use-body-scroll-lock.ts +0 -119
- package/src/hooks/use-breakpoint.ts +0 -133
- package/src/hooks/use-close-transition.ts +0 -107
- package/src/hooks/use-copy-to-clipboard.ts +0 -122
- package/src/hooks/use-debounce.ts +0 -114
- package/src/hooks/use-dismiss.ts +0 -371
- package/src/hooks/use-document-title.ts +0 -33
- package/src/hooks/use-file-drop.ts +0 -121
- package/src/hooks/use-file-picker-labels.ts +0 -28
- package/src/hooks/use-file-picker.tsx +0 -359
- package/src/hooks/use-focus-trap.ts +0 -199
- package/src/hooks/use-hotkey.ts +0 -212
- package/src/hooks/use-large-text.ts +0 -41
- package/src/hooks/use-long-press.ts +0 -140
- package/src/hooks/use-media-query.ts +0 -39
- package/src/hooks/use-mounted.ts +0 -39
- package/src/hooks/use-noindex.ts +0 -37
- package/src/hooks/use-overlay-history.ts +0 -714
- package/src/hooks/use-row-swipe.ts +0 -207
- package/src/hooks/use-search-param-state.ts +0 -434
- package/src/hooks/use-windowed-rows.ts +0 -225
- package/src/i18n/defaults.ts +0 -267
- package/src/i18n/german.ts +0 -2059
- package/src/i18n/kit-labels.tsx +0 -1003
- package/src/i18n/languages.ts +0 -349
- package/src/i18n/locales/de-CH.ts +0 -24
- package/src/i18n/locales/en.ts +0 -267
- package/src/i18n/locales/es.ts +0 -1999
- package/src/i18n/locales/fr.ts +0 -2037
- package/src/i18n/locales/hu.ts +0 -2004
- package/src/i18n/locales/it.ts +0 -2014
- package/src/i18n/locales/zh.ts +0 -1912
- package/src/i18n/plurals.ts +0 -86
- package/src/i18n/review.ts +0 -475
- package/src/i18n/shared-labels.ts +0 -138
- package/src/i18n/swiss.ts +0 -29
- package/src/index.ts +0 -1191
- package/src/landing/access.ts +0 -93
- package/src/landing/landing-actions.tsx +0 -97
- package/src/landing/landing-labels.ts +0 -59
- package/src/landing/landing-sections.tsx +0 -341
- package/src/landing/page-seo.ts +0 -261
- package/src/landing/public-header.tsx +0 -121
- package/src/landing/public-page.tsx +0 -106
- package/src/landing/routing.tsx +0 -225
- package/src/lib/broadcast.ts +0 -52
- package/src/lib/calc.ts +0 -323
- package/src/lib/chip-edge-snap.ts +0 -212
- package/src/lib/clipboard-minus.ts +0 -107
- package/src/lib/clipping.ts +0 -34
- package/src/lib/cn.ts +0 -28
- package/src/lib/column-mapping.ts +0 -234
- package/src/lib/countries.ts +0 -91
- package/src/lib/data-attributes.ts +0 -14
- package/src/lib/date-format.ts +0 -227
- package/src/lib/dates.ts +0 -288
- package/src/lib/day-format.ts +0 -96
- package/src/lib/decimal-marks.ts +0 -108
- package/src/lib/describe-failure.ts +0 -18
- package/src/lib/device-settings.ts +0 -147
- package/src/lib/direction.ts +0 -74
- package/src/lib/document-navigation.ts +0 -17
- package/src/lib/document-title.ts +0 -41
- package/src/lib/download.ts +0 -172
- package/src/lib/float-clearance.ts +0 -70
- package/src/lib/floating-stack.ts +0 -70
- package/src/lib/focus-left.ts +0 -156
- package/src/lib/format.ts +0 -585
- package/src/lib/http-status.ts +0 -38
- package/src/lib/iban.ts +0 -251
- package/src/lib/ime.ts +0 -24
- package/src/lib/intl-cache.ts +0 -27
- package/src/lib/iso-day.ts +0 -13
- package/src/lib/lazy-with-fallback.ts +0 -82
- package/src/lib/logger.ts +0 -69
- package/src/lib/minus.ts +0 -50
- package/src/lib/path-pattern.ts +0 -55
- package/src/lib/person-name.ts +0 -155
- package/src/lib/phone.ts +0 -208
- package/src/lib/plain-text.ts +0 -22
- package/src/lib/presence.ts +0 -18
- package/src/lib/qr-encode.ts +0 -444
- package/src/lib/quiet-focus.ts +0 -32
- package/src/lib/reduced-motion.ts +0 -22
- package/src/lib/refs.ts +0 -22
- package/src/lib/round.ts +0 -43
- package/src/lib/safe-storage.ts +0 -119
- package/src/lib/server-wake.ts +0 -315
- package/src/lib/session-refresh.ts +0 -472
- package/src/lib/share-format.ts +0 -18
- package/src/lib/status-tone.ts +0 -43
- package/src/lib/strip-fade.ts +0 -287
- package/src/lib/table-text.ts +0 -554
- package/src/lib/text-case.ts +0 -19
- package/src/lib/text-match.ts +0 -169
- package/src/lib/thenable.ts +0 -19
- package/src/lib/translation-review.ts +0 -769
- package/src/notifications/device-zone-report.ts +0 -67
- package/src/notifications/feedback-notification-types-labels.ts +0 -33
- package/src/notifications/feedback-notification-types.ts +0 -71
- package/src/notifications/notification-bell.tsx +0 -119
- package/src/notifications/notification-inbox.tsx +0 -309
- package/src/notifications/notification-parts.tsx +0 -81
- package/src/notifications/notification-types-setting.tsx +0 -406
- package/src/notifications/notification-types.ts +0 -89
- package/src/notifications/notifications-labels.ts +0 -287
- package/src/notifications/push-device-setting.tsx +0 -230
- package/src/notifications/push-devices-setting.tsx +0 -374
- package/src/notifications/push-worker.ts +0 -168
- package/src/notifications/quiet-hours-setting.tsx +0 -238
- package/src/notifications/unsubscribe-panel.tsx +0 -200
- package/src/notifications/use-push-device.ts +0 -448
- package/src/offline/local-first.ts +0 -100
- package/src/offline/pwa-update-prompt-labels.ts +0 -9
- package/src/offline/pwa-update-prompt.tsx +0 -78
- package/src/offline/query-persistence.ts +0 -391
- package/src/offline/service-worker-updates.ts +0 -81
- package/src/offline/shared-computer-labels.ts +0 -8
- package/src/offline/shared-computer.tsx +0 -87
- package/src/offline/sign-out-pending-dialog-labels.ts +0 -21
- package/src/offline/sign-out-pending-dialog.tsx +0 -135
- package/src/offline.ts +0 -37
- package/src/push-worker.ts +0 -25
- package/src/rhf/fields.tsx +0 -2187
- package/src/rhf/form-core.tsx +0 -324
- package/src/rhf/form.tsx +0 -12
- package/src/rhf/line-items.tsx +0 -135
- package/src/rhf/use-rhf-wizard-step.ts +0 -104
- package/src/rhf.ts +0 -21
- package/src/search/command-palette-labels.ts +0 -16
- package/src/search/command-palette.tsx +0 -624
- package/src/search/global-search-labels.ts +0 -13
- package/src/search/global-search.tsx +0 -660
- package/src/search/search-index.ts +0 -283
- package/src/search/use-command-key.ts +0 -23
- package/src/search.ts +0 -14
- package/src/settings/device-reset-setting-labels.ts +0 -20
- package/src/settings/device-reset-setting.tsx +0 -116
- package/src/settings/settings-card-classes.ts +0 -11
- package/src/settings/settings-catalogue.ts +0 -150
- package/src/settings/settings-context.ts +0 -33
- package/src/settings/settings-heading.tsx +0 -67
- package/src/settings/settings-labels.ts +0 -87
- package/src/settings/settings-layout.tsx +0 -471
- package/src/settings/settings-section.tsx +0 -108
- package/src/settings/use-account-appearance.ts +0 -148
- package/src/settings/use-account-language.ts +0 -146
- package/src/settings/use-settings-focus.ts +0 -128
- package/src/settings/use-settings-route.ts +0 -258
- package/src/shell/account-menu-language.tsx +0 -130
- package/src/shell/account-menu-text-size.tsx +0 -80
- package/src/shell/admin-menu.tsx +0 -183
- package/src/shell/app-shell-labels.ts +0 -11
- package/src/shell/app-shell.tsx +0 -1560
- package/src/shell/auth-layout.tsx +0 -186
- package/src/shell/company-switcher-labels.ts +0 -13
- package/src/shell/company-switcher.tsx +0 -136
- package/src/shell/dev-menu.tsx +0 -257
- package/src/shell/fill-height.tsx +0 -45
- package/src/shell/language-code.ts +0 -5
- package/src/shell/option-switcher-menu.tsx +0 -84
- package/src/shell/sync-status-indicator.tsx +0 -303
- package/src/shell/top-bar-actions.tsx +0 -87
- package/src/shell/top-bar-brand.tsx +0 -78
- package/src/shell/top-bar-parts-labels.ts +0 -148
- package/src/shell/top-bar.tsx +0 -40
- package/src/shell/topbar-action-menu.tsx +0 -567
- package/src/shell/topbar-controls.tsx +0 -269
- package/src/shell/tour-menu.tsx +0 -187
- package/src/shell.ts +0 -108
- package/src/sync/db.ts +0 -129
- package/src/sync/engine.ts +0 -1011
- package/src/sync/hooks.ts +0 -98
- package/src/sync/testing.ts +0 -73
- package/src/sync/wire.ts +0 -61
- package/src/sync.ts +0 -37
- package/src/table-text.ts +0 -8
- package/src/testing/css-variables.generated.ts +0 -112
- package/src/testing/css-variables.ts +0 -189
- package/src/testing/index.ts +0 -29
- package/src/testing/react.ts +0 -58
- package/src/testing/tour.ts +0 -41
- package/src/testing/viewport.ts +0 -357
- package/src/theme/chart-palette.ts +0 -232
- package/src/theme/color.ts +0 -272
- package/src/theme/contrast-tokens.ts +0 -268
- package/src/theme/contrast.ts +0 -250
- package/src/theme/palette-derive.ts +0 -825
- package/src/theme/palette-presets.ts +0 -544
- package/src/theme/palette-store.ts +0 -108
- package/src/theme/text-size.ts +0 -289
- package/src/theme/theme-store.ts +0 -157
- package/src/tour/tour-catalogue-labels.ts +0 -75
- package/src/tour/tour-catalogue.tsx +0 -335
- package/src/tour/tour-dock.ts +0 -134
- package/src/tour/tour-engine.ts +0 -37
- package/src/tour/tour-gates.ts +0 -218
- package/src/tour/tour-guide-button.tsx +0 -64
- package/src/tour/tour-guide-labels.ts +0 -15
- package/src/tour/tour-info.ts +0 -144
- package/src/tour/tour-labels.ts +0 -23
- package/src/tour/tour-overlay.tsx +0 -1170
- package/src/tour/tour.tsx +0 -750
- package/src/tour/use-tour-progress.ts +0 -671
- package/src/tour/use-tour-url-sync.ts +0 -266
- package/src/tour.ts +0 -21
- package/src/vite-env.d.ts +0 -23
- package/src/wizard/stepper-nav.tsx +0 -360
- package/src/wizard/types.ts +0 -275
- package/src/wizard/use-wizard.ts +0 -560
- package/src/wizard/validation.ts +0 -39
- package/src/wizard/wizard-context.tsx +0 -74
- package/src/wizard/wizard-labels.ts +0 -29
- package/src/wizard/wizard-step.tsx +0 -76
- package/src/wizard/wizard-summary.tsx +0 -84
- package/src/wizard.ts +0 -15
package/src/components/list.tsx
DELETED
|
@@ -1,870 +0,0 @@
|
|
|
1
|
-
import { Children, createContext, useContext, useId, useState } from "react";
|
|
2
|
-
import type { ComponentPropsWithoutRef, HTMLAttributes, MouseEvent, ReactElement, ReactNode, Ref } from "react";
|
|
3
|
-
import { ChevronDown, ExternalLink } from "lucide-react";
|
|
4
|
-
import type { LucideIcon } from "lucide-react";
|
|
5
|
-
import { cn } from "../lib/cn";
|
|
6
|
-
import { hasContent } from "../lib/presence";
|
|
7
|
-
import { FOCUS_RING } from "./focus-ring";
|
|
8
|
-
import { Spinner } from "./spinner";
|
|
9
|
-
import { StatusDot } from "./status-dot";
|
|
10
|
-
import { Collapse } from "./disclosure";
|
|
11
|
-
import { toneTextClass } from "./signed-amount";
|
|
12
|
-
import type { TextTone } from "./signed-amount";
|
|
13
|
-
import { useKitLabels, useKitLink } from "../i18n/kit-labels";
|
|
14
|
-
import { pickLinkRenderer } from "./text-link";
|
|
15
|
-
import { LockedReason, mergeDescribedBy, useLockReason, type DisabledReasonDisplay } from "./field-parts";
|
|
16
|
-
import type { CommitScope } from "./write-lock";
|
|
17
|
-
import { DEFAULT_LIST_LABELS } from "./list-labels";
|
|
18
|
-
import { Button } from "./button";
|
|
19
|
-
|
|
20
|
-
/* ── Labels ───────────────────────────────────────────────────────────────── */
|
|
21
|
-
|
|
22
|
-
export interface ListLabels {
|
|
23
|
-
/** Read after an unread row's title — the dot alone says nothing to a screen reader. */
|
|
24
|
-
unread: string;
|
|
25
|
-
/** Read after an external row's title: the row leaves the app in a new tab. */
|
|
26
|
-
opensInNewTab: string;
|
|
27
|
-
/** 0.51.4: the row under a {@link ListProps.limit}ed list that opens the rest, with
|
|
28
|
-
* the WHOLE list's count — "Show all (12)". Optional, as every key added to a
|
|
29
|
-
* namespace an app may annotate: left out, the provider's, then English. */
|
|
30
|
-
showAll?: (count: number) => string;
|
|
31
|
-
/** 0.51.4: the same row once the list is open, folding it back. */
|
|
32
|
-
showFewer?: string;
|
|
33
|
-
}
|
|
34
|
-
|
|
35
|
-
// Defined in ./list-labels, which holds no component code (0.34, KS U8).
|
|
36
|
-
export { DEFAULT_LIST_LABELS };
|
|
37
|
-
|
|
38
|
-
/* ── List ─────────────────────────────────────────────────────────────────── */
|
|
39
|
-
|
|
40
|
-
/**
|
|
41
|
-
* `compact` 36px-ish rows for a dense panel (an inbox in a menu), `default` the ~44px
|
|
42
|
-
* row every site draws with `py-2.5`, `comfortable` for a list that is the page.
|
|
43
|
-
*/
|
|
44
|
-
export type ListDensity = "compact" | "default" | "comfortable";
|
|
45
|
-
/** `divider`: a rule between rows (kastlan's `divide-y` lists); `gap`: a small space
|
|
46
|
-
* between rows (lenkbank's `space-y-2`, kastlan's `space-y-1`); `none`: flush. */
|
|
47
|
-
export type ListSeparator = "divider" | "gap" | "none";
|
|
48
|
-
|
|
49
|
-
const ListContext = createContext<{ density: ListDensity; separator: ListSeparator }>({
|
|
50
|
-
density: "default",
|
|
51
|
-
separator: "gap",
|
|
52
|
-
});
|
|
53
|
-
|
|
54
|
-
export interface ListProps extends Omit<ComponentPropsWithoutRef<"ul">, "role"> {
|
|
55
|
-
/** `ol` when the order means something (a ranked list, numbered segments). */
|
|
56
|
-
as?: "ul" | "ol";
|
|
57
|
-
/** Every row's density, unless a row says otherwise. Default `default`. */
|
|
58
|
-
density?: ListDensity;
|
|
59
|
-
/** Default `gap`. */
|
|
60
|
-
separator?: ListSeparator;
|
|
61
|
-
/** The `<ul>` (or `<ol>`). A React 19 ref prop since 0.34 (MOD-4, refactor audit
|
|
62
|
-
* 2026-10); it was `forwardRef`. */
|
|
63
|
-
ref?: Ref<HTMLUListElement>;
|
|
64
|
-
/**
|
|
65
|
-
* Show the first `limit` rows, then a "Show all (n)" row that opens the rest and turns
|
|
66
|
-
* into "Show fewer" (0.51.4, keksdose run 89: a long "Placed only roughly" list on its
|
|
67
|
-
* Matching report could only fold as a whole, so it opened as nothing or everything).
|
|
68
|
-
* A list of `limit` rows or fewer draws them all, with no such row. Rows are counted as
|
|
69
|
-
* `Children` counts them: one per `ListItem`, a fragment as one.
|
|
70
|
-
*
|
|
71
|
-
* The row is a button with `aria-expanded`, controlling the list, in the list's last
|
|
72
|
-
* item: a reader hears "list, 6 items" for five rows and the Show all. Until 0.52 that
|
|
73
|
-
* item was `role="none"`, which left the button standing in the list itself — axe 4.13
|
|
74
|
-
* fails `aria-required-children` on it, and a `<ul>` may hold nothing but items (refactor
|
|
75
|
-
* audit 2026-10-30, found building 0.51.7; DataTable's phone list made the same call for
|
|
76
|
-
* its leading row).
|
|
77
|
-
*/
|
|
78
|
-
limit?: number;
|
|
79
|
-
}
|
|
80
|
-
|
|
81
|
-
/** The show-all row's inset, in step with each density's row padding (`PAD`). */
|
|
82
|
-
const MORE_PAD: Record<ListDensity, string> = {
|
|
83
|
-
compact: "px-2 py-1",
|
|
84
|
-
default: "px-3 py-1.5",
|
|
85
|
-
comfortable: "px-4 py-2",
|
|
86
|
-
};
|
|
87
|
-
|
|
88
|
-
/**
|
|
89
|
-
* The list of {@link ListItem}s.
|
|
90
|
-
*
|
|
91
|
-
* A `<ul>` with an explicit `role="list"`: Safari drops a list's semantics once its
|
|
92
|
-
* bullets are styled away, and "list, 7 items" is exactly what a screen-reader user
|
|
93
|
-
* wants to hear before the first row.
|
|
94
|
-
*/
|
|
95
|
-
export function List({
|
|
96
|
-
ref,
|
|
97
|
-
as = "ul",
|
|
98
|
-
density = "default",
|
|
99
|
-
separator = "gap",
|
|
100
|
-
limit,
|
|
101
|
-
className,
|
|
102
|
-
children,
|
|
103
|
-
...rest
|
|
104
|
-
}: ListProps) {
|
|
105
|
-
const Tag = as;
|
|
106
|
-
const labels = useKitLabels("list", DEFAULT_LIST_LABELS);
|
|
107
|
-
const [open, setOpen] = useState(false);
|
|
108
|
-
const generatedId = useId();
|
|
109
|
-
const id = rest.id ?? generatedId;
|
|
110
|
-
const rows = limit === undefined ? null : Children.toArray(children);
|
|
111
|
-
const folds = rows !== null && rows.length > Math.max(0, limit!);
|
|
112
|
-
return (
|
|
113
|
-
<ListContext.Provider value={{ density, separator }}>
|
|
114
|
-
<Tag
|
|
115
|
-
{...rest}
|
|
116
|
-
id={folds ? id : rest.id}
|
|
117
|
-
ref={ref as Ref<HTMLUListElement & HTMLOListElement>}
|
|
118
|
-
role="list"
|
|
119
|
-
className={cn(
|
|
120
|
-
"m-0 flex list-none flex-col p-0",
|
|
121
|
-
separator === "gap" && (density === "compact" ? "gap-0.5" : "gap-1"),
|
|
122
|
-
className,
|
|
123
|
-
)}
|
|
124
|
-
>
|
|
125
|
-
{/* The same array folded and open: `Children.toArray` re-keys every row (`.$a`),
|
|
126
|
-
so the raw `children` on one side remounted the first rows at each toggle and
|
|
127
|
-
dropped their state — an opened row, a typed input (audit 2026-10-30 DSP-20). */}
|
|
128
|
-
{folds && !open ? rows.slice(0, Math.max(0, limit!)) : (rows ?? children)}
|
|
129
|
-
{folds && (
|
|
130
|
-
<li className={MORE_PAD[density]}>
|
|
131
|
-
<Button
|
|
132
|
-
type="button"
|
|
133
|
-
variant="link"
|
|
134
|
-
size="sm"
|
|
135
|
-
className="h-auto p-0"
|
|
136
|
-
aria-expanded={open}
|
|
137
|
-
aria-controls={id}
|
|
138
|
-
onClick={() => setOpen((was) => !was)}
|
|
139
|
-
>
|
|
140
|
-
{open
|
|
141
|
-
? (labels.showFewer ?? DEFAULT_LIST_LABELS.showFewer)
|
|
142
|
-
: (labels.showAll ?? DEFAULT_LIST_LABELS.showAll!)(rows.length)}
|
|
143
|
-
</Button>
|
|
144
|
-
</li>
|
|
145
|
-
)}
|
|
146
|
-
</Tag>
|
|
147
|
-
</ListContext.Provider>
|
|
148
|
-
);
|
|
149
|
-
}
|
|
150
|
-
|
|
151
|
-
/* ── ListItem ─────────────────────────────────────────────────────────────── */
|
|
152
|
-
|
|
153
|
-
/** What {@link ListItemProps.renderLink} is handed. Spread it onto your router's link,
|
|
154
|
-
* mapping `href` to what it calls it — `({ href, ...p }) => <Link to={href} {...p} />`. */
|
|
155
|
-
export interface ListItemLinkProps {
|
|
156
|
-
href: string;
|
|
157
|
-
/** The row's target look — keep it, or the row's padding and focus ring go. */
|
|
158
|
-
className: string;
|
|
159
|
-
children: ReactNode;
|
|
160
|
-
ref?: Ref<HTMLAnchorElement>;
|
|
161
|
-
onClick?: (event: MouseEvent<HTMLAnchorElement>) => void;
|
|
162
|
-
onAuxClick?: (event: MouseEvent<HTMLAnchorElement>) => void;
|
|
163
|
-
"aria-current"?: "true";
|
|
164
|
-
"aria-busy"?: true;
|
|
165
|
-
id?: string;
|
|
166
|
-
[key: `aria-${string}`]: string | boolean | number | undefined;
|
|
167
|
-
[key: `data-${string}`]: unknown;
|
|
168
|
-
}
|
|
169
|
-
|
|
170
|
-
const PAD: Record<ListDensity, { target: string; actions: string; leadingActions: string; gap: string; body: string }> =
|
|
171
|
-
{
|
|
172
|
-
compact: {
|
|
173
|
-
target: "gap-2 px-2 py-1.5",
|
|
174
|
-
actions: "pe-1.5",
|
|
175
|
-
leadingActions: "ps-1.5",
|
|
176
|
-
gap: "gap-0.5",
|
|
177
|
-
body: "px-2 pb-1.5",
|
|
178
|
-
},
|
|
179
|
-
default: {
|
|
180
|
-
target: "gap-3 px-3 py-2.5",
|
|
181
|
-
actions: "pe-2",
|
|
182
|
-
leadingActions: "ps-2",
|
|
183
|
-
gap: "gap-1",
|
|
184
|
-
body: "px-3 pb-2.5",
|
|
185
|
-
},
|
|
186
|
-
comfortable: {
|
|
187
|
-
target: "gap-3 px-4 py-3",
|
|
188
|
-
actions: "pe-3",
|
|
189
|
-
leadingActions: "ps-3",
|
|
190
|
-
gap: "gap-1",
|
|
191
|
-
body: "px-4 pb-3",
|
|
192
|
-
},
|
|
193
|
-
};
|
|
194
|
-
|
|
195
|
-
/** {@link ListItemBaseProps.trailingTone}: a {@link TextTone}, or `inherit` — no
|
|
196
|
-
* colour of the slot's own, so an element's colour (or the row's) stands. */
|
|
197
|
-
export type ListItemTrailingTone = TextTone | "inherit";
|
|
198
|
-
|
|
199
|
-
// The kit's focus frame (§5), inset so the row's own border and its neighbours do not
|
|
200
|
-
// clip it.
|
|
201
|
-
const TARGET_RING = cn(FOCUS_RING, "focus-visible:ring-inset");
|
|
202
|
-
|
|
203
|
-
/**
|
|
204
|
-
* §4 "ListItem: title, subtitle and meta wrap instead of truncating" at Large and Extra
|
|
205
|
-
* large (docs/text-size-harmonization.md). `large:` variants over the Normal look, so
|
|
206
|
-
* a list keeps its one-height rows at Normal and costs no render to switch: a one-line
|
|
207
|
-
* line is `truncate-until-large` (tokens.css, 0.33 §10.17: `truncate`, and at Large a
|
|
208
|
-
* wrap that breaks a word too long for the row — the kit's one name for what this file
|
|
209
|
-
* spelt as `WRAP_AT_LARGE`), a `line-clamp-2` lets go. An ellipsis hides the end of a
|
|
210
|
-
* name, which is the part a reader who needs big type cannot recover by squinting.
|
|
211
|
-
*/
|
|
212
|
-
const UNCLAMP_AT_LARGE = "large:line-clamp-none";
|
|
213
|
-
|
|
214
|
-
interface ListItemBaseProps {
|
|
215
|
-
/** The row's name: one line, truncated — unless {@link titleLines} says otherwise. */
|
|
216
|
-
title: ReactNode;
|
|
217
|
-
/**
|
|
218
|
-
* How many lines the title may take. `1` (default) truncates with an ellipsis, which
|
|
219
|
-
* is right for a name the app chose — a unit number, a user, a file — where the
|
|
220
|
-
* cut-off end is still recognisable and every row keeps one height.
|
|
221
|
-
*
|
|
222
|
-
* `2` clamps at two lines; `"all"` shows every line, breaking inside a long word
|
|
223
|
-
* rather than overflowing. For rows whose only name is free text a person typed
|
|
224
|
-
* (kastlan 44): a defect or a note titled by its description, where the first 30
|
|
225
|
-
* characters on a phone say nothing and there is no other field to tell two rows
|
|
226
|
-
* apart. Pair it with `align="start"` so the icon stays by the first line.
|
|
227
|
-
*/
|
|
228
|
-
titleLines?: 1 | 2 | "all";
|
|
229
|
-
/** The line under it: one line, truncated — or two, with `subtitleLines={2}`. */
|
|
230
|
-
subtitle?: ReactNode;
|
|
231
|
-
/** `2` for a line that is a body rather than a label (keksdose's notification text). */
|
|
232
|
-
subtitleLines?: 1 | 2;
|
|
233
|
-
/**
|
|
234
|
-
* A small line ABOVE the title, in the caption type: the group a row belongs to, a
|
|
235
|
-
* date heading, a category ("Groceries · weekly"). Part of the target and of its
|
|
236
|
-
* name, read before the title. One line, truncated.
|
|
237
|
-
*/
|
|
238
|
-
overline?: ReactNode;
|
|
239
|
-
/** A third line in the caption type: a timestamp, "Updated …" (lenkbank's projects). */
|
|
240
|
-
meta?: ReactNode;
|
|
241
|
-
/**
|
|
242
|
-
* Let {@link meta} wrap: it becomes a wrapping row (`flex-wrap`, a small gap)
|
|
243
|
-
* instead of one truncated line — for a run of chips (keksdose's payee-backfill
|
|
244
|
-
* tags), which otherwise had nowhere to go but the body, outside the target. Still
|
|
245
|
-
* inside the target, so still no controls: chips that only show, not ones that
|
|
246
|
-
* remove themselves.
|
|
247
|
-
*/
|
|
248
|
-
metaWrap?: boolean;
|
|
249
|
-
/**
|
|
250
|
-
* Content INSIDE the main target, under the title, subtitle and meta: a progress or
|
|
251
|
-
* budget bar, a sparkline, a strip of figures (keksdose's food-group bars). Unlike
|
|
252
|
-
* {@link children}, which sits outside the target, a click on it is a click on the
|
|
253
|
-
* row, and its hover fill covers it.
|
|
254
|
-
*
|
|
255
|
-
* Because it is inside the button or link it obeys the {@link trailing} rule: shown,
|
|
256
|
-
* never operated — no buttons, links or inputs (invalid HTML in a button, and folded
|
|
257
|
-
* into its name). Its text joins the row's accessible name, so give a bar that only
|
|
258
|
-
* repeats a figure already in the row `aria-hidden`. Rendered in a block `<span>`,
|
|
259
|
-
* full width of the TEXT COLUMN only — the column the title and subtitle are in, not
|
|
260
|
-
* the whole row: it starts after the {@link icon} / {@link leading} and stops where
|
|
261
|
-
* {@link trailing} begins, so a meter under a row with a trailing figure is as wide as
|
|
262
|
-
* the title, not run on under the figure (keksdose's budget rows). For a bar across
|
|
263
|
-
* the full row, put it in {@link children} (outside the target) or leave `trailing`
|
|
264
|
-
* off and show the figure in `meta`. Strictly a button holds phrasing content only; the
|
|
265
|
-
* kit's `ProgressBar` draws `<div>`s, which every browser lays out and reads fine
|
|
266
|
-
* there but an HTML validator flags.
|
|
267
|
-
*/
|
|
268
|
-
content?: ReactNode;
|
|
269
|
-
/** A Lucide icon before the text, muted, at 16px. */
|
|
270
|
-
icon?: LucideIcon;
|
|
271
|
-
/** Anything else before the text — an avatar, a file-type badge, a drag handle. */
|
|
272
|
-
leading?: ReactNode;
|
|
273
|
-
/**
|
|
274
|
-
* Inside the main target, at its end: a status chip, a file size, a count. It is part
|
|
275
|
-
* of what the row's click does and part of its accessible name — so never a control.
|
|
276
|
-
* Controls go in {@link actions}.
|
|
277
|
-
*/
|
|
278
|
-
trailing?: ReactNode;
|
|
279
|
-
/**
|
|
280
|
-
* The colour of the {@link trailing} slot. Default `muted` — today's look, right for
|
|
281
|
-
* a size or a count in plain text. `inherit` sets none, so an element's own colour
|
|
282
|
-
* (an amount coloured by its sign) stands without a second override; any
|
|
283
|
-
* {@link TextTone} colours a plain-text figure (`"danger"` for an overdue count).
|
|
284
|
-
*/
|
|
285
|
-
trailingTone?: ListItemTrailingTone;
|
|
286
|
-
/**
|
|
287
|
-
* Controls BESIDE the main target, never inside it: copy, delete, "Open".
|
|
288
|
-
*
|
|
289
|
-
* A button inside a button (or a link) is invalid HTML, and a screen reader folds the
|
|
290
|
-
* inner one into the outer one's name where it cannot be reached. lenkbank found this
|
|
291
|
-
* three times (profile-bar.tsx:110, projects-page.tsx:61, segment-list.tsx:165) and
|
|
292
|
-
* solved it the same way each time: the row's target and its actions are siblings in
|
|
293
|
-
* one bordered box. That is this slot — and being siblings is also what stops a click
|
|
294
|
-
* on "Copy" from selecting the row.
|
|
295
|
-
*/
|
|
296
|
-
actions?: ReactNode;
|
|
297
|
-
/**
|
|
298
|
-
* Controls BEFORE the main target, never inside it: a selection checkbox, a drag
|
|
299
|
-
* handle that is a button. The mirror of {@link actions} at the start edge — a
|
|
300
|
-
* sibling of the target, so checking the box does not activate (or expand) the row
|
|
301
|
-
* and the checkbox keeps its own name. Give the control an `aria-label` naming the
|
|
302
|
-
* row ("Select Groceries"), since it is not inside the row's name. Anything that only
|
|
303
|
-
* shows goes in {@link leading}, inside the target.
|
|
304
|
-
*/
|
|
305
|
-
leadingActions?: ReactNode;
|
|
306
|
-
/**
|
|
307
|
-
* Rich content UNDER the title row and outside its target: photos, per-row buttons,
|
|
308
|
-
* form fields — kastlan's handover room inspector (room-inspector.tsx), the handover
|
|
309
|
-
* detail page and the wizard's defects step (wizard/defects-step.tsx), which draw
|
|
310
|
-
* each room or defect as a `Card variant="inset"` because a row could not hold a
|
|
311
|
-
* photo strip with its own buttons.
|
|
312
|
-
*
|
|
313
|
-
* The same rule as {@link actions}, one row down: the title area stays ONE named
|
|
314
|
-
* target (the button or link, with the title and subtitle as its name), and the body
|
|
315
|
-
* is its sibling, never nested in it — a thumbnail's "Remove" inside the row's button
|
|
316
|
-
* would be invalid HTML and unreachable by a screen reader. The body is a
|
|
317
|
-
* `role="group"` named by the row's title (`aria-labelledby`), so tabbing into the
|
|
318
|
-
* third photo's button of the second room is heard as "Kitchen, group" first rather
|
|
319
|
-
* than as a button floating free of any row. Inside the row's box, so a `selected`
|
|
320
|
-
* border and a `divider` hold both; the hover fill stays on the target alone, since
|
|
321
|
-
* the body is not what a click on the row does.
|
|
322
|
-
*/
|
|
323
|
-
children?: ReactNode;
|
|
324
|
-
/** Classes on the {@link children} body. */
|
|
325
|
-
bodyClassName?: string;
|
|
326
|
-
/**
|
|
327
|
-
* The unread mark: a brand dot at the row's end, the title in semibold, and "Unread"
|
|
328
|
-
* read after the title (keksdose notification-inbox.tsx:215). For another status,
|
|
329
|
-
* pass your own mark in {@link status}.
|
|
330
|
-
*/
|
|
331
|
-
unread?: boolean;
|
|
332
|
-
/** A mark in the unread dot's place — a `StatusDot` of another tone, a count. */
|
|
333
|
-
status?: ReactNode;
|
|
334
|
-
/**
|
|
335
|
-
* The row is the chosen one — a brand border on the raised surface (lenkbank's
|
|
336
|
-
* profile bar and segment list). `aria-current="true"` on the target: the row is the
|
|
337
|
-
* current one of a set, which is what those lists mean, not a pressed toggle.
|
|
338
|
-
*/
|
|
339
|
-
selected?: boolean;
|
|
340
|
-
disabled?: boolean;
|
|
341
|
-
/**
|
|
342
|
-
* Work under way on the row — keksdose's attachment download (support-attachments
|
|
343
|
-
* .tsx:91). A spinner takes the trailing edge, the target is `aria-busy`, and a
|
|
344
|
-
* second click is ignored. The row keeps focus: `aria-disabled`, not `disabled`, so
|
|
345
|
-
* a keyboard user is not dropped back to the top of the page mid-download.
|
|
346
|
-
*/
|
|
347
|
-
loading?: boolean;
|
|
348
|
-
/** Overrides the {@link List}'s density for this row. */
|
|
349
|
-
density?: ListDensity;
|
|
350
|
-
/** `start` for rows whose text runs to two or three lines, so the icon sits by the
|
|
351
|
-
* title rather than the middle of the paragraph. Default `center`. */
|
|
352
|
-
align?: "center" | "start";
|
|
353
|
-
/** Classes on the visible row (the bordered box). */
|
|
354
|
-
className?: string;
|
|
355
|
-
/** Classes on the main target (the button, link or static block). */
|
|
356
|
-
targetClassName?: string;
|
|
357
|
-
/**
|
|
358
|
-
* Extra attributes and handlers for the main target — e.g. HTML5 drag-and-drop
|
|
359
|
-
* (`draggable`, `onDragStart`, `onDragEnd`): lenkbank's segment list drags the WHOLE
|
|
360
|
-
* 44px row, and a grip inside the button cannot start a drag in Firefox. Spread first,
|
|
361
|
-
* so the row's own role, name, state and click handling always win.
|
|
362
|
-
*/
|
|
363
|
-
targetProps?: HTMLAttributes<HTMLElement>;
|
|
364
|
-
/**
|
|
365
|
-
* A visible border while unselected, instead of the transparent one. For rows laid out
|
|
366
|
-
* as a wrapping strip (lenkbank's profile bar), where borderless rows read as loose
|
|
367
|
-
* text. The selected row's brand border is unchanged.
|
|
368
|
-
*/
|
|
369
|
-
bordered?: boolean;
|
|
370
|
-
/** `div` for a single row outside a {@link List}; an `<li>` must sit in a list. */
|
|
371
|
-
as?: "li" | "div";
|
|
372
|
-
/**
|
|
373
|
-
* Wraps the visible row (the bordered box: target, actions and body) in an element
|
|
374
|
-
* of your own, INSIDE the `<li>` — a `<Tooltip>` explaining why the row is disabled,
|
|
375
|
-
* an app's save guard: `renderRow={(row) => <Tooltip label="Locked">{row}</Tooltip>}`.
|
|
376
|
-
*
|
|
377
|
-
* The wrapper otherwise had to go round the whole `ListItem`, which put a `<span>`
|
|
378
|
-
* between the `<ul>` and its `<li>` (invalid; the list stops counting items), so
|
|
379
|
-
* callers wrote `<li><Wrapper><ListItem as="div" /></Wrapper></li>` — and lost the
|
|
380
|
-
* divider and its spacing, which sit on the row's own `<li>`. Here the `<li>` stays
|
|
381
|
-
* the list's child and keeps both. The `<li>` becomes a column and the row takes the
|
|
382
|
-
* full width, so an inline wrapper (the tooltip's `inline-flex` span) still stretches
|
|
383
|
-
* the row across the list.
|
|
384
|
-
*
|
|
385
|
-
* `row` is the row BOX (a `<div>`), not the target: a wrapper that forces a prop onto
|
|
386
|
-
* its child with `cloneElement` — a save guard that injects `disabled` while a form is
|
|
387
|
-
* dirty (keksdose's SaveGuard) — sets it on that div, where it does nothing, and the
|
|
388
|
-
* button inside stays live. Pass `disabled` (or `loading`) to the ListItem yourself,
|
|
389
|
-
* from the same state the guard reads, and let the wrapper only explain it:
|
|
390
|
-
* `<ListItem disabled={dirty} renderRow={(row) => <Tooltip label="Save first">{row}</Tooltip>} />`.
|
|
391
|
-
*/
|
|
392
|
-
renderRow?: (row: ReactElement) => ReactNode;
|
|
393
|
-
/** Reaches the main target — the element with the row's name and action. */
|
|
394
|
-
id?: string;
|
|
395
|
-
[key: `aria-${string}`]: string | boolean | number | undefined;
|
|
396
|
-
[key: `data-${string}`]: unknown;
|
|
397
|
-
/** The main target — the row's `<a>`, `<button>` or `<div>`, where `id` goes. A React
|
|
398
|
-
* 19 ref prop since 0.34 (MOD-4, refactor audit 2026-10); it was `forwardRef`. */
|
|
399
|
-
ref?: Ref<HTMLElement>;
|
|
400
|
-
}
|
|
401
|
-
|
|
402
|
-
/**
|
|
403
|
-
* The row is ONE thing to activate, so the types allow one: a button, an in-app link,
|
|
404
|
-
* an external link, or nothing (a static row, like kastlan's passkey and user lists).
|
|
405
|
-
*/
|
|
406
|
-
export type ListItemProps = ListItemBaseProps &
|
|
407
|
-
(
|
|
408
|
-
| ({
|
|
409
|
-
/** Makes the row a button — select, open, mark read. */
|
|
410
|
-
onClick: (event: MouseEvent<HTMLButtonElement>) => void;
|
|
411
|
-
/**
|
|
412
|
-
* Why the row's click is not available — {@link Button}'s `disabledReason`, for
|
|
413
|
-
* a row whose click WRITES (mark read, assign, toggle a grant). keksdose K3: such
|
|
414
|
-
* rows sat behind a `SaveGuard` that forced a native `disabled`, out of the tab
|
|
415
|
-
* order, so the reason never reached a keyboard; `renderRow` with a Tooltip could
|
|
416
|
-
* explain it but not keep the row reachable.
|
|
417
|
-
*
|
|
418
|
-
* With a reason the row's button is `aria-disabled` instead: still focusable, a
|
|
419
|
-
* click does nothing, the reason is a line under the row at Large and on a touch
|
|
420
|
-
* screen, else in the kit {@link Tooltip} over the row (`disabledReasonDisplay`),
|
|
421
|
-
* and on its `aria-describedby`, and the row wears the disabled look. It wins over
|
|
422
|
-
* `disabled`. The row's `actions` are untouched — each control there is its own.
|
|
423
|
-
*/
|
|
424
|
-
disabledReason?: ReactNode;
|
|
425
|
-
/** Where the reason shows — {@link Button}'s `disabledReasonDisplay`. A long list
|
|
426
|
-
* of locked rows under a banner that already says why can keep it to the
|
|
427
|
-
* tooltip with `"tooltip"` (DUP-3). */
|
|
428
|
-
disabledReasonDisplay?: DisabledReasonDisplay;
|
|
429
|
-
/**
|
|
430
|
-
* The row's click COMMITS. Under a locked {@link WriteLockProvider} it is locked
|
|
431
|
-
* the `disabledReason` way with the lock's reason (which wins over its own). No
|
|
432
|
-
* provider, or an unlocked one: no effect. Button's `commit`, for keksdose K3.
|
|
433
|
-
*/
|
|
434
|
-
commit?: CommitScope;
|
|
435
|
-
href?: never;
|
|
436
|
-
renderLink?: never;
|
|
437
|
-
external?: never;
|
|
438
|
-
onAuxClick?: never;
|
|
439
|
-
} & NotExpandable)
|
|
440
|
-
| ({
|
|
441
|
-
/**
|
|
442
|
-
* Makes the row a link. A real `<a href>`, so a middle click opens it in a
|
|
443
|
-
* background tab (keksdose feedback #451) — which a button calling `navigate`
|
|
444
|
-
* cannot do.
|
|
445
|
-
*/
|
|
446
|
-
href: string;
|
|
447
|
-
/** Your router's link for an in-app `href`. Default: the `<UiKitProvider
|
|
448
|
-
* linkComponent>`, then `<a>`. The API `Chip`, `StatTile` and `MenuItem`
|
|
449
|
-
* share. Ignored for an `external` row. */
|
|
450
|
-
renderLink?: (props: ListItemLinkProps) => ReactElement;
|
|
451
|
-
/**
|
|
452
|
-
* The link leaves the app: a plain `<a target="_blank" rel="noopener
|
|
453
|
-
* noreferrer">` with an external-link mark, and "opens in a new tab" read
|
|
454
|
-
* after the title. keksdose's inbox rows whose URL is absolute.
|
|
455
|
-
*/
|
|
456
|
-
external?: boolean;
|
|
457
|
-
/** Runs on a click, before the navigation (mark the row read). */
|
|
458
|
-
onClick?: (event: MouseEvent<HTMLAnchorElement>) => void;
|
|
459
|
-
/** Runs on a middle click, which fires no `click` — keksdose marks a
|
|
460
|
-
* notification read here too, so a row opened into a background tab does not
|
|
461
|
-
* stay unread. */
|
|
462
|
-
onAuxClick?: (event: MouseEvent<HTMLAnchorElement>) => void;
|
|
463
|
-
disabledReason?: never;
|
|
464
|
-
disabledReasonDisplay?: never;
|
|
465
|
-
commit?: never;
|
|
466
|
-
} & NotExpandable)
|
|
467
|
-
| ({
|
|
468
|
-
onClick?: never;
|
|
469
|
-
href?: never;
|
|
470
|
-
renderLink?: never;
|
|
471
|
-
external?: never;
|
|
472
|
-
onAuxClick?: never;
|
|
473
|
-
disabledReason?: never;
|
|
474
|
-
disabledReasonDisplay?: never;
|
|
475
|
-
commit?: never;
|
|
476
|
-
} & NotExpandable)
|
|
477
|
-
| {
|
|
478
|
-
/**
|
|
479
|
-
* Makes the row a disclosure: the target is a button with `aria-expanded` and a
|
|
480
|
-
* turning chevron at its end, and this opens under the row, outside the target
|
|
481
|
-
* (so it may hold controls), animated by {@link Collapse}. keksdose's collapsible
|
|
482
|
-
* groups — a group row with a select-all checkbox before it
|
|
483
|
-
* ({@link ListItemBaseProps.leadingActions}) and its members inside.
|
|
484
|
-
*
|
|
485
|
-
* The row's ONE action is the toggle, so it takes no `onClick` or `href`. The
|
|
486
|
-
* content is a `role="group"` named by the title, unmounted while shut (as a
|
|
487
|
-
* `Disclosure`'s body is).
|
|
488
|
-
*/
|
|
489
|
-
expandedContent: ReactNode;
|
|
490
|
-
/** Controlled open state. Leave it out for the row to keep its own. */
|
|
491
|
-
expanded?: boolean;
|
|
492
|
-
/** The uncontrolled row's first state. Default `false`. */
|
|
493
|
-
defaultExpanded?: boolean;
|
|
494
|
-
/** Runs on every toggle with the new state. */
|
|
495
|
-
onExpandedChange?: (expanded: boolean) => void;
|
|
496
|
-
onClick?: never;
|
|
497
|
-
href?: never;
|
|
498
|
-
renderLink?: never;
|
|
499
|
-
external?: never;
|
|
500
|
-
onAuxClick?: never;
|
|
501
|
-
disabledReason?: never;
|
|
502
|
-
disabledReasonDisplay?: never;
|
|
503
|
-
commit?: never;
|
|
504
|
-
}
|
|
505
|
-
);
|
|
506
|
-
|
|
507
|
-
interface NotExpandable {
|
|
508
|
-
expandedContent?: never;
|
|
509
|
-
expanded?: never;
|
|
510
|
-
defaultExpanded?: never;
|
|
511
|
-
onExpandedChange?: never;
|
|
512
|
-
}
|
|
513
|
-
|
|
514
|
-
/**
|
|
515
|
-
* One row of a {@link List}: leading icon or avatar, title and subtitle (both
|
|
516
|
-
* truncating by default), a trailing slot, and — beside the row, not inside it — its actions.
|
|
517
|
-
*
|
|
518
|
-
* At Large and Extra large (0.32, docs/text-size-harmonization.md §4) nothing in it
|
|
519
|
-
* truncates: the overline, title, subtitle and meta wrap, a two-line clamp lets go, and
|
|
520
|
-
* a trailing slot drops under the text when the two no longer fit side by side. The
|
|
521
|
-
* rows lose their one height there; that is the trade the reader asked for.
|
|
522
|
-
*
|
|
523
|
-
* All three apps draw this row by hand, a dozen times: kastlan's units
|
|
524
|
-
* (building-detail-page.tsx:402), open tickets (group-overview-page.tsx:160), activity
|
|
525
|
-
* feed (activity-feed.tsx:53), company users (platform-company-detail-page.tsx:140)
|
|
526
|
-
* and passkeys (passkeys-card.tsx:75); keksdose's notification inbox and attachment
|
|
527
|
-
* downloads; lenkbank's profiles, projects and segments. The copies differ in the
|
|
528
|
-
* details that are easy to get wrong — which of them truncate, whether the actions
|
|
529
|
-
* are nested in the button, whether a link row is a link at all.
|
|
530
|
-
*/
|
|
531
|
-
export function ListItem({
|
|
532
|
-
ref,
|
|
533
|
-
title,
|
|
534
|
-
titleLines = 1,
|
|
535
|
-
overline,
|
|
536
|
-
subtitle,
|
|
537
|
-
subtitleLines = 1,
|
|
538
|
-
meta,
|
|
539
|
-
metaWrap = false,
|
|
540
|
-
content,
|
|
541
|
-
icon: Icon,
|
|
542
|
-
leading,
|
|
543
|
-
trailing,
|
|
544
|
-
trailingTone = "muted",
|
|
545
|
-
actions,
|
|
546
|
-
leadingActions,
|
|
547
|
-
unread = false,
|
|
548
|
-
status,
|
|
549
|
-
selected = false,
|
|
550
|
-
disabled = false,
|
|
551
|
-
loading = false,
|
|
552
|
-
density: densityProp,
|
|
553
|
-
align = "center",
|
|
554
|
-
className,
|
|
555
|
-
targetClassName,
|
|
556
|
-
targetProps,
|
|
557
|
-
bordered = false,
|
|
558
|
-
as = "li",
|
|
559
|
-
renderRow,
|
|
560
|
-
children,
|
|
561
|
-
bodyClassName,
|
|
562
|
-
href,
|
|
563
|
-
renderLink,
|
|
564
|
-
external = false,
|
|
565
|
-
onClick,
|
|
566
|
-
onAuxClick,
|
|
567
|
-
disabledReason,
|
|
568
|
-
disabledReasonDisplay,
|
|
569
|
-
commit,
|
|
570
|
-
expandedContent,
|
|
571
|
-
expanded: expandedProp,
|
|
572
|
-
defaultExpanded = false,
|
|
573
|
-
onExpandedChange,
|
|
574
|
-
...rest
|
|
575
|
-
}: ListItemProps) {
|
|
576
|
-
const list = useContext(ListContext);
|
|
577
|
-
const labels = useKitLabels("list", DEFAULT_LIST_LABELS);
|
|
578
|
-
const kitLink = useKitLink();
|
|
579
|
-
const [ownExpanded, setOwnExpanded] = useState(defaultExpanded);
|
|
580
|
-
const density = densityProp ?? list.density;
|
|
581
|
-
const pad = PAD[density];
|
|
582
|
-
const expandable = expandedContent !== undefined;
|
|
583
|
-
const expanded = expandable && (expandedProp ?? ownExpanded);
|
|
584
|
-
const isLink = href !== undefined && !disabled;
|
|
585
|
-
const isButton = !isLink && (onClick !== undefined || expandable) && href === undefined;
|
|
586
|
-
const interactive = isLink || isButton;
|
|
587
|
-
// Only an onClick row takes a reason (the types allow no other); the hook runs on
|
|
588
|
-
// every row so the hook order never depends on which kind of row this is.
|
|
589
|
-
const lock = useLockReason(commit, disabledReason);
|
|
590
|
-
const locked = lock.locked && isButton && !expandable;
|
|
591
|
-
const inert = disabled || loading || locked;
|
|
592
|
-
// `hasContent` (refactor audit 2026-10-30, DUP-14): a `""` body opened an empty line.
|
|
593
|
-
const hasBody = hasContent(children);
|
|
594
|
-
// Anything under the row's own line: the box turns into a column, and the target
|
|
595
|
-
// takes its own corners and hover fill (see `children`).
|
|
596
|
-
const stacked = hasBody || expandable;
|
|
597
|
-
const titleId = useId();
|
|
598
|
-
const expandedId = useId();
|
|
599
|
-
|
|
600
|
-
const toggle = () => {
|
|
601
|
-
const next = !expanded;
|
|
602
|
-
if (expandedProp === undefined) setOwnExpanded(next);
|
|
603
|
-
onExpandedChange?.(next);
|
|
604
|
-
};
|
|
605
|
-
|
|
606
|
-
const mark =
|
|
607
|
-
status ??
|
|
608
|
-
(unread ? <StatusDot tone="brand" size="sm" className={align === "start" ? "mt-1.5" : undefined} /> : null);
|
|
609
|
-
|
|
610
|
-
const body = (
|
|
611
|
-
<>
|
|
612
|
-
{Icon && <Icon className={cn("size-4 shrink-0 text-muted", align === "start" && "mt-0.5")} aria-hidden />}
|
|
613
|
-
{leading}
|
|
614
|
-
{/* With a trailing slot, a basis at Large: below it the trailing chip or figure
|
|
615
|
-
wraps under the text (the target wraps, see `target`) rather than squeezing the
|
|
616
|
-
now-wrapping title into a column one word wide (§4, 240 px effective width). */}
|
|
617
|
-
<span className={cn("flex min-w-0 flex-1 flex-col", trailing != null && "large:basis-40")}>
|
|
618
|
-
{overline != null && (
|
|
619
|
-
<span className="block truncate-until-large text-caption font-medium leading-snug text-muted">
|
|
620
|
-
{overline}
|
|
621
|
-
</span>
|
|
622
|
-
)}
|
|
623
|
-
<span
|
|
624
|
-
// Names the body's and the expanded content's group; harmless without one.
|
|
625
|
-
id={stacked ? titleId : undefined}
|
|
626
|
-
className={cn(
|
|
627
|
-
"block text-sm text-primary",
|
|
628
|
-
titleLines === 1
|
|
629
|
-
? "truncate-until-large"
|
|
630
|
-
: titleLines === 2
|
|
631
|
-
? cn("line-clamp-2 break-words", UNCLAMP_AT_LARGE)
|
|
632
|
-
: "break-words",
|
|
633
|
-
unread ? "font-semibold" : "font-medium",
|
|
634
|
-
)}
|
|
635
|
-
>
|
|
636
|
-
{title}
|
|
637
|
-
{unread && <span className="sr-only"> ({labels.unread})</span>}
|
|
638
|
-
{external && href !== undefined && <span className="sr-only"> ({labels.opensInNewTab})</span>}
|
|
639
|
-
</span>
|
|
640
|
-
{subtitle != null && (
|
|
641
|
-
<span
|
|
642
|
-
className={cn(
|
|
643
|
-
"block text-xs text-muted",
|
|
644
|
-
subtitleLines === 2 ? cn("line-clamp-2 break-words", UNCLAMP_AT_LARGE) : "truncate-until-large",
|
|
645
|
-
)}
|
|
646
|
-
>
|
|
647
|
-
{subtitle}
|
|
648
|
-
</span>
|
|
649
|
-
)}
|
|
650
|
-
{meta != null && (
|
|
651
|
-
<span
|
|
652
|
-
className={cn(
|
|
653
|
-
"mt-0.5 text-caption leading-snug text-muted",
|
|
654
|
-
metaWrap ? "flex flex-wrap items-center gap-1" : "block truncate-until-large",
|
|
655
|
-
)}
|
|
656
|
-
>
|
|
657
|
-
{meta}
|
|
658
|
-
</span>
|
|
659
|
-
)}
|
|
660
|
-
{content != null && <span className="mt-1.5 block min-w-0">{content}</span>}
|
|
661
|
-
</span>
|
|
662
|
-
{trailing != null && (
|
|
663
|
-
<span
|
|
664
|
-
className={cn(
|
|
665
|
-
"flex shrink-0 items-center gap-2 text-xs large:ms-auto",
|
|
666
|
-
trailingTone !== "inherit" && toneTextClass(trailingTone),
|
|
667
|
-
)}
|
|
668
|
-
>
|
|
669
|
-
{trailing}
|
|
670
|
-
</span>
|
|
671
|
-
)}
|
|
672
|
-
{loading ? (
|
|
673
|
-
<Spinner label={null} className="size-3.5 shrink-0" />
|
|
674
|
-
) : (
|
|
675
|
-
external &&
|
|
676
|
-
href !== undefined && <ExternalLink className="size-3.5 shrink-0 text-muted rtl:-scale-x-100" aria-hidden />
|
|
677
|
-
)}
|
|
678
|
-
{mark}
|
|
679
|
-
{expandable && (
|
|
680
|
-
// Turned, not swapped — the Disclosure card's convention: down while shut, up
|
|
681
|
-
// while open. A rotation is its own mirror, so RTL needs nothing.
|
|
682
|
-
<ChevronDown
|
|
683
|
-
aria-hidden
|
|
684
|
-
className={cn(
|
|
685
|
-
"size-4 shrink-0 text-muted transition-transform duration-200 ease-out motion-reduce:transition-none",
|
|
686
|
-
align === "start" && "mt-0.5",
|
|
687
|
-
expanded && "rotate-180",
|
|
688
|
-
)}
|
|
689
|
-
/>
|
|
690
|
-
)}
|
|
691
|
-
</>
|
|
692
|
-
);
|
|
693
|
-
|
|
694
|
-
const target = cn(
|
|
695
|
-
"flex min-w-0 flex-1 text-start",
|
|
696
|
-
// §4 at Large: the trailing slot drops under the text when both no longer fit.
|
|
697
|
-
trailing != null && "large:flex-wrap",
|
|
698
|
-
align === "start" ? "items-start" : "items-center",
|
|
699
|
-
pad.target,
|
|
700
|
-
// When stacked the target is the top of the box, not all of it, so it takes its
|
|
701
|
-
// own corners and its own hover fill (see `children`).
|
|
702
|
-
stacked ? "rounded-md" : "rounded-[inherit]",
|
|
703
|
-
stacked && interactive && !inert && !selected && "transition-colors hover:bg-hover",
|
|
704
|
-
interactive && TARGET_RING,
|
|
705
|
-
interactive && !inert && "cursor-pointer",
|
|
706
|
-
loading && "cursor-progress",
|
|
707
|
-
locked && !loading && "cursor-not-allowed",
|
|
708
|
-
targetClassName,
|
|
709
|
-
);
|
|
710
|
-
|
|
711
|
-
// `role` is the row's own (a button, a link, or nothing on a static block): a
|
|
712
|
-
// targetProps role would silently turn the row into something else.
|
|
713
|
-
const { role: _ignoredRole, ...targetExtras } = targetProps ?? {};
|
|
714
|
-
|
|
715
|
-
let main: ReactNode;
|
|
716
|
-
if (isLink) {
|
|
717
|
-
const linkProps: ListItemLinkProps = {
|
|
718
|
-
...(targetExtras as Partial<ListItemLinkProps>),
|
|
719
|
-
...rest,
|
|
720
|
-
ref: ref as Ref<HTMLAnchorElement>,
|
|
721
|
-
href,
|
|
722
|
-
className: target,
|
|
723
|
-
"aria-current": selected ? "true" : undefined,
|
|
724
|
-
"aria-busy": loading || undefined,
|
|
725
|
-
onClick: loading ? (e) => e.preventDefault() : (onClick as ListItemLinkProps["onClick"]),
|
|
726
|
-
onAuxClick,
|
|
727
|
-
children: body,
|
|
728
|
-
};
|
|
729
|
-
const { children: linkBody, ...anchorProps } = linkProps;
|
|
730
|
-
const render = external ? undefined : pickLinkRenderer(renderLink, kitLink, href);
|
|
731
|
-
main = render ? (
|
|
732
|
-
<RenderedLink render={render} {...linkProps} />
|
|
733
|
-
) : (
|
|
734
|
-
<a {...anchorProps} {...(external ? { target: "_blank", rel: "noopener noreferrer" } : null)}>
|
|
735
|
-
{linkBody}
|
|
736
|
-
</a>
|
|
737
|
-
);
|
|
738
|
-
} else if (isButton) {
|
|
739
|
-
main = (
|
|
740
|
-
<button
|
|
741
|
-
{...(targetExtras as HTMLAttributes<HTMLButtonElement>)}
|
|
742
|
-
{...rest}
|
|
743
|
-
ref={ref as Ref<HTMLButtonElement>}
|
|
744
|
-
type="button"
|
|
745
|
-
// A disabled row is `disabled`: nothing to do there, and nothing to reach. A
|
|
746
|
-
// loading row is only `aria-disabled` — see `loading` — and so is a locked one:
|
|
747
|
-
// a reason wins over `disabled`, so the row stays reachable to say it.
|
|
748
|
-
disabled={locked ? undefined : disabled}
|
|
749
|
-
aria-disabled={loading || locked || undefined}
|
|
750
|
-
aria-busy={loading || undefined}
|
|
751
|
-
aria-current={selected ? "true" : undefined}
|
|
752
|
-
aria-expanded={expandable ? expanded : undefined}
|
|
753
|
-
aria-controls={expandable ? expandedId : undefined}
|
|
754
|
-
aria-describedby={
|
|
755
|
-
locked
|
|
756
|
-
? mergeDescribedBy(rest["aria-describedby"] as string | undefined, lock.reasonId)
|
|
757
|
-
: (rest["aria-describedby"] as string | undefined)
|
|
758
|
-
}
|
|
759
|
-
onClick={
|
|
760
|
-
loading || locked
|
|
761
|
-
? undefined
|
|
762
|
-
: expandable
|
|
763
|
-
? toggle
|
|
764
|
-
: (onClick as (event: MouseEvent<HTMLButtonElement>) => void)
|
|
765
|
-
}
|
|
766
|
-
className={target}
|
|
767
|
-
>
|
|
768
|
-
{body}
|
|
769
|
-
</button>
|
|
770
|
-
);
|
|
771
|
-
if (locked) {
|
|
772
|
-
// The frame takes the target's place in the row, so it takes its flex sizing too;
|
|
773
|
-
// the button fills it (`items-stretch` in the line's column). The line takes the
|
|
774
|
-
// row's body padding, so its words start where the title's do.
|
|
775
|
-
main = (
|
|
776
|
-
<LockedReason
|
|
777
|
-
lock={lock}
|
|
778
|
-
display={disabledReasonDisplay}
|
|
779
|
-
className="flex min-w-0 flex-1 items-stretch"
|
|
780
|
-
lineClassName={pad.body}
|
|
781
|
-
>
|
|
782
|
-
{main}
|
|
783
|
-
</LockedReason>
|
|
784
|
-
);
|
|
785
|
-
}
|
|
786
|
-
} else {
|
|
787
|
-
main = (
|
|
788
|
-
<div
|
|
789
|
-
{...(targetExtras as HTMLAttributes<HTMLDivElement>)}
|
|
790
|
-
{...rest}
|
|
791
|
-
ref={ref as Ref<HTMLDivElement>}
|
|
792
|
-
aria-disabled={disabled || undefined}
|
|
793
|
-
aria-busy={loading || undefined}
|
|
794
|
-
className={target}
|
|
795
|
-
>
|
|
796
|
-
{body}
|
|
797
|
-
</div>
|
|
798
|
-
);
|
|
799
|
-
}
|
|
800
|
-
|
|
801
|
-
const leadingActionsEl =
|
|
802
|
-
leadingActions != null ? (
|
|
803
|
-
<div className={cn("flex shrink-0 items-center", pad.gap, pad.leadingActions)}>{leadingActions}</div>
|
|
804
|
-
) : null;
|
|
805
|
-
const actionsEl =
|
|
806
|
-
actions != null ? <div className={cn("flex shrink-0 items-center", pad.gap, pad.actions)}>{actions}</div> : null;
|
|
807
|
-
|
|
808
|
-
const row = (
|
|
809
|
-
<div
|
|
810
|
-
className={cn(
|
|
811
|
-
"flex min-w-0 rounded-md border transition-colors",
|
|
812
|
-
stacked ? "flex-col" : "items-center",
|
|
813
|
-
// See `renderRow`: the wrapper may be inline, the row is not.
|
|
814
|
-
renderRow && "w-full",
|
|
815
|
-
selected ? "border-brand bg-surface-2" : bordered ? "border-subtle" : "border-transparent",
|
|
816
|
-
!stacked && interactive && !inert && !selected && "hover:bg-hover",
|
|
817
|
-
(disabled || locked) && "opacity-50",
|
|
818
|
-
className,
|
|
819
|
-
)}
|
|
820
|
-
>
|
|
821
|
-
{stacked ? (
|
|
822
|
-
<>
|
|
823
|
-
<div className="flex min-w-0 items-center">
|
|
824
|
-
{leadingActionsEl}
|
|
825
|
-
{main}
|
|
826
|
-
{actionsEl}
|
|
827
|
-
</div>
|
|
828
|
-
{expandable && (
|
|
829
|
-
<Collapse open={expanded}>
|
|
830
|
-
<div id={expandedId} role="group" aria-labelledby={titleId} className={cn("min-w-0", pad.body)}>
|
|
831
|
-
{expandedContent}
|
|
832
|
-
</div>
|
|
833
|
-
</Collapse>
|
|
834
|
-
)}
|
|
835
|
-
{hasBody && (
|
|
836
|
-
<div role="group" aria-labelledby={titleId} className={cn("min-w-0", pad.body, bodyClassName)}>
|
|
837
|
-
{children}
|
|
838
|
-
</div>
|
|
839
|
-
)}
|
|
840
|
-
</>
|
|
841
|
-
) : (
|
|
842
|
-
<>
|
|
843
|
-
{leadingActionsEl}
|
|
844
|
-
{main}
|
|
845
|
-
{actionsEl}
|
|
846
|
-
</>
|
|
847
|
-
)}
|
|
848
|
-
</div>
|
|
849
|
-
);
|
|
850
|
-
|
|
851
|
-
const Tag = as;
|
|
852
|
-
return (
|
|
853
|
-
<Tag
|
|
854
|
-
className={cn(
|
|
855
|
-
list.separator === "divider" && "border-b border-subtle last:border-b-0",
|
|
856
|
-
list.separator === "divider" && as === "li" && "py-0.5",
|
|
857
|
-
renderRow && "flex flex-col",
|
|
858
|
-
)}
|
|
859
|
-
>
|
|
860
|
-
{renderRow ? renderRow(row) : row}
|
|
861
|
-
</Tag>
|
|
862
|
-
);
|
|
863
|
-
}
|
|
864
|
-
|
|
865
|
-
function RenderedLink({
|
|
866
|
-
render,
|
|
867
|
-
...props
|
|
868
|
-
}: ListItemLinkProps & { render: (props: ListItemLinkProps) => ReactElement }) {
|
|
869
|
-
return render(props);
|
|
870
|
-
}
|