@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
@@ -1,6 +1,10 @@
1
- # Loader
1
+ # Loader
2
2
 
3
- ## Inline mode
3
+ **`sonic-loader`** shows a loading animation in the page or as a viewport overlay. Default **`mode`** is **`fixed`** (centered overlay). Use **`inline`** inside lists and fetch placeholders. Pair **`noDelay`** when the spinner should appear without the default fade-in wait. For **`sonic-fetch`** / **`sonic-list`**, set the parent **`loader`** attribute instead of embedding a tag manually.
4
+
5
+ ## Basic example
6
+
7
+ Inline loaders fit content areas; they use the theme primary color unless **`currentColor`** is set.
4
8
 
5
9
  <sonic-code>
6
10
  <template>
@@ -8,48 +12,101 @@
8
12
  </template>
9
13
  </sonic-code>
10
14
 
11
- ## CurrentColor
15
+ ## Mode
16
+
17
+ **`inline`** — ellipsis animation in the document flow. **`fixed`** — centered overlay (`position: fixed`); default when the tag is omitted.
12
18
 
13
19
  <sonic-code>
14
20
  <template>
15
- <sonic-loader mode="inline" currentColor style="color:purple;"></sonic-loader>
21
+ <sonic-loader mode="inline"></sonic-loader>
16
22
  </template>
17
23
  </sonic-code>
18
24
 
25
+ Use the checkbox below to toggle a **`fixed`** loader over the page (default **`mode`** on **`sonic-loader`**).
19
26
 
20
- ## Align
27
+ <docs-lit-demo for="docs-toggle-loader-demo"></docs-lit-demo>
28
+
29
+ ## Inline alignment and color
30
+
31
+ **`align`** only affects **`mode="inline"`**: **`left`** · **`center`** (default) · **`right`**. Set **`currentColor`** so dots follow the host `color` (for example on a purple parent).
21
32
 
22
33
  <sonic-code>
23
34
  <template>
24
- <sonic-loader mode="inline" align="left"></sonic-loader>
25
- <sonic-loader mode="inline" align="center"></sonic-loader>
26
- <sonic-loader mode="inline" align="right"></sonic-loader>
35
+ <div class="grid gap-4">
36
+ <sonic-loader mode="inline" currentColor style="color: purple;"></sonic-loader>
37
+ <div class="flex flex-col gap-2">
38
+ <sonic-loader mode="inline" align="left"></sonic-loader>
39
+ <sonic-loader mode="inline" align="center"></sonic-loader>
40
+ <sonic-loader mode="inline" align="right"></sonic-loader>
41
+ </div>
42
+ </div>
27
43
  </template>
28
44
  </sonic-code>
29
45
 
30
- ## Fixed mode
46
+ ## `noDelay`
31
47
 
32
- <docs-lit-demo for="docs-toggle-loader-demo"></docs-lit-demo>
48
+ By default **`mode="fixed"`** waits briefly before fading in. **`mode="inline"`** already skips that wait. Set **`noDelay`** on **`fixed`** (or pass **`noDelay: true`** to **`Loader.show()`**) to appear immediately.
33
49
 
50
+ <sonic-code>
51
+ <template>
52
+ <sonic-loader mode="inline" noDelay></sonic-loader>
53
+ </template>
54
+ </sonic-code>
55
+
56
+ ## Accessibility (`announce`)
57
+
58
+ The animation is **`aria-hidden`** by default so screen readers are not spammed on every fetch. Set **`announce`** when the loader is injected **after** user action (for example a global overlay): the host gets **`role="status"`**, **`aria-live="polite"`**, and a localized **`aria-label`** (“Loading” / “Chargement en cours”, …). For in-button loading, prefer **`sonic-button`** **`loading`** and **`aria-busy`** on the control—not on the loader.
34
59
 
35
- ## Loading button
36
60
  <sonic-code>
37
61
  <template>
38
- <sonic-button loading>A loading button</sonic-button>
62
+ <sonic-loader mode="inline" announce></sonic-loader>
39
63
  </template>
40
64
  </sonic-code>
41
65
 
42
- ## Hide / show programmatically
66
+ ## Show and hide programmatically
67
+
68
+ Import **`Loader`** and call **`Loader.show()`** / **`Loader.hide()`**. **`hide()`** is reference-counted: call it once per **`show()`**. With no **`container`**, the loader is appended to the theme pop container and **`mode`** is always **`fixed`**. Pass **`container`** and **`mode: "inline"`** to mount an inline instance in a specific element.
43
69
 
44
70
  <sonic-code language="javascript">
45
71
  <template>
46
- import {Loader} from "@supersoniks/concorde/core/components/ui/loader/loader";
47
- // Show
48
- Loader.show({
49
- mode:"fixed" // optional : fixed | inline
50
- container : document.querySelector('#foo') // optional, default : parent sonic-theme || document.body
51
- });
52
- // Hide
53
- Loader.hide();
72
+ import { Loader } from "@supersoniks/concorde/core/components/ui/loader/loader";
73
+
74
+ Loader.show({
75
+ mode: "fixed",
76
+ noDelay: false,
77
+ announce: true,
78
+ container: document.querySelector("#foo"),
79
+ });
80
+
81
+ Loader.hide();
54
82
  </template>
55
- </sonic-code>
83
+ </sonic-code>
84
+
85
+ ## Composition
86
+
87
+ **`sonic-button`** **`loading`** shows an icon spinner and sets **`aria-busy`** on the button. **`sonic-fetch`** and **`sonic-list`** render **`sonic-loader`** when their **`loader`** attribute is set: **`true`** or an empty string maps to **`fixed`**; otherwise use **`inline`** or **`fixed`**.
88
+
89
+ <sonic-code>
90
+ <template>
91
+ <sonic-button loading>Save changes</sonic-button>
92
+ </template>
93
+ </sonic-code>
94
+
95
+ ## API reference
96
+
97
+ | Attribute | Values | Description |
98
+ |----------|---------|-------------|
99
+ | `mode` | `inline` · `fixed` (default `fixed`) | Layout: in-flow ellipsis vs viewport-centered overlay |
100
+ | `noDelay` | boolean | Skips the initial fade-in delay before the animation appears |
101
+ | `announce` | boolean | **`role="status"`** and **`aria-live="polite"`** with localized loading label when the loader should be announced |
102
+ | `align` | `left` · `center` · `right` | Horizontal alignment for **`mode="inline"`** only (attribute selector; default centered) |
103
+ | `currentColor` | boolean | Uses `currentColor` for dot fill instead of **`--sc-primary`** |
104
+
105
+ This component has **no slots**. The animation markup is internal.
106
+
107
+ ### Static methods
108
+
109
+ | Method | Description |
110
+ |--------|-------------|
111
+ | `Loader.show(conf?)` | Mounts the shared loader instance. **`conf.mode`**, **`conf.noDelay`**, **`conf.announce`**, optional **`conf.container`**. Without **`container`**, uses the theme pop container and forces **`fixed`**. |
112
+ | `Loader.hide()` | Decrements the show counter and removes the instance from the DOM when it reaches zero. |
@@ -1,12 +1,27 @@
1
- import { html, LitElement, css } from "lit";
1
+ import { html, LitElement, css, PropertyValues } from "lit";
2
2
  import { customElement, property } from "lit/decorators.js";
3
+ import { classMap } from "lit/directives/class-map.js";
3
4
 
4
5
  import { inline } from "@supersoniks/concorde/core/components/ui/loader/styles/inline";
5
6
  import { fixed } from "@supersoniks/concorde/core/components/ui/loader/styles/fixed";
6
7
  import { Theme } from "@supersoniks/concorde/core/components/ui/theme/theme";
7
- export type LoaderMode = "inline" | "fixed" | "noDelay";
8
- type LoaderConf = { mode?: string; container?: HTMLElement; noDelay?: boolean };
8
+ import {
9
+ resolveUiLabel,
10
+ uiAriaLabels,
11
+ } from "@supersoniks/concorde/core/components/ui/_i18n/ui-aria-labels";
12
+
13
+ export type LoaderMode = "inline" | "fixed";
14
+
15
+ export type LoaderConf = {
16
+ mode?: LoaderMode;
17
+ container?: HTMLElement;
18
+ noDelay?: boolean;
19
+ /** Screen reader announcement when the loader is injected (e.g. global overlay). */
20
+ announce?: boolean;
21
+ };
22
+
9
23
  const tagName = "sonic-loader";
24
+
10
25
  @customElement(tagName)
11
26
  export class Loader extends LitElement {
12
27
  static styles = [
@@ -42,45 +57,70 @@ export class Loader extends LitElement {
42
57
  }
43
58
  `,
44
59
  ];
45
- static loader: Loader;
60
+
61
+ static loader: Loader | null = null;
46
62
  static callCounter = 0;
47
- static show(conf?: LoaderConf) {
48
- if (!Loader.loader)
49
- Loader.loader = document.createElement("sonic-loader") as Loader;
50
- const loader: Loader = Loader.loader;
51
- if (!conf) conf = {};
52
- if (conf.mode) loader.setAttribute("mode", conf.mode);
53
- if (conf.noDelay) loader.setAttribute("noDelay", "");
54
-
55
- if (!conf.container) {
56
- conf.container = Theme.getPopContainer();
57
- conf.mode = "fixed";
63
+
64
+ static show(conf: LoaderConf = {}) {
65
+ if (!Loader.loader) {
66
+ Loader.loader = document.createElement(tagName) as Loader;
58
67
  }
68
+ const loader = Loader.loader;
59
69
 
60
- conf.container.appendChild(loader);
70
+ const container = conf.container ?? Theme.getPopContainer();
71
+ const mode: LoaderMode = conf.container ? (conf.mode ?? "fixed") : "fixed";
72
+ const noDelay = conf.noDelay ?? false;
73
+
74
+ loader.mode = mode;
75
+ loader.noDelay = noDelay;
76
+ loader.announce = conf.announce ?? false;
77
+ container.appendChild(loader);
61
78
  Loader.callCounter++;
62
79
  }
63
80
 
64
81
  static hide() {
82
+ if (Loader.callCounter <= 0) return;
65
83
  Loader.callCounter--;
66
84
  if (Loader.callCounter > 0) return;
67
- if (Loader.loader) Loader.loader.remove();
85
+ Loader.loader?.remove();
68
86
  }
69
87
 
88
+ /** Display mode: inline (in content) or fixed (viewport overlay). */
89
+ @property({ type: String }) mode: LoaderMode = "fixed";
90
+ /** Skip the initial fade-in delay before the loader appears. */
91
+ @property({ type: Boolean }) noDelay = false;
70
92
  /**
71
- * Mode d'affichage du loader
72
- * * inline : Loader dans le contenu
73
- * * fixed : Loader global par dessus la page
93
+ * When true, exposes `role="status"` and `aria-live="polite"` on the host (like `sonic-alert`).
94
+ * Use when the loader appears after user action; default inline loaders stay decorative.
74
95
  */
75
- @property({ type: String }) mode: LoaderMode = "fixed";
76
- @property({ type: Boolean }) noDelay: boolean = false;
96
+ @property({ type: Boolean, reflect: true }) announce = false;
97
+
98
+ willUpdate(changed: PropertyValues<this>) {
99
+ if (changed.has("announce")) {
100
+ this._syncAnnounceA11y();
101
+ }
102
+ }
103
+
104
+ private _syncAnnounceA11y() {
105
+ if (!this.announce) {
106
+ this.removeAttribute("role");
107
+ this.removeAttribute("aria-live");
108
+ this.removeAttribute("aria-label");
109
+ return;
110
+ }
111
+ this.setAttribute("role", "status");
112
+ this.setAttribute("aria-live", "polite");
113
+ this.setAttribute("aria-label", resolveUiLabel(uiAriaLabels.loading));
114
+ }
77
115
 
78
116
  render() {
79
- return html`<div
80
- class="sonic-loader sonic-loader--${this.mode} ${this.noDelay
81
- ? "sonic-loader--nodelay"
82
- : ""} "
83
- >
117
+ const classes = {
118
+ "sonic-loader": true,
119
+ [`sonic-loader--${this.mode}`]: true,
120
+ "sonic-loader--nodelay": this.noDelay,
121
+ };
122
+
123
+ return html`<div aria-hidden="true" class=${classMap(classes)}>
84
124
  <div></div>
85
125
  <div></div>
86
126
  <div></div>
@@ -22,7 +22,7 @@ export const fixed = css`
22
22
  position: fixed;
23
23
  top: 50%;
24
24
  left: 50%;
25
- transform: transateY(-50%) translateX(-50%);
25
+ transform: translate(-50%, -50%);
26
26
  z-index: 999;
27
27
  }
28
28
 
@@ -37,20 +37,15 @@ export const fixed = css`
37
37
  display: none !important;
38
38
  }
39
39
  .sonic-loader--fixed > div {
40
- background-color: var(--sc-_loader-bg);
41
- width: 5rem;
42
- height: 5rem;
43
- border-radius: 100%;
44
- margin: 2px;
45
- animation-fill-mode: both;
46
40
  position: absolute;
47
- top: 0px;
48
- opacity: 0;
49
- margin: 0;
50
41
  top: -2.5rem;
51
42
  left: -2.5rem;
52
43
  width: 5rem;
53
44
  height: 5rem;
54
- animation: sonic-loader--fixed 1s 0s linear infinite;
45
+ border-radius: 100%;
46
+ background-color: var(--sc-_loader-bg);
47
+ opacity: 0;
48
+ animation: sonic-loader--fixed 1s linear infinite;
49
+ animation-fill-mode: both;
55
50
  }
56
51
  `;