@supersoniks/concorde 4.9.98-visual-stack.1 → 4.9.98-visual-stack.3

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 (340) hide show
  1. package/.gitlab-ci.yml +0 -13
  2. package/build-infos.json +1 -1
  3. package/concorde-3d.bundle.js +1 -1
  4. package/concorde-3d.es.js +2 -2
  5. package/concorde-core.bundle.js +557 -622
  6. package/concorde-core.es.js +6025 -5575
  7. package/concorde-hugging-face-infer.bundle.js +1 -1
  8. package/concorde-hugging-face-infer.es.js +1 -1
  9. package/concorde-interactive.bundle.js +1162 -0
  10. package/concorde-interactive.es.js +10723 -0
  11. package/concorde-shader.bundle.js +1 -1
  12. package/concorde-shader.es.js +2 -2
  13. package/concorde-webgpu.bundle.js +1 -1
  14. package/concorde-webgpu.es.js +2 -2
  15. package/dist/concorde-3d.bundle.js +1 -1
  16. package/dist/concorde-3d.es.js +2 -2
  17. package/dist/concorde-core.bundle.js +557 -622
  18. package/dist/concorde-core.es.js +6025 -5575
  19. package/dist/concorde-hugging-face-infer.bundle.js +1 -1
  20. package/dist/concorde-hugging-face-infer.es.js +1 -1
  21. package/dist/concorde-interactive.bundle.js +1162 -0
  22. package/dist/concorde-interactive.es.js +10723 -0
  23. package/dist/concorde-shader.bundle.js +1 -1
  24. package/dist/concorde-shader.es.js +2 -2
  25. package/dist/concorde-webgpu.bundle.js +1 -1
  26. package/dist/concorde-webgpu.es.js +2 -2
  27. package/dist/docs-mock-api-sw.js +5 -1
  28. package/dist/docs-mock-api-sw.js.map +2 -2
  29. package/dist/js/addons/interactive.js +6 -0
  30. package/dist/js/addons/interactive.js.map +1 -0
  31. package/dist/js/core/components/functional/if/if.js +65 -7
  32. package/dist/js/core/components/functional/if/if.js.map +1 -1
  33. package/dist/js/core/components/functional/interactive/action.js +96 -0
  34. package/dist/js/core/components/functional/interactive/action.js.map +1 -0
  35. package/dist/js/core/components/functional/interactive/gamepad.js +206 -0
  36. package/dist/js/core/components/functional/interactive/gamepad.js.map +1 -0
  37. package/dist/js/core/components/functional/interactive/gesture.js +148 -0
  38. package/dist/js/core/components/functional/interactive/gesture.js.map +1 -0
  39. package/dist/js/core/components/functional/interactive/helpers.js +82 -0
  40. package/dist/js/core/components/functional/interactive/helpers.js.map +1 -0
  41. package/dist/js/core/components/functional/interactive/index.js +20 -0
  42. package/dist/js/core/components/functional/interactive/index.js.map +1 -0
  43. package/dist/js/core/components/functional/interactive/keyboard.js +183 -0
  44. package/dist/js/core/components/functional/interactive/keyboard.js.map +1 -0
  45. package/dist/js/core/components/functional/interactive/matrix.js +201 -0
  46. package/dist/js/core/components/functional/interactive/matrix.js.map +1 -0
  47. package/dist/js/core/components/functional/interactive/registry.js +28 -0
  48. package/dist/js/core/components/functional/interactive/registry.js.map +1 -0
  49. package/dist/js/core/components/functional/interactive/store.js +264 -0
  50. package/dist/js/core/components/functional/interactive/store.js.map +1 -0
  51. package/dist/js/core/components/functional/interactive/ticker.js +182 -0
  52. package/dist/js/core/components/functional/interactive/ticker.js.map +1 -0
  53. package/dist/js/core/components/functional/value/value.js +49 -4
  54. package/dist/js/core/components/functional/value/value.js.map +1 -1
  55. package/dist/js/core/components/ui/_css/rounded.js +34 -0
  56. package/dist/js/core/components/ui/_css/rounded.js.map +1 -0
  57. package/dist/js/core/components/ui/_css/type.js +44 -0
  58. package/dist/js/core/components/ui/_css/type.js.map +1 -1
  59. package/dist/js/core/components/ui/_i18n/ui-aria-labels.js +95 -0
  60. package/dist/js/core/components/ui/_i18n/ui-aria-labels.js.map +1 -0
  61. package/dist/js/core/components/ui/alert/alert.js +72 -87
  62. package/dist/js/core/components/ui/alert/alert.js.map +1 -1
  63. package/dist/js/core/components/ui/alert-messages/alert-messages.js +1 -0
  64. package/dist/js/core/components/ui/alert-messages/alert-messages.js.map +1 -1
  65. package/dist/js/core/components/ui/badge/badge.js +29 -80
  66. package/dist/js/core/components/ui/badge/badge.js.map +1 -1
  67. package/dist/js/core/components/ui/button/button.js +8 -7
  68. package/dist/js/core/components/ui/button/button.js.map +1 -1
  69. package/dist/js/core/components/ui/card/card-header.js +7 -2
  70. package/dist/js/core/components/ui/card/card-header.js.map +1 -1
  71. package/dist/js/core/components/ui/divider/divider.js +1 -1
  72. package/dist/js/core/components/ui/divider/divider.js.map +1 -1
  73. package/dist/js/core/components/ui/form/checkbox/checkbox.js +4 -20
  74. package/dist/js/core/components/ui/form/checkbox/checkbox.js.map +1 -1
  75. package/dist/js/core/components/ui/form/fieldset/legend-description.js +1 -1
  76. package/dist/js/core/components/ui/form/fieldset/legend.js +1 -1
  77. package/dist/js/core/components/ui/form/input/input.js +12 -15
  78. package/dist/js/core/components/ui/form/input/input.js.map +1 -1
  79. package/dist/js/core/components/ui/form/input-autocomplete/input-autocomplete.js +363 -158
  80. package/dist/js/core/components/ui/form/input-autocomplete/input-autocomplete.js.map +1 -1
  81. package/dist/js/core/components/ui/form/radio/radio.js +1 -1
  82. package/dist/js/core/components/ui/form/select/select.js +3 -6
  83. package/dist/js/core/components/ui/form/select/select.js.map +1 -1
  84. package/dist/js/core/components/ui/form/textarea/textarea.js +1 -2
  85. package/dist/js/core/components/ui/form/textarea/textarea.js.map +1 -1
  86. package/dist/js/core/components/ui/image/image.js +9 -37
  87. package/dist/js/core/components/ui/image/image.js.map +1 -1
  88. package/dist/js/core/components/ui/link/link.js +25 -26
  89. package/dist/js/core/components/ui/link/link.js.map +1 -1
  90. package/dist/js/core/components/ui/modal/modal-close.js +3 -12
  91. package/dist/js/core/components/ui/modal/modal-close.js.map +1 -1
  92. package/dist/js/core/components/ui/modal/modal.js +18 -18
  93. package/dist/js/core/components/ui/modal/modal.js.map +1 -1
  94. package/dist/js/core/components/ui/pop/pop.js +131 -112
  95. package/dist/js/core/components/ui/pop/pop.js.map +1 -1
  96. package/dist/js/core/components/ui/table/table.js.map +1 -1
  97. package/dist/js/core/components/ui/theme/theme.js +1 -1
  98. package/dist/js/core/components/ui/toast/dismissed.js +9 -0
  99. package/dist/js/core/components/ui/toast/dismissed.js.map +1 -0
  100. package/dist/js/core/components/ui/toast/render-content.js +14 -0
  101. package/dist/js/core/components/ui/toast/render-content.js.map +1 -0
  102. package/dist/js/core/components/ui/toast/toast-item.js +150 -96
  103. package/dist/js/core/components/ui/toast/toast-item.js.map +1 -1
  104. package/dist/js/core/components/ui/toast/toast.js +41 -13
  105. package/dist/js/core/components/ui/toast/toast.js.map +1 -1
  106. package/dist/js/core/components/ui/tooltip/tooltip.js +144 -143
  107. package/dist/js/core/components/ui/tooltip/tooltip.js.map +1 -1
  108. package/dist/js/core/decorators/subscriber/ancestorAttribute.js.map +1 -1
  109. package/dist/js/core/decorators/subscriber/derive.js +3 -1
  110. package/dist/js/core/decorators/subscriber/derive.js.map +1 -1
  111. package/dist/js/core/mixins/Fetcher.js.map +1 -1
  112. package/dist/js/core/mixins/FormCheckable.js +1 -8
  113. package/dist/js/core/mixins/FormCheckable.js.map +1 -1
  114. package/dist/js/core/mixins/FormElement.js +26 -53
  115. package/dist/js/core/mixins/FormElement.js.map +1 -1
  116. package/dist/js/core/utils/AncestorAttributeObserver.js +130 -55
  117. package/dist/js/core/utils/AncestorAttributeObserver.js.map +1 -1
  118. package/dist/js/core/utils/LocationHandler.js +1 -1
  119. package/dist/js/core/utils/LocationHandler.js.map +1 -1
  120. package/dist/js/core/utils/dismissed.js +23 -0
  121. package/dist/js/core/utils/dismissed.js.map +1 -0
  122. package/dist/js/core/utils/positioning.js +110 -0
  123. package/dist/js/core/utils/positioning.js.map +1 -0
  124. package/dist/js/directives.js +1 -2
  125. package/dist/js/directives.js.map +1 -1
  126. package/dist/types/addons/interactive.d.ts +6 -0
  127. package/dist/types/addons/interactive.d.ts.map +1 -0
  128. package/dist/types/core/components/functional/if/if.d.ts +14 -5
  129. package/dist/types/core/components/functional/if/if.d.ts.map +1 -1
  130. package/dist/types/core/components/functional/interactive/action.d.ts +22 -0
  131. package/dist/types/core/components/functional/interactive/action.d.ts.map +1 -0
  132. package/dist/types/core/components/functional/interactive/gamepad.d.ts +37 -0
  133. package/dist/types/core/components/functional/interactive/gamepad.d.ts.map +1 -0
  134. package/dist/types/core/components/functional/interactive/gesture.d.ts +26 -0
  135. package/dist/types/core/components/functional/interactive/gesture.d.ts.map +1 -0
  136. package/dist/types/core/components/functional/interactive/helpers.d.ts +23 -0
  137. package/dist/types/core/components/functional/interactive/helpers.d.ts.map +1 -0
  138. package/dist/types/core/components/functional/interactive/index.d.ts +20 -0
  139. package/dist/types/core/components/functional/interactive/index.d.ts.map +1 -0
  140. package/dist/types/core/components/functional/interactive/keyboard.d.ts +37 -0
  141. package/dist/types/core/components/functional/interactive/keyboard.d.ts.map +1 -0
  142. package/dist/types/core/components/functional/interactive/matrix.d.ts +31 -0
  143. package/dist/types/core/components/functional/interactive/matrix.d.ts.map +1 -0
  144. package/dist/types/core/components/functional/interactive/registry.d.ts +23 -0
  145. package/dist/types/core/components/functional/interactive/registry.d.ts.map +1 -0
  146. package/dist/types/core/components/functional/interactive/store.d.ts +46 -0
  147. package/dist/types/core/components/functional/interactive/store.d.ts.map +1 -0
  148. package/dist/types/core/components/functional/interactive/ticker.d.ts +33 -0
  149. package/dist/types/core/components/functional/interactive/ticker.d.ts.map +1 -0
  150. package/dist/types/core/components/functional/value/value.d.ts +6 -0
  151. package/dist/types/core/components/functional/value/value.d.ts.map +1 -1
  152. package/dist/types/core/components/ui/_css/rounded.d.ts +3 -0
  153. package/dist/types/core/components/ui/_css/rounded.d.ts.map +1 -0
  154. package/dist/types/core/components/ui/_css/type.d.ts +13 -0
  155. package/dist/types/core/components/ui/_css/type.d.ts.map +1 -1
  156. package/dist/types/core/components/ui/_i18n/ui-aria-labels.d.ts +83 -0
  157. package/dist/types/core/components/ui/_i18n/ui-aria-labels.d.ts.map +1 -0
  158. package/dist/types/core/components/ui/alert/alert.d.ts +14 -12
  159. package/dist/types/core/components/ui/alert/alert.d.ts.map +1 -1
  160. package/dist/types/core/components/ui/alert-messages/alert-messages.d.ts.map +1 -1
  161. package/dist/types/core/components/ui/badge/badge.d.ts +1 -1
  162. package/dist/types/core/components/ui/badge/badge.d.ts.map +1 -1
  163. package/dist/types/core/components/ui/button/button.d.ts +13 -29
  164. package/dist/types/core/components/ui/button/button.d.ts.map +1 -1
  165. package/dist/types/core/components/ui/card/card-header.d.ts.map +1 -1
  166. package/dist/types/core/components/ui/divider/divider.d.ts +2 -1
  167. package/dist/types/core/components/ui/divider/divider.d.ts.map +1 -1
  168. package/dist/types/core/components/ui/form/checkbox/checkbox.d.ts +25 -73
  169. package/dist/types/core/components/ui/form/checkbox/checkbox.d.ts.map +1 -1
  170. package/dist/types/core/components/ui/form/input/input.d.ts +14 -29
  171. package/dist/types/core/components/ui/form/input/input.d.ts.map +1 -1
  172. package/dist/types/core/components/ui/form/input-autocomplete/input-autocomplete.d.ts +63 -65
  173. package/dist/types/core/components/ui/form/input-autocomplete/input-autocomplete.d.ts.map +1 -1
  174. package/dist/types/core/components/ui/form/radio/radio.d.ts +1 -1
  175. package/dist/types/core/components/ui/form/select/select.d.ts +3 -5
  176. package/dist/types/core/components/ui/form/select/select.d.ts.map +1 -1
  177. package/dist/types/core/components/ui/form/textarea/textarea.d.ts +12 -28
  178. package/dist/types/core/components/ui/form/textarea/textarea.d.ts.map +1 -1
  179. package/dist/types/core/components/ui/image/image.d.ts +2 -1
  180. package/dist/types/core/components/ui/image/image.d.ts.map +1 -1
  181. package/dist/types/core/components/ui/link/link.d.ts +10 -9
  182. package/dist/types/core/components/ui/link/link.d.ts.map +1 -1
  183. package/dist/types/core/components/ui/modal/modal-close.d.ts +2 -2
  184. package/dist/types/core/components/ui/modal/modal-close.d.ts.map +1 -1
  185. package/dist/types/core/components/ui/pop/pop.d.ts +12 -4
  186. package/dist/types/core/components/ui/pop/pop.d.ts.map +1 -1
  187. package/dist/types/core/components/ui/table/table.d.ts +2 -1
  188. package/dist/types/core/components/ui/table/table.d.ts.map +1 -1
  189. package/dist/types/core/components/ui/toast/dismissed.d.ts +3 -0
  190. package/dist/types/core/components/ui/toast/dismissed.d.ts.map +1 -0
  191. package/dist/types/core/components/ui/toast/render-content.d.ts +7 -0
  192. package/dist/types/core/components/ui/toast/render-content.d.ts.map +1 -0
  193. package/dist/types/core/components/ui/toast/toast-item.d.ts +26 -9
  194. package/dist/types/core/components/ui/toast/toast-item.d.ts.map +1 -1
  195. package/dist/types/core/components/ui/toast/toast.d.ts +6 -3
  196. package/dist/types/core/components/ui/toast/toast.d.ts.map +1 -1
  197. package/dist/types/core/components/ui/toast/types.d.ts +12 -2
  198. package/dist/types/core/components/ui/toast/types.d.ts.map +1 -1
  199. package/dist/types/core/components/ui/tooltip/tooltip.d.ts +19 -11
  200. package/dist/types/core/components/ui/tooltip/tooltip.d.ts.map +1 -1
  201. package/dist/types/core/decorators/subscriber/ancestorAttribute.d.ts +3 -4
  202. package/dist/types/core/decorators/subscriber/ancestorAttribute.d.ts.map +1 -1
  203. package/dist/types/core/decorators/subscriber/derive.d.ts.map +1 -1
  204. package/dist/types/core/mixins/FormCheckable.d.ts +10 -27
  205. package/dist/types/core/mixins/FormCheckable.d.ts.map +1 -1
  206. package/dist/types/core/mixins/FormElement.d.ts +21 -10
  207. package/dist/types/core/mixins/FormElement.d.ts.map +1 -1
  208. package/dist/types/core/mixins/FormInput.d.ts +11 -27
  209. package/dist/types/core/mixins/FormInput.d.ts.map +1 -1
  210. package/dist/types/core/utils/AncestorAttributeObserver.d.ts +17 -9
  211. package/dist/types/core/utils/AncestorAttributeObserver.d.ts.map +1 -1
  212. package/dist/types/core/utils/LocationHandler.d.ts +3 -2
  213. package/dist/types/core/utils/LocationHandler.d.ts.map +1 -1
  214. package/dist/types/core/utils/dismissed.d.ts +3 -0
  215. package/dist/types/core/utils/dismissed.d.ts.map +1 -0
  216. package/dist/types/core/utils/positioning.d.ts +44 -0
  217. package/dist/types/core/utils/positioning.d.ts.map +1 -0
  218. package/dist/types/directives.d.ts +1 -3
  219. package/dist/types/directives.d.ts.map +1 -1
  220. package/dist/types/mixins.d.ts +22 -55
  221. package/dist/types/mixins.d.ts.map +1 -1
  222. package/docs/assets/{index-FmK4JaIM.js → index-D8MVWqY6.js} +946 -687
  223. package/docs/assets/index-DiD0qYvE.css +1 -0
  224. package/docs/crawl/core/components/ui/form/input-autocomplete/input-autocomplete.html +17 -85
  225. package/docs/crawl/docs/_misc/formelement-subscriber-removal.html +1 -1
  226. package/docs/crawl/hubs/form-components.html +13 -11
  227. package/docs/docs-mock-api-sw.js +5 -1
  228. package/docs/docs-mock-api-sw.js.map +2 -2
  229. package/docs/index.html +2 -2
  230. package/docs/llms-full.txt +12 -38
  231. package/docs/llms.txt +1 -1
  232. package/docs/src/core/components/functional/sdui/sdui.md +0 -0
  233. package/docs/src/core/components/ui/form/checkbox/checkbox.md +0 -0
  234. package/docs/src/core/components/ui/form/input-autocomplete/input-autocomplete.md +14 -118
  235. package/docs/src/docs/_getting-started/create-a-component.md +0 -0
  236. package/docs/src/docs/_misc/formelement-subscriber-removal.md +1 -1
  237. package/docs/src/docs/search/docs-search.json +195 -200
  238. package/docs/src/tsconfig.json +324 -0
  239. package/gitlab/job_tests.sh +25 -12
  240. package/index.html +3 -3
  241. package/package.json +182 -10
  242. package/public/docs-mock-api-sw.js +5 -1
  243. package/public/docs-mock-api-sw.js.map +2 -2
  244. package/scripts/build-addons.mjs +2 -2
  245. package/scripts/post-build.mjs +9 -0
  246. package/src/addons/interactive.ts +5 -0
  247. package/src/core/components/functional/if/if.ts +54 -7
  248. package/src/core/components/functional/interactive/action.ts +84 -0
  249. package/src/core/components/functional/interactive/gamepad.ts +197 -0
  250. package/src/core/components/functional/interactive/gesture.ts +136 -0
  251. package/src/core/components/functional/interactive/helpers.spec.ts +50 -0
  252. package/src/core/components/functional/interactive/helpers.ts +97 -0
  253. package/src/core/components/functional/interactive/index.ts +25 -0
  254. package/src/core/components/functional/interactive/interactive.md +33 -0
  255. package/src/core/components/functional/interactive/keyboard.ts +171 -0
  256. package/src/core/components/functional/interactive/matrix.ts +185 -0
  257. package/src/core/components/functional/interactive/registry.ts +46 -0
  258. package/src/core/components/functional/interactive/store.ts +270 -0
  259. package/src/core/components/functional/interactive/ticker.ts +171 -0
  260. package/src/core/components/functional/list/list.ts +0 -0
  261. package/src/core/components/functional/subscriber/subscriber.ts +0 -0
  262. package/src/core/components/functional/value/value.ts +44 -4
  263. package/src/core/components/ui/_css/rounded.ts +36 -0
  264. package/src/core/components/ui/_css/type.ts +49 -0
  265. package/src/core/components/ui/_i18n/ui-aria-labels.ts +104 -0
  266. package/src/core/components/ui/alert/alert.md +128 -72
  267. package/src/core/components/ui/alert/alert.spec.ts +145 -0
  268. package/src/core/components/ui/alert/alert.ts +86 -91
  269. package/src/core/components/ui/alert-messages/alert-messages.ts +1 -1
  270. package/src/core/components/ui/badge/badge.md +126 -78
  271. package/src/core/components/ui/badge/badge.ts +29 -81
  272. package/src/core/components/ui/button/button.md +1 -0
  273. package/src/core/components/ui/button/button.ts +12 -10
  274. package/src/core/components/ui/card/card-header.ts +7 -2
  275. package/src/core/components/ui/card/card.md +120 -65
  276. package/src/core/components/ui/divider/divider.ts +4 -9
  277. package/src/core/components/ui/form/checkbox/checkbox.md +1 -1
  278. package/src/core/components/ui/form/checkbox/checkbox.ts +4 -20
  279. package/src/core/components/ui/form/fieldset/legend-description.ts +1 -1
  280. package/src/core/components/ui/form/fieldset/legend.ts +1 -1
  281. package/src/core/components/ui/form/input/input.md +1 -1
  282. package/src/core/components/ui/form/input/input.ts +25 -27
  283. package/src/core/components/ui/form/input-autocomplete/input-autocomplete.md +14 -118
  284. package/src/core/components/ui/form/input-autocomplete/input-autocomplete.ts +419 -187
  285. package/src/core/components/ui/form/radio/radio.ts +1 -1
  286. package/src/core/components/ui/form/select/select.ts +3 -6
  287. package/src/core/components/ui/form/textarea/textarea.md +1 -1
  288. package/src/core/components/ui/form/textarea/textarea.ts +1 -2
  289. package/src/core/components/ui/image/image.md +147 -53
  290. package/src/core/components/ui/image/image.ts +10 -44
  291. package/src/core/components/ui/link/link.md +2 -2
  292. package/src/core/components/ui/link/link.ts +42 -37
  293. package/src/core/components/ui/modal/modal-close.ts +8 -12
  294. package/src/core/components/ui/modal/modal.ts +18 -18
  295. package/src/core/components/ui/pop/pop.md +105 -1
  296. package/src/core/components/ui/pop/pop.ts +145 -141
  297. package/src/core/components/ui/table/table.ts +2 -8
  298. package/src/core/components/ui/theme/theme.ts +1 -1
  299. package/src/core/components/ui/toast/dismissed.ts +14 -0
  300. package/src/core/components/ui/toast/render-content.ts +13 -0
  301. package/src/core/components/ui/toast/toast-item.ts +179 -103
  302. package/src/core/components/ui/toast/toast.ts +58 -21
  303. package/src/core/components/ui/toast/types.ts +14 -2
  304. package/src/core/components/ui/tooltip/tooltip.ts +176 -154
  305. package/src/core/decorators/subscriber/ancestorAttribute.spec.ts +26 -0
  306. package/src/core/decorators/subscriber/ancestorAttribute.ts +3 -4
  307. package/src/core/decorators/subscriber/derive.ts +3 -3
  308. package/src/core/mixins/Fetcher.ts +1 -1
  309. package/src/core/mixins/FormCheckable.ts +1 -8
  310. package/src/core/mixins/FormElement.ts +74 -76
  311. package/src/core/mixins/Subscriber.ts +5 -1
  312. package/src/core/utils/AncestorAttributeObserver.ts +183 -70
  313. package/src/core/utils/DataBindObserver.ts +0 -0
  314. package/src/core/utils/LocationHandler.ts +12 -5
  315. package/src/core/utils/Objects.ts +0 -0
  316. package/src/core/utils/dismissed.ts +22 -0
  317. package/src/core/utils/positioning.spec.ts +208 -0
  318. package/src/core/utils/positioning.ts +183 -0
  319. package/src/directives.ts +1 -3
  320. package/src/docs/_core-concept/dataFlow.md +1 -1
  321. package/src/docs/_decorators/ancestor-attribute.md +3 -2
  322. package/src/docs/_getting-started/cdn-addons.md +1 -0
  323. package/src/docs/_getting-started/concorde-outside.md +3 -3
  324. package/src/docs/_misc/formelement-subscriber-removal.md +115 -0
  325. package/src/docs/_misc/html-integration.md +2 -0
  326. package/src/docs/code.ts +3 -1
  327. package/src/docs/components/docs-demo-sources.ts +60 -0
  328. package/src/docs/docs.ts +1 -0
  329. package/src/docs/example/docs-input-autocomplete-demos.ts +110 -0
  330. package/src/docs/mock-api/router.ts +17 -1
  331. package/src/docs/navigation/navigation.ts +8 -0
  332. package/src/docs/search/docs-search.json +956 -243
  333. package/src/docs/tailwind/css/tailwind.css +13 -6
  334. package/src/tsconfig.json +135 -6
  335. package/src/tsconfig.tsbuildinfo +1 -1
  336. package/tailwind.config.js +50 -3
  337. package/vite/config.js +23 -35
  338. package/vite.config.mts +5 -0
  339. package/vitest.setup.ts +49 -13
  340. package/docs/assets/index-BZiZXMU-.css +0 -1
@@ -1,55 +1,73 @@
1
1
  import { PublisherManager } from "@supersoniks/concorde/core/utils/PublisherProxy";
2
2
  import { property } from "lit/decorators.js";
3
- import { SubscriberInterface } from "@supersoniks/concorde/core/mixins/Subscriber";
4
3
  import Objects from "@supersoniks/concorde/core/utils/Objects";
5
4
  import { traverseDotNotation } from "@supersoniks/concorde/core/utils/Objects";
5
+ import HTML from "@supersoniks/concorde/core/utils/HTML";
6
+ import { LitElement } from "lit";
6
7
  import {
7
8
  PublisherInterface,
8
9
  HTMLFormControl,
9
10
  CoreJSType,
11
+ MixinArgsType,
10
12
  } from "../_types/types";
11
- import { MixinArgsType } from "../_types/types";
13
+
12
14
  type Constructor<T> = new (...args: MixinArgsType[]) => T;
15
+
13
16
  export type FormElementValue = string | string[] | object | null | undefined;
14
- export interface FormElementInterface extends SubscriberInterface {
15
- getFormPublisher(): PublisherInterface;
17
+
18
+ export interface FormElementInterface {
19
+ getFormPublisher(): PublisherInterface | null;
16
20
  updateDataValue(): void;
17
21
  handleChange(e?: Event): void;
18
22
  handleBlur(e?: Event): void;
19
23
  getValueForFormPublisher(): FormElementValue;
20
- setValueFromPublisher(value: FormElementValue): void;
21
24
  setFormPublisherValue(value: FormElementValue): void;
22
25
  getFormPublisherValue(): FormElementValue;
26
+ setFormValueFromPublisher(value: FormElementValue): void;
23
27
  unsetOnDisconnect(): boolean;
24
28
  unset(): void;
25
-
26
29
  validateFormElement(): void;
27
30
  focus?: () => void;
28
31
  forceAutoFill: boolean;
29
- shadowRoot?: ShadowRoot;
32
+ shadowRoot: ShadowRoot | null;
30
33
  error: boolean;
31
34
  autofocus: boolean;
32
35
  required: boolean;
33
36
  disabled: boolean;
34
37
  formDataProvider: string;
35
- ariaLabelledby?: string;
36
- ariaLabel?: string;
38
+ ariaLabel: string | null;
39
+ ariaLabelledby: string | null;
37
40
  _value: FormElementValue;
38
41
  get value(): FormElementValue;
39
42
  set value(value: FormElementValue);
40
43
  _name: string;
41
44
  get name(): string;
42
45
  set name(value: string);
46
+ getAncestorAttributeValue(attributeName: string): string;
47
+ hasAncestorAttribute(attributeName: string): boolean;
48
+ isConnected: boolean;
49
+ requestUpdate(): void;
50
+ getAttribute(name: string): string | null;
51
+ hasAttribute(attributeName: string): boolean;
52
+ setAttribute(name: string, value: string): void;
53
+ removeAttribute(name: string): void;
54
+ addEventListener(
55
+ type: string,
56
+ listener: EventListenerOrEventListenerObject,
57
+ options?: boolean | AddEventListenerOptions
58
+ ): void;
59
+ dispatchEvent(event: Event): void;
60
+ connectedCallback(): void;
61
+ disconnectedCallback(): void;
43
62
  }
63
+
44
64
  const keyboardLoops = new Map<string, Array<FormElementInterface>>();
45
- const Form = <T extends Constructor<SubscriberInterface>>(superClass: T) => {
65
+
66
+ const Form = <T extends Constructor<LitElement>>(superClass: T) => {
46
67
  /**
47
- * ## FormElement est la mixin utilisée par les éléments de formulaire de concorde ainsi que par le composant sonic-button.
48
- * * La propriété value est remplie automatiquement a l'aide de l'attribut name renseigné, ceci en prenant la valeur de la propriété du même nom dans les données du dataprovider associé.
49
- * * Par défault lorsque l'on édite l'input, la valeur est également mise à jour via le même dataprovider
50
- * * On peut cependant décider de mettre à jour la donnée à une autre adresse en renseignent l'attribut *formDataProvider*.
51
- * * Par conséquent, on peut par exemple le lier à un composant *queue* (via sa propriété *dataFilterProvider*) de manière à appeller en auto une api avec des filtres.
52
- *
68
+ * ## FormElement — mixin des champs de formulaire Concorde (et sonic-button).
69
+ * Synchronise `value` avec `formDataProvider` + `name` uniquement
70
+ * (plus de canal `dataProvider` / mixin Subscriber).
53
71
  */
54
72
  class FormElement extends superClass implements FormElementInterface {
55
73
  @property({ type: Boolean, reflect: true }) touched = false;
@@ -61,19 +79,16 @@ const Form = <T extends Constructor<SubscriberInterface>>(superClass: T) => {
61
79
 
62
80
  /* Attribut data-aria-label pour passer aria-label */
63
81
  @property({ type: String, attribute: "data-aria-label" })
64
- ariaLabel?: string;
82
+ ariaLabel: string | null = null;
65
83
  @property({ type: String, attribute: "data-aria-labelledby" })
66
- ariaLabelledby?: string;
84
+ ariaLabelledby: string | null = null;
67
85
 
68
- onValueAssign?: (v: string) => void;
69
86
  onFormValueAssign?: (v: string) => void;
70
87
  onFormDataInValidate?: VoidFunction;
88
+
71
89
  constructor(...args: MixinArgsType[]) {
72
90
  super();
73
91
  args;
74
- this.onValueAssign = (value) => {
75
- this.setValueFromPublisher(value);
76
- };
77
92
  this.onFormValueAssign = async (value) => {
78
93
  this.setFormValueFromPublisher(value);
79
94
  };
@@ -85,24 +100,41 @@ const Form = <T extends Constructor<SubscriberInterface>>(superClass: T) => {
85
100
  this.validateFormElement();
86
101
  };
87
102
  }
103
+
104
+ @property({ type: String })
88
105
  formDataProvider = "";
89
106
 
90
- /**
91
- * Le nom du champ avec des caractéristiques similaire à un input html classique.
92
- */
107
+ hasAncestorAttribute(attributeName: string) {
108
+ return HTML.getAncestorAttributeValue(
109
+ this as unknown as HTMLElement,
110
+ attributeName
111
+ ) != null;
112
+ }
113
+
114
+ getAncestorAttributeValue(attributeName: string) {
115
+ return (
116
+ HTML.getAncestorAttributeValue(
117
+ this as unknown as HTMLElement,
118
+ attributeName
119
+ ) || ""
120
+ );
121
+ }
122
+
93
123
  _name = "";
94
124
  @property() get name(): string {
95
125
  return this._name;
96
126
  }
97
127
  set name(value: string) {
98
128
  if (this.hasAttribute("name") && !this.forceAutoFill)
99
- value = this.getAttribute("name");
129
+ value = this.getAttribute("name") as string;
100
130
  this._name = value;
101
131
  this.requestUpdate();
102
132
  }
133
+
103
134
  validateFormElement() {
104
- //Implémentation dans une sous classe
135
+ // Implémentation dans une sous-classe
105
136
  }
137
+
106
138
  unsetOnDisconnect() {
107
139
  return this.hasAttribute("unsetOnDisconnect");
108
140
  }
@@ -117,15 +149,15 @@ const Form = <T extends Constructor<SubscriberInterface>>(superClass: T) => {
117
149
  }
118
150
  }
119
151
  }
152
+
120
153
  getFormPublisher() {
121
154
  if (!this.formDataProvider)
122
155
  this.formDataProvider =
123
- this.getAncestorAttributeValue("formDataProvider");
156
+ this.getAncestorAttributeValue("formDataProvider") || "";
124
157
  if (this.formDataProvider) {
125
158
  return PublisherManager.get(this.formDataProvider);
126
159
  }
127
160
  return null;
128
- //else return this.publisher;
129
161
  }
130
162
 
131
163
  setFormPublisherValue(value: FormElementValue): void {
@@ -143,31 +175,14 @@ const Form = <T extends Constructor<SubscriberInterface>>(superClass: T) => {
143
175
  return null;
144
176
  }
145
177
 
146
- /**
147
- * Mise en forme de la valeur fournie au formPublisher associé au composant
148
- * Destinée à être surchargée si besoin (cf Form-checkable)
149
- */
150
178
  getValueForFormPublisher() {
151
179
  return this.value;
152
180
  }
153
- /**
154
- * Mise à jour de la valeur interne du composant en fonction de la valeur venant du publisher associé au composant
155
- * Destinée à être surchargée si besoin (cf Form-checkable)
156
- */
157
- setValueFromPublisher(value: FormElementValue) {
158
- this.value = value;
159
- }
160
181
 
161
- /**
162
- * Mise à jour de la valeur interne du composant en fonction de la valeur venant du formPublisher associé au composant
163
- * Destinée à être surchargée si besoin (cf Form-checkable)
164
- */
165
182
  setFormValueFromPublisher(value: FormElementValue) {
166
183
  this.value = value;
167
184
  }
168
- /**
169
- * La valeur du champ avec des caractéristiques similaire à un input html classique :
170
- */
185
+
171
186
  _value: FormElementValue = "";
172
187
  @property() get value() {
173
188
  return this._value;
@@ -188,7 +203,8 @@ const Form = <T extends Constructor<SubscriberInterface>>(superClass: T) => {
188
203
  this.updateDataValue();
189
204
  this.requestUpdate();
190
205
  }
191
- initPublisher() {
206
+
207
+ initFormPublisher() {
192
208
  let formPublisher = this.getFormPublisher();
193
209
  const value =
194
210
  this.hasAncestorAttribute("initFromPublisher") &&
@@ -196,22 +212,12 @@ const Form = <T extends Constructor<SubscriberInterface>>(superClass: T) => {
196
212
  this.getFormPublisherValue()
197
213
  ? this.getFormPublisherValue()
198
214
  : this.getAttribute("value");
199
- if (this._name && this.publisher)
200
- traverseDotNotation(this.publisher, this._name).offAssign(
201
- this.onValueAssign
202
- );
203
215
  if (this._name && formPublisher)
204
216
  traverseDotNotation(formPublisher, this._name).offAssign(
205
217
  this.onFormValueAssign
206
218
  );
207
- super.initPublisher();
208
- if (!this.name) this._name = this.getAttribute("name");
219
+ if (!this.name) this._name = this.getAttribute("name") || "";
209
220
  if (!this.value) this._value = this.getAttribute("value");
210
- if (this.publisher && this._name) {
211
- traverseDotNotation(this.publisher, this._name).onAssign(
212
- this.onValueAssign
213
- );
214
- }
215
221
  formPublisher = this.getFormPublisher();
216
222
  if (this._name && formPublisher) {
217
223
  traverseDotNotation(formPublisher, this._name).onAssign(
@@ -225,7 +231,6 @@ const Form = <T extends Constructor<SubscriberInterface>>(superClass: T) => {
225
231
 
226
232
  handleBlur() {
227
233
  this.touched = true;
228
- // this.validateFormElement();
229
234
  }
230
235
 
231
236
  handleChange(e: Event) {
@@ -233,16 +238,10 @@ const Form = <T extends Constructor<SubscriberInterface>>(superClass: T) => {
233
238
  const event = new Event("change");
234
239
  this.dispatchEvent(event);
235
240
  }
236
- /**
237
- * Ajoute un comportement de navigation au clavier pour les éléments de formulaire
238
- * data-keyboard-nav peut contenir plusieurs valeurs qui identifient les boucles de navigation auquelles est attaché cet élément.
239
- * Les valeurs sont séparées par des espaces.
240
- * En appuyant sur la touche "Down", le composant va se déplacer dans la boucle de navigation correspondante en suivant le flux.
241
- * En appuyant sur la touche "Up", le déplacement inverse est effectué.
242
- */
241
+
243
242
  addKeyboardNavigation() {
244
243
  const keyboardLoopIds: string =
245
- this.getAncestorAttributeValue("data-keyboard-nav");
244
+ this.getAncestorAttributeValue("data-keyboard-nav") || "";
246
245
  if (!keyboardLoopIds) return;
247
246
 
248
247
  const split = keyboardLoopIds.split(" ");
@@ -277,7 +276,7 @@ const Form = <T extends Constructor<SubscriberInterface>>(superClass: T) => {
277
276
  );
278
277
  });
279
278
 
280
- let next: SubscriberInterface | null = null;
279
+ let next: FormElementInterface | null = null;
281
280
  if (keyboardEvent.key == "ArrowDown" && loop) {
282
281
  const index = loop.indexOf(this);
283
282
  if (index == loop.length - 1) {
@@ -317,13 +316,16 @@ const Form = <T extends Constructor<SubscriberInterface>>(superClass: T) => {
317
316
  }
318
317
 
319
318
  connectedCallback(): void {
320
- this.formDataProvider = this.getAncestorAttributeValue(
321
- "formDataProvider"
322
- ) as string;
319
+ if (!this.formDataProvider) {
320
+ this.formDataProvider =
321
+ this.getAncestorAttributeValue("formDataProvider") || "";
322
+ }
323
323
 
324
324
  super.connectedCallback();
325
+ this.initFormPublisher();
325
326
  this.addKeyboardNavigation();
326
327
  }
328
+
327
329
  unset() {
328
330
  this.value = null;
329
331
  }
@@ -333,10 +335,6 @@ const Form = <T extends Constructor<SubscriberInterface>>(superClass: T) => {
333
335
  this.unset();
334
336
  }
335
337
  super.disconnectedCallback();
336
- if (this._name && this.publisher)
337
- traverseDotNotation(this.publisher, this._name).offAssign(
338
- this.onValueAssign
339
- );
340
338
  const formPublisher = this.getFormPublisher();
341
339
  if (this._name && formPublisher) {
342
340
  traverseDotNotation(formPublisher, this._name).offAssign(
@@ -154,7 +154,11 @@ const Subscriber = <
154
154
  typeof value == "string" &&
155
155
  ["{", "["].includes(value.trim().charAt(0))
156
156
  ) {
157
- value = JSON.parse(value);
157
+ try {
158
+ value = JSON.parse(value);
159
+ } catch {
160
+ /* keep raw string (ex. score/label leaf, not a JSON attr) */
161
+ }
158
162
  }
159
163
  if (value == this._props) return;
160
164
 
@@ -3,13 +3,14 @@ import HTML, { SearchableDomElement } from "./HTML";
3
3
  /**
4
4
  * Observateur pour `@ancestorAttribute({ dynamic: true })`.
5
5
  *
6
- * Un MutationObserver sur `document` ne voit pas les mutations dans les shadow
7
- * roots (Lit par défaut). Chaque abonnement observe donc directement les nœuds
8
- * de sa chaîne d'ancêtres (composant → parent → … → host shadow), comme
9
- * `watchScopedConfiguration` dans `api.ts`.
6
+ * ## Perf (FF / listes denses d'icônes)
7
+ * Ancien modèle : 1 MO/abonnement avec `childList` sur **toute** la chaîne +
8
+ * `reconnect()` à chaque mutation → O(n²) quand une list insert des siblings.
10
9
  *
11
- * Après un `childList` (wrapper plus proche, reparenting), la chaîne est
12
- * recalculée pour écouter les nouveaux ancêtres.
10
+ * Modèle actuel :
11
+ * 1. **MO attributs partagés** — 1 observer par `(ancêtre, attributeName)`.
12
+ * 2. **Reparent** — 1 MO `childList` partagé sur le parent direct ; on ne
13
+ * réagit que si *notre* nœud est dans added/removed (insert sibling → no-op).
13
14
  */
14
15
 
15
16
  type SyncOptions = {
@@ -22,7 +23,18 @@ type Subscription = {
22
23
  attributeName: string;
23
24
  propertyKey: string;
24
25
  syncOptions: SyncOptions;
25
- disconnectObservers: (() => void) | null;
26
+ watchedAncestors: Element[];
27
+ parentForReparent: Element | null;
28
+ };
29
+
30
+ type AttrSlot = {
31
+ observer: MutationObserver;
32
+ subscriptions: Set<Subscription>;
33
+ };
34
+
35
+ type ParentSlot = {
36
+ observer: MutationObserver;
37
+ byComponent: Map<Element, Set<Subscription>>;
26
38
  };
27
39
 
28
40
  /** Chaîne composant → ancêtres, en traversant les shadow roots. */
@@ -40,58 +52,17 @@ function walkAncestorElements(node: Node): Element[] {
40
52
  return elements;
41
53
  }
42
54
 
43
- /**
44
- * Observe attributs + enfants directs de chaque ancêtre.
45
- * Retourne une fonction de nettoyage (disconnect).
46
- */
47
- function attachAncestorChainObservers(
48
- subscription: Subscription,
49
- onMutation: () => void,
50
- ): () => void {
51
- const observers: MutationObserver[] = [];
52
- let disconnected = false;
53
- const attributeFilter = HTML.scopeAttributeNames(subscription.attributeName);
54
-
55
- const reconnect = () => {
56
- for (const observer of observers) {
57
- observer.disconnect();
58
- }
59
- observers.length = 0;
60
- if (disconnected) return;
61
-
62
- for (const element of walkAncestorElements(subscription.component)) {
63
- const observer = new MutationObserver((records) => {
64
- if (disconnected) return;
65
- if (records.some((record) => record.type === "childList")) {
66
- reconnect();
67
- }
68
- onMutation();
69
- });
70
- observer.observe(element, {
71
- attributes: true,
72
- attributeFilter,
73
- childList: true,
74
- subtree: false,
75
- });
76
- observers.push(observer);
77
- }
78
- };
79
-
80
- reconnect();
81
-
82
- return () => {
83
- disconnected = true;
84
- for (const observer of observers) {
85
- observer.disconnect();
86
- }
87
- observers.length = 0;
88
- };
55
+ function directParentElement(component: HTMLElement): Element | null {
56
+ const parent =
57
+ component.parentNode ||
58
+ ((component.getRootNode() as ShadowRoot)?.host ?? null);
59
+ return parent instanceof Element ? parent : null;
89
60
  }
90
61
 
91
62
  /**
92
63
  * Point unique de synchronisation DOM → propriété du composant.
93
64
  * N'assigne que si la valeur change (`Object.is`) pour limiter les re-renders Lit
94
- * et éviter de reboucler inutilement `observeDynamicProperty` (@bind / @subscribe).
65
+ * et éviter de reboucler inutilement `observeDynamicProperty` (@bind / `@subscribe`).
95
66
  */
96
67
  export function syncAncestorAttributeValue(
97
68
  component: object,
@@ -115,8 +86,11 @@ export default class AncestorAttributeObserver {
115
86
  private static pendingRefresh = new Set<Subscription>();
116
87
  private static animationFrameId: number | null = null;
117
88
 
89
+ private static attrSlots = new WeakMap<Element, Map<string, AttrSlot>>();
90
+ private static parentSlots = new WeakMap<Element, ParentSlot>();
91
+
118
92
  /**
119
- * Enregistre un composant en mode `{ dynamic: true }`.
93
+ * Enregistre un composant en mode `{ dynamic: true }` (attributs + reparent).
120
94
  * Le `unsubscribe` retourné doit être appelé au `disconnectedCallback`.
121
95
  */
122
96
  static subscribe(
@@ -130,32 +104,172 @@ export default class AncestorAttributeObserver {
130
104
  attributeName,
131
105
  propertyKey,
132
106
  syncOptions,
133
- disconnectObservers: null,
107
+ watchedAncestors: [],
108
+ parentForReparent: null,
134
109
  };
135
110
 
136
- subscription.disconnectObservers = attachAncestorChainObservers(
137
- subscription,
138
- () => {
139
- if (!AncestorAttributeObserver.subscriptions.has(subscription)) return;
140
- AncestorAttributeObserver.pendingRefresh.add(subscription);
141
- AncestorAttributeObserver.scheduleRefresh();
142
- },
143
- );
144
-
145
111
  AncestorAttributeObserver.subscriptions.add(subscription);
112
+ AncestorAttributeObserver.bindSubscription(subscription);
146
113
 
147
114
  return () => {
148
115
  AncestorAttributeObserver.unsubscribe(subscription);
149
116
  };
150
117
  }
151
118
 
152
- /** Coupe les observateurs et retire l'abonnement (pas de fuite après disconnect). */
119
+ private static bindSubscription(subscription: Subscription): void {
120
+ AncestorAttributeObserver.unbindWatchers(subscription);
121
+
122
+ const ancestors = walkAncestorElements(subscription.component);
123
+ subscription.watchedAncestors = ancestors;
124
+
125
+ for (const ancestor of ancestors) {
126
+ AncestorAttributeObserver.addAttrSlot(
127
+ ancestor,
128
+ subscription.attributeName,
129
+ subscription,
130
+ );
131
+ }
132
+
133
+ const parent = directParentElement(subscription.component);
134
+ subscription.parentForReparent = parent;
135
+ if (parent) {
136
+ AncestorAttributeObserver.addParentSlot(parent, subscription);
137
+ }
138
+
139
+ AncestorAttributeObserver.pendingRefresh.add(subscription);
140
+ AncestorAttributeObserver.scheduleRefresh();
141
+ }
142
+
143
+ private static unbindWatchers(subscription: Subscription): void {
144
+ for (const ancestor of subscription.watchedAncestors) {
145
+ AncestorAttributeObserver.removeAttrSlot(
146
+ ancestor,
147
+ subscription.attributeName,
148
+ subscription,
149
+ );
150
+ }
151
+ subscription.watchedAncestors = [];
152
+
153
+ if (subscription.parentForReparent) {
154
+ AncestorAttributeObserver.removeParentSlot(
155
+ subscription.parentForReparent,
156
+ subscription,
157
+ );
158
+ subscription.parentForReparent = null;
159
+ }
160
+ }
161
+
162
+ private static addAttrSlot(
163
+ element: Element,
164
+ attributeName: string,
165
+ subscription: Subscription,
166
+ ): void {
167
+ let byAttr = AncestorAttributeObserver.attrSlots.get(element);
168
+ if (!byAttr) {
169
+ byAttr = new Map();
170
+ AncestorAttributeObserver.attrSlots.set(element, byAttr);
171
+ }
172
+
173
+ let slot = byAttr.get(attributeName);
174
+ if (!slot) {
175
+ const attributeFilter = HTML.scopeAttributeNames(attributeName);
176
+ const subscriptions = new Set<Subscription>();
177
+ const observer = new MutationObserver(() => {
178
+ for (const sub of subscriptions) {
179
+ if (!AncestorAttributeObserver.subscriptions.has(sub)) continue;
180
+ AncestorAttributeObserver.pendingRefresh.add(sub);
181
+ }
182
+ AncestorAttributeObserver.scheduleRefresh();
183
+ });
184
+ observer.observe(element, {
185
+ attributes: true,
186
+ attributeFilter,
187
+ });
188
+ slot = { observer, subscriptions };
189
+ byAttr.set(attributeName, slot);
190
+ }
191
+
192
+ slot.subscriptions.add(subscription);
193
+ }
194
+
195
+ private static removeAttrSlot(
196
+ element: Element,
197
+ attributeName: string,
198
+ subscription: Subscription,
199
+ ): void {
200
+ const byAttr = AncestorAttributeObserver.attrSlots.get(element);
201
+ if (!byAttr) return;
202
+ const slot = byAttr.get(attributeName);
203
+ if (!slot) return;
204
+
205
+ slot.subscriptions.delete(subscription);
206
+ if (slot.subscriptions.size > 0) return;
207
+
208
+ slot.observer.disconnect();
209
+ byAttr.delete(attributeName);
210
+ }
211
+
212
+ private static addParentSlot(
213
+ parent: Element,
214
+ subscription: Subscription,
215
+ ): void {
216
+ let slot = AncestorAttributeObserver.parentSlots.get(parent);
217
+ if (!slot) {
218
+ const byComponent = new Map<Element, Set<Subscription>>();
219
+ const observer = new MutationObserver((records) => {
220
+ const touched = new Set<Element>();
221
+ for (const record of records) {
222
+ record.removedNodes.forEach((n) => {
223
+ if (n instanceof Element) touched.add(n);
224
+ });
225
+ record.addedNodes.forEach((n) => {
226
+ if (n instanceof Element) touched.add(n);
227
+ });
228
+ }
229
+ for (const el of touched) {
230
+ const subs = byComponent.get(el);
231
+ if (!subs) continue;
232
+ for (const sub of [...subs]) {
233
+ if (!AncestorAttributeObserver.subscriptions.has(sub)) continue;
234
+ AncestorAttributeObserver.bindSubscription(sub);
235
+ }
236
+ }
237
+ });
238
+ observer.observe(parent, { childList: true });
239
+ slot = { observer, byComponent };
240
+ AncestorAttributeObserver.parentSlots.set(parent, slot);
241
+ }
242
+
243
+ let set = slot.byComponent.get(subscription.component);
244
+ if (!set) {
245
+ set = new Set();
246
+ slot.byComponent.set(subscription.component, set);
247
+ }
248
+ set.add(subscription);
249
+ }
250
+
251
+ private static removeParentSlot(
252
+ parent: Element,
253
+ subscription: Subscription,
254
+ ): void {
255
+ const slot = AncestorAttributeObserver.parentSlots.get(parent);
256
+ if (!slot) return;
257
+
258
+ const set = slot.byComponent.get(subscription.component);
259
+ if (set) {
260
+ set.delete(subscription);
261
+ if (set.size === 0) slot.byComponent.delete(subscription.component);
262
+ }
263
+
264
+ if (slot.byComponent.size > 0) return;
265
+ slot.observer.disconnect();
266
+ AncestorAttributeObserver.parentSlots.delete(parent);
267
+ }
268
+
153
269
  private static unsubscribe(subscription: Subscription): void {
154
270
  if (!AncestorAttributeObserver.subscriptions.has(subscription)) return;
155
271
 
156
- subscription.disconnectObservers?.();
157
- subscription.disconnectObservers = null;
158
-
272
+ AncestorAttributeObserver.unbindWatchers(subscription);
159
273
  AncestorAttributeObserver.subscriptions.delete(subscription);
160
274
  AncestorAttributeObserver.pendingRefresh.delete(subscription);
161
275
 
@@ -187,7 +301,6 @@ export default class AncestorAttributeObserver {
187
301
 
188
302
  for (const subscription of subscriptions) {
189
303
  if (!AncestorAttributeObserver.subscriptions.has(subscription)) continue;
190
- if (!subscription.component.isConnected) continue;
191
304
  syncAncestorAttributeValue(
192
305
  subscription.component,
193
306
  subscription.attributeName,
File without changes
@@ -1,13 +1,20 @@
1
1
  import { Route } from "./route";
2
2
 
3
+ export type AutoActiveMode =
4
+ | "strict"
5
+ | "partial"
6
+ | "disabled"
7
+ | "strict-path-only";
8
+
3
9
  declare type Listener = {
4
10
  location: string;
5
11
  };
6
- declare type ActivableLink = HTMLElement & {
12
+
13
+ export type ActivableLink = HTMLElement & {
7
14
  location?: string;
8
15
  href?: Route | string;
9
16
  goBack?: Route | string | null;
10
- autoActive?: "strict" | "partial" | "disabled" | "strict-path-only";
17
+ autoActive?: AutoActiveMode;
11
18
  setAttribute(name: string, value: string): void;
12
19
  removeAttribute(name: string): void;
13
20
  };
@@ -22,7 +29,7 @@ export default class LocationHandler {
22
29
  static listening = false;
23
30
  static prevURL: string = document.location?.href.replace(
24
31
  document.location.origin,
25
- ""
32
+ "",
26
33
  );
27
34
  static listen() {
28
35
  if (!LocationHandler.listening) {
@@ -30,7 +37,7 @@ export default class LocationHandler {
30
37
  }
31
38
  const newURL = document.location?.href.replace(
32
39
  document.location.origin,
33
- ""
40
+ "",
34
41
  );
35
42
  if (LocationHandler.prevURL && LocationHandler.prevURL != newURL) {
36
43
  LocationHandler.prevURL = newURL;
@@ -116,7 +123,7 @@ export default class LocationHandler {
116
123
  prevSp = sp;
117
124
  }
118
125
 
119
- to = "/" + newPathName.join("/") + url.search + (url.hash ? +url.hash : "");
126
+ to = "/" + newPathName.join("/") + url.search + (url.hash ? url.hash : "");
120
127
  if (component.hasAttribute("pushState")) {
121
128
  history.pushState(null, "", to);
122
129
  } else if (component.hasAttribute("replaceState")) {
File without changes