@godxjp/ui 17.0.1 → 18.0.1
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/dist/components/data-display/card.d.ts +37 -1
- package/dist/components/data-display/card.js +7 -1
- package/dist/components/data-display/data-table.js +19 -4
- package/dist/components/data-display/empty-state.d.ts +1 -1
- package/dist/components/data-display/empty-state.js +5 -1
- package/dist/components/data-display/scroll-area.js +1 -1
- package/dist/components/data-display/table.d.ts +20 -1
- package/dist/components/data-display/table.js +23 -9
- package/dist/components/data-entry/calendar.js +4 -0
- package/dist/components/data-entry/cascader.d.ts +1 -1
- package/dist/components/data-entry/cascader.js +10 -1
- package/dist/components/data-entry/checkbox-group.d.ts +1 -1
- package/dist/components/data-entry/checkbox-group.js +13 -4
- package/dist/components/data-entry/color-picker.d.ts +1 -1
- package/dist/components/data-entry/color-picker.js +5 -2
- package/dist/components/data-entry/command.d.ts +2 -2
- package/dist/components/data-entry/date-picker.d.ts +1 -1
- package/dist/components/data-entry/date-picker.js +11 -1
- package/dist/components/data-entry/date-range-picker.d.ts +1 -1
- package/dist/components/data-entry/date-range-picker.js +11 -3
- package/dist/components/data-entry/form-field.js +7 -3
- package/dist/components/data-entry/month-picker.d.ts +1 -1
- package/dist/components/data-entry/month-picker.js +13 -1
- package/dist/components/data-entry/month-range-picker.d.ts +1 -1
- package/dist/components/data-entry/month-range-picker.js +11 -3
- package/dist/components/data-entry/number-input.d.ts +19 -2
- package/dist/components/data-entry/number-input.js +5 -7
- package/dist/components/data-entry/radio.d.ts +1 -1
- package/dist/components/data-entry/radio.js +11 -3
- package/dist/components/data-entry/search-input.d.ts +3 -2
- package/dist/components/data-entry/search-input.js +5 -2
- package/dist/components/data-entry/search-select.d.ts +1 -1
- package/dist/components/data-entry/search-select.js +51 -10
- package/dist/components/data-entry/select.d.ts +7 -0
- package/dist/components/data-entry/select.js +21 -3
- package/dist/components/data-entry/time-picker.d.ts +1 -1
- package/dist/components/data-entry/time-picker.js +11 -1
- package/dist/components/data-entry/transfer.d.ts +1 -1
- package/dist/components/data-entry/transfer.js +73 -59
- package/dist/components/data-entry/tree-select.d.ts +1 -1
- package/dist/components/data-entry/tree-select.js +10 -1
- package/dist/components/data-entry/upload.d.ts +1 -1
- package/dist/components/data-entry/upload.js +7 -2
- package/dist/components/layout/app-shell.d.ts +1 -1
- package/dist/components/layout/app-shell.js +42 -2
- package/dist/components/layout/breadcrumb.d.ts +7 -1
- package/dist/components/layout/breadcrumb.js +6 -2
- package/dist/components/layout/page-container.d.ts +1 -1
- package/dist/components/layout/page-container.js +32 -22
- package/dist/components/layout/responsive-grid.js +1 -1
- package/dist/components/layout/sidebar.d.ts +1 -1
- package/dist/components/layout/sidebar.js +44 -11
- package/dist/components/layout/split-pane.js +2 -2
- package/dist/components/navigation/app-setting-picker.js +15 -7
- package/dist/components/navigation/pagination.d.ts +1 -1
- package/dist/components/navigation/pagination.js +84 -95
- package/dist/components/navigation/tabs.js +21 -4
- package/dist/components/ui/tag-input.js +1 -0
- package/dist/i18n/messages/en.json +3 -1
- package/dist/i18n/messages/ja.json +3 -1
- package/dist/i18n/messages/vi.json +3 -1
- package/dist/lib/field-a11y.d.ts +66 -0
- package/dist/lib/field-a11y.js +44 -0
- package/dist/props/components/app.prop.d.ts +9 -5
- package/dist/props/components/data-display.prop.d.ts +16 -1
- package/dist/props/components/data-entry.prop.d.ts +69 -19
- package/dist/props/components/layout.prop.d.ts +42 -0
- package/dist/props/components/navigation.prop.d.ts +16 -0
- package/dist/props/registry.d.ts +8 -3
- package/dist/props/registry.js +21 -3
- package/dist/props/vocabulary/data.prop.d.ts +9 -0
- package/dist/styles/layout.css +46 -9
- package/dist/styles/shell-layout.css +19 -0
- package/package.json +8 -4
|
@@ -7,7 +7,8 @@ import type { DayPickerProps } from "react-day-picker";
|
|
|
7
7
|
import type { DateRange } from "react-day-picker";
|
|
8
8
|
import type * as React from "react";
|
|
9
9
|
import type { UploadFileItem } from "../../components/data-entry/upload-types.js";
|
|
10
|
-
import type {
|
|
10
|
+
import type { FieldA11yProps } from "../../lib/field-a11y.js";
|
|
11
|
+
import type { ClassNameProp, DisabledProp, EmptyMessageProp, ErrorProp, HelperProp, IdProp, LabelProp, NameProp, OnChangeProp, OnValueChangeProp, OnSearchChangeProp, OpenProp, OnOpenChangeProp, PlaceholderProp, RequiredProp, ValueProp, DefaultValueProp, FormLayoutProp, WidthProp, BreakpointProp, DensityProp, SizeProp } from "../vocabulary/index.js";
|
|
11
12
|
import type { ResponsiveGridColumnsProp } from "./layout.prop.js";
|
|
12
13
|
/** @see Input */
|
|
13
14
|
export type InputProp = React.InputHTMLAttributes<HTMLInputElement> & {
|
|
@@ -33,7 +34,7 @@ export type TextareaProp = React.TextareaHTMLAttributes<HTMLTextAreaElement> & {
|
|
|
33
34
|
* the stepper buttons and ArrowUp/ArrowDown (Shift = ×10); `precision` sets the committed decimal
|
|
34
35
|
* places (inferred from `step` when omitted). Value commits clamped to `min`/`max` on blur/Enter.
|
|
35
36
|
*/
|
|
36
|
-
export type NumberInputProp = {
|
|
37
|
+
export type NumberInputProp = FieldA11yProps & {
|
|
37
38
|
value?: ValueProp<number | null>;
|
|
38
39
|
defaultValue?: DefaultValueProp<number | null>;
|
|
39
40
|
onValueChange?: OnValueChangeProp<number | null>;
|
|
@@ -58,9 +59,6 @@ export type NumberInputProp = {
|
|
|
58
59
|
name?: NameProp;
|
|
59
60
|
id?: IdProp;
|
|
60
61
|
className?: ClassNameProp;
|
|
61
|
-
"aria-label"?: string;
|
|
62
|
-
"aria-labelledby"?: string;
|
|
63
|
-
"aria-describedby"?: string;
|
|
64
62
|
"data-testid"?: string;
|
|
65
63
|
};
|
|
66
64
|
/**
|
|
@@ -101,7 +99,7 @@ export type FormFieldProp = {
|
|
|
101
99
|
children: React.ReactNode;
|
|
102
100
|
};
|
|
103
101
|
/** @see SearchInput */
|
|
104
|
-
export type SearchInputProp = {
|
|
102
|
+
export type SearchInputProp = FieldA11yProps & {
|
|
105
103
|
id?: IdProp;
|
|
106
104
|
label?: LabelProp;
|
|
107
105
|
placeholder?: PlaceholderProp;
|
|
@@ -121,7 +119,7 @@ export type ChoiceOptionProp = {
|
|
|
121
119
|
description?: React.ReactNode;
|
|
122
120
|
};
|
|
123
121
|
/** @see Checkbox.Group */
|
|
124
|
-
export type CheckboxGroupProp = {
|
|
122
|
+
export type CheckboxGroupProp = FieldA11yProps & {
|
|
125
123
|
value?: ValueProp<string[]>;
|
|
126
124
|
defaultValue?: DefaultValueProp<string[]>;
|
|
127
125
|
onValueChange?: OnValueChangeProp<string[]>;
|
|
@@ -129,11 +127,13 @@ export type CheckboxGroupProp = {
|
|
|
129
127
|
orientation?: "horizontal" | "vertical";
|
|
130
128
|
disabled?: DisabledProp;
|
|
131
129
|
name?: NameProp;
|
|
130
|
+
/** Injected by FormField (or set directly) — applied to the `role="group"` container. */
|
|
131
|
+
id?: IdProp;
|
|
132
132
|
className?: ClassNameProp;
|
|
133
133
|
children?: React.ReactNode;
|
|
134
134
|
};
|
|
135
135
|
/** @see Radio.Group */
|
|
136
|
-
export type RadioGroupProp = {
|
|
136
|
+
export type RadioGroupProp = FieldA11yProps & {
|
|
137
137
|
value?: ValueProp;
|
|
138
138
|
defaultValue?: DefaultValueProp;
|
|
139
139
|
onValueChange?: OnValueChangeProp;
|
|
@@ -141,6 +141,8 @@ export type RadioGroupProp = {
|
|
|
141
141
|
orientation?: "horizontal" | "vertical";
|
|
142
142
|
disabled?: DisabledProp;
|
|
143
143
|
name?: NameProp;
|
|
144
|
+
/** Injected by FormField (or set directly) — applied to the `role="radiogroup"` container. */
|
|
145
|
+
id?: IdProp;
|
|
144
146
|
className?: ClassNameProp;
|
|
145
147
|
children?: React.ReactNode;
|
|
146
148
|
};
|
|
@@ -163,7 +165,7 @@ export type SliderProp = React.ComponentPropsWithoutRef<typeof SliderPrimitive.R
|
|
|
163
165
|
/** @see Calendar — react-day-picker DayPicker. */
|
|
164
166
|
export type CalendarProp = DayPickerProps;
|
|
165
167
|
/** @see DatePicker */
|
|
166
|
-
export type DatePickerProp = {
|
|
168
|
+
export type DatePickerProp = FieldA11yProps & {
|
|
167
169
|
value?: ValueProp<Date>;
|
|
168
170
|
defaultValue?: DefaultValueProp<Date | undefined>;
|
|
169
171
|
onValueChange?: OnValueChangeProp<Date | undefined>;
|
|
@@ -180,7 +182,7 @@ export type DatePickerProp = {
|
|
|
180
182
|
allowClear?: boolean;
|
|
181
183
|
};
|
|
182
184
|
/** @see MonthPicker */
|
|
183
|
-
export type MonthPickerProp = {
|
|
185
|
+
export type MonthPickerProp = FieldA11yProps & {
|
|
184
186
|
value?: ValueProp<Date>;
|
|
185
187
|
defaultValue?: DefaultValueProp<Date | undefined>;
|
|
186
188
|
onValueChange?: OnValueChangeProp<Date | undefined>;
|
|
@@ -200,7 +202,7 @@ export type MonthPickerProp = {
|
|
|
200
202
|
* @see MonthRangePicker — both edges are normalized to the FIRST day of their month
|
|
201
203
|
* (the `DateRange` shape is shared with DateRangePicker so ranges interop).
|
|
202
204
|
*/
|
|
203
|
-
export type MonthRangePickerProp = {
|
|
205
|
+
export type MonthRangePickerProp = FieldA11yProps & {
|
|
204
206
|
value?: ValueProp<DateRange>;
|
|
205
207
|
defaultValue?: DefaultValueProp<DateRange | undefined>;
|
|
206
208
|
onValueChange?: OnValueChangeProp<DateRange | undefined>;
|
|
@@ -217,7 +219,7 @@ export type MonthRangePickerProp = {
|
|
|
217
219
|
allowClear?: boolean;
|
|
218
220
|
};
|
|
219
221
|
/** @see DateRangePicker */
|
|
220
|
-
export type DateRangePickerProp = {
|
|
222
|
+
export type DateRangePickerProp = FieldA11yProps & {
|
|
221
223
|
value?: ValueProp<DateRange>;
|
|
222
224
|
defaultValue?: DefaultValueProp<DateRange | undefined>;
|
|
223
225
|
onValueChange?: OnValueChangeProp<DateRange | undefined>;
|
|
@@ -234,7 +236,7 @@ export type DateRangePickerProp = {
|
|
|
234
236
|
allowClear?: boolean;
|
|
235
237
|
};
|
|
236
238
|
/** @see TimePicker — popover HH:mm picker (canonical 24h storage). */
|
|
237
|
-
export type TimePickerProp = {
|
|
239
|
+
export type TimePickerProp = FieldA11yProps & {
|
|
238
240
|
value?: ValueProp;
|
|
239
241
|
defaultValue?: DefaultValueProp;
|
|
240
242
|
onValueChange?: OnValueChangeProp;
|
|
@@ -250,7 +252,7 @@ export type TimePickerProp = {
|
|
|
250
252
|
allowClear?: boolean;
|
|
251
253
|
};
|
|
252
254
|
/** @see ColorPicker */
|
|
253
|
-
export type ColorPickerProp = {
|
|
255
|
+
export type ColorPickerProp = FieldA11yProps & {
|
|
254
256
|
value?: ValueProp;
|
|
255
257
|
onValueChange?: OnValueChangeProp;
|
|
256
258
|
disabled?: DisabledProp;
|
|
@@ -320,12 +322,51 @@ export type SearchSelectProp = {
|
|
|
320
322
|
searchPlaceholder?: PlaceholderProp;
|
|
321
323
|
emptyMessage?: EmptyMessageProp;
|
|
322
324
|
loadingMessage?: string;
|
|
323
|
-
/** Message shown when an async `loadOptions` rejects — a distinct state from empty/loading.
|
|
325
|
+
/** Message shown when an async `loadOptions` rejects — a distinct state from empty/loading. Used
|
|
326
|
+
* as-is unless `renderError` is provided. */
|
|
324
327
|
errorMessage?: string;
|
|
325
328
|
clearLabel?: string;
|
|
326
329
|
/** Show a "clear" row when a value is selected (default true). */
|
|
327
330
|
clearable?: boolean;
|
|
328
331
|
disabled?: DisabledProp;
|
|
332
|
+
/**
|
|
333
|
+
* Read-only: the current value is shown (and the clear affordance hidden) but the popover cannot
|
|
334
|
+
* be opened — no new pick, no search. Mirrors the Input/NumberInput readOnly contract (stays
|
|
335
|
+
* focusable + submits its value, unlike `disabled`). Default false.
|
|
336
|
+
*/
|
|
337
|
+
readOnly?: boolean;
|
|
338
|
+
/** Trigger height tier — forwarded to the underlying Button. Default matches Button's own default. */
|
|
339
|
+
size?: SizeProp;
|
|
340
|
+
/** Controlled open state for the popover (uncontrolled by default). */
|
|
341
|
+
open?: OpenProp;
|
|
342
|
+
onOpenChange?: OnOpenChangeProp;
|
|
343
|
+
/** Controlled search-box query (uncontrolled by default). Pairs with `onSearchChange`. */
|
|
344
|
+
search?: string;
|
|
345
|
+
onSearchChange?: OnSearchChangeProp;
|
|
346
|
+
/**
|
|
347
|
+
* Override the default client-side filter (`options` mode only — ignored with `loadOptions`,
|
|
348
|
+
* which is responsible for its own server-side filtering). Receives the option and the trimmed
|
|
349
|
+
* query; return true to keep the row. Only consulted while the query is non-empty.
|
|
350
|
+
*/
|
|
351
|
+
filterOption?: (option: SearchSelectOptionProp, query: string) => boolean;
|
|
352
|
+
/**
|
|
353
|
+
* Custom error slot — receives the resolved message and a `retry` callback that reloads from the
|
|
354
|
+
* first page (a predictable recovery, not a resume of a failed page-N append). Overrides the
|
|
355
|
+
* default `errorMessage` row.
|
|
356
|
+
*/
|
|
357
|
+
renderError?: (params: {
|
|
358
|
+
message: string;
|
|
359
|
+
retry: () => void;
|
|
360
|
+
}) => React.ReactNode;
|
|
361
|
+
/**
|
|
362
|
+
* Custom "load more" affordance appended below the list while another page is available — pairs
|
|
363
|
+
* with (does not replace) the built-in scroll-triggered pagination.
|
|
364
|
+
*/
|
|
365
|
+
renderLoadMore?: (params: {
|
|
366
|
+
hasMore: boolean;
|
|
367
|
+
loading: boolean;
|
|
368
|
+
loadMore: () => void;
|
|
369
|
+
}) => React.ReactNode;
|
|
329
370
|
/** Form field name — submits the selected value via a hidden input. */
|
|
330
371
|
name?: NameProp;
|
|
331
372
|
id?: IdProp;
|
|
@@ -342,6 +383,11 @@ export type SearchSelectProp = {
|
|
|
342
383
|
* Data-driven (Ant-style) form of {@link Select} — one component covering static `options` or
|
|
343
384
|
* async `loadOptions`, with `showSearch` toggling the searchable combobox vs a plain listbox.
|
|
344
385
|
* Passing `options`/`loadOptions` to `<Select>` switches it from the compound API to this one.
|
|
386
|
+
*
|
|
387
|
+
* `readOnly`/`size`/`open`/`onOpenChange`/`search`/`onSearchChange`/`filterOption`/`renderError`/
|
|
388
|
+
* `renderLoadMore` (inherited from {@link SearchSelectProp}) take effect ONLY in searchable mode
|
|
389
|
+
* (`showSearch` or `loadOptions`) — they configure the `SearchSelect` engine that mode delegates
|
|
390
|
+
* to. The plain listbox (no search) is a native Radix listbox and ignores them.
|
|
345
391
|
*/
|
|
346
392
|
export type SelectDataProp = SearchSelectProp & {
|
|
347
393
|
/** Show the search box (combobox). Defaults to true when `loadOptions` is set, otherwise false. */
|
|
@@ -352,7 +398,7 @@ export type UploadFileItemProp = UploadFileItem;
|
|
|
352
398
|
/** @see Upload */
|
|
353
399
|
export type UploadVariantProp = "dropzone" | "button" | "picture-card" | "picture" | "avatar" | "avatar-crop";
|
|
354
400
|
/** @see Upload — presentational; wire `onUpload` to media-service in app api.ts */
|
|
355
|
-
export type UploadProp = {
|
|
401
|
+
export type UploadProp = FieldA11yProps & {
|
|
356
402
|
variant?: UploadVariantProp;
|
|
357
403
|
value?: ValueProp<UploadFileItemProp[]>;
|
|
358
404
|
defaultValue?: DefaultValueProp<UploadFileItemProp[]>;
|
|
@@ -368,6 +414,8 @@ export type UploadProp = {
|
|
|
368
414
|
mediaId: string;
|
|
369
415
|
previewUrl?: string;
|
|
370
416
|
}>;
|
|
417
|
+
/** Injected by FormField (or set directly) — applied to the native `<input type="file">`. */
|
|
418
|
+
id?: IdProp;
|
|
371
419
|
className?: ClassNameProp;
|
|
372
420
|
children?: React.ReactNode;
|
|
373
421
|
};
|
|
@@ -386,7 +434,7 @@ export type TreeFieldNamesProp = {
|
|
|
386
434
|
children?: string;
|
|
387
435
|
};
|
|
388
436
|
/** @see Cascader — cascade picker (Popover + multi-column). */
|
|
389
|
-
export type CascaderProp = {
|
|
437
|
+
export type CascaderProp = FieldA11yProps & {
|
|
390
438
|
options: TreeOptionProp[];
|
|
391
439
|
value?: ValueProp<string[] | string[][]>;
|
|
392
440
|
defaultValue?: DefaultValueProp<string[] | string[][]>;
|
|
@@ -404,7 +452,7 @@ export type CascaderProp = {
|
|
|
404
452
|
};
|
|
405
453
|
export type ShowCheckedStrategyProp = "SHOW_CHILD" | "SHOW_PARENT" | "SHOW_ALL";
|
|
406
454
|
/** @see TreeSelect — tree in Popover (cmdk search + expand/collapse). */
|
|
407
|
-
export type TreeSelectProp = {
|
|
455
|
+
export type TreeSelectProp = FieldA11yProps & {
|
|
408
456
|
treeData: TreeOptionProp[];
|
|
409
457
|
value?: ValueProp<string | string[]>;
|
|
410
458
|
defaultValue?: DefaultValueProp<string | string[]>;
|
|
@@ -430,7 +478,7 @@ export type TransferItemProp = {
|
|
|
430
478
|
disabled?: boolean;
|
|
431
479
|
};
|
|
432
480
|
/** @see Transfer — dual-list shuttle (Checkbox + SearchInput). */
|
|
433
|
-
export type TransferProp = {
|
|
481
|
+
export type TransferProp = FieldA11yProps & {
|
|
434
482
|
dataSource: TransferItemProp[];
|
|
435
483
|
targetKeys: string[];
|
|
436
484
|
onValueChange?: (targetKeys: string[], direction: "left" | "right", moveKeys: string[]) => void;
|
|
@@ -438,6 +486,8 @@ export type TransferProp = {
|
|
|
438
486
|
showSearch?: boolean;
|
|
439
487
|
oneWay?: boolean;
|
|
440
488
|
disabled?: DisabledProp;
|
|
489
|
+
/** Injected by FormField (or set directly) — applied to the `role="group"` shuttle container. */
|
|
490
|
+
id?: IdProp;
|
|
441
491
|
className?: ClassNameProp;
|
|
442
492
|
selectedKeys?: [string[], string[]];
|
|
443
493
|
onSelectChange?: (sourceSelectedKeys: string[], targetSelectedKeys: string[]) => void;
|
|
@@ -9,6 +9,13 @@ export type PageContainerProp = {
|
|
|
9
9
|
extra?: ExtraProp;
|
|
10
10
|
footer?: FooterProp;
|
|
11
11
|
breadcrumb?: BreadcrumbProp;
|
|
12
|
+
/**
|
|
13
|
+
* Override the breadcrumb `<nav>` landmark's accessible name. Defaults to a localized
|
|
14
|
+
* "Breadcrumb". Needed when more than one `PageContainer` (each with its own `breadcrumb`)
|
|
15
|
+
* renders on the same page/view — two `<nav>` landmarks sharing one name/role fail axe's
|
|
16
|
+
* `landmark-unique` (WCAG 2.4.1 / 1.3.1).
|
|
17
|
+
*/
|
|
18
|
+
breadcrumbAriaLabel?: string;
|
|
12
19
|
linkComponent?: React.ElementType;
|
|
13
20
|
density?: PageDensityProp;
|
|
14
21
|
variant?: PageContainerVariantProp;
|
|
@@ -66,6 +73,21 @@ export type AppShellProp = {
|
|
|
66
73
|
breadcrumb?: ReactNode;
|
|
67
74
|
footer?: ReactNode;
|
|
68
75
|
sidebarCollapsed?: boolean;
|
|
76
|
+
/**
|
|
77
|
+
* Navigation shown in the mobile drawer below the `lg` breakpoint, where the docked sidebar is
|
|
78
|
+
* hidden. AppShell OWNS the drawer: it renders a hamburger trigger in the topbar and a focus-
|
|
79
|
+
* trapped Sheet (Esc + overlay close, focus returns to the trigger) — hiding the sidebar without
|
|
80
|
+
* a reachable alternative is invalid (gh#165). Defaults to `sidebar`, so the same nav is
|
|
81
|
+
* available on mobile with no extra wiring; pass a distinct node for a mobile-tailored menu, or
|
|
82
|
+
* `null` to opt out (only when navigation lives elsewhere, e.g. a bottom bar).
|
|
83
|
+
*/
|
|
84
|
+
mobileNav?: ReactNode;
|
|
85
|
+
/** Accessible title for the mobile navigation drawer. Defaults to the localized "Menu". */
|
|
86
|
+
mobileNavLabel?: string;
|
|
87
|
+
/** Controlled open state of the mobile drawer. Omit for AppShell-owned (uncontrolled) state. */
|
|
88
|
+
mobileNavOpen?: boolean;
|
|
89
|
+
/** Change handler for the mobile drawer open state (pairs with `mobileNavOpen`). */
|
|
90
|
+
onMobileNavOpenChange?: (open: boolean) => void;
|
|
69
91
|
};
|
|
70
92
|
/**
|
|
71
93
|
* @see AuthShell — centred auth/login page shell (login · mfa · passkey · device · reset). A
|
|
@@ -97,6 +119,13 @@ export type SidebarItemProp = {
|
|
|
97
119
|
icon: ComponentType<SVGProps<SVGSVGElement>>;
|
|
98
120
|
badge?: ReactNode;
|
|
99
121
|
disabled?: boolean;
|
|
122
|
+
/**
|
|
123
|
+
* Render the row as a real anchor (`<a href>`) — the link is the SOLE interactive element (no
|
|
124
|
+
* nested `<button>`). Use for MPA links / right-click-open-in-new-tab. Omit for SPA rows that
|
|
125
|
+
* report selection via `onSelect(id)`. For a framework router `<Link>`, use `renderItem` instead
|
|
126
|
+
* (its returned element is merged as the row via Slot, so there is still no nested interactive).
|
|
127
|
+
*/
|
|
128
|
+
href?: string;
|
|
100
129
|
/** Nested rows — renders a collapsible submenu group (the parent reads active when any child is). */
|
|
101
130
|
children?: SidebarItemProp[];
|
|
102
131
|
};
|
|
@@ -117,8 +146,21 @@ export type SidebarProp = {
|
|
|
117
146
|
brand?: ReactNode;
|
|
118
147
|
collapsed?: boolean;
|
|
119
148
|
children?: ChildrenProp;
|
|
149
|
+
/**
|
|
150
|
+
* Escape hatch to render a leaf row as a custom element — typically a framework router `<Link>`.
|
|
151
|
+
* Return a SINGLE interactive element; the Sidebar merges the row styling + active state onto it
|
|
152
|
+
* via Slot (so it is the row and the sole interactive element — no nested `<button>`). Any
|
|
153
|
+
* secondary affix (a star, a count) must be a non-interactive descendant of that element.
|
|
154
|
+
*/
|
|
120
155
|
renderItem?: (item: SidebarItemData) => ReactNode;
|
|
121
156
|
footer?: ReactNode;
|
|
157
|
+
/**
|
|
158
|
+
* Override the nav landmark's accessible name. Defaults to a localized "Main navigation".
|
|
159
|
+
* Needed when more than one Sidebar renders on the same page/view (e.g. a docked sidebar +
|
|
160
|
+
* its mobile-drawer twin, both mounted at once) — two `<nav>` landmarks sharing one name/role
|
|
161
|
+
* fail axe's `landmark-unique` (WCAG 2.4.1 / 1.3.1).
|
|
162
|
+
*/
|
|
163
|
+
"aria-label"?: string;
|
|
122
164
|
};
|
|
123
165
|
/**
|
|
124
166
|
* @see Topbar — a PURE SLOT bar (no baked chrome). The library only positions three clusters; the
|
|
@@ -22,10 +22,26 @@ export type PaginationProp = {
|
|
|
22
22
|
pageSizeOptions?: number[];
|
|
23
23
|
showSizeChanger?: boolean;
|
|
24
24
|
showTotal?: boolean | ((total: number, range: [number, number]) => React.ReactNode);
|
|
25
|
+
/**
|
|
26
|
+
* Hide the whole control when there is nothing to page through — zero items OR exactly one page.
|
|
27
|
+
* `true` (default) keeps table footers clean: pagination is navigation between multiple result
|
|
28
|
+
* pages, so a lone disabled `1 / 1` bar is noise. Set `false` for the explicit opt-in when a
|
|
29
|
+
* consumer still wants the bar on a single page (e.g. to keep `showTotal` visible). A control
|
|
30
|
+
* with `total === 0` is ALWAYS hidden — there is no data to navigate. (gh#153)
|
|
31
|
+
*/
|
|
32
|
+
hideOnSinglePage?: boolean;
|
|
25
33
|
simple?: boolean;
|
|
26
34
|
disabled?: DisabledProp;
|
|
27
35
|
className?: ClassNameProp;
|
|
28
36
|
onValueChange?: (page: number, pageSize: number) => void;
|
|
37
|
+
/**
|
|
38
|
+
* Override the `<nav>` landmark's accessible name. Defaults to a localized "Pagination".
|
|
39
|
+
* Multiple Pagination instances on one page/view (e.g. two independent result lists) need a
|
|
40
|
+
* DISTINCT name each — two `<nav>` landmarks sharing one name/role fail axe's `landmark-unique`
|
|
41
|
+
* (WCAG 2.4.1 / 1.3.1). Pass something that names what is being paged, e.g. `"注文一覧の
|
|
42
|
+
* ページネーション"` vs `"請求書一覧のページネーション"`.
|
|
43
|
+
*/
|
|
44
|
+
"aria-label"?: string;
|
|
29
45
|
};
|
|
30
46
|
export type StepStatusProp = "wait" | "process" | "finish" | "error";
|
|
31
47
|
/** @see StepItem */
|
package/dist/props/registry.d.ts
CHANGED
|
@@ -610,13 +610,13 @@ export declare const COMPONENT_PROP_REGISTRY: {
|
|
|
610
610
|
readonly SearchSelectProp: {
|
|
611
611
|
readonly group: "data-entry";
|
|
612
612
|
readonly file: "components/data-entry.prop.ts";
|
|
613
|
-
readonly vocabulary: readonly ["ValueProp", "OnValueChangeProp", "PlaceholderProp", "EmptyMessageProp", "DisabledProp", "NameProp", "IdProp", "ClassNameProp"];
|
|
613
|
+
readonly vocabulary: readonly ["ValueProp", "OnValueChangeProp", "PlaceholderProp", "EmptyMessageProp", "DisabledProp", "NameProp", "IdProp", "ClassNameProp", "OpenProp", "OnOpenChangeProp", "SizeProp"];
|
|
614
614
|
readonly note: "Internal — the searchable engine behind `<Select options showSearch>` (not public API); use Select.";
|
|
615
615
|
};
|
|
616
616
|
readonly SelectDataProp: {
|
|
617
617
|
readonly group: "data-entry";
|
|
618
618
|
readonly file: "components/data-entry.prop.ts";
|
|
619
|
-
readonly vocabulary: readonly ["ValueProp", "OnValueChangeProp", "PlaceholderProp", "EmptyMessageProp", "DisabledProp", "NameProp", "IdProp", "ClassNameProp"];
|
|
619
|
+
readonly vocabulary: readonly ["ValueProp", "OnValueChangeProp", "PlaceholderProp", "EmptyMessageProp", "DisabledProp", "NameProp", "IdProp", "ClassNameProp", "OpenProp", "OnOpenChangeProp", "SizeProp"];
|
|
620
620
|
readonly note: "Ant-style data-driven form of Select (options|loadOptions + showSearch). One Select for all single-selects.";
|
|
621
621
|
};
|
|
622
622
|
readonly SearchSelectOptionProp: {
|
|
@@ -687,7 +687,7 @@ export declare const COMPONENT_PROP_REGISTRY: {
|
|
|
687
687
|
readonly EmptyStateProp: {
|
|
688
688
|
readonly group: "data-display";
|
|
689
689
|
readonly file: "components/data-display.prop.ts";
|
|
690
|
-
readonly vocabulary: readonly ["IconProp", "TitleProp", "DescriptionProp", "ActionProp", "ToneProp"];
|
|
690
|
+
readonly vocabulary: readonly ["IconProp", "TitleProp", "DescriptionProp", "ActionProp", "ToneProp", "HeadingLevelProp"];
|
|
691
691
|
};
|
|
692
692
|
readonly EmptyStateToneProp: {
|
|
693
693
|
readonly group: "data-display";
|
|
@@ -1097,6 +1097,11 @@ export declare const COMPONENT_PROP_REGISTRY: {
|
|
|
1097
1097
|
readonly file: "components/data-display/card.tsx";
|
|
1098
1098
|
readonly vocabulary: readonly ["TitleProp", "DescriptionProp", "ClassNameProp", "ChildrenProp"];
|
|
1099
1099
|
};
|
|
1100
|
+
readonly CardTitleProp: {
|
|
1101
|
+
readonly group: "data-display";
|
|
1102
|
+
readonly file: "components/data-display/card.tsx";
|
|
1103
|
+
readonly vocabulary: readonly ["HeadingLevelProp", "ClassNameProp", "ChildrenProp"];
|
|
1104
|
+
};
|
|
1100
1105
|
readonly CardContentProp: {
|
|
1101
1106
|
readonly group: "data-display";
|
|
1102
1107
|
readonly file: "components/data-display/card.tsx";
|
package/dist/props/registry.js
CHANGED
|
@@ -637,7 +637,10 @@ const COMPONENT_PROP_REGISTRY = {
|
|
|
637
637
|
"DisabledProp",
|
|
638
638
|
"NameProp",
|
|
639
639
|
"IdProp",
|
|
640
|
-
"ClassNameProp"
|
|
640
|
+
"ClassNameProp",
|
|
641
|
+
"OpenProp",
|
|
642
|
+
"OnOpenChangeProp",
|
|
643
|
+
"SizeProp"
|
|
641
644
|
],
|
|
642
645
|
note: "Internal \u2014 the searchable engine behind `<Select options showSearch>` (not public API); use Select."
|
|
643
646
|
},
|
|
@@ -652,7 +655,10 @@ const COMPONENT_PROP_REGISTRY = {
|
|
|
652
655
|
"DisabledProp",
|
|
653
656
|
"NameProp",
|
|
654
657
|
"IdProp",
|
|
655
|
-
"ClassNameProp"
|
|
658
|
+
"ClassNameProp",
|
|
659
|
+
"OpenProp",
|
|
660
|
+
"OnOpenChangeProp",
|
|
661
|
+
"SizeProp"
|
|
656
662
|
],
|
|
657
663
|
note: "Ant-style data-driven form of Select (options|loadOptions + showSearch). One Select for all single-selects."
|
|
658
664
|
},
|
|
@@ -742,7 +748,14 @@ const COMPONENT_PROP_REGISTRY = {
|
|
|
742
748
|
EmptyStateProp: {
|
|
743
749
|
group: "data-display",
|
|
744
750
|
file: "components/data-display.prop.ts",
|
|
745
|
-
vocabulary: [
|
|
751
|
+
vocabulary: [
|
|
752
|
+
"IconProp",
|
|
753
|
+
"TitleProp",
|
|
754
|
+
"DescriptionProp",
|
|
755
|
+
"ActionProp",
|
|
756
|
+
"ToneProp",
|
|
757
|
+
"HeadingLevelProp"
|
|
758
|
+
]
|
|
746
759
|
},
|
|
747
760
|
EmptyStateToneProp: {
|
|
748
761
|
group: "data-display",
|
|
@@ -1104,6 +1117,11 @@ const COMPONENT_PROP_REGISTRY = {
|
|
|
1104
1117
|
file: "components/data-display/card.tsx",
|
|
1105
1118
|
vocabulary: ["TitleProp", "DescriptionProp", "ClassNameProp", "ChildrenProp"]
|
|
1106
1119
|
},
|
|
1120
|
+
CardTitleProp: {
|
|
1121
|
+
group: "data-display",
|
|
1122
|
+
file: "components/data-display/card.tsx",
|
|
1123
|
+
vocabulary: ["HeadingLevelProp", "ClassNameProp", "ChildrenProp"]
|
|
1124
|
+
},
|
|
1107
1125
|
CardContentProp: {
|
|
1108
1126
|
group: "data-display",
|
|
1109
1127
|
file: "components/data-display/card.tsx",
|
|
@@ -13,6 +13,15 @@ export type OnRowClickProp<T> = (row: T) => void;
|
|
|
13
13
|
export type ColumnDefProp<T> = {
|
|
14
14
|
key: string;
|
|
15
15
|
header: React.ReactNode;
|
|
16
|
+
/**
|
|
17
|
+
* Accessible header text for a column whose `header` is visually empty — the
|
|
18
|
+
* standard case for a row-actions or selection column. Rendered as an
|
|
19
|
+
* `sr-only` label inside the `<th>` so the column keeps a screen-reader name
|
|
20
|
+
* (e.g. "Actions" / "Select") while showing nothing on screen. Required
|
|
21
|
+
* (dev-warned) when `header` is empty; ignored when `header` has visible text.
|
|
22
|
+
* Route the string through `t()` for i18n.
|
|
23
|
+
*/
|
|
24
|
+
ariaLabel?: string;
|
|
16
25
|
render?: (row: T) => React.ReactNode;
|
|
17
26
|
sortable?: boolean;
|
|
18
27
|
width?: string;
|
package/dist/styles/layout.css
CHANGED
|
@@ -175,6 +175,16 @@
|
|
|
175
175
|
gap: var(--space-inline-lg);
|
|
176
176
|
}
|
|
177
177
|
|
|
178
|
+
/* ResponsiveGrid OWNS its query container. The component wraps the grid in
|
|
179
|
+
* `.ui-responsive-grid-scope` (container-type: inline-size, named `responsive-grid`) so the
|
|
180
|
+
* column breakpoints resolve against the WIDTH AVAILABLE TO THE GRID — not the viewport and not
|
|
181
|
+
* an undeclared ancestor `container-type`. This makes it correct inside a narrow card, a
|
|
182
|
+
* SplitPane aside, or a bare `<div>`; it can never silently stay one column for want of an
|
|
183
|
+
* external container context (gh#165). Named so it queries its own scope, never a closer one. */
|
|
184
|
+
.ui-responsive-grid-scope {
|
|
185
|
+
container: responsive-grid / inline-size;
|
|
186
|
+
}
|
|
187
|
+
|
|
178
188
|
.ui-responsive-grid {
|
|
179
189
|
display: grid;
|
|
180
190
|
gap: var(--space-stack-md);
|
|
@@ -185,24 +195,33 @@
|
|
|
185
195
|
min-width: 0;
|
|
186
196
|
}
|
|
187
197
|
|
|
188
|
-
@container (min-width:
|
|
198
|
+
@container responsive-grid (min-width: 40rem) {
|
|
189
199
|
.ui-responsive-grid {
|
|
190
200
|
grid-template-columns: repeat(var(--responsive-grid-sm, 2), minmax(0, 1fr));
|
|
191
201
|
}
|
|
192
202
|
}
|
|
193
203
|
|
|
194
|
-
@container (min-width:
|
|
204
|
+
@container responsive-grid (min-width: 48rem) {
|
|
195
205
|
.ui-responsive-grid {
|
|
196
206
|
grid-template-columns: repeat(var(--responsive-grid-md, 3), minmax(0, 1fr));
|
|
197
207
|
}
|
|
198
208
|
}
|
|
199
209
|
|
|
200
|
-
@container (min-width:
|
|
210
|
+
@container responsive-grid (min-width: 64rem) {
|
|
201
211
|
.ui-responsive-grid {
|
|
202
212
|
grid-template-columns: repeat(var(--responsive-grid-lg, 4), minmax(0, 1fr));
|
|
203
213
|
}
|
|
204
214
|
}
|
|
205
215
|
|
|
216
|
+
/* SplitPane OWNS its query container too — `.ui-split-pane-scope`
|
|
217
|
+
* (container-type: inline-size, named `split-pane`). The two-column layout is chosen from the
|
|
218
|
+
* pane's OWN available width, so a narrow embedded pane on a large viewport correctly stays a
|
|
219
|
+
* single column, and a wide pane on a small viewport can split (gh#165 — replaces the old
|
|
220
|
+
* `@media (min-width: 1080px)` viewport query that ignored the container). */
|
|
221
|
+
.ui-split-pane-scope {
|
|
222
|
+
container: split-pane / inline-size;
|
|
223
|
+
}
|
|
224
|
+
|
|
206
225
|
.ui-split-pane {
|
|
207
226
|
display: grid;
|
|
208
227
|
gap: var(--space-stack-md);
|
|
@@ -259,7 +278,7 @@
|
|
|
259
278
|
opacity: 0.5;
|
|
260
279
|
}
|
|
261
280
|
|
|
262
|
-
@
|
|
281
|
+
@container split-pane (min-width: 48rem) {
|
|
263
282
|
.ui-split-pane[data-aside-width="sm"] {
|
|
264
283
|
grid-template-columns: minmax(0, 1fr) 20rem;
|
|
265
284
|
}
|
|
@@ -543,22 +562,30 @@
|
|
|
543
562
|
}
|
|
544
563
|
|
|
545
564
|
@layer components {
|
|
565
|
+
/* Pagination is ONE horizontal row and never wraps to a second desktop line (gh#153 — the old
|
|
566
|
+
* `flex-wrap: wrap` split the range / size-changer / page strip across rows). The number strip
|
|
567
|
+
* (`.ui-pagination-list`) absorbs any overflow by scrolling horizontally rather than wrapping; a
|
|
568
|
+
* genuinely narrow viewport uses the INTENTIONAL compact form via the `simple` prop (Prev · n/N ·
|
|
569
|
+
* Next, no page buttons) — not browser-driven wrapping. */
|
|
546
570
|
.ui-pagination {
|
|
547
571
|
display: flex;
|
|
548
|
-
flex-wrap:
|
|
572
|
+
flex-wrap: nowrap;
|
|
573
|
+
min-width: 0;
|
|
549
574
|
align-items: center;
|
|
550
575
|
justify-content: flex-end;
|
|
551
576
|
gap: var(--pagination-gap);
|
|
552
577
|
}
|
|
553
578
|
|
|
554
|
-
|
|
555
|
-
|
|
556
|
-
}
|
|
557
|
-
|
|
579
|
+
/* Total / range label sits at the start and truncates rather than pushing the controls onto a
|
|
580
|
+
* second line — the nav row stays one line at every width (gh#153). */
|
|
558
581
|
.ui-pagination-total {
|
|
582
|
+
min-width: 0;
|
|
559
583
|
margin-inline-end: auto;
|
|
584
|
+
overflow: hidden;
|
|
560
585
|
color: hsl(var(--muted-foreground));
|
|
561
586
|
font-size: var(--pagination-total-font-size);
|
|
587
|
+
text-overflow: ellipsis;
|
|
588
|
+
white-space: nowrap;
|
|
562
589
|
}
|
|
563
590
|
|
|
564
591
|
.ui-pagination-count {
|
|
@@ -576,12 +603,22 @@
|
|
|
576
603
|
|
|
577
604
|
.ui-pagination-list {
|
|
578
605
|
display: flex;
|
|
606
|
+
min-width: 0;
|
|
579
607
|
align-items: center;
|
|
580
608
|
gap: var(--pagination-item-gap);
|
|
609
|
+
/* Overflow scrolls horizontally instead of wrapping onto a second row. Hidden scrollbar keeps
|
|
610
|
+
* the desktop bar clean; the strip stays swipeable on touch. */
|
|
611
|
+
overflow-x: auto;
|
|
612
|
+
scrollbar-width: none;
|
|
613
|
+
}
|
|
614
|
+
|
|
615
|
+
.ui-pagination-list::-webkit-scrollbar {
|
|
616
|
+
display: none;
|
|
581
617
|
}
|
|
582
618
|
|
|
583
619
|
.ui-pagination-item {
|
|
584
620
|
display: flex;
|
|
621
|
+
flex: 0 0 auto;
|
|
585
622
|
align-items: center;
|
|
586
623
|
justify-content: center;
|
|
587
624
|
}
|
|
@@ -143,6 +143,21 @@
|
|
|
143
143
|
display: none;
|
|
144
144
|
}
|
|
145
145
|
|
|
146
|
+
/* AppShell-owned mobile drawer trigger — hidden on desktop, shown once the docked sidebar
|
|
147
|
+
* collapses out below `lg` (gh#165). The drawer nav itself is a focus-trapped Sheet. */
|
|
148
|
+
.app-mobile-nav-trigger {
|
|
149
|
+
display: none;
|
|
150
|
+
flex: 0 0 auto;
|
|
151
|
+
margin-inline-end: var(--space-1);
|
|
152
|
+
}
|
|
153
|
+
|
|
154
|
+
/* The drawer nav reuses the docked Sidebar node; its `.sb-root { display: contents }` flattens
|
|
155
|
+
* into the scrollable SheetBody so sections/footer flow naturally in the panel. */
|
|
156
|
+
.app-mobile-nav-body {
|
|
157
|
+
display: flex;
|
|
158
|
+
flex-direction: column;
|
|
159
|
+
}
|
|
160
|
+
|
|
146
161
|
.app-topbar-spacer {
|
|
147
162
|
flex: 1;
|
|
148
163
|
}
|
|
@@ -171,6 +186,10 @@
|
|
|
171
186
|
.app-topbar-left:has(.app-mobile-sidebar-trigger) {
|
|
172
187
|
display: flex;
|
|
173
188
|
}
|
|
189
|
+
|
|
190
|
+
.app-mobile-nav-trigger {
|
|
191
|
+
display: inline-flex;
|
|
192
|
+
}
|
|
174
193
|
}
|
|
175
194
|
|
|
176
195
|
.sb-root {
|
package/package.json
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@godxjp/ui",
|
|
3
|
-
"version": "
|
|
4
|
-
"godxUiMcp": "
|
|
3
|
+
"version": "18.0.1",
|
|
4
|
+
"godxUiMcp": "18.0.0",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"packageManager": "pnpm@10.29.1",
|
|
7
7
|
"sideEffects": false,
|
|
@@ -276,9 +276,10 @@
|
|
|
276
276
|
"test:watch": "vitest",
|
|
277
277
|
"test:coverage": "vitest run --coverage",
|
|
278
278
|
"check:example-imports": "node scripts/check-example-imports.mjs",
|
|
279
|
-
"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:control-sizing && pnpm check:rtl && pnpm check:typography && pnpm check:mcp-token-sync && pnpm check:mcp-lockstep && pnpm check:mcp-sync && pnpm check:mcp-orphans && pnpm check:audit-sync && pnpm test",
|
|
280
|
-
"verify:release": "pnpm build && 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:control-sizing && pnpm check:rtl && pnpm check:typography && pnpm check:mcp-token-sync && pnpm check:mcp-lockstep && pnpm check:mcp-sync && pnpm check:mcp-orphans && pnpm check:audit-sync && pnpm check:mcp-prop-sync && pnpm check:contrast && pnpm check:visual-audit && pnpm test",
|
|
279
|
+
"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:control-sizing && pnpm check:rtl && pnpm check:typography && pnpm check:mcp-token-sync && pnpm check:mcp-lockstep && pnpm check:mcp-sync && pnpm check:mcp-orphans && pnpm check:mcp-pattern-imports && pnpm check:audit-sync && pnpm check:frame-coverage && pnpm test",
|
|
280
|
+
"verify:release": "pnpm build && 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:control-sizing && pnpm check:rtl && pnpm check:typography && pnpm check:mcp-token-sync && pnpm check:mcp-lockstep && pnpm check:mcp-sync && 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 check:frame-coverage && pnpm check:frame-axe && pnpm test",
|
|
281
281
|
"check:mcp-lockstep": "node scripts/check-release-lockstep.mjs",
|
|
282
|
+
"check:mcp-pattern-imports": "node scripts/check-mcp-pattern-imports.mjs",
|
|
282
283
|
"check:mcp-sync": "node scripts/check-mcp-sync.mjs",
|
|
283
284
|
"check:mcp-orphans": "node scripts/check-mcp-orphans.mjs",
|
|
284
285
|
"check:mcp-prop-sync": "node scripts/check-mcp-prop-sync.mjs",
|
|
@@ -304,6 +305,9 @@
|
|
|
304
305
|
"check:contrast": "node scripts/check-contrast.mjs",
|
|
305
306
|
"visual-audit": "node scripts/visual-audit.mjs",
|
|
306
307
|
"check:visual-audit": "node scripts/visual-audit-smoke.mjs",
|
|
308
|
+
"check:frame-axe": "node scripts/check-frame-axe.mjs",
|
|
309
|
+
"check:frame-geometry": "node scripts/frame-geometry.mjs",
|
|
310
|
+
"check:frame-coverage": "node scripts/frame-coverage.mjs",
|
|
307
311
|
"postinstall": "node scripts/postinstall.mjs",
|
|
308
312
|
"init-agent": "node scripts/init-agent-kit.mjs",
|
|
309
313
|
"check:use-client": "node scripts/check-use-client.mjs"
|