@floegence/floe-webapp-core 0.26.0 → 0.26.2
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/app/ActivityAppsMain.d.ts +1 -1
- package/dist/app/ActivityAppsMain.js +4 -4
- package/dist/components/launchpad/LaunchpadModal.d.ts +28 -0
- package/dist/components/launchpad/LaunchpadModal.js +113 -0
- package/dist/components/launchpad/index.d.ts +2 -0
- package/dist/components/layout/Shell.js +129 -119
- package/dist/components/layout/mobileTabs.d.ts +6 -0
- package/dist/components/layout/mobileTabs.js +1 -1
- package/dist/context/ComponentRegistry.d.ts +9 -0
- package/dist/full.js +250 -248
- package/dist/launchpad.js +12 -10
- package/package.json +1 -1
|
@@ -11,7 +11,7 @@ export interface ActivityAppsMainProps<TProtocol = unknown> {
|
|
|
11
11
|
*/
|
|
12
12
|
views?: KeepAliveView[];
|
|
13
13
|
/**
|
|
14
|
-
* Registry-driven filter (default: sidebar.fullScreen === true).
|
|
14
|
+
* Registry-driven filter (default: sidebar.fullScreen === true OR sidebar.renderIn === 'main').
|
|
15
15
|
* Only used when `views` is not provided.
|
|
16
16
|
*/
|
|
17
17
|
include?: (component: FloeComponent<TProtocol>) => boolean;
|
|
@@ -4,7 +4,7 @@ import { useLayout as l } from "../context/LayoutContext.js";
|
|
|
4
4
|
import { useComponentRegistry as v } from "../context/ComponentRegistry.js";
|
|
5
5
|
import { KeepAliveStack as f } from "../components/layout/KeepAliveStack.js";
|
|
6
6
|
function y(e) {
|
|
7
|
-
return e.sidebar?.fullScreen === !0;
|
|
7
|
+
return e.sidebar?.fullScreen === !0 || e.sidebar?.renderIn === "main";
|
|
8
8
|
}
|
|
9
9
|
function A(e) {
|
|
10
10
|
const i = l(), r = (() => {
|
|
@@ -16,7 +16,7 @@ function A(e) {
|
|
|
16
16
|
})();
|
|
17
17
|
if (!d(() => !!e.views) && !r)
|
|
18
18
|
throw new Error("ActivityAppsMain requires ComponentRegistryProvider when `views` is not provided.");
|
|
19
|
-
const o = () => e.activeId ? e.activeId() : i.sidebarActiveTab(),
|
|
19
|
+
const o = () => e.activeId ? e.activeId() : i.sidebarActiveTab(), u = m(() => {
|
|
20
20
|
if (!r) return [];
|
|
21
21
|
const s = e.include ?? y;
|
|
22
22
|
return r.sidebarItems().filter((t) => s(t)).map((t) => ({
|
|
@@ -27,10 +27,10 @@ function A(e) {
|
|
|
27
27
|
}
|
|
28
28
|
})
|
|
29
29
|
}));
|
|
30
|
-
}),
|
|
30
|
+
}), c = () => e.views ?? u();
|
|
31
31
|
return n(f, {
|
|
32
32
|
get views() {
|
|
33
|
-
return
|
|
33
|
+
return c();
|
|
34
34
|
},
|
|
35
35
|
get activeId() {
|
|
36
36
|
return o();
|
|
@@ -0,0 +1,28 @@
|
|
|
1
|
+
import { type JSX } from 'solid-js';
|
|
2
|
+
import { type LaunchpadItemData } from './Launchpad';
|
|
3
|
+
export interface LaunchpadModalProps {
|
|
4
|
+
open: boolean;
|
|
5
|
+
onOpenChange: (open: boolean) => void;
|
|
6
|
+
items: LaunchpadItemData[];
|
|
7
|
+
additionalItems?: LaunchpadItemData[];
|
|
8
|
+
itemsPerPage?: number;
|
|
9
|
+
columns?: number;
|
|
10
|
+
showSearch?: boolean;
|
|
11
|
+
class?: string;
|
|
12
|
+
style?: JSX.CSSProperties;
|
|
13
|
+
/** Called after the modal reacts (closes first when closeOnSelect is enabled). */
|
|
14
|
+
onSelect?: (item: LaunchpadItemData) => void;
|
|
15
|
+
/**
|
|
16
|
+
* Whether to close the modal when an item is selected (default: true).
|
|
17
|
+
* Use a function for per-item control.
|
|
18
|
+
*/
|
|
19
|
+
closeOnSelect?: boolean | ((item: LaunchpadItemData) => boolean);
|
|
20
|
+
}
|
|
21
|
+
/**
|
|
22
|
+
* Modal wrapper for Launchpad.
|
|
23
|
+
*
|
|
24
|
+
* Guarantees "mask semantics":
|
|
25
|
+
* - Wheel keeps Launchpad pagination working but prevents background scroll.
|
|
26
|
+
* - Escape closes the modal and does not leak to underlying global shortcuts.
|
|
27
|
+
*/
|
|
28
|
+
export declare function LaunchpadModal(props: LaunchpadModalProps): JSX.Element;
|
|
@@ -0,0 +1,113 @@
|
|
|
1
|
+
import { createComponent as f, Portal as P, insert as T, template as D, use as M } from "solid-js/web";
|
|
2
|
+
import { createMemo as s, createEffect as x, onCleanup as B, Show as I } from "solid-js";
|
|
3
|
+
import { lockBodyStyle as O } from "../../utils/bodyStyleLock.js";
|
|
4
|
+
import { deferNonBlocking as A } from "../../utils/defer.js";
|
|
5
|
+
import { Launchpad as F } from "./Launchpad.js";
|
|
6
|
+
var H = /* @__PURE__ */ D("<div role=dialog aria-modal=true tabindex=-1>");
|
|
7
|
+
function y(n) {
|
|
8
|
+
const c = ["a[href]", "button:not([disabled])", "input:not([disabled])", "select:not([disabled])", "textarea:not([disabled])", '[tabindex]:not([tabindex="-1"])', '[contenteditable="true"]'].join(",");
|
|
9
|
+
return Array.from(n.querySelectorAll(c)).filter((u) => u instanceof HTMLElement);
|
|
10
|
+
}
|
|
11
|
+
function N(n) {
|
|
12
|
+
let c;
|
|
13
|
+
const u = s(() => n.onOpenChange), w = s(() => n.onSelect), i = () => u()(!1), L = s(() => n.items.map((t) => ({
|
|
14
|
+
...t,
|
|
15
|
+
onClick: void 0
|
|
16
|
+
}))), k = s(() => n.additionalItems?.map((t) => ({
|
|
17
|
+
...t,
|
|
18
|
+
onClick: void 0
|
|
19
|
+
}))), C = (t) => {
|
|
20
|
+
const o = n.closeOnSelect;
|
|
21
|
+
return typeof o == "function" ? o(t) : o !== !1;
|
|
22
|
+
}, S = (t) => {
|
|
23
|
+
C(t) && i();
|
|
24
|
+
const o = w();
|
|
25
|
+
o && A(() => o(t));
|
|
26
|
+
};
|
|
27
|
+
return x(() => {
|
|
28
|
+
if (!n.open || typeof document > "u") return;
|
|
29
|
+
const t = document.activeElement instanceof HTMLElement ? document.activeElement : null, o = O({
|
|
30
|
+
overflow: "hidden"
|
|
31
|
+
});
|
|
32
|
+
setTimeout(() => {
|
|
33
|
+
const e = c;
|
|
34
|
+
if (!e) return;
|
|
35
|
+
const r = e.querySelector(".launchpad-search input");
|
|
36
|
+
if (r) {
|
|
37
|
+
r.focus();
|
|
38
|
+
return;
|
|
39
|
+
}
|
|
40
|
+
(y(e)[0] ?? e).focus();
|
|
41
|
+
}, 0);
|
|
42
|
+
const m = (e) => {
|
|
43
|
+
if (e.key !== "Tab") return;
|
|
44
|
+
const r = c;
|
|
45
|
+
if (!r) return;
|
|
46
|
+
const a = y(r);
|
|
47
|
+
if (!a.length) {
|
|
48
|
+
e.preventDefault(), r.focus();
|
|
49
|
+
return;
|
|
50
|
+
}
|
|
51
|
+
const d = a[0], b = a[a.length - 1], l = document.activeElement instanceof HTMLElement ? document.activeElement : null;
|
|
52
|
+
e.shiftKey ? (l === d || !l || !r.contains(l)) && (e.preventDefault(), b.focus()) : l === b && (e.preventDefault(), d.focus());
|
|
53
|
+
}, v = (e) => {
|
|
54
|
+
e.key === "Escape" && (e.preventDefault(), e.stopImmediatePropagation(), i());
|
|
55
|
+
}, h = (e) => {
|
|
56
|
+
e.stopPropagation();
|
|
57
|
+
}, p = (e) => {
|
|
58
|
+
e.cancelable && e.preventDefault();
|
|
59
|
+
}, g = (e) => {
|
|
60
|
+
e.stopPropagation();
|
|
61
|
+
}, E = (e) => {
|
|
62
|
+
e.cancelable && e.preventDefault();
|
|
63
|
+
};
|
|
64
|
+
document.addEventListener("keydown", m, !0), window.addEventListener("keydown", v, !0), document.addEventListener("keydown", h), document.addEventListener("wheel", p, {
|
|
65
|
+
capture: !0,
|
|
66
|
+
passive: !1
|
|
67
|
+
}), document.addEventListener("wheel", g), document.addEventListener("touchmove", E, {
|
|
68
|
+
capture: !0,
|
|
69
|
+
passive: !1
|
|
70
|
+
}), B(() => {
|
|
71
|
+
document.removeEventListener("keydown", m, !0), window.removeEventListener("keydown", v, !0), document.removeEventListener("keydown", h), document.removeEventListener("wheel", p, !0), document.removeEventListener("wheel", g), document.removeEventListener("touchmove", E, !0), o(), t?.focus();
|
|
72
|
+
});
|
|
73
|
+
}), f(I, {
|
|
74
|
+
get when() {
|
|
75
|
+
return n.open;
|
|
76
|
+
},
|
|
77
|
+
get children() {
|
|
78
|
+
return f(P, {
|
|
79
|
+
get children() {
|
|
80
|
+
var t = H(), o = c;
|
|
81
|
+
return typeof o == "function" ? M(o, t) : c = t, T(t, f(F, {
|
|
82
|
+
get items() {
|
|
83
|
+
return L();
|
|
84
|
+
},
|
|
85
|
+
get additionalItems() {
|
|
86
|
+
return k();
|
|
87
|
+
},
|
|
88
|
+
get itemsPerPage() {
|
|
89
|
+
return n.itemsPerPage;
|
|
90
|
+
},
|
|
91
|
+
get columns() {
|
|
92
|
+
return n.columns;
|
|
93
|
+
},
|
|
94
|
+
get showSearch() {
|
|
95
|
+
return n.showSearch;
|
|
96
|
+
},
|
|
97
|
+
get class() {
|
|
98
|
+
return n.class;
|
|
99
|
+
},
|
|
100
|
+
get style() {
|
|
101
|
+
return n.style;
|
|
102
|
+
},
|
|
103
|
+
onItemClick: S,
|
|
104
|
+
onClose: i
|
|
105
|
+
})), t;
|
|
106
|
+
}
|
|
107
|
+
});
|
|
108
|
+
}
|
|
109
|
+
});
|
|
110
|
+
}
|
|
111
|
+
export {
|
|
112
|
+
N as LaunchpadModal
|
|
113
|
+
};
|
|
@@ -1,5 +1,7 @@
|
|
|
1
1
|
export { Launchpad } from './Launchpad';
|
|
2
2
|
export type { LaunchpadProps, LaunchpadItemData } from './Launchpad';
|
|
3
|
+
export { LaunchpadModal } from './LaunchpadModal';
|
|
4
|
+
export type { LaunchpadModalProps } from './LaunchpadModal';
|
|
3
5
|
export { LaunchpadItem } from './LaunchpadItem';
|
|
4
6
|
export type { LaunchpadItemProps } from './LaunchpadItem';
|
|
5
7
|
export { LaunchpadGrid } from './LaunchpadGrid';
|
|
@@ -1,258 +1,268 @@
|
|
|
1
|
-
import { createComponent as
|
|
2
|
-
import { createSignal as
|
|
3
|
-
import { useLayout as
|
|
4
|
-
import { useResolvedFloeConfig as
|
|
5
|
-
import { useMediaQuery as
|
|
1
|
+
import { createComponent as r, Dynamic as S, insert as c, memo as C, effect as T, className as M, setStyleProperty as E, template as h, delegateEvents as N } from "solid-js/web";
|
|
2
|
+
import { createSignal as Q, createEffect as v, createMemo as f, For as $, Show as m } from "solid-js";
|
|
3
|
+
import { useLayout as D } from "../../context/LayoutContext.js";
|
|
4
|
+
import { useResolvedFloeConfig as K } from "../../context/FloeConfigContext.js";
|
|
5
|
+
import { useMediaQuery as L } from "../../hooks/useMediaQuery.js";
|
|
6
6
|
import { cn as x } from "../../utils/cn.js";
|
|
7
|
-
import { deferNonBlocking as
|
|
8
|
-
import { useComponentRegistry as
|
|
9
|
-
import { Sidebar as
|
|
10
|
-
import { TopBar as
|
|
11
|
-
import { TopBarIconButton as
|
|
12
|
-
import { BottomBar as
|
|
13
|
-
import { MobileTabBar as
|
|
14
|
-
import { ActivityBar as
|
|
7
|
+
import { deferNonBlocking as V } from "../../utils/defer.js";
|
|
8
|
+
import { useComponentRegistry as j } from "../../context/ComponentRegistry.js";
|
|
9
|
+
import { Sidebar as q } from "./Sidebar.js";
|
|
10
|
+
import { TopBar as G } from "./TopBar.js";
|
|
11
|
+
import { TopBarIconButton as J } from "./TopBarIconButton.js";
|
|
12
|
+
import { BottomBar as U } from "./BottomBar.js";
|
|
13
|
+
import { MobileTabBar as X } from "./MobileTabBar.js";
|
|
14
|
+
import { ActivityBar as Y } from "./ActivityBar.js";
|
|
15
15
|
import { ResizeHandle as _ } from "./ResizeHandle.js";
|
|
16
|
-
import { resolveMobileTabActiveId as
|
|
17
|
-
import { KeepAliveStack as
|
|
18
|
-
var k = /* @__PURE__ */
|
|
19
|
-
function
|
|
20
|
-
const
|
|
16
|
+
import { resolveMobileTabActiveId as Z, resolveMobileTabSelect as ee } from "./mobileTabs.js";
|
|
17
|
+
import { KeepAliveStack as te } from "./KeepAliveStack.js";
|
|
18
|
+
var k = /* @__PURE__ */ h('<div class="flex items-center gap-2">'), re = /* @__PURE__ */ h('<div class="absolute inset-0 z-40 bg-black/30 cursor-pointer">'), ie = /* @__PURE__ */ h('<div><div class="h-full overflow-auto overscroll-contain">'), ne = /* @__PURE__ */ h('<div class="relative shrink-0 border-t border-border bg-terminal-background overflow-hidden">'), oe = /* @__PURE__ */ h('<div><div class="flex-1 min-h-0 flex overflow-hidden relative"><div class="flex-1 min-w-0 flex flex-col overflow-hidden"><main class="flex-1 min-h-0 overflow-auto overscroll-contain">');
|
|
19
|
+
function Be(o) {
|
|
20
|
+
const i = D(), O = K(), d = L(O.config.layout.mobileQuery), [I, b] = Q(!1), u = () => o.sidebarMode === "hidden", a = (() => {
|
|
21
21
|
try {
|
|
22
|
-
return
|
|
22
|
+
return j();
|
|
23
23
|
} catch {
|
|
24
24
|
return null;
|
|
25
25
|
}
|
|
26
|
-
})(),
|
|
27
|
-
const l =
|
|
28
|
-
|
|
29
|
-
openSidebar:
|
|
26
|
+
})(), w = (e, s) => {
|
|
27
|
+
const l = a?.getComponent(e)?.sidebar?.fullScreen ?? !1, t = u() ? !1 : s?.openSidebar ?? !l;
|
|
28
|
+
i.setSidebarActiveTab(e, {
|
|
29
|
+
openSidebar: t
|
|
30
30
|
});
|
|
31
31
|
};
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
}),
|
|
35
|
-
const e =
|
|
36
|
-
|
|
37
|
-
}),
|
|
38
|
-
|
|
32
|
+
v(() => {
|
|
33
|
+
u() && b(!1);
|
|
34
|
+
}), v(() => {
|
|
35
|
+
const e = d();
|
|
36
|
+
i.isMobile() !== e && i.setIsMobile(e);
|
|
37
|
+
}), v(() => {
|
|
38
|
+
d() || b(!1);
|
|
39
39
|
});
|
|
40
|
-
const
|
|
40
|
+
const g = f(() => o.activityItems ? o.activityItems : a ? a.sidebarItems().filter((e) => !!e.icon).filter((e) => !(d() && e.sidebar?.hiddenOnMobile)).map((e) => ({
|
|
41
41
|
id: e.id,
|
|
42
42
|
icon: e.icon,
|
|
43
43
|
label: e.name,
|
|
44
44
|
badge: e.sidebar?.badge,
|
|
45
45
|
collapseBehavior: e.sidebar?.fullScreen ? "preserve" : "toggle"
|
|
46
|
-
})) : []), z =
|
|
46
|
+
})) : []), z = f(() => u() ? [] : o.sidebarContent ? [] : a ? a.sidebarItems().filter((e) => !(d() && e.sidebar?.hiddenOnMobile)).filter((e) => e.sidebar?.fullScreen !== !0 && e.sidebar?.renderIn !== "main").map((e) => ({
|
|
47
47
|
id: e.id,
|
|
48
|
-
render: () =>
|
|
48
|
+
render: () => r(S, {
|
|
49
49
|
get component() {
|
|
50
50
|
return e.component;
|
|
51
51
|
}
|
|
52
52
|
})
|
|
53
|
-
})) : []),
|
|
54
|
-
if (!
|
|
53
|
+
})) : []), y = (e) => {
|
|
54
|
+
if (!u()) {
|
|
55
55
|
if (o.sidebarContent) return o.sidebarContent(e);
|
|
56
|
-
if (
|
|
57
|
-
return
|
|
56
|
+
if (a)
|
|
57
|
+
return r(te, {
|
|
58
58
|
get views() {
|
|
59
59
|
return z();
|
|
60
60
|
},
|
|
61
61
|
activeId: e
|
|
62
62
|
});
|
|
63
63
|
}
|
|
64
|
-
}, B =
|
|
65
|
-
|
|
66
|
-
|
|
64
|
+
}, B = f(() => u() ? !0 : a ? a.getComponent(i.sidebarActiveTab())?.sidebar?.fullScreen ?? !1 : !1), F = f(() => {
|
|
65
|
+
if (u()) return !0;
|
|
66
|
+
if (!a) return !1;
|
|
67
|
+
const e = a.getComponent(i.sidebarActiveTab());
|
|
68
|
+
return e?.sidebar ? e.sidebar.fullScreen === !0 || e.sidebar.renderIn === "main" : !1;
|
|
67
69
|
});
|
|
68
|
-
|
|
70
|
+
v(() => {
|
|
71
|
+
d() && B() && b(!1);
|
|
72
|
+
});
|
|
73
|
+
const H = f(() => {
|
|
69
74
|
if (o.bottomBarItems) return o.bottomBarItems;
|
|
70
|
-
if (!
|
|
71
|
-
const e = [...
|
|
75
|
+
if (!a) return;
|
|
76
|
+
const e = [...a.statusBarItems()].sort((t, n) => (t.order ?? 100) - (n.order ?? 100)), s = e.filter((t) => t.position === "left"), l = e.filter((t) => t.position === "right");
|
|
72
77
|
return [(() => {
|
|
73
|
-
var
|
|
74
|
-
return
|
|
75
|
-
each:
|
|
76
|
-
children: (n) =>
|
|
78
|
+
var t = k();
|
|
79
|
+
return c(t, r($, {
|
|
80
|
+
each: s,
|
|
81
|
+
children: (n) => r(S, {
|
|
77
82
|
get component() {
|
|
78
83
|
return n.component;
|
|
79
84
|
}
|
|
80
85
|
})
|
|
81
|
-
})),
|
|
86
|
+
})), t;
|
|
82
87
|
})(), (() => {
|
|
83
|
-
var
|
|
84
|
-
return
|
|
88
|
+
var t = k();
|
|
89
|
+
return c(t, r($, {
|
|
85
90
|
each: l,
|
|
86
|
-
children: (n) =>
|
|
91
|
+
children: (n) => r(S, {
|
|
87
92
|
get component() {
|
|
88
93
|
return n.component;
|
|
89
94
|
}
|
|
90
95
|
})
|
|
91
|
-
})),
|
|
96
|
+
})), t;
|
|
92
97
|
})()];
|
|
93
98
|
});
|
|
94
|
-
|
|
95
|
-
const e =
|
|
99
|
+
v(() => {
|
|
100
|
+
const e = g();
|
|
96
101
|
if (!e.length) return;
|
|
97
|
-
|
|
102
|
+
if (!i.sidebarActiveTab()) {
|
|
103
|
+
const l = e.find((t) => !t.onClick);
|
|
104
|
+
if (!l) return;
|
|
105
|
+
w(l.id);
|
|
106
|
+
}
|
|
98
107
|
});
|
|
99
108
|
const A = (e) => {
|
|
100
|
-
const
|
|
109
|
+
const s = u() ? !0 : a?.getComponent(e)?.sidebar?.fullScreen ?? !1, {
|
|
101
110
|
nextActiveId: l,
|
|
102
|
-
nextMobileSidebarOpen:
|
|
103
|
-
} =
|
|
111
|
+
nextMobileSidebarOpen: t
|
|
112
|
+
} = ee({
|
|
104
113
|
clickedId: e,
|
|
105
|
-
activeId:
|
|
106
|
-
mobileSidebarOpen:
|
|
107
|
-
clickedIsFullScreen:
|
|
114
|
+
activeId: i.sidebarActiveTab(),
|
|
115
|
+
mobileSidebarOpen: I(),
|
|
116
|
+
clickedIsFullScreen: s
|
|
108
117
|
});
|
|
109
|
-
|
|
110
|
-
},
|
|
118
|
+
i.sidebarActiveTab() !== l && w(l), b(t);
|
|
119
|
+
}, P = (e) => {
|
|
111
120
|
if (e.onClick) {
|
|
112
|
-
|
|
121
|
+
V(() => e.onClick());
|
|
113
122
|
return;
|
|
114
123
|
}
|
|
115
124
|
A(e.id);
|
|
116
|
-
}, R =
|
|
125
|
+
}, R = f(() => {
|
|
117
126
|
const e = o.topBarActions;
|
|
118
|
-
if (!
|
|
127
|
+
if (!d() || (o.activityBottomItemsMobileMode ?? "hidden") !== "topBar") return e;
|
|
119
128
|
const l = o.activityBottomItems ?? [];
|
|
120
|
-
return l.length ? [
|
|
129
|
+
return l.length ? [r($, {
|
|
121
130
|
each: l,
|
|
122
|
-
children: (
|
|
131
|
+
children: (t) => r(J, {
|
|
123
132
|
get label() {
|
|
124
|
-
return
|
|
133
|
+
return t.label;
|
|
125
134
|
},
|
|
126
|
-
onClick: () =>
|
|
135
|
+
onClick: () => P(t),
|
|
127
136
|
get children() {
|
|
128
|
-
return
|
|
137
|
+
return r(S, {
|
|
129
138
|
get component() {
|
|
130
|
-
return
|
|
139
|
+
return t.icon;
|
|
131
140
|
},
|
|
132
141
|
class: "w-4 h-4"
|
|
133
142
|
});
|
|
134
143
|
}
|
|
135
144
|
})
|
|
136
145
|
}), e] : e;
|
|
137
|
-
}),
|
|
146
|
+
}), W = () => u() ? !0 : i.sidebarCollapsed();
|
|
138
147
|
return (() => {
|
|
139
|
-
var e =
|
|
140
|
-
return
|
|
148
|
+
var e = oe(), s = e.firstChild, l = s.firstChild, t = l.firstChild;
|
|
149
|
+
return c(e, r(G, {
|
|
141
150
|
get logo() {
|
|
142
151
|
return o.logo;
|
|
143
152
|
},
|
|
144
153
|
get actions() {
|
|
145
154
|
return R();
|
|
146
155
|
}
|
|
147
|
-
}),
|
|
156
|
+
}), s), c(s, r(m, {
|
|
148
157
|
get when() {
|
|
149
|
-
return !
|
|
158
|
+
return !d();
|
|
150
159
|
},
|
|
151
160
|
get children() {
|
|
152
|
-
return [
|
|
161
|
+
return [r(m, {
|
|
153
162
|
get when() {
|
|
154
|
-
return
|
|
163
|
+
return g().length > 0;
|
|
155
164
|
},
|
|
156
165
|
get children() {
|
|
157
|
-
return
|
|
166
|
+
return r(Y, {
|
|
158
167
|
get items() {
|
|
159
|
-
return
|
|
168
|
+
return g();
|
|
160
169
|
},
|
|
161
170
|
get bottomItems() {
|
|
162
171
|
return o.activityBottomItems;
|
|
163
172
|
},
|
|
164
173
|
get activeId() {
|
|
165
|
-
return
|
|
174
|
+
return i.sidebarActiveTab();
|
|
166
175
|
},
|
|
167
|
-
onActiveChange:
|
|
176
|
+
onActiveChange: w,
|
|
168
177
|
get collapsed() {
|
|
169
|
-
return
|
|
178
|
+
return W();
|
|
170
179
|
},
|
|
171
180
|
get onCollapsedChange() {
|
|
172
|
-
return C(() => !!
|
|
181
|
+
return C(() => !!u())() ? void 0 : i.setSidebarCollapsed;
|
|
173
182
|
}
|
|
174
183
|
});
|
|
175
184
|
}
|
|
176
|
-
}),
|
|
185
|
+
}), r(m, {
|
|
177
186
|
get when() {
|
|
178
|
-
return !
|
|
187
|
+
return !u();
|
|
179
188
|
},
|
|
180
189
|
get children() {
|
|
181
|
-
return
|
|
190
|
+
return r(q, {
|
|
182
191
|
get width() {
|
|
183
|
-
return
|
|
192
|
+
return i.sidebarWidth();
|
|
184
193
|
},
|
|
185
194
|
get collapsed() {
|
|
186
|
-
return
|
|
195
|
+
return i.sidebarCollapsed() || B();
|
|
187
196
|
},
|
|
188
197
|
get resizer() {
|
|
189
|
-
return
|
|
198
|
+
return r(_, {
|
|
190
199
|
direction: "horizontal",
|
|
191
|
-
onResize: (n) =>
|
|
200
|
+
onResize: (n) => i.setSidebarWidth(i.sidebarWidth() + n)
|
|
192
201
|
});
|
|
193
202
|
},
|
|
194
203
|
get children() {
|
|
195
|
-
return
|
|
204
|
+
return y(i.sidebarActiveTab());
|
|
196
205
|
}
|
|
197
206
|
});
|
|
198
207
|
}
|
|
199
208
|
})];
|
|
200
209
|
}
|
|
201
|
-
}), l), s
|
|
210
|
+
}), l), c(s, r(m, {
|
|
202
211
|
get when() {
|
|
203
|
-
return C(() => !!(
|
|
212
|
+
return C(() => !!(d() && I()))() && !u();
|
|
204
213
|
},
|
|
205
214
|
get children() {
|
|
206
215
|
return [(() => {
|
|
207
|
-
var n =
|
|
216
|
+
var n = re();
|
|
208
217
|
return n.$$click = () => b(!1), n;
|
|
209
218
|
})(), (() => {
|
|
210
|
-
var n =
|
|
211
|
-
return
|
|
219
|
+
var n = ie(), p = n.firstChild;
|
|
220
|
+
return c(p, () => y(i.sidebarActiveTab())), T(() => M(n, x("absolute left-0 top-0 bottom-0 z-50", "w-72 max-w-[80vw]", "bg-sidebar border-r border-sidebar-border", "shadow-xl", "animate-in slide-in-from-left duration-200"))), n;
|
|
212
221
|
})()];
|
|
213
222
|
}
|
|
214
|
-
}), l),
|
|
223
|
+
}), l), c(t, () => o.children), c(l, r(m, {
|
|
215
224
|
get when() {
|
|
216
|
-
return C(() => !!(!
|
|
225
|
+
return C(() => !!(!d() && i.terminalOpened()))() && o.terminalPanel;
|
|
217
226
|
},
|
|
218
227
|
get children() {
|
|
219
|
-
var n =
|
|
220
|
-
return
|
|
228
|
+
var n = ne();
|
|
229
|
+
return c(n, r(_, {
|
|
221
230
|
direction: "vertical",
|
|
222
|
-
onResize: (p) =>
|
|
223
|
-
}), null),
|
|
231
|
+
onResize: (p) => i.setTerminalHeight(i.terminalHeight() - p)
|
|
232
|
+
}), null), c(n, () => o.terminalPanel, null), T((p) => E(n, "height", `${i.terminalHeight()}px`)), n;
|
|
224
233
|
}
|
|
225
|
-
}), null),
|
|
234
|
+
}), null), c(e, r(m, {
|
|
226
235
|
get when() {
|
|
227
|
-
return !
|
|
236
|
+
return !d();
|
|
228
237
|
},
|
|
229
238
|
get children() {
|
|
230
|
-
return
|
|
239
|
+
return r(U, {
|
|
231
240
|
get children() {
|
|
232
|
-
return
|
|
241
|
+
return H();
|
|
233
242
|
}
|
|
234
243
|
});
|
|
235
244
|
}
|
|
236
|
-
}), null),
|
|
245
|
+
}), null), c(e, r(m, {
|
|
237
246
|
get when() {
|
|
238
|
-
return C(() => !!
|
|
247
|
+
return C(() => !!d())() && g().length > 0;
|
|
239
248
|
},
|
|
240
249
|
get children() {
|
|
241
|
-
return
|
|
250
|
+
return r(X, {
|
|
242
251
|
get items() {
|
|
243
|
-
return
|
|
252
|
+
return g();
|
|
244
253
|
},
|
|
245
254
|
get activeId() {
|
|
246
|
-
return
|
|
247
|
-
activeId:
|
|
248
|
-
mobileSidebarOpen:
|
|
249
|
-
activeIsFullScreen: B()
|
|
255
|
+
return Z({
|
|
256
|
+
activeId: i.sidebarActiveTab(),
|
|
257
|
+
mobileSidebarOpen: I(),
|
|
258
|
+
activeIsFullScreen: B(),
|
|
259
|
+
activeIsPage: F()
|
|
250
260
|
});
|
|
251
261
|
},
|
|
252
262
|
onSelect: A
|
|
253
263
|
});
|
|
254
264
|
}
|
|
255
|
-
}), null),
|
|
265
|
+
}), null), T(() => M(e, x(
|
|
256
266
|
// Use dvh when supported to avoid mobile browser UI causing layout jumps.
|
|
257
267
|
"h-screen h-[100dvh] w-full flex flex-col overflow-hidden",
|
|
258
268
|
"bg-background text-foreground",
|
|
@@ -262,7 +272,7 @@ function Ie(o) {
|
|
|
262
272
|
))), e;
|
|
263
273
|
})();
|
|
264
274
|
}
|
|
265
|
-
|
|
275
|
+
N(["click"]);
|
|
266
276
|
export {
|
|
267
|
-
|
|
277
|
+
Be as Shell
|
|
268
278
|
};
|
|
@@ -5,6 +5,12 @@ export interface ResolveMobileTabActiveIdArgs {
|
|
|
5
5
|
mobileSidebarOpen: boolean;
|
|
6
6
|
/** Whether the active component is marked as fullScreen. */
|
|
7
7
|
activeIsFullScreen: boolean;
|
|
8
|
+
/**
|
|
9
|
+
* Whether the active tab should be treated as a page, even if it isn't fullScreen.
|
|
10
|
+
*
|
|
11
|
+
* This is useful for "main view + sidebar panel" tabs.
|
|
12
|
+
*/
|
|
13
|
+
activeIsPage?: boolean;
|
|
8
14
|
}
|
|
9
15
|
/**
|
|
10
16
|
* Determine which tab should appear active in the mobile tab bar.
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
function i(e) {
|
|
2
|
-
return e.activeIsFullScreen || e.mobileSidebarOpen ? e.activeId : "";
|
|
2
|
+
return e.activeIsFullScreen || e.activeIsPage || e.mobileSidebarOpen ? e.activeId : "";
|
|
3
3
|
}
|
|
4
4
|
function t(e) {
|
|
5
5
|
return e.clickedIsFullScreen ? { nextActiveId: e.clickedId, nextMobileSidebarOpen: !1 } : e.clickedId === e.activeId && e.mobileSidebarOpen ? { nextActiveId: e.clickedId, nextMobileSidebarOpen: !1 } : { nextActiveId: e.clickedId, nextMobileSidebarOpen: !0 };
|
|
@@ -56,6 +56,15 @@ export interface FloeComponent<TProtocol = unknown> {
|
|
|
56
56
|
sidebar?: {
|
|
57
57
|
order?: number;
|
|
58
58
|
badge?: () => number | string | undefined;
|
|
59
|
+
/**
|
|
60
|
+
* Where this component should render when active.
|
|
61
|
+
*
|
|
62
|
+
* - `sidebar` (default): render inside Shell's sidebar panel.
|
|
63
|
+
* - `main`: render in the main content area (typically via ActivityAppsMain).
|
|
64
|
+
*
|
|
65
|
+
* Note: `fullScreen: true` implies `renderIn: 'main'` and also hides the sidebar.
|
|
66
|
+
*/
|
|
67
|
+
renderIn?: 'sidebar' | 'main';
|
|
59
68
|
/** When true, this component uses the full content area without sidebar */
|
|
60
69
|
fullScreen?: boolean;
|
|
61
70
|
/** When true, this component is hidden in the activity bar on mobile */
|