@ug666/ui-react 0.1.0 → 0.2.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/blocks/index.cjs +238 -0
- package/dist/blocks/index.cjs.map +1 -0
- package/dist/blocks/index.d.cts +86 -0
- package/dist/blocks/index.d.ts +86 -0
- package/dist/blocks/index.js +153 -0
- package/dist/blocks/index.js.map +1 -0
- package/dist/button-CaLZig8j.d.cts +22 -0
- package/dist/button-CaLZig8j.d.ts +22 -0
- package/dist/chunk-2IVRUJKO.js +377 -0
- package/dist/chunk-2IVRUJKO.js.map +1 -0
- package/dist/chunk-73WQAE3E.js +3003 -0
- package/dist/chunk-73WQAE3E.js.map +1 -0
- package/dist/chunk-RUDEZA5Q.js +62 -0
- package/dist/chunk-RUDEZA5Q.js.map +1 -0
- package/dist/chunk-S45GP6IB.js +254 -0
- package/dist/chunk-S45GP6IB.js.map +1 -0
- package/dist/components/index.cjs +3993 -0
- package/dist/components/index.cjs.map +1 -0
- package/dist/components/index.d.cts +1097 -0
- package/dist/components/index.d.ts +1097 -0
- package/dist/components/index.js +330 -0
- package/dist/components/index.js.map +1 -0
- package/dist/hooks/index.cjs +1 -0
- package/dist/hooks/index.cjs.map +1 -1
- package/dist/hooks/index.js +1 -0
- package/dist/index.cjs +1410 -710
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.cts +274 -1340
- package/dist/index.d.ts +274 -1340
- package/dist/index.js +385 -3229
- package/dist/index.js.map +1 -1
- package/dist/labs/index.cjs +34 -0
- package/dist/labs/index.cjs.map +1 -0
- package/dist/labs/index.d.cts +12 -0
- package/dist/labs/index.d.ts +12 -0
- package/dist/labs/index.js +9 -0
- package/dist/labs/index.js.map +1 -0
- package/dist/patterns/index.cjs +758 -0
- package/dist/patterns/index.cjs.map +1 -0
- package/dist/patterns/index.d.cts +158 -0
- package/dist/patterns/index.d.ts +158 -0
- package/dist/patterns/index.js +320 -0
- package/dist/patterns/index.js.map +1 -0
- package/dist/primitives/index.cjs +384 -0
- package/dist/primitives/index.cjs.map +1 -0
- package/dist/primitives/index.d.cts +137 -0
- package/dist/primitives/index.d.ts +137 -0
- package/dist/primitives/index.js +56 -0
- package/dist/primitives/index.js.map +1 -0
- package/dist/sidebar-vl00Z2o-.d.cts +93 -0
- package/dist/sidebar-vl00Z2o-.d.ts +93 -0
- package/dist/styles.css +2499 -0
- package/dist/tokens.css +86 -9
- package/package.json +36 -6
|
@@ -0,0 +1,758 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
"use client";
|
|
3
|
+
var __defProp = Object.defineProperty;
|
|
4
|
+
var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
|
|
5
|
+
var __getOwnPropNames = Object.getOwnPropertyNames;
|
|
6
|
+
var __hasOwnProp = Object.prototype.hasOwnProperty;
|
|
7
|
+
var __export = (target, all) => {
|
|
8
|
+
for (var name in all)
|
|
9
|
+
__defProp(target, name, { get: all[name], enumerable: true });
|
|
10
|
+
};
|
|
11
|
+
var __copyProps = (to, from, except, desc) => {
|
|
12
|
+
if (from && typeof from === "object" || typeof from === "function") {
|
|
13
|
+
for (let key of __getOwnPropNames(from))
|
|
14
|
+
if (!__hasOwnProp.call(to, key) && key !== except)
|
|
15
|
+
__defProp(to, key, { get: () => from[key], enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable });
|
|
16
|
+
}
|
|
17
|
+
return to;
|
|
18
|
+
};
|
|
19
|
+
var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod);
|
|
20
|
+
|
|
21
|
+
// src/patterns/index.ts
|
|
22
|
+
var patterns_exports = {};
|
|
23
|
+
__export(patterns_exports, {
|
|
24
|
+
AdminShell: () => AdminShell,
|
|
25
|
+
ConfirmDialog: () => ConfirmDialog,
|
|
26
|
+
CopyField: () => CopyField,
|
|
27
|
+
PageHeader: () => PageHeader,
|
|
28
|
+
UGAdminShell: () => AdminShell,
|
|
29
|
+
UGConfirmDialog: () => ConfirmDialog,
|
|
30
|
+
UGCopyField: () => CopyField,
|
|
31
|
+
UGPageHeader: () => PageHeader
|
|
32
|
+
});
|
|
33
|
+
module.exports = __toCommonJS(patterns_exports);
|
|
34
|
+
|
|
35
|
+
// src/patterns/admin-shell.tsx
|
|
36
|
+
var import_react3 = require("react");
|
|
37
|
+
var import_lucide_react3 = require("lucide-react");
|
|
38
|
+
|
|
39
|
+
// src/components/button.tsx
|
|
40
|
+
var import_react = require("react");
|
|
41
|
+
var import_lucide_react = require("lucide-react");
|
|
42
|
+
var import_class_variance_authority = require("class-variance-authority");
|
|
43
|
+
|
|
44
|
+
// src/internal/cn.ts
|
|
45
|
+
var import_clsx = require("clsx");
|
|
46
|
+
var import_tailwind_merge = require("tailwind-merge");
|
|
47
|
+
function cn(...inputs) {
|
|
48
|
+
return (0, import_tailwind_merge.twMerge)((0, import_clsx.clsx)(inputs));
|
|
49
|
+
}
|
|
50
|
+
|
|
51
|
+
// src/components/button.tsx
|
|
52
|
+
var import_jsx_runtime = require("react/jsx-runtime");
|
|
53
|
+
var buttonVariants = (0, import_class_variance_authority.cva)(
|
|
54
|
+
"inline-flex items-center justify-center gap-2 whitespace-nowrap rounded-lg text-sm font-medium transition-[background,border-color,color,box-shadow,transform] duration-150 focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-offset-2 disabled:pointer-events-none disabled:opacity-50",
|
|
55
|
+
{
|
|
56
|
+
variants: {
|
|
57
|
+
variant: {
|
|
58
|
+
default: "bg-primary text-primary-fg shadow-sm hover:bg-primary-hover hover:shadow-md focus-visible:ring-ring",
|
|
59
|
+
destructive: "bg-danger text-danger-fg shadow-sm hover:bg-danger-hover hover:shadow-md focus-visible:ring-danger",
|
|
60
|
+
outline: "border border-border-strong bg-surface-1 text-text-primary shadow-sm hover:border-primary/55 hover:bg-surface-2 focus-visible:ring-ring/30",
|
|
61
|
+
secondary: "border border-border-base bg-surface-2 text-text-primary shadow-sm hover:bg-surface-3 focus-visible:ring-ring/30",
|
|
62
|
+
ghost: "text-text-primary hover:bg-surface-2 focus-visible:ring-ring/30",
|
|
63
|
+
link: "text-text-primary underline-offset-4 hover:underline focus-visible:ring-ring/30"
|
|
64
|
+
},
|
|
65
|
+
size: {
|
|
66
|
+
default: "h-9 px-4 py-2",
|
|
67
|
+
sm: "h-8 px-3 text-xs",
|
|
68
|
+
lg: "h-11 px-5 text-base",
|
|
69
|
+
icon: "h-9 w-9"
|
|
70
|
+
}
|
|
71
|
+
},
|
|
72
|
+
defaultVariants: {
|
|
73
|
+
variant: "default",
|
|
74
|
+
size: "default"
|
|
75
|
+
}
|
|
76
|
+
}
|
|
77
|
+
);
|
|
78
|
+
var Button = (0, import_react.forwardRef)(
|
|
79
|
+
({ className, variant, size, loading = false, disabled, children, ...props }, ref) => {
|
|
80
|
+
return /* @__PURE__ */ (0, import_jsx_runtime.jsxs)(
|
|
81
|
+
"button",
|
|
82
|
+
{
|
|
83
|
+
ref,
|
|
84
|
+
className: cn(buttonVariants({ variant, size }), className),
|
|
85
|
+
disabled: disabled || loading,
|
|
86
|
+
...props,
|
|
87
|
+
children: [
|
|
88
|
+
loading && /* @__PURE__ */ (0, import_jsx_runtime.jsx)(import_lucide_react.Loader2, { className: "animate-spin", size: 16 }),
|
|
89
|
+
children
|
|
90
|
+
]
|
|
91
|
+
}
|
|
92
|
+
);
|
|
93
|
+
}
|
|
94
|
+
);
|
|
95
|
+
Button.displayName = "Button";
|
|
96
|
+
|
|
97
|
+
// src/components/sidebar.tsx
|
|
98
|
+
var import_react2 = require("react");
|
|
99
|
+
var import_lucide_react2 = require("lucide-react");
|
|
100
|
+
var import_jsx_runtime2 = require("react/jsx-runtime");
|
|
101
|
+
var variantStyles = {
|
|
102
|
+
primary: {
|
|
103
|
+
container: "border-r border-border-base bg-surface-1 text-text-primary shadow-sm",
|
|
104
|
+
active: "bg-primary/10 text-primary shadow-sm ring-1 ring-primary/20 before:absolute before:left-0 before:top-1/2 before:h-6 before:w-[3px] before:-translate-y-1/2 before:rounded-r-full before:bg-primary",
|
|
105
|
+
inactive: "text-text-secondary hover:bg-surface-2 hover:text-text-primary",
|
|
106
|
+
divider: "border-border-base",
|
|
107
|
+
icon: "bg-transparent text-text-tertiary group-hover:bg-surface-3 group-hover:text-primary",
|
|
108
|
+
activeIcon: "bg-primary/15 text-primary"
|
|
109
|
+
},
|
|
110
|
+
dark: {
|
|
111
|
+
container: "border-r border-border-base bg-surface-1 text-text-primary shadow-sm",
|
|
112
|
+
active: "bg-primary/10 text-primary shadow-sm ring-1 ring-primary/20 before:absolute before:left-0 before:top-1/2 before:h-6 before:w-[3px] before:-translate-y-1/2 before:rounded-r-full before:bg-primary",
|
|
113
|
+
inactive: "text-text-secondary hover:bg-surface-2 hover:text-text-primary",
|
|
114
|
+
divider: "border-border-base",
|
|
115
|
+
icon: "bg-transparent text-text-tertiary group-hover:bg-surface-3 group-hover:text-primary",
|
|
116
|
+
activeIcon: "bg-primary/15 text-primary"
|
|
117
|
+
}
|
|
118
|
+
};
|
|
119
|
+
function getItemKey(item, index, parentKey) {
|
|
120
|
+
return item.id ?? item.href ?? `${parentKey}-${index}-${item.label}`;
|
|
121
|
+
}
|
|
122
|
+
function itemHasActiveChild(item) {
|
|
123
|
+
return Boolean(item.children?.some((child) => child.active || itemHasActiveChild(child)));
|
|
124
|
+
}
|
|
125
|
+
function normalizeSearch(value) {
|
|
126
|
+
return value.toLowerCase().replace(/\s+/g, "");
|
|
127
|
+
}
|
|
128
|
+
function filterSidebarItems(items, query) {
|
|
129
|
+
if (!query) return items;
|
|
130
|
+
return items.reduce((result, item) => {
|
|
131
|
+
const children = item.children ? filterSidebarItems(item.children, query) : [];
|
|
132
|
+
const matched = normalizeSearch(item.label).includes(query);
|
|
133
|
+
if (matched || children.length > 0) {
|
|
134
|
+
result.push({ ...item, children });
|
|
135
|
+
}
|
|
136
|
+
return result;
|
|
137
|
+
}, []);
|
|
138
|
+
}
|
|
139
|
+
var Sidebar = (0, import_react2.forwardRef)(
|
|
140
|
+
({
|
|
141
|
+
items,
|
|
142
|
+
variant = "primary",
|
|
143
|
+
collapsed,
|
|
144
|
+
defaultCollapsed = false,
|
|
145
|
+
onCollapsedChange,
|
|
146
|
+
collapsible = false,
|
|
147
|
+
searchable = false,
|
|
148
|
+
searchPlaceholder = "\u641C\u7D22\u83DC\u5355...",
|
|
149
|
+
responsive = false,
|
|
150
|
+
mobileOpen = false,
|
|
151
|
+
onMobileOpenChange,
|
|
152
|
+
header,
|
|
153
|
+
footer,
|
|
154
|
+
className
|
|
155
|
+
}, ref) => {
|
|
156
|
+
const styles = variantStyles[variant];
|
|
157
|
+
const [internalCollapsed, setInternalCollapsed] = (0, import_react2.useState)(defaultCollapsed);
|
|
158
|
+
const [expandedKeys, setExpandedKeys] = (0, import_react2.useState)(() => /* @__PURE__ */ new Set());
|
|
159
|
+
const [query, setQuery] = (0, import_react2.useState)("");
|
|
160
|
+
const effectiveCollapsed = collapsed ?? internalCollapsed;
|
|
161
|
+
const normalizedQuery = normalizeSearch(query);
|
|
162
|
+
const visibleItems = (0, import_react2.useMemo)(() => filterSidebarItems(items, normalizedQuery), [items, normalizedQuery]);
|
|
163
|
+
function setCollapsedState(nextCollapsed) {
|
|
164
|
+
setInternalCollapsed(nextCollapsed);
|
|
165
|
+
onCollapsedChange?.(nextCollapsed);
|
|
166
|
+
}
|
|
167
|
+
function toggleExpanded(key) {
|
|
168
|
+
setExpandedKeys((current) => {
|
|
169
|
+
const next = new Set(current);
|
|
170
|
+
if (next.has(key)) {
|
|
171
|
+
next.delete(key);
|
|
172
|
+
} else {
|
|
173
|
+
next.add(key);
|
|
174
|
+
}
|
|
175
|
+
return next;
|
|
176
|
+
});
|
|
177
|
+
}
|
|
178
|
+
function closeMobile() {
|
|
179
|
+
onMobileOpenChange?.(false);
|
|
180
|
+
}
|
|
181
|
+
function renderItems(list, depth = 0, parentKey = "root") {
|
|
182
|
+
return /* @__PURE__ */ (0, import_jsx_runtime2.jsx)("ul", { className: cn("flex flex-col gap-1", depth === 0 ? "px-2.5" : "ml-6 mt-1 border-l border-border-base pl-2"), children: list.map((item, index) => {
|
|
183
|
+
const key = getItemKey(item, index, parentKey);
|
|
184
|
+
const hasChildren = Boolean(item.children?.length);
|
|
185
|
+
const active = Boolean(item.active || itemHasActiveChild(item));
|
|
186
|
+
const expanded = !effectiveCollapsed && hasChildren && (normalizedQuery.length > 0 || active || expandedKeys.has(key));
|
|
187
|
+
const itemContent = /* @__PURE__ */ (0, import_jsx_runtime2.jsxs)(import_jsx_runtime2.Fragment, { children: [
|
|
188
|
+
/* @__PURE__ */ (0, import_jsx_runtime2.jsx)(
|
|
189
|
+
"span",
|
|
190
|
+
{
|
|
191
|
+
className: cn(
|
|
192
|
+
"flex h-8 w-8 shrink-0 items-center justify-center rounded-lg transition-colors",
|
|
193
|
+
active ? styles.activeIcon : styles.icon
|
|
194
|
+
),
|
|
195
|
+
children: /* @__PURE__ */ (0, import_jsx_runtime2.jsx)(item.icon, { size: 16 })
|
|
196
|
+
}
|
|
197
|
+
),
|
|
198
|
+
!effectiveCollapsed && /* @__PURE__ */ (0, import_jsx_runtime2.jsx)("span", { className: "min-w-0 flex-1 truncate text-left", children: item.label }),
|
|
199
|
+
!effectiveCollapsed && hasChildren && /* @__PURE__ */ (0, import_jsx_runtime2.jsx)(
|
|
200
|
+
import_lucide_react2.ChevronDown,
|
|
201
|
+
{
|
|
202
|
+
size: 15,
|
|
203
|
+
className: cn("shrink-0 text-text-tertiary transition-transform", expanded && "rotate-180"),
|
|
204
|
+
"aria-hidden": "true"
|
|
205
|
+
}
|
|
206
|
+
)
|
|
207
|
+
] });
|
|
208
|
+
const itemClassName = cn(
|
|
209
|
+
"group relative flex min-w-0 items-center gap-2.5 rounded-lg px-2.5 py-2 text-sm font-medium outline-none transition-all duration-150 focus-visible:ring-2 focus-visible:ring-primary/35",
|
|
210
|
+
effectiveCollapsed && "justify-center px-2",
|
|
211
|
+
active ? styles.active : styles.inactive
|
|
212
|
+
);
|
|
213
|
+
return /* @__PURE__ */ (0, import_jsx_runtime2.jsxs)("li", { children: [
|
|
214
|
+
hasChildren ? /* @__PURE__ */ (0, import_jsx_runtime2.jsx)(
|
|
215
|
+
"button",
|
|
216
|
+
{
|
|
217
|
+
type: "button",
|
|
218
|
+
className: cn("w-full", itemClassName),
|
|
219
|
+
"aria-expanded": expanded,
|
|
220
|
+
title: effectiveCollapsed ? item.label : void 0,
|
|
221
|
+
onClick: () => toggleExpanded(key),
|
|
222
|
+
children: itemContent
|
|
223
|
+
}
|
|
224
|
+
) : /* @__PURE__ */ (0, import_jsx_runtime2.jsx)(
|
|
225
|
+
"a",
|
|
226
|
+
{
|
|
227
|
+
href: item.href ?? "#",
|
|
228
|
+
"aria-current": item.active ? "page" : void 0,
|
|
229
|
+
className: itemClassName,
|
|
230
|
+
title: effectiveCollapsed ? item.label : void 0,
|
|
231
|
+
onClick: closeMobile,
|
|
232
|
+
children: itemContent
|
|
233
|
+
}
|
|
234
|
+
),
|
|
235
|
+
expanded && item.children ? renderItems(item.children, depth + 1, key) : null
|
|
236
|
+
] }, key);
|
|
237
|
+
}) });
|
|
238
|
+
}
|
|
239
|
+
const sidebar = /* @__PURE__ */ (0, import_jsx_runtime2.jsxs)(
|
|
240
|
+
"aside",
|
|
241
|
+
{
|
|
242
|
+
ref,
|
|
243
|
+
className: cn(
|
|
244
|
+
"flex flex-col overflow-hidden transition-all duration-300",
|
|
245
|
+
styles.container,
|
|
246
|
+
effectiveCollapsed ? "w-[72px]" : "w-64",
|
|
247
|
+
responsive && [
|
|
248
|
+
"fixed inset-y-0 left-0 z-50 md:relative md:inset-auto md:z-auto",
|
|
249
|
+
mobileOpen ? "translate-x-0" : "-translate-x-full md:translate-x-0"
|
|
250
|
+
],
|
|
251
|
+
className
|
|
252
|
+
),
|
|
253
|
+
children: [
|
|
254
|
+
(header || collapsible || responsive && mobileOpen) && /* @__PURE__ */ (0, import_jsx_runtime2.jsxs)(
|
|
255
|
+
"div",
|
|
256
|
+
{
|
|
257
|
+
className: cn(
|
|
258
|
+
"flex border-b px-3 py-3",
|
|
259
|
+
styles.divider,
|
|
260
|
+
effectiveCollapsed ? "justify-center" : "items-center gap-2"
|
|
261
|
+
),
|
|
262
|
+
children: [
|
|
263
|
+
!effectiveCollapsed && header ? /* @__PURE__ */ (0, import_jsx_runtime2.jsx)("div", { className: "min-w-0 flex-1", children: header }) : null,
|
|
264
|
+
collapsible && /* @__PURE__ */ (0, import_jsx_runtime2.jsx)(
|
|
265
|
+
"button",
|
|
266
|
+
{
|
|
267
|
+
type: "button",
|
|
268
|
+
className: "flex h-9 w-9 shrink-0 items-center justify-center rounded-lg border border-border-base bg-surface-2 text-text-secondary transition-colors hover:border-primary/40 hover:text-text-primary",
|
|
269
|
+
"aria-label": effectiveCollapsed ? "\u5C55\u5F00\u4FA7\u8FB9\u680F" : "\u6298\u53E0\u4FA7\u8FB9\u680F",
|
|
270
|
+
onClick: () => setCollapsedState(!effectiveCollapsed),
|
|
271
|
+
children: effectiveCollapsed ? /* @__PURE__ */ (0, import_jsx_runtime2.jsx)(import_lucide_react2.PanelLeftOpen, { size: 17 }) : /* @__PURE__ */ (0, import_jsx_runtime2.jsx)(import_lucide_react2.PanelLeftClose, { size: 17 })
|
|
272
|
+
}
|
|
273
|
+
),
|
|
274
|
+
responsive && /* @__PURE__ */ (0, import_jsx_runtime2.jsx)(
|
|
275
|
+
"button",
|
|
276
|
+
{
|
|
277
|
+
type: "button",
|
|
278
|
+
className: "flex h-9 w-9 shrink-0 items-center justify-center rounded-lg border border-border-base bg-surface-2 text-text-secondary transition-colors hover:border-primary/40 hover:text-text-primary md:hidden",
|
|
279
|
+
"aria-label": "\u5173\u95ED\u4FA7\u8FB9\u680F",
|
|
280
|
+
onClick: closeMobile,
|
|
281
|
+
children: /* @__PURE__ */ (0, import_jsx_runtime2.jsx)(import_lucide_react2.X, { size: 17 })
|
|
282
|
+
}
|
|
283
|
+
)
|
|
284
|
+
]
|
|
285
|
+
}
|
|
286
|
+
),
|
|
287
|
+
searchable && !effectiveCollapsed && /* @__PURE__ */ (0, import_jsx_runtime2.jsxs)("div", { className: cn("border-b px-3 py-3", styles.divider), children: [
|
|
288
|
+
/* @__PURE__ */ (0, import_jsx_runtime2.jsx)("label", { className: "sr-only", htmlFor: "ug-sidebar-search", children: "\u641C\u7D22\u83DC\u5355" }),
|
|
289
|
+
/* @__PURE__ */ (0, import_jsx_runtime2.jsxs)("div", { className: "relative", children: [
|
|
290
|
+
/* @__PURE__ */ (0, import_jsx_runtime2.jsx)(import_lucide_react2.Search, { className: "pointer-events-none absolute left-3 top-1/2 h-4 w-4 -translate-y-1/2 text-text-tertiary", "aria-hidden": "true" }),
|
|
291
|
+
/* @__PURE__ */ (0, import_jsx_runtime2.jsx)(
|
|
292
|
+
"input",
|
|
293
|
+
{
|
|
294
|
+
id: "ug-sidebar-search",
|
|
295
|
+
value: query,
|
|
296
|
+
onChange: (event) => setQuery(event.target.value),
|
|
297
|
+
placeholder: searchPlaceholder,
|
|
298
|
+
autoComplete: "off",
|
|
299
|
+
className: "h-10 w-full rounded-lg border border-border-base bg-surface-0 px-3 pl-9 pr-9 text-sm text-text-primary outline-none transition-colors placeholder:text-text-tertiary focus:border-primary focus:ring-2 focus:ring-primary/20",
|
|
300
|
+
type: "text",
|
|
301
|
+
role: "searchbox"
|
|
302
|
+
}
|
|
303
|
+
),
|
|
304
|
+
query ? /* @__PURE__ */ (0, import_jsx_runtime2.jsx)(
|
|
305
|
+
"button",
|
|
306
|
+
{
|
|
307
|
+
type: "button",
|
|
308
|
+
className: "absolute right-1 top-1/2 flex h-8 w-8 -translate-y-1/2 items-center justify-center rounded-md text-text-tertiary transition-colors hover:bg-surface-2 hover:text-text-primary",
|
|
309
|
+
"aria-label": "\u6E05\u7A7A\u641C\u7D22",
|
|
310
|
+
onClick: () => setQuery(""),
|
|
311
|
+
children: /* @__PURE__ */ (0, import_jsx_runtime2.jsx)(import_lucide_react2.X, { size: 14 })
|
|
312
|
+
}
|
|
313
|
+
) : null
|
|
314
|
+
] })
|
|
315
|
+
] }),
|
|
316
|
+
/* @__PURE__ */ (0, import_jsx_runtime2.jsx)("nav", { className: "flex-1 overflow-y-auto py-3.5", children: visibleItems.length > 0 ? renderItems(visibleItems) : /* @__PURE__ */ (0, import_jsx_runtime2.jsx)("p", { className: "mx-3 rounded-lg border border-dashed border-border-base bg-surface-0 px-3 py-3 text-sm text-text-tertiary", children: "\u6CA1\u6709\u5339\u914D\u7684\u83DC\u5355" }) }),
|
|
317
|
+
footer && /* @__PURE__ */ (0, import_jsx_runtime2.jsx)(
|
|
318
|
+
"div",
|
|
319
|
+
{
|
|
320
|
+
className: cn(
|
|
321
|
+
"border-t px-2.5 py-3",
|
|
322
|
+
styles.divider,
|
|
323
|
+
effectiveCollapsed && "flex justify-center"
|
|
324
|
+
),
|
|
325
|
+
children: footer
|
|
326
|
+
}
|
|
327
|
+
)
|
|
328
|
+
]
|
|
329
|
+
}
|
|
330
|
+
);
|
|
331
|
+
return /* @__PURE__ */ (0, import_jsx_runtime2.jsxs)(import_jsx_runtime2.Fragment, { children: [
|
|
332
|
+
responsive && mobileOpen ? /* @__PURE__ */ (0, import_jsx_runtime2.jsx)(
|
|
333
|
+
"button",
|
|
334
|
+
{
|
|
335
|
+
type: "button",
|
|
336
|
+
className: "fixed inset-0 z-40 bg-overlay md:hidden",
|
|
337
|
+
"aria-label": "\u5173\u95ED\u4FA7\u8FB9\u680F\u906E\u7F69",
|
|
338
|
+
onClick: closeMobile
|
|
339
|
+
}
|
|
340
|
+
) : null,
|
|
341
|
+
sidebar
|
|
342
|
+
] });
|
|
343
|
+
}
|
|
344
|
+
);
|
|
345
|
+
Sidebar.displayName = "Sidebar";
|
|
346
|
+
|
|
347
|
+
// src/patterns/admin-shell.tsx
|
|
348
|
+
var import_jsx_runtime3 = require("react/jsx-runtime");
|
|
349
|
+
var AdminShell = (0, import_react3.forwardRef)(
|
|
350
|
+
({
|
|
351
|
+
navItems,
|
|
352
|
+
sidebarHeader,
|
|
353
|
+
sidebarFooter,
|
|
354
|
+
sidebarVariant = "dark",
|
|
355
|
+
sidebarSearchable = false,
|
|
356
|
+
sidebarCollapsible = true,
|
|
357
|
+
sidebarCollapsed,
|
|
358
|
+
defaultSidebarCollapsed = false,
|
|
359
|
+
onSidebarCollapsedChange,
|
|
360
|
+
mobileSidebarOpen,
|
|
361
|
+
onMobileSidebarOpenChange,
|
|
362
|
+
topbarStart,
|
|
363
|
+
topbarEnd,
|
|
364
|
+
topbar,
|
|
365
|
+
mainClassName,
|
|
366
|
+
contentClassName,
|
|
367
|
+
children,
|
|
368
|
+
className,
|
|
369
|
+
...props
|
|
370
|
+
}, ref) => {
|
|
371
|
+
const [internalMobileOpen, setInternalMobileOpen] = (0, import_react3.useState)(false);
|
|
372
|
+
const effectiveMobileOpen = mobileSidebarOpen ?? internalMobileOpen;
|
|
373
|
+
function setMobileOpen(open) {
|
|
374
|
+
if (mobileSidebarOpen === void 0) {
|
|
375
|
+
setInternalMobileOpen(open);
|
|
376
|
+
}
|
|
377
|
+
onMobileSidebarOpenChange?.(open);
|
|
378
|
+
}
|
|
379
|
+
return /* @__PURE__ */ (0, import_jsx_runtime3.jsx)(
|
|
380
|
+
"div",
|
|
381
|
+
{
|
|
382
|
+
ref,
|
|
383
|
+
className: cn("min-h-screen bg-surface-0 text-text-primary", className),
|
|
384
|
+
...props,
|
|
385
|
+
children: /* @__PURE__ */ (0, import_jsx_runtime3.jsxs)("div", { className: "flex min-h-screen min-w-0", children: [
|
|
386
|
+
/* @__PURE__ */ (0, import_jsx_runtime3.jsx)(
|
|
387
|
+
Sidebar,
|
|
388
|
+
{
|
|
389
|
+
items: navItems,
|
|
390
|
+
variant: sidebarVariant,
|
|
391
|
+
header: sidebarHeader,
|
|
392
|
+
footer: sidebarFooter,
|
|
393
|
+
searchable: sidebarSearchable,
|
|
394
|
+
collapsible: sidebarCollapsible,
|
|
395
|
+
collapsed: sidebarCollapsed,
|
|
396
|
+
defaultCollapsed: defaultSidebarCollapsed,
|
|
397
|
+
onCollapsedChange: onSidebarCollapsedChange,
|
|
398
|
+
responsive: true,
|
|
399
|
+
mobileOpen: effectiveMobileOpen,
|
|
400
|
+
onMobileOpenChange: setMobileOpen,
|
|
401
|
+
className: "shrink-0"
|
|
402
|
+
}
|
|
403
|
+
),
|
|
404
|
+
/* @__PURE__ */ (0, import_jsx_runtime3.jsxs)("div", { className: "flex min-w-0 flex-1 flex-col", children: [
|
|
405
|
+
/* @__PURE__ */ (0, import_jsx_runtime3.jsxs)("header", { className: "sticky top-0 z-30 flex min-h-14 items-center gap-3 border-b border-border-base bg-surface-0/95 px-4 backdrop-blur sm:px-6 lg:px-8", children: [
|
|
406
|
+
/* @__PURE__ */ (0, import_jsx_runtime3.jsx)(
|
|
407
|
+
Button,
|
|
408
|
+
{
|
|
409
|
+
type: "button",
|
|
410
|
+
variant: "ghost",
|
|
411
|
+
size: "icon",
|
|
412
|
+
className: "md:hidden",
|
|
413
|
+
"aria-label": "\u6253\u5F00\u4FA7\u8FB9\u680F",
|
|
414
|
+
onClick: () => setMobileOpen(true),
|
|
415
|
+
children: /* @__PURE__ */ (0, import_jsx_runtime3.jsx)(import_lucide_react3.Menu, { size: 18 })
|
|
416
|
+
}
|
|
417
|
+
),
|
|
418
|
+
topbar ? /* @__PURE__ */ (0, import_jsx_runtime3.jsx)("div", { className: "min-w-0 flex-1", children: topbar }) : /* @__PURE__ */ (0, import_jsx_runtime3.jsxs)(import_jsx_runtime3.Fragment, { children: [
|
|
419
|
+
/* @__PURE__ */ (0, import_jsx_runtime3.jsx)("div", { className: "min-w-0 flex-1", children: topbarStart }),
|
|
420
|
+
topbarEnd ? /* @__PURE__ */ (0, import_jsx_runtime3.jsx)("div", { className: "flex shrink-0 items-center gap-2", children: topbarEnd }) : null
|
|
421
|
+
] })
|
|
422
|
+
] }),
|
|
423
|
+
/* @__PURE__ */ (0, import_jsx_runtime3.jsx)("main", { className: cn("min-w-0 flex-1 overflow-x-hidden", mainClassName), children: /* @__PURE__ */ (0, import_jsx_runtime3.jsx)("div", { className: cn("mx-auto w-full max-w-7xl px-4 py-6 sm:px-6 lg:px-8", contentClassName), children }) })
|
|
424
|
+
] })
|
|
425
|
+
] })
|
|
426
|
+
}
|
|
427
|
+
);
|
|
428
|
+
}
|
|
429
|
+
);
|
|
430
|
+
AdminShell.displayName = "AdminShell";
|
|
431
|
+
|
|
432
|
+
// src/patterns/confirm-dialog.tsx
|
|
433
|
+
var import_react7 = require("react");
|
|
434
|
+
var import_lucide_react5 = require("lucide-react");
|
|
435
|
+
|
|
436
|
+
// src/components/modal.tsx
|
|
437
|
+
var import_react6 = require("react");
|
|
438
|
+
var import_react_dom = require("react-dom");
|
|
439
|
+
var import_lucide_react4 = require("lucide-react");
|
|
440
|
+
|
|
441
|
+
// src/hooks/use-escape-key.ts
|
|
442
|
+
var import_react4 = require("react");
|
|
443
|
+
function useEscapeKey(open, onEscape) {
|
|
444
|
+
const handleEscape = (0, import_react4.useCallback)(
|
|
445
|
+
(e) => {
|
|
446
|
+
if (e.key === "Escape") onEscape();
|
|
447
|
+
},
|
|
448
|
+
[onEscape]
|
|
449
|
+
);
|
|
450
|
+
(0, import_react4.useEffect)(() => {
|
|
451
|
+
if (!open || typeof document === "undefined") return;
|
|
452
|
+
document.addEventListener("keydown", handleEscape);
|
|
453
|
+
document.body.style.overflow = "hidden";
|
|
454
|
+
return () => {
|
|
455
|
+
document.removeEventListener("keydown", handleEscape);
|
|
456
|
+
document.body.style.overflow = "";
|
|
457
|
+
};
|
|
458
|
+
}, [open, handleEscape]);
|
|
459
|
+
}
|
|
460
|
+
|
|
461
|
+
// src/internal/use-portal-container.ts
|
|
462
|
+
var import_react5 = require("react");
|
|
463
|
+
function usePortalContainer() {
|
|
464
|
+
const [container, setContainer] = (0, import_react5.useState)(null);
|
|
465
|
+
(0, import_react5.useEffect)(() => {
|
|
466
|
+
if (typeof document === "undefined") return;
|
|
467
|
+
setContainer(document.body);
|
|
468
|
+
}, []);
|
|
469
|
+
return container;
|
|
470
|
+
}
|
|
471
|
+
|
|
472
|
+
// src/components/modal.tsx
|
|
473
|
+
var import_jsx_runtime4 = require("react/jsx-runtime");
|
|
474
|
+
var Modal = (0, import_react6.forwardRef)(({ open, onClose, children, className }, ref) => {
|
|
475
|
+
useEscapeKey(open, onClose);
|
|
476
|
+
const portalContainer = usePortalContainer();
|
|
477
|
+
if (!open || !portalContainer) return null;
|
|
478
|
+
return (0, import_react_dom.createPortal)(
|
|
479
|
+
/* @__PURE__ */ (0, import_jsx_runtime4.jsxs)(
|
|
480
|
+
"div",
|
|
481
|
+
{
|
|
482
|
+
ref,
|
|
483
|
+
className: cn(
|
|
484
|
+
"fixed inset-0 z-[80] flex items-center justify-center p-4",
|
|
485
|
+
className
|
|
486
|
+
),
|
|
487
|
+
role: "dialog",
|
|
488
|
+
"aria-modal": "true",
|
|
489
|
+
children: [
|
|
490
|
+
/* @__PURE__ */ (0, import_jsx_runtime4.jsx)(
|
|
491
|
+
"div",
|
|
492
|
+
{
|
|
493
|
+
className: "absolute inset-0 bg-overlay",
|
|
494
|
+
onClick: onClose,
|
|
495
|
+
"aria-hidden": "true"
|
|
496
|
+
}
|
|
497
|
+
),
|
|
498
|
+
/* @__PURE__ */ (0, import_jsx_runtime4.jsx)("div", { className: "relative z-10", children })
|
|
499
|
+
]
|
|
500
|
+
}
|
|
501
|
+
),
|
|
502
|
+
portalContainer
|
|
503
|
+
);
|
|
504
|
+
});
|
|
505
|
+
var ModalContent = (0, import_react6.forwardRef)(({ className, maxWidth = "max-w-lg", children, ...props }, ref) => {
|
|
506
|
+
return /* @__PURE__ */ (0, import_jsx_runtime4.jsx)("div", { ref, className: cn("flex max-h-[85vh] w-full flex-col rounded-lg border border-border-base bg-surface-1 shadow-xl", maxWidth, className), ...props, children });
|
|
507
|
+
});
|
|
508
|
+
var ModalHeader = (0, import_react6.forwardRef)(({ className, ...props }, ref) => {
|
|
509
|
+
return /* @__PURE__ */ (0, import_jsx_runtime4.jsx)("div", { ref, className: cn("flex shrink-0 items-center justify-between border-b border-border-base px-6 py-4", className), ...props });
|
|
510
|
+
});
|
|
511
|
+
var ModalTitle = (0, import_react6.forwardRef)(({ className, ...props }, ref) => {
|
|
512
|
+
return /* @__PURE__ */ (0, import_jsx_runtime4.jsx)("h2", { ref, className: cn("text-lg font-semibold text-text-primary", className), ...props });
|
|
513
|
+
});
|
|
514
|
+
var ModalFooter = (0, import_react6.forwardRef)(({ className, ...props }, ref) => {
|
|
515
|
+
return /* @__PURE__ */ (0, import_jsx_runtime4.jsx)("div", { ref, className: cn("flex shrink-0 items-center justify-end gap-2 border-t border-border-base px-6 py-4", className), ...props });
|
|
516
|
+
});
|
|
517
|
+
var ModalCloseButton = (0, import_react6.forwardRef)(({ onClick, className, type = "button", ...props }, ref) => {
|
|
518
|
+
return /* @__PURE__ */ (0, import_jsx_runtime4.jsx)(
|
|
519
|
+
"button",
|
|
520
|
+
{
|
|
521
|
+
ref,
|
|
522
|
+
type,
|
|
523
|
+
onClick,
|
|
524
|
+
className: cn(
|
|
525
|
+
"rounded-md p-1 text-text-tertiary transition-colors hover:bg-surface-3 hover:text-text-secondary",
|
|
526
|
+
className
|
|
527
|
+
),
|
|
528
|
+
"aria-label": "\u5173\u95ED",
|
|
529
|
+
...props,
|
|
530
|
+
children: /* @__PURE__ */ (0, import_jsx_runtime4.jsx)(import_lucide_react4.X, { size: 18 })
|
|
531
|
+
}
|
|
532
|
+
);
|
|
533
|
+
});
|
|
534
|
+
Modal.displayName = "Modal";
|
|
535
|
+
ModalContent.displayName = "ModalContent";
|
|
536
|
+
ModalHeader.displayName = "ModalHeader";
|
|
537
|
+
ModalTitle.displayName = "ModalTitle";
|
|
538
|
+
ModalFooter.displayName = "ModalFooter";
|
|
539
|
+
ModalCloseButton.displayName = "ModalCloseButton";
|
|
540
|
+
|
|
541
|
+
// src/patterns/confirm-dialog.tsx
|
|
542
|
+
var import_jsx_runtime5 = require("react/jsx-runtime");
|
|
543
|
+
var ConfirmDialog = (0, import_react7.forwardRef)(
|
|
544
|
+
({
|
|
545
|
+
open,
|
|
546
|
+
onOpenChange,
|
|
547
|
+
title,
|
|
548
|
+
description,
|
|
549
|
+
children,
|
|
550
|
+
variant = "destructive",
|
|
551
|
+
icon,
|
|
552
|
+
cancelText = "\u53D6\u6D88",
|
|
553
|
+
confirmText = "\u786E\u8BA4",
|
|
554
|
+
loading = false,
|
|
555
|
+
disabled = false,
|
|
556
|
+
closeOnConfirm = true,
|
|
557
|
+
onCancel,
|
|
558
|
+
onConfirm,
|
|
559
|
+
className,
|
|
560
|
+
...props
|
|
561
|
+
}, ref) => {
|
|
562
|
+
const Icon = icon ?? (variant === "destructive" ? import_lucide_react5.AlertTriangle : import_lucide_react5.HelpCircle);
|
|
563
|
+
function handleCancel() {
|
|
564
|
+
onCancel?.();
|
|
565
|
+
onOpenChange(false);
|
|
566
|
+
}
|
|
567
|
+
function handleConfirm() {
|
|
568
|
+
const result = onConfirm?.();
|
|
569
|
+
if (closeOnConfirm) onOpenChange(false);
|
|
570
|
+
return result;
|
|
571
|
+
}
|
|
572
|
+
return /* @__PURE__ */ (0, import_jsx_runtime5.jsx)(Modal, { open, onClose: handleCancel, children: /* @__PURE__ */ (0, import_jsx_runtime5.jsxs)(
|
|
573
|
+
ModalContent,
|
|
574
|
+
{
|
|
575
|
+
ref,
|
|
576
|
+
className: cn("max-w-md", className),
|
|
577
|
+
...props,
|
|
578
|
+
children: [
|
|
579
|
+
/* @__PURE__ */ (0, import_jsx_runtime5.jsxs)(ModalHeader, { className: "items-start gap-3", children: [
|
|
580
|
+
/* @__PURE__ */ (0, import_jsx_runtime5.jsx)(
|
|
581
|
+
"div",
|
|
582
|
+
{
|
|
583
|
+
className: cn(
|
|
584
|
+
"flex h-10 w-10 shrink-0 items-center justify-center rounded-md",
|
|
585
|
+
variant === "destructive" ? "bg-danger-soft text-danger-soft-fg" : "bg-primary-soft text-primary-soft-fg"
|
|
586
|
+
),
|
|
587
|
+
children: /* @__PURE__ */ (0, import_jsx_runtime5.jsx)(Icon, { size: 20, "aria-hidden": "true" })
|
|
588
|
+
}
|
|
589
|
+
),
|
|
590
|
+
/* @__PURE__ */ (0, import_jsx_runtime5.jsxs)("div", { className: "min-w-0 flex-1 space-y-1", children: [
|
|
591
|
+
/* @__PURE__ */ (0, import_jsx_runtime5.jsx)(ModalTitle, { className: "break-words text-base", children: title }),
|
|
592
|
+
description ? /* @__PURE__ */ (0, import_jsx_runtime5.jsx)("p", { className: "text-sm leading-6 text-text-secondary", children: description }) : null
|
|
593
|
+
] })
|
|
594
|
+
] }),
|
|
595
|
+
children ? /* @__PURE__ */ (0, import_jsx_runtime5.jsx)("div", { className: "px-6 py-4 text-sm text-text-secondary", children }) : null,
|
|
596
|
+
/* @__PURE__ */ (0, import_jsx_runtime5.jsxs)(ModalFooter, { className: "flex-col-reverse gap-2 sm:flex-row", children: [
|
|
597
|
+
/* @__PURE__ */ (0, import_jsx_runtime5.jsx)(Button, { type: "button", variant: "outline", disabled: loading, onClick: handleCancel, children: cancelText }),
|
|
598
|
+
/* @__PURE__ */ (0, import_jsx_runtime5.jsx)(
|
|
599
|
+
Button,
|
|
600
|
+
{
|
|
601
|
+
type: "button",
|
|
602
|
+
variant: variant === "destructive" ? "destructive" : "default",
|
|
603
|
+
loading,
|
|
604
|
+
disabled,
|
|
605
|
+
onClick: handleConfirm,
|
|
606
|
+
children: confirmText
|
|
607
|
+
}
|
|
608
|
+
)
|
|
609
|
+
] })
|
|
610
|
+
]
|
|
611
|
+
}
|
|
612
|
+
) });
|
|
613
|
+
}
|
|
614
|
+
);
|
|
615
|
+
ConfirmDialog.displayName = "ConfirmDialog";
|
|
616
|
+
|
|
617
|
+
// src/patterns/copy-field.tsx
|
|
618
|
+
var import_react8 = require("react");
|
|
619
|
+
var import_lucide_react6 = require("lucide-react");
|
|
620
|
+
var import_jsx_runtime6 = require("react/jsx-runtime");
|
|
621
|
+
var CopyField = (0, import_react8.forwardRef)(
|
|
622
|
+
({
|
|
623
|
+
value,
|
|
624
|
+
label,
|
|
625
|
+
displayValue,
|
|
626
|
+
monospace = true,
|
|
627
|
+
disabled = false,
|
|
628
|
+
copyLabel = "\u590D\u5236",
|
|
629
|
+
copiedLabel = "\u5DF2\u590D\u5236",
|
|
630
|
+
onCopied,
|
|
631
|
+
onCopyError,
|
|
632
|
+
className,
|
|
633
|
+
...props
|
|
634
|
+
}, ref) => {
|
|
635
|
+
const [copied, setCopied] = (0, import_react8.useState)(false);
|
|
636
|
+
const timeoutRef = (0, import_react8.useRef)(null);
|
|
637
|
+
(0, import_react8.useEffect)(() => {
|
|
638
|
+
return () => {
|
|
639
|
+
if (timeoutRef.current) clearTimeout(timeoutRef.current);
|
|
640
|
+
};
|
|
641
|
+
}, []);
|
|
642
|
+
async function handleCopy() {
|
|
643
|
+
if (disabled) return;
|
|
644
|
+
try {
|
|
645
|
+
if (!navigator.clipboard?.writeText) {
|
|
646
|
+
throw new Error("Clipboard API is not available");
|
|
647
|
+
}
|
|
648
|
+
await navigator.clipboard.writeText(value);
|
|
649
|
+
setCopied(true);
|
|
650
|
+
onCopied?.(value);
|
|
651
|
+
if (timeoutRef.current) clearTimeout(timeoutRef.current);
|
|
652
|
+
timeoutRef.current = setTimeout(() => setCopied(false), 1400);
|
|
653
|
+
} catch (error) {
|
|
654
|
+
onCopyError?.(error);
|
|
655
|
+
}
|
|
656
|
+
}
|
|
657
|
+
return /* @__PURE__ */ (0, import_jsx_runtime6.jsxs)("div", { ref, className: cn("space-y-2", className), ...props, children: [
|
|
658
|
+
label ? /* @__PURE__ */ (0, import_jsx_runtime6.jsx)("div", { className: "text-xs font-medium text-text-secondary", children: label }) : null,
|
|
659
|
+
/* @__PURE__ */ (0, import_jsx_runtime6.jsxs)(
|
|
660
|
+
"div",
|
|
661
|
+
{
|
|
662
|
+
className: cn(
|
|
663
|
+
"flex min-w-0 items-stretch overflow-hidden rounded-md border border-border-base bg-surface-1",
|
|
664
|
+
disabled && "opacity-60"
|
|
665
|
+
),
|
|
666
|
+
children: [
|
|
667
|
+
/* @__PURE__ */ (0, import_jsx_runtime6.jsx)(
|
|
668
|
+
"div",
|
|
669
|
+
{
|
|
670
|
+
className: cn(
|
|
671
|
+
"min-w-0 flex-1 truncate px-3 py-2 text-sm text-text-primary",
|
|
672
|
+
monospace && "font-mono"
|
|
673
|
+
),
|
|
674
|
+
title: typeof displayValue === "string" ? displayValue : value,
|
|
675
|
+
children: displayValue ?? value
|
|
676
|
+
}
|
|
677
|
+
),
|
|
678
|
+
/* @__PURE__ */ (0, import_jsx_runtime6.jsx)("div", { className: "flex shrink-0 items-center border-l border-border-base bg-surface-2 px-1.5", children: /* @__PURE__ */ (0, import_jsx_runtime6.jsxs)(
|
|
679
|
+
Button,
|
|
680
|
+
{
|
|
681
|
+
type: "button",
|
|
682
|
+
variant: "ghost",
|
|
683
|
+
size: "sm",
|
|
684
|
+
disabled,
|
|
685
|
+
onClick: handleCopy,
|
|
686
|
+
"aria-live": "polite",
|
|
687
|
+
children: [
|
|
688
|
+
copied ? /* @__PURE__ */ (0, import_jsx_runtime6.jsx)(import_lucide_react6.Check, { size: 15 }) : /* @__PURE__ */ (0, import_jsx_runtime6.jsx)(import_lucide_react6.Copy, { size: 15 }),
|
|
689
|
+
copied ? copiedLabel : copyLabel
|
|
690
|
+
]
|
|
691
|
+
}
|
|
692
|
+
) })
|
|
693
|
+
]
|
|
694
|
+
}
|
|
695
|
+
)
|
|
696
|
+
] });
|
|
697
|
+
}
|
|
698
|
+
);
|
|
699
|
+
CopyField.displayName = "CopyField";
|
|
700
|
+
|
|
701
|
+
// src/patterns/page-header.tsx
|
|
702
|
+
var import_react9 = require("react");
|
|
703
|
+
var import_jsx_runtime7 = require("react/jsx-runtime");
|
|
704
|
+
var PageHeader = (0, import_react9.forwardRef)(
|
|
705
|
+
({
|
|
706
|
+
eyebrow,
|
|
707
|
+
title,
|
|
708
|
+
description,
|
|
709
|
+
badge,
|
|
710
|
+
breadcrumb,
|
|
711
|
+
actions,
|
|
712
|
+
meta,
|
|
713
|
+
children,
|
|
714
|
+
className,
|
|
715
|
+
...props
|
|
716
|
+
}, ref) => {
|
|
717
|
+
return /* @__PURE__ */ (0, import_jsx_runtime7.jsxs)(
|
|
718
|
+
"header",
|
|
719
|
+
{
|
|
720
|
+
ref,
|
|
721
|
+
className: cn(
|
|
722
|
+
"flex min-w-0 flex-col gap-5 border-b border-border-base pb-6",
|
|
723
|
+
className
|
|
724
|
+
),
|
|
725
|
+
...props,
|
|
726
|
+
children: [
|
|
727
|
+
breadcrumb ? /* @__PURE__ */ (0, import_jsx_runtime7.jsx)("div", { className: "min-w-0", children: breadcrumb }) : null,
|
|
728
|
+
/* @__PURE__ */ (0, import_jsx_runtime7.jsxs)("div", { className: "flex min-w-0 flex-col gap-4 lg:flex-row lg:items-start lg:justify-between", children: [
|
|
729
|
+
/* @__PURE__ */ (0, import_jsx_runtime7.jsxs)("div", { className: "min-w-0 space-y-3", children: [
|
|
730
|
+
eyebrow ? /* @__PURE__ */ (0, import_jsx_runtime7.jsx)("div", { className: "text-xs font-semibold uppercase text-primary", children: eyebrow }) : null,
|
|
731
|
+
/* @__PURE__ */ (0, import_jsx_runtime7.jsxs)("div", { className: "flex min-w-0 flex-wrap items-center gap-2.5", children: [
|
|
732
|
+
/* @__PURE__ */ (0, import_jsx_runtime7.jsx)("h1", { className: "min-w-0 break-words text-2xl font-bold leading-tight text-text-primary sm:text-3xl", children: title }),
|
|
733
|
+
badge ? /* @__PURE__ */ (0, import_jsx_runtime7.jsx)("div", { className: "shrink-0", children: badge }) : null
|
|
734
|
+
] }),
|
|
735
|
+
description ? /* @__PURE__ */ (0, import_jsx_runtime7.jsx)("p", { className: "max-w-3xl text-sm leading-6 text-text-secondary", children: description }) : null,
|
|
736
|
+
meta ? /* @__PURE__ */ (0, import_jsx_runtime7.jsx)("div", { className: "flex min-w-0 flex-wrap items-center gap-x-4 gap-y-2 text-xs text-text-tertiary", children: meta }) : null
|
|
737
|
+
] }),
|
|
738
|
+
actions ? /* @__PURE__ */ (0, import_jsx_runtime7.jsx)("div", { className: "flex shrink-0 flex-wrap items-center gap-2 lg:justify-end", children: actions }) : null
|
|
739
|
+
] }),
|
|
740
|
+
children ? /* @__PURE__ */ (0, import_jsx_runtime7.jsx)("div", { className: "min-w-0", children }) : null
|
|
741
|
+
]
|
|
742
|
+
}
|
|
743
|
+
);
|
|
744
|
+
}
|
|
745
|
+
);
|
|
746
|
+
PageHeader.displayName = "PageHeader";
|
|
747
|
+
// Annotate the CommonJS export names for ESM import in node:
|
|
748
|
+
0 && (module.exports = {
|
|
749
|
+
AdminShell,
|
|
750
|
+
ConfirmDialog,
|
|
751
|
+
CopyField,
|
|
752
|
+
PageHeader,
|
|
753
|
+
UGAdminShell,
|
|
754
|
+
UGConfirmDialog,
|
|
755
|
+
UGCopyField,
|
|
756
|
+
UGPageHeader
|
|
757
|
+
});
|
|
758
|
+
//# sourceMappingURL=index.cjs.map
|