@latty-ds/web 0.10.4 → 1.0.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/custom-elements.json +1969 -228
- package/dist/components/accordion/index.js +36 -2
- package/dist/components/alert/alert.d.ts +29 -6
- package/dist/components/alert/alert.types.d.ts +5 -0
- package/dist/components/alert/index.js +124 -17
- package/dist/components/avatar/avatar.d.ts +2 -0
- package/dist/components/avatar/index.js +10 -3
- package/dist/components/breadcrumb/breadcrumb.d.ts +4 -0
- package/dist/components/breadcrumb/breadcrumb.types.d.ts +5 -0
- package/dist/components/breadcrumb/index.js +20 -3
- package/dist/components/button/button.d.ts +33 -0
- package/dist/components/button/index.js +135 -12
- package/dist/components/calendar/calendar.d.ts +15 -7
- package/dist/components/calendar/calendar.types.d.ts +17 -1
- package/dist/components/calendar/index.js +78 -25
- package/dist/components/checkbox/checkbox.d.ts +14 -2
- package/dist/components/checkbox/checkbox.types.d.ts +5 -0
- package/dist/components/checkbox/index.js +82 -5
- package/dist/components/chip/chip.d.ts +4 -1
- package/dist/components/chip/chip.types.d.ts +5 -0
- package/dist/components/chip/index.js +29 -1
- package/dist/components/color-input/color-input.d.ts +11 -2
- package/dist/components/color-input/color-input.types.d.ts +5 -0
- package/dist/components/color-input/index.js +92 -8
- package/dist/components/combobox/combobox.d.ts +18 -2
- package/dist/components/combobox/combobox.types.d.ts +7 -0
- package/dist/components/combobox/index.js +164 -23
- package/dist/components/date-input/date-input.d.ts +22 -7
- package/dist/components/date-input/date-input.types.d.ts +7 -0
- package/dist/components/date-input/index.js +216 -53
- package/dist/components/datepicker/datepicker.d.ts +9 -1
- package/dist/components/datepicker/index.js +108 -15
- package/dist/components/dialog/dialog.d.ts +39 -19
- package/dist/components/dialog/dialog.types.d.ts +5 -0
- package/dist/components/dialog/index.js +237 -90
- package/dist/components/divider/index.js +2 -2
- package/dist/components/dropdown/dropdown.d.ts +4 -0
- package/dist/components/dropdown/index.js +43 -3
- package/dist/components/icon-button/icon-button.d.ts +4 -0
- package/dist/components/icon-button/index.js +36 -1
- package/dist/components/image/image.d.ts +7 -7
- package/dist/components/image/index.js +6 -11
- package/dist/components/list/index.js +14 -4
- package/dist/components/nav/index.js +37 -17
- package/dist/components/nav/nav-item.d.ts +8 -8
- package/dist/components/pagination/index.js +57 -16
- package/dist/components/pagination/pagination.d.ts +8 -1
- package/dist/components/pagination/pagination.types.d.ts +15 -0
- package/dist/components/progress/index.js +44 -6
- package/dist/components/progress/progress.d.ts +12 -0
- package/dist/components/radio/index.js +148 -9
- package/dist/components/radio/radio.d.ts +34 -2
- package/dist/components/radio/radio.types.d.ts +5 -0
- package/dist/components/radio-group/index.js +120 -29
- package/dist/components/radio-group/radio-group.d.ts +27 -2
- package/dist/components/select/index.js +197 -44
- package/dist/components/select/select.d.ts +38 -4
- package/dist/components/select/select.types.d.ts +5 -0
- package/dist/components/shared/aria-forwarding.d.ts +1 -1
- package/dist/components/shared/form-default.d.ts +30 -0
- package/dist/components/shared/form-disabled.d.ts +40 -0
- package/dist/components/shared/form-field.d.ts +7 -0
- package/dist/components/shared/form-validity.d.ts +17 -0
- package/dist/components/shared/roving.d.ts +11 -0
- package/dist/components/shared/scroll-lock.d.ts +2 -0
- package/dist/components/sidepanel/index.js +275 -72
- package/dist/components/sidepanel/sidepanel.d.ts +32 -10
- package/dist/components/sidepanel/sidepanel.types.d.ts +10 -1
- package/dist/components/skeleton/index.js +3 -8
- package/dist/components/slider/index.js +307 -75
- package/dist/components/slider/slider.d.ts +16 -3
- package/dist/components/snackbar/index.js +82 -9
- package/dist/components/snackbar/snackbar.d.ts +17 -1
- package/dist/components/snackbar/snackbar.types.d.ts +5 -0
- package/dist/components/surface/index.js +8 -0
- package/dist/components/switch/index.js +101 -5
- package/dist/components/switch/switch.d.ts +13 -2
- package/dist/components/switch/switch.types.d.ts +5 -0
- package/dist/components/tab/index.js +15 -14
- package/dist/components/tab/tab.d.ts +0 -1
- package/dist/components/tab-group/index.js +102 -30
- package/dist/components/tab-group/tab-group.d.ts +17 -2
- package/dist/components/table/index.js +105 -61
- package/dist/components/table/table.d.ts +8 -2
- package/dist/components/table/table.types.d.ts +4 -3
- package/dist/components/text/index.js +16 -1
- package/dist/components/text/text.d.ts +1 -1
- package/dist/components/textfield/index.js +243 -35
- package/dist/components/textfield/textfield.d.ts +24 -2
- package/dist/components/textfield/textfield.types.d.ts +11 -0
- package/dist/components/tooltip/index.js +176 -49
- package/dist/components/tooltip/tooltip.d.ts +17 -0
- package/dist/components/tooltip/tooltip.types.d.ts +5 -1
- package/dist/index.cjs +2458 -683
- package/dist/index.js +2469 -690
- package/dist/manifest.json +202 -32
- package/dist/utils/dev-warn.d.ts +5 -0
- package/dist/utils/index.d.ts +1 -0
- package/package.json +3 -7
|
@@ -34,6 +34,13 @@ __decorateClass([
|
|
|
34
34
|
property({ reflect: true })
|
|
35
35
|
], ThemeableElement.prototype, "theme", 2);
|
|
36
36
|
|
|
37
|
+
// src/utils/dev-warn.ts
|
|
38
|
+
var devWarn = (tag, message) => {
|
|
39
|
+
if (typeof process !== "undefined" && process.env.NODE_ENV !== "production") {
|
|
40
|
+
console.warn(`[${tag}] ${message}`);
|
|
41
|
+
}
|
|
42
|
+
};
|
|
43
|
+
|
|
37
44
|
// src/components/checkbox/checkbox.ts
|
|
38
45
|
import { customElement, property as property2, query } from "lit/decorators.js";
|
|
39
46
|
|
|
@@ -62,7 +69,10 @@ var checkboxStyles = css`
|
|
|
62
69
|
flex-direction: row-reverse;
|
|
63
70
|
}
|
|
64
71
|
|
|
65
|
-
:host(
|
|
72
|
+
/* :host(:disabled) — the browser matches this automatically for a form-associated element inside a
|
|
73
|
+
disabled <fieldset>, no JS required; :host([disabled]) covers the component's own explicit attribute. */
|
|
74
|
+
:host([disabled]) .checkbox-wrapper,
|
|
75
|
+
:host(:disabled) .checkbox-wrapper {
|
|
66
76
|
cursor: not-allowed;
|
|
67
77
|
opacity: 0.6;
|
|
68
78
|
}
|
|
@@ -195,13 +205,63 @@ var checkboxStyles = css`
|
|
|
195
205
|
background: var(--lt-interactive-info-bg-hover);
|
|
196
206
|
border-color: var(--lt-interactive-info-bg-hover);
|
|
197
207
|
}
|
|
208
|
+
|
|
209
|
+
/* ── Reduced motion ─────────────────────────────────────────────────────── */
|
|
210
|
+
|
|
211
|
+
@media (prefers-reduced-motion: reduce) {
|
|
212
|
+
input[type='checkbox'] {
|
|
213
|
+
transition: none;
|
|
214
|
+
}
|
|
215
|
+
}
|
|
198
216
|
`;
|
|
199
217
|
|
|
218
|
+
// src/components/shared/form-default.ts
|
|
219
|
+
var FormDefaultController = class {
|
|
220
|
+
constructor(host, get) {
|
|
221
|
+
this._captured = false;
|
|
222
|
+
this._get = get;
|
|
223
|
+
host.addController(this);
|
|
224
|
+
}
|
|
225
|
+
hostConnected() {
|
|
226
|
+
if (this._captured) return;
|
|
227
|
+
this._captured = true;
|
|
228
|
+
this.value = this._get();
|
|
229
|
+
}
|
|
230
|
+
};
|
|
231
|
+
|
|
232
|
+
// src/components/shared/form-disabled.ts
|
|
233
|
+
var FormDisabledController = class {
|
|
234
|
+
constructor(host) {
|
|
235
|
+
this._fieldsetDisabled = false;
|
|
236
|
+
this._host = host;
|
|
237
|
+
host.addController(this);
|
|
238
|
+
}
|
|
239
|
+
// No-op — this controller has no connect-time work of its own (formDisabledCallback drives it instead), but
|
|
240
|
+
// ReactiveController's members are all optional, and a class satisfying an all-optional interface with no
|
|
241
|
+
// members in common is a TS error (TS2559); this gives it one.
|
|
242
|
+
hostConnected() {
|
|
243
|
+
}
|
|
244
|
+
/** Whether an ancestor `<fieldset>` is currently disabled. */
|
|
245
|
+
get fieldsetDisabled() {
|
|
246
|
+
return this._fieldsetDisabled;
|
|
247
|
+
}
|
|
248
|
+
setFieldsetDisabled(disabled) {
|
|
249
|
+
if (this._fieldsetDisabled === disabled) return;
|
|
250
|
+
this._fieldsetDisabled = disabled;
|
|
251
|
+
this._host.requestUpdate();
|
|
252
|
+
}
|
|
253
|
+
};
|
|
254
|
+
|
|
200
255
|
// src/components/checkbox/checkbox.ts
|
|
201
256
|
import "@latty-ds/icons";
|
|
257
|
+
var DEFAULT_LABELS = {
|
|
258
|
+
validationMessage: "Please check this box"
|
|
259
|
+
};
|
|
202
260
|
var Checkbox = class extends ThemeableElement {
|
|
203
261
|
constructor() {
|
|
204
262
|
super();
|
|
263
|
+
this._default = new FormDefaultController(this, () => this.checked);
|
|
264
|
+
this._fieldsetDisabled = new FormDisabledController(this);
|
|
205
265
|
this.variant = "primary";
|
|
206
266
|
this.size = "md";
|
|
207
267
|
this.checked = false;
|
|
@@ -212,21 +272,32 @@ var Checkbox = class extends ThemeableElement {
|
|
|
212
272
|
this.labelPosition = "right";
|
|
213
273
|
this.name = "";
|
|
214
274
|
this.value = "on";
|
|
275
|
+
this.labels = {};
|
|
215
276
|
this._internals = this.attachInternals();
|
|
216
277
|
}
|
|
278
|
+
get _labels() {
|
|
279
|
+
return { ...DEFAULT_LABELS, ...this.labels };
|
|
280
|
+
}
|
|
217
281
|
updated(changedProperties) {
|
|
218
282
|
if (changedProperties.has("indeterminate") && this.input) {
|
|
219
283
|
this.input.indeterminate = this.indeterminate;
|
|
220
284
|
}
|
|
221
285
|
this._internals.setFormValue(this.checked ? this.value : null);
|
|
222
286
|
if (this.required && !this.checked && this.input) {
|
|
223
|
-
this._internals.setValidity({ valueMissing: true },
|
|
287
|
+
this._internals.setValidity({ valueMissing: true }, this._labels.validationMessage, this.input);
|
|
224
288
|
} else {
|
|
225
289
|
this._internals.setValidity({});
|
|
226
290
|
}
|
|
227
291
|
}
|
|
228
292
|
formResetCallback() {
|
|
229
|
-
this.checked =
|
|
293
|
+
this.checked = this._default.value;
|
|
294
|
+
}
|
|
295
|
+
formDisabledCallback(disabled) {
|
|
296
|
+
this._fieldsetDisabled.setFieldsetDisabled(disabled);
|
|
297
|
+
}
|
|
298
|
+
/** `this.disabled` combined with an ancestor `<fieldset>`'s own disabled state (see `FormDisabledController`). */
|
|
299
|
+
get _isDisabled() {
|
|
300
|
+
return this.disabled || this._fieldsetDisabled.fieldsetDisabled;
|
|
230
301
|
}
|
|
231
302
|
checkValidity() {
|
|
232
303
|
return this._internals.checkValidity();
|
|
@@ -269,6 +340,9 @@ var Checkbox = class extends ThemeableElement {
|
|
|
269
340
|
}
|
|
270
341
|
return html``;
|
|
271
342
|
}
|
|
343
|
+
firstUpdated() {
|
|
344
|
+
if (!this.label) devWarn("lt-checkbox", "no `label` \u2014 the checkbox has no accessible name");
|
|
345
|
+
}
|
|
272
346
|
render() {
|
|
273
347
|
return html`
|
|
274
348
|
<label class="checkbox-wrapper">
|
|
@@ -276,7 +350,7 @@ var Checkbox = class extends ThemeableElement {
|
|
|
276
350
|
<input
|
|
277
351
|
type="checkbox"
|
|
278
352
|
.checked=${this.checked}
|
|
279
|
-
?disabled=${this.
|
|
353
|
+
?disabled=${this._isDisabled}
|
|
280
354
|
?required=${this.required}
|
|
281
355
|
name=${this.name}
|
|
282
356
|
value=${this.value}
|
|
@@ -300,7 +374,7 @@ __decorateClass([
|
|
|
300
374
|
property2({ reflect: true })
|
|
301
375
|
], Checkbox.prototype, "size", 2);
|
|
302
376
|
__decorateClass([
|
|
303
|
-
property2({ type: Boolean
|
|
377
|
+
property2({ type: Boolean })
|
|
304
378
|
], Checkbox.prototype, "checked", 2);
|
|
305
379
|
__decorateClass([
|
|
306
380
|
property2({ type: Boolean, reflect: true })
|
|
@@ -323,6 +397,9 @@ __decorateClass([
|
|
|
323
397
|
__decorateClass([
|
|
324
398
|
property2({ reflect: true })
|
|
325
399
|
], Checkbox.prototype, "value", 2);
|
|
400
|
+
__decorateClass([
|
|
401
|
+
property2({ type: Object })
|
|
402
|
+
], Checkbox.prototype, "labels", 2);
|
|
326
403
|
__decorateClass([
|
|
327
404
|
query('input[type="checkbox"]')
|
|
328
405
|
], Checkbox.prototype, "input", 2);
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import { ThemeableElement } from '../../base';
|
|
2
2
|
import '@latty-ds/icons';
|
|
3
|
-
import type { ChipVariant, ChipSize, ChipAppearance } from './chip.types';
|
|
3
|
+
import type { ChipVariant, ChipSize, ChipAppearance, ChipLabels } from './chip.types';
|
|
4
4
|
/**
|
|
5
5
|
* Compact label element for tags, filters, and attributes.
|
|
6
6
|
*
|
|
@@ -29,6 +29,9 @@ export declare class Chip extends ThemeableElement {
|
|
|
29
29
|
deletable: boolean;
|
|
30
30
|
/** Background color override. Accepts a hex value (#1a1a2e) or a CSS token name (--lt-color-primary-600). */
|
|
31
31
|
background: string;
|
|
32
|
+
/** Overridable UI text (the delete button's accessible name), for i18n. English defaults — override only the keys you need. */
|
|
33
|
+
labels: Partial<ChipLabels>;
|
|
34
|
+
private get _labels();
|
|
32
35
|
private get _deleteIconSize();
|
|
33
36
|
private _handleDelete;
|
|
34
37
|
render(): import("lit").TemplateResult<1>;
|
|
@@ -1,3 +1,8 @@
|
|
|
1
1
|
export type ChipVariant = 'primary' | 'secondary' | 'neutral' | 'success' | 'warning' | 'error' | 'info';
|
|
2
2
|
export type ChipSize = 'sm' | 'md' | 'lg';
|
|
3
3
|
export type ChipAppearance = 'filled' | 'outlined';
|
|
4
|
+
/** Overridable UI text, for i18n — English defaults; override only the keys you need. */
|
|
5
|
+
export interface ChipLabels {
|
|
6
|
+
/** Accessible label for the delete/remove button. */
|
|
7
|
+
remove: string;
|
|
8
|
+
}
|
|
@@ -82,6 +82,10 @@ var chipStyles = css`
|
|
|
82
82
|
display: inline-flex;
|
|
83
83
|
flex-shrink: 0;
|
|
84
84
|
justify-content: center;
|
|
85
|
+
/* WCAG 2.5.8: a 24px target. The negative margin gives the extra size back, so the chip layout is unchanged. */
|
|
86
|
+
margin: -6px;
|
|
87
|
+
min-height: 24px;
|
|
88
|
+
min-width: 24px;
|
|
85
89
|
opacity: 0.6;
|
|
86
90
|
padding: 0;
|
|
87
91
|
transition:
|
|
@@ -89,6 +93,11 @@ var chipStyles = css`
|
|
|
89
93
|
background-color 120ms ease;
|
|
90
94
|
}
|
|
91
95
|
|
|
96
|
+
/* The large chip's icon is 16px rather than 12px, so it needs less negative margin to keep the same layout. */
|
|
97
|
+
:host([size='lg']) .delete {
|
|
98
|
+
margin: -4px;
|
|
99
|
+
}
|
|
100
|
+
|
|
92
101
|
.delete:hover:not(:disabled) {
|
|
93
102
|
opacity: 1;
|
|
94
103
|
}
|
|
@@ -210,6 +219,15 @@ var chipStyles = css`
|
|
|
210
219
|
border-color: var(--lt-border-info-strong);
|
|
211
220
|
color: var(--lt-text-info);
|
|
212
221
|
}
|
|
222
|
+
|
|
223
|
+
/* ── Reduced motion ─────────────────────────────────────────────────────── */
|
|
224
|
+
|
|
225
|
+
@media (prefers-reduced-motion: reduce) {
|
|
226
|
+
span[part='base'],
|
|
227
|
+
.delete {
|
|
228
|
+
transition: none;
|
|
229
|
+
}
|
|
230
|
+
}
|
|
213
231
|
`;
|
|
214
232
|
|
|
215
233
|
// src/components/chip/chip.ts
|
|
@@ -222,6 +240,9 @@ var dispatch = (host, name, detail, init) => host.dispatchEvent(new CustomEvent(
|
|
|
222
240
|
var resolveColorValue = (value) => value.startsWith("--") ? `var(${value})` : value;
|
|
223
241
|
|
|
224
242
|
// src/components/chip/chip.ts
|
|
243
|
+
var DEFAULT_LABELS = {
|
|
244
|
+
remove: "Remove"
|
|
245
|
+
};
|
|
225
246
|
var Chip = class extends ThemeableElement {
|
|
226
247
|
constructor() {
|
|
227
248
|
super(...arguments);
|
|
@@ -231,6 +252,10 @@ var Chip = class extends ThemeableElement {
|
|
|
231
252
|
this.disabled = false;
|
|
232
253
|
this.deletable = false;
|
|
233
254
|
this.background = "";
|
|
255
|
+
this.labels = {};
|
|
256
|
+
}
|
|
257
|
+
get _labels() {
|
|
258
|
+
return { ...DEFAULT_LABELS, ...this.labels };
|
|
234
259
|
}
|
|
235
260
|
get _deleteIconSize() {
|
|
236
261
|
return this.size === "lg" ? "sm" : "xs";
|
|
@@ -249,7 +274,7 @@ var Chip = class extends ThemeableElement {
|
|
|
249
274
|
class="delete"
|
|
250
275
|
part="delete-button"
|
|
251
276
|
?disabled=${this.disabled}
|
|
252
|
-
aria-label
|
|
277
|
+
aria-label=${this._labels.remove}
|
|
253
278
|
@click=${this._handleDelete}
|
|
254
279
|
>
|
|
255
280
|
<lt-icon name="xmark" size=${this._deleteIconSize}></lt-icon>
|
|
@@ -278,6 +303,9 @@ __decorateClass([
|
|
|
278
303
|
__decorateClass([
|
|
279
304
|
property2({ reflect: true })
|
|
280
305
|
], Chip.prototype, "background", 2);
|
|
306
|
+
__decorateClass([
|
|
307
|
+
property2({ type: Object })
|
|
308
|
+
], Chip.prototype, "labels", 2);
|
|
281
309
|
Chip = __decorateClass([
|
|
282
310
|
customElement("lt-chip")
|
|
283
311
|
], Chip);
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import { ThemeableElement } from '../../base';
|
|
2
|
-
import { ColorInputFormat, ColorInputSize } from './color-input.types';
|
|
2
|
+
import { ColorInputFormat, ColorInputSize, type ColorInputLabels } from './color-input.types';
|
|
3
3
|
import '@latty-ds/icons';
|
|
4
4
|
import '../text/text';
|
|
5
5
|
/**
|
|
@@ -21,10 +21,13 @@ export declare class ColorInput extends ThemeableElement {
|
|
|
21
21
|
static styles: import("lit").CSSResult;
|
|
22
22
|
static formAssociated: boolean;
|
|
23
23
|
private _internals;
|
|
24
|
+
private _default;
|
|
25
|
+
private _fieldsetDisabled;
|
|
24
26
|
constructor();
|
|
25
27
|
/**
|
|
26
28
|
* The current color value. Accepts hex (`#7c3aed`), rgb (`rgb(124, 58, 237)`),
|
|
27
|
-
* or hsl (`hsl(263, 70%, 58%)`). Emitted values match the `format` prop.
|
|
29
|
+
* or hsl (`hsl(263, 70%, 58%)`). Emitted values match the `format` prop. Not reflected as an attribute —
|
|
30
|
+
* read the property, or the `change` event's `detail.value`, instead of `getAttribute('value')`/`[value]`.
|
|
28
31
|
* @default ''
|
|
29
32
|
*/
|
|
30
33
|
value: string;
|
|
@@ -63,8 +66,14 @@ export declare class ColorInput extends ThemeableElement {
|
|
|
63
66
|
* @default 'md'
|
|
64
67
|
*/
|
|
65
68
|
size: ColorInputSize;
|
|
69
|
+
/** Overridable UI text (the required-field validation message), for i18n. English defaults — override only the keys you need. */
|
|
70
|
+
labels: Partial<ColorInputLabels>;
|
|
71
|
+
private get _labels();
|
|
66
72
|
updated(): void;
|
|
67
73
|
formResetCallback(): void;
|
|
74
|
+
formDisabledCallback(disabled: boolean): void;
|
|
75
|
+
/** `this.disabled` combined with an ancestor `<fieldset>`'s own disabled state (see `FormDisabledController`). */
|
|
76
|
+
private get _isDisabled();
|
|
68
77
|
checkValidity(): boolean;
|
|
69
78
|
reportValidity(): boolean;
|
|
70
79
|
private _handleChange;
|
|
@@ -1,2 +1,7 @@
|
|
|
1
1
|
export type ColorInputSize = 'sm' | 'md' | 'lg';
|
|
2
2
|
export type ColorInputFormat = 'hex' | 'rgb' | 'hsl';
|
|
3
|
+
/** Overridable UI text for `lt-color-input`, for i18n. */
|
|
4
|
+
export interface ColorInputLabels {
|
|
5
|
+
/** Validation message shown when a required field has no color selected. */
|
|
6
|
+
validationMessage: string;
|
|
7
|
+
}
|
|
@@ -53,7 +53,10 @@ var colorInputStyles = css`
|
|
|
53
53
|
cursor: pointer;
|
|
54
54
|
}
|
|
55
55
|
|
|
56
|
-
:host(
|
|
56
|
+
/* :host(:disabled) — the browser matches this automatically for a form-associated element inside a disabled
|
|
57
|
+
<fieldset>, no JS required; :host([disabled]) covers the component's own explicit attribute. */
|
|
58
|
+
:host([disabled]) .wrapper,
|
|
59
|
+
:host(:disabled) .wrapper {
|
|
57
60
|
cursor: not-allowed;
|
|
58
61
|
}
|
|
59
62
|
|
|
@@ -86,7 +89,8 @@ var colorInputStyles = css`
|
|
|
86
89
|
outline: none;
|
|
87
90
|
}
|
|
88
91
|
|
|
89
|
-
:host([disabled]) .input-container
|
|
92
|
+
:host([disabled]) .input-container,
|
|
93
|
+
:host(:disabled) .input-container {
|
|
90
94
|
background: var(--lt-bg-surface);
|
|
91
95
|
}
|
|
92
96
|
|
|
@@ -117,7 +121,8 @@ var colorInputStyles = css`
|
|
|
117
121
|
color: var(--lt-text-muted);
|
|
118
122
|
}
|
|
119
123
|
|
|
120
|
-
:host([disabled]) .display-value
|
|
124
|
+
:host([disabled]) .display-value,
|
|
125
|
+
:host(:disabled) .display-value {
|
|
121
126
|
color: var(--lt-text-muted);
|
|
122
127
|
}
|
|
123
128
|
|
|
@@ -185,8 +190,53 @@ var colorInputStyles = css`
|
|
|
185
190
|
width: 24px;
|
|
186
191
|
height: 24px;
|
|
187
192
|
}
|
|
193
|
+
|
|
194
|
+
/* ── Reduced motion ─────────────────────────────────────────────────────── */
|
|
195
|
+
|
|
196
|
+
@media (prefers-reduced-motion: reduce) {
|
|
197
|
+
.input-container {
|
|
198
|
+
transition: none;
|
|
199
|
+
}
|
|
200
|
+
}
|
|
188
201
|
`;
|
|
189
202
|
|
|
203
|
+
// src/components/shared/form-default.ts
|
|
204
|
+
var FormDefaultController = class {
|
|
205
|
+
constructor(host, get) {
|
|
206
|
+
this._captured = false;
|
|
207
|
+
this._get = get;
|
|
208
|
+
host.addController(this);
|
|
209
|
+
}
|
|
210
|
+
hostConnected() {
|
|
211
|
+
if (this._captured) return;
|
|
212
|
+
this._captured = true;
|
|
213
|
+
this.value = this._get();
|
|
214
|
+
}
|
|
215
|
+
};
|
|
216
|
+
|
|
217
|
+
// src/components/shared/form-disabled.ts
|
|
218
|
+
var FormDisabledController = class {
|
|
219
|
+
constructor(host) {
|
|
220
|
+
this._fieldsetDisabled = false;
|
|
221
|
+
this._host = host;
|
|
222
|
+
host.addController(this);
|
|
223
|
+
}
|
|
224
|
+
// No-op — this controller has no connect-time work of its own (formDisabledCallback drives it instead), but
|
|
225
|
+
// ReactiveController's members are all optional, and a class satisfying an all-optional interface with no
|
|
226
|
+
// members in common is a TS error (TS2559); this gives it one.
|
|
227
|
+
hostConnected() {
|
|
228
|
+
}
|
|
229
|
+
/** Whether an ancestor `<fieldset>` is currently disabled. */
|
|
230
|
+
get fieldsetDisabled() {
|
|
231
|
+
return this._fieldsetDisabled;
|
|
232
|
+
}
|
|
233
|
+
setFieldsetDisabled(disabled) {
|
|
234
|
+
if (this._fieldsetDisabled === disabled) return;
|
|
235
|
+
this._fieldsetDisabled = disabled;
|
|
236
|
+
this._host.requestUpdate();
|
|
237
|
+
}
|
|
238
|
+
};
|
|
239
|
+
|
|
190
240
|
// src/components/color-input/color-input.ts
|
|
191
241
|
import "@latty-ds/icons";
|
|
192
242
|
|
|
@@ -359,6 +409,20 @@ var textStyles = css2`
|
|
|
359
409
|
`;
|
|
360
410
|
|
|
361
411
|
// src/components/text/text.ts
|
|
412
|
+
var ALLOWED_TAGS = /* @__PURE__ */ new Set([
|
|
413
|
+
"h1",
|
|
414
|
+
"h2",
|
|
415
|
+
"h3",
|
|
416
|
+
"h4",
|
|
417
|
+
"h5",
|
|
418
|
+
"h6",
|
|
419
|
+
"p",
|
|
420
|
+
"span",
|
|
421
|
+
"div",
|
|
422
|
+
"label",
|
|
423
|
+
"strong",
|
|
424
|
+
"em"
|
|
425
|
+
]);
|
|
362
426
|
var VARIANT_TAG = {
|
|
363
427
|
"display-2xl": "p",
|
|
364
428
|
"display-xl": "p",
|
|
@@ -383,7 +447,8 @@ var Text = class extends ThemeableElement {
|
|
|
383
447
|
this.as = "";
|
|
384
448
|
}
|
|
385
449
|
render() {
|
|
386
|
-
const
|
|
450
|
+
const requested = this.as && ALLOWED_TAGS.has(this.as) ? this.as : "";
|
|
451
|
+
const tag = unsafeStatic(requested || VARIANT_TAG[this.variant] || "p");
|
|
387
452
|
return html`<${tag} part="base"><slot></slot></${tag}>`;
|
|
388
453
|
}
|
|
389
454
|
};
|
|
@@ -456,9 +521,14 @@ function formatColor(hex, format) {
|
|
|
456
521
|
}
|
|
457
522
|
return hex;
|
|
458
523
|
}
|
|
524
|
+
var DEFAULT_LABELS = {
|
|
525
|
+
validationMessage: "Please select a color"
|
|
526
|
+
};
|
|
459
527
|
var ColorInput = class extends ThemeableElement {
|
|
460
528
|
constructor() {
|
|
461
529
|
super();
|
|
530
|
+
this._default = new FormDefaultController(this, () => this.value);
|
|
531
|
+
this._fieldsetDisabled = new FormDisabledController(this);
|
|
462
532
|
this.value = "";
|
|
463
533
|
this.format = "hex";
|
|
464
534
|
this.label = "";
|
|
@@ -467,19 +537,30 @@ var ColorInput = class extends ThemeableElement {
|
|
|
467
537
|
this.required = false;
|
|
468
538
|
this.name = "";
|
|
469
539
|
this.size = "md";
|
|
540
|
+
this.labels = {};
|
|
470
541
|
this._internals = this.attachInternals();
|
|
471
542
|
}
|
|
543
|
+
get _labels() {
|
|
544
|
+
return { ...DEFAULT_LABELS, ...this.labels };
|
|
545
|
+
}
|
|
472
546
|
updated() {
|
|
473
547
|
this._internals.setFormValue(this.value || null);
|
|
474
548
|
const input = this.shadowRoot?.querySelector('input[type="color"]');
|
|
475
549
|
if (this.required && !this.value && input) {
|
|
476
|
-
this._internals.setValidity({ valueMissing: true },
|
|
550
|
+
this._internals.setValidity({ valueMissing: true }, this._labels.validationMessage, input);
|
|
477
551
|
} else {
|
|
478
552
|
this._internals.setValidity({});
|
|
479
553
|
}
|
|
480
554
|
}
|
|
481
555
|
formResetCallback() {
|
|
482
|
-
this.value =
|
|
556
|
+
this.value = this._default.value;
|
|
557
|
+
}
|
|
558
|
+
formDisabledCallback(disabled) {
|
|
559
|
+
this._fieldsetDisabled.setFieldsetDisabled(disabled);
|
|
560
|
+
}
|
|
561
|
+
/** `this.disabled` combined with an ancestor `<fieldset>`'s own disabled state (see `FormDisabledController`). */
|
|
562
|
+
get _isDisabled() {
|
|
563
|
+
return this.disabled || this._fieldsetDisabled.fieldsetDisabled;
|
|
483
564
|
}
|
|
484
565
|
checkValidity() {
|
|
485
566
|
return this._internals.checkValidity();
|
|
@@ -513,7 +594,7 @@ var ColorInput = class extends ThemeableElement {
|
|
|
513
594
|
class="native-picker"
|
|
514
595
|
.value=${hex || "#000000"}
|
|
515
596
|
name=${ifDefined(this.name || void 0)}
|
|
516
|
-
?disabled=${this.
|
|
597
|
+
?disabled=${this._isDisabled}
|
|
517
598
|
aria-label=${this.label || this.placeholder}
|
|
518
599
|
@change=${this._handleChange}
|
|
519
600
|
/>
|
|
@@ -525,7 +606,7 @@ var ColorInput = class extends ThemeableElement {
|
|
|
525
606
|
ColorInput.styles = colorInputStyles;
|
|
526
607
|
ColorInput.formAssociated = true;
|
|
527
608
|
__decorateClass([
|
|
528
|
-
property3(
|
|
609
|
+
property3()
|
|
529
610
|
], ColorInput.prototype, "value", 2);
|
|
530
611
|
__decorateClass([
|
|
531
612
|
property3({ reflect: true })
|
|
@@ -548,6 +629,9 @@ __decorateClass([
|
|
|
548
629
|
__decorateClass([
|
|
549
630
|
property3({ reflect: true })
|
|
550
631
|
], ColorInput.prototype, "size", 2);
|
|
632
|
+
__decorateClass([
|
|
633
|
+
property3({ type: Object })
|
|
634
|
+
], ColorInput.prototype, "labels", 2);
|
|
551
635
|
ColorInput = __decorateClass([
|
|
552
636
|
customElement2("lt-color-input")
|
|
553
637
|
], ColorInput);
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import { ThemeableElement } from '../../base';
|
|
2
|
-
import type { ComboboxOption, ComboboxSize, ComboboxVariant } from './combobox.types';
|
|
2
|
+
import type { ComboboxOption, ComboboxSize, ComboboxVariant, ComboboxLabels } from './combobox.types';
|
|
3
3
|
import '@latty-ds/icons';
|
|
4
4
|
import '../text/text';
|
|
5
5
|
/**
|
|
@@ -22,10 +22,15 @@ export declare class Combobox extends ThemeableElement {
|
|
|
22
22
|
static styles: import("lit").CSSResult[];
|
|
23
23
|
static formAssociated: boolean;
|
|
24
24
|
private _internals;
|
|
25
|
+
private _default;
|
|
26
|
+
private _fieldsetDisabled;
|
|
27
|
+
private readonly _uid;
|
|
25
28
|
constructor();
|
|
26
29
|
/** Array of selectable options. Set as a JS property (`.options`). */
|
|
27
30
|
options: ComboboxOption[];
|
|
28
|
-
/** Currently selected value.
|
|
31
|
+
/** Currently selected value. Not reflected as an attribute — read the property, or the `change` event's
|
|
32
|
+
* `detail.value`, instead of `getAttribute('value')`/`[value]` (consistent with the rest of the form
|
|
33
|
+
* controls; see `lt-textfield`'s equivalent doc comment for why). */
|
|
29
34
|
value: string;
|
|
30
35
|
/** Field label displayed above the input. */
|
|
31
36
|
label: string;
|
|
@@ -43,23 +48,34 @@ export declare class Combobox extends ThemeableElement {
|
|
|
43
48
|
required: boolean;
|
|
44
49
|
/** Name used in form submission. */
|
|
45
50
|
name: string;
|
|
51
|
+
/** Overridable UI text (validation message, "no results" text), for i18n. English defaults — override only the keys you need. */
|
|
52
|
+
labels: Partial<ComboboxLabels>;
|
|
53
|
+
private get _labels();
|
|
46
54
|
private query;
|
|
47
55
|
private open;
|
|
48
56
|
private activeIndex;
|
|
49
57
|
private _cleanupClickOutside;
|
|
50
58
|
private _floatingCleanup;
|
|
59
|
+
private readonly _fieldIds;
|
|
51
60
|
private get selectedLabel();
|
|
52
61
|
private get filtered();
|
|
62
|
+
private get enabledOpts();
|
|
63
|
+
private _idFor;
|
|
64
|
+
private _preventFocusSteal;
|
|
53
65
|
private openDropdown;
|
|
54
66
|
private closeDropdown;
|
|
55
67
|
private selectOption;
|
|
56
68
|
private handleInput;
|
|
57
69
|
private handleFocus;
|
|
58
70
|
private handleKeydown;
|
|
71
|
+
private _onFocusOut;
|
|
59
72
|
connectedCallback(): void;
|
|
60
73
|
disconnectedCallback(): void;
|
|
61
74
|
updated(): void;
|
|
62
75
|
formResetCallback(): void;
|
|
76
|
+
formDisabledCallback(disabled: boolean): void;
|
|
77
|
+
/** `this.disabled` combined with an ancestor `<fieldset>`'s own disabled state (see `FormDisabledController`). */
|
|
78
|
+
private get _isDisabled();
|
|
63
79
|
checkValidity(): boolean;
|
|
64
80
|
reportValidity(): boolean;
|
|
65
81
|
render(): import("lit").TemplateResult<1>;
|
|
@@ -5,3 +5,10 @@ export interface ComboboxOption {
|
|
|
5
5
|
label: string;
|
|
6
6
|
disabled?: boolean;
|
|
7
7
|
}
|
|
8
|
+
/** Overridable UI text for `lt-combobox`, for i18n. */
|
|
9
|
+
export interface ComboboxLabels {
|
|
10
|
+
/** Validation message shown when a required combobox has no option selected. */
|
|
11
|
+
validationMessage: string;
|
|
12
|
+
/** Shown in the dropdown when no options match the current search text. */
|
|
13
|
+
noResults: string;
|
|
14
|
+
}
|