@rogieking/figui3 8.2.0 → 8.3.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/README.md +5 -4
- package/components.css +10 -9
- package/dist/components.css +1 -1
- package/dist/fig-editor.css +1 -1
- package/dist/fig-lab.js +1 -1
- package/dist/fig.css +1 -1
- package/dist/fig.js +21 -21
- package/fig-editor.css +1 -1
- package/fig-lab.js +1 -1
- package/fig.js +74 -63
- package/package.json +1 -1
package/fig-editor.css
CHANGED
|
@@ -702,7 +702,7 @@ fig-select-options,
|
|
|
702
702
|
|
|
703
703
|
}
|
|
704
704
|
|
|
705
|
-
fig-select-options > fig-separator {
|
|
705
|
+
fig-select-options > :is(fig-separator, fig-menu-separator) {
|
|
706
706
|
/* Align labels with select option text after the checkmark column. */
|
|
707
707
|
&[label]:not([label=""]) {
|
|
708
708
|
--fig-menu-inline-padding: 0 var(--spacer-2) 0 var(--spacer-5);
|
package/fig-lab.js
CHANGED
|
@@ -4267,7 +4267,7 @@ class PropskitSlider extends HTMLElement {
|
|
|
4267
4267
|
}
|
|
4268
4268
|
|
|
4269
4269
|
#pushExternalValueToSlider() {
|
|
4270
|
-
if (!this.#slider) return;
|
|
4270
|
+
if (!this.#slider || !this.hasAttribute("value")) return;
|
|
4271
4271
|
const next = this.getAttribute("value") ?? "";
|
|
4272
4272
|
if (String(this.#slider.value) !== next) {
|
|
4273
4273
|
this.#slider.value = next;
|
package/fig.js
CHANGED
|
@@ -5173,7 +5173,6 @@ figDefineElement("fig-options", FigOptions);
|
|
|
5173
5173
|
class FigSlider extends HTMLElement {
|
|
5174
5174
|
#isInteracting = false;
|
|
5175
5175
|
#pendingRegeneration = false;
|
|
5176
|
-
#showEmptyTextValue = false;
|
|
5177
5176
|
#isSyncingValueAttribute = false;
|
|
5178
5177
|
#value = "";
|
|
5179
5178
|
#a11yAttributes = [
|
|
@@ -5278,10 +5277,6 @@ class FigSlider extends HTMLElement {
|
|
|
5278
5277
|
: this.type === "delta"
|
|
5279
5278
|
? 0
|
|
5280
5279
|
: this.min;
|
|
5281
|
-
this.#showEmptyTextValue =
|
|
5282
|
-
this.type !== "range" &&
|
|
5283
|
-
(rawValue === null ||
|
|
5284
|
-
(typeof rawValue === "string" && rawValue.trim() === ""));
|
|
5285
5280
|
this.value = this.#normalizeSliderValue(rawValue);
|
|
5286
5281
|
}
|
|
5287
5282
|
|
|
@@ -5321,10 +5316,7 @@ class FigSlider extends HTMLElement {
|
|
|
5321
5316
|
this.figInputNumber.setAttribute("max", String(this.max));
|
|
5322
5317
|
this.figInputNumber.setAttribute("transform", String(this.transform));
|
|
5323
5318
|
this.figInputNumber.setAttribute("step", String(this.step));
|
|
5324
|
-
this.figInputNumber.setAttribute(
|
|
5325
|
-
"value",
|
|
5326
|
-
this.#showEmptyTextValue ? "" : String(this.value),
|
|
5327
|
-
);
|
|
5319
|
+
this.figInputNumber.setAttribute("value", String(this.value));
|
|
5328
5320
|
if (this.units) this.figInputNumber.setAttribute("units", this.units);
|
|
5329
5321
|
else this.figInputNumber.removeAttribute("units");
|
|
5330
5322
|
if (this.precision !== null) {
|
|
@@ -5411,7 +5403,7 @@ class FigSlider extends HTMLElement {
|
|
|
5411
5403
|
max="${this.max}"
|
|
5412
5404
|
transform="${this.transform}"
|
|
5413
5405
|
step="${this.step}"
|
|
5414
|
-
value="${this
|
|
5406
|
+
value="${this.value}"
|
|
5415
5407
|
${this.units ? `units="${figEscapeAttribute(this.units)}"` : ""}
|
|
5416
5408
|
${this.precision !== null ? `precision="${this.precision}"` : ""}>
|
|
5417
5409
|
</fig-input-number>`;
|
|
@@ -5487,8 +5479,6 @@ class FigSlider extends HTMLElement {
|
|
|
5487
5479
|
|
|
5488
5480
|
set value(value) {
|
|
5489
5481
|
const rawValue = value === null || value === undefined ? "" : String(value);
|
|
5490
|
-
this.#showEmptyTextValue =
|
|
5491
|
-
this.type !== "range" && rawValue.trim() === "";
|
|
5492
5482
|
const hasParsedBounds = this.min !== undefined || this.max !== undefined;
|
|
5493
5483
|
const normalized = hasParsedBounds
|
|
5494
5484
|
? String(this.#normalizeSliderValue(rawValue))
|
|
@@ -5504,10 +5494,7 @@ class FigSlider extends HTMLElement {
|
|
|
5504
5494
|
this.input.setAttribute("aria-valuenow", normalized);
|
|
5505
5495
|
}
|
|
5506
5496
|
if (this.figInputNumber) {
|
|
5507
|
-
this.figInputNumber.setAttribute(
|
|
5508
|
-
"value",
|
|
5509
|
-
this.#showEmptyTextValue ? "" : normalized,
|
|
5510
|
-
);
|
|
5497
|
+
this.figInputNumber.setAttribute("value", normalized);
|
|
5511
5498
|
}
|
|
5512
5499
|
if (this.input) this.#syncProperties();
|
|
5513
5500
|
}
|
|
@@ -5537,10 +5524,6 @@ class FigSlider extends HTMLElement {
|
|
|
5537
5524
|
#handleTextInput() {
|
|
5538
5525
|
if (this.figInputNumber) {
|
|
5539
5526
|
const rawTextValue = this.figInputNumber.value;
|
|
5540
|
-
this.#showEmptyTextValue =
|
|
5541
|
-
rawTextValue === null ||
|
|
5542
|
-
rawTextValue === undefined ||
|
|
5543
|
-
(typeof rawTextValue === "string" && rawTextValue.trim() === "");
|
|
5544
5527
|
const normalized = this.#normalizeSliderValue(rawTextValue);
|
|
5545
5528
|
this.value = normalized;
|
|
5546
5529
|
this.input.value = String(normalized);
|
|
@@ -5624,10 +5607,7 @@ class FigSlider extends HTMLElement {
|
|
|
5624
5607
|
// Update ARIA value
|
|
5625
5608
|
this.input.setAttribute("aria-valuenow", val);
|
|
5626
5609
|
if (this.figInputNumber) {
|
|
5627
|
-
this.figInputNumber.setAttribute(
|
|
5628
|
-
"value",
|
|
5629
|
-
this.#showEmptyTextValue ? "" : val,
|
|
5630
|
-
);
|
|
5610
|
+
this.figInputNumber.setAttribute("value", val);
|
|
5631
5611
|
}
|
|
5632
5612
|
}
|
|
5633
5613
|
#syncInputA11yAttributes() {
|
|
@@ -5665,7 +5645,6 @@ class FigSlider extends HTMLElement {
|
|
|
5665
5645
|
}
|
|
5666
5646
|
|
|
5667
5647
|
#handleInput() {
|
|
5668
|
-
this.#showEmptyTextValue = false;
|
|
5669
5648
|
this.#syncValue();
|
|
5670
5649
|
this.dispatchEvent(
|
|
5671
5650
|
new CustomEvent("input", { detail: this.value, bubbles: true }),
|
|
@@ -5674,7 +5653,6 @@ class FigSlider extends HTMLElement {
|
|
|
5674
5653
|
|
|
5675
5654
|
#handleChange() {
|
|
5676
5655
|
this.#isInteracting = false;
|
|
5677
|
-
this.#showEmptyTextValue = false;
|
|
5678
5656
|
this.#syncValue();
|
|
5679
5657
|
this.dispatchEvent(
|
|
5680
5658
|
new CustomEvent("change", { detail: this.value, bubbles: true }),
|
|
@@ -5690,7 +5668,6 @@ class FigSlider extends HTMLElement {
|
|
|
5690
5668
|
}
|
|
5691
5669
|
|
|
5692
5670
|
event.preventDefault();
|
|
5693
|
-
this.#showEmptyTextValue = false;
|
|
5694
5671
|
|
|
5695
5672
|
const direction =
|
|
5696
5673
|
event.key === "ArrowRight" || event.key === "ArrowUp" ? 1 : -1;
|
|
@@ -5712,10 +5689,6 @@ class FigSlider extends HTMLElement {
|
|
|
5712
5689
|
#handleTextChange() {
|
|
5713
5690
|
if (this.figInputNumber) {
|
|
5714
5691
|
const rawTextValue = this.figInputNumber.value;
|
|
5715
|
-
this.#showEmptyTextValue =
|
|
5716
|
-
rawTextValue === null ||
|
|
5717
|
-
rawTextValue === undefined ||
|
|
5718
|
-
(typeof rawTextValue === "string" && rawTextValue.trim() === "");
|
|
5719
5692
|
const normalized = this.#normalizeSliderValue(rawTextValue);
|
|
5720
5693
|
this.value = normalized;
|
|
5721
5694
|
this.input.value = String(normalized);
|
|
@@ -9868,6 +9841,30 @@ class FigInputGradient extends HTMLElement {
|
|
|
9868
9841
|
);
|
|
9869
9842
|
}
|
|
9870
9843
|
|
|
9844
|
+
#activeStopHandle() {
|
|
9845
|
+
if (!this.#track) return null;
|
|
9846
|
+
const selected = this.#track.querySelector(
|
|
9847
|
+
"fig-handle[selected]:not(.fig-input-gradient-ghost)",
|
|
9848
|
+
);
|
|
9849
|
+
if (selected) return selected;
|
|
9850
|
+
const active = document.activeElement;
|
|
9851
|
+
if (!(active instanceof Element) || !this.#track.contains(active)) {
|
|
9852
|
+
return null;
|
|
9853
|
+
}
|
|
9854
|
+
return active.closest("fig-handle:not(.fig-input-gradient-ghost)");
|
|
9855
|
+
}
|
|
9856
|
+
|
|
9857
|
+
#activateStopHandle(handle) {
|
|
9858
|
+
if (!handle || !this.#track) return;
|
|
9859
|
+
this.#track
|
|
9860
|
+
.querySelectorAll("fig-handle:not(.fig-input-gradient-ghost)")
|
|
9861
|
+
.forEach((other) => {
|
|
9862
|
+
if (other !== handle) other.deselect();
|
|
9863
|
+
});
|
|
9864
|
+
handle.select();
|
|
9865
|
+
handle.focus();
|
|
9866
|
+
}
|
|
9867
|
+
|
|
9871
9868
|
#syncFocusTarget() {
|
|
9872
9869
|
const disabled =
|
|
9873
9870
|
this.hasAttribute("disabled") && this.getAttribute("disabled") !== "false";
|
|
@@ -9937,7 +9934,15 @@ class FigInputGradient extends HTMLElement {
|
|
|
9937
9934
|
|
|
9938
9935
|
#onKeyDown = (e) => {
|
|
9939
9936
|
const active = document.activeElement;
|
|
9940
|
-
|
|
9937
|
+
const activeIsInside = active instanceof Node && this.contains(active);
|
|
9938
|
+
const selectedHandle = this.#track?.querySelector(
|
|
9939
|
+
"fig-handle[selected]:not(.fig-input-gradient-ghost)",
|
|
9940
|
+
);
|
|
9941
|
+
const focusLostToBody =
|
|
9942
|
+
!active ||
|
|
9943
|
+
active === document.body ||
|
|
9944
|
+
active === document.documentElement;
|
|
9945
|
+
if (!activeIsInside && !(selectedHandle && focusLostToBody)) return;
|
|
9941
9946
|
const isTyping =
|
|
9942
9947
|
active &&
|
|
9943
9948
|
(active.tagName === "INPUT" ||
|
|
@@ -9946,9 +9951,7 @@ class FigInputGradient extends HTMLElement {
|
|
|
9946
9951
|
if (!this.#track) return;
|
|
9947
9952
|
|
|
9948
9953
|
if (e.key === "Tab" && !isTyping) {
|
|
9949
|
-
const selected = this.#
|
|
9950
|
-
"fig-handle[selected]:not(.fig-input-gradient-ghost)",
|
|
9951
|
-
);
|
|
9954
|
+
const selected = this.#activeStopHandle();
|
|
9952
9955
|
if (!selected) return;
|
|
9953
9956
|
e.preventDefault();
|
|
9954
9957
|
const handles = [
|
|
@@ -9961,14 +9964,12 @@ class FigInputGradient extends HTMLElement {
|
|
|
9961
9964
|
? (curIdx - 1 + handles.length) % handles.length
|
|
9962
9965
|
: (curIdx + 1) % handles.length;
|
|
9963
9966
|
selected.deselect();
|
|
9964
|
-
handles[next]
|
|
9967
|
+
this.#activateStopHandle(handles[next]);
|
|
9965
9968
|
return;
|
|
9966
9969
|
}
|
|
9967
9970
|
|
|
9968
9971
|
if ((e.key === "ArrowLeft" || e.key === "ArrowRight") && !isTyping) {
|
|
9969
|
-
const selected = this.#
|
|
9970
|
-
"fig-handle[selected]:not(.fig-input-gradient-ghost)",
|
|
9971
|
-
);
|
|
9972
|
+
const selected = this.#activeStopHandle();
|
|
9972
9973
|
if (!selected) return;
|
|
9973
9974
|
const idx = parseInt(selected.dataset.stopIndex, 10);
|
|
9974
9975
|
if (isNaN(idx) || !this.#gradient.stops[idx]) return;
|
|
@@ -10000,19 +10001,21 @@ class FigInputGradient extends HTMLElement {
|
|
|
10000
10001
|
if (e.key !== "Delete" && e.key !== "Backspace") return;
|
|
10001
10002
|
if (isTyping) return;
|
|
10002
10003
|
if (this.#gradient.stops.length <= 2) return;
|
|
10003
|
-
const selected = this.#
|
|
10004
|
-
"fig-handle[selected]:not(.fig-input-gradient-ghost)",
|
|
10005
|
-
);
|
|
10004
|
+
const selected = this.#activeStopHandle();
|
|
10006
10005
|
if (!selected) return;
|
|
10007
10006
|
const idx = parseInt(selected.dataset.stopIndex, 10);
|
|
10008
10007
|
if (isNaN(idx) || !this.#gradient.stops[idx]) return;
|
|
10009
10008
|
e.preventDefault();
|
|
10010
|
-
selected.removeAttribute("selected");
|
|
10011
10009
|
this.#gradient.stops.splice(idx, 1);
|
|
10012
10010
|
this.#syncHandles();
|
|
10013
10011
|
this.#syncSwatch();
|
|
10014
10012
|
this.#emitInput();
|
|
10015
10013
|
this.#emitChange();
|
|
10014
|
+
const nextIdx = Math.min(idx, this.#gradient.stops.length - 1);
|
|
10015
|
+
const next = this.#track.querySelectorAll(
|
|
10016
|
+
"fig-handle:not(.fig-input-gradient-ghost)",
|
|
10017
|
+
)[nextIdx];
|
|
10018
|
+
this.#activateStopHandle(next);
|
|
10016
10019
|
};
|
|
10017
10020
|
|
|
10018
10021
|
#onPickerKeyDown = (e) => {
|
|
@@ -10306,7 +10309,7 @@ class FigInputGradient extends HTMLElement {
|
|
|
10306
10309
|
"fig-handle:not(.fig-input-gradient-ghost)",
|
|
10307
10310
|
);
|
|
10308
10311
|
const newHandle = handles[newIndex];
|
|
10309
|
-
if (newHandle) newHandle
|
|
10312
|
+
if (newHandle) this.#activateStopHandle(newHandle);
|
|
10310
10313
|
});
|
|
10311
10314
|
};
|
|
10312
10315
|
|
|
@@ -10473,12 +10476,7 @@ class FigInputGradient extends HTMLElement {
|
|
|
10473
10476
|
);
|
|
10474
10477
|
const newHandle = handles[newIndex];
|
|
10475
10478
|
if (newHandle) {
|
|
10476
|
-
this.#
|
|
10477
|
-
.querySelectorAll("fig-handle:not(.fig-input-gradient-ghost)")
|
|
10478
|
-
.forEach((h) => {
|
|
10479
|
-
if (h !== newHandle) h.deselect();
|
|
10480
|
-
});
|
|
10481
|
-
newHandle.select();
|
|
10479
|
+
this.#activateStopHandle(newHandle);
|
|
10482
10480
|
newHandle.dispatchEvent(
|
|
10483
10481
|
new PointerEvent("pointerdown", {
|
|
10484
10482
|
bubbles: true,
|
|
@@ -17822,15 +17820,14 @@ class FigHandle extends HTMLElement {
|
|
|
17822
17820
|
this.#didDrag = false;
|
|
17823
17821
|
return;
|
|
17824
17822
|
}
|
|
17823
|
+
this.select();
|
|
17825
17824
|
if (
|
|
17826
17825
|
this.getAttribute("type") === "color" &&
|
|
17827
17826
|
this.#canOpenColorPicker &&
|
|
17828
17827
|
!this.#tipMode
|
|
17829
17828
|
) {
|
|
17830
17829
|
this.#openDirectColorPicker();
|
|
17831
|
-
return;
|
|
17832
17830
|
}
|
|
17833
|
-
this.select();
|
|
17834
17831
|
};
|
|
17835
17832
|
|
|
17836
17833
|
#handleDeselect = (e) => {
|
|
@@ -18012,6 +18009,8 @@ class FigHandle extends HTMLElement {
|
|
|
18012
18009
|
#onPointerDown(e) {
|
|
18013
18010
|
if (!this.#dragEnabled || figBooleanAttribute(this, "disabled")) return;
|
|
18014
18011
|
e.preventDefault();
|
|
18012
|
+
this.focus();
|
|
18013
|
+
this.select();
|
|
18015
18014
|
const container = this.#getContainer();
|
|
18016
18015
|
if (!container) return;
|
|
18017
18016
|
|
|
@@ -18411,17 +18410,19 @@ class FigHandle extends HTMLElement {
|
|
|
18411
18410
|
e.stopPropagation();
|
|
18412
18411
|
const detail = this.#detailFromNativeColor(e.target.value);
|
|
18413
18412
|
this.setAttribute("color", this.#colorWithOpacity(detail.color, detail.opacity));
|
|
18414
|
-
this.removeAttribute("selected");
|
|
18415
18413
|
this.dispatchEvent(
|
|
18416
18414
|
new CustomEvent("change", {
|
|
18417
18415
|
bubbles: true,
|
|
18418
18416
|
detail,
|
|
18419
18417
|
}),
|
|
18420
18418
|
);
|
|
18419
|
+
if (this.isConnected) this.focus();
|
|
18421
18420
|
};
|
|
18422
18421
|
|
|
18423
18422
|
#handleDirectColorPickerClose = () => {
|
|
18424
|
-
this.
|
|
18423
|
+
if (!this.isConnected) return;
|
|
18424
|
+
this.setAttribute("selected", "");
|
|
18425
|
+
this.focus();
|
|
18425
18426
|
};
|
|
18426
18427
|
|
|
18427
18428
|
#handleColorTipInput = (e) => {
|
|
@@ -18585,6 +18586,19 @@ class FigSeparator extends HTMLElement {
|
|
|
18585
18586
|
}
|
|
18586
18587
|
figDefineElement("fig-separator", FigSeparator);
|
|
18587
18588
|
|
|
18589
|
+
// Backwards-compatible alias. Custom element constructors cannot be registered
|
|
18590
|
+
// under multiple tag names, so the legacy tag uses an otherwise empty subclass.
|
|
18591
|
+
class FigMenuSeparator extends FigSeparator {}
|
|
18592
|
+
figDefineElement("fig-menu-separator", FigMenuSeparator);
|
|
18593
|
+
|
|
18594
|
+
const FIG_MENU_CHILD_SELECTOR =
|
|
18595
|
+
":scope > fig-menu-item, :scope > fig-separator, :scope > fig-menu-separator";
|
|
18596
|
+
const FIG_MENU_CHILD_TAGS = new Set([
|
|
18597
|
+
"FIG-MENU-ITEM",
|
|
18598
|
+
"FIG-SEPARATOR",
|
|
18599
|
+
"FIG-MENU-SEPARATOR",
|
|
18600
|
+
]);
|
|
18601
|
+
|
|
18588
18602
|
class FigMenu extends HTMLElement {
|
|
18589
18603
|
#popup = null;
|
|
18590
18604
|
#panel = null;
|
|
@@ -18661,9 +18675,7 @@ class FigMenu extends HTMLElement {
|
|
|
18661
18675
|
if (this.#popup) {
|
|
18662
18676
|
this.#popup.removeEventListener("close", this.#boundPopupClose);
|
|
18663
18677
|
const items = Array.from(
|
|
18664
|
-
this.#panel?.querySelectorAll(
|
|
18665
|
-
":scope > fig-menu-item, :scope > fig-separator",
|
|
18666
|
-
) ?? [],
|
|
18678
|
+
this.#panel?.querySelectorAll(FIG_MENU_CHILD_SELECTOR) ?? [],
|
|
18667
18679
|
);
|
|
18668
18680
|
for (const item of items) this.insertBefore(item, this.#popup);
|
|
18669
18681
|
this.#popup.remove();
|
|
@@ -18705,7 +18717,9 @@ class FigMenu extends HTMLElement {
|
|
|
18705
18717
|
#detectTrigger() {
|
|
18706
18718
|
this.#trigger =
|
|
18707
18719
|
this.querySelector("[fig-menu-trigger]") ||
|
|
18708
|
-
this.querySelector(
|
|
18720
|
+
this.querySelector(
|
|
18721
|
+
":scope > :not(fig-menu-item):not(fig-separator):not(fig-menu-separator)",
|
|
18722
|
+
);
|
|
18709
18723
|
}
|
|
18710
18724
|
|
|
18711
18725
|
#usesContextMenuTrigger() {
|
|
@@ -18744,9 +18758,7 @@ class FigMenu extends HTMLElement {
|
|
|
18744
18758
|
|
|
18745
18759
|
#moveItemsToPopup() {
|
|
18746
18760
|
if (!this.#panel) return;
|
|
18747
|
-
const items = Array.from(this.querySelectorAll(
|
|
18748
|
-
":scope > fig-menu-item, :scope > fig-separator"
|
|
18749
|
-
));
|
|
18761
|
+
const items = Array.from(this.querySelectorAll(FIG_MENU_CHILD_SELECTOR));
|
|
18750
18762
|
for (const item of items) {
|
|
18751
18763
|
this.#panel.appendChild(item);
|
|
18752
18764
|
}
|
|
@@ -18785,8 +18797,7 @@ class FigMenu extends HTMLElement {
|
|
|
18785
18797
|
for (const node of mutation.addedNodes) {
|
|
18786
18798
|
if (node.nodeType !== 1 || node === this.#popup) continue;
|
|
18787
18799
|
if (
|
|
18788
|
-
(node.tagName
|
|
18789
|
-
node.tagName === "FIG-SEPARATOR") &&
|
|
18800
|
+
FIG_MENU_CHILD_TAGS.has(node.tagName) &&
|
|
18790
18801
|
node.parentElement === this
|
|
18791
18802
|
) {
|
|
18792
18803
|
this.#panel?.appendChild(node);
|
package/package.json
CHANGED