@supersoniks/concorde 4.7.3 → 4.8.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 (152) hide show
  1. package/README.md +1 -1
  2. package/ai/AGENTS.md +4 -0
  3. package/ai/cursor/rules/concorde.mdc +11 -1
  4. package/ai/jetbrains/rules/concorde.md +8 -0
  5. package/ai/skills/concorde/SKILL.md +29 -2
  6. package/ai/skills/concorde-scope/SKILL.md +2 -2
  7. package/build-infos.json +1 -1
  8. package/concorde-core.bundle.js +289 -289
  9. package/concorde-core.es.js +4839 -4546
  10. package/dist/concorde-core.bundle.js +289 -289
  11. package/dist/concorde-core.es.js +4839 -4546
  12. package/dist/docs-mock-api-sw.js +19 -0
  13. package/dist/docs-mock-api-sw.js.map +2 -2
  14. package/dist/robots.txt +2 -0
  15. package/docs/assets/index-wyNMyWT9.js +11196 -0
  16. package/docs/docs-mock-api-sw.js +19 -0
  17. package/docs/docs-mock-api-sw.js.map +2 -2
  18. package/docs/index.html +1 -1
  19. package/docs/robots.txt +2 -0
  20. package/package.json +9 -1
  21. package/public/docs-mock-api-sw.js +19 -0
  22. package/public/docs-mock-api-sw.js.map +2 -2
  23. package/public/robots.txt +2 -0
  24. package/src/core/components/functional/example/example.ts +3 -3
  25. package/src/core/components/ui/captcha/captcha.md +0 -12
  26. package/src/core/components/ui/icon/icon.ts +17 -2
  27. package/src/core/components/ui/menu/menu.ts +12 -3
  28. package/src/core/decorators/api.post.spec.ts +293 -0
  29. package/src/core/decorators/api.spec.ts +7 -14
  30. package/src/core/decorators/api.ts +648 -15
  31. package/src/core/decorators/subscriber/bind.ts +13 -5
  32. package/src/core/decorators/subscriber/dynamicPath.spec.ts +53 -0
  33. package/src/core/decorators/subscriber/dynamicPath.ts +23 -1
  34. package/src/core/decorators/subscriber/handle.ts +3 -1
  35. package/src/core/decorators/subscriber/onAssign.ts +10 -2
  36. package/src/core/decorators/subscriber/publish.ts +12 -2
  37. package/src/core/utils/PublisherProxy.ts +95 -11
  38. package/src/core/utils/api.ts +72 -3
  39. package/src/core/utils/dpOptions.spec.ts +56 -0
  40. package/src/core/utils/endpoint.ts +3 -3
  41. package/src/decorators.ts +17 -1
  42. package/src/docs/_core-concept/dataFlow.md +9 -3
  43. package/src/docs/_decorators/bind.md +2 -2
  44. package/src/docs/_decorators/get.md +13 -4
  45. package/src/docs/_decorators/handle.md +5 -1
  46. package/src/docs/_decorators/on-assign.md +2 -0
  47. package/src/docs/_decorators/patch.md +45 -0
  48. package/src/docs/_decorators/post.md +93 -0
  49. package/src/docs/_decorators/publish.md +1 -1
  50. package/src/docs/_decorators/put.md +43 -0
  51. package/src/docs/_decorators/subscribe.md +4 -1
  52. package/src/docs/_directives/sub.md +1 -1
  53. package/src/docs/_getting-started/my-first-component.md +1 -1
  54. package/src/docs/_misc/api-configuration.md +3 -1
  55. package/src/docs/_misc/dataProviderKey.md +2 -2
  56. package/src/docs/_misc/dynamic-path.md +71 -0
  57. package/src/docs/_misc/endpoint.md +5 -3
  58. package/src/docs/components/docs-demo-sources.ts +102 -3
  59. package/src/docs/components/docs-lit-demo-raw.ts +2 -26
  60. package/src/docs/components/docs-lit-demo.ts +9 -42
  61. package/src/docs/components/docs-source-excerpt.ts +53 -0
  62. package/src/docs/components/docs-source-link.ts +24 -8
  63. package/src/docs/components/docs-source-raw.ts +34 -0
  64. package/src/docs/example/decorators-demo-geo.ts +2 -2
  65. package/src/docs/example/decorators-demo-post.ts +249 -0
  66. package/src/docs/example/decorators-demo-subscribe-publish-get-demos.ts +5 -5
  67. package/src/docs/example/decorators-demo.ts +1 -0
  68. package/src/docs/example/docs-api-config-demos.ts +5 -5
  69. package/src/docs/mock-api/router.ts +20 -0
  70. package/src/docs/navigation/navigation.ts +16 -0
  71. package/src/docs/search/docs-search.json +540 -15
  72. package/src/tsconfig.json +24 -0
  73. package/src/tsconfig.tsbuildinfo +1 -1
  74. package/vite.config.mts +1 -1
  75. package/docs/assets/index-D9pxaQYK.js +0 -7508
  76. package/docs/src/core/components/functional/date/date.md +0 -290
  77. package/docs/src/core/components/functional/fetch/fetch.md +0 -125
  78. package/docs/src/core/components/functional/if/if.md +0 -9
  79. package/docs/src/core/components/functional/list/list.md +0 -65
  80. package/docs/src/core/components/functional/mix/mix.md +0 -41
  81. package/docs/src/core/components/functional/queue/queue.md +0 -72
  82. package/docs/src/core/components/functional/router/router.md +0 -94
  83. package/docs/src/core/components/functional/sdui/default-library.json +0 -108
  84. package/docs/src/core/components/functional/sdui/example.json +0 -99
  85. package/docs/src/core/components/functional/sdui/sdui.md +0 -356
  86. package/docs/src/core/components/functional/states/states.md +0 -87
  87. package/docs/src/core/components/functional/submit/submit.md +0 -114
  88. package/docs/src/core/components/functional/subscriber/subscriber.md +0 -91
  89. package/docs/src/core/components/functional/value/value.md +0 -35
  90. package/docs/src/core/components/ui/alert/alert.md +0 -121
  91. package/docs/src/core/components/ui/alert-messages/alert-messages.md +0 -0
  92. package/docs/src/core/components/ui/badge/badge.md +0 -127
  93. package/docs/src/core/components/ui/button/button.md +0 -182
  94. package/docs/src/core/components/ui/captcha/captcha.md +0 -24
  95. package/docs/src/core/components/ui/card/card.md +0 -97
  96. package/docs/src/core/components/ui/divider/divider.md +0 -35
  97. package/docs/src/core/components/ui/form/checkbox/checkbox.md +0 -77
  98. package/docs/src/core/components/ui/form/fieldset/fieldset.md +0 -129
  99. package/docs/src/core/components/ui/form/form-actions/form-actions.md +0 -77
  100. package/docs/src/core/components/ui/form/form-layout/form-layout.md +0 -44
  101. package/docs/src/core/components/ui/form/input/input.md +0 -142
  102. package/docs/src/core/components/ui/form/input-autocomplete/input-autocomplete.md +0 -133
  103. package/docs/src/core/components/ui/form/radio/radio.md +0 -57
  104. package/docs/src/core/components/ui/form/select/select.md +0 -71
  105. package/docs/src/core/components/ui/form/switch/switch.md +0 -57
  106. package/docs/src/core/components/ui/form/textarea/textarea.md +0 -65
  107. package/docs/src/core/components/ui/group/group.md +0 -75
  108. package/docs/src/core/components/ui/icon/icon.md +0 -125
  109. package/docs/src/core/components/ui/icon/icons.json +0 -1
  110. package/docs/src/core/components/ui/image/image.md +0 -107
  111. package/docs/src/core/components/ui/link/link.md +0 -43
  112. package/docs/src/core/components/ui/loader/loader.md +0 -55
  113. package/docs/src/core/components/ui/menu/menu.md +0 -329
  114. package/docs/src/core/components/ui/modal/modal.md +0 -119
  115. package/docs/src/core/components/ui/pop/pop.md +0 -96
  116. package/docs/src/core/components/ui/progress/progress.md +0 -63
  117. package/docs/src/core/components/ui/table/table.md +0 -455
  118. package/docs/src/core/components/ui/toast/toast.md +0 -166
  119. package/docs/src/core/components/ui/tooltip/tooltip.md +0 -82
  120. package/docs/src/docs/_core-concept/dataFlow.md +0 -73
  121. package/docs/src/docs/_core-concept/overview.md +0 -57
  122. package/docs/src/docs/_core-concept/subscriber.md +0 -75
  123. package/docs/src/docs/_decorators/ancestor-attribute.md +0 -79
  124. package/docs/src/docs/_decorators/auto-subscribe.md +0 -202
  125. package/docs/src/docs/_decorators/bind.md +0 -167
  126. package/docs/src/docs/_decorators/get.md +0 -68
  127. package/docs/src/docs/_decorators/handle.md +0 -171
  128. package/docs/src/docs/_decorators/on-assign.md +0 -388
  129. package/docs/src/docs/_decorators/publish.md +0 -55
  130. package/docs/src/docs/_decorators/subscribe.md +0 -97
  131. package/docs/src/docs/_decorators/wait-for-ancestors.md +0 -163
  132. package/docs/src/docs/_directives/sub.md +0 -91
  133. package/docs/src/docs/_getting-started/ai-agents.md +0 -56
  134. package/docs/src/docs/_getting-started/concorde-manual-install.md +0 -133
  135. package/docs/src/docs/_getting-started/concorde-outside.md +0 -33
  136. package/docs/src/docs/_getting-started/create-a-component.md +0 -139
  137. package/docs/src/docs/_getting-started/my-first-component.md +0 -236
  138. package/docs/src/docs/_getting-started/my-first-subscriber.md +0 -120
  139. package/docs/src/docs/_getting-started/pubsub.md +0 -37
  140. package/docs/src/docs/_getting-started/start.md +0 -47
  141. package/docs/src/docs/_getting-started/theming.md +0 -91
  142. package/docs/src/docs/_misc/api-configuration.md +0 -79
  143. package/docs/src/docs/_misc/dataProviderKey.md +0 -168
  144. package/docs/src/docs/_misc/docs-mock-api.md +0 -60
  145. package/docs/src/docs/_misc/endpoint.md +0 -43
  146. package/docs/src/docs/_misc/html-integration.md +0 -13
  147. package/docs/src/docs/search/docs-search.json +0 -8532
  148. package/docs/src/tag-list.json +0 -1
  149. package/docs/src/tsconfig-model.json +0 -23
  150. package/docs/src/tsconfig.json +0 -1050
  151. package/php/get-challenge.php +0 -34
  152. package/php/some-service.php +0 -42
@@ -1,236 +0,0 @@
1
- # My first component
2
-
3
- Build a **Lit** user card with Tailwind and Concorde UI, then connect it to the **DataProvider** store: declare the **data configuration** (type, key, scope), and let **`@subscribe`** keep the card in sync.
4
-
5
- > Legacy approach with the **Subscriber mixin**: [Legacy: My first subscriber](#docs/_getting-started/my-first-subscriber.md/my-first-subscriber).
6
-
7
- ## 1. Lit component + Tailwind
8
-
9
- Export Tailwind once (e.g. `src/docs/tailwind.ts` in this repo):
10
-
11
- <sonic-code language="typescript">
12
- <template>
13
- import { css, unsafeCSS } from "lit";
14
- import tailwindImport from "./css/tailwind.css?inline";
15
-
16
- export const tailwind = css`${unsafeCSS(tailwindImport)}`;
17
- </template>
18
- </sonic-code>
19
-
20
- User card — plain Lit properties and UI components (no store yet):
21
-
22
- <sonic-code language="typescript">
23
- <template>
24
- import { html, LitElement } from "lit";
25
- import { customElement, property } from "lit/decorators.js";
26
- import { tailwind } from "../tailwind";
27
-
28
- @customElement("docs-user")
29
- export class DocsUser extends LitElement {
30
- static styles = [tailwind];
31
-
32
- @property({ type: String }) first_name = "";
33
- @property({ type: String }) last_name = "";
34
- @property({ type: String }) email = "";
35
- @property({ type: String }) avatar = "";
36
-
37
- render() {
38
- return html`&lt;div class="flex items-center gap-3 rounded-md p-2"&gt;
39
- &lt;sonic-image src=${this.avatar} rounded="md" ratio="1/1" class="w-16"&gt;&lt;/sonic-image&gt;
40
- &lt;div&gt;
41
- &lt;div&gt;${this.first_name} &lt;span class="font-bold"&gt;${this.last_name}&lt;/span&gt;&lt;/div&gt;
42
- &lt;div class="text-sm text-neutral-400"&gt;${this.email}&lt;/div&gt;
43
- &lt;/div&gt;
44
- &lt;/div&gt;`;
45
- }
46
- }
47
- </template>
48
- </sonic-code>
49
-
50
- ## 2. Data configuration
51
-
52
- The card does not hard-code user fields anymore. You declare **what** is stored, **where** it lives, and **which ancestor scope** applies — then `@subscribe` mirrors that object on the component.
53
-
54
- ### Type — shape of the data
55
-
56
- `DocsUserData` documents the fields you expect at this scope (first name, email, avatar, …). TypeScript checks that `user` matches that shape.
57
-
58
- <sonic-code language="typescript">
59
- <template>
60
- export type DocsUserData = {
61
- first_name: string;
62
- last_name: string;
63
- email: string;
64
- avatar: string;
65
- };
66
- </template>
67
- </sonic-code>
68
-
69
- ### Key — path in the DataProvider
70
-
71
- `docsUserRowKey` points at the store segment to read. The path `"${dataProvider}"` is resolved at runtime from a property on the component (see scope below).
72
-
73
- <sonic-code language="typescript">
74
- <template>
75
- import { DataProviderKey } from "@supersoniks/concorde/core/utils/dataProviderKey";
76
-
77
- export const docsUserRowKey = new DataProviderKey&lt;
78
- DocsUserData,
79
- { dataProvider: string | null }
80
- &gt;("${dataProvider}");
81
- </template>
82
- </sonic-code>
83
-
84
- The second generic (`{ dataProvider: string | null }`) lists what the host must expose so `"${dataProvider}"` can be resolved. See [DataProviderKey](#docs/_misc/dataProviderKey.md/dataProviderKey).
85
-
86
- ### Scope — which store segment applies
87
-
88
- A parent sets `dataProvider=${docsUserScopeAKey.path}` (or a list row sets `…/list-item/0`). [`@ancestorAttribute`](#docs/_decorators/ancestor-attribute.md/ancestor-attribute) copies that attribute onto `this.dataProvider`, so the key resolves to the correct branch.
89
-
90
- <sonic-code language="typescript">
91
- <template>
92
- @ancestorAttribute("dataProvider")
93
- dataProvider: string | null = null;
94
- </template>
95
- </sonic-code>
96
-
97
- ### Subscribe — keep the card in sync
98
-
99
- [`@subscribe`](#docs/_decorators/subscribe.md/subscribe) watches `docsUserRowKey` and updates `user` when the store changes. Use `@state()` so Lit re-renders. The template reads `this.user` like any other property.
100
-
101
- <sonic-code language="typescript">
102
- <template>
103
- import { html, LitElement, nothing } from "lit";
104
- import { customElement, state } from "lit/decorators.js";
105
- import {
106
- ancestorAttribute,
107
- subscribe,
108
- } from "@supersoniks/concorde/core/decorators/Subscriber";
109
- import { docsUserRowKey, type DocsUserData } from "./users";
110
- import { tailwind } from "../tailwind";
111
-
112
- @customElement("docs-user")
113
- export class DocsUser extends LitElement {
114
- static styles = [tailwind];
115
-
116
- @ancestorAttribute("dataProvider")
117
- dataProvider: string | null = null;
118
-
119
- @subscribe(docsUserRowKey)
120
- @state()
121
- user: DocsUserData | null = null;
122
-
123
- render() {
124
- const u = this.user;
125
- if (!u) return nothing;
126
- return html`&lt;div class="flex items-center gap-3 rounded-md p-2"&gt;
127
- &lt;sonic-image src=${u.avatar} rounded="md" ratio="1/1" class="w-16"&gt;&lt;/sonic-image&gt;
128
- &lt;div&gt;
129
- &lt;div&gt;${u.first_name} &lt;span class="font-bold"&gt;${u.last_name}&lt;/span&gt;&lt;/div&gt;
130
- &lt;div class="text-sm text-neutral-400"&gt;${u.email}&lt;/div&gt;
131
- &lt;/div&gt;
132
- &lt;/div&gt;`;
133
- }
134
- }
135
- </template>
136
- </sonic-code>
137
-
138
- Live code: `src/docs/example/users.ts`. In this repo, imports use **`core/…` paths** (short `@supersoniks/concorde/…` exports apply in **consumer apps** only).
139
-
140
- ### Two scopes, one component
141
-
142
- The same `docs-user` is mounted twice. Each copy inherits a **different** nearest `dataProvider` — that is the row/list **scope**:
143
-
144
- <sonic-code>
145
- <template>
146
- <docs-demo-sources for="docs-user-two-scopes"></docs-demo-sources>
147
- <docs-user-two-scopes></docs-user-two-scopes>
148
- </template>
149
- </sonic-code>
150
-
151
- Markup (two isolated stores; keys from `docs-provider-keys.ts`):
152
-
153
- <sonic-code language="markup">
154
- <template>
155
- &lt;div class="grid md:grid-cols-2 gap-6"&gt;
156
- &lt;div dataProvider="${docsUserScopeAKey.path}"&gt;
157
- &lt;docs-user&gt;&lt;/docs-user&gt;
158
- &lt;/div&gt;
159
- &lt;div dataProvider="${docsUserScopeBKey.path}"&gt;
160
- &lt;docs-user&gt;&lt;/docs-user&gt;
161
- &lt;/div&gt;
162
- &lt;/div&gt;
163
- </template>
164
- </sonic-code>
165
-
166
- Seeded in `docs-provider-keys.ts` (`set(docsUserScopeAKey, …)`): **Paul** / **Marie**. Without `@ancestorAttribute`, both cards would not know which store to read.
167
-
168
- ## 3. Fetch users — `sonic-list` with `.items`
169
-
170
- Use a Lit parent and the **`items`** renderer (not HTML `<template>` children). The callback receives each row object from fetch — render fields directly (`${item.first_name}`, …), like porting a template that used `data-bind` / `<sonic-value>`.
171
-
172
- <sonic-code>
173
- <template>
174
- <docs-lit-demo for="docs-users-list"></docs-lit-demo>
175
- </template>
176
- </sonic-code>
177
-
178
- Wrapper (`docs-users-list.ts`):
179
-
180
- <sonic-code language="typescript">
181
- <template>
182
- import { html, LitElement } from "lit";
183
- import { customElement } from "lit/decorators.js";
184
- import "../../core/components/functional/list/list";
185
- import "./users";
186
-
187
- @customElement("docs-users-list")
188
- export class DocsUsersList extends LitElement {
189
- private items = ({ first_name, last_name, email, avatar }) => html`
190
- &lt;div class="flex gap-3"&gt;
191
- &lt;sonic-image src=${avatar} ...&gt;&lt;/sonic-image&gt;
192
- &lt;div&gt;${first_name} &lt;b&gt;${last_name}&lt;/b&gt;&lt;/div&gt;
193
- &lt;div class="text-sm text-neutral-400"&gt;${email}&lt;/div&gt;
194
- &lt;/div&gt;
195
- `;
196
-
197
- render() {
198
- return html`
199
- &lt;sonic-list fetch dataProvider=${usersListEndpoint.path} key="data" .items=${this.items}&gt;&lt;/sonic-list&gt;
200
- `;
201
- }
202
- }
203
- </template>
204
- </sonic-code>
205
-
206
- See [Local API demos](#docs/_misc/docs-mock-api.md/docs-mock-api) for `serviceURL="/docs-mock-api"`.
207
-
208
- ## 4. Form preview with `formDataProvider`
209
-
210
- Edit fields in a form; the card follows the same `docsUserRowKey` when the preview host sets `dataProvider="userPreview"`.
211
-
212
- <sonic-code>
213
- <template>
214
- <div class="grid grid-cols-1 gap-4 max-w-xl">
215
- <form formDataProvider="${docsUserPreviewKey.path}" class="grid grid-cols-2 gap-3">
216
- <sonic-input label="First name" name="first_name" value="Paul" size="sm"></sonic-input>
217
- <sonic-input label="Last name" name="last_name" value="Metrand" size="sm"></sonic-input>
218
- <sonic-input class="col-span-2" label="Email" name="email" value="paul@example.com" size="sm"></sonic-input>
219
- <sonic-input class="col-span-2" label="Avatar URL" name="avatar" value="https://i.pravatar.cc/150?u=paul" size="sm"></sonic-input>
220
- </form>
221
- <sonic-divider align="left">Preview</sonic-divider>
222
- <div dataProvider="${docsUserPreviewKey.path}">
223
- <docs-user></docs-user>
224
- </div>
225
- </div>
226
- </template>
227
- </sonic-code>
228
-
229
- Use `formDataProvider` + `name` on inputs — no manual `@input` handlers ([Data flow](#docs/_core-concept/dataFlow.md/dataFlow)).
230
-
231
- ## Next steps
232
-
233
- - [Data flow](#docs/_core-concept/dataFlow.md/dataFlow) — full map
234
- - [DataProviderKey](#docs/_misc/dataProviderKey.md/dataProviderKey) — typed paths and host constraints
235
- - [@subscribe](#docs/_decorators/subscribe.md/subscribe) / [sub()](#docs/_directives/sub.md/sub) — read-only in templates
236
- - [List](#core/components/functional/list/list.md/list) — `.items`, `.noItems`, `.skeleton`
@@ -1,120 +0,0 @@
1
- # Legacy: My first subscriber component
2
-
3
- > **New projects:** use [My first component](#docs/_getting-started/my-first-component.md/my-first-component) (`@ancestorAttribute`, `@subscribe` + `DataProviderKey`, `.items` on lists) and [Data flow](#docs/_core-concept/dataFlow.md/dataFlow). This page documents the **Subscriber mixin** used by older apps and core components.
4
-
5
- Learn how to build a component with the **Subscriber** mixin, styled with Tailwind, filled from a DataProvider via automatic property mapping.
6
-
7
- ## Create a classic lit component
8
-
9
- <sonic-code language="javascript" >
10
- <template>
11
- import { html, LitElement, nothing } from "lit";
12
- import { customElement, property } from "lit/decorators.js";
13
- @customElement("docs-user")
14
- export class user extends LitElement {
15
- @property({ type: String }) first_name = "";
16
- @property({ type: String }) last_name = "";
17
- @property({ type: String }) avatar = "";
18
- @property({ type: String }) email = "";
19
- render() {
20
- return html`
21
- &lt;img src="${this.avatar}" /&gt; &lt;br&gt;
22
- ${this.first_name} ${this.last_name} &lt;br&gt;
23
- ${this.email}`;
24
- }
25
- }
26
- </template>
27
- </sonic-code>
28
-
29
- ### Style with tailwind and ui components
30
-
31
- <sonic-code language="javascript">
32
- <template>
33
- import { css, unsafeCSS } from "lit";
34
- import tailwindImport from "./css/tailwind.css?inline";
35
- export const tailwind = css`${unsafeCSS(tailwindImport)}`;
36
- </template>
37
- </sonic-code>
38
-
39
- <sonic-code language="javascript">
40
- <template>
41
- import { html, LitElement } from "lit";
42
- import { customElement, property } from "lit/decorators.js";
43
- import { tailwind } from "../tailwind";
44
- import '@supersoniks/concode/ui/image'
45
- import '@supersoniks/concode/ui/button'
46
- import '@supersoniks/concode/ui/icon'
47
- @customElement("docs-user")
48
- export class user extends LitElement {
49
- static styles = [tailwind];
50
- @property({ type: String }) first_name = "";
51
- @property({ type: String }) last_name = "";
52
- @property({ type: String }) avatar = "";
53
- @property({ type: String }) email = "";
54
- render() {
55
- return html`&lt;div class="flex items-center gap-3 p-2"&gt;
56
- &lt;sonic-image src=${this.avatar} rounded="md" ratio="1/1" class="w-16"&gt;&lt;/sonic-image&gt;
57
- &lt;div&gt;${this.first_name} &lt;span class="font-bold"&gt;${this.last_name}&lt;/span&gt;&lt;/div&gt;
58
- &lt;div class="text-sm text-neutral-400"&gt;${this.email}&lt;/div&gt;
59
- &lt;/div&gt;`;
60
- }
61
- }
62
- </template>
63
- </sonic-code>
64
-
65
- ## Add Subscriber mixin
66
-
67
- <sonic-code language="javascript">
68
- <template>
69
- import Subscriber from "@supersoniks/concorde/core/mixins/Subscriber";
70
- @customElement("docs-user")
71
- export class user extends Subscriber(LitElement) {
72
- // properties auto-filled from DataProvider when names match
73
- }
74
- </template>
75
- </sonic-code>
76
-
77
- See [Legacy: Subscriber mixin](#docs/_core-concept/subscriber.md/subscriber).
78
-
79
- ## Autofill from a dataProvider
80
-
81
- <sonic-code >
82
- <template>
83
- <docs-demo-sources for="list-users-fetch"></docs-demo-sources>
84
- <div serviceURL="/docs-mock-api">
85
- <sonic-fetch
86
- serviceURL="/docs-mock-api"
87
- dataProvider="api/users/3"
88
- key="data">
89
- <docs-user></docs-user>
90
- </sonic-fetch>
91
- </div>
92
- </template>
93
- </sonic-code>
94
-
95
- <sonic-code >
96
- <template>
97
- <sonic-fetch
98
- serviceURL="/docs-mock-api"
99
- dataProvider="api/users/2"
100
- key="data"></sonic-fetch>
101
- <docs-user dataProvider="api/users/2" ></docs-user>
102
- </template>
103
- </sonic-code>
104
-
105
- <sonic-code >
106
- <template>
107
- <div class="grid grid-cols-1 gap-4">
108
- <form formDataProvider="userPreview" class="grid grid-cols-4 gap-3" >
109
- <sonic-input label="First name" type="text" name="first_name" value="Paul" size="sm"></sonic-input>
110
- <sonic-input label="Last name" type="text" name="last_name" value="Metrand" size="sm"></sonic-input>
111
- <sonic-input class="col-span-2" label="email" type="text" name="email" value="paul@example.com" size="sm"></sonic-input>
112
- <sonic-input label="Image url" type="text" name="avatar" value="https://i.pravatar.cc/150?u=paul" size="sm"></sonic-input>
113
- </form>
114
- <sonic-divider align="left">Preview before submit</sonic-divider>
115
- <div dataProvider="userPreview">
116
- <docs-user></docs-user>
117
- </div>
118
- </div>
119
- </template>
120
- </sonic-code>
@@ -1,37 +0,0 @@
1
- # Legacy: Sharing data
2
-
3
- > **New apps:** [Data flow](#docs/_core-concept/dataFlow.md/dataFlow) (`get` / `set` / `DataProviderKey`, decorators). This page documents the historical **Publisher** proxy API (`PublisherManager`, `publisher.set`, `onAssign`, …).
4
-
5
- This section describes how data is shared between graphical and non-graphical components.
6
-
7
- Graphical components should not reference each other directly — they stay decoupled via a **publish/subscribe** store.
8
-
9
- ## The Publisher
10
-
11
- ### Principle
12
-
13
- * The **publisher** is a [JavaScript proxy](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Proxy) that holds data.<br>
14
- Example: `{foo:{hello:["world"]}, bar:"baz"}`
15
-
16
- * Accessing a property (`myPublisher.foo.hello`) returns another **publisher** for that segment.
17
-
18
- * Missing properties create a publisher with internal data `null`, filled later.
19
-
20
- * **Subscribers** listen via `onAssign`, `onInternalMutation`, template filling on the **Subscriber mixin**, etc.
21
-
22
- * Updates use `publisher.set(...)` or nested assignment; changes propagate to subscribers.
23
-
24
- ❇️ Order of creation vs subscription theoretically does not matter.
25
-
26
- ### Methods
27
-
28
- * **set** — replace internal value
29
- <sonic-code language="javascript"><template>publisher.set({foo:{hello:["world"]}, bar:"baz"});</template></sonic-code>
30
-
31
- * **get** — read internal value
32
- <sonic-code language="javascript"><template>publisher.get()</template></sonic-code>
33
-
34
- * **onAssign / offAssign** — react to `set`
35
- <sonic-code language="javascript"><template>publisher.a.b.onAssign(console.log);</template></sonic-code>
36
-
37
- Modern equivalent: `get` / `set` / `@handle` — see [Data flow](#docs/_core-concept/dataFlow.md/dataFlow).
@@ -1,47 +0,0 @@
1
- # Introduction
2
-
3
- ## What is Concorde?
4
-
5
- Based on **[lit.dev](https://lit.dev)**, Concorde is a collection of web components for shared apps and websites.
6
- Build UIs without tying components to a specific host stack, while keeping visual consistency through a small set of CSS variables.
7
-
8
- ## Why and use case
9
-
10
- In 2022, Supersoniks needed a new ticketing stack for nearly 100 sites — mobile apps, modern sites, and legacy PHP without bundlers.
11
- One composable web-component library replaced many one-off apps. Lit was chosen for broad runtime compatibility.
12
-
13
- ### Stack
14
-
15
- * Lit
16
- * TypeScript
17
- * Vite
18
- * Tailwind (starter kit, not required in the core package)
19
-
20
- ### Functional features
21
-
22
- * **DataProvider** store (decorators, `get` / `set`)
23
- * Forms (`formDataProvider`)
24
- * Lists, queues, lazy loading
25
- * Router, states, UI kit with status variants
26
-
27
- ## Learn Concorde
28
-
29
- | Step | Page |
30
- |------|------|
31
- | 1 | [My first component](#docs/_getting-started/my-first-component.md/my-first-component) — Lit card, `@ancestorAttribute`, `@bind`, mock API |
32
- | 2 | [Data flow](#docs/_core-concept/dataFlow.md/dataFlow) — Core concepts: decorators and APIs |
33
- | 3 | [Local API demos](#docs/_misc/docs-mock-api.md/docs-mock-api) — offline `serviceURL` for this site (Misc) |
34
- | 4 | [create-concorde-ts-starter](https://www.npmjs.com/package/@supersoniks/create-concorde-ts-starter) — **recommended** project kit (Vite, Tailwind, `yarn ai:sync`) |
35
- | 5 | [AI agents (skills)](#docs/_getting-started/ai-agents.md/ai-agents) — `AGENTS.md`, Cursor / JetBrains rules |
36
-
37
- Legacy (Subscriber mixin, Publisher API): **Legacy** section at the bottom of the sidebar.
38
-
39
- ## Start a new project
40
-
41
- <sonic-code language="bash">
42
- <template>
43
- npx @supersoniks/create-concorde-ts-starter "project_name"
44
- </template>
45
- </sonic-code>
46
-
47
- The starter runs **`yarn ai:sync`** for you. Details: [AI agents (skills)](#docs/_getting-started/ai-agents.md/ai-agents). Manual Vite setup: [Legacy: Manual installation](#docs/_getting-started/concorde-manual-install.md/concorde-manual-install).
@@ -1,91 +0,0 @@
1
- # Adding styles
2
-
3
- ## Normal Behavior
4
-
5
- No style crosses the shadow root of a component, except for inheritable properties (which have the "inherit" property possible) and CSS variables.
6
- Properties integrated via a "[slot](https://developer.mozilla.org/en/docs/Web/HTML/Element/slot)" remain stylizable in a conventional way.
7
-
8
- - **During creation / from the inside:**
9
- - We edit the [static "styles" property of the lit component](https://lit.dev/docs/components/styles/), which can also reference shared and dynamic styles.
10
- These styles are scoped and do not impact the outside.
11
- - We use CSS variables as the value of properties intended to be customized from the outside.
12
- For each variable, we define a default value to have a simple but consistent base style.
13
- - We only rewrite inheritable properties with hard values if they are truly specific to the component.
14
- - The `<style>` tag as a direct child can be used as a last resort, especially if there is a need for particularly dynamic customization. Performance is reduced.
15
- - **During use / from the outside:**
16
- We define values for **inheritable CSS properties** (e.g., font-\_, color...) using tools like Tailwind.
17
- We modify the value of **CSS variables** used by the component.
18
-
19
- ## Choosing Style Presets via Reactive Properties:
20
-
21
- The declaration of reactive properties is useful for selecting a particular configuration that mostly affects a set of properties.
22
-
23
- For example, a `size` property (xs, sm, md, xl) will affect margins, font, line heights to align them with the corresponding CSS vars, which can be customized using the methods mentioned earlier if necessary.
24
-
25
- It is recommended to use the `{reflect: true}` property for reactive properties that have an associated style on the `:host()`. For example: `:host([type='primary']){...}`
26
-
27
- ☢️ **Caution:** Passing class names via reactive properties / HTML attributes of the component should be avoided as it can quickly lead to difficult-to-manage situations.
28
-
29
- #### CSS "display" Property
30
-
31
- By default, the display property is `inline`.
32
- Therefore, be careful to define it according to the needs, as one might mistakenly expect it to be `block` as with a regular `<div>`.
33
-
34
- ☢️ **Caution:** Defining the `display` property as `contents` may seem attractive at first, but:
35
-
36
- - It almost always leads to the creation of wrappers to style the content (instead of using `:host`).
37
- - It is no longer possible to directly add classes to the component or style it from the outside.
38
- Ultimately, the amount of code to write increases significantly.
39
-
40
- ## TAILWIND Functional Classes
41
-
42
- [tailwind](https://tailwindcss.com/) has been integrated into Concorde and is available in scoped components (with Shadow DOM).
43
- To use it, you need to import the following:
44
-
45
- <sonic-code language="javascript">
46
- <template>
47
- import { tailwind } from "@supersoniks/concorde/la-billetterie/ui/theme/theme";
48
- </template>
49
- </sonic-code>
50
-
51
- Then include the `tailwind` style in the static `styles` property of the component:
52
-
53
- <sonic-code language="javascript">
54
- <template>
55
- static styles = [tailwind];
56
- </template>
57
- </sonic-code>
58
-
59
- Finally, use it in the HTML within the render function:
60
-
61
- <sonic-code language="html">
62
- <template>
63
- <p class="m-2">A paragraph with margin</p>
64
- </template>
65
- </sonic-code>
66
-
67
- The colors from Concorde's theme are referenced in Tailwind's theme.
68
-
69
- ## Operation without Shadow DOM
70
-
71
- ### Usefulness
72
-
73
- This operation is particularly useful when it comes to **adding behavior to a simple existing element**.
74
- It may also become necessary to establish **compatibility with a traditional JS library**.
75
-
76
- For example, with a text input:
77
-
78
- - Trigger automatic data or filter update when typing text.
79
- - Automatic formatting.
80
- - Constraints that cannot be handled by native methods.
81
-
82
- ### Consequences
83
-
84
- If there is no shadow DOM (see the **noShadowDom** property of **Subscriber**):
85
-
86
- - Styling using the static "styles" property of the lit component will not be applied.
87
- - The element and its content can be styled in a traditional manner.
88
-
89
- For example, the components `queue`, `list`, and `fetch` do not have a shadow DOM.
90
-
91
- ℹ️ **Note:** Specifically in this case, it may be useful to set the `display` property to `contents`.
@@ -1,79 +0,0 @@
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 configuration key](#docs/_decorators/get.md/get)). It is passed to [`API`](../../core/utils/api.ts) by fetchers, **sonic-submit**, the **`wording()`** directive, and **`@get`**.
4
-
5
- > **Mock service:** same [Local API demos](#docs/_misc/docs-mock-api.md/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.md/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="wording/labels?lang=fr"` + `wording('api-config.greeting')` in Lit. Mock returns label map from `labels[]` query params.
53
-
54
- <docs-lit-demo for="docs-api-config-wording-demo"></docs-lit-demo>
55
-
56
- ## Scoped attributes (HTML / sonic-scope)
57
-
58
- Attributes on **`sonic-scope`** (or any ancestor) are visible to descendants via `getAncestorAttributeValue`.
59
-
60
- <docs-lit-demo for="docs-api-config-scoped-attrs-demo"></docs-lit-demo>
61
-
62
- ## API config routes
63
-
64
- | Route | Demo |
65
- |-------|------|
66
- | `GET /docs-mock-api/auth/token` | tokenProvider, eventsApiToken |
67
- | `GET /docs-mock-api/api/config/protected` | Bearer / Basic / 498 |
68
- | `GET /docs-mock-api/wording/labels?labels[]=…&lang=fr` | `wording()` |
69
-
70
- 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`.
71
-
72
- Implementation: `src/docs/mock-api/api-config-mock.ts` (bundled in the Service Worker with `router.ts`).
73
-
74
- ## See also
75
-
76
- - [@get](#docs/_decorators/get.md/get) — `APIConfiguration` + `Endpoint`
77
- - [Endpoint](#docs/_misc/endpoint.md/endpoint) — typed path
78
- - [Local API demos](#docs/_misc/docs-mock-api.md/docs-mock-api) — offline `serviceURL`
79
- - [Fetch](#core/components/functional/fetch/fetch.md/fetch) — attribute table (legacy sonic-fetch)