@godxjp/ui 19.1.0 → 19.3.1
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/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 +20 -14
- package/dist/components/data-display/badge.js +18 -4
- 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/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 +6 -1
- package/dist/components/data-entry/date-range-picker.d.ts +1 -1
- package/dist/components/data-entry/date-range-picker.js +8 -3
- package/dist/components/data-entry/form-errors.d.ts +7 -18
- package/dist/components/data-entry/form-field.js +1 -5
- 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 +3 -0
- package/dist/components/data-entry/month-picker.js +2 -2
- package/dist/components/data-entry/month-range-picker.d.ts +4 -6
- package/dist/components/data-entry/month-range-picker.js +2 -2
- 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 +0 -1
- package/dist/components/data-entry/search-select.d.ts +2 -4
- package/dist/components/data-entry/select.d.ts +11 -6
- package/dist/components/data-entry/select.js +4 -2
- package/dist/components/data-entry/switch.js +0 -1
- package/dist/components/data-entry/textarea.d.ts +10 -16
- package/dist/components/data-entry/time-picker.d.ts +3 -5
- 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 +11 -68
- package/dist/lib/field-a11y.js +0 -1
- 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 +15 -38
- package/dist/props/components/charts.prop.d.ts +2 -3
- package/dist/props/components/data-display.prop.d.ts +55 -72
- package/dist/props/components/data-entry.prop.d.ts +35 -40
- 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 +36 -1
- package/dist/props/registry.js +45 -1
- 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 +19 -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 +12 -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 +283 -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 +160 -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 +188 -0
- package/docs/data-display/popover-touch.tsx +27 -0
- package/docs/data-display/popover.tsx +246 -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 +303 -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 +175 -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 +330 -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 +102 -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 +420 -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 +204 -0
- package/docs/foundation/density.tsx +232 -0
- package/docs/foundation/email-tokens.tsx +323 -0
- package/docs/foundation/radius-shadow.tsx +154 -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 +135 -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 +266 -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 +954 -0
- package/docs/layout/resizable-panel.tsx +419 -0
- package/docs/layout/responsive-grid.tsx +243 -0
- package/docs/layout/separator.tsx +327 -0
- package/docs/layout/service-role-panel.tsx +144 -0
- package/docs/layout/sidebar.tsx +609 -0
- package/docs/layout/split-pane.tsx +468 -0
- package/docs/layout/topbar.tsx +349 -0
- package/docs/navigation/app-setting-picker.tsx +142 -0
- package/docs/navigation/breadcrumb.tsx +135 -0
- package/docs/navigation/context-menu.tsx +123 -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 +158 -0
- package/docs/navigation/pagination.tsx +241 -0
- package/docs/navigation/steps.tsx +265 -0
- package/docs/navigation/tabs-rtl.tsx +28 -0
- package/docs/navigation/tabs.tsx +314 -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 +455 -0
- package/docs/showcase/acme-website.tsx +461 -0
- package/docs/showcase/case1-warehouse-dashboard.tsx +359 -0
- package/docs/showcase/case2-employee-me.tsx +444 -0
- package/docs/showcase/case3-approval-workflow.tsx +529 -0
- package/docs/showcase/case4-login.tsx +313 -0
- package/docs/showcase/case5-shift-calendar.tsx +795 -0
- package/docs/showcase/case6-agency-handy.tsx +1113 -0
- package/docs/showcase/futurelastic-web.tsx +392 -0
- package/docs/showcase/org-switcher.tsx +313 -0
- package/docs/showcase/permission-matrix.tsx +346 -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 +347 -0
- package/docs/showcase/table-expandable-rows.tsx +480 -0
- package/docs/showcase/table-filter-chips.tsx +456 -0
- package/docs/showcase/table-footer-totals.tsx +314 -0
- package/docs/showcase/table-grouped-subtotals.tsx +391 -0
- package/docs/showcase/table-master-detail.tsx +484 -0
- package/docs/showcase/table-pagination.tsx +327 -0
- package/docs/showcase/table-states.tsx +366 -0
- package/docs/showcase/table-sticky-columns.tsx +376 -0
- package/docs/showcase/table-tree-rows.tsx +444 -0
- package/docs/showcase/table-view-tabs.tsx +488 -0
- package/package.json +9 -12
- 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
|
@@ -1,259 +1,85 @@
|
|
|
1
|
-
|
|
1
|
+
|
|
2
2
|
|
|
3
3
|
:root {
|
|
4
|
-
/* Semantic spacing — ONE coherent 4px grid (Tailwind/Material/Ant standard). All steps reference
|
|
5
|
-
* the linear `--space-*` scale (NOT the golden φ scale — golden ratio is for modular SIZE scales
|
|
6
|
-
* like type/radius, not the spacing grid; mixing the two left an incoherent density rhythm). The
|
|
7
|
-
* φ tokens remain available as an optional golden-layout utility, just not the spacing baseline. */
|
|
8
|
-
--space-page-x: var(--space-6); /* 24px — page gutter */
|
|
9
|
-
--space-page-y: var(--space-6); /* 24px */
|
|
10
|
-
--space-section: var(--space-4); /* 16px */
|
|
11
|
-
--space-stack-xs: var(--space-1); /* 4px */
|
|
12
|
-
--space-stack-sm: var(--space-2); /* 8px */
|
|
13
|
-
--space-stack-md: var(--space-4); /* 16px */
|
|
14
|
-
--space-stack-lg: var(--space-6); /* 24px */
|
|
15
|
-
--space-stack-xl: var(--space-10); /* 40px */
|
|
16
|
-
--space-inline-xs: var(--space-1); /* 4px */
|
|
17
|
-
--space-inline-sm: var(--space-2); /* 8px */
|
|
18
|
-
--space-inline-md: var(--space-3); /* 12px */
|
|
19
|
-
--space-inline-lg: var(--space-4); /* 16px */
|
|
20
4
|
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
5
|
+
--space-page-x: var(--space-6);
|
|
6
|
+
--space-page-y: var(--space-6);
|
|
7
|
+
--space-section: var(--space-4);
|
|
8
|
+
--space-stack-xs: var(--space-1);
|
|
9
|
+
--space-stack-sm: var(--space-2);
|
|
10
|
+
--space-stack-md: var(--space-4);
|
|
11
|
+
--space-stack-lg: var(--space-6);
|
|
12
|
+
--space-stack-xl: var(--space-10);
|
|
13
|
+
--space-inline-xs: var(--space-1);
|
|
14
|
+
--space-inline-sm: var(--space-2);
|
|
15
|
+
--space-inline-md: var(--space-3);
|
|
16
|
+
--space-inline-lg: var(--space-4);
|
|
17
|
+
|
|
26
18
|
--overlay-z-index: 50;
|
|
27
19
|
|
|
28
|
-
|
|
29
|
-
--master-detail-rail-
|
|
30
|
-
--master-detail-rail-standard: 20rem; /* 320px */
|
|
20
|
+
--master-detail-rail-compact: 18.75rem;
|
|
21
|
+
--master-detail-rail-standard: 20rem;
|
|
31
22
|
--master-detail-gap: var(--space-stack-md);
|
|
32
|
-
/* The collapse threshold: MasterDetail keeps its two-track split while the composition's OWN
|
|
33
|
-
* inline size is at least this wide, and stacks (master then detail) below it. A service theme
|
|
34
|
-
* retunes it once globally; the `collapseBelow` prop overrides it per instance (rule #45).
|
|
35
|
-
* This is a real knob — the layout reads it through the flex-basis threshold, NOT a media
|
|
36
|
-
* query, precisely so a `var()` can drive it (see src/styles/layout.css · .ui-master-detail). */
|
|
37
|
-
--master-detail-collapse-below: 40rem; /* 640px — the `sm` step */
|
|
38
23
|
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
--master-detail-master-viewport-compact: 20rem; /* 320px — about 8 nominal rows */
|
|
46
|
-
--master-detail-master-viewport-standard: 28rem; /* 448px — about 11 nominal rows */
|
|
47
|
-
/* Focus-ring room INSIDE the bounded region: an overflow container clips both axes, so without
|
|
48
|
-
* an inset the ring of a row at the edge would be cut off (WCAG 2.4.11/2.4.13). Doubles as the
|
|
49
|
-
* scroll-padding so a row scrolled into view never sits flush against the clip edge. */
|
|
50
|
-
--master-detail-master-viewport-inset: var(--space-1); /* 4px */
|
|
24
|
+
--master-detail-collapse-below: 40rem;
|
|
25
|
+
|
|
26
|
+
--master-detail-master-viewport-compact: 20rem;
|
|
27
|
+
--master-detail-master-viewport-standard: 28rem;
|
|
28
|
+
|
|
29
|
+
--master-detail-master-viewport-inset: var(--space-1);
|
|
51
30
|
|
|
52
31
|
--space-page-active-x: var(--space-page-x);
|
|
53
32
|
--space-page-active-y: var(--space-page-y);
|
|
54
33
|
--space-section-active: var(--space-section);
|
|
55
|
-
--space-page-compact-x: var(--space-4);
|
|
34
|
+
--space-page-compact-x: var(--space-4);
|
|
56
35
|
--space-page-compact-y: var(--space-4);
|
|
57
36
|
--space-section-compact: var(--space-4);
|
|
58
37
|
|
|
59
|
-
/* Modal scrim — the single backdrop colour shared by EVERY overlay (Dialog, AlertDialog, Sheet,
|
|
60
|
-
* Drawer, AppShell mobile nav). Themeable (rule #44) so a service tints the wash to its brand
|
|
61
|
-
* once, e.g. a navy `--overlay-background: rgb(12 26 49 / .55)`, instead of forking each overlay.
|
|
62
|
-
*
|
|
63
|
-
* HOW IT REACHES AN OVERLAY (gh#215 — it previously reached NOTHING): each surface declares its
|
|
64
|
-
* own knob `initial` and resolves a SHARE of this colour at the call site,
|
|
65
|
-
* `var(--dialog-overlay-background, color-mix(in srgb, var(--overlay-background)
|
|
66
|
-
* var(--dialog-overlay-alpha), transparent))`. That keeps the calibrated per-surface depth — a
|
|
67
|
-
* slide-in Sheet washes the page more lightly (40%) than a modal Dialog (60%) — while ONE
|
|
68
|
-
* override here retints every backdrop. Per docs/TOKENS.md the knobs must stay `initial`: a
|
|
69
|
-
* `:root` binding would freeze and a scoped `[data-tenant]`/`.dark` override of this token would
|
|
70
|
-
* never reach the overlay. Overlays are portaled, so a tenant scope must also sit on the portal
|
|
71
|
-
* container (see docs/CUSTOMER-THEMING.md). */
|
|
72
38
|
--overlay-background: rgb(0 0 0 / 0.5);
|
|
73
39
|
|
|
74
|
-
|
|
75
|
-
* gap already separates them; a divider is a service-theme opt-in:
|
|
76
|
-
* `--page-header-divider: 1px solid hsl(var(--border));` */
|
|
40
|
+
--page-footer-pad-block-end: var(--space-stack-md);
|
|
77
41
|
--page-header-divider: none;
|
|
78
42
|
|
|
79
|
-
/* PageContainer `toolbar` — the fixed chrome band between the header and the (scrolling) body.
|
|
80
|
-
* ALL THREE knobs are quiet by default (rule #44):
|
|
81
|
-
* background — `transparent`, i.e. the band shows the page ground exactly as it did before
|
|
82
|
-
* the knob existed. It is bound at `:root` and NOT `initial`, unlike the
|
|
83
|
-
* divider below, because the default is a plain CSS keyword rather than
|
|
84
|
-
* another role token: there is nothing for a scoped [data-tenant]/.dark
|
|
85
|
-
* override to re-resolve, so the `initial` + call-site-fallback dance would
|
|
86
|
-
* buy nothing and only hide the default from anyone reading this file. A
|
|
87
|
-
* service that wants the band to read as its own surface — the design that
|
|
88
|
-
* asked for this knob puts a chat channel's workflow rail on the card ground —
|
|
89
|
-
* sets `--page-toolbar-background: hsl(var(--card));` ONCE in its theme. Never
|
|
90
|
-
* `className="bg-card"` at the call site: that is hand-laid page chrome, it
|
|
91
|
-
* paints only under `variant="flush"` gutters correctly by accident, and it
|
|
92
|
-
* cannot be re-themed per tenant.
|
|
93
|
-
* pad-block 0 — the band's ONLY breathing room, and the only one it should ever have. The
|
|
94
|
-
* band is chrome, so it sits FLUSH against the header above and the body
|
|
95
|
-
* below (src/styles/layout.css cancels the container's --page-band-gap from
|
|
96
|
-
* the band itself); there is deliberately no outside space to tune, because a
|
|
97
|
-
* ruled, painted band floating in a void divides nothing. A service that opts
|
|
98
|
-
* into the background or the divider gives the band its inset HERE
|
|
99
|
-
* (`--page-toolbar-pad-block: var(--space-2)`) instead of padding the strip at
|
|
100
|
-
* the call site. Still 0 by default: a transparent band is not a surface and
|
|
101
|
-
* has no inside to breathe, and under `fill` every pixel of it comes straight
|
|
102
|
-
* off the scroll viewport the slot exists to protect.
|
|
103
|
-
* divider — declared `initial` so the CALL SITE can fall back to --page-header-divider
|
|
104
|
-
* (`var(--page-toolbar-divider, var(--page-header-divider))`). One theme
|
|
105
|
-
* declaration therefore rules the whole page chrome consistently, and a
|
|
106
|
-
* scoped [data-tenant]/.dark override of the header divider still reaches the
|
|
107
|
-
* band — a `:root` binding would freeze it at the :root value
|
|
108
|
-
* (docs/TOKENS.md · "Role-mirror knobs MUST be `initial`"). Set
|
|
109
|
-
* `--page-toolbar-divider: none` to silence just this band. */
|
|
110
43
|
--page-toolbar-background: transparent;
|
|
111
44
|
--page-toolbar-pad-block: 0px;
|
|
112
45
|
--page-toolbar-divider: initial;
|
|
113
46
|
|
|
114
|
-
/* Top rule of the PageContainer `footer` — the third page chrome band, brought onto the same
|
|
115
|
-
* contract as the header and the toolbar (its rule used to be a hard literal in layout.css, so
|
|
116
|
-
* a page could not turn it off at all). Declared `initial` like the toolbar's, so the CALL SITE
|
|
117
|
-
* resolves it as `var(--page-footer-divider, 1px solid hsl(var(--border)))` and a scoped
|
|
118
|
-
* [data-tenant]/.dark override still reaches it (docs/TOKENS.md · "Role-mirror knobs MUST be
|
|
119
|
-
* `initial`").
|
|
120
|
-
*
|
|
121
|
-
* It is the ONE chrome knob whose default is a RULE rather than silence, and deliberately so:
|
|
122
|
-
* `footer` is the shared slot a form's Save/Cancel bar lands in, where the line separating the
|
|
123
|
-
* actions from the page content is the behaviour every existing page already depends on. The
|
|
124
|
-
* old literal is the fallback verbatim, so unset is byte-identical. A page whose footer content
|
|
125
|
-
* already carries its own frame — a chat composer is a bordered Card — silences the duplicate
|
|
126
|
-
* with `--page-footer-divider: none`. */
|
|
127
47
|
--page-footer-divider: initial;
|
|
128
48
|
|
|
129
|
-
/* Bottom inset of the page header, sized so title→body distance (this pad + the
|
|
130
|
-
* --space-section-active container gap) EQUALS the page's top padding — the title
|
|
131
|
-
* band reads vertically balanced (24 above / 24 below by default), instead of the
|
|
132
|
-
* old fixed 16px pad that left 24 above vs 32 below. A page that passes a `toolbar`
|
|
133
|
-
* measures title→BAND instead (this pad alone, the gap being cancelled): the band is
|
|
134
|
-
* chrome attached to the header, not the next section down. */
|
|
135
49
|
--page-header-pad-bottom: calc(var(--space-page-active-y) - var(--space-section-active));
|
|
136
50
|
|
|
137
|
-
|
|
138
|
-
* arrangement (gh#231). Below the 640px step the default arrangement drops `extra` onto its own
|
|
139
|
-
* full-width line under the subtitle; `headerLayout="responsive-inline"` keeps it beside the
|
|
140
|
-
* title band at this measure instead, so a single compact control (a search field, one primary
|
|
141
|
-
* action) stays on the title row at 390px. Unused by the default arrangement, so no existing
|
|
142
|
-
* page moves. 11rem = 176px, i.e. the control ends flush with the compact page gutter. */
|
|
143
|
-
--page-header-extra-measure: 11rem; /* 176px */
|
|
51
|
+
--page-header-extra-measure: 11rem;
|
|
144
52
|
|
|
145
|
-
/* Gap between the page title and its status/meta band (PageContainer `status`,
|
|
146
|
-
* godxjp-ui#255), and between the band's own items. One knob aligns the badge row
|
|
147
|
-
* to a service's grid; a page that never passes `status` reads neither the token
|
|
148
|
-
* nor the wrapping row. */
|
|
149
53
|
--page-header-status-gap: var(--space-inline-sm);
|
|
150
54
|
|
|
151
|
-
|
|
152
|
-
* shared `.ui-skeleton-block` skin, so they need only a MEASURE and a block size — a service
|
|
153
|
-
* retunes the pending band's proportions here instead of per page. */
|
|
154
|
-
--page-title-placeholder-measure: 14rem; /* 224px */
|
|
55
|
+
--page-title-placeholder-measure: 14rem;
|
|
155
56
|
--page-title-placeholder-block-size: 1.5em;
|
|
156
|
-
--page-subtitle-placeholder-measure: 22rem;
|
|
57
|
+
--page-subtitle-placeholder-measure: 22rem;
|
|
157
58
|
--page-subtitle-placeholder-block-size: 1.25em;
|
|
158
59
|
|
|
159
|
-
|
|
160
|
-
|
|
161
|
-
* `variant="narrow"` complaint: it caps only `.ui-page-body`, leaving the header action out at
|
|
162
|
-
* the page edge). Selected by the semantic `measure` prop; `measure="default"` reads NEITHER
|
|
163
|
-
* token, so an existing page is untouched.
|
|
164
|
-
*
|
|
165
|
-
* These are OUTER measures: the page gutters (--space-page-active-x, 24px each side by default)
|
|
166
|
-
* live INSIDE the cap, so the VISIBLE surface is the measure minus both gutters:
|
|
167
|
-
* narrow 42rem = 672px → 624px visible surface (the historical variant="narrow" body width)
|
|
168
|
-
* medium 48rem = 768px → 720px visible surface (the canonical readable/feed measure)
|
|
169
|
-
* Below the cap nothing binds, so a 390px viewport stays fluid at the 16px compact gutter
|
|
170
|
-
* (358px surface). A service theme retunes both in ONE place; never a page-local max-width. */
|
|
171
|
-
--page-measure-narrow: 42rem; /* 672px outer → 624px surface */
|
|
172
|
-
--page-measure-medium: 48rem; /* 768px outer → 720px surface */
|
|
60
|
+
--page-measure-narrow: 42rem;
|
|
61
|
+
--page-measure-medium: 48rem;
|
|
173
62
|
|
|
174
|
-
/* Responsive page typography is independent from density. Density changes information spacing;
|
|
175
|
-
* these tokens change only page chrome so mobile keeps readable body text and touch targets. */
|
|
176
63
|
--page-title-font-size: var(--heading-h1);
|
|
177
64
|
--page-title-font-size-compact: var(--heading-h2);
|
|
178
65
|
--page-subtitle-font-size: var(--font-size-base);
|
|
179
66
|
--page-subtitle-font-size-compact: var(--font-size-sm);
|
|
180
67
|
|
|
181
|
-
/* PageContainer `headerScale="chrome"` — the title step for a page whose top row IS CHROME
|
|
182
|
-
* rather than a document title: a chat channel name, a mail subject line, an IDE tab. It is a
|
|
183
|
-
* SEPARATE knob from the two above on purpose: those are ONE document title at two viewport
|
|
184
|
-
* sizes (a responsive step), while this is a different KIND of page and holds at every width.
|
|
185
|
-
* `--heading-h3` (= --font-size-base, 14px) is the body step, which is the point — the row
|
|
186
|
-
* reads as a label ON the surface, not as the page's headline, and the header band collapses
|
|
187
|
-
* from the measured 61px to ~40px once it stops carrying a 20px h1. Quiet by default: a page
|
|
188
|
-
* that never passes `headerScale` never reads this token (rule #44). */
|
|
189
68
|
--page-title-font-size-chrome: var(--heading-h3);
|
|
190
69
|
|
|
191
|
-
/* The SUBTITLE step of the same fact. Measured against the reference chat screen, the chrome
|
|
192
|
-
* title and the chrome subtitle were rendering at the SAME step (both --font-size-base), which
|
|
193
|
-
* is not a hierarchy — a channel name and the channel's purpose line read as one undifferentiated
|
|
194
|
-
* block. The design puts the purpose line two steps down (`Text size="2xs"`), and the size is
|
|
195
|
-
* what carries the LINE BOX: at 14px/1.7 the subtitle line is 23.8px tall, at 11px/1.7 it is
|
|
196
|
-
* 18.9px, so the whole header band loses ~5px it was spending on a caption. `--font-size-2xs`
|
|
197
|
-
* (ratio⁻², ≈11px) is that step, and it is the same golden scale the title step reads — never a
|
|
198
|
-
* literal. Quiet by default: a page that never passes `headerScale` never resolves it (#44). */
|
|
199
70
|
--page-subtitle-font-size-chrome: var(--font-size-2xs);
|
|
200
71
|
|
|
201
|
-
/* The page's TOP inset under `headerScale="chrome"`, the second half of the same fact: chrome
|
|
202
|
-
* sits on the frame's edge. A document page opens with --space-page-active-y (24px, 16px below
|
|
203
|
-
* the 720px step) because a title needs air above it; a chat channel head, a mail subject bar or
|
|
204
|
-
* an IDE tab strip is the frame itself, and 24px of margin above it reads as a page floating
|
|
205
|
-
* inside its own shell — measured on a consumer chat screen as 24px lost off the top of the
|
|
206
|
-
* transcript viewport, against a design whose channel head starts at y=0. 0 is therefore the
|
|
207
|
-
* quiet default (rule #44), and it is a knob rather than a literal so a service whose grid wants
|
|
208
|
-
* its chrome inset (`--page-pad-block-start-chrome: var(--space-2)`) retunes it once instead of
|
|
209
|
-
* forking the page shell. Read ONLY when the prop is passed, so no document page resolves it. */
|
|
210
72
|
--page-pad-block-start-chrome: 0px;
|
|
211
73
|
|
|
212
|
-
/* The BAND HEIGHT of the same fact (gh#331). A document header is content-height by definition —
|
|
213
|
-
* a title is as tall as the title is. A chrome band is the opposite: it is furniture, and
|
|
214
|
-
* furniture has a height that things centre INTO. `AppShell` has had `--app-shell-bar-height`
|
|
215
|
-
* for exactly that since it shipped; `PageContainer` had no equivalent, so a `headerScale="chrome"`
|
|
216
|
-
* band's vertical centre drifted with its own copy — measured in Chromium on
|
|
217
|
-
* /isolate/layout-page-container, 42.02px with an `extra` control and 40.38px without, i.e. the
|
|
218
|
-
* centre moves 0.8px for a change of content and there is no value a service can aim at.
|
|
219
|
-
*
|
|
220
|
-
* WHO OWNS THE BAND-HEIGHT AXIS (the question gh#331 defers to gh#330). `--app-shell-bar-height`
|
|
221
|
-
* does: it is the system's one declared chrome-band height, and `--centered-shell-bar-height`
|
|
222
|
-
* already reads it. A service that wants its page chrome to sit on the shell bar's band writes
|
|
223
|
-
* ONE line — `--page-header-min-block-size-chrome: var(--app-shell-bar-height)` — and the two
|
|
224
|
-
* bands are on one axis for good.
|
|
225
|
-
*
|
|
226
|
-
* It is NOT that value by DEFAULT, and the reason is not timidity: a `PageContainer` with a
|
|
227
|
-
* chrome header is not necessarily inside an `AppShell` (the canonical chat composition renders
|
|
228
|
-
* one inside a bordered region, a SplitPane pane, a Card), and a band that is not trying to line
|
|
229
|
-
* up with a bar has no business inheriting that bar's height. `auto` is the quiet state (rule
|
|
230
|
-
* #44): no floor, content-height, byte-identical to every page rendered before this token
|
|
231
|
-
* existed — document AND chrome.
|
|
232
|
-
*
|
|
233
|
-
* A MIN, never a fixed height: a taller `extra` (an `lg` control, a wrapped JA/VI channel name)
|
|
234
|
-
* must still fit rather than overflow its own band. The header centres its content in whatever
|
|
235
|
-
* band it ends up with — see `justify-content` in styles/layout.css — so raising this knob
|
|
236
|
-
* centres, it does not top-pack. The header's own `--page-header-pad-bottom` lives INSIDE the
|
|
237
|
-
* band (border-box); under the canonical chrome composition (`variant="ghost"`) that pad is 0
|
|
238
|
-
* and the centring is exact. */
|
|
239
74
|
--page-header-min-block-size-chrome: auto;
|
|
240
75
|
|
|
241
|
-
|
|
242
|
-
|
|
243
|
-
|
|
244
|
-
* horizontal stays 24 (Ant standard). Per-component tokens (--sheet-pad-*, --dialog-space-inset…)
|
|
245
|
-
* default to these and only override when a surface genuinely needs to differ. */
|
|
246
|
-
--space-chrome-x: var(--space-6); /* 24px — horizontal inset */
|
|
247
|
-
--space-chrome-y: var(--space-4); /* 16px — vertical inset (header/footer/body) */
|
|
248
|
-
--space-chrome-gap: var(--space-stack-sm); /* gap between header ↔ body ↔ footer */
|
|
76
|
+
--space-chrome-x: var(--space-6);
|
|
77
|
+
--space-chrome-y: var(--space-4);
|
|
78
|
+
--space-chrome-gap: var(--space-stack-sm);
|
|
249
79
|
|
|
250
|
-
|
|
251
|
-
* a control or a value (FormField, Descriptions, Form, any label-above stack). Single source so the
|
|
252
|
-
* whole system stays in sync (gh feedback: Descriptions was ~0px while FormField was 8px). */
|
|
253
|
-
--field-label-gap: var(--space-2); /* 8px */
|
|
80
|
+
--field-label-gap: var(--space-2);
|
|
254
81
|
}
|
|
255
82
|
|
|
256
|
-
/* Canonical admin collection composition. Services may retune these semantic knobs once. */
|
|
257
83
|
:root {
|
|
258
84
|
--admin-collection-control-height: var(--control-height-default);
|
|
259
85
|
--admin-collection-section-gap: var(--space-stack-md);
|
|
@@ -0,0 +1,206 @@
|
|
|
1
|
+
# Canonical contracts — the answer to "does @godxjp/ui have an X?"
|
|
2
|
+
|
|
3
|
+
A consumer design spec names a component (`PageHeader`, `Banner`, `SocialLinks`, `OrganizationChoiceList`, `ServiceRolePanel`, `BranchScopePicker`, `PermissionMatrix`, `FilterBar`).
|
|
4
|
+
|
|
5
|
+
---
|
|
6
|
+
|
|
7
|
+
## 1. `PageHeader` — **`PageContainer`'s embedded header IS the DXS PageHeader** (gh#255)
|
|
8
|
+
|
|
9
|
+
```ts
|
|
10
|
+
import { PageContainer, type PageContainerProps } from "@godxjp/ui/layout";
|
|
11
|
+
```
|
|
12
|
+
|
|
13
|
+
There is **no standalone `PageHeader` export**. The canonical page title band — breadcrumbs · `<h1>` · subtitle · status/meta (`status`) · actions (`extra`) — lives on **one renderer**: `PageContainer`'s embedded header, with `headerLayout` (`stack` | `responsive-inline`), `breadcrumbLabel` (the landmark-unique override), `measure` and `headerLoading` (skeleton title band + `aria-busy`, keeping the `<h1>` in the document with an sr-only name so the heading outline never disappears mid-load).
|
|
14
|
+
|
|
15
|
+
**Why one renderer rather than a lifted export.** The band's geometry is token-owned (`.ui-page-header`, `--page-header-status-gap`, the placeholder measures) and every page mounts it through `PageContainer`, so a second mount point would be a second `<h1>` waiting to happen. A title band outside a full page shell (a Sheet detail, a `MasterDetail` pane, a tab body) is a COMPOSITION of `Breadcrumb` + heading text + `Flex` at section level — it should NOT be an `<h1>`.
|
|
16
|
+
|
|
17
|
+
| Situation | Use |
|
|
18
|
+
| -------------------------------------------- | ------------------------------------------------------------------------- |
|
|
19
|
+
| The surface **is a page** | `PageContainer` (`title`/`subtitle`/`status`/`extra`/`breadcrumb`) |
|
|
20
|
+
| A title band **inside** a pane/sheet/tab | Compose at section level — never a second `<h1>` / `PageContainer` header |
|
|
21
|
+
| The user **may not see the resource at all** | `ErrorSurface` — never a header that leaks the resource's name |
|
|
22
|
+
|
|
23
|
+
`denied` / `error` are deliberately **not** states of the band — see the table above.
|
|
24
|
+
|
|
25
|
+
---
|
|
26
|
+
|
|
27
|
+
## 2. `Banner` — **EXPORTED** as the page-level `Alert` (gh#255)
|
|
28
|
+
|
|
29
|
+
```ts
|
|
30
|
+
import { Banner, type BannerProps } from "@godxjp/ui/feedback";
|
|
31
|
+
```
|
|
32
|
+
|
|
33
|
+
Same tones, same icon defaults, same assertive/polite role split, same actions grid, same dismiss control. `Banner.Title` **is** `AlertTitle` — the same element, not a parallel family.
|
|
34
|
+
|
|
35
|
+
It is an alias, not a second implementation, for the same reason `FilterBar` is an alias of `Toolbar`: a banner and an inline alert are one object at two measures, and duplicating the tone mapping and dismiss behaviour is exactly what the no-duplication rule forbids.
|
|
36
|
+
|
|
37
|
+
| Scope of the message | Use |
|
|
38
|
+
| --------------------------------------------------------------------- | ------------------------------------------- |
|
|
39
|
+
| The page or the whole app (maintenance, trial expiry, read-only mode) | `Banner` above the header, or in `AppShell` |
|
|
40
|
+
| One section / card / form | `Alert` inside that section |
|
|
41
|
+
| One field | `FormField` `error` |
|
|
42
|
+
| Transient ("saved") | `toast()` |
|
|
43
|
+
| The user may not see the page at all | `ErrorSurface` |
|
|
44
|
+
|
|
45
|
+
Retheme through tokens, never a wrapper class: `--banner-radius`, `--banner-border-width`, `--banner-border-block-end-width`, `--banner-space-block`, `--banner-space-inline`, `--banner-dismiss-space-offset`. Never stack two banners.
|
|
46
|
+
|
|
47
|
+
---
|
|
48
|
+
|
|
49
|
+
## 3. `AuthShell preset="registration"` — **EXPORTED** (gh#256)
|
|
50
|
+
|
|
51
|
+
```tsx
|
|
52
|
+
<AuthShell variant="canonical" preset="registration" brand={…} footer={…}>
|
|
53
|
+
```
|
|
54
|
+
|
|
55
|
+
The 360px sign-up measure with a 15px inline gutter at 390px — the same page rhythm as `preset="login"`, so sign-in → sign-up never jumps on a phone. It carries the full password form **and** the pending-email confirmation state with no consumer geometry CSS.
|
|
56
|
+
|
|
57
|
+
Two things make it structurally distinct from every other preset, and both are load-bearing:
|
|
58
|
+
|
|
59
|
+
1. **It is the only START-aligned preset.** A sign-up card is the tallest surface in the hosted-identity set (name · email · password · confirm · strength · consent · submit · providers). A vertically _centred_ tall card overflows **above the scroll origin** on a short viewport, putting its first field permanently out of reach. 2. **It is the only preset with its own footer-clearance knob**, so the legal/consent footer never sits flush against the submit button at the end of a long scroll.
|
|
60
|
+
|
|
61
|
+
Geometry knobs: `--auth-shell-registration-{card-max-width, main-padding-block-start, main-padding-block-start-mobile, main-padding-inline, main-padding-inline-mobile, main-padding-block-end, main-padding-block-end-mobile, card-stack-gap}`.
|
|
62
|
+
|
|
63
|
+
Worked screen: `docs/layout/auth-shell-registration.tsx`.
|
|
64
|
+
|
|
65
|
+
---
|
|
66
|
+
|
|
67
|
+
## 4. `SocialLinks` — **COMPOSE** (gh#256)
|
|
68
|
+
|
|
69
|
+
There is no `SocialLinks` component, and none is planned.
|
|
70
|
+
|
|
71
|
+
```tsx
|
|
72
|
+
<AuthDivider label="または" />
|
|
73
|
+
<Flex direction="col" gap="sm">
|
|
74
|
+
{providers.map((p) => (
|
|
75
|
+
<Button key={p.id} variant="outline" disabled={submitting} onClick={p.start}>
|
|
76
|
+
<p.Icon aria-hidden="true" />
|
|
77
|
+
{p.label}
|
|
78
|
+
</Button>
|
|
79
|
+
))}
|
|
80
|
+
</Flex>
|
|
81
|
+
```
|
|
82
|
+
|
|
83
|
+
**Why.** It owns no behaviour: each provider is a plain action the app points at its own OAuth start URL. A framework component would have to invent _which_ providers a product offers, in what order, and what consent they imply — product decisions the package must not make. `disabled` and `loading` are the `Button`'s own props; there is no provider-specific API to learn.
|
|
84
|
+
|
|
85
|
+
---
|
|
86
|
+
|
|
87
|
+
## 5. `OrganizationChoiceList` — **COMPOSE** (gh#256)
|
|
88
|
+
|
|
89
|
+
```tsx
|
|
90
|
+
<Card>
|
|
91
|
+
<CardHeader>…</CardHeader>
|
|
92
|
+
<CardContent flush>
|
|
93
|
+
<ul>
|
|
94
|
+
{orgs.map((org) => (
|
|
95
|
+
<ListRow
|
|
96
|
+
as="li"
|
|
97
|
+
key={org.id}
|
|
98
|
+
leading={<Avatar>…</Avatar>}
|
|
99
|
+
title={org.name}
|
|
100
|
+
description={org.role}
|
|
101
|
+
trailing={
|
|
102
|
+
<Button variant="ghost" size="sm">
|
|
103
|
+
選択
|
|
104
|
+
</Button>
|
|
105
|
+
}
|
|
106
|
+
/>
|
|
107
|
+
))}
|
|
108
|
+
</ul>
|
|
109
|
+
</CardContent>
|
|
110
|
+
</Card>
|
|
111
|
+
```
|
|
112
|
+
|
|
113
|
+
`CardContent flush` is what produces shared row dividers instead of a card outline per row.
|
|
114
|
+
|
|
115
|
+
States — all existing exports, no bespoke markup:
|
|
116
|
+
|
|
117
|
+
| State | Use |
|
|
118
|
+
| ----------------- | -------------------------------------------------------- |
|
|
119
|
+
| loading | `Skeleton` rows at the settled row height |
|
|
120
|
+
| empty | `EmptyState` |
|
|
121
|
+
| error | `Alert tone="destructive"` + a retry action |
|
|
122
|
+
| permission-denied | `Alert tone="warning"` (section) / `ErrorSurface` (page) |
|
|
123
|
+
| disabled row | the row's own `Button disabled` |
|
|
124
|
+
|
|
125
|
+
Worked screens: `docs/layout/auth-shell-context.tsx`, `docs/layout/auth-shell-registration.tsx`.
|
|
126
|
+
|
|
127
|
+
---
|
|
128
|
+
|
|
129
|
+
## 6. `ServiceRolePanel` · `BranchScopePicker` · `PermissionMatrix` — **EXPORTED** (gh#257)
|
|
130
|
+
|
|
131
|
+
All three compositions were promoted to public exports — the composition-first Gate 0 verdict was revisited when consumers kept re-authoring the same states and geometry:
|
|
132
|
+
|
|
133
|
+
```ts
|
|
134
|
+
import { ServiceRolePanel } from "@godxjp/ui/layout";
|
|
135
|
+
import { BranchScopePicker } from "@godxjp/ui/data-entry";
|
|
136
|
+
import { PermissionMatrix } from "@godxjp/ui/data-display";
|
|
137
|
+
```
|
|
138
|
+
|
|
139
|
+
```ts
|
|
140
|
+
import {
|
|
141
|
+
grantKey,
|
|
142
|
+
hasGrant,
|
|
143
|
+
rolesDifferOnPermission,
|
|
144
|
+
visibleRows,
|
|
145
|
+
countGrants,
|
|
146
|
+
countDifferences,
|
|
147
|
+
} from "@godxjp/ui/lib/permission-grid";
|
|
148
|
+
```
|
|
149
|
+
|
|
150
|
+
Layout the role list beside the editor with `MasterDetail` — it owns the tracks, the gap and the stacking threshold as tokens, so the page carries no `grid-template-columns` and no media query at 1440 / 1024 / 390. Destructive changes go through `AlertDialog variant="destructive"` (add `challenge` for type-to-confirm).
|
|
151
|
+
|
|
152
|
+
Worked screens: `docs/layout/service-role-panel.tsx`, `docs/data-entry/branch-scope-picker.tsx`, `docs/data-display/permission-matrix.tsx`, `docs/showcase/permission-matrix.tsx`.
|
|
153
|
+
|
|
154
|
+
---
|
|
155
|
+
|
|
156
|
+
## 7. `FilterBar` — **EXPORTED, and now typed** (gh#258)
|
|
157
|
+
|
|
158
|
+
`FilterBar` / `FilterBarGroup` remain the public domain-neutral names for the `Toolbar` primitives.
|
|
159
|
+
|
|
160
|
+
```tsx
|
|
161
|
+
<FilterBar
|
|
162
|
+
search={{ value: q, onValueChange: setQ, placeholder: "Search records" }}
|
|
163
|
+
filters={[
|
|
164
|
+
{
|
|
165
|
+
value: "status",
|
|
166
|
+
label: "状態",
|
|
167
|
+
options: STATUS_OPTIONS,
|
|
168
|
+
selected: status,
|
|
169
|
+
onSelectedChange: setStatus,
|
|
170
|
+
},
|
|
171
|
+
]}
|
|
172
|
+
chips={applied.map((f) => ({ value: f.value, label: f.label }))}
|
|
173
|
+
onChipRemove={lift}
|
|
174
|
+
resultCount={rows.length}
|
|
175
|
+
onClear={clearAll}
|
|
176
|
+
hasActiveFilters={applied.length > 0}
|
|
177
|
+
actions={
|
|
178
|
+
<Button variant="outline" size="sm">
|
|
179
|
+
エクスポート
|
|
180
|
+
</Button>
|
|
181
|
+
}
|
|
182
|
+
/>
|
|
183
|
+
```
|
|
184
|
+
|
|
185
|
+
**Order is the contract.** DOM order is tab order, and the **bar** decides it, not each page:
|
|
186
|
+
|
|
187
|
+
```
|
|
188
|
+
search → typed filters → children (custom composition filters) → reset → actions
|
|
189
|
+
→ applied-chips row → result-count / error line
|
|
190
|
+
```
|
|
191
|
+
|
|
192
|
+
Reset sits before `actions` deliberately, so "clear filters" never lands at the end of the row beside an unrelated primary action.
|
|
193
|
+
|
|
194
|
+
What each prop buys that a plain child did not:
|
|
195
|
+
|
|
196
|
+
- **`search`** — the canonical `SearchInput` at one token-owned measure (`--filter-bar-search-width`) across every list page, full-width below the 640px step. Controlled through the `value`/`defaultValue`/`onValueChange` triad; `onSearch` mirrors the debounced-term callback. - **`filters`** — labelled, domain-neutral `Select` filters whose visible `label` is the control's real `<label htmlFor>` (WCAG 2.5.3 / 1.3.1), at the `--filter-bar-filter-width` measure. - **`chips`** — the chip lifecycle: a labelled row, a remove control named after _that specific_ filter (a row of buttons all called "Remove" is unusable from a screen-reader's control list), and no row at all when nothing is applied. Remove = `onChipRemove(value)`; clear-all = `onClear`. - **`resultCount`** — a polite live region formatted with `Intl.NumberFormat` + CLDR plurals.
|
|
197
|
+
|
|
198
|
+
The bar still owns **no filter state**. `search`/`filters`/`chips` are rendered consumer data, `resultCount` is a number you computed. It owns placement, measure, ordering, keyboard order and announcement — nothing else.
|
|
199
|
+
|
|
200
|
+
Worked screen: `docs/navigation/filter-bar.tsx`.
|
|
201
|
+
|
|
202
|
+
---
|
|
203
|
+
|
|
204
|
+
## Adding to this document
|
|
205
|
+
|
|
206
|
+
Any future "does the package have an X?" answer belongs here, with: the Gate 0 verdict, the public-route question, and — for a composition — the exact primitives, the token knobs, and the state table. If the honest answer is "the consumer cannot reach it publicly", that is a package gap: fix the library, never patch the consumer app.
|