@godxjp/ui 19.0.0 → 19.2.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +25 -128
- package/dist/app/app-provider.d.ts +1 -1
- package/dist/app/app-provider.js +3 -0
- package/dist/app/theme-axes.d.ts +4 -15
- package/dist/app/timezones.d.ts +1 -4
- package/dist/components/charts/area-chart.d.ts +2 -3
- package/dist/components/charts/bar-chart.d.ts +2 -3
- package/dist/components/charts/chart-frame.d.ts +7 -16
- package/dist/components/charts/chart-summary.d.ts +2 -2
- package/dist/components/charts/compact-bar-trend.d.ts +9 -24
- package/dist/components/charts/index.d.ts +1 -6
- package/dist/components/data-display/badge.d.ts +2 -12
- package/dist/components/data-display/card.d.ts +21 -41
- package/dist/components/data-display/carousel.d.ts +1 -2
- package/dist/components/data-display/code-block.d.ts +4 -0
- package/dist/components/data-display/code-block.js +24 -0
- package/dist/components/data-display/data-table.d.ts +15 -37
- package/dist/components/data-display/data-table.js +1 -3
- package/dist/components/data-display/descriptions.d.ts +2 -6
- package/dist/components/data-display/descriptions.js +0 -2
- package/dist/components/data-display/index.d.ts +4 -0
- package/dist/components/data-display/index.js +4 -0
- package/dist/components/data-display/list-row.d.ts +3 -22
- package/dist/components/data-display/permission-matrix.d.ts +7 -20
- package/dist/components/data-display/progress.d.ts +1 -1
- package/dist/components/data-display/prose.d.ts +4 -0
- package/dist/components/data-display/prose.js +20 -0
- package/dist/components/data-display/service-launcher-card.d.ts +3 -10
- package/dist/components/data-display/table.d.ts +20 -80
- package/dist/components/data-display/table.js +0 -3
- package/dist/components/data-display/timeline.d.ts +3 -5
- package/dist/components/data-entry/branch-scope-picker.d.ts +2 -19
- package/dist/components/data-entry/branch-scope-picker.js +0 -1
- package/dist/components/data-entry/calendar.d.ts +3 -2
- package/dist/components/data-entry/calendar.js +58 -3
- package/dist/components/data-entry/cascader.js +3 -1
- package/dist/components/data-entry/checkbox-group.js +12 -5
- package/dist/components/data-entry/checkbox.js +30 -21
- package/dist/components/data-entry/command-palette.d.ts +8 -22
- package/dist/components/data-entry/date-picker.d.ts +4 -5
- package/dist/components/data-entry/date-picker.js +12 -3
- package/dist/components/data-entry/date-range-picker.d.ts +1 -1
- package/dist/components/data-entry/date-range-picker.js +17 -6
- package/dist/components/data-entry/form-errors.d.ts +7 -18
- package/dist/components/data-entry/form-field.d.ts +1 -1
- package/dist/components/data-entry/form-field.js +15 -6
- package/dist/components/data-entry/form.d.ts +1 -9
- package/dist/components/data-entry/input.d.ts +16 -14
- package/dist/components/data-entry/input.js +13 -3
- package/dist/components/data-entry/month-picker.js +6 -4
- package/dist/components/data-entry/month-range-picker.d.ts +4 -6
- package/dist/components/data-entry/month-range-picker.js +11 -5
- package/dist/components/data-entry/number-input.d.ts +1 -5
- package/dist/components/data-entry/number-input.js +1 -0
- package/dist/components/data-entry/radio.js +19 -6
- package/dist/components/data-entry/search-select.d.ts +3 -5
- package/dist/components/data-entry/search-select.js +8 -2
- package/dist/components/data-entry/select.d.ts +15 -2
- package/dist/components/data-entry/select.js +57 -10
- package/dist/components/data-entry/switch.js +9 -2
- package/dist/components/data-entry/textarea.d.ts +10 -16
- package/dist/components/data-entry/textarea.js +8 -1
- package/dist/components/data-entry/time-picker.d.ts +3 -5
- package/dist/components/data-entry/tree-select.js +3 -1
- package/dist/components/data-entry/upload-types.d.ts +1 -5
- package/dist/components/data-entry/use-upload-draft.d.ts +0 -4
- package/dist/components/feedback/dialog.d.ts +6 -15
- package/dist/components/feedback/overlay-header-tone.d.ts +1 -1
- package/dist/components/feedback/sheet.d.ts +3 -10
- package/dist/components/feedback/sheet.js +1 -1
- package/dist/components/feedback/sonner.js +2 -3
- package/dist/components/general/activity.d.ts +4 -30
- package/dist/components/general/button.js +1 -10
- package/dist/components/general/logo.d.ts +6 -28
- package/dist/components/general/reveal.d.ts +3 -9
- package/dist/components/general/typography.d.ts +1 -3
- package/dist/components/layout/account-chip.d.ts +8 -0
- package/dist/components/layout/account-chip.js +45 -0
- package/dist/components/layout/auth-divider.d.ts +2 -9
- package/dist/components/layout/auth-shell.d.ts +1 -14
- package/dist/components/layout/breadcrumb.d.ts +1 -5
- package/dist/components/layout/centered-shell.d.ts +4 -18
- package/dist/components/layout/error-surface.d.ts +11 -28
- package/dist/components/layout/error-surface.js +4 -1
- package/dist/components/layout/index.d.ts +2 -0
- package/dist/components/layout/index.js +2 -0
- package/dist/components/layout/legal-document-shell.d.ts +5 -28
- package/dist/components/layout/master-detail.d.ts +2 -18
- package/dist/components/layout/page-container.js +0 -1
- package/dist/components/layout/responsive-grid.d.ts +6 -1
- package/dist/components/layout/responsive-grid.js +9 -2
- package/dist/components/layout/service-role-panel.d.ts +7 -19
- package/dist/components/layout/sidebar.d.ts +5 -27
- package/dist/components/layout/sidebar.js +0 -1
- package/dist/components/layout/split-pane.d.ts +0 -7
- package/dist/components/layout/topbar.d.ts +1 -14
- package/dist/components/navigation/app-setting-picker.js +1 -3
- package/dist/components/navigation/filter-bar.d.ts +1 -6
- package/dist/components/navigation/pagination-utils.d.ts +2 -12
- package/dist/components/navigation/tabs-scroll.d.ts +2 -36
- package/dist/components/navigation/tabs.js +4 -8
- package/dist/components/query/data-state.d.ts +2 -2
- package/dist/components/ui/credential-reveal.d.ts +1 -4
- package/dist/components/ui/hover-card.d.ts +1 -2
- package/dist/components/ui/separator.d.ts +2 -15
- package/dist/components/ui/toggle-group.d.ts +1 -5
- package/dist/components/ui/toggle.d.ts +6 -31
- package/dist/email/brand-mark.d.ts +6 -34
- package/dist/email/color.d.ts +7 -17
- package/dist/email/geometry.d.ts +4 -8
- package/dist/email/index.d.ts +4 -48
- package/dist/email/inline-style.d.ts +3 -9
- package/dist/email/urgency.d.ts +2 -7
- package/dist/form/form-context.d.ts +2 -5
- package/dist/form/form-root.d.ts +1 -2
- package/dist/i18n/messages/en.json +4 -0
- package/dist/i18n/messages/ja.json +4 -0
- package/dist/i18n/messages/vi.json +4 -0
- package/dist/inertia/index.d.ts +2 -10
- package/dist/lib/control-styles.d.ts +10 -21
- package/dist/lib/control-styles.js +4 -6
- package/dist/lib/datetime/format-date.d.ts +1 -4
- package/dist/lib/field-a11y.d.ts +31 -36
- package/dist/lib/field-a11y.js +16 -2
- package/dist/lib/format.d.ts +4 -8
- package/dist/lib/hooks.d.ts +6 -12
- package/dist/lib/permission-grid.d.ts +3 -18
- package/dist/lib/query-error.d.ts +3 -3
- package/dist/props/components/app.prop.d.ts +19 -27
- package/dist/props/components/charts.prop.d.ts +2 -3
- package/dist/props/components/data-display.prop.d.ts +48 -72
- package/dist/props/components/data-entry.prop.d.ts +41 -30
- package/dist/props/components/form.prop.d.ts +2 -6
- package/dist/props/components/general.prop.d.ts +11 -27
- package/dist/props/components/layout.prop.d.ts +89 -260
- package/dist/props/components/navigation.prop.d.ts +27 -42
- package/dist/props/registry.d.ts +31 -0
- package/dist/props/registry.js +33 -0
- package/dist/props/vocabulary/data.prop.d.ts +18 -49
- package/dist/props/vocabulary/index.d.ts +1 -1
- package/dist/props/vocabulary/interaction.prop.d.ts +10 -12
- package/dist/props/vocabulary/layout.prop.d.ts +8 -30
- package/dist/props/vocabulary/shared.prop.d.ts +3 -2
- package/dist/styles/alert-layout.css +1 -32
- package/dist/styles/badge-layout.css +4 -18
- package/dist/styles/base.css +14 -113
- package/dist/styles/card-layout.css +6 -128
- package/dist/styles/chart-layout.css +2 -17
- package/dist/styles/control.css +380 -458
- package/dist/styles/core.css +21 -0
- package/dist/styles/data-display-layout.css +175 -94
- package/dist/styles/data-entry-layout.css +0 -45
- package/dist/styles/density.css +1 -30
- package/dist/styles/dialog-layout.css +5 -69
- package/dist/styles/focus-ring.css +13 -87
- package/dist/styles/fonts.css +1 -31
- package/dist/styles/form-layout.css +7 -91
- package/dist/styles/index.css +2 -20
- package/dist/styles/layout.css +38 -456
- package/dist/styles/logo-layout.css +1 -35
- package/dist/styles/motion.css +3 -42
- package/dist/styles/navigation-layout.css +3 -50
- package/dist/styles/shell-layout.css +37 -403
- package/dist/styles/table-layout.css +16 -274
- package/dist/styles/text-layout.css +7 -21
- package/dist/styles/toggle.css +1 -23
- package/dist/theme/dxs.canonical.css +1 -55
- package/dist/theme/example.service.css +1 -26
- package/dist/theme/famgia.service.css +5 -15
- package/dist/tokens/axes.css +3 -40
- package/dist/tokens/base.css +1 -4
- package/dist/tokens/components/activity.css +6 -42
- package/dist/tokens/components/badge.css +4 -13
- package/dist/tokens/components/banner.css +4 -9
- package/dist/tokens/components/card.css +32 -88
- package/dist/tokens/components/chart.css +9 -26
- package/dist/tokens/components/control.css +37 -222
- package/dist/tokens/components/data-display.css +28 -79
- package/dist/tokens/components/data-entry.css +5 -19
- package/dist/tokens/components/descriptions.css +7 -27
- package/dist/tokens/components/email.css +38 -84
- package/dist/tokens/components/error-surface.css +2 -18
- package/dist/tokens/components/feedback.css +27 -124
- package/dist/tokens/components/form.css +13 -45
- package/dist/tokens/components/legal-document.css +16 -41
- package/dist/tokens/components/list-row.css +11 -36
- package/dist/tokens/components/logo.css +2 -57
- package/dist/tokens/components/navigation.css +16 -94
- package/dist/tokens/components/scroll-area.css +2 -18
- package/dist/tokens/components/separator.css +8 -30
- package/dist/tokens/components/sheet.css +3 -14
- package/dist/tokens/components/shell.css +53 -307
- package/dist/tokens/components/sidebar.css +5 -22
- package/dist/tokens/components/table.css +19 -140
- package/dist/tokens/components/toggle.css +3 -65
- package/dist/tokens/components/upload.css +7 -43
- package/dist/tokens/foundation.css +108 -383
- package/dist/tokens/semantic/layout.css +33 -207
- package/docs/CANONICAL-CONTRACTS.md +206 -0
- package/docs/COMPONENTS.md +157 -0
- package/docs/COMPOSITION-VS-COMPONENT.md +105 -0
- package/docs/CONSUMER-RULES.md +14 -0
- package/docs/CUSTOMER-THEMING.md +162 -0
- package/docs/DATETIME.md +69 -0
- package/docs/DEVELOPMENT.md +173 -0
- package/docs/FORMS.md +143 -0
- package/docs/FRAME-A11Y-CI.md +267 -0
- package/docs/FRAME-COVERAGE-LEDGER.md +123 -0
- package/docs/FRAME-COVERAGE-REPORT.md +140 -0
- package/docs/FRAME-COVERAGE-STANDARD.md +65 -0
- package/docs/FRAME-COVERAGE.md +29 -0
- package/docs/PROPS-REGISTRY.md +61 -0
- package/docs/PROPS-VOCABULARY.md +100 -0
- package/docs/README.md +60 -0
- package/docs/REGISTRY.md +70 -0
- package/docs/SPACING.md +56 -0
- package/docs/STANDARDS-vocabulary-tokens.md +48 -0
- package/docs/TESTING.md +98 -0
- package/docs/TOKENS.md +347 -0
- package/docs/asset-modules.d.ts +46 -0
- package/docs/assets/cover-terrain.svg +6 -0
- package/docs/assets/portrait-amber.svg +5 -0
- package/docs/assets/portrait-clay.svg +5 -0
- package/docs/assets/portrait-indigo.svg +5 -0
- package/docs/assets/portrait-iris.svg +5 -0
- package/docs/assets/portrait-moss.svg +5 -0
- package/docs/assets/portrait-plum.svg +5 -0
- package/docs/assets/portrait-slate.svg +5 -0
- package/docs/charts/compact-bar-trend.tsx +328 -0
- package/docs/charts/size-tiers.tsx +192 -0
- package/docs/data-display/accordion.tsx +99 -0
- package/docs/data-display/avatar.tsx +355 -0
- package/docs/data-display/badge.tsx +247 -0
- package/docs/data-display/card/examples/detail-panel.tsx +106 -0
- package/docs/data-display/card/index.md +3 -0
- package/docs/data-display/card/index.tsx +285 -0
- package/docs/data-display/carousel.tsx +156 -0
- package/docs/data-display/charts.tsx +198 -0
- package/docs/data-display/code-block.tsx +90 -0
- package/docs/data-display/collapsible.tsx +162 -0
- package/docs/data-display/credential-reveal.tsx +145 -0
- package/docs/data-display/data-table/examples/approval-queue.tsx +212 -0
- package/docs/data-display/data-table/examples/grid-features.tsx +158 -0
- package/docs/data-display/data-table/examples/list-page.tsx +175 -0
- package/docs/data-display/data-table/index.md +5 -0
- package/docs/data-display/data-table/index.tsx +295 -0
- package/docs/data-display/descriptions.tsx +143 -0
- package/docs/data-display/empty-state.tsx +164 -0
- package/docs/data-display/hover-card.tsx +181 -0
- package/docs/data-display/list-row.tsx +420 -0
- package/docs/data-display/permission-matrix.tsx +184 -0
- package/docs/data-display/popover-touch.tsx +27 -0
- package/docs/data-display/popover.tsx +245 -0
- package/docs/data-display/progress.tsx +84 -0
- package/docs/data-display/prose.tsx +105 -0
- package/docs/data-display/qr-code.tsx +68 -0
- package/docs/data-display/scroll-area.tsx +271 -0
- package/docs/data-display/service-launcher-card.tsx +145 -0
- package/docs/data-display/stat-card.tsx +99 -0
- package/docs/data-display/table.tsx +251 -0
- package/docs/data-display/timeline.tsx +112 -0
- package/docs/data-display/touch-actions.tsx +36 -0
- package/docs/data-display/tree-list.tsx +107 -0
- package/docs/data-entry/branch-scope-picker.tsx +123 -0
- package/docs/data-entry/calendar.tsx +180 -0
- package/docs/data-entry/cascader.tsx +378 -0
- package/docs/data-entry/checkbox.tsx +256 -0
- package/docs/data-entry/color-picker.tsx +117 -0
- package/docs/data-entry/command-palette.tsx +179 -0
- package/docs/data-entry/command.tsx +262 -0
- package/docs/data-entry/country-picker-recipe.tsx +170 -0
- package/docs/data-entry/date-picker.tsx +191 -0
- package/docs/data-entry/date-range-picker.tsx +149 -0
- package/docs/data-entry/form/examples/employee-settings.tsx +267 -0
- package/docs/data-entry/form/examples/invoice-form.tsx +387 -0
- package/docs/data-entry/form-field/examples/a11y-contract.tsx +240 -0
- package/docs/data-entry/form-field/examples/create-form.tsx +105 -0
- package/docs/data-entry/form-field/index.md +8 -0
- package/docs/data-entry/form-field/index.tsx +326 -0
- package/docs/data-entry/form-inertia.tsx +80 -0
- package/docs/data-entry/form-root.tsx +102 -0
- package/docs/data-entry/form.tsx +724 -0
- package/docs/data-entry/input-otp.tsx +231 -0
- package/docs/data-entry/input.tsx +114 -0
- package/docs/data-entry/label.tsx +100 -0
- package/docs/data-entry/month-picker.tsx +101 -0
- package/docs/data-entry/month-range-picker.tsx +115 -0
- package/docs/data-entry/number-input.tsx +240 -0
- package/docs/data-entry/password-input.tsx +106 -0
- package/docs/data-entry/password-strength.tsx +97 -0
- package/docs/data-entry/radio-group.tsx +95 -0
- package/docs/data-entry/rating.tsx +87 -0
- package/docs/data-entry/search-input.tsx +120 -0
- package/docs/data-entry/select-async-contracts.tsx +108 -0
- package/docs/data-entry/select-matrix.tsx +204 -0
- package/docs/data-entry/select.tsx +369 -0
- package/docs/data-entry/slider.tsx +130 -0
- package/docs/data-entry/switch.tsx +67 -0
- package/docs/data-entry/tag-input.tsx +108 -0
- package/docs/data-entry/textarea.tsx +209 -0
- package/docs/data-entry/time-picker.tsx +99 -0
- package/docs/data-entry/toggle-count.tsx +293 -0
- package/docs/data-entry/toggle-group.tsx +225 -0
- package/docs/data-entry/toggle.tsx +127 -0
- package/docs/data-entry/transfer.tsx +97 -0
- package/docs/data-entry/tree-select.tsx +204 -0
- package/docs/data-entry/upload.tsx +184 -0
- package/docs/feedback/alert-dialog.tsx +270 -0
- package/docs/feedback/alert.tsx +248 -0
- package/docs/feedback/banner.tsx +183 -0
- package/docs/feedback/danger-confirm.tsx +88 -0
- package/docs/feedback/dialog-touch.tsx +24 -0
- package/docs/feedback/dialog.tsx +193 -0
- package/docs/feedback/sheet.tsx +410 -0
- package/docs/feedback/skeleton.tsx +111 -0
- package/docs/feedback/toast.tsx +135 -0
- package/docs/feedback/tooltip.tsx +171 -0
- package/docs/feedback/two-factor-setup.tsx +68 -0
- package/docs/foundation/_email-specimen.ts +274 -0
- package/docs/foundation/colors.tsx +202 -0
- package/docs/foundation/density.tsx +232 -0
- package/docs/foundation/email-tokens.tsx +306 -0
- package/docs/foundation/radius-shadow.tsx +152 -0
- package/docs/foundation/spacing.tsx +211 -0
- package/docs/foundation/typography.tsx +147 -0
- package/docs/general/activity.tsx +224 -0
- package/docs/general/button/examples/destructive-confirm.tsx +90 -0
- package/docs/general/button/examples/form-actions.tsx +85 -0
- package/docs/general/button/examples/toolbar.tsx +160 -0
- package/docs/general/button/index.md +12 -0
- package/docs/general/button/index.tsx +211 -0
- package/docs/general/logo.tsx +131 -0
- package/docs/general/reveal.tsx +41 -0
- package/docs/general/typography.tsx +152 -0
- package/docs/layout/account-chip.tsx +72 -0
- package/docs/layout/admin-collection.tsx +122 -0
- package/docs/layout/app-shell.tsx +374 -0
- package/docs/layout/aspect-ratio.tsx +119 -0
- package/docs/layout/auth-account-summary.tsx +103 -0
- package/docs/layout/auth-divider.tsx +28 -0
- package/docs/layout/auth-footer.tsx +37 -0
- package/docs/layout/auth-identity.tsx +36 -0
- package/docs/layout/auth-recovery/examples/mfa-challenge.md +41 -0
- package/docs/layout/auth-recovery/examples/mfa-challenge.tsx +254 -0
- package/docs/layout/auth-recovery/examples/mobile-390.md +25 -0
- package/docs/layout/auth-recovery/examples/mobile-390.tsx +82 -0
- package/docs/layout/auth-recovery/examples/password-recovery.md +24 -0
- package/docs/layout/auth-recovery/examples/password-recovery.tsx +197 -0
- package/docs/layout/auth-recovery/examples/wrapping-ja-en-vi.md +27 -0
- package/docs/layout/auth-recovery/examples/wrapping-ja-en-vi.tsx +156 -0
- package/docs/layout/auth-recovery/index.md +140 -0
- package/docs/layout/auth-recovery/index.tsx +96 -0
- package/docs/layout/auth-shell-context.tsx +103 -0
- package/docs/layout/auth-shell-device.tsx +112 -0
- package/docs/layout/auth-shell-registration.tsx +335 -0
- package/docs/layout/auth-shell-variants.tsx +139 -0
- package/docs/layout/auth-shell.tsx +59 -0
- package/docs/layout/auth-stack.tsx +40 -0
- package/docs/layout/centered-shell.tsx +102 -0
- package/docs/layout/error-surface/examples/application-403.tsx +84 -0
- package/docs/layout/error-surface/examples/application-404.tsx +77 -0
- package/docs/layout/error-surface/examples/system-500.tsx +47 -0
- package/docs/layout/error-surface/examples/system-503.tsx +48 -0
- package/docs/layout/error-surface/index.md +153 -0
- package/docs/layout/error-surface/index.tsx +239 -0
- package/docs/layout/flex.tsx +262 -0
- package/docs/layout/legal-document-shell/_data.ts +110 -0
- package/docs/layout/legal-document-shell/examples/desktop-1440.md +12 -0
- package/docs/layout/legal-document-shell/examples/desktop-1440.tsx +83 -0
- package/docs/layout/legal-document-shell/examples/mobile-390.md +22 -0
- package/docs/layout/legal-document-shell/examples/mobile-390.tsx +70 -0
- package/docs/layout/legal-document-shell/examples/tablet-1024.md +3 -0
- package/docs/layout/legal-document-shell/examples/tablet-1024.tsx +84 -0
- package/docs/layout/legal-document-shell/examples/wrapping-ja-en-vi.md +18 -0
- package/docs/layout/legal-document-shell/examples/wrapping-ja-en-vi.tsx +61 -0
- package/docs/layout/legal-document-shell/index.md +51 -0
- package/docs/layout/legal-document-shell/index.tsx +101 -0
- package/docs/layout/master-detail.tsx +387 -0
- package/docs/layout/org-switcher.tsx +131 -0
- package/docs/layout/page-container.tsx +946 -0
- package/docs/layout/resizable-panel.tsx +419 -0
- package/docs/layout/responsive-grid.tsx +235 -0
- package/docs/layout/separator.tsx +327 -0
- package/docs/layout/service-role-panel.tsx +144 -0
- package/docs/layout/sidebar.tsx +586 -0
- package/docs/layout/split-pane.tsx +451 -0
- package/docs/layout/topbar.tsx +347 -0
- package/docs/navigation/app-setting-picker.tsx +141 -0
- package/docs/navigation/breadcrumb.tsx +128 -0
- package/docs/navigation/context-menu.tsx +117 -0
- package/docs/navigation/dropdown-menu.tsx +213 -0
- package/docs/navigation/filter-bar.tsx +227 -0
- package/docs/navigation/menubar.tsx +141 -0
- package/docs/navigation/navigation-menu.tsx +165 -0
- package/docs/navigation/pagination.tsx +241 -0
- package/docs/navigation/steps.tsx +263 -0
- package/docs/navigation/tabs-rtl.tsx +28 -0
- package/docs/navigation/tabs.tsx +308 -0
- package/docs/navigation/toolbar.tsx +339 -0
- package/docs/providers/app-provider.tsx +191 -0
- package/docs/providers/format-date.tsx +230 -0
- package/docs/query/button-refetch.tsx +160 -0
- package/docs/query/data-state.tsx +192 -0
- package/docs/query/infinite-query-state.tsx +93 -0
- package/docs/query/mutation-feedback.tsx +70 -0
- package/docs/query/prefetch-link.tsx +262 -0
- package/docs/query/touch-actions.tsx +68 -0
- package/docs/showcase/acme-portal.tsx +441 -0
- package/docs/showcase/acme-website.tsx +455 -0
- package/docs/showcase/case1-warehouse-dashboard.tsx +343 -0
- package/docs/showcase/case2-employee-me.tsx +441 -0
- package/docs/showcase/case3-approval-workflow.tsx +527 -0
- package/docs/showcase/case4-login.tsx +307 -0
- package/docs/showcase/case5-shift-calendar.tsx +795 -0
- package/docs/showcase/case6-agency-handy.tsx +1072 -0
- package/docs/showcase/futurelastic-web.tsx +390 -0
- package/docs/showcase/org-switcher.tsx +313 -0
- package/docs/showcase/permission-matrix.tsx +343 -0
- package/docs/showcase/public-landing.tsx +210 -0
- package/docs/showcase/settings-account-sections.tsx +559 -0
- package/docs/showcase/settings-security-mfa.tsx +145 -0
- package/docs/showcase/table-approval-queue.tsx +199 -0
- package/docs/showcase/table-bulk-actions.tsx +460 -0
- package/docs/showcase/table-compact-kintone.tsx +438 -0
- package/docs/showcase/table-conditional-format.tsx +367 -0
- package/docs/showcase/table-crud-list.tsx +544 -0
- package/docs/showcase/table-density.tsx +340 -0
- package/docs/showcase/table-expandable-rows.tsx +471 -0
- package/docs/showcase/table-filter-chips.tsx +461 -0
- package/docs/showcase/table-footer-totals.tsx +311 -0
- package/docs/showcase/table-grouped-subtotals.tsx +388 -0
- package/docs/showcase/table-master-detail.tsx +479 -0
- package/docs/showcase/table-pagination.tsx +320 -0
- package/docs/showcase/table-states.tsx +363 -0
- package/docs/showcase/table-sticky-columns.tsx +373 -0
- package/docs/showcase/table-tree-rows.tsx +444 -0
- package/docs/showcase/table-view-tabs.tsx +488 -0
- package/package.json +10 -11
- package/scripts/_agent-setup.mjs +16 -2
- package/scripts/audit-hook.mjs +3 -13
- package/scripts/init-agent-kit.mjs +1 -14
- package/scripts/postinstall.mjs +12 -12
- package/scripts/ui-audit.mjs +93 -31
- package/scripts/visual-audit-rules.mjs +51 -7
- package/scripts/visual-audit.mjs +118 -47
|
@@ -0,0 +1,455 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Showcase · ACME marketing website — a TOKEN-ONLY rebuild of the Claude Design `ui_kits/website`.
|
|
3
|
+
*
|
|
4
|
+
* Proves the hard brief: a CONSUMER agent, given a Claude Design export, reproduces a full marketing
|
|
5
|
+
* landing page from **token configuration + a brand stylesheet + REAL @godxjp/ui primitives** — with
|
|
6
|
+
* NO new framework components. Per docs/COMPOSITION-VS-COMPONENT.md, marketing sections (Navbar,
|
|
7
|
+
* Hero, CTA, Footer) FAIL the Framework-Component Test, so they are COMPOSITION: layout `<section>`s
|
|
8
|
+
* arranging Card / Button / Text / Avatar / ResponsiveGrid / Flex.
|
|
9
|
+
*
|
|
10
|
+
* The brand-specific styling lives in the `THEME` <style> block (a consumer's own stylesheet) — the
|
|
11
|
+
* design's tokens + a few marketing type/section classes + per-region role scoping for the navy
|
|
12
|
+
* sections. The TSX stays clean: real primitives + semantic class names, no arbitrary utilities.
|
|
13
|
+
*/
|
|
14
|
+
import * as React from "react";
|
|
15
|
+
import {
|
|
16
|
+
ArrowRight,
|
|
17
|
+
ChevronDown,
|
|
18
|
+
CreditCard,
|
|
19
|
+
Globe,
|
|
20
|
+
Link2,
|
|
21
|
+
Mail,
|
|
22
|
+
PackageCheck,
|
|
23
|
+
Phone,
|
|
24
|
+
Plus,
|
|
25
|
+
Receipt,
|
|
26
|
+
Scale,
|
|
27
|
+
Search,
|
|
28
|
+
ShieldCheck,
|
|
29
|
+
ShoppingCart,
|
|
30
|
+
Ship,
|
|
31
|
+
UserPlus,
|
|
32
|
+
Warehouse,
|
|
33
|
+
} from "lucide-react";
|
|
34
|
+
|
|
35
|
+
import { Button, Text } from "@godxjp/ui/general";
|
|
36
|
+
import { Avatar, AvatarFallback, Card, CardContent, CardCover } from "@godxjp/ui/data-display";
|
|
37
|
+
import { Flex, ResponsiveGrid } from "@godxjp/ui/layout";
|
|
38
|
+
|
|
39
|
+
// ── Brand stylesheet: the design's tokens + marketing type/section classes + navy role-scoping. ───
|
|
40
|
+
// This is what a consumer ships as their own theme.css — raw brand values live HERE (CSS), not as
|
|
41
|
+
// arbitrary utilities in the markup. The page below reads it via semantic class names only.
|
|
42
|
+
const THEME = `
|
|
43
|
+
@import url('https://fonts.googleapis.com/css2?family=Source+Sans+3:wght@400;600;700;800;900&family=Inter:wght@400;500;600;700&display=swap');
|
|
44
|
+
[data-tenant="acme-web"] {
|
|
45
|
+
--primary: 41 73% 53%; --primary-foreground: 217 61% 12%; --ring: 41 73% 53%;
|
|
46
|
+
--accent: 42 81% 96%; --accent-foreground: 41 72% 44%;
|
|
47
|
+
--background: 210 33% 97%; --foreground: 217 61% 12%;
|
|
48
|
+
--card: 0 0% 100%; --card-foreground: 217 61% 12%;
|
|
49
|
+
--secondary: 217 61% 12%; --secondary-foreground: 0 0% 100%;
|
|
50
|
+
--muted: 214 27% 95%; --muted-foreground: 216 14% 37%;
|
|
51
|
+
/* --input is the CONTROL boundary, held to 3:1 (SC 1.4.11): 3.33 on the page, 3.57 on a card,
|
|
52
|
+
3.18 on --muted. It was 216 16% 80% = 1.46:1. --border is decorative chrome; it stays. */
|
|
53
|
+
--border: 214 27% 90%; --input: 216 16% 55%;
|
|
54
|
+
--success: 152 100% 25%; --warning: 41 73% 53%; --destructive: 11 82% 56%; --info: 203 100% 37%;
|
|
55
|
+
--radius: 0.875rem; --radius-md: 10px; --radius-lg: 14px;
|
|
56
|
+
--card-radius: var(--radius); --control-radius: var(--radius);
|
|
57
|
+
--shadow-color: 38 79 145;
|
|
58
|
+
--card-shadow: 0 1px 3px rgb(38 79 145 / 0.08), 0 1px 2px rgb(38 79 145 / 0.06);
|
|
59
|
+
--shadow-glow: 0 8px 20px hsl(41 73% 53% / 0.32);
|
|
60
|
+
--focus-ring-color: 41 73% 53%;
|
|
61
|
+
--font-family-display: "Source Sans 3", system-ui, sans-serif;
|
|
62
|
+
--font-family-body: "Inter", system-ui, -apple-system, "Segoe UI", sans-serif;
|
|
63
|
+
--font-family-sans: var(--font-family-body);
|
|
64
|
+
--text-brand: 41 84% 26%; /* dark gold, eyebrows clear AA on light sections */
|
|
65
|
+
}
|
|
66
|
+
/* Marketing layout + type (a consumer's section stylesheet) */
|
|
67
|
+
[data-tenant="acme-web"] .tx-shell { margin-inline: auto; width: 100%; max-width: 1200px; padding-inline: 2rem;
|
|
68
|
+
/* ResponsiveGrid uses @container queries, so establish the container here (PageContainer does this
|
|
69
|
+
* in an app; a marketing composition provides it on its own shell). */
|
|
70
|
+
container-type: inline-size; }
|
|
71
|
+
[data-tenant="acme-web"] .tx-section { padding-block: 5rem; }
|
|
72
|
+
[data-tenant="acme-web"] .tx-navbar { position: sticky; top: 0; z-index: 30; background: hsl(var(--background) / 0.85);
|
|
73
|
+
backdrop-filter: blur(10px); border-bottom: 1px solid hsl(var(--border)); }
|
|
74
|
+
[data-tenant="acme-web"] .tx-navbar-inner { height: 72px; display: flex; align-items: center; gap: 2.25rem; }
|
|
75
|
+
[data-tenant="acme-web"] .tx-brand { font-family: var(--font-family-display); font-weight: 800; font-size: 1.375rem; letter-spacing: -0.01em; color: hsl(var(--foreground)); }
|
|
76
|
+
[data-tenant="acme-web"] .tx-eyebrow { font-family: var(--font-family-display); font-weight: 700; font-size: 0.8125rem;
|
|
77
|
+
letter-spacing: 0.12em; text-transform: uppercase; color: hsl(var(--text-brand)); }
|
|
78
|
+
[data-tenant="acme-web"] .tx-display { font-family: var(--font-family-display); font-weight: 900; font-size: 3.5rem;
|
|
79
|
+
line-height: 1.05; letter-spacing: -0.02em; margin: 1rem 0; color: hsl(var(--foreground)); }
|
|
80
|
+
[data-tenant="acme-web"] .tx-h2 { font-family: var(--font-family-display); font-weight: 800; font-size: 2.25rem;
|
|
81
|
+
line-height: 1.15; letter-spacing: -0.02em; margin: 0.75rem 0 0.625rem; color: hsl(var(--foreground)); }
|
|
82
|
+
[data-tenant="acme-web"] .tx-lead { font-size: 1.1875rem; line-height: 1.6; color: hsl(var(--muted-foreground)); max-width: 480px; }
|
|
83
|
+
[data-tenant="acme-web"] .tx-gold { color: hsl(var(--primary)); }
|
|
84
|
+
[data-tenant="acme-web"] .tx-stat { font-family: var(--font-family-display); font-weight: 800; font-size: 1.75rem; color: hsl(var(--primary)); }
|
|
85
|
+
[data-tenant="acme-web"] .tx-hero-grid { display: grid; gap: 3rem; align-items: center; padding-block: 6rem; }
|
|
86
|
+
@media (min-width: 1024px) { [data-tenant="acme-web"] .tx-hero-grid { grid-template-columns: 1.1fr 0.9fr; } }
|
|
87
|
+
[data-tenant="acme-web"] .tx-glow { position: absolute; inset: 0; pointer-events: none; }
|
|
88
|
+
[data-tenant="acme-web"] .tx-glow-tr { background: radial-gradient(40% 50% at 88% -10%, hsl(41 73% 53% / 0.22), transparent 70%); }
|
|
89
|
+
[data-tenant="acme-web"] .tx-glow-bl { background: radial-gradient(40% 50% at 12% 120%, hsl(41 73% 53% / 0.18), transparent 70%); }
|
|
90
|
+
[data-tenant="acme-web"] .tx-field { display: flex; align-items: center; gap: 0.75rem; padding: 0.75rem 1rem;
|
|
91
|
+
background: hsl(0 0% 100% / 0.08); border-radius: var(--radius-md); }
|
|
92
|
+
[data-tenant="acme-web"] .tx-quote-total { display: flex; align-items: center; justify-content: space-between;
|
|
93
|
+
padding: 0.875rem 1rem; background: hsl(var(--primary)); border-radius: var(--radius-md); }
|
|
94
|
+
[data-tenant="acme-web"] .tx-route-flag { height: 80px; display: flex; align-items: center; justify-content: center; background: hsl(217 49% 24%); }
|
|
95
|
+
[data-tenant="acme-web"] .tx-route-code { font-family: var(--font-family-display); font-weight: 800; font-size: 1.75rem; letter-spacing: 0.05em; color: hsl(var(--primary)); }
|
|
96
|
+
[data-tenant="acme-web"] .tx-footer-grid { display: grid; gap: 2.25rem; }
|
|
97
|
+
@media (min-width: 768px) { [data-tenant="acme-web"] .tx-footer-grid { grid-template-columns: 1.4fr 1fr 1fr 1fr; } }
|
|
98
|
+
[data-tenant="acme-web"] .tx-footer-bottom { display: flex; align-items: center; justify-content: space-between;
|
|
99
|
+
margin-top: 2.25rem; padding-top: 1.25rem; border-top: 1px solid hsl(0 0% 100% / 0.1); }
|
|
100
|
+
[data-tenant="acme-web"] .tx-medallion svg { width: 1.25rem; height: 1.25rem; }
|
|
101
|
+
[data-tenant="acme-web"] .tx-icon-18 { width: 1.125rem; height: 1.125rem; }
|
|
102
|
+
[data-tenant="acme-web"] .tx-icon-22 { width: 1.375rem; height: 1.375rem; }
|
|
103
|
+
/* Navy region: role scoping so descendants render on-dark (white text, glass cards, outline btns). */
|
|
104
|
+
[data-tenant="acme-web"] .tx-navy {
|
|
105
|
+
background: hsl(217 61% 12%); --foreground: 0 0% 100%;
|
|
106
|
+
--card: 217 45% 18%; --card-foreground: 0 0% 100%;
|
|
107
|
+
--card-background: hsl(0 0% 100% / 0.06); --card-border: 0 0% 100% / 0.12;
|
|
108
|
+
--muted-foreground: 214 36% 80%; --border: 214 30% 30%; --input: 214 24% 60%; --background: 217 61% 12%;
|
|
109
|
+
--text-brand: 41 80% 62%; /* light gold, eyebrows clear AA on the navy regions */
|
|
110
|
+
}
|
|
111
|
+
[data-tenant="acme-web"] .tx-navy-deep { background: hsl(217 61% 9%); }
|
|
112
|
+
`;
|
|
113
|
+
|
|
114
|
+
const SHELL = "tx-shell";
|
|
115
|
+
|
|
116
|
+
function Navbar() {
|
|
117
|
+
const links = ["Mua hộ", "Vận chuyển", "Bảng giá", "Tra cứu", "Về chúng tôi"];
|
|
118
|
+
return (
|
|
119
|
+
<header className="tx-navbar">
|
|
120
|
+
<div className={`${SHELL} tx-navbar-inner`}>
|
|
121
|
+
<span className="tx-brand" data-logotype="">
|
|
122
|
+
TIXI<span className="tx-gold">MAX</span>
|
|
123
|
+
</span>
|
|
124
|
+
<Flex direction="row" gap="xs" align="center" className="ms-2">
|
|
125
|
+
{links.map((l, i) => (
|
|
126
|
+
<Button key={l} variant="ghost" size="sm" aria-current={i === 0 ? "page" : undefined}>
|
|
127
|
+
{l}
|
|
128
|
+
</Button>
|
|
129
|
+
))}
|
|
130
|
+
</Flex>
|
|
131
|
+
<Flex direction="row" gap="sm" align="center" className="ms-auto">
|
|
132
|
+
<Button variant="ghost" size="sm">
|
|
133
|
+
Đăng nhập
|
|
134
|
+
</Button>
|
|
135
|
+
<Button size="sm">
|
|
136
|
+
<Plus aria-hidden="true" />
|
|
137
|
+
Tạo đơn mua hộ
|
|
138
|
+
</Button>
|
|
139
|
+
</Flex>
|
|
140
|
+
</div>
|
|
141
|
+
</header>
|
|
142
|
+
);
|
|
143
|
+
}
|
|
144
|
+
|
|
145
|
+
function Hero() {
|
|
146
|
+
const stats: Array<[string, string]> = [
|
|
147
|
+
["120K+", "Đơn đã giao"],
|
|
148
|
+
["6", "Quốc gia"],
|
|
149
|
+
["12–18", "Ngày vận chuyển"],
|
|
150
|
+
];
|
|
151
|
+
const fields: Array<[typeof Globe, string, string]> = [
|
|
152
|
+
[Globe, "Quốc gia", "Nhật Bản"],
|
|
153
|
+
[Scale, "Cân nặng (kg)", "3.5 kg"],
|
|
154
|
+
];
|
|
155
|
+
return (
|
|
156
|
+
<section className="tx-navy relative overflow-hidden">
|
|
157
|
+
<div className="tx-glow tx-glow-tr" />
|
|
158
|
+
<div className={`${SHELL} tx-hero-grid relative`}>
|
|
159
|
+
<div>
|
|
160
|
+
<div className="tx-eyebrow">Mua hộ & vận chuyển quốc tế</div>
|
|
161
|
+
<h1 className="tx-display">
|
|
162
|
+
Mua sắm toàn cầu,
|
|
163
|
+
<br />
|
|
164
|
+
<span className="tx-gold">ACME</span> lo phần còn lại.
|
|
165
|
+
</h1>
|
|
166
|
+
<p className="tx-lead">
|
|
167
|
+
Đặt mua, thanh toán và vận chuyển hàng từ Nhật, Hàn, Indonesia và Mỹ về tận nhà. Minh
|
|
168
|
+
bạch chi phí, theo dõi từng bước.
|
|
169
|
+
</p>
|
|
170
|
+
<Flex direction="row" gap="md" className="mt-6">
|
|
171
|
+
<Button size="lg">
|
|
172
|
+
Nhận báo giá miễn phí
|
|
173
|
+
<ArrowRight aria-hidden="true" />
|
|
174
|
+
</Button>
|
|
175
|
+
<Button variant="outline" size="lg">
|
|
176
|
+
<Search aria-hidden="true" />
|
|
177
|
+
Tra cứu đơn
|
|
178
|
+
</Button>
|
|
179
|
+
</Flex>
|
|
180
|
+
<Flex direction="row" gap="lg" className="mt-10">
|
|
181
|
+
{stats.map(([n, l]) => (
|
|
182
|
+
<div key={l}>
|
|
183
|
+
<div className="tx-stat">{n}</div>
|
|
184
|
+
<Text as="div" size="xs" tone="muted">
|
|
185
|
+
{l}
|
|
186
|
+
</Text>
|
|
187
|
+
</div>
|
|
188
|
+
))}
|
|
189
|
+
</Flex>
|
|
190
|
+
</div>
|
|
191
|
+
|
|
192
|
+
<Card>
|
|
193
|
+
<CardContent>
|
|
194
|
+
<div className="tx-eyebrow">Ước tính phí vận chuyển</div>
|
|
195
|
+
<Flex direction="col" gap="sm" className="mt-4">
|
|
196
|
+
{fields.map(([Icon, label, value]) => (
|
|
197
|
+
<div key={label} className="tx-field">
|
|
198
|
+
<Icon aria-hidden="true" className="tx-gold tx-icon-18" />
|
|
199
|
+
<div className="min-w-0 flex-1">
|
|
200
|
+
<Text as="div" size="2xs" tone="muted">
|
|
201
|
+
{label}
|
|
202
|
+
</Text>
|
|
203
|
+
<Text as="div" weight="bold">
|
|
204
|
+
{value}
|
|
205
|
+
</Text>
|
|
206
|
+
</div>
|
|
207
|
+
<ChevronDown aria-hidden="true" className="tx-icon-18" />
|
|
208
|
+
</div>
|
|
209
|
+
))}
|
|
210
|
+
<div className="tx-quote-total">
|
|
211
|
+
<Text as="span" weight="bold" className="text-primary-foreground">
|
|
212
|
+
Tạm tính
|
|
213
|
+
</Text>
|
|
214
|
+
<Text as="span" weight="bold" size="2xl" className="text-primary-foreground">
|
|
215
|
+
525.000đ
|
|
216
|
+
</Text>
|
|
217
|
+
</div>
|
|
218
|
+
</Flex>
|
|
219
|
+
</CardContent>
|
|
220
|
+
</Card>
|
|
221
|
+
</div>
|
|
222
|
+
</section>
|
|
223
|
+
);
|
|
224
|
+
}
|
|
225
|
+
|
|
226
|
+
function SectionHead({
|
|
227
|
+
eyebrow,
|
|
228
|
+
title,
|
|
229
|
+
sub,
|
|
230
|
+
center,
|
|
231
|
+
}: {
|
|
232
|
+
eyebrow: string;
|
|
233
|
+
title: string;
|
|
234
|
+
sub?: string;
|
|
235
|
+
center?: boolean;
|
|
236
|
+
}) {
|
|
237
|
+
return (
|
|
238
|
+
<div className={center ? "mx-auto mb-10 text-center" : "mb-8"}>
|
|
239
|
+
<div className="tx-eyebrow">{eyebrow}</div>
|
|
240
|
+
<h2 className="tx-h2">{title}</h2>
|
|
241
|
+
{sub ? <p className="tx-lead mx-auto">{sub}</p> : null}
|
|
242
|
+
</div>
|
|
243
|
+
);
|
|
244
|
+
}
|
|
245
|
+
|
|
246
|
+
function Medallion({ icon: Icon }: { icon: typeof Globe }) {
|
|
247
|
+
return (
|
|
248
|
+
<Avatar className="rounded-md">
|
|
249
|
+
<AvatarFallback className="bg-primary/10 text-primary tx-medallion rounded-md">
|
|
250
|
+
<Icon aria-hidden="true" />
|
|
251
|
+
</AvatarFallback>
|
|
252
|
+
</Avatar>
|
|
253
|
+
);
|
|
254
|
+
}
|
|
255
|
+
|
|
256
|
+
function Services() {
|
|
257
|
+
const items: Array<[typeof Globe, string, string]> = [
|
|
258
|
+
[
|
|
259
|
+
ShoppingCart,
|
|
260
|
+
"Mua hộ",
|
|
261
|
+
"Gửi link sản phẩm, ACME đặt mua và thanh toán giúp bạn với tỷ giá minh bạch.",
|
|
262
|
+
],
|
|
263
|
+
[Ship, "Vận chuyển", "Đường biển và đường bay từ Nhật, Hàn, Indonesia, Mỹ về Việt Nam."],
|
|
264
|
+
[Warehouse, "Gom hàng", "Gom nhiều đơn vào một kiện để tiết kiệm tối đa chi phí vận chuyển."],
|
|
265
|
+
[
|
|
266
|
+
ShieldCheck,
|
|
267
|
+
"Bảo hiểm hàng hóa",
|
|
268
|
+
"Bảo vệ giá trị đơn hàng trong suốt quá trình vận chuyển quốc tế.",
|
|
269
|
+
],
|
|
270
|
+
];
|
|
271
|
+
return (
|
|
272
|
+
<section className="bg-card tx-section">
|
|
273
|
+
<div className={SHELL}>
|
|
274
|
+
<SectionHead
|
|
275
|
+
center
|
|
276
|
+
eyebrow="Dịch vụ"
|
|
277
|
+
title="Một điểm chạm, trọn quy trình"
|
|
278
|
+
sub="Từ lúc bạn thấy món hàng ở nước ngoài đến khi nó nằm trong tay bạn."
|
|
279
|
+
/>
|
|
280
|
+
<ResponsiveGrid columns={{ sm: 1, md: 2, lg: 4 }}>
|
|
281
|
+
{items.map(([icon, t, d]) => (
|
|
282
|
+
<Card key={t}>
|
|
283
|
+
<CardContent>
|
|
284
|
+
<Medallion icon={icon} />
|
|
285
|
+
<Text as="div" weight="bold" size="lg" className="mt-4">
|
|
286
|
+
{t}
|
|
287
|
+
</Text>
|
|
288
|
+
<Text as="p" size="sm" tone="muted" className="mt-1">
|
|
289
|
+
{d}
|
|
290
|
+
</Text>
|
|
291
|
+
</CardContent>
|
|
292
|
+
</Card>
|
|
293
|
+
))}
|
|
294
|
+
</ResponsiveGrid>
|
|
295
|
+
</div>
|
|
296
|
+
</section>
|
|
297
|
+
);
|
|
298
|
+
}
|
|
299
|
+
|
|
300
|
+
function Steps() {
|
|
301
|
+
const steps: Array<[typeof Globe, string, string]> = [
|
|
302
|
+
[Link2, "Gửi link sản phẩm", "Dán đường link món hàng bạn muốn mua từ bất kỳ trang nào."],
|
|
303
|
+
[Receipt, "Nhận báo giá", "ACME báo giá tiền hàng và phí vận chuyển trong vài phút."],
|
|
304
|
+
[CreditCard, "Thanh toán", "Đặt cọc hoặc thanh toán toàn bộ, chúng tôi đặt mua ngay."],
|
|
305
|
+
[PackageCheck, "Nhận hàng tận nơi", "Theo dõi đơn theo thời gian thực đến khi giao tận nhà."],
|
|
306
|
+
];
|
|
307
|
+
return (
|
|
308
|
+
<section className="bg-background tx-section">
|
|
309
|
+
<div className={SHELL}>
|
|
310
|
+
<SectionHead eyebrow="Quy trình" title="Mua hàng quốc tế trong 4 bước" />
|
|
311
|
+
<ResponsiveGrid columns={{ sm: 1, md: 2, lg: 4 }}>
|
|
312
|
+
{steps.map(([Icon, t, d], i) => (
|
|
313
|
+
<div key={t}>
|
|
314
|
+
<Flex direction="row" gap="sm" align="center" className="mb-3">
|
|
315
|
+
<Avatar>
|
|
316
|
+
<AvatarFallback className="bg-secondary text-primary font-bold">
|
|
317
|
+
{i + 1}
|
|
318
|
+
</AvatarFallback>
|
|
319
|
+
</Avatar>
|
|
320
|
+
<Icon aria-hidden="true" className="text-brand tx-icon-22" />
|
|
321
|
+
</Flex>
|
|
322
|
+
<Text as="div" weight="bold" size="lg">
|
|
323
|
+
{t}
|
|
324
|
+
</Text>
|
|
325
|
+
<Text as="p" size="sm" tone="muted" className="mt-1">
|
|
326
|
+
{d}
|
|
327
|
+
</Text>
|
|
328
|
+
</div>
|
|
329
|
+
))}
|
|
330
|
+
</ResponsiveGrid>
|
|
331
|
+
</div>
|
|
332
|
+
</section>
|
|
333
|
+
);
|
|
334
|
+
}
|
|
335
|
+
|
|
336
|
+
function Routes() {
|
|
337
|
+
const routes: Array<[string, string, string, string]> = [
|
|
338
|
+
["Nhật Bản", "JP", "Đường bay · 5–7 ngày", "210.000đ/kg"],
|
|
339
|
+
["Hàn Quốc", "KR", "Đường bay · 4–6 ngày", "180.000đ/kg"],
|
|
340
|
+
["Indonesia", "ID", "Đường biển · 12–18 ngày", "38.000đ/kg"],
|
|
341
|
+
["Hoa Kỳ", "US", "Đường bay · 7–10 ngày", "260.000đ/kg"],
|
|
342
|
+
];
|
|
343
|
+
return (
|
|
344
|
+
<section className="bg-card tx-section">
|
|
345
|
+
<div className={SHELL}>
|
|
346
|
+
<SectionHead eyebrow="Tuyến vận chuyển" title="Giá cước rõ ràng theo từng tuyến" />
|
|
347
|
+
<ResponsiveGrid columns={{ sm: 1, md: 2, lg: 4 }}>
|
|
348
|
+
{routes.map(([c, code, mode, price]) => (
|
|
349
|
+
<Card key={c} className="overflow-hidden">
|
|
350
|
+
<CardCover className="tx-route-flag">
|
|
351
|
+
<span className="tx-route-code">{code}</span>
|
|
352
|
+
</CardCover>
|
|
353
|
+
<CardContent>
|
|
354
|
+
<Text as="div" weight="bold" size="lg">
|
|
355
|
+
{c}
|
|
356
|
+
</Text>
|
|
357
|
+
<Text as="div" size="xs" tone="muted" className="mt-1 mb-3">
|
|
358
|
+
{mode}
|
|
359
|
+
</Text>
|
|
360
|
+
<Text as="div" weight="bold" size="2xl">
|
|
361
|
+
{price}
|
|
362
|
+
</Text>
|
|
363
|
+
</CardContent>
|
|
364
|
+
</Card>
|
|
365
|
+
))}
|
|
366
|
+
</ResponsiveGrid>
|
|
367
|
+
</div>
|
|
368
|
+
</section>
|
|
369
|
+
);
|
|
370
|
+
}
|
|
371
|
+
|
|
372
|
+
function CtaBanner() {
|
|
373
|
+
return (
|
|
374
|
+
<section className="tx-navy tx-section relative overflow-hidden">
|
|
375
|
+
<div className="tx-glow tx-glow-bl" />
|
|
376
|
+
<div className={`${SHELL} relative text-center`}>
|
|
377
|
+
<h2 className="tx-h2">Sẵn sàng cho đơn hàng đầu tiên?</h2>
|
|
378
|
+
<p className="tx-lead mx-auto">Tạo tài khoản miễn phí và nhận báo giá trong 5 phút.</p>
|
|
379
|
+
<Flex direction="row" gap="md" className="mt-6 justify-center">
|
|
380
|
+
<Button size="lg">
|
|
381
|
+
<UserPlus aria-hidden="true" />
|
|
382
|
+
Đăng ký ngay
|
|
383
|
+
</Button>
|
|
384
|
+
<Button variant="outline" size="lg">
|
|
385
|
+
Liên hệ tư vấn
|
|
386
|
+
</Button>
|
|
387
|
+
</Flex>
|
|
388
|
+
</div>
|
|
389
|
+
</section>
|
|
390
|
+
);
|
|
391
|
+
}
|
|
392
|
+
|
|
393
|
+
function Footer() {
|
|
394
|
+
const cols: Array<[string, string[]]> = [
|
|
395
|
+
["Dịch vụ", ["Mua hộ", "Vận chuyển", "Gom hàng", "Bảng giá"]],
|
|
396
|
+
["Công ty", ["Về ACME", "Tuyển dụng", "Tin tức", "Liên hệ"]],
|
|
397
|
+
["Hỗ trợ", ["Tra cứu đơn", "Câu hỏi thường gặp", "Chính sách", "Điều khoản"]],
|
|
398
|
+
];
|
|
399
|
+
return (
|
|
400
|
+
<footer className="tx-navy tx-navy-deep">
|
|
401
|
+
<div className={`${SHELL} tx-footer-grid`} style={{ paddingBlock: "3.5rem 2rem" }}>
|
|
402
|
+
<div>
|
|
403
|
+
<span className="tx-brand">
|
|
404
|
+
TIXI<span className="tx-gold">MAX</span>
|
|
405
|
+
</span>
|
|
406
|
+
<Text as="p" size="sm" tone="muted" className="mt-4">
|
|
407
|
+
Dịch vụ mua hộ & vận chuyển quốc tế uy tín, minh bạch về tận nhà bạn.
|
|
408
|
+
</Text>
|
|
409
|
+
</div>
|
|
410
|
+
{cols.map(([h, items]) => (
|
|
411
|
+
<div key={h}>
|
|
412
|
+
<div className="tx-eyebrow">{h}</div>
|
|
413
|
+
<Flex direction="col" gap="xs" className="mt-3">
|
|
414
|
+
{items.map((i) => (
|
|
415
|
+
<Button
|
|
416
|
+
key={i}
|
|
417
|
+
variant="link"
|
|
418
|
+
size="sm"
|
|
419
|
+
className="text-muted-foreground justify-start"
|
|
420
|
+
>
|
|
421
|
+
{i}
|
|
422
|
+
</Button>
|
|
423
|
+
))}
|
|
424
|
+
</Flex>
|
|
425
|
+
</div>
|
|
426
|
+
))}
|
|
427
|
+
</div>
|
|
428
|
+
<div className={`${SHELL} tx-footer-bottom`}>
|
|
429
|
+
<Text as="span" size="xs" tone="muted">
|
|
430
|
+
2026 ACME Logistics. All rights reserved.
|
|
431
|
+
</Text>
|
|
432
|
+
<Flex direction="row" gap="md">
|
|
433
|
+
{[Mail, Phone, Globe].map((Icon, i) => (
|
|
434
|
+
<Icon key={i} aria-hidden="true" className="text-muted-foreground tx-icon-18" />
|
|
435
|
+
))}
|
|
436
|
+
</Flex>
|
|
437
|
+
</div>
|
|
438
|
+
</footer>
|
|
439
|
+
);
|
|
440
|
+
}
|
|
441
|
+
|
|
442
|
+
export default function AcmeWebsiteShowcase() {
|
|
443
|
+
return (
|
|
444
|
+
<div data-tenant="acme-web" className="bg-background min-h-screen">
|
|
445
|
+
<style>{THEME}</style>
|
|
446
|
+
<Navbar />
|
|
447
|
+
<Hero />
|
|
448
|
+
<Services />
|
|
449
|
+
<Steps />
|
|
450
|
+
<Routes />
|
|
451
|
+
<CtaBanner />
|
|
452
|
+
<Footer />
|
|
453
|
+
</div>
|
|
454
|
+
);
|
|
455
|
+
}
|