@petrarca/sonnet-shell 0.1.6 → 0.3.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/index.d.ts +183 -32
- package/dist/index.js +523 -211
- package/dist/index.js.map +1 -1
- package/package.json +3 -3
package/dist/index.js
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
// src/AppShell.tsx
|
|
2
2
|
import {
|
|
3
|
-
useState,
|
|
3
|
+
useState as useState2,
|
|
4
4
|
useEffect as useEffect3,
|
|
5
5
|
useCallback as useCallback2,
|
|
6
6
|
useRef as useRef2,
|
|
@@ -68,58 +68,40 @@ function TopBar({ children }) {
|
|
|
68
68
|
return /* @__PURE__ */ jsx2("header", { className: "h-12 shrink-0 border-b border-border flex items-center justify-between px-3 bg-background z-20", children });
|
|
69
69
|
}
|
|
70
70
|
|
|
71
|
-
// src/
|
|
72
|
-
import {
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
import { Tooltip, TooltipContent, TooltipTrigger } from "@petrarca/sonnet-ui";
|
|
76
|
-
|
|
77
|
-
// src/shellModules.ts
|
|
78
|
-
import { createContext, useContext } from "react";
|
|
79
|
-
var ShellModulesContext = createContext(null);
|
|
80
|
-
function useShellModules() {
|
|
81
|
-
const registry = useContext(ShellModulesContext);
|
|
82
|
-
if (!registry) {
|
|
83
|
-
throw new Error("useShellModules must be used within an AppShell");
|
|
84
|
-
}
|
|
85
|
-
return registry;
|
|
71
|
+
// src/ShellFooter.tsx
|
|
72
|
+
import { jsx as jsx3 } from "react/jsx-runtime";
|
|
73
|
+
function ShellFooter({ children }) {
|
|
74
|
+
return /* @__PURE__ */ jsx3("footer", { className: "h-8 shrink-0 border-t border-border flex items-center justify-between px-3 bg-background text-[11px] text-muted-foreground z-20", children });
|
|
86
75
|
}
|
|
87
76
|
|
|
88
77
|
// src/IconRail.tsx
|
|
89
|
-
import {
|
|
78
|
+
import { cn } from "@petrarca/sonnet-core";
|
|
79
|
+
import { Button as Button2, Separator } from "@petrarca/sonnet-ui";
|
|
80
|
+
import { Tooltip, TooltipContent, TooltipTrigger } from "@petrarca/sonnet-ui";
|
|
81
|
+
import { jsx as jsx4, jsxs as jsxs2 } from "react/jsx-runtime";
|
|
90
82
|
function IconRail({
|
|
91
|
-
|
|
92
|
-
|
|
93
|
-
onServiceSelect
|
|
83
|
+
children,
|
|
84
|
+
className
|
|
94
85
|
}) {
|
|
95
|
-
|
|
96
|
-
|
|
97
|
-
|
|
98
|
-
|
|
99
|
-
|
|
100
|
-
|
|
101
|
-
|
|
102
|
-
|
|
103
|
-
|
|
104
|
-
|
|
105
|
-
service.id
|
|
106
|
-
)) }),
|
|
107
|
-
/* @__PURE__ */ jsx3(Separator, { className: "w-6 my-1" }),
|
|
108
|
-
/* @__PURE__ */ jsx3("div", { className: "flex flex-col items-center gap-1", children: bottomModules.map((service) => /* @__PURE__ */ jsx3(
|
|
109
|
-
RailIcon,
|
|
110
|
-
{
|
|
111
|
-
service,
|
|
112
|
-
isActive: isActive(service.id),
|
|
113
|
-
onClick: () => onServiceSelect(service.id)
|
|
114
|
-
},
|
|
115
|
-
service.id
|
|
116
|
-
)) })
|
|
117
|
-
] });
|
|
86
|
+
return /* @__PURE__ */ jsx4(
|
|
87
|
+
"nav",
|
|
88
|
+
{
|
|
89
|
+
className: cn(
|
|
90
|
+
"w-14 shrink-0 border-r bg-muted flex flex-col items-center py-2 gap-1",
|
|
91
|
+
className
|
|
92
|
+
),
|
|
93
|
+
children
|
|
94
|
+
}
|
|
95
|
+
);
|
|
118
96
|
}
|
|
119
|
-
function RailIcon({
|
|
120
|
-
|
|
97
|
+
function RailIcon({
|
|
98
|
+
icon: Icon,
|
|
99
|
+
label,
|
|
100
|
+
active = false,
|
|
101
|
+
onClick
|
|
102
|
+
}) {
|
|
121
103
|
return /* @__PURE__ */ jsxs2(Tooltip, { delayDuration: 0, children: [
|
|
122
|
-
/* @__PURE__ */
|
|
104
|
+
/* @__PURE__ */ jsx4(TooltipTrigger, { asChild: true, children: /* @__PURE__ */ jsxs2(
|
|
123
105
|
Button2,
|
|
124
106
|
{
|
|
125
107
|
variant: "ghost",
|
|
@@ -127,23 +109,24 @@ function RailIcon({ service, isActive, onClick }) {
|
|
|
127
109
|
onClick,
|
|
128
110
|
className: cn(
|
|
129
111
|
"h-10 w-10 rounded-lg transition-colors",
|
|
130
|
-
|
|
112
|
+
active ? "bg-background text-foreground shadow-sm" : "text-muted-foreground hover:text-foreground hover:bg-muted-foreground/10"
|
|
131
113
|
),
|
|
132
114
|
children: [
|
|
133
|
-
/* @__PURE__ */
|
|
134
|
-
/* @__PURE__ */
|
|
115
|
+
/* @__PURE__ */ jsx4(Icon, { className: "h-5 w-5" }),
|
|
116
|
+
/* @__PURE__ */ jsx4("span", { className: "sr-only", children: label })
|
|
135
117
|
]
|
|
136
118
|
}
|
|
137
119
|
) }),
|
|
138
|
-
/* @__PURE__ */
|
|
120
|
+
/* @__PURE__ */ jsx4(TooltipContent, { side: "right", sideOffset: 8, children: label })
|
|
139
121
|
] });
|
|
140
122
|
}
|
|
123
|
+
function RailSeparator() {
|
|
124
|
+
return /* @__PURE__ */ jsx4(Separator, { className: "w-6 my-1" });
|
|
125
|
+
}
|
|
141
126
|
|
|
142
127
|
// src/SubNavPanel.tsx
|
|
143
128
|
import { useMemo as useMemo2 } from "react";
|
|
144
|
-
import { useLocation, Link } from "react-router-dom";
|
|
145
129
|
import { ChevronsLeft, ChevronsRight } from "lucide-react";
|
|
146
|
-
import { cn as cn2 } from "@petrarca/sonnet-core";
|
|
147
130
|
import { ScrollArea } from "@petrarca/sonnet-ui";
|
|
148
131
|
import { Tooltip as Tooltip2, TooltipContent as TooltipContent2, TooltipTrigger as TooltipTrigger2 } from "@petrarca/sonnet-ui";
|
|
149
132
|
|
|
@@ -413,6 +396,17 @@ var events = {
|
|
|
413
396
|
}
|
|
414
397
|
};
|
|
415
398
|
|
|
399
|
+
// src/shellModules.ts
|
|
400
|
+
import { createContext, useContext } from "react";
|
|
401
|
+
var ShellModulesContext = createContext(null);
|
|
402
|
+
function useShellModules() {
|
|
403
|
+
const registry = useContext(ShellModulesContext);
|
|
404
|
+
if (!registry) {
|
|
405
|
+
throw new Error("useShellModules must be used within an AppShell");
|
|
406
|
+
}
|
|
407
|
+
return registry;
|
|
408
|
+
}
|
|
409
|
+
|
|
416
410
|
// src/hooks.ts
|
|
417
411
|
function useExtensionPoint(name) {
|
|
418
412
|
const { getExtensionPoint } = useShellModules();
|
|
@@ -430,8 +424,145 @@ function useShellEvent(key, handler) {
|
|
|
430
424
|
}, [key]);
|
|
431
425
|
}
|
|
432
426
|
|
|
427
|
+
// src/SidebarGroup.tsx
|
|
428
|
+
import { useState } from "react";
|
|
429
|
+
import { ChevronDown } from "lucide-react";
|
|
430
|
+
import { cn as cn2 } from "@petrarca/sonnet-core";
|
|
431
|
+
import { jsx as jsx5, jsxs as jsxs3 } from "react/jsx-runtime";
|
|
432
|
+
function GroupHeading({
|
|
433
|
+
heading,
|
|
434
|
+
canCollapse,
|
|
435
|
+
open,
|
|
436
|
+
onToggle
|
|
437
|
+
}) {
|
|
438
|
+
return /* @__PURE__ */ jsxs3(
|
|
439
|
+
"button",
|
|
440
|
+
{
|
|
441
|
+
type: "button",
|
|
442
|
+
onClick: canCollapse ? onToggle : void 0,
|
|
443
|
+
className: cn2(
|
|
444
|
+
"flex w-full items-center gap-1 px-2 py-1.5",
|
|
445
|
+
"text-[11px] font-semibold uppercase tracking-widest text-muted-foreground/70",
|
|
446
|
+
canCollapse ? "hover:text-foreground cursor-pointer" : "cursor-default"
|
|
447
|
+
),
|
|
448
|
+
children: [
|
|
449
|
+
canCollapse && /* @__PURE__ */ jsx5(
|
|
450
|
+
ChevronDown,
|
|
451
|
+
{
|
|
452
|
+
className: cn2("h-3 w-3 transition-transform", !open && "-rotate-90")
|
|
453
|
+
}
|
|
454
|
+
),
|
|
455
|
+
/* @__PURE__ */ jsx5("span", { children: heading })
|
|
456
|
+
]
|
|
457
|
+
}
|
|
458
|
+
);
|
|
459
|
+
}
|
|
460
|
+
function SidebarGroup({
|
|
461
|
+
heading,
|
|
462
|
+
collapsible = false,
|
|
463
|
+
defaultOpen = true,
|
|
464
|
+
separator = false,
|
|
465
|
+
children
|
|
466
|
+
}) {
|
|
467
|
+
const [open, setOpen] = useState(defaultOpen);
|
|
468
|
+
const canCollapse = collapsible && !!heading;
|
|
469
|
+
return /* @__PURE__ */ jsxs3("div", { className: cn2(separator && "border-b border-border pb-2"), children: [
|
|
470
|
+
heading && /* @__PURE__ */ jsx5(
|
|
471
|
+
GroupHeading,
|
|
472
|
+
{
|
|
473
|
+
heading,
|
|
474
|
+
canCollapse,
|
|
475
|
+
open,
|
|
476
|
+
onToggle: () => setOpen((v) => !v)
|
|
477
|
+
}
|
|
478
|
+
),
|
|
479
|
+
(!canCollapse || open) && /* @__PURE__ */ jsx5("ul", { className: "space-y-0.5", children })
|
|
480
|
+
] });
|
|
481
|
+
}
|
|
482
|
+
|
|
483
|
+
// src/SidebarItem.tsx
|
|
484
|
+
import { Link, useLocation } from "react-router-dom";
|
|
485
|
+
import { ChevronRight } from "lucide-react";
|
|
486
|
+
import { cn as cn3 } from "@petrarca/sonnet-core";
|
|
487
|
+
import { jsx as jsx6, jsxs as jsxs4 } from "react/jsx-runtime";
|
|
488
|
+
function ItemTrailing({
|
|
489
|
+
badge,
|
|
490
|
+
expandable,
|
|
491
|
+
expanded,
|
|
492
|
+
onToggle
|
|
493
|
+
}) {
|
|
494
|
+
if (badge != null) {
|
|
495
|
+
return /* @__PURE__ */ jsx6("span", { className: "inline-flex items-center rounded-full bg-muted px-1.5 h-[18px] text-[10px] tabular-nums text-muted-foreground", children: badge });
|
|
496
|
+
}
|
|
497
|
+
if (expandable) {
|
|
498
|
+
const handleClick = (e) => {
|
|
499
|
+
e.preventDefault();
|
|
500
|
+
e.stopPropagation();
|
|
501
|
+
onToggle?.();
|
|
502
|
+
};
|
|
503
|
+
return /* @__PURE__ */ jsx6(
|
|
504
|
+
"button",
|
|
505
|
+
{
|
|
506
|
+
type: "button",
|
|
507
|
+
onClick: handleClick,
|
|
508
|
+
className: "p-0.5 text-muted-foreground hover:text-foreground",
|
|
509
|
+
children: /* @__PURE__ */ jsx6(
|
|
510
|
+
ChevronRight,
|
|
511
|
+
{
|
|
512
|
+
className: cn3(
|
|
513
|
+
"h-3 w-3 transition-transform",
|
|
514
|
+
expanded && "rotate-90"
|
|
515
|
+
)
|
|
516
|
+
}
|
|
517
|
+
)
|
|
518
|
+
}
|
|
519
|
+
);
|
|
520
|
+
}
|
|
521
|
+
return null;
|
|
522
|
+
}
|
|
523
|
+
function SidebarItem({
|
|
524
|
+
icon: Icon,
|
|
525
|
+
label,
|
|
526
|
+
path,
|
|
527
|
+
badge,
|
|
528
|
+
indent = 0,
|
|
529
|
+
expandable = false,
|
|
530
|
+
expanded = false,
|
|
531
|
+
onToggle,
|
|
532
|
+
onClick
|
|
533
|
+
}) {
|
|
534
|
+
const { pathname } = useLocation();
|
|
535
|
+
const isActive = pathname === path;
|
|
536
|
+
const style = indent > 0 ? { paddingLeft: `${indent * 16 + 8}px` } : void 0;
|
|
537
|
+
return /* @__PURE__ */ jsx6("li", { children: /* @__PURE__ */ jsxs4(
|
|
538
|
+
Link,
|
|
539
|
+
{
|
|
540
|
+
to: path,
|
|
541
|
+
onClick,
|
|
542
|
+
style,
|
|
543
|
+
className: cn3(
|
|
544
|
+
"flex items-center gap-2 rounded px-2 py-1.5 text-[13px] font-medium transition-colors select-none",
|
|
545
|
+
isActive ? "bg-accent text-accent-foreground" : "text-muted-foreground hover:text-foreground hover:bg-accent/50"
|
|
546
|
+
),
|
|
547
|
+
children: [
|
|
548
|
+
Icon && /* @__PURE__ */ jsx6(Icon, { className: "h-4 w-4 shrink-0" }),
|
|
549
|
+
/* @__PURE__ */ jsx6("span", { className: "min-w-0 flex-1 truncate", children: label }),
|
|
550
|
+
/* @__PURE__ */ jsx6(
|
|
551
|
+
ItemTrailing,
|
|
552
|
+
{
|
|
553
|
+
badge,
|
|
554
|
+
expandable,
|
|
555
|
+
expanded,
|
|
556
|
+
onToggle
|
|
557
|
+
}
|
|
558
|
+
)
|
|
559
|
+
]
|
|
560
|
+
}
|
|
561
|
+
) });
|
|
562
|
+
}
|
|
563
|
+
|
|
433
564
|
// src/SubNavPanel.tsx
|
|
434
|
-
import { jsx as
|
|
565
|
+
import { jsx as jsx7, jsxs as jsxs5 } from "react/jsx-runtime";
|
|
435
566
|
function useMergedNavigation(service) {
|
|
436
567
|
const contributions = useExtensionPoint(`${service.id}.nav`);
|
|
437
568
|
return useMemo2(() => {
|
|
@@ -452,66 +583,125 @@ function SubNavPanel({
|
|
|
452
583
|
collapsed,
|
|
453
584
|
onToggleCollapse
|
|
454
585
|
}) {
|
|
455
|
-
const { pathname } = useLocation();
|
|
456
586
|
const mergedNavigation = useMergedNavigation(service);
|
|
457
587
|
if (collapsed) {
|
|
458
|
-
return /* @__PURE__ */
|
|
459
|
-
/* @__PURE__ */
|
|
588
|
+
return /* @__PURE__ */ jsx7("aside", { className: "shrink-0 border-r bg-background flex flex-col items-center pt-2.5", children: /* @__PURE__ */ jsxs5(Tooltip2, { children: [
|
|
589
|
+
/* @__PURE__ */ jsx7(TooltipTrigger2, { asChild: true, children: /* @__PURE__ */ jsx7(
|
|
460
590
|
"button",
|
|
461
591
|
{
|
|
592
|
+
type: "button",
|
|
462
593
|
className: "text-muted-foreground/50 hover:text-muted-foreground transition-colors p-1",
|
|
463
594
|
onClick: onToggleCollapse,
|
|
464
|
-
children: /* @__PURE__ */
|
|
595
|
+
children: /* @__PURE__ */ jsx7(ChevronsRight, { className: "h-4 w-4" })
|
|
465
596
|
}
|
|
466
597
|
) }),
|
|
467
|
-
/* @__PURE__ */
|
|
598
|
+
/* @__PURE__ */ jsx7(TooltipContent2, { side: "right", children: "Expand navigation" })
|
|
468
599
|
] }) });
|
|
469
600
|
}
|
|
470
|
-
return /* @__PURE__ */
|
|
471
|
-
/* @__PURE__ */
|
|
472
|
-
/* @__PURE__ */
|
|
473
|
-
/* @__PURE__ */
|
|
474
|
-
/* @__PURE__ */
|
|
601
|
+
return /* @__PURE__ */ jsxs5("aside", { className: "w-52 shrink-0 border-r bg-background flex flex-col", children: [
|
|
602
|
+
/* @__PURE__ */ jsxs5("div", { className: "h-10 shrink-0 flex items-center justify-between px-4", children: [
|
|
603
|
+
/* @__PURE__ */ jsx7("span", { className: "text-sm font-semibold text-foreground", children: service.label }),
|
|
604
|
+
/* @__PURE__ */ jsxs5(Tooltip2, { children: [
|
|
605
|
+
/* @__PURE__ */ jsx7(TooltipTrigger2, { asChild: true, children: /* @__PURE__ */ jsx7(
|
|
475
606
|
"button",
|
|
476
607
|
{
|
|
608
|
+
type: "button",
|
|
477
609
|
className: "text-muted-foreground/40 hover:text-muted-foreground transition-colors p-0.5",
|
|
478
610
|
onClick: onToggleCollapse,
|
|
479
|
-
children: /* @__PURE__ */
|
|
611
|
+
children: /* @__PURE__ */ jsx7(ChevronsLeft, { className: "h-3.5 w-3.5" })
|
|
480
612
|
}
|
|
481
613
|
) }),
|
|
482
|
-
/* @__PURE__ */
|
|
614
|
+
/* @__PURE__ */ jsx7(TooltipContent2, { side: "right", children: "Collapse navigation" })
|
|
483
615
|
] })
|
|
484
616
|
] }),
|
|
485
|
-
/* @__PURE__ */
|
|
486
|
-
|
|
487
|
-
|
|
488
|
-
|
|
489
|
-
|
|
490
|
-
|
|
617
|
+
/* @__PURE__ */ jsx7(ScrollArea, { className: "flex-1", children: /* @__PURE__ */ jsx7("nav", { className: "px-1.5 pb-4 space-y-2", children: mergedNavigation.map((group) => /* @__PURE__ */ jsx7(
|
|
618
|
+
SidebarGroup,
|
|
619
|
+
{
|
|
620
|
+
heading: group.heading,
|
|
621
|
+
collapsible: group.collapsible,
|
|
622
|
+
children: group.links.map((link) => /* @__PURE__ */ jsx7(
|
|
623
|
+
SidebarItem,
|
|
491
624
|
{
|
|
492
|
-
|
|
493
|
-
|
|
494
|
-
|
|
495
|
-
|
|
496
|
-
|
|
497
|
-
|
|
498
|
-
|
|
499
|
-
|
|
500
|
-
|
|
501
|
-
|
|
625
|
+
label: link.label,
|
|
626
|
+
path: link.path,
|
|
627
|
+
badge: link.badge
|
|
628
|
+
},
|
|
629
|
+
link.path
|
|
630
|
+
))
|
|
631
|
+
},
|
|
632
|
+
group.id
|
|
633
|
+
)) }) })
|
|
634
|
+
] });
|
|
635
|
+
}
|
|
636
|
+
|
|
637
|
+
// src/shellNavigation.ts
|
|
638
|
+
import { createContext as createContext2, useContext as useContext2 } from "react";
|
|
639
|
+
var ShellNavigationContext = createContext2(null);
|
|
640
|
+
function useShellNavigation() {
|
|
641
|
+
const ctx = useContext2(ShellNavigationContext);
|
|
642
|
+
if (!ctx) {
|
|
643
|
+
throw new Error("useShellNavigation must be used within AppShell");
|
|
644
|
+
}
|
|
645
|
+
return ctx;
|
|
646
|
+
}
|
|
647
|
+
|
|
648
|
+
// src/ShellRail.tsx
|
|
649
|
+
import { Fragment, jsx as jsx8, jsxs as jsxs6 } from "react/jsx-runtime";
|
|
650
|
+
function ShellRail() {
|
|
651
|
+
const { mainModules, bottomModules } = useShellModules();
|
|
652
|
+
const {
|
|
653
|
+
activeService,
|
|
654
|
+
sidePaneModuleId,
|
|
655
|
+
subNavCollapsed,
|
|
656
|
+
onToggleSubNav,
|
|
657
|
+
onServiceSelect
|
|
658
|
+
} = useShellNavigation();
|
|
659
|
+
const isActive = (id) => activeService?.id === id || sidePaneModuleId === id;
|
|
660
|
+
return /* @__PURE__ */ jsxs6(Fragment, { children: [
|
|
661
|
+
/* @__PURE__ */ jsxs6(IconRail, { children: [
|
|
662
|
+
/* @__PURE__ */ jsx8("div", { className: "flex-1 flex flex-col items-center gap-1 overflow-y-auto", children: mainModules.map((service) => /* @__PURE__ */ jsx8(
|
|
663
|
+
RailIcon,
|
|
664
|
+
{
|
|
665
|
+
icon: service.icon,
|
|
666
|
+
label: service.label,
|
|
667
|
+
active: isActive(service.id),
|
|
668
|
+
onClick: () => onServiceSelect(service.id)
|
|
669
|
+
},
|
|
670
|
+
service.id
|
|
671
|
+
)) }),
|
|
672
|
+
/* @__PURE__ */ jsx8(RailSeparator, {}),
|
|
673
|
+
/* @__PURE__ */ jsx8("div", { className: "flex flex-col items-center gap-1", children: bottomModules.map((service) => /* @__PURE__ */ jsx8(
|
|
674
|
+
RailIcon,
|
|
675
|
+
{
|
|
676
|
+
icon: service.icon,
|
|
677
|
+
label: service.label,
|
|
678
|
+
active: isActive(service.id),
|
|
679
|
+
onClick: () => onServiceSelect(service.id)
|
|
680
|
+
},
|
|
681
|
+
service.id
|
|
682
|
+
)) })
|
|
683
|
+
] }),
|
|
684
|
+
activeService && activeService.navigation.length > 0 && /* @__PURE__ */ jsx8(
|
|
685
|
+
SubNavPanel,
|
|
686
|
+
{
|
|
687
|
+
service: activeService,
|
|
688
|
+
collapsed: subNavCollapsed,
|
|
689
|
+
onToggleCollapse: onToggleSubNav
|
|
690
|
+
}
|
|
691
|
+
)
|
|
502
692
|
] });
|
|
503
693
|
}
|
|
504
694
|
|
|
505
695
|
// src/SidePane.tsx
|
|
506
696
|
import { X } from "lucide-react";
|
|
507
|
-
import { cn as
|
|
697
|
+
import { cn as cn4 } from "@petrarca/sonnet-core";
|
|
508
698
|
import { useResizablePanel } from "@petrarca/sonnet-core/hooks";
|
|
509
699
|
|
|
510
700
|
// src/sidePaneState.ts
|
|
511
|
-
import { createContext as
|
|
512
|
-
var SidePaneContext =
|
|
701
|
+
import { createContext as createContext3, useContext as useContext3 } from "react";
|
|
702
|
+
var SidePaneContext = createContext3(null);
|
|
513
703
|
function useSidePaneState() {
|
|
514
|
-
const ctx =
|
|
704
|
+
const ctx = useContext3(SidePaneContext);
|
|
515
705
|
if (!ctx) {
|
|
516
706
|
throw new Error("useSidePaneState must be used within an AppShell");
|
|
517
707
|
}
|
|
@@ -519,19 +709,19 @@ function useSidePaneState() {
|
|
|
519
709
|
}
|
|
520
710
|
|
|
521
711
|
// src/SidePane.tsx
|
|
522
|
-
import { jsx as
|
|
712
|
+
import { jsx as jsx9, jsxs as jsxs7 } from "react/jsx-runtime";
|
|
523
713
|
function DragHandle({
|
|
524
714
|
separatorProps,
|
|
525
715
|
onPointerDown,
|
|
526
716
|
onDoubleClick
|
|
527
717
|
}) {
|
|
528
|
-
return /* @__PURE__ */
|
|
718
|
+
return /* @__PURE__ */ jsx9(
|
|
529
719
|
"div",
|
|
530
720
|
{
|
|
531
721
|
...separatorProps,
|
|
532
722
|
onPointerDown,
|
|
533
723
|
onDoubleClick,
|
|
534
|
-
className:
|
|
724
|
+
className: cn4(
|
|
535
725
|
"absolute right-0 top-0 h-full w-1 cursor-col-resize",
|
|
536
726
|
"hover:bg-primary/40 active:bg-primary/60 transition-colors"
|
|
537
727
|
)
|
|
@@ -544,7 +734,7 @@ var DEFAULT_MAX = 800;
|
|
|
544
734
|
function SidePane() {
|
|
545
735
|
const { pane, close } = useSidePaneState();
|
|
546
736
|
if (!pane) return null;
|
|
547
|
-
return /* @__PURE__ */
|
|
737
|
+
return /* @__PURE__ */ jsx9(SidePaneOpen, { pane, onClose: close });
|
|
548
738
|
}
|
|
549
739
|
function SidePaneOpen({
|
|
550
740
|
pane,
|
|
@@ -557,30 +747,30 @@ function SidePaneOpen({
|
|
|
557
747
|
direction: "right-edge"
|
|
558
748
|
});
|
|
559
749
|
const isFullWidth = pane.fullWidth === true;
|
|
560
|
-
return /* @__PURE__ */
|
|
750
|
+
return /* @__PURE__ */ jsxs7(
|
|
561
751
|
"div",
|
|
562
752
|
{
|
|
563
|
-
className:
|
|
753
|
+
className: cn4(
|
|
564
754
|
"relative flex flex-col border-r bg-background",
|
|
565
755
|
isFullWidth ? "flex-1" : "shrink-0"
|
|
566
756
|
),
|
|
567
757
|
style: isFullWidth ? void 0 : { width: panelWidth },
|
|
568
758
|
children: [
|
|
569
|
-
/* @__PURE__ */
|
|
759
|
+
/* @__PURE__ */ jsx9("div", { className: "flex h-10 shrink-0 items-center justify-end border-b px-2", children: /* @__PURE__ */ jsx9(
|
|
570
760
|
"button",
|
|
571
761
|
{
|
|
572
762
|
onClick: onClose,
|
|
573
|
-
className:
|
|
763
|
+
className: cn4(
|
|
574
764
|
"flex h-6 w-6 items-center justify-center rounded text-muted-foreground",
|
|
575
765
|
"hover:bg-accent hover:text-foreground transition-colors",
|
|
576
766
|
"focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-ring"
|
|
577
767
|
),
|
|
578
768
|
"aria-label": "Close side pane",
|
|
579
|
-
children: /* @__PURE__ */
|
|
769
|
+
children: /* @__PURE__ */ jsx9(X, { className: "h-3.5 w-3.5" })
|
|
580
770
|
}
|
|
581
771
|
) }),
|
|
582
|
-
/* @__PURE__ */
|
|
583
|
-
!isFullWidth && /* @__PURE__ */
|
|
772
|
+
/* @__PURE__ */ jsx9("div", { className: "flex-1 overflow-auto", children: pane.content }),
|
|
773
|
+
!isFullWidth && /* @__PURE__ */ jsx9(
|
|
584
774
|
DragHandle,
|
|
585
775
|
{
|
|
586
776
|
separatorProps,
|
|
@@ -605,7 +795,7 @@ import {
|
|
|
605
795
|
CommandList,
|
|
606
796
|
CommandSeparator
|
|
607
797
|
} from "@petrarca/sonnet-ui";
|
|
608
|
-
import { Fragment, jsx as
|
|
798
|
+
import { Fragment as Fragment2, jsx as jsx10, jsxs as jsxs8 } from "react/jsx-runtime";
|
|
609
799
|
function CommandMenu({ open, onOpenChange }) {
|
|
610
800
|
const navigate = useNavigate();
|
|
611
801
|
const { mainModules, bottomModules } = useShellModules();
|
|
@@ -629,16 +819,16 @@ function CommandMenu({ open, onOpenChange }) {
|
|
|
629
819
|
const renderNavGroup = (service) => {
|
|
630
820
|
if (service.navigation.length === 0) return null;
|
|
631
821
|
const Icon = service.icon;
|
|
632
|
-
return /* @__PURE__ */
|
|
633
|
-
(group) => group.links.map((link) => /* @__PURE__ */
|
|
822
|
+
return /* @__PURE__ */ jsx10(CommandGroup, { heading: service.label, children: service.navigation.flatMap(
|
|
823
|
+
(group) => group.links.map((link) => /* @__PURE__ */ jsxs8(
|
|
634
824
|
CommandItem,
|
|
635
825
|
{
|
|
636
826
|
value: `${service.label} ${group.heading ?? ""} ${link.label}`,
|
|
637
827
|
onSelect: () => handleSelect(link.path),
|
|
638
828
|
children: [
|
|
639
|
-
/* @__PURE__ */
|
|
640
|
-
/* @__PURE__ */
|
|
641
|
-
group.heading && /* @__PURE__ */
|
|
829
|
+
/* @__PURE__ */ jsx10(Icon, { className: "mr-2 h-4 w-4 text-muted-foreground" }),
|
|
830
|
+
/* @__PURE__ */ jsx10("span", { children: link.label }),
|
|
831
|
+
group.heading && /* @__PURE__ */ jsx10("span", { className: "ml-auto text-xs text-muted-foreground", children: group.heading })
|
|
642
832
|
]
|
|
643
833
|
},
|
|
644
834
|
link.path
|
|
@@ -648,13 +838,13 @@ function CommandMenu({ open, onOpenChange }) {
|
|
|
648
838
|
const renderCommandGroup = (service) => {
|
|
649
839
|
if (!service.commands?.length) return null;
|
|
650
840
|
const Icon = service.icon;
|
|
651
|
-
return /* @__PURE__ */
|
|
841
|
+
return /* @__PURE__ */ jsx10(
|
|
652
842
|
CommandGroup,
|
|
653
843
|
{
|
|
654
844
|
heading: service.commands[0].group ?? service.label,
|
|
655
845
|
children: service.commands.map((cmd) => {
|
|
656
846
|
const CmdIcon = cmd.icon ?? Icon;
|
|
657
|
-
return /* @__PURE__ */
|
|
847
|
+
return /* @__PURE__ */ jsxs8(
|
|
658
848
|
CommandItem,
|
|
659
849
|
{
|
|
660
850
|
value: `${service.label} ${cmd.label}`,
|
|
@@ -663,8 +853,8 @@ function CommandMenu({ open, onOpenChange }) {
|
|
|
663
853
|
onOpenChange(false);
|
|
664
854
|
},
|
|
665
855
|
children: [
|
|
666
|
-
/* @__PURE__ */
|
|
667
|
-
/* @__PURE__ */
|
|
856
|
+
/* @__PURE__ */ jsx10(CmdIcon, { className: "mr-2 h-4 w-4 text-muted-foreground" }),
|
|
857
|
+
/* @__PURE__ */ jsx10("span", { children: cmd.label })
|
|
668
858
|
]
|
|
669
859
|
},
|
|
670
860
|
cmd.id
|
|
@@ -675,15 +865,15 @@ function CommandMenu({ open, onOpenChange }) {
|
|
|
675
865
|
);
|
|
676
866
|
};
|
|
677
867
|
const allModules = [...mainModules, ...bottomModules];
|
|
678
|
-
return /* @__PURE__ */
|
|
679
|
-
/* @__PURE__ */
|
|
680
|
-
/* @__PURE__ */
|
|
681
|
-
/* @__PURE__ */
|
|
868
|
+
return /* @__PURE__ */ jsxs8(CommandDialog, { open, onOpenChange, children: [
|
|
869
|
+
/* @__PURE__ */ jsx10(CommandInput, { placeholder: "Search pages, services, actions..." }),
|
|
870
|
+
/* @__PURE__ */ jsxs8(CommandList, { children: [
|
|
871
|
+
/* @__PURE__ */ jsx10(CommandEmpty, { children: "No results found." }),
|
|
682
872
|
mainModules.map(renderNavGroup),
|
|
683
|
-
/* @__PURE__ */
|
|
873
|
+
/* @__PURE__ */ jsx10(CommandSeparator, {}),
|
|
684
874
|
bottomModules.map(renderNavGroup),
|
|
685
|
-
allModules.some((m) => m.commands?.length) && /* @__PURE__ */
|
|
686
|
-
/* @__PURE__ */
|
|
875
|
+
allModules.some((m) => m.commands?.length) && /* @__PURE__ */ jsxs8(Fragment2, { children: [
|
|
876
|
+
/* @__PURE__ */ jsx10(CommandSeparator, {}),
|
|
687
877
|
allModules.map(renderCommandGroup)
|
|
688
878
|
] })
|
|
689
879
|
] })
|
|
@@ -691,10 +881,10 @@ function CommandMenu({ open, onOpenChange }) {
|
|
|
691
881
|
}
|
|
692
882
|
|
|
693
883
|
// src/shellConfig.ts
|
|
694
|
-
import { createContext as
|
|
695
|
-
var ShellConfigContext =
|
|
884
|
+
import { createContext as createContext4, useContext as useContext4 } from "react";
|
|
885
|
+
var ShellConfigContext = createContext4(null);
|
|
696
886
|
function useShellConfig() {
|
|
697
|
-
const config =
|
|
887
|
+
const config = useContext4(ShellConfigContext);
|
|
698
888
|
if (!config) {
|
|
699
889
|
throw new Error("useShellConfig must be used within a ShellConfigProvider");
|
|
700
890
|
}
|
|
@@ -702,7 +892,7 @@ function useShellConfig() {
|
|
|
702
892
|
}
|
|
703
893
|
|
|
704
894
|
// src/AppShell.tsx
|
|
705
|
-
import { Fragment as
|
|
895
|
+
import { Fragment as Fragment3, jsx as jsx11, jsxs as jsxs9 } from "react/jsx-runtime";
|
|
706
896
|
var PANEL_WIDTH_CLASS = {
|
|
707
897
|
narrow: "w-[480px]",
|
|
708
898
|
default: "w-[640px]",
|
|
@@ -776,7 +966,7 @@ function useActiveService(modules) {
|
|
|
776
966
|
},
|
|
777
967
|
[serviceByBasePath]
|
|
778
968
|
);
|
|
779
|
-
const [selectedServiceId, setSelectedServiceId] =
|
|
969
|
+
const [selectedServiceId, setSelectedServiceId] = useState2(
|
|
780
970
|
() => resolveServiceFromPath(location.pathname)
|
|
781
971
|
);
|
|
782
972
|
useEffect3(
|
|
@@ -787,7 +977,7 @@ function useActiveService(modules) {
|
|
|
787
977
|
return { activeService, selectedServiceId, setSelectedServiceId };
|
|
788
978
|
}
|
|
789
979
|
function useSidePaneState2() {
|
|
790
|
-
const [sidePaneState, setSidePaneState] =
|
|
980
|
+
const [sidePaneState, setSidePaneState] = useState2(
|
|
791
981
|
null
|
|
792
982
|
);
|
|
793
983
|
const handleOpen = useCallback2(
|
|
@@ -817,7 +1007,7 @@ function useSidePaneState2() {
|
|
|
817
1007
|
};
|
|
818
1008
|
}
|
|
819
1009
|
function usePanelState() {
|
|
820
|
-
const [panelState, setPanelState] =
|
|
1010
|
+
const [panelState, setPanelState] = useState2(null);
|
|
821
1011
|
const panelOnCloseRef = useRef2(void 0);
|
|
822
1012
|
const handleOpen = useCallback2(
|
|
823
1013
|
(opts) => setPanelState(opts),
|
|
@@ -839,7 +1029,7 @@ function usePanelState() {
|
|
|
839
1029
|
};
|
|
840
1030
|
}
|
|
841
1031
|
function useDialogState() {
|
|
842
|
-
const [dialogState, setDialogState] =
|
|
1032
|
+
const [dialogState, setDialogState] = useState2(null);
|
|
843
1033
|
const handleConfirm = useCallback2(() => {
|
|
844
1034
|
dialogState?.resolve(true);
|
|
845
1035
|
setDialogState(null);
|
|
@@ -863,15 +1053,15 @@ function useFeatureLookup(modules) {
|
|
|
863
1053
|
return (featureId) => map.get(featureId) ?? null;
|
|
864
1054
|
}, [modules]);
|
|
865
1055
|
}
|
|
866
|
-
function AppShell({ registry }) {
|
|
1056
|
+
function AppShell({ registry, sidebar }) {
|
|
867
1057
|
const navigate = useNavigate2();
|
|
868
1058
|
const config = useShellConfig();
|
|
869
1059
|
const { modules } = registry;
|
|
870
1060
|
const { activeService, setSelectedServiceId } = useActiveService(modules);
|
|
871
|
-
const [subNavCollapsed, setSubNavCollapsed] =
|
|
872
|
-
const [commandMenuOpen, setCommandMenuOpen] =
|
|
1061
|
+
const [subNavCollapsed, setSubNavCollapsed] = useState2(false);
|
|
1062
|
+
const [commandMenuOpen, setCommandMenuOpen] = useState2(false);
|
|
873
1063
|
const openCommandMenu = useCallback2(() => setCommandMenuOpen(true), []);
|
|
874
|
-
const [fullscreenState, setFullscreenState] =
|
|
1064
|
+
const [fullscreenState, setFullscreenState] = useState2(null);
|
|
875
1065
|
const handleFullscreenEnter = useCallback2(
|
|
876
1066
|
(opts) => setFullscreenState(opts),
|
|
877
1067
|
[]
|
|
@@ -946,27 +1136,32 @@ function AppShell({ registry }) {
|
|
|
946
1136
|
}),
|
|
947
1137
|
[sidePane2]
|
|
948
1138
|
);
|
|
949
|
-
|
|
950
|
-
|
|
951
|
-
|
|
1139
|
+
const navigationValue = {
|
|
1140
|
+
activeService,
|
|
1141
|
+
sidePaneModuleId: sidePane2.sidePaneState?.moduleId ?? null,
|
|
1142
|
+
subNavCollapsed,
|
|
1143
|
+
onToggleSubNav: () => setSubNavCollapsed((c) => !c),
|
|
1144
|
+
onServiceSelect: handleServiceSelect
|
|
1145
|
+
};
|
|
1146
|
+
return /* @__PURE__ */ jsx11(ShellModulesContext.Provider, { value: registry, children: /* @__PURE__ */ jsx11(SidePaneContext.Provider, { value: sidePaneContextValue, children: /* @__PURE__ */ jsx11(ShellNavigationContext.Provider, { value: navigationValue, children: /* @__PURE__ */ jsx11(TooltipProvider, { children: /* @__PURE__ */ jsxs9("div", { className: "flex h-screen w-screen flex-col overflow-hidden", children: [
|
|
1147
|
+
/* @__PURE__ */ jsx11(TopBar, { children: config.topBar }),
|
|
1148
|
+
/* @__PURE__ */ jsx11(
|
|
952
1149
|
CommandMenu,
|
|
953
1150
|
{
|
|
954
1151
|
open: commandMenuOpen,
|
|
955
1152
|
onOpenChange: setCommandMenuOpen
|
|
956
1153
|
}
|
|
957
1154
|
),
|
|
958
|
-
/* @__PURE__ */
|
|
1155
|
+
/* @__PURE__ */ jsx11(
|
|
959
1156
|
ShellBody,
|
|
960
1157
|
{
|
|
961
1158
|
activeService,
|
|
962
1159
|
sidePaneFullWidth: sidePane2.sidePaneState?.fullWidth,
|
|
963
|
-
|
|
964
|
-
subNavCollapsed,
|
|
965
|
-
onToggleSubNav: () => setSubNavCollapsed((c) => !c),
|
|
966
|
-
onServiceSelect: handleServiceSelect
|
|
1160
|
+
sidebar
|
|
967
1161
|
}
|
|
968
1162
|
),
|
|
969
|
-
|
|
1163
|
+
config.footer && /* @__PURE__ */ jsx11(ShellFooter, { children: config.footer }),
|
|
1164
|
+
dialog2.dialogState && /* @__PURE__ */ jsx11(
|
|
970
1165
|
ConfirmDialog,
|
|
971
1166
|
{
|
|
972
1167
|
open: true,
|
|
@@ -979,8 +1174,8 @@ function AppShell({ registry }) {
|
|
|
979
1174
|
onCancel: dialog2.handleCancel
|
|
980
1175
|
}
|
|
981
1176
|
),
|
|
982
|
-
fullscreenState && /* @__PURE__ */
|
|
983
|
-
/* @__PURE__ */
|
|
1177
|
+
fullscreenState && /* @__PURE__ */ jsx11("div", { className: "fixed inset-0 z-50 bg-background overflow-auto", children: fullscreenState.content }),
|
|
1178
|
+
/* @__PURE__ */ jsx11(
|
|
984
1179
|
SlideOverPanel,
|
|
985
1180
|
{
|
|
986
1181
|
panelState: panel2.panelState,
|
|
@@ -990,7 +1185,7 @@ function AppShell({ registry }) {
|
|
|
990
1185
|
onClose: panel2.handleClose
|
|
991
1186
|
}
|
|
992
1187
|
)
|
|
993
|
-
] }) }) }) });
|
|
1188
|
+
] }) }) }) }) });
|
|
994
1189
|
}
|
|
995
1190
|
function SlideOverPanel({
|
|
996
1191
|
panelState,
|
|
@@ -999,14 +1194,14 @@ function SlideOverPanel({
|
|
|
999
1194
|
panelOnCloseRef,
|
|
1000
1195
|
onClose
|
|
1001
1196
|
}) {
|
|
1002
|
-
return /* @__PURE__ */
|
|
1197
|
+
return /* @__PURE__ */ jsx11(
|
|
1003
1198
|
Sheet,
|
|
1004
1199
|
{
|
|
1005
1200
|
open: panelState !== null,
|
|
1006
1201
|
onOpenChange: (open) => {
|
|
1007
1202
|
if (!open) onClose();
|
|
1008
1203
|
},
|
|
1009
|
-
children: /* @__PURE__ */
|
|
1204
|
+
children: /* @__PURE__ */ jsx11(
|
|
1010
1205
|
SheetContent,
|
|
1011
1206
|
{
|
|
1012
1207
|
side: "right",
|
|
@@ -1021,7 +1216,7 @@ function SlideOverPanel({
|
|
|
1021
1216
|
...!panelState?.description && {
|
|
1022
1217
|
"aria-describedby": void 0
|
|
1023
1218
|
},
|
|
1024
|
-
children: panelState && /* @__PURE__ */
|
|
1219
|
+
children: panelState && /* @__PURE__ */ jsx11(PanelContent, { state: panelState })
|
|
1025
1220
|
}
|
|
1026
1221
|
)
|
|
1027
1222
|
}
|
|
@@ -1030,45 +1225,27 @@ function SlideOverPanel({
|
|
|
1030
1225
|
function ShellBody({
|
|
1031
1226
|
activeService,
|
|
1032
1227
|
sidePaneFullWidth,
|
|
1033
|
-
|
|
1034
|
-
subNavCollapsed,
|
|
1035
|
-
onToggleSubNav,
|
|
1036
|
-
onServiceSelect
|
|
1228
|
+
sidebar
|
|
1037
1229
|
}) {
|
|
1038
|
-
return /* @__PURE__ */
|
|
1039
|
-
/* @__PURE__ */
|
|
1040
|
-
|
|
1041
|
-
|
|
1042
|
-
activeServiceId: activeService?.id ?? null,
|
|
1043
|
-
activeSidePaneModuleId: sidePaneModuleId,
|
|
1044
|
-
onServiceSelect
|
|
1045
|
-
}
|
|
1046
|
-
),
|
|
1047
|
-
activeService && activeService.navigation.length > 0 && /* @__PURE__ */ jsx7(
|
|
1048
|
-
SubNavPanel,
|
|
1049
|
-
{
|
|
1050
|
-
service: activeService,
|
|
1051
|
-
collapsed: subNavCollapsed,
|
|
1052
|
-
onToggleCollapse: onToggleSubNav
|
|
1053
|
-
}
|
|
1054
|
-
),
|
|
1055
|
-
/* @__PURE__ */ jsx7(SidePane, {}),
|
|
1056
|
-
sidePaneFullWidth !== true && /* @__PURE__ */ jsx7("div", { className: "flex-1 min-w-0 h-full overflow-hidden", children: /* @__PURE__ */ jsx7(ContentArea, { layout: activeService?.layout }) })
|
|
1230
|
+
return /* @__PURE__ */ jsxs9("div", { className: "flex flex-1 overflow-hidden", children: [
|
|
1231
|
+
sidebar ?? /* @__PURE__ */ jsx11(ShellRail, {}),
|
|
1232
|
+
/* @__PURE__ */ jsx11(SidePane, {}),
|
|
1233
|
+
sidePaneFullWidth !== true && /* @__PURE__ */ jsx11("div", { className: "flex-1 min-w-0 h-full overflow-hidden", children: /* @__PURE__ */ jsx11(ContentArea, { layout: activeService?.layout }) })
|
|
1057
1234
|
] });
|
|
1058
1235
|
}
|
|
1059
1236
|
function ContentArea({ layout }) {
|
|
1060
1237
|
if (layout === "full") {
|
|
1061
|
-
return /* @__PURE__ */
|
|
1238
|
+
return /* @__PURE__ */ jsx11("div", { className: "h-full w-full overflow-hidden", children: /* @__PURE__ */ jsx11(Outlet, {}) });
|
|
1062
1239
|
}
|
|
1063
|
-
return /* @__PURE__ */
|
|
1240
|
+
return /* @__PURE__ */ jsx11(ScrollArea2, { className: "h-full", children: /* @__PURE__ */ jsx11("main", { className: "p-6", children: /* @__PURE__ */ jsx11(Outlet, {}) }) });
|
|
1064
1241
|
}
|
|
1065
1242
|
function PanelContent({ state }) {
|
|
1066
|
-
return /* @__PURE__ */
|
|
1067
|
-
state.title ? /* @__PURE__ */
|
|
1068
|
-
/* @__PURE__ */
|
|
1069
|
-
state.description && /* @__PURE__ */
|
|
1070
|
-
] }) : /* @__PURE__ */
|
|
1071
|
-
/* @__PURE__ */
|
|
1243
|
+
return /* @__PURE__ */ jsxs9(Fragment3, { children: [
|
|
1244
|
+
state.title ? /* @__PURE__ */ jsxs9(SheetHeader, { children: [
|
|
1245
|
+
/* @__PURE__ */ jsx11(SheetTitle, { children: state.title }),
|
|
1246
|
+
state.description && /* @__PURE__ */ jsx11(SheetDescription, { children: state.description })
|
|
1247
|
+
] }) : /* @__PURE__ */ jsx11(SheetTitle, { className: "sr-only", children: "Panel" }),
|
|
1248
|
+
/* @__PURE__ */ jsx11(SheetBody, { children: state.content })
|
|
1072
1249
|
] });
|
|
1073
1250
|
}
|
|
1074
1251
|
|
|
@@ -1076,32 +1253,36 @@ function PanelContent({ state }) {
|
|
|
1076
1253
|
import { Toaster } from "sonner";
|
|
1077
1254
|
|
|
1078
1255
|
// src/ShellConfigProvider.tsx
|
|
1079
|
-
import { jsx as
|
|
1256
|
+
import { jsx as jsx12 } from "react/jsx-runtime";
|
|
1080
1257
|
function ShellConfigProvider({
|
|
1081
1258
|
config,
|
|
1082
1259
|
children
|
|
1083
1260
|
}) {
|
|
1084
|
-
return /* @__PURE__ */
|
|
1261
|
+
return /* @__PURE__ */ jsx12(ShellConfigContext.Provider, { value: config, children });
|
|
1085
1262
|
}
|
|
1086
1263
|
|
|
1087
1264
|
// src/RootLayout.tsx
|
|
1088
|
-
import { jsx as
|
|
1089
|
-
function RootLayout({
|
|
1090
|
-
|
|
1091
|
-
|
|
1092
|
-
|
|
1265
|
+
import { jsx as jsx13, jsxs as jsxs10 } from "react/jsx-runtime";
|
|
1266
|
+
function RootLayout({
|
|
1267
|
+
config,
|
|
1268
|
+
registry,
|
|
1269
|
+
sidebar
|
|
1270
|
+
}) {
|
|
1271
|
+
return /* @__PURE__ */ jsxs10(ShellConfigProvider, { config, children: [
|
|
1272
|
+
/* @__PURE__ */ jsx13(Toaster, { position: "top-right", richColors: true, closeButton: true }),
|
|
1273
|
+
/* @__PURE__ */ jsx13(AppShell, { registry, sidebar })
|
|
1093
1274
|
] });
|
|
1094
1275
|
}
|
|
1095
1276
|
|
|
1096
1277
|
// src/PlaceholderPage.tsx
|
|
1097
1278
|
import { useLocation as useLocation3 } from "react-router-dom";
|
|
1098
|
-
import { jsx as
|
|
1279
|
+
import { jsx as jsx14, jsxs as jsxs11 } from "react/jsx-runtime";
|
|
1099
1280
|
function PlaceholderPage() {
|
|
1100
1281
|
const { pathname } = useLocation3();
|
|
1101
|
-
return /* @__PURE__ */
|
|
1102
|
-
/* @__PURE__ */
|
|
1103
|
-
/* @__PURE__ */
|
|
1104
|
-
/* @__PURE__ */
|
|
1282
|
+
return /* @__PURE__ */ jsxs11("div", { children: [
|
|
1283
|
+
/* @__PURE__ */ jsx14("h1", { className: "mb-1", children: pathToTitle(pathname) }),
|
|
1284
|
+
/* @__PURE__ */ jsx14("p", { className: "text-sm text-muted-foreground mb-6", children: pathname }),
|
|
1285
|
+
/* @__PURE__ */ jsx14("div", { className: "rounded-lg border-2 border-dashed border-border p-12 flex items-center justify-center", children: /* @__PURE__ */ jsx14("span", { className: "text-sm text-muted-foreground", children: "Content area \u2014 not yet implemented" }) })
|
|
1105
1286
|
] });
|
|
1106
1287
|
}
|
|
1107
1288
|
function pathToTitle(path) {
|
|
@@ -1110,12 +1291,131 @@ function pathToTitle(path) {
|
|
|
1110
1291
|
return last.split("-").map((w) => w.charAt(0).toUpperCase() + w.slice(1)).join(" ");
|
|
1111
1292
|
}
|
|
1112
1293
|
|
|
1294
|
+
// src/Sidebar.tsx
|
|
1295
|
+
import { cn as cn5 } from "@petrarca/sonnet-core";
|
|
1296
|
+
import { ScrollArea as ScrollArea3 } from "@petrarca/sonnet-ui";
|
|
1297
|
+
import { jsx as jsx15, jsxs as jsxs12 } from "react/jsx-runtime";
|
|
1298
|
+
function Sidebar({
|
|
1299
|
+
children,
|
|
1300
|
+
header,
|
|
1301
|
+
width = 260,
|
|
1302
|
+
className
|
|
1303
|
+
}) {
|
|
1304
|
+
return /* @__PURE__ */ jsxs12(
|
|
1305
|
+
"aside",
|
|
1306
|
+
{
|
|
1307
|
+
style: { width },
|
|
1308
|
+
className: cn5(
|
|
1309
|
+
"shrink-0 border-r bg-muted/30 flex flex-col h-full",
|
|
1310
|
+
className
|
|
1311
|
+
),
|
|
1312
|
+
children: [
|
|
1313
|
+
header,
|
|
1314
|
+
/* @__PURE__ */ jsx15(ScrollArea3, { className: "flex-1", children: /* @__PURE__ */ jsx15("nav", { className: "px-1.5 py-2 space-y-3", children }) })
|
|
1315
|
+
]
|
|
1316
|
+
}
|
|
1317
|
+
);
|
|
1318
|
+
}
|
|
1319
|
+
|
|
1320
|
+
// src/ShellSidebar.tsx
|
|
1321
|
+
import { jsx as jsx16, jsxs as jsxs13 } from "react/jsx-runtime";
|
|
1322
|
+
function ShellSidebar({
|
|
1323
|
+
bottomGroupLabel = "Tools",
|
|
1324
|
+
...sidebarProps
|
|
1325
|
+
}) {
|
|
1326
|
+
const { mainModules, bottomModules } = useShellModules();
|
|
1327
|
+
const topNavItems = mainModules.flatMap(
|
|
1328
|
+
(mod) => (mod.topNav ?? []).map((link) => ({ link, icon: mod.icon }))
|
|
1329
|
+
);
|
|
1330
|
+
return /* @__PURE__ */ jsxs13(Sidebar, { ...sidebarProps, children: [
|
|
1331
|
+
topNavItems.length > 0 && /* @__PURE__ */ jsx16(SidebarGroup, { separator: true, children: topNavItems.map(({ link, icon }) => /* @__PURE__ */ jsx16(
|
|
1332
|
+
SidebarItem,
|
|
1333
|
+
{
|
|
1334
|
+
icon,
|
|
1335
|
+
label: link.label,
|
|
1336
|
+
path: link.path,
|
|
1337
|
+
badge: link.badge
|
|
1338
|
+
},
|
|
1339
|
+
link.path
|
|
1340
|
+
)) }),
|
|
1341
|
+
mainModules.map((mod) => {
|
|
1342
|
+
if (mod.navigation.length === 0) {
|
|
1343
|
+
return /* @__PURE__ */ jsx16(
|
|
1344
|
+
SidebarItem,
|
|
1345
|
+
{
|
|
1346
|
+
icon: mod.icon,
|
|
1347
|
+
label: mod.label,
|
|
1348
|
+
path: mod.basePath
|
|
1349
|
+
},
|
|
1350
|
+
mod.id
|
|
1351
|
+
);
|
|
1352
|
+
}
|
|
1353
|
+
return /* @__PURE__ */ jsx16(SidebarGroup, { heading: mod.label, collapsible: true, children: mod.navigation.flatMap((group) => [
|
|
1354
|
+
// Render NavGroup heading if it has one
|
|
1355
|
+
...group.heading ? [
|
|
1356
|
+
/* @__PURE__ */ jsx16(
|
|
1357
|
+
SidebarGroup,
|
|
1358
|
+
{
|
|
1359
|
+
heading: group.heading,
|
|
1360
|
+
collapsible: group.collapsible,
|
|
1361
|
+
children: group.links.map((link) => /* @__PURE__ */ jsx16(
|
|
1362
|
+
SidebarItem,
|
|
1363
|
+
{
|
|
1364
|
+
icon: mod.icon,
|
|
1365
|
+
label: link.label,
|
|
1366
|
+
path: link.path,
|
|
1367
|
+
badge: link.badge
|
|
1368
|
+
},
|
|
1369
|
+
link.path
|
|
1370
|
+
))
|
|
1371
|
+
},
|
|
1372
|
+
group.id
|
|
1373
|
+
)
|
|
1374
|
+
] : group.links.map((link) => /* @__PURE__ */ jsx16(
|
|
1375
|
+
SidebarItem,
|
|
1376
|
+
{
|
|
1377
|
+
icon: mod.icon,
|
|
1378
|
+
label: link.label,
|
|
1379
|
+
path: link.path,
|
|
1380
|
+
badge: link.badge
|
|
1381
|
+
},
|
|
1382
|
+
link.path
|
|
1383
|
+
))
|
|
1384
|
+
]) }, mod.id);
|
|
1385
|
+
}),
|
|
1386
|
+
bottomModules.length > 0 && /* @__PURE__ */ jsx16(SidebarGroup, { heading: bottomGroupLabel, collapsible: true, children: bottomModules.map((mod) => /* @__PURE__ */ jsx16(
|
|
1387
|
+
SidebarItem,
|
|
1388
|
+
{
|
|
1389
|
+
icon: mod.icon,
|
|
1390
|
+
label: mod.label,
|
|
1391
|
+
path: mod.basePath
|
|
1392
|
+
},
|
|
1393
|
+
mod.id
|
|
1394
|
+
)) })
|
|
1395
|
+
] });
|
|
1396
|
+
}
|
|
1397
|
+
|
|
1398
|
+
// src/ShellVersion.tsx
|
|
1399
|
+
import { jsx as jsx17, jsxs as jsxs14 } from "react/jsx-runtime";
|
|
1400
|
+
function ShellVersion({
|
|
1401
|
+
name,
|
|
1402
|
+
version
|
|
1403
|
+
}) {
|
|
1404
|
+
return /* @__PURE__ */ jsxs14("div", { className: "flex items-center gap-2", children: [
|
|
1405
|
+
/* @__PURE__ */ jsx17("span", { children: name }),
|
|
1406
|
+
version && /* @__PURE__ */ jsxs14("span", { className: "text-muted-foreground/50", children: [
|
|
1407
|
+
"v",
|
|
1408
|
+
version
|
|
1409
|
+
] })
|
|
1410
|
+
] });
|
|
1411
|
+
}
|
|
1412
|
+
|
|
1113
1413
|
// src/SearchTrigger.tsx
|
|
1114
1414
|
import { Search } from "lucide-react";
|
|
1115
1415
|
import { Button as Button3 } from "@petrarca/sonnet-ui";
|
|
1116
|
-
import { jsx as
|
|
1416
|
+
import { jsx as jsx18, jsxs as jsxs15 } from "react/jsx-runtime";
|
|
1117
1417
|
function SearchTrigger() {
|
|
1118
|
-
return /* @__PURE__ */
|
|
1418
|
+
return /* @__PURE__ */ jsxs15(
|
|
1119
1419
|
Button3,
|
|
1120
1420
|
{
|
|
1121
1421
|
variant: "outline",
|
|
@@ -1123,10 +1423,10 @@ function SearchTrigger() {
|
|
|
1123
1423
|
className: "h-8 gap-2 text-sm text-muted-foreground w-56 justify-start",
|
|
1124
1424
|
onClick: () => navigation.openCommandMenu(),
|
|
1125
1425
|
children: [
|
|
1126
|
-
/* @__PURE__ */
|
|
1127
|
-
/* @__PURE__ */
|
|
1128
|
-
/* @__PURE__ */
|
|
1129
|
-
/* @__PURE__ */
|
|
1426
|
+
/* @__PURE__ */ jsx18(Search, { className: "h-4 w-4" }),
|
|
1427
|
+
/* @__PURE__ */ jsx18("span", { children: "Search..." }),
|
|
1428
|
+
/* @__PURE__ */ jsxs15("kbd", { className: "ml-auto pointer-events-none inline-flex h-5 select-none items-center gap-1 rounded border bg-muted px-1.5 font-mono text-[10px] font-medium text-muted-foreground", children: [
|
|
1429
|
+
/* @__PURE__ */ jsx18("span", { className: "text-xs", children: "\u2318" }),
|
|
1130
1430
|
"K"
|
|
1131
1431
|
] })
|
|
1132
1432
|
]
|
|
@@ -1146,23 +1446,23 @@ import {
|
|
|
1146
1446
|
DropdownMenuSeparator,
|
|
1147
1447
|
DropdownMenuTrigger
|
|
1148
1448
|
} from "@petrarca/sonnet-ui";
|
|
1149
|
-
import { jsx as
|
|
1449
|
+
import { jsx as jsx19, jsxs as jsxs16 } from "react/jsx-runtime";
|
|
1150
1450
|
function UserMenu({ user, onSignOut }) {
|
|
1151
|
-
return /* @__PURE__ */
|
|
1152
|
-
/* @__PURE__ */
|
|
1153
|
-
/* @__PURE__ */
|
|
1154
|
-
/* @__PURE__ */
|
|
1155
|
-
/* @__PURE__ */
|
|
1156
|
-
/* @__PURE__ */
|
|
1451
|
+
return /* @__PURE__ */ jsxs16(DropdownMenu, { children: [
|
|
1452
|
+
/* @__PURE__ */ jsx19(DropdownMenuTrigger, { asChild: true, children: /* @__PURE__ */ jsx19(Button4, { variant: "ghost", size: "compact", className: "rounded-full", children: /* @__PURE__ */ jsx19(Avatar, { className: "h-7 w-7", children: /* @__PURE__ */ jsx19(AvatarFallback, { className: "text-xs", children: user.initials }) }) }) }),
|
|
1453
|
+
/* @__PURE__ */ jsxs16(DropdownMenuContent, { align: "end", className: "w-48", children: [
|
|
1454
|
+
/* @__PURE__ */ jsx19(DropdownMenuLabel, { className: "font-normal", children: /* @__PURE__ */ jsxs16("div", { className: "flex flex-col gap-1", children: [
|
|
1455
|
+
/* @__PURE__ */ jsx19("p", { className: "text-sm font-medium", children: user.name }),
|
|
1456
|
+
/* @__PURE__ */ jsx19("p", { className: "text-xs text-muted-foreground", children: user.email })
|
|
1157
1457
|
] }) }),
|
|
1158
|
-
/* @__PURE__ */
|
|
1159
|
-
/* @__PURE__ */
|
|
1160
|
-
/* @__PURE__ */
|
|
1458
|
+
/* @__PURE__ */ jsx19(DropdownMenuSeparator, {}),
|
|
1459
|
+
/* @__PURE__ */ jsxs16(DropdownMenuItem, { children: [
|
|
1460
|
+
/* @__PURE__ */ jsx19(User, { className: "mr-2 h-4 w-4" }),
|
|
1161
1461
|
"Profile"
|
|
1162
1462
|
] }),
|
|
1163
|
-
/* @__PURE__ */
|
|
1164
|
-
/* @__PURE__ */
|
|
1165
|
-
/* @__PURE__ */
|
|
1463
|
+
/* @__PURE__ */ jsx19(DropdownMenuSeparator, {}),
|
|
1464
|
+
/* @__PURE__ */ jsxs16(DropdownMenuItem, { onSelect: onSignOut, children: [
|
|
1465
|
+
/* @__PURE__ */ jsx19(LogOut, { className: "mr-2 h-4 w-4" }),
|
|
1166
1466
|
"Sign out"
|
|
1167
1467
|
] })
|
|
1168
1468
|
] })
|
|
@@ -1193,13 +1493,13 @@ function createModuleRegistry(modules) {
|
|
|
1193
1493
|
}
|
|
1194
1494
|
|
|
1195
1495
|
// src/OverviewCard.tsx
|
|
1196
|
-
import { cn as
|
|
1197
|
-
import { jsx as
|
|
1496
|
+
import { cn as cn6 } from "@petrarca/sonnet-core";
|
|
1497
|
+
import { jsx as jsx20, jsxs as jsxs17 } from "react/jsx-runtime";
|
|
1198
1498
|
function FeatureLink({
|
|
1199
1499
|
feature,
|
|
1200
1500
|
children
|
|
1201
1501
|
}) {
|
|
1202
|
-
return /* @__PURE__ */
|
|
1502
|
+
return /* @__PURE__ */ jsx20(
|
|
1203
1503
|
"span",
|
|
1204
1504
|
{
|
|
1205
1505
|
role: "link",
|
|
@@ -1227,22 +1527,22 @@ function OverviewCard({
|
|
|
1227
1527
|
feature,
|
|
1228
1528
|
className
|
|
1229
1529
|
}) {
|
|
1230
|
-
return /* @__PURE__ */
|
|
1530
|
+
return /* @__PURE__ */ jsxs17(
|
|
1231
1531
|
"button",
|
|
1232
1532
|
{
|
|
1233
1533
|
onClick: feature ? () => navigation.goToFeature(feature) : void 0,
|
|
1234
1534
|
disabled: !feature,
|
|
1235
|
-
className:
|
|
1535
|
+
className: cn6(
|
|
1236
1536
|
"rounded-lg border bg-card p-5 text-left flex flex-col gap-3",
|
|
1237
1537
|
"disabled:cursor-default",
|
|
1238
1538
|
feature && "hover:bg-accent/50 transition-colors",
|
|
1239
1539
|
className
|
|
1240
1540
|
),
|
|
1241
1541
|
children: [
|
|
1242
|
-
/* @__PURE__ */
|
|
1243
|
-
/* @__PURE__ */
|
|
1244
|
-
/* @__PURE__ */
|
|
1245
|
-
/* @__PURE__ */
|
|
1542
|
+
/* @__PURE__ */ jsx20("div", { className: "h-9 w-9 rounded-md bg-blue-50 flex items-center justify-center shrink-0", children: /* @__PURE__ */ jsx20(Icon, { className: "h-5 w-5 text-blue-600" }) }),
|
|
1543
|
+
/* @__PURE__ */ jsxs17("div", { children: [
|
|
1544
|
+
/* @__PURE__ */ jsx20("p", { className: "text-sm font-medium mb-1", children: title }),
|
|
1545
|
+
/* @__PURE__ */ jsx20("p", { className: "text-xs text-muted-foreground leading-relaxed", children: description })
|
|
1246
1546
|
] })
|
|
1247
1547
|
]
|
|
1248
1548
|
}
|
|
@@ -1256,11 +1556,20 @@ export {
|
|
|
1256
1556
|
IconRail,
|
|
1257
1557
|
OverviewCard,
|
|
1258
1558
|
PlaceholderPage,
|
|
1559
|
+
RailIcon,
|
|
1560
|
+
RailSeparator,
|
|
1259
1561
|
RootLayout,
|
|
1260
1562
|
SearchTrigger,
|
|
1261
1563
|
ShellConfigProvider,
|
|
1564
|
+
ShellFooter,
|
|
1565
|
+
ShellRail,
|
|
1566
|
+
ShellSidebar,
|
|
1567
|
+
ShellVersion,
|
|
1262
1568
|
SidePane,
|
|
1263
1569
|
SidePaneContext,
|
|
1570
|
+
Sidebar,
|
|
1571
|
+
SidebarGroup,
|
|
1572
|
+
SidebarItem,
|
|
1264
1573
|
SubNavPanel,
|
|
1265
1574
|
TopBar,
|
|
1266
1575
|
UserMenu,
|
|
@@ -1269,6 +1578,8 @@ export {
|
|
|
1269
1578
|
events,
|
|
1270
1579
|
fullscreen,
|
|
1271
1580
|
initDialog,
|
|
1581
|
+
initFeatureNav,
|
|
1582
|
+
initFullscreen,
|
|
1272
1583
|
initNavigation,
|
|
1273
1584
|
initPanel,
|
|
1274
1585
|
initSidePane,
|
|
@@ -1281,6 +1592,7 @@ export {
|
|
|
1281
1592
|
useShellConfig,
|
|
1282
1593
|
useShellEvent,
|
|
1283
1594
|
useShellModules,
|
|
1595
|
+
useShellNavigation,
|
|
1284
1596
|
useSidePaneState
|
|
1285
1597
|
};
|
|
1286
1598
|
//# sourceMappingURL=index.js.map
|