@supersoniks/concorde 5.0.4 → 5.0.5

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 (208) hide show
  1. package/.agents/skills/concorde-component-docs/SKILL.md +194 -0
  2. package/.agents/skills/concorde-component-docs/template.md +45 -0
  3. package/ai/cursor/rules/concorde-theme.mdc +1 -1
  4. package/ai/cursor/rules/concorde.mdc +1 -1
  5. package/ai/skills/concorde/SKILL.md +1 -1
  6. package/ai/skills/concorde-theme/SKILL.md +21 -10
  7. package/build-infos.json +1 -1
  8. package/concorde-core.bundle.js +528 -534
  9. package/concorde-core.es.js +4257 -4212
  10. package/dist/concorde-core.bundle.js +528 -534
  11. package/dist/concorde-core.es.js +4257 -4212
  12. package/dist/docs-mock-api-sw.js +2 -0
  13. package/dist/docs-mock-api-sw.js.map +2 -2
  14. package/docs/assets/index-CD4WyL6o.css +1 -0
  15. package/docs/assets/{index-D8MVWqY6.js → index-wVZpLVYW.js} +1221 -1350
  16. package/docs/crawl/core/components/ui/alert/alert.html +172 -71
  17. package/docs/crawl/core/components/ui/alert-messages/alert-messages.html +113 -5
  18. package/docs/crawl/core/components/ui/badge/badge.html +157 -79
  19. package/docs/crawl/core/components/ui/button/button.html +1 -0
  20. package/docs/crawl/core/components/ui/captcha/captcha.html +90 -8
  21. package/docs/crawl/core/components/ui/card/card.html +222 -68
  22. package/docs/crawl/core/components/ui/divider/divider.html +117 -31
  23. package/docs/crawl/core/components/ui/form/fieldset/fieldset.html +232 -101
  24. package/docs/crawl/core/components/ui/form/form-actions/form-actions.html +95 -52
  25. package/docs/crawl/core/components/ui/form/form-layout/form-layout.html +97 -38
  26. package/docs/crawl/core/components/ui/form/input/input.html +3 -3
  27. package/docs/crawl/core/components/ui/form/textarea/textarea.html +3 -3
  28. package/docs/crawl/core/components/ui/group/group.html +60 -38
  29. package/docs/crawl/core/components/ui/icon/icon.html +136 -47
  30. package/docs/crawl/core/components/ui/image/image.html +244 -56
  31. package/docs/crawl/core/components/ui/link/link.html +67 -9
  32. package/docs/crawl/core/components/ui/loader/loader.html +97 -23
  33. package/docs/crawl/core/components/ui/menu/menu.html +162 -90
  34. package/docs/crawl/core/components/ui/modal/modal.html +275 -50
  35. package/docs/crawl/core/components/ui/pop/pop.html +260 -66
  36. package/docs/crawl/core/components/ui/progress/progress.html +103 -30
  37. package/docs/crawl/core/components/ui/table/table.html +303 -171
  38. package/docs/crawl/core/components/ui/theme/theme.html +131 -0
  39. package/docs/crawl/core/components/ui/toast/toast.html +170 -59
  40. package/docs/crawl/core/components/ui/tooltip/tooltip.html +90 -29
  41. package/docs/crawl/docs/_decorators/ancestor-attribute.html +3 -2
  42. package/docs/crawl/docs/_getting-started/concorde-outside.html +3 -3
  43. package/docs/crawl/docs/_getting-started/start.html +1 -1
  44. package/docs/crawl/docs/_getting-started/theming.html +311 -63
  45. package/docs/crawl/hubs/form-components.html +75 -53
  46. package/docs/crawl/index.html +7 -6
  47. package/docs/docs-mock-api-sw.js +2 -0
  48. package/docs/docs-mock-api-sw.js.map +2 -2
  49. package/docs/index.html +9 -7
  50. package/docs/llms-full.txt +1703 -456
  51. package/docs/llms.txt +25 -32
  52. package/docs/sitemap.xml +3 -0
  53. package/docs/src/core/components/functional/fetch/fetch.md +0 -0
  54. package/docs/src/core/components/functional/if/if.md +0 -0
  55. package/docs/src/core/components/functional/list/list.md +0 -0
  56. package/docs/src/core/components/functional/router/router.md +0 -0
  57. package/docs/src/core/components/functional/sdui/sdui.md +0 -0
  58. package/docs/src/core/components/functional/states/states.md +0 -0
  59. package/docs/src/core/components/functional/submit/submit.md +0 -0
  60. package/docs/src/core/components/ui/alert/alert.md +147 -72
  61. package/docs/src/core/components/ui/alert-messages/alert-messages.md +85 -0
  62. package/docs/src/core/components/ui/badge/badge.md +141 -80
  63. package/docs/src/core/components/ui/button/button.md +1 -0
  64. package/docs/src/core/components/ui/captcha/captcha.md +65 -6
  65. package/docs/src/core/components/ui/card/card.md +183 -65
  66. package/docs/src/core/components/ui/divider/divider.md +107 -13
  67. package/docs/src/core/components/ui/form/fieldset/fieldset.md +175 -99
  68. package/docs/src/core/components/ui/form/form-actions/form-actions.md +75 -52
  69. package/docs/src/core/components/ui/form/form-layout/form-layout.md +109 -34
  70. package/docs/src/core/components/ui/form/input/input.md +1 -1
  71. package/docs/src/core/components/ui/form/radio/radio.md +0 -0
  72. package/docs/src/core/components/ui/form/select/select.md +0 -0
  73. package/docs/src/core/components/ui/form/switch/switch.md +0 -0
  74. package/docs/src/core/components/ui/form/textarea/textarea.md +1 -1
  75. package/docs/src/core/components/ui/group/group.md +36 -36
  76. package/docs/src/core/components/ui/icon/icon.md +132 -43
  77. package/docs/src/core/components/ui/image/image.md +179 -53
  78. package/docs/src/core/components/ui/link/link.md +45 -7
  79. package/docs/src/core/components/ui/loader/loader.md +79 -22
  80. package/docs/src/core/components/ui/menu/menu.md +133 -92
  81. package/docs/src/core/components/ui/modal/modal.md +163 -47
  82. package/docs/src/core/components/ui/pop/pop.md +262 -64
  83. package/docs/src/core/components/ui/progress/progress.md +76 -30
  84. package/docs/src/core/components/ui/table/table.md +147 -171
  85. package/docs/src/core/components/ui/theme/theme.md +122 -0
  86. package/docs/src/core/components/ui/toast/toast.md +108 -58
  87. package/docs/src/core/components/ui/tooltip/tooltip.md +68 -26
  88. package/docs/src/docs/_core-concept/subscriber.md +0 -0
  89. package/docs/src/docs/_decorators/ancestor-attribute.md +3 -2
  90. package/docs/src/docs/_getting-started/concorde-outside.md +3 -3
  91. package/docs/src/docs/_getting-started/my-first-subscriber.md +0 -0
  92. package/docs/src/docs/_getting-started/pubsub.md +0 -0
  93. package/docs/src/docs/_getting-started/start.md +1 -1
  94. package/docs/src/docs/_getting-started/theming.md +223 -61
  95. package/docs/src/docs/search/docs-search.json +3083 -348
  96. package/docs/src/tsconfig.json +63 -3
  97. package/gitlab/job_tests.sh +0 -0
  98. package/index.html +4 -2
  99. package/package.json +7 -1
  100. package/public/docs-mock-api-sw.js +2 -0
  101. package/public/docs-mock-api-sw.js.map +2 -2
  102. package/scripts/post-build-docs.js +0 -0
  103. package/scripts/post-build.mjs +0 -0
  104. package/src/core/components/functional/fetch/fetch.md +0 -0
  105. package/src/core/components/functional/if/if.md +0 -0
  106. package/src/core/components/functional/list/list.demo.ts +0 -0
  107. package/src/core/components/functional/list/list.md +0 -0
  108. package/src/core/components/functional/router/router.md +0 -0
  109. package/src/core/components/functional/router/router.ts +0 -0
  110. package/src/core/components/functional/sdui/sdui.md +0 -0
  111. package/src/core/components/functional/states/states.md +0 -0
  112. package/src/core/components/functional/submit/submit.md +0 -0
  113. package/src/core/components/functional/subscriber/subscriber.ts +0 -0
  114. package/src/core/components/ui/_css/align.ts +1 -0
  115. package/src/core/components/ui/_css/size.ts +0 -0
  116. package/src/core/components/ui/_css/type.ts +86 -8
  117. package/src/core/components/ui/_i18n/ui-aria-labels.ts +8 -0
  118. package/src/core/components/ui/alert/alert.md +21 -2
  119. package/src/core/components/ui/alert-messages/alert-messages.md +85 -0
  120. package/src/core/components/ui/badge/badge.md +19 -6
  121. package/src/core/components/ui/badge/badge.ts +8 -9
  122. package/src/core/components/ui/button/button.ts +5 -15
  123. package/src/core/components/ui/captcha/altchaStyles.ts +0 -0
  124. package/src/core/components/ui/captcha/captcha.md +65 -6
  125. package/src/core/components/ui/card/card.md +73 -10
  126. package/src/core/components/ui/card/card.ts +24 -22
  127. package/src/core/components/ui/divider/divider.md +107 -13
  128. package/src/core/components/ui/divider/divider.ts +40 -33
  129. package/src/core/components/ui/form/fieldset/fieldset.md +175 -99
  130. package/src/core/components/ui/form/fieldset/fieldset.ts +15 -28
  131. package/src/core/components/ui/form/fieldset/legend.ts +13 -13
  132. package/src/core/components/ui/form/form-actions/form-actions.md +75 -52
  133. package/src/core/components/ui/form/form-actions/form-actions.ts +7 -5
  134. package/src/core/components/ui/form/form-layout/form-layout.md +109 -34
  135. package/src/core/components/ui/form/form-layout/form-layout.ts +27 -24
  136. package/src/core/components/ui/form/radio/radio.md +0 -0
  137. package/src/core/components/ui/form/select/select.md +0 -0
  138. package/src/core/components/ui/form/switch/switch.md +0 -0
  139. package/src/core/components/ui/form/textarea/textarea.ts +4 -3
  140. package/src/core/components/ui/group/group.md +36 -36
  141. package/src/core/components/ui/group/group.ts +5 -10
  142. package/src/core/components/ui/icon/icon.md +132 -43
  143. package/src/core/components/ui/image/image.md +35 -3
  144. package/src/core/components/ui/link/link.md +43 -5
  145. package/src/core/components/ui/loader/loader.md +79 -22
  146. package/src/core/components/ui/loader/loader.ts +67 -27
  147. package/src/core/components/ui/loader/styles/fixed.ts +6 -11
  148. package/src/core/components/ui/menu/menu.md +133 -92
  149. package/src/core/components/ui/menu/menu.ts +53 -58
  150. package/src/core/components/ui/modal/modal.md +163 -47
  151. package/src/core/components/ui/modal/modal.ts +2 -4
  152. package/src/core/components/ui/pop/pop.md +217 -123
  153. package/src/core/components/ui/pop/pop.ts +0 -1
  154. package/src/core/components/ui/progress/progress.md +76 -30
  155. package/src/core/components/ui/progress/progress.ts +25 -56
  156. package/src/core/components/ui/table/table-caption.ts +2 -2
  157. package/src/core/components/ui/table/table-tbody.ts +3 -3
  158. package/src/core/components/ui/table/table-td.ts +23 -18
  159. package/src/core/components/ui/table/table-th.ts +8 -8
  160. package/src/core/components/ui/table/table-tr.ts +4 -4
  161. package/src/core/components/ui/table/table.md +147 -171
  162. package/src/core/components/ui/table/table.ts +20 -19
  163. package/src/core/components/ui/theme/theme-collection/auto.ts +15 -0
  164. package/src/core/components/ui/theme/theme-collection/core-variables.ts +8 -31
  165. package/src/core/components/ui/theme/theme-collection/dark.ts +1 -7
  166. package/src/core/components/ui/theme/theme-collection/light.ts +30 -26
  167. package/src/core/components/ui/theme/theme.md +122 -0
  168. package/src/core/components/ui/theme/theme.ts +30 -7
  169. package/src/core/components/ui/toast/toast-item.ts +6 -9
  170. package/src/core/components/ui/toast/toast.md +108 -58
  171. package/src/core/components/ui/toast/types.ts +1 -1
  172. package/src/core/components/ui/tooltip/tooltip.md +68 -26
  173. package/src/core/mixins/Subscriber.ts +0 -0
  174. package/src/core/utils/DataBindObserver.ts +0 -0
  175. package/src/core/utils/Objects.ts +0 -0
  176. package/src/core/utils/route.ts +0 -0
  177. package/src/docs/_core-concept/subscriber.md +0 -0
  178. package/src/docs/_getting-started/my-first-subscriber.md +0 -0
  179. package/src/docs/_getting-started/pubsub.md +0 -0
  180. package/src/docs/_getting-started/start.md +1 -1
  181. package/src/docs/_getting-started/theming.md +223 -61
  182. package/src/docs/code.ts +125 -58
  183. package/src/docs/example/users.ts +0 -0
  184. package/src/docs/header/header.ts +62 -54
  185. package/src/docs/mock-api/router.ts +2 -0
  186. package/src/docs/navigation/navigation.ts +6 -3
  187. package/src/docs/search/docs-search.json +2504 -399
  188. package/src/docs/search/markdown-renderer.ts +6 -6
  189. package/src/docs/search/page.ts +0 -0
  190. package/src/docs/search/search.ts +4 -4
  191. package/src/docs/tailwind/css/tailwind.css +6 -5
  192. package/src/tsconfig.json +18 -0
  193. package/src/tsconfig.tsbuildinfo +1 -1
  194. package/tailwind.config.js +19 -0
  195. package/.github/workflows/ci.yml +0 -21
  196. package/.github-export-ignore +0 -30
  197. package/CONTRIBUTING.md +0 -59
  198. package/DEV.md +0 -54
  199. package/LICENSE +0 -21
  200. package/OPEN_SOURCE_CHECKPOINT.md +0 -133
  201. package/docs/assets/index-DiD0qYvE.css +0 -1
  202. package/docs/src/tsconfig.declarations.json +0 -22
  203. package/docs/src/tsconfig.emit.json +0 -23
  204. package/gitlab/job_github_mirror.sh +0 -39
  205. package/scripts/github-export.mjs +0 -150
  206. package/src/css.d.ts +0 -19
  207. package/src/tsconfig.declarations.json +0 -22
  208. package/src/tsconfig.emit.json +0 -23
@@ -0,0 +1,122 @@
1
+ # Theme
2
+
3
+ **`sonic-theme`** wraps a Concorde UI: it registers **`--sc-*`** design tokens and provides the default slot for your app. With no **`theme`** attribute (or **`theme="custom"`**), only shared primitives and your overrides apply—built-in **`light`** / **`dark`** / **`auto`** palettes are opt-in. Set **`color`** and **`font`** when the host should carry base text and typography; add Tailwind **`bg-base`** and **`block`** (or **`min-h-screen`**) on the tag for a full surface fill. **Popovers**, **modals**, and **toasts** mount under the nearest connected theme (see [Pop container](#pop-container)). Import **`@supersoniks/concorde/theme`** once at the app entry. For the full public token list and brand overrides, see [Customization](#docs/_getting-started/theming.md/theming).
4
+
5
+ ## Basic example
6
+
7
+ Wrap interactive components so tokens and overlays resolve from one root.
8
+
9
+ <sonic-code>
10
+ <template>
11
+ <sonic-theme color font class="block bg-base p-6 rounded-lg">
12
+ <sonic-button type="primary">Save changes</sonic-button>
13
+ </sonic-theme>
14
+ </template>
15
+ </sonic-code>
16
+
17
+ ## Theme mode
18
+
19
+ **Default:** omit **`theme`** or set **`theme="custom"`**. The host loads core tokens (`--sc-rounded`, shadows, form defaults, …) and any **`--sc-*`** you set; it does **not** apply the built-in light or dark palette.
20
+
21
+ Set **`theme`** to **`light`** or **`dark`** for Concorde’s preset palettes. Set **`theme="auto"`** to follow **`prefers-color-scheme`** (light palette until the OS prefers dark).
22
+
23
+ <sonic-code>
24
+ <template>
25
+ <div class="grid gap-4 md:grid-cols-2">
26
+ <sonic-theme theme="light" color font class="block bg-base p-4 rounded-md border border-neutral-200">
27
+ <p class="text-sm mb-3 opacity-80">theme="light"</p>
28
+ <div class="flex flex-wrap gap-2">
29
+ <sonic-badge type="primary">Primary</sonic-badge>
30
+ <sonic-badge type="success">Success</sonic-badge>
31
+ <sonic-badge type="danger">Danger</sonic-badge>
32
+ </div>
33
+ </sonic-theme>
34
+ <sonic-theme theme="dark" color font class="block bg-base p-4 rounded-md">
35
+ <p class="text-sm mb-3 opacity-80">theme="dark"</p>
36
+ <div class="flex flex-wrap gap-2">
37
+ <sonic-badge type="primary">Primary</sonic-badge>
38
+ <sonic-badge type="success">Success</sonic-badge>
39
+ <sonic-badge type="danger">Danger</sonic-badge>
40
+ </div>
41
+ </sonic-theme>
42
+ </div>
43
+ </template>
44
+ </sonic-code>
45
+
46
+ ## Presentation
47
+
48
+ **`color`** sets text from **`--sc-base-content`**. **`font`** applies **`--sc-font-family-base`**, **`--sc-font-weight-base`**, and **`--sc-font-style-base`**. For the page or shell background, use **`bg-base`** on **`sonic-theme`** (maps to **`--sc-base`** in Tailwind) with **`block`** so the host paints the surface. Components keep their own fallbacks when **`color`** / **`font`** are omitted.
49
+
50
+ <sonic-code>
51
+ <template>
52
+ <sonic-theme theme="light" color font class="block bg-base p-6 min-h-[8rem] rounded-lg">
53
+ <p>Body copy inherits base content color and font from the theme host.</p>
54
+ </sonic-theme>
55
+ </template>
56
+ </sonic-code>
57
+
58
+ ## Custom tokens
59
+
60
+ Override **primitives** on **`sonic-theme`** (or **`:root`** / a project stylesheet). Derived radii, shadows, and control rounding are computed from tokens such as **`--sc-rounded`**—avoid copying long lists of internal variables unless you have a specific need.
61
+
62
+ <sonic-code>
63
+ <template>
64
+ <sonic-theme
65
+ theme="custom"
66
+ color
67
+ font
68
+ class="block bg-base p-6 rounded-lg"
69
+ style="--sc-primary: #353429; --sc-rounded: 0.25rem;"
70
+ >
71
+ <sonic-button type="primary">Brand primary</sonic-button>
72
+ </sonic-theme>
73
+ </template>
74
+ </sonic-code>
75
+
76
+ ## Pop container
77
+
78
+ **`Theme.getPopContainer()`** returns the last connected **`sonic-theme`**, or **`document.body`** if none is connected. When a theme disconnects, the previous connected instance is adopted. Imperative **`Modal.create()`** and declarative **`sonic-modal`** use the same container.
79
+
80
+ <sonic-code>
81
+ <template>
82
+ <sonic-theme theme="light" color font class="block bg-base p-4 rounded-lg">
83
+ <sonic-button onclick="document.getElementById('themePopModal').show()">
84
+ Open modal
85
+ </sonic-button>
86
+ <sonic-modal id="themePopModal">
87
+ <sonic-modal-title>Mounted on theme</sonic-modal-title>
88
+ <sonic-modal-content>
89
+ This dialog is appended under the nearest sonic-theme pop container.
90
+ </sonic-modal-content>
91
+ <sonic-modal-actions>
92
+ <sonic-button hideModal>Close</sonic-button>
93
+ </sonic-modal-actions>
94
+ </sonic-modal>
95
+ </sonic-theme>
96
+ </template>
97
+ </sonic-code>
98
+
99
+ ## Embedded iframes
100
+
101
+ On connect, the theme publishes resolved **`--sc-*`** values and linked font stylesheet URLs (Google Fonts / Adobe Fonts) to the **`sonic-theme`** data channel and **`postMessage`**s them to same-page iframes. Iframes can request a refresh by posting **`{ type: "GetSonicTheme" }`**.
102
+
103
+ <sonic-code language="javascript">
104
+ <template>
105
+ // Inside the iframe — ask the parent theme to rebroadcast tokens
106
+ window.parent.postMessage({ type: "GetSonicTheme" }, "*");
107
+ </template>
108
+ </sonic-code>
109
+
110
+ ## API reference
111
+
112
+ | Attribute | Values | Description |
113
+ |----------|---------|-------------|
114
+ | `theme` | omitted · `custom` (default) · `light` · `dark` · `auto` | Omitted or `custom`: core tokens and your `--sc-*` only. `light` / `dark`: fixed presets. `auto`: presets follow `prefers-color-scheme` |
115
+ | `color` | boolean | Host text color uses `--sc-base-content` |
116
+ | `font` | boolean | Host font uses `--sc-font-family-base` and related base weight/style tokens |
117
+
118
+ | Slot | Description |
119
+ |------|-------------|
120
+ | *(default)* | Application markup and Concorde components |
121
+
122
+ Surface background: Tailwind **`bg-base`** on **`sonic-theme`** (requires Concorde Tailwind color **`base`** → **`--sc-base`**).
@@ -1,166 +1,216 @@
1
1
  # Toast
2
2
 
3
- ## Utilisation de base
3
+ Toasts surface **short-lived feedback** in a fixed stack (bottom-right in the main window). Queue messages with **`SonicToast.add()`** on the global **`SonicToast`** class—the host **`sonic-toast`** is created automatically. Prefer **`label`** for a heading; use **`preserve`** or interactive **`text`** when the user must read or act before dismiss.
4
+
5
+ ## Basic example
6
+
7
+ Click the button to show a toast.
4
8
 
5
9
  <sonic-code>
6
10
  <template>
7
- <sonic-button onclick="window.SonicToast.add({ text: 'Message de notification simple' })">
8
- Afficher un toast
11
+ <sonic-button onclick="SonicToast.add({ text: 'Simple notification' })">
12
+ Show toast
9
13
  </sonic-button>
10
14
  </template>
11
15
  </sonic-code>
12
16
 
13
- ## Statut
17
+ ## Status
14
18
 
15
- Les statuts disponibles sont : `success`, `error`, `warning`, `info` ou vide (par défaut).
19
+ **`status`** drives color, icon, and live-region behavior. Omit **`status`** or pass an empty string for a neutral toast.
16
20
 
17
21
  <sonic-code>
18
22
  <template>
19
23
  <div class="flex flex-wrap gap-2">
20
- <sonic-button onclick="window.SonicToast.add({ text: 'Message par défaut', status: '' })">
24
+ <sonic-button onclick="SonicToast.add({ text: 'Default message', status: '' })">
21
25
  Default
22
26
  </sonic-button>
23
- <sonic-button onclick="window.SonicToast.add({ text: 'Opération réussie !', status: 'success' })">
27
+ <sonic-button onclick="SonicToast.add({ text: 'Operation succeeded', status: 'success' })">
24
28
  Success
25
29
  </sonic-button>
26
- <sonic-button onclick="window.SonicToast.add({ text: 'Une erreur est survenue', status: 'error' })">
30
+ <sonic-button onclick="SonicToast.add({ text: 'Something went wrong', status: 'error' })">
27
31
  Error
28
32
  </sonic-button>
29
- <sonic-button onclick="window.SonicToast.add({ text: 'Attention à ce point', status: 'warning' })">
33
+ <sonic-button onclick="SonicToast.add({ text: 'Check this detail', status: 'warning' })">
30
34
  Warning
31
35
  </sonic-button>
32
- <sonic-button onclick="window.SonicToast.add({ text: 'Information importante', status: 'info' })">
36
+ <sonic-button onclick="SonicToast.add({ text: 'Helpful context', status: 'info' })">
33
37
  Info
34
38
  </sonic-button>
35
39
  </div>
36
40
  </template>
37
41
  </sonic-code>
38
42
 
39
- ## Avec titre
43
+ ## Label
44
+
45
+ Set **`label`** for a bold title above **`text`**. **`title`** still works but is deprecated—use **`label`** in new code.
40
46
 
41
47
  <sonic-code>
42
48
  <template>
43
49
  <div class="flex flex-wrap gap-2">
44
- <sonic-button onclick="window.SonicToast.add({ title: 'Succès', text: 'Votre demande a été traitée avec succès.', status: 'success' })">
45
- Toast avec titre
50
+ <sonic-button
51
+ onclick="SonicToast.add({ label: 'Success', text: 'Your request was processed.', status: 'success' })"
52
+ >
53
+ Toast with label
46
54
  </sonic-button>
47
- <sonic-button onclick="window.SonicToast.add({ title: 'Test', text: 'Une erreur est survenue lors du traitement.', status: 'error' })">
48
- Toast d'erreur avec titre
55
+ <sonic-button
56
+ onclick="SonicToast.add({ label: 'Error', text: 'Processing failed. Try again.', status: 'error' })"
57
+ >
58
+ Error with label
49
59
  </sonic-button>
50
60
  </div>
51
61
  </template>
52
62
  </sonic-code>
53
63
 
54
- ## Avec contenu HTML
64
+ ## HTML in text
55
65
 
56
- Le contenu du toast peut contenir du HTML.
66
+ **`text`** (and **`label`**) can include HTML strings. Links and controls in **`text`** automatically enable **`preserve`** so the toast does not auto-hide while the user interacts.
57
67
 
58
68
  <sonic-code>
59
69
  <template>
60
- <sonic-button onclick="window.SonicToast.add({ text: 'Message avec <strong>HTML</strong> et un <a href=&quot;#&quot;>lien cliquable</a>', status: 'info' })">
61
- Toast avec HTML
70
+ <sonic-button
71
+ onclick="SonicToast.add({ text: 'Message with <strong>HTML</strong> and an <a href=&quot;#&quot;>action link</a>', status: 'info' })"
72
+ >
73
+ Toast with HTML
62
74
  </sonic-button>
63
75
  </template>
64
76
  </sonic-code>
65
77
 
78
+ ## Preserve
66
79
 
67
- ## Persistance
68
-
69
- Par défaut, les toasts disparaissent automatiquement. Avec `preserve: true`, le toast reste affiché jusqu'à ce qu'il soit fermé manuellement.
80
+ Without **`preserve`**, toasts auto-hide after about six seconds (timer pauses on hover or focus). Set **`preserve`** to keep the toast until the user closes it.
70
81
 
71
82
  <sonic-code>
72
83
  <template>
73
- <sonic-button onclick="window.SonicToast.add({ text: 'Ce toast ne disparaîtra pas automatiquement', status: 'info', preserve: true })">
74
- Toast persistant
84
+ <sonic-button
85
+ onclick="SonicToast.add({ text: 'This toast stays until you dismiss it', status: 'info', preserve: true })"
86
+ >
87
+ Persistent toast
75
88
  </sonic-button>
76
89
  </template>
77
90
  </sonic-code>
78
91
 
79
- ## Masquer définitivement
92
+ ## Dismiss forever
80
93
 
81
- Avec `dismissForever: true` et un `id`, le toast peut être masqué définitivement. Une fois fermé, il ne réapparaîtra plus même après rechargement de la page.
94
+ With **`dismissForever`** and a stable **`id`**, closing the toast stores dismissal in **`localStorage`**—**`SonicToast.add`** skips it on later visits. Duplicate payloads (same fields, ignoring **`id`**) are not queued twice.
82
95
 
83
96
  <sonic-code>
84
97
  <template>
85
- <sonic-button onclick="window.SonicToast.add({ id: 'unique-toast-id', text: 'Ce toast peut être masqué définitivement', status: 'info', dismissForever: true })">
86
- Toast avec dismiss forever
98
+ <sonic-button
99
+ onclick="SonicToast.add({ id: 'unique-toast-id', text: 'Dismiss forever hides this across reloads', status: 'info', dismissForever: true })"
100
+ >
101
+ Dismiss forever
87
102
  </sonic-button>
88
103
  </template>
89
104
  </sonic-code>
90
105
 
91
- ## Fantôme
106
+ ## Ghost
92
107
 
93
- Avec `ghost: true`, le toast devient semi-transparent et non-interactif.
108
+ **`ghost`** renders a semi-transparent, non-interactive toast—useful for loading or background states. **`SonicToast.removeAll`** leaves ghost toasts in place.
94
109
 
95
110
  <sonic-code>
96
111
  <template>
97
- <sonic-button onclick="window.SonicToast.add({ text: 'Toast fantôme (semi-transparent)', status: 'info', ghost: true })">
98
- Toast ghost
112
+ <sonic-button
113
+ onclick="SonicToast.add({ text: 'Ghost toast (non-interactive)', status: 'info', ghost: true })"
114
+ >
115
+ Ghost toast
99
116
  </sonic-button>
100
117
  </template>
101
118
  </sonic-code>
102
119
 
120
+ ## Dismissal
103
121
 
104
- ## Méthodes de suppression
122
+ Use static helpers to clear the stack from app logic (for example after navigation).
105
123
 
106
- ### Tout supprimer
124
+ ### Remove all
107
125
 
108
- Supprime tous les toasts sauf ceux marqués comme `ghost`.
126
+ Removes every toast except **`ghost`** items.
109
127
 
110
128
  <sonic-code>
111
129
  <template>
112
130
  <div class="flex flex-wrap gap-2">
113
- <sonic-button onclick="window.SonicToast.add({ text: 'Toast 1', status: 'info' })">Ajouter toast 1</sonic-button>
114
- <sonic-button onclick="window.SonicToast.add({ text: 'Toast 2', status: 'success' })">Ajouter toast 2</sonic-button>
115
- <sonic-button onclick="window.SonicToast.add({ text: 'Toast 3', status: 'warning' })">Ajouter toast 3</sonic-button>
116
- <sonic-button onclick="window.SonicToast.removeAll()">Supprimer tous</sonic-button>
131
+ <sonic-button onclick="SonicToast.add({ text: 'Toast 1', status: 'info' })">Add toast 1</sonic-button>
132
+ <sonic-button onclick="SonicToast.add({ text: 'Toast 2', status: 'success' })">Add toast 2</sonic-button>
133
+ <sonic-button onclick="SonicToast.add({ text: 'Toast 3', status: 'warning' })">Add toast 3</sonic-button>
134
+ <sonic-button onclick="SonicToast.removeAll()">Remove all</sonic-button>
117
135
  </div>
118
136
  </template>
119
137
  </sonic-code>
120
138
 
121
- ### Supprimer par statut
122
-
123
- Supprime tous les toasts d'un statut spécifique.
139
+ ### Remove by status
124
140
 
125
141
  <sonic-code>
126
142
  <template>
127
143
  <div class="flex flex-wrap gap-2">
128
- <sonic-button onclick="window.SonicToast.add({ text: 'Toast success', status: 'success' })">Success</sonic-button>
129
- <sonic-button onclick="window.SonicToast.add({ text: 'Toast error', status: 'error' })">Error</sonic-button>
130
- <sonic-button onclick="window.SonicToast.add({ text: 'Toast warning', status: 'warning' })">Warning</sonic-button>
131
- <sonic-button onclick="window.SonicToast.removeItemsByStatus('success')">Supprimer success</sonic-button>
132
- <sonic-button onclick="window.SonicToast.removeItemsByStatus('error')">Supprimer error</sonic-button>
144
+ <sonic-button onclick="SonicToast.add({ text: 'Success toast', status: 'success' })">Success</sonic-button>
145
+ <sonic-button onclick="SonicToast.add({ text: 'Error toast', status: 'error' })">Error</sonic-button>
146
+ <sonic-button onclick="SonicToast.add({ text: 'Warning toast', status: 'warning' })">Warning</sonic-button>
147
+ <sonic-button onclick="SonicToast.removeItemsByStatus('success')">Remove success</sonic-button>
148
+ <sonic-button onclick="SonicToast.removeItemsByStatus('error')">Remove error</sonic-button>
133
149
  </div>
134
150
  </template>
135
151
  </sonic-code>
136
152
 
137
- ### Supprimer les éléments temporaires
153
+ ### Remove temporary items
138
154
 
139
- Supprime tous les toasts qui ne sont pas marqués comme `preserve`.
155
+ Removes toasts that are not **`preserve`**.
140
156
 
141
157
  <sonic-code>
142
158
  <template>
143
159
  <div class="flex flex-wrap gap-2">
144
- <sonic-button onclick="window.SonicToast.add({ text: 'Toast temporaire', status: 'info' })">Temporaire</sonic-button>
145
- <sonic-button onclick="window.SonicToast.add({ text: 'Toast persistant', status: 'success', preserve: true })">Persistant</sonic-button>
146
- <sonic-button onclick="window.SonicToast.removeTemporaryItems()">Supprimer temporaires</sonic-button>
160
+ <sonic-button onclick="SonicToast.add({ text: 'Temporary toast', status: 'info' })">Temporary</sonic-button>
161
+ <sonic-button onclick="SonicToast.add({ text: 'Persistent toast', status: 'success', preserve: true })">
162
+ Persistent
163
+ </sonic-button>
164
+ <sonic-button onclick="SonicToast.removeTemporaryItems()">Remove temporary</sonic-button>
147
165
  </div>
148
166
  </template>
149
167
  </sonic-code>
150
168
 
151
- ## Exemple complet
169
+ ## Combined options
152
170
 
153
171
  <sonic-code>
154
172
  <template>
155
- <sonic-button onclick="window.SonicToast.add({
173
+ <sonic-button
174
+ onclick="SonicToast.add({
156
175
  id: 'welcome-toast',
157
- title: 'Bienvenue',
158
- text: 'Bienvenue sur notre plateforme ! Vous pouvez commencer à explorer les fonctionnalités.',
176
+ label: 'Welcome',
177
+ text: 'Welcome to the platform. Explore the docs to get started.',
159
178
  status: 'success',
160
179
  dismissForever: true
161
- })">
162
- Toast complet
180
+ })"
181
+ >
182
+ Full example
163
183
  </sonic-button>
164
184
  </template>
165
185
  </sonic-code>
166
186
 
187
+ ## Accessibility
188
+
189
+ Each toast uses **`role="alert"`** for **`error`** and **`role="status"`** otherwise (with **`aria-live="polite"`** when applicable). Status icons are decorative (**`aria-hidden`**). The close control has an i18n **`aria-label`**. When there is no **`label`**, a truncated string **`aria-label`** may be derived from plain **`text`**.
190
+
191
+ ## API reference
192
+
193
+ Options passed to **`SonicToast.add(conf)`**:
194
+
195
+ | Option | Values | Description |
196
+ |----------|---------|-------------|
197
+ | `text` | string · Lit template | Main body; HTML strings are supported |
198
+ | `label` | string · Lit template | Optional heading above **`text`** |
199
+ | `title` | string · Lit template | Deprecated alias for **`label`** |
200
+ | `status` | `success` · `error` · `warning` · `info` · `` (empty) | Semantic styling and live region behavior |
201
+ | `id` | string · number | Stable id for deduplication and **`dismissForever`** (defaults to timestamp) |
202
+ | `preserve` | boolean | Skip auto-hide; forced when **`text`** contains interactive markup |
203
+ | `ghost` | boolean | Semi-transparent and non-interactive; kept by **`removeAll`** |
204
+ | `dismissForever` | boolean | Persist dismissal in **`localStorage`** when closed (requires stable **`id`**) |
205
+ | `styleSheet` | modal style input | Extra adopted styles on the toast item shadow root |
206
+ | `useSlot` | boolean | Legacy: project **`text`** into the light DOM slot |
207
+
208
+ | Method | Description |
209
+ |--------|-------------|
210
+ | `SonicToast.add(conf)` | Append a toast; returns the config or **`null`** if skipped (dismissed forever or duplicate) |
211
+ | `SonicToast.removeAll()` | Remove all non-**`ghost`** toasts |
212
+ | `SonicToast.removeItemsByStatus(status)` | Remove toasts matching **`status`** |
213
+ | `SonicToast.removeItemById(id)` | Remove a single toast by **`id`** |
214
+ | `SonicToast.removeTemporaryItems()` | Remove toasts without **`preserve`** |
215
+
216
+ **`sonic-toast`** is mounted automatically; **`sonic-toast-item`** is internal. In iframes, toasts can delegate to the parent window via **`postMessage`**.
@@ -1,71 +1,97 @@
1
1
  # Tooltip
2
2
 
3
+ Tooltip shows a short **`label`** on hover (and on focus when the trigger can receive focus). Wrap the trigger in the default slot—buttons, icons, or plain text. Default **`placement`** is **`top`** (center-aligned). An empty **`label`** hides the bubble the same way as **`disabled`**.
4
+
5
+ ## Basic example
6
+
3
7
  <sonic-code>
4
8
  <template>
5
- <sonic-tooltip label="Tada : Text appears">hover me</sonic-tooltip>
9
+ <sonic-tooltip label="Additional context on hover">
10
+ <sonic-button variant="outline">Hover me</sonic-button>
11
+ </sonic-tooltip>
6
12
  </template>
7
13
  </sonic-code>
8
14
 
9
15
  ## Placement
10
16
 
11
- By default, tooltip is centered next to its content
17
+ Use **`top`** · **`bottom`** · **`left`** · **`right`** for the main axis. Add **`-start`** or **`-end`** to align the bubble along the anchor edge.
12
18
 
13
19
  <sonic-code>
14
20
  <template>
15
- <sonic-tooltip placement="top" label="Top text">
16
- <sonic-button>Top</sonic-button>
17
- </sonic-tooltip>
18
- <sonic-tooltip placement="bottom" label="Bottom text">
19
- <sonic-button>Bottom</sonic-button>
20
- </sonic-tooltip>
21
- <sonic-tooltip placement="right" label="Right text">
22
- <sonic-button>Right</sonic-button>
23
- </sonic-tooltip>
24
- <sonic-tooltip placement="left" label="Left text">
25
- <sonic-button>Left</sonic-button>
26
- </sonic-tooltip>
21
+ <div class="flex flex-wrap gap-2">
22
+ <sonic-tooltip placement="top" label="Top">
23
+ <sonic-button>Top</sonic-button>
24
+ </sonic-tooltip>
25
+ <sonic-tooltip placement="bottom" label="Bottom">
26
+ <sonic-button>Bottom</sonic-button>
27
+ </sonic-tooltip>
28
+ <sonic-tooltip placement="right" label="Right">
29
+ <sonic-button>Right</sonic-button>
30
+ </sonic-tooltip>
31
+ <sonic-tooltip placement="left" label="Left">
32
+ <sonic-button>Left</sonic-button>
33
+ </sonic-tooltip>
34
+ </div>
27
35
  </template>
28
36
  </sonic-code>
29
37
 
30
- ## More placement
38
+ ### Aligned placements
39
+
31
40
  <sonic-code>
32
41
  <template>
33
42
  <div class="flex gap-3 flex-wrap">
34
- <sonic-tooltip placement="top-start" label="My tooltip">
43
+ <sonic-tooltip placement="top-start" label="Top start">
35
44
  <sonic-button class="size-40 bg-neutral-200 rounded-lg">Top start</sonic-button>
36
45
  </sonic-tooltip>
37
- <sonic-tooltip placement="top-end" label="My tooltip">
46
+ <sonic-tooltip placement="top-end" label="Top end">
38
47
  <sonic-button class="size-40 bg-neutral-200 rounded-lg">Top end</sonic-button>
39
48
  </sonic-tooltip>
40
- <sonic-tooltip placement="bottom-start" label="My tooltip">
49
+ <sonic-tooltip placement="bottom-start" label="Bottom start">
41
50
  <sonic-button class="size-40 bg-neutral-200 rounded-lg">Bottom start</sonic-button>
42
51
  </sonic-tooltip>
43
- <sonic-tooltip placement="bottom-end" label="My tooltip">
52
+ <sonic-tooltip placement="bottom-end" label="Bottom end">
44
53
  <sonic-button class="size-40 bg-neutral-200 rounded-lg">Bottom end</sonic-button>
45
54
  </sonic-tooltip>
46
- <sonic-tooltip placement="right-start" label="My tooltip">
55
+ <sonic-tooltip placement="right-start" label="Right start">
47
56
  <sonic-button class="size-40 bg-neutral-200 rounded-lg">Right start</sonic-button>
48
57
  </sonic-tooltip>
49
- <sonic-tooltip placement="right-end" label="My tooltip">
58
+ <sonic-tooltip placement="right-end" label="Right end">
50
59
  <sonic-button class="size-40 bg-neutral-200 rounded-lg">Right end</sonic-button>
51
60
  </sonic-tooltip>
52
- <sonic-tooltip placement="left-start" label="My tooltip">
61
+ <sonic-tooltip placement="left-start" label="Left start">
53
62
  <sonic-button class="size-40 bg-neutral-200 rounded-lg">Left start</sonic-button>
54
63
  </sonic-tooltip>
55
- <sonic-tooltip placement="left-end" label="My tooltip">
64
+ <sonic-tooltip placement="left-end" label="Left end">
56
65
  <sonic-button class="size-40 bg-neutral-200 rounded-lg">Left end</sonic-button>
57
66
  </sonic-tooltip>
58
67
  </div>
59
68
  </template>
60
69
  </sonic-code>
61
70
 
71
+ ## Label formatting
72
+
73
+ **`label`** supports line breaks (`\n` in markup or multiline text). Lines are trimmed; **`&nbsp;`** is normalized to spaces. **`white-space: pre-line`** preserves breaks in the bubble (max width **18rem**).
74
+
75
+ <sonic-code>
76
+ <template>
77
+ <sonic-tooltip label="First line&#10;Second line">
78
+ <sonic-button variant="outline">Multiline label</sonic-button>
79
+ </sonic-tooltip>
80
+ </template>
81
+ </sonic-code>
62
82
 
63
83
  ## Focusable
64
84
 
85
+ On non-interactive triggers, set **`focusable`** so the host gets **`tabindex="0"`** and the tooltip opens on keyboard focus as well as hover.
86
+
65
87
  <sonic-code>
66
88
  <template>
67
- <sonic-tooltip focusable label="The Concorde made its first transatlantic crossing on September 26, 1973">
68
- <sonic-icon library="iconoir" name="chat-bubble-question"></sonic-icon> Focus or hover non interactive element
89
+ <sonic-tooltip
90
+ focusable
91
+ label="The Concorde made its first transatlantic crossing on September 26, 1973"
92
+ >
93
+ <sonic-icon library="iconoir" name="chat-bubble-question"></sonic-icon>
94
+ Focus or hover this text
69
95
  </sonic-tooltip>
70
96
  </template>
71
97
  </sonic-code>
@@ -74,9 +100,25 @@ By default, tooltip is centered next to its content
74
100
 
75
101
  <sonic-code>
76
102
  <template>
77
- <sonic-tooltip disabled label="Disabled text">
103
+ <sonic-tooltip disabled label="Not shown">
78
104
  <sonic-button>Tooltip disabled</sonic-button>
79
105
  </sonic-tooltip>
80
106
  </template>
81
107
  </sonic-code>
82
108
 
109
+ ## Accessibility
110
+
111
+ The bubble uses **`popover="hint"`** (non-modal, no pointer capture). Prefer **`focusable`** when the slotted content is not already focusable. When the Popover API is unavailable, the host falls back to the native **`title`** attribute with a single-line label. Opacity transitions respect **`prefers-reduced-motion`**.
112
+
113
+ ## API reference
114
+
115
+ | Attribute | Values | Description |
116
+ |----------|---------|-------------|
117
+ | `label` | string | Tooltip copy; whitespace-only values suppress the bubble |
118
+ | `placement` | `top` (default) · `bottom` · `left` · `right` · `top-start` · `top-end` · `bottom-start` · `bottom-end` · `left-start` · `left-end` · `right-start` · `right-end` | Position relative to the trigger; repositions while open |
119
+ | `disabled` | boolean | Suppress show/hide; sets **`tabindex="-1"`** on the host |
120
+ | `focusable` | boolean | Add **`tabindex="0"`** on the host for keyboard access |
121
+
122
+ | Slot | Description |
123
+ |------|-------------|
124
+ | *(default)* | Trigger content (hover target) |
File without changes
@@ -69,8 +69,9 @@ This decorator is particularly useful for:
69
69
  - By default (`dynamic: false`), the value is read once at connect time and is not updated afterward
70
70
  - With `{ dynamic: true }`, the property stays in sync when:
71
71
  - an ancestor **changes** the attribute value
72
- - a **closer** ancestor **gains** the attribute (that value wins)
73
- - the **nearest** ancestor **loses** the attribute (falls back to the next one up, or `null`)
72
+ - a **closer** ancestor **gains** / **loses** the attribute (fallback / `null`)
73
+ - the component is **reparented** (no extra opt-in) — parent `childList` only reacts if *this* node moves
74
+ - Observers are **shared** (one per ancestor attribute / one per parent) so large lists of `sonic-icon` stay cheap on Firefox.
74
75
  - When `dynamic` is enabled, updates also propagate to `@subscribe` / `@bind` paths that depend on the decorated property (e.g. `${dataProvider}`)
75
76
 
76
77
  ### Dynamic mode
@@ -1,8 +1,8 @@
1
1
  # Installation
2
2
 
3
- <sonic-alert status="success" label="Recommended — use the starter" size="xl" background>
4
- <p><strong>For almost all new projects, use <a href="https://www.npmjs.com/package/@supersoniks/create-concorde-ts-starter">create-concorde-ts-starter</a>.</strong></p>
5
- <p>You get Vite + TypeScript + Lit + Tailwind, an example component, <code>npx concorde enable-short-paths</code> ready to run, and <code>yarn ai:sync</code> for <a href="#docs/_getting-started/ai-agents.md/ai-agents">AI agent skills</a> (<code>AGENTS.md</code>, Cursor / JetBrains rules) without extra setup.</p>
3
+ <sonic-alert status="info" label="Recommended — use the starter" background>
4
+ <p>For almost all new projects, use <a href="https://www.npmjs.com/package/@supersoniks/create-concorde-ts-starter">create-concorde-ts-starter</a></p>
5
+ <p>You get Vite + TypeScript + Lit + Tailwind, an example component, <code>npx concorde enable-short-paths</code> ready to run, and <code>yarn ai:sync</code> for <a href="#docs/_getting-started/ai-agents.md/ai-agents">AI agent skills</a> (<code>AGENTS.md</code>, Cursor / JetBrains rules) without extra setup.</p>
6
6
  </sonic-alert>
7
7
 
8
8
  ## Starter
File without changes
@@ -3,7 +3,7 @@
3
3
  ## What is Concorde?
4
4
 
5
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.
6
+ Build UIs without tying components to a specific host stack, while keeping visual consistency through the smallest set of CSS variables needed to define a theme.
7
7
 
8
8
  ## Why and use case
9
9