@rogieking/figui3 3.13.1 → 3.14.0
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/components.css +49 -23
- package/fig.js +340 -157
- package/package.json +1 -1
package/components.css
CHANGED
|
@@ -1204,10 +1204,8 @@ fig-chit {
|
|
|
1204
1204
|
box-shadow: inset 0 0 0 1px var(--figma-color-border-selected);
|
|
1205
1205
|
}
|
|
1206
1206
|
|
|
1207
|
+
&[size="medium"],
|
|
1207
1208
|
&[size="large"] {
|
|
1208
|
-
--size: 1.75rem;
|
|
1209
|
-
|
|
1210
|
-
/* Large size: swatch fills the whole area */
|
|
1211
1209
|
input[type="color"] {
|
|
1212
1210
|
padding: 0;
|
|
1213
1211
|
width: var(--size);
|
|
@@ -1233,7 +1231,6 @@ fig-chit {
|
|
|
1233
1231
|
inset 0 0 0 3px var(--figma-color-bg);
|
|
1234
1232
|
}
|
|
1235
1233
|
|
|
1236
|
-
/* Large gradient/image: also fill the area */
|
|
1237
1234
|
&[data-type="gradient"]::after,
|
|
1238
1235
|
&[data-type="image"]::after,
|
|
1239
1236
|
&[data-type="gradient"]::before,
|
|
@@ -1244,6 +1241,14 @@ fig-chit {
|
|
|
1244
1241
|
}
|
|
1245
1242
|
}
|
|
1246
1243
|
|
|
1244
|
+
&[size="medium"] {
|
|
1245
|
+
--size: 1.5rem;
|
|
1246
|
+
}
|
|
1247
|
+
|
|
1248
|
+
&[size="large"] {
|
|
1249
|
+
--size: 2rem;
|
|
1250
|
+
}
|
|
1251
|
+
|
|
1247
1252
|
&[disabled] {
|
|
1248
1253
|
pointer-events: none;
|
|
1249
1254
|
}
|
|
@@ -3174,14 +3179,12 @@ fig-input-gradient {
|
|
|
3174
3179
|
}
|
|
3175
3180
|
fig-chit {
|
|
3176
3181
|
flex: 1 1 auto;
|
|
3177
|
-
width: 100
|
|
3178
|
-
min-width: 0;
|
|
3182
|
+
width: 100% !important;
|
|
3183
|
+
min-width: 0 !important;
|
|
3179
3184
|
&::before,
|
|
3180
3185
|
&::after {
|
|
3181
|
-
width:
|
|
3182
|
-
height: auto;
|
|
3186
|
+
width: 100% !important;
|
|
3183
3187
|
place-self: stretch;
|
|
3184
|
-
border-radius: var(--radius-large) !important;
|
|
3185
3188
|
}
|
|
3186
3189
|
&[data-type="gradient"]::after {
|
|
3187
3190
|
width: calc(100% - 0.625rem);
|
|
@@ -3193,12 +3196,24 @@ fig-input-gradient {
|
|
|
3193
3196
|
|
|
3194
3197
|
.fig-input-gradient-track {
|
|
3195
3198
|
position: absolute;
|
|
3196
|
-
|
|
3199
|
+
display: flex;
|
|
3200
|
+
align-items: center;
|
|
3201
|
+
inset: 0;
|
|
3197
3202
|
pointer-events: auto;
|
|
3198
3203
|
|
|
3199
3204
|
fig-handle {
|
|
3200
3205
|
pointer-events: auto;
|
|
3201
3206
|
cursor: default;
|
|
3207
|
+
|
|
3208
|
+
&.dragging {
|
|
3209
|
+
fig-color-tip {
|
|
3210
|
+
display: none;
|
|
3211
|
+
}
|
|
3212
|
+
}
|
|
3213
|
+
|
|
3214
|
+
&:hover {
|
|
3215
|
+
z-index: 5;
|
|
3216
|
+
}
|
|
3202
3217
|
}
|
|
3203
3218
|
}
|
|
3204
3219
|
}
|
|
@@ -4244,12 +4259,6 @@ fig-preview {
|
|
|
4244
4259
|
}
|
|
4245
4260
|
|
|
4246
4261
|
.fig-fill-picker-color-area fig-handle {
|
|
4247
|
-
--width: 1rem;
|
|
4248
|
-
--height: 1rem;
|
|
4249
|
-
--border-radius: 50%;
|
|
4250
|
-
--box-shadow:
|
|
4251
|
-
inset 0 0 0 0.125rem var(--handle-color),
|
|
4252
|
-
0px 0 0 0.5px rgba(0, 0, 0, 0.1), var(--elevation-100-canvas);
|
|
4253
4262
|
z-index: 1;
|
|
4254
4263
|
}
|
|
4255
4264
|
|
|
@@ -4743,8 +4752,8 @@ fig-choice {
|
|
|
4743
4752
|
}
|
|
4744
4753
|
|
|
4745
4754
|
fig-handle {
|
|
4746
|
-
--width: 0.
|
|
4747
|
-
--height: 0.
|
|
4755
|
+
--width: 0.875rem;
|
|
4756
|
+
--height: 0.875rem;
|
|
4748
4757
|
--fill: var(--figma-color-bg-brand);
|
|
4749
4758
|
--border-radius: 50%;
|
|
4750
4759
|
--ring-width: 1.25px;
|
|
@@ -4754,15 +4763,27 @@ fig-handle {
|
|
|
4754
4763
|
--outline: none;
|
|
4755
4764
|
--border: none;
|
|
4756
4765
|
|
|
4757
|
-
display: inline-
|
|
4766
|
+
display: inline-grid;
|
|
4767
|
+
place-items: center;
|
|
4758
4768
|
width: var(--width);
|
|
4759
4769
|
height: var(--height);
|
|
4760
|
-
background: var(--
|
|
4770
|
+
background: var(--handle-color);
|
|
4761
4771
|
border-radius: var(--border-radius);
|
|
4762
4772
|
box-shadow: var(--box-shadow);
|
|
4763
4773
|
outline: var(--outline);
|
|
4764
4774
|
border: var(--border);
|
|
4765
4775
|
|
|
4776
|
+
&::before {
|
|
4777
|
+
content: "";
|
|
4778
|
+
color-scheme: light only;
|
|
4779
|
+
width: calc(var(--width) - 4px);
|
|
4780
|
+
height: calc(var(--height) - 4px);
|
|
4781
|
+
background: var(--fill);
|
|
4782
|
+
border-radius: var(--border-radius);
|
|
4783
|
+
box-shadow: inset 0 0 0 1px var(--figma-color-bordertranslucent);
|
|
4784
|
+
place-self: center;
|
|
4785
|
+
}
|
|
4786
|
+
|
|
4766
4787
|
&[size="small"] {
|
|
4767
4788
|
--width: 0.5625rem;
|
|
4768
4789
|
--height: 0.5625rem;
|
|
@@ -4772,10 +4793,10 @@ fig-handle {
|
|
|
4772
4793
|
position: absolute;
|
|
4773
4794
|
touch-action: none;
|
|
4774
4795
|
}
|
|
4775
|
-
|
|
4796
|
+
&:hover,
|
|
4776
4797
|
&[selected]:not([selected="false"]) {
|
|
4777
4798
|
outline: var(--ring-width) solid var(--figma-color-border-selected);
|
|
4778
|
-
outline-offset:
|
|
4799
|
+
outline-offset: 0;
|
|
4779
4800
|
}
|
|
4780
4801
|
|
|
4781
4802
|
&[disabled]:not([disabled="false"]),
|
|
@@ -4786,7 +4807,7 @@ fig-handle {
|
|
|
4786
4807
|
}
|
|
4787
4808
|
|
|
4788
4809
|
&[type="color"],
|
|
4789
|
-
&[
|
|
4810
|
+
&[control] {
|
|
4790
4811
|
overflow: visible;
|
|
4791
4812
|
|
|
4792
4813
|
fig-color-tip {
|
|
@@ -4823,6 +4844,11 @@ fig-color-tip {
|
|
|
4823
4844
|
drop-shadow(0px 2.5px 6px rgba(0, 0, 0, 0.13))
|
|
4824
4845
|
drop-shadow(0px 0px 0.5px rgba(0, 0, 0, 0.15));
|
|
4825
4846
|
|
|
4847
|
+
&[control="add"],
|
|
4848
|
+
&[control="remove"] {
|
|
4849
|
+
cursor: pointer;
|
|
4850
|
+
}
|
|
4851
|
+
|
|
4826
4852
|
fig-chit {
|
|
4827
4853
|
input[type="color"] {
|
|
4828
4854
|
background: transparent;
|
package/fig.js
CHANGED
|
@@ -659,7 +659,12 @@ class FigTooltip extends HTMLElement {
|
|
|
659
659
|
};
|
|
660
660
|
}
|
|
661
661
|
|
|
662
|
+
get #showPersisted() {
|
|
663
|
+
return this.hasAttribute("show") && this.getAttribute("show") !== "false";
|
|
664
|
+
}
|
|
665
|
+
|
|
662
666
|
showDelayedPopup() {
|
|
667
|
+
if (this.#showPersisted) return;
|
|
663
668
|
this.render();
|
|
664
669
|
clearTimeout(this.timeout);
|
|
665
670
|
const warm =
|
|
@@ -669,10 +674,12 @@ class FigTooltip extends HTMLElement {
|
|
|
669
674
|
}
|
|
670
675
|
|
|
671
676
|
showPopup() {
|
|
677
|
+
if (!this.popup) this.render();
|
|
678
|
+
this.popup.style.display = "block";
|
|
679
|
+
this.popup.style.visibility = "hidden";
|
|
672
680
|
this.#repositionPopup();
|
|
673
681
|
this.popup.style.opacity = "1";
|
|
674
682
|
this.popup.style.visibility = "visible";
|
|
675
|
-
this.popup.style.display = "block";
|
|
676
683
|
this.popup.style.pointerEvents = "all";
|
|
677
684
|
this.popup.style.zIndex = figGetHighestZIndex() + 1;
|
|
678
685
|
|
|
@@ -725,6 +732,7 @@ class FigTooltip extends HTMLElement {
|
|
|
725
732
|
}
|
|
726
733
|
|
|
727
734
|
hidePopup() {
|
|
735
|
+
if (this.#showPersisted) return;
|
|
728
736
|
clearTimeout(this.timeout);
|
|
729
737
|
clearTimeout(this.#touchTimeout);
|
|
730
738
|
this.#stopObserving();
|
|
@@ -824,7 +832,28 @@ class FigTooltip extends HTMLElement {
|
|
|
824
832
|
}
|
|
825
833
|
|
|
826
834
|
static get observedAttributes() {
|
|
827
|
-
return ["action", "delay", "open"];
|
|
835
|
+
return ["action", "delay", "open", "show", "text"];
|
|
836
|
+
}
|
|
837
|
+
get text() {
|
|
838
|
+
return this.getAttribute("text") ?? "";
|
|
839
|
+
}
|
|
840
|
+
set text(value) {
|
|
841
|
+
this.setAttribute("text", value);
|
|
842
|
+
}
|
|
843
|
+
#updateText(value) {
|
|
844
|
+
if (!this.popup) return;
|
|
845
|
+
const content = this.popup.firstElementChild ?? this.popup.firstChild;
|
|
846
|
+
if (!content) return;
|
|
847
|
+
content.innerText = value;
|
|
848
|
+
content.style.width = "";
|
|
849
|
+
const textNode = content.childNodes[0];
|
|
850
|
+
if (textNode) {
|
|
851
|
+
const range = document.createRange();
|
|
852
|
+
range.setStartBefore(textNode);
|
|
853
|
+
range.setEndAfter(textNode);
|
|
854
|
+
content.style.width = `${range.getBoundingClientRect().width}px`;
|
|
855
|
+
}
|
|
856
|
+
if (this.isOpen) this.#repositionPopup();
|
|
828
857
|
}
|
|
829
858
|
get open() {
|
|
830
859
|
return this.hasAttribute("open") && this.getAttribute("open") === "true";
|
|
@@ -851,6 +880,17 @@ class FigTooltip extends HTMLElement {
|
|
|
851
880
|
});
|
|
852
881
|
}
|
|
853
882
|
}
|
|
883
|
+
if (name === "show") {
|
|
884
|
+
const on = newValue !== null && newValue !== "false";
|
|
885
|
+
if (on) {
|
|
886
|
+
this.showPopup();
|
|
887
|
+
} else {
|
|
888
|
+
this.hidePopup();
|
|
889
|
+
}
|
|
890
|
+
}
|
|
891
|
+
if (name === "text") {
|
|
892
|
+
this.#updateText(newValue ?? "");
|
|
893
|
+
}
|
|
854
894
|
}
|
|
855
895
|
|
|
856
896
|
#hideOnChromeOpen(e) {
|
|
@@ -5651,8 +5691,9 @@ customElements.define("fig-input-fill", FigInputFill);
|
|
|
5651
5691
|
* @fires change - When the gradient value is committed
|
|
5652
5692
|
*/
|
|
5653
5693
|
class FigInputGradient extends HTMLElement {
|
|
5654
|
-
#
|
|
5694
|
+
#chit;
|
|
5655
5695
|
#track;
|
|
5696
|
+
#handleDragging = false;
|
|
5656
5697
|
#colorObserver = null;
|
|
5657
5698
|
#gradient = {
|
|
5658
5699
|
type: "linear",
|
|
@@ -5670,14 +5711,46 @@ class FigInputGradient extends HTMLElement {
|
|
|
5670
5711
|
}
|
|
5671
5712
|
|
|
5672
5713
|
static get observedAttributes() {
|
|
5673
|
-
return ["value", "disabled"
|
|
5714
|
+
return ["value", "disabled"];
|
|
5674
5715
|
}
|
|
5675
5716
|
|
|
5676
5717
|
connectedCallback() {
|
|
5677
5718
|
this.#parseValue();
|
|
5678
5719
|
this.#render();
|
|
5720
|
+
document.addEventListener("keydown", this.#onKeyDown);
|
|
5721
|
+
}
|
|
5722
|
+
|
|
5723
|
+
disconnectedCallback() {
|
|
5724
|
+
document.removeEventListener("keydown", this.#onKeyDown);
|
|
5679
5725
|
}
|
|
5680
5726
|
|
|
5727
|
+
#onKeyDown = (e) => {
|
|
5728
|
+
if (e.key !== "Delete" && e.key !== "Backspace") return;
|
|
5729
|
+
const active = document.activeElement;
|
|
5730
|
+
if (
|
|
5731
|
+
active &&
|
|
5732
|
+
(active.tagName === "INPUT" ||
|
|
5733
|
+
active.tagName === "TEXTAREA" ||
|
|
5734
|
+
active.isContentEditable)
|
|
5735
|
+
)
|
|
5736
|
+
return;
|
|
5737
|
+
if (this.#gradient.stops.length <= 2) return;
|
|
5738
|
+
if (!this.#track) return;
|
|
5739
|
+
const selected = this.#track.querySelector(
|
|
5740
|
+
"fig-handle[selected]:not(.fig-input-gradient-ghost)",
|
|
5741
|
+
);
|
|
5742
|
+
if (!selected) return;
|
|
5743
|
+
const idx = parseInt(selected.dataset.stopIndex, 10);
|
|
5744
|
+
if (isNaN(idx) || !this.#gradient.stops[idx]) return;
|
|
5745
|
+
e.preventDefault();
|
|
5746
|
+
selected.removeAttribute("selected");
|
|
5747
|
+
this.#gradient.stops.splice(idx, 1);
|
|
5748
|
+
this.#syncHandles();
|
|
5749
|
+
this.#syncChit();
|
|
5750
|
+
this.#emitInput();
|
|
5751
|
+
this.#emitChange();
|
|
5752
|
+
};
|
|
5753
|
+
|
|
5681
5754
|
#parseValue() {
|
|
5682
5755
|
const valueAttr = this.getAttribute("value");
|
|
5683
5756
|
if (!valueAttr) return;
|
|
@@ -5701,19 +5774,12 @@ class FigInputGradient extends HTMLElement {
|
|
|
5701
5774
|
}
|
|
5702
5775
|
}
|
|
5703
5776
|
|
|
5704
|
-
#
|
|
5705
|
-
const
|
|
5706
|
-
|
|
5707
|
-
|
|
5708
|
-
|
|
5709
|
-
|
|
5710
|
-
attrs[name.slice(7)] = value;
|
|
5711
|
-
}
|
|
5712
|
-
}
|
|
5713
|
-
if (!attrs["dialog-position"]) attrs["dialog-position"] = "left";
|
|
5714
|
-
return Object.entries(attrs)
|
|
5715
|
-
.map(([k, v]) => `${k}="${v}"`)
|
|
5716
|
-
.join(" ");
|
|
5777
|
+
#buildGradientCSS() {
|
|
5778
|
+
const sorted = [...this.#gradient.stops].sort(
|
|
5779
|
+
(a, b) => a.position - b.position,
|
|
5780
|
+
);
|
|
5781
|
+
const stops = sorted.map((s) => `${s.color} ${s.position}%`).join(", ");
|
|
5782
|
+
return `linear-gradient(${this.#gradient.angle}deg, ${stops})`;
|
|
5717
5783
|
}
|
|
5718
5784
|
|
|
5719
5785
|
#buildStopHandles() {
|
|
@@ -5721,23 +5787,19 @@ class FigInputGradient extends HTMLElement {
|
|
|
5721
5787
|
return this.#gradient.stops
|
|
5722
5788
|
.map(
|
|
5723
5789
|
(stop, i) =>
|
|
5724
|
-
`<fig-handle drag drag-axes="x" type="color" color="${stop.color}" value="${stop.position}% 50%" data-stop-index="${i}"${disabled ? " disabled" : ""}></fig-handle>`,
|
|
5790
|
+
`<fig-tooltip action="manual" text="${Math.round(stop.position)}%"><fig-handle drag drag-axes="x" drag-surface=".fig-input-gradient-track" type="color" color="${stop.color}" value="${stop.position}% 50%" data-stop-index="${i}"${disabled ? " disabled" : ""}></fig-handle></fig-tooltip>`,
|
|
5725
5791
|
)
|
|
5726
5792
|
.join("");
|
|
5727
5793
|
}
|
|
5728
5794
|
|
|
5729
5795
|
#ghostHandle = null;
|
|
5730
|
-
#ghostTooltip = null;
|
|
5731
5796
|
|
|
5732
5797
|
#render() {
|
|
5733
5798
|
const disabled = this.hasAttribute("disabled");
|
|
5734
|
-
const fillPickerValue = JSON.stringify(this.value);
|
|
5735
|
-
const fpAttrs = this.#buildFillPickerAttrs();
|
|
5736
5799
|
this.innerHTML = `
|
|
5737
|
-
<fig-
|
|
5738
|
-
disabled ? "disabled" : ""
|
|
5739
|
-
}></fig-fill-picker>
|
|
5800
|
+
<fig-chit size="medium" background="${this.#buildGradientCSS()}"${disabled ? " disabled" : ""}></fig-chit>
|
|
5740
5801
|
<div class="fig-input-gradient-track">${this.#buildStopHandles()}</div>`;
|
|
5802
|
+
this.#chit = this.querySelector("fig-chit");
|
|
5741
5803
|
this.#track = this.querySelector(".fig-input-gradient-track");
|
|
5742
5804
|
this.#setupGhostHandle();
|
|
5743
5805
|
this.#setupEventListeners();
|
|
@@ -5768,22 +5830,31 @@ class FigInputGradient extends HTMLElement {
|
|
|
5768
5830
|
|
|
5769
5831
|
const ghost = document.createElement("fig-handle");
|
|
5770
5832
|
ghost.classList.add("fig-input-gradient-ghost");
|
|
5771
|
-
ghost.setAttribute("add", "");
|
|
5772
5833
|
ghost.style.position = "absolute";
|
|
5773
5834
|
ghost.style.top = "50%";
|
|
5774
5835
|
ghost.style.transform = "translate(-50%, -50%)";
|
|
5775
5836
|
ghost.style.pointerEvents = "none";
|
|
5776
5837
|
ghost.style.opacity = "0";
|
|
5777
5838
|
ghost.style.transition = "opacity 0.15s";
|
|
5839
|
+
ghost.style.overflow = "visible";
|
|
5840
|
+
|
|
5841
|
+
const tip = document.createElement("fig-color-tip");
|
|
5842
|
+
tip.setAttribute("control", "add");
|
|
5843
|
+
tip.style.position = "absolute";
|
|
5844
|
+
tip.style.bottom = "calc(100% + 6px)";
|
|
5845
|
+
tip.style.left = "50%";
|
|
5846
|
+
tip.style.transform = "translateX(-50%)";
|
|
5847
|
+
tip.style.zIndex = "10";
|
|
5848
|
+
ghost.appendChild(tip);
|
|
5778
5849
|
|
|
5779
5850
|
this.#track.appendChild(ghost);
|
|
5780
5851
|
this.#ghostHandle = ghost;
|
|
5781
|
-
this.#ghostTooltip = null;
|
|
5782
5852
|
|
|
5783
5853
|
this.addEventListener("pointerenter", this.#onTrackEnter);
|
|
5784
5854
|
this.addEventListener("pointermove", this.#onTrackMove);
|
|
5785
5855
|
this.addEventListener("pointerleave", this.#onTrackLeave);
|
|
5786
5856
|
this.addEventListener("click", this.#onTrackClick);
|
|
5857
|
+
this.addEventListener("dblclick", this.#onTrackDblClick);
|
|
5787
5858
|
}
|
|
5788
5859
|
|
|
5789
5860
|
#showGhost() {
|
|
@@ -5797,6 +5868,7 @@ class FigInputGradient extends HTMLElement {
|
|
|
5797
5868
|
}
|
|
5798
5869
|
|
|
5799
5870
|
#onTrackEnter = () => {
|
|
5871
|
+
if (this.#handleDragging) return;
|
|
5800
5872
|
this.#showGhost();
|
|
5801
5873
|
};
|
|
5802
5874
|
|
|
@@ -5805,6 +5877,10 @@ class FigInputGradient extends HTMLElement {
|
|
|
5805
5877
|
};
|
|
5806
5878
|
|
|
5807
5879
|
#onTrackMove = (e) => {
|
|
5880
|
+
if (this.#handleDragging) {
|
|
5881
|
+
this.#hideGhost();
|
|
5882
|
+
return;
|
|
5883
|
+
}
|
|
5808
5884
|
if (!this.#ghostHandle || !this.#track) return;
|
|
5809
5885
|
if (e.target.closest("fig-handle:not(.fig-input-gradient-ghost)")) {
|
|
5810
5886
|
this.#hideGhost();
|
|
@@ -5821,9 +5897,37 @@ class FigInputGradient extends HTMLElement {
|
|
|
5821
5897
|
this.#showGhost();
|
|
5822
5898
|
};
|
|
5823
5899
|
|
|
5900
|
+
#distributeStops() {
|
|
5901
|
+
const count = this.#gradient.stops.length;
|
|
5902
|
+
if (count < 2) return;
|
|
5903
|
+
for (let i = 0; i < count; i++) {
|
|
5904
|
+
this.#gradient.stops[i].position = Math.round((i / (count - 1)) * 100);
|
|
5905
|
+
}
|
|
5906
|
+
this.#syncHandles();
|
|
5907
|
+
this.#syncChit();
|
|
5908
|
+
this.#emitInput();
|
|
5909
|
+
this.#emitChange();
|
|
5910
|
+
this.#track?.querySelectorAll("fig-handle[selected]").forEach((h) => {
|
|
5911
|
+
h.removeAttribute("selected");
|
|
5912
|
+
});
|
|
5913
|
+
}
|
|
5914
|
+
|
|
5915
|
+
#onTrackDblClick = (e) => {
|
|
5916
|
+
if (!this.#track) return;
|
|
5917
|
+
if (!e.target.closest("fig-handle:not(.fig-input-gradient-ghost)")) return;
|
|
5918
|
+
this.#distributeStops();
|
|
5919
|
+
};
|
|
5920
|
+
|
|
5824
5921
|
#onTrackClick = (e) => {
|
|
5825
5922
|
if (!this.#track) return;
|
|
5826
|
-
if (
|
|
5923
|
+
if (this.#handleDragging) return;
|
|
5924
|
+
if (e.target.closest("fig-handle:not(.fig-input-gradient-ghost)")) {
|
|
5925
|
+
if (e.shiftKey) {
|
|
5926
|
+
this.#distributeStops();
|
|
5927
|
+
e.stopPropagation();
|
|
5928
|
+
}
|
|
5929
|
+
return;
|
|
5930
|
+
}
|
|
5827
5931
|
const trackRect = this.#track.getBoundingClientRect();
|
|
5828
5932
|
const pct = Math.max(
|
|
5829
5933
|
0,
|
|
@@ -5837,7 +5941,7 @@ class FigInputGradient extends HTMLElement {
|
|
|
5837
5941
|
(s) => s.position === position && s.color === color,
|
|
5838
5942
|
);
|
|
5839
5943
|
this.#syncHandles();
|
|
5840
|
-
this.#
|
|
5944
|
+
this.#syncChit();
|
|
5841
5945
|
this.#emitInput();
|
|
5842
5946
|
this.#emitChange();
|
|
5843
5947
|
|
|
@@ -5870,6 +5974,8 @@ class FigInputGradient extends HTMLElement {
|
|
|
5870
5974
|
const stop = stops[i];
|
|
5871
5975
|
h.setAttribute("value", `${stop.position}% 50%`);
|
|
5872
5976
|
h.setAttribute("color", stop.color);
|
|
5977
|
+
const tip = h.closest("fig-tooltip");
|
|
5978
|
+
if (tip) tip.setAttribute("text", `${Math.round(stop.position)}%`);
|
|
5873
5979
|
}
|
|
5874
5980
|
}
|
|
5875
5981
|
|
|
@@ -5886,92 +5992,155 @@ class FigInputGradient extends HTMLElement {
|
|
|
5886
5992
|
});
|
|
5887
5993
|
}
|
|
5888
5994
|
|
|
5889
|
-
#
|
|
5890
|
-
if (!this.#
|
|
5891
|
-
this.#
|
|
5995
|
+
#syncStopIndices() {
|
|
5996
|
+
if (!this.#track) return;
|
|
5997
|
+
const handles = this.#track.querySelectorAll(
|
|
5998
|
+
"fig-handle:not(.fig-input-gradient-ghost)",
|
|
5999
|
+
);
|
|
6000
|
+
const stops = this.#gradient.stops;
|
|
6001
|
+
const used = new Set();
|
|
6002
|
+
handles.forEach((h) => {
|
|
6003
|
+
const pos = Math.round(parseFloat(h.getAttribute("value")) || 0);
|
|
6004
|
+
const color = (h.getAttribute("color") || "").toUpperCase();
|
|
6005
|
+
let best = -1;
|
|
6006
|
+
for (let i = 0; i < stops.length; i++) {
|
|
6007
|
+
if (used.has(i)) continue;
|
|
6008
|
+
if (
|
|
6009
|
+
stops[i].position === pos &&
|
|
6010
|
+
stops[i].color.toUpperCase() === color
|
|
6011
|
+
) {
|
|
6012
|
+
best = i;
|
|
6013
|
+
break;
|
|
6014
|
+
}
|
|
6015
|
+
}
|
|
6016
|
+
if (best === -1) {
|
|
6017
|
+
let minDist = Infinity;
|
|
6018
|
+
for (let i = 0; i < stops.length; i++) {
|
|
6019
|
+
if (used.has(i)) continue;
|
|
6020
|
+
const d = Math.abs(stops[i].position - pos);
|
|
6021
|
+
if (d < minDist) {
|
|
6022
|
+
minDist = d;
|
|
6023
|
+
best = i;
|
|
6024
|
+
}
|
|
6025
|
+
}
|
|
6026
|
+
}
|
|
6027
|
+
if (best !== -1) {
|
|
6028
|
+
used.add(best);
|
|
6029
|
+
h.dataset.stopIndex = best;
|
|
6030
|
+
}
|
|
6031
|
+
});
|
|
6032
|
+
}
|
|
6033
|
+
|
|
6034
|
+
#syncChit() {
|
|
6035
|
+
if (!this.#chit) return;
|
|
6036
|
+
this.#chit.setAttribute("background", this.#buildGradientCSS());
|
|
5892
6037
|
}
|
|
5893
6038
|
|
|
5894
6039
|
#setupEventListeners() {
|
|
5895
|
-
|
|
5896
|
-
this.#fillPicker = this.querySelector("fig-fill-picker");
|
|
5897
|
-
if (!this.#fillPicker) return;
|
|
6040
|
+
if (!this.#track) return;
|
|
5898
6041
|
|
|
5899
|
-
|
|
5900
|
-
|
|
5901
|
-
|
|
6042
|
+
this.#track.addEventListener("input", (e) => {
|
|
6043
|
+
const handle = e.target.closest("fig-handle");
|
|
6044
|
+
if (!handle) return;
|
|
6045
|
+
e.stopPropagation();
|
|
6046
|
+
if (!this.#handleDragging) handle.style.zIndex = "5";
|
|
6047
|
+
this.#handleDragging = true;
|
|
6048
|
+
const idx = parseInt(handle.dataset.stopIndex, 10);
|
|
6049
|
+
if (isNaN(idx) || !this.#gradient.stops[idx]) return;
|
|
6050
|
+
const px = e.detail?.px ?? 0;
|
|
6051
|
+
const rawPosition = Math.round(px * 100);
|
|
6052
|
+
let position = rawPosition;
|
|
6053
|
+
const trackW = this.#track.getBoundingClientRect().width;
|
|
6054
|
+
if (e.detail?.shiftKey) {
|
|
6055
|
+
position = Math.round(position / 10) * 10;
|
|
5902
6056
|
} else {
|
|
5903
|
-
const
|
|
5904
|
-
|
|
6057
|
+
const snapPct = trackW > 0 ? (5 / trackW) * 100 : 0;
|
|
6058
|
+
for (let i = 0; i < this.#gradient.stops.length; i++) {
|
|
6059
|
+
if (i === idx) continue;
|
|
6060
|
+
if (
|
|
6061
|
+
Math.abs(this.#gradient.stops[i].position - position) <= snapPct
|
|
6062
|
+
) {
|
|
6063
|
+
position = this.#gradient.stops[i].position;
|
|
6064
|
+
break;
|
|
6065
|
+
}
|
|
6066
|
+
}
|
|
6067
|
+
}
|
|
6068
|
+
this.#gradient.stops[idx].position = position;
|
|
6069
|
+
if (position !== rawPosition) {
|
|
6070
|
+
handle.style.left = `${(position / 100) * trackW - handle.offsetWidth / 2}px`;
|
|
5905
6071
|
}
|
|
6072
|
+
const tooltip = handle.closest("fig-tooltip");
|
|
6073
|
+
if (tooltip) {
|
|
6074
|
+
tooltip.text = `${Math.round(position)}%`;
|
|
6075
|
+
if (!tooltip.hasAttribute("show")) tooltip.setAttribute("show", "true");
|
|
6076
|
+
}
|
|
6077
|
+
this.#syncChit();
|
|
6078
|
+
this.#emitInput();
|
|
6079
|
+
});
|
|
5906
6080
|
|
|
5907
|
-
|
|
5908
|
-
|
|
5909
|
-
|
|
5910
|
-
|
|
5911
|
-
|
|
5912
|
-
|
|
5913
|
-
|
|
5914
|
-
|
|
5915
|
-
|
|
5916
|
-
|
|
6081
|
+
this.#track.addEventListener("change", (e) => {
|
|
6082
|
+
const handle = e.target.closest("fig-handle");
|
|
6083
|
+
if (!handle) return;
|
|
6084
|
+
e.stopPropagation();
|
|
6085
|
+
handle.style.zIndex = "";
|
|
6086
|
+
const tooltip = handle.closest("fig-tooltip");
|
|
6087
|
+
if (tooltip) tooltip.removeAttribute("show");
|
|
6088
|
+
const idx = parseInt(handle.dataset.stopIndex, 10);
|
|
6089
|
+
if (isNaN(idx) || !this.#gradient.stops[idx]) return;
|
|
6090
|
+
const px = e.detail?.px ?? 0;
|
|
6091
|
+
let position = Math.round(px * 100);
|
|
6092
|
+
const trackW = this.#track.getBoundingClientRect().width;
|
|
6093
|
+
const snapPct = trackW > 0 ? (5 / trackW) * 100 : 0;
|
|
6094
|
+
for (let i = 0; i < this.#gradient.stops.length; i++) {
|
|
6095
|
+
if (i === idx) continue;
|
|
6096
|
+
if (Math.abs(this.#gradient.stops[i].position - position) <= snapPct) {
|
|
6097
|
+
position = this.#gradient.stops[i].position;
|
|
6098
|
+
break;
|
|
5917
6099
|
}
|
|
6100
|
+
}
|
|
6101
|
+
this.#gradient.stops[idx].position = position;
|
|
6102
|
+
handle.style.left = `${(position / 100) * trackW - handle.offsetWidth / 2}px`;
|
|
6103
|
+
this.#gradient.stops.sort((a, b) => a.position - b.position);
|
|
6104
|
+
this.#syncStopIndices();
|
|
6105
|
+
this.#syncChit();
|
|
6106
|
+
this.#emitChange();
|
|
6107
|
+
const swallow = (evt) => {
|
|
6108
|
+
evt.stopPropagation();
|
|
6109
|
+
evt.preventDefault();
|
|
6110
|
+
};
|
|
6111
|
+
this.#track.addEventListener("click", swallow, {
|
|
6112
|
+
capture: true,
|
|
6113
|
+
once: true,
|
|
5918
6114
|
});
|
|
5919
|
-
|
|
5920
|
-
|
|
5921
|
-
|
|
5922
|
-
this.#emitChange();
|
|
6115
|
+
requestAnimationFrame(() => {
|
|
6116
|
+
this.#handleDragging = false;
|
|
6117
|
+
this.#track.removeEventListener("click", swallow, { capture: true });
|
|
5923
6118
|
});
|
|
6119
|
+
});
|
|
5924
6120
|
|
|
5925
|
-
|
|
5926
|
-
|
|
5927
|
-
|
|
5928
|
-
|
|
5929
|
-
|
|
5930
|
-
|
|
5931
|
-
|
|
5932
|
-
|
|
5933
|
-
|
|
5934
|
-
this.#
|
|
6121
|
+
this.#colorObserver = new MutationObserver((mutations) => {
|
|
6122
|
+
for (const m of mutations) {
|
|
6123
|
+
if (m.attributeName !== "color") continue;
|
|
6124
|
+
const handle = m.target;
|
|
6125
|
+
if (handle.classList.contains("fig-input-gradient-ghost")) continue;
|
|
6126
|
+
const idx = parseInt(handle.dataset.stopIndex, 10);
|
|
6127
|
+
if (isNaN(idx) || !this.#gradient.stops[idx]) continue;
|
|
6128
|
+
const newColor = handle.getAttribute("color");
|
|
6129
|
+
if (newColor && newColor !== this.#gradient.stops[idx].color) {
|
|
6130
|
+
this.#gradient.stops[idx].color = newColor;
|
|
6131
|
+
this.#syncChit();
|
|
5935
6132
|
this.#emitInput();
|
|
5936
|
-
}
|
|
5937
|
-
|
|
5938
|
-
this.#track.addEventListener("change", (e) => {
|
|
5939
|
-
const handle = e.target.closest("fig-handle");
|
|
5940
|
-
if (!handle) return;
|
|
5941
|
-
e.stopPropagation();
|
|
5942
|
-
const idx = parseInt(handle.dataset.stopIndex, 10);
|
|
5943
|
-
if (isNaN(idx) || !this.#gradient.stops[idx]) return;
|
|
5944
|
-
const px = e.detail?.px ?? 0;
|
|
5945
|
-
this.#gradient.stops[idx].position = Math.round(px * 100);
|
|
5946
|
-
this.#syncFillPicker();
|
|
5947
|
-
this.#emitChange();
|
|
5948
|
-
});
|
|
5949
|
-
|
|
5950
|
-
this.#colorObserver = new MutationObserver((mutations) => {
|
|
5951
|
-
for (const m of mutations) {
|
|
5952
|
-
if (m.attributeName !== "color") continue;
|
|
5953
|
-
const handle = m.target;
|
|
5954
|
-
if (handle.classList.contains("fig-input-gradient-ghost")) continue;
|
|
5955
|
-
const idx = parseInt(handle.dataset.stopIndex, 10);
|
|
5956
|
-
if (isNaN(idx) || !this.#gradient.stops[idx]) continue;
|
|
5957
|
-
const newColor = handle.getAttribute("color");
|
|
5958
|
-
if (newColor && newColor !== this.#gradient.stops[idx].color) {
|
|
5959
|
-
this.#gradient.stops[idx].color = newColor;
|
|
5960
|
-
this.#syncFillPicker();
|
|
5961
|
-
this.#emitInput();
|
|
5962
|
-
}
|
|
5963
|
-
}
|
|
5964
|
-
});
|
|
5965
|
-
this.#track
|
|
5966
|
-
.querySelectorAll("fig-handle:not(.fig-input-gradient-ghost)")
|
|
5967
|
-
.forEach((h) => {
|
|
5968
|
-
this.#colorObserver.observe(h, {
|
|
5969
|
-
attributes: true,
|
|
5970
|
-
attributeFilter: ["color"],
|
|
5971
|
-
});
|
|
5972
|
-
});
|
|
6133
|
+
}
|
|
5973
6134
|
}
|
|
5974
6135
|
});
|
|
6136
|
+
this.#track
|
|
6137
|
+
.querySelectorAll("fig-handle:not(.fig-input-gradient-ghost)")
|
|
6138
|
+
.forEach((h) => {
|
|
6139
|
+
this.#colorObserver.observe(h, {
|
|
6140
|
+
attributes: true,
|
|
6141
|
+
attributeFilter: ["color"],
|
|
6142
|
+
});
|
|
6143
|
+
});
|
|
5975
6144
|
}
|
|
5976
6145
|
|
|
5977
6146
|
#emitInput() {
|
|
@@ -6012,15 +6181,11 @@ class FigInputGradient extends HTMLElement {
|
|
|
6012
6181
|
switch (name) {
|
|
6013
6182
|
case "value":
|
|
6014
6183
|
this.#parseValue();
|
|
6015
|
-
|
|
6016
|
-
this.#syncFillPicker();
|
|
6017
|
-
}
|
|
6184
|
+
this.#syncChit();
|
|
6018
6185
|
this.#syncHandles();
|
|
6019
6186
|
break;
|
|
6020
6187
|
case "disabled":
|
|
6021
|
-
|
|
6022
|
-
case "picker-anchor":
|
|
6023
|
-
if (this.#fillPicker) this.#render();
|
|
6188
|
+
this.#render();
|
|
6024
6189
|
break;
|
|
6025
6190
|
}
|
|
6026
6191
|
}
|
|
@@ -10295,6 +10460,7 @@ class FigFillPicker extends HTMLElement {
|
|
|
10295
10460
|
drag
|
|
10296
10461
|
drag-surface=".fig-fill-picker-color-area"
|
|
10297
10462
|
drag-axes="x,y"
|
|
10463
|
+
drag-snapping="modifier"
|
|
10298
10464
|
></fig-handle>
|
|
10299
10465
|
</fig-preview>
|
|
10300
10466
|
<div class="fig-fill-picker-sliders">
|
|
@@ -11882,12 +12048,11 @@ class FigColorTip extends HTMLElement {
|
|
|
11882
12048
|
#boundHandleChange = this.#handlePickerChange.bind(this);
|
|
11883
12049
|
|
|
11884
12050
|
static get observedAttributes() {
|
|
11885
|
-
return ["value", "selected", "disabled", "alpha", "
|
|
12051
|
+
return ["value", "selected", "disabled", "alpha", "control"];
|
|
11886
12052
|
}
|
|
11887
12053
|
|
|
11888
|
-
get #
|
|
11889
|
-
|
|
11890
|
-
return v !== null && v !== "false";
|
|
12054
|
+
get #controlMode() {
|
|
12055
|
+
return this.getAttribute("control") || "color";
|
|
11891
12056
|
}
|
|
11892
12057
|
|
|
11893
12058
|
connectedCallback() {
|
|
@@ -11897,7 +12062,7 @@ class FigColorTip extends HTMLElement {
|
|
|
11897
12062
|
|
|
11898
12063
|
disconnectedCallback() {
|
|
11899
12064
|
this.#teardownListeners();
|
|
11900
|
-
this.removeEventListener("click", this.#
|
|
12065
|
+
this.removeEventListener("click", this.#handleControlClick);
|
|
11901
12066
|
}
|
|
11902
12067
|
|
|
11903
12068
|
#teardownListeners() {
|
|
@@ -11922,14 +12087,16 @@ class FigColorTip extends HTMLElement {
|
|
|
11922
12087
|
}
|
|
11923
12088
|
|
|
11924
12089
|
#render() {
|
|
11925
|
-
|
|
11926
|
-
|
|
12090
|
+
const mode = this.#controlMode;
|
|
12091
|
+
if (mode === "add" || mode === "remove") {
|
|
12092
|
+
const icon = mode === "add" ? "var(--icon-add)" : "var(--icon-minus)";
|
|
12093
|
+
this.innerHTML = `<fig-button icon variant="ghost"><span class="fig-mask-icon" style="--icon: ${icon}"></span></fig-button>`;
|
|
11927
12094
|
this.#fillPicker = null;
|
|
11928
12095
|
this.#chit = null;
|
|
11929
|
-
this.addEventListener("click", this.#
|
|
12096
|
+
this.addEventListener("click", this.#handleControlClick);
|
|
11930
12097
|
return;
|
|
11931
12098
|
}
|
|
11932
|
-
this.removeEventListener("click", this.#
|
|
12099
|
+
this.removeEventListener("click", this.#handleControlClick);
|
|
11933
12100
|
|
|
11934
12101
|
const color = this.#normalizeColor(this.getAttribute("value"));
|
|
11935
12102
|
const alphaAttr = this.#alphaEnabled ? "" : 'alpha="false"';
|
|
@@ -11949,9 +12116,10 @@ class FigColorTip extends HTMLElement {
|
|
|
11949
12116
|
});
|
|
11950
12117
|
}
|
|
11951
12118
|
|
|
11952
|
-
#
|
|
12119
|
+
#handleControlClick = () => {
|
|
12120
|
+
const mode = this.#controlMode;
|
|
11953
12121
|
this.dispatchEvent(
|
|
11954
|
-
new CustomEvent(
|
|
12122
|
+
new CustomEvent(mode, { bubbles: true, composed: true }),
|
|
11955
12123
|
);
|
|
11956
12124
|
};
|
|
11957
12125
|
|
|
@@ -12083,7 +12251,7 @@ class FigColorTip extends HTMLElement {
|
|
|
12083
12251
|
if (!this.isConnected) return;
|
|
12084
12252
|
|
|
12085
12253
|
switch (name) {
|
|
12086
|
-
case "
|
|
12254
|
+
case "control":
|
|
12087
12255
|
this.#render();
|
|
12088
12256
|
break;
|
|
12089
12257
|
case "value":
|
|
@@ -12695,7 +12863,7 @@ class FigHandle extends HTMLElement {
|
|
|
12695
12863
|
"drag-snapping",
|
|
12696
12864
|
"value",
|
|
12697
12865
|
"type",
|
|
12698
|
-
"
|
|
12866
|
+
"control",
|
|
12699
12867
|
];
|
|
12700
12868
|
|
|
12701
12869
|
#isDragging = false;
|
|
@@ -12704,8 +12872,16 @@ class FigHandle extends HTMLElement {
|
|
|
12704
12872
|
#applyingValue = false;
|
|
12705
12873
|
#colorTip = null;
|
|
12706
12874
|
|
|
12707
|
-
get #
|
|
12708
|
-
return this.
|
|
12875
|
+
get #controlMode() {
|
|
12876
|
+
return this.getAttribute("control") || null;
|
|
12877
|
+
}
|
|
12878
|
+
|
|
12879
|
+
get #hasControlMode() {
|
|
12880
|
+
return this.#controlMode === "add" || this.#controlMode === "remove";
|
|
12881
|
+
}
|
|
12882
|
+
|
|
12883
|
+
get #isGhost() {
|
|
12884
|
+
return this.classList.contains("fig-input-gradient-ghost");
|
|
12709
12885
|
}
|
|
12710
12886
|
|
|
12711
12887
|
get #dragEnabled() {
|
|
@@ -12838,7 +13014,7 @@ class FigHandle extends HTMLElement {
|
|
|
12838
13014
|
document.addEventListener("pointerdown", this.#handleDeselect);
|
|
12839
13015
|
const initial = this.getAttribute("value");
|
|
12840
13016
|
if (initial) this.#applyValue(initial);
|
|
12841
|
-
if (this.#
|
|
13017
|
+
if (this.#hasControlMode && !this.#isGhost) this.#showColorTip();
|
|
12842
13018
|
}
|
|
12843
13019
|
|
|
12844
13020
|
disconnectedCallback() {
|
|
@@ -12850,7 +13026,7 @@ class FigHandle extends HTMLElement {
|
|
|
12850
13026
|
|
|
12851
13027
|
#handleSelect = (e) => {
|
|
12852
13028
|
if (this.hasAttribute("disabled")) return;
|
|
12853
|
-
if (this.#
|
|
13029
|
+
if (this.#hasControlMode) return;
|
|
12854
13030
|
if (this.#didDrag) {
|
|
12855
13031
|
this.#didDrag = false;
|
|
12856
13032
|
return;
|
|
@@ -12860,7 +13036,7 @@ class FigHandle extends HTMLElement {
|
|
|
12860
13036
|
};
|
|
12861
13037
|
|
|
12862
13038
|
#handleDeselect = (e) => {
|
|
12863
|
-
if (this.#
|
|
13039
|
+
if (this.#hasControlMode) return;
|
|
12864
13040
|
if (this.contains(e.target)) return;
|
|
12865
13041
|
if (this.#colorTip && e.target.closest?.("dialog, [popover]")) return;
|
|
12866
13042
|
this.removeAttribute("selected");
|
|
@@ -12869,7 +13045,7 @@ class FigHandle extends HTMLElement {
|
|
|
12869
13045
|
|
|
12870
13046
|
attributeChangedCallback(name, _old, value) {
|
|
12871
13047
|
if (name === "color") {
|
|
12872
|
-
if (!value || value === "false") {
|
|
13048
|
+
if (!value || value === "false" || value === "true") {
|
|
12873
13049
|
this.style.removeProperty("--fill");
|
|
12874
13050
|
} else {
|
|
12875
13051
|
this.style.setProperty("--fill", value);
|
|
@@ -12879,8 +13055,9 @@ class FigHandle extends HTMLElement {
|
|
|
12879
13055
|
if (name === "value" && !this.#applyingValue && !this.#isDragging) {
|
|
12880
13056
|
this.#applyValue(value);
|
|
12881
13057
|
}
|
|
12882
|
-
if (name === "
|
|
12883
|
-
if (this.#
|
|
13058
|
+
if (name === "control" && !this.#isGhost) {
|
|
13059
|
+
if (this.#hasControlMode) {
|
|
13060
|
+
this.#hideColorTip();
|
|
12884
13061
|
this.#showColorTip();
|
|
12885
13062
|
} else {
|
|
12886
13063
|
this.#hideColorTip();
|
|
@@ -12962,28 +13139,21 @@ class FigHandle extends HTMLElement {
|
|
|
12962
13139
|
}
|
|
12963
13140
|
};
|
|
12964
13141
|
|
|
12965
|
-
const isColorType = this.getAttribute("type") === "color";
|
|
12966
|
-
if (!isColorType) {
|
|
12967
|
-
clampAndApply(e.clientX, e.clientY, e.shiftKey);
|
|
12968
|
-
}
|
|
12969
|
-
this.style.cursor = "grabbing";
|
|
12970
|
-
if (!isColorType) {
|
|
12971
|
-
this.dispatchEvent(
|
|
12972
|
-
new CustomEvent("input", {
|
|
12973
|
-
bubbles: true,
|
|
12974
|
-
detail: this.#positionDetail(containerRect),
|
|
12975
|
-
}),
|
|
12976
|
-
);
|
|
12977
|
-
}
|
|
12978
|
-
|
|
12979
13142
|
const onMove = (e) => {
|
|
12980
13143
|
if (!this.#isDragging) return;
|
|
13144
|
+
if (!this.#didDrag) {
|
|
13145
|
+
this.classList.add("dragging");
|
|
13146
|
+
this.style.cursor = "grabbing";
|
|
13147
|
+
}
|
|
12981
13148
|
this.#didDrag = true;
|
|
12982
13149
|
clampAndApply(e.clientX, e.clientY, e.shiftKey);
|
|
12983
13150
|
this.dispatchEvent(
|
|
12984
13151
|
new CustomEvent("input", {
|
|
12985
13152
|
bubbles: true,
|
|
12986
|
-
detail:
|
|
13153
|
+
detail: {
|
|
13154
|
+
...this.#positionDetail(container.getBoundingClientRect()),
|
|
13155
|
+
shiftKey: e.shiftKey,
|
|
13156
|
+
},
|
|
12987
13157
|
}),
|
|
12988
13158
|
);
|
|
12989
13159
|
};
|
|
@@ -12991,18 +13161,30 @@ class FigHandle extends HTMLElement {
|
|
|
12991
13161
|
const onUp = (e) => {
|
|
12992
13162
|
this.#isDragging = false;
|
|
12993
13163
|
this.style.cursor = "";
|
|
13164
|
+
this.classList.remove("dragging");
|
|
12994
13165
|
window.removeEventListener("pointermove", onMove);
|
|
12995
13166
|
window.removeEventListener("pointerup", onUp);
|
|
12996
|
-
if (this.#didDrag
|
|
13167
|
+
if (this.#didDrag) {
|
|
12997
13168
|
clampAndApply(e.clientX, e.clientY, e.shiftKey);
|
|
13169
|
+
this.#syncValueAttribute();
|
|
13170
|
+
this.dispatchEvent(
|
|
13171
|
+
new CustomEvent("change", {
|
|
13172
|
+
bubbles: true,
|
|
13173
|
+
detail: this.#positionDetail(container.getBoundingClientRect()),
|
|
13174
|
+
}),
|
|
13175
|
+
);
|
|
13176
|
+
const swallowClick = (evt) => {
|
|
13177
|
+
evt.stopPropagation();
|
|
13178
|
+
evt.preventDefault();
|
|
13179
|
+
};
|
|
13180
|
+
this.addEventListener("click", swallowClick, {
|
|
13181
|
+
capture: true,
|
|
13182
|
+
once: true,
|
|
13183
|
+
});
|
|
13184
|
+
} else {
|
|
13185
|
+
this.#syncValueAttribute();
|
|
12998
13186
|
}
|
|
12999
|
-
this.#
|
|
13000
|
-
this.dispatchEvent(
|
|
13001
|
-
new CustomEvent("change", {
|
|
13002
|
-
bubbles: true,
|
|
13003
|
-
detail: this.#positionDetail(container.getBoundingClientRect()),
|
|
13004
|
-
}),
|
|
13005
|
-
);
|
|
13187
|
+
this.#didDrag = false;
|
|
13006
13188
|
};
|
|
13007
13189
|
|
|
13008
13190
|
window.addEventListener("pointermove", onMove);
|
|
@@ -13012,17 +13194,17 @@ class FigHandle extends HTMLElement {
|
|
|
13012
13194
|
#showColorTip() {
|
|
13013
13195
|
if (this.#colorTip) return;
|
|
13014
13196
|
const tip = document.createElement("fig-color-tip");
|
|
13015
|
-
if (this.#
|
|
13016
|
-
tip.setAttribute("
|
|
13197
|
+
if (this.#hasControlMode) {
|
|
13198
|
+
tip.setAttribute("control", this.#controlMode);
|
|
13017
13199
|
} else {
|
|
13018
13200
|
tip.setAttribute("value", this.getAttribute("color") || "#D9D9D9");
|
|
13019
13201
|
tip.setAttribute("alpha", "true");
|
|
13020
13202
|
tip.setAttribute("selected", "");
|
|
13021
13203
|
}
|
|
13022
|
-
tip.addEventListener("pointerdown", (e) => e.stopPropagation());
|
|
13023
13204
|
tip.addEventListener("input", this.#handleColorTipInput);
|
|
13024
13205
|
tip.addEventListener("change", this.#handleColorTipChange);
|
|
13025
|
-
tip.addEventListener("add", this.#
|
|
13206
|
+
tip.addEventListener("add", this.#handleColorTipControl);
|
|
13207
|
+
tip.addEventListener("remove", this.#handleColorTipControl);
|
|
13026
13208
|
this.appendChild(tip);
|
|
13027
13209
|
this.#colorTip = tip;
|
|
13028
13210
|
}
|
|
@@ -13031,7 +13213,8 @@ class FigHandle extends HTMLElement {
|
|
|
13031
13213
|
if (!this.#colorTip) return;
|
|
13032
13214
|
this.#colorTip.removeEventListener("input", this.#handleColorTipInput);
|
|
13033
13215
|
this.#colorTip.removeEventListener("change", this.#handleColorTipChange);
|
|
13034
|
-
this.#colorTip.removeEventListener("add", this.#
|
|
13216
|
+
this.#colorTip.removeEventListener("add", this.#handleColorTipControl);
|
|
13217
|
+
this.#colorTip.removeEventListener("remove", this.#handleColorTipControl);
|
|
13035
13218
|
this.#colorTip.remove();
|
|
13036
13219
|
this.#colorTip = null;
|
|
13037
13220
|
}
|
|
@@ -13046,10 +13229,10 @@ class FigHandle extends HTMLElement {
|
|
|
13046
13229
|
if (e.detail?.color) this.setAttribute("color", e.detail.color);
|
|
13047
13230
|
};
|
|
13048
13231
|
|
|
13049
|
-
#
|
|
13232
|
+
#handleColorTipControl = (e) => {
|
|
13050
13233
|
e.stopPropagation();
|
|
13051
13234
|
this.dispatchEvent(
|
|
13052
|
-
new CustomEvent(
|
|
13235
|
+
new CustomEvent(e.type, { bubbles: true, composed: true }),
|
|
13053
13236
|
);
|
|
13054
13237
|
};
|
|
13055
13238
|
|
package/package.json
CHANGED