@rogieking/figui3 9.4.13 → 10.0.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-editor.css CHANGED
@@ -824,11 +824,6 @@ fig-select-option {
824
824
  white-space: nowrap;
825
825
  text-align: left;
826
826
 
827
- /* Anonymous flex items cannot ellipsize; text-only options stay a block. */
828
- &:not(:has(> :not([slot="prepend"]):not([slot="append"]))) {
829
- display: block;
830
- }
831
-
832
827
  h3{
833
828
  margin: 0 0 var(--spacer-1) 0;
834
829
  overflow: hidden;
package/fig-editor.js CHANGED
@@ -397,7 +397,6 @@ class FigSelectOptions extends HTMLElement {
397
397
  connectedCallback() {
398
398
  if (!this.hasAttribute("slot")) this.setAttribute("slot", "panel");
399
399
  this.#unwrapLegacyChooser();
400
- this.#markFirstSeparatorBorderless();
401
400
  this.#ensureNavButtons();
402
401
  this.addEventListener("scroll", this.#boundSyncOverflow, { passive: true });
403
402
  this.#resizeObserver?.disconnect();
@@ -423,7 +422,6 @@ class FigSelectOptions extends HTMLElement {
423
422
  }
424
423
 
425
424
  syncOverflow() {
426
- this.#markFirstSeparatorBorderless();
427
425
  return figEditorSyncOverflowState(this, this, "y");
428
426
  }
429
427
 
@@ -440,15 +438,6 @@ class FigSelectOptions extends HTMLElement {
440
438
  chooser.remove();
441
439
  }
442
440
 
443
- #markFirstSeparatorBorderless() {
444
- const firstContent = Array.from(this.children).find(
445
- (child) => !child.hasAttribute("data-fig-select-nav"),
446
- );
447
- if (firstContent?.tagName === "FIG-SEPARATOR") {
448
- firstContent.setAttribute("borderless", "");
449
- }
450
- }
451
-
452
441
  #ensureNavButtons() {
453
442
  if (
454
443
  this.#navStart &&
package/fig.js CHANGED
@@ -229,8 +229,8 @@ fig-select-options > :not(.fig-overflow),
229
229
  .fig-menu-options > :not(.fig-overflow) {
230
230
  flex-shrink: 0;
231
231
  }
232
- fig-select-options > :nth-child(1 of :not(.fig-overflow)),
233
- .fig-menu-options > :nth-child(1 of :not(.fig-overflow)) {
232
+ fig-select-options > :nth-child(1 of :not(.fig-overflow)):not(:is(fig-separator, fig-menu-separator):has(> label)),
233
+ .fig-menu-options > :nth-child(1 of :not(.fig-overflow)):not(:is(fig-separator, fig-menu-separator):has(> label)) {
234
234
  margin-top: var(--spacer-2);
235
235
  }
236
236
  fig-select-options > :not(.fig-overflow):last-child,
@@ -21637,12 +21637,12 @@ figDefineElement("fig-menu-item", FigMenuItem);
21637
21637
  * Visual divider between content groups.
21638
21638
  * @attr {string} label - Optional group label shown in secondary text under the line.
21639
21639
  * @attr {string} direction - Orientation: "vertical" for a tall rule; default is horizontal.
21640
- * @attr {boolean} borderless - Hides the separator line when present or "true".
21641
21640
  * @attr {boolean} sticky - Stick to the top of the nearest scrollport while scrolling.
21642
21641
  */
21643
21642
  class FigSeparator extends HTMLElement {
21644
21643
  #scrollRoot = null;
21645
21644
  #resizeObserver = null;
21645
+ #labelObserver = null;
21646
21646
  #boundSyncStuck = this.#syncStuck.bind(this);
21647
21647
 
21648
21648
  static get observedAttributes() {
@@ -21660,10 +21660,13 @@ class FigSeparator extends HTMLElement {
21660
21660
 
21661
21661
  connectedCallback() {
21662
21662
  this.#sync();
21663
+ this.#bindLabelObserver();
21663
21664
  this.#bindStuck();
21664
21665
  }
21665
21666
 
21666
21667
  disconnectedCallback() {
21668
+ this.#labelObserver?.disconnect();
21669
+ this.#labelObserver = null;
21667
21670
  this.#unbindStuck();
21668
21671
  }
21669
21672
 
@@ -21684,10 +21687,46 @@ class FigSeparator extends HTMLElement {
21684
21687
  this.setAttribute("aria-orientation", "horizontal");
21685
21688
  }
21686
21689
  const label = this.label.trim();
21687
- if (label) this.setAttribute("aria-label", label);
21690
+ const childLabels = Array.from(this.children).filter(
21691
+ (child) => child.localName === "label",
21692
+ );
21693
+ const authoredLabel = childLabels.find(
21694
+ (child) => !child.hasAttribute("data-fig-separator-generated"),
21695
+ );
21696
+ const generatedLabels = childLabels.filter((child) =>
21697
+ child.hasAttribute("data-fig-separator-generated"),
21698
+ );
21699
+
21700
+ if (authoredLabel) {
21701
+ generatedLabels.forEach((child) => child.remove());
21702
+ } else if (label) {
21703
+ const generatedLabel =
21704
+ generatedLabels[0] ?? document.createElement("label");
21705
+ generatedLabels.slice(1).forEach((child) => child.remove());
21706
+ generatedLabel.setAttribute("data-fig-separator-generated", "");
21707
+ if (generatedLabel.textContent !== label) {
21708
+ generatedLabel.textContent = label;
21709
+ }
21710
+ if (!generatedLabel.parentElement) this.appendChild(generatedLabel);
21711
+ } else {
21712
+ generatedLabels.forEach((child) => child.remove());
21713
+ }
21714
+
21715
+ const accessibleLabel = authoredLabel?.textContent?.trim() || label;
21716
+ if (accessibleLabel) this.setAttribute("aria-label", accessibleLabel);
21688
21717
  else this.removeAttribute("aria-label");
21689
21718
  }
21690
21719
 
21720
+ #bindLabelObserver() {
21721
+ this.#labelObserver?.disconnect();
21722
+ this.#labelObserver = new MutationObserver(() => this.#sync());
21723
+ this.#labelObserver.observe(this, {
21724
+ childList: true,
21725
+ characterData: true,
21726
+ subtree: true,
21727
+ });
21728
+ }
21729
+
21691
21730
  #isSticky() {
21692
21731
  return this.hasAttribute("sticky") && this.getAttribute("sticky") !== "false";
21693
21732
  }
@@ -22060,15 +22099,7 @@ class FigMenu extends HTMLElement {
22060
22099
  this.#removeNavButtons();
22061
22100
  }
22062
22101
 
22063
- #markFirstSeparatorBorderless() {
22064
- const first = Array.from(this.children).find((child) => figIsMenuChild(child));
22065
- if (first && (first.tagName === "FIG-SEPARATOR" || first.tagName === "FIG-MENU-SEPARATOR")) {
22066
- first.setAttribute("borderless", "");
22067
- }
22068
- }
22069
-
22070
22102
  #syncOverflow() {
22071
- this.#markFirstSeparatorBorderless();
22072
22103
  const scrollable = figSyncOverflowState(this.#panel, this.#panel, "y");
22073
22104
  this.classList.toggle(
22074
22105
  "overflow-start",
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@rogieking/figui3",
3
- "version": "9.4.13",
3
+ "version": "10.0.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": "SEE LICENSE IN LICENSE",