@rogieking/figui3 2.17.4 → 2.18.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.
package/components.css CHANGED
@@ -2486,6 +2486,11 @@ fig-input-number {
2486
2486
  }
2487
2487
  }
2488
2488
 
2489
+ fig-input-number > [slot],
2490
+ fig-input-text[type="number"] > [slot] {
2491
+ cursor: ew-resize !important;
2492
+ }
2493
+
2489
2494
  fig-input-color,
2490
2495
  fig-input-fill {
2491
2496
  & > .input-combo > fig-chit:not(:only-child),
@@ -2512,6 +2517,12 @@ fig-input-fill {
2512
2517
  gap: 0;
2513
2518
  }
2514
2519
  }
2520
+
2521
+ fig-field[direction="horizontal"] &,
2522
+ fig-field[direction="row"] & {
2523
+ flex: 1;
2524
+ min-width: 0;
2525
+ }
2515
2526
  }
2516
2527
 
2517
2528
  fig-slider {
@@ -2524,6 +2535,12 @@ fig-slider {
2524
2535
  & fig-input-number {
2525
2536
  flex-basis: 5rem;
2526
2537
  }
2538
+
2539
+ fig-field[direction="horizontal"] &,
2540
+ fig-field[direction="row"] & {
2541
+ flex: 1;
2542
+ min-width: 0;
2543
+ }
2527
2544
  }
2528
2545
 
2529
2546
  fig-field,
package/fig.js CHANGED
@@ -2022,6 +2022,7 @@ customElements.define("fig-segmented-control", FigSegmentedControl);
2022
2022
  * @attr {string} color - The color for the slider track (for opacity type)
2023
2023
  */
2024
2024
  class FigSlider extends HTMLElement {
2025
+ #isInteracting = false;
2025
2026
  // Private fields declarations
2026
2027
  #typeDefaults = {
2027
2028
  range: { min: 0, max: 100, step: 1 },
@@ -2088,6 +2089,7 @@ class FigSlider extends HTMLElement {
2088
2089
  let slider = `<div class="fig-slider-input-container" role="group">
2089
2090
  <input
2090
2091
  type="range"
2092
+ ${this.text ? 'tabindex="-1"' : ""}
2091
2093
  ${this.disabled ? "disabled" : ""}
2092
2094
  min="${this.min}"
2093
2095
  max="${this.max}"
@@ -2124,6 +2126,8 @@ class FigSlider extends HTMLElement {
2124
2126
  this.input.addEventListener("input", this.#boundHandleInput);
2125
2127
  this.input.removeEventListener("change", this.#boundHandleChange);
2126
2128
  this.input.addEventListener("change", this.#boundHandleChange);
2129
+ this.input.addEventListener("pointerdown", () => { this.#isInteracting = true; });
2130
+ this.input.addEventListener("pointerup", () => { this.#isInteracting = false; });
2127
2131
 
2128
2132
  if (this.default) {
2129
2133
  this.style.setProperty(
@@ -2253,6 +2257,7 @@ class FigSlider extends HTMLElement {
2253
2257
  }
2254
2258
 
2255
2259
  #handleChange() {
2260
+ this.#isInteracting = false;
2256
2261
  this.#syncValue();
2257
2262
  this.dispatchEvent(
2258
2263
  new CustomEvent("change", { detail: this.value, bubbles: true })
@@ -2306,6 +2311,7 @@ class FigSlider extends HTMLElement {
2306
2311
  }
2307
2312
  break;
2308
2313
  case "value":
2314
+ if (this.#isInteracting) break;
2309
2315
  this.value = newValue;
2310
2316
  this.input.value = newValue;
2311
2317
  this.#syncProperties();
@@ -2365,6 +2371,7 @@ customElements.define("fig-slider", FigSlider);
2365
2371
  * @attr {number} transform - A multiplier for displayed number values
2366
2372
  */
2367
2373
  class FigInputText extends HTMLElement {
2374
+ #isInteracting = false;
2368
2375
  #boundMouseMove;
2369
2376
  #boundMouseUp;
2370
2377
  #boundMouseDown;
@@ -2490,41 +2497,39 @@ class FigInputText extends HTMLElement {
2490
2497
  }
2491
2498
  #handleMouseMove(e) {
2492
2499
  if (this.type !== "number") return;
2493
- if (e.altKey) {
2494
- let step = (this.step || 1) * e.movementX;
2495
- let value = Number(this.input.value);
2496
- value = value / (this.transform || 1) + step;
2497
- value = this.#sanitizeInput(value, false);
2498
- let valueTransformed = value * (this.transform || 1);
2499
- value = this.#formatNumber(value);
2500
- valueTransformed = this.#formatNumber(valueTransformed);
2501
- this.value = value;
2502
- this.input.value = valueTransformed;
2503
- this.dispatchEvent(new CustomEvent("input", { bubbles: true }));
2504
- this.dispatchEvent(new CustomEvent("change", { bubbles: true }));
2505
- }
2500
+ let step = (this.step || 1) * e.movementX;
2501
+ let value = Number(this.input.value);
2502
+ value = value / (this.transform || 1) + step;
2503
+ value = this.#sanitizeInput(value, false);
2504
+ let valueTransformed = value * (this.transform || 1);
2505
+ value = this.#formatNumber(value);
2506
+ valueTransformed = this.#formatNumber(valueTransformed);
2507
+ this.value = value;
2508
+ this.input.value = valueTransformed;
2509
+ this.dispatchEvent(new CustomEvent("input", { bubbles: true }));
2510
+ this.dispatchEvent(new CustomEvent("change", { bubbles: true }));
2506
2511
  }
2507
2512
  #handleMouseDown(e) {
2508
2513
  if (this.type !== "number") return;
2509
- if (e.altKey) {
2514
+ if (e.altKey || e.target.closest("[slot]")) {
2515
+ this.#isInteracting = true;
2510
2516
  this.input.style.cursor =
2511
2517
  this.style.cursor =
2512
2518
  document.body.style.cursor =
2513
2519
  "ew-resize";
2514
2520
  this.style.userSelect = "none";
2515
- // Use the pre-bound handlers
2516
2521
  window.addEventListener("pointermove", this.#boundMouseMove);
2517
2522
  window.addEventListener("pointerup", this.#boundMouseUp);
2518
2523
  }
2519
2524
  }
2520
2525
  #handleMouseUp(e) {
2521
2526
  if (this.type !== "number") return;
2527
+ this.#isInteracting = false;
2522
2528
  this.input.style.cursor =
2523
2529
  this.style.cursor =
2524
2530
  document.body.style.cursor =
2525
2531
  "";
2526
2532
  this.style.userSelect = "all";
2527
- // Remove the pre-bound handlers
2528
2533
  window.removeEventListener("pointermove", this.#boundMouseMove);
2529
2534
  window.removeEventListener("pointerup", this.#boundMouseUp);
2530
2535
  }
@@ -2594,6 +2599,7 @@ class FigInputText extends HTMLElement {
2594
2599
  }
2595
2600
  break;
2596
2601
  case "value":
2602
+ if (this.#isInteracting) break;
2597
2603
  let value = newValue;
2598
2604
  if (this.type === "number") {
2599
2605
  value = this.#sanitizeInput(value, false);
@@ -2651,6 +2657,7 @@ class FigInputNumber extends HTMLElement {
2651
2657
  #units;
2652
2658
  #unitPosition;
2653
2659
  #precision;
2660
+ #isInteracting = false;
2654
2661
 
2655
2662
  constructor() {
2656
2663
  super();
@@ -2830,6 +2837,7 @@ class FigInputNumber extends HTMLElement {
2830
2837
  }
2831
2838
 
2832
2839
  #handleFocus(e) {
2840
+ this.#isInteracting = true;
2833
2841
  setTimeout(() => {
2834
2842
  const value = e.target.value;
2835
2843
  if (value && this.#units) {
@@ -2846,6 +2854,7 @@ class FigInputNumber extends HTMLElement {
2846
2854
  }
2847
2855
 
2848
2856
  #handleBlur(e) {
2857
+ this.#isInteracting = false;
2849
2858
  let numericValue = this.#getNumericValue(e.target.value);
2850
2859
  if (numericValue !== "") {
2851
2860
  let val = Number(numericValue) / (this.transform || 1);
@@ -2924,39 +2933,37 @@ class FigInputNumber extends HTMLElement {
2924
2933
 
2925
2934
  #handleMouseMove(e) {
2926
2935
  if (this.disabled) return;
2927
- if (e.altKey) {
2928
- let step = (this.step || 1) * e.movementX;
2929
- let numericValue = this.#getNumericValue(this.input.value);
2930
- let value = Number(numericValue) / (this.transform || 1) + step;
2931
- value = this.#sanitizeInput(value, false);
2932
- this.value = value;
2933
- this.input.value = this.#formatWithUnit(this.value);
2934
- this.dispatchEvent(new CustomEvent("input", { bubbles: true }));
2935
- this.dispatchEvent(new CustomEvent("change", { bubbles: true }));
2936
- }
2936
+ let step = (this.step || 1) * e.movementX;
2937
+ let numericValue = this.#getNumericValue(this.input.value);
2938
+ let value = Number(numericValue) / (this.transform || 1) + step;
2939
+ value = this.#sanitizeInput(value, false);
2940
+ this.value = value;
2941
+ this.input.value = this.#formatWithUnit(this.value);
2942
+ this.dispatchEvent(new CustomEvent("input", { bubbles: true }));
2943
+ this.dispatchEvent(new CustomEvent("change", { bubbles: true }));
2937
2944
  }
2938
2945
 
2939
2946
  #handleMouseDown(e) {
2940
2947
  if (this.disabled) return;
2941
- if (e.altKey) {
2948
+ if (e.altKey || e.target.closest("[slot]")) {
2949
+ this.#isInteracting = true;
2942
2950
  this.input.style.cursor =
2943
2951
  this.style.cursor =
2944
2952
  document.body.style.cursor =
2945
2953
  "ew-resize";
2946
2954
  this.style.userSelect = "none";
2947
- // Use the pre-bound handlers
2948
2955
  window.addEventListener("pointermove", this.#boundMouseMove);
2949
2956
  window.addEventListener("pointerup", this.#boundMouseUp);
2950
2957
  }
2951
2958
  }
2952
2959
 
2953
2960
  #handleMouseUp(e) {
2961
+ this.#isInteracting = false;
2954
2962
  this.input.style.cursor =
2955
2963
  this.style.cursor =
2956
2964
  document.body.style.cursor =
2957
2965
  "";
2958
2966
  this.style.userSelect = "all";
2959
- // Remove the pre-bound handlers
2960
2967
  window.removeEventListener("pointermove", this.#boundMouseMove);
2961
2968
  window.removeEventListener("pointerup", this.#boundMouseUp);
2962
2969
  }
@@ -3019,6 +3026,7 @@ class FigInputNumber extends HTMLElement {
3019
3026
  this.input.value = this.#formatWithUnit(this.value);
3020
3027
  break;
3021
3028
  case "value":
3029
+ if (this.#isInteracting) break;
3022
3030
  let value =
3023
3031
  newValue !== null && newValue !== "" ? Number(newValue) : "";
3024
3032
  if (value !== "") {
@@ -4167,9 +4175,15 @@ class FigInputFill extends HTMLElement {
4167
4175
 
4168
4176
  switch (name) {
4169
4177
  case "value":
4178
+ const prevType = this.#fillType;
4170
4179
  this.#parseValue();
4171
4180
  if (this.#fillPicker) {
4172
- this.#render();
4181
+ if (this.#fillType !== prevType) {
4182
+ this.#render();
4183
+ } else {
4184
+ this.#updateFillPicker();
4185
+ this.#updateControls();
4186
+ }
4173
4187
  }
4174
4188
  break;
4175
4189
  case "disabled":
@@ -5314,6 +5328,7 @@ class FigInputJoystick extends HTMLElement {
5314
5328
  }
5315
5329
  attributeChangedCallback(name, oldValue, newValue) {
5316
5330
  if (name === "value") {
5331
+ if (this.isDragging) return;
5317
5332
  this.value = newValue;
5318
5333
  }
5319
5334
  if (name === "precision") {
@@ -5771,6 +5786,7 @@ class FigInputAngle extends HTMLElement {
5771
5786
  attributeChangedCallback(name, oldValue, newValue) {
5772
5787
  switch (name) {
5773
5788
  case "value":
5789
+ if (this.isDragging) break;
5774
5790
  this.value = Number(newValue);
5775
5791
  break;
5776
5792
  case "precision":
package/index.html CHANGED
@@ -1267,69 +1267,62 @@
1267
1267
  </fig-field>
1268
1268
 
1269
1269
  <h3>Horizontal Fields with Different Inputs</h3>
1270
- <fig-field direction="horizontal"
1271
- style="width: 240px;">
1272
- <label>Text Input</label>
1273
- <fig-input-text placeholder="Enter text"></fig-input-text>
1274
- </fig-field>
1275
- <fig-field direction="horizontal"
1276
- style="width: 240px;">
1277
- <label>Number Input</label>
1278
- <fig-input-number value="100"
1279
- units="px"></fig-input-number>
1280
- </fig-field>
1281
- <fig-field direction="horizontal"
1282
- style="width: 240px;">
1283
- <label>Dropdown</label>
1284
- <fig-dropdown>
1285
- <option>Option One</option>
1286
- <option>Option Two</option>
1287
- <option>Option Three</option>
1288
- </fig-dropdown>
1289
- </fig-field>
1290
- <fig-field direction="horizontal"
1291
- style="width: 240px;">
1292
- <label>Slider</label>
1293
- <fig-slider value="50"
1294
- text="true"></fig-slider>
1295
- </fig-field>
1296
- <fig-field direction="horizontal"
1297
- style="width: 240px;">
1298
- <label>Color</label>
1299
- <fig-input-color value="#0D99FF"
1300
- text="true"></fig-input-color>
1301
- </fig-field>
1302
- <fig-field direction="horizontal"
1303
- style="width: 240px;">
1304
- <label>Angle</label>
1305
- <fig-input-angle value="45"
1306
- text="true"></fig-input-angle>
1307
- </fig-field>
1308
- <fig-field direction="horizontal"
1309
- style="width: 240px;">
1310
- <label>Joystick</label>
1311
- <fig-input-joystick text="true"
1312
- value="50,50"></fig-input-joystick>
1313
- </fig-field>
1314
- <fig-field direction="horizontal"
1315
- style="width: 240px;">
1316
- <label>Switch</label>
1317
- <fig-switch></fig-switch>
1318
- </fig-field>
1319
- <fig-field direction="horizontal"
1320
- style="width: 240px;">
1321
- <label>Checkbox</label>
1322
- <fig-checkbox></fig-checkbox>
1323
- </fig-field>
1324
- <fig-field direction="horizontal"
1325
- style="width: 240px;">
1326
- <label>Segmented</label>
1327
- <fig-segmented-control>
1328
- <fig-segment value="left">Left</fig-segment>
1329
- <fig-segment value="center">Center</fig-segment>
1330
- <fig-segment value="right">Right</fig-segment>
1331
- </fig-segmented-control>
1332
- </fig-field>
1270
+ <p class="description">Drag the right edge to test at different widths.</p>
1271
+ <div class="resize-test" style="width: 240px;">
1272
+ <fig-field direction="horizontal">
1273
+ <label>Text Input</label>
1274
+ <fig-input-text placeholder="Enter text" full></fig-input-text>
1275
+ </fig-field>
1276
+ <fig-field direction="horizontal">
1277
+ <label>Number Input</label>
1278
+ <fig-input-number value="100"
1279
+ units="px" full></fig-input-number>
1280
+ </fig-field>
1281
+ <fig-field direction="horizontal">
1282
+ <label>Dropdown</label>
1283
+ <fig-dropdown full>
1284
+ <option>Option One</option>
1285
+ <option>Option Two</option>
1286
+ <option>Option Three</option>
1287
+ </fig-dropdown>
1288
+ </fig-field>
1289
+ <fig-field direction="horizontal">
1290
+ <label>Slider</label>
1291
+ <fig-slider value="50"
1292
+ text="true" full></fig-slider>
1293
+ </fig-field>
1294
+ <fig-field direction="horizontal">
1295
+ <label>Color</label>
1296
+ <fig-input-color value="#0D99FF"
1297
+ text="true" full></fig-input-color>
1298
+ </fig-field>
1299
+ <fig-field direction="horizontal">
1300
+ <label>Angle</label>
1301
+ <fig-input-angle value="45"
1302
+ text="true" full></fig-input-angle>
1303
+ </fig-field>
1304
+ <fig-field direction="horizontal">
1305
+ <label>Joystick</label>
1306
+ <fig-input-joystick text="true"
1307
+ value="50,50" full></fig-input-joystick>
1308
+ </fig-field>
1309
+ <fig-field direction="horizontal">
1310
+ <label>Switch</label>
1311
+ <fig-switch></fig-switch>
1312
+ </fig-field>
1313
+ <fig-field direction="horizontal">
1314
+ <label>Checkbox</label>
1315
+ <fig-checkbox></fig-checkbox>
1316
+ </fig-field>
1317
+ <fig-field direction="horizontal">
1318
+ <label>Segmented</label>
1319
+ <fig-segmented-control full>
1320
+ <fig-segment value="left">Left</fig-segment>
1321
+ <fig-segment value="center">Center</fig-segment>
1322
+ <fig-segment value="right">Right</fig-segment>
1323
+ </fig-segmented-control>
1324
+ </fig-field>
1325
+ </div>
1333
1326
  </section>
1334
1327
  <hr>
1335
1328
 
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@rogieking/figui3",
3
- "version": "2.17.4",
3
+ "version": "2.18.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",