@rogieking/figui3 2.22.0 → 2.22.1

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/fig.js +49 -42
  2. package/index.html +4 -2
  3. package/package.json +1 -1
package/fig.js CHANGED
@@ -1072,7 +1072,7 @@ class FigPopup extends HTMLDialogElement {
1072
1072
  constructor() {
1073
1073
  super();
1074
1074
  this.#boundReposition = this.#queueReposition.bind(this);
1075
- this.#boundScroll = this.#queueReposition.bind(this);
1075
+ this.#boundScroll = () => { if (this.open) this.#positionPopup(); };
1076
1076
  this.#boundOutsidePointerDown = this.#handleOutsidePointerDown.bind(this);
1077
1077
  this.#boundPointerDown = this.#handlePointerDown.bind(this);
1078
1078
  this.#boundPointerMove = this.#handlePointerMove.bind(this);
@@ -1265,7 +1265,7 @@ class FigPopup extends HTMLDialogElement {
1265
1265
  }
1266
1266
 
1267
1267
  window.addEventListener("resize", this.#boundReposition);
1268
- window.addEventListener("scroll", this.#boundScroll, true);
1268
+ window.addEventListener("scroll", this.#boundScroll, { capture: true, passive: true });
1269
1269
  }
1270
1270
 
1271
1271
  #teardownObservers() {
@@ -1282,7 +1282,7 @@ class FigPopup extends HTMLDialogElement {
1282
1282
  this.#mutationObserver = null;
1283
1283
  }
1284
1284
  window.removeEventListener("resize", this.#boundReposition);
1285
- window.removeEventListener("scroll", this.#boundScroll, true);
1285
+ window.removeEventListener("scroll", this.#boundScroll, { capture: true, passive: true });
1286
1286
  }
1287
1287
 
1288
1288
  #handleOutsidePointerDown(event) {
@@ -1542,9 +1542,8 @@ class FigPopup extends HTMLDialogElement {
1542
1542
  const opp = { top: "bottom", bottom: "top", left: "right", right: "left", center: "center" };
1543
1543
 
1544
1544
  if (shorthand) {
1545
- const perp = (shorthand === "left" || shorthand === "right")
1546
- ? ["top", "bottom"]
1547
- : ["left", "right"];
1545
+ const isHorizontal = shorthand === "left" || shorthand === "right";
1546
+ const perp = isHorizontal ? ["top", "bottom"] : ["left", "right"];
1548
1547
  return [
1549
1548
  { v: vertical, h: horizontal, s: shorthand },
1550
1549
  { v: vertical, h: horizontal, s: opp[shorthand] },
@@ -1587,32 +1586,19 @@ class FigPopup extends HTMLDialogElement {
1587
1586
  let top;
1588
1587
  let left;
1589
1588
 
1590
- // Shorthand support:
1591
- // position="right" => top edges aligned, popup sits to the right of anchor.
1592
- // position="left" => top edges aligned, popup sits to the left of anchor.
1593
- if (shorthand === "right") {
1594
- return {
1595
- top: anchorRect.top,
1596
- left: anchorRect.right + offset.xPx,
1597
- };
1598
- }
1599
- if (shorthand === "left") {
1600
- return {
1601
- top: anchorRect.top,
1602
- left: anchorRect.left - popupRect.width - offset.xPx,
1603
- };
1589
+ if (shorthand === "left" || shorthand === "right") {
1590
+ left = shorthand === "left"
1591
+ ? anchorRect.left - popupRect.width - offset.xPx
1592
+ : anchorRect.right + offset.xPx;
1593
+ top = anchorRect.top;
1594
+ return { top, left };
1604
1595
  }
1605
- if (shorthand === "top") {
1606
- return {
1607
- top: anchorRect.top - popupRect.height - offset.yPx,
1608
- left: anchorRect.left,
1609
- };
1610
- }
1611
- if (shorthand === "bottom") {
1612
- return {
1613
- top: anchorRect.bottom + offset.yPx,
1614
- left: anchorRect.left,
1615
- };
1596
+ if (shorthand === "top" || shorthand === "bottom") {
1597
+ top = shorthand === "top"
1598
+ ? anchorRect.top - popupRect.height - offset.yPx
1599
+ : anchorRect.bottom + offset.yPx;
1600
+ left = anchorRect.left;
1601
+ return { top, left };
1616
1602
  }
1617
1603
 
1618
1604
  if (vertical === "top") {
@@ -1757,17 +1743,38 @@ class FigPopup extends HTMLDialogElement {
1757
1743
  for (const { v, h, s } of candidates) {
1758
1744
  const coords = this.#computeCoords(anchorRect, popupRect, v, h, offset, s);
1759
1745
  const placementSide = this.#getPlacementSide(v, h, s);
1760
- if (this.#fits(coords, popupRect)) {
1761
- this.style.left = `${coords.left}px`;
1762
- this.style.top = `${coords.top}px`;
1763
- this.#updatePopoverBeak(anchorRect, popupRect, coords.left, coords.top, placementSide);
1764
- return;
1765
- }
1766
- const score = this.#overflowScore(coords, popupRect);
1767
- if (score < bestScore) {
1768
- bestScore = score;
1769
- best = coords;
1770
- bestSide = placementSide;
1746
+
1747
+ if (s) {
1748
+ // Shorthand: clamp cross-axis to viewport, check primary axis fit
1749
+ const clamped = this.#clamp(coords, popupRect);
1750
+ const primaryFits = (s === "left" || s === "right")
1751
+ ? (coords.left >= this.#viewportPadding && coords.left + popupRect.width <= window.innerWidth - this.#viewportPadding)
1752
+ : (coords.top >= this.#viewportPadding && coords.top + popupRect.height <= window.innerHeight - this.#viewportPadding);
1753
+ if (primaryFits) {
1754
+ this.style.left = `${clamped.left}px`;
1755
+ this.style.top = `${clamped.top}px`;
1756
+ this.#updatePopoverBeak(anchorRect, popupRect, clamped.left, clamped.top, placementSide);
1757
+ return;
1758
+ }
1759
+ const score = this.#overflowScore(coords, popupRect);
1760
+ if (score < bestScore) {
1761
+ bestScore = score;
1762
+ best = clamped;
1763
+ bestSide = placementSide;
1764
+ }
1765
+ } else {
1766
+ if (this.#fits(coords, popupRect)) {
1767
+ this.style.left = `${coords.left}px`;
1768
+ this.style.top = `${coords.top}px`;
1769
+ this.#updatePopoverBeak(anchorRect, popupRect, coords.left, coords.top, placementSide);
1770
+ return;
1771
+ }
1772
+ const score = this.#overflowScore(coords, popupRect);
1773
+ if (score < bestScore) {
1774
+ bestScore = score;
1775
+ best = coords;
1776
+ bestSide = placementSide;
1777
+ }
1771
1778
  }
1772
1779
  }
1773
1780
 
package/index.html CHANGED
@@ -24,7 +24,9 @@
24
24
 
25
25
  nav {
26
26
  position: fixed;
27
- width: 240px;
27
+ width: 20vw;
28
+ min-width: 128px;
29
+ max-width: 320px;
28
30
  height: 100vh;
29
31
  overflow-y: auto;
30
32
  background: var(--figma-color-bg-secondary);
@@ -105,7 +107,7 @@
105
107
  }
106
108
 
107
109
  main {
108
- margin-left: 240px;
110
+ margin-left: clamp(128px, 20vw, 320px);
109
111
  padding: 24px 32px;
110
112
  max-width: 800px;
111
113
  min-height: 100vh;
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@rogieking/figui3",
3
- "version": "2.22.0",
3
+ "version": "2.22.1",
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",