@rogieking/figui3 9.4.9 → 9.4.11

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/fig.js CHANGED
@@ -2987,9 +2987,11 @@ class FigPopup extends HTMLDialogElement {
2987
2987
  _lastAnchorRect = null;
2988
2988
  _isPopupActive = false;
2989
2989
  _boundReposition;
2990
+ _boundContentReposition;
2990
2991
  _boundScroll;
2991
2992
  _boundOutsidePointerDown;
2992
2993
  _rafId = null;
2994
+ _pendingFullReposition = false;
2993
2995
  _anchorRef = null;
2994
2996
 
2995
2997
  _isDragging = false;
@@ -3007,7 +3009,9 @@ class FigPopup extends HTMLDialogElement {
3007
3009
 
3008
3010
  constructor() {
3009
3011
  super();
3010
- this._boundReposition = this.queueReposition.bind(this);
3012
+ this._boundReposition = () => this.queueReposition();
3013
+ this._boundContentReposition = () =>
3014
+ this.queueReposition({ preserveCurrentPosition: true });
3011
3015
  this._boundScroll = (e) => {
3012
3016
  const target = e.target;
3013
3017
  if (
@@ -3042,6 +3046,8 @@ class FigPopup extends HTMLDialogElement {
3042
3046
  this._lastAnchorRect = null;
3043
3047
  if (typeof this._isPopupActive === "undefined") this._isPopupActive = false;
3044
3048
  if (typeof this._rafId === "undefined") this._rafId = null;
3049
+ if (typeof this._pendingFullReposition === "undefined")
3050
+ this._pendingFullReposition = false;
3045
3051
  if (typeof this._anchorRef === "undefined") this._anchorRef = null;
3046
3052
  if (typeof this._isDragging === "undefined") this._isDragging = false;
3047
3053
  if (typeof this._dragPending === "undefined") this._dragPending = false;
@@ -3054,7 +3060,11 @@ class FigPopup extends HTMLDialogElement {
3054
3060
  if (typeof this._previousFocus === "undefined") this._previousFocus = null;
3055
3061
 
3056
3062
  if (typeof this._boundReposition !== "function") {
3057
- this._boundReposition = this.queueReposition.bind(this);
3063
+ this._boundReposition = () => this.queueReposition();
3064
+ }
3065
+ if (typeof this._boundContentReposition !== "function") {
3066
+ this._boundContentReposition = () =>
3067
+ this.queueReposition({ preserveCurrentPosition: true });
3058
3068
  }
3059
3069
  if (typeof this._boundScroll !== "function") {
3060
3070
  this._boundScroll = (e) => {
@@ -3416,11 +3426,15 @@ class FigPopup extends HTMLDialogElement {
3416
3426
 
3417
3427
  if (this.autoresize) {
3418
3428
  if ("ResizeObserver" in window) {
3419
- this._contentObserver = new ResizeObserver(this._boundReposition);
3429
+ this._contentObserver = new ResizeObserver(
3430
+ this._boundContentReposition,
3431
+ );
3420
3432
  this._contentObserver.observe(this);
3421
3433
  }
3422
3434
 
3423
- this._mutationObserver = new MutationObserver(this._boundReposition);
3435
+ this._mutationObserver = new MutationObserver(
3436
+ this._boundContentReposition,
3437
+ );
3424
3438
  this._mutationObserver.observe(this, {
3425
3439
  childList: true,
3426
3440
  subtree: true,
@@ -4291,14 +4305,64 @@ class FigPopup extends HTMLDialogElement {
4291
4305
  );
4292
4306
  }
4293
4307
 
4294
- positionPopup() {
4308
+ currentPlacementSide() {
4309
+ const beakSide = this.getAttribute("data-beak-side");
4310
+ if (beakSide) return this.oppositeSide(beakSide);
4311
+ const { vertical, horizontal, shorthand } = this.parsePosition();
4312
+ return this.getPlacementSide(vertical, horizontal, shorthand);
4313
+ }
4314
+
4315
+ preservePopupPosition(popupRect, anchor, m) {
4316
+ const current = {
4317
+ left: popupRect.left,
4318
+ top: popupRect.top,
4319
+ };
4320
+ const next = this.fits(current, popupRect, m)
4321
+ ? current
4322
+ : this.clampToViewport(current, popupRect, m);
4323
+ const anchorRect = anchor ? anchor.getBoundingClientRect() : null;
4324
+ const placementSide = this.currentPlacementSide();
4325
+
4326
+ if (
4327
+ anchorRect &&
4328
+ this.tracksAnchorBeak() &&
4329
+ !this.canPointAtAnchor(
4330
+ anchorRect,
4331
+ popupRect,
4332
+ next.left,
4333
+ next.top,
4334
+ placementSide,
4335
+ )
4336
+ ) {
4337
+ return false;
4338
+ }
4339
+
4340
+ this.style.left = `${next.left}px`;
4341
+ this.style.top = `${next.top}px`;
4342
+ this.updatePopoverBeak(
4343
+ anchorRect,
4344
+ popupRect,
4345
+ next.left,
4346
+ next.top,
4347
+ placementSide,
4348
+ );
4349
+ return true;
4350
+ }
4351
+
4352
+ positionPopup({ preserveCurrentPosition = false } = {}) {
4295
4353
  if (!this.open) return;
4296
4354
 
4297
4355
  const popupRect = this.getBoundingClientRect();
4298
- const offset = this.parseOffset();
4299
- const { vertical, horizontal, shorthand } = this.parsePosition();
4300
4356
  const anchor = this.resolveAnchor();
4301
4357
  const m = this.parseViewportMargins();
4358
+ if (
4359
+ preserveCurrentPosition &&
4360
+ this.preservePopupPosition(popupRect, anchor, m)
4361
+ ) {
4362
+ return;
4363
+ }
4364
+ const offset = this.parseOffset();
4365
+ const { vertical, horizontal, shorthand } = this.parsePosition();
4302
4366
 
4303
4367
  if (!anchor) {
4304
4368
  this.updatePopoverBeak(null, popupRect, 0, 0, "top");
@@ -4383,15 +4447,18 @@ class FigPopup extends HTMLDialogElement {
4383
4447
  );
4384
4448
  }
4385
4449
 
4386
- queueReposition() {
4450
+ queueReposition({ preserveCurrentPosition = false } = {}) {
4387
4451
  if (!this.open || !this.isPopupDisplayed() || !this.shouldAutoReposition()) {
4388
4452
  return;
4389
4453
  }
4454
+ if (!preserveCurrentPosition) this._pendingFullReposition = true;
4390
4455
  if (this._rafId !== null) return;
4391
4456
 
4392
4457
  this._rafId = requestAnimationFrame(() => {
4393
4458
  this._rafId = null;
4394
- this.positionPopup();
4459
+ const preservePosition = !this._pendingFullReposition;
4460
+ this._pendingFullReposition = false;
4461
+ this.positionPopup({ preserveCurrentPosition: preservePosition });
4395
4462
  });
4396
4463
  }
4397
4464
 
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@rogieking/figui3",
3
- "version": "9.4.9",
3
+ "version": "9.4.11",
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": "SEE LICENSE IN LICENSE",