@rogieking/figui3 6.27.0 → 6.28.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-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
 
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@rogieking/figui3",
3
- "version": "6.27.0",
3
+ "version": "6.28.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": "MIT",