@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.
@@ -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;