@rogieking/figui3 3.4.2 → 3.5.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 +22 -4
- package/fig.js +165 -81
- package/package.json +1 -1
package/components.css
CHANGED
|
@@ -1229,7 +1229,9 @@ fig-chit {
|
|
|
1229
1229
|
|
|
1230
1230
|
/* Large gradient/image: also fill the area */
|
|
1231
1231
|
&[data-type="gradient"]::after,
|
|
1232
|
-
&[data-type="image"]::after
|
|
1232
|
+
&[data-type="image"]::after,
|
|
1233
|
+
&[data-type="gradient"]::before,
|
|
1234
|
+
&[data-type="image"]::before {
|
|
1233
1235
|
width: var(--size);
|
|
1234
1236
|
height: var(--size);
|
|
1235
1237
|
border-radius: var(--radius-medium);
|
|
@@ -1241,6 +1243,20 @@ fig-chit {
|
|
|
1241
1243
|
opacity: 0.5;
|
|
1242
1244
|
}
|
|
1243
1245
|
|
|
1246
|
+
&::before {
|
|
1247
|
+
content: "";
|
|
1248
|
+
width: 0.875rem;
|
|
1249
|
+
height: 0.875rem;
|
|
1250
|
+
border-radius: 0.125rem;
|
|
1251
|
+
grid-area: 1/1;
|
|
1252
|
+
place-self: center;
|
|
1253
|
+
}
|
|
1254
|
+
&[size="large"]::before {
|
|
1255
|
+
width: var(--size);
|
|
1256
|
+
height: var(--size);
|
|
1257
|
+
border-radius: var(--radius-medium);
|
|
1258
|
+
}
|
|
1259
|
+
|
|
1244
1260
|
/* Gradient/Image types - inset thumbnail with hidden input */
|
|
1245
1261
|
&[data-type="gradient"],
|
|
1246
1262
|
&[data-type="image"] {
|
|
@@ -1250,6 +1266,7 @@ fig-chit {
|
|
|
1250
1266
|
content: "";
|
|
1251
1267
|
width: 0.875rem;
|
|
1252
1268
|
height: 0.875rem;
|
|
1269
|
+
|
|
1253
1270
|
background: var(--chit-background);
|
|
1254
1271
|
background-size: var(--chit-bg-size);
|
|
1255
1272
|
background-position: var(--chit-bg-position);
|
|
@@ -1288,9 +1305,10 @@ fig-chit {
|
|
|
1288
1305
|
}
|
|
1289
1306
|
|
|
1290
1307
|
/* Checkerboard for empty/missing images */
|
|
1291
|
-
&[data-type="image"]:not([background])::
|
|
1292
|
-
&[data-type="image"][background=""]::
|
|
1293
|
-
&[data-type="image"][background="url()"]::
|
|
1308
|
+
&[data-type="image"]:not([background])::before,
|
|
1309
|
+
&[data-type="image"][background=""]::before,
|
|
1310
|
+
&[data-type="image"][background="url()"]::before,
|
|
1311
|
+
&[checkerboard]:not([checkerboard="false"])::before {
|
|
1294
1312
|
background: var(--checkerboard);
|
|
1295
1313
|
}
|
|
1296
1314
|
}
|
package/fig.js
CHANGED
|
@@ -9,7 +9,7 @@ function figIsWebKitOrIOSBrowser() {
|
|
|
9
9
|
const userAgent = navigator.userAgent || "";
|
|
10
10
|
const isIOSBrowser =
|
|
11
11
|
/\b(iPad|iPhone|iPod)\b/.test(userAgent) ||
|
|
12
|
-
/\bMacintosh\b/.test(userAgent) && /\bMobile\b/.test(userAgent);
|
|
12
|
+
(/\bMacintosh\b/.test(userAgent) && /\bMobile\b/.test(userAgent));
|
|
13
13
|
const isDesktopWebKit =
|
|
14
14
|
/\bAppleWebKit\b/.test(userAgent) &&
|
|
15
15
|
!/\b(Chrome|Chromium|Edg|OPR|SamsungBrowser)\b/.test(userAgent);
|
|
@@ -41,9 +41,10 @@ function figSupportsCustomizedBuiltIns() {
|
|
|
41
41
|
|
|
42
42
|
const figNeedsBuiltInPolyfill =
|
|
43
43
|
figIsWebKitOrIOSBrowser() && !figSupportsCustomizedBuiltIns();
|
|
44
|
-
const figBuiltInPolyfillReady = (
|
|
45
|
-
|
|
46
|
-
|
|
44
|
+
const figBuiltInPolyfillReady = (
|
|
45
|
+
figNeedsBuiltInPolyfill
|
|
46
|
+
? import("./polyfills/custom-elements-webkit.js")
|
|
47
|
+
: Promise.resolve()
|
|
47
48
|
)
|
|
48
49
|
.then(() => {})
|
|
49
50
|
.catch((error) => {
|
|
@@ -62,14 +63,12 @@ function figDefineCustomizedBuiltIn(name, constructor, options) {
|
|
|
62
63
|
return;
|
|
63
64
|
}
|
|
64
65
|
|
|
65
|
-
figBuiltInPolyfillReady
|
|
66
|
-
.
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
);
|
|
72
|
-
});
|
|
66
|
+
figBuiltInPolyfillReady.then(define).catch((error) => {
|
|
67
|
+
console.error(
|
|
68
|
+
`[figui3] Failed to load customized built-in polyfill for "${name}".`,
|
|
69
|
+
error,
|
|
70
|
+
);
|
|
71
|
+
});
|
|
73
72
|
}
|
|
74
73
|
|
|
75
74
|
function figUniqueId() {
|
|
@@ -1208,18 +1207,25 @@ class FigPopup extends HTMLDialogElement {
|
|
|
1208
1207
|
}
|
|
1209
1208
|
|
|
1210
1209
|
ensureInitialized() {
|
|
1211
|
-
if (typeof this._anchorObserver === "undefined")
|
|
1212
|
-
|
|
1213
|
-
if (typeof this.
|
|
1214
|
-
|
|
1215
|
-
if (typeof this.
|
|
1210
|
+
if (typeof this._anchorObserver === "undefined")
|
|
1211
|
+
this._anchorObserver = null;
|
|
1212
|
+
if (typeof this._contentObserver === "undefined")
|
|
1213
|
+
this._contentObserver = null;
|
|
1214
|
+
if (typeof this._mutationObserver === "undefined")
|
|
1215
|
+
this._mutationObserver = null;
|
|
1216
|
+
if (typeof this._anchorTrackRAF === "undefined")
|
|
1217
|
+
this._anchorTrackRAF = null;
|
|
1218
|
+
if (typeof this._lastAnchorRect === "undefined")
|
|
1219
|
+
this._lastAnchorRect = null;
|
|
1216
1220
|
if (typeof this._isPopupActive === "undefined") this._isPopupActive = false;
|
|
1217
1221
|
if (typeof this._rafId === "undefined") this._rafId = null;
|
|
1218
1222
|
if (typeof this._anchorRef === "undefined") this._anchorRef = null;
|
|
1219
1223
|
if (typeof this._isDragging === "undefined") this._isDragging = false;
|
|
1220
1224
|
if (typeof this._dragPending === "undefined") this._dragPending = false;
|
|
1221
|
-
if (typeof this._dragStartPos === "undefined")
|
|
1222
|
-
|
|
1225
|
+
if (typeof this._dragStartPos === "undefined")
|
|
1226
|
+
this._dragStartPos = { x: 0, y: 0 };
|
|
1227
|
+
if (typeof this._dragOffset === "undefined")
|
|
1228
|
+
this._dragOffset = { x: 0, y: 0 };
|
|
1223
1229
|
if (typeof this._dragThreshold !== "number") this._dragThreshold = 3;
|
|
1224
1230
|
if (typeof this._wasDragged === "undefined") this._wasDragged = false;
|
|
1225
1231
|
|
|
@@ -1228,7 +1234,11 @@ class FigPopup extends HTMLDialogElement {
|
|
|
1228
1234
|
}
|
|
1229
1235
|
if (typeof this._boundScroll !== "function") {
|
|
1230
1236
|
this._boundScroll = (e) => {
|
|
1231
|
-
if (
|
|
1237
|
+
if (
|
|
1238
|
+
this.open &&
|
|
1239
|
+
!this.contains(e.target) &&
|
|
1240
|
+
this.shouldAutoReposition()
|
|
1241
|
+
) {
|
|
1232
1242
|
this.queueReposition();
|
|
1233
1243
|
}
|
|
1234
1244
|
};
|
|
@@ -1516,7 +1526,10 @@ class FigPopup extends HTMLDialogElement {
|
|
|
1516
1526
|
const anchor = this.resolveAnchor();
|
|
1517
1527
|
const nextRect = this.readRectSnapshot(anchor);
|
|
1518
1528
|
const canAutoReposition = this.shouldAutoReposition();
|
|
1519
|
-
if (
|
|
1529
|
+
if (
|
|
1530
|
+
canAutoReposition &&
|
|
1531
|
+
this.hasRectChanged(this._lastAnchorRect, nextRect)
|
|
1532
|
+
) {
|
|
1520
1533
|
this._lastAnchorRect = nextRect;
|
|
1521
1534
|
this.queueReposition();
|
|
1522
1535
|
} else if (!canAutoReposition) {
|
|
@@ -1989,7 +2002,9 @@ class FigPopup extends HTMLDialogElement {
|
|
|
1989
2002
|
const anchorCenterY = anchorRect.top + anchorRect.height / 2;
|
|
1990
2003
|
const measuredRect = this.getBoundingClientRect();
|
|
1991
2004
|
const rect =
|
|
1992
|
-
measuredRect.width > 0 && measuredRect.height > 0
|
|
2005
|
+
measuredRect.width > 0 && measuredRect.height > 0
|
|
2006
|
+
? measuredRect
|
|
2007
|
+
: popupRect;
|
|
1993
2008
|
// Always use the rendered popup rect so beak alignment matches real final placement.
|
|
1994
2009
|
const resolvedLeft = rect.left;
|
|
1995
2010
|
const resolvedTop = rect.top;
|
|
@@ -2082,14 +2097,7 @@ class FigPopup extends HTMLDialogElement {
|
|
|
2082
2097
|
let bestScore = Number.POSITIVE_INFINITY;
|
|
2083
2098
|
|
|
2084
2099
|
for (const { v, h, s } of candidates) {
|
|
2085
|
-
const coords = this.computeCoords(
|
|
2086
|
-
anchorRect,
|
|
2087
|
-
popupRect,
|
|
2088
|
-
v,
|
|
2089
|
-
h,
|
|
2090
|
-
offset,
|
|
2091
|
-
s,
|
|
2092
|
-
);
|
|
2100
|
+
const coords = this.computeCoords(anchorRect, popupRect, v, h, offset, s);
|
|
2093
2101
|
const placementSide = this.getPlacementSide(v, h, s);
|
|
2094
2102
|
|
|
2095
2103
|
if (s) {
|
|
@@ -3102,11 +3110,7 @@ class FigSlider extends HTMLElement {
|
|
|
3102
3110
|
break;
|
|
3103
3111
|
case "default":
|
|
3104
3112
|
this.default =
|
|
3105
|
-
newValue !== null
|
|
3106
|
-
? newValue
|
|
3107
|
-
: this.type === "delta"
|
|
3108
|
-
? 0
|
|
3109
|
-
: this.min;
|
|
3113
|
+
newValue !== null ? newValue : this.type === "delta" ? 0 : this.min;
|
|
3110
3114
|
this.#syncProperties();
|
|
3111
3115
|
break;
|
|
3112
3116
|
case "min":
|
|
@@ -3172,7 +3176,8 @@ class FigInputText extends HTMLElement {
|
|
|
3172
3176
|
this.placeholder = this.getAttribute("placeholder") || "";
|
|
3173
3177
|
this.name = this.getAttribute("name") || null;
|
|
3174
3178
|
this.readonly =
|
|
3175
|
-
this.hasAttribute("readonly") &&
|
|
3179
|
+
this.hasAttribute("readonly") &&
|
|
3180
|
+
this.getAttribute("readonly") !== "false";
|
|
3176
3181
|
|
|
3177
3182
|
if (this.type === "number") {
|
|
3178
3183
|
if (this.getAttribute("step")) {
|
|
@@ -5684,8 +5689,22 @@ class FigChit extends HTMLElement {
|
|
|
5684
5689
|
}
|
|
5685
5690
|
}
|
|
5686
5691
|
|
|
5692
|
+
#resolveBackground(bg) {
|
|
5693
|
+
if (!bg || !bg.includes("var(")) return bg;
|
|
5694
|
+
const prev = this.style.background;
|
|
5695
|
+
this.style.background = bg;
|
|
5696
|
+
const cs = getComputedStyle(this);
|
|
5697
|
+
const bgImage = cs.backgroundImage;
|
|
5698
|
+
const bgColor = cs.backgroundColor;
|
|
5699
|
+
this.style.background = prev;
|
|
5700
|
+
if (bgImage && bgImage !== "none") return bgImage;
|
|
5701
|
+
return bgColor || bg;
|
|
5702
|
+
}
|
|
5703
|
+
|
|
5687
5704
|
#render() {
|
|
5688
|
-
const
|
|
5705
|
+
const rawBg = this.getAttribute("background") || "#D9D9D9";
|
|
5706
|
+
const isVar = rawBg.includes("var(");
|
|
5707
|
+
const bg = isVar ? this.#resolveBackground(rawBg) : rawBg;
|
|
5689
5708
|
const newType = this.#detectType(bg);
|
|
5690
5709
|
|
|
5691
5710
|
// Only rebuild DOM if type changes
|
|
@@ -5702,21 +5721,22 @@ class FigChit extends HTMLElement {
|
|
|
5702
5721
|
const hex = this.#toHex(bg);
|
|
5703
5722
|
this.innerHTML = `<input type="color" value="${hex}" />`;
|
|
5704
5723
|
this.input = this.querySelector("input");
|
|
5705
|
-
|
|
5724
|
+
if (!isVar) {
|
|
5725
|
+
this.input.addEventListener("input", this.#boundHandleInput);
|
|
5726
|
+
}
|
|
5706
5727
|
} else {
|
|
5707
5728
|
this.innerHTML = "";
|
|
5708
5729
|
this.input = null;
|
|
5709
5730
|
}
|
|
5710
5731
|
} else if (this.#type === "color" && this.input) {
|
|
5711
|
-
// Just update input value without rebuilding DOM
|
|
5712
5732
|
const hex = this.#toHex(bg);
|
|
5713
5733
|
if (this.input.value !== hex) {
|
|
5714
5734
|
this.input.value = hex;
|
|
5715
5735
|
}
|
|
5716
5736
|
}
|
|
5717
5737
|
|
|
5718
|
-
// Always update CSS variable
|
|
5719
|
-
this.style.setProperty("--chit-background",
|
|
5738
|
+
// Always update CSS variable with raw value so vars stay reactive
|
|
5739
|
+
this.style.setProperty("--chit-background", rawBg);
|
|
5720
5740
|
}
|
|
5721
5741
|
|
|
5722
5742
|
#handleInput(e) {
|
|
@@ -5783,9 +5803,9 @@ class FigImage extends HTMLElement {
|
|
|
5783
5803
|
super();
|
|
5784
5804
|
}
|
|
5785
5805
|
#getInnerHTML() {
|
|
5786
|
-
|
|
5787
|
-
|
|
5788
|
-
}" disabled></fig-chit><div>${
|
|
5806
|
+
const cb = this.hasAttribute("checkerboard") && this.getAttribute("checkerboard") !== "false";
|
|
5807
|
+
const bg = this.src ? `url(${this.src})` : (cb ? "url()" : "var(--figma-color-bg-secondary)");
|
|
5808
|
+
return `<fig-chit size="large" data-type="image" background="${bg}" disabled${cb ? ' checkerboard' : ''}></fig-chit><div>${
|
|
5789
5809
|
this.upload
|
|
5790
5810
|
? `<fig-button variant="overlay" type="upload">
|
|
5791
5811
|
${this.label}
|
|
@@ -5946,7 +5966,7 @@ class FigImage extends HTMLElement {
|
|
|
5946
5966
|
this.setAttribute("src", this.blob);
|
|
5947
5967
|
}
|
|
5948
5968
|
static get observedAttributes() {
|
|
5949
|
-
return ["src", "upload", "download", "aspect-ratio", "fit"];
|
|
5969
|
+
return ["src", "upload", "download", "aspect-ratio", "fit", "checkerboard"];
|
|
5950
5970
|
}
|
|
5951
5971
|
get src() {
|
|
5952
5972
|
return this.#src;
|
|
@@ -5960,10 +5980,12 @@ class FigImage extends HTMLElement {
|
|
|
5960
5980
|
if (name === "src") {
|
|
5961
5981
|
this.#src = newValue;
|
|
5962
5982
|
if (this.chit) {
|
|
5963
|
-
this.
|
|
5964
|
-
|
|
5965
|
-
this
|
|
5966
|
-
|
|
5983
|
+
const hasCb = this.hasAttribute("checkerboard") && this.getAttribute("checkerboard") !== "false";
|
|
5984
|
+
if (this.#src) {
|
|
5985
|
+
this.chit.setAttribute("background", `url(${this.#src})`);
|
|
5986
|
+
} else {
|
|
5987
|
+
this.chit.setAttribute("background", hasCb ? "url()" : "var(--figma-color-bg-secondary)");
|
|
5988
|
+
}
|
|
5967
5989
|
}
|
|
5968
5990
|
if (this.#src) {
|
|
5969
5991
|
this.#loadImage(this.#src);
|
|
@@ -5996,6 +6018,15 @@ class FigImage extends HTMLElement {
|
|
|
5996
6018
|
this.style.removeProperty("--fit");
|
|
5997
6019
|
}
|
|
5998
6020
|
}
|
|
6021
|
+
if (name === "checkerboard") {
|
|
6022
|
+
if (this.chit) {
|
|
6023
|
+
if (newValue !== null && newValue !== "false") {
|
|
6024
|
+
this.chit.setAttribute("checkerboard", "");
|
|
6025
|
+
} else {
|
|
6026
|
+
this.chit.removeAttribute("checkerboard");
|
|
6027
|
+
}
|
|
6028
|
+
}
|
|
6029
|
+
}
|
|
5999
6030
|
}
|
|
6000
6031
|
}
|
|
6001
6032
|
customElements.define("fig-image", FigImage);
|
|
@@ -6714,7 +6745,9 @@ class FigEasingCurve extends HTMLElement {
|
|
|
6714
6745
|
this.#startBezierDrag(e, 2),
|
|
6715
6746
|
);
|
|
6716
6747
|
|
|
6717
|
-
const bezierSurface = this.querySelector(
|
|
6748
|
+
const bezierSurface = this.querySelector(
|
|
6749
|
+
".fig-easing-curve-svg-container",
|
|
6750
|
+
);
|
|
6718
6751
|
if (bezierSurface) {
|
|
6719
6752
|
bezierSurface.addEventListener("pointerdown", (e) => {
|
|
6720
6753
|
// Handles keep their own direct drag behavior.
|
|
@@ -6732,7 +6765,9 @@ class FigEasingCurve extends HTMLElement {
|
|
|
6732
6765
|
this.#startSpringDrag(e, "duration");
|
|
6733
6766
|
});
|
|
6734
6767
|
|
|
6735
|
-
const springSurface = this.querySelector(
|
|
6768
|
+
const springSurface = this.querySelector(
|
|
6769
|
+
".fig-easing-curve-svg-container",
|
|
6770
|
+
);
|
|
6736
6771
|
if (springSurface) {
|
|
6737
6772
|
springSurface.addEventListener("pointerdown", (e) => {
|
|
6738
6773
|
// Bounce handle keeps its own drag mode/cursor.
|
|
@@ -6902,14 +6937,27 @@ class Fig3DRotate extends HTMLElement {
|
|
|
6902
6937
|
#fieldInputs = {};
|
|
6903
6938
|
|
|
6904
6939
|
static get observedAttributes() {
|
|
6905
|
-
return [
|
|
6940
|
+
return [
|
|
6941
|
+
"value",
|
|
6942
|
+
"precision",
|
|
6943
|
+
"aspect-ratio",
|
|
6944
|
+
"fields",
|
|
6945
|
+
"perspective",
|
|
6946
|
+
"perspective-origin",
|
|
6947
|
+
"transform-origin",
|
|
6948
|
+
"selected",
|
|
6949
|
+
"drag",
|
|
6950
|
+
];
|
|
6906
6951
|
}
|
|
6907
6952
|
|
|
6908
6953
|
connectedCallback() {
|
|
6909
6954
|
this.#precision = parseInt(this.getAttribute("precision") || "1");
|
|
6910
6955
|
this.#syncAspectRatioVar(this.getAttribute("aspect-ratio"));
|
|
6911
6956
|
this.#syncPerspectiveVar(this.getAttribute("perspective"));
|
|
6912
|
-
this.#syncCSSVar(
|
|
6957
|
+
this.#syncCSSVar(
|
|
6958
|
+
"--perspective-origin",
|
|
6959
|
+
this.getAttribute("perspective-origin"),
|
|
6960
|
+
);
|
|
6913
6961
|
this.#syncTransformOrigin(this.getAttribute("transform-origin"));
|
|
6914
6962
|
this.#parseFields(this.getAttribute("fields"));
|
|
6915
6963
|
const val = this.getAttribute("value");
|
|
@@ -6958,7 +7006,10 @@ class Fig3DRotate extends HTMLElement {
|
|
|
6958
7006
|
}
|
|
6959
7007
|
const parts = value.trim().split(/\s+/);
|
|
6960
7008
|
if (parts.length === 2) {
|
|
6961
|
-
this.style.setProperty(
|
|
7009
|
+
this.style.setProperty(
|
|
7010
|
+
"--transform-origin",
|
|
7011
|
+
`${parts[0]} ${parts[1]} -50cqi`,
|
|
7012
|
+
);
|
|
6962
7013
|
} else {
|
|
6963
7014
|
this.style.setProperty("--transform-origin", value.trim());
|
|
6964
7015
|
}
|
|
@@ -6974,7 +7025,10 @@ class Fig3DRotate extends HTMLElement {
|
|
|
6974
7025
|
const faces = this.#cube.querySelectorAll(".fig-3d-rotate-face");
|
|
6975
7026
|
const name = value ? value.trim().toLowerCase() : "";
|
|
6976
7027
|
for (const face of faces) {
|
|
6977
|
-
face.classList.toggle(
|
|
7028
|
+
face.classList.toggle(
|
|
7029
|
+
"selected",
|
|
7030
|
+
name !== "" && face.classList.contains(name),
|
|
7031
|
+
);
|
|
6978
7032
|
}
|
|
6979
7033
|
}
|
|
6980
7034
|
|
|
@@ -7062,7 +7116,11 @@ class Fig3DRotate extends HTMLElement {
|
|
|
7062
7116
|
|
|
7063
7117
|
#render() {
|
|
7064
7118
|
const axisLabels = { rotateX: "X", rotateY: "Y", rotateZ: "Z" };
|
|
7065
|
-
const axisValues = {
|
|
7119
|
+
const axisValues = {
|
|
7120
|
+
rotateX: this.#rx,
|
|
7121
|
+
rotateY: this.#ry,
|
|
7122
|
+
rotateZ: this.#rz,
|
|
7123
|
+
};
|
|
7066
7124
|
const fieldsHTML = this.#fields
|
|
7067
7125
|
.map(
|
|
7068
7126
|
(axis) =>
|
|
@@ -7115,17 +7173,21 @@ class Fig3DRotate extends HTMLElement {
|
|
|
7115
7173
|
}
|
|
7116
7174
|
|
|
7117
7175
|
#syncFieldInputs() {
|
|
7118
|
-
const axisValues = {
|
|
7176
|
+
const axisValues = {
|
|
7177
|
+
rotateX: this.#rx,
|
|
7178
|
+
rotateY: this.#ry,
|
|
7179
|
+
rotateZ: this.#rz,
|
|
7180
|
+
};
|
|
7119
7181
|
for (const axis of this.#fields) {
|
|
7120
7182
|
const input = this.#fieldInputs[axis];
|
|
7121
|
-
if (input)
|
|
7183
|
+
if (input)
|
|
7184
|
+
input.setAttribute("value", axisValues[axis].toFixed(this.#precision));
|
|
7122
7185
|
}
|
|
7123
7186
|
}
|
|
7124
7187
|
|
|
7125
7188
|
#updateCube() {
|
|
7126
7189
|
if (!this.#cube) return;
|
|
7127
|
-
this.#cube.style.transform =
|
|
7128
|
-
`rotateX(${this.#rx}deg) rotateY(${this.#ry}deg) rotateZ(${this.#rz}deg)`;
|
|
7190
|
+
this.#cube.style.transform = `rotateX(${this.#rx}deg) rotateY(${this.#ry}deg) rotateZ(${this.#rz}deg)`;
|
|
7129
7191
|
}
|
|
7130
7192
|
|
|
7131
7193
|
#emit(type) {
|
|
@@ -7339,11 +7401,7 @@ class FigOriginGrid extends HTMLElement {
|
|
|
7339
7401
|
}
|
|
7340
7402
|
|
|
7341
7403
|
#parseValue(value) {
|
|
7342
|
-
const parts = value
|
|
7343
|
-
.trim()
|
|
7344
|
-
.replace(/,/g, " ")
|
|
7345
|
-
.split(/\s+/)
|
|
7346
|
-
.filter(Boolean);
|
|
7404
|
+
const parts = value.trim().replace(/,/g, " ").split(/\s+/).filter(Boolean);
|
|
7347
7405
|
if (parts.length < 1) return;
|
|
7348
7406
|
|
|
7349
7407
|
if (parts.length === 1) {
|
|
@@ -7439,7 +7497,8 @@ class FigOriginGrid extends HTMLElement {
|
|
|
7439
7497
|
#syncHandlePosition() {
|
|
7440
7498
|
if (!this.#handle) return;
|
|
7441
7499
|
// Constrain draggable visual bounds to the 3x3 dot centers.
|
|
7442
|
-
const toVisual = (value) =>
|
|
7500
|
+
const toVisual = (value) =>
|
|
7501
|
+
16.6667 + (this.#clampPercentage(value) / 100) * 66.6667;
|
|
7443
7502
|
this.#handle.style.left = `${toVisual(this.#x)}%`;
|
|
7444
7503
|
this.#handle.style.top = `${toVisual(this.#y)}%`;
|
|
7445
7504
|
}
|
|
@@ -7553,10 +7612,18 @@ class FigOriginGrid extends HTMLElement {
|
|
|
7553
7612
|
}
|
|
7554
7613
|
|
|
7555
7614
|
#detachHandleDragListeners() {
|
|
7556
|
-
if (
|
|
7615
|
+
if (
|
|
7616
|
+
!this.#grid ||
|
|
7617
|
+
!this.#boundHandlePointerMove ||
|
|
7618
|
+
!this.#boundHandlePointerEnd
|
|
7619
|
+
)
|
|
7620
|
+
return;
|
|
7557
7621
|
this.#grid.removeEventListener("pointermove", this.#boundHandlePointerMove);
|
|
7558
7622
|
this.#grid.removeEventListener("pointerup", this.#boundHandlePointerEnd);
|
|
7559
|
-
this.#grid.removeEventListener(
|
|
7623
|
+
this.#grid.removeEventListener(
|
|
7624
|
+
"pointercancel",
|
|
7625
|
+
this.#boundHandlePointerEnd,
|
|
7626
|
+
);
|
|
7560
7627
|
this.#grid.removeEventListener(
|
|
7561
7628
|
"lostpointercapture",
|
|
7562
7629
|
this.#boundHandlePointerEnd,
|
|
@@ -7577,7 +7644,8 @@ class FigOriginGrid extends HTMLElement {
|
|
|
7577
7644
|
this.#grid.setPointerCapture(e.pointerId);
|
|
7578
7645
|
|
|
7579
7646
|
this.#boundHandlePointerMove = (moveEvent) => {
|
|
7580
|
-
if (!this.#isDragging || moveEvent.pointerId !== this.#activePointerId)
|
|
7647
|
+
if (!this.#isDragging || moveEvent.pointerId !== this.#activePointerId)
|
|
7648
|
+
return;
|
|
7581
7649
|
const dx = moveEvent.clientX - startClientX;
|
|
7582
7650
|
const dy = moveEvent.clientY - startClientY;
|
|
7583
7651
|
const distance = Math.hypot(dx, dy);
|
|
@@ -7595,7 +7663,8 @@ class FigOriginGrid extends HTMLElement {
|
|
|
7595
7663
|
};
|
|
7596
7664
|
|
|
7597
7665
|
this.#boundHandlePointerEnd = (endEvent) => {
|
|
7598
|
-
if (!this.#isDragging || endEvent.pointerId !== this.#activePointerId)
|
|
7666
|
+
if (!this.#isDragging || endEvent.pointerId !== this.#activePointerId)
|
|
7667
|
+
return;
|
|
7599
7668
|
this.#isDragging = false;
|
|
7600
7669
|
this.#activePointerId = null;
|
|
7601
7670
|
this.#grid.classList.remove("is-dragging");
|
|
@@ -7612,7 +7681,10 @@ class FigOriginGrid extends HTMLElement {
|
|
|
7612
7681
|
this.#grid.addEventListener("pointermove", this.#boundHandlePointerMove);
|
|
7613
7682
|
this.#grid.addEventListener("pointerup", this.#boundHandlePointerEnd);
|
|
7614
7683
|
this.#grid.addEventListener("pointercancel", this.#boundHandlePointerEnd);
|
|
7615
|
-
this.#grid.addEventListener(
|
|
7684
|
+
this.#grid.addEventListener(
|
|
7685
|
+
"lostpointercapture",
|
|
7686
|
+
this.#boundHandlePointerEnd,
|
|
7687
|
+
);
|
|
7616
7688
|
}
|
|
7617
7689
|
|
|
7618
7690
|
#setupEvents() {
|
|
@@ -8064,7 +8136,8 @@ class FigInputJoystick extends HTMLElement {
|
|
|
8064
8136
|
const isPercent = token.includes("%");
|
|
8065
8137
|
const numeric = Number.parseFloat(token.replace(/%/g, "").trim());
|
|
8066
8138
|
if (!Number.isFinite(numeric)) return 0.5;
|
|
8067
|
-
const decimal =
|
|
8139
|
+
const decimal =
|
|
8140
|
+
isPercent || Math.abs(numeric) > 1 ? numeric / 100 : numeric;
|
|
8068
8141
|
return Math.max(0, Math.min(1, decimal));
|
|
8069
8142
|
};
|
|
8070
8143
|
const x = parseAxis(parts[0]);
|
|
@@ -10480,7 +10553,9 @@ class FigChooser extends HTMLElement {
|
|
|
10480
10553
|
}
|
|
10481
10554
|
|
|
10482
10555
|
get #overflowMode() {
|
|
10483
|
-
return this.getAttribute("overflow") === "scrollbar"
|
|
10556
|
+
return this.getAttribute("overflow") === "scrollbar"
|
|
10557
|
+
? "scrollbar"
|
|
10558
|
+
: "buttons";
|
|
10484
10559
|
}
|
|
10485
10560
|
|
|
10486
10561
|
get #dragEnabled() {
|
|
@@ -10730,12 +10805,14 @@ class FigChooser extends HTMLElement {
|
|
|
10730
10805
|
|
|
10731
10806
|
if (isHorizontal) {
|
|
10732
10807
|
const atStart = this.scrollLeft <= threshold;
|
|
10733
|
-
const atEnd =
|
|
10808
|
+
const atEnd =
|
|
10809
|
+
this.scrollLeft + this.clientWidth >= this.scrollWidth - threshold;
|
|
10734
10810
|
this.classList.toggle("overflow-start", !atStart);
|
|
10735
10811
|
this.classList.toggle("overflow-end", !atEnd);
|
|
10736
10812
|
} else {
|
|
10737
10813
|
const atStart = this.scrollTop <= threshold;
|
|
10738
|
-
const atEnd =
|
|
10814
|
+
const atEnd =
|
|
10815
|
+
this.scrollTop + this.clientHeight >= this.scrollHeight - threshold;
|
|
10739
10816
|
this.classList.toggle("overflow-start", !atStart);
|
|
10740
10817
|
this.classList.toggle("overflow-end", !atEnd);
|
|
10741
10818
|
}
|
|
@@ -10800,7 +10877,9 @@ class FigChooser extends HTMLElement {
|
|
|
10800
10877
|
this.style.cursor = "";
|
|
10801
10878
|
this.style.userSelect = "";
|
|
10802
10879
|
if (e.pointerId !== undefined) {
|
|
10803
|
-
try {
|
|
10880
|
+
try {
|
|
10881
|
+
this.releasePointerCapture(e.pointerId);
|
|
10882
|
+
} catch {}
|
|
10804
10883
|
}
|
|
10805
10884
|
if (wasDrag) {
|
|
10806
10885
|
e.preventDefault();
|
|
@@ -10853,7 +10932,11 @@ class FigChooser extends HTMLElement {
|
|
|
10853
10932
|
this.removeEventListener("pointerdown", this.#dragState.onPointerDown);
|
|
10854
10933
|
window.removeEventListener("pointermove", this.#dragState.onPointerMove);
|
|
10855
10934
|
window.removeEventListener("pointerup", this.#dragState.onPointerUp);
|
|
10856
|
-
this.removeEventListener(
|
|
10935
|
+
this.removeEventListener(
|
|
10936
|
+
"pointerup",
|
|
10937
|
+
this.#dragState.onPointerUpCapture,
|
|
10938
|
+
true,
|
|
10939
|
+
);
|
|
10857
10940
|
this.removeEventListener("click", this.#dragState.onClick, true);
|
|
10858
10941
|
this.style.cursor = "";
|
|
10859
10942
|
this.style.userSelect = "";
|
|
@@ -10904,8 +10987,7 @@ class FigChooser extends HTMLElement {
|
|
|
10904
10987
|
}
|
|
10905
10988
|
|
|
10906
10989
|
#scrollByPage(direction) {
|
|
10907
|
-
const isHorizontal =
|
|
10908
|
-
this.getAttribute("layout") === "horizontal";
|
|
10990
|
+
const isHorizontal = this.getAttribute("layout") === "horizontal";
|
|
10909
10991
|
const pageSize = isHorizontal ? this.clientWidth : this.clientHeight;
|
|
10910
10992
|
const scrollAmount = pageSize * 0.8 * direction;
|
|
10911
10993
|
|
|
@@ -10925,12 +11007,14 @@ class FigChooser extends HTMLElement {
|
|
|
10925
11007
|
const options = { behavior: "smooth" };
|
|
10926
11008
|
|
|
10927
11009
|
if (overflowY) {
|
|
10928
|
-
const target =
|
|
11010
|
+
const target =
|
|
11011
|
+
el.offsetTop - this.clientHeight / 2 + el.offsetHeight / 2;
|
|
10929
11012
|
options.top = target;
|
|
10930
11013
|
}
|
|
10931
11014
|
|
|
10932
11015
|
if (overflowX) {
|
|
10933
|
-
const target =
|
|
11016
|
+
const target =
|
|
11017
|
+
el.offsetLeft - this.clientWidth / 2 + el.offsetWidth / 2;
|
|
10934
11018
|
options.left = target;
|
|
10935
11019
|
}
|
|
10936
11020
|
|
package/package.json
CHANGED