@supersoniks/concorde 5.0.1 → 5.0.2

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 (50) hide show
  1. package/build-infos.json +1 -1
  2. package/concorde-core.bundle.js +519 -586
  3. package/concorde-core.es.js +3783 -3689
  4. package/dist/concorde-core.bundle.js +519 -586
  5. package/dist/concorde-core.es.js +3783 -3689
  6. package/index.html +2 -2
  7. package/package.json +14 -1
  8. package/src/core/components/ui/_css/rounded.ts +36 -0
  9. package/src/core/components/ui/_css/type.ts +49 -0
  10. package/src/core/components/ui/_i18n/ui-aria-labels.ts +104 -0
  11. package/src/core/components/ui/alert/alert.md +128 -72
  12. package/src/core/components/ui/alert/alert.spec.ts +145 -0
  13. package/src/core/components/ui/alert/alert.ts +86 -91
  14. package/src/core/components/ui/alert-messages/alert-messages.ts +1 -1
  15. package/src/core/components/ui/badge/badge.md +126 -78
  16. package/src/core/components/ui/badge/badge.ts +29 -81
  17. package/src/core/components/ui/button/button.md +1 -0
  18. package/src/core/components/ui/button/button.ts +11 -8
  19. package/src/core/components/ui/card/card-header.ts +7 -2
  20. package/src/core/components/ui/card/card.md +120 -65
  21. package/src/core/components/ui/divider/divider.ts +4 -9
  22. package/src/core/components/ui/form/fieldset/legend-description.ts +1 -1
  23. package/src/core/components/ui/form/fieldset/legend.ts +1 -1
  24. package/src/core/components/ui/form/input/input.md +1 -1
  25. package/src/core/components/ui/form/input/input.ts +19 -15
  26. package/src/core/components/ui/form/textarea/textarea.md +1 -1
  27. package/src/core/components/ui/image/image.md +147 -53
  28. package/src/core/components/ui/image/image.ts +10 -44
  29. package/src/core/components/ui/link/link.md +2 -2
  30. package/src/core/components/ui/link/link.ts +42 -37
  31. package/src/core/components/ui/modal/modal-close.ts +8 -12
  32. package/src/core/components/ui/modal/modal.ts +18 -18
  33. package/src/core/components/ui/pop/pop.md +7 -5
  34. package/src/core/components/ui/pop/pop.ts +78 -38
  35. package/src/core/components/ui/table/table.ts +2 -8
  36. package/src/core/components/ui/toast/dismissed.ts +14 -0
  37. package/src/core/components/ui/toast/toast-item.ts +139 -91
  38. package/src/core/components/ui/toast/toast.ts +4 -7
  39. package/src/core/components/ui/tooltip/tooltip.ts +6 -8
  40. package/src/core/utils/LocationHandler.ts +12 -5
  41. package/src/core/utils/dismissed.ts +22 -0
  42. package/src/core/utils/positioning.spec.ts +28 -0
  43. package/src/core/utils/positioning.ts +19 -0
  44. package/src/docs/_getting-started/concorde-outside.md +3 -3
  45. package/src/docs/code.ts +3 -1
  46. package/src/docs/search/docs-search.json +541 -1
  47. package/src/docs/tailwind/css/tailwind.css +6 -0
  48. package/src/tsconfig.json +422 -383
  49. package/src/tsconfig.tsbuildinfo +1 -1
  50. package/tailwind.config.js +50 -3
@@ -1,107 +1,201 @@
1
1
  # Image
2
2
 
3
+ Responsive **`<img>`** wrapper: aspect ratio, `object-fit: cover`, rounded corners, and optional fade-in on load. The host uses a light placeholder background (`--sc-placeholder-bg`) until the file is ready. Default **`loading`** is `lazy`; set **`loading="eager"`** for above-the-fold heroes.
4
+
3
5
  ## Rounded
4
6
 
7
+ Omit `rounded` for square corners. Boolean **`rounded`** uses the theme token `--sc-rounded`. Sizes: **`sm`**, **`md`**, **`lg`**, **`xl`**, **`full`** (circle — pair with `ratio="1/1"`), **`none`** (explicit reset).
8
+
5
9
  <sonic-code>
6
10
  <template>
7
- <div class="grid gap-8 grid-cols-3 items-center">
8
- <sonic-image
9
- src="https://thegoodlife.fr/wp-content/uploads/sites/2/2022/03/compagnies-aeriennes-nostalgie-coeur-insert-03-dr.jpg"
10
- ratio="1/1"
11
- >
12
- </sonic-image>
13
- <sonic-image
14
- rounded="sm"
15
- ratio="1/1"
16
- src="https://thegoodlife.fr/wp-content/uploads/sites/2/2022/03/compagnies-aeriennes-nostalgie-coeur-insert-03-dr.jpg"
17
- >
18
- </sonic-image>
19
- <sonic-image
20
- rounded
21
- ratio="1/1"
22
- src="https://thegoodlife.fr/wp-content/uploads/sites/2/2022/03/compagnies-aeriennes-nostalgie-coeur-insert-03-dr.jpg"
23
- >
24
- </sonic-image>
25
- <sonic-image
26
- rounded="md"
27
- ratio="1/1"
28
- src="https://thegoodlife.fr/wp-content/uploads/sites/2/2022/03/compagnies-aeriennes-nostalgie-coeur-insert-03-dr.jpg"
29
- >
30
- </sonic-image>
31
- <sonic-image
32
- rounded="lg"
33
- ratio="1/1"
34
- src="https://thegoodlife.fr/wp-content/uploads/sites/2/2022/03/compagnies-aeriennes-nostalgie-coeur-insert-03-dr.jpg"
35
- >
36
- </sonic-image>
37
- <sonic-image
38
- rounded="full"
39
- ratio="1/1"
40
- src="https://thegoodlife.fr/wp-content/uploads/sites/2/2022/03/compagnies-aeriennes-nostalgie-coeur-insert-03-dr.jpg"
41
- >
42
- </sonic-image>
11
+ <div class="grid gap-6 grid-cols-3 lg:grid-cols-4 items-end text-center text-xs ">
12
+ <div>
13
+ <sonic-image
14
+ ratio="1/1"
15
+ src="https://thegoodlife.fr/wp-content/uploads/sites/2/2022/03/compagnies-aeriennes-nostalgie-coeur-insert-03-dr.jpg"
16
+ ></sonic-image>
17
+ <p class="mt-2">default</p>
18
+ </div>
19
+ <div>
20
+ <sonic-image
21
+ rounded="sm"
22
+ ratio="1/1"
23
+ src="https://thegoodlife.fr/wp-content/uploads/sites/2/2022/03/compagnies-aeriennes-nostalgie-coeur-insert-03-dr.jpg"
24
+ ></sonic-image>
25
+ <p class="mt-2">sm</p>
26
+ </div>
27
+ <div>
28
+ <sonic-image
29
+ rounded
30
+ ratio="1/1"
31
+ src="https://thegoodlife.fr/wp-content/uploads/sites/2/2022/03/compagnies-aeriennes-nostalgie-coeur-insert-03-dr.jpg"
32
+ ></sonic-image>
33
+ <p class="mt-2">rounded</p>
34
+ </div>
35
+ <div>
36
+ <sonic-image
37
+ rounded="md"
38
+ ratio="1/1"
39
+ src="https://thegoodlife.fr/wp-content/uploads/sites/2/2022/03/compagnies-aeriennes-nostalgie-coeur-insert-03-dr.jpg"
40
+ ></sonic-image>
41
+ <p class="mt-2">md</p>
42
+ </div>
43
+ <div>
44
+ <sonic-image
45
+ rounded="lg"
46
+ ratio="1/1"
47
+ src="https://thegoodlife.fr/wp-content/uploads/sites/2/2022/03/compagnies-aeriennes-nostalgie-coeur-insert-03-dr.jpg"
48
+ ></sonic-image>
49
+ <p class="mt-2">lg</p>
50
+ </div>
51
+ <div>
52
+ <sonic-image
53
+ rounded="xl"
54
+ ratio="1/1"
55
+ src="https://thegoodlife.fr/wp-content/uploads/sites/2/2022/03/compagnies-aeriennes-nostalgie-coeur-insert-03-dr.jpg"
56
+ ></sonic-image>
57
+ <p class="mt-2">xl</p>
58
+ </div>
59
+ <div >
60
+ <div >
61
+ <sonic-image
62
+ rounded="full"
63
+ ratio="1/1"
64
+ src="https://thegoodlife.fr/wp-content/uploads/sites/2/2022/03/compagnies-aeriennes-nostalgie-coeur-insert-03-dr.jpg"
65
+ ></sonic-image>
66
+ <p class="mt-2">full</p>
67
+ </div>
68
+ </div>
43
69
  </div>
44
70
  </template>
45
71
  </sonic-code>
46
72
 
47
- ## Ratio
73
+ ## Aspect ratio
74
+
75
+ **`ratio`** sets CSS `aspect-ratio` on the image (default **`auto`**). The image still fills the host width (`width: 100%`).
48
76
 
49
77
  <sonic-code>
50
78
  <template>
51
79
  <div class="grid gap-8 grid-cols-2 items-center">
52
80
  <sonic-image
53
81
  src="https://thegoodlife.fr/wp-content/uploads/sites/2/2022/03/compagnies-aeriennes-nostalgie-coeur-insert-03-dr.jpg"
54
- >
55
- </sonic-image>
82
+ ></sonic-image>
56
83
  <sonic-image
57
84
  ratio="16/9"
58
85
  src="https://thegoodlife.fr/wp-content/uploads/sites/2/2022/03/compagnies-aeriennes-nostalgie-coeur-insert-03-dr.jpg"
59
- >
60
- </sonic-image>
86
+ ></sonic-image>
61
87
  <sonic-image
62
88
  ratio="1/1"
63
89
  src="https://thegoodlife.fr/wp-content/uploads/sites/2/2022/03/compagnies-aeriennes-nostalgie-coeur-insert-03-dr.jpg"
64
- >
65
- </sonic-image>
90
+ ></sonic-image>
66
91
  <sonic-image
67
92
  ratio="2/3"
68
93
  src="https://thegoodlife.fr/wp-content/uploads/sites/2/2022/03/compagnies-aeriennes-nostalgie-coeur-insert-03-dr.jpg"
69
- >
70
- </sonic-image>
94
+ ></sonic-image>
71
95
  </div>
72
96
  </template>
73
97
  </sonic-code>
74
98
 
75
99
  ## Object position
76
100
 
101
+ **`objectPosition`** maps to CSS `object-position` (default **`center center`**). Useful on wide crops when the subject sits off-center.
102
+
77
103
  <sonic-code>
78
104
  <template>
79
105
  <div class="grid gap-8 grid-cols-2 items-center">
80
106
  <sonic-image
81
- src="https://thegoodlife.fr/wp-content/uploads/sites/2/2022/03/compagnies-aeriennes-nostalgie-coeur-insert-03-dr.jpg"
82
107
  ratio="11/4"
83
- >
84
- </sonic-image>
108
+ src="https://thegoodlife.fr/wp-content/uploads/sites/2/2022/03/compagnies-aeriennes-nostalgie-coeur-insert-03-dr.jpg"
109
+ ></sonic-image>
85
110
  <sonic-image
86
111
  objectPosition="center top"
87
- src="https://thegoodlife.fr/wp-content/uploads/sites/2/2022/03/compagnies-aeriennes-nostalgie-coeur-insert-03-dr.jpg"
88
112
  ratio="11/4"
89
- >
90
- </sonic-image>
113
+ src="https://thegoodlife.fr/wp-content/uploads/sites/2/2022/03/compagnies-aeriennes-nostalgie-coeur-insert-03-dr.jpg"
114
+ ></sonic-image>
91
115
  </div>
92
116
  </template>
93
117
  </sonic-code>
94
118
 
95
119
  ## Cover
96
120
 
121
+ **`cover`** stretches the image to fill a **positioned** parent (`position: relative` + fixed height or inset). Aspect ratio on the host is ignored while `cover` is set.
122
+
97
123
  <sonic-code>
98
124
  <template>
99
- <div class="h-96 relative">
125
+ <div class="h-96 relative rounded-lg overflow-hidden">
100
126
  <sonic-image
101
127
  cover
102
128
  src="https://thegoodlife.fr/wp-content/uploads/sites/2/2022/03/compagnies-aeriennes-nostalgie-coeur-insert-03-dr.jpg"
129
+ ></sonic-image>
130
+ </div>
131
+ </template>
132
+ </sonic-code>
133
+
134
+ ## Load transition
135
+
136
+ Set **`transition`** to **`fade`** (default when the attribute is present) or **`fade-scale-out`**. The image stays at `opacity: 0` until the browser fires **`load`**, then the **`loaded`** class runs the animation. Changing `src` on an existing element does not replay the effect — mount a new `sonic-image` when you need another entrance (galleries, infinite scroll).
137
+
138
+ Click **Add image** to append small thumbnails and replay the transition. **Clear** resets the row.
139
+
140
+ <sonic-code>
141
+ <template>
142
+ <div class="flex flex-wrap gap-2 mb-4">
143
+ <sonic-button
144
+ size="sm"
145
+ onclick="(function () {
146
+ var host = document.getElementById('sonic-image-transition-host');
147
+ var img = document.createElement('sonic-image');
148
+ img.transition = 'fade';
149
+ img.ratio = '1/1';
150
+ img.rounded = 'md';
151
+ img.loading = 'eager';
152
+ img.style.width = '5rem';
153
+ img.src = 'https://picsum.photos/seed/' + Date.now() + '/120/120';
154
+ host.appendChild(img);
155
+ })()"
156
+ >
157
+ Add image (fade)
158
+ </sonic-button>
159
+ <sonic-button
160
+ size="sm"
161
+ variant="outline"
162
+ onclick="(function () {
163
+ var host = document.getElementById('sonic-image-transition-host');
164
+ var img = document.createElement('sonic-image');
165
+ img.transition = 'fade-scale-out';
166
+ img.ratio = '1/1';
167
+ img.rounded = 'md';
168
+ img.loading = 'eager';
169
+ img.style.width = '5rem';
170
+ img.src = 'https://picsum.photos/seed/' + Date.now() + '/120/120';
171
+ host.appendChild(img);
172
+ })()"
173
+ >
174
+ Add image (fade-scale-out)
175
+ </sonic-button>
176
+ <sonic-button
177
+ size="sm"
178
+ variant="ghost"
179
+ onclick="document.getElementById('sonic-image-transition-host').replaceChildren()"
103
180
  >
104
- </sonic-image>
181
+ Clear
182
+ </sonic-button>
105
183
  </div>
184
+ <div id="sonic-image-transition-host" class="flex flex-wrap gap-2 min-h-[5rem]"></div>
185
+ </template>
186
+ </sonic-code>
187
+
188
+ ## Accessibility and parts
189
+
190
+ Always set meaningful **`alt`** text (empty string only for decorative images).
191
+
192
+ <sonic-code>
193
+ <template>
194
+ <sonic-image
195
+ rounded="md"
196
+ ratio="16/9"
197
+ alt="Concorde aircraft in flight"
198
+ src="https://thegoodlife.fr/wp-content/uploads/sites/2/2022/03/compagnies-aeriennes-nostalgie-coeur-insert-03-dr.jpg"
199
+ ></sonic-image>
106
200
  </template>
107
201
  </sonic-code>
@@ -1,18 +1,18 @@
1
1
  import { html, LitElement, css } from "lit";
2
2
  import { customElement, property } from "lit/decorators.js";
3
3
  import { styleMap } from "lit/directives/style-map.js";
4
+ import { Rounded, hostRounded } from "../_css/rounded";
4
5
  const tagName = "sonic-image";
5
6
  @customElement(tagName)
6
7
  export class Image extends LitElement {
7
8
  static styles = [
9
+ hostRounded,
8
10
  css`
9
11
  :host {
10
- --sc-img-radius: 0;
11
- --sc-img-bg: var(--sc-placeholder-bg, rgba(12, 12, 12, 0.05));
12
- border-radius: var(--sc-img-radius);
12
+ --sc-_bg: var(--sc-placeholder-bg, rgba(12, 12, 12, 0.05));
13
+ background: var(--sc-_bg);
13
14
  display: block;
14
15
  width: 100%;
15
- background: var(--sc-img-bg);
16
16
  }
17
17
 
18
18
  img {
@@ -25,34 +25,6 @@ export class Image extends LitElement {
25
25
  visibility: hidden;
26
26
  }
27
27
 
28
- /*Rounded*/
29
- :host([rounded]) {
30
- --sc-img-radius: var(--sc-rounded);
31
- overflow: hidden;
32
- }
33
- :host([rounded="sm"]) {
34
- --sc-img-radius: var(--sc-rounded-sm);
35
- }
36
-
37
- :host([rounded="md"]) {
38
- --sc-img-radius: var(--sc-rounded-md);
39
- }
40
-
41
- :host([rounded="lg"]) {
42
- --sc-img-radius: var(--sc-rounded-lg);
43
- }
44
- :host([rounded="xl"]) {
45
- --sc-img-radius: var(--sc-rounded-xl);
46
- }
47
-
48
- /*Cercle*/
49
- :host([rounded="full"]) {
50
- --sc-img-radius: 50% !important;
51
- }
52
- :host([rounded="none"]) {
53
- --sc-img-radius: 0 !important;
54
- }
55
-
56
28
  :host([cover]),
57
29
  :host([cover]) > div,
58
30
  :host([cover]) img {
@@ -72,7 +44,8 @@ export class Image extends LitElement {
72
44
 
73
45
  :host([transition="fade-scale-out"]) img {
74
46
  scale: 1.08;
75
- transition: opacity 0.3s linear,
47
+ transition:
48
+ opacity 0.3s linear,
76
49
  scale 0.3s cubic-bezier(0.16, 1, 0.3, 1);
77
50
  }
78
51
  :host([transition]) img.loaded {
@@ -82,13 +55,7 @@ export class Image extends LitElement {
82
55
  `,
83
56
  ];
84
57
 
85
- @property({ type: String }) rounded:
86
- | ""
87
- | "none"
88
- | "full"
89
- | "sm"
90
- | "md"
91
- | "lg" = "none";
58
+ @property({ type: String, reflect: true }) rounded: Rounded = "none";
92
59
  @property({ type: String }) src = "";
93
60
  @property({ type: String }) alt = "";
94
61
  @property({ type: String }) loading: "eager" | "lazy" = "lazy";
@@ -101,7 +68,7 @@ export class Image extends LitElement {
101
68
  @property({ type: Boolean, reflect: true }) cover = false;
102
69
 
103
70
  firstUpdated(
104
- changedProperties: Map<string | number | symbol, unknown>
71
+ changedProperties: Map<string | number | symbol, unknown>,
105
72
  ): void {
106
73
  if (this.transition) {
107
74
  const img = this.shadowRoot?.querySelector("img");
@@ -119,10 +86,9 @@ export class Image extends LitElement {
119
86
  imageRendering: this.imageRendering,
120
87
  objectPosition: this.objectPosition,
121
88
  };
122
- return html`<div part="image">
123
- <picture part="picture"
89
+ return html`<div>
90
+ <picture
124
91
  ><img
125
- part="img"
126
92
  src="${this.src}"
127
93
  loading="${this.loading}"
128
94
  alt="${this.alt}"
@@ -3,14 +3,14 @@
3
3
  ## Href
4
4
  <sonic-code>
5
5
  <template>
6
- <sonic-link href="/">Basic link with href attibute</sonic-link>
6
+ <sonic-link href="/">Basic link with href attribute</sonic-link>
7
7
  </template>
8
8
  </sonic-code>
9
9
 
10
10
  ## Target
11
11
  <sonic-code>
12
12
  <template>
13
- <sonic-link href="/" target="_blank">Link with target attibute</sonic-link>
13
+ <sonic-link href="/" target="_blank">Link with target attribute</sonic-link>
14
14
  </template>
15
15
  </sonic-code>
16
16
 
@@ -1,7 +1,9 @@
1
- import LocationHandler from "@supersoniks/concorde/core/utils/LocationHandler";
2
- import {html, LitElement, css, PropertyValues, nothing} from "lit";
3
- import {customElement, property} from "lit/decorators.js";
4
- import {ifDefined} from "lit/directives/if-defined.js";
1
+ import LocationHandler, {
2
+ type AutoActiveMode,
3
+ } from "@supersoniks/concorde/core/utils/LocationHandler";
4
+ import { html, LitElement, css, nothing } from "lit";
5
+ import { customElement, property } from "lit/decorators.js";
6
+ import { ifDefined } from "lit/directives/if-defined.js";
5
7
  import Electron from "@supersoniks/concorde/core/utils/Electron";
6
8
  const tagName = "sonic-link";
7
9
 
@@ -11,13 +13,27 @@ export class Link extends LitElement {
11
13
  css`
12
14
  a {
13
15
  color: inherit;
14
- text-decoration: none;
15
- display: contents;
16
+ text-decoration: inherit;
17
+ display: inline-flex;
18
+ align-items: inherit;
19
+ gap: inherit;
20
+ min-width: 0;
21
+ max-width: 100%;
22
+ }
23
+
24
+ a:focus {
25
+ outline: none;
26
+ }
27
+
28
+ a:focus-visible {
29
+ outline: 2px solid currentColor;
30
+ outline-offset: 2px;
31
+ border-radius: 2px;
16
32
  }
17
33
  `,
18
34
  ];
19
35
 
20
- @property({type: String}) href = "";
36
+ @property({ type: String }) href = "";
21
37
  private _location = "";
22
38
  get location(): string {
23
39
  return this._location;
@@ -27,47 +43,37 @@ export class Link extends LitElement {
27
43
  LocationHandler.updateComponentActiveState(this);
28
44
  }
29
45
 
30
- @property({type: String, attribute: "data-aria-label"}) ariaLabel = null;
46
+ @property({ type: String, attribute: "data-aria-label" }) ariaLabel:
47
+ | string
48
+ | null = null;
31
49
 
32
50
  /**
33
- * mode d'activation du bouton :
34
- * - strict : l'url courante match exactement avec le href du bouton
35
- * - partial : l'url courante match à gauche avec le href du bouton
36
- * - disabled : aucune activation / désactivation
51
+ * Active state for in-app navigation:
52
+ * - strict — pathname, search, and hash must match
53
+ * - strict-path-only — pathname and hash must match (ignore search)
54
+ * - partial — current URL starts with href (default)
55
+ * - disabled — never sets `active`
37
56
  */
38
- @property({type: String}) autoActive: "strict" | "partial" | "disabled" = "partial";
57
+ @property({ type: String }) autoActive: AutoActiveMode = "partial";
58
+
39
59
  connectedCallback() {
40
60
  if (this.href && this.href.indexOf("http") != 0) {
41
61
  LocationHandler.onChange(this);
42
- this.location = document.location.href.replace(document.location.origin, "");
62
+ this.location = document.location.href.replace(
63
+ document.location.origin,
64
+ "",
65
+ );
43
66
  }
44
67
 
45
- // on Enter keypress we trigger a click on the link tag
46
- this.addEventListener("keypress", (e: KeyboardEvent) => {
47
- if (e.key === "Enter") {
48
- this.shadowRoot?.querySelector("a")?.click();
49
- }
50
- });
51
-
52
- this.setFocusable();
53
-
54
68
  super.connectedCallback();
55
69
  }
56
70
 
57
- setFocusable() {
58
- if (this.href) {
59
- this.setAttribute("tabIndex", "0");
60
- } else {
61
- this.removeAttribute("tabIndex");
62
- }
63
- }
64
-
65
71
  disconnectedCallback(): void {
66
72
  LocationHandler.offChange(this);
67
73
  super.disconnectedCallback();
68
74
  }
69
75
  private _target: string | null = null;
70
- @property({type: String}) set target(newTarget) {
76
+ @property({ type: String }) set target(newTarget) {
71
77
  this._target = newTarget;
72
78
  Electron.fixBlankLink(this);
73
79
  this.requestUpdate();
@@ -79,17 +85,15 @@ export class Link extends LitElement {
79
85
  /**
80
86
  * Si présent on passe en mode pushstate
81
87
  */
82
- @property({type: Boolean}) pushState: boolean | null = null;
88
+ @property({ type: Boolean, reflect: true }) pushState: boolean | null = null;
83
89
 
84
90
  handlePushState(e: Event) {
85
91
  e.preventDefault();
86
92
  LocationHandler.changeFromComponent(this);
87
93
  }
88
94
 
89
- updated(changedProperties: PropertyValues) {
90
- if (changedProperties.has("href")) {
91
- this.setFocusable();
92
- }
95
+ private get blankRel(): string | undefined {
96
+ return this.target === "_blank" ? "noopener noreferrer" : undefined;
93
97
  }
94
98
 
95
99
  render() {
@@ -99,6 +103,7 @@ export class Link extends LitElement {
99
103
  href="${this.href}"
100
104
  aria-label=${this.ariaLabel || nothing}
101
105
  target=${ifDefined(this.target)}
106
+ rel=${ifDefined(this.blankRel)}
102
107
  @click=${this.pushState ? this.handlePushState : null}
103
108
  >
104
109
  <slot></slot>
@@ -4,31 +4,27 @@ import { Modal } from "@supersoniks/concorde/core/components/ui/modal/modal";
4
4
  import { ifDefined } from "lit/directives/if-defined.js";
5
5
  import HTML from "@supersoniks/concorde/core/utils/HTML";
6
6
  import { ButtonType } from "../button/button";
7
+ import {
8
+ resolveUiLabel,
9
+ uiAriaLabels,
10
+ type UiLabelDict,
11
+ } from "@supersoniks/concorde/core/components/ui/_i18n/ui-aria-labels";
12
+
7
13
  const tagName = "sonic-modal-close";
8
14
 
9
15
  @customElement(tagName)
10
16
  export class ModalClose extends LitElement {
11
- @property() translation: Record<string, string> = {
12
- fr: "Fermer la fenêtre",
13
- en: "Close window",
14
- de: "Fenster schließen",
15
- nl: "Venster sluiten",
16
- es: "Cerrar",
17
- };
17
+ @property() translation: UiLabelDict = { ...uiAriaLabels.closeWindow };
18
18
 
19
19
  @property() reset?: string;
20
20
  @property() type?: ButtonType;
21
21
 
22
- connectedCallback() {
23
- super.connectedCallback();
24
- this.lang = document.documentElement.lang?.split("-")[0] ?? "fr";
25
- }
26
22
  render() {
27
23
  return html`<sonic-button
28
24
  noAutoFill
29
- data-aria-label=${this.translation[this.lang]}
30
25
  reset=${ifDefined(this.reset)}
31
26
  shape="circle"
27
+ .ariaLabel=${resolveUiLabel(this.translation)}
32
28
  @click=${this.handleClick}
33
29
  type=${ifDefined(this.type)}
34
30
  ><sonic-icon name="cancel" size="lg"></sonic-icon
@@ -58,13 +58,13 @@ export class Modal extends Subscriber(LitElement) {
58
58
  --sc-modal-py: 2.5rem;
59
59
  --sc-modal-px: 1.5rem;
60
60
 
61
- --sc_backdrop-bg: var(
62
- --sc_overlay-bg,
61
+ --sc-_backdrop-bg: var(
62
+ --sc-_overlay-bg,
63
63
  var(--sc-base-200, rgba(0, 0, 0, 0.12))
64
64
  );
65
- --sc_backdrop-opacity: 0;
66
- --sc_rounded: var(--sc-rounded-lg);
67
- --sc_z-index: 990;
65
+ --sc-_backdrop-opacity: 0;
66
+ --sc-_rounded: var(--sc-rounded-lg);
67
+ --sc-_z-index: 990;
68
68
  }
69
69
 
70
70
  * {
@@ -76,7 +76,7 @@ export class Modal extends Subscriber(LitElement) {
76
76
  color: var(--sc-base-content, #000);
77
77
  width: 100%;
78
78
  box-shadow: var(--sc-shadow-lg);
79
- border-radius: var(--sc_rounded) var(--sc_rounded);
79
+ border-radius: var(--sc-_rounded) var(--sc-_rounded);
80
80
  transform: translateZ(0);
81
81
  border: none;
82
82
  outline: none;
@@ -87,16 +87,16 @@ export class Modal extends Subscriber(LitElement) {
87
87
  opacity: 0;
88
88
  position: fixed;
89
89
  inset: 0;
90
- z-index: var(--sc_z-index);
90
+ z-index: var(--sc-_z-index);
91
91
  }
92
92
 
93
93
  #backdrop {
94
- opacity: var(--sc_backdrop-opacity, 0);
95
- background: var(--sc_backdrop-bg);
94
+ opacity: var(--sc-_backdrop-opacity, 0);
95
+ background: var(--sc-_backdrop-bg);
96
96
  transition: opacity 0.15s linear;
97
97
  inset: 0;
98
98
  position: fixed;
99
- z-index: var(--sc_z-index);
99
+ z-index: var(--sc-_z-index);
100
100
  }
101
101
 
102
102
  #modal-content {
@@ -112,12 +112,12 @@ export class Modal extends Subscriber(LitElement) {
112
112
  max-width: none !important;
113
113
  margin: auto 0 0 !important;
114
114
  width: 100% !important;
115
- border-radius: var(--sc_rounded) var(--sc_rounded) 0 0 !important;
115
+ border-radius: var(--sc-_rounded) var(--sc-_rounded) 0 0 !important;
116
116
  }
117
117
  }
118
118
 
119
119
  :host([fullScreen]) {
120
- --sc_rounded: 0;
120
+ --sc-_rounded: 0;
121
121
  }
122
122
  :host([fullScreen]) #modal {
123
123
  width: 100% !important;
@@ -161,11 +161,11 @@ export class Modal extends Subscriber(LitElement) {
161
161
  /* Close button */
162
162
  ::slotted(sonic-modal-close),
163
163
  sonic-modal-close {
164
- --sc_top: 0.25rem;
165
- --sc_x: 0.25rem;
164
+ --sc-_top: 0.25rem;
165
+ --sc-_x: 0.25rem;
166
166
  position: sticky;
167
167
  display: block;
168
- top: var(--sc_top);
168
+ top: var(--sc-_top);
169
169
  margin-left: auto;
170
170
  margin-bottom: -1rem;
171
171
  margin-top: calc(-1 * var(--sc-modal-py) - 0.25rem);
@@ -312,7 +312,7 @@ export class Modal extends Subscriber(LitElement) {
312
312
  }
313
313
 
314
314
  if (_changedProperties.has("zIndex")) {
315
- this.style.setProperty("--sc_z-index", this.zIndex || "990");
315
+ this.style.setProperty("--sc-_z-index", this.zIndex || "990");
316
316
  }
317
317
 
318
318
  if (_changedProperties.has("paddingX")) {
@@ -530,10 +530,10 @@ export class Modal extends Subscriber(LitElement) {
530
530
  // Backdrop
531
531
  if (!this.fullScreen) {
532
532
  if (isEntering) {
533
- this.style.setProperty("--sc_backdrop-opacity", "0.8");
533
+ this.style.setProperty("--sc-_backdrop-opacity", "0.8");
534
534
  } else {
535
535
  setTimeout(() => {
536
- this.style.setProperty("--sc_backdrop-opacity", "0");
536
+ this.style.setProperty("--sc-_backdrop-opacity", "0");
537
537
  }, 150);
538
538
  }
539
539
  }