@rogieking/figui3 6.27.0 → 6.28.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/fig-lab.js CHANGED
@@ -724,6 +724,7 @@ class PropskitSelect extends HTMLElement {
724
724
  #managedSelectAttrs = new Set();
725
725
  #boundHandleInput = null;
726
726
  #boundHandleChange = null;
727
+ #boundHandleOptionHover = null;
727
728
  #boundHandleClick = this.#handleClick.bind(this);
728
729
  #boundHandlePointerDown = this.#handlePointerDown.bind(this);
729
730
  /** True when pointerdown saw the menu open — skip click-to-open after light-dismiss. */
@@ -883,8 +884,13 @@ class PropskitSelect extends HTMLElement {
883
884
  if (!this.#select) return;
884
885
  this.#boundHandleInput ??= this.#forwardSelectEvent.bind(this, "input");
885
886
  this.#boundHandleChange ??= this.#forwardSelectEvent.bind(this, "change");
887
+ this.#boundHandleOptionHover ??= this.#forwardSelectEvent.bind(
888
+ this,
889
+ "optionhover",
890
+ );
886
891
  this.#select.addEventListener("input", this.#boundHandleInput);
887
892
  this.#select.addEventListener("change", this.#boundHandleChange);
893
+ this.#select.addEventListener("optionhover", this.#boundHandleOptionHover);
888
894
  }
889
895
 
890
896
  #unbindSelectEvents() {
@@ -895,13 +901,19 @@ class PropskitSelect extends HTMLElement {
895
901
  if (this.#boundHandleChange) {
896
902
  this.#select.removeEventListener("change", this.#boundHandleChange);
897
903
  }
904
+ if (this.#boundHandleOptionHover) {
905
+ this.#select.removeEventListener(
906
+ "optionhover",
907
+ this.#boundHandleOptionHover,
908
+ );
909
+ }
898
910
  }
899
911
 
900
912
  #forwardSelectEvent(type, event) {
901
913
  if (event.target !== this.#select) return;
902
914
  event.stopImmediatePropagation();
903
915
  const value = this.#select?.value ?? "";
904
- this.setAttribute("value", String(value));
916
+ if (type !== "optionhover") this.setAttribute("value", String(value));
905
917
  const detail =
906
918
  event instanceof CustomEvent && event.detail !== undefined
907
919
  ? event.detail
package/fig.js CHANGED
@@ -5349,6 +5349,7 @@ class FigSelect extends HTMLElement {
5349
5349
  #syncingOptions = false;
5350
5350
  #boundTriggerClick = this.#handleTriggerClick.bind(this);
5351
5351
  #boundOptionClick = this.#handleOptionClick.bind(this);
5352
+ #boundOptionPointerOver = this.#handleOptionPointerOver.bind(this);
5352
5353
  #boundKeydown = this.#handleKeydown.bind(this);
5353
5354
  #boundPopupClose = this.#handlePopupClose.bind(this);
5354
5355
  #boundSlotChange = this.#handleSlotChange.bind(this);
@@ -5855,6 +5856,7 @@ class FigSelect extends HTMLElement {
5855
5856
  this.#button?.addEventListener("keydown", this.#boundKeydown);
5856
5857
  // Host click: slotted options stay in light DOM (not dialog.contains).
5857
5858
  this.addEventListener("click", this.#boundOptionClick);
5859
+ this.addEventListener("pointerover", this.#boundOptionPointerOver);
5858
5860
  this.#popup?.addEventListener("keydown", this.#boundKeydown);
5859
5861
  this.#popup?.addEventListener("close", this.#boundPopupClose);
5860
5862
  this.#panelSlot?.addEventListener("slotchange", this.#boundSlotChange);
@@ -5864,6 +5866,7 @@ class FigSelect extends HTMLElement {
5864
5866
  this.#button?.removeEventListener("click", this.#boundTriggerClick);
5865
5867
  this.#button?.removeEventListener("keydown", this.#boundKeydown);
5866
5868
  this.removeEventListener("click", this.#boundOptionClick);
5869
+ this.removeEventListener("pointerover", this.#boundOptionPointerOver);
5867
5870
  this.#popup?.removeEventListener("keydown", this.#boundKeydown);
5868
5871
  this.#popup?.removeEventListener("close", this.#boundPopupClose);
5869
5872
  this.#panelSlot?.removeEventListener("slotchange", this.#boundSlotChange);
@@ -6113,6 +6116,32 @@ class FigSelect extends HTMLElement {
6113
6116
  this.#selectOption(option);
6114
6117
  }
6115
6118
 
6119
+ /**
6120
+ * Fires `optionhover` with the enabled option's value in `event.detail`
6121
+ * without changing the current selection.
6122
+ */
6123
+ #handleOptionPointerOver(e) {
6124
+ const path = typeof e.composedPath === "function" ? e.composedPath() : [];
6125
+ const option = path.find(
6126
+ (node) => node?.tagName === "FIG-SELECT-OPTION",
6127
+ );
6128
+ if (!option || !this.contains(option)) return;
6129
+ if (figBooleanAttribute(option, "disabled")) return;
6130
+ if (
6131
+ e.relatedTarget instanceof Node &&
6132
+ option.contains(e.relatedTarget)
6133
+ ) {
6134
+ return;
6135
+ }
6136
+ this.dispatchEvent(
6137
+ new CustomEvent("optionhover", {
6138
+ detail: this.#optionValue(option),
6139
+ bubbles: true,
6140
+ composed: true,
6141
+ }),
6142
+ );
6143
+ }
6144
+
6116
6145
  #handleKeydown(e) {
6117
6146
  if (e.currentTarget === document && e.key !== "Escape") return;
6118
6147
 
@@ -10958,6 +10987,7 @@ class FigInputGradient extends HTMLElement {
10958
10987
  #arrowTooltipTimer = null;
10959
10988
  #colorObserver = null;
10960
10989
  #repositionRAF = null;
10990
+ #pickerDefinitionPromise = null;
10961
10991
  #gradient = {
10962
10992
  type: "linear",
10963
10993
  angle: 90,
@@ -11031,11 +11061,22 @@ class FigInputGradient extends HTMLElement {
11031
11061
  connectedCallback() {
11032
11062
  this.#parseValue();
11033
11063
  this.#render();
11064
+ this.#renderPickerWhenAvailable();
11034
11065
  this.removeEventListener("keydown", this.#onPickerKeyDown);
11035
11066
  this.addEventListener("keydown", this.#onPickerKeyDown);
11036
11067
  if (this.#isEditable) document.addEventListener("keydown", this.#onKeyDown);
11037
11068
  }
11038
11069
 
11070
+ #renderPickerWhenAvailable() {
11071
+ if (this.#editMode !== "picker" || hasFigFillPicker()) return;
11072
+ this.#pickerDefinitionPromise ??= customElements
11073
+ .whenDefined("fig-fill-picker")
11074
+ .then(() => {
11075
+ if (!this.isConnected || this.#editMode !== "picker") return;
11076
+ this.#render();
11077
+ });
11078
+ }
11079
+
11039
11080
  disconnectedCallback() {
11040
11081
  document.removeEventListener("keydown", this.#onKeyDown);
11041
11082
  this.removeEventListener("keydown", this.#onPickerKeyDown);
@@ -11822,6 +11863,7 @@ class FigInputGradient extends HTMLElement {
11822
11863
  break;
11823
11864
  case "edit":
11824
11865
  this.#render();
11866
+ this.#renderPickerWhenAvailable();
11825
11867
  if (this.#isEditable) {
11826
11868
  document.addEventListener("keydown", this.#onKeyDown);
11827
11869
  } else {
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@rogieking/figui3",
3
- "version": "6.27.0",
3
+ "version": "6.28.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",