color-elements 0.0.4 → 0.0.5
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/.claude/settings.local.json +30 -0
- package/.editorconfig +8 -0
- package/.prettierrc +17 -0
- package/.vscode/settings.json +7 -0
- package/README.md +27 -18
- package/_build/copy-config.js +15 -14
- package/_build/copy-config.json +4 -9
- package/_build/eleventy.js +8 -8
- package/_includes/component.njk +9 -14
- package/_includes/plain.njk +5 -0
- package/_redirects +1 -1
- package/assets/css/style.css +4 -4
- package/debug.html +46 -0
- package/package.json +19 -8
- package/src/channel-picker/channel-picker.css +4 -4
- package/src/channel-picker/channel-picker.js +15 -11
- package/src/channel-slider/channel-slider.css +14 -7
- package/src/channel-slider/channel-slider.js +13 -5
- package/src/color-chart/README.md +36 -5
- package/src/color-chart/color-chart-global.css +13 -12
- package/src/color-chart/color-chart-shadow.css +123 -0
- package/src/color-chart/color-chart.css +2 -112
- package/src/color-chart/color-chart.js +307 -103
- package/src/color-inline/color-inline.css +21 -16
- package/src/color-inline/color-inline.js +2 -3
- package/src/color-inline/style.css +1 -1
- package/src/color-picker/color-picker.css +3 -3
- package/src/color-picker/color-picker.js +14 -7
- package/src/color-scale/README.md +42 -2
- package/src/color-scale/color-scale.css +1 -1
- package/src/color-scale/color-scale.js +12 -9
- package/src/color-slider/README.md +17 -3
- package/src/color-slider/color-slider.css +54 -33
- package/src/color-slider/color-slider.js +9 -7
- package/src/color-swatch/color-swatch.css +41 -32
- package/src/color-swatch/color-swatch.js +17 -9
- package/src/common/color-element.js +34 -76
- package/src/common/dom.js +4 -2
- package/src/common/util.js +1 -1
- package/src/gamut-badge/gamut-badge.css +33 -13
- package/src/gamut-badge/gamut-badge.js +9 -7
- package/src/space-picker/space-picker.css +3 -3
- package/src/space-picker/space-picker.js +28 -10
- package/src/src.json +1 -1
|
@@ -42,7 +42,7 @@ const Self = class ColorSwatch extends ColorElement {
|
|
|
42
42
|
|
|
43
43
|
#updateStatic () {
|
|
44
44
|
let previousInput = this._el.input;
|
|
45
|
-
let input = this._el.input = this.querySelector("input");
|
|
45
|
+
let input = (this._el.input = this.querySelector("input"));
|
|
46
46
|
|
|
47
47
|
this.static = !input;
|
|
48
48
|
|
|
@@ -50,7 +50,9 @@ const Self = class ColorSwatch extends ColorElement {
|
|
|
50
50
|
this._el.wrapper.classList.toggle("static", this.static);
|
|
51
51
|
|
|
52
52
|
if (input && input !== previousInput) {
|
|
53
|
-
importIncrementable ??= import("https://incrementable.verou.me/incrementable.mjs").then(
|
|
53
|
+
importIncrementable ??= import("https://incrementable.verou.me/incrementable.mjs").then(
|
|
54
|
+
m => m.default,
|
|
55
|
+
);
|
|
54
56
|
importIncrementable?.then(Incrementable => new Incrementable(input));
|
|
55
57
|
|
|
56
58
|
input.addEventListener("input", evt => {
|
|
@@ -65,10 +67,14 @@ const Self = class ColorSwatch extends ColorElement {
|
|
|
65
67
|
|
|
66
68
|
get swatchTextContent () {
|
|
67
69
|
// Children that are not assigned to another slot
|
|
68
|
-
return [...this.childNodes]
|
|
70
|
+
return [...this.childNodes]
|
|
71
|
+
.filter(n => !n.slot)
|
|
72
|
+
.map(n => n.textContent)
|
|
73
|
+
.join("")
|
|
74
|
+
.trim();
|
|
69
75
|
}
|
|
70
76
|
|
|
71
|
-
propChangedCallback ({name, prop, detail: change}) {
|
|
77
|
+
propChangedCallback ({ name, prop, detail: change }) {
|
|
72
78
|
let input = this._el.input;
|
|
73
79
|
|
|
74
80
|
if (name === "gamuts") {
|
|
@@ -91,9 +97,11 @@ const Self = class ColorSwatch extends ColorElement {
|
|
|
91
97
|
this._el.gamutIndicator.addEventListener("gamutchange", evt => {
|
|
92
98
|
let gamut = this._el.gamutIndicator.gamut;
|
|
93
99
|
this.setAttribute("gamut", gamut);
|
|
94
|
-
this.dispatchEvent(
|
|
95
|
-
|
|
96
|
-
|
|
100
|
+
this.dispatchEvent(
|
|
101
|
+
new CustomEvent("gamutchange", {
|
|
102
|
+
detail: gamut,
|
|
103
|
+
}),
|
|
104
|
+
);
|
|
97
105
|
});
|
|
98
106
|
}
|
|
99
107
|
else {
|
|
@@ -137,7 +145,7 @@ const Self = class ColorSwatch extends ColorElement {
|
|
|
137
145
|
return;
|
|
138
146
|
}
|
|
139
147
|
|
|
140
|
-
this._el.info ??= Object.assign(document.createElement("dl"), {part: "info"});
|
|
148
|
+
this._el.info ??= Object.assign(document.createElement("dl"), { part: "info" });
|
|
141
149
|
if (!this._el.info.parentNode) {
|
|
142
150
|
this._el.colorWrapper.after(this._el.info);
|
|
143
151
|
}
|
|
@@ -153,7 +161,7 @@ const Self = class ColorSwatch extends ColorElement {
|
|
|
153
161
|
|
|
154
162
|
value = typeof value === "number" ? Number(value.toPrecision(4)) : value;
|
|
155
163
|
|
|
156
|
-
info.push(`<div class="coord"><dt>${
|
|
164
|
+
info.push(`<div class="coord"><dt>${label}</dt><dd>${value}</dd></div>`);
|
|
157
165
|
}
|
|
158
166
|
|
|
159
167
|
this._el.info.innerHTML = info.join("\n");
|
|
@@ -1,28 +1,32 @@
|
|
|
1
|
-
import
|
|
2
|
-
import
|
|
1
|
+
import Color from "colorjs.io";
|
|
2
|
+
import NudeElement from "nude-element";
|
|
3
|
+
import { states } from "nude-element/plugins";
|
|
4
|
+
import { defer, wait, dynamicAll, noOpTemplateTag as css } from "./util.js";
|
|
3
5
|
|
|
4
6
|
const baseGlobalStyles = css`
|
|
5
|
-
@keyframes fade-in {
|
|
6
|
-
|
|
7
|
-
|
|
7
|
+
@keyframes fade-in {
|
|
8
|
+
from {
|
|
9
|
+
opacity: 0;
|
|
10
|
+
}
|
|
11
|
+
}
|
|
8
12
|
|
|
9
|
-
:state(color-element) {
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
+
:state(color-element) {
|
|
14
|
+
&:state(loading) {
|
|
15
|
+
content-visibility: hidden;
|
|
16
|
+
opacity: 0;
|
|
13
17
|
|
|
14
|
-
|
|
15
|
-
|
|
18
|
+
&,
|
|
19
|
+
* {
|
|
20
|
+
transition-property: opacity !important;
|
|
21
|
+
}
|
|
16
22
|
}
|
|
17
|
-
}
|
|
18
23
|
|
|
19
|
-
|
|
20
|
-
|
|
24
|
+
&:not(:state(loading)) {
|
|
25
|
+
animation: fade-in 300ms both;
|
|
26
|
+
}
|
|
21
27
|
}
|
|
22
|
-
}
|
|
23
28
|
`;
|
|
24
29
|
|
|
25
|
-
|
|
26
30
|
const Self = class ColorElement extends NudeElement {
|
|
27
31
|
static url = import.meta.url;
|
|
28
32
|
// TODO make lazy
|
|
@@ -30,7 +34,8 @@ const Self = class ColorElement extends NudeElement {
|
|
|
30
34
|
static all = {};
|
|
31
35
|
static dependencies = new Set();
|
|
32
36
|
|
|
33
|
-
static globalStyles = [{css: baseGlobalStyles}];
|
|
37
|
+
static globalStyles = [{ css: baseGlobalStyles }];
|
|
38
|
+
static plugins = [states];
|
|
34
39
|
|
|
35
40
|
constructor () {
|
|
36
41
|
super();
|
|
@@ -38,40 +43,15 @@ const Self = class ColorElement extends NudeElement {
|
|
|
38
43
|
let Self = this.constructor;
|
|
39
44
|
|
|
40
45
|
if (Self.shadowTemplate !== undefined) {
|
|
41
|
-
this.attachShadow({mode: "open"});
|
|
46
|
+
this.attachShadow({ mode: "open" });
|
|
42
47
|
this.shadowRoot.innerHTML = Self.shadowTemplate;
|
|
43
48
|
}
|
|
44
49
|
|
|
45
|
-
this.
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
Self.whenReady.then(() => {
|
|
51
|
-
this._internals.states.delete("loading");
|
|
52
|
-
});
|
|
53
|
-
}
|
|
54
|
-
}
|
|
55
|
-
|
|
56
|
-
static init () {
|
|
57
|
-
let wasInitialized = super.init();
|
|
58
|
-
|
|
59
|
-
if (!wasInitialized) {
|
|
60
|
-
return wasInitialized;
|
|
61
|
-
}
|
|
62
|
-
|
|
63
|
-
if (this.fetchedStyles) {
|
|
64
|
-
this.ready.push(...this.fetchedStyles);
|
|
65
|
-
}
|
|
66
|
-
|
|
67
|
-
if (this.fetchedGlobalStyles) {
|
|
68
|
-
this.ready.push(...this.fetchedGlobalStyles );
|
|
69
|
-
}
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
this.ready[0].resolve();
|
|
73
|
-
|
|
74
|
-
return wasInitialized;
|
|
50
|
+
this.toggleState("color-element", true);
|
|
51
|
+
this.toggleState("loading", true);
|
|
52
|
+
Self.whenReady.then(() => {
|
|
53
|
+
this.toggleState("loading");
|
|
54
|
+
});
|
|
75
55
|
}
|
|
76
56
|
|
|
77
57
|
static ready = [defer()];
|
|
@@ -91,7 +71,7 @@ const Self = class ColorElement extends NudeElement {
|
|
|
91
71
|
|
|
92
72
|
if (this.shadowTemplate) {
|
|
93
73
|
// TODO find dependencies
|
|
94
|
-
let colorTagRegex = RegExp(`(?<=</)(${
|
|
74
|
+
let colorTagRegex = RegExp(`(?<=</)(${colorTags.join("|")})(?=>)`, "g");
|
|
95
75
|
(this.shadowTemplate.match(colorTagRegex) ?? []).forEach(tag => {
|
|
96
76
|
this.dependencies ??= new Set();
|
|
97
77
|
this.dependencies.add(tag);
|
|
@@ -99,41 +79,19 @@ const Self = class ColorElement extends NudeElement {
|
|
|
99
79
|
}
|
|
100
80
|
|
|
101
81
|
if (this.dependencies.size > 0) {
|
|
102
|
-
let whenDefined = [...this.dependencies].map(tag =>
|
|
82
|
+
let whenDefined = [...this.dependencies].map(tag =>
|
|
83
|
+
customElements.whenDefined(tag).then(Class => Class.whenReady));
|
|
103
84
|
this.ready.push(...whenDefined);
|
|
104
85
|
}
|
|
105
86
|
|
|
106
87
|
// Give other code a chance to overwrite Self.Color
|
|
107
88
|
await wait();
|
|
108
89
|
|
|
109
|
-
|
|
110
|
-
let specifier;
|
|
111
|
-
|
|
112
|
-
try {
|
|
113
|
-
// Is already loaded? (e.g. via an import map, or if we're in Node)
|
|
114
|
-
import.meta.resolve("colorjs.io");
|
|
115
|
-
specifier = "colorjs.io";
|
|
116
|
-
}
|
|
117
|
-
catch (e) {
|
|
118
|
-
// specifier = "../../node_modules/colorjs.io/dist/color.js";
|
|
119
|
-
specifier = "https://colorjs.io/dist/color.js";
|
|
120
|
-
}
|
|
121
|
-
|
|
122
|
-
Self.Color = import(specifier).then(module => module.default);
|
|
123
|
-
}
|
|
124
|
-
|
|
125
|
-
// We can't just use top level await, see https://bugs.webkit.org/show_bug.cgi?id=242740
|
|
126
|
-
if (getType(Self.Color) === "Promise") {
|
|
127
|
-
let ColorPending = Self.Color;
|
|
128
|
-
let Color = await ColorPending;
|
|
129
|
-
|
|
130
|
-
if (Self.Color === ColorPending) {
|
|
131
|
-
// Hasn't changed
|
|
132
|
-
Self.Color = Color;
|
|
133
|
-
}
|
|
134
|
-
}
|
|
90
|
+
Self.Color ??= Color;
|
|
135
91
|
|
|
136
92
|
customElements.define(this.tagName, this);
|
|
93
|
+
|
|
94
|
+
this.ready[0].resolve();
|
|
137
95
|
}
|
|
138
96
|
};
|
|
139
97
|
|
package/src/common/dom.js
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
export function named (host, attributes = ["id", "part"]) {
|
|
2
2
|
let ret = {};
|
|
3
|
-
let selector = attributes.map(attr => `[${
|
|
3
|
+
let selector = attributes.map(attr => `[${attr}]`).join(", ");
|
|
4
4
|
|
|
5
5
|
for (let el of host.shadowRoot.querySelectorAll(selector)) {
|
|
6
6
|
// Get the value of the first attribute in attributes that has a value
|
|
@@ -27,7 +27,9 @@ export function slots (host) {
|
|
|
27
27
|
|
|
28
28
|
export function toSlots ({
|
|
29
29
|
slots = this._slots,
|
|
30
|
-
slotElements = slots
|
|
30
|
+
slotElements = slots
|
|
31
|
+
? Object.values(slots)
|
|
32
|
+
: Array.from(this.shadowRoot.querySelectorAll("slot")),
|
|
31
33
|
}) {
|
|
32
34
|
let children = this.childNodes;
|
|
33
35
|
let assignments = new WeakMap();
|
package/src/common/util.js
CHANGED
|
@@ -67,7 +67,7 @@ export async function dynamicAll (promises) {
|
|
|
67
67
|
* @param {number} max
|
|
68
68
|
* @param {options} options
|
|
69
69
|
*/
|
|
70
|
-
export function getStep (min, max, {minSteps = 100, maxStep = 1} = {}) {
|
|
70
|
+
export function getStep (min, max, { minSteps = 100, maxStep = 1 } = {}) {
|
|
71
71
|
let range = Math.abs(max - min);
|
|
72
72
|
let step = range / minSteps;
|
|
73
73
|
|
|
@@ -7,27 +7,47 @@
|
|
|
7
7
|
--_color-invalid: var(--color-invalid, hsl(220 10% 60%));
|
|
8
8
|
|
|
9
9
|
/* Low-level scales, i.e. between pairs of our core colors */
|
|
10
|
-
--color-scale-1: color-mix(
|
|
11
|
-
|
|
10
|
+
--color-scale-1: color-mix(
|
|
11
|
+
in oklch,
|
|
12
|
+
var(--_color-green),
|
|
13
|
+
var(--_color-yellow) var(--progress-1)
|
|
14
|
+
);
|
|
15
|
+
--color-scale-2: color-mix(
|
|
16
|
+
in oklch,
|
|
17
|
+
var(--_color-yellow),
|
|
18
|
+
var(--_color-orange) var(--progress-2)
|
|
19
|
+
);
|
|
12
20
|
--color-scale-3: color-mix(in oklch, var(--_color-orange), var(--_color-red) var(--progress-3));
|
|
13
21
|
|
|
14
22
|
/* Recursive scales: their only purpose is to select one of the low-level scales, and will only ever have 0%/100% positions
|
|
15
23
|
For N colors there are N-2 + N-3 + ... + 1 = (N-1)(N-2) / 2 of these
|
|
16
24
|
*/
|
|
17
|
-
--color-scale-12: color-mix(
|
|
18
|
-
|
|
19
|
-
|
|
25
|
+
--color-scale-12: color-mix(
|
|
26
|
+
in oklch,
|
|
27
|
+
var(--color-scale-1),
|
|
28
|
+
var(--color-scale-2) var(--progress-12)
|
|
29
|
+
);
|
|
30
|
+
--color-scale-23: color-mix(
|
|
31
|
+
in oklch,
|
|
32
|
+
var(--color-scale-2),
|
|
33
|
+
var(--color-scale-3) var(--progress-23)
|
|
34
|
+
);
|
|
35
|
+
--color-scale-123: color-mix(
|
|
36
|
+
in oklch,
|
|
37
|
+
var(--color-scale-12),
|
|
38
|
+
var(--color-scale-23) var(--progress-123)
|
|
39
|
+
);
|
|
20
40
|
|
|
21
41
|
--gamut-progress: calc(var(--gamut-level) / (var(--gamut-count) - 1));
|
|
22
42
|
--progress-ext: calc(var(--gamut-progress) * 300%);
|
|
23
43
|
|
|
24
|
-
--progress-123: clamp(0%, (var(--progress-ext) - 150%)
|
|
25
|
-
--progress-12:
|
|
26
|
-
--progress-23:
|
|
44
|
+
--progress-123: clamp(0%, (var(--progress-ext) - 150%) * infinity, 100%);
|
|
45
|
+
--progress-12: clamp(0%, (var(--progress-ext) - 150% + 75%) * infinity, 100%);
|
|
46
|
+
--progress-23: clamp(0%, (var(--progress-ext) - 150% - 75%) * infinity, 100%);
|
|
27
47
|
|
|
28
|
-
--progress-1:
|
|
29
|
-
--progress-2:
|
|
30
|
-
--progress-3:
|
|
48
|
+
--progress-1: clamp(0%, var(--progress-ext), 100%);
|
|
49
|
+
--progress-2: calc(clamp(100%, var(--progress-ext), 200%) - 100%);
|
|
50
|
+
--progress-3: calc(clamp(200%, var(--progress-ext), 300%) - 200%);
|
|
31
51
|
|
|
32
52
|
--color-level-infinity: var(--_color-red-dark);
|
|
33
53
|
--color: var(--color-scale-123, var(--_color-invalid));
|
|
@@ -35,11 +55,11 @@
|
|
|
35
55
|
display: inline-flex;
|
|
36
56
|
align-items: center;
|
|
37
57
|
justify-content: center;
|
|
38
|
-
border-radius: .2em;
|
|
58
|
+
border-radius: 0.2em;
|
|
39
59
|
color: white;
|
|
40
60
|
background-color: var(--color);
|
|
41
61
|
font-weight: bold;
|
|
42
|
-
padding-inline: .4em;
|
|
62
|
+
padding-inline: 0.4em;
|
|
43
63
|
line-height: 1.4;
|
|
44
64
|
|
|
45
65
|
/* See https://lea.verou.me/blog/2024/contrast-color/ */
|
|
@@ -23,7 +23,7 @@ const Self = class GamutBadge extends ColorElement {
|
|
|
23
23
|
return this.gamutInfo?.label ?? "";
|
|
24
24
|
}
|
|
25
25
|
|
|
26
|
-
propChangedCallback ({name, prop, detail: change}) {
|
|
26
|
+
propChangedCallback ({ name, prop, detail: change }) {
|
|
27
27
|
if (name === "gamuts") {
|
|
28
28
|
this.style.setProperty("--gamut-count", this.gamuts.length - 1);
|
|
29
29
|
}
|
|
@@ -31,8 +31,8 @@ const Self = class GamutBadge extends ColorElement {
|
|
|
31
31
|
if (name === "gamutInfo") {
|
|
32
32
|
if (this.gamutInfo) {
|
|
33
33
|
this.style.setProperty("--gamut-level", this.gamutInfo.level);
|
|
34
|
-
this.style.setProperty("--gamut-label", `"${
|
|
35
|
-
this.style.setProperty("--gamut-id", `"${
|
|
34
|
+
this.style.setProperty("--gamut-label", `"${this.gamutInfo.label}"`);
|
|
35
|
+
this.style.setProperty("--gamut-id", `"${this.gamutInfo.id}"`);
|
|
36
36
|
}
|
|
37
37
|
else {
|
|
38
38
|
this.style.removeProperty("--gamut-level");
|
|
@@ -61,7 +61,7 @@ const Self = class GamutBadge extends ColorElement {
|
|
|
61
61
|
}
|
|
62
62
|
else if (!Array.isArray(gamuts) && typeof gamuts === "object") {
|
|
63
63
|
// Object
|
|
64
|
-
return Object.entries(gamuts).map(([id, label]) => ({id, label}));
|
|
64
|
+
return Object.entries(gamuts).map(([id, label]) => ({ id, label }));
|
|
65
65
|
}
|
|
66
66
|
|
|
67
67
|
let ret = gamuts.map((gamut, level) => {
|
|
@@ -73,7 +73,7 @@ const Self = class GamutBadge extends ColorElement {
|
|
|
73
73
|
gamut = gamut.trim().split(/\s*:\s*/);
|
|
74
74
|
let id = gamut[0];
|
|
75
75
|
let label = gamut[1] ?? Self.Color.spaces[id]?.name ?? id;
|
|
76
|
-
return {id, label, level};
|
|
76
|
+
return { id, label, level };
|
|
77
77
|
});
|
|
78
78
|
|
|
79
79
|
if (!ret.find(gamut => gamut.id === "none")) {
|
|
@@ -89,7 +89,7 @@ const Self = class GamutBadge extends ColorElement {
|
|
|
89
89
|
return ret;
|
|
90
90
|
},
|
|
91
91
|
stringify (gamuts) {
|
|
92
|
-
return gamuts.map(({id, label}) => `${
|
|
92
|
+
return gamuts.map(({ id, label }) => `${id}: ${label}`).join(", ");
|
|
93
93
|
},
|
|
94
94
|
},
|
|
95
95
|
gamutInfo: {
|
|
@@ -98,7 +98,9 @@ const Self = class GamutBadge extends ColorElement {
|
|
|
98
98
|
return null;
|
|
99
99
|
}
|
|
100
100
|
|
|
101
|
-
return this.gamuts?.find(
|
|
101
|
+
return this.gamuts?.find(
|
|
102
|
+
gamut => gamut.id === "none" || this.color?.inGamut(gamut.id),
|
|
103
|
+
);
|
|
102
104
|
},
|
|
103
105
|
},
|
|
104
106
|
gamut: {
|
|
@@ -1,9 +1,9 @@
|
|
|
1
1
|
:host {
|
|
2
2
|
--border-width: 1px;
|
|
3
|
-
--border-color: rgb(0 0 0 / .2);
|
|
4
|
-
--border-radius: .2em;
|
|
3
|
+
--border-color: rgb(0 0 0 / 0.2);
|
|
4
|
+
--border-radius: 0.2em;
|
|
5
5
|
|
|
6
|
-
padding: .3em .5em;
|
|
6
|
+
padding: 0.3em 0.5em;
|
|
7
7
|
|
|
8
8
|
border-radius: var(--border-radius);
|
|
9
9
|
border: var(--border-width) solid var(--border-color);
|
|
@@ -29,11 +29,14 @@ const Self = class SpacePicker extends ColorElement {
|
|
|
29
29
|
}
|
|
30
30
|
}
|
|
31
31
|
|
|
32
|
-
propChangedCallback ({name, prop, detail: change}) {
|
|
32
|
+
propChangedCallback ({ name, prop, detail: change }) {
|
|
33
33
|
if (name === "spaces") {
|
|
34
34
|
if (!this.groups) {
|
|
35
35
|
this._el.picker.innerHTML = Object.entries(this.spaces)
|
|
36
|
-
.map(
|
|
36
|
+
.map(
|
|
37
|
+
([id, space]) =>
|
|
38
|
+
`<option value="${id}">${this.getSpaceLabel(space)}</option>`,
|
|
39
|
+
)
|
|
37
40
|
.join("\n");
|
|
38
41
|
}
|
|
39
42
|
else {
|
|
@@ -42,7 +45,9 @@ const Self = class SpacePicker extends ColorElement {
|
|
|
42
45
|
// Remove empty groups
|
|
43
46
|
groups = Object.entries(groups).filter(([type, spaces]) => {
|
|
44
47
|
if (Object.keys(spaces).length === 0) {
|
|
45
|
-
console.warn(
|
|
48
|
+
console.warn(
|
|
49
|
+
`Removed empty group of color spaces with the label "${type}."`,
|
|
50
|
+
);
|
|
46
51
|
return false;
|
|
47
52
|
}
|
|
48
53
|
|
|
@@ -50,17 +55,26 @@ const Self = class SpacePicker extends ColorElement {
|
|
|
50
55
|
});
|
|
51
56
|
|
|
52
57
|
if (!groups.length) {
|
|
53
|
-
console.warn(
|
|
58
|
+
console.warn(
|
|
59
|
+
"All provided groups of color spaces are empty. Falling back to default grouping.",
|
|
60
|
+
);
|
|
54
61
|
groups = [["All spaces", this.spaces]];
|
|
55
62
|
}
|
|
56
63
|
|
|
57
|
-
this._el.picker.innerHTML = groups
|
|
64
|
+
this._el.picker.innerHTML = groups
|
|
65
|
+
.map(
|
|
66
|
+
([type, spaces]) => `
|
|
58
67
|
<optgroup label="${type}">
|
|
59
68
|
${Object.entries(spaces)
|
|
60
|
-
.map(
|
|
69
|
+
.map(
|
|
70
|
+
([id, space]) =>
|
|
71
|
+
`<option value="${id}">${this.getSpaceLabel(space)}</option>`,
|
|
72
|
+
)
|
|
61
73
|
.join("\n")}
|
|
62
74
|
</optgroup>
|
|
63
|
-
|
|
75
|
+
`,
|
|
76
|
+
)
|
|
77
|
+
.join("\n");
|
|
64
78
|
}
|
|
65
79
|
|
|
66
80
|
this._el.picker.value = this.value;
|
|
@@ -76,7 +90,9 @@ const Self = class SpacePicker extends ColorElement {
|
|
|
76
90
|
let currentSpace = this._el.picker.value;
|
|
77
91
|
let fallback = spaces.includes(currentSpace) ? currentSpace : firstSpace;
|
|
78
92
|
|
|
79
|
-
console.warn(
|
|
93
|
+
console.warn(
|
|
94
|
+
`No color space found with id = "${value}". Choose one of the following: ${spaces.join(", ")}. Falling back to "${fallback}".`,
|
|
95
|
+
);
|
|
80
96
|
this.value = value = fallback;
|
|
81
97
|
}
|
|
82
98
|
|
|
@@ -140,7 +156,9 @@ const Self = class SpacePicker extends ColorElement {
|
|
|
140
156
|
return value;
|
|
141
157
|
},
|
|
142
158
|
stringify (value) {
|
|
143
|
-
return Object.entries(value)
|
|
159
|
+
return Object.entries(value)
|
|
160
|
+
.map(([id, space]) => id)
|
|
161
|
+
.join(", ");
|
|
144
162
|
},
|
|
145
163
|
},
|
|
146
164
|
|
|
@@ -201,7 +219,7 @@ const Self = class SpacePicker extends ColorElement {
|
|
|
201
219
|
},
|
|
202
220
|
};
|
|
203
221
|
|
|
204
|
-
static
|
|
222
|
+
static formBehavior = {
|
|
205
223
|
like: el => el._el.picker,
|
|
206
224
|
role: "combobox",
|
|
207
225
|
changeEvent: "change",
|
package/src/src.json
CHANGED