@godxjp/ui 19.0.0 → 19.2.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 +25 -128
- package/dist/app/app-provider.d.ts +1 -1
- package/dist/app/app-provider.js +3 -0
- package/dist/app/theme-axes.d.ts +4 -15
- package/dist/app/timezones.d.ts +1 -4
- package/dist/components/charts/area-chart.d.ts +2 -3
- package/dist/components/charts/bar-chart.d.ts +2 -3
- package/dist/components/charts/chart-frame.d.ts +7 -16
- package/dist/components/charts/chart-summary.d.ts +2 -2
- package/dist/components/charts/compact-bar-trend.d.ts +9 -24
- package/dist/components/charts/index.d.ts +1 -6
- package/dist/components/data-display/badge.d.ts +2 -12
- package/dist/components/data-display/card.d.ts +21 -41
- package/dist/components/data-display/carousel.d.ts +1 -2
- package/dist/components/data-display/code-block.d.ts +4 -0
- package/dist/components/data-display/code-block.js +24 -0
- package/dist/components/data-display/data-table.d.ts +15 -37
- package/dist/components/data-display/data-table.js +1 -3
- package/dist/components/data-display/descriptions.d.ts +2 -6
- package/dist/components/data-display/descriptions.js +0 -2
- package/dist/components/data-display/index.d.ts +4 -0
- package/dist/components/data-display/index.js +4 -0
- package/dist/components/data-display/list-row.d.ts +3 -22
- package/dist/components/data-display/permission-matrix.d.ts +7 -20
- package/dist/components/data-display/progress.d.ts +1 -1
- package/dist/components/data-display/prose.d.ts +4 -0
- package/dist/components/data-display/prose.js +20 -0
- package/dist/components/data-display/service-launcher-card.d.ts +3 -10
- package/dist/components/data-display/table.d.ts +20 -80
- package/dist/components/data-display/table.js +0 -3
- package/dist/components/data-display/timeline.d.ts +3 -5
- package/dist/components/data-entry/branch-scope-picker.d.ts +2 -19
- package/dist/components/data-entry/branch-scope-picker.js +0 -1
- package/dist/components/data-entry/calendar.d.ts +3 -2
- package/dist/components/data-entry/calendar.js +58 -3
- package/dist/components/data-entry/cascader.js +3 -1
- package/dist/components/data-entry/checkbox-group.js +12 -5
- package/dist/components/data-entry/checkbox.js +30 -21
- package/dist/components/data-entry/command-palette.d.ts +8 -22
- package/dist/components/data-entry/date-picker.d.ts +4 -5
- package/dist/components/data-entry/date-picker.js +12 -3
- package/dist/components/data-entry/date-range-picker.d.ts +1 -1
- package/dist/components/data-entry/date-range-picker.js +17 -6
- package/dist/components/data-entry/form-errors.d.ts +7 -18
- package/dist/components/data-entry/form-field.d.ts +1 -1
- package/dist/components/data-entry/form-field.js +15 -6
- package/dist/components/data-entry/form.d.ts +1 -9
- package/dist/components/data-entry/input.d.ts +16 -14
- package/dist/components/data-entry/input.js +13 -3
- package/dist/components/data-entry/month-picker.js +6 -4
- package/dist/components/data-entry/month-range-picker.d.ts +4 -6
- package/dist/components/data-entry/month-range-picker.js +11 -5
- package/dist/components/data-entry/number-input.d.ts +1 -5
- package/dist/components/data-entry/number-input.js +1 -0
- package/dist/components/data-entry/radio.js +19 -6
- package/dist/components/data-entry/search-select.d.ts +3 -5
- package/dist/components/data-entry/search-select.js +8 -2
- package/dist/components/data-entry/select.d.ts +15 -2
- package/dist/components/data-entry/select.js +57 -10
- package/dist/components/data-entry/switch.js +9 -2
- package/dist/components/data-entry/textarea.d.ts +10 -16
- package/dist/components/data-entry/textarea.js +8 -1
- package/dist/components/data-entry/time-picker.d.ts +3 -5
- package/dist/components/data-entry/tree-select.js +3 -1
- package/dist/components/data-entry/upload-types.d.ts +1 -5
- package/dist/components/data-entry/use-upload-draft.d.ts +0 -4
- package/dist/components/feedback/dialog.d.ts +6 -15
- package/dist/components/feedback/overlay-header-tone.d.ts +1 -1
- package/dist/components/feedback/sheet.d.ts +3 -10
- package/dist/components/feedback/sheet.js +1 -1
- package/dist/components/feedback/sonner.js +2 -3
- package/dist/components/general/activity.d.ts +4 -30
- package/dist/components/general/button.js +1 -10
- package/dist/components/general/logo.d.ts +6 -28
- package/dist/components/general/reveal.d.ts +3 -9
- package/dist/components/general/typography.d.ts +1 -3
- package/dist/components/layout/account-chip.d.ts +8 -0
- package/dist/components/layout/account-chip.js +45 -0
- package/dist/components/layout/auth-divider.d.ts +2 -9
- package/dist/components/layout/auth-shell.d.ts +1 -14
- package/dist/components/layout/breadcrumb.d.ts +1 -5
- package/dist/components/layout/centered-shell.d.ts +4 -18
- package/dist/components/layout/error-surface.d.ts +11 -28
- package/dist/components/layout/error-surface.js +4 -1
- package/dist/components/layout/index.d.ts +2 -0
- package/dist/components/layout/index.js +2 -0
- package/dist/components/layout/legal-document-shell.d.ts +5 -28
- package/dist/components/layout/master-detail.d.ts +2 -18
- package/dist/components/layout/page-container.js +0 -1
- package/dist/components/layout/responsive-grid.d.ts +6 -1
- package/dist/components/layout/responsive-grid.js +9 -2
- package/dist/components/layout/service-role-panel.d.ts +7 -19
- package/dist/components/layout/sidebar.d.ts +5 -27
- package/dist/components/layout/sidebar.js +0 -1
- package/dist/components/layout/split-pane.d.ts +0 -7
- package/dist/components/layout/topbar.d.ts +1 -14
- package/dist/components/navigation/app-setting-picker.js +1 -3
- package/dist/components/navigation/filter-bar.d.ts +1 -6
- package/dist/components/navigation/pagination-utils.d.ts +2 -12
- package/dist/components/navigation/tabs-scroll.d.ts +2 -36
- package/dist/components/navigation/tabs.js +4 -8
- package/dist/components/query/data-state.d.ts +2 -2
- package/dist/components/ui/credential-reveal.d.ts +1 -4
- package/dist/components/ui/hover-card.d.ts +1 -2
- package/dist/components/ui/separator.d.ts +2 -15
- package/dist/components/ui/toggle-group.d.ts +1 -5
- package/dist/components/ui/toggle.d.ts +6 -31
- package/dist/email/brand-mark.d.ts +6 -34
- package/dist/email/color.d.ts +7 -17
- package/dist/email/geometry.d.ts +4 -8
- package/dist/email/index.d.ts +4 -48
- package/dist/email/inline-style.d.ts +3 -9
- package/dist/email/urgency.d.ts +2 -7
- package/dist/form/form-context.d.ts +2 -5
- package/dist/form/form-root.d.ts +1 -2
- package/dist/i18n/messages/en.json +4 -0
- package/dist/i18n/messages/ja.json +4 -0
- package/dist/i18n/messages/vi.json +4 -0
- package/dist/inertia/index.d.ts +2 -10
- package/dist/lib/control-styles.d.ts +10 -21
- package/dist/lib/control-styles.js +4 -6
- package/dist/lib/datetime/format-date.d.ts +1 -4
- package/dist/lib/field-a11y.d.ts +31 -36
- package/dist/lib/field-a11y.js +16 -2
- package/dist/lib/format.d.ts +4 -8
- package/dist/lib/hooks.d.ts +6 -12
- package/dist/lib/permission-grid.d.ts +3 -18
- package/dist/lib/query-error.d.ts +3 -3
- package/dist/props/components/app.prop.d.ts +19 -27
- package/dist/props/components/charts.prop.d.ts +2 -3
- package/dist/props/components/data-display.prop.d.ts +48 -72
- package/dist/props/components/data-entry.prop.d.ts +41 -30
- package/dist/props/components/form.prop.d.ts +2 -6
- package/dist/props/components/general.prop.d.ts +11 -27
- package/dist/props/components/layout.prop.d.ts +89 -260
- package/dist/props/components/navigation.prop.d.ts +27 -42
- package/dist/props/registry.d.ts +31 -0
- package/dist/props/registry.js +33 -0
- package/dist/props/vocabulary/data.prop.d.ts +18 -49
- package/dist/props/vocabulary/index.d.ts +1 -1
- package/dist/props/vocabulary/interaction.prop.d.ts +10 -12
- package/dist/props/vocabulary/layout.prop.d.ts +8 -30
- package/dist/props/vocabulary/shared.prop.d.ts +3 -2
- package/dist/styles/alert-layout.css +1 -32
- package/dist/styles/badge-layout.css +4 -18
- package/dist/styles/base.css +14 -113
- package/dist/styles/card-layout.css +6 -128
- package/dist/styles/chart-layout.css +2 -17
- package/dist/styles/control.css +380 -458
- package/dist/styles/core.css +21 -0
- package/dist/styles/data-display-layout.css +175 -94
- package/dist/styles/data-entry-layout.css +0 -45
- package/dist/styles/density.css +1 -30
- package/dist/styles/dialog-layout.css +5 -69
- package/dist/styles/focus-ring.css +13 -87
- package/dist/styles/fonts.css +1 -31
- package/dist/styles/form-layout.css +7 -91
- package/dist/styles/index.css +2 -20
- package/dist/styles/layout.css +38 -456
- package/dist/styles/logo-layout.css +1 -35
- package/dist/styles/motion.css +3 -42
- package/dist/styles/navigation-layout.css +3 -50
- package/dist/styles/shell-layout.css +37 -403
- package/dist/styles/table-layout.css +16 -274
- package/dist/styles/text-layout.css +7 -21
- package/dist/styles/toggle.css +1 -23
- package/dist/theme/dxs.canonical.css +1 -55
- package/dist/theme/example.service.css +1 -26
- package/dist/theme/famgia.service.css +5 -15
- package/dist/tokens/axes.css +3 -40
- package/dist/tokens/base.css +1 -4
- package/dist/tokens/components/activity.css +6 -42
- package/dist/tokens/components/badge.css +4 -13
- package/dist/tokens/components/banner.css +4 -9
- package/dist/tokens/components/card.css +32 -88
- package/dist/tokens/components/chart.css +9 -26
- package/dist/tokens/components/control.css +37 -222
- package/dist/tokens/components/data-display.css +28 -79
- package/dist/tokens/components/data-entry.css +5 -19
- package/dist/tokens/components/descriptions.css +7 -27
- package/dist/tokens/components/email.css +38 -84
- package/dist/tokens/components/error-surface.css +2 -18
- package/dist/tokens/components/feedback.css +27 -124
- package/dist/tokens/components/form.css +13 -45
- package/dist/tokens/components/legal-document.css +16 -41
- package/dist/tokens/components/list-row.css +11 -36
- package/dist/tokens/components/logo.css +2 -57
- package/dist/tokens/components/navigation.css +16 -94
- package/dist/tokens/components/scroll-area.css +2 -18
- package/dist/tokens/components/separator.css +8 -30
- package/dist/tokens/components/sheet.css +3 -14
- package/dist/tokens/components/shell.css +53 -307
- package/dist/tokens/components/sidebar.css +5 -22
- package/dist/tokens/components/table.css +19 -140
- package/dist/tokens/components/toggle.css +3 -65
- package/dist/tokens/components/upload.css +7 -43
- package/dist/tokens/foundation.css +108 -383
- package/dist/tokens/semantic/layout.css +33 -207
- package/docs/CANONICAL-CONTRACTS.md +206 -0
- package/docs/COMPONENTS.md +157 -0
- package/docs/COMPOSITION-VS-COMPONENT.md +105 -0
- package/docs/CONSUMER-RULES.md +14 -0
- package/docs/CUSTOMER-THEMING.md +162 -0
- package/docs/DATETIME.md +69 -0
- package/docs/DEVELOPMENT.md +173 -0
- package/docs/FORMS.md +143 -0
- package/docs/FRAME-A11Y-CI.md +267 -0
- package/docs/FRAME-COVERAGE-LEDGER.md +123 -0
- package/docs/FRAME-COVERAGE-REPORT.md +140 -0
- package/docs/FRAME-COVERAGE-STANDARD.md +65 -0
- package/docs/FRAME-COVERAGE.md +29 -0
- package/docs/PROPS-REGISTRY.md +61 -0
- package/docs/PROPS-VOCABULARY.md +100 -0
- package/docs/README.md +60 -0
- package/docs/REGISTRY.md +70 -0
- package/docs/SPACING.md +56 -0
- package/docs/STANDARDS-vocabulary-tokens.md +48 -0
- package/docs/TESTING.md +98 -0
- package/docs/TOKENS.md +347 -0
- package/docs/asset-modules.d.ts +46 -0
- package/docs/assets/cover-terrain.svg +6 -0
- package/docs/assets/portrait-amber.svg +5 -0
- package/docs/assets/portrait-clay.svg +5 -0
- package/docs/assets/portrait-indigo.svg +5 -0
- package/docs/assets/portrait-iris.svg +5 -0
- package/docs/assets/portrait-moss.svg +5 -0
- package/docs/assets/portrait-plum.svg +5 -0
- package/docs/assets/portrait-slate.svg +5 -0
- package/docs/charts/compact-bar-trend.tsx +328 -0
- package/docs/charts/size-tiers.tsx +192 -0
- package/docs/data-display/accordion.tsx +99 -0
- package/docs/data-display/avatar.tsx +355 -0
- package/docs/data-display/badge.tsx +247 -0
- package/docs/data-display/card/examples/detail-panel.tsx +106 -0
- package/docs/data-display/card/index.md +3 -0
- package/docs/data-display/card/index.tsx +285 -0
- package/docs/data-display/carousel.tsx +156 -0
- package/docs/data-display/charts.tsx +198 -0
- package/docs/data-display/code-block.tsx +90 -0
- package/docs/data-display/collapsible.tsx +162 -0
- package/docs/data-display/credential-reveal.tsx +145 -0
- package/docs/data-display/data-table/examples/approval-queue.tsx +212 -0
- package/docs/data-display/data-table/examples/grid-features.tsx +158 -0
- package/docs/data-display/data-table/examples/list-page.tsx +175 -0
- package/docs/data-display/data-table/index.md +5 -0
- package/docs/data-display/data-table/index.tsx +295 -0
- package/docs/data-display/descriptions.tsx +143 -0
- package/docs/data-display/empty-state.tsx +164 -0
- package/docs/data-display/hover-card.tsx +181 -0
- package/docs/data-display/list-row.tsx +420 -0
- package/docs/data-display/permission-matrix.tsx +184 -0
- package/docs/data-display/popover-touch.tsx +27 -0
- package/docs/data-display/popover.tsx +245 -0
- package/docs/data-display/progress.tsx +84 -0
- package/docs/data-display/prose.tsx +105 -0
- package/docs/data-display/qr-code.tsx +68 -0
- package/docs/data-display/scroll-area.tsx +271 -0
- package/docs/data-display/service-launcher-card.tsx +145 -0
- package/docs/data-display/stat-card.tsx +99 -0
- package/docs/data-display/table.tsx +251 -0
- package/docs/data-display/timeline.tsx +112 -0
- package/docs/data-display/touch-actions.tsx +36 -0
- package/docs/data-display/tree-list.tsx +107 -0
- package/docs/data-entry/branch-scope-picker.tsx +123 -0
- package/docs/data-entry/calendar.tsx +180 -0
- package/docs/data-entry/cascader.tsx +378 -0
- package/docs/data-entry/checkbox.tsx +256 -0
- package/docs/data-entry/color-picker.tsx +117 -0
- package/docs/data-entry/command-palette.tsx +179 -0
- package/docs/data-entry/command.tsx +262 -0
- package/docs/data-entry/country-picker-recipe.tsx +170 -0
- package/docs/data-entry/date-picker.tsx +191 -0
- package/docs/data-entry/date-range-picker.tsx +149 -0
- package/docs/data-entry/form/examples/employee-settings.tsx +267 -0
- package/docs/data-entry/form/examples/invoice-form.tsx +387 -0
- package/docs/data-entry/form-field/examples/a11y-contract.tsx +240 -0
- package/docs/data-entry/form-field/examples/create-form.tsx +105 -0
- package/docs/data-entry/form-field/index.md +8 -0
- package/docs/data-entry/form-field/index.tsx +326 -0
- package/docs/data-entry/form-inertia.tsx +80 -0
- package/docs/data-entry/form-root.tsx +102 -0
- package/docs/data-entry/form.tsx +724 -0
- package/docs/data-entry/input-otp.tsx +231 -0
- package/docs/data-entry/input.tsx +114 -0
- package/docs/data-entry/label.tsx +100 -0
- package/docs/data-entry/month-picker.tsx +101 -0
- package/docs/data-entry/month-range-picker.tsx +115 -0
- package/docs/data-entry/number-input.tsx +240 -0
- package/docs/data-entry/password-input.tsx +106 -0
- package/docs/data-entry/password-strength.tsx +97 -0
- package/docs/data-entry/radio-group.tsx +95 -0
- package/docs/data-entry/rating.tsx +87 -0
- package/docs/data-entry/search-input.tsx +120 -0
- package/docs/data-entry/select-async-contracts.tsx +108 -0
- package/docs/data-entry/select-matrix.tsx +204 -0
- package/docs/data-entry/select.tsx +369 -0
- package/docs/data-entry/slider.tsx +130 -0
- package/docs/data-entry/switch.tsx +67 -0
- package/docs/data-entry/tag-input.tsx +108 -0
- package/docs/data-entry/textarea.tsx +209 -0
- package/docs/data-entry/time-picker.tsx +99 -0
- package/docs/data-entry/toggle-count.tsx +293 -0
- package/docs/data-entry/toggle-group.tsx +225 -0
- package/docs/data-entry/toggle.tsx +127 -0
- package/docs/data-entry/transfer.tsx +97 -0
- package/docs/data-entry/tree-select.tsx +204 -0
- package/docs/data-entry/upload.tsx +184 -0
- package/docs/feedback/alert-dialog.tsx +270 -0
- package/docs/feedback/alert.tsx +248 -0
- package/docs/feedback/banner.tsx +183 -0
- package/docs/feedback/danger-confirm.tsx +88 -0
- package/docs/feedback/dialog-touch.tsx +24 -0
- package/docs/feedback/dialog.tsx +193 -0
- package/docs/feedback/sheet.tsx +410 -0
- package/docs/feedback/skeleton.tsx +111 -0
- package/docs/feedback/toast.tsx +135 -0
- package/docs/feedback/tooltip.tsx +171 -0
- package/docs/feedback/two-factor-setup.tsx +68 -0
- package/docs/foundation/_email-specimen.ts +274 -0
- package/docs/foundation/colors.tsx +202 -0
- package/docs/foundation/density.tsx +232 -0
- package/docs/foundation/email-tokens.tsx +306 -0
- package/docs/foundation/radius-shadow.tsx +152 -0
- package/docs/foundation/spacing.tsx +211 -0
- package/docs/foundation/typography.tsx +147 -0
- package/docs/general/activity.tsx +224 -0
- package/docs/general/button/examples/destructive-confirm.tsx +90 -0
- package/docs/general/button/examples/form-actions.tsx +85 -0
- package/docs/general/button/examples/toolbar.tsx +160 -0
- package/docs/general/button/index.md +12 -0
- package/docs/general/button/index.tsx +211 -0
- package/docs/general/logo.tsx +131 -0
- package/docs/general/reveal.tsx +41 -0
- package/docs/general/typography.tsx +152 -0
- package/docs/layout/account-chip.tsx +72 -0
- package/docs/layout/admin-collection.tsx +122 -0
- package/docs/layout/app-shell.tsx +374 -0
- package/docs/layout/aspect-ratio.tsx +119 -0
- package/docs/layout/auth-account-summary.tsx +103 -0
- package/docs/layout/auth-divider.tsx +28 -0
- package/docs/layout/auth-footer.tsx +37 -0
- package/docs/layout/auth-identity.tsx +36 -0
- package/docs/layout/auth-recovery/examples/mfa-challenge.md +41 -0
- package/docs/layout/auth-recovery/examples/mfa-challenge.tsx +254 -0
- package/docs/layout/auth-recovery/examples/mobile-390.md +25 -0
- package/docs/layout/auth-recovery/examples/mobile-390.tsx +82 -0
- package/docs/layout/auth-recovery/examples/password-recovery.md +24 -0
- package/docs/layout/auth-recovery/examples/password-recovery.tsx +197 -0
- package/docs/layout/auth-recovery/examples/wrapping-ja-en-vi.md +27 -0
- package/docs/layout/auth-recovery/examples/wrapping-ja-en-vi.tsx +156 -0
- package/docs/layout/auth-recovery/index.md +140 -0
- package/docs/layout/auth-recovery/index.tsx +96 -0
- package/docs/layout/auth-shell-context.tsx +103 -0
- package/docs/layout/auth-shell-device.tsx +112 -0
- package/docs/layout/auth-shell-registration.tsx +335 -0
- package/docs/layout/auth-shell-variants.tsx +139 -0
- package/docs/layout/auth-shell.tsx +59 -0
- package/docs/layout/auth-stack.tsx +40 -0
- package/docs/layout/centered-shell.tsx +102 -0
- package/docs/layout/error-surface/examples/application-403.tsx +84 -0
- package/docs/layout/error-surface/examples/application-404.tsx +77 -0
- package/docs/layout/error-surface/examples/system-500.tsx +47 -0
- package/docs/layout/error-surface/examples/system-503.tsx +48 -0
- package/docs/layout/error-surface/index.md +153 -0
- package/docs/layout/error-surface/index.tsx +239 -0
- package/docs/layout/flex.tsx +262 -0
- package/docs/layout/legal-document-shell/_data.ts +110 -0
- package/docs/layout/legal-document-shell/examples/desktop-1440.md +12 -0
- package/docs/layout/legal-document-shell/examples/desktop-1440.tsx +83 -0
- package/docs/layout/legal-document-shell/examples/mobile-390.md +22 -0
- package/docs/layout/legal-document-shell/examples/mobile-390.tsx +70 -0
- package/docs/layout/legal-document-shell/examples/tablet-1024.md +3 -0
- package/docs/layout/legal-document-shell/examples/tablet-1024.tsx +84 -0
- package/docs/layout/legal-document-shell/examples/wrapping-ja-en-vi.md +18 -0
- package/docs/layout/legal-document-shell/examples/wrapping-ja-en-vi.tsx +61 -0
- package/docs/layout/legal-document-shell/index.md +51 -0
- package/docs/layout/legal-document-shell/index.tsx +101 -0
- package/docs/layout/master-detail.tsx +387 -0
- package/docs/layout/org-switcher.tsx +131 -0
- package/docs/layout/page-container.tsx +946 -0
- package/docs/layout/resizable-panel.tsx +419 -0
- package/docs/layout/responsive-grid.tsx +235 -0
- package/docs/layout/separator.tsx +327 -0
- package/docs/layout/service-role-panel.tsx +144 -0
- package/docs/layout/sidebar.tsx +586 -0
- package/docs/layout/split-pane.tsx +451 -0
- package/docs/layout/topbar.tsx +347 -0
- package/docs/navigation/app-setting-picker.tsx +141 -0
- package/docs/navigation/breadcrumb.tsx +128 -0
- package/docs/navigation/context-menu.tsx +117 -0
- package/docs/navigation/dropdown-menu.tsx +213 -0
- package/docs/navigation/filter-bar.tsx +227 -0
- package/docs/navigation/menubar.tsx +141 -0
- package/docs/navigation/navigation-menu.tsx +165 -0
- package/docs/navigation/pagination.tsx +241 -0
- package/docs/navigation/steps.tsx +263 -0
- package/docs/navigation/tabs-rtl.tsx +28 -0
- package/docs/navigation/tabs.tsx +308 -0
- package/docs/navigation/toolbar.tsx +339 -0
- package/docs/providers/app-provider.tsx +191 -0
- package/docs/providers/format-date.tsx +230 -0
- package/docs/query/button-refetch.tsx +160 -0
- package/docs/query/data-state.tsx +192 -0
- package/docs/query/infinite-query-state.tsx +93 -0
- package/docs/query/mutation-feedback.tsx +70 -0
- package/docs/query/prefetch-link.tsx +262 -0
- package/docs/query/touch-actions.tsx +68 -0
- package/docs/showcase/acme-portal.tsx +441 -0
- package/docs/showcase/acme-website.tsx +455 -0
- package/docs/showcase/case1-warehouse-dashboard.tsx +343 -0
- package/docs/showcase/case2-employee-me.tsx +441 -0
- package/docs/showcase/case3-approval-workflow.tsx +527 -0
- package/docs/showcase/case4-login.tsx +307 -0
- package/docs/showcase/case5-shift-calendar.tsx +795 -0
- package/docs/showcase/case6-agency-handy.tsx +1072 -0
- package/docs/showcase/futurelastic-web.tsx +390 -0
- package/docs/showcase/org-switcher.tsx +313 -0
- package/docs/showcase/permission-matrix.tsx +343 -0
- package/docs/showcase/public-landing.tsx +210 -0
- package/docs/showcase/settings-account-sections.tsx +559 -0
- package/docs/showcase/settings-security-mfa.tsx +145 -0
- package/docs/showcase/table-approval-queue.tsx +199 -0
- package/docs/showcase/table-bulk-actions.tsx +460 -0
- package/docs/showcase/table-compact-kintone.tsx +438 -0
- package/docs/showcase/table-conditional-format.tsx +367 -0
- package/docs/showcase/table-crud-list.tsx +544 -0
- package/docs/showcase/table-density.tsx +340 -0
- package/docs/showcase/table-expandable-rows.tsx +471 -0
- package/docs/showcase/table-filter-chips.tsx +461 -0
- package/docs/showcase/table-footer-totals.tsx +311 -0
- package/docs/showcase/table-grouped-subtotals.tsx +388 -0
- package/docs/showcase/table-master-detail.tsx +479 -0
- package/docs/showcase/table-pagination.tsx +320 -0
- package/docs/showcase/table-states.tsx +363 -0
- package/docs/showcase/table-sticky-columns.tsx +373 -0
- package/docs/showcase/table-tree-rows.tsx +444 -0
- package/docs/showcase/table-view-tabs.tsx +488 -0
- package/package.json +10 -11
- package/scripts/_agent-setup.mjs +16 -2
- package/scripts/audit-hook.mjs +3 -13
- package/scripts/init-agent-kit.mjs +1 -14
- package/scripts/postinstall.mjs +12 -12
- package/scripts/ui-audit.mjs +93 -31
- package/scripts/visual-audit-rules.mjs +51 -7
- package/scripts/visual-audit.mjs +118 -47
|
@@ -3,7 +3,7 @@ import { jsx, jsxs } from "react/jsx-runtime";
|
|
|
3
3
|
import * as React from "react";
|
|
4
4
|
import { X } from "lucide-react";
|
|
5
5
|
import { useTranslation } from "../../i18n/use-translation.js";
|
|
6
|
-
import { useFieldNameFallback } from "../../lib/field-a11y.js";
|
|
6
|
+
import { useFieldIdentity, useFieldNameFallback } from "../../lib/field-a11y.js";
|
|
7
7
|
import { cn } from "../../lib/utils.js";
|
|
8
8
|
const inputBaseClass = [
|
|
9
9
|
"ui-control ui-input border-input bg-background w-full rounded-[var(--control-radius)] transition-[color,box-shadow] outline-none",
|
|
@@ -13,6 +13,7 @@ const inputBaseClass = [
|
|
|
13
13
|
];
|
|
14
14
|
const Input = React.forwardRef(
|
|
15
15
|
({
|
|
16
|
+
size,
|
|
16
17
|
className,
|
|
17
18
|
type,
|
|
18
19
|
allowClear = false,
|
|
@@ -29,6 +30,11 @@ const Input = React.forwardRef(
|
|
|
29
30
|
"aria-label": props["aria-label"],
|
|
30
31
|
"aria-labelledby": props["aria-labelledby"]
|
|
31
32
|
});
|
|
33
|
+
const identity = useFieldIdentity({
|
|
34
|
+
id: props.id,
|
|
35
|
+
name: props.name,
|
|
36
|
+
"data-field": props["data-field"]
|
|
37
|
+
});
|
|
32
38
|
const innerRef = React.useRef(null);
|
|
33
39
|
const setRefs = React.useCallback(
|
|
34
40
|
(node) => {
|
|
@@ -68,13 +74,15 @@ const Input = React.forwardRef(
|
|
|
68
74
|
{
|
|
69
75
|
type,
|
|
70
76
|
"data-slot": "input",
|
|
77
|
+
"data-size": size,
|
|
71
78
|
ref: setRefs,
|
|
72
79
|
value,
|
|
73
80
|
defaultValue,
|
|
74
81
|
onChange,
|
|
75
82
|
className: cn(inputBaseClass, className),
|
|
76
83
|
...props,
|
|
77
|
-
...nameFallback
|
|
84
|
+
...nameFallback,
|
|
85
|
+
...identity
|
|
78
86
|
}
|
|
79
87
|
);
|
|
80
88
|
}
|
|
@@ -97,6 +105,7 @@ const Input = React.forwardRef(
|
|
|
97
105
|
{
|
|
98
106
|
type,
|
|
99
107
|
"data-slot": "input",
|
|
108
|
+
"data-size": size,
|
|
100
109
|
ref: setRefs,
|
|
101
110
|
value,
|
|
102
111
|
defaultValue,
|
|
@@ -108,7 +117,8 @@ const Input = React.forwardRef(
|
|
|
108
117
|
className
|
|
109
118
|
),
|
|
110
119
|
...props,
|
|
111
|
-
...nameFallback
|
|
120
|
+
...nameFallback,
|
|
121
|
+
...identity
|
|
112
122
|
}
|
|
113
123
|
),
|
|
114
124
|
trailing != null ? /* @__PURE__ */ jsx("span", { className: "ui-input-trailing", children: trailing }) : null
|
|
@@ -4,7 +4,7 @@ import * as React from "react";
|
|
|
4
4
|
import { CalendarIcon, ChevronLeft, ChevronRight, X } from "lucide-react";
|
|
5
5
|
import { usePickerLocales, useTranslation } from "../../i18n/use-translation.js";
|
|
6
6
|
import { useControlledLatch } from "../../lib/hooks.js";
|
|
7
|
-
import { pickFieldA11y } from "../../lib/field-a11y.js";
|
|
7
|
+
import { pickFieldA11y, useFieldIdentity } from "../../lib/field-a11y.js";
|
|
8
8
|
import { cn } from "../../lib/utils.js";
|
|
9
9
|
import { Button } from "../general/button.js";
|
|
10
10
|
import { Popover, PopoverAnchor, PopoverContent, PopoverTrigger } from "../data-display/popover.js";
|
|
@@ -38,6 +38,7 @@ function MonthPicker({
|
|
|
38
38
|
const inputId = id ?? autoId;
|
|
39
39
|
const dialogId = `${inputId}-dialog`;
|
|
40
40
|
const fieldA11y = pickFieldA11y(ariaProps);
|
|
41
|
+
const identity = useFieldIdentity({ id, name, "data-field": fieldA11y["data-field"] });
|
|
41
42
|
const isControlled = useControlledLatch(valueProp !== void 0);
|
|
42
43
|
const [internalValue, setInternalValue] = React.useState(defaultValue);
|
|
43
44
|
const value = isControlled ? valueProp : internalValue;
|
|
@@ -62,10 +63,10 @@ function MonthPicker({
|
|
|
62
63
|
"div",
|
|
63
64
|
{
|
|
64
65
|
"data-disabled": disabled ? "" : void 0,
|
|
66
|
+
"data-state": open ? "open" : "closed",
|
|
65
67
|
className: cn(
|
|
66
68
|
"ui-control ui-control-composite-field",
|
|
67
|
-
"
|
|
68
|
-
open && "border-ring ring-ring/50 ring-[3px]",
|
|
69
|
+
"aria-invalid:border-destructive",
|
|
69
70
|
className
|
|
70
71
|
),
|
|
71
72
|
onClick: () => {
|
|
@@ -76,7 +77,8 @@ function MonthPicker({
|
|
|
76
77
|
"input",
|
|
77
78
|
{
|
|
78
79
|
id: inputId,
|
|
79
|
-
name,
|
|
80
|
+
name: name ?? identity.name,
|
|
81
|
+
"data-field": fieldA11y["data-field"] ?? identity["data-field"],
|
|
80
82
|
value: text,
|
|
81
83
|
disabled,
|
|
82
84
|
placeholder: placeholder ?? t("dataEntry.monthPicker.placeholder") ?? YM_HINT,
|
|
@@ -2,11 +2,9 @@ import * as React from "react";
|
|
|
2
2
|
import type { MonthRangePickerProp } from "../../props/components/data-entry.prop.js";
|
|
3
3
|
export type { MonthRangePickerProp, MonthRangePickerProp as MonthRangePickerProps, } from "../../props/components/data-entry.prop.js";
|
|
4
4
|
/**
|
|
5
|
-
* MonthRangePicker — year/month (`yyyy/MM`) RANGE rendered as ONE input-styled
|
|
6
|
-
*
|
|
7
|
-
*
|
|
8
|
-
*
|
|
9
|
-
* affordance. Grid picks are two-step (from, then to — swapped when picked
|
|
10
|
-
* backwards) and a pick on a COMPLETE range starts a new one (reset-on-complete).
|
|
5
|
+
* MonthRangePicker — year/month (`yyyy/MM`) RANGE rendered as ONE input-styled control (Ant Design
|
|
6
|
+
* RangePicker convention): `[ from → to ✕ 📅 ]`. The two inner fields stay real, typeable
|
|
7
|
+
* `yyyy/MM` inputs (form-submittable via `${name}_from` / `${name}_to`); the Ant-style month grid
|
|
8
|
+
* is the visual affordance.
|
|
11
9
|
*/
|
|
12
10
|
export declare function MonthRangePicker({ value: valueProp, defaultValue, onValueChange, placeholder, disabled, className, id, name, fromYear, toYear, allowClear, ...ariaProps }: MonthRangePickerProp): React.JSX.Element;
|
|
@@ -4,7 +4,7 @@ import * as React from "react";
|
|
|
4
4
|
import { ArrowRight, CalendarIcon, ChevronLeft, ChevronRight, X } from "lucide-react";
|
|
5
5
|
import { usePickerLocales, useTranslation } from "../../i18n/use-translation.js";
|
|
6
6
|
import { useControlledLatch } from "../../lib/hooks.js";
|
|
7
|
-
import { pickGroupFieldA11y } from "../../lib/field-a11y.js";
|
|
7
|
+
import { pickGroupFieldA11y, useFieldIdentity } from "../../lib/field-a11y.js";
|
|
8
8
|
import { cn } from "../../lib/utils.js";
|
|
9
9
|
import { Button } from "../general/button.js";
|
|
10
10
|
import { Popover, PopoverAnchor, PopoverContent, PopoverTrigger } from "../data-display/popover.js";
|
|
@@ -40,6 +40,9 @@ function MonthRangePicker({
|
|
|
40
40
|
const groupId = id ?? autoId;
|
|
41
41
|
const fromId = `${groupId}-from`;
|
|
42
42
|
const toId = `${groupId}-to`;
|
|
43
|
+
const identity = useFieldIdentity({ id: groupId, name, "data-field": groupA11y["data-field"] });
|
|
44
|
+
const rangeField = groupA11y["data-field"] ?? identity["data-field"];
|
|
45
|
+
const rangeName = name ?? identity.name;
|
|
43
46
|
const isControlled = useControlledLatch(valueProp !== void 0);
|
|
44
47
|
const [internalValue, setInternalValue] = React.useState(defaultValue);
|
|
45
48
|
const value = isControlled ? valueProp : internalValue;
|
|
@@ -107,12 +110,13 @@ function MonthRangePicker({
|
|
|
107
110
|
role: "group",
|
|
108
111
|
id: groupId,
|
|
109
112
|
...groupA11y,
|
|
113
|
+
"data-field": rangeField,
|
|
110
114
|
"aria-disabled": disabled ? true : void 0,
|
|
111
115
|
"data-disabled": disabled ? "" : void 0,
|
|
116
|
+
"data-state": open ? "open" : "closed",
|
|
112
117
|
className: cn(
|
|
113
118
|
"ui-control ui-control-composite-field",
|
|
114
|
-
"
|
|
115
|
-
open && "border-ring ring-ring/50 ring-[3px]",
|
|
119
|
+
"aria-invalid:border-destructive",
|
|
116
120
|
className
|
|
117
121
|
),
|
|
118
122
|
onClick: () => {
|
|
@@ -123,7 +127,8 @@ function MonthRangePicker({
|
|
|
123
127
|
"input",
|
|
124
128
|
{
|
|
125
129
|
id: fromId,
|
|
126
|
-
|
|
130
|
+
"data-field": rangeField ? `${rangeField}_from` : void 0,
|
|
131
|
+
name: rangeName ? `${rangeName}_from` : void 0,
|
|
127
132
|
value: fromText,
|
|
128
133
|
disabled,
|
|
129
134
|
placeholder: resolvedPlaceholder,
|
|
@@ -144,7 +149,8 @@ function MonthRangePicker({
|
|
|
144
149
|
"input",
|
|
145
150
|
{
|
|
146
151
|
id: toId,
|
|
147
|
-
|
|
152
|
+
"data-field": rangeField ? `${rangeField}_to` : void 0,
|
|
153
|
+
name: rangeName ? `${rangeName}_to` : void 0,
|
|
148
154
|
value: toText,
|
|
149
155
|
disabled,
|
|
150
156
|
placeholder: resolvedPlaceholder,
|
|
@@ -2,11 +2,7 @@ import * as React from "react";
|
|
|
2
2
|
export type { NumberInputProp, NumberInputProp as NumberInputProps, } from "../../props/components/data-entry.prop.js";
|
|
3
3
|
/**
|
|
4
4
|
* NumberInput — WAI-ARIA spinbutton: a localized numeric `<Input>` with increment/decrement steps.
|
|
5
|
-
*
|
|
6
|
-
* Composes the real `Input` primitive (no raw `<input>`) plus two icon `Button`s. The text input is
|
|
7
|
-
* the `role="spinbutton"` element carrying `aria-valuenow/min/max/text`; type freely, ArrowUp/Down
|
|
8
|
-
* (Shift = ×10) step, and the value commits clamped + rounded to `precision` on blur/Enter/step.
|
|
9
|
-
* Display formats via `Intl.NumberFormat` at rest, but stays raw and typeable while focused.
|
|
5
|
+
* Composes the real `Input` primitive (no raw `<input>`) plus two icon `Button`s.
|
|
10
6
|
*/
|
|
11
7
|
export declare const NumberInput: React.ForwardRefExoticComponent<import("../../lib/field-a11y.js").FieldA11yProps & {
|
|
12
8
|
value?: import("../../props/index.js").ValueProp<number | null>;
|
|
@@ -4,7 +4,7 @@ import * as React from "react";
|
|
|
4
4
|
import * as RadioGroupPrimitive from "@radix-ui/react-radio-group";
|
|
5
5
|
import { Circle } from "lucide-react";
|
|
6
6
|
import { cn } from "../../lib/utils.js";
|
|
7
|
-
import { pickFieldA11y } from "../../lib/field-a11y.js";
|
|
7
|
+
import { pickFieldA11y, useFieldIdentity } from "../../lib/field-a11y.js";
|
|
8
8
|
import { Field } from "./field.js";
|
|
9
9
|
import { choiceGroupClassName } from "./choice-option.js";
|
|
10
10
|
const RadioGroupRoot = React.forwardRef(({ className, ...props }, ref) => /* @__PURE__ */ jsx(
|
|
@@ -23,7 +23,6 @@ const RadioItem = React.forwardRef(({ className, ...props }, ref) => /* @__PURE_
|
|
|
23
23
|
ref,
|
|
24
24
|
"data-slot": "radio-group-item",
|
|
25
25
|
className: cn(
|
|
26
|
-
// `disabled:cursor-not-allowed disabled:opacity-50` DELETED, not moved (#319):
|
|
27
26
|
// `.ui-radio:disabled, .ui-radio[data-disabled]` in styles/control.css already declares both
|
|
28
27
|
// and reads --disabled-opacity. The utility was layered after components, so it silently
|
|
29
28
|
// outranked that token — a service theme's --disabled-opacity never reached a radio.
|
|
@@ -58,6 +57,10 @@ function RadioGroupOptions({
|
|
|
58
57
|
}) {
|
|
59
58
|
const reactId = React.useId();
|
|
60
59
|
const groupA11y = pickFieldA11y(ariaProps);
|
|
60
|
+
const identity = useFieldIdentity({ id, name, "data-field": groupA11y["data-field"] });
|
|
61
|
+
const resolvedName = name ?? identity.name;
|
|
62
|
+
const resolvedField = groupA11y["data-field"] ?? identity["data-field"];
|
|
63
|
+
const optionDomId = (optionValue, index) => id ? `${id}-${optionValue}` : `${reactId}-${optionValue}-${index}`;
|
|
61
64
|
if (options && options.length > 0) {
|
|
62
65
|
return /* @__PURE__ */ jsx(
|
|
63
66
|
RadioGroupRoot,
|
|
@@ -66,14 +69,23 @@ function RadioGroupOptions({
|
|
|
66
69
|
defaultValue,
|
|
67
70
|
onValueChange,
|
|
68
71
|
disabled,
|
|
69
|
-
name,
|
|
72
|
+
name: resolvedName,
|
|
70
73
|
id,
|
|
71
74
|
...groupA11y,
|
|
75
|
+
"data-field": resolvedField,
|
|
72
76
|
"data-orientation": orientation,
|
|
73
77
|
className: choiceGroupClassName(orientation, className),
|
|
74
78
|
children: options.map((opt, index) => {
|
|
75
|
-
const
|
|
76
|
-
return /* @__PURE__ */ jsx(Field, { id:
|
|
79
|
+
const optionId = optionDomId(opt.value, index);
|
|
80
|
+
return /* @__PURE__ */ jsx(Field, { id: optionId, label: opt.label, description: opt.description, children: /* @__PURE__ */ jsx(
|
|
81
|
+
RadioItem,
|
|
82
|
+
{
|
|
83
|
+
id: optionId,
|
|
84
|
+
value: opt.value,
|
|
85
|
+
disabled: opt.disabled,
|
|
86
|
+
"data-field": resolvedField
|
|
87
|
+
}
|
|
88
|
+
) }, opt.value);
|
|
77
89
|
})
|
|
78
90
|
}
|
|
79
91
|
);
|
|
@@ -85,9 +97,10 @@ function RadioGroupOptions({
|
|
|
85
97
|
defaultValue,
|
|
86
98
|
onValueChange,
|
|
87
99
|
disabled,
|
|
88
|
-
name,
|
|
100
|
+
name: resolvedName,
|
|
89
101
|
id,
|
|
90
102
|
...groupA11y,
|
|
103
|
+
"data-field": resolvedField,
|
|
91
104
|
"data-orientation": orientation,
|
|
92
105
|
className: choiceGroupClassName(orientation, className),
|
|
93
106
|
children
|
|
@@ -4,9 +4,7 @@ export type { SearchSelectProp, SearchSelectProp as SearchSelectProps, SearchSel
|
|
|
4
4
|
/**
|
|
5
5
|
* SearchSelect — a searchable single-select combobox with a debounced search box, optional
|
|
6
6
|
* optgroup-style grouping (`option.group`), and loading/empty states. Drive it EITHER remotely
|
|
7
|
-
* with `loadOptions({ query, page })` (server search + infinite scroll) OR with a static
|
|
8
|
-
*
|
|
9
|
-
* Custom per-option rendering via `renderOption` (Ant-Design style). Form-submittable via
|
|
10
|
-
* `name`; e2e-testable by the trigger's `data-testid` + each option's `${data-testid}-option-${value}`.
|
|
7
|
+
* with `loadOptions({ query, page })` (server search + infinite scroll) OR with a static `options`
|
|
8
|
+
* array (client-side filter) — the latter supersedes the legacy `Autocomplete`.
|
|
11
9
|
*/
|
|
12
|
-
export declare function SearchSelect({ value: valueProp, defaultValue, onValueChange, options: staticOptions, loadOptions, renderOption, labelRender, selectedLabel, selectedIcon, placeholder, searchPlaceholder, emptyMessage, loadingMessage, errorMessage, clearLabel, clearable, disabled, readOnly, size, open: openProp, onOpenChange, search: searchProp, onSearchChange, filterOption, renderError, renderLoadMore, name, id, className, "data-testid": dataTestId, "aria-label": ariaLabel, "aria-labelledby": ariaLabelledby, "aria-describedby": ariaDescribedby, "aria-errormessage": ariaErrorMessage, "aria-invalid": ariaInvalid, "aria-required": ariaRequired, }: SearchSelectProp): React.JSX.Element;
|
|
10
|
+
export declare function SearchSelect({ value: valueProp, defaultValue, onValueChange, options: staticOptions, loadOptions, renderOption, labelRender, selectedLabel, selectedIcon, placeholder, searchPlaceholder, emptyMessage, loadingMessage, errorMessage, clearLabel, clearable, disabled, readOnly, size, open: openProp, onOpenChange, search: searchProp, onSearchChange, filterOption, renderError, renderLoadMore, name, id, className, "data-testid": dataTestId, "data-field": dataField, "aria-label": ariaLabel, "aria-labelledby": ariaLabelledby, "aria-describedby": ariaDescribedby, "aria-errormessage": ariaErrorMessage, "aria-invalid": ariaInvalid, "aria-required": ariaRequired, }: SearchSelectProp): React.JSX.Element;
|
|
@@ -3,7 +3,7 @@ import { Fragment, jsx, jsxs } from "react/jsx-runtime";
|
|
|
3
3
|
import * as React from "react";
|
|
4
4
|
import { ChevronsUpDown, Loader2, X } from "lucide-react";
|
|
5
5
|
import { useTranslation } from "../../i18n/use-translation.js";
|
|
6
|
-
import { useFieldNameFallback } from "../../lib/field-a11y.js";
|
|
6
|
+
import { useFieldIdentity, useFieldNameFallback } from "../../lib/field-a11y.js";
|
|
7
7
|
import { cn } from "../../lib/utils.js";
|
|
8
8
|
import { controlOpenRingClass } from "../../lib/control-styles.js";
|
|
9
9
|
import { Button } from "../general/button.js";
|
|
@@ -42,6 +42,7 @@ function SearchSelect({
|
|
|
42
42
|
id,
|
|
43
43
|
className,
|
|
44
44
|
"data-testid": dataTestId,
|
|
45
|
+
"data-field": dataField,
|
|
45
46
|
"aria-label": ariaLabel,
|
|
46
47
|
"aria-labelledby": ariaLabelledby,
|
|
47
48
|
"aria-describedby": ariaDescribedby,
|
|
@@ -54,6 +55,9 @@ function SearchSelect({
|
|
|
54
55
|
"aria-label": ariaLabel,
|
|
55
56
|
"aria-labelledby": ariaLabelledby
|
|
56
57
|
});
|
|
58
|
+
const identity = useFieldIdentity({ id, name, "data-field": dataField });
|
|
59
|
+
const resolvedName = name ?? identity.name;
|
|
60
|
+
const resolvedField = dataField ?? identity["data-field"];
|
|
57
61
|
const triggerAriaLabel = ariaLabel ?? nameFallback["aria-label"];
|
|
58
62
|
const triggerAriaLabelledby = ariaLabelledby ?? nameFallback["aria-labelledby"];
|
|
59
63
|
const reactId = React.useId();
|
|
@@ -254,6 +258,8 @@ function SearchSelect({
|
|
|
254
258
|
"aria-readonly": readOnly || void 0,
|
|
255
259
|
disabled,
|
|
256
260
|
"data-testid": dataTestId,
|
|
261
|
+
"data-field": resolvedField,
|
|
262
|
+
"data-value": value || void 0,
|
|
257
263
|
className: cn(
|
|
258
264
|
"w-full justify-start font-normal",
|
|
259
265
|
controlOpenRingClass,
|
|
@@ -275,7 +281,7 @@ function SearchSelect({
|
|
|
275
281
|
)
|
|
276
282
|
}
|
|
277
283
|
) }),
|
|
278
|
-
|
|
284
|
+
resolvedName ? /* @__PURE__ */ jsx("input", { type: "hidden", name: resolvedName, value, readOnly: true }) : null,
|
|
279
285
|
/* @__PURE__ */ jsx(
|
|
280
286
|
PopoverContent,
|
|
281
287
|
{
|
|
@@ -1,4 +1,5 @@
|
|
|
1
1
|
import * as React from "react";
|
|
2
|
+
import type { ControlWidthProp } from "../../props/vocabulary/shared.prop.js";
|
|
2
3
|
import * as SelectPrimitive from "@radix-ui/react-select";
|
|
3
4
|
import type { FieldA11yProps } from "../../lib/field-a11y.js";
|
|
4
5
|
import type { SelectDataProp } from "../../props/components/data-entry.prop.js";
|
|
@@ -20,13 +21,25 @@ export declare function SelectGroup(props: React.ComponentProps<typeof SelectPri
|
|
|
20
21
|
export declare function SelectValue(props: React.ComponentProps<typeof SelectPrimitive.Value>): React.JSX.Element;
|
|
21
22
|
export declare const SelectTrigger: React.ForwardRefExoticComponent<Omit<SelectPrimitive.SelectTriggerProps & React.RefAttributes<HTMLButtonElement>, "ref"> & {
|
|
22
23
|
size?: "sm" | "md";
|
|
24
|
+
/**
|
|
25
|
+
* `full` (default) fills the field column — right inside a FormField. `auto` sizes to the
|
|
26
|
+
* selected label — right in a PageContainer `extra` slot, a toolbar or a footer row, where a
|
|
27
|
+
* full-width trigger swallows the row and starves its siblings (text truncated to "UA…").
|
|
28
|
+
*/
|
|
29
|
+
width?: ControlWidthProp;
|
|
23
30
|
/**
|
|
24
31
|
* Show the built-in chevron disclosure indicator (default true). Set `false` for specialized
|
|
25
32
|
* triggers — icon-only, or one that already renders its own affordance — so it isn't
|
|
26
|
-
* duplicated.
|
|
27
|
-
* descendant CSS is needed to remove it.
|
|
33
|
+
* duplicated.
|
|
28
34
|
*/
|
|
29
35
|
showIndicator?: boolean;
|
|
36
|
+
"data-field"?: string;
|
|
37
|
+
/**
|
|
38
|
+
* Normally supplied by `Select` itself — the trigger shows the option's LABEL, and this is the
|
|
39
|
+
* only place the underlying value is readable from the DOM without reaching into Radix's
|
|
40
|
+
* aria-hidden native `<select>`.
|
|
41
|
+
*/
|
|
42
|
+
"data-value"?: string;
|
|
30
43
|
} & React.RefAttributes<HTMLButtonElement>>;
|
|
31
44
|
export declare const SelectScrollUpButton: React.ForwardRefExoticComponent<Omit<SelectPrimitive.SelectScrollUpButtonProps & React.RefAttributes<HTMLDivElement>, "ref"> & React.RefAttributes<HTMLDivElement>>;
|
|
32
45
|
export declare const SelectScrollDownButton: React.ForwardRefExoticComponent<Omit<SelectPrimitive.SelectScrollDownButtonProps & React.RefAttributes<HTMLDivElement>, "ref"> & React.RefAttributes<HTMLDivElement>>;
|
|
@@ -7,6 +7,7 @@ import { cn } from "../../lib/utils.js";
|
|
|
7
7
|
import { controlTriggerClass } from "../../lib/control-styles.js";
|
|
8
8
|
import {
|
|
9
9
|
mergeAriaIds,
|
|
10
|
+
useFieldIdentity,
|
|
10
11
|
omitFieldA11y,
|
|
11
12
|
pickFieldA11y,
|
|
12
13
|
useFieldNameFallback
|
|
@@ -26,7 +27,36 @@ function Select(props) {
|
|
|
26
27
|
function CompoundSelect({ id, ...props }) {
|
|
27
28
|
const fieldA11y = pickFieldA11y(props);
|
|
28
29
|
const rootProps = omitFieldA11y(props);
|
|
29
|
-
|
|
30
|
+
const [uncontrolled, setUncontrolled] = React.useState(props.defaultValue);
|
|
31
|
+
const value = props.value ?? uncontrolled;
|
|
32
|
+
const identity = useFieldIdentity({
|
|
33
|
+
id,
|
|
34
|
+
name: props.name,
|
|
35
|
+
"data-field": fieldA11y["data-field"]
|
|
36
|
+
});
|
|
37
|
+
return /* @__PURE__ */ jsx(
|
|
38
|
+
SelectFieldA11yContext.Provider,
|
|
39
|
+
{
|
|
40
|
+
value: {
|
|
41
|
+
...fieldA11y,
|
|
42
|
+
"data-field": identity["data-field"] ?? fieldA11y["data-field"],
|
|
43
|
+
id,
|
|
44
|
+
value
|
|
45
|
+
},
|
|
46
|
+
children: /* @__PURE__ */ jsx(
|
|
47
|
+
SelectPrimitive.Root,
|
|
48
|
+
{
|
|
49
|
+
"data-slot": "select",
|
|
50
|
+
...rootProps,
|
|
51
|
+
name: props.name ?? identity.name,
|
|
52
|
+
onValueChange: (next) => {
|
|
53
|
+
setUncontrolled(next);
|
|
54
|
+
props.onValueChange?.(next);
|
|
55
|
+
}
|
|
56
|
+
}
|
|
57
|
+
)
|
|
58
|
+
}
|
|
59
|
+
);
|
|
30
60
|
}
|
|
31
61
|
function SelectGroup(props) {
|
|
32
62
|
return /* @__PURE__ */ jsx(SelectPrimitive.Group, { "data-slot": "select-group", ...props });
|
|
@@ -34,7 +64,7 @@ function SelectGroup(props) {
|
|
|
34
64
|
function SelectValue(props) {
|
|
35
65
|
return /* @__PURE__ */ jsx(SelectPrimitive.Value, { "data-slot": "select-value", ...props });
|
|
36
66
|
}
|
|
37
|
-
const SelectTrigger = React.forwardRef(({ className, children, size = "md", showIndicator = true, ...props }, ref) => {
|
|
67
|
+
const SelectTrigger = React.forwardRef(({ className, children, size = "md", width = "full", showIndicator = true, ...props }, ref) => {
|
|
38
68
|
const field = React.useContext(SelectFieldA11yContext);
|
|
39
69
|
const ownsName = props["aria-label"] !== void 0 || props["aria-labelledby"] !== void 0;
|
|
40
70
|
const fieldOwnsName = field?.["aria-label"] !== void 0 || field?.["aria-labelledby"] !== void 0;
|
|
@@ -54,21 +84,26 @@ const SelectTrigger = React.forwardRef(({ className, children, size = "md", show
|
|
|
54
84
|
field?.["aria-errormessage"]
|
|
55
85
|
),
|
|
56
86
|
"aria-required": props["aria-required"] ?? field?.["aria-required"],
|
|
57
|
-
"aria-invalid": props["aria-invalid"] ?? field?.["aria-invalid"]
|
|
87
|
+
"aria-invalid": props["aria-invalid"] ?? field?.["aria-invalid"],
|
|
88
|
+
"data-field": props["data-field"] ?? field?.["data-field"]
|
|
58
89
|
} : void 0;
|
|
90
|
+
const dataValue = (props["data-value"] ?? field?.value) || void 0;
|
|
59
91
|
return /* @__PURE__ */ jsxs(
|
|
60
92
|
SelectPrimitive.Trigger,
|
|
61
93
|
{
|
|
62
94
|
ref,
|
|
63
95
|
"data-slot": "select-trigger",
|
|
64
96
|
"data-size": size,
|
|
97
|
+
"data-width": width,
|
|
65
98
|
className: cn(
|
|
66
99
|
controlTriggerClass,
|
|
67
|
-
"
|
|
100
|
+
width === "auto" ? "w-auto" : "w-full",
|
|
101
|
+
"aria-invalid:border-destructive aria-invalid:ring-destructive/20 data-[placeholder]:text-muted-foreground [&_svg:not([class*='text-'])]:text-muted-foreground whitespace-nowrap transition-[color,box-shadow] outline-none *:data-[slot=select-value]:line-clamp-1 *:data-[slot=select-value]:flex *:data-[slot=select-value]:items-center",
|
|
68
102
|
className
|
|
69
103
|
),
|
|
70
104
|
...props,
|
|
71
105
|
...fieldA11y,
|
|
106
|
+
"data-value": dataValue,
|
|
72
107
|
children: [
|
|
73
108
|
children,
|
|
74
109
|
showIndicator ? /* @__PURE__ */ jsx(SelectPrimitive.Icon, { asChild: true, children: /* @__PURE__ */ jsx(
|
|
@@ -212,12 +247,18 @@ function DataSelect({
|
|
|
212
247
|
id,
|
|
213
248
|
className,
|
|
214
249
|
"data-testid": dataTestId,
|
|
250
|
+
"data-field": dataField,
|
|
215
251
|
...rest
|
|
216
252
|
}) {
|
|
217
253
|
const ariaProps = Object.fromEntries(
|
|
218
254
|
Object.entries(rest).filter(([key]) => key.startsWith("aria-"))
|
|
219
255
|
);
|
|
220
256
|
const { t } = useTranslation();
|
|
257
|
+
const [uncontrolledValue, setUncontrolledValue] = React.useState(defaultValue);
|
|
258
|
+
const currentValue = value ?? uncontrolledValue;
|
|
259
|
+
const identity = useFieldIdentity({ id, name, "data-field": dataField });
|
|
260
|
+
const resolvedName = name ?? identity.name;
|
|
261
|
+
const resolvedField = dataField ?? identity["data-field"];
|
|
221
262
|
const searchable = showSearch ?? Boolean(loadOptions);
|
|
222
263
|
const hasOptions = options.length > 0;
|
|
223
264
|
if (searchable) {
|
|
@@ -250,10 +291,11 @@ function DataSelect({
|
|
|
250
291
|
filterOption,
|
|
251
292
|
renderError,
|
|
252
293
|
renderLoadMore,
|
|
253
|
-
name,
|
|
294
|
+
name: resolvedName,
|
|
254
295
|
id,
|
|
255
296
|
className,
|
|
256
297
|
"data-testid": dataTestId,
|
|
298
|
+
"data-field": resolvedField,
|
|
257
299
|
...ariaProps
|
|
258
300
|
}
|
|
259
301
|
);
|
|
@@ -278,18 +320,23 @@ function DataSelect({
|
|
|
278
320
|
"data-slot": "select",
|
|
279
321
|
value: isControlled ? value : void 0,
|
|
280
322
|
defaultValue: isControlled ? void 0 : defaultValue || void 0,
|
|
281
|
-
onValueChange: (next) =>
|
|
282
|
-
next
|
|
283
|
-
|
|
284
|
-
|
|
323
|
+
onValueChange: (next) => {
|
|
324
|
+
setUncontrolledValue(next);
|
|
325
|
+
onValueChange?.(
|
|
326
|
+
next,
|
|
327
|
+
options.find((option) => option.value === next)
|
|
328
|
+
);
|
|
329
|
+
},
|
|
285
330
|
disabled: disabled || !hasOptions,
|
|
286
|
-
name,
|
|
331
|
+
name: resolvedName,
|
|
287
332
|
children: [
|
|
288
333
|
/* @__PURE__ */ jsx(
|
|
289
334
|
SelectTrigger,
|
|
290
335
|
{
|
|
291
336
|
id,
|
|
292
337
|
"data-testid": dataTestId,
|
|
338
|
+
"data-field": resolvedField,
|
|
339
|
+
"data-value": currentValue || void 0,
|
|
293
340
|
className: cn(showClear && "ui-control-trigger-affixed", canClear ? void 0 : className),
|
|
294
341
|
showIndicator: !showClear,
|
|
295
342
|
...ariaProps,
|
|
@@ -3,8 +3,15 @@ import { Fragment, jsx, jsxs } from "react/jsx-runtime";
|
|
|
3
3
|
import * as React from "react";
|
|
4
4
|
import * as SwitchPrimitive from "@radix-ui/react-switch";
|
|
5
5
|
import { cn } from "../../lib/utils.js";
|
|
6
|
+
import { useFieldIdentity } from "../../lib/field-a11y.js";
|
|
6
7
|
const Switch = React.forwardRef(
|
|
7
8
|
({ className, size = "md", name, checked, defaultChecked = false, onCheckedChange, ...props }, ref) => {
|
|
9
|
+
const identity = useFieldIdentity({
|
|
10
|
+
id: props.id,
|
|
11
|
+
name,
|
|
12
|
+
"data-field": props["data-field"]
|
|
13
|
+
});
|
|
14
|
+
const resolvedName = name ?? identity.name;
|
|
8
15
|
const [internalChecked, setInternalChecked] = React.useState(defaultChecked);
|
|
9
16
|
const isControlled = checked !== void 0;
|
|
10
17
|
const isChecked = isControlled ? checked : internalChecked;
|
|
@@ -15,7 +22,7 @@ const Switch = React.forwardRef(
|
|
|
15
22
|
onCheckedChange?.(next);
|
|
16
23
|
};
|
|
17
24
|
return /* @__PURE__ */ jsxs(Fragment, { children: [
|
|
18
|
-
|
|
25
|
+
resolvedName ? /* @__PURE__ */ jsx("input", { type: "hidden", name: resolvedName, value: isChecked ? "1" : "0", readOnly: true }) : null,
|
|
19
26
|
/* @__PURE__ */ jsx(
|
|
20
27
|
SwitchPrimitive.Root,
|
|
21
28
|
{
|
|
@@ -25,7 +32,6 @@ const Switch = React.forwardRef(
|
|
|
25
32
|
checked: isChecked,
|
|
26
33
|
onCheckedChange: handleCheckedChange,
|
|
27
34
|
className: cn(
|
|
28
|
-
// `disabled:cursor-not-allowed disabled:opacity-50` DELETED, not moved (#319):
|
|
29
35
|
// `.ui-switch:disabled, .ui-switch[data-disabled]` in styles/control.css already
|
|
30
36
|
// declares both and reads --disabled-opacity. The utility was layered after
|
|
31
37
|
// components, so it silently outranked that token. Byte-identical: the token
|
|
@@ -35,6 +41,7 @@ const Switch = React.forwardRef(
|
|
|
35
41
|
className
|
|
36
42
|
),
|
|
37
43
|
...props,
|
|
44
|
+
"data-field": identity["data-field"] ?? props["data-field"],
|
|
38
45
|
children: /* @__PURE__ */ jsx(SwitchPrimitive.Thumb, { "data-slot": "switch-thumb", className: "ui-switch-thumb" })
|
|
39
46
|
}
|
|
40
47
|
)
|
|
@@ -5,20 +5,17 @@ export type TextareaProps = React.TextareaHTMLAttributes<HTMLTextAreaElement> &
|
|
|
5
5
|
/** Called after the field is cleared via the inline ✕. */
|
|
6
6
|
onClear?: () => void;
|
|
7
7
|
/**
|
|
8
|
-
* `ghost` strips the field's own border, background and focus ring, for a textarea embedded
|
|
9
|
-
*
|
|
10
|
-
*
|
|
8
|
+
* `ghost` strips the field's own border, background and focus ring, for a textarea embedded in a
|
|
9
|
+
* surface that already draws the box (a chat composer inside a Card). The surface then owns
|
|
10
|
+
* focus — give it `focus-within`.
|
|
11
11
|
*/
|
|
12
12
|
variant?: "default" | "ghost";
|
|
13
13
|
/**
|
|
14
|
-
* Grow the control with its content instead of holding a fixed `rows` height (default false —
|
|
15
|
-
* the inert default, so every existing `<Textarea>` keeps the geometry it has today).
|
|
16
|
-
*
|
|
17
14
|
* The floor is `minRows` (or `rows`, when that is the only one given) and never undercuts the
|
|
18
15
|
* `--control-height` tier; past `maxRows` the control stops growing and scrolls internally.
|
|
19
16
|
* Sizing is done in CSS by a hidden replica of the text, so it follows a paste, a programmatic
|
|
20
17
|
* value change, a font swap and a container resize — not just typing — and it never writes
|
|
21
|
-
* `style.height` or reads `scrollHeight`.
|
|
18
|
+
* `style.height` or reads `scrollHeight`.
|
|
22
19
|
*/
|
|
23
20
|
autoGrow?: boolean;
|
|
24
21
|
/**
|
|
@@ -29,7 +26,7 @@ export type TextareaProps = React.TextareaHTMLAttributes<HTMLTextAreaElement> &
|
|
|
29
26
|
/**
|
|
30
27
|
* Ceiling in text rows while `autoGrow` (theme default `--textarea-autogrow-max-height-rows`,
|
|
31
28
|
* 8); beyond it the control scrolls internally rather than pushing the page. Pass `0` for no
|
|
32
|
-
* ceiling — only correct inside an owning scroll container.
|
|
29
|
+
* ceiling — only correct inside an owning scroll container.
|
|
33
30
|
*/
|
|
34
31
|
maxRows?: number;
|
|
35
32
|
};
|
|
@@ -39,20 +36,17 @@ export declare const Textarea: React.ForwardRefExoticComponent<React.TextareaHTM
|
|
|
39
36
|
/** Called after the field is cleared via the inline ✕. */
|
|
40
37
|
onClear?: () => void;
|
|
41
38
|
/**
|
|
42
|
-
* `ghost` strips the field's own border, background and focus ring, for a textarea embedded
|
|
43
|
-
*
|
|
44
|
-
*
|
|
39
|
+
* `ghost` strips the field's own border, background and focus ring, for a textarea embedded in a
|
|
40
|
+
* surface that already draws the box (a chat composer inside a Card). The surface then owns
|
|
41
|
+
* focus — give it `focus-within`.
|
|
45
42
|
*/
|
|
46
43
|
variant?: "default" | "ghost";
|
|
47
44
|
/**
|
|
48
|
-
* Grow the control with its content instead of holding a fixed `rows` height (default false —
|
|
49
|
-
* the inert default, so every existing `<Textarea>` keeps the geometry it has today).
|
|
50
|
-
*
|
|
51
45
|
* The floor is `minRows` (or `rows`, when that is the only one given) and never undercuts the
|
|
52
46
|
* `--control-height` tier; past `maxRows` the control stops growing and scrolls internally.
|
|
53
47
|
* Sizing is done in CSS by a hidden replica of the text, so it follows a paste, a programmatic
|
|
54
48
|
* value change, a font swap and a container resize — not just typing — and it never writes
|
|
55
|
-
* `style.height` or reads `scrollHeight`.
|
|
49
|
+
* `style.height` or reads `scrollHeight`.
|
|
56
50
|
*/
|
|
57
51
|
autoGrow?: boolean;
|
|
58
52
|
/**
|
|
@@ -63,7 +57,7 @@ export declare const Textarea: React.ForwardRefExoticComponent<React.TextareaHTM
|
|
|
63
57
|
/**
|
|
64
58
|
* Ceiling in text rows while `autoGrow` (theme default `--textarea-autogrow-max-height-rows`,
|
|
65
59
|
* 8); beyond it the control scrolls internally rather than pushing the page. Pass `0` for no
|
|
66
|
-
* ceiling — only correct inside an owning scroll container.
|
|
60
|
+
* ceiling — only correct inside an owning scroll container.
|
|
67
61
|
*/
|
|
68
62
|
maxRows?: number;
|
|
69
63
|
} & React.RefAttributes<HTMLTextAreaElement>>;
|
|
@@ -4,6 +4,7 @@ import * as React from "react";
|
|
|
4
4
|
import { X } from "lucide-react";
|
|
5
5
|
import { useTranslation } from "../../i18n/use-translation.js";
|
|
6
6
|
import { cn } from "../../lib/utils.js";
|
|
7
|
+
import { useFieldIdentity } from "../../lib/field-a11y.js";
|
|
7
8
|
import { controlMultilineClass, controlMultilineGhostClass } from "../../lib/control-styles.js";
|
|
8
9
|
const UNBOUNDED_ROWS = "infinity";
|
|
9
10
|
const Textarea = React.forwardRef(
|
|
@@ -26,6 +27,11 @@ const Textarea = React.forwardRef(
|
|
|
26
27
|
}, ref) => {
|
|
27
28
|
const { t } = useTranslation();
|
|
28
29
|
const base = variant === "ghost" ? controlMultilineGhostClass : controlMultilineClass;
|
|
30
|
+
const identity = useFieldIdentity({
|
|
31
|
+
id: props.id,
|
|
32
|
+
name: props.name,
|
|
33
|
+
"data-field": props["data-field"]
|
|
34
|
+
});
|
|
29
35
|
const innerRef = React.useRef(null);
|
|
30
36
|
const setRefs = React.useCallback(
|
|
31
37
|
(node) => {
|
|
@@ -110,7 +116,8 @@ const Textarea = React.forwardRef(
|
|
|
110
116
|
onCompositionEnd: handleCompositionEnd,
|
|
111
117
|
style,
|
|
112
118
|
className: cn(base, showClear && "ui-input--trailing-affix", className),
|
|
113
|
-
...props
|
|
119
|
+
...props,
|
|
120
|
+
...identity
|
|
114
121
|
}
|
|
115
122
|
);
|
|
116
123
|
if (!needsWrapper) return field;
|