@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
|
@@ -4,6 +4,7 @@ import * as React from "react";
|
|
|
4
4
|
import { ChevronDown, ChevronRight, ChevronsUpDown, X } from "lucide-react";
|
|
5
5
|
import { useTranslation } from "../../i18n/use-translation.js";
|
|
6
6
|
import { cn } from "../../lib/utils.js";
|
|
7
|
+
import { pickFieldA11y } from "../../lib/field-a11y.js";
|
|
7
8
|
import { controlOpenRingClass } from "../../lib/control-styles.js";
|
|
8
9
|
import { Button } from "../general/button.js";
|
|
9
10
|
import { Popover, PopoverContent, PopoverTrigger } from "../data-display/popover.js";
|
|
@@ -57,9 +58,13 @@ function TreeSelectRoot({
|
|
|
57
58
|
allowClear = true,
|
|
58
59
|
className,
|
|
59
60
|
id,
|
|
60
|
-
fieldNames
|
|
61
|
+
fieldNames,
|
|
62
|
+
...ariaProps
|
|
61
63
|
}) {
|
|
62
64
|
const { t } = useTranslation();
|
|
65
|
+
const fieldA11y = pickFieldA11y(ariaProps);
|
|
66
|
+
const reactId = React.useId();
|
|
67
|
+
const treeId = `${id ?? reactId}-tree`;
|
|
63
68
|
const options = React.useMemo(
|
|
64
69
|
() => normalizeTreeOptions(treeDataProp, fieldNames),
|
|
65
70
|
[treeDataProp, fieldNames]
|
|
@@ -177,6 +182,9 @@ function TreeSelectRoot({
|
|
|
177
182
|
variant: "outline",
|
|
178
183
|
role: "combobox",
|
|
179
184
|
"aria-expanded": open,
|
|
185
|
+
"aria-haspopup": "tree",
|
|
186
|
+
"aria-controls": open ? treeId : void 0,
|
|
187
|
+
...fieldA11y,
|
|
180
188
|
disabled,
|
|
181
189
|
className: cn(
|
|
182
190
|
"w-full justify-between font-normal",
|
|
@@ -211,6 +219,7 @@ function TreeSelectRoot({
|
|
|
211
219
|
/* @__PURE__ */ jsx(ScrollArea, { className: "max-h-[min(300px,50vh)]", children: /* @__PURE__ */ jsx(
|
|
212
220
|
"div",
|
|
213
221
|
{
|
|
222
|
+
id: treeId,
|
|
214
223
|
role: "tree",
|
|
215
224
|
"aria-multiselectable": Boolean(checkable) || Boolean(multiple),
|
|
216
225
|
className: "p-1",
|
|
@@ -3,4 +3,4 @@ export type { UploadProp, UploadProp as UploadProps, UploadFileItemProp, UploadV
|
|
|
3
3
|
export type { UploadFileItem, UploadVariant, UploadCommitAction } from "./upload-types.js";
|
|
4
4
|
export { collectUploadCommitActions, createUploadItem } from "./upload-types.js";
|
|
5
5
|
export { useUploadDraft } from "./use-upload-draft.js";
|
|
6
|
-
export declare function Upload({ variant, value, defaultValue, onValueChange, accept: acceptProp, multiple: multipleProp, maxCount: maxCountProp, maxSizeBytes, disabled, removable, onUpload, className, children, }: UploadProp): import("react/jsx-runtime").JSX.Element;
|
|
6
|
+
export declare function Upload({ variant, value, defaultValue, onValueChange, accept: acceptProp, multiple: multipleProp, maxCount: maxCountProp, maxSizeBytes, disabled, removable, onUpload, id, className, children, ...ariaProps }: UploadProp): import("react/jsx-runtime").JSX.Element;
|
|
@@ -5,6 +5,7 @@ import { Camera, ImagePlus, RotateCcw, Trash2, Upload as UploadIcon, X } from "l
|
|
|
5
5
|
import { useTranslation } from "../../i18n/use-translation.js";
|
|
6
6
|
import { formatBytes } from "../../lib/format.js";
|
|
7
7
|
import { cn } from "../../lib/utils.js";
|
|
8
|
+
import { resolveFieldA11y } from "../../lib/field-a11y.js";
|
|
8
9
|
import { controlIconClass } from "../../lib/control-styles.js";
|
|
9
10
|
import { Button } from "../general/button.js";
|
|
10
11
|
import { UploadCropDialog } from "./upload-crop-dialog.js";
|
|
@@ -84,10 +85,13 @@ function Upload({
|
|
|
84
85
|
disabled,
|
|
85
86
|
removable = true,
|
|
86
87
|
onUpload,
|
|
88
|
+
id,
|
|
87
89
|
className,
|
|
88
|
-
children
|
|
90
|
+
children,
|
|
91
|
+
...ariaProps
|
|
89
92
|
}) {
|
|
90
93
|
const { t } = useTranslation();
|
|
94
|
+
const inputA11y = resolveFieldA11y(ariaProps, t("dataEntry.upload.inputLabel"));
|
|
91
95
|
const accept = acceptProp ?? defaultAcceptForVariant(variant);
|
|
92
96
|
const maxCount = maxCountProp ?? defaultMaxCount(variant);
|
|
93
97
|
const multiple = multipleProp ?? (maxCount === 1 ? false : true);
|
|
@@ -144,12 +148,13 @@ function Upload({
|
|
|
144
148
|
"input",
|
|
145
149
|
{
|
|
146
150
|
ref: inputRef,
|
|
151
|
+
id,
|
|
147
152
|
type: "file",
|
|
148
153
|
className: "sr-only",
|
|
149
154
|
accept,
|
|
150
155
|
multiple: multiple && !isSingleAvatar,
|
|
151
156
|
disabled,
|
|
152
|
-
|
|
157
|
+
...inputA11y,
|
|
153
158
|
onChange: (e) => {
|
|
154
159
|
pickFiles(e.target.files);
|
|
155
160
|
e.target.value = "";
|
|
@@ -1,3 +1,3 @@
|
|
|
1
1
|
import type { AppShellProp } from "../../props/components/layout.prop.js";
|
|
2
2
|
export type { AppShellProp, AppShellProp as AppShellProps, } from "../../props/components/layout.prop.js";
|
|
3
|
-
export declare function AppShell({ sidebar, topbar, topbarLeft, topbarRight, logo, breadcrumb, footer, children, sidebarCollapsed, }: AppShellProp): import("react/jsx-runtime").JSX.Element;
|
|
3
|
+
export declare function AppShell({ sidebar, topbar, topbarLeft, topbarRight, logo, breadcrumb, footer, children, sidebarCollapsed, mobileNav, mobileNavLabel, mobileNavOpen, onMobileNavOpenChange, }: AppShellProp): import("react/jsx-runtime").JSX.Element;
|
|
@@ -1,6 +1,10 @@
|
|
|
1
1
|
"use client";
|
|
2
2
|
import { jsx, jsxs } from "react/jsx-runtime";
|
|
3
|
+
import * as React from "react";
|
|
4
|
+
import { Menu } from "lucide-react";
|
|
3
5
|
import { useTranslation } from "../../i18n/use-translation.js";
|
|
6
|
+
import { Button } from "../general/button.js";
|
|
7
|
+
import { Sheet, SheetBody, SheetContent, SheetHeader, SheetTrigger } from "../feedback/sheet.js";
|
|
4
8
|
function AppShell({
|
|
5
9
|
sidebar,
|
|
6
10
|
topbar,
|
|
@@ -10,9 +14,25 @@ function AppShell({
|
|
|
10
14
|
breadcrumb,
|
|
11
15
|
footer,
|
|
12
16
|
children,
|
|
13
|
-
sidebarCollapsed = false
|
|
17
|
+
sidebarCollapsed = false,
|
|
18
|
+
mobileNav,
|
|
19
|
+
mobileNavLabel,
|
|
20
|
+
mobileNavOpen,
|
|
21
|
+
onMobileNavOpenChange
|
|
14
22
|
}) {
|
|
15
23
|
const { t } = useTranslation();
|
|
24
|
+
const drawerNav = mobileNav !== void 0 ? mobileNav : sidebar;
|
|
25
|
+
const hasDrawer = drawerNav != null;
|
|
26
|
+
const [uncontrolledOpen, setUncontrolledOpen] = React.useState(false);
|
|
27
|
+
const drawerOpen = mobileNavOpen ?? uncontrolledOpen;
|
|
28
|
+
const setDrawerOpen = onMobileNavOpenChange ?? setUncontrolledOpen;
|
|
29
|
+
const handleDrawerClick = (event) => {
|
|
30
|
+
const target = event.target;
|
|
31
|
+
const hit = target.closest("a[href], button, [role='menuitem']");
|
|
32
|
+
if (hit && !hit.classList.contains("sb-nav-group-trigger")) {
|
|
33
|
+
setDrawerOpen(false);
|
|
34
|
+
}
|
|
35
|
+
};
|
|
16
36
|
const resolvedTopbar = topbar !== void 0 ? topbar : /* @__PURE__ */ jsxs("div", { className: "app-topbar-rail", children: [
|
|
17
37
|
logo !== void 0 && /* @__PURE__ */ jsx("div", { className: "app-topbar-logo", children: logo }),
|
|
18
38
|
topbarLeft !== void 0 && /* @__PURE__ */ jsx("div", { className: "app-topbar-left", children: topbarLeft }),
|
|
@@ -21,7 +41,27 @@ function AppShell({
|
|
|
21
41
|
] });
|
|
22
42
|
return /* @__PURE__ */ jsxs("div", { className: "app-root", "data-collapsed": sidebarCollapsed ? "true" : void 0, children: [
|
|
23
43
|
/* @__PURE__ */ jsx("aside", { className: "app-sidebar", "aria-label": t("layout.appShell.sidebarLabel"), children: sidebar }),
|
|
24
|
-
/* @__PURE__ */
|
|
44
|
+
/* @__PURE__ */ jsxs("header", { className: "app-topbar ui-scale-fixed", "aria-label": t("layout.appShell.headerLabel"), children: [
|
|
45
|
+
hasDrawer && /* @__PURE__ */ jsxs(Sheet, { open: drawerOpen, onOpenChange: setDrawerOpen, children: [
|
|
46
|
+
/* @__PURE__ */ jsx(SheetTrigger, { asChild: true, children: /* @__PURE__ */ jsx(
|
|
47
|
+
Button,
|
|
48
|
+
{
|
|
49
|
+
type: "button",
|
|
50
|
+
variant: "ghost",
|
|
51
|
+
size: "sm",
|
|
52
|
+
className: "app-mobile-nav-trigger",
|
|
53
|
+
"aria-label": t("layout.appShell.openNav"),
|
|
54
|
+
"aria-haspopup": "dialog",
|
|
55
|
+
children: /* @__PURE__ */ jsx(Menu, { className: "size-5", "aria-hidden": "true" })
|
|
56
|
+
}
|
|
57
|
+
) }),
|
|
58
|
+
/* @__PURE__ */ jsxs(SheetContent, { side: "left", className: "app-mobile-nav-drawer", children: [
|
|
59
|
+
/* @__PURE__ */ jsx(SheetHeader, { title: mobileNavLabel ?? t("layout.appShell.navLabel") }),
|
|
60
|
+
/* @__PURE__ */ jsx(SheetBody, { className: "app-mobile-nav-body", onClick: handleDrawerClick, children: drawerNav })
|
|
61
|
+
] })
|
|
62
|
+
] }),
|
|
63
|
+
resolvedTopbar
|
|
64
|
+
] }),
|
|
25
65
|
/* @__PURE__ */ jsxs("main", { className: "app-main", "aria-label": t("layout.appShell.mainLabel"), children: [
|
|
26
66
|
breadcrumb !== void 0 && /* @__PURE__ */ jsx("div", { className: "app-breadcrumb", children: breadcrumb }),
|
|
27
67
|
children
|
|
@@ -3,5 +3,11 @@ import type { BreadcrumbProp } from "../../props/vocabulary/navigation.prop.js";
|
|
|
3
3
|
export type BreadcrumbProps = {
|
|
4
4
|
items: BreadcrumbProp;
|
|
5
5
|
linkComponent?: ElementType;
|
|
6
|
+
/**
|
|
7
|
+
* Override the `<nav>` landmark's accessible name. Defaults to a localized "Breadcrumb".
|
|
8
|
+
* Multiple Breadcrumb instances on one page/view need a DISTINCT name each — two `<nav>`
|
|
9
|
+
* landmarks sharing one name/role fail axe's `landmark-unique` (WCAG 2.4.1 / 1.3.1).
|
|
10
|
+
*/
|
|
11
|
+
"aria-label"?: string;
|
|
6
12
|
};
|
|
7
|
-
export declare function Breadcrumb({ items, linkComponent: LinkComponent }: BreadcrumbProps): import("react/jsx-runtime").JSX.Element;
|
|
13
|
+
export declare function Breadcrumb({ items, linkComponent: LinkComponent, "aria-label": ariaLabel, }: BreadcrumbProps): import("react/jsx-runtime").JSX.Element;
|
|
@@ -2,9 +2,13 @@
|
|
|
2
2
|
import { jsx, jsxs } from "react/jsx-runtime";
|
|
3
3
|
import { ChevronRight } from "lucide-react";
|
|
4
4
|
import { useTranslation } from "../../i18n/use-translation.js";
|
|
5
|
-
function Breadcrumb({
|
|
5
|
+
function Breadcrumb({
|
|
6
|
+
items,
|
|
7
|
+
linkComponent: LinkComponent = "a",
|
|
8
|
+
"aria-label": ariaLabel
|
|
9
|
+
}) {
|
|
6
10
|
const { t } = useTranslation();
|
|
7
|
-
return /* @__PURE__ */ jsx("nav", { "aria-label": t("navigation.breadcrumb.ariaLabel"), className: "ui-breadcrumb", children: /* @__PURE__ */ jsx("ol", { className: "ui-breadcrumb-list", children: items.map((item, index) => {
|
|
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) => {
|
|
8
12
|
const isLast = index === items.length - 1;
|
|
9
13
|
return /* @__PURE__ */ jsxs("li", { className: "ui-breadcrumb-item", children: [
|
|
10
14
|
item.to && !isLast ? /* @__PURE__ */ jsx(LinkComponent, { href: item.to, to: item.to, className: "ui-breadcrumb-link", children: item.label }) : /* @__PURE__ */ jsx("span", { className: "ui-breadcrumb-current", "aria-current": isLast ? "page" : void 0, children: item.label }),
|
|
@@ -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, 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, 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
|
};
|
|
@@ -2,6 +2,7 @@
|
|
|
2
2
|
import { jsx, jsxs } from "react/jsx-runtime";
|
|
3
3
|
import { useEffect, useRef, useState } from "react";
|
|
4
4
|
import { ChevronRight } from "lucide-react";
|
|
5
|
+
import { useTranslation } from "../../i18n/use-translation.js";
|
|
5
6
|
import { cn } from "../../lib/utils.js";
|
|
6
7
|
import { densityClass, pageContainerVariantClass } from "../../lib/variants.js";
|
|
7
8
|
function scrollParent(el) {
|
|
@@ -38,6 +39,7 @@ function PageContainerRoot({
|
|
|
38
39
|
extra,
|
|
39
40
|
footer,
|
|
40
41
|
breadcrumb,
|
|
42
|
+
breadcrumbAriaLabel,
|
|
41
43
|
linkComponent: LinkComponent = "a",
|
|
42
44
|
density,
|
|
43
45
|
variant = "default",
|
|
@@ -49,6 +51,7 @@ function PageContainerRoot({
|
|
|
49
51
|
}) {
|
|
50
52
|
const reveal = stickyFooter && footer != null && footerReveal === "onScroll";
|
|
51
53
|
const { headerRef, revealed } = useFooterReveal(reveal);
|
|
54
|
+
const { t } = useTranslation();
|
|
52
55
|
return /* @__PURE__ */ jsxs(
|
|
53
56
|
"div",
|
|
54
57
|
{
|
|
@@ -66,28 +69,35 @@ function PageContainerRoot({
|
|
|
66
69
|
),
|
|
67
70
|
children: [
|
|
68
71
|
/* @__PURE__ */ jsxs("header", { ref: headerRef, className: "ui-page-header", children: [
|
|
69
|
-
breadcrumb && breadcrumb.length > 0 && /* @__PURE__ */ jsx(
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
|
|
72
|
+
breadcrumb && breadcrumb.length > 0 && /* @__PURE__ */ jsx(
|
|
73
|
+
"nav",
|
|
74
|
+
{
|
|
75
|
+
"aria-label": breadcrumbAriaLabel ?? t("navigation.breadcrumb.ariaLabel"),
|
|
76
|
+
className: "ui-breadcrumb",
|
|
77
|
+
children: /* @__PURE__ */ jsx("ol", { className: "ui-breadcrumb-list", children: breadcrumb.map((item, i) => {
|
|
78
|
+
const isLast = i === breadcrumb.length - 1;
|
|
79
|
+
return /* @__PURE__ */ jsxs("li", { className: "ui-inline-xs", children: [
|
|
80
|
+
item.to && !isLast ? /* @__PURE__ */ jsx(
|
|
81
|
+
LinkComponent,
|
|
82
|
+
{
|
|
83
|
+
href: item.to,
|
|
84
|
+
to: item.to,
|
|
85
|
+
className: "hover:text-foreground hover:underline",
|
|
86
|
+
children: item.label
|
|
87
|
+
}
|
|
88
|
+
) : /* @__PURE__ */ jsx(
|
|
89
|
+
"span",
|
|
90
|
+
{
|
|
91
|
+
className: isLast ? "text-foreground" : "",
|
|
92
|
+
"aria-current": isLast ? "page" : void 0,
|
|
93
|
+
children: item.label
|
|
94
|
+
}
|
|
95
|
+
),
|
|
96
|
+
!isLast && /* @__PURE__ */ jsx(ChevronRight, { className: "size-3", "aria-hidden": "true" })
|
|
97
|
+
] }, i);
|
|
98
|
+
}) })
|
|
99
|
+
}
|
|
100
|
+
),
|
|
91
101
|
/* @__PURE__ */ jsxs("div", { className: "ui-page-header-row", children: [
|
|
92
102
|
/* @__PURE__ */ jsxs("div", { className: "min-w-0", children: [
|
|
93
103
|
/* @__PURE__ */ jsx("h1", { className: "ui-page-title", children: title }),
|
|
@@ -14,7 +14,7 @@ function resolveColumns(columns) {
|
|
|
14
14
|
};
|
|
15
15
|
}
|
|
16
16
|
function ResponsiveGrid({ columns = 4, children }) {
|
|
17
|
-
return /* @__PURE__ */ jsx("div", { className: "ui-responsive-grid", style: resolveColumns(columns), children });
|
|
17
|
+
return /* @__PURE__ */ jsx("div", { className: "ui-responsive-grid-scope", children: /* @__PURE__ */ jsx("div", { className: "ui-responsive-grid", style: resolveColumns(columns), children }) });
|
|
18
18
|
}
|
|
19
19
|
export {
|
|
20
20
|
ResponsiveGrid
|
|
@@ -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, }: SidebarProp): 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;
|
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
"use client";
|
|
2
|
-
import {
|
|
2
|
+
import { jsx, jsxs } from "react/jsx-runtime";
|
|
3
3
|
import * as React from "react";
|
|
4
|
+
import { Slot } from "@radix-ui/react-slot";
|
|
4
5
|
import { ChevronDown } from "lucide-react";
|
|
5
6
|
import { Collapsible, CollapsibleContent, CollapsibleTrigger } from "../data-display/collapsible.js";
|
|
6
7
|
import { Popover, PopoverContent, PopoverTrigger } from "../data-display/popover.js";
|
|
@@ -34,25 +35,52 @@ function SidebarItem({
|
|
|
34
35
|
const Icon = item.icon;
|
|
35
36
|
const showBadge = item.badge !== void 0 && item.badge !== "";
|
|
36
37
|
const disabled = item.disabled || props.disabled;
|
|
37
|
-
const
|
|
38
|
-
|
|
38
|
+
const custom = children ?? (renderItem ? renderItem(item) : void 0);
|
|
39
|
+
const rowClass = cn("sb-nav-item", sub && "sb-nav-item--sub");
|
|
40
|
+
const stateProps = {
|
|
41
|
+
className: rowClass,
|
|
42
|
+
"data-active": active ? "true" : void 0,
|
|
43
|
+
"aria-current": active ? "page" : void 0
|
|
44
|
+
};
|
|
45
|
+
if (custom !== void 0) {
|
|
46
|
+
return /* @__PURE__ */ jsx(Slot, { ...stateProps, "aria-disabled": disabled || void 0, children: custom });
|
|
47
|
+
}
|
|
48
|
+
if (item.href) {
|
|
49
|
+
return /* @__PURE__ */ jsxs(
|
|
50
|
+
"a",
|
|
51
|
+
{
|
|
52
|
+
...props,
|
|
53
|
+
href: disabled ? void 0 : item.href,
|
|
54
|
+
...stateProps,
|
|
55
|
+
"aria-disabled": disabled || void 0,
|
|
56
|
+
onClick: (event) => {
|
|
57
|
+
if (disabled) event.preventDefault();
|
|
58
|
+
else onActivate?.(item.id);
|
|
59
|
+
},
|
|
60
|
+
children: [
|
|
61
|
+
!sub ? /* @__PURE__ */ jsx("span", { className: "sb-icon", children: /* @__PURE__ */ jsx(Icon, { "aria-hidden": "true" }) }) : null,
|
|
62
|
+
/* @__PURE__ */ jsx("span", { className: "sb-label", children: item.label }),
|
|
63
|
+
showBadge ? /* @__PURE__ */ jsx("span", { className: "sb-badge", children: item.badge }) : null
|
|
64
|
+
]
|
|
65
|
+
}
|
|
66
|
+
);
|
|
67
|
+
}
|
|
68
|
+
return /* @__PURE__ */ jsxs(
|
|
39
69
|
"button",
|
|
40
70
|
{
|
|
41
71
|
type: "button",
|
|
42
|
-
|
|
43
|
-
"data-active": active ? "true" : void 0,
|
|
44
|
-
"aria-current": active ? "page" : void 0,
|
|
72
|
+
...stateProps,
|
|
45
73
|
"aria-disabled": disabled,
|
|
46
74
|
...props,
|
|
47
75
|
onClick: () => {
|
|
48
76
|
if (disabled) return;
|
|
49
77
|
onActivate?.(item.id);
|
|
50
78
|
},
|
|
51
|
-
children:
|
|
79
|
+
children: [
|
|
52
80
|
!sub ? /* @__PURE__ */ jsx("span", { className: "sb-icon", children: /* @__PURE__ */ jsx(Icon, { "aria-hidden": "true" }) }) : null,
|
|
53
81
|
/* @__PURE__ */ jsx("span", { className: "sb-label", children: item.label }),
|
|
54
82
|
showBadge ? /* @__PURE__ */ jsx("span", { className: "sb-badge", children: item.badge }) : null
|
|
55
|
-
]
|
|
83
|
+
]
|
|
56
84
|
}
|
|
57
85
|
);
|
|
58
86
|
}
|
|
@@ -95,7 +123,11 @@ function NavGroup({ item, activeId, onSelect, renderItem }) {
|
|
|
95
123
|
const Icon = item.icon;
|
|
96
124
|
const active = isItemActive(item, activeId);
|
|
97
125
|
const children = item.children ?? [];
|
|
98
|
-
|
|
126
|
+
const [open, setOpen] = React.useState(active);
|
|
127
|
+
React.useEffect(() => {
|
|
128
|
+
if (active) setOpen(true);
|
|
129
|
+
}, [active]);
|
|
130
|
+
return /* @__PURE__ */ jsxs(Collapsible, { open, onOpenChange: setOpen, className: "sb-nav-group", children: [
|
|
99
131
|
/* @__PURE__ */ jsxs(
|
|
100
132
|
CollapsibleTrigger,
|
|
101
133
|
{
|
|
@@ -186,7 +218,8 @@ function Sidebar({
|
|
|
186
218
|
collapsed = false,
|
|
187
219
|
children,
|
|
188
220
|
renderItem,
|
|
189
|
-
footer
|
|
221
|
+
footer,
|
|
222
|
+
"aria-label": ariaLabel
|
|
190
223
|
}) {
|
|
191
224
|
const { t } = useTranslation();
|
|
192
225
|
const resolvedSections = sections ?? [];
|
|
@@ -223,7 +256,7 @@ function Sidebar({
|
|
|
223
256
|
meta
|
|
224
257
|
] });
|
|
225
258
|
})() : null,
|
|
226
|
-
/* @__PURE__ */ jsx("nav", { className: "sb-nav-scroll", "aria-label": t("layout.sidebar.ariaLabel"), children: children ?? resolvedSections.map((section, sectionIndex) => /* @__PURE__ */ jsx(
|
|
259
|
+
/* @__PURE__ */ jsx("nav", { className: "sb-nav-scroll", "aria-label": ariaLabel ?? t("layout.sidebar.ariaLabel"), children: children ?? resolvedSections.map((section, sectionIndex) => /* @__PURE__ */ jsx(
|
|
227
260
|
SidebarSection,
|
|
228
261
|
{
|
|
229
262
|
label: section.label,
|
|
@@ -1,9 +1,9 @@
|
|
|
1
1
|
import { jsx, jsxs } from "react/jsx-runtime";
|
|
2
2
|
function SplitPane({ children, aside, asideWidth = "md" }) {
|
|
3
|
-
return /* @__PURE__ */ jsxs("div", { className: "ui-split-pane", "data-aside-width": asideWidth, children: [
|
|
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
5
|
/* @__PURE__ */ jsx("aside", { className: "ui-split-pane-aside", children: aside })
|
|
6
|
-
] });
|
|
6
|
+
] }) });
|
|
7
7
|
}
|
|
8
8
|
export {
|
|
9
9
|
SplitPane
|
|
@@ -63,7 +63,8 @@ const ARIA_KEY = {
|
|
|
63
63
|
};
|
|
64
64
|
const BRAND_NONE = "__app__";
|
|
65
65
|
const AppSettingPicker = React.forwardRef(
|
|
66
|
-
function AppSettingPicker2({ kind, appearance
|
|
66
|
+
function AppSettingPicker2({ kind, appearance, className, disabled, id, name, value, onValueChange }, ref) {
|
|
67
|
+
const resolvedAppearance = appearance ?? (kind === "locale" ? "icon" : "labeled");
|
|
67
68
|
const ctx = useOptionalAppContext();
|
|
68
69
|
const { t, locale, fallbackLocale } = useTranslation();
|
|
69
70
|
const raw = value ?? ctx?.[kind];
|
|
@@ -119,7 +120,7 @@ const AppSettingPicker = React.forwardRef(
|
|
|
119
120
|
}, [kind, ctx?.timezoneOptions, current, t, locale, fallbackLocale]);
|
|
120
121
|
const unbound = current === void 0 || !handleChange;
|
|
121
122
|
const Icon = ICON[kind];
|
|
122
|
-
const iconOnly =
|
|
123
|
+
const iconOnly = resolvedAppearance === "icon";
|
|
123
124
|
return /* @__PURE__ */ jsxs(
|
|
124
125
|
Select,
|
|
125
126
|
{
|
|
@@ -134,13 +135,20 @@ const AppSettingPicker = React.forwardRef(
|
|
|
134
135
|
{
|
|
135
136
|
ref,
|
|
136
137
|
id,
|
|
138
|
+
showIndicator: !iconOnly,
|
|
137
139
|
className: cn(
|
|
138
140
|
iconOnly ? (
|
|
139
|
-
// Structurally icon-only: drop the owned width + value spacing
|
|
140
|
-
// the density-aware --control-height tap target,
|
|
141
|
-
|
|
142
|
-
|
|
143
|
-
|
|
141
|
+
// Structurally icon-only: drop the owned width + value spacing and square the box to
|
|
142
|
+
// the density-aware --control-height tap target, centring the icon.
|
|
143
|
+
"w-[length:var(--control-height)] justify-center ps-0 pe-0"
|
|
144
|
+
) : (
|
|
145
|
+
// Labeled: sized to a per-kind width from `sm` up; below `sm` it hugs its content and
|
|
146
|
+
// caps at the container (`w-auto max-w-full`) instead of the old UNCONDITIONAL
|
|
147
|
+
// `w-full` — so a labeled picker dropped into a narrow topbar no longer stretches to
|
|
148
|
+
// fill the bar (gh#165). A form field that wants a full-width control passes
|
|
149
|
+
// `className="w-full"`, which wins over `w-auto`.
|
|
150
|
+
cn("w-auto max-w-full", TRIGGER_WIDTH[kind])
|
|
151
|
+
),
|
|
144
152
|
className
|
|
145
153
|
),
|
|
146
154
|
"aria-label": t(ARIA_KEY[kind]),
|
|
@@ -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, simple, disabled, className, onValueChange, }: PaginationProp): import("react/jsx-runtime").JSX.Element | null;
|
|
25
|
+
export declare function Pagination({ value, total, pageSize, pageSizeOptions, showSizeChanger, showTotal, hideOnSinglePage, simple, disabled, className, onValueChange, "aria-label": ariaLabel, }: PaginationProp): import("react/jsx-runtime").JSX.Element | null;
|
|
26
26
|
export { PaginationContent, PaginationItem, PaginationLink, PaginationEllipsis, PaginationPrevious, PaginationNext, };
|