@godxjp/ui 28.9.0 → 28.12.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 +77 -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 +93 -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 +15515 -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 +8427 -0
- package/agent/vocabulary.json +198 -0
- package/dist/components/data-display/service-launcher-card.d.ts +19 -0
- package/dist/components/data-display/service-launcher-card.js +14 -1
- package/dist/components/data-entry/attachments.js +77 -33
- 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/avatar.d.ts +1 -18
- package/dist/components/ui/avatar.js +1 -36
- 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 +190 -1
- package/dist/i18n/messages/ja.json +188 -1
- package/dist/i18n/messages/vi.json +188 -1
- package/dist/lib/image-loading-status.d.ts +25 -0
- package/dist/lib/image-loading-status.js +41 -0
- 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 +14 -1
- package/dist/props/registry.js +18 -1
- package/dist/styles/card-layout.css +10 -4
- package/dist/styles/control.css +33 -4
- package/dist/styles/data-display-layout.css +1 -1
- package/dist/styles/data-entry-layout.css +245 -2
- package/dist/styles/layout.css +17 -0
- package/dist/styles/navigation-layout.css +3 -1
- package/dist/styles/shell-layout.css +2 -0
- package/dist/styles/table-layout.css +50 -9
- package/dist/tokens/components/attachments.css +18 -9
- package/dist/tokens/components/segmented.css +7 -3
- package/dist/tokens/components/table.css +2 -1
- package/docs/COMPOSITION-VS-COMPONENT.md +41 -0
- package/docs/DESIGN-AUTHORITY.md +52 -0
- package/docs/DEVELOPMENT.md +81 -6
- package/docs/assets/service-mark-rose.svg +6 -0
- package/docs/assets/service-mark-teal.svg +5 -0
- package/docs/data-display/service-launcher-card.tsx +232 -92
- 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/marketing-page.tsx +54 -45
- package/docs/showcase/table-pagination.tsx +99 -18
- package/docs/showcase/theme-customization.tsx +25 -2
- package/package.json +8 -5
|
@@ -88,12 +88,14 @@
|
|
|
88
88
|
|
|
89
89
|
.ui-table-row[data-tone] > [data-slot="table-cell"]:first-child {
|
|
90
90
|
border-inline-start: var(--table-row-tone-rail-width) solid hsl(var(--table-row-tone-color));
|
|
91
|
-
padding-inline-start: calc(
|
|
91
|
+
padding-inline-start: calc(
|
|
92
|
+
var(--table-cell-space-x, var(--space-section-active)) - var(--table-row-tone-rail-width)
|
|
93
|
+
);
|
|
92
94
|
}
|
|
93
95
|
|
|
94
96
|
[data-slot="table-head"] {
|
|
95
97
|
height: var(--table-row-height);
|
|
96
|
-
padding: var(--table-cell-padding-y) var(--table-cell-space-x);
|
|
98
|
+
padding: var(--table-cell-padding-y) var(--table-cell-space-x, var(--space-section-active));
|
|
97
99
|
text-align: start;
|
|
98
100
|
vertical-align: middle;
|
|
99
101
|
background: var(--table-header-background, hsl(var(--muted)));
|
|
@@ -113,7 +115,7 @@
|
|
|
113
115
|
}
|
|
114
116
|
|
|
115
117
|
[data-slot="table-cell"] {
|
|
116
|
-
padding: var(--table-cell-padding-y) var(--table-cell-space-x);
|
|
118
|
+
padding: var(--table-cell-padding-y) var(--table-cell-space-x, var(--space-section-active));
|
|
117
119
|
vertical-align: middle;
|
|
118
120
|
|
|
119
121
|
white-space: nowrap;
|
|
@@ -146,7 +148,7 @@
|
|
|
146
148
|
|
|
147
149
|
[data-slot="table-cell"][data-indent] {
|
|
148
150
|
padding-inline-start: calc(
|
|
149
|
-
var(--table-cell-space-x) + var(--table-cell-indent-level, 0) *
|
|
151
|
+
var(--table-cell-space-x, var(--space-section-active)) + var(--table-cell-indent-level, 0) *
|
|
150
152
|
var(--table-cell-indent-space-step)
|
|
151
153
|
);
|
|
152
154
|
}
|
|
@@ -207,7 +209,10 @@
|
|
|
207
209
|
justify-content: flex-end;
|
|
208
210
|
gap: var(--space-inline-sm);
|
|
209
211
|
padding-block: var(--table-pagination-padding-y, var(--space-stack-sm));
|
|
210
|
-
padding-inline: var(
|
|
212
|
+
padding-inline: var(
|
|
213
|
+
--table-pagination-padding-x,
|
|
214
|
+
var(--table-cell-space-x, var(--space-section-active))
|
|
215
|
+
);
|
|
211
216
|
}
|
|
212
217
|
|
|
213
218
|
.ui-data-table-pagination--numbered {
|
|
@@ -634,7 +639,16 @@
|
|
|
634
639
|
white-space: normal;
|
|
635
640
|
}
|
|
636
641
|
|
|
637
|
-
[data-collapse-below="sm"]
|
|
642
|
+
[data-collapse-below="sm"]
|
|
643
|
+
[data-slot="table"]:has(
|
|
644
|
+
[data-slot="table-head"]:nth-child(7),
|
|
645
|
+
[data-slot="table-head"][data-priority="primary"]
|
|
646
|
+
~ [data-slot="table-head"][data-priority="primary"],
|
|
647
|
+
[data-slot="table-head"][data-priority="secondary"]
|
|
648
|
+
~ [data-slot="table-head"][data-priority="secondary"],
|
|
649
|
+
[data-slot="table-head"][data-priority="meta"]
|
|
650
|
+
~ [data-slot="table-head"][data-priority="meta"]
|
|
651
|
+
) {
|
|
638
652
|
--table-action-collection-primary-width: var(--table-action-collection-primary-width-floor);
|
|
639
653
|
--table-action-collection-secondary-width: var(
|
|
640
654
|
--table-action-collection-secondary-width-floor
|
|
@@ -664,7 +678,16 @@
|
|
|
664
678
|
white-space: normal;
|
|
665
679
|
}
|
|
666
680
|
|
|
667
|
-
[data-collapse-below="md"]
|
|
681
|
+
[data-collapse-below="md"]
|
|
682
|
+
[data-slot="table"]:has(
|
|
683
|
+
[data-slot="table-head"]:nth-child(7),
|
|
684
|
+
[data-slot="table-head"][data-priority="primary"]
|
|
685
|
+
~ [data-slot="table-head"][data-priority="primary"],
|
|
686
|
+
[data-slot="table-head"][data-priority="secondary"]
|
|
687
|
+
~ [data-slot="table-head"][data-priority="secondary"],
|
|
688
|
+
[data-slot="table-head"][data-priority="meta"]
|
|
689
|
+
~ [data-slot="table-head"][data-priority="meta"]
|
|
690
|
+
) {
|
|
668
691
|
--table-action-collection-primary-width: var(--table-action-collection-primary-width-floor);
|
|
669
692
|
--table-action-collection-secondary-width: var(
|
|
670
693
|
--table-action-collection-secondary-width-floor
|
|
@@ -694,7 +717,16 @@
|
|
|
694
717
|
white-space: normal;
|
|
695
718
|
}
|
|
696
719
|
|
|
697
|
-
[data-collapse-below="lg"]
|
|
720
|
+
[data-collapse-below="lg"]
|
|
721
|
+
[data-slot="table"]:has(
|
|
722
|
+
[data-slot="table-head"]:nth-child(7),
|
|
723
|
+
[data-slot="table-head"][data-priority="primary"]
|
|
724
|
+
~ [data-slot="table-head"][data-priority="primary"],
|
|
725
|
+
[data-slot="table-head"][data-priority="secondary"]
|
|
726
|
+
~ [data-slot="table-head"][data-priority="secondary"],
|
|
727
|
+
[data-slot="table-head"][data-priority="meta"]
|
|
728
|
+
~ [data-slot="table-head"][data-priority="meta"]
|
|
729
|
+
) {
|
|
698
730
|
--table-action-collection-primary-width: var(--table-action-collection-primary-width-floor);
|
|
699
731
|
--table-action-collection-secondary-width: var(
|
|
700
732
|
--table-action-collection-secondary-width-floor
|
|
@@ -724,7 +756,16 @@
|
|
|
724
756
|
white-space: normal;
|
|
725
757
|
}
|
|
726
758
|
|
|
727
|
-
[data-collapse-below="xl"]
|
|
759
|
+
[data-collapse-below="xl"]
|
|
760
|
+
[data-slot="table"]:has(
|
|
761
|
+
[data-slot="table-head"]:nth-child(7),
|
|
762
|
+
[data-slot="table-head"][data-priority="primary"]
|
|
763
|
+
~ [data-slot="table-head"][data-priority="primary"],
|
|
764
|
+
[data-slot="table-head"][data-priority="secondary"]
|
|
765
|
+
~ [data-slot="table-head"][data-priority="secondary"],
|
|
766
|
+
[data-slot="table-head"][data-priority="meta"]
|
|
767
|
+
~ [data-slot="table-head"][data-priority="meta"]
|
|
768
|
+
) {
|
|
728
769
|
--table-action-collection-primary-width: var(--table-action-collection-primary-width-floor);
|
|
729
770
|
--table-action-collection-secondary-width: var(
|
|
730
771
|
--table-action-collection-secondary-width-floor
|
|
@@ -1,15 +1,24 @@
|
|
|
1
1
|
|
|
2
2
|
:root {
|
|
3
|
+
|
|
3
4
|
--attachments-gap: var(--space-2);
|
|
4
|
-
|
|
5
|
-
--attachments-card-
|
|
6
|
-
--attachments-card-
|
|
7
|
-
--attachments-
|
|
8
|
-
--attachments-
|
|
9
|
-
|
|
10
|
-
--attachments-placeholder-
|
|
11
|
-
--attachments-placeholder-
|
|
12
|
-
|
|
5
|
+
|
|
6
|
+
--attachments-card-size: 16.75rem;
|
|
7
|
+
--attachments-card-block-size: 4.25rem;
|
|
8
|
+
--attachments-card-radius: var(--radius-lg);
|
|
9
|
+
--attachments-card-gap: var(--space-3);
|
|
10
|
+
|
|
11
|
+
--attachments-placeholder-space-inset: var(--space-4);
|
|
12
|
+
--attachments-placeholder-radius: var(
|
|
13
|
+
--radius-lg
|
|
14
|
+
);
|
|
15
|
+
|
|
16
|
+
--attachments-placeholder-icon-size: var(--icon-size-3xl);
|
|
17
|
+
--attachments-placeholder-title-font-size: var(--font-size-base);
|
|
18
|
+
--attachments-placeholder-description-font-size: var(--font-size-sm, var(--font-size-base));
|
|
19
|
+
--attachments-placeholder-gap: var(--space-1);
|
|
20
|
+
|
|
13
21
|
--attachments-drop-overlay-background: initial;
|
|
22
|
+
|
|
14
23
|
--attachments-remove-icon-size: var(--upload-remove-icon-size);
|
|
15
24
|
}
|
|
@@ -4,7 +4,7 @@
|
|
|
4
4
|
|
|
5
5
|
--segmented-track-padding: calc(var(--space-1) / 2);
|
|
6
6
|
|
|
7
|
-
--segmented-track-background:
|
|
7
|
+
--segmented-track-background: initial;
|
|
8
8
|
|
|
9
9
|
--segmented-track-radius: var(--radius);
|
|
10
10
|
--segmented-item-radius: var(--radius-md);
|
|
@@ -27,8 +27,12 @@
|
|
|
27
27
|
--segmented-item-hover-background: initial;
|
|
28
28
|
--segmented-item-active-background: var(--secondary);
|
|
29
29
|
|
|
30
|
-
--segmented-item-selected-background:
|
|
31
|
-
--segmented-item-selected-shadow: var(--shadow-
|
|
30
|
+
--segmented-item-selected-background: initial;
|
|
31
|
+
--segmented-item-selected-shadow: var(--shadow-md);
|
|
32
|
+
|
|
33
|
+
--segmented-item-selected-font-weight: var(--font-weight-medium);
|
|
34
|
+
|
|
35
|
+
--segmented-item-selected-border-color: initial;
|
|
32
36
|
|
|
33
37
|
--segmented-count-min-width: var(--button-count-min-width);
|
|
34
38
|
--segmented-count-space-inline: var(--button-count-space-inline);
|
|
@@ -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
|
|
|
@@ -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,58 @@ 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
|
+
|
|
466
|
+
- **`Attachments` is Ant Design X's card and tray, with five measured departures (gh#855).** The
|
|
467
|
+
component had shipped with NO stylesheet at all — fifteen slot classes, one rule, twelve tokens
|
|
468
|
+
read by nothing — so the port below is the first time it followed anything. Geometry was taken
|
|
469
|
+
from `@ant-design/x@2.9.0` (`es/attachments/style/index.js` for root/placeholder/drop-area,
|
|
470
|
+
`es/file-card/style/index.js` for list/card/overflow/remove), not from a screenshot. What was
|
|
471
|
+
NOT followed, and why:
|
|
472
|
+
|
|
473
|
+
1. **The card's 268px is a CEILING, not a fixed width.** Ant X writes `width: 268` flat. At the
|
|
474
|
+
320px viewport this repo sweeps, 268 plus the page gutter spills, and `check:frame-overflow`
|
|
475
|
+
is the gate that would have to be baselined around it. `inline-size` + `max-inline-size: 100%`
|
|
476
|
+
keeps Ant's box everywhere it fits and gives ground only where the alternative is a clip.
|
|
477
|
+
2. **One leading box for a thumbnail AND a glyph.** Ant X has two card types — a 268x68 overview
|
|
478
|
+
card and a separate 68x68 image card — so a tray mixing a `.png` with a `.pdf` gets two
|
|
479
|
+
shapes. This library already decided that question for `Upload` (gh#720: "the image rows draw
|
|
480
|
+
their previewUrl as a thumbnail and every other row draws the glyph for its kind, on one row
|
|
481
|
+
height"), and a second answer in the same group would be the defect.
|
|
482
|
+
3. **The remove ✕ is always visible, and in flow.** Ant X pins it absolutely outside the card
|
|
483
|
+
corner at `opacity: 0` until the card is hovered. A hover-only control has no touch
|
|
484
|
+
equivalent — worse, an `opacity: 0` button is still hit-testable, so a tablet user taps a
|
|
485
|
+
control they cannot see. `.ui-upload-tile-remove` already made this call. Always-visible in
|
|
486
|
+
turn removes the reason to position it outside the box, so it is the row's trailing item.
|
|
487
|
+
4. **The placeholder mark is the icon scale's 40px step, not `fontSizeHeading2` (30px).** 30 is
|
|
488
|
+
not one of the nine steps gh#326 fixed, and its neighbours are 24 and 36 — equidistant. The
|
|
489
|
+
token keeps the value the frozen table in `src/tokens/__tests__/icon-size-scale.test.ts`
|
|
490
|
+
already records for it, which is `--upload-dropzone-icon-size`: the mark a reader meets this
|
|
491
|
+
surface beside. Same reasoning holds `--attachments-remove-icon-size` at 14px against Ant's
|
|
492
|
+
`fontSizeLG` = 16.
|
|
493
|
+
5. **The placeholder carries a dashed border at rest; Ant X's is `transparent`.** Ant X's
|
|
494
|
+
placeholder sits INSIDE a `Sender`, which already draws the boundary. Here `Attachments` is
|
|
495
|
+
also used standalone, where a target with no edge is not a target — so it takes
|
|
496
|
+
`.ui-upload-dropzone`'s dashed edge.
|
|
497
|
+
|
|
498
|
+
Not ported, and named here so the gap is a decision rather than an oversight: Ant X's 8px
|
|
499
|
+
`::before`/`::after` scroll-edge gradients and their `ping-start`/`ping-end` state (they need a
|
|
500
|
+
scroll listener, and the clipped card already reads as "more this way"), and its full-screen
|
|
501
|
+
drop area — `getDropContainer` positions the layer `fixed`, but activation is still the
|
|
502
|
+
control's own dragenter, not the document's.
|
|
503
|
+
|
|
452
504
|
**A knob that only a fork could reach is not parity either.** antd's `components`,
|
|
453
505
|
`filterDropdown`, `classNames`/`styles` semantic maps and `prefixCls` all exist to let a consumer
|
|
454
506
|
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
|
|
|
@@ -0,0 +1,6 @@
|
|
|
1
|
+
<svg xmlns="http://www.w3.org/2000/svg" width="240" height="96" viewBox="0 0 240 96" role="img">
|
|
2
|
+
<rect width="240" height="96" rx="12" fill="hsl(348 32% 42%)"/>
|
|
3
|
+
<rect x="24" y="30" width="36" height="36" rx="8" fill="hsl(348 32% 88%)"/>
|
|
4
|
+
<rect x="76" y="36" width="140" height="10" rx="5" fill="hsl(348 32% 88%)"/>
|
|
5
|
+
<rect x="76" y="54" width="96" height="10" rx="5" fill="hsl(348 32% 74%)"/>
|
|
6
|
+
</svg>
|
|
@@ -0,0 +1,5 @@
|
|
|
1
|
+
<svg xmlns="http://www.w3.org/2000/svg" width="128" height="128" viewBox="0 0 128 128" role="img">
|
|
2
|
+
<rect width="128" height="128" rx="28" fill="hsl(178 38% 34%)"/>
|
|
3
|
+
<path d="M40 78 L64 34 L88 78 Z" fill="hsl(178 38% 88%)"/>
|
|
4
|
+
<circle cx="64" cy="90" r="9" fill="hsl(178 38% 88%)"/>
|
|
5
|
+
</svg>
|