@godxjp/ui 28.8.0 → 28.10.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/agent/START-HERE.md +193 -0
- package/agent/anti-ai-tells.json +158 -0
- package/agent/components/Accordion.json +60 -0
- package/agent/components/AccountChip.json +59 -0
- package/agent/components/Actions.json +78 -0
- package/agent/components/Activity.json +80 -0
- package/agent/components/Affix.json +78 -0
- package/agent/components/Alert.json +65 -0
- package/agent/components/AlertDialog.json +109 -0
- package/agent/components/AlertDialogRoot.json +52 -0
- package/agent/components/Anchor.json +119 -0
- package/agent/components/AppLauncher.json +95 -0
- package/agent/components/AppProvider.json +105 -0
- package/agent/components/AppSettingPicker.json +88 -0
- package/agent/components/AppSettingToggle.json +70 -0
- package/agent/components/AppShell.json +159 -0
- package/agent/components/AreaChart.json +105 -0
- package/agent/components/AspectRatio.json +38 -0
- package/agent/components/Attachments.json +76 -0
- package/agent/components/AuthAccountSummary.json +64 -0
- package/agent/components/AuthDivider.json +35 -0
- package/agent/components/AuthFooter.json +48 -0
- package/agent/components/AuthIdentity.json +42 -0
- package/agent/components/AuthShell.json +108 -0
- package/agent/components/AuthStack.json +21 -0
- package/agent/components/Avatar.json +89 -0
- package/agent/components/Badge.json +96 -0
- package/agent/components/Banner.json +48 -0
- package/agent/components/BarChart.json +108 -0
- package/agent/components/BranchScopePicker.json +89 -0
- package/agent/components/Breadcrumb.json +54 -0
- package/agent/components/Button.json +133 -0
- package/agent/components/Calendar.json +259 -0
- package/agent/components/Callout.json +46 -0
- package/agent/components/Card.json +112 -0
- package/agent/components/CardBar.json +49 -0
- package/agent/components/CardContent.json +51 -0
- package/agent/components/Carousel.json +50 -0
- package/agent/components/Cascader.json +209 -0
- package/agent/components/CenteredShell.json +66 -0
- package/agent/components/ChatBubble.json +100 -0
- package/agent/components/ChatBubbleList.json +64 -0
- package/agent/components/ChatComposer.json +160 -0
- package/agent/components/ChatSuggestion.json +86 -0
- package/agent/components/Checkbox.json +68 -0
- package/agent/components/CheckboxGroup.json +96 -0
- package/agent/components/CodeBlock.json +64 -0
- package/agent/components/Collapsible.json +74 -0
- package/agent/components/ColorPicker.json +87 -0
- package/agent/components/Command.json +168 -0
- package/agent/components/CommandPalette.json +84 -0
- package/agent/components/CompactBarTrend.json +101 -0
- package/agent/components/Conversations.json +82 -0
- package/agent/components/CredentialReveal.json +93 -0
- package/agent/components/DataState.json +79 -0
- package/agent/components/DataTable.json +268 -0
- package/agent/components/DatePicker.json +275 -0
- package/agent/components/Descriptions.json +67 -0
- package/agent/components/Dialog.json +78 -0
- package/agent/components/DraggablePanel.json +106 -0
- package/agent/components/DropdownMenu.json +102 -0
- package/agent/components/EmptyState.json +83 -0
- package/agent/components/ErrorSurface.json +128 -0
- package/agent/components/FeatureList.json +43 -0
- package/agent/components/Field.json +64 -0
- package/agent/components/FilterBar.json +99 -0
- package/agent/components/Flex.json +153 -0
- package/agent/components/FloatButton.json +91 -0
- package/agent/components/Form.json +87 -0
- package/agent/components/FormErrors.json +51 -0
- package/agent/components/FormField.json +137 -0
- package/agent/components/FormFieldArray.json +39 -0
- package/agent/components/FormFieldControl.json +129 -0
- package/agent/components/FormRoot.json +122 -0
- package/agent/components/Heading.json +61 -0
- package/agent/components/HoverCard.json +55 -0
- package/agent/components/Icon.json +60 -0
- package/agent/components/InfiniteQueryState.json +58 -0
- package/agent/components/Input.json +122 -0
- package/agent/components/InputOTP.json +106 -0
- package/agent/components/Label.json +43 -0
- package/agent/components/LegalDocumentShell.json +102 -0
- package/agent/components/Legend.json +42 -0
- package/agent/components/LineChart.json +103 -0
- package/agent/components/Link.json +41 -0
- package/agent/components/ListRow.json +92 -0
- package/agent/components/Logo.json +85 -0
- package/agent/components/Marquee.json +91 -0
- package/agent/components/Masonry.json +82 -0
- package/agent/components/MasterDetail.json +95 -0
- package/agent/components/MegaMenu.json +120 -0
- package/agent/components/MobileShell.json +73 -0
- package/agent/components/NavList.json +63 -0
- package/agent/components/NumberInput.json +158 -0
- package/agent/components/OrgSwitcher.json +89 -0
- package/agent/components/OverlayPortalProvider.json +42 -0
- package/agent/components/PageContainer.json +181 -0
- package/agent/components/Pagination.json +132 -0
- package/agent/components/Paragraph.json +40 -0
- package/agent/components/PasswordInput.json +79 -0
- package/agent/components/PasswordStrength.json +51 -0
- package/agent/components/PermissionMatrix.json +81 -0
- package/agent/components/PieChart.json +99 -0
- package/agent/components/Popover.json +110 -0
- package/agent/components/PrefetchLink.json +65 -0
- package/agent/components/Progress.json +79 -0
- package/agent/components/Prose.json +57 -0
- package/agent/components/QrCode.json +62 -0
- package/agent/components/Radio.json +98 -0
- package/agent/components/RadioGroup.json +91 -0
- package/agent/components/RangeTimeline.json +80 -0
- package/agent/components/Rating.json +92 -0
- package/agent/components/ResizablePanel.json +69 -0
- package/agent/components/ResponsiveGrid.json +77 -0
- package/agent/components/Reveal.json +70 -0
- package/agent/components/ScrollArea.json +104 -0
- package/agent/components/SearchInput.json +98 -0
- package/agent/components/Segmented.json +96 -0
- package/agent/components/Select.json +397 -0
- package/agent/components/Separator.json +86 -0
- package/agent/components/ServiceCatalogCta.json +46 -0
- package/agent/components/ServiceLauncherCard.json +86 -0
- package/agent/components/ServiceRolePanel.json +83 -0
- package/agent/components/Sheet.json +85 -0
- package/agent/components/Sidebar.json +118 -0
- package/agent/components/Skeleton.json +57 -0
- package/agent/components/SkeletonArticle.json +71 -0
- package/agent/components/SkeletonAvatar.json +50 -0
- package/agent/components/SkeletonButton.json +57 -0
- package/agent/components/SkeletonForm.json +52 -0
- package/agent/components/SkeletonImage.json +37 -0
- package/agent/components/SkeletonInput.json +51 -0
- package/agent/components/SkeletonNode.json +42 -0
- package/agent/components/SkeletonRows.json +49 -0
- package/agent/components/SkeletonTable.json +45 -0
- package/agent/components/Slider.json +160 -0
- package/agent/components/SplitPane.json +66 -0
- package/agent/components/StatCard.json +83 -0
- package/agent/components/Steps.json +95 -0
- package/agent/components/Swatch.json +41 -0
- package/agent/components/Switch.json +81 -0
- package/agent/components/Table.json +112 -0
- package/agent/components/Tabs.json +158 -0
- package/agent/components/TagInput.json +105 -0
- package/agent/components/Text.json +201 -0
- package/agent/components/Textarea.json +126 -0
- package/agent/components/ThoughtChain.json +76 -0
- package/agent/components/Thumbnail.json +70 -0
- package/agent/components/TimePicker.json +200 -0
- package/agent/components/TimeRangePicker.json +90 -0
- package/agent/components/Timeline.json +47 -0
- package/agent/components/TimelineGrid.json +92 -0
- package/agent/components/Title.json +67 -0
- package/agent/components/Toaster.json +42 -0
- package/agent/components/Toggle.json +90 -0
- package/agent/components/ToggleGroup.json +102 -0
- package/agent/components/Toolbar.json +120 -0
- package/agent/components/Tooltip.json +110 -0
- package/agent/components/Topbar.json +83 -0
- package/agent/components/TopbarItem.json +79 -0
- package/agent/components/Transfer.json +141 -0
- package/agent/components/Tree.json +185 -0
- package/agent/components/TreeSelect.json +232 -0
- package/agent/components/TwoFactorSetup.json +79 -0
- package/agent/components/Typography.json +42 -0
- package/agent/components/Upload.json +221 -0
- package/agent/components/UploadCropDialog.json +60 -0
- package/agent/components/VisuallyHidden.json +20 -0
- package/agent/components/Welcome.json +65 -0
- package/agent/components/formatDate.json +46 -0
- package/agent/components/inertiaUpload.json +32 -0
- package/agent/components/useZodForm.json +39 -0
- package/agent/components-index.json +884 -0
- package/agent/components.json +15507 -0
- package/agent/index.json +56 -0
- package/agent/llms.txt +32 -0
- package/agent/patterns/account-recovery-settings.json +19 -0
- package/agent/patterns/async-data-state.json +20 -0
- package/agent/patterns/auth-recovery-panels.json +29 -0
- package/agent/patterns/badge-coloring.json +14 -0
- package/agent/patterns/common-fixes.json +16 -0
- package/agent/patterns/confirm-destructive.json +11 -0
- package/agent/patterns/data-table-page.json +18 -0
- package/agent/patterns/deferred-loading.json +12 -0
- package/agent/patterns/error-pages.json +28 -0
- package/agent/patterns/inertia-detail-page.json +13 -0
- package/agent/patterns/inertia-list-page.json +15 -0
- package/agent/patterns/inertia-persistent-layout.json +14 -0
- package/agent/patterns/organization-memberships.json +19 -0
- package/agent/patterns/page-sections.json +18 -0
- package/agent/patterns/settings-page-responsive.json +18 -0
- package/agent/patterns/settings-section-rows.json +23 -0
- package/agent/patterns/signup-form.json +13 -0
- package/agent/patterns/topbar-account-chip.json +18 -0
- package/agent/patterns/transactional-email.json +22 -0
- package/agent/patterns-index.json +323 -0
- package/agent/patterns.json +342 -0
- package/agent/rules.json +237 -0
- package/agent/tokens.json +8422 -0
- package/agent/vocabulary.json +198 -0
- package/dist/components/data-entry/input.js +8 -1
- package/dist/components/layout/flex.d.ts +2 -2
- package/dist/components/layout/flex.js +2 -0
- package/dist/components/ui/tag-input.d.ts +10 -0
- package/dist/components/ui/tag-input.js +35 -2
- package/dist/contracts/measurement.json +1 -1
- package/dist/i18n/messages/en.json +23 -1
- package/dist/i18n/messages/ja.json +21 -1
- package/dist/i18n/messages/vi.json +21 -1
- package/dist/lib/variants.js +4 -1
- package/dist/props/components/data-entry.prop.d.ts +21 -2
- package/dist/props/components/layout.prop.d.ts +42 -0
- package/dist/props/registry.d.ts +9 -0
- package/dist/props/registry.js +6 -0
- package/dist/props/vocabulary/layout.prop.d.ts +1 -1
- package/dist/styles/base.css +47 -14
- package/dist/styles/card-layout.css +6 -6
- package/dist/styles/chart-layout.css +6 -6
- package/dist/styles/control.css +41 -6
- package/dist/styles/data-display-layout.css +21 -6
- package/dist/styles/density.css +2 -0
- package/dist/styles/dialog-layout.css +4 -1
- package/dist/styles/focus-ring.css +4 -1
- package/dist/styles/layout.css +30 -3
- package/dist/styles/navigation-layout.css +3 -1
- package/dist/styles/shell-layout.css +27 -21
- package/dist/styles/table-layout.css +50 -9
- package/dist/styles/text-layout.css +94 -23
- package/dist/tokens/components/activity.css +13 -4
- package/dist/tokens/components/attachments.css +1 -1
- package/dist/tokens/components/badge.css +1 -1
- package/dist/tokens/components/card.css +28 -7
- package/dist/tokens/components/chart.css +4 -1
- package/dist/tokens/components/chat-composer.css +4 -1
- package/dist/tokens/components/control.css +69 -30
- package/dist/tokens/components/conversations.css +4 -1
- package/dist/tokens/components/data-display.css +42 -15
- package/dist/tokens/components/data-entry.css +8 -2
- package/dist/tokens/components/descriptions.css +1 -1
- package/dist/tokens/components/feedback.css +8 -5
- package/dist/tokens/components/float-button.css +8 -2
- package/dist/tokens/components/legal-document.css +12 -3
- package/dist/tokens/components/logo.css +15 -6
- package/dist/tokens/components/mega-menu.css +14 -5
- package/dist/tokens/components/navigation.css +37 -13
- package/dist/tokens/components/segmented.css +9 -2
- package/dist/tokens/components/separator.css +4 -1
- package/dist/tokens/components/shell.css +96 -31
- package/dist/tokens/components/table.css +13 -6
- package/dist/tokens/components/thought-chain.css +4 -1
- package/dist/tokens/components/toggle.css +4 -1
- package/dist/tokens/components/tree.css +1 -1
- package/dist/tokens/components/upload.css +21 -9
- package/dist/tokens/foundation.css +24 -30
- package/dist/tokens/semantic/layout.css +19 -5
- package/docs/COMPOSITION-VS-COMPONENT.md +41 -0
- package/docs/DESIGN-AUTHORITY.md +14 -0
- package/docs/DEVELOPMENT.md +81 -6
- package/docs/TOKENS.md +16 -1
- package/docs/data-entry/tag-input.tsx +37 -0
- package/docs/layout/flex.tsx +40 -0
- package/docs/roadmap/website-components.md +34 -0
- package/docs/showcase/case4-login.tsx +10 -2
- package/docs/showcase/case5-shift-calendar.tsx +1 -1
- package/docs/showcase/case6-agency-handy.tsx +6 -6
- package/docs/showcase/futurelastic-web.tsx +7 -9
- package/docs/showcase/marketing-page.tsx +61 -52
- package/docs/showcase/table-expandable-rows.tsx +4 -1
- package/docs/showcase/table-pagination.tsx +88 -18
- package/docs/showcase/theme-customization.tsx +25 -2
- package/package.json +8 -5
|
@@ -6,7 +6,8 @@
|
|
|
6
6
|
--table-row-height-comfortable: var(--band-height-xl);
|
|
7
7
|
--table-row-height: calc(var(--table-row-height-default) * var(--scaling));
|
|
8
8
|
--table-cell-padding-y: var(--space-2);
|
|
9
|
-
|
|
9
|
+
|
|
10
|
+
--table-cell-space-x: initial;
|
|
10
11
|
|
|
11
12
|
--table-cell-indent-space-step: var(--space-4);
|
|
12
13
|
|
|
@@ -15,7 +16,7 @@
|
|
|
15
16
|
--table-pagination-padding-x: initial;
|
|
16
17
|
|
|
17
18
|
--table-surface-min-inline-size: 640px;
|
|
18
|
-
--table-head-font-size: var(--font-size-xs);
|
|
19
|
+
--table-head-font-size: var(--font-size-xs, calc(var(--font-size-base) / var(--font-size-ratio)));
|
|
19
20
|
|
|
20
21
|
--table-head-font-weight: var(--font-weight-medium);
|
|
21
22
|
|
|
@@ -59,7 +60,10 @@
|
|
|
59
60
|
--table-action-collection-meta-width-floor: 5rem;
|
|
60
61
|
|
|
61
62
|
--table-action-collection-flex-width-floor: 5rem;
|
|
62
|
-
--table-action-collection-font-size-compact: var(
|
|
63
|
+
--table-action-collection-font-size-compact: var(
|
|
64
|
+
--font-size-xs,
|
|
65
|
+
calc(var(--font-size-base) / var(--font-size-ratio))
|
|
66
|
+
);
|
|
63
67
|
--table-action-collection-cell-space-x-compact: var(--space-2);
|
|
64
68
|
--table-action-collection-cell-padding-y-compact: var(--space-2);
|
|
65
69
|
--table-action-collection-row-height-compact: var(--table-row-height-compact);
|
|
@@ -72,13 +76,16 @@
|
|
|
72
76
|
--table-stacked-collection-card-padding-x: var(--space-inline-md);
|
|
73
77
|
--table-stacked-collection-card-gap: var(--space-stack-sm);
|
|
74
78
|
--table-stacked-collection-cell-padding-y: var(--space-stack-xs);
|
|
75
|
-
--table-stacked-collection-label-font-size: var(
|
|
79
|
+
--table-stacked-collection-label-font-size: var(
|
|
80
|
+
--font-size-xs,
|
|
81
|
+
calc(var(--font-size-base) / var(--font-size-ratio))
|
|
82
|
+
);
|
|
76
83
|
|
|
77
84
|
--table-select-column-width: 2.5rem;
|
|
78
85
|
--table-sort-icon-size: var(--icon-size-xs);
|
|
79
86
|
--table-toolbar-icon-size: var(--icon-size-md);
|
|
80
87
|
--table-pagination-icon-size: var(--icon-size-md);
|
|
81
|
-
--table-pagination-font-size: var(--font-size-sm);
|
|
88
|
+
--table-pagination-font-size: var(--font-size-sm, var(--font-size-base));
|
|
82
89
|
|
|
83
90
|
--table-skeleton-check-size: 1rem;
|
|
84
91
|
|
|
@@ -86,7 +93,7 @@
|
|
|
86
93
|
--table-skeleton-line-height: var(--table-skeleton-line-block-size);
|
|
87
94
|
--table-skeleton-radius: var(--radius-sm);
|
|
88
95
|
|
|
89
|
-
--table-font-size: var(--font-size-sm);
|
|
96
|
+
--table-font-size: var(--font-size-sm, var(--font-size-base));
|
|
90
97
|
|
|
91
98
|
--table-line-height: calc(1.25 / 0.875);
|
|
92
99
|
|
|
@@ -7,7 +7,10 @@
|
|
|
7
7
|
--thought-chain-body-gap: var(--space-1);
|
|
8
8
|
|
|
9
9
|
--thought-chain-icon-size: var(--band-height-sm);
|
|
10
|
-
--thought-chain-icon-font-size: var(
|
|
10
|
+
--thought-chain-icon-font-size: var(
|
|
11
|
+
--font-size-xs,
|
|
12
|
+
calc(var(--font-size-base) / var(--font-size-ratio))
|
|
13
|
+
);
|
|
11
14
|
--thought-chain-icon-radius: var(--radius-pill);
|
|
12
15
|
|
|
13
16
|
--thought-chain-icon-background: initial;
|
|
@@ -3,7 +3,10 @@
|
|
|
3
3
|
|
|
4
4
|
--toggle-count-min-width: var(--space-4);
|
|
5
5
|
--toggle-count-space-inline: var(--space-1);
|
|
6
|
-
--toggle-count-font-size: var(
|
|
6
|
+
--toggle-count-font-size: var(
|
|
7
|
+
--font-size-xs,
|
|
8
|
+
calc(var(--font-size-base) / var(--font-size-ratio))
|
|
9
|
+
);
|
|
7
10
|
--toggle-count-radius: var(--radius-pill);
|
|
8
11
|
|
|
9
12
|
--toggle-count-gap: 0;
|
|
@@ -9,7 +9,7 @@
|
|
|
9
9
|
--tree-node-padding-inline: var(--space-2);
|
|
10
10
|
--tree-node-gap: var(--space-2);
|
|
11
11
|
--tree-node-radius: var(--radius-sm);
|
|
12
|
-
--tree-node-font-size: var(--font-size-sm);
|
|
12
|
+
--tree-node-font-size: var(--font-size-sm, var(--font-size-base));
|
|
13
13
|
|
|
14
14
|
--tree-switcher-size: 1.25rem;
|
|
15
15
|
|
|
@@ -7,17 +7,26 @@
|
|
|
7
7
|
--upload-dropzone-border-width: var(--stroke-md);
|
|
8
8
|
--upload-dropzone-icon-size: var(--icon-size-3xl);
|
|
9
9
|
--upload-dropzone-hint-space-block-start: var(--space-3);
|
|
10
|
-
--upload-dropzone-hint-font-size: var(--font-size-sm);
|
|
10
|
+
--upload-dropzone-hint-font-size: var(--font-size-sm, var(--font-size-base));
|
|
11
11
|
--upload-dropzone-meta-space-block-start: var(--space-1);
|
|
12
|
-
--upload-dropzone-meta-font-size: var(
|
|
12
|
+
--upload-dropzone-meta-font-size: var(
|
|
13
|
+
--font-size-xs,
|
|
14
|
+
calc(var(--font-size-base) / var(--font-size-ratio))
|
|
15
|
+
);
|
|
13
16
|
|
|
14
17
|
--upload-tile-size: 6rem;
|
|
15
18
|
--upload-tile-radius: var(--radius-md);
|
|
16
19
|
--upload-tile-space-gap: var(--space-3);
|
|
17
20
|
--upload-tile-icon-size: var(--icon-size-xl);
|
|
18
21
|
--upload-tile-label-space-block-start: var(--space-1);
|
|
19
|
-
--upload-tile-label-font-size: var(
|
|
20
|
-
|
|
22
|
+
--upload-tile-label-font-size: var(
|
|
23
|
+
--font-size-xs,
|
|
24
|
+
calc(var(--font-size-base) / var(--font-size-ratio))
|
|
25
|
+
);
|
|
26
|
+
--upload-tile-overlay-font-size: var(
|
|
27
|
+
--font-size-xs,
|
|
28
|
+
calc(var(--font-size-base) / var(--font-size-ratio))
|
|
29
|
+
);
|
|
21
30
|
|
|
22
31
|
--upload-overlay-background: initial;
|
|
23
32
|
--upload-overlay-alpha: 70%;
|
|
@@ -33,14 +42,17 @@
|
|
|
33
42
|
|
|
34
43
|
--upload-picture-icon-size: var(--icon-size-2xl);
|
|
35
44
|
--upload-picture-empty-label-space-block-start: var(--space-2);
|
|
36
|
-
--upload-picture-empty-label-font-size: var(--font-size-sm);
|
|
37
|
-
--upload-picture-overlay-font-size: var(--font-size-sm);
|
|
45
|
+
--upload-picture-empty-label-font-size: var(--font-size-sm, var(--font-size-base));
|
|
46
|
+
--upload-picture-overlay-font-size: var(--font-size-sm, var(--font-size-base));
|
|
38
47
|
|
|
39
48
|
--upload-picture-badge-radius: var(--radius-md);
|
|
40
49
|
--upload-picture-badge-offset: var(--space-2);
|
|
41
50
|
--upload-picture-badge-space-inline: var(--space-2);
|
|
42
51
|
--upload-picture-badge-space-block: 0.125rem;
|
|
43
|
-
--upload-picture-badge-font-size: var(
|
|
52
|
+
--upload-picture-badge-font-size: var(
|
|
53
|
+
--font-size-xs,
|
|
54
|
+
calc(var(--font-size-base) / var(--font-size-ratio))
|
|
55
|
+
);
|
|
44
56
|
|
|
45
57
|
--upload-avatar-size: 6rem;
|
|
46
58
|
|
|
@@ -57,14 +69,14 @@
|
|
|
57
69
|
--upload-draft-space-block: var(--space-2);
|
|
58
70
|
--upload-draft-space-gap: var(--space-2);
|
|
59
71
|
--upload-draft-radius: var(--radius-md);
|
|
60
|
-
--upload-draft-font-size: var(--font-size-sm);
|
|
72
|
+
--upload-draft-font-size: var(--font-size-sm, var(--font-size-base));
|
|
61
73
|
--upload-draft-icon-size: var(--icon-size-sm);
|
|
62
74
|
|
|
63
75
|
--upload-row-space-inline: var(--space-3);
|
|
64
76
|
--upload-row-space-block: var(--space-2);
|
|
65
77
|
--upload-row-space-gap: var(--space-3);
|
|
66
78
|
--upload-row-radius: var(--radius-md);
|
|
67
|
-
--upload-row-font-size: var(--font-size-sm);
|
|
79
|
+
--upload-row-font-size: var(--font-size-sm, var(--font-size-base));
|
|
68
80
|
--upload-row-icon-size: var(--icon-size-md);
|
|
69
81
|
|
|
70
82
|
--upload-crop-dialog-max-width: 24rem;
|
|
@@ -146,37 +146,27 @@
|
|
|
146
146
|
|
|
147
147
|
--font-size-base: 0.875rem;
|
|
148
148
|
--font-size-ratio: 1.1227;
|
|
149
|
-
|
|
150
|
-
|
|
151
|
-
|
|
152
|
-
--font-size-
|
|
153
|
-
--font-size-
|
|
154
|
-
--font-size-
|
|
155
|
-
|
|
156
|
-
|
|
157
|
-
--font-size-
|
|
158
|
-
--font-size-2xl: calc(var(--font-size-xl) * var(--font-size-ratio));
|
|
159
|
-
|
|
160
|
-
--font-size-display: 3.375rem;
|
|
149
|
+
|
|
150
|
+
--font-size-2xs: initial;
|
|
151
|
+
--font-size-xs: initial;
|
|
152
|
+
--font-size-sm: initial;
|
|
153
|
+
--font-size-lg: initial;
|
|
154
|
+
--font-size-xl: initial;
|
|
155
|
+
--font-size-2xl: initial;
|
|
156
|
+
|
|
157
|
+
--font-size-display: clamp(2rem, 1.5rem + 2.5vw, 3.375rem);
|
|
161
158
|
--font-size-display-ratio: 1.28;
|
|
162
|
-
|
|
163
|
-
|
|
164
|
-
|
|
165
|
-
--font-size-
|
|
166
|
-
|
|
167
|
-
|
|
168
|
-
--
|
|
169
|
-
|
|
170
|
-
--heading-
|
|
171
|
-
|
|
172
|
-
|
|
173
|
-
--heading-h2: calc(
|
|
174
|
-
var(--font-size-base) * var(--font-size-ratio) * var(--font-size-ratio)
|
|
175
|
-
);
|
|
176
|
-
--heading-h3: var(--font-size-base);
|
|
177
|
-
--heading-h4: var(--font-size-xs);
|
|
178
|
-
|
|
179
|
-
--heading-h5: var(--font-size-2xs);
|
|
159
|
+
|
|
160
|
+
--font-size-3xl: initial;
|
|
161
|
+
--font-size-4xl: initial;
|
|
162
|
+
--font-size-5xl: initial;
|
|
163
|
+
|
|
164
|
+
--heading-h1: initial;
|
|
165
|
+
--heading-h2: initial;
|
|
166
|
+
--heading-h3: initial;
|
|
167
|
+
--heading-h4: initial;
|
|
168
|
+
|
|
169
|
+
--heading-h5: initial;
|
|
180
170
|
|
|
181
171
|
--font-weight-normal: 400;
|
|
182
172
|
--font-weight-medium: 500;
|
|
@@ -225,6 +215,10 @@
|
|
|
225
215
|
--stroke-xl: 4px;
|
|
226
216
|
--stroke-2xl: 6px;
|
|
227
217
|
|
|
218
|
+
--blur-sm: 4px;
|
|
219
|
+
--blur-md: 8px;
|
|
220
|
+
--blur-lg: 16px;
|
|
221
|
+
|
|
228
222
|
--band-height-xs: 1.5rem;
|
|
229
223
|
--band-height-sm: 1.75rem;
|
|
230
224
|
--band-height-md: 2rem;
|
|
@@ -18,6 +18,8 @@
|
|
|
18
18
|
--space-inline-md: var(--space-3);
|
|
19
19
|
--space-inline-lg: var(--space-4);
|
|
20
20
|
|
|
21
|
+
--space-inline-xl: var(--space-6);
|
|
22
|
+
|
|
21
23
|
--overlay-z-index: 50;
|
|
22
24
|
|
|
23
25
|
--sticky-z-index: 20;
|
|
@@ -71,14 +73,26 @@
|
|
|
71
73
|
|
|
72
74
|
--page-measure-wide: 72rem;
|
|
73
75
|
|
|
74
|
-
--page-title-font-size: var(
|
|
75
|
-
|
|
76
|
+
--page-title-font-size: var(
|
|
77
|
+
--heading-h1,
|
|
78
|
+
calc(
|
|
79
|
+
var(--font-size-base) * var(--font-size-ratio) * var(--font-size-ratio) *
|
|
80
|
+
var(--font-size-ratio)
|
|
81
|
+
)
|
|
82
|
+
);
|
|
83
|
+
--page-title-font-size-compact: var(
|
|
84
|
+
--heading-h2,
|
|
85
|
+
calc(var(--font-size-base) * var(--font-size-ratio) * var(--font-size-ratio))
|
|
86
|
+
);
|
|
76
87
|
--page-subtitle-font-size: var(--font-size-base);
|
|
77
|
-
--page-subtitle-font-size-compact: var(--font-size-sm);
|
|
88
|
+
--page-subtitle-font-size-compact: var(--font-size-sm, var(--font-size-base));
|
|
78
89
|
|
|
79
|
-
--page-title-font-size-chrome: var(--heading-h3);
|
|
90
|
+
--page-title-font-size-chrome: var(--heading-h3, var(--font-size-base));
|
|
80
91
|
|
|
81
|
-
--page-subtitle-font-size-chrome: var(
|
|
92
|
+
--page-subtitle-font-size-chrome: var(
|
|
93
|
+
--font-size-2xs,
|
|
94
|
+
calc(var(--font-size-base) / var(--font-size-ratio) / var(--font-size-ratio))
|
|
95
|
+
);
|
|
82
96
|
|
|
83
97
|
--page-pad-block-start-chrome: 0px;
|
|
84
98
|
|
|
@@ -84,6 +84,7 @@ new UI need
|
|
|
84
84
|
| **PricingTable** / feature grid | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | **Composition** — `ResponsiveGrid` + `Card` |
|
|
85
85
|
| Dashboard **page layout** | ❌ | ❌ | ❌ | ❌ | ➖ | ❌ | ❌ | **Composition** — `AppShell` + `PageContainer` + `ResponsiveGrid` |
|
|
86
86
|
| "Icon medallion" | ❌ | ❌ | ❌ | ❌ | ✅ | ❌ | ❌ | **Composition** — `Avatar` (square) + a Lucide glyph |
|
|
87
|
+
| **Section** / **Band** (full-bleed + measured column) | ❌ | ❌ | ❌ | ❌ | ✅ | ❌ | ❌ | **Composition** — `<section>` + `Flex measure` + `pad`; see §3.1 |
|
|
87
88
|
|
|
88
89
|
`✅ 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.
|
|
89
90
|
|
|
@@ -106,6 +107,46 @@ C2 rather than C7.
|
|
|
106
107
|
|
|
107
108
|
**ServiceLauncherCard is the ONE recorded exception, and it is recorded so that it stays one.** It shipped before the test was run against it, and when the test was run it came back with two hard FAILs: **C2** — no state, no keyboard handling, no focus management, its only ARIA three static attributes — and **C3** — its own imports are `Card` + `CardContent` + `Badge` + a Lucide glyph, so "could I build this right now from primitives?" is yes. By §2 that makes it a composition pattern. It is kept anyway because `src/components/layout/app-launcher.tsx` consumes it: it is an internal building block of a component that **does** pass, so the question was never "should it exist" but "should it be PUBLIC", and removing a public export is breaking. Keeping it public was the cheaper call and the ledger lives on gh#814 and at the top of `src/components/data-display/service-launcher-card.tsx`. **Consumers should compose `Card` + `Badge` for a service tile** — reach for `ServiceLauncherCard` only to match `AppLauncher`'s own tiles — and this row is not precedent for adding another static tile to `src/components/`.
|
|
108
109
|
|
|
110
|
+
### 3.1 "Full-bleed outside, measured column inside" — the case that was answered with a PROP (gh#839)
|
|
111
|
+
|
|
112
|
+
This row exists because the question it settles was asked the other way round, and the right answer
|
|
113
|
+
turned out to be neither "add a component" nor "do nothing".
|
|
114
|
+
|
|
115
|
+
**A `Section` component is refused, and it is refused for Hero's reasons.** It owns no state, no
|
|
116
|
+
keyboard, no focus and no ARIA a `<section aria-labelledby>` does not already have (**C2**); it is
|
|
117
|
+
`<section>` + `Flex` + padding + a max-width, i.e. buildable today (**C3**); its API would be the
|
|
118
|
+
grab-bag `band` / `measure` / `glow` / `surface` / `bleed` that **C4** names by name; and a JP
|
|
119
|
+
business-software library would be shipping a marketing band to every consumer (**C7**). One
|
|
120
|
+
criterion of seven passes. Nothing about that is close.
|
|
121
|
+
|
|
122
|
+
**But "do nothing" was also refused, and that is the part worth remembering.** The doctrine's own
|
|
123
|
+
remedy for a composition is a TOKEN (§4.3), and `--page-measure-wide` shipped in 28.8.0 — so on
|
|
124
|
+
paper the gap was already closed. It was not. A token is only closed when something can READ it,
|
|
125
|
+
and three unrelated pages had each hand-written the identical four declarations to do so:
|
|
126
|
+
`docs/showcase/marketing-page.tsx` as an inline `style` constant, `acme-website.tsx` as `.tx-shell`,
|
|
127
|
+
`futurelastic-web.tsx` as `.fl-shell` — one shape, three spellings, two of them page-local CSS
|
|
128
|
+
classes on the pages whose entire claim is that they need none. `docs/TOKENS.md` calls a value that
|
|
129
|
+
appears in more than one place tier 1, and the same logic reads on a SHAPE.
|
|
130
|
+
|
|
131
|
+
**The third move is a prop on a primitive that already passes the test.** `Flex measure` (narrow |
|
|
132
|
+
medium | wide) centres the box and caps it at `var(--page-measure-*)`; it adds no gutter, because
|
|
133
|
+
`pad` owns that. A full-bleed band is now `<section>` — carrying the edge-to-edge paint — around one
|
|
134
|
+
`<Flex direction="col" measure="wide" pad={{ inline: 6, block: 20 }}>`. Measured on
|
|
135
|
+
`marketing-page.tsx`: seven bands, 7 inline `style` spreads and 3 `CSSProperties` constants gone,
|
|
136
|
+
the metric that page defends (0 bespoke classes, 0 raw px/rem literals) unchanged at 0/0, and the
|
|
137
|
+
geometry byte-identical (1440: section 1440px, column 1152px, band 96/80px, gutter 24px).
|
|
138
|
+
|
|
139
|
+
**`PageContainer measure="wide"` stays refused, and for the original reason.** A marketing page is
|
|
140
|
+
full-bleed `<section>`s; `PageContainer` owns page padding and a header/toolbar/footer scaffold, so
|
|
141
|
+
the two pages that are the prop's proof still cannot consume it. The prop went to the primitive
|
|
142
|
+
those pages CAN put inside a `<section>`, which is the distinction the earlier deferral was missing
|
|
143
|
+
rather than a reversal of it.
|
|
144
|
+
|
|
145
|
+
**The rule this leaves behind:** when a composition repeats a shape, ask whether an existing
|
|
146
|
+
primitive is missing ONE AXIS before you ask whether a new component is missing. A component that
|
|
147
|
+
fails C1–C7 and a prop that closes the same gap are not the same proposal, and the test above is
|
|
148
|
+
only asking about the first.
|
|
149
|
+
|
|
109
150
|
---
|
|
110
151
|
|
|
111
152
|
## 4. How to build a composition pattern correctly
|
package/docs/DESIGN-AUTHORITY.md
CHANGED
|
@@ -449,6 +449,20 @@ expandable.expandedRowKeys` / `onExpandedRowsChange`. This library already mappe
|
|
|
449
449
|
(`role="toolbar"`, `aria-pressed`); the prop there only keeps the last item selected.
|
|
450
450
|
Divergence from Radix's markup is the point of the change, not a side effect of it.
|
|
451
451
|
|
|
452
|
+
- **`Input addonBefore` / `addonAfter` stay, although antd DEPRECATED them (gh#841).** Verified in
|
|
453
|
+
`ant-design@master` rather than on the docs page: `components/input/Input.tsx` carries
|
|
454
|
+
`@deprecated Use Space.Compact instead` on both props and fires a dev-time
|
|
455
|
+
`devUseWarning('Input').deprecated(…)` for each, while still rendering them; both locale tables
|
|
456
|
+
strike the rows through and the `addon` demo is flagged `debug`, so it no longer appears on the
|
|
457
|
+
published page. The deprecation is a REFACTOR onto `Space.Compact`, and this library has no
|
|
458
|
+
`Space` — so following it would delete the joined control and put nothing in its place, which is
|
|
459
|
+
a breaking change bought for nothing. `addonBefore` IS the joined control here: it renders
|
|
460
|
+
`.ui-input-group`, and gh#841 squared its seam. The steer that IS followed is the one antd's own
|
|
461
|
+
live surface gives: a GLYPH belongs in `prefix`, inside the field, where there is one box, one
|
|
462
|
+
border and no seam; an addon is for a label segment. Written on the prop
|
|
463
|
+
(`src/props/components/data-entry.prop.ts`) and in the MCP catalog. Revisit if a `Space`/compact
|
|
464
|
+
primitive is ever ported — then antd's steer is followable and this becomes a migration.
|
|
465
|
+
|
|
452
466
|
**A knob that only a fork could reach is not parity either.** antd's `components`,
|
|
453
467
|
`filterDropdown`, `classNames`/`styles` semantic maps and `prefixCls` all exist to let a consumer
|
|
454
468
|
replace the rendered markup. This library answers that layer with tokens (cardinal rule #45), so
|
package/docs/DEVELOPMENT.md
CHANGED
|
@@ -112,16 +112,91 @@ A change isn't done until its documentation reflects it:
|
|
|
112
112
|
|
|
113
113
|
---
|
|
114
114
|
|
|
115
|
-
## 5. Verify before finishing
|
|
115
|
+
## 5. Verify before finishing — scope the checks to the DIFF
|
|
116
|
+
|
|
117
|
+
> **Read §5.0 before you run anything.** This section was rewritten after the owner watched a
|
|
118
|
+
> two-file change take six minutes of gates and asked, correctly, _"bản chất chỉ sửa rất ít, check
|
|
119
|
+
> diff đéo được hay sao? có phải release đâu mà run hết thế?"_ — it is not a release, so stop
|
|
120
|
+
> running a release's worth of checks.
|
|
121
|
+
|
|
122
|
+
### 5.0 MEASURE FIRST, THEN COMPLAIN — the real cost table
|
|
123
|
+
|
|
124
|
+
Every number below was measured on this repo, on an M-series Mac, warm. **Measure again before you
|
|
125
|
+
believe them; a cost you assumed is how you end up optimising the wrong thing.**
|
|
126
|
+
|
|
127
|
+
| command | cost | scope |
|
|
128
|
+
| -------------------------- | --------------- | ------------------------------------------ |
|
|
129
|
+
| `check:token-tiers` | **0.2s** | whole repo |
|
|
130
|
+
| `audit` | **0.5s** | whole repo (~600 files) |
|
|
131
|
+
| `typecheck:docs` | **0.7s** | whole `docs/` program |
|
|
132
|
+
| `typecheck` | **1.3s** | whole `src/` program |
|
|
133
|
+
| `build` | **1.5s** | whole package |
|
|
134
|
+
| `preview:build` | **1.9s** | whole preview |
|
|
135
|
+
| `lint` | **12.9s** | whole repo |
|
|
136
|
+
| **`check:frame-overflow`** | **52s** (was 339s before it was parallelised, gh#851) | **199 frames x 2 viewports, in a browser** |
|
|
137
|
+
|
|
138
|
+
**The lesson is the opposite of the intuition.** "Typecheck the whole system" sounds wasteful and
|
|
139
|
+
costs **1.3 seconds** — typescript-7 is the native compiler, there is nothing to save there, and
|
|
140
|
+
scoping it to changed files would cost more in ceremony than it saves in wall clock. Meanwhile the
|
|
141
|
+
one command that _does_ cost real time is the browser sweep, and it is the one that looks innocent
|
|
142
|
+
in a shell script.
|
|
143
|
+
|
|
144
|
+
`check:frame-overflow` alone was **~96% of the wall clock** of a full local pass. It ran all 398
|
|
145
|
+
navigations down a SINGLE page, in series. It now runs a pool of one page per core (capped at 8):
|
|
146
|
+
**339s -> 52.3s, 6.5x**, byte-identical output, and a planted overflow is still caught at both
|
|
147
|
+
viewports by both. `FRAME_CONCURRENCY=1` restores the serial run for debugging.
|
|
148
|
+
|
|
149
|
+
> **Never argue about the cost of a gate you have not timed.** Time it:
|
|
150
|
+
> `st=$(date +%s); pnpm <gate> >/dev/null 2>&1; echo $(( $(date +%s) - st ))s`
|
|
151
|
+
|
|
152
|
+
### 5.1 What to run, by what you touched
|
|
153
|
+
|
|
154
|
+
Find the row that matches your diff. Run that row. Do not run the rows below it.
|
|
155
|
+
|
|
156
|
+
| you changed | run | why |
|
|
157
|
+
| ---------------------------------- | ------------------------------------------------------------------------------------------------ | --------------------------------------------------------- |
|
|
158
|
+
| a `.css` file only | `audit` · `check:token-tiers` · the component's own tests · `check:frame-overflow --only <slug>` | no TS changed, so `typecheck` has nothing to say |
|
|
159
|
+
| a `.tsx`/`.ts` in `src/` | `typecheck` · `lint` · `audit` · that group's tests | 1.3s + 12.9s, both worth it |
|
|
160
|
+
| a file in `docs/` | `typecheck:docs` · `audit` · `check:example-imports` | `typecheck` covers `src/`, not `docs/` |
|
|
161
|
+
| a token in `src/tokens/` | + `check:token-tiers` · `src/tokens/__tests__` · `pnpm regen` twice (gh#847) | frozen tier tables go stale instantly |
|
|
162
|
+
| a public export / prop | + `pnpm ship:surface` | 8 stacked generators; the list is derived, not remembered |
|
|
163
|
+
| anything that moves LAYOUT | `check:frame-overflow --only <slug>` while you work; the FULL sweep once, before the PR | 17.5s vs 339s |
|
|
164
|
+
| opening the PR / cutting a release | the full sweep, `verify:ci:static`, the full suite in CI | the only place "run everything" is right |
|
|
165
|
+
|
|
166
|
+
### 5.2 `--only` — the diff-scoped browser sweep
|
|
167
|
+
|
|
168
|
+
Added in gh#851 for exactly this. The sweep had no filter at all: 199 frames or nothing.
|
|
169
|
+
|
|
170
|
+
```bash
|
|
171
|
+
pnpm check:frame-overflow --only table # 9 frames, 17.5s
|
|
172
|
+
pnpm check:frame-overflow --only '/^data-entry-(switch|segmented)/' # 3 frames
|
|
173
|
+
pnpm check:frame-overflow # all 199, 52s
|
|
174
|
+
```
|
|
175
|
+
|
|
176
|
+
Measured: `--only table` is **17.5s against the full sweep's 52.3s**. Both matter — the pool cut
|
|
177
|
+
the full sweep 6.5x, and `--only` cuts what is left to the frames a diff can actually reach.
|
|
178
|
+
|
|
179
|
+
Two guards, both deliberate:
|
|
180
|
+
|
|
181
|
+
- **`--only` refuses `--update-baseline`.** A partial sweep does not know whether the frames it
|
|
182
|
+
skipped are still clean, and recording that as the whole truth is how a baseline stops meaning
|
|
183
|
+
anything. Rebaselining needs the full sweep.
|
|
184
|
+
- **Its success line says `PARTIAL, not a release gate`** and prints how many frames it skipped, so
|
|
185
|
+
a filtered green can never be pasted into a PR as if it were the real thing.
|
|
186
|
+
|
|
187
|
+
### 5.3 The commands, for reference
|
|
116
188
|
|
|
117
189
|
```bash
|
|
118
|
-
pnpm lint # eslint — self-contained flat config
|
|
119
|
-
pnpm typecheck # tsc --noEmit
|
|
190
|
+
pnpm lint # eslint — self-contained flat config 12.9s
|
|
191
|
+
pnpm typecheck # tsc --noEmit over src/ 1.3s
|
|
192
|
+
pnpm typecheck:docs # tsc --noEmit over docs/ 0.7s
|
|
193
|
+
pnpm audit # godxjp-ui-audit — 0 errors for touched files 0.5s
|
|
194
|
+
pnpm check:mcp-sync # MCP registry <-> library export drift guard
|
|
120
195
|
pnpm vitest run src/components/<group>/__tests__ --maxWorkers=2 # ONLY what you touched
|
|
196
|
+
pnpm check:frame-overflow --only <slug> # the frames your change can reach ~18s
|
|
197
|
+
pnpm check:frame-overflow # all 199 — pre-PR and CI only 52s
|
|
198
|
+
pnpm preview:build # integration test: examples + docs must build 1.9s
|
|
121
199
|
pnpm test # FULL suite — CI only, never from an agent loop
|
|
122
|
-
pnpm preview:build # integration test: examples + docs must build — at most once, pre-PR
|
|
123
|
-
pnpm audit # godxjp-ui-audit — 0 errors for touched files
|
|
124
|
-
pnpm check:mcp-sync # MCP registry ↔ library export drift guard
|
|
125
200
|
pnpm check:frame-axe # WCAG 2.2 AA over every frame — LOCAL ONLY, never in CI (FRAME-A11Y-CI.md)
|
|
126
201
|
```
|
|
127
202
|
|
package/docs/TOKENS.md
CHANGED
|
@@ -297,7 +297,22 @@ Instead, declare the knob `initial` (a real, catalogued, guaranteed-invalid decl
|
|
|
297
297
|
}
|
|
298
298
|
```
|
|
299
299
|
|
|
300
|
-
The same rule applies to `@theme inline` (utilities re-resolve scoped roles) and to any `:root`-declared **composite** that wraps a role (e.g. a focus-ring box-shadow): read the role **directly** at the call site, never through a frozen `:root` intermediate. Pure non-colour knobs (spacing, radius, font-size) don't need this
|
|
300
|
+
The same rule applies to `@theme inline` (utilities re-resolve scoped roles) and to any `:root`-declared **composite** that wraps a role (e.g. a focus-ring box-shadow): read the role **directly** at the call site, never through a frozen `:root` intermediate. Pure non-colour knobs (spacing, radius, font-size) don't need this **as long as nothing re-scopes what they read** — see the two paragraphs below, which is where that qualifier cost a release.
|
|
301
|
+
|
|
302
|
+
**A DERIVED TIER FREEZES ON ITS OWN SEED — the `--font-size-*` ramp (gh#834).** The type scale is one base and one ratio, and every step used to be written `--font-size-5xl: var(--font-size-display)` / `--font-size-lg: calc(var(--font-size-base) * …)` on `:root`. Those substitute on `<html>`, so a `[data-tenant]` that re-seeds the base — the route level 3 of `docs/CUSTOMER-THEMING.md` documents, and which level 1 calls a seed — moved `text-base` and **nothing else**. Measured with `--font-size-base: 24px; --font-size-display: 80px` on a scope: 2xs/xs/sm/lg/xl/2xl/3xl/4xl/5xl all sat exactly where `:root` had left them, and a showcase whose comment read "80px hero via text-5xl" painted 54.
|
|
303
|
+
|
|
304
|
+
So every **derived** step is now an `initial` knob and the formula lives at the call site, spelled in terms of the un-derived knobs only (`--font-size-base`, `--font-size-ratio`, `--font-size-display`, `--font-size-display-ratio`) — an `initial` knob cannot be chained through, so `xl` reads `base × ratio³` rather than `lg × ratio`:
|
|
305
|
+
|
|
306
|
+
```css
|
|
307
|
+
:root {
|
|
308
|
+
--font-size-5xl: initial;
|
|
309
|
+
} /* documented default = var(--font-size-display) */
|
|
310
|
+
[data-slot="text"][data-size="5xl"] {
|
|
311
|
+
font-size: var(--font-size-5xl, var(--font-size-display));
|
|
312
|
+
}
|
|
313
|
+
```
|
|
314
|
+
|
|
315
|
+
**Every reader must carry the fallback**: a bare `var(--font-size-xs)` on an `initial` knob resolves to nothing, and the failure is silent and total. `check:frame-token-scope` is the gate that measures both halves — it fails on a step that stops following a scoped seed, and on a bare read of an empty knob.
|
|
301
316
|
|
|
302
317
|
**The same freeze bites any knob whose default is a RE-SCOPED tier, colour or not.** `--control-height` is re-scoped by `.ui-auth-shell` (44px comfortable) and by `.ui-auth-shell[data-variant="canonical"]` (36px), so a knob that mirrors it must follow the same `initial` + call-site-fallback shape:
|
|
303
318
|
|
|
@@ -2,6 +2,7 @@ import { useState } from "react";
|
|
|
2
2
|
|
|
3
3
|
import { Card, CardContent, CardDescription, CardHeader, CardTitle } from "@godxjp/ui/data-display";
|
|
4
4
|
import { FormField, TagInput } from "@godxjp/ui/data-entry";
|
|
5
|
+
import { useTranslation } from "@godxjp/ui/i18n";
|
|
5
6
|
import { Flex, PageContainer } from "@godxjp/ui/layout";
|
|
6
7
|
|
|
7
8
|
/**
|
|
@@ -11,9 +12,17 @@ import { Flex, PageContainer } from "@godxjp/ui/layout";
|
|
|
11
12
|
* Composed only from real @godxjp/ui components.
|
|
12
13
|
*/
|
|
13
14
|
export default function Demo() {
|
|
15
|
+
const { t } = useTranslation();
|
|
14
16
|
const [invoiceTags, setInvoiceTags] = useState<string[]>(["営業部", "Q1"]);
|
|
15
17
|
const [skillTags, setSkillTags] = useState<string[]>(["経理", "仕訳入力"]);
|
|
16
18
|
const [recipientEmails, setRecipientEmails] = useState<string[]>([]);
|
|
19
|
+
/* The reporter's exact 71-character string, held FIRST so the truncated chip is one of the two
|
|
20
|
+
that render rather than one of the ones `+N` hides (gh#840). */
|
|
21
|
+
const [ledgerTags, setLedgerTags] = useState<string[]>([
|
|
22
|
+
"THEME_SEED_LEDGER_0007_CONTRAST_VERIFIED_AGAINST_CANVAS_AND_LABEL_00042",
|
|
23
|
+
"本番",
|
|
24
|
+
"ổn định",
|
|
25
|
+
]);
|
|
17
26
|
|
|
18
27
|
return (
|
|
19
28
|
<PageContainer
|
|
@@ -87,6 +96,34 @@ export default function Demo() {
|
|
|
87
96
|
</CardContent>
|
|
88
97
|
</Card>
|
|
89
98
|
|
|
99
|
+
<Card>
|
|
100
|
+
<CardHeader>
|
|
101
|
+
<CardTitle level={2}>{t("showcase.tagInput.longIdTitle")}</CardTitle>
|
|
102
|
+
<CardDescription>
|
|
103
|
+
maxTagTextLength cuts the chip TEXT only — the whole value stays in the chip's
|
|
104
|
+
title and in the remove button's accessible name. maxTagCount collapses the rest
|
|
105
|
+
into a +N that names, in its own title and aria-label, exactly which tags it hides.
|
|
106
|
+
Neither may swallow a value silently (gh#840).
|
|
107
|
+
</CardDescription>
|
|
108
|
+
</CardHeader>
|
|
109
|
+
<CardContent>
|
|
110
|
+
<FormField
|
|
111
|
+
id="ledger-tags"
|
|
112
|
+
label={t("showcase.tagInput.ledgerLabel")}
|
|
113
|
+
helper={t("showcase.tagInput.ledgerHelper")}
|
|
114
|
+
>
|
|
115
|
+
<TagInput
|
|
116
|
+
id="ledger-tags"
|
|
117
|
+
value={ledgerTags}
|
|
118
|
+
onValueChange={setLedgerTags}
|
|
119
|
+
maxTagCount={2}
|
|
120
|
+
maxTagTextLength={16}
|
|
121
|
+
aria-label={t("showcase.tagInput.ledgerLabel")}
|
|
122
|
+
/>
|
|
123
|
+
</FormField>
|
|
124
|
+
</CardContent>
|
|
125
|
+
</Card>
|
|
126
|
+
|
|
90
127
|
<Card>
|
|
91
128
|
<CardHeader>
|
|
92
129
|
<CardTitle level={2}>無効状態</CardTitle>
|
package/docs/layout/flex.tsx
CHANGED
|
@@ -8,6 +8,7 @@ import {
|
|
|
8
8
|
ListRow,
|
|
9
9
|
} from "@godxjp/ui/data-display";
|
|
10
10
|
import { Button, Text } from "@godxjp/ui/general";
|
|
11
|
+
import { useTranslation } from "@godxjp/ui/i18n";
|
|
11
12
|
import { Flex, PageContainer } from "@godxjp/ui/layout";
|
|
12
13
|
|
|
13
14
|
/**
|
|
@@ -20,6 +21,7 @@ import { Flex, PageContainer } from "@godxjp/ui/layout";
|
|
|
20
21
|
* @godxjp/ui components.
|
|
21
22
|
*/
|
|
22
23
|
export default function Demo() {
|
|
24
|
+
const { t } = useTranslation();
|
|
23
25
|
return (
|
|
24
26
|
<PageContainer
|
|
25
27
|
title="Flex"
|
|
@@ -398,6 +400,44 @@ export default function Demo() {
|
|
|
398
400
|
</Flex>
|
|
399
401
|
</CardContent>
|
|
400
402
|
</Card>
|
|
403
|
+
|
|
404
|
+
<Card>
|
|
405
|
+
<CardHeader>
|
|
406
|
+
<CardTitle level={2}>{t("showcase.flexMeasure.title")}</CardTitle>
|
|
407
|
+
<CardDescription>{t("showcase.flexMeasure.lead")}</CardDescription>
|
|
408
|
+
</CardHeader>
|
|
409
|
+
<CardContent>
|
|
410
|
+
<Flex direction="col" gap="sm">
|
|
411
|
+
<Flex
|
|
412
|
+
id="measure-narrow"
|
|
413
|
+
measure="narrow"
|
|
414
|
+
surface="muted"
|
|
415
|
+
pad={{ block: 2, inline: 6 }}
|
|
416
|
+
justify="center"
|
|
417
|
+
>
|
|
418
|
+
<Text tone="muted">measure="narrow" · 42rem</Text>
|
|
419
|
+
</Flex>
|
|
420
|
+
<Flex
|
|
421
|
+
id="measure-medium"
|
|
422
|
+
measure="medium"
|
|
423
|
+
surface="muted"
|
|
424
|
+
pad={{ block: 2, inline: 6 }}
|
|
425
|
+
justify="center"
|
|
426
|
+
>
|
|
427
|
+
<Text tone="muted">measure="medium" · 48rem</Text>
|
|
428
|
+
</Flex>
|
|
429
|
+
<Flex
|
|
430
|
+
id="measure-wide"
|
|
431
|
+
measure="wide"
|
|
432
|
+
surface="muted"
|
|
433
|
+
pad={{ block: 2, inline: 6 }}
|
|
434
|
+
justify="center"
|
|
435
|
+
>
|
|
436
|
+
<Text tone="muted">measure="wide" · 72rem</Text>
|
|
437
|
+
</Flex>
|
|
438
|
+
</Flex>
|
|
439
|
+
</CardContent>
|
|
440
|
+
</Card>
|
|
401
441
|
</Flex>
|
|
402
442
|
</PageContainer>
|
|
403
443
|
);
|
|
@@ -649,6 +649,40 @@ with no call site in the two pages that are its proof, which is the tier-2 mista
|
|
|
649
649
|
warns about. The token stands on its own as the vocabulary a composition caps its shell with, the
|
|
650
650
|
way `--gradient-hero` does.
|
|
651
651
|
|
|
652
|
+
**CLOSED in gh#839, and the refusal above still stands.** Leaving the centred column to "the
|
|
653
|
+
composition writes it" was measured and found wanting: three unrelated pages hand-wrote the SAME
|
|
654
|
+
four declarations — `marketing-page.tsx` as an inline `style` constant, `acme-website.tsx` as
|
|
655
|
+
`.tx-shell`, `futurelastic-web.tsx` as `.fl-shell` — which `docs/TOKENS.md` calls tier 1, and two of
|
|
656
|
+
the three spelled it as a page-local CSS class. The answer was not a `Section` component (it fails
|
|
657
|
+
C1–C7 the way Hero does — `docs/COMPOSITION-VS-COMPONENT.md` §3.1 carries the ledger) and not
|
|
658
|
+
`PageContainer`, which still cannot be consumed by a full-bleed page. It is **`Flex measure`**
|
|
659
|
+
(`narrow | medium | wide`, reading `--page-measure-*`), on the primitive a `<section>` CAN put
|
|
660
|
+
inside itself. It centres and caps and nothing else: `pad` keeps the gutter, so a band is
|
|
661
|
+
`<section>` around one `<Flex direction="col" measure="wide" pad={{ inline: 6, block: 20 }}>`.
|
|
662
|
+
|
|
663
|
+
| step | reader |
|
|
664
|
+
| ---------------------------------- | -------------------------------------------------------------- |
|
|
665
|
+
| `--space-section-band` (80px) | `pad={{ block: 20 }}` — `GapStepProp` gained 20/24 |
|
|
666
|
+
| `--space-section-hero` (96px) | `pad={{ block: 24 }}` |
|
|
667
|
+
| `--page-measure-{narrow,med,wide}` | `Flex measure` — and `PageContainer measure` for the first two |
|
|
668
|
+
|
|
669
|
+
**No compact rung for the band steps, decided on measurement.** At 320×568 the hero band is 96px
|
|
670
|
+
at both edges = 33.8% of the first screen, and the `<h1>` still lands fully above the fold (top
|
|
671
|
+
195px, bottom 315px). Three reasons not to add one: (1) 96px is already the NARROW rung of the
|
|
672
|
+
industry pair — Tailwind UI's marketing sections are `py-24 sm:py-32`, i.e. 96px on a phone and
|
|
673
|
+
128px from `sm` up, so the missing step is at the wide end, not the narrow one; (2) a numeric `pad`
|
|
674
|
+
step is a VALUE by contract (`pad={3}` is 12px at every width — `GapStepProp`'s own docstring says
|
|
675
|
+
so), and making 20/24 responsive would make them the two steps whose number lies; (3) a
|
|
676
|
+
`--space-section-band-compact` token would have nowhere to be flipped: every `-active`/`-compact`
|
|
677
|
+
pair in this repo switches inside a COMPONENT's scope (`.ui-page-container`,
|
|
678
|
+
`.ui-centered-shell[data-preset="public-landing"]`), and a plain `<section>` has no such scope — so
|
|
679
|
+
it would ship as vocabulary with no caller, the exact defect gh#839 exists to stop.
|
|
680
|
+
`--centered-shell-landing-main-padding-block-compact` is not the counter-example it looks like: it
|
|
681
|
+
is 40px → 24px of a SHELL's `main` padding, not a marketing band, and it lives inside that shell's
|
|
682
|
+
own scope. **The real capability the band wants is a responsive object form for `pad`**, the one
|
|
683
|
+
`direction` and `ResponsiveGrid columns` already take (`pad={{ block: { base: 12, md: 20 } }}`) —
|
|
684
|
+
that is its own issue, and a much larger one than a token rung.
|
|
685
|
+
|
|
652
686
|
---
|
|
653
687
|
|
|
654
688
|
## 6. The animation and motion story
|