@floegence/floe-webapp-core 0.86.54 → 0.86.57

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/chat.css CHANGED
@@ -1918,7 +1918,7 @@ pre.chat-md-code-block *::selection,
1918
1918
  /* Images and HTML retain one quiet, bounded canvas throughout their lifecycle. */
1919
1919
  @layer components {
1920
1920
  .chat-html-canvas, .chat-media[data-media-kind="image"] .chat-media-viewport { position: relative; isolation: isolate; display: block; width: 100%; overflow: hidden; border: 1px solid color-mix(in srgb, var(--border) 65%, transparent); border-radius: 1rem; background: color-mix(in srgb, var(--muted) 38%, var(--background)); }
1921
- .chat-html-canvas { --canvas-inset: clamp(1rem, 5%, 3rem); height: 28rem; }
1921
+ .chat-html-canvas { --canvas-inset: .625rem; --canvas-control-size: 2.125rem; height: 28rem; }
1922
1922
  .chat-media[data-media-kind="image"] .chat-media-viewport { min-height: 14rem; padding: 3.5rem clamp(1rem, 5%, 2rem) 1.5rem; border: 0; }
1923
1923
  .chat-media[data-media-kind="image"] .chat-media-viewport::before { content: ''; position: absolute; inset: 0; z-index: -1; pointer-events: none; border-radius: inherit; }
1924
1924
  .chat-media[data-media-kind="image"] .chat-media-placeholder { padding: 0; border-radius: 0; background: transparent; }
@@ -1929,7 +1929,7 @@ pre.chat-md-code-block *::selection,
1929
1929
  .chat-html-dots, .chat-media[data-media-kind="image"] .chat-media-viewport::before { background-image: radial-gradient(circle, color-mix(in srgb, var(--muted-foreground) 24%, transparent) .75px, transparent .9px); background-size: 20px 20px; background-position: 9px 9px; }
1930
1930
  .chat-html-sheen { opacity: 0; background: linear-gradient(115deg, transparent 25%, color-mix(in srgb, var(--foreground) 20%, transparent) 49%, transparent 73%); background-size: 250% 100%; mask-image: radial-gradient(circle, black .9px, transparent 1.1px); mask-size: 20px 20px; mask-position: 9px 9px; }
1931
1931
  .chat-html-canvas:is([data-state="generating"], [data-state="loading"]) .chat-html-sheen { opacity: 1; animation: chat-html-sweep 3.4s ease-in-out infinite; }
1932
- .chat-html-sheet, .chat-html-source { position: absolute; inset: 3.5rem var(--canvas-inset) 4.25rem; display: flex; min-width: 0; min-height: 0; overflow: hidden; border: 1px solid color-mix(in srgb, var(--border) 75%, transparent); border-radius: .625rem; box-shadow: 0 14px 40px rgb(0 0 0 / .06), 0 2px 6px rgb(0 0 0 / .03); background: var(--background); }
1932
+ .chat-html-sheet, .chat-html-source { position: absolute; inset: calc(var(--canvas-control-size) + 1rem) var(--canvas-inset) var(--canvas-inset); display: flex; min-width: 0; min-height: 0; overflow: hidden; border: 1px solid color-mix(in srgb, var(--border) 75%, transparent); border-radius: .625rem; box-shadow: 0 14px 40px rgb(0 0 0 / .06), 0 2px 6px rgb(0 0 0 / .03); background: var(--background); }
1933
1933
  .chat-html-sheet { transition: opacity 280ms ease; }
1934
1934
  .chat-html-sheet-hidden { opacity: 0; visibility: hidden; pointer-events: none; }
1935
1935
  .chat-html-sheet .chat-media-html { height: 100%; border-radius: 0; }
@@ -1937,17 +1937,21 @@ pre.chat-md-code-block *::selection,
1937
1937
  .chat-html-source code { padding: 0; color: inherit; background: none; font: inherit; }
1938
1938
  .chat-html-loading { position: absolute; inset: 3.5rem var(--canvas-inset); display: flex; flex-direction: column; justify-content: center; align-items: center; gap: 1rem; text-align: center; color: var(--muted-foreground); font-size: .75rem; }
1939
1939
  .chat-html-orb, .chat-media[data-media-kind="image"] .chat-media-action { display: inline-flex; align-items: center; justify-content: center; flex-shrink: 0; width: 2.125rem; height: 2.125rem; padding: 0; border: 1px solid color-mix(in srgb, var(--border) 80%, transparent); border-radius: 50%; color: var(--muted-foreground); background: color-mix(in srgb, var(--background) 88%, transparent); box-shadow: 0 2px 5px rgb(0 0 0 / .035); backdrop-filter: blur(12px); cursor: pointer; transition: color 140ms, background 140ms, transform 140ms; }
1940
- .chat-html-orb:hover, .chat-media[data-media-kind="image"] .chat-media-action:hover { color: var(--foreground); background: var(--background); transform: translateY(-1px); }
1940
+ .chat-html-orb:hover:not(:disabled), .chat-media[data-media-kind="image"] .chat-media-action:hover { color: var(--foreground); background: var(--background); transform: translateY(-1px); }
1941
+ .chat-html-orb { width: var(--canvas-control-size); height: var(--canvas-control-size); }
1942
+ .chat-html-orb:disabled { opacity: .45; cursor: not-allowed; }
1941
1943
  .chat-html-orb[aria-pressed="true"] { color: var(--foreground); background: var(--muted); }
1942
1944
  .chat-html-orb:focus-visible, .chat-html-source:focus-visible, .chat-media[data-media-kind="image"] .chat-media-action:focus-visible { outline: 2px solid var(--ring); outline-offset: 3px; }
1943
1945
  .chat-html-orb svg { width: .9375rem; height: .9375rem; }
1944
- .chat-html-expand { position: absolute; top: .875rem; right: .875rem; }
1945
- .chat-html-controls { position: absolute; bottom: .875rem; left: .875rem; display: flex; align-items: center; gap: .5rem; }
1946
- .chat-html-feedback { position: absolute; right: 1rem; bottom: 1.125rem; max-width: calc(100% - 7.5rem); display: flex; align-items: center; gap: .4rem; font-size: .6875rem; line-height: 1.5; color: var(--muted-foreground); }
1946
+ .chat-html-toolbar { position: absolute; top: .5rem; right: var(--canvas-inset); left: var(--canvas-inset); height: var(--canvas-control-size); display: flex; align-items: center; gap: .5rem; }
1947
+ .chat-html-controls, .chat-html-window-actions { display: flex; flex-shrink: 0; align-items: center; gap: .5rem; }
1948
+ .chat-html-window-actions { margin-left: auto; }
1949
+ .chat-html-feedback { min-width: 0; display: flex; align-items: center; gap: .4rem; font-size: .6875rem; line-height: 1.5; color: var(--muted-foreground); }
1950
+ .chat-html-feedback > span { min-width: 0; max-height: var(--canvas-control-size); overflow: auto; }
1947
1951
  .chat-html-feedback svg { width: .875rem; height: .875rem; flex-shrink: 0; }
1948
1952
  @keyframes chat-html-sweep { from { background-position: 120% 0; } to { background-position: -80% 0; } }
1949
- @media (max-width: 480px) { .chat-html-canvas { height: 25rem; --canvas-inset: 1rem; } }
1950
- @media (pointer: coarse) { .chat-html-orb, .chat-media[data-media-kind="image"] .chat-media-action { width: 2.625rem; height: 2.625rem; } .chat-media[data-media-kind="image"] .chat-media-viewport { padding-top: 4rem; } .chat-html-controls { bottom: .75rem; left: .75rem; } }
1953
+ @media (max-width: 480px) { .chat-html-canvas { height: 25rem; } }
1954
+ @media (pointer: coarse) { .chat-html-canvas { --canvas-control-size: 2.625rem; } .chat-media[data-media-kind="image"] .chat-media-action { width: 2.625rem; height: 2.625rem; } .chat-media[data-media-kind="image"] .chat-media-viewport { padding-top: 4rem; } }
1951
1955
  @media (prefers-reduced-motion: reduce) { .chat-html-sheen { animation: none !important; background-position: 50% 0; } .chat-html-orb, .chat-html-sheet, .chat-media[data-media-kind="image"] .chat-media-action { transition: none; } }
1952
1956
  @media (forced-colors: active) { .chat-html-orb, .chat-html-source, .chat-html-canvas, .chat-media[data-media-kind="image"] .chat-media-action { border-color: CanvasText; } .chat-html-sheen { display: none; } }
1953
1957
  }
@@ -7,7 +7,7 @@ export interface HtmlPreviewCanvasProps {
7
7
  expanded: boolean;
8
8
  onExpand: () => void;
9
9
  onRetry: () => void;
10
- onPreview: () => void;
10
+ onPreview: (event?: MouseEvent) => void;
11
11
  previewLabel: string;
12
12
  resource?: ResolvedMarkdownMedia;
13
13
  children: JSX.Element;
@@ -1,129 +1,129 @@
1
- import { createComponent as a, insert as l, effect as y, setAttribute as r, memo as N, template as h, use as O, delegateEvents as j } from "solid-js/web";
2
- import { createSignal as U, onCleanup as B, createMemo as I, Show as d } from "solid-js";
3
- import { Copy as J, Eye as z, Refresh as D, ExternalLink as K, FolderOpen as Q, Minus as W, Maximize as X, Code as Y, MoreHorizontal as Z, Check as p } from "../../icons/index.js";
4
- import { Dropdown as ee } from "../../ui/Dropdown.js";
5
- var te = /* @__PURE__ */ h("<pre class=chat-html-source tabindex=0><code>"), ae = /* @__PURE__ */ h("<button type=button class=chat-media-retry>"), le = /* @__PURE__ */ h("<span class=chat-html-loading role=status><span>"), ne = /* @__PURE__ */ h("<span class=chat-html-feedback role=status>"), re = /* @__PURE__ */ h('<span class=chat-html-canvas><span class=chat-html-dots aria-hidden=true></span><span class=chat-html-sheen aria-hidden=true></span><span class=chat-html-sheet></span><button type=button class="chat-html-orb chat-html-expand"></button><span class=chat-html-controls><button type=button class=chat-html-orb data-chat-media-action=source>');
6
- const de = (e) => {
7
- const [c, x] = U(!1), [S, k] = U("");
8
- let b, v = !1, f;
9
- const $ = (n) => {
10
- clearTimeout(f), k(n), f = setTimeout(() => k(""), 2400);
1
+ import { createComponent as a, insert as l, effect as $, setAttribute as n, memo as Q, template as b, use as W, delegateEvents as X } from "solid-js/web";
2
+ import { createSignal as N, onCleanup as Y, createMemo as Z, Show as u } from "solid-js";
3
+ import { Copy as p, Eye as O, Refresh as j, ExternalLink as B, FolderOpen as ee, Code as te, MoreHorizontal as ae, Check as le, Minus as ne, Maximize as ie } from "../../icons/index.js";
4
+ import { Dropdown as re } from "../../ui/Dropdown.js";
5
+ var ce = /* @__PURE__ */ b("<pre class=chat-html-source tabindex=0><code>"), oe = /* @__PURE__ */ b("<button type=button class=chat-media-retry>"), se = /* @__PURE__ */ b("<span class=chat-html-loading role=status><span>"), de = /* @__PURE__ */ b("<span class=chat-html-feedback role=status><span>"), ue = /* @__PURE__ */ b('<span class=chat-html-canvas><span class=chat-html-dots aria-hidden=true></span><span class=chat-html-sheen aria-hidden=true></span><span class=chat-html-sheet></span><span class=chat-html-toolbar><span class=chat-html-controls><button type=button class=chat-html-orb data-chat-media-action=source></button></span><span class=chat-html-window-actions><button type=button class=chat-html-orb data-chat-media-action=preview></button><button type=button class="chat-html-orb chat-html-expand">');
6
+ const ge = (e) => {
7
+ const [o, k] = N(!1), [C, L] = N("");
8
+ let v, m = !1, x;
9
+ const M = (i) => {
10
+ clearTimeout(x), L(i), x = setTimeout(() => L(""), 2400);
11
11
  };
12
- B(() => {
13
- v = !0, clearTimeout(f);
12
+ Y(() => {
13
+ m = !0, clearTimeout(x);
14
14
  });
15
- const V = async () => {
15
+ const I = async () => {
16
16
  try {
17
- if (await navigator.clipboard.writeText(e.html), v) return;
18
- $(e.labels.copied ?? "Copied");
17
+ if (await navigator.clipboard.writeText(e.html), m) return;
18
+ M(e.labels.copied ?? "Copied");
19
19
  } catch {
20
- if (v) return;
21
- const n = e.labels.copyFailed ?? "Select and copy the source.";
22
- x(!0), queueMicrotask(() => {
23
- if (v) return;
24
- b.focus({
20
+ if (m) return;
21
+ const i = e.labels.copyFailed ?? "Select and copy the source.";
22
+ k(!0), queueMicrotask(() => {
23
+ if (m) return;
24
+ v.focus({
25
25
  preventScroll: !0
26
26
  });
27
27
  const g = document.createRange();
28
- g.selectNodeContents(b);
29
- const m = window.getSelection();
30
- m?.removeAllRanges(), m?.addRange(g), $(n);
28
+ g.selectNodeContents(v);
29
+ const w = window.getSelection();
30
+ w?.removeAllRanges(), w?.addRange(g), M(i);
31
31
  });
32
32
  }
33
- }, q = I(() => [{
33
+ }, J = Z(() => [{
34
34
  id: "copy",
35
35
  label: e.labels.copyHTML ?? "Copy HTML",
36
- icon: () => a(J, {}),
36
+ icon: () => a(p, {}),
37
37
  disabled: !e.html
38
38
  }, ...e.state === "ready" ? [{
39
39
  id: "preview",
40
40
  label: e.previewLabel,
41
- icon: () => a(z, {})
41
+ icon: () => a(O, {})
42
42
  }, {
43
43
  id: "replay",
44
44
  label: e.labels.replay ?? "Reload preview",
45
- icon: () => a(D, {})
45
+ icon: () => a(j, {})
46
46
  }] : [], ...e.resource?.openURL && !e.resource.reveal ? [{
47
47
  id: "open",
48
48
  label: e.labels.open,
49
- icon: () => a(K, {})
49
+ icon: () => a(B, {})
50
50
  }] : [], ...e.resource?.reveal ? [{
51
51
  id: "reveal",
52
52
  label: e.resource.reveal.label,
53
- icon: () => a(Q, {})
54
- }] : []]), G = () => e.state === "generating" ? e.labels.generating ?? e.labels.loading : e.state === "incomplete" ? e.labels.incomplete ?? "Generation interrupted. Source is available." : e.state === "error" ? e.labels.unavailable : e.labels.loading;
53
+ icon: () => a(ee, {})
54
+ }] : []]), K = () => e.state === "generating" ? e.labels.generating ?? e.labels.loading : e.state === "incomplete" ? e.labels.incomplete ?? "Generation interrupted. Source is available." : e.state === "error" ? e.labels.unavailable : e.labels.loading;
55
55
  return (() => {
56
- var n = re(), g = n.firstChild, m = g.nextSibling, w = m.nextSibling, o = w.nextSibling, C = o.nextSibling, u = C.firstChild;
57
- return n.$$keydown = (t) => {
56
+ var i = ue(), g = i.firstChild, w = g.nextSibling, f = w.nextSibling, y = f.nextSibling, S = y.firstChild, h = S.firstChild, R = S.nextSibling, s = R.firstChild, d = s.nextSibling;
57
+ return i.$$keydown = (t) => {
58
58
  t.key === "Escape" && e.expanded && !t.defaultPrevented && (t.preventDefault(), e.onExpand());
59
- }, l(w, () => e.children), l(n, a(d, {
59
+ }, l(f, () => e.children), l(i, a(u, {
60
60
  get when() {
61
- return c();
61
+ return o();
62
62
  },
63
63
  get children() {
64
- var t = te(), s = t.firstChild, i = b;
65
- return typeof i == "function" ? O(i, t) : b = t, l(s, () => e.html), y(() => r(t, "aria-label", e.labels.showSource ?? "HTML source")), t;
64
+ var t = ce(), r = t.firstChild, c = v;
65
+ return typeof c == "function" ? W(c, t) : v = t, l(r, () => e.html), $(() => n(t, "aria-label", e.labels.showSource ?? "HTML source")), t;
66
66
  }
67
- }), o), l(n, a(d, {
67
+ }), y), l(i, a(u, {
68
68
  get when() {
69
- return N(() => !c())() && e.state !== "ready";
69
+ return Q(() => !o())() && e.state !== "ready";
70
70
  },
71
71
  get children() {
72
- var t = le(), s = t.firstChild;
73
- return l(s, G), l(t, a(d, {
72
+ var t = se(), r = t.firstChild;
73
+ return l(r, K), l(t, a(u, {
74
74
  get when() {
75
75
  return e.state === "error";
76
76
  },
77
77
  get children() {
78
- var i = ae();
79
- return i.$$click = () => e.onRetry(), l(i, a(D, {}), null), l(i, () => e.labels.retry, null), i;
78
+ var c = oe();
79
+ return c.$$click = () => e.onRetry(), l(c, a(j, {}), null), l(c, () => e.labels.retry, null), c;
80
80
  }
81
- }), null), y(() => r(s, "data-floe-progress-shimmer", e.state === "loading" || e.state === "generating" ? "text" : void 0)), t;
81
+ }), null), $(() => n(r, "data-floe-progress-shimmer", e.state === "loading" || e.state === "generating" ? "text" : void 0)), t;
82
82
  }
83
- }), o), o.$$click = () => e.onExpand(), l(o, a(d, {
83
+ }), y), h.$$click = () => k((t) => !t), l(h, a(u, {
84
84
  get when() {
85
- return e.expanded;
86
- },
87
- get fallback() {
88
- return a(X, {});
89
- },
90
- get children() {
91
- return a(W, {});
92
- }
93
- })), u.$$click = () => x((t) => !t), l(u, a(d, {
94
- get when() {
95
- return c();
85
+ return o();
96
86
  },
97
87
  get fallback() {
98
- return a(Y, {});
88
+ return a(te, {});
99
89
  },
100
90
  get children() {
101
- return a(z, {});
91
+ return a(O, {});
102
92
  }
103
- })), l(C, a(ee, {
93
+ })), l(S, a(re, {
104
94
  get trigger() {
105
- return a(Z, {});
95
+ return a(ae, {});
106
96
  },
107
97
  triggerClass: "chat-html-orb",
108
98
  get triggerAriaLabel() {
109
99
  return e.labels.more ?? "More actions";
110
100
  },
111
- items: q,
101
+ items: J,
112
102
  align: "start",
113
103
  onSelect: (t) => {
114
- t === "copy" ? V() : t === "preview" ? e.onPreview() : t === "replay" ? e.onRetry() : t === "reveal" ? e.resource?.reveal?.onSelect() : t === "open" && e.resource?.openURL && window.open(e.resource.openURL, "_blank", "noopener,noreferrer");
104
+ t === "copy" ? I() : t === "preview" ? e.onPreview() : t === "replay" ? e.onRetry() : t === "reveal" ? e.resource?.reveal?.onSelect() : t === "open" && e.resource?.openURL && window.open(e.resource.openURL, "_blank", "noopener,noreferrer");
115
105
  }
116
- }), null), l(n, a(d, {
106
+ }), null), l(y, a(u, {
117
107
  get when() {
118
- return S();
108
+ return C();
109
+ },
110
+ get children() {
111
+ var t = de(), r = t.firstChild;
112
+ return l(t, a(le, {}), r), l(r, C), t;
113
+ }
114
+ }), R), s.$$click = (t) => e.onPreview(t), l(s, a(B, {})), d.$$click = () => e.onExpand(), l(d, a(u, {
115
+ get when() {
116
+ return e.expanded;
117
+ },
118
+ get fallback() {
119
+ return a(ie, {});
119
120
  },
120
121
  get children() {
121
- var t = ne();
122
- return l(t, a(p, {}), null), l(t, S, null), t;
122
+ return a(ne, {});
123
123
  }
124
- }), null), y((t) => {
125
- var s = e.state, i = c() ? "source" : "preview", L = e.state === "generating" || e.state === "loading", M = !!(c() || e.state !== "ready"), R = c() || e.state !== "ready", T = e.expanded ? "collapse" : "expand", _ = e.expanded, H = e.expanded ? e.labels.collapse : e.labels.expand, E = e.expanded ? e.labels.collapse : e.labels.expand, P = c(), A = c() ? e.labels.showPreview ?? "Show preview" : e.labels.showSource ?? "Show HTML source", F = c() ? e.labels.showPreview ?? "Show preview" : e.labels.showSource ?? "Show HTML source";
126
- return s !== t.e && r(n, "data-state", t.e = s), i !== t.t && r(n, "data-view", t.t = i), L !== t.a && r(n, "aria-busy", t.a = L), M !== t.o && w.classList.toggle("chat-html-sheet-hidden", t.o = M), R !== t.i && (w.inert = t.i = R), T !== t.n && r(o, "data-chat-media-action", t.n = T), _ !== t.s && r(o, "aria-expanded", t.s = _), H !== t.h && r(o, "aria-label", t.h = H), E !== t.r && r(o, "title", t.r = E), P !== t.d && r(u, "aria-pressed", t.d = P), A !== t.l && r(u, "aria-label", t.l = A), F !== t.u && r(u, "title", t.u = F), t;
124
+ })), $((t) => {
125
+ var r = e.state, c = o() ? "source" : "preview", T = e.state === "generating" || e.state === "loading", _ = !!(o() || e.state !== "ready"), H = o() || e.state !== "ready", E = o(), P = o() ? e.labels.showPreview ?? "Show preview" : e.labels.showSource ?? "Show HTML source", A = o() ? e.labels.showPreview ?? "Show preview" : e.labels.showSource ?? "Show HTML source", F = e.state !== "ready", U = e.previewLabel, z = e.previewLabel, D = e.expanded ? "collapse" : "expand", V = e.expanded, q = e.expanded ? e.labels.collapse : e.labels.expand, G = e.expanded ? e.labels.collapse : e.labels.expand;
126
+ return r !== t.e && n(i, "data-state", t.e = r), c !== t.t && n(i, "data-view", t.t = c), T !== t.a && n(i, "aria-busy", t.a = T), _ !== t.o && f.classList.toggle("chat-html-sheet-hidden", t.o = _), H !== t.i && (f.inert = t.i = H), E !== t.n && n(h, "aria-pressed", t.n = E), P !== t.s && n(h, "aria-label", t.s = P), A !== t.h && n(h, "title", t.h = A), F !== t.r && (s.disabled = t.r = F), U !== t.d && n(s, "aria-label", t.d = U), z !== t.l && n(s, "title", t.l = z), D !== t.u && n(d, "data-chat-media-action", t.u = D), V !== t.c && n(d, "aria-expanded", t.c = V), q !== t.w && n(d, "aria-label", t.w = q), G !== t.m && n(d, "title", t.m = G), t;
127
127
  }, {
128
128
  e: void 0,
129
129
  t: void 0,
@@ -136,11 +136,14 @@ const de = (e) => {
136
136
  r: void 0,
137
137
  d: void 0,
138
138
  l: void 0,
139
- u: void 0
140
- }), n;
139
+ u: void 0,
140
+ c: void 0,
141
+ w: void 0,
142
+ m: void 0
143
+ }), i;
141
144
  })();
142
145
  };
143
- j(["keydown", "click"]);
146
+ X(["keydown", "click"]);
144
147
  export {
145
- de as HtmlPreviewCanvas
148
+ ge as HtmlPreviewCanvas
146
149
  };
@@ -262,7 +262,7 @@ const Fe = (e) => {
262
262
  },
263
263
  onExpand: () => S((r) => !r),
264
264
  onRetry: () => D((r) => r + 1),
265
- onPreview: () => j(),
265
+ onPreview: j,
266
266
  get previewLabel() {
267
267
  return M();
268
268
  },
@@ -1,6 +1,6 @@
1
1
  import { effect as s, className as a, template as c } from "solid-js/web";
2
2
  import "solid-js";
3
- import v from "../../../node_modules/.pnpm/dompurify@3.4.16/node_modules/dompurify/dist/purify.es.js";
3
+ import v from "../../../node_modules/.pnpm/dompurify@3.4.17/node_modules/dompurify/dist/purify.es.js";
4
4
  import { cn as m } from "../../../utils/cn.js";
5
5
  var l = /* @__PURE__ */ c("<div>");
6
6
  const S = (r) => {
@@ -1,5 +1,5 @@
1
1
  import { type JSX } from 'solid-js';
2
- export interface SurfaceAnchoredLayerProps {
2
+ export interface SurfaceAnchoredLayerProps extends Omit<JSX.HTMLAttributes<HTMLDivElement>, 'children' | 'class' | 'style' | 'ref'> {
3
3
  anchor: HTMLElement | undefined;
4
4
  /** Changes when the anchor moves through a transform; no idle polling is used. */
5
5
  revision?: unknown;
@@ -11,8 +11,14 @@ export interface SurfaceAnchoredLayerProps {
11
11
  narrowTop?: number;
12
12
  bottom: number;
13
13
  };
14
+ /** Auto places object tools above/below; side panels prefer the requested side and flip when needed. */
15
+ placement?: 'auto' | 'right' | 'left';
16
+ gap?: number;
14
17
  children: JSX.Element;
15
18
  class?: string;
19
+ style?: JSX.CSSProperties;
20
+ layerRef?: (element: HTMLDivElement) => void;
21
+ onAnchorDisconnect?: () => void;
16
22
  }
17
23
  /** Object-attached tools remain in screen pixels within the owning surface. */
18
24
  export declare function SurfaceAnchoredLayer(props: SurfaceAnchoredLayerProps): JSX.Element;
@@ -1,101 +1,128 @@
1
- import { createComponent as p, memo as k } from "solid-js/web";
2
- import { createSignal as l, createEffect as z, onCleanup as g, onMount as T, Show as V } from "solid-js";
3
- import { SurfaceFloatingLayer as $ } from "./SurfaceFloatingLayer.js";
4
- import { resolveFloatingBoundary as j } from "./surfaceFloatingBoundary.js";
5
- import { resolveSurfacePortalHost as E } from "./dialogSurfaceScope.js";
6
- function N(n) {
7
- const [O, R] = l(!1), [S, F] = l({
1
+ import { createComponent as E, mergeProps as K, memo as N } from "solid-js/web";
2
+ import { splitProps as Q, createSignal as l, createEffect as R, onCleanup as O, onMount as U, Show as X } from "solid-js";
3
+ import { SurfaceFloatingLayer as Z } from "./SurfaceFloatingLayer.js";
4
+ import { resolveFloatingBoundary as _ } from "./surfaceFloatingBoundary.js";
5
+ import { observeViewport as ee } from "../../viewport.js";
6
+ import { resolveSurfacePortalHost as L } from "./dialogSurfaceScope.js";
7
+ function se(C) {
8
+ const [o, H] = Q(C, ["anchor", "revision", "topOffset", "reservedSpace", "placement", "gap", "children", "class", "style", "layerRef", "onAnchorDisconnect"]), [P, $] = l(!1), [B, V] = l({
8
9
  x: 0,
9
10
  y: 0
10
- }), [L, A] = l("above"), [x, y] = l(!1), [C, P] = l(480), [M, B] = l();
11
- let d;
12
- const Y = () => {
13
- d = void 0;
14
- const o = n.anchor, r = M();
15
- if (!o || !r) return;
16
- const t = j(E({
17
- owner: o
11
+ }), [Y, q] = l("above"), [S, w] = l(!1), [D, W] = l(480), [z, k] = l();
12
+ let m, x = !1;
13
+ const [A, T] = l({
14
+ x: 0,
15
+ y: 0
16
+ }), [j, G] = l(0), I = () => {
17
+ m = void 0;
18
+ const n = o.anchor, h = z();
19
+ if (!n || !h) return;
20
+ if (!n.isConnected) {
21
+ w(!1), x || o.onAnchorDisconnect?.(), x = !0;
22
+ return;
23
+ }
24
+ x = !1;
25
+ const t = _(L({
26
+ owner: n
18
27
  }));
19
28
  if (!t) {
20
- y(!1);
29
+ w(!1);
21
30
  return;
22
31
  }
23
- const e = o.getBoundingClientRect(), q = Math.max(120, t.width - 24);
24
- P(q);
25
- const a = r.getBoundingClientRect(), H = (Math.max(t.left, e.left) + Math.min(t.right, e.right)) / 2;
26
- let f = Math.max(t.left + 12, Math.min(H - a.width / 2, t.right - a.width - 12));
27
- const u = e.top - (n.topOffset ?? 0), m = u - a.height - 12, h = n.reservedSpace, v = t.top + (window.matchMedia("(max-width:760px)").matches ? h?.narrowTop ?? h?.top ?? 12 : h?.top ?? 12), b = Math.max(v, t.bottom - (h?.bottom ?? 12) - a.height), w = (W) => Math.max(v, Math.min(W, b));
28
- let s = m, c = "above";
29
- m < v ? e.bottom + 12 <= b ? (s = e.bottom + 12, c = "below") : m >= t.top + 12 ? c = "above" : e.bottom + a.height + 12 <= t.bottom - 12 ? (s = e.bottom + 12, c = "below") : e.right + a.width + 24 <= t.right ? (f = e.right + 12, s = w(u), c = "right") : e.left - a.width - 24 >= t.left ? (f = e.left - a.width - 12, s = w(u), c = "left") : (s = w(m), c = "edge") : s = Math.min(s, b), A(c), F({
30
- x: Math.round(f),
32
+ const e = n.getBoundingClientRect(), f = Math.max(120, t.width - 24);
33
+ W(f);
34
+ const r = h.getBoundingClientRect(), J = (Math.max(t.left, e.left) + Math.min(t.right, e.right)) / 2;
35
+ let d = Math.max(t.left + 12, Math.min(J - r.width / 2, t.right - r.width - 12));
36
+ const y = e.top - (o.topOffset ?? 0), i = Math.max(0, o.gap ?? 12), g = y - r.height - i, p = o.reservedSpace, u = t.top + (window.matchMedia("(max-width:760px)").matches ? p?.narrowTop ?? p?.top ?? 12 : p?.top ?? 12), M = Math.max(u, t.bottom - (p?.bottom ?? 12) - r.height), b = (v) => Math.max(u, Math.min(v, M));
37
+ G(Math.max(0, t.bottom - (p?.bottom ?? 12) - u));
38
+ let s = g, a = "above";
39
+ if (o.placement === "right" || o.placement === "left") {
40
+ const v = e.right + i + r.width <= t.right - 12, F = e.left - i - r.width >= t.left + 12;
41
+ a = o.placement, a === "right" && !v && F ? a = "left" : a === "left" && !F && v && (a = "right"), d = Math.max(t.left + 12, Math.min(a === "right" ? e.right + i : e.left - r.width - i, t.right - r.width - 12)), s = b(e.top + e.height / 2 - r.height / 2);
42
+ } else g < u ? e.bottom + i <= M ? (s = e.bottom + i, a = "below") : g >= t.top + 12 ? a = "above" : e.bottom + r.height + i <= t.bottom - 12 ? (s = e.bottom + i, a = "below") : e.right + r.width + i + 12 <= t.right ? (d = e.right + i, s = b(y), a = "right") : e.left - r.width - i - 12 >= t.left ? (d = e.left - r.width - i, s = b(y), a = "left") : (s = b(g), a = "edge") : s = Math.min(s, M);
43
+ T({
44
+ x: Math.max(18, Math.min(e.left + e.width / 2 - d, Math.max(18, r.width - 18))),
45
+ y: Math.max(18, Math.min(e.top + e.height / 2 - s, Math.max(18, r.height - 18)))
46
+ }), q(a), V({
47
+ x: Math.round(d),
31
48
  y: Math.round(s)
32
- }), y(e.right > t.left && e.left < t.right && e.bottom > t.top && e.top < t.bottom);
33
- }, i = () => {
34
- d === void 0 && typeof requestAnimationFrame == "function" && (d = requestAnimationFrame(Y));
49
+ }), w(e.right > t.left && e.left < t.right && e.bottom > t.top && e.top < t.bottom);
50
+ }, c = () => {
51
+ m === void 0 && typeof requestAnimationFrame == "function" && (m = requestAnimationFrame(I));
35
52
  };
36
- return z(() => {
37
- n.anchor, n.revision, n.topOffset, n.reservedSpace, i();
38
- }), z(() => {
39
- const o = M();
40
- if (!o || typeof ResizeObserver > "u") return;
41
- const r = new ResizeObserver(i);
42
- r.observe(o), g(() => r.disconnect());
43
- }), T(() => {
44
- R(!0);
45
- const o = typeof ResizeObserver == "function" ? new ResizeObserver(i) : void 0, r = E({
46
- owner: n.anchor
53
+ return R(() => {
54
+ o.anchor, o.revision, o.topOffset, o.reservedSpace, o.placement, o.gap, c();
55
+ }), R(() => {
56
+ const n = z();
57
+ if (!n || typeof ResizeObserver > "u") return;
58
+ const h = new ResizeObserver(c);
59
+ h.observe(n), O(() => h.disconnect());
60
+ }), U(() => $(!0)), R(() => {
61
+ if (!P()) return;
62
+ const n = o.anchor, h = typeof ResizeObserver == "function" ? new ResizeObserver(c) : void 0, t = L({
63
+ owner: n
47
64
  }).boundaryHost;
48
- r && o?.observe(r);
49
- const t = new MutationObserver(i);
50
- let e = n.anchor?.parentElement;
51
- for (; e && (t.observe(e, {
65
+ t && h?.observe(t), n && h?.observe(n);
66
+ const e = new MutationObserver(c);
67
+ n && e.observe(n, {
52
68
  attributes: !0,
53
69
  attributeFilter: ["style"]
54
- }), e !== r); )
55
- e = e.parentElement;
56
- window.addEventListener("resize", i), window.addEventListener("scroll", i, !0), i(), g(() => {
57
- o?.disconnect(), t.disconnect(), window.removeEventListener("resize", i), window.removeEventListener("scroll", i, !0);
58
70
  });
59
- }), g(() => {
60
- d !== void 0 && cancelAnimationFrame(d);
61
- }), p(V, {
71
+ let f = n?.parentElement;
72
+ for (; f && (e.observe(f, {
73
+ attributes: !0,
74
+ attributeFilter: ["style"],
75
+ childList: !0
76
+ }), f !== t); )
77
+ f = f.parentElement;
78
+ const r = ee(window, c);
79
+ window.addEventListener("scroll", c, !0), c(), O(() => {
80
+ h?.disconnect(), e.disconnect(), r(), window.removeEventListener("scroll", c, !0);
81
+ });
82
+ }), O(() => {
83
+ m !== void 0 && cancelAnimationFrame(m);
84
+ }), E(X, {
62
85
  get when() {
63
- return k(() => !!O())() && n.anchor;
86
+ return N(() => !!P())() && o.anchor;
64
87
  },
65
88
  get children() {
66
- return p($, {
89
+ return E(Z, K(H, {
67
90
  get owner() {
68
- return n.anchor;
91
+ return o.anchor;
69
92
  },
70
93
  get position() {
71
- return S();
94
+ return B();
72
95
  },
73
96
  get class() {
74
- return n.class;
97
+ return o.class;
75
98
  },
76
99
  get "data-placement"() {
77
- return L();
100
+ return Y();
78
101
  },
79
102
  get inert() {
80
- return !x();
103
+ return !S();
81
104
  },
82
105
  get style() {
83
106
  return {
84
- visibility: x() ? "visible" : "hidden",
85
- "max-width": `${C()}px`,
86
- "z-index": 60
107
+ ...o.style,
108
+ "--floe-anchored-layer-anchor-x": `${A().x}px`,
109
+ "--floe-anchored-layer-anchor-y": `${A().y}px`,
110
+ "--floe-anchored-layer-max-height": `${j()}px`,
111
+ visibility: S() ? "visible" : "hidden",
112
+ "max-width": `${D()}px`,
113
+ "z-index": o.style?.["z-index"] ?? 60
87
114
  };
88
115
  },
89
- layerRef: (o) => {
90
- B(o), i();
116
+ layerRef: (n) => {
117
+ k(n), o.layerRef?.(n), c();
91
118
  },
92
119
  get children() {
93
- return n.children;
120
+ return o.children;
94
121
  }
95
- });
122
+ }));
96
123
  }
97
124
  });
98
125
  }
99
126
  export {
100
- N as SurfaceAnchoredLayer
127
+ se as SurfaceAnchoredLayer
101
128
  };