@supersoniks/concorde 5.1.0 → 5.1.2

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 (628) 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/launch.json +15 -0
  6. package/.claude/vite.http.config.mjs +7 -0
  7. package/.taste-skill/after/desktop-fold.jpg +0 -0
  8. package/.taste-skill/after/desktop-page-01.jpg +0 -0
  9. package/.taste-skill/after/desktop-page-02.jpg +0 -0
  10. package/.taste-skill/after/desktop-page-03.jpg +0 -0
  11. package/.taste-skill/after/mobile-fold.jpg +0 -0
  12. package/.taste-skill/after/mobile-page-01.jpg +0 -0
  13. package/.taste-skill/after/report.json +4103 -0
  14. package/.taste-skill/after/tablet-fold.jpg +0 -0
  15. package/.taste-skill/after/tablet-page-01.jpg +0 -0
  16. package/.taste-skill/after/tablet-page-02.jpg +0 -0
  17. package/.taste-skill/before/desktop-fold.jpg +0 -0
  18. package/.taste-skill/before/desktop-page-01.jpg +0 -0
  19. package/.taste-skill/before/desktop-page-02.jpg +0 -0
  20. package/.taste-skill/before/mobile-fold.jpg +0 -0
  21. package/.taste-skill/before/mobile-page-01.jpg +0 -0
  22. package/.taste-skill/before/report.json +2556 -0
  23. package/.taste-skill/before/tablet-fold.jpg +0 -0
  24. package/.taste-skill/before/tablet-page-01.jpg +0 -0
  25. package/.taste-skill/direction.json +510 -0
  26. package/.taste-skill/notes.md +84 -0
  27. package/.taste-skill/prod/desktop-fold.jpg +0 -0
  28. package/.taste-skill/prod/desktop-page-01.jpg +0 -0
  29. package/.taste-skill/prod/desktop-page-02.jpg +0 -0
  30. package/.taste-skill/prod/desktop-page-03.jpg +0 -0
  31. package/.taste-skill/prod/mobile-fold.jpg +0 -0
  32. package/.taste-skill/prod/mobile-page-01.jpg +0 -0
  33. package/.taste-skill/prod/mobile-page-02.jpg +0 -0
  34. package/.taste-skill/prod/report.json +1973 -0
  35. package/.taste-skill/prod/tablet-fold.jpg +0 -0
  36. package/.taste-skill/prod/tablet-page-01.jpg +0 -0
  37. package/.taste-skill/prod/tablet-page-02.jpg +0 -0
  38. package/.tmp-cem/custom-elements.json +2013 -2013
  39. package/AUDIT.md +228 -0
  40. package/PLAN-AMELIORATION.md +220 -0
  41. package/PLAN-DOCS-AGENTS.md +80 -0
  42. package/README.md +3 -3
  43. package/ai/skills/concorde/SKILL.md +1 -1
  44. package/ai/skills/concorde-get-set-dp/SKILL.md +3 -3
  45. package/ai/skills/concorde-theme/SKILL.md +1 -1
  46. package/build-infos.json +1 -1
  47. package/concorde-core.bundle.js +16 -16
  48. package/concorde-core.es.js +235 -233
  49. package/dist/concorde-core.bundle.js +16 -16
  50. package/dist/concorde-core.es.js +235 -233
  51. package/dist/img/archive/concorde-001-2cv.webp +0 -0
  52. package/dist/img/archive/concorde-red-arrows-2002-poster.jpg +0 -0
  53. package/dist/img/archive/concorde-red-arrows-2002.webm +0 -0
  54. package/dist/img/archive/credits.json +28 -0
  55. package/docs/.htaccess +75 -0
  56. package/docs/404.html +15 -0
  57. package/docs/404.md +5 -0
  58. package/docs/assets/index-BgG6FFPt.js +11765 -0
  59. package/docs/assets/index-x89XINSG.css +1 -0
  60. package/docs/core/components/functional/date/date.html +211 -0
  61. package/docs/core/components/functional/date/date.md +150 -0
  62. package/docs/core/components/functional/fetch/fetch.html +180 -0
  63. package/docs/core/components/functional/fetch/fetch.md +108 -0
  64. package/docs/core/components/functional/if/if.html +65 -0
  65. package/docs/core/components/functional/if/if.md +34 -0
  66. package/docs/core/components/functional/jsonata/jsonata.html +110 -0
  67. package/docs/core/components/functional/jsonata/jsonata.md +61 -0
  68. package/docs/core/components/functional/list/list.html +198 -0
  69. package/docs/core/components/functional/list/list.md +121 -0
  70. package/docs/core/components/functional/mix/mix.html +78 -0
  71. package/docs/core/components/functional/mix/mix.md +46 -0
  72. package/docs/core/components/functional/queue/queue.html +155 -0
  73. package/docs/core/components/functional/queue/queue.md +51 -0
  74. package/docs/core/components/functional/router/router.html +154 -0
  75. package/docs/core/components/functional/router/router.md +93 -0
  76. package/docs/core/components/functional/sdui/sdui-extension-points.html +127 -0
  77. package/docs/core/components/functional/sdui/sdui-extension-points.md +94 -0
  78. package/docs/core/components/functional/sdui/sdui.html +397 -0
  79. package/docs/core/components/functional/sdui/sdui.md +307 -0
  80. package/docs/core/components/functional/states/states.html +141 -0
  81. package/docs/core/components/functional/states/states.md +112 -0
  82. package/docs/core/components/functional/submit/submit.html +178 -0
  83. package/docs/core/components/functional/submit/submit.md +106 -0
  84. package/docs/{crawl/core → core}/components/functional/subscriber/subscriber.html +6 -5
  85. package/docs/core/components/functional/subscriber/subscriber.md +91 -0
  86. package/docs/core/components/functional/translation/translation.html +60 -0
  87. package/docs/core/components/functional/translation/translation.md +38 -0
  88. package/docs/core/components/functional/value/value.html +81 -0
  89. package/docs/core/components/functional/value/value.md +47 -0
  90. package/docs/core/components/ui/alert/alert.html +201 -0
  91. package/docs/core/components/ui/alert/alert.md +186 -0
  92. package/docs/core/components/ui/alert-messages/alert-messages.html +132 -0
  93. package/docs/core/components/ui/alert-messages/alert-messages.md +85 -0
  94. package/docs/core/components/ui/badge/badge.html +197 -0
  95. package/docs/core/components/ui/badge/badge.md +181 -0
  96. package/docs/core/components/ui/button/button.html +309 -0
  97. package/docs/core/components/ui/button/button.md +216 -0
  98. package/docs/core/components/ui/captcha/captcha.html +80 -0
  99. package/docs/core/components/ui/captcha/captcha.md +56 -0
  100. package/docs/core/components/ui/card/card.html +254 -0
  101. package/docs/core/components/ui/card/card.md +215 -0
  102. package/docs/core/components/ui/divider/divider.html +144 -0
  103. package/docs/core/components/ui/divider/divider.md +126 -0
  104. package/docs/core/components/ui/form/checkbox/checkbox.html +200 -0
  105. package/docs/core/components/ui/form/checkbox/checkbox.md +125 -0
  106. package/docs/core/components/ui/form/fieldset/fieldset.html +238 -0
  107. package/docs/core/components/ui/form/fieldset/fieldset.md +161 -0
  108. package/docs/core/components/ui/form/form-actions/form-actions.html +122 -0
  109. package/docs/core/components/ui/form/form-actions/form-actions.md +98 -0
  110. package/docs/core/components/ui/form/form-layout/form-layout.html +115 -0
  111. package/docs/core/components/ui/form/form-layout/form-layout.md +109 -0
  112. package/docs/core/components/ui/form/input/input.html +235 -0
  113. package/docs/core/components/ui/form/input/input.md +142 -0
  114. package/docs/core/components/ui/form/radio/radio.html +144 -0
  115. package/docs/core/components/ui/form/radio/radio.md +78 -0
  116. package/docs/core/components/ui/form/select/select.html +178 -0
  117. package/docs/core/components/ui/form/select/select.md +86 -0
  118. package/docs/core/components/ui/form/switch/switch.html +146 -0
  119. package/docs/core/components/ui/form/switch/switch.md +80 -0
  120. package/docs/core/components/ui/form/textarea/textarea.html +162 -0
  121. package/docs/core/components/ui/form/textarea/textarea.md +82 -0
  122. package/docs/core/components/ui/group/group.html +113 -0
  123. package/docs/core/components/ui/group/group.md +77 -0
  124. package/docs/core/components/ui/icon/icon.html +223 -0
  125. package/docs/core/components/ui/icon/icon.md +214 -0
  126. package/docs/core/components/ui/image/image.html +194 -0
  127. package/docs/core/components/ui/image/image.md +167 -0
  128. package/docs/core/components/ui/link/link.html +101 -0
  129. package/docs/core/components/ui/link/link.md +81 -0
  130. package/docs/core/components/ui/loader/loader.html +114 -0
  131. package/docs/core/components/ui/loader/loader.md +87 -0
  132. package/docs/{crawl/core → core}/components/ui/menu/menu.html +189 -116
  133. package/docs/core/components/ui/menu/menu.md +370 -0
  134. package/docs/core/components/ui/modal/modal.html +324 -0
  135. package/docs/core/components/ui/modal/modal.md +211 -0
  136. package/docs/core/components/ui/pop/pop.html +250 -0
  137. package/docs/core/components/ui/pop/pop.md +216 -0
  138. package/docs/core/components/ui/progress/progress.html +132 -0
  139. package/docs/core/components/ui/progress/progress.md +109 -0
  140. package/docs/core/components/ui/table/table.html +333 -0
  141. package/docs/core/components/ui/table/table.md +267 -0
  142. package/docs/core/components/ui/theme/theme.html +116 -0
  143. package/docs/core/components/ui/theme/theme.md +97 -0
  144. package/docs/core/components/ui/toast/toast.html +185 -0
  145. package/docs/core/components/ui/toast/toast.md +147 -0
  146. package/docs/core/components/ui/tooltip/tooltip.html +112 -0
  147. package/docs/core/components/ui/tooltip/tooltip.md +89 -0
  148. package/docs/docs/decorators/ancestor-attribute.html +71 -0
  149. package/docs/docs/decorators/ancestor-attribute.md +59 -0
  150. package/docs/docs/decorators/auto-subscribe.html +61 -0
  151. package/docs/docs/decorators/auto-subscribe.md +40 -0
  152. package/docs/docs/decorators/bind.html +86 -0
  153. package/docs/docs/decorators/bind.md +77 -0
  154. package/docs/docs/decorators/get.html +166 -0
  155. package/docs/docs/decorators/get.md +160 -0
  156. package/docs/docs/decorators/handle.html +139 -0
  157. package/docs/docs/decorators/handle.md +119 -0
  158. package/docs/docs/decorators/on-assign.html +72 -0
  159. package/docs/docs/decorators/on-assign.md +63 -0
  160. package/docs/docs/decorators/patch.html +76 -0
  161. package/docs/docs/decorators/patch.md +44 -0
  162. package/docs/docs/decorators/post.html +150 -0
  163. package/docs/docs/decorators/post.md +134 -0
  164. package/docs/docs/decorators/publish.html +74 -0
  165. package/docs/docs/decorators/publish.md +56 -0
  166. package/docs/docs/decorators/put.html +83 -0
  167. package/docs/docs/decorators/put.md +51 -0
  168. package/docs/docs/decorators/subscribe.html +91 -0
  169. package/docs/docs/decorators/subscribe.md +87 -0
  170. package/docs/docs/decorators/wait-for-ancestors.html +82 -0
  171. package/docs/docs/decorators/wait-for-ancestors.md +76 -0
  172. package/docs/docs/directives/sub.html +79 -0
  173. package/docs/docs/directives/sub.md +75 -0
  174. package/docs/docs/directives/t.html +91 -0
  175. package/docs/docs/directives/t.md +73 -0
  176. package/docs/{crawl/docs/_getting-started → docs/getting-started}/ai-agents.html +12 -11
  177. package/{src/docs/_getting-started → docs/docs/getting-started}/ai-agents.md +3 -3
  178. package/docs/docs/getting-started/components.html +27 -0
  179. package/docs/docs/getting-started/components.md +5 -0
  180. package/docs/{crawl/docs/_getting-started → docs/getting-started}/create-a-component.html +11 -14
  181. package/docs/{src/docs/_getting-started → docs/getting-started}/create-a-component.md +3 -6
  182. package/docs/{crawl/docs/_core-concept → docs/getting-started}/dataFlow.html +26 -29
  183. package/docs/{src/docs/_core-concept → docs/getting-started}/dataFlow.md +17 -18
  184. package/docs/docs/getting-started/installation.html +69 -0
  185. package/docs/docs/getting-started/installation.md +36 -0
  186. package/docs/{crawl/docs/_getting-started → docs/getting-started}/my-first-component.html +13 -22
  187. package/docs/{src/docs/_getting-started → docs/getting-started}/my-first-component.md +5 -14
  188. package/docs/docs/getting-started/start.html +47 -0
  189. package/{src/docs/_getting-started → docs/docs/getting-started}/start.md +1 -13
  190. package/docs/docs/getting-started/theming.html +334 -0
  191. package/{src/docs/_getting-started → docs/docs/getting-started}/theming.md +2 -2
  192. package/docs/docs/index.html +99 -0
  193. package/docs/{crawl/docs/_misc → docs/misc}/api-configuration.html +18 -18
  194. package/docs/{src/docs/_misc → docs/misc}/api-configuration.md +10 -12
  195. package/docs/{crawl/docs/_misc → docs/misc}/dataProviderKey.html +12 -11
  196. package/{src/docs/_misc → docs/docs/misc}/dataProviderKey.md +4 -4
  197. package/docs/{crawl/docs/_misc → docs/misc}/docs-mock-api.html +25 -28
  198. package/docs/{src/docs/_misc → docs/misc}/docs-mock-api.md +12 -13
  199. package/docs/{crawl/docs/_misc → docs/misc}/dynamic-path.html +16 -15
  200. package/{src/docs/_misc → docs/docs/misc}/dynamic-path.md +8 -8
  201. package/docs/{crawl/docs/_misc → docs/misc}/endpoint.html +16 -15
  202. package/{src/docs/_misc → docs/docs/misc}/endpoint.md +8 -8
  203. package/docs/{crawl/docs/_misc → docs/misc}/html-integration.html +12 -15
  204. package/docs/{src/docs/_misc → docs/misc}/html-integration.md +4 -5
  205. package/docs/docs-mock-api-sw.js +60 -223
  206. package/docs/docs-mock-api-sw.js.map +4 -4
  207. package/docs/hubs/decorators.html +443 -0
  208. package/docs/hubs/form-components.html +404 -0
  209. package/docs/hubs/remote-data.html +371 -0
  210. package/docs/img/archive/concorde-001-2cv.webp +0 -0
  211. package/docs/img/archive/concorde-red-arrows-2002-poster.jpg +0 -0
  212. package/docs/img/archive/concorde-red-arrows-2002.webm +0 -0
  213. package/docs/img/archive/credits.json +28 -0
  214. package/docs/img/concorde/plane_01.jpg +0 -0
  215. package/docs/img/concorde/plane_02.jpg +0 -0
  216. package/docs/img/concorde/plane_03.jpg +0 -0
  217. package/docs/img/concorde/plane_04.jpg +0 -0
  218. package/docs/img/concorde/plane_05.jpg +0 -0
  219. package/docs/img/concorde/plane_06.jpg +0 -0
  220. package/docs/img/concorde/plane_07.jpg +0 -0
  221. package/docs/img/concorde/plane_08.jpg +0 -0
  222. package/docs/img/concorde/plane_09.jpg +0 -0
  223. package/docs/img/concorde/plane_10.jpg +0 -0
  224. package/docs/img/concorde/plane_11.jpg +0 -0
  225. package/docs/img/concorde/plane_12.jpg +0 -0
  226. package/docs/img/concorde/plane_13.jpg +0 -0
  227. package/docs/index.html +96 -67
  228. package/docs/index.md +22 -0
  229. package/docs/llms-full.txt +3329 -3295
  230. package/docs/llms.txt +94 -92
  231. package/docs/robots.txt +11 -10
  232. package/docs/sitemap.xml +78 -78
  233. package/docs/src/core/components/functional/date/date.md +91 -231
  234. package/docs/src/core/components/functional/fetch/fetch.md +66 -83
  235. package/docs/src/core/components/functional/if/if.md +28 -3
  236. package/docs/src/core/components/functional/jsonata/jsonata.md +42 -37
  237. package/docs/src/core/components/functional/list/list.md +99 -43
  238. package/docs/src/core/components/functional/mix/mix.md +31 -26
  239. package/docs/src/core/components/functional/queue/queue.md +40 -61
  240. package/docs/src/core/components/functional/router/router.md +64 -65
  241. package/docs/src/core/components/functional/sdui/component-catalog.gaps.json +511 -0
  242. package/docs/src/core/components/functional/sdui/component-catalog.json +3103 -0
  243. package/docs/src/core/components/functional/sdui/example.json +19 -86
  244. package/docs/src/core/components/functional/sdui/sdui-extension-points.md +94 -0
  245. package/docs/src/core/components/functional/sdui/sdui.md +196 -245
  246. package/docs/src/core/components/functional/states/states.md +86 -61
  247. package/docs/src/core/components/functional/submit/submit.md +64 -72
  248. package/docs/src/core/components/functional/translation/translation.md +38 -0
  249. package/docs/src/core/components/functional/value/value.md +34 -22
  250. package/docs/src/core/components/ui/alert/alert.md +139 -74
  251. package/docs/src/core/components/ui/alert-messages/alert-messages.md +85 -0
  252. package/docs/src/core/components/ui/badge/badge.md +137 -83
  253. package/docs/src/core/components/ui/button/button.md +139 -105
  254. package/docs/src/core/components/ui/captcha/captcha.md +50 -6
  255. package/docs/src/core/components/ui/card/card.md +183 -65
  256. package/docs/src/core/components/ui/divider/divider.md +104 -13
  257. package/docs/src/core/components/ui/form/checkbox/checkbox.md +90 -42
  258. package/docs/src/core/components/ui/form/fieldset/fieldset.md +135 -103
  259. package/docs/src/core/components/ui/form/form-actions/form-actions.md +71 -50
  260. package/docs/src/core/components/ui/form/form-layout/form-layout.md +99 -34
  261. package/docs/src/core/components/ui/form/input/input.md +95 -95
  262. package/docs/src/core/components/ui/form/radio/radio.md +55 -34
  263. package/docs/src/core/components/ui/form/select/select.md +60 -45
  264. package/docs/src/core/components/ui/form/switch/switch.md +57 -34
  265. package/docs/src/core/components/ui/form/textarea/textarea.md +55 -38
  266. package/docs/src/core/components/ui/group/group.md +49 -47
  267. package/docs/src/core/components/ui/icon/icon.md +132 -43
  268. package/docs/src/core/components/ui/image/image.md +132 -72
  269. package/docs/src/core/components/ui/link/link.md +46 -8
  270. package/docs/src/core/components/ui/loader/loader.md +55 -23
  271. package/docs/src/core/components/ui/menu/menu.md +155 -114
  272. package/docs/src/core/components/ui/modal/modal.md +154 -62
  273. package/docs/src/core/components/ui/pop/pop.md +185 -65
  274. package/docs/src/core/components/ui/progress/progress.md +76 -30
  275. package/docs/src/core/components/ui/table/table.md +146 -334
  276. package/docs/src/core/components/ui/theme/theme.md +97 -0
  277. package/docs/src/core/components/ui/toast/toast.md +80 -99
  278. package/docs/src/core/components/ui/tooltip/tooltip.md +52 -45
  279. package/docs/src/docs/decorators/ancestor-attribute.md +59 -0
  280. package/docs/src/docs/decorators/auto-subscribe.md +40 -0
  281. package/docs/src/docs/decorators/bind.md +77 -0
  282. package/docs/src/docs/decorators/get.md +160 -0
  283. package/docs/src/docs/decorators/handle.md +119 -0
  284. package/docs/src/docs/decorators/on-assign.md +63 -0
  285. package/docs/src/docs/decorators/patch.md +44 -0
  286. package/docs/src/docs/decorators/post.md +134 -0
  287. package/docs/src/docs/decorators/publish.md +56 -0
  288. package/docs/src/docs/decorators/put.md +51 -0
  289. package/docs/src/docs/decorators/subscribe.md +87 -0
  290. package/docs/src/docs/decorators/wait-for-ancestors.md +76 -0
  291. package/docs/src/docs/directives/sub.md +75 -0
  292. package/docs/src/docs/directives/t.md +73 -0
  293. package/docs/src/docs/{_getting-started → getting-started}/ai-agents.md +3 -3
  294. package/docs/src/docs/getting-started/components.md +5 -0
  295. package/{src/docs/_getting-started → docs/src/docs/getting-started}/create-a-component.md +3 -6
  296. package/{src/docs/_core-concept → docs/src/docs/getting-started}/dataFlow.md +17 -18
  297. package/docs/src/docs/getting-started/installation.md +36 -0
  298. package/{src/docs/_getting-started → docs/src/docs/getting-started}/my-first-component.md +5 -14
  299. package/docs/src/docs/getting-started/start.md +35 -0
  300. package/docs/src/docs/getting-started/theming.md +253 -0
  301. package/{src/docs/_misc → docs/src/docs/misc}/api-configuration.md +10 -12
  302. package/docs/src/docs/{_misc → misc}/dataProviderKey.md +4 -4
  303. package/{src/docs/_misc → docs/src/docs/misc}/docs-mock-api.md +12 -13
  304. package/docs/src/docs/{_misc → misc}/dynamic-path.md +8 -8
  305. package/docs/src/docs/{_misc → misc}/endpoint.md +8 -8
  306. package/{src/docs/_misc → docs/src/docs/misc}/html-integration.md +4 -5
  307. package/docs/src/docs/search/docs-search.json +3729 -2949
  308. package/docs/src/tsconfig.json +176 -5
  309. package/index.html +94 -67
  310. package/package.json +11 -4
  311. package/public/docs-mock-api-sw.js +58 -223
  312. package/public/docs-mock-api-sw.js.map +4 -4
  313. package/public/img/archive/concorde-001-2cv.webp +0 -0
  314. package/public/img/archive/concorde-red-arrows-2002-poster.jpg +0 -0
  315. package/public/img/archive/concorde-red-arrows-2002.webm +0 -0
  316. package/public/img/archive/credits.json +28 -0
  317. package/public/img/concorde/plane_01.jpg +0 -0
  318. package/public/img/concorde/plane_02.jpg +0 -0
  319. package/public/img/concorde/plane_03.jpg +0 -0
  320. package/public/img/concorde/plane_04.jpg +0 -0
  321. package/public/img/concorde/plane_05.jpg +0 -0
  322. package/public/img/concorde/plane_06.jpg +0 -0
  323. package/public/img/concorde/plane_07.jpg +0 -0
  324. package/public/img/concorde/plane_08.jpg +0 -0
  325. package/public/img/concorde/plane_09.jpg +0 -0
  326. package/public/img/concorde/plane_10.jpg +0 -0
  327. package/public/img/concorde/plane_11.jpg +0 -0
  328. package/public/img/concorde/plane_12.jpg +0 -0
  329. package/public/img/concorde/plane_13.jpg +0 -0
  330. package/public/robots.txt +11 -10
  331. package/scripts/docs-markdown-vite-plugin.ts +37 -0
  332. package/scripts/docs-public-url.mjs +50 -0
  333. package/scripts/docs.htaccess +75 -0
  334. package/scripts/generate-crawl-docs.mjs +207 -116
  335. package/scripts/generate-crawl-docs.test.mjs +124 -0
  336. package/scripts/post-build-docs.js +34 -50
  337. package/scripts/post-build.mjs +0 -0
  338. package/src/core/components/functional/date/date.md +91 -231
  339. package/src/core/components/functional/fetch/fetch.md +66 -83
  340. package/src/core/components/functional/if/if.md +28 -3
  341. package/src/core/components/functional/if/if.ts +0 -0
  342. package/src/core/components/functional/jsonata/jsonata.md +42 -37
  343. package/src/core/components/functional/list/list.demo.ts +0 -0
  344. package/src/core/components/functional/list/list.md +99 -43
  345. package/src/core/components/functional/mix/mix.md +31 -26
  346. package/src/core/components/functional/queue/queue.demo.ts +10 -7
  347. package/src/core/components/functional/queue/queue.md +40 -61
  348. package/src/core/components/functional/router/router.demo.ts +16 -16
  349. package/src/core/components/functional/router/router.md +64 -65
  350. package/src/core/components/functional/router/router.ts +0 -0
  351. package/src/core/components/functional/sdui/SDUIDescriptorTransformer.ts +0 -0
  352. package/src/core/components/functional/sdui/component-catalog.gaps.json +1 -1
  353. package/src/core/components/functional/sdui/component-catalog.json +1 -1
  354. package/src/core/components/functional/sdui/example.json +19 -86
  355. package/src/core/components/functional/sdui/sdui-extension-points.md +1 -1
  356. package/src/core/components/functional/sdui/sdui.md +187 -358
  357. package/src/core/components/functional/sdui/types.ts +0 -0
  358. package/src/core/components/functional/states/states.demo.ts +21 -22
  359. package/src/core/components/functional/states/states.md +86 -61
  360. package/src/core/components/functional/states/states.ts +1 -1
  361. package/src/core/components/functional/submit/submit.md +64 -72
  362. package/src/core/components/functional/subscriber/subscriber.ts +0 -0
  363. package/src/core/components/functional/translation/translation.md +38 -0
  364. package/src/core/components/functional/value/value.md +34 -22
  365. package/src/core/components/functional/value/value.ts +0 -0
  366. package/src/core/components/ui/_css/size.ts +0 -0
  367. package/src/core/components/ui/alert/alert.md +48 -58
  368. package/src/core/components/ui/badge/badge.md +27 -34
  369. package/src/core/components/ui/button/button.md +139 -106
  370. package/src/core/components/ui/captcha/altchaStyles.ts +0 -0
  371. package/src/core/components/ui/captcha/captcha.md +17 -32
  372. package/src/core/components/ui/card/card.md +6 -6
  373. package/src/core/components/ui/divider/divider.md +8 -11
  374. package/src/core/components/ui/form/checkbox/checkbox.md +90 -42
  375. package/src/core/components/ui/form/fieldset/fieldset.md +31 -75
  376. package/src/core/components/ui/form/form-actions/form-actions.md +14 -16
  377. package/src/core/components/ui/form/form-layout/form-layout.md +19 -29
  378. package/src/core/components/ui/form/input/input.md +95 -95
  379. package/src/core/components/ui/form/radio/radio.md +55 -34
  380. package/src/core/components/ui/form/select/select.md +60 -45
  381. package/src/core/components/ui/form/switch/switch.md +57 -34
  382. package/src/core/components/ui/form/textarea/textarea.md +55 -38
  383. package/src/core/components/ui/group/group.md +35 -33
  384. package/src/core/components/ui/icon/icon.md +4 -4
  385. package/src/core/components/ui/image/image.md +41 -107
  386. package/src/core/components/ui/link/link.md +6 -6
  387. package/src/core/components/ui/loader/loader.md +30 -55
  388. package/src/core/components/ui/menu/menu.md +27 -27
  389. package/src/core/components/ui/modal/modal.md +72 -96
  390. package/src/core/components/ui/modal/modal.ts +14 -11
  391. package/src/core/components/ui/pop/pop.md +80 -158
  392. package/src/core/components/ui/progress/progress.md +2 -2
  393. package/src/core/components/ui/table/table.md +91 -255
  394. package/src/core/components/ui/theme/theme.md +11 -36
  395. package/src/core/components/ui/toast/toast.md +48 -117
  396. package/src/core/components/ui/tooltip/tooltip.md +27 -62
  397. package/src/core/mixins/Subscriber.ts +0 -0
  398. package/src/core/utils/DataBindObserver.ts +0 -0
  399. package/src/core/utils/LocationHandler.spec.ts +80 -0
  400. package/src/core/utils/LocationHandler.ts +5 -9
  401. package/src/core/utils/Objects.ts +0 -0
  402. package/src/core/utils/route.ts +0 -0
  403. package/src/docs/code.ts +88 -75
  404. package/src/docs/components/docs-demo-sources.ts +70 -147
  405. package/src/docs/components/docs-lit-demo.ts +20 -40
  406. package/src/docs/components/docs-source-link.ts +0 -82
  407. package/src/docs/decorators/ancestor-attribute.md +59 -0
  408. package/src/docs/decorators/auto-subscribe.md +40 -0
  409. package/src/docs/decorators/bind.md +77 -0
  410. package/src/docs/decorators/get.md +160 -0
  411. package/src/docs/decorators/handle.md +119 -0
  412. package/src/docs/decorators/on-assign.md +63 -0
  413. package/src/docs/decorators/patch.md +44 -0
  414. package/src/docs/decorators/post.md +134 -0
  415. package/src/docs/decorators/publish.md +56 -0
  416. package/src/docs/decorators/put.md +51 -0
  417. package/src/docs/decorators/subscribe.md +87 -0
  418. package/src/docs/decorators/wait-for-ancestors.md +76 -0
  419. package/src/docs/directives/sub.md +75 -0
  420. package/src/docs/directives/t.md +73 -0
  421. package/src/docs/docs-location.spec.ts +46 -0
  422. package/src/docs/docs-location.ts +123 -32
  423. package/src/docs/docs.ts +6 -2
  424. package/src/docs/example/decorators-demo-bind-demos.ts +81 -116
  425. package/src/docs/example/decorators-demo-geo.ts +30 -19
  426. package/src/docs/example/decorators-demo-post.ts +88 -186
  427. package/src/docs/example/decorators-demo-subscribe-publish-get-demos.ts +165 -268
  428. package/src/docs/example/decorators-demo.ts +85 -98
  429. package/src/docs/example/docs-api-config-demos.ts +19 -20
  430. package/src/docs/example/docs-boarding-pass-demo.ts +134 -0
  431. package/src/docs/example/docs-flight-demos.ts +147 -0
  432. package/src/docs/example/docs-jsonata-demos.ts +52 -52
  433. package/src/docs/example/docs-list-demos.ts +43 -123
  434. package/src/docs/example/docs-provider-keys.ts +33 -28
  435. package/src/docs/example/docs-queue-demos.ts +37 -77
  436. package/src/docs/example/docs-router-demos.ts +20 -25
  437. package/src/docs/example/docs-submit-demos.ts +48 -48
  438. package/src/docs/example/docs-toggle-demos.ts +4 -3
  439. package/src/docs/example/users.ts +0 -0
  440. package/src/docs/getting-started/ai-agents.md +76 -0
  441. package/src/docs/getting-started/components.md +5 -0
  442. package/src/docs/getting-started/create-a-component.md +136 -0
  443. package/src/docs/getting-started/dataFlow.md +87 -0
  444. package/src/docs/getting-started/installation.md +36 -0
  445. package/src/docs/getting-started/my-first-component.md +227 -0
  446. package/src/docs/getting-started/start.md +35 -0
  447. package/src/docs/getting-started/theming.md +253 -0
  448. package/src/docs/header/header.ts +240 -71
  449. package/src/docs/home/catalog.ts +44 -0
  450. package/src/docs/home/home.ts +520 -0
  451. package/src/docs/home/mach-stage.ts +389 -0
  452. package/src/docs/layout.ts +12 -11
  453. package/src/docs/misc/api-configuration.md +79 -0
  454. package/src/docs/misc/dataProviderKey.md +168 -0
  455. package/src/docs/misc/docs-mock-api.md +62 -0
  456. package/src/docs/misc/dynamic-path.md +71 -0
  457. package/src/docs/misc/endpoint.md +45 -0
  458. package/src/docs/misc/html-integration.md +14 -0
  459. package/src/docs/mock-api/api-config-mock.ts +5 -0
  460. package/src/docs/mock-api/fixtures.ts +0 -278
  461. package/src/docs/mock-api/flights.ts +89 -0
  462. package/src/docs/mock-api/router.ts +3 -4
  463. package/src/docs/mock-api/urls.ts +1 -2
  464. package/src/docs/navigation/components-index.ts +56 -0
  465. package/src/docs/navigation/navigation.ts +219 -232
  466. package/src/docs/navigation/pager.ts +67 -0
  467. package/src/docs/navigation/toc.ts +101 -0
  468. package/src/docs/search/docs-search.json +2419 -4374
  469. package/src/docs/search/markdown-renderer.ts +33 -7
  470. package/src/docs/search/page.ts +9 -6
  471. package/src/docs/search/search.ts +154 -122
  472. package/src/docs/shiki/index.ts +109 -0
  473. package/src/docs/tailwind/css/base/scrollbar.css +22 -0
  474. package/src/docs/tailwind/css/base/theme.css +96 -0
  475. package/src/docs/tailwind/css/base/typography.css +4 -0
  476. package/src/docs/tailwind/css/docs/boarding-pass.css +65 -0
  477. package/src/docs/tailwind/css/docs/content.css +32 -0
  478. package/src/docs/tailwind/css/docs/page.css +10 -0
  479. package/src/docs/tailwind/css/docs.css +9 -0
  480. package/src/docs/tailwind/css/home/hero.css +210 -0
  481. package/src/docs/tailwind/css/home/motion.css +84 -0
  482. package/src/docs/tailwind/css/home/sections.css +416 -0
  483. package/src/docs/tailwind/css/tailwind.css +7 -185
  484. package/src/tsconfig.json +23 -2
  485. package/src/tsconfig.tsbuildinfo +1 -1
  486. package/tailwind.config.js +8 -4
  487. package/vite.config.mts +11 -2
  488. package/.agents/skills/concorde-component-docs/SKILL.md +0 -194
  489. package/.github/workflows/ci.yml +0 -21
  490. package/.github-export-ignore +0 -30
  491. package/CONTRIBUTING.md +0 -59
  492. package/DEV.md +0 -54
  493. package/LICENSE +0 -21
  494. package/OPEN_SOURCE_CHECKPOINT.md +0 -133
  495. package/concorde-3d.bundle.js +0 -3960
  496. package/concorde-3d.es.js +0 -33433
  497. package/concorde-hugging-face-infer.bundle.js +0 -32
  498. package/concorde-hugging-face-infer.es.js +0 -2952
  499. package/concorde-interactive.bundle.js +0 -1157
  500. package/concorde-interactive.es.js +0 -10734
  501. package/concorde-shader.bundle.js +0 -116
  502. package/concorde-shader.es.js +0 -8353
  503. package/concorde-webgpu.bundle.js +0 -307
  504. package/concorde-webgpu.es.js +0 -8627
  505. package/docs/assets/index-D8MVWqY6.js +0 -12251
  506. package/docs/assets/index-DiD0qYvE.css +0 -1
  507. package/docs/crawl/core/components/functional/date/date.html +0 -190
  508. package/docs/crawl/core/components/functional/fetch/fetch.html +0 -109
  509. package/docs/crawl/core/components/functional/if/if.html +0 -27
  510. package/docs/crawl/core/components/functional/jsonata/jsonata.html +0 -79
  511. package/docs/crawl/core/components/functional/list/list.html +0 -70
  512. package/docs/crawl/core/components/functional/mix/mix.html +0 -45
  513. package/docs/crawl/core/components/functional/queue/queue.html +0 -96
  514. package/docs/crawl/core/components/functional/router/router.html +0 -106
  515. package/docs/crawl/core/components/functional/sdui/sdui.html +0 -269
  516. package/docs/crawl/core/components/functional/states/states.html +0 -66
  517. package/docs/crawl/core/components/functional/submit/submit.html +0 -160
  518. package/docs/crawl/core/components/functional/value/value.html +0 -51
  519. package/docs/crawl/core/components/ui/alert/alert.html +0 -110
  520. package/docs/crawl/core/components/ui/alert-messages/alert-messages.html +0 -23
  521. package/docs/crawl/core/components/ui/badge/badge.html +0 -119
  522. package/docs/crawl/core/components/ui/button/button.html +0 -149
  523. package/docs/crawl/core/components/ui/captcha/captcha.html +0 -30
  524. package/docs/crawl/core/components/ui/card/card.html +0 -99
  525. package/docs/crawl/core/components/ui/divider/divider.html +0 -58
  526. package/docs/crawl/core/components/ui/form/checkbox/checkbox.html +0 -73
  527. package/docs/crawl/core/components/ui/form/fieldset/fieldset.html +0 -135
  528. package/docs/crawl/core/components/ui/form/form-actions/form-actions.html +0 -79
  529. package/docs/crawl/core/components/ui/form/form-layout/form-layout.html +0 -62
  530. package/docs/crawl/core/components/ui/form/input/input.html +0 -109
  531. package/docs/crawl/core/components/ui/form/input-autocomplete/input-autocomplete.html +0 -38
  532. package/docs/crawl/core/components/ui/form/radio/radio.html +0 -56
  533. package/docs/crawl/core/components/ui/form/select/select.html +0 -73
  534. package/docs/crawl/core/components/ui/form/switch/switch.html +0 -56
  535. package/docs/crawl/core/components/ui/form/textarea/textarea.html +0 -59
  536. package/docs/crawl/core/components/ui/group/group.html +0 -82
  537. package/docs/crawl/core/components/ui/icon/icon.html +0 -133
  538. package/docs/crawl/core/components/ui/image/image.html +0 -110
  539. package/docs/crawl/core/components/ui/link/link.html +0 -42
  540. package/docs/crawl/core/components/ui/loader/loader.html +0 -50
  541. package/docs/crawl/core/components/ui/modal/modal.html +0 -117
  542. package/docs/crawl/core/components/ui/pop/pop.html +0 -102
  543. package/docs/crawl/core/components/ui/progress/progress.html +0 -58
  544. package/docs/crawl/core/components/ui/table/table.html +0 -413
  545. package/docs/crawl/core/components/ui/toast/toast.html +0 -122
  546. package/docs/crawl/core/components/ui/tooltip/tooltip.html +0 -79
  547. package/docs/crawl/docs/_core-concept/overview.html +0 -66
  548. package/docs/crawl/docs/_core-concept/subscriber.html +0 -75
  549. package/docs/crawl/docs/_decorators/ancestor-attribute.html +0 -116
  550. package/docs/crawl/docs/_decorators/auto-subscribe.html +0 -202
  551. package/docs/crawl/docs/_decorators/bind.html +0 -141
  552. package/docs/crawl/docs/_decorators/get.html +0 -149
  553. package/docs/crawl/docs/_decorators/handle.html +0 -165
  554. package/docs/crawl/docs/_decorators/on-assign.html +0 -355
  555. package/docs/crawl/docs/_decorators/patch.html +0 -78
  556. package/docs/crawl/docs/_decorators/post.html +0 -139
  557. package/docs/crawl/docs/_decorators/publish.html +0 -61
  558. package/docs/crawl/docs/_decorators/put.html +0 -78
  559. package/docs/crawl/docs/_decorators/subscribe.html +0 -109
  560. package/docs/crawl/docs/_decorators/wait-for-ancestors.html +0 -137
  561. package/docs/crawl/docs/_directives/sub.html +0 -93
  562. package/docs/crawl/docs/_getting-started/concorde-manual-install.html +0 -100
  563. package/docs/crawl/docs/_getting-started/concorde-outside.html +0 -58
  564. package/docs/crawl/docs/_getting-started/my-first-subscriber.html +0 -110
  565. package/docs/crawl/docs/_getting-started/pubsub.html +0 -62
  566. package/docs/crawl/docs/_getting-started/start.html +0 -76
  567. package/docs/crawl/docs/_getting-started/theming.html +0 -85
  568. package/docs/crawl/docs/_misc/formelement-subscriber-removal.html +0 -138
  569. package/docs/crawl/hubs/decorators.html +0 -547
  570. package/docs/crawl/hubs/form-components.html +0 -359
  571. package/docs/crawl/hubs/remote-data.html +0 -452
  572. package/docs/crawl/index.html +0 -101
  573. package/docs/src/core/components/ui/form/input-autocomplete/input-autocomplete.md +0 -29
  574. package/docs/src/docs/_core-concept/overview.md +0 -57
  575. package/docs/src/docs/_core-concept/subscriber.md +0 -75
  576. package/docs/src/docs/_decorators/ancestor-attribute.md +0 -127
  577. package/docs/src/docs/_decorators/auto-subscribe.md +0 -202
  578. package/docs/src/docs/_decorators/bind.md +0 -167
  579. package/docs/src/docs/_decorators/get.md +0 -162
  580. package/docs/src/docs/_decorators/handle.md +0 -175
  581. package/docs/src/docs/_decorators/on-assign.md +0 -390
  582. package/docs/src/docs/_decorators/patch.md +0 -70
  583. package/docs/src/docs/_decorators/post.md +0 -146
  584. package/docs/src/docs/_decorators/publish.md +0 -55
  585. package/docs/src/docs/_decorators/put.md +0 -70
  586. package/docs/src/docs/_decorators/subscribe.md +0 -100
  587. package/docs/src/docs/_decorators/wait-for-ancestors.md +0 -163
  588. package/docs/src/docs/_directives/sub.md +0 -91
  589. package/docs/src/docs/_getting-started/concorde-manual-install.md +0 -133
  590. package/docs/src/docs/_getting-started/concorde-outside.md +0 -33
  591. package/docs/src/docs/_getting-started/my-first-subscriber.md +0 -120
  592. package/docs/src/docs/_getting-started/pubsub.md +0 -37
  593. package/docs/src/docs/_getting-started/start.md +0 -47
  594. package/docs/src/docs/_getting-started/theming.md +0 -91
  595. package/docs/src/docs/_misc/formelement-subscriber-removal.md +0 -115
  596. package/docs/src/tsconfig.declarations.json +0 -22
  597. package/docs/src/tsconfig.emit.json +0 -23
  598. package/gitlab/job_github_mirror.sh +0 -39
  599. package/scripts/github-export.mjs +0 -150
  600. package/src/core/components/ui/form/input-autocomplete/input-autocomplete.md +0 -29
  601. package/src/css.d.ts +0 -19
  602. package/src/docs/_core-concept/overview.md +0 -57
  603. package/src/docs/_core-concept/subscriber.md +0 -75
  604. package/src/docs/_decorators/ancestor-attribute.md +0 -128
  605. package/src/docs/_decorators/auto-subscribe.md +0 -202
  606. package/src/docs/_decorators/bind.md +0 -167
  607. package/src/docs/_decorators/get.md +0 -162
  608. package/src/docs/_decorators/handle.md +0 -175
  609. package/src/docs/_decorators/on-assign.md +0 -390
  610. package/src/docs/_decorators/patch.md +0 -70
  611. package/src/docs/_decorators/post.md +0 -146
  612. package/src/docs/_decorators/publish.md +0 -55
  613. package/src/docs/_decorators/put.md +0 -70
  614. package/src/docs/_decorators/subscribe.md +0 -100
  615. package/src/docs/_decorators/wait-for-ancestors.md +0 -163
  616. package/src/docs/_directives/sub.md +0 -91
  617. package/src/docs/_getting-started/concorde-manual-install.md +0 -133
  618. package/src/docs/_getting-started/concorde-outside.md +0 -33
  619. package/src/docs/_getting-started/my-first-subscriber.md +0 -120
  620. package/src/docs/_getting-started/pubsub.md +0 -37
  621. package/src/docs/_misc/formelement-subscriber-removal.md +0 -115
  622. package/src/docs/example/docs-input-autocomplete-demos.ts +0 -110
  623. package/src/docs/example/docs-joke-demos.ts +0 -297
  624. package/src/docs/prism/index.ts +0 -6
  625. package/src/docs/prism/prism.css +0 -158
  626. package/src/docs/prism/prism.js +0 -1022
  627. package/src/tsconfig.declarations.json +0 -22
  628. package/src/tsconfig.emit.json +0 -23
@@ -0,0 +1,389 @@
1
+ import { LitElement, html } from "lit";
2
+ import { customElement } from "lit/decorators.js";
3
+
4
+ /** The Concorde silhouette from the brand icon, nose up, in a 66 × 66 box centred on (33, 33). */
5
+ const PLANE =
6
+ "M33.2499 62.03C33.8799 59.24 34.26 56.17 34.39 53.08C34.57 52.78 34.9099 52.6 35.2599 52.64H35.39C35.48 52.64 35.5799 52.64 35.6899 52.64H35.7599C35.7599 52.64 35.7999 52.64 35.8299 52.64C36.2499 52.62 36.6799 52.58 36.9099 52.56C36.9399 52.56 36.9599 52.56 36.9799 52.56C37.0099 52.56 37.0299 52.56 37.0499 52.56H37.0899L37.2099 51.93H37.4799L37.5799 52.4L37.6899 52.49H39.2699L39.39 52.38L39.5099 51.93H39.7899L39.8399 52.21L39.9999 52.29L45.2099 51.86L46.2799 51.29C46.2799 51.29 46.2799 50.85 46.2399 50.25V50.18C46.2399 50.18 46.2399 50.13 46.2399 50.11C46.2099 49.62 46.1399 49.13 46.0399 48.65C45.7899 47.45 45.29 46 42.2 41.58C39.11 37.16 38.04 35.52 35.89 27.63C35.85 27.48 35.8199 27.35 35.7899 27.2C35.1399 24.53 34.6899 22.95 34.5199 22.38V10.89C34.4999 9.60996 34.3999 8.33996 34.2099 7.07996C34.0499 5.97996 33.6099 4.89996 33.3499 3.95996H32.6299C32.3599 4.89996 31.9299 5.97996 31.7699 7.06996C31.5799 8.33996 31.4799 9.60996 31.4599 10.89V22.38C31.2899 22.95 30.8299 24.52 30.1899 27.2C30.1599 27.35 30.1199 27.49 30.0899 27.63C27.9499 35.52 26.8699 37.16 23.7799 41.58C20.6899 46 20.1899 47.45 19.9399 48.65C19.8399 49.13 19.7799 49.62 19.7399 50.11C19.7399 50.13 19.7399 50.16 19.7399 50.18V50.25C19.6999 50.85 19.7 51.29 19.7 51.29L20.7699 51.86L25.9799 52.29L26.14 52.21L26.1899 51.93H26.4799L26.5999 52.38L26.7299 52.49H28.2999L28.4099 52.4L28.5099 51.93H28.7699L28.89 52.56H28.9399C28.9399 52.56 28.9799 52.56 29.0099 52.56C29.0299 52.56 29.0499 52.56 29.0799 52.56C29.3099 52.58 29.7499 52.63 30.1599 52.64C30.1799 52.64 30.2099 52.64 30.2299 52.64H30.2999C30.4099 52.64 30.5099 52.64 30.5999 52.64H30.7299C31.0799 52.6 31.4299 52.77 31.6099 53.08C31.7299 56.17 32.1099 59.24 32.7399 62.03H33.2499Z";
7
+
8
+ /** Speed of sound on the stage, in stage widths per second. */
9
+ const SOUND = 0.19;
10
+ /** Cruise: Concorde flew at Mach 2.02, 18 000 m up. */
11
+ const CRUISE = 2.02;
12
+ /** Grid cells across the field; every fourth line is heavier. */
13
+ const GRID = 24;
14
+ const WAVE_EVERY = 0.05;
15
+ const WAVE_LIFE = 2.6;
16
+
17
+ const clamp = (v: number, lo: number, hi: number) =>
18
+ Math.min(hi, Math.max(lo, v));
19
+ const smooth = (a: number, b: number, v: number) => {
20
+ const t = clamp((v - a) / (b - a), 0, 1);
21
+ return t * t * (3 - 2 * t);
22
+ };
23
+
24
+ type Wave = { x: number; y: number; t: number };
25
+
26
+ /**
27
+ * The hero's orange field as a Mach diagram: the aircraft drops a sound wave as it flies and,
28
+ * once it outruns them, the waves pile into the shock cone. On autopilot it accelerates through
29
+ * the barrier on every pass; a moving pointer steers it and moving fast
30
+ * enough breaks the barrier by hand. Reduced motion gets one still frame at cruise.
31
+ */
32
+ @customElement("docs-mach-stage")
33
+ export class DocsMachStage extends LitElement {
34
+ private canvas?: HTMLCanvasElement;
35
+ private ints: HTMLElement[] = [];
36
+ private decs: HTMLElement[] = [];
37
+ private plane = new Path2D(PLANE);
38
+ private waves: Wave[] = [];
39
+ private x = -0.3;
40
+ private y = 0.55;
41
+ private vx = 0.75 * SOUND;
42
+ private vy = 0;
43
+ private mach = 0;
44
+ private time = 0;
45
+ private lastWave = 0;
46
+ private pointer: { x: number; y: number; t: number } | null = null;
47
+ private boom = -10;
48
+ private frame = 0;
49
+ private last = 0;
50
+ private resize?: ResizeObserver;
51
+ private visible = true;
52
+ private io?: IntersectionObserver;
53
+
54
+ createRenderRoot() {
55
+ return this;
56
+ }
57
+
58
+ render() {
59
+ return html`<canvas class="mach-canvas" aria-hidden="true"></canvas>
60
+ <p class="mach-readout" aria-label="Concorde cruise speed: Mach 2.02">
61
+ <span class="mach-label">mach</span>
62
+ <span class="mach-value">
63
+ ${[
64
+ "mach-layer",
65
+ "mach-layer mach-ghost-a",
66
+ "mach-layer mach-ghost-b",
67
+ ].map(
68
+ (layer, i) =>
69
+ html`<span class=${layer} aria-hidden=${i ? "true" : "false"}
70
+ ><span class="mach-int">0</span><span class="mach-dot">.</span
71
+ ><span class="mach-dec">00</span></span
72
+ >`,
73
+ )}
74
+ </span>
75
+ </p>
76
+ <p class="mach-note">
77
+ cruise mach 2.02 · 18 000 m · paris – new york in 3 h 30
78
+ </p>`;
79
+ }
80
+
81
+ firstUpdated() {
82
+ this.canvas = this.querySelector("canvas")!;
83
+ this.ints = [...this.querySelectorAll<HTMLElement>(".mach-int")];
84
+ this.decs = [...this.querySelectorAll<HTMLElement>(".mach-dec")];
85
+ this.resize = new ResizeObserver(() => this.fit());
86
+ this.resize.observe(this);
87
+ this.io = new IntersectionObserver(
88
+ ([e]) => (this.visible = e.isIntersecting),
89
+ );
90
+ this.io.observe(this);
91
+ this.addEventListener("pointermove", this.onPointer);
92
+ this.addEventListener("pointerdown", this.onPointer);
93
+ this.addEventListener("pointerleave", this.onLeave);
94
+ this.fit();
95
+ if (matchMedia("(prefers-reduced-motion: reduce)").matches) {
96
+ this.still();
97
+ return;
98
+ }
99
+ this.frame = requestAnimationFrame(this.tick);
100
+ }
101
+
102
+ disconnectedCallback() {
103
+ super.disconnectedCallback();
104
+ cancelAnimationFrame(this.frame);
105
+ this.resize?.disconnect();
106
+ this.io?.disconnect();
107
+ }
108
+
109
+ private onPointer = (e: PointerEvent) => {
110
+ const r = this.getBoundingClientRect();
111
+ this.pointer = {
112
+ x: (e.clientX - r.left) / r.width,
113
+ y: (e.clientY - r.top) / r.width,
114
+ t: this.time,
115
+ };
116
+ };
117
+
118
+ private onLeave = () => {
119
+ this.pointer = null;
120
+ };
121
+
122
+ private fit() {
123
+ const c = this.canvas!;
124
+ const dpr = Math.min(devicePixelRatio || 1, 2);
125
+ c.width = Math.round(this.clientWidth * dpr);
126
+ c.height = Math.round(this.clientHeight * dpr);
127
+ // publish the grid cell so the field's bevel can be cut along the grid
128
+ this.parentElement?.style.setProperty(
129
+ "--mach-cell",
130
+ `${this.clientWidth / GRID}px`,
131
+ );
132
+ if (matchMedia("(prefers-reduced-motion: reduce)").matches) this.still();
133
+ }
134
+
135
+ /** Height of the field in stage widths (positions are kept in widths so speed is uniform). */
136
+ private get aspect() {
137
+ return this.clientHeight / Math.max(1, this.clientWidth);
138
+ }
139
+
140
+ private tick = (now: number) => {
141
+ this.frame = requestAnimationFrame(this.tick);
142
+ const dt = Math.min(0.05, (now - (this.last || now)) / 1000);
143
+ this.last = now;
144
+ if (!this.visible || !dt) return;
145
+ this.time += dt;
146
+ this.fly(dt);
147
+ if (this.time - this.lastWave > WAVE_EVERY) {
148
+ this.lastWave = this.time;
149
+ this.waves.push({ x: this.x, y: this.y, t: this.time });
150
+ }
151
+ this.waves = this.waves.filter((w) => this.time - w.t < WAVE_LIFE);
152
+ this.draw();
153
+ };
154
+
155
+ private fly(dt: number) {
156
+ const h = this.aspect;
157
+ const before = this.mach;
158
+ // flown by heading and speed, never by position, so it always carries on along an arc
159
+ let speed = Math.hypot(this.vx, this.vy);
160
+ let heading = Math.atan2(this.vy, this.vx);
161
+ let wantSpeed: number;
162
+ let wantHeading: number;
163
+ let turn: number;
164
+ let throttle: number;
165
+ const steering = this.pointer && this.time - this.pointer.t < 0.4;
166
+ if (steering) {
167
+ // head for a moving pointer; the further ahead it runs, the faster the aircraft goes
168
+ const dx = this.pointer!.x - this.x;
169
+ const dy = this.pointer!.y - this.y;
170
+ wantHeading = Math.atan2(dy, dx);
171
+ wantSpeed = clamp(Math.hypot(dx, dy) * 2.5, 0.6 * SOUND, 2.4 * SOUND);
172
+ turn = 5;
173
+ throttle = 4;
174
+ } else {
175
+ // autopilot: endless passes, speeding up to cruise across the field and easing off
176
+ // while out of sight, so each pass hands over to the next without a cut
177
+ const up = smooth(-0.1, 0.65, this.x);
178
+ const down = smooth(1.0, 1.2, this.x);
179
+ wantSpeed = (0.6 + (CRUISE - 0.6) * up * (1 - down)) * SOUND;
180
+ const cy = h * 0.55 + Math.sin(this.time * 0.6) * h * 0.06;
181
+ wantHeading = Math.atan2(cy - this.y, 0.6);
182
+ turn = 2;
183
+ throttle = 2;
184
+ }
185
+ let delta = wantHeading - heading;
186
+ delta = Math.atan2(Math.sin(delta), Math.cos(delta));
187
+ heading += delta * Math.min(1, dt * turn);
188
+ speed += (wantSpeed - speed) * Math.min(1, dt * throttle);
189
+ this.vx = Math.cos(heading) * speed;
190
+ this.vy = Math.sin(heading) * speed;
191
+ this.x += this.vx * dt;
192
+ this.y += this.vy * dt;
193
+ // out of sight on the right, back in on the left; the old waves fade where they were left
194
+ if (!steering && this.x > 1.3) this.x -= 1.6;
195
+ this.mach = speed / SOUND;
196
+ if (before < 1 && this.mach >= 1) this.boom = this.time;
197
+ }
198
+
199
+ private colours() {
200
+ const s = getComputedStyle(this);
201
+ return { ink: s.color, field: s.backgroundColor };
202
+ }
203
+
204
+ private draw() {
205
+ const c = this.canvas!;
206
+ const g = c.getContext("2d")!;
207
+ const W = c.width;
208
+ const u = W; // one stage width in device pixels
209
+ const { ink } = this.colours();
210
+ g.clearRect(0, 0, c.width, c.height);
211
+ g.strokeStyle = ink;
212
+ g.fillStyle = ink;
213
+ const px = this.x * u;
214
+ const py = this.y * u;
215
+
216
+ // graph paper under the diagram: a fine square grid, every fourth line heavier
217
+ const cell = u / GRID;
218
+ g.lineWidth = Math.max(1, u * 0.0008);
219
+ for (let i = 0, x = 0; x <= c.width; i++, x += cell) {
220
+ g.globalAlpha = i % 4 ? 0.1 : 0.22;
221
+ g.beginPath();
222
+ g.moveTo(Math.round(x) + 0.5, 0);
223
+ g.lineTo(Math.round(x) + 0.5, c.height);
224
+ g.stroke();
225
+ }
226
+ for (let i = 0, y = 0; y <= c.height; i++, y += cell) {
227
+ g.globalAlpha = i % 4 ? 0.1 : 0.22;
228
+ g.beginPath();
229
+ g.moveTo(0, Math.round(y) + 0.5);
230
+ g.lineTo(c.width, Math.round(y) + 0.5);
231
+ g.stroke();
232
+ }
233
+
234
+ // the shock cone, filled, once supersonic
235
+ if (this.mach > 1.02) {
236
+ const mu = Math.asin(1 / this.mach);
237
+ const dir = Math.atan2(this.vy, this.vx);
238
+ const len = u * 2;
239
+ g.globalAlpha = Math.min(0.22, (this.mach - 1) * 0.35);
240
+ g.beginPath();
241
+ g.moveTo(px, py);
242
+ g.lineTo(px - Math.cos(dir - mu) * len, py - Math.sin(dir - mu) * len);
243
+ g.lineTo(px - Math.cos(dir + mu) * len, py - Math.sin(dir + mu) * len);
244
+ g.closePath();
245
+ g.fill();
246
+ }
247
+
248
+ // the waves: each one a circle growing at the speed of sound from where it was dropped
249
+ g.lineWidth = Math.max(2, u * 0.003);
250
+ for (const w of this.waves) {
251
+ const age = this.time - w.t;
252
+ const r = age * SOUND * u;
253
+ g.globalAlpha = Math.max(0, 1 - age / WAVE_LIFE) * 0.9;
254
+ g.beginPath();
255
+ g.arc(w.x * u, w.y * u, r, 0, Math.PI * 2);
256
+ g.stroke();
257
+ }
258
+
259
+ this.construct(g, u, px, py);
260
+
261
+ // the boom: one heavy ring when the barrier goes
262
+ const since = this.time - this.boom;
263
+ if (since >= 0 && since < 1.4) {
264
+ g.globalAlpha = 1 - since / 1.4;
265
+ g.lineWidth = u * 0.018 * (1 - since / 1.4) + 2;
266
+ g.beginPath();
267
+ g.arc(px, py, since * SOUND * u * 3.2, 0, Math.PI * 2);
268
+ g.stroke();
269
+ }
270
+
271
+ // the aircraft, pointing where it flies
272
+ g.globalAlpha = 1;
273
+ const size = u * 0.15;
274
+ g.save();
275
+ g.translate(px, py);
276
+ g.rotate(Math.atan2(this.vy, this.vx) + Math.PI / 2);
277
+ g.scale(size / 66, size / 66);
278
+ g.translate(-33, -33);
279
+ g.fill(this.plane);
280
+ g.restore();
281
+
282
+ const [int, dec] = this.mach.toFixed(2).split(".");
283
+ for (const el of this.ints) el.textContent = int;
284
+ for (const el of this.decs) el.textContent = dec;
285
+ // the readout splits and shakes for a moment as the barrier goes
286
+ this.toggleAttribute("data-boom", since >= 0 && since < 0.9);
287
+ this.toggleAttribute("data-supersonic", this.mach >= 1);
288
+ }
289
+
290
+ /**
291
+ * Construction lines, as on a textbook figure: the flight path, the Mach lines run out to the
292
+ * edges, a few radii dropped square onto them from the centres that made them, and the angle.
293
+ */
294
+ private construct(
295
+ g: CanvasRenderingContext2D,
296
+ u: number,
297
+ px: number,
298
+ py: number,
299
+ ) {
300
+ const c = this.canvas!;
301
+ const dir = Math.atan2(this.vy, this.vx);
302
+ const reach = Math.hypot(c.width, c.height) * 2;
303
+ const line = (x1: number, y1: number, x2: number, y2: number) => {
304
+ g.beginPath();
305
+ g.moveTo(x1, y1);
306
+ g.lineTo(x2, y2);
307
+ g.stroke();
308
+ };
309
+ g.lineWidth = Math.max(1, u * 0.0012);
310
+
311
+ // flight path, dashed, through the whole field
312
+ g.globalAlpha = 0.45;
313
+ g.setLineDash([u * 0.012, u * 0.008]);
314
+ line(
315
+ px - Math.cos(dir) * reach,
316
+ py - Math.sin(dir) * reach,
317
+ px + Math.cos(dir) * reach,
318
+ py + Math.sin(dir) * reach,
319
+ );
320
+ g.setLineDash([]);
321
+
322
+ // centre marks where the waves were dropped
323
+ const mark = u * 0.006;
324
+ g.globalAlpha = 0.5;
325
+ this.waves.forEach((w, i) => {
326
+ if (i % 6) return;
327
+ line(w.x * u - mark, w.y * u, w.x * u + mark, w.y * u);
328
+ line(w.x * u, w.y * u - mark, w.x * u, w.y * u + mark);
329
+ });
330
+
331
+ if (this.mach <= 1.02) return;
332
+ const mu = Math.asin(1 / this.mach);
333
+ for (const side of [-1, 1]) {
334
+ const ex = Math.cos(dir + Math.PI + side * mu);
335
+ const ey = Math.sin(dir + Math.PI + side * mu);
336
+ // the Mach line, run out past the cone to the edge
337
+ g.globalAlpha = 0.6;
338
+ line(px, py, px + ex * reach, py + ey * reach);
339
+ // radii, square to the Mach line, from a few of the centres
340
+ g.globalAlpha = 0.45;
341
+ this.waves.forEach((w, i) => {
342
+ if (i % 12 || this.time - w.t < 0.5) return;
343
+ const cx = w.x * u;
344
+ const cy = w.y * u;
345
+ const along = (cx - px) * ex + (cy - py) * ey;
346
+ if (along <= 0) return;
347
+ line(cx, cy, px + ex * along, py + ey * along);
348
+ });
349
+ }
350
+
351
+ // the angle, marked at the apex, its value set just outside the cone where no wave reaches
352
+ const r = u * 0.12;
353
+ g.globalAlpha = 1;
354
+ g.lineWidth = Math.max(2, u * 0.003);
355
+ g.beginPath();
356
+ g.arc(px, py, r, dir + Math.PI - mu, dir + Math.PI + mu);
357
+ g.stroke();
358
+ const edge = dir + Math.PI + mu;
359
+ const out = edge + Math.PI / 2;
360
+ const gap = u * 0.03;
361
+ g.font = `600 ${Math.round(u * 0.024)}px ${getComputedStyle(this).fontFamily}`;
362
+ g.textAlign = "center";
363
+ g.textBaseline = "middle";
364
+ const deg = ((mu * 180) / Math.PI).toFixed(1);
365
+ g.fillText(
366
+ `μ ${deg}°`,
367
+ px + Math.cos(edge) * r * 1.1 + Math.cos(out) * gap,
368
+ py + Math.sin(edge) * r * 1.1 + Math.sin(out) * gap,
369
+ );
370
+ }
371
+
372
+ /** Reduced motion: the field at cruise, waves laid out as they would be, nothing moving. */
373
+ private still() {
374
+ if (!this.canvas) return;
375
+ const h = this.aspect;
376
+ this.x = 0.68;
377
+ this.y = h * 0.55;
378
+ this.vx = CRUISE * SOUND;
379
+ this.vy = 0;
380
+ this.mach = CRUISE;
381
+ this.time = WAVE_LIFE;
382
+ this.boom = -10;
383
+ this.waves = [];
384
+ for (let t = 0; t < WAVE_LIFE; t += WAVE_EVERY * 2) {
385
+ this.waves.push({ x: this.x - this.vx * (WAVE_LIFE - t), y: this.y, t });
386
+ }
387
+ this.draw();
388
+ }
389
+ }
@@ -1,18 +1,19 @@
1
- const onLocationChange = (location: Location) => {
2
- if (location.pathname === "/" && 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) {
3
8
  document.documentElement.setAttribute("data-home", "");
4
9
  } else {
5
10
  document.documentElement.removeAttribute("data-home");
6
11
  }
7
12
  };
8
- const getCurrentLocation = () => document.location;
9
- const currentLocation: Location = getCurrentLocation();
10
- onLocationChange(currentLocation);
11
- window.addEventListener("popstate", (event) => {
12
- onLocationChange(getCurrentLocation());
13
- });
14
13
 
15
- // Listen for changes in the URL hash
16
- window.addEventListener("hashchange", () => {
17
- 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
+ },
18
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)
@@ -0,0 +1,168 @@
1
+ # DataProviderKey
2
+
3
+ The `DataProviderKey<T>` utility provides type-safe navigation through composite data structures. Each property or index access extends the path, and the final key can be retrieved via `toString()` or the `path` property.
4
+
5
+ For a **single HTTP path string** (no dot-syntax), see [Endpoint](/docs/misc/endpoint). For **`DataProviderKey<APIConfiguration>`**, see [API configuration](/docs/misc/api-configuration).
6
+
7
+ ## Principle
8
+
9
+ `DataProviderKey` uses a Proxy to intercept property access and build a cumulative path string. TypeScript infers the nested type at each level, so `myKey.items[0]` is correctly typed as `DataProviderKey<Item>` when `items` is `Item[]`.
10
+
11
+ In Lit demos, bind HTML attributes from a key’s **`.path`** (single source of truth), and use **`get` / `set` / `dp`** instead of `PublisherManager.get("…")`:
12
+
13
+ <sonic-code language="typescript">
14
+ <template>
15
+ import { DataProviderKey } from "@supersoniks/concorde/dataProviderKey";
16
+ import { get, set } from "@supersoniks/concorde/utils";
17
+
18
+ export const myFormKey = new DataProviderKey&lt;{ email: string }&gt;("myForm");
19
+ set(myFormKey, { email: "a@b.c" });
20
+
21
+ // template: formDataProvider=${myFormKey.path}
22
+ </template>
23
+ </sonic-code>
24
+
25
+ ## Usage
26
+
27
+ ### Import
28
+
29
+ <sonic-code language="typescript">
30
+ <template>
31
+ import { DataProviderKey } from "@supersoniks/concorde/dataProviderKey";
32
+ </template>
33
+ </sonic-code>
34
+
35
+ ### Basic example
36
+
37
+ <sonic-code language="typescript">
38
+ <template>
39
+ type Item = { id: string; name: string };
40
+ //
41
+ type Data = {
42
+ items: Item[];
43
+ count: number;
44
+ };
45
+ //
46
+ const myKey = new DataProviderKey&lt;Data&gt;("data").items[0];
47
+ // Equivalent to: new DataProviderKey&lt;Item&gt;("data.items.0")
48
+ myKey.toString(); // "data.items.0"
49
+ myKey.path; // same value
50
+ // myKey is typed as DataProviderKey&lt;Item&gt;
51
+ </template>
52
+ </sonic-code>
53
+
54
+ ### Object property access
55
+
56
+ <sonic-code language="typescript">
57
+ <template>
58
+ const key = new DataProviderKey&lt;Data&gt;("data");
59
+ const countKey = key.count;
60
+ countKey.path; // "data.count"
61
+ countKey.toString(); // "data.count"
62
+ </template>
63
+ </sonic-code>
64
+
65
+ ### Array index access
66
+
67
+ <sonic-code language="typescript">
68
+ <template>
69
+ const itemsKey = new DataProviderKey&lt;Data&gt;("data").items;
70
+ itemsKey.path; // "data.items"
71
+ // itemsKey is DataProviderKey&lt;Item[]&gt;
72
+ //
73
+ const firstItem = itemsKey[0];
74
+ firstItem.path; // "data.items.0"
75
+ // firstItem is DataProviderKey&lt;Item&gt;
76
+ </template>
77
+ </sonic-code>
78
+
79
+ ### Dynamic paths
80
+
81
+ Use placeholders `${prop}` or `{$prop}` in the path string. The path is resolved at runtime from the component's properties. See [Dynamic path placeholders](/docs/misc/dynamic-path) for resolution rules and `skipEmptyPlaceholder`. The type remains declarative:
82
+
83
+ <sonic-code language="typescript">
84
+ <template>
85
+ type User = { name: string; email: string };
86
+ //
87
+ // Path resolved from component.userIndex at runtime
88
+ @subscribe(new DataProviderKey&lt;User&gt;("users.${userIndex}"))
89
+ @state()
90
+ user: User | null = null;
91
+ </template>
92
+ </sonic-code>
93
+
94
+ Dynamic keys are **not** supported by `get`, `set`, or `dp` — those APIs take a snapshot at call time with no component context. For dynamic paths use decorators (`@subscribe`, `@publish`, `@handle`) or **`sub(key)`** in Lit templates (resolves `${…}` from the host component). See [sub()](/docs/directives/sub).
95
+
96
+ ### get / set / dp with static keys
97
+
98
+ For programmatic access, pass a `DataProviderKey` or a static path string. Dynamic placeholders are rejected:
99
+
100
+ <sonic-code language="typescript">
101
+ <template>
102
+ import { dp, get, set } from "@supersoniks/concorde/utils";
103
+ import { DataProviderKey } from "@supersoniks/concorde/dataProviderKey";
104
+ //
105
+ const counterKey = new DataProviderKey&lt;{ count: number }&gt;("myCounter");
106
+ //
107
+ set(counterKey, { count: 0 });
108
+ dp(counterKey.count).set(1);
109
+ get(counterKey); // snapshot: { count: 1 }
110
+ </template>
111
+ </sonic-code>
112
+
113
+ ## Path retrieval
114
+
115
+ The final path is built by concatenating each accessed property with a dot:
116
+
117
+ - `new DataProviderKey<T>("base")` → `"base"`
118
+ - `key.prop` → `"base.prop"`
119
+ - `key.items[0]` → `"base.items.0"`
120
+
121
+ Use `toString()` or `path` to get the full path string:
122
+
123
+ <sonic-code language="typescript">
124
+ <template>
125
+ const key = new DataProviderKey&lt;Data&gt;("data").count;
126
+ const pathString = key.toString(); // "data.count"
127
+ const pathProp = key.path; // "data.count"
128
+ </template>
129
+ </sonic-code>
130
+
131
+ ## Use cases
132
+
133
+ - **Type-safe bindings**: paths for `@bind`, `@subscribe`, `@publish`, `@handle`
134
+ - **Dynamic paths**: reusable keys with `${...}` placeholders
135
+ - **Form fields**: form data paths with compile-time checking
136
+
137
+ ## Integration with @subscribe, @publish and @handle
138
+
139
+ Use `DataProviderKey` with `@subscribe` (read-only), `@publish` (write-only), or `@handle` (method callback on assign). With `@subscribe` / `@publish`, the decorated property **must** match the key’s value type. With `@handle`, the method receives `(value: T)`.
140
+
141
+ <sonic-code language="typescript">
142
+ <template>
143
+ import { subscribe } from "@supersoniks/concorde/decorators";
144
+ import { DataProviderKey } from "@supersoniks/concorde/dataProviderKey";
145
+ //
146
+ type FormData = { email: string };
147
+ const formKey = new DataProviderKey&lt;FormData&gt;("formData");
148
+ //
149
+ @customElement("user-form")
150
+ export class UserForm extends LitElement {
151
+ @subscribe(formKey.email)
152
+ @state()
153
+ email = "";
154
+ //
155
+ render() {
156
+ return html`&lt;input .value=${this.email} @input=${(e) => this.email = (e.target as HTMLInputElement).value}&gt;`;
157
+ }
158
+ }
159
+ </template>
160
+ </sonic-code>
161
+
162
+ These decorators support dynamic paths: `"base.${prop}"` in the constructor. A wrong property type (e.g. `number` for `DataProviderKey<string>`) is a TypeScript error. Resolution rules: [Dynamic path placeholders](/docs/misc/dynamic-path). See [@handle](/docs/decorators/handle) for method callbacks.
163
+
164
+ ## Notes
165
+
166
+ - Function properties are excluded from navigation (no `key.method()` chaining)
167
+ - Primitives have no navigable properties
168
+ - The `path` property and `toString()` are equivalent for retrieving the key