@supersoniks/concorde 5.0.5 → 5.1.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 (282) hide show
  1. package/.claude/launch.json +15 -0
  2. package/.claude/vite.http.config.mjs +7 -0
  3. package/.taste-skill/after/desktop-fold.jpg +0 -0
  4. package/.taste-skill/after/desktop-page-01.jpg +0 -0
  5. package/.taste-skill/after/desktop-page-02.jpg +0 -0
  6. package/.taste-skill/after/desktop-page-03.jpg +0 -0
  7. package/.taste-skill/after/mobile-fold.jpg +0 -0
  8. package/.taste-skill/after/mobile-page-01.jpg +0 -0
  9. package/.taste-skill/after/report.json +4103 -0
  10. package/.taste-skill/after/tablet-fold.jpg +0 -0
  11. package/.taste-skill/after/tablet-page-01.jpg +0 -0
  12. package/.taste-skill/after/tablet-page-02.jpg +0 -0
  13. package/.taste-skill/before/desktop-fold.jpg +0 -0
  14. package/.taste-skill/before/desktop-page-01.jpg +0 -0
  15. package/.taste-skill/before/desktop-page-02.jpg +0 -0
  16. package/.taste-skill/before/mobile-fold.jpg +0 -0
  17. package/.taste-skill/before/mobile-page-01.jpg +0 -0
  18. package/.taste-skill/before/report.json +2556 -0
  19. package/.taste-skill/before/tablet-fold.jpg +0 -0
  20. package/.taste-skill/before/tablet-page-01.jpg +0 -0
  21. package/.taste-skill/direction.json +510 -0
  22. package/.taste-skill/notes.md +84 -0
  23. package/.taste-skill/prod/desktop-fold.jpg +0 -0
  24. package/.taste-skill/prod/desktop-page-01.jpg +0 -0
  25. package/.taste-skill/prod/desktop-page-02.jpg +0 -0
  26. package/.taste-skill/prod/desktop-page-03.jpg +0 -0
  27. package/.taste-skill/prod/mobile-fold.jpg +0 -0
  28. package/.taste-skill/prod/mobile-page-01.jpg +0 -0
  29. package/.taste-skill/prod/mobile-page-02.jpg +0 -0
  30. package/.taste-skill/prod/report.json +1973 -0
  31. package/.taste-skill/prod/tablet-fold.jpg +0 -0
  32. package/.taste-skill/prod/tablet-page-01.jpg +0 -0
  33. package/.taste-skill/prod/tablet-page-02.jpg +0 -0
  34. package/.tmp-cem/custom-elements.json +13705 -0
  35. package/AUDIT.md +228 -0
  36. package/PLAN-AMELIORATION.md +220 -0
  37. package/build-infos.json +1 -1
  38. package/concorde-core.bundle.js +196 -196
  39. package/concorde-core.es.js +3854 -3572
  40. package/custom-elements-manifest.config.mjs +14 -0
  41. package/dist/concorde-core.bundle.js +196 -196
  42. package/dist/concorde-core.es.js +3854 -3572
  43. package/dist/img/archive/concorde-001-2cv.webp +0 -0
  44. package/dist/img/archive/concorde-red-arrows-2002-poster.jpg +0 -0
  45. package/dist/img/archive/concorde-red-arrows-2002.webm +0 -0
  46. package/dist/img/archive/credits.json +28 -0
  47. package/docs/assets/index-Bb-_LRyY.js +12280 -0
  48. package/docs/index.html +1 -1
  49. package/index.html +27 -63
  50. package/package.json +44 -3
  51. package/public/img/archive/concorde-001-2cv.webp +0 -0
  52. package/public/img/archive/concorde-red-arrows-2002-poster.jpg +0 -0
  53. package/public/img/archive/concorde-red-arrows-2002.webm +0 -0
  54. package/public/img/archive/credits.json +28 -0
  55. package/scripts/generate-sdui-catalog.mjs +250 -0
  56. package/scripts/generate-sdui-catalog.spec.ts +91 -0
  57. package/scripts/pre-build.mjs +15 -0
  58. package/src/core/components/functional/fetch/fetch.md +2 -2
  59. package/src/core/components/functional/sdui/SDUIDescriptorTransformer.ts +5 -5
  60. package/src/core/components/functional/sdui/__fixtures__/descriptors.ts +251 -0
  61. package/src/core/components/functional/sdui/__snapshots__/sdui-action.spec.ts.snap +73 -0
  62. package/src/core/components/functional/sdui/__snapshots__/sdui-incremental.spec.ts.snap +50 -0
  63. package/src/core/components/functional/sdui/__snapshots__/sdui-partial.spec.ts.snap +50 -0
  64. package/src/core/components/functional/sdui/__snapshots__/sdui.regression.spec.ts.snap +461 -0
  65. package/src/core/components/functional/sdui/component-catalog.gaps.json +511 -0
  66. package/src/core/components/functional/sdui/component-catalog.json +3103 -0
  67. package/src/core/components/functional/sdui/component-catalog.spec.ts +23 -0
  68. package/src/core/components/functional/sdui/sdui-action.spec.ts +99 -0
  69. package/src/core/components/functional/sdui/sdui-dom-snapshot.ts +61 -0
  70. package/src/core/components/functional/sdui/sdui-extension-points.md +94 -0
  71. package/src/core/components/functional/sdui/sdui-incremental.spec.ts +137 -0
  72. package/src/core/components/functional/sdui/sdui-partial.spec.ts +83 -0
  73. package/src/core/components/functional/sdui/sdui-partial.ts +19 -0
  74. package/src/core/components/functional/sdui/sdui-safe.spec.ts +188 -0
  75. package/src/core/components/functional/sdui/sdui-safe.ts +100 -0
  76. package/src/core/components/functional/sdui/sdui.md +122 -0
  77. package/src/core/components/functional/sdui/sdui.regression.spec.ts +64 -0
  78. package/src/core/components/functional/sdui/sdui.ts +442 -34
  79. package/src/core/components/functional/sdui/types.ts +49 -0
  80. package/src/core/components/ui/modal/modal.ts +14 -11
  81. package/src/docs/_getting-started/components.md +5 -0
  82. package/src/docs/_getting-started/theming.md +2 -2
  83. package/src/docs/code.ts +88 -75
  84. package/src/docs/components/docs-demo-sources.ts +16 -8
  85. package/src/docs/components/docs-lit-demo.ts +19 -37
  86. package/src/docs/docs.ts +5 -0
  87. package/src/docs/example/docs-boarding-pass-demo.ts +134 -0
  88. package/src/docs/example/docs-provider-keys.ts +12 -0
  89. package/src/docs/header/header.ts +233 -69
  90. package/src/docs/home/catalog.ts +44 -0
  91. package/src/docs/home/home.ts +513 -0
  92. package/src/docs/home/mach-stage.ts +389 -0
  93. package/src/docs/layout.ts +3 -1
  94. package/src/docs/navigation/components-index.ts +56 -0
  95. package/src/docs/navigation/navigation.ts +240 -232
  96. package/src/docs/navigation/pager.ts +67 -0
  97. package/src/docs/navigation/toc.ts +98 -0
  98. package/src/docs/search/docs-search.json +330 -20
  99. package/src/docs/search/markdown-renderer.ts +11 -3
  100. package/src/docs/shiki/index.ts +109 -0
  101. package/src/docs/tailwind/css/base/scrollbar.css +22 -0
  102. package/src/docs/tailwind/css/base/theme.css +96 -0
  103. package/src/docs/tailwind/css/base/typography.css +4 -0
  104. package/src/docs/tailwind/css/docs/boarding-pass.css +65 -0
  105. package/src/docs/tailwind/css/docs/content.css +32 -0
  106. package/src/docs/tailwind/css/docs/page.css +10 -0
  107. package/src/docs/tailwind/css/docs.css +9 -0
  108. package/src/docs/tailwind/css/home/hero.css +210 -0
  109. package/src/docs/tailwind/css/home/motion.css +84 -0
  110. package/src/docs/tailwind/css/home/sections.css +416 -0
  111. package/src/docs/tailwind/css/tailwind.css +7 -185
  112. package/src/tsconfig.json +113 -2
  113. package/src/tsconfig.tsbuildinfo +1 -1
  114. package/tailwind.config.js +8 -4
  115. package/docs/assets/index-wVZpLVYW.js +0 -12122
  116. package/docs/crawl/core/components/functional/date/date.html +0 -190
  117. package/docs/crawl/core/components/functional/fetch/fetch.html +0 -109
  118. package/docs/crawl/core/components/functional/if/if.html +0 -27
  119. package/docs/crawl/core/components/functional/jsonata/jsonata.html +0 -79
  120. package/docs/crawl/core/components/functional/list/list.html +0 -70
  121. package/docs/crawl/core/components/functional/mix/mix.html +0 -45
  122. package/docs/crawl/core/components/functional/queue/queue.html +0 -96
  123. package/docs/crawl/core/components/functional/router/router.html +0 -106
  124. package/docs/crawl/core/components/functional/sdui/sdui.html +0 -269
  125. package/docs/crawl/core/components/functional/states/states.html +0 -66
  126. package/docs/crawl/core/components/functional/submit/submit.html +0 -160
  127. package/docs/crawl/core/components/functional/subscriber/subscriber.html +0 -67
  128. package/docs/crawl/core/components/functional/value/value.html +0 -51
  129. package/docs/crawl/core/components/ui/alert/alert.html +0 -211
  130. package/docs/crawl/core/components/ui/alert-messages/alert-messages.html +0 -131
  131. package/docs/crawl/core/components/ui/badge/badge.html +0 -197
  132. package/docs/crawl/core/components/ui/button/button.html +0 -150
  133. package/docs/crawl/core/components/ui/captcha/captcha.html +0 -112
  134. package/docs/crawl/core/components/ui/card/card.html +0 -253
  135. package/docs/crawl/core/components/ui/divider/divider.html +0 -144
  136. package/docs/crawl/core/components/ui/form/checkbox/checkbox.html +0 -73
  137. package/docs/crawl/core/components/ui/form/fieldset/fieldset.html +0 -266
  138. package/docs/crawl/core/components/ui/form/form-actions/form-actions.html +0 -122
  139. package/docs/crawl/core/components/ui/form/form-layout/form-layout.html +0 -121
  140. package/docs/crawl/core/components/ui/form/input/input.html +0 -109
  141. package/docs/crawl/core/components/ui/form/input-autocomplete/input-autocomplete.html +0 -38
  142. package/docs/crawl/core/components/ui/form/radio/radio.html +0 -56
  143. package/docs/crawl/core/components/ui/form/select/select.html +0 -73
  144. package/docs/crawl/core/components/ui/form/switch/switch.html +0 -56
  145. package/docs/crawl/core/components/ui/form/textarea/textarea.html +0 -59
  146. package/docs/crawl/core/components/ui/group/group.html +0 -104
  147. package/docs/crawl/core/components/ui/icon/icon.html +0 -222
  148. package/docs/crawl/core/components/ui/image/image.html +0 -298
  149. package/docs/crawl/core/components/ui/link/link.html +0 -100
  150. package/docs/crawl/core/components/ui/loader/loader.html +0 -124
  151. package/docs/crawl/core/components/ui/menu/menu.html +0 -394
  152. package/docs/crawl/core/components/ui/modal/modal.html +0 -342
  153. package/docs/crawl/core/components/ui/pop/pop.html +0 -296
  154. package/docs/crawl/core/components/ui/progress/progress.html +0 -131
  155. package/docs/crawl/core/components/ui/table/table.html +0 -545
  156. package/docs/crawl/core/components/ui/theme/theme.html +0 -131
  157. package/docs/crawl/core/components/ui/toast/toast.html +0 -233
  158. package/docs/crawl/core/components/ui/tooltip/tooltip.html +0 -140
  159. package/docs/crawl/docs/_core-concept/dataFlow.html +0 -177
  160. package/docs/crawl/docs/_core-concept/overview.html +0 -66
  161. package/docs/crawl/docs/_core-concept/subscriber.html +0 -75
  162. package/docs/crawl/docs/_decorators/ancestor-attribute.html +0 -117
  163. package/docs/crawl/docs/_decorators/auto-subscribe.html +0 -202
  164. package/docs/crawl/docs/_decorators/bind.html +0 -141
  165. package/docs/crawl/docs/_decorators/get.html +0 -149
  166. package/docs/crawl/docs/_decorators/handle.html +0 -165
  167. package/docs/crawl/docs/_decorators/on-assign.html +0 -355
  168. package/docs/crawl/docs/_decorators/patch.html +0 -78
  169. package/docs/crawl/docs/_decorators/post.html +0 -139
  170. package/docs/crawl/docs/_decorators/publish.html +0 -61
  171. package/docs/crawl/docs/_decorators/put.html +0 -78
  172. package/docs/crawl/docs/_decorators/subscribe.html +0 -109
  173. package/docs/crawl/docs/_decorators/wait-for-ancestors.html +0 -137
  174. package/docs/crawl/docs/_directives/sub.html +0 -93
  175. package/docs/crawl/docs/_getting-started/ai-agents.html +0 -173
  176. package/docs/crawl/docs/_getting-started/concorde-manual-install.html +0 -100
  177. package/docs/crawl/docs/_getting-started/concorde-outside.html +0 -58
  178. package/docs/crawl/docs/_getting-started/create-a-component.html +0 -111
  179. package/docs/crawl/docs/_getting-started/my-first-component.html +0 -189
  180. package/docs/crawl/docs/_getting-started/my-first-subscriber.html +0 -110
  181. package/docs/crawl/docs/_getting-started/pubsub.html +0 -62
  182. package/docs/crawl/docs/_getting-started/start.html +0 -76
  183. package/docs/crawl/docs/_getting-started/theming.html +0 -333
  184. package/docs/crawl/docs/_misc/api-configuration.html +0 -149
  185. package/docs/crawl/docs/_misc/dataProviderKey.html +0 -135
  186. package/docs/crawl/docs/_misc/docs-mock-api.html +0 -158
  187. package/docs/crawl/docs/_misc/dynamic-path.html +0 -180
  188. package/docs/crawl/docs/_misc/endpoint.html +0 -50
  189. package/docs/crawl/docs/_misc/formelement-subscriber-removal.html +0 -138
  190. package/docs/crawl/docs/_misc/html-integration.html +0 -48
  191. package/docs/crawl/hubs/decorators.html +0 -547
  192. package/docs/crawl/hubs/form-components.html +0 -381
  193. package/docs/crawl/hubs/remote-data.html +0 -452
  194. package/docs/crawl/index.html +0 -102
  195. package/docs/llms-full.txt +0 -7008
  196. package/docs/llms.txt +0 -97
  197. package/docs/sitemap.xml +0 -240
  198. package/docs/src/core/components/functional/date/date.md +0 -290
  199. package/docs/src/core/components/functional/fetch/fetch.md +0 -125
  200. package/docs/src/core/components/functional/if/if.md +0 -9
  201. package/docs/src/core/components/functional/jsonata/jsonata.md +0 -56
  202. package/docs/src/core/components/functional/list/list.md +0 -65
  203. package/docs/src/core/components/functional/mix/mix.md +0 -41
  204. package/docs/src/core/components/functional/queue/queue.md +0 -72
  205. package/docs/src/core/components/functional/router/router.md +0 -94
  206. package/docs/src/core/components/functional/sdui/default-library.json +0 -108
  207. package/docs/src/core/components/functional/sdui/example.json +0 -99
  208. package/docs/src/core/components/functional/sdui/sdui.md +0 -356
  209. package/docs/src/core/components/functional/states/states.md +0 -87
  210. package/docs/src/core/components/functional/submit/submit.md +0 -114
  211. package/docs/src/core/components/functional/subscriber/subscriber.md +0 -91
  212. package/docs/src/core/components/functional/value/value.md +0 -35
  213. package/docs/src/core/components/ui/alert/alert.md +0 -196
  214. package/docs/src/core/components/ui/alert-messages/alert-messages.md +0 -85
  215. package/docs/src/core/components/ui/badge/badge.md +0 -188
  216. package/docs/src/core/components/ui/button/button.md +0 -183
  217. package/docs/src/core/components/ui/captcha/captcha.md +0 -71
  218. package/docs/src/core/components/ui/card/card.md +0 -215
  219. package/docs/src/core/components/ui/divider/divider.md +0 -129
  220. package/docs/src/core/components/ui/form/checkbox/checkbox.md +0 -77
  221. package/docs/src/core/components/ui/form/fieldset/fieldset.md +0 -205
  222. package/docs/src/core/components/ui/form/form-actions/form-actions.md +0 -100
  223. package/docs/src/core/components/ui/form/form-layout/form-layout.md +0 -119
  224. package/docs/src/core/components/ui/form/input/input.md +0 -142
  225. package/docs/src/core/components/ui/form/input-autocomplete/input-autocomplete.md +0 -29
  226. package/docs/src/core/components/ui/form/radio/radio.md +0 -57
  227. package/docs/src/core/components/ui/form/select/select.md +0 -71
  228. package/docs/src/core/components/ui/form/switch/switch.md +0 -57
  229. package/docs/src/core/components/ui/form/textarea/textarea.md +0 -65
  230. package/docs/src/core/components/ui/group/group.md +0 -75
  231. package/docs/src/core/components/ui/icon/icon.md +0 -214
  232. package/docs/src/core/components/ui/icon/icons.json +0 -1
  233. package/docs/src/core/components/ui/image/image.md +0 -233
  234. package/docs/src/core/components/ui/link/link.md +0 -81
  235. package/docs/src/core/components/ui/loader/loader.md +0 -112
  236. package/docs/src/core/components/ui/menu/menu.md +0 -370
  237. package/docs/src/core/components/ui/modal/modal.md +0 -235
  238. package/docs/src/core/components/ui/pop/pop.md +0 -294
  239. package/docs/src/core/components/ui/progress/progress.md +0 -109
  240. package/docs/src/core/components/ui/table/table.md +0 -431
  241. package/docs/src/core/components/ui/theme/theme.md +0 -122
  242. package/docs/src/core/components/ui/toast/toast.md +0 -216
  243. package/docs/src/core/components/ui/tooltip/tooltip.md +0 -124
  244. package/docs/src/docs/_core-concept/dataFlow.md +0 -88
  245. package/docs/src/docs/_core-concept/overview.md +0 -57
  246. package/docs/src/docs/_core-concept/subscriber.md +0 -75
  247. package/docs/src/docs/_decorators/ancestor-attribute.md +0 -128
  248. package/docs/src/docs/_decorators/auto-subscribe.md +0 -202
  249. package/docs/src/docs/_decorators/bind.md +0 -167
  250. package/docs/src/docs/_decorators/get.md +0 -162
  251. package/docs/src/docs/_decorators/handle.md +0 -175
  252. package/docs/src/docs/_decorators/on-assign.md +0 -390
  253. package/docs/src/docs/_decorators/patch.md +0 -70
  254. package/docs/src/docs/_decorators/post.md +0 -146
  255. package/docs/src/docs/_decorators/publish.md +0 -55
  256. package/docs/src/docs/_decorators/put.md +0 -70
  257. package/docs/src/docs/_decorators/subscribe.md +0 -100
  258. package/docs/src/docs/_decorators/wait-for-ancestors.md +0 -163
  259. package/docs/src/docs/_directives/sub.md +0 -91
  260. package/docs/src/docs/_getting-started/ai-agents.md +0 -76
  261. package/docs/src/docs/_getting-started/concorde-manual-install.md +0 -133
  262. package/docs/src/docs/_getting-started/concorde-outside.md +0 -33
  263. package/docs/src/docs/_getting-started/create-a-component.md +0 -139
  264. package/docs/src/docs/_getting-started/my-first-component.md +0 -236
  265. package/docs/src/docs/_getting-started/my-first-subscriber.md +0 -120
  266. package/docs/src/docs/_getting-started/pubsub.md +0 -37
  267. package/docs/src/docs/_getting-started/start.md +0 -47
  268. package/docs/src/docs/_getting-started/theming.md +0 -253
  269. package/docs/src/docs/_misc/api-configuration.md +0 -81
  270. package/docs/src/docs/_misc/dataProviderKey.md +0 -168
  271. package/docs/src/docs/_misc/docs-mock-api.md +0 -63
  272. package/docs/src/docs/_misc/dynamic-path.md +0 -71
  273. package/docs/src/docs/_misc/endpoint.md +0 -45
  274. package/docs/src/docs/_misc/formelement-subscriber-removal.md +0 -115
  275. package/docs/src/docs/_misc/html-integration.md +0 -15
  276. package/docs/src/docs/search/docs-search.json +0 -12242
  277. package/docs/src/tag-list.json +0 -1
  278. package/docs/src/tsconfig-model.json +0 -23
  279. package/docs/src/tsconfig.json +0 -1242
  280. package/src/docs/prism/index.ts +0 -6
  281. package/src/docs/prism/prism.css +0 -158
  282. package/src/docs/prism/prism.js +0 -1022
@@ -0,0 +1,5 @@
1
+ # Components
2
+
3
+ Every Concorde web component, grouped like the sidebar. Pick one to see its live demos, attributes and import path.
4
+
5
+ <docs-components-index></docs-components-index>
@@ -1,4 +1,4 @@
1
- # Customization
1
+ # Theming
2
2
 
3
3
  ## Theme-first customization
4
4
 
@@ -10,7 +10,7 @@ Concorde derives radius steps, button/input rounding, shadows, and most per-comp
10
10
 
11
11
  <sonic-code language="html">
12
12
  <template>
13
- <sonic-theme color font class="block bg-base min-h-screen">
13
+ <sonic-theme color font >
14
14
  <!-- your app -->
15
15
  </sonic-theme>
16
16
  </template>
package/src/docs/code.ts CHANGED
@@ -7,42 +7,18 @@ import { query } from "lit/decorators/query.js";
7
7
 
8
8
  import SDUIUtils from "../core/components/functional/sdui/sdui-utils";
9
9
 
10
- import "./prism/prism";
11
- import { prismCSS } from "./prism";
12
- import * as Prism from "prismjs";
13
- import "prismjs/plugins/normalize-whitespace/prism-normalize-whitespace";
14
- import "prismjs/components/prism-json"; // Language
15
- import "prismjs/components/prism-typescript"; // Language
16
- import "prismjs/components/prism-javascript"; // Language
17
- import "prismjs/components/prism-bash"; // Language
18
- // import "prismjs/components/prism-css"; // Language
19
- import "prismjs/components/prism-markup"; // Language
20
-
21
- let normalizeWhitespaceDefaultsApplied = false;
22
-
23
- function normalizeDocsCodeLanguage(language: string): string {
24
- return language === "html" ? "markup" : language;
25
- }
26
-
27
- function applyNormalizeWhitespaceDefaults(): void {
28
- if (normalizeWhitespaceDefaultsApplied) return;
29
- normalizeWhitespaceDefaultsApplied = true;
30
- Prism.plugins.NormalizeWhitespace.setDefaults({
31
- "remove-trailing": true,
32
- "remove-indent": true,
33
- "left-trim": true,
34
- "right-trim": true,
35
- "remove-initial-line-feed": true,
36
- "tabs-to-tabs": 2,
37
- });
38
- }
10
+ import {
11
+ docsCodeCSS,
12
+ highlightDocsCode,
13
+ normalizeDocsCodeLanguage,
14
+ } from "./shiki";
39
15
 
40
16
  const tagName = "sonic-code";
41
17
  @customElement(tagName)
42
18
  export class DocsCode extends LitElement {
43
19
  static styles = [
44
20
  tailwind,
45
- prismCSS,
21
+ docsCodeCSS,
46
22
  css`
47
23
  :host(:not([inline])) {
48
24
  display: block;
@@ -53,11 +29,7 @@ export class DocsCode extends LitElement {
53
29
  display: inline-block;
54
30
  }
55
31
  pre {
56
- font-size: 13px !important;
57
32
  padding-right: 5rem !important;
58
- border: 1px solid var(--sc-base-200);
59
- border-radius: var(--sc-rounded);
60
- margin: 0 !important;
61
33
  }
62
34
  .custom-scroll {
63
35
  overflow: auto !important;
@@ -82,6 +54,34 @@ export class DocsCode extends LitElement {
82
54
  border-radius: var(--sc-rounded);
83
55
  border: solid 0.15rem transparent;
84
56
  }
57
+
58
+ /* Tall blocks are folded behind a fade; a click unfolds them */
59
+ pre.collapsible {
60
+ transition: max-height 0.4s ease;
61
+ }
62
+ pre.collapsible:not(.expanded) {
63
+ max-height: var(--docs-code-max-height, 15rem);
64
+ overflow-y: hidden !important;
65
+ }
66
+ pre.overflowing:not(.expanded) {
67
+ cursor: pointer;
68
+ }
69
+ /* fade the code only: the block keeps its background and corners */
70
+ pre.overflowing:not(.expanded) > code {
71
+ display: block;
72
+ /* span the longest line, or the mask would clip horizontal overflow */
73
+ width: max-content;
74
+ min-width: 100%;
75
+ /* fade over the last 11rem; on hover the mask slides down a little */
76
+ mask-image: linear-gradient(to bottom, #000 calc(100% - 11rem), transparent);
77
+ mask-size: 100% var(--docs-code-max-height, 20rem);
78
+ mask-repeat: no-repeat;
79
+ mask-position: 0 -2rem;
80
+ transition: mask-position 0.35s ease;
81
+ }
82
+ pre.overflowing:not(.expanded):hover > code {
83
+ mask-position: 0 0;
84
+ }
85
85
  `,
86
86
  ];
87
87
 
@@ -90,6 +90,8 @@ export class DocsCode extends LitElement {
90
90
  @property({ type: Boolean, reflect: true }) showCode = false;
91
91
  @property({ type: Boolean, reflect: true }) toggleCode = false;
92
92
  @property({ type: Boolean, reflect: true }) noEdit = false;
93
+ /** Markup shown as code only: no live preview (e.g. PHP / Vue snippets). */
94
+ @property({ type: Boolean, reflect: true }) noPreview = false;
93
95
 
94
96
  @property() language = "markup";
95
97
  @property({ attribute: false }) defaultCode?: string;
@@ -101,14 +103,16 @@ export class DocsCode extends LitElement {
101
103
  private templateEl: HTMLTemplateElement | null = null;
102
104
 
103
105
  @state() codeEdited = false;
106
+ @state() private overflowing = false;
107
+ @state() private expanded = false;
104
108
 
105
109
  /** Live preview only for markup (avoid injecting HTML from JS/TS examples). */
106
- private get prismLanguage(): string {
110
+ private get highlightLanguage(): string {
107
111
  return normalizeDocsCodeLanguage(this.language);
108
112
  }
109
113
 
110
114
  private get rendersLiveOutput(): boolean {
111
- return this.prismLanguage === "markup";
115
+ return this.highlightLanguage === "html" && !this.noPreview;
112
116
  }
113
117
 
114
118
  connectedCallback() {
@@ -128,29 +132,12 @@ export class DocsCode extends LitElement {
128
132
  }
129
133
  }
130
134
 
131
- private normalizeSourceForHighlight(source: string): string {
132
- applyNormalizeWhitespaceDefaults();
133
- const nw = Prism.plugins.NormalizeWhitespace;
134
- return nw
135
- .normalize(source)
136
- .replaceAll('=""', "")
137
- .replaceAll("&quot;", '"')
138
- .replaceAll('"{', "'{")
139
- .replaceAll('}"', "}'")
140
- .replaceAll("&amp;", "&");
141
- }
142
-
143
- private highlightSource(source: string): string {
144
- const lang = this.prismLanguage;
145
- const grammar = Prism.languages[lang];
146
- if (!grammar) {
147
- return source;
135
+ private async applyHighlightFromSource(source: string | undefined) {
136
+ if (!source) {
137
+ this.currentCode = undefined;
138
+ return;
148
139
  }
149
- return Prism.highlight(
150
- this.normalizeSourceForHighlight(source),
151
- grammar,
152
- lang,
153
- );
140
+ this.currentCode = await highlightDocsCode(source, this.language);
154
141
  }
155
142
 
156
143
  private syncFromTemplate() {
@@ -158,11 +145,7 @@ export class DocsCode extends LitElement {
158
145
  this.defaultCode = this.readTemplateSourceCode();
159
146
  this.codeEdited = false;
160
147
 
161
- if (this.defaultCode) {
162
- this.currentCode = this.highlightSource(this.defaultCode);
163
- } else {
164
- this.currentCode = undefined;
165
- }
148
+ void this.applyHighlightFromSource(this.defaultCode);
166
149
 
167
150
  if (this.rendersLiveOutput) {
168
151
  this.codeOutput = this.defaultCode;
@@ -175,11 +158,7 @@ export class DocsCode extends LitElement {
175
158
  this.defaultCode = this.readTemplateSourceCode();
176
159
  this.codeEdited = false;
177
160
 
178
- if (this.defaultCode) {
179
- this.currentCode = this.highlightSource(this.defaultCode);
180
- } else {
181
- this.currentCode = undefined;
182
- }
161
+ void this.applyHighlightFromSource(this.defaultCode);
183
162
 
184
163
  if (this.rendersLiveOutput) {
185
164
  this.codeOutput = this.defaultCode;
@@ -204,7 +183,7 @@ export class DocsCode extends LitElement {
204
183
  const template = this.templateEl ?? this.querySelector("template");
205
184
  if (!template) return "";
206
185
 
207
- if (this.prismLanguage === "markup") {
186
+ if (this.highlightLanguage === "html") {
208
187
  return this.decodeTemplateEntities(template.innerHTML);
209
188
  }
210
189
 
@@ -231,7 +210,7 @@ export class DocsCode extends LitElement {
231
210
  if (this.defaultCode) {
232
211
  this.currentCode = "";
233
212
  window.requestAnimationFrame(() => {
234
- this.currentCode = this.highlightSource(this.defaultCode || "");
213
+ void this.applyHighlightFromSource(this.defaultCode);
235
214
  });
236
215
  }
237
216
  if (this.rendersLiveOutput) {
@@ -269,6 +248,7 @@ export class DocsCode extends LitElement {
269
248
 
270
249
  updated(changedProperties: PropertyValues) {
271
250
  super.updated(changedProperties);
251
+ this.measureOverflow();
272
252
  if (
273
253
  changedProperties.has("codeOutput") ||
274
254
  changedProperties.has("language")
@@ -298,12 +278,38 @@ export class DocsCode extends LitElement {
298
278
  }
299
279
  }
300
280
 
281
+ private measureOverflow() {
282
+ const pre = this.codePreview;
283
+ if (!pre || this.inline || this.expanded) return;
284
+ // Folding to hide only a few lines is just friction: show those in full.
285
+ if (
286
+ pre.scrollHeight > pre.clientHeight + 4 &&
287
+ pre.scrollHeight < pre.clientHeight * 1.3
288
+ ) {
289
+ this.expanded = true;
290
+ return;
291
+ }
292
+ const overflowing = pre.scrollHeight > pre.clientHeight + 4;
293
+ if (overflowing !== this.overflowing) this.overflowing = overflowing;
294
+ }
295
+
296
+ private expand() {
297
+ if (!this.overflowing || this.expanded) return;
298
+ const pre = this.codePreview;
299
+ pre.style.maxHeight = `${pre.scrollHeight}px`;
300
+ // Release the height once unfolded, so edited code can still grow.
301
+ pre.addEventListener("transitionend", () => (pre.style.maxHeight = ""), {
302
+ once: true,
303
+ });
304
+ this.expanded = true;
305
+ }
306
+
301
307
  handleGetSDUI() {
302
308
  SDUIUtils.toJson(this.templateEl?.content.children);
303
309
  }
304
310
 
305
311
  render() {
306
- const isMarkup = this.prismLanguage === "markup";
312
+ const isMarkup = this.rendersLiveOutput;
307
313
 
308
314
  return html`
309
315
  <div
@@ -316,7 +322,11 @@ export class DocsCode extends LitElement {
316
322
  : nothing}
317
323
 
318
324
  <div class="relative">
319
- <div class="flex justify-end absolute right-2 gap-1 mt-2">
325
+ <div
326
+ class="flex justify-end gap-1 z-10 ${this.showCode && this.currentCode
327
+ ? "absolute right-2 mt-2"
328
+ : ""}"
329
+ >
320
330
  ${this.codeEdited
321
331
  ? html`<sonic-button
322
332
  size="2xs"
@@ -383,10 +393,13 @@ export class DocsCode extends LitElement {
383
393
  <div>
384
394
  <pre
385
395
  id="codePreview"
386
- class="rounded-md custom-scroll language-${this.prismLanguage} ${!this
387
- .showCode || !this.currentCode
396
+ class="rounded-md custom-scroll language-${this
397
+ .highlightLanguage} ${!this.showCode || !this.currentCode
388
398
  ? "hidden"
389
- : ""}"
399
+ : ""} ${this.inline ? "" : "collapsible"} ${this.overflowing
400
+ ? "overflowing"
401
+ : ""} ${this.expanded ? "expanded" : ""}"
402
+ @click=${this.expand}
390
403
  ?contenteditable=${!this.noEdit}
391
404
  spellcheck="false"
392
405
  @input=${this.updateCodeRender}
@@ -5,10 +5,7 @@ import { tailwind } from "../tailwind";
5
5
  import { docsSourceLinks, type DocsSource } from "./docs-source-link";
6
6
  import { DOCS_SOURCE_RAW } from "./docs-source-raw";
7
7
  import { resolveSourceExcerpt } from "./docs-source-excerpt";
8
- import "../prism/prism";
9
- import { prismCSS } from "../prism";
10
- import * as Prism from "prismjs";
11
- import "prismjs/components/prism-typescript";
8
+ import { docsCodeCSS, highlightDocsCode } from "../shiki";
12
9
 
13
10
  export type { DocsSource };
14
11
 
@@ -23,6 +20,15 @@ export type DocsLitDemoConfig = {
23
20
  };
24
21
 
25
22
  export const DOCS_LIT_DEMO_REGISTRY: Record<string, DocsLitDemoConfig> = {
23
+ "docs-boarding-pass-demo": {
24
+ sources: [
25
+ {
26
+ path: "src/docs/example/docs-boarding-pass-demo.ts",
27
+ line: 19,
28
+ label: "docs-boarding-pass-demo",
29
+ },
30
+ ],
31
+ },
26
32
  "docs-toggle-if-demo": {
27
33
  sources: [
28
34
  {
@@ -528,15 +534,15 @@ export const DOCS_DEMO_SOURCE_REGISTRY: Record<string, DocsSource[]> = {
528
534
  ],
529
535
  };
530
536
 
531
- function highlightTs(code: string): string {
532
- return Prism.highlight(code, Prism.languages.typescript, "typescript");
537
+ function highlightTs(code: string): Promise<string> {
538
+ return highlightDocsCode(code, "typescript");
533
539
  }
534
540
 
535
541
  @customElement("docs-demo-sources")
536
542
  export class DocsDemoSources extends LitElement {
537
543
  static styles = [
538
544
  tailwind,
539
- prismCSS,
545
+ docsCodeCSS,
540
546
  css`
541
547
  :host {
542
548
  display: block;
@@ -588,7 +594,9 @@ export class DocsDemoSources extends LitElement {
588
594
  const excerpt = resolveSourceExcerpt(raw, this.forTag, {
589
595
  line: primary.line,
590
596
  });
591
- this.highlighted = highlightTs(excerpt);
597
+ void highlightTs(excerpt).then((html) => {
598
+ this.highlighted = html;
599
+ });
592
600
  }
593
601
 
594
602
  render() {
@@ -1,5 +1,5 @@
1
- import { css, html, LitElement, nothing } from "lit";
2
- import { customElement, property, state } from "lit/decorators.js";
1
+ import { css, html, LitElement, nothing, PropertyValues } from "lit";
2
+ import { customElement, property } from "lit/decorators.js";
3
3
  import { unsafeHTML } from "lit/directives/unsafe-html.js";
4
4
  import { tailwind } from "../tailwind";
5
5
  import { docsSourceLinks } from "./docs-source-link";
@@ -8,17 +8,8 @@ import {
8
8
  type DocsLitDemoConfig,
9
9
  } from "./docs-demo-sources";
10
10
 
11
- import "../prism/prism";
12
- import { prismCSS } from "../prism";
13
- import * as Prism from "prismjs";
14
- import "prismjs/components/prism-typescript";
15
-
16
11
  import { DOCS_SOURCE_RAW } from "./docs-source-raw";
17
- import {
18
- excerptLines,
19
- excerptForCustomElement,
20
- resolveSourceExcerpt,
21
- } from "./docs-source-excerpt";
12
+ import { excerptLines, resolveSourceExcerpt } from "./docs-source-excerpt";
22
13
 
23
14
  export { excerptForCustomElement } from "./docs-source-excerpt";
24
15
 
@@ -33,9 +24,9 @@ function resolveDemoExcerpt(
33
24
  return resolveSourceExcerpt(raw, liveTag);
34
25
  }
35
26
 
36
- function highlightTs(code: string): string {
37
- return Prism.highlight(code, Prism.languages.typescript, "typescript");
38
- }
27
+ /** Escape so tags in the TS excerpt stay text inside &lt;template&gt; (same as home.ts). */
28
+ const escapeCode = (code: string) =>
29
+ code.replace(/&/g, "&amp;").replace(/</g, "&lt;").replace(/>/g, "&gt;");
39
30
 
40
31
  const tagName = "docs-lit-demo";
41
32
 
@@ -43,21 +34,21 @@ const tagName = "docs-lit-demo";
43
34
  export class DocsLitDemo extends LitElement {
44
35
  static styles = [
45
36
  tailwind,
46
- prismCSS,
47
37
  css`
48
38
  :host {
49
39
  display: block;
50
40
  margin: 1.1rem 0;
51
41
  }
52
- pre {
53
- font-size: 13px !important;
54
- }
55
42
  .preview {
56
43
  border: 1px solid var(--sc-border, #e5e5e5);
57
44
  border-radius: 0.375rem;
58
45
  padding: 1rem;
59
46
  margin-bottom: 0.75rem;
60
47
  }
48
+ /* Nested sonic-code already has its own block margin */
49
+ sonic-code {
50
+ margin: 0;
51
+ }
61
52
  `,
62
53
  ];
63
54
 
@@ -66,16 +57,11 @@ export class DocsLitDemo extends LitElement {
66
57
 
67
58
  @property({ type: Boolean }) showCode = true;
68
59
 
69
- @state() private highlighted = "";
70
-
71
- private liveHost?: HTMLDivElement;
72
-
73
60
  private get config(): DocsLitDemoConfig | undefined {
74
61
  return DOCS_LIT_DEMO_REGISTRY[this.forTag];
75
62
  }
76
63
 
77
- connectedCallback() {
78
- super.connectedCallback();
64
+ private get excerpt(): string | undefined {
79
65
  const cfg = this.config;
80
66
  if (!cfg?.sources[0]) return;
81
67
 
@@ -85,32 +71,28 @@ export class DocsLitDemo extends LitElement {
85
71
  return;
86
72
  }
87
73
 
88
- const liveTag = cfg.liveTag ?? this.forTag;
89
- const excerpt = resolveDemoExcerpt(raw, liveTag, cfg);
90
- this.highlighted = highlightTs(excerpt);
74
+ return resolveDemoExcerpt(raw, cfg.liveTag ?? this.forTag, cfg);
91
75
  }
92
76
 
93
77
  render() {
94
78
  const cfg = this.config;
95
79
  if (!cfg) return nothing;
96
80
 
97
- const liveTag = cfg.liveTag ?? this.forTag;
81
+ const excerpt = this.excerpt;
98
82
 
99
83
  return html`
100
84
  ${docsSourceLinks(cfg.sources)}
101
85
  <div class="preview" data-live-host></div>
102
- ${this.showCode && this.highlighted
103
- ? html`
104
- <pre
105
- class="rounded-md custom-scroll language-typescript overflow-auto"
106
- ><code>${unsafeHTML(this.highlighted)}</code></pre>
107
- `
86
+ ${this.showCode && excerpt
87
+ ? unsafeHTML(
88
+ `<sonic-code language="typescript" noEdit noPreview><template>${escapeCode(excerpt)}</template></sonic-code>`,
89
+ )
108
90
  : nothing}
109
91
  `;
110
92
  }
111
93
 
112
- firstUpdated() {
113
- super.firstUpdated();
94
+ firstUpdated(_changedProperties: PropertyValues) {
95
+ super.firstUpdated(_changedProperties);
114
96
  this.mountLiveDemo();
115
97
  }
116
98
 
package/src/docs/docs.ts CHANGED
@@ -8,6 +8,10 @@ import "./components/docs-demo-sources";
8
8
  import "./components/docs-lit-demo";
9
9
  import "./header/header";
10
10
  import "./navigation/navigation";
11
+ import "./navigation/toc";
12
+ import "./navigation/pager";
13
+ import "./navigation/components-index";
14
+ import "./home/home";
11
15
  import "./example/users";
12
16
  import "./example/docs-users-list";
13
17
  import "./example/docs-user-two-scopes";
@@ -15,6 +19,7 @@ import "./example/docs-joke-demos";
15
19
  import "./example/docs-queue-demos";
16
20
  import "./example/docs-input-autocomplete-demos";
17
21
  import "./example/docs-toggle-demos";
22
+ import "./example/docs-boarding-pass-demo";
18
23
  import "./example/docs-list-demos";
19
24
  import "./example/docs-jsonata-demos";
20
25
  import "./example/docs-router-demos";
@@ -0,0 +1,134 @@
1
+ import { html, LitElement } from "lit";
2
+ import { customElement, state } from "lit/decorators.js";
3
+ import { keyed } from "lit/directives/keyed.js";
4
+ import { subscribe } from "@supersoniks/concorde/core/decorators/Subscriber";
5
+ import { docsBoardingPassKey } from "./docs-provider-keys";
6
+
7
+ const destinations: Record<string, string> = {
8
+ JFK: "New York",
9
+ GIG: "Rio de Janeiro",
10
+ HND: "Tokyo",
11
+ DXB: "Dubai",
12
+ SYD: "Sydney",
13
+ };
14
+
15
+ const isChecked = (v: unknown) =>
16
+ v === true || v === "true" || v === 1 || v === "1";
17
+
18
+ @customElement("docs-boarding-pass-demo")
19
+ export class DocsBoardingPassDemo extends LitElement {
20
+ /** Light DOM: the pass is part of the page (styles in tailwind/css/docs/boarding-pass.css). */
21
+ createRenderRoot() {
22
+ return this;
23
+ }
24
+
25
+
26
+ @subscribe(docsBoardingPassKey.firstName)
27
+ @state()
28
+ firstName = "";
29
+
30
+ @subscribe(docsBoardingPassKey.lastName)
31
+ @state()
32
+ lastName = "";
33
+
34
+ @subscribe(docsBoardingPassKey.destination)
35
+ @state()
36
+ destination = "JFK";
37
+
38
+ @subscribe(docsBoardingPassKey.firstClass)
39
+ @state()
40
+ firstClass = "";
41
+
42
+ render() {
43
+ const first = isChecked(this.firstClass);
44
+ const code = this.destination || "JFK";
45
+ const passenger =
46
+ `${this.lastName || "—"} / ${this.firstName || "—"}`.toUpperCase();
47
+
48
+ return html`
49
+ <div class="grid gap-6 max-w-[34rem] mx-auto">
50
+ <div formDataProvider=${docsBoardingPassKey.path} class="grid gap-3">
51
+ <div class="grid gap-3 sm:grid-cols-2">
52
+ <sonic-input name="firstName" label="First name"></sonic-input>
53
+ <sonic-input name="lastName" label="Last name"></sonic-input>
54
+ </div>
55
+ <sonic-select name="destination" label="Destination">
56
+ ${Object.entries(destinations).map(
57
+ ([value, city]) =>
58
+ html`<option value=${value}>${city} (${value})</option>`,
59
+ )}
60
+ </sonic-select>
61
+ <sonic-switch name="firstClass" value="true" unique
62
+ >First class</sonic-switch
63
+ >
64
+ </div>
65
+
66
+ <sonic-card
67
+ type=${first ? "invert" : "light"}
68
+ shadow="none"
69
+ class="block relative"
70
+ >
71
+ <div class="flex items-center justify-between gap-3 mb-5">
72
+ <span class="font-headings italic font-semibold text-xl"
73
+ >concorde airways</span
74
+ >
75
+ ${keyed(
76
+ first,
77
+ html`<sonic-badge
78
+ class="bp-pop"
79
+ variant="outline"
80
+ type=${first ? "warning" : "default"}
81
+ >${first ? "First class" : "Economy"}</sonic-badge
82
+ >`,
83
+ )}
84
+ </div>
85
+
86
+ <div class="grid grid-cols-[auto_1fr_auto] items-center gap-3">
87
+ <div>
88
+ <div class="font-headings text-4xl sm:text-5xl leading-none">CDG</div>
89
+ <div class="text-xs opacity-70">Paris</div>
90
+ </div>
91
+ <div class="bp-route">
92
+ ${keyed(
93
+ code,
94
+ html`<sonic-icon
95
+ class="bp-fly"
96
+ name="plane"
97
+ library="fontAwesome"
98
+ prefix="solid"
99
+ size="lg"
100
+ ></sonic-icon>`,
101
+ )}
102
+ </div>
103
+ <div class="text-right">
104
+ ${keyed(
105
+ code,
106
+ html`<div class="bp-pop font-headings text-4xl sm:text-5xl leading-none">
107
+ ${code}
108
+ </div>`,
109
+ )}
110
+ <div class="text-xs opacity-70">${destinations[code]}</div>
111
+ </div>
112
+ </div>
113
+
114
+ <div class="grid grid-cols-3 gap-3 mt-6 text-sm">
115
+ <div class="col-span-3 sm:col-span-1 min-w-0">
116
+ <div class="text-xs opacity-60">Passenger</div>
117
+ <div class="font-bold truncate">${passenger}</div>
118
+ </div>
119
+ <div>
120
+ <div class="text-xs opacity-60">Seat</div>
121
+ <div class="font-bold">${first ? "1A" : "24C"}</div>
122
+ </div>
123
+ <div>
124
+ <div class="text-xs opacity-60">Boarding</div>
125
+ <div class="font-bold">${first ? "10:05" : "10:25"}</div>
126
+ </div>
127
+ </div>
128
+
129
+ <div class="bp-barcode h-10 mt-6 opacity-80"></div>
130
+ </sonic-card>
131
+ </div>
132
+ `;
133
+ }
134
+ }
@@ -111,6 +111,12 @@ export const docsToggleVisibilityKey = new DataProviderKey<{ togglePlan?: string
111
111
  export const docsToggleLoaderFormKey = new DataProviderKey<{ toggleLoader?: string }>(
112
112
  "toggleLoaderForm",
113
113
  );
114
+ export const docsBoardingPassKey = new DataProviderKey<{
115
+ firstName?: string;
116
+ lastName?: string;
117
+ destination?: string;
118
+ firstClass?: string;
119
+ }>("boardingPass");
114
120
 
115
121
  /** User / preview scopes */
116
122
  export const docsUserScopeAKey = new DataProviderKey<DocsUserData>(
@@ -222,6 +228,12 @@ export function initDocsProviderDefaults(): void {
222
228
 
223
229
  set(docsToggleVisibilityKey, { togglePlan: "true" });
224
230
  set(docsToggleLoaderFormKey, { toggleLoader: "" });
231
+ set(docsBoardingPassKey, {
232
+ firstName: "André",
233
+ lastName: "Turcat",
234
+ destination: "JFK",
235
+ firstClass: "true",
236
+ });
225
237
 
226
238
  set(docsUserScopeAKey, {
227
239
  first_name: "Paul",