@floegence/floe-webapp-core 0.39.5 → 0.39.7
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/components/layout/ActivityBar.d.ts +8 -0
- package/dist/components/layout/ActivityBar.js +68 -62
- package/dist/components/layout/BottomBarCompanion.d.ts +33 -0
- package/dist/components/layout/BottomBarCompanion.js +233 -0
- package/dist/components/layout/index.d.ts +1 -0
- package/dist/floe.css +60 -0
- package/dist/full.js +516 -514
- package/dist/layout.js +33 -31
- package/dist/styles.css +1 -1
- package/package.json +1 -1
|
@@ -8,6 +8,14 @@ export interface ActivityBarItem {
|
|
|
8
8
|
label: string;
|
|
9
9
|
badge?: number | string | (() => number | string | undefined);
|
|
10
10
|
onClick?: () => void;
|
|
11
|
+
/** Receives the concrete trigger button for anchored product surfaces. */
|
|
12
|
+
buttonRef?: (button: HTMLButtonElement | null) => void;
|
|
13
|
+
/** ARIA disclosure state for a surface controlled by this item. */
|
|
14
|
+
ariaExpanded?: boolean | (() => boolean | undefined);
|
|
15
|
+
/** ID of the surface controlled by this item. */
|
|
16
|
+
ariaControls?: string;
|
|
17
|
+
/** Semantic kind of popup opened by this item. */
|
|
18
|
+
ariaHasPopup?: 'menu' | 'listbox' | 'tree' | 'grid' | 'dialog' | boolean;
|
|
11
19
|
/**
|
|
12
20
|
* How this item should affect the sidebar collapsed state when clicked.
|
|
13
21
|
*
|
|
@@ -1,110 +1,116 @@
|
|
|
1
|
-
import { insert as c, createComponent as
|
|
2
|
-
import { createMemo as
|
|
1
|
+
import { insert as c, createComponent as r, effect as g, className as h, setAttribute as u, template as s, use as I, Dynamic as B, memo as $, delegateEvents as E } from "solid-js/web";
|
|
2
|
+
import { createMemo as m, For as k, Show as x, onMount as S, onCleanup as _ } from "solid-js";
|
|
3
3
|
import { cn as y } from "../../utils/cn.js";
|
|
4
|
-
import { deferNonBlocking as
|
|
5
|
-
import { Tooltip as
|
|
6
|
-
import { resolveActivityBarClick as
|
|
7
|
-
var
|
|
8
|
-
function
|
|
9
|
-
const
|
|
10
|
-
if (
|
|
11
|
-
|
|
4
|
+
import { deferNonBlocking as j } from "../../utils/defer.js";
|
|
5
|
+
import { Tooltip as R } from "../ui/Tooltip.js";
|
|
6
|
+
import { resolveActivityBarClick as M } from "./activityBarBehavior.js";
|
|
7
|
+
var N = /* @__PURE__ */ s('<div class="flex flex-col">'), q = /* @__PURE__ */ s('<nav data-floe-shell-slot=activity-bar style=border-right-color:var(--activity-bar-border)><div class="flex flex-col">'), D = /* @__PURE__ */ s('<div class="absolute left-0 top-0 w-1 h-full bg-primary rounded-r">'), F = /* @__PURE__ */ s("<span>"), H = /* @__PURE__ */ s("<button type=button>");
|
|
8
|
+
function J(t) {
|
|
9
|
+
const l = m(() => t.activeId), d = m(() => t.collapsed ?? !1), b = m(() => t.onActiveChange), i = m(() => t.onCollapsedChange), v = (e) => {
|
|
10
|
+
if (e.onClick) {
|
|
11
|
+
j(() => e.onClick());
|
|
12
12
|
return;
|
|
13
13
|
}
|
|
14
|
-
const
|
|
15
|
-
clickedId:
|
|
16
|
-
activeId:
|
|
17
|
-
collapsed:
|
|
18
|
-
behavior:
|
|
14
|
+
const a = M({
|
|
15
|
+
clickedId: e.id,
|
|
16
|
+
activeId: l(),
|
|
17
|
+
collapsed: d(),
|
|
18
|
+
behavior: e.collapseBehavior
|
|
19
19
|
});
|
|
20
|
-
|
|
21
|
-
openSidebar:
|
|
22
|
-
}) :
|
|
20
|
+
a.nextActiveId !== l() && (typeof a.openSidebar == "boolean" ? b()(a.nextActiveId, {
|
|
21
|
+
openSidebar: a.openSidebar
|
|
22
|
+
}) : b()(a.nextActiveId)), typeof a.nextCollapsed == "boolean" && i()?.(a.nextCollapsed);
|
|
23
23
|
};
|
|
24
24
|
return (() => {
|
|
25
|
-
var
|
|
26
|
-
return c(
|
|
25
|
+
var e = q(), a = e.firstChild;
|
|
26
|
+
return c(a, r(k, {
|
|
27
27
|
get each() {
|
|
28
|
-
return
|
|
28
|
+
return t.items;
|
|
29
29
|
},
|
|
30
|
-
children: (
|
|
31
|
-
item:
|
|
30
|
+
children: (n) => r(w, {
|
|
31
|
+
item: n,
|
|
32
32
|
get isActive() {
|
|
33
|
-
return
|
|
33
|
+
return l() === n.id;
|
|
34
34
|
},
|
|
35
|
-
onClick: () => v(
|
|
35
|
+
onClick: () => v(n)
|
|
36
36
|
})
|
|
37
|
-
})), c(
|
|
37
|
+
})), c(e, r(x, {
|
|
38
38
|
get when() {
|
|
39
|
-
return
|
|
39
|
+
return t.bottomItems?.length;
|
|
40
40
|
},
|
|
41
41
|
get children() {
|
|
42
|
-
var
|
|
43
|
-
return c(
|
|
42
|
+
var n = N();
|
|
43
|
+
return c(n, r(k, {
|
|
44
44
|
get each() {
|
|
45
|
-
return
|
|
45
|
+
return t.bottomItems;
|
|
46
46
|
},
|
|
47
|
-
children: (
|
|
48
|
-
item:
|
|
47
|
+
children: (o) => r(w, {
|
|
48
|
+
item: o,
|
|
49
49
|
isActive: !1,
|
|
50
|
-
onClick: () => v(
|
|
50
|
+
onClick: () => v(o)
|
|
51
51
|
})
|
|
52
|
-
})),
|
|
52
|
+
})), n;
|
|
53
53
|
}
|
|
54
|
-
}), null),
|
|
55
|
-
var
|
|
56
|
-
return
|
|
54
|
+
}), null), g((n) => {
|
|
55
|
+
var o = y("w-10 md:w-12 flex flex-col justify-between shrink-0 min-h-0", "bg-activity-bar border-r border-border", t.class), f = t.ariaLabel;
|
|
56
|
+
return o !== n.e && h(e, n.e = o), f !== n.t && u(e, "aria-label", n.t = f), n;
|
|
57
57
|
}, {
|
|
58
58
|
e: void 0,
|
|
59
59
|
t: void 0
|
|
60
|
-
}),
|
|
60
|
+
}), e;
|
|
61
61
|
})();
|
|
62
62
|
}
|
|
63
|
-
function
|
|
64
|
-
|
|
65
|
-
|
|
63
|
+
function w(t) {
|
|
64
|
+
let l;
|
|
65
|
+
const d = () => typeof t.item.badge == "function" ? t.item.badge() : t.item.badge, b = () => typeof t.item.ariaExpanded == "function" ? t.item.ariaExpanded() : t.item.ariaExpanded;
|
|
66
|
+
return S(() => t.item.buttonRef?.(l ?? null)), _(() => t.item.buttonRef?.(null)), r(R, {
|
|
66
67
|
get content() {
|
|
67
|
-
return
|
|
68
|
+
return t.item.label;
|
|
68
69
|
},
|
|
69
70
|
placement: "right",
|
|
70
71
|
delay: 0,
|
|
71
72
|
get children() {
|
|
72
|
-
var
|
|
73
|
-
|
|
73
|
+
var i = H();
|
|
74
|
+
i.$$click = () => t.onClick();
|
|
75
|
+
var v = l;
|
|
76
|
+
return typeof v == "function" ? I(v, i) : l = i, c(i, r(x, {
|
|
74
77
|
get when() {
|
|
75
|
-
return
|
|
78
|
+
return t.isActive;
|
|
76
79
|
},
|
|
77
80
|
get children() {
|
|
78
|
-
return
|
|
81
|
+
return D();
|
|
79
82
|
}
|
|
80
|
-
}), null), c(
|
|
83
|
+
}), null), c(i, r(B, {
|
|
81
84
|
get component() {
|
|
82
|
-
return
|
|
85
|
+
return t.item.icon;
|
|
83
86
|
},
|
|
84
87
|
class: "w-5 h-5"
|
|
85
|
-
}), null), c(
|
|
88
|
+
}), null), c(i, r(x, {
|
|
86
89
|
get when() {
|
|
87
|
-
return
|
|
90
|
+
return d();
|
|
88
91
|
},
|
|
89
92
|
get children() {
|
|
90
|
-
var
|
|
91
|
-
return c(
|
|
92
|
-
var
|
|
93
|
-
return () =>
|
|
94
|
-
})()),
|
|
93
|
+
var e = F();
|
|
94
|
+
return c(e, (() => {
|
|
95
|
+
var a = $(() => typeof d() == "number" && d() > 99);
|
|
96
|
+
return () => a() ? "99+" : d();
|
|
97
|
+
})()), g(() => h(e, y("absolute top-0.5 right-0.5 min-w-3.5 h-3.5 px-1", "flex items-center justify-center", "text-[9px] font-medium rounded-full", "bg-activity-bar-badge text-activity-bar-badge-foreground"))), e;
|
|
95
98
|
}
|
|
96
|
-
}), null),
|
|
97
|
-
var
|
|
98
|
-
return
|
|
99
|
+
}), null), g((e) => {
|
|
100
|
+
var a = y("relative w-full aspect-square flex items-center justify-center cursor-pointer", "focus:outline-none focus-visible:ring-1 focus-visible:ring-ring focus-visible:ring-inset", t.isActive ? "text-activity-bar-foreground-active bg-accent/80" : "text-activity-bar-foreground transition-[color,background-color] duration-100 hover:text-activity-bar-foreground-active hover:bg-accent/40"), n = t.item.label, o = t.isActive, f = b(), C = t.item.ariaControls, A = t.item.ariaHasPopup;
|
|
101
|
+
return a !== e.e && h(i, e.e = a), n !== e.t && u(i, "aria-label", e.t = n), o !== e.a && u(i, "aria-pressed", e.a = o), f !== e.o && u(i, "aria-expanded", e.o = f), C !== e.i && u(i, "aria-controls", e.i = C), A !== e.n && u(i, "aria-haspopup", e.n = A), e;
|
|
99
102
|
}, {
|
|
100
103
|
e: void 0,
|
|
101
104
|
t: void 0,
|
|
102
|
-
a: void 0
|
|
103
|
-
|
|
105
|
+
a: void 0,
|
|
106
|
+
o: void 0,
|
|
107
|
+
i: void 0,
|
|
108
|
+
n: void 0
|
|
109
|
+
}), i;
|
|
104
110
|
}
|
|
105
111
|
});
|
|
106
112
|
}
|
|
107
|
-
|
|
113
|
+
E(["click"]);
|
|
108
114
|
export {
|
|
109
|
-
|
|
115
|
+
J as ActivityBar
|
|
110
116
|
};
|
|
@@ -0,0 +1,33 @@
|
|
|
1
|
+
import { type JSX } from 'solid-js';
|
|
2
|
+
export type BottomBarCompanionPhase = 'collapsed' | 'expanding' | 'expanded' | 'collapsing';
|
|
3
|
+
export type BottomBarCompanionDismissReason = 'outside-pointer' | 'escape';
|
|
4
|
+
export interface BottomBarCompanionProps {
|
|
5
|
+
retained: boolean;
|
|
6
|
+
visible: boolean;
|
|
7
|
+
open: boolean;
|
|
8
|
+
anchor: HTMLElement | null;
|
|
9
|
+
mount: HTMLElement | null;
|
|
10
|
+
id: string;
|
|
11
|
+
label: string;
|
|
12
|
+
children?: JSX.Element;
|
|
13
|
+
maxWidth?: number;
|
|
14
|
+
maxHeight?: number;
|
|
15
|
+
viewportPadding?: number;
|
|
16
|
+
class?: string;
|
|
17
|
+
contentClass?: string;
|
|
18
|
+
surfaceRef?: (element: HTMLElement | null) => void;
|
|
19
|
+
contentHostRef?: (element: HTMLElement | null) => void;
|
|
20
|
+
isOwnedInteraction?: (event: PointerEvent | KeyboardEvent) => boolean;
|
|
21
|
+
onDismiss?: (reason: BottomBarCompanionDismissReason) => void;
|
|
22
|
+
onPhaseChange?: (phase: BottomBarCompanionPhase) => void;
|
|
23
|
+
}
|
|
24
|
+
/**
|
|
25
|
+
* A non-modal surface that grows upward from a Bottom Bar anchor.
|
|
26
|
+
*
|
|
27
|
+
* This is intentionally distinct from windows, popovers, and modal drawers:
|
|
28
|
+
* it retains one fixed shell and one content host across collapsed and expanded
|
|
29
|
+
* presentation. Products that also have a full-page placement can Portal their
|
|
30
|
+
* stable product tree into `contentHostRef` without giving this component
|
|
31
|
+
* ownership of that tree.
|
|
32
|
+
*/
|
|
33
|
+
export declare function BottomBarCompanion(props: BottomBarCompanionProps): JSX.Element;
|
|
@@ -0,0 +1,233 @@
|
|
|
1
|
+
import { createComponent as Z, Portal as ce, use as $, insert as le, effect as ue, setAttribute as R, className as p, style as de, memo as fe, template as me } from "solid-js/web";
|
|
2
|
+
import { createSignal as N, createEffect as k, untrack as G, onCleanup as U, Show as he } from "solid-js";
|
|
3
|
+
import { cn as ee } from "../../utils/cn.js";
|
|
4
|
+
var ve = /* @__PURE__ */ me("<section role=region data-floe-bottom-bar-companion=true><div data-floe-bottom-bar-companion-content=true>");
|
|
5
|
+
const we = 544, be = 544, ge = 12, z = {
|
|
6
|
+
top: "--floe-bottom-bar-companion-safe-area-top",
|
|
7
|
+
right: "--floe-bottom-bar-companion-safe-area-right",
|
|
8
|
+
bottom: "--floe-bottom-bar-companion-safe-area-bottom",
|
|
9
|
+
left: "--floe-bottom-bar-companion-safe-area-left"
|
|
10
|
+
};
|
|
11
|
+
function te(e, a) {
|
|
12
|
+
const l = Number(e);
|
|
13
|
+
return Number.isFinite(l) && l > 0 ? l : a;
|
|
14
|
+
}
|
|
15
|
+
function Ce(e, a) {
|
|
16
|
+
const l = Number(e);
|
|
17
|
+
return Number.isFinite(l) && l >= 0 ? l : a;
|
|
18
|
+
}
|
|
19
|
+
function ne(e) {
|
|
20
|
+
if (!e?.isConnected) return null;
|
|
21
|
+
const a = e.getBoundingClientRect();
|
|
22
|
+
return !Number.isFinite(a.left) || !Number.isFinite(a.top) || a.width <= 0 || a.height <= 0 ? null : {
|
|
23
|
+
left: a.left,
|
|
24
|
+
top: a.top,
|
|
25
|
+
width: a.width,
|
|
26
|
+
height: a.height
|
|
27
|
+
};
|
|
28
|
+
}
|
|
29
|
+
function B(e, a) {
|
|
30
|
+
const l = e.ownerDocument.defaultView;
|
|
31
|
+
if (!l) return 0;
|
|
32
|
+
const m = Number.parseFloat(l.getComputedStyle(e).getPropertyValue(a));
|
|
33
|
+
return Number.isFinite(m) && m > 0 ? m : 0;
|
|
34
|
+
}
|
|
35
|
+
function Fe(e) {
|
|
36
|
+
return {
|
|
37
|
+
top: B(e, z.top),
|
|
38
|
+
right: B(e, z.right),
|
|
39
|
+
bottom: B(e, z.bottom),
|
|
40
|
+
left: B(e, z.left)
|
|
41
|
+
};
|
|
42
|
+
}
|
|
43
|
+
function ye(e, a, l, m, C) {
|
|
44
|
+
const F = a.ownerDocument.defaultView, y = F?.visualViewport, v = y?.offsetLeft ?? 0, D = y?.offsetTop ?? 0, q = y?.width ?? F?.innerWidth ?? e.left + e.width, H = y?.height ?? F?.innerHeight ?? e.top + e.height, E = Fe(a), W = v + E.left + C, w = v + q - E.right - C, b = D + E.top + C, h = D + H - E.bottom - C, g = Math.max(0, w - W), d = Math.min(e.width, l, g), P = e.left + (e.width - d) / 2, M = Math.max(W, Math.min(P, w - d)), L = Math.min(e.top + e.height, h), V = Math.max(e.height, L - b), x = Math.min(m, V);
|
|
45
|
+
return {
|
|
46
|
+
left: M,
|
|
47
|
+
top: L - x,
|
|
48
|
+
width: d,
|
|
49
|
+
height: x
|
|
50
|
+
};
|
|
51
|
+
}
|
|
52
|
+
function Ee(e, a) {
|
|
53
|
+
return !!(e && e.left === a.left && e.top === a.top && e.width === a.width && e.height === a.height);
|
|
54
|
+
}
|
|
55
|
+
function Ae(e) {
|
|
56
|
+
return e ? {
|
|
57
|
+
left: `${e.left}px`,
|
|
58
|
+
top: `${e.top}px`,
|
|
59
|
+
width: `${e.width}px`,
|
|
60
|
+
height: `${e.height}px`
|
|
61
|
+
} : {};
|
|
62
|
+
}
|
|
63
|
+
function Me(e) {
|
|
64
|
+
const [a, l] = N(null), [m, C] = N(!1), [F, y] = N(!1), [v, D] = N(null), [q, H] = N(null), [E, W] = N("collapsed");
|
|
65
|
+
let w = null, b = 0, h = 0, g = null, d = null, P = null, M = !1, L = !1;
|
|
66
|
+
const V = (i) => {
|
|
67
|
+
E() !== i && (W(i), e.onPhaseChange?.(i));
|
|
68
|
+
}, x = () => a()?.ownerDocument.defaultView ?? e.anchor?.ownerDocument.defaultView ?? null, oe = () => x()?.matchMedia?.("(prefers-reduced-motion: reduce)").matches ?? !1, _ = (i) => {
|
|
69
|
+
const t = e.mount, r = e.anchor, n = !!(t?.isConnected && i && r?.ownerDocument === t.ownerDocument);
|
|
70
|
+
n && l(t);
|
|
71
|
+
const c = a();
|
|
72
|
+
if (c) {
|
|
73
|
+
C(c.isConnected);
|
|
74
|
+
const o = !!(n && c === t);
|
|
75
|
+
return y(o), {
|
|
76
|
+
mount: c,
|
|
77
|
+
ready: o
|
|
78
|
+
};
|
|
79
|
+
}
|
|
80
|
+
return C(!1), y(!1), {
|
|
81
|
+
mount: null,
|
|
82
|
+
ready: !1
|
|
83
|
+
};
|
|
84
|
+
}, ie = (i) => {
|
|
85
|
+
const t = ne(e.anchor);
|
|
86
|
+
t && H(t);
|
|
87
|
+
const {
|
|
88
|
+
mount: r,
|
|
89
|
+
ready: n
|
|
90
|
+
} = _(t), c = t ?? q();
|
|
91
|
+
return !c || !r || !n ? null : i ? ye(c, r, te(e.maxWidth, we), te(e.maxHeight, be), Ce(e.viewportPadding, ge)) : c;
|
|
92
|
+
}, X = () => {
|
|
93
|
+
b && g && g.cancelAnimationFrame(b), h && d && d.cancelAnimationFrame(h), b = 0, h = 0, g = null, d = null, P = null;
|
|
94
|
+
}, K = (i, t) => {
|
|
95
|
+
const r = ie(i);
|
|
96
|
+
if (!r) return;
|
|
97
|
+
const n = v(), c = i ? "expanded" : "collapsed";
|
|
98
|
+
if (!t || oe() || Ee(n, r)) {
|
|
99
|
+
D(r), P = null, V(c);
|
|
100
|
+
return;
|
|
101
|
+
}
|
|
102
|
+
P = ["height", "width", "top", "left"].find((u) => n?.[u] !== r[u]) ?? null, V(i ? "expanding" : "collapsing");
|
|
103
|
+
const o = x();
|
|
104
|
+
if (!o) {
|
|
105
|
+
D(r), V(c);
|
|
106
|
+
return;
|
|
107
|
+
}
|
|
108
|
+
h = o.requestAnimationFrame(() => {
|
|
109
|
+
h = 0, d = null, D(r);
|
|
110
|
+
}), d = o;
|
|
111
|
+
}, j = (i, t) => {
|
|
112
|
+
const r = x();
|
|
113
|
+
if (!r) {
|
|
114
|
+
K(t, i);
|
|
115
|
+
return;
|
|
116
|
+
}
|
|
117
|
+
b && g && g.cancelAnimationFrame(b), h && d && d.cancelAnimationFrame(h), h = 0, d = null, b = r.requestAnimationFrame(() => {
|
|
118
|
+
b = 0, g = null, G(() => K(t, i));
|
|
119
|
+
}), g = r;
|
|
120
|
+
};
|
|
121
|
+
k(() => {
|
|
122
|
+
const i = e.retained, t = e.visible, r = e.open;
|
|
123
|
+
if (e.anchor, e.mount, e.maxWidth, e.maxHeight, e.viewportPadding, !i) {
|
|
124
|
+
X(), l(null), C(!1), y(!1), D(null), H(null), w = null, e.surfaceRef?.(null), e.contentHostRef?.(null), M = !1, L = r;
|
|
125
|
+
return;
|
|
126
|
+
}
|
|
127
|
+
const n = ne(e.anchor);
|
|
128
|
+
if (n && H(n), _(n), !t) {
|
|
129
|
+
M = !1, L = r;
|
|
130
|
+
return;
|
|
131
|
+
}
|
|
132
|
+
const c = !M, o = L !== r;
|
|
133
|
+
M = !0, L = r, j(!c && o, r);
|
|
134
|
+
}), k(() => {
|
|
135
|
+
if (!e.retained) return;
|
|
136
|
+
const i = e.anchor, t = a(), r = e.mount, n = /* @__PURE__ */ new Set(), c = /* @__PURE__ */ new Set();
|
|
137
|
+
for (const s of [i, t, r]) {
|
|
138
|
+
if (!s) continue;
|
|
139
|
+
n.add(s.ownerDocument);
|
|
140
|
+
const f = s.ownerDocument.defaultView;
|
|
141
|
+
f && c.add(f);
|
|
142
|
+
}
|
|
143
|
+
if (c.size === 0 || n.size === 0) return;
|
|
144
|
+
const o = () => j(!1, G(() => e.open)), u = [];
|
|
145
|
+
for (const s of /* @__PURE__ */ new Set([i, t, r])) {
|
|
146
|
+
const f = s?.ownerDocument.defaultView;
|
|
147
|
+
if (!s || !f || typeof f.ResizeObserver != "function") continue;
|
|
148
|
+
const A = new f.ResizeObserver(o);
|
|
149
|
+
A.observe(s), u.push(A);
|
|
150
|
+
}
|
|
151
|
+
let S = i?.isConnected ?? !1, T = t?.isConnected ?? !1, I = r?.isConnected ?? !1;
|
|
152
|
+
const O = [];
|
|
153
|
+
for (const s of n) {
|
|
154
|
+
const f = s.defaultView;
|
|
155
|
+
if (!f || typeof f.MutationObserver != "function" || !s.documentElement) continue;
|
|
156
|
+
const A = new f.MutationObserver(() => {
|
|
157
|
+
const J = i?.isConnected ?? !1, Q = t?.isConnected ?? !1, Y = r?.isConnected ?? !1;
|
|
158
|
+
S === J && T === Q && I === Y || (S = J, T = Q, I = Y, G(o));
|
|
159
|
+
});
|
|
160
|
+
A.observe(s.documentElement, {
|
|
161
|
+
childList: !0,
|
|
162
|
+
subtree: !0
|
|
163
|
+
}), O.push(A);
|
|
164
|
+
}
|
|
165
|
+
for (const s of c)
|
|
166
|
+
s.addEventListener("resize", o), s.visualViewport?.addEventListener("resize", o), s.visualViewport?.addEventListener("scroll", o);
|
|
167
|
+
U(() => {
|
|
168
|
+
for (const s of u) s.disconnect();
|
|
169
|
+
for (const s of O) s.disconnect();
|
|
170
|
+
for (const s of c)
|
|
171
|
+
s.removeEventListener("resize", o), s.visualViewport?.removeEventListener("resize", o), s.visualViewport?.removeEventListener("scroll", o);
|
|
172
|
+
});
|
|
173
|
+
}), k(() => {
|
|
174
|
+
if (!e.retained || !e.visible || !e.open || !m() || !F() || !v()) return;
|
|
175
|
+
const t = a()?.ownerDocument;
|
|
176
|
+
if (!t) return;
|
|
177
|
+
const r = (o) => {
|
|
178
|
+
const u = typeof o.composedPath == "function" ? o.composedPath() : [];
|
|
179
|
+
return w && u.includes(w) || e.anchor && u.includes(e.anchor) ? !0 : e.isOwnedInteraction?.(o) ?? !1;
|
|
180
|
+
}, n = (o) => {
|
|
181
|
+
r(o) || e.onDismiss?.("outside-pointer");
|
|
182
|
+
}, c = (o) => {
|
|
183
|
+
if (o.key !== "Escape" || o.defaultPrevented || o.isComposing || o.keyCode === 229) return;
|
|
184
|
+
const u = t.activeElement;
|
|
185
|
+
!w?.contains(u) && !e.isOwnedInteraction?.(o) || (o.preventDefault(), e.onDismiss?.("escape"));
|
|
186
|
+
};
|
|
187
|
+
t.addEventListener("pointerdown", n, !0), t.addEventListener("keydown", c), U(() => {
|
|
188
|
+
t.removeEventListener("pointerdown", n, !0), t.removeEventListener("keydown", c);
|
|
189
|
+
});
|
|
190
|
+
}), U(() => {
|
|
191
|
+
X(), e.surfaceRef?.(null), e.contentHostRef?.(null);
|
|
192
|
+
});
|
|
193
|
+
const re = (i) => {
|
|
194
|
+
w = i, e.surfaceRef?.(i);
|
|
195
|
+
}, ae = (i) => {
|
|
196
|
+
e.contentHostRef?.(i);
|
|
197
|
+
}, se = (i) => {
|
|
198
|
+
if (i.target !== w || i.propertyName !== P) return;
|
|
199
|
+
const t = e.open ? "expanding" : "collapsing";
|
|
200
|
+
E() === t && (P = null, V(e.open ? "expanded" : "collapsed"));
|
|
201
|
+
};
|
|
202
|
+
return Z(he, {
|
|
203
|
+
get when() {
|
|
204
|
+
return fe(() => !!e.retained)() && a();
|
|
205
|
+
},
|
|
206
|
+
children: (i) => Z(ce, {
|
|
207
|
+
get mount() {
|
|
208
|
+
return i();
|
|
209
|
+
},
|
|
210
|
+
get children() {
|
|
211
|
+
var t = ve(), r = t.firstChild;
|
|
212
|
+
return t.addEventListener("transitionend", se), $((n) => re(n), t), $((n) => ae(n), r), le(r, () => e.children), ue((n) => {
|
|
213
|
+
var c = e.id, o = e.label, u = !e.visible || !m() || !F() || !v() ? "true" : void 0, S = !e.visible || !m() || !F() || !v(), T = ee("floe-bottom-bar-companion", e.class), I = E(), O = e.visible && m() && F() ? "visible" : "hidden", s = v() ? "true" : "false", f = Ae(v()), A = ee("floe-bottom-bar-companion__content", e.contentClass);
|
|
214
|
+
return c !== n.e && R(t, "id", n.e = c), o !== n.t && R(t, "aria-label", n.t = o), u !== n.a && R(t, "aria-hidden", n.a = u), S !== n.o && (t.inert = n.o = S), T !== n.i && p(t, n.i = T), I !== n.n && R(t, "data-companion-phase", n.n = I), O !== n.s && R(t, "data-companion-visibility", n.s = O), s !== n.h && R(t, "data-companion-frame-ready", n.h = s), n.r = de(t, f, n.r), A !== n.d && p(r, n.d = A), n;
|
|
215
|
+
}, {
|
|
216
|
+
e: void 0,
|
|
217
|
+
t: void 0,
|
|
218
|
+
a: void 0,
|
|
219
|
+
o: void 0,
|
|
220
|
+
i: void 0,
|
|
221
|
+
n: void 0,
|
|
222
|
+
s: void 0,
|
|
223
|
+
h: void 0,
|
|
224
|
+
r: void 0,
|
|
225
|
+
d: void 0
|
|
226
|
+
}), t;
|
|
227
|
+
}
|
|
228
|
+
})
|
|
229
|
+
});
|
|
230
|
+
}
|
|
231
|
+
export {
|
|
232
|
+
Me as BottomBarCompanion
|
|
233
|
+
};
|
|
@@ -4,6 +4,7 @@ export { Sidebar, SidebarContent, SidebarItemList, SidebarSection, SidebarItem,
|
|
|
4
4
|
export { TopBar, type TopBarProps } from './TopBar';
|
|
5
5
|
export { TopBarIconButton, type TopBarIconButtonProps } from './TopBarIconButton';
|
|
6
6
|
export { BottomBar, BottomBarItem, StatusIndicator, type BottomBarProps, type BottomBarItemProps, type StatusIndicatorProps } from './BottomBar';
|
|
7
|
+
export { BottomBarCompanion, type BottomBarCompanionDismissReason, type BottomBarCompanionPhase, type BottomBarCompanionProps, } from './BottomBarCompanion';
|
|
7
8
|
export { MobileTabBar, type MobileTabBarItem, type MobileTabBarProps } from './MobileTabBar';
|
|
8
9
|
export { ResizeHandle, type ResizeHandleProps } from './ResizeHandle';
|
|
9
10
|
export { SidebarPane, type SidebarPaneProps } from './SidebarPane';
|
package/dist/floe.css
CHANGED
|
@@ -687,6 +687,66 @@
|
|
|
687
687
|
}
|
|
688
688
|
}
|
|
689
689
|
|
|
690
|
+
.floe-bottom-bar-companion {
|
|
691
|
+
position: fixed;
|
|
692
|
+
z-index: var(--floe-bottom-bar-companion-z-index, 72);
|
|
693
|
+
min-width: 0;
|
|
694
|
+
min-height: 0;
|
|
695
|
+
overflow: hidden;
|
|
696
|
+
border: 1px solid color-mix(in srgb, var(--border) 92%, transparent);
|
|
697
|
+
border-radius: var(--floe-bottom-bar-companion-collapsed-radius, 0.3125rem);
|
|
698
|
+
background: var(--background);
|
|
699
|
+
color: var(--foreground);
|
|
700
|
+
opacity: 1;
|
|
701
|
+
pointer-events: auto;
|
|
702
|
+
transform-origin: bottom center;
|
|
703
|
+
transition:
|
|
704
|
+
left 240ms cubic-bezier(0.22, 1, 0.36, 1),
|
|
705
|
+
top 240ms cubic-bezier(0.22, 1, 0.36, 1),
|
|
706
|
+
width 240ms cubic-bezier(0.22, 1, 0.36, 1),
|
|
707
|
+
height 240ms cubic-bezier(0.22, 1, 0.36, 1),
|
|
708
|
+
border-radius 200ms ease,
|
|
709
|
+
border-color 180ms ease,
|
|
710
|
+
box-shadow 200ms ease,
|
|
711
|
+
opacity 120ms ease;
|
|
712
|
+
will-change: left, top, width, height;
|
|
713
|
+
}
|
|
714
|
+
|
|
715
|
+
.floe-bottom-bar-companion[data-companion-phase='expanding'],
|
|
716
|
+
.floe-bottom-bar-companion[data-companion-phase='expanded'] {
|
|
717
|
+
border-radius: var(--floe-bottom-bar-companion-expanded-radius, 0.5rem);
|
|
718
|
+
border-color: color-mix(in srgb, var(--border) 96%, transparent);
|
|
719
|
+
box-shadow:
|
|
720
|
+
0 22px 54px -24px color-mix(in srgb, var(--foreground) 34%, transparent),
|
|
721
|
+
0 6px 18px -12px color-mix(in srgb, var(--foreground) 24%, transparent);
|
|
722
|
+
}
|
|
723
|
+
|
|
724
|
+
.floe-bottom-bar-companion[data-companion-phase='collapsing'] {
|
|
725
|
+
transition-duration: 180ms, 180ms, 180ms, 180ms, 160ms, 140ms, 160ms, 100ms;
|
|
726
|
+
}
|
|
727
|
+
|
|
728
|
+
.floe-bottom-bar-companion[data-companion-visibility='hidden'],
|
|
729
|
+
.floe-bottom-bar-companion[data-companion-frame-ready='false'] {
|
|
730
|
+
visibility: hidden;
|
|
731
|
+
opacity: 0;
|
|
732
|
+
pointer-events: none;
|
|
733
|
+
}
|
|
734
|
+
|
|
735
|
+
.floe-bottom-bar-companion__content {
|
|
736
|
+
width: 100%;
|
|
737
|
+
height: 100%;
|
|
738
|
+
min-width: 0;
|
|
739
|
+
min-height: 0;
|
|
740
|
+
overflow: hidden;
|
|
741
|
+
}
|
|
742
|
+
|
|
743
|
+
@media (prefers-reduced-motion: reduce) {
|
|
744
|
+
.floe-bottom-bar-companion {
|
|
745
|
+
transition: none;
|
|
746
|
+
will-change: auto;
|
|
747
|
+
}
|
|
748
|
+
}
|
|
749
|
+
|
|
690
750
|
@keyframes glow-pulse {
|
|
691
751
|
0%, 100% {
|
|
692
752
|
box-shadow: 0 0 5px var(--primary), 0 0 20px var(--primary);
|