@latty-ds/web 0.2.0 → 0.4.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.
Files changed (36) hide show
  1. package/custom-elements.json +877 -503
  2. package/dist/components/accordion/index.js +1 -1
  3. package/dist/components/avatar/index.js +1 -1
  4. package/dist/components/checkbox/checkbox.d.ts +7 -5
  5. package/dist/components/checkbox/index.js +22 -9
  6. package/dist/components/color-input/color-input.d.ts +17 -0
  7. package/dist/components/color-input/index.js +32 -4
  8. package/dist/components/combobox/combobox.d.ts +8 -1
  9. package/dist/components/combobox/index.js +26 -7
  10. package/dist/components/date-input/date-input.d.ts +7 -0
  11. package/dist/components/date-input/index.js +24 -5
  12. package/dist/components/datepicker/datepicker.d.ts +8 -0
  13. package/dist/components/datepicker/index.js +27 -7
  14. package/dist/components/dialog/dialog.d.ts +4 -2
  15. package/dist/components/dialog/index.js +5 -12
  16. package/dist/components/divider/index.js +1 -1
  17. package/dist/components/nav/index.js +2 -2
  18. package/dist/components/progress/index.js +2 -2
  19. package/dist/components/radio/index.js +24 -4
  20. package/dist/components/radio/radio.d.ts +7 -0
  21. package/dist/components/radio-group/index.js +3 -3
  22. package/dist/components/select/index.js +28 -9
  23. package/dist/components/select/select.d.ts +11 -3
  24. package/dist/components/sidepanel/index.js +1 -1
  25. package/dist/components/slider/index.js +17 -4
  26. package/dist/components/slider/slider.d.ts +6 -0
  27. package/dist/components/switch/index.js +24 -4
  28. package/dist/components/switch/switch.d.ts +7 -0
  29. package/dist/components/tab/index.js +2 -2
  30. package/dist/components/tab-group/index.js +3 -3
  31. package/dist/components/textfield/index.js +26 -4
  32. package/dist/components/textfield/textfield.d.ts +11 -0
  33. package/dist/index.cjs +269 -83
  34. package/dist/index.js +269 -83
  35. package/dist/manifest.json +140 -116
  36. package/package.json +3 -3
@@ -208,7 +208,7 @@ var radioStyles = css`
208
208
  // src/components/radio/radio.ts
209
209
  var Radio = class extends ThemeableElement {
210
210
  constructor() {
211
- super(...arguments);
211
+ super();
212
212
  this.variant = "primary";
213
213
  this.size = "md";
214
214
  this.checked = false;
@@ -218,6 +218,25 @@ var Radio = class extends ThemeableElement {
218
218
  this.labelPosition = "right";
219
219
  this.name = "";
220
220
  this.value = "";
221
+ this._internals = this.attachInternals();
222
+ }
223
+ updated() {
224
+ this._internals.setFormValue(this.checked ? this.value : null);
225
+ const input = this.shadowRoot?.querySelector("input");
226
+ if (this.required && !this.checked && input) {
227
+ this._internals.setValidity({ valueMissing: true }, "Please select this option", input);
228
+ } else {
229
+ this._internals.setValidity({});
230
+ }
231
+ }
232
+ formResetCallback() {
233
+ this.checked = false;
234
+ }
235
+ checkValidity() {
236
+ return this._internals.checkValidity();
237
+ }
238
+ reportValidity() {
239
+ return this._internals.reportValidity();
221
240
  }
222
241
  /**
223
242
  * Handles radio change events.
@@ -259,6 +278,7 @@ var Radio = class extends ThemeableElement {
259
278
  }
260
279
  };
261
280
  Radio.styles = radioStyles;
281
+ Radio.formAssociated = true;
262
282
  __decorateClass([
263
283
  property2({ reflect: true })
264
284
  ], Radio.prototype, "variant", 2);
@@ -275,16 +295,16 @@ __decorateClass([
275
295
  property2({ type: Boolean, reflect: true })
276
296
  ], Radio.prototype, "required", 2);
277
297
  __decorateClass([
278
- property2()
298
+ property2({ reflect: true })
279
299
  ], Radio.prototype, "label", 2);
280
300
  __decorateClass([
281
301
  property2({ attribute: "label-position", reflect: true })
282
302
  ], Radio.prototype, "labelPosition", 2);
283
303
  __decorateClass([
284
- property2()
304
+ property2({ reflect: true })
285
305
  ], Radio.prototype, "name", 2);
286
306
  __decorateClass([
287
- property2()
307
+ property2({ reflect: true })
288
308
  ], Radio.prototype, "value", 2);
289
309
  Radio = __decorateClass([
290
310
  customElement("lt-radio")
@@ -38,6 +38,9 @@ import { RadioSize, RadioVariant, RadioLabelPosition } from './radio.types';
38
38
  */
39
39
  export declare class Radio extends ThemeableElement {
40
40
  static styles: import("lit").CSSResult;
41
+ static formAssociated: boolean;
42
+ private _internals;
43
+ constructor();
41
44
  /**
42
45
  * Visual variant that determines the color when checked.
43
46
  * @default 'primary'
@@ -84,6 +87,10 @@ export declare class Radio extends ThemeableElement {
84
87
  * @default ''
85
88
  */
86
89
  value: string;
90
+ updated(): void;
91
+ formResetCallback(): void;
92
+ checkValidity(): boolean;
93
+ reportValidity(): boolean;
87
94
  /**
88
95
  * Handles radio change events.
89
96
  * Updates the checked state and dispatches a custom change event.
@@ -353,13 +353,13 @@ var RadioGroup = class extends ThemeableElement {
353
353
  };
354
354
  RadioGroup.styles = radioGroupStyles;
355
355
  __decorateClass([
356
- property3()
356
+ property3({ reflect: true })
357
357
  ], RadioGroup.prototype, "label", 2);
358
358
  __decorateClass([
359
- property3()
359
+ property3({ reflect: true })
360
360
  ], RadioGroup.prototype, "name", 2);
361
361
  __decorateClass([
362
- property3()
362
+ property3({ reflect: true })
363
363
  ], RadioGroup.prototype, "value", 2);
364
364
  __decorateClass([
365
365
  property3({ reflect: true })
@@ -1910,12 +1910,13 @@ Text = __decorateClass([
1910
1910
  // src/components/select/select.ts
1911
1911
  var Select = class extends ThemeableElement {
1912
1912
  constructor() {
1913
- super(...arguments);
1913
+ super();
1914
1914
  this.variant = "default";
1915
1915
  this.size = "md";
1916
1916
  this.value = "";
1917
1917
  this.placeholder = "Select an option";
1918
1918
  this.label = "";
1919
+ this.name = "";
1919
1920
  this.helperText = "";
1920
1921
  this.disabled = false;
1921
1922
  this.required = false;
@@ -1923,6 +1924,7 @@ var Select = class extends ThemeableElement {
1923
1924
  this.isOpen = false;
1924
1925
  this._cleanupClickOutside = null;
1925
1926
  this._floatingCleanup = null;
1927
+ this._internals = this.attachInternals();
1926
1928
  }
1927
1929
  /**
1928
1930
  * Toggles the dropdown open/closed state.
@@ -2008,16 +2010,20 @@ var Select = class extends ThemeableElement {
2008
2010
  const selected = this.options.find((opt) => opt.value === this.value);
2009
2011
  return selected ? selected.label : "";
2010
2012
  }
2011
- /**
2012
- * Reflects the open state as an attribute for CSS styling.
2013
- */
2014
2013
  updated(changedProperties) {
2014
+ this._internals.setFormValue(this.value || null);
2015
+ const trigger = this.shadowRoot?.querySelector(".select-trigger");
2016
+ if (this.required && !this.value && trigger) {
2017
+ this._internals.setValidity({ valueMissing: true }, "Please select an option", trigger);
2018
+ } else {
2019
+ this._internals.setValidity({});
2020
+ }
2015
2021
  if (!changedProperties.has("isOpen")) return;
2016
2022
  if (this.isOpen) {
2017
2023
  this.setAttribute("open", "");
2018
- const trigger = this.shadowRoot.querySelector(".select-trigger");
2024
+ const selectTrigger = this.shadowRoot.querySelector(".select-trigger");
2019
2025
  const listbox = this.shadowRoot.querySelector("lt-surface.dropdown");
2020
- openFloating(trigger, listbox, { matchWidth: true }).then((cleanup) => {
2026
+ openFloating(selectTrigger, listbox, { matchWidth: true }).then((cleanup) => {
2021
2027
  this._floatingCleanup = cleanup;
2022
2028
  });
2023
2029
  } else {
@@ -2027,6 +2033,15 @@ var Select = class extends ThemeableElement {
2027
2033
  this._floatingCleanup = null;
2028
2034
  }
2029
2035
  }
2036
+ formResetCallback() {
2037
+ this.value = "";
2038
+ }
2039
+ checkValidity() {
2040
+ return this._internals.checkValidity();
2041
+ }
2042
+ reportValidity() {
2043
+ return this._internals.reportValidity();
2044
+ }
2030
2045
  render() {
2031
2046
  const selectedLabel = this.getSelectedLabel();
2032
2047
  const hasValue = Boolean(this.value && selectedLabel);
@@ -2085,6 +2100,7 @@ var Select = class extends ThemeableElement {
2085
2100
  }
2086
2101
  };
2087
2102
  Select.styles = selectStyles;
2103
+ Select.formAssociated = true;
2088
2104
  __decorateClass([
2089
2105
  property4({ reflect: true })
2090
2106
  ], Select.prototype, "variant", 2);
@@ -2092,14 +2108,17 @@ __decorateClass([
2092
2108
  property4({ reflect: true })
2093
2109
  ], Select.prototype, "size", 2);
2094
2110
  __decorateClass([
2095
- property4()
2111
+ property4({ reflect: true })
2096
2112
  ], Select.prototype, "value", 2);
2097
2113
  __decorateClass([
2098
- property4()
2114
+ property4({ reflect: true })
2099
2115
  ], Select.prototype, "placeholder", 2);
2100
2116
  __decorateClass([
2101
- property4()
2117
+ property4({ reflect: true })
2102
2118
  ], Select.prototype, "label", 2);
2119
+ __decorateClass([
2120
+ property4({ reflect: true })
2121
+ ], Select.prototype, "name", 2);
2103
2122
  __decorateClass([
2104
2123
  property4({ attribute: "helper-text" })
2105
2124
  ], Select.prototype, "helperText", 2);
@@ -36,6 +36,9 @@ import '../text/text';
36
36
  */
37
37
  export declare class Select extends ThemeableElement {
38
38
  static styles: import("lit").CSSResult[];
39
+ static formAssociated: boolean;
40
+ private _internals;
41
+ constructor();
39
42
  /**
40
43
  * Visual variant that determines styling.
41
44
  * @default 'default'
@@ -61,6 +64,11 @@ export declare class Select extends ThemeableElement {
61
64
  * @default ''
62
65
  */
63
66
  label: string;
67
+ /**
68
+ * Name used when submitting a form.
69
+ * @default ''
70
+ */
71
+ name: string;
64
72
  /**
65
73
  * Helper text displayed below the select. Color changes based on variant.
66
74
  * @default ''
@@ -121,9 +129,9 @@ export declare class Select extends ThemeableElement {
121
129
  * @private
122
130
  */
123
131
  private getSelectedLabel;
124
- /**
125
- * Reflects the open state as an attribute for CSS styling.
126
- */
127
132
  updated(changedProperties: Map<string, unknown>): void;
133
+ formResetCallback(): void;
134
+ checkValidity(): boolean;
135
+ reportValidity(): boolean;
128
136
  render(): import("lit").TemplateResult<1>;
129
137
  }
@@ -749,7 +749,7 @@ __decorateClass([
749
749
  property4()
750
750
  ], SidePanel.prototype, "size", 2);
751
751
  __decorateClass([
752
- property4()
752
+ property4({ reflect: true })
753
753
  ], SidePanel.prototype, "label", 2);
754
754
  __decorateClass([
755
755
  property4({ type: Boolean, attribute: "no-close-button" })
@@ -518,7 +518,7 @@ Tooltip = __decorateClass([
518
518
  // src/components/slider/slider.ts
519
519
  var Slider = class extends ThemeableElement {
520
520
  constructor() {
521
- super(...arguments);
521
+ super();
522
522
  this.size = "md";
523
523
  this.disabled = false;
524
524
  this.tooltip = false;
@@ -528,6 +528,7 @@ var Slider = class extends ThemeableElement {
528
528
  this.value = 0;
529
529
  this.label = "";
530
530
  this.name = "";
531
+ this._internals = this.attachInternals();
531
532
  }
532
533
  get _fillPercent() {
533
534
  return (this.value - this.min) / (this.max - this.min) * 100;
@@ -544,6 +545,17 @@ var Slider = class extends ThemeableElement {
544
545
  const centerPx = fill / 100 * (trackW - thumbPx) + thumbPx / 2;
545
546
  this.style.setProperty("--_thumb-left", `${centerPx / trackW * 100}%`);
546
547
  }
548
+ this._internals.setFormValue(String(this.value));
549
+ this._internals.setValidity({});
550
+ }
551
+ formResetCallback() {
552
+ this.value = this.min;
553
+ }
554
+ checkValidity() {
555
+ return this._internals.checkValidity();
556
+ }
557
+ reportValidity() {
558
+ return this._internals.reportValidity();
547
559
  }
548
560
  _onInput(e) {
549
561
  e.stopPropagation();
@@ -597,6 +609,7 @@ var Slider = class extends ThemeableElement {
597
609
  }
598
610
  };
599
611
  Slider.styles = sliderStyles;
612
+ Slider.formAssociated = true;
600
613
  __decorateClass([
601
614
  property4({ reflect: true })
602
615
  ], Slider.prototype, "size", 2);
@@ -616,13 +629,13 @@ __decorateClass([
616
629
  property4({ type: Number })
617
630
  ], Slider.prototype, "step", 2);
618
631
  __decorateClass([
619
- property4({ type: Number })
632
+ property4({ type: Number, reflect: true })
620
633
  ], Slider.prototype, "value", 2);
621
634
  __decorateClass([
622
- property4()
635
+ property4({ reflect: true })
623
636
  ], Slider.prototype, "label", 2);
624
637
  __decorateClass([
625
- property4()
638
+ property4({ reflect: true })
626
639
  ], Slider.prototype, "name", 2);
627
640
  __decorateClass([
628
641
  query2("input")
@@ -11,6 +11,9 @@ import '../text/text';
11
11
  */
12
12
  export declare class Slider extends ThemeableElement {
13
13
  static styles: import("lit").CSSResult;
14
+ static formAssociated: boolean;
15
+ private _internals;
16
+ constructor();
14
17
  size: SliderSize;
15
18
  disabled: boolean;
16
19
  /** Show the current value in a tooltip above the thumb. */
@@ -27,6 +30,9 @@ export declare class Slider extends ThemeableElement {
27
30
  private get _fillPercent();
28
31
  private _thumbSizePx;
29
32
  updated(): void;
33
+ formResetCallback(): void;
34
+ checkValidity(): boolean;
35
+ reportValidity(): boolean;
30
36
  private _onInput;
31
37
  private _onChange;
32
38
  render(): import("lit").TemplateResult<1>;
@@ -205,7 +205,7 @@ var switchStyles = css`
205
205
  // src/components/switch/switch.ts
206
206
  var Switch = class extends ThemeableElement {
207
207
  constructor() {
208
- super(...arguments);
208
+ super();
209
209
  this.variant = "primary";
210
210
  this.size = "md";
211
211
  this.checked = false;
@@ -215,6 +215,7 @@ var Switch = class extends ThemeableElement {
215
215
  this.labelPosition = "right";
216
216
  this.name = "";
217
217
  this.value = "on";
218
+ this._internals = this.attachInternals();
218
219
  }
219
220
  /**
220
221
  * Handles switch change events.
@@ -223,6 +224,24 @@ var Switch = class extends ThemeableElement {
223
224
  * @param e - The native change event
224
225
  * @private
225
226
  */
227
+ updated() {
228
+ this._internals.setFormValue(this.checked ? this.value : null);
229
+ const input = this.shadowRoot?.querySelector("input");
230
+ if (this.required && !this.checked && input) {
231
+ this._internals.setValidity({ valueMissing: true }, "Please check this switch", input);
232
+ } else {
233
+ this._internals.setValidity({});
234
+ }
235
+ }
236
+ formResetCallback() {
237
+ this.checked = false;
238
+ }
239
+ checkValidity() {
240
+ return this._internals.checkValidity();
241
+ }
242
+ reportValidity() {
243
+ return this._internals.reportValidity();
244
+ }
226
245
  handleChange(e) {
227
246
  const target = e.target;
228
247
  this.checked = target.checked;
@@ -258,6 +277,7 @@ var Switch = class extends ThemeableElement {
258
277
  }
259
278
  };
260
279
  Switch.styles = switchStyles;
280
+ Switch.formAssociated = true;
261
281
  __decorateClass([
262
282
  property2({ reflect: true })
263
283
  ], Switch.prototype, "variant", 2);
@@ -274,16 +294,16 @@ __decorateClass([
274
294
  property2({ type: Boolean, reflect: true })
275
295
  ], Switch.prototype, "required", 2);
276
296
  __decorateClass([
277
- property2()
297
+ property2({ reflect: true })
278
298
  ], Switch.prototype, "label", 2);
279
299
  __decorateClass([
280
300
  property2({ attribute: "label-position", reflect: true })
281
301
  ], Switch.prototype, "labelPosition", 2);
282
302
  __decorateClass([
283
- property2()
303
+ property2({ reflect: true })
284
304
  ], Switch.prototype, "name", 2);
285
305
  __decorateClass([
286
- property2()
306
+ property2({ reflect: true })
287
307
  ], Switch.prototype, "value", 2);
288
308
  Switch = __decorateClass([
289
309
  customElement("lt-switch")
@@ -33,6 +33,9 @@ import { SwitchSize, SwitchVariant, SwitchLabelPosition } from './switch.types';
33
33
  */
34
34
  export declare class Switch extends ThemeableElement {
35
35
  static styles: import("lit").CSSResult;
36
+ static formAssociated: boolean;
37
+ private _internals;
38
+ constructor();
36
39
  /**
37
40
  * Visual variant that determines the color when checked.
38
41
  * @default 'primary'
@@ -85,6 +88,10 @@ export declare class Switch extends ThemeableElement {
85
88
  * @param e - The native change event
86
89
  * @private
87
90
  */
91
+ updated(): void;
92
+ formResetCallback(): void;
93
+ checkValidity(): boolean;
94
+ reportValidity(): boolean;
88
95
  private handleChange;
89
96
  render(): import("lit").TemplateResult<1>;
90
97
  }
@@ -188,10 +188,10 @@ var Tab = class extends ThemeableElement {
188
188
  };
189
189
  Tab.styles = tabStyles;
190
190
  __decorateClass([
191
- property2()
191
+ property2({ reflect: true })
192
192
  ], Tab.prototype, "label", 2);
193
193
  __decorateClass([
194
- property2()
194
+ property2({ reflect: true })
195
195
  ], Tab.prototype, "value", 2);
196
196
  __decorateClass([
197
197
  property2({ attribute: "icon-start" })
@@ -248,10 +248,10 @@ var Tab = class extends ThemeableElement {
248
248
  };
249
249
  Tab.styles = tabStyles;
250
250
  __decorateClass([
251
- property2()
251
+ property2({ reflect: true })
252
252
  ], Tab.prototype, "label", 2);
253
253
  __decorateClass([
254
- property2()
254
+ property2({ reflect: true })
255
255
  ], Tab.prototype, "value", 2);
256
256
  __decorateClass([
257
257
  property2({ attribute: "icon-start" })
@@ -419,7 +419,7 @@ var TabGroup = class extends ThemeableElement {
419
419
  };
420
420
  TabGroup.styles = tabGroupStyles;
421
421
  __decorateClass([
422
- property4()
422
+ property4({ reflect: true })
423
423
  ], TabGroup.prototype, "value", 2);
424
424
  __decorateClass([
425
425
  property4({ reflect: true })
@@ -460,13 +460,14 @@ Text = __decorateClass([
460
460
  // src/components/textfield/textfield.ts
461
461
  var Textfield = class extends ThemeableElement {
462
462
  constructor() {
463
- super(...arguments);
463
+ super();
464
464
  this.variant = "default";
465
465
  this.size = "md";
466
466
  this.type = "text";
467
467
  this.value = "";
468
468
  this.placeholder = "";
469
469
  this.label = "";
470
+ this.name = "";
470
471
  this.helperText = "";
471
472
  this.disabled = false;
472
473
  this.required = false;
@@ -485,6 +486,7 @@ var Textfield = class extends ThemeableElement {
485
486
  this._touched = true;
486
487
  this._autoError = !this._validate();
487
488
  };
489
+ this._internals = this.attachInternals();
488
490
  }
489
491
  /**
490
492
  * Handles input events from the native input or textarea element.
@@ -582,6 +584,22 @@ var Textfield = class extends ThemeableElement {
582
584
  updated(changed) {
583
585
  super.updated(changed);
584
586
  this.toggleAttribute("data-invalid", this._autoError);
587
+ this._internals.setFormValue(this.value || null);
588
+ const anchor = this.shadowRoot.querySelector("input") ?? this.shadowRoot.querySelector("textarea");
589
+ if (this.required && !this.value && anchor) {
590
+ this._internals.setValidity({ valueMissing: true }, "Please fill in this field", anchor);
591
+ } else {
592
+ this._internals.setValidity({});
593
+ }
594
+ }
595
+ formResetCallback() {
596
+ this.value = "";
597
+ }
598
+ checkValidity() {
599
+ return this._internals.checkValidity();
600
+ }
601
+ reportValidity() {
602
+ return this._internals.reportValidity();
585
603
  }
586
604
  render() {
587
605
  const hasStartIcon = Boolean(this.iconStart);
@@ -656,6 +674,7 @@ var Textfield = class extends ThemeableElement {
656
674
  }
657
675
  };
658
676
  Textfield.styles = textfieldStyles;
677
+ Textfield.formAssociated = true;
659
678
  __decorateClass([
660
679
  property3({ reflect: true })
661
680
  ], Textfield.prototype, "variant", 2);
@@ -666,14 +685,17 @@ __decorateClass([
666
685
  property3({ reflect: true })
667
686
  ], Textfield.prototype, "type", 2);
668
687
  __decorateClass([
669
- property3()
688
+ property3({ reflect: true })
670
689
  ], Textfield.prototype, "value", 2);
671
690
  __decorateClass([
672
- property3()
691
+ property3({ reflect: true })
673
692
  ], Textfield.prototype, "placeholder", 2);
674
693
  __decorateClass([
675
- property3()
694
+ property3({ reflect: true })
676
695
  ], Textfield.prototype, "label", 2);
696
+ __decorateClass([
697
+ property3({ reflect: true })
698
+ ], Textfield.prototype, "name", 2);
677
699
  __decorateClass([
678
700
  property3({ attribute: "helper-text" })
679
701
  ], Textfield.prototype, "helperText", 2);
@@ -44,6 +44,9 @@ import '../text/text';
44
44
  */
45
45
  export declare class Textfield extends ThemeableElement {
46
46
  static styles: import("lit").CSSResult;
47
+ static formAssociated: boolean;
48
+ private _internals;
49
+ constructor();
47
50
  /**
48
51
  * Visual variant that determines styling and automatic end icon.
49
52
  * @default 'default'
@@ -74,6 +77,11 @@ export declare class Textfield extends ThemeableElement {
74
77
  * @default ''
75
78
  */
76
79
  label: string;
80
+ /**
81
+ * Name used when submitting a form.
82
+ * @default ''
83
+ */
84
+ name: string;
77
85
  /**
78
86
  * Helper text displayed below the input. Can be a static string or a function
79
87
  * that receives the current error state and returns the string to display.
@@ -164,5 +172,8 @@ export declare class Textfield extends ThemeableElement {
164
172
  */
165
173
  private getEndIconName;
166
174
  updated(changed: PropertyValues): void;
175
+ formResetCallback(): void;
176
+ checkValidity(): boolean;
177
+ reportValidity(): boolean;
167
178
  render(): import("lit").TemplateResult<1>;
168
179
  }