@rogieking/figui3 6.23.2 → 6.23.4

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
@@ -1685,6 +1685,10 @@ class PropskitSlider extends HTMLElement {
1685
1685
 
1686
1686
  for (const mutation of mutations) {
1687
1687
  if (mutation.type === "attributes") {
1688
+ if (mutation.attributeName === "value") {
1689
+ this.#pushExternalValueToSlider();
1690
+ continue;
1691
+ }
1688
1692
  if (
1689
1693
  mutation.attributeName &&
1690
1694
  this.#ignoredSliderAttrs.has(mutation.attributeName)
@@ -1822,7 +1826,9 @@ class PropskitSlider extends HTMLElement {
1822
1826
  if (!this.#slider) return;
1823
1827
  const hostAttrs = this.#getForwardedSliderAttrNames();
1824
1828
 
1825
- const nextManaged = new Set(hostAttrs.filter((name) => name !== "text"));
1829
+ const nextManaged = new Set(
1830
+ hostAttrs.filter((name) => name !== "text" && name !== "value"),
1831
+ );
1826
1832
 
1827
1833
  for (const attrName of this.#managedSliderAttrs) {
1828
1834
  if (!nextManaged.has(attrName)) {
@@ -1831,7 +1837,7 @@ class PropskitSlider extends HTMLElement {
1831
1837
  }
1832
1838
 
1833
1839
  for (const attrName of hostAttrs) {
1834
- if (attrName === "text") continue;
1840
+ if (attrName === "text" || attrName === "value") continue;
1835
1841
  const value = this.getAttribute(attrName) ?? "";
1836
1842
  if (this.#slider.getAttribute(attrName) !== value) {
1837
1843
  this.#slider.setAttribute(attrName, value);
@@ -1868,9 +1874,18 @@ class PropskitSlider extends HTMLElement {
1868
1874
  }
1869
1875
 
1870
1876
  this.#managedSliderAttrs = nextManaged;
1877
+ this.#pushExternalValueToSlider();
1871
1878
  this.#queueSteppersSync();
1872
1879
  }
1873
1880
 
1881
+ #pushExternalValueToSlider() {
1882
+ if (!this.#slider) return;
1883
+ const next = this.getAttribute("value") ?? "";
1884
+ if (String(this.#slider.value) !== next) {
1885
+ this.#slider.value = next;
1886
+ }
1887
+ }
1888
+
1874
1889
  #getForwardedSliderAttrNames() {
1875
1890
  const reserved = new Set([
1876
1891
  "label",
@@ -1977,9 +1992,6 @@ class PropskitSlider extends HTMLElement {
1977
1992
 
1978
1993
  #handleElasticPointerDown(event) {
1979
1994
  if (event.button !== 0 || figLabBooleanAttribute(this, "disabled")) return;
1980
- if (!event.target?.closest?.("fig-input-number, fig-menu")) {
1981
- this.#queueRangeFocus();
1982
- }
1983
1995
  if (this.getAttribute("elastic") === "false") return;
1984
1996
  if (event.target?.closest?.("fig-input-number")) return;
1985
1997
  const rangeInput =
@@ -2031,8 +2043,12 @@ class PropskitSlider extends HTMLElement {
2031
2043
  ) {
2032
2044
  return;
2033
2045
  }
2046
+ const shouldFocus =
2047
+ event?.type === "pointerup" ||
2048
+ (event?.type === "pointermove" && event.buttons === 0);
2034
2049
  this.#stopElasticTracking();
2035
2050
  this.#resetElasticPull();
2051
+ if (shouldFocus) this.#queueRangeFocus();
2036
2052
  }
2037
2053
 
2038
2054
  #stopElasticTracking() {
@@ -2258,7 +2274,10 @@ class PropskitSlider extends HTMLElement {
2258
2274
  ? event.detail
2259
2275
  : this.#slider?.value;
2260
2276
  if (this.#slider?.value !== undefined) {
2261
- this.setAttribute("value", String(this.#slider.value));
2277
+ const next = String(this.#slider.value);
2278
+ if (this.getAttribute("value") !== next) {
2279
+ this.setAttribute("value", next);
2280
+ }
2262
2281
  }
2263
2282
  this.dispatchEvent(
2264
2283
  new CustomEvent(type, {
package/fig.js CHANGED
@@ -6282,6 +6282,7 @@ figDefineElement("fig-select", FigSelect);
6282
6282
  */
6283
6283
  class FigSlider extends HTMLElement {
6284
6284
  #isInteracting = false;
6285
+ #pendingRegeneration = false;
6285
6286
  #showEmptyTextValue = false;
6286
6287
  #isSyncingValueAttribute = false;
6287
6288
  #value = "";
@@ -6347,6 +6348,10 @@ class FigSlider extends HTMLElement {
6347
6348
  };
6348
6349
  this.#boundRangePointerUp = () => {
6349
6350
  this.#isInteracting = false;
6351
+ if (this.#pendingRegeneration && this.isConnected) {
6352
+ this.#pendingRegeneration = false;
6353
+ this.#regenerateInnerHTML();
6354
+ }
6350
6355
  };
6351
6356
  }
6352
6357
 
@@ -6616,6 +6621,7 @@ class FigSlider extends HTMLElement {
6616
6621
  }
6617
6622
 
6618
6623
  disconnectedCallback() {
6624
+ this.#pendingRegeneration = false;
6619
6625
  if (this.input) {
6620
6626
  this.input.removeEventListener("input", this.#boundHandleInput);
6621
6627
  this.input.removeEventListener("change", this.#boundHandleChange);
@@ -6828,6 +6834,62 @@ class FigSlider extends HTMLElement {
6828
6834
  }
6829
6835
  }
6830
6836
 
6837
+ #syncRangeConstraint(name, rawValue) {
6838
+ if (!this.input) return;
6839
+ const defaults = this.#typeDefaults[this.type] || this.#typeDefaults.range;
6840
+ const parsed =
6841
+ rawValue === null || String(rawValue).trim() === ""
6842
+ ? defaults[name]
6843
+ : Number(rawValue);
6844
+ let next = Number.isFinite(parsed) ? parsed : defaults[name];
6845
+ if (name === "step" && !(next > 0)) {
6846
+ next = defaults.step > 0 ? defaults.step : 1;
6847
+ }
6848
+ if (this[name] === next && this.input[name] === String(next)) return;
6849
+
6850
+ this[name] = next;
6851
+ this.input[name] = String(next);
6852
+ if (name === "min") {
6853
+ this.input.setAttribute("aria-valuemin", String(next));
6854
+ } else if (name === "max") {
6855
+ this.input.setAttribute("aria-valuemax", String(next));
6856
+ }
6857
+ if (this.figInputNumber) {
6858
+ this.figInputNumber.setAttribute(name, String(next));
6859
+ }
6860
+ if (!this.hasAttribute("default") && this.type !== "delta") {
6861
+ this.default = this.min;
6862
+ }
6863
+ this.value = this.#normalizeSliderValue(this.value);
6864
+ this.#syncProperties();
6865
+ this.#syncStepperDatalist();
6866
+ }
6867
+
6868
+ #syncStepperDatalist() {
6869
+ if (this.type !== "stepper" || !this.datalist) return;
6870
+ const steps = Math.min(
6871
+ 1001,
6872
+ Math.max(0, Math.floor((this.max - this.min) / this.step) + 1),
6873
+ );
6874
+ const fragment = document.createDocumentFragment();
6875
+ for (let i = 0; i < steps; i++) {
6876
+ const option = document.createElement("option");
6877
+ option.setAttribute("value", this.min + i * this.step);
6878
+ fragment.append(option);
6879
+ }
6880
+ this.datalist.replaceChildren(fragment);
6881
+ this.input.setAttribute("list", this.datalist.id);
6882
+ }
6883
+
6884
+ #regenerateWhenIdle() {
6885
+ if (this.#isInteracting) {
6886
+ this.#pendingRegeneration = true;
6887
+ return;
6888
+ }
6889
+ this.#pendingRegeneration = false;
6890
+ this.#regenerateInnerHTML();
6891
+ }
6892
+
6831
6893
  static get observedAttributes() {
6832
6894
  return [
6833
6895
  "value",
@@ -6862,6 +6924,7 @@ class FigSlider extends HTMLElement {
6862
6924
  }
6863
6925
 
6864
6926
  attributeChangedCallback(name, oldValue, newValue) {
6927
+ if (oldValue === newValue) return;
6865
6928
  if (name === "value" && this.#isSyncingValueAttribute) return;
6866
6929
  if (this.input) {
6867
6930
  switch (name) {
@@ -6922,15 +6985,26 @@ class FigSlider extends HTMLElement {
6922
6985
  case "min":
6923
6986
  case "max":
6924
6987
  case "step":
6988
+ this.#syncRangeConstraint(name, newValue);
6989
+ break;
6990
+ case "units":
6991
+ this.units = newValue || "";
6992
+ if (this.figInputNumber) {
6993
+ if (this.units) {
6994
+ this.figInputNumber.setAttribute("units", this.units);
6995
+ } else {
6996
+ this.figInputNumber.removeAttribute("units");
6997
+ }
6998
+ }
6999
+ break;
6925
7000
  case "type":
6926
7001
  case "variant":
6927
- case "units":
6928
- this[name] = newValue;
6929
- this.#regenerateInnerHTML();
7002
+ if (!this.#isInteracting) this[name] = newValue;
7003
+ this.#regenerateWhenIdle();
6930
7004
  break;
6931
7005
  case "text":
6932
- this.text = newValue !== "false";
6933
- this.#regenerateInnerHTML();
7006
+ if (!this.#isInteracting) this.text = newValue !== "false";
7007
+ this.#regenerateWhenIdle();
6934
7008
  break;
6935
7009
  case "aria-label":
6936
7010
  case "aria-labelledby":
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@rogieking/figui3",
3
- "version": "6.23.2",
3
+ "version": "6.23.4",
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",