@hyperfixi/behaviors 2.0.0 → 2.1.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (189) hide show
  1. package/dist/all.browser.global.js +35 -6
  2. package/dist/all.browser.global.js.map +1 -1
  3. package/dist/autodismiss.browser.global.js +3 -0
  4. package/dist/autodismiss.browser.global.js.map +1 -0
  5. package/dist/behaviors/autodismiss.cjs +177 -0
  6. package/dist/behaviors/autodismiss.cjs.map +1 -0
  7. package/dist/behaviors/autodismiss.d.cts +15 -0
  8. package/dist/behaviors/autodismiss.d.ts +15 -0
  9. package/dist/behaviors/autodismiss.js +15 -0
  10. package/dist/behaviors/autodismiss.js.map +1 -0
  11. package/dist/behaviors/clickoutside.cjs +123 -0
  12. package/dist/behaviors/clickoutside.cjs.map +1 -0
  13. package/dist/behaviors/clickoutside.d.cts +15 -0
  14. package/dist/behaviors/clickoutside.d.ts +15 -0
  15. package/dist/behaviors/clickoutside.js +15 -0
  16. package/dist/behaviors/clickoutside.js.map +1 -0
  17. package/dist/behaviors/clipboard.cjs +193 -0
  18. package/dist/behaviors/clipboard.cjs.map +1 -0
  19. package/dist/behaviors/clipboard.d.cts +15 -0
  20. package/dist/behaviors/clipboard.d.ts +15 -0
  21. package/dist/behaviors/clipboard.js +15 -0
  22. package/dist/behaviors/clipboard.js.map +1 -0
  23. package/dist/behaviors/draggable.cjs +49 -7
  24. package/dist/behaviors/draggable.cjs.map +1 -1
  25. package/dist/behaviors/draggable.d.cts +2 -1
  26. package/dist/behaviors/draggable.d.ts +2 -1
  27. package/dist/behaviors/draggable.js +2 -1
  28. package/dist/behaviors/focustrap.cjs +191 -0
  29. package/dist/behaviors/focustrap.cjs.map +1 -0
  30. package/dist/behaviors/focustrap.d.cts +15 -0
  31. package/dist/behaviors/focustrap.d.ts +15 -0
  32. package/dist/behaviors/focustrap.js +15 -0
  33. package/dist/behaviors/focustrap.js.map +1 -0
  34. package/dist/behaviors/removable.cjs +9 -2
  35. package/dist/behaviors/removable.cjs.map +1 -1
  36. package/dist/behaviors/removable.d.cts +1 -1
  37. package/dist/behaviors/removable.d.ts +1 -1
  38. package/dist/behaviors/removable.js +2 -1
  39. package/dist/behaviors/resizable.cjs +54 -7
  40. package/dist/behaviors/resizable.cjs.map +1 -1
  41. package/dist/behaviors/resizable.d.cts +1 -1
  42. package/dist/behaviors/resizable.d.ts +1 -1
  43. package/dist/behaviors/resizable.js +2 -1
  44. package/dist/behaviors/scrollreveal.cjs +149 -0
  45. package/dist/behaviors/scrollreveal.cjs.map +1 -0
  46. package/dist/behaviors/scrollreveal.d.cts +15 -0
  47. package/dist/behaviors/scrollreveal.d.ts +15 -0
  48. package/dist/behaviors/scrollreveal.js +15 -0
  49. package/dist/behaviors/scrollreveal.js.map +1 -0
  50. package/dist/behaviors/sortable.cjs +49 -7
  51. package/dist/behaviors/sortable.cjs.map +1 -1
  52. package/dist/behaviors/sortable.d.cts +1 -1
  53. package/dist/behaviors/sortable.d.ts +1 -1
  54. package/dist/behaviors/sortable.js +2 -1
  55. package/dist/behaviors/tabs.cjs +247 -0
  56. package/dist/behaviors/tabs.cjs.map +1 -0
  57. package/dist/behaviors/tabs.d.cts +15 -0
  58. package/dist/behaviors/tabs.d.ts +15 -0
  59. package/dist/behaviors/tabs.js +15 -0
  60. package/dist/behaviors/tabs.js.map +1 -0
  61. package/dist/behaviors/toggleable.cjs +36 -7
  62. package/dist/behaviors/toggleable.cjs.map +1 -1
  63. package/dist/behaviors/toggleable.d.cts +2 -1
  64. package/dist/behaviors/toggleable.d.ts +2 -1
  65. package/dist/behaviors/toggleable.js +2 -1
  66. package/dist/chunk-244WSZOL.js +67 -0
  67. package/dist/chunk-244WSZOL.js.map +1 -0
  68. package/dist/chunk-2NSKQMNM.js +99 -0
  69. package/dist/chunk-2NSKQMNM.js.map +1 -0
  70. package/dist/chunk-64DIQGQI.js +37 -0
  71. package/dist/chunk-64DIQGQI.js.map +1 -0
  72. package/dist/chunk-6TJXDCAQ.js +11 -0
  73. package/dist/chunk-6TJXDCAQ.js.map +1 -0
  74. package/dist/chunk-7JDV2THA.js +62 -0
  75. package/dist/chunk-7JDV2THA.js.map +1 -0
  76. package/dist/chunk-AFGA54SA.js +116 -0
  77. package/dist/chunk-AFGA54SA.js.map +1 -0
  78. package/dist/chunk-DYHBKDKB.js +62 -0
  79. package/dist/chunk-DYHBKDKB.js.map +1 -0
  80. package/dist/chunk-GPTHAUWN.js +58 -0
  81. package/dist/chunk-GPTHAUWN.js.map +1 -0
  82. package/dist/chunk-GVJPA2EK.js +68 -0
  83. package/dist/chunk-GVJPA2EK.js.map +1 -0
  84. package/dist/chunk-H2MCHR5A.js +89 -0
  85. package/dist/chunk-H2MCHR5A.js.map +1 -0
  86. package/dist/{chunk-2NQHIHD5.js → chunk-H5Y5ARYG.js} +6 -3
  87. package/dist/chunk-H5Y5ARYG.js.map +1 -0
  88. package/dist/chunk-JKBWIJFI.js +155 -0
  89. package/dist/chunk-JKBWIJFI.js.map +1 -0
  90. package/dist/chunk-QKDYW4VM.js +70 -0
  91. package/dist/chunk-QKDYW4VM.js.map +1 -0
  92. package/dist/chunk-RB7OB6OD.js +51 -0
  93. package/dist/chunk-RB7OB6OD.js.map +1 -0
  94. package/dist/chunk-RPERQTFU.js +75 -0
  95. package/dist/chunk-RPERQTFU.js.map +1 -0
  96. package/dist/chunk-S4QDV2MH.js +75 -0
  97. package/dist/chunk-S4QDV2MH.js.map +1 -0
  98. package/dist/chunk-WTUVPVSD.js +80 -0
  99. package/dist/chunk-WTUVPVSD.js.map +1 -0
  100. package/dist/chunk-YHQRFUWV.js +62 -0
  101. package/dist/chunk-YHQRFUWV.js.map +1 -0
  102. package/dist/chunk-ZQQZTMCJ.js +64 -0
  103. package/dist/chunk-ZQQZTMCJ.js.map +1 -0
  104. package/dist/clickoutside.browser.global.js +12 -0
  105. package/dist/clickoutside.browser.global.js.map +1 -0
  106. package/dist/clipboard.browser.global.js +3 -0
  107. package/dist/clipboard.browser.global.js.map +1 -0
  108. package/dist/core.browser.global.js +3 -3
  109. package/dist/core.browser.global.js.map +1 -1
  110. package/dist/draggable.browser.global.js +2 -2
  111. package/dist/draggable.browser.global.js.map +1 -1
  112. package/dist/focustrap.browser.global.js +9 -0
  113. package/dist/focustrap.browser.global.js.map +1 -0
  114. package/dist/index.cjs +1270 -50
  115. package/dist/index.cjs.map +1 -1
  116. package/dist/index.d.cts +13 -7
  117. package/dist/index.d.ts +13 -7
  118. package/dist/index.js +155 -48
  119. package/dist/index.js.map +1 -1
  120. package/dist/loaders.cjs +1151 -30
  121. package/dist/loaders.cjs.map +1 -1
  122. package/dist/loaders.js +9 -3
  123. package/dist/registry.d.cts +1 -1
  124. package/dist/registry.d.ts +1 -1
  125. package/dist/removable.browser.global.js +2 -2
  126. package/dist/removable.browser.global.js.map +1 -1
  127. package/dist/resizable.browser.global.js +2 -2
  128. package/dist/resizable.browser.global.js.map +1 -1
  129. package/dist/schemas/index.cjs +343 -1
  130. package/dist/schemas/index.cjs.map +1 -1
  131. package/dist/schemas/index.d.cts +45 -3
  132. package/dist/schemas/index.d.ts +45 -3
  133. package/dist/schemas/index.js +34 -4
  134. package/dist/schemas/index.js.map +1 -1
  135. package/dist/scrollreveal.browser.global.js +11 -0
  136. package/dist/scrollreveal.browser.global.js.map +1 -0
  137. package/dist/sortable.browser.global.js +2 -2
  138. package/dist/sortable.browser.global.js.map +1 -1
  139. package/dist/tabs.browser.global.js +3 -0
  140. package/dist/tabs.browser.global.js.map +1 -0
  141. package/dist/toggleable.browser.global.js +2 -2
  142. package/dist/toggleable.browser.global.js.map +1 -1
  143. package/dist/{types-CCc_2wAb.d.cts → types-DCCtVQS5.d.cts} +1 -1
  144. package/dist/{types-CCc_2wAb.d.ts → types-DCCtVQS5.d.ts} +1 -1
  145. package/package.json +45 -2
  146. package/src/behaviors/autodismiss.test.ts +61 -0
  147. package/src/behaviors/autodismiss.ts +107 -0
  148. package/src/behaviors/clickoutside.test.ts +52 -0
  149. package/src/behaviors/clickoutside.ts +77 -0
  150. package/src/behaviors/clipboard.test.ts +67 -0
  151. package/src/behaviors/clipboard.ts +130 -0
  152. package/src/behaviors/draggable.ts +62 -15
  153. package/src/behaviors/focustrap.test.ts +59 -0
  154. package/src/behaviors/focustrap.ts +158 -0
  155. package/src/behaviors/index.ts +37 -0
  156. package/src/behaviors/integration.test.ts +120 -45
  157. package/src/behaviors/removable.ts +4 -5
  158. package/src/behaviors/resizable.ts +63 -14
  159. package/src/behaviors/scrollreveal.test.ts +59 -0
  160. package/src/behaviors/scrollreveal.ts +78 -0
  161. package/src/behaviors/sortable.ts +61 -14
  162. package/src/behaviors/tabs.test.ts +81 -0
  163. package/src/behaviors/tabs.ts +196 -0
  164. package/src/behaviors/toggleable.ts +45 -13
  165. package/src/generated/metadata.ts +38 -7
  166. package/src/generated/types.ts +5 -5
  167. package/src/index.test.ts +143 -5
  168. package/src/index.ts +65 -13
  169. package/src/loaders.ts +18 -0
  170. package/src/registry.test.ts +26 -5
  171. package/src/schemas/autodismiss.schema.ts +66 -0
  172. package/src/schemas/clickoutside.schema.ts +39 -0
  173. package/src/schemas/clipboard.schema.ts +72 -0
  174. package/src/schemas/focustrap.schema.ts +53 -0
  175. package/src/schemas/index.ts +18 -0
  176. package/src/schemas/scrollreveal.schema.ts +60 -0
  177. package/src/schemas/tabs.schema.ts +66 -0
  178. package/src/schemas/types.ts +13 -1
  179. package/dist/chunk-2NQHIHD5.js.map +0 -1
  180. package/dist/chunk-3Q652JQB.js +0 -37
  181. package/dist/chunk-3Q652JQB.js.map +0 -1
  182. package/dist/chunk-HMRPQWQU.js +0 -37
  183. package/dist/chunk-HMRPQWQU.js.map +0 -1
  184. package/dist/chunk-MEP6B7XW.js +0 -37
  185. package/dist/chunk-MEP6B7XW.js.map +0 -1
  186. package/dist/chunk-URBOGGW6.js +0 -32
  187. package/dist/chunk-URBOGGW6.js.map +0 -1
  188. package/dist/chunk-WU37DFAL.js +0 -37
  189. package/dist/chunk-WU37DFAL.js.map +0 -1
@@ -0,0 +1,155 @@
1
+ import {
2
+ tabsSchema
3
+ } from "./chunk-GVJPA2EK.js";
4
+ import {
5
+ resolveRuntime
6
+ } from "./chunk-6TJXDCAQ.js";
7
+
8
+ // src/behaviors/tabs.ts
9
+ var tabsSource = tabsSchema.source;
10
+ var tabsMetadata = tabsSchema;
11
+ var idCounter = 0;
12
+ function ensureId(el, prefix) {
13
+ if (!el.id) {
14
+ el.id = `${prefix}-${++idCounter}`;
15
+ }
16
+ return el.id;
17
+ }
18
+ function installTabs(element, params) {
19
+ const orientation = params.orientation === "vertical" ? "vertical" : "horizontal";
20
+ const wrap = params.wrap !== false;
21
+ const activeClass = params.activeClass || "active";
22
+ const initialIndex = typeof params.activeTab === "number" ? params.activeTab : 0;
23
+ const tabs = Array.from(element.querySelectorAll('[role="tab"]'));
24
+ const panels = Array.from(element.querySelectorAll('[role="tabpanel"]'));
25
+ if (tabs.length === 0 || panels.length === 0) return;
26
+ const tablist = element.querySelector('[role="tablist"]') || tabs[0].parentElement;
27
+ if (tablist && !tablist.getAttribute("role")) {
28
+ tablist.setAttribute("role", "tablist");
29
+ }
30
+ if (tablist) {
31
+ tablist.setAttribute("aria-orientation", orientation);
32
+ }
33
+ const count = Math.min(tabs.length, panels.length);
34
+ for (let i = 0; i < count; i++) {
35
+ const tabId = ensureId(tabs[i], "tab");
36
+ const panelId = ensureId(panels[i], "tabpanel");
37
+ tabs[i].setAttribute("aria-controls", panelId);
38
+ panels[i].setAttribute("aria-labelledby", tabId);
39
+ }
40
+ let currentIndex = -1;
41
+ function selectTab(index, previousIndex) {
42
+ if (index === previousIndex || index < 0 || index >= count) return false;
43
+ const detail = {
44
+ tab: tabs[index],
45
+ panel: panels[index],
46
+ index,
47
+ previousIndex
48
+ };
49
+ const changeEvent = new CustomEvent("tabs:change", {
50
+ bubbles: true,
51
+ cancelable: true,
52
+ detail
53
+ });
54
+ element.dispatchEvent(changeEvent);
55
+ if (changeEvent.defaultPrevented) return false;
56
+ if (previousIndex >= 0 && previousIndex < count) {
57
+ tabs[previousIndex].setAttribute("aria-selected", "false");
58
+ tabs[previousIndex].setAttribute("tabindex", "-1");
59
+ tabs[previousIndex].classList.remove(activeClass);
60
+ panels[previousIndex].setAttribute("aria-hidden", "true");
61
+ panels[previousIndex].classList.remove(activeClass);
62
+ }
63
+ tabs[index].setAttribute("aria-selected", "true");
64
+ tabs[index].setAttribute("tabindex", "0");
65
+ tabs[index].classList.add(activeClass);
66
+ panels[index].setAttribute("aria-hidden", "false");
67
+ panels[index].classList.add(activeClass);
68
+ currentIndex = index;
69
+ element.dispatchEvent(new CustomEvent("tabs:changed", { bubbles: true, detail }));
70
+ return true;
71
+ }
72
+ for (let i = 0; i < count; i++) {
73
+ tabs[i].setAttribute("aria-selected", "false");
74
+ tabs[i].setAttribute("tabindex", "-1");
75
+ tabs[i].classList.remove(activeClass);
76
+ panels[i].setAttribute("aria-hidden", "true");
77
+ panels[i].classList.remove(activeClass);
78
+ }
79
+ const clamped = Math.max(0, Math.min(initialIndex, count - 1));
80
+ tabs[clamped].setAttribute("aria-selected", "true");
81
+ tabs[clamped].setAttribute("tabindex", "0");
82
+ tabs[clamped].classList.add(activeClass);
83
+ panels[clamped].setAttribute("aria-hidden", "false");
84
+ panels[clamped].classList.add(activeClass);
85
+ currentIndex = clamped;
86
+ for (let i = 0; i < count; i++) {
87
+ tabs[i].addEventListener("click", () => {
88
+ selectTab(i, currentIndex);
89
+ tabs[i].focus();
90
+ });
91
+ }
92
+ const keyTarget = tablist || element;
93
+ keyTarget.addEventListener("keydown", (e) => {
94
+ const isHorizontal = orientation === "horizontal";
95
+ const nextKey = isHorizontal ? "ArrowRight" : "ArrowDown";
96
+ const prevKey = isHorizontal ? "ArrowLeft" : "ArrowUp";
97
+ let nextIndex = null;
98
+ if (e.key === nextKey) {
99
+ nextIndex = currentIndex + 1;
100
+ if (nextIndex >= count) nextIndex = wrap ? 0 : null;
101
+ } else if (e.key === prevKey) {
102
+ nextIndex = currentIndex - 1;
103
+ if (nextIndex < 0) nextIndex = wrap ? count - 1 : null;
104
+ } else if (e.key === "Home") {
105
+ nextIndex = 0;
106
+ } else if (e.key === "End") {
107
+ nextIndex = count - 1;
108
+ }
109
+ if (nextIndex !== null) {
110
+ e.preventDefault();
111
+ if (selectTab(nextIndex, currentIndex)) {
112
+ tabs[nextIndex].focus();
113
+ }
114
+ }
115
+ });
116
+ element.addEventListener("tabs:select", ((e) => {
117
+ const index = e.detail?.index;
118
+ if (typeof index === "number") {
119
+ selectTab(index, currentIndex);
120
+ }
121
+ }));
122
+ }
123
+ async function registerTabs(hyperfixi) {
124
+ const hf = hyperfixi || resolveRuntime();
125
+ if (!hf) {
126
+ throw new Error(
127
+ "LokaScript not found. Make sure @hyperfixi/core is loaded before registering behaviors."
128
+ );
129
+ }
130
+ const syntheticNode = {
131
+ type: "behavior",
132
+ name: "Tabs",
133
+ parameters: ["orientation", "activeTab", "wrap", "activeClass"],
134
+ eventHandlers: [],
135
+ imperativeInstaller: installTabs
136
+ };
137
+ const ctx = hf.createContext ? hf.createContext() : { locals: /* @__PURE__ */ new Map(), globals: /* @__PURE__ */ new Map() };
138
+ await hf.execute(syntheticNode, ctx);
139
+ }
140
+ if (resolveRuntime()) {
141
+ registerTabs().catch(console.error);
142
+ }
143
+ var tabs_default = {
144
+ source: tabsSchema.source,
145
+ metadata: tabsSchema,
146
+ register: registerTabs
147
+ };
148
+
149
+ export {
150
+ tabsSource,
151
+ tabsMetadata,
152
+ registerTabs,
153
+ tabs_default
154
+ };
155
+ //# sourceMappingURL=chunk-JKBWIJFI.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../src/behaviors/tabs.ts"],"sourcesContent":["/**\n * Tabs Behavior — Imperative Implementation\n *\n * WAI-ARIA compliant tabs with roving tabindex keyboard navigation.\n * Auto-wires role, aria-selected, aria-controls, and aria-labelledby.\n */\n\nimport { tabsSchema } from '../schemas/tabs.schema';\nimport type { LokaScriptInstance } from '../schemas/types';\nimport { resolveRuntime } from '../schemas/types';\n\nexport const tabsSource = tabsSchema.source;\nexport const tabsMetadata = tabsSchema;\n\nlet idCounter = 0;\n\nfunction ensureId(el: HTMLElement, prefix: string): string {\n if (!el.id) {\n el.id = `${prefix}-${++idCounter}`;\n }\n return el.id;\n}\n\n/**\n * Imperative installer for Tabs behavior.\n */\nfunction installTabs(element: HTMLElement, params: Record<string, any>): void {\n const orientation = params.orientation === 'vertical' ? 'vertical' : 'horizontal';\n const wrap = params.wrap !== false;\n const activeClass = (params.activeClass as string) || 'active';\n const initialIndex = typeof params.activeTab === 'number' ? params.activeTab : 0;\n\n // Discover tabs and panels\n const tabs = Array.from(element.querySelectorAll<HTMLElement>('[role=\"tab\"]'));\n const panels = Array.from(element.querySelectorAll<HTMLElement>('[role=\"tabpanel\"]'));\n\n if (tabs.length === 0 || panels.length === 0) return;\n\n // Find or mark the tablist\n const tablist = element.querySelector<HTMLElement>('[role=\"tablist\"]') || tabs[0].parentElement;\n if (tablist && !tablist.getAttribute('role')) {\n tablist.setAttribute('role', 'tablist');\n }\n if (tablist) {\n tablist.setAttribute('aria-orientation', orientation);\n }\n\n // Wire IDs, aria-controls, aria-labelledby\n const count = Math.min(tabs.length, panels.length);\n for (let i = 0; i < count; i++) {\n const tabId = ensureId(tabs[i], 'tab');\n const panelId = ensureId(panels[i], 'tabpanel');\n tabs[i].setAttribute('aria-controls', panelId);\n panels[i].setAttribute('aria-labelledby', tabId);\n }\n\n let currentIndex = -1;\n\n function selectTab(index: number, previousIndex: number): boolean {\n if (index === previousIndex || index < 0 || index >= count) return false;\n\n const detail = {\n tab: tabs[index],\n panel: panels[index],\n index,\n previousIndex,\n };\n\n // Cancelable before-event\n const changeEvent = new CustomEvent('tabs:change', {\n bubbles: true,\n cancelable: true,\n detail,\n });\n element.dispatchEvent(changeEvent);\n if (changeEvent.defaultPrevented) return false;\n\n // Deactivate previous\n if (previousIndex >= 0 && previousIndex < count) {\n tabs[previousIndex].setAttribute('aria-selected', 'false');\n tabs[previousIndex].setAttribute('tabindex', '-1');\n tabs[previousIndex].classList.remove(activeClass);\n panels[previousIndex].setAttribute('aria-hidden', 'true');\n panels[previousIndex].classList.remove(activeClass);\n }\n\n // Activate new\n tabs[index].setAttribute('aria-selected', 'true');\n tabs[index].setAttribute('tabindex', '0');\n tabs[index].classList.add(activeClass);\n panels[index].setAttribute('aria-hidden', 'false');\n panels[index].classList.add(activeClass);\n\n currentIndex = index;\n\n element.dispatchEvent(new CustomEvent('tabs:changed', { bubbles: true, detail }));\n return true;\n }\n\n // Initialize all tabs as inactive, then activate initial\n for (let i = 0; i < count; i++) {\n tabs[i].setAttribute('aria-selected', 'false');\n tabs[i].setAttribute('tabindex', '-1');\n tabs[i].classList.remove(activeClass);\n panels[i].setAttribute('aria-hidden', 'true');\n panels[i].classList.remove(activeClass);\n }\n\n const clamped = Math.max(0, Math.min(initialIndex, count - 1));\n // Directly activate without firing change event on init\n tabs[clamped].setAttribute('aria-selected', 'true');\n tabs[clamped].setAttribute('tabindex', '0');\n tabs[clamped].classList.add(activeClass);\n panels[clamped].setAttribute('aria-hidden', 'false');\n panels[clamped].classList.add(activeClass);\n currentIndex = clamped;\n\n // Click handler\n for (let i = 0; i < count; i++) {\n tabs[i].addEventListener('click', () => {\n selectTab(i, currentIndex);\n tabs[i].focus();\n });\n }\n\n // Keyboard handler on tablist\n const keyTarget = tablist || element;\n keyTarget.addEventListener('keydown', (e: KeyboardEvent) => {\n const isHorizontal = orientation === 'horizontal';\n const nextKey = isHorizontal ? 'ArrowRight' : 'ArrowDown';\n const prevKey = isHorizontal ? 'ArrowLeft' : 'ArrowUp';\n\n let nextIndex: number | null = null;\n\n if (e.key === nextKey) {\n nextIndex = currentIndex + 1;\n if (nextIndex >= count) nextIndex = wrap ? 0 : null;\n } else if (e.key === prevKey) {\n nextIndex = currentIndex - 1;\n if (nextIndex < 0) nextIndex = wrap ? count - 1 : null;\n } else if (e.key === 'Home') {\n nextIndex = 0;\n } else if (e.key === 'End') {\n nextIndex = count - 1;\n }\n\n if (nextIndex !== null) {\n e.preventDefault();\n if (selectTab(nextIndex, currentIndex)) {\n tabs[nextIndex].focus();\n }\n }\n });\n\n // Programmatic tab selection\n element.addEventListener('tabs:select', ((e: CustomEvent) => {\n const index = e.detail?.index;\n if (typeof index === 'number') {\n selectTab(index, currentIndex);\n }\n }) as EventListener);\n}\n\n/**\n * Register the Tabs behavior with LokaScript.\n */\nexport async function registerTabs(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: 'Tabs',\n parameters: ['orientation', 'activeTab', 'wrap', 'activeClass'],\n eventHandlers: [],\n imperativeInstaller: installTabs,\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 registerTabs().catch(console.error);\n}\n\nexport default {\n source: tabsSchema.source,\n metadata: tabsSchema,\n register: registerTabs,\n};\n"],"mappings":"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","names":[]}
@@ -0,0 +1,70 @@
1
+ // src/schemas/clipboard.schema.ts
2
+ var clipboardSchema = {
3
+ name: "Clipboard",
4
+ category: "ui",
5
+ tier: "core",
6
+ version: "1.0.0",
7
+ description: "Copies text to clipboard on click with visual feedback",
8
+ parameters: [
9
+ {
10
+ name: "text",
11
+ type: "string",
12
+ optional: true,
13
+ description: "Literal text to copy (takes priority over source)"
14
+ },
15
+ {
16
+ name: "source",
17
+ type: "selector",
18
+ optional: true,
19
+ default: "me",
20
+ description: "Element whose textContent or value is copied"
21
+ },
22
+ {
23
+ name: "feedback",
24
+ type: "selector",
25
+ optional: true,
26
+ description: "Element to show .copied feedback on (defaults to the installed element)"
27
+ },
28
+ {
29
+ name: "feedbackDuration",
30
+ type: "number",
31
+ optional: true,
32
+ default: 2e3,
33
+ description: "Duration in ms to show .copied class feedback"
34
+ }
35
+ ],
36
+ events: [
37
+ { name: "clipboard:copied", description: "Fired after text is copied successfully" },
38
+ { name: "clipboard:error", description: "Fired when clipboard write fails" }
39
+ ],
40
+ requirements: [
41
+ "navigator.clipboard.writeText() requires HTTPS or localhost",
42
+ 'Falls back to document.execCommand("copy") for older browsers'
43
+ ],
44
+ source: [
45
+ "behavior Clipboard(text, source, feedback, feedbackDuration)",
46
+ " init",
47
+ " if feedbackDuration is undefined set feedbackDuration to 2000",
48
+ " if source is undefined set source to me",
49
+ " end",
50
+ " on click",
51
+ " if text is not undefined",
52
+ " set copyText to text",
53
+ " else",
54
+ " set copyText to source's value or source's textContent",
55
+ " end",
56
+ " js(copyText) navigator.clipboard.writeText(copyText) end",
57
+ " set feedbackEl to feedback or me",
58
+ " add .copied to feedbackEl",
59
+ " wait feedbackDuration ms",
60
+ " remove .copied from feedbackEl",
61
+ " trigger clipboard:copied",
62
+ " end",
63
+ "end"
64
+ ].join("\n")
65
+ };
66
+
67
+ export {
68
+ clipboardSchema
69
+ };
70
+ //# sourceMappingURL=chunk-QKDYW4VM.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../src/schemas/clipboard.schema.ts"],"sourcesContent":["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"],"mappings":";AAQO,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,IACN;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,EACF,EAAE,KAAK,IAAI;AACb;","names":[]}
@@ -0,0 +1,51 @@
1
+ // src/schemas/focustrap.schema.ts
2
+ var focusTrapSchema = {
3
+ name: "FocusTrap",
4
+ category: "ui",
5
+ tier: "core",
6
+ version: "1.0.0",
7
+ description: "Confines Tab navigation inside an element with ARIA support",
8
+ parameters: [
9
+ {
10
+ name: "active",
11
+ type: "boolean",
12
+ optional: true,
13
+ default: true,
14
+ description: "Whether the trap is active on install"
15
+ },
16
+ {
17
+ name: "initialFocus",
18
+ type: "selector",
19
+ optional: true,
20
+ description: "Element to focus when the trap activates"
21
+ },
22
+ {
23
+ name: "returnFocus",
24
+ type: "boolean",
25
+ optional: true,
26
+ default: true,
27
+ description: "Restore focus to the previously focused element on deactivation"
28
+ }
29
+ ],
30
+ events: [
31
+ { name: "focustrap:activated", description: "Fired when the trap is activated" },
32
+ { name: "focustrap:deactivated", description: "Fired when the trap is deactivated" }
33
+ ],
34
+ requirements: [
35
+ 'Sets aria-modal="true" on the element when active',
36
+ "Listens for focustrap:activate and focustrap:deactivate custom events for programmatic control"
37
+ ],
38
+ source: `
39
+ behavior FocusTrap(active, initialFocus, returnFocus)
40
+ init
41
+ if active is undefined set active to true
42
+ if returnFocus is undefined set returnFocus to true
43
+ end
44
+ -- Imperative installer handles Tab key trapping and focus management
45
+ end`.trim()
46
+ };
47
+
48
+ export {
49
+ focusTrapSchema
50
+ };
51
+ //# sourceMappingURL=chunk-RB7OB6OD.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../src/schemas/focustrap.schema.ts"],"sourcesContent":["import type { BehaviorSchema } from './types';\n\n/**\n * FocusTrap Behavior Schema\n *\n * Confines Tab navigation inside an element and restores focus on release.\n * Manages aria-modal for accessibility compliance.\n */\nexport const focusTrapSchema: BehaviorSchema = {\n name: 'FocusTrap',\n category: 'ui',\n tier: 'core',\n version: '1.0.0',\n description: 'Confines Tab navigation inside an element with ARIA support',\n parameters: [\n {\n name: 'active',\n type: 'boolean',\n optional: true,\n default: true,\n description: 'Whether the trap is active on install',\n },\n {\n name: 'initialFocus',\n type: 'selector',\n optional: true,\n description: 'Element to focus when the trap activates',\n },\n {\n name: 'returnFocus',\n type: 'boolean',\n optional: true,\n default: true,\n description: 'Restore focus to the previously focused element on deactivation',\n },\n ],\n events: [\n { name: 'focustrap:activated', description: 'Fired when the trap is activated' },\n { name: 'focustrap:deactivated', description: 'Fired when the trap is deactivated' },\n ],\n requirements: [\n 'Sets aria-modal=\"true\" on the element when active',\n 'Listens for focustrap:activate and focustrap:deactivate custom events for programmatic control',\n ],\n source: `\nbehavior FocusTrap(active, initialFocus, returnFocus)\n init\n if active is undefined set active to true\n if returnFocus is undefined set returnFocus to true\n end\n -- Imperative installer handles Tab key trapping and focus management\nend`.trim(),\n};\n"],"mappings":";AAQO,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,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,uBAAuB,aAAa,mCAAmC;AAAA,IAC/E,EAAE,MAAM,yBAAyB,aAAa,qCAAqC;AAAA,EACrF;AAAA,EACA,cAAc;AAAA,IACZ;AAAA,IACA;AAAA,EACF;AAAA,EACA,QAAQ;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,KAOL,KAAK;AACV;","names":[]}
@@ -0,0 +1,75 @@
1
+ import {
2
+ sortableSchema
3
+ } from "./chunk-BWZ6EGII.js";
4
+ import {
5
+ resolveRuntime
6
+ } from "./chunk-6TJXDCAQ.js";
7
+
8
+ // src/behaviors/sortable.ts
9
+ var sortableSource = sortableSchema.source;
10
+ var sortableMetadata = sortableSchema;
11
+ function installSortable(element, params) {
12
+ const dragClass = params.dragClass || "sorting";
13
+ const handleSelector = params.handle || null;
14
+ element.addEventListener("pointerdown", (e) => {
15
+ const target = e.target;
16
+ const item = target.closest("li");
17
+ if (!item || !element.contains(item)) return;
18
+ if (handleSelector) {
19
+ const handleEl = target.closest(handleSelector);
20
+ if (!handleEl) return;
21
+ }
22
+ e.preventDefault();
23
+ item.classList.add(dragClass);
24
+ element.dispatchEvent(new CustomEvent("sortable:start", { bubbles: true, detail: { item } }));
25
+ function onMove(ev) {
26
+ element.dispatchEvent(
27
+ new CustomEvent("sortable:move", {
28
+ bubbles: true,
29
+ detail: { clientY: ev.clientY, item }
30
+ })
31
+ );
32
+ }
33
+ function onUp() {
34
+ document.removeEventListener("pointermove", onMove);
35
+ document.removeEventListener("pointerup", onUp);
36
+ item.classList.remove(dragClass);
37
+ element.dispatchEvent(new CustomEvent("sortable:end", { bubbles: true, detail: { item } }));
38
+ }
39
+ document.addEventListener("pointermove", onMove);
40
+ document.addEventListener("pointerup", onUp);
41
+ });
42
+ }
43
+ async function registerSortable(hyperfixi) {
44
+ const hf = hyperfixi || resolveRuntime();
45
+ if (!hf) {
46
+ throw new Error(
47
+ "LokaScript not found. Make sure @hyperfixi/core is loaded before registering behaviors."
48
+ );
49
+ }
50
+ const syntheticNode = {
51
+ type: "behavior",
52
+ name: "Sortable",
53
+ parameters: ["handle", "dragClass"],
54
+ eventHandlers: [],
55
+ imperativeInstaller: installSortable
56
+ };
57
+ const ctx = hf.createContext ? hf.createContext() : { locals: /* @__PURE__ */ new Map(), globals: /* @__PURE__ */ new Map() };
58
+ await hf.execute(syntheticNode, ctx);
59
+ }
60
+ if (resolveRuntime()) {
61
+ registerSortable().catch(console.error);
62
+ }
63
+ var sortable_default = {
64
+ source: sortableSchema.source,
65
+ metadata: sortableSchema,
66
+ register: registerSortable
67
+ };
68
+
69
+ export {
70
+ sortableSource,
71
+ sortableMetadata,
72
+ registerSortable,
73
+ sortable_default
74
+ };
75
+ //# sourceMappingURL=chunk-RPERQTFU.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../src/behaviors/sortable.ts"],"sourcesContent":["/**\n * Sortable Behavior — Imperative Implementation\n *\n * Drag-and-drop reordering of list items.\n * Apply to a container element; children become sortable.\n *\n * Note: This behavior fires lifecycle events but does NOT automatically\n * reorder DOM elements. Users must handle actual reordering in their\n * `sortable:move` event handlers.\n *\n * @example\n * ```html\n * <ul _=\"install Sortable\">\n * <li>Item 1</li>\n * <li>Item 2</li>\n * </ul>\n * ```\n */\n\nimport { sortableSchema } from '../schemas/sortable.schema';\nimport type { LokaScriptInstance } from '../schemas/types';\nimport { resolveRuntime } from '../schemas/types';\n\n// Re-export schema-derived values for backwards compatibility\nexport const sortableSource = sortableSchema.source;\nexport const sortableMetadata = sortableSchema;\n\n/**\n * Imperative installer for Sortable behavior.\n */\nfunction installSortable(element: HTMLElement, params: Record<string, any>): void {\n const dragClass = params.dragClass || 'sorting';\n const handleSelector = params.handle || null;\n\n element.addEventListener('pointerdown', (e: PointerEvent) => {\n const target = e.target as HTMLElement;\n const item = target.closest('li');\n if (!item || !element.contains(item)) return;\n\n // If a handle selector is specified, only start drag from the handle\n if (handleSelector) {\n const handleEl = target.closest(handleSelector);\n if (!handleEl) return;\n }\n\n e.preventDefault();\n item.classList.add(dragClass);\n element.dispatchEvent(new CustomEvent('sortable:start', { bubbles: true, detail: { item } }));\n\n function onMove(ev: PointerEvent) {\n element.dispatchEvent(\n new CustomEvent('sortable:move', {\n bubbles: true,\n detail: { clientY: ev.clientY, item },\n })\n );\n }\n\n function onUp() {\n document.removeEventListener('pointermove', onMove);\n document.removeEventListener('pointerup', onUp);\n item!.classList.remove(dragClass);\n element.dispatchEvent(new CustomEvent('sortable:end', { bubbles: true, detail: { item } }));\n }\n\n document.addEventListener('pointermove', onMove);\n document.addEventListener('pointerup', onUp);\n });\n}\n\n/**\n * Register the Sortable behavior with LokaScript.\n */\nexport async function registerSortable(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: 'Sortable',\n parameters: ['handle', 'dragClass'],\n eventHandlers: [],\n imperativeInstaller: installSortable,\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 registerSortable().catch(console.error);\n}\n\nexport default {\n source: sortableSchema.source,\n metadata: sortableSchema,\n register: registerSortable,\n};\n"],"mappings":";;;;;;;;AAwBO,IAAM,iBAAiB,eAAe;AACtC,IAAM,mBAAmB;AAKhC,SAAS,gBAAgB,SAAsB,QAAmC;AAChF,QAAM,YAAY,OAAO,aAAa;AACtC,QAAM,iBAAiB,OAAO,UAAU;AAExC,UAAQ,iBAAiB,eAAe,CAAC,MAAoB;AAC3D,UAAM,SAAS,EAAE;AACjB,UAAM,OAAO,OAAO,QAAQ,IAAI;AAChC,QAAI,CAAC,QAAQ,CAAC,QAAQ,SAAS,IAAI,EAAG;AAGtC,QAAI,gBAAgB;AAClB,YAAM,WAAW,OAAO,QAAQ,cAAc;AAC9C,UAAI,CAAC,SAAU;AAAA,IACjB;AAEA,MAAE,eAAe;AACjB,SAAK,UAAU,IAAI,SAAS;AAC5B,YAAQ,cAAc,IAAI,YAAY,kBAAkB,EAAE,SAAS,MAAM,QAAQ,EAAE,KAAK,EAAE,CAAC,CAAC;AAE5F,aAAS,OAAO,IAAkB;AAChC,cAAQ;AAAA,QACN,IAAI,YAAY,iBAAiB;AAAA,UAC/B,SAAS;AAAA,UACT,QAAQ,EAAE,SAAS,GAAG,SAAS,KAAK;AAAA,QACtC,CAAC;AAAA,MACH;AAAA,IACF;AAEA,aAAS,OAAO;AACd,eAAS,oBAAoB,eAAe,MAAM;AAClD,eAAS,oBAAoB,aAAa,IAAI;AAC9C,WAAM,UAAU,OAAO,SAAS;AAChC,cAAQ,cAAc,IAAI,YAAY,gBAAgB,EAAE,SAAS,MAAM,QAAQ,EAAE,KAAK,EAAE,CAAC,CAAC;AAAA,IAC5F;AAEA,aAAS,iBAAiB,eAAe,MAAM;AAC/C,aAAS,iBAAiB,aAAa,IAAI;AAAA,EAC7C,CAAC;AACH;AAKA,eAAsB,iBAAiB,WAA+C;AACpF,QAAM,KAAK,aAAa,eAAe;AAEvC,MAAI,CAAC,IAAI;AACP,UAAM,IAAI;AAAA,MACR;AAAA,IACF;AAAA,EACF;AAEA,QAAM,gBAAgB;AAAA,IACpB,MAAM;AAAA,IACN,MAAM;AAAA,IACN,YAAY,CAAC,UAAU,WAAW;AAAA,IAClC,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,mBAAiB,EAAE,MAAM,QAAQ,KAAK;AACxC;AAEA,IAAO,mBAAQ;AAAA,EACb,QAAQ,eAAe;AAAA,EACvB,UAAU;AAAA,EACV,UAAU;AACZ;","names":[]}
@@ -0,0 +1,75 @@
1
+ import {
2
+ draggableSchema
3
+ } from "./chunk-G6WR2AYR.js";
4
+ import {
5
+ resolveRuntime
6
+ } from "./chunk-6TJXDCAQ.js";
7
+
8
+ // src/behaviors/draggable.ts
9
+ var draggableSource = draggableSchema.source;
10
+ var draggableMetadata = draggableSchema;
11
+ function installDraggable(element, params) {
12
+ let dragHandle = element;
13
+ if (params.dragHandle && params.dragHandle !== "me") {
14
+ if (typeof params.dragHandle === "string") {
15
+ const found = element.querySelector(params.dragHandle);
16
+ if (found instanceof HTMLElement) dragHandle = found;
17
+ } else if (params.dragHandle instanceof HTMLElement) {
18
+ dragHandle = params.dragHandle;
19
+ }
20
+ }
21
+ dragHandle.addEventListener("pointerdown", (e) => {
22
+ e.preventDefault();
23
+ e.stopPropagation();
24
+ element.dispatchEvent(new CustomEvent("draggable:start", { bubbles: true }));
25
+ const startX = element.offsetLeft;
26
+ const startY = element.offsetTop;
27
+ const xoff = e.clientX - startX;
28
+ const yoff = e.clientY - startY;
29
+ function onMove(ev) {
30
+ element.style.left = `${ev.clientX - xoff}px`;
31
+ element.style.top = `${ev.clientY - yoff}px`;
32
+ element.dispatchEvent(new CustomEvent("draggable:move", { bubbles: true }));
33
+ }
34
+ function onUp() {
35
+ document.removeEventListener("pointermove", onMove);
36
+ document.removeEventListener("pointerup", onUp);
37
+ element.dispatchEvent(new CustomEvent("draggable:end", { bubbles: true }));
38
+ }
39
+ document.addEventListener("pointermove", onMove);
40
+ document.addEventListener("pointerup", onUp);
41
+ });
42
+ }
43
+ async function registerDraggable(hyperfixi) {
44
+ const hf = hyperfixi || resolveRuntime();
45
+ if (!hf) {
46
+ throw new Error(
47
+ "LokaScript not found. Make sure @hyperfixi/core is loaded before registering behaviors."
48
+ );
49
+ }
50
+ const syntheticNode = {
51
+ type: "behavior",
52
+ name: "Draggable",
53
+ parameters: ["dragHandle"],
54
+ eventHandlers: [],
55
+ imperativeInstaller: installDraggable
56
+ };
57
+ const ctx = hf.createContext ? hf.createContext() : { locals: /* @__PURE__ */ new Map(), globals: /* @__PURE__ */ new Map() };
58
+ await hf.execute(syntheticNode, ctx);
59
+ }
60
+ if (resolveRuntime()) {
61
+ registerDraggable().catch(console.error);
62
+ }
63
+ var draggable_default = {
64
+ source: draggableSchema.source,
65
+ metadata: draggableSchema,
66
+ register: registerDraggable
67
+ };
68
+
69
+ export {
70
+ draggableSource,
71
+ draggableMetadata,
72
+ registerDraggable,
73
+ draggable_default
74
+ };
75
+ //# sourceMappingURL=chunk-S4QDV2MH.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../src/behaviors/draggable.ts"],"sourcesContent":["/**\n * Draggable Behavior — Imperative Implementation\n *\n * Makes elements draggable with pointer events.\n * Uses direct DOM APIs instead of compiling hyperscript source,\n * bypassing the complex repeat-until-event + wait-for async pattern.\n *\n * @example\n * ```html\n * <!-- Basic usage -->\n * <div _=\"install Draggable\">Drag me!</div>\n *\n * <!-- With custom drag handle -->\n * <div _=\"install Draggable(dragHandle: .titlebar)\">\n * <div class=\"titlebar\">Drag here</div>\n * <div class=\"content\">Content</div>\n * </div>\n * ```\n */\n\nimport { draggableSchema } from '../schemas/draggable.schema';\nimport type { LokaScriptInstance } from '../schemas/types';\nimport { resolveRuntime } from '../schemas/types';\n\n// Re-export schema-derived values for backwards compatibility\nexport const draggableSource = draggableSchema.source;\nexport const draggableMetadata = draggableSchema;\n\n/**\n * Imperative installer for Draggable behavior.\n * Called directly by the runtime when `install Draggable` is executed.\n */\nfunction installDraggable(element: HTMLElement, params: Record<string, any>): void {\n // Resolve drag handle: parameter value, CSS selector, or the element itself\n let dragHandle: HTMLElement = element;\n if (params.dragHandle && params.dragHandle !== 'me') {\n if (typeof params.dragHandle === 'string') {\n const found = element.querySelector(params.dragHandle);\n if (found instanceof HTMLElement) dragHandle = found;\n } else if (params.dragHandle instanceof HTMLElement) {\n dragHandle = params.dragHandle;\n }\n }\n\n dragHandle.addEventListener('pointerdown', (e: PointerEvent) => {\n e.preventDefault();\n e.stopPropagation();\n element.dispatchEvent(new CustomEvent('draggable:start', { bubbles: true }));\n\n const startX = element.offsetLeft;\n const startY = element.offsetTop;\n const xoff = e.clientX - startX;\n const yoff = e.clientY - startY;\n\n function onMove(ev: PointerEvent) {\n element.style.left = `${ev.clientX - xoff}px`;\n element.style.top = `${ev.clientY - yoff}px`;\n element.dispatchEvent(new CustomEvent('draggable:move', { bubbles: true }));\n }\n\n function onUp() {\n document.removeEventListener('pointermove', onMove);\n document.removeEventListener('pointerup', onUp);\n element.dispatchEvent(new CustomEvent('draggable:end', { bubbles: true }));\n }\n\n document.addEventListener('pointermove', onMove);\n document.addEventListener('pointerup', onUp);\n });\n}\n\n/**\n * Register the Draggable behavior with LokaScript.\n * Uses imperative installer via synthetic behavior node.\n */\nexport async function registerDraggable(hyperfixi?: LokaScriptInstance): Promise<void> {\n const hf = hyperfixi || resolveRuntime();\n\n if (!hf) {\n throw new Error(\n 'LokaScript not found. Make sure @hyperfixi/core is loaded before registering behaviors.'\n );\n }\n\n // Register via execute() with a synthetic behavior node containing the imperative installer.\n // The runtime detects imperativeInstaller and stores it directly in the behaviorRegistry.\n const syntheticNode = {\n type: 'behavior',\n name: 'Draggable',\n parameters: ['dragHandle'],\n eventHandlers: [],\n imperativeInstaller: installDraggable,\n };\n const ctx = hf.createContext ? hf.createContext() : { locals: new Map(), globals: new Map() };\n await hf.execute(syntheticNode, ctx);\n}\n\n// Auto-register when loaded as a script tag\nif (resolveRuntime()) {\n registerDraggable().catch(console.error);\n}\n\nexport default {\n source: draggableSchema.source,\n metadata: draggableSchema,\n register: registerDraggable,\n};\n"],"mappings":";;;;;;;;AAyBO,IAAM,kBAAkB,gBAAgB;AACxC,IAAM,oBAAoB;AAMjC,SAAS,iBAAiB,SAAsB,QAAmC;AAEjF,MAAI,aAA0B;AAC9B,MAAI,OAAO,cAAc,OAAO,eAAe,MAAM;AACnD,QAAI,OAAO,OAAO,eAAe,UAAU;AACzC,YAAM,QAAQ,QAAQ,cAAc,OAAO,UAAU;AACrD,UAAI,iBAAiB,YAAa,cAAa;AAAA,IACjD,WAAW,OAAO,sBAAsB,aAAa;AACnD,mBAAa,OAAO;AAAA,IACtB;AAAA,EACF;AAEA,aAAW,iBAAiB,eAAe,CAAC,MAAoB;AAC9D,MAAE,eAAe;AACjB,MAAE,gBAAgB;AAClB,YAAQ,cAAc,IAAI,YAAY,mBAAmB,EAAE,SAAS,KAAK,CAAC,CAAC;AAE3E,UAAM,SAAS,QAAQ;AACvB,UAAM,SAAS,QAAQ;AACvB,UAAM,OAAO,EAAE,UAAU;AACzB,UAAM,OAAO,EAAE,UAAU;AAEzB,aAAS,OAAO,IAAkB;AAChC,cAAQ,MAAM,OAAO,GAAG,GAAG,UAAU,IAAI;AACzC,cAAQ,MAAM,MAAM,GAAG,GAAG,UAAU,IAAI;AACxC,cAAQ,cAAc,IAAI,YAAY,kBAAkB,EAAE,SAAS,KAAK,CAAC,CAAC;AAAA,IAC5E;AAEA,aAAS,OAAO;AACd,eAAS,oBAAoB,eAAe,MAAM;AAClD,eAAS,oBAAoB,aAAa,IAAI;AAC9C,cAAQ,cAAc,IAAI,YAAY,iBAAiB,EAAE,SAAS,KAAK,CAAC,CAAC;AAAA,IAC3E;AAEA,aAAS,iBAAiB,eAAe,MAAM;AAC/C,aAAS,iBAAiB,aAAa,IAAI;AAAA,EAC7C,CAAC;AACH;AAMA,eAAsB,kBAAkB,WAA+C;AACrF,QAAM,KAAK,aAAa,eAAe;AAEvC,MAAI,CAAC,IAAI;AACP,UAAM,IAAI;AAAA,MACR;AAAA,IACF;AAAA,EACF;AAIA,QAAM,gBAAgB;AAAA,IACpB,MAAM;AAAA,IACN,MAAM;AAAA,IACN,YAAY,CAAC,YAAY;AAAA,IACzB,eAAe,CAAC;AAAA,IAChB,qBAAqB;AAAA,EACvB;AACA,QAAM,MAAM,GAAG,gBAAgB,GAAG,cAAc,IAAI,EAAE,QAAQ,oBAAI,IAAI,GAAG,SAAS,oBAAI,IAAI,EAAE;AAC5F,QAAM,GAAG,QAAQ,eAAe,GAAG;AACrC;AAGA,IAAI,eAAe,GAAG;AACpB,oBAAkB,EAAE,MAAM,QAAQ,KAAK;AACzC;AAEA,IAAO,oBAAQ;AAAA,EACb,QAAQ,gBAAgB;AAAA,EACxB,UAAU;AAAA,EACV,UAAU;AACZ;","names":[]}
@@ -0,0 +1,80 @@
1
+ import {
2
+ resizableSchema
3
+ } from "./chunk-V5IWDPDP.js";
4
+ import {
5
+ resolveRuntime
6
+ } from "./chunk-6TJXDCAQ.js";
7
+
8
+ // src/behaviors/resizable.ts
9
+ var resizableSource = resizableSchema.source;
10
+ var resizableMetadata = resizableSchema;
11
+ function installResizable(element, params) {
12
+ let handleEl = element;
13
+ if (params.handle && params.handle !== "me") {
14
+ if (typeof params.handle === "string") {
15
+ const found = element.querySelector(params.handle);
16
+ if (found instanceof HTMLElement) handleEl = found;
17
+ } else if (params.handle instanceof HTMLElement) {
18
+ handleEl = params.handle;
19
+ }
20
+ }
21
+ const minW = params.minWidth ?? 50;
22
+ const minH = params.minHeight ?? 50;
23
+ const maxW = params.maxWidth ?? 9999;
24
+ const maxH = params.maxHeight ?? 9999;
25
+ handleEl.addEventListener("pointerdown", (e) => {
26
+ e.preventDefault();
27
+ element.dispatchEvent(new CustomEvent("resizable:start", { bubbles: true }));
28
+ const startWidth = element.offsetWidth;
29
+ const startHeight = element.offsetHeight;
30
+ const startX = e.clientX;
31
+ const startY = e.clientY;
32
+ function onMove(ev) {
33
+ const newWidth = Math.max(minW, Math.min(maxW, startWidth + (ev.clientX - startX)));
34
+ const newHeight = Math.max(minH, Math.min(maxH, startHeight + (ev.clientY - startY)));
35
+ element.style.width = `${newWidth}px`;
36
+ element.style.height = `${newHeight}px`;
37
+ element.dispatchEvent(new CustomEvent("resizable:resize", { bubbles: true }));
38
+ }
39
+ function onUp() {
40
+ document.removeEventListener("pointermove", onMove);
41
+ document.removeEventListener("pointerup", onUp);
42
+ element.dispatchEvent(new CustomEvent("resizable:end", { bubbles: true }));
43
+ }
44
+ document.addEventListener("pointermove", onMove);
45
+ document.addEventListener("pointerup", onUp);
46
+ });
47
+ }
48
+ async function registerResizable(hyperfixi) {
49
+ const hf = hyperfixi || resolveRuntime();
50
+ if (!hf) {
51
+ throw new Error(
52
+ "LokaScript not found. Make sure @hyperfixi/core is loaded before registering behaviors."
53
+ );
54
+ }
55
+ const syntheticNode = {
56
+ type: "behavior",
57
+ name: "Resizable",
58
+ parameters: ["handle", "minWidth", "minHeight", "maxWidth", "maxHeight"],
59
+ eventHandlers: [],
60
+ imperativeInstaller: installResizable
61
+ };
62
+ const ctx = hf.createContext ? hf.createContext() : { locals: /* @__PURE__ */ new Map(), globals: /* @__PURE__ */ new Map() };
63
+ await hf.execute(syntheticNode, ctx);
64
+ }
65
+ if (resolveRuntime()) {
66
+ registerResizable().catch(console.error);
67
+ }
68
+ var resizable_default = {
69
+ source: resizableSchema.source,
70
+ metadata: resizableSchema,
71
+ register: registerResizable
72
+ };
73
+
74
+ export {
75
+ resizableSource,
76
+ resizableMetadata,
77
+ registerResizable,
78
+ resizable_default
79
+ };
80
+ //# sourceMappingURL=chunk-WTUVPVSD.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../src/behaviors/resizable.ts"],"sourcesContent":["/**\n * Resizable Behavior — Imperative Implementation\n *\n * Makes elements resizable by dragging edges or corners.\n * Supports minimum/maximum dimensions and resize handles.\n *\n * @example\n * ```html\n * <div _=\"install Resizable\" style=\"width: 200px; height: 150px;\">\n * Resize me!\n * </div>\n * ```\n */\n\nimport { resizableSchema } from '../schemas/resizable.schema';\nimport type { LokaScriptInstance } from '../schemas/types';\nimport { resolveRuntime } from '../schemas/types';\n\n// Re-export schema-derived values for backwards compatibility\nexport const resizableSource = resizableSchema.source;\nexport const resizableMetadata = resizableSchema;\n\n/**\n * Imperative installer for Resizable behavior.\n */\nfunction installResizable(element: HTMLElement, params: Record<string, any>): void {\n // Resolve handle element\n let handleEl: HTMLElement = element;\n if (params.handle && params.handle !== 'me') {\n if (typeof params.handle === 'string') {\n const found = element.querySelector(params.handle);\n if (found instanceof HTMLElement) handleEl = found;\n } else if (params.handle instanceof HTMLElement) {\n handleEl = params.handle;\n }\n }\n\n const minW = params.minWidth ?? 50;\n const minH = params.minHeight ?? 50;\n const maxW = params.maxWidth ?? 9999;\n const maxH = params.maxHeight ?? 9999;\n\n handleEl.addEventListener('pointerdown', (e: PointerEvent) => {\n e.preventDefault();\n element.dispatchEvent(new CustomEvent('resizable:start', { bubbles: true }));\n\n const startWidth = element.offsetWidth;\n const startHeight = element.offsetHeight;\n const startX = e.clientX;\n const startY = e.clientY;\n\n function onMove(ev: PointerEvent) {\n const newWidth = Math.max(minW, Math.min(maxW, startWidth + (ev.clientX - startX)));\n const newHeight = Math.max(minH, Math.min(maxH, startHeight + (ev.clientY - startY)));\n\n element.style.width = `${newWidth}px`;\n element.style.height = `${newHeight}px`;\n element.dispatchEvent(new CustomEvent('resizable:resize', { bubbles: true }));\n }\n\n function onUp() {\n document.removeEventListener('pointermove', onMove);\n document.removeEventListener('pointerup', onUp);\n element.dispatchEvent(new CustomEvent('resizable:end', { bubbles: true }));\n }\n\n document.addEventListener('pointermove', onMove);\n document.addEventListener('pointerup', onUp);\n });\n}\n\n/**\n * Register the Resizable behavior with LokaScript.\n */\nexport async function registerResizable(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: 'Resizable',\n parameters: ['handle', 'minWidth', 'minHeight', 'maxWidth', 'maxHeight'],\n eventHandlers: [],\n imperativeInstaller: installResizable,\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 registerResizable().catch(console.error);\n}\n\nexport default {\n source: resizableSchema.source,\n metadata: resizableSchema,\n register: registerResizable,\n};\n"],"mappings":";;;;;;;;AAmBO,IAAM,kBAAkB,gBAAgB;AACxC,IAAM,oBAAoB;AAKjC,SAAS,iBAAiB,SAAsB,QAAmC;AAEjF,MAAI,WAAwB;AAC5B,MAAI,OAAO,UAAU,OAAO,WAAW,MAAM;AAC3C,QAAI,OAAO,OAAO,WAAW,UAAU;AACrC,YAAM,QAAQ,QAAQ,cAAc,OAAO,MAAM;AACjD,UAAI,iBAAiB,YAAa,YAAW;AAAA,IAC/C,WAAW,OAAO,kBAAkB,aAAa;AAC/C,iBAAW,OAAO;AAAA,IACpB;AAAA,EACF;AAEA,QAAM,OAAO,OAAO,YAAY;AAChC,QAAM,OAAO,OAAO,aAAa;AACjC,QAAM,OAAO,OAAO,YAAY;AAChC,QAAM,OAAO,OAAO,aAAa;AAEjC,WAAS,iBAAiB,eAAe,CAAC,MAAoB;AAC5D,MAAE,eAAe;AACjB,YAAQ,cAAc,IAAI,YAAY,mBAAmB,EAAE,SAAS,KAAK,CAAC,CAAC;AAE3E,UAAM,aAAa,QAAQ;AAC3B,UAAM,cAAc,QAAQ;AAC5B,UAAM,SAAS,EAAE;AACjB,UAAM,SAAS,EAAE;AAEjB,aAAS,OAAO,IAAkB;AAChC,YAAM,WAAW,KAAK,IAAI,MAAM,KAAK,IAAI,MAAM,cAAc,GAAG,UAAU,OAAO,CAAC;AAClF,YAAM,YAAY,KAAK,IAAI,MAAM,KAAK,IAAI,MAAM,eAAe,GAAG,UAAU,OAAO,CAAC;AAEpF,cAAQ,MAAM,QAAQ,GAAG,QAAQ;AACjC,cAAQ,MAAM,SAAS,GAAG,SAAS;AACnC,cAAQ,cAAc,IAAI,YAAY,oBAAoB,EAAE,SAAS,KAAK,CAAC,CAAC;AAAA,IAC9E;AAEA,aAAS,OAAO;AACd,eAAS,oBAAoB,eAAe,MAAM;AAClD,eAAS,oBAAoB,aAAa,IAAI;AAC9C,cAAQ,cAAc,IAAI,YAAY,iBAAiB,EAAE,SAAS,KAAK,CAAC,CAAC;AAAA,IAC3E;AAEA,aAAS,iBAAiB,eAAe,MAAM;AAC/C,aAAS,iBAAiB,aAAa,IAAI;AAAA,EAC7C,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,UAAU,YAAY,aAAa,YAAY,WAAW;AAAA,IACvE,eAAe,CAAC;AAAA,IAChB,qBAAqB;AAAA,EACvB;AACA,QAAM,MAAM,GAAG,gBAAgB,GAAG,cAAc,IAAI,EAAE,QAAQ,oBAAI,IAAI,GAAG,SAAS,oBAAI,IAAI,EAAE;AAC5F,QAAM,GAAG,QAAQ,eAAe,GAAG;AACrC;AAGA,IAAI,eAAe,GAAG;AACpB,oBAAkB,EAAE,MAAM,QAAQ,KAAK;AACzC;AAEA,IAAO,oBAAQ;AAAA,EACb,QAAQ,gBAAgB;AAAA,EACxB,UAAU;AAAA,EACV,UAAU;AACZ;","names":[]}
@@ -0,0 +1,62 @@
1
+ import {
2
+ toggleableSchema
3
+ } from "./chunk-WUHHMDAA.js";
4
+ import {
5
+ resolveRuntime
6
+ } from "./chunk-6TJXDCAQ.js";
7
+
8
+ // src/behaviors/toggleable.ts
9
+ var toggleableSource = toggleableSchema.source;
10
+ var toggleableMetadata = toggleableSchema;
11
+ function installToggleable(element, params) {
12
+ const cls = params.cls || "active";
13
+ let targetEl = element;
14
+ if (params.target && params.target !== "me") {
15
+ if (typeof params.target === "string") {
16
+ const found = document.querySelector(params.target);
17
+ if (found instanceof HTMLElement) targetEl = found;
18
+ } else if (params.target instanceof HTMLElement) {
19
+ targetEl = params.target;
20
+ }
21
+ }
22
+ element.addEventListener("click", () => {
23
+ const wasOn = targetEl.classList.contains(cls);
24
+ targetEl.classList.toggle(cls);
25
+ targetEl.dispatchEvent(
26
+ new CustomEvent(wasOn ? "toggleable:off" : "toggleable:on", { bubbles: true })
27
+ );
28
+ });
29
+ }
30
+ async function registerToggleable(hyperfixi) {
31
+ const hf = hyperfixi || resolveRuntime();
32
+ if (!hf) {
33
+ throw new Error(
34
+ "LokaScript not found. Make sure @hyperfixi/core is loaded before registering behaviors."
35
+ );
36
+ }
37
+ const syntheticNode = {
38
+ type: "behavior",
39
+ name: "Toggleable",
40
+ parameters: ["cls", "target"],
41
+ eventHandlers: [],
42
+ imperativeInstaller: installToggleable
43
+ };
44
+ const ctx = hf.createContext ? hf.createContext() : { locals: /* @__PURE__ */ new Map(), globals: /* @__PURE__ */ new Map() };
45
+ await hf.execute(syntheticNode, ctx);
46
+ }
47
+ if (resolveRuntime()) {
48
+ registerToggleable().catch(console.error);
49
+ }
50
+ var toggleable_default = {
51
+ source: toggleableSchema.source,
52
+ metadata: toggleableSchema,
53
+ register: registerToggleable
54
+ };
55
+
56
+ export {
57
+ toggleableSource,
58
+ toggleableMetadata,
59
+ registerToggleable,
60
+ toggleable_default
61
+ };
62
+ //# sourceMappingURL=chunk-YHQRFUWV.js.map