@hyperfixi/behaviors 2.2.0 → 2.3.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 (131) hide show
  1. package/dist/all.browser.global.js +316 -54
  2. package/dist/all.browser.global.js.map +1 -1
  3. package/dist/autodismiss.browser.global.js +54 -2
  4. package/dist/autodismiss.browser.global.js.map +1 -1
  5. package/dist/behaviors/autodismiss.cjs +54 -18
  6. package/dist/behaviors/autodismiss.cjs.map +1 -1
  7. package/dist/behaviors/autodismiss.js +2 -2
  8. package/dist/behaviors/clickoutside.cjs +23 -4
  9. package/dist/behaviors/clickoutside.cjs.map +1 -1
  10. package/dist/behaviors/clickoutside.js +2 -2
  11. package/dist/behaviors/clipboard.cjs +43 -21
  12. package/dist/behaviors/clipboard.cjs.map +1 -1
  13. package/dist/behaviors/clipboard.js +2 -2
  14. package/dist/behaviors/focustrap.cjs +44 -3
  15. package/dist/behaviors/focustrap.cjs.map +1 -1
  16. package/dist/behaviors/focustrap.js +2 -2
  17. package/dist/behaviors/removable.cjs +7 -4
  18. package/dist/behaviors/removable.cjs.map +1 -1
  19. package/dist/behaviors/removable.js +2 -2
  20. package/dist/behaviors/resizable.cjs +22 -14
  21. package/dist/behaviors/resizable.cjs.map +1 -1
  22. package/dist/behaviors/resizable.js +2 -2
  23. package/dist/behaviors/scrollreveal.cjs +25 -13
  24. package/dist/behaviors/scrollreveal.cjs.map +1 -1
  25. package/dist/behaviors/scrollreveal.js +2 -2
  26. package/dist/behaviors/sortable.cjs +18 -12
  27. package/dist/behaviors/sortable.cjs.map +1 -1
  28. package/dist/behaviors/sortable.js +2 -2
  29. package/dist/behaviors/tabs.cjs +80 -11
  30. package/dist/behaviors/tabs.cjs.map +1 -1
  31. package/dist/behaviors/tabs.js +2 -2
  32. package/dist/behaviors/toggleable.cjs +5 -2
  33. package/dist/behaviors/toggleable.cjs.map +1 -1
  34. package/dist/behaviors/toggleable.js +2 -2
  35. package/dist/chunk-66U2RSYJ.js +100 -0
  36. package/dist/chunk-66U2RSYJ.js.map +1 -0
  37. package/dist/{chunk-2NSKQMNM.js → chunk-7O7UOSBH.js} +2 -2
  38. package/dist/{chunk-244WSZOL.js → chunk-EKKJVXDZ.js} +2 -2
  39. package/dist/{chunk-AFGA54SA.js → chunk-F3CASJ7Q.js} +2 -2
  40. package/dist/{chunk-YHQRFUWV.js → chunk-GALKOMJ5.js} +2 -2
  41. package/dist/{chunk-272NKUJ3.js → chunk-HMU342XE.js} +8 -5
  42. package/dist/chunk-HMU342XE.js.map +1 -0
  43. package/dist/chunk-HQDYH45I.js +137 -0
  44. package/dist/chunk-HQDYH45I.js.map +1 -0
  45. package/dist/{chunk-WTUVPVSD.js → chunk-IQM32TEY.js} +2 -2
  46. package/dist/{chunk-H5Y5ARYG.js → chunk-L52AGCMP.js} +2 -2
  47. package/dist/{chunk-H2MCHR5A.js → chunk-LQJOQTBZ.js} +2 -2
  48. package/dist/{chunk-7JDV2THA.js → chunk-MVNHMYIK.js} +11 -11
  49. package/dist/{chunk-BWZ6EGII.js → chunk-NC6I6T7T.js} +19 -13
  50. package/dist/{chunk-BWZ6EGII.js.map → chunk-NC6I6T7T.js.map} +1 -1
  51. package/dist/chunk-OJ3YWO3W.js +92 -0
  52. package/dist/chunk-OJ3YWO3W.js.map +1 -0
  53. package/dist/{chunk-64DIQGQI.js → chunk-SLOXO6IY.js} +24 -5
  54. package/dist/chunk-SLOXO6IY.js.map +1 -0
  55. package/dist/{chunk-RPERQTFU.js → chunk-TLLGH5KX.js} +2 -2
  56. package/dist/{chunk-V5IWDPDP.js → chunk-U5GNXZUF.js} +23 -15
  57. package/dist/{chunk-V5IWDPDP.js.map → chunk-U5GNXZUF.js.map} +1 -1
  58. package/dist/{chunk-GPTHAUWN.js → chunk-URZGNPTQ.js} +26 -14
  59. package/dist/chunk-URZGNPTQ.js.map +1 -0
  60. package/dist/chunk-WOTZO7K4.js +92 -0
  61. package/dist/chunk-WOTZO7K4.js.map +1 -0
  62. package/dist/{chunk-JKBWIJFI.js → chunk-WPOQIMCC.js} +2 -2
  63. package/dist/{chunk-WUHHMDAA.js → chunk-XYZ7FOXJ.js} +6 -3
  64. package/dist/{chunk-WUHHMDAA.js.map → chunk-XYZ7FOXJ.js.map} +1 -1
  65. package/dist/{chunk-DYHBKDKB.js → chunk-ZZ2WSAX3.js} +2 -2
  66. package/dist/clickoutside.browser.global.js +16 -5
  67. package/dist/clickoutside.browser.global.js.map +1 -1
  68. package/dist/clipboard.browser.global.js +43 -2
  69. package/dist/clipboard.browser.global.js.map +1 -1
  70. package/dist/core.browser.global.js +5 -2
  71. package/dist/core.browser.global.js.map +1 -1
  72. package/dist/focustrap.browser.global.js +46 -5
  73. package/dist/focustrap.browser.global.js.map +1 -1
  74. package/dist/index.cjs +321 -102
  75. package/dist/index.cjs.map +1 -1
  76. package/dist/index.js +21 -21
  77. package/dist/loaders.cjs +321 -102
  78. package/dist/loaders.cjs.map +1 -1
  79. package/dist/loaders.js +11 -11
  80. package/dist/removable.browser.global.js +8 -5
  81. package/dist/removable.browser.global.js.map +1 -1
  82. package/dist/resizable.browser.global.js +24 -16
  83. package/dist/resizable.browser.global.js.map +1 -1
  84. package/dist/resolver.browser.global.js +407 -0
  85. package/dist/resolver.browser.global.js.map +1 -0
  86. package/dist/schemas/index.cjs +321 -102
  87. package/dist/schemas/index.cjs.map +1 -1
  88. package/dist/schemas/index.js +10 -10
  89. package/dist/scrollreveal.browser.global.js +27 -8
  90. package/dist/scrollreveal.browser.global.js.map +1 -1
  91. package/dist/sortable.browser.global.js +19 -13
  92. package/dist/sortable.browser.global.js.map +1 -1
  93. package/dist/tabs.browser.global.js +80 -2
  94. package/dist/tabs.browser.global.js.map +1 -1
  95. package/dist/toggleable.browser.global.js +6 -3
  96. package/dist/toggleable.browser.global.js.map +1 -1
  97. package/package.json +1 -1
  98. package/src/behavior-resolver.ts +91 -0
  99. package/src/browser-resolver-bundle.ts +42 -0
  100. package/src/schemas/autodismiss.schema.ts +54 -18
  101. package/src/schemas/clickoutside.schema.ts +22 -3
  102. package/src/schemas/clipboard.schema.ts +43 -21
  103. package/src/schemas/focustrap.schema.ts +44 -3
  104. package/src/schemas/removable.schema.ts +7 -4
  105. package/src/schemas/resizable.schema.ts +22 -14
  106. package/src/schemas/scrollreveal.schema.ts +25 -13
  107. package/src/schemas/sortable.schema.ts +18 -12
  108. package/src/schemas/tabs.schema.ts +80 -11
  109. package/src/schemas/toggleable.schema.ts +5 -2
  110. package/dist/chunk-272NKUJ3.js.map +0 -1
  111. package/dist/chunk-64DIQGQI.js.map +0 -1
  112. package/dist/chunk-GPTHAUWN.js.map +0 -1
  113. package/dist/chunk-GVJPA2EK.js +0 -68
  114. package/dist/chunk-GVJPA2EK.js.map +0 -1
  115. package/dist/chunk-QKDYW4VM.js +0 -70
  116. package/dist/chunk-QKDYW4VM.js.map +0 -1
  117. package/dist/chunk-RB7OB6OD.js +0 -51
  118. package/dist/chunk-RB7OB6OD.js.map +0 -1
  119. package/dist/chunk-ZQQZTMCJ.js +0 -64
  120. package/dist/chunk-ZQQZTMCJ.js.map +0 -1
  121. /package/dist/{chunk-2NSKQMNM.js.map → chunk-7O7UOSBH.js.map} +0 -0
  122. /package/dist/{chunk-244WSZOL.js.map → chunk-EKKJVXDZ.js.map} +0 -0
  123. /package/dist/{chunk-AFGA54SA.js.map → chunk-F3CASJ7Q.js.map} +0 -0
  124. /package/dist/{chunk-YHQRFUWV.js.map → chunk-GALKOMJ5.js.map} +0 -0
  125. /package/dist/{chunk-WTUVPVSD.js.map → chunk-IQM32TEY.js.map} +0 -0
  126. /package/dist/{chunk-H5Y5ARYG.js.map → chunk-L52AGCMP.js.map} +0 -0
  127. /package/dist/{chunk-H2MCHR5A.js.map → chunk-LQJOQTBZ.js.map} +0 -0
  128. /package/dist/{chunk-7JDV2THA.js.map → chunk-MVNHMYIK.js.map} +0 -0
  129. /package/dist/{chunk-RPERQTFU.js.map → chunk-TLLGH5KX.js.map} +0 -0
  130. /package/dist/{chunk-JKBWIJFI.js.map → chunk-WPOQIMCC.js.map} +0 -0
  131. /package/dist/{chunk-DYHBKDKB.js.map → chunk-ZZ2WSAX3.js.map} +0 -0
@@ -1 +1 @@
1
- {"version":3,"sources":["../src/schemas/toggleable.schema.ts"],"sourcesContent":["import type { BehaviorSchema } from './types';\n\n/**\n * Toggleable Behavior Schema\n *\n * Toggles a CSS class on click.\n * Useful for accordions, dropdowns, and toggle buttons.\n */\nexport const toggleableSchema: BehaviorSchema = {\n name: 'Toggleable',\n category: 'form',\n tier: 'core',\n version: '1.0.0',\n description: 'Toggles a CSS class on click',\n parameters: [\n {\n name: 'cls',\n type: 'string',\n optional: true,\n default: 'active',\n description: 'CSS class to toggle',\n },\n {\n name: 'target',\n type: 'selector',\n optional: true,\n default: 'me',\n description: 'Element to toggle the class on',\n },\n ],\n events: [\n { name: 'toggleable:on', description: 'Fired when class is added' },\n { name: 'toggleable:off', description: 'Fired when class is removed' },\n ],\n source: `\nbehavior Toggleable(cls, target)\n init\n if cls is undefined\n set cls to \"active\"\n end\n if target is undefined\n set target to me\n end\n end\n on click\n toggle .{cls} on target\n end\nend\n`.trim(),\n};\n"],"mappings":";AAQO,IAAM,mBAAmC;AAAA,EAC9C,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,EACF;AAAA,EACA,QAAQ;AAAA,IACN,EAAE,MAAM,iBAAiB,aAAa,4BAA4B;AAAA,IAClE,EAAE,MAAM,kBAAkB,aAAa,8BAA8B;AAAA,EACvE;AAAA,EACA,QAAQ;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAcR,KAAK;AACP;","names":[]}
1
+ {"version":3,"sources":["../src/schemas/toggleable.schema.ts"],"sourcesContent":["import type { BehaviorSchema } from './types';\n\n/**\n * Toggleable Behavior Schema\n *\n * Toggles a CSS class on click.\n * Useful for accordions, dropdowns, and toggle buttons.\n */\nexport const toggleableSchema: BehaviorSchema = {\n name: 'Toggleable',\n category: 'form',\n tier: 'core',\n version: '1.0.0',\n description: 'Toggles a CSS class on click',\n parameters: [\n {\n name: 'cls',\n type: 'string',\n optional: true,\n default: 'active',\n description: 'CSS class to toggle',\n },\n {\n name: 'target',\n type: 'selector',\n optional: true,\n default: 'me',\n description: 'Element to toggle the class on',\n },\n ],\n events: [\n { name: 'toggleable:on', description: 'Fired when class is added' },\n { name: 'toggleable:off', description: 'Fired when class is removed' },\n ],\n source: `\nbehavior Toggleable(cls, target)\n init\n if cls is undefined\n set cls to \"active\"\n end\n if target is undefined\n set target to me\n end\n end\n on click\n toggle .{cls} on target\n js(target, cls)\n var eventName = target.classList.contains(cls) ? 'toggleable:on' : 'toggleable:off';\n target.dispatchEvent(new CustomEvent(eventName, { bubbles: true }));\n end\n end\nend`.trim(),\n};\n"],"mappings":";AAQO,IAAM,mBAAmC;AAAA,EAC9C,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,EACF;AAAA,EACA,QAAQ;AAAA,IACN,EAAE,MAAM,iBAAiB,aAAa,4BAA4B;AAAA,IAClE,EAAE,MAAM,kBAAkB,aAAa,8BAA8B;AAAA,EACvE;AAAA,EACA,QAAQ;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,KAiBL,KAAK;AACV;","names":[]}
@@ -1,6 +1,6 @@
1
1
  import {
2
2
  clickOutsideSchema
3
- } from "./chunk-64DIQGQI.js";
3
+ } from "./chunk-SLOXO6IY.js";
4
4
  import {
5
5
  resolveRuntime
6
6
  } from "./chunk-6TJXDCAQ.js";
@@ -59,4 +59,4 @@ export {
59
59
  registerClickOutside,
60
60
  clickoutside_default
61
61
  };
62
- //# sourceMappingURL=chunk-DYHBKDKB.js.map
62
+ //# sourceMappingURL=chunk-ZZ2WSAX3.js.map
@@ -1,12 +1,23 @@
1
- "use strict";var HyperFixiBehaviors=(()=>{var a=Object.defineProperty;var d=Object.getOwnPropertyDescriptor;var u=Object.getOwnPropertyNames;var p=Object.prototype.hasOwnProperty;var l=(e,t)=>{for(var i in t)a(e,i,{get:t[i],enumerable:!0})},m=(e,t,i,n)=>{if(t&&typeof t=="object"||typeof t=="function")for(let r of u(t))!p.call(e,r)&&r!==i&&a(e,r,{get:()=>t[r],enumerable:!(n=d(t,r))||n.enumerable});return e};var v=e=>m(a({},"__esModule",{value:!0}),e);var w={};l(w,{clickOutsideMetadata:()=>f,clickOutsideSource:()=>h,default:()=>k,registerClickOutside:()=>c});var o={name:"ClickOutside",category:"ui",tier:"core",version:"1.0.0",description:"Fires an event when the user clicks outside the element",parameters:[{name:"active",type:"boolean",optional:!0,default:!0,description:"Whether the listener is active (can be toggled programmatically)"}],events:[{name:"clickoutside",description:"Fired when a pointer press occurs outside the element"}],requirements:["Uses pointerdown instead of click to avoid timing issues with removed elements"],source:`
1
+ "use strict";var HyperFixiBehaviors=(()=>{var a=Object.defineProperty;var d=Object.getOwnPropertyDescriptor;var u=Object.getOwnPropertyNames;var l=Object.prototype.hasOwnProperty;var m=(e,t)=>{for(var i in t)a(e,i,{get:t[i],enumerable:!0})},p=(e,t,i,n)=>{if(t&&typeof t=="object"||typeof t=="function")for(let o of u(t))!l.call(e,o)&&o!==i&&a(e,o,{get:()=>t[o],enumerable:!(n=d(t,o))||n.enumerable});return e};var v=e=>p(a({},"__esModule",{value:!0}),e);var w={};m(w,{clickOutsideMetadata:()=>f,clickOutsideSource:()=>h,default:()=>k,registerClickOutside:()=>s});var r={name:"ClickOutside",category:"ui",tier:"core",version:"1.0.0",description:"Fires an event when the user clicks outside the element",parameters:[{name:"active",type:"boolean",optional:!0,default:!0,description:"Whether the listener is active (can be toggled programmatically)"}],events:[{name:"clickoutside",description:"Fired when a pointer press occurs outside the element"},{name:"clickoutside:activate",description:"Listen for this event to programmatically activate detection"},{name:"clickoutside:deactivate",description:"Listen for this event to programmatically deactivate detection"}],requirements:["Uses pointerdown instead of click to avoid timing issues with removed elements"],source:`
2
2
  behavior ClickOutside(active)
3
3
  init
4
- if active is undefined set active to true
4
+ if active is undefined
5
+ set active to true
6
+ end
5
7
  end
6
8
  on pointerdown from document
7
- if active and not me.contains(event.target)
8
- trigger clickoutside on me
9
+ js(me, active)
10
+ if (!me.isConnected) return;
11
+ if (active && !me.contains(event.target)) {
12
+ me.dispatchEvent(new CustomEvent('clickoutside', { bubbles: true }));
13
+ }
9
14
  end
10
15
  end
11
- end`.trim()};function s(){if(typeof window>"u")return null;let e=window;return e.lokascript||e.hyperfixi||null}var h=o.source,f=o;function g(e,t){let i=t.active!==!1;function n(r){if(!e.isConnected){document.removeEventListener("pointerdown",n);return}i&&!e.contains(r.target)&&e.dispatchEvent(new CustomEvent("clickoutside",{bubbles:!0}))}document.addEventListener("pointerdown",n),e.addEventListener("clickoutside:activate",()=>{i=!0}),e.addEventListener("clickoutside:deactivate",()=>{i=!1})}async function c(e){let t=e||s();if(!t)throw new Error("LokaScript not found. Make sure @hyperfixi/core is loaded before registering behaviors.");let i={type:"behavior",name:"ClickOutside",parameters:["active"],eventHandlers:[],imperativeInstaller:g},n=t.createContext?t.createContext():{locals:new Map,globals:new Map};await t.execute(i,n)}s()&&c().catch(console.error);var k={source:o.source,metadata:o,register:c};return v(w);})();
16
+ on clickoutside:activate
17
+ set active to true
18
+ end
19
+ on clickoutside:deactivate
20
+ set active to false
21
+ end
22
+ end`.trim()};function c(){if(typeof window>"u")return null;let e=window;return e.lokascript||e.hyperfixi||null}var h=r.source,f=r;function g(e,t){let i=t.active!==!1;function n(o){if(!e.isConnected){document.removeEventListener("pointerdown",n);return}i&&!e.contains(o.target)&&e.dispatchEvent(new CustomEvent("clickoutside",{bubbles:!0}))}document.addEventListener("pointerdown",n),e.addEventListener("clickoutside:activate",()=>{i=!0}),e.addEventListener("clickoutside:deactivate",()=>{i=!1})}async function s(e){let t=e||c();if(!t)throw new Error("LokaScript not found. Make sure @hyperfixi/core is loaded before registering behaviors.");let i={type:"behavior",name:"ClickOutside",parameters:["active"],eventHandlers:[],imperativeInstaller:g},n=t.createContext?t.createContext():{locals:new Map,globals:new Map};await t.execute(i,n)}c()&&s().catch(console.error);var k={source:r.source,metadata:r,register:s};return v(w);})();
12
23
  //# sourceMappingURL=clickoutside.browser.global.js.map
@@ -1 +1 @@
1
- {"version":3,"sources":["../src/behaviors/clickoutside.ts","../src/schemas/clickoutside.schema.ts","../src/schemas/types.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","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","/**\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":"scAAA,IAAAA,EAAA,GAAAC,EAAAD,EAAA,0BAAAE,EAAA,uBAAAC,EAAA,YAAAC,EAAA,yBAAAC,ICQO,IAAMC,EAAqC,CAChD,KAAM,eACN,SAAU,KACV,KAAM,OACN,QAAS,QACT,YAAa,0DACb,WAAY,CACV,CACE,KAAM,SACN,KAAM,UACN,SAAU,GACV,QAAS,GACT,YAAa,kEACf,CACF,EACA,OAAQ,CACN,CAAE,KAAM,eAAgB,YAAa,uDAAwD,CAC/F,EACA,aAAc,CAAC,gFAAgF,EAC/F,OAAQ;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,KAUL,KAAK,CACV,EC4EO,SAASC,GAA4C,CAC1D,GAAI,OAAO,OAAW,IAAa,OAAO,KAC1C,IAAMC,EAAM,OACZ,OAAOA,EAAI,YAAcA,EAAI,WAAa,IAC5C,CF1GO,IAAMC,EAAqBC,EAAmB,OACxCC,EAAuBD,EAKpC,SAASE,EAAoBC,EAAsBC,EAAmC,CACpF,IAAIC,EAASD,EAAO,SAAW,GAE/B,SAASE,EAAcC,EAAU,CAE/B,GAAI,CAACJ,EAAQ,YAAa,CACxB,SAAS,oBAAoB,cAAeG,CAAa,EACzD,MACF,CAEID,GAAU,CAACF,EAAQ,SAASI,EAAE,MAAc,GAC9CJ,EAAQ,cAAc,IAAI,YAAY,eAAgB,CAAE,QAAS,EAAK,CAAC,CAAC,CAE5E,CAEA,SAAS,iBAAiB,cAAeG,CAAa,EAGtDH,EAAQ,iBAAiB,wBAAyB,IAAM,CACtDE,EAAS,EACX,CAAC,EACDF,EAAQ,iBAAiB,0BAA2B,IAAM,CACxDE,EAAS,EACX,CAAC,CACH,CAKA,eAAsBG,EAAqBC,EAA+C,CACxF,IAAMC,EAAKD,GAAaE,EAAe,EAEvC,GAAI,CAACD,EACH,MAAM,IAAI,MACR,yFACF,EAGF,IAAME,EAAgB,CACpB,KAAM,WACN,KAAM,eACN,WAAY,CAAC,QAAQ,EACrB,cAAe,CAAC,EAChB,oBAAqBV,CACvB,EACMW,EAAMH,EAAG,cAAgBA,EAAG,cAAc,EAAI,CAAE,OAAQ,IAAI,IAAO,QAAS,IAAI,GAAM,EAC5F,MAAMA,EAAG,QAAQE,EAAeC,CAAG,CACrC,CAGIF,EAAe,GACjBH,EAAqB,EAAE,MAAM,QAAQ,KAAK,EAG5C,IAAOM,EAAQ,CACb,OAAQd,EAAmB,OAC3B,SAAUA,EACV,SAAUQ,CACZ","names":["clickoutside_exports","__export","clickOutsideMetadata","clickOutsideSource","clickoutside_default","registerClickOutside","clickOutsideSchema","resolveRuntime","win","clickOutsideSource","clickOutsideSchema","clickOutsideMetadata","installClickOutside","element","params","active","onPointerDown","e","registerClickOutside","hyperfixi","hf","resolveRuntime","syntheticNode","ctx","clickoutside_default"]}
1
+ {"version":3,"sources":["../src/behaviors/clickoutside.ts","../src/schemas/clickoutside.schema.ts","../src/schemas/types.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","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 name: 'clickoutside:activate',\n description: 'Listen for this event to programmatically activate detection',\n },\n {\n name: 'clickoutside:deactivate',\n description: 'Listen for this event to programmatically deactivate detection',\n },\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\n set active to true\n end\n end\n on pointerdown from document\n js(me, active)\n if (!me.isConnected) return;\n if (active && !me.contains(event.target)) {\n me.dispatchEvent(new CustomEvent('clickoutside', { bubbles: true }));\n }\n end\n end\n on clickoutside:activate\n set active to true\n end\n on clickoutside:deactivate\n set active to false\n end\nend`.trim(),\n};\n","/**\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":"scAAA,IAAAA,EAAA,GAAAC,EAAAD,EAAA,0BAAAE,EAAA,uBAAAC,EAAA,YAAAC,EAAA,yBAAAC,ICQO,IAAMC,EAAqC,CAChD,KAAM,eACN,SAAU,KACV,KAAM,OACN,QAAS,QACT,YAAa,0DACb,WAAY,CACV,CACE,KAAM,SACN,KAAM,UACN,SAAU,GACV,QAAS,GACT,YAAa,kEACf,CACF,EACA,OAAQ,CACN,CAAE,KAAM,eAAgB,YAAa,uDAAwD,EAC7F,CACE,KAAM,wBACN,YAAa,8DACf,EACA,CACE,KAAM,0BACN,YAAa,gEACf,CACF,EACA,aAAc,CAAC,gFAAgF,EAC/F,OAAQ;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,KAqBL,KAAK,CACV,ECyDO,SAASC,GAA4C,CAC1D,GAAI,OAAO,OAAW,IAAa,OAAO,KAC1C,IAAMC,EAAM,OACZ,OAAOA,EAAI,YAAcA,EAAI,WAAa,IAC5C,CF1GO,IAAMC,EAAqBC,EAAmB,OACxCC,EAAuBD,EAKpC,SAASE,EAAoBC,EAAsBC,EAAmC,CACpF,IAAIC,EAASD,EAAO,SAAW,GAE/B,SAASE,EAAcC,EAAU,CAE/B,GAAI,CAACJ,EAAQ,YAAa,CACxB,SAAS,oBAAoB,cAAeG,CAAa,EACzD,MACF,CAEID,GAAU,CAACF,EAAQ,SAASI,EAAE,MAAc,GAC9CJ,EAAQ,cAAc,IAAI,YAAY,eAAgB,CAAE,QAAS,EAAK,CAAC,CAAC,CAE5E,CAEA,SAAS,iBAAiB,cAAeG,CAAa,EAGtDH,EAAQ,iBAAiB,wBAAyB,IAAM,CACtDE,EAAS,EACX,CAAC,EACDF,EAAQ,iBAAiB,0BAA2B,IAAM,CACxDE,EAAS,EACX,CAAC,CACH,CAKA,eAAsBG,EAAqBC,EAA+C,CACxF,IAAMC,EAAKD,GAAaE,EAAe,EAEvC,GAAI,CAACD,EACH,MAAM,IAAI,MACR,yFACF,EAGF,IAAME,EAAgB,CACpB,KAAM,WACN,KAAM,eACN,WAAY,CAAC,QAAQ,EACrB,cAAe,CAAC,EAChB,oBAAqBV,CACvB,EACMW,EAAMH,EAAG,cAAgBA,EAAG,cAAc,EAAI,CAAE,OAAQ,IAAI,IAAO,QAAS,IAAI,GAAM,EAC5F,MAAMA,EAAG,QAAQE,EAAeC,CAAG,CACrC,CAGIF,EAAe,GACjBH,EAAqB,EAAE,MAAM,QAAQ,KAAK,EAG5C,IAAOM,EAAQ,CACb,OAAQd,EAAmB,OAC3B,SAAUA,EACV,SAAUQ,CACZ","names":["clickoutside_exports","__export","clickOutsideMetadata","clickOutsideSource","clickoutside_default","registerClickOutside","clickOutsideSchema","resolveRuntime","win","clickOutsideSource","clickOutsideSchema","clickOutsideMetadata","installClickOutside","element","params","active","onPointerDown","e","registerClickOutside","hyperfixi","hf","resolveRuntime","syntheticNode","ctx","clickoutside_default"]}
@@ -1,3 +1,44 @@
1
- "use strict";var HyperFixiBehaviors=(()=>{var a=Object.defineProperty;var l=Object.getOwnPropertyDescriptor;var p=Object.getOwnPropertyNames;var u=Object.prototype.hasOwnProperty;var m=(t,e)=>{for(var n in e)a(t,n,{get:e[n],enumerable:!0})},f=(t,e,n,r)=>{if(e&&typeof e=="object"||typeof e=="function")for(let o of p(e))!u.call(t,o)&&o!==n&&a(t,o,{get:()=>e[o],enumerable:!(r=l(e,o))||r.enumerable});return t};var b=t=>f(a({},"__esModule",{value:!0}),t);var g={};m(g,{clipboardMetadata:()=>x,clipboardSource:()=>y,default:()=>h,registerClipboard:()=>s});var i={name:"Clipboard",category:"ui",tier:"core",version:"1.0.0",description:"Copies text to clipboard on click with visual feedback",parameters:[{name:"text",type:"string",optional:!0,description:"Literal text to copy (takes priority over source)"},{name:"source",type:"selector",optional:!0,default:"me",description:"Element whose textContent or value is copied"},{name:"feedback",type:"selector",optional:!0,description:"Element to show .copied feedback on (defaults to the installed element)"},{name:"feedbackDuration",type:"number",optional:!0,default:2e3,description:"Duration in ms to show .copied class feedback"}],events:[{name:"clipboard:copied",description:"Fired after text is copied successfully"},{name:"clipboard:error",description:"Fired when clipboard write fails"}],requirements:["navigator.clipboard.writeText() requires HTTPS or localhost",'Falls back to document.execCommand("copy") for older browsers'],source:["behavior Clipboard(text, source, feedback, feedbackDuration)"," init"," if feedbackDuration is undefined set feedbackDuration to 2000"," if source is undefined set source to me"," end"," on click"," if text is not undefined"," set copyText to text"," else"," set copyText to source's value or source's textContent"," end"," js(copyText) navigator.clipboard.writeText(copyText) end"," set feedbackEl to feedback or me"," add .copied to feedbackEl"," wait feedbackDuration ms"," remove .copied from feedbackEl"," trigger clipboard:copied"," end","end"].join(`
2
- `)};function c(){if(typeof window>"u")return null;let t=window;return t.lokascript||t.hyperfixi||null}var y=i.source,x=i;async function k(t){if(navigator.clipboard?.writeText){await navigator.clipboard.writeText(t);return}let e=document.createElement("textarea");e.value=t,e.style.position="fixed",e.style.opacity="0",document.body.appendChild(e),e.select();try{document.execCommand("copy")}finally{document.body.removeChild(e)}}function d(t,e){return!e||e==="me"?t:e instanceof HTMLElement?e:typeof e=="string"&&(t.querySelector(e)||document.querySelector(e))||null}function v(t,e){let n=typeof e.feedbackDuration=="number"?e.feedbackDuration:2e3;t.addEventListener("click",async()=>{let r;if(e.text!=null)r=String(e.text);else{let o=d(t,e.source)||t;r=o.value??o.textContent??""}try{await k(r);let o=d(t,e.feedback)||t;o.classList.add("copied"),setTimeout(()=>o.classList.remove("copied"),n),t.dispatchEvent(new CustomEvent("clipboard:copied",{bubbles:!0,detail:{text:r}}))}catch(o){t.dispatchEvent(new CustomEvent("clipboard:error",{bubbles:!0,detail:{error:o}}))}})}async function s(t){let e=t||c();if(!e)throw new Error("LokaScript not found. Make sure @hyperfixi/core is loaded before registering behaviors.");let n={type:"behavior",name:"Clipboard",parameters:["text","source","feedback","feedbackDuration"],eventHandlers:[],imperativeInstaller:v},r=e.createContext?e.createContext():{locals:new Map,globals:new Map};await e.execute(n,r)}c()&&s().catch(console.error);var h={source:i.source,metadata:i,register:s};return b(g);})();
1
+ "use strict";var HyperFixiBehaviors=(()=>{var a=Object.defineProperty;var l=Object.getOwnPropertyDescriptor;var p=Object.getOwnPropertyNames;var u=Object.prototype.hasOwnProperty;var m=(t,e)=>{for(var n in e)a(t,n,{get:e[n],enumerable:!0})},b=(t,e,n,r)=>{if(e&&typeof e=="object"||typeof e=="function")for(let o of p(e))!u.call(t,o)&&o!==n&&a(t,o,{get:()=>e[o],enumerable:!(r=l(e,o))||r.enumerable});return t};var f=t=>b(a({},"__esModule",{value:!0}),t);var g={};m(g,{clipboardMetadata:()=>x,clipboardSource:()=>y,default:()=>h,registerClipboard:()=>s});var i={name:"Clipboard",category:"ui",tier:"core",version:"1.0.0",description:"Copies text to clipboard on click with visual feedback",parameters:[{name:"text",type:"string",optional:!0,description:"Literal text to copy (takes priority over source)"},{name:"source",type:"selector",optional:!0,default:"me",description:"Element whose textContent or value is copied"},{name:"feedback",type:"selector",optional:!0,description:"Element to show .copied feedback on (defaults to the installed element)"},{name:"feedbackDuration",type:"number",optional:!0,default:2e3,description:"Duration in ms to show .copied class feedback"}],events:[{name:"clipboard:copied",description:"Fired after text is copied successfully"},{name:"clipboard:error",description:"Fired when clipboard write fails"}],requirements:["navigator.clipboard.writeText() requires HTTPS or localhost",'Falls back to document.execCommand("copy") for older browsers'],source:`
2
+ behavior Clipboard(text, source, feedback, feedbackDuration)
3
+ init
4
+ if feedbackDuration is undefined
5
+ set feedbackDuration to 2000
6
+ end
7
+ if source is undefined
8
+ set source to me
9
+ end
10
+ end
11
+ on click
12
+ if text is not undefined
13
+ set copyText to text
14
+ else
15
+ set copyText to source's textContent
16
+ end
17
+ js(me, copyText, feedback, feedbackDuration)
18
+ async function copyToClipboard(t) {
19
+ if (navigator.clipboard && navigator.clipboard.writeText) {
20
+ await navigator.clipboard.writeText(t);
21
+ return;
22
+ }
23
+ var ta = document.createElement('textarea');
24
+ ta.value = t;
25
+ ta.style.position = 'fixed';
26
+ ta.style.opacity = '0';
27
+ document.body.appendChild(ta);
28
+ ta.select();
29
+ try { document.execCommand('copy'); } finally { document.body.removeChild(ta); }
30
+ }
31
+ try {
32
+ await copyToClipboard(copyText);
33
+ var feedbackEl = feedback ? (typeof feedback === 'string' ? document.querySelector(feedback) : feedback) : me;
34
+ if (!feedbackEl) feedbackEl = me;
35
+ feedbackEl.classList.add('copied');
36
+ me.dispatchEvent(new CustomEvent('clipboard:copied', { bubbles: true, detail: { text: copyText } }));
37
+ setTimeout(function() { feedbackEl.classList.remove('copied'); }, feedbackDuration);
38
+ } catch(err) {
39
+ me.dispatchEvent(new CustomEvent('clipboard:error', { bubbles: true, detail: { error: err } }));
40
+ }
41
+ end
42
+ end
43
+ end`.trim()};function c(){if(typeof window>"u")return null;let t=window;return t.lokascript||t.hyperfixi||null}var y=i.source,x=i;async function v(t){if(navigator.clipboard?.writeText){await navigator.clipboard.writeText(t);return}let e=document.createElement("textarea");e.value=t,e.style.position="fixed",e.style.opacity="0",document.body.appendChild(e),e.select();try{document.execCommand("copy")}finally{document.body.removeChild(e)}}function d(t,e){return!e||e==="me"?t:e instanceof HTMLElement?e:typeof e=="string"&&(t.querySelector(e)||document.querySelector(e))||null}function k(t,e){let n=typeof e.feedbackDuration=="number"?e.feedbackDuration:2e3;t.addEventListener("click",async()=>{let r;if(e.text!=null)r=String(e.text);else{let o=d(t,e.source)||t;r=o.value??o.textContent??""}try{await v(r);let o=d(t,e.feedback)||t;o.classList.add("copied"),setTimeout(()=>o.classList.remove("copied"),n),t.dispatchEvent(new CustomEvent("clipboard:copied",{bubbles:!0,detail:{text:r}}))}catch(o){t.dispatchEvent(new CustomEvent("clipboard:error",{bubbles:!0,detail:{error:o}}))}})}async function s(t){let e=t||c();if(!e)throw new Error("LokaScript not found. Make sure @hyperfixi/core is loaded before registering behaviors.");let n={type:"behavior",name:"Clipboard",parameters:["text","source","feedback","feedbackDuration"],eventHandlers:[],imperativeInstaller:k},r=e.createContext?e.createContext():{locals:new Map,globals:new Map};await e.execute(n,r)}c()&&s().catch(console.error);var h={source:i.source,metadata:i,register:s};return f(g);})();
3
44
  //# sourceMappingURL=clipboard.browser.global.js.map
@@ -1 +1 @@
1
- {"version":3,"sources":["../src/behaviors/clipboard.ts","../src/schemas/clipboard.schema.ts","../src/schemas/types.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","import type { BehaviorSchema } from './types';\n\n/**\n * Clipboard Behavior Schema\n *\n * Copies text to clipboard on click with visual feedback.\n * Uses the Clipboard API with execCommand fallback.\n */\nexport const clipboardSchema: BehaviorSchema = {\n name: 'Clipboard',\n category: 'ui',\n tier: 'core',\n version: '1.0.0',\n description: 'Copies text to clipboard on click with visual feedback',\n parameters: [\n {\n name: 'text',\n type: 'string',\n optional: true,\n description: 'Literal text to copy (takes priority over source)',\n },\n {\n name: 'source',\n type: 'selector',\n optional: true,\n default: 'me',\n description: 'Element whose textContent or value is copied',\n },\n {\n name: 'feedback',\n type: 'selector',\n optional: true,\n description: 'Element to show .copied feedback on (defaults to the installed element)',\n },\n {\n name: 'feedbackDuration',\n type: 'number',\n optional: true,\n default: 2000,\n description: 'Duration in ms to show .copied class feedback',\n },\n ],\n events: [\n { name: 'clipboard:copied', description: 'Fired after text is copied successfully' },\n { name: 'clipboard:error', description: 'Fired when clipboard write fails' },\n ],\n requirements: [\n 'navigator.clipboard.writeText() requires HTTPS or localhost',\n 'Falls back to document.execCommand(\"copy\") for older browsers',\n ],\n source: [\n 'behavior Clipboard(text, source, feedback, feedbackDuration)',\n ' init',\n ' if feedbackDuration is undefined set feedbackDuration to 2000',\n ' if source is undefined set source to me',\n ' end',\n ' on click',\n ' if text is not undefined',\n ' set copyText to text',\n ' else',\n \" set copyText to source's value or source's textContent\",\n ' end',\n ' js(copyText) navigator.clipboard.writeText(copyText) end',\n ' set feedbackEl to feedback or me',\n ' add .copied to feedbackEl',\n ' wait feedbackDuration ms',\n ' remove .copied from feedbackEl',\n ' trigger clipboard:copied',\n ' end',\n 'end',\n ].join('\\n'),\n};\n","/**\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":"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","names":["clipboard_exports","__export","clipboardMetadata","clipboardSource","clipboard_default","registerClipboard","clipboardSchema","resolveRuntime","win","clipboardSource","clipboardSchema","clipboardMetadata","copyToClipboard","text","textarea","resolveElement","element","param","installClipboard","params","feedbackDuration","copyText","sourceEl","feedbackEl","error","registerClipboard","hyperfixi","hf","resolveRuntime","syntheticNode","ctx","clipboard_default"]}
1
+ {"version":3,"sources":["../src/behaviors/clipboard.ts","../src/schemas/clipboard.schema.ts","../src/schemas/types.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","import type { BehaviorSchema } from './types';\n\n/**\n * Clipboard Behavior Schema\n *\n * Copies text to clipboard on click with visual feedback.\n * Uses the Clipboard API with execCommand fallback.\n */\nexport const clipboardSchema: BehaviorSchema = {\n name: 'Clipboard',\n category: 'ui',\n tier: 'core',\n version: '1.0.0',\n description: 'Copies text to clipboard on click with visual feedback',\n parameters: [\n {\n name: 'text',\n type: 'string',\n optional: true,\n description: 'Literal text to copy (takes priority over source)',\n },\n {\n name: 'source',\n type: 'selector',\n optional: true,\n default: 'me',\n description: 'Element whose textContent or value is copied',\n },\n {\n name: 'feedback',\n type: 'selector',\n optional: true,\n description: 'Element to show .copied feedback on (defaults to the installed element)',\n },\n {\n name: 'feedbackDuration',\n type: 'number',\n optional: true,\n default: 2000,\n description: 'Duration in ms to show .copied class feedback',\n },\n ],\n events: [\n { name: 'clipboard:copied', description: 'Fired after text is copied successfully' },\n { name: 'clipboard:error', description: 'Fired when clipboard write fails' },\n ],\n requirements: [\n 'navigator.clipboard.writeText() requires HTTPS or localhost',\n 'Falls back to document.execCommand(\"copy\") for older browsers',\n ],\n source: `\nbehavior Clipboard(text, source, feedback, feedbackDuration)\n init\n if feedbackDuration is undefined\n set feedbackDuration to 2000\n end\n if source is undefined\n set source to me\n end\n end\n on click\n if text is not undefined\n set copyText to text\n else\n set copyText to source's textContent\n end\n js(me, copyText, feedback, feedbackDuration)\n async function copyToClipboard(t) {\n if (navigator.clipboard && navigator.clipboard.writeText) {\n await navigator.clipboard.writeText(t);\n return;\n }\n var ta = document.createElement('textarea');\n ta.value = t;\n ta.style.position = 'fixed';\n ta.style.opacity = '0';\n document.body.appendChild(ta);\n ta.select();\n try { document.execCommand('copy'); } finally { document.body.removeChild(ta); }\n }\n try {\n await copyToClipboard(copyText);\n var feedbackEl = feedback ? (typeof feedback === 'string' ? document.querySelector(feedback) : feedback) : me;\n if (!feedbackEl) feedbackEl = me;\n feedbackEl.classList.add('copied');\n me.dispatchEvent(new CustomEvent('clipboard:copied', { bubbles: true, detail: { text: copyText } }));\n setTimeout(function() { feedbackEl.classList.remove('copied'); }, feedbackDuration);\n } catch(err) {\n me.dispatchEvent(new CustomEvent('clipboard:error', { bubbles: true, detail: { error: err } }));\n }\n end\n end\nend`.trim(),\n};\n","/**\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":"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","names":["clipboard_exports","__export","clipboardMetadata","clipboardSource","clipboard_default","registerClipboard","clipboardSchema","resolveRuntime","win","clipboardSource","clipboardSchema","clipboardMetadata","copyToClipboard","text","textarea","resolveElement","element","param","installClipboard","params","feedbackDuration","copyText","sourceEl","feedbackEl","error","registerClipboard","hyperfixi","hf","resolveRuntime","syntheticNode","ctx","clipboard_default"]}
@@ -33,7 +33,10 @@ behavior Toggleable(cls, target)
33
33
  end
34
34
  on click
35
35
  toggle .{cls} on target
36
+ js(target, cls)
37
+ var eventName = target.classList.contains(cls) ? 'toggleable:on' : 'toggleable:off';
38
+ target.dispatchEvent(new CustomEvent(eventName, { bubbles: true }));
39
+ end
36
40
  end
37
- end
38
- `.trim()};var v=l.source,h=l;function I(t,e){let r=e.cls||"active",o=t;if(e.target&&e.target!=="me")if(typeof e.target=="string"){let n=document.querySelector(e.target);n instanceof HTMLElement&&(o=n)}else e.target instanceof HTMLElement&&(o=e.target);t.addEventListener("click",()=>{let n=o.classList.contains(r);o.classList.toggle(r),o.dispatchEvent(new CustomEvent(n?"toggleable:off":"toggleable:on",{bubbles:!0}))})}async function s(t){let e=t||a();if(!e)throw new Error("LokaScript not found. Make sure @hyperfixi/core is loaded before registering behaviors.");let r={type:"behavior",name:"Toggleable",parameters:["cls","target"],eventHandlers:[],imperativeInstaller:I},o=e.createContext?e.createContext():{locals:new Map,globals:new Map};await e.execute(r,o)}a()&&s().catch(console.error);var N={source:l.source,metadata:l,register:s};async function y(t){await Promise.all([i(t),s(t)])}var d=null;typeof window<"u"&&window.lokascript&&(d=y(),d.catch(t=>{console.error("[behaviors] Core auto-registration failed:",t)}));return T(P);})();
41
+ end`.trim()};var v=l.source,h=l;function I(t,e){let r=e.cls||"active",o=t;if(e.target&&e.target!=="me")if(typeof e.target=="string"){let n=document.querySelector(e.target);n instanceof HTMLElement&&(o=n)}else e.target instanceof HTMLElement&&(o=e.target);t.addEventListener("click",()=>{let n=o.classList.contains(r);o.classList.toggle(r),o.dispatchEvent(new CustomEvent(n?"toggleable:off":"toggleable:on",{bubbles:!0}))})}async function s(t){let e=t||a();if(!e)throw new Error("LokaScript not found. Make sure @hyperfixi/core is loaded before registering behaviors.");let r={type:"behavior",name:"Toggleable",parameters:["cls","target"],eventHandlers:[],imperativeInstaller:I},o=e.createContext?e.createContext():{locals:new Map,globals:new Map};await e.execute(r,o)}a()&&s().catch(console.error);var $={source:l.source,metadata:l,register:s};async function y(t){await Promise.all([i(t),s(t)])}var d=null;typeof window<"u"&&window.lokascript&&(d=y(),d.catch(t=>{console.error("[behaviors] Core auto-registration failed:",t)}));return T(P);})();
39
42
  //# sourceMappingURL=core.browser.global.js.map
@@ -1 +1 @@
1
- {"version":3,"sources":["../src/core-bundle.ts","../src/schemas/draggable.schema.ts","../src/schemas/types.ts","../src/behaviors/draggable.ts","../src/schemas/toggleable.schema.ts","../src/behaviors/toggleable.ts"],"sourcesContent":["/**\n * Core Tier Bundle\n *\n * Includes only core tier behaviors (Draggable, Toggleable).\n * Use this for minimal bundle size when you only need essential behaviors.\n */\n\nexport { registerDraggable, draggableSource, draggableMetadata } from './behaviors/draggable';\n\nexport { registerToggleable, toggleableSource, toggleableMetadata } from './behaviors/toggleable';\n\nimport { registerDraggable } from './behaviors/draggable';\nimport { registerToggleable } from './behaviors/toggleable';\nimport type { LokaScriptInstance, LokaScriptWindow } from './schemas/types';\n\n/**\n * Register all core tier behaviors.\n */\nexport async function registerCore(hyperfixi?: LokaScriptInstance): Promise<void> {\n await Promise.all([registerDraggable(hyperfixi), registerToggleable(hyperfixi)]);\n}\n\n/**\n * Promise that resolves when core behaviors are registered.\n * Set when the package auto-registers in browser environments.\n */\nexport let ready: Promise<void> | null = null;\n\n// Auto-register when loaded in browser\nif (typeof window !== 'undefined' && (window as unknown as LokaScriptWindow).lokascript) {\n ready = registerCore();\n ready.catch(err => {\n console.error('[behaviors] Core auto-registration failed:', err);\n });\n}\n","import type { BehaviorSchema } from './types';\n\n/**\n * Draggable Behavior Schema\n *\n * Makes elements draggable with pointer events.\n * Supports custom drag handles and lifecycle events.\n */\nexport const draggableSchema: BehaviorSchema = {\n name: 'Draggable',\n category: 'ui',\n tier: 'core',\n version: '1.0.0',\n description: 'Makes elements draggable with pointer events',\n parameters: [\n {\n name: 'dragHandle',\n type: 'selector',\n optional: true,\n default: 'me',\n description: 'CSS selector for the drag handle element',\n },\n ],\n events: [\n { name: 'draggable:start', description: 'Fired when drag begins' },\n { name: 'draggable:move', description: 'Fired during each movement' },\n { name: 'draggable:end', description: 'Fired when drag completes' },\n ],\n requirements: ['position: absolute or position: fixed on the element'],\n source: `\nbehavior Draggable(dragHandle)\n init\n if no dragHandle set dragHandle to me\n end\n on pointerdown(clientX, clientY) from dragHandle\n halt the event\n trigger draggable:start\n measure x\n set startX to it\n measure y\n set startY to it\n set xoff to clientX - startX\n set yoff to clientY - startY\n repeat until event pointerup from document\n wait for pointermove(clientX, clientY) or\n pointerup(clientX, clientY) from document\n add { left: \\${clientX - xoff}px; top: \\${clientY - yoff}px; }\n trigger draggable:move\n end\n trigger draggable:end\n end\nend\n`.trim(),\n};\n","/**\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","/**\n * Draggable Behavior — Imperative Implementation\n *\n * Makes elements draggable with pointer events.\n * Uses direct DOM APIs instead of compiling hyperscript source,\n * bypassing the complex repeat-until-event + wait-for async pattern.\n *\n * @example\n * ```html\n * <!-- Basic usage -->\n * <div _=\"install Draggable\">Drag me!</div>\n *\n * <!-- With custom drag handle -->\n * <div _=\"install Draggable(dragHandle: .titlebar)\">\n * <div class=\"titlebar\">Drag here</div>\n * <div class=\"content\">Content</div>\n * </div>\n * ```\n */\n\nimport { draggableSchema } from '../schemas/draggable.schema';\nimport type { LokaScriptInstance } from '../schemas/types';\nimport { resolveRuntime } from '../schemas/types';\n\n// Re-export schema-derived values for backwards compatibility\nexport const draggableSource = draggableSchema.source;\nexport const draggableMetadata = draggableSchema;\n\n/**\n * Imperative installer for Draggable behavior.\n * Called directly by the runtime when `install Draggable` is executed.\n */\nfunction installDraggable(element: HTMLElement, params: Record<string, any>): void {\n // Resolve drag handle: parameter value, CSS selector, or the element itself\n let dragHandle: HTMLElement = element;\n if (params.dragHandle && params.dragHandle !== 'me') {\n if (typeof params.dragHandle === 'string') {\n const found = element.querySelector(params.dragHandle);\n if (found instanceof HTMLElement) dragHandle = found;\n } else if (params.dragHandle instanceof HTMLElement) {\n dragHandle = params.dragHandle;\n }\n }\n\n dragHandle.addEventListener('pointerdown', (e: PointerEvent) => {\n e.preventDefault();\n e.stopPropagation();\n element.dispatchEvent(new CustomEvent('draggable:start', { bubbles: true }));\n\n const startX = element.offsetLeft;\n const startY = element.offsetTop;\n const xoff = e.clientX - startX;\n const yoff = e.clientY - startY;\n\n function onMove(ev: PointerEvent) {\n element.style.left = `${ev.clientX - xoff}px`;\n element.style.top = `${ev.clientY - yoff}px`;\n element.dispatchEvent(new CustomEvent('draggable:move', { bubbles: true }));\n }\n\n function onUp() {\n document.removeEventListener('pointermove', onMove);\n document.removeEventListener('pointerup', onUp);\n element.dispatchEvent(new CustomEvent('draggable:end', { bubbles: true }));\n }\n\n document.addEventListener('pointermove', onMove);\n document.addEventListener('pointerup', onUp);\n });\n}\n\n/**\n * Register the Draggable behavior with LokaScript.\n * Uses imperative installer via synthetic behavior node.\n */\nexport async function registerDraggable(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 // Register via execute() with a synthetic behavior node containing the imperative installer.\n // The runtime detects imperativeInstaller and stores it directly in the behaviorRegistry.\n const syntheticNode = {\n type: 'behavior',\n name: 'Draggable',\n parameters: ['dragHandle'],\n eventHandlers: [],\n imperativeInstaller: installDraggable,\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 registerDraggable().catch(console.error);\n}\n\nexport default {\n source: draggableSchema.source,\n metadata: draggableSchema,\n register: registerDraggable,\n};\n","import type { BehaviorSchema } from './types';\n\n/**\n * Toggleable Behavior Schema\n *\n * Toggles a CSS class on click.\n * Useful for accordions, dropdowns, and toggle buttons.\n */\nexport const toggleableSchema: BehaviorSchema = {\n name: 'Toggleable',\n category: 'form',\n tier: 'core',\n version: '1.0.0',\n description: 'Toggles a CSS class on click',\n parameters: [\n {\n name: 'cls',\n type: 'string',\n optional: true,\n default: 'active',\n description: 'CSS class to toggle',\n },\n {\n name: 'target',\n type: 'selector',\n optional: true,\n default: 'me',\n description: 'Element to toggle the class on',\n },\n ],\n events: [\n { name: 'toggleable:on', description: 'Fired when class is added' },\n { name: 'toggleable:off', description: 'Fired when class is removed' },\n ],\n source: `\nbehavior Toggleable(cls, target)\n init\n if cls is undefined\n set cls to \"active\"\n end\n if target is undefined\n set target to me\n end\n end\n on click\n toggle .{cls} on target\n end\nend\n`.trim(),\n};\n","/**\n * Toggleable Behavior — Imperative Implementation\n *\n * A behavior that toggles a CSS class on click.\n * Useful for accordions, dropdowns, and toggle buttons.\n *\n * Uses direct DOM APIs instead of compiling hyperscript source,\n * because `toggle .{cls}` template interpolation doesn't resolve\n * behavior parameters at runtime.\n *\n * @example\n * ```html\n * <button _=\"install Toggleable\">Toggle</button>\n *\n * <button _=\"install Toggleable(cls: expanded, target: #menu)\">Menu</button>\n * ```\n */\n\nimport { toggleableSchema } from '../schemas/toggleable.schema';\nimport type { LokaScriptInstance } from '../schemas/types';\nimport { resolveRuntime } from '../schemas/types';\n\n// Re-export schema-derived values for backwards compatibility\nexport const toggleableSource = toggleableSchema.source;\nexport const toggleableMetadata = toggleableSchema;\n\n/**\n * Imperative installer for Toggleable behavior.\n * Called directly by the runtime when `install Toggleable` is executed.\n */\nfunction installToggleable(element: HTMLElement, params: Record<string, any>): void {\n const cls = params.cls || 'active';\n\n // Resolve target element\n let targetEl: HTMLElement = element;\n if (params.target && params.target !== 'me') {\n if (typeof params.target === 'string') {\n const found = document.querySelector(params.target);\n if (found instanceof HTMLElement) targetEl = found;\n } else if (params.target instanceof HTMLElement) {\n targetEl = params.target;\n }\n }\n\n element.addEventListener('click', () => {\n const wasOn = targetEl.classList.contains(cls);\n targetEl.classList.toggle(cls);\n targetEl.dispatchEvent(\n new CustomEvent(wasOn ? 'toggleable:off' : 'toggleable:on', { bubbles: true })\n );\n });\n}\n\n/**\n * Register the Toggleable behavior with LokaScript.\n * Uses imperative installer via synthetic behavior node.\n */\nexport async function registerToggleable(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: 'Toggleable',\n parameters: ['cls', 'target'],\n eventHandlers: [],\n imperativeInstaller: installToggleable,\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 registerToggleable().catch(console.error);\n}\n\nexport default {\n source: toggleableSchema.source,\n metadata: toggleableSchema,\n register: registerToggleable,\n};\n"],"mappings":"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","names":["core_bundle_exports","__export","draggableMetadata","draggableSource","ready","registerCore","registerDraggable","registerToggleable","toggleableMetadata","toggleableSource","draggableSchema","resolveRuntime","win","draggableSource","draggableSchema","draggableMetadata","installDraggable","element","params","dragHandle","found","e","startX","startY","xoff","yoff","onMove","ev","onUp","registerDraggable","hyperfixi","hf","resolveRuntime","syntheticNode","ctx","draggable_default","toggleableSchema","toggleableSource","toggleableSchema","toggleableMetadata","installToggleable","element","params","cls","targetEl","found","wasOn","registerToggleable","hyperfixi","hf","resolveRuntime","syntheticNode","ctx","toggleable_default","registerCore","hyperfixi","registerDraggable","registerToggleable","ready","err"]}
1
+ {"version":3,"sources":["../src/core-bundle.ts","../src/schemas/draggable.schema.ts","../src/schemas/types.ts","../src/behaviors/draggable.ts","../src/schemas/toggleable.schema.ts","../src/behaviors/toggleable.ts"],"sourcesContent":["/**\n * Core Tier Bundle\n *\n * Includes only core tier behaviors (Draggable, Toggleable).\n * Use this for minimal bundle size when you only need essential behaviors.\n */\n\nexport { registerDraggable, draggableSource, draggableMetadata } from './behaviors/draggable';\n\nexport { registerToggleable, toggleableSource, toggleableMetadata } from './behaviors/toggleable';\n\nimport { registerDraggable } from './behaviors/draggable';\nimport { registerToggleable } from './behaviors/toggleable';\nimport type { LokaScriptInstance, LokaScriptWindow } from './schemas/types';\n\n/**\n * Register all core tier behaviors.\n */\nexport async function registerCore(hyperfixi?: LokaScriptInstance): Promise<void> {\n await Promise.all([registerDraggable(hyperfixi), registerToggleable(hyperfixi)]);\n}\n\n/**\n * Promise that resolves when core behaviors are registered.\n * Set when the package auto-registers in browser environments.\n */\nexport let ready: Promise<void> | null = null;\n\n// Auto-register when loaded in browser\nif (typeof window !== 'undefined' && (window as unknown as LokaScriptWindow).lokascript) {\n ready = registerCore();\n ready.catch(err => {\n console.error('[behaviors] Core auto-registration failed:', err);\n });\n}\n","import type { BehaviorSchema } from './types';\n\n/**\n * Draggable Behavior Schema\n *\n * Makes elements draggable with pointer events.\n * Supports custom drag handles and lifecycle events.\n */\nexport const draggableSchema: BehaviorSchema = {\n name: 'Draggable',\n category: 'ui',\n tier: 'core',\n version: '1.0.0',\n description: 'Makes elements draggable with pointer events',\n parameters: [\n {\n name: 'dragHandle',\n type: 'selector',\n optional: true,\n default: 'me',\n description: 'CSS selector for the drag handle element',\n },\n ],\n events: [\n { name: 'draggable:start', description: 'Fired when drag begins' },\n { name: 'draggable:move', description: 'Fired during each movement' },\n { name: 'draggable:end', description: 'Fired when drag completes' },\n ],\n requirements: ['position: absolute or position: fixed on the element'],\n source: `\nbehavior Draggable(dragHandle)\n init\n if no dragHandle set dragHandle to me\n end\n on pointerdown(clientX, clientY) from dragHandle\n halt the event\n trigger draggable:start\n measure x\n set startX to it\n measure y\n set startY to it\n set xoff to clientX - startX\n set yoff to clientY - startY\n repeat until event pointerup from document\n wait for pointermove(clientX, clientY) or\n pointerup(clientX, clientY) from document\n add { left: \\${clientX - xoff}px; top: \\${clientY - yoff}px; }\n trigger draggable:move\n end\n trigger draggable:end\n end\nend\n`.trim(),\n};\n","/**\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","/**\n * Draggable Behavior — Imperative Implementation\n *\n * Makes elements draggable with pointer events.\n * Uses direct DOM APIs instead of compiling hyperscript source,\n * bypassing the complex repeat-until-event + wait-for async pattern.\n *\n * @example\n * ```html\n * <!-- Basic usage -->\n * <div _=\"install Draggable\">Drag me!</div>\n *\n * <!-- With custom drag handle -->\n * <div _=\"install Draggable(dragHandle: .titlebar)\">\n * <div class=\"titlebar\">Drag here</div>\n * <div class=\"content\">Content</div>\n * </div>\n * ```\n */\n\nimport { draggableSchema } from '../schemas/draggable.schema';\nimport type { LokaScriptInstance } from '../schemas/types';\nimport { resolveRuntime } from '../schemas/types';\n\n// Re-export schema-derived values for backwards compatibility\nexport const draggableSource = draggableSchema.source;\nexport const draggableMetadata = draggableSchema;\n\n/**\n * Imperative installer for Draggable behavior.\n * Called directly by the runtime when `install Draggable` is executed.\n */\nfunction installDraggable(element: HTMLElement, params: Record<string, any>): void {\n // Resolve drag handle: parameter value, CSS selector, or the element itself\n let dragHandle: HTMLElement = element;\n if (params.dragHandle && params.dragHandle !== 'me') {\n if (typeof params.dragHandle === 'string') {\n const found = element.querySelector(params.dragHandle);\n if (found instanceof HTMLElement) dragHandle = found;\n } else if (params.dragHandle instanceof HTMLElement) {\n dragHandle = params.dragHandle;\n }\n }\n\n dragHandle.addEventListener('pointerdown', (e: PointerEvent) => {\n e.preventDefault();\n e.stopPropagation();\n element.dispatchEvent(new CustomEvent('draggable:start', { bubbles: true }));\n\n const startX = element.offsetLeft;\n const startY = element.offsetTop;\n const xoff = e.clientX - startX;\n const yoff = e.clientY - startY;\n\n function onMove(ev: PointerEvent) {\n element.style.left = `${ev.clientX - xoff}px`;\n element.style.top = `${ev.clientY - yoff}px`;\n element.dispatchEvent(new CustomEvent('draggable:move', { bubbles: true }));\n }\n\n function onUp() {\n document.removeEventListener('pointermove', onMove);\n document.removeEventListener('pointerup', onUp);\n element.dispatchEvent(new CustomEvent('draggable:end', { bubbles: true }));\n }\n\n document.addEventListener('pointermove', onMove);\n document.addEventListener('pointerup', onUp);\n });\n}\n\n/**\n * Register the Draggable behavior with LokaScript.\n * Uses imperative installer via synthetic behavior node.\n */\nexport async function registerDraggable(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 // Register via execute() with a synthetic behavior node containing the imperative installer.\n // The runtime detects imperativeInstaller and stores it directly in the behaviorRegistry.\n const syntheticNode = {\n type: 'behavior',\n name: 'Draggable',\n parameters: ['dragHandle'],\n eventHandlers: [],\n imperativeInstaller: installDraggable,\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 registerDraggable().catch(console.error);\n}\n\nexport default {\n source: draggableSchema.source,\n metadata: draggableSchema,\n register: registerDraggable,\n};\n","import type { BehaviorSchema } from './types';\n\n/**\n * Toggleable Behavior Schema\n *\n * Toggles a CSS class on click.\n * Useful for accordions, dropdowns, and toggle buttons.\n */\nexport const toggleableSchema: BehaviorSchema = {\n name: 'Toggleable',\n category: 'form',\n tier: 'core',\n version: '1.0.0',\n description: 'Toggles a CSS class on click',\n parameters: [\n {\n name: 'cls',\n type: 'string',\n optional: true,\n default: 'active',\n description: 'CSS class to toggle',\n },\n {\n name: 'target',\n type: 'selector',\n optional: true,\n default: 'me',\n description: 'Element to toggle the class on',\n },\n ],\n events: [\n { name: 'toggleable:on', description: 'Fired when class is added' },\n { name: 'toggleable:off', description: 'Fired when class is removed' },\n ],\n source: `\nbehavior Toggleable(cls, target)\n init\n if cls is undefined\n set cls to \"active\"\n end\n if target is undefined\n set target to me\n end\n end\n on click\n toggle .{cls} on target\n js(target, cls)\n var eventName = target.classList.contains(cls) ? 'toggleable:on' : 'toggleable:off';\n target.dispatchEvent(new CustomEvent(eventName, { bubbles: true }));\n end\n end\nend`.trim(),\n};\n","/**\n * Toggleable Behavior — Imperative Implementation\n *\n * A behavior that toggles a CSS class on click.\n * Useful for accordions, dropdowns, and toggle buttons.\n *\n * Uses direct DOM APIs instead of compiling hyperscript source,\n * because `toggle .{cls}` template interpolation doesn't resolve\n * behavior parameters at runtime.\n *\n * @example\n * ```html\n * <button _=\"install Toggleable\">Toggle</button>\n *\n * <button _=\"install Toggleable(cls: expanded, target: #menu)\">Menu</button>\n * ```\n */\n\nimport { toggleableSchema } from '../schemas/toggleable.schema';\nimport type { LokaScriptInstance } from '../schemas/types';\nimport { resolveRuntime } from '../schemas/types';\n\n// Re-export schema-derived values for backwards compatibility\nexport const toggleableSource = toggleableSchema.source;\nexport const toggleableMetadata = toggleableSchema;\n\n/**\n * Imperative installer for Toggleable behavior.\n * Called directly by the runtime when `install Toggleable` is executed.\n */\nfunction installToggleable(element: HTMLElement, params: Record<string, any>): void {\n const cls = params.cls || 'active';\n\n // Resolve target element\n let targetEl: HTMLElement = element;\n if (params.target && params.target !== 'me') {\n if (typeof params.target === 'string') {\n const found = document.querySelector(params.target);\n if (found instanceof HTMLElement) targetEl = found;\n } else if (params.target instanceof HTMLElement) {\n targetEl = params.target;\n }\n }\n\n element.addEventListener('click', () => {\n const wasOn = targetEl.classList.contains(cls);\n targetEl.classList.toggle(cls);\n targetEl.dispatchEvent(\n new CustomEvent(wasOn ? 'toggleable:off' : 'toggleable:on', { bubbles: true })\n );\n });\n}\n\n/**\n * Register the Toggleable behavior with LokaScript.\n * Uses imperative installer via synthetic behavior node.\n */\nexport async function registerToggleable(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: 'Toggleable',\n parameters: ['cls', 'target'],\n eventHandlers: [],\n imperativeInstaller: installToggleable,\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 registerToggleable().catch(console.error);\n}\n\nexport default {\n source: toggleableSchema.source,\n metadata: toggleableSchema,\n register: registerToggleable,\n};\n"],"mappings":"scAAA,IAAAA,EAAA,GAAAC,EAAAD,EAAA,uBAAAE,EAAA,oBAAAC,EAAA,UAAAC,EAAA,iBAAAC,EAAA,sBAAAC,EAAA,uBAAAC,EAAA,uBAAAC,EAAA,qBAAAC,ICQO,IAAMC,EAAkC,CAC7C,KAAM,YACN,SAAU,KACV,KAAM,OACN,QAAS,QACT,YAAa,+CACb,WAAY,CACV,CACE,KAAM,aACN,KAAM,WACN,SAAU,GACV,QAAS,KACT,YAAa,0CACf,CACF,EACA,OAAQ,CACN,CAAE,KAAM,kBAAmB,YAAa,wBAAyB,EACjE,CAAE,KAAM,iBAAkB,YAAa,4BAA6B,EACpE,CAAE,KAAM,gBAAiB,YAAa,2BAA4B,CACpE,EACA,aAAc,CAAC,sDAAsD,EACrE,OAAQ;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAuBR,KAAK,CACP,EC6DO,SAASC,GAA4C,CAC1D,GAAI,OAAO,OAAW,IAAa,OAAO,KAC1C,IAAMC,EAAM,OACZ,OAAOA,EAAI,YAAcA,EAAI,WAAa,IAC5C,CC7FO,IAAMC,EAAkBC,EAAgB,OAClCC,EAAoBD,EAMjC,SAASE,EAAiBC,EAAsBC,EAAmC,CAEjF,IAAIC,EAA0BF,EAC9B,GAAIC,EAAO,YAAcA,EAAO,aAAe,KAC7C,GAAI,OAAOA,EAAO,YAAe,SAAU,CACzC,IAAME,EAAQH,EAAQ,cAAcC,EAAO,UAAU,EACjDE,aAAiB,cAAaD,EAAaC,EACjD,MAAWF,EAAO,sBAAsB,cACtCC,EAAaD,EAAO,YAIxBC,EAAW,iBAAiB,cAAgBE,GAAoB,CAC9DA,EAAE,eAAe,EACjBA,EAAE,gBAAgB,EAClBJ,EAAQ,cAAc,IAAI,YAAY,kBAAmB,CAAE,QAAS,EAAK,CAAC,CAAC,EAE3E,IAAMK,EAASL,EAAQ,WACjBM,EAASN,EAAQ,UACjBO,EAAOH,EAAE,QAAUC,EACnBG,EAAOJ,EAAE,QAAUE,EAEzB,SAASG,EAAOC,EAAkB,CAChCV,EAAQ,MAAM,KAAO,GAAGU,EAAG,QAAUH,CAAI,KACzCP,EAAQ,MAAM,IAAM,GAAGU,EAAG,QAAUF,CAAI,KACxCR,EAAQ,cAAc,IAAI,YAAY,iBAAkB,CAAE,QAAS,EAAK,CAAC,CAAC,CAC5E,CAEA,SAASW,GAAO,CACd,SAAS,oBAAoB,cAAeF,CAAM,EAClD,SAAS,oBAAoB,YAAaE,CAAI,EAC9CX,EAAQ,cAAc,IAAI,YAAY,gBAAiB,CAAE,QAAS,EAAK,CAAC,CAAC,CAC3E,CAEA,SAAS,iBAAiB,cAAeS,CAAM,EAC/C,SAAS,iBAAiB,YAAaE,CAAI,CAC7C,CAAC,CACH,CAMA,eAAsBC,EAAkBC,EAA+C,CACrF,IAAMC,EAAKD,GAAaE,EAAe,EAEvC,GAAI,CAACD,EACH,MAAM,IAAI,MACR,yFACF,EAKF,IAAME,EAAgB,CACpB,KAAM,WACN,KAAM,YACN,WAAY,CAAC,YAAY,EACzB,cAAe,CAAC,EAChB,oBAAqBjB,CACvB,EACMkB,EAAMH,EAAG,cAAgBA,EAAG,cAAc,EAAI,CAAE,OAAQ,IAAI,IAAO,QAAS,IAAI,GAAM,EAC5F,MAAMA,EAAG,QAAQE,EAAeC,CAAG,CACrC,CAGIF,EAAe,GACjBH,EAAkB,EAAE,MAAM,QAAQ,KAAK,EAGzC,IAAOM,EAAQ,CACb,OAAQrB,EAAgB,OACxB,SAAUA,EACV,SAAUe,CACZ,EClGO,IAAMO,EAAmC,CAC9C,KAAM,aACN,SAAU,OACV,KAAM,OACN,QAAS,QACT,YAAa,+BACb,WAAY,CACV,CACE,KAAM,MACN,KAAM,SACN,SAAU,GACV,QAAS,SACT,YAAa,qBACf,EACA,CACE,KAAM,SACN,KAAM,WACN,SAAU,GACV,QAAS,KACT,YAAa,gCACf,CACF,EACA,OAAQ,CACN,CAAE,KAAM,gBAAiB,YAAa,2BAA4B,EAClE,CAAE,KAAM,iBAAkB,YAAa,6BAA8B,CACvE,EACA,OAAQ;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,KAiBL,KAAK,CACV,EC7BO,IAAMC,EAAmBC,EAAiB,OACpCC,EAAqBD,EAMlC,SAASE,EAAkBC,EAAsBC,EAAmC,CAClF,IAAMC,EAAMD,EAAO,KAAO,SAGtBE,EAAwBH,EAC5B,GAAIC,EAAO,QAAUA,EAAO,SAAW,KACrC,GAAI,OAAOA,EAAO,QAAW,SAAU,CACrC,IAAMG,EAAQ,SAAS,cAAcH,EAAO,MAAM,EAC9CG,aAAiB,cAAaD,EAAWC,EAC/C,MAAWH,EAAO,kBAAkB,cAClCE,EAAWF,EAAO,QAItBD,EAAQ,iBAAiB,QAAS,IAAM,CACtC,IAAMK,EAAQF,EAAS,UAAU,SAASD,CAAG,EAC7CC,EAAS,UAAU,OAAOD,CAAG,EAC7BC,EAAS,cACP,IAAI,YAAYE,EAAQ,iBAAmB,gBAAiB,CAAE,QAAS,EAAK,CAAC,CAC/E,CACF,CAAC,CACH,CAMA,eAAsBC,EAAmBC,EAA+C,CACtF,IAAMC,EAAKD,GAAaE,EAAe,EAEvC,GAAI,CAACD,EACH,MAAM,IAAI,MACR,yFACF,EAGF,IAAME,EAAgB,CACpB,KAAM,WACN,KAAM,aACN,WAAY,CAAC,MAAO,QAAQ,EAC5B,cAAe,CAAC,EAChB,oBAAqBX,CACvB,EACMY,EAAMH,EAAG,cAAgBA,EAAG,cAAc,EAAI,CAAE,OAAQ,IAAI,IAAO,QAAS,IAAI,GAAM,EAC5F,MAAMA,EAAG,QAAQE,EAAeC,CAAG,CACrC,CAGIF,EAAe,GACjBH,EAAmB,EAAE,MAAM,QAAQ,KAAK,EAG1C,IAAOM,EAAQ,CACb,OAAQf,EAAiB,OACzB,SAAUA,EACV,SAAUS,CACZ,ELpEA,eAAsBO,EAAaC,EAA+C,CAChF,MAAM,QAAQ,IAAI,CAACC,EAAkBD,CAAS,EAAGE,EAAmBF,CAAS,CAAC,CAAC,CACjF,CAMO,IAAIG,EAA8B,KAGrC,OAAO,OAAW,KAAgB,OAAuC,aAC3EA,EAAQJ,EAAa,EACrBI,EAAM,MAAMC,GAAO,CACjB,QAAQ,MAAM,6CAA8CA,CAAG,CACjE,CAAC","names":["core_bundle_exports","__export","draggableMetadata","draggableSource","ready","registerCore","registerDraggable","registerToggleable","toggleableMetadata","toggleableSource","draggableSchema","resolveRuntime","win","draggableSource","draggableSchema","draggableMetadata","installDraggable","element","params","dragHandle","found","e","startX","startY","xoff","yoff","onMove","ev","onUp","registerDraggable","hyperfixi","hf","resolveRuntime","syntheticNode","ctx","draggable_default","toggleableSchema","toggleableSource","toggleableSchema","toggleableMetadata","installToggleable","element","params","cls","targetEl","found","wasOn","registerToggleable","hyperfixi","hf","resolveRuntime","syntheticNode","ctx","toggleable_default","registerCore","hyperfixi","registerDraggable","registerToggleable","ready","err"]}
@@ -1,9 +1,50 @@
1
- "use strict";var HyperFixiBehaviors=(()=>{var l=Object.defineProperty;var g=Object.getOwnPropertyDescriptor;var y=Object.getOwnPropertyNames;var b=Object.prototype.hasOwnProperty;var x=(t,e)=>{for(var i in e)l(t,i,{get:e[i],enumerable:!0})},E=(t,e,i,n)=>{if(e&&typeof e=="object"||typeof e=="function")for(let r of y(e))!b.call(t,r)&&r!==i&&l(t,r,{get:()=>e[r],enumerable:!(n=g(e,r))||n.enumerable});return t};var w=t=>E(l({},"__esModule",{value:!0}),t);var I={};x(I,{default:()=>M,focusTrapMetadata:()=>L,focusTrapSource:()=>S,registerFocusTrap:()=>d});var s={name:"FocusTrap",category:"ui",tier:"core",version:"1.0.0",description:"Confines Tab navigation inside an element with ARIA support",parameters:[{name:"active",type:"boolean",optional:!0,default:!0,description:"Whether the trap is active on install"},{name:"initialFocus",type:"selector",optional:!0,description:"Element to focus when the trap activates"},{name:"returnFocus",type:"boolean",optional:!0,default:!0,description:"Restore focus to the previously focused element on deactivation"}],events:[{name:"focustrap:activated",description:"Fired when the trap is activated"},{name:"focustrap:deactivated",description:"Fired when the trap is deactivated"}],requirements:['Sets aria-modal="true" on the element when active',"Listens for focustrap:activate and focustrap:deactivate custom events for programmatic control"],source:`
1
+ "use strict";var HyperFixiBehaviors=(()=>{var l=Object.defineProperty;var h=Object.getOwnPropertyDescriptor;var y=Object.getOwnPropertyNames;var g=Object.prototype.hasOwnProperty;var E=(t,e)=>{for(var r in e)l(t,r,{get:e[r],enumerable:!0})},x=(t,e,r,n)=>{if(e&&typeof e=="object"||typeof e=="function")for(let i of y(e))!g.call(t,i)&&i!==r&&l(t,i,{get:()=>e[i],enumerable:!(n=h(e,i))||n.enumerable});return t};var F=t=>x(l({},"__esModule",{value:!0}),t);var M={};E(M,{default:()=>A,focusTrapMetadata:()=>L,focusTrapSource:()=>w,registerFocusTrap:()=>f});var s={name:"FocusTrap",category:"ui",tier:"core",version:"1.0.0",description:"Confines Tab navigation inside an element with ARIA support",parameters:[{name:"active",type:"boolean",optional:!0,default:!0,description:"Whether the trap is active on install"},{name:"initialFocus",type:"selector",optional:!0,description:"Element to focus when the trap activates"},{name:"returnFocus",type:"boolean",optional:!0,default:!0,description:"Restore focus to the previously focused element on deactivation"}],events:[{name:"focustrap:activated",description:"Fired when the trap is activated"},{name:"focustrap:deactivated",description:"Fired when the trap is deactivated"}],requirements:['Sets aria-modal="true" on the element when active',"Listens for focustrap:activate and focustrap:deactivate custom events for programmatic control"],source:`
2
2
  behavior FocusTrap(active, initialFocus, returnFocus)
3
3
  init
4
- if active is undefined set active to true
5
- if returnFocus is undefined set returnFocus to true
4
+ if active is undefined
5
+ set active to true
6
+ end
7
+ if returnFocus is undefined
8
+ set returnFocus to true
9
+ end
10
+ js(me, active, initialFocus, returnFocus)
11
+ var FOCUSABLE = 'a[href],button:not(:disabled),input:not(:disabled),select:not(:disabled),textarea:not(:disabled),[tabindex]:not([tabindex="-1"])';
12
+ var isActive = false;
13
+ var previouslyFocused = null;
14
+ function getFocusable() { return Array.from(me.querySelectorAll(FOCUSABLE)); }
15
+ function activate() {
16
+ if (isActive) return;
17
+ isActive = true;
18
+ previouslyFocused = document.activeElement;
19
+ me.setAttribute('aria-modal', 'true');
20
+ var initEl = initialFocus ? (typeof initialFocus === 'string' ? me.querySelector(initialFocus) : initialFocus) : null;
21
+ if (initEl) { initEl.focus(); } else { var f = getFocusable(); if (f.length) f[0].focus(); }
22
+ me.dispatchEvent(new CustomEvent('focustrap:activated', { bubbles: true }));
23
+ }
24
+ function deactivate() {
25
+ if (!isActive) return;
26
+ isActive = false;
27
+ me.removeAttribute('aria-modal');
28
+ if (returnFocus && previouslyFocused instanceof HTMLElement) previouslyFocused.focus();
29
+ previouslyFocused = null;
30
+ me.dispatchEvent(new CustomEvent('focustrap:deactivated', { bubbles: true }));
31
+ }
32
+ me.addEventListener('keydown', function(e) {
33
+ if (!isActive || e.key !== 'Tab') return;
34
+ var focusable = getFocusable();
35
+ if (focusable.length === 0) { e.preventDefault(); return; }
36
+ e.preventDefault();
37
+ var idx = focusable.indexOf(document.activeElement);
38
+ if (e.shiftKey) {
39
+ focusable[idx <= 0 ? focusable.length - 1 : idx - 1].focus();
40
+ } else {
41
+ focusable[idx >= focusable.length - 1 ? 0 : idx + 1].focus();
42
+ }
43
+ });
44
+ me.addEventListener('focustrap:activate', function() { activate(); });
45
+ me.addEventListener('focustrap:deactivate', function() { deactivate(); });
46
+ if (active) activate();
47
+ end
6
48
  end
7
- -- Imperative installer handles Tab key trapping and focus management
8
- end`.trim()};function p(){if(typeof window>"u")return null;let t=window;return t.lokascript||t.hyperfixi||null}var S=s.source,L=s,k=["a[href]","button:not(:disabled)","input:not(:disabled)","select:not(:disabled)","textarea:not(:disabled)",'[tabindex]:not([tabindex="-1"])'].join(", ");function T(t,e){return e?e instanceof HTMLElement?e:typeof e=="string"&&(t.querySelector(e)||document.querySelector(e))||null:null}function F(t,e){let i=e.returnFocus!==!1,n=!1,r=null;function f(){return Array.from(t.querySelectorAll(k))}function v(a){if(!n||a.key!=="Tab")return;let o=f();if(o.length===0){a.preventDefault();return}a.preventDefault();let c=o.indexOf(document.activeElement);if(a.shiftKey){let u=c<=0?o.length-1:c-1;o[u].focus()}else{let u=c>=o.length-1?0:c+1;o[u].focus()}}function m(){if(n)return;n=!0,r=document.activeElement,t.setAttribute("aria-modal","true");let a=T(t,e.initialFocus);if(a)a.focus();else{let o=f();o.length>0&&o[0].focus()}t.dispatchEvent(new CustomEvent("focustrap:activated",{bubbles:!0}))}function h(){n&&(n=!1,t.removeAttribute("aria-modal"),i&&r instanceof HTMLElement&&r.focus(),r=null,t.dispatchEvent(new CustomEvent("focustrap:deactivated",{bubbles:!0})))}t.addEventListener("keydown",v),t.addEventListener("focustrap:activate",()=>m()),t.addEventListener("focustrap:deactivate",()=>h()),e.active!==!1&&m()}async function d(t){let e=t||p();if(!e)throw new Error("LokaScript not found. Make sure @hyperfixi/core is loaded before registering behaviors.");let i={type:"behavior",name:"FocusTrap",parameters:["active","initialFocus","returnFocus"],eventHandlers:[],imperativeInstaller:F},n=e.createContext?e.createContext():{locals:new Map,globals:new Map};await e.execute(i,n)}p()&&d().catch(console.error);var M={source:s.source,metadata:s,register:d};return w(I);})();
49
+ end`.trim()};function d(){if(typeof window>"u")return null;let t=window;return t.lokascript||t.hyperfixi||null}var w=s.source,L=s,S=["a[href]","button:not(:disabled)","input:not(:disabled)","select:not(:disabled)","textarea:not(:disabled)",'[tabindex]:not([tabindex="-1"])'].join(", ");function k(t,e){return e?e instanceof HTMLElement?e:typeof e=="string"&&(t.querySelector(e)||document.querySelector(e))||null:null}function T(t,e){let r=e.returnFocus!==!1,n=!1,i=null;function p(){return Array.from(t.querySelectorAll(S))}function m(a){if(!n||a.key!=="Tab")return;let o=p();if(o.length===0){a.preventDefault();return}a.preventDefault();let c=o.indexOf(document.activeElement);if(a.shiftKey){let u=c<=0?o.length-1:c-1;o[u].focus()}else{let u=c>=o.length-1?0:c+1;o[u].focus()}}function v(){if(n)return;n=!0,i=document.activeElement,t.setAttribute("aria-modal","true");let a=k(t,e.initialFocus);if(a)a.focus();else{let o=p();o.length>0&&o[0].focus()}t.dispatchEvent(new CustomEvent("focustrap:activated",{bubbles:!0}))}function b(){n&&(n=!1,t.removeAttribute("aria-modal"),r&&i instanceof HTMLElement&&i.focus(),i=null,t.dispatchEvent(new CustomEvent("focustrap:deactivated",{bubbles:!0})))}t.addEventListener("keydown",m),t.addEventListener("focustrap:activate",()=>v()),t.addEventListener("focustrap:deactivate",()=>b()),e.active!==!1&&v()}async function f(t){let e=t||d();if(!e)throw new Error("LokaScript not found. Make sure @hyperfixi/core is loaded before registering behaviors.");let r={type:"behavior",name:"FocusTrap",parameters:["active","initialFocus","returnFocus"],eventHandlers:[],imperativeInstaller:T},n=e.createContext?e.createContext():{locals:new Map,globals:new Map};await e.execute(r,n)}d()&&f().catch(console.error);var A={source:s.source,metadata:s,register:f};return F(M);})();
9
50
  //# sourceMappingURL=focustrap.browser.global.js.map
@@ -1 +1 @@
1
- {"version":3,"sources":["../src/behaviors/focustrap.ts","../src/schemas/focustrap.schema.ts","../src/schemas/types.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","import type { BehaviorSchema } from './types';\n\n/**\n * FocusTrap Behavior Schema\n *\n * Confines Tab navigation inside an element and restores focus on release.\n * Manages aria-modal for accessibility compliance.\n */\nexport const focusTrapSchema: BehaviorSchema = {\n name: 'FocusTrap',\n category: 'ui',\n tier: 'core',\n version: '1.0.0',\n description: 'Confines Tab navigation inside an element with ARIA support',\n parameters: [\n {\n name: 'active',\n type: 'boolean',\n optional: true,\n default: true,\n description: 'Whether the trap is active on install',\n },\n {\n name: 'initialFocus',\n type: 'selector',\n optional: true,\n description: 'Element to focus when the trap activates',\n },\n {\n name: 'returnFocus',\n type: 'boolean',\n optional: true,\n default: true,\n description: 'Restore focus to the previously focused element on deactivation',\n },\n ],\n events: [\n { name: 'focustrap:activated', description: 'Fired when the trap is activated' },\n { name: 'focustrap:deactivated', description: 'Fired when the trap is deactivated' },\n ],\n requirements: [\n 'Sets aria-modal=\"true\" on the element when active',\n 'Listens for focustrap:activate and focustrap:deactivate custom events for programmatic control',\n ],\n source: `\nbehavior FocusTrap(active, initialFocus, returnFocus)\n init\n if active is undefined set active to true\n if returnFocus is undefined set returnFocus to true\n end\n -- Imperative installer handles Tab key trapping and focus management\nend`.trim(),\n};\n","/**\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":"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","names":["focustrap_exports","__export","focustrap_default","focusTrapMetadata","focusTrapSource","registerFocusTrap","focusTrapSchema","resolveRuntime","win","focusTrapSource","focusTrapSchema","focusTrapMetadata","FOCUSABLE_SELECTOR","resolveElement","container","param","installFocusTrap","element","params","returnFocus","isActive","previouslyFocused","getFocusableElements","onKeyDown","e","focusable","currentIndex","prevIndex","nextIndex","activate","initialEl","deactivate","registerFocusTrap","hyperfixi","hf","resolveRuntime","syntheticNode","ctx","focustrap_default"]}
1
+ {"version":3,"sources":["../src/behaviors/focustrap.ts","../src/schemas/focustrap.schema.ts","../src/schemas/types.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","import type { BehaviorSchema } from './types';\n\n/**\n * FocusTrap Behavior Schema\n *\n * Confines Tab navigation inside an element and restores focus on release.\n * Manages aria-modal for accessibility compliance.\n */\nexport const focusTrapSchema: BehaviorSchema = {\n name: 'FocusTrap',\n category: 'ui',\n tier: 'core',\n version: '1.0.0',\n description: 'Confines Tab navigation inside an element with ARIA support',\n parameters: [\n {\n name: 'active',\n type: 'boolean',\n optional: true,\n default: true,\n description: 'Whether the trap is active on install',\n },\n {\n name: 'initialFocus',\n type: 'selector',\n optional: true,\n description: 'Element to focus when the trap activates',\n },\n {\n name: 'returnFocus',\n type: 'boolean',\n optional: true,\n default: true,\n description: 'Restore focus to the previously focused element on deactivation',\n },\n ],\n events: [\n { name: 'focustrap:activated', description: 'Fired when the trap is activated' },\n { name: 'focustrap:deactivated', description: 'Fired when the trap is deactivated' },\n ],\n requirements: [\n 'Sets aria-modal=\"true\" on the element when active',\n 'Listens for focustrap:activate and focustrap:deactivate custom events for programmatic control',\n ],\n source: `\nbehavior FocusTrap(active, initialFocus, returnFocus)\n init\n if active is undefined\n set active to true\n end\n if returnFocus is undefined\n set returnFocus to true\n end\n js(me, active, initialFocus, returnFocus)\n var FOCUSABLE = 'a[href],button:not(:disabled),input:not(:disabled),select:not(:disabled),textarea:not(:disabled),[tabindex]:not([tabindex=\"-1\"])';\n var isActive = false;\n var previouslyFocused = null;\n function getFocusable() { return Array.from(me.querySelectorAll(FOCUSABLE)); }\n function activate() {\n if (isActive) return;\n isActive = true;\n previouslyFocused = document.activeElement;\n me.setAttribute('aria-modal', 'true');\n var initEl = initialFocus ? (typeof initialFocus === 'string' ? me.querySelector(initialFocus) : initialFocus) : null;\n if (initEl) { initEl.focus(); } else { var f = getFocusable(); if (f.length) f[0].focus(); }\n me.dispatchEvent(new CustomEvent('focustrap:activated', { bubbles: true }));\n }\n function deactivate() {\n if (!isActive) return;\n isActive = false;\n me.removeAttribute('aria-modal');\n if (returnFocus && previouslyFocused instanceof HTMLElement) previouslyFocused.focus();\n previouslyFocused = null;\n me.dispatchEvent(new CustomEvent('focustrap:deactivated', { bubbles: true }));\n }\n me.addEventListener('keydown', function(e) {\n if (!isActive || e.key !== 'Tab') return;\n var focusable = getFocusable();\n if (focusable.length === 0) { e.preventDefault(); return; }\n e.preventDefault();\n var idx = focusable.indexOf(document.activeElement);\n if (e.shiftKey) {\n focusable[idx <= 0 ? focusable.length - 1 : idx - 1].focus();\n } else {\n focusable[idx >= focusable.length - 1 ? 0 : idx + 1].focus();\n }\n });\n me.addEventListener('focustrap:activate', function() { activate(); });\n me.addEventListener('focustrap:deactivate', function() { deactivate(); });\n if (active) activate();\n end\n end\nend`.trim(),\n};\n","/**\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":"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","names":["focustrap_exports","__export","focustrap_default","focusTrapMetadata","focusTrapSource","registerFocusTrap","focusTrapSchema","resolveRuntime","win","focusTrapSource","focusTrapSchema","focusTrapMetadata","FOCUSABLE_SELECTOR","resolveElement","container","param","installFocusTrap","element","params","returnFocus","isActive","previouslyFocused","getFocusableElements","onKeyDown","e","focusable","currentIndex","prevIndex","nextIndex","activate","initialEl","deactivate","registerFocusTrap","hyperfixi","hf","resolveRuntime","syntheticNode","ctx","focustrap_default"]}