@reliability-design/web 1.1.1 → 1.2.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.
- package/dist/components/rel-accordion/rel-accordion.ts +17 -32
- package/dist/components/rel-alert/rel-alert.ts +34 -34
- package/dist/components/rel-avatar/rel-avatar.ts +5 -3
- package/dist/components/rel-badge/rel-badge.ts +2 -1
- package/dist/components/rel-breadcrumb/rel-breadcrumb.ts +6 -6
- package/dist/components/rel-button/rel-button.ts +67 -21
- package/dist/components/rel-calendar/rel-calendar.ts +15 -8
- package/dist/components/rel-card/rel-card.ts +9 -17
- package/dist/components/rel-cardmedia/rel-cardmedia.ts +20 -23
- package/dist/components/rel-carousel/rel-carousel.ts +596 -468
- package/dist/components/rel-checkbox/rel-checkbox.ts +68 -16
- package/dist/components/rel-chip/rel-chip.ts +291 -244
- package/dist/components/rel-container/rel-container.ts +2 -2
- package/dist/components/rel-date-picker/rel-date-picker.ts +23 -19
- package/dist/components/rel-divider/rel-divider.ts +3 -3
- package/dist/components/rel-drawer/rel-drawer-footer.ts +0 -2
- package/dist/components/rel-drawer/rel-drawer.ts +41 -88
- package/dist/components/rel-kbd/rel-kbd.ts +94 -118
- package/dist/components/rel-layout/rel-layout.ts +49 -58
- package/dist/components/rel-menu/rel-menu.ts +359 -359
- package/dist/components/rel-menubar/rel-menubar-menu.css +3 -0
- package/dist/components/rel-menubar/rel-menubar-menu.ts +2 -1
- package/dist/components/rel-menubar/rel-menubar.ts +602 -605
- package/dist/components/rel-otp/rel-otp.ts +22 -25
- package/dist/components/rel-pagination/rel-pagination.ts +101 -57
- package/dist/components/rel-popover/rel-popover-content.ts +6 -5
- package/dist/components/rel-popover/rel-popover.ts +26 -7
- package/dist/components/rel-progress/rel-progress.ts +10 -9
- package/dist/components/rel-radio/rel-radio.ts +228 -172
- package/dist/components/rel-range-picker/rel-range-picker.css +349 -0
- package/dist/components/rel-range-picker/rel-range-picker.ts +1079 -0
- package/dist/components/rel-resizable/rel-resizable-handle.ts +8 -7
- package/dist/components/rel-segmented-button/rel-segmented-button.ts +41 -20
- package/dist/components/rel-select/rel-select.ts +103 -32
- package/dist/components/rel-sheet/rel-sheet.ts +362 -684
- package/dist/components/rel-slider/rel-slider.ts +49 -27
- package/dist/components/rel-snackbar/rel-snackbar.ts +28 -28
- package/dist/components/rel-stepper/rel-stepper.ts +11 -10
- package/dist/components/rel-switch/rel-switch.ts +7 -6
- package/dist/components/rel-tab/rel-tab.ts +15 -29
- package/dist/components/rel-textfield/rel-textfield.ts +144 -35
- package/dist/components/rel-toast/rel-toast.ts +25 -12
- package/dist/components/rel-tooltip/rel-tooltip.ts +123 -123
- package/dist/components/rel-topbar/rel-topbar-actions.ts +1 -0
- package/dist/components/rel-topbar/rel-topbar-brand.ts +1 -0
- package/dist/components/rel-topbar/rel-topbar-dropdown-item.ts +32 -2
- package/dist/components/rel-topbar/rel-topbar-dropdown.ts +1 -1
- package/dist/components/rel-topbar/rel-topbar-item.ts +15 -10
- package/dist/components/rel-topbar/rel-topbar-mobile-panel.ts +1 -0
- package/dist/components/rel-topbar/rel-topbar-profile.ts +30 -56
- package/dist/components/rel-topbar/rel-topbar-utilities.ts +1 -0
- package/dist/components/rel-topbar/rel-topbar.ts +137 -28
- package/dist/index.d.mts +153 -178
- package/dist/index.d.ts +153 -178
- package/dist/index.js +4711 -3875
- package/dist/index.js.map +1 -1
- package/dist/index.mjs +4047 -3202
- package/dist/index.mjs.map +1 -1
- package/dist/rel-menubar-menu-BEEQDAXW.css +3 -0
- package/dist/styles/vars-v2.css +525 -0
- package/dist/styles/vars.css +346 -346
- package/dist/{vars-TBB4BMSD.css → vars-I2PC74XD.css} +346 -346
- package/dist/vars-v2-VMGWTFJZ.css +525 -0
- package/package.json +2 -1
|
@@ -1,5 +1,7 @@
|
|
|
1
1
|
import { LitElement, html, css } from "lit";
|
|
2
2
|
import { customElement, property, state } from "lit/decorators.js";
|
|
3
|
+
import "../../styles/vars-v2.css";
|
|
4
|
+
import "@reliability-design/icons/rel-icon";
|
|
3
5
|
|
|
4
6
|
export type TextFieldState = "default" | "error" | "disabled";
|
|
5
7
|
export type TextFieldSize = "small" | "medium" | "large";
|
|
@@ -15,30 +17,106 @@ export class RelTextfield extends LitElement {
|
|
|
15
17
|
@property({ type: String }) supportingText?: string;
|
|
16
18
|
@property({ type: String }) state: TextFieldState = "default";
|
|
17
19
|
@property({ type: String }) size: TextFieldSize = "medium";
|
|
20
|
+
@property({ type: Boolean, reflect: true }) floatingLabel = false;
|
|
18
21
|
|
|
19
22
|
@state() private internalState: "default" | "focused" = "default";
|
|
23
|
+
private _wasError = false;
|
|
20
24
|
|
|
21
25
|
private uniqueId = `textfield-${Math.random().toString(36).slice(2)}`;
|
|
22
26
|
|
|
23
27
|
static styles = css`
|
|
24
28
|
:host {
|
|
25
29
|
display: block;
|
|
26
|
-
font-family: var(--rel-fontFamilies-primary
|
|
30
|
+
font-family: var(--rel-fontFamilies-primary);
|
|
27
31
|
}
|
|
28
32
|
|
|
29
33
|
/* Wrapper */
|
|
30
34
|
.textfield-wrapper {
|
|
31
35
|
display: flex;
|
|
32
36
|
flex-direction: column;
|
|
33
|
-
gap: var(--rel-spacing-space-2xs
|
|
37
|
+
gap: var(--rel-spacing-space-2xs);
|
|
34
38
|
width: 100%;
|
|
35
39
|
}
|
|
36
40
|
|
|
37
41
|
/* Label */
|
|
38
42
|
.textfield-label {
|
|
39
|
-
font-size: var(--rel-fontSizes-sm
|
|
40
|
-
font-weight: var(--rel-fontWeights-medium
|
|
41
|
-
color: var(--rel-text-heading
|
|
43
|
+
font-size: var(--rel-fontSizes-sm);
|
|
44
|
+
font-weight: var(--rel-fontWeights-medium);
|
|
45
|
+
color: var(--rel-color-text-heading);
|
|
46
|
+
}
|
|
47
|
+
|
|
48
|
+
/* Floating label variant */
|
|
49
|
+
:host([floatinglabel]) .textfield-wrapper {
|
|
50
|
+
gap: 0;
|
|
51
|
+
}
|
|
52
|
+
|
|
53
|
+
:host([floatinglabel]) .textfield-container {
|
|
54
|
+
overflow: visible;
|
|
55
|
+
position: relative;
|
|
56
|
+
padding-top: 0;
|
|
57
|
+
}
|
|
58
|
+
|
|
59
|
+
:host([floatinglabel]) .textfield-label {
|
|
60
|
+
position: absolute;
|
|
61
|
+
left: var(--rel-spacing-space-sm);
|
|
62
|
+
top: 50%;
|
|
63
|
+
transform: translateY(-50%);
|
|
64
|
+
font-size: var(--rel-fontSizes-md);
|
|
65
|
+
font-weight: var(--rel-fontWeights-regular);
|
|
66
|
+
color: var(--rel-color-text-placeholder);
|
|
67
|
+
pointer-events: none;
|
|
68
|
+
transition: top 0.15s ease, font-size 0.15s ease, color 0.15s ease, transform 0.15s ease;
|
|
69
|
+
background: var(--rel-color-bg-primary);
|
|
70
|
+
padding: 0 2px;
|
|
71
|
+
z-index: 1;
|
|
72
|
+
line-height: 1;
|
|
73
|
+
white-space: nowrap;
|
|
74
|
+
}
|
|
75
|
+
|
|
76
|
+
:host([floatinglabel]) .textfield-wrapper.focused .textfield-label,
|
|
77
|
+
:host([floatinglabel]) .textfield-wrapper.has-value .textfield-label {
|
|
78
|
+
top: 0;
|
|
79
|
+
transform: translateY(-50%);
|
|
80
|
+
font-size: var(--rel-fontSizes-xs);
|
|
81
|
+
color: var(--rel-color-text-primary);
|
|
82
|
+
}
|
|
83
|
+
|
|
84
|
+
:host([floatinglabel]) .textfield-wrapper.error .textfield-label {
|
|
85
|
+
color: var(--rel-error-text);
|
|
86
|
+
}
|
|
87
|
+
|
|
88
|
+
:host([floatinglabel]) .textfield-wrapper.focused:not(.error) .textfield-label {
|
|
89
|
+
color: var(--rel-color-text-primary);
|
|
90
|
+
}
|
|
91
|
+
|
|
92
|
+
:host([floatinglabel]) .textfield-wrapper.focused.error .textfield-label,
|
|
93
|
+
:host([floatinglabel]) .textfield-wrapper.has-value.error .textfield-label {
|
|
94
|
+
top: 0;
|
|
95
|
+
transform: translateY(-50%);
|
|
96
|
+
font-size: var(--rel-fontSizes-xs);
|
|
97
|
+
color: var(--rel-error-text);
|
|
98
|
+
}
|
|
99
|
+
|
|
100
|
+
:host([floatinglabel]) .textfield-input {
|
|
101
|
+
padding-top: var(--rel-spacing-space-sm);
|
|
102
|
+
padding-bottom: var(--rel-spacing-space-sm);
|
|
103
|
+
}
|
|
104
|
+
|
|
105
|
+
:host([floatinglabel]) .textfield-input.has-left-icon {
|
|
106
|
+
padding-left: var(--rel-spacing-space-2xl);
|
|
107
|
+
}
|
|
108
|
+
|
|
109
|
+
:host([floatinglabel]) .textfield-label.has-left-icon {
|
|
110
|
+
left: var(--rel-spacing-space-2xl);
|
|
111
|
+
}
|
|
112
|
+
|
|
113
|
+
:host([floatinglabel]) .textfield-wrapper.focused .textfield-label.has-left-icon,
|
|
114
|
+
:host([floatinglabel]) .textfield-wrapper.has-value .textfield-label.has-left-icon {
|
|
115
|
+
left: var(--rel-spacing-space-sm);
|
|
116
|
+
}
|
|
117
|
+
|
|
118
|
+
:host([floatinglabel]) .textfield-wrapper.disabled .textfield-label {
|
|
119
|
+
background: var(--rel-color-bg-tertiary);
|
|
42
120
|
}
|
|
43
121
|
|
|
44
122
|
/* Container */
|
|
@@ -46,14 +124,15 @@ export class RelTextfield extends LitElement {
|
|
|
46
124
|
display: flex;
|
|
47
125
|
align-items: center;
|
|
48
126
|
position: relative;
|
|
49
|
-
border: 1px solid var(--rel-border-default
|
|
50
|
-
border-radius: var(--rel-borders-radius-border-radius-
|
|
51
|
-
background: var(--rel-
|
|
127
|
+
border: 1px solid var(--rel-color-border-default);
|
|
128
|
+
border-radius: var(--rel-borders-radius-border-radius-100);
|
|
129
|
+
background: var(--rel-color-bg-primary);
|
|
130
|
+
overflow: hidden;
|
|
52
131
|
transition: border 0.2s;
|
|
53
132
|
}
|
|
54
133
|
|
|
55
134
|
.textfield-container.disabled {
|
|
56
|
-
background: var(--rel-
|
|
135
|
+
background: var(--rel-color-bg-tertiary);
|
|
57
136
|
cursor: not-allowed;
|
|
58
137
|
}
|
|
59
138
|
|
|
@@ -62,23 +141,23 @@ export class RelTextfield extends LitElement {
|
|
|
62
141
|
flex: 1;
|
|
63
142
|
border: none;
|
|
64
143
|
outline: none;
|
|
65
|
-
font-size: var(--rel-fontSizes-md
|
|
66
|
-
padding: var(--rel-spacing-space-xs
|
|
144
|
+
font-size: var(--rel-fontSizes-md);
|
|
145
|
+
padding: var(--rel-spacing-space-xs) var(--rel-spacing-space-sm);
|
|
67
146
|
background: transparent;
|
|
68
|
-
font-family: var(--rel-fontFamilies-primary
|
|
69
|
-
color: var(--rel-text-primary
|
|
147
|
+
font-family: var(--rel-fontFamilies-primary);
|
|
148
|
+
color: var(--rel-color-text-primary);
|
|
70
149
|
}
|
|
71
150
|
|
|
72
151
|
.textfield-input:disabled {
|
|
73
152
|
cursor: not-allowed;
|
|
74
|
-
color: var(--rel-text-disabled
|
|
153
|
+
color: var(--rel-color-text-disabled);
|
|
75
154
|
}
|
|
76
155
|
|
|
77
156
|
.icon {
|
|
78
157
|
position: absolute;
|
|
79
158
|
display: flex;
|
|
80
159
|
pointer-events: none;
|
|
81
|
-
color: var(--rel-text-placeholder
|
|
160
|
+
color: var(--rel-color-text-placeholder);
|
|
82
161
|
}
|
|
83
162
|
|
|
84
163
|
.icon.left {
|
|
@@ -90,32 +169,32 @@ export class RelTextfield extends LitElement {
|
|
|
90
169
|
}
|
|
91
170
|
|
|
92
171
|
.textfield-wrapper.small .textfield-input {
|
|
93
|
-
padding: var(--rel-spacing-space-xs
|
|
94
|
-
font-size: var(--rel-fontSizes-sm
|
|
172
|
+
padding: var(--rel-spacing-space-xs) var(--rel-spacing-space-sm);
|
|
173
|
+
font-size: var(--rel-fontSizes-sm);
|
|
95
174
|
}
|
|
96
175
|
|
|
97
176
|
.textfield-wrapper.medium .textfield-input {
|
|
98
|
-
padding: var(--rel-spacing-space-sm
|
|
99
|
-
font-size: var(--rel-fontSizes-md
|
|
177
|
+
padding: var(--rel-spacing-space-sm) var(--rel-spacing-space-md);
|
|
178
|
+
font-size: var(--rel-fontSizes-md);
|
|
100
179
|
}
|
|
101
180
|
|
|
102
181
|
.textfield-wrapper.large .textfield-input {
|
|
103
|
-
padding: var(--rel-spacing-space-md
|
|
104
|
-
font-size: var(--rel-fontSizes-lg
|
|
182
|
+
padding: var(--rel-spacing-space-md) var(--rel-spacing-space-md);
|
|
183
|
+
font-size: var(--rel-fontSizes-lg);
|
|
105
184
|
}
|
|
106
185
|
|
|
107
186
|
/* Adjust padding when icons are present */
|
|
108
187
|
.textfield-wrapper .textfield-input.has-left-icon {
|
|
109
|
-
padding-left: var(--rel-spacing-space-2xl
|
|
188
|
+
padding-left: var(--rel-spacing-space-2xl);
|
|
110
189
|
}
|
|
111
190
|
|
|
112
191
|
.textfield-wrapper .textfield-input.has-right-icon {
|
|
113
|
-
padding-right: var(--rel-spacing-space-2xl
|
|
192
|
+
padding-right: var(--rel-spacing-space-2xl);
|
|
114
193
|
}
|
|
115
194
|
|
|
116
195
|
/* States */
|
|
117
196
|
.textfield-wrapper.focused .textfield-container {
|
|
118
|
-
border-color: var(--rel-
|
|
197
|
+
border-color: var(--rel-color-text-primary);
|
|
119
198
|
}
|
|
120
199
|
|
|
121
200
|
.textfield-input:focus-visible {
|
|
@@ -124,34 +203,51 @@ export class RelTextfield extends LitElement {
|
|
|
124
203
|
|
|
125
204
|
.textfield-wrapper.focused .textfield-container,
|
|
126
205
|
.textfield-container:focus-within {
|
|
127
|
-
border-color: var(--rel-
|
|
128
|
-
box-shadow: 0 0 0 1px var(--rel-
|
|
206
|
+
border-color: var(--rel-color-text-primary);
|
|
207
|
+
box-shadow: 0 0 0 1px var(--rel-color-text-primary);
|
|
129
208
|
}
|
|
130
209
|
|
|
131
210
|
.textfield-wrapper.error .textfield-container {
|
|
132
|
-
border-color: var(--rel-
|
|
211
|
+
border-color: var(--rel-error-surface-default);
|
|
212
|
+
box-shadow: none;
|
|
133
213
|
}
|
|
134
214
|
|
|
135
215
|
.textfield-wrapper.disabled .textfield-container {
|
|
136
|
-
border-color: var(--rel-border-default
|
|
216
|
+
border-color: var(--rel-color-border-default);
|
|
137
217
|
}
|
|
138
218
|
|
|
139
219
|
/* Supporting text */
|
|
140
220
|
.textfield-support {
|
|
141
|
-
font-size: var(--rel-fontSizes-xs
|
|
142
|
-
color: var(--rel-text-placeholder
|
|
221
|
+
font-size: var(--rel-fontSizes-xs);
|
|
222
|
+
color: var(--rel-color-text-placeholder);
|
|
143
223
|
}
|
|
144
224
|
|
|
145
225
|
.textfield-support.error {
|
|
146
|
-
color: var(--rel-text
|
|
226
|
+
color: var(--rel-error-text);
|
|
147
227
|
}
|
|
148
228
|
|
|
149
229
|
/* Placeholder */
|
|
150
230
|
.textfield-input::placeholder {
|
|
151
|
-
color: var(--rel-text-placeholder
|
|
231
|
+
color: var(--rel-color-text-placeholder);
|
|
232
|
+
}
|
|
233
|
+
|
|
234
|
+
/* Suppress Chrome autofill blue background */
|
|
235
|
+
.textfield-input:-webkit-autofill,
|
|
236
|
+
.textfield-input:-webkit-autofill:hover,
|
|
237
|
+
.textfield-input:-webkit-autofill:focus {
|
|
238
|
+
-webkit-box-shadow: 0 0 0px 1000px var(--rel-color-bg-primary) inset;
|
|
239
|
+
-webkit-text-fill-color: var(--rel-color-text-primary);
|
|
152
240
|
}
|
|
153
241
|
`;
|
|
154
242
|
|
|
243
|
+
connectedCallback() {
|
|
244
|
+
super.connectedCallback();
|
|
245
|
+
const leftIcon = this.getAttribute('lefticon') || this.getAttribute('leftIcon');
|
|
246
|
+
if (leftIcon) this.leftIcon = leftIcon;
|
|
247
|
+
const rightIcon = this.getAttribute('righticon') || this.getAttribute('rightIcon');
|
|
248
|
+
if (rightIcon) this.rightIcon = rightIcon;
|
|
249
|
+
}
|
|
250
|
+
|
|
155
251
|
private handleFocus() {
|
|
156
252
|
if (this.state !== "disabled") {
|
|
157
253
|
this.internalState = "focused";
|
|
@@ -167,6 +263,13 @@ export class RelTextfield extends LitElement {
|
|
|
167
263
|
private handleInput(e: Event) {
|
|
168
264
|
const input = e.target as HTMLInputElement;
|
|
169
265
|
this.value = input.value;
|
|
266
|
+
if (this.state === "error" && this.value) {
|
|
267
|
+
this._wasError = true;
|
|
268
|
+
this.state = "default";
|
|
269
|
+
} else if (this._wasError && !this.value) {
|
|
270
|
+
this._wasError = false;
|
|
271
|
+
this.state = "error";
|
|
272
|
+
}
|
|
170
273
|
this.dispatchEvent(
|
|
171
274
|
new CustomEvent<string>("rel-change", {
|
|
172
275
|
detail: this.value,
|
|
@@ -182,6 +285,7 @@ export class RelTextfield extends LitElement {
|
|
|
182
285
|
this.size,
|
|
183
286
|
this.state,
|
|
184
287
|
this.internalState === "focused" ? "focused" : "",
|
|
288
|
+
this.value ? "has-value" : "",
|
|
185
289
|
].filter(Boolean).join(" ");
|
|
186
290
|
|
|
187
291
|
const inputClasses = [
|
|
@@ -194,7 +298,7 @@ export class RelTextfield extends LitElement {
|
|
|
194
298
|
|
|
195
299
|
return html`
|
|
196
300
|
<div class="${wrapperClasses}">
|
|
197
|
-
${this.label
|
|
301
|
+
${!this.floatingLabel && this.label
|
|
198
302
|
? html`<label class="textfield-label" for="${this.uniqueId}">${this.label}</label>`
|
|
199
303
|
: ""}
|
|
200
304
|
|
|
@@ -203,8 +307,13 @@ export class RelTextfield extends LitElement {
|
|
|
203
307
|
? "disabled"
|
|
204
308
|
: ""}"
|
|
205
309
|
>
|
|
310
|
+
${this.floatingLabel && this.label
|
|
311
|
+
? html`<label
|
|
312
|
+
class="textfield-label${this.leftIcon ? ' has-left-icon' : ''}"
|
|
313
|
+
for="${this.uniqueId}">${this.label}</label>`
|
|
314
|
+
: ""}
|
|
206
315
|
${this.leftIcon
|
|
207
|
-
? html`<
|
|
316
|
+
? html`<rel-icon name="${this.leftIcon}" size="sm" class="icon left"></rel-icon>`
|
|
208
317
|
: ""}
|
|
209
318
|
|
|
210
319
|
<input
|
|
@@ -221,7 +330,7 @@ export class RelTextfield extends LitElement {
|
|
|
221
330
|
/>
|
|
222
331
|
|
|
223
332
|
${this.rightIcon
|
|
224
|
-
? html`<
|
|
333
|
+
? html`<rel-icon name="${this.rightIcon}" size="sm" class="icon right"></rel-icon>`
|
|
225
334
|
: ""}
|
|
226
335
|
</div>
|
|
227
336
|
|
|
@@ -1,5 +1,6 @@
|
|
|
1
1
|
import { LitElement, html, css } from "lit";
|
|
2
2
|
import { customElement, property, state } from "lit/decorators.js";
|
|
3
|
+
import "../../styles/vars-v2.css";
|
|
3
4
|
|
|
4
5
|
export type ToastType = "default" | "error";
|
|
5
6
|
|
|
@@ -32,20 +33,20 @@ export class RelToast extends LitElement {
|
|
|
32
33
|
.toast {
|
|
33
34
|
display: inline-flex;
|
|
34
35
|
align-items: center;
|
|
35
|
-
gap: var(--rel-spacing-space-sm
|
|
36
|
-
background-color: var(--rel-
|
|
37
|
-
color: var(--rel-
|
|
38
|
-
font-family: var(--rel-fontFamilies-primary
|
|
39
|
-
font-size: var(--rel-fontSizes-md
|
|
40
|
-
border-radius: var(--rel-borders-radius-border-radius-200
|
|
41
|
-
padding: var(--rel-spacing-space-md
|
|
36
|
+
gap: var(--rel-spacing-space-sm);
|
|
37
|
+
background-color: var(--rel-color-text-primary);
|
|
38
|
+
color: var(--rel-color-bg-primary);
|
|
39
|
+
font-family: var(--rel-fontFamilies-primary);
|
|
40
|
+
font-size: var(--rel-fontSizes-md);
|
|
41
|
+
border-radius: var(--rel-borders-radius-border-radius-200);
|
|
42
|
+
padding: var(--rel-spacing-space-md);
|
|
42
43
|
box-shadow: var(--rel-shadows-shadow-300);
|
|
43
44
|
pointer-events: all;
|
|
44
45
|
animation: fadeInUp 0.25s ease;
|
|
45
46
|
}
|
|
46
47
|
|
|
47
48
|
.toast.error {
|
|
48
|
-
background-color: var(--rel-
|
|
49
|
+
background-color: var(--rel-error-surface-default);
|
|
49
50
|
}
|
|
50
51
|
|
|
51
52
|
.toast.hidden {
|
|
@@ -74,7 +75,7 @@ export class RelToast extends LitElement {
|
|
|
74
75
|
}
|
|
75
76
|
|
|
76
77
|
.toast-action:focus-visible {
|
|
77
|
-
outline: 2px solid
|
|
78
|
+
outline: 2px solid #FFFFFF;
|
|
78
79
|
outline-offset: 2px;
|
|
79
80
|
border-radius: 2px;
|
|
80
81
|
}
|
|
@@ -87,8 +88,8 @@ export class RelToast extends LitElement {
|
|
|
87
88
|
font-size: 1rem;
|
|
88
89
|
cursor: pointer;
|
|
89
90
|
line-height: 1;
|
|
90
|
-
padding: var(--rel-spacing-space-2xs
|
|
91
|
-
margin-left: var(--rel-spacing-space-2xs
|
|
91
|
+
padding: var(--rel-spacing-space-2xs);
|
|
92
|
+
margin-left: var(--rel-spacing-space-2xs);
|
|
92
93
|
}
|
|
93
94
|
|
|
94
95
|
.toast-close:hover {
|
|
@@ -96,11 +97,23 @@ export class RelToast extends LitElement {
|
|
|
96
97
|
}
|
|
97
98
|
|
|
98
99
|
.toast-close:focus-visible {
|
|
99
|
-
outline: 2px solid
|
|
100
|
+
outline: 2px solid #FFFFFF;
|
|
100
101
|
outline-offset: 2px;
|
|
101
102
|
border-radius: 2px;
|
|
102
103
|
}
|
|
103
104
|
|
|
105
|
+
/* Dark mode overrides */
|
|
106
|
+
:host-context([data-theme="dark"]) .toast-action,
|
|
107
|
+
:host-context(.dark) .toast-action {
|
|
108
|
+
color: var(--rel-colors-green-tertiary);
|
|
109
|
+
}
|
|
110
|
+
|
|
111
|
+
:host-context([data-theme="dark"]) .toast.error,
|
|
112
|
+
:host-context(.dark) .toast.error {
|
|
113
|
+
background-color: var(--rel-error-surface-default);
|
|
114
|
+
color: #ffffff;
|
|
115
|
+
}
|
|
116
|
+
|
|
104
117
|
@media (prefers-reduced-motion: reduce) {
|
|
105
118
|
.toast {
|
|
106
119
|
animation: none;
|
|
@@ -1,123 +1,123 @@
|
|
|
1
|
-
import { LitElement, html, css } from "lit";
|
|
2
|
-
import { customElement, property } from "lit/decorators.js";
|
|
3
|
-
|
|
4
|
-
export type TooltipPosition = "above" | "below";
|
|
5
|
-
|
|
6
|
-
@customElement("rel-tooltip")
|
|
7
|
-
export class RelTooltip extends LitElement {
|
|
8
|
-
@property({ type: String }) text: string = "";
|
|
9
|
-
@property({ type: String }) position: TooltipPosition = "above";
|
|
10
|
-
@property({ type: Boolean, attribute: "show-tail" }) showTail: boolean =
|
|
11
|
-
false;
|
|
12
|
-
|
|
13
|
-
// Stable id so aria-describedby can reference the bubble across renders.
|
|
14
|
-
private uniqueId = Math.random().toString(36).slice(2);
|
|
15
|
-
|
|
16
|
-
static styles = css`
|
|
17
|
-
:host {
|
|
18
|
-
display: inline-block;
|
|
19
|
-
position: relative;
|
|
20
|
-
}
|
|
21
|
-
|
|
22
|
-
/* Tooltip container */
|
|
23
|
-
.tooltip-bubble {
|
|
24
|
-
position: absolute;
|
|
25
|
-
left: 50%;
|
|
26
|
-
transform: translateX(-50%);
|
|
27
|
-
background-color: #1a1a1a;
|
|
28
|
-
color: #ffffff;
|
|
29
|
-
padding: var(--rel-spacing-space-xs, 8px)
|
|
30
|
-
var(--rel-spacing-space-sm, 12px);
|
|
31
|
-
border-radius: var(--rel-borders-radius-border-radius-200, 8px);
|
|
32
|
-
font-size: var(--rel-fontSizes-sm, 12px);
|
|
33
|
-
font-family: var(--rel-fontFamilies-primary, sans-serif);
|
|
34
|
-
white-space: nowrap;
|
|
35
|
-
z-index: 1000;
|
|
36
|
-
opacity: 0;
|
|
37
|
-
pointer-events: none;
|
|
38
|
-
transition: opacity 0.2s ease;
|
|
39
|
-
overflow: visible;
|
|
40
|
-
}
|
|
41
|
-
|
|
42
|
-
:host(:hover) .tooltip-bubble,
|
|
43
|
-
:host(:focus-within) .tooltip-bubble {
|
|
44
|
-
opacity: 1;
|
|
45
|
-
}
|
|
46
|
-
|
|
47
|
-
/* Positioning */
|
|
48
|
-
.tooltip-bubble.above {
|
|
49
|
-
bottom: calc(100% + 8px);
|
|
50
|
-
}
|
|
51
|
-
|
|
52
|
-
.tooltip-bubble.below {
|
|
53
|
-
top: calc(100% + 8px);
|
|
54
|
-
}
|
|
55
|
-
|
|
56
|
-
/* Tail/Arrow */
|
|
57
|
-
.tooltip-tail {
|
|
58
|
-
position: absolute;
|
|
59
|
-
left: 50%;
|
|
60
|
-
transform: translateX(-50%);
|
|
61
|
-
width: 0;
|
|
62
|
-
height: 0;
|
|
63
|
-
border-left: 6px solid transparent;
|
|
64
|
-
border-right: 6px solid transparent;
|
|
65
|
-
display: block;
|
|
66
|
-
}
|
|
67
|
-
|
|
68
|
-
.tooltip-bubble.above .tooltip-tail {
|
|
69
|
-
bottom: -6px;
|
|
70
|
-
border-top: 6px solid #1a1a1a;
|
|
71
|
-
border-bottom: none;
|
|
72
|
-
}
|
|
73
|
-
|
|
74
|
-
.tooltip-bubble.below .tooltip-tail {
|
|
75
|
-
top: -6px;
|
|
76
|
-
border-bottom: 6px solid #1a1a1a;
|
|
77
|
-
border-top: none;
|
|
78
|
-
}
|
|
79
|
-
|
|
80
|
-
:host-context([data-theme="dark"]) .tooltip-bubble,
|
|
81
|
-
:host-context(.dark) .tooltip-bubble {
|
|
82
|
-
background-color: #ffffff;
|
|
83
|
-
color: #000000;
|
|
84
|
-
}
|
|
85
|
-
|
|
86
|
-
:host-context([data-theme="dark"]) .tooltip-bubble.above .tooltip-tail,
|
|
87
|
-
:host-context(.dark) .tooltip-bubble.above .tooltip-tail {
|
|
88
|
-
border-top-color: #ffffff;
|
|
89
|
-
}
|
|
90
|
-
|
|
91
|
-
:host-context([data-theme="dark"]) .tooltip-bubble.below .tooltip-tail,
|
|
92
|
-
:host-context(.dark) .tooltip-bubble.below .tooltip-tail {
|
|
93
|
-
border-bottom-color: #ffffff;
|
|
94
|
-
}
|
|
95
|
-
`;
|
|
96
|
-
|
|
97
|
-
firstUpdated() {
|
|
98
|
-
this.linkTrigger();
|
|
99
|
-
}
|
|
100
|
-
|
|
101
|
-
private linkTrigger() {
|
|
102
|
-
const slot = this.shadowRoot?.querySelector("slot");
|
|
103
|
-
if (!slot) return;
|
|
104
|
-
const trigger = slot.assignedElements()[0];
|
|
105
|
-
if (trigger) {
|
|
106
|
-
trigger.setAttribute("aria-describedby", `tooltip-${this.uniqueId}`);
|
|
107
|
-
}
|
|
108
|
-
}
|
|
109
|
-
|
|
110
|
-
render() {
|
|
111
|
-
return html`
|
|
112
|
-
<slot @slotchange="${this.linkTrigger}"></slot>
|
|
113
|
-
<div
|
|
114
|
-
class="tooltip-bubble ${this.position}"
|
|
115
|
-
id="tooltip-${this.uniqueId}"
|
|
116
|
-
role="tooltip"
|
|
117
|
-
>
|
|
118
|
-
${this.text}
|
|
119
|
-
${this.showTail ? html`<span class="tooltip-tail"></span>` : ""}
|
|
120
|
-
</div>
|
|
121
|
-
`;
|
|
122
|
-
}
|
|
123
|
-
}
|
|
1
|
+
import { LitElement, html, css } from "lit";
|
|
2
|
+
import { customElement, property } from "lit/decorators.js";
|
|
3
|
+
|
|
4
|
+
export type TooltipPosition = "above" | "below";
|
|
5
|
+
|
|
6
|
+
@customElement("rel-tooltip")
|
|
7
|
+
export class RelTooltip extends LitElement {
|
|
8
|
+
@property({ type: String }) text: string = "";
|
|
9
|
+
@property({ type: String }) position: TooltipPosition = "above";
|
|
10
|
+
@property({ type: Boolean, attribute: "show-tail" }) showTail: boolean =
|
|
11
|
+
false;
|
|
12
|
+
|
|
13
|
+
// Stable id so aria-describedby can reference the bubble across renders.
|
|
14
|
+
private uniqueId = Math.random().toString(36).slice(2);
|
|
15
|
+
|
|
16
|
+
static styles = css`
|
|
17
|
+
:host {
|
|
18
|
+
display: inline-block;
|
|
19
|
+
position: relative;
|
|
20
|
+
}
|
|
21
|
+
|
|
22
|
+
/* Tooltip container */
|
|
23
|
+
.tooltip-bubble {
|
|
24
|
+
position: absolute;
|
|
25
|
+
left: 50%;
|
|
26
|
+
transform: translateX(-50%);
|
|
27
|
+
background-color: #1a1a1a;
|
|
28
|
+
color: #ffffff;
|
|
29
|
+
padding: var(--rel-spacing-space-xs, 8px)
|
|
30
|
+
var(--rel-spacing-space-sm, 12px);
|
|
31
|
+
border-radius: var(--rel-borders-radius-border-radius-200, 8px);
|
|
32
|
+
font-size: var(--rel-fontSizes-sm, 12px);
|
|
33
|
+
font-family: var(--rel-fontFamilies-primary, sans-serif);
|
|
34
|
+
white-space: nowrap;
|
|
35
|
+
z-index: 1000;
|
|
36
|
+
opacity: 0;
|
|
37
|
+
pointer-events: none;
|
|
38
|
+
transition: opacity 0.2s ease;
|
|
39
|
+
overflow: visible;
|
|
40
|
+
}
|
|
41
|
+
|
|
42
|
+
:host(:hover) .tooltip-bubble,
|
|
43
|
+
:host(:focus-within) .tooltip-bubble {
|
|
44
|
+
opacity: 1;
|
|
45
|
+
}
|
|
46
|
+
|
|
47
|
+
/* Positioning */
|
|
48
|
+
.tooltip-bubble.above {
|
|
49
|
+
bottom: calc(100% + 8px);
|
|
50
|
+
}
|
|
51
|
+
|
|
52
|
+
.tooltip-bubble.below {
|
|
53
|
+
top: calc(100% + 8px);
|
|
54
|
+
}
|
|
55
|
+
|
|
56
|
+
/* Tail/Arrow */
|
|
57
|
+
.tooltip-tail {
|
|
58
|
+
position: absolute;
|
|
59
|
+
left: 50%;
|
|
60
|
+
transform: translateX(-50%);
|
|
61
|
+
width: 0;
|
|
62
|
+
height: 0;
|
|
63
|
+
border-left: 6px solid transparent;
|
|
64
|
+
border-right: 6px solid transparent;
|
|
65
|
+
display: block;
|
|
66
|
+
}
|
|
67
|
+
|
|
68
|
+
.tooltip-bubble.above .tooltip-tail {
|
|
69
|
+
bottom: -6px;
|
|
70
|
+
border-top: 6px solid #1a1a1a;
|
|
71
|
+
border-bottom: none;
|
|
72
|
+
}
|
|
73
|
+
|
|
74
|
+
.tooltip-bubble.below .tooltip-tail {
|
|
75
|
+
top: -6px;
|
|
76
|
+
border-bottom: 6px solid #1a1a1a;
|
|
77
|
+
border-top: none;
|
|
78
|
+
}
|
|
79
|
+
|
|
80
|
+
:host-context([data-theme="dark"]) .tooltip-bubble,
|
|
81
|
+
:host-context(.dark) .tooltip-bubble {
|
|
82
|
+
background-color: #ffffff;
|
|
83
|
+
color: #000000;
|
|
84
|
+
}
|
|
85
|
+
|
|
86
|
+
:host-context([data-theme="dark"]) .tooltip-bubble.above .tooltip-tail,
|
|
87
|
+
:host-context(.dark) .tooltip-bubble.above .tooltip-tail {
|
|
88
|
+
border-top-color: #ffffff;
|
|
89
|
+
}
|
|
90
|
+
|
|
91
|
+
:host-context([data-theme="dark"]) .tooltip-bubble.below .tooltip-tail,
|
|
92
|
+
:host-context(.dark) .tooltip-bubble.below .tooltip-tail {
|
|
93
|
+
border-bottom-color: #ffffff;
|
|
94
|
+
}
|
|
95
|
+
`;
|
|
96
|
+
|
|
97
|
+
firstUpdated() {
|
|
98
|
+
this.linkTrigger();
|
|
99
|
+
}
|
|
100
|
+
|
|
101
|
+
private linkTrigger() {
|
|
102
|
+
const slot = this.shadowRoot?.querySelector("slot");
|
|
103
|
+
if (!slot) return;
|
|
104
|
+
const trigger = slot.assignedElements()[0];
|
|
105
|
+
if (trigger) {
|
|
106
|
+
trigger.setAttribute("aria-describedby", `tooltip-${this.uniqueId}`);
|
|
107
|
+
}
|
|
108
|
+
}
|
|
109
|
+
|
|
110
|
+
render() {
|
|
111
|
+
return html`
|
|
112
|
+
<slot @slotchange="${this.linkTrigger}"></slot>
|
|
113
|
+
<div
|
|
114
|
+
class="tooltip-bubble ${this.position}"
|
|
115
|
+
id="tooltip-${this.uniqueId}"
|
|
116
|
+
role="tooltip"
|
|
117
|
+
>
|
|
118
|
+
${this.text}
|
|
119
|
+
${this.showTail ? html`<span class="tooltip-tail"></span>` : ""}
|
|
120
|
+
</div>
|
|
121
|
+
`;
|
|
122
|
+
}
|
|
123
|
+
}
|