@supersoniks/concorde 5.0.4 → 5.1.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 (123) 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/.tmp-cem/custom-elements.json +13705 -0
  4. package/ai/cursor/rules/concorde-theme.mdc +1 -1
  5. package/ai/cursor/rules/concorde.mdc +1 -1
  6. package/ai/skills/concorde/SKILL.md +1 -1
  7. package/ai/skills/concorde-theme/SKILL.md +21 -10
  8. package/build-infos.json +1 -1
  9. package/concorde-3d.bundle.js +3960 -0
  10. package/concorde-3d.es.js +33433 -0
  11. package/concorde-core.bundle.js +507 -513
  12. package/concorde-core.es.js +4027 -3702
  13. package/concorde-hugging-face-infer.bundle.js +32 -0
  14. package/concorde-hugging-face-infer.es.js +2952 -0
  15. package/concorde-interactive.bundle.js +1157 -0
  16. package/concorde-interactive.es.js +10734 -0
  17. package/concorde-shader.bundle.js +116 -0
  18. package/concorde-shader.es.js +8353 -0
  19. package/concorde-webgpu.bundle.js +307 -0
  20. package/concorde-webgpu.es.js +8627 -0
  21. package/custom-elements-manifest.config.mjs +14 -0
  22. package/dist/concorde-core.bundle.js +507 -513
  23. package/dist/concorde-core.es.js +4027 -3702
  24. package/dist/docs-mock-api-sw.js +2 -0
  25. package/dist/docs-mock-api-sw.js.map +2 -2
  26. package/gitlab/job_tests.sh +0 -0
  27. package/index.html +4 -2
  28. package/package.json +42 -2
  29. package/public/docs-mock-api-sw.js +2 -0
  30. package/public/docs-mock-api-sw.js.map +2 -2
  31. package/scripts/generate-sdui-catalog.mjs +250 -0
  32. package/scripts/generate-sdui-catalog.spec.ts +91 -0
  33. package/scripts/pre-build.mjs +15 -0
  34. package/src/core/components/functional/if/if.ts +0 -0
  35. package/src/core/components/functional/sdui/SDUIDescriptorTransformer.ts +5 -5
  36. package/src/core/components/functional/sdui/__fixtures__/descriptors.ts +251 -0
  37. package/src/core/components/functional/sdui/__snapshots__/sdui-action.spec.ts.snap +73 -0
  38. package/src/core/components/functional/sdui/__snapshots__/sdui-incremental.spec.ts.snap +50 -0
  39. package/src/core/components/functional/sdui/__snapshots__/sdui-partial.spec.ts.snap +50 -0
  40. package/src/core/components/functional/sdui/__snapshots__/sdui.regression.spec.ts.snap +461 -0
  41. package/src/core/components/functional/sdui/component-catalog.gaps.json +511 -0
  42. package/src/core/components/functional/sdui/component-catalog.json +3103 -0
  43. package/src/core/components/functional/sdui/component-catalog.spec.ts +23 -0
  44. package/src/core/components/functional/sdui/sdui-action.spec.ts +99 -0
  45. package/src/core/components/functional/sdui/sdui-dom-snapshot.ts +61 -0
  46. package/src/core/components/functional/sdui/sdui-extension-points.md +94 -0
  47. package/src/core/components/functional/sdui/sdui-incremental.spec.ts +137 -0
  48. package/src/core/components/functional/sdui/sdui-partial.spec.ts +83 -0
  49. package/src/core/components/functional/sdui/sdui-partial.ts +19 -0
  50. package/src/core/components/functional/sdui/sdui-safe.spec.ts +188 -0
  51. package/src/core/components/functional/sdui/sdui-safe.ts +100 -0
  52. package/src/core/components/functional/sdui/sdui.md +122 -0
  53. package/src/core/components/functional/sdui/sdui.regression.spec.ts +64 -0
  54. package/src/core/components/functional/sdui/sdui.ts +442 -34
  55. package/src/core/components/functional/sdui/types.ts +49 -0
  56. package/src/core/components/functional/value/value.ts +0 -0
  57. package/src/core/components/ui/_css/align.ts +1 -0
  58. package/src/core/components/ui/_css/type.ts +86 -8
  59. package/src/core/components/ui/_i18n/ui-aria-labels.ts +8 -0
  60. package/src/core/components/ui/alert/alert.md +21 -2
  61. package/src/core/components/ui/alert-messages/alert-messages.md +85 -0
  62. package/src/core/components/ui/badge/badge.md +19 -6
  63. package/src/core/components/ui/badge/badge.ts +8 -9
  64. package/src/core/components/ui/button/button.ts +5 -15
  65. package/src/core/components/ui/captcha/captcha.md +65 -6
  66. package/src/core/components/ui/card/card.md +73 -10
  67. package/src/core/components/ui/card/card.ts +24 -22
  68. package/src/core/components/ui/divider/divider.md +107 -13
  69. package/src/core/components/ui/divider/divider.ts +40 -33
  70. package/src/core/components/ui/form/fieldset/fieldset.md +175 -99
  71. package/src/core/components/ui/form/fieldset/fieldset.ts +15 -28
  72. package/src/core/components/ui/form/fieldset/legend.ts +13 -13
  73. package/src/core/components/ui/form/form-actions/form-actions.md +75 -52
  74. package/src/core/components/ui/form/form-actions/form-actions.ts +7 -5
  75. package/src/core/components/ui/form/form-layout/form-layout.md +109 -34
  76. package/src/core/components/ui/form/form-layout/form-layout.ts +27 -24
  77. package/src/core/components/ui/form/textarea/textarea.ts +4 -3
  78. package/src/core/components/ui/group/group.md +36 -36
  79. package/src/core/components/ui/group/group.ts +5 -10
  80. package/src/core/components/ui/icon/icon.md +132 -43
  81. package/src/core/components/ui/image/image.md +35 -3
  82. package/src/core/components/ui/link/link.md +43 -5
  83. package/src/core/components/ui/loader/loader.md +79 -22
  84. package/src/core/components/ui/loader/loader.ts +67 -27
  85. package/src/core/components/ui/loader/styles/fixed.ts +6 -11
  86. package/src/core/components/ui/menu/menu.md +133 -92
  87. package/src/core/components/ui/menu/menu.ts +53 -58
  88. package/src/core/components/ui/modal/modal.md +163 -47
  89. package/src/core/components/ui/modal/modal.ts +2 -4
  90. package/src/core/components/ui/pop/pop.md +217 -123
  91. package/src/core/components/ui/pop/pop.ts +0 -1
  92. package/src/core/components/ui/progress/progress.md +76 -30
  93. package/src/core/components/ui/progress/progress.ts +25 -56
  94. package/src/core/components/ui/table/table-caption.ts +2 -2
  95. package/src/core/components/ui/table/table-tbody.ts +3 -3
  96. package/src/core/components/ui/table/table-td.ts +23 -18
  97. package/src/core/components/ui/table/table-th.ts +8 -8
  98. package/src/core/components/ui/table/table-tr.ts +4 -4
  99. package/src/core/components/ui/table/table.md +147 -171
  100. package/src/core/components/ui/table/table.ts +20 -19
  101. package/src/core/components/ui/theme/theme-collection/auto.ts +15 -0
  102. package/src/core/components/ui/theme/theme-collection/core-variables.ts +8 -31
  103. package/src/core/components/ui/theme/theme-collection/dark.ts +1 -7
  104. package/src/core/components/ui/theme/theme-collection/light.ts +30 -26
  105. package/src/core/components/ui/theme/theme.md +122 -0
  106. package/src/core/components/ui/theme/theme.ts +30 -7
  107. package/src/core/components/ui/toast/toast-item.ts +6 -9
  108. package/src/core/components/ui/toast/toast.md +108 -58
  109. package/src/core/components/ui/toast/types.ts +1 -1
  110. package/src/core/components/ui/tooltip/tooltip.md +68 -26
  111. package/src/docs/_getting-started/start.md +1 -1
  112. package/src/docs/_getting-started/theming.md +223 -61
  113. package/src/docs/code.ts +125 -58
  114. package/src/docs/header/header.ts +62 -54
  115. package/src/docs/mock-api/router.ts +2 -0
  116. package/src/docs/navigation/navigation.ts +6 -3
  117. package/src/docs/search/docs-search.json +2504 -399
  118. package/src/docs/search/markdown-renderer.ts +6 -6
  119. package/src/docs/search/search.ts +4 -4
  120. package/src/docs/tailwind/css/tailwind.css +6 -5
  121. package/src/tsconfig.json +108 -0
  122. package/src/tsconfig.tsbuildinfo +1 -1
  123. package/tailwind.config.js +19 -0
@@ -25,6 +25,22 @@ export function statusAriaLive(status?: StatusIconKey): "polite" | null {
25
25
  return status === "error" ? null : "polite";
26
26
  }
27
27
 
28
+ /** Types sémantiques partagés (badge, progress, …). */
29
+ export const defaultTypes = [
30
+ "default",
31
+ "primary",
32
+ "warning",
33
+ "danger",
34
+ "success",
35
+ "info",
36
+ "neutral",
37
+ ] as const;
38
+
39
+ export type DefaultType = (typeof defaultTypes)[number];
40
+
41
+ /** `sonic-card` `type` — `DefaultType` plus surface variants (`typesBg`). */
42
+ export type CardType = DefaultType | "base" | "light" | "invert";
43
+
28
44
  export const statusColor = css`
29
45
  :host {
30
46
  --sc-_color: var(--sc-base-content, #000);
@@ -51,7 +67,7 @@ export const statusColor = css`
51
67
 
52
68
  export const typeColor = css`
53
69
  :host {
54
- --sc-_color: inherit;
70
+ --sc-_color: var(--sc-base-content, #000);
55
71
  color: var(--sc-_color);
56
72
  }
57
73
 
@@ -70,21 +86,88 @@ export const typeColor = css`
70
86
  :host([type="success"]) {
71
87
  --sc-_color: var(--sc-success, var(--sc-base-content, #000));
72
88
  }
89
+ :host([type="neutral"]) {
90
+ --sc-_color: var(--sc-base-content, #000);
91
+ }
73
92
 
74
93
  .inherit-color {
75
94
  color: var(--sc-_color);
76
95
  }
77
96
  `;
78
97
 
98
+ export const typeColorInvert = css`
99
+ :host([type="default"][invert]) {
100
+ --sc-_color: var(--sc-base, #fff);
101
+ --sc-_bg: color-mix(
102
+ in srgb,
103
+ var(--sc-base-content, #000) 8%,
104
+ var(--sc-base, #fff)
105
+ );
106
+ }
107
+ :host([type="primary"][invert]) {
108
+ --sc-_color: var(--sc-primary-content, var(--sc-base, #fff));
109
+ --sc-_bg: color-mix(
110
+ in srgb,
111
+ var(--sc-primary, var(--sc-base-content, #000)) 85%,
112
+ var(--sc-primary-content, #fff)
113
+ );
114
+ }
115
+ :host([type="warning"][invert]) {
116
+ --sc-_color: var(--sc-warning-content, var(--sc-base, #fff));
117
+ --sc-_bg: color-mix(
118
+ in srgb,
119
+ var(--sc-warning, var(--sc-base-content, #000)) 85%,
120
+ var(--sc-warning-content, #fff)
121
+ );
122
+ }
123
+ :host([type="danger"][invert]) {
124
+ --sc-_color: var(--sc-danger-content, var(--sc-base, #fff));
125
+ --sc-_bg: color-mix(
126
+ in srgb,
127
+ var(--sc-danger, var(--sc-base-content, #000)) 85%,
128
+ var(--sc-danger-content, #fff)
129
+ );
130
+ }
131
+ :host([type="info"][invert]) {
132
+ --sc-_color: var(--sc-info-content, var(--sc-base, #fff));
133
+ --sc-_bg: color-mix(
134
+ in srgb,
135
+ var(--sc-info, var(--sc-base-content, #000)) 85%,
136
+ var(--sc-info-content, #fff)
137
+ );
138
+ }
139
+ :host([type="success"][invert]) {
140
+ --sc-_color: var(--sc-success-content, var(--sc-base, #fff));
141
+ --sc-_bg: color-mix(
142
+ in srgb,
143
+ var(--sc-success, var(--sc-base-content, #000)) 85%,
144
+ var(--sc-success-content, #fff)
145
+ );
146
+ }
147
+ :host([type="neutral"][invert]) {
148
+ --sc-_color: var(--sc-base, #fff);
149
+ --sc-_bg: color-mix(
150
+ in srgb,
151
+ var(--sc-base, #fff) 80%,
152
+ var(--sc-base-content, #000)
153
+ );
154
+ }
155
+ `;
156
+
79
157
  export const typesBg = css`
80
158
  :host {
81
- --sc-_color: inherit;
82
- --sc-_bg: inherit;
159
+ --sc-_bg: var(--sc-base-100, rgba(0, 0, 0, 0.07));
160
+ --sc-_color: var(--sc-base-content, #000);
83
161
  color: var(--sc-_color);
84
162
  background: var(--sc-_bg);
85
163
  }
86
164
 
87
165
  /*TYPES*/
166
+ :host([type="default"]),
167
+ :host([type="light"]) {
168
+ --sc-_bg: var(--sc-base-100, rgba(0, 0, 0, 0.07));
169
+ --sc-_color: var(--sc-base-content, #000);
170
+ }
88
171
  :host([type="primary"]) {
89
172
  --sc-_bg: var(--sc-primary, var(--sc-base-content, #000));
90
173
  --sc-_color: var(--sc-primary-content, var(--sc-base, #fff));
@@ -120,11 +203,6 @@ export const typesBg = css`
120
203
  --sc-_bg: var(--sc-base, #fff);
121
204
  --sc-_color: var(--sc-base-content, #000);
122
205
  }
123
- :host([type="default"]),
124
- :host([type="light"]) {
125
- --sc-_bg: var(--sc-base-100, rgba(0, 0, 0, 0.07));
126
- --sc-_color: var(--sc-base-content, #000);
127
- }
128
206
 
129
207
  :host([type="neutral"]) {
130
208
  --sc-_bg: var(--sc-base-content, #000);
@@ -89,6 +89,14 @@ export const uiAriaLabels = {
89
89
  es: "Cerrar información",
90
90
  it: "Chiudi informazione",
91
91
  },
92
+ loading: {
93
+ en: "Loading",
94
+ fr: "Chargement en cours",
95
+ de: "Wird geladen",
96
+ nl: "Laden",
97
+ es: "Cargando",
98
+ it: "Caricamento in corso",
99
+ },
92
100
  } as const satisfies Record<string, UiLabelDict>;
93
101
 
94
102
  const toastCloseByStatus: Record<string, UiLabelDict> = {
@@ -1,8 +1,8 @@
1
1
  # Alert
2
2
 
3
- Inline message in the page: title (`label`), body (`text` or default slot), icon from `status`. For HTML or actions, use the slot instead of `label` / `text` (plain text only).
3
+ Alerts **surface important feedback** inline—errors, confirmations, or contextual help. Use **`label`** / **`text`** for simple copy, or the **default slot** for rich content (links, buttons). Set **`announce`** when the message appears after an action so screen readers pick it up.
4
4
 
5
- Use **`status`**: `default`, `info`, `success`, `warning`, `error`.
5
+ ## Basic example
6
6
 
7
7
  <sonic-code>
8
8
  <template>
@@ -175,3 +175,22 @@ With **`dismissForever`**, dismissal is stored in `localStorage` (key `sonic-ale
175
175
  </sonic-alert>
176
176
  </template>
177
177
  </sonic-code>
178
+
179
+ ## API reference
180
+
181
+ | Attribute | Values | Description |
182
+ |----------|---------|-------------|
183
+ | `status` | `default` · `info` · `success` · `warning` · `error` | Color and default icon |
184
+ | `label` | string | Title (plain text) |
185
+ | `text` | string | Short body (plain text), rendered before the slot |
186
+ | `size` | `2xs` … `2xl` | Corner radius and typography |
187
+ | `background` | boolean | Tinted background (`color-mix` on status color) |
188
+ | `dismissible` | boolean | Close control; removes the element from the DOM |
189
+ | `dismissForever` | boolean | Persists dismissal in `localStorage`; requires **`id`** |
190
+ | `noIcon` | boolean | Hides the icon (including custom `icon` slot content) |
191
+ | `announce` | boolean | `role="alert"` / `aria-live` for dynamically injected content |
192
+
193
+ | Slot | Description |
194
+ |------|-------------|
195
+ | *(default)* | Message body (HTML, actions); rendered after `text` |
196
+ | `icon` | Replaces the default `sonic-icon` |
@@ -0,0 +1,85 @@
1
+ # Alert messages
2
+
3
+ **`sonic-alert-messages`** renders a vertical stack of **`sonic-alert`** items from a **`messages`** array on a linked **data provider** (typical pattern: **`submitResultDataProvider`** after a form submit). Only entries with **`type="public"`** are shown. Each alert gets **`announce`** so screen readers pick up feedback after the request.
4
+
5
+ ## With submit result
6
+
7
+ Bind **`dataProvider`** to the same publisher as **`submitResultDataProvider`**. API **`messages`** entries need **`type`**: **`public`**, plus **`content`** and optional **`status`** (`warning` · `success` · `error` · `info`).
8
+
9
+ <sonic-code>
10
+ <template>
11
+ <sonic-scope
12
+ serviceURL="/docs-mock-api"
13
+ formDataProvider="submit-example"
14
+ submitResultDataProvider="submit-example-result"
15
+ >
16
+ <sonic-alert-messages dataProvider="submit-example-result" background class="mb-4"></sonic-alert-messages>
17
+ <div class="grid gap-4 max-w-md">
18
+ <sonic-input name="email" type="email" label="Email" value=""></sonic-input>
19
+ <sonic-input name="password" type="password" label="Password" value=""></sonic-input>
20
+ <sonic-submit endPoint="api/register" onClick>
21
+ <sonic-button type="primary">Submit (empty fields → error messages)</sonic-button>
22
+ </sonic-submit>
23
+ </div>
24
+ </sonic-scope>
25
+ </template>
26
+ </sonic-code>
27
+
28
+ ## Shared alert props
29
+
30
+ **`size`** · **`background`** and **`noIcon`** apply to every rendered **`sonic-alert`** in the list.
31
+
32
+ <sonic-code>
33
+ <template>
34
+ <sonic-button
35
+ size="sm"
36
+ variant="outline"
37
+ class="mb-3"
38
+ onclick="SonicPublisherManager.get('submit-example-result').set({ messages: [{ type: 'public', content: 'Compact inline feedback without icons.', status: 'info' }] })"
39
+ >
40
+ Load sample messages
41
+ </sonic-button>
42
+ <sonic-alert-messages
43
+ dataProvider="submit-example-result"
44
+ size="sm"
45
+ background
46
+ noIcon
47
+ ></sonic-alert-messages>
48
+ </template>
49
+ </sonic-code>
50
+
51
+ ## Message shape
52
+
53
+ Example JSON on the result publisher (or API response merged into it):
54
+
55
+ <sonic-code language="typescript">
56
+ <template>
57
+ {
58
+ "messages": [
59
+ {
60
+ "type": "public",
61
+ "content": "The product has been added to your cart",
62
+ "status": "success"
63
+ }
64
+ ]
65
+ }
66
+ </template>
67
+ </sonic-code>
68
+
69
+ ## API reference
70
+
71
+ | Attribute | Values | Description |
72
+ |----------|---------|-------------|
73
+ | `dataProvider` | publisher id | Source object; **`messages`** array is auto-filled via **Subscriber** |
74
+ | `size` | `2xs` … `2xl` (default `md`) | Passed to each **`sonic-alert`** |
75
+ | `background` | boolean | Tinted background on each alert |
76
+ | `noIcon` | boolean | Hides icons on each alert |
77
+ | `messages` | `Message[]` | Usually set by the publisher; each item uses **`content`** as alert **`text`** |
78
+
79
+ | Message field | Values | Description |
80
+ |---------------|---------|-------------|
81
+ | `type` | `public` | Required for the message to render |
82
+ | `content` | string | Alert body (**`text`** on **`sonic-alert`**) |
83
+ | `status` | `warning` · `success` · `error` · `info` | Alert **`status`**; defaults to **`default`** when omitted |
84
+
85
+ No slots — alerts are generated from **`messages`**.
@@ -1,8 +1,6 @@
1
1
  # Badge
2
2
 
3
- A **non-interactive** pill for labels, counts, or highlights (counter, status, category). The API mirrors `sonic-button` (`type`, `variant`, `size`) without focus or click states.
4
-
5
- Colors come from theme tokens (`--sc-primary`, `--sc-danger`, …) or the semantic `type` values below.
3
+ Badges are **compact, non-interactive** labels for status, counts, or categories. They mirror **`sonic-button`** styling (`type`, `variant`, `size`) without focus rings or click handling—use a button when the control should be actionable.
6
4
 
7
5
  ## Type
8
6
 
@@ -24,9 +22,9 @@ Colors come from theme tokens (`--sc-primary`, `--sc-danger`, …) or the semant
24
22
 
25
23
  ## Variant
26
24
 
27
- `outline` — border and text in the `type` color. `ghost` — text only, no padding (except in forced-colors mode).
25
+ Default **`variant`** is filled. **`outline`** — border and text in the `type` color. **`ghost`** — text only, no padding (except in forced-colors mode).
28
26
 
29
- ## Outline
27
+ ### Outline
30
28
 
31
29
  <sonic-code>
32
30
  <template>
@@ -42,7 +40,7 @@ Colors come from theme tokens (`--sc-primary`, `--sc-danger`, …) or the semant
42
40
  </template>
43
41
  </sonic-code>
44
42
 
45
- ## Ghost
43
+ ### Ghost
46
44
 
47
45
  <sonic-code>
48
46
  <template>
@@ -173,3 +171,18 @@ Count inside a button (`slot="suffix"`) or a badge absolutely positioned on a bu
173
171
  </div>
174
172
  </template>
175
173
  </sonic-code>
174
+
175
+ ## API reference
176
+
177
+ | Attribute | Values | Description |
178
+ |----------|---------|-------------|
179
+ | `type` | `default` (default) · `primary` · `neutral` · `warning` · `info` · `success` · `danger` | Semantic color (`--sc-*` tokens) |
180
+ | `variant` | `default` (default) · `outline` · `ghost` | Filled, bordered, or text-only |
181
+ | `size` | `2xs` … `2xl` (default `md`) | Typography and padding (aligned with **`sonic-button`**) |
182
+ | `ellipsis` | boolean | Single-line truncation; parent must constrain width |
183
+
184
+ | Slot | Description |
185
+ |------|-------------|
186
+ | *(default)* | Main label |
187
+ | `prefix` | Icon or short text before the label |
188
+ | `suffix` | Icon or short text after the label |
@@ -4,7 +4,11 @@ import {
4
4
  fontSize,
5
5
  Size,
6
6
  } from "@supersoniks/concorde/core/components/ui/_css/size";
7
- import { typesBg } from "@supersoniks/concorde/core/components/ui/_css/type";
7
+ import {
8
+ typesBg,
9
+ DefaultType,
10
+ typeColorInvert,
11
+ } from "@supersoniks/concorde/core/components/ui/_css/type";
8
12
 
9
13
  const tagName = "sonic-badge";
10
14
  /**
@@ -17,6 +21,7 @@ export class Badge extends LitElement {
17
21
  static styles = [
18
22
  fontSize,
19
23
  typesBg,
24
+ typeColorInvert,
20
25
  css`
21
26
  :host {
22
27
  --sc-_gap: 0.3em;
@@ -111,14 +116,8 @@ export class Badge extends LitElement {
111
116
  * Le type change surtout la couleur composant
112
117
  */
113
118
  @property({ type: String, reflect: true })
114
- type:
115
- | "default"
116
- | "primary"
117
- | "warning"
118
- | "danger"
119
- | "success"
120
- | "info"
121
- | "neutral" = "default";
119
+ type: DefaultType = "default";
120
+
122
121
  /**
123
122
  * Le composant par defaut sans se paramètre à forte afordance
124
123
  * * ghost : composant super léger visuellement
@@ -18,6 +18,7 @@ import {
18
18
  } from "@supersoniks/concorde/core/components/ui/_css/size";
19
19
  import { PublisherManager } from "@supersoniks/concorde/utils";
20
20
  import { Route } from "@supersoniks/concorde/core/utils/route";
21
+ import { Align } from "../_css/align";
21
22
 
22
23
  export type ButtonType =
23
24
  | "default"
@@ -458,10 +459,7 @@ export class Button extends FormCheckable(FormElement(LitElement)) {
458
459
  /**
459
460
  * Propriété text-align du bouton
460
461
  */
461
- @property({ type: String, reflect: true }) align?:
462
- | "right"
463
- | "left"
464
- | "center";
462
+ @property({ type: String, reflect: true }) align?: Align;
465
463
 
466
464
  /**
467
465
  * Propriété min-width du bouton
@@ -647,17 +645,9 @@ export class Button extends FormCheckable(FormElement(LitElement)) {
647
645
  @click=${this.handleChange}
648
646
  @pointerdown=${this.handleRepeatStart}
649
647
  >
650
- <slot
651
- @slotchange=${this.onSlotChange}
652
- part="prefix"
653
- name="prefix"
654
- ></slot>
655
- <slot part="main" class="main-slot"></slot>
656
- <slot
657
- @slotchange=${this.onSlotChange}
658
- part="suffix"
659
- name="suffix"
660
- ></slot>
648
+ <slot @slotchange=${this.onSlotChange} name="prefix"></slot>
649
+ <slot class="main-slot"></slot>
650
+ <slot @slotchange=${this.onSlotChange} name="suffix"></slot>
661
651
  ${this.loading == true
662
652
  ? html`<sonic-icon name="loader" class="loader"></sonic-icon>`
663
653
  : ""}
@@ -1,12 +1,71 @@
1
1
  # Captcha
2
2
 
3
+ **`sonic-captcha`** embeds an **ALTCHA** widget and wires **`captchaToken`** / **`needsCaptchaValidation`** on the ancestor **`formDataProvider`** (or **`headersDataProvider`**). **`sonic-submit`** waits for a token before sending when validation is required. The widget loads only on **HTTPS**; on plain HTTP the host renders nothing.
4
+
5
+ > Live widget calls the Supersoniks challenge service — not part of [docs mock API](#docs/_misc/docs-mock-api.md/docs-mock-api).
6
+
7
+ ## Basic example
8
+
9
+ Wrap the form scope and place **`sonic-submit`** in the default slot so the challenge appears above the action.
10
+
11
+ <sonic-code>
12
+ <template>
13
+ <sonic-scope
14
+ serviceURL="/docs-mock-api"
15
+ formDataProvider="captcha-docs-form"
16
+ submitResultDataProvider="captcha-docs-result"
17
+ >
18
+ <sonic-captcha formDataProvider="captcha-docs-form">
19
+ <sonic-input class="mb-3" name="email" type="email" label="Email" value="demo@example.com"></sonic-input>
20
+ <sonic-submit endPoint="api/register" onClick>
21
+ <sonic-button type="primary">Submit with captcha</sonic-button>
22
+ </sonic-submit>
23
+ </sonic-captcha>
24
+ </sonic-scope>
25
+ </template>
26
+ </sonic-code>
27
+
28
+ ## Encrypted site key
29
+
30
+ Optional **`key`** skips client-side key generation. When omitted, the component derives an encrypted key on connect (after **`generateEncryptedKey`**).
31
+
3
32
  <sonic-code>
4
33
  <template>
5
- <sonic-captcha formDataProvider="captchaTestDataProvider" key="6Leq5V0iAAAAAB-41DlWN335jDlcIuXmhNtdd00t">
6
- <sonic-submit serviceURL="/docs-mock-api" endPoint="api/unknown" onclick>
7
- <sonic-button class="mt-4">Submit with captcha</sonic-button>
8
- </sonic-submit>
9
- </sonic-captcha>
34
+ <sonic-captcha formDataProvider="captcha-docs-form" key="6Leq5V0iAAAAAB-41DlWN335jDlcIuXmhNtdd00t">
35
+ <sonic-button type="outline" disabled>Complete the challenge above to enable submit</sonic-button>
36
+ </sonic-captcha>
10
37
  </template>
11
38
  </sonic-code>
12
-
39
+
40
+ ## Form publisher fields
41
+
42
+ On connect (HTTPS only), **`needsCaptchaValidation`** is set to **`true`** and **`captchaToken`** is cleared. When the ALTCHA widget reaches **`verified`**, **`captchaToken`** is written on the form publisher and **`sonic-captcha-validate`** fires (`detail.valid` · **`detail.state`** · optional **`detail.token`** / **`detail.payload`**). **`sonic-submit`** still listens for **`request_token`** to refresh the token immediately before send.
43
+
44
+ <sonic-code language="typescript">
45
+ <template>
46
+ {
47
+ needsCaptchaValidation: true,
48
+ captchaKey: "…",
49
+ captchaToken: "…"
50
+ }
51
+ </template>
52
+ </sonic-code>
53
+
54
+ ## API reference
55
+
56
+ | Attribute | Values | Description |
57
+ |----------|---------|-------------|
58
+ | `formDataProvider` | publisher id | Same as ancestor form scope; reads/writes **`needsCaptchaValidation`** · **`captchaKey`** · **`captchaToken`** |
59
+ | `key` | string | ALTCHA site key; auto-generated when empty |
60
+ | `action` | string | Optional action name forwarded to the widget |
61
+ | `zIndex` | number (default `9999`) | Stacking for the challenge overlay |
62
+
63
+ | Slot | Description |
64
+ |------|-------------|
65
+ | *(default)* | Form actions (typically **`sonic-submit`** and fields) rendered below the widget |
66
+
67
+ | Event | Description |
68
+ |-------|-------------|
69
+ | `sonic-captcha-validate` | Fired when **`state`** is **`verified`** · **`error`** or **`expired`**; **`detail.valid`** is **`true`** only for **`verified`** |
70
+
71
+ Related: [Submit](#core/components/functional/submit/submit.md/submit) — **`needsCaptchaValidation`** and deferred send.
@@ -1,16 +1,27 @@
1
1
  # Card
2
2
 
3
- A **surface** for grouped content: padding, radius, shadow, and semantic **`type`** colors via shared theme tokens. Compose **`sonic-card-header`**, **`sonic-card-main`**, and **`sonic-card-footer`** inside the card, or put any markup in the default slot.
3
+ Cards **group related content** on a padded surface with radius, theme **`type`** colors, and elevation. Default **`shadow`** is `lg`. Compose **`sonic-card-header`** / **`sonic-card-main`** / **`sonic-card-footer`**, or place any markup in the default slot.
4
4
 
5
- Default **`type`** is `base` (page background). Use `light` for a subtle gray panel, `invert` / `neutral` for high-contrast blocks, and `primary`, `info`, `success`, `warning`, or `danger` for tinted surfaces (divider tokens apply on colored types).
5
+ ## Basic example
6
+
7
+ <sonic-code>
8
+ <template>
9
+ <sonic-card class="max-w-sm">
10
+ <p class="m-0">Related content on a raised surface.</p>
11
+ </sonic-card>
12
+ </template>
13
+ </sonic-code>
6
14
 
7
15
  ## Type
8
16
 
17
+ Default **`type`** is `base`. **`default`** and **`light`** share the same surface tokens.
18
+
9
19
  <sonic-code>
10
20
  <template>
11
21
  <div class="flex flex-wrap gap-3">
12
22
  <sonic-card type="base" class="min-w-[8rem]">Base</sonic-card>
13
23
  <sonic-card type="light" class="min-w-[8rem]">Light</sonic-card>
24
+ <sonic-card type="default" class="min-w-[8rem]">Default</sonic-card>
14
25
  <sonic-card type="primary" class="min-w-[8rem]">Primary</sonic-card>
15
26
  <sonic-card type="info" class="min-w-[8rem]">Info</sonic-card>
16
27
  <sonic-card type="success" class="min-w-[8rem]">Success</sonic-card>
@@ -22,9 +33,26 @@ Default **`type`** is `base` (page background). Use `light` for a subtle gray pa
22
33
  </template>
23
34
  </sonic-code>
24
35
 
36
+ ## Shadow
37
+
38
+ Set **`shadow`** to control elevation. Default is `lg`.
39
+
40
+ <sonic-code>
41
+ <template>
42
+ <div class="grid gap-4 sm:grid-cols-2 max-w-2xl">
43
+ <sonic-card shadow="none" class="min-h-[5rem] flex items-center justify-center">None</sonic-card>
44
+ <sonic-card shadow="sm" class="min-h-[5rem] flex items-center justify-center">Small</sonic-card>
45
+ <sonic-card shadow="md" class="min-h-[5rem] flex items-center justify-center">Medium</sonic-card>
46
+ <sonic-card shadow="lg" class="min-h-[5rem] flex items-center justify-center">Large</sonic-card>
47
+ </div>
48
+ </template>
49
+ </sonic-code>
50
+
25
51
  ## Header
26
52
 
27
- Quick titles with **`label`** and **`description`** attributes, or full control through the default slot. **`slot="suffix"`** aligns badges or actions on the right; suffix content does not shrink when the title wraps.
53
+ Quick titles with **`label`** and **`description`**, or full control through the default slot. **`slot="suffix"`** aligns badges or actions on the right; suffix content does not shrink when the title wraps.
54
+
55
+ `label` and `description` accept HTML (rendered as markup). Prefer plain text when possible; use **`sonic-card-header-description`** or the default slot for structured content.
28
56
 
29
57
  <sonic-code>
30
58
  <template>
@@ -42,7 +70,7 @@ Quick titles with **`label`** and **`description`** attributes, or full control
42
70
  <sonic-card-header-description>
43
71
  Choose what we email you about.
44
72
  </sonic-card-header-description>
45
- <sonic-badge slot="suffix" type="warning" size="xs">3 new</sonic-badge>
73
+ <sonic-badge slot="suffix" type="warning" size="xs">3 new</sonic-badge>
46
74
  </sonic-card-header>
47
75
  </sonic-card>
48
76
 
@@ -77,8 +105,6 @@ Quick titles with **`label`** and **`description`** attributes, or full control
77
105
  </template>
78
106
  </sonic-code>
79
107
 
80
- `label` and `description` accept HTML (rendered as markup). Prefer plain text when possible; use the slot for structured content.
81
-
82
108
  ## Main
83
109
 
84
110
  Optional wrapper for the primary content area (typography, media, forms).
@@ -110,7 +136,7 @@ Optional footer for actions, metadata, or secondary text.
110
136
  <p class="m-0">This project and all of its data will be removed permanently.</p>
111
137
  </sonic-card-main>
112
138
  <sonic-card-footer>
113
- <sonic-divider></sonic-divider>
139
+ <sonic-divider></sonic-divider>
114
140
  <div class="flex flex-wrap gap-2 justify-end">
115
141
  <sonic-button variant="ghost" size="sm">Cancel</sonic-button>
116
142
  <sonic-button type="danger" size="sm">Delete</sonic-button>
@@ -128,14 +154,14 @@ Header, media, body, and footer together.
128
154
  <template>
129
155
  <sonic-card class="max-w-md">
130
156
  <sonic-card-header label="Featured route" description="San Francisco → New York">
131
- <sonic-icon slot="suffix" library="iconoir" name="airplane"></sonic-icon>
157
+ <sonic-icon slot="suffix" library="iconoir" name="airplane" aria-hidden="true"></sonic-icon>
132
158
  </sonic-card-header>
133
159
  <sonic-card-main>
134
160
  <sonic-image
135
161
  rounded
136
162
  ratio="16/9"
137
- src="https://images.unsplash.com/photo-1436491865332-7a61a109cc05?w=800&q=80"
138
- alt=""
163
+ src="https://thegoodlife.fr/wp-content/uploads/sites/2/2022/03/compagnies-aeriennes-nostalgie-coeur-insert-03-dr.jpg"
164
+ alt="Airplane wing above the clouds"
139
165
  ></sonic-image>
140
166
  <p class="mb-0">
141
167
  Nonstop flight with flexible dates. Prices shown include taxes and fees.
@@ -150,3 +176,40 @@ Header, media, body, and footer together.
150
176
  </sonic-card>
151
177
  </template>
152
178
  </sonic-code>
179
+
180
+ ## API reference
181
+
182
+ ### `sonic-card`
183
+
184
+ | Attribute | Values | Description |
185
+ |----------|---------|-------------|
186
+ | `type` | `base` (default) · `light` · `invert` · `default` · `primary` · `warning` · `danger` · `success` · `info` · `neutral` | Semantic background and text (`default` and `light` share the same surface) |
187
+ | `shadow` | `none` · `sm` · `md` · `lg` (default `lg`) | Elevation on the card surface |
188
+
189
+ | Slot | Description |
190
+ |------|-------------|
191
+ | *(default)* | Free-form content (header, main, footer, or direct markup) |
192
+
193
+ ### `sonic-card-header`
194
+
195
+ | Attribute | Values | Description |
196
+ |----------|---------|-------------|
197
+ | `label` | HTML | Title (rendered as markup) |
198
+ | `description` | HTML | Subtitle below the title |
199
+
200
+ | Slot | Description |
201
+ |------|-------------|
202
+ | *(default)* | Custom title / description when attributes are not enough |
203
+ | `suffix` | Actions or badges aligned on the right (does not shrink) |
204
+
205
+ ### `sonic-card-header-description`
206
+
207
+ | Slot | Description |
208
+ |------|-------------|
209
+ | *(default)* | Subtitle text; styled below the title when slotted in **`sonic-card-header`** |
210
+
211
+ ### `sonic-card-main` · `sonic-card-footer`
212
+
213
+ | Slot | Description |
214
+ |------|-------------|
215
+ | *(default)* | Primary content (`main`) or actions / metadata (`footer`) |