-
Notifications
You must be signed in to change notification settings - Fork 1
/
gamut-badge.js
124 lines (108 loc) · 2.77 KB
/
gamut-badge.js
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
import NudeElement from "../../node_modules/nude-element/src/Element.js";
// See https://bugs.webkit.org/show_bug.cgi?id=242740
import ColorJS from "../common/color.js";
const Color = await ColorJS;
const Self = class GamutBadge extends NudeElement {
static tagName = "gamut-badge";
static Color = Color;
#label;
constructor () {
super();
this.attachShadow({mode: "open"});
let styleURL = new URL(`./${ Self.tagName }.css`, import.meta.url);
this.shadowRoot.innerHTML = `
<style>@import url("${ styleURL }")</style>
<slot>
<span id="label" part="label"></span>
</slot>
`;
if (!this.#label) {
this.#label = this.shadowRoot.querySelector("#label");
}
}
get gamutLabel () {
return this.gamutInfo?.label ?? "";
}
propChangedCallback ({name, prop, detail: change}) {
if (name === "gamuts") {
this.style.setProperty("--gamut-count", this.gamuts.length - 1);
}
if (name === "gamutInfo") {
if (this.gamutInfo) {
this.style.setProperty("--gamut-level", this.gamutInfo.level);
this.style.setProperty("--gamut-label", `"${ this.gamutInfo.label }"`);
this.style.setProperty("--gamut-id", `"${ this.gamutInfo.id }"`);
}
else {
this.style.removeProperty("--gamut-level");
this.style.removeProperty("--gamut-label");
this.style.removeProperty("--gamut-id");
}
}
}
static props = {
color: {
type: Color,
},
gamuts: {
type: Array,
default: "srgb, p3, rec2020, prophoto",
parse (gamuts) {
if (!gamuts) {
return [];
}
if (typeof gamuts === "string") {
gamuts = gamuts.trim().split(/\s*,\s*/);
}
else if (!Array.isArray(gamuts) && typeof gamuts === "object") {
// Object
return Object.entries(gamuts).map(([id, label]) => ({id, label}));
}
let ret = gamuts.map((gamut, level) => {
if (gamut?.id && "label" in gamut) {
// Already in the correct format
return gamut;
}
gamut = gamut.trim().split(/\s*:\s*/);
let id = gamut[0];
let label = gamut[1] ?? Color.spaces[id]?.name ?? id;
return {id, label, level};
});
if (!ret.find(gamut => gamut.id === "none")) {
ret.push({
id: "none",
get label () {
return ret[this.level - 1].label + "+";
},
level: ret.length,
});
}
return ret;
},
stringify (gamuts) {
return gamuts.map(({id, label}) => `${ id }: ${ label }`).join(", ");
},
},
gamutInfo: {
get () {
if (!this.color) {
return null;
}
return this.gamuts?.find(gamut => gamut.id === "none" || this.color?.inGamut(gamut.id));
},
},
gamut: {
type: String,
get () {
return this.gamutInfo?.id;
},
},
};
static events = {
gamutchange: {
propchange: "gamut",
},
};
};
customElements.define(Self.tagName, Self);
export default Self;