@rogieking/figui3 2.17.2 → 2.17.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/components.css CHANGED
@@ -2060,6 +2060,20 @@ dialog[is="fig-popup"] {
2060
2060
  display: block;
2061
2061
  }
2062
2062
 
2063
+ &[theme="dark"] {
2064
+ color-scheme: dark;
2065
+ }
2066
+
2067
+ &[theme="light"] {
2068
+ color-scheme: light;
2069
+ }
2070
+
2071
+ &[theme="menu"] {
2072
+ background-color: var(--figma-color-bg-menu);
2073
+ color: var(--figma-color-text-menu);
2074
+ color-scheme: dark;
2075
+ }
2076
+
2063
2077
  &[variant="popover"] {
2064
2078
  overflow: visible;
2065
2079
  box-shadow: inset 0 0.5px 0 0 rgba(255, 255, 255, 0.1);
package/fig.js CHANGED
@@ -1057,6 +1057,7 @@ customElements.define("fig-dialog", FigDialog, { extends: "dialog" });
1057
1057
  * @attr {string} position - Preferred placement as "vertical horizontal" (default: "top center").
1058
1058
  * @attr {string} offset - Horizontal and vertical offset as "x y" (default: "0 0").
1059
1059
  * @attr {string} variant - Visual variant. Use variant="popover" to show an anchor beak.
1060
+ * @attr {string} theme - Visual theme: "light", "dark", or "menu".
1060
1061
  * @attr {boolean|string} open - Open when present and not "false".
1061
1062
  */
1062
1063
  class FigPopup extends HTMLDialogElement {
@@ -1078,7 +1079,7 @@ class FigPopup extends HTMLDialogElement {
1078
1079
  }
1079
1080
 
1080
1081
  static get observedAttributes() {
1081
- return ["open", "anchor", "position", "offset", "variant"];
1082
+ return ["open", "anchor", "position", "offset", "variant", "theme"];
1082
1083
  }
1083
1084
 
1084
1085
  get open() {
@@ -4539,18 +4540,37 @@ customElements.define("fig-toast", FigToast, { extends: "dialog" });
4539
4540
  * @attr {string} value - The current input value
4540
4541
  */
4541
4542
  class FigComboInput extends HTMLElement {
4543
+ #usesCustomDropdown = false;
4544
+ #boundHandleSelectInput = null;
4545
+
4542
4546
  constructor() {
4543
4547
  super();
4548
+ this.#boundHandleSelectInput = this.handleSelectInput.bind(this);
4544
4549
  }
4545
4550
  getOptionsFromAttribute() {
4546
4551
  return (this.getAttribute("options") || "").split(",");
4547
4552
  }
4548
4553
  connectedCallback() {
4554
+ const customDropdown =
4555
+ Array.from(this.children).find((child) => child.tagName === "FIG-DROPDOWN") ||
4556
+ null;
4557
+ this.#usesCustomDropdown = customDropdown !== null;
4558
+ if (customDropdown) {
4559
+ customDropdown.remove();
4560
+ }
4561
+
4549
4562
  this.options = this.getOptionsFromAttribute();
4550
4563
  this.placeholder = this.getAttribute("placeholder") || "";
4551
4564
  this.value = this.getAttribute("value") || "";
4552
4565
  const experimental = this.getAttribute("experimental");
4553
4566
  const expAttr = experimental ? `experimental="${experimental}"` : "";
4567
+ const dropdownHTML = this.#usesCustomDropdown
4568
+ ? ""
4569
+ : `<fig-dropdown type="dropdown" ${expAttr}>
4570
+ ${this.options
4571
+ .map((option) => `<option>${option}</option>`)
4572
+ .join("")}
4573
+ </fig-dropdown>`;
4554
4574
  this.innerHTML = `<div class="input-combo">
4555
4575
  <fig-input-text placeholder="${this.placeholder}">
4556
4576
  </fig-input-text>
@@ -4558,21 +4578,30 @@ class FigComboInput extends HTMLElement {
4558
4578
  <svg width='16' height='16' viewBox='0 0 16 16' fill='none' xmlns='http://www.w3.org/2000/svg'>
4559
4579
  <path d='M5.87868 7.12132L8 9.24264L10.1213 7.12132' stroke='currentColor' stroke-opacity="0.9" stroke-linecap='round'/>
4560
4580
  </svg>
4561
- <fig-dropdown type="dropdown" ${expAttr}>
4562
- ${this.options
4563
- .map((option) => `<option>${option}</option>`)
4564
- .join("")}
4565
- </fig-dropdown>
4581
+ ${dropdownHTML}
4566
4582
  </fig-button>
4567
4583
  </div>`;
4568
4584
  requestAnimationFrame(() => {
4569
4585
  this.input = this.querySelector("fig-input-text");
4586
+ const button = this.querySelector("fig-button");
4587
+
4588
+ if (this.#usesCustomDropdown && customDropdown && button) {
4589
+ if (!customDropdown.hasAttribute("type")) {
4590
+ customDropdown.setAttribute("type", "dropdown");
4591
+ }
4592
+ if (experimental) {
4593
+ customDropdown.setAttribute("experimental", experimental);
4594
+ }
4595
+ button.append(customDropdown);
4596
+ }
4570
4597
  this.dropdown = this.querySelector("fig-dropdown");
4571
4598
 
4572
- this.dropdown.addEventListener(
4573
- "input",
4574
- this.handleSelectInput.bind(this)
4575
- );
4599
+ this.dropdown?.removeEventListener("input", this.#boundHandleSelectInput);
4600
+ this.dropdown?.addEventListener("input", this.#boundHandleSelectInput);
4601
+
4602
+ if (this.input) {
4603
+ this.input.setAttribute("value", this.value);
4604
+ }
4576
4605
 
4577
4606
  // Apply initial disabled state
4578
4607
  if (this.hasAttribute("disabled")) {
@@ -4580,6 +4609,9 @@ class FigComboInput extends HTMLElement {
4580
4609
  }
4581
4610
  });
4582
4611
  }
4612
+ disconnectedCallback() {
4613
+ this.dropdown?.removeEventListener("input", this.#boundHandleSelectInput);
4614
+ }
4583
4615
  handleSelectInput(e) {
4584
4616
  this.setAttribute("value", e.target.closest("fig-dropdown").value);
4585
4617
  }
@@ -4613,7 +4645,7 @@ class FigComboInput extends HTMLElement {
4613
4645
  switch (name) {
4614
4646
  case "options":
4615
4647
  this.options = newValue.split(",");
4616
- if (this.dropdown) {
4648
+ if (this.dropdown && !this.#usesCustomDropdown) {
4617
4649
  this.dropdown.innerHTML = this.options
4618
4650
  .map((option) => `<option>${option}</option>`)
4619
4651
  .join("");
@@ -4638,7 +4670,7 @@ class FigComboInput extends HTMLElement {
4638
4670
  if (this.dropdown) {
4639
4671
  if (newValue) {
4640
4672
  this.dropdown.setAttribute("experimental", newValue);
4641
- } else {
4673
+ } else if (!this.#usesCustomDropdown) {
4642
4674
  this.dropdown.removeAttribute("experimental");
4643
4675
  }
4644
4676
  }
package/index.html CHANGED
@@ -2682,7 +2682,14 @@
2682
2682
 
2683
2683
  <h3>Popover Variant (with Arrow)</h3>
2684
2684
  <p class="description">Use <code>variant="popover"</code> to show the beak and automatically point it at the
2685
- anchor.</p>
2685
+ anchor. Use <code>theme="menu"</code> for menu-style dark surfaces.</p>
2686
+ <fig-segmented-control id="popup-theme-control">
2687
+ <fig-segment id="popup-theme-default">Default</fig-segment>
2688
+ <fig-segment id="popup-theme-dark">Dark</fig-segment>
2689
+ <fig-segment id="popup-theme-light">Light</fig-segment>
2690
+ <fig-segment id="popup-theme-menu"
2691
+ selected>Menu</fig-segment>
2692
+ </fig-segmented-control>
2686
2693
  <hstack>
2687
2694
  <fig-button id="popup-open-popover">Open Popover Variant</fig-button>
2688
2695
  <fig-button id="popup-close-popover"
@@ -2692,7 +2699,8 @@
2692
2699
  is="fig-popup"
2693
2700
  anchor="#popup-open-popover"
2694
2701
  position="top center"
2695
- variant="popover">
2702
+ variant="popover"
2703
+ theme="menu">
2696
2704
  <vstack style="min-width: 12rem;">
2697
2705
  <strong style="padding: 0 var(--spacer-1);">Popover Beak</strong>
2698
2706
  <fig-field direction="horizontal">
@@ -2705,7 +2713,8 @@
2705
2713
  &lt;dialog is="fig-popup"
2706
2714
  anchor="#popup-open-popover"
2707
2715
  position="top center"
2708
- variant="popover"&gt;
2716
+ variant="popover"
2717
+ theme="menu"&gt;
2709
2718
  ...
2710
2719
  &lt;/dialog&gt;</code></pre>
2711
2720
 
@@ -4166,6 +4175,8 @@ button.addEventListener('click', () => {
4166
4175
  const popupDefault = document.getElementById('popup-default');
4167
4176
  const popupPreferred = document.getElementById('popup-preferred');
4168
4177
  const popupProp = document.getElementById('popup-prop');
4178
+ const popupPopover = document.getElementById('popup-popover');
4179
+ const popupThemeControl = document.getElementById('popup-theme-control');
4169
4180
 
4170
4181
  document.getElementById('popup-open-default')?.addEventListener('click', () => {
4171
4182
  popupDefault?.setAttribute('open', 'true');
@@ -4188,6 +4199,23 @@ button.addEventListener('click', () => {
4188
4199
  if (popupProp) popupProp.open = false;
4189
4200
  });
4190
4201
 
4202
+ popupThemeControl?.addEventListener('click', () => {
4203
+ if (!popupPopover) return;
4204
+ if (document.getElementById('popup-theme-default')?.hasAttribute('selected')) {
4205
+ popupPopover.removeAttribute('theme');
4206
+ return;
4207
+ }
4208
+ if (document.getElementById('popup-theme-dark')?.hasAttribute('selected')) {
4209
+ popupPopover.setAttribute('theme', 'dark');
4210
+ return;
4211
+ }
4212
+ if (document.getElementById('popup-theme-light')?.hasAttribute('selected')) {
4213
+ popupPopover.setAttribute('theme', 'light');
4214
+ return;
4215
+ }
4216
+ popupPopover.setAttribute('theme', 'menu');
4217
+ });
4218
+
4191
4219
  const popupExamples = [
4192
4220
  ['popup-open-popover', 'popup-close-popover', 'popup-popover'],
4193
4221
  ['popup-open-top-left', 'popup-close-top-left', 'popup-top-left'],
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@rogieking/figui3",
3
- "version": "2.17.2",
3
+ "version": "2.17.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",