@hyperfixi/behaviors 2.0.0 → 2.1.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
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../src/behaviors/clipboard.ts"],"sourcesContent":["/**\n * Clipboard Behavior — Imperative Implementation\n *\n * Copies text to clipboard on click with visual feedback.\n * Uses navigator.clipboard.writeText() with execCommand fallback.\n */\n\nimport { clipboardSchema } from '../schemas/clipboard.schema';\nimport type { LokaScriptInstance } from '../schemas/types';\nimport { resolveRuntime } from '../schemas/types';\n\n// Re-export schema-derived values\nexport const clipboardSource = clipboardSchema.source;\nexport const clipboardMetadata = clipboardSchema;\n\n/**\n * Copy text to clipboard using the modern Clipboard API,\n * falling back to execCommand for older browsers.\n */\nasync function copyToClipboard(text: string): Promise<void> {\n if (navigator.clipboard?.writeText) {\n await navigator.clipboard.writeText(text);\n return;\n }\n\n // Fallback: temporary textarea + execCommand\n const textarea = document.createElement('textarea');\n textarea.value = text;\n textarea.style.position = 'fixed';\n textarea.style.opacity = '0';\n document.body.appendChild(textarea);\n textarea.select();\n try {\n document.execCommand('copy');\n } finally {\n document.body.removeChild(textarea);\n }\n}\n\n/**\n * Resolve a selector parameter to an HTMLElement.\n */\nfunction resolveElement(element: HTMLElement, param: unknown): HTMLElement | null {\n if (!param || param === 'me') return element;\n if (param instanceof HTMLElement) return param;\n if (typeof param === 'string') {\n return (\n (element.querySelector(param) as HTMLElement) ||\n (document.querySelector(param) as HTMLElement) ||\n null\n );\n }\n return null;\n}\n\n/**\n * Imperative installer for Clipboard behavior.\n */\nfunction installClipboard(element: HTMLElement, params: Record<string, any>): void {\n const feedbackDuration =\n typeof params.feedbackDuration === 'number' ? params.feedbackDuration : 2000;\n\n element.addEventListener('click', async () => {\n // Determine text to copy\n let copyText: string;\n if (params.text != null) {\n copyText = String(params.text);\n } else {\n const sourceEl = resolveElement(element, params.source) || element;\n copyText = (sourceEl as HTMLInputElement).value ?? sourceEl.textContent ?? '';\n }\n\n try {\n await copyToClipboard(copyText);\n\n // Show feedback\n const feedbackEl = resolveElement(element, params.feedback) || element;\n feedbackEl.classList.add('copied');\n setTimeout(() => feedbackEl.classList.remove('copied'), feedbackDuration);\n\n element.dispatchEvent(\n new CustomEvent('clipboard:copied', {\n bubbles: true,\n detail: { text: copyText },\n })\n );\n } catch (error) {\n element.dispatchEvent(\n new CustomEvent('clipboard:error', {\n bubbles: true,\n detail: { error },\n })\n );\n }\n });\n}\n\n/**\n * Register the Clipboard behavior with LokaScript.\n */\nexport async function registerClipboard(hyperfixi?: LokaScriptInstance): Promise<void> {\n const hf = hyperfixi || resolveRuntime();\n\n if (!hf) {\n throw new Error(\n 'LokaScript not found. Make sure @hyperfixi/core is loaded before registering behaviors.'\n );\n }\n\n const syntheticNode = {\n type: 'behavior',\n name: 'Clipboard',\n parameters: ['text', 'source', 'feedback', 'feedbackDuration'],\n eventHandlers: [],\n imperativeInstaller: installClipboard,\n };\n const ctx = hf.createContext ? hf.createContext() : { locals: new Map(), globals: new Map() };\n await hf.execute(syntheticNode, ctx);\n}\n\n// Auto-register when loaded as a script tag\nif (resolveRuntime()) {\n registerClipboard().catch(console.error);\n}\n\nexport default {\n source: clipboardSchema.source,\n metadata: clipboardSchema,\n register: registerClipboard,\n};\n"],"mappings":";;;;;;;;AAYO,IAAM,kBAAkB,gBAAgB;AACxC,IAAM,oBAAoB;AAMjC,eAAe,gBAAgB,MAA6B;AAC1D,MAAI,UAAU,WAAW,WAAW;AAClC,UAAM,UAAU,UAAU,UAAU,IAAI;AACxC;AAAA,EACF;AAGA,QAAM,WAAW,SAAS,cAAc,UAAU;AAClD,WAAS,QAAQ;AACjB,WAAS,MAAM,WAAW;AAC1B,WAAS,MAAM,UAAU;AACzB,WAAS,KAAK,YAAY,QAAQ;AAClC,WAAS,OAAO;AAChB,MAAI;AACF,aAAS,YAAY,MAAM;AAAA,EAC7B,UAAE;AACA,aAAS,KAAK,YAAY,QAAQ;AAAA,EACpC;AACF;AAKA,SAAS,eAAe,SAAsB,OAAoC;AAChF,MAAI,CAAC,SAAS,UAAU,KAAM,QAAO;AACrC,MAAI,iBAAiB,YAAa,QAAO;AACzC,MAAI,OAAO,UAAU,UAAU;AAC7B,WACG,QAAQ,cAAc,KAAK,KAC3B,SAAS,cAAc,KAAK,KAC7B;AAAA,EAEJ;AACA,SAAO;AACT;AAKA,SAAS,iBAAiB,SAAsB,QAAmC;AACjF,QAAM,mBACJ,OAAO,OAAO,qBAAqB,WAAW,OAAO,mBAAmB;AAE1E,UAAQ,iBAAiB,SAAS,YAAY;AAE5C,QAAI;AACJ,QAAI,OAAO,QAAQ,MAAM;AACvB,iBAAW,OAAO,OAAO,IAAI;AAAA,IAC/B,OAAO;AACL,YAAM,WAAW,eAAe,SAAS,OAAO,MAAM,KAAK;AAC3D,iBAAY,SAA8B,SAAS,SAAS,eAAe;AAAA,IAC7E;AAEA,QAAI;AACF,YAAM,gBAAgB,QAAQ;AAG9B,YAAM,aAAa,eAAe,SAAS,OAAO,QAAQ,KAAK;AAC/D,iBAAW,UAAU,IAAI,QAAQ;AACjC,iBAAW,MAAM,WAAW,UAAU,OAAO,QAAQ,GAAG,gBAAgB;AAExE,cAAQ;AAAA,QACN,IAAI,YAAY,oBAAoB;AAAA,UAClC,SAAS;AAAA,UACT,QAAQ,EAAE,MAAM,SAAS;AAAA,QAC3B,CAAC;AAAA,MACH;AAAA,IACF,SAAS,OAAO;AACd,cAAQ;AAAA,QACN,IAAI,YAAY,mBAAmB;AAAA,UACjC,SAAS;AAAA,UACT,QAAQ,EAAE,MAAM;AAAA,QAClB,CAAC;AAAA,MACH;AAAA,IACF;AAAA,EACF,CAAC;AACH;AAKA,eAAsB,kBAAkB,WAA+C;AACrF,QAAM,KAAK,aAAa,eAAe;AAEvC,MAAI,CAAC,IAAI;AACP,UAAM,IAAI;AAAA,MACR;AAAA,IACF;AAAA,EACF;AAEA,QAAM,gBAAgB;AAAA,IACpB,MAAM;AAAA,IACN,MAAM;AAAA,IACN,YAAY,CAAC,QAAQ,UAAU,YAAY,kBAAkB;AAAA,IAC7D,eAAe,CAAC;AAAA,IAChB,qBAAqB;AAAA,EACvB;AACA,QAAM,MAAM,GAAG,gBAAgB,GAAG,cAAc,IAAI,EAAE,QAAQ,oBAAI,IAAI,GAAG,SAAS,oBAAI,IAAI,EAAE;AAC5F,QAAM,GAAG,QAAQ,eAAe,GAAG;AACrC;AAGA,IAAI,eAAe,GAAG;AACpB,oBAAkB,EAAE,MAAM,QAAQ,KAAK;AACzC;AAEA,IAAO,oBAAQ;AAAA,EACb,QAAQ,gBAAgB;AAAA,EACxB,UAAU;AAAA,EACV,UAAU;AACZ;","names":[]}
@@ -0,0 +1,37 @@
1
+ // src/schemas/clickoutside.schema.ts
2
+ var clickOutsideSchema = {
3
+ name: "ClickOutside",
4
+ category: "ui",
5
+ tier: "core",
6
+ version: "1.0.0",
7
+ description: "Fires an event when the user clicks outside the element",
8
+ parameters: [
9
+ {
10
+ name: "active",
11
+ type: "boolean",
12
+ optional: true,
13
+ default: true,
14
+ description: "Whether the listener is active (can be toggled programmatically)"
15
+ }
16
+ ],
17
+ events: [
18
+ { name: "clickoutside", description: "Fired when a pointer press occurs outside the element" }
19
+ ],
20
+ requirements: ["Uses pointerdown instead of click to avoid timing issues with removed elements"],
21
+ source: `
22
+ behavior ClickOutside(active)
23
+ init
24
+ if active is undefined set active to true
25
+ end
26
+ on pointerdown from document
27
+ if active and not me.contains(event.target)
28
+ trigger clickoutside on me
29
+ end
30
+ end
31
+ end`.trim()
32
+ };
33
+
34
+ export {
35
+ clickOutsideSchema
36
+ };
37
+ //# sourceMappingURL=chunk-64DIQGQI.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../src/schemas/clickoutside.schema.ts"],"sourcesContent":["import type { BehaviorSchema } from './types';\n\n/**\n * ClickOutside Behavior Schema\n *\n * Fires an event when the user clicks outside the element.\n * Uses pointerdown instead of click to avoid timing issues.\n */\nexport const clickOutsideSchema: BehaviorSchema = {\n name: 'ClickOutside',\n category: 'ui',\n tier: 'core',\n version: '1.0.0',\n description: 'Fires an event when the user clicks outside the element',\n parameters: [\n {\n name: 'active',\n type: 'boolean',\n optional: true,\n default: true,\n description: 'Whether the listener is active (can be toggled programmatically)',\n },\n ],\n events: [\n { name: 'clickoutside', description: 'Fired when a pointer press occurs outside the element' },\n ],\n requirements: ['Uses pointerdown instead of click to avoid timing issues with removed elements'],\n source: `\nbehavior ClickOutside(active)\n init\n if active is undefined set active to true\n end\n on pointerdown from document\n if active and not me.contains(event.target)\n trigger clickoutside on me\n end\n end\nend`.trim(),\n};\n"],"mappings":";AAQO,IAAM,qBAAqC;AAAA,EAChD,MAAM;AAAA,EACN,UAAU;AAAA,EACV,MAAM;AAAA,EACN,SAAS;AAAA,EACT,aAAa;AAAA,EACb,YAAY;AAAA,IACV;AAAA,MACE,MAAM;AAAA,MACN,MAAM;AAAA,MACN,UAAU;AAAA,MACV,SAAS;AAAA,MACT,aAAa;AAAA,IACf;AAAA,EACF;AAAA,EACA,QAAQ;AAAA,IACN,EAAE,MAAM,gBAAgB,aAAa,wDAAwD;AAAA,EAC/F;AAAA,EACA,cAAc,CAAC,gFAAgF;AAAA,EAC/F,QAAQ;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,KAUL,KAAK;AACV;","names":[]}
@@ -0,0 +1,11 @@
1
+ // src/schemas/types.ts
2
+ function resolveRuntime() {
3
+ if (typeof window === "undefined") return null;
4
+ const win = window;
5
+ return win.lokascript || win.hyperfixi || null;
6
+ }
7
+
8
+ export {
9
+ resolveRuntime
10
+ };
11
+ //# sourceMappingURL=chunk-6TJXDCAQ.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../src/schemas/types.ts"],"sourcesContent":["/**\n * Behavior Schema Types\n *\n * Defines the structure for behavior metadata used for:\n * - Code generation (TypeScript types, documentation)\n * - Runtime categorization and lazy loading\n * - Tooling and IDE integration\n */\n\n/**\n * Behavior categories for organization.\n * - ui: Visual interaction behaviors (drag, resize, sort)\n * - data: Data manipulation behaviors (remove, transform)\n * - animation: Animation and transition behaviors\n * - form: Form-related behaviors (validation, toggle states)\n * - layout: Layout behaviors (sticky, scrollspy)\n */\nexport type BehaviorCategory = 'ui' | 'data' | 'animation' | 'form' | 'layout';\n\n/**\n * Loading tiers for lazy loading optimization.\n * - core: Always loaded (essential behaviors)\n * - common: High usage (loaded for typical apps)\n * - optional: Low usage (loaded on demand)\n */\nexport type BehaviorTier = 'core' | 'common' | 'optional';\n\n/**\n * Schema for a behavior parameter.\n */\nexport interface ParameterSchema {\n name: string;\n type: 'string' | 'number' | 'boolean' | 'selector' | 'element';\n optional?: boolean;\n default?: string | number | boolean;\n /** Allowed values for constrained parameters */\n enum?: string[];\n description: string;\n}\n\n/**\n * Schema for a behavior event.\n */\nexport interface EventSchema {\n name: string;\n description: string;\n}\n\n/**\n * Complete schema for a behavior.\n * This is the source of truth for all behavior metadata.\n */\nexport interface BehaviorSchema {\n /** Behavior name (PascalCase) */\n name: string;\n /** Category for organization */\n category: BehaviorCategory;\n /** Loading tier for lazy loading */\n tier: BehaviorTier;\n /** Semantic version */\n version: string;\n /** Human-readable description */\n description: string;\n /** Parameter definitions */\n parameters: ParameterSchema[];\n /** Event definitions */\n events: EventSchema[];\n /** The hyperscript behavior source code */\n source: string;\n /** Optional requirements or notes */\n requirements?: string[];\n}\n\n/**\n * Runtime behavior module interface.\n * This is what gets registered with the hyperfixi runtime.\n */\nexport interface BehaviorModule {\n source: string;\n metadata: BehaviorSchema;\n register: (hyperfixi?: LokaScriptInstance) => Promise<void>;\n}\n\n/**\n * Minimal LokaScript instance interface for behavior registration.\n */\nexport interface LokaScriptInstance {\n compileSync: (\n code: string,\n options?: { traditional?: boolean; language?: string }\n ) => {\n ok: boolean;\n ast?: unknown;\n errors?: Array<{ message: string; line?: number; column?: number }>;\n };\n execute: (ast: unknown, ctx: unknown) => Promise<unknown>;\n createContext?: () => { locals: Map<string, unknown>; globals: Map<string, unknown> };\n}\n\n/**\n * Typed window interface for behavior auto-registration.\n * Avoids `(window as any)` casts throughout the codebase.\n * Checks both `window.lokascript` and `window.hyperfixi` for the runtime instance.\n */\nexport interface LokaScriptWindow {\n lokascript?: LokaScriptInstance;\n hyperfixi?: LokaScriptInstance;\n __hyperfixi_behaviors_ready?: Promise<void> | undefined;\n}\n\n/**\n * Resolve the LokaScript runtime from window globals.\n * Checks both `window.lokascript` and `window.hyperfixi`.\n */\nexport function resolveRuntime(): LokaScriptInstance | null {\n if (typeof window === 'undefined') return null;\n const win = window as unknown as LokaScriptWindow;\n return win.lokascript || win.hyperfixi || null;\n}\n"],"mappings":";AAkHO,SAAS,iBAA4C;AAC1D,MAAI,OAAO,WAAW,YAAa,QAAO;AAC1C,QAAM,MAAM;AACZ,SAAO,IAAI,cAAc,IAAI,aAAa;AAC5C;","names":[]}
@@ -0,0 +1,62 @@
1
+ import {
2
+ removableSchema
3
+ } from "./chunk-272NKUJ3.js";
4
+ import {
5
+ resizableSchema
6
+ } from "./chunk-V5IWDPDP.js";
7
+ import {
8
+ scrollRevealSchema
9
+ } from "./chunk-GPTHAUWN.js";
10
+ import {
11
+ sortableSchema
12
+ } from "./chunk-BWZ6EGII.js";
13
+ import {
14
+ tabsSchema
15
+ } from "./chunk-GVJPA2EK.js";
16
+ import {
17
+ toggleableSchema
18
+ } from "./chunk-WUHHMDAA.js";
19
+ import {
20
+ registerLoader,
21
+ registerSchema
22
+ } from "./chunk-3DVDS7CT.js";
23
+ import {
24
+ autoDismissSchema
25
+ } from "./chunk-ZQQZTMCJ.js";
26
+ import {
27
+ clickOutsideSchema
28
+ } from "./chunk-64DIQGQI.js";
29
+ import {
30
+ clipboardSchema
31
+ } from "./chunk-QKDYW4VM.js";
32
+ import {
33
+ draggableSchema
34
+ } from "./chunk-G6WR2AYR.js";
35
+ import {
36
+ focusTrapSchema
37
+ } from "./chunk-RB7OB6OD.js";
38
+
39
+ // src/loaders.ts
40
+ registerSchema(draggableSchema);
41
+ registerSchema(sortableSchema);
42
+ registerSchema(resizableSchema);
43
+ registerSchema(removableSchema);
44
+ registerSchema(toggleableSchema);
45
+ registerSchema(clipboardSchema);
46
+ registerSchema(autoDismissSchema);
47
+ registerSchema(clickOutsideSchema);
48
+ registerSchema(focusTrapSchema);
49
+ registerSchema(scrollRevealSchema);
50
+ registerSchema(tabsSchema);
51
+ registerLoader("Draggable", () => import("./behaviors/draggable.js"));
52
+ registerLoader("Sortable", () => import("./behaviors/sortable.js"));
53
+ registerLoader("Resizable", () => import("./behaviors/resizable.js"));
54
+ registerLoader("Removable", () => import("./behaviors/removable.js"));
55
+ registerLoader("Toggleable", () => import("./behaviors/toggleable.js"));
56
+ registerLoader("Clipboard", () => import("./behaviors/clipboard.js"));
57
+ registerLoader("AutoDismiss", () => import("./behaviors/autodismiss.js"));
58
+ registerLoader("ClickOutside", () => import("./behaviors/clickoutside.js"));
59
+ registerLoader("FocusTrap", () => import("./behaviors/focustrap.js"));
60
+ registerLoader("ScrollReveal", () => import("./behaviors/scrollreveal.js"));
61
+ registerLoader("Tabs", () => import("./behaviors/tabs.js"));
62
+ //# sourceMappingURL=chunk-7JDV2THA.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../src/loaders.ts"],"sourcesContent":["/**\n * Behavior Loaders\n *\n * Registers lazy loaders for all behaviors.\n * Import this module to enable on-demand loading without bundling all behaviors.\n *\n * @example\n * ```typescript\n * // Enable lazy loading\n * import '@hyperfixi/behaviors/loaders';\n *\n * // Now load behaviors on demand\n * import { loadBehavior } from '@hyperfixi/behaviors/registry';\n * await loadBehavior('Draggable');\n * ```\n */\n\nimport { registerLoader, registerSchema } from './registry';\n\n// Register schemas for metadata queries before loading\nimport { draggableSchema } from './schemas/draggable.schema';\nimport { sortableSchema } from './schemas/sortable.schema';\nimport { resizableSchema } from './schemas/resizable.schema';\nimport { removableSchema } from './schemas/removable.schema';\nimport { toggleableSchema } from './schemas/toggleable.schema';\nimport { clipboardSchema } from './schemas/clipboard.schema';\nimport { autoDismissSchema } from './schemas/autodismiss.schema';\nimport { clickOutsideSchema } from './schemas/clickoutside.schema';\nimport { focusTrapSchema } from './schemas/focustrap.schema';\nimport { scrollRevealSchema } from './schemas/scrollreveal.schema';\nimport { tabsSchema } from './schemas/tabs.schema';\n\n// Register all schemas\nregisterSchema(draggableSchema);\nregisterSchema(sortableSchema);\nregisterSchema(resizableSchema);\nregisterSchema(removableSchema);\nregisterSchema(toggleableSchema);\nregisterSchema(clipboardSchema);\nregisterSchema(autoDismissSchema);\nregisterSchema(clickOutsideSchema);\nregisterSchema(focusTrapSchema);\nregisterSchema(scrollRevealSchema);\nregisterSchema(tabsSchema);\n\n// Register lazy loaders - behaviors are only loaded when requested\nregisterLoader('Draggable', () => import('./behaviors/draggable'));\nregisterLoader('Sortable', () => import('./behaviors/sortable'));\nregisterLoader('Resizable', () => import('./behaviors/resizable'));\nregisterLoader('Removable', () => import('./behaviors/removable'));\nregisterLoader('Toggleable', () => import('./behaviors/toggleable'));\nregisterLoader('Clipboard', () => import('./behaviors/clipboard'));\nregisterLoader('AutoDismiss', () => import('./behaviors/autodismiss'));\nregisterLoader('ClickOutside', () => import('./behaviors/clickoutside'));\nregisterLoader('FocusTrap', () => import('./behaviors/focustrap'));\nregisterLoader('ScrollReveal', () => import('./behaviors/scrollreveal'));\nregisterLoader('Tabs', () => import('./behaviors/tabs'));\n"],"mappings":";;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;AAiCA,eAAe,eAAe;AAC9B,eAAe,cAAc;AAC7B,eAAe,eAAe;AAC9B,eAAe,eAAe;AAC9B,eAAe,gBAAgB;AAC/B,eAAe,eAAe;AAC9B,eAAe,iBAAiB;AAChC,eAAe,kBAAkB;AACjC,eAAe,eAAe;AAC9B,eAAe,kBAAkB;AACjC,eAAe,UAAU;AAGzB,eAAe,aAAa,MAAM,OAAO,0BAAuB,CAAC;AACjE,eAAe,YAAY,MAAM,OAAO,yBAAsB,CAAC;AAC/D,eAAe,aAAa,MAAM,OAAO,0BAAuB,CAAC;AACjE,eAAe,aAAa,MAAM,OAAO,0BAAuB,CAAC;AACjE,eAAe,cAAc,MAAM,OAAO,2BAAwB,CAAC;AACnE,eAAe,aAAa,MAAM,OAAO,0BAAuB,CAAC;AACjE,eAAe,eAAe,MAAM,OAAO,4BAAyB,CAAC;AACrE,eAAe,gBAAgB,MAAM,OAAO,6BAA0B,CAAC;AACvE,eAAe,aAAa,MAAM,OAAO,0BAAuB,CAAC;AACjE,eAAe,gBAAgB,MAAM,OAAO,6BAA0B,CAAC;AACvE,eAAe,QAAQ,MAAM,OAAO,qBAAkB,CAAC;","names":[]}
@@ -0,0 +1,116 @@
1
+ import {
2
+ focusTrapSchema
3
+ } from "./chunk-RB7OB6OD.js";
4
+ import {
5
+ resolveRuntime
6
+ } from "./chunk-6TJXDCAQ.js";
7
+
8
+ // src/behaviors/focustrap.ts
9
+ var focusTrapSource = focusTrapSchema.source;
10
+ var focusTrapMetadata = focusTrapSchema;
11
+ var FOCUSABLE_SELECTOR = [
12
+ "a[href]",
13
+ "button:not(:disabled)",
14
+ "input:not(:disabled)",
15
+ "select:not(:disabled)",
16
+ "textarea:not(:disabled)",
17
+ '[tabindex]:not([tabindex="-1"])'
18
+ ].join(", ");
19
+ function resolveElement(container, param) {
20
+ if (!param) return null;
21
+ if (param instanceof HTMLElement) return param;
22
+ if (typeof param === "string") {
23
+ return container.querySelector(param) || document.querySelector(param) || null;
24
+ }
25
+ return null;
26
+ }
27
+ function installFocusTrap(element, params) {
28
+ const returnFocus = params.returnFocus !== false;
29
+ let isActive = false;
30
+ let previouslyFocused = null;
31
+ function getFocusableElements() {
32
+ return Array.from(element.querySelectorAll(FOCUSABLE_SELECTOR));
33
+ }
34
+ function onKeyDown(e) {
35
+ if (!isActive || e.key !== "Tab") return;
36
+ const focusable = getFocusableElements();
37
+ if (focusable.length === 0) {
38
+ e.preventDefault();
39
+ return;
40
+ }
41
+ e.preventDefault();
42
+ const currentIndex = focusable.indexOf(document.activeElement);
43
+ if (e.shiftKey) {
44
+ const prevIndex = currentIndex <= 0 ? focusable.length - 1 : currentIndex - 1;
45
+ focusable[prevIndex].focus();
46
+ } else {
47
+ const nextIndex = currentIndex >= focusable.length - 1 ? 0 : currentIndex + 1;
48
+ focusable[nextIndex].focus();
49
+ }
50
+ }
51
+ function activate() {
52
+ if (isActive) return;
53
+ isActive = true;
54
+ previouslyFocused = document.activeElement;
55
+ element.setAttribute("aria-modal", "true");
56
+ const initialEl = resolveElement(element, params.initialFocus);
57
+ if (initialEl) {
58
+ initialEl.focus();
59
+ } else {
60
+ const focusable = getFocusableElements();
61
+ if (focusable.length > 0) {
62
+ focusable[0].focus();
63
+ }
64
+ }
65
+ element.dispatchEvent(new CustomEvent("focustrap:activated", { bubbles: true }));
66
+ }
67
+ function deactivate() {
68
+ if (!isActive) return;
69
+ isActive = false;
70
+ element.removeAttribute("aria-modal");
71
+ if (returnFocus && previouslyFocused instanceof HTMLElement) {
72
+ previouslyFocused.focus();
73
+ }
74
+ previouslyFocused = null;
75
+ element.dispatchEvent(new CustomEvent("focustrap:deactivated", { bubbles: true }));
76
+ }
77
+ element.addEventListener("keydown", onKeyDown);
78
+ element.addEventListener("focustrap:activate", () => activate());
79
+ element.addEventListener("focustrap:deactivate", () => deactivate());
80
+ if (params.active !== false) {
81
+ activate();
82
+ }
83
+ }
84
+ async function registerFocusTrap(hyperfixi) {
85
+ const hf = hyperfixi || resolveRuntime();
86
+ if (!hf) {
87
+ throw new Error(
88
+ "LokaScript not found. Make sure @hyperfixi/core is loaded before registering behaviors."
89
+ );
90
+ }
91
+ const syntheticNode = {
92
+ type: "behavior",
93
+ name: "FocusTrap",
94
+ parameters: ["active", "initialFocus", "returnFocus"],
95
+ eventHandlers: [],
96
+ imperativeInstaller: installFocusTrap
97
+ };
98
+ const ctx = hf.createContext ? hf.createContext() : { locals: /* @__PURE__ */ new Map(), globals: /* @__PURE__ */ new Map() };
99
+ await hf.execute(syntheticNode, ctx);
100
+ }
101
+ if (resolveRuntime()) {
102
+ registerFocusTrap().catch(console.error);
103
+ }
104
+ var focustrap_default = {
105
+ source: focusTrapSchema.source,
106
+ metadata: focusTrapSchema,
107
+ register: registerFocusTrap
108
+ };
109
+
110
+ export {
111
+ focusTrapSource,
112
+ focusTrapMetadata,
113
+ registerFocusTrap,
114
+ focustrap_default
115
+ };
116
+ //# sourceMappingURL=chunk-AFGA54SA.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../src/behaviors/focustrap.ts"],"sourcesContent":["/**\n * FocusTrap Behavior — Imperative Implementation\n *\n * Confines Tab navigation inside an element, manages aria-modal,\n * and restores focus on deactivation.\n */\n\nimport { focusTrapSchema } from '../schemas/focustrap.schema';\nimport type { LokaScriptInstance } from '../schemas/types';\nimport { resolveRuntime } from '../schemas/types';\n\n// Re-export schema-derived values\nexport const focusTrapSource = focusTrapSchema.source;\nexport const focusTrapMetadata = focusTrapSchema;\n\nconst FOCUSABLE_SELECTOR = [\n 'a[href]',\n 'button:not(:disabled)',\n 'input:not(:disabled)',\n 'select:not(:disabled)',\n 'textarea:not(:disabled)',\n '[tabindex]:not([tabindex=\"-1\"])',\n].join(', ');\n\n/**\n * Resolve a selector parameter to an HTMLElement within the container.\n */\nfunction resolveElement(container: HTMLElement, param: unknown): HTMLElement | null {\n if (!param) return null;\n if (param instanceof HTMLElement) return param;\n if (typeof param === 'string') {\n return (\n (container.querySelector(param) as HTMLElement) ||\n (document.querySelector(param) as HTMLElement) ||\n null\n );\n }\n return null;\n}\n\n/**\n * Imperative installer for FocusTrap behavior.\n */\nfunction installFocusTrap(element: HTMLElement, params: Record<string, any>): void {\n const returnFocus = params.returnFocus !== false;\n let isActive = false;\n let previouslyFocused: Element | null = null;\n\n function getFocusableElements(): HTMLElement[] {\n return Array.from(element.querySelectorAll<HTMLElement>(FOCUSABLE_SELECTOR));\n }\n\n function onKeyDown(e: KeyboardEvent) {\n if (!isActive || e.key !== 'Tab') return;\n\n const focusable = getFocusableElements();\n if (focusable.length === 0) {\n e.preventDefault();\n return;\n }\n\n // Always prevent default Tab and manually manage focus.\n // This ensures focus never escapes to elements outside the trap,\n // even when the modal is embedded in a page with other focusable elements.\n e.preventDefault();\n\n const currentIndex = focusable.indexOf(document.activeElement as HTMLElement);\n\n if (e.shiftKey) {\n const prevIndex = currentIndex <= 0 ? focusable.length - 1 : currentIndex - 1;\n focusable[prevIndex].focus();\n } else {\n const nextIndex = currentIndex >= focusable.length - 1 ? 0 : currentIndex + 1;\n focusable[nextIndex].focus();\n }\n }\n\n function activate() {\n if (isActive) return;\n isActive = true;\n previouslyFocused = document.activeElement;\n\n element.setAttribute('aria-modal', 'true');\n\n // Focus initialFocus element or first focusable\n const initialEl = resolveElement(element, params.initialFocus);\n if (initialEl) {\n initialEl.focus();\n } else {\n const focusable = getFocusableElements();\n if (focusable.length > 0) {\n focusable[0].focus();\n }\n }\n\n element.dispatchEvent(new CustomEvent('focustrap:activated', { bubbles: true }));\n }\n\n function deactivate() {\n if (!isActive) return;\n isActive = false;\n\n element.removeAttribute('aria-modal');\n\n if (returnFocus && previouslyFocused instanceof HTMLElement) {\n previouslyFocused.focus();\n }\n previouslyFocused = null;\n\n element.dispatchEvent(new CustomEvent('focustrap:deactivated', { bubbles: true }));\n }\n\n // Keydown handler for Tab trapping\n element.addEventListener('keydown', onKeyDown);\n\n // Programmatic activation/deactivation via custom events\n element.addEventListener('focustrap:activate', () => activate());\n element.addEventListener('focustrap:deactivate', () => deactivate());\n\n // Activate immediately if requested\n if (params.active !== false) {\n activate();\n }\n}\n\n/**\n * Register the FocusTrap behavior with LokaScript.\n */\nexport async function registerFocusTrap(hyperfixi?: LokaScriptInstance): Promise<void> {\n const hf = hyperfixi || resolveRuntime();\n\n if (!hf) {\n throw new Error(\n 'LokaScript not found. Make sure @hyperfixi/core is loaded before registering behaviors.'\n );\n }\n\n const syntheticNode = {\n type: 'behavior',\n name: 'FocusTrap',\n parameters: ['active', 'initialFocus', 'returnFocus'],\n eventHandlers: [],\n imperativeInstaller: installFocusTrap,\n };\n const ctx = hf.createContext ? hf.createContext() : { locals: new Map(), globals: new Map() };\n await hf.execute(syntheticNode, ctx);\n}\n\n// Auto-register when loaded as a script tag\nif (resolveRuntime()) {\n registerFocusTrap().catch(console.error);\n}\n\nexport default {\n source: focusTrapSchema.source,\n metadata: focusTrapSchema,\n register: registerFocusTrap,\n};\n"],"mappings":";;;;;;;;AAYO,IAAM,kBAAkB,gBAAgB;AACxC,IAAM,oBAAoB;AAEjC,IAAM,qBAAqB;AAAA,EACzB;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AACF,EAAE,KAAK,IAAI;AAKX,SAAS,eAAe,WAAwB,OAAoC;AAClF,MAAI,CAAC,MAAO,QAAO;AACnB,MAAI,iBAAiB,YAAa,QAAO;AACzC,MAAI,OAAO,UAAU,UAAU;AAC7B,WACG,UAAU,cAAc,KAAK,KAC7B,SAAS,cAAc,KAAK,KAC7B;AAAA,EAEJ;AACA,SAAO;AACT;AAKA,SAAS,iBAAiB,SAAsB,QAAmC;AACjF,QAAM,cAAc,OAAO,gBAAgB;AAC3C,MAAI,WAAW;AACf,MAAI,oBAAoC;AAExC,WAAS,uBAAsC;AAC7C,WAAO,MAAM,KAAK,QAAQ,iBAA8B,kBAAkB,CAAC;AAAA,EAC7E;AAEA,WAAS,UAAU,GAAkB;AACnC,QAAI,CAAC,YAAY,EAAE,QAAQ,MAAO;AAElC,UAAM,YAAY,qBAAqB;AACvC,QAAI,UAAU,WAAW,GAAG;AAC1B,QAAE,eAAe;AACjB;AAAA,IACF;AAKA,MAAE,eAAe;AAEjB,UAAM,eAAe,UAAU,QAAQ,SAAS,aAA4B;AAE5E,QAAI,EAAE,UAAU;AACd,YAAM,YAAY,gBAAgB,IAAI,UAAU,SAAS,IAAI,eAAe;AAC5E,gBAAU,SAAS,EAAE,MAAM;AAAA,IAC7B,OAAO;AACL,YAAM,YAAY,gBAAgB,UAAU,SAAS,IAAI,IAAI,eAAe;AAC5E,gBAAU,SAAS,EAAE,MAAM;AAAA,IAC7B;AAAA,EACF;AAEA,WAAS,WAAW;AAClB,QAAI,SAAU;AACd,eAAW;AACX,wBAAoB,SAAS;AAE7B,YAAQ,aAAa,cAAc,MAAM;AAGzC,UAAM,YAAY,eAAe,SAAS,OAAO,YAAY;AAC7D,QAAI,WAAW;AACb,gBAAU,MAAM;AAAA,IAClB,OAAO;AACL,YAAM,YAAY,qBAAqB;AACvC,UAAI,UAAU,SAAS,GAAG;AACxB,kBAAU,CAAC,EAAE,MAAM;AAAA,MACrB;AAAA,IACF;AAEA,YAAQ,cAAc,IAAI,YAAY,uBAAuB,EAAE,SAAS,KAAK,CAAC,CAAC;AAAA,EACjF;AAEA,WAAS,aAAa;AACpB,QAAI,CAAC,SAAU;AACf,eAAW;AAEX,YAAQ,gBAAgB,YAAY;AAEpC,QAAI,eAAe,6BAA6B,aAAa;AAC3D,wBAAkB,MAAM;AAAA,IAC1B;AACA,wBAAoB;AAEpB,YAAQ,cAAc,IAAI,YAAY,yBAAyB,EAAE,SAAS,KAAK,CAAC,CAAC;AAAA,EACnF;AAGA,UAAQ,iBAAiB,WAAW,SAAS;AAG7C,UAAQ,iBAAiB,sBAAsB,MAAM,SAAS,CAAC;AAC/D,UAAQ,iBAAiB,wBAAwB,MAAM,WAAW,CAAC;AAGnE,MAAI,OAAO,WAAW,OAAO;AAC3B,aAAS;AAAA,EACX;AACF;AAKA,eAAsB,kBAAkB,WAA+C;AACrF,QAAM,KAAK,aAAa,eAAe;AAEvC,MAAI,CAAC,IAAI;AACP,UAAM,IAAI;AAAA,MACR;AAAA,IACF;AAAA,EACF;AAEA,QAAM,gBAAgB;AAAA,IACpB,MAAM;AAAA,IACN,MAAM;AAAA,IACN,YAAY,CAAC,UAAU,gBAAgB,aAAa;AAAA,IACpD,eAAe,CAAC;AAAA,IAChB,qBAAqB;AAAA,EACvB;AACA,QAAM,MAAM,GAAG,gBAAgB,GAAG,cAAc,IAAI,EAAE,QAAQ,oBAAI,IAAI,GAAG,SAAS,oBAAI,IAAI,EAAE;AAC5F,QAAM,GAAG,QAAQ,eAAe,GAAG;AACrC;AAGA,IAAI,eAAe,GAAG;AACpB,oBAAkB,EAAE,MAAM,QAAQ,KAAK;AACzC;AAEA,IAAO,oBAAQ;AAAA,EACb,QAAQ,gBAAgB;AAAA,EACxB,UAAU;AAAA,EACV,UAAU;AACZ;","names":[]}
@@ -0,0 +1,62 @@
1
+ import {
2
+ clickOutsideSchema
3
+ } from "./chunk-64DIQGQI.js";
4
+ import {
5
+ resolveRuntime
6
+ } from "./chunk-6TJXDCAQ.js";
7
+
8
+ // src/behaviors/clickoutside.ts
9
+ var clickOutsideSource = clickOutsideSchema.source;
10
+ var clickOutsideMetadata = clickOutsideSchema;
11
+ function installClickOutside(element, params) {
12
+ let active = params.active !== false;
13
+ function onPointerDown(e) {
14
+ if (!element.isConnected) {
15
+ document.removeEventListener("pointerdown", onPointerDown);
16
+ return;
17
+ }
18
+ if (active && !element.contains(e.target)) {
19
+ element.dispatchEvent(new CustomEvent("clickoutside", { bubbles: true }));
20
+ }
21
+ }
22
+ document.addEventListener("pointerdown", onPointerDown);
23
+ element.addEventListener("clickoutside:activate", () => {
24
+ active = true;
25
+ });
26
+ element.addEventListener("clickoutside:deactivate", () => {
27
+ active = false;
28
+ });
29
+ }
30
+ async function registerClickOutside(hyperfixi) {
31
+ const hf = hyperfixi || resolveRuntime();
32
+ if (!hf) {
33
+ throw new Error(
34
+ "LokaScript not found. Make sure @hyperfixi/core is loaded before registering behaviors."
35
+ );
36
+ }
37
+ const syntheticNode = {
38
+ type: "behavior",
39
+ name: "ClickOutside",
40
+ parameters: ["active"],
41
+ eventHandlers: [],
42
+ imperativeInstaller: installClickOutside
43
+ };
44
+ const ctx = hf.createContext ? hf.createContext() : { locals: /* @__PURE__ */ new Map(), globals: /* @__PURE__ */ new Map() };
45
+ await hf.execute(syntheticNode, ctx);
46
+ }
47
+ if (resolveRuntime()) {
48
+ registerClickOutside().catch(console.error);
49
+ }
50
+ var clickoutside_default = {
51
+ source: clickOutsideSchema.source,
52
+ metadata: clickOutsideSchema,
53
+ register: registerClickOutside
54
+ };
55
+
56
+ export {
57
+ clickOutsideSource,
58
+ clickOutsideMetadata,
59
+ registerClickOutside,
60
+ clickoutside_default
61
+ };
62
+ //# sourceMappingURL=chunk-DYHBKDKB.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../src/behaviors/clickoutside.ts"],"sourcesContent":["/**\n * ClickOutside Behavior — Imperative Implementation\n *\n * Fires a clickoutside event when the user clicks outside the element.\n * Uses pointerdown instead of click to avoid timing issues.\n */\n\nimport { clickOutsideSchema } from '../schemas/clickoutside.schema';\nimport type { LokaScriptInstance } from '../schemas/types';\nimport { resolveRuntime } from '../schemas/types';\n\n// Re-export schema-derived values\nexport const clickOutsideSource = clickOutsideSchema.source;\nexport const clickOutsideMetadata = clickOutsideSchema;\n\n/**\n * Imperative installer for ClickOutside behavior.\n */\nfunction installClickOutside(element: HTMLElement, params: Record<string, any>): void {\n let active = params.active !== false;\n\n function onPointerDown(e: Event) {\n // Auto-cleanup if element has been removed from DOM\n if (!element.isConnected) {\n document.removeEventListener('pointerdown', onPointerDown);\n return;\n }\n\n if (active && !element.contains(e.target as Node)) {\n element.dispatchEvent(new CustomEvent('clickoutside', { bubbles: true }));\n }\n }\n\n document.addEventListener('pointerdown', onPointerDown);\n\n // Programmatic activation/deactivation via custom events\n element.addEventListener('clickoutside:activate', () => {\n active = true;\n });\n element.addEventListener('clickoutside:deactivate', () => {\n active = false;\n });\n}\n\n/**\n * Register the ClickOutside behavior with LokaScript.\n */\nexport async function registerClickOutside(hyperfixi?: LokaScriptInstance): Promise<void> {\n const hf = hyperfixi || resolveRuntime();\n\n if (!hf) {\n throw new Error(\n 'LokaScript not found. Make sure @hyperfixi/core is loaded before registering behaviors.'\n );\n }\n\n const syntheticNode = {\n type: 'behavior',\n name: 'ClickOutside',\n parameters: ['active'],\n eventHandlers: [],\n imperativeInstaller: installClickOutside,\n };\n const ctx = hf.createContext ? hf.createContext() : { locals: new Map(), globals: new Map() };\n await hf.execute(syntheticNode, ctx);\n}\n\n// Auto-register when loaded as a script tag\nif (resolveRuntime()) {\n registerClickOutside().catch(console.error);\n}\n\nexport default {\n source: clickOutsideSchema.source,\n metadata: clickOutsideSchema,\n register: registerClickOutside,\n};\n"],"mappings":";;;;;;;;AAYO,IAAM,qBAAqB,mBAAmB;AAC9C,IAAM,uBAAuB;AAKpC,SAAS,oBAAoB,SAAsB,QAAmC;AACpF,MAAI,SAAS,OAAO,WAAW;AAE/B,WAAS,cAAc,GAAU;AAE/B,QAAI,CAAC,QAAQ,aAAa;AACxB,eAAS,oBAAoB,eAAe,aAAa;AACzD;AAAA,IACF;AAEA,QAAI,UAAU,CAAC,QAAQ,SAAS,EAAE,MAAc,GAAG;AACjD,cAAQ,cAAc,IAAI,YAAY,gBAAgB,EAAE,SAAS,KAAK,CAAC,CAAC;AAAA,IAC1E;AAAA,EACF;AAEA,WAAS,iBAAiB,eAAe,aAAa;AAGtD,UAAQ,iBAAiB,yBAAyB,MAAM;AACtD,aAAS;AAAA,EACX,CAAC;AACD,UAAQ,iBAAiB,2BAA2B,MAAM;AACxD,aAAS;AAAA,EACX,CAAC;AACH;AAKA,eAAsB,qBAAqB,WAA+C;AACxF,QAAM,KAAK,aAAa,eAAe;AAEvC,MAAI,CAAC,IAAI;AACP,UAAM,IAAI;AAAA,MACR;AAAA,IACF;AAAA,EACF;AAEA,QAAM,gBAAgB;AAAA,IACpB,MAAM;AAAA,IACN,MAAM;AAAA,IACN,YAAY,CAAC,QAAQ;AAAA,IACrB,eAAe,CAAC;AAAA,IAChB,qBAAqB;AAAA,EACvB;AACA,QAAM,MAAM,GAAG,gBAAgB,GAAG,cAAc,IAAI,EAAE,QAAQ,oBAAI,IAAI,GAAG,SAAS,oBAAI,IAAI,EAAE;AAC5F,QAAM,GAAG,QAAQ,eAAe,GAAG;AACrC;AAGA,IAAI,eAAe,GAAG;AACpB,uBAAqB,EAAE,MAAM,QAAQ,KAAK;AAC5C;AAEA,IAAO,uBAAQ;AAAA,EACb,QAAQ,mBAAmB;AAAA,EAC3B,UAAU;AAAA,EACV,UAAU;AACZ;","names":[]}
@@ -0,0 +1,58 @@
1
+ // src/schemas/scrollreveal.schema.ts
2
+ var scrollRevealSchema = {
3
+ name: "ScrollReveal",
4
+ category: "layout",
5
+ tier: "common",
6
+ version: "1.0.0",
7
+ description: "Adds a class when the element enters the viewport via IntersectionObserver",
8
+ parameters: [
9
+ {
10
+ name: "cls",
11
+ type: "string",
12
+ optional: true,
13
+ default: "revealed",
14
+ description: "CSS class added when element enters viewport"
15
+ },
16
+ {
17
+ name: "threshold",
18
+ type: "number",
19
+ optional: true,
20
+ default: 0.1,
21
+ description: "Intersection ratio threshold (0-1) for triggering"
22
+ },
23
+ {
24
+ name: "once",
25
+ type: "boolean",
26
+ optional: true,
27
+ default: true,
28
+ description: "If true, disconnect observer after first intersection"
29
+ },
30
+ {
31
+ name: "rootMargin",
32
+ type: "string",
33
+ optional: true,
34
+ default: "0px",
35
+ description: "CSS margin around the viewport for triggering earlier or later"
36
+ }
37
+ ],
38
+ events: [
39
+ { name: "scrollreveal:enter", description: "Fired when the element enters the viewport" },
40
+ { name: "scrollreveal:exit", description: "Fired when the element exits the viewport" }
41
+ ],
42
+ requirements: ["Uses IntersectionObserver API (supported in all modern browsers)"],
43
+ source: `
44
+ behavior ScrollReveal(cls, threshold, once, rootMargin)
45
+ init
46
+ if cls is undefined set cls to "revealed"
47
+ if threshold is undefined set threshold to 0.1
48
+ if once is undefined set once to true
49
+ if rootMargin is undefined set rootMargin to "0px"
50
+ end
51
+ -- Imperative installer handles IntersectionObserver setup
52
+ end`.trim()
53
+ };
54
+
55
+ export {
56
+ scrollRevealSchema
57
+ };
58
+ //# sourceMappingURL=chunk-GPTHAUWN.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../src/schemas/scrollreveal.schema.ts"],"sourcesContent":["import type { BehaviorSchema } from './types';\n\n/**\n * ScrollReveal Behavior Schema\n *\n * Adds a class or fires events when the element enters or exits the viewport.\n * Uses the IntersectionObserver web standard API.\n */\nexport const scrollRevealSchema: BehaviorSchema = {\n name: 'ScrollReveal',\n category: 'layout',\n tier: 'common',\n version: '1.0.0',\n description: 'Adds a class when the element enters the viewport via IntersectionObserver',\n parameters: [\n {\n name: 'cls',\n type: 'string',\n optional: true,\n default: 'revealed',\n description: 'CSS class added when element enters viewport',\n },\n {\n name: 'threshold',\n type: 'number',\n optional: true,\n default: 0.1,\n description: 'Intersection ratio threshold (0-1) for triggering',\n },\n {\n name: 'once',\n type: 'boolean',\n optional: true,\n default: true,\n description: 'If true, disconnect observer after first intersection',\n },\n {\n name: 'rootMargin',\n type: 'string',\n optional: true,\n default: '0px',\n description: 'CSS margin around the viewport for triggering earlier or later',\n },\n ],\n events: [\n { name: 'scrollreveal:enter', description: 'Fired when the element enters the viewport' },\n { name: 'scrollreveal:exit', description: 'Fired when the element exits the viewport' },\n ],\n requirements: ['Uses IntersectionObserver API (supported in all modern browsers)'],\n source: `\nbehavior ScrollReveal(cls, threshold, once, rootMargin)\n init\n if cls is undefined set cls to \"revealed\"\n if threshold is undefined set threshold to 0.1\n if once is undefined set once to true\n if rootMargin is undefined set rootMargin to \"0px\"\n end\n -- Imperative installer handles IntersectionObserver setup\nend`.trim(),\n};\n"],"mappings":";AAQO,IAAM,qBAAqC;AAAA,EAChD,MAAM;AAAA,EACN,UAAU;AAAA,EACV,MAAM;AAAA,EACN,SAAS;AAAA,EACT,aAAa;AAAA,EACb,YAAY;AAAA,IACV;AAAA,MACE,MAAM;AAAA,MACN,MAAM;AAAA,MACN,UAAU;AAAA,MACV,SAAS;AAAA,MACT,aAAa;AAAA,IACf;AAAA,IACA;AAAA,MACE,MAAM;AAAA,MACN,MAAM;AAAA,MACN,UAAU;AAAA,MACV,SAAS;AAAA,MACT,aAAa;AAAA,IACf;AAAA,IACA;AAAA,MACE,MAAM;AAAA,MACN,MAAM;AAAA,MACN,UAAU;AAAA,MACV,SAAS;AAAA,MACT,aAAa;AAAA,IACf;AAAA,IACA;AAAA,MACE,MAAM;AAAA,MACN,MAAM;AAAA,MACN,UAAU;AAAA,MACV,SAAS;AAAA,MACT,aAAa;AAAA,IACf;AAAA,EACF;AAAA,EACA,QAAQ;AAAA,IACN,EAAE,MAAM,sBAAsB,aAAa,6CAA6C;AAAA,IACxF,EAAE,MAAM,qBAAqB,aAAa,4CAA4C;AAAA,EACxF;AAAA,EACA,cAAc,CAAC,kEAAkE;AAAA,EACjF,QAAQ;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,KASL,KAAK;AACV;","names":[]}
@@ -0,0 +1,68 @@
1
+ // src/schemas/tabs.schema.ts
2
+ var tabsSchema = {
3
+ name: "Tabs",
4
+ category: "ui",
5
+ tier: "core",
6
+ version: "1.0.0",
7
+ description: "WAI-ARIA compliant tabs with roving tabindex keyboard navigation. Auto-wires role, aria-selected, aria-controls, and aria-labelledby attributes.",
8
+ parameters: [
9
+ {
10
+ name: "orientation",
11
+ type: "string",
12
+ optional: true,
13
+ default: "horizontal",
14
+ enum: ["horizontal", "vertical"],
15
+ description: "Arrow key direction: horizontal (Left/Right) or vertical (Up/Down)"
16
+ },
17
+ {
18
+ name: "activeTab",
19
+ type: "number",
20
+ optional: true,
21
+ default: 0,
22
+ description: "Initial active tab index (zero-based)"
23
+ },
24
+ {
25
+ name: "wrap",
26
+ type: "boolean",
27
+ optional: true,
28
+ default: true,
29
+ description: "Wrap to first/last tab when navigating past the end"
30
+ },
31
+ {
32
+ name: "activeClass",
33
+ type: "string",
34
+ optional: true,
35
+ default: "active",
36
+ description: "CSS class applied to the active tab and its panel"
37
+ }
38
+ ],
39
+ events: [
40
+ {
41
+ name: "tabs:change",
42
+ description: "Fired before tab selection changes (cancelable via preventDefault)"
43
+ },
44
+ { name: "tabs:changed", description: "Fired after tab selection has changed" }
45
+ ],
46
+ requirements: [
47
+ 'Sets role="tablist" on the tab container',
48
+ 'Sets role="tab" on tab buttons and role="tabpanel" on content panels',
49
+ "Manages aria-selected, aria-controls, aria-labelledby, and tabindex",
50
+ "Keyboard: Arrow keys navigate, Home/End jump to first/last, Tab exits tablist"
51
+ ],
52
+ source: [
53
+ "behavior Tabs(orientation, activeTab, wrap, activeClass)",
54
+ " init",
55
+ ' if orientation is undefined set orientation to "horizontal"',
56
+ " if activeTab is undefined set activeTab to 0",
57
+ " if wrap is undefined set wrap to true",
58
+ ' if activeClass is undefined set activeClass to "active"',
59
+ " end",
60
+ " -- Imperative installer handles ARIA wiring and keyboard navigation",
61
+ "end"
62
+ ].join("\n")
63
+ };
64
+
65
+ export {
66
+ tabsSchema
67
+ };
68
+ //# sourceMappingURL=chunk-GVJPA2EK.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../src/schemas/tabs.schema.ts"],"sourcesContent":["import type { BehaviorSchema } from './types';\n\nexport const tabsSchema: BehaviorSchema = {\n name: 'Tabs',\n category: 'ui',\n tier: 'core',\n version: '1.0.0',\n description:\n 'WAI-ARIA compliant tabs with roving tabindex keyboard navigation. ' +\n 'Auto-wires role, aria-selected, aria-controls, and aria-labelledby attributes.',\n parameters: [\n {\n name: 'orientation',\n type: 'string',\n optional: true,\n default: 'horizontal',\n enum: ['horizontal', 'vertical'],\n description: 'Arrow key direction: horizontal (Left/Right) or vertical (Up/Down)',\n },\n {\n name: 'activeTab',\n type: 'number',\n optional: true,\n default: 0,\n description: 'Initial active tab index (zero-based)',\n },\n {\n name: 'wrap',\n type: 'boolean',\n optional: true,\n default: true,\n description: 'Wrap to first/last tab when navigating past the end',\n },\n {\n name: 'activeClass',\n type: 'string',\n optional: true,\n default: 'active',\n description: 'CSS class applied to the active tab and its panel',\n },\n ],\n events: [\n {\n name: 'tabs:change',\n description: 'Fired before tab selection changes (cancelable via preventDefault)',\n },\n { name: 'tabs:changed', description: 'Fired after tab selection has changed' },\n ],\n requirements: [\n 'Sets role=\"tablist\" on the tab container',\n 'Sets role=\"tab\" on tab buttons and role=\"tabpanel\" on content panels',\n 'Manages aria-selected, aria-controls, aria-labelledby, and tabindex',\n 'Keyboard: Arrow keys navigate, Home/End jump to first/last, Tab exits tablist',\n ],\n source: [\n 'behavior Tabs(orientation, activeTab, wrap, activeClass)',\n ' init',\n ' if orientation is undefined set orientation to \"horizontal\"',\n ' if activeTab is undefined set activeTab to 0',\n ' if wrap is undefined set wrap to true',\n ' if activeClass is undefined set activeClass to \"active\"',\n ' end',\n ' -- Imperative installer handles ARIA wiring and keyboard navigation',\n 'end',\n ].join('\\n'),\n};\n"],"mappings":";AAEO,IAAM,aAA6B;AAAA,EACxC,MAAM;AAAA,EACN,UAAU;AAAA,EACV,MAAM;AAAA,EACN,SAAS;AAAA,EACT,aACE;AAAA,EAEF,YAAY;AAAA,IACV;AAAA,MACE,MAAM;AAAA,MACN,MAAM;AAAA,MACN,UAAU;AAAA,MACV,SAAS;AAAA,MACT,MAAM,CAAC,cAAc,UAAU;AAAA,MAC/B,aAAa;AAAA,IACf;AAAA,IACA;AAAA,MACE,MAAM;AAAA,MACN,MAAM;AAAA,MACN,UAAU;AAAA,MACV,SAAS;AAAA,MACT,aAAa;AAAA,IACf;AAAA,IACA;AAAA,MACE,MAAM;AAAA,MACN,MAAM;AAAA,MACN,UAAU;AAAA,MACV,SAAS;AAAA,MACT,aAAa;AAAA,IACf;AAAA,IACA;AAAA,MACE,MAAM;AAAA,MACN,MAAM;AAAA,MACN,UAAU;AAAA,MACV,SAAS;AAAA,MACT,aAAa;AAAA,IACf;AAAA,EACF;AAAA,EACA,QAAQ;AAAA,IACN;AAAA,MACE,MAAM;AAAA,MACN,aAAa;AAAA,IACf;AAAA,IACA,EAAE,MAAM,gBAAgB,aAAa,wCAAwC;AAAA,EAC/E;AAAA,EACA,cAAc;AAAA,IACZ;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,EACF;AAAA,EACA,QAAQ;AAAA,IACN;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,EACF,EAAE,KAAK,IAAI;AACb;","names":[]}
@@ -0,0 +1,89 @@
1
+ import {
2
+ autoDismissSchema
3
+ } from "./chunk-ZQQZTMCJ.js";
4
+ import {
5
+ resolveRuntime
6
+ } from "./chunk-6TJXDCAQ.js";
7
+
8
+ // src/behaviors/autodismiss.ts
9
+ var autoDismissSource = autoDismissSchema.source;
10
+ var autoDismissMetadata = autoDismissSchema;
11
+ function installAutoDismiss(element, params) {
12
+ const delay = typeof params.delay === "number" ? params.delay : 5e3;
13
+ const pauseOnHover = params.pauseOnHover !== false;
14
+ const effect = params.effect === "fade" ? "fade" : "none";
15
+ let timerId = null;
16
+ let remaining = delay;
17
+ let startedAt = Date.now();
18
+ function dismiss() {
19
+ const event = new CustomEvent("autodismiss:dismissed", {
20
+ bubbles: true,
21
+ cancelable: true
22
+ });
23
+ element.dispatchEvent(event);
24
+ if (event.defaultPrevented) return;
25
+ if (effect === "fade") {
26
+ element.style.transition = "opacity 300ms";
27
+ element.style.opacity = "0";
28
+ setTimeout(() => element.remove(), 300);
29
+ } else {
30
+ element.remove();
31
+ }
32
+ }
33
+ function start() {
34
+ startedAt = Date.now();
35
+ timerId = setTimeout(dismiss, remaining);
36
+ }
37
+ element.dispatchEvent(new CustomEvent("autodismiss:start", { bubbles: true }));
38
+ start();
39
+ if (pauseOnHover) {
40
+ element.addEventListener("mouseenter", () => {
41
+ if (timerId != null) {
42
+ clearTimeout(timerId);
43
+ timerId = null;
44
+ remaining -= Date.now() - startedAt;
45
+ if (remaining < 0) remaining = 0;
46
+ element.dispatchEvent(new CustomEvent("autodismiss:paused", { bubbles: true }));
47
+ }
48
+ });
49
+ element.addEventListener("mouseleave", () => {
50
+ if (timerId == null && element.isConnected) {
51
+ element.dispatchEvent(new CustomEvent("autodismiss:resumed", { bubbles: true }));
52
+ start();
53
+ }
54
+ });
55
+ }
56
+ }
57
+ async function registerAutoDismiss(hyperfixi) {
58
+ const hf = hyperfixi || resolveRuntime();
59
+ if (!hf) {
60
+ throw new Error(
61
+ "LokaScript not found. Make sure @hyperfixi/core is loaded before registering behaviors."
62
+ );
63
+ }
64
+ const syntheticNode = {
65
+ type: "behavior",
66
+ name: "AutoDismiss",
67
+ parameters: ["delay", "pauseOnHover", "effect"],
68
+ eventHandlers: [],
69
+ imperativeInstaller: installAutoDismiss
70
+ };
71
+ const ctx = hf.createContext ? hf.createContext() : { locals: /* @__PURE__ */ new Map(), globals: /* @__PURE__ */ new Map() };
72
+ await hf.execute(syntheticNode, ctx);
73
+ }
74
+ if (resolveRuntime()) {
75
+ registerAutoDismiss().catch(console.error);
76
+ }
77
+ var autodismiss_default = {
78
+ source: autoDismissSchema.source,
79
+ metadata: autoDismissSchema,
80
+ register: registerAutoDismiss
81
+ };
82
+
83
+ export {
84
+ autoDismissSource,
85
+ autoDismissMetadata,
86
+ registerAutoDismiss,
87
+ autodismiss_default
88
+ };
89
+ //# sourceMappingURL=chunk-H2MCHR5A.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../src/behaviors/autodismiss.ts"],"sourcesContent":["/**\n * AutoDismiss Behavior — Imperative Implementation\n *\n * Auto-removes elements after a configurable delay.\n * Supports pause-on-hover and fade effect using standard setTimeout/clearTimeout.\n */\n\nimport { autoDismissSchema } from '../schemas/autodismiss.schema';\nimport type { LokaScriptInstance } from '../schemas/types';\nimport { resolveRuntime } from '../schemas/types';\n\n// Re-export schema-derived values\nexport const autoDismissSource = autoDismissSchema.source;\nexport const autoDismissMetadata = autoDismissSchema;\n\n/**\n * Imperative installer for AutoDismiss behavior.\n */\nfunction installAutoDismiss(element: HTMLElement, params: Record<string, any>): void {\n const delay = typeof params.delay === 'number' ? params.delay : 5000;\n const pauseOnHover = params.pauseOnHover !== false;\n const effect = params.effect === 'fade' ? 'fade' : 'none';\n\n let timerId: ReturnType<typeof setTimeout> | null = null;\n let remaining = delay;\n let startedAt = Date.now();\n\n function dismiss() {\n const event = new CustomEvent('autodismiss:dismissed', {\n bubbles: true,\n cancelable: true,\n });\n element.dispatchEvent(event);\n\n if (event.defaultPrevented) return;\n\n if (effect === 'fade') {\n element.style.transition = 'opacity 300ms';\n element.style.opacity = '0';\n setTimeout(() => element.remove(), 300);\n } else {\n element.remove();\n }\n }\n\n function start() {\n startedAt = Date.now();\n timerId = setTimeout(dismiss, remaining);\n }\n\n // Start the countdown\n element.dispatchEvent(new CustomEvent('autodismiss:start', { bubbles: true }));\n start();\n\n if (pauseOnHover) {\n element.addEventListener('mouseenter', () => {\n if (timerId != null) {\n clearTimeout(timerId);\n timerId = null;\n remaining -= Date.now() - startedAt;\n if (remaining < 0) remaining = 0;\n element.dispatchEvent(new CustomEvent('autodismiss:paused', { bubbles: true }));\n }\n });\n\n element.addEventListener('mouseleave', () => {\n if (timerId == null && element.isConnected) {\n element.dispatchEvent(new CustomEvent('autodismiss:resumed', { bubbles: true }));\n start();\n }\n });\n }\n}\n\n/**\n * Register the AutoDismiss behavior with LokaScript.\n */\nexport async function registerAutoDismiss(hyperfixi?: LokaScriptInstance): Promise<void> {\n const hf = hyperfixi || resolveRuntime();\n\n if (!hf) {\n throw new Error(\n 'LokaScript not found. Make sure @hyperfixi/core is loaded before registering behaviors.'\n );\n }\n\n const syntheticNode = {\n type: 'behavior',\n name: 'AutoDismiss',\n parameters: ['delay', 'pauseOnHover', 'effect'],\n eventHandlers: [],\n imperativeInstaller: installAutoDismiss,\n };\n const ctx = hf.createContext ? hf.createContext() : { locals: new Map(), globals: new Map() };\n await hf.execute(syntheticNode, ctx);\n}\n\n// Auto-register when loaded as a script tag\nif (resolveRuntime()) {\n registerAutoDismiss().catch(console.error);\n}\n\nexport default {\n source: autoDismissSchema.source,\n metadata: autoDismissSchema,\n register: registerAutoDismiss,\n};\n"],"mappings":";;;;;;;;AAYO,IAAM,oBAAoB,kBAAkB;AAC5C,IAAM,sBAAsB;AAKnC,SAAS,mBAAmB,SAAsB,QAAmC;AACnF,QAAM,QAAQ,OAAO,OAAO,UAAU,WAAW,OAAO,QAAQ;AAChE,QAAM,eAAe,OAAO,iBAAiB;AAC7C,QAAM,SAAS,OAAO,WAAW,SAAS,SAAS;AAEnD,MAAI,UAAgD;AACpD,MAAI,YAAY;AAChB,MAAI,YAAY,KAAK,IAAI;AAEzB,WAAS,UAAU;AACjB,UAAM,QAAQ,IAAI,YAAY,yBAAyB;AAAA,MACrD,SAAS;AAAA,MACT,YAAY;AAAA,IACd,CAAC;AACD,YAAQ,cAAc,KAAK;AAE3B,QAAI,MAAM,iBAAkB;AAE5B,QAAI,WAAW,QAAQ;AACrB,cAAQ,MAAM,aAAa;AAC3B,cAAQ,MAAM,UAAU;AACxB,iBAAW,MAAM,QAAQ,OAAO,GAAG,GAAG;AAAA,IACxC,OAAO;AACL,cAAQ,OAAO;AAAA,IACjB;AAAA,EACF;AAEA,WAAS,QAAQ;AACf,gBAAY,KAAK,IAAI;AACrB,cAAU,WAAW,SAAS,SAAS;AAAA,EACzC;AAGA,UAAQ,cAAc,IAAI,YAAY,qBAAqB,EAAE,SAAS,KAAK,CAAC,CAAC;AAC7E,QAAM;AAEN,MAAI,cAAc;AAChB,YAAQ,iBAAiB,cAAc,MAAM;AAC3C,UAAI,WAAW,MAAM;AACnB,qBAAa,OAAO;AACpB,kBAAU;AACV,qBAAa,KAAK,IAAI,IAAI;AAC1B,YAAI,YAAY,EAAG,aAAY;AAC/B,gBAAQ,cAAc,IAAI,YAAY,sBAAsB,EAAE,SAAS,KAAK,CAAC,CAAC;AAAA,MAChF;AAAA,IACF,CAAC;AAED,YAAQ,iBAAiB,cAAc,MAAM;AAC3C,UAAI,WAAW,QAAQ,QAAQ,aAAa;AAC1C,gBAAQ,cAAc,IAAI,YAAY,uBAAuB,EAAE,SAAS,KAAK,CAAC,CAAC;AAC/E,cAAM;AAAA,MACR;AAAA,IACF,CAAC;AAAA,EACH;AACF;AAKA,eAAsB,oBAAoB,WAA+C;AACvF,QAAM,KAAK,aAAa,eAAe;AAEvC,MAAI,CAAC,IAAI;AACP,UAAM,IAAI;AAAA,MACR;AAAA,IACF;AAAA,EACF;AAEA,QAAM,gBAAgB;AAAA,IACpB,MAAM;AAAA,IACN,MAAM;AAAA,IACN,YAAY,CAAC,SAAS,gBAAgB,QAAQ;AAAA,IAC9C,eAAe,CAAC;AAAA,IAChB,qBAAqB;AAAA,EACvB;AACA,QAAM,MAAM,GAAG,gBAAgB,GAAG,cAAc,IAAI,EAAE,QAAQ,oBAAI,IAAI,GAAG,SAAS,oBAAI,IAAI,EAAE;AAC5F,QAAM,GAAG,QAAQ,eAAe,GAAG;AACrC;AAGA,IAAI,eAAe,GAAG;AACpB,sBAAoB,EAAE,MAAM,QAAQ,KAAK;AAC3C;AAEA,IAAO,sBAAQ;AAAA,EACb,QAAQ,kBAAkB;AAAA,EAC1B,UAAU;AAAA,EACV,UAAU;AACZ;","names":[]}
@@ -1,12 +1,15 @@
1
1
  import {
2
2
  removableSchema
3
3
  } from "./chunk-272NKUJ3.js";
4
+ import {
5
+ resolveRuntime
6
+ } from "./chunk-6TJXDCAQ.js";
4
7
 
5
8
  // src/behaviors/removable.ts
6
9
  var removableSource = removableSchema.source;
7
10
  var removableMetadata = removableSchema;
8
11
  async function registerRemovable(hyperfixi) {
9
- const hf = hyperfixi || (typeof window !== "undefined" ? window.lokascript : null);
12
+ const hf = hyperfixi || resolveRuntime();
10
13
  if (!hf) {
11
14
  throw new Error(
12
15
  "LokaScript not found. Make sure @hyperfixi/core is loaded before registering behaviors."
@@ -19,7 +22,7 @@ async function registerRemovable(hyperfixi) {
19
22
  const ctx = hf.createContext ? hf.createContext() : { locals: /* @__PURE__ */ new Map(), globals: /* @__PURE__ */ new Map() };
20
23
  await hf.execute(result.ast, ctx);
21
24
  }
22
- if (typeof window !== "undefined" && window.lokascript) {
25
+ if (resolveRuntime()) {
23
26
  registerRemovable().catch(console.error);
24
27
  }
25
28
  var removable_default = {
@@ -34,4 +37,4 @@ export {
34
37
  registerRemovable,
35
38
  removable_default
36
39
  };
37
- //# sourceMappingURL=chunk-2NQHIHD5.js.map
40
+ //# sourceMappingURL=chunk-H5Y5ARYG.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../src/behaviors/removable.ts"],"sourcesContent":["/**\n * Removable Behavior\n *\n * A behavior that removes an element when a trigger is clicked.\n * Supports optional confirmation and transition effects.\n *\n * @example\n * ```html\n * <div _=\"install Removable\">Click to remove</div>\n *\n * <div _=\"install Removable(confirm: true)\">With confirmation</div>\n * ```\n */\n\nimport { removableSchema } from '../schemas/removable.schema';\nimport type { LokaScriptInstance } from '../schemas/types';\nimport { resolveRuntime } from '../schemas/types';\n\n// Re-export schema-derived values for backwards compatibility\nexport const removableSource = removableSchema.source;\nexport const removableMetadata = removableSchema;\n\n/**\n * Register the Removable behavior with LokaScript.\n */\nexport async function registerRemovable(hyperfixi?: LokaScriptInstance): Promise<void> {\n const hf = hyperfixi || resolveRuntime();\n\n if (!hf) {\n throw new Error(\n 'LokaScript not found. Make sure @hyperfixi/core is loaded before registering behaviors.'\n );\n }\n\n const result = hf.compileSync(removableSchema.source, { traditional: true });\n\n if (!result.ok) {\n throw new Error(`Failed to compile Removable behavior: ${JSON.stringify(result.errors)}`);\n }\n\n const ctx = hf.createContext ? hf.createContext() : { locals: new Map(), globals: new Map() };\n await hf.execute(result.ast, ctx);\n}\n\n// Auto-register when loaded as a script tag\nif (resolveRuntime()) {\n registerRemovable().catch(console.error);\n}\n\nexport default {\n source: removableSchema.source,\n metadata: removableSchema,\n register: registerRemovable,\n};\n"],"mappings":";;;;;;;;AAmBO,IAAM,kBAAkB,gBAAgB;AACxC,IAAM,oBAAoB;AAKjC,eAAsB,kBAAkB,WAA+C;AACrF,QAAM,KAAK,aAAa,eAAe;AAEvC,MAAI,CAAC,IAAI;AACP,UAAM,IAAI;AAAA,MACR;AAAA,IACF;AAAA,EACF;AAEA,QAAM,SAAS,GAAG,YAAY,gBAAgB,QAAQ,EAAE,aAAa,KAAK,CAAC;AAE3E,MAAI,CAAC,OAAO,IAAI;AACd,UAAM,IAAI,MAAM,yCAAyC,KAAK,UAAU,OAAO,MAAM,CAAC,EAAE;AAAA,EAC1F;AAEA,QAAM,MAAM,GAAG,gBAAgB,GAAG,cAAc,IAAI,EAAE,QAAQ,oBAAI,IAAI,GAAG,SAAS,oBAAI,IAAI,EAAE;AAC5F,QAAM,GAAG,QAAQ,OAAO,KAAK,GAAG;AAClC;AAGA,IAAI,eAAe,GAAG;AACpB,oBAAkB,EAAE,MAAM,QAAQ,KAAK;AACzC;AAEA,IAAO,oBAAQ;AAAA,EACb,QAAQ,gBAAgB;AAAA,EACxB,UAAU;AAAA,EACV,UAAU;AACZ;","names":[]}