@hyperfixi/behaviors 2.2.1 → 2.3.1

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,3 +1,55 @@
1
- "use strict";var HyperFixiBehaviors=(()=>{var u=Object.defineProperty;var v=Object.getOwnPropertyDescriptor;var h=Object.getOwnPropertyNames;var y=Object.prototype.hasOwnProperty;var g=(e,t)=>{for(var o in t)u(e,o,{get:t[o],enumerable:!0})},b=(e,t,o,i)=>{if(t&&typeof t=="object"||typeof t=="function")for(let n of h(t))!y.call(e,n)&&n!==o&&u(e,n,{get:()=>t[n],enumerable:!(i=v(t,n))||i.enumerable});return e};var w=e=>b(u({},"__esModule",{value:!0}),e);var D={};g(D,{autoDismissMetadata:()=>S,autoDismissSource:()=>x,default:()=>E,registerAutoDismiss:()=>d});var r={name:"AutoDismiss",category:"ui",tier:"core",version:"1.0.0",description:"Auto-removes elements after a delay with optional pause-on-hover",parameters:[{name:"delay",type:"number",optional:!0,default:5e3,description:"Time in ms before the element is removed"},{name:"pauseOnHover",type:"boolean",optional:!0,default:!0,description:"Pause the countdown when the mouse hovers over the element"},{name:"effect",type:"string",optional:!0,default:"none",enum:["fade","none"],description:'Transition effect before removal: "fade" or "none"'}],events:[{name:"autodismiss:start",description:"Fired when the countdown timer starts"},{name:"autodismiss:dismissed",description:"Fired before removal (cancelable via preventDefault)"},{name:"autodismiss:paused",description:"Fired when the timer is paused on hover"},{name:"autodismiss:resumed",description:"Fired when the timer resumes on mouseleave"}],source:["behavior AutoDismiss(delay, pauseOnHover, effect)"," init"," if delay is undefined set delay to 5000"," if pauseOnHover is undefined set pauseOnHover to true",' if effect is undefined set effect to "none"'," end"," on load"," trigger autodismiss:start"," wait delay ms"," trigger autodismiss:dismissed",' if effect is "fade"'," transition opacity to 0 over 300ms"," end"," remove me"," end","end"].join(`
2
- `)};function c(){if(typeof window>"u")return null;let e=window;return e.lokascript||e.hyperfixi||null}var x=r.source,S=r;function k(e,t){let o=typeof t.delay=="number"?t.delay:5e3,i=t.pauseOnHover!==!1,n=t.effect==="fade"?"fade":"none",s=null,a=o,m=Date.now();function f(){let l=new CustomEvent("autodismiss:dismissed",{bubbles:!0,cancelable:!0});e.dispatchEvent(l),!l.defaultPrevented&&(n==="fade"?(e.style.transition="opacity 300ms",e.style.opacity="0",setTimeout(()=>e.remove(),300)):e.remove())}function p(){m=Date.now(),s=setTimeout(f,a)}e.dispatchEvent(new CustomEvent("autodismiss:start",{bubbles:!0})),p(),i&&(e.addEventListener("mouseenter",()=>{s!=null&&(clearTimeout(s),s=null,a-=Date.now()-m,a<0&&(a=0),e.dispatchEvent(new CustomEvent("autodismiss:paused",{bubbles:!0})))}),e.addEventListener("mouseleave",()=>{s==null&&e.isConnected&&(e.dispatchEvent(new CustomEvent("autodismiss:resumed",{bubbles:!0})),p())}))}async function d(e){let t=e||c();if(!t)throw new Error("LokaScript not found. Make sure @hyperfixi/core is loaded before registering behaviors.");let o={type:"behavior",name:"AutoDismiss",parameters:["delay","pauseOnHover","effect"],eventHandlers:[],imperativeInstaller:k},i=t.createContext?t.createContext():{locals:new Map,globals:new Map};await t.execute(o,i)}c()&&d().catch(console.error);var E={source:r.source,metadata:r,register:d};return w(D);})();
1
+ "use strict";var HyperFixiBehaviors=(()=>{var u=Object.defineProperty;var v=Object.getOwnPropertyDescriptor;var h=Object.getOwnPropertyNames;var y=Object.prototype.hasOwnProperty;var b=(e,t)=>{for(var n in t)u(e,n,{get:t[n],enumerable:!0})},g=(e,t,n,s)=>{if(t&&typeof t=="object"||typeof t=="function")for(let i of h(t))!y.call(e,i)&&i!==n&&u(e,i,{get:()=>t[i],enumerable:!(s=v(t,i))||s.enumerable});return e};var w=e=>g(u({},"__esModule",{value:!0}),e);var D={};b(D,{autoDismissMetadata:()=>E,autoDismissSource:()=>x,default:()=>k,registerAutoDismiss:()=>d});var r={name:"AutoDismiss",category:"ui",tier:"core",version:"1.0.0",description:"Auto-removes elements after a delay with optional pause-on-hover",parameters:[{name:"delay",type:"number",optional:!0,default:5e3,description:"Time in ms before the element is removed"},{name:"pauseOnHover",type:"boolean",optional:!0,default:!0,description:"Pause the countdown when the mouse hovers over the element"},{name:"effect",type:"string",optional:!0,default:"none",enum:["fade","none"],description:'Transition effect before removal: "fade" or "none"'}],events:[{name:"autodismiss:start",description:"Fired when the countdown timer starts"},{name:"autodismiss:dismissed",description:"Fired before removal (cancelable via preventDefault)"},{name:"autodismiss:paused",description:"Fired when the timer is paused on hover"},{name:"autodismiss:resumed",description:"Fired when the timer resumes on mouseleave"}],source:`
2
+ behavior AutoDismiss(delay, pauseOnHover, effect)
3
+ init
4
+ if delay is undefined
5
+ set delay to 5000
6
+ end
7
+ if pauseOnHover is undefined
8
+ set pauseOnHover to true
9
+ end
10
+ if effect is undefined
11
+ set effect to "none"
12
+ end
13
+ js(me, delay, effect, pauseOnHover)
14
+ me.dispatchEvent(new CustomEvent('autodismiss:start', { bubbles: true }));
15
+ var remaining = delay;
16
+ var startedAt = Date.now();
17
+ var timerId = null;
18
+ function dismiss() {
19
+ var ev = new CustomEvent('autodismiss:dismissed', { bubbles: true, cancelable: true });
20
+ me.dispatchEvent(ev);
21
+ if (ev.defaultPrevented) return;
22
+ if (effect === 'fade') {
23
+ me.style.transition = 'opacity 300ms';
24
+ me.style.opacity = '0';
25
+ setTimeout(function() { me.remove(); }, 300);
26
+ } else {
27
+ me.remove();
28
+ }
29
+ }
30
+ function start() {
31
+ startedAt = Date.now();
32
+ timerId = setTimeout(dismiss, remaining);
33
+ }
34
+ start();
35
+ if (pauseOnHover) {
36
+ me.addEventListener('mouseenter', function() {
37
+ if (timerId != null) {
38
+ clearTimeout(timerId);
39
+ timerId = null;
40
+ remaining -= Date.now() - startedAt;
41
+ if (remaining < 0) remaining = 0;
42
+ me.dispatchEvent(new CustomEvent('autodismiss:paused', { bubbles: true }));
43
+ }
44
+ });
45
+ me.addEventListener('mouseleave', function() {
46
+ if (timerId == null && me.isConnected) {
47
+ me.dispatchEvent(new CustomEvent('autodismiss:resumed', { bubbles: true }));
48
+ start();
49
+ }
50
+ });
51
+ }
52
+ end
53
+ end
54
+ end`.trim()};function m(){if(typeof window>"u")return null;let e=window;return e.lokascript||e.hyperfixi||null}var x=r.source,E=r;function S(e,t){let n=typeof t.delay=="number"?t.delay:5e3,s=t.pauseOnHover!==!1,i=t.effect==="fade"?"fade":"none",o=null,a=n,c=Date.now();function f(){let p=new CustomEvent("autodismiss:dismissed",{bubbles:!0,cancelable:!0});e.dispatchEvent(p),!p.defaultPrevented&&(i==="fade"?(e.style.transition="opacity 300ms",e.style.opacity="0",setTimeout(()=>e.remove(),300)):e.remove())}function l(){c=Date.now(),o=setTimeout(f,a)}e.dispatchEvent(new CustomEvent("autodismiss:start",{bubbles:!0})),l(),s&&(e.addEventListener("mouseenter",()=>{o!=null&&(clearTimeout(o),o=null,a-=Date.now()-c,a<0&&(a=0),e.dispatchEvent(new CustomEvent("autodismiss:paused",{bubbles:!0})))}),e.addEventListener("mouseleave",()=>{o==null&&e.isConnected&&(e.dispatchEvent(new CustomEvent("autodismiss:resumed",{bubbles:!0})),l())}))}async function d(e){let t=e||m();if(!t)throw new Error("LokaScript not found. Make sure @hyperfixi/core is loaded before registering behaviors.");let n={type:"behavior",name:"AutoDismiss",parameters:["delay","pauseOnHover","effect"],eventHandlers:[],imperativeInstaller:S},s=t.createContext?t.createContext():{locals:new Map,globals:new Map};await t.execute(n,s)}m()&&d().catch(console.error);var k={source:r.source,metadata:r,register:d};return w(D);})();
3
55
  //# sourceMappingURL=autodismiss.browser.global.js.map
@@ -1 +1 @@
1
- {"version":3,"sources":["../src/behaviors/autodismiss.ts","../src/schemas/autodismiss.schema.ts","../src/schemas/types.ts"],"sourcesContent":["/**\n * AutoDismiss Behavior — Imperative Implementation\n *\n * Auto-removes elements after a configurable delay.\n * Supports pause-on-hover and fade effect using standard setTimeout/clearTimeout.\n */\n\nimport { autoDismissSchema } from '../schemas/autodismiss.schema';\nimport type { LokaScriptInstance } from '../schemas/types';\nimport { resolveRuntime } from '../schemas/types';\n\n// Re-export schema-derived values\nexport const autoDismissSource = autoDismissSchema.source;\nexport const autoDismissMetadata = autoDismissSchema;\n\n/**\n * Imperative installer for AutoDismiss behavior.\n */\nfunction installAutoDismiss(element: HTMLElement, params: Record<string, any>): void {\n const delay = typeof params.delay === 'number' ? params.delay : 5000;\n const pauseOnHover = params.pauseOnHover !== false;\n const effect = params.effect === 'fade' ? 'fade' : 'none';\n\n let timerId: ReturnType<typeof setTimeout> | null = null;\n let remaining = delay;\n let startedAt = Date.now();\n\n function dismiss() {\n const event = new CustomEvent('autodismiss:dismissed', {\n bubbles: true,\n cancelable: true,\n });\n element.dispatchEvent(event);\n\n if (event.defaultPrevented) return;\n\n if (effect === 'fade') {\n element.style.transition = 'opacity 300ms';\n element.style.opacity = '0';\n setTimeout(() => element.remove(), 300);\n } else {\n element.remove();\n }\n }\n\n function start() {\n startedAt = Date.now();\n timerId = setTimeout(dismiss, remaining);\n }\n\n // Start the countdown\n element.dispatchEvent(new CustomEvent('autodismiss:start', { bubbles: true }));\n start();\n\n if (pauseOnHover) {\n element.addEventListener('mouseenter', () => {\n if (timerId != null) {\n clearTimeout(timerId);\n timerId = null;\n remaining -= Date.now() - startedAt;\n if (remaining < 0) remaining = 0;\n element.dispatchEvent(new CustomEvent('autodismiss:paused', { bubbles: true }));\n }\n });\n\n element.addEventListener('mouseleave', () => {\n if (timerId == null && element.isConnected) {\n element.dispatchEvent(new CustomEvent('autodismiss:resumed', { bubbles: true }));\n start();\n }\n });\n }\n}\n\n/**\n * Register the AutoDismiss behavior with LokaScript.\n */\nexport async function registerAutoDismiss(hyperfixi?: LokaScriptInstance): Promise<void> {\n const hf = hyperfixi || resolveRuntime();\n\n if (!hf) {\n throw new Error(\n 'LokaScript not found. Make sure @hyperfixi/core is loaded before registering behaviors.'\n );\n }\n\n const syntheticNode = {\n type: 'behavior',\n name: 'AutoDismiss',\n parameters: ['delay', 'pauseOnHover', 'effect'],\n eventHandlers: [],\n imperativeInstaller: installAutoDismiss,\n };\n const ctx = hf.createContext ? hf.createContext() : { locals: new Map(), globals: new Map() };\n await hf.execute(syntheticNode, ctx);\n}\n\n// Auto-register when loaded as a script tag\nif (resolveRuntime()) {\n registerAutoDismiss().catch(console.error);\n}\n\nexport default {\n source: autoDismissSchema.source,\n metadata: autoDismissSchema,\n register: registerAutoDismiss,\n};\n","import type { BehaviorSchema } from './types';\n\n/**\n * AutoDismiss Behavior Schema\n *\n * Auto-removes flash messages and toasts after a configurable delay.\n * Supports pause-on-hover and fade effect.\n */\nexport const autoDismissSchema: BehaviorSchema = {\n name: 'AutoDismiss',\n category: 'ui',\n tier: 'core',\n version: '1.0.0',\n description: 'Auto-removes elements after a delay with optional pause-on-hover',\n parameters: [\n {\n name: 'delay',\n type: 'number',\n optional: true,\n default: 5000,\n description: 'Time in ms before the element is removed',\n },\n {\n name: 'pauseOnHover',\n type: 'boolean',\n optional: true,\n default: true,\n description: 'Pause the countdown when the mouse hovers over the element',\n },\n {\n name: 'effect',\n type: 'string',\n optional: true,\n default: 'none',\n enum: ['fade', 'none'],\n description: 'Transition effect before removal: \"fade\" or \"none\"',\n },\n ],\n events: [\n { name: 'autodismiss:start', description: 'Fired when the countdown timer starts' },\n {\n name: 'autodismiss:dismissed',\n description: 'Fired before removal (cancelable via preventDefault)',\n },\n { name: 'autodismiss:paused', description: 'Fired when the timer is paused on hover' },\n { name: 'autodismiss:resumed', description: 'Fired when the timer resumes on mouseleave' },\n ],\n source: [\n 'behavior AutoDismiss(delay, pauseOnHover, effect)',\n ' init',\n ' if delay is undefined set delay to 5000',\n ' if pauseOnHover is undefined set pauseOnHover to true',\n ' if effect is undefined set effect to \"none\"',\n ' end',\n ' on load',\n ' trigger autodismiss:start',\n ' wait delay ms',\n ' trigger autodismiss:dismissed',\n ' if effect is \"fade\"',\n ' transition opacity to 0 over 300ms',\n ' end',\n ' remove me',\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":["autodismiss_exports","__export","autoDismissMetadata","autoDismissSource","autodismiss_default","registerAutoDismiss","autoDismissSchema","resolveRuntime","win","autoDismissSource","autoDismissSchema","autoDismissMetadata","installAutoDismiss","element","params","delay","pauseOnHover","effect","timerId","remaining","startedAt","dismiss","event","start","registerAutoDismiss","hyperfixi","hf","resolveRuntime","syntheticNode","ctx","autodismiss_default"]}
1
+ {"version":3,"sources":["../src/behaviors/autodismiss.ts","../src/schemas/autodismiss.schema.ts","../src/schemas/types.ts"],"sourcesContent":["/**\n * AutoDismiss Behavior — Imperative Implementation\n *\n * Auto-removes elements after a configurable delay.\n * Supports pause-on-hover and fade effect using standard setTimeout/clearTimeout.\n */\n\nimport { autoDismissSchema } from '../schemas/autodismiss.schema';\nimport type { LokaScriptInstance } from '../schemas/types';\nimport { resolveRuntime } from '../schemas/types';\n\n// Re-export schema-derived values\nexport const autoDismissSource = autoDismissSchema.source;\nexport const autoDismissMetadata = autoDismissSchema;\n\n/**\n * Imperative installer for AutoDismiss behavior.\n */\nfunction installAutoDismiss(element: HTMLElement, params: Record<string, any>): void {\n const delay = typeof params.delay === 'number' ? params.delay : 5000;\n const pauseOnHover = params.pauseOnHover !== false;\n const effect = params.effect === 'fade' ? 'fade' : 'none';\n\n let timerId: ReturnType<typeof setTimeout> | null = null;\n let remaining = delay;\n let startedAt = Date.now();\n\n function dismiss() {\n const event = new CustomEvent('autodismiss:dismissed', {\n bubbles: true,\n cancelable: true,\n });\n element.dispatchEvent(event);\n\n if (event.defaultPrevented) return;\n\n if (effect === 'fade') {\n element.style.transition = 'opacity 300ms';\n element.style.opacity = '0';\n setTimeout(() => element.remove(), 300);\n } else {\n element.remove();\n }\n }\n\n function start() {\n startedAt = Date.now();\n timerId = setTimeout(dismiss, remaining);\n }\n\n // Start the countdown\n element.dispatchEvent(new CustomEvent('autodismiss:start', { bubbles: true }));\n start();\n\n if (pauseOnHover) {\n element.addEventListener('mouseenter', () => {\n if (timerId != null) {\n clearTimeout(timerId);\n timerId = null;\n remaining -= Date.now() - startedAt;\n if (remaining < 0) remaining = 0;\n element.dispatchEvent(new CustomEvent('autodismiss:paused', { bubbles: true }));\n }\n });\n\n element.addEventListener('mouseleave', () => {\n if (timerId == null && element.isConnected) {\n element.dispatchEvent(new CustomEvent('autodismiss:resumed', { bubbles: true }));\n start();\n }\n });\n }\n}\n\n/**\n * Register the AutoDismiss behavior with LokaScript.\n */\nexport async function registerAutoDismiss(hyperfixi?: LokaScriptInstance): Promise<void> {\n const hf = hyperfixi || resolveRuntime();\n\n if (!hf) {\n throw new Error(\n 'LokaScript not found. Make sure @hyperfixi/core is loaded before registering behaviors.'\n );\n }\n\n const syntheticNode = {\n type: 'behavior',\n name: 'AutoDismiss',\n parameters: ['delay', 'pauseOnHover', 'effect'],\n eventHandlers: [],\n imperativeInstaller: installAutoDismiss,\n };\n const ctx = hf.createContext ? hf.createContext() : { locals: new Map(), globals: new Map() };\n await hf.execute(syntheticNode, ctx);\n}\n\n// Auto-register when loaded as a script tag\nif (resolveRuntime()) {\n registerAutoDismiss().catch(console.error);\n}\n\nexport default {\n source: autoDismissSchema.source,\n metadata: autoDismissSchema,\n register: registerAutoDismiss,\n};\n","import type { BehaviorSchema } from './types';\n\n/**\n * AutoDismiss Behavior Schema\n *\n * Auto-removes flash messages and toasts after a configurable delay.\n * Supports pause-on-hover and fade effect.\n */\nexport const autoDismissSchema: BehaviorSchema = {\n name: 'AutoDismiss',\n category: 'ui',\n tier: 'core',\n version: '1.0.0',\n description: 'Auto-removes elements after a delay with optional pause-on-hover',\n parameters: [\n {\n name: 'delay',\n type: 'number',\n optional: true,\n default: 5000,\n description: 'Time in ms before the element is removed',\n },\n {\n name: 'pauseOnHover',\n type: 'boolean',\n optional: true,\n default: true,\n description: 'Pause the countdown when the mouse hovers over the element',\n },\n {\n name: 'effect',\n type: 'string',\n optional: true,\n default: 'none',\n enum: ['fade', 'none'],\n description: 'Transition effect before removal: \"fade\" or \"none\"',\n },\n ],\n events: [\n { name: 'autodismiss:start', description: 'Fired when the countdown timer starts' },\n {\n name: 'autodismiss:dismissed',\n description: 'Fired before removal (cancelable via preventDefault)',\n },\n { name: 'autodismiss:paused', description: 'Fired when the timer is paused on hover' },\n { name: 'autodismiss:resumed', description: 'Fired when the timer resumes on mouseleave' },\n ],\n source: `\nbehavior AutoDismiss(delay, pauseOnHover, effect)\n init\n if delay is undefined\n set delay to 5000\n end\n if pauseOnHover is undefined\n set pauseOnHover to true\n end\n if effect is undefined\n set effect to \"none\"\n end\n js(me, delay, effect, pauseOnHover)\n me.dispatchEvent(new CustomEvent('autodismiss:start', { bubbles: true }));\n var remaining = delay;\n var startedAt = Date.now();\n var timerId = null;\n function dismiss() {\n var ev = new CustomEvent('autodismiss:dismissed', { bubbles: true, cancelable: true });\n me.dispatchEvent(ev);\n if (ev.defaultPrevented) return;\n if (effect === 'fade') {\n me.style.transition = 'opacity 300ms';\n me.style.opacity = '0';\n setTimeout(function() { me.remove(); }, 300);\n } else {\n me.remove();\n }\n }\n function start() {\n startedAt = Date.now();\n timerId = setTimeout(dismiss, remaining);\n }\n start();\n if (pauseOnHover) {\n me.addEventListener('mouseenter', function() {\n if (timerId != null) {\n clearTimeout(timerId);\n timerId = null;\n remaining -= Date.now() - startedAt;\n if (remaining < 0) remaining = 0;\n me.dispatchEvent(new CustomEvent('autodismiss:paused', { bubbles: true }));\n }\n });\n me.addEventListener('mouseleave', function() {\n if (timerId == null && me.isConnected) {\n me.dispatchEvent(new CustomEvent('autodismiss:resumed', { bubbles: true }));\n start();\n }\n });\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":["autodismiss_exports","__export","autoDismissMetadata","autoDismissSource","autodismiss_default","registerAutoDismiss","autoDismissSchema","resolveRuntime","win","autoDismissSource","autoDismissSchema","autoDismissMetadata","installAutoDismiss","element","params","delay","pauseOnHover","effect","timerId","remaining","startedAt","dismiss","event","start","registerAutoDismiss","hyperfixi","hf","resolveRuntime","syntheticNode","ctx","autodismiss_default"]}
@@ -67,24 +67,60 @@ var autoDismissSchema = {
67
67
  { name: "autodismiss:paused", description: "Fired when the timer is paused on hover" },
68
68
  { name: "autodismiss:resumed", description: "Fired when the timer resumes on mouseleave" }
69
69
  ],
70
- source: [
71
- "behavior AutoDismiss(delay, pauseOnHover, effect)",
72
- " init",
73
- " if delay is undefined set delay to 5000",
74
- " if pauseOnHover is undefined set pauseOnHover to true",
75
- ' if effect is undefined set effect to "none"',
76
- " end",
77
- " on load",
78
- " trigger autodismiss:start",
79
- " wait delay ms",
80
- " trigger autodismiss:dismissed",
81
- ' if effect is "fade"',
82
- " transition opacity to 0 over 300ms",
83
- " end",
84
- " remove me",
85
- " end",
86
- "end"
87
- ].join("\n")
70
+ source: `
71
+ behavior AutoDismiss(delay, pauseOnHover, effect)
72
+ init
73
+ if delay is undefined
74
+ set delay to 5000
75
+ end
76
+ if pauseOnHover is undefined
77
+ set pauseOnHover to true
78
+ end
79
+ if effect is undefined
80
+ set effect to "none"
81
+ end
82
+ js(me, delay, effect, pauseOnHover)
83
+ me.dispatchEvent(new CustomEvent('autodismiss:start', { bubbles: true }));
84
+ var remaining = delay;
85
+ var startedAt = Date.now();
86
+ var timerId = null;
87
+ function dismiss() {
88
+ var ev = new CustomEvent('autodismiss:dismissed', { bubbles: true, cancelable: true });
89
+ me.dispatchEvent(ev);
90
+ if (ev.defaultPrevented) return;
91
+ if (effect === 'fade') {
92
+ me.style.transition = 'opacity 300ms';
93
+ me.style.opacity = '0';
94
+ setTimeout(function() { me.remove(); }, 300);
95
+ } else {
96
+ me.remove();
97
+ }
98
+ }
99
+ function start() {
100
+ startedAt = Date.now();
101
+ timerId = setTimeout(dismiss, remaining);
102
+ }
103
+ start();
104
+ if (pauseOnHover) {
105
+ me.addEventListener('mouseenter', function() {
106
+ if (timerId != null) {
107
+ clearTimeout(timerId);
108
+ timerId = null;
109
+ remaining -= Date.now() - startedAt;
110
+ if (remaining < 0) remaining = 0;
111
+ me.dispatchEvent(new CustomEvent('autodismiss:paused', { bubbles: true }));
112
+ }
113
+ });
114
+ me.addEventListener('mouseleave', function() {
115
+ if (timerId == null && me.isConnected) {
116
+ me.dispatchEvent(new CustomEvent('autodismiss:resumed', { bubbles: true }));
117
+ start();
118
+ }
119
+ });
120
+ }
121
+ end
122
+ end
123
+ end`.trim()
88
124
  };
89
125
 
90
126
  // src/schemas/types.ts
@@ -1 +1 @@
1
- {"version":3,"sources":["../../src/behaviors/autodismiss.ts","../../src/schemas/autodismiss.schema.ts","../../src/schemas/types.ts"],"sourcesContent":["/**\n * AutoDismiss Behavior — Imperative Implementation\n *\n * Auto-removes elements after a configurable delay.\n * Supports pause-on-hover and fade effect using standard setTimeout/clearTimeout.\n */\n\nimport { autoDismissSchema } from '../schemas/autodismiss.schema';\nimport type { LokaScriptInstance } from '../schemas/types';\nimport { resolveRuntime } from '../schemas/types';\n\n// Re-export schema-derived values\nexport const autoDismissSource = autoDismissSchema.source;\nexport const autoDismissMetadata = autoDismissSchema;\n\n/**\n * Imperative installer for AutoDismiss behavior.\n */\nfunction installAutoDismiss(element: HTMLElement, params: Record<string, any>): void {\n const delay = typeof params.delay === 'number' ? params.delay : 5000;\n const pauseOnHover = params.pauseOnHover !== false;\n const effect = params.effect === 'fade' ? 'fade' : 'none';\n\n let timerId: ReturnType<typeof setTimeout> | null = null;\n let remaining = delay;\n let startedAt = Date.now();\n\n function dismiss() {\n const event = new CustomEvent('autodismiss:dismissed', {\n bubbles: true,\n cancelable: true,\n });\n element.dispatchEvent(event);\n\n if (event.defaultPrevented) return;\n\n if (effect === 'fade') {\n element.style.transition = 'opacity 300ms';\n element.style.opacity = '0';\n setTimeout(() => element.remove(), 300);\n } else {\n element.remove();\n }\n }\n\n function start() {\n startedAt = Date.now();\n timerId = setTimeout(dismiss, remaining);\n }\n\n // Start the countdown\n element.dispatchEvent(new CustomEvent('autodismiss:start', { bubbles: true }));\n start();\n\n if (pauseOnHover) {\n element.addEventListener('mouseenter', () => {\n if (timerId != null) {\n clearTimeout(timerId);\n timerId = null;\n remaining -= Date.now() - startedAt;\n if (remaining < 0) remaining = 0;\n element.dispatchEvent(new CustomEvent('autodismiss:paused', { bubbles: true }));\n }\n });\n\n element.addEventListener('mouseleave', () => {\n if (timerId == null && element.isConnected) {\n element.dispatchEvent(new CustomEvent('autodismiss:resumed', { bubbles: true }));\n start();\n }\n });\n }\n}\n\n/**\n * Register the AutoDismiss behavior with LokaScript.\n */\nexport async function registerAutoDismiss(hyperfixi?: LokaScriptInstance): Promise<void> {\n const hf = hyperfixi || resolveRuntime();\n\n if (!hf) {\n throw new Error(\n 'LokaScript not found. Make sure @hyperfixi/core is loaded before registering behaviors.'\n );\n }\n\n const syntheticNode = {\n type: 'behavior',\n name: 'AutoDismiss',\n parameters: ['delay', 'pauseOnHover', 'effect'],\n eventHandlers: [],\n imperativeInstaller: installAutoDismiss,\n };\n const ctx = hf.createContext ? hf.createContext() : { locals: new Map(), globals: new Map() };\n await hf.execute(syntheticNode, ctx);\n}\n\n// Auto-register when loaded as a script tag\nif (resolveRuntime()) {\n registerAutoDismiss().catch(console.error);\n}\n\nexport default {\n source: autoDismissSchema.source,\n metadata: autoDismissSchema,\n register: registerAutoDismiss,\n};\n","import type { BehaviorSchema } from './types';\n\n/**\n * AutoDismiss Behavior Schema\n *\n * Auto-removes flash messages and toasts after a configurable delay.\n * Supports pause-on-hover and fade effect.\n */\nexport const autoDismissSchema: BehaviorSchema = {\n name: 'AutoDismiss',\n category: 'ui',\n tier: 'core',\n version: '1.0.0',\n description: 'Auto-removes elements after a delay with optional pause-on-hover',\n parameters: [\n {\n name: 'delay',\n type: 'number',\n optional: true,\n default: 5000,\n description: 'Time in ms before the element is removed',\n },\n {\n name: 'pauseOnHover',\n type: 'boolean',\n optional: true,\n default: true,\n description: 'Pause the countdown when the mouse hovers over the element',\n },\n {\n name: 'effect',\n type: 'string',\n optional: true,\n default: 'none',\n enum: ['fade', 'none'],\n description: 'Transition effect before removal: \"fade\" or \"none\"',\n },\n ],\n events: [\n { name: 'autodismiss:start', description: 'Fired when the countdown timer starts' },\n {\n name: 'autodismiss:dismissed',\n description: 'Fired before removal (cancelable via preventDefault)',\n },\n { name: 'autodismiss:paused', description: 'Fired when the timer is paused on hover' },\n { name: 'autodismiss:resumed', description: 'Fired when the timer resumes on mouseleave' },\n ],\n source: [\n 'behavior AutoDismiss(delay, pauseOnHover, effect)',\n ' init',\n ' if delay is undefined set delay to 5000',\n ' if pauseOnHover is undefined set pauseOnHover to true',\n ' if effect is undefined set effect to \"none\"',\n ' end',\n ' on load',\n ' trigger autodismiss:start',\n ' wait delay ms',\n ' trigger autodismiss:dismissed',\n ' if effect is \"fade\"',\n ' transition opacity to 0 over 300ms',\n ' end',\n ' remove me',\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":[]}
1
+ {"version":3,"sources":["../../src/behaviors/autodismiss.ts","../../src/schemas/autodismiss.schema.ts","../../src/schemas/types.ts"],"sourcesContent":["/**\n * AutoDismiss Behavior — Imperative Implementation\n *\n * Auto-removes elements after a configurable delay.\n * Supports pause-on-hover and fade effect using standard setTimeout/clearTimeout.\n */\n\nimport { autoDismissSchema } from '../schemas/autodismiss.schema';\nimport type { LokaScriptInstance } from '../schemas/types';\nimport { resolveRuntime } from '../schemas/types';\n\n// Re-export schema-derived values\nexport const autoDismissSource = autoDismissSchema.source;\nexport const autoDismissMetadata = autoDismissSchema;\n\n/**\n * Imperative installer for AutoDismiss behavior.\n */\nfunction installAutoDismiss(element: HTMLElement, params: Record<string, any>): void {\n const delay = typeof params.delay === 'number' ? params.delay : 5000;\n const pauseOnHover = params.pauseOnHover !== false;\n const effect = params.effect === 'fade' ? 'fade' : 'none';\n\n let timerId: ReturnType<typeof setTimeout> | null = null;\n let remaining = delay;\n let startedAt = Date.now();\n\n function dismiss() {\n const event = new CustomEvent('autodismiss:dismissed', {\n bubbles: true,\n cancelable: true,\n });\n element.dispatchEvent(event);\n\n if (event.defaultPrevented) return;\n\n if (effect === 'fade') {\n element.style.transition = 'opacity 300ms';\n element.style.opacity = '0';\n setTimeout(() => element.remove(), 300);\n } else {\n element.remove();\n }\n }\n\n function start() {\n startedAt = Date.now();\n timerId = setTimeout(dismiss, remaining);\n }\n\n // Start the countdown\n element.dispatchEvent(new CustomEvent('autodismiss:start', { bubbles: true }));\n start();\n\n if (pauseOnHover) {\n element.addEventListener('mouseenter', () => {\n if (timerId != null) {\n clearTimeout(timerId);\n timerId = null;\n remaining -= Date.now() - startedAt;\n if (remaining < 0) remaining = 0;\n element.dispatchEvent(new CustomEvent('autodismiss:paused', { bubbles: true }));\n }\n });\n\n element.addEventListener('mouseleave', () => {\n if (timerId == null && element.isConnected) {\n element.dispatchEvent(new CustomEvent('autodismiss:resumed', { bubbles: true }));\n start();\n }\n });\n }\n}\n\n/**\n * Register the AutoDismiss behavior with LokaScript.\n */\nexport async function registerAutoDismiss(hyperfixi?: LokaScriptInstance): Promise<void> {\n const hf = hyperfixi || resolveRuntime();\n\n if (!hf) {\n throw new Error(\n 'LokaScript not found. Make sure @hyperfixi/core is loaded before registering behaviors.'\n );\n }\n\n const syntheticNode = {\n type: 'behavior',\n name: 'AutoDismiss',\n parameters: ['delay', 'pauseOnHover', 'effect'],\n eventHandlers: [],\n imperativeInstaller: installAutoDismiss,\n };\n const ctx = hf.createContext ? hf.createContext() : { locals: new Map(), globals: new Map() };\n await hf.execute(syntheticNode, ctx);\n}\n\n// Auto-register when loaded as a script tag\nif (resolveRuntime()) {\n registerAutoDismiss().catch(console.error);\n}\n\nexport default {\n source: autoDismissSchema.source,\n metadata: autoDismissSchema,\n register: registerAutoDismiss,\n};\n","import type { BehaviorSchema } from './types';\n\n/**\n * AutoDismiss Behavior Schema\n *\n * Auto-removes flash messages and toasts after a configurable delay.\n * Supports pause-on-hover and fade effect.\n */\nexport const autoDismissSchema: BehaviorSchema = {\n name: 'AutoDismiss',\n category: 'ui',\n tier: 'core',\n version: '1.0.0',\n description: 'Auto-removes elements after a delay with optional pause-on-hover',\n parameters: [\n {\n name: 'delay',\n type: 'number',\n optional: true,\n default: 5000,\n description: 'Time in ms before the element is removed',\n },\n {\n name: 'pauseOnHover',\n type: 'boolean',\n optional: true,\n default: true,\n description: 'Pause the countdown when the mouse hovers over the element',\n },\n {\n name: 'effect',\n type: 'string',\n optional: true,\n default: 'none',\n enum: ['fade', 'none'],\n description: 'Transition effect before removal: \"fade\" or \"none\"',\n },\n ],\n events: [\n { name: 'autodismiss:start', description: 'Fired when the countdown timer starts' },\n {\n name: 'autodismiss:dismissed',\n description: 'Fired before removal (cancelable via preventDefault)',\n },\n { name: 'autodismiss:paused', description: 'Fired when the timer is paused on hover' },\n { name: 'autodismiss:resumed', description: 'Fired when the timer resumes on mouseleave' },\n ],\n source: `\nbehavior AutoDismiss(delay, pauseOnHover, effect)\n init\n if delay is undefined\n set delay to 5000\n end\n if pauseOnHover is undefined\n set pauseOnHover to true\n end\n if effect is undefined\n set effect to \"none\"\n end\n js(me, delay, effect, pauseOnHover)\n me.dispatchEvent(new CustomEvent('autodismiss:start', { bubbles: true }));\n var remaining = delay;\n var startedAt = Date.now();\n var timerId = null;\n function dismiss() {\n var ev = new CustomEvent('autodismiss:dismissed', { bubbles: true, cancelable: true });\n me.dispatchEvent(ev);\n if (ev.defaultPrevented) return;\n if (effect === 'fade') {\n me.style.transition = 'opacity 300ms';\n me.style.opacity = '0';\n setTimeout(function() { me.remove(); }, 300);\n } else {\n me.remove();\n }\n }\n function start() {\n startedAt = Date.now();\n timerId = setTimeout(dismiss, remaining);\n }\n start();\n if (pauseOnHover) {\n me.addEventListener('mouseenter', function() {\n if (timerId != null) {\n clearTimeout(timerId);\n timerId = null;\n remaining -= Date.now() - startedAt;\n if (remaining < 0) remaining = 0;\n me.dispatchEvent(new CustomEvent('autodismiss:paused', { bubbles: true }));\n }\n });\n me.addEventListener('mouseleave', function() {\n if (timerId == null && me.isConnected) {\n me.dispatchEvent(new CustomEvent('autodismiss:resumed', { bubbles: true }));\n start();\n }\n });\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":[]}
@@ -3,8 +3,8 @@ import {
3
3
  autoDismissSource,
4
4
  autodismiss_default,
5
5
  registerAutoDismiss
6
- } from "../chunk-H2MCHR5A.js";
7
- import "../chunk-ZQQZTMCJ.js";
6
+ } from "../chunk-LQJOQTBZ.js";
7
+ import "../chunk-66U2RSYJ.js";
8
8
  import "../chunk-6TJXDCAQ.js";
9
9
  export {
10
10
  autoDismissMetadata,
@@ -44,19 +44,38 @@ var clickOutsideSchema = {
44
44
  }
45
45
  ],
46
46
  events: [
47
- { name: "clickoutside", description: "Fired when a pointer press occurs outside the element" }
47
+ { name: "clickoutside", description: "Fired when a pointer press occurs outside the element" },
48
+ {
49
+ name: "clickoutside:activate",
50
+ description: "Listen for this event to programmatically activate detection"
51
+ },
52
+ {
53
+ name: "clickoutside:deactivate",
54
+ description: "Listen for this event to programmatically deactivate detection"
55
+ }
48
56
  ],
49
57
  requirements: ["Uses pointerdown instead of click to avoid timing issues with removed elements"],
50
58
  source: `
51
59
  behavior ClickOutside(active)
52
60
  init
53
- if active is undefined set active to true
61
+ if active is undefined
62
+ set active to true
63
+ end
54
64
  end
55
65
  on pointerdown from document
56
- if active and not me.contains(event.target)
57
- trigger clickoutside on me
66
+ js(me, active)
67
+ if (!me.isConnected) return;
68
+ if (active && !me.contains(event.target)) {
69
+ me.dispatchEvent(new CustomEvent('clickoutside', { bubbles: true }));
70
+ }
58
71
  end
59
72
  end
73
+ on clickoutside:activate
74
+ set active to true
75
+ end
76
+ on clickoutside:deactivate
77
+ set active to false
78
+ end
60
79
  end`.trim()
61
80
  };
62
81
 
@@ -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":";;;;;;;;;;;;;;;;;;;;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;;;ACQO,IAAM,qBAAqC;AAAA,EAChD,MAAM;AAAA,EACN,UAAU;AAAA,EACV,MAAM;AAAA,EACN,SAAS;AAAA,EACT,aAAa;AAAA,EACb,YAAY;AAAA,IACV;AAAA,MACE,MAAM;AAAA,MACN,MAAM;AAAA,MACN,UAAU;AAAA,MACV,SAAS;AAAA,MACT,aAAa;AAAA,IACf;AAAA,EACF;AAAA,EACA,QAAQ;AAAA,IACN,EAAE,MAAM,gBAAgB,aAAa,wDAAwD;AAAA,EAC/F;AAAA,EACA,cAAc,CAAC,gFAAgF;AAAA,EAC/F,QAAQ;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,KAUL,KAAK;AACV;;;AC4EO,SAAS,iBAA4C;AAC1D,MAAI,OAAO,WAAW,YAAa,QAAO;AAC1C,QAAM,MAAM;AACZ,SAAO,IAAI,cAAc,IAAI,aAAa;AAC5C;;;AF1GO,IAAM,qBAAqB,mBAAmB;AAC9C,IAAM,uBAAuB;AAKpC,SAAS,oBAAoB,SAAsB,QAAmC;AACpF,MAAI,SAAS,OAAO,WAAW;AAE/B,WAAS,cAAc,GAAU;AAE/B,QAAI,CAAC,QAAQ,aAAa;AACxB,eAAS,oBAAoB,eAAe,aAAa;AACzD;AAAA,IACF;AAEA,QAAI,UAAU,CAAC,QAAQ,SAAS,EAAE,MAAc,GAAG;AACjD,cAAQ,cAAc,IAAI,YAAY,gBAAgB,EAAE,SAAS,KAAK,CAAC,CAAC;AAAA,IAC1E;AAAA,EACF;AAEA,WAAS,iBAAiB,eAAe,aAAa;AAGtD,UAAQ,iBAAiB,yBAAyB,MAAM;AACtD,aAAS;AAAA,EACX,CAAC;AACD,UAAQ,iBAAiB,2BAA2B,MAAM;AACxD,aAAS;AAAA,EACX,CAAC;AACH;AAKA,eAAsB,qBAAqB,WAA+C;AACxF,QAAM,KAAK,aAAa,eAAe;AAEvC,MAAI,CAAC,IAAI;AACP,UAAM,IAAI;AAAA,MACR;AAAA,IACF;AAAA,EACF;AAEA,QAAM,gBAAgB;AAAA,IACpB,MAAM;AAAA,IACN,MAAM;AAAA,IACN,YAAY,CAAC,QAAQ;AAAA,IACrB,eAAe,CAAC;AAAA,IAChB,qBAAqB;AAAA,EACvB;AACA,QAAM,MAAM,GAAG,gBAAgB,GAAG,cAAc,IAAI,EAAE,QAAQ,oBAAI,IAAI,GAAG,SAAS,oBAAI,IAAI,EAAE;AAC5F,QAAM,GAAG,QAAQ,eAAe,GAAG;AACrC;AAGA,IAAI,eAAe,GAAG;AACpB,uBAAqB,EAAE,MAAM,QAAQ,KAAK;AAC5C;AAEA,IAAO,uBAAQ;AAAA,EACb,QAAQ,mBAAmB;AAAA,EAC3B,UAAU;AAAA,EACV,UAAU;AACZ;","names":[]}
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":";;;;;;;;;;;;;;;;;;;;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;;;ACQO,IAAM,qBAAqC;AAAA,EAChD,MAAM;AAAA,EACN,UAAU;AAAA,EACV,MAAM;AAAA,EACN,SAAS;AAAA,EACT,aAAa;AAAA,EACb,YAAY;AAAA,IACV;AAAA,MACE,MAAM;AAAA,MACN,MAAM;AAAA,MACN,UAAU;AAAA,MACV,SAAS;AAAA,MACT,aAAa;AAAA,IACf;AAAA,EACF;AAAA,EACA,QAAQ;AAAA,IACN,EAAE,MAAM,gBAAgB,aAAa,wDAAwD;AAAA,IAC7F;AAAA,MACE,MAAM;AAAA,MACN,aAAa;AAAA,IACf;AAAA,IACA;AAAA,MACE,MAAM;AAAA,MACN,aAAa;AAAA,IACf;AAAA,EACF;AAAA,EACA,cAAc,CAAC,gFAAgF;AAAA,EAC/F,QAAQ;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,KAqBL,KAAK;AACV;;;ACyDO,SAAS,iBAA4C;AAC1D,MAAI,OAAO,WAAW,YAAa,QAAO;AAC1C,QAAM,MAAM;AACZ,SAAO,IAAI,cAAc,IAAI,aAAa;AAC5C;;;AF1GO,IAAM,qBAAqB,mBAAmB;AAC9C,IAAM,uBAAuB;AAKpC,SAAS,oBAAoB,SAAsB,QAAmC;AACpF,MAAI,SAAS,OAAO,WAAW;AAE/B,WAAS,cAAc,GAAU;AAE/B,QAAI,CAAC,QAAQ,aAAa;AACxB,eAAS,oBAAoB,eAAe,aAAa;AACzD;AAAA,IACF;AAEA,QAAI,UAAU,CAAC,QAAQ,SAAS,EAAE,MAAc,GAAG;AACjD,cAAQ,cAAc,IAAI,YAAY,gBAAgB,EAAE,SAAS,KAAK,CAAC,CAAC;AAAA,IAC1E;AAAA,EACF;AAEA,WAAS,iBAAiB,eAAe,aAAa;AAGtD,UAAQ,iBAAiB,yBAAyB,MAAM;AACtD,aAAS;AAAA,EACX,CAAC;AACD,UAAQ,iBAAiB,2BAA2B,MAAM;AACxD,aAAS;AAAA,EACX,CAAC;AACH;AAKA,eAAsB,qBAAqB,WAA+C;AACxF,QAAM,KAAK,aAAa,eAAe;AAEvC,MAAI,CAAC,IAAI;AACP,UAAM,IAAI;AAAA,MACR;AAAA,IACF;AAAA,EACF;AAEA,QAAM,gBAAgB;AAAA,IACpB,MAAM;AAAA,IACN,MAAM;AAAA,IACN,YAAY,CAAC,QAAQ;AAAA,IACrB,eAAe,CAAC;AAAA,IAChB,qBAAqB;AAAA,EACvB;AACA,QAAM,MAAM,GAAG,gBAAgB,GAAG,cAAc,IAAI,EAAE,QAAQ,oBAAI,IAAI,GAAG,SAAS,oBAAI,IAAI,EAAE;AAC5F,QAAM,GAAG,QAAQ,eAAe,GAAG;AACrC;AAGA,IAAI,eAAe,GAAG;AACpB,uBAAqB,EAAE,MAAM,QAAQ,KAAK;AAC5C;AAEA,IAAO,uBAAQ;AAAA,EACb,QAAQ,mBAAmB;AAAA,EAC3B,UAAU;AAAA,EACV,UAAU;AACZ;","names":[]}
@@ -3,8 +3,8 @@ import {
3
3
  clickOutsideSource,
4
4
  clickoutside_default,
5
5
  registerClickOutside
6
- } from "../chunk-DYHBKDKB.js";
7
- import "../chunk-64DIQGQI.js";
6
+ } from "../chunk-ZZ2WSAX3.js";
7
+ import "../chunk-SLOXO6IY.js";
8
8
  import "../chunk-6TJXDCAQ.js";
9
9
  export {
10
10
  clickOutsideMetadata,
@@ -70,27 +70,49 @@ var clipboardSchema = {
70
70
  "navigator.clipboard.writeText() requires HTTPS or localhost",
71
71
  'Falls back to document.execCommand("copy") for older browsers'
72
72
  ],
73
- source: [
74
- "behavior Clipboard(text, source, feedback, feedbackDuration)",
75
- " init",
76
- " if feedbackDuration is undefined set feedbackDuration to 2000",
77
- " if source is undefined set source to me",
78
- " end",
79
- " on click",
80
- " if text is not undefined",
81
- " set copyText to text",
82
- " else",
83
- " set copyText to source's value or source's textContent",
84
- " end",
85
- " js(copyText) navigator.clipboard.writeText(copyText) end",
86
- " set feedbackEl to feedback or me",
87
- " add .copied to feedbackEl",
88
- " wait feedbackDuration ms",
89
- " remove .copied from feedbackEl",
90
- " trigger clipboard:copied",
91
- " end",
92
- "end"
93
- ].join("\n")
73
+ source: `
74
+ behavior Clipboard(text, source, feedback, feedbackDuration)
75
+ init
76
+ if feedbackDuration is undefined
77
+ set feedbackDuration to 2000
78
+ end
79
+ if source is undefined
80
+ set source to me
81
+ end
82
+ end
83
+ on click
84
+ if text is not undefined
85
+ set copyText to text
86
+ else
87
+ set copyText to source's textContent
88
+ end
89
+ js(me, copyText, feedback, feedbackDuration)
90
+ async function copyToClipboard(t) {
91
+ if (navigator.clipboard && navigator.clipboard.writeText) {
92
+ await navigator.clipboard.writeText(t);
93
+ return;
94
+ }
95
+ var ta = document.createElement('textarea');
96
+ ta.value = t;
97
+ ta.style.position = 'fixed';
98
+ ta.style.opacity = '0';
99
+ document.body.appendChild(ta);
100
+ ta.select();
101
+ try { document.execCommand('copy'); } finally { document.body.removeChild(ta); }
102
+ }
103
+ try {
104
+ await copyToClipboard(copyText);
105
+ var feedbackEl = feedback ? (typeof feedback === 'string' ? document.querySelector(feedback) : feedback) : me;
106
+ if (!feedbackEl) feedbackEl = me;
107
+ feedbackEl.classList.add('copied');
108
+ me.dispatchEvent(new CustomEvent('clipboard:copied', { bubbles: true, detail: { text: copyText } }));
109
+ setTimeout(function() { feedbackEl.classList.remove('copied'); }, feedbackDuration);
110
+ } catch(err) {
111
+ me.dispatchEvent(new CustomEvent('clipboard:error', { bubbles: true, detail: { error: err } }));
112
+ }
113
+ end
114
+ end
115
+ end`.trim()
94
116
  };
95
117
 
96
118
  // src/schemas/types.ts
@@ -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":[]}
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":";;;;;;;;;;;;;;;;;;;;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;;;ACQO,IAAM,kBAAkC;AAAA,EAC7C,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,aAAa;AAAA,IACf;AAAA,IACA;AAAA,MACE,MAAM;AAAA,MACN,MAAM;AAAA,MACN,UAAU;AAAA,MACV,SAAS;AAAA,MACT,aAAa;AAAA,IACf;AAAA,IACA;AAAA,MACE,MAAM;AAAA,MACN,MAAM;AAAA,MACN,UAAU;AAAA,MACV,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,oBAAoB,aAAa,0CAA0C;AAAA,IACnF,EAAE,MAAM,mBAAmB,aAAa,mCAAmC;AAAA,EAC7E;AAAA,EACA,cAAc;AAAA,IACZ;AAAA,IACA;AAAA,EACF;AAAA,EACA,QAAQ;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,KA0CL,KAAK;AACV;;;ACqBO,SAAS,iBAA4C;AAC1D,MAAI,OAAO,WAAW,YAAa,QAAO;AAC1C,QAAM,MAAM;AACZ,SAAO,IAAI,cAAc,IAAI,aAAa;AAC5C;;;AF1GO,IAAM,kBAAkB,gBAAgB;AACxC,IAAM,oBAAoB;AAMjC,eAAe,gBAAgB,MAA6B;AAC1D,MAAI,UAAU,WAAW,WAAW;AAClC,UAAM,UAAU,UAAU,UAAU,IAAI;AACxC;AAAA,EACF;AAGA,QAAM,WAAW,SAAS,cAAc,UAAU;AAClD,WAAS,QAAQ;AACjB,WAAS,MAAM,WAAW;AAC1B,WAAS,MAAM,UAAU;AACzB,WAAS,KAAK,YAAY,QAAQ;AAClC,WAAS,OAAO;AAChB,MAAI;AACF,aAAS,YAAY,MAAM;AAAA,EAC7B,UAAE;AACA,aAAS,KAAK,YAAY,QAAQ;AAAA,EACpC;AACF;AAKA,SAAS,eAAe,SAAsB,OAAoC;AAChF,MAAI,CAAC,SAAS,UAAU,KAAM,QAAO;AACrC,MAAI,iBAAiB,YAAa,QAAO;AACzC,MAAI,OAAO,UAAU,UAAU;AAC7B,WACG,QAAQ,cAAc,KAAK,KAC3B,SAAS,cAAc,KAAK,KAC7B;AAAA,EAEJ;AACA,SAAO;AACT;AAKA,SAAS,iBAAiB,SAAsB,QAAmC;AACjF,QAAM,mBACJ,OAAO,OAAO,qBAAqB,WAAW,OAAO,mBAAmB;AAE1E,UAAQ,iBAAiB,SAAS,YAAY;AAE5C,QAAI;AACJ,QAAI,OAAO,QAAQ,MAAM;AACvB,iBAAW,OAAO,OAAO,IAAI;AAAA,IAC/B,OAAO;AACL,YAAM,WAAW,eAAe,SAAS,OAAO,MAAM,KAAK;AAC3D,iBAAY,SAA8B,SAAS,SAAS,eAAe;AAAA,IAC7E;AAEA,QAAI;AACF,YAAM,gBAAgB,QAAQ;AAG9B,YAAM,aAAa,eAAe,SAAS,OAAO,QAAQ,KAAK;AAC/D,iBAAW,UAAU,IAAI,QAAQ;AACjC,iBAAW,MAAM,WAAW,UAAU,OAAO,QAAQ,GAAG,gBAAgB;AAExE,cAAQ;AAAA,QACN,IAAI,YAAY,oBAAoB;AAAA,UAClC,SAAS;AAAA,UACT,QAAQ,EAAE,MAAM,SAAS;AAAA,QAC3B,CAAC;AAAA,MACH;AAAA,IACF,SAAS,OAAO;AACd,cAAQ;AAAA,QACN,IAAI,YAAY,mBAAmB;AAAA,UACjC,SAAS;AAAA,UACT,QAAQ,EAAE,MAAM;AAAA,QAClB,CAAC;AAAA,MACH;AAAA,IACF;AAAA,EACF,CAAC;AACH;AAKA,eAAsB,kBAAkB,WAA+C;AACrF,QAAM,KAAK,aAAa,eAAe;AAEvC,MAAI,CAAC,IAAI;AACP,UAAM,IAAI;AAAA,MACR;AAAA,IACF;AAAA,EACF;AAEA,QAAM,gBAAgB;AAAA,IACpB,MAAM;AAAA,IACN,MAAM;AAAA,IACN,YAAY,CAAC,QAAQ,UAAU,YAAY,kBAAkB;AAAA,IAC7D,eAAe,CAAC;AAAA,IAChB,qBAAqB;AAAA,EACvB;AACA,QAAM,MAAM,GAAG,gBAAgB,GAAG,cAAc,IAAI,EAAE,QAAQ,oBAAI,IAAI,GAAG,SAAS,oBAAI,IAAI,EAAE;AAC5F,QAAM,GAAG,QAAQ,eAAe,GAAG;AACrC;AAGA,IAAI,eAAe,GAAG;AACpB,oBAAkB,EAAE,MAAM,QAAQ,KAAK;AACzC;AAEA,IAAO,oBAAQ;AAAA,EACb,QAAQ,gBAAgB;AAAA,EACxB,UAAU;AAAA,EACV,UAAU;AACZ;","names":[]}
@@ -3,8 +3,8 @@ import {
3
3
  clipboardSource,
4
4
  clipboard_default,
5
5
  registerClipboard
6
- } from "../chunk-2NSKQMNM.js";
7
- import "../chunk-QKDYW4VM.js";
6
+ } from "../chunk-7O7UOSBH.js";
7
+ import "../chunk-WOTZO7K4.js";
8
8
  import "../chunk-6TJXDCAQ.js";
9
9
  export {
10
10
  clipboardMetadata,
@@ -67,10 +67,51 @@ var focusTrapSchema = {
67
67
  source: `
68
68
  behavior FocusTrap(active, initialFocus, returnFocus)
69
69
  init
70
- if active is undefined set active to true
71
- if returnFocus is undefined set returnFocus to true
70
+ if active is undefined
71
+ set active to true
72
+ end
73
+ if returnFocus is undefined
74
+ set returnFocus to true
75
+ end
76
+ js(me, active, initialFocus, returnFocus)
77
+ var FOCUSABLE = 'a[href],button:not(:disabled),input:not(:disabled),select:not(:disabled),textarea:not(:disabled),[tabindex]:not([tabindex="-1"])';
78
+ var isActive = false;
79
+ var previouslyFocused = null;
80
+ function getFocusable() { return Array.from(me.querySelectorAll(FOCUSABLE)); }
81
+ function activate() {
82
+ if (isActive) return;
83
+ isActive = true;
84
+ previouslyFocused = document.activeElement;
85
+ me.setAttribute('aria-modal', 'true');
86
+ var initEl = initialFocus ? (typeof initialFocus === 'string' ? me.querySelector(initialFocus) : initialFocus) : null;
87
+ if (initEl) { initEl.focus(); } else { var f = getFocusable(); if (f.length) f[0].focus(); }
88
+ me.dispatchEvent(new CustomEvent('focustrap:activated', { bubbles: true }));
89
+ }
90
+ function deactivate() {
91
+ if (!isActive) return;
92
+ isActive = false;
93
+ me.removeAttribute('aria-modal');
94
+ if (returnFocus && previouslyFocused instanceof HTMLElement) previouslyFocused.focus();
95
+ previouslyFocused = null;
96
+ me.dispatchEvent(new CustomEvent('focustrap:deactivated', { bubbles: true }));
97
+ }
98
+ me.addEventListener('keydown', function(e) {
99
+ if (!isActive || e.key !== 'Tab') return;
100
+ var focusable = getFocusable();
101
+ if (focusable.length === 0) { e.preventDefault(); return; }
102
+ e.preventDefault();
103
+ var idx = focusable.indexOf(document.activeElement);
104
+ if (e.shiftKey) {
105
+ focusable[idx <= 0 ? focusable.length - 1 : idx - 1].focus();
106
+ } else {
107
+ focusable[idx >= focusable.length - 1 ? 0 : idx + 1].focus();
108
+ }
109
+ });
110
+ me.addEventListener('focustrap:activate', function() { activate(); });
111
+ me.addEventListener('focustrap:deactivate', function() { deactivate(); });
112
+ if (active) activate();
113
+ end
72
114
  end
73
- -- Imperative installer handles Tab key trapping and focus management
74
115
  end`.trim()
75
116
  };
76
117