-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathcheck-tri.js
88 lines (81 loc) · 3.51 KB
/
check-tri.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
export {CheckTri};
import {VALUE, BaseElement} from "./base-element.js";
import {CheckBase} from "./check-base.js";
const
VB_WIDTH = 2,
DEFAULT = "default", // custom attributes
SHOW_DEF = "show-default";
// =============================================================================
// Three-state checkbox: true, false, indeterminate (null)
class CheckTri extends CheckBase {
#def; #svg; #vbWidth; #viewBox;
static observedAttributes = [VALUE, DEFAULT, SHOW_DEF,
...CheckBase.observedAttributes];
constructor() {
const states = [
{value:null, id:"null" },
{value:false, id:"false"},
{value:true, id:"true" }
];
super(import.meta, CheckTri, states);
this.is();
}
// _init()
_init() {
super._init();
this.#svg = this.shadowRoot.getElementById("shapes");
this.#def = this.#svg.getElementById("default-mark");
this.#viewBox = this.#svg.getAttribute("viewBox")
.split(" ")
.map(v => Number(v));
if (!this.#vbWidth)
this.#vbWidth = this.#viewBox[VB_WIDTH]; // baseline width
this.default = this.default; // attributeChangedCallback() did
this.showDefault = this.showDefault; // nothing, gotta do it here.
}
// attributeChangedCallback() handles changes to the observed attributes
attributeChangedCallback(name, _, val) {
const b = (val !== null);
switch (name) {
case DEFAULT:
this._setHref(this.map.get(b).id, this.#def);
break;
case SHOW_DEF:
if (!this.#def) return;
//------------------------------------
const w = this.#vbWidth * (b ? 2 : 1);
this.#viewBox[VB_WIDTH] = w;
this.#svg.setAttribute("width", w);
this.#svg.setAttribute("viewBox", this.#viewBox.join(" "));
this.#def .parentNode.setAttribute("visibility", b ? "" : "hidden");
this._use?.parentNode.setAttribute("transform",
b ? `translate(${this.#vbWidth})`
: "");
break;
default:
super.attributeChangedCallback(name, _, val);
}
}
// this.default is the default value for when value == null (indeterminate)
// this.showDefault determines whether to show the default value as a 2nd box
get default() { return this.hasAttribute(DEFAULT); }
get showDefault() { return this.hasAttribute(SHOW_DEF); }
set default(val) { this.toggleAttribute(DEFAULT, Boolean(val)); }
set showDefault(val) { this.toggleAttribute(SHOW_DEF, Boolean(val)); }
// this.checked is read-only, null = indeterminate = inherit default
get checked() { return this.value ?? this.default; }
// _change() converts click and spacebar-up to a self-inflicted change event
// The 3-way rotation order depends on the boolean default attribute.
// Starting from null, rotate to the opposite of default:
// null -> !def -> def -> null -> ...
_change(evt) {
if (this._handleEvent(evt)) {
const def = this.default;
this.value = (this.value === null) ? !def
: (this.value !== def) ? def
: null;
this.dispatchEvent(new Event("change"));
}
}
}
BaseElement.define(CheckTri);