@godxjp/ui 19.1.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/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/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 +48 -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 +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 +9 -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
|
@@ -0,0 +1,157 @@
|
|
|
1
|
+
# Component Catalog
|
|
2
|
+
|
|
3
|
+
All components consume prop types from `src/props/components/`. Preview: `pnpm preview`.
|
|
4
|
+
|
|
5
|
+
---
|
|
6
|
+
|
|
7
|
+
## Layout
|
|
8
|
+
|
|
9
|
+
### AppShell / Sidebar / Topbar
|
|
10
|
+
|
|
11
|
+
**Prop types:** `AppShellProp`, `SidebarProp`, `TopbarProp` **Import:** `@godxjp/ui/layout`
|
|
12
|
+
|
|
13
|
+
Slot-based app chrome for admin products:
|
|
14
|
+
|
|
15
|
+
```tsx
|
|
16
|
+
<AppShell
|
|
17
|
+
sidebar={<Sidebar sections={sections} activeId="dashboard" />}
|
|
18
|
+
topbar={<Topbar start={<Logo mark="godx" label={product.name} />} />}
|
|
19
|
+
>
|
|
20
|
+
<PageContainer title="Dashboard">...</PageContainer>
|
|
21
|
+
</AppShell>
|
|
22
|
+
```
|
|
23
|
+
|
|
24
|
+
Do not rebuild sidebar or topbar chrome inside product previews or apps. Compose the shell slots, then put product content in the `children` slot.
|
|
25
|
+
|
|
26
|
+
### PageContainer
|
|
27
|
+
|
|
28
|
+
**Prop type:** `PageContainerProp` **Import:** `@godxjp/ui/layout`
|
|
29
|
+
|
|
30
|
+
| Prop | Vocabulary | Required |
|
|
31
|
+
| --------------- | ----------------- | ----------------- |
|
|
32
|
+
| `title` | `TitleProp` | ✅ |
|
|
33
|
+
| `subtitle` | `SubtitleProp` | |
|
|
34
|
+
| `extra` | `ExtraProp` | |
|
|
35
|
+
| `footer` | `FooterProp` | |
|
|
36
|
+
| `breadcrumb` | `BreadcrumbProp` | |
|
|
37
|
+
| `headerLoading` | local (`boolean`) | default `false` |
|
|
38
|
+
| `density` | `PageDensityProp` | default `default` |
|
|
39
|
+
| `children` | `ChildrenProp` | |
|
|
40
|
+
|
|
41
|
+
Every admin page **must** use PageContainer.
|
|
42
|
+
|
|
43
|
+
## Mobile-first
|
|
44
|
+
|
|
45
|
+
All UI is **mobile-first**: base layout targets ~320–428px viewport; `sm` (640px+) adds horizontal layouts. See `packages/ui/src/tokens/base.css` and `.ui-page-*` in `src/styles/index.css`. Preview defaults to mobile viewport.
|
|
46
|
+
|
|
47
|
+
### Flex
|
|
48
|
+
|
|
49
|
+
Default `direction="row"`; use `direction="col"` for vertical rhythm.
|
|
50
|
+
|
|
51
|
+
| Component | Prop | Key props |
|
|
52
|
+
| --------- | ---------- | ----------------------------------------------------------------------- |
|
|
53
|
+
| `Flex` | `FlexProp` | `direction: "row" \| "col"`, `gap: GapProp`, `align`, `justify`, `wrap` |
|
|
54
|
+
|
|
55
|
+
---
|
|
56
|
+
|
|
57
|
+
## Foundation
|
|
58
|
+
|
|
59
|
+
### Button
|
|
60
|
+
|
|
61
|
+
**Prop type:** `ButtonProp` **Import:** `@godxjp/ui/general`
|
|
62
|
+
|
|
63
|
+
| Prop | Vocabulary |
|
|
64
|
+
| ---------- | ------------------- |
|
|
65
|
+
| `variant` | `ButtonVariantProp` |
|
|
66
|
+
| `size` | `ButtonSizeProp` |
|
|
67
|
+
| `asChild` | `AsChildProp` |
|
|
68
|
+
| `disabled` | `DisabledProp` |
|
|
69
|
+
| `onClick` | `OnClickProp` |
|
|
70
|
+
|
|
71
|
+
---
|
|
72
|
+
|
|
73
|
+
## Data Entry
|
|
74
|
+
|
|
75
|
+
| Component | Prop type | Key props |
|
|
76
|
+
| ------------- | ----------------- | -------------------------------------------------- |
|
|
77
|
+
| `Input` | `InputProp` | extends native input |
|
|
78
|
+
| `Textarea` | `TextareaProp` | extends native textarea |
|
|
79
|
+
| `FormField` | `FormFieldProp` | `id`, `label`, `required`, `helper`, `error` |
|
|
80
|
+
| `SearchInput` | `SearchInputProp` | `onSearchChange: OnSearchChangeProp` |
|
|
81
|
+
| `Checkbox` | `CheckboxProp` | Radix checkbox; `Checkbox.Group` với `options` |
|
|
82
|
+
| `Radio` | `RadioGroupProp` | `Radio.Group` single-select; `Radio.Root` compound |
|
|
83
|
+
|
|
84
|
+
---
|
|
85
|
+
|
|
86
|
+
## Data Display
|
|
87
|
+
|
|
88
|
+
| Component | Prop type | Key props |
|
|
89
|
+
| -------------- | ------------------ | ---------------------------------------- |
|
|
90
|
+
| `EmptyState` | `EmptyStateProp` | `icon`, `title`, `description`, `action` |
|
|
91
|
+
| `DataTable` | `DataTableProp<T>` | `columns`, `density: TableDensityProp` |
|
|
92
|
+
| `Descriptions` | `DescriptionsProp` | `items[]` |
|
|
93
|
+
| `Badge` | `BadgeProp` | `status`, `tone: ToneProp` |
|
|
94
|
+
| `Badge` | `BadgeProp` | shadcn badge variants |
|
|
95
|
+
| `Popover` | Radix primitives | floating content panel |
|
|
96
|
+
| `ScrollArea` | Radix primitives | scrollable regions |
|
|
97
|
+
| `Collapsible` | Radix primitives | expand/collapse sections |
|
|
98
|
+
|
|
99
|
+
---
|
|
100
|
+
|
|
101
|
+
## Feedback
|
|
102
|
+
|
|
103
|
+
| Component | Prop type | Key props |
|
|
104
|
+
| ----------- | ------------------- | ---------------------------------------------------------------------------- |
|
|
105
|
+
| `Alert` | `AlertProp` | `tone` (colour), `variant` (measure), slots, `onDismiss`, `Alert.QueryError` |
|
|
106
|
+
| `Banner` | `BannerProp` | page-level `Alert` (`variant="banner"`); same tones/slots/dismiss |
|
|
107
|
+
| `Dialog` | `DialogConfirmProp` | `mode: form \| confirm`, `Dialog.Confirm` preset |
|
|
108
|
+
| `Sheet` | Radix primitives | slide-in panel (mobile filters, detail flyouts) |
|
|
109
|
+
| `Skeleton*` | `SkeletonRowsProp` | loading placeholders |
|
|
110
|
+
|
|
111
|
+
---
|
|
112
|
+
|
|
113
|
+
## Query
|
|
114
|
+
|
|
115
|
+
Async data lifecycle helpers (TanStack Query). **Not visual components.**
|
|
116
|
+
|
|
117
|
+
| Component | Prop type | Key props |
|
|
118
|
+
| ----------------------- | --------------------------- | --------------------------------------------------------------------------------------- |
|
|
119
|
+
| `DataState` | `DataStateProp<T>` | `query`, `skeleton`, `empty`, `isEmpty`, `showRetry`, `onRetry`, render-prop `children` |
|
|
120
|
+
| `AlertMutationFeedback` | `AlertMutationFeedbackProp` | `mutation`, `onRetry`, `pending` — inline `useMutation` error |
|
|
121
|
+
| `InfiniteQueryState` | `InfiniteQueryStateProp` | `flatten`, `loadMore`, `showLoadMore` — infinite scroll / timeline |
|
|
122
|
+
| `PrefetchLink` | `PrefetchLinkProp` | `queryKey`, `queryFn`, `prefetchOn`, `staleTime` |
|
|
123
|
+
|
|
124
|
+
Import: `@godxjp/ui/query` (re-exported from `@godxjp/ui/admin`).
|
|
125
|
+
|
|
126
|
+
**`DataState`** — one `useQuery` = one content block (list, detail). Not whole page when filters stay visible.
|
|
127
|
+
|
|
128
|
+
**`InfiniteQueryState`** — `useInfiniteQuery` + Load more. CRM timeline, activity feeds. Offset pagination lists → `DataState` + `DataTable.Pagination`.
|
|
129
|
+
|
|
130
|
+
**`PrefetchLink`** — hover/focus prefetch before navigate to detail.
|
|
131
|
+
|
|
132
|
+
**`AlertMutationFeedback`** — blocking mutation errors (simulator). Small saves → toast.
|
|
133
|
+
|
|
134
|
+
**`ButtonRefetch`** — `PageContainer extra` refresh pattern (MediaListPage).
|
|
135
|
+
|
|
136
|
+
**`Alert.QueryError`** — manual error when not using DataState (audit results region).
|
|
137
|
+
|
|
138
|
+
Auto retry: `useQuery({ retry, retryDelay })`. Manual retry: default `refetch()`.
|
|
139
|
+
|
|
140
|
+
---
|
|
141
|
+
|
|
142
|
+
## Navigation
|
|
143
|
+
|
|
144
|
+
| Component | Prop type | Key props |
|
|
145
|
+
| ---------------- | ------------------ | ------------------------------------------------------------------------------------------------------------------------------ |
|
|
146
|
+
| `FilterBar` | `ToolbarProp` | typed model: `search`, `filters`, `chips`, `onChipRemove`, `resultCount`, `actions`, `loading`, `disabled`, `error`, `onClear` |
|
|
147
|
+
| `FilterBarGroup` | `ToolbarGroupProp` | `label: LabelProp`, `controlId: IdProp` |
|
|
148
|
+
| `Toolbar` | `ToolbarProp` | back-compat alias of `FilterBar` |
|
|
149
|
+
| `ToolbarGroup` | `ToolbarGroupProp` | back-compat alias of `FilterBarGroup` |
|
|
150
|
+
| `Tabs` | Radix primitives | — |
|
|
151
|
+
| `DropdownMenu` | Radix primitives | — |
|
|
152
|
+
|
|
153
|
+
---
|
|
154
|
+
|
|
155
|
+
## Adding a new component
|
|
156
|
+
|
|
157
|
+
1. Check `PROPS-REGISTRY.md` — concept may already exist 2. Add vocabulary types if needed → `src/props/vocabulary/` 3.
|
|
@@ -0,0 +1,105 @@
|
|
|
1
|
+
# Composition pattern vs Framework component — the decision contract
|
|
2
|
+
|
|
3
|
+
> **Cardinal rule:** before ANY new thing is added to `src/components/`, it MUST pass the
|
|
4
|
+
> **Framework-Component Test** below — _all_ criteria, no exceptions. If it fails even one, it is a
|
|
5
|
+
> **composition pattern**: build it from existing primitives + tokens in the app/showcase, and do
|
|
6
|
+
> **not** add it to the framework. **When in doubt, compose.** The framework stays lean; brand- and
|
|
7
|
+
> screen-specific UI lives where it belongs — in the consumer app (or a `docs/` showcase), as a
|
|
8
|
+
> composition of real primitives configured by tokens.
|
|
9
|
+
|
|
10
|
+
This document defines the two concepts precisely, gives the mandatory test, and lists worked examples so the call is never a matter of taste.
|
|
11
|
+
|
|
12
|
+
---
|
|
13
|
+
|
|
14
|
+
## 1. The two concepts
|
|
15
|
+
|
|
16
|
+
### Framework component (`src/components/**`)
|
|
17
|
+
|
|
18
|
+
A **reusable, behavior-bearing primitive** that ships in the `@godxjp/ui` bundle and is imported by many consumer apps. It encapsulates interaction, state, accessibility and a controlled API that must NOT be re-implemented per app. Examples: `Button`, `Select`, `DataTable`, `Dialog`, `Calendar`, `Switch`, `Combobox` (= `Select showSearch`), `StatCard`.
|
|
19
|
+
|
|
20
|
+
### Composition pattern (consumer app, or a `docs/` showcase)
|
|
21
|
+
|
|
22
|
+
A **specific arrangement of existing primitives** for a specific screen, domain or brand — a dashboard layout, a marketing **Hero**, a **Navbar**, a **Footer**, a pricing section, a settings page. It has **no reusable behavior of its own**: it is layout + content + token configuration over real components. It is brand/design-specific and is **expressible today** by composing `Card`, `Button`, `Text`, `ResponsiveGrid`, `Flex`, `Badge`, `Avatar`, … + token overrides (incl. scoped `[data-tenant]` / per-region role scoping).
|
|
23
|
+
|
|
24
|
+
> A Claude Design's marketing landing page (Hero / Services / CTA / Footer) is the canonical
|
|
25
|
+
> composition case: it is reproduced 100% from **token configuration + real primitives**, with zero
|
|
26
|
+
> new framework components. See `docs/showcase/acme-website.tsx`.
|
|
27
|
+
|
|
28
|
+
---
|
|
29
|
+
|
|
30
|
+
## 2. The Framework-Component Test (MANDATORY — all 7 must pass)
|
|
31
|
+
|
|
32
|
+
Before creating OR proposing a framework component, evaluate **every** criterion and record the verdict. **Allowed only if ALL are `PASS`.** Any `FAIL` ⇒ it is a composition pattern; use existing components instead.
|
|
33
|
+
|
|
34
|
+
| # | Criterion | PASS means | FAIL means (→ compose) |
|
|
35
|
+
| ----------------------------------------------------------------- | ------------------------------------------------------------------------------------------------------------------------------ | --------------------------------------------------------------------- | ------------------------------------------------------------------------ |
|
|
36
|
+
| **C1. Universal, not design-specific** | Needed by many apps across domains; not a recreation of one design's block. | A generic capability (a select, a table, a date picker). | "ACME Hero", "AcmePricingTable", "this dashboard's header". |
|
|
37
|
+
| **C2. Encapsulates reusable BEHAVIOR** | Owns non-trivial state / keyboard / focus / ARIA that must not be re-implemented per app. | Listbox navigation, dialog focus-trap, table sort/select, async load. | Pure static layout/visual arrangement (a hero, a footer, a banner). |
|
|
38
|
+
| **C3. Not expressible by composing existing primitives + tokens** | You genuinely cannot build it from `Card`/`Button`/`Text`/`Grid`/`Flex`/… + token overrides. | A new interaction primitive with no existing equivalent. | You _can_ build it today from primitives + tokens (then you must). |
|
|
39
|
+
| **C4. Single responsibility + controlled-vocabulary API** | One job; maps to `value`/`defaultValue`/`onValueChange`, `size ∈ xs\|sm\|md\|lg`, `tone`, etc.; generalizes beyond one screen. | `Select`, `Switch`, `Pagination`. | A grab-bag "Section"/"Block"/"Layout" with a bespoke, screen-shaped API. |
|
|
40
|
+
| **C5. Fully token-themeable, zero baked brand** | Appearance is 100% token-driven; works for every brand with no code change. | Reads `hsl(var(--…))` / semantic tokens only. | Needs baked colors / raw hex / per-brand styling to look right. |
|
|
41
|
+
| **C6. Earns the international contract** | Broad reuse justifies the full i18n (`t()`/`Intl`) + WAI-ARIA APG + WCAG 2.2 AA + RTL + a11y-test + MCP-catalog cost. | A control everyone uses and that needs correct ARIA. | A one-off where that cost is pure overhead. |
|
|
42
|
+
| **C7. Earns its bundle cost** | Broadly used ⇒ worth shipping to _every_ consumer. | Used across most apps. | Used by one app / one design ⇒ it belongs in that app. |
|
|
43
|
+
|
|
44
|
+
> **Heuristic shortcuts** (a single one is usually enough to send it to composition):
|
|
45
|
+
>
|
|
46
|
+
> - "Could I build this **right now** from existing primitives + token overrides?" → **yes ⇒ compose** (C3).
|
|
47
|
+
> - "Is the name a **proper noun / screen name / brand block** (Hero, Navbar, Footer, Pricing,
|
|
48
|
+
> DashboardHeader)?" → **yes ⇒ compose** (C1).
|
|
49
|
+
> - "Does it own **any real behavior**, or is it just **layout + content + color**?" → layout only ⇒ **compose** (C2).
|
|
50
|
+
|
|
51
|
+
### Decision flow
|
|
52
|
+
|
|
53
|
+
```
|
|
54
|
+
new UI need
|
|
55
|
+
│
|
|
56
|
+
├─ Does an existing primitive already cover it? ───────────── yes → USE IT (no new code)
|
|
57
|
+
│ (Select = searchable/async; AppShell/PageContainer = chrome; DataTable = grids)
|
|
58
|
+
│
|
|
59
|
+
├─ Run the Framework-Component Test (C1–C7).
|
|
60
|
+
│ ├─ ALL pass → it MAY be a framework component
|
|
61
|
+
│ │ → follow the full `godxjp-ui-component` contract (i18n/a11y/vocab/
|
|
62
|
+
│ │ tokens/test/MCP/registry) before merging into src/components/.
|
|
63
|
+
│ └─ ANY fail → it is a COMPOSITION PATTERN
|
|
64
|
+
│ → build it from existing primitives + tokens in the app (or a docs/
|
|
65
|
+
│ showcase). Resolve any visual gap with a TOKEN, never a baked value.
|
|
66
|
+
│ NEVER add it to src/components/.
|
|
67
|
+
│
|
|
68
|
+
└─ If a token is missing to express it → ADD THE TOKEN (extensibility), not a component.
|
|
69
|
+
```
|
|
70
|
+
|
|
71
|
+
---
|
|
72
|
+
|
|
73
|
+
## 3. Worked examples
|
|
74
|
+
|
|
75
|
+
| Thing | C1 | C2 | C3 | C4 | C5 | C6 | C7 | Verdict |
|
|
76
|
+
| ------------------------------------------------------- | --- | --- | --- | --- | --- | --- | --- | ------------------------------------------------------------------------ |
|
|
77
|
+
| `Select` (incl. search/async) | ✅ | ✅ | ✅ | ✅ | ✅ | ✅ | ✅ | **Framework component** |
|
|
78
|
+
| `DataTable`, `Dialog`, `Calendar`, `Switch`, `Combobox` | ✅ | ✅ | ✅ | ✅ | ✅ | ✅ | ✅ | **Framework component** |
|
|
79
|
+
| `StatCard` (+ `icon`) | ✅ | ➖ | ✅ | ✅ | ✅ | ✅ | ✅ | **Framework component** (a reusable KPI tile with a stable API + tokens) |
|
|
80
|
+
| Marketing **Hero** | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | **Composition** — section, static, composable, brand-specific |
|
|
81
|
+
| **Navbar** / **Footer** | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | **Composition** — layout of `Text`/`Button`/`Flex` |
|
|
82
|
+
| **PricingTable** / feature grid | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | **Composition** — `ResponsiveGrid` + `Card` |
|
|
83
|
+
| Dashboard **page layout** | ❌ | ❌ | ❌ | ❌ | ➖ | ❌ | ❌ | **Composition** — `AppShell` + `PageContainer` + `ResponsiveGrid` |
|
|
84
|
+
| "Icon medallion" | ❌ | ❌ | ❌ | ❌ | ✅ | ❌ | ❌ | **Composition** — `Avatar` (square) + a Lucide glyph |
|
|
85
|
+
|
|
86
|
+
`✅ pass · ❌ fail · ➖ borderline`. **StatCard** is the instructive borderline: C2 is weak (it owns little behavior), but it is a universal KPI tile with a controlled API, fully tokenized, broadly reused — so it earns its place. A **Hero** fails six of seven; it is unambiguously a composition.
|
|
87
|
+
|
|
88
|
+
---
|
|
89
|
+
|
|
90
|
+
## 4. How to build a composition pattern correctly
|
|
91
|
+
|
|
92
|
+
1. **Real primitives only.** Compose `Card`/`Button`/`Text`/`ResponsiveGrid`/`Flex`/`Avatar`/… — never hand-roll a control or fake a primitive with a styled `<div>`. 2. **Sections are layout, not components.** A `<section>`/`<header>`/`<footer>` wrapper that arranges primitives is allowed — it is plain layout, not a faked primitive. 3. **Resolve every visual gap with a TOKEN.** A navy hero, a glass card, a brand glow, display type → a token override (global `:root`, scoped `[data-tenant]`, or **per-region role scoping** `[data-tenant] .region { --card: navy; --foreground: white; … }`). If the token doesn't exist, **add the token to the framework** (extensibility), never bake a value into the composition. 4. **Live in the app, or a `docs/` showcase** — never `src/components/`.
|
|
93
|
+
|
|
94
|
+
> The whole point of the token-extensibility work (scoped theming, glow / tint / gradient / focus,
|
|
95
|
+
> display type, dual-font, role-scoping) is so that **a composition pattern can reach 100% design
|
|
96
|
+
> fidelity from tokens alone** — which is exactly why almost nothing new needs to become a framework
|
|
97
|
+
> component.
|
|
98
|
+
|
|
99
|
+
---
|
|
100
|
+
|
|
101
|
+
## 5. The mandatory gate (enforced)
|
|
102
|
+
|
|
103
|
+
This contract is wired into the build/skill gates:
|
|
104
|
+
|
|
105
|
+
- **`godxjp-ui-component` skill, Gate 0** — the FIRST gate before writing any component is the Framework-Component Test.
|
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
# @godxjp/ui — the ten consumer rules
|
|
2
|
+
|
|
3
|
+
Read this once; the audit enforces it. Everything else in `docs/` is for contributors.
|
|
4
|
+
|
|
5
|
+
1. Load styles with `@import "@godxjp/ui/styles"` (fonts bundled) or `@import "@godxjp/ui/styles/core"` (no fonts). Never cherry-pick `*-layout.css`.
|
|
6
|
+
2. Every page is `<PageContainer title subtitle extra footer>`; its sections are spaced by the page. Group items inside a section with `<Flex direction="col" gap>` or `<ResponsiveGrid>`.
|
|
7
|
+
3. No Tailwind layout on your own elements: no `flex`, `grid`, `gap-*`, `p-*`, `m-*`, `space-*`. Rows are `<Flex>` (default row), stacks are `<Flex direction="col">`, grids are `<ResponsiveGrid>`.
|
|
8
|
+
4. No hand-rolled surfaces: no `rounded-* border bg-*` divs. A box is `Card`, a pill is `Badge`, a person is `Avatar`, a row is `ListRow`, a label/value pair is `Descriptions`, an empty area is `EmptyState`.
|
|
9
|
+
5. Real controls only: `Button`, `Input`, `Select`, `Textarea`, `Checkbox`… never raw `<button>`/`<input>`; a labelled control lives in `<FormField label>`. A Select outside a form takes `width="auto"`.
|
|
10
|
+
6. Text is `<Text>` / `<Heading>` with `tone`, `size`, `weight`, `truncate`, `mono` — not `className="text-muted-foreground font-semibold"`.
|
|
11
|
+
7. Colours are semantic tokens (`tone="destructive"`, `bg-primary`), never palette names, hex, or `bg-black` / `text-white`.
|
|
12
|
+
8. Sizes come from props (`size`, `width`, `columns`), never `w-[240px]` / `max-h-[420px]`.
|
|
13
|
+
9. Logical directions (`ms-`, `me-`, `start-`, `end-`) when a utility is unavoidable; never `ml-` / `left-`.
|
|
14
|
+
10. Run `node node_modules/@godxjp/ui/scripts/ui-audit.mjs <dir>` before every review; then `visual-audit.mjs <url>` on the running app. Zero errors is the bar.
|
|
@@ -0,0 +1,162 @@
|
|
|
1
|
+
# Theming `@godxjp/ui`
|
|
2
|
+
|
|
3
|
+
The design system ships a complete, **zero-config default theme**. Two audiences:
|
|
4
|
+
|
|
5
|
+
- **Internal apps** — just import the styles. No configuration needed. - **Customer apps** — override a handful of **anchor tokens** in your own `theme.css`; the whole system rescales/retints in proportion (golden-ratio type & radius, derived shadow ramp, etc.).
|
|
6
|
+
|
|
7
|
+
---
|
|
8
|
+
|
|
9
|
+
## Internal apps — zero config
|
|
10
|
+
|
|
11
|
+
```ts
|
|
12
|
+
import "@godxjp/ui/styles";
|
|
13
|
+
```
|
|
14
|
+
|
|
15
|
+
That single import ships everything: colors, the bundled fonts (**Noto Sans JP** as the default face — including the Vietnamese coverage — with **M PLUS 2** as the fallback, self-bundled & subsetted), the golden-ratio type scale, spacing grid, radius scale, shadow ramp, and all component CSS. Nothing else to configure. Pick density per surface with `<PageContainer density="compact | default | comfortable">`.
|
|
16
|
+
|
|
17
|
+
---
|
|
18
|
+
|
|
19
|
+
## CSS entries — `styles` or `styles/core`, nothing smaller
|
|
20
|
+
|
|
21
|
+
`@godxjp/ui/styles` bundles every component's CSS plus the fonts. When you manage fonts yourself (next/font, a system stack, a browser extension that must not ship font files), load the same layers without the faces:
|
|
22
|
+
|
|
23
|
+
```css
|
|
24
|
+
@import "@godxjp/ui/styles/core"; /* every component layer, no @font-face */
|
|
25
|
+
```
|
|
26
|
+
|
|
27
|
+
The per-layer files (`control`, `card-layout`, `navigation-layout`, …) are the package's internal structure, **not a public menu**. Layers share rules — a Select's rows and a menu's surface, a form's rhythm, a card's header type — so a page that loads a subset renders naked menus and unsized rows with no error. The runtime `visual-audit` reports it as `css-layers-missing`.
|
|
28
|
+
|
|
29
|
+
---
|
|
30
|
+
|
|
31
|
+
## Fonts — token-driven, per-language
|
|
32
|
+
|
|
33
|
+
The base ships **no hardcoded brand face** (`--font-sans-base` is a pure system stack). Supply your own faces (next/font, `@fontsource`, self-host) and set tokens — never edit the library. Two modes, both token-only:
|
|
34
|
+
|
|
35
|
+
```css
|
|
36
|
+
/* 1. One face everywhere */
|
|
37
|
+
:root {
|
|
38
|
+
--font-sans-base: var(--my-face), system-ui, sans-serif;
|
|
39
|
+
}
|
|
40
|
+
|
|
41
|
+
/* 2. Per-language faces — no [lang] selectors to write. Each locale reads its
|
|
42
|
+
slot, falling back to --font-sans-base. */
|
|
43
|
+
:root {
|
|
44
|
+
--font-sans-base: var(--brand-sans), system-ui, sans-serif;
|
|
45
|
+
--font-sans-ja: "Noto Sans JP", var(--font-sans-base); /* html lang="ja" */
|
|
46
|
+
--font-sans-vi: "Montserrat", var(--font-sans-base); /* html lang="vi" */
|
|
47
|
+
--font-sans-ko: var(--font-kr), var(--font-sans-base); /* html lang="ko" */
|
|
48
|
+
--font-sans-zh-hans: var(--font-sc), var(--font-sans-base); /* zh | zh-Hans | zh-CN */
|
|
49
|
+
--font-sans-zh-hant: var(--font-tc), var(--font-sans-base); /* zh-Hant | zh-TW */
|
|
50
|
+
}
|
|
51
|
+
```
|
|
52
|
+
|
|
53
|
+
`styles/base.css` wires every `[lang]` to its slot; the opt-in `styles/fonts`
|
|
54
|
+
overwrites `--font-sans-base` (and `--font-sans-vi`) with the bundled stack —
|
|
55
|
+
**Noto Sans JP** primary, **M PLUS 2** fallback. (**Bundle change:** v16 bundled
|
|
56
|
+
Noto Sans JP + Montserrat; v18.12.0–18.12.19 bundled M PLUS 2 + Noto Sans JP;
|
|
57
|
+
v18.12.20+ bundles Noto Sans JP + M PLUS 2 (product override, direct
|
|
58
|
+
instruction). If your design spec named an earlier bundle's faces, set the
|
|
59
|
+
tokens yourself rather than relying on the bundle.) Headings read
|
|
60
|
+
`--font-family-display` and body reads `--font-family-body`, both defaulting to
|
|
61
|
+
`--font-family-sans` — override them for a dual-font (display + body) brand.
|
|
62
|
+
|
|
63
|
+
> **Per-locale @font-face loading is the consumer's job.** The library only
|
|
64
|
+
> exposes the tokens; deciding _which_ `@font-face` blocks ship on _which_ pages
|
|
65
|
+
> (e.g. loading the heavy CJK face only on `lang="ja"` routes) is done in your
|
|
66
|
+
> app's font pipeline, not the library.
|
|
67
|
+
|
|
68
|
+
---
|
|
69
|
+
|
|
70
|
+
## Customer apps — override anchor tokens
|
|
71
|
+
|
|
72
|
+
Import the styles, then set anchor tokens in your app's `theme.css` (loaded after the import).
|
|
73
|
+
**Never edit the package token files** — override from your app.
|
|
74
|
+
|
|
75
|
+
````css
|
|
76
|
+
@import "@godxjp/ui/styles";
|
|
77
|
+
|
|
78
|
+
:root { /* ── Brand color (HSL components — no hsl() wrapper) ─────────────── */ --primary: 211 73% 15%; /* your brand hue → buttons, links, focus ring, brand chrome */ --primary-foreground: 0 0% 100%; /* text on --primary */ --ring: 24 99% 46%; /* focus ring (often a brand accent) */ --accent: 24 99% 95%; /* hover/active surface tint */ --accent-foreground: 24 99% 28%;
|
|
79
|
+
|
|
80
|
+
/* ── Type scale — ONE knob, golden-ratio derived ────────────────── */ --font-size-base: 1rem; /* 16px (default 14px). Every step (xs…2xl) + headings rescale by ratio. */ --font-size-ratio: 1.1227; /* φ^¼ default — raise toward φ=1.618 for a more dramatic scale. */
|
|
81
|
+
|
|
82
|
+
/* ── Radius — ONE knob, golden-ratio derived ───────────────────── */ --radius: 0.5rem; /* 8px (default 6px). xs…2xl rescale by --radius-ratio (φ). */
|
|
83
|
+
|
|
84
|
+
/* ── Shadow tint — ONE knob ─────────────────────────────────────── */ --shadow-color: 12 26 49; /* RGB channels (default 0 0 0). Tints the WHOLE shadow ramp. */
|
|
85
|
+
|
|
86
|
+
/* ── Brand depth — all opt-in, all quiet by default ─────────────── */ --shadow-glow: 0 8px 20px hsl(var(--primary) / 0.32); /* glow halo on the primary CTA */ --card-shadow: 0 1px 2px rgb(12 26 49 / 0.06), 0 10px 28px -14px rgb(12 26 49 / 0.2); /* lift every Card */ --focus-ring-color: var(--ring); /* hue of every focus ring */ --focus-ring-width: 2px; /* thickness of every focus ring — 0 turns it OFF */ --focus-ring-opacity: 1; /* alpha of every focus ring */ --focus-ring-offset: 0px; /* gap, outline-form rings only (star, dot, anchor) */ --gradient-hero: linear-gradient( 180deg, hsl(var(--accent)), transparent ); /* PageContainer header banner */ --gradient-glow: radial-gradient( 60% 70% at 90% -8%, hsl(var(--primary) / 0.1), transparent 70% ); /* AppShell ambient wash */ --overlay-background: rgb(12 26 49 / 0.55); /* modal scrim (Dialog / Sheet / Drawer) */ } ```
|
|
87
|
+
|
|
88
|
+
### The anchor tokens (single knobs that propagate)
|
|
89
|
+
|
|
90
|
+
| Anchor | Default | Propagates to |
|
|
91
|
+
| -------------------------------------------------------------------------- | ----------------------- | --------------------------------------------------------------------------------------- |
|
|
92
|
+
| `--primary` (+ `-foreground`, `--ring`, `--accent`, `--accent-foreground`) | SmartHR blue | every brand/action/focus surface |
|
|
93
|
+
| `--font-size-base` (+ `--font-size-ratio`) | `0.875rem` (14px) / φ^¼ | the whole type scale `--font-size-{2xs…2xl}` + `--heading-h{1…4}` (all `base × ratioⁿ`) |
|
|
94
|
+
| `--radius` (+ `--radius-ratio`) | `0.375rem` (6px) / φ | `--radius-{xs…2xl}` (all `radius × φⁿ`) |
|
|
95
|
+
| `--shadow-color` | `0 0 0` | every shadow step `--shadow-{xs…2xl}` (`rgb(color / α)`) |
|
|
96
|
+
| `--shadow-glow` | invisible | brand glow halo on the primary CTA (set the full shadow value) |
|
|
97
|
+
| `--card-shadow` | `none` | resting elevation of every Card |
|
|
98
|
+
| `--focus-ring-color` / `--focus-ring-width` | `var(--ring)` / `2px` | hue & thickness of every keyboard-focus ring (`width: 0` turns every ring OFF) |
|
|
99
|
+
| `--focus-ring-opacity` / `--focus-ring-offset` | `1` / `0px` | alpha of every ring · gap for outline-form rings (star, carousel dot, heading anchor) |
|
|
100
|
+
| `--gradient-{hero,glow,brand}` | `none` | hero header banner / AppShell ambient wash / spare (set the full gradient) |
|
|
101
|
+
| `--overlay-background` | `rgb(0 0 0 / .5)` | the scrim of every overlay (Dialog / AlertDialog / Sheet / Drawer) |
|
|
102
|
+
|
|
103
|
+
### Focus ring — one definition, three levels of override
|
|
104
|
+
|
|
105
|
+
Every keyboard-focus ring in the system is drawn by a single rule (`src/styles/focus-ring.css`) reading the four tokens above. Nothing else paints one; a test fails the build if a stylesheet tries.
|
|
106
|
+
|
|
107
|
+
That means retuning is a one-liner and it reaches everything:
|
|
108
|
+
|
|
109
|
+
```css
|
|
110
|
+
:root {
|
|
111
|
+
--focus-ring-color: 24 99% 46%; /* every ring, brand orange */
|
|
112
|
+
--focus-ring-width: 3px; /* every ring, thicker */
|
|
113
|
+
}
|
|
114
|
+
````
|
|
115
|
+
|
|
116
|
+
**Per component.** A component that genuinely needs a different ring publishes its own knob and the rule picks it up locally — Toggle and TimeInput ship a heavier, softer ring because they are filled surfaces where a hard 2px reads as a second border:
|
|
117
|
+
|
|
118
|
+
```css
|
|
119
|
+
:root {
|
|
120
|
+
--toggle-focus-ring-width: 3px;
|
|
121
|
+
--toggle-focus-ring-alpha: 0.35;
|
|
122
|
+
--sidebar-user-focus-ring-alpha: 0.45; /* tinted shell ground */
|
|
123
|
+
--rating-focus-ring-offset: 2px; /* outline form needs a gap */
|
|
124
|
+
}
|
|
125
|
+
```
|
|
126
|
+
|
|
127
|
+
**Per instance.** Any subtree, no CSS file needed:
|
|
128
|
+
|
|
129
|
+
```tsx
|
|
130
|
+
<div style={{ "--focus-ring-color": "0 84% 60%" } as React.CSSProperties}>…</div>
|
|
131
|
+
```
|
|
132
|
+
|
|
133
|
+
**Turning it off** — `--focus-ring-width: 0`, at any of the three levels. It ships **on** (WCAG 2.4.7 / 2.4.11); switching it off is a deliberate act on your side, never a default of this package. Removing the visible focus indicator fails WCAG 2.4.7 — do it only where another indicator takes over.
|
|
134
|
+
|
|
135
|
+
**Adding your own component to the system**: put `ui-focus-ring` (or `ui-focus-ring-outline` when the mark needs a gap) on the focusable element.
|
|
136
|
+
|
|
137
|
+
### What does NOT need an anchor
|
|
138
|
+
|
|
139
|
+
Density (`<PageContainer density>`) scales component sizes, not the grid. - **Pills / squared corners** use `--radius-pill` (9999px) / `--radius-sharp` (0) — full-round shapes stay round regardless of `--radius`.
|
|
140
|
+
|
|
141
|
+
---
|
|
142
|
+
|
|
143
|
+
## Multi-tenant (one app, many brands)
|
|
144
|
+
|
|
145
|
+
Scope the overrides under a tenant attribute instead of `:root`. The colour utilities are declared with `@theme inline`, so a scoped `--primary` (and the other anchors) **re-resolve at the element** — `bg-primary`, `text-success`, every component surface, the focus ring, the brand glow, gradients and the modal scrim all retint inside the scope:
|
|
146
|
+
|
|
147
|
+
```css
|
|
148
|
+
[data-tenant="betoya"] {
|
|
149
|
+
/* Colours, focus, glow, gradient, scrim — all propagate scoped */
|
|
150
|
+
--primary: 146 60% 30%; /* VN green */
|
|
151
|
+
--primary-foreground: 0 0% 100%;
|
|
152
|
+
--ring: 146 60% 30%;
|
|
153
|
+
--focus-ring-color: 146 60% 30%;
|
|
154
|
+
--shadow-glow: 0 8px 20px hsl(var(--primary) / 0.3);
|
|
155
|
+
--gradient-glow: radial-gradient(60% 70% at 90% -8%, hsl(var(--primary) / 0.1), transparent 70%);
|
|
156
|
+
--overlay-background: rgb(10 40 25 / 0.55);
|
|
157
|
+
}
|
|
158
|
+
```
|
|
159
|
+
|
|
160
|
+
Set `data-tenant` on the app root. Two CSS-inheritance caveats for the **scoped** case (a single `:root` brand theme is unaffected — there, overriding just `--radius` / `--shadow-color` cascades):
|
|
161
|
+
|
|
162
|
+
- **Radius & shadow-tint don't cascade from a scoped anchor.** `--radius-{xs…2xl}`, `--card-radius`, `--control-radius` and the `--shadow-{xs…2xl}` ramp are computed at their declaring element, so a scoped `--radius` / `--shadow-color` override won't reach them. For a scoped re-theme, re-declare the derived tokens you need (e.g. `--card-radius: var(--radius)`, or set `--card-shadow` to a literal value).
|
package/docs/DATETIME.md
ADDED
|
@@ -0,0 +1,69 @@
|
|
|
1
|
+
# formatDate — mandatory datetime display
|
|
2
|
+
|
|
3
|
+
Package: `@godxjp/ui/datetime`
|
|
4
|
+
|
|
5
|
+
## Import
|
|
6
|
+
|
|
7
|
+
```tsx
|
|
8
|
+
import { formatDate } from "@godxjp/ui/datetime";
|
|
9
|
+
import { useDateTime } from "@godxjp/ui/app";
|
|
10
|
+
```
|
|
11
|
+
|
|
12
|
+
## Rules
|
|
13
|
+
|
|
14
|
+
1. **Never** use `date-fns/format`, `toLocaleString`, or raw ISO slices for UI.
|
|
15
|
+
2. **Always** wrap apps in `<AppProvider>` so defaults apply.
|
|
16
|
+
3. **Optional** per-call `timezone` override — global prefs unchanged.
|
|
17
|
+
|
|
18
|
+
## Defaults
|
|
19
|
+
|
|
20
|
+
Omit `locale`, `timezone`, `timeFormat`, `dateFormat` → synced from AppProvider.
|
|
21
|
+
|
|
22
|
+
## dateFormat presets
|
|
23
|
+
|
|
24
|
+
| value | Pattern | Default locale |
|
|
25
|
+
| ----- | ------------ | -------------- |
|
|
26
|
+
| `iso` | `yyyy-MM-dd` | ja |
|
|
27
|
+
| `dmy` | `dd/MM/yyyy` | vi |
|
|
28
|
+
| `mdy` | `MM/dd/yyyy` | en |
|
|
29
|
+
|
|
30
|
+
Sent to backend as `x-date-format`. Pick with `<DateFormatPicker />`.
|
|
31
|
+
|
|
32
|
+
## kind presets
|
|
33
|
+
|
|
34
|
+
| kind | Use |
|
|
35
|
+
| ---------- | ---------------------------------------- |
|
|
36
|
+
| `auto` | Default — detects date / time / datetime |
|
|
37
|
+
| `datetime` | Audit logs, `created_at` |
|
|
38
|
+
| `date` | `"2026-05-01"` fields |
|
|
39
|
+
| `calendar` | `Date` from DatePicker |
|
|
40
|
+
| `time` | `"14:30"` HH:mm |
|
|
41
|
+
| `long` | Detail headings (PPP) |
|
|
42
|
+
| `relative` | Activity feeds |
|
|
43
|
+
|
|
44
|
+
## ISO 8601 patterns
|
|
45
|
+
|
|
46
|
+
Date order follows `dateFormat` from AppProvider (`iso` | `dmy` | `mdy`):
|
|
47
|
+
|
|
48
|
+
- `iso`: `yyyy-MM-dd` + `yyyy-MM-dd HH:mm`
|
|
49
|
+
- `dmy`: `dd/MM/yyyy` + `dd/MM/yyyy HH:mm`
|
|
50
|
+
- `mdy`: `MM/dd/yyyy` + `MM/dd/yyyy HH:mm`
|
|
51
|
+
|
|
52
|
+
Time portion still follows `timeFormat` (24h vs 12h).
|
|
53
|
+
|
|
54
|
+
## Examples
|
|
55
|
+
|
|
56
|
+
```tsx
|
|
57
|
+
formatDate("2026-05-01T14:30:00Z");
|
|
58
|
+
formatDate("2026-05-01");
|
|
59
|
+
formatDate("17:30", { kind: "time" });
|
|
60
|
+
formatDate(pickedDate, { kind: "calendar" });
|
|
61
|
+
formatDate(iso, { timezone: "Asia/Tokyo" });
|
|
62
|
+
```
|
|
63
|
+
|
|
64
|
+
## React
|
|
65
|
+
|
|
66
|
+
```tsx
|
|
67
|
+
const { format } = useDateTime();
|
|
68
|
+
return <td>{format(row.createdAt)}</td>;
|
|
69
|
+
```
|