@rogieking/figui3 8.9.29 → 8.9.30

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.js CHANGED
@@ -4639,6 +4639,7 @@ class PropskitSlider extends HTMLElement {
4639
4639
  "data-wave-index",
4640
4640
  "data-active",
4641
4641
  "data-elastic-dragging",
4642
+ "default",
4642
4643
  "style",
4643
4644
  ]);
4644
4645
 
@@ -4761,8 +4762,11 @@ class PropskitSlider extends HTMLElement {
4761
4762
  }
4762
4763
 
4763
4764
  #initialize() {
4765
+ const sliderType = (this.getAttribute("type") || "range").toLowerCase();
4764
4766
  this.#initialValue =
4765
- this.getAttribute("value") ?? this.getAttribute("min") ?? "0";
4767
+ this.getAttribute("value") ??
4768
+ this.getAttribute("default") ??
4769
+ (sliderType === "delta" ? "0" : this.getAttribute("min") ?? "0");
4766
4770
  const initialChildren = Array.from(this.childNodes).filter((node) => {
4767
4771
  return (
4768
4772
  node.nodeType !== Node.TEXT_NODE || Boolean(node.textContent?.trim())
@@ -4866,12 +4870,15 @@ class PropskitSlider extends HTMLElement {
4866
4870
  this.#slider.setAttribute("text", "true");
4867
4871
 
4868
4872
  const sliderType = (this.getAttribute("type") || "range").toLowerCase();
4869
- if (sliderType === "delta" || sliderType === "stepper") {
4870
- this.#slider.setAttribute(
4871
- "default",
4872
- this.getAttribute("default") ?? "50",
4873
- );
4874
- } else if (!this.hasAttribute("default")) {
4873
+ if (sliderType === "delta") {
4874
+ const min = Number(this.#slider.min);
4875
+ const max = Number(this.#slider.max);
4876
+ const midpoint =
4877
+ Number.isFinite(min) && Number.isFinite(max)
4878
+ ? min + (max - min) / 2
4879
+ : 0;
4880
+ this.#slider.setAttribute("default", String(midpoint));
4881
+ } else {
4875
4882
  this.#slider.removeAttribute("default");
4876
4883
  }
4877
4884
  if (sliderType === "stepper") {
@@ -4910,8 +4917,10 @@ class PropskitSlider extends HTMLElement {
4910
4917
  }
4911
4918
 
4912
4919
  #pushExternalValueToSlider() {
4913
- if (!this.#slider || !this.hasAttribute("value")) return;
4914
- const next = this.getAttribute("value") ?? "";
4920
+ if (!this.#slider) return;
4921
+ const next = this.hasAttribute("value")
4922
+ ? this.getAttribute("value") ?? ""
4923
+ : this.#initialValue ?? "";
4915
4924
  if (String(this.#slider.value) !== next) {
4916
4925
  this.#slider.value = next;
4917
4926
  }
@@ -5313,7 +5322,6 @@ class PropskitSlider extends HTMLElement {
5313
5322
  #defaultValue() {
5314
5323
  return (
5315
5324
  this.getAttribute("default") ??
5316
- this.#slider?.getAttribute("default") ??
5317
5325
  this.#initialValue ??
5318
5326
  this.#rangeInput?.min ??
5319
5327
  "0"
@@ -7163,6 +7171,7 @@ class PropskitOscillator extends HTMLElement {
7163
7171
  { text: label },
7164
7172
  figLabCreateElement("fig-handle", {
7165
7173
  size: "small",
7174
+ type: "minimal",
7166
7175
  "aria-label": `Oscillator ${type} handle`,
7167
7176
  }),
7168
7177
  ),
package/fig.js CHANGED
@@ -5700,11 +5700,7 @@ class FigSlider extends HTMLElement {
5700
5700
  this.step = readNumber("step", defaults.step);
5701
5701
  if (!(this.step > 0)) this.step = defaults.step > 0 ? defaults.step : 1;
5702
5702
  this.color = this.getAttribute("color") || defaults?.color;
5703
- this.default = this.hasAttribute("default")
5704
- ? this.getAttribute("default")
5705
- : this.type === "delta"
5706
- ? 0
5707
- : this.min;
5703
+ this.default = this.#resolveDefaultValue();
5708
5704
  this.value = this.#normalizeSliderValue(rawValue);
5709
5705
  }
5710
5706
 
@@ -5772,12 +5768,7 @@ class FigSlider extends HTMLElement {
5772
5768
  this.input.removeEventListener("pointercancel", this.#boundRangePointerUp);
5773
5769
  this.input.addEventListener("pointercancel", this.#boundRangePointerUp);
5774
5770
 
5775
- if (this.default) {
5776
- this.style.setProperty(
5777
- "--default",
5778
- this.#calculateNormal(this.default),
5779
- );
5780
- }
5771
+ this.style.setProperty("--default", this.#calculateNormal(this.default));
5781
5772
 
5782
5773
  if (this.figInputNumber) {
5783
5774
  this.#syncTextInputA11yAttributes();
@@ -5864,6 +5855,7 @@ class FigSlider extends HTMLElement {
5864
5855
  this.input.setAttribute("list", this.datalist.getAttribute("id"));
5865
5856
  } else if (this.type === "stepper") {
5866
5857
  this.datalist = document.createElement("datalist");
5858
+ this.datalist.setAttribute("data-generated", "slider-stepper");
5867
5859
  this.datalist.setAttribute("id", figUniqueId());
5868
5860
  const steps = Math.min(
5869
5861
  1001,
@@ -5878,6 +5870,7 @@ class FigSlider extends HTMLElement {
5878
5870
  this.input.setAttribute("list", this.datalist.getAttribute("id"));
5879
5871
  } else if (this.type === "delta") {
5880
5872
  this.datalist = document.createElement("datalist");
5873
+ this.datalist.setAttribute("data-generated", "slider-delta");
5881
5874
  this.datalist.setAttribute("id", figUniqueId());
5882
5875
  let option = document.createElement("option");
5883
5876
  option.setAttribute("value", this.default);
@@ -5885,14 +5878,7 @@ class FigSlider extends HTMLElement {
5885
5878
  this.inputContainer.append(this.datalist);
5886
5879
  this.input.setAttribute("list", this.datalist.getAttribute("id"));
5887
5880
  }
5888
- if (this.datalist) {
5889
- const defaultOption = [...this.datalist.querySelectorAll("option")].find(
5890
- (option) => option.value === String(this.default),
5891
- );
5892
- if (defaultOption) {
5893
- defaultOption.setAttribute("default", "true");
5894
- }
5895
- }
5881
+ this.#syncDefaultDatalist();
5896
5882
  this.#syncValue();
5897
5883
  }
5898
5884
 
@@ -5938,6 +5924,10 @@ class FigSlider extends HTMLElement {
5938
5924
  if (this.input) this.#syncProperties();
5939
5925
  }
5940
5926
 
5927
+ get defaultValue() {
5928
+ return this.#resolveDefaultValue();
5929
+ }
5930
+
5941
5931
  disconnectedCallback() {
5942
5932
  this.#pendingRegeneration = false;
5943
5933
  if (this.input) {
@@ -5998,6 +5988,28 @@ class FigSlider extends HTMLElement {
5998
5988
  const { min, max } = this.#getBounds();
5999
5989
  return Math.min(max, Math.max(min, value));
6000
5990
  }
5991
+ #isStepAligned(value) {
5992
+ const { min } = this.#getBounds();
5993
+ const step = this.#toFiniteNumber(this.step);
5994
+ if (!(step > 0)) return true;
5995
+ const steps = (value - min) / step;
5996
+ const nearest = Math.round(steps);
5997
+ const tolerance = Number.EPSILON * Math.max(1, Math.abs(steps)) * 16;
5998
+ return Math.abs(steps - nearest) <= tolerance;
5999
+ }
6000
+ #resolveDefaultValue(rawDefault = this.getAttribute("default")) {
6001
+ const { min, max } = this.#getBounds();
6002
+ const parsed = this.#toFiniteNumber(rawDefault);
6003
+ const isValid =
6004
+ parsed !== null &&
6005
+ parsed >= min &&
6006
+ parsed <= max &&
6007
+ (this.type !== "stepper" || this.#isStepAligned(parsed));
6008
+ if (isValid) return parsed;
6009
+ return this.type === "delta"
6010
+ ? Math.min(max, Math.max(min, 0))
6011
+ : min;
6012
+ }
6001
6013
  #getFallbackValue() {
6002
6014
  if (this.type === "delta") {
6003
6015
  const deltaDefault = this.#toFiniteNumber(this.default);
@@ -6163,10 +6175,13 @@ class FigSlider extends HTMLElement {
6163
6175
  }
6164
6176
  if (!this.hasAttribute("default") && this.type !== "delta") {
6165
6177
  this.default = this.min;
6178
+ } else {
6179
+ this.default = this.#resolveDefaultValue();
6166
6180
  }
6167
6181
  this.value = this.#normalizeSliderValue(this.value);
6168
6182
  this.#syncProperties();
6169
6183
  this.#syncStepperDatalist();
6184
+ this.#syncDefaultDatalist();
6170
6185
  }
6171
6186
 
6172
6187
  #syncStepperDatalist() {
@@ -6183,6 +6198,25 @@ class FigSlider extends HTMLElement {
6183
6198
  }
6184
6199
  this.datalist.replaceChildren(fragment);
6185
6200
  this.input.setAttribute("list", this.datalist.id);
6201
+ this.#syncDefaultDatalist();
6202
+ }
6203
+
6204
+ #syncDefaultDatalist() {
6205
+ if (!this.datalist) return;
6206
+ const defaultValue = String(this.default);
6207
+ const options = [...this.datalist.querySelectorAll("option")];
6208
+ options.forEach((option) => option.removeAttribute("default"));
6209
+ let defaultOption = options.find((option) => option.value === defaultValue);
6210
+ if (
6211
+ !defaultOption &&
6212
+ this.type === "delta" &&
6213
+ this.datalist.getAttribute("data-generated") === "slider-delta"
6214
+ ) {
6215
+ defaultOption = document.createElement("option");
6216
+ defaultOption.value = defaultValue;
6217
+ this.datalist.replaceChildren(defaultOption);
6218
+ }
6219
+ defaultOption?.setAttribute("default", "true");
6186
6220
  }
6187
6221
 
6188
6222
  #regenerateWhenIdle() {
@@ -6272,9 +6306,9 @@ class FigSlider extends HTMLElement {
6272
6306
  }
6273
6307
  break;
6274
6308
  case "default":
6275
- this.default =
6276
- newValue !== null ? newValue : this.type === "delta" ? 0 : this.min;
6309
+ this.default = this.#resolveDefaultValue(newValue);
6277
6310
  this.#syncProperties();
6311
+ this.#syncDefaultDatalist();
6278
6312
  break;
6279
6313
  case "min":
6280
6314
  case "max":
@@ -16850,6 +16884,7 @@ class FigGroup extends HTMLElement {
16850
16884
 
16851
16885
  attributeChangedCallback(name, oldValue, newValue) {
16852
16886
  if (oldValue === newValue) return;
16887
+ if (!this.isConnected) return;
16853
16888
  if (name === "open") {
16854
16889
  this.#header?.setAttribute("aria-expanded", String(this.open));
16855
16890
  return;
@@ -16898,7 +16933,9 @@ class FigGroup extends HTMLElement {
16898
16933
  const label = nameAttr || (isCollapsible ? "Group" : null);
16899
16934
 
16900
16935
  // Check if user supplied their own fig-header
16901
- const userHeader = this.querySelector(":scope > fig-header");
16936
+ const userHeader = this.querySelector(
16937
+ ":scope > fig-header:not([data-generated])",
16938
+ );
16902
16939
 
16903
16940
  if (!label && !isCollapsible && !userHeader) {
16904
16941
  if (this.#header && this.#header.dataset.generated) {
@@ -16910,6 +16947,9 @@ class FigGroup extends HTMLElement {
16910
16947
  }
16911
16948
 
16912
16949
  if (userHeader) {
16950
+ this.querySelectorAll(":scope > fig-header[data-generated]").forEach(
16951
+ (header) => header.remove(),
16952
+ );
16913
16953
  this.#header = userHeader;
16914
16954
  } else if (!this.#header || !this.#header.dataset.generated) {
16915
16955
  this.#header = document.createElement("fig-header");
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@rogieking/figui3",
3
- "version": "8.9.29",
3
+ "version": "8.9.30",
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",