@xenide-io/the-old-ui-theme 0.4.4 → 0.4.8
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/{chunk-54ZR4VL5.mjs → chunk-RZXHZWUB.mjs} +44 -17
- package/dist/{index-B5NOyoKS.d.mts → index-Od4pIP4F.d.mts} +7 -1
- package/dist/{index-B5NOyoKS.d.ts → index-Od4pIP4F.d.ts} +7 -1
- package/dist/index.d.mts +2 -2
- package/dist/index.d.ts +2 -2
- package/dist/index.js +37 -10
- package/dist/index.mjs +1 -1
- package/dist/suite.d.mts +152 -41
- package/dist/suite.d.ts +152 -41
- package/dist/suite.js +1366 -671
- package/dist/suite.mjs +1304 -610
- package/dist/ui.d.mts +1 -1
- package/dist/ui.d.ts +1 -1
- package/dist/ui.js +37 -10
- package/dist/ui.mjs +1 -1
- package/package.json +7 -3
- package/src/components/ui/Modal.tsx +70 -26
- package/src/styles/suite-skin.css +284 -24
- package/src/suite/components/ai-panel.test.ts +20 -0
- package/src/suite/components/ai-panel.tsx +494 -103
- package/src/suite/components/suite-app-layout.tsx +48 -28
- package/src/suite/components/suite-layout.tsx +84 -40
- package/src/suite/components/suite-mobile-drawer.tsx +35 -22
- package/src/suite/components/suite-notification-bell.tsx +9 -3
- package/src/suite/components/suite-settings-layout.tsx +82 -0
- package/src/suite/components/suite-settings-mobile-nav.tsx +18 -17
- package/src/suite/components/suite-skeleton.tsx +3 -3
- package/src/suite/components/today-calibrating.tsx +11 -35
- package/src/suite/components/today-page-frame.tsx +19 -11
- package/src/suite/components/today-ui.tsx +276 -19
- package/src/suite/index.ts +41 -25
- package/src/suite/lib/apps.ts +32 -2
- package/src/suite/lib/use-sidebar-width.ts +114 -0
- package/src/components/sections/AccordionShowcase.tsx +0 -45
- package/src/components/sections/AlertShowcase.tsx +0 -40
- package/src/components/sections/AvatarShowcase.tsx +0 -80
- package/src/components/sections/BadgeShowcase.tsx +0 -65
- package/src/components/sections/ButtonShowcase.tsx +0 -308
- package/src/components/sections/CalendarShowcase.tsx +0 -35
- package/src/components/sections/CardShowcase.tsx +0 -159
- package/src/components/sections/CodeMockupShowcase.tsx +0 -56
- package/src/components/sections/ColorPalette.tsx +0 -117
- package/src/components/sections/CommandPaletteShowcase.tsx +0 -48
- package/src/components/sections/CountdownShowcase.tsx +0 -43
- package/src/components/sections/DiffShowcase.tsx +0 -70
- package/src/components/sections/DrawerShowcase.tsx +0 -97
- package/src/components/sections/DropdownShowcase.tsx +0 -98
- package/src/components/sections/EmptyStateShowcase.tsx +0 -50
- package/src/components/sections/FilterChipsShowcase.tsx +0 -98
- package/src/components/sections/FormShowcase.tsx +0 -127
- package/src/components/sections/HoverCardShowcase.tsx +0 -50
- package/src/components/sections/IconShowcase.tsx +0 -121
- package/src/components/sections/IndicatorShowcase.tsx +0 -52
- package/src/components/sections/KbdShowcase.tsx +0 -57
- package/src/components/sections/ModalShowcase.tsx +0 -211
- package/src/components/sections/NavigationShowcase.tsx +0 -199
- package/src/components/sections/NewComponentsShowcase.tsx +0 -1052
- package/src/components/sections/ProductLayoutsShowcase.tsx +0 -78
- package/src/components/sections/ProgressShowcase.tsx +0 -82
- package/src/components/sections/QuillChartShowcase.tsx +0 -92
- package/src/components/sections/QuillDashboardShowcase.tsx +0 -149
- package/src/components/sections/SegmentedControlShowcase.tsx +0 -49
- package/src/components/sections/SetupThemeShowcase.tsx +0 -262
- package/src/components/sections/SidebarShowcase.tsx +0 -152
- package/src/components/sections/StackShowcase.tsx +0 -33
- package/src/components/sections/StepperShowcase.tsx +0 -37
- package/src/components/sections/SuiteShowcase.tsx +0 -669
- package/src/components/sections/SwapShowcase.tsx +0 -99
- package/src/components/sections/TabShowcase.tsx +0 -84
- package/src/components/sections/TableShowcase.tsx +0 -142
- package/src/components/sections/TimelineShowcase.tsx +0 -83
- package/src/components/sections/ToastShowcase.tsx +0 -108
- package/src/components/sections/TooltipShowcase.tsx +0 -38
- package/src/components/sections/UtilityShowcase.tsx +0 -81
- package/src/styles/excel-themes.css +0 -110
- package/src/styles/lemon-primitives.css +0 -550
package/dist/suite.mjs
CHANGED
|
@@ -15,24 +15,32 @@ function TodayPageFrame({ children }) {
|
|
|
15
15
|
"div",
|
|
16
16
|
{
|
|
17
17
|
"data-test": "today-page",
|
|
18
|
-
className: "today-page-frame relative flex min-h-0 flex-1 flex-col overflow-
|
|
18
|
+
className: "today-page-frame relative flex min-h-0 w-full flex-1 flex-col overflow-x-hidden",
|
|
19
19
|
children: [
|
|
20
20
|
/* @__PURE__ */ jsxs(
|
|
21
21
|
"div",
|
|
22
22
|
{
|
|
23
|
-
className: "pointer-events-none absolute inset-
|
|
23
|
+
className: "pointer-events-none absolute inset-0 overflow-hidden",
|
|
24
24
|
"aria-hidden": true,
|
|
25
25
|
children: [
|
|
26
26
|
/* @__PURE__ */ jsx("div", { className: "today-page-frame__glow absolute inset-0" }),
|
|
27
|
-
/* @__PURE__ */ jsx("div", { className: "today-page-
|
|
28
|
-
/* @__PURE__ */ jsx("div", { className: "today-page-
|
|
29
|
-
/* @__PURE__ */ jsx("div", { className: "today-page-frame__cloud today-page-frame__cloud--
|
|
30
|
-
/* @__PURE__ */ jsx("div", { className: "today-page-frame__cloud today-page-frame__cloud--
|
|
31
|
-
/* @__PURE__ */ jsx("div", { className: "today-page-frame__cloud today-page-frame__cloud--
|
|
27
|
+
/* @__PURE__ */ jsx("div", { className: "today-page-frame__top-fade absolute inset-x-0 top-0 h-[28rem]" }),
|
|
28
|
+
/* @__PURE__ */ jsx("div", { className: "today-page-frame__cloud today-page-frame__cloud--1 absolute -left-28 top-16 h-96 w-[30rem] rounded-[45%]" }),
|
|
29
|
+
/* @__PURE__ */ jsx("div", { className: "today-page-frame__cloud today-page-frame__cloud--2 absolute -right-24 top-24 h-80 w-[22rem] rounded-[40%]" }),
|
|
30
|
+
/* @__PURE__ */ jsx("div", { className: "today-page-frame__cloud today-page-frame__cloud--3 absolute left-[22%] top-48 h-72 w-[24rem] rounded-[50%]" }),
|
|
31
|
+
/* @__PURE__ */ jsx("div", { className: "today-page-frame__cloud today-page-frame__cloud--4 absolute right-[18%] top-[42%] h-64 w-[20rem] rounded-[48%]" }),
|
|
32
|
+
/* @__PURE__ */ jsx("div", { className: "today-page-frame__cloud today-page-frame__cloud--5 absolute left-[8%] top-[68%] h-56 w-[18rem] rounded-[42%]" })
|
|
32
33
|
]
|
|
33
34
|
}
|
|
34
35
|
),
|
|
35
|
-
/* @__PURE__ */ jsx(
|
|
36
|
+
/* @__PURE__ */ jsx(
|
|
37
|
+
"div",
|
|
38
|
+
{
|
|
39
|
+
"data-width": "full",
|
|
40
|
+
className: "suite-page-stage suite-page-inset relative z-[1] flex w-full min-w-0 flex-1 flex-col [&_.list-row]:min-h-[52px] [&_.list-row]:sm:min-h-[44px]",
|
|
41
|
+
children
|
|
42
|
+
}
|
|
43
|
+
)
|
|
36
44
|
]
|
|
37
45
|
}
|
|
38
46
|
);
|
|
@@ -392,7 +400,7 @@ function SuiteIcon({
|
|
|
392
400
|
}
|
|
393
401
|
|
|
394
402
|
// src/suite/components/today-ui.tsx
|
|
395
|
-
import { jsx as jsx5, jsxs as jsxs5 } from "react/jsx-runtime";
|
|
403
|
+
import { Fragment as Fragment2, jsx as jsx5, jsxs as jsxs5 } from "react/jsx-runtime";
|
|
396
404
|
var APP_META = {
|
|
397
405
|
shellstack: { name: "ShellStack" },
|
|
398
406
|
tides: { name: "Tides" },
|
|
@@ -485,15 +493,15 @@ function AnimatedSun({ className }) {
|
|
|
485
493
|
/* @__PURE__ */ jsx5("stop", { stopColor: "#f59e0b" }),
|
|
486
494
|
/* @__PURE__ */ jsx5("stop", { offset: "1", stopColor: "#fb923c" })
|
|
487
495
|
] }) }),
|
|
488
|
-
/* @__PURE__ */ jsx5("g", { className: "origin-center motion-safe:animate-[
|
|
496
|
+
/* @__PURE__ */ jsx5("g", { className: "origin-center opacity-80 motion-safe:animate-[pulse_8s_ease-in-out_infinite] motion-reduce:animate-none", children: [0, 45, 90, 135, 180, 225, 270, 315].map((angle) => /* @__PURE__ */ jsx5(
|
|
489
497
|
"line",
|
|
490
498
|
{
|
|
491
499
|
x1: "20",
|
|
492
|
-
y1: "
|
|
500
|
+
y1: "5",
|
|
493
501
|
x2: "20",
|
|
494
502
|
y2: "9",
|
|
495
503
|
stroke: "#fbbf24",
|
|
496
|
-
strokeWidth: "
|
|
504
|
+
strokeWidth: "1.75",
|
|
497
505
|
strokeLinecap: "round",
|
|
498
506
|
transform: `rotate(${angle} 20 20)`
|
|
499
507
|
},
|
|
@@ -527,10 +535,9 @@ function AnimatedMoon({ className }) {
|
|
|
527
535
|
fill: "url(#animatedMoonBody)"
|
|
528
536
|
}
|
|
529
537
|
),
|
|
530
|
-
/* @__PURE__ */ jsxs5("g", { className: "motion-safe:animate-[
|
|
531
|
-
/* @__PURE__ */ jsx5("circle", { cx: "29", cy: "10", r: "1.
|
|
532
|
-
/* @__PURE__ */ jsx5("circle", { cx: "34", cy: "16", r: "
|
|
533
|
-
/* @__PURE__ */ jsx5("circle", { cx: "25", cy: "5.5", r: "0.9", fill: "#c7d2fe" })
|
|
538
|
+
/* @__PURE__ */ jsxs5("g", { className: "opacity-70 motion-safe:animate-[pulse_10s_ease-in-out_infinite] motion-reduce:animate-none", children: [
|
|
539
|
+
/* @__PURE__ */ jsx5("circle", { cx: "29", cy: "10", r: "1.2", fill: "#c7d2fe" }),
|
|
540
|
+
/* @__PURE__ */ jsx5("circle", { cx: "34", cy: "16", r: "0.9", fill: "#c7d2fe" })
|
|
534
541
|
] })
|
|
535
542
|
]
|
|
536
543
|
}
|
|
@@ -592,30 +599,193 @@ function getTodayGreeting(user, stats) {
|
|
|
592
599
|
const overdueCount = (_d = stats == null ? void 0 : stats.overdueCount) != null ? _d : 0;
|
|
593
600
|
const hours = (_e = stats == null ? void 0 : stats.hours) != null ? _e : 0;
|
|
594
601
|
if (overdueCount > 0) {
|
|
595
|
-
return `${greeting}.
|
|
602
|
+
return `${greeting}. ${taskCount} task${taskCount === 1 ? "" : "s"} due today, ${overdueCount} overdue.`;
|
|
596
603
|
}
|
|
597
604
|
if (taskCount > 0) {
|
|
598
|
-
return `${greeting}.
|
|
605
|
+
return `${greeting}. ${taskCount} task${taskCount === 1 ? "" : "s"} due today.`;
|
|
599
606
|
}
|
|
600
607
|
if (hours > 0) {
|
|
601
|
-
return `${greeting}.
|
|
608
|
+
return `${greeting}. ${hours} hour${hours === 1 ? "" : "s"} logged today.`;
|
|
602
609
|
}
|
|
603
610
|
if (period === "evening" || period === "night") {
|
|
604
|
-
return `${greeting}.
|
|
611
|
+
return `${greeting}. Nice work \u2014 time to wrap up.`;
|
|
605
612
|
}
|
|
606
|
-
return `${greeting}.
|
|
613
|
+
return `${greeting}. Clear queue \u2014 take a nice, deep breath.`;
|
|
607
614
|
}
|
|
608
615
|
function TodayHero({
|
|
609
|
-
message = "Take a nice, deep breath."
|
|
616
|
+
message = "Take a nice, deep breath.",
|
|
617
|
+
brief,
|
|
618
|
+
briefMeta
|
|
619
|
+
}) {
|
|
620
|
+
return /* @__PURE__ */ jsxs5("div", { className: "mt-4 sm:mt-6", children: [
|
|
621
|
+
/* @__PURE__ */ jsx5(
|
|
622
|
+
"p",
|
|
623
|
+
{
|
|
624
|
+
className: "today-hero max-w-2xl font-display text-lg font-semibold tracking-tight text-ph-ink sm:text-xl sm:leading-snug",
|
|
625
|
+
children: message
|
|
626
|
+
},
|
|
627
|
+
typeof message === "string" ? message : "hero"
|
|
628
|
+
),
|
|
629
|
+
brief ? /* @__PURE__ */ jsxs5("div", { className: "mt-4 max-w-2xl", "data-test": "today-focus-brief", children: [
|
|
630
|
+
/* @__PURE__ */ jsx5("p", { className: "text-[15px] leading-[1.65] text-ph-ink", children: brief }),
|
|
631
|
+
briefMeta ? /* @__PURE__ */ jsx5("p", { className: "mt-1.5 text-xs text-ph-mutedtext", children: briefMeta }) : null
|
|
632
|
+
] }) : null
|
|
633
|
+
] });
|
|
634
|
+
}
|
|
635
|
+
function TodayPrimaryAction({
|
|
636
|
+
label,
|
|
637
|
+
description,
|
|
638
|
+
icon,
|
|
639
|
+
accent = "neutral",
|
|
640
|
+
onClick,
|
|
641
|
+
href,
|
|
642
|
+
loading = false,
|
|
643
|
+
active = false,
|
|
644
|
+
className,
|
|
645
|
+
dataTest = "today-primary-action"
|
|
610
646
|
}) {
|
|
611
|
-
|
|
612
|
-
"
|
|
647
|
+
const classes = cn(
|
|
648
|
+
"today-primary-action group relative flex w-full max-w-md items-center gap-3 overflow-hidden rounded-xl px-3.5 py-2.5 text-left transition sm:px-4 sm:py-3",
|
|
649
|
+
`today-primary-action--${accent}`,
|
|
650
|
+
active && "today-primary-action--active",
|
|
651
|
+
loading && "pointer-events-none opacity-70",
|
|
652
|
+
className
|
|
653
|
+
);
|
|
654
|
+
const body = /* @__PURE__ */ jsxs5(Fragment2, { children: [
|
|
655
|
+
/* @__PURE__ */ jsx5("span", { className: "today-primary-action__icon inline-flex h-9 w-9 shrink-0 items-center justify-center rounded-lg sm:h-10 sm:w-10", children: icon }),
|
|
656
|
+
/* @__PURE__ */ jsxs5("span", { className: "min-w-0 flex-1", children: [
|
|
657
|
+
/* @__PURE__ */ jsx5("span", { className: "block text-sm font-semibold tracking-tight sm:text-base", children: label }),
|
|
658
|
+
description ? /* @__PURE__ */ jsx5("span", { className: "mt-0.5 block text-xs opacity-80 sm:text-sm", children: description }) : null
|
|
659
|
+
] }),
|
|
660
|
+
/* @__PURE__ */ jsx5(
|
|
661
|
+
"span",
|
|
662
|
+
{
|
|
663
|
+
className: "today-primary-action__chevron shrink-0 text-base opacity-60 transition group-hover:translate-x-0.5 group-hover:opacity-100",
|
|
664
|
+
"aria-hidden": true,
|
|
665
|
+
children: "\u2192"
|
|
666
|
+
}
|
|
667
|
+
)
|
|
668
|
+
] });
|
|
669
|
+
if (href && !onClick) {
|
|
670
|
+
return /* @__PURE__ */ jsx5(
|
|
671
|
+
"a",
|
|
672
|
+
{
|
|
673
|
+
href,
|
|
674
|
+
className: classes,
|
|
675
|
+
"data-test": dataTest,
|
|
676
|
+
"aria-busy": loading,
|
|
677
|
+
children: body
|
|
678
|
+
}
|
|
679
|
+
);
|
|
680
|
+
}
|
|
681
|
+
return /* @__PURE__ */ jsx5(
|
|
682
|
+
"button",
|
|
613
683
|
{
|
|
614
|
-
|
|
615
|
-
|
|
616
|
-
|
|
617
|
-
|
|
618
|
-
|
|
684
|
+
type: "button",
|
|
685
|
+
onClick,
|
|
686
|
+
disabled: loading,
|
|
687
|
+
className: classes,
|
|
688
|
+
"data-test": dataTest,
|
|
689
|
+
"aria-busy": loading,
|
|
690
|
+
children: body
|
|
691
|
+
}
|
|
692
|
+
);
|
|
693
|
+
}
|
|
694
|
+
function TodayEmptyAction({
|
|
695
|
+
title,
|
|
696
|
+
description,
|
|
697
|
+
actionLabel,
|
|
698
|
+
href,
|
|
699
|
+
onClick,
|
|
700
|
+
dataTest
|
|
701
|
+
}) {
|
|
702
|
+
return /* @__PURE__ */ jsxs5(
|
|
703
|
+
"div",
|
|
704
|
+
{
|
|
705
|
+
className: "rounded-lg border border-dashed border-ph-border/80 bg-ph-muted/30 px-4 py-4 text-center",
|
|
706
|
+
"data-test": dataTest,
|
|
707
|
+
children: [
|
|
708
|
+
/* @__PURE__ */ jsx5("p", { className: "text-sm font-semibold text-ph-ink", children: title }),
|
|
709
|
+
description ? /* @__PURE__ */ jsx5("p", { className: "mx-auto mt-1 max-w-sm text-xs leading-relaxed text-ph-subtle sm:text-sm", children: description }) : null,
|
|
710
|
+
actionLabel && (href || onClick) ? href ? /* @__PURE__ */ jsx5(
|
|
711
|
+
"a",
|
|
712
|
+
{
|
|
713
|
+
href,
|
|
714
|
+
className: "mt-2.5 inline-flex text-sm font-semibold text-ph-brand hover:underline",
|
|
715
|
+
children: actionLabel
|
|
716
|
+
}
|
|
717
|
+
) : /* @__PURE__ */ jsx5(
|
|
718
|
+
"button",
|
|
719
|
+
{
|
|
720
|
+
type: "button",
|
|
721
|
+
onClick,
|
|
722
|
+
className: "mt-2.5 inline-flex text-sm font-semibold text-ph-brand hover:underline",
|
|
723
|
+
children: actionLabel
|
|
724
|
+
}
|
|
725
|
+
) : null
|
|
726
|
+
]
|
|
727
|
+
}
|
|
728
|
+
);
|
|
729
|
+
}
|
|
730
|
+
function TodayLayout({
|
|
731
|
+
primary,
|
|
732
|
+
main,
|
|
733
|
+
aside,
|
|
734
|
+
className
|
|
735
|
+
}) {
|
|
736
|
+
return /* @__PURE__ */ jsxs5(
|
|
737
|
+
"div",
|
|
738
|
+
{
|
|
739
|
+
className: cn("mt-5 space-y-6 sm:mt-6", className),
|
|
740
|
+
"data-test": "today-layout",
|
|
741
|
+
children: [
|
|
742
|
+
primary ? /* @__PURE__ */ jsx5("div", { className: "max-w-md", children: primary }) : null,
|
|
743
|
+
/* @__PURE__ */ jsxs5("div", { className: "grid gap-6 lg:grid-cols-[minmax(0,1fr)_minmax(16rem,20rem)] lg:items-start lg:gap-8", children: [
|
|
744
|
+
/* @__PURE__ */ jsx5("div", { className: "min-w-0 space-y-8", children: main }),
|
|
745
|
+
aside ? /* @__PURE__ */ jsx5("aside", { className: "space-y-3 lg:sticky lg:top-6 lg:self-start", children: aside }) : null
|
|
746
|
+
] })
|
|
747
|
+
]
|
|
748
|
+
}
|
|
749
|
+
);
|
|
750
|
+
}
|
|
751
|
+
function TodayAskAiCard({
|
|
752
|
+
title = "Ask AI",
|
|
753
|
+
description = "Ask about your workspace, draft something, or look a fact up online.",
|
|
754
|
+
cta = "Ask",
|
|
755
|
+
className,
|
|
756
|
+
onClick,
|
|
757
|
+
href
|
|
758
|
+
}) {
|
|
759
|
+
const classes = cn(
|
|
760
|
+
"group flex w-full items-start gap-3.5 rounded-2xl border border-ph-border/70 bg-ph-surface px-4 py-3.5 text-left shadow-[0_1px_12px_-8px_rgba(15,23,42,0.1)] transition hover:border-ph-brand/35 hover:bg-[color-mix(in_oklab,var(--ph-accent)_6%,var(--ph-surface))] sm:px-5",
|
|
761
|
+
className
|
|
762
|
+
);
|
|
763
|
+
const body = /* @__PURE__ */ jsxs5(Fragment2, { children: [
|
|
764
|
+
/* @__PURE__ */ jsx5("span", { className: "inline-flex h-10 w-10 shrink-0 items-center justify-center rounded-2xl bg-ph-brand/15 text-ph-brand shadow-sm ring-1 ring-black/[0.06]", children: /* @__PURE__ */ jsx5(SuiteIcon, { name: "stack-hex", accent: "shellstack", className: "h-5 w-5" }) }),
|
|
765
|
+
/* @__PURE__ */ jsxs5("span", { className: "min-w-0 flex-1", children: [
|
|
766
|
+
/* @__PURE__ */ jsxs5("span", { className: "flex flex-wrap items-baseline justify-between gap-x-3 gap-y-1", children: [
|
|
767
|
+
/* @__PURE__ */ jsx5("span", { className: "font-display text-sm font-bold tracking-tight text-ph-ink", children: title }),
|
|
768
|
+
/* @__PURE__ */ jsx5("span", { className: "text-sm font-medium text-ph-brand transition group-hover:underline", children: cta })
|
|
769
|
+
] }),
|
|
770
|
+
/* @__PURE__ */ jsx5("span", { className: "mt-1 block text-sm leading-relaxed text-ph-subtle", children: description })
|
|
771
|
+
] })
|
|
772
|
+
] });
|
|
773
|
+
if (onClick) {
|
|
774
|
+
return /* @__PURE__ */ jsx5(
|
|
775
|
+
"button",
|
|
776
|
+
{
|
|
777
|
+
type: "button",
|
|
778
|
+
onClick,
|
|
779
|
+
className: classes,
|
|
780
|
+
"data-test": "today-ask-ai",
|
|
781
|
+
children: body
|
|
782
|
+
}
|
|
783
|
+
);
|
|
784
|
+
}
|
|
785
|
+
if (href) {
|
|
786
|
+
return /* @__PURE__ */ jsx5("a", { href, className: classes, "data-test": "today-ask-ai", children: body });
|
|
787
|
+
}
|
|
788
|
+
return /* @__PURE__ */ jsx5("div", { className: classes, "data-test": "today-ask-ai", children: body });
|
|
619
789
|
}
|
|
620
790
|
function TodaySection({
|
|
621
791
|
icon: Icon,
|
|
@@ -626,7 +796,7 @@ function TodaySection({
|
|
|
626
796
|
testId,
|
|
627
797
|
children
|
|
628
798
|
}) {
|
|
629
|
-
return /* @__PURE__ */ jsxs5("section", { "data-test": testId, className: "space-y-
|
|
799
|
+
return /* @__PURE__ */ jsxs5("section", { "data-test": testId, className: "space-y-5", children: [
|
|
630
800
|
/* @__PURE__ */ jsxs5("div", { className: "flex items-start justify-between gap-4", children: [
|
|
631
801
|
/* @__PURE__ */ jsxs5("div", { className: "flex min-w-0 items-start gap-3.5", children: [
|
|
632
802
|
/* @__PURE__ */ jsx5(
|
|
@@ -657,8 +827,7 @@ function TodayPanel({
|
|
|
657
827
|
"div",
|
|
658
828
|
{
|
|
659
829
|
className: cn(
|
|
660
|
-
"border-ph-border/70 rounded-2xl border bg-ph-surface p-
|
|
661
|
-
"hover:shadow-[0_8px_32px_-12px_rgba(15,23,42,0.18)] hover:-translate-y-0.5 motion-reduce:transition-none motion-reduce:hover:transform-none",
|
|
830
|
+
"border-ph-border/70 rounded-2xl border bg-ph-surface p-5 shadow-[0_1px_16px_-8px_rgba(15,23,42,0.12)] sm:p-5",
|
|
662
831
|
className
|
|
663
832
|
),
|
|
664
833
|
children
|
|
@@ -836,6 +1005,70 @@ function AppSwitcher({
|
|
|
836
1005
|
import { useCallback, useEffect, useState as useState2 } from "react";
|
|
837
1006
|
import { useRouter } from "next/navigation";
|
|
838
1007
|
import { Bell } from "iconoir-react";
|
|
1008
|
+
|
|
1009
|
+
// src/suite/lib/apps.ts
|
|
1010
|
+
var SUITE_APPS2 = [
|
|
1011
|
+
{
|
|
1012
|
+
slug: "shellstack",
|
|
1013
|
+
name: "ShellStack",
|
|
1014
|
+
description: "Organisation and billing",
|
|
1015
|
+
icon: "/icon-shellstack.svg",
|
|
1016
|
+
landing: "/home",
|
|
1017
|
+
baseUrlEnv: "NEXT_PUBLIC_SHELLSTACK_URL",
|
|
1018
|
+
baseUrlFallback: "http://localhost:3002"
|
|
1019
|
+
},
|
|
1020
|
+
{
|
|
1021
|
+
slug: "tides",
|
|
1022
|
+
name: "Tides",
|
|
1023
|
+
description: "Projects and tasks",
|
|
1024
|
+
icon: "/tides-icon.svg",
|
|
1025
|
+
landing: "/today",
|
|
1026
|
+
baseUrlEnv: "NEXT_PUBLIC_TIDES_URL",
|
|
1027
|
+
baseUrlFallback: "http://localhost:3001"
|
|
1028
|
+
},
|
|
1029
|
+
{
|
|
1030
|
+
slug: "turtletime",
|
|
1031
|
+
name: "TurtleTime",
|
|
1032
|
+
description: "Time tracking",
|
|
1033
|
+
icon: "/turtletime-icon.svg",
|
|
1034
|
+
landing: "/today",
|
|
1035
|
+
baseUrlEnv: "NEXT_PUBLIC_TURTLETIME_URL",
|
|
1036
|
+
baseUrlFallback: "http://localhost:3000"
|
|
1037
|
+
},
|
|
1038
|
+
{
|
|
1039
|
+
slug: "kraken",
|
|
1040
|
+
name: "Kraken",
|
|
1041
|
+
description: "Documents and knowledge",
|
|
1042
|
+
icon: "/kraken-icon.svg",
|
|
1043
|
+
landing: "/today",
|
|
1044
|
+
baseUrlEnv: "NEXT_PUBLIC_KRAKEN_URL",
|
|
1045
|
+
baseUrlFallback: "http://localhost:3003"
|
|
1046
|
+
}
|
|
1047
|
+
];
|
|
1048
|
+
var SUITE_APP_MAP = Object.fromEntries(SUITE_APPS2.map((app) => [app.slug, app]));
|
|
1049
|
+
function suiteAppBaseUrl(slug) {
|
|
1050
|
+
const def = SUITE_APP_MAP[slug];
|
|
1051
|
+
const fromEnv = typeof process !== "undefined" ? process.env[def.baseUrlEnv] : void 0;
|
|
1052
|
+
return (fromEnv || def.baseUrlFallback).replace(/\/$/, "");
|
|
1053
|
+
}
|
|
1054
|
+
var SOURCE_APP_SLUG = {
|
|
1055
|
+
turtletime: "turtletime",
|
|
1056
|
+
tides: "tides",
|
|
1057
|
+
kraken: "kraken",
|
|
1058
|
+
portal: "shellstack",
|
|
1059
|
+
shellstack: "shellstack"
|
|
1060
|
+
};
|
|
1061
|
+
function resolveSuiteNotificationHref(href, sourceApp) {
|
|
1062
|
+
const value = (href || "").trim();
|
|
1063
|
+
if (!value) return "";
|
|
1064
|
+
if (/^(https?:|mailto:|\/\/)/i.test(value)) return value;
|
|
1065
|
+
const path = value.startsWith("/") ? value : `/${value}`;
|
|
1066
|
+
const slug = SOURCE_APP_SLUG[(sourceApp || "").toLowerCase()];
|
|
1067
|
+
if (!slug) return path;
|
|
1068
|
+
return `${suiteAppBaseUrl(slug)}${path}`;
|
|
1069
|
+
}
|
|
1070
|
+
|
|
1071
|
+
// src/suite/components/suite-notification-bell.tsx
|
|
839
1072
|
import { jsx as jsx7, jsxs as jsxs7 } from "react/jsx-runtime";
|
|
840
1073
|
var POLL_MS = 6e4;
|
|
841
1074
|
function timeAgo(iso) {
|
|
@@ -926,9 +1159,13 @@ function SuiteNotificationBell({
|
|
|
926
1159
|
} catch (e) {
|
|
927
1160
|
}
|
|
928
1161
|
}
|
|
929
|
-
|
|
930
|
-
if (
|
|
931
|
-
|
|
1162
|
+
const target = resolveSuiteNotificationHref(n.href, n.source_app);
|
|
1163
|
+
if (!target) return;
|
|
1164
|
+
if (/^https?:\/\//i.test(target)) {
|
|
1165
|
+
window.location.assign(target);
|
|
1166
|
+
return;
|
|
1167
|
+
}
|
|
1168
|
+
router.push(target);
|
|
932
1169
|
},
|
|
933
1170
|
[router, markRead]
|
|
934
1171
|
);
|
|
@@ -1064,11 +1301,11 @@ function useIdleMount(timeoutMs = 1200) {
|
|
|
1064
1301
|
}
|
|
1065
1302
|
|
|
1066
1303
|
// src/suite/components/deferred-chrome.tsx
|
|
1067
|
-
import { Fragment as
|
|
1304
|
+
import { Fragment as Fragment3, jsx as jsx9 } from "react/jsx-runtime";
|
|
1068
1305
|
function DeferredChrome({ children }) {
|
|
1069
1306
|
const ready = useIdleMount();
|
|
1070
1307
|
if (!ready) return null;
|
|
1071
|
-
return /* @__PURE__ */ jsx9(
|
|
1308
|
+
return /* @__PURE__ */ jsx9(Fragment3, { children });
|
|
1072
1309
|
}
|
|
1073
1310
|
|
|
1074
1311
|
// src/suite/components/suite-mobile-drawer.tsx
|
|
@@ -1081,6 +1318,7 @@ function SuiteMobileDrawer({
|
|
|
1081
1318
|
children,
|
|
1082
1319
|
side = "left",
|
|
1083
1320
|
showCloseButton = false,
|
|
1321
|
+
title,
|
|
1084
1322
|
closeLabel = "Close navigation",
|
|
1085
1323
|
backdropLabel = "Close navigation",
|
|
1086
1324
|
dialogLabel = "Navigation",
|
|
@@ -1158,23 +1396,35 @@ function SuiteMobileDrawer({
|
|
|
1158
1396
|
tabIndex: -1,
|
|
1159
1397
|
"data-test": panelDataTest,
|
|
1160
1398
|
className: cn(
|
|
1161
|
-
"suite-scroll-lock relative flex h-full w-[86%] max-w-
|
|
1399
|
+
"suite-scroll-lock relative flex h-full w-[86%] max-w-72 flex-col overflow-hidden bg-ph-surface shadow-xl outline-none motion-safe:transition-transform motion-safe:ease-spring-fast",
|
|
1162
1400
|
side === "right" && "ml-auto",
|
|
1163
1401
|
shown ? "translate-x-0" : side === "right" ? "translate-x-full" : "-translate-x-full",
|
|
1164
1402
|
panelClassName
|
|
1165
1403
|
),
|
|
1166
1404
|
style: { transitionDuration: `${durationMs}ms` },
|
|
1167
1405
|
children: [
|
|
1168
|
-
showCloseButton ? /* @__PURE__ */
|
|
1169
|
-
"
|
|
1406
|
+
showCloseButton ? /* @__PURE__ */ jsxs8(
|
|
1407
|
+
"div",
|
|
1170
1408
|
{
|
|
1171
|
-
|
|
1172
|
-
|
|
1173
|
-
|
|
1174
|
-
|
|
1175
|
-
children:
|
|
1409
|
+
className: cn(
|
|
1410
|
+
"flex h-14 shrink-0 items-center border-b border-ph-border px-3",
|
|
1411
|
+
title ? "justify-between" : "justify-end"
|
|
1412
|
+
),
|
|
1413
|
+
children: [
|
|
1414
|
+
title ? /* @__PURE__ */ jsx10("span", { className: "truncate text-sm font-semibold text-ph-ink", children: title }) : null,
|
|
1415
|
+
/* @__PURE__ */ jsx10(
|
|
1416
|
+
"button",
|
|
1417
|
+
{
|
|
1418
|
+
type: "button",
|
|
1419
|
+
onClick: onClose,
|
|
1420
|
+
className: "-mr-1.5 inline-flex h-11 w-11 items-center justify-center rounded-lg text-ph-mutedtext transition-colors hover:bg-ph-muted hover:text-ph-ink focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-ph-brand",
|
|
1421
|
+
"aria-label": closeLabel,
|
|
1422
|
+
children: /* @__PURE__ */ jsx10(X, { className: "h-4 w-4", "aria-hidden": true })
|
|
1423
|
+
}
|
|
1424
|
+
)
|
|
1425
|
+
]
|
|
1176
1426
|
}
|
|
1177
|
-
)
|
|
1427
|
+
) : null,
|
|
1178
1428
|
children
|
|
1179
1429
|
]
|
|
1180
1430
|
}
|
|
@@ -1231,74 +1481,361 @@ function SuiteMobileHeader({
|
|
|
1231
1481
|
);
|
|
1232
1482
|
}
|
|
1233
1483
|
|
|
1234
|
-
// src/suite/components/suite-
|
|
1235
|
-
import
|
|
1236
|
-
|
|
1237
|
-
|
|
1484
|
+
// src/suite/components/suite-layout.tsx
|
|
1485
|
+
import {
|
|
1486
|
+
useEffect as useEffect5,
|
|
1487
|
+
useRef as useRef2,
|
|
1488
|
+
useState as useState6
|
|
1489
|
+
} from "react";
|
|
1238
1490
|
import { jsx as jsx12, jsxs as jsxs10 } from "react/jsx-runtime";
|
|
1239
|
-
function
|
|
1240
|
-
|
|
1241
|
-
|
|
1491
|
+
function SuiteBreadcrumbs({ items, className }) {
|
|
1492
|
+
return /* @__PURE__ */ jsx12("nav", { "aria-label": "Breadcrumb", className, children: /* @__PURE__ */ jsx12("ol", { className: "flex min-w-0 items-center gap-1.5", children: items.map((item, index) => {
|
|
1493
|
+
const isLast = index === items.length - 1;
|
|
1494
|
+
return /* @__PURE__ */ jsxs10("li", { className: "flex min-w-0 items-center gap-1.5", children: [
|
|
1495
|
+
index > 0 ? /* @__PURE__ */ jsx12("span", { className: "select-none text-ph-border", "aria-hidden": "true", children: "/" }) : null,
|
|
1496
|
+
item.href && !isLast ? /* @__PURE__ */ jsx12(
|
|
1497
|
+
"a",
|
|
1498
|
+
{
|
|
1499
|
+
href: item.href,
|
|
1500
|
+
className: "truncate transition hover:text-ph-ink",
|
|
1501
|
+
children: item.label
|
|
1502
|
+
}
|
|
1503
|
+
) : /* @__PURE__ */ jsx12(
|
|
1504
|
+
"span",
|
|
1505
|
+
{
|
|
1506
|
+
className: cn(
|
|
1507
|
+
"truncate",
|
|
1508
|
+
isLast ? "font-medium text-ph-ink" : "text-ph-subtle"
|
|
1509
|
+
),
|
|
1510
|
+
"aria-current": isLast ? "page" : void 0,
|
|
1511
|
+
children: item.label
|
|
1512
|
+
}
|
|
1513
|
+
)
|
|
1514
|
+
] }, index);
|
|
1515
|
+
}) }) });
|
|
1242
1516
|
}
|
|
1243
|
-
function
|
|
1244
|
-
|
|
1245
|
-
|
|
1246
|
-
|
|
1247
|
-
|
|
1248
|
-
|
|
1249
|
-
|
|
1250
|
-
|
|
1251
|
-
|
|
1517
|
+
function SuitePage({
|
|
1518
|
+
children,
|
|
1519
|
+
width = "full",
|
|
1520
|
+
inset = true,
|
|
1521
|
+
className,
|
|
1522
|
+
as: Component = "div",
|
|
1523
|
+
dataTest,
|
|
1524
|
+
id,
|
|
1525
|
+
role,
|
|
1526
|
+
"aria-live": ariaLive
|
|
1252
1527
|
}) {
|
|
1253
|
-
|
|
1254
|
-
|
|
1255
|
-
const avatar = /* @__PURE__ */ jsx12("span", { className: "inline-flex h-11 w-11 items-center justify-center rounded-full transition-colors hover:bg-ph-muted", children: image ? /* @__PURE__ */ jsx12(
|
|
1256
|
-
Image2,
|
|
1528
|
+
return /* @__PURE__ */ jsx12(
|
|
1529
|
+
Component,
|
|
1257
1530
|
{
|
|
1258
|
-
|
|
1259
|
-
|
|
1260
|
-
width:
|
|
1261
|
-
|
|
1262
|
-
|
|
1263
|
-
|
|
1531
|
+
id,
|
|
1532
|
+
"data-test": dataTest,
|
|
1533
|
+
"data-width": width,
|
|
1534
|
+
role,
|
|
1535
|
+
"aria-live": ariaLive,
|
|
1536
|
+
className: cn(
|
|
1537
|
+
"suite-page-stage flex w-full min-w-0 flex-col",
|
|
1538
|
+
inset && "suite-page-inset",
|
|
1539
|
+
className
|
|
1540
|
+
),
|
|
1541
|
+
children
|
|
1542
|
+
}
|
|
1543
|
+
);
|
|
1544
|
+
}
|
|
1545
|
+
function SuitePageHeader({
|
|
1546
|
+
title,
|
|
1547
|
+
description,
|
|
1548
|
+
eyebrow,
|
|
1549
|
+
actions,
|
|
1550
|
+
className,
|
|
1551
|
+
titleClassName,
|
|
1552
|
+
dataTest,
|
|
1553
|
+
/** Optional icon rendered before the title. */
|
|
1554
|
+
icon,
|
|
1555
|
+
/** Use the animated sun/moon icon from the Today page. */
|
|
1556
|
+
todayIcon,
|
|
1557
|
+
todayIconClassName,
|
|
1558
|
+
/** Small badge/pill next to the title (e.g. "Beta", org name). */
|
|
1559
|
+
badge,
|
|
1560
|
+
/** Breadcrumb line rendered above the title. */
|
|
1561
|
+
breadcrumb,
|
|
1562
|
+
/** Stick to the top of the scrollport (desktop page titles). */
|
|
1563
|
+
sticky = false
|
|
1564
|
+
}) {
|
|
1565
|
+
const headerRef = useRef2(null);
|
|
1566
|
+
const [stuck, setStuck] = useState6(false);
|
|
1567
|
+
useEffect5(() => {
|
|
1568
|
+
var _a;
|
|
1569
|
+
if (!sticky) return;
|
|
1570
|
+
const el = headerRef.current;
|
|
1571
|
+
if (!el) return;
|
|
1572
|
+
const sentinel = document.createElement("div");
|
|
1573
|
+
sentinel.setAttribute("aria-hidden", "true");
|
|
1574
|
+
sentinel.style.cssText = "position:relative;height:1px;width:100%;margin:0;padding:0;pointer-events:none";
|
|
1575
|
+
(_a = el.parentElement) == null ? void 0 : _a.insertBefore(sentinel, el);
|
|
1576
|
+
const observer = new IntersectionObserver(
|
|
1577
|
+
([entry]) => {
|
|
1578
|
+
setStuck(!entry.isIntersecting);
|
|
1579
|
+
},
|
|
1580
|
+
{ threshold: [1], root: null }
|
|
1581
|
+
);
|
|
1582
|
+
observer.observe(sentinel);
|
|
1583
|
+
return () => {
|
|
1584
|
+
observer.disconnect();
|
|
1585
|
+
sentinel.remove();
|
|
1586
|
+
};
|
|
1587
|
+
}, [sticky]);
|
|
1588
|
+
const resolvedIcon = todayIcon ? /* @__PURE__ */ jsx12(
|
|
1589
|
+
TodayTimeIcon,
|
|
1590
|
+
{
|
|
1591
|
+
className: cn(
|
|
1592
|
+
"h-7 w-7 text-amber-500 sm:h-8 sm:w-8",
|
|
1593
|
+
todayIconClassName
|
|
1594
|
+
)
|
|
1264
1595
|
}
|
|
1265
|
-
) :
|
|
1596
|
+
) : icon;
|
|
1266
1597
|
return /* @__PURE__ */ jsxs10(
|
|
1267
|
-
|
|
1598
|
+
"header",
|
|
1268
1599
|
{
|
|
1269
|
-
|
|
1270
|
-
"aria-label": "Account menu",
|
|
1271
|
-
align: "end",
|
|
1272
|
-
side: "bottom",
|
|
1273
|
-
sideOffset: 6,
|
|
1274
|
-
collisionPadding: 16,
|
|
1275
|
-
modal: false,
|
|
1276
|
-
className,
|
|
1600
|
+
ref: headerRef,
|
|
1277
1601
|
"data-test": dataTest,
|
|
1602
|
+
"data-stuck": sticky ? stuck ? "true" : "false" : void 0,
|
|
1603
|
+
className: cn(
|
|
1604
|
+
"flex items-start justify-between gap-4 pb-2 sm:pb-3",
|
|
1605
|
+
// No extra pt here — page inset sets the shared title baseline.
|
|
1606
|
+
// Stuck state adds pad via .suite-page-header-sticky[data-stuck].
|
|
1607
|
+
sticky && "suite-page-header-sticky",
|
|
1608
|
+
className
|
|
1609
|
+
),
|
|
1278
1610
|
children: [
|
|
1279
|
-
/* @__PURE__ */ jsxs10("div", { className: "
|
|
1280
|
-
/* @__PURE__ */ jsx12("
|
|
1281
|
-
|
|
1282
|
-
|
|
1283
|
-
|
|
1284
|
-
|
|
1285
|
-
|
|
1286
|
-
|
|
1287
|
-
|
|
1288
|
-
|
|
1611
|
+
/* @__PURE__ */ jsxs10("div", { className: "min-w-0 flex-1", children: [
|
|
1612
|
+
eyebrow ? /* @__PURE__ */ jsx12("div", { className: "mb-0.5 flex min-w-0 items-center gap-1.5 text-xs text-ph-subtle", children: eyebrow }) : null,
|
|
1613
|
+
breadcrumb ? /* @__PURE__ */ jsx12("div", { className: "mb-0.5 flex min-w-0 items-center gap-1.5 text-xs text-ph-subtle", children: breadcrumb }) : null,
|
|
1614
|
+
/* @__PURE__ */ jsxs10("div", { className: "flex min-w-0 items-center gap-3", children: [
|
|
1615
|
+
resolvedIcon ? /* @__PURE__ */ jsx12(
|
|
1616
|
+
"div",
|
|
1617
|
+
{
|
|
1618
|
+
className: "hidden shrink-0 sm:flex sm:items-center [&_svg]:h-7 [&_svg]:w-7 sm:[&_svg]:h-8 sm:[&_svg]:w-8",
|
|
1619
|
+
"aria-hidden": "true",
|
|
1620
|
+
children: resolvedIcon
|
|
1621
|
+
}
|
|
1622
|
+
) : null,
|
|
1623
|
+
/* @__PURE__ */ jsxs10("div", { className: "flex min-w-0 flex-wrap items-center gap-x-2 gap-y-1", children: [
|
|
1624
|
+
/* @__PURE__ */ jsx12(
|
|
1625
|
+
"h1",
|
|
1626
|
+
{
|
|
1627
|
+
className: cn(
|
|
1628
|
+
"font-display text-[1.625rem] font-bold leading-none tracking-tight text-ph-ink sm:text-[2.25rem]",
|
|
1629
|
+
titleClassName
|
|
1630
|
+
),
|
|
1631
|
+
children: title
|
|
1632
|
+
}
|
|
1633
|
+
),
|
|
1634
|
+
badge ? /* @__PURE__ */ jsx12("span", { className: "rounded-md bg-ph-muted px-2 py-0.5 text-[11px] font-semibold uppercase tracking-wide text-ph-subtle", children: badge }) : null
|
|
1635
|
+
] })
|
|
1636
|
+
] }),
|
|
1637
|
+
description ? /* @__PURE__ */ jsx12(
|
|
1638
|
+
"div",
|
|
1639
|
+
{
|
|
1640
|
+
className: cn(
|
|
1641
|
+
"mt-1.5 max-w-2xl text-pretty text-sm leading-5 text-ph-subtle",
|
|
1642
|
+
resolvedIcon && "sm:pl-11"
|
|
1643
|
+
),
|
|
1644
|
+
children: description
|
|
1645
|
+
}
|
|
1646
|
+
) : null
|
|
1647
|
+
] }),
|
|
1648
|
+
actions ? /* @__PURE__ */ jsx12("div", { className: "flex shrink-0 items-center gap-2 self-center", children: actions }) : null
|
|
1649
|
+
]
|
|
1650
|
+
}
|
|
1651
|
+
);
|
|
1652
|
+
}
|
|
1653
|
+
function SuiteToolbar({
|
|
1654
|
+
children,
|
|
1655
|
+
className,
|
|
1656
|
+
label = "Page tools",
|
|
1657
|
+
dataTest
|
|
1658
|
+
}) {
|
|
1659
|
+
return /* @__PURE__ */ jsx12(
|
|
1660
|
+
"div",
|
|
1661
|
+
{
|
|
1662
|
+
role: "toolbar",
|
|
1663
|
+
"aria-label": label,
|
|
1664
|
+
"data-test": dataTest,
|
|
1665
|
+
className: cn("flex min-w-0 flex-wrap items-center gap-2", className),
|
|
1666
|
+
children
|
|
1667
|
+
}
|
|
1668
|
+
);
|
|
1669
|
+
}
|
|
1670
|
+
function SuiteTabList({
|
|
1671
|
+
children,
|
|
1672
|
+
className,
|
|
1673
|
+
label,
|
|
1674
|
+
dataTest
|
|
1675
|
+
}) {
|
|
1676
|
+
return /* @__PURE__ */ jsx12(
|
|
1677
|
+
"nav",
|
|
1678
|
+
{
|
|
1679
|
+
"aria-label": label,
|
|
1680
|
+
"data-test": dataTest,
|
|
1681
|
+
className: cn(
|
|
1682
|
+
"flex min-w-0 flex-wrap gap-2 [&_a]:min-h-[48px] [&_button]:min-h-[48px] sm:[&_a]:min-h-[44px] sm:[&_button]:min-h-[44px]",
|
|
1683
|
+
className
|
|
1684
|
+
),
|
|
1685
|
+
children
|
|
1686
|
+
}
|
|
1687
|
+
);
|
|
1688
|
+
}
|
|
1689
|
+
function SuiteSectionHeader({
|
|
1690
|
+
title,
|
|
1691
|
+
description,
|
|
1692
|
+
action,
|
|
1693
|
+
className
|
|
1694
|
+
}) {
|
|
1695
|
+
return /* @__PURE__ */ jsxs10(
|
|
1696
|
+
"div",
|
|
1697
|
+
{
|
|
1698
|
+
className: cn(
|
|
1699
|
+
"flex min-w-0 flex-col gap-4 sm:flex-row sm:items-end sm:justify-between",
|
|
1700
|
+
className
|
|
1701
|
+
),
|
|
1702
|
+
children: [
|
|
1703
|
+
/* @__PURE__ */ jsxs10("div", { className: "min-w-0", children: [
|
|
1704
|
+
/* @__PURE__ */ jsx12("h2", { className: "font-display text-balance text-lg font-semibold tracking-tight text-ph-ink sm:text-xl", children: title }),
|
|
1705
|
+
description ? /* @__PURE__ */ jsx12("div", { className: "mt-1 max-w-2xl text-pretty text-sm leading-5 text-ph-subtle", children: description }) : null
|
|
1706
|
+
] }),
|
|
1707
|
+
action ? /* @__PURE__ */ jsx12("div", { className: "flex min-h-[44px] shrink-0 items-center", children: action }) : null
|
|
1708
|
+
]
|
|
1709
|
+
}
|
|
1710
|
+
);
|
|
1711
|
+
}
|
|
1712
|
+
|
|
1713
|
+
// src/suite/components/suite-settings-layout.tsx
|
|
1714
|
+
import { jsx as jsx13, jsxs as jsxs11 } from "react/jsx-runtime";
|
|
1715
|
+
function SuiteSettingsLayout({
|
|
1716
|
+
children,
|
|
1717
|
+
sidebar,
|
|
1718
|
+
mobileNav,
|
|
1719
|
+
loading,
|
|
1720
|
+
title = "Settings",
|
|
1721
|
+
description,
|
|
1722
|
+
header,
|
|
1723
|
+
dataTest = "settings-page",
|
|
1724
|
+
headerDataTest = "settings-page-header",
|
|
1725
|
+
className,
|
|
1726
|
+
contentClassName
|
|
1727
|
+
}) {
|
|
1728
|
+
return /* @__PURE__ */ jsxs11(
|
|
1729
|
+
SuitePage,
|
|
1730
|
+
{
|
|
1731
|
+
dataTest,
|
|
1732
|
+
className: cn("flex h-full flex-col overflow-hidden", className),
|
|
1733
|
+
children: [
|
|
1734
|
+
header != null ? header : /* @__PURE__ */ jsx13(
|
|
1735
|
+
SuitePageHeader,
|
|
1736
|
+
{
|
|
1737
|
+
sticky: true,
|
|
1738
|
+
dataTest: headerDataTest,
|
|
1739
|
+
title,
|
|
1740
|
+
description
|
|
1741
|
+
}
|
|
1742
|
+
),
|
|
1743
|
+
loading != null ? loading : /* @__PURE__ */ jsxs11("div", { className: "suite-page-body mt-6 flex min-h-0 flex-1 flex-col", children: [
|
|
1744
|
+
mobileNav ? /* @__PURE__ */ jsx13("div", { className: "sticky top-0 z-20 mb-2 shrink-0 bg-ph-canvas/95 backdrop-blur lg:hidden", children: mobileNav }) : null,
|
|
1745
|
+
/* @__PURE__ */ jsxs11("div", { className: "flex min-h-0 flex-1 flex-col gap-6 lg:flex-row lg:gap-8", children: [
|
|
1746
|
+
/* @__PURE__ */ jsx13(
|
|
1747
|
+
"aside",
|
|
1748
|
+
{
|
|
1749
|
+
"aria-label": "Settings",
|
|
1750
|
+
className: "hidden w-56 shrink-0 bg-transparent lg:block lg:self-stretch lg:overflow-y-auto lg:overscroll-contain",
|
|
1751
|
+
children: sidebar
|
|
1752
|
+
}
|
|
1753
|
+
),
|
|
1754
|
+
/* @__PURE__ */ jsx13(
|
|
1755
|
+
"div",
|
|
1756
|
+
{
|
|
1757
|
+
className: cn(
|
|
1758
|
+
"min-h-0 min-w-0 flex-1 overflow-y-auto overscroll-contain pb-6",
|
|
1759
|
+
contentClassName
|
|
1760
|
+
),
|
|
1761
|
+
children
|
|
1762
|
+
}
|
|
1763
|
+
)
|
|
1764
|
+
] })
|
|
1765
|
+
] })
|
|
1766
|
+
]
|
|
1767
|
+
}
|
|
1768
|
+
);
|
|
1769
|
+
}
|
|
1770
|
+
|
|
1771
|
+
// src/suite/components/suite-user-menu.tsx
|
|
1772
|
+
import Image2 from "next/image";
|
|
1773
|
+
import { useRouter as useRouter2 } from "next/navigation";
|
|
1774
|
+
import { LogOut, Settings } from "iconoir-react";
|
|
1775
|
+
import { jsx as jsx14, jsxs as jsxs12 } from "react/jsx-runtime";
|
|
1776
|
+
function computeInitials(name, email) {
|
|
1777
|
+
const source = (name || email || "?").trim();
|
|
1778
|
+
return source.split(/[\s@]+/).filter(Boolean).slice(0, 2).map((part) => part[0]).join("").toUpperCase();
|
|
1779
|
+
}
|
|
1780
|
+
function SuiteUserMenu({
|
|
1781
|
+
name,
|
|
1782
|
+
email,
|
|
1783
|
+
image,
|
|
1784
|
+
settingsHref,
|
|
1785
|
+
onSignOut,
|
|
1786
|
+
fallbackInitials,
|
|
1787
|
+
dataTest = "suite-user-menu",
|
|
1788
|
+
className
|
|
1789
|
+
}) {
|
|
1790
|
+
const router = useRouter2();
|
|
1791
|
+
const initials = fallbackInitials != null ? fallbackInitials : computeInitials(name, email);
|
|
1792
|
+
const avatar = /* @__PURE__ */ jsx14("span", { className: "inline-flex h-11 w-11 items-center justify-center rounded-full transition-colors hover:bg-ph-muted", children: image ? /* @__PURE__ */ jsx14(
|
|
1793
|
+
Image2,
|
|
1794
|
+
{
|
|
1795
|
+
src: image,
|
|
1796
|
+
alt: "",
|
|
1797
|
+
width: 32,
|
|
1798
|
+
height: 32,
|
|
1799
|
+
className: "h-8 w-8 rounded-full object-cover",
|
|
1800
|
+
unoptimized: true
|
|
1801
|
+
}
|
|
1802
|
+
) : /* @__PURE__ */ jsx14("span", { className: "flex h-8 w-8 items-center justify-center rounded-full bg-ph-muted text-sm font-semibold text-ph-brand", children: initials }) });
|
|
1803
|
+
return /* @__PURE__ */ jsxs12(
|
|
1804
|
+
DropdownMenu,
|
|
1805
|
+
{
|
|
1806
|
+
trigger: avatar,
|
|
1807
|
+
"aria-label": "Account menu",
|
|
1808
|
+
align: "end",
|
|
1809
|
+
side: "bottom",
|
|
1810
|
+
sideOffset: 6,
|
|
1811
|
+
collisionPadding: 16,
|
|
1812
|
+
modal: false,
|
|
1813
|
+
className,
|
|
1814
|
+
"data-test": dataTest,
|
|
1815
|
+
children: [
|
|
1816
|
+
/* @__PURE__ */ jsxs12("div", { className: "px-2 py-1.5", children: [
|
|
1817
|
+
/* @__PURE__ */ jsx14("p", { className: "truncate text-sm font-medium text-ph-ink", children: name || email || "Account" }),
|
|
1818
|
+
email ? /* @__PURE__ */ jsx14("p", { className: "truncate text-xs text-ph-mutedtext", children: email }) : null
|
|
1819
|
+
] }),
|
|
1820
|
+
/* @__PURE__ */ jsx14("div", { className: "my-1 border-t border-ph-border" }),
|
|
1821
|
+
/* @__PURE__ */ jsxs12(
|
|
1822
|
+
DropdownItem,
|
|
1823
|
+
{
|
|
1824
|
+
"data-test": `${dataTest}-settings`,
|
|
1825
|
+
onClick: () => router.push(settingsHref),
|
|
1289
1826
|
children: [
|
|
1290
|
-
/* @__PURE__ */
|
|
1827
|
+
/* @__PURE__ */ jsx14(Settings, { className: "h-4 w-4 text-ph-mutedtext", "aria-hidden": true }),
|
|
1291
1828
|
"Profile settings"
|
|
1292
1829
|
]
|
|
1293
1830
|
}
|
|
1294
1831
|
),
|
|
1295
|
-
/* @__PURE__ */
|
|
1832
|
+
/* @__PURE__ */ jsxs12(
|
|
1296
1833
|
DropdownItem,
|
|
1297
1834
|
{
|
|
1298
1835
|
"data-test": `${dataTest}-sign-out`,
|
|
1299
1836
|
onClick: onSignOut,
|
|
1300
1837
|
children: [
|
|
1301
|
-
/* @__PURE__ */
|
|
1838
|
+
/* @__PURE__ */ jsx14(LogOut, { className: "h-4 w-4 text-ph-mutedtext", "aria-hidden": true }),
|
|
1302
1839
|
"Sign out"
|
|
1303
1840
|
]
|
|
1304
1841
|
}
|
|
@@ -1310,7 +1847,7 @@ function SuiteUserMenu({
|
|
|
1310
1847
|
|
|
1311
1848
|
// src/suite/components/suite-bottom-nav.tsx
|
|
1312
1849
|
import Link from "next/link";
|
|
1313
|
-
import { Fragment as
|
|
1850
|
+
import { Fragment as Fragment4, jsx as jsx15, jsxs as jsxs13 } from "react/jsx-runtime";
|
|
1314
1851
|
function SuiteBottomNav({
|
|
1315
1852
|
items,
|
|
1316
1853
|
ariaLabel = "Primary navigation",
|
|
@@ -1323,8 +1860,8 @@ function SuiteBottomNav({
|
|
|
1323
1860
|
);
|
|
1324
1861
|
}
|
|
1325
1862
|
const activeIndex = items.findIndex((item) => item.active);
|
|
1326
|
-
return /* @__PURE__ */
|
|
1327
|
-
/* @__PURE__ */
|
|
1863
|
+
return /* @__PURE__ */ jsxs13(Fragment4, { children: [
|
|
1864
|
+
/* @__PURE__ */ jsx15(
|
|
1328
1865
|
"div",
|
|
1329
1866
|
{
|
|
1330
1867
|
"aria-hidden": true,
|
|
@@ -1332,7 +1869,7 @@ function SuiteBottomNav({
|
|
|
1332
1869
|
style: { height: "calc(60px + env(safe-area-inset-bottom))" }
|
|
1333
1870
|
}
|
|
1334
1871
|
),
|
|
1335
|
-
/* @__PURE__ */
|
|
1872
|
+
/* @__PURE__ */ jsxs13(
|
|
1336
1873
|
"nav",
|
|
1337
1874
|
{
|
|
1338
1875
|
"aria-label": ariaLabel,
|
|
@@ -1347,12 +1884,12 @@ function SuiteBottomNav({
|
|
|
1347
1884
|
"--suite-nav-active": activeIndex >= 0 ? activeIndex : 0
|
|
1348
1885
|
},
|
|
1349
1886
|
children: [
|
|
1350
|
-
activeIndex >= 0 ? /* @__PURE__ */
|
|
1887
|
+
activeIndex >= 0 ? /* @__PURE__ */ jsx15("span", { "aria-hidden": true, className: "suite-bottom-nav__indicator" }) : null,
|
|
1351
1888
|
items.map((item) => {
|
|
1352
1889
|
var _a;
|
|
1353
1890
|
const Icon = item.icon;
|
|
1354
1891
|
const active = Boolean(item.active);
|
|
1355
|
-
return /* @__PURE__ */
|
|
1892
|
+
return /* @__PURE__ */ jsxs13(
|
|
1356
1893
|
Link,
|
|
1357
1894
|
{
|
|
1358
1895
|
href: item.href,
|
|
@@ -1363,14 +1900,14 @@ function SuiteBottomNav({
|
|
|
1363
1900
|
active && "font-semibold text-ph-brand"
|
|
1364
1901
|
),
|
|
1365
1902
|
children: [
|
|
1366
|
-
/* @__PURE__ */
|
|
1903
|
+
/* @__PURE__ */ jsx15(
|
|
1367
1904
|
"span",
|
|
1368
1905
|
{
|
|
1369
1906
|
className: cn(
|
|
1370
1907
|
"suite-bottom-nav__icon relative z-10 inline-flex items-center justify-center",
|
|
1371
1908
|
active && "suite-bottom-nav__icon--active"
|
|
1372
1909
|
),
|
|
1373
|
-
children: /* @__PURE__ */
|
|
1910
|
+
children: /* @__PURE__ */ jsx15(
|
|
1374
1911
|
Icon,
|
|
1375
1912
|
{
|
|
1376
1913
|
className: "h-6 w-6",
|
|
@@ -1380,7 +1917,7 @@ function SuiteBottomNav({
|
|
|
1380
1917
|
)
|
|
1381
1918
|
}
|
|
1382
1919
|
),
|
|
1383
|
-
/* @__PURE__ */
|
|
1920
|
+
/* @__PURE__ */ jsx15("span", { className: "relative z-10 max-w-full truncate", children: item.label })
|
|
1384
1921
|
]
|
|
1385
1922
|
},
|
|
1386
1923
|
item.href
|
|
@@ -1392,117 +1929,39 @@ function SuiteBottomNav({
|
|
|
1392
1929
|
] });
|
|
1393
1930
|
}
|
|
1394
1931
|
|
|
1395
|
-
// src/suite/lib/apps.ts
|
|
1396
|
-
var SUITE_APPS2 = [
|
|
1397
|
-
{
|
|
1398
|
-
slug: "shellstack",
|
|
1399
|
-
name: "ShellStack",
|
|
1400
|
-
description: "Organisation and billing",
|
|
1401
|
-
icon: "/icon-shellstack.svg",
|
|
1402
|
-
landing: "/home",
|
|
1403
|
-
baseUrlEnv: "NEXT_PUBLIC_SHELLSTACK_URL",
|
|
1404
|
-
baseUrlFallback: "http://localhost:3002"
|
|
1405
|
-
},
|
|
1406
|
-
{
|
|
1407
|
-
slug: "tides",
|
|
1408
|
-
name: "Tides",
|
|
1409
|
-
description: "Projects and tasks",
|
|
1410
|
-
icon: "/tides-icon.svg",
|
|
1411
|
-
landing: "/today",
|
|
1412
|
-
baseUrlEnv: "NEXT_PUBLIC_TIDES_URL",
|
|
1413
|
-
baseUrlFallback: "http://localhost:3001"
|
|
1414
|
-
},
|
|
1415
|
-
{
|
|
1416
|
-
slug: "turtletime",
|
|
1417
|
-
name: "TurtleTime",
|
|
1418
|
-
description: "Time tracking",
|
|
1419
|
-
icon: "/turtletime-icon.svg",
|
|
1420
|
-
landing: "/tracker",
|
|
1421
|
-
baseUrlEnv: "NEXT_PUBLIC_TURTLETIME_URL",
|
|
1422
|
-
baseUrlFallback: "http://localhost:3000"
|
|
1423
|
-
},
|
|
1424
|
-
{
|
|
1425
|
-
slug: "kraken",
|
|
1426
|
-
name: "Kraken",
|
|
1427
|
-
description: "Documents and knowledge",
|
|
1428
|
-
icon: "/kraken-icon.svg",
|
|
1429
|
-
landing: "/today",
|
|
1430
|
-
baseUrlEnv: "NEXT_PUBLIC_KRAKEN_URL",
|
|
1431
|
-
baseUrlFallback: "http://localhost:3003"
|
|
1432
|
-
}
|
|
1433
|
-
];
|
|
1434
|
-
var SUITE_APP_MAP = Object.fromEntries(SUITE_APPS2.map((app) => [app.slug, app]));
|
|
1435
|
-
function suiteAppBaseUrl(slug) {
|
|
1436
|
-
const def = SUITE_APP_MAP[slug];
|
|
1437
|
-
const fromEnv = typeof process !== "undefined" ? process.env[def.baseUrlEnv] : void 0;
|
|
1438
|
-
return (fromEnv || def.baseUrlFallback).replace(/\/$/, "");
|
|
1439
|
-
}
|
|
1440
|
-
|
|
1441
1932
|
// src/suite/components/today-calibrating.tsx
|
|
1442
1933
|
import { Refresh as RefreshCw2, SunLight as Sun } from "iconoir-react";
|
|
1443
|
-
import {
|
|
1934
|
+
import { jsx as jsx16, jsxs as jsxs14 } from "react/jsx-runtime";
|
|
1444
1935
|
function TodayCalibrating({
|
|
1445
1936
|
onRetry,
|
|
1446
1937
|
retrying = false,
|
|
1447
1938
|
className,
|
|
1448
1939
|
spinner: Spinner,
|
|
1449
|
-
variant = "ring",
|
|
1940
|
+
variant: _variant = "ring",
|
|
1450
1941
|
retrySpinnerClassName = "text-ph-brand"
|
|
1451
1942
|
}) {
|
|
1452
|
-
|
|
1943
|
+
void _variant;
|
|
1944
|
+
return /* @__PURE__ */ jsxs14(
|
|
1453
1945
|
"div",
|
|
1454
1946
|
{
|
|
1455
1947
|
className: cn(
|
|
1456
|
-
"relative flex min-h-[14rem] flex-col items-center justify-center overflow-hidden rounded-2xl border border-ph-border bg-ph-surface px-5 py-8 text-center shadow-sm",
|
|
1948
|
+
"suite-auth-handoff relative flex min-h-[14rem] flex-col items-center justify-center overflow-hidden rounded-2xl border border-ph-border bg-ph-surface px-5 py-8 text-center shadow-sm",
|
|
1457
1949
|
className
|
|
1458
1950
|
),
|
|
1459
1951
|
"data-test": "today-calibrating",
|
|
1460
1952
|
children: [
|
|
1461
|
-
/* @__PURE__ */
|
|
1953
|
+
/* @__PURE__ */ jsx16(
|
|
1462
1954
|
"div",
|
|
1463
1955
|
{
|
|
1464
|
-
className: "pointer-events-none absolute inset-0 bg-[radial-gradient(circle_at_50%_35%,rgba(251,191,36,0.
|
|
1956
|
+
className: "pointer-events-none absolute inset-0 bg-[radial-gradient(circle_at_50%_35%,rgba(251,191,36,0.1),transparent_55%)]",
|
|
1465
1957
|
"aria-hidden": true
|
|
1466
1958
|
}
|
|
1467
1959
|
),
|
|
1468
|
-
/* @__PURE__ */
|
|
1469
|
-
|
|
1470
|
-
|
|
1471
|
-
|
|
1472
|
-
|
|
1473
|
-
size: "lg",
|
|
1474
|
-
className: "absolute inset-0 m-auto opacity-40",
|
|
1475
|
-
label: "Loading today"
|
|
1476
|
-
}
|
|
1477
|
-
),
|
|
1478
|
-
/* @__PURE__ */ jsx14(
|
|
1479
|
-
"span",
|
|
1480
|
-
{
|
|
1481
|
-
className: "bg-ph-muted/30 absolute inset-2 animate-ping rounded-full",
|
|
1482
|
-
"aria-hidden": true
|
|
1483
|
-
}
|
|
1484
|
-
)
|
|
1485
|
-
] }) : null,
|
|
1486
|
-
/* @__PURE__ */ jsx14("span", { className: "relative flex h-14 w-14 items-center justify-center rounded-2xl border border-ph-border bg-ph-surface text-ph-ink shadow-sm", children: /* @__PURE__ */ jsx14(
|
|
1487
|
-
Sun,
|
|
1488
|
-
{
|
|
1489
|
-
className: cn("h-9 w-9", variant === "pulse" && "animate-pulse"),
|
|
1490
|
-
strokeWidth: 2,
|
|
1491
|
-
"aria-hidden": true
|
|
1492
|
-
}
|
|
1493
|
-
) })
|
|
1494
|
-
] }),
|
|
1495
|
-
/* @__PURE__ */ jsx14("h2", { className: "relative text-base font-semibold tracking-tight text-ph-ink sm:text-lg md:text-xl", children: "Calibrating your day" }),
|
|
1496
|
-
/* @__PURE__ */ jsx14("p", { className: "relative mt-1.5 max-w-sm text-sm sm:text-[15px] leading-relaxed text-ph-subtle", children: "Pulling together tasks, time and updates from your workspace\u2026" }),
|
|
1497
|
-
/* @__PURE__ */ jsx14("div", { className: "relative mt-5 flex gap-1.5", "aria-hidden": true, children: [0, 1, 2, 3, 4].map((i) => /* @__PURE__ */ jsx14(
|
|
1498
|
-
"span",
|
|
1499
|
-
{
|
|
1500
|
-
className: "h-1.5 w-5 animate-pulse rounded-full bg-ph-muted",
|
|
1501
|
-
style: { animationDelay: `${i * 120}ms` }
|
|
1502
|
-
},
|
|
1503
|
-
i
|
|
1504
|
-
)) }),
|
|
1505
|
-
onRetry ? /* @__PURE__ */ jsxs12(
|
|
1960
|
+
/* @__PURE__ */ jsx16("div", { className: "relative mb-5 flex h-14 w-14 items-center justify-center rounded-2xl border border-ph-border bg-ph-surface text-ph-ink shadow-sm", children: /* @__PURE__ */ jsx16(Sun, { className: "h-8 w-8", strokeWidth: 2, "aria-hidden": true }) }),
|
|
1961
|
+
/* @__PURE__ */ jsx16("h2", { className: "relative text-base font-semibold tracking-tight text-ph-ink sm:text-lg md:text-xl", children: "Calibrating your day" }),
|
|
1962
|
+
/* @__PURE__ */ jsx16("p", { className: "relative mt-1.5 max-w-sm text-sm sm:text-[15px] leading-relaxed text-ph-subtle", children: "Pulling together tasks, time and updates from your workspace\u2026" }),
|
|
1963
|
+
/* @__PURE__ */ jsx16("div", { className: "relative mt-5 flex justify-center", children: /* @__PURE__ */ jsx16(Spinner, { size: "sm", className: "opacity-70", label: "Loading today" }) }),
|
|
1964
|
+
onRetry ? /* @__PURE__ */ jsxs14(
|
|
1506
1965
|
"button",
|
|
1507
1966
|
{
|
|
1508
1967
|
type: "button",
|
|
@@ -1510,7 +1969,7 @@ function TodayCalibrating({
|
|
|
1510
1969
|
disabled: retrying,
|
|
1511
1970
|
className: "relative mt-6 inline-flex items-center gap-2 rounded-xl border border-ph-border bg-ph-canvas px-4 py-2 text-sm font-medium text-ph-ink transition hover:bg-ph-muted disabled:opacity-60",
|
|
1512
1971
|
children: [
|
|
1513
|
-
retrying ? /* @__PURE__ */
|
|
1972
|
+
retrying ? /* @__PURE__ */ jsx16(Spinner, { size: "sm", className: retrySpinnerClassName }) : /* @__PURE__ */ jsx16(RefreshCw2, { className: "h-4 w-4", "aria-hidden": true }),
|
|
1514
1973
|
"Try again"
|
|
1515
1974
|
]
|
|
1516
1975
|
}
|
|
@@ -1525,11 +1984,11 @@ import {
|
|
|
1525
1984
|
createContext,
|
|
1526
1985
|
useCallback as useCallback2,
|
|
1527
1986
|
useContext,
|
|
1528
|
-
useEffect as
|
|
1987
|
+
useEffect as useEffect6,
|
|
1529
1988
|
useMemo,
|
|
1530
|
-
useState as
|
|
1989
|
+
useState as useState7
|
|
1531
1990
|
} from "react";
|
|
1532
|
-
import { jsx as
|
|
1991
|
+
import { jsx as jsx17 } from "react/jsx-runtime";
|
|
1533
1992
|
var SuiteThemeContext = createContext(null);
|
|
1534
1993
|
function systemTheme(fallback) {
|
|
1535
1994
|
if (typeof window === "undefined") return fallback;
|
|
@@ -1567,7 +2026,7 @@ function SuiteThemeProvider({
|
|
|
1567
2026
|
config,
|
|
1568
2027
|
children
|
|
1569
2028
|
}) {
|
|
1570
|
-
const [state, setState] =
|
|
2029
|
+
const [state, setState] = useState7(() => {
|
|
1571
2030
|
const theme2 = readStoredTheme(config.storageKey);
|
|
1572
2031
|
if (typeof document === "undefined") {
|
|
1573
2032
|
return { theme: theme2, resolvedTheme: config.fallbackTheme };
|
|
@@ -1577,7 +2036,7 @@ function SuiteThemeProvider({
|
|
|
1577
2036
|
return { theme: theme2, resolvedTheme: resolvedTheme2 };
|
|
1578
2037
|
});
|
|
1579
2038
|
const { theme, resolvedTheme } = state;
|
|
1580
|
-
|
|
2039
|
+
useEffect6(() => {
|
|
1581
2040
|
if (theme !== "system") return;
|
|
1582
2041
|
const media = window.matchMedia("(prefers-color-scheme: dark)");
|
|
1583
2042
|
const update = () => {
|
|
@@ -1607,7 +2066,7 @@ function SuiteThemeProvider({
|
|
|
1607
2066
|
() => ({ theme, resolvedTheme, setTheme, toggleTheme }),
|
|
1608
2067
|
[theme, resolvedTheme, setTheme, toggleTheme]
|
|
1609
2068
|
);
|
|
1610
|
-
return /* @__PURE__ */
|
|
2069
|
+
return /* @__PURE__ */ jsx17(SuiteThemeContext.Provider, { value, children });
|
|
1611
2070
|
}
|
|
1612
2071
|
function useSuiteTheme() {
|
|
1613
2072
|
const ctx = useContext(SuiteThemeContext);
|
|
@@ -1616,39 +2075,170 @@ function useSuiteTheme() {
|
|
|
1616
2075
|
}
|
|
1617
2076
|
|
|
1618
2077
|
// src/suite/components/ai-panel.tsx
|
|
1619
|
-
import {
|
|
1620
|
-
|
|
1621
|
-
|
|
2078
|
+
import {
|
|
2079
|
+
useCallback as useCallback3,
|
|
2080
|
+
useEffect as useEffect7,
|
|
2081
|
+
useRef as useRef3,
|
|
2082
|
+
useState as useState8
|
|
2083
|
+
} from "react";
|
|
2084
|
+
import { Check as Check2, Copy, Sparks, Xmark as X2 } from "iconoir-react";
|
|
2085
|
+
import { Fragment as Fragment5, jsx as jsx18, jsxs as jsxs15 } from "react/jsx-runtime";
|
|
2086
|
+
var SUITE_OPEN_ASK_AI_EVENT = "shellstack:open-ask-ai";
|
|
2087
|
+
function openSuiteAskAi(detail) {
|
|
2088
|
+
if (typeof window === "undefined") return;
|
|
2089
|
+
window.dispatchEvent(
|
|
2090
|
+
new CustomEvent(SUITE_OPEN_ASK_AI_EVENT, {
|
|
2091
|
+
detail: detail != null ? detail : {}
|
|
2092
|
+
})
|
|
2093
|
+
);
|
|
2094
|
+
}
|
|
2095
|
+
var LAUNCHER_EDGE_GAP = 12;
|
|
2096
|
+
var LAUNCHER_STORAGE_KEY = "suite-ask-ai-launcher-position";
|
|
2097
|
+
function resolveSuiteAiLauncherPosition(side, desiredY, viewportWidth, viewportHeight, launcherWidth, launcherHeight) {
|
|
2098
|
+
const maxX = Math.max(
|
|
2099
|
+
LAUNCHER_EDGE_GAP,
|
|
2100
|
+
viewportWidth - launcherWidth - LAUNCHER_EDGE_GAP
|
|
2101
|
+
);
|
|
2102
|
+
const maxY = Math.max(
|
|
2103
|
+
LAUNCHER_EDGE_GAP,
|
|
2104
|
+
viewportHeight - launcherHeight - LAUNCHER_EDGE_GAP
|
|
2105
|
+
);
|
|
2106
|
+
return {
|
|
2107
|
+
x: side === "left" ? LAUNCHER_EDGE_GAP : maxX,
|
|
2108
|
+
y: Math.min(Math.max(desiredY, LAUNCHER_EDGE_GAP), maxY)
|
|
2109
|
+
};
|
|
2110
|
+
}
|
|
1622
2111
|
function SuiteAiPanel({
|
|
1623
|
-
presets,
|
|
1624
|
-
emptyState,
|
|
1625
|
-
|
|
1626
|
-
|
|
2112
|
+
presets = [],
|
|
2113
|
+
emptyState = "Ask anything about your workspace, or look something up online.",
|
|
2114
|
+
title = "Ask AI",
|
|
2115
|
+
fetchChat,
|
|
2116
|
+
sendMessage,
|
|
2117
|
+
clearChat,
|
|
1627
2118
|
brandIcon: BrandIcon,
|
|
1628
|
-
spinner: Spinner
|
|
2119
|
+
spinner: Spinner,
|
|
2120
|
+
hideLauncher = false
|
|
1629
2121
|
}) {
|
|
1630
|
-
const [open, setOpen] =
|
|
1631
|
-
const [prompt, setPrompt] =
|
|
1632
|
-
const [
|
|
1633
|
-
const [
|
|
1634
|
-
const [
|
|
1635
|
-
const [
|
|
2122
|
+
const [open, setOpen] = useState8(false);
|
|
2123
|
+
const [prompt, setPrompt] = useState8("");
|
|
2124
|
+
const [messages, setMessages] = useState8([]);
|
|
2125
|
+
const [loading, setLoading] = useState8(false);
|
|
2126
|
+
const [hydrating, setHydrating] = useState8(false);
|
|
2127
|
+
const [error, setError] = useState8("");
|
|
2128
|
+
const [copiedId, setCopiedId] = useState8(null);
|
|
2129
|
+
const [launcherSide, setLauncherSide] = useState8("right");
|
|
2130
|
+
const [launcherPosition, setLauncherPosition] = useState8(null);
|
|
2131
|
+
const [draggingLauncher, setDraggingLauncher] = useState8(false);
|
|
2132
|
+
const scrollerRef = useRef3(null);
|
|
2133
|
+
const launcherRef = useRef3(null);
|
|
2134
|
+
const launcherSideRef = useRef3("right");
|
|
2135
|
+
const launcherPositionRef = useRef3(null);
|
|
2136
|
+
const launcherDragRef = useRef3(null);
|
|
2137
|
+
const suppressLauncherClickRef = useRef3(false);
|
|
2138
|
+
const pendingPromptRef = useRef3(null);
|
|
2139
|
+
useEffect7(() => {
|
|
2140
|
+
const launcher = launcherRef.current;
|
|
2141
|
+
if (!launcher) return;
|
|
2142
|
+
let side = "right";
|
|
2143
|
+
let desiredY = window.innerHeight - launcher.offsetHeight - 20;
|
|
2144
|
+
try {
|
|
2145
|
+
const stored = JSON.parse(
|
|
2146
|
+
localStorage.getItem(LAUNCHER_STORAGE_KEY) || "null"
|
|
2147
|
+
);
|
|
2148
|
+
if ((stored == null ? void 0 : stored.side) === "left" || (stored == null ? void 0 : stored.side) === "right")
|
|
2149
|
+
side = stored.side;
|
|
2150
|
+
if (typeof (stored == null ? void 0 : stored.y) === "number") desiredY = stored.y;
|
|
2151
|
+
} catch (e) {
|
|
2152
|
+
}
|
|
2153
|
+
launcherSideRef.current = side;
|
|
2154
|
+
setLauncherSide(side);
|
|
2155
|
+
const placeLauncher = () => {
|
|
2156
|
+
var _a, _b;
|
|
2157
|
+
const element = launcherRef.current;
|
|
2158
|
+
if (!element) return;
|
|
2159
|
+
const next = resolveSuiteAiLauncherPosition(
|
|
2160
|
+
launcherSideRef.current,
|
|
2161
|
+
(_b = (_a = launcherPositionRef.current) == null ? void 0 : _a.y) != null ? _b : desiredY,
|
|
2162
|
+
window.innerWidth,
|
|
2163
|
+
window.innerHeight,
|
|
2164
|
+
element.offsetWidth,
|
|
2165
|
+
element.offsetHeight
|
|
2166
|
+
);
|
|
2167
|
+
launcherPositionRef.current = next;
|
|
2168
|
+
setLauncherPosition(next);
|
|
2169
|
+
};
|
|
2170
|
+
placeLauncher();
|
|
2171
|
+
window.addEventListener("resize", placeLauncher);
|
|
2172
|
+
return () => window.removeEventListener("resize", placeLauncher);
|
|
2173
|
+
}, []);
|
|
2174
|
+
const scrollToBottom = useCallback3(() => {
|
|
2175
|
+
const el = scrollerRef.current;
|
|
2176
|
+
if (!el) return;
|
|
2177
|
+
el.scrollTop = el.scrollHeight;
|
|
2178
|
+
}, []);
|
|
2179
|
+
const hydrate = useCallback3(async () => {
|
|
2180
|
+
var _a;
|
|
2181
|
+
setHydrating(true);
|
|
2182
|
+
setError("");
|
|
2183
|
+
try {
|
|
2184
|
+
const data = await fetchChat();
|
|
2185
|
+
setMessages((_a = data.messages) != null ? _a : []);
|
|
2186
|
+
if (!data.configured) {
|
|
2187
|
+
setError("ShellStack AI is not configured for this workspace yet.");
|
|
2188
|
+
}
|
|
2189
|
+
} catch (err) {
|
|
2190
|
+
setError(
|
|
2191
|
+
err instanceof Error ? err.message : "Could not load your Ask AI chat."
|
|
2192
|
+
);
|
|
2193
|
+
} finally {
|
|
2194
|
+
setHydrating(false);
|
|
2195
|
+
}
|
|
2196
|
+
}, [fetchChat]);
|
|
2197
|
+
useEffect7(() => {
|
|
2198
|
+
function onOpen(event) {
|
|
2199
|
+
var _a;
|
|
2200
|
+
const detail = event.detail;
|
|
2201
|
+
setOpen(true);
|
|
2202
|
+
if ((_a = detail == null ? void 0 : detail.prompt) == null ? void 0 : _a.trim()) {
|
|
2203
|
+
pendingPromptRef.current = detail.prompt.trim();
|
|
2204
|
+
setPrompt(detail.prompt.trim());
|
|
2205
|
+
}
|
|
2206
|
+
}
|
|
2207
|
+
window.addEventListener(SUITE_OPEN_ASK_AI_EVENT, onOpen);
|
|
2208
|
+
return () => window.removeEventListener(SUITE_OPEN_ASK_AI_EVENT, onOpen);
|
|
2209
|
+
}, []);
|
|
2210
|
+
useEffect7(() => {
|
|
2211
|
+
if (!open) return;
|
|
2212
|
+
void hydrate().then(() => {
|
|
2213
|
+
const pending = pendingPromptRef.current;
|
|
2214
|
+
pendingPromptRef.current = null;
|
|
2215
|
+
if (pending) {
|
|
2216
|
+
setPrompt(pending);
|
|
2217
|
+
}
|
|
2218
|
+
});
|
|
2219
|
+
}, [open, hydrate]);
|
|
2220
|
+
useEffect7(() => {
|
|
2221
|
+
if (open) scrollToBottom();
|
|
2222
|
+
}, [messages, loading, open, scrollToBottom]);
|
|
1636
2223
|
async function ask(text) {
|
|
2224
|
+
var _a;
|
|
1637
2225
|
const trimmed = text.trim();
|
|
1638
2226
|
if (!trimmed || loading) return;
|
|
1639
2227
|
setLoading(true);
|
|
1640
2228
|
setError("");
|
|
1641
|
-
|
|
1642
|
-
|
|
2229
|
+
setPrompt("");
|
|
2230
|
+
setMessages((prev) => [...prev, { role: "user", content: trimmed }]);
|
|
1643
2231
|
try {
|
|
1644
|
-
const
|
|
1645
|
-
|
|
1646
|
-
setError("ShellStack AI is not configured for this workspace yet.");
|
|
1647
|
-
return;
|
|
1648
|
-
}
|
|
1649
|
-
const result = await complete({ prompt: trimmed });
|
|
1650
|
-
setAnswer(result.text);
|
|
2232
|
+
const result = await sendMessage({ prompt: trimmed });
|
|
2233
|
+
setMessages((_a = result.messages) != null ? _a : []);
|
|
1651
2234
|
} catch (err) {
|
|
2235
|
+
setMessages(
|
|
2236
|
+
(prev) => {
|
|
2237
|
+
var _a2, _b;
|
|
2238
|
+
return ((_a2 = prev[prev.length - 1]) == null ? void 0 : _a2.role) === "user" && ((_b = prev[prev.length - 1]) == null ? void 0 : _b.content) === trimmed ? prev.slice(0, -1) : prev;
|
|
2239
|
+
}
|
|
2240
|
+
);
|
|
2241
|
+
setPrompt(trimmed);
|
|
1652
2242
|
setError(
|
|
1653
2243
|
err instanceof Error ? err.message : "The AI request failed. Try again."
|
|
1654
2244
|
);
|
|
@@ -1656,133 +2246,395 @@ function SuiteAiPanel({
|
|
|
1656
2246
|
setLoading(false);
|
|
1657
2247
|
}
|
|
1658
2248
|
}
|
|
1659
|
-
async function
|
|
1660
|
-
if (
|
|
2249
|
+
async function handleClear() {
|
|
2250
|
+
if (loading) return;
|
|
1661
2251
|
try {
|
|
1662
|
-
await
|
|
1663
|
-
|
|
1664
|
-
|
|
2252
|
+
await clearChat();
|
|
2253
|
+
setMessages([]);
|
|
2254
|
+
setError("");
|
|
2255
|
+
} catch (err) {
|
|
2256
|
+
setError(
|
|
2257
|
+
err instanceof Error ? err.message : "Could not clear this chat."
|
|
2258
|
+
);
|
|
2259
|
+
}
|
|
2260
|
+
}
|
|
2261
|
+
async function copyMessage(index, content) {
|
|
2262
|
+
try {
|
|
2263
|
+
await navigator.clipboard.writeText(content);
|
|
2264
|
+
setCopiedId(index);
|
|
2265
|
+
window.setTimeout(() => setCopiedId(null), 1500);
|
|
1665
2266
|
} catch (e) {
|
|
1666
2267
|
}
|
|
1667
2268
|
}
|
|
1668
|
-
|
|
1669
|
-
|
|
1670
|
-
|
|
1671
|
-
|
|
1672
|
-
|
|
1673
|
-
|
|
1674
|
-
|
|
1675
|
-
|
|
1676
|
-
|
|
1677
|
-
|
|
1678
|
-
|
|
1679
|
-
|
|
1680
|
-
|
|
1681
|
-
|
|
1682
|
-
|
|
1683
|
-
|
|
1684
|
-
|
|
2269
|
+
function saveLauncherPosition(side, position) {
|
|
2270
|
+
try {
|
|
2271
|
+
localStorage.setItem(
|
|
2272
|
+
LAUNCHER_STORAGE_KEY,
|
|
2273
|
+
JSON.stringify({ side, y: position.y })
|
|
2274
|
+
);
|
|
2275
|
+
} catch (e) {
|
|
2276
|
+
}
|
|
2277
|
+
}
|
|
2278
|
+
function dockLauncher(side, desiredY) {
|
|
2279
|
+
const launcher = launcherRef.current;
|
|
2280
|
+
if (!launcher) return;
|
|
2281
|
+
const next = resolveSuiteAiLauncherPosition(
|
|
2282
|
+
side,
|
|
2283
|
+
desiredY,
|
|
2284
|
+
window.innerWidth,
|
|
2285
|
+
window.innerHeight,
|
|
2286
|
+
launcher.offsetWidth,
|
|
2287
|
+
launcher.offsetHeight
|
|
2288
|
+
);
|
|
2289
|
+
launcherSideRef.current = side;
|
|
2290
|
+
launcherPositionRef.current = next;
|
|
2291
|
+
setLauncherSide(side);
|
|
2292
|
+
setLauncherPosition(next);
|
|
2293
|
+
saveLauncherPosition(side, next);
|
|
2294
|
+
}
|
|
2295
|
+
function startLauncherDrag(event) {
|
|
2296
|
+
if (event.pointerType === "mouse" && event.button !== 0) return;
|
|
2297
|
+
const rect = event.currentTarget.getBoundingClientRect();
|
|
2298
|
+
launcherDragRef.current = {
|
|
2299
|
+
pointerId: event.pointerId,
|
|
2300
|
+
offsetX: event.clientX - rect.left,
|
|
2301
|
+
offsetY: event.clientY - rect.top,
|
|
2302
|
+
startX: event.clientX,
|
|
2303
|
+
startY: event.clientY
|
|
2304
|
+
};
|
|
2305
|
+
suppressLauncherClickRef.current = false;
|
|
2306
|
+
event.currentTarget.setPointerCapture(event.pointerId);
|
|
2307
|
+
setDraggingLauncher(true);
|
|
2308
|
+
}
|
|
2309
|
+
function moveLauncher(event) {
|
|
2310
|
+
const drag = launcherDragRef.current;
|
|
2311
|
+
if (!drag || drag.pointerId !== event.pointerId) return;
|
|
2312
|
+
const launcher = event.currentTarget;
|
|
2313
|
+
const maxX = Math.max(
|
|
2314
|
+
LAUNCHER_EDGE_GAP,
|
|
2315
|
+
window.innerWidth - launcher.offsetWidth - LAUNCHER_EDGE_GAP
|
|
2316
|
+
);
|
|
2317
|
+
const maxY = Math.max(
|
|
2318
|
+
LAUNCHER_EDGE_GAP,
|
|
2319
|
+
window.innerHeight - launcher.offsetHeight - LAUNCHER_EDGE_GAP
|
|
2320
|
+
);
|
|
2321
|
+
const next = {
|
|
2322
|
+
x: Math.min(
|
|
2323
|
+
Math.max(event.clientX - drag.offsetX, LAUNCHER_EDGE_GAP),
|
|
2324
|
+
maxX
|
|
2325
|
+
),
|
|
2326
|
+
y: Math.min(
|
|
2327
|
+
Math.max(event.clientY - drag.offsetY, LAUNCHER_EDGE_GAP),
|
|
2328
|
+
maxY
|
|
2329
|
+
)
|
|
2330
|
+
};
|
|
2331
|
+
if (Math.hypot(event.clientX - drag.startX, event.clientY - drag.startY) > 4) {
|
|
2332
|
+
suppressLauncherClickRef.current = true;
|
|
2333
|
+
}
|
|
2334
|
+
launcherPositionRef.current = next;
|
|
2335
|
+
setLauncherPosition(next);
|
|
2336
|
+
}
|
|
2337
|
+
function finishLauncherDrag(event) {
|
|
2338
|
+
var _a, _b, _c, _d;
|
|
2339
|
+
const drag = launcherDragRef.current;
|
|
2340
|
+
if (!drag || drag.pointerId !== event.pointerId) return;
|
|
2341
|
+
if (event.currentTarget.hasPointerCapture(event.pointerId)) {
|
|
2342
|
+
event.currentTarget.releasePointerCapture(event.pointerId);
|
|
2343
|
+
}
|
|
2344
|
+
launcherDragRef.current = null;
|
|
2345
|
+
setDraggingLauncher(false);
|
|
2346
|
+
const rect = event.currentTarget.getBoundingClientRect();
|
|
2347
|
+
const currentX = (_b = (_a = launcherPositionRef.current) == null ? void 0 : _a.x) != null ? _b : rect.left;
|
|
2348
|
+
const side = currentX + rect.width / 2 < window.innerWidth / 2 ? "left" : "right";
|
|
2349
|
+
dockLauncher(side, (_d = (_c = launcherPositionRef.current) == null ? void 0 : _c.y) != null ? _d : rect.top);
|
|
2350
|
+
}
|
|
2351
|
+
function moveLauncherWithKeyboard(event) {
|
|
2352
|
+
var _a, _b;
|
|
2353
|
+
if (!["ArrowLeft", "ArrowRight", "ArrowUp", "ArrowDown"].includes(event.key))
|
|
2354
|
+
return;
|
|
2355
|
+
event.preventDefault();
|
|
2356
|
+
const currentY = (_b = (_a = launcherPositionRef.current) == null ? void 0 : _a.y) != null ? _b : event.currentTarget.getBoundingClientRect().top;
|
|
2357
|
+
if (event.key === "ArrowLeft") dockLauncher("left", currentY);
|
|
2358
|
+
else if (event.key === "ArrowRight") dockLauncher("right", currentY);
|
|
2359
|
+
else
|
|
2360
|
+
dockLauncher(
|
|
2361
|
+
launcherSideRef.current,
|
|
2362
|
+
currentY + (event.key === "ArrowUp" ? -24 : 24)
|
|
2363
|
+
);
|
|
2364
|
+
}
|
|
2365
|
+
const Icon = BrandIcon != null ? BrandIcon : Sparks;
|
|
2366
|
+
return /* @__PURE__ */ jsxs15(Fragment5, { children: [
|
|
2367
|
+
!hideLauncher ? /* @__PURE__ */ jsxs15(Fragment5, { children: [
|
|
2368
|
+
/* @__PURE__ */ jsxs15(
|
|
2369
|
+
"button",
|
|
2370
|
+
{
|
|
2371
|
+
ref: launcherRef,
|
|
2372
|
+
type: "button",
|
|
2373
|
+
"data-test": "ai-panel-launcher",
|
|
2374
|
+
onClick: () => {
|
|
2375
|
+
if (suppressLauncherClickRef.current) {
|
|
2376
|
+
suppressLauncherClickRef.current = false;
|
|
2377
|
+
return;
|
|
2378
|
+
}
|
|
2379
|
+
setOpen(true);
|
|
2380
|
+
},
|
|
2381
|
+
onPointerDown: startLauncherDrag,
|
|
2382
|
+
onPointerMove: moveLauncher,
|
|
2383
|
+
onPointerUp: finishLauncherDrag,
|
|
2384
|
+
onPointerCancel: finishLauncherDrag,
|
|
2385
|
+
onKeyDown: moveLauncherWithKeyboard,
|
|
2386
|
+
className: `fixed z-30 flex touch-none select-none items-center gap-2 rounded-full border border-ph-border bg-ph-surface px-4 py-2.5 text-sm font-medium text-ph-ink shadow-ph hover:bg-ph-muted focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-ph-brand ${draggingLauncher ? "cursor-grabbing" : "cursor-grab"}`,
|
|
2387
|
+
style: launcherPosition ? { left: launcherPosition.x, top: launcherPosition.y } : { bottom: 20, right: 20 },
|
|
2388
|
+
"aria-label": "Open Ask AI",
|
|
2389
|
+
"aria-describedby": "suite-ask-ai-launcher-help",
|
|
2390
|
+
children: [
|
|
2391
|
+
/* @__PURE__ */ jsx18(Icon, { className: "h-4 w-4 text-ph-brand" }),
|
|
2392
|
+
"Ask AI"
|
|
2393
|
+
]
|
|
2394
|
+
}
|
|
2395
|
+
),
|
|
2396
|
+
/* @__PURE__ */ jsx18("span", { id: "suite-ask-ai-launcher-help", className: "sr-only", children: "Drag to reposition, or use arrow keys. The launcher docks to the nearest screen edge." })
|
|
2397
|
+
] }) : null,
|
|
2398
|
+
open ? /* @__PURE__ */ jsxs15("div", { className: "fixed inset-0 z-40", role: "dialog", "aria-modal": "true", children: [
|
|
2399
|
+
/* @__PURE__ */ jsx18(
|
|
1685
2400
|
"button",
|
|
1686
2401
|
{
|
|
1687
2402
|
type: "button",
|
|
1688
2403
|
className: "absolute inset-0 bg-black/25",
|
|
1689
2404
|
onClick: () => setOpen(false),
|
|
1690
|
-
"aria-label": "Close AI
|
|
2405
|
+
"aria-label": "Close Ask AI"
|
|
1691
2406
|
}
|
|
1692
2407
|
),
|
|
1693
|
-
/* @__PURE__ */
|
|
1694
|
-
|
|
1695
|
-
|
|
1696
|
-
|
|
1697
|
-
|
|
1698
|
-
|
|
1699
|
-
|
|
1700
|
-
|
|
1701
|
-
|
|
1702
|
-
|
|
1703
|
-
|
|
1704
|
-
|
|
1705
|
-
|
|
1706
|
-
|
|
1707
|
-
|
|
1708
|
-
|
|
1709
|
-
|
|
1710
|
-
|
|
1711
|
-
|
|
1712
|
-
|
|
1713
|
-
|
|
1714
|
-
|
|
1715
|
-
|
|
1716
|
-
|
|
1717
|
-
|
|
1718
|
-
|
|
1719
|
-
|
|
1720
|
-
|
|
1721
|
-
|
|
1722
|
-
|
|
1723
|
-
|
|
1724
|
-
|
|
1725
|
-
|
|
1726
|
-
|
|
1727
|
-
|
|
1728
|
-
|
|
1729
|
-
|
|
1730
|
-
|
|
1731
|
-
/* @__PURE__ */
|
|
1732
|
-
/* @__PURE__ */ jsxs13(
|
|
2408
|
+
/* @__PURE__ */ jsxs15(
|
|
2409
|
+
"aside",
|
|
2410
|
+
{
|
|
2411
|
+
className: `absolute inset-y-0 flex w-full max-w-md flex-col bg-ph-surface shadow-2xl ${launcherSide === "left" ? "left-0 border-r border-ph-border" : "right-0 border-l border-ph-border"}`,
|
|
2412
|
+
"data-test": "suite-ask-ai-panel",
|
|
2413
|
+
children: [
|
|
2414
|
+
/* @__PURE__ */ jsxs15("div", { className: "flex items-center justify-between border-b border-ph-border px-4 py-3", children: [
|
|
2415
|
+
/* @__PURE__ */ jsxs15("div", { className: "min-w-0", children: [
|
|
2416
|
+
/* @__PURE__ */ jsxs15("div", { className: "flex items-center gap-2", children: [
|
|
2417
|
+
/* @__PURE__ */ jsx18(Icon, { className: "h-4 w-4 shrink-0 text-ph-brand" }),
|
|
2418
|
+
/* @__PURE__ */ jsx18("span", { className: "text-sm font-semibold text-ph-ink", children: title })
|
|
2419
|
+
] }),
|
|
2420
|
+
/* @__PURE__ */ jsx18("p", { className: "mt-0.5 text-[11px] text-ph-mutedtext", children: "Shared across your suite \xB7 same chat in every app" })
|
|
2421
|
+
] }),
|
|
2422
|
+
/* @__PURE__ */ jsxs15("div", { className: "flex items-center gap-1", children: [
|
|
2423
|
+
messages.length > 0 ? /* @__PURE__ */ jsx18(
|
|
2424
|
+
"button",
|
|
2425
|
+
{
|
|
2426
|
+
type: "button",
|
|
2427
|
+
onClick: () => void handleClear(),
|
|
2428
|
+
disabled: loading,
|
|
2429
|
+
className: "rounded-md px-2 py-1 text-xs text-ph-mutedtext hover:bg-ph-muted hover:text-ph-ink disabled:opacity-50",
|
|
2430
|
+
"data-test": "ask-ai-clear",
|
|
2431
|
+
children: "Clear"
|
|
2432
|
+
}
|
|
2433
|
+
) : null,
|
|
2434
|
+
/* @__PURE__ */ jsx18(
|
|
2435
|
+
"button",
|
|
2436
|
+
{
|
|
2437
|
+
type: "button",
|
|
2438
|
+
onClick: () => setOpen(false),
|
|
2439
|
+
className: "rounded p-1 hover:bg-ph-muted",
|
|
2440
|
+
"aria-label": "Close",
|
|
2441
|
+
children: /* @__PURE__ */ jsx18(X2, { className: "h-4 w-4" })
|
|
2442
|
+
}
|
|
2443
|
+
)
|
|
2444
|
+
] })
|
|
2445
|
+
] }),
|
|
2446
|
+
presets.length > 0 && messages.length === 0 ? /* @__PURE__ */ jsx18("div", { className: "flex flex-wrap gap-1.5 border-b border-ph-border px-4 py-2", children: presets.map((preset) => /* @__PURE__ */ jsx18(
|
|
1733
2447
|
"button",
|
|
1734
2448
|
{
|
|
1735
2449
|
type: "button",
|
|
1736
|
-
onClick: () => void
|
|
1737
|
-
|
|
2450
|
+
onClick: () => void ask(preset.prompt),
|
|
2451
|
+
disabled: loading || hydrating,
|
|
2452
|
+
className: "rounded-full border border-ph-border px-2.5 py-1 text-xs text-ph-ink hover:bg-ph-muted disabled:opacity-50",
|
|
2453
|
+
children: preset.label
|
|
2454
|
+
},
|
|
2455
|
+
preset.label
|
|
2456
|
+
)) }) : null,
|
|
2457
|
+
/* @__PURE__ */ jsxs15(
|
|
2458
|
+
"div",
|
|
2459
|
+
{
|
|
2460
|
+
ref: scrollerRef,
|
|
2461
|
+
className: "flex-1 space-y-3 overflow-y-auto p-4",
|
|
1738
2462
|
children: [
|
|
1739
|
-
|
|
1740
|
-
|
|
2463
|
+
error ? /* @__PURE__ */ jsx18("p", { className: "bg-ph-danger/10 rounded-lg px-3 py-2 text-sm text-ph-danger", children: error }) : null,
|
|
2464
|
+
hydrating && messages.length === 0 ? /* @__PURE__ */ jsxs15("div", { className: "flex items-center gap-2 text-sm text-ph-mutedtext", children: [
|
|
2465
|
+
/* @__PURE__ */ jsx18(Spinner, { className: "h-4 w-4 animate-spin" }),
|
|
2466
|
+
"Loading chat\u2026"
|
|
2467
|
+
] }) : null,
|
|
2468
|
+
!hydrating && messages.length === 0 && !error ? /* @__PURE__ */ jsxs15("div", { className: "mt-10 px-2 text-center", children: [
|
|
2469
|
+
/* @__PURE__ */ jsx18("p", { className: "font-display text-base font-semibold text-ph-ink", children: "How can I help?" }),
|
|
2470
|
+
/* @__PURE__ */ jsx18("p", { className: "mt-2 text-sm leading-relaxed text-ph-subtle", children: emptyState })
|
|
2471
|
+
] }) : null,
|
|
2472
|
+
messages.map((message, index) => {
|
|
2473
|
+
const isUser = message.role === "user";
|
|
2474
|
+
return /* @__PURE__ */ jsxs15(
|
|
2475
|
+
"div",
|
|
2476
|
+
{
|
|
2477
|
+
className: isUser ? "ml-8 rounded-2xl bg-ph-brand/10 px-3.5 py-2.5 text-sm text-ph-ink" : "mr-4 rounded-2xl bg-ph-muted px-3.5 py-2.5 text-sm text-ph-ink",
|
|
2478
|
+
"data-test": isUser ? "ask-ai-user" : "ask-ai-assistant",
|
|
2479
|
+
children: [
|
|
2480
|
+
/* @__PURE__ */ jsx18("p", { className: "whitespace-pre-wrap", children: message.content }),
|
|
2481
|
+
!isUser ? /* @__PURE__ */ jsxs15(
|
|
2482
|
+
"button",
|
|
2483
|
+
{
|
|
2484
|
+
type: "button",
|
|
2485
|
+
onClick: () => void copyMessage(index, message.content),
|
|
2486
|
+
className: "mt-2 inline-flex items-center gap-1 text-xs text-ph-mutedtext hover:text-ph-ink",
|
|
2487
|
+
children: [
|
|
2488
|
+
copiedId === index ? /* @__PURE__ */ jsx18(Check2, { className: "h-3 w-3" }) : /* @__PURE__ */ jsx18(Copy, { className: "h-3 w-3" }),
|
|
2489
|
+
copiedId === index ? "Copied" : "Copy"
|
|
2490
|
+
]
|
|
2491
|
+
}
|
|
2492
|
+
) : null
|
|
2493
|
+
]
|
|
2494
|
+
},
|
|
2495
|
+
`${message.role}-${index}-${message.content.slice(0, 24)}`
|
|
2496
|
+
);
|
|
2497
|
+
}),
|
|
2498
|
+
loading ? /* @__PURE__ */ jsxs15("div", { className: "flex items-center gap-2 text-sm text-ph-mutedtext", children: [
|
|
2499
|
+
/* @__PURE__ */ jsx18(Spinner, { className: "h-4 w-4 animate-spin" }),
|
|
2500
|
+
"Thinking\u2026"
|
|
2501
|
+
] }) : null
|
|
1741
2502
|
]
|
|
1742
2503
|
}
|
|
1743
|
-
)
|
|
1744
|
-
|
|
1745
|
-
|
|
1746
|
-
|
|
1747
|
-
|
|
1748
|
-
|
|
1749
|
-
|
|
1750
|
-
|
|
1751
|
-
|
|
1752
|
-
|
|
1753
|
-
|
|
1754
|
-
|
|
1755
|
-
|
|
1756
|
-
|
|
2504
|
+
),
|
|
2505
|
+
/* @__PURE__ */ jsx18("div", { className: "border-t border-ph-border p-3", children: /* @__PURE__ */ jsxs15("div", { className: "flex gap-2", children: [
|
|
2506
|
+
/* @__PURE__ */ jsx18(
|
|
2507
|
+
"textarea",
|
|
2508
|
+
{
|
|
2509
|
+
value: prompt,
|
|
2510
|
+
onChange: (e) => setPrompt(e.target.value),
|
|
2511
|
+
onKeyDown: (e) => {
|
|
2512
|
+
if (e.key === "Enter" && !e.shiftKey) {
|
|
2513
|
+
e.preventDefault();
|
|
2514
|
+
void ask(prompt);
|
|
2515
|
+
}
|
|
2516
|
+
},
|
|
2517
|
+
placeholder: "Ask anything\u2026",
|
|
2518
|
+
rows: 2,
|
|
2519
|
+
disabled: loading,
|
|
2520
|
+
"data-test": "ask-ai-input",
|
|
2521
|
+
className: "flex-1 resize-none rounded-xl border border-ph-border bg-ph-canvas p-2.5 text-sm text-ph-ink outline-none focus:ring-1 focus:ring-ph-brand"
|
|
1757
2522
|
}
|
|
1758
|
-
|
|
1759
|
-
|
|
1760
|
-
|
|
1761
|
-
|
|
1762
|
-
|
|
1763
|
-
|
|
1764
|
-
|
|
1765
|
-
|
|
1766
|
-
|
|
1767
|
-
|
|
1768
|
-
|
|
1769
|
-
|
|
1770
|
-
|
|
1771
|
-
|
|
1772
|
-
|
|
1773
|
-
|
|
1774
|
-
|
|
1775
|
-
] }) })
|
|
1776
|
-
] })
|
|
1777
|
-
] })
|
|
2523
|
+
),
|
|
2524
|
+
/* @__PURE__ */ jsx18(
|
|
2525
|
+
"button",
|
|
2526
|
+
{
|
|
2527
|
+
type: "button",
|
|
2528
|
+
onClick: () => void ask(prompt),
|
|
2529
|
+
disabled: loading || !prompt.trim(),
|
|
2530
|
+
"data-test": "ask-ai-send",
|
|
2531
|
+
className: "self-end rounded-xl bg-ph-brand px-3.5 py-2 text-sm font-medium text-white disabled:opacity-50",
|
|
2532
|
+
children: "Ask"
|
|
2533
|
+
}
|
|
2534
|
+
)
|
|
2535
|
+
] }) })
|
|
2536
|
+
]
|
|
2537
|
+
}
|
|
2538
|
+
)
|
|
2539
|
+
] }) : null
|
|
1778
2540
|
] });
|
|
1779
2541
|
}
|
|
1780
2542
|
|
|
2543
|
+
// src/suite/lib/use-sidebar-width.ts
|
|
2544
|
+
import {
|
|
2545
|
+
useCallback as useCallback4,
|
|
2546
|
+
useEffect as useEffect8,
|
|
2547
|
+
useState as useState9
|
|
2548
|
+
} from "react";
|
|
2549
|
+
var SIDEBAR_RAIL_WIDTH = 56;
|
|
2550
|
+
var SIDEBAR_COLLAPSE_THRESHOLD = 80;
|
|
2551
|
+
var SIDEBAR_MIN_EXPANDED_WIDTH = 180;
|
|
2552
|
+
var SIDEBAR_MAX_WIDTH = 320;
|
|
2553
|
+
var SIDEBAR_DEFAULT_WIDTH = 320;
|
|
2554
|
+
function clampWidth(width) {
|
|
2555
|
+
return Math.min(SIDEBAR_MAX_WIDTH, Math.max(SIDEBAR_RAIL_WIDTH, width));
|
|
2556
|
+
}
|
|
2557
|
+
function snapWidth(width) {
|
|
2558
|
+
if (width <= SIDEBAR_COLLAPSE_THRESHOLD) return SIDEBAR_RAIL_WIDTH;
|
|
2559
|
+
if (width < SIDEBAR_MIN_EXPANDED_WIDTH) return SIDEBAR_MIN_EXPANDED_WIDTH;
|
|
2560
|
+
return Math.min(SIDEBAR_MAX_WIDTH, width);
|
|
2561
|
+
}
|
|
2562
|
+
function useSidebarWidth(storageKey) {
|
|
2563
|
+
const [width, setWidth] = useState9(SIDEBAR_DEFAULT_WIDTH);
|
|
2564
|
+
const [narrowViewport, setNarrowViewport] = useState9(false);
|
|
2565
|
+
const collapsed = narrowViewport || width <= SIDEBAR_COLLAPSE_THRESHOLD;
|
|
2566
|
+
useEffect8(() => {
|
|
2567
|
+
let stored = null;
|
|
2568
|
+
try {
|
|
2569
|
+
stored = localStorage.getItem(storageKey);
|
|
2570
|
+
} catch (e) {
|
|
2571
|
+
}
|
|
2572
|
+
if (!stored) return;
|
|
2573
|
+
const parsed = Number.parseInt(stored, 10);
|
|
2574
|
+
if (!Number.isNaN(parsed)) {
|
|
2575
|
+
queueMicrotask(() => setWidth(snapWidth(clampWidth(parsed))));
|
|
2576
|
+
}
|
|
2577
|
+
}, [storageKey]);
|
|
2578
|
+
useEffect8(() => {
|
|
2579
|
+
const media = window.matchMedia("(max-width: 639px)");
|
|
2580
|
+
const sync = () => setNarrowViewport(media.matches);
|
|
2581
|
+
sync();
|
|
2582
|
+
media.addEventListener("change", sync);
|
|
2583
|
+
return () => media.removeEventListener("change", sync);
|
|
2584
|
+
}, []);
|
|
2585
|
+
const persist = useCallback4(
|
|
2586
|
+
(value) => {
|
|
2587
|
+
try {
|
|
2588
|
+
localStorage.setItem(storageKey, String(value));
|
|
2589
|
+
} catch (e) {
|
|
2590
|
+
}
|
|
2591
|
+
},
|
|
2592
|
+
[storageKey]
|
|
2593
|
+
);
|
|
2594
|
+
const setCollapsed = useCallback4(
|
|
2595
|
+
(value) => {
|
|
2596
|
+
setWidth((current) => {
|
|
2597
|
+
const next = value ? SIDEBAR_RAIL_WIDTH : current <= SIDEBAR_COLLAPSE_THRESHOLD ? SIDEBAR_DEFAULT_WIDTH : snapWidth(current);
|
|
2598
|
+
persist(next);
|
|
2599
|
+
return next;
|
|
2600
|
+
});
|
|
2601
|
+
},
|
|
2602
|
+
[persist]
|
|
2603
|
+
);
|
|
2604
|
+
const resetWidth = useCallback4(() => {
|
|
2605
|
+
setWidth(SIDEBAR_DEFAULT_WIDTH);
|
|
2606
|
+
persist(SIDEBAR_DEFAULT_WIDTH);
|
|
2607
|
+
}, [persist]);
|
|
2608
|
+
const startResize = useCallback4(
|
|
2609
|
+
(event) => {
|
|
2610
|
+
event.preventDefault();
|
|
2611
|
+
const startX = event.clientX;
|
|
2612
|
+
const startWidth = width;
|
|
2613
|
+
const onMove = (moveEvent) => {
|
|
2614
|
+
setWidth(clampWidth(startWidth + moveEvent.clientX - startX));
|
|
2615
|
+
};
|
|
2616
|
+
const onUp = () => {
|
|
2617
|
+
document.removeEventListener("pointermove", onMove);
|
|
2618
|
+
document.removeEventListener("pointerup", onUp);
|
|
2619
|
+
setWidth((current) => {
|
|
2620
|
+
const snapped = snapWidth(current);
|
|
2621
|
+
persist(snapped);
|
|
2622
|
+
return snapped;
|
|
2623
|
+
});
|
|
2624
|
+
};
|
|
2625
|
+
document.addEventListener("pointermove", onMove);
|
|
2626
|
+
document.addEventListener("pointerup", onUp);
|
|
2627
|
+
},
|
|
2628
|
+
[persist, width]
|
|
2629
|
+
);
|
|
2630
|
+
return { width, collapsed, setCollapsed, resetWidth, startResize };
|
|
2631
|
+
}
|
|
2632
|
+
|
|
1781
2633
|
// src/suite/lib/motion.tsx
|
|
1782
2634
|
import { LazyMotion, domAnimation, m } from "motion/react";
|
|
1783
|
-
import { jsx as
|
|
2635
|
+
import { jsx as jsx19 } from "react/jsx-runtime";
|
|
1784
2636
|
function SuiteMotionProvider({ children }) {
|
|
1785
|
-
return /* @__PURE__ */
|
|
2637
|
+
return /* @__PURE__ */ jsx19(LazyMotion, { features: domAnimation, strict: true, children });
|
|
1786
2638
|
}
|
|
1787
2639
|
var SUITE_SPRINGS = {
|
|
1788
2640
|
/** Snappy panel/sheet entrances — small overshoot. */
|
|
@@ -1793,217 +2645,25 @@ var SUITE_SPRINGS = {
|
|
|
1793
2645
|
press: { type: "spring", stiffness: 600, damping: 35, mass: 0.5 }
|
|
1794
2646
|
};
|
|
1795
2647
|
|
|
1796
|
-
// src/suite/components/suite-layout.tsx
|
|
1797
|
-
import { jsx as jsx18, jsxs as jsxs14 } from "react/jsx-runtime";
|
|
1798
|
-
var WIDTHS = {
|
|
1799
|
-
full: "max-w-none",
|
|
1800
|
-
wide: "max-w-7xl",
|
|
1801
|
-
content: "max-w-6xl",
|
|
1802
|
-
narrow: "max-w-4xl"
|
|
1803
|
-
};
|
|
1804
|
-
function SuiteBreadcrumbs({ items, className }) {
|
|
1805
|
-
return /* @__PURE__ */ jsx18("nav", { "aria-label": "Breadcrumb", className, children: /* @__PURE__ */ jsx18("ol", { className: "flex min-w-0 items-center gap-1.5", children: items.map((item, index) => {
|
|
1806
|
-
const isLast = index === items.length - 1;
|
|
1807
|
-
return /* @__PURE__ */ jsxs14("li", { className: "flex min-w-0 items-center gap-1.5", children: [
|
|
1808
|
-
index > 0 ? /* @__PURE__ */ jsx18("span", { className: "select-none text-ph-border", "aria-hidden": "true", children: "/" }) : null,
|
|
1809
|
-
item.href && !isLast ? /* @__PURE__ */ jsx18(
|
|
1810
|
-
"a",
|
|
1811
|
-
{
|
|
1812
|
-
href: item.href,
|
|
1813
|
-
className: "truncate transition hover:text-ph-ink",
|
|
1814
|
-
children: item.label
|
|
1815
|
-
}
|
|
1816
|
-
) : /* @__PURE__ */ jsx18(
|
|
1817
|
-
"span",
|
|
1818
|
-
{
|
|
1819
|
-
className: cn(
|
|
1820
|
-
"truncate",
|
|
1821
|
-
isLast ? "font-medium text-ph-ink" : "text-ph-subtle"
|
|
1822
|
-
),
|
|
1823
|
-
"aria-current": isLast ? "page" : void 0,
|
|
1824
|
-
children: item.label
|
|
1825
|
-
}
|
|
1826
|
-
)
|
|
1827
|
-
] }, index);
|
|
1828
|
-
}) }) });
|
|
1829
|
-
}
|
|
1830
|
-
function SuitePage({
|
|
1831
|
-
children,
|
|
1832
|
-
width = "wide",
|
|
1833
|
-
inset = true,
|
|
1834
|
-
className,
|
|
1835
|
-
as: Component = "div",
|
|
1836
|
-
dataTest,
|
|
1837
|
-
id,
|
|
1838
|
-
role,
|
|
1839
|
-
"aria-live": ariaLive
|
|
1840
|
-
}) {
|
|
1841
|
-
return /* @__PURE__ */ jsx18(
|
|
1842
|
-
Component,
|
|
1843
|
-
{
|
|
1844
|
-
id,
|
|
1845
|
-
"data-test": dataTest,
|
|
1846
|
-
role,
|
|
1847
|
-
"aria-live": ariaLive,
|
|
1848
|
-
className: cn(
|
|
1849
|
-
"mx-auto flex w-full min-w-0 flex-col",
|
|
1850
|
-
WIDTHS[width],
|
|
1851
|
-
// Tight inset keeps page titles aligned without excessive whitespace.
|
|
1852
|
-
inset && "px-4 pb-5 pt-2 sm:px-6 sm:pb-6 sm:pt-3 lg:px-8",
|
|
1853
|
-
className
|
|
1854
|
-
),
|
|
1855
|
-
children
|
|
1856
|
-
}
|
|
1857
|
-
);
|
|
1858
|
-
}
|
|
1859
|
-
function SuitePageHeader({
|
|
1860
|
-
title,
|
|
1861
|
-
description,
|
|
1862
|
-
eyebrow,
|
|
1863
|
-
actions,
|
|
1864
|
-
className,
|
|
1865
|
-
titleClassName,
|
|
1866
|
-
dataTest,
|
|
1867
|
-
/** Optional icon rendered before the title. */
|
|
1868
|
-
icon,
|
|
1869
|
-
/** Use the animated sun/moon icon from the Today page. */
|
|
1870
|
-
todayIcon,
|
|
1871
|
-
todayIconClassName,
|
|
1872
|
-
/** Small badge/pill next to the title (e.g. "Beta", org name). */
|
|
1873
|
-
badge,
|
|
1874
|
-
/** Breadcrumb line rendered above the title. */
|
|
1875
|
-
breadcrumb
|
|
1876
|
-
}) {
|
|
1877
|
-
const resolvedIcon = todayIcon ? /* @__PURE__ */ jsx18(
|
|
1878
|
-
TodayTimeIcon,
|
|
1879
|
-
{
|
|
1880
|
-
className: cn(
|
|
1881
|
-
"h-6 w-6 sm:h-7 sm:w-7 text-amber-500",
|
|
1882
|
-
todayIconClassName
|
|
1883
|
-
)
|
|
1884
|
-
}
|
|
1885
|
-
) : icon;
|
|
1886
|
-
return /* @__PURE__ */ jsxs14(
|
|
1887
|
-
"header",
|
|
1888
|
-
{
|
|
1889
|
-
"data-test": dataTest,
|
|
1890
|
-
className: cn(
|
|
1891
|
-
"flex items-start justify-between gap-4 pb-2 sm:pb-3",
|
|
1892
|
-
className
|
|
1893
|
-
),
|
|
1894
|
-
children: [
|
|
1895
|
-
/* @__PURE__ */ jsxs14("div", { className: "flex min-w-0 items-start gap-3", children: [
|
|
1896
|
-
resolvedIcon ? /* @__PURE__ */ jsx18(
|
|
1897
|
-
"div",
|
|
1898
|
-
{
|
|
1899
|
-
className: "hidden shrink-0 pt-1 sm:block",
|
|
1900
|
-
"aria-hidden": "true",
|
|
1901
|
-
children: resolvedIcon
|
|
1902
|
-
}
|
|
1903
|
-
) : null,
|
|
1904
|
-
/* @__PURE__ */ jsxs14("div", { className: "flex min-w-0 flex-col gap-1", children: [
|
|
1905
|
-
eyebrow ? /* @__PURE__ */ jsx18("div", { className: "mb-0.5 flex min-w-0 items-center gap-1.5 text-xs text-ph-subtle", children: eyebrow }) : null,
|
|
1906
|
-
breadcrumb ? /* @__PURE__ */ jsx18("div", { className: "mb-0.5 flex min-w-0 items-center gap-1.5 text-xs text-ph-subtle", children: breadcrumb }) : null,
|
|
1907
|
-
/* @__PURE__ */ jsxs14("div", { className: "flex min-w-0 flex-wrap items-center gap-x-2 gap-y-1", children: [
|
|
1908
|
-
/* @__PURE__ */ jsx18(
|
|
1909
|
-
"h1",
|
|
1910
|
-
{
|
|
1911
|
-
className: cn(
|
|
1912
|
-
"font-display text-[1.625rem] font-bold leading-tight tracking-tight text-ph-ink sm:text-[2.25rem]",
|
|
1913
|
-
titleClassName
|
|
1914
|
-
),
|
|
1915
|
-
children: title
|
|
1916
|
-
}
|
|
1917
|
-
),
|
|
1918
|
-
badge ? /* @__PURE__ */ jsx18("span", { className: "rounded-md bg-ph-muted px-2 py-0.5 text-[11px] font-semibold uppercase tracking-wide text-ph-subtle", children: badge }) : null
|
|
1919
|
-
] }),
|
|
1920
|
-
description ? /* @__PURE__ */ jsx18("div", { className: "mt-1 max-w-2xl text-pretty text-sm leading-5 text-ph-subtle", children: description }) : null
|
|
1921
|
-
] })
|
|
1922
|
-
] }),
|
|
1923
|
-
actions ? /* @__PURE__ */ jsx18("div", { className: "flex shrink-0 items-center gap-2 pt-1", children: actions }) : null
|
|
1924
|
-
]
|
|
1925
|
-
}
|
|
1926
|
-
);
|
|
1927
|
-
}
|
|
1928
|
-
function SuiteToolbar({
|
|
1929
|
-
children,
|
|
1930
|
-
className,
|
|
1931
|
-
label = "Page tools",
|
|
1932
|
-
dataTest
|
|
1933
|
-
}) {
|
|
1934
|
-
return /* @__PURE__ */ jsx18(
|
|
1935
|
-
"div",
|
|
1936
|
-
{
|
|
1937
|
-
role: "toolbar",
|
|
1938
|
-
"aria-label": label,
|
|
1939
|
-
"data-test": dataTest,
|
|
1940
|
-
className: cn("flex min-w-0 flex-wrap items-center gap-2", className),
|
|
1941
|
-
children
|
|
1942
|
-
}
|
|
1943
|
-
);
|
|
1944
|
-
}
|
|
1945
|
-
function SuiteTabList({
|
|
1946
|
-
children,
|
|
1947
|
-
className,
|
|
1948
|
-
label,
|
|
1949
|
-
dataTest
|
|
1950
|
-
}) {
|
|
1951
|
-
return /* @__PURE__ */ jsx18(
|
|
1952
|
-
"nav",
|
|
1953
|
-
{
|
|
1954
|
-
"aria-label": label,
|
|
1955
|
-
"data-test": dataTest,
|
|
1956
|
-
className: cn(
|
|
1957
|
-
"flex min-w-0 flex-wrap gap-2 [&_a]:min-h-[48px] [&_button]:min-h-[48px] sm:[&_a]:min-h-[44px] sm:[&_button]:min-h-[44px]",
|
|
1958
|
-
className
|
|
1959
|
-
),
|
|
1960
|
-
children
|
|
1961
|
-
}
|
|
1962
|
-
);
|
|
1963
|
-
}
|
|
1964
|
-
function SuiteSectionHeader({
|
|
1965
|
-
title,
|
|
1966
|
-
description,
|
|
1967
|
-
action,
|
|
1968
|
-
className
|
|
1969
|
-
}) {
|
|
1970
|
-
return /* @__PURE__ */ jsxs14(
|
|
1971
|
-
"div",
|
|
1972
|
-
{
|
|
1973
|
-
className: cn(
|
|
1974
|
-
"flex min-w-0 flex-col gap-4 sm:flex-row sm:items-end sm:justify-between",
|
|
1975
|
-
className
|
|
1976
|
-
),
|
|
1977
|
-
children: [
|
|
1978
|
-
/* @__PURE__ */ jsxs14("div", { className: "min-w-0", children: [
|
|
1979
|
-
/* @__PURE__ */ jsx18("h2", { className: "font-display text-balance text-lg font-semibold tracking-tight text-ph-ink sm:text-xl", children: title }),
|
|
1980
|
-
description ? /* @__PURE__ */ jsx18("div", { className: "mt-1 max-w-2xl text-pretty text-sm leading-5 text-ph-subtle", children: description }) : null
|
|
1981
|
-
] }),
|
|
1982
|
-
action ? /* @__PURE__ */ jsx18("div", { className: "flex min-h-[44px] shrink-0 items-center", children: action }) : null
|
|
1983
|
-
]
|
|
1984
|
-
}
|
|
1985
|
-
);
|
|
1986
|
-
}
|
|
1987
|
-
|
|
1988
2648
|
// src/suite/components/suite-skeleton.tsx
|
|
1989
|
-
import { jsx as
|
|
2649
|
+
import { jsx as jsx20, jsxs as jsxs16 } from "react/jsx-runtime";
|
|
1990
2650
|
function SuiteSkeleton({
|
|
1991
2651
|
className,
|
|
1992
2652
|
lines = 1,
|
|
1993
2653
|
circle,
|
|
1994
2654
|
width
|
|
1995
2655
|
}) {
|
|
1996
|
-
return /* @__PURE__ */
|
|
2656
|
+
return /* @__PURE__ */ jsx20(
|
|
1997
2657
|
"div",
|
|
1998
2658
|
{
|
|
1999
2659
|
className: cn("space-y-2", circle ? "flex flex-col items-center" : ""),
|
|
2000
2660
|
"aria-hidden": true,
|
|
2001
|
-
children: Array.from({ length: lines }).map((_, index) => /* @__PURE__ */
|
|
2661
|
+
children: Array.from({ length: lines }).map((_, index) => /* @__PURE__ */ jsx20(
|
|
2002
2662
|
"div",
|
|
2003
2663
|
{
|
|
2004
2664
|
className: "animate-[skeleton-stagger_0.6s_ease-out_both]",
|
|
2005
2665
|
style: { animationDelay: `${index * 80}ms` },
|
|
2006
|
-
children: /* @__PURE__ */
|
|
2666
|
+
children: /* @__PURE__ */ jsx20(
|
|
2007
2667
|
"div",
|
|
2008
2668
|
{
|
|
2009
2669
|
className: cn(
|
|
@@ -2027,35 +2687,35 @@ function SuiteSkeletonCard({
|
|
|
2027
2687
|
rows = 3,
|
|
2028
2688
|
header = true
|
|
2029
2689
|
}) {
|
|
2030
|
-
return /* @__PURE__ */
|
|
2690
|
+
return /* @__PURE__ */ jsxs16(
|
|
2031
2691
|
"div",
|
|
2032
2692
|
{
|
|
2033
2693
|
className: cn(
|
|
2034
|
-
"ph-skeleton-card animate-[skeleton-stagger_0.5s_ease-out_both] rounded-2xl border border-ph-border
|
|
2694
|
+
"ph-skeleton-card animate-[skeleton-stagger_0.5s_ease-out_both] rounded-2xl border border-ph-border bg-ph-surface p-6 shadow-sm",
|
|
2035
2695
|
className
|
|
2036
2696
|
),
|
|
2037
2697
|
"aria-hidden": true,
|
|
2038
2698
|
children: [
|
|
2039
|
-
header ? /* @__PURE__ */
|
|
2699
|
+
header ? /* @__PURE__ */ jsxs16(
|
|
2040
2700
|
"div",
|
|
2041
2701
|
{
|
|
2042
2702
|
className: "mb-5 flex items-center gap-3 animate-[skeleton-stagger_0.5s_ease-out_both]",
|
|
2043
2703
|
style: { animationDelay: "100ms" },
|
|
2044
2704
|
children: [
|
|
2045
|
-
/* @__PURE__ */
|
|
2046
|
-
/* @__PURE__ */
|
|
2047
|
-
/* @__PURE__ */
|
|
2048
|
-
/* @__PURE__ */
|
|
2705
|
+
/* @__PURE__ */ jsx20("div", { className: "ph-skeleton h-10 w-10 rounded-xl" }),
|
|
2706
|
+
/* @__PURE__ */ jsxs16("div", { className: "flex-1 space-y-2", children: [
|
|
2707
|
+
/* @__PURE__ */ jsx20("div", { className: "ph-skeleton h-4 w-1/3" }),
|
|
2708
|
+
/* @__PURE__ */ jsx20("div", { className: "ph-skeleton h-3 w-1/2" })
|
|
2049
2709
|
] })
|
|
2050
2710
|
]
|
|
2051
2711
|
}
|
|
2052
2712
|
) : null,
|
|
2053
|
-
/* @__PURE__ */
|
|
2713
|
+
/* @__PURE__ */ jsx20("div", { className: "space-y-3", children: Array.from({ length: rows }).map((_, index) => /* @__PURE__ */ jsx20(
|
|
2054
2714
|
"div",
|
|
2055
2715
|
{
|
|
2056
2716
|
className: "animate-[skeleton-stagger_0.5s_ease-out_both]",
|
|
2057
2717
|
style: { animationDelay: `${200 + index * 80}ms` },
|
|
2058
|
-
children: /* @__PURE__ */
|
|
2718
|
+
children: /* @__PURE__ */ jsx20(
|
|
2059
2719
|
"div",
|
|
2060
2720
|
{
|
|
2061
2721
|
className: "ph-skeleton h-3",
|
|
@@ -2073,16 +2733,16 @@ function SuiteSkeletonList({
|
|
|
2073
2733
|
className,
|
|
2074
2734
|
items = 4
|
|
2075
2735
|
}) {
|
|
2076
|
-
return /* @__PURE__ */
|
|
2736
|
+
return /* @__PURE__ */ jsx20("div", { className: cn("space-y-3", className), "aria-hidden": true, children: Array.from({ length: items }).map((_, index) => /* @__PURE__ */ jsx20(
|
|
2077
2737
|
"div",
|
|
2078
2738
|
{
|
|
2079
2739
|
className: "animate-[skeleton-stagger_0.6s_ease-out_both]",
|
|
2080
2740
|
style: { animationDelay: `${index * 100}ms` },
|
|
2081
|
-
children: /* @__PURE__ */
|
|
2082
|
-
/* @__PURE__ */
|
|
2083
|
-
/* @__PURE__ */
|
|
2084
|
-
/* @__PURE__ */
|
|
2085
|
-
/* @__PURE__ */
|
|
2741
|
+
children: /* @__PURE__ */ jsxs16("div", { className: "flex items-center gap-3 rounded-xl border border-ph-border bg-ph-surface p-4", children: [
|
|
2742
|
+
/* @__PURE__ */ jsx20("div", { className: "ph-skeleton h-10 w-10 rounded-lg" }),
|
|
2743
|
+
/* @__PURE__ */ jsxs16("div", { className: "min-w-0 flex-1 space-y-2", children: [
|
|
2744
|
+
/* @__PURE__ */ jsx20("div", { className: "ph-skeleton h-3.5 w-3/4" }),
|
|
2745
|
+
/* @__PURE__ */ jsx20("div", { className: "ph-skeleton h-3 w-1/2" })
|
|
2086
2746
|
] })
|
|
2087
2747
|
] })
|
|
2088
2748
|
},
|
|
@@ -2097,22 +2757,22 @@ function SuiteEmptyState({
|
|
|
2097
2757
|
className,
|
|
2098
2758
|
size = "md"
|
|
2099
2759
|
}) {
|
|
2100
|
-
return /* @__PURE__ */
|
|
2760
|
+
return /* @__PURE__ */ jsxs16(
|
|
2101
2761
|
"div",
|
|
2102
2762
|
{
|
|
2103
2763
|
className: cn(
|
|
2104
|
-
"relative overflow-hidden rounded-2xl border border-ph-border
|
|
2764
|
+
"relative overflow-hidden rounded-2xl border border-ph-border bg-ph-surface text-center",
|
|
2105
2765
|
size === "sm" ? "px-5 py-8" : "px-6 py-12 sm:px-10 sm:py-16",
|
|
2106
2766
|
className
|
|
2107
2767
|
),
|
|
2108
2768
|
children: [
|
|
2109
|
-
/* @__PURE__ */
|
|
2110
|
-
/* @__PURE__ */
|
|
2111
|
-
/* @__PURE__ */
|
|
2769
|
+
/* @__PURE__ */ jsxs16("div", { className: "pointer-events-none absolute inset-0 overflow-hidden opacity-60", "aria-hidden": true, children: [
|
|
2770
|
+
/* @__PURE__ */ jsx20("div", { className: "absolute -left-10 -top-10 h-40 w-40 rounded-full bg-ph-brand/10 blur-3xl" }),
|
|
2771
|
+
/* @__PURE__ */ jsx20("div", { className: "absolute -bottom-10 -right-10 h-40 w-40 rounded-full bg-ph-accent/10 blur-3xl" })
|
|
2112
2772
|
] }),
|
|
2113
|
-
/* @__PURE__ */
|
|
2114
|
-
icon ? /* @__PURE__ */
|
|
2115
|
-
/* @__PURE__ */
|
|
2773
|
+
/* @__PURE__ */ jsxs16("div", { className: "relative", children: [
|
|
2774
|
+
icon ? /* @__PURE__ */ jsx20("div", { className: "mx-auto mb-4 inline-flex items-center justify-center rounded-2xl bg-ph-muted p-3 shadow-sm ring-1 ring-black/[0.06]", children: icon }) : null,
|
|
2775
|
+
/* @__PURE__ */ jsx20(
|
|
2116
2776
|
"h3",
|
|
2117
2777
|
{
|
|
2118
2778
|
className: cn(
|
|
@@ -2122,8 +2782,8 @@ function SuiteEmptyState({
|
|
|
2122
2782
|
children: title
|
|
2123
2783
|
}
|
|
2124
2784
|
),
|
|
2125
|
-
description ? /* @__PURE__ */
|
|
2126
|
-
action ? /* @__PURE__ */
|
|
2785
|
+
description ? /* @__PURE__ */ jsx20("p", { className: "mx-auto mt-2 max-w-sm text-sm leading-relaxed text-ph-subtle", children: description }) : null,
|
|
2786
|
+
action ? /* @__PURE__ */ jsx20("div", { className: "mt-5 flex flex-wrap items-center justify-center gap-2", children: action }) : null
|
|
2127
2787
|
] })
|
|
2128
2788
|
]
|
|
2129
2789
|
}
|
|
@@ -2132,23 +2792,25 @@ function SuiteEmptyState({
|
|
|
2132
2792
|
|
|
2133
2793
|
// src/suite/components/suite-settings-mobile-nav.tsx
|
|
2134
2794
|
import { isValidElement } from "react";
|
|
2135
|
-
import { jsx as
|
|
2795
|
+
import { jsx as jsx21, jsxs as jsxs17 } from "react/jsx-runtime";
|
|
2136
2796
|
function SuiteSettingsMobileNav({
|
|
2137
2797
|
items,
|
|
2138
2798
|
activeHref,
|
|
2139
2799
|
onSelect,
|
|
2140
|
-
dataTest
|
|
2800
|
+
dataTest,
|
|
2801
|
+
ariaLabel = "Settings sections",
|
|
2802
|
+
className
|
|
2141
2803
|
}) {
|
|
2142
|
-
return /* @__PURE__ */
|
|
2804
|
+
return /* @__PURE__ */ jsx21(
|
|
2143
2805
|
"nav",
|
|
2144
2806
|
{
|
|
2145
2807
|
"data-test": dataTest,
|
|
2146
|
-
"aria-label":
|
|
2147
|
-
className: "-
|
|
2148
|
-
children: /* @__PURE__ */
|
|
2808
|
+
"aria-label": ariaLabel,
|
|
2809
|
+
className: cn("suite-settings-mobile-nav lg:hidden", className),
|
|
2810
|
+
children: /* @__PURE__ */ jsx21("div", { className: "flex snap-x gap-2 overflow-x-auto pb-3 pt-1 scrollbar-hide [-ms-overflow-style:none] [scrollbar-width:none] [&::-webkit-scrollbar]:hidden", children: items.map((item) => {
|
|
2149
2811
|
const Icon = item.icon;
|
|
2150
2812
|
const active = activeHref === item.href || activeHref.startsWith(`${item.href}/`);
|
|
2151
|
-
const iconNode = isValidElement(item.icon) ? item.icon : /* @__PURE__ */
|
|
2813
|
+
const iconNode = isValidElement(item.icon) ? item.icon : /* @__PURE__ */ jsx21(
|
|
2152
2814
|
Icon,
|
|
2153
2815
|
{
|
|
2154
2816
|
className: cn(
|
|
@@ -2158,7 +2820,7 @@ function SuiteSettingsMobileNav({
|
|
|
2158
2820
|
"aria-hidden": true
|
|
2159
2821
|
}
|
|
2160
2822
|
);
|
|
2161
|
-
return /* @__PURE__ */
|
|
2823
|
+
return /* @__PURE__ */ jsxs17(
|
|
2162
2824
|
"button",
|
|
2163
2825
|
{
|
|
2164
2826
|
type: "button",
|
|
@@ -2166,14 +2828,14 @@ function SuiteSettingsMobileNav({
|
|
|
2166
2828
|
onClick: () => onSelect(item.href),
|
|
2167
2829
|
"aria-current": active ? "page" : void 0,
|
|
2168
2830
|
className: cn(
|
|
2169
|
-
"group relative flex shrink-0 snap-start items-center gap-2 rounded-full px-3.5 py-2.5 text-sm font-medium transition",
|
|
2831
|
+
"group relative flex shrink-0 snap-start items-center gap-2 rounded-full px-3.5 py-2.5 text-sm font-medium transition-colors",
|
|
2170
2832
|
"min-h-[44px] focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-ph-brand",
|
|
2171
2833
|
active ? "bg-ph-ink text-ph-surface shadow-sm" : "bg-ph-surface text-ph-subtle ring-1 ring-ph-border hover:bg-ph-muted hover:text-ph-ink"
|
|
2172
2834
|
),
|
|
2173
2835
|
children: [
|
|
2174
2836
|
iconNode,
|
|
2175
|
-
/* @__PURE__ */
|
|
2176
|
-
active ? /* @__PURE__ */
|
|
2837
|
+
/* @__PURE__ */ jsx21("span", { className: "whitespace-nowrap", children: item.label }),
|
|
2838
|
+
active ? /* @__PURE__ */ jsx21("span", { className: "absolute inset-x-0 -bottom-3 h-0.5 rounded-full bg-ph-ink lg:hidden" }) : null
|
|
2177
2839
|
]
|
|
2178
2840
|
},
|
|
2179
2841
|
item.href
|
|
@@ -2185,7 +2847,7 @@ function SuiteSettingsMobileNav({
|
|
|
2185
2847
|
|
|
2186
2848
|
// src/suite/components/suite-sidebar.tsx
|
|
2187
2849
|
import Link2 from "next/link";
|
|
2188
|
-
import { jsx as
|
|
2850
|
+
import { jsx as jsx22, jsxs as jsxs18 } from "react/jsx-runtime";
|
|
2189
2851
|
function renderNode(node, collapsed) {
|
|
2190
2852
|
if (typeof node === "function") return node(collapsed);
|
|
2191
2853
|
return node;
|
|
@@ -2202,7 +2864,7 @@ function SuiteSidebar({
|
|
|
2202
2864
|
className,
|
|
2203
2865
|
surface = false
|
|
2204
2866
|
}) {
|
|
2205
|
-
return /* @__PURE__ */
|
|
2867
|
+
return /* @__PURE__ */ jsxs18(
|
|
2206
2868
|
"div",
|
|
2207
2869
|
{
|
|
2208
2870
|
className: cn(
|
|
@@ -2211,7 +2873,7 @@ function SuiteSidebar({
|
|
|
2211
2873
|
className
|
|
2212
2874
|
),
|
|
2213
2875
|
children: [
|
|
2214
|
-
/* @__PURE__ */
|
|
2876
|
+
/* @__PURE__ */ jsxs18(
|
|
2215
2877
|
"div",
|
|
2216
2878
|
{
|
|
2217
2879
|
className: cn(
|
|
@@ -2220,12 +2882,12 @@ function SuiteSidebar({
|
|
|
2220
2882
|
collapsed ? "flex-col items-center gap-1 px-1 py-2" : "h-14 items-center justify-between gap-2 px-3"
|
|
2221
2883
|
),
|
|
2222
2884
|
children: [
|
|
2223
|
-
/* @__PURE__ */
|
|
2224
|
-
collapsed ? null : /* @__PURE__ */
|
|
2885
|
+
/* @__PURE__ */ jsx22("div", { className: cn("min-w-0", collapsed ? "shrink-0" : "flex-1"), children: renderNode(appSwitcher, collapsed) }),
|
|
2886
|
+
collapsed ? null : /* @__PURE__ */ jsx22("div", { className: "shrink-0", children: renderNode(notificationBell, collapsed) })
|
|
2225
2887
|
]
|
|
2226
2888
|
}
|
|
2227
2889
|
),
|
|
2228
|
-
/* @__PURE__ */
|
|
2890
|
+
/* @__PURE__ */ jsxs18(
|
|
2229
2891
|
"div",
|
|
2230
2892
|
{
|
|
2231
2893
|
className: cn(
|
|
@@ -2234,17 +2896,17 @@ function SuiteSidebar({
|
|
|
2234
2896
|
collapsed ? "px-1.5 py-2" : "p-2"
|
|
2235
2897
|
),
|
|
2236
2898
|
children: [
|
|
2237
|
-
/* @__PURE__ */
|
|
2899
|
+
/* @__PURE__ */ jsxs18(
|
|
2238
2900
|
"nav",
|
|
2239
2901
|
{
|
|
2240
2902
|
"aria-label": "Pages",
|
|
2241
2903
|
className: "shrink-0 space-y-0.5",
|
|
2242
2904
|
children: [
|
|
2243
|
-
/* @__PURE__ */
|
|
2244
|
-
/* @__PURE__ */
|
|
2905
|
+
/* @__PURE__ */ jsx22("div", { className: cn("mb-3", collapsed && "flex justify-center"), children: renderNode(contextSwitcher, collapsed) }),
|
|
2906
|
+
/* @__PURE__ */ jsx22("div", { className: "space-y-0.5", children: navItems.map((item) => {
|
|
2245
2907
|
const Icon = item.icon;
|
|
2246
2908
|
const active = Boolean(item.active);
|
|
2247
|
-
const link = /* @__PURE__ */
|
|
2909
|
+
const link = /* @__PURE__ */ jsxs18(
|
|
2248
2910
|
Link2,
|
|
2249
2911
|
{
|
|
2250
2912
|
href: item.href,
|
|
@@ -2257,7 +2919,7 @@ function SuiteSidebar({
|
|
|
2257
2919
|
collapsed ? "mx-auto size-10 shrink-0 justify-center gap-0 px-0 py-0" : "w-full px-2.5 py-2"
|
|
2258
2920
|
),
|
|
2259
2921
|
children: [
|
|
2260
|
-
/* @__PURE__ */
|
|
2922
|
+
/* @__PURE__ */ jsx22(
|
|
2261
2923
|
"span",
|
|
2262
2924
|
{
|
|
2263
2925
|
className: cn(
|
|
@@ -2265,7 +2927,7 @@ function SuiteSidebar({
|
|
|
2265
2927
|
item.iconClassName
|
|
2266
2928
|
),
|
|
2267
2929
|
"aria-hidden": true,
|
|
2268
|
-
children: /* @__PURE__ */
|
|
2930
|
+
children: /* @__PURE__ */ jsx22(
|
|
2269
2931
|
Icon,
|
|
2270
2932
|
{
|
|
2271
2933
|
className: "h-full w-full",
|
|
@@ -2274,7 +2936,7 @@ function SuiteSidebar({
|
|
|
2274
2936
|
)
|
|
2275
2937
|
}
|
|
2276
2938
|
),
|
|
2277
|
-
/* @__PURE__ */
|
|
2939
|
+
/* @__PURE__ */ jsx22(
|
|
2278
2940
|
"span",
|
|
2279
2941
|
{
|
|
2280
2942
|
className: cn(
|
|
@@ -2285,17 +2947,17 @@ function SuiteSidebar({
|
|
|
2285
2947
|
children: item.label
|
|
2286
2948
|
}
|
|
2287
2949
|
),
|
|
2288
|
-
!collapsed && item.badge ? /* @__PURE__ */
|
|
2950
|
+
!collapsed && item.badge ? /* @__PURE__ */ jsx22("span", { className: "relative ml-auto shrink-0", children: item.badge }) : null
|
|
2289
2951
|
]
|
|
2290
2952
|
},
|
|
2291
2953
|
item.label
|
|
2292
2954
|
);
|
|
2293
|
-
return collapsed ? /* @__PURE__ */
|
|
2955
|
+
return collapsed ? /* @__PURE__ */ jsx22(Tooltip, { content: item.label, side: "right", children: link }, item.label) : link;
|
|
2294
2956
|
}) })
|
|
2295
2957
|
]
|
|
2296
2958
|
}
|
|
2297
2959
|
),
|
|
2298
|
-
secondaryNav ? /* @__PURE__ */
|
|
2960
|
+
secondaryNav ? /* @__PURE__ */ jsx22(
|
|
2299
2961
|
"div",
|
|
2300
2962
|
{
|
|
2301
2963
|
className: "min-h-0 flex-1",
|
|
@@ -2306,7 +2968,7 @@ function SuiteSidebar({
|
|
|
2306
2968
|
]
|
|
2307
2969
|
}
|
|
2308
2970
|
),
|
|
2309
|
-
/* @__PURE__ */
|
|
2971
|
+
/* @__PURE__ */ jsx22(
|
|
2310
2972
|
"div",
|
|
2311
2973
|
{
|
|
2312
2974
|
className: cn(
|
|
@@ -2314,7 +2976,7 @@ function SuiteSidebar({
|
|
|
2314
2976
|
surface ? "bg-ph-surface" : "bg-ph-canvas",
|
|
2315
2977
|
collapsed ? "p-1.5" : "p-3"
|
|
2316
2978
|
),
|
|
2317
|
-
children: /* @__PURE__ */
|
|
2979
|
+
children: /* @__PURE__ */ jsxs18(
|
|
2318
2980
|
"div",
|
|
2319
2981
|
{
|
|
2320
2982
|
className: cn(
|
|
@@ -2323,7 +2985,7 @@ function SuiteSidebar({
|
|
|
2323
2985
|
),
|
|
2324
2986
|
children: [
|
|
2325
2987
|
renderNode(userMenu, collapsed),
|
|
2326
|
-
!collapsed && footerExtras ? /* @__PURE__ */
|
|
2988
|
+
!collapsed && footerExtras ? /* @__PURE__ */ jsx22("div", { className: "ml-auto shrink-0", children: renderNode(footerExtras, collapsed) }) : null
|
|
2327
2989
|
]
|
|
2328
2990
|
}
|
|
2329
2991
|
)
|
|
@@ -2335,7 +2997,7 @@ function SuiteSidebar({
|
|
|
2335
2997
|
}
|
|
2336
2998
|
|
|
2337
2999
|
// src/suite/components/suite-app-layout.tsx
|
|
2338
|
-
import { jsx as
|
|
3000
|
+
import { jsx as jsx23, jsxs as jsxs19 } from "react/jsx-runtime";
|
|
2339
3001
|
function SuiteAppLayout({
|
|
2340
3002
|
sidebar,
|
|
2341
3003
|
children,
|
|
@@ -2343,41 +3005,59 @@ function SuiteAppLayout({
|
|
|
2343
3005
|
bottomNav,
|
|
2344
3006
|
sidebarWidth = 240,
|
|
2345
3007
|
collapsed = false,
|
|
3008
|
+
lockMainScroll = false,
|
|
2346
3009
|
onStartResize,
|
|
2347
3010
|
onResetWidth,
|
|
2348
3011
|
className
|
|
2349
3012
|
}) {
|
|
2350
|
-
return /* @__PURE__ */
|
|
2351
|
-
|
|
2352
|
-
|
|
2353
|
-
|
|
2354
|
-
|
|
2355
|
-
|
|
2356
|
-
|
|
2357
|
-
|
|
2358
|
-
|
|
2359
|
-
|
|
2360
|
-
|
|
2361
|
-
|
|
2362
|
-
|
|
2363
|
-
|
|
2364
|
-
|
|
2365
|
-
|
|
2366
|
-
|
|
2367
|
-
|
|
2368
|
-
|
|
2369
|
-
|
|
2370
|
-
|
|
2371
|
-
|
|
2372
|
-
|
|
2373
|
-
|
|
2374
|
-
|
|
2375
|
-
|
|
2376
|
-
|
|
2377
|
-
|
|
2378
|
-
|
|
2379
|
-
|
|
2380
|
-
|
|
3013
|
+
return /* @__PURE__ */ jsxs19(
|
|
3014
|
+
"div",
|
|
3015
|
+
{
|
|
3016
|
+
"data-test": "app-shell",
|
|
3017
|
+
className: cn("flex min-h-dvh lg:h-screen lg:overflow-hidden", className),
|
|
3018
|
+
children: [
|
|
3019
|
+
/* @__PURE__ */ jsxs19(
|
|
3020
|
+
"aside",
|
|
3021
|
+
{
|
|
3022
|
+
className: "relative hidden shrink-0 flex-col overflow-hidden border-r border-ph-border transition-[width] duration-200 ease-out lg:flex",
|
|
3023
|
+
style: { width: `${sidebarWidth}px` },
|
|
3024
|
+
"data-collapsed": collapsed ? "true" : "false",
|
|
3025
|
+
children: [
|
|
3026
|
+
sidebar,
|
|
3027
|
+
onStartResize ? /* @__PURE__ */ jsx23(
|
|
3028
|
+
"div",
|
|
3029
|
+
{
|
|
3030
|
+
role: "separator",
|
|
3031
|
+
"aria-orientation": "vertical",
|
|
3032
|
+
"aria-label": "Resize sidebar",
|
|
3033
|
+
onPointerDown: onStartResize,
|
|
3034
|
+
onDoubleClick: onResetWidth,
|
|
3035
|
+
className: "absolute inset-y-0 right-0 z-10 w-1 cursor-col-resize transition-colors hover:bg-[color-mix(in_oklab,var(--ph-accent)_30%,transparent)]"
|
|
3036
|
+
}
|
|
3037
|
+
) : null
|
|
3038
|
+
]
|
|
3039
|
+
}
|
|
3040
|
+
),
|
|
3041
|
+
/* @__PURE__ */ jsxs19("div", { className: "flex min-h-0 min-w-0 flex-1 flex-col", children: [
|
|
3042
|
+
mobileHeader ? /* @__PURE__ */ jsx23("div", { className: "shrink-0 lg:hidden", children: mobileHeader }) : null,
|
|
3043
|
+
/* @__PURE__ */ jsx23(
|
|
3044
|
+
"main",
|
|
3045
|
+
{
|
|
3046
|
+
id: "main-content",
|
|
3047
|
+
tabIndex: -1,
|
|
3048
|
+
"data-lock-scroll": lockMainScroll ? "true" : void 0,
|
|
3049
|
+
className: cn(
|
|
3050
|
+
"flex min-h-0 min-w-0 flex-1 flex-col overflow-x-hidden overscroll-contain bg-ph-canvas focus:outline-none",
|
|
3051
|
+
lockMainScroll ? "overflow-hidden" : "overflow-y-auto"
|
|
3052
|
+
),
|
|
3053
|
+
children
|
|
3054
|
+
}
|
|
3055
|
+
),
|
|
3056
|
+
bottomNav ? /* @__PURE__ */ jsx23("div", { className: "shrink-0 lg:hidden", children: bottomNav }) : null
|
|
3057
|
+
] })
|
|
3058
|
+
]
|
|
3059
|
+
}
|
|
3060
|
+
);
|
|
2381
3061
|
}
|
|
2382
3062
|
export {
|
|
2383
3063
|
APP_ACCENTS,
|
|
@@ -2389,10 +3069,16 @@ export {
|
|
|
2389
3069
|
AppSwitcherMark,
|
|
2390
3070
|
CommandPaletteHost,
|
|
2391
3071
|
DeferredChrome,
|
|
3072
|
+
SIDEBAR_COLLAPSE_THRESHOLD,
|
|
3073
|
+
SIDEBAR_DEFAULT_WIDTH,
|
|
3074
|
+
SIDEBAR_MAX_WIDTH,
|
|
3075
|
+
SIDEBAR_MIN_EXPANDED_WIDTH,
|
|
3076
|
+
SIDEBAR_RAIL_WIDTH,
|
|
2392
3077
|
SUITE_APPS2 as SUITE_APPS,
|
|
2393
3078
|
SUITE_APP_MAP,
|
|
2394
3079
|
SUITE_GLYPHS,
|
|
2395
3080
|
SUITE_ICON_NAMES,
|
|
3081
|
+
SUITE_OPEN_ASK_AI_EVENT,
|
|
2396
3082
|
SUITE_SPRINGS,
|
|
2397
3083
|
SourceAppGlyph,
|
|
2398
3084
|
SuiteAiPanel,
|
|
@@ -2410,6 +3096,7 @@ export {
|
|
|
2410
3096
|
SuitePage,
|
|
2411
3097
|
SuitePageHeader,
|
|
2412
3098
|
SuiteSectionHeader,
|
|
3099
|
+
SuiteSettingsLayout,
|
|
2413
3100
|
SuiteSettingsMobileNav,
|
|
2414
3101
|
SuiteSidebar,
|
|
2415
3102
|
SuiteSkeleton,
|
|
@@ -2419,11 +3106,15 @@ export {
|
|
|
2419
3106
|
SuiteThemeProvider,
|
|
2420
3107
|
SuiteToolbar,
|
|
2421
3108
|
SuiteUserMenu,
|
|
3109
|
+
TodayAskAiCard,
|
|
2422
3110
|
TodayCalibrating,
|
|
3111
|
+
TodayEmptyAction,
|
|
2423
3112
|
TodayEmptyState,
|
|
2424
3113
|
TodayHero,
|
|
3114
|
+
TodayLayout,
|
|
2425
3115
|
TodayPageFrame,
|
|
2426
3116
|
TodayPanel,
|
|
3117
|
+
TodayPrimaryAction,
|
|
2427
3118
|
TodaySection,
|
|
2428
3119
|
TodayTimeIcon,
|
|
2429
3120
|
TodayTopBar,
|
|
@@ -2433,9 +3124,12 @@ export {
|
|
|
2433
3124
|
cn,
|
|
2434
3125
|
getTodayGreeting,
|
|
2435
3126
|
m,
|
|
3127
|
+
openSuiteAskAi,
|
|
3128
|
+
resolveSuiteNotificationHref,
|
|
2436
3129
|
sourceToSuiteApp,
|
|
2437
3130
|
suiteAppBaseUrl,
|
|
2438
3131
|
suiteAppLabel,
|
|
2439
3132
|
useIdleMount,
|
|
3133
|
+
useSidebarWidth,
|
|
2440
3134
|
useSuiteTheme
|
|
2441
3135
|
};
|