@rogieking/figui3 8.9.46 → 8.9.47
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/.cursor/skills/figui3/components.md +1 -1
- package/README.md +1 -0
- package/dist/fig-editor.js +2 -2
- package/dist/fig.js +5 -5
- package/fig-editor.js +21 -2
- package/fig.js +85 -13
- package/package.json +1 -1
package/fig-editor.js
CHANGED
|
@@ -391,6 +391,7 @@ class FigSelectOptions extends HTMLElement {
|
|
|
391
391
|
#navStart = null;
|
|
392
392
|
#navEnd = null;
|
|
393
393
|
#resizeObserver = null;
|
|
394
|
+
#mutationObserver = null;
|
|
394
395
|
#boundSyncOverflow = this.syncOverflow.bind(this);
|
|
395
396
|
|
|
396
397
|
connectedCallback() {
|
|
@@ -402,6 +403,13 @@ class FigSelectOptions extends HTMLElement {
|
|
|
402
403
|
this.#resizeObserver?.disconnect();
|
|
403
404
|
this.#resizeObserver = new ResizeObserver(() => this.syncOverflow());
|
|
404
405
|
this.#resizeObserver.observe(this);
|
|
406
|
+
this.#mutationObserver?.disconnect();
|
|
407
|
+
this.#mutationObserver = new MutationObserver(() => {
|
|
408
|
+
if (!this.isConnected) return;
|
|
409
|
+
this.#ensureNavButtons();
|
|
410
|
+
this.syncOverflow();
|
|
411
|
+
});
|
|
412
|
+
this.#mutationObserver.observe(this, { childList: true });
|
|
405
413
|
requestAnimationFrame(() => this.syncOverflow());
|
|
406
414
|
}
|
|
407
415
|
|
|
@@ -409,6 +417,8 @@ class FigSelectOptions extends HTMLElement {
|
|
|
409
417
|
this.removeEventListener("scroll", this.#boundSyncOverflow);
|
|
410
418
|
this.#resizeObserver?.disconnect();
|
|
411
419
|
this.#resizeObserver = null;
|
|
420
|
+
this.#mutationObserver?.disconnect();
|
|
421
|
+
this.#mutationObserver = null;
|
|
412
422
|
this.#removeNavButtons();
|
|
413
423
|
}
|
|
414
424
|
|
|
@@ -446,6 +456,7 @@ class FigSelectOptions extends HTMLElement {
|
|
|
446
456
|
this.contains(this.#navStart) &&
|
|
447
457
|
this.contains(this.#navEnd)
|
|
448
458
|
) {
|
|
459
|
+
this.#positionNavButtons();
|
|
449
460
|
return;
|
|
450
461
|
}
|
|
451
462
|
this.#removeNavButtons();
|
|
@@ -458,8 +469,16 @@ class FigSelectOptions extends HTMLElement {
|
|
|
458
469
|
});
|
|
459
470
|
this.#navStart = buttons.start;
|
|
460
471
|
this.#navEnd = buttons.end;
|
|
461
|
-
this
|
|
462
|
-
|
|
472
|
+
this.#positionNavButtons();
|
|
473
|
+
}
|
|
474
|
+
|
|
475
|
+
#positionNavButtons() {
|
|
476
|
+
if (this.firstElementChild !== this.#navStart) {
|
|
477
|
+
this.prepend(this.#navStart);
|
|
478
|
+
}
|
|
479
|
+
if (this.lastElementChild !== this.#navEnd) {
|
|
480
|
+
this.append(this.#navEnd);
|
|
481
|
+
}
|
|
463
482
|
}
|
|
464
483
|
|
|
465
484
|
#removeNavButtons() {
|
package/fig.js
CHANGED
|
@@ -4522,6 +4522,7 @@ class FigTabs extends HTMLElement {
|
|
|
4522
4522
|
this.contains(this.#navStart) &&
|
|
4523
4523
|
this.contains(this.#navEnd)
|
|
4524
4524
|
) {
|
|
4525
|
+
this.#positionNavButtons();
|
|
4525
4526
|
return;
|
|
4526
4527
|
}
|
|
4527
4528
|
|
|
@@ -4535,8 +4536,16 @@ class FigTabs extends HTMLElement {
|
|
|
4535
4536
|
});
|
|
4536
4537
|
this.#navStart = buttons.start;
|
|
4537
4538
|
this.#navEnd = buttons.end;
|
|
4538
|
-
this
|
|
4539
|
-
|
|
4539
|
+
this.#positionNavButtons();
|
|
4540
|
+
}
|
|
4541
|
+
|
|
4542
|
+
#positionNavButtons() {
|
|
4543
|
+
if (this.firstElementChild !== this.#navStart) {
|
|
4544
|
+
this.prepend(this.#navStart);
|
|
4545
|
+
}
|
|
4546
|
+
if (this.lastElementChild !== this.#navEnd) {
|
|
4547
|
+
this.append(this.#navEnd);
|
|
4548
|
+
}
|
|
4540
4549
|
}
|
|
4541
4550
|
|
|
4542
4551
|
#handleKeyDown(event) {
|
|
@@ -18261,6 +18270,7 @@ class FigChooser extends HTMLElement {
|
|
|
18261
18270
|
this.contains(this.#navStart) &&
|
|
18262
18271
|
this.contains(this.#navEnd)
|
|
18263
18272
|
) {
|
|
18273
|
+
this.#positionNavButtons();
|
|
18264
18274
|
return;
|
|
18265
18275
|
}
|
|
18266
18276
|
|
|
@@ -18279,9 +18289,16 @@ class FigChooser extends HTMLElement {
|
|
|
18279
18289
|
});
|
|
18280
18290
|
this.#navStart = buttons.start;
|
|
18281
18291
|
this.#navEnd = buttons.end;
|
|
18292
|
+
this.#positionNavButtons();
|
|
18293
|
+
}
|
|
18282
18294
|
|
|
18283
|
-
|
|
18284
|
-
this.
|
|
18295
|
+
#positionNavButtons() {
|
|
18296
|
+
if (this.firstElementChild !== this.#navStart) {
|
|
18297
|
+
this.prepend(this.#navStart);
|
|
18298
|
+
}
|
|
18299
|
+
if (this.lastElementChild !== this.#navEnd) {
|
|
18300
|
+
this.append(this.#navEnd);
|
|
18301
|
+
}
|
|
18285
18302
|
}
|
|
18286
18303
|
|
|
18287
18304
|
#scrollByPage(direction) {
|
|
@@ -18403,6 +18420,10 @@ class FigChooser extends HTMLElement {
|
|
|
18403
18420
|
figDefineElement("fig-chooser", FigChooser);
|
|
18404
18421
|
|
|
18405
18422
|
/* Handle */
|
|
18423
|
+
/**
|
|
18424
|
+
* A draggable handle positioned within a drag surface.
|
|
18425
|
+
* @attr {number} precision - Decimal places for position values and pixel dragging (default 2).
|
|
18426
|
+
*/
|
|
18406
18427
|
class FigHandle extends HTMLElement {
|
|
18407
18428
|
static observedAttributes = [
|
|
18408
18429
|
"color",
|
|
@@ -18413,6 +18434,7 @@ class FigHandle extends HTMLElement {
|
|
|
18413
18434
|
"drag-axes",
|
|
18414
18435
|
"drag-snapping",
|
|
18415
18436
|
"value",
|
|
18437
|
+
"precision",
|
|
18416
18438
|
"type",
|
|
18417
18439
|
"tip",
|
|
18418
18440
|
"hit-area",
|
|
@@ -18495,13 +18517,37 @@ class FigHandle extends HTMLElement {
|
|
|
18495
18517
|
const container = this.#getContainer();
|
|
18496
18518
|
if (!container) return "0% 0%";
|
|
18497
18519
|
const { px, py } = this.#positionDetail(container.getBoundingClientRect());
|
|
18498
|
-
return `${
|
|
18520
|
+
return `${(px * 100).toFixed(this.precision)}% ${(py * 100).toFixed(this.precision)}%`;
|
|
18499
18521
|
}
|
|
18500
18522
|
|
|
18501
18523
|
set value(v) {
|
|
18502
18524
|
this.setAttribute("value", v ?? "0% 0%");
|
|
18503
18525
|
}
|
|
18504
18526
|
|
|
18527
|
+
get precision() {
|
|
18528
|
+
const parsed = Number(this.getAttribute("precision") ?? 2);
|
|
18529
|
+
if (!Number.isFinite(parsed)) return 2;
|
|
18530
|
+
return Math.max(0, Math.min(10, Math.trunc(parsed)));
|
|
18531
|
+
}
|
|
18532
|
+
|
|
18533
|
+
set precision(value) {
|
|
18534
|
+
if (value === null || value === undefined || value === "") {
|
|
18535
|
+
this.removeAttribute("precision");
|
|
18536
|
+
} else {
|
|
18537
|
+
const parsed = Number(value);
|
|
18538
|
+
const precision = Number.isFinite(parsed)
|
|
18539
|
+
? Math.max(0, Math.min(10, Math.trunc(parsed)))
|
|
18540
|
+
: 2;
|
|
18541
|
+
this.setAttribute("precision", String(precision));
|
|
18542
|
+
}
|
|
18543
|
+
}
|
|
18544
|
+
|
|
18545
|
+
#roundCoordinate(value) {
|
|
18546
|
+
const factor = 10 ** this.precision;
|
|
18547
|
+
const rounded = Math.round(value * factor) / factor;
|
|
18548
|
+
return Object.is(rounded, -0) ? 0 : rounded;
|
|
18549
|
+
}
|
|
18550
|
+
|
|
18505
18551
|
#parseValue(str) {
|
|
18506
18552
|
const normalized = str == null ? "" : String(str).trim();
|
|
18507
18553
|
if (!normalized) return { xPct: 0, yPct: 0 };
|
|
@@ -18541,7 +18587,7 @@ class FigHandle extends HTMLElement {
|
|
|
18541
18587
|
|
|
18542
18588
|
const resolveResponsive = (token) => {
|
|
18543
18589
|
const pct = typeof token === "number" ? token : 0;
|
|
18544
|
-
return `${pct}%`;
|
|
18590
|
+
return `${this.#roundCoordinate(pct)}%`;
|
|
18545
18591
|
};
|
|
18546
18592
|
|
|
18547
18593
|
const axes = this.#axes;
|
|
@@ -18549,12 +18595,16 @@ class FigHandle extends HTMLElement {
|
|
|
18549
18595
|
if (axes.x) {
|
|
18550
18596
|
const xPx = resolvePx(xToken, rect.width);
|
|
18551
18597
|
this.style.left =
|
|
18552
|
-
xPx === null
|
|
18598
|
+
xPx === null
|
|
18599
|
+
? resolveResponsive(xToken)
|
|
18600
|
+
: `${this.#roundCoordinate(xPx)}px`;
|
|
18553
18601
|
}
|
|
18554
18602
|
if (axes.y) {
|
|
18555
18603
|
const yPx = resolvePx(yToken, rect.height);
|
|
18556
18604
|
this.style.top =
|
|
18557
|
-
yPx === null
|
|
18605
|
+
yPx === null
|
|
18606
|
+
? resolveResponsive(yToken)
|
|
18607
|
+
: `${this.#roundCoordinate(yPx)}px`;
|
|
18558
18608
|
}
|
|
18559
18609
|
}
|
|
18560
18610
|
|
|
@@ -18783,8 +18833,12 @@ class FigHandle extends HTMLElement {
|
|
|
18783
18833
|
px = Math.max(0, Math.min(1, px));
|
|
18784
18834
|
py = Math.max(0, Math.min(1, py));
|
|
18785
18835
|
this.#syncPositionTranslate(axes);
|
|
18786
|
-
if (axes.x)
|
|
18787
|
-
|
|
18836
|
+
if (axes.x) {
|
|
18837
|
+
this.style.left = `${this.#roundCoordinate(px * rect.width)}px`;
|
|
18838
|
+
}
|
|
18839
|
+
if (axes.y) {
|
|
18840
|
+
this.style.top = `${this.#roundCoordinate(py * rect.height)}px`;
|
|
18841
|
+
}
|
|
18788
18842
|
this.#syncValueAttribute();
|
|
18789
18843
|
const detail = {
|
|
18790
18844
|
...this.#positionDetail(rect),
|
|
@@ -18824,6 +18878,15 @@ class FigHandle extends HTMLElement {
|
|
|
18824
18878
|
if (name === "value" && !this.#applyingValue && !this.#isDragging) {
|
|
18825
18879
|
this.#applyValue(value);
|
|
18826
18880
|
}
|
|
18881
|
+
if (
|
|
18882
|
+
name === "precision" &&
|
|
18883
|
+
this.isConnected &&
|
|
18884
|
+
!this.#isDragging &&
|
|
18885
|
+
this.hasAttribute("value")
|
|
18886
|
+
) {
|
|
18887
|
+
this.#applyValue(this.getAttribute("value"));
|
|
18888
|
+
this.#syncValueAttribute();
|
|
18889
|
+
}
|
|
18827
18890
|
if (name === "tip") {
|
|
18828
18891
|
this.#hideColorTip();
|
|
18829
18892
|
if (this.#tipMode) {
|
|
@@ -18926,10 +18989,14 @@ class FigHandle extends HTMLElement {
|
|
|
18926
18989
|
|
|
18927
18990
|
this.#syncPositionTranslate(axes);
|
|
18928
18991
|
if (axes.x) {
|
|
18929
|
-
this.style.left = `${
|
|
18992
|
+
this.style.left = `${this.#roundCoordinate(
|
|
18993
|
+
Math.max(0, Math.min(rect.width, centerX * rect.width)),
|
|
18994
|
+
)}px`;
|
|
18930
18995
|
}
|
|
18931
18996
|
if (axes.y) {
|
|
18932
|
-
this.style.top = `${
|
|
18997
|
+
this.style.top = `${this.#roundCoordinate(
|
|
18998
|
+
Math.max(0, Math.min(rect.height, centerY * rect.height)),
|
|
18999
|
+
)}px`;
|
|
18933
19000
|
}
|
|
18934
19001
|
};
|
|
18935
19002
|
|
|
@@ -19360,7 +19427,12 @@ class FigHandle extends HTMLElement {
|
|
|
19360
19427
|
const centerY = y + hh;
|
|
19361
19428
|
const px = rect.width > 0 ? centerX / rect.width : 0;
|
|
19362
19429
|
const py = rect.height > 0 ? centerY / rect.height : 0;
|
|
19363
|
-
return {
|
|
19430
|
+
return {
|
|
19431
|
+
x: this.#roundCoordinate(x),
|
|
19432
|
+
y: this.#roundCoordinate(y),
|
|
19433
|
+
px,
|
|
19434
|
+
py,
|
|
19435
|
+
};
|
|
19364
19436
|
}
|
|
19365
19437
|
}
|
|
19366
19438
|
figDefineElement("fig-handle", FigHandle);
|
package/package.json
CHANGED