@rogieking/figui3 6.37.1 → 6.39.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/fig-lab.css CHANGED
@@ -1293,6 +1293,13 @@ propskit-slider {
1293
1293
  flex: 0 0 auto;
1294
1294
  text-align: right;
1295
1295
  color: var(--field-text-color);
1296
+ cursor: default;
1297
+ touch-action: none;
1298
+
1299
+ &:focus {
1300
+ cursor: text;
1301
+ touch-action: auto;
1302
+ }
1296
1303
  }
1297
1304
  }
1298
1305
  }
@@ -1330,6 +1337,22 @@ propskit-slider {
1330
1337
  }
1331
1338
  }
1332
1339
 
1340
+ :is(
1341
+ propskit-switch,
1342
+ propskit-color,
1343
+ propskit-gradient,
1344
+ propskit-select,
1345
+ propskit-text,
1346
+ propskit-number,
1347
+ propskit-slider
1348
+ ) fig-field:not([direction="vertical"]) > label {
1349
+ display: block;
1350
+ max-width: 40%;
1351
+ overflow: hidden;
1352
+ text-overflow: ellipsis;
1353
+ white-space: nowrap;
1354
+ }
1355
+
1333
1356
  /* Canvas Control */
1334
1357
  body {
1335
1358
  --fig-lab-cursor: url('data:image/svg+xml,<svg width="32" height="32" viewBox="0 0 32 32" fill="none" xmlns="http://www.w3.org/2000/svg"><g clip-path="url(%23clip0_20065_231516)"><g filter="url(%23filter0_d_20065_231516)"><path fill-rule="evenodd" clip-rule="evenodd" d="M2.93938 2.93938C3.35531 2.52345 3.97597 2.38901 4.52673 2.59555L15.5267 6.72055C16.1416 6.95111 16.535 7.55477 16.4976 8.21034C16.4603 8.86592 16.0009 9.421 15.3638 9.58026L10.737 10.737L9.58026 15.3638C9.421 16.0009 8.86592 16.4603 8.21034 16.4976C7.55477 16.535 6.95111 16.1416 6.72055 15.5267L2.59555 4.52673C2.38901 3.97597 2.52345 3.35531 2.93938 2.93938Z" fill="white"/></g><path fill-rule="evenodd" clip-rule="evenodd" d="M4.17558 3.53185C3.99199 3.463 3.7851 3.50782 3.64646 3.64646C3.50782 3.7851 3.463 3.99199 3.53185 4.17558L7.65685 15.1756C7.7337 15.3805 7.93492 15.5117 8.15345 15.4992C8.37197 15.4868 8.557 15.3336 8.61009 15.1213L9.91232 9.91232L15.1213 8.61009C15.3336 8.557 15.4868 8.37197 15.4992 8.15345C15.5117 7.93492 15.3805 7.7337 15.1756 7.65685L4.17558 3.53185Z" fill="black"/></g><defs><filter id="filter0_d_20065_231516" x="-0.5" y="0.5" width="20" height="20" filterUnits="userSpaceOnUse" color-interpolation-filters="sRGB"><feFlood flood-opacity="0" result="BackgroundImageFix"/><feColorMatrix in="SourceAlpha" type="matrix" values="0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 127 0" result="hardAlpha"/><feOffset dy="1"/><feGaussianBlur stdDeviation="1.5"/><feColorMatrix type="matrix" values="0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0.35 0"/><feBlend mode="normal" in2="BackgroundImageFix" result="effect1_dropShadow_20065_231516"/><feBlend mode="normal" in="SourceGraphic" in2="effect1_dropShadow_20065_231516" result="shape"/></filter><clipPath id="clip0_20065_231516"><rect width="32" height="32" fill="white"/></clipPath></defs></svg>') 3 3, default;
package/fig-lab.js CHANGED
@@ -2299,11 +2299,20 @@ class PropskitSlider extends HTMLElement {
2299
2299
  #elasticRangeRect = null;
2300
2300
  #elasticHostWidth = 0;
2301
2301
  #elasticPointerId = null;
2302
+ #numberPointerId = null;
2303
+ #numberPointerStartX = 0;
2304
+ #numberPointerStartY = 0;
2305
+ #isNumberScrubbing = false;
2306
+ #suppressNumberClick = false;
2307
+ #numberClickResetTimer = 0;
2302
2308
  #boundHandleSliderInput = null;
2303
2309
  #boundHandleSliderChange = null;
2304
2310
  #boundHandleElasticPointerDown = this.#handleElasticPointerDown.bind(this);
2305
2311
  #boundHandleElasticPointerMove = this.#handleElasticPointerMove.bind(this);
2306
2312
  #boundHandleElasticPointerEnd = this.#handleElasticPointerEnd.bind(this);
2313
+ #boundHandleNumberPointerDown = this.#handleNumberPointerDown.bind(this);
2314
+ #boundHandleNumberPointerMove = this.#handleNumberPointerMove.bind(this);
2315
+ #boundHandleNumberPointerEnd = this.#handleNumberPointerEnd.bind(this);
2307
2316
  #boundHandleRangeDoubleClick = this.#handleRangeDoubleClick.bind(this);
2308
2317
  #boundHandleContextMenu = this.#handleContextMenu.bind(this);
2309
2318
  #boundHandleContextMenuChange = this.#handleContextMenuChange.bind(this);
@@ -2343,6 +2352,12 @@ class PropskitSlider extends HTMLElement {
2343
2352
  capture: true,
2344
2353
  passive: true,
2345
2354
  });
2355
+ this.removeEventListener("pointerdown", this.#boundHandleNumberPointerDown, {
2356
+ capture: true,
2357
+ });
2358
+ this.addEventListener("pointerdown", this.#boundHandleNumberPointerDown, {
2359
+ capture: true,
2360
+ });
2346
2361
  this.removeEventListener("contextmenu", this.#boundHandleContextMenu);
2347
2362
  this.addEventListener("contextmenu", this.#boundHandleContextMenu);
2348
2363
  this.removeEventListener("click", this.#boundHandleClick, true);
@@ -2410,6 +2425,9 @@ class PropskitSlider extends HTMLElement {
2410
2425
  this.#focusSyncFrame = 0;
2411
2426
  }
2412
2427
  this.#clearPendingClick();
2428
+ this.#stopNumberTracking();
2429
+ clearTimeout(this.#numberClickResetTimer);
2430
+ this.#numberClickResetTimer = 0;
2413
2431
  this.#stopElasticTracking();
2414
2432
  this.#resetElasticPull();
2415
2433
  this.#unbindRangeInput();
@@ -2417,6 +2435,9 @@ class PropskitSlider extends HTMLElement {
2417
2435
  this.removeEventListener("pointerdown", this.#boundHandleElasticPointerDown, {
2418
2436
  capture: true,
2419
2437
  });
2438
+ this.removeEventListener("pointerdown", this.#boundHandleNumberPointerDown, {
2439
+ capture: true,
2440
+ });
2420
2441
  this.removeEventListener("contextmenu", this.#boundHandleContextMenu);
2421
2442
  this.removeEventListener("click", this.#boundHandleClick, true);
2422
2443
  this.#contextMenu?.removeEventListener("change", this.#boundHandleContextMenuChange);
@@ -2652,6 +2673,14 @@ class PropskitSlider extends HTMLElement {
2652
2673
  event.target instanceof Element &&
2653
2674
  event.target.closest("fig-input-number, fig-menu")
2654
2675
  ) {
2676
+ if (
2677
+ this.#suppressNumberClick &&
2678
+ event.target.closest("fig-input-number")
2679
+ ) {
2680
+ event.preventDefault();
2681
+ event.stopImmediatePropagation();
2682
+ this.#suppressNumberClick = false;
2683
+ }
2655
2684
  return;
2656
2685
  }
2657
2686
  this.#queueRangeFocus();
@@ -2690,6 +2719,89 @@ class PropskitSlider extends HTMLElement {
2690
2719
  this.#resetToDefault();
2691
2720
  }
2692
2721
 
2722
+ #handleNumberPointerDown(event) {
2723
+ if (
2724
+ event.button !== 0 ||
2725
+ event.altKey ||
2726
+ figLabBooleanAttribute(this, "disabled") ||
2727
+ !(event.target instanceof Element)
2728
+ ) {
2729
+ return;
2730
+ }
2731
+ const input = event.target.closest("fig-input-number input");
2732
+ if (!input || input === document.activeElement) return;
2733
+
2734
+ event.preventDefault();
2735
+ event.stopImmediatePropagation();
2736
+ this.#stopNumberTracking();
2737
+ this.#numberPointerId = event.pointerId;
2738
+ this.#numberPointerStartX = event.clientX;
2739
+ this.#numberPointerStartY = event.clientY;
2740
+ this.#isNumberScrubbing = false;
2741
+ window.addEventListener("pointermove", this.#boundHandleNumberPointerMove);
2742
+ window.addEventListener("pointerup", this.#boundHandleNumberPointerEnd, {
2743
+ once: true,
2744
+ });
2745
+ window.addEventListener("pointercancel", this.#boundHandleNumberPointerEnd, {
2746
+ once: true,
2747
+ });
2748
+ window.addEventListener("blur", this.#boundHandleNumberPointerEnd, {
2749
+ once: true,
2750
+ });
2751
+ }
2752
+
2753
+ #handleNumberPointerMove(event) {
2754
+ if (event.pointerId !== this.#numberPointerId) return;
2755
+ if (event.buttons === 0) {
2756
+ this.#handleNumberPointerEnd(event);
2757
+ return;
2758
+ }
2759
+ if (!this.#isNumberScrubbing) {
2760
+ const distance = Math.hypot(
2761
+ event.clientX - this.#numberPointerStartX,
2762
+ event.clientY - this.#numberPointerStartY,
2763
+ );
2764
+ if (distance < 4) return;
2765
+ this.#isNumberScrubbing = true;
2766
+ this.setAttribute("data-number-scrubbing", "");
2767
+ }
2768
+ this.#setSliderValue(this.#valueFromPointer(event), "input");
2769
+ }
2770
+
2771
+ #handleNumberPointerEnd(event) {
2772
+ if (
2773
+ event?.pointerId !== undefined &&
2774
+ this.#numberPointerId !== null &&
2775
+ event.pointerId !== this.#numberPointerId
2776
+ ) {
2777
+ return;
2778
+ }
2779
+ const wasScrubbing = this.#isNumberScrubbing;
2780
+ this.#stopNumberTracking();
2781
+ if (wasScrubbing) {
2782
+ this.#setSliderValue(this.#slider?.value, "change");
2783
+ this.#suppressNumberClick = true;
2784
+ clearTimeout(this.#numberClickResetTimer);
2785
+ this.#numberClickResetTimer = window.setTimeout(() => {
2786
+ this.#suppressNumberClick = false;
2787
+ this.#numberClickResetTimer = 0;
2788
+ }, 0);
2789
+ this.#queueRangeFocus();
2790
+ return;
2791
+ }
2792
+ this.#slider?.querySelector("fig-input-number input")?.focus();
2793
+ }
2794
+
2795
+ #stopNumberTracking() {
2796
+ window.removeEventListener("pointermove", this.#boundHandleNumberPointerMove);
2797
+ window.removeEventListener("pointerup", this.#boundHandleNumberPointerEnd);
2798
+ window.removeEventListener("pointercancel", this.#boundHandleNumberPointerEnd);
2799
+ window.removeEventListener("blur", this.#boundHandleNumberPointerEnd);
2800
+ this.#numberPointerId = null;
2801
+ this.#isNumberScrubbing = false;
2802
+ this.removeAttribute("data-number-scrubbing");
2803
+ }
2804
+
2693
2805
  #handleElasticPointerDown(event) {
2694
2806
  if (event.button !== 0 || figLabBooleanAttribute(this, "disabled")) return;
2695
2807
  if (this.getAttribute("elastic") === "false") return;
package/fig.js CHANGED
@@ -6659,6 +6659,8 @@ class FigSlider extends HTMLElement {
6659
6659
 
6660
6660
  set value(value) {
6661
6661
  const rawValue = value === null || value === undefined ? "" : String(value);
6662
+ this.#showEmptyTextValue =
6663
+ this.type !== "range" && rawValue.trim() === "";
6662
6664
  const hasParsedBounds = this.min !== undefined || this.max !== undefined;
6663
6665
  const normalized = hasParsedBounds
6664
6666
  ? String(this.#normalizeSliderValue(rawValue))
@@ -7004,18 +7006,8 @@ class FigSlider extends HTMLElement {
7004
7006
  break;
7005
7007
  case "value":
7006
7008
  if (this.#isInteracting) break;
7007
- this.#showEmptyTextValue =
7008
- newValue === null ||
7009
- (typeof newValue === "string" && newValue.trim() === "");
7010
- this.value = this.#normalizeSliderValue(newValue);
7011
- this.input.value = String(this.value);
7009
+ this.value = newValue;
7012
7010
  this.#syncValue();
7013
- if (this.figInputNumber) {
7014
- this.figInputNumber.setAttribute(
7015
- "value",
7016
- this.#showEmptyTextValue ? "" : this.value,
7017
- );
7018
- }
7019
7011
  break;
7020
7012
  case "transform":
7021
7013
  this.transform = Number(newValue) || 1;
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@rogieking/figui3",
3
- "version": "6.37.1",
3
+ "version": "6.39.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",