@godxjp/ui 18.0.1 → 18.0.3
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/charts/chart-cartesian.js +1 -1
- package/dist/components/charts/pie-chart.js +1 -1
- package/dist/components/data-display/data-table.js +13 -5
- package/dist/components/data-entry/calendar.d.ts +1 -1
- package/dist/components/data-entry/calendar.js +7 -0
- package/dist/components/data-entry/search-select.js +13 -6
- package/dist/components/data-entry/transfer.js +1 -1
- package/dist/components/data-entry/tree-select.js +37 -33
- package/dist/components/data-entry/upload.js +1 -1
- package/dist/components/feedback/dialog.js +4 -2
- package/dist/components/feedback/sheet.js +4 -2
- package/dist/components/general/button.js +2 -2
- package/dist/components/layout/breadcrumb.d.ts +2 -2
- package/dist/components/layout/breadcrumb.js +1 -1
- package/dist/components/layout/page-container.d.ts +1 -1
- package/dist/components/layout/page-container.js +2 -1
- package/dist/components/layout/sidebar.d.ts +1 -1
- package/dist/components/layout/sidebar.js +2 -1
- package/dist/components/layout/split-pane.d.ts +3 -1
- package/dist/components/layout/split-pane.js +2 -2
- package/dist/components/navigation/pagination.d.ts +1 -1
- package/dist/components/navigation/pagination.js +2 -2
- package/dist/components/navigation/tabs.js +1 -1
- package/dist/components/query/infinite-query-state.d.ts +1 -1
- package/dist/components/query/infinite-query-state.js +14 -2
- package/dist/props/components/data-entry.prop.d.ts +12 -0
- package/dist/props/components/layout.prop.d.ts +4 -0
- package/dist/props/components/navigation.prop.d.ts +8 -8
- package/dist/props/components/query.prop.d.ts +2 -0
- package/dist/styles/chart-layout.css +2 -0
- package/dist/styles/control.css +15 -0
- package/dist/styles/layout.css +27 -2
- package/dist/styles/navigation-layout.css +7 -0
- package/dist/styles/table-layout.css +25 -0
- package/dist/tokens/components/navigation.css +2 -0
- package/dist/tokens/semantic/layout.css +10 -0
- package/package.json +23 -4
|
@@ -165,7 +165,7 @@ function CartesianChart({
|
|
|
165
165
|
height: resolvedHeight,
|
|
166
166
|
className,
|
|
167
167
|
id,
|
|
168
|
-
children: hasData ? /* @__PURE__ */ jsx(ResponsiveContainer, { width: "100%", height: "100%", children: chart() }) : /* @__PURE__ */ jsx(EmptyState, { title: emptyMessage ?? t("chart.empty") })
|
|
168
|
+
children: hasData ? /* @__PURE__ */ jsx(ResponsiveContainer, { width: "100%", height: "100%", minWidth: 0, children: chart() }) : /* @__PURE__ */ jsx(EmptyState, { title: emptyMessage ?? t("chart.empty") })
|
|
169
169
|
}
|
|
170
170
|
);
|
|
171
171
|
}
|
|
@@ -43,7 +43,7 @@ function PieChart({
|
|
|
43
43
|
height: resolvedHeight,
|
|
44
44
|
className,
|
|
45
45
|
id,
|
|
46
|
-
children: hasData ? /* @__PURE__ */ jsx(ResponsiveContainer, { width: "100%", height: "100%", children: /* @__PURE__ */ jsxs(RPieChart, { children: [
|
|
46
|
+
children: hasData ? /* @__PURE__ */ jsx(ResponsiveContainer, { width: "100%", height: "100%", minWidth: 0, children: /* @__PURE__ */ jsxs(RPieChart, { children: [
|
|
47
47
|
/* @__PURE__ */ jsx(
|
|
48
48
|
Pie,
|
|
49
49
|
{
|
|
@@ -640,23 +640,31 @@ function NumberedPagination({
|
|
|
640
640
|
justify: "between",
|
|
641
641
|
gap: "md",
|
|
642
642
|
wrap: true,
|
|
643
|
-
className: cn("ui-data-table-pagination", className),
|
|
643
|
+
className: cn("ui-data-table-pagination ui-data-table-pagination--numbered", className),
|
|
644
644
|
children: [
|
|
645
|
-
/* @__PURE__ */ jsxs(Flex, { direction: "row", align: "center", gap: "sm", children: [
|
|
646
|
-
/* @__PURE__ */ jsx("span", { className: "text-muted-foreground text-sm", children: t("dataGrid.rowsPerPage") }),
|
|
645
|
+
/* @__PURE__ */ jsxs(Flex, { direction: "row", align: "center", gap: "sm", className: "ui-data-table-page-size", children: [
|
|
646
|
+
/* @__PURE__ */ jsx("span", { className: "ui-data-table-page-size-label text-muted-foreground text-sm", children: t("dataGrid.rowsPerPage") }),
|
|
647
647
|
/* @__PURE__ */ jsxs(
|
|
648
648
|
Select,
|
|
649
649
|
{
|
|
650
650
|
value: String(pageSize),
|
|
651
651
|
onValueChange: (v) => table.setPageSize(Number(v)),
|
|
652
652
|
children: [
|
|
653
|
-
/* @__PURE__ */ jsx(
|
|
653
|
+
/* @__PURE__ */ jsx(
|
|
654
|
+
SelectTrigger,
|
|
655
|
+
{
|
|
656
|
+
size: "sm",
|
|
657
|
+
"aria-label": t("dataGrid.rowsPerPage"),
|
|
658
|
+
className: "ui-data-table-page-size-trigger w-auto shrink-0 tabular-nums",
|
|
659
|
+
children: /* @__PURE__ */ jsx(SelectValue, {})
|
|
660
|
+
}
|
|
661
|
+
),
|
|
654
662
|
/* @__PURE__ */ jsx(SelectContent, { children: pageSizeOptions.map((n) => /* @__PURE__ */ jsx(SelectItem, { value: String(n), className: "tabular-nums", children: n }, n)) })
|
|
655
663
|
]
|
|
656
664
|
}
|
|
657
665
|
)
|
|
658
666
|
] }),
|
|
659
|
-
/* @__PURE__ */ jsxs(Flex, { direction: "row", align: "center", gap: "sm", children: [
|
|
667
|
+
/* @__PURE__ */ jsxs(Flex, { direction: "row", align: "center", gap: "sm", className: "ui-data-table-page-nav", children: [
|
|
660
668
|
/* @__PURE__ */ jsx("span", { className: "text-muted-foreground text-sm tabular-nums", children: t("dataGrid.pageOf", { page: pageIndex + 1, total: Math.max(1, pageCount) }) }),
|
|
661
669
|
/* @__PURE__ */ jsx(
|
|
662
670
|
Button,
|
|
@@ -1,3 +1,3 @@
|
|
|
1
1
|
import type { CalendarProp } from "../../props/components/data-entry.prop.js";
|
|
2
2
|
export type { CalendarProp, CalendarProp as CalendarProps, } from "../../props/components/data-entry.prop.js";
|
|
3
|
-
export declare function Calendar({ className, classNames, showOutsideDays, ...props }: CalendarProp): import("react/jsx-runtime").JSX.Element;
|
|
3
|
+
export declare function Calendar({ className, classNames, showOutsideDays, "aria-label": ariaLabel, labels, ...props }: CalendarProp): import("react/jsx-runtime").JSX.Element;
|
|
@@ -9,6 +9,8 @@ function Calendar({
|
|
|
9
9
|
className,
|
|
10
10
|
classNames,
|
|
11
11
|
showOutsideDays = true,
|
|
12
|
+
"aria-label": ariaLabel,
|
|
13
|
+
labels,
|
|
12
14
|
...props
|
|
13
15
|
}) {
|
|
14
16
|
const rangeDefaults = props.mode === "range" ? { resetOnSelect: props.resetOnSelect ?? true } : null;
|
|
@@ -16,6 +18,11 @@ function Calendar({
|
|
|
16
18
|
DayPicker,
|
|
17
19
|
{
|
|
18
20
|
showOutsideDays,
|
|
21
|
+
"aria-label": ariaLabel,
|
|
22
|
+
labels: {
|
|
23
|
+
...labels,
|
|
24
|
+
labelNav: labels?.labelNav ?? (() => `${ariaLabel ?? "Calendar"} navigation`)
|
|
25
|
+
},
|
|
19
26
|
className: cn("relative w-fit p-3", className),
|
|
20
27
|
classNames: {
|
|
21
28
|
months: cn("flex flex-col gap-4 sm:flex-row", classNames?.months),
|
|
@@ -373,13 +373,20 @@ function SearchSelect({
|
|
|
373
373
|
]
|
|
374
374
|
}
|
|
375
375
|
),
|
|
376
|
-
renderLoadMore && hasMore ? /* @__PURE__ */ jsx(
|
|
377
|
-
|
|
378
|
-
|
|
379
|
-
|
|
380
|
-
|
|
376
|
+
renderLoadMore && hasMore ? /* @__PURE__ */ jsx(
|
|
377
|
+
"div",
|
|
378
|
+
{
|
|
379
|
+
className: "border-border shrink-0 border-t p-1",
|
|
380
|
+
onKeyDown: (event) => event.stopPropagation(),
|
|
381
|
+
children: renderLoadMore({
|
|
382
|
+
hasMore,
|
|
383
|
+
loading,
|
|
384
|
+
loadMore: () => {
|
|
385
|
+
if (!loading) void fetchPage(page + 1, debouncedQuery, true);
|
|
386
|
+
}
|
|
387
|
+
})
|
|
381
388
|
}
|
|
382
|
-
|
|
389
|
+
) : null
|
|
383
390
|
] })
|
|
384
391
|
}
|
|
385
392
|
)
|
|
@@ -76,7 +76,7 @@ function TransferPanel({
|
|
|
76
76
|
className: cn(
|
|
77
77
|
"flex cursor-pointer items-start gap-2 rounded-sm px-2 py-2 text-sm",
|
|
78
78
|
"hover:bg-accent hover:text-accent-foreground",
|
|
79
|
-
item.disabled && "pointer-events-none
|
|
79
|
+
item.disabled && "bg-muted/40 text-muted-foreground pointer-events-none"
|
|
80
80
|
),
|
|
81
81
|
children: [
|
|
82
82
|
/* @__PURE__ */ jsx(
|
|
@@ -174,39 +174,43 @@ function TreeSelectRoot({
|
|
|
174
174
|
}
|
|
175
175
|
};
|
|
176
176
|
return /* @__PURE__ */ jsxs(Popover, { open, onOpenChange: setOpen, children: [
|
|
177
|
-
/* @__PURE__ */
|
|
178
|
-
|
|
179
|
-
|
|
180
|
-
|
|
181
|
-
|
|
182
|
-
|
|
183
|
-
|
|
184
|
-
|
|
185
|
-
|
|
186
|
-
|
|
187
|
-
|
|
188
|
-
|
|
189
|
-
|
|
190
|
-
|
|
191
|
-
|
|
192
|
-
|
|
193
|
-
|
|
194
|
-
|
|
195
|
-
|
|
196
|
-
|
|
197
|
-
|
|
198
|
-
"
|
|
199
|
-
{
|
|
200
|
-
|
|
201
|
-
|
|
202
|
-
|
|
203
|
-
|
|
204
|
-
|
|
205
|
-
|
|
206
|
-
|
|
207
|
-
|
|
208
|
-
|
|
209
|
-
|
|
177
|
+
/* @__PURE__ */ jsxs("div", { className: "relative", children: [
|
|
178
|
+
/* @__PURE__ */ jsx(PopoverTrigger, { asChild: true, children: /* @__PURE__ */ jsxs(
|
|
179
|
+
Button,
|
|
180
|
+
{
|
|
181
|
+
id,
|
|
182
|
+
type: "button",
|
|
183
|
+
variant: "outline",
|
|
184
|
+
role: "combobox",
|
|
185
|
+
"aria-expanded": open,
|
|
186
|
+
"aria-haspopup": "tree",
|
|
187
|
+
"aria-controls": open ? treeId : void 0,
|
|
188
|
+
...fieldA11y,
|
|
189
|
+
disabled,
|
|
190
|
+
className: cn(
|
|
191
|
+
"w-full justify-between font-normal",
|
|
192
|
+
allowClear && displayKeys.length > 0 && !disabled && "pe-10",
|
|
193
|
+
controlOpenRingClass,
|
|
194
|
+
!displayKeys.length && "text-muted-foreground",
|
|
195
|
+
className
|
|
196
|
+
),
|
|
197
|
+
children: [
|
|
198
|
+
/* @__PURE__ */ jsx("span", { className: "truncate", children: displayKeys.length ? displayLabel : resolvedPlaceholder }),
|
|
199
|
+
/* @__PURE__ */ jsx("span", { className: "ms-2 flex shrink-0 items-center", children: !(allowClear && displayKeys.length > 0 && !disabled) && /* @__PURE__ */ jsx(ChevronsUpDown, { className: "size-4 opacity-50", "aria-hidden": "true" }) })
|
|
200
|
+
]
|
|
201
|
+
}
|
|
202
|
+
) }),
|
|
203
|
+
allowClear && displayKeys.length > 0 && !disabled && /* @__PURE__ */ jsx(
|
|
204
|
+
"button",
|
|
205
|
+
{
|
|
206
|
+
type: "button",
|
|
207
|
+
"aria-label": t("dataEntry.treeSelect.clear"),
|
|
208
|
+
className: "absolute end-3 top-1/2 z-10 flex size-6 -translate-y-1/2 items-center justify-center rounded-sm opacity-50 hover:opacity-100 focus-visible:opacity-100",
|
|
209
|
+
onClick: clearValue,
|
|
210
|
+
children: /* @__PURE__ */ jsx(X, { className: "size-4", "aria-hidden": "true" })
|
|
211
|
+
}
|
|
212
|
+
)
|
|
213
|
+
] }),
|
|
210
214
|
/* @__PURE__ */ jsxs(PopoverContent, { className: "w-[var(--radix-popover-trigger-width)] p-0", align: "start", children: [
|
|
211
215
|
showSearch && /* @__PURE__ */ jsx(Command, { shouldFilter: false, children: /* @__PURE__ */ jsx(
|
|
212
216
|
CommandInput,
|
|
@@ -319,7 +319,7 @@ function Upload({
|
|
|
319
319
|
"aria-label": t("dataEntry.upload.avatarLabel"),
|
|
320
320
|
children: [
|
|
321
321
|
!showPlaceholder && item?.previewUrl ? /* @__PURE__ */ jsx("img", { src: item.previewUrl, alt: "", className: "size-full object-cover" }) : /* @__PURE__ */ jsx("span", { className: "text-muted-foreground flex size-full items-center justify-center", children: /* @__PURE__ */ jsx(Camera, { className: controlIconClass, "aria-hidden": "true" }) }),
|
|
322
|
-
!disabled && /* @__PURE__ */ jsx("span", { className: "text-2xs absolute inset-x-0 bottom-0 bg-black/
|
|
322
|
+
!disabled && /* @__PURE__ */ jsx("span", { className: "text-2xs absolute inset-x-0 bottom-0 bg-black/70 py-1 text-center text-white", children: t("dataEntry.upload.change") })
|
|
323
323
|
]
|
|
324
324
|
}
|
|
325
325
|
),
|
|
@@ -37,6 +37,7 @@ const DialogOverlay = React.forwardRef(({ className, ...props }, ref) => /* @__P
|
|
|
37
37
|
));
|
|
38
38
|
DialogOverlay.displayName = DialogPrimitive.Overlay.displayName;
|
|
39
39
|
const DialogContent = React.forwardRef(({ className, children, showClose, showCloseButton: showCloseButtonProp, ...props }, ref) => {
|
|
40
|
+
const { t } = useTranslation();
|
|
40
41
|
const showCloseButton = showCloseButtonProp ?? showClose ?? true;
|
|
41
42
|
return /* @__PURE__ */ jsxs(DialogPortal, { children: [
|
|
42
43
|
/* @__PURE__ */ jsx(DialogOverlay, {}),
|
|
@@ -59,7 +60,7 @@ const DialogContent = React.forwardRef(({ className, children, showClose, showCl
|
|
|
59
60
|
className: "ring-offset-background focus:ring-ring transition-opacity focus:ring-2 focus:ring-offset-2 focus:outline-hidden disabled:pointer-events-none",
|
|
60
61
|
children: [
|
|
61
62
|
/* @__PURE__ */ jsx(X, { className: "size-4", "aria-hidden": "true" }),
|
|
62
|
-
/* @__PURE__ */ jsx("span", { className: "sr-only", children: "
|
|
63
|
+
/* @__PURE__ */ jsx("span", { className: "sr-only", children: t("feedback.alert.dismiss") })
|
|
63
64
|
]
|
|
64
65
|
}
|
|
65
66
|
) : null
|
|
@@ -138,6 +139,7 @@ const AlertDialogOverlay = React.forwardRef(({ className, ...props }, ref) => /*
|
|
|
138
139
|
));
|
|
139
140
|
AlertDialogOverlay.displayName = AlertDialogPrimitive.Overlay.displayName;
|
|
140
141
|
const AlertDialogContent = React.forwardRef(({ className, children, showClose, showCloseButton: showCloseButtonProp, ...props }, ref) => {
|
|
142
|
+
const { t } = useTranslation();
|
|
141
143
|
const showCloseButton = showCloseButtonProp ?? showClose ?? false;
|
|
142
144
|
return /* @__PURE__ */ jsxs(
|
|
143
145
|
AlertDialogPrimitive.Content,
|
|
@@ -156,7 +158,7 @@ const AlertDialogContent = React.forwardRef(({ className, children, showClose, s
|
|
|
156
158
|
{
|
|
157
159
|
type: "button",
|
|
158
160
|
className: "ring-offset-background focus:ring-ring transition-opacity focus:ring-2 focus:ring-offset-2 focus:outline-hidden disabled:pointer-events-none",
|
|
159
|
-
"aria-label": "
|
|
161
|
+
"aria-label": t("feedback.alert.dismiss"),
|
|
160
162
|
children: /* @__PURE__ */ jsx(X, { className: "size-4", "aria-hidden": "true" })
|
|
161
163
|
}
|
|
162
164
|
) }) : null
|
|
@@ -6,6 +6,7 @@ import { cva } from "class-variance-authority";
|
|
|
6
6
|
import { X } from "lucide-react";
|
|
7
7
|
import { cn } from "../../lib/utils.js";
|
|
8
8
|
import { overlayHeaderToneClass } from "./overlay-header-tone.js";
|
|
9
|
+
import { useTranslation } from "../../i18n/use-translation.js";
|
|
9
10
|
const toCssLength = (v) => typeof v === "number" ? `${v}px` : v;
|
|
10
11
|
function Sheet(props) {
|
|
11
12
|
return /* @__PURE__ */ jsx(DialogPrimitive.Root, { "data-slot": "sheet", ...props });
|
|
@@ -55,6 +56,7 @@ const sheetVariants = cva(
|
|
|
55
56
|
);
|
|
56
57
|
const SheetContent = React.forwardRef(
|
|
57
58
|
({ side = "right", className, children, showCloseButton = true, width, style, ...props }, ref) => {
|
|
59
|
+
const { t } = useTranslation();
|
|
58
60
|
const horizontal = side === "left" || side === "right";
|
|
59
61
|
const widthSet = width != null && horizontal;
|
|
60
62
|
const mergedStyle = widthSet ? { ...style, ["--sheet-width"]: toCssLength(width) } : style;
|
|
@@ -82,7 +84,7 @@ const SheetContent = React.forwardRef(
|
|
|
82
84
|
className: "ring-offset-background focus:ring-ring absolute end-4 top-4 rounded-sm opacity-70 transition-opacity hover:opacity-100 focus:ring-2 focus:ring-offset-2 focus:outline-hidden disabled:pointer-events-none",
|
|
83
85
|
children: [
|
|
84
86
|
/* @__PURE__ */ jsx(X, { className: "size-4", "aria-hidden": "true" }),
|
|
85
|
-
/* @__PURE__ */ jsx("span", { className: "sr-only", children: "
|
|
87
|
+
/* @__PURE__ */ jsx("span", { className: "sr-only", children: t("feedback.alert.dismiss") })
|
|
86
88
|
]
|
|
87
89
|
}
|
|
88
90
|
) : null
|
|
@@ -175,7 +177,7 @@ const SheetDescription = React.forwardRef(({ className, ...props }, ref) => /* @
|
|
|
175
177
|
{
|
|
176
178
|
ref,
|
|
177
179
|
"data-slot": "sheet-description",
|
|
178
|
-
className: cn("text-
|
|
180
|
+
className: cn("text-foreground/80 text-sm", className),
|
|
179
181
|
...props
|
|
180
182
|
}
|
|
181
183
|
));
|
|
@@ -33,7 +33,7 @@ const buttonVariants = cva("ui-button", {
|
|
|
33
33
|
sm: "ui-button--sm gap-1.5 has-[>svg]:px-2.5",
|
|
34
34
|
lg: "ui-button--lg has-[>svg]:px-4",
|
|
35
35
|
icon: "ui-button--icon",
|
|
36
|
-
"icon-xs": "
|
|
36
|
+
"icon-xs": "ui-button--icon-xs [&_svg]:size-3 [&_svg]:shrink-0",
|
|
37
37
|
"icon-sm": "ui-button--icon-sm",
|
|
38
38
|
"icon-lg": "ui-button--icon-lg"
|
|
39
39
|
},
|
|
@@ -105,7 +105,7 @@ const Button = React.forwardRef(
|
|
|
105
105
|
"disabled:pointer-events-none disabled:opacity-50",
|
|
106
106
|
"data-[loading]:pointer-events-none",
|
|
107
107
|
"aria-invalid:border-destructive aria-invalid:ring-destructive/20",
|
|
108
|
-
"[&_svg]:pointer-events-none [&_svg]:shrink-0
|
|
108
|
+
"[&_svg]:pointer-events-none [&_svg]:shrink-0",
|
|
109
109
|
buttonVariants({ variant, size, shape, className })
|
|
110
110
|
),
|
|
111
111
|
ref,
|
|
@@ -8,6 +8,6 @@ export type BreadcrumbProps = {
|
|
|
8
8
|
* Multiple Breadcrumb instances on one page/view need a DISTINCT name each — two `<nav>`
|
|
9
9
|
* landmarks sharing one name/role fail axe's `landmark-unique` (WCAG 2.4.1 / 1.3.1).
|
|
10
10
|
*/
|
|
11
|
-
|
|
11
|
+
ariaLabel?: string;
|
|
12
12
|
};
|
|
13
|
-
export declare function Breadcrumb({ items, linkComponent: LinkComponent,
|
|
13
|
+
export declare function Breadcrumb({ items, linkComponent: LinkComponent, ariaLabel, }: BreadcrumbProps): import("react/jsx-runtime").JSX.Element;
|
|
@@ -5,7 +5,7 @@ import { useTranslation } from "../../i18n/use-translation.js";
|
|
|
5
5
|
function Breadcrumb({
|
|
6
6
|
items,
|
|
7
7
|
linkComponent: LinkComponent = "a",
|
|
8
|
-
|
|
8
|
+
ariaLabel
|
|
9
9
|
}) {
|
|
10
10
|
const { t } = useTranslation();
|
|
11
11
|
return /* @__PURE__ */ jsx("nav", { "aria-label": ariaLabel ?? t("navigation.breadcrumb.ariaLabel"), className: "ui-breadcrumb", children: /* @__PURE__ */ jsx("ol", { className: "ui-breadcrumb-list", children: items.map((item, index) => {
|
|
@@ -2,7 +2,7 @@ import type { PageContainerProp, PageInsetProp } from "../../props/components/la
|
|
|
2
2
|
export type { PageContainerProp, PageContainerProp as PageContainerProps, } from "../../props/components/layout.prop.js";
|
|
3
3
|
export type { BreadcrumbItemProp, BreadcrumbItemProp as BreadcrumbItem, } from "../../props/vocabulary/navigation.prop.js";
|
|
4
4
|
export declare function PageContainerInset({ className, children, ...props }: PageInsetProp): import("react/jsx-runtime").JSX.Element;
|
|
5
|
-
declare function PageContainerRoot({ title, subtitle, extra, footer, breadcrumb, breadcrumbAriaLabel, linkComponent: LinkComponent, density, variant, stickyFooter, footerReveal, fill, children, className, }: PageContainerProp): import("react/jsx-runtime").JSX.Element;
|
|
5
|
+
declare function PageContainerRoot({ title, subtitle, extra, footer, breadcrumb, breadcrumbLabel, breadcrumbAriaLabel, linkComponent: LinkComponent, density, variant, stickyFooter, footerReveal, fill, children, className, }: PageContainerProp): import("react/jsx-runtime").JSX.Element;
|
|
6
6
|
export declare const PageContainer: typeof PageContainerRoot & {
|
|
7
7
|
Inset: typeof PageContainerInset;
|
|
8
8
|
};
|
|
@@ -39,6 +39,7 @@ function PageContainerRoot({
|
|
|
39
39
|
extra,
|
|
40
40
|
footer,
|
|
41
41
|
breadcrumb,
|
|
42
|
+
breadcrumbLabel,
|
|
42
43
|
breadcrumbAriaLabel,
|
|
43
44
|
linkComponent: LinkComponent = "a",
|
|
44
45
|
density,
|
|
@@ -72,7 +73,7 @@ function PageContainerRoot({
|
|
|
72
73
|
breadcrumb && breadcrumb.length > 0 && /* @__PURE__ */ jsx(
|
|
73
74
|
"nav",
|
|
74
75
|
{
|
|
75
|
-
"aria-label": breadcrumbAriaLabel ?? t("navigation.breadcrumb.ariaLabel"),
|
|
76
|
+
"aria-label": breadcrumbLabel ?? breadcrumbAriaLabel ?? t("navigation.breadcrumb.ariaLabel"),
|
|
76
77
|
className: "ui-breadcrumb",
|
|
77
78
|
children: /* @__PURE__ */ jsx("ol", { className: "ui-breadcrumb-list", children: breadcrumb.map((item, i) => {
|
|
78
79
|
const isLast = i === breadcrumb.length - 1;
|
|
@@ -18,4 +18,4 @@ type SidebarItemProps = {
|
|
|
18
18
|
export declare function SidebarHeader({ children, className, ...props }: SidebarHeaderProps): import("react/jsx-runtime").JSX.Element;
|
|
19
19
|
export declare function SidebarSection({ label, collapsed, children, className, ...props }: SidebarSectionProps & React.HTMLAttributes<HTMLDivElement>): import("react/jsx-runtime").JSX.Element;
|
|
20
20
|
export declare function SidebarItem({ item, active, sub, onActivate, renderItem, children, ...props }: SidebarItemProps & Omit<React.ButtonHTMLAttributes<HTMLButtonElement>, "onClick">): import("react/jsx-runtime").JSX.Element;
|
|
21
|
-
export declare function Sidebar({ activeId, onSelect, sections, product, onProductClick, brand, collapsed, children, renderItem, footer, "aria-label": ariaLabel, }: SidebarProp): import("react/jsx-runtime").JSX.Element;
|
|
21
|
+
export declare function Sidebar({ ariaLabel: ariaLabelCamel, activeId, onSelect, sections, product, onProductClick, brand, collapsed, children, renderItem, footer, "aria-label": ariaLabel, }: SidebarProp): import("react/jsx-runtime").JSX.Element;
|
|
@@ -209,6 +209,7 @@ function CollapsedRow({ item, activeId, onSelect }) {
|
|
|
209
209
|
] });
|
|
210
210
|
}
|
|
211
211
|
function Sidebar({
|
|
212
|
+
ariaLabel: ariaLabelCamel,
|
|
212
213
|
activeId,
|
|
213
214
|
onSelect,
|
|
214
215
|
sections,
|
|
@@ -256,7 +257,7 @@ function Sidebar({
|
|
|
256
257
|
meta
|
|
257
258
|
] });
|
|
258
259
|
})() : null,
|
|
259
|
-
/* @__PURE__ */ jsx("nav", { className: "sb-nav-scroll", "aria-label": ariaLabel ?? t("layout.sidebar.ariaLabel"), children: children ?? resolvedSections.map((section, sectionIndex) => /* @__PURE__ */ jsx(
|
|
260
|
+
/* @__PURE__ */ jsx("nav", { className: "sb-nav-scroll", "aria-label": ariaLabel ?? ariaLabelCamel ?? t("layout.sidebar.ariaLabel"), children: children ?? resolvedSections.map((section, sectionIndex) => /* @__PURE__ */ jsx(
|
|
260
261
|
SidebarSection,
|
|
261
262
|
{
|
|
262
263
|
label: section.label,
|
|
@@ -3,5 +3,7 @@ export type SplitPaneProps = {
|
|
|
3
3
|
children: ReactNode;
|
|
4
4
|
aside: ReactNode;
|
|
5
5
|
asideWidth?: "sm" | "md";
|
|
6
|
+
/** Accessible complementary landmark name; required when multiple panes share a document. */
|
|
7
|
+
asideLabel?: string;
|
|
6
8
|
};
|
|
7
|
-
export declare function SplitPane({ children, aside, asideWidth }: SplitPaneProps): import("react/jsx-runtime").JSX.Element;
|
|
9
|
+
export declare function SplitPane({ children, aside, asideWidth, asideLabel }: SplitPaneProps): import("react/jsx-runtime").JSX.Element;
|
|
@@ -1,8 +1,8 @@
|
|
|
1
1
|
import { jsx, jsxs } from "react/jsx-runtime";
|
|
2
|
-
function SplitPane({ children, aside, asideWidth = "md" }) {
|
|
2
|
+
function SplitPane({ children, aside, asideWidth = "md", asideLabel }) {
|
|
3
3
|
return /* @__PURE__ */ jsx("div", { className: "ui-split-pane-scope", children: /* @__PURE__ */ jsxs("div", { className: "ui-split-pane", "data-aside-width": asideWidth, children: [
|
|
4
4
|
/* @__PURE__ */ jsx("div", { className: "ui-split-pane-main", children }),
|
|
5
|
-
/* @__PURE__ */ jsx("aside", { className: "ui-split-pane-aside", children: aside })
|
|
5
|
+
/* @__PURE__ */ jsx("aside", { className: "ui-split-pane-aside", "aria-label": asideLabel, children: aside })
|
|
6
6
|
] }) });
|
|
7
7
|
}
|
|
8
8
|
export {
|
|
@@ -22,5 +22,5 @@ declare const PaginationNext: React.ForwardRefExoticComponent<Omit<Omit<React.De
|
|
|
22
22
|
disabled?: boolean;
|
|
23
23
|
href?: string;
|
|
24
24
|
} & React.RefAttributes<HTMLButtonElement>>;
|
|
25
|
-
export declare function Pagination({ value, total, pageSize, pageSizeOptions, showSizeChanger, showTotal, hideOnSinglePage, simple, disabled, className, onValueChange,
|
|
25
|
+
export declare function Pagination({ ariaLabel, value, total, pageSize, pageSizeOptions, showSizeChanger, showTotal, hideOnSinglePage, simple, disabled, className, onValueChange, }: PaginationProp): import("react/jsx-runtime").JSX.Element | null;
|
|
26
26
|
export { PaginationContent, PaginationItem, PaginationLink, PaginationEllipsis, PaginationPrevious, PaginationNext, };
|
|
@@ -82,6 +82,7 @@ const PaginationNext = React.forwardRef(
|
|
|
82
82
|
);
|
|
83
83
|
PaginationNext.displayName = "PaginationNext";
|
|
84
84
|
function Pagination({
|
|
85
|
+
ariaLabel,
|
|
85
86
|
value = 1,
|
|
86
87
|
total = 0,
|
|
87
88
|
pageSize = 10,
|
|
@@ -92,8 +93,7 @@ function Pagination({
|
|
|
92
93
|
simple,
|
|
93
94
|
disabled,
|
|
94
95
|
className,
|
|
95
|
-
onValueChange
|
|
96
|
-
"aria-label": ariaLabel
|
|
96
|
+
onValueChange
|
|
97
97
|
}) {
|
|
98
98
|
const { t } = useTranslation();
|
|
99
99
|
const navLabel = ariaLabel ?? t("navigation.pagination.ariaLabel");
|
|
@@ -102,7 +102,7 @@ const TabsTrigger = React.forwardRef(({ className, ...props }, ref) => /* @__PUR
|
|
|
102
102
|
ref,
|
|
103
103
|
"data-slot": "tabs-trigger",
|
|
104
104
|
className: cn(
|
|
105
|
-
"text-foreground
|
|
105
|
+
"text-muted-foreground ring-offset-background hover:text-foreground focus-visible:border-ring focus-visible:outline-ring focus-visible:ring-ring/50 data-[state=active]:bg-background data-[state=active]:text-foreground data-[state=active]:ring-primary/25 after:bg-foreground relative inline-flex flex-1 items-center justify-center gap-1.5 rounded-md border border-transparent px-3 py-1 text-sm font-medium whitespace-nowrap transition-all group-data-[orientation=vertical]/tabs:w-full group-data-[orientation=vertical]/tabs:justify-start after:absolute after:opacity-0 after:transition-opacity group-data-[orientation=horizontal]/tabs:after:inset-x-0 group-data-[orientation=horizontal]/tabs:after:bottom-[-5px] group-data-[orientation=horizontal]/tabs:after:h-0.5 group-data-[orientation=vertical]/tabs:after:inset-y-0 group-data-[orientation=vertical]/tabs:after:-right-1 group-data-[orientation=vertical]/tabs:after:w-0.5 focus-visible:ring-[3px] focus-visible:outline-1 disabled:pointer-events-none disabled:opacity-50 data-[state=active]:ring-1 group-data-[variant=default]/tabs-list:data-[state=active]:shadow-sm group-data-[variant=line]/tabs-list:data-[state=active]:bg-transparent group-data-[variant=line]/tabs-list:data-[state=active]:shadow-none group-data-[variant=line]/tabs-list:data-[state=active]:after:opacity-100",
|
|
106
106
|
className
|
|
107
107
|
),
|
|
108
108
|
...props
|
|
@@ -10,4 +10,4 @@ export declare function flattenItemPages<TItem, TPage extends {
|
|
|
10
10
|
* `useInfiniteQuery` lifecycle widget — flatten pages, load-more footer.
|
|
11
11
|
* Cursor / activity feeds where user accumulates pages (vs DataTable cursor buttons).
|
|
12
12
|
*/
|
|
13
|
-
export declare function InfiniteQueryState<TPage, TFlat>({ query, skeleton, empty, flatten, isEmpty, errorRenderer, showRetry, onRetry, loadingMore, loadMore, showLoadMore, children, }: InfiniteQueryStateProp<TPage, TFlat>): import("react/jsx-runtime").JSX.Element;
|
|
13
|
+
export declare function InfiniteQueryState<TPage, TFlat>({ query, skeleton, empty, flatten, isEmpty, errorRenderer, showRetry, onRetry, onAuthError, loadingMore, loadMore, showLoadMore, children, }: InfiniteQueryStateProp<TPage, TFlat>): import("react/jsx-runtime").JSX.Element;
|
|
@@ -4,6 +4,7 @@ import * as React from "react";
|
|
|
4
4
|
import { AlertQueryError } from "../feedback/alert.js";
|
|
5
5
|
import { Button } from "../general/button.js";
|
|
6
6
|
import { useTranslation } from "../../i18n/use-translation.js";
|
|
7
|
+
import { classifyQueryError } from "../../lib/query-error.js";
|
|
7
8
|
function flattenItemPages(data) {
|
|
8
9
|
if (!data) return [];
|
|
9
10
|
return data.pages.flatMap((page) => page.items);
|
|
@@ -19,8 +20,9 @@ function InfiniteQueryState({
|
|
|
19
20
|
flatten,
|
|
20
21
|
isEmpty = defaultIsEmptyFlat,
|
|
21
22
|
errorRenderer,
|
|
22
|
-
showRetry =
|
|
23
|
+
showRetry = false,
|
|
23
24
|
onRetry,
|
|
25
|
+
onAuthError,
|
|
24
26
|
loadingMore,
|
|
25
27
|
loadMore,
|
|
26
28
|
showLoadMore = true,
|
|
@@ -38,7 +40,17 @@ function InfiniteQueryState({
|
|
|
38
40
|
if (query.isError) {
|
|
39
41
|
if (query.isFetching && !query.isFetchingNextPage) return /* @__PURE__ */ jsx(Fragment, { children: skeleton });
|
|
40
42
|
if (errorRenderer) return /* @__PURE__ */ jsx(Fragment, { children: errorRenderer(query.error, retry) });
|
|
41
|
-
|
|
43
|
+
const info = classifyQueryError(query.error);
|
|
44
|
+
const canRetry = (info.category === "transient" || info.category === "unknown") && (info.retryable || showRetry || Boolean(onRetry));
|
|
45
|
+
return /* @__PURE__ */ jsx(
|
|
46
|
+
AlertQueryError,
|
|
47
|
+
{
|
|
48
|
+
error: query.error,
|
|
49
|
+
category: info.category,
|
|
50
|
+
onRetry: canRetry ? retry : void 0,
|
|
51
|
+
onAuthAction: info.category === "auth" ? onAuthError : void 0
|
|
52
|
+
}
|
|
53
|
+
);
|
|
42
54
|
}
|
|
43
55
|
const data = query.data;
|
|
44
56
|
if (!data) return /* @__PURE__ */ jsx(Fragment, { children: skeleton });
|
|
@@ -449,6 +449,12 @@ export type CascaderProp = FieldA11yProps & {
|
|
|
449
449
|
expandTrigger?: "click" | "hover";
|
|
450
450
|
fieldNames?: TreeFieldNamesProp;
|
|
451
451
|
allowClear?: boolean;
|
|
452
|
+
"aria-label"?: string;
|
|
453
|
+
"aria-labelledby"?: string;
|
|
454
|
+
"aria-describedby"?: string;
|
|
455
|
+
"aria-errormessage"?: string;
|
|
456
|
+
"aria-invalid"?: boolean | "true" | "false";
|
|
457
|
+
"aria-required"?: boolean | "true" | "false";
|
|
452
458
|
};
|
|
453
459
|
export type ShowCheckedStrategyProp = "SHOW_CHILD" | "SHOW_PARENT" | "SHOW_ALL";
|
|
454
460
|
/** @see TreeSelect — tree in Popover (cmdk search + expand/collapse). */
|
|
@@ -469,6 +475,12 @@ export type TreeSelectProp = FieldA11yProps & {
|
|
|
469
475
|
className?: ClassNameProp;
|
|
470
476
|
id?: IdProp;
|
|
471
477
|
fieldNames?: TreeFieldNamesProp;
|
|
478
|
+
"aria-label"?: string;
|
|
479
|
+
"aria-labelledby"?: string;
|
|
480
|
+
"aria-describedby"?: string;
|
|
481
|
+
"aria-errormessage"?: string;
|
|
482
|
+
"aria-invalid"?: boolean | "true" | "false";
|
|
483
|
+
"aria-required"?: boolean | "true" | "false";
|
|
472
484
|
};
|
|
473
485
|
/** @see TransferItem */
|
|
474
486
|
export type TransferItemProp = {
|
|
@@ -15,6 +15,8 @@ export type PageContainerProp = {
|
|
|
15
15
|
* renders on the same page/view — two `<nav>` landmarks sharing one name/role fail axe's
|
|
16
16
|
* `landmark-unique` (WCAG 2.4.1 / 1.3.1).
|
|
17
17
|
*/
|
|
18
|
+
breadcrumbLabel?: string;
|
|
19
|
+
/** Kebab/DOM-style alias of `breadcrumbLabel` (same landmark-unique override). */
|
|
18
20
|
breadcrumbAriaLabel?: string;
|
|
19
21
|
linkComponent?: React.ElementType;
|
|
20
22
|
density?: PageDensityProp;
|
|
@@ -138,6 +140,8 @@ export type SidebarSectionProp = {
|
|
|
138
140
|
};
|
|
139
141
|
/** @see Sidebar */
|
|
140
142
|
export type SidebarProp = {
|
|
143
|
+
/** Accessible navigation landmark name; make it unique when multiple sidebars share a document. */
|
|
144
|
+
ariaLabel?: string;
|
|
141
145
|
activeId: string;
|
|
142
146
|
onSelect?: (id: string) => void;
|
|
143
147
|
sections?: SidebarSectionProp[];
|
|
@@ -16,6 +16,14 @@ export type ToolbarGroupProp = {
|
|
|
16
16
|
};
|
|
17
17
|
/** @see Pagination — offset/page-based (distinct from DataTable cursor pagination). */
|
|
18
18
|
export type PaginationProp = {
|
|
19
|
+
/**
|
|
20
|
+
* Override the `<nav>` landmark's accessible name. Defaults to a localized "Pagination".
|
|
21
|
+
* Multiple Pagination instances on one page/view (e.g. two independent result lists) need a
|
|
22
|
+
* DISTINCT name each — two `<nav>` landmarks sharing one name/role fail axe's `landmark-unique`
|
|
23
|
+
* (WCAG 2.4.1 / 1.3.1). Pass something that names what is being paged, e.g. `"注文一覧の
|
|
24
|
+
* ページネーション"` vs `"請求書一覧のページネーション"`.
|
|
25
|
+
*/
|
|
26
|
+
ariaLabel?: string;
|
|
19
27
|
value?: number;
|
|
20
28
|
total?: number;
|
|
21
29
|
pageSize?: number;
|
|
@@ -34,14 +42,6 @@ export type PaginationProp = {
|
|
|
34
42
|
disabled?: DisabledProp;
|
|
35
43
|
className?: ClassNameProp;
|
|
36
44
|
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;
|
|
45
45
|
};
|
|
46
46
|
export type StepStatusProp = "wait" | "process" | "finish" | "error";
|
|
47
47
|
/** @see StepItem */
|
|
@@ -57,6 +57,8 @@ export type InfiniteQueryStateProp<TPage, TFlat> = {
|
|
|
57
57
|
errorRenderer?: (error: unknown, retry: () => void) => React.ReactNode;
|
|
58
58
|
showRetry?: boolean;
|
|
59
59
|
onRetry?: HandlerProp;
|
|
60
|
+
/** Recovery for authentication errors (401 / expired token), shown instead of Retry. */
|
|
61
|
+
onAuthError?: HandlerProp;
|
|
60
62
|
loadingMore?: React.ReactNode;
|
|
61
63
|
/** Custom load-more footer; `false` hides footer entirely. */
|
|
62
64
|
loadMore?: React.ReactNode | false;
|
|
@@ -8,6 +8,7 @@
|
|
|
8
8
|
gap: var(--space-stack-sm);
|
|
9
9
|
margin: 0;
|
|
10
10
|
inline-size: 100%;
|
|
11
|
+
min-inline-size: 0;
|
|
11
12
|
}
|
|
12
13
|
|
|
13
14
|
.ui-chart-title {
|
|
@@ -18,6 +19,7 @@
|
|
|
18
19
|
|
|
19
20
|
.ui-chart-canvas {
|
|
20
21
|
inline-size: 100%;
|
|
22
|
+
min-inline-size: 0;
|
|
21
23
|
}
|
|
22
24
|
|
|
23
25
|
/* recharts legend/axis text inherits the design typography + muted tone. */
|
package/dist/styles/control.css
CHANGED
|
@@ -202,6 +202,21 @@
|
|
|
202
202
|
* icon button can sit flush beside a labelled one (split buttons, toolbars). Derive them from
|
|
203
203
|
* the density tokens — never from a hand-written offset off the base --control-height, which
|
|
204
204
|
* is how icon-sm drifted a step down to the xs height (issue #133). */
|
|
205
|
+
.ui-button--icon-xs {
|
|
206
|
+
width: var(--control-height-xs);
|
|
207
|
+
height: var(--control-height-xs);
|
|
208
|
+
padding: 0;
|
|
209
|
+
}
|
|
210
|
+
|
|
211
|
+
/* Rule #24: compact visual tiers never shrink the actual coarse-pointer hit target below 44px.
|
|
212
|
+
* The glyph remains 12px; only the interactive square expands. */
|
|
213
|
+
@media (pointer: coarse) {
|
|
214
|
+
.ui-button--icon-xs {
|
|
215
|
+
width: var(--control-height-default);
|
|
216
|
+
height: var(--control-height-default);
|
|
217
|
+
}
|
|
218
|
+
}
|
|
219
|
+
|
|
205
220
|
.ui-button--icon-sm {
|
|
206
221
|
width: var(--control-height-sm);
|
|
207
222
|
height: var(--control-height-sm);
|
package/dist/styles/layout.css
CHANGED
|
@@ -403,13 +403,38 @@
|
|
|
403
403
|
}
|
|
404
404
|
|
|
405
405
|
.ui-page-title {
|
|
406
|
-
font-size: var(--
|
|
406
|
+
font-size: var(--page-title-font-size);
|
|
407
407
|
font-weight: var(--font-weight-medium);
|
|
408
408
|
letter-spacing: var(--letter-spacing-tight);
|
|
409
409
|
line-height: var(--line-height-tight);
|
|
410
410
|
overflow-wrap: anywhere;
|
|
411
411
|
}
|
|
412
412
|
|
|
413
|
+
/* Compact viewports use a responsive type step, not compact density: body/control text and
|
|
414
|
+
* touch targets remain readable while page chrome stops competing with primary actions. A
|
|
415
|
+
* single Flex action group must wrap even when the consumer omitted `wrap`, because clipping
|
|
416
|
+
* header actions makes functionality unreachable. */
|
|
417
|
+
@media (max-width: 639px) {
|
|
418
|
+
.ui-page-container {
|
|
419
|
+
--space-page-active-x: var(--space-page-compact-x);
|
|
420
|
+
--space-page-active-y: var(--space-page-compact-y);
|
|
421
|
+
--space-section-active: var(--space-section-compact);
|
|
422
|
+
}
|
|
423
|
+
|
|
424
|
+
.ui-page-title {
|
|
425
|
+
font-size: var(--page-title-font-size-compact);
|
|
426
|
+
}
|
|
427
|
+
|
|
428
|
+
.ui-page-header .ui-page-subtitle {
|
|
429
|
+
font-size: var(--page-subtitle-font-size-compact);
|
|
430
|
+
}
|
|
431
|
+
|
|
432
|
+
.ui-page-header-extra > .ui-flex[data-direction="row"] {
|
|
433
|
+
flex-wrap: wrap;
|
|
434
|
+
max-width: 100%;
|
|
435
|
+
}
|
|
436
|
+
}
|
|
437
|
+
|
|
413
438
|
@media (min-width: 640px) {
|
|
414
439
|
.ui-page-header-row {
|
|
415
440
|
flex-direction: row;
|
|
@@ -426,7 +451,7 @@
|
|
|
426
451
|
}
|
|
427
452
|
|
|
428
453
|
.ui-page-subtitle {
|
|
429
|
-
font-size: var(--font-size
|
|
454
|
+
font-size: var(--page-subtitle-font-size);
|
|
430
455
|
color: hsl(var(--muted-foreground));
|
|
431
456
|
margin-top: var(--space-1);
|
|
432
457
|
}
|
|
@@ -1,4 +1,11 @@
|
|
|
1
1
|
@layer components {
|
|
2
|
+
[data-slot="tabs-list"] {
|
|
3
|
+
max-inline-size: var(--tabs-list-max-inline-size);
|
|
4
|
+
overflow-x: var(--tabs-list-overflow);
|
|
5
|
+
overscroll-behavior-inline: contain;
|
|
6
|
+
scrollbar-width: thin;
|
|
7
|
+
}
|
|
8
|
+
|
|
2
9
|
.ui-context-menu-content {
|
|
3
10
|
z-index: 50;
|
|
4
11
|
min-width: 10rem;
|
|
@@ -82,6 +82,31 @@
|
|
|
82
82
|
padding-top: var(--space-stack-sm);
|
|
83
83
|
}
|
|
84
84
|
|
|
85
|
+
/* Numbered footer may wrap only between its two semantic groups. The supported JA/EN/VI locale
|
|
86
|
+
* label and select stay fully visible together (gh#184). */
|
|
87
|
+
.ui-data-table-pagination--numbered {
|
|
88
|
+
flex-wrap: wrap;
|
|
89
|
+
min-width: 0;
|
|
90
|
+
}
|
|
91
|
+
|
|
92
|
+
.ui-data-table-page-size {
|
|
93
|
+
flex: 0 0 auto;
|
|
94
|
+
flex-wrap: nowrap;
|
|
95
|
+
max-width: 100%;
|
|
96
|
+
min-width: 0;
|
|
97
|
+
}
|
|
98
|
+
|
|
99
|
+
.ui-data-table-page-size-label {
|
|
100
|
+
flex: 0 0 auto;
|
|
101
|
+
white-space: nowrap;
|
|
102
|
+
}
|
|
103
|
+
|
|
104
|
+
.ui-data-table-page-size-trigger,
|
|
105
|
+
.ui-data-table-page-nav {
|
|
106
|
+
flex: 0 0 auto;
|
|
107
|
+
white-space: nowrap;
|
|
108
|
+
}
|
|
109
|
+
|
|
85
110
|
.ui-data-table-root {
|
|
86
111
|
display: flex;
|
|
87
112
|
flex-direction: column;
|
|
@@ -12,6 +12,8 @@
|
|
|
12
12
|
--filter-picker-width-md: 14rem;
|
|
13
13
|
--breadcrumb-font-size: var(--font-size-xs);
|
|
14
14
|
--menubar-shortcut-font-size: var(--font-size-xs);
|
|
15
|
+
--tabs-list-max-inline-size: 100%;
|
|
16
|
+
--tabs-list-overflow: auto;
|
|
15
17
|
|
|
16
18
|
/* Menu item hover/highlight tint — `initial` so the --accent default re-resolves at the call site
|
|
17
19
|
* under a scoped theme (a :root binding to a role var freezes at :root).
|
|
@@ -21,6 +21,9 @@
|
|
|
21
21
|
--space-page-active-x: var(--space-page-x);
|
|
22
22
|
--space-page-active-y: var(--space-page-y);
|
|
23
23
|
--space-section-active: var(--space-section);
|
|
24
|
+
--space-page-compact-x: var(--space-4); /* 16px mobile page gutter */
|
|
25
|
+
--space-page-compact-y: var(--space-4);
|
|
26
|
+
--space-section-compact: var(--space-4);
|
|
24
27
|
|
|
25
28
|
/* Modal scrim — the single backdrop colour shared by EVERY overlay (Dialog, AlertDialog, Sheet,
|
|
26
29
|
* Drawer). Themeable (rule #44) so a service tints the wash to its brand once, e.g. a navy
|
|
@@ -38,6 +41,13 @@
|
|
|
38
41
|
* old fixed 16px pad that left 24 above vs 32 below. */
|
|
39
42
|
--page-header-pad-bottom: calc(var(--space-page-active-y) - var(--space-section-active));
|
|
40
43
|
|
|
44
|
+
/* Responsive page typography is independent from density. Density changes information spacing;
|
|
45
|
+
* these tokens change only page chrome so mobile keeps readable body text and touch targets. */
|
|
46
|
+
--page-title-font-size: var(--heading-h1);
|
|
47
|
+
--page-title-font-size-compact: var(--heading-h2);
|
|
48
|
+
--page-subtitle-font-size: var(--font-size-base);
|
|
49
|
+
--page-subtitle-font-size-compact: var(--font-size-sm);
|
|
50
|
+
|
|
41
51
|
/* Section "chrome" padding — the SHARED inset for header / body / footer of every overlay-ish
|
|
42
52
|
* surface (Dialog · Sheet · Drawer · Card). One global knob: a service sets these once instead of
|
|
43
53
|
* per-component. Vertical is tightened (16 vs the old 24) and density-aware (see density.css);
|
package/package.json
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@godxjp/ui",
|
|
3
|
-
"version": "18.0.
|
|
4
|
-
"godxUiMcp": "18.0.
|
|
3
|
+
"version": "18.0.3",
|
|
4
|
+
"godxUiMcp": "18.0.2",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"packageManager": "pnpm@10.29.1",
|
|
7
7
|
"sideEffects": false,
|
|
@@ -276,13 +276,33 @@
|
|
|
276
276
|
"test:watch": "vitest",
|
|
277
277
|
"test:coverage": "vitest run --coverage",
|
|
278
278
|
"check:example-imports": "node scripts/check-example-imports.mjs",
|
|
279
|
+
"check:frame-coverage": "node scripts/frame-coverage.mjs",
|
|
280
|
+
"check:screen-reader-evidence": "node scripts/check-screen-reader-evidence.mjs",
|
|
281
|
+
"check:voiceover-capture": "node scripts/check-voiceover-capture.mjs",
|
|
282
|
+
"check:data-entry-frame-runtime": "node scripts/check-data-entry-frame-runtime.mjs",
|
|
283
|
+
"check:data-entry-owner-source": "node scripts/check-data-entry-owner-source.mjs",
|
|
284
|
+
"check:data-entry-touch-aria": "node scripts/check-data-entry-touch-aria.mjs",
|
|
285
|
+
"check:layout-nav-frames": "node scripts/check-layout-nav-frames.mjs",
|
|
286
|
+
"check:provider-feedback-query-runtime": "for frames in navigation-app-setting-picker,feedback-dialog,feedback-sheet,feedback-alert-dialog feedback-tooltip,feedback-toast,feedback-skeleton,query-data-state query-infinite-query-state,query-mutation-feedback,query-prefetch-link; do FRAMES=$frames node scripts/check-provider-feedback-query-runtime.mjs || exit 1; done",
|
|
287
|
+
"check:layout-nav-closure": "for frames in layout-flex,layout-app-shell,layout-aspect-ratio,layout-auth-shell layout-page-container,layout-resizable-panel,layout-separator,layout-sidebar layout-split-pane,layout-topbar,navigation-breadcrumb,navigation-app-setting-picker navigation-context-menu,navigation-dropdown-menu,navigation-menubar,navigation-navigation-menu navigation-steps,navigation-toolbar,navigation-tabs,navigation-pagination; do FRAMES=$frames node scripts/check-layout-nav-closure.mjs || exit 1; done",
|
|
288
|
+
"check:display-runtime-evidence": "node scripts/check-display-runtime-evidence.mjs",
|
|
289
|
+
"check:data-table-pagination-wrap": "node scripts/check-data-table-pagination-wrap.mjs",
|
|
290
|
+
"check:button-icon-xs": "node scripts/check-button-icon-xs.mjs",
|
|
291
|
+
"check:frame-contracts": "pnpm check:component-api-manifest && pnpm audit:component-cases && pnpm check:frame-coverage && pnpm check:screen-reader-evidence && pnpm check:data-entry-owner-source && pnpm check:display-runtime-evidence",
|
|
292
|
+
"check:final-touch-rtl": "node scripts/check-final-touch-rtl.mjs",
|
|
293
|
+
"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",
|
|
294
|
+
"pretest": "pnpm check:frame-coverage",
|
|
279
295
|
"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:
|
|
296
|
+
"verify:static": "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 test",
|
|
297
|
+
"verify:release": "pnpm verify:static && pnpm check:frame-contracts && pnpm check:frame-coverage && pnpm check:frame-axe",
|
|
281
298
|
"check:mcp-lockstep": "node scripts/check-release-lockstep.mjs",
|
|
282
299
|
"check:mcp-pattern-imports": "node scripts/check-mcp-pattern-imports.mjs",
|
|
283
300
|
"check:mcp-sync": "node scripts/check-mcp-sync.mjs",
|
|
284
301
|
"check:mcp-orphans": "node scripts/check-mcp-orphans.mjs",
|
|
285
302
|
"check:mcp-prop-sync": "node scripts/check-mcp-prop-sync.mjs",
|
|
303
|
+
"gen:component-api-manifest": "node scripts/gen-component-api-manifest.mjs",
|
|
304
|
+
"check:component-api-manifest": "node scripts/gen-component-api-manifest.mjs --check",
|
|
305
|
+
"audit:component-cases": "node scripts/check-component-case-evidence.mjs",
|
|
286
306
|
"check:prop-vocabulary": "node scripts/check-prop-vocabulary.mjs",
|
|
287
307
|
"check:token-tiers": "node scripts/check-token-tiers.mjs",
|
|
288
308
|
"check:control-sizing": "node scripts/check-control-sizing.mjs",
|
|
@@ -307,7 +327,6 @@
|
|
|
307
327
|
"check:visual-audit": "node scripts/visual-audit-smoke.mjs",
|
|
308
328
|
"check:frame-axe": "node scripts/check-frame-axe.mjs",
|
|
309
329
|
"check:frame-geometry": "node scripts/frame-geometry.mjs",
|
|
310
|
-
"check:frame-coverage": "node scripts/frame-coverage.mjs",
|
|
311
330
|
"postinstall": "node scripts/postinstall.mjs",
|
|
312
331
|
"init-agent": "node scripts/init-agent-kit.mjs",
|
|
313
332
|
"check:use-client": "node scripts/check-use-client.mjs"
|