@rogieking/figui3 2.34.0 → 2.36.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.
Files changed (3) hide show
  1. package/components.css +9 -1
  2. package/fig.js +77 -6
  3. package/package.json +1 -1
package/components.css CHANGED
@@ -1440,6 +1440,8 @@ fig-3d-rotate {
1440
1440
  width: 100%;
1441
1441
  --aspect-ratio: 1 / 1;
1442
1442
  --perspective: 20rem;
1443
+ --perspective-origin: 50% 50%;
1444
+ --transform-origin: 50% 50% -50cqi;
1443
1445
  --gradient-start-color: light-dark(
1444
1446
  rgba(0, 0, 0, 0.05),
1445
1447
  rgba(255, 255, 255, 0.05)
@@ -1493,6 +1495,7 @@ fig-3d-rotate {
1493
1495
  max-height: max(3.5rem, 50%);
1494
1496
  max-width: max(3.5rem, 50%);
1495
1497
  perspective: var(--perspective, 20rem);
1498
+ perspective-origin: var(--perspective-origin, 50% 50%);
1496
1499
  container-type: inline-size;
1497
1500
  }
1498
1501
 
@@ -1502,7 +1505,7 @@ fig-3d-rotate {
1502
1505
  position: relative;
1503
1506
  aspect-ratio: 1 / 1;
1504
1507
  transform-style: preserve-3d;
1505
- transform-origin: 50% 50% -50cqi;
1508
+ transform-origin: var(--transform-origin, 50% 50% -50cqi);
1506
1509
  }
1507
1510
 
1508
1511
  .fig-3d-rotate-face {
@@ -1514,6 +1517,11 @@ fig-3d-rotate {
1514
1517
  var(--gradient-start-color),
1515
1518
  var(--gradient-end-color)
1516
1519
  );
1520
+ &.selected {
1521
+ background: var(--figma-color-border-strong) !important;
1522
+ inset: -1px;
1523
+ border-radius: var(--radius-medium);
1524
+ }
1517
1525
 
1518
1526
  &.front {
1519
1527
  background: var(--front-face-bg);
package/fig.js CHANGED
@@ -6462,17 +6462,21 @@ class Fig3DRotate extends HTMLElement {
6462
6462
  #fieldInputs = {};
6463
6463
 
6464
6464
  static get observedAttributes() {
6465
- return ["value", "precision", "aspect-ratio", "fields", "perspective"];
6465
+ return ["value", "precision", "aspect-ratio", "fields", "perspective", "perspective-origin", "transform-origin", "selected", "drag"];
6466
6466
  }
6467
6467
 
6468
6468
  connectedCallback() {
6469
6469
  this.#precision = parseInt(this.getAttribute("precision") || "1");
6470
6470
  this.#syncAspectRatioVar(this.getAttribute("aspect-ratio"));
6471
6471
  this.#syncPerspectiveVar(this.getAttribute("perspective"));
6472
+ this.#syncCSSVar("--perspective-origin", this.getAttribute("perspective-origin"));
6473
+ this.#syncTransformOrigin(this.getAttribute("transform-origin"));
6472
6474
  this.#parseFields(this.getAttribute("fields"));
6473
6475
  const val = this.getAttribute("value");
6474
6476
  if (val) this.#parseValue(val);
6475
6477
  this.#render();
6478
+ this.#syncSelected(this.getAttribute("selected"));
6479
+ this.#syncDragState();
6476
6480
  }
6477
6481
 
6478
6482
  disconnectedCallback() {
@@ -6499,6 +6503,41 @@ class Fig3DRotate extends HTMLElement {
6499
6503
  }
6500
6504
  }
6501
6505
 
6506
+ #syncCSSVar(prop, value) {
6507
+ if (value && value.trim()) {
6508
+ this.style.setProperty(prop, value.trim());
6509
+ } else {
6510
+ this.style.removeProperty(prop);
6511
+ }
6512
+ }
6513
+
6514
+ #syncTransformOrigin(value) {
6515
+ if (!value || !value.trim()) {
6516
+ this.style.removeProperty("--transform-origin");
6517
+ return;
6518
+ }
6519
+ const parts = value.trim().split(/\s+/);
6520
+ if (parts.length === 2) {
6521
+ this.style.setProperty("--transform-origin", `${parts[0]} ${parts[1]} -50cqi`);
6522
+ } else {
6523
+ this.style.setProperty("--transform-origin", value.trim());
6524
+ }
6525
+ }
6526
+
6527
+ #syncDragState() {
6528
+ if (!this.#container) return;
6529
+ this.#container.style.cursor = this.#dragEnabled ? "" : "default";
6530
+ }
6531
+
6532
+ #syncSelected(value) {
6533
+ if (!this.#cube) return;
6534
+ const faces = this.#cube.querySelectorAll(".fig-3d-rotate-face");
6535
+ const name = value ? value.trim().toLowerCase() : "";
6536
+ for (const face of faces) {
6537
+ face.classList.toggle("selected", name !== "" && face.classList.contains(name));
6538
+ }
6539
+ }
6540
+
6502
6541
  #parseFields(str) {
6503
6542
  if (!str || !str.trim()) {
6504
6543
  this.#fields = [];
@@ -6520,6 +6559,22 @@ class Fig3DRotate extends HTMLElement {
6520
6559
  this.#syncPerspectiveVar(newValue);
6521
6560
  return;
6522
6561
  }
6562
+ if (name === "perspective-origin") {
6563
+ this.#syncCSSVar("--perspective-origin", newValue);
6564
+ return;
6565
+ }
6566
+ if (name === "transform-origin") {
6567
+ this.#syncTransformOrigin(newValue);
6568
+ return;
6569
+ }
6570
+ if (name === "selected") {
6571
+ this.#syncSelected(newValue);
6572
+ return;
6573
+ }
6574
+ if (name === "drag") {
6575
+ this.#syncDragState();
6576
+ return;
6577
+ }
6523
6578
  if (name === "fields") {
6524
6579
  this.#parseFields(newValue);
6525
6580
  if (this.#cube) this.#render();
@@ -6664,10 +6719,17 @@ class Fig3DRotate extends HTMLElement {
6664
6719
  window.addEventListener("keyup", this.#boundKeyUp);
6665
6720
  }
6666
6721
 
6722
+ get #dragEnabled() {
6723
+ const attr = this.getAttribute("drag");
6724
+ return attr === null || attr.toLowerCase() !== "false";
6725
+ }
6726
+
6667
6727
  #startDrag(e) {
6728
+ if (!this.#dragEnabled) return;
6668
6729
  e.preventDefault();
6669
6730
  this.#isDragging = true;
6670
6731
  this.#container.classList.add("dragging");
6732
+ this.#container.setPointerCapture(e.pointerId);
6671
6733
 
6672
6734
  const startX = e.clientX;
6673
6735
  const startY = e.clientY;
@@ -6676,6 +6738,10 @@ class Fig3DRotate extends HTMLElement {
6676
6738
 
6677
6739
  const onMove = (e) => {
6678
6740
  if (!this.#isDragging) return;
6741
+ if (e.buttons === 0) {
6742
+ onEnd();
6743
+ return;
6744
+ }
6679
6745
  const dx = e.clientX - startX;
6680
6746
  const dy = e.clientY - startY;
6681
6747
  this.#ry = this.#snapToIncrement(startRy + dx * 0.5);
@@ -6686,17 +6752,22 @@ class Fig3DRotate extends HTMLElement {
6686
6752
  this.#emit("input");
6687
6753
  };
6688
6754
 
6689
- const onUp = () => {
6755
+ const onEnd = () => {
6756
+ if (!this.#isDragging) return;
6690
6757
  this.setAttribute("value", this.value);
6691
6758
  this.#isDragging = false;
6692
6759
  this.#container.classList.remove("dragging");
6693
- document.removeEventListener("pointermove", onMove);
6694
- document.removeEventListener("pointerup", onUp);
6760
+ this.#container.removeEventListener("pointermove", onMove);
6761
+ this.#container.removeEventListener("pointerup", onEnd);
6762
+ this.#container.removeEventListener("pointercancel", onEnd);
6763
+ this.#container.removeEventListener("lostpointercapture", onEnd);
6695
6764
  this.#emit("change");
6696
6765
  };
6697
6766
 
6698
- document.addEventListener("pointermove", onMove);
6699
- document.addEventListener("pointerup", onUp);
6767
+ this.#container.addEventListener("pointermove", onMove);
6768
+ this.#container.addEventListener("pointerup", onEnd);
6769
+ this.#container.addEventListener("pointercancel", onEnd);
6770
+ this.#container.addEventListener("lostpointercapture", onEnd);
6700
6771
  }
6701
6772
  }
6702
6773
  customElements.define("fig-3d-rotate", Fig3DRotate);
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@rogieking/figui3",
3
- "version": "2.34.0",
3
+ "version": "2.36.0",
4
4
  "description": "A lightweight web components library for building Figma plugin and widget UIs with native look and feel",
5
5
  "author": "Rogie King",
6
6
  "license": "MIT",