snice 1.13.2 → 1.13.4

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 (295) hide show
  1. package/bin/templates/base/README.md +1 -1
  2. package/dist/components/accordion/snice-accordion-item.d.ts +25 -0
  3. package/dist/components/accordion/snice-accordion-item.js +260 -0
  4. package/dist/components/accordion/snice-accordion-item.js.map +1 -0
  5. package/dist/components/accordion/snice-accordion.d.ts +28 -0
  6. package/dist/components/accordion/snice-accordion.js +221 -0
  7. package/dist/components/accordion/snice-accordion.js.map +1 -0
  8. package/dist/components/accordion/snice-accordion.types.d.ts +29 -0
  9. package/dist/components/accordion/snice-accordion.types.js +2 -0
  10. package/dist/components/accordion/snice-accordion.types.js.map +1 -0
  11. package/dist/components/alert/snice-alert.d.ts +26 -0
  12. package/dist/components/alert/snice-alert.js +191 -0
  13. package/dist/components/alert/snice-alert.js.map +1 -0
  14. package/dist/components/alert/snice-alert.types.d.ts +11 -0
  15. package/dist/components/alert/snice-alert.types.js +2 -0
  16. package/dist/components/alert/snice-alert.types.js.map +1 -0
  17. package/dist/components/avatar/snice-avatar.d.ts +24 -0
  18. package/dist/components/avatar/snice-avatar.js +177 -0
  19. package/dist/components/avatar/snice-avatar.js.map +1 -0
  20. package/dist/components/avatar/snice-avatar.types.d.ts +12 -0
  21. package/dist/components/avatar/snice-avatar.types.js +2 -0
  22. package/dist/components/avatar/snice-avatar.types.js.map +1 -0
  23. package/dist/components/badge/snice-badge.d.ts +25 -0
  24. package/dist/components/badge/snice-badge.js +157 -0
  25. package/dist/components/badge/snice-badge.js.map +1 -0
  26. package/dist/components/badge/snice-badge.types.d.ts +15 -0
  27. package/dist/components/badge/snice-badge.types.js +2 -0
  28. package/dist/components/badge/snice-badge.types.js.map +1 -0
  29. package/dist/components/breadcrumbs/snice-breadcrumbs.d.ts +27 -0
  30. package/dist/components/breadcrumbs/snice-breadcrumbs.js +212 -0
  31. package/dist/components/breadcrumbs/snice-breadcrumbs.js.map +1 -0
  32. package/dist/components/breadcrumbs/snice-breadcrumbs.types.d.ts +23 -0
  33. package/dist/components/breadcrumbs/snice-breadcrumbs.types.js +2 -0
  34. package/dist/components/breadcrumbs/snice-breadcrumbs.types.js.map +1 -0
  35. package/dist/components/breadcrumbs/snice-crumb.d.ts +9 -0
  36. package/dist/components/breadcrumbs/snice-crumb.js +50 -0
  37. package/dist/components/breadcrumbs/snice-crumb.js.map +1 -0
  38. package/dist/components/button/snice-button.d.ts +32 -0
  39. package/dist/components/button/snice-button.js +212 -0
  40. package/dist/components/button/snice-button.js.map +1 -0
  41. package/dist/components/button/snice-button.types.d.ts +23 -0
  42. package/dist/components/button/snice-button.types.js +2 -0
  43. package/dist/components/button/snice-button.types.js.map +1 -0
  44. package/dist/components/card/snice-card.d.ts +19 -0
  45. package/dist/components/card/snice-card.js +132 -0
  46. package/dist/components/card/snice-card.js.map +1 -0
  47. package/dist/components/card/snice-card.types.d.ts +9 -0
  48. package/dist/components/card/snice-card.types.js +2 -0
  49. package/dist/components/card/snice-card.types.js.map +1 -0
  50. package/dist/components/checkbox/snice-checkbox.d.ts +34 -0
  51. package/dist/components/checkbox/snice-checkbox.js +289 -0
  52. package/dist/components/checkbox/snice-checkbox.js.map +1 -0
  53. package/dist/components/checkbox/snice-checkbox.types.d.ts +20 -0
  54. package/dist/components/checkbox/snice-checkbox.types.js +2 -0
  55. package/dist/components/checkbox/snice-checkbox.types.js.map +1 -0
  56. package/dist/components/chip/snice-chip.d.ts +28 -0
  57. package/dist/components/chip/snice-chip.js +203 -0
  58. package/dist/components/chip/snice-chip.js.map +1 -0
  59. package/dist/components/chip/snice-chip.types.d.ts +14 -0
  60. package/dist/components/chip/snice-chip.types.js +2 -0
  61. package/dist/components/chip/snice-chip.types.js.map +1 -0
  62. package/dist/components/date-picker/snice-date-picker.d.ts +82 -0
  63. package/dist/components/date-picker/snice-date-picker.js +880 -0
  64. package/dist/components/date-picker/snice-date-picker.js.map +1 -0
  65. package/dist/components/date-picker/snice-date-picker.types.d.ts +71 -0
  66. package/dist/components/date-picker/snice-date-picker.types.js +2 -0
  67. package/dist/components/date-picker/snice-date-picker.types.js.map +1 -0
  68. package/dist/components/divider/snice-divider.d.ts +17 -0
  69. package/dist/components/divider/snice-divider.js +111 -0
  70. package/dist/components/divider/snice-divider.js.map +1 -0
  71. package/dist/components/divider/snice-divider.types.d.ts +14 -0
  72. package/dist/components/divider/snice-divider.types.js +2 -0
  73. package/dist/components/divider/snice-divider.types.js.map +1 -0
  74. package/dist/components/drawer/snice-drawer.d.ts +37 -0
  75. package/dist/components/drawer/snice-drawer.js +335 -0
  76. package/dist/components/drawer/snice-drawer.js.map +1 -0
  77. package/dist/components/drawer/snice-drawer.types.d.ts +16 -0
  78. package/dist/components/drawer/snice-drawer.types.js +2 -0
  79. package/dist/components/drawer/snice-drawer.types.js.map +1 -0
  80. package/dist/components/input/snice-input.d.ts +65 -0
  81. package/dist/components/input/snice-input.js +603 -0
  82. package/dist/components/input/snice-input.js.map +1 -0
  83. package/dist/components/input/snice-input.types.d.ts +53 -0
  84. package/dist/components/input/snice-input.types.js +2 -0
  85. package/dist/components/input/snice-input.types.js.map +1 -0
  86. package/dist/components/layout/snice-layout-blog.d.ts +4 -0
  87. package/dist/components/layout/snice-layout-blog.js +56 -0
  88. package/dist/components/layout/snice-layout-blog.js.map +1 -0
  89. package/dist/components/layout/snice-layout-card.d.ts +6 -0
  90. package/dist/components/layout/snice-layout-card.js +53 -0
  91. package/dist/components/layout/snice-layout-card.js.map +1 -0
  92. package/dist/components/layout/snice-layout-centered.d.ts +5 -0
  93. package/dist/components/layout/snice-layout-centered.js +38 -0
  94. package/dist/components/layout/snice-layout-centered.js.map +1 -0
  95. package/dist/components/layout/snice-layout-dashboard.d.ts +4 -0
  96. package/dist/components/layout/snice-layout-dashboard.js +53 -0
  97. package/dist/components/layout/snice-layout-dashboard.js.map +1 -0
  98. package/dist/components/layout/snice-layout-fullscreen.d.ts +5 -0
  99. package/dist/components/layout/snice-layout-fullscreen.js +50 -0
  100. package/dist/components/layout/snice-layout-fullscreen.js.map +1 -0
  101. package/dist/components/layout/snice-layout-landing.d.ts +4 -0
  102. package/dist/components/layout/snice-layout-landing.js +55 -0
  103. package/dist/components/layout/snice-layout-landing.js.map +1 -0
  104. package/dist/components/layout/snice-layout-minimal.d.ts +4 -0
  105. package/dist/components/layout/snice-layout-minimal.js +27 -0
  106. package/dist/components/layout/snice-layout-minimal.js.map +1 -0
  107. package/dist/components/layout/snice-layout-sidebar.d.ts +5 -0
  108. package/dist/components/layout/snice-layout-sidebar.js +64 -0
  109. package/dist/components/layout/snice-layout-sidebar.js.map +1 -0
  110. package/dist/components/layout/snice-layout-split.d.ts +6 -0
  111. package/dist/components/layout/snice-layout-split.js +47 -0
  112. package/dist/components/layout/snice-layout-split.js.map +1 -0
  113. package/dist/components/layout/snice-layout.d.ts +4 -0
  114. package/dist/components/layout/snice-layout.js +43 -0
  115. package/dist/components/layout/snice-layout.js.map +1 -0
  116. package/dist/components/layout/snice-layout.types.d.ts +3 -0
  117. package/dist/components/layout/snice-layout.types.js +2 -0
  118. package/dist/components/layout/snice-layout.types.js.map +1 -0
  119. package/dist/components/login/snice-login.d.ts +45 -0
  120. package/dist/components/login/snice-login.js +385 -0
  121. package/dist/components/login/snice-login.js.map +1 -0
  122. package/dist/components/login/snice-login.types.d.ts +31 -0
  123. package/dist/components/login/snice-login.types.js +2 -0
  124. package/dist/components/login/snice-login.types.js.map +1 -0
  125. package/dist/components/modal/snice-modal.d.ts +32 -0
  126. package/dist/components/modal/snice-modal.js +288 -0
  127. package/dist/components/modal/snice-modal.js.map +1 -0
  128. package/dist/components/modal/snice-modal.types.d.ts +18 -0
  129. package/dist/components/modal/snice-modal.types.js +2 -0
  130. package/dist/components/modal/snice-modal.types.js.map +1 -0
  131. package/dist/components/pagination/snice-pagination.d.ts +26 -0
  132. package/dist/components/pagination/snice-pagination.js +373 -0
  133. package/dist/components/pagination/snice-pagination.js.map +1 -0
  134. package/dist/components/pagination/snice-pagination.types.d.ts +18 -0
  135. package/dist/components/pagination/snice-pagination.types.js +2 -0
  136. package/dist/components/pagination/snice-pagination.types.js.map +1 -0
  137. package/dist/components/progress/snice-progress.d.ts +35 -0
  138. package/dist/components/progress/snice-progress.js +295 -0
  139. package/dist/components/progress/snice-progress.js.map +1 -0
  140. package/dist/components/progress/snice-progress.types.d.ts +18 -0
  141. package/dist/components/progress/snice-progress.types.js +2 -0
  142. package/dist/components/progress/snice-progress.types.js.map +1 -0
  143. package/dist/components/radio/snice-radio.d.ts +33 -0
  144. package/dist/components/radio/snice-radio.js +286 -0
  145. package/dist/components/radio/snice-radio.js.map +1 -0
  146. package/dist/components/radio/snice-radio.types.d.ts +19 -0
  147. package/dist/components/radio/snice-radio.types.js +2 -0
  148. package/dist/components/radio/snice-radio.types.js.map +1 -0
  149. package/dist/components/select/snice-option.d.ts +17 -0
  150. package/dist/components/select/snice-option.js +77 -0
  151. package/dist/components/select/snice-option.js.map +1 -0
  152. package/dist/components/select/snice-option.types.d.ts +14 -0
  153. package/dist/components/select/snice-option.types.js +2 -0
  154. package/dist/components/select/snice-option.types.js.map +1 -0
  155. package/dist/components/select/snice-select.d.ts +89 -0
  156. package/dist/components/select/snice-select.js +900 -0
  157. package/dist/components/select/snice-select.js.map +1 -0
  158. package/dist/components/select/snice-select.types.d.ts +49 -0
  159. package/dist/components/select/snice-select.types.js +2 -0
  160. package/dist/components/select/snice-select.types.js.map +1 -0
  161. package/dist/components/skeleton/snice-skeleton.d.ts +16 -0
  162. package/dist/components/skeleton/snice-skeleton.js +159 -0
  163. package/dist/components/skeleton/snice-skeleton.js.map +1 -0
  164. package/dist/components/skeleton/snice-skeleton.types.d.ts +10 -0
  165. package/dist/components/skeleton/snice-skeleton.types.js +2 -0
  166. package/dist/components/skeleton/snice-skeleton.types.js.map +1 -0
  167. package/dist/components/switch/snice-switch.d.ts +38 -0
  168. package/dist/components/switch/snice-switch.js +309 -0
  169. package/dist/components/switch/snice-switch.js.map +1 -0
  170. package/dist/components/switch/snice-switch.types.d.ts +21 -0
  171. package/dist/components/switch/snice-switch.types.js +2 -0
  172. package/dist/components/switch/snice-switch.types.js.map +1 -0
  173. package/dist/components/symbols.d.ts +1 -0
  174. package/dist/components/symbols.js +20 -0
  175. package/dist/components/symbols.js.map +1 -0
  176. package/dist/components/table/snice-cell-boolean.d.ts +21 -0
  177. package/dist/components/table/snice-cell-boolean.js +152 -0
  178. package/dist/components/table/snice-cell-boolean.js.map +1 -0
  179. package/dist/components/table/snice-cell-date.d.ts +24 -0
  180. package/dist/components/table/snice-cell-date.js +240 -0
  181. package/dist/components/table/snice-cell-date.js.map +1 -0
  182. package/dist/components/table/snice-cell-duration.d.ts +16 -0
  183. package/dist/components/table/snice-cell-duration.js +123 -0
  184. package/dist/components/table/snice-cell-duration.js.map +1 -0
  185. package/dist/components/table/snice-cell-filesize.d.ts +16 -0
  186. package/dist/components/table/snice-cell-filesize.js +119 -0
  187. package/dist/components/table/snice-cell-filesize.js.map +1 -0
  188. package/dist/components/table/snice-cell-number.d.ts +23 -0
  189. package/dist/components/table/snice-cell-number.js +202 -0
  190. package/dist/components/table/snice-cell-number.js.map +1 -0
  191. package/dist/components/table/snice-cell-progress.d.ts +17 -0
  192. package/dist/components/table/snice-cell-progress.js +114 -0
  193. package/dist/components/table/snice-cell-progress.js.map +1 -0
  194. package/dist/components/table/snice-cell-rating.d.ts +17 -0
  195. package/dist/components/table/snice-cell-rating.js +113 -0
  196. package/dist/components/table/snice-cell-rating.js.map +1 -0
  197. package/dist/components/table/snice-cell-sparkline.d.ts +29 -0
  198. package/dist/components/table/snice-cell-sparkline.js +290 -0
  199. package/dist/components/table/snice-cell-sparkline.js.map +1 -0
  200. package/dist/components/table/snice-cell-text.d.ts +19 -0
  201. package/dist/components/table/snice-cell-text.js +153 -0
  202. package/dist/components/table/snice-cell-text.js.map +1 -0
  203. package/dist/components/table/snice-cell.d.ts +32 -0
  204. package/dist/components/table/snice-cell.js +451 -0
  205. package/dist/components/table/snice-cell.js.map +1 -0
  206. package/dist/components/table/snice-column.d.ts +62 -0
  207. package/dist/components/table/snice-column.js +440 -0
  208. package/dist/components/table/snice-column.js.map +1 -0
  209. package/dist/components/table/snice-header.d.ts +33 -0
  210. package/dist/components/table/snice-header.js +303 -0
  211. package/dist/components/table/snice-header.js.map +1 -0
  212. package/dist/components/table/snice-progress.d.ts +10 -0
  213. package/dist/components/table/snice-progress.js +91 -0
  214. package/dist/components/table/snice-progress.js.map +1 -0
  215. package/dist/components/table/snice-rating.d.ts +9 -0
  216. package/dist/components/table/snice-rating.js +68 -0
  217. package/dist/components/table/snice-rating.js.map +1 -0
  218. package/dist/components/table/snice-row.d.ts +43 -0
  219. package/dist/components/table/snice-row.js +365 -0
  220. package/dist/components/table/snice-row.js.map +1 -0
  221. package/dist/components/table/snice-table.d.ts +69 -0
  222. package/dist/components/table/snice-table.js +814 -0
  223. package/dist/components/table/snice-table.js.map +1 -0
  224. package/dist/components/table/snice-table.types.d.ts +137 -0
  225. package/dist/components/table/snice-table.types.js +2 -0
  226. package/dist/components/table/snice-table.types.js.map +1 -0
  227. package/dist/components/tabs/snice-tab-panel.d.ts +12 -0
  228. package/dist/components/tabs/snice-tab-panel.js +78 -0
  229. package/dist/components/tabs/snice-tab-panel.js.map +1 -0
  230. package/dist/components/tabs/snice-tab.d.ts +13 -0
  231. package/dist/components/tabs/snice-tab.js +90 -0
  232. package/dist/components/tabs/snice-tab.js.map +1 -0
  233. package/dist/components/tabs/snice-tabs.d.ts +34 -0
  234. package/dist/components/tabs/snice-tabs.js +367 -0
  235. package/dist/components/tabs/snice-tabs.js.map +1 -0
  236. package/dist/components/tabs/snice-tabs.types.d.ts +23 -0
  237. package/dist/components/tabs/snice-tabs.types.js +2 -0
  238. package/dist/components/tabs/snice-tabs.types.js.map +1 -0
  239. package/dist/components/toast/snice-toast-container.d.ts +25 -0
  240. package/dist/components/toast/snice-toast-container.js +251 -0
  241. package/dist/components/toast/snice-toast-container.js.map +1 -0
  242. package/dist/components/toast/snice-toast.d.ts +23 -0
  243. package/dist/components/toast/snice-toast.js +316 -0
  244. package/dist/components/toast/snice-toast.js.map +1 -0
  245. package/dist/components/toast/snice-toast.types.d.ts +30 -0
  246. package/dist/components/toast/snice-toast.types.js +2 -0
  247. package/dist/components/toast/snice-toast.types.js.map +1 -0
  248. package/dist/components/tooltip/snice-tooltip.d.ts +50 -0
  249. package/dist/components/tooltip/snice-tooltip.js +656 -0
  250. package/dist/components/tooltip/snice-tooltip.js.map +1 -0
  251. package/dist/components/tooltip/snice-tooltip.types.d.ts +18 -0
  252. package/dist/components/tooltip/snice-tooltip.types.js +2 -0
  253. package/dist/components/tooltip/snice-tooltip.types.js.map +1 -0
  254. package/dist/components/transitions.d.ts +11 -0
  255. package/dist/components/transitions.js +69 -0
  256. package/dist/components/transitions.js.map +1 -0
  257. package/dist/src/controller.d.ts +61 -0
  258. package/dist/src/controller.js +297 -0
  259. package/dist/src/controller.js.map +1 -0
  260. package/dist/src/element.d.ts +77 -0
  261. package/dist/src/element.js +805 -0
  262. package/dist/src/element.js.map +1 -0
  263. package/dist/src/events.d.ts +37 -0
  264. package/dist/src/events.js +289 -0
  265. package/dist/src/events.js.map +1 -0
  266. package/dist/src/global.d.ts +7 -0
  267. package/dist/src/global.js +23 -0
  268. package/dist/src/global.js.map +1 -0
  269. package/{src/index.ts → dist/src/index.d.ts} +1 -1
  270. package/dist/src/index.js +8 -0
  271. package/dist/src/index.js.map +1 -0
  272. package/dist/src/observe.d.ts +26 -0
  273. package/dist/src/observe.js +329 -0
  274. package/dist/src/observe.js.map +1 -0
  275. package/dist/src/request-response.d.ts +46 -0
  276. package/dist/src/request-response.js +267 -0
  277. package/dist/src/request-response.js.map +1 -0
  278. package/dist/src/router.d.ts +87 -0
  279. package/dist/src/router.js +375 -0
  280. package/dist/src/router.js.map +1 -0
  281. package/dist/src/symbols.d.ts +29 -0
  282. package/{src/symbols.ts → dist/src/symbols.js} +2 -12
  283. package/dist/src/symbols.js.map +1 -0
  284. package/dist/src/transitions.d.ts +50 -0
  285. package/dist/src/transitions.js +199 -0
  286. package/dist/src/transitions.js.map +1 -0
  287. package/package.json +6 -8
  288. package/src/controller.ts +0 -347
  289. package/src/element.ts +0 -897
  290. package/src/events.ts +0 -349
  291. package/src/global.ts +0 -31
  292. package/src/observe.ts +0 -414
  293. package/src/request-response.ts +0 -336
  294. package/src/router.ts +0 -552
  295. package/src/transitions.ts +0 -264
@@ -0,0 +1,199 @@
1
+ /**
2
+ * Generic transition system for animating between elements
3
+ */
4
+ /**
5
+ * Parse CSS property string into an object
6
+ */
7
+ function parseStyles(styleString) {
8
+ const styles = {};
9
+ styleString.split(';').forEach(rule => {
10
+ const [prop, value] = rule.split(':').map(s => s.trim());
11
+ if (prop && value) {
12
+ styles[prop] = value;
13
+ }
14
+ });
15
+ return styles;
16
+ }
17
+ /**
18
+ * Perform a transition between two elements
19
+ */
20
+ export async function performTransition(container, oldElement, newElement, transition = {}) {
21
+ const outDuration = transition.outDuration || 300;
22
+ const inDuration = transition.inDuration || 300;
23
+ const mode = transition.mode || 'sequential';
24
+ // Default transitions
25
+ const outStyles = transition.out ? parseStyles(transition.out) : { opacity: '0' };
26
+ const inStartStyles = { opacity: '0' }; // Always start invisible
27
+ const inEndStyles = transition.in ? parseStyles(transition.in) : { opacity: '1' };
28
+ // Set container to relative positioning to allow absolute positioning
29
+ // Skip for layout elements to avoid jumpy transitions
30
+ const containerStyle = container.style;
31
+ const originalPosition = containerStyle.position;
32
+ const isLayoutElement = container.tagName.includes('-') && container.shadowRoot;
33
+ if (!isLayoutElement) {
34
+ containerStyle.position = 'relative';
35
+ }
36
+ // Check if elements are slotted (inside a layout)
37
+ const isSlottedTransition = oldElement.hasAttribute('slot') || newElement.hasAttribute('slot');
38
+ if (isSlottedTransition) {
39
+ // For slotted elements, use absolute with width/height for crossfade
40
+ oldElement.style.position = 'absolute';
41
+ oldElement.style.width = '100%';
42
+ oldElement.style.height = '100%';
43
+ oldElement.style.transition = `opacity ${outDuration}ms ease-in-out`;
44
+ newElement.style.position = 'absolute';
45
+ newElement.style.width = '100%';
46
+ newElement.style.height = '100%';
47
+ newElement.style.transition = `opacity ${inDuration}ms ease-in-out`;
48
+ }
49
+ else {
50
+ // Original absolute positioning for non-slotted elements
51
+ oldElement.style.position = 'absolute';
52
+ oldElement.style.top = '0';
53
+ oldElement.style.left = '0';
54
+ oldElement.style.width = '100%';
55
+ oldElement.style.transition = `all ${outDuration}ms ease-in-out`;
56
+ newElement.style.position = 'absolute';
57
+ newElement.style.top = '0';
58
+ newElement.style.left = '0';
59
+ newElement.style.width = '100%';
60
+ }
61
+ Object.assign(newElement.style, inStartStyles);
62
+ newElement.style.transition = `all ${inDuration}ms ease-in-out`;
63
+ // Add new element to container
64
+ container.appendChild(newElement);
65
+ // Force browser to calculate styles
66
+ void newElement.offsetHeight;
67
+ if (mode === 'simultaneous') {
68
+ // Start both transitions at once
69
+ Object.assign(oldElement.style, outStyles);
70
+ Object.assign(newElement.style, inEndStyles);
71
+ // Wait for both transitions to complete
72
+ await new Promise(resolve => setTimeout(resolve, Math.max(outDuration, inDuration)));
73
+ }
74
+ else {
75
+ // Sequential: transition out old, then transition in new
76
+ Object.assign(oldElement.style, outStyles);
77
+ await new Promise(resolve => setTimeout(resolve, outDuration));
78
+ Object.assign(newElement.style, inEndStyles);
79
+ await new Promise(resolve => setTimeout(resolve, inDuration));
80
+ }
81
+ // Cleanup
82
+ oldElement.remove();
83
+ if (isSlottedTransition) {
84
+ // Cleanup for slotted elements
85
+ newElement.style.position = '';
86
+ newElement.style.width = '';
87
+ newElement.style.height = '';
88
+ newElement.style.transition = '';
89
+ }
90
+ else {
91
+ // Cleanup for non-slotted elements
92
+ newElement.style.position = '';
93
+ newElement.style.top = '';
94
+ newElement.style.left = '';
95
+ newElement.style.width = '';
96
+ newElement.style.transition = '';
97
+ }
98
+ // Reset any transition styles
99
+ Object.keys({ ...inStartStyles, ...inEndStyles }).forEach(prop => {
100
+ newElement.style[prop] = '';
101
+ });
102
+ if (!isLayoutElement) {
103
+ containerStyle.position = originalPosition;
104
+ }
105
+ }
106
+ /**
107
+ * Predefined transitions
108
+ */
109
+ // Fade transition
110
+ export const fadeTransition = {
111
+ name: 'fade',
112
+ outDuration: 200,
113
+ inDuration: 200,
114
+ out: 'opacity: 0',
115
+ in: 'opacity: 1',
116
+ mode: 'simultaneous'
117
+ };
118
+ // Slide transition (from left)
119
+ export const slideTransition = {
120
+ name: 'slide',
121
+ outDuration: 300,
122
+ inDuration: 300,
123
+ out: 'transform: translateX(-100%)',
124
+ in: 'transform: translateX(0)',
125
+ mode: 'sequential'
126
+ };
127
+ // Slide from right
128
+ export const slideRightTransition = {
129
+ name: 'slide-right',
130
+ outDuration: 300,
131
+ inDuration: 300,
132
+ out: 'transform: translateX(100%)',
133
+ in: 'transform: translateX(0)',
134
+ mode: 'sequential'
135
+ };
136
+ // Slide from top
137
+ export const slideUpTransition = {
138
+ name: 'slide-up',
139
+ outDuration: 300,
140
+ inDuration: 300,
141
+ out: 'transform: translateY(-100%)',
142
+ in: 'transform: translateY(0)',
143
+ mode: 'sequential'
144
+ };
145
+ // Slide from bottom
146
+ export const slideDownTransition = {
147
+ name: 'slide-down',
148
+ outDuration: 300,
149
+ inDuration: 300,
150
+ out: 'transform: translateY(100%)',
151
+ in: 'transform: translateY(0)',
152
+ mode: 'sequential'
153
+ };
154
+ // Scale transition
155
+ export const scaleTransition = {
156
+ name: 'scale',
157
+ outDuration: 250,
158
+ inDuration: 250,
159
+ out: 'transform: scale(0.9); opacity: 0',
160
+ in: 'transform: scale(1); opacity: 1',
161
+ mode: 'simultaneous'
162
+ };
163
+ // Rotate transition
164
+ export const rotateTransition = {
165
+ name: 'rotate',
166
+ outDuration: 400,
167
+ inDuration: 400,
168
+ out: 'transform: rotate(180deg) scale(0.5); opacity: 0',
169
+ in: 'transform: rotate(0) scale(1); opacity: 1',
170
+ mode: 'simultaneous'
171
+ };
172
+ // Flip transition
173
+ export const flipTransition = {
174
+ name: 'flip',
175
+ outDuration: 400,
176
+ inDuration: 400,
177
+ out: 'transform: rotateY(180deg); opacity: 0',
178
+ in: 'transform: rotateY(0); opacity: 1',
179
+ mode: 'sequential'
180
+ };
181
+ // Zoom transition
182
+ export const zoomTransition = {
183
+ name: 'zoom',
184
+ outDuration: 300,
185
+ inDuration: 300,
186
+ out: 'transform: scale(2); opacity: 0',
187
+ in: 'transform: scale(1); opacity: 1',
188
+ mode: 'simultaneous'
189
+ };
190
+ // None transition (instant swap)
191
+ export const noneTransition = {
192
+ name: 'none',
193
+ outDuration: 0,
194
+ inDuration: 0,
195
+ out: '',
196
+ in: '',
197
+ mode: 'simultaneous'
198
+ };
199
+ //# sourceMappingURL=transitions.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"transitions.js","sourceRoot":"","sources":["../../src/transitions.ts"],"names":[],"mappings":"AAAA;;GAEG;AAsCH;;GAEG;AACH,SAAS,WAAW,CAAC,WAAmB;IACtC,MAAM,MAAM,GAA2B,EAAE,CAAC;IAC1C,WAAW,CAAC,KAAK,CAAC,GAAG,CAAC,CAAC,OAAO,CAAC,IAAI,CAAC,EAAE;QACpC,MAAM,CAAC,IAAI,EAAE,KAAK,CAAC,GAAG,IAAI,CAAC,KAAK,CAAC,GAAG,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,IAAI,EAAE,CAAC,CAAC;QACzD,IAAI,IAAI,IAAI,KAAK,EAAE,CAAC;YAClB,MAAM,CAAC,IAAI,CAAC,GAAG,KAAK,CAAC;QACvB,CAAC;IACH,CAAC,CAAC,CAAC;IACH,OAAO,MAAM,CAAC;AAChB,CAAC;AAED;;GAEG;AACH,MAAM,CAAC,KAAK,UAAU,iBAAiB,CACrC,SAAkB,EAClB,UAAuB,EACvB,UAAuB,EACvB,aAAyB,EAAE;IAE3B,MAAM,WAAW,GAAG,UAAU,CAAC,WAAW,IAAI,GAAG,CAAC;IAClD,MAAM,UAAU,GAAG,UAAU,CAAC,UAAU,IAAI,GAAG,CAAC;IAChD,MAAM,IAAI,GAAG,UAAU,CAAC,IAAI,IAAI,YAAY,CAAC;IAE7C,sBAAsB;IACtB,MAAM,SAAS,GAAG,UAAU,CAAC,GAAG,CAAC,CAAC,CAAC,WAAW,CAAC,UAAU,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,EAAE,OAAO,EAAE,GAAG,EAAE,CAAC;IAClF,MAAM,aAAa,GAAG,EAAE,OAAO,EAAE,GAAG,EAAE,CAAC,CAAC,yBAAyB;IACjE,MAAM,WAAW,GAAG,UAAU,CAAC,EAAE,CAAC,CAAC,CAAC,WAAW,CAAC,UAAU,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC,EAAE,OAAO,EAAE,GAAG,EAAE,CAAC;IAElF,sEAAsE;IACtE,sDAAsD;IACtD,MAAM,cAAc,GAAI,SAAyB,CAAC,KAAK,CAAC;IACxD,MAAM,gBAAgB,GAAG,cAAc,CAAC,QAAQ,CAAC;IACjD,MAAM,eAAe,GAAG,SAAS,CAAC,OAAO,CAAC,QAAQ,CAAC,GAAG,CAAC,IAAI,SAAS,CAAC,UAAU,CAAC;IAEhF,IAAI,CAAC,eAAe,EAAE,CAAC;QACrB,cAAc,CAAC,QAAQ,GAAG,UAAU,CAAC;IACvC,CAAC;IAED,kDAAkD;IAClD,MAAM,mBAAmB,GAAG,UAAU,CAAC,YAAY,CAAC,MAAM,CAAC,IAAI,UAAU,CAAC,YAAY,CAAC,MAAM,CAAC,CAAC;IAE/F,IAAI,mBAAmB,EAAE,CAAC;QACxB,qEAAqE;QACrE,UAAU,CAAC,KAAK,CAAC,QAAQ,GAAG,UAAU,CAAC;QACvC,UAAU,CAAC,KAAK,CAAC,KAAK,GAAG,MAAM,CAAC;QAChC,UAAU,CAAC,KAAK,CAAC,MAAM,GAAG,MAAM,CAAC;QACjC,UAAU,CAAC,KAAK,CAAC,UAAU,GAAG,WAAW,WAAW,gBAAgB,CAAC;QAErE,UAAU,CAAC,KAAK,CAAC,QAAQ,GAAG,UAAU,CAAC;QACvC,UAAU,CAAC,KAAK,CAAC,KAAK,GAAG,MAAM,CAAC;QAChC,UAAU,CAAC,KAAK,CAAC,MAAM,GAAG,MAAM,CAAC;QACjC,UAAU,CAAC,KAAK,CAAC,UAAU,GAAG,WAAW,UAAU,gBAAgB,CAAC;IACtE,CAAC;SAAM,CAAC;QACN,yDAAyD;QACzD,UAAU,CAAC,KAAK,CAAC,QAAQ,GAAG,UAAU,CAAC;QACvC,UAAU,CAAC,KAAK,CAAC,GAAG,GAAG,GAAG,CAAC;QAC3B,UAAU,CAAC,KAAK,CAAC,IAAI,GAAG,GAAG,CAAC;QAC5B,UAAU,CAAC,KAAK,CAAC,KAAK,GAAG,MAAM,CAAC;QAChC,UAAU,CAAC,KAAK,CAAC,UAAU,GAAG,OAAO,WAAW,gBAAgB,CAAC;QAEjE,UAAU,CAAC,KAAK,CAAC,QAAQ,GAAG,UAAU,CAAC;QACvC,UAAU,CAAC,KAAK,CAAC,GAAG,GAAG,GAAG,CAAC;QAC3B,UAAU,CAAC,KAAK,CAAC,IAAI,GAAG,GAAG,CAAC;QAC5B,UAAU,CAAC,KAAK,CAAC,KAAK,GAAG,MAAM,CAAC;IAClC,CAAC;IACD,MAAM,CAAC,MAAM,CAAC,UAAU,CAAC,KAAK,EAAE,aAAa,CAAC,CAAC;IAC/C,UAAU,CAAC,KAAK,CAAC,UAAU,GAAG,OAAO,UAAU,gBAAgB,CAAC;IAEhE,+BAA+B;IAC/B,SAAS,CAAC,WAAW,CAAC,UAAU,CAAC,CAAC;IAElC,oCAAoC;IACpC,KAAK,UAAU,CAAC,YAAY,CAAC;IAE7B,IAAI,IAAI,KAAK,cAAc,EAAE,CAAC;QAC5B,iCAAiC;QACjC,MAAM,CAAC,MAAM,CAAC,UAAU,CAAC,KAAK,EAAE,SAAS,CAAC,CAAC;QAC3C,MAAM,CAAC,MAAM,CAAC,UAAU,CAAC,KAAK,EAAE,WAAW,CAAC,CAAC;QAE7C,wCAAwC;QACxC,MAAM,IAAI,OAAO,CAAC,OAAO,CAAC,EAAE,CAAC,UAAU,CAAC,OAAO,EAAE,IAAI,CAAC,GAAG,CAAC,WAAW,EAAE,UAAU,CAAC,CAAC,CAAC,CAAC;IACvF,CAAC;SAAM,CAAC;QACN,yDAAyD;QACzD,MAAM,CAAC,MAAM,CAAC,UAAU,CAAC,KAAK,EAAE,SAAS,CAAC,CAAC;QAC3C,MAAM,IAAI,OAAO,CAAC,OAAO,CAAC,EAAE,CAAC,UAAU,CAAC,OAAO,EAAE,WAAW,CAAC,CAAC,CAAC;QAE/D,MAAM,CAAC,MAAM,CAAC,UAAU,CAAC,KAAK,EAAE,WAAW,CAAC,CAAC;QAC7C,MAAM,IAAI,OAAO,CAAC,OAAO,CAAC,EAAE,CAAC,UAAU,CAAC,OAAO,EAAE,UAAU,CAAC,CAAC,CAAC;IAChE,CAAC;IAED,UAAU;IACV,UAAU,CAAC,MAAM,EAAE,CAAC;IAEpB,IAAI,mBAAmB,EAAE,CAAC;QACxB,+BAA+B;QAC/B,UAAU,CAAC,KAAK,CAAC,QAAQ,GAAG,EAAE,CAAC;QAC/B,UAAU,CAAC,KAAK,CAAC,KAAK,GAAG,EAAE,CAAC;QAC5B,UAAU,CAAC,KAAK,CAAC,MAAM,GAAG,EAAE,CAAC;QAC7B,UAAU,CAAC,KAAK,CAAC,UAAU,GAAG,EAAE,CAAC;IACnC,CAAC;SAAM,CAAC;QACN,mCAAmC;QACnC,UAAU,CAAC,KAAK,CAAC,QAAQ,GAAG,EAAE,CAAC;QAC/B,UAAU,CAAC,KAAK,CAAC,GAAG,GAAG,EAAE,CAAC;QAC1B,UAAU,CAAC,KAAK,CAAC,IAAI,GAAG,EAAE,CAAC;QAC3B,UAAU,CAAC,KAAK,CAAC,KAAK,GAAG,EAAE,CAAC;QAC5B,UAAU,CAAC,KAAK,CAAC,UAAU,GAAG,EAAE,CAAC;IACnC,CAAC;IAED,8BAA8B;IAC9B,MAAM,CAAC,IAAI,CAAC,EAAC,GAAG,aAAa,EAAE,GAAG,WAAW,EAAC,CAAC,CAAC,OAAO,CAAC,IAAI,CAAC,EAAE;QAC7D,UAAU,CAAC,KAAK,CAAC,IAAW,CAAC,GAAG,EAAE,CAAC;IACrC,CAAC,CAAC,CAAC;IACH,IAAI,CAAC,eAAe,EAAE,CAAC;QACrB,cAAc,CAAC,QAAQ,GAAG,gBAAgB,CAAC;IAC7C,CAAC;AACH,CAAC;AAED;;GAEG;AAEH,kBAAkB;AAClB,MAAM,CAAC,MAAM,cAAc,GAAe;IACxC,IAAI,EAAE,MAAM;IACZ,WAAW,EAAE,GAAG;IAChB,UAAU,EAAE,GAAG;IACf,GAAG,EAAE,YAAY;IACjB,EAAE,EAAE,YAAY;IAChB,IAAI,EAAE,cAAc;CACrB,CAAC;AAEF,+BAA+B;AAC/B,MAAM,CAAC,MAAM,eAAe,GAAe;IACzC,IAAI,EAAE,OAAO;IACb,WAAW,EAAE,GAAG;IAChB,UAAU,EAAE,GAAG;IACf,GAAG,EAAE,8BAA8B;IACnC,EAAE,EAAE,0BAA0B;IAC9B,IAAI,EAAE,YAAY;CACnB,CAAC;AAEF,mBAAmB;AACnB,MAAM,CAAC,MAAM,oBAAoB,GAAe;IAC9C,IAAI,EAAE,aAAa;IACnB,WAAW,EAAE,GAAG;IAChB,UAAU,EAAE,GAAG;IACf,GAAG,EAAE,6BAA6B;IAClC,EAAE,EAAE,0BAA0B;IAC9B,IAAI,EAAE,YAAY;CACnB,CAAC;AAEF,iBAAiB;AACjB,MAAM,CAAC,MAAM,iBAAiB,GAAe;IAC3C,IAAI,EAAE,UAAU;IAChB,WAAW,EAAE,GAAG;IAChB,UAAU,EAAE,GAAG;IACf,GAAG,EAAE,8BAA8B;IACnC,EAAE,EAAE,0BAA0B;IAC9B,IAAI,EAAE,YAAY;CACnB,CAAC;AAEF,oBAAoB;AACpB,MAAM,CAAC,MAAM,mBAAmB,GAAe;IAC7C,IAAI,EAAE,YAAY;IAClB,WAAW,EAAE,GAAG;IAChB,UAAU,EAAE,GAAG;IACf,GAAG,EAAE,6BAA6B;IAClC,EAAE,EAAE,0BAA0B;IAC9B,IAAI,EAAE,YAAY;CACnB,CAAC;AAEF,mBAAmB;AACnB,MAAM,CAAC,MAAM,eAAe,GAAe;IACzC,IAAI,EAAE,OAAO;IACb,WAAW,EAAE,GAAG;IAChB,UAAU,EAAE,GAAG;IACf,GAAG,EAAE,mCAAmC;IACxC,EAAE,EAAE,iCAAiC;IACrC,IAAI,EAAE,cAAc;CACrB,CAAC;AAEF,oBAAoB;AACpB,MAAM,CAAC,MAAM,gBAAgB,GAAe;IAC1C,IAAI,EAAE,QAAQ;IACd,WAAW,EAAE,GAAG;IAChB,UAAU,EAAE,GAAG;IACf,GAAG,EAAE,kDAAkD;IACvD,EAAE,EAAE,2CAA2C;IAC/C,IAAI,EAAE,cAAc;CACrB,CAAC;AAEF,kBAAkB;AAClB,MAAM,CAAC,MAAM,cAAc,GAAe;IACxC,IAAI,EAAE,MAAM;IACZ,WAAW,EAAE,GAAG;IAChB,UAAU,EAAE,GAAG;IACf,GAAG,EAAE,wCAAwC;IAC7C,EAAE,EAAE,mCAAmC;IACvC,IAAI,EAAE,YAAY;CACnB,CAAC;AAEF,kBAAkB;AAClB,MAAM,CAAC,MAAM,cAAc,GAAe;IACxC,IAAI,EAAE,MAAM;IACZ,WAAW,EAAE,GAAG;IAChB,UAAU,EAAE,GAAG;IACf,GAAG,EAAE,iCAAiC;IACtC,EAAE,EAAE,iCAAiC;IACrC,IAAI,EAAE,cAAc;CACrB,CAAC;AAEF,iCAAiC;AACjC,MAAM,CAAC,MAAM,cAAc,GAAe;IACxC,IAAI,EAAE,MAAM;IACZ,WAAW,EAAE,CAAC;IACd,UAAU,EAAE,CAAC;IACb,GAAG,EAAE,EAAE;IACP,EAAE,EAAE,EAAE;IACN,IAAI,EAAE,cAAc;CACrB,CAAC"}
package/package.json CHANGED
@@ -1,22 +1,20 @@
1
1
  {
2
2
  "name": "snice",
3
- "version": "1.13.2",
3
+ "version": "1.13.4",
4
4
  "type": "module",
5
5
  "description": "Imperative TypeScript framework for building vanilla web components with decorators, routing, and controllers. No virtual DOM, no build complexity.",
6
- "main": "src/index.ts",
7
- "module": "src/index.ts",
8
- "types": "src/index.ts",
6
+ "main": "dist/index.js",
7
+ "module": "dist/index.js",
8
+ "types": "dist/index.d.ts",
9
9
  "bin": {
10
10
  "snice": "./bin/snice.js"
11
11
  },
12
12
  "files": [
13
- "src",
13
+ "dist",
14
14
  "components",
15
15
  "bin",
16
16
  "templates",
17
17
  "README.md",
18
- "!src/**/*.test.ts",
19
- "!src/**/*.spec.ts",
20
18
  "!components/**/*.test.ts",
21
19
  "!components/**/*.spec.ts",
22
20
  "!components/**/*.html",
@@ -62,7 +60,7 @@
62
60
  },
63
61
  "scripts": {
64
62
  "dev": "vite",
65
- "build": "tsc && vite build",
63
+ "build": "tsc -p tsconfig.build.json --noEmitOnError false",
66
64
  "preview": "vite preview",
67
65
  "test": "vitest run",
68
66
  "test:watch": "vitest",
package/src/controller.ts DELETED
@@ -1,347 +0,0 @@
1
- import { setupEventHandlers, cleanupEventHandlers } from './events';
2
- import { setupObservers, cleanupObservers } from './observe';
3
- import { setupResponseHandlers, cleanupResponseHandlers } from './request-response';
4
- import { IS_CONTROLLER_CLASS, IS_CONTROLLER_INSTANCE, CONTROLLER_KEY, CONTROLLER_NAME_KEY, CONTROLLER_ID, CONTROLLER_OPERATIONS, NATIVE_CONTROLLER, IS_ELEMENT_CLASS, ROUTER_CONTEXT } from './symbols';
5
- import { snice } from './global';
6
-
7
- type Maybe<T> = T | null | undefined;
8
-
9
- export interface IController<T extends HTMLElement = HTMLElement> {
10
- element: Maybe<T>;
11
- attach(element: T): void | Promise<void>;
12
- detach(element: T): void | Promise<void>;
13
- }
14
-
15
- export type ControllerClass<T extends HTMLElement = HTMLElement> = new() => IController<T>;
16
-
17
- // Controller-scoped cleanup registry
18
- class ControllerScope {
19
- private cleanupFns: Map<string, Function> = new Map();
20
- private pendingOperations: Set<Promise<void>> = new Set();
21
-
22
- register(key: string, cleanup: Function): void {
23
- this.cleanupFns.set(key, cleanup);
24
- }
25
-
26
- unregister(key: string): void {
27
- this.cleanupFns.delete(key);
28
- }
29
-
30
- async cleanup(): Promise<void> {
31
- // Wait for all pending operations
32
- await Promise.all(this.pendingOperations);
33
-
34
- // Run all cleanup functions
35
- for (const cleanup of this.cleanupFns.values()) {
36
- try {
37
- await cleanup();
38
- } catch (error) {
39
- console.error('Error during cleanup:', error);
40
- }
41
- }
42
- this.cleanupFns.clear();
43
- }
44
-
45
- async runOperation<T>(operation: () => Promise<T>): Promise<T> {
46
- const promise = operation();
47
- const voidPromise = promise.then(() => {}, () => {});
48
- this.pendingOperations.add(voidPromise);
49
-
50
- try {
51
- const result = await promise;
52
- this.pendingOperations.delete(voidPromise);
53
- return result;
54
- } catch (error) {
55
- this.pendingOperations.delete(voidPromise);
56
- throw error;
57
- }
58
- }
59
- }
60
-
61
- /**
62
- * Decorator to register a controller class with a name
63
- * @param name The name to register the controller under
64
- */
65
- export function controller(name: string) {
66
- return function <T extends ControllerClass>(constructor: T) {
67
- snice.controllerRegistry.set(name, constructor);
68
- // Mark as controller class for channel decorator detection
69
- (constructor.prototype as any)[IS_CONTROLLER_CLASS] = true;
70
- return constructor;
71
- };
72
- }
73
-
74
- /**
75
- * Attaches a controller to an element
76
- * @param element The element to attach the controller to
77
- * @param controllerName The name of the controller to attach
78
- */
79
- export async function attachController(element: HTMLElement, controllerName: string): Promise<void> {
80
- const existingController = (element as any)[CONTROLLER_KEY] as IController | undefined;
81
- const existingName = (element as any)[CONTROLLER_NAME_KEY] as string | undefined;
82
-
83
- // For native elements, check if this is actually the desired controller
84
- const nativeController = (element as any)[NATIVE_CONTROLLER];
85
- if (nativeController !== undefined && nativeController !== controllerName) {
86
- // This attachment is outdated, skip it
87
- return;
88
- }
89
-
90
- if (existingName === controllerName && existingController) {
91
- // Already attached and controller exists
92
- return;
93
- }
94
-
95
- // If there's an existing controller, detach it first
96
- if (existingController) {
97
- await detachController(element);
98
- }
99
-
100
- const ControllerClass = snice.controllerRegistry.get(controllerName);
101
- if (!ControllerClass) {
102
- throw new Error(`Controller "${controllerName}" not found in registry`);
103
- }
104
-
105
- // Create controller instance with unique ID and scope
106
- const controllerInstance = new ControllerClass();
107
- snice.controllerIdCounter += 1;
108
- const controllerId = snice.controllerIdCounter;
109
- const scope = new ControllerScope();
110
-
111
- // Mark this as a controller instance
112
- (controllerInstance as any)[IS_CONTROLLER_INSTANCE] = true;
113
- (controllerInstance as any)[CONTROLLER_ID] = controllerId;
114
- controllerInstance.element = element;
115
-
116
- // Pass router context from element to controller if it exists
117
- const routerContext = (element as any)[ROUTER_CONTEXT];
118
- if (routerContext !== undefined) {
119
- (controllerInstance as any)[ROUTER_CONTEXT] = routerContext;
120
- }
121
-
122
- // Store references
123
- (element as any)[CONTROLLER_KEY] = controllerInstance;
124
- (element as any)[CONTROLLER_NAME_KEY] = controllerName;
125
- (element as any)[CONTROLLER_OPERATIONS] = scope;
126
-
127
- // Wait for element to be ready (required)
128
- await (element as any).ready;
129
-
130
- // Run attach in the controller's scope
131
- await scope.runOperation(async () => {
132
- await controllerInstance.attach(element);
133
- });
134
-
135
- // Setup @on event handlers for controller
136
- setupEventHandlers(controllerInstance, element);
137
-
138
- // Setup @observe observers for controller
139
- setupObservers(controllerInstance, element);
140
-
141
- // Setup @channel handlers for controller
142
- setupResponseHandlers(controllerInstance, element);
143
-
144
- element.dispatchEvent(new CustomEvent('@snice/controller-attached', {
145
- detail: { name: controllerName, controller: controllerInstance }
146
- }));
147
- }
148
-
149
- /**
150
- * Detaches a controller from an element
151
- * @param element The element to detach the controller from
152
- */
153
- export async function detachController(element: HTMLElement): Promise<void> {
154
- const controllerInstance = (element as any)[CONTROLLER_KEY] as IController | undefined;
155
- const controllerName = (element as any)[CONTROLLER_NAME_KEY] as string | undefined;
156
- const scope = (element as any)[CONTROLLER_OPERATIONS] as ControllerScope | undefined;
157
-
158
- if (!controllerInstance) {
159
- return;
160
- }
161
-
162
- // Run detach in the controller's scope
163
- if (scope) {
164
- await scope.runOperation(async () => {
165
- await controllerInstance.detach(element);
166
- });
167
- } else {
168
- await controllerInstance.detach(element);
169
- }
170
-
171
- controllerInstance.element = null;
172
-
173
- // Cleanup @on event handlers for controller
174
- cleanupEventHandlers(controllerInstance);
175
-
176
- // Cleanup @observe observers for controller
177
- cleanupObservers(controllerInstance);
178
-
179
- // Cleanup @channel handlers for controller
180
- cleanupResponseHandlers(controllerInstance);
181
-
182
- // Cleanup the controller scope
183
- if (scope) {
184
- await scope.cleanup();
185
- }
186
-
187
- // Clean up router context reference
188
- delete (controllerInstance as any)[ROUTER_CONTEXT];
189
-
190
- delete (element as any)[CONTROLLER_KEY];
191
- delete (element as any)[CONTROLLER_NAME_KEY];
192
- delete (element as any)[CONTROLLER_OPERATIONS];
193
-
194
- element.dispatchEvent(new CustomEvent('@snice/controller-detached', {
195
- detail: { name: controllerName, controller: controllerInstance }
196
- }));
197
- }
198
-
199
- /**
200
- * Gets the controller instance attached to an element
201
- * @param element The element to get the controller from
202
- * @returns The controller instance or undefined
203
- */
204
- export function getController<T extends IController = IController>(element: HTMLElement): T | undefined {
205
- return (element as any)[CONTROLLER_KEY] as T | undefined;
206
- }
207
-
208
- /**
209
- * Gets the controller scope for an element
210
- * @param element The element to get the scope from
211
- * @returns The controller scope or undefined
212
- */
213
- export function getControllerScope(element: HTMLElement): ControllerScope | undefined {
214
- return (element as any)[CONTROLLER_OPERATIONS] as ControllerScope | undefined;
215
- }
216
-
217
- /**
218
- * Enable controller support for native HTML elements
219
- * This sets up a MutationObserver to watch for controller attributes
220
- * on non-custom elements (elements without hyphens in their tag names)
221
- */
222
- export function useNativeElementControllers() {
223
- // Return if already initialized
224
- if ((globalThis as any).sniceNativeControllersInitialized) {
225
- return;
226
- }
227
- (globalThis as any).sniceNativeControllersInitialized = true;
228
-
229
- // Process elements that already have controller attribute
230
- function processElement(element: Element) {
231
- if (!(element instanceof HTMLElement)) return;
232
-
233
- // Skip custom elements (they handle controllers themselves)
234
- if (element.tagName.includes('-')) return;
235
-
236
- // Skip elements that are @element decorated (they have their own controller handling)
237
- if ((element as any)[IS_ELEMENT_CLASS]) return;
238
-
239
- const controllerName = element.getAttribute('controller');
240
- const currentControllerName = (element as any)[NATIVE_CONTROLLER];
241
-
242
- if (controllerName && controllerName !== currentControllerName) {
243
- // Controller added or changed
244
- (element as any)[NATIVE_CONTROLLER] = controllerName;
245
-
246
- // For non-custom elements, we need to add the ready promise
247
- if (!(element as any).ready) {
248
- (element as any).ready = Promise.resolve();
249
- }
250
-
251
- // Detach old controller if exists (don't await - let it run async)
252
- if (currentControllerName) {
253
- detachController(element as HTMLElement).catch(error => {
254
- console.error(`Failed to detach old controller from native element:`, error);
255
- });
256
- }
257
-
258
- // Attach the new controller
259
- attachController(element as HTMLElement, controllerName).catch(error => {
260
- console.error(`Failed to attach controller "${controllerName}" to native element:`, error);
261
- });
262
- } else if (!controllerName && currentControllerName) {
263
- // Controller was removed
264
- delete (element as any)[NATIVE_CONTROLLER];
265
- // Clear the controller name immediately to allow re-attachment
266
- delete (element as any)[CONTROLLER_NAME_KEY];
267
- detachController(element as HTMLElement).catch(error => {
268
- console.error(`Failed to detach controller from native element:`, error);
269
- });
270
- }
271
- }
272
-
273
- // Set up MutationObserver to watch for controller attributes
274
- const observer = new MutationObserver((mutations) => {
275
- for (const mutation of mutations) {
276
- if (mutation.type === 'attributes' && mutation.attributeName === 'controller') {
277
- processElement(mutation.target as Element);
278
- } else if (mutation.type === 'childList') {
279
- // Process added nodes
280
- mutation.addedNodes.forEach(node => {
281
- if (node instanceof HTMLElement) {
282
- // Process the node itself
283
- processElement(node);
284
- // Process all descendants with controller attribute
285
- node.querySelectorAll('[controller]:not([class*="-"])').forEach(processElement);
286
- }
287
- });
288
- }
289
- }
290
- });
291
-
292
- // Start observing when DOM is ready
293
- if (document.readyState === 'loading') {
294
- document.addEventListener('DOMContentLoaded', () => {
295
- // Process existing elements (excluding custom elements)
296
- document.querySelectorAll('[controller]:not([class*="-"])').forEach(processElement);
297
-
298
- // Start observing
299
- observer.observe(document.body, {
300
- attributes: true,
301
- attributeFilter: ['controller'],
302
- childList: true,
303
- subtree: true
304
- });
305
- });
306
- } else {
307
- // DOM already loaded
308
- document.querySelectorAll('[controller]:not([class*="-"])').forEach(processElement);
309
-
310
- observer.observe(document.body, {
311
- attributes: true,
312
- attributeFilter: ['controller'],
313
- childList: true,
314
- subtree: true
315
- });
316
- }
317
-
318
- // Store observer reference for cleanup if needed
319
- (globalThis as any).sniceNativeControllerObserver = observer;
320
- }
321
-
322
- /**
323
- * Stop watching for native element controllers
324
- */
325
- export function cleanupNativeElementControllers() {
326
- const observer = (globalThis as any).sniceNativeControllerObserver;
327
- if (observer) {
328
- observer.disconnect();
329
- delete (globalThis as any).sniceNativeControllerObserver;
330
- delete (globalThis as any).sniceNativeControllersInitialized;
331
- }
332
- }
333
-
334
- /**
335
- * Registers a cleanup function for the current controller
336
- * @param controller The controller instance
337
- * @param key A unique key for this cleanup function
338
- * @param cleanup The cleanup function to register
339
- */
340
- export function registerControllerCleanup(controller: IController, key: string, cleanup: Function): void {
341
- if (!controller.element) return;
342
-
343
- const scope = getControllerScope(controller.element as HTMLElement);
344
- if (scope) {
345
- scope.register(key, cleanup);
346
- }
347
- }