@supersoniks/concorde 5.1.1 → 5.1.3-immutable.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (459) hide show
  1. package/.agents/skills/concorde-docs/SKILL.md +153 -0
  2. package/.agents/skills/{concorde-component-docs/template.md → concorde-docs/templates/component.md} +6 -2
  3. package/.agents/skills/concorde-docs/templates/decorator.md +43 -0
  4. package/.agents/skills/concorde-docs/templates/guide.md +25 -0
  5. package/.claude/skills +1 -0
  6. package/.github/workflows/ci.yml +21 -0
  7. package/.github-export-ignore +30 -0
  8. package/CONTRIBUTING.md +59 -0
  9. package/DEV.md +54 -0
  10. package/LICENSE +21 -0
  11. package/OPEN_SOURCE_CHECKPOINT.md +133 -0
  12. package/README.md +4 -4
  13. package/ai/README.md +29 -41
  14. package/ai/skills/concorde/SKILL.md +54 -324
  15. package/ai/skills/concorde/rules/composition.md +32 -0
  16. package/ai/skills/concorde/rules/data.md +47 -0
  17. package/ai/skills/concorde/rules/http.md +25 -0
  18. package/ai/skills/concorde/rules/lists-forms.md +35 -0
  19. package/ai/skills/concorde/rules/styling.md +46 -0
  20. package/ai/skills/concorde/rules/troubleshooting.md +45 -0
  21. package/build-infos.json +1 -1
  22. package/concorde-core.bundle.js +177 -177
  23. package/concorde-core.es.js +4993 -4833
  24. package/custom-elements-manifest.public.config.mjs +8 -0
  25. package/{.tmp-cem/custom-elements.json → custom-elements.json} +11758 -8904
  26. package/dist/concorde-core.bundle.js +177 -177
  27. package/dist/concorde-core.es.js +4993 -4833
  28. package/dist/docs-mock-api-sw.js +58 -223
  29. package/dist/docs-mock-api-sw.js.map +4 -4
  30. package/dist/img/concorde/plane_01.jpg +0 -0
  31. package/dist/img/concorde/plane_02.jpg +0 -0
  32. package/dist/img/concorde/plane_03.jpg +0 -0
  33. package/dist/img/concorde/plane_04.jpg +0 -0
  34. package/dist/img/concorde/plane_05.jpg +0 -0
  35. package/dist/img/concorde/plane_06.jpg +0 -0
  36. package/dist/img/concorde/plane_07.jpg +0 -0
  37. package/dist/img/concorde/plane_08.jpg +0 -0
  38. package/dist/img/concorde/plane_09.jpg +0 -0
  39. package/dist/img/concorde/plane_10.jpg +0 -0
  40. package/dist/img/concorde/plane_11.jpg +0 -0
  41. package/dist/img/concorde/plane_12.jpg +0 -0
  42. package/dist/img/concorde/plane_13.jpg +0 -0
  43. package/dist/img/og-concorde.jpg +0 -0
  44. package/dist/robots.txt +11 -10
  45. package/docs/assets/index-D_alEsng.js +12122 -0
  46. package/docs/crawl/core/components/functional/date/date.html +190 -0
  47. package/docs/crawl/core/components/functional/fetch/fetch.html +109 -0
  48. package/docs/crawl/core/components/functional/if/if.html +27 -0
  49. package/docs/crawl/core/components/functional/jsonata/jsonata.html +79 -0
  50. package/docs/crawl/core/components/functional/list/list.html +70 -0
  51. package/docs/crawl/core/components/functional/mix/mix.html +45 -0
  52. package/docs/crawl/core/components/functional/queue/queue.html +96 -0
  53. package/docs/crawl/core/components/functional/router/router.html +106 -0
  54. package/docs/crawl/core/components/functional/sdui/sdui-extension-points.html +126 -0
  55. package/docs/crawl/core/components/functional/sdui/sdui.html +368 -0
  56. package/docs/crawl/core/components/functional/states/states.html +66 -0
  57. package/docs/crawl/core/components/functional/submit/submit.html +160 -0
  58. package/docs/crawl/core/components/functional/subscriber/subscriber.html +67 -0
  59. package/docs/crawl/core/components/functional/value/value.html +51 -0
  60. package/docs/crawl/core/components/ui/alert/alert.html +211 -0
  61. package/docs/crawl/core/components/ui/alert-messages/alert-messages.html +131 -0
  62. package/docs/crawl/core/components/ui/badge/badge.html +197 -0
  63. package/docs/crawl/core/components/ui/button/button.html +150 -0
  64. package/docs/crawl/core/components/ui/captcha/captcha.html +112 -0
  65. package/docs/crawl/core/components/ui/card/card.html +253 -0
  66. package/docs/crawl/core/components/ui/divider/divider.html +144 -0
  67. package/docs/crawl/core/components/ui/form/checkbox/checkbox.html +73 -0
  68. package/docs/crawl/core/components/ui/form/fieldset/fieldset.html +266 -0
  69. package/docs/crawl/core/components/ui/form/form-actions/form-actions.html +122 -0
  70. package/docs/crawl/core/components/ui/form/form-layout/form-layout.html +121 -0
  71. package/docs/crawl/core/components/ui/form/input/input.html +109 -0
  72. package/docs/crawl/core/components/ui/form/input-autocomplete/input-autocomplete.html +38 -0
  73. package/docs/crawl/core/components/ui/form/radio/radio.html +56 -0
  74. package/docs/crawl/core/components/ui/form/select/select.html +73 -0
  75. package/docs/crawl/core/components/ui/form/switch/switch.html +56 -0
  76. package/docs/crawl/core/components/ui/form/textarea/textarea.html +59 -0
  77. package/docs/crawl/core/components/ui/group/group.html +104 -0
  78. package/docs/crawl/core/components/ui/icon/icon.html +222 -0
  79. package/docs/crawl/core/components/ui/image/image.html +298 -0
  80. package/docs/crawl/core/components/ui/link/link.html +100 -0
  81. package/docs/crawl/core/components/ui/loader/loader.html +124 -0
  82. package/docs/crawl/core/components/ui/menu/menu.html +394 -0
  83. package/docs/crawl/core/components/ui/modal/modal.html +342 -0
  84. package/docs/crawl/core/components/ui/pop/pop.html +296 -0
  85. package/docs/crawl/core/components/ui/progress/progress.html +131 -0
  86. package/docs/crawl/core/components/ui/table/table.html +545 -0
  87. package/docs/crawl/core/components/ui/theme/theme.html +131 -0
  88. package/docs/crawl/core/components/ui/toast/toast.html +233 -0
  89. package/docs/crawl/core/components/ui/tooltip/tooltip.html +140 -0
  90. package/docs/crawl/docs/_core-concept/dataFlow.html +177 -0
  91. package/docs/crawl/docs/_core-concept/overview.html +66 -0
  92. package/docs/crawl/docs/_core-concept/subscriber.html +75 -0
  93. package/docs/crawl/docs/_decorators/ancestor-attribute.html +117 -0
  94. package/docs/crawl/docs/_decorators/auto-subscribe.html +202 -0
  95. package/docs/crawl/docs/_decorators/bind.html +141 -0
  96. package/docs/crawl/docs/_decorators/get.html +149 -0
  97. package/docs/crawl/docs/_decorators/handle.html +165 -0
  98. package/docs/crawl/docs/_decorators/on-assign.html +355 -0
  99. package/docs/crawl/docs/_decorators/patch.html +78 -0
  100. package/docs/crawl/docs/_decorators/post.html +139 -0
  101. package/docs/crawl/docs/_decorators/publish.html +61 -0
  102. package/docs/crawl/docs/_decorators/put.html +78 -0
  103. package/docs/crawl/docs/_decorators/subscribe.html +109 -0
  104. package/docs/crawl/docs/_decorators/wait-for-ancestors.html +137 -0
  105. package/docs/crawl/docs/_directives/sub.html +93 -0
  106. package/docs/crawl/docs/_getting-started/ai-agents.html +173 -0
  107. package/docs/crawl/docs/_getting-started/concorde-manual-install.html +100 -0
  108. package/docs/crawl/docs/_getting-started/concorde-outside.html +58 -0
  109. package/docs/crawl/docs/_getting-started/create-a-component.html +111 -0
  110. package/docs/crawl/docs/_getting-started/my-first-component.html +189 -0
  111. package/docs/crawl/docs/_getting-started/my-first-subscriber.html +110 -0
  112. package/docs/crawl/docs/_getting-started/pubsub.html +62 -0
  113. package/docs/crawl/docs/_getting-started/start.html +76 -0
  114. package/docs/crawl/docs/_getting-started/theming.html +333 -0
  115. package/docs/crawl/docs/_misc/api-configuration.html +149 -0
  116. package/docs/crawl/docs/_misc/dataProviderKey.html +135 -0
  117. package/docs/crawl/docs/_misc/docs-mock-api.html +158 -0
  118. package/docs/crawl/docs/_misc/dynamic-path.html +180 -0
  119. package/docs/crawl/docs/_misc/endpoint.html +50 -0
  120. package/docs/crawl/docs/_misc/formelement-subscriber-removal.html +138 -0
  121. package/docs/crawl/docs/_misc/html-integration.html +48 -0
  122. package/docs/crawl/hubs/decorators.html +547 -0
  123. package/docs/crawl/hubs/form-components.html +381 -0
  124. package/docs/crawl/hubs/remote-data.html +452 -0
  125. package/docs/crawl/index.html +103 -0
  126. package/docs/index.html +1 -1
  127. package/docs/llms-full.txt +7174 -0
  128. package/docs/llms.txt +98 -0
  129. package/docs/sitemap.xml +243 -0
  130. package/docs/src/core/components/functional/date/date.md +290 -0
  131. package/docs/src/core/components/functional/fetch/fetch.md +125 -0
  132. package/docs/src/core/components/functional/if/if.md +9 -0
  133. package/docs/src/core/components/functional/jsonata/jsonata.md +56 -0
  134. package/docs/src/core/components/functional/list/list.md +65 -0
  135. package/docs/src/core/components/functional/mix/mix.md +41 -0
  136. package/docs/src/core/components/functional/queue/queue.md +72 -0
  137. package/docs/src/core/components/functional/router/router.md +94 -0
  138. package/docs/src/core/components/functional/sdui/component-catalog.gaps.json +511 -0
  139. package/docs/src/core/components/functional/sdui/component-catalog.json +3103 -0
  140. package/docs/src/core/components/functional/sdui/default-library.json +108 -0
  141. package/docs/src/core/components/functional/sdui/example.json +99 -0
  142. package/docs/src/core/components/functional/sdui/sdui-extension-points.md +94 -0
  143. package/docs/src/core/components/functional/sdui/sdui.md +478 -0
  144. package/docs/src/core/components/functional/states/states.md +87 -0
  145. package/docs/src/core/components/functional/submit/submit.md +114 -0
  146. package/docs/src/core/components/functional/subscriber/subscriber.md +91 -0
  147. package/docs/src/core/components/functional/value/value.md +35 -0
  148. package/docs/src/core/components/ui/alert/alert.md +196 -0
  149. package/docs/src/core/components/ui/alert-messages/alert-messages.md +85 -0
  150. package/docs/src/core/components/ui/badge/badge.md +188 -0
  151. package/docs/src/core/components/ui/button/button.md +183 -0
  152. package/docs/src/core/components/ui/captcha/captcha.md +71 -0
  153. package/docs/src/core/components/ui/card/card.md +215 -0
  154. package/docs/src/core/components/ui/divider/divider.md +129 -0
  155. package/docs/src/core/components/ui/form/checkbox/checkbox.md +77 -0
  156. package/docs/src/core/components/ui/form/fieldset/fieldset.md +205 -0
  157. package/docs/src/core/components/ui/form/form-actions/form-actions.md +100 -0
  158. package/docs/src/core/components/ui/form/form-layout/form-layout.md +119 -0
  159. package/docs/src/core/components/ui/form/input/input.md +142 -0
  160. package/docs/src/core/components/ui/form/radio/radio.md +57 -0
  161. package/docs/src/core/components/ui/form/select/select.md +71 -0
  162. package/docs/src/core/components/ui/form/switch/switch.md +57 -0
  163. package/docs/src/core/components/ui/form/textarea/textarea.md +65 -0
  164. package/docs/src/core/components/ui/group/group.md +75 -0
  165. package/docs/src/core/components/ui/icon/icon.md +214 -0
  166. package/docs/src/core/components/ui/icon/icons.json +1 -0
  167. package/docs/src/core/components/ui/image/image.md +233 -0
  168. package/docs/src/core/components/ui/link/link.md +81 -0
  169. package/docs/src/core/components/ui/loader/loader.md +112 -0
  170. package/docs/src/core/components/ui/menu/menu.md +370 -0
  171. package/docs/src/core/components/ui/modal/modal.md +235 -0
  172. package/docs/src/core/components/ui/pop/pop.md +294 -0
  173. package/docs/src/core/components/ui/progress/progress.md +109 -0
  174. package/docs/src/core/components/ui/table/table.md +431 -0
  175. package/docs/src/core/components/ui/theme/theme.md +122 -0
  176. package/docs/src/core/components/ui/toast/toast.md +216 -0
  177. package/docs/src/core/components/ui/tooltip/tooltip.md +124 -0
  178. package/{src → docs/src}/docs/_core-concept/subscriber.md +0 -0
  179. package/{src → docs/src}/docs/_getting-started/my-first-subscriber.md +0 -0
  180. package/{src → docs/src}/docs/_getting-started/pubsub.md +0 -0
  181. package/docs/src/docs/_getting-started/theming.md +253 -0
  182. package/docs/src/docs/search/docs-search.json +12242 -0
  183. package/docs/src/tag-list.json +1 -0
  184. package/docs/src/tsconfig-model.json +23 -0
  185. package/docs/src/tsconfig.declarations.json +22 -0
  186. package/docs/src/tsconfig.emit.json +23 -0
  187. package/docs/src/tsconfig.json +1332 -0
  188. package/gitlab/job_github_mirror.sh +39 -0
  189. package/index.html +157 -5
  190. package/package.json +22 -4
  191. package/public/docs-mock-api-sw.js +58 -223
  192. package/public/docs-mock-api-sw.js.map +4 -4
  193. package/public/img/concorde/plane_01.jpg +0 -0
  194. package/public/img/concorde/plane_02.jpg +0 -0
  195. package/public/img/concorde/plane_03.jpg +0 -0
  196. package/public/img/concorde/plane_04.jpg +0 -0
  197. package/public/img/concorde/plane_05.jpg +0 -0
  198. package/public/img/concorde/plane_06.jpg +0 -0
  199. package/public/img/concorde/plane_07.jpg +0 -0
  200. package/public/img/concorde/plane_08.jpg +0 -0
  201. package/public/img/concorde/plane_09.jpg +0 -0
  202. package/public/img/concorde/plane_10.jpg +0 -0
  203. package/public/img/concorde/plane_11.jpg +0 -0
  204. package/public/img/concorde/plane_12.jpg +0 -0
  205. package/public/img/concorde/plane_13.jpg +0 -0
  206. package/public/img/og-concorde.jpg +0 -0
  207. package/public/robots.txt +11 -10
  208. package/scripts/ai-init.mjs +104 -379
  209. package/scripts/ai-init.test.mjs +81 -239
  210. package/scripts/docs-markdown-vite-plugin.ts +43 -0
  211. package/scripts/docs-public-url.mjs +56 -0
  212. package/scripts/docs.htaccess +82 -0
  213. package/scripts/generate-cem.mjs +244 -0
  214. package/scripts/generate-cem.test.mjs +122 -0
  215. package/scripts/generate-crawl-docs.mjs +233 -118
  216. package/scripts/generate-crawl-docs.test.mjs +124 -0
  217. package/scripts/generate-sdui-catalog.mjs +11 -10
  218. package/scripts/github-export.mjs +150 -0
  219. package/scripts/post-build-docs.js +37 -50
  220. package/scripts/post-build.mjs +0 -0
  221. package/scripts/pre-publish.mjs +2 -1
  222. package/scripts/site-pages.mjs +212 -0
  223. package/scripts/site-pages.test.mjs +116 -0
  224. package/site-pages/about.md +22 -0
  225. package/site-pages/privacy.md +32 -0
  226. package/src/core/components/functional/date/date.md +91 -231
  227. package/src/core/components/functional/example/example.ts +3 -1
  228. package/src/core/components/functional/fetch/fetch.md +66 -83
  229. package/src/core/components/functional/if/if.md +28 -3
  230. package/src/core/components/functional/if/if.ts +0 -0
  231. package/src/core/components/functional/jsonata/jsonata.md +42 -37
  232. package/src/core/components/functional/list/list.demo.ts +0 -0
  233. package/src/core/components/functional/list/list.md +103 -43
  234. package/src/core/components/functional/list/list.ts +17 -4
  235. package/src/core/components/functional/mix/mix.md +31 -26
  236. package/src/core/components/functional/queue/queue.demo.ts +10 -7
  237. package/src/core/components/functional/queue/queue.md +40 -61
  238. package/src/core/components/functional/router/router.demo.ts +16 -16
  239. package/src/core/components/functional/router/router.md +64 -65
  240. package/src/core/components/functional/router/router.ts +0 -0
  241. package/src/core/components/functional/sdui/SDUIDescriptorTransformer.ts +0 -0
  242. package/src/core/components/functional/sdui/component-catalog.gaps.json +1 -1
  243. package/src/core/components/functional/sdui/component-catalog.json +2 -2
  244. package/src/core/components/functional/sdui/example.json +19 -86
  245. package/src/core/components/functional/sdui/sdui-extension-points.md +1 -1
  246. package/src/core/components/functional/sdui/sdui-immutable.spec.ts +74 -0
  247. package/src/core/components/functional/sdui/sdui.md +187 -358
  248. package/src/core/components/functional/sdui/sdui.ts +33 -8
  249. package/src/core/components/functional/sdui/types.ts +0 -0
  250. package/src/core/components/functional/states/states.demo.ts +21 -22
  251. package/src/core/components/functional/states/states.md +86 -61
  252. package/src/core/components/functional/states/states.ts +1 -1
  253. package/src/core/components/functional/submit/submit.md +64 -72
  254. package/src/core/components/functional/submit/submit.spec.ts +60 -0
  255. package/src/core/components/functional/submit/submit.ts +6 -3
  256. package/src/core/components/functional/subscriber/subscriber.ts +0 -0
  257. package/src/core/components/functional/translation/translation.md +38 -0
  258. package/src/core/components/functional/value/value.md +34 -22
  259. package/src/core/components/functional/value/value.ts +0 -0
  260. package/src/core/components/ui/_css/size.ts +0 -0
  261. package/src/core/components/ui/alert/alert.md +48 -58
  262. package/src/core/components/ui/badge/badge.md +27 -34
  263. package/src/core/components/ui/button/button.md +139 -106
  264. package/src/core/components/ui/captcha/altchaStyles.ts +0 -0
  265. package/src/core/components/ui/captcha/captcha.md +17 -32
  266. package/src/core/components/ui/card/card.md +6 -6
  267. package/src/core/components/ui/divider/divider.md +8 -11
  268. package/src/core/components/ui/form/checkbox/checkbox.md +90 -42
  269. package/src/core/components/ui/form/fieldset/fieldset.md +31 -75
  270. package/src/core/components/ui/form/form-actions/form-actions.md +14 -16
  271. package/src/core/components/ui/form/form-layout/form-layout.md +19 -29
  272. package/src/core/components/ui/form/input/input.md +108 -90
  273. package/src/core/components/ui/form/input/input.ts +8 -2
  274. package/src/core/components/ui/form/radio/radio.md +65 -30
  275. package/src/core/components/ui/form/select/select.md +60 -45
  276. package/src/core/components/ui/form/switch/switch.md +57 -34
  277. package/src/core/components/ui/form/textarea/textarea.md +55 -38
  278. package/src/core/components/ui/group/group.md +35 -33
  279. package/src/core/components/ui/icon/icon.md +4 -4
  280. package/src/core/components/ui/image/image.md +41 -107
  281. package/src/core/components/ui/link/link.md +6 -6
  282. package/src/core/components/ui/loader/loader.md +30 -55
  283. package/src/core/components/ui/menu/menu.md +27 -27
  284. package/src/core/components/ui/modal/modal.md +72 -96
  285. package/src/core/components/ui/pop/pop.md +80 -158
  286. package/src/core/components/ui/progress/progress.md +2 -2
  287. package/src/core/components/ui/table/table.md +91 -255
  288. package/src/core/components/ui/theme/theme.md +11 -36
  289. package/src/core/components/ui/toast/toast.md +48 -117
  290. package/src/core/components/ui/tooltip/tooltip.md +27 -62
  291. package/src/core/decorators/subscriber/bind.ts +9 -14
  292. package/src/core/decorators/subscriber/subscribe.ts +15 -9
  293. package/src/core/decorators/subscriber/subscribe.type-test.ts +14 -5
  294. package/src/core/mixins/Subscriber.ts +0 -0
  295. package/src/core/utils/DataBindObserver.ts +0 -0
  296. package/src/core/utils/LocationHandler.spec.ts +80 -0
  297. package/src/core/utils/LocationHandler.ts +5 -9
  298. package/src/core/utils/Objects.ts +0 -0
  299. package/src/core/utils/PublisherProxy.ts +166 -125
  300. package/src/core/utils/deepReadonly.spec.ts +66 -0
  301. package/src/core/utils/deepReadonly.ts +71 -0
  302. package/src/core/utils/immutableValue.spec.ts +54 -0
  303. package/src/core/utils/immutableValue.ts +102 -0
  304. package/src/core/utils/nestedDotForm.spec.ts +88 -0
  305. package/src/core/utils/publisherImmutable.spec.ts +76 -0
  306. package/src/core/utils/route.ts +0 -0
  307. package/src/core/utils/strictGet.spec.ts +61 -0
  308. package/src/core/utils/strictGet.ts +102 -0
  309. package/src/css.d.ts +19 -0
  310. package/src/docs/components/docs-demo-sources.ts +55 -140
  311. package/src/docs/components/docs-lit-demo.ts +1 -3
  312. package/src/docs/components/docs-source-link.ts +0 -82
  313. package/src/docs/decorators/ancestor-attribute.md +59 -0
  314. package/src/docs/decorators/auto-subscribe.md +40 -0
  315. package/src/docs/decorators/bind.md +76 -0
  316. package/src/docs/decorators/get.md +160 -0
  317. package/src/docs/decorators/handle.md +119 -0
  318. package/src/docs/decorators/on-assign.md +63 -0
  319. package/src/docs/decorators/patch.md +44 -0
  320. package/src/docs/decorators/post.md +134 -0
  321. package/src/docs/decorators/publish.md +56 -0
  322. package/src/docs/decorators/put.md +51 -0
  323. package/src/docs/decorators/subscribe.md +87 -0
  324. package/src/docs/decorators/wait-for-ancestors.md +76 -0
  325. package/src/docs/directives/sub.md +75 -0
  326. package/src/docs/directives/t.md +73 -0
  327. package/src/docs/docs-location.spec.ts +56 -0
  328. package/src/docs/docs-location.ts +133 -32
  329. package/src/docs/docs.ts +1 -2
  330. package/src/docs/example/decorators-demo-bind-demos.ts +83 -135
  331. package/src/docs/example/decorators-demo-geo.ts +30 -19
  332. package/src/docs/example/decorators-demo-post.ts +88 -186
  333. package/src/docs/example/decorators-demo-subscribe-publish-get-demos.ts +165 -268
  334. package/src/docs/example/decorators-demo.ts +85 -98
  335. package/src/docs/example/docs-api-config-demos.ts +19 -20
  336. package/src/docs/example/docs-flight-demos.ts +147 -0
  337. package/src/docs/example/docs-jsonata-demos.ts +52 -52
  338. package/src/docs/example/docs-list-demos.ts +43 -123
  339. package/src/docs/example/docs-provider-keys.ts +21 -28
  340. package/src/docs/example/docs-queue-demos.ts +37 -77
  341. package/src/docs/example/docs-router-demos.ts +20 -25
  342. package/src/docs/example/docs-submit-demos.ts +48 -48
  343. package/src/docs/example/docs-toggle-demos.ts +4 -3
  344. package/src/docs/example/users.ts +0 -0
  345. package/src/docs/getting-started/ai-agents.md +50 -0
  346. package/src/docs/getting-started/create-a-component.md +136 -0
  347. package/src/docs/getting-started/dataFlow.md +87 -0
  348. package/src/docs/getting-started/installation.md +36 -0
  349. package/src/docs/getting-started/my-first-component.md +227 -0
  350. package/src/docs/getting-started/start.md +35 -0
  351. package/src/docs/header/header.ts +11 -6
  352. package/src/docs/home/catalog.ts +1 -1
  353. package/src/docs/home/home.ts +20 -11
  354. package/src/docs/layout.ts +12 -13
  355. package/src/docs/misc/api-configuration.md +79 -0
  356. package/src/docs/misc/dataProviderKey.md +168 -0
  357. package/src/docs/misc/docs-mock-api.md +62 -0
  358. package/src/docs/misc/dynamic-path.md +71 -0
  359. package/src/docs/misc/endpoint.md +45 -0
  360. package/src/docs/misc/html-integration.md +14 -0
  361. package/src/docs/misc/publisher-get-immutability-docs-crawl.json +902 -0
  362. package/src/docs/misc/publisher-get-immutability-docs-recheck.json +13 -0
  363. package/src/docs/misc/publisher-get-immutability-study.md +229 -0
  364. package/src/docs/mock-api/api-config-mock.ts +5 -0
  365. package/src/docs/mock-api/fixtures.ts +0 -278
  366. package/src/docs/mock-api/flights.ts +89 -0
  367. package/src/docs/mock-api/router.ts +3 -4
  368. package/src/docs/mock-api/urls.ts +1 -2
  369. package/src/docs/navigation/navigation.ts +84 -101
  370. package/src/docs/navigation/toc.ts +7 -4
  371. package/src/docs/search/docs-search.json +3188 -5153
  372. package/src/docs/search/markdown-renderer.ts +31 -8
  373. package/src/docs/search/page.ts +9 -6
  374. package/src/docs/search/search.ts +154 -122
  375. package/src/docs/tailwind/css/docs/content.css +4 -5
  376. package/src/tsconfig.declarations.json +22 -0
  377. package/src/tsconfig.emit.json +23 -0
  378. package/src/tsconfig.json +53 -5
  379. package/src/tsconfig.tsbuildinfo +1 -1
  380. package/vite.config.mts +11 -2
  381. package/.agents/skills/concorde-component-docs/SKILL.md +0 -194
  382. package/.taste-skill/after/desktop-fold.jpg +0 -0
  383. package/.taste-skill/after/desktop-page-01.jpg +0 -0
  384. package/.taste-skill/after/desktop-page-02.jpg +0 -0
  385. package/.taste-skill/after/desktop-page-03.jpg +0 -0
  386. package/.taste-skill/after/mobile-fold.jpg +0 -0
  387. package/.taste-skill/after/mobile-page-01.jpg +0 -0
  388. package/.taste-skill/after/report.json +0 -4103
  389. package/.taste-skill/after/tablet-fold.jpg +0 -0
  390. package/.taste-skill/after/tablet-page-01.jpg +0 -0
  391. package/.taste-skill/after/tablet-page-02.jpg +0 -0
  392. package/.taste-skill/before/desktop-fold.jpg +0 -0
  393. package/.taste-skill/before/desktop-page-01.jpg +0 -0
  394. package/.taste-skill/before/desktop-page-02.jpg +0 -0
  395. package/.taste-skill/before/mobile-fold.jpg +0 -0
  396. package/.taste-skill/before/mobile-page-01.jpg +0 -0
  397. package/.taste-skill/before/report.json +0 -2556
  398. package/.taste-skill/before/tablet-fold.jpg +0 -0
  399. package/.taste-skill/before/tablet-page-01.jpg +0 -0
  400. package/.taste-skill/direction.json +0 -510
  401. package/.taste-skill/notes.md +0 -84
  402. package/.taste-skill/prod/desktop-fold.jpg +0 -0
  403. package/.taste-skill/prod/desktop-page-01.jpg +0 -0
  404. package/.taste-skill/prod/desktop-page-02.jpg +0 -0
  405. package/.taste-skill/prod/desktop-page-03.jpg +0 -0
  406. package/.taste-skill/prod/mobile-fold.jpg +0 -0
  407. package/.taste-skill/prod/mobile-page-01.jpg +0 -0
  408. package/.taste-skill/prod/mobile-page-02.jpg +0 -0
  409. package/.taste-skill/prod/report.json +0 -1973
  410. package/.taste-skill/prod/tablet-fold.jpg +0 -0
  411. package/.taste-skill/prod/tablet-page-01.jpg +0 -0
  412. package/.taste-skill/prod/tablet-page-02.jpg +0 -0
  413. package/AUDIT.md +0 -228
  414. package/PLAN-AMELIORATION.md +0 -220
  415. package/ai/AGENTS.md +0 -56
  416. package/ai/cursor/rules/concorde-menu.mdc +0 -15
  417. package/ai/cursor/rules/concorde-scope.mdc +0 -14
  418. package/ai/cursor/rules/concorde-theme.mdc +0 -13
  419. package/ai/cursor/rules/concorde.mdc +0 -66
  420. package/ai/jetbrains/rules/concorde.md +0 -53
  421. package/ai/skills/concorde-get-set-dp/SKILL.md +0 -194
  422. package/ai/skills/concorde-imports/SKILL.md +0 -78
  423. package/ai/skills/concorde-menu/SKILL.md +0 -74
  424. package/ai/skills/concorde-scope/SKILL.md +0 -70
  425. package/ai/skills/concorde-theme/SKILL.md +0 -57
  426. package/docs/assets/index-Bb-_LRyY.js +0 -12280
  427. package/src/docs/example/docs-input-autocomplete-demos.ts +0 -110
  428. package/src/docs/example/docs-joke-demos.ts +0 -297
  429. /package/{src → docs/src}/core/components/ui/form/input-autocomplete/input-autocomplete.md +0 -0
  430. /package/{src → docs/src}/docs/_core-concept/dataFlow.md +0 -0
  431. /package/{src → docs/src}/docs/_core-concept/overview.md +0 -0
  432. /package/{src → docs/src}/docs/_decorators/ancestor-attribute.md +0 -0
  433. /package/{src → docs/src}/docs/_decorators/auto-subscribe.md +0 -0
  434. /package/{src → docs/src}/docs/_decorators/bind.md +0 -0
  435. /package/{src → docs/src}/docs/_decorators/get.md +0 -0
  436. /package/{src → docs/src}/docs/_decorators/handle.md +0 -0
  437. /package/{src → docs/src}/docs/_decorators/on-assign.md +0 -0
  438. /package/{src → docs/src}/docs/_decorators/patch.md +0 -0
  439. /package/{src → docs/src}/docs/_decorators/post.md +0 -0
  440. /package/{src → docs/src}/docs/_decorators/publish.md +0 -0
  441. /package/{src → docs/src}/docs/_decorators/put.md +0 -0
  442. /package/{src → docs/src}/docs/_decorators/subscribe.md +0 -0
  443. /package/{src → docs/src}/docs/_decorators/wait-for-ancestors.md +0 -0
  444. /package/{src → docs/src}/docs/_directives/sub.md +0 -0
  445. /package/{src → docs/src}/docs/_getting-started/ai-agents.md +0 -0
  446. /package/{src → docs/src}/docs/_getting-started/concorde-manual-install.md +0 -0
  447. /package/{src → docs/src}/docs/_getting-started/concorde-outside.md +0 -0
  448. /package/{src → docs/src}/docs/_getting-started/create-a-component.md +0 -0
  449. /package/{src → docs/src}/docs/_getting-started/my-first-component.md +0 -0
  450. /package/{src → docs/src}/docs/_getting-started/start.md +0 -0
  451. /package/{src → docs/src}/docs/_misc/api-configuration.md +0 -0
  452. /package/{src → docs/src}/docs/_misc/dataProviderKey.md +0 -0
  453. /package/{src → docs/src}/docs/_misc/docs-mock-api.md +0 -0
  454. /package/{src → docs/src}/docs/_misc/dynamic-path.md +0 -0
  455. /package/{src → docs/src}/docs/_misc/endpoint.md +0 -0
  456. /package/{src → docs/src}/docs/_misc/formelement-subscriber-removal.md +0 -0
  457. /package/{src → docs/src}/docs/_misc/html-integration.md +0 -0
  458. /package/src/docs/{_getting-started → getting-started}/components.md +0 -0
  459. /package/src/docs/{_getting-started → getting-started}/theming.md +0 -0
File without changes
@@ -1,56 +1,61 @@
1
1
  # Jsonata
2
2
 
3
- `sonic-jsonata` : **1 input → expression → 1 output** (readonly).
3
+ **`sonic-jsonata`** reads one data provider, evaluates a [JSONata](https://jsonata.org) expression on it and writes the result to another data provider. Use it for read-only aggregates such as groups, rankings and totals; use [Mix](/core/components/functional/mix) to compose data in both directions, and [`derive`](/docs/getting-started/dataFlow) for several inputs or a TypeScript function.
4
4
 
5
- Unidirectional (fetch → compute → display), unlike [`sonic-mix`](#core/components/functional/mix/mix.md/mix).
5
+ ## Group and sort
6
6
 
7
- > Offline : `serviceURL="/docs-mock-api"` — [Local API demos](#docs/_misc/docs-mock-api.md/docs-mock-api).
8
-
9
- ## Demos
10
-
11
- ### Groupby + top N
12
-
13
- Change **Top N** → recalcul sans refetch.
7
+ `inputProvider` is available as `$input` and the result is written to `outputProvider`. Each field of the optional `formDataProvider` store becomes a variable (`$direction` here): changing it recomputes the output without fetching again.
14
8
 
15
9
  <docs-lit-demo for="docs-jsonata-space-cats-demo"></docs-lit-demo>
16
10
 
17
- ### Totaux (somme + taxe)
18
-
19
- Change **Tax %** → même idée.
20
-
21
- <docs-lit-demo for="docs-jsonata-table-totals-demo"></docs-lit-demo>
22
-
23
- ## Attributes
11
+ JSONata returns a single object instead of an array when only one item matches. Wrap the expression in `$append([], …)` when a list renders the output.
24
12
 
25
- | Attribute | Role |
26
- |-----------|------|
27
- | `inputProvider` | Entrée (`$input` dans l’expression) |
28
- | `outputProvider` | Sortie (readonly) |
29
- | `expression` | Expression JSONata |
30
- | `formDataProvider` | Form optionnel (`$top`, `$taxPercent`, …) — même id que le form |
31
- | `outputSchema` | Schéma léger optionnel (`type`, `required`) |
13
+ ## Totals
32
14
 
33
- ## Helpers
15
+ A `( … )` block declares local variables and returns an object; read its fields with `sonic-value`. Change the reserve to recompute the block fuel.
34
16
 
35
- `$ucFirst` · `$currency` · `$percent` · `$date` · `$toChart(items, labelKey, valueKey, datasetLabel?)`
17
+ <docs-lit-demo for="docs-jsonata-table-totals-demo"></docs-lit-demo>
36
18
 
37
- Pas de DOM, pas de réseau, pas d’`eval`.
19
+ ## States
38
20
 
39
- ## Markup
21
+ The evaluation state is published on `{outputProvider}/_state_` as `{ status, error }`, with `status` among `loading` · `ready` · `empty` · `error`. Display it with [States](/core/components/functional/states).
40
22
 
41
- <sonic-code language="html">
23
+ <sonic-code>
42
24
  <template>
43
- &lt;sonic-jsonata
44
- inputProvider="api/space-cats"
45
- outputProvider="leaderboard"
46
- formDataProvider="topForm"
47
- expression='$input{name: $sum(points)} ~> $each(function($v,$k){{"name":$k,"points":$v}}) ^(>points)[[0..$number($top)-1]]'
48
- &gt;&lt;/sonic-jsonata&gt;
25
+ <div serviceURL="/docs-mock-api">
26
+ <sonic-fetch dataProvider="jsonataStateFlights" endPoint="flights" key="flights"></sonic-fetch>
27
+ <sonic-jsonata
28
+ inputProvider="jsonataStateFlights"
29
+ outputProvider="jsonataLanded"
30
+ expression='{"landed": $count($input[status="landed"])}'
31
+ ></sonic-jsonata>
32
+ <sonic-states dataProvider="jsonataLanded/_state_" data-path="status">
33
+ <template data-value="loading">Counting flights…</template>
34
+ <template data-value="ready">Landed flights: <sonic-value dataProvider="jsonataLanded" key="landed"></sonic-value></template>
35
+ <template data-value="error">Expression error</template>
36
+ </sonic-states>
37
+ </div>
49
38
  </template>
50
39
  </sonic-code>
51
40
 
52
- Pour du multi-entrées ou une fonction TS : primitive [`derive`](#docs/_core-concept/dataFlow.md/dataFlow).
41
+ ## API reference
53
42
 
54
- ## States
43
+ | Attribute | Values | Description |
44
+ |-----------|--------|-------------|
45
+ | `inputProvider` | string | Source data provider, bound to `$input`. Required |
46
+ | `outputProvider` | string | Data provider that receives the result. Required |
47
+ | `expression` | JSONata string (max 8,000 characters) | Expression to evaluate. Required |
48
+ | `formDataProvider` | string | Store whose fields become variables (`$name`) |
49
+ | `outputSchema` | object | Light check of the result: `type` and `required` only; a mismatch sets the `error` state |
50
+
51
+ | Helper | Description |
52
+ |--------|-------------|
53
+ | `$ucFirst(value)` | Upper-cases the first letter |
54
+ | `$currency(value, locale?, currency?)` | Formats a price (default `fr-FR` and `EUR`) |
55
+ | `$percent(value, locale?, digits?)` | Formats a ratio as a percentage (default `fr-FR` and `0` digits) |
56
+ | `$date(value, locale?, optionsJson?)` | Formats a date (default `fr-FR`, medium style) |
57
+ | `$toChart(items, labelKey, valueKey, datasetLabel?)` | Converts rows to `{ labels, datasets }` for a chart |
58
+
59
+ Expressions have no access to the DOM or the network.
55
60
 
56
- `{output}/_state_` → `{ status, error? }` (`loading` | `ready` | `error` | `empty`). Brancher avec `sonic-states`.
61
+ No slots.
File without changes
@@ -1,65 +1,125 @@
1
1
  # List
2
2
 
3
- > **Try offline:** `serviceURL="/docs-mock-api"` and `dataProvider="api/users"` with `key="data"` — see [Local API demos](#docs/_misc/docs-mock-api.md/docs-mock-api). Recommended patterns: [Data flow](#docs/_core-concept/dataFlow.md/dataFlow).
3
+ **`sonic-list`** renders one row per entry of its `props` array, either set directly or loaded with `fetch`. In TypeScript, prefer the `.items` row renderer (with `.separator` · `.noItems` · `.skeleton`); `<template>` children are for plain HTML hosts without Lit. Each row gets its own data provider at `<dataProvider>/list-item/<index>`.
4
4
 
5
- The **sonic-list** component renders one row per entry in **`props`** (array from fetch or set on the element).
5
+ ## Basic example
6
6
 
7
- List extends [Subscriber](#docs/_core-concept/subscriber.md/subscriber) and **Fetcher**:
8
- * **Subscriber** — `props` + `dataProvider`
9
- * **Fetcher** — optional `fetch` + `serviceURL` / `key` (see [Fetch](#core/components/functional/fetch/fetch.md/fetch))
7
+ Add `fetch` to load `props` from `serviceURL` + `endPoint` (or `dataProvider` when `endPoint` is empty). `key` picks the array inside the response. Without `fetch`, the list only renders the `props` it receives.
10
8
 
11
- ## Row renderer (`items`) — recommended
9
+ <sonic-code>
10
+ <template>
11
+ <sonic-list fetch serviceURL="/docs-mock-api" dataProvider="flights?direction=arrivals" key="flights" class="grid gap-1">
12
+ <template>
13
+ <div class="text-sm" data-bind ::inner-html="<b>$time</b> $code from $city ($airport)"></div>
14
+ </template>
15
+ </sonic-list>
16
+ </template>
17
+ </sonic-code>
12
18
 
13
- From a **Lit** parent, pass a function on the **`items`** property (`ListItems`). Each row is wrapped in a `sonic-subscriber` with `dataProvider="…/list-item/n"` (hover rows with `debug`).
19
+ This example uses HTML templates; from Lit, use the [row renderer](#row-renderer) instead. Fetch attributes (`lazyload` · `refetchEveryMs` · headers · authentication) are shared with [Fetch](/core/components/functional/fetch).
14
20
 
15
- ```typescript
16
- private items = ({ first_name, last_name, email, avatar }) => html`
17
- <sonic-image src=${avatar} …></sonic-image>
18
- <div>${first_name} <b>${last_name}</b></div>
19
- <div>${email}</div>
20
- `;
21
+ ## Row renderer
21
22
 
22
- html`<sonic-list
23
- fetch
24
- dataProvider="api/users"
25
- key="data"
26
- serviceURL="/docs-mock-api"
27
- .items=${this.items}
28
- ></sonic-list>`;
29
- ```
30
-
31
- Use **`.items=${fn}`** (property binding): Lit passes functions only as properties, not as HTML attributes — `@property({ type: Function })` does not change that. Same for **`.noItems`**, **`.separator`**, **`.skeleton`**. The callback receives each row object (replacing `data-bind` / `<sonic-value>` in a `<template>`).
32
-
33
- Live demo + TypeScript source (one file, no Markdown copy):
34
-
35
- <docs-lit-demo for="docs-users-list"></docs-lit-demo>
36
-
37
- Implementation: `src/docs/example/docs-users-list.ts` — row markup in the **`items`** callback (`item.first_name`, …), same idea as replacing `data-bind` / `<sonic-value>` in a `<template>`.
38
-
39
- ## Alternating row layouts
40
-
41
- Use **`metadata`** (`even`, `odd`, `firstChild`, …) or fields on each item (e.g. `tpl` with `templateKey`):
23
+ From a Lit component, set `.items` to a function `(item, metadata) => TemplateResult`. Functions only pass as properties, so always use the `.` binding: the same applies to `.separator` · `.noItems` · `.skeleton`. `metadata` holds `key` · `even` · `odd` · `firstChild` · `lastChild` · `onlyChild`.
42
24
 
43
25
  <docs-lit-demo for="docs-list-alternate-demo"></docs-lit-demo>
44
26
 
45
- <docs-lit-demo for="docs-list-template-key-demo"></docs-lit-demo>
27
+ ## Row variants
28
+
29
+ In HTML, `templateKey` (default `template`) names the row field that selects a `<template data-value="…">`. Rows without a match cycle through the `<template>` children that have no `data-value`. From Lit, branch inside the `items` callback instead.
30
+
31
+ <sonic-code>
32
+ <template>
33
+ <sonic-list fetch serviceURL="/docs-mock-api" dataProvider="flights?direction=departures" key="flights" templateKey="status" class="grid gap-1">
34
+ <template>
35
+ <div class="text-sm" data-bind ::inner-html="$code to $city"></div>
36
+ </template>
37
+ <template data-value="delayed">
38
+ <div class="text-sm text-warning" data-bind ::inner-html="$code to $city: delayed"></div>
39
+ </template>
40
+ <template data-value="cancelled">
41
+ <div class="text-sm text-danger line-through" data-bind ::inner-html="$code to $city"></div>
42
+ </template>
43
+ </sonic-list>
44
+ </template>
45
+ </sonic-code>
46
46
 
47
47
  ## Separator and empty list
48
48
 
49
+ `.separator` renders between rows (not after the last one). `.noItems` renders when the array is empty. In HTML, use `<template data-value="separator">` and `<template data-value="no-item">`.
50
+
49
51
  <docs-lit-demo for="docs-list-separator-demo"></docs-lit-demo>
50
52
 
51
- ## Fetch + `extractValues`
53
+ ## Limit and offset
52
54
 
53
- <docs-lit-demo for="docs-list-extract-values-demo"></docs-lit-demo>
55
+ `limit` caps the number of rendered rows and `offset` skips the first ones, without changing the data. With no `limit`, every row is rendered.
54
56
 
55
- ## HTML `<template>` children (integration without Lit)
57
+ <sonic-code>
58
+ <template>
59
+ <sonic-list fetch serviceURL="/docs-mock-api" dataProvider="flights?direction=departures" key="flights" limit="3" class="grid gap-1">
60
+ <template>
61
+ <div class="text-sm" data-bind ::inner-html="<b>$time</b> $code to $city"></div>
62
+ </template>
63
+ </sonic-list>
64
+ </template>
65
+ </sonic-code>
56
66
 
57
- For **plain HTML** hosts, you can still declare **`<template>`** children (and `data-value` for `templateKey`, `separator`, `no-item`). That path is for [HTML integration](#docs/_misc/html-integration.md/html-integration) — not used in Concorde doc live demos.
67
+ ## Objects and `extractValues`
58
68
 
59
- Each list row still gets `dataProvider="[list]/list-item/[index]"`.
69
+ When the data is an object, the list wraps it in a one-row array. Add `extractValues` to render one row per property instead, as `{ key, value }`.
60
70
 
61
- ## Additionnal tips
71
+ <docs-lit-demo for="docs-list-extract-values-demo"></docs-lit-demo>
62
72
 
63
- * If the request returns an object, it is wrapped in an array (unless `extractValues` is set).
64
- * Call **`invalidate()`** on the list publisher to reload fetch data.
65
- * Each row publisher exposes **`_parent_`** pointing at the list publisher.
73
+ ## Loading state
74
+
75
+ With no `loader`, nothing is shown while fetching. Set `loader` (`fixed`) or `loader="inline"` to show a [Loader](/core/components/ui/loader), or provide `.skeleton` / `<template skeleton>` to render placeholder rows; a skeleton replaces the loader. Call `invalidate()` on the list publisher to fetch again.
76
+
77
+ <sonic-code>
78
+ <template>
79
+ <sonic-list fetch loader="inline" serviceURL="/docs-mock-api" dataProvider="flights?direction=arrivals&status=landed" key="flights" class="grid gap-1">
80
+ <template>
81
+ <div class="text-sm" data-bind ::inner-html="$code from $city: landed"></div>
82
+ </template>
83
+ </sonic-list>
84
+ </template>
85
+ </sonic-code>
86
+
87
+ ## API reference
88
+
89
+ | Attribute | Values | Description |
90
+ |-----------|--------|-------------|
91
+ | `dataProvider` | string | Publisher of the list. Also the endpoint when `endPoint` is empty. Inherited from ancestors |
92
+ | `fetch` | boolean | Loads `props` from the API. Without it, the list never fetches |
93
+ | `serviceURL` · `endPoint` · `key` | string | Request configuration, see [Fetch](/core/components/functional/fetch) |
94
+ | `templateKey` | string (default `template`) | Row field that selects a `<template data-value>` |
95
+ | `extractValues` | boolean | Renders an object as one `{ key, value }` row per property |
96
+ | `limit` | number (default unlimited) | Maximum number of rendered rows |
97
+ | `offset` | number (default `0`) | Index of the first rendered row |
98
+ | `loader` | `fixed` (when empty) · `inline` | Loader shown while fetching. None by default |
99
+ | `debug` | boolean | Shows each row's data on hover |
100
+
101
+ Properties (TypeScript / Lit, preferred):
102
+
103
+ | Property | Type | Description |
104
+ |----------|------|-------------|
105
+ | `props` | array · object | Rows to render |
106
+ | `items` | `(item, metadata) => TemplateResult` | Row renderer |
107
+ | `separator` | `() => TemplateResult` | Rendered between rows |
108
+ | `noItems` | `() => TemplateResult` | Rendered when there are no rows |
109
+ | `skeleton` | `() => TemplateResult` | Rendered while fetching |
110
+ | `itemPropertyMap` | object | `propertyMap` passed to each row subscriber |
111
+
112
+ Templates (plain HTML hosts):
113
+
114
+ | Template | Description |
115
+ |----------|-------------|
116
+ | `<template>` | Row markup; several are used in turn |
117
+ | `<template data-value="…">` | Row variant selected by `templateKey` |
118
+ | `<template data-value="separator">` | Between rows |
119
+ | `<template data-value="no-item">` | Empty list |
120
+ | `<template skeleton>` | While fetching |
121
+
122
+ | Event | Description |
123
+ |-------|-------------|
124
+ | `loading` | A fetch starts |
125
+ | `load` | Data is loaded and assigned to `props` |
@@ -339,10 +339,23 @@ export class List extends Fetcher(Subscriber(TemplatesContainer(LitElement))) {
339
339
  };
340
340
 
341
341
  childPublisher._key_ = key + "";
342
- childPublisher._metadata_ = {
343
- ...childPublisher._metadata_.get(),
344
- ...metadata,
345
- };
342
+ // Immutable store: assigning `_metadata_` every render rebuilds the item + list
343
+ // publisher and retriggers render → infinite loop. Only write when values change.
344
+ const previousMetadata =
345
+ childPublisher._metadata_?.get() as ListItemMetadata | null;
346
+ if (
347
+ previousMetadata?.key !== metadata.key ||
348
+ previousMetadata?.even !== metadata.even ||
349
+ previousMetadata?.odd !== metadata.odd ||
350
+ previousMetadata?.onlyChild !== metadata.onlyChild ||
351
+ previousMetadata?.firstChild !== metadata.firstChild ||
352
+ previousMetadata?.lastChild !== metadata.lastChild
353
+ ) {
354
+ childPublisher._metadata_ = {
355
+ ...(previousMetadata || {}),
356
+ ...metadata,
357
+ };
358
+ }
346
359
 
347
360
  // Essayer d'utiliser les templates programmatiques
348
361
  const programmaticTemplate = this.handleProgrammaticTemplates(
@@ -1,41 +1,46 @@
1
1
  # Mix
2
2
 
3
- Mix allows you to mix several subsets of dataProvider in a new key/value structure which is itself associated with a new dataProvider. The data update is then bidirectional.
3
+ **`sonic-mix`** builds a new data provider from parts of other ones. Each key of `composition` maps to a source data provider id, with an optional dot path to a sub-value. The mixed provider is named by the `dataProvider` attribute and stays in sync with its sources in both directions.
4
4
 
5
- Dot notation is supported to extract a sub-part of the data.
5
+ ## Basic example
6
+
7
+ Two sources hold the flight and its gate. The mix exposes the whole flight under `flight` and only the gate number under `gate`; children read them like any other data provider.
6
8
 
7
- For example, if we declare dataproviders as follows :
8
- <sonic-code>
9
- <template>
10
- <sonic-subscriber dataProvider="dataToMixA" props='{"foo":{"bar":2}}'></sonic-subscriber>
11
- <sonic-subscriber dataProvider="dataToMixB" props='{"baz":3}'></sonic-subscriber>
12
- </template>
13
- </sonic-code>
14
- We can rearrange the data as follows
15
9
  <sonic-code>
16
10
  <template>
17
- <sonic-mix dataProvider="mixedData" composition='{"either":"dataToMixB","orThat":"dataToMixA.foo.bar"}'>
18
- <div>Value of dataToMixA.foo.bar and mixedData.orThat : <sonic-value key="orThat"></sonic-value></div>
19
- <div>Value of dataToMixB.baz and mixedData.either.baz : <sonic-value key="either.baz"></sonic-value></div>
11
+ <sonic-subscriber dataProvider="docs-mix-flight" props='{"code":"CN 001","route":"CDG → JFK"}'></sonic-subscriber>
12
+ <sonic-subscriber dataProvider="docs-mix-gate" props='{"gate":"B12","terminal":"2E"}'></sonic-subscriber>
13
+ <sonic-mix dataProvider="docs-mix-board" composition='{"flight":"docs-mix-flight","gate":"docs-mix-gate.gate"}'>
14
+ <p>
15
+ <sonic-value key="flight.code"></sonic-value> ·
16
+ <sonic-value key="flight.route"></sonic-value> ·
17
+ gate <sonic-value key="gate"></sonic-value>
18
+ </p>
20
19
  </sonic-mix>
21
20
  </template>
22
21
  </sonic-code>
23
- Then we can change values in both dataProviders programaticaly this way, they will stay in sync
24
- <sonic-code language="javascript">
22
+
23
+ ## Two-way sync
24
+
25
+ Writing to a source updates the mix, and writing to the mix updates the source. The button changes `docs-mix-gate`; the field writes to `docs-mix-board.gate`.
26
+
27
+ <sonic-code>
25
28
  <template>
26
- SonicPublisherManager.get("mixedData").either.baz=6;
27
- SonicPublisherManager.get("dataToMixB").baz=8;
28
- SonicPublisherManager.get("dataToMixA").foo.bar=8;
29
- SonicPublisherManager.get("mixedData").orThat=6;
29
+ <div class="flex flex-wrap items-end gap-4">
30
+ <sonic-button size="sm" onclick="SonicPublisherManager.get('docs-mix-gate').gate = 'C34'">Gate change to C34</sonic-button>
31
+ <sonic-input label="Gate (mixed provider)" formDataProvider="docs-mix-board" name="gate"></sonic-input>
32
+ </div>
33
+ <p class="mt-2">Source gate: <sonic-value dataProvider="docs-mix-gate" key="gate"></sonic-value></p>
30
34
  </template>
31
35
  </sonic-code>
32
- Or by using a form element
33
- <sonic-code>
34
- <template>
35
- <sonic-input label="mixedData.orThat" formDataProvider="mixedData" name="orThat"></sonic-input>
36
- </template>
37
- </sonic-code>
38
-
39
36
 
37
+ ## API reference
40
38
 
39
+ | Attribute | Values | Description |
40
+ |-----------|--------|-------------|
41
+ | `dataProvider` | string | Id of the mixed data provider. Its content is reset when the composition changes |
42
+ | `composition` | object (JSON) | Keys of the mixed provider mapped to `"providerId"` or `"providerId.path.to.value"` |
41
43
 
44
+ | Slot | Description |
45
+ |------|-------------|
46
+ | *(default)* | Content that reads the mixed provider |
@@ -4,19 +4,21 @@ import { customElement } from "lit/decorators.js";
4
4
  import "./queue";
5
5
  import { tailwind } from "../../../../docs/tailwind";
6
6
 
7
+ type FlightRow = { code: string; city: string; airport: string; time: string };
8
+
7
9
  @customElement("sonic-queue-demo")
8
10
  export class QueueDemo extends LitElement {
9
11
  static styles = [tailwind];
10
12
 
11
- private items = (item: any) => html`
13
+ private items = (item: FlightRow) => html`
12
14
  <div class="bg-neutral-100 p-2 rounded-md">
13
- <div class="font-medium">${item.nom}</div>
14
- <div class="text-sm text-gray-600">Code: ${item.code}</div>
15
+ <div class="font-medium">${item.code} · ${item.city}</div>
16
+ <div class="text-sm text-gray-600">${item.airport} · ${item.time}</div>
15
17
  </div>
16
18
  `;
17
19
  private noItems = () => html`
18
20
  <div class="flex flex-col items-center justify-center p-4 text-gray-500">
19
- <p>Aucune commune trouvée</p>
21
+ <p>No flight found</p>
20
22
  </div>
21
23
  `;
22
24
 
@@ -24,9 +26,10 @@ export class QueueDemo extends LitElement {
24
26
  return html`
25
27
  <sonic-queue
26
28
  class="grid grid-cols-3 gap-3"
27
- serviceurl="/docs-mock-api/geo/"
28
- dataproviderexpression="communes?limit=$limit"
29
- limit="30"
29
+ serviceURL="/docs-mock-api"
30
+ dataProviderExpression="flights?limit=$limit"
31
+ key="flights"
32
+ limit="15"
30
33
  .items=${this.items}
31
34
  .noItems=${this.noItems}
32
35
  ></sonic-queue>
@@ -1,72 +1,51 @@
1
1
  # Queue
2
2
 
3
- > **Try offline:** `serviceURL="/docs-mock-api"` — see [Local API demos](#docs/_misc/docs-mock-api.md/docs-mock-api). Row rendering: [Data flow](#docs/_core-concept/dataFlow.md/dataFlow) (`.items` property binding).
3
+ **`sonic-queue`** loads a paginated API in batches and renders each batch as an internal [List](/core/components/functional/list). Choose it over `sonic-list` for long or endless lists; the key attributes are `dataProviderExpression` · `limit` · `dataFilterProvider`.
4
4
 
5
- **sonic-queue** loads data in **batches**. Each batch is an internal [List](#core/components/functional/list/list.md/list) with its own `dataProvider` (`…/list-item/0`, `…/1`, …).
5
+ ## Lazy load
6
6
 
7
- | Mechanism | Role |
8
- |-----------|------|
9
- | **`dataProviderExpression`** | API path template; `$offset` and `$limit` are replaced per batch |
10
- | **`lazyload`** | Load the next batch when the user scrolls near the end |
11
- | **`dataFilterProvider`** | Publisher id of a form (`formDataProvider`); field values are merged into the request query string |
12
- | **`filteredFields`** | Optional list of form field names to **exclude** from the query (space-separated) — omit when every field should be sent |
13
- | **`.items`**, **`.noItems`**, **`.separator`**, **`.skeleton`** | Lit callbacks forwarded to each batch list (use the **dot** — functions are properties, not attributes) |
7
+ `dataProviderExpression` is the request path: `$offset` and `$limit` are replaced for each batch. The first batch starts at `offset` (default `0`) with `limit` rows (default `5`, at most `15`). The next batch loads when the end of the list scrolls into view, and the queue stops at the first empty batch. Put the queue in a box with a fixed height and `overflow-y-auto`, then scroll inside it.
14
8
 
15
- ## Lazy load — `$offset` and `$limit`
9
+ <docs-lit-demo for="docs-queue-geo-demo"></docs-lit-demo>
16
10
 
17
- When the expression contains **`$offset`** and **`$limit`**, the queue:
11
+ Rows come from the `.items` callback, as on [List](/core/components/functional/list); `.noItems` and `.skeleton` work the same way. Without `$offset` in the expression, the queue sends one request and behaves like a list. Set `noLazyload` to load every batch in a row without waiting for the scroll.
18
12
 
19
- 1. Fetches the first batch with `offset=0` (or the initial `offset` attribute) and `per_page=$limit`.
20
- 2. On scroll, appends a batch with `offset` increased by the previous batch size.
21
- 3. Stops when a batch returns fewer rows than `limit` (or none).
13
+ ## Filters
22
14
 
23
- The doc mock implements this on `GET /docs-mock-api/api/users?offset=…&per_page=…` (`paginateUsers` in `src/docs/mock-api/router.ts`).
15
+ `dataFilterProvider` names a form store (`formDataProvider`). Each non-empty field is added to the query string; when a field changes, the queue drops the loaded batches and reloads from the first offset, after a `filterTimeoutMs` debounce (default `400`). Search a city, an airport or a flight number.
24
16
 
25
17
  <docs-lit-demo for="docs-queue-users-demo"></docs-lit-demo>
26
18
 
27
- Wrap the queue in a **fixed height** with **`overflow-y-auto`** so lazy load triggers when scrolling inside the box (same layout as the [TS starter](https://github.com/supersoniks/create-concorde-ts-starter) `demo-queue-templates`).
28
-
29
- Try scrolling after load — batches of 4 users. Search e.g. `George`, `Bluth`, or `zzz` for empty results.
30
-
31
- ### Expression example
32
-
33
- ```typescript
34
- html`<sonic-queue
35
- lazyload
36
- serviceURL="/docs-mock-api"
37
- dataProviderExpression="api/users?offset=$offset&limit=$limit"
38
- key="data"
39
- limit="4"
40
- class="grid max-h-96 overflow-y-auto"
41
- .items=${this.renderUser}
42
- ></sonic-queue>`;
43
- ```
44
-
45
- Without **`$offset`** in the expression, the queue behaves like a single list (one batch), e.g. geo communes below.
46
-
47
- ## Filter — `dataFilterProvider` + `q`
48
-
49
- One search field (`name="q"`) on `formDataProvider="filter"`. The queue listens via **`dataFilterProvider="filter"`** and, on change:
50
-
51
- 1. Resets loaded batches.
52
- 2. Appends each non-empty form field to the query (here only **`q`** — no `filteredFields` needed).
53
- 3. Fetches again from offset `0`.
54
-
55
- Use **`filteredFields`** only when the form has extra fields that must **not** be sent to the API (e.g. `filteredFields="rememberMe internalId"`).
56
-
57
- The mock API filters before pagination — same haystack logic as the starter (`filterDocsUsers` in `src/docs/mock-api/fixtures.ts`, used by `paginateUsers` in `router.ts` / Service Worker):
58
-
59
- ```typescript
60
- const haystack = `${first_name} ${last_name} ${email}`.toLowerCase();
61
- return haystack.includes(q);
62
- ```
63
-
64
- ## Simple batch (no lazy scroll)
65
-
66
- Geo communes: expression uses **`$limit` only** (no `$offset`) — one request, one batch.
67
-
68
- <docs-lit-demo for="docs-queue-geo-demo"></docs-lit-demo>
69
-
70
- ## HTML `<template>` children
71
-
72
- Optional for hosts without Lit — see [HTML integration](#docs/_misc/html-integration.md/html-integration).
19
+ To keep some form fields out of the request, list their names in `filteredFields`, separated by spaces.
20
+
21
+ ## API reference
22
+
23
+ | Attribute | Values | Description |
24
+ |-----------|--------|-------------|
25
+ | `dataProviderExpression` | string (default: closest ancestor `dataProvider`) | Request path; `$offset` and `$limit` are replaced for each batch |
26
+ | `serviceURL` | string | API base URL; inherited from the closest ancestor |
27
+ | `key` | string | Response property that holds the rows |
28
+ | `limit` | number (default `5`, max `15`) | Rows per batch |
29
+ | `offset` | number (default `0`) | Offset of the first batch |
30
+ | `idKey` | string (default `id`) | Row property used as identity |
31
+ | `dataFilterProvider` | string | Form store whose fields are added to the query; inherited from the closest ancestor |
32
+ | `filteredFields` | space-separated names | Form fields not sent to the API |
33
+ | `filterTimeoutMs` | number (default `400`) | Debounce before reloading after a filter change |
34
+ | `noLazyload` | boolean | Loads all batches without waiting for the scroll |
35
+ | `lazyBoundsRatio` | number (default `1`) | Lazy-load margin, as a multiple of the viewport size |
36
+ | `loader` | `inline` · `fixed` (default `inline`) | Loader shown while a batch loads |
37
+ | `cache` | `RequestCache` (default `default`) | Fetch cache mode |
38
+ | `invalidateOnPageShow` | boolean | Reloads batches when the page is restored from the back/forward cache |
39
+ | `localStorage` | `disabled` · `enabled` (default `disabled`) | Forwarded to each batch list |
40
+ | `debug` | boolean | Shows a live inspector of each batch list's data |
41
+
42
+ | Property | Type | Description |
43
+ |----------|------|-------------|
44
+ | `items` | `ListItems` | Row renderer |
45
+ | `noItems` | `ListItems` | Rendered when the first batch is empty |
46
+ | `skeleton` | `ListItems` | Rendered while a batch loads |
47
+ | `itemPropertyMap` | object | Forwarded to each batch list |
48
+
49
+ The queue publisher exposes `resultCount`, the number of rows loaded so far.
50
+
51
+ No slots. `<template>` children are used as row templates for hosts without Lit; see [HTML integration](/docs/misc/html-integration).
@@ -5,7 +5,7 @@ import { Routes } from "@supersoniks/concorde/core/utils/route";
5
5
 
6
6
  import { tailwind } from "../../../../docs/tailwind";
7
7
  const defaultRoute = {
8
- user: "#user/:id/:slug",
8
+ flight: "#flights/:code",
9
9
  };
10
10
  export type AppRoutes = typeof defaultRoute;
11
11
 
@@ -17,28 +17,28 @@ export class RouterDemo extends LitElement {
17
17
 
18
18
  @state()
19
19
  private routes = {
20
- "#home": () => html`
20
+ "#departures": () => html`
21
21
  <div class="p-4 border border-gray-200 rounded-md">
22
- <h1 class="text-xl font-medium mb-2">Accueil</h1>
23
- <p class="text-gray-600">Bienvenue sur la démo du router</p>
22
+ <h1 class="text-xl font-medium mb-2">Departures</h1>
23
+ <p class="text-gray-600">CN 001 to New York boards at gate B12.</p>
24
24
  </div>
25
25
  `,
26
- [defaultRoute.user]: ({ slug, id }: { id: string; slug: string }) => html`
26
+ [defaultRoute.flight]: ({ code }: { code: string }) => html`
27
27
  <div class="p-4 border border-gray-200 rounded-md">
28
- <h1 class="text-xl font-medium mb-2">Profil Utilisateur ${id}</h1>
29
- <p class="text-gray-600">Slug: ${slug}</p>
28
+ <h1 class="text-xl font-medium mb-2">Flight ${code}</h1>
29
+ <p class="text-gray-600">CDG → JFK</p>
30
30
  </div>
31
31
  `,
32
- "#products/(\\d+)/(\\w+)": ([id, slug]: [string, string]) => html`
32
+ "#gates/([A-Z])(\\d+)": ([terminal, gate]: [string, string]) => html`
33
33
  <div class="p-4 border border-gray-200 rounded-md">
34
- <h1 class="text-xl font-medium mb-2">Produit ${id}</h1>
35
- <p class="text-gray-600">Slug: ${slug}</p>
34
+ <h1 class="text-xl font-medium mb-2">Terminal ${terminal}</h1>
35
+ <p class="text-gray-600">Gate ${gate}</p>
36
36
  </div>
37
37
  `,
38
38
  fallback: () => html`
39
39
  <div class="p-4 border border-red-200 bg-red-50 rounded-md">
40
40
  <h1 class="text-xl font-medium text-red-800 mb-2">404</h1>
41
- <p class="text-red-600">Page non trouvée</p>
41
+ <p class="text-red-600">Page not found</p>
42
42
  </div>
43
43
  `,
44
44
  };
@@ -46,13 +46,13 @@ export class RouterDemo extends LitElement {
46
46
  render() {
47
47
  return html`
48
48
  <div class="p-4">
49
- <h2 class="text-2xl font-medium mb-6">Démo du router</h2>
49
+ <h2 class="text-2xl font-medium mb-6">Router demo</h2>
50
50
 
51
51
  <div class="flex gap-4 mb-6">
52
- <sonic-button href="#home"> Accueil </sonic-button>
53
- <sonic-button href="#user/123/mySlug"> Utilisateur 123 </sonic-button>
54
- <sonic-button href="#products/456/mySlug"> Produit 456 </sonic-button>
55
- <sonic-button href="#invalid"> 404 </sonic-button>
52
+ <sonic-button href="#departures">Departures</sonic-button>
53
+ <sonic-button href="#flights/CN001">Flight CN 001</sonic-button>
54
+ <sonic-button href="#gates/B12">Gate B12</sonic-button>
55
+ <sonic-button href="#invalid">404</sonic-button>
56
56
  </div>
57
57
 
58
58
  <sonic-router .routes=${this.routes}></sonic-router>