@hyperfixi/behaviors 2.0.0 → 2.2.0

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.
Files changed (189) hide show
  1. package/dist/all.browser.global.js +35 -6
  2. package/dist/all.browser.global.js.map +1 -1
  3. package/dist/autodismiss.browser.global.js +3 -0
  4. package/dist/autodismiss.browser.global.js.map +1 -0
  5. package/dist/behaviors/autodismiss.cjs +177 -0
  6. package/dist/behaviors/autodismiss.cjs.map +1 -0
  7. package/dist/behaviors/autodismiss.d.cts +15 -0
  8. package/dist/behaviors/autodismiss.d.ts +15 -0
  9. package/dist/behaviors/autodismiss.js +15 -0
  10. package/dist/behaviors/autodismiss.js.map +1 -0
  11. package/dist/behaviors/clickoutside.cjs +123 -0
  12. package/dist/behaviors/clickoutside.cjs.map +1 -0
  13. package/dist/behaviors/clickoutside.d.cts +15 -0
  14. package/dist/behaviors/clickoutside.d.ts +15 -0
  15. package/dist/behaviors/clickoutside.js +15 -0
  16. package/dist/behaviors/clickoutside.js.map +1 -0
  17. package/dist/behaviors/clipboard.cjs +193 -0
  18. package/dist/behaviors/clipboard.cjs.map +1 -0
  19. package/dist/behaviors/clipboard.d.cts +15 -0
  20. package/dist/behaviors/clipboard.d.ts +15 -0
  21. package/dist/behaviors/clipboard.js +15 -0
  22. package/dist/behaviors/clipboard.js.map +1 -0
  23. package/dist/behaviors/draggable.cjs +49 -7
  24. package/dist/behaviors/draggable.cjs.map +1 -1
  25. package/dist/behaviors/draggable.d.cts +2 -1
  26. package/dist/behaviors/draggable.d.ts +2 -1
  27. package/dist/behaviors/draggable.js +2 -1
  28. package/dist/behaviors/focustrap.cjs +191 -0
  29. package/dist/behaviors/focustrap.cjs.map +1 -0
  30. package/dist/behaviors/focustrap.d.cts +15 -0
  31. package/dist/behaviors/focustrap.d.ts +15 -0
  32. package/dist/behaviors/focustrap.js +15 -0
  33. package/dist/behaviors/focustrap.js.map +1 -0
  34. package/dist/behaviors/removable.cjs +9 -2
  35. package/dist/behaviors/removable.cjs.map +1 -1
  36. package/dist/behaviors/removable.d.cts +1 -1
  37. package/dist/behaviors/removable.d.ts +1 -1
  38. package/dist/behaviors/removable.js +2 -1
  39. package/dist/behaviors/resizable.cjs +54 -7
  40. package/dist/behaviors/resizable.cjs.map +1 -1
  41. package/dist/behaviors/resizable.d.cts +1 -1
  42. package/dist/behaviors/resizable.d.ts +1 -1
  43. package/dist/behaviors/resizable.js +2 -1
  44. package/dist/behaviors/scrollreveal.cjs +149 -0
  45. package/dist/behaviors/scrollreveal.cjs.map +1 -0
  46. package/dist/behaviors/scrollreveal.d.cts +15 -0
  47. package/dist/behaviors/scrollreveal.d.ts +15 -0
  48. package/dist/behaviors/scrollreveal.js +15 -0
  49. package/dist/behaviors/scrollreveal.js.map +1 -0
  50. package/dist/behaviors/sortable.cjs +49 -7
  51. package/dist/behaviors/sortable.cjs.map +1 -1
  52. package/dist/behaviors/sortable.d.cts +1 -1
  53. package/dist/behaviors/sortable.d.ts +1 -1
  54. package/dist/behaviors/sortable.js +2 -1
  55. package/dist/behaviors/tabs.cjs +247 -0
  56. package/dist/behaviors/tabs.cjs.map +1 -0
  57. package/dist/behaviors/tabs.d.cts +15 -0
  58. package/dist/behaviors/tabs.d.ts +15 -0
  59. package/dist/behaviors/tabs.js +15 -0
  60. package/dist/behaviors/tabs.js.map +1 -0
  61. package/dist/behaviors/toggleable.cjs +36 -7
  62. package/dist/behaviors/toggleable.cjs.map +1 -1
  63. package/dist/behaviors/toggleable.d.cts +2 -1
  64. package/dist/behaviors/toggleable.d.ts +2 -1
  65. package/dist/behaviors/toggleable.js +2 -1
  66. package/dist/chunk-244WSZOL.js +67 -0
  67. package/dist/chunk-244WSZOL.js.map +1 -0
  68. package/dist/chunk-2NSKQMNM.js +99 -0
  69. package/dist/chunk-2NSKQMNM.js.map +1 -0
  70. package/dist/chunk-64DIQGQI.js +37 -0
  71. package/dist/chunk-64DIQGQI.js.map +1 -0
  72. package/dist/chunk-6TJXDCAQ.js +11 -0
  73. package/dist/chunk-6TJXDCAQ.js.map +1 -0
  74. package/dist/chunk-7JDV2THA.js +62 -0
  75. package/dist/chunk-7JDV2THA.js.map +1 -0
  76. package/dist/chunk-AFGA54SA.js +116 -0
  77. package/dist/chunk-AFGA54SA.js.map +1 -0
  78. package/dist/chunk-DYHBKDKB.js +62 -0
  79. package/dist/chunk-DYHBKDKB.js.map +1 -0
  80. package/dist/chunk-GPTHAUWN.js +58 -0
  81. package/dist/chunk-GPTHAUWN.js.map +1 -0
  82. package/dist/chunk-GVJPA2EK.js +68 -0
  83. package/dist/chunk-GVJPA2EK.js.map +1 -0
  84. package/dist/chunk-H2MCHR5A.js +89 -0
  85. package/dist/chunk-H2MCHR5A.js.map +1 -0
  86. package/dist/{chunk-2NQHIHD5.js → chunk-H5Y5ARYG.js} +6 -3
  87. package/dist/chunk-H5Y5ARYG.js.map +1 -0
  88. package/dist/chunk-JKBWIJFI.js +155 -0
  89. package/dist/chunk-JKBWIJFI.js.map +1 -0
  90. package/dist/chunk-QKDYW4VM.js +70 -0
  91. package/dist/chunk-QKDYW4VM.js.map +1 -0
  92. package/dist/chunk-RB7OB6OD.js +51 -0
  93. package/dist/chunk-RB7OB6OD.js.map +1 -0
  94. package/dist/chunk-RPERQTFU.js +75 -0
  95. package/dist/chunk-RPERQTFU.js.map +1 -0
  96. package/dist/chunk-S4QDV2MH.js +75 -0
  97. package/dist/chunk-S4QDV2MH.js.map +1 -0
  98. package/dist/chunk-WTUVPVSD.js +80 -0
  99. package/dist/chunk-WTUVPVSD.js.map +1 -0
  100. package/dist/chunk-YHQRFUWV.js +62 -0
  101. package/dist/chunk-YHQRFUWV.js.map +1 -0
  102. package/dist/chunk-ZQQZTMCJ.js +64 -0
  103. package/dist/chunk-ZQQZTMCJ.js.map +1 -0
  104. package/dist/clickoutside.browser.global.js +12 -0
  105. package/dist/clickoutside.browser.global.js.map +1 -0
  106. package/dist/clipboard.browser.global.js +3 -0
  107. package/dist/clipboard.browser.global.js.map +1 -0
  108. package/dist/core.browser.global.js +3 -3
  109. package/dist/core.browser.global.js.map +1 -1
  110. package/dist/draggable.browser.global.js +2 -2
  111. package/dist/draggable.browser.global.js.map +1 -1
  112. package/dist/focustrap.browser.global.js +9 -0
  113. package/dist/focustrap.browser.global.js.map +1 -0
  114. package/dist/index.cjs +1270 -50
  115. package/dist/index.cjs.map +1 -1
  116. package/dist/index.d.cts +13 -7
  117. package/dist/index.d.ts +13 -7
  118. package/dist/index.js +155 -48
  119. package/dist/index.js.map +1 -1
  120. package/dist/loaders.cjs +1151 -30
  121. package/dist/loaders.cjs.map +1 -1
  122. package/dist/loaders.js +9 -3
  123. package/dist/registry.d.cts +1 -1
  124. package/dist/registry.d.ts +1 -1
  125. package/dist/removable.browser.global.js +2 -2
  126. package/dist/removable.browser.global.js.map +1 -1
  127. package/dist/resizable.browser.global.js +2 -2
  128. package/dist/resizable.browser.global.js.map +1 -1
  129. package/dist/schemas/index.cjs +343 -1
  130. package/dist/schemas/index.cjs.map +1 -1
  131. package/dist/schemas/index.d.cts +45 -3
  132. package/dist/schemas/index.d.ts +45 -3
  133. package/dist/schemas/index.js +34 -4
  134. package/dist/schemas/index.js.map +1 -1
  135. package/dist/scrollreveal.browser.global.js +11 -0
  136. package/dist/scrollreveal.browser.global.js.map +1 -0
  137. package/dist/sortable.browser.global.js +2 -2
  138. package/dist/sortable.browser.global.js.map +1 -1
  139. package/dist/tabs.browser.global.js +3 -0
  140. package/dist/tabs.browser.global.js.map +1 -0
  141. package/dist/toggleable.browser.global.js +2 -2
  142. package/dist/toggleable.browser.global.js.map +1 -1
  143. package/dist/{types-CCc_2wAb.d.cts → types-DCCtVQS5.d.cts} +1 -1
  144. package/dist/{types-CCc_2wAb.d.ts → types-DCCtVQS5.d.ts} +1 -1
  145. package/package.json +45 -2
  146. package/src/behaviors/autodismiss.test.ts +61 -0
  147. package/src/behaviors/autodismiss.ts +107 -0
  148. package/src/behaviors/clickoutside.test.ts +52 -0
  149. package/src/behaviors/clickoutside.ts +77 -0
  150. package/src/behaviors/clipboard.test.ts +67 -0
  151. package/src/behaviors/clipboard.ts +130 -0
  152. package/src/behaviors/draggable.ts +62 -15
  153. package/src/behaviors/focustrap.test.ts +59 -0
  154. package/src/behaviors/focustrap.ts +158 -0
  155. package/src/behaviors/index.ts +37 -0
  156. package/src/behaviors/integration.test.ts +120 -45
  157. package/src/behaviors/removable.ts +4 -5
  158. package/src/behaviors/resizable.ts +63 -14
  159. package/src/behaviors/scrollreveal.test.ts +59 -0
  160. package/src/behaviors/scrollreveal.ts +78 -0
  161. package/src/behaviors/sortable.ts +61 -14
  162. package/src/behaviors/tabs.test.ts +81 -0
  163. package/src/behaviors/tabs.ts +196 -0
  164. package/src/behaviors/toggleable.ts +45 -13
  165. package/src/generated/metadata.ts +38 -7
  166. package/src/generated/types.ts +5 -5
  167. package/src/index.test.ts +143 -5
  168. package/src/index.ts +65 -13
  169. package/src/loaders.ts +18 -0
  170. package/src/registry.test.ts +26 -5
  171. package/src/schemas/autodismiss.schema.ts +66 -0
  172. package/src/schemas/clickoutside.schema.ts +39 -0
  173. package/src/schemas/clipboard.schema.ts +72 -0
  174. package/src/schemas/focustrap.schema.ts +53 -0
  175. package/src/schemas/index.ts +18 -0
  176. package/src/schemas/scrollreveal.schema.ts +60 -0
  177. package/src/schemas/tabs.schema.ts +66 -0
  178. package/src/schemas/types.ts +13 -1
  179. package/dist/chunk-2NQHIHD5.js.map +0 -1
  180. package/dist/chunk-3Q652JQB.js +0 -37
  181. package/dist/chunk-3Q652JQB.js.map +0 -1
  182. package/dist/chunk-HMRPQWQU.js +0 -37
  183. package/dist/chunk-HMRPQWQU.js.map +0 -1
  184. package/dist/chunk-MEP6B7XW.js +0 -37
  185. package/dist/chunk-MEP6B7XW.js.map +0 -1
  186. package/dist/chunk-URBOGGW6.js +0 -32
  187. package/dist/chunk-URBOGGW6.js.map +0 -1
  188. package/dist/chunk-WU37DFAL.js +0 -37
  189. package/dist/chunk-WU37DFAL.js.map +0 -1
package/dist/index.cjs CHANGED
@@ -74,6 +74,18 @@ end
74
74
  }
75
75
  });
76
76
 
77
+ // src/schemas/types.ts
78
+ function resolveRuntime() {
79
+ if (typeof window === "undefined") return null;
80
+ const win = window;
81
+ return win.lokascript || win.hyperfixi || null;
82
+ }
83
+ var init_types = __esm({
84
+ "src/schemas/types.ts"() {
85
+ "use strict";
86
+ }
87
+ });
88
+
77
89
  // src/behaviors/draggable.ts
78
90
  var draggable_exports = {};
79
91
  __export(draggable_exports, {
@@ -82,28 +94,64 @@ __export(draggable_exports, {
82
94
  draggableSource: () => draggableSource,
83
95
  registerDraggable: () => registerDraggable
84
96
  });
97
+ function installDraggable(element, params) {
98
+ let dragHandle = element;
99
+ if (params.dragHandle && params.dragHandle !== "me") {
100
+ if (typeof params.dragHandle === "string") {
101
+ const found = element.querySelector(params.dragHandle);
102
+ if (found instanceof HTMLElement) dragHandle = found;
103
+ } else if (params.dragHandle instanceof HTMLElement) {
104
+ dragHandle = params.dragHandle;
105
+ }
106
+ }
107
+ dragHandle.addEventListener("pointerdown", (e) => {
108
+ e.preventDefault();
109
+ e.stopPropagation();
110
+ element.dispatchEvent(new CustomEvent("draggable:start", { bubbles: true }));
111
+ const startX = element.offsetLeft;
112
+ const startY = element.offsetTop;
113
+ const xoff = e.clientX - startX;
114
+ const yoff = e.clientY - startY;
115
+ function onMove(ev) {
116
+ element.style.left = `${ev.clientX - xoff}px`;
117
+ element.style.top = `${ev.clientY - yoff}px`;
118
+ element.dispatchEvent(new CustomEvent("draggable:move", { bubbles: true }));
119
+ }
120
+ function onUp() {
121
+ document.removeEventListener("pointermove", onMove);
122
+ document.removeEventListener("pointerup", onUp);
123
+ element.dispatchEvent(new CustomEvent("draggable:end", { bubbles: true }));
124
+ }
125
+ document.addEventListener("pointermove", onMove);
126
+ document.addEventListener("pointerup", onUp);
127
+ });
128
+ }
85
129
  async function registerDraggable(hyperfixi) {
86
- const hf = hyperfixi || (typeof window !== "undefined" ? window.lokascript : null);
130
+ const hf = hyperfixi || resolveRuntime();
87
131
  if (!hf) {
88
132
  throw new Error(
89
133
  "LokaScript not found. Make sure @hyperfixi/core is loaded before registering behaviors."
90
134
  );
91
135
  }
92
- const result = hf.compileSync(draggableSchema.source, { traditional: true });
93
- if (!result.ok) {
94
- throw new Error(`Failed to compile Draggable behavior: ${JSON.stringify(result.errors)}`);
95
- }
136
+ const syntheticNode = {
137
+ type: "behavior",
138
+ name: "Draggable",
139
+ parameters: ["dragHandle"],
140
+ eventHandlers: [],
141
+ imperativeInstaller: installDraggable
142
+ };
96
143
  const ctx = hf.createContext ? hf.createContext() : { locals: /* @__PURE__ */ new Map(), globals: /* @__PURE__ */ new Map() };
97
- await hf.execute(result.ast, ctx);
144
+ await hf.execute(syntheticNode, ctx);
98
145
  }
99
146
  var draggableSource, draggableMetadata, draggable_default;
100
147
  var init_draggable = __esm({
101
148
  "src/behaviors/draggable.ts"() {
102
149
  "use strict";
103
150
  init_draggable_schema();
151
+ init_types();
104
152
  draggableSource = draggableSchema.source;
105
153
  draggableMetadata = draggableSchema;
106
- if (typeof window !== "undefined" && window.lokascript) {
154
+ if (resolveRuntime()) {
107
155
  registerDraggable().catch(console.error);
108
156
  }
109
157
  draggable_default = {
@@ -188,7 +236,7 @@ __export(removable_exports, {
188
236
  removableSource: () => removableSource
189
237
  });
190
238
  async function registerRemovable(hyperfixi) {
191
- const hf = hyperfixi || (typeof window !== "undefined" ? window.lokascript : null);
239
+ const hf = hyperfixi || resolveRuntime();
192
240
  if (!hf) {
193
241
  throw new Error(
194
242
  "LokaScript not found. Make sure @hyperfixi/core is loaded before registering behaviors."
@@ -206,9 +254,10 @@ var init_removable = __esm({
206
254
  "src/behaviors/removable.ts"() {
207
255
  "use strict";
208
256
  init_removable_schema();
257
+ init_types();
209
258
  removableSource = removableSchema.source;
210
259
  removableMetadata = removableSchema;
211
- if (typeof window !== "undefined" && window.lokascript) {
260
+ if (resolveRuntime()) {
212
261
  registerRemovable().catch(console.error);
213
262
  }
214
263
  removable_default = {
@@ -277,28 +326,51 @@ __export(toggleable_exports, {
277
326
  toggleableMetadata: () => toggleableMetadata,
278
327
  toggleableSource: () => toggleableSource
279
328
  });
329
+ function installToggleable(element, params) {
330
+ const cls = params.cls || "active";
331
+ let targetEl = element;
332
+ if (params.target && params.target !== "me") {
333
+ if (typeof params.target === "string") {
334
+ const found = document.querySelector(params.target);
335
+ if (found instanceof HTMLElement) targetEl = found;
336
+ } else if (params.target instanceof HTMLElement) {
337
+ targetEl = params.target;
338
+ }
339
+ }
340
+ element.addEventListener("click", () => {
341
+ const wasOn = targetEl.classList.contains(cls);
342
+ targetEl.classList.toggle(cls);
343
+ targetEl.dispatchEvent(
344
+ new CustomEvent(wasOn ? "toggleable:off" : "toggleable:on", { bubbles: true })
345
+ );
346
+ });
347
+ }
280
348
  async function registerToggleable(hyperfixi) {
281
- const hf = hyperfixi || (typeof window !== "undefined" ? window.lokascript : null);
349
+ const hf = hyperfixi || resolveRuntime();
282
350
  if (!hf) {
283
351
  throw new Error(
284
352
  "LokaScript not found. Make sure @hyperfixi/core is loaded before registering behaviors."
285
353
  );
286
354
  }
287
- const result = hf.compileSync(toggleableSchema.source, { traditional: true });
288
- if (!result.ok) {
289
- throw new Error(`Failed to compile Toggleable behavior: ${JSON.stringify(result.errors)}`);
290
- }
355
+ const syntheticNode = {
356
+ type: "behavior",
357
+ name: "Toggleable",
358
+ parameters: ["cls", "target"],
359
+ eventHandlers: [],
360
+ imperativeInstaller: installToggleable
361
+ };
291
362
  const ctx = hf.createContext ? hf.createContext() : { locals: /* @__PURE__ */ new Map(), globals: /* @__PURE__ */ new Map() };
292
- await hf.execute(result.ast, ctx);
363
+ await hf.execute(syntheticNode, ctx);
293
364
  }
294
365
  var toggleableSource, toggleableMetadata, toggleable_default;
295
366
  var init_toggleable = __esm({
296
367
  "src/behaviors/toggleable.ts"() {
297
368
  "use strict";
298
369
  init_toggleable_schema();
370
+ init_types();
299
371
  toggleableSource = toggleableSchema.source;
300
372
  toggleableMetadata = toggleableSchema;
301
- if (typeof window !== "undefined" && window.lokascript) {
373
+ if (resolveRuntime()) {
302
374
  registerToggleable().catch(console.error);
303
375
  }
304
376
  toggleable_default = {
@@ -381,28 +453,64 @@ __export(sortable_exports, {
381
453
  sortableMetadata: () => sortableMetadata,
382
454
  sortableSource: () => sortableSource
383
455
  });
456
+ function installSortable(element, params) {
457
+ const dragClass = params.dragClass || "sorting";
458
+ const handleSelector = params.handle || null;
459
+ element.addEventListener("pointerdown", (e) => {
460
+ const target = e.target;
461
+ const item = target.closest("li");
462
+ if (!item || !element.contains(item)) return;
463
+ if (handleSelector) {
464
+ const handleEl = target.closest(handleSelector);
465
+ if (!handleEl) return;
466
+ }
467
+ e.preventDefault();
468
+ item.classList.add(dragClass);
469
+ element.dispatchEvent(new CustomEvent("sortable:start", { bubbles: true, detail: { item } }));
470
+ function onMove(ev) {
471
+ element.dispatchEvent(
472
+ new CustomEvent("sortable:move", {
473
+ bubbles: true,
474
+ detail: { clientY: ev.clientY, item }
475
+ })
476
+ );
477
+ }
478
+ function onUp() {
479
+ document.removeEventListener("pointermove", onMove);
480
+ document.removeEventListener("pointerup", onUp);
481
+ item.classList.remove(dragClass);
482
+ element.dispatchEvent(new CustomEvent("sortable:end", { bubbles: true, detail: { item } }));
483
+ }
484
+ document.addEventListener("pointermove", onMove);
485
+ document.addEventListener("pointerup", onUp);
486
+ });
487
+ }
384
488
  async function registerSortable(hyperfixi) {
385
- const hf = hyperfixi || (typeof window !== "undefined" ? window.lokascript : null);
489
+ const hf = hyperfixi || resolveRuntime();
386
490
  if (!hf) {
387
491
  throw new Error(
388
492
  "LokaScript not found. Make sure @hyperfixi/core is loaded before registering behaviors."
389
493
  );
390
494
  }
391
- const result = hf.compileSync(sortableSchema.source, { traditional: true });
392
- if (!result.ok) {
393
- throw new Error(`Failed to compile Sortable behavior: ${JSON.stringify(result.errors)}`);
394
- }
495
+ const syntheticNode = {
496
+ type: "behavior",
497
+ name: "Sortable",
498
+ parameters: ["handle", "dragClass"],
499
+ eventHandlers: [],
500
+ imperativeInstaller: installSortable
501
+ };
395
502
  const ctx = hf.createContext ? hf.createContext() : { locals: /* @__PURE__ */ new Map(), globals: /* @__PURE__ */ new Map() };
396
- await hf.execute(result.ast, ctx);
503
+ await hf.execute(syntheticNode, ctx);
397
504
  }
398
505
  var sortableSource, sortableMetadata, sortable_default;
399
506
  var init_sortable = __esm({
400
507
  "src/behaviors/sortable.ts"() {
401
508
  "use strict";
402
509
  init_sortable_schema();
510
+ init_types();
403
511
  sortableSource = sortableSchema.source;
404
512
  sortableMetadata = sortableSchema;
405
- if (typeof window !== "undefined" && window.lokascript) {
513
+ if (resolveRuntime()) {
406
514
  registerSortable().catch(console.error);
407
515
  }
408
516
  sortable_default = {
@@ -512,28 +620,69 @@ __export(resizable_exports, {
512
620
  resizableMetadata: () => resizableMetadata,
513
621
  resizableSource: () => resizableSource
514
622
  });
623
+ function installResizable(element, params) {
624
+ let handleEl = element;
625
+ if (params.handle && params.handle !== "me") {
626
+ if (typeof params.handle === "string") {
627
+ const found = element.querySelector(params.handle);
628
+ if (found instanceof HTMLElement) handleEl = found;
629
+ } else if (params.handle instanceof HTMLElement) {
630
+ handleEl = params.handle;
631
+ }
632
+ }
633
+ const minW = params.minWidth ?? 50;
634
+ const minH = params.minHeight ?? 50;
635
+ const maxW = params.maxWidth ?? 9999;
636
+ const maxH = params.maxHeight ?? 9999;
637
+ handleEl.addEventListener("pointerdown", (e) => {
638
+ e.preventDefault();
639
+ element.dispatchEvent(new CustomEvent("resizable:start", { bubbles: true }));
640
+ const startWidth = element.offsetWidth;
641
+ const startHeight = element.offsetHeight;
642
+ const startX = e.clientX;
643
+ const startY = e.clientY;
644
+ function onMove(ev) {
645
+ const newWidth = Math.max(minW, Math.min(maxW, startWidth + (ev.clientX - startX)));
646
+ const newHeight = Math.max(minH, Math.min(maxH, startHeight + (ev.clientY - startY)));
647
+ element.style.width = `${newWidth}px`;
648
+ element.style.height = `${newHeight}px`;
649
+ element.dispatchEvent(new CustomEvent("resizable:resize", { bubbles: true }));
650
+ }
651
+ function onUp() {
652
+ document.removeEventListener("pointermove", onMove);
653
+ document.removeEventListener("pointerup", onUp);
654
+ element.dispatchEvent(new CustomEvent("resizable:end", { bubbles: true }));
655
+ }
656
+ document.addEventListener("pointermove", onMove);
657
+ document.addEventListener("pointerup", onUp);
658
+ });
659
+ }
515
660
  async function registerResizable(hyperfixi) {
516
- const hf = hyperfixi || (typeof window !== "undefined" ? window.lokascript : null);
661
+ const hf = hyperfixi || resolveRuntime();
517
662
  if (!hf) {
518
663
  throw new Error(
519
664
  "LokaScript not found. Make sure @hyperfixi/core is loaded before registering behaviors."
520
665
  );
521
666
  }
522
- const result = hf.compileSync(resizableSchema.source, { traditional: true });
523
- if (!result.ok) {
524
- throw new Error(`Failed to compile Resizable behavior: ${JSON.stringify(result.errors)}`);
525
- }
667
+ const syntheticNode = {
668
+ type: "behavior",
669
+ name: "Resizable",
670
+ parameters: ["handle", "minWidth", "minHeight", "maxWidth", "maxHeight"],
671
+ eventHandlers: [],
672
+ imperativeInstaller: installResizable
673
+ };
526
674
  const ctx = hf.createContext ? hf.createContext() : { locals: /* @__PURE__ */ new Map(), globals: /* @__PURE__ */ new Map() };
527
- await hf.execute(result.ast, ctx);
675
+ await hf.execute(syntheticNode, ctx);
528
676
  }
529
677
  var resizableSource, resizableMetadata, resizable_default;
530
678
  var init_resizable = __esm({
531
679
  "src/behaviors/resizable.ts"() {
532
680
  "use strict";
533
681
  init_resizable_schema();
682
+ init_types();
534
683
  resizableSource = resizableSchema.source;
535
684
  resizableMetadata = resizableSchema;
536
- if (typeof window !== "undefined" && window.lokascript) {
685
+ if (resolveRuntime()) {
537
686
  registerResizable().catch(console.error);
538
687
  }
539
688
  resizable_default = {
@@ -544,21 +693,989 @@ var init_resizable = __esm({
544
693
  }
545
694
  });
546
695
 
696
+ // src/schemas/clipboard.schema.ts
697
+ var clipboardSchema;
698
+ var init_clipboard_schema = __esm({
699
+ "src/schemas/clipboard.schema.ts"() {
700
+ "use strict";
701
+ clipboardSchema = {
702
+ name: "Clipboard",
703
+ category: "ui",
704
+ tier: "core",
705
+ version: "1.0.0",
706
+ description: "Copies text to clipboard on click with visual feedback",
707
+ parameters: [
708
+ {
709
+ name: "text",
710
+ type: "string",
711
+ optional: true,
712
+ description: "Literal text to copy (takes priority over source)"
713
+ },
714
+ {
715
+ name: "source",
716
+ type: "selector",
717
+ optional: true,
718
+ default: "me",
719
+ description: "Element whose textContent or value is copied"
720
+ },
721
+ {
722
+ name: "feedback",
723
+ type: "selector",
724
+ optional: true,
725
+ description: "Element to show .copied feedback on (defaults to the installed element)"
726
+ },
727
+ {
728
+ name: "feedbackDuration",
729
+ type: "number",
730
+ optional: true,
731
+ default: 2e3,
732
+ description: "Duration in ms to show .copied class feedback"
733
+ }
734
+ ],
735
+ events: [
736
+ { name: "clipboard:copied", description: "Fired after text is copied successfully" },
737
+ { name: "clipboard:error", description: "Fired when clipboard write fails" }
738
+ ],
739
+ requirements: [
740
+ "navigator.clipboard.writeText() requires HTTPS or localhost",
741
+ 'Falls back to document.execCommand("copy") for older browsers'
742
+ ],
743
+ source: [
744
+ "behavior Clipboard(text, source, feedback, feedbackDuration)",
745
+ " init",
746
+ " if feedbackDuration is undefined set feedbackDuration to 2000",
747
+ " if source is undefined set source to me",
748
+ " end",
749
+ " on click",
750
+ " if text is not undefined",
751
+ " set copyText to text",
752
+ " else",
753
+ " set copyText to source's value or source's textContent",
754
+ " end",
755
+ " js(copyText) navigator.clipboard.writeText(copyText) end",
756
+ " set feedbackEl to feedback or me",
757
+ " add .copied to feedbackEl",
758
+ " wait feedbackDuration ms",
759
+ " remove .copied from feedbackEl",
760
+ " trigger clipboard:copied",
761
+ " end",
762
+ "end"
763
+ ].join("\n")
764
+ };
765
+ }
766
+ });
767
+
768
+ // src/behaviors/clipboard.ts
769
+ var clipboard_exports = {};
770
+ __export(clipboard_exports, {
771
+ clipboardMetadata: () => clipboardMetadata,
772
+ clipboardSource: () => clipboardSource,
773
+ default: () => clipboard_default,
774
+ registerClipboard: () => registerClipboard
775
+ });
776
+ async function copyToClipboard(text) {
777
+ if (navigator.clipboard?.writeText) {
778
+ await navigator.clipboard.writeText(text);
779
+ return;
780
+ }
781
+ const textarea = document.createElement("textarea");
782
+ textarea.value = text;
783
+ textarea.style.position = "fixed";
784
+ textarea.style.opacity = "0";
785
+ document.body.appendChild(textarea);
786
+ textarea.select();
787
+ try {
788
+ document.execCommand("copy");
789
+ } finally {
790
+ document.body.removeChild(textarea);
791
+ }
792
+ }
793
+ function resolveElement(element, param) {
794
+ if (!param || param === "me") return element;
795
+ if (param instanceof HTMLElement) return param;
796
+ if (typeof param === "string") {
797
+ return element.querySelector(param) || document.querySelector(param) || null;
798
+ }
799
+ return null;
800
+ }
801
+ function installClipboard(element, params) {
802
+ const feedbackDuration = typeof params.feedbackDuration === "number" ? params.feedbackDuration : 2e3;
803
+ element.addEventListener("click", async () => {
804
+ let copyText;
805
+ if (params.text != null) {
806
+ copyText = String(params.text);
807
+ } else {
808
+ const sourceEl = resolveElement(element, params.source) || element;
809
+ copyText = sourceEl.value ?? sourceEl.textContent ?? "";
810
+ }
811
+ try {
812
+ await copyToClipboard(copyText);
813
+ const feedbackEl = resolveElement(element, params.feedback) || element;
814
+ feedbackEl.classList.add("copied");
815
+ setTimeout(() => feedbackEl.classList.remove("copied"), feedbackDuration);
816
+ element.dispatchEvent(
817
+ new CustomEvent("clipboard:copied", {
818
+ bubbles: true,
819
+ detail: { text: copyText }
820
+ })
821
+ );
822
+ } catch (error) {
823
+ element.dispatchEvent(
824
+ new CustomEvent("clipboard:error", {
825
+ bubbles: true,
826
+ detail: { error }
827
+ })
828
+ );
829
+ }
830
+ });
831
+ }
832
+ async function registerClipboard(hyperfixi) {
833
+ const hf = hyperfixi || resolveRuntime();
834
+ if (!hf) {
835
+ throw new Error(
836
+ "LokaScript not found. Make sure @hyperfixi/core is loaded before registering behaviors."
837
+ );
838
+ }
839
+ const syntheticNode = {
840
+ type: "behavior",
841
+ name: "Clipboard",
842
+ parameters: ["text", "source", "feedback", "feedbackDuration"],
843
+ eventHandlers: [],
844
+ imperativeInstaller: installClipboard
845
+ };
846
+ const ctx = hf.createContext ? hf.createContext() : { locals: /* @__PURE__ */ new Map(), globals: /* @__PURE__ */ new Map() };
847
+ await hf.execute(syntheticNode, ctx);
848
+ }
849
+ var clipboardSource, clipboardMetadata, clipboard_default;
850
+ var init_clipboard = __esm({
851
+ "src/behaviors/clipboard.ts"() {
852
+ "use strict";
853
+ init_clipboard_schema();
854
+ init_types();
855
+ clipboardSource = clipboardSchema.source;
856
+ clipboardMetadata = clipboardSchema;
857
+ if (resolveRuntime()) {
858
+ registerClipboard().catch(console.error);
859
+ }
860
+ clipboard_default = {
861
+ source: clipboardSchema.source,
862
+ metadata: clipboardSchema,
863
+ register: registerClipboard
864
+ };
865
+ }
866
+ });
867
+
868
+ // src/schemas/autodismiss.schema.ts
869
+ var autoDismissSchema;
870
+ var init_autodismiss_schema = __esm({
871
+ "src/schemas/autodismiss.schema.ts"() {
872
+ "use strict";
873
+ autoDismissSchema = {
874
+ name: "AutoDismiss",
875
+ category: "ui",
876
+ tier: "core",
877
+ version: "1.0.0",
878
+ description: "Auto-removes elements after a delay with optional pause-on-hover",
879
+ parameters: [
880
+ {
881
+ name: "delay",
882
+ type: "number",
883
+ optional: true,
884
+ default: 5e3,
885
+ description: "Time in ms before the element is removed"
886
+ },
887
+ {
888
+ name: "pauseOnHover",
889
+ type: "boolean",
890
+ optional: true,
891
+ default: true,
892
+ description: "Pause the countdown when the mouse hovers over the element"
893
+ },
894
+ {
895
+ name: "effect",
896
+ type: "string",
897
+ optional: true,
898
+ default: "none",
899
+ enum: ["fade", "none"],
900
+ description: 'Transition effect before removal: "fade" or "none"'
901
+ }
902
+ ],
903
+ events: [
904
+ { name: "autodismiss:start", description: "Fired when the countdown timer starts" },
905
+ {
906
+ name: "autodismiss:dismissed",
907
+ description: "Fired before removal (cancelable via preventDefault)"
908
+ },
909
+ { name: "autodismiss:paused", description: "Fired when the timer is paused on hover" },
910
+ { name: "autodismiss:resumed", description: "Fired when the timer resumes on mouseleave" }
911
+ ],
912
+ source: [
913
+ "behavior AutoDismiss(delay, pauseOnHover, effect)",
914
+ " init",
915
+ " if delay is undefined set delay to 5000",
916
+ " if pauseOnHover is undefined set pauseOnHover to true",
917
+ ' if effect is undefined set effect to "none"',
918
+ " end",
919
+ " on load",
920
+ " trigger autodismiss:start",
921
+ " wait delay ms",
922
+ " trigger autodismiss:dismissed",
923
+ ' if effect is "fade"',
924
+ " transition opacity to 0 over 300ms",
925
+ " end",
926
+ " remove me",
927
+ " end",
928
+ "end"
929
+ ].join("\n")
930
+ };
931
+ }
932
+ });
933
+
934
+ // src/behaviors/autodismiss.ts
935
+ var autodismiss_exports = {};
936
+ __export(autodismiss_exports, {
937
+ autoDismissMetadata: () => autoDismissMetadata,
938
+ autoDismissSource: () => autoDismissSource,
939
+ default: () => autodismiss_default,
940
+ registerAutoDismiss: () => registerAutoDismiss
941
+ });
942
+ function installAutoDismiss(element, params) {
943
+ const delay = typeof params.delay === "number" ? params.delay : 5e3;
944
+ const pauseOnHover = params.pauseOnHover !== false;
945
+ const effect = params.effect === "fade" ? "fade" : "none";
946
+ let timerId = null;
947
+ let remaining = delay;
948
+ let startedAt = Date.now();
949
+ function dismiss() {
950
+ const event = new CustomEvent("autodismiss:dismissed", {
951
+ bubbles: true,
952
+ cancelable: true
953
+ });
954
+ element.dispatchEvent(event);
955
+ if (event.defaultPrevented) return;
956
+ if (effect === "fade") {
957
+ element.style.transition = "opacity 300ms";
958
+ element.style.opacity = "0";
959
+ setTimeout(() => element.remove(), 300);
960
+ } else {
961
+ element.remove();
962
+ }
963
+ }
964
+ function start() {
965
+ startedAt = Date.now();
966
+ timerId = setTimeout(dismiss, remaining);
967
+ }
968
+ element.dispatchEvent(new CustomEvent("autodismiss:start", { bubbles: true }));
969
+ start();
970
+ if (pauseOnHover) {
971
+ element.addEventListener("mouseenter", () => {
972
+ if (timerId != null) {
973
+ clearTimeout(timerId);
974
+ timerId = null;
975
+ remaining -= Date.now() - startedAt;
976
+ if (remaining < 0) remaining = 0;
977
+ element.dispatchEvent(new CustomEvent("autodismiss:paused", { bubbles: true }));
978
+ }
979
+ });
980
+ element.addEventListener("mouseleave", () => {
981
+ if (timerId == null && element.isConnected) {
982
+ element.dispatchEvent(new CustomEvent("autodismiss:resumed", { bubbles: true }));
983
+ start();
984
+ }
985
+ });
986
+ }
987
+ }
988
+ async function registerAutoDismiss(hyperfixi) {
989
+ const hf = hyperfixi || resolveRuntime();
990
+ if (!hf) {
991
+ throw new Error(
992
+ "LokaScript not found. Make sure @hyperfixi/core is loaded before registering behaviors."
993
+ );
994
+ }
995
+ const syntheticNode = {
996
+ type: "behavior",
997
+ name: "AutoDismiss",
998
+ parameters: ["delay", "pauseOnHover", "effect"],
999
+ eventHandlers: [],
1000
+ imperativeInstaller: installAutoDismiss
1001
+ };
1002
+ const ctx = hf.createContext ? hf.createContext() : { locals: /* @__PURE__ */ new Map(), globals: /* @__PURE__ */ new Map() };
1003
+ await hf.execute(syntheticNode, ctx);
1004
+ }
1005
+ var autoDismissSource, autoDismissMetadata, autodismiss_default;
1006
+ var init_autodismiss = __esm({
1007
+ "src/behaviors/autodismiss.ts"() {
1008
+ "use strict";
1009
+ init_autodismiss_schema();
1010
+ init_types();
1011
+ autoDismissSource = autoDismissSchema.source;
1012
+ autoDismissMetadata = autoDismissSchema;
1013
+ if (resolveRuntime()) {
1014
+ registerAutoDismiss().catch(console.error);
1015
+ }
1016
+ autodismiss_default = {
1017
+ source: autoDismissSchema.source,
1018
+ metadata: autoDismissSchema,
1019
+ register: registerAutoDismiss
1020
+ };
1021
+ }
1022
+ });
1023
+
1024
+ // src/schemas/clickoutside.schema.ts
1025
+ var clickOutsideSchema;
1026
+ var init_clickoutside_schema = __esm({
1027
+ "src/schemas/clickoutside.schema.ts"() {
1028
+ "use strict";
1029
+ clickOutsideSchema = {
1030
+ name: "ClickOutside",
1031
+ category: "ui",
1032
+ tier: "core",
1033
+ version: "1.0.0",
1034
+ description: "Fires an event when the user clicks outside the element",
1035
+ parameters: [
1036
+ {
1037
+ name: "active",
1038
+ type: "boolean",
1039
+ optional: true,
1040
+ default: true,
1041
+ description: "Whether the listener is active (can be toggled programmatically)"
1042
+ }
1043
+ ],
1044
+ events: [
1045
+ { name: "clickoutside", description: "Fired when a pointer press occurs outside the element" }
1046
+ ],
1047
+ requirements: ["Uses pointerdown instead of click to avoid timing issues with removed elements"],
1048
+ source: `
1049
+ behavior ClickOutside(active)
1050
+ init
1051
+ if active is undefined set active to true
1052
+ end
1053
+ on pointerdown from document
1054
+ if active and not me.contains(event.target)
1055
+ trigger clickoutside on me
1056
+ end
1057
+ end
1058
+ end`.trim()
1059
+ };
1060
+ }
1061
+ });
1062
+
1063
+ // src/behaviors/clickoutside.ts
1064
+ var clickoutside_exports = {};
1065
+ __export(clickoutside_exports, {
1066
+ clickOutsideMetadata: () => clickOutsideMetadata,
1067
+ clickOutsideSource: () => clickOutsideSource,
1068
+ default: () => clickoutside_default,
1069
+ registerClickOutside: () => registerClickOutside
1070
+ });
1071
+ function installClickOutside(element, params) {
1072
+ let active = params.active !== false;
1073
+ function onPointerDown(e) {
1074
+ if (!element.isConnected) {
1075
+ document.removeEventListener("pointerdown", onPointerDown);
1076
+ return;
1077
+ }
1078
+ if (active && !element.contains(e.target)) {
1079
+ element.dispatchEvent(new CustomEvent("clickoutside", { bubbles: true }));
1080
+ }
1081
+ }
1082
+ document.addEventListener("pointerdown", onPointerDown);
1083
+ element.addEventListener("clickoutside:activate", () => {
1084
+ active = true;
1085
+ });
1086
+ element.addEventListener("clickoutside:deactivate", () => {
1087
+ active = false;
1088
+ });
1089
+ }
1090
+ async function registerClickOutside(hyperfixi) {
1091
+ const hf = hyperfixi || resolveRuntime();
1092
+ if (!hf) {
1093
+ throw new Error(
1094
+ "LokaScript not found. Make sure @hyperfixi/core is loaded before registering behaviors."
1095
+ );
1096
+ }
1097
+ const syntheticNode = {
1098
+ type: "behavior",
1099
+ name: "ClickOutside",
1100
+ parameters: ["active"],
1101
+ eventHandlers: [],
1102
+ imperativeInstaller: installClickOutside
1103
+ };
1104
+ const ctx = hf.createContext ? hf.createContext() : { locals: /* @__PURE__ */ new Map(), globals: /* @__PURE__ */ new Map() };
1105
+ await hf.execute(syntheticNode, ctx);
1106
+ }
1107
+ var clickOutsideSource, clickOutsideMetadata, clickoutside_default;
1108
+ var init_clickoutside = __esm({
1109
+ "src/behaviors/clickoutside.ts"() {
1110
+ "use strict";
1111
+ init_clickoutside_schema();
1112
+ init_types();
1113
+ clickOutsideSource = clickOutsideSchema.source;
1114
+ clickOutsideMetadata = clickOutsideSchema;
1115
+ if (resolveRuntime()) {
1116
+ registerClickOutside().catch(console.error);
1117
+ }
1118
+ clickoutside_default = {
1119
+ source: clickOutsideSchema.source,
1120
+ metadata: clickOutsideSchema,
1121
+ register: registerClickOutside
1122
+ };
1123
+ }
1124
+ });
1125
+
1126
+ // src/schemas/focustrap.schema.ts
1127
+ var focusTrapSchema;
1128
+ var init_focustrap_schema = __esm({
1129
+ "src/schemas/focustrap.schema.ts"() {
1130
+ "use strict";
1131
+ focusTrapSchema = {
1132
+ name: "FocusTrap",
1133
+ category: "ui",
1134
+ tier: "core",
1135
+ version: "1.0.0",
1136
+ description: "Confines Tab navigation inside an element with ARIA support",
1137
+ parameters: [
1138
+ {
1139
+ name: "active",
1140
+ type: "boolean",
1141
+ optional: true,
1142
+ default: true,
1143
+ description: "Whether the trap is active on install"
1144
+ },
1145
+ {
1146
+ name: "initialFocus",
1147
+ type: "selector",
1148
+ optional: true,
1149
+ description: "Element to focus when the trap activates"
1150
+ },
1151
+ {
1152
+ name: "returnFocus",
1153
+ type: "boolean",
1154
+ optional: true,
1155
+ default: true,
1156
+ description: "Restore focus to the previously focused element on deactivation"
1157
+ }
1158
+ ],
1159
+ events: [
1160
+ { name: "focustrap:activated", description: "Fired when the trap is activated" },
1161
+ { name: "focustrap:deactivated", description: "Fired when the trap is deactivated" }
1162
+ ],
1163
+ requirements: [
1164
+ 'Sets aria-modal="true" on the element when active',
1165
+ "Listens for focustrap:activate and focustrap:deactivate custom events for programmatic control"
1166
+ ],
1167
+ source: `
1168
+ behavior FocusTrap(active, initialFocus, returnFocus)
1169
+ init
1170
+ if active is undefined set active to true
1171
+ if returnFocus is undefined set returnFocus to true
1172
+ end
1173
+ -- Imperative installer handles Tab key trapping and focus management
1174
+ end`.trim()
1175
+ };
1176
+ }
1177
+ });
1178
+
1179
+ // src/behaviors/focustrap.ts
1180
+ var focustrap_exports = {};
1181
+ __export(focustrap_exports, {
1182
+ default: () => focustrap_default,
1183
+ focusTrapMetadata: () => focusTrapMetadata,
1184
+ focusTrapSource: () => focusTrapSource,
1185
+ registerFocusTrap: () => registerFocusTrap
1186
+ });
1187
+ function resolveElement2(container, param) {
1188
+ if (!param) return null;
1189
+ if (param instanceof HTMLElement) return param;
1190
+ if (typeof param === "string") {
1191
+ return container.querySelector(param) || document.querySelector(param) || null;
1192
+ }
1193
+ return null;
1194
+ }
1195
+ function installFocusTrap(element, params) {
1196
+ const returnFocus = params.returnFocus !== false;
1197
+ let isActive = false;
1198
+ let previouslyFocused = null;
1199
+ function getFocusableElements() {
1200
+ return Array.from(element.querySelectorAll(FOCUSABLE_SELECTOR));
1201
+ }
1202
+ function onKeyDown(e) {
1203
+ if (!isActive || e.key !== "Tab") return;
1204
+ const focusable = getFocusableElements();
1205
+ if (focusable.length === 0) {
1206
+ e.preventDefault();
1207
+ return;
1208
+ }
1209
+ e.preventDefault();
1210
+ const currentIndex = focusable.indexOf(document.activeElement);
1211
+ if (e.shiftKey) {
1212
+ const prevIndex = currentIndex <= 0 ? focusable.length - 1 : currentIndex - 1;
1213
+ focusable[prevIndex].focus();
1214
+ } else {
1215
+ const nextIndex = currentIndex >= focusable.length - 1 ? 0 : currentIndex + 1;
1216
+ focusable[nextIndex].focus();
1217
+ }
1218
+ }
1219
+ function activate() {
1220
+ if (isActive) return;
1221
+ isActive = true;
1222
+ previouslyFocused = document.activeElement;
1223
+ element.setAttribute("aria-modal", "true");
1224
+ const initialEl = resolveElement2(element, params.initialFocus);
1225
+ if (initialEl) {
1226
+ initialEl.focus();
1227
+ } else {
1228
+ const focusable = getFocusableElements();
1229
+ if (focusable.length > 0) {
1230
+ focusable[0].focus();
1231
+ }
1232
+ }
1233
+ element.dispatchEvent(new CustomEvent("focustrap:activated", { bubbles: true }));
1234
+ }
1235
+ function deactivate() {
1236
+ if (!isActive) return;
1237
+ isActive = false;
1238
+ element.removeAttribute("aria-modal");
1239
+ if (returnFocus && previouslyFocused instanceof HTMLElement) {
1240
+ previouslyFocused.focus();
1241
+ }
1242
+ previouslyFocused = null;
1243
+ element.dispatchEvent(new CustomEvent("focustrap:deactivated", { bubbles: true }));
1244
+ }
1245
+ element.addEventListener("keydown", onKeyDown);
1246
+ element.addEventListener("focustrap:activate", () => activate());
1247
+ element.addEventListener("focustrap:deactivate", () => deactivate());
1248
+ if (params.active !== false) {
1249
+ activate();
1250
+ }
1251
+ }
1252
+ async function registerFocusTrap(hyperfixi) {
1253
+ const hf = hyperfixi || resolveRuntime();
1254
+ if (!hf) {
1255
+ throw new Error(
1256
+ "LokaScript not found. Make sure @hyperfixi/core is loaded before registering behaviors."
1257
+ );
1258
+ }
1259
+ const syntheticNode = {
1260
+ type: "behavior",
1261
+ name: "FocusTrap",
1262
+ parameters: ["active", "initialFocus", "returnFocus"],
1263
+ eventHandlers: [],
1264
+ imperativeInstaller: installFocusTrap
1265
+ };
1266
+ const ctx = hf.createContext ? hf.createContext() : { locals: /* @__PURE__ */ new Map(), globals: /* @__PURE__ */ new Map() };
1267
+ await hf.execute(syntheticNode, ctx);
1268
+ }
1269
+ var focusTrapSource, focusTrapMetadata, FOCUSABLE_SELECTOR, focustrap_default;
1270
+ var init_focustrap = __esm({
1271
+ "src/behaviors/focustrap.ts"() {
1272
+ "use strict";
1273
+ init_focustrap_schema();
1274
+ init_types();
1275
+ focusTrapSource = focusTrapSchema.source;
1276
+ focusTrapMetadata = focusTrapSchema;
1277
+ FOCUSABLE_SELECTOR = [
1278
+ "a[href]",
1279
+ "button:not(:disabled)",
1280
+ "input:not(:disabled)",
1281
+ "select:not(:disabled)",
1282
+ "textarea:not(:disabled)",
1283
+ '[tabindex]:not([tabindex="-1"])'
1284
+ ].join(", ");
1285
+ if (resolveRuntime()) {
1286
+ registerFocusTrap().catch(console.error);
1287
+ }
1288
+ focustrap_default = {
1289
+ source: focusTrapSchema.source,
1290
+ metadata: focusTrapSchema,
1291
+ register: registerFocusTrap
1292
+ };
1293
+ }
1294
+ });
1295
+
1296
+ // src/schemas/scrollreveal.schema.ts
1297
+ var scrollRevealSchema;
1298
+ var init_scrollreveal_schema = __esm({
1299
+ "src/schemas/scrollreveal.schema.ts"() {
1300
+ "use strict";
1301
+ scrollRevealSchema = {
1302
+ name: "ScrollReveal",
1303
+ category: "layout",
1304
+ tier: "common",
1305
+ version: "1.0.0",
1306
+ description: "Adds a class when the element enters the viewport via IntersectionObserver",
1307
+ parameters: [
1308
+ {
1309
+ name: "cls",
1310
+ type: "string",
1311
+ optional: true,
1312
+ default: "revealed",
1313
+ description: "CSS class added when element enters viewport"
1314
+ },
1315
+ {
1316
+ name: "threshold",
1317
+ type: "number",
1318
+ optional: true,
1319
+ default: 0.1,
1320
+ description: "Intersection ratio threshold (0-1) for triggering"
1321
+ },
1322
+ {
1323
+ name: "once",
1324
+ type: "boolean",
1325
+ optional: true,
1326
+ default: true,
1327
+ description: "If true, disconnect observer after first intersection"
1328
+ },
1329
+ {
1330
+ name: "rootMargin",
1331
+ type: "string",
1332
+ optional: true,
1333
+ default: "0px",
1334
+ description: "CSS margin around the viewport for triggering earlier or later"
1335
+ }
1336
+ ],
1337
+ events: [
1338
+ { name: "scrollreveal:enter", description: "Fired when the element enters the viewport" },
1339
+ { name: "scrollreveal:exit", description: "Fired when the element exits the viewport" }
1340
+ ],
1341
+ requirements: ["Uses IntersectionObserver API (supported in all modern browsers)"],
1342
+ source: `
1343
+ behavior ScrollReveal(cls, threshold, once, rootMargin)
1344
+ init
1345
+ if cls is undefined set cls to "revealed"
1346
+ if threshold is undefined set threshold to 0.1
1347
+ if once is undefined set once to true
1348
+ if rootMargin is undefined set rootMargin to "0px"
1349
+ end
1350
+ -- Imperative installer handles IntersectionObserver setup
1351
+ end`.trim()
1352
+ };
1353
+ }
1354
+ });
1355
+
1356
+ // src/behaviors/scrollreveal.ts
1357
+ var scrollreveal_exports = {};
1358
+ __export(scrollreveal_exports, {
1359
+ default: () => scrollreveal_default,
1360
+ registerScrollReveal: () => registerScrollReveal,
1361
+ scrollRevealMetadata: () => scrollRevealMetadata,
1362
+ scrollRevealSource: () => scrollRevealSource
1363
+ });
1364
+ function installScrollReveal(element, params) {
1365
+ const cls = typeof params.cls === "string" ? params.cls : "revealed";
1366
+ const threshold = typeof params.threshold === "number" ? params.threshold : 0.1;
1367
+ const once = params.once !== false;
1368
+ const rootMargin = typeof params.rootMargin === "string" ? params.rootMargin : "0px";
1369
+ const observer = new IntersectionObserver(
1370
+ (entries) => {
1371
+ for (const entry of entries) {
1372
+ if (entry.isIntersecting) {
1373
+ element.classList.add(cls);
1374
+ element.dispatchEvent(new CustomEvent("scrollreveal:enter", { bubbles: true }));
1375
+ if (once) {
1376
+ observer.disconnect();
1377
+ }
1378
+ } else if (!once) {
1379
+ element.classList.remove(cls);
1380
+ element.dispatchEvent(new CustomEvent("scrollreveal:exit", { bubbles: true }));
1381
+ }
1382
+ }
1383
+ },
1384
+ { threshold, rootMargin }
1385
+ );
1386
+ observer.observe(element);
1387
+ }
1388
+ async function registerScrollReveal(hyperfixi) {
1389
+ const hf = hyperfixi || resolveRuntime();
1390
+ if (!hf) {
1391
+ throw new Error(
1392
+ "LokaScript not found. Make sure @hyperfixi/core is loaded before registering behaviors."
1393
+ );
1394
+ }
1395
+ const syntheticNode = {
1396
+ type: "behavior",
1397
+ name: "ScrollReveal",
1398
+ parameters: ["cls", "threshold", "once", "rootMargin"],
1399
+ eventHandlers: [],
1400
+ imperativeInstaller: installScrollReveal
1401
+ };
1402
+ const ctx = hf.createContext ? hf.createContext() : { locals: /* @__PURE__ */ new Map(), globals: /* @__PURE__ */ new Map() };
1403
+ await hf.execute(syntheticNode, ctx);
1404
+ }
1405
+ var scrollRevealSource, scrollRevealMetadata, scrollreveal_default;
1406
+ var init_scrollreveal = __esm({
1407
+ "src/behaviors/scrollreveal.ts"() {
1408
+ "use strict";
1409
+ init_scrollreveal_schema();
1410
+ init_types();
1411
+ scrollRevealSource = scrollRevealSchema.source;
1412
+ scrollRevealMetadata = scrollRevealSchema;
1413
+ if (resolveRuntime()) {
1414
+ registerScrollReveal().catch(console.error);
1415
+ }
1416
+ scrollreveal_default = {
1417
+ source: scrollRevealSchema.source,
1418
+ metadata: scrollRevealSchema,
1419
+ register: registerScrollReveal
1420
+ };
1421
+ }
1422
+ });
1423
+
1424
+ // src/schemas/tabs.schema.ts
1425
+ var tabsSchema;
1426
+ var init_tabs_schema = __esm({
1427
+ "src/schemas/tabs.schema.ts"() {
1428
+ "use strict";
1429
+ tabsSchema = {
1430
+ name: "Tabs",
1431
+ category: "ui",
1432
+ tier: "core",
1433
+ version: "1.0.0",
1434
+ description: "WAI-ARIA compliant tabs with roving tabindex keyboard navigation. Auto-wires role, aria-selected, aria-controls, and aria-labelledby attributes.",
1435
+ parameters: [
1436
+ {
1437
+ name: "orientation",
1438
+ type: "string",
1439
+ optional: true,
1440
+ default: "horizontal",
1441
+ enum: ["horizontal", "vertical"],
1442
+ description: "Arrow key direction: horizontal (Left/Right) or vertical (Up/Down)"
1443
+ },
1444
+ {
1445
+ name: "activeTab",
1446
+ type: "number",
1447
+ optional: true,
1448
+ default: 0,
1449
+ description: "Initial active tab index (zero-based)"
1450
+ },
1451
+ {
1452
+ name: "wrap",
1453
+ type: "boolean",
1454
+ optional: true,
1455
+ default: true,
1456
+ description: "Wrap to first/last tab when navigating past the end"
1457
+ },
1458
+ {
1459
+ name: "activeClass",
1460
+ type: "string",
1461
+ optional: true,
1462
+ default: "active",
1463
+ description: "CSS class applied to the active tab and its panel"
1464
+ }
1465
+ ],
1466
+ events: [
1467
+ {
1468
+ name: "tabs:change",
1469
+ description: "Fired before tab selection changes (cancelable via preventDefault)"
1470
+ },
1471
+ { name: "tabs:changed", description: "Fired after tab selection has changed" }
1472
+ ],
1473
+ requirements: [
1474
+ 'Sets role="tablist" on the tab container',
1475
+ 'Sets role="tab" on tab buttons and role="tabpanel" on content panels',
1476
+ "Manages aria-selected, aria-controls, aria-labelledby, and tabindex",
1477
+ "Keyboard: Arrow keys navigate, Home/End jump to first/last, Tab exits tablist"
1478
+ ],
1479
+ source: [
1480
+ "behavior Tabs(orientation, activeTab, wrap, activeClass)",
1481
+ " init",
1482
+ ' if orientation is undefined set orientation to "horizontal"',
1483
+ " if activeTab is undefined set activeTab to 0",
1484
+ " if wrap is undefined set wrap to true",
1485
+ ' if activeClass is undefined set activeClass to "active"',
1486
+ " end",
1487
+ " -- Imperative installer handles ARIA wiring and keyboard navigation",
1488
+ "end"
1489
+ ].join("\n")
1490
+ };
1491
+ }
1492
+ });
1493
+
1494
+ // src/behaviors/tabs.ts
1495
+ var tabs_exports = {};
1496
+ __export(tabs_exports, {
1497
+ default: () => tabs_default,
1498
+ registerTabs: () => registerTabs,
1499
+ tabsMetadata: () => tabsMetadata,
1500
+ tabsSource: () => tabsSource
1501
+ });
1502
+ function ensureId(el, prefix) {
1503
+ if (!el.id) {
1504
+ el.id = `${prefix}-${++idCounter}`;
1505
+ }
1506
+ return el.id;
1507
+ }
1508
+ function installTabs(element, params) {
1509
+ const orientation = params.orientation === "vertical" ? "vertical" : "horizontal";
1510
+ const wrap = params.wrap !== false;
1511
+ const activeClass = params.activeClass || "active";
1512
+ const initialIndex = typeof params.activeTab === "number" ? params.activeTab : 0;
1513
+ const tabs = Array.from(element.querySelectorAll('[role="tab"]'));
1514
+ const panels = Array.from(element.querySelectorAll('[role="tabpanel"]'));
1515
+ if (tabs.length === 0 || panels.length === 0) return;
1516
+ const tablist = element.querySelector('[role="tablist"]') || tabs[0].parentElement;
1517
+ if (tablist && !tablist.getAttribute("role")) {
1518
+ tablist.setAttribute("role", "tablist");
1519
+ }
1520
+ if (tablist) {
1521
+ tablist.setAttribute("aria-orientation", orientation);
1522
+ }
1523
+ const count = Math.min(tabs.length, panels.length);
1524
+ for (let i = 0; i < count; i++) {
1525
+ const tabId = ensureId(tabs[i], "tab");
1526
+ const panelId = ensureId(panels[i], "tabpanel");
1527
+ tabs[i].setAttribute("aria-controls", panelId);
1528
+ panels[i].setAttribute("aria-labelledby", tabId);
1529
+ }
1530
+ let currentIndex = -1;
1531
+ function selectTab(index, previousIndex) {
1532
+ if (index === previousIndex || index < 0 || index >= count) return false;
1533
+ const detail = {
1534
+ tab: tabs[index],
1535
+ panel: panels[index],
1536
+ index,
1537
+ previousIndex
1538
+ };
1539
+ const changeEvent = new CustomEvent("tabs:change", {
1540
+ bubbles: true,
1541
+ cancelable: true,
1542
+ detail
1543
+ });
1544
+ element.dispatchEvent(changeEvent);
1545
+ if (changeEvent.defaultPrevented) return false;
1546
+ if (previousIndex >= 0 && previousIndex < count) {
1547
+ tabs[previousIndex].setAttribute("aria-selected", "false");
1548
+ tabs[previousIndex].setAttribute("tabindex", "-1");
1549
+ tabs[previousIndex].classList.remove(activeClass);
1550
+ panels[previousIndex].setAttribute("aria-hidden", "true");
1551
+ panels[previousIndex].classList.remove(activeClass);
1552
+ }
1553
+ tabs[index].setAttribute("aria-selected", "true");
1554
+ tabs[index].setAttribute("tabindex", "0");
1555
+ tabs[index].classList.add(activeClass);
1556
+ panels[index].setAttribute("aria-hidden", "false");
1557
+ panels[index].classList.add(activeClass);
1558
+ currentIndex = index;
1559
+ element.dispatchEvent(new CustomEvent("tabs:changed", { bubbles: true, detail }));
1560
+ return true;
1561
+ }
1562
+ for (let i = 0; i < count; i++) {
1563
+ tabs[i].setAttribute("aria-selected", "false");
1564
+ tabs[i].setAttribute("tabindex", "-1");
1565
+ tabs[i].classList.remove(activeClass);
1566
+ panels[i].setAttribute("aria-hidden", "true");
1567
+ panels[i].classList.remove(activeClass);
1568
+ }
1569
+ const clamped = Math.max(0, Math.min(initialIndex, count - 1));
1570
+ tabs[clamped].setAttribute("aria-selected", "true");
1571
+ tabs[clamped].setAttribute("tabindex", "0");
1572
+ tabs[clamped].classList.add(activeClass);
1573
+ panels[clamped].setAttribute("aria-hidden", "false");
1574
+ panels[clamped].classList.add(activeClass);
1575
+ currentIndex = clamped;
1576
+ for (let i = 0; i < count; i++) {
1577
+ tabs[i].addEventListener("click", () => {
1578
+ selectTab(i, currentIndex);
1579
+ tabs[i].focus();
1580
+ });
1581
+ }
1582
+ const keyTarget = tablist || element;
1583
+ keyTarget.addEventListener("keydown", (e) => {
1584
+ const isHorizontal = orientation === "horizontal";
1585
+ const nextKey = isHorizontal ? "ArrowRight" : "ArrowDown";
1586
+ const prevKey = isHorizontal ? "ArrowLeft" : "ArrowUp";
1587
+ let nextIndex = null;
1588
+ if (e.key === nextKey) {
1589
+ nextIndex = currentIndex + 1;
1590
+ if (nextIndex >= count) nextIndex = wrap ? 0 : null;
1591
+ } else if (e.key === prevKey) {
1592
+ nextIndex = currentIndex - 1;
1593
+ if (nextIndex < 0) nextIndex = wrap ? count - 1 : null;
1594
+ } else if (e.key === "Home") {
1595
+ nextIndex = 0;
1596
+ } else if (e.key === "End") {
1597
+ nextIndex = count - 1;
1598
+ }
1599
+ if (nextIndex !== null) {
1600
+ e.preventDefault();
1601
+ if (selectTab(nextIndex, currentIndex)) {
1602
+ tabs[nextIndex].focus();
1603
+ }
1604
+ }
1605
+ });
1606
+ element.addEventListener("tabs:select", ((e) => {
1607
+ const index = e.detail?.index;
1608
+ if (typeof index === "number") {
1609
+ selectTab(index, currentIndex);
1610
+ }
1611
+ }));
1612
+ }
1613
+ async function registerTabs(hyperfixi) {
1614
+ const hf = hyperfixi || resolveRuntime();
1615
+ if (!hf) {
1616
+ throw new Error(
1617
+ "LokaScript not found. Make sure @hyperfixi/core is loaded before registering behaviors."
1618
+ );
1619
+ }
1620
+ const syntheticNode = {
1621
+ type: "behavior",
1622
+ name: "Tabs",
1623
+ parameters: ["orientation", "activeTab", "wrap", "activeClass"],
1624
+ eventHandlers: [],
1625
+ imperativeInstaller: installTabs
1626
+ };
1627
+ const ctx = hf.createContext ? hf.createContext() : { locals: /* @__PURE__ */ new Map(), globals: /* @__PURE__ */ new Map() };
1628
+ await hf.execute(syntheticNode, ctx);
1629
+ }
1630
+ var tabsSource, tabsMetadata, idCounter, tabs_default;
1631
+ var init_tabs = __esm({
1632
+ "src/behaviors/tabs.ts"() {
1633
+ "use strict";
1634
+ init_tabs_schema();
1635
+ init_types();
1636
+ tabsSource = tabsSchema.source;
1637
+ tabsMetadata = tabsSchema;
1638
+ idCounter = 0;
1639
+ if (resolveRuntime()) {
1640
+ registerTabs().catch(console.error);
1641
+ }
1642
+ tabs_default = {
1643
+ source: tabsSchema.source,
1644
+ metadata: tabsSchema,
1645
+ register: registerTabs
1646
+ };
1647
+ }
1648
+ });
1649
+
547
1650
  // src/index.ts
548
1651
  var index_exports = {};
549
1652
  __export(index_exports, {
550
1653
  ALL_BEHAVIOR_NAMES: () => ALL_BEHAVIOR_NAMES,
1654
+ AutoDismiss: () => autodismiss_default,
551
1655
  BEHAVIORS_BY_CATEGORY: () => BEHAVIORS_BY_CATEGORY,
552
1656
  BEHAVIORS_BY_TIER: () => BEHAVIORS_BY_TIER,
553
1657
  BEHAVIOR_CATEGORIES: () => BEHAVIOR_CATEGORIES,
554
1658
  BEHAVIOR_TIERS: () => BEHAVIOR_TIERS,
1659
+ ClickOutside: () => clickoutside_default,
1660
+ Clipboard: () => clipboard_default,
555
1661
  Draggable: () => draggable_default,
1662
+ FocusTrap: () => focustrap_default,
556
1663
  Removable: () => removable_default,
557
1664
  Resizable: () => resizable_default,
1665
+ ScrollReveal: () => scrollreveal_default,
558
1666
  Sortable: () => sortable_default,
1667
+ Tabs: () => tabs_default,
559
1668
  Toggleable: () => toggleable_default,
1669
+ autoDismissMetadata: () => autoDismissMetadata,
1670
+ autoDismissSource: () => autoDismissSource,
1671
+ clickOutsideMetadata: () => clickOutsideMetadata,
1672
+ clickOutsideSource: () => clickOutsideSource,
1673
+ clipboardMetadata: () => clipboardMetadata,
1674
+ clipboardSource: () => clipboardSource,
560
1675
  draggableMetadata: () => draggableMetadata,
561
1676
  draggableSource: () => draggableSource,
1677
+ focusTrapMetadata: () => focusTrapMetadata,
1678
+ focusTrapSource: () => focusTrapSource,
562
1679
  getAllSchemas: () => getAllSchemas,
563
1680
  getAllSchemasRecord: () => getAllSchemasRecord,
564
1681
  getAvailableBehaviors: () => getAvailableBehaviors,
@@ -576,21 +1693,31 @@ __export(index_exports, {
576
1693
  ready: () => ready,
577
1694
  registerAll: () => registerAll,
578
1695
  registerAllWithRuntime: () => registerAllWithRuntime,
1696
+ registerAutoDismiss: () => registerAutoDismiss,
579
1697
  registerBehavior: () => registerBehavior,
1698
+ registerClickOutside: () => registerClickOutside,
1699
+ registerClipboard: () => registerClipboard,
580
1700
  registerDraggable: () => registerDraggable,
1701
+ registerFocusTrap: () => registerFocusTrap,
581
1702
  registerLoader: () => registerLoader,
582
1703
  registerRemovable: () => registerRemovable,
583
1704
  registerResizable: () => registerResizable,
584
1705
  registerSchema: () => registerSchema,
1706
+ registerScrollReveal: () => registerScrollReveal,
585
1707
  registerSortable: () => registerSortable,
1708
+ registerTabs: () => registerTabs,
586
1709
  registerToggleable: () => registerToggleable,
587
1710
  registerWithRuntime: () => registerWithRuntime,
588
1711
  removableMetadata: () => removableMetadata,
589
1712
  removableSource: () => removableSource,
590
1713
  resizableMetadata: () => resizableMetadata,
591
1714
  resizableSource: () => resizableSource,
1715
+ scrollRevealMetadata: () => scrollRevealMetadata,
1716
+ scrollRevealSource: () => scrollRevealSource,
592
1717
  sortableMetadata: () => sortableMetadata,
593
1718
  sortableSource: () => sortableSource,
1719
+ tabsMetadata: () => tabsMetadata,
1720
+ tabsSource: () => tabsSource,
594
1721
  toggleableMetadata: () => toggleableMetadata,
595
1722
  toggleableSource: () => toggleableSource,
596
1723
  tryGetBehavior: () => tryGetBehavior,
@@ -602,6 +1729,12 @@ init_removable();
602
1729
  init_toggleable();
603
1730
  init_sortable();
604
1731
  init_resizable();
1732
+ init_clipboard();
1733
+ init_autodismiss();
1734
+ init_clickoutside();
1735
+ init_focustrap();
1736
+ init_scrollreveal();
1737
+ init_tabs();
605
1738
 
606
1739
  // src/registry.ts
607
1740
  var behaviors = /* @__PURE__ */ new Map();
@@ -755,16 +1888,34 @@ init_sortable_schema();
755
1888
  init_resizable_schema();
756
1889
  init_removable_schema();
757
1890
  init_toggleable_schema();
1891
+ init_clipboard_schema();
1892
+ init_autodismiss_schema();
1893
+ init_clickoutside_schema();
1894
+ init_focustrap_schema();
1895
+ init_scrollreveal_schema();
1896
+ init_tabs_schema();
758
1897
  registerSchema(draggableSchema);
759
1898
  registerSchema(sortableSchema);
760
1899
  registerSchema(resizableSchema);
761
1900
  registerSchema(removableSchema);
762
1901
  registerSchema(toggleableSchema);
1902
+ registerSchema(clipboardSchema);
1903
+ registerSchema(autoDismissSchema);
1904
+ registerSchema(clickOutsideSchema);
1905
+ registerSchema(focusTrapSchema);
1906
+ registerSchema(scrollRevealSchema);
1907
+ registerSchema(tabsSchema);
763
1908
  registerLoader("Draggable", () => Promise.resolve().then(() => (init_draggable(), draggable_exports)));
764
1909
  registerLoader("Sortable", () => Promise.resolve().then(() => (init_sortable(), sortable_exports)));
765
1910
  registerLoader("Resizable", () => Promise.resolve().then(() => (init_resizable(), resizable_exports)));
766
1911
  registerLoader("Removable", () => Promise.resolve().then(() => (init_removable(), removable_exports)));
767
1912
  registerLoader("Toggleable", () => Promise.resolve().then(() => (init_toggleable(), toggleable_exports)));
1913
+ registerLoader("Clipboard", () => Promise.resolve().then(() => (init_clipboard(), clipboard_exports)));
1914
+ registerLoader("AutoDismiss", () => Promise.resolve().then(() => (init_autodismiss(), autodismiss_exports)));
1915
+ registerLoader("ClickOutside", () => Promise.resolve().then(() => (init_clickoutside(), clickoutside_exports)));
1916
+ registerLoader("FocusTrap", () => Promise.resolve().then(() => (init_focustrap(), focustrap_exports)));
1917
+ registerLoader("ScrollReveal", () => Promise.resolve().then(() => (init_scrollreveal(), scrollreveal_exports)));
1918
+ registerLoader("Tabs", () => Promise.resolve().then(() => (init_tabs(), tabs_exports)));
768
1919
 
769
1920
  // src/generated/metadata.ts
770
1921
  var ALL_BEHAVIOR_NAMES = [
@@ -772,13 +1923,24 @@ var ALL_BEHAVIOR_NAMES = [
772
1923
  "Sortable",
773
1924
  "Resizable",
774
1925
  "Removable",
775
- "Toggleable"
1926
+ "Toggleable",
1927
+ "Clipboard",
1928
+ "AutoDismiss",
1929
+ "ClickOutside",
1930
+ "FocusTrap",
1931
+ "ScrollReveal",
1932
+ "Tabs"
776
1933
  ];
777
1934
  var BEHAVIORS_BY_CATEGORY = {
778
1935
  "ui": [
779
1936
  "Draggable",
780
1937
  "Sortable",
781
- "Resizable"
1938
+ "Resizable",
1939
+ "Clipboard",
1940
+ "AutoDismiss",
1941
+ "ClickOutside",
1942
+ "FocusTrap",
1943
+ "Tabs"
782
1944
  ],
783
1945
  "data": [
784
1946
  "Removable"
@@ -787,16 +1949,24 @@ var BEHAVIORS_BY_CATEGORY = {
787
1949
  "form": [
788
1950
  "Toggleable"
789
1951
  ],
790
- "layout": []
1952
+ "layout": [
1953
+ "ScrollReveal"
1954
+ ]
791
1955
  };
792
1956
  var BEHAVIORS_BY_TIER = {
793
1957
  "core": [
794
1958
  "Draggable",
795
- "Toggleable"
1959
+ "Toggleable",
1960
+ "Clipboard",
1961
+ "AutoDismiss",
1962
+ "ClickOutside",
1963
+ "FocusTrap",
1964
+ "Tabs"
796
1965
  ],
797
1966
  "common": [
798
1967
  "Sortable",
799
- "Removable"
1968
+ "Removable",
1969
+ "ScrollReveal"
800
1970
  ],
801
1971
  "optional": [
802
1972
  "Resizable"
@@ -807,14 +1977,26 @@ var BEHAVIOR_CATEGORIES = {
807
1977
  "Sortable": "ui",
808
1978
  "Resizable": "ui",
809
1979
  "Removable": "data",
810
- "Toggleable": "form"
1980
+ "Toggleable": "form",
1981
+ "Clipboard": "ui",
1982
+ "AutoDismiss": "ui",
1983
+ "ClickOutside": "ui",
1984
+ "FocusTrap": "ui",
1985
+ "ScrollReveal": "layout",
1986
+ "Tabs": "ui"
811
1987
  };
812
1988
  var BEHAVIOR_TIERS = {
813
1989
  "Draggable": "core",
814
1990
  "Sortable": "common",
815
1991
  "Resizable": "optional",
816
1992
  "Removable": "common",
817
- "Toggleable": "core"
1993
+ "Toggleable": "core",
1994
+ "Clipboard": "core",
1995
+ "AutoDismiss": "core",
1996
+ "ClickOutside": "core",
1997
+ "FocusTrap": "core",
1998
+ "ScrollReveal": "common",
1999
+ "Tabs": "core"
818
2000
  };
819
2001
 
820
2002
  // src/index.ts
@@ -823,31 +2005,45 @@ init_removable();
823
2005
  init_toggleable();
824
2006
  init_sortable();
825
2007
  init_resizable();
2008
+ init_clipboard();
2009
+ init_autodismiss();
2010
+ init_clickoutside();
2011
+ init_focustrap();
2012
+ init_scrollreveal();
2013
+ init_tabs();
2014
+ init_types();
826
2015
  async function registerAll(hyperfixi) {
827
2016
  await Promise.all([
828
2017
  registerDraggable(hyperfixi),
829
2018
  registerRemovable(hyperfixi),
830
2019
  registerToggleable(hyperfixi),
831
2020
  registerSortable(hyperfixi),
832
- registerResizable(hyperfixi)
2021
+ registerResizable(hyperfixi),
2022
+ registerClipboard(hyperfixi),
2023
+ registerAutoDismiss(hyperfixi),
2024
+ registerClickOutside(hyperfixi),
2025
+ registerFocusTrap(hyperfixi),
2026
+ registerScrollReveal(hyperfixi),
2027
+ registerTabs(hyperfixi)
833
2028
  ]);
834
2029
  }
835
2030
  var ready = null;
836
- if (typeof window !== "undefined" && window.lokascript) {
2031
+ var _runtime = resolveRuntime();
2032
+ if (_runtime) {
837
2033
  const lsWin = window;
838
- ready = registerAll();
839
- lsWin.__lokascript_behaviors_ready = ready;
2034
+ ready = registerAll(_runtime);
2035
+ lsWin.__hyperfixi_behaviors_ready = ready;
840
2036
  ready.then(() => {
841
- const hyperfixi = lsWin.lokascript;
842
- const savedPromise = lsWin.__lokascript_behaviors_ready;
843
- delete lsWin.__lokascript_behaviors_ready;
844
- if (hyperfixi.attributeProcessor?.scanAndProcessAll) {
845
- hyperfixi.attributeProcessor.scanAndProcessAll().finally(() => {
846
- lsWin.__lokascript_behaviors_ready = savedPromise;
2037
+ const hf = _runtime;
2038
+ const savedPromise = lsWin.__hyperfixi_behaviors_ready;
2039
+ delete lsWin.__hyperfixi_behaviors_ready;
2040
+ if (hf.attributeProcessor?.scanAndProcessAll) {
2041
+ hf.attributeProcessor.scanAndProcessAll().finally(() => {
2042
+ lsWin.__hyperfixi_behaviors_ready = savedPromise;
847
2043
  });
848
- } else if (hyperfixi.processNode) {
849
- hyperfixi.processNode(document);
850
- lsWin.__lokascript_behaviors_ready = savedPromise;
2044
+ } else if (hf.processNode) {
2045
+ hf.processNode(document);
2046
+ lsWin.__hyperfixi_behaviors_ready = savedPromise;
851
2047
  }
852
2048
  }).catch((err) => {
853
2049
  console.error("[behaviors] Auto-registration failed:", err);
@@ -856,17 +2052,31 @@ if (typeof window !== "undefined" && window.lokascript) {
856
2052
  // Annotate the CommonJS export names for ESM import in node:
857
2053
  0 && (module.exports = {
858
2054
  ALL_BEHAVIOR_NAMES,
2055
+ AutoDismiss,
859
2056
  BEHAVIORS_BY_CATEGORY,
860
2057
  BEHAVIORS_BY_TIER,
861
2058
  BEHAVIOR_CATEGORIES,
862
2059
  BEHAVIOR_TIERS,
2060
+ ClickOutside,
2061
+ Clipboard,
863
2062
  Draggable,
2063
+ FocusTrap,
864
2064
  Removable,
865
2065
  Resizable,
2066
+ ScrollReveal,
866
2067
  Sortable,
2068
+ Tabs,
867
2069
  Toggleable,
2070
+ autoDismissMetadata,
2071
+ autoDismissSource,
2072
+ clickOutsideMetadata,
2073
+ clickOutsideSource,
2074
+ clipboardMetadata,
2075
+ clipboardSource,
868
2076
  draggableMetadata,
869
2077
  draggableSource,
2078
+ focusTrapMetadata,
2079
+ focusTrapSource,
870
2080
  getAllSchemas,
871
2081
  getAllSchemasRecord,
872
2082
  getAvailableBehaviors,
@@ -884,21 +2094,31 @@ if (typeof window !== "undefined" && window.lokascript) {
884
2094
  ready,
885
2095
  registerAll,
886
2096
  registerAllWithRuntime,
2097
+ registerAutoDismiss,
887
2098
  registerBehavior,
2099
+ registerClickOutside,
2100
+ registerClipboard,
888
2101
  registerDraggable,
2102
+ registerFocusTrap,
889
2103
  registerLoader,
890
2104
  registerRemovable,
891
2105
  registerResizable,
892
2106
  registerSchema,
2107
+ registerScrollReveal,
893
2108
  registerSortable,
2109
+ registerTabs,
894
2110
  registerToggleable,
895
2111
  registerWithRuntime,
896
2112
  removableMetadata,
897
2113
  removableSource,
898
2114
  resizableMetadata,
899
2115
  resizableSource,
2116
+ scrollRevealMetadata,
2117
+ scrollRevealSource,
900
2118
  sortableMetadata,
901
2119
  sortableSource,
2120
+ tabsMetadata,
2121
+ tabsSource,
902
2122
  toggleableMetadata,
903
2123
  toggleableSource,
904
2124
  tryGetBehavior,