@rogieking/figui3 1.4.0 → 1.4.2
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/example.html +11 -29
- package/fig.css +1 -2
- package/fig.js +219 -190
- package/package.json +1 -1
- package/test.html +39 -0
package/example.html
CHANGED
|
@@ -20,40 +20,17 @@
|
|
|
20
20
|
|
|
21
21
|
<body>
|
|
22
22
|
<fig-header>
|
|
23
|
-
|
|
23
|
+
|
|
24
|
+
<h2><label>Effects/</label>UI3 Components</h2>
|
|
24
25
|
</fig-header>
|
|
25
26
|
<fig-content>
|
|
26
|
-
<fig-field>
|
|
27
|
-
<fig-tooltip text="Options">
|
|
28
|
-
<fig-dropdown>
|
|
29
|
-
<option>One</option>
|
|
30
|
-
<option>Two</option>
|
|
31
|
-
</fig-dropdown>
|
|
32
|
-
</fig-tooltip>
|
|
33
27
|
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
<fig-tooltip text="Delta slider">
|
|
37
|
-
<fig-slider type="delta"
|
|
38
|
-
value=".25"
|
|
39
|
-
default="2"
|
|
40
|
-
step="0.1"
|
|
41
|
-
max="5"
|
|
42
|
-
min="-5">
|
|
43
|
-
</fig-slider>
|
|
44
|
-
</fig-tooltip>
|
|
45
|
-
</fig-field>
|
|
46
|
-
|
|
47
|
-
<br /><br />
|
|
48
|
-
<fig-input-angle value="45"
|
|
49
|
-
text="true"></fig-input-angle>
|
|
50
|
-
<br /><br />
|
|
51
|
-
<fig-slider min="0.01"
|
|
52
|
-
max="0.25"
|
|
28
|
+
<fig-slider min="-1"
|
|
29
|
+
max="1"
|
|
53
30
|
name="u_thickness"
|
|
54
31
|
variant="minimal"
|
|
55
32
|
step="0.01"
|
|
56
|
-
value="
|
|
33
|
+
value="0"
|
|
57
34
|
text="true"
|
|
58
35
|
type="range"
|
|
59
36
|
units="%"
|
|
@@ -784,7 +761,12 @@
|
|
|
784
761
|
</fig-button>
|
|
785
762
|
</fig-field>
|
|
786
763
|
</fig-content>
|
|
787
|
-
|
|
764
|
+
<script>
|
|
765
|
+
let elements = Array.from(document.querySelectorAll('*'));
|
|
766
|
+
elements.filter(n => n.tagName.toLowerCase().indexOf("fig-slider") > -1).forEach(n => n.addEventListener('input', (e) => {
|
|
767
|
+
console.log('input:', n.tagName, e.target)
|
|
768
|
+
}))
|
|
769
|
+
</script>
|
|
788
770
|
</body>
|
|
789
771
|
|
|
790
772
|
</html>
|
package/fig.css
CHANGED
|
@@ -2054,14 +2054,13 @@ fig-input-color {
|
|
|
2054
2054
|
fig-header {
|
|
2055
2055
|
height: var(--spacer-6);
|
|
2056
2056
|
margin: 0;
|
|
2057
|
-
padding: var(--spacer-
|
|
2057
|
+
padding: var(--spacer-1) var(--spacer-3);
|
|
2058
2058
|
display: flex;
|
|
2059
2059
|
align-items: center;
|
|
2060
2060
|
box-shadow: inset 0 -1px 0 0 var(--figma-color-border);
|
|
2061
2061
|
gap: 0.25rem;
|
|
2062
2062
|
|
|
2063
2063
|
& h3 {
|
|
2064
|
-
padding-left: var(--spacer-2);
|
|
2065
2064
|
font-weight: var(--body-medium-strong-fontWeight);
|
|
2066
2065
|
flex-grow: 1;
|
|
2067
2066
|
}
|
package/fig.js
CHANGED
|
@@ -5,23 +5,22 @@ function figSupportsPopover() {
|
|
|
5
5
|
return HTMLElement.prototype.hasOwnProperty("popover");
|
|
6
6
|
}
|
|
7
7
|
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
this.shadowRoot.innerHTML = `
|
|
8
|
+
/**
|
|
9
|
+
* A custom button element that supports different types and states.
|
|
10
|
+
* @attr {string} type - The button type: "button" (default), "toggle", or "submit"
|
|
11
|
+
* @attr {boolean} selected - Whether the button is in a selected state
|
|
12
|
+
* @attr {boolean} disabled - Whether the button is disabled
|
|
13
|
+
*/
|
|
14
|
+
class FigButton extends HTMLElement {
|
|
15
|
+
type;
|
|
16
|
+
#selected;
|
|
17
|
+
constructor() {
|
|
18
|
+
super();
|
|
19
|
+
this.attachShadow({ mode: "open" });
|
|
20
|
+
}
|
|
21
|
+
connectedCallback() {
|
|
22
|
+
this.type = this.getAttribute("type") || "button";
|
|
23
|
+
this.shadowRoot.innerHTML = `
|
|
25
24
|
<style>
|
|
26
25
|
button, button:hover, button:active {
|
|
27
26
|
padding: 0 var(--spacer-2);
|
|
@@ -46,168 +45,159 @@ if (window.customElements && !window.customElements.get("fig-button")) {
|
|
|
46
45
|
</button>
|
|
47
46
|
`;
|
|
48
47
|
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
48
|
+
this.#selected =
|
|
49
|
+
this.hasAttribute("selected") &&
|
|
50
|
+
this.getAttribute("selected") !== "false";
|
|
52
51
|
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
52
|
+
requestAnimationFrame(() => {
|
|
53
|
+
this.button = this.shadowRoot.querySelector("button");
|
|
54
|
+
this.button.addEventListener("click", this.#handleClick.bind(this));
|
|
55
|
+
});
|
|
56
|
+
}
|
|
58
57
|
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
58
|
+
get type() {
|
|
59
|
+
return this.type;
|
|
60
|
+
}
|
|
61
|
+
set type(value) {
|
|
62
|
+
this.setAttribute("type", value);
|
|
63
|
+
}
|
|
64
|
+
get selected() {
|
|
65
|
+
return this.#selected;
|
|
66
|
+
}
|
|
67
|
+
set selected(value) {
|
|
68
|
+
this.setAttribute("selected", value);
|
|
69
|
+
}
|
|
71
70
|
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
}
|
|
76
|
-
if (this.type === "submit") {
|
|
77
|
-
this.closest("form").dispatchEvent(new Event("submit"));
|
|
78
|
-
}
|
|
71
|
+
#handleClick() {
|
|
72
|
+
if (this.type === "toggle") {
|
|
73
|
+
this.toggleAttribute("selected", !this.hasAttribute("selected"));
|
|
79
74
|
}
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
}
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
|
|
93
|
-
|
|
94
|
-
|
|
95
|
-
|
|
96
|
-
|
|
97
|
-
|
|
98
|
-
|
|
99
|
-
|
|
100
|
-
|
|
75
|
+
if (this.type === "submit") {
|
|
76
|
+
this.closest("form").dispatchEvent(new Event("submit"));
|
|
77
|
+
}
|
|
78
|
+
}
|
|
79
|
+
static get observedAttributes() {
|
|
80
|
+
return ["disabled", "selected"];
|
|
81
|
+
}
|
|
82
|
+
attributeChangedCallback(name, oldValue, newValue) {
|
|
83
|
+
if (this.button) {
|
|
84
|
+
this.button[name] = newValue;
|
|
85
|
+
switch (name) {
|
|
86
|
+
case "disabled":
|
|
87
|
+
this.disabled = this.button.disabled =
|
|
88
|
+
newValue === "true" ||
|
|
89
|
+
(newValue === undefined && newValue !== null);
|
|
90
|
+
break;
|
|
91
|
+
case "type":
|
|
92
|
+
this.type = newValue;
|
|
93
|
+
this.button.type = this.type;
|
|
94
|
+
this.button.setAttribute("type", this.type);
|
|
95
|
+
break;
|
|
96
|
+
case "selected":
|
|
97
|
+
this.#selected = newValue === "true";
|
|
98
|
+
break;
|
|
101
99
|
}
|
|
102
100
|
}
|
|
103
101
|
}
|
|
104
|
-
window.customElements.define("fig-button", FigButton);
|
|
105
102
|
}
|
|
103
|
+
window.customElements.define("fig-button", FigButton);
|
|
106
104
|
|
|
107
|
-
|
|
108
|
-
|
|
109
|
-
|
|
110
|
-
|
|
111
|
-
|
|
112
|
-
|
|
113
|
-
|
|
114
|
-
|
|
115
|
-
|
|
116
|
-
|
|
117
|
-
|
|
118
|
-
|
|
119
|
-
}
|
|
120
|
-
|
|
121
|
-
#addEventListeners() {
|
|
122
|
-
this.select.addEventListener("input", this.#handleSelectInput.bind(this));
|
|
123
|
-
this.select.addEventListener(
|
|
124
|
-
"change",
|
|
125
|
-
this.#handleSelectChange.bind(this)
|
|
126
|
-
);
|
|
127
|
-
}
|
|
105
|
+
/**
|
|
106
|
+
* A custom dropdown/select element.
|
|
107
|
+
* @attr {string} type - The dropdown type: "select" (default) or "dropdown"
|
|
108
|
+
* @attr {string} value - The currently selected value
|
|
109
|
+
*/
|
|
110
|
+
class FigDropdown extends HTMLElement {
|
|
111
|
+
constructor() {
|
|
112
|
+
super();
|
|
113
|
+
this.select = document.createElement("select");
|
|
114
|
+
this.optionsSlot = document.createElement("slot");
|
|
115
|
+
this.attachShadow({ mode: "open" });
|
|
116
|
+
}
|
|
128
117
|
|
|
129
|
-
|
|
130
|
-
|
|
118
|
+
#addEventListeners() {
|
|
119
|
+
this.select.addEventListener("input", this.#handleSelectInput.bind(this));
|
|
120
|
+
this.select.addEventListener("change", this.#handleSelectChange.bind(this));
|
|
121
|
+
}
|
|
131
122
|
|
|
132
|
-
|
|
133
|
-
|
|
123
|
+
connectedCallback() {
|
|
124
|
+
this.type = this.getAttribute("type") || "select";
|
|
134
125
|
|
|
135
|
-
|
|
136
|
-
|
|
137
|
-
this.slotChange.bind(this)
|
|
138
|
-
);
|
|
126
|
+
this.appendChild(this.select);
|
|
127
|
+
this.shadowRoot.appendChild(this.optionsSlot);
|
|
139
128
|
|
|
140
|
-
|
|
141
|
-
}
|
|
129
|
+
this.optionsSlot.addEventListener("slotchange", this.slotChange.bind(this));
|
|
142
130
|
|
|
143
|
-
|
|
144
|
-
|
|
145
|
-
this.select.firstChild.remove();
|
|
146
|
-
}
|
|
131
|
+
this.#addEventListeners();
|
|
132
|
+
}
|
|
147
133
|
|
|
148
|
-
|
|
149
|
-
|
|
150
|
-
|
|
151
|
-
hiddenOption.setAttribute("selected", "true");
|
|
152
|
-
this.select.appendChild(hiddenOption);
|
|
153
|
-
}
|
|
154
|
-
this.optionsSlot.assignedNodes().forEach((option) => {
|
|
155
|
-
if (option.nodeName === "OPTION" || option.nodeName === "OPTGROUP") {
|
|
156
|
-
this.select.appendChild(option.cloneNode(true));
|
|
157
|
-
}
|
|
158
|
-
});
|
|
159
|
-
this.#syncSelectedValue(this.value);
|
|
160
|
-
if (this.type === "dropdown") {
|
|
161
|
-
this.select.selectedIndex = -1;
|
|
162
|
-
}
|
|
134
|
+
slotChange() {
|
|
135
|
+
while (this.select.firstChild) {
|
|
136
|
+
this.select.firstChild.remove();
|
|
163
137
|
}
|
|
164
138
|
|
|
165
|
-
|
|
166
|
-
|
|
167
|
-
|
|
139
|
+
if (this.type === "dropdown") {
|
|
140
|
+
const hiddenOption = document.createElement("option");
|
|
141
|
+
hiddenOption.setAttribute("hidden", "true");
|
|
142
|
+
hiddenOption.setAttribute("selected", "true");
|
|
143
|
+
this.select.appendChild(hiddenOption);
|
|
168
144
|
}
|
|
169
|
-
|
|
170
|
-
if (
|
|
171
|
-
this.select.
|
|
145
|
+
this.optionsSlot.assignedNodes().forEach((option) => {
|
|
146
|
+
if (option.nodeName === "OPTION" || option.nodeName === "OPTGROUP") {
|
|
147
|
+
this.select.appendChild(option.cloneNode(true));
|
|
172
148
|
}
|
|
149
|
+
});
|
|
150
|
+
this.#syncSelectedValue(this.value);
|
|
151
|
+
if (this.type === "dropdown") {
|
|
152
|
+
this.select.selectedIndex = -1;
|
|
173
153
|
}
|
|
174
|
-
|
|
175
|
-
|
|
176
|
-
|
|
177
|
-
|
|
178
|
-
|
|
179
|
-
|
|
180
|
-
|
|
181
|
-
|
|
182
|
-
|
|
183
|
-
set value(value) {
|
|
184
|
-
this.setAttribute("value", value);
|
|
154
|
+
}
|
|
155
|
+
|
|
156
|
+
#handleSelectInput(e) {
|
|
157
|
+
this.value = e.target.value;
|
|
158
|
+
this.setAttribute("value", this.value);
|
|
159
|
+
}
|
|
160
|
+
#handleSelectChange() {
|
|
161
|
+
if (this.type === "dropdown") {
|
|
162
|
+
this.select.selectedIndex = -1;
|
|
185
163
|
}
|
|
186
|
-
|
|
187
|
-
|
|
164
|
+
}
|
|
165
|
+
focus() {
|
|
166
|
+
this.select.focus();
|
|
167
|
+
}
|
|
168
|
+
blur() {
|
|
169
|
+
this.select.blur();
|
|
170
|
+
}
|
|
171
|
+
get value() {
|
|
172
|
+
return this.select?.value;
|
|
173
|
+
}
|
|
174
|
+
set value(value) {
|
|
175
|
+
this.setAttribute("value", value);
|
|
176
|
+
}
|
|
177
|
+
static get observedAttributes() {
|
|
178
|
+
return ["value", "type"];
|
|
179
|
+
}
|
|
180
|
+
#syncSelectedValue(value) {
|
|
181
|
+
if (this.select) {
|
|
182
|
+
this.select.querySelectorAll("option").forEach((o, i) => {
|
|
183
|
+
if (o.value === this.getAttribute("value")) {
|
|
184
|
+
this.select.selectedIndex = i;
|
|
185
|
+
}
|
|
186
|
+
});
|
|
188
187
|
}
|
|
189
|
-
|
|
190
|
-
|
|
191
|
-
|
|
192
|
-
|
|
193
|
-
this.select.selectedIndex = i;
|
|
194
|
-
}
|
|
195
|
-
});
|
|
196
|
-
}
|
|
188
|
+
}
|
|
189
|
+
attributeChangedCallback(name, oldValue, newValue) {
|
|
190
|
+
if (name === "value") {
|
|
191
|
+
this.#syncSelectedValue(newValue);
|
|
197
192
|
}
|
|
198
|
-
|
|
199
|
-
|
|
200
|
-
this.#syncSelectedValue(newValue);
|
|
201
|
-
}
|
|
202
|
-
if (name === "type") {
|
|
203
|
-
this.type = newValue;
|
|
204
|
-
}
|
|
193
|
+
if (name === "type") {
|
|
194
|
+
this.type = newValue;
|
|
205
195
|
}
|
|
206
196
|
}
|
|
207
|
-
|
|
208
|
-
customElements.define("fig-dropdown", FigDropdown);
|
|
209
197
|
}
|
|
210
198
|
|
|
199
|
+
customElements.define("fig-dropdown", FigDropdown);
|
|
200
|
+
|
|
211
201
|
/* Tooltip */
|
|
212
202
|
/**
|
|
213
203
|
* A custom tooltip element that displays on hover or click.
|
|
@@ -752,6 +742,7 @@ window.customElements.define("fig-segmented-control", FigSegmentedControl);
|
|
|
752
742
|
* @attr {string} color - The color for the slider track (for opacity type)
|
|
753
743
|
*/
|
|
754
744
|
class FigSlider extends HTMLElement {
|
|
745
|
+
// Private fields declarations
|
|
755
746
|
#typeDefaults = {
|
|
756
747
|
range: { min: 0, max: 100, step: 1 },
|
|
757
748
|
hue: { min: 0, max: 255, step: 1 },
|
|
@@ -759,9 +750,25 @@ class FigSlider extends HTMLElement {
|
|
|
759
750
|
stepper: { min: 0, max: 100, step: 25 },
|
|
760
751
|
opacity: { min: 0, max: 100, step: 0.1, color: "#FF0000" },
|
|
761
752
|
};
|
|
753
|
+
|
|
754
|
+
#boundHandleInput;
|
|
755
|
+
#boundHandleTextInput;
|
|
756
|
+
|
|
762
757
|
constructor() {
|
|
763
758
|
super();
|
|
759
|
+
|
|
760
|
+
// Bind the event handlers
|
|
761
|
+
this.#boundHandleInput = (e) => {
|
|
762
|
+
e.stopPropagation();
|
|
763
|
+
this.#handleInput();
|
|
764
|
+
};
|
|
765
|
+
|
|
766
|
+
this.#boundHandleTextInput = (e) => {
|
|
767
|
+
e.stopPropagation();
|
|
768
|
+
this.#handleTextInput();
|
|
769
|
+
};
|
|
764
770
|
}
|
|
771
|
+
|
|
765
772
|
#regenerateInnerHTML() {
|
|
766
773
|
this.value = Number(this.getAttribute("value") || 0);
|
|
767
774
|
this.type = this.getAttribute("type") || "range";
|
|
@@ -818,8 +825,8 @@ class FigSlider extends HTMLElement {
|
|
|
818
825
|
requestAnimationFrame(() => {
|
|
819
826
|
this.input = this.querySelector("[type=range]");
|
|
820
827
|
this.inputContainer = this.querySelector(".fig-slider-input-container");
|
|
821
|
-
this.input.removeEventListener("input", this
|
|
822
|
-
this.input.addEventListener("input", this
|
|
828
|
+
this.input.removeEventListener("input", this.#boundHandleInput);
|
|
829
|
+
this.input.addEventListener("input", this.#boundHandleInput);
|
|
823
830
|
|
|
824
831
|
if (this.default) {
|
|
825
832
|
this.style.setProperty(
|
|
@@ -866,14 +873,14 @@ class FigSlider extends HTMLElement {
|
|
|
866
873
|
}
|
|
867
874
|
}
|
|
868
875
|
if (this.figInputText) {
|
|
869
|
-
this.figInputText.removeEventListener(
|
|
870
|
-
this.figInputText.addEventListener(
|
|
876
|
+
this.figInputText.removeEventListener(
|
|
871
877
|
"input",
|
|
872
|
-
this
|
|
878
|
+
this.#boundHandleTextInput
|
|
873
879
|
);
|
|
880
|
+
this.figInputText.addEventListener("input", this.#boundHandleTextInput);
|
|
874
881
|
}
|
|
875
882
|
|
|
876
|
-
this
|
|
883
|
+
this.#syncValue();
|
|
877
884
|
});
|
|
878
885
|
}
|
|
879
886
|
|
|
@@ -881,6 +888,40 @@ class FigSlider extends HTMLElement {
|
|
|
881
888
|
this.initialInnerHTML = this.innerHTML;
|
|
882
889
|
this.#regenerateInnerHTML();
|
|
883
890
|
}
|
|
891
|
+
|
|
892
|
+
#handleTextInput() {
|
|
893
|
+
if (this.figInputText) {
|
|
894
|
+
this.value = this.input.value = this.figInputText.value;
|
|
895
|
+
this.#syncProperties();
|
|
896
|
+
this.dispatchEvent(new CustomEvent("input", { bubbles: true }));
|
|
897
|
+
}
|
|
898
|
+
}
|
|
899
|
+
#calculateNormal(value) {
|
|
900
|
+
let min = Number(this.min);
|
|
901
|
+
let max = Number(this.max);
|
|
902
|
+
return (Number(value) - min) / (max - min);
|
|
903
|
+
}
|
|
904
|
+
#syncProperties() {
|
|
905
|
+
let complete = this.#calculateNormal(this.value);
|
|
906
|
+
this.style.setProperty("--slider-complete", complete);
|
|
907
|
+
let defaultValue = this.#calculateNormal(this.default);
|
|
908
|
+
this.style.setProperty("--default", defaultValue);
|
|
909
|
+
this.style.setProperty("--unchanged", complete === defaultValue ? 1 : 0);
|
|
910
|
+
}
|
|
911
|
+
#syncValue() {
|
|
912
|
+
let val = this.input.value;
|
|
913
|
+
this.value = val;
|
|
914
|
+
this.#syncProperties();
|
|
915
|
+
if (this.figInputText) {
|
|
916
|
+
this.figInputText.setAttribute("value", val);
|
|
917
|
+
}
|
|
918
|
+
}
|
|
919
|
+
|
|
920
|
+
#handleInput() {
|
|
921
|
+
this.#syncValue();
|
|
922
|
+
this.dispatchEvent(new CustomEvent("input", { bubbles: true }));
|
|
923
|
+
}
|
|
924
|
+
|
|
884
925
|
static get observedAttributes() {
|
|
885
926
|
return [
|
|
886
927
|
"value",
|
|
@@ -938,38 +979,11 @@ class FigSlider extends HTMLElement {
|
|
|
938
979
|
break;
|
|
939
980
|
default:
|
|
940
981
|
this[name] = this.input[name] = newValue;
|
|
941
|
-
this
|
|
982
|
+
this.#syncValue();
|
|
942
983
|
break;
|
|
943
984
|
}
|
|
944
985
|
}
|
|
945
986
|
}
|
|
946
|
-
handleTextInput() {
|
|
947
|
-
if (this.figInputText) {
|
|
948
|
-
this.value = this.input.value = this.figInputText.value;
|
|
949
|
-
this.#syncProperties();
|
|
950
|
-
}
|
|
951
|
-
}
|
|
952
|
-
#calculateNormal(value) {
|
|
953
|
-
let min = Number(this.min);
|
|
954
|
-
let max = Number(this.max);
|
|
955
|
-
return (Number(value) - min) / (max - min);
|
|
956
|
-
}
|
|
957
|
-
#syncProperties() {
|
|
958
|
-
let complete = this.#calculateNormal(this.value);
|
|
959
|
-
this.style.setProperty("--slider-complete", complete);
|
|
960
|
-
let defaultValue = this.#calculateNormal(this.default);
|
|
961
|
-
this.style.setProperty("--default", defaultValue);
|
|
962
|
-
this.style.setProperty("--unchanged", complete === defaultValue ? 1 : 0);
|
|
963
|
-
}
|
|
964
|
-
|
|
965
|
-
handleInput() {
|
|
966
|
-
let val = this.input.value;
|
|
967
|
-
this.value = val;
|
|
968
|
-
this.#syncProperties();
|
|
969
|
-
if (this.figInputText) {
|
|
970
|
-
this.figInputText.setAttribute("value", val);
|
|
971
|
-
}
|
|
972
|
-
}
|
|
973
987
|
}
|
|
974
988
|
window.customElements.define("fig-slider", FigSlider);
|
|
975
989
|
|
|
@@ -989,6 +1003,7 @@ class FigInputText extends HTMLElement {
|
|
|
989
1003
|
#boundMouseMove;
|
|
990
1004
|
#boundMouseUp;
|
|
991
1005
|
#boundMouseDown;
|
|
1006
|
+
#boundInputChange;
|
|
992
1007
|
|
|
993
1008
|
constructor() {
|
|
994
1009
|
super();
|
|
@@ -996,6 +1011,10 @@ class FigInputText extends HTMLElement {
|
|
|
996
1011
|
this.#boundMouseMove = this.#handleMouseMove.bind(this);
|
|
997
1012
|
this.#boundMouseUp = this.#handleMouseUp.bind(this);
|
|
998
1013
|
this.#boundMouseDown = this.#handleMouseDown.bind(this);
|
|
1014
|
+
this.#boundInputChange = (e) => {
|
|
1015
|
+
e.stopPropagation();
|
|
1016
|
+
this.#handleInputChange(e);
|
|
1017
|
+
};
|
|
999
1018
|
}
|
|
1000
1019
|
|
|
1001
1020
|
connectedCallback() {
|
|
@@ -1063,7 +1082,8 @@ class FigInputText extends HTMLElement {
|
|
|
1063
1082
|
}
|
|
1064
1083
|
this.addEventListener("pointerdown", this.#boundMouseDown);
|
|
1065
1084
|
}
|
|
1066
|
-
this.input.
|
|
1085
|
+
this.input.removeEventListener("change", this.#boundInputChange);
|
|
1086
|
+
this.input.addEventListener("change", this.#boundInputChange);
|
|
1067
1087
|
});
|
|
1068
1088
|
}
|
|
1069
1089
|
focus() {
|
|
@@ -1075,14 +1095,14 @@ class FigInputText extends HTMLElement {
|
|
|
1075
1095
|
transformed = this.#formatNumber(transformed);
|
|
1076
1096
|
return transformed;
|
|
1077
1097
|
}
|
|
1078
|
-
#
|
|
1079
|
-
console.log("handleInput", e.target.value);
|
|
1098
|
+
#handleInputChange(e) {
|
|
1080
1099
|
e.stopPropagation();
|
|
1081
1100
|
let value = e.target.value;
|
|
1082
1101
|
let valueTransformed = value;
|
|
1083
1102
|
if (this.type === "number") {
|
|
1084
1103
|
value = value / (this.transform || 1);
|
|
1085
1104
|
value = this.#sanitizeInput(value, false);
|
|
1105
|
+
console.log("sanitizeInput", value);
|
|
1086
1106
|
valueTransformed = value * (this.transform || 1);
|
|
1087
1107
|
}
|
|
1088
1108
|
this.value = value;
|
|
@@ -1155,6 +1175,16 @@ class FigInputText extends HTMLElement {
|
|
|
1155
1175
|
return Number.isInteger(rounded) ? rounded : rounded.toFixed(precision);
|
|
1156
1176
|
}
|
|
1157
1177
|
|
|
1178
|
+
/*
|
|
1179
|
+
get value() {
|
|
1180
|
+
return this.value;
|
|
1181
|
+
}
|
|
1182
|
+
|
|
1183
|
+
set value(val) {
|
|
1184
|
+
this.value = val;
|
|
1185
|
+
this.setAttribute("value", val);
|
|
1186
|
+
}*/
|
|
1187
|
+
|
|
1158
1188
|
static get observedAttributes() {
|
|
1159
1189
|
return [
|
|
1160
1190
|
"value",
|
|
@@ -1194,7 +1224,6 @@ class FigInputText extends HTMLElement {
|
|
|
1194
1224
|
this.value = value;
|
|
1195
1225
|
this.input.value = value;
|
|
1196
1226
|
}
|
|
1197
|
-
this.dispatchEvent(new CustomEvent("input", { bubbles: true }));
|
|
1198
1227
|
break;
|
|
1199
1228
|
case "min":
|
|
1200
1229
|
case "max":
|
package/package.json
CHANGED
package/test.html
ADDED
|
@@ -0,0 +1,39 @@
|
|
|
1
|
+
<!DOCTYPE html>
|
|
2
|
+
<html lang="en">
|
|
3
|
+
|
|
4
|
+
<head>
|
|
5
|
+
<meta charset="UTF-8">
|
|
6
|
+
<meta name="viewport"
|
|
7
|
+
content="width=device-width, initial-scale=1.0">
|
|
8
|
+
<title>Figma UI3 Web Components</title>
|
|
9
|
+
<link rel="stylesheet"
|
|
10
|
+
type="text/css"
|
|
11
|
+
href="fig.css">
|
|
12
|
+
<script src="fig.js"></script>
|
|
13
|
+
<style>
|
|
14
|
+
body {
|
|
15
|
+
width: 480px;
|
|
16
|
+
margin: 0 auto;
|
|
17
|
+
}
|
|
18
|
+
</style>
|
|
19
|
+
</head>
|
|
20
|
+
|
|
21
|
+
<body>
|
|
22
|
+
<fig-content>
|
|
23
|
+
<fig-slider type="delta"
|
|
24
|
+
value=".25"
|
|
25
|
+
default="2"
|
|
26
|
+
step="0.1"
|
|
27
|
+
max="5"
|
|
28
|
+
min="-5">
|
|
29
|
+
</fig-slider>
|
|
30
|
+
</fig-content>
|
|
31
|
+
<script>
|
|
32
|
+
let elements = Array.from(document.querySelectorAll('*'));
|
|
33
|
+
elements.filter(n => n.tagName.toLowerCase().indexOf("fig-") > -1).forEach(n => n.addEventListener('input', (e) => {
|
|
34
|
+
console.log('input:', n.tagName, e.target)
|
|
35
|
+
}))
|
|
36
|
+
</script>
|
|
37
|
+
</body>
|
|
38
|
+
|
|
39
|
+
</html>
|