@floegence/floe-webapp-core 0.89.2 → 0.90.1
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/ui/Dropdown.js +199 -185
- package/dist/components/ui/FloatingWindow.js +30 -30
- package/dist/components/ui/Popover.js +78 -71
- package/dist/components/ui/SurfaceAnchoredLayer.js +45 -43
- package/dist/components/ui/Tabs.d.ts +2 -0
- package/dist/components/ui/Tabs.js +190 -172
- package/dist/components/ui/WindowTabs.js +1 -1
- package/dist/components/ui/tabReorder.d.ts +19 -0
- package/dist/components/ui/tabReorder.js +55 -0
- package/dist/floe.css +43 -0
- package/dist/styles.css +1 -1
- package/package.json +1 -1
|
@@ -0,0 +1,55 @@
|
|
|
1
|
+
import { createSignal as p, createEffect as M, onCleanup as P } from "solid-js";
|
|
2
|
+
import { startPointerSession as X } from "./pointerSession.js";
|
|
3
|
+
function C(o) {
|
|
4
|
+
const [d, w] = p(), [h, b] = p(), [A, k] = p();
|
|
5
|
+
let a, l, c = 0, s = 0, u = !1, m, f;
|
|
6
|
+
const E = (e, r) => {
|
|
7
|
+
const t = o.items().map((n) => n.id).filter((n) => n !== e), i = r ? t.indexOf(r) : t.length;
|
|
8
|
+
return t.splice(i < 0 ? t.length : i, 0, e), t;
|
|
9
|
+
}, y = () => {
|
|
10
|
+
const e = o.items().filter((t) => t.id !== l), r = e.find((t) => {
|
|
11
|
+
const i = o.elements.get(t.id)?.getBoundingClientRect();
|
|
12
|
+
return i && c < i.left + i.width / 2;
|
|
13
|
+
});
|
|
14
|
+
b(r?.id), k(r ? void 0 : e.at(-1)?.id);
|
|
15
|
+
}, R = () => {
|
|
16
|
+
s = 0;
|
|
17
|
+
const e = o.container();
|
|
18
|
+
if (!d() || !e) return;
|
|
19
|
+
const r = e.getBoundingClientRect(), t = c < r.left + 28 ? c - r.left - 28 : c > r.right - 28 ? c - r.right + 28 : 0;
|
|
20
|
+
t && (e.scrollLeft += Math.sign(t) * Math.min(12, Math.abs(t) / 3)), y(), s = requestAnimationFrame(R);
|
|
21
|
+
}, g = (e) => {
|
|
22
|
+
e.key === "Escape" && (e.preventDefault(), e.stopPropagation(), a?.stop({ commit: !1 }));
|
|
23
|
+
}, D = (e) => {
|
|
24
|
+
const r = l, t = !!d(), i = r && t ? E(r, h()) : void 0;
|
|
25
|
+
s && cancelAnimationFrame(s), s = 0, f?.defaultView?.removeEventListener("keydown", g, !0), a = void 0, l = void 0, w(void 0), b(void 0), k(void 0), t && (u = !0, m = setTimeout(() => {
|
|
26
|
+
u = !1;
|
|
27
|
+
}, 0)), e && i && i.join("\0") !== o.items().map((n) => n.id).join("\0") && o.onReorder()?.(i);
|
|
28
|
+
}, L = (e, r) => {
|
|
29
|
+
if (!o.onReorder() || r.disabled || e.button !== 0 || a || e.target?.closest('button, a, input, [contenteditable="true"]')) return;
|
|
30
|
+
const t = e.clientX, i = e.clientY;
|
|
31
|
+
l = r.id, c = t, f = e.currentTarget.ownerDocument, f.defaultView?.addEventListener("keydown", g, !0), a = X({
|
|
32
|
+
pointerEvent: e,
|
|
33
|
+
captureEl: e.currentTarget,
|
|
34
|
+
capturePointer: !1,
|
|
35
|
+
onMove: (n) => {
|
|
36
|
+
c = n.clientX, !(!d() && Math.hypot(n.clientX - t, n.clientY - i) < 5) && (d() || (w(r.id), a?.capturePointer()), n.preventDefault(), y(), s || (s = requestAnimationFrame(R)));
|
|
37
|
+
},
|
|
38
|
+
onEnd: (n) => D(n.commit && (n.reason === "pointer_up" || n.reason === "buttons_released"))
|
|
39
|
+
});
|
|
40
|
+
}, T = (e, r) => {
|
|
41
|
+
if (!o.onReorder() || r.disabled || !e.altKey || !e.shiftKey || !["ArrowLeft", "ArrowRight"].includes(e.key)) return !1;
|
|
42
|
+
e.preventDefault(), e.stopPropagation();
|
|
43
|
+
const t = o.items().map((F) => F.id), i = t.indexOf(r.id), n = i + (e.key === "ArrowLeft" ? -1 : 1);
|
|
44
|
+
return n >= 0 && n < t.length && ([t[i], t[n]] = [t[n], t[i]], o.onReorder()?.(t), o.elements.get(r.id)?.focus({ preventScroll: !0 }), o.elements.get(r.id)?.scrollIntoView({ block: "nearest", inline: "nearest" })), !0;
|
|
45
|
+
};
|
|
46
|
+
return M(() => {
|
|
47
|
+
const e = o.items(), r = o.onReorder();
|
|
48
|
+
l && (!r || !e.some((t) => t.id === l && !t.disabled)) && a?.stop({ commit: !1 });
|
|
49
|
+
}), P(() => {
|
|
50
|
+
a?.stop({ commit: !1 }), s && cancelAnimationFrame(s), m !== void 0 && clearTimeout(m), f?.defaultView?.removeEventListener("keydown", g, !0);
|
|
51
|
+
}), { start: L, keyDown: T, dragging: d, before: h, after: A, suppressClick: () => u };
|
|
52
|
+
}
|
|
53
|
+
export {
|
|
54
|
+
C as createTabReorder
|
|
55
|
+
};
|
package/dist/floe.css
CHANGED
|
@@ -480,6 +480,9 @@
|
|
|
480
480
|
* which costs memory and rasterisation on every window, menu and dialog that
|
|
481
481
|
* merely sits on screen. Only the two transitions need it. */
|
|
482
482
|
.floe-floating-presence[data-floating-presence='entering'] {
|
|
483
|
+
/* Placement may resolve after the initial size read. Set its starting pose
|
|
484
|
+
* immediately; only the subsequent open state should transition. */
|
|
485
|
+
transition: none;
|
|
483
486
|
opacity: 0;
|
|
484
487
|
--floe-floating-presence-x: var(--floe-floating-enter-x);
|
|
485
488
|
--floe-floating-presence-y: var(--floe-floating-enter-y);
|
|
@@ -591,6 +594,46 @@
|
|
|
591
594
|
--floe-floating-origin: left top;
|
|
592
595
|
}
|
|
593
596
|
|
|
597
|
+
/* The positioning owner supplies the resolved side, including collision flips.
|
|
598
|
+
* Keep motion on the child so measuring the anchor layer never reads a scale. */
|
|
599
|
+
[data-floe-surface-floating-layer][data-placement='above'] > .floe-floating-menu,
|
|
600
|
+
.floe-floating-menu[data-floating-side='top'] {
|
|
601
|
+
--floe-floating-enter-y: 0.375rem;
|
|
602
|
+
--floe-floating-exit-y: 0.125rem;
|
|
603
|
+
--floe-floating-origin: var(--floe-anchored-layer-anchor-x, 50%) bottom;
|
|
604
|
+
}
|
|
605
|
+
|
|
606
|
+
[data-floe-surface-floating-layer][data-placement='below'] > .floe-floating-menu,
|
|
607
|
+
.floe-floating-menu[data-floating-side='bottom'] {
|
|
608
|
+
--floe-floating-origin: var(--floe-anchored-layer-anchor-x, 50%) top;
|
|
609
|
+
}
|
|
610
|
+
|
|
611
|
+
[data-floe-surface-floating-layer][data-placement='right'] > .floe-floating-menu,
|
|
612
|
+
.floe-floating-menu[data-floating-side='right'] {
|
|
613
|
+
--floe-floating-enter-x: -0.375rem;
|
|
614
|
+
--floe-floating-exit-x: -0.125rem;
|
|
615
|
+
--floe-floating-enter-y: 0;
|
|
616
|
+
--floe-floating-exit-y: 0;
|
|
617
|
+
--floe-floating-origin: left var(--floe-anchored-layer-anchor-y, 50%);
|
|
618
|
+
}
|
|
619
|
+
|
|
620
|
+
[data-floe-surface-floating-layer][data-placement='left'] > .floe-floating-menu,
|
|
621
|
+
.floe-floating-menu[data-floating-side='left'] {
|
|
622
|
+
--floe-floating-enter-x: 0.375rem;
|
|
623
|
+
--floe-floating-exit-x: 0.125rem;
|
|
624
|
+
--floe-floating-enter-y: 0;
|
|
625
|
+
--floe-floating-exit-y: 0;
|
|
626
|
+
--floe-floating-origin: right var(--floe-anchored-layer-anchor-y, 50%);
|
|
627
|
+
}
|
|
628
|
+
|
|
629
|
+
/* A fully clamped panel has no reliable opening side. Fade it in place. */
|
|
630
|
+
[data-floe-surface-floating-layer][data-placement='edge'] > .floe-floating-menu {
|
|
631
|
+
--floe-floating-enter-y: 0;
|
|
632
|
+
--floe-floating-exit-y: 0;
|
|
633
|
+
--floe-floating-enter-scale: 1;
|
|
634
|
+
--floe-floating-exit-scale: 1;
|
|
635
|
+
}
|
|
636
|
+
|
|
594
637
|
.floe-floating-tooltip {
|
|
595
638
|
--floe-floating-enter-duration: 140ms;
|
|
596
639
|
--floe-floating-exit-duration: 90ms;
|