@godxjp/ui 18.15.4 → 19.1.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/app/app-provider.d.ts +1 -1
- package/dist/app/app-provider.js +3 -0
- package/dist/app/date-format-labels.d.ts +1 -1
- package/dist/app/time-format-labels.d.ts +1 -1
- package/dist/components/data-display/badge.d.ts +1 -1
- package/dist/components/data-display/card.d.ts +4 -13
- package/dist/components/data-display/card.js +2 -15
- package/dist/components/data-display/data-table.d.ts +3 -8
- package/dist/components/data-display/data-table.js +106 -68
- package/dist/components/data-display/descriptions.js +34 -5
- package/dist/components/data-display/empty-state.js +1 -1
- package/dist/components/data-display/permission-matrix.js +7 -7
- package/dist/components/data-display/popover.js +2 -9
- package/dist/components/data-display/qr-code.d.ts +1 -1
- package/dist/components/data-display/scroll-area.d.ts +3 -1
- package/dist/components/data-display/scroll-area.js +150 -16
- package/dist/components/data-display/table.js +12 -3
- package/dist/components/data-entry/branch-scope-picker.js +4 -4
- package/dist/components/data-entry/calendar.js +15 -24
- package/dist/components/data-entry/cascader.js +70 -72
- package/dist/components/data-entry/checkbox-group.js +12 -5
- package/dist/components/data-entry/checkbox.js +30 -13
- package/dist/components/data-entry/command.d.ts +6 -6
- package/dist/components/data-entry/date-picker.js +34 -17
- package/dist/components/data-entry/date-range-picker.js +19 -13
- package/dist/components/data-entry/form-field.d.ts +1 -1
- package/dist/components/data-entry/form-field.js +22 -5
- package/dist/components/data-entry/index.d.ts +2 -1
- package/dist/components/data-entry/input.js +18 -22
- package/dist/components/data-entry/label.js +4 -2
- package/dist/components/data-entry/month-picker.js +20 -17
- package/dist/components/data-entry/month-range-picker.js +26 -19
- package/dist/components/data-entry/radio.js +25 -6
- package/dist/components/data-entry/search-select.d.ts +1 -1
- package/dist/components/data-entry/search-select.js +37 -31
- package/dist/components/data-entry/select.d.ts +8 -0
- package/dist/components/data-entry/select.js +68 -26
- package/dist/components/data-entry/switch.js +16 -2
- package/dist/components/data-entry/textarea.d.ts +56 -0
- package/dist/components/data-entry/textarea.js +110 -40
- package/dist/components/data-entry/time-picker.js +52 -52
- package/dist/components/data-entry/toggle-group.d.ts +1 -0
- package/dist/components/data-entry/toggle.d.ts +1 -1
- package/dist/components/data-entry/transfer.js +14 -15
- package/dist/components/data-entry/tree-select.js +19 -23
- package/dist/components/data-entry/upload-crop-dialog.js +4 -4
- package/dist/components/data-entry/upload.d.ts +1 -1
- package/dist/components/data-entry/upload.js +46 -46
- package/dist/components/feedback/alert.js +7 -14
- package/dist/components/feedback/dialog.d.ts +23 -32
- package/dist/components/feedback/dialog.js +16 -13
- package/dist/components/feedback/sheet.d.ts +1 -1
- package/dist/components/feedback/sheet.js +14 -14
- package/dist/components/feedback/skeleton.js +13 -10
- package/dist/components/feedback/sonner.d.ts +1 -1
- package/dist/components/feedback/sonner.js +17 -8
- package/dist/components/feedback/tooltip.js +1 -1
- package/dist/components/general/activity.d.ts +44 -0
- package/dist/components/general/activity.js +65 -0
- package/dist/components/general/button.d.ts +2 -2
- package/dist/components/general/button.js +11 -24
- package/dist/components/general/index.d.ts +2 -0
- package/dist/components/general/index.js +2 -0
- package/dist/components/layout/app-shell.js +5 -3
- package/dist/components/layout/auth-divider.d.ts +9 -2
- package/dist/components/layout/auth-divider.js +7 -11
- package/dist/components/layout/index.d.ts +1 -0
- package/dist/components/layout/page-container.d.ts +1 -1
- package/dist/components/layout/page-container.js +32 -20
- package/dist/components/layout/resizable.d.ts +12 -12
- package/dist/components/layout/separator.d.ts +1 -0
- package/dist/components/layout/service-role-panel.js +47 -42
- package/dist/components/layout/sidebar.js +13 -1
- package/dist/components/layout/split-pane.d.ts +12 -1
- package/dist/components/layout/split-pane.js +13 -4
- package/dist/components/navigation/app-setting-picker.js +5 -14
- package/dist/components/navigation/dropdown-menu.js +10 -16
- package/dist/components/navigation/menubar.d.ts +3 -6
- package/dist/components/navigation/pagination-utils.d.ts +15 -2
- package/dist/components/navigation/pagination-utils.js +27 -21
- package/dist/components/navigation/pagination.d.ts +4 -4
- package/dist/components/navigation/pagination.js +2 -2
- package/dist/components/navigation/steps.js +31 -67
- package/dist/components/navigation/tabs.js +17 -5
- package/dist/components/query/infinite-query-state.js +2 -2
- package/dist/components/ui/accordion.d.ts +1 -1
- package/dist/components/ui/avatar.d.ts +1 -1
- package/dist/components/ui/avatar.js +29 -10
- package/dist/components/ui/input-otp.d.ts +8 -6
- package/dist/components/ui/rating.js +1 -1
- package/dist/components/ui/separator.d.ts +27 -2
- package/dist/components/ui/separator.js +42 -11
- package/dist/components/ui/toggle-group.d.ts +15 -5
- package/dist/components/ui/toggle-group.js +43 -18
- package/dist/components/ui/toggle.d.ts +66 -5
- package/dist/components/ui/toggle.js +64 -9
- package/dist/i18n/messages/en.json +8 -0
- package/dist/i18n/messages/ja.json +8 -0
- package/dist/i18n/messages/vi.json +8 -0
- package/dist/lib/control-styles.d.ts +14 -0
- package/dist/lib/control-styles.js +2 -0
- package/dist/lib/field-a11y.d.ts +52 -0
- package/dist/lib/field-a11y.js +17 -2
- package/dist/props/components/app.prop.d.ts +15 -0
- package/dist/props/components/data-display.prop.d.ts +85 -3
- package/dist/props/components/data-entry.prop.d.ts +35 -2
- package/dist/props/components/general.prop.d.ts +52 -1
- package/dist/props/components/layout.prop.d.ts +137 -2
- package/dist/props/registry.d.ts +116 -5
- package/dist/props/registry.js +165 -4
- package/dist/props/vocabulary/index.d.ts +2 -2
- package/dist/props/vocabulary/interaction.prop.d.ts +15 -0
- package/dist/props/vocabulary/layout.prop.d.ts +8 -0
- package/dist/styles/alert-layout.css +69 -3
- package/dist/styles/badge-layout.css +2 -2
- package/dist/styles/base.css +6 -0
- package/dist/styles/card-layout.css +25 -8
- package/dist/styles/control.css +1150 -29
- package/dist/styles/data-display-layout.css +185 -11
- package/dist/styles/data-entry-layout.css +352 -1
- package/dist/styles/density.css +2 -2
- package/dist/styles/dialog-layout.css +203 -4
- package/dist/styles/focus-ring.css +155 -0
- package/dist/styles/form-layout.css +50 -5
- package/dist/styles/index.css +1 -0
- package/dist/styles/layout.css +412 -23
- package/dist/styles/motion.css +178 -0
- package/dist/styles/navigation-layout.css +398 -22
- package/dist/styles/shell-layout.css +137 -39
- package/dist/styles/table-layout.css +153 -22
- package/dist/styles/toggle.css +59 -0
- package/dist/tokens/base.css +5 -0
- package/dist/tokens/components/activity.css +64 -0
- package/dist/tokens/components/badge.css +7 -0
- package/dist/tokens/components/card.css +14 -10
- package/dist/tokens/components/chart.css +1 -1
- package/dist/tokens/components/control.css +358 -8
- package/dist/tokens/components/data-display.css +75 -0
- package/dist/tokens/components/data-entry.css +25 -0
- package/dist/tokens/components/descriptions.css +22 -0
- package/dist/tokens/components/feedback.css +143 -4
- package/dist/tokens/components/form.css +16 -0
- package/dist/tokens/components/legal-document.css +5 -1
- package/dist/tokens/components/navigation.css +109 -0
- package/dist/tokens/components/scroll-area.css +21 -0
- package/dist/tokens/components/separator.css +52 -0
- package/dist/tokens/components/shell.css +132 -20
- package/dist/tokens/components/table.css +52 -3
- package/dist/tokens/components/toggle.css +82 -0
- package/dist/tokens/components/upload.css +107 -0
- package/dist/tokens/foundation.css +171 -10
- package/dist/tokens/semantic/layout.css +120 -1
- package/package.json +85 -68
- package/scripts/ui-audit.mjs +51 -2
|
@@ -6,20 +6,11 @@ import { cva } from "class-variance-authority";
|
|
|
6
6
|
import { Loader2 } from "lucide-react";
|
|
7
7
|
import { cn } from "../../lib/utils.js";
|
|
8
8
|
import { useTranslation } from "../../i18n/use-translation.js";
|
|
9
|
-
const buttonCountClass = {
|
|
10
|
-
default: "bg-primary-foreground/15",
|
|
11
|
-
destructive: "bg-destructive-foreground/15",
|
|
12
|
-
secondary: "bg-secondary-foreground/15",
|
|
13
|
-
outline: "bg-foreground/8 text-muted-foreground",
|
|
14
|
-
dashed: "bg-foreground/8 text-muted-foreground",
|
|
15
|
-
ghost: "bg-foreground/8 text-muted-foreground",
|
|
16
|
-
link: "bg-foreground/8 text-muted-foreground"
|
|
17
|
-
};
|
|
18
9
|
const buttonVariants = cva("ui-button", {
|
|
19
10
|
variants: {
|
|
20
11
|
variant: {
|
|
21
12
|
default: "ui-button--default bg-primary text-primary-foreground hover:bg-primary/90",
|
|
22
|
-
destructive: "ui-button--destructive bg-destructive text-destructive-foreground
|
|
13
|
+
destructive: "ui-button--destructive bg-destructive text-destructive-foreground",
|
|
23
14
|
outline: "ui-button--outline border bg-background shadow-xs hover:bg-accent hover:text-accent-foreground",
|
|
24
15
|
dashed: "ui-button--dashed border border-dashed bg-background hover:bg-accent hover:text-accent-foreground",
|
|
25
16
|
secondary: "ui-button--secondary bg-secondary text-secondary-foreground hover:bg-secondary/80",
|
|
@@ -27,13 +18,16 @@ const buttonVariants = cva("ui-button", {
|
|
|
27
18
|
link: "ui-button--link text-primary underline-offset-4 hover:underline"
|
|
28
19
|
},
|
|
29
20
|
size: {
|
|
30
|
-
default: "ui-button--default-size
|
|
31
|
-
md: "ui-button--default-size
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
21
|
+
default: "ui-button--default-size",
|
|
22
|
+
md: "ui-button--default-size",
|
|
23
|
+
// The glyph rules stay UTILITIES, not a components-layer rule: Tailwind v4 orders
|
|
24
|
+
// utilities after components, so only a utility can out-rank a child's own `size-*`.
|
|
25
|
+
// They read the token, so the value is still themeable.
|
|
26
|
+
xs: "ui-button--xs [&_svg:not([class*='size-'])]:size-[var(--button-xs-icon-size)]",
|
|
27
|
+
sm: "ui-button--sm",
|
|
28
|
+
lg: "ui-button--lg",
|
|
35
29
|
icon: "ui-button--icon",
|
|
36
|
-
"icon-xs": "ui-button--icon-xs [&_svg]:size-
|
|
30
|
+
"icon-xs": "ui-button--icon-xs [&_svg]:size-[var(--button-xs-icon-size)] [&_svg]:shrink-0",
|
|
37
31
|
"icon-sm": "ui-button--icon-sm",
|
|
38
32
|
"icon-lg": "ui-button--icon-lg"
|
|
39
33
|
},
|
|
@@ -79,10 +73,7 @@ const Button = React.forwardRef(
|
|
|
79
73
|
"span",
|
|
80
74
|
{
|
|
81
75
|
"data-slot": "button-count",
|
|
82
|
-
className:
|
|
83
|
-
"inline-flex min-w-4 items-center justify-center rounded-[var(--radius-pill)] px-1 text-xs leading-none tabular-nums",
|
|
84
|
-
buttonCountClass[variant ?? "default"]
|
|
85
|
-
),
|
|
76
|
+
className: "ui-button-count",
|
|
86
77
|
children: countLabel
|
|
87
78
|
}
|
|
88
79
|
) : null;
|
|
@@ -99,11 +90,7 @@ const Button = React.forwardRef(
|
|
|
99
90
|
disabled: isLoading || disabled,
|
|
100
91
|
type: asChild ? void 0 : type ?? "button",
|
|
101
92
|
className: cn(
|
|
102
|
-
"inline-flex shrink-0 items-center justify-center gap-2 text-sm font-medium whitespace-nowrap transition-all outline-none",
|
|
103
93
|
fullWidth && "w-full",
|
|
104
|
-
"focus-visible:border-ring focus-visible:ring-ring/50 focus-visible:ring-[3px]",
|
|
105
|
-
"disabled:pointer-events-none disabled:opacity-50",
|
|
106
|
-
"data-[loading]:pointer-events-none",
|
|
107
94
|
"aria-invalid:border-destructive aria-invalid:ring-destructive/20",
|
|
108
95
|
"[&_svg]:pointer-events-none [&_svg]:shrink-0",
|
|
109
96
|
buttonVariants({ variant, size, shape, className })
|
|
@@ -6,3 +6,5 @@ export { Logo } from "./logo.js";
|
|
|
6
6
|
export type { LogoMark, LogoProps, LogoSize, LogoTone } from "./logo.js";
|
|
7
7
|
export { Reveal } from "./reveal.js";
|
|
8
8
|
export type { RevealProp, RevealProps } from "./reveal.js";
|
|
9
|
+
export { Activity } from "./activity.js";
|
|
10
|
+
export type { ActivityProp, ActivityProps } from "./activity.js";
|
|
@@ -2,7 +2,9 @@ import { Button, buttonVariants } from "./button.js";
|
|
|
2
2
|
import { Text, Heading } from "./typography.js";
|
|
3
3
|
import { Logo } from "./logo.js";
|
|
4
4
|
import { Reveal } from "./reveal.js";
|
|
5
|
+
import { Activity } from "./activity.js";
|
|
5
6
|
export {
|
|
7
|
+
Activity,
|
|
6
8
|
Button,
|
|
7
9
|
Heading,
|
|
8
10
|
Logo,
|
|
@@ -35,6 +35,7 @@ function AppShell({
|
|
|
35
35
|
setDrawerOpen(false);
|
|
36
36
|
}
|
|
37
37
|
};
|
|
38
|
+
const hasTopbarContent = topbar !== void 0 || topbarLeft !== void 0 || topbarRight !== void 0 || logo !== void 0;
|
|
38
39
|
const resolvedTopbar = topbar !== void 0 ? topbar : /* @__PURE__ */ jsxs("div", { className: "app-topbar-rail", children: [
|
|
39
40
|
logo !== void 0 && /* @__PURE__ */ jsx("div", { className: "app-topbar-logo", children: logo }),
|
|
40
41
|
topbarLeft !== void 0 && /* @__PURE__ */ jsx("div", { className: "app-topbar-left", children: topbarLeft }),
|
|
@@ -42,7 +43,7 @@ function AppShell({
|
|
|
42
43
|
topbarRight !== void 0 && /* @__PURE__ */ jsx("div", { className: "app-topbar-right", children: topbarRight })
|
|
43
44
|
] });
|
|
44
45
|
const rail = /* @__PURE__ */ jsx("aside", { className: "app-sidebar", "aria-label": t("layout.appShell.sidebarLabel"), children: sidebar });
|
|
45
|
-
const bar = /* @__PURE__ */ jsxs("header", { className: "app-topbar ui-scale-fixed", "aria-label": t("layout.appShell.headerLabel"), children: [
|
|
46
|
+
const bar = !hasTopbarContent && !hasDrawer ? null : /* @__PURE__ */ jsxs("header", { className: "app-topbar ui-scale-fixed", "aria-label": t("layout.appShell.headerLabel"), children: [
|
|
46
47
|
hasDrawer && /* @__PURE__ */ jsxs(Sheet, { open: drawerOpen, onOpenChange: setDrawerOpen, children: [
|
|
47
48
|
/* @__PURE__ */ jsx(SheetTrigger, { asChild: true, children: /* @__PURE__ */ jsx(
|
|
48
49
|
Button,
|
|
@@ -53,7 +54,7 @@ function AppShell({
|
|
|
53
54
|
className: "app-mobile-nav-trigger hidden max-[900px]:inline-flex",
|
|
54
55
|
"aria-label": t("layout.appShell.openNav"),
|
|
55
56
|
"aria-haspopup": "dialog",
|
|
56
|
-
children: /* @__PURE__ */ jsx(Menu, { className: "size-
|
|
57
|
+
children: /* @__PURE__ */ jsx(Menu, { className: "size-[var(--app-shell-mobile-nav-icon-size)]", "aria-hidden": "true" })
|
|
57
58
|
}
|
|
58
59
|
) }),
|
|
59
60
|
/* @__PURE__ */ jsxs(
|
|
@@ -77,7 +78,7 @@ function AppShell({
|
|
|
77
78
|
}
|
|
78
79
|
)
|
|
79
80
|
] }),
|
|
80
|
-
resolvedTopbar
|
|
81
|
+
hasTopbarContent && resolvedTopbar
|
|
81
82
|
] });
|
|
82
83
|
return /* @__PURE__ */ jsxs(
|
|
83
84
|
"div",
|
|
@@ -85,6 +86,7 @@ function AppShell({
|
|
|
85
86
|
className: "app-root",
|
|
86
87
|
"data-collapsed": sidebarCollapsed ? "true" : void 0,
|
|
87
88
|
"data-responsive-navigation": responsiveNavigation,
|
|
89
|
+
"data-topbar": hasTopbarContent ? void 0 : "none",
|
|
88
90
|
"data-topbar-span": topbarSpan === "full" ? "full" : void 0,
|
|
89
91
|
children: [
|
|
90
92
|
topbarSpan === "full" ? bar : rail,
|
|
@@ -1,7 +1,14 @@
|
|
|
1
1
|
import type { AuthDividerProp } from "../../props/components/layout.prop.js";
|
|
2
2
|
export type { AuthDividerProp, AuthDividerProp as AuthDividerProps, } from "../../props/components/layout.prop.js";
|
|
3
3
|
/**
|
|
4
|
-
* AuthDivider — a centred, localized conjunction between two equal separator rules.
|
|
5
|
-
*
|
|
4
|
+
* AuthDivider — a centred, localized conjunction between two equal separator rules.
|
|
5
|
+
*
|
|
6
|
+
* Since gh#308 this is a thin PRESET over `Separator label`, not a parallel implementation: the
|
|
7
|
+
* grid, the accessible-name contract and the rule geometry all live on the primitive, and
|
|
8
|
+
* `.ui-auth-divider` only re-points Separator's `--separator-*` knobs at the `--auth-shell-divider-*`
|
|
9
|
+
* layer. That keeps #263's canonical login geometry byte-for-byte identical while breaking the
|
|
10
|
+
* coupling the issue reported — a service retuning its login divider no longer retunes every day
|
|
11
|
+
* divider in its message streams, and vice versa. New code that wants a labelled rule outside an
|
|
12
|
+
* auth form should use `<Separator label>` directly.
|
|
6
13
|
*/
|
|
7
14
|
export declare function AuthDivider({ label, className }: AuthDividerProp): import("react").JSX.Element;
|
|
@@ -1,18 +1,14 @@
|
|
|
1
|
-
|
|
1
|
+
"use client";
|
|
2
|
+
import { jsx } from "react/jsx-runtime";
|
|
2
3
|
import { cn } from "../../lib/utils.js";
|
|
4
|
+
import { Separator } from "../ui/separator.js";
|
|
3
5
|
function AuthDivider({ label, className }) {
|
|
4
|
-
return /* @__PURE__ */
|
|
5
|
-
|
|
6
|
+
return /* @__PURE__ */ jsx(
|
|
7
|
+
Separator,
|
|
6
8
|
{
|
|
7
9
|
"data-slot": "auth-divider",
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
"aria-label": label,
|
|
11
|
-
children: [
|
|
12
|
-
/* @__PURE__ */ jsx("span", { className: "ui-auth-divider-rule", "aria-hidden": "true" }),
|
|
13
|
-
/* @__PURE__ */ jsx("span", { className: "ui-auth-divider-label", "aria-hidden": "true", children: label }),
|
|
14
|
-
/* @__PURE__ */ jsx("span", { className: "ui-auth-divider-rule", "aria-hidden": "true" })
|
|
15
|
-
]
|
|
10
|
+
label,
|
|
11
|
+
className: cn("ui-auth-divider", className)
|
|
16
12
|
}
|
|
17
13
|
);
|
|
18
14
|
}
|
|
@@ -39,6 +39,7 @@ export type { MasterDetailProps } from "./master-detail.js";
|
|
|
39
39
|
export { SplitPane } from "./split-pane.js";
|
|
40
40
|
export type { SplitPaneProps } from "./split-pane.js";
|
|
41
41
|
export { Separator } from "./separator.js";
|
|
42
|
+
export type { SeparatorProp, SeparatorProps } from "./separator.js";
|
|
42
43
|
export { AspectRatio } from "./aspect-ratio.js";
|
|
43
44
|
export { LegalDocumentShell } from "./legal-document-shell.js";
|
|
44
45
|
export type { LegalDocumentSectionProp, LegalDocumentShellProp, LegalDocumentShellProps, } from "./legal-document-shell.js";
|
|
@@ -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.Element;
|
|
5
|
-
declare function PageContainerRoot({ title, subtitle, status, extra, footer, breadcrumb, breadcrumbLabel, breadcrumbAriaLabel, linkComponent: LinkComponent, headerLoading, density, variant, preset, headerLayout, measure, stickyFooter, footerReveal, fill, children, className, }: PageContainerProp): import("react").JSX.Element;
|
|
5
|
+
declare function PageContainerRoot({ title, subtitle, status, extra, toolbar, footer, breadcrumb, breadcrumbLabel, breadcrumbAriaLabel, linkComponent: LinkComponent, headerLoading, density, variant, preset, headerLayout, headerScale, measure, stickyFooter, footerReveal, fill, children, className, }: PageContainerProp): import("react").JSX.Element;
|
|
6
6
|
export declare const PageContainer: typeof PageContainerRoot & {
|
|
7
7
|
Inset: typeof PageContainerInset;
|
|
8
8
|
};
|
|
@@ -38,6 +38,7 @@ function PageContainerRoot({
|
|
|
38
38
|
subtitle,
|
|
39
39
|
status,
|
|
40
40
|
extra,
|
|
41
|
+
toolbar,
|
|
41
42
|
footer,
|
|
42
43
|
breadcrumb,
|
|
43
44
|
breadcrumbLabel,
|
|
@@ -48,6 +49,7 @@ function PageContainerRoot({
|
|
|
48
49
|
variant = "default",
|
|
49
50
|
preset = "default",
|
|
50
51
|
headerLayout = "stack",
|
|
52
|
+
headerScale = "document",
|
|
51
53
|
measure = "default",
|
|
52
54
|
stickyFooter = false,
|
|
53
55
|
footerReveal = "always",
|
|
@@ -63,6 +65,7 @@ function PageContainerRoot({
|
|
|
63
65
|
{
|
|
64
66
|
"data-preset": preset,
|
|
65
67
|
"data-measure": measure,
|
|
68
|
+
"data-header-scale": headerScale === "chrome" ? "chrome" : void 0,
|
|
66
69
|
"data-revealed": revealed ? "true" : void 0,
|
|
67
70
|
className: cn(
|
|
68
71
|
"ui-page-container",
|
|
@@ -91,30 +94,38 @@ function PageContainerRoot({
|
|
|
91
94
|
className: "ui-breadcrumb",
|
|
92
95
|
children: /* @__PURE__ */ jsx("ol", { className: "ui-breadcrumb-list", children: breadcrumb.map((item, i) => {
|
|
93
96
|
const isLast = i === breadcrumb.length - 1;
|
|
94
|
-
return
|
|
95
|
-
|
|
96
|
-
|
|
97
|
-
|
|
98
|
-
|
|
99
|
-
|
|
100
|
-
|
|
101
|
-
|
|
102
|
-
|
|
103
|
-
|
|
104
|
-
|
|
105
|
-
|
|
106
|
-
|
|
107
|
-
|
|
108
|
-
|
|
109
|
-
|
|
110
|
-
|
|
111
|
-
|
|
112
|
-
|
|
97
|
+
return (
|
|
98
|
+
// The package's own breadcrumb item hook (gh#319): same
|
|
99
|
+
// `--space-inline-xs` gap the previous `.ui-inline-xs` gave, and it brings
|
|
100
|
+
// `.ui-breadcrumb-item svg { 0.75rem }` with it, so the separator glyph no
|
|
101
|
+
// longer carries a `size-3` literal. It also drops `.ui-inline-xs`'s
|
|
102
|
+
// `flex-wrap: wrap` — a crumb must not break between its label and its
|
|
103
|
+
// chevron; the LIST wraps instead, exactly as <Breadcrumb> already behaves.
|
|
104
|
+
/* @__PURE__ */ jsxs("li", { className: "ui-breadcrumb-item", children: [
|
|
105
|
+
item.to && !isLast ? /* @__PURE__ */ jsx(
|
|
106
|
+
LinkComponent,
|
|
107
|
+
{
|
|
108
|
+
href: item.to,
|
|
109
|
+
to: item.to,
|
|
110
|
+
className: "hover:text-foreground hover:underline",
|
|
111
|
+
children: item.label
|
|
112
|
+
}
|
|
113
|
+
) : /* @__PURE__ */ jsx(
|
|
114
|
+
"span",
|
|
115
|
+
{
|
|
116
|
+
className: isLast ? "text-foreground" : "",
|
|
117
|
+
"aria-current": isLast ? "page" : void 0,
|
|
118
|
+
children: item.label
|
|
119
|
+
}
|
|
120
|
+
),
|
|
121
|
+
!isLast && /* @__PURE__ */ jsx(ChevronRight, { "aria-hidden": "true" })
|
|
122
|
+
] }, i)
|
|
123
|
+
);
|
|
113
124
|
}) })
|
|
114
125
|
}
|
|
115
126
|
),
|
|
116
127
|
/* @__PURE__ */ jsxs("div", { className: "ui-page-header-row", children: [
|
|
117
|
-
/* @__PURE__ */ jsxs("div", { className: "ui-page-header-heading
|
|
128
|
+
/* @__PURE__ */ jsxs("div", { className: "ui-page-header-heading", children: [
|
|
118
129
|
headerLoading ? /* @__PURE__ */ jsx("h1", { className: "ui-page-title ui-skeleton-block ui-page-title-placeholder", children: /* @__PURE__ */ jsx("span", { className: "sr-only", children: t("layout.pageHeader.loading") }) }) : status != null ? /* @__PURE__ */ jsxs("div", { className: "ui-page-header-title-row", children: [
|
|
119
130
|
/* @__PURE__ */ jsx("h1", { className: "ui-page-title", children: title }),
|
|
120
131
|
/* @__PURE__ */ jsx("div", { className: "ui-page-header-status", children: status })
|
|
@@ -136,6 +147,7 @@ function PageContainerRoot({
|
|
|
136
147
|
]
|
|
137
148
|
}
|
|
138
149
|
),
|
|
150
|
+
toolbar != null && /* @__PURE__ */ jsx("div", { className: "ui-page-toolbar", children: toolbar }),
|
|
139
151
|
children != null && /* @__PURE__ */ jsx("div", { className: "ui-page-body", children }),
|
|
140
152
|
footer && /* @__PURE__ */ jsx("footer", { className: "ui-page-footer", children: footer })
|
|
141
153
|
]
|
|
@@ -1,14 +1,14 @@
|
|
|
1
1
|
import * as React from "react";
|
|
2
2
|
import * as ResizablePrimitive from "react-resizable-panels";
|
|
3
|
-
export declare
|
|
4
|
-
|
|
5
|
-
displayName: string;
|
|
6
|
-
}
|
|
7
|
-
export declare
|
|
8
|
-
|
|
9
|
-
displayName: string;
|
|
10
|
-
}
|
|
11
|
-
export declare
|
|
12
|
-
|
|
13
|
-
displayName: string;
|
|
14
|
-
}
|
|
3
|
+
export declare function ResizablePanelGroup({ className, ...props }: React.ComponentPropsWithoutRef<typeof ResizablePrimitive.Group>): React.JSX.Element;
|
|
4
|
+
export declare namespace ResizablePanelGroup {
|
|
5
|
+
var displayName: string;
|
|
6
|
+
}
|
|
7
|
+
export declare function ResizablePanel({ className, elementRef, ...props }: React.ComponentPropsWithoutRef<typeof ResizablePrimitive.Panel>): React.JSX.Element;
|
|
8
|
+
export declare namespace ResizablePanel {
|
|
9
|
+
var displayName: string;
|
|
10
|
+
}
|
|
11
|
+
export declare function ResizableHandle({ className, ...props }: React.ComponentPropsWithoutRef<typeof ResizablePrimitive.Separator>): React.JSX.Element;
|
|
12
|
+
export declare namespace ResizableHandle {
|
|
13
|
+
var displayName: string;
|
|
14
|
+
}
|
|
@@ -132,49 +132,54 @@ const ServiceRolePanel = React.forwardRef(
|
|
|
132
132
|
masterLabel: masterLabel ?? t("layout.serviceRolePanel.rolesLabel"),
|
|
133
133
|
detailLabel: detailLabel ?? t("layout.serviceRolePanel.detailLabel"),
|
|
134
134
|
detailId,
|
|
135
|
-
master: /* @__PURE__ */ jsx("ul", { className: "
|
|
135
|
+
master: /* @__PURE__ */ jsx("ul", { className: "ui-service-role-panel-list", "data-slot": "service-role-panel-list", children: roles.map((role) => {
|
|
136
136
|
const selected = role.id === value;
|
|
137
|
-
return
|
|
138
|
-
|
|
139
|
-
|
|
140
|
-
|
|
141
|
-
|
|
142
|
-
|
|
143
|
-
|
|
144
|
-
|
|
145
|
-
|
|
146
|
-
|
|
147
|
-
|
|
148
|
-
|
|
149
|
-
|
|
150
|
-
|
|
151
|
-
|
|
152
|
-
|
|
153
|
-
|
|
154
|
-
|
|
155
|
-
|
|
156
|
-
|
|
157
|
-
|
|
158
|
-
|
|
159
|
-
|
|
160
|
-
|
|
161
|
-
|
|
162
|
-
|
|
163
|
-
|
|
164
|
-
|
|
165
|
-
|
|
166
|
-
|
|
167
|
-
|
|
168
|
-
|
|
169
|
-
|
|
170
|
-
|
|
171
|
-
|
|
172
|
-
|
|
173
|
-
|
|
174
|
-
|
|
175
|
-
|
|
176
|
-
|
|
177
|
-
|
|
137
|
+
return (
|
|
138
|
+
// NOT `.ui-inline-xs`: that helper adds `flex-wrap: wrap`, and this row holds a
|
|
139
|
+
// flex-1 select button next to an icon-only delete button that must never wrap
|
|
140
|
+
// onto its own line.
|
|
141
|
+
/* @__PURE__ */ jsxs("li", { className: "ui-service-role-panel-row", children: [
|
|
142
|
+
/* @__PURE__ */ jsx(
|
|
143
|
+
Button,
|
|
144
|
+
{
|
|
145
|
+
variant: selected ? "secondary" : "ghost",
|
|
146
|
+
className: "ui-service-role-panel-item h-auto flex-1 justify-start text-start",
|
|
147
|
+
"aria-current": selected ? "true" : void 0,
|
|
148
|
+
"aria-controls": detailId,
|
|
149
|
+
onClick: () => select(role.id),
|
|
150
|
+
children: /* @__PURE__ */ jsxs("span", { className: "ui-service-role-panel-item-body", children: [
|
|
151
|
+
/* @__PURE__ */ jsxs("span", { className: "ui-service-role-panel-item-title", children: [
|
|
152
|
+
/* @__PURE__ */ jsx(Text, { weight: "medium", className: "truncate", children: role.name }),
|
|
153
|
+
role.locked && /* @__PURE__ */ jsxs(Badge, { tone: "default", variant: "outline", children: [
|
|
154
|
+
/* @__PURE__ */ jsx(Lock, { "aria-hidden": "true" }),
|
|
155
|
+
t("layout.serviceRolePanel.locked")
|
|
156
|
+
] })
|
|
157
|
+
] }),
|
|
158
|
+
(role.description !== void 0 || role.memberCount !== void 0) && /* @__PURE__ */ jsx(Text, { size: "2xs", tone: "muted", className: "max-w-full truncate", children: [
|
|
159
|
+
role.description,
|
|
160
|
+
role.memberCount !== void 0 ? (
|
|
161
|
+
// `{count}` is Intl.NumberFormat-grouped by `interpolate`,
|
|
162
|
+
// pluralized by CLDR category — no hand-built formatting.
|
|
163
|
+
t("layout.serviceRolePanel.memberCount", {
|
|
164
|
+
count: role.memberCount
|
|
165
|
+
})
|
|
166
|
+
) : void 0
|
|
167
|
+
].filter((part) => part !== void 0).join(" \xB7 ") })
|
|
168
|
+
] })
|
|
169
|
+
}
|
|
170
|
+
),
|
|
171
|
+
deletable && !role.locked && /* @__PURE__ */ jsx(
|
|
172
|
+
Button,
|
|
173
|
+
{
|
|
174
|
+
variant: "ghost",
|
|
175
|
+
size: "icon-sm",
|
|
176
|
+
"aria-label": t("layout.serviceRolePanel.deleteRole", { role: role.name }),
|
|
177
|
+
onClick: () => setPendingDelete(role),
|
|
178
|
+
children: /* @__PURE__ */ jsx(Trash2, { "aria-hidden": "true" })
|
|
179
|
+
}
|
|
180
|
+
)
|
|
181
|
+
] }, role.id)
|
|
182
|
+
);
|
|
178
183
|
}) }),
|
|
179
184
|
children: detail
|
|
180
185
|
}
|
|
@@ -36,7 +36,19 @@ function SidebarRowContent({
|
|
|
36
36
|
return /* @__PURE__ */ jsxs(Fragment, { children: [
|
|
37
37
|
!sub ? /* @__PURE__ */ jsx(SidebarIcon, { icon: item.icon }) : null,
|
|
38
38
|
/* @__PURE__ */ jsx("span", { className: "sb-label", children: item.label }),
|
|
39
|
-
showBadge ?
|
|
39
|
+
showBadge ? (
|
|
40
|
+
// `data-tone` is emitted ONLY for the emphasis tone (rule #44: present-when-on,
|
|
41
|
+
// absent-when-off), so a rail that never sets `badgeTone` renders the exact same node it
|
|
42
|
+
// always did and no consumer selector has to out-specify a marker meaning "unchanged".
|
|
43
|
+
/* @__PURE__ */ jsx(
|
|
44
|
+
"span",
|
|
45
|
+
{
|
|
46
|
+
className: "sb-badge",
|
|
47
|
+
"data-tone": item.badgeTone === "destructive" ? "destructive" : void 0,
|
|
48
|
+
children: item.badge
|
|
49
|
+
}
|
|
50
|
+
)
|
|
51
|
+
) : null
|
|
40
52
|
] });
|
|
41
53
|
}
|
|
42
54
|
function SidebarItem({
|
|
@@ -1,7 +1,18 @@
|
|
|
1
1
|
import type { ReactNode } from "react";
|
|
2
2
|
export type SplitPaneProps = {
|
|
3
3
|
children: ReactNode;
|
|
4
|
-
|
|
4
|
+
/**
|
|
5
|
+
* Aside (trailing) panel content. Pass `null` to CLOSE the rail: no `<aside>` element is
|
|
6
|
+
* rendered, the grid drops to one full-width column and the gap goes with it.
|
|
7
|
+
*
|
|
8
|
+
* Closing this way — rather than dropping the whole `SplitPane` at the call site — is what
|
|
9
|
+
* keeps `children` MOUNTED. The three wrappers below are rendered unconditionally, so the
|
|
10
|
+
* main column sits at the same depth and the same slot in the React tree in both states and
|
|
11
|
+
* React reuses its DOM node instead of remounting it. A collapsible thread/detail panel that
|
|
12
|
+
* swapped `<SplitPane>{page}</SplitPane>` for a bare `{page}` changed the tree depth, which
|
|
13
|
+
* remounted the page and threw the reader to the bottom of a scrolled list.
|
|
14
|
+
*/
|
|
15
|
+
aside: ReactNode | null;
|
|
5
16
|
/**
|
|
6
17
|
* How wide the rail is once the pane is wide enough to split: `sm` 20rem,
|
|
7
18
|
* `md` 22rem, `lg` 30rem. `lg` is for rails that carry a panel rather than a
|
|
@@ -1,9 +1,18 @@
|
|
|
1
1
|
import { jsx, jsxs } from "react/jsx-runtime";
|
|
2
2
|
function SplitPane({ children, aside, asideWidth = "md", asideLabel }) {
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
|
|
3
|
+
const closed = aside === null || aside === void 0;
|
|
4
|
+
return /* @__PURE__ */ jsx("div", { className: "ui-split-pane-scope", children: /* @__PURE__ */ jsxs(
|
|
5
|
+
"div",
|
|
6
|
+
{
|
|
7
|
+
className: "ui-split-pane",
|
|
8
|
+
"data-aside-width": asideWidth,
|
|
9
|
+
"data-aside": closed ? "closed" : void 0,
|
|
10
|
+
children: [
|
|
11
|
+
/* @__PURE__ */ jsx("div", { className: "ui-split-pane-main", children }),
|
|
12
|
+
closed ? null : /* @__PURE__ */ jsx("aside", { className: "ui-split-pane-aside", "aria-label": asideLabel, children: aside })
|
|
13
|
+
]
|
|
14
|
+
}
|
|
15
|
+
) });
|
|
7
16
|
}
|
|
8
17
|
export {
|
|
9
18
|
SplitPane
|
|
@@ -41,16 +41,6 @@ const ICON = {
|
|
|
41
41
|
density: Rows3,
|
|
42
42
|
fontSize: Type
|
|
43
43
|
};
|
|
44
|
-
const TRIGGER_WIDTH = {
|
|
45
|
-
locale: "sm:w-40",
|
|
46
|
-
timezone: "sm:w-56",
|
|
47
|
-
dateFormat: "sm:w-44",
|
|
48
|
-
timeFormat: "sm:w-44",
|
|
49
|
-
theme: "sm:w-36",
|
|
50
|
-
brand: "sm:w-44",
|
|
51
|
-
density: "sm:w-40",
|
|
52
|
-
fontSize: "sm:w-36"
|
|
53
|
-
};
|
|
54
44
|
const ARIA_KEY = {
|
|
55
45
|
locale: "navigation.localePicker.ariaLabel",
|
|
56
46
|
timezone: "navigation.timezonePicker.ariaLabel",
|
|
@@ -139,7 +129,7 @@ const AppSettingPicker = React.forwardRef(
|
|
|
139
129
|
id,
|
|
140
130
|
showIndicator: !iconOnly && !inline,
|
|
141
131
|
className: cn(
|
|
142
|
-
inline ? "ui-app-setting-picker-inline
|
|
132
|
+
inline ? "ui-app-setting-picker-inline" : iconOnly ? (
|
|
143
133
|
// Structurally icon-only: drop the owned width + value spacing and square the box to
|
|
144
134
|
// the density-aware --control-height tap target, centring the icon. Visually it
|
|
145
135
|
// sits among ghost icon buttons (the topbar's sidebar-toggle/notifications/account
|
|
@@ -149,7 +139,7 @@ const AppSettingPicker = React.forwardRef(
|
|
|
149
139
|
// (`data-[state=open]:border-ring`, from controlTriggerClass) and the
|
|
150
140
|
// focus-visible ring are untouched, so keyboard and "is this open" affordance
|
|
151
141
|
// still hold.
|
|
152
|
-
"ui-app-setting-picker-icon hover:bg-accent hover:text-accent-foreground
|
|
142
|
+
"ui-app-setting-picker-icon hover:bg-accent hover:text-accent-foreground"
|
|
153
143
|
) : (
|
|
154
144
|
// Labeled: sized to a per-kind width from `sm` up; below `sm` it hugs its content and
|
|
155
145
|
// caps at the container (`w-auto max-w-full`) instead of the old UNCONDITIONAL
|
|
@@ -157,7 +147,7 @@ const AppSettingPicker = React.forwardRef(
|
|
|
157
147
|
// fill the bar (gh#165). A form field that wants a full-width control passes
|
|
158
148
|
// `className="w-full"`, which wins over `w-auto`.
|
|
159
149
|
// `compact` drops the per-kind width entirely so the trigger hugs its value.
|
|
160
|
-
cn("w-auto max-w-full", !isCompact &&
|
|
150
|
+
cn("w-auto max-w-full", !isCompact && "ui-app-setting-picker-trigger")
|
|
161
151
|
),
|
|
162
152
|
// Compact re-tiers the box through tokens (--app-setting-picker-compact-*); the height
|
|
163
153
|
// still comes from the official --control-height-sm tier, never a literal. The gap is a
|
|
@@ -165,13 +155,14 @@ const AppSettingPicker = React.forwardRef(
|
|
|
165
155
|
isCompact && "ui-app-setting-picker-compact gap-[length:var(--app-setting-picker-compact-gap)]",
|
|
166
156
|
className
|
|
167
157
|
),
|
|
158
|
+
"data-kind": kind,
|
|
168
159
|
"aria-label": t(ARIA_KEY[kind]),
|
|
169
160
|
children: [
|
|
170
161
|
inline ? null : /* @__PURE__ */ jsx(
|
|
171
162
|
Icon,
|
|
172
163
|
{
|
|
173
164
|
className: cn(
|
|
174
|
-
"
|
|
165
|
+
"ui-app-setting-picker-glyph",
|
|
175
166
|
// Compact relies on the trigger's tokenized flex gap instead of an icon margin.
|
|
176
167
|
!iconOnly && !isCompact && "me-2"
|
|
177
168
|
),
|