@waggylabs/yumekit 0.5.0-beta.76 → 0.5.0-beta.79

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/CHANGELOG.md CHANGED
@@ -53,6 +53,8 @@ Delete any empty sections before publishing.
53
53
 
54
54
  - New `y-paginator` component — page navigation control with a configurable button window.
55
55
 
56
+ - New `y-animate` component — a declarative wrapper that applies CSS-based entrance animations to its slotted children.
57
+
56
58
  ### Changed
57
59
 
58
60
  - **Icon rename — `comp-*` prefix dropped.** All 26 component-illustrating icons renamed. Two resolved collisions: `comp-menu` → `droplist` and `comp-tag` → `chip`.
@@ -90,7 +92,7 @@ Delete any empty sections before publishing.
90
92
 
91
93
  | Old name | New name | Glyph |
92
94
  | ---------- | ---------------------- | -------------------------- |
93
- | `ai` | `robot` | Microchip / CPU |
95
+ | `ai` | `robot` | Robot Head |
94
96
  | `ban` | `circle-slash` | Circle with diagonal slash |
95
97
  | `chart` | `waveform` | ECG / pulse waveform |
96
98
  | `close` | `x` | × mark |
@@ -113,6 +115,10 @@ Delete any empty sections before publishing.
113
115
 
114
116
  - **Breaking** `y-stack`: refocused as a flexbox-only primitive. Migration: `<y-stack mode="grid" …>` → `<y-grid …>`; `<y-stack mode="masonry" …>` → `<y-masonry …>`. The `mode` and `columns` attributes and the related `--component-stack-*` variables are removed.
115
117
 
118
+ ### Fixed
119
+
120
+ - `y-avatar`: when the image at `src` fails to load, the component now falls back to the initials rendering rather than displaying the browser's broken-image graphic.
121
+
116
122
  ### Security
117
123
 
118
124
  - **Breaking** `y-appbar` / `y-sidebar`: nav-item `icon` no longer accepts raw SVG markup — only registered icon names. Use `registerIcon` / `registerIcons` for custom glyphs.
@@ -1,5 +1,6 @@
1
1
  export class YumeAvatar extends HTMLElement {
2
2
  static get observedAttributes(): string[];
3
+ _imgFailed: boolean;
3
4
  attributeChangedCallback(name: any, oldValue: any, newValue: any): void;
4
5
  set alt(val: string);
5
6
  /** Initials fallback text when no src is provided (default "AN"). */
@@ -17,8 +18,8 @@ export class YumeAvatar extends HTMLElement {
17
18
  /** Image URL. When set, renders an <img> instead of initials. */
18
19
  get src(): string;
19
20
  render(): void;
20
- _buildAvatar(): HTMLElement;
21
- _buildStyleSheet(dimensions: any, borderRadius: any, bgColor: any, textColor: any): CSSStyleSheet;
21
+ _buildAvatar(showImg: any): HTMLElement;
22
+ _buildStyleSheet(showImg: any, dimensions: any, borderRadius: any, bgColor: any, textColor: any): CSSStyleSheet;
22
23
  _getDimensions(size: any): any;
23
24
  _getInitials(alt: any): any;
24
25
  }
@@ -12,11 +12,14 @@ class YumeAvatar extends HTMLElement {
12
12
  constructor() {
13
13
  super();
14
14
  this.attachShadow({ mode: "open" });
15
+ this._imgFailed = false;
15
16
  this.render();
16
17
  }
17
18
 
18
19
  attributeChangedCallback(name, oldValue, newValue) {
19
- if (oldValue !== newValue) this.render();
20
+ if (oldValue === newValue) return;
21
+ if (name === "src") this._imgFailed = false;
22
+ this.render();
20
23
  }
21
24
 
22
25
  // -------------------------------------------------------------------------
@@ -54,31 +57,37 @@ class YumeAvatar extends HTMLElement {
54
57
  const dimensions = this._getDimensions(this.size);
55
58
  const borderRadius = `var(--component-avatar-border-radius-${this.shape}, 9999px)`;
56
59
  const [bgColor, textColor] = getColorVarPair(this.color);
60
+ const showImg = !!this.src && !this._imgFailed;
57
61
 
58
- this.shadowRoot.adoptedStyleSheets = [this._buildStyleSheet(dimensions, borderRadius, bgColor, textColor)];
59
- this.shadowRoot.replaceChildren(this._buildAvatar());
62
+ this.shadowRoot.adoptedStyleSheets = [this._buildStyleSheet(showImg, dimensions, borderRadius, bgColor, textColor)];
63
+ this.shadowRoot.replaceChildren(this._buildAvatar(showImg));
60
64
  }
61
65
 
62
66
  // -------------------------------------------------------------------------
63
67
  // Private
64
68
  // -------------------------------------------------------------------------
65
69
 
66
- _buildAvatar() {
67
- if (this.src) {
68
- return createElement("img", {
70
+ _buildAvatar(showImg) {
71
+ if (showImg) {
72
+ const img = createElement("img", {
69
73
  src: this.src,
70
74
  alt: this.alt,
71
75
  part: "avatar",
72
76
  });
77
+ img.addEventListener("error", () => {
78
+ this._imgFailed = true;
79
+ this.render();
80
+ }, { once: true });
81
+ return img;
73
82
  }
74
83
  return createElement("div", { class: "avatar", part: "avatar" }, [
75
84
  createElement("h5", null, [this._getInitials(this.alt)]),
76
85
  ]);
77
86
  }
78
87
 
79
- _buildStyleSheet(dimensions, borderRadius, bgColor, textColor) {
88
+ _buildStyleSheet(showImg, dimensions, borderRadius, bgColor, textColor) {
80
89
  const sheet = new CSSStyleSheet();
81
- const css = this.src
90
+ const css = showImg
82
91
  ? `
83
92
  :host {
84
93
  display: inline-block;
@@ -1,5 +1,6 @@
1
1
  export class YumeAvatar extends HTMLElement {
2
2
  static get observedAttributes(): string[];
3
+ _imgFailed: boolean;
3
4
  attributeChangedCallback(name: any, oldValue: any, newValue: any): void;
4
5
  set alt(val: string);
5
6
  /** Initials fallback text when no src is provided (default "AN"). */
@@ -17,8 +18,8 @@ export class YumeAvatar extends HTMLElement {
17
18
  /** Image URL. When set, renders an <img> instead of initials. */
18
19
  get src(): string;
19
20
  render(): void;
20
- _buildAvatar(): HTMLElement;
21
- _buildStyleSheet(dimensions: any, borderRadius: any, bgColor: any, textColor: any): CSSStyleSheet;
21
+ _buildAvatar(showImg: any): HTMLElement;
22
+ _buildStyleSheet(showImg: any, dimensions: any, borderRadius: any, bgColor: any, textColor: any): CSSStyleSheet;
22
23
  _getDimensions(size: any): any;
23
24
  _getInitials(alt: any): any;
24
25
  }
@@ -12,11 +12,14 @@ class YumeAvatar extends HTMLElement {
12
12
  constructor() {
13
13
  super();
14
14
  this.attachShadow({ mode: "open" });
15
+ this._imgFailed = false;
15
16
  this.render();
16
17
  }
17
18
 
18
19
  attributeChangedCallback(name, oldValue, newValue) {
19
- if (oldValue !== newValue) this.render();
20
+ if (oldValue === newValue) return;
21
+ if (name === "src") this._imgFailed = false;
22
+ this.render();
20
23
  }
21
24
 
22
25
  // -------------------------------------------------------------------------
@@ -54,31 +57,37 @@ class YumeAvatar extends HTMLElement {
54
57
  const dimensions = this._getDimensions(this.size);
55
58
  const borderRadius = `var(--component-avatar-border-radius-${this.shape}, 9999px)`;
56
59
  const [bgColor, textColor] = getColorVarPair(this.color);
60
+ const showImg = !!this.src && !this._imgFailed;
57
61
 
58
- this.shadowRoot.adoptedStyleSheets = [this._buildStyleSheet(dimensions, borderRadius, bgColor, textColor)];
59
- this.shadowRoot.replaceChildren(this._buildAvatar());
62
+ this.shadowRoot.adoptedStyleSheets = [this._buildStyleSheet(showImg, dimensions, borderRadius, bgColor, textColor)];
63
+ this.shadowRoot.replaceChildren(this._buildAvatar(showImg));
60
64
  }
61
65
 
62
66
  // -------------------------------------------------------------------------
63
67
  // Private
64
68
  // -------------------------------------------------------------------------
65
69
 
66
- _buildAvatar() {
67
- if (this.src) {
68
- return createElement("img", {
70
+ _buildAvatar(showImg) {
71
+ if (showImg) {
72
+ const img = createElement("img", {
69
73
  src: this.src,
70
74
  alt: this.alt,
71
75
  part: "avatar",
72
76
  });
77
+ img.addEventListener("error", () => {
78
+ this._imgFailed = true;
79
+ this.render();
80
+ }, { once: true });
81
+ return img;
73
82
  }
74
83
  return createElement("div", { class: "avatar", part: "avatar" }, [
75
84
  createElement("h5", null, [this._getInitials(this.alt)]),
76
85
  ]);
77
86
  }
78
87
 
79
- _buildStyleSheet(dimensions, borderRadius, bgColor, textColor) {
88
+ _buildStyleSheet(showImg, dimensions, borderRadius, bgColor, textColor) {
80
89
  const sheet = new CSSStyleSheet();
81
- const css = this.src
90
+ const css = showImg
82
91
  ? `
83
92
  :host {
84
93
  display: inline-block;
@@ -268,6 +268,14 @@ export class YumeDroplist extends HTMLElement {
268
268
  _findListForElement(el: any): any;
269
269
  _findSwapTarget(e: any): Element;
270
270
  _flip(snapshot: any): void;
271
+ /**
272
+ * Pick the element to mount drag-time overlays (preview, float ghost) into.
273
+ * Prefer the nearest `<y-theme>` ancestor so the overlay inherits the theme's
274
+ * CSS custom properties — `y-theme` sets them as inline styles on its host,
275
+ * so they only cascade to descendants. Falls back to `document.body` when no
276
+ * `<y-theme>` is in scope.
277
+ */
278
+ _getOverlayHost(): any;
271
279
  /**
272
280
  * Returns the zero-based index at which the ghost is currently projected
273
281
  * to be inserted (counting only non-ghost children before the ghost).
@@ -268,6 +268,14 @@ export class YumeDroplist extends HTMLElement {
268
268
  _findListForElement(el: any): any;
269
269
  _findSwapTarget(e: any): Element;
270
270
  _flip(snapshot: any): void;
271
+ /**
272
+ * Pick the element to mount drag-time overlays (preview, float ghost) into.
273
+ * Prefer the nearest `<y-theme>` ancestor so the overlay inherits the theme's
274
+ * CSS custom properties — `y-theme` sets them as inline styles on its host,
275
+ * so they only cascade to descendants. Falls back to `document.body` when no
276
+ * `<y-theme>` is in scope.
277
+ */
278
+ _getOverlayHost(): any;
271
279
  /**
272
280
  * Returns the zero-based index at which the ghost is currently projected
273
281
  * to be inserted (counting only non-ghost children before the ghost).
@@ -919,7 +919,7 @@ class YumeDroplist extends HTMLElement {
919
919
  return;
920
920
  }
921
921
 
922
- document.body.appendChild(preview);
922
+ this._getOverlayHost().appendChild(preview);
923
923
  this._dragPreview = preview;
924
924
  _previewOwner = this;
925
925
 
@@ -1192,6 +1192,20 @@ class YumeDroplist extends HTMLElement {
1192
1192
  }
1193
1193
  }
1194
1194
 
1195
+ /**
1196
+ * Pick the element to mount drag-time overlays (preview, float ghost) into.
1197
+ * Prefer the nearest `<y-theme>` ancestor so the overlay inherits the theme's
1198
+ * CSS custom properties — `y-theme` sets them as inline styles on its host,
1199
+ * so they only cascade to descendants. Falls back to `document.body` when no
1200
+ * `<y-theme>` is in scope.
1201
+ */
1202
+ _getOverlayHost() {
1203
+ // `this.closest()` is overridden as a public coordinate-lookup API on
1204
+ // y-droplist, so reach for the native traversal via the prototype.
1205
+ const theme = Element.prototype.closest.call(this, "y-theme");
1206
+ return theme || document.body;
1207
+ }
1208
+
1195
1209
  /**
1196
1210
  * Returns the zero-based index at which the ghost is currently projected
1197
1211
  * to be inserted (counting only non-ghost children before the ghost).
@@ -1728,7 +1742,7 @@ class YumeDroplist extends HTMLElement {
1728
1742
  this._positionFloatGhost(reference);
1729
1743
 
1730
1744
  if (!this._ghost.parentNode) {
1731
- document.body.appendChild(this._ghost);
1745
+ this._getOverlayHost().appendChild(this._ghost);
1732
1746
  }
1733
1747
  } else {
1734
1748
  if (
@@ -531,8 +531,11 @@ class YumeGallery extends HTMLElement {
531
531
  });
532
532
  if (!this.dispatchEvent(event)) return;
533
533
 
534
- const item_el = this.shadowRoot.querySelector(`.item[data-index="${index}"]`);
535
- this._previouslyFocused = item_el?.querySelector(".item-btn") || item_el;
534
+ const item_el = this.shadowRoot.querySelector(
535
+ `.item[data-index="${index}"]`,
536
+ );
537
+ this._previouslyFocused =
538
+ item_el?.querySelector(".item-btn") || item_el;
536
539
  this._expandedIndex = index;
537
540
  this._showExpandedView();
538
541
  document.addEventListener("keydown", this._onKeyDown);
@@ -753,7 +756,7 @@ class YumeGallery extends HTMLElement {
753
756
  const closeBtn = this._createNavButton(
754
757
  "expand-close",
755
758
  "Close image viewer",
756
- "close",
759
+ "x",
757
760
  "expand-close-icon",
758
761
  );
759
762
  const prevBtn = this._createNavButton(
@@ -941,14 +944,28 @@ class YumeGallery extends HTMLElement {
941
944
  }
942
945
 
943
946
  _createItemWrapper(data, index) {
944
- const attrs = { class: "item", part: "item", role: "listitem", "data-index": String(index) };
945
- const img = createElement("img", { src: data.src, alt: data.alt, part: "item-img", draggable: "false" });
947
+ const attrs = {
948
+ class: "item",
949
+ part: "item",
950
+ role: "listitem",
951
+ "data-index": String(index),
952
+ };
953
+ const img = createElement("img", {
954
+ src: data.src,
955
+ alt: data.alt,
956
+ part: "item-img",
957
+ draggable: "false",
958
+ });
946
959
 
947
960
  if (this.expandable) {
948
- const btn = createElement("button", {
949
- class: "item-btn",
950
- "aria-label": `View image: ${data.alt || `Image ${index + 1}`}`,
951
- }, [img]);
961
+ const btn = createElement(
962
+ "button",
963
+ {
964
+ class: "item-btn",
965
+ "aria-label": `View image: ${data.alt || `Image ${index + 1}`}`,
966
+ },
967
+ [img],
968
+ );
952
969
  btn.addEventListener("click", () => this.open(index));
953
970
  return createElement("div", attrs, [btn]);
954
971
  }
@@ -1020,7 +1037,9 @@ class YumeGallery extends HTMLElement {
1020
1037
  if (!data) return;
1021
1038
 
1022
1039
  this._items.push(data);
1023
- gallery.appendChild(this._createItemWrapper(data, this._items.length - 1));
1040
+ gallery.appendChild(
1041
+ this._createItemWrapper(data, this._items.length - 1),
1042
+ );
1024
1043
  });
1025
1044
  }
1026
1045
 
@@ -1060,7 +1079,11 @@ class YumeGallery extends HTMLElement {
1060
1079
 
1061
1080
  if (gapMap[gap]) return gapMap[gap];
1062
1081
 
1063
- if (typeof CSS !== "undefined" && CSS.supports && CSS.supports("gap", gap)) {
1082
+ if (
1083
+ typeof CSS !== "undefined" &&
1084
+ CSS.supports &&
1085
+ CSS.supports("gap", gap)
1086
+ ) {
1064
1087
  return gap;
1065
1088
  }
1066
1089
 
@@ -313,6 +313,7 @@ class YumeProgress extends HTMLElement {
313
313
  }
314
314
  set values(val) {
315
315
  if (val === null || val === undefined) this.removeAttribute("values");
316
+ else if (typeof val === "string") this.setAttribute("values", val);
316
317
  else this.setAttribute("values", JSON.stringify(val));
317
318
  }
318
319
 
package/dist/index.js CHANGED
@@ -3690,11 +3690,14 @@ class YumeAvatar extends HTMLElement {
3690
3690
  constructor() {
3691
3691
  super();
3692
3692
  this.attachShadow({ mode: "open" });
3693
+ this._imgFailed = false;
3693
3694
  this.render();
3694
3695
  }
3695
3696
 
3696
3697
  attributeChangedCallback(name, oldValue, newValue) {
3697
- if (oldValue !== newValue) this.render();
3698
+ if (oldValue === newValue) return;
3699
+ if (name === "src") this._imgFailed = false;
3700
+ this.render();
3698
3701
  }
3699
3702
 
3700
3703
  // -------------------------------------------------------------------------
@@ -3732,31 +3735,37 @@ class YumeAvatar extends HTMLElement {
3732
3735
  const dimensions = this._getDimensions(this.size);
3733
3736
  const borderRadius = `var(--component-avatar-border-radius-${this.shape}, 9999px)`;
3734
3737
  const [bgColor, textColor] = getColorVarPair(this.color);
3738
+ const showImg = !!this.src && !this._imgFailed;
3735
3739
 
3736
- this.shadowRoot.adoptedStyleSheets = [this._buildStyleSheet(dimensions, borderRadius, bgColor, textColor)];
3737
- this.shadowRoot.replaceChildren(this._buildAvatar());
3740
+ this.shadowRoot.adoptedStyleSheets = [this._buildStyleSheet(showImg, dimensions, borderRadius, bgColor, textColor)];
3741
+ this.shadowRoot.replaceChildren(this._buildAvatar(showImg));
3738
3742
  }
3739
3743
 
3740
3744
  // -------------------------------------------------------------------------
3741
3745
  // Private
3742
3746
  // -------------------------------------------------------------------------
3743
3747
 
3744
- _buildAvatar() {
3745
- if (this.src) {
3746
- return createElement("img", {
3748
+ _buildAvatar(showImg) {
3749
+ if (showImg) {
3750
+ const img = createElement("img", {
3747
3751
  src: this.src,
3748
3752
  alt: this.alt,
3749
3753
  part: "avatar",
3750
3754
  });
3755
+ img.addEventListener("error", () => {
3756
+ this._imgFailed = true;
3757
+ this.render();
3758
+ }, { once: true });
3759
+ return img;
3751
3760
  }
3752
3761
  return createElement("div", { class: "avatar", part: "avatar" }, [
3753
3762
  createElement("h5", null, [this._getInitials(this.alt)]),
3754
3763
  ]);
3755
3764
  }
3756
3765
 
3757
- _buildStyleSheet(dimensions, borderRadius, bgColor, textColor) {
3766
+ _buildStyleSheet(showImg, dimensions, borderRadius, bgColor, textColor) {
3758
3767
  const sheet = new CSSStyleSheet();
3759
- const css = this.src
3768
+ const css = showImg
3760
3769
  ? `
3761
3770
  :host {
3762
3771
  display: inline-block;
@@ -13646,7 +13655,7 @@ class YumeDroplist extends HTMLElement {
13646
13655
  return;
13647
13656
  }
13648
13657
 
13649
- document.body.appendChild(preview);
13658
+ this._getOverlayHost().appendChild(preview);
13650
13659
  this._dragPreview = preview;
13651
13660
  _previewOwner = this;
13652
13661
 
@@ -13919,6 +13928,20 @@ class YumeDroplist extends HTMLElement {
13919
13928
  }
13920
13929
  }
13921
13930
 
13931
+ /**
13932
+ * Pick the element to mount drag-time overlays (preview, float ghost) into.
13933
+ * Prefer the nearest `<y-theme>` ancestor so the overlay inherits the theme's
13934
+ * CSS custom properties — `y-theme` sets them as inline styles on its host,
13935
+ * so they only cascade to descendants. Falls back to `document.body` when no
13936
+ * `<y-theme>` is in scope.
13937
+ */
13938
+ _getOverlayHost() {
13939
+ // `this.closest()` is overridden as a public coordinate-lookup API on
13940
+ // y-droplist, so reach for the native traversal via the prototype.
13941
+ const theme = Element.prototype.closest.call(this, "y-theme");
13942
+ return theme || document.body;
13943
+ }
13944
+
13922
13945
  /**
13923
13946
  * Returns the zero-based index at which the ghost is currently projected
13924
13947
  * to be inserted (counting only non-ghost children before the ghost).
@@ -14455,7 +14478,7 @@ class YumeDroplist extends HTMLElement {
14455
14478
  this._positionFloatGhost(reference);
14456
14479
 
14457
14480
  if (!this._ghost.parentNode) {
14458
- document.body.appendChild(this._ghost);
14481
+ this._getOverlayHost().appendChild(this._ghost);
14459
14482
  }
14460
14483
  } else {
14461
14484
  if (
@@ -15494,8 +15517,11 @@ class YumeGallery extends HTMLElement {
15494
15517
  });
15495
15518
  if (!this.dispatchEvent(event)) return;
15496
15519
 
15497
- const item_el = this.shadowRoot.querySelector(`.item[data-index="${index}"]`);
15498
- this._previouslyFocused = item_el?.querySelector(".item-btn") || item_el;
15520
+ const item_el = this.shadowRoot.querySelector(
15521
+ `.item[data-index="${index}"]`,
15522
+ );
15523
+ this._previouslyFocused =
15524
+ item_el?.querySelector(".item-btn") || item_el;
15499
15525
  this._expandedIndex = index;
15500
15526
  this._showExpandedView();
15501
15527
  document.addEventListener("keydown", this._onKeyDown);
@@ -15716,7 +15742,7 @@ class YumeGallery extends HTMLElement {
15716
15742
  const closeBtn = this._createNavButton(
15717
15743
  "expand-close",
15718
15744
  "Close image viewer",
15719
- "close",
15745
+ "x",
15720
15746
  "expand-close-icon",
15721
15747
  );
15722
15748
  const prevBtn = this._createNavButton(
@@ -15904,14 +15930,28 @@ class YumeGallery extends HTMLElement {
15904
15930
  }
15905
15931
 
15906
15932
  _createItemWrapper(data, index) {
15907
- const attrs = { class: "item", part: "item", role: "listitem", "data-index": String(index) };
15908
- const img = createElement("img", { src: data.src, alt: data.alt, part: "item-img", draggable: "false" });
15933
+ const attrs = {
15934
+ class: "item",
15935
+ part: "item",
15936
+ role: "listitem",
15937
+ "data-index": String(index),
15938
+ };
15939
+ const img = createElement("img", {
15940
+ src: data.src,
15941
+ alt: data.alt,
15942
+ part: "item-img",
15943
+ draggable: "false",
15944
+ });
15909
15945
 
15910
15946
  if (this.expandable) {
15911
- const btn = createElement("button", {
15912
- class: "item-btn",
15913
- "aria-label": `View image: ${data.alt || `Image ${index + 1}`}`,
15914
- }, [img]);
15947
+ const btn = createElement(
15948
+ "button",
15949
+ {
15950
+ class: "item-btn",
15951
+ "aria-label": `View image: ${data.alt || `Image ${index + 1}`}`,
15952
+ },
15953
+ [img],
15954
+ );
15915
15955
  btn.addEventListener("click", () => this.open(index));
15916
15956
  return createElement("div", attrs, [btn]);
15917
15957
  }
@@ -15983,7 +16023,9 @@ class YumeGallery extends HTMLElement {
15983
16023
  if (!data) return;
15984
16024
 
15985
16025
  this._items.push(data);
15986
- gallery.appendChild(this._createItemWrapper(data, this._items.length - 1));
16026
+ gallery.appendChild(
16027
+ this._createItemWrapper(data, this._items.length - 1),
16028
+ );
15987
16029
  });
15988
16030
  }
15989
16031
 
@@ -16023,7 +16065,11 @@ class YumeGallery extends HTMLElement {
16023
16065
 
16024
16066
  if (gapMap[gap]) return gapMap[gap];
16025
16067
 
16026
- if (typeof CSS !== "undefined" && CSS.supports && CSS.supports("gap", gap)) {
16068
+ if (
16069
+ typeof CSS !== "undefined" &&
16070
+ CSS.supports &&
16071
+ CSS.supports("gap", gap)
16072
+ ) {
16027
16073
  return gap;
16028
16074
  }
16029
16075
 
@@ -18523,6 +18569,7 @@ class YumeProgress extends HTMLElement {
18523
18569
  }
18524
18570
  set values(val) {
18525
18571
  if (val === null || val === undefined) this.removeAttribute("values");
18572
+ else if (typeof val === "string") this.setAttribute("values", val);
18526
18573
  else this.setAttribute("values", JSON.stringify(val));
18527
18574
  }
18528
18575