@supersoniks/concorde 4.5.2 → 4.7.0

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 (185) hide show
  1. package/.gitlab-ci.yml +23 -0
  2. package/README.md +106 -55
  3. package/ai/AGENTS.md +52 -0
  4. package/ai/README.md +30 -0
  5. package/ai/cursor/rules/concorde-menu.mdc +15 -0
  6. package/ai/cursor/rules/concorde-scope.mdc +14 -0
  7. package/ai/cursor/rules/concorde-theme.mdc +13 -0
  8. package/ai/cursor/rules/concorde.mdc +49 -0
  9. package/ai/jetbrains/rules/concorde.md +39 -0
  10. package/ai/skills/concorde/SKILL.md +220 -0
  11. package/ai/skills/concorde-get-set-dp/SKILL.md +194 -0
  12. package/ai/skills/concorde-imports/SKILL.md +78 -0
  13. package/ai/skills/concorde-menu/SKILL.md +74 -0
  14. package/ai/skills/concorde-scope/SKILL.md +70 -0
  15. package/ai/skills/concorde-theme/SKILL.md +46 -0
  16. package/build-infos.json +1 -1
  17. package/concorde-core.bundle.js +159 -159
  18. package/concorde-core.es.js +1915 -1809
  19. package/dist/altcha-widget.js +2662 -0
  20. package/dist/concorde-core.bundle.js +159 -159
  21. package/dist/concorde-core.es.js +1915 -1809
  22. package/dist/docs-mock-api-sw.js +589 -0
  23. package/dist/docs-mock-api-sw.js.map +7 -0
  24. package/docs/altcha-widget.js +2662 -0
  25. package/docs/assets/index-D9pxaQYK.js +7508 -0
  26. package/docs/assets/index-t0-i22oI.css +1 -0
  27. package/docs/docs-mock-api-sw.js +589 -0
  28. package/docs/docs-mock-api-sw.js.map +7 -0
  29. package/docs/index.html +2 -2
  30. package/docs/src/core/components/functional/fetch/fetch.md +13 -11
  31. package/docs/src/core/components/functional/if/if.md +4 -11
  32. package/docs/src/core/components/functional/list/list.md +60 -194
  33. package/docs/src/core/components/functional/queue/queue.md +70 -85
  34. package/docs/src/core/components/functional/router/router.md +62 -97
  35. package/docs/src/core/components/functional/states/states.md +2 -2
  36. package/docs/src/core/components/functional/submit/submit.md +86 -55
  37. package/docs/src/core/components/ui/captcha/captcha.md +2 -2
  38. package/docs/src/core/components/ui/card/card.md +1 -1
  39. package/docs/src/core/components/ui/form/checkbox/checkbox.md +5 -32
  40. package/docs/src/core/components/ui/form/input/input.md +5 -30
  41. package/docs/src/core/components/ui/form/input-autocomplete/input-autocomplete.md +6 -4
  42. package/docs/src/core/components/ui/form/radio/radio.md +5 -32
  43. package/docs/src/core/components/ui/form/select/select.md +5 -31
  44. package/docs/src/core/components/ui/form/switch/switch.md +5 -32
  45. package/docs/src/core/components/ui/loader/loader.md +1 -13
  46. package/docs/src/core/components/ui/table/table.md +3 -3
  47. package/docs/src/docs/_core-concept/dataFlow.md +73 -0
  48. package/docs/src/docs/_core-concept/subscriber.md +9 -10
  49. package/docs/src/docs/_decorators/ancestor-attribute.md +4 -3
  50. package/docs/src/docs/_decorators/auto-subscribe.md +19 -16
  51. package/docs/src/docs/_decorators/bind.md +20 -17
  52. package/docs/src/docs/_decorators/get.md +7 -4
  53. package/docs/src/docs/_decorators/handle.md +171 -0
  54. package/docs/src/docs/_decorators/on-assign.md +99 -73
  55. package/docs/src/docs/_decorators/publish.md +2 -1
  56. package/docs/src/docs/_decorators/subscribe.md +70 -9
  57. package/docs/src/docs/_decorators/wait-for-ancestors.md +13 -10
  58. package/docs/src/docs/_directives/sub.md +91 -0
  59. package/docs/src/docs/_getting-started/ai-agents.md +56 -0
  60. package/docs/src/docs/_getting-started/concorde-manual-install.md +133 -0
  61. package/docs/src/docs/_getting-started/concorde-outside.md +13 -123
  62. package/docs/src/docs/_getting-started/create-a-component.md +2 -0
  63. package/docs/src/docs/_getting-started/my-first-component.md +236 -0
  64. package/docs/src/docs/_getting-started/my-first-subscriber.md +29 -83
  65. package/docs/src/docs/_getting-started/pubsub.md +21 -134
  66. package/docs/src/docs/_getting-started/start.md +26 -18
  67. package/docs/src/docs/_misc/api-configuration.md +79 -0
  68. package/docs/src/docs/_misc/dataProviderKey.md +38 -5
  69. package/docs/src/docs/_misc/docs-mock-api.md +60 -0
  70. package/docs/src/docs/_misc/endpoint.md +2 -1
  71. package/docs/src/docs/_misc/html-integration.md +13 -0
  72. package/docs/src/docs/search/docs-search.json +4163 -873
  73. package/docs/src/tsconfig.json +380 -317
  74. package/gitlab/job_tests.sh +55 -0
  75. package/package.json +37 -3
  76. package/public/altcha-widget.js +2662 -0
  77. package/public/docs-mock-api-sw.js +589 -0
  78. package/public/docs-mock-api-sw.js.map +7 -0
  79. package/scripts/ai-init.mjs +167 -0
  80. package/scripts/docs-mock-api-vite-plugin.ts +116 -0
  81. package/scripts/docs-open-in-editor-plugin.ts +130 -0
  82. package/scripts/pre-publish.mjs +2 -1
  83. package/src/core/components/functional/example/example.ts +1 -1
  84. package/src/core/components/functional/fetch/fetch.md +13 -11
  85. package/src/core/components/functional/if/if.md +4 -11
  86. package/src/core/components/functional/list/list.demo.ts +4 -4
  87. package/src/core/components/functional/list/list.md +60 -194
  88. package/src/core/components/functional/list/list.ts +8 -7
  89. package/src/core/components/functional/queue/queue.demo.ts +1 -1
  90. package/src/core/components/functional/queue/queue.md +70 -85
  91. package/src/core/components/functional/queue/queue.ts +4 -4
  92. package/src/core/components/functional/router/router.md +62 -97
  93. package/src/core/components/functional/router/router.ts +1 -1
  94. package/src/core/components/functional/states/states.md +2 -2
  95. package/src/core/components/functional/submit/submit.md +86 -55
  96. package/src/core/components/functional/submit/submit.ts +10 -3
  97. package/src/core/components/ui/captcha/captcha.md +2 -2
  98. package/src/core/components/ui/card/card.md +1 -1
  99. package/src/core/components/ui/form/checkbox/checkbox.md +5 -32
  100. package/src/core/components/ui/form/input/input.md +5 -30
  101. package/src/core/components/ui/form/input-autocomplete/input-autocomplete.md +6 -4
  102. package/src/core/components/ui/form/radio/radio.md +5 -32
  103. package/src/core/components/ui/form/select/select.md +5 -31
  104. package/src/core/components/ui/form/switch/switch.md +5 -32
  105. package/src/core/components/ui/loader/loader.md +1 -13
  106. package/src/core/components/ui/table/table.md +3 -3
  107. package/src/core/decorators/Subscriber.ts +2 -0
  108. package/src/core/decorators/subscriber/handle.disambig.spec.ts +20 -0
  109. package/src/core/decorators/subscriber/handle.skip.spec.ts +37 -0
  110. package/src/core/decorators/subscriber/handle.ts +128 -0
  111. package/src/core/decorators/subscriber/onAssign.ts +94 -4
  112. package/src/core/directives/DataProvider.sub.spec.ts +96 -0
  113. package/src/core/directives/DataProvider.ts +109 -40
  114. package/src/core/utils/PublisherProxy.ts +33 -18
  115. package/src/core/utils/dataProviderKey.ts +23 -0
  116. package/src/core/utils/publisherPathKey.spec.ts +58 -0
  117. package/src/decorators.ts +6 -0
  118. package/src/docs/_core-concept/dataFlow.md +73 -0
  119. package/src/docs/_core-concept/subscriber.md +9 -10
  120. package/src/docs/_decorators/ancestor-attribute.md +4 -3
  121. package/src/docs/_decorators/auto-subscribe.md +19 -16
  122. package/src/docs/_decorators/bind.md +20 -17
  123. package/src/docs/_decorators/get.md +7 -4
  124. package/src/docs/_decorators/handle.md +171 -0
  125. package/src/docs/_decorators/on-assign.md +99 -47
  126. package/src/docs/_decorators/publish.md +2 -1
  127. package/src/docs/_decorators/subscribe.md +70 -9
  128. package/src/docs/_decorators/wait-for-ancestors.md +13 -10
  129. package/src/docs/_directives/sub.md +91 -0
  130. package/src/docs/_getting-started/ai-agents.md +56 -0
  131. package/src/docs/_getting-started/concorde-manual-install.md +133 -0
  132. package/src/docs/_getting-started/concorde-outside.md +13 -123
  133. package/src/docs/_getting-started/create-a-component.md +2 -0
  134. package/src/docs/_getting-started/my-first-component.md +236 -0
  135. package/src/docs/_getting-started/my-first-subscriber.md +29 -83
  136. package/src/docs/_getting-started/pubsub.md +21 -134
  137. package/src/docs/_getting-started/start.md +26 -18
  138. package/src/docs/_misc/api-configuration.md +79 -0
  139. package/src/docs/_misc/dataProviderKey.md +38 -5
  140. package/src/docs/_misc/docs-mock-api.md +60 -0
  141. package/src/docs/_misc/endpoint.md +2 -1
  142. package/src/docs/_misc/html-integration.md +13 -0
  143. package/src/docs/code.ts +58 -12
  144. package/src/docs/components/docs-demo-sources.ts +397 -0
  145. package/src/docs/components/docs-lit-demo-raw.ts +28 -0
  146. package/src/docs/components/docs-lit-demo.ts +166 -0
  147. package/src/docs/components/docs-source-link.ts +72 -0
  148. package/src/docs/docs-location.ts +54 -0
  149. package/src/docs/docs.ts +12 -0
  150. package/src/docs/example/decorators-demo-bind-demos.ts +41 -46
  151. package/src/docs/example/decorators-demo-geo.ts +16 -11
  152. package/src/docs/example/decorators-demo-init.ts +2 -228
  153. package/src/docs/example/decorators-demo-subscribe-publish-get-demos.ts +142 -12
  154. package/src/docs/example/decorators-demo.ts +71 -70
  155. package/src/docs/example/docs-api-config-demos.ts +234 -0
  156. package/src/docs/example/docs-joke-demos.ts +297 -0
  157. package/src/docs/example/docs-list-demos.ts +179 -0
  158. package/src/docs/example/docs-provider-keys.ts +315 -0
  159. package/src/docs/example/docs-queue-demos.ts +114 -0
  160. package/src/docs/example/docs-router-demos.ts +89 -0
  161. package/src/docs/example/docs-submit-demos.ts +455 -0
  162. package/src/docs/example/docs-toggle-demos.ts +73 -0
  163. package/src/docs/example/docs-user-two-scopes.ts +37 -0
  164. package/src/docs/example/docs-users-list.ts +71 -0
  165. package/src/docs/example/users.ts +41 -24
  166. package/src/docs/mock-api/api-config-mock.ts +152 -0
  167. package/src/docs/mock-api/fixtures.ts +377 -0
  168. package/src/docs/mock-api/register.ts +25 -0
  169. package/src/docs/mock-api/router.ts +234 -0
  170. package/src/docs/mock-api/service-worker.ts +23 -0
  171. package/src/docs/mock-api/urls.ts +11 -0
  172. package/src/docs/navigation/navigation.ts +43 -7
  173. package/src/docs/search/docs-search.json +4193 -858
  174. package/src/docs/search/markdown-renderer.ts +7 -3
  175. package/src/docs/search/page.ts +11 -14
  176. package/src/docs/search/sonic-code-markdown.spec.ts +29 -0
  177. package/src/docs/search/sonic-code-markdown.ts +28 -0
  178. package/src/docs.ts +4 -0
  179. package/src/tsconfig.json +96 -0
  180. package/src/tsconfig.tsbuildinfo +1 -1
  181. package/vite.config.mts +8 -0
  182. package/docs/assets/index-CaysOMFz.js +0 -5046
  183. package/docs/assets/index-D8mGoXzF.css +0 -1
  184. package/docs/src/docs/_misc/templates-demo.md +0 -19
  185. package/src/docs/_misc/templates-demo.md +0 -19
@@ -0,0 +1,397 @@
1
+ import { html, LitElement, nothing } from "lit";
2
+ import { customElement, property } from "lit/decorators.js";
3
+ import { docsSourceLinks, type DocsSource } from "./docs-source-link";
4
+
5
+ export type { DocsSource };
6
+
7
+ /** Live demo + TypeScript excerpt shown by `<docs-lit-demo>` (one file, no Markdown copy). */
8
+ export type DocsLitDemoConfig = {
9
+ sources: DocsSource[];
10
+ /** Optional manual excerpt (1-based); default is auto from `@customElement(liveTag)` */
11
+ excerptStart?: number;
12
+ excerptEnd?: number;
13
+ /** Defaults to registry key */
14
+ liveTag?: string;
15
+ };
16
+
17
+ export const DOCS_LIT_DEMO_REGISTRY: Record<string, DocsLitDemoConfig> = {
18
+ "docs-toggle-if-demo": {
19
+ sources: [
20
+ {
21
+ path: "src/docs/example/docs-toggle-demos.ts",
22
+ line: 18,
23
+ label: "docs-toggle-if-demo",
24
+ },
25
+ ],
26
+ },
27
+ "docs-toggle-loader-demo": {
28
+ sources: [
29
+ {
30
+ path: "src/docs/example/docs-toggle-demos.ts",
31
+ line: 49,
32
+ label: "docs-toggle-loader-demo",
33
+ },
34
+ ],
35
+ },
36
+ "docs-joke-search-demo": {
37
+ sources: [
38
+ { path: "src/docs/example/docs-joke-demos.ts", line: 111, label: "search" },
39
+ ],
40
+ },
41
+ "docs-joke-lang-demo": {
42
+ sources: [
43
+ { path: "src/docs/example/docs-joke-demos.ts", line: 136, label: "lang" },
44
+ ],
45
+ },
46
+ "docs-joke-blacklist-demo": {
47
+ sources: [
48
+ { path: "src/docs/example/docs-joke-demos.ts", line: 181, label: "blacklist" },
49
+ ],
50
+ },
51
+ "docs-joke-blacklist-radio-demo": {
52
+ sources: [
53
+ { path: "src/docs/example/docs-joke-demos.ts", line: 212, label: "radio" },
54
+ ],
55
+ },
56
+ "docs-joke-blacklist-switch-demo": {
57
+ sources: [
58
+ { path: "src/docs/example/docs-joke-demos.ts", line: 256, label: "switch" },
59
+ ],
60
+ },
61
+ "docs-queue-users-demo": {
62
+ sources: [
63
+ { path: "src/docs/example/docs-queue-demos.ts", line: 66, label: "users" },
64
+ ],
65
+ },
66
+ "docs-queue-geo-demo": {
67
+ sources: [
68
+ { path: "src/docs/example/docs-queue-demos.ts", line: 38, label: "geo" },
69
+ ],
70
+ },
71
+ "docs-users-list": {
72
+ sources: [
73
+ { path: "src/docs/example/docs-users-list.ts", line: 15, label: "docs-users-list" },
74
+ ],
75
+ },
76
+ "docs-list-alternate-demo": {
77
+ sources: [
78
+ { path: "src/docs/example/docs-list-demos.ts", line: 51, label: "alternate" },
79
+ ],
80
+ },
81
+ "docs-list-template-key-demo": {
82
+ sources: [
83
+ { path: "src/docs/example/docs-list-demos.ts", line: 79, label: "templateKey" },
84
+ ],
85
+ },
86
+ "docs-list-separator-demo": {
87
+ sources: [
88
+ { path: "src/docs/example/docs-list-demos.ts", line: 118, label: "separator" },
89
+ ],
90
+ },
91
+ "docs-list-extract-values-demo": {
92
+ sources: [
93
+ { path: "src/docs/example/docs-list-demos.ts", line: 146, label: "extractValues" },
94
+ ],
95
+ },
96
+ "docs-router-basic-demo": {
97
+ sources: [
98
+ { path: "src/docs/example/docs-router-demos.ts", line: 33, label: "basic" },
99
+ ],
100
+ },
101
+ "docs-router-params-demo": {
102
+ sources: [
103
+ { path: "src/docs/example/docs-router-demos.ts", line: 61, label: "params" },
104
+ ],
105
+ },
106
+ "docs-submit-demo": {
107
+ sources: [
108
+ { path: "src/docs/example/docs-submit-demos.ts", line: 86, label: "submit" },
109
+ ],
110
+ },
111
+ "docs-submit-native-demo": {
112
+ sources: [
113
+ { path: "src/docs/example/docs-submit-demos.ts", line: 307, label: "native" },
114
+ ],
115
+ },
116
+ "docs-submit-formdata-demo": {
117
+ sources: [
118
+ { path: "src/docs/example/docs-submit-demos.ts", line: 231, label: "formdata" },
119
+ ],
120
+ },
121
+ "docs-submit-result-key-demo": {
122
+ sources: [
123
+ { path: "src/docs/example/docs-submit-demos.ts", line: 184, label: "result-key" },
124
+ ],
125
+ },
126
+ "docs-submit-clear-demo": {
127
+ sources: [
128
+ { path: "src/docs/example/docs-submit-demos.ts", line: 144, label: "clear" },
129
+ ],
130
+ },
131
+ "docs-submit-event-demo": {
132
+ sources: [
133
+ { path: "src/docs/example/docs-submit-demos.ts", line: 357, label: "event" },
134
+ ],
135
+ },
136
+ "docs-submit-endpoint-demo": {
137
+ sources: [
138
+ { path: "src/docs/example/docs-submit-demos.ts", line: 407, label: "endpoint" },
139
+ ],
140
+ },
141
+ "docs-submit-get-demo": {
142
+ sources: [
143
+ { path: "src/docs/example/docs-submit-demos.ts", line: 276, label: "get" },
144
+ ],
145
+ },
146
+ "docs-api-config-bearer-demo": {
147
+ sources: [
148
+ { path: "src/docs/example/docs-api-config-demos.ts", line: 63, label: "bearer" },
149
+ ],
150
+ },
151
+ "docs-api-config-token-provider-demo": {
152
+ sources: [
153
+ {
154
+ path: "src/docs/example/docs-api-config-demos.ts",
155
+ line: 83,
156
+ label: "tokenProvider",
157
+ },
158
+ ],
159
+ },
160
+ "docs-api-config-stale-token-demo": {
161
+ sources: [
162
+ { path: "src/docs/example/docs-api-config-demos.ts", line: 104, label: "498" },
163
+ ],
164
+ },
165
+ "docs-api-config-wording-demo": {
166
+ sources: [
167
+ { path: "src/docs/example/docs-api-config-demos.ts", line: 132, label: "wording" },
168
+ ],
169
+ },
170
+ "docs-api-config-scoped-attrs-demo": {
171
+ sources: [
172
+ { path: "src/docs/example/docs-api-config-demos.ts", line: 162, label: "scope" },
173
+ ],
174
+ },
175
+ "docs-api-config-events-token-demo": {
176
+ sources: [
177
+ {
178
+ path: "src/docs/example/docs-api-config-demos.ts",
179
+ line: 191,
180
+ label: "eventsApiToken",
181
+ },
182
+ ],
183
+ },
184
+ };
185
+
186
+ /** Live demo tag → useful source files (not inline sonic-code samples). */
187
+ export const DOCS_DEMO_SOURCE_REGISTRY: Record<string, DocsSource[]> = {
188
+ "docs-user": [
189
+ { path: "src/docs/example/users.ts", label: "docs-user" },
190
+ ],
191
+ "docs-user-two-scopes": [
192
+ { path: "src/docs/example/docs-user-two-scopes.ts", label: "two scopes" },
193
+ { path: "src/docs/example/users.ts", label: "docs-user" },
194
+ { path: "src/docs/example/decorators-demo-init.ts", label: "demo data" },
195
+ ],
196
+ "docs-joke-search-demo": [
197
+ { path: "src/docs/example/docs-joke-demos.ts", label: "joke demos" },
198
+ ],
199
+ "docs-joke-lang-demo": [
200
+ { path: "src/docs/example/docs-joke-demos.ts", label: "joke demos" },
201
+ ],
202
+ "docs-queue-geo-demo": [
203
+ { path: "src/docs/example/docs-queue-demos.ts", label: "queue demos" },
204
+ ],
205
+ "docs-queue-users-demo": [
206
+ { path: "src/docs/example/docs-queue-demos.ts", label: "queue demos" },
207
+ ],
208
+ "docs-toggle-if-demo": [
209
+ { path: "src/docs/example/docs-toggle-demos.ts", label: "toggle demos" },
210
+ ],
211
+ "docs-toggle-loader-demo": [
212
+ { path: "src/docs/example/docs-toggle-demos.ts", label: "toggle demos" },
213
+ ],
214
+ "demo-publish": [
215
+ {
216
+ path: "src/docs/example/decorators-demo-subscribe-publish-get-demos.ts",
217
+ line: 29,
218
+ label: "demo-publish",
219
+ },
220
+ { path: "src/docs/example/decorators-demo-init.ts", label: "demo data" },
221
+ ],
222
+ "demo-subscribe-dynamic": [
223
+ {
224
+ path: "src/docs/example/decorators-demo-subscribe-publish-get-demos.ts",
225
+ line: 313,
226
+ label: "demo-subscribe-dynamic",
227
+ },
228
+ { path: "src/docs/example/decorators-demo-init.ts", label: "demo data" },
229
+ ],
230
+ "demo-sub-template": [
231
+ {
232
+ path: "src/docs/example/decorators-demo-subscribe-publish-get-demos.ts",
233
+ line: 282,
234
+ label: "demo-sub-template",
235
+ },
236
+ { path: "src/docs/example/decorators-demo-init.ts", label: "demo data" },
237
+ ],
238
+ "demo-api-get": [
239
+ {
240
+ path: "src/docs/example/decorators-demo-subscribe-publish-get-demos.ts",
241
+ line: 83,
242
+ label: "demo-api-get",
243
+ },
244
+ { path: "src/docs/example/decorators-demo-geo.ts", label: "geo API" },
245
+ { path: "src/docs/mock-api/router.ts", label: "mock router" },
246
+ ],
247
+ "demo-api-get-configuration-key": [
248
+ {
249
+ path: "src/docs/example/decorators-demo-subscribe-publish-get-demos.ts",
250
+ line: 126,
251
+ label: "demo-api-get-configuration-key",
252
+ },
253
+ { path: "src/docs/example/decorators-demo-geo.ts", label: "geo API" },
254
+ ],
255
+ "demo-api-get-publish-subscribe": [
256
+ {
257
+ path: "src/docs/example/decorators-demo-subscribe-publish-get-demos.ts",
258
+ line: 227,
259
+ label: "demo-api-get-publish-subscribe",
260
+ },
261
+ { path: "src/docs/example/decorators-demo-geo.ts", label: "geo API" },
262
+ ],
263
+ "demo-handle": [
264
+ {
265
+ path: "src/docs/example/decorators-demo-subscribe-publish-get-demos.ts",
266
+ line: 360,
267
+ label: "demo-handle",
268
+ },
269
+ { path: "src/docs/example/decorators-demo-init.ts", label: "demo data" },
270
+ ],
271
+ "demo-handle-dynamic": [
272
+ {
273
+ path: "src/docs/example/decorators-demo-subscribe-publish-get-demos.ts",
274
+ line: 396,
275
+ label: "demo-handle-dynamic",
276
+ },
277
+ { path: "src/docs/example/decorators-demo-init.ts", label: "demo data" },
278
+ ],
279
+ "demo-bind": [
280
+ { path: "src/docs/example/decorators-demo-bind-demos.ts", line: 14, label: "demo-bind" },
281
+ { path: "src/docs/example/decorators-demo-init.ts", label: "demo data" },
282
+ ],
283
+ "demo-bind-reflect": [
284
+ {
285
+ path: "src/docs/example/decorators-demo-bind-demos.ts",
286
+ line: 56,
287
+ label: "demo-bind-reflect",
288
+ },
289
+ { path: "src/docs/example/decorators-demo-init.ts", label: "demo data" },
290
+ ],
291
+ "demo-bind-dynamic": [
292
+ {
293
+ path: "src/docs/example/decorators-demo-bind-demos.ts",
294
+ line: 124,
295
+ label: "demo-bind-dynamic",
296
+ },
297
+ { path: "src/docs/example/decorators-demo-init.ts", label: "demo data" },
298
+ ],
299
+ "demo-ancestor-attribute": [
300
+ { path: "src/docs/example/decorators-demo.ts", line: 19, label: "demo-ancestor-attribute" },
301
+ ],
302
+ "demo-on-assign": [
303
+ { path: "src/docs/example/decorators-demo.ts", line: 43, label: "demo-on-assign" },
304
+ { path: "src/docs/example/decorators-demo-init.ts", label: "demo data" },
305
+ ],
306
+ "demo-on-assign-dynamic": [
307
+ {
308
+ path: "src/docs/example/decorators-demo.ts",
309
+ line: 94,
310
+ label: "demo-on-assign-dynamic",
311
+ },
312
+ { path: "src/docs/example/decorators-demo-init.ts", label: "demo data" },
313
+ ],
314
+ "demo-auto-subscribe": [
315
+ { path: "src/docs/example/decorators-demo.ts", line: 211, label: "demo-auto-subscribe" },
316
+ { path: "src/docs/example/decorators-demo-init.ts", label: "demo data" },
317
+ ],
318
+ "demo-wait-ancestors-section": [
319
+ {
320
+ path: "src/docs/example/decorators-demo.ts",
321
+ line: 278,
322
+ label: "demo-wait-ancestors-section",
323
+ },
324
+ { path: "src/docs/example/decorators-demo-init.ts", label: "demo data" },
325
+ ],
326
+ "demo-wait-ancestors-multi-section": [
327
+ {
328
+ path: "src/docs/example/decorators-demo.ts",
329
+ line: 355,
330
+ label: "demo-wait-ancestors-multi-section",
331
+ },
332
+ { path: "src/docs/example/decorators-demo-init.ts", label: "demo data" },
333
+ ],
334
+ "demo-wait-ancestors-static-section": [
335
+ {
336
+ path: "src/docs/example/decorators-demo.ts",
337
+ line: 462,
338
+ label: "demo-wait-ancestors-static-section",
339
+ },
340
+ ],
341
+ "demo-wait-ancestors-ready-section": [
342
+ {
343
+ path: "src/docs/example/decorators-demo.ts",
344
+ line: 432,
345
+ label: "demo-wait-ancestors-ready-section",
346
+ },
347
+ ],
348
+ "sonic-queue-demo": [
349
+ { path: "src/core/components/functional/queue/queue.demo.ts", label: "sonic-queue-demo" },
350
+ { path: "src/docs/mock-api/router.ts", label: "mock router" },
351
+ ],
352
+ "sonic-list-demo": [
353
+ { path: "src/core/components/functional/list/list.demo.ts", label: "sonic-list-demo" },
354
+ { path: "src/docs/mock-api/router.ts", label: "mock router" },
355
+ ],
356
+ "queue-users-scroll": [
357
+ { path: "src/docs/example/docs-queue-demos.ts", label: "docs-queue-users-demo" },
358
+ { path: "src/docs/example/users.ts", label: "docs-user" },
359
+ ],
360
+ /** Inline list.md fetch demo — component + mock. */
361
+ "list-users-fetch": [
362
+ { path: "src/docs/example/docs-users-list.ts", label: "docs-users-list" },
363
+ { path: "src/docs/mock-api/router.ts", label: "mock API" },
364
+ ],
365
+ "docs-submit-demo": [
366
+ { path: "src/docs/example/docs-submit-demos.ts", label: "submit demo" },
367
+ { path: "src/docs/mock-api/router.ts", label: "mock API (POST register)" },
368
+ ],
369
+ "docs-api-config-bearer-demo": [
370
+ { path: "src/docs/example/docs-api-config-demos.ts", label: "API config demos" },
371
+ { path: "src/docs/mock-api/api-config-mock.ts", label: "mock routes" },
372
+ ],
373
+ "docs-api-config-token-provider-demo": [
374
+ { path: "src/docs/example/docs-api-config-demos.ts", label: "API config demos" },
375
+ { path: "src/docs/mock-api/api-config-mock.ts", label: "mock routes" },
376
+ ],
377
+ "docs-api-config-stale-token-demo": [
378
+ { path: "src/docs/example/docs-api-config-demos.ts", label: "API config demos" },
379
+ { path: "src/docs/mock-api/api-config-mock.ts", label: "mock routes" },
380
+ ],
381
+ "docs-api-config-wording-demo": [
382
+ { path: "src/docs/example/docs-api-config-demos.ts", label: "API config demos" },
383
+ { path: "src/docs/mock-api/api-config-mock.ts", label: "mock routes" },
384
+ ],
385
+ };
386
+
387
+ @customElement("docs-demo-sources")
388
+ export class DocsDemoSources extends LitElement {
389
+ /** Registry key matching the live demo custom element tag. */
390
+ @property({ attribute: "for" }) forTag = "";
391
+
392
+ render() {
393
+ const sources = DOCS_DEMO_SOURCE_REGISTRY[this.forTag];
394
+ if (!sources?.length) return nothing;
395
+ return docsSourceLinks(sources);
396
+ }
397
+ }
@@ -0,0 +1,28 @@
1
+ /**
2
+ * Raw sources for `<docs-lit-demo>` — explicit imports only (no import.meta.glob).
3
+ * Included in the **docs** bundle (`src/docs.ts`), not in the **core** library build (`src/index.ts`).
4
+ * Add one import + map entry when registering a new file in `DOCS_LIT_DEMO_REGISTRY`.
5
+ */
6
+ import docsJokeDemos from "../example/docs-joke-demos.ts?raw";
7
+ import docsListDemos from "../example/docs-list-demos.ts?raw";
8
+ import docsQueueDemos from "../example/docs-queue-demos.ts?raw";
9
+ import docsToggleDemos from "../example/docs-toggle-demos.ts?raw";
10
+ import docsUserTwoScopes from "../example/docs-user-two-scopes.ts?raw";
11
+ import docsRouterDemos from "../example/docs-router-demos.ts?raw";
12
+ import docsSubmitDemos from "../example/docs-submit-demos.ts?raw";
13
+ import docsApiConfigDemos from "../example/docs-api-config-demos.ts?raw";
14
+ import docsUsersList from "../example/docs-users-list.ts?raw";
15
+ import users from "../example/users.ts?raw";
16
+
17
+ export const DOCS_LIT_DEMO_RAW: Record<string, string> = {
18
+ "src/docs/example/docs-toggle-demos.ts": docsToggleDemos,
19
+ "src/docs/example/docs-joke-demos.ts": docsJokeDemos,
20
+ "src/docs/example/docs-queue-demos.ts": docsQueueDemos,
21
+ "src/docs/example/docs-list-demos.ts": docsListDemos,
22
+ "src/docs/example/docs-router-demos.ts": docsRouterDemos,
23
+ "src/docs/example/docs-submit-demos.ts": docsSubmitDemos,
24
+ "src/docs/example/docs-api-config-demos.ts": docsApiConfigDemos,
25
+ "src/docs/example/docs-users-list.ts": docsUsersList,
26
+ "src/docs/example/docs-user-two-scopes.ts": docsUserTwoScopes,
27
+ "src/docs/example/users.ts": users,
28
+ };
@@ -0,0 +1,166 @@
1
+ import { css, html, LitElement, nothing } from "lit";
2
+ import { customElement, property, state } from "lit/decorators.js";
3
+ import { unsafeHTML } from "lit/directives/unsafe-html.js";
4
+ import { tailwind } from "../tailwind";
5
+ import { docsSourceLinks } from "./docs-source-link";
6
+ import {
7
+ DOCS_LIT_DEMO_REGISTRY,
8
+ type DocsLitDemoConfig,
9
+ } from "./docs-demo-sources";
10
+
11
+ import "../prism/prism";
12
+ import { prismCSS } from "../prism";
13
+ import * as Prism from "prismjs";
14
+ import "prismjs/components/prism-typescript";
15
+
16
+ import { DOCS_LIT_DEMO_RAW } from "./docs-lit-demo-raw";
17
+
18
+ /** Class body for `liveTag`: from `@customElement("…")` through the line before the next `@customElement`. */
19
+ export function excerptForCustomElement(
20
+ source: string,
21
+ liveTag: string,
22
+ ): string | null {
23
+ const lines = source.split("\n");
24
+ const needle = `@customElement("${liveTag}")`;
25
+ let start = -1;
26
+ for (let i = 0; i < lines.length; i++) {
27
+ if (lines[i].includes(needle)) {
28
+ start = i;
29
+ break;
30
+ }
31
+ }
32
+ if (start < 0) return null;
33
+
34
+ let end = lines.length;
35
+ for (let i = start + 1; i < lines.length; i++) {
36
+ if (lines[i].includes("@customElement(")) {
37
+ end = i;
38
+ break;
39
+ }
40
+ }
41
+ return lines.slice(start, end).join("\n");
42
+ }
43
+
44
+ function excerptLines(
45
+ source: string,
46
+ start?: number,
47
+ end?: number,
48
+ ): string {
49
+ const lines = source.split("\n");
50
+ if (!start && !end) return source;
51
+ const from = Math.max(1, start ?? 1) - 1;
52
+ const to = end ?? lines.length;
53
+ return lines.slice(from, to).join("\n");
54
+ }
55
+
56
+ function resolveDemoExcerpt(
57
+ raw: string,
58
+ liveTag: string,
59
+ cfg: DocsLitDemoConfig,
60
+ ): string {
61
+ const auto = excerptForCustomElement(raw, liveTag);
62
+ if (auto) return auto;
63
+ if (cfg.excerptStart != null || cfg.excerptEnd != null) {
64
+ return excerptLines(raw, cfg.excerptStart, cfg.excerptEnd);
65
+ }
66
+ return raw;
67
+ }
68
+
69
+ function highlightTs(code: string): string {
70
+ return Prism.highlight(code, Prism.languages.typescript, "typescript");
71
+ }
72
+
73
+ const tagName = "docs-lit-demo";
74
+
75
+ @customElement(tagName)
76
+ export class DocsLitDemo extends LitElement {
77
+ static styles = [
78
+ tailwind,
79
+ prismCSS,
80
+ css`
81
+ :host {
82
+ display: block;
83
+ margin: 1.1rem 0;
84
+ }
85
+ pre {
86
+ font-size: 13px !important;
87
+ }
88
+ .preview {
89
+ border: 1px solid var(--sc-border, #e5e5e5);
90
+ border-radius: 0.375rem;
91
+ padding: 1rem;
92
+ margin-bottom: 0.75rem;
93
+ }
94
+ `,
95
+ ];
96
+
97
+ /** Registry key = live custom element tag name */
98
+ @property({ attribute: "for" }) forTag = "";
99
+
100
+ @property({ type: Boolean }) showCode = true;
101
+
102
+ @state() private highlighted = "";
103
+
104
+ private liveHost?: HTMLDivElement;
105
+
106
+ private get config(): DocsLitDemoConfig | undefined {
107
+ return DOCS_LIT_DEMO_REGISTRY[this.forTag];
108
+ }
109
+
110
+ connectedCallback() {
111
+ super.connectedCallback();
112
+ const cfg = this.config;
113
+ if (!cfg?.sources[0]) return;
114
+
115
+ const raw = DOCS_LIT_DEMO_RAW[cfg.sources[0].path];
116
+ if (!raw) {
117
+ console.warn(`[docs-lit-demo] No raw source for ${cfg.sources[0].path}`);
118
+ return;
119
+ }
120
+
121
+ const liveTag = cfg.liveTag ?? this.forTag;
122
+ const excerpt = resolveDemoExcerpt(raw, liveTag, cfg);
123
+ this.highlighted = highlightTs(excerpt);
124
+ }
125
+
126
+ render() {
127
+ const cfg = this.config;
128
+ if (!cfg) return nothing;
129
+
130
+ const liveTag = cfg.liveTag ?? this.forTag;
131
+
132
+ return html`
133
+ ${docsSourceLinks(cfg.sources)}
134
+ <div class="preview" data-live-host></div>
135
+ ${this.showCode && this.highlighted
136
+ ? html`
137
+ <pre
138
+ class="rounded-md custom-scroll language-typescript overflow-auto"
139
+ ><code>${unsafeHTML(this.highlighted)}</code></pre>
140
+ `
141
+ : nothing}
142
+ `;
143
+ }
144
+
145
+ firstUpdated() {
146
+ super.firstUpdated();
147
+ this.mountLiveDemo();
148
+ }
149
+
150
+ updated(changed: Map<string, unknown>) {
151
+ super.updated(changed);
152
+ if (changed.has("forTag")) this.mountLiveDemo();
153
+ }
154
+
155
+ private mountLiveDemo() {
156
+ const cfg = this.config;
157
+ const tag = cfg?.liveTag ?? this.forTag;
158
+ const host = this.renderRoot.querySelector(
159
+ "[data-live-host]",
160
+ ) as HTMLDivElement | null;
161
+ if (!host || !tag) return;
162
+ const existing = host.firstElementChild;
163
+ if (existing?.tagName.toLowerCase() === tag && existing.isConnected) return;
164
+ host.replaceChildren(document.createElement(tag));
165
+ }
166
+ }
@@ -0,0 +1,72 @@
1
+ import { html, nothing } from "lit";
2
+ import "../../core/components/ui/button/button";
3
+ import "../../core/components/ui/icon/icon";
4
+
5
+ declare const __DOCS_EDITOR_AVAILABLE__: boolean;
6
+
7
+ export type DocsSource = {
8
+ path: string;
9
+ line?: number;
10
+ column?: number;
11
+ label?: string;
12
+ };
13
+
14
+ const editorAvailable =
15
+ import.meta.env.DEV &&
16
+ typeof __DOCS_EDITOR_AVAILABLE__ !== "undefined" &&
17
+ __DOCS_EDITOR_AVAILABLE__;
18
+
19
+ function openDocsSource(source: DocsSource, event: Event) {
20
+ event.preventDefault();
21
+ if (!editorAvailable) return;
22
+
23
+ const params = new URLSearchParams({
24
+ path: source.path,
25
+ line: String(source.line ?? 1),
26
+ column: String(source.column ?? 1),
27
+ });
28
+
29
+ void fetch(`/__docs/open?${params}`).catch(() => {
30
+ console.warn("[docs] Could not open in editor:", source.path);
31
+ });
32
+ }
33
+
34
+ export function docsSourceLink(source: DocsSource) {
35
+ if (!editorAvailable) return nothing;
36
+ const label = source.label ?? source.path.split("/").pop() ?? "source";
37
+ return html`
38
+ <sonic-button
39
+ variant="link"
40
+ size="2xs"
41
+ type="neutral"
42
+ title=${source.path}
43
+ @click=${(e: Event) => openDocsSource(source, e)}
44
+ >
45
+ <sonic-icon
46
+ library="heroicons"
47
+ name="arrow-top-right-on-square"
48
+ class="w-3 h-3 opacity-70"
49
+ ></sonic-icon>
50
+ ${label}
51
+ </sonic-button>
52
+ `;
53
+ }
54
+
55
+ export function docsSourceLinks(sources: DocsSource[]) {
56
+ if (!editorAvailable || sources.length === 0) return nothing;
57
+ return html`
58
+ <div
59
+ class="flex flex-wrap items-center gap-x-1 gap-y-1 mb-4 pb-3 border-b border-neutral-200/80 dark:border-neutral-700/80"
60
+ >
61
+ <span class="text-xs uppercase tracking-wide text-neutral-400 mr-1"
62
+ >Source</span
63
+ >
64
+ ${sources.map((s, i) =>
65
+ i === 0
66
+ ? docsSourceLink(s)
67
+ : html`<span class="text-neutral-300 dark:text-neutral-600">·</span
68
+ >${docsSourceLink(s)}`,
69
+ )}
70
+ </div>
71
+ `;
72
+ }