@godxjp/ui 19.6.0 → 20.1.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +8 -2
- package/dist/app/theme-axes.d.ts +2 -0
- package/dist/app/theme-axes.js +45 -0
- package/dist/components/charts/chart-cartesian.d.ts +2 -1
- package/dist/components/charts/chart-cartesian.js +52 -3
- package/dist/components/charts/chart-category-axis.d.ts +55 -0
- package/dist/components/charts/chart-category-axis.js +93 -0
- package/dist/components/charts/chart-frame.d.ts +10 -1
- package/dist/components/charts/chart-frame.js +19 -3
- package/dist/components/charts/compact-bar-trend.d.ts +1 -1
- package/dist/components/charts/compact-bar-trend.js +2 -0
- package/dist/components/charts/pie-chart.d.ts +1 -1
- package/dist/components/charts/pie-chart.js +12 -1
- package/dist/components/charts/recharts-peer.d.ts +49 -0
- package/dist/components/charts/recharts-peer.js +45 -0
- package/dist/components/data-display/card.d.ts +14 -3
- package/dist/components/data-display/card.js +22 -4
- package/dist/components/data-display/code-block.js +6 -2
- package/dist/components/data-display/collapsible.d.ts +23 -4
- package/dist/components/data-display/collapsible.js +119 -4
- package/dist/components/data-display/data-table.d.ts +39 -4
- package/dist/components/data-display/data-table.js +802 -270
- package/dist/components/data-display/descriptions.d.ts +27 -6
- package/dist/components/data-display/descriptions.js +58 -17
- package/dist/components/data-display/index.d.ts +5 -1
- package/dist/components/data-display/index.js +4 -0
- package/dist/components/data-display/legend.d.ts +15 -0
- package/dist/components/data-display/legend.js +11 -0
- package/dist/components/data-display/list-row.d.ts +10 -1
- package/dist/components/data-display/list-row.js +8 -2
- package/dist/components/data-display/popover.d.ts +60 -7
- package/dist/components/data-display/popover.js +268 -39
- package/dist/components/data-display/progress.d.ts +50 -2
- package/dist/components/data-display/progress.js +57 -9
- package/dist/components/data-display/range-timeline.d.ts +38 -0
- package/dist/components/data-display/range-timeline.js +161 -0
- package/dist/components/data-display/scroll-area.js +13 -2
- package/dist/components/data-display/service-launcher-card.js +10 -10
- package/dist/components/data-display/table.d.ts +11 -3
- package/dist/components/data-display/table.js +48 -18
- package/dist/components/data-display/tree-list.js +4 -9
- package/dist/components/data-entry/calendar.d.ts +2 -2
- package/dist/components/data-entry/calendar.js +79 -33
- package/dist/components/data-entry/cascader.d.ts +1 -1
- package/dist/components/data-entry/cascader.js +188 -24
- package/dist/components/data-entry/checkbox.d.ts +19 -6
- package/dist/components/data-entry/checkbox.js +55 -16
- package/dist/components/data-entry/choice-option.d.ts +1 -1
- package/dist/components/data-entry/color-picker.d.ts +1 -1
- package/dist/components/data-entry/color-picker.js +17 -5
- package/dist/components/data-entry/control-appearance.d.ts +64 -0
- package/dist/components/data-entry/control-appearance.js +39 -0
- package/dist/components/data-entry/control-surface.d.ts +61 -0
- package/dist/components/data-entry/control-surface.js +39 -0
- package/dist/components/data-entry/date-picker.d.ts +1 -1
- package/dist/components/data-entry/date-picker.js +344 -113
- package/dist/components/data-entry/date-range-picker.d.ts +2 -2
- package/dist/components/data-entry/date-range-picker.js +278 -140
- package/dist/components/data-entry/field.js +0 -1
- package/dist/components/data-entry/form-field.d.ts +1 -1
- package/dist/components/data-entry/form-field.js +39 -4
- package/dist/components/data-entry/form.d.ts +4 -0
- package/dist/components/data-entry/form.js +5 -3
- package/dist/components/data-entry/index.d.ts +7 -3
- package/dist/components/data-entry/index.js +10 -1
- package/dist/components/data-entry/input-otp.d.ts +1 -1
- package/dist/components/data-entry/input.d.ts +12 -34
- package/dist/components/data-entry/input.js +92 -24
- package/dist/components/data-entry/label.d.ts +3 -2
- package/dist/components/data-entry/label.js +23 -10
- package/dist/components/data-entry/month-picker.d.ts +2 -2
- package/dist/components/data-entry/month-picker.js +47 -10
- package/dist/components/data-entry/month-range-picker.d.ts +2 -2
- package/dist/components/data-entry/month-range-picker.js +51 -11
- package/dist/components/data-entry/number-input.d.ts +7 -0
- package/dist/components/data-entry/number-input.js +147 -98
- package/dist/components/data-entry/password-input.d.ts +1 -1
- package/dist/components/data-entry/radio.d.ts +1 -1
- package/dist/components/data-entry/radio.js +61 -13
- package/dist/components/data-entry/search-input.d.ts +1 -1
- package/dist/components/data-entry/search-input.js +16 -2
- package/dist/components/data-entry/search-select.d.ts +2 -2
- package/dist/components/data-entry/search-select.js +209 -78
- package/dist/components/data-entry/select.d.ts +22 -4
- package/dist/components/data-entry/select.js +215 -163
- package/dist/components/data-entry/slider.d.ts +9 -1
- package/dist/components/data-entry/slider.js +87 -9
- package/dist/components/data-entry/switch.d.ts +3 -0
- package/dist/components/data-entry/switch.js +29 -3
- package/dist/components/data-entry/textarea.d.ts +14 -56
- package/dist/components/data-entry/textarea.js +80 -33
- package/dist/components/data-entry/time-picker.d.ts +2 -2
- package/dist/components/data-entry/time-picker.js +333 -109
- package/dist/components/data-entry/time-range-picker.d.ts +5 -0
- package/dist/components/data-entry/time-range-picker.js +89 -0
- package/dist/components/data-entry/transfer.d.ts +1 -1
- package/dist/components/data-entry/transfer.js +99 -31
- package/dist/components/data-entry/tree-select-strategy.d.ts +1 -1
- package/dist/components/data-entry/tree-select.d.ts +1 -1
- package/dist/components/data-entry/tree-select.js +197 -92
- package/dist/components/data-entry/tree-utils.d.ts +1 -1
- package/dist/components/data-entry/tree-utils.js +7 -14
- package/dist/components/data-entry/upload-files.d.ts +2 -0
- package/dist/components/data-entry/upload-files.js +31 -0
- package/dist/components/data-entry/upload-request.d.ts +4 -0
- package/dist/components/data-entry/upload-request.js +53 -0
- package/dist/components/data-entry/upload-types.d.ts +28 -0
- package/dist/components/data-entry/upload-types.js +2 -0
- package/dist/components/data-entry/upload.d.ts +2 -2
- package/dist/components/data-entry/upload.js +482 -117
- package/dist/components/feedback/dialog.d.ts +105 -38
- package/dist/components/feedback/dialog.js +268 -193
- package/dist/components/feedback/overlay-close-focus.d.ts +31 -0
- package/dist/components/feedback/overlay-close-focus.js +31 -0
- package/dist/components/feedback/overlay-header-tone.d.ts +1 -1
- package/dist/components/feedback/sheet.d.ts +53 -11
- package/dist/components/feedback/sheet.js +150 -81
- package/dist/components/feedback/tooltip.d.ts +51 -7
- package/dist/components/feedback/tooltip.js +107 -25
- package/dist/components/general/button.d.ts +1 -1
- package/dist/components/general/button.js +7 -3
- package/dist/components/general/index.d.ts +1 -0
- package/dist/components/general/index.js +2 -0
- package/dist/components/general/logo.d.ts +17 -0
- package/dist/components/general/logo.js +22 -16
- package/dist/components/general/typography.d.ts +3 -0
- package/dist/components/general/typography.js +15 -1
- package/dist/components/general/visually-hidden.d.ts +3 -0
- package/dist/components/general/visually-hidden.js +9 -0
- package/dist/components/layout/app-launcher.d.ts +34 -0
- package/dist/components/layout/app-launcher.js +228 -0
- package/dist/components/layout/app-shell.d.ts +3 -1
- package/dist/components/layout/app-shell.js +69 -12
- package/dist/components/layout/aspect-ratio.js +0 -1
- package/dist/components/layout/auth-divider.js +0 -1
- package/dist/components/layout/breadcrumb.d.ts +14 -2
- package/dist/components/layout/breadcrumb.js +46 -4
- package/dist/components/layout/flex.d.ts +1 -1
- package/dist/components/layout/flex.js +41 -3
- package/dist/components/layout/index.d.ts +3 -0
- package/dist/components/layout/index.js +5 -1
- package/dist/components/layout/nav-surface.d.ts +26 -0
- package/dist/components/layout/nav-surface.js +17 -0
- package/dist/components/layout/org-switcher.d.ts +5 -1
- package/dist/components/layout/org-switcher.js +25 -4
- package/dist/components/layout/page-container.d.ts +1 -1
- package/dist/components/layout/page-container.js +5 -3
- package/dist/components/layout/responsive-grid.d.ts +16 -2
- package/dist/components/layout/responsive-grid.js +29 -2
- package/dist/components/layout/separator.js +0 -1
- package/dist/components/layout/sidebar.js +4 -1
- package/dist/components/layout/split-pane.d.ts +14 -1
- package/dist/components/layout/split-pane.js +26 -13
- package/dist/components/layout/topbar-item.d.ts +3 -0
- package/dist/components/layout/topbar-item.js +19 -5
- package/dist/components/layout/topbar.d.ts +1 -1
- package/dist/components/layout/topbar.js +27 -6
- package/dist/components/navigation/app-setting-picker.js +21 -2
- package/dist/components/navigation/app-setting-toggle.d.ts +16 -0
- package/dist/components/navigation/app-setting-toggle.js +96 -0
- package/dist/components/navigation/dropdown-menu.d.ts +227 -18
- package/dist/components/navigation/dropdown-menu.js +402 -118
- package/dist/components/navigation/index.d.ts +2 -0
- package/dist/components/navigation/index.js +2 -0
- package/dist/components/navigation/pagination-utils.d.ts +2 -1
- package/dist/components/navigation/pagination.d.ts +2 -2
- package/dist/components/navigation/pagination.js +155 -83
- package/dist/components/navigation/steps.d.ts +2 -2
- package/dist/components/navigation/steps.js +29 -4
- package/dist/components/navigation/tabs.d.ts +29 -16
- package/dist/components/navigation/tabs.js +374 -144
- package/dist/components/ui/accordion.d.ts +50 -5
- package/dist/components/ui/accordion.js +239 -33
- package/dist/components/ui/aspect-ratio.d.ts +23 -2
- package/dist/components/ui/aspect-ratio.js +15 -13
- package/dist/components/ui/avatar.d.ts +29 -4
- package/dist/components/ui/avatar.js +111 -25
- package/dist/components/ui/hover-card.d.ts +42 -4
- package/dist/components/ui/hover-card.js +183 -27
- package/dist/components/ui/input-otp.d.ts +26 -28
- package/dist/components/ui/input-otp.js +50 -7
- package/dist/components/ui/label.js +0 -1
- package/dist/components/ui/password-input.d.ts +36 -2
- package/dist/components/ui/password-input.js +27 -7
- package/dist/components/ui/rating.d.ts +25 -0
- package/dist/components/ui/rating.js +67 -27
- package/dist/components/ui/segmented.d.ts +12 -3
- package/dist/components/ui/segmented.js +17 -2
- package/dist/components/ui/separator.d.ts +12 -2
- package/dist/components/ui/separator.js +30 -9
- package/dist/components/ui/tag-input.d.ts +45 -0
- package/dist/components/ui/tag-input.js +109 -27
- package/dist/components/ui/toggle-group.d.ts +50 -5
- package/dist/components/ui/toggle-group.js +79 -20
- package/dist/components/ui/toggle.d.ts +31 -5
- package/dist/components/ui/toggle.js +42 -3
- package/dist/form/form-context.d.ts +29 -0
- package/dist/form/form-context.js +44 -4
- package/dist/form/form-field-array.d.ts +22 -0
- package/dist/form/form-field-array.js +50 -0
- package/dist/form/form-field-control.d.ts +2 -1
- package/dist/form/form-field-control.js +116 -40
- package/dist/form/form-root.d.ts +2 -1
- package/dist/form/form-root.js +142 -23
- package/dist/form/index.d.ts +3 -1
- package/dist/form/index.js +12 -1
- package/dist/i18n/messages/en.json +64 -5
- package/dist/i18n/messages/ja.json +64 -5
- package/dist/i18n/messages/vi.json +64 -5
- package/dist/inertia/index.d.ts +20 -0
- package/dist/inertia/index.js +60 -1
- package/dist/lib/control-styles.d.ts +25 -3
- package/dist/lib/control-styles.js +9 -3
- package/dist/lib/datetime/picker-format.d.ts +8 -0
- package/dist/lib/datetime/picker-format.js +54 -0
- package/dist/lib/slot.d.ts +32 -0
- package/dist/lib/slot.js +22 -0
- package/dist/lib/variants.d.ts +22 -3
- package/dist/lib/variants.js +56 -1
- package/dist/props/components/app.prop.d.ts +25 -1
- package/dist/props/components/charts.prop.d.ts +21 -0
- package/dist/props/components/data-display.prop.d.ts +72 -4
- package/dist/props/components/data-entry.prop.d.ts +718 -46
- package/dist/props/components/form.prop.d.ts +142 -4
- package/dist/props/components/general.prop.d.ts +17 -1
- package/dist/props/components/index.d.ts +3 -3
- package/dist/props/components/layout.prop.d.ts +281 -11
- package/dist/props/components/navigation.prop.d.ts +114 -4
- package/dist/props/registry.d.ts +397 -11
- package/dist/props/registry.js +526 -11
- package/dist/props/vocabulary/content.prop.d.ts +1 -1
- package/dist/props/vocabulary/data.prop.d.ts +179 -1
- package/dist/props/vocabulary/index.d.ts +5 -5
- package/dist/props/vocabulary/interaction.prop.d.ts +68 -3
- package/dist/props/vocabulary/layout.prop.d.ts +57 -1
- package/dist/props/vocabulary/navigation.prop.d.ts +40 -0
- package/dist/props/vocabulary/shared.prop.d.ts +33 -0
- package/dist/styles/badge-layout.css +2 -1
- package/dist/styles/card-layout.css +26 -4
- package/dist/styles/chart-layout.css +15 -0
- package/dist/styles/control.css +657 -15
- package/dist/styles/core.css +5 -2
- package/dist/styles/data-display-layout.css +313 -6
- package/dist/styles/data-entry-layout.css +13 -0
- package/dist/styles/focus-ring.css +4 -0
- package/dist/styles/index.css +5 -2
- package/dist/styles/layout.css +327 -4
- package/dist/styles/navigation-layout.css +227 -0
- package/dist/styles/shell-layout.css +369 -13
- package/dist/styles/table-layout.css +95 -6
- package/dist/styles/text-layout.css +10 -4
- package/dist/tokens/base.css +2 -1
- package/dist/tokens/components/badge.css +1 -0
- package/dist/tokens/components/chart.css +6 -0
- package/dist/tokens/components/control.css +79 -2
- package/dist/tokens/components/data-display.css +20 -0
- package/dist/tokens/components/descriptions.css +11 -0
- package/dist/tokens/components/flex.css +8 -0
- package/dist/tokens/components/navigation.css +55 -0
- package/dist/tokens/components/shell.css +53 -3
- package/dist/tokens/components/table.css +14 -0
- package/dist/tokens/foundation.css +2 -0
- package/dist/tokens/semantic/layout.css +9 -0
- package/docs/COMPONENTS.md +9 -3
- package/docs/CONSUMER-RULES.md +13 -0
- package/docs/DESIGN-AUTHORITY.md +145 -83
- package/docs/DEVELOPMENT.md +4 -3
- package/docs/FORMS.md +151 -6
- package/docs/FRAME-COVERAGE-REPORT.md +32 -17
- package/docs/README.md +15 -15
- package/docs/STANDARDS-vocabulary-tokens.md +1 -1
- package/docs/TESTING.md +15 -6
- package/docs/WHAT-BELONGS-HERE.md +179 -0
- package/docs/charts/cjk-category-axis.tsx +81 -0
- package/docs/data-display/card/index.tsx +22 -0
- package/docs/data-display/data-table/examples/antd-parity.tsx +257 -0
- package/docs/data-display/data-table/index.tsx +23 -0
- package/docs/data-display/descriptions.tsx +41 -0
- package/docs/data-display/legend.tsx +145 -0
- package/docs/data-display/progress.tsx +32 -0
- package/docs/data-display/scroll-area.tsx +31 -25
- package/docs/data-display/table.tsx +104 -45
- package/docs/data-display/timeline.tsx +41 -0
- package/docs/data-entry/date-picker.tsx +85 -0
- package/docs/data-entry/date-range-picker.tsx +26 -0
- package/docs/data-entry/form-dynamic-fields.tsx +199 -0
- package/docs/data-entry/form.tsx +74 -4
- package/docs/data-entry/input-otp.tsx +24 -0
- package/docs/data-entry/input.tsx +46 -1
- package/docs/data-entry/month-range-picker.tsx +1 -1
- package/docs/data-entry/segmented.tsx +1 -1
- package/docs/data-entry/select.tsx +29 -2
- package/docs/data-entry/switch.tsx +41 -0
- package/docs/data-entry/textarea.tsx +38 -0
- package/docs/data-entry/time-picker.tsx +85 -1
- package/docs/data-entry/time-range-picker.tsx +55 -0
- package/docs/data-entry/transfer.tsx +17 -0
- package/docs/data-entry/upload.tsx +56 -12
- package/docs/feedback/sheet.tsx +1 -1
- package/docs/feedback/tooltip.tsx +1 -1
- package/docs/general/activity.tsx +2 -2
- package/docs/general/button/index.tsx +14 -1
- package/docs/general/typography.tsx +14 -1
- package/docs/layout/app-launcher.tsx +151 -0
- package/docs/layout/app-shell-arrangements.tsx +225 -0
- package/docs/layout/app-shell.tsx +11 -0
- package/docs/layout/aspect-ratio.tsx +1 -1
- package/docs/layout/flex.tsx +50 -0
- package/docs/layout/responsive-grid.tsx +21 -1
- package/docs/layout/topbar.tsx +5 -9
- package/docs/navigation/app-setting-picker.tsx +37 -1
- package/docs/navigation/app-setting-toggle.tsx +111 -0
- package/docs/navigation/breadcrumb.tsx +48 -0
- package/docs/navigation/dropdown-menu.tsx +21 -0
- package/docs/navigation/pagination.tsx +52 -0
- package/docs/navigation/steps.tsx +37 -0
- package/docs/navigation/tabs.tsx +97 -1
- package/docs/query/button-refetch.tsx +1 -0
- package/package.json +28 -8
- package/scripts/_agent-setup.mjs +182 -3
- package/scripts/consumer-rule.md +98 -0
- package/scripts/guinea-pig-skill.md +322 -0
- package/scripts/init-guinea-pig.mjs +84 -0
- package/scripts/postinstall.mjs +13 -2
- package/scripts/ui-audit.mjs +351 -37
- /package/dist/tokens/{antd.generated.css → derived.css} +0 -0
|
@@ -235,6 +235,58 @@ export default function Demo() {
|
|
|
235
235
|
/>
|
|
236
236
|
</CardContent>
|
|
237
237
|
</Card>
|
|
238
|
+
|
|
239
|
+
{/* Ant Design parity surface — showQuickJumper / size / align / responsive */}
|
|
240
|
+
<Card>
|
|
241
|
+
<CardHeader>
|
|
242
|
+
<CardTitle level={2}>showQuickJumper · size · align (Ant Design パリティ)</CardTitle>
|
|
243
|
+
<CardDescription>
|
|
244
|
+
showQuickJumper はページ番号を直接入力するフィールド(Enter または goButton
|
|
245
|
+
で確定、範囲外はクランプ)。size="sm" はバーに --control-height
|
|
246
|
+
を一度だけ再束縛するので、ページボタン・サイズ変更・ジャンプ欄が同時に縮む。align
|
|
247
|
+
は論理軸(start / center / end)。responsive は既定で有効で、モバイル幅では simple
|
|
248
|
+
形態に畳む。
|
|
249
|
+
</CardDescription>
|
|
250
|
+
</CardHeader>
|
|
251
|
+
<CardContent>
|
|
252
|
+
<Flex direction="col" gap="lg">
|
|
253
|
+
<div id="antd-pagination-jumper">
|
|
254
|
+
<Pagination
|
|
255
|
+
ariaLabel="クイックジャンパー付きページネーション"
|
|
256
|
+
value={3}
|
|
257
|
+
total={95}
|
|
258
|
+
pageSize={10}
|
|
259
|
+
showTotal
|
|
260
|
+
showSizeChanger
|
|
261
|
+
showQuickJumper
|
|
262
|
+
onValueChange={() => {}}
|
|
263
|
+
/>
|
|
264
|
+
</div>
|
|
265
|
+
<div id="antd-pagination-sm">
|
|
266
|
+
<Pagination
|
|
267
|
+
ariaLabel="小サイズ・中央寄せのページネーション"
|
|
268
|
+
value={3}
|
|
269
|
+
total={95}
|
|
270
|
+
pageSize={10}
|
|
271
|
+
size="sm"
|
|
272
|
+
align="center"
|
|
273
|
+
showQuickJumper={{ goButton: "移動" }}
|
|
274
|
+
onValueChange={() => {}}
|
|
275
|
+
/>
|
|
276
|
+
</div>
|
|
277
|
+
<div id="antd-pagination-start">
|
|
278
|
+
<Pagination
|
|
279
|
+
ariaLabel="先頭寄せのページネーション"
|
|
280
|
+
value={3}
|
|
281
|
+
total={95}
|
|
282
|
+
pageSize={10}
|
|
283
|
+
align="start"
|
|
284
|
+
onValueChange={() => {}}
|
|
285
|
+
/>
|
|
286
|
+
</div>
|
|
287
|
+
</Flex>
|
|
288
|
+
</CardContent>
|
|
289
|
+
</Card>
|
|
238
290
|
</Flex>
|
|
239
291
|
</PageContainer>
|
|
240
292
|
);
|
|
@@ -259,6 +259,43 @@ export default function Demo() {
|
|
|
259
259
|
</Flex>
|
|
260
260
|
</CardContent>
|
|
261
261
|
</Card>
|
|
262
|
+
|
|
263
|
+
{/* Ant Design parity surface — percent + navigation */}
|
|
264
|
+
<Card>
|
|
265
|
+
<CardHeader>
|
|
266
|
+
<CardTitle level={2}>percent · navigation (Ant Design パリティ)</CardTitle>
|
|
267
|
+
<CardDescription>
|
|
268
|
+
percent は antd と同じく「現在ステップ」の進捗のみ(0–100
|
|
269
|
+
にクランプ)。マーカーの周りに確定アークを描き、role="progressbar"
|
|
270
|
+
として読み上げられる。type="navigation" は antd
|
|
271
|
+
のスラブ型ナビゲーションバーで、既定のヘアライン
|
|
272
|
+
コネクタは切られ、代わりにシェブロンで繋がる。
|
|
273
|
+
</CardDescription>
|
|
274
|
+
</CardHeader>
|
|
275
|
+
<CardContent>
|
|
276
|
+
<Flex direction="col" gap="lg">
|
|
277
|
+
<div id="antd-steps-percent">
|
|
278
|
+
<Steps
|
|
279
|
+
value={1}
|
|
280
|
+
percent={40}
|
|
281
|
+
items={[{ title: "申込" }, { title: "審査" }, { title: "完了" }]}
|
|
282
|
+
/>
|
|
283
|
+
</div>
|
|
284
|
+
<div id="antd-steps-navigation">
|
|
285
|
+
<Steps
|
|
286
|
+
type="navigation"
|
|
287
|
+
value={1}
|
|
288
|
+
onValueChange={() => {}}
|
|
289
|
+
items={[
|
|
290
|
+
{ title: "申込", description: "受付済" },
|
|
291
|
+
{ title: "審査", description: "書類確認中" },
|
|
292
|
+
{ title: "完了", description: "未着手" },
|
|
293
|
+
]}
|
|
294
|
+
/>
|
|
295
|
+
</div>
|
|
296
|
+
</Flex>
|
|
297
|
+
</CardContent>
|
|
298
|
+
</Card>
|
|
262
299
|
</Flex>
|
|
263
300
|
</PageContainer>
|
|
264
301
|
);
|
package/docs/navigation/tabs.tsx
CHANGED
|
@@ -46,6 +46,17 @@ const journalItems = [
|
|
|
46
46
|
|
|
47
47
|
export default function Demo() {
|
|
48
48
|
const [activeTab, setActiveTab] = useState("pending");
|
|
49
|
+
const [editableTabs, setEditableTabs] = useState([
|
|
50
|
+
{ value: "je-0042", label: "JE-0042", content: <Text as="p">売上計上 ¥480,000</Text> },
|
|
51
|
+
{ value: "je-0043", label: "JE-0043", content: <Text as="p">仕入計上 ¥120,000</Text> },
|
|
52
|
+
{
|
|
53
|
+
value: "je-0040",
|
|
54
|
+
label: "JE-0040 (固定)",
|
|
55
|
+
content: <Text as="p">給与支払 ¥2,800,000</Text>,
|
|
56
|
+
closable: false,
|
|
57
|
+
},
|
|
58
|
+
]);
|
|
59
|
+
const [editableTab, setEditableTab] = useState("je-0042");
|
|
49
60
|
|
|
50
61
|
return (
|
|
51
62
|
<PageContainer
|
|
@@ -106,7 +117,7 @@ export default function Demo() {
|
|
|
106
117
|
<CardTitle level={2}>320px stress · 長いローカライズラベル</CardTitle>
|
|
107
118
|
<CardDescription>
|
|
108
119
|
狭いコンテナでも長いラベルはクリップされず、水平タブリストが自身でスクロールする
|
|
109
|
-
。compact navigation への変換は Tabs API に存在しないため擬似実装しない
|
|
120
|
+
。compact navigation への変換は Tabs API に存在しないため擬似実装しない ·
|
|
110
121
|
スクロールが意図した縮退動作。
|
|
111
122
|
</CardDescription>
|
|
112
123
|
</CardHeader>
|
|
@@ -308,6 +319,91 @@ export default function Demo() {
|
|
|
308
319
|
</Flex>
|
|
309
320
|
</CardContent>
|
|
310
321
|
</Card>
|
|
322
|
+
|
|
323
|
+
{/* Ant Design parity surface — editable-card + extra + centered + placement + size */}
|
|
324
|
+
<Card>
|
|
325
|
+
<CardHeader>
|
|
326
|
+
<CardTitle level={2}>Editable card · onEdit / extra / hideAdd</CardTitle>
|
|
327
|
+
<CardDescription>
|
|
328
|
+
variant="editable-card" は Ant Design の editable-card。タブ内の ×
|
|
329
|
+
はポインタ用ショートカット(aria-hidden)で、キーボードでは Delete /
|
|
330
|
+
Backspace(aria-keyshortcuts)。追加ボタンは tablist の外にある本物の button。extra は
|
|
331
|
+
antd の tabBarExtraContent を論理軸(start / end)にしたもの。
|
|
332
|
+
</CardDescription>
|
|
333
|
+
</CardHeader>
|
|
334
|
+
<CardContent>
|
|
335
|
+
<Tabs
|
|
336
|
+
id="antd-editable-card"
|
|
337
|
+
variant="editable-card"
|
|
338
|
+
value={editableTab}
|
|
339
|
+
onValueChange={setEditableTab}
|
|
340
|
+
onEdit={(target, action) => {
|
|
341
|
+
if (action === "add") {
|
|
342
|
+
const next = `tab-${editableTabs.length + 1}`;
|
|
343
|
+
setEditableTabs([
|
|
344
|
+
...editableTabs,
|
|
345
|
+
{
|
|
346
|
+
value: next,
|
|
347
|
+
label: `新規 ${editableTabs.length + 1}`,
|
|
348
|
+
content: <Text as="p">新規タブ {next}</Text>,
|
|
349
|
+
},
|
|
350
|
+
]);
|
|
351
|
+
setEditableTab(next);
|
|
352
|
+
return;
|
|
353
|
+
}
|
|
354
|
+
const rest = editableTabs.filter((item) => item.value !== target);
|
|
355
|
+
setEditableTabs(rest);
|
|
356
|
+
if (target === editableTab && rest[0]) setEditableTab(rest[0].value);
|
|
357
|
+
}}
|
|
358
|
+
extra={{
|
|
359
|
+
end: (
|
|
360
|
+
<Button size="sm" variant="outline">
|
|
361
|
+
一括操作
|
|
362
|
+
</Button>
|
|
363
|
+
),
|
|
364
|
+
}}
|
|
365
|
+
items={editableTabs}
|
|
366
|
+
/>
|
|
367
|
+
</CardContent>
|
|
368
|
+
</Card>
|
|
369
|
+
|
|
370
|
+
<Card>
|
|
371
|
+
<CardHeader>
|
|
372
|
+
<CardTitle level={2}>tabPlacement · size · centered</CardTitle>
|
|
373
|
+
<CardDescription>
|
|
374
|
+
tabPlacement は antd 6.6.2 の名前で、値は論理軸(top / bottom / start / end)。start /
|
|
375
|
+
end は tablist を縦方向のロービングフォーカスに切り替える。size はライブラリの control
|
|
376
|
+
band(sm / md / lg)に対応。
|
|
377
|
+
</CardDescription>
|
|
378
|
+
</CardHeader>
|
|
379
|
+
<CardContent>
|
|
380
|
+
<Flex direction="col" gap="lg">
|
|
381
|
+
<Tabs
|
|
382
|
+
id="antd-centered"
|
|
383
|
+
defaultValue="pending"
|
|
384
|
+
variant="line"
|
|
385
|
+
centered
|
|
386
|
+
items={journalItems}
|
|
387
|
+
/>
|
|
388
|
+
<Tabs
|
|
389
|
+
id="antd-bottom"
|
|
390
|
+
defaultValue="pending"
|
|
391
|
+
variant="card"
|
|
392
|
+
tabPlacement="bottom"
|
|
393
|
+
size="sm"
|
|
394
|
+
items={journalItems}
|
|
395
|
+
/>
|
|
396
|
+
<Tabs
|
|
397
|
+
id="antd-start"
|
|
398
|
+
defaultValue="pending"
|
|
399
|
+
variant="line"
|
|
400
|
+
tabPlacement="start"
|
|
401
|
+
size="lg"
|
|
402
|
+
items={journalItems}
|
|
403
|
+
/>
|
|
404
|
+
</Flex>
|
|
405
|
+
</CardContent>
|
|
406
|
+
</Card>
|
|
311
407
|
</Flex>
|
|
312
408
|
</PageContainer>
|
|
313
409
|
);
|
|
@@ -81,6 +81,7 @@ function VariantBlock() {
|
|
|
81
81
|
<ButtonRefetch query={query} variant="ghost" label="ghost" />
|
|
82
82
|
<ButtonRefetch query={query} variant="destructive" label="destructive" />
|
|
83
83
|
<ButtonRefetch query={query} variant="link" label="link" />
|
|
84
|
+
<ButtonRefetch query={query} variant="bare" label="bare" />
|
|
84
85
|
</Flex>
|
|
85
86
|
</CardContent>
|
|
86
87
|
</Card>
|
package/package.json
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@godxjp/ui",
|
|
3
|
-
"version": "
|
|
4
|
-
"godxUiMcp": "
|
|
3
|
+
"version": "20.1.0",
|
|
4
|
+
"godxUiMcp": "20.1.0",
|
|
5
5
|
"license": "Apache-2.0",
|
|
6
6
|
"repository": {
|
|
7
7
|
"type": "git",
|
|
@@ -30,6 +30,9 @@
|
|
|
30
30
|
"scripts/visual-audit-rules.mjs",
|
|
31
31
|
"scripts/audit-hook.mjs",
|
|
32
32
|
"scripts/init-agent-kit.mjs",
|
|
33
|
+
"scripts/init-guinea-pig.mjs",
|
|
34
|
+
"scripts/guinea-pig-skill.md",
|
|
35
|
+
"scripts/consumer-rule.md",
|
|
33
36
|
"scripts/postinstall.mjs",
|
|
34
37
|
"scripts/_agent-setup.mjs",
|
|
35
38
|
"scripts/cli.mjs",
|
|
@@ -82,6 +85,22 @@
|
|
|
82
85
|
"types": "./dist/components/charts/compact-bar-trend.d.ts",
|
|
83
86
|
"import": "./dist/components/charts/compact-bar-trend.js"
|
|
84
87
|
},
|
|
88
|
+
"./charts/line-chart": {
|
|
89
|
+
"types": "./dist/components/charts/line-chart.d.ts",
|
|
90
|
+
"import": "./dist/components/charts/line-chart.js"
|
|
91
|
+
},
|
|
92
|
+
"./charts/bar-chart": {
|
|
93
|
+
"types": "./dist/components/charts/bar-chart.d.ts",
|
|
94
|
+
"import": "./dist/components/charts/bar-chart.js"
|
|
95
|
+
},
|
|
96
|
+
"./charts/area-chart": {
|
|
97
|
+
"types": "./dist/components/charts/area-chart.d.ts",
|
|
98
|
+
"import": "./dist/components/charts/area-chart.js"
|
|
99
|
+
},
|
|
100
|
+
"./charts/pie-chart": {
|
|
101
|
+
"types": "./dist/components/charts/pie-chart.d.ts",
|
|
102
|
+
"import": "./dist/components/charts/pie-chart.js"
|
|
103
|
+
},
|
|
85
104
|
"./ui": {
|
|
86
105
|
"types": "./dist/components/ui/index.d.ts",
|
|
87
106
|
"import": "./dist/components/ui/index.js"
|
|
@@ -308,10 +327,12 @@
|
|
|
308
327
|
"format": "prettier --check .",
|
|
309
328
|
"format:fix": "prettier --write .",
|
|
310
329
|
"test": "vitest run",
|
|
330
|
+
"test:manual": "vitest run --config vitest.manual.config.ts",
|
|
311
331
|
"test:visual:auth-login": "node scripts/auth-shell-login-visual.mjs",
|
|
312
332
|
"test:visual:auth-registration": "node scripts/auth-shell-registration-visual.mjs",
|
|
313
333
|
"test:visual:topbar-collision": "node scripts/topbar-collision-visual.mjs",
|
|
314
334
|
"test:visual:table-collection-cjk": "node scripts/table-collection-cjk-visual.mjs",
|
|
335
|
+
"test:visual:chart-cjk-axis": "node scripts/chart-cjk-axis-visual.mjs",
|
|
315
336
|
"test:watch": "vitest",
|
|
316
337
|
"test:coverage": "vitest run --coverage",
|
|
317
338
|
"check:example-imports": "node scripts/check-example-imports.mjs",
|
|
@@ -335,8 +356,8 @@
|
|
|
335
356
|
"check:frame-runtime": "pnpm check:data-entry-frame-runtime && pnpm check:data-entry-touch-aria && pnpm check:layout-nav-frames && pnpm check:provider-feedback-query-runtime && pnpm check:layout-nav-closure && pnpm check:final-touch-rtl && pnpm check:data-table-pagination-wrap && pnpm check:button-icon-xs",
|
|
336
357
|
"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:no-external-assets && pnpm check:token-scale-bypass && pnpm check:dist-tokens-resolve && pnpm check:no-hardcoded-geometry && pnpm check:no-hardcoded-css-values && 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",
|
|
337
358
|
"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:dist-tokens-resolve && pnpm check:no-hardcoded-geometry && pnpm check:no-hardcoded-css-values && 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",
|
|
338
|
-
"verify:ci": "pnpm
|
|
339
|
-
"verify:ci: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:no-external-assets && pnpm check:token-scale-bypass && pnpm check:dist-tokens-resolve && pnpm check:no-hardcoded-geometry && pnpm check:no-hardcoded-css-values && 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",
|
|
359
|
+
"verify:ci": "pnpm verify:ci:static && pnpm check:frame-contracts && pnpm test",
|
|
360
|
+
"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:no-external-assets && pnpm check:token-scale-bypass && pnpm check:no-antd-runtime && pnpm check:dist-tokens-resolve && pnpm check:no-hardcoded-geometry && pnpm check:no-hardcoded-css-values && 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:gate-coverage && pnpm check:mcp-prop-sync",
|
|
340
361
|
"verify:browser": "pnpm check:contrast && pnpm check:visual-audit",
|
|
341
362
|
"verify:release": "pnpm verify:static && pnpm check:frame-contracts && pnpm check:frame-coverage && pnpm check:frame-axe",
|
|
342
363
|
"verify:publish-tree": "pnpm build && pnpm check:packed-public-contract && pnpm check:use-client && pnpm check:dist-tokens-resolve",
|
|
@@ -365,9 +386,6 @@
|
|
|
365
386
|
"check:rtl": "node scripts/check-rtl.mjs",
|
|
366
387
|
"check:typography": "node scripts/check-typography.mjs",
|
|
367
388
|
"gen:component-tokens": "node scripts/gen-component-tokens.mjs",
|
|
368
|
-
"gen:antd-tokens": "node scripts/gen-antd-tokens.mjs",
|
|
369
|
-
"check:antd-tokens": "node scripts/gen-antd-tokens.mjs --check",
|
|
370
|
-
"report:antd-tokens": "node scripts/gen-antd-tokens.mjs --report",
|
|
371
389
|
"check:no-antd-runtime": "node scripts/check-no-antd-runtime.mjs",
|
|
372
390
|
"gen:email-tokens": "node scripts/gen-email-tokens.mjs",
|
|
373
391
|
"check:core-isolation": "node scripts/check-core-isolation.mjs",
|
|
@@ -384,6 +402,7 @@
|
|
|
384
402
|
"dev": "node scripts/dev.mjs",
|
|
385
403
|
"prepublishOnly": "pnpm run build",
|
|
386
404
|
"check:audit-sync": "node scripts/check-audit-sync.mjs",
|
|
405
|
+
"check:gate-coverage": "node scripts/check-gate-coverage.mjs",
|
|
387
406
|
"check:contrast": "node scripts/check-contrast.mjs",
|
|
388
407
|
"visual-audit": "node scripts/visual-audit.mjs",
|
|
389
408
|
"check:visual-audit": "node scripts/visual-audit-smoke.mjs",
|
|
@@ -451,6 +470,7 @@
|
|
|
451
470
|
"@radix-ui/react-toggle": "^1.1.18",
|
|
452
471
|
"@radix-ui/react-toggle-group": "^1.1.19",
|
|
453
472
|
"@radix-ui/react-tooltip": "^1.2.16",
|
|
473
|
+
"@react-aria/utils": "^3.34.1",
|
|
454
474
|
"@tanstack/react-table": "^9.2.4",
|
|
455
475
|
"class-variance-authority": "^0.7.1",
|
|
456
476
|
"clsx": "^2.1.1",
|
|
@@ -460,6 +480,7 @@
|
|
|
460
480
|
"input-otp": "^1.5.0",
|
|
461
481
|
"lucide-react": "^1.37.0",
|
|
462
482
|
"qrcode.react": "4.2.0",
|
|
483
|
+
"react-aria-components": "^1.21.1",
|
|
463
484
|
"react-day-picker": "^10.0.1",
|
|
464
485
|
"react-resizable-panels": "^4.12.3",
|
|
465
486
|
"sonner": "^2.0.8",
|
|
@@ -483,7 +504,6 @@
|
|
|
483
504
|
"@types/react-dom": "^19.2.5",
|
|
484
505
|
"@vitejs/plugin-react": "^6.1.1",
|
|
485
506
|
"@vitest/coverage-v8": "^4.1.11",
|
|
486
|
-
"antd": "6.6.2",
|
|
487
507
|
"axe-core": "^4.13.0",
|
|
488
508
|
"eslint": "^10.9.1",
|
|
489
509
|
"eslint-plugin-react": "^7.37.5",
|
package/scripts/_agent-setup.mjs
CHANGED
|
@@ -4,10 +4,15 @@
|
|
|
4
4
|
* NON-DESTRUCTIVE: it only creates a missing file or ADDS a missing key, never
|
|
5
5
|
* overwrites existing config.
|
|
6
6
|
*/
|
|
7
|
+
import { createHash } from "node:crypto";
|
|
7
8
|
import { existsSync, mkdirSync, readFileSync, writeFileSync } from "node:fs";
|
|
8
9
|
import { dirname, join } from "node:path";
|
|
10
|
+
import { fileURLToPath } from "node:url";
|
|
9
11
|
|
|
10
12
|
/** The godxjp-ui MCP server — pulled on demand via npx (no extra dependency to ship). */
|
|
13
|
+
/** This package's own root — the source of the version we stamp with. */
|
|
14
|
+
const SELF_ROOT = join(dirname(fileURLToPath(import.meta.url)), "..");
|
|
15
|
+
|
|
11
16
|
export const MCP_SERVER = { command: "npx", args: ["@godxjp/ui-mcp"] };
|
|
12
17
|
export const MCP_KEY = "godx-ui";
|
|
13
18
|
|
|
@@ -16,7 +21,47 @@ export const AUDIT_HOOK_CMD = "node node_modules/@godxjp/ui/scripts/audit-hook.m
|
|
|
16
21
|
export const PRIMER_CMD = "cat .claude/godxjp-ui-workflow.md";
|
|
17
22
|
|
|
18
23
|
/** The per-session workflow mandate the SessionStart hook injects into the agent. */
|
|
19
|
-
export const
|
|
24
|
+
export const KIT_VERSION = readJson(join(SELF_ROOT, "package.json"))?.version ?? "0.0.0";
|
|
25
|
+
|
|
26
|
+
const STAMP = (v) => `<!-- godxjp-ui:version ${v} -->`;
|
|
27
|
+
const STAMP_RE = /<!-- godxjp-ui:version ([^\s]+) -->/;
|
|
28
|
+
|
|
29
|
+
/** The version stamped in `text`, or null when it predates stamping. */
|
|
30
|
+
export function stampedVersion(text) {
|
|
31
|
+
return text?.match(STAMP_RE)?.[1] ?? null;
|
|
32
|
+
}
|
|
33
|
+
|
|
34
|
+
/**
|
|
35
|
+
* A stamp that tracks the CONTENT, for the files this package owns outright.
|
|
36
|
+
*
|
|
37
|
+
* A version stamp answers "which release wrote this", which is the wrong question for a file whose
|
|
38
|
+
* whole job is to carry current guidance. Measured: editing `consumer-rule.md` without bumping the
|
|
39
|
+
* package left two of three consumers holding the previous text, with a stamp that read as current
|
|
40
|
+
* and nothing anywhere reporting a difference. The rules are edited far more often than the
|
|
41
|
+
* version moves — most of all while they are being written, which is exactly when a stale copy
|
|
42
|
+
* does the most damage.
|
|
43
|
+
*
|
|
44
|
+
* So the digest goes in alongside the version: the version stays for humans reading the file, and
|
|
45
|
+
* the digest is what the refresh actually compares. Identical body → still a no-op.
|
|
46
|
+
*/
|
|
47
|
+
const DIGEST_RE = /<!-- godxjp-ui:digest ([0-9a-f]{12}) -->/;
|
|
48
|
+
const digestOf = (body) => createHash("sha256").update(body).digest("hex").slice(0, 12);
|
|
49
|
+
const OWNED_STAMP = (body) => `${STAMP(KIT_VERSION)}\n<!-- godxjp-ui:digest ${digestOf(body)} -->`;
|
|
50
|
+
|
|
51
|
+
/** The content digest stamped in `text`, or null when it predates digest stamping. */
|
|
52
|
+
export function stampedDigest(text) {
|
|
53
|
+
return text?.match(DIGEST_RE)?.[1] ?? null;
|
|
54
|
+
}
|
|
55
|
+
|
|
56
|
+
/**
|
|
57
|
+
* Replace the MANAGED region of a file and leave everything else alone.
|
|
58
|
+
*
|
|
59
|
+
* Refreshing is only safe if it cannot eat hand-written content, so the contract is narrow: the
|
|
60
|
+
* region is delimited, and anything outside the delimiters survives byte-for-byte. A consumer that
|
|
61
|
+
* appended repo-specific sections keeps them.
|
|
62
|
+
*/
|
|
63
|
+
export const WORKFLOW_MD = `${STAMP(KIT_VERSION)}
|
|
64
|
+
# @godxjp/ui — mandatory workflow (read every session)
|
|
20
65
|
|
|
21
66
|
You are building UI in an app that uses @godxjp/ui. Follow this EVERY time you create
|
|
22
67
|
or change a component, page, or form — no exceptions.
|
|
@@ -50,6 +95,7 @@ or change a component, page, or form — no exceptions.
|
|
|
50
95
|
/** Delimited block appended to the consumer's CLAUDE.md — loaded into the agent's context
|
|
51
96
|
* every turn (the most reliable "ensure it reads the rules"). Markers keep it idempotent. */
|
|
52
97
|
export const CLAUDE_MD_BLOCK = `<!-- godxjp-ui:start (managed by @godxjp/ui — edit .claude/godxjp-ui-workflow.md instead) -->
|
|
98
|
+
${STAMP(KIT_VERSION)}
|
|
53
99
|
## @godxjp/ui — mandatory UI workflow (do NOT skip)
|
|
54
100
|
|
|
55
101
|
This app uses @godxjp/ui. EVERY time you build or change UI:
|
|
@@ -82,6 +128,24 @@ function readJson(path) {
|
|
|
82
128
|
}
|
|
83
129
|
|
|
84
130
|
/** Ensure `.mcp.json` registers the godx-ui MCP server. Returns 'created' | 'added' | 'present'. */
|
|
131
|
+
/**
|
|
132
|
+
* The version that wrote each managed artefact, stamped so `postinstall` can tell "already there"
|
|
133
|
+
* apart from "already there and STALE".
|
|
134
|
+
*
|
|
135
|
+
* Everything below used to be install-once: `ensureMcpJson` returned early on a present key,
|
|
136
|
+
* `writeWorkflowMd` on a present file, `ensureClaudeMd` on a present marker. So `npm update
|
|
137
|
+
* @godxjp/ui` brought new components, new audit rules and new catalog entries — and left the
|
|
138
|
+
* agent reading whatever guidance shipped the day the package was FIRST installed. The library
|
|
139
|
+
* moved; the instructions for using it did not.
|
|
140
|
+
*/
|
|
141
|
+
export function refreshBlock(current, next, startMarker, endMarker) {
|
|
142
|
+
const i = current.indexOf(startMarker);
|
|
143
|
+
if (i < 0) return current.replace(/\s*$/, "") + "\n\n" + next;
|
|
144
|
+
const j = endMarker ? current.indexOf(endMarker, i) : -1;
|
|
145
|
+
const tail = j < 0 ? "" : current.slice(j + endMarker.length);
|
|
146
|
+
return current.slice(0, i) + next + tail;
|
|
147
|
+
}
|
|
148
|
+
|
|
85
149
|
export function ensureMcpJson(root) {
|
|
86
150
|
const path = join(root, ".mcp.json");
|
|
87
151
|
const json = readJson(path) ?? {};
|
|
@@ -127,7 +191,14 @@ export function ensureClaudeHooks(root) {
|
|
|
127
191
|
export function writeWorkflowMd(root) {
|
|
128
192
|
const path = join(root, ".claude", "godxjp-ui-workflow.md");
|
|
129
193
|
mkdirSync(dirname(path), { recursive: true });
|
|
130
|
-
|
|
194
|
+
// This file is owned entirely by the package — the CLAUDE.md block tells the consumer to edit
|
|
195
|
+
// it, but nothing else reads from it, so a stale copy is pure loss. Rewrite when the stamp moves.
|
|
196
|
+
if (existsSync(path)) {
|
|
197
|
+
const cur = readFileSync(path, "utf8");
|
|
198
|
+
if (stampedVersion(cur) === KIT_VERSION) return false;
|
|
199
|
+
writeFileSync(path, WORKFLOW_MD);
|
|
200
|
+
return "refreshed";
|
|
201
|
+
}
|
|
131
202
|
writeFileSync(path, WORKFLOW_MD);
|
|
132
203
|
return true;
|
|
133
204
|
}
|
|
@@ -139,7 +210,16 @@ export function writeWorkflowMd(root) {
|
|
|
139
210
|
export function ensureClaudeMd(root) {
|
|
140
211
|
const path = join(root, "CLAUDE.md");
|
|
141
212
|
const existing = existsSync(path) ? readFileSync(path, "utf8") : null;
|
|
142
|
-
if (existing?.includes("godxjp-ui:start"))
|
|
213
|
+
if (existing?.includes("godxjp-ui:start")) {
|
|
214
|
+
// Present — but at WHICH version? Refresh only the delimited block; anything the consumer
|
|
215
|
+
// wrote around it is untouched.
|
|
216
|
+
if (stampedVersion(existing) === KIT_VERSION) return "present";
|
|
217
|
+
writeFileSync(
|
|
218
|
+
path,
|
|
219
|
+
refreshBlock(existing, CLAUDE_MD_BLOCK, "<!-- godxjp-ui:start", "<!-- godxjp-ui:end -->"),
|
|
220
|
+
);
|
|
221
|
+
return "refreshed";
|
|
222
|
+
}
|
|
143
223
|
if (existing == null) {
|
|
144
224
|
writeFileSync(path, CLAUDE_MD_BLOCK);
|
|
145
225
|
return "created";
|
|
@@ -157,3 +237,102 @@ export function shouldSkip(root) {
|
|
|
157
237
|
if (pkg.name === "@godxjp/ui" || pkg.name === "@godxjp/ui-mcp") return "self";
|
|
158
238
|
return null;
|
|
159
239
|
}
|
|
240
|
+
|
|
241
|
+
/**
|
|
242
|
+
* Keep an opted-in guinea-pig skill current.
|
|
243
|
+
*
|
|
244
|
+
* The file is co-authored: sections 0–7 come from this package, and section 8 onward is whatever
|
|
245
|
+
* the repo wrote about ITSELF — its package manager, its audit baseline, its deliberate
|
|
246
|
+
* exceptions. So the refresh replaces the head and keeps the tail, which is the only split that
|
|
247
|
+
* lets the guidance move without eating the consumer's own notes.
|
|
248
|
+
*
|
|
249
|
+
* Only runs where `.guinea-pig-optin` exists: the skill carries an obligation to fix things
|
|
250
|
+
* UPSTREAM, and pushing that into a repo that never asked for it would tell its agent to go edit
|
|
251
|
+
* a library it has no mandate over.
|
|
252
|
+
*/
|
|
253
|
+
export function refreshGuineaPigSkill(root) {
|
|
254
|
+
const dir = join(root, ".claude", "skills", "godx-ui-guinea-pig");
|
|
255
|
+
const target = join(dir, "SKILL.md");
|
|
256
|
+
const optin = join(dir, ".guinea-pig-optin");
|
|
257
|
+
if (!existsSync(optin) || !existsSync(target)) return false;
|
|
258
|
+
|
|
259
|
+
const base = readFileSync(join(SELF_ROOT, "scripts", "guinea-pig-skill.md"), "utf8");
|
|
260
|
+
/*
|
|
261
|
+
* The marker tracks the BASE TEXT, not the release — the same correction the consumer rule file
|
|
262
|
+
* needed, for the same reason. A version marker means editing this skill without cutting a
|
|
263
|
+
* release reaches nobody, and the skill is edited far more often than the version moves. The
|
|
264
|
+
* digest covers only the base: everything from the `# 8.` marker down belongs to the repo and
|
|
265
|
+
* must not make the package's own content look changed.
|
|
266
|
+
*
|
|
267
|
+
* `<version>:<digest>` rather than a bare digest, so the file still says which release wrote it
|
|
268
|
+
* to anyone reading it. Only the digest half is compared.
|
|
269
|
+
*/
|
|
270
|
+
const stamp = `${KIT_VERSION}:${digestOf(base)}`;
|
|
271
|
+
if (readFileSync(optin, "utf8").trim().split(":").pop() === digestOf(base)) return false;
|
|
272
|
+
|
|
273
|
+
const current = readFileSync(target, "utf8");
|
|
274
|
+
const marker = "\n---\n\n# 8. ";
|
|
275
|
+
const i = current.indexOf(marker);
|
|
276
|
+
writeFileSync(target, base.replace(/\s*$/, "") + "\n" + (i < 0 ? "" : current.slice(i)));
|
|
277
|
+
writeFileSync(optin, `${stamp}\n`);
|
|
278
|
+
return true;
|
|
279
|
+
}
|
|
280
|
+
|
|
281
|
+
/** The stamp `init-guinea-pig` writes on a fresh install, so the first refresh is a no-op. */
|
|
282
|
+
export function guineaPigStamp() {
|
|
283
|
+
return `${KIT_VERSION}:${digestOf(readFileSync(join(SELF_ROOT, "scripts", "guinea-pig-skill.md"), "utf8"))}`;
|
|
284
|
+
}
|
|
285
|
+
|
|
286
|
+
/**
|
|
287
|
+
* Install the common consumer rules as a PATH-TRIGGERED file, and wire them into `.ai/rules`.
|
|
288
|
+
*
|
|
289
|
+
* The skill and this file say overlapping things on purpose, because they fire at different
|
|
290
|
+
* moments: a skill loads when the TASK matches its description — once, at the start — while an
|
|
291
|
+
* `.ai/rules` entry loads every time an agent touches a file under its glob. Measured over one
|
|
292
|
+
* session: a dashboard file was edited dozens of times and the skill was never re-read, so the
|
|
293
|
+
* laws that mattered were out of context for every edit after the first.
|
|
294
|
+
*
|
|
295
|
+
* The glob is DETECTED, not assumed. A rule wired to a directory the repo does not have is a rule
|
|
296
|
+
* that never fires, which is worse than no rule at all — it looks installed.
|
|
297
|
+
*
|
|
298
|
+
* Unlike the skill, this file is owned OUTRIGHT by the package and is rewritten whole. That is the
|
|
299
|
+
* honest shape for `.ai/rules`, where the convention is one file per concern and the index loads
|
|
300
|
+
* them all: a repo with something of its own to say writes its own rule file instead of editing
|
|
301
|
+
* this one. The file says so at the top, because the first draft preserved nothing and silently
|
|
302
|
+
* ate a note left inside it — measured, and the reason for that banner.
|
|
303
|
+
*/
|
|
304
|
+
export function ensureConsumerRules(root) {
|
|
305
|
+
const uiDir = ["resources/js", "app/javascript", "src/components", "src", "app"].find((d) =>
|
|
306
|
+
existsSync(join(root, d)),
|
|
307
|
+
);
|
|
308
|
+
if (!uiDir) return false;
|
|
309
|
+
|
|
310
|
+
const dir = join(root, ".ai", "rules");
|
|
311
|
+
const target = join(dir, "godxjp-ui.md");
|
|
312
|
+
const body = readFileSync(join(SELF_ROOT, "scripts", "consumer-rule.md"), "utf8");
|
|
313
|
+
const front = `---\npaths:\n - '${uiDir}/**'\n---\n\n`;
|
|
314
|
+
// The digest covers the FRONT MATTER too: the detected glob is part of what makes this file
|
|
315
|
+
// correct, and a repo that grows a `resources/js` after shipping with `src` needs the rewrite.
|
|
316
|
+
const managed = `${front}${body}`;
|
|
317
|
+
const next = `${OWNED_STAMP(managed)}\n${managed}`;
|
|
318
|
+
|
|
319
|
+
if (existsSync(target) && stampedDigest(readFileSync(target, "utf8")) === digestOf(managed)) {
|
|
320
|
+
return false;
|
|
321
|
+
}
|
|
322
|
+
mkdirSync(dir, { recursive: true });
|
|
323
|
+
writeFileSync(target, next);
|
|
324
|
+
|
|
325
|
+
// Only touch the index when the repo keeps one; a missing index means the repo reads rule files
|
|
326
|
+
// directly, and inventing one would change how it loads everything else.
|
|
327
|
+
const index = join(dir, "index.md");
|
|
328
|
+
if (existsSync(index)) {
|
|
329
|
+
const cur = readFileSync(index, "utf8");
|
|
330
|
+
if (!cur.includes(".ai/rules/godxjp-ui.md")) {
|
|
331
|
+
writeFileSync(
|
|
332
|
+
index,
|
|
333
|
+
cur.replace(/\s*$/, "") + `\n| ${uiDir}/** | .ai/rules/godxjp-ui.md |\n`,
|
|
334
|
+
);
|
|
335
|
+
}
|
|
336
|
+
}
|
|
337
|
+
return uiDir;
|
|
338
|
+
}
|