@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.
- package/build-infos.json +1 -1
- package/concorde-core.bundle.js +519 -586
- package/concorde-core.es.js +3783 -3689
- package/dist/concorde-core.bundle.js +519 -586
- package/dist/concorde-core.es.js +3783 -3689
- package/index.html +2 -2
- package/package.json +14 -1
- package/src/core/components/ui/_css/rounded.ts +36 -0
- package/src/core/components/ui/_css/type.ts +49 -0
- package/src/core/components/ui/_i18n/ui-aria-labels.ts +104 -0
- package/src/core/components/ui/alert/alert.md +128 -72
- package/src/core/components/ui/alert/alert.spec.ts +145 -0
- package/src/core/components/ui/alert/alert.ts +86 -91
- package/src/core/components/ui/alert-messages/alert-messages.ts +1 -1
- package/src/core/components/ui/badge/badge.md +126 -78
- package/src/core/components/ui/badge/badge.ts +29 -81
- package/src/core/components/ui/button/button.md +1 -0
- package/src/core/components/ui/button/button.ts +11 -8
- package/src/core/components/ui/card/card-header.ts +7 -2
- package/src/core/components/ui/card/card.md +120 -65
- package/src/core/components/ui/divider/divider.ts +4 -9
- package/src/core/components/ui/form/fieldset/legend-description.ts +1 -1
- package/src/core/components/ui/form/fieldset/legend.ts +1 -1
- package/src/core/components/ui/form/input/input.md +1 -1
- package/src/core/components/ui/form/input/input.ts +19 -15
- package/src/core/components/ui/form/textarea/textarea.md +1 -1
- package/src/core/components/ui/image/image.md +147 -53
- package/src/core/components/ui/image/image.ts +10 -44
- package/src/core/components/ui/link/link.md +2 -2
- package/src/core/components/ui/link/link.ts +42 -37
- package/src/core/components/ui/modal/modal-close.ts +8 -12
- package/src/core/components/ui/modal/modal.ts +18 -18
- package/src/core/components/ui/pop/pop.md +7 -5
- package/src/core/components/ui/pop/pop.ts +78 -38
- package/src/core/components/ui/table/table.ts +2 -8
- package/src/core/components/ui/toast/dismissed.ts +14 -0
- package/src/core/components/ui/toast/toast-item.ts +139 -91
- package/src/core/components/ui/toast/toast.ts +4 -7
- package/src/core/components/ui/tooltip/tooltip.ts +6 -8
- package/src/core/utils/LocationHandler.ts +12 -5
- package/src/core/utils/dismissed.ts +22 -0
- package/src/core/utils/positioning.spec.ts +28 -0
- package/src/core/utils/positioning.ts +19 -0
- package/src/docs/_getting-started/concorde-outside.md +3 -3
- package/src/docs/code.ts +3 -1
- package/src/docs/search/docs-search.json +541 -1
- package/src/docs/tailwind/css/tailwind.css +6 -0
- package/src/tsconfig.json +422 -383
- package/src/tsconfig.tsbuildinfo +1 -1
- 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
|
-
<
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
>
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
</
|
|
31
|
-
<
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
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
|
-
##
|
|
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
|
-
|
|
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
|
-
|
|
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
|
-
|
|
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-
|
|
11
|
-
|
|
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:
|
|
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
|
|
123
|
-
<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
|
|
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
|
|
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
|
|
2
|
-
|
|
3
|
-
|
|
4
|
-
import {
|
|
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:
|
|
15
|
-
display:
|
|
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
|
|
46
|
+
@property({ type: String, attribute: "data-aria-label" }) ariaLabel:
|
|
47
|
+
| string
|
|
48
|
+
| null = null;
|
|
31
49
|
|
|
32
50
|
/**
|
|
33
|
-
*
|
|
34
|
-
* - strict
|
|
35
|
-
* -
|
|
36
|
-
* -
|
|
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:
|
|
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(
|
|
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
|
-
|
|
90
|
-
|
|
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:
|
|
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
|
-
--
|
|
62
|
-
--
|
|
61
|
+
--sc-_backdrop-bg: var(
|
|
62
|
+
--sc-_overlay-bg,
|
|
63
63
|
var(--sc-base-200, rgba(0, 0, 0, 0.12))
|
|
64
64
|
);
|
|
65
|
-
--
|
|
66
|
-
--
|
|
67
|
-
--
|
|
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(--
|
|
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(--
|
|
90
|
+
z-index: var(--sc-_z-index);
|
|
91
91
|
}
|
|
92
92
|
|
|
93
93
|
#backdrop {
|
|
94
|
-
opacity: var(--
|
|
95
|
-
background: var(--
|
|
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(--
|
|
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(--
|
|
115
|
+
border-radius: var(--sc-_rounded) var(--sc-_rounded) 0 0 !important;
|
|
116
116
|
}
|
|
117
117
|
}
|
|
118
118
|
|
|
119
119
|
:host([fullScreen]) {
|
|
120
|
-
--
|
|
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
|
-
--
|
|
165
|
-
--
|
|
164
|
+
--sc-_top: 0.25rem;
|
|
165
|
+
--sc-_x: 0.25rem;
|
|
166
166
|
position: sticky;
|
|
167
167
|
display: block;
|
|
168
|
-
top: var(--
|
|
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("--
|
|
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("--
|
|
533
|
+
this.style.setProperty("--sc-_backdrop-opacity", "0.8");
|
|
534
534
|
} else {
|
|
535
535
|
setTimeout(() => {
|
|
536
|
-
this.style.setProperty("--
|
|
536
|
+
this.style.setProperty("--sc-_backdrop-opacity", "0");
|
|
537
537
|
}, 150);
|
|
538
538
|
}
|
|
539
539
|
}
|