@rogieking/figui3 8.9.49 → 8.10.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.js CHANGED
@@ -633,7 +633,7 @@ class FigButton extends HTMLElement {
633
633
  const style = document.createElement("style");
634
634
  style.textContent = `
635
635
  button, button:hover, button:active, .fig-button-control {
636
- padding: 0 var(--spacer-2);
636
+ padding: var(--fig-button-control-padding, 0 var(--spacer-2));
637
637
  appearance: none;
638
638
  display: flex;
639
639
  border: 0;
@@ -646,7 +646,7 @@ class FigButton extends HTMLElement {
646
646
  outline: 0;
647
647
  place-items: center;
648
648
  background: transparent;
649
- margin: calc(var(--spacer-2)*-1);
649
+ margin: var(--fig-button-control-margin, calc(var(--spacer-2)*-1));
650
650
  height: var(--spacer-4);
651
651
  white-space: nowrap;
652
652
  overflow: hidden;
@@ -14054,6 +14054,7 @@ figDefineElement("fig-input-file", FigInputFile);
14054
14054
  /**
14055
14055
  * A bezier / spring easing curve editor with draggable control points.
14056
14056
  * @attr {string} value - Bezier: "0.42, 0, 0.58, 1" or Spring: "spring(200, 15, 1)"
14057
+ * @attr {string} mode - Optional editor constraint: "bezier" or "spring".
14057
14058
  * @attr {number} precision - Decimal places for output values (default 2)
14058
14059
  * @attr {boolean} edit - Show the editor and custom preset options (default true; set "false" for presets only)
14059
14060
  */
@@ -14153,14 +14154,17 @@ class FigEasingCurve extends HTMLElement {
14153
14154
  ];
14154
14155
 
14155
14156
  static get observedAttributes() {
14156
- return ["value", "precision", "aspect-ratio", "edit"];
14157
+ return ["value", "mode", "precision", "aspect-ratio", "edit"];
14157
14158
  }
14158
14159
 
14159
14160
  connectedCallback() {
14160
14161
  this.#precision = parseInt(this.getAttribute("precision") || "2");
14161
14162
  figSyncCssVar(this, "--aspect-ratio", this.getAttribute("aspect-ratio"));
14163
+ const constrainedMode = this.#constrainedMode();
14164
+ if (constrainedMode) this.#mode = constrainedMode;
14162
14165
  const val = this.getAttribute("value");
14163
14166
  if (val) this.#parseValue(val);
14167
+ this.#applyModeConstraint();
14164
14168
  this.#presetName = this.#matchPreset();
14165
14169
  this.#render();
14166
14170
  this.#setupResizeObserver();
@@ -14191,6 +14195,13 @@ class FigEasingCurve extends HTMLElement {
14191
14195
  return;
14192
14196
  }
14193
14197
 
14198
+ if (name === "mode") {
14199
+ this.#applyModeConstraint();
14200
+ this.#presetName = this.#matchPreset();
14201
+ if (this.isConnected) this.#render();
14202
+ return;
14203
+ }
14204
+
14194
14205
  if (name === "value" && newValue) {
14195
14206
  const prevMode = this.#mode;
14196
14207
  this.#parseValue(newValue);
@@ -14242,11 +14253,26 @@ class FigEasingCurve extends HTMLElement {
14242
14253
  this.setAttribute("value", v);
14243
14254
  }
14244
14255
 
14256
+ #constrainedMode() {
14257
+ const mode = this.getAttribute("mode")?.trim().toLowerCase();
14258
+ return mode === "bezier" || mode === "spring" ? mode : null;
14259
+ }
14260
+
14261
+ #applyModeConstraint() {
14262
+ const mode = this.#constrainedMode();
14263
+ if (mode) this.#mode = mode;
14264
+ }
14265
+
14266
+ #allowsPreset(preset) {
14267
+ const mode = this.#constrainedMode();
14268
+ return !mode || preset.type === mode;
14269
+ }
14270
+
14245
14271
  #parseValue(str) {
14246
14272
  const springMatch = str.match(
14247
14273
  /^spring\(\s*([\d.]+)\s*,\s*([\d.]+)\s*,\s*([\d.]+)\s*\)$/,
14248
14274
  );
14249
- if (springMatch) {
14275
+ if (springMatch && this.#constrainedMode() !== "bezier") {
14250
14276
  this.#mode = "spring";
14251
14277
  this.#spring.stiffness = parseFloat(springMatch[1]);
14252
14278
  this.#spring.damping = parseFloat(springMatch[2]);
@@ -14254,7 +14280,11 @@ class FigEasingCurve extends HTMLElement {
14254
14280
  return true;
14255
14281
  }
14256
14282
  const parts = str.split(",").map((s) => parseFloat(s.trim()));
14257
- if (parts.length >= 4 && parts.every((n) => !isNaN(n))) {
14283
+ if (
14284
+ parts.length >= 4 &&
14285
+ parts.every((n) => !isNaN(n)) &&
14286
+ this.#constrainedMode() !== "spring"
14287
+ ) {
14258
14288
  this.#mode = "bezier";
14259
14289
  this.#cp1.x = parts[0];
14260
14290
  this.#cp1.y = parts[1];
@@ -14473,6 +14503,7 @@ class FigEasingCurve extends HTMLElement {
14473
14503
  let currentGroup = undefined;
14474
14504
  let parent = dropdown;
14475
14505
  for (const preset of FigEasingCurve.PRESETS) {
14506
+ if (!this.#allowsPreset(preset)) continue;
14476
14507
  if (!this.#isEditEnabled() && !preset.value && !preset.spring) continue;
14477
14508
  if (preset.group !== currentGroup) {
14478
14509
  currentGroup = preset.group;
@@ -14494,6 +14525,7 @@ class FigEasingCurve extends HTMLElement {
14494
14525
  const options = document.createElement("fig-select-options");
14495
14526
  let currentGroup = undefined;
14496
14527
  for (const p of FigEasingCurve.PRESETS) {
14528
+ if (!this.#allowsPreset(p)) continue;
14497
14529
  if (!this.#isEditEnabled() && !p.value && !p.spring) continue;
14498
14530
  if (p.group !== currentGroup) {
14499
14531
  if (p.group) {
@@ -14962,19 +14994,41 @@ class FigEasingCurve extends HTMLElement {
14962
14994
  return parts;
14963
14995
  }
14964
14996
 
14997
+ #parseManualSpringValue(value) {
14998
+ const match = value.match(
14999
+ /^spring\(\s*([\d.]+)\s*,\s*([\d.]+)\s*,\s*([\d.]+)\s*\)$/,
15000
+ );
15001
+ if (!match) return null;
15002
+ const spring = {
15003
+ stiffness: Number(match[1]),
15004
+ damping: Number(match[2]),
15005
+ mass: Number(match[3]),
15006
+ };
15007
+ return Object.values(spring).every((part) => part > 0) ? spring : null;
15008
+ }
15009
+
14965
15010
  #applyManualValue(value, eventType) {
14966
- const parts = this.#parseManualBezierValue(value);
14967
- if (!parts) {
15011
+ const constrainedMode = this.#constrainedMode();
15012
+ const spring =
15013
+ constrainedMode === "bezier" ? null : this.#parseManualSpringValue(value);
15014
+ const bezier =
15015
+ constrainedMode === "spring" ? null : this.#parseManualBezierValue(value);
15016
+ if (!spring && !bezier) {
14968
15017
  if (eventType === "change") this.#syncValueInput();
14969
15018
  return;
14970
15019
  }
14971
15020
 
14972
15021
  const prevMode = this.#mode;
14973
- this.#mode = "bezier";
14974
- this.#cp1.x = parts[0];
14975
- this.#cp1.y = parts[1];
14976
- this.#cp2.x = parts[2];
14977
- this.#cp2.y = parts[3];
15022
+ if (spring) {
15023
+ this.#mode = "spring";
15024
+ this.#spring = spring;
15025
+ } else {
15026
+ this.#mode = "bezier";
15027
+ this.#cp1.x = bezier[0];
15028
+ this.#cp1.y = bezier[1];
15029
+ this.#cp2.x = bezier[2];
15030
+ this.#cp2.y = bezier[3];
15031
+ }
14978
15032
 
14979
15033
  this.#presetName = this.#matchPreset();
14980
15034
  if (prevMode !== this.#mode) {
@@ -16453,18 +16507,12 @@ class FigInputJoystick extends HTMLElement {
16453
16507
  const planeContainer = figCreateElement("div", {
16454
16508
  className: "fig-input-joystick-plane-container",
16455
16509
  });
16456
- const createAxisLabel = (position, text, noRotate = false) =>
16510
+ const createAxisLabel = (position, text) =>
16457
16511
  text
16458
16512
  ? figCreateElement(
16459
16513
  "label",
16460
16514
  {
16461
- className: [
16462
- "fig-joystick-axis-label",
16463
- position,
16464
- noRotate ? "no-rotate" : "",
16465
- ]
16466
- .filter(Boolean)
16467
- .join(" "),
16515
+ className: ["fig-joystick-axis-label", position].join(" "),
16468
16516
  "aria-hidden": "true",
16469
16517
  },
16470
16518
  text,
@@ -16472,11 +16520,7 @@ class FigInputJoystick extends HTMLElement {
16472
16520
  : null;
16473
16521
  planeContainer.append(
16474
16522
  ...[
16475
- createAxisLabel(
16476
- "left",
16477
- axisLabels.left,
16478
- axisLabels.leftNoRotate,
16479
- ),
16523
+ createAxisLabel("left", axisLabels.left),
16480
16524
  createAxisLabel("right", axisLabels.right),
16481
16525
  createAxisLabel("top", axisLabels.top),
16482
16526
  createAxisLabel("bottom", axisLabels.bottom),
@@ -16548,7 +16592,7 @@ class FigInputJoystick extends HTMLElement {
16548
16592
  #getAxisLabels() {
16549
16593
  const raw = (this.getAttribute("axis-labels") || "").trim();
16550
16594
  if (!raw) {
16551
- return { left: "", right: "", top: "", bottom: "", leftNoRotate: false };
16595
+ return { left: "", right: "", top: "", bottom: "" };
16552
16596
  }
16553
16597
  const tokens = raw.split(/[\s,]+/).filter(Boolean);
16554
16598
  if (tokens.length === 1) {
@@ -16557,18 +16601,17 @@ class FigInputJoystick extends HTMLElement {
16557
16601
  right: "",
16558
16602
  top: tokens[0],
16559
16603
  bottom: "",
16560
- leftNoRotate: false,
16561
16604
  };
16562
16605
  }
16563
16606
  if (tokens.length === 2) {
16564
16607
  const [x, y] = tokens;
16565
- return { left: x, right: "", top: "", bottom: y, leftNoRotate: true };
16608
+ return { left: x, right: "", top: "", bottom: y };
16566
16609
  }
16567
16610
  if (tokens.length === 4) {
16568
16611
  const [left, right, top, bottom] = tokens;
16569
- return { left, right, top, bottom, leftNoRotate: false };
16612
+ return { left, right, top, bottom };
16570
16613
  }
16571
- return { left: "", right: "", top: "", bottom: "", leftNoRotate: false };
16614
+ return { left: "", right: "", top: "", bottom: "" };
16572
16615
  }
16573
16616
 
16574
16617
  #setupListeners() {
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@rogieking/figui3",
3
- "version": "8.9.49",
3
+ "version": "8.10.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": "SEE LICENSE IN LICENSE",