@waggylabs/yumekit 0.4.0-beta.41 → 0.4.0-beta.46
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 +1 -1
- package/dist/components/y-appbar.js +5 -0
- package/dist/components/y-menu.js +5 -0
- package/dist/components/y-select.js +169 -76
- package/dist/components/y-switch.d.ts +7 -4
- package/dist/components/y-switch.js +16 -7
- package/dist/components/y-table.js +5 -0
- package/dist/components/y-tag.js +103 -29
- package/dist/components/y-theme.js +1 -1
- package/dist/index.js +367 -170
- package/dist/modules/helpers.d.ts +25 -18
- package/dist/modules/helpers.js +84 -71
- package/dist/styles/variables.css +3 -3
- package/dist/yumekit.min.js +1 -1
- package/package.json +1 -1
package/CHANGELOG.md
CHANGED
|
@@ -42,7 +42,7 @@ Delete any empty sections before publishing.
|
|
|
42
42
|
- `y-select`: new `searchable` attribute — enables autocomplete-style inline filtering. In single mode the value display is replaced by a text input that clears on open (showing the current selection as a placeholder) and restores the selected label on close. In multi-tag mode the input appears after the last tag and the dropdown stays open after each selection.
|
|
43
43
|
- `y-select`: new `clearable` attribute — shows a clear button (using the `close` icon) when a value is selected. Works independently of `searchable`.
|
|
44
44
|
- `y-select` tag display mode: per-option `color` field — each option object in the `options` array may now include a `color` key (predefined scheme or CSS color) to individually color its tag.
|
|
45
|
-
- `y-switch`: new `color`
|
|
45
|
+
- `y-switch`: new `on-color` and `off-color` attributes for the toggle indicator when checked and unchecked respectively. Accepts predefined scheme names or custom CSS colors. Defaults to `"primary"` for on.
|
|
46
46
|
- Custom CSS color support (`#hex`, `rgb()`, `hsl()`) added to the `color` attribute of `y-avatar`, `y-button`, `y-icon`, `y-tag`, `y-toast`, and `y-tooltip`. Predefined scheme names continue to resolve through design tokens; custom values use WCAG-based luminance to auto-contrast the text color. `y-slider` already supported custom color passthrough.
|
|
47
47
|
|
|
48
48
|
### Changed
|
|
@@ -1,3 +1,5 @@
|
|
|
1
|
+
import { contrastTextColor } from '../modules/helpers.js';
|
|
2
|
+
|
|
1
3
|
var chevronDown = "<svg xmlns=\"http://www.w3.org/2000/svg\" viewBox=\"0 0 24 24\" fill=\"none\" stroke=\"currentColor\" stroke-width=\"1.5\" stroke-linecap=\"round\" stroke-linejoin=\"round\">\n <polyline points=\"6 9 12 15 18 9\"/>\n</svg>\n";
|
|
2
4
|
|
|
3
5
|
class YumeSelect extends HTMLElement {
|
|
@@ -54,7 +56,10 @@ class YumeSelect extends HTMLElement {
|
|
|
54
56
|
if (name === "value") {
|
|
55
57
|
if (this.hasAttribute("multiple")) {
|
|
56
58
|
this.selectedValues = new Set(
|
|
57
|
-
(newValue || "")
|
|
59
|
+
(newValue || "")
|
|
60
|
+
.split(",")
|
|
61
|
+
.map((v) => v.trim())
|
|
62
|
+
.filter(Boolean),
|
|
58
63
|
);
|
|
59
64
|
} else {
|
|
60
65
|
this._value = newValue || "";
|
|
@@ -65,17 +70,19 @@ class YumeSelect extends HTMLElement {
|
|
|
65
70
|
this._updateSelectedStyles();
|
|
66
71
|
}
|
|
67
72
|
|
|
68
|
-
if (
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
|
|
73
|
+
if (
|
|
74
|
+
[
|
|
75
|
+
"label-position",
|
|
76
|
+
"disabled",
|
|
77
|
+
"invalid",
|
|
78
|
+
"required",
|
|
79
|
+
"placeholder",
|
|
80
|
+
"options",
|
|
81
|
+
"size",
|
|
82
|
+
"searchable",
|
|
83
|
+
"clearable",
|
|
84
|
+
].includes(name)
|
|
85
|
+
) {
|
|
79
86
|
this.render();
|
|
80
87
|
}
|
|
81
88
|
|
|
@@ -89,44 +96,64 @@ class YumeSelect extends HTMLElement {
|
|
|
89
96
|
// -------------------------------------------------------------------------
|
|
90
97
|
|
|
91
98
|
/** @type {boolean} Whether to show a clear button when a value is selected. */
|
|
92
|
-
get clearable() {
|
|
99
|
+
get clearable() {
|
|
100
|
+
return this.hasAttribute("clearable");
|
|
101
|
+
}
|
|
93
102
|
set clearable(val) {
|
|
94
103
|
if (val) this.setAttribute("clearable", "");
|
|
95
104
|
else this.removeAttribute("clearable");
|
|
96
105
|
}
|
|
97
106
|
|
|
98
107
|
/** @type {boolean} Whether the select is disabled. */
|
|
99
|
-
get disabled() {
|
|
108
|
+
get disabled() {
|
|
109
|
+
return this.hasAttribute("disabled");
|
|
110
|
+
}
|
|
100
111
|
set disabled(val) {
|
|
101
112
|
if (val) this.setAttribute("disabled", "");
|
|
102
113
|
else this.removeAttribute("disabled");
|
|
103
114
|
}
|
|
104
115
|
|
|
105
116
|
/** @type {string} Display mode: "tag" for multi-select tag display. */
|
|
106
|
-
get displayMode() {
|
|
107
|
-
|
|
117
|
+
get displayMode() {
|
|
118
|
+
return this.getAttribute("display-mode") || "";
|
|
119
|
+
}
|
|
120
|
+
set displayMode(val) {
|
|
121
|
+
this.setAttribute("display-mode", val);
|
|
122
|
+
}
|
|
108
123
|
|
|
109
124
|
/** @type {boolean} Whether the select is in an invalid state. */
|
|
110
|
-
get invalid() {
|
|
125
|
+
get invalid() {
|
|
126
|
+
return this.hasAttribute("invalid");
|
|
127
|
+
}
|
|
111
128
|
set invalid(val) {
|
|
112
129
|
if (val) this.setAttribute("invalid", "");
|
|
113
130
|
else this.removeAttribute("invalid");
|
|
114
131
|
}
|
|
115
132
|
|
|
116
133
|
/** @type {string} Label position: "top" | "bottom" (default "top"). */
|
|
117
|
-
get labelPosition() {
|
|
118
|
-
|
|
134
|
+
get labelPosition() {
|
|
135
|
+
return this.getAttribute("label-position") || "top";
|
|
136
|
+
}
|
|
137
|
+
set labelPosition(val) {
|
|
138
|
+
this.setAttribute("label-position", val);
|
|
139
|
+
}
|
|
119
140
|
|
|
120
141
|
/** @type {boolean} Whether multiple values can be selected. */
|
|
121
|
-
get multiple() {
|
|
142
|
+
get multiple() {
|
|
143
|
+
return this.hasAttribute("multiple");
|
|
144
|
+
}
|
|
122
145
|
set multiple(val) {
|
|
123
146
|
if (val) this.setAttribute("multiple", "");
|
|
124
147
|
else this.removeAttribute("multiple");
|
|
125
148
|
}
|
|
126
149
|
|
|
127
150
|
/** @type {string} The form field name. */
|
|
128
|
-
get name() {
|
|
129
|
-
|
|
151
|
+
get name() {
|
|
152
|
+
return this.getAttribute("name") || "";
|
|
153
|
+
}
|
|
154
|
+
set name(val) {
|
|
155
|
+
this.setAttribute("name", val);
|
|
156
|
+
}
|
|
130
157
|
|
|
131
158
|
/** @type {Array<{value: string, label: string}>} The options array for the select. */
|
|
132
159
|
get options() {
|
|
@@ -137,30 +164,45 @@ class YumeSelect extends HTMLElement {
|
|
|
137
164
|
}
|
|
138
165
|
}
|
|
139
166
|
set options(val) {
|
|
140
|
-
this.setAttribute(
|
|
167
|
+
this.setAttribute(
|
|
168
|
+
"options",
|
|
169
|
+
Array.isArray(val) ? JSON.stringify(val) : (val ?? "[]"),
|
|
170
|
+
);
|
|
141
171
|
}
|
|
142
172
|
|
|
143
173
|
/** @type {string} Placeholder text when no value is selected. */
|
|
144
|
-
get placeholder() {
|
|
145
|
-
|
|
174
|
+
get placeholder() {
|
|
175
|
+
return this.getAttribute("placeholder") || "Select...";
|
|
176
|
+
}
|
|
177
|
+
set placeholder(val) {
|
|
178
|
+
this.setAttribute("placeholder", val);
|
|
179
|
+
}
|
|
146
180
|
|
|
147
181
|
/** @type {boolean} Whether the select requires a value. */
|
|
148
|
-
get required() {
|
|
182
|
+
get required() {
|
|
183
|
+
return this.hasAttribute("required");
|
|
184
|
+
}
|
|
149
185
|
set required(val) {
|
|
150
186
|
if (val) this.setAttribute("required", "");
|
|
151
187
|
else this.removeAttribute("required");
|
|
152
188
|
}
|
|
153
189
|
|
|
154
190
|
/** @type {boolean} Whether the dropdown shows an inline search filter input. */
|
|
155
|
-
get searchable() {
|
|
191
|
+
get searchable() {
|
|
192
|
+
return this.hasAttribute("searchable");
|
|
193
|
+
}
|
|
156
194
|
set searchable(val) {
|
|
157
195
|
if (val) this.setAttribute("searchable", "");
|
|
158
196
|
else this.removeAttribute("searchable");
|
|
159
197
|
}
|
|
160
198
|
|
|
161
199
|
/** @type {string} Select size: "small" | "medium" | "large" (default "medium"). */
|
|
162
|
-
get size() {
|
|
163
|
-
|
|
200
|
+
get size() {
|
|
201
|
+
return this.getAttribute("size") || "medium";
|
|
202
|
+
}
|
|
203
|
+
set size(val) {
|
|
204
|
+
this.setAttribute("size", val);
|
|
205
|
+
}
|
|
164
206
|
|
|
165
207
|
/** @type {string} The current selected value, or comma-separated values when multiple. */
|
|
166
208
|
get value() {
|
|
@@ -172,7 +214,9 @@ class YumeSelect extends HTMLElement {
|
|
|
172
214
|
set value(val) {
|
|
173
215
|
if (this.hasAttribute("multiple")) {
|
|
174
216
|
if (typeof val === "string") {
|
|
175
|
-
this.selectedValues = new Set(
|
|
217
|
+
this.selectedValues = new Set(
|
|
218
|
+
val.split(",").map((v) => v.trim()),
|
|
219
|
+
);
|
|
176
220
|
} else if (Array.isArray(val)) {
|
|
177
221
|
this.selectedValues = new Set(val);
|
|
178
222
|
}
|
|
@@ -263,17 +307,19 @@ class YumeSelect extends HTMLElement {
|
|
|
263
307
|
const isDisabled = this.hasAttribute("disabled");
|
|
264
308
|
const size = this.getAttribute("size") || "medium";
|
|
265
309
|
|
|
266
|
-
const paddingVar =
|
|
267
|
-
|
|
268
|
-
|
|
269
|
-
|
|
270
|
-
|
|
310
|
+
const paddingVar =
|
|
311
|
+
{
|
|
312
|
+
small: "--component-inputs-padding-small",
|
|
313
|
+
medium: "--component-inputs-padding-medium",
|
|
314
|
+
large: "--component-inputs-padding-large",
|
|
315
|
+
}[size] || "--component-inputs-padding-medium";
|
|
271
316
|
|
|
272
|
-
const minHeightVar =
|
|
273
|
-
|
|
274
|
-
|
|
275
|
-
|
|
276
|
-
|
|
317
|
+
const minHeightVar =
|
|
318
|
+
{
|
|
319
|
+
small: "var(--sizing-small, 32px)",
|
|
320
|
+
medium: "var(--sizing-medium, 40px)",
|
|
321
|
+
large: "var(--sizing-large, 56px)",
|
|
322
|
+
}[size] || "var(--sizing-medium, 40px)";
|
|
277
323
|
|
|
278
324
|
const sheet = new CSSStyleSheet();
|
|
279
325
|
sheet.replaceSync(`
|
|
@@ -407,7 +453,6 @@ class YumeSelect extends HTMLElement {
|
|
|
407
453
|
justify-content: center;
|
|
408
454
|
background: none;
|
|
409
455
|
border: none;
|
|
410
|
-
padding: 2px;
|
|
411
456
|
cursor: pointer;
|
|
412
457
|
color: inherit;
|
|
413
458
|
opacity: 0.6;
|
|
@@ -478,9 +523,13 @@ class YumeSelect extends HTMLElement {
|
|
|
478
523
|
});
|
|
479
524
|
|
|
480
525
|
// Prevent input click from bubbling to container (avoid re-focusing)
|
|
481
|
-
this.searchInput?.addEventListener("click", (e) =>
|
|
526
|
+
this.searchInput?.addEventListener("click", (e) =>
|
|
527
|
+
e.stopPropagation(),
|
|
528
|
+
);
|
|
482
529
|
} else {
|
|
483
|
-
this.selectContainer.addEventListener("click", () =>
|
|
530
|
+
this.selectContainer.addEventListener("click", () =>
|
|
531
|
+
this.toggleDropdown(),
|
|
532
|
+
);
|
|
484
533
|
}
|
|
485
534
|
|
|
486
535
|
// Clear button click → clear selection
|
|
@@ -497,18 +546,21 @@ class YumeSelect extends HTMLElement {
|
|
|
497
546
|
this._filterOptions("");
|
|
498
547
|
if (this.searchInput) {
|
|
499
548
|
this.searchInput.value = "";
|
|
500
|
-
this.searchInput.placeholder =
|
|
549
|
+
this.searchInput.placeholder =
|
|
550
|
+
this.getAttribute("placeholder") || "Select...";
|
|
501
551
|
this.searchInput.focus();
|
|
502
552
|
if (!this.dropdown.classList.contains("open")) {
|
|
503
553
|
this._openDropdown();
|
|
504
554
|
}
|
|
505
555
|
}
|
|
506
556
|
}
|
|
507
|
-
this.dispatchEvent(
|
|
508
|
-
|
|
509
|
-
|
|
510
|
-
|
|
511
|
-
|
|
557
|
+
this.dispatchEvent(
|
|
558
|
+
new CustomEvent("change", {
|
|
559
|
+
detail: { value: "" },
|
|
560
|
+
bubbles: true,
|
|
561
|
+
composed: true,
|
|
562
|
+
}),
|
|
563
|
+
);
|
|
512
564
|
this.updateValidation();
|
|
513
565
|
});
|
|
514
566
|
|
|
@@ -526,7 +578,10 @@ class YumeSelect extends HTMLElement {
|
|
|
526
578
|
this.selectedValues.add(val);
|
|
527
579
|
}
|
|
528
580
|
|
|
529
|
-
this.setAttribute(
|
|
581
|
+
this.setAttribute(
|
|
582
|
+
"value",
|
|
583
|
+
Array.from(this.selectedValues).join(","),
|
|
584
|
+
);
|
|
530
585
|
} else {
|
|
531
586
|
const isSelected = val === this.value;
|
|
532
587
|
if (isSelected && !isRequired) {
|
|
@@ -536,11 +591,13 @@ class YumeSelect extends HTMLElement {
|
|
|
536
591
|
}
|
|
537
592
|
}
|
|
538
593
|
|
|
539
|
-
this.dispatchEvent(
|
|
540
|
-
|
|
541
|
-
|
|
542
|
-
|
|
543
|
-
|
|
594
|
+
this.dispatchEvent(
|
|
595
|
+
new CustomEvent("change", {
|
|
596
|
+
detail: { value: this.value },
|
|
597
|
+
bubbles: true,
|
|
598
|
+
composed: true,
|
|
599
|
+
}),
|
|
600
|
+
);
|
|
544
601
|
|
|
545
602
|
this.updateValidation();
|
|
546
603
|
|
|
@@ -571,7 +628,8 @@ class YumeSelect extends HTMLElement {
|
|
|
571
628
|
});
|
|
572
629
|
|
|
573
630
|
const noResults = this.dropdown.querySelector(".no-results");
|
|
574
|
-
if (noResults)
|
|
631
|
+
if (noResults)
|
|
632
|
+
noResults.style.display = visibleCount === 0 ? "" : "none";
|
|
575
633
|
}
|
|
576
634
|
|
|
577
635
|
_generateTemplate() {
|
|
@@ -633,11 +691,14 @@ class YumeSelect extends HTMLElement {
|
|
|
633
691
|
${!isLabelTop ? '<div class="label-wrapper"><slot name="label"></slot></div>' : ""}
|
|
634
692
|
<div class="dropdown" part="dropdown">
|
|
635
693
|
${this.options
|
|
636
|
-
.map((opt) =>
|
|
637
|
-
|
|
638
|
-
|
|
639
|
-
|
|
640
|
-
|
|
694
|
+
.map((opt) => {
|
|
695
|
+
const isSelected = valueSet.has(opt.value);
|
|
696
|
+
const customColor = isSelected && opt.color && !["base","primary","secondary","success","warning","error","help"].includes(opt.color);
|
|
697
|
+
const inlineStyle = customColor
|
|
698
|
+
? `style="background:${opt.color};color:${contrastTextColor(opt.color)}"`
|
|
699
|
+
: "";
|
|
700
|
+
return `<div class="dropdown-item ${isSelected ? "selected" : ""}" data-value="${opt.value}" data-color="${opt.color || ""}" ${inlineStyle}>${opt.label}</div>`;
|
|
701
|
+
})
|
|
641
702
|
.join("")}
|
|
642
703
|
<div class="no-results" style="display:none">No results</div>
|
|
643
704
|
</div>
|
|
@@ -652,13 +713,21 @@ class YumeSelect extends HTMLElement {
|
|
|
652
713
|
if (isMulti && isTagMode) return "";
|
|
653
714
|
|
|
654
715
|
if (isMulti) {
|
|
655
|
-
const count = this.options.filter((opt) =>
|
|
716
|
+
const count = this.options.filter((opt) =>
|
|
717
|
+
this.selectedValues.has(opt.value),
|
|
718
|
+
).length;
|
|
656
719
|
return count > 0
|
|
657
720
|
? `${count} Selected`
|
|
658
721
|
: this.getAttribute("placeholder") || "Select...";
|
|
659
722
|
} else {
|
|
660
|
-
const selected = this.options.find(
|
|
661
|
-
|
|
723
|
+
const selected = this.options.find(
|
|
724
|
+
(opt) => opt.value === this.value,
|
|
725
|
+
);
|
|
726
|
+
return (
|
|
727
|
+
selected?.label ||
|
|
728
|
+
this.getAttribute("placeholder") ||
|
|
729
|
+
"Select..."
|
|
730
|
+
);
|
|
662
731
|
}
|
|
663
732
|
}
|
|
664
733
|
|
|
@@ -680,9 +749,14 @@ class YumeSelect extends HTMLElement {
|
|
|
680
749
|
this._onScrollOrResize = this._positionDropdown.bind(this);
|
|
681
750
|
|
|
682
751
|
// For single searchable: clear input so user can type fresh
|
|
683
|
-
if (
|
|
752
|
+
if (
|
|
753
|
+
this.searchable &&
|
|
754
|
+
!this.hasAttribute("multiple") &&
|
|
755
|
+
this.searchInput
|
|
756
|
+
) {
|
|
684
757
|
const currentLabel = this.value ? this._getDisplayText() : "";
|
|
685
|
-
this.searchInput.placeholder =
|
|
758
|
+
this.searchInput.placeholder =
|
|
759
|
+
currentLabel || this.getAttribute("placeholder") || "Select...";
|
|
686
760
|
this.searchInput.value = "";
|
|
687
761
|
this._filterOptions("");
|
|
688
762
|
}
|
|
@@ -712,7 +786,8 @@ class YumeSelect extends HTMLElement {
|
|
|
712
786
|
}
|
|
713
787
|
|
|
714
788
|
_queryRefs() {
|
|
715
|
-
this.selectContainer =
|
|
789
|
+
this.selectContainer =
|
|
790
|
+
this.shadowRoot.querySelector(".select-container");
|
|
716
791
|
this.dropdown = this.shadowRoot.querySelector(".dropdown");
|
|
717
792
|
this.labelWrapper = this.shadowRoot.querySelector(".label-wrapper");
|
|
718
793
|
this.displayElement = this.shadowRoot.querySelector(".value-display");
|
|
@@ -735,7 +810,9 @@ class YumeSelect extends HTMLElement {
|
|
|
735
810
|
|
|
736
811
|
this.displayElement.innerHTML = "";
|
|
737
812
|
|
|
738
|
-
const selected = this.options.filter((opt) =>
|
|
813
|
+
const selected = this.options.filter((opt) =>
|
|
814
|
+
this.selectedValues.has(opt.value),
|
|
815
|
+
);
|
|
739
816
|
|
|
740
817
|
selected.forEach((opt) => {
|
|
741
818
|
const tag = document.createElement("y-tag");
|
|
@@ -748,16 +825,21 @@ class YumeSelect extends HTMLElement {
|
|
|
748
825
|
|
|
749
826
|
tag.addEventListener("remove", () => {
|
|
750
827
|
this.selectedValues.delete(opt.value);
|
|
751
|
-
this.setAttribute(
|
|
828
|
+
this.setAttribute(
|
|
829
|
+
"value",
|
|
830
|
+
Array.from(this.selectedValues).join(","),
|
|
831
|
+
);
|
|
752
832
|
this._renderTags();
|
|
753
833
|
this._updateSelectedStyles();
|
|
754
834
|
this.updateValidation();
|
|
755
835
|
|
|
756
|
-
this.dispatchEvent(
|
|
757
|
-
|
|
758
|
-
|
|
759
|
-
|
|
760
|
-
|
|
836
|
+
this.dispatchEvent(
|
|
837
|
+
new CustomEvent("change", {
|
|
838
|
+
detail: { value: this.value },
|
|
839
|
+
bubbles: true,
|
|
840
|
+
composed: true,
|
|
841
|
+
}),
|
|
842
|
+
);
|
|
761
843
|
});
|
|
762
844
|
|
|
763
845
|
this.displayElement.appendChild(tag);
|
|
@@ -778,7 +860,8 @@ class YumeSelect extends HTMLElement {
|
|
|
778
860
|
if (isTagMode) {
|
|
779
861
|
this._renderTags();
|
|
780
862
|
if (isClearable && this.clearButton) {
|
|
781
|
-
this.clearButton.style.display =
|
|
863
|
+
this.clearButton.style.display =
|
|
864
|
+
this.selectedValues.size > 0 ? "flex" : "none";
|
|
782
865
|
}
|
|
783
866
|
} else if (isSearchable && !isMulti && this.searchInput) {
|
|
784
867
|
// Update inline search input to reflect current selection
|
|
@@ -808,9 +891,19 @@ class YumeSelect extends HTMLElement {
|
|
|
808
891
|
const isMulti = this.hasAttribute("multiple");
|
|
809
892
|
const valueSet = isMulti ? this.selectedValues : new Set([this.value]);
|
|
810
893
|
|
|
894
|
+
const namedColors = new Set(["base","primary","secondary","success","warning","error","help"]);
|
|
811
895
|
this.dropdown?.querySelectorAll(".dropdown-item").forEach((item) => {
|
|
812
896
|
const val = item.getAttribute("data-value");
|
|
813
|
-
|
|
897
|
+
const isSelected = valueSet.has(val);
|
|
898
|
+
item.classList.toggle("selected", isSelected);
|
|
899
|
+
const color = item.getAttribute("data-color");
|
|
900
|
+
if (isSelected && color && !namedColors.has(color)) {
|
|
901
|
+
item.style.background = color;
|
|
902
|
+
item.style.color = contrastTextColor(color);
|
|
903
|
+
} else {
|
|
904
|
+
item.style.background = "";
|
|
905
|
+
item.style.color = "";
|
|
906
|
+
}
|
|
814
907
|
});
|
|
815
908
|
}
|
|
816
909
|
|
|
@@ -10,9 +10,12 @@ declare class YumeSwitch extends HTMLElement {
|
|
|
10
10
|
set checked(val: boolean);
|
|
11
11
|
/** @type {boolean} Whether the switch is on. */
|
|
12
12
|
get checked(): boolean;
|
|
13
|
-
set
|
|
14
|
-
/** @type {string} Color theme for the active toggle. */
|
|
15
|
-
get
|
|
13
|
+
set onColor(val: string);
|
|
14
|
+
/** @type {string} Color theme for the active (on) toggle. */
|
|
15
|
+
get onColor(): string;
|
|
16
|
+
set offColor(val: string);
|
|
17
|
+
/** @type {string} Color theme for the inactive (off) toggle. Defaults to base. */
|
|
18
|
+
get offColor(): string;
|
|
16
19
|
set disabled(val: boolean);
|
|
17
20
|
/** @type {boolean} Whether the switch is disabled. */
|
|
18
21
|
get disabled(): boolean;
|
|
@@ -36,7 +39,7 @@ declare class YumeSwitch extends HTMLElement {
|
|
|
36
39
|
_buildStyleSheet(): CSSStyleSheet;
|
|
37
40
|
_labelTag(pos: any): "" | "<label class=\"label-wrapper\"><slot name=\"label\"></slot></label>";
|
|
38
41
|
_mirrorToggleLabels(): void;
|
|
39
|
-
|
|
42
|
+
_resolveColor(color: any, fallback: any): any;
|
|
40
43
|
_update(): void;
|
|
41
44
|
_updateAria(): void;
|
|
42
45
|
_updateDirection(): void;
|
|
@@ -2,7 +2,7 @@ class YumeSwitch extends HTMLElement {
|
|
|
2
2
|
static formAssociated = true;
|
|
3
3
|
|
|
4
4
|
static get observedAttributes() {
|
|
5
|
-
return ["checked", "disabled", "animate", "toggle-label", "label-position", "size", "value", "color"];
|
|
5
|
+
return ["checked", "disabled", "animate", "toggle-label", "label-position", "size", "value", "on-color", "off-color"];
|
|
6
6
|
}
|
|
7
7
|
|
|
8
8
|
// -------------------------------------------------------------------------
|
|
@@ -45,9 +45,16 @@ class YumeSwitch extends HTMLElement {
|
|
|
45
45
|
this._update();
|
|
46
46
|
}
|
|
47
47
|
|
|
48
|
-
/** @type {string} Color theme for the active toggle. */
|
|
49
|
-
get
|
|
50
|
-
set
|
|
48
|
+
/** @type {string} Color theme for the active (on) toggle. */
|
|
49
|
+
get onColor() { return this.getAttribute("on-color") || "primary"; }
|
|
50
|
+
set onColor(val) { this.setAttribute("on-color", val); }
|
|
51
|
+
|
|
52
|
+
/** @type {string} Color theme for the inactive (off) toggle. Defaults to base. */
|
|
53
|
+
get offColor() { return this.getAttribute("off-color") || ""; }
|
|
54
|
+
set offColor(val) {
|
|
55
|
+
if (val) this.setAttribute("off-color", val);
|
|
56
|
+
else this.removeAttribute("off-color");
|
|
57
|
+
}
|
|
51
58
|
|
|
52
59
|
/** @type {boolean} Whether the switch is disabled. */
|
|
53
60
|
get disabled() { return this.hasAttribute("disabled"); }
|
|
@@ -282,7 +289,7 @@ class YumeSwitch extends HTMLElement {
|
|
|
282
289
|
});
|
|
283
290
|
}
|
|
284
291
|
|
|
285
|
-
|
|
292
|
+
_resolveColor(color, fallback) {
|
|
286
293
|
const predefined = {
|
|
287
294
|
primary: "var(--primary-content--)",
|
|
288
295
|
secondary: "var(--secondary-content--)",
|
|
@@ -292,7 +299,7 @@ class YumeSwitch extends HTMLElement {
|
|
|
292
299
|
error: "var(--error-content--)",
|
|
293
300
|
help: "var(--help-content--)",
|
|
294
301
|
};
|
|
295
|
-
return predefined[
|
|
302
|
+
return predefined[color] || color || fallback;
|
|
296
303
|
}
|
|
297
304
|
|
|
298
305
|
_update() {
|
|
@@ -364,7 +371,9 @@ class YumeSwitch extends HTMLElement {
|
|
|
364
371
|
: "0",
|
|
365
372
|
);
|
|
366
373
|
this.style.setProperty("--toggle-bg",
|
|
367
|
-
this.checked
|
|
374
|
+
this.checked
|
|
375
|
+
? this._resolveColor(this.onColor, "var(--primary-content--)")
|
|
376
|
+
: this._resolveColor(this.offColor, "var(--base-content-light)"),
|
|
368
377
|
);
|
|
369
378
|
this.style.setProperty("--toggle-transition",
|
|
370
379
|
this.animate ? "transform 0.25s ease, background 0.25s ease" : "none",
|