@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
@@ -0,0 +1,36 @@
1
+ # Installation
2
+
3
+ Start a new project from the official starter. It sets up Vite, TypeScript, Lit, Tailwind and Concorde in one command.
4
+
5
+ ## Use the starter
6
+
7
+ <sonic-code language="shell">
8
+ <template>
9
+ npx @supersoniks/create-concorde-ts-starter my-app
10
+ cd my-app
11
+ yarn install
12
+ yarn dev --host
13
+ </template>
14
+ </sonic-code>
15
+
16
+ The project includes:
17
+
18
+ - an example component to copy from
19
+ - `npx concorde enable-short-paths` for short import paths
20
+ - `yarn ai:sync` for [AI agent skills](/docs/getting-started/ai-agents)
21
+
22
+ Package: [create-concorde-ts-starter](https://www.npmjs.com/package/@supersoniks/create-concorde-ts-starter).
23
+
24
+ ## Stack
25
+
26
+ | Tool | Role |
27
+ |------|------|
28
+ | [Lit](https://lit.dev) | Base class, templates and reactive properties for web components |
29
+ | [TypeScript](https://www.typescriptlang.org) | Decorators and typed store paths |
30
+ | [Vite](https://vite.dev) | Dev server and build |
31
+ | [Tailwind](https://tailwindcss.com) | Optional, layout in your components. Concorde components ship their own styles, driven by [theme](/docs/getting-started/theming) variables |
32
+
33
+ ## Gotchas
34
+
35
+ - `yarn dev` does not type-check. Run `tsc --noEmit` or a production build to catch type errors.
36
+ - Scripts that query the global document (`document.querySelector`, jQuery plugins, icon replacers) cannot see inside a shadow root. Query from the component's `renderRoot`, or pass the element as slotted content.
@@ -0,0 +1,227 @@
1
+ # My first component
2
+
3
+ Build a **Lit** user card with Tailwind and Concorde UI, then connect it to the **DataProvider** store: declare the **data configuration** (type, key, scope), and let **`@subscribe`** keep the card in sync.
4
+
5
+ ## 1. Lit component + Tailwind
6
+
7
+ Export Tailwind once (e.g. `src/docs/tailwind.ts` in this repo):
8
+
9
+ <sonic-code language="typescript">
10
+ <template>
11
+ import { css, unsafeCSS } from "lit";
12
+ import tailwindImport from "./css/tailwind.css?inline";
13
+
14
+ export const tailwind = css`${unsafeCSS(tailwindImport)}`;
15
+ </template>
16
+ </sonic-code>
17
+
18
+ User card — plain Lit properties and UI components (no store yet):
19
+
20
+ <sonic-code language="typescript">
21
+ <template>
22
+ import { html, LitElement } from "lit";
23
+ import { customElement, property } from "lit/decorators.js";
24
+ import { tailwind } from "../tailwind";
25
+
26
+ @customElement("docs-user")
27
+ export class DocsUser extends LitElement {
28
+ static styles = [tailwind];
29
+
30
+ @property({ type: String }) first_name = "";
31
+ @property({ type: String }) last_name = "";
32
+ @property({ type: String }) email = "";
33
+ @property({ type: String }) avatar = "";
34
+
35
+ render() {
36
+ return html`&lt;div class="flex items-center gap-3 rounded-md p-2"&gt;
37
+ &lt;sonic-image src=${this.avatar} rounded="md" ratio="1/1" class="w-16"&gt;&lt;/sonic-image&gt;
38
+ &lt;div&gt;
39
+ &lt;div&gt;${this.first_name} &lt;span class="font-bold"&gt;${this.last_name}&lt;/span&gt;&lt;/div&gt;
40
+ &lt;div class="text-sm text-neutral-400"&gt;${this.email}&lt;/div&gt;
41
+ &lt;/div&gt;
42
+ &lt;/div&gt;`;
43
+ }
44
+ }
45
+ </template>
46
+ </sonic-code>
47
+
48
+ ## 2. Data configuration
49
+
50
+ The card does not hard-code user fields anymore. You declare **what** is stored, **where** it lives, and **which ancestor scope** applies — then `@subscribe` mirrors that object on the component.
51
+
52
+ ### Type — shape of the data
53
+
54
+ `DocsUserData` documents the fields you expect at this scope (first name, email, avatar, …). TypeScript checks that `user` matches that shape.
55
+
56
+ <sonic-code language="typescript">
57
+ <template>
58
+ export type DocsUserData = {
59
+ first_name: string;
60
+ last_name: string;
61
+ email: string;
62
+ avatar: string;
63
+ };
64
+ </template>
65
+ </sonic-code>
66
+
67
+ ### Key — path in the DataProvider
68
+
69
+ `docsUserRowKey` points at the store segment to read. The path `"${dataProvider}"` is resolved at runtime from a property on the component (see scope below).
70
+
71
+ <sonic-code language="typescript">
72
+ <template>
73
+ import { DataProviderKey } from "@supersoniks/concorde/core/utils/dataProviderKey";
74
+
75
+ export const docsUserRowKey = new DataProviderKey&lt;
76
+ DocsUserData,
77
+ { dataProvider: string | null }
78
+ &gt;("${dataProvider}");
79
+ </template>
80
+ </sonic-code>
81
+
82
+ The second generic (`{ dataProvider: string | null }`) lists what the host must expose so `"${dataProvider}"` can be resolved. See [DataProviderKey](/docs/misc/dataProviderKey) and [Dynamic path placeholders](/docs/misc/dynamic-path).
83
+
84
+ ### Scope — which store segment applies
85
+
86
+ A parent sets `dataProvider=${docsUserScopeAKey.path}` (or a list row sets `…/list-item/0`). [`@ancestorAttribute`](/docs/decorators/ancestor-attribute) copies that attribute onto `this.dataProvider`, so the key resolves to the correct branch.
87
+
88
+ <sonic-code language="typescript">
89
+ <template>
90
+ @ancestorAttribute("dataProvider")
91
+ dataProvider: string | null = null;
92
+ </template>
93
+ </sonic-code>
94
+
95
+ ### Subscribe — keep the card in sync
96
+
97
+ [`@subscribe`](/docs/decorators/subscribe) watches `docsUserRowKey` and updates `user` when the store changes. Use `@state()` so Lit re-renders. The template reads `this.user` like any other property.
98
+
99
+ <sonic-code language="typescript">
100
+ <template>
101
+ import { html, LitElement, nothing } from "lit";
102
+ import { customElement, state } from "lit/decorators.js";
103
+ import {
104
+ ancestorAttribute,
105
+ subscribe,
106
+ } from "@supersoniks/concorde/core/decorators/Subscriber";
107
+ import { docsUserRowKey, type DocsUserData } from "./users";
108
+ import { tailwind } from "../tailwind";
109
+
110
+ @customElement("docs-user")
111
+ export class DocsUser extends LitElement {
112
+ static styles = [tailwind];
113
+
114
+ @ancestorAttribute("dataProvider")
115
+ dataProvider: string | null = null;
116
+
117
+ @subscribe(docsUserRowKey)
118
+ @state()
119
+ user: DocsUserData | null = null;
120
+
121
+ render() {
122
+ const u = this.user;
123
+ if (!u) return nothing;
124
+ return html`&lt;div class="flex items-center gap-3 rounded-md p-2"&gt;
125
+ &lt;sonic-image src=${u.avatar} rounded="md" ratio="1/1" class="w-16"&gt;&lt;/sonic-image&gt;
126
+ &lt;div&gt;
127
+ &lt;div&gt;${u.first_name} &lt;span class="font-bold"&gt;${u.last_name}&lt;/span&gt;&lt;/div&gt;
128
+ &lt;div class="text-sm text-neutral-400"&gt;${u.email}&lt;/div&gt;
129
+ &lt;/div&gt;
130
+ &lt;/div&gt;`;
131
+ }
132
+ }
133
+ </template>
134
+ </sonic-code>
135
+
136
+ Live code: `src/docs/example/users.ts`. In this repo, imports use **`core/…` paths** (short `@supersoniks/concorde/…` exports apply in **consumer apps** only).
137
+
138
+ ### Two scopes, one component
139
+
140
+ The same `docs-user` is mounted twice. Each copy inherits a **different** nearest `dataProvider` — that is the row/list **scope**:
141
+
142
+ <sonic-code>
143
+ <template>
144
+ <docs-demo-sources for="docs-user-two-scopes"></docs-demo-sources>
145
+ <docs-user-two-scopes></docs-user-two-scopes>
146
+ </template>
147
+ </sonic-code>
148
+
149
+ Markup (two isolated stores; keys from `docs-provider-keys.ts`):
150
+
151
+ <sonic-code language="markup">
152
+ <template>
153
+ &lt;div class="grid md:grid-cols-2 gap-6"&gt;
154
+ &lt;div dataProvider="${docsUserScopeAKey.path}"&gt;
155
+ &lt;docs-user&gt;&lt;/docs-user&gt;
156
+ &lt;/div&gt;
157
+ &lt;div dataProvider="${docsUserScopeBKey.path}"&gt;
158
+ &lt;docs-user&gt;&lt;/docs-user&gt;
159
+ &lt;/div&gt;
160
+ &lt;/div&gt;
161
+ </template>
162
+ </sonic-code>
163
+
164
+ Seeded in `docs-provider-keys.ts` (`set(docsUserScopeAKey, …)`): **Paul** / **Marie**. Without `@ancestorAttribute`, both cards would not know which store to read.
165
+
166
+ ## 3. Fetch users — `sonic-list` with `.items`
167
+
168
+ Use a Lit parent and the **`items`** renderer (not HTML `<template>` children). The callback receives each row object from fetch — render fields directly (`${item.first_name}`, …), like porting a template that used `data-bind` / `<sonic-value>`.
169
+
170
+ <sonic-code>
171
+ <template>
172
+ <docs-lit-demo for="docs-users-list"></docs-lit-demo>
173
+ </template>
174
+ </sonic-code>
175
+
176
+ Wrapper (`docs-users-list.ts`):
177
+
178
+ <sonic-code language="typescript">
179
+ <template>
180
+ import { html, LitElement } from "lit";
181
+ import { customElement } from "lit/decorators.js";
182
+ import "../../core/components/functional/list/list";
183
+ import "./users";
184
+
185
+ @customElement("docs-users-list")
186
+ export class DocsUsersList extends LitElement {
187
+ private items = ({ first_name, last_name, email, avatar }) => html`
188
+ &lt;div class="flex gap-3"&gt;
189
+ &lt;sonic-image src=${avatar} ...&gt;&lt;/sonic-image&gt;
190
+ &lt;div&gt;${first_name} &lt;b&gt;${last_name}&lt;/b&gt;&lt;/div&gt;
191
+ &lt;div class="text-sm text-neutral-400"&gt;${email}&lt;/div&gt;
192
+ &lt;/div&gt;
193
+ `;
194
+
195
+ render() {
196
+ return html`
197
+ &lt;sonic-list fetch dataProvider=${usersListEndpoint.path} key="data" .items=${this.items}&gt;&lt;/sonic-list&gt;
198
+ `;
199
+ }
200
+ }
201
+ </template>
202
+ </sonic-code>
203
+
204
+ See [Local API demos](/docs/misc/docs-mock-api) for `serviceURL="/docs-mock-api"`.
205
+
206
+ ## 4. Form preview with `formDataProvider`
207
+
208
+ Edit fields in a form; the card follows the same `docsUserRowKey` when the preview host sets `dataProvider="userPreview"`.
209
+
210
+ <sonic-code>
211
+ <template>
212
+ <div class="grid grid-cols-1 gap-4 max-w-xl">
213
+ <form formDataProvider="${docsUserPreviewKey.path}" class="grid grid-cols-2 gap-3">
214
+ <sonic-input label="First name" name="first_name" value="Paul" size="sm"></sonic-input>
215
+ <sonic-input label="Last name" name="last_name" value="Metrand" size="sm"></sonic-input>
216
+ <sonic-input class="col-span-2" label="Email" name="email" value="paul@example.com" size="sm"></sonic-input>
217
+ <sonic-input class="col-span-2" label="Avatar URL" name="avatar" value="https://i.pravatar.cc/150?u=paul" size="sm"></sonic-input>
218
+ </form>
219
+ <sonic-divider align="left">Preview</sonic-divider>
220
+ <div dataProvider="${docsUserPreviewKey.path}">
221
+ <docs-user></docs-user>
222
+ </div>
223
+ </div>
224
+ </template>
225
+ </sonic-code>
226
+
227
+ Use `formDataProvider` + `name` on inputs — no manual `@input` handlers ([Data flow](/docs/getting-started/dataFlow)).
@@ -0,0 +1,35 @@
1
+ # Introduction
2
+
3
+ ## What is Concorde?
4
+
5
+ Based on **[lit.dev](https://lit.dev)**, Concorde is a collection of web components for shared apps and websites.
6
+ Build UIs without tying components to a specific host stack, while keeping visual consistency through the smallest set of CSS variables needed to define a theme.
7
+
8
+ ## Why and use case
9
+
10
+ In 2022, Supersoniks needed a new ticketing stack for nearly 100 sites — mobile apps, modern sites, and legacy PHP without bundlers.
11
+ One composable web-component library replaced many one-off apps. Lit was chosen for broad runtime compatibility.
12
+
13
+ ### Stack
14
+
15
+ * Lit
16
+ * TypeScript
17
+ * Vite
18
+ * Tailwind (starter kit, not required in the core package)
19
+
20
+ ### Functional features
21
+
22
+ * **DataProvider** store (decorators, `get` / `set`)
23
+ * Forms (`formDataProvider`)
24
+ * Lists, queues, lazy loading
25
+ * Router, states, UI kit with status variants
26
+
27
+ ## Start a new project
28
+
29
+ <sonic-code language="bash">
30
+ <template>
31
+ npx @supersoniks/create-concorde-ts-starter "project_name"
32
+ </template>
33
+ </sonic-code>
34
+
35
+ The starter runs **`yarn ai:sync`** for you. Details: [AI agents (skills)](/docs/getting-started/ai-agents).
@@ -120,11 +120,13 @@ export class SonicComponent extends Subscriber(LitElement) {
120
120
  }
121
121
  });
122
122
 
123
- // on hash change, hide search and mobile navigation
124
- window.addEventListener("hashchange", () => {
123
+ // on navigation, hide search and mobile navigation
124
+ const onNav = () => {
125
125
  this.hideSearch();
126
126
  this.closeNavigation();
127
- });
127
+ };
128
+ window.addEventListener("hashchange", onNav);
129
+ window.addEventListener("popstate", onNav);
128
130
  }
129
131
 
130
132
  handleColorScheme() {
@@ -181,7 +183,7 @@ export class SonicComponent extends Subscriber(LitElement) {
181
183
  <sonic-icon name="menu" library="iconoir"></sonic-icon>
182
184
  </sonic-button>
183
185
  <div class="min-w-0">
184
- <sonic-link href="/" class="logo flex items-end gap-x-1">
186
+ <sonic-link pushState href="/" class="logo flex items-end gap-x-1">
185
187
  <svg
186
188
  class="size-8 sm:size-[2.4rem] inline-block rotate-[55deg]"
187
189
  viewBox="0 0 66 66"
@@ -217,14 +219,16 @@ export class SonicComponent extends Subscriber(LitElement) {
217
219
  class="hidden md:block"
218
220
  variant="ghost"
219
221
  size="sm"
220
- href="#docs/_getting-started/start.md/start"
222
+ pushState
223
+ href="/docs/getting-started/start"
221
224
  >Docs</sonic-button
222
225
  >
223
226
  <sonic-button
224
227
  class="hidden md:block"
225
228
  variant="ghost"
226
229
  size="sm"
227
- href="#docs/_getting-started/components.md/components"
230
+ pushState
231
+ href="/docs/getting-started/components"
228
232
  >Components</sonic-button
229
233
  >
230
234
  <sonic-button
@@ -375,6 +379,7 @@ export class SonicComponent extends Subscriber(LitElement) {
375
379
  <docs-search
376
380
  setFocus
377
381
  class="max-w-[30rem] lg:max-w-[35rem] w-full block"
382
+ @docs-search-close=${() => this.hideSearch()}
378
383
  >
379
384
  </docs-search>
380
385
  </div>
@@ -14,7 +14,6 @@ export const COMPONENT_NOTES: Record<string, { tag: string; note: string }> = {
14
14
  Icon: { tag: "sonic-icon", note: "Inline SVG icons from the core set or a CDN library." },
15
15
  Image: { tag: "sonic-image", note: "Responsive image with ratio, cover fit and load transition." },
16
16
  Input: { tag: "sonic-input", note: "Text field that publishes its value to a form provider." },
17
- "Input autocomplete": { tag: "sonic-input-autocomplete", note: "Field with suggestions fed by a queue." },
18
17
  Link: { tag: "sonic-link", note: "Navigation for routes, anchors and external URLs." },
19
18
  Loader: { tag: "sonic-loader", note: "Loading animation, inline or as an overlay." },
20
19
  Menu: { tag: "sonic-menu", note: "Row or column of menu items for navigation or actions." },
@@ -40,5 +39,6 @@ export const COMPONENT_NOTES: Record<string, { tag: string; note: string }> = {
40
39
  SDUI: { tag: "sonic-sdui", note: "Builds an interface from a JSON descriptor." },
41
40
  States: { tag: "sonic-states", note: "Switches content on a data value or a pattern." },
42
41
  Submit: { tag: "sonic-submit", note: "Sends a form provider to an API endpoint." },
42
+ Translation: { tag: "sonic-t", note: "Renders a translated label in plain HTML, by key." },
43
43
  Value: { tag: "sonic-value", note: "Prints a live value from a data provider." },
44
44
  };
@@ -5,8 +5,8 @@ import { sectionPages } from "../navigation/components-index";
5
5
  import { COMPONENT_NOTES } from "./catalog";
6
6
  import "./mach-stage";
7
7
 
8
- const GET_STARTED = "#docs/_getting-started/start.md/start";
9
- const COMPONENTS_PAGE = "#docs/_getting-started/components.md/components";
8
+ const GET_STARTED = "/docs/getting-started/start";
9
+ const COMPONENTS_PAGE = "/docs/getting-started/components";
10
10
 
11
11
  /**
12
12
  * Presets for the theming instrument: palette, typeface and radius all come from tokens.
@@ -125,7 +125,13 @@ const INDEX_TABS = [
125
125
  { title: "Functional components", label: "Functional" },
126
126
  ];
127
127
 
128
- const ARCHIVE = "./img/archive/";
128
+ /** Components listed in the sidebar, so the count follows the menu (hidden pages excluded). */
129
+ const COMPONENT_COUNT = INDEX_TABS.reduce(
130
+ (total, tab) => total + sectionPages(tab.title).length,
131
+ 0,
132
+ );
133
+
134
+ const ARCHIVE = "/img/archive/";
129
135
 
130
136
  /** Credit lines for the archive pictures (CC BY / CC BY-SA, from assets.mjs --credits). */
131
137
  const CREDITS = `Film: <a href="https://commons.wikimedia.org/wiki/File:Concorde_%26_Red_Arrows_2002.webm">“Concorde &amp; Red Arrows 2002”</a> by Steve Elliott, <a href="https://creativecommons.org/licenses/by-sa/2.0/">CC BY-SA 2.0</a>, via Wikimedia Commons.`;
@@ -209,10 +215,10 @@ this.querySelectorAll("[data-reveal]").forEach((el) =>
209
215
  Web components<br />for every stack.
210
216
  </h1>
211
217
  <div class="hero-actions hero-in" style="--d:180ms">
212
- <sonic-button size="lg" type="primary" class="signal-button" href=${GET_STARTED}
218
+ <sonic-button size="lg" type="primary" class="signal-button" pushState href=${GET_STARTED}
213
219
  >Open the manual</sonic-button
214
220
  >
215
- <sonic-link href=${COMPONENTS_PAGE} class="text-link"
221
+ <sonic-link pushState href=${COMPONENTS_PAGE} class="text-link"
216
222
  >Browse the components</sonic-link
217
223
  >
218
224
  </div>
@@ -229,7 +235,7 @@ this.querySelectorAll("[data-reveal]").forEach((el) =>
229
235
  private renderManifesto() {
230
236
  return html`<section class="manifesto" aria-label="What Concorde is">
231
237
  <p class="manifesto-text" data-reveal>
232
- Concorde is a Lit library of 41 web components. They bind data, call
238
+ Concorde is a Lit library of ${COMPONENT_COUNT} web components. They bind data, call
233
239
  APIs and theme themselves from plain HTML, in React, Vue, PHP or a
234
240
  static page.
235
241
  </p>
@@ -251,7 +257,7 @@ this.querySelectorAll("[data-reveal]").forEach((el) =>
251
257
  const focus = COMPONENT_NOTES[this.focus] ?? COMPONENT_NOTES[pages[0]?.label];
252
258
  return html`<section class="index" aria-labelledby="index-title">
253
259
  <div class="index-head" data-reveal>
254
- <h2 id="index-title" class="section-title">41 components,<br />one tag each.</h2>
260
+ <h2 id="index-title" class="section-title">${COMPONENT_COUNT} components,<br />one tag each.</h2>
255
261
  <div class="index-filters" role="group" aria-label="Component families" data-ui>
256
262
  ${INDEX_TABS.map((t, i) => {
257
263
  const on = this.families.has(i);
@@ -268,9 +274,10 @@ this.querySelectorAll("[data-reveal]").forEach((el) =>
268
274
  </div>
269
275
  </div>
270
276
  <p class="index-wall">
271
- ${pages.map(
277
+ ${pages.map(
272
278
  (page) => html`<span class="wall-item"
273
279
  ><sonic-link
280
+ pushState
274
281
  href=${page.href}
275
282
  class="wall-name ${page.label === this.focus ? "is-focus" : ""}"
276
283
  @mouseenter=${() => (this.focus = page.label)}
@@ -283,7 +290,7 @@ this.querySelectorAll("[data-reveal]").forEach((el) =>
283
290
  <div class="index-caption" aria-live="polite">
284
291
  <code class="index-caption-tag">&lt;${focus?.tag ?? ""}&gt;</code>
285
292
  <span class="index-caption-note">${focus?.note ?? ""}</span>
286
- <sonic-link href=${COMPONENTS_PAGE} class="text-link index-caption-all"
293
+ <sonic-link pushState href=${COMPONENTS_PAGE} class="text-link index-caption-all"
287
294
  >All components</sonic-link
288
295
  >
289
296
  </div>
@@ -489,11 +496,13 @@ this.querySelectorAll("[data-reveal]").forEach((el) =>
489
496
  <div class="footer-line">
490
497
  <span>Concorde, web components by Supersoniks</span>
491
498
  <nav class="footer-links" aria-label="Footer">
492
- <sonic-link href=${GET_STARTED}>Docs</sonic-link>
493
- <sonic-link href=${COMPONENTS_PAGE}>Components</sonic-link>
499
+ <sonic-link pushState href=${GET_STARTED}>Docs</sonic-link>
500
+ <sonic-link pushState href=${COMPONENTS_PAGE}>Components</sonic-link>
494
501
  <sonic-link href="https://www.npmjs.com/package/@supersoniks/concorde" target="_blank"
495
502
  >npm</sonic-link
496
503
  >
504
+ <sonic-link href="/about">About</sonic-link>
505
+ <sonic-link href="/privacy">Privacy</sonic-link>
497
506
  </nav>
498
507
  <span class="footer-end">MIT licence · ${new Date().getFullYear()}</span>
499
508
  </div>
@@ -1,20 +1,19 @@
1
- const onLocationChange = (location: Location) => {
2
- // Docs pages all live in the hash: no hash means the home, whatever the path
3
- // (served at /, /index.html or from a sub-folder).
4
- if (location.hash === "") {
1
+ import LocationHandler from "@supersoniks/concorde/core/utils/LocationHandler";
2
+ import { parseDocsLocation } from "./docs-location";
3
+
4
+ const onLocationChange = (locationHref: string) => {
5
+ const { url } = parseDocsLocation(locationHref);
6
+ // No markdown path → home.
7
+ if (!url) {
5
8
  document.documentElement.setAttribute("data-home", "");
6
9
  } else {
7
10
  document.documentElement.removeAttribute("data-home");
8
11
  }
9
12
  };
10
- const getCurrentLocation = () => document.location;
11
- const currentLocation: Location = getCurrentLocation();
12
- onLocationChange(currentLocation);
13
- window.addEventListener("popstate", (event) => {
14
- onLocationChange(getCurrentLocation());
15
- });
16
13
 
17
- // Listen for changes in the URL hash
18
- window.addEventListener("hashchange", () => {
19
- onLocationChange(getCurrentLocation());
14
+ // LocationHandler polls document.location (covers pushState; popstate alone does not).
15
+ LocationHandler.onChange({
16
+ set location(value: string) {
17
+ onLocationChange(value);
18
+ },
20
19
  });
@@ -0,0 +1,79 @@
1
+ # API configuration
2
+
3
+ `APIConfiguration` is the object built by [`HTML.getApiConfiguration`](../../core/utils/HTML.ts) from **ancestor attributes** on the DOM (or from a typed publisher — see [@get](/docs/decorators/get) / [@post](/docs/decorators/post) configuration key). It is passed to [`API`](../../core/utils/api.ts) by fetchers, **sonic-submit**, the **`wording()`** directive, **`@get`**, **`@post`**, **`@put`**, and **`@patch`**.
4
+
5
+ > **Mock service:** same [Local API demos](/docs/misc/docs-mock-api) Service Worker / Vite middleware. Routes used on this page are listed in the [API config routes](#api-config-routes) section below.
6
+
7
+ ## Attribute map
8
+
9
+ | Attribute (ancestor) | `APIConfiguration` field | Role |
10
+ |---------------------|---------------------------|------|
11
+ | `serviceURL` | `serviceURL` | Base URL (e.g. `/docs-mock-api`) |
12
+ | `token` | `token` | Static Bearer sent on REST calls |
13
+ | `userName` / `password` | `userName` / `password` | Basic auth for **tokenProvider** fetch only |
14
+ | `eventsApiToken` | `authToken` | Bearer for **tokenProvider** when no Basic |
15
+ | `tokenProvider` | `tokenProvider` | Path to GET a new token (`{ token }` JSON) |
16
+ | `wordingProvider` | — (read by `wording()`) | Base path + query for label batch GET |
17
+ | `wordingVersionProvider` | — | Publisher id; bump version → reload wordings |
18
+ | `credentials` | `credentials` | `fetch` credentials mode |
19
+ | `addHTTPResponse` | `addHTTPResponse` | Attach `_sonic_http_response_` on result |
20
+ | `cache` | `cache` | `fetch` cache mode |
21
+ | `blockUntilDone` | `blockUntilDone` | Serialize calls per `serviceURL` |
22
+ | `keepAlive` | `keepAlive` | `fetch` keepalive |
23
+
24
+ **Lit / TypeScript:** store the same shape in a publisher and pass `DataProviderKey<APIConfiguration>` as the second argument of `@get` (see [DataProviderKey](/docs/misc/dataProviderKey)).
25
+
26
+ ## Bearer token (static)
27
+
28
+ Publisher `docsApiConfBearerKey` (`set(docsApiConfBearerKey, { token: "docs-mock-valid-token", … })`) — mock returns the protected payload.
29
+
30
+ <docs-lit-demo for="docs-api-config-bearer-demo"></docs-lit-demo>
31
+
32
+ ## tokenProvider + Basic auth
33
+
34
+ No static `token`: `API.auth()` calls `GET /docs-mock-api/auth/token` with Basic **demo** / **secret**, stores `token`, then calls the protected route.
35
+
36
+ <docs-lit-demo for="docs-api-config-token-provider-demo"></docs-lit-demo>
37
+
38
+ ## HTTP 498 — stale token refresh
39
+
40
+ Initial `token="docs-mock-stale-token"` → mock responds **498** → Concorde invalidates the token, runs `auth()` again (same `tokenProvider` + Basic), retries with `docs-mock-fresh-token`.
41
+
42
+ <docs-lit-demo for="docs-api-config-stale-token-demo"></docs-lit-demo>
43
+
44
+ ## eventsApiToken
45
+
46
+ Attribute **`eventsApiToken`** on an ancestor maps to **`authToken`** in config (used as Bearer when calling `tokenProvider`, instead of Basic).
47
+
48
+ <docs-lit-demo for="docs-api-config-events-token-demo"></docs-lit-demo>
49
+
50
+ ## Wording API
51
+
52
+ `wordingProvider` and `wordingVersionProvider` are read by the translation directive: see [t()](/docs/directives/t).
53
+
54
+ ## Scoped attributes (HTML / sonic-scope)
55
+
56
+ Attributes on **`sonic-scope`** (or any ancestor) are visible to descendants via `getAncestorAttributeValue`.
57
+
58
+ <docs-lit-demo for="docs-api-config-scoped-attrs-demo"></docs-lit-demo>
59
+
60
+ ## API config routes
61
+
62
+ | Route | Demo |
63
+ |-------|------|
64
+ | `GET /docs-mock-api/auth/token` | tokenProvider, eventsApiToken |
65
+ | `GET /docs-mock-api/api/config/protected` | Bearer / Basic / 498 |
66
+ | `GET /docs-mock-api/wording/labels?labels[]=…&lang=fr` | `wording()` |
67
+
68
+ Mock tokens (doc only): `docs-mock-valid-token`, `docs-mock-stale-token` (498), `docs-mock-fresh-token` (after refresh). Basic: **demo** / **secret**. Events token: `docs-mock-events-token`.
69
+
70
+ Implementation: `src/docs/mock-api/api-config-mock.ts` (bundled in the Service Worker with `router.ts`).
71
+
72
+ ## See also
73
+
74
+ - [@get](/docs/decorators/get) — `APIConfiguration` + `Endpoint`
75
+ - [@post](/docs/decorators/post) — same configuration model for POST
76
+ - [@put](/docs/decorators/put) · [@patch](/docs/decorators/patch) — PUT / PATCH
77
+ - [Endpoint](/docs/misc/endpoint) — typed path
78
+ - [Local API demos](/docs/misc/docs-mock-api) — offline `serviceURL`
79
+ - [Fetch](/core/components/functional/fetch) — attribute table (legacy sonic-fetch)