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,805 @@
1
+ import { attachController, detachController } from './controller';
2
+ import { setupEventHandlers, cleanupEventHandlers } from './events';
3
+ import { setupObservers, cleanupObservers } from './observe';
4
+ import { setupResponseHandlers, cleanupResponseHandlers } from './request-response';
5
+ import { IS_ELEMENT_CLASS, IS_CONTROLLER_INSTANCE, READY_PROMISE, READY_RESOLVE, CONTROLLER, PROPERTIES, PROPERTY_VALUES, PROPERTIES_INITIALIZED, PROPERTY_WATCHERS, EXPLICITLY_SET_PROPERTIES, ROUTER_CONTEXT, READY_HANDLERS, DISPOSE_HANDLERS, PARTS, PART_TIMERS } from './symbols';
6
+ /**
7
+ * Applies core element functionality to a constructor
8
+ * This is shared between @element and @page decorators
9
+ */
10
+ export function applyElementFunctionality(constructor) {
11
+ // Mark as element class for channel decorator detection
12
+ constructor.prototype[IS_ELEMENT_CLASS] = true;
13
+ // Add controller property to all elements
14
+ const originalConnectedCallback = constructor.prototype.connectedCallback;
15
+ const originalDisconnectedCallback = constructor.prototype.disconnectedCallback;
16
+ const originalAttributeChangedCallback = constructor.prototype.attributeChangedCallback;
17
+ // Add 'controller' and all reflected properties to observed attributes
18
+ const observedAttributes = constructor.observedAttributes || [];
19
+ if (!observedAttributes.includes('controller')) {
20
+ observedAttributes.push('controller');
21
+ }
22
+ // Add all properties to observed attributes (not just reflected ones)
23
+ const properties = constructor[PROPERTIES];
24
+ if (properties) {
25
+ for (const [propName, propOptions] of properties) {
26
+ const attributeName = typeof propOptions.attribute === 'string' ? propOptions.attribute : propName.toLowerCase();
27
+ if (!observedAttributes.includes(attributeName)) {
28
+ observedAttributes.push(attributeName);
29
+ }
30
+ }
31
+ }
32
+ Object.defineProperty(constructor, 'observedAttributes', {
33
+ get() { return observedAttributes; },
34
+ configurable: true
35
+ });
36
+ // Add ready property - always returns a promise
37
+ Object.defineProperty(constructor.prototype, 'ready', {
38
+ get() {
39
+ if (!this[READY_PROMISE]) {
40
+ // Create a pending promise if not yet initialized
41
+ this[READY_PROMISE] = new Promise((resolve) => {
42
+ this[READY_RESOLVE] = resolve;
43
+ });
44
+ }
45
+ return this[READY_PROMISE];
46
+ },
47
+ enumerable: true,
48
+ configurable: true
49
+ });
50
+ // Add controller property
51
+ Object.defineProperty(constructor.prototype, 'controller', {
52
+ get() {
53
+ return this[CONTROLLER];
54
+ },
55
+ set(value) {
56
+ const oldValue = this[CONTROLLER];
57
+ this[CONTROLLER] = value;
58
+ if (value !== oldValue && value) {
59
+ // Attach controller asynchronously
60
+ attachController(this, value).catch(error => {
61
+ console.error(`Failed to attach controller "${value}":`, error);
62
+ });
63
+ }
64
+ else if (!value && oldValue) {
65
+ // Detach controller asynchronously
66
+ detachController(this).catch(error => {
67
+ console.error(`Failed to detach controller:`, error);
68
+ });
69
+ }
70
+ },
71
+ enumerable: true,
72
+ configurable: true
73
+ });
74
+ constructor.prototype.connectedCallback = async function () {
75
+ // If ready promise was already created (controller attached before connected), use existing resolve
76
+ // Otherwise create the ready promise now
77
+ if (!this[READY_PROMISE]) {
78
+ this[READY_PROMISE] = new Promise((resolve) => {
79
+ this[READY_RESOLVE] = resolve;
80
+ });
81
+ }
82
+ try {
83
+ // Initialize properties from attributes before rendering
84
+ const properties = constructor[PROPERTIES];
85
+ if (properties) {
86
+ for (const [propName, propOptions] of properties) {
87
+ // If attribute exists, it always wins
88
+ if (this.hasAttribute(propName)) {
89
+ // Attribute exists, parse and set the property value
90
+ const attrValue = this.getAttribute(propName);
91
+ // Mark as explicitly set since it came from an attribute
92
+ if (!this[EXPLICITLY_SET_PROPERTIES]) {
93
+ this[EXPLICITLY_SET_PROPERTIES] = new Set();
94
+ }
95
+ this[EXPLICITLY_SET_PROPERTIES].add(propName);
96
+ switch (propOptions.type) {
97
+ case Boolean:
98
+ this[propName] = attrValue !== null && attrValue !== 'false';
99
+ break;
100
+ case Number:
101
+ this[propName] = Number(attrValue);
102
+ break;
103
+ case String:
104
+ this[propName] = attrValue;
105
+ break;
106
+ case Date:
107
+ this[propName] = attrValue ? new Date(attrValue) : null;
108
+ break;
109
+ case BigInt:
110
+ if (attrValue && attrValue.endsWith('n')) {
111
+ this[propName] = BigInt(attrValue.slice(0, -1));
112
+ }
113
+ else {
114
+ this[propName] = attrValue ? BigInt(attrValue) : null;
115
+ }
116
+ break;
117
+ case SimpleArray:
118
+ this[propName] = SimpleArray.parse(attrValue);
119
+ break;
120
+ default:
121
+ this[propName] = attrValue;
122
+ }
123
+ }
124
+ }
125
+ }
126
+ // Mark that properties have been initialized
127
+ this[PROPERTIES_INITIALIZED] = true;
128
+ // Reflect properties that were explicitly set before connection
129
+ // but skip default values that were never explicitly set
130
+ if (properties && this[EXPLICITLY_SET_PROPERTIES]) {
131
+ for (const [propName, propOptions] of properties) {
132
+ if (propOptions.reflect && this[EXPLICITLY_SET_PROPERTIES].has(propName) && propName in this[PROPERTY_VALUES]) {
133
+ const value = this[PROPERTY_VALUES][propName];
134
+ const attributeName = typeof propOptions.attribute === 'string' ? propOptions.attribute : propName.toLowerCase();
135
+ if (value !== null && value !== undefined && value !== false &&
136
+ !(propOptions.type === SimpleArray && Array.isArray(value) && value.length === 0)) {
137
+ // Handle special types for reflection
138
+ let attributeValue;
139
+ if (value instanceof Date) {
140
+ attributeValue = value.toISOString();
141
+ }
142
+ else if (typeof value === 'bigint') {
143
+ attributeValue = value.toString() + 'n';
144
+ }
145
+ else if (propOptions.type === SimpleArray && Array.isArray(value)) {
146
+ attributeValue = SimpleArray.serialize(value);
147
+ }
148
+ else {
149
+ attributeValue = String(value);
150
+ }
151
+ this.setAttribute(attributeName, attributeValue);
152
+ }
153
+ }
154
+ }
155
+ }
156
+ // Clean up any existing event handlers first (for reconnection)
157
+ cleanupEventHandlers(this);
158
+ // Create shadow root if it doesn't exist
159
+ if (!this.shadowRoot) {
160
+ this.attachShadow({ mode: 'open' });
161
+ }
162
+ // Build the shadow DOM content
163
+ let shadowContent = '';
164
+ // Add HTML first (maintaining original order)
165
+ if (this.html) {
166
+ try {
167
+ const htmlResult = this.html();
168
+ // Handle both async and sync html
169
+ const htmlContent = htmlResult instanceof Promise ? await htmlResult : htmlResult;
170
+ if (htmlContent !== undefined) {
171
+ shadowContent += htmlContent;
172
+ }
173
+ }
174
+ catch (error) {
175
+ console.error(`Error in html() method for ${this.tagName}:`, error);
176
+ }
177
+ }
178
+ // Add CSS after HTML (maintaining original order)
179
+ if (this.css) {
180
+ try {
181
+ const cssResult = this.css();
182
+ // Handle both async and sync css
183
+ const cssResolved = cssResult instanceof Promise ? await cssResult : cssResult;
184
+ if (cssResolved) {
185
+ // Handle both string and array of strings
186
+ const cssContent = Array.isArray(cssResolved) ? cssResolved.join('\n') : cssResolved;
187
+ // No need for scoping with Shadow DOM, but add data attribute for compatibility
188
+ shadowContent += `<style data-component-css>${cssContent}</style>`;
189
+ }
190
+ }
191
+ catch (error) {
192
+ console.error(`Error in css() method for ${this.tagName}:`, error);
193
+ }
194
+ }
195
+ // Set shadow DOM content
196
+ if (shadowContent) {
197
+ this.shadowRoot.innerHTML = shadowContent;
198
+ }
199
+ // Render all @part methods into their corresponding elements
200
+ const parts = constructor[PARTS];
201
+ if (parts && this.shadowRoot) {
202
+ for (const [partName, partHandler] of parts) {
203
+ try {
204
+ const partElement = this.shadowRoot.querySelector(`[part="${partName}"]`);
205
+ if (partElement) {
206
+ const partResult = partHandler.method.call(this);
207
+ const partContent = partResult instanceof Promise ? await partResult : partResult;
208
+ if (partContent !== undefined) {
209
+ partElement.innerHTML = partContent;
210
+ }
211
+ }
212
+ }
213
+ catch (error) {
214
+ console.error(`Error rendering @part('${partName}') in ${this.tagName}:`, error);
215
+ }
216
+ }
217
+ }
218
+ // NOW call the original user-defined connectedCallback after shadow DOM is set up
219
+ if (originalConnectedCallback) {
220
+ originalConnectedCallback.call(this);
221
+ }
222
+ const controllerName = this.getAttribute('controller');
223
+ if (controllerName) {
224
+ this.controller = controllerName;
225
+ }
226
+ // Setup @on event handlers - use element for host events, shadow root for delegated events
227
+ setupEventHandlers(this, this);
228
+ // Setup @respond handlers for elements
229
+ setupResponseHandlers(this, this);
230
+ // Setup @observe observers
231
+ try {
232
+ setupObservers(this, this);
233
+ }
234
+ catch (error) {
235
+ console.error(`Error setting up observers for ${this.tagName}:`, error);
236
+ }
237
+ // Call @ready handlers after everything is set up
238
+ const readyHandlers = constructor[READY_HANDLERS];
239
+ if (readyHandlers) {
240
+ for (const handler of readyHandlers) {
241
+ try {
242
+ await handler.method.call(this);
243
+ }
244
+ catch (error) {
245
+ console.error(`Error in @ready handler ${handler.methodName}:`, error);
246
+ }
247
+ }
248
+ }
249
+ }
250
+ finally {
251
+ // Always mark element as ready, even if there were errors
252
+ if (this[READY_RESOLVE]) {
253
+ this[READY_RESOLVE]();
254
+ this[READY_RESOLVE] = null; // Clear the resolver
255
+ }
256
+ }
257
+ };
258
+ constructor.prototype.disconnectedCallback = async function () {
259
+ // Call @dispose handlers
260
+ const disposeHandlers = constructor[DISPOSE_HANDLERS];
261
+ if (disposeHandlers) {
262
+ for (const handler of disposeHandlers) {
263
+ try {
264
+ await handler.method.call(this);
265
+ }
266
+ catch (error) {
267
+ console.error(`Error in @dispose handler ${handler.methodName}:`, error);
268
+ }
269
+ }
270
+ }
271
+ // Call original user-defined disconnectedCallback
272
+ if (originalDisconnectedCallback) {
273
+ originalDisconnectedCallback.call(this);
274
+ }
275
+ if (this[CONTROLLER]) {
276
+ detachController(this).catch(error => {
277
+ console.error(`Failed to detach controller:`, error);
278
+ });
279
+ }
280
+ // Cleanup @on event handlers
281
+ cleanupEventHandlers(this);
282
+ // Cleanup @respond handlers
283
+ cleanupResponseHandlers(this);
284
+ // Cleanup @observe observers
285
+ cleanupObservers(this);
286
+ };
287
+ constructor.prototype.attributeChangedCallback = function (name, oldValue, newValue) {
288
+ originalAttributeChangedCallback?.call(this, name, oldValue, newValue);
289
+ if (name === 'controller') {
290
+ this.controller = newValue;
291
+ }
292
+ else {
293
+ // Handle all properties (not just reflected ones)
294
+ const properties = constructor[PROPERTIES];
295
+ if (properties) {
296
+ for (const [propName, propOptions] of properties) {
297
+ const attributeName = typeof propOptions.attribute === 'string' ? propOptions.attribute : propName.toLowerCase();
298
+ if (attributeName === name) {
299
+ // Check if the current property value already matches to avoid feedback loops
300
+ const currentValue = this[PROPERTY_VALUES]?.[propName];
301
+ // Parse the new value based on type
302
+ let parsedValue;
303
+ if (propOptions.type === Boolean) {
304
+ parsedValue = newValue !== null && newValue !== 'false';
305
+ }
306
+ else if (propOptions.type === Number) {
307
+ parsedValue = Number(newValue);
308
+ }
309
+ else if (propOptions.type === Date) {
310
+ parsedValue = newValue ? new Date(newValue) : null;
311
+ }
312
+ else if (propOptions.type === BigInt) {
313
+ if (newValue && newValue.endsWith('n')) {
314
+ parsedValue = BigInt(newValue.slice(0, -1));
315
+ }
316
+ else {
317
+ parsedValue = newValue ? BigInt(newValue) : null;
318
+ }
319
+ }
320
+ else if (propOptions.type === SimpleArray) {
321
+ parsedValue = SimpleArray.parse(newValue);
322
+ }
323
+ else {
324
+ // If no type specified, try to infer from current value type
325
+ if (typeof currentValue === 'number' && newValue !== null) {
326
+ parsedValue = Number(newValue);
327
+ }
328
+ else {
329
+ parsedValue = newValue;
330
+ }
331
+ }
332
+ // Only update if the value actually changed and avoid infinite loops
333
+ if (currentValue !== parsedValue) {
334
+ // Mark as explicitly set since it came from an attribute change
335
+ if (!this[EXPLICITLY_SET_PROPERTIES]) {
336
+ this[EXPLICITLY_SET_PROPERTIES] = new Set();
337
+ }
338
+ this[EXPLICITLY_SET_PROPERTIES].add(propName);
339
+ // Set the property value directly in the storage to avoid triggering setter
340
+ if (!this[PROPERTY_VALUES]) {
341
+ this[PROPERTY_VALUES] = {};
342
+ }
343
+ this[PROPERTY_VALUES][propName] = parsedValue;
344
+ // Call watchers manually since we bypassed the setter
345
+ const watchers = constructor[PROPERTY_WATCHERS];
346
+ if (watchers) {
347
+ // Call specific property watchers
348
+ if (watchers.has(propName)) {
349
+ const propertyWatchers = watchers.get(propName);
350
+ for (const watcher of propertyWatchers) {
351
+ try {
352
+ watcher.method.call(this, currentValue, parsedValue, propName);
353
+ }
354
+ catch (error) {
355
+ console.error(`Error in @watch('${propName}') method ${watcher.methodName}:`, error);
356
+ }
357
+ }
358
+ }
359
+ // Call wildcard watchers (watching "*")
360
+ if (watchers.has('*')) {
361
+ const wildcardWatchers = watchers.get('*');
362
+ for (const watcher of wildcardWatchers) {
363
+ try {
364
+ watcher.method.call(this, currentValue, parsedValue, propName);
365
+ }
366
+ catch (error) {
367
+ console.error(`Error in @watch('*') method ${watcher.methodName}:`, error);
368
+ }
369
+ }
370
+ }
371
+ }
372
+ }
373
+ break;
374
+ }
375
+ }
376
+ }
377
+ }
378
+ };
379
+ }
380
+ export function element(tagName) {
381
+ return function (constructor) {
382
+ applyElementFunctionality(constructor);
383
+ customElements.define(tagName, constructor);
384
+ };
385
+ }
386
+ export function layout(tagName) {
387
+ return function (constructor) {
388
+ applyElementFunctionality(constructor);
389
+ customElements.define(tagName, constructor);
390
+ };
391
+ }
392
+ export function property(options) {
393
+ return function (target, propertyKey) {
394
+ const constructor = target.constructor;
395
+ // Warn about problematic reflection usage
396
+ if (options?.reflect && options?.type === Array) {
397
+ console.warn(`⚠️ Property '${propertyKey}' uses reflect:true with Array type.`);
398
+ }
399
+ if (options?.reflect && options?.type === Object) {
400
+ console.warn(`⚠️ Property '${propertyKey}' uses reflect:true with Object type.`);
401
+ }
402
+ if (!constructor[PROPERTIES]) {
403
+ constructor[PROPERTIES] = new Map();
404
+ }
405
+ constructor[PROPERTIES].set(propertyKey, options || {});
406
+ const descriptor = {
407
+ get() {
408
+ if (!this[PROPERTY_VALUES]) {
409
+ this[PROPERTY_VALUES] = {};
410
+ }
411
+ return this[PROPERTY_VALUES][propertyKey];
412
+ },
413
+ set(value) {
414
+ if (!this[PROPERTY_VALUES]) {
415
+ this[PROPERTY_VALUES] = {};
416
+ }
417
+ if (!this[EXPLICITLY_SET_PROPERTIES]) {
418
+ this[EXPLICITLY_SET_PROPERTIES] = new Set();
419
+ }
420
+ const oldValue = this[PROPERTY_VALUES][propertyKey];
421
+ // Don't update if value hasn't changed
422
+ if (oldValue === value)
423
+ return;
424
+ // Mark as explicitly set in these cases:
425
+ // 1. There was a previous value (normal property update)
426
+ // 2. This is during element construction and we have a non-null/non-undefined value
427
+ // (this handles default values declared in class properties)
428
+ const isInitialDefaultValue = oldValue === undefined && !this[PROPERTIES_INITIALIZED];
429
+ if (oldValue !== undefined || (isInitialDefaultValue && value !== null && value !== undefined)) {
430
+ this[EXPLICITLY_SET_PROPERTIES].add(propertyKey);
431
+ }
432
+ this[PROPERTY_VALUES][propertyKey] = value;
433
+ // Only reflect to attributes if:
434
+ // 1. Properties have been initialized from attributes
435
+ // 2. The property was explicitly set (not just default value)
436
+ // This prevents default values from creating attributes
437
+ if (options?.reflect && this.setAttribute && this[PROPERTIES_INITIALIZED] && this[EXPLICITLY_SET_PROPERTIES].has(propertyKey)) {
438
+ const attributeName = typeof options.attribute === 'string' ? options.attribute : propertyKey.toLowerCase();
439
+ if (value === null || value === undefined || value === false ||
440
+ (options?.type === SimpleArray && Array.isArray(value) && value.length === 0)) {
441
+ this.removeAttribute(attributeName);
442
+ }
443
+ else {
444
+ // Handle special types for reflection
445
+ let attributeValue;
446
+ if (value instanceof Date) {
447
+ attributeValue = value.toISOString();
448
+ }
449
+ else if (typeof value === 'bigint') {
450
+ attributeValue = value.toString() + 'n';
451
+ }
452
+ else if (options?.type === SimpleArray && Array.isArray(value)) {
453
+ attributeValue = SimpleArray.serialize(value);
454
+ }
455
+ else {
456
+ attributeValue = String(value);
457
+ }
458
+ this.setAttribute(attributeName, attributeValue);
459
+ }
460
+ }
461
+ // Call watchers for this property
462
+ const watchers = constructor[PROPERTY_WATCHERS];
463
+ if (watchers) {
464
+ // Call specific property watchers
465
+ if (watchers.has(propertyKey)) {
466
+ const propertyWatchers = watchers.get(propertyKey);
467
+ for (const watcher of propertyWatchers) {
468
+ try {
469
+ // Always pass oldValue, newValue, and propertyName
470
+ watcher.method.call(this, oldValue, value, propertyKey);
471
+ }
472
+ catch (error) {
473
+ console.error(`Error in @watch('${propertyKey}') method ${watcher.methodName}:`, error);
474
+ }
475
+ }
476
+ }
477
+ // Call wildcard watchers (watching "*")
478
+ if (watchers.has('*')) {
479
+ const wildcardWatchers = watchers.get('*');
480
+ for (const watcher of wildcardWatchers) {
481
+ try {
482
+ // Same signature for consistency
483
+ watcher.method.call(this, oldValue, value, propertyKey);
484
+ }
485
+ catch (error) {
486
+ console.error(`Error in @watch('*') method ${watcher.methodName}:`, error);
487
+ }
488
+ }
489
+ }
490
+ }
491
+ // Call requestUpdate if available and value changed
492
+ if (this.requestUpdate) {
493
+ this.requestUpdate(propertyKey, oldValue);
494
+ }
495
+ },
496
+ enumerable: true,
497
+ configurable: true,
498
+ };
499
+ Object.defineProperty(target, propertyKey, descriptor);
500
+ };
501
+ }
502
+ export function query(selector, options = {}) {
503
+ return function (target, propertyKey) {
504
+ // Default to shadow DOM only
505
+ const { light = false, shadow = true } = options;
506
+ Object.defineProperty(target, propertyKey, {
507
+ get() {
508
+ // Check if this is a controller using the symbol
509
+ const isController = this[IS_CONTROLLER_INSTANCE] === true;
510
+ const root = isController && this.element ? this.element : this;
511
+ // Query in specified contexts
512
+ let result = null;
513
+ if (shadow && root.shadowRoot) {
514
+ result = root.shadowRoot.querySelector(selector);
515
+ }
516
+ if (!result && light) {
517
+ result = root.querySelector(selector);
518
+ }
519
+ return result || null;
520
+ },
521
+ enumerable: true,
522
+ configurable: true,
523
+ });
524
+ };
525
+ }
526
+ export function queryAll(selector, options = {}) {
527
+ return function (target, propertyKey) {
528
+ // Default to shadow DOM only
529
+ const { light = false, shadow = true } = options;
530
+ Object.defineProperty(target, propertyKey, {
531
+ get() {
532
+ // Check if this is a controller using the symbol
533
+ const isController = this[IS_CONTROLLER_INSTANCE] === true;
534
+ const root = isController && this.element ? this.element : this;
535
+ // Query in specified contexts and combine results
536
+ const results = [];
537
+ if (shadow && root.shadowRoot) {
538
+ const shadowResults = root.shadowRoot.querySelectorAll(selector);
539
+ results.push(...shadowResults);
540
+ }
541
+ if (light) {
542
+ const lightResults = root.querySelectorAll(selector);
543
+ results.push(...lightResults);
544
+ }
545
+ // Return a static NodeList-like object
546
+ return results;
547
+ },
548
+ enumerable: true,
549
+ configurable: true,
550
+ });
551
+ };
552
+ }
553
+ /**
554
+ * SimpleArray type for arrays that can be safely reflected to attributes
555
+ * Supports arrays of: string, number, boolean
556
+ * Uses full-width comma (,) as separator to avoid conflicts
557
+ * Strings cannot contain the full-width comma character
558
+ */
559
+ export class SimpleArray {
560
+ /**
561
+ * Serialize array to string for attribute storage
562
+ */
563
+ static serialize(arr) {
564
+ if (!Array.isArray(arr))
565
+ return '';
566
+ return arr.map(item => {
567
+ if (typeof item === 'string') {
568
+ // Validate string doesn't contain our separator
569
+ if (item.includes(SimpleArray.SEPARATOR)) {
570
+ throw new Error(`SimpleArray strings cannot contain the character "${SimpleArray.SEPARATOR}" (U+FF0C)`);
571
+ }
572
+ return item;
573
+ }
574
+ else if (typeof item === 'number' || typeof item === 'boolean') {
575
+ return String(item);
576
+ }
577
+ else {
578
+ throw new Error(`SimpleArray only supports string, number, and boolean types. Got: ${typeof item}`);
579
+ }
580
+ }).join(SimpleArray.SEPARATOR);
581
+ }
582
+ /**
583
+ * Parse string from attribute back to array
584
+ */
585
+ static parse(str) {
586
+ if (str === null || str === undefined)
587
+ return [];
588
+ // Empty string should not be parsed as containing an empty string
589
+ // since empty arrays don't get reflected (handled by the reflection logic)
590
+ if (str === '')
591
+ return [];
592
+ return str.split(SimpleArray.SEPARATOR).map(item => {
593
+ // Try to parse as number
594
+ if (/^-?\d+\.?\d*$/.test(item)) {
595
+ const num = Number(item);
596
+ if (!isNaN(num))
597
+ return num;
598
+ }
599
+ // Parse as boolean
600
+ if (item === 'true')
601
+ return true;
602
+ if (item === 'false')
603
+ return false;
604
+ // Default to string
605
+ return item;
606
+ });
607
+ }
608
+ }
609
+ SimpleArray.SEPARATOR = ','; // U+FF0C Full-width comma
610
+ export function watch(...propertyNames) {
611
+ return function (target, methodName, descriptor) {
612
+ const constructor = target.constructor;
613
+ if (!constructor[PROPERTY_WATCHERS]) {
614
+ constructor[PROPERTY_WATCHERS] = new Map();
615
+ }
616
+ // Store the watcher method for each property
617
+ for (const propertyName of propertyNames) {
618
+ if (!constructor[PROPERTY_WATCHERS].has(propertyName)) {
619
+ constructor[PROPERTY_WATCHERS].set(propertyName, []);
620
+ }
621
+ constructor[PROPERTY_WATCHERS].get(propertyName).push({
622
+ methodName,
623
+ method: descriptor.value
624
+ });
625
+ }
626
+ return descriptor;
627
+ };
628
+ }
629
+ /**
630
+ * Decorator that injects router context into a property
631
+ * The context is automatically provided to page components by the router
632
+ */
633
+ export function context() {
634
+ return function (target, propertyKey) {
635
+ // Define property getter that returns the context
636
+ Object.defineProperty(target, propertyKey, {
637
+ get() {
638
+ // First check if context is stored directly on this element
639
+ if (this[ROUTER_CONTEXT] !== undefined) {
640
+ return this[ROUTER_CONTEXT];
641
+ }
642
+ // Otherwise, request context from parent page via event
643
+ const detail = { target: this };
644
+ const event = new CustomEvent('@context/request', {
645
+ bubbles: true,
646
+ cancelable: true,
647
+ detail
648
+ });
649
+ // Dispatch event and wait for response
650
+ // Check if this is a controller using the symbol
651
+ const isController = this[IS_CONTROLLER_INSTANCE] === true;
652
+ let targetElement = isController && this.element ? this.element : this;
653
+ // If element is null (e.g., controller was detached), can't get context
654
+ if (!targetElement || !targetElement.dispatchEvent) {
655
+ return undefined;
656
+ }
657
+ // If we're in shadow DOM, dispatch on the host element to ensure proper bubbling
658
+ if (targetElement.getRootNode && targetElement.getRootNode() instanceof ShadowRoot) {
659
+ const shadowRoot = targetElement.getRootNode();
660
+ targetElement = shadowRoot.host;
661
+ }
662
+ targetElement.dispatchEvent(event);
663
+ // Check if context was provided via the event
664
+ if (detail.context !== undefined) {
665
+ // Cache it for future use
666
+ this[ROUTER_CONTEXT] = detail.context;
667
+ return detail.context;
668
+ }
669
+ return undefined;
670
+ },
671
+ enumerable: true,
672
+ configurable: true
673
+ });
674
+ };
675
+ }
676
+ /**
677
+ * Decorator for methods that should run when element is ready
678
+ * Runs after shadow DOM, controller attachment, and event setup
679
+ * Supports async methods
680
+ */
681
+ export function ready() {
682
+ return function (target, methodName, descriptor) {
683
+ const constructor = target.constructor;
684
+ if (!constructor[READY_HANDLERS]) {
685
+ constructor[READY_HANDLERS] = [];
686
+ }
687
+ constructor[READY_HANDLERS].push({
688
+ methodName,
689
+ method: descriptor.value
690
+ });
691
+ return descriptor;
692
+ };
693
+ }
694
+ /**
695
+ * Decorator for methods that should run when element is being disposed
696
+ * Used for cleanup tasks when element is removed from DOM
697
+ */
698
+ export function dispose() {
699
+ return function (target, methodName, descriptor) {
700
+ const constructor = target.constructor;
701
+ if (!constructor[DISPOSE_HANDLERS]) {
702
+ constructor[DISPOSE_HANDLERS] = [];
703
+ }
704
+ constructor[DISPOSE_HANDLERS].push({
705
+ methodName,
706
+ method: descriptor.value
707
+ });
708
+ return descriptor;
709
+ };
710
+ }
711
+ /**
712
+ * Decorator for methods that render specific parts of the template
713
+ * Parts are identified by the 'part' attribute in the HTML template
714
+ * When the decorated method is called, it automatically re-renders its part
715
+ */
716
+ export function part(partName, options = {}) {
717
+ return function (target, methodName, descriptor) {
718
+ const constructor = target.constructor;
719
+ // Handle case where descriptor might be undefined (TypeScript experimental decorators)
720
+ if (!descriptor) {
721
+ descriptor = Object.getOwnPropertyDescriptor(target, methodName) || {
722
+ value: target[methodName],
723
+ writable: true,
724
+ enumerable: true,
725
+ configurable: true
726
+ };
727
+ }
728
+ const originalMethod = descriptor.value;
729
+ if (!constructor[PARTS]) {
730
+ constructor[PARTS] = new Map();
731
+ }
732
+ constructor[PARTS].set(partName, {
733
+ methodName,
734
+ method: originalMethod
735
+ });
736
+ // Wrap the original method to automatically re-render the part when called
737
+ descriptor.value = async function (...args) {
738
+ // Initialize timers storage if not present
739
+ if (!this[PART_TIMERS]) {
740
+ this[PART_TIMERS] = new Map();
741
+ }
742
+ // Get or create timers for this specific part
743
+ if (!this[PART_TIMERS].has(partName)) {
744
+ this[PART_TIMERS].set(partName, {
745
+ throttleTimer: null,
746
+ debounceTimer: null,
747
+ lastThrottleCall: 0
748
+ });
749
+ }
750
+ const timers = this[PART_TIMERS].get(partName);
751
+ // Create the render function
752
+ const renderPart = async () => {
753
+ // Call the original method to get the content
754
+ const result = originalMethod.apply(this, args);
755
+ const content = result instanceof Promise ? await result : result;
756
+ // Re-render the part if shadow DOM exists and content is defined
757
+ if (this.shadowRoot && content !== undefined) {
758
+ const partElement = this.shadowRoot.querySelector(`[part="${partName}"]`);
759
+ if (partElement) {
760
+ partElement.innerHTML = content;
761
+ }
762
+ }
763
+ return content;
764
+ };
765
+ // Handle debounce (only if positive value)
766
+ if (options.debounce !== undefined && options.debounce > 0) {
767
+ if (timers.debounceTimer) {
768
+ clearTimeout(timers.debounceTimer);
769
+ }
770
+ return new Promise((resolve) => {
771
+ timers.debounceTimer = setTimeout(async () => {
772
+ const result = await renderPart();
773
+ resolve(result);
774
+ }, options.debounce);
775
+ });
776
+ }
777
+ // Handle throttle (only if positive value)
778
+ if (options.throttle !== undefined && options.throttle > 0) {
779
+ const now = Date.now();
780
+ if (timers.lastThrottleCall === 0 || now - timers.lastThrottleCall >= options.throttle) {
781
+ timers.lastThrottleCall = now;
782
+ return await renderPart();
783
+ }
784
+ else {
785
+ // If throttled, schedule the next call if not already scheduled
786
+ if (!timers.throttleTimer) {
787
+ const remainingTime = options.throttle - (now - timers.lastThrottleCall);
788
+ timers.throttleTimer = setTimeout(async () => {
789
+ timers.throttleTimer = null;
790
+ timers.lastThrottleCall = Date.now();
791
+ await renderPart();
792
+ }, remainingTime);
793
+ }
794
+ // For throttled calls, don't execute the original method, just return undefined
795
+ // The actual render will happen in the scheduled timeout
796
+ return undefined;
797
+ }
798
+ }
799
+ // No throttle/debounce - render immediately
800
+ return await renderPart();
801
+ };
802
+ return descriptor;
803
+ };
804
+ }
805
+ //# sourceMappingURL=element.js.map