@pactor-app/ui 0.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/LICENSE +21 -0
- package/README.md +113 -0
- package/dist/chunk-57NRUZ5G.js +95 -0
- package/dist/chunk-DMK6RSTK.js +746 -0
- package/dist/chunk-OH3U6PCM.js +536 -0
- package/dist/chunk-OUTSIJMO.js +442 -0
- package/dist/chunk-QDTVOJ5P.js +147 -0
- package/dist/chunk-QWZ23QLS.js +68 -0
- package/dist/chunk-RQHJBTEU.js +10 -0
- package/dist/chunk-SNFDI77B.js +136 -0
- package/dist/chunk-XGOTHOI6.js +619 -0
- package/dist/components/index.cjs +1111 -0
- package/dist/components/index.d.cts +307 -0
- package/dist/components/index.d.ts +307 -0
- package/dist/components/index.js +40 -0
- package/dist/index.cjs +2626 -0
- package/dist/index.d.cts +41 -0
- package/dist/index.d.ts +41 -0
- package/dist/index.js +87 -0
- package/dist/interaction/index.cjs +752 -0
- package/dist/interaction/index.d.cts +178 -0
- package/dist/interaction/index.d.ts +178 -0
- package/dist/interaction/index.js +19 -0
- package/dist/layout/index.cjs +938 -0
- package/dist/layout/index.d.cts +158 -0
- package/dist/layout/index.d.ts +158 -0
- package/dist/layout/index.js +25 -0
- package/dist/ui/index.cjs +1076 -0
- package/dist/ui/index.d.cts +166 -0
- package/dist/ui/index.d.ts +166 -0
- package/dist/ui/index.js +233 -0
- package/package.json +127 -0
- package/styles.css +1672 -0
|
@@ -0,0 +1,938 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
var __defProp = Object.defineProperty;
|
|
3
|
+
var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
|
|
4
|
+
var __getOwnPropNames = Object.getOwnPropertyNames;
|
|
5
|
+
var __hasOwnProp = Object.prototype.hasOwnProperty;
|
|
6
|
+
var __export = (target, all) => {
|
|
7
|
+
for (var name in all)
|
|
8
|
+
__defProp(target, name, { get: all[name], enumerable: true });
|
|
9
|
+
};
|
|
10
|
+
var __copyProps = (to, from, except, desc) => {
|
|
11
|
+
if (from && typeof from === "object" || typeof from === "function") {
|
|
12
|
+
for (let key of __getOwnPropNames(from))
|
|
13
|
+
if (!__hasOwnProp.call(to, key) && key !== except)
|
|
14
|
+
__defProp(to, key, { get: () => from[key], enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable });
|
|
15
|
+
}
|
|
16
|
+
return to;
|
|
17
|
+
};
|
|
18
|
+
var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod);
|
|
19
|
+
|
|
20
|
+
// src/layout/index.ts
|
|
21
|
+
var layout_exports = {};
|
|
22
|
+
__export(layout_exports, {
|
|
23
|
+
ShadcnAdminLayout: () => ShadcnAdminLayout,
|
|
24
|
+
ShadcnBlankLayout: () => ShadcnBlankLayout,
|
|
25
|
+
ShadcnLandingLayout: () => ShadcnLandingLayout,
|
|
26
|
+
ShadcnLoginLayout: () => ShadcnLoginLayout,
|
|
27
|
+
collectDefaultOpenKeys: () => collectDefaultOpenKeys,
|
|
28
|
+
createShadcnLayoutRegistry: () => createShadcnLayoutRegistry,
|
|
29
|
+
findMenuChain: () => findMenuChain,
|
|
30
|
+
registerShadcnLayouts: () => registerShadcnLayouts,
|
|
31
|
+
resolveLayout: () => resolveLayout
|
|
32
|
+
});
|
|
33
|
+
module.exports = __toCommonJS(layout_exports);
|
|
34
|
+
|
|
35
|
+
// src/layout/admin/menu-chain.ts
|
|
36
|
+
function findMenuChain(registry, menuId) {
|
|
37
|
+
const walk = (menus, ancestors) => {
|
|
38
|
+
for (const menu of menus) {
|
|
39
|
+
const chain = [...ancestors, menu];
|
|
40
|
+
if (menu.id === menuId) {
|
|
41
|
+
return chain;
|
|
42
|
+
}
|
|
43
|
+
if (menu.children !== void 0) {
|
|
44
|
+
const hit = walk(menu.children, chain);
|
|
45
|
+
if (hit !== null) {
|
|
46
|
+
return hit;
|
|
47
|
+
}
|
|
48
|
+
}
|
|
49
|
+
}
|
|
50
|
+
return null;
|
|
51
|
+
};
|
|
52
|
+
return walk(registry.tree(), []) ?? [];
|
|
53
|
+
}
|
|
54
|
+
|
|
55
|
+
// src/layout/admin/menu-items.ts
|
|
56
|
+
function collectDefaultOpenKeys(registry, activeMenuId) {
|
|
57
|
+
const keys = [];
|
|
58
|
+
const walk = (menus) => {
|
|
59
|
+
for (const menu of menus) {
|
|
60
|
+
if (menu.type === "group" && menu.defaultOpen === true) {
|
|
61
|
+
keys.push(menu.id);
|
|
62
|
+
}
|
|
63
|
+
if (menu.children !== void 0) {
|
|
64
|
+
walk(menu.children);
|
|
65
|
+
}
|
|
66
|
+
}
|
|
67
|
+
};
|
|
68
|
+
walk(registry.tree());
|
|
69
|
+
if (activeMenuId !== void 0) {
|
|
70
|
+
for (const menu of findMenuChain(registry, activeMenuId)) {
|
|
71
|
+
if (menu.type === "group" && !keys.includes(menu.id)) {
|
|
72
|
+
keys.push(menu.id);
|
|
73
|
+
}
|
|
74
|
+
}
|
|
75
|
+
}
|
|
76
|
+
return keys;
|
|
77
|
+
}
|
|
78
|
+
|
|
79
|
+
// src/layout/admin/ShadcnAdminLayout.tsx
|
|
80
|
+
var import_permission = require("@pactor-app/permission");
|
|
81
|
+
var import_router = require("@pactor-app/router");
|
|
82
|
+
var import_runtime = require("@pactor-app/runtime");
|
|
83
|
+
var import_react2 = require("react");
|
|
84
|
+
|
|
85
|
+
// src/lib/utils.ts
|
|
86
|
+
var import_clsx = require("clsx");
|
|
87
|
+
var import_tailwind_merge = require("tailwind-merge");
|
|
88
|
+
function cn(...inputs) {
|
|
89
|
+
return (0, import_tailwind_merge.twMerge)((0, import_clsx.clsx)(inputs));
|
|
90
|
+
}
|
|
91
|
+
|
|
92
|
+
// src/ui/accordion.tsx
|
|
93
|
+
var import_accordion = require("@base-ui/react/accordion");
|
|
94
|
+
var import_lucide_react = require("lucide-react");
|
|
95
|
+
var import_jsx_runtime = require("react/jsx-runtime");
|
|
96
|
+
function toArray(value) {
|
|
97
|
+
if (value === void 0) {
|
|
98
|
+
return void 0;
|
|
99
|
+
}
|
|
100
|
+
return Array.isArray(value) ? value : [value];
|
|
101
|
+
}
|
|
102
|
+
function Accordion({
|
|
103
|
+
type = "single",
|
|
104
|
+
value,
|
|
105
|
+
defaultValue,
|
|
106
|
+
onValueChange,
|
|
107
|
+
...props
|
|
108
|
+
}) {
|
|
109
|
+
return /* @__PURE__ */ (0, import_jsx_runtime.jsx)(
|
|
110
|
+
import_accordion.Accordion.Root,
|
|
111
|
+
{
|
|
112
|
+
"data-slot": "accordion",
|
|
113
|
+
multiple: type === "multiple",
|
|
114
|
+
value: toArray(value),
|
|
115
|
+
defaultValue: toArray(defaultValue),
|
|
116
|
+
onValueChange: onValueChange === void 0 ? void 0 : (next) => onValueChange(type === "multiple" ? next : next[0] ?? ""),
|
|
117
|
+
...props
|
|
118
|
+
}
|
|
119
|
+
);
|
|
120
|
+
}
|
|
121
|
+
function AccordionItem({
|
|
122
|
+
className,
|
|
123
|
+
...props
|
|
124
|
+
}) {
|
|
125
|
+
return /* @__PURE__ */ (0, import_jsx_runtime.jsx)(
|
|
126
|
+
import_accordion.Accordion.Item,
|
|
127
|
+
{
|
|
128
|
+
"data-slot": "accordion-item",
|
|
129
|
+
className: cn("border-b border-border last:border-b-0", className),
|
|
130
|
+
...props
|
|
131
|
+
}
|
|
132
|
+
);
|
|
133
|
+
}
|
|
134
|
+
function AccordionTrigger({
|
|
135
|
+
className,
|
|
136
|
+
children,
|
|
137
|
+
...props
|
|
138
|
+
}) {
|
|
139
|
+
return /* @__PURE__ */ (0, import_jsx_runtime.jsx)(import_accordion.Accordion.Header, { className: "flex", children: /* @__PURE__ */ (0, import_jsx_runtime.jsxs)(
|
|
140
|
+
import_accordion.Accordion.Trigger,
|
|
141
|
+
{
|
|
142
|
+
"data-slot": "accordion-trigger",
|
|
143
|
+
className: cn(
|
|
144
|
+
"flex flex-1 cursor-pointer items-center justify-between gap-4 rounded-md py-4 text-left text-sm font-medium transition-colors outline-none hover:bg-accent hover:text-accent-foreground focus-visible:border-ring focus-visible:ring-[3px] focus-visible:ring-ring/50 disabled:pointer-events-none disabled:opacity-50 [&[aria-expanded=true]>svg]:rotate-180",
|
|
145
|
+
className
|
|
146
|
+
),
|
|
147
|
+
...props,
|
|
148
|
+
children: [
|
|
149
|
+
children,
|
|
150
|
+
/* @__PURE__ */ (0, import_jsx_runtime.jsx)(import_lucide_react.ChevronDownIcon, { className: "pointer-events-none size-4 shrink-0 translate-y-0.5 text-muted-foreground transition-transform duration-200" })
|
|
151
|
+
]
|
|
152
|
+
}
|
|
153
|
+
) });
|
|
154
|
+
}
|
|
155
|
+
function AccordionContent({
|
|
156
|
+
className,
|
|
157
|
+
children,
|
|
158
|
+
...props
|
|
159
|
+
}) {
|
|
160
|
+
return /* @__PURE__ */ (0, import_jsx_runtime.jsx)(
|
|
161
|
+
import_accordion.Accordion.Panel,
|
|
162
|
+
{
|
|
163
|
+
"data-slot": "accordion-content",
|
|
164
|
+
className: "overflow-hidden text-sm data-open:animate-accordion-down data-closed:animate-accordion-up",
|
|
165
|
+
...props,
|
|
166
|
+
children: /* @__PURE__ */ (0, import_jsx_runtime.jsx)("div", { className: cn("pt-0 pb-4", className), children })
|
|
167
|
+
}
|
|
168
|
+
);
|
|
169
|
+
}
|
|
170
|
+
|
|
171
|
+
// src/ui/popover.tsx
|
|
172
|
+
var import_popover = require("@base-ui/react/popover");
|
|
173
|
+
var import_jsx_runtime2 = require("react/jsx-runtime");
|
|
174
|
+
function Popover({
|
|
175
|
+
...props
|
|
176
|
+
}) {
|
|
177
|
+
return /* @__PURE__ */ (0, import_jsx_runtime2.jsx)(import_popover.Popover.Root, { "data-slot": "popover", ...props });
|
|
178
|
+
}
|
|
179
|
+
function PopoverTrigger({
|
|
180
|
+
...props
|
|
181
|
+
}) {
|
|
182
|
+
return /* @__PURE__ */ (0, import_jsx_runtime2.jsx)(import_popover.Popover.Trigger, { "data-slot": "popover-trigger", ...props });
|
|
183
|
+
}
|
|
184
|
+
function PopoverContent({
|
|
185
|
+
className,
|
|
186
|
+
align = "center",
|
|
187
|
+
side = "bottom",
|
|
188
|
+
sideOffset = 4,
|
|
189
|
+
anchor,
|
|
190
|
+
...props
|
|
191
|
+
}) {
|
|
192
|
+
return /* @__PURE__ */ (0, import_jsx_runtime2.jsx)(import_popover.Popover.Portal, { children: /* @__PURE__ */ (0, import_jsx_runtime2.jsx)(
|
|
193
|
+
import_popover.Popover.Positioner,
|
|
194
|
+
{
|
|
195
|
+
align,
|
|
196
|
+
side,
|
|
197
|
+
sideOffset,
|
|
198
|
+
anchor,
|
|
199
|
+
className: "isolate z-50",
|
|
200
|
+
children: /* @__PURE__ */ (0, import_jsx_runtime2.jsx)(
|
|
201
|
+
import_popover.Popover.Popup,
|
|
202
|
+
{
|
|
203
|
+
"data-slot": "popover-content",
|
|
204
|
+
className: cn(
|
|
205
|
+
"z-50 w-72 rounded-md border border-border bg-popover p-4 text-popover-foreground shadow-md outline-none duration-200 data-open:animate-in data-open:fade-in-0 data-open:zoom-in-95 data-closed:animate-out data-closed:fade-out-0 data-closed:zoom-out-95",
|
|
206
|
+
className
|
|
207
|
+
),
|
|
208
|
+
...props
|
|
209
|
+
}
|
|
210
|
+
)
|
|
211
|
+
}
|
|
212
|
+
) });
|
|
213
|
+
}
|
|
214
|
+
|
|
215
|
+
// src/layout/admin/use-media-query.ts
|
|
216
|
+
var import_react = require("react");
|
|
217
|
+
var BREAKPOINT_PX = {
|
|
218
|
+
xs: 480,
|
|
219
|
+
sm: 576,
|
|
220
|
+
md: 768,
|
|
221
|
+
lg: 992,
|
|
222
|
+
xl: 1200,
|
|
223
|
+
xxl: 1600
|
|
224
|
+
};
|
|
225
|
+
function useMediaQuery(query) {
|
|
226
|
+
const [matches, setMatches] = (0, import_react.useState)(
|
|
227
|
+
() => typeof window !== "undefined" && typeof window.matchMedia === "function" ? window.matchMedia(query).matches : false
|
|
228
|
+
);
|
|
229
|
+
(0, import_react.useEffect)(() => {
|
|
230
|
+
if (typeof window === "undefined" || typeof window.matchMedia !== "function") {
|
|
231
|
+
return;
|
|
232
|
+
}
|
|
233
|
+
const mql = window.matchMedia(query);
|
|
234
|
+
const onChange = (event) => setMatches(event.matches);
|
|
235
|
+
setMatches(mql.matches);
|
|
236
|
+
mql.addEventListener("change", onChange);
|
|
237
|
+
return () => mql.removeEventListener("change", onChange);
|
|
238
|
+
}, [query]);
|
|
239
|
+
return matches;
|
|
240
|
+
}
|
|
241
|
+
function useBreakpointBelow(breakpoint) {
|
|
242
|
+
const matches = useMediaQuery(
|
|
243
|
+
breakpoint ? `(max-width: ${BREAKPOINT_PX[breakpoint] - 1}px)` : "(min-width: 0px)"
|
|
244
|
+
);
|
|
245
|
+
return breakpoint !== void 0 && matches;
|
|
246
|
+
}
|
|
247
|
+
|
|
248
|
+
// src/layout/admin/ShadcnAdminLayout.tsx
|
|
249
|
+
var import_jsx_runtime3 = require("react/jsx-runtime");
|
|
250
|
+
function buildVisibleMenuTree(registry, permissionChecker) {
|
|
251
|
+
const tree = registry.tree();
|
|
252
|
+
return permissionChecker === void 0 ? [...tree] : (0, import_permission.filterMenusByPermission)(tree, permissionChecker);
|
|
253
|
+
}
|
|
254
|
+
function navigateMenuItem(menu, bridge) {
|
|
255
|
+
if (menu === void 0 || menu.type === "group" || menu.path === void 0) {
|
|
256
|
+
return;
|
|
257
|
+
}
|
|
258
|
+
if (menu.external === true || menu.type === "link") {
|
|
259
|
+
window.open(menu.path, menu.target ?? "_blank");
|
|
260
|
+
return;
|
|
261
|
+
}
|
|
262
|
+
bridge.push(menu.path);
|
|
263
|
+
}
|
|
264
|
+
var menuItemClass = "flex w-full cursor-pointer items-center rounded-md px-3 py-2 text-left text-sm text-muted-foreground transition-colors hover:bg-accent hover:text-accent-foreground disabled:pointer-events-none disabled:opacity-50";
|
|
265
|
+
function CollapsedGroupFlyout({
|
|
266
|
+
menu,
|
|
267
|
+
registry,
|
|
268
|
+
bridge,
|
|
269
|
+
activeMenuId,
|
|
270
|
+
defaultOpenKeys
|
|
271
|
+
}) {
|
|
272
|
+
const [open, setOpen] = (0, import_react2.useState)(false);
|
|
273
|
+
const closeTimer = (0, import_react2.useRef)(void 0);
|
|
274
|
+
const openNow = () => {
|
|
275
|
+
window.clearTimeout(closeTimer.current);
|
|
276
|
+
setOpen(true);
|
|
277
|
+
};
|
|
278
|
+
const closeLater = () => {
|
|
279
|
+
window.clearTimeout(closeTimer.current);
|
|
280
|
+
closeTimer.current = window.setTimeout(() => setOpen(false), 200);
|
|
281
|
+
};
|
|
282
|
+
(0, import_react2.useEffect)(() => () => window.clearTimeout(closeTimer.current), []);
|
|
283
|
+
return /* @__PURE__ */ (0, import_jsx_runtime3.jsxs)(Popover, { open, onOpenChange: setOpen, children: [
|
|
284
|
+
/* @__PURE__ */ (0, import_jsx_runtime3.jsx)(
|
|
285
|
+
PopoverTrigger,
|
|
286
|
+
{
|
|
287
|
+
render: /* @__PURE__ */ (0, import_jsx_runtime3.jsx)(
|
|
288
|
+
"button",
|
|
289
|
+
{
|
|
290
|
+
type: "button",
|
|
291
|
+
"data-slot": "menu-item",
|
|
292
|
+
className: cn(
|
|
293
|
+
menuItemClass,
|
|
294
|
+
"mx-auto size-10 justify-center px-0 font-semibold"
|
|
295
|
+
),
|
|
296
|
+
disabled: menu.disabled,
|
|
297
|
+
title: menu.title,
|
|
298
|
+
onMouseEnter: openNow,
|
|
299
|
+
onMouseLeave: closeLater,
|
|
300
|
+
children: menu.title.slice(0, 1)
|
|
301
|
+
}
|
|
302
|
+
)
|
|
303
|
+
}
|
|
304
|
+
),
|
|
305
|
+
/* @__PURE__ */ (0, import_jsx_runtime3.jsxs)(
|
|
306
|
+
PopoverContent,
|
|
307
|
+
{
|
|
308
|
+
"data-slot": "menu-flyout",
|
|
309
|
+
side: "right",
|
|
310
|
+
align: "start",
|
|
311
|
+
sideOffset: 8,
|
|
312
|
+
className: "max-h-[70vh] w-40 overflow-auto p-1",
|
|
313
|
+
initialFocus: false,
|
|
314
|
+
onMouseEnter: openNow,
|
|
315
|
+
onMouseLeave: closeLater,
|
|
316
|
+
onClick: (event) => {
|
|
317
|
+
if (event.target.closest("[data-slot=menu-item]")) {
|
|
318
|
+
setOpen(false);
|
|
319
|
+
}
|
|
320
|
+
},
|
|
321
|
+
children: [
|
|
322
|
+
/* @__PURE__ */ (0, import_jsx_runtime3.jsx)("div", { className: "px-3 pt-2 pb-1 text-xs font-semibold text-muted-foreground", children: menu.title }),
|
|
323
|
+
/* @__PURE__ */ (0, import_jsx_runtime3.jsx)(
|
|
324
|
+
MenuTree,
|
|
325
|
+
{
|
|
326
|
+
menus: menu.children ?? [],
|
|
327
|
+
registry,
|
|
328
|
+
bridge,
|
|
329
|
+
activeMenuId,
|
|
330
|
+
defaultOpenKeys
|
|
331
|
+
}
|
|
332
|
+
)
|
|
333
|
+
]
|
|
334
|
+
}
|
|
335
|
+
)
|
|
336
|
+
] });
|
|
337
|
+
}
|
|
338
|
+
function MenuTree({
|
|
339
|
+
menus,
|
|
340
|
+
registry,
|
|
341
|
+
bridge,
|
|
342
|
+
activeMenuId,
|
|
343
|
+
defaultOpenKeys,
|
|
344
|
+
collapsed = false
|
|
345
|
+
}) {
|
|
346
|
+
if (collapsed) {
|
|
347
|
+
return /* @__PURE__ */ (0, import_jsx_runtime3.jsx)("div", { "data-slot": "menu", "data-collapsed": "true", className: "flex flex-col gap-1", children: menus.map((menu) => {
|
|
348
|
+
if (menu.type === "group") {
|
|
349
|
+
return /* @__PURE__ */ (0, import_jsx_runtime3.jsx)(
|
|
350
|
+
CollapsedGroupFlyout,
|
|
351
|
+
{
|
|
352
|
+
menu,
|
|
353
|
+
registry,
|
|
354
|
+
bridge,
|
|
355
|
+
activeMenuId,
|
|
356
|
+
defaultOpenKeys
|
|
357
|
+
},
|
|
358
|
+
menu.id
|
|
359
|
+
);
|
|
360
|
+
}
|
|
361
|
+
return /* @__PURE__ */ (0, import_jsx_runtime3.jsx)(
|
|
362
|
+
"button",
|
|
363
|
+
{
|
|
364
|
+
type: "button",
|
|
365
|
+
"data-slot": "menu-item",
|
|
366
|
+
"data-active": menu.id === activeMenuId || void 0,
|
|
367
|
+
className: cn(
|
|
368
|
+
menuItemClass,
|
|
369
|
+
"mx-auto size-10 justify-center px-0 font-semibold",
|
|
370
|
+
menu.id === activeMenuId && "bg-accent font-semibold text-accent-foreground"
|
|
371
|
+
),
|
|
372
|
+
disabled: menu.disabled,
|
|
373
|
+
title: menu.title,
|
|
374
|
+
onClick: () => navigateMenuItem(registry.findById(menu.id), bridge),
|
|
375
|
+
children: menu.title.slice(0, 1)
|
|
376
|
+
},
|
|
377
|
+
menu.id
|
|
378
|
+
);
|
|
379
|
+
}) });
|
|
380
|
+
}
|
|
381
|
+
return /* @__PURE__ */ (0, import_jsx_runtime3.jsx)(
|
|
382
|
+
Accordion,
|
|
383
|
+
{
|
|
384
|
+
type: "multiple",
|
|
385
|
+
defaultValue: defaultOpenKeys,
|
|
386
|
+
"data-slot": "menu",
|
|
387
|
+
className: "flex flex-col gap-0.5 px-2",
|
|
388
|
+
children: menus.map((menu) => {
|
|
389
|
+
if (menu.type === "group") {
|
|
390
|
+
return /* @__PURE__ */ (0, import_jsx_runtime3.jsxs)(
|
|
391
|
+
AccordionItem,
|
|
392
|
+
{
|
|
393
|
+
value: menu.id,
|
|
394
|
+
"data-slot": "menu-group",
|
|
395
|
+
className: "border-b-0",
|
|
396
|
+
children: [
|
|
397
|
+
/* @__PURE__ */ (0, import_jsx_runtime3.jsx)(
|
|
398
|
+
AccordionTrigger,
|
|
399
|
+
{
|
|
400
|
+
"data-slot": "menu-group-trigger",
|
|
401
|
+
className: cn(menuItemClass, "py-2 font-medium"),
|
|
402
|
+
disabled: menu.disabled,
|
|
403
|
+
title: menu.title,
|
|
404
|
+
children: menu.title
|
|
405
|
+
}
|
|
406
|
+
),
|
|
407
|
+
/* @__PURE__ */ (0, import_jsx_runtime3.jsx)(AccordionContent, { "data-slot": "menu-group-content", className: "pb-1", children: /* @__PURE__ */ (0, import_jsx_runtime3.jsx)("div", { className: "flex flex-col gap-0.5 pl-3", children: /* @__PURE__ */ (0, import_jsx_runtime3.jsx)(
|
|
408
|
+
MenuTree,
|
|
409
|
+
{
|
|
410
|
+
menus: menu.children ?? [],
|
|
411
|
+
registry,
|
|
412
|
+
bridge,
|
|
413
|
+
activeMenuId,
|
|
414
|
+
defaultOpenKeys
|
|
415
|
+
}
|
|
416
|
+
) }) })
|
|
417
|
+
]
|
|
418
|
+
},
|
|
419
|
+
menu.id
|
|
420
|
+
);
|
|
421
|
+
}
|
|
422
|
+
return /* @__PURE__ */ (0, import_jsx_runtime3.jsx)(
|
|
423
|
+
"button",
|
|
424
|
+
{
|
|
425
|
+
type: "button",
|
|
426
|
+
"data-slot": "menu-item",
|
|
427
|
+
"data-active": menu.id === activeMenuId || void 0,
|
|
428
|
+
className: cn(
|
|
429
|
+
menuItemClass,
|
|
430
|
+
menu.id === activeMenuId && "bg-accent font-semibold text-accent-foreground"
|
|
431
|
+
),
|
|
432
|
+
disabled: menu.disabled,
|
|
433
|
+
title: menu.title,
|
|
434
|
+
onClick: () => navigateMenuItem(registry.findById(menu.id), bridge),
|
|
435
|
+
children: menu.title
|
|
436
|
+
},
|
|
437
|
+
menu.id
|
|
438
|
+
);
|
|
439
|
+
})
|
|
440
|
+
}
|
|
441
|
+
);
|
|
442
|
+
}
|
|
443
|
+
function ShadcnAdminLayout({
|
|
444
|
+
config = {},
|
|
445
|
+
brand,
|
|
446
|
+
registry,
|
|
447
|
+
bridge,
|
|
448
|
+
route: routeProp,
|
|
449
|
+
permissionChecker,
|
|
450
|
+
headerExtra,
|
|
451
|
+
children
|
|
452
|
+
}) {
|
|
453
|
+
const { t } = (0, import_runtime.useI18n)();
|
|
454
|
+
const mode = config.mode ?? "top-side";
|
|
455
|
+
const showHeader = config.header ?? true;
|
|
456
|
+
const showSidebar = (config.sidebar ?? true) && mode !== "top-bottom";
|
|
457
|
+
const showTabs = config.tabs ?? false;
|
|
458
|
+
const showBreadcrumb = config.breadcrumb ?? false;
|
|
459
|
+
const showFooter = config.footer ?? false;
|
|
460
|
+
const [collapsed, setCollapsed] = (0, import_react2.useState)(config.collapsed ?? false);
|
|
461
|
+
const broken = useBreakpointBelow(config.breakpoint);
|
|
462
|
+
const effectiveCollapsed = collapsed || broken;
|
|
463
|
+
const [bridgeRoute, setBridgeRoute] = (0, import_react2.useState)(
|
|
464
|
+
() => (0, import_router.resolveRoute)(registry, bridge.getLocation())
|
|
465
|
+
);
|
|
466
|
+
const [tabs, setTabs] = (0, import_react2.useState)([]);
|
|
467
|
+
const tabsRef = (0, import_react2.useRef)(tabs);
|
|
468
|
+
tabsRef.current = tabs;
|
|
469
|
+
(0, import_react2.useEffect)(() => {
|
|
470
|
+
const handleLocation = (location) => {
|
|
471
|
+
const next = (0, import_router.resolveRoute)(registry, location);
|
|
472
|
+
setBridgeRoute(next);
|
|
473
|
+
if (next?.menuId !== void 0) {
|
|
474
|
+
const menu = registry.findById(next.menuId);
|
|
475
|
+
if (menu !== void 0 && menu.type === "page" && menu.path !== void 0) {
|
|
476
|
+
setTabs((prev) => {
|
|
477
|
+
if (prev.some((tab) => tab.key === location.pathname)) {
|
|
478
|
+
return prev;
|
|
479
|
+
}
|
|
480
|
+
return [...prev, { key: location.pathname, title: menu.title }];
|
|
481
|
+
});
|
|
482
|
+
}
|
|
483
|
+
}
|
|
484
|
+
};
|
|
485
|
+
handleLocation(bridge.getLocation());
|
|
486
|
+
return bridge.subscribe(handleLocation);
|
|
487
|
+
}, [registry, bridge]);
|
|
488
|
+
const route = routeProp ?? bridgeRoute;
|
|
489
|
+
const activeMenuId = route?.activeMenu;
|
|
490
|
+
const visibleMenus = (0, import_react2.useMemo)(
|
|
491
|
+
() => buildVisibleMenuTree(registry, permissionChecker),
|
|
492
|
+
[registry, permissionChecker]
|
|
493
|
+
);
|
|
494
|
+
const defaultOpenKeysRef = (0, import_react2.useRef)(null);
|
|
495
|
+
if (defaultOpenKeysRef.current === null) {
|
|
496
|
+
defaultOpenKeysRef.current = collectDefaultOpenKeys(registry, activeMenuId);
|
|
497
|
+
}
|
|
498
|
+
const defaultOpenKeys = defaultOpenKeysRef.current;
|
|
499
|
+
const activeTopId = (0, import_react2.useMemo)(() => {
|
|
500
|
+
if (activeMenuId !== void 0) {
|
|
501
|
+
const chain = findMenuChain(registry, activeMenuId);
|
|
502
|
+
if (chain.length > 0) {
|
|
503
|
+
return chain[0].id;
|
|
504
|
+
}
|
|
505
|
+
}
|
|
506
|
+
return void 0;
|
|
507
|
+
}, [registry, activeMenuId]);
|
|
508
|
+
const [selectedTopId, setSelectedTopId] = (0, import_react2.useState)();
|
|
509
|
+
const secondaryTopId = selectedTopId ?? activeTopId ?? visibleMenus.find((m) => m.type === "group")?.id ?? visibleMenus[0]?.id;
|
|
510
|
+
const secondaryTop = visibleMenus.find((m) => m.id === secondaryTopId);
|
|
511
|
+
const hasSecondary = (secondaryTop?.children?.length ?? 0) > 0;
|
|
512
|
+
const breadcrumbItems = (0, import_react2.useMemo)(() => {
|
|
513
|
+
if (!showBreadcrumb || activeMenuId === void 0) {
|
|
514
|
+
return [];
|
|
515
|
+
}
|
|
516
|
+
return findMenuChain(registry, activeMenuId).map((menu) => menu.title);
|
|
517
|
+
}, [showBreadcrumb, registry, activeMenuId]);
|
|
518
|
+
const currentPath = route?.path;
|
|
519
|
+
const closeTab = (targetKey) => {
|
|
520
|
+
const remaining = tabsRef.current.filter((tab) => tab.key !== targetKey);
|
|
521
|
+
setTabs(remaining);
|
|
522
|
+
if (targetKey === currentPath && remaining.length > 0) {
|
|
523
|
+
bridge.push(remaining[remaining.length - 1].key);
|
|
524
|
+
}
|
|
525
|
+
};
|
|
526
|
+
const fixedHeader = config.fixedHeader ?? true;
|
|
527
|
+
const fixedSider = config.fixedSider ?? true;
|
|
528
|
+
const header = showHeader ? /* @__PURE__ */ (0, import_jsx_runtime3.jsxs)(
|
|
529
|
+
"header",
|
|
530
|
+
{
|
|
531
|
+
"data-slot": "admin-header",
|
|
532
|
+
className: cn(
|
|
533
|
+
"flex h-14 items-center gap-4 border-b border-border bg-background px-6",
|
|
534
|
+
fixedHeader && "sticky top-0 z-20"
|
|
535
|
+
),
|
|
536
|
+
children: [
|
|
537
|
+
mode !== "side-full" && /* @__PURE__ */ (0, import_jsx_runtime3.jsxs)(import_jsx_runtime3.Fragment, { children: [
|
|
538
|
+
brand.logo,
|
|
539
|
+
/* @__PURE__ */ (0, import_jsx_runtime3.jsx)("span", { "data-slot": "admin-brand", className: "text-lg font-semibold", children: brand.title })
|
|
540
|
+
] }),
|
|
541
|
+
/* @__PURE__ */ (0, import_jsx_runtime3.jsx)("div", { className: "flex-1" }),
|
|
542
|
+
headerExtra
|
|
543
|
+
]
|
|
544
|
+
}
|
|
545
|
+
) : null;
|
|
546
|
+
const primaryColumn = /* @__PURE__ */ (0, import_jsx_runtime3.jsx)(
|
|
547
|
+
"div",
|
|
548
|
+
{
|
|
549
|
+
"data-slot": "admin-primary-col",
|
|
550
|
+
className: "flex w-12 shrink-0 flex-col items-center gap-1 border-r border-border py-2",
|
|
551
|
+
children: visibleMenus.map((menu) => /* @__PURE__ */ (0, import_jsx_runtime3.jsx)(
|
|
552
|
+
"button",
|
|
553
|
+
{
|
|
554
|
+
type: "button",
|
|
555
|
+
"data-slot": "admin-primary-item",
|
|
556
|
+
"data-active": menu.id === secondaryTopId || menu.id === activeTopId || void 0,
|
|
557
|
+
className: cn(
|
|
558
|
+
menuItemClass,
|
|
559
|
+
"size-10 justify-center px-0 font-semibold",
|
|
560
|
+
(menu.id === secondaryTopId || menu.id === activeTopId) && "bg-accent text-accent-foreground"
|
|
561
|
+
),
|
|
562
|
+
disabled: menu.disabled,
|
|
563
|
+
title: menu.title,
|
|
564
|
+
onClick: () => {
|
|
565
|
+
if (menu.type === "group") {
|
|
566
|
+
setSelectedTopId(menu.id);
|
|
567
|
+
} else {
|
|
568
|
+
navigateMenuItem(menu, bridge);
|
|
569
|
+
}
|
|
570
|
+
},
|
|
571
|
+
children: menu.title.slice(0, 1)
|
|
572
|
+
},
|
|
573
|
+
menu.id
|
|
574
|
+
))
|
|
575
|
+
}
|
|
576
|
+
);
|
|
577
|
+
const showTrigger = config.collapsible && mode !== "two-column";
|
|
578
|
+
const sidebar = showSidebar ? /* @__PURE__ */ (0, import_jsx_runtime3.jsxs)(
|
|
579
|
+
"aside",
|
|
580
|
+
{
|
|
581
|
+
"data-slot": "admin-sidebar",
|
|
582
|
+
"data-collapsed": effectiveCollapsed || void 0,
|
|
583
|
+
className: cn(
|
|
584
|
+
"shrink-0 overflow-auto border-r border-border bg-background py-2",
|
|
585
|
+
effectiveCollapsed ? "w-16 px-1.5" : "w-52",
|
|
586
|
+
fixedSider && (mode === "side-full" ? "sticky top-0 h-screen" : "sticky top-14 h-[calc(100vh-3.5rem)]")
|
|
587
|
+
),
|
|
588
|
+
style: mode === "two-column" && !hasSecondary ? { width: 56 } : void 0,
|
|
589
|
+
children: [
|
|
590
|
+
mode === "side-full" && /* @__PURE__ */ (0, import_jsx_runtime3.jsxs)(
|
|
591
|
+
"div",
|
|
592
|
+
{
|
|
593
|
+
"data-slot": "admin-sidebar-brand",
|
|
594
|
+
className: "flex items-center gap-2 border-b border-border px-4 py-4 font-semibold",
|
|
595
|
+
children: [
|
|
596
|
+
brand.logo,
|
|
597
|
+
/* @__PURE__ */ (0, import_jsx_runtime3.jsx)("span", { children: brand.title })
|
|
598
|
+
]
|
|
599
|
+
}
|
|
600
|
+
),
|
|
601
|
+
mode === "two-column" ? /* @__PURE__ */ (0, import_jsx_runtime3.jsxs)("div", { "data-slot": "admin-two-col", className: "flex h-full", children: [
|
|
602
|
+
primaryColumn,
|
|
603
|
+
hasSecondary && /* @__PURE__ */ (0, import_jsx_runtime3.jsx)("div", { "data-slot": "admin-secondary-col", className: "min-w-0 flex-1", children: /* @__PURE__ */ (0, import_jsx_runtime3.jsx)(
|
|
604
|
+
MenuTree,
|
|
605
|
+
{
|
|
606
|
+
menus: secondaryTop?.children ?? [],
|
|
607
|
+
registry,
|
|
608
|
+
bridge,
|
|
609
|
+
activeMenuId,
|
|
610
|
+
defaultOpenKeys
|
|
611
|
+
}
|
|
612
|
+
) })
|
|
613
|
+
] }) : /* @__PURE__ */ (0, import_jsx_runtime3.jsx)(
|
|
614
|
+
MenuTree,
|
|
615
|
+
{
|
|
616
|
+
menus: visibleMenus,
|
|
617
|
+
registry,
|
|
618
|
+
bridge,
|
|
619
|
+
activeMenuId,
|
|
620
|
+
defaultOpenKeys,
|
|
621
|
+
collapsed: effectiveCollapsed
|
|
622
|
+
}
|
|
623
|
+
),
|
|
624
|
+
showTrigger && /* @__PURE__ */ (0, import_jsx_runtime3.jsx)(
|
|
625
|
+
"button",
|
|
626
|
+
{
|
|
627
|
+
type: "button",
|
|
628
|
+
"data-slot": "admin-collapse-trigger",
|
|
629
|
+
"aria-label": effectiveCollapsed ? t("pactor.layout.expandSidebar") : t("pactor.layout.collapseSidebar"),
|
|
630
|
+
"aria-expanded": !effectiveCollapsed,
|
|
631
|
+
className: "sticky bottom-0 flex w-full cursor-pointer items-center justify-center border-t border-border bg-background py-2 text-muted-foreground transition-colors hover:bg-accent hover:text-foreground",
|
|
632
|
+
onClick: () => setCollapsed((value) => !value),
|
|
633
|
+
children: effectiveCollapsed ? "\xBB" : "\xAB"
|
|
634
|
+
}
|
|
635
|
+
)
|
|
636
|
+
]
|
|
637
|
+
}
|
|
638
|
+
) : null;
|
|
639
|
+
const body = /* @__PURE__ */ (0, import_jsx_runtime3.jsxs)("div", { "data-slot": "admin-body", className: "flex min-w-0 flex-1 flex-col", children: [
|
|
640
|
+
showTabs && /* @__PURE__ */ (0, import_jsx_runtime3.jsx)(
|
|
641
|
+
"div",
|
|
642
|
+
{
|
|
643
|
+
"data-slot": "admin-tabs",
|
|
644
|
+
role: "tablist",
|
|
645
|
+
className: "flex items-center gap-1 border-b border-border bg-background px-4 pt-2",
|
|
646
|
+
children: tabs.map((tab, index) => /* @__PURE__ */ (0, import_jsx_runtime3.jsxs)(
|
|
647
|
+
"div",
|
|
648
|
+
{
|
|
649
|
+
"data-slot": "admin-tab",
|
|
650
|
+
"data-active": tab.key === currentPath || void 0,
|
|
651
|
+
role: "presentation",
|
|
652
|
+
className: cn(
|
|
653
|
+
"inline-flex items-center gap-1 rounded-t-md border border-b-0 border-border px-3 py-1.5 text-sm",
|
|
654
|
+
tab.key === currentPath ? "bg-background font-medium text-foreground" : "bg-muted text-muted-foreground"
|
|
655
|
+
),
|
|
656
|
+
children: [
|
|
657
|
+
/* @__PURE__ */ (0, import_jsx_runtime3.jsx)(
|
|
658
|
+
"button",
|
|
659
|
+
{
|
|
660
|
+
type: "button",
|
|
661
|
+
role: "tab",
|
|
662
|
+
"aria-selected": tab.key === currentPath,
|
|
663
|
+
className: "cursor-pointer",
|
|
664
|
+
onClick: () => bridge.push(tab.key),
|
|
665
|
+
children: tab.title
|
|
666
|
+
}
|
|
667
|
+
),
|
|
668
|
+
index > 0 && /* @__PURE__ */ (0, import_jsx_runtime3.jsx)(
|
|
669
|
+
"button",
|
|
670
|
+
{
|
|
671
|
+
type: "button",
|
|
672
|
+
"data-slot": "admin-tab-close",
|
|
673
|
+
"aria-label": t("pactor.layout.closeTab", { title: tab.title }),
|
|
674
|
+
className: "cursor-pointer text-muted-foreground hover:text-foreground",
|
|
675
|
+
onClick: () => closeTab(tab.key),
|
|
676
|
+
children: "\xD7"
|
|
677
|
+
}
|
|
678
|
+
)
|
|
679
|
+
]
|
|
680
|
+
},
|
|
681
|
+
tab.key
|
|
682
|
+
))
|
|
683
|
+
}
|
|
684
|
+
),
|
|
685
|
+
/* @__PURE__ */ (0, import_jsx_runtime3.jsxs)(
|
|
686
|
+
"main",
|
|
687
|
+
{
|
|
688
|
+
"data-slot": "admin-content",
|
|
689
|
+
className: "flex-1 bg-muted/40 p-6",
|
|
690
|
+
children: [
|
|
691
|
+
showBreadcrumb && breadcrumbItems.length > 0 && /* @__PURE__ */ (0, import_jsx_runtime3.jsx)(
|
|
692
|
+
"nav",
|
|
693
|
+
{
|
|
694
|
+
"data-slot": "admin-breadcrumb",
|
|
695
|
+
"aria-label": t("pactor.layout.breadcrumb"),
|
|
696
|
+
className: "mb-4",
|
|
697
|
+
children: /* @__PURE__ */ (0, import_jsx_runtime3.jsx)("ol", { className: "flex items-center gap-2 text-sm text-muted-foreground", children: breadcrumbItems.map((title, index) => /* @__PURE__ */ (0, import_jsx_runtime3.jsxs)("li", { className: "flex items-center gap-2", children: [
|
|
698
|
+
index > 0 && /* @__PURE__ */ (0, import_jsx_runtime3.jsx)("span", { "aria-hidden": true, children: "/" }),
|
|
699
|
+
/* @__PURE__ */ (0, import_jsx_runtime3.jsx)("span", { "data-slot": "breadcrumb-link", children: title })
|
|
700
|
+
] }, index)) })
|
|
701
|
+
}
|
|
702
|
+
),
|
|
703
|
+
children
|
|
704
|
+
]
|
|
705
|
+
}
|
|
706
|
+
)
|
|
707
|
+
] });
|
|
708
|
+
const footer = showFooter ? /* @__PURE__ */ (0, import_jsx_runtime3.jsx)(
|
|
709
|
+
"footer",
|
|
710
|
+
{
|
|
711
|
+
"data-slot": "admin-footer",
|
|
712
|
+
className: "bg-muted p-4 text-center text-sm text-muted-foreground",
|
|
713
|
+
children: brand.title
|
|
714
|
+
}
|
|
715
|
+
) : null;
|
|
716
|
+
return /* @__PURE__ */ (0, import_jsx_runtime3.jsx)(
|
|
717
|
+
"div",
|
|
718
|
+
{
|
|
719
|
+
"data-slot": "admin-layout",
|
|
720
|
+
"data-mode": mode,
|
|
721
|
+
"data-fixed-header": fixedHeader || void 0,
|
|
722
|
+
"data-fixed-sider": fixedSider || void 0,
|
|
723
|
+
className: "flex min-h-screen flex-col bg-background text-foreground",
|
|
724
|
+
children: mode === "side-full" ? /* @__PURE__ */ (0, import_jsx_runtime3.jsxs)("div", { "data-slot": "admin-side-full", className: "flex min-h-screen flex-1", children: [
|
|
725
|
+
sidebar,
|
|
726
|
+
/* @__PURE__ */ (0, import_jsx_runtime3.jsxs)(
|
|
727
|
+
"div",
|
|
728
|
+
{
|
|
729
|
+
"data-slot": "admin-side-full-main",
|
|
730
|
+
className: "flex min-w-0 flex-1 flex-col",
|
|
731
|
+
children: [
|
|
732
|
+
header,
|
|
733
|
+
body,
|
|
734
|
+
footer
|
|
735
|
+
]
|
|
736
|
+
}
|
|
737
|
+
)
|
|
738
|
+
] }) : /* @__PURE__ */ (0, import_jsx_runtime3.jsxs)(import_jsx_runtime3.Fragment, { children: [
|
|
739
|
+
header,
|
|
740
|
+
/* @__PURE__ */ (0, import_jsx_runtime3.jsxs)("div", { "data-slot": "admin-main", className: "flex min-h-0 flex-1", children: [
|
|
741
|
+
sidebar,
|
|
742
|
+
body
|
|
743
|
+
] }),
|
|
744
|
+
footer
|
|
745
|
+
] })
|
|
746
|
+
}
|
|
747
|
+
);
|
|
748
|
+
}
|
|
749
|
+
|
|
750
|
+
// src/layout/basic/ShadcnBlankLayout.tsx
|
|
751
|
+
var import_jsx_runtime4 = require("react/jsx-runtime");
|
|
752
|
+
function ShadcnBlankLayout({ children }) {
|
|
753
|
+
return /* @__PURE__ */ (0, import_jsx_runtime4.jsx)(
|
|
754
|
+
"div",
|
|
755
|
+
{
|
|
756
|
+
"data-slot": "blank-layout",
|
|
757
|
+
className: "min-h-screen bg-background text-foreground",
|
|
758
|
+
children
|
|
759
|
+
}
|
|
760
|
+
);
|
|
761
|
+
}
|
|
762
|
+
|
|
763
|
+
// src/ui/card.tsx
|
|
764
|
+
var import_jsx_runtime5 = require("react/jsx-runtime");
|
|
765
|
+
function Card({ className, ...props }) {
|
|
766
|
+
return /* @__PURE__ */ (0, import_jsx_runtime5.jsx)(
|
|
767
|
+
"div",
|
|
768
|
+
{
|
|
769
|
+
"data-slot": "card",
|
|
770
|
+
className: cn(
|
|
771
|
+
"flex flex-col gap-6 rounded-xl border border-border bg-card py-6 text-card-foreground shadow-sm",
|
|
772
|
+
className
|
|
773
|
+
),
|
|
774
|
+
...props
|
|
775
|
+
}
|
|
776
|
+
);
|
|
777
|
+
}
|
|
778
|
+
function CardHeader({ className, ...props }) {
|
|
779
|
+
return /* @__PURE__ */ (0, import_jsx_runtime5.jsx)(
|
|
780
|
+
"div",
|
|
781
|
+
{
|
|
782
|
+
"data-slot": "card-header",
|
|
783
|
+
className: cn(
|
|
784
|
+
"grid auto-rows-min grid-rows-[auto_auto] items-start gap-1.5 px-6 has-data-[slot=card-action]:grid-cols-[1fr_auto] [.border-b]:pb-6",
|
|
785
|
+
className
|
|
786
|
+
),
|
|
787
|
+
...props
|
|
788
|
+
}
|
|
789
|
+
);
|
|
790
|
+
}
|
|
791
|
+
function CardTitle({ className, ...props }) {
|
|
792
|
+
return /* @__PURE__ */ (0, import_jsx_runtime5.jsx)(
|
|
793
|
+
"div",
|
|
794
|
+
{
|
|
795
|
+
"data-slot": "card-title",
|
|
796
|
+
className: cn("leading-none font-semibold", className),
|
|
797
|
+
...props
|
|
798
|
+
}
|
|
799
|
+
);
|
|
800
|
+
}
|
|
801
|
+
function CardContent({ className, ...props }) {
|
|
802
|
+
return /* @__PURE__ */ (0, import_jsx_runtime5.jsx)(
|
|
803
|
+
"div",
|
|
804
|
+
{
|
|
805
|
+
"data-slot": "card-content",
|
|
806
|
+
className: cn("px-6", className),
|
|
807
|
+
...props
|
|
808
|
+
}
|
|
809
|
+
);
|
|
810
|
+
}
|
|
811
|
+
|
|
812
|
+
// src/layout/basic/ShadcnLoginLayout.tsx
|
|
813
|
+
var import_jsx_runtime6 = require("react/jsx-runtime");
|
|
814
|
+
function ShadcnLoginLayout({
|
|
815
|
+
variant = "center",
|
|
816
|
+
brand,
|
|
817
|
+
children
|
|
818
|
+
}) {
|
|
819
|
+
const brandBlock = /* @__PURE__ */ (0, import_jsx_runtime6.jsxs)("div", { "data-slot": "login-brand", className: "flex flex-col items-center gap-2", children: [
|
|
820
|
+
brand.logo,
|
|
821
|
+
/* @__PURE__ */ (0, import_jsx_runtime6.jsx)("h1", { className: "text-xl font-semibold", children: brand.title }),
|
|
822
|
+
brand.description !== void 0 && /* @__PURE__ */ (0, import_jsx_runtime6.jsx)("div", { className: "text-sm text-muted-foreground", children: brand.description })
|
|
823
|
+
] });
|
|
824
|
+
if (variant === "split") {
|
|
825
|
+
return /* @__PURE__ */ (0, import_jsx_runtime6.jsxs)(
|
|
826
|
+
"div",
|
|
827
|
+
{
|
|
828
|
+
"data-slot": "login-layout",
|
|
829
|
+
"data-variant": "split",
|
|
830
|
+
className: "grid min-h-screen grid-cols-2 bg-background text-foreground",
|
|
831
|
+
children: [
|
|
832
|
+
/* @__PURE__ */ (0, import_jsx_runtime6.jsx)(
|
|
833
|
+
"div",
|
|
834
|
+
{
|
|
835
|
+
"data-slot": "login-brand-panel",
|
|
836
|
+
className: "flex items-center justify-center bg-muted/40 p-10",
|
|
837
|
+
children: brandBlock
|
|
838
|
+
}
|
|
839
|
+
),
|
|
840
|
+
/* @__PURE__ */ (0, import_jsx_runtime6.jsx)(
|
|
841
|
+
"div",
|
|
842
|
+
{
|
|
843
|
+
"data-slot": "login-form-panel",
|
|
844
|
+
className: "flex items-center justify-center p-10",
|
|
845
|
+
children
|
|
846
|
+
}
|
|
847
|
+
)
|
|
848
|
+
]
|
|
849
|
+
}
|
|
850
|
+
);
|
|
851
|
+
}
|
|
852
|
+
return /* @__PURE__ */ (0, import_jsx_runtime6.jsx)(
|
|
853
|
+
"div",
|
|
854
|
+
{
|
|
855
|
+
"data-slot": "login-layout",
|
|
856
|
+
"data-variant": "center",
|
|
857
|
+
className: "flex min-h-screen items-center justify-center bg-muted/40 text-foreground",
|
|
858
|
+
children: /* @__PURE__ */ (0, import_jsx_runtime6.jsxs)(Card, { "data-slot": "login-card", className: "w-full max-w-sm gap-4 py-6", children: [
|
|
859
|
+
/* @__PURE__ */ (0, import_jsx_runtime6.jsxs)(CardHeader, { className: "px-6", children: [
|
|
860
|
+
/* @__PURE__ */ (0, import_jsx_runtime6.jsx)(CardTitle, { className: "sr-only", children: brand.title }),
|
|
861
|
+
brandBlock
|
|
862
|
+
] }),
|
|
863
|
+
/* @__PURE__ */ (0, import_jsx_runtime6.jsx)(CardContent, { className: "flex flex-col gap-4 px-6", children })
|
|
864
|
+
] })
|
|
865
|
+
}
|
|
866
|
+
);
|
|
867
|
+
}
|
|
868
|
+
|
|
869
|
+
// src/layout/basic/ShadcnLandingLayout.tsx
|
|
870
|
+
var import_jsx_runtime7 = require("react/jsx-runtime");
|
|
871
|
+
function ShadcnLandingLayout({
|
|
872
|
+
navbar,
|
|
873
|
+
footer,
|
|
874
|
+
children
|
|
875
|
+
}) {
|
|
876
|
+
return /* @__PURE__ */ (0, import_jsx_runtime7.jsxs)(
|
|
877
|
+
"div",
|
|
878
|
+
{
|
|
879
|
+
"data-slot": "landing-layout",
|
|
880
|
+
className: "flex min-h-screen flex-col bg-background text-foreground",
|
|
881
|
+
children: [
|
|
882
|
+
navbar !== void 0 && /* @__PURE__ */ (0, import_jsx_runtime7.jsx)(
|
|
883
|
+
"header",
|
|
884
|
+
{
|
|
885
|
+
"data-slot": "landing-navbar",
|
|
886
|
+
className: "border-b border-border bg-background",
|
|
887
|
+
children: navbar
|
|
888
|
+
}
|
|
889
|
+
),
|
|
890
|
+
/* @__PURE__ */ (0, import_jsx_runtime7.jsx)("main", { "data-slot": "landing-content", className: "flex-1", children }),
|
|
891
|
+
footer !== void 0 && /* @__PURE__ */ (0, import_jsx_runtime7.jsx)(
|
|
892
|
+
"footer",
|
|
893
|
+
{
|
|
894
|
+
"data-slot": "landing-footer",
|
|
895
|
+
className: "border-t border-border text-sm text-muted-foreground",
|
|
896
|
+
children: footer
|
|
897
|
+
}
|
|
898
|
+
)
|
|
899
|
+
]
|
|
900
|
+
}
|
|
901
|
+
);
|
|
902
|
+
}
|
|
903
|
+
|
|
904
|
+
// src/layout/registry.ts
|
|
905
|
+
var import_core = require("@pactor-app/core");
|
|
906
|
+
function registerShadcnLayouts(registry) {
|
|
907
|
+
registry.register("admin", ShadcnAdminLayout);
|
|
908
|
+
registry.register("blank", ShadcnBlankLayout);
|
|
909
|
+
registry.register("login", ShadcnLoginLayout);
|
|
910
|
+
registry.register("landing", ShadcnLandingLayout);
|
|
911
|
+
}
|
|
912
|
+
function createShadcnLayoutRegistry() {
|
|
913
|
+
const registry = new import_core.Registry("LayoutRegistry");
|
|
914
|
+
registerShadcnLayouts(registry);
|
|
915
|
+
return registry;
|
|
916
|
+
}
|
|
917
|
+
function resolveLayout(registry, type) {
|
|
918
|
+
const component = registry.get(type);
|
|
919
|
+
if (component === void 0) {
|
|
920
|
+
console.warn(
|
|
921
|
+
`[pactor-layout] unknown layout type "${type}", fallback to BlankLayout`
|
|
922
|
+
);
|
|
923
|
+
return ShadcnBlankLayout;
|
|
924
|
+
}
|
|
925
|
+
return component;
|
|
926
|
+
}
|
|
927
|
+
// Annotate the CommonJS export names for ESM import in node:
|
|
928
|
+
0 && (module.exports = {
|
|
929
|
+
ShadcnAdminLayout,
|
|
930
|
+
ShadcnBlankLayout,
|
|
931
|
+
ShadcnLandingLayout,
|
|
932
|
+
ShadcnLoginLayout,
|
|
933
|
+
collectDefaultOpenKeys,
|
|
934
|
+
createShadcnLayoutRegistry,
|
|
935
|
+
findMenuChain,
|
|
936
|
+
registerShadcnLayouts,
|
|
937
|
+
resolveLayout
|
|
938
|
+
});
|