@tempots/beatui 1.1.1 → 1.1.3

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 @@
1
+ "use strict";const e=require("@tempots/dom"),q=require("@tempots/ui"),K=require("@tempots/std"),W=require("./use-animated-toggle-cKcuItmz.cjs"),M=require("./session-id-B5lJMzbB.cjs");function H(u){const o={fade:!0,scale:!0};return u.startsWith("top")?(o.slide="down",o.transformOrigin="bottom"):u.startsWith("bottom")?(o.slide="up",o.transformOrigin="top"):u.startsWith("left")?(o.slide="right",o.transformOrigin="right"):u.startsWith("right")&&(o.slide="left",o.transformOrigin="left"),o}function $(u){const{content:o,placement:E="top",showDelay:A=250,hideDelay:D=500,mainAxisOffset:k=8,crossAxisOffset:F=0,showOn:d="hover-focus",closable:b=!0,arrow:P,role:p,hasPopup:I="dialog",open:y}=u;return q.PopOver((g,c)=>{const s=y??e.prop(!1),l=W.useAnimatedElementToggle({initialStatus:"closed"}),L=M.sessionId("flyout");let m=null,f=null,O=!1,v;function T(){t!=null&&(clearTimeout(t),t=null),a!=null&&(clearTimeout(a),a=null),f&&(f(),f=null),m&&(document.removeEventListener("keydown",m),m=null),O=!1}function S(){e.Value.get(b)&&(m=r=>{r.key==="Escape"&&s.set(!1)},document.addEventListener("keydown",m)),O=!0,g({placement:E??"top",mainAxisOffset:k,crossAxisOffset:F,arrow:P,content:e.WithElement(r=>{l.setElement(r);const h=typeof d=="function"?null:e.Value.get(d);(h==="hover"||h==="hover-focus")&&(r.addEventListener("mouseenter",()=>s.set(!0)),r.addEventListener("mouseleave",()=>s.set(!1))),f=K.delayedAnimationFrame(()=>{l.open(),f=null});const C=x=>{e.Value.get(b)&&x.key==="Escape"&&(x.preventDefault(),x.stopPropagation(),s.set(!1))};document.addEventListener("keydown",C,!0);let V=null;return e.Value.get(b)&&(V=x=>{const _=x.target;!r.contains(_)&&!v?.contains(_)&&s.set(!1)},document.addEventListener("click",V)),e.Fragment(e.OnDispose(()=>{V&&(document.removeEventListener("click",V),V=null),T(),document.removeEventListener("keydown",C,!0)}),e.attr.class("bc-flyout-container"),W.AnimatedToggleClass({animation:e.Value.map(E,H),status:l.status}),e.attr.id(L),e.attr.tabindex(-1),e.html.div(e.attr.class("bc-flyout"),p?e.attr.role(p):e.attr.role("dialog"),o()))})})}let t=null;function n(){if(t!=null&&(clearTimeout(t),t=null),a!=null&&(clearTimeout(a),a=null),l.isOpened.value||l.isOpening.value||l.isStartOpening.value)return;if(l.isClosing.value||l.isStartClosing.value){l.open();return}const r=e.Value.get(A);t=setTimeout(()=>{t=null,S()},r)}let a=null;function i(){if(!O&&t==null)return;if(t!=null&&(clearTimeout(t),t=null),a!=null&&(clearTimeout(a),a=null),f&&(f(),f=null,O)){c(),T();return}const r=e.Value.get(D);a=setTimeout(()=>{a=null,l.close(),l.listenOnClosed(()=>{c(),T()})},r)}const w=s.onChange(r=>{r?n():i()});return s.value&&n(),e.WithElement(r=>{v=r;const h=e.Fragment(e.aria.expanded(s),e.aria.controls(L),e.aria.haspopup(I));if(typeof d=="function")return e.Fragment(e.OnDispose(w),h,d(s));const C=d;return e.Fragment(e.OnDispose(w),h,e.OneOfValue(C,{"hover-focus":()=>e.Fragment(e.on.mouseenter(()=>s.set(!0)),e.on.mouseleave(()=>s.set(!1)),e.on.focus(()=>s.set(!0)),e.on.blur(()=>s.set(!1))),hover:()=>e.Fragment(e.on.mouseenter(()=>s.set(!0)),e.on.mouseleave(()=>s.set(!1))),focus:()=>e.Fragment(e.on.focus(()=>s.set(!0)),e.on.blur(()=>s.set(!1))),click:()=>e.on.click(()=>s.set(!s.value)),never:()=>null}))})})}function z(u){const{items:o,placement:E="bottom-start",showDelay:A=0,hideDelay:D=100,mainAxisOffset:k=4,crossAxisOffset:F=0,showOn:d="click",closable:b=!0,onClose:P,onAction:p,ariaLabel:I,ariaLabelledBy:y}=u,g=M.sessionId("menu"),c=e.prop(-1),s=e.prop([]),l=e.prop(!1);let L=null;return l.onChange(m=>{m||P?.()}),$({open:l,content:()=>e.WithElement(m=>{L=document.activeElement;const f=(t,n,a)=>{if(n.length===0)return-1;let i=t+a,w=0;for(;w<n.length;){i>=n.length&&(i=0),i<0&&(i=n.length-1);const r=n[i];if(r&&r.getAttribute("aria-disabled")!=="true")return i;i+=a,w++}return t},O=t=>{const n=s.value,a=c.value;switch(t.key){case"ArrowDown":t.preventDefault(),t.stopPropagation();const i=f(a,n,1);v(i,n);break;case"ArrowUp":t.preventDefault(),t.stopPropagation();const w=f(a,n,-1);v(w,n);break;case"Enter":case" ":if(t.preventDefault(),t.stopPropagation(),a>=0&&n[a]){const r=n[a];if(r.getAttribute("aria-disabled")==="true")return;const h=r.getAttribute("data-key");h&&p&&p(h),r.click(),l.set(!1)}break;case"Escape":l.set(!1);break;case"Home":t.preventDefault(),t.stopPropagation(),n.length>0&&v(0,n);break;case"End":t.preventDefault(),t.stopPropagation(),n.length>0&&v(n.length-1,n);break;case"ArrowRight":if(t.preventDefault(),t.stopPropagation(),a>=0&&n[a]){const r=n[a];r.classList.contains("bc-menu-item--has-submenu")&&r.dispatchEvent(new Event("mouseenter"))}break;case"ArrowLeft":t.preventDefault(),t.stopPropagation(),l.set(!1);break}},v=(t,n)=>{c.value>=0&&n[c.value]&&(n[c.value].classList.remove("bc-menu-item--focused"),n[c.value].removeAttribute("aria-selected")),t>=0&&n[t]&&(n[t].classList.add("bc-menu-item--focused"),n[t].setAttribute("aria-selected","true"),c.set(t),typeof n[t].scrollIntoView=="function"&&n[t].scrollIntoView({block:"nearest"}))},T=()=>{const t=Array.from(m.querySelectorAll('[role="menuitem"]'));if(s.set(t),t.length>0){const n=t.findIndex(a=>a.getAttribute("aria-disabled")!=="true");n>=0&&v(n,t)}},S=new MutationObserver(T);return S.observe(m,{childList:!0,subtree:!0}),setTimeout(()=>{T(),m.focus()},0),document.addEventListener("keydown",O,!0),e.Fragment(e.OnDispose(()=>{S.disconnect(),document.removeEventListener("keydown",O,!0),L&&L.focus()}),e.attr.class("bc-menu"),e.attr.id(g),e.attr.role("menu"),e.attr.tabindex(-1),e.aria.orientation("vertical"),I?e.aria.label(I):e.Empty,y?e.aria.labelledby(y):e.Empty,e.aria.activedescendant(c.map(t=>{const n=s.value;return t>=0&&n[t]?n[t].id||`${g}-item-${t}`:""})),e.on.click(t=>{const a=t.target.closest('[role="menuitem"]');if(a&&a.getAttribute("aria-disabled")!=="true"){const i=a.getAttribute("data-key");i&&p&&p(i),l.set(!1)}}),e.html.div(e.attr.class("sr-only"),e.aria.live("polite"),e.aria.atomic(!0),c.map(t=>{const n=s.value;if(t>=0&&n[t]){const a=n[t].textContent||"";return n[t].getAttribute("aria-disabled")==="true"?`${a}, disabled`:`${a}, ${t+1} of ${n.length}`}return""})),...o())}),placement:E,showDelay:A,hideDelay:D,mainAxisOffset:k,crossAxisOffset:F,showOn:d,closable:b,role:"menu"})}function B(u){const{key:o,content:E,before:A,after:D,disabled:k=!1,onClick:F,ariaLabel:d,submenu:b,submenuPlacement:P="right-start"}=u,p=o??M.sessionId("menu-item"),I=`menu-item-${p}`,y=b!=null;return e.html.div(e.attr.class(e.computedOf(k)(g=>`bc-menu-item ${g?"bc-menu-item--disabled":""} ${y?"bc-menu-item--has-submenu":""}`)),e.attr.id(I),e.attr.role("menuitem"),e.attr.tabindex(-1),e.dataAttr("key",p),e.aria.disabled(k),e.aria.selected(!1),y?e.aria.expanded(!1):e.Empty,d?e.aria.label(d):e.Empty,e.on.click(g=>{if(e.Value.get(k)){g.preventDefault(),g.stopPropagation();return}F?.()}),A&&e.html.span(e.attr.class("bc-menu-item__start"),A),e.html.span(e.attr.class("bc-menu-item__content"),E),D&&e.html.span(e.attr.class("bc-menu-item__end"),D),y&&b?$({content:()=>e.Fragment(e.attr.class("bc-menu bc-submenu"),e.attr.role("menu"),...b()),placement:P,showOn:"hover",hasPopup:"menu",showDelay:100,hideDelay:300,mainAxisOffset:0,crossAxisOffset:0,role:"menu"}):e.Empty)}function N(u={}){const{label:o}=u;return e.html.div(e.attr.class("bc-menu-separator"),e.attr.role("separator"),e.aria.orientation("horizontal"),o&&e.html.span(e.attr.class("bc-menu-separator__label"),o))}exports.Flyout=$;exports.Menu=z;exports.MenuItem=B;exports.MenuSeparator=N;
@@ -0,0 +1,366 @@
1
+ import { prop as q, WithElement as B, Fragment as k, aria as u, OnDispose as z, OneOfValue as j, on as p, Value as A, attr as a, html as E, Empty as W, computedOf as G, dataAttr as J } from "@tempots/dom";
2
+ import { PopOver as Q } from "@tempots/ui";
3
+ import { delayedAnimationFrame as X } from "@tempots/std";
4
+ import { u as Y, A as Z } from "./use-animated-toggle-C3asw_Sg.js";
5
+ import { s as N } from "./session-id-3KiilioY.js";
6
+ function ee(c) {
7
+ const l = { fade: !0, scale: !0 };
8
+ return c.startsWith("top") ? (l.slide = "down", l.transformOrigin = "bottom") : c.startsWith("bottom") ? (l.slide = "up", l.transformOrigin = "top") : c.startsWith("left") ? (l.slide = "right", l.transformOrigin = "right") : c.startsWith("right") && (l.slide = "left", l.transformOrigin = "left"), l;
9
+ }
10
+ function U(c) {
11
+ const {
12
+ content: l,
13
+ placement: T = "top",
14
+ showDelay: P = 250,
15
+ hideDelay: x = 500,
16
+ mainAxisOffset: D = 8,
17
+ crossAxisOffset: _ = 0,
18
+ showOn: b = "hover-focus",
19
+ closable: h = !0,
20
+ arrow: F,
21
+ role: g,
22
+ hasPopup: C = "dialog",
23
+ open: w
24
+ } = c;
25
+ return Q((v, f) => {
26
+ const s = w ?? q(!1), r = Y({
27
+ initialStatus: "closed"
28
+ }), S = N("flyout");
29
+ let m = null, d = null, I = !1, O;
30
+ function $() {
31
+ e != null && (clearTimeout(e), e = null), n != null && (clearTimeout(n), n = null), d && (d(), d = null), m && (document.removeEventListener("keydown", m), m = null), I = !1;
32
+ }
33
+ function K() {
34
+ A.get(h) && (m = (o) => {
35
+ o.key === "Escape" && s.set(!1);
36
+ }, document.addEventListener("keydown", m)), I = !0, v({
37
+ placement: T ?? "top",
38
+ mainAxisOffset: D,
39
+ crossAxisOffset: _,
40
+ arrow: F,
41
+ content: B((o) => {
42
+ r.setElement(o);
43
+ const y = typeof b == "function" ? null : A.get(b);
44
+ (y === "hover" || y === "hover-focus") && (o.addEventListener("mouseenter", () => s.set(!0)), o.addEventListener("mouseleave", () => s.set(!1))), d = X(() => {
45
+ r.open(), d = null;
46
+ });
47
+ const H = (V) => {
48
+ A.get(h) && V.key === "Escape" && (V.preventDefault(), V.stopPropagation(), s.set(!1));
49
+ };
50
+ document.addEventListener("keydown", H, !0);
51
+ let M = null;
52
+ return A.get(h) && (M = (V) => {
53
+ const R = V.target;
54
+ !o.contains(R) && !O?.contains(R) && s.set(!1);
55
+ }, document.addEventListener("click", M)), k(
56
+ z(() => {
57
+ M && (document.removeEventListener("click", M), M = null), $(), document.removeEventListener("keydown", H, !0);
58
+ }),
59
+ a.class("bc-flyout-container"),
60
+ Z({
61
+ animation: A.map(T, ee),
62
+ status: r.status
63
+ }),
64
+ a.id(S),
65
+ a.tabindex(-1),
66
+ // Make focusable for screen readers
67
+ E.div(
68
+ a.class("bc-flyout"),
69
+ g ? a.role(g) : a.role("dialog"),
70
+ // Default to dialog role
71
+ l()
72
+ )
73
+ );
74
+ })
75
+ });
76
+ }
77
+ let e = null;
78
+ function t() {
79
+ if (e != null && (clearTimeout(e), e = null), n != null && (clearTimeout(n), n = null), r.isOpened.value || r.isOpening.value || r.isStartOpening.value)
80
+ return;
81
+ if (r.isClosing.value || r.isStartClosing.value) {
82
+ r.open();
83
+ return;
84
+ }
85
+ const o = A.get(P);
86
+ e = setTimeout(() => {
87
+ e = null, K();
88
+ }, o);
89
+ }
90
+ let n = null;
91
+ function i() {
92
+ if (!I && e == null)
93
+ return;
94
+ if (e != null && (clearTimeout(e), e = null), n != null && (clearTimeout(n), n = null), d && (d(), d = null, I)) {
95
+ f(), $();
96
+ return;
97
+ }
98
+ const o = A.get(x);
99
+ n = setTimeout(() => {
100
+ n = null, r.close(), r.listenOnClosed(() => {
101
+ f(), $();
102
+ });
103
+ }, o);
104
+ }
105
+ const L = s.onChange((o) => {
106
+ o ? t() : i();
107
+ });
108
+ return s.value && t(), B((o) => {
109
+ O = o;
110
+ const y = k(
111
+ u.expanded(s),
112
+ u.controls(S),
113
+ u.haspopup(
114
+ C
115
+ )
116
+ );
117
+ if (typeof b == "function")
118
+ return k(
119
+ z(L),
120
+ y,
121
+ b(s)
122
+ );
123
+ const H = b;
124
+ return k(
125
+ z(L),
126
+ y,
127
+ j(H, {
128
+ "hover-focus": () => k(
129
+ p.mouseenter(() => s.set(!0)),
130
+ p.mouseleave(() => s.set(!1)),
131
+ p.focus(() => s.set(!0)),
132
+ p.blur(() => s.set(!1))
133
+ ),
134
+ hover: () => k(
135
+ p.mouseenter(() => s.set(!0)),
136
+ p.mouseleave(() => s.set(!1))
137
+ ),
138
+ focus: () => k(
139
+ p.focus(() => s.set(!0)),
140
+ p.blur(() => s.set(!1))
141
+ ),
142
+ click: () => p.click(() => s.set(!s.value)),
143
+ never: () => null
144
+ })
145
+ );
146
+ });
147
+ });
148
+ }
149
+ function le(c) {
150
+ const {
151
+ items: l,
152
+ placement: T = "bottom-start",
153
+ showDelay: P = 0,
154
+ hideDelay: x = 100,
155
+ mainAxisOffset: D = 4,
156
+ crossAxisOffset: _ = 0,
157
+ showOn: b = "click",
158
+ closable: h = !0,
159
+ onClose: F,
160
+ onAction: g,
161
+ ariaLabel: C,
162
+ ariaLabelledBy: w
163
+ } = c, v = N("menu"), f = q(-1), s = q([]), r = q(!1);
164
+ let S = null;
165
+ return r.onChange((m) => {
166
+ m || F?.();
167
+ }), U({
168
+ open: r,
169
+ content: () => B((m) => {
170
+ S = document.activeElement;
171
+ const d = (e, t, n) => {
172
+ if (t.length === 0) return -1;
173
+ let i = e + n, L = 0;
174
+ for (; L < t.length; ) {
175
+ i >= t.length && (i = 0), i < 0 && (i = t.length - 1);
176
+ const o = t[i];
177
+ if (o && o.getAttribute("aria-disabled") !== "true")
178
+ return i;
179
+ i += n, L++;
180
+ }
181
+ return e;
182
+ }, I = (e) => {
183
+ const t = s.value, n = f.value;
184
+ switch (e.key) {
185
+ case "ArrowDown":
186
+ e.preventDefault(), e.stopPropagation();
187
+ const i = d(n, t, 1);
188
+ O(i, t);
189
+ break;
190
+ case "ArrowUp":
191
+ e.preventDefault(), e.stopPropagation();
192
+ const L = d(n, t, -1);
193
+ O(L, t);
194
+ break;
195
+ case "Enter":
196
+ case " ":
197
+ if (e.preventDefault(), e.stopPropagation(), n >= 0 && t[n]) {
198
+ const o = t[n];
199
+ if (o.getAttribute("aria-disabled") === "true")
200
+ return;
201
+ const y = o.getAttribute("data-key");
202
+ y && g && g(y), o.click(), r.set(!1);
203
+ }
204
+ break;
205
+ case "Escape":
206
+ r.set(!1);
207
+ break;
208
+ case "Home":
209
+ e.preventDefault(), e.stopPropagation(), t.length > 0 && O(0, t);
210
+ break;
211
+ case "End":
212
+ e.preventDefault(), e.stopPropagation(), t.length > 0 && O(t.length - 1, t);
213
+ break;
214
+ case "ArrowRight":
215
+ if (e.preventDefault(), e.stopPropagation(), n >= 0 && t[n]) {
216
+ const o = t[n];
217
+ o.classList.contains(
218
+ "bc-menu-item--has-submenu"
219
+ ) && o.dispatchEvent(new Event("mouseenter"));
220
+ }
221
+ break;
222
+ case "ArrowLeft":
223
+ e.preventDefault(), e.stopPropagation(), r.set(!1);
224
+ break;
225
+ }
226
+ }, O = (e, t) => {
227
+ f.value >= 0 && t[f.value] && (t[f.value].classList.remove(
228
+ "bc-menu-item--focused"
229
+ ), t[f.value].removeAttribute("aria-selected")), e >= 0 && t[e] && (t[e].classList.add("bc-menu-item--focused"), t[e].setAttribute("aria-selected", "true"), f.set(e), typeof t[e].scrollIntoView == "function" && t[e].scrollIntoView({ block: "nearest" }));
230
+ }, $ = () => {
231
+ const e = Array.from(
232
+ m.querySelectorAll('[role="menuitem"]')
233
+ );
234
+ if (s.set(e), e.length > 0) {
235
+ const t = e.findIndex(
236
+ (n) => n.getAttribute("aria-disabled") !== "true"
237
+ );
238
+ t >= 0 && O(t, e);
239
+ }
240
+ }, K = new MutationObserver($);
241
+ return K.observe(m, { childList: !0, subtree: !0 }), setTimeout(() => {
242
+ $(), m.focus();
243
+ }, 0), document.addEventListener("keydown", I, !0), k(
244
+ z(() => {
245
+ K.disconnect(), document.removeEventListener("keydown", I, !0), S && S.focus();
246
+ }),
247
+ a.class("bc-menu"),
248
+ a.id(v),
249
+ a.role("menu"),
250
+ a.tabindex(-1),
251
+ u.orientation("vertical"),
252
+ C ? u.label(C) : W,
253
+ w ? u.labelledby(w) : W,
254
+ u.activedescendant(
255
+ f.map((e) => {
256
+ const t = s.value;
257
+ return e >= 0 && t[e] ? t[e].id || `${v}-item-${e}` : "";
258
+ })
259
+ ),
260
+ p.click((e) => {
261
+ const n = e.target.closest('[role="menuitem"]');
262
+ if (n && n.getAttribute("aria-disabled") !== "true") {
263
+ const i = n.getAttribute("data-key");
264
+ i && g && g(i), r.set(!1);
265
+ }
266
+ }),
267
+ // Live region for screen reader announcements
268
+ E.div(
269
+ a.class("sr-only"),
270
+ u.live("polite"),
271
+ u.atomic(!0),
272
+ f.map((e) => {
273
+ const t = s.value;
274
+ if (e >= 0 && t[e]) {
275
+ const n = t[e].textContent || "";
276
+ return t[e].getAttribute("aria-disabled") === "true" ? `${n}, disabled` : `${n}, ${e + 1} of ${t.length}`;
277
+ }
278
+ return "";
279
+ })
280
+ ),
281
+ ...l()
282
+ );
283
+ }),
284
+ placement: T,
285
+ showDelay: P,
286
+ hideDelay: x,
287
+ mainAxisOffset: D,
288
+ crossAxisOffset: _,
289
+ showOn: b,
290
+ closable: h,
291
+ role: "menu"
292
+ });
293
+ }
294
+ function re(c) {
295
+ const {
296
+ key: l,
297
+ content: T,
298
+ before: P,
299
+ after: x,
300
+ disabled: D = !1,
301
+ onClick: _,
302
+ ariaLabel: b,
303
+ submenu: h,
304
+ submenuPlacement: F = "right-start"
305
+ } = c, g = l ?? N("menu-item"), C = `menu-item-${g}`, w = h != null;
306
+ return E.div(
307
+ a.class(
308
+ G(D)(
309
+ (v) => `bc-menu-item ${v ? "bc-menu-item--disabled" : ""} ${w ? "bc-menu-item--has-submenu" : ""}`
310
+ )
311
+ ),
312
+ a.id(C),
313
+ a.role("menuitem"),
314
+ a.tabindex(-1),
315
+ J("key", g),
316
+ u.disabled(D),
317
+ u.selected(!1),
318
+ // Will be updated by focus management
319
+ w ? u.expanded(!1) : W,
320
+ b ? u.label(b) : W,
321
+ p.click((v) => {
322
+ if (A.get(D)) {
323
+ v.preventDefault(), v.stopPropagation();
324
+ return;
325
+ }
326
+ _?.();
327
+ }),
328
+ // Before content
329
+ P && E.span(a.class("bc-menu-item__start"), P),
330
+ // Main content
331
+ E.span(a.class("bc-menu-item__content"), T),
332
+ // After content
333
+ x && E.span(a.class("bc-menu-item__end"), x),
334
+ // Submenu (if present)
335
+ w && h ? U({
336
+ content: () => k(
337
+ a.class("bc-menu bc-submenu"),
338
+ a.role("menu"),
339
+ ...h()
340
+ ),
341
+ placement: F,
342
+ showOn: "hover",
343
+ hasPopup: "menu",
344
+ showDelay: 100,
345
+ hideDelay: 300,
346
+ mainAxisOffset: 0,
347
+ crossAxisOffset: 0,
348
+ role: "menu"
349
+ }) : W
350
+ );
351
+ }
352
+ function ie(c = {}) {
353
+ const { label: l } = c;
354
+ return E.div(
355
+ a.class("bc-menu-separator"),
356
+ a.role("separator"),
357
+ u.orientation("horizontal"),
358
+ l && E.span(a.class("bc-menu-separator__label"), l)
359
+ );
360
+ }
361
+ export {
362
+ U as F,
363
+ le as M,
364
+ re as a,
365
+ ie as b
366
+ };
@@ -29,7 +29,7 @@ export interface BreadcrumbsOptions {
29
29
  /**
30
30
  * Maximum number of items to display. When exceeded, middle items
31
31
  * are collapsed into an ellipsis ("...").
32
- * @default undefined (show all items)
32
+ * @default undefined
33
33
  */
34
34
  maxItems?: Value<number>;
35
35
  /**
@@ -1,4 +1,4 @@
1
- import { Renderable, TNode, Value } from '@tempots/dom';
1
+ import { Renderable, TNode, Value, Prop } from '@tempots/dom';
2
2
  import { Placement } from '@tempots/ui';
3
3
  /**
4
4
  * Built-in trigger modes that control how the {@link Flyout} is shown.
@@ -12,14 +12,13 @@ import { Placement } from '@tempots/ui';
12
12
  export type FlyoutTrigger = 'hover' | 'focus' | 'hover-focus' | 'click' | 'never';
13
13
  /**
14
14
  * Custom trigger function for the {@link Flyout} component.
15
- * Receives `show` and `hide` callbacks and returns trigger content that controls
15
+ * Receives the open state signal and returns trigger content that controls
16
16
  * when the flyout appears and disappears.
17
17
  *
18
- * @param show - Call to show the flyout
19
- * @param hide - Call to hide the flyout
18
+ * @param open - Writable signal representing the flyout's open state. Set to `true` to show, `false` to hide.
20
19
  * @returns A renderable node containing the trigger logic
21
20
  */
22
- export type FlyoutTriggerFunction = (show: () => void, hide: () => void) => TNode;
21
+ export type FlyoutTriggerFunction = (open: Prop<boolean>) => TNode;
23
22
  /**
24
23
  * Positioning data for a popover arrow element, provided by the PopOver positioning engine.
25
24
  */
@@ -101,6 +100,17 @@ export interface FlyoutOptions {
101
100
  * @default 'dialog'
102
101
  */
103
102
  hasPopup?: Value<boolean | 'dialog' | 'menu' | 'listbox' | 'tree' | 'grid'>;
103
+ /**
104
+ * External signal controlling the flyout's open/closed state.
105
+ * When provided, this signal becomes the single source of truth:
106
+ * - Setting it to `true` opens the flyout (respecting `showDelay`)
107
+ * - Setting it to `false` closes the flyout (respecting `hideDelay`)
108
+ * - Internal close paths (click-outside, Escape) set this signal to `false`
109
+ * - Built-in and custom triggers toggle this signal
110
+ *
111
+ * When omitted, the flyout manages its own internal open state.
112
+ */
113
+ open?: Prop<boolean>;
104
114
  }
105
115
  /**
106
116
  * Flexible popover component with configurable trigger modes, animated transitions,
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@tempots/beatui",
3
- "version": "1.1.1",
3
+ "version": "1.1.3",
4
4
  "type": "module",
5
5
  "main": "dist/index.umd.js",
6
6
  "module": "dist/index.es.js",