@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
|
@@ -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
|
|
@@ -30,26 +30,34 @@
|
|
|
30
30
|
*
|
|
31
31
|
* ── WHAT IS STILL HAND-WRITTEN, AND WHY (the finding this page exists to produce) ───────────────
|
|
32
32
|
*
|
|
33
|
-
* Zero classes and zero literals did NOT mean zero CSS. Six things below
|
|
34
|
-
* objects because no PROP
|
|
33
|
+
* Zero classes and zero literals did NOT mean zero CSS. Six things below WERE inline `style`
|
|
34
|
+
* objects because no PROP reached them. Each one is a named gap, in the order a reader meets them;
|
|
35
|
+
* gh#839 closed the first two:
|
|
35
36
|
*
|
|
36
|
-
* 1. THE SECTION BAND — `paddingBlock: var(--space-section-band | --space-section-hero)`.
|
|
37
|
-
*
|
|
37
|
+
* 1. THE SECTION BAND — was `paddingBlock: var(--space-section-band | --space-section-hero)`.
|
|
38
|
+
* CLOSED by gh#839: the numeric `GapProp` ladder reaches the two band steps, so
|
|
38
39
|
* `pad={{ block: 20 }}` (80px) and `pad={{ block: 24 }}` (96px) state the rhythm through the
|
|
39
|
-
* public API
|
|
40
|
-
*
|
|
41
|
-
*
|
|
42
|
-
*
|
|
43
|
-
*
|
|
44
|
-
*
|
|
40
|
+
* public API, and every band below now does. Neither step has a compact variant and gh#839
|
|
41
|
+
* decided it should not: `--space-section-hero` measures 96px at 1440 AND at 320, which is
|
|
42
|
+
* deliberate — Tailwind UI's own marketing sections are `py-24 sm:py-32`, i.e. 96px is the
|
|
43
|
+
* NARROW rung of the industry pair and the desktop one is the step above. A numeric `pad`
|
|
44
|
+
* step is a VALUE (`pad={3}` is 12px everywhere); making one of them responsive would break
|
|
45
|
+
* that contract for the whole ladder. `--centered-shell-landing-main-padding-block-compact`
|
|
46
|
+
* is not the counter-example it looks like: 40px → 24px is a SHELL's main padding, not a
|
|
47
|
+
* marketing band, and it switches inside `.ui-centered-shell`'s own scope, which a plain
|
|
48
|
+
* `<section>` has no equivalent of.
|
|
49
|
+
* 2. THE CENTRED COLUMN — was `marginInline: auto` + `inlineSize: 100%` +
|
|
45
50
|
* `maxInlineSize: var(--page-measure-wide)` + `paddingInline: var(--space-6)`, repeated at
|
|
46
|
-
* every band. gh#
|
|
47
|
-
* `PageContainer measure="wide"`, reasoning
|
|
48
|
-
* a centred inner column and `PageContainer`
|
|
49
|
-
*
|
|
50
|
-
*
|
|
51
|
-
*
|
|
52
|
-
*
|
|
51
|
+
* every band. CLOSED by gh#839 as `Flex measure="wide"` + `pad={{ inline: 6 }}`. gh#831 minted
|
|
52
|
+
* `--page-measure-wide` and deliberately did not add `PageContainer measure="wide"`, reasoning
|
|
53
|
+
* that a marketing page is full-bleed sections with a centred inner column and `PageContainer`
|
|
54
|
+
* owns neither. That reasoning still holds and was not reopened — the prop went to `Flex`, the
|
|
55
|
+
* primitive a full-bleed `<section>` can actually put inside itself, where it has seven call
|
|
56
|
+
* sites on this page. `measure` adds NO gutter: `pad` owns that, and one band with two padding
|
|
57
|
+
* owners is how a measure and its inset drift apart.
|
|
58
|
+
* 3. THE STICKY BAR — `position: sticky` + `insetBlockStart` + `zIndex`. `Affix` has since
|
|
59
|
+
* shipped (28.8.0, with the measured placeholder that removes the 62px page jump) and this
|
|
60
|
+
* page has not yet been moved onto it; `Topbar` still has no `sticky` prop.
|
|
53
61
|
* 4. THE GLASS — `--topbar-background-alpha` / `--topbar-backdrop-blur-size` as inline custom
|
|
54
62
|
* properties. They are `initial` by design, so a call site MUST set them, and that is correct.
|
|
55
63
|
* This used to read `--space-2`, borrowing a token that means something else, because the
|
|
@@ -155,20 +163,9 @@ import { useTranslation } from "@godxjp/ui/i18n";
|
|
|
155
163
|
import { Flex, ResponsiveGrid, Separator, Topbar } from "@godxjp/ui/layout";
|
|
156
164
|
import { AppSettingPicker } from "@godxjp/ui/navigation";
|
|
157
165
|
|
|
158
|
-
/* ── The
|
|
159
|
-
|
|
160
|
-
|
|
161
|
-
/** (2) The centred inner column. Nothing in the package owns this shape yet. */
|
|
162
|
-
const SHELL: CSSProperties = {
|
|
163
|
-
marginInline: "auto",
|
|
164
|
-
inlineSize: "100%",
|
|
165
|
-
maxInlineSize: "var(--page-measure-wide)",
|
|
166
|
-
paddingInline: "var(--space-6)",
|
|
167
|
-
};
|
|
168
|
-
|
|
169
|
-
/** (1) The section rhythm gh#831 named and no prop reads. */
|
|
170
|
-
const BAND: CSSProperties = { paddingBlock: "var(--space-section-band)" };
|
|
171
|
-
const HERO_BAND: CSSProperties = { paddingBlock: "var(--space-section-hero)" };
|
|
166
|
+
/* ── The inline-style constants named in the docblock. Every value is a token reference; no number
|
|
167
|
+
with a unit appears anywhere in this file. Gaps 1 and 2 no longer have one: `Flex measure` and
|
|
168
|
+
`Flex pad` state the band through props (gh#839). ──────────────────────────────────────────── */
|
|
172
169
|
|
|
173
170
|
/** (5) The halo host and the halo layer. */
|
|
174
171
|
const GLOW_HOST: CSSProperties = { position: "relative", overflow: "hidden" };
|
|
@@ -446,7 +443,13 @@ export default function MarketingPage() {
|
|
|
446
443
|
className="ui-brand-glow"
|
|
447
444
|
style={{ ...GLOW_LAYER, ...HERO_GLOW }}
|
|
448
445
|
/>
|
|
449
|
-
<
|
|
446
|
+
<Flex
|
|
447
|
+
direction="col"
|
|
448
|
+
gap="none"
|
|
449
|
+
measure="wide"
|
|
450
|
+
pad={{ inline: 6, block: 24 }}
|
|
451
|
+
style={ABOVE_GLOW}
|
|
452
|
+
>
|
|
450
453
|
<ResponsiveGrid columns={{ base: 1, lg: 2 }} gap="xl" align="start">
|
|
451
454
|
<Reveal>
|
|
452
455
|
<Flex direction="col" gap="lg">
|
|
@@ -532,12 +535,12 @@ export default function MarketingPage() {
|
|
|
532
535
|
</Card>
|
|
533
536
|
</Reveal>
|
|
534
537
|
</ResponsiveGrid>
|
|
535
|
-
</
|
|
538
|
+
</Flex>
|
|
536
539
|
</section>
|
|
537
540
|
|
|
538
541
|
{/* ── LOGO WALL ────────────────────────────────────────────────────────────────────── */}
|
|
539
542
|
<section aria-labelledby="logos-title">
|
|
540
|
-
<
|
|
543
|
+
<Flex direction="col" gap="none" measure="wide" pad={{ inline: 6, block: 20 }}>
|
|
541
544
|
<Flex direction="col" gap="lg">
|
|
542
545
|
<Flex direction="col" gap="xs">
|
|
543
546
|
<Heading level={2} size="lg" id="logos-title">
|
|
@@ -567,13 +570,13 @@ export default function MarketingPage() {
|
|
|
567
570
|
))}
|
|
568
571
|
</Marquee>
|
|
569
572
|
</Flex>
|
|
570
|
-
</
|
|
573
|
+
</Flex>
|
|
571
574
|
</section>
|
|
572
575
|
|
|
573
576
|
{/* ── FEATURE GRID ─────────────────────────────────────────────────────────────────── */}
|
|
574
577
|
<section id="solutions" aria-labelledby="features-title">
|
|
575
578
|
<Flex as="div" direction="col" gap="none" surface="muted">
|
|
576
|
-
<
|
|
579
|
+
<Flex direction="col" gap="none" measure="wide" pad={{ inline: 6, block: 20 }}>
|
|
577
580
|
<Flex direction="col" gap="xl">
|
|
578
581
|
<Flex direction="col" gap="xs">
|
|
579
582
|
<Heading level={2} size="3xl" weight="bold" id="features-title">
|
|
@@ -613,13 +616,13 @@ export default function MarketingPage() {
|
|
|
613
616
|
))}
|
|
614
617
|
</ResponsiveGrid>
|
|
615
618
|
</Flex>
|
|
616
|
-
</
|
|
619
|
+
</Flex>
|
|
617
620
|
</Flex>
|
|
618
621
|
</section>
|
|
619
622
|
|
|
620
623
|
{/* ── TESTIMONIALS ─────────────────────────────────────────────────────────────────── */}
|
|
621
624
|
<section aria-labelledby="quotes-title">
|
|
622
|
-
<
|
|
625
|
+
<Flex direction="col" gap="none" measure="wide" pad={{ inline: 6, block: 20 }}>
|
|
623
626
|
<Flex direction="col" gap="lg">
|
|
624
627
|
<Heading level={2} size="3xl" weight="bold" id="quotes-title">
|
|
625
628
|
{t("marketingShowcase.testimonials.title")}
|
|
@@ -673,13 +676,13 @@ export default function MarketingPage() {
|
|
|
673
676
|
<CarouselDots />
|
|
674
677
|
</Carousel>
|
|
675
678
|
</Flex>
|
|
676
|
-
</
|
|
679
|
+
</Flex>
|
|
677
680
|
</section>
|
|
678
681
|
|
|
679
682
|
{/* ── PRICING ──────────────────────────────────────────────────────────────────────── */}
|
|
680
683
|
<section id="pricing" aria-labelledby="pricing-title">
|
|
681
684
|
<Flex as="div" direction="col" gap="none" surface="muted">
|
|
682
|
-
<
|
|
685
|
+
<Flex direction="col" gap="none" measure="wide" pad={{ inline: 6, block: 20 }}>
|
|
683
686
|
<Flex direction="col" gap="xl">
|
|
684
687
|
<Flex direction="col" gap="md">
|
|
685
688
|
<Heading level={2} size="3xl" weight="bold" id="pricing-title">
|
|
@@ -774,7 +777,7 @@ export default function MarketingPage() {
|
|
|
774
777
|
})}
|
|
775
778
|
</ResponsiveGrid>
|
|
776
779
|
</Flex>
|
|
777
|
-
</
|
|
780
|
+
</Flex>
|
|
778
781
|
</Flex>
|
|
779
782
|
</section>
|
|
780
783
|
|
|
@@ -785,7 +788,13 @@ export default function MarketingPage() {
|
|
|
785
788
|
className="ui-brand-glow"
|
|
786
789
|
style={{ ...GLOW_LAYER, ...CTA_GLOW }}
|
|
787
790
|
/>
|
|
788
|
-
<
|
|
791
|
+
<Flex
|
|
792
|
+
direction="col"
|
|
793
|
+
gap="none"
|
|
794
|
+
measure="wide"
|
|
795
|
+
pad={{ inline: 6, block: 20 }}
|
|
796
|
+
style={ABOVE_GLOW}
|
|
797
|
+
>
|
|
789
798
|
<Reveal on="view">
|
|
790
799
|
<Flex direction="col" gap="md" align="center">
|
|
791
800
|
<Heading level={2} size="4xl" weight="bold" align="center" id="cta-title">
|
|
@@ -810,14 +819,14 @@ export default function MarketingPage() {
|
|
|
810
819
|
</Text>
|
|
811
820
|
</Flex>
|
|
812
821
|
</Reveal>
|
|
813
|
-
</
|
|
822
|
+
</Flex>
|
|
814
823
|
</section>
|
|
815
824
|
</main>
|
|
816
825
|
|
|
817
826
|
{/* ── FOOTER ───────────────────────────────────────────────────────────────────────── */}
|
|
818
827
|
<footer>
|
|
819
828
|
<Flex as="div" direction="col" gap="none" surface="muted">
|
|
820
|
-
<
|
|
829
|
+
<Flex direction="col" gap="none" measure="wide" pad={{ inline: 6, block: 20 }}>
|
|
821
830
|
<Flex direction="col" gap="lg">
|
|
822
831
|
{/* ResponsiveGrid.Item span — the asymmetric footer both siblings hand-wrote a
|
|
823
832
|
`grid-template-columns: 1.4fr 1fr 1fr 1fr` for. It has shipped the whole time. */}
|
|
@@ -877,7 +886,7 @@ export default function MarketingPage() {
|
|
|
877
886
|
</Flex>
|
|
878
887
|
</Flex>
|
|
879
888
|
</Flex>
|
|
880
|
-
</
|
|
889
|
+
</Flex>
|
|
881
890
|
</Flex>
|
|
882
891
|
</footer>
|
|
883
892
|
</Flex>
|
|
@@ -36,6 +36,7 @@ import {
|
|
|
36
36
|
import { Button, Text } from "@godxjp/ui/general";
|
|
37
37
|
import { Flex, PageContainer } from "@godxjp/ui/layout";
|
|
38
38
|
import { Pagination } from "@godxjp/ui/navigation";
|
|
39
|
+
import { useTranslation } from "@godxjp/ui/i18n";
|
|
39
40
|
import {
|
|
40
41
|
Select,
|
|
41
42
|
SelectContent,
|
|
@@ -91,8 +92,13 @@ function makeRows(count: number, prefix = "ATT"): Attendance[] {
|
|
|
91
92
|
date: `2026-06-${String((i % 28) + 1).padStart(2, "0")}`,
|
|
92
93
|
employee: NAMES[i % NAMES.length],
|
|
93
94
|
dept: DEPTS[i % DEPTS.length],
|
|
94
|
-
|
|
95
|
-
|
|
95
|
+
// `0${startHour}` hard-coded the leading zero and printed `010:07` at startHour 10 —
|
|
96
|
+
// the hand-built formatting this repo's own rules forbid. `padStart` on the hour, the
|
|
97
|
+
// same way the line above already does it for the date.
|
|
98
|
+
clockIn: `${String(startHour).padStart(2, "0")}:${["02", "58", "31", "07"][i % 4]}`,
|
|
99
|
+
clockOut: ot
|
|
100
|
+
? `${String(18 + Math.floor(ot / 60)).padStart(2, "0")}:${String(ot % 60).padStart(2, "0")}`
|
|
101
|
+
: "18:00",
|
|
96
102
|
overtime: ot,
|
|
97
103
|
status: statuses[i % statuses.length],
|
|
98
104
|
};
|
|
@@ -102,20 +108,38 @@ function makeRows(count: number, prefix = "ATT"): Attendance[] {
|
|
|
102
108
|
const minutesFmt = (m: number) => (m === 0 ? "—" : `${m}分`);
|
|
103
109
|
|
|
104
110
|
// Columns are shared between the cards (pure data — no per-card state inside).
|
|
111
|
+
/* EVERY column declares a width, not just the first (gh#849).
|
|
112
|
+
*
|
|
113
|
+
* Measured at 2000px before this, as empty pixels between one cell's ink and the next's:
|
|
114
|
+
*
|
|
115
|
+
* 部署 → 出勤 521 残業 → 状態 57
|
|
116
|
+
* 従業員 → 部署 411 勤務日 → 従業員 40
|
|
117
|
+
* 退勤 → 残業 280
|
|
118
|
+
*
|
|
119
|
+
* A 521px hole beside a 40px seam, in one row. Only `勤務日` carried a width, so
|
|
120
|
+
* `table-layout: auto` sized the rest from content and dumped ALL the slack of a 1952px card
|
|
121
|
+
* into the two free-text columns — and because those are start-aligned while the measures are
|
|
122
|
+
* end-aligned, the slack opened as craters BETWEEN columns rather than inside them.
|
|
123
|
+
*
|
|
124
|
+
* With a width on every column the engine distributes the excess proportionally instead, so the
|
|
125
|
+
* gaps scale together and no single one dominates. The numbers are a ratio, not a measurement:
|
|
126
|
+
* the two free-text columns get the larger share because they are the ones that actually wrap. */
|
|
105
127
|
const columns: ColumnDef<Attendance>[] = [
|
|
106
128
|
{ key: "date", header: "勤務日", width: "w-28" },
|
|
107
|
-
{ key: "employee", header: "従業員" },
|
|
108
|
-
{ key: "dept", header: "部署", hiddenOnMobile: true },
|
|
129
|
+
{ key: "employee", header: "従業員", width: "w-44" },
|
|
130
|
+
{ key: "dept", header: "部署", hiddenOnMobile: true, width: "w-36" },
|
|
109
131
|
{
|
|
110
132
|
key: "clockIn",
|
|
111
133
|
header: "出勤",
|
|
112
134
|
align: "right",
|
|
135
|
+
width: "w-24",
|
|
113
136
|
render: (row) => <Text tabular>{row.clockIn}</Text>,
|
|
114
137
|
},
|
|
115
138
|
{
|
|
116
139
|
key: "clockOut",
|
|
117
140
|
header: "退勤",
|
|
118
141
|
align: "right",
|
|
142
|
+
width: "w-24",
|
|
119
143
|
render: (row) => <Text tabular>{row.clockOut}</Text>,
|
|
120
144
|
},
|
|
121
145
|
{
|
|
@@ -123,12 +147,17 @@ const columns: ColumnDef<Attendance>[] = [
|
|
|
123
147
|
header: "残業",
|
|
124
148
|
align: "right",
|
|
125
149
|
hiddenOnMobile: true,
|
|
150
|
+
width: "w-24",
|
|
126
151
|
render: (row) => <Text tabular>{minutesFmt(row.overtime)}</Text>,
|
|
127
152
|
},
|
|
128
153
|
{
|
|
129
154
|
key: "status",
|
|
130
155
|
header: "状態",
|
|
131
|
-
|
|
156
|
+
/* END, not CENTER (gh#849). The status column carries the table's right edge; centring a
|
|
157
|
+
* ~90px pill in it put the badges 102px inboard while the header count, the column headers
|
|
158
|
+
* and the pagination all landed on 17px. */
|
|
159
|
+
align: "right",
|
|
160
|
+
width: "w-32",
|
|
132
161
|
render: (row) => <Badge status={row.status}>{STATUS_LABEL[row.status]}</Badge>,
|
|
133
162
|
},
|
|
134
163
|
];
|
|
@@ -138,6 +167,8 @@ const columns: ColumnDef<Attendance>[] = [
|
|
|
138
167
|
const NUMBERED_DATA = makeRows(83, "OFS");
|
|
139
168
|
|
|
140
169
|
function NumberedPaginationCard() {
|
|
170
|
+
const { t } = useTranslation();
|
|
171
|
+
const fmt = useFormatters();
|
|
141
172
|
const [page, setPage] = React.useState(2); // start mid-set so prev/next are both live
|
|
142
173
|
const [pageSize, setPageSize] = React.useState(10);
|
|
143
174
|
|
|
@@ -150,7 +181,7 @@ function NumberedPaginationCard() {
|
|
|
150
181
|
<CardTitle level={2}>番号付き + 件数選択</CardTitle>
|
|
151
182
|
<CardAction>
|
|
152
183
|
<Text size="xs" tone="muted" tabular>
|
|
153
|
-
|
|
184
|
+
{t("showcase.pagination.recordCount", { count: NUMBERED_DATA.length })}
|
|
154
185
|
</Text>
|
|
155
186
|
</CardAction>
|
|
156
187
|
</CardHeader>
|
|
@@ -164,7 +195,9 @@ function NumberedPaginationCard() {
|
|
|
164
195
|
pageSize={pageSize}
|
|
165
196
|
pageSizeOptions={[10, 20, 50]}
|
|
166
197
|
showSizeChanger
|
|
167
|
-
showTotal={(total, [from, to]) =>
|
|
198
|
+
showTotal={(total, [from, to]) =>
|
|
199
|
+
`${fmt.number(from)}–${fmt.number(to)} / ${t("showcase.pagination.recordCount", { count: total })}`
|
|
200
|
+
}
|
|
168
201
|
onValueChange={(nextPage, nextSize) => {
|
|
169
202
|
setPage(nextPage);
|
|
170
203
|
setPageSize(nextSize);
|
|
@@ -181,6 +214,8 @@ const LOADMORE_DATA = makeRows(42, "LDM");
|
|
|
181
214
|
const LOADMORE_STEP = 8;
|
|
182
215
|
|
|
183
216
|
function LoadMoreCard() {
|
|
217
|
+
const { t } = useTranslation();
|
|
218
|
+
const fmt = useFormatters();
|
|
184
219
|
// Mid-load state at rest: some rows already revealed, more remaining.
|
|
185
220
|
const [visible, setVisible] = React.useState(LOADMORE_STEP * 2);
|
|
186
221
|
const [loading, setLoading] = React.useState(false);
|
|
@@ -205,7 +240,8 @@ function LoadMoreCard() {
|
|
|
205
240
|
<CardTitle level={2}>もっと読む</CardTitle>
|
|
206
241
|
<CardAction>
|
|
207
242
|
<Text size="xs" tone="muted" tabular>
|
|
208
|
-
{rows.length} /
|
|
243
|
+
{fmt.number(rows.length)} /{" "}
|
|
244
|
+
{t("showcase.pagination.recordCount", { count: LOADMORE_DATA.length })}
|
|
209
245
|
</Text>
|
|
210
246
|
</CardAction>
|
|
211
247
|
</CardHeader>
|
|
@@ -225,11 +261,13 @@ function LoadMoreCard() {
|
|
|
225
261
|
{!done && <ChevronDown aria-hidden="true" />}
|
|
226
262
|
{done
|
|
227
263
|
? "すべて表示しました"
|
|
228
|
-
:
|
|
264
|
+
: t("showcase.pagination.loadMore", {
|
|
265
|
+
count: Math.min(LOADMORE_STEP, remaining),
|
|
266
|
+
})}
|
|
229
267
|
</Button>
|
|
230
268
|
{!done && (
|
|
231
269
|
<Text size="xs" tone="muted" tabular>
|
|
232
|
-
|
|
270
|
+
{t("showcase.pagination.recordCount", { count: remaining })}
|
|
233
271
|
</Text>
|
|
234
272
|
)}
|
|
235
273
|
</Flex>
|
|
@@ -242,11 +280,11 @@ function LoadMoreCard() {
|
|
|
242
280
|
|
|
243
281
|
// Time-series 勤怠 logs grouped by month — offset paging is meaningless here,
|
|
244
282
|
// so we use cursor first/next (DataTable.Pagination) + a period Select to jump.
|
|
245
|
-
|
|
246
|
-
|
|
247
|
-
|
|
248
|
-
|
|
249
|
-
] as const;
|
|
283
|
+
/* The VALUE is data; the LABEL is a formatting decision and belongs to the active locale.
|
|
284
|
+
* Hard-coded "2026年 6月" rendered beside the library's own "Đầu" / "Tiếp" — two languages in one
|
|
285
|
+
* row, which is what the owner photographed. `Intl.DateTimeFormat` gives 「2026年6月」, "June 2026"
|
|
286
|
+
* and "tháng 6 năm 2026" from the same value. */
|
|
287
|
+
const PERIODS = [{ value: "2026-06" }, { value: "2026-05" }, { value: "2026-04" }] as const;
|
|
250
288
|
|
|
251
289
|
const PERIOD_DATA: Record<string, Attendance[]> = {
|
|
252
290
|
"2026-06": makeRows(7, "CUR-06"),
|
|
@@ -255,6 +293,8 @@ const PERIOD_DATA: Record<string, Attendance[]> = {
|
|
|
255
293
|
};
|
|
256
294
|
|
|
257
295
|
function CursorPeriodCard() {
|
|
296
|
+
const { t } = useTranslation();
|
|
297
|
+
const fmt = useFormatters();
|
|
258
298
|
const [period, setPeriod] = React.useState<string>("2026-06");
|
|
259
299
|
// cursor === id of the last row of the previous page; undefined = first page.
|
|
260
300
|
const [cursor, setCursor] = React.useState<string | undefined>(undefined);
|
|
@@ -284,7 +324,7 @@ function CursorPeriodCard() {
|
|
|
284
324
|
<SelectContent>
|
|
285
325
|
{PERIODS.map((p) => (
|
|
286
326
|
<SelectItem key={p.value} value={p.value}>
|
|
287
|
-
{p.
|
|
327
|
+
{fmt.month(p.value)}
|
|
288
328
|
</SelectItem>
|
|
289
329
|
))}
|
|
290
330
|
</SelectContent>
|
|
@@ -294,10 +334,30 @@ function CursorPeriodCard() {
|
|
|
294
334
|
<CardContent flush>
|
|
295
335
|
<DataTable data={rows} columns={columns} getRowId={(row) => row.id} density="compact" />
|
|
296
336
|
</CardContent>
|
|
297
|
-
|
|
337
|
+
{/* `DataTable.Pagination` owns its own insets ON BOTH AXES, because it is normally the lone
|
|
338
|
+
* child of a FLUSH container. Here it shares a padded `CardContent` with the period label,
|
|
339
|
+
* so both stack.
|
|
340
|
+
*
|
|
341
|
+
* The first pass at this zeroed only the INLINE knob and declared it done — a two-axis
|
|
342
|
+
* defect fixed on one axis, which looks fixed from the side you were measuring. The block
|
|
343
|
+
* one kept stacking: 16px from the CardContent plus 7.36px of the slot's own, so this
|
|
344
|
+
* footer sat 27px off the last row while the other two cards sat at 20px.
|
|
345
|
+
*
|
|
346
|
+
* Zeroing both hands the insets to the container that already supplies them; that is what
|
|
347
|
+
* these knobs are for, and an instance override is the right tier for one element in one
|
|
348
|
+
* arrangement (docs/CUSTOMER-THEMING.md, tier 4). */}
|
|
349
|
+
<CardContent
|
|
350
|
+
className="border-t"
|
|
351
|
+
style={
|
|
352
|
+
{
|
|
353
|
+
"--table-pagination-padding-x": "0",
|
|
354
|
+
"--table-pagination-padding-y": "0",
|
|
355
|
+
} as React.CSSProperties
|
|
356
|
+
}
|
|
357
|
+
>
|
|
298
358
|
<Flex direction="row" align="center" justify="between" wrap gap="sm">
|
|
299
359
|
<Text size="xs" tone="muted" tabular>
|
|
300
|
-
{
|
|
360
|
+
{fmt.month(period)} · {t("showcase.pagination.recordCount", { count: all.length })}
|
|
301
361
|
</Text>
|
|
302
362
|
<DataTable.Pagination
|
|
303
363
|
cursor={lastVisibleId}
|
|
@@ -310,6 +370,27 @@ function CursorPeriodCard() {
|
|
|
310
370
|
);
|
|
311
371
|
}
|
|
312
372
|
|
|
373
|
+
/* COUNTS AND MONTHS FOLLOW THE ACTIVE LOCALE, and this page used to hard-code them.
|
|
374
|
+
*
|
|
375
|
+
* The library's own chrome is localized — the page-size Select renders "10 / trang" under `vi` —
|
|
376
|
+
* so a page that hard-codes `件` puts two languages in one row and they can never agree. That is
|
|
377
|
+
* exactly what the owner photographed: "11–20 / 83 件" beside "10 / trang".
|
|
378
|
+
*
|
|
379
|
+
* `Intl.NumberFormat` groups the number for the locale; the unit word comes from the library's own
|
|
380
|
+
* message catalogue, which already carries a CLDR plural map per language. Nothing here is a
|
|
381
|
+
* hand-built string. */
|
|
382
|
+
const useFormatters = () => {
|
|
383
|
+
const { locale } = useTranslation();
|
|
384
|
+
return React.useMemo(() => {
|
|
385
|
+
const number = new Intl.NumberFormat(locale);
|
|
386
|
+
const month = new Intl.DateTimeFormat(locale, { year: "numeric", month: "long" });
|
|
387
|
+
return {
|
|
388
|
+
number: (n: number) => number.format(n),
|
|
389
|
+
month: (iso: string) => month.format(new Date(`${iso}-01T00:00:00`)),
|
|
390
|
+
};
|
|
391
|
+
}, [locale]);
|
|
392
|
+
};
|
|
393
|
+
|
|
313
394
|
export default function Demo() {
|
|
314
395
|
return (
|
|
315
396
|
<PageContainer
|
|
@@ -302,7 +302,13 @@ export default function ThemeCustomizationShowcase() {
|
|
|
302
302
|
const [corner, setCorner] = React.useState("default");
|
|
303
303
|
const [custom, setCustom] = React.useState("#0F62FE");
|
|
304
304
|
const [regions, setRegions] = React.useState<string[]>(["JP", "VN"]);
|
|
305
|
-
|
|
305
|
+
/* UNBREAKABLE FIRST, ON PURPOSE (gh#840). With `maxTagCount={2}` the tag in third place is the
|
|
306
|
+
* one that collapses into `+N` — so while the 71-character id sat last, the chip that painted
|
|
307
|
+
* outside the control was never actually drawn on this page, and `maxTagTextLength` had nothing
|
|
308
|
+
* to demonstrate. Held first, the row now draws all three of the issue's answers at once: the
|
|
309
|
+
* long id truncated to its ceiling (full value in `title` and in the remover's name), a normal
|
|
310
|
+
* chip beside it, and a `+1` that names the tag behind it. */
|
|
311
|
+
const [labels, setLabels] = React.useState<string[]>([UNBREAKABLE, "本番", "ổn định"]);
|
|
306
312
|
const [plan, setPlan] = React.useState("standard");
|
|
307
313
|
const [channels, setChannels] = React.useState<string[]>(["email"]);
|
|
308
314
|
const [cadence, setCadence] = React.useState("weekly");
|
|
@@ -565,7 +571,19 @@ function ComponentsBoard(props: {
|
|
|
565
571
|
} = props;
|
|
566
572
|
|
|
567
573
|
return (
|
|
568
|
-
|
|
574
|
+
/* PADDED HERE, because nothing above this pads it (gh#841 follow-up). The board sits in
|
|
575
|
+
`<CardContent flush>` so the tab STRIP can meet the card edge — which is right, a line
|
|
576
|
+
variant's underline should run edge to edge — and `bodied` is a no-op on `variant="line"`
|
|
577
|
+
by design (`tabs.tsx`: `const bodiedCard = card && Boolean(bodied)`). So the body has no
|
|
578
|
+
inline inset from either side, and the form sat 1px from the card border: measured label
|
|
579
|
+
at x=25 against a card at x=24. `pad` on the board is the composition answer — the same
|
|
580
|
+
step `CardContent` would have used. */
|
|
581
|
+
<ResponsiveGrid
|
|
582
|
+
columns={{ base: 1, sm: 2, lg: 3 }}
|
|
583
|
+
gap="lg"
|
|
584
|
+
align="start"
|
|
585
|
+
pad={{ inline: "lg", block: "md" }}
|
|
586
|
+
>
|
|
569
587
|
{/* 1 · text entry */}
|
|
570
588
|
<Flex direction="col" gap="md">
|
|
571
589
|
<FormField
|
|
@@ -618,6 +636,11 @@ function ComponentsBoard(props: {
|
|
|
618
636
|
value={labels}
|
|
619
637
|
onValueChange={setLabels}
|
|
620
638
|
maxTagCount={2}
|
|
639
|
+
/* The ceiling the 71-character id is measured against (gh#840). 16 is the widest cut
|
|
640
|
+
that still leaves room for a second chip and the `+1` on one row at 375px; the value
|
|
641
|
+
is untouched — it stays in the chip's `title` and in the remover's accessible name,
|
|
642
|
+
which is the only reason truncating an identifier is allowed at all. */
|
|
643
|
+
maxTagTextLength={16}
|
|
621
644
|
placeholder={t("themeShowcase.form.labelsPlaceholder")}
|
|
622
645
|
/>
|
|
623
646
|
</FormField>
|
package/package.json
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@godxjp/ui",
|
|
3
|
-
"version": "28.
|
|
4
|
-
"godxUiMcp": "28.
|
|
3
|
+
"version": "28.12.0",
|
|
4
|
+
"godxUiMcp": "28.12.0",
|
|
5
5
|
"license": "Apache-2.0",
|
|
6
6
|
"repository": {
|
|
7
7
|
"type": "git",
|
|
@@ -23,6 +23,7 @@
|
|
|
23
23
|
"description": "@godxjp/ui — shared React UI framework (shadcn + Radix + Tailwind v4).",
|
|
24
24
|
"files": [
|
|
25
25
|
"LICENSE",
|
|
26
|
+
"agent",
|
|
26
27
|
"dist",
|
|
27
28
|
"scripts/ui-audit.mjs",
|
|
28
29
|
"README.md",
|
|
@@ -387,12 +388,12 @@
|
|
|
387
388
|
"gen:frame-coverage-ledger": "node scripts/gen-frame-coverage-ledger.mjs",
|
|
388
389
|
"gen:registry": "node scripts/gen-registry.mjs",
|
|
389
390
|
"init-agent": "node scripts/init-agent-kit.mjs",
|
|
390
|
-
"lint": "eslint .",
|
|
391
|
+
"lint": "eslint . --cache --cache-strategy content",
|
|
391
392
|
"lint:fix": "eslint . --fix",
|
|
392
393
|
"postinstall": "node scripts/postinstall.mjs",
|
|
393
394
|
"prepublishOnly": "pnpm run build",
|
|
394
395
|
"preview": "node preview/scripts/kill-port.mjs && vite --config preview/vite.config.ts --port 6008 --strictPort",
|
|
395
|
-
"preview:build": "vite build --config preview/vite.config.ts && node scripts/gen-registry.mjs",
|
|
396
|
+
"preview:build": "vite build --config preview/vite.config.ts && node scripts/gen-registry.mjs && node scripts/copy-agent-catalog.mjs",
|
|
396
397
|
"regen": "node scripts/regen-generated.mjs",
|
|
397
398
|
"release": "node scripts/release.mjs",
|
|
398
399
|
"ship:surface": "pnpm regen && pnpm verify:ci:static && pnpm check:frame-contracts",
|
|
@@ -413,13 +414,15 @@
|
|
|
413
414
|
"verify": "pnpm typecheck && pnpm lint && pnpm format && pnpm build && pnpm preview:build && pnpm check:example-imports && pnpm check:core-isolation && pnpm check:no-consumer-coupling && pnpm check:prop-vocabulary && pnpm check:token-tiers && pnpm check:token-width-wins && pnpm check:no-external-assets && pnpm check:token-scale-bypass && pnpm check:radix-surface && pnpm check:dist-tokens-resolve && pnpm check:no-hardcoded-geometry && pnpm check:no-hardcoded-css-values && pnpm check:disclosure-duplication && pnpm check:no-inline-magic-numbers && pnpm check:no-tailwind-class-assertions && pnpm check:control-sizing && pnpm check:rtl && pnpm check:typography && pnpm check:mcp-lockstep && pnpm check:mcp-sync && pnpm check:doc-prop-existence && pnpm check:mcp-catalog-coverage && pnpm check:mcp-orphans && pnpm check:mcp-pattern-imports && pnpm check:audit-sync && pnpm check:frame-coverage && pnpm test",
|
|
414
415
|
"verify:browser": "pnpm check:contrast && pnpm check:text-ink-clip && pnpm check:frame-overflow && pnpm check:font-fallback-metrics && pnpm check:visual-audit",
|
|
415
416
|
"verify:ci": "pnpm verify:ci:static && pnpm check:frame-contracts && pnpm test",
|
|
416
|
-
"verify:ci:static": "pnpm build && pnpm check:packed-public-contract && pnpm typecheck && pnpm typecheck:docs && pnpm lint && pnpm preview:build && pnpm check:registry && pnpm check:example-imports && pnpm check:core-isolation && pnpm check:no-consumer-coupling && pnpm check:use-client && pnpm check:prop-vocabulary && pnpm check:token-tiers && pnpm check:token-width-wins && pnpm check:no-external-assets && pnpm check:token-scale-bypass && pnpm check:no-antd-runtime && pnpm check:radix-surface && pnpm check:dist-tokens-resolve && pnpm check:no-hardcoded-geometry && pnpm check:no-hardcoded-css-values && pnpm check:disclosure-duplication && pnpm check:no-inline-magic-numbers && pnpm check:no-tailwind-class-assertions && pnpm check:control-sizing && pnpm check:rtl && pnpm check:typography && pnpm check:mcp-lockstep && pnpm check:measurement-contract && pnpm check:mcp-token-sync && pnpm check:email-token-sync && pnpm check:mcp-sync && pnpm check:doc-prop-existence && pnpm check:mcp-catalog-coverage && pnpm check:mcp-orphans && pnpm check:mcp-catalog-completeness && pnpm check:mcp-pattern-imports && pnpm check:audit-sync && pnpm run audit && pnpm check:frame-coverage-report && pnpm check:gate-coverage && pnpm check:mcp-prop-sync && pnpm check:catalog-contradictions && pnpm check:catalog-snippets && pnpm check:absorbed-names && pnpm check:agent-catalog",
|
|
417
|
+
"verify:ci:static:gates": "pnpm build && pnpm check:packed-public-contract && pnpm typecheck && pnpm typecheck:docs && pnpm lint && pnpm preview:build && pnpm check:registry && pnpm check:example-imports && pnpm check:core-isolation && pnpm check:no-consumer-coupling && pnpm check:use-client && pnpm check:prop-vocabulary && pnpm check:token-tiers && pnpm check:token-width-wins && pnpm check:no-external-assets && pnpm check:token-scale-bypass && pnpm check:no-antd-runtime && pnpm check:radix-surface && pnpm check:dist-tokens-resolve && pnpm check:no-hardcoded-geometry && pnpm check:no-hardcoded-css-values && pnpm check:disclosure-duplication && pnpm check:no-inline-magic-numbers && pnpm check:no-tailwind-class-assertions && pnpm check:control-sizing && pnpm check:rtl && pnpm check:typography && pnpm check:mcp-lockstep && pnpm check:measurement-contract && pnpm check:mcp-token-sync && pnpm check:email-token-sync && pnpm check:mcp-sync && pnpm check:doc-prop-existence && pnpm check:mcp-catalog-coverage && pnpm check:mcp-orphans && pnpm check:mcp-catalog-completeness && pnpm check:mcp-pattern-imports && pnpm check:audit-sync && pnpm run audit && pnpm check:frame-coverage-report && pnpm check:gate-coverage && pnpm check:mcp-prop-sync && pnpm check:catalog-contradictions && pnpm check:catalog-snippets && pnpm check:absorbed-names && pnpm check:agent-catalog",
|
|
418
|
+
"verify:ci:static": "node scripts/run-gate-list.mjs verify:ci:static:gates",
|
|
417
419
|
"verify:publish-tree": "pnpm build && pnpm check:packed-public-contract && pnpm check:use-client && pnpm check:dist-tokens-resolve",
|
|
418
420
|
"verify:release": "pnpm verify:static && pnpm check:frame-contracts && pnpm check:frame-coverage",
|
|
419
421
|
"verify:static": "pnpm build && pnpm check:packed-public-contract && pnpm typecheck && pnpm typecheck:docs && pnpm lint && pnpm preview:build && pnpm check:example-imports && pnpm check:core-isolation && pnpm check:no-consumer-coupling && pnpm check:use-client && pnpm check:prop-vocabulary && pnpm check:token-tiers && pnpm check:token-scale-bypass && pnpm check:radix-surface && pnpm check:dist-tokens-resolve && pnpm check:no-hardcoded-geometry && pnpm check:no-hardcoded-css-values && pnpm check:disclosure-duplication && pnpm check:no-inline-magic-numbers && pnpm check:no-tailwind-class-assertions && pnpm check:control-sizing && pnpm check:rtl && pnpm check:typography && pnpm check:mcp-lockstep && pnpm check:mcp-sync && pnpm check:doc-prop-existence && pnpm check:mcp-catalog-coverage && pnpm check:mcp-orphans && pnpm check:mcp-pattern-imports && pnpm check:audit-sync && pnpm check:mcp-prop-sync && pnpm check:contrast && pnpm check:visual-audit && pnpm test",
|
|
420
422
|
"visual-audit": "node scripts/visual-audit.mjs",
|
|
421
423
|
"gen:brand": "node scripts/gen-brand.mjs",
|
|
422
424
|
"check:absorbed-names": "node scripts/check-absorbed-names.mjs",
|
|
425
|
+
"check:control-glyph-tier": "node scripts/check-control-glyph-tier.mjs",
|
|
423
426
|
"check:frame-overflow": "node scripts/check-frame-overflow.mjs",
|
|
424
427
|
"check:frame-token-wins": "node scripts/check-frame-token-wins.mjs",
|
|
425
428
|
"check:frame-token-scope": "node scripts/check-frame-token-scope.mjs"
|