@stackone/malachite 2.47.0 → 2.47.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.
@@ -1,5 +1,5 @@
1
- import { jsx as e, jsxs as m, Fragment as bt } from "react/jsx-runtime";
2
- import Ot, { useState as F, useRef as x, useEffect as Pt, useCallback as Mt, useLayoutEffect as oe, useInsertionEffect as le, useId as se } from "react";
1
+ import { jsx as e, jsxs as x, Fragment as bt } from "react/jsx-runtime";
2
+ import Ot, { useState as F, useRef as g, useEffect as Pt, useCallback as Mt, useLayoutEffect as oe, useInsertionEffect as le, useId as se } from "react";
3
3
  import { createPortal as ce } from "react-dom";
4
4
  import de, { useFormFieldIds as ue } from "./BaseFormComponent.js";
5
5
  import Zt from "./CustomIcons/CaretDownIcon.js";
@@ -95,7 +95,7 @@ const Re = Ot.lazy(() => import("./ActionMenuTagHost.js")), Xt = ({ id: t, text:
95
95
  onArrowDown: y,
96
96
  onTabAway: k,
97
97
  size: E = "large",
98
- hasClear: v = !1,
98
+ hasClear: m = !1,
99
99
  onClear: P,
100
100
  clearLabel: W,
101
101
  controlId: i,
@@ -106,18 +106,18 @@ const Re = Ot.lazy(() => import("./ActionMenuTagHost.js")), Xt = ({ id: t, text:
106
106
  ariaLabelledBy: yt,
107
107
  hasCallerId: $ = !1
108
108
  }, wt) => {
109
- const O = T && !p && !!(r != null && r.subtitle), it = O ? ze[E] : De[E], at = Fe[E], G = `${i}-value`, St = `${i}-subtitle`, D = `${i}-tag`, ot = !p || u, H = ot && !!(r != null && r.triggerTag), lt = !ot && !t && !!(r != null && r.triggerTag), st = H ? `${G} ${D}` : G, ct = !c && !w && !$ && (O || H), b = yt ?? (c && !w ? `${c} ${st}` : void 0) ?? (ct ? st : void 0), R = H && !(b != null && b.split(" ").includes(D)), Tt = (l) => {
109
+ const O = T && !p && !!(r != null && r.subtitle), it = O ? ze[E] : De[E], at = Fe[E], G = `${i}-value`, St = `${i}-subtitle`, D = `${i}-tag`, ot = !p || u, H = ot && !!(r != null && r.triggerTag), lt = !ot && !t && !!(r != null && r.triggerTag), st = H ? `${G} ${D}` : G, ct = !c && !w && !$ && (O || H), v = yt ?? (c && !w ? `${c} ${st}` : void 0) ?? (ct ? st : void 0), R = H && !(v != null && v.split(" ").includes(D)), Tt = (l) => {
110
110
  if (l.key === "Tab") {
111
111
  k == null || k();
112
112
  return;
113
113
  }
114
114
  l.key === "ArrowDown" && (l.preventDefault(), y == null || y());
115
- }, j = x(null), J = x(null), z = ve({ disabled: u, error: d, tone: S, open: t }), dt = !t && !!r, K = (r == null ? void 0 : r.triggerLabel) ?? (r == null ? void 0 : r.label), g = O ? r == null ? void 0 : r.subtitle : void 0, I = () => xt(j.current), [tt, A] = F({ value: !1, subtitle: !0 }), Dt = () => {
115
+ }, j = g(null), J = g(null), z = ve({ disabled: u, error: d, tone: S, open: t }), dt = !t && !!r, K = (r == null ? void 0 : r.triggerLabel) ?? (r == null ? void 0 : r.label), b = O ? r == null ? void 0 : r.subtitle : void 0, I = () => xt(j.current), [tt, A] = F({ value: !1, subtitle: !0 }), Dt = () => {
116
116
  const l = I(), et = xt(J.current);
117
117
  return !l && !et ? !1 : (A({ value: l, subtitle: et }), !0);
118
118
  };
119
119
  if (p && !u)
120
- return /* @__PURE__ */ m(
120
+ return /* @__PURE__ */ x(
121
121
  "div",
122
122
  {
123
123
  ref: wt,
@@ -132,7 +132,7 @@ const Re = Ot.lazy(() => import("./ActionMenuTagHost.js")), Xt = ({ id: t, text:
132
132
  onClick: (l) => l.stopPropagation(),
133
133
  children: [
134
134
  (r == null ? void 0 : r.icon) && /* @__PURE__ */ e("span", { className: "flex shrink-0 items-center justify-center pr-2", children: r.icon }),
135
- /* @__PURE__ */ e($t, { text: K, shouldShow: I, isShrinkable: !0, fill: !0, children: /* @__PURE__ */ m("div", { className: "relative flex-1 flex items-center min-w-0", children: [
135
+ /* @__PURE__ */ e($t, { text: K, shouldShow: I, isShrinkable: !0, fill: !0, children: /* @__PURE__ */ x("div", { className: "relative flex-1 flex items-center min-w-0", children: [
136
136
  dt && /* @__PURE__ */ e(
137
137
  "span",
138
138
  {
@@ -174,11 +174,11 @@ const Re = Ot.lazy(() => import("./ActionMenuTagHost.js")), Xt = ({ id: t, text:
174
174
  }
175
175
  )
176
176
  ] }) }),
177
- lt && (r == null ? void 0 : r.triggerTag) && /* @__PURE__ */ m(bt, { children: [
177
+ lt && (r == null ? void 0 : r.triggerTag) && /* @__PURE__ */ x(bt, { children: [
178
178
  /* @__PURE__ */ e("span", { "aria-hidden": "true", className: "w-2 shrink-0" }),
179
179
  /* @__PURE__ */ e(Xt, { id: D, text: r.triggerTag })
180
180
  ] }),
181
- v && /* @__PURE__ */ e(
181
+ m && /* @__PURE__ */ e(
182
182
  "button",
183
183
  {
184
184
  type: "button",
@@ -217,19 +217,19 @@ const Re = Ot.lazy(() => import("./ActionMenuTagHost.js")), Xt = ({ id: t, text:
217
217
  ]
218
218
  }
219
219
  );
220
- const ut = /* @__PURE__ */ m(
220
+ const ut = /* @__PURE__ */ x(
221
221
  "button",
222
222
  {
223
223
  ref: wt,
224
224
  id: i,
225
225
  type: "button",
226
226
  "aria-label": w,
227
- "aria-labelledby": b,
227
+ "aria-labelledby": v,
228
228
  "aria-invalid": d || void 0,
229
229
  "aria-required": f || void 0,
230
230
  "aria-describedby": [
231
231
  o,
232
- g ? St : void 0,
232
+ b ? St : void 0,
233
233
  R ? D : void 0
234
234
  ].filter(Boolean).join(" ") || void 0,
235
235
  onClick: (l) => {
@@ -251,17 +251,17 @@ const Re = Ot.lazy(() => import("./ActionMenuTagHost.js")), Xt = ({ id: t, text:
251
251
  /* @__PURE__ */ e(
252
252
  "span",
253
253
  {
254
- id: g ? void 0 : G,
255
- className: `text-left ${H ? "flex-[1_1_auto]" : "flex-1"} min-w-0 flex ${g ? "flex-col gap-1" : "items-center gap-2"}`,
256
- children: r ? /* @__PURE__ */ m(bt, { children: [
257
- /* @__PURE__ */ m(Pe, { wrap: !!g, id: G, children: [
254
+ id: b ? void 0 : G,
255
+ className: `text-left ${H ? "flex-[1_1_auto]" : "flex-1"} min-w-0 flex ${b ? "flex-col gap-1" : "items-center gap-2"}`,
256
+ children: r ? /* @__PURE__ */ x(bt, { children: [
257
+ /* @__PURE__ */ x(Pe, { wrap: !!b, id: G, children: [
258
258
  r.icon && /* @__PURE__ */ e("span", { className: "flex items-center justify-center shrink-0", children: r.icon }),
259
259
  /* @__PURE__ */ e(
260
260
  $t,
261
261
  {
262
262
  text: K,
263
- shouldShow: g ? Qt : I,
264
- triggerAs: g ? "span" : "div",
263
+ shouldShow: b ? Qt : I,
264
+ triggerAs: "span",
265
265
  isShrinkable: !0,
266
266
  children: /* @__PURE__ */ e(
267
267
  "span",
@@ -274,13 +274,13 @@ const Re = Ot.lazy(() => import("./ActionMenuTagHost.js")), Xt = ({ id: t, text:
274
274
  }
275
275
  )
276
276
  ] }),
277
- g && /* @__PURE__ */ e(
277
+ b && /* @__PURE__ */ e(
278
278
  "span",
279
279
  {
280
280
  id: St,
281
281
  ref: J,
282
282
  className: "min-w-0 block truncate text-[length:var(--malachite-font-size-xsmall,11px)] text-[var(--malachite-text-secondary,rgb(123,123,123))] leading-normal",
283
- children: /* @__PURE__ */ e(mt, { text: g })
283
+ children: /* @__PURE__ */ e(mt, { text: b })
284
284
  }
285
285
  )
286
286
  ] }) : /* @__PURE__ */ e(
@@ -293,7 +293,7 @@ const Re = Ot.lazy(() => import("./ActionMenuTagHost.js")), Xt = ({ id: t, text:
293
293
  }
294
294
  ),
295
295
  (r == null ? void 0 : r.triggerTag) && /* @__PURE__ */ e(Xt, { id: D, text: r.triggerTag, disabled: u }),
296
- v && /* @__PURE__ */ e("span", { "aria-hidden": "true", className: "shrink-0 w-4" }),
296
+ m && /* @__PURE__ */ e("span", { "aria-hidden": "true", className: "shrink-0 w-4" }),
297
297
  /* @__PURE__ */ e("span", { className: "flex items-center justify-center shrink-0", children: /* @__PURE__ */ e(
298
298
  Zt,
299
299
  {
@@ -315,10 +315,10 @@ const Re = Ot.lazy(() => import("./ActionMenuTagHost.js")), Xt = ({ id: t, text:
315
315
  ["value", tt.value && K],
316
316
  [
317
317
  "subtitle",
318
- tt.subtitle && g && /* @__PURE__ */ e(mt, { text: g })
318
+ tt.subtitle && b && /* @__PURE__ */ e(mt, { text: b })
319
319
  ]
320
320
  ]),
321
- shouldShow: g ? Dt : Qt,
321
+ shouldShow: b ? Dt : Qt,
322
322
  fill: !0,
323
323
  describesTrigger: !1,
324
324
  children: ut
@@ -334,9 +334,9 @@ const Ge = ({
334
334
  subtitleLayout: u,
335
335
  onItemSelected: d
336
336
  }) => {
337
- const S = a ? "var(--malachite-accent-foreground, rgb(2, 122, 66))" : "var(--malachite-text-primary, rgb(10, 10, 10))", N = u === "stacked" && !!t.subtitle, p = `mal-${se().replace(/[^a-zA-Z0-9_-]/g, "")}`, T = `${p}-label`, L = `${p}-subtitle`, C = `${p}-badge`, _ = x(null), y = x(null), k = x(null), [E, v] = F({ label: !0, subtitle: !0, rightSide: !0 }), P = () => {
337
+ const S = a ? "var(--malachite-accent-foreground, rgb(2, 122, 66))" : "var(--malachite-text-primary, rgb(10, 10, 10))", N = u === "stacked" && !!t.subtitle, p = `mal-${se().replace(/[^a-zA-Z0-9_-]/g, "")}`, T = `${p}-label`, L = `${p}-subtitle`, C = `${p}-badge`, _ = g(null), y = g(null), k = g(null), [E, m] = F({ label: !0, subtitle: !0, rightSide: !0 }), P = () => {
338
338
  const o = xt(_.current), f = xt(y.current), w = xt(k.current);
339
- return !o && !f && !w ? !1 : (v({ label: o, subtitle: f, rightSide: w }), !0);
339
+ return !o && !f && !w ? !1 : (m({ label: o, subtitle: f, rightSide: w }), !0);
340
340
  }, W = t.rightSideTextVariant === "primary" ? "var(--malachite-text-right-side-text-primary, rgb(10, 10, 10))" : "var(--malachite-text-right-side-text-muted, rgb(123, 123, 123))", i = t.rightSideTextAlignment === "left" ? "flex-start" : "flex-end", c = (
341
341
  // `role="option"` would be invalid — nothing here declares a `listbox`, and an
342
342
  // orphaned option is dropped from the a11y tree. `aria-current`, not
@@ -376,7 +376,7 @@ const Ge = ({
376
376
  font: "inherit",
377
377
  color: "inherit"
378
378
  },
379
- children: /* @__PURE__ */ m(
379
+ children: /* @__PURE__ */ x(
380
380
  "span",
381
381
  {
382
382
  style: {
@@ -387,12 +387,12 @@ const Ge = ({
387
387
  minWidth: 0
388
388
  },
389
389
  children: [
390
- /* @__PURE__ */ e("span", { style: { flex: "1 1 auto", display: "block", minWidth: 0 }, children: /* @__PURE__ */ m(
390
+ /* @__PURE__ */ e("span", { style: { flex: "1 1 auto", display: "block", minWidth: 0 }, children: /* @__PURE__ */ x(
391
391
  "span",
392
392
  {
393
393
  style: N ? { display: "flex", flexDirection: "column", gap: 2 } : { display: "flex", alignItems: "center", gap: 8 },
394
394
  children: [
395
- /* @__PURE__ */ m(We, { row: N && !!t.icon, children: [
395
+ /* @__PURE__ */ x(We, { row: N && !!t.icon, children: [
396
396
  t.icon && /* @__PURE__ */ e(
397
397
  "span",
398
398
  {
@@ -438,7 +438,7 @@ const Ge = ({
438
438
  },
439
439
  children: /* @__PURE__ */ e(mt, { text: t.subtitle })
440
440
  }
441
- ) : /* @__PURE__ */ m(
441
+ ) : /* @__PURE__ */ x(
442
442
  "span",
443
443
  {
444
444
  style: {
@@ -556,20 +556,20 @@ const Ge = ({
556
556
  subtitleLayout: y,
557
557
  size: k,
558
558
  style: E
559
- } = t, v = x(null), P = _e("dropdown", !0, v);
559
+ } = t, m = g(null), P = _e("dropdown", !0, m);
560
560
  return le(() => {
561
561
  Ce();
562
- }, []), ke(v, !0), Pt(() => {
562
+ }, []), ke(m, !0), Pt(() => {
563
563
  var o;
564
564
  if (!p || !T)
565
565
  return;
566
- const i = Wt(v.current);
567
- (o = i.find((f) => f.dataset.selected === "true") ?? i[0] ?? v.current) == null || o.focus();
566
+ const i = Wt(m.current);
567
+ (o = i.find((f) => f.dataset.selected === "true") ?? i[0] ?? m.current) == null || o.focus();
568
568
  }, [p, T]), /* @__PURE__ */ e(
569
569
  "div",
570
570
  {
571
571
  ref: (i) => {
572
- v.current = i, typeof a == "function" ? a(i) : a && (a.current = i);
572
+ m.current = i, typeof a == "function" ? a(i) : a && (a.current = i);
573
573
  },
574
574
  ...P,
575
575
  tabIndex: -1,
@@ -579,7 +579,7 @@ const Ge = ({
579
579
  L();
580
580
  return;
581
581
  }
582
- const c = Wt(v.current);
582
+ const c = Wt(m.current);
583
583
  if (c.length === 0)
584
584
  return;
585
585
  const o = c.indexOf(document.activeElement), f = {
@@ -602,7 +602,7 @@ const Ge = ({
602
602
  fontSize: me[k],
603
603
  ...E
604
604
  },
605
- children: S ? /* @__PURE__ */ m("div", { style: Yt, children: [
605
+ children: S ? /* @__PURE__ */ x("div", { style: Yt, children: [
606
606
  /* @__PURE__ */ e(fe, { size: "xxxsmall" }),
607
607
  /* @__PURE__ */ e("span", { children: "Loading…" })
608
608
  ] }) : r.length === 0 ? /* @__PURE__ */ e("div", { style: Yt, children: N }) : /* @__PURE__ */ e(
@@ -619,7 +619,7 @@ const Ge = ({
619
619
  },
620
620
  children: r.map((i, c) => {
621
621
  const o = r[c - 1], f = !!i.group && (!o || o.group !== i.group);
622
- return /* @__PURE__ */ m("div", { style: { flexShrink: 0 }, children: [
622
+ return /* @__PURE__ */ x("div", { style: { flexShrink: 0 }, children: [
623
623
  f && /* @__PURE__ */ e(
624
624
  "div",
625
625
  {
@@ -668,7 +668,7 @@ const pr = ({
668
668
  required: y = !1,
669
669
  requiredIndicator: k,
670
670
  loading: E,
671
- menuLoading: v,
671
+ menuLoading: m,
672
672
  formControl: P,
673
673
  description: W,
674
674
  helperText: i,
@@ -692,11 +692,11 @@ const pr = ({
692
692
  description: W,
693
693
  hint: T,
694
694
  helperText: !0
695
- }), [b, R] = F(!1), [Tt, j] = F(r), J = u ?? Tt, z = t.find((n) => n.id === J), dt = yt && J !== void 0 && J !== "" && !d, K = f && !o && !!(z != null && z.subtitle), g = `Clear ${p ?? c ?? "selection"}`, I = x(r);
695
+ }), [v, R] = F(!1), [Tt, j] = F(r), J = u ?? Tt, z = t.find((n) => n.id === J), dt = yt && J !== void 0 && J !== "" && !d, K = f && !o && !!(z != null && z.subtitle), b = `Clear ${p ?? c ?? "selection"}`, I = g(r);
696
696
  Pt(() => {
697
697
  I.current !== r && (I.current = r, j(r));
698
698
  }, [r]);
699
- const [tt, A] = F(""), [Dt, ut] = F(!1), [l, et] = F(!1), zt = x(null), Et = x(null), B = x(null), [h, Gt] = F(null), Nt = x(!0), Z = Mt(() => {
699
+ const [tt, A] = F(""), [Dt, ut] = F(!1), [l, et] = F(!1), zt = g(null), Et = g(null), B = g(null), [h, Gt] = F(null), Nt = g(!0), Z = Mt(() => {
700
700
  const n = Et.current, s = n instanceof HTMLButtonElement ? n : (n == null ? void 0 : n.querySelector("input")) ?? null;
701
701
  if (!(!s || s === Rt())) {
702
702
  if (!o) {
@@ -725,7 +725,7 @@ const pr = ({
725
725
  );
726
726
  }, [it, at]);
727
727
  Pt(() => {
728
- if (!b) {
728
+ if (!v) {
729
729
  Gt(null), ut(!1);
730
730
  return;
731
731
  }
@@ -754,8 +754,8 @@ const pr = ({
754
754
  return pt = requestAnimationFrame(_t), document.addEventListener("mousedown", n), window.addEventListener("scroll", rt, !0), window.addEventListener("resize", rt), () => {
755
755
  cancelAnimationFrame(pt), document.removeEventListener("mousedown", n), s(), window.removeEventListener("scroll", rt, !0), window.removeEventListener("resize", rt);
756
756
  };
757
- }, [b, o, U, Z]), oe(() => {
758
- if (!b)
757
+ }, [v, o, U, Z]), oe(() => {
758
+ if (!v)
759
759
  return;
760
760
  U();
761
761
  const n = B.current;
@@ -763,8 +763,8 @@ const pr = ({
763
763
  return;
764
764
  const s = new ResizeObserver(() => U());
765
765
  return s.observe(n), () => s.disconnect();
766
- }, [b, U]);
767
- const q = x(void 0), V = x(void 0), At = x(""), ne = (n) => {
766
+ }, [v, U]);
767
+ const q = g(void 0), V = g(void 0), At = g(""), ne = (n) => {
768
768
  var s;
769
769
  j(n == null ? void 0 : n.id), (s = q.current) == null || s.call(q, (n == null ? void 0 : n.id) ?? At.current), R(!1), o && A(""), a == null || a(n == null ? void 0 : n.id), Z();
770
770
  }, jt = () => {
@@ -819,8 +819,8 @@ const pr = ({
819
819
  i ? ct : void 0,
820
820
  X ? M : void 0
821
821
  ].filter(Boolean).join(" ") || void 0;
822
- return /* @__PURE__ */ m(bt, { children: [
823
- /* @__PURE__ */ m(
822
+ return /* @__PURE__ */ x(bt, { children: [
823
+ /* @__PURE__ */ x(
824
824
  "div",
825
825
  {
826
826
  ref: zt,
@@ -837,7 +837,7 @@ const pr = ({
837
837
  {
838
838
  type: "button",
839
839
  onClick: Ht,
840
- "aria-label": g,
840
+ "aria-label": b,
841
841
  className: `absolute ${K ? Me[$] : "top-1/2 -translate-y-1/2"} z-10 flex items-center
842
842
  justify-center rounded-full text-[var(--malachite-text-placeholder)]
843
843
  hover:text-[var(--malachite-text-primary)] transition-colors
@@ -850,11 +850,11 @@ const pr = ({
850
850
  {
851
851
  hasClear: dt,
852
852
  onClear: Ht,
853
- clearLabel: g,
853
+ clearLabel: b,
854
854
  ref: Et,
855
- isOpen: b,
855
+ isOpen: v,
856
856
  onClick: (Q) => {
857
- d || (et(!!Q), R(!b));
857
+ d || (et(!!Q), R(!v));
858
858
  },
859
859
  selectedItem: z,
860
860
  disabled: d,
@@ -876,7 +876,7 @@ const pr = ({
876
876
  d || ie();
877
877
  },
878
878
  onTabAway: () => {
879
- b && jt();
879
+ v && jt();
880
880
  },
881
881
  size: $,
882
882
  controlId: ot,
@@ -888,7 +888,7 @@ const pr = ({
888
888
  ariaLabelledBy: D
889
889
  }
890
890
  ),
891
- b && ce(
891
+ v && ce(
892
892
  /* @__PURE__ */ e(
893
893
  re,
894
894
  {
@@ -905,7 +905,7 @@ const pr = ({
905
905
  items: ae,
906
906
  onItemSelected: ne,
907
907
  selectedItem: z,
908
- menuLoading: v,
908
+ menuLoading: m,
909
909
  emptyMessage: t.length === 0 ? "No options available" : "No results found",
910
910
  subtitleLayout: w,
911
911
  size: $,
@@ -1 +1 @@
1
- {"version":3,"file":"Dropdown.js","sources":["../../src/components/Dropdown.tsx"],"sourcesContent":["import React, {\n useId,\n useState,\n useRef,\n useEffect,\n useInsertionEffect,\n useLayoutEffect,\n useCallback,\n} from 'react';\nimport { createPortal } from 'react-dom';\nimport { Control, FieldPath, FieldValues } from 'react-hook-form';\nimport BaseFormComponent, {\n type RequiredIndicator,\n type RightSideContent,\n useFormFieldIds,\n} from './BaseFormComponent';\nimport CaretDownIcon from './CustomIcons/CaretDownIcon';\nimport CloseIcon from './CustomIcons/CloseIcon';\nimport FieldMessage from './FieldMessage';\nimport LoadingInput from './LoadingInput';\nimport Spinner from './Spinner';\nimport Tag from './Tag';\nimport Tooltip from './Tooltip';\nimport MarkdownBlock from './Typography/MarkdownBlock';\nimport { inlineMarkdownText } from './Typography/inlineMarkdown';\nimport { getDeepActiveElement } from './activeElement';\nimport { CONTROL_TEXT_SIZE, CONTROL_TEXT_SIZE_CLASS } from './controlTextSize';\nimport { controlWidthStyle } from './controlWidth';\nimport { DROPDOWN_TRIGGER_ATTR, type DropdownTone, getTriggerVisual } from './dropdownTriggerStyle';\nimport { pushEscapeLayer } from './escapeLayers';\nimport {\n MENU_MAX_HEIGHT_PX,\n MENU_SPECS,\n type MenuGeometry,\n isTriggerOffscreen,\n measureMenuGeometry,\n rectSignature,\n} from './floatingMenuGeometry';\nimport { FOCUS_RING, FOCUS_RING_WITHIN_INPUT } from './focusRing';\nimport { hasBadge } from './hasBadge';\nimport { ensureDropdownPanelStyles } from './optionRowStyles';\nimport { usePopupLayer } from './overlayLayers';\nimport { useTopLayer } from './topLayer';\nimport { isCut, tooltipLines } from './truncatedLines';\n\n// The menu portals into document.body, outside any shadow root, so a Tailwind-styled badge (a Tag)\n// needs a shadow host of its own; loaded only when a badge is passed.\nconst BadgeHost = React.lazy(() => import('./ActionMenuTagHost'));\n\nconst TriggerTag = ({ id, text, disabled }: { id: string; text: string; disabled?: boolean }) => (\n <span\n id={id}\n className={`flex min-w-0 max-w-[40%] [flex-shrink:3] ${disabled ? 'opacity-60' : ''}`}\n >\n <Tag value={text} paddingSize=\"compact\" fontSize=\"xsmall\" textTransform=\"none\" />\n </span>\n);\n\nexport type { DropdownTone };\n\nexport interface DropdownItem {\n id: string;\n label: string;\n icon?: React.ReactNode;\n /** Alternate label shown in the closed trigger when selected (falls back to `label`). */\n triggerLabel?: string;\n /** Short tag shown at the right of the closed trigger while this item is selected. */\n triggerTag?: string;\n /** Items sharing a `group` render under a section header, in first-seen order. */\n group?: string;\n subtitle?: string;\n rightSideText?: string;\n rightSideTextVariant?: 'muted' | 'primary';\n rightSideTextAlignment?: 'left' | 'right';\n /** Right-aligned badge shown in the open menu only (not in the trigger or the search input). */\n badge?: React.ReactNode;\n}\n\ninterface DropdownBaseProps {\n label?: string;\n hint?: string;\n rightSideContent?: RightSideContent;\n tooltip?: string;\n name: FieldPath<FieldValues> | string;\n loading?: boolean;\n menuLoading?: boolean;\n items: DropdownItem[];\n onItemSelected?: (id?: string) => void;\n defaultValue?: string;\n /** Controlled selection. When set, the trigger always reflects this id and the component\n * keeps no selection state of its own. Pass it with `onItemSelected`. */\n value?: string;\n disabled?: boolean;\n error?: boolean;\n /** `pending` marks a value the user still has to supply. Outranks open and selection. */\n tone?: DropdownTone;\n className?: string;\n formControl?: Control<FieldValues, unknown>;\n description?: string;\n required?: boolean;\n requiredIndicator?: RequiredIndicator;\n helperText?: React.ReactNode;\n placeholder?: string;\n subtitleLayout?: SubtitleLayout;\n /** Adds a clear control to the trigger, reported as `onItemSelected(undefined)`. */\n clearable?: boolean;\n /** 'large' (42px) for form inputs; 'medium' (32px) for toolbar chips; 'small' (28px) beside a title. */\n size?: DropdownSize;\n fullWidth?: boolean;\n width?: string | number;\n /**\n * Raises the open menu's floor above the shared 160px one, without widening the trigger.\n * For a control pinned narrow by its column — a role picker in a 160px cell, a member\n * picker in a 200px slot — whose options carry a subtitle the trigger never has to show.\n */\n minWidth?: number;\n /**\n * Which trigger edge a menu wider than its trigger lines up with. `end` grows it leftwards,\n * for a control at the right of its container. Either flips when the viewport has no room.\n */\n menuAlign?: 'start' | 'end';\n /** Names the trigger from the light DOM, where `htmlFor` cannot reach into the shadow root. */\n id?: string;\n 'aria-label'?: string;\n 'aria-labelledby'?: string;\n}\n\n/**\n * The search trigger is a single-line text input with nowhere for a second line, so\n * `showSubtitleInTrigger` is rejected alongside `search` rather than silently ignored.\n */\ntype DropdownTriggerModeProps =\n | {\n search?: false;\n /** Promotes the selected item's `subtitle` into the closed trigger, beneath the value. */\n showSubtitleInTrigger?: boolean;\n }\n | { search: true; showSubtitleInTrigger?: never };\n\nexport type DropdownProps = DropdownBaseProps & DropdownTriggerModeProps;\n\n/**\n * Matches Button and the Figma component library: 28 / 32 / 42px. These names moved up a\n * tier in 0.71 — what was `xsmall`/`small`/`medium` is now `small`/`medium`/`large`.\n */\nexport type DropdownSize = 'small' | 'medium' | 'large';\n\nexport type SubtitleLayout = 'inline' | 'stacked';\n\n// Text without these renders the same parsed or not, so it skips the parser.\nconst INLINE_MARKDOWN_SYNTAX = /[*`[<&\\\\]/;\n\n// Inert links: a <button> takes no interactive content.\nconst ItemSubtitle = ({ text }: { text: string }) =>\n INLINE_MARKDOWN_SYNTAX.test(text) ? (\n <MarkdownBlock\n text={text}\n variant=\"inline\"\n color=\"inherit\"\n size=\"inherit\"\n links=\"inert\"\n omitMargin\n />\n ) : (\n text\n );\n\nconst PANEL_MESSAGE_STYLE: React.CSSProperties = {\n display: 'flex',\n alignItems: 'center',\n justifyContent: 'center',\n gap: 8,\n padding: '24px 16px',\n color: 'var(--malachite-text-dimmed, rgb(161, 161, 161))',\n};\n\n// Figma pins the option's inline annotation at 11px on every tier — unlike the label,\n// it does not ride the ladder (Item Large 68:2617, Item Medium 2343:2134).\nconst ANNOTATION_FONT_SIZE = 'var(--malachite-font-size-xsmall, 11px)';\n\nconst OPTION_SELECTOR = '[data-dropdown-option]';\n\nconst panelOptions = (panel: HTMLElement | null): HTMLElement[] =>\n Array.from(panel?.querySelectorAll<HTMLElement>(OPTION_SELECTOR) ?? []);\n\n// Search what the subtitle shows: link and image text, not their destinations or markers.\nconst subtitleSearchText = (subtitle: string) =>\n INLINE_MARKDOWN_SYNTAX.test(subtitle)\n ? inlineMarkdownText(subtitle)\n : subtitle.replace(/\\s+/g, ' ');\n\nconst matchesSearch = (item: DropdownItem, query: string) => {\n const q = query.toLowerCase();\n const labelMatches = item.label.toLowerCase().includes(q);\n const subtitleMatches = item.subtitle\n ? subtitleSearchText(item.subtitle).toLowerCase().includes(q)\n : false;\n const rightSideTextMatches = item.rightSideText\n ? item.rightSideText.toLowerCase().includes(q)\n : false;\n return labelMatches || subtitleMatches || rightSideTextMatches;\n};\n\nconst TRIGGER_SIZE_HEIGHT: Record<DropdownSize, string> = {\n small: 'h-[var(--malachite-control-height-small,28px)]',\n medium: 'h-[var(--malachite-control-height-medium,32px)]',\n large: 'h-[var(--malachite-control-height-large,42px)]',\n};\n\nconst TRIGGER_SIZE_CLASSES: Record<DropdownSize, string> = {\n small: `${TRIGGER_SIZE_HEIGHT.small} px-2.5 py-1.5 ${CONTROL_TEXT_SIZE_CLASS.small}`,\n medium: `${TRIGGER_SIZE_HEIGHT.medium} px-3 py-1.5 ${CONTROL_TEXT_SIZE_CLASS.medium}`,\n large: `${TRIGGER_SIZE_HEIGHT.large} px-4 py-2.5 ${CONTROL_TEXT_SIZE_CLASS.large}`,\n};\n\nconst TRIGGER_SIZE_STACKED_CLASSES: Record<DropdownSize, string> = {\n small: `min-h-[var(--malachite-control-height-small,28px)] px-2.5 py-1.5 ${CONTROL_TEXT_SIZE_CLASS.small}`,\n medium: `min-h-[var(--malachite-control-height-medium,32px)] px-3 py-1.5 ${CONTROL_TEXT_SIZE_CLASS.medium}`,\n large: `min-h-[var(--malachite-control-height-large,42px)] px-4 py-2.5 ${CONTROL_TEXT_SIZE_CLASS.large}`,\n};\n\nconst CLEAR_OFFSET_CLASSES: Record<DropdownSize, string> = {\n small: 'right-[26px] size-4',\n medium: 'right-[30px] size-4',\n large: 'right-[38px] size-4',\n};\n\nconst CLEAR_STACKED_TOP_CLASSES: Record<DropdownSize, string> = {\n small: 'top-[calc(var(--malachite-control-height-small,28px)/2)] -translate-y-1/2',\n medium: 'top-[calc(var(--malachite-control-height-medium,32px)/2)] -translate-y-1/2',\n large: 'top-[calc(var(--malachite-control-height-large,42px)/2)] -translate-y-1/2',\n};\n\n// Radius tracks the tier in Figma: 10 / 12 / 14. Only 12 has a --malachite-radius-* rung.\nconst TRIGGER_SIZE_RADIUS: Record<DropdownSize, string> = {\n small: 'rounded-[var(--malachite-radius-10,10px)]',\n medium: 'rounded-xl',\n large: 'rounded-[var(--malachite-radius-xxl,14px)]',\n};\n\nconst NEVER = () => false;\n\nconst ValueRow: React.FC<{ wrap: boolean; id?: string; children: React.ReactNode }> = ({\n wrap,\n id,\n children,\n}) =>\n wrap ? (\n <span id={id} className=\"min-w-0 flex items-center gap-2\">\n {children}\n </span>\n ) : (\n <>{children}</>\n );\n\nconst LabelRow: React.FC<{ row: boolean; children: React.ReactNode }> = ({ row, children }) =>\n row ? (\n <span style={{ display: 'flex', alignItems: 'center', gap: 8, minWidth: 0 }}>\n {children}\n </span>\n ) : (\n <>{children}</>\n );\n\ninterface DropdownTriggerProps {\n isOpen: boolean;\n onClick: (fromKeyboard?: boolean) => void;\n selectedItem: DropdownItem | undefined;\n hasClear?: boolean;\n onClear?: (event: React.MouseEvent<HTMLButtonElement>) => void;\n clearLabel?: string;\n disabled?: boolean;\n error?: boolean;\n tone?: DropdownTone;\n placeholder?: string;\n search?: boolean;\n showSubtitleInTrigger?: boolean;\n searchQuery?: string;\n onSearchChange?: (value: string) => void;\n onFocusOpen?: () => void;\n /** ArrowDown on the trigger: opens the menu, or steps into it if already open. */\n onArrowDown?: () => void;\n /** Tab off the trigger: dismisses the panel, which is portaled and would outlive the focus. */\n onTabAway?: () => void;\n size?: DropdownSize;\n controlId: string;\n labelId?: string;\n describedBy?: string;\n required?: boolean;\n ariaLabel?: string;\n ariaLabelledBy?: string;\n /** A caller-supplied id means an external `<label for>` may be naming the control. */\n hasCallerId?: boolean;\n}\n\nconst DropdownTrigger = React.forwardRef<HTMLElement, DropdownTriggerProps>(\n (\n {\n isOpen,\n onClick,\n selectedItem,\n disabled = false,\n error = false,\n tone,\n placeholder,\n search = false,\n showSubtitleInTrigger = false,\n searchQuery = '',\n onSearchChange,\n onFocusOpen,\n onArrowDown,\n onTabAway,\n size = 'large',\n hasClear = false,\n onClear,\n clearLabel,\n controlId,\n labelId,\n describedBy,\n required = false,\n ariaLabel,\n ariaLabelledBy,\n hasCallerId = false,\n },\n forwardedRef,\n ) => {\n const stacked = showSubtitleInTrigger && !search && !!selectedItem?.subtitle;\n const sizeClasses = stacked\n ? TRIGGER_SIZE_STACKED_CLASSES[size]\n : TRIGGER_SIZE_CLASSES[size];\n const sizeRadius = TRIGGER_SIZE_RADIUS[size];\n const valueId = `${controlId}-value`;\n const subtitleId = `${controlId}-subtitle`;\n // aria-labelledby outranks aria-label in the accessible-name algorithm, so the\n // generated label+value pair has to be dropped for a caller's aria-label to apply.\n // Named off nothing, the button takes its name from every descendant — the subtitle\n // included, which `aria-describedby` then repeats. Naming it off the value alone fixes\n // that, but only where nothing else already names the control.\n const tagId = `${controlId}-tag`;\n const rendersButton = !search || disabled;\n const hasTag = rendersButton && !!selectedItem?.triggerTag;\n const showsSearchTag = !rendersButton && !isOpen && !!selectedItem?.triggerTag;\n const valueIds = hasTag ? `${valueId} ${tagId}` : valueId;\n const namesItself = !labelId && !ariaLabel && !hasCallerId && (stacked || hasTag);\n const labelledBy =\n ariaLabelledBy ??\n (labelId && !ariaLabel ? `${labelId} ${valueIds}` : undefined) ??\n (namesItself ? valueIds : undefined);\n const tagOutsideName = hasTag && !labelledBy?.split(' ').includes(tagId);\n\n const handleTriggerKeyDown = (event: React.KeyboardEvent): void => {\n // Not prevented: Tab carries on to the next control. In search mode the trigger keeps\n // focus on open, so this is the panel's only Tab dismissal.\n if (event.key === 'Tab') {\n onTabAway?.();\n return;\n }\n if (event.key !== 'ArrowDown') {\n return;\n }\n event.preventDefault();\n onArrowDown?.();\n };\n\n const valueTextRef = useRef<HTMLSpanElement>(null);\n const subtitleTextRef = useRef<HTMLSpanElement>(null);\n const triggerVisual = getTriggerVisual({ disabled, error, tone, open: isOpen });\n const showValueLabel = !isOpen && !!selectedItem;\n const valueText = selectedItem?.triggerLabel ?? selectedItem?.label;\n const triggerSubtitle = stacked ? selectedItem?.subtitle : undefined;\n const isValueTruncated = () => isCut(valueTextRef.current);\n\n // A tooltip reads its text at render, but which line is cut off is only knowable on\n // hover — so the one measurement pass that decides whether to show also records what\n // to say. The initial value never shows: untruncated, the tooltip refuses to open.\n const [cutLines, setCutLines] = useState({ value: false, subtitle: true });\n const measureTruncatedLines = () => {\n const value = isValueTruncated();\n const subtitle = isCut(subtitleTextRef.current);\n if (!value && !subtitle) {\n return false;\n }\n setCutLines({ value, subtitle });\n return true;\n };\n\n if (search && !disabled) {\n return (\n <div\n ref={forwardedRef as React.Ref<HTMLDivElement>}\n className={`\n relative w-full ${sizeClasses} ${sizeRadius}\n border border-solid\n transition-all duration-200\n flex items-center ${FOCUS_RING_WITHIN_INPUT}\n `}\n style={triggerVisual}\n {...{ [DROPDOWN_TRIGGER_ATTR]: '' }}\n onClick={(e) => e.stopPropagation()}\n >\n {selectedItem?.icon && (\n <span className=\"flex shrink-0 items-center justify-center pr-2\">\n {selectedItem.icon}\n </span>\n )}\n <Tooltip text={valueText} shouldShow={isValueTruncated} isShrinkable fill>\n <div className=\"relative flex-1 flex items-center min-w-0\">\n {showValueLabel && (\n <span\n aria-hidden=\"true\"\n className=\"absolute inset-0 flex items-center pointer-events-none\"\n >\n <span\n ref={valueTextRef}\n className=\"min-w-0 block truncate text-[length:inherit]\n text-[var(--malachite-text-primary)]\"\n >\n {valueText}\n </span>\n </span>\n )}\n <input\n id={controlId}\n type=\"text\"\n aria-label={ariaLabel}\n aria-labelledby={ariaLabelledBy}\n aria-invalid={error || undefined}\n aria-required={required || undefined}\n aria-describedby={\n [describedBy, showsSearchTag ? tagId : undefined]\n .filter(Boolean)\n .join(' ') || undefined\n }\n value={isOpen ? searchQuery : (selectedItem?.label ?? '')}\n onChange={(e) => {\n e.stopPropagation();\n onSearchChange?.(e.target.value);\n if (!isOpen) {\n onClick();\n }\n }}\n onFocus={() => {\n onFocusOpen?.();\n }}\n onKeyDown={handleTriggerKeyDown}\n placeholder={placeholder ?? 'Select Field'}\n className={`flex-1 min-w-0 bg-transparent outline-none\n text-[length:inherit] font-normal\n placeholder:text-[var(--malachite-text-dimmed)] ${\n showValueLabel\n ? 'text-transparent'\n : 'text-[var(--malachite-text-primary)]'\n }`}\n />\n </div>\n </Tooltip>\n {showsSearchTag && selectedItem?.triggerTag && (\n <>\n <span aria-hidden=\"true\" className=\"w-2 shrink-0\" />\n <TriggerTag id={tagId} text={selectedItem.triggerTag} />\n </>\n )}\n {hasClear && (\n <button\n type=\"button\"\n aria-label={clearLabel}\n onClick={onClear}\n className=\"flex shrink-0 items-center justify-center pl-2 cursor-pointer\n bg-transparent border-none p-0 text-[var(--malachite-text-placeholder)]\n hover:text-[var(--malachite-text-primary)] transition-colors\n rounded-full focus-visible:[outline:2px_solid_var(--malachite-text-primary)] focus-visible:outline-offset-2\"\n >\n <CloseIcon size={13} />\n </button>\n )}\n <div className=\"flex items-center justify-center pl-2\">\n {/* Mouse-only affordance: the input beside it already opens the menu on\n click and focus, so this stays out of the tab order to avoid a\n duplicate stop — but it must still be a button, not a click-handling\n span, so it is exposed and activatable rather than invisible. */}\n <button\n type=\"button\"\n tabIndex={-1}\n aria-label={isOpen ? 'Close options' : 'Open options'}\n onClick={(e) => {\n e.stopPropagation();\n onClick();\n }}\n className=\"flex items-center justify-center cursor-pointer bg-transparent border-none p-0\"\n >\n <CaretDownIcon\n size={13}\n style={{\n color: isOpen\n ? 'var(--malachite-text-primary, rgb(10, 10, 10))'\n : 'var(--malachite-text-placeholder, rgb(187, 187, 187))',\n transition: 'transform 0.2s ease, color 0.2s ease',\n transform: isOpen ? 'rotate(180deg)' : 'rotate(0deg)',\n }}\n />\n </button>\n </div>\n </div>\n );\n }\n\n const trigger = (\n <button\n ref={forwardedRef as React.Ref<HTMLButtonElement>}\n id={controlId}\n type=\"button\"\n aria-label={ariaLabel}\n aria-labelledby={labelledBy}\n aria-invalid={error || undefined}\n aria-required={required || undefined}\n aria-describedby={\n [\n describedBy,\n triggerSubtitle ? subtitleId : undefined,\n tagOutsideName ? tagId : undefined,\n ]\n .filter(Boolean)\n .join(' ') || undefined\n }\n onClick={(e) => {\n e.stopPropagation();\n onClick(e.detail === 0);\n }}\n onKeyDown={handleTriggerKeyDown}\n disabled={disabled}\n style={triggerVisual}\n {...{ [DROPDOWN_TRIGGER_ATTR]: '' }}\n className={`\n relative w-full ${sizeClasses} ${sizeRadius}\n border border-solid\n transition-all duration-200\n flex ${stacked ? 'items-start' : 'items-center'} gap-3\n cursor-pointer\n disabled:cursor-not-allowed ${FOCUS_RING}\n `}\n >\n {/* Spans: <button> takes phrasing content only. */}\n <span\n id={triggerSubtitle ? undefined : valueId}\n className={`text-left ${hasTag ? 'flex-[1_1_auto]' : 'flex-1'} min-w-0 flex ${\n triggerSubtitle ? 'flex-col gap-1' : 'items-center gap-2'\n }`}\n >\n {selectedItem ? (\n <>\n <ValueRow wrap={!!triggerSubtitle} id={valueId}>\n {selectedItem.icon && (\n <span className=\"flex items-center justify-center shrink-0\">\n {selectedItem.icon}\n </span>\n )}\n <Tooltip\n text={valueText}\n shouldShow={triggerSubtitle ? NEVER : isValueTruncated}\n triggerAs={triggerSubtitle ? 'span' : 'div'}\n isShrinkable\n >\n <span\n ref={valueTextRef}\n className={`min-w-0 block truncate text-[length:inherit] ${\n disabled\n ? 'text-[var(--malachite-text-placeholder)]'\n : 'text-[var(--malachite-text-primary)]'\n }`}\n >\n {valueText}\n </span>\n </Tooltip>\n </ValueRow>\n {triggerSubtitle && (\n <span\n id={subtitleId}\n ref={subtitleTextRef}\n className=\"min-w-0 block truncate text-[length:var(--malachite-font-size-xsmall,11px)] text-[var(--malachite-text-secondary,rgb(123,123,123))] leading-normal\"\n >\n <ItemSubtitle text={triggerSubtitle} />\n </span>\n )}\n </>\n ) : (\n <span\n className={`flex-1 min-w-0 truncate text-[length:inherit] ${\n disabled\n ? 'text-[var(--malachite-text-placeholder)]'\n : 'text-[var(--malachite-text-dimmed)]'\n }`}\n >\n {placeholder ?? 'Select Field'}\n </span>\n )}\n </span>\n {selectedItem?.triggerTag && (\n <TriggerTag id={tagId} text={selectedItem.triggerTag} disabled={disabled} />\n )}\n {hasClear && <span aria-hidden=\"true\" className=\"shrink-0 w-4\" />}\n <span className=\"flex items-center justify-center shrink-0\">\n <CaretDownIcon\n size={13}\n style={{\n color: isOpen\n ? 'var(--malachite-text-primary, rgb(10, 10, 10))'\n : 'var(--malachite-text-placeholder, rgb(187, 187, 187))',\n transition: 'transform 0.2s ease, color 0.2s ease',\n transform: isOpen ? 'rotate(180deg)' : 'rotate(0deg)',\n }}\n />\n </span>\n </button>\n );\n\n // The button is what takes focus, so the tooltip wraps it rather than a line inside:\n // mounted on a line it could only ever open with a pointer, and nested tooltips opened\n // together on hover. Its text is already in the trigger's name and description, so it\n // repeats it visually only. `fill`, not `isShrinkable`, whose `overflow: hidden` would\n // clip the error ring the button paints outside its border box.\n // Gated on the prop, not on there being a subtitle to show: keyed off the selection the\n // wrapper would appear on the first choice, remounting the button `focusTrigger` has\n // just handed focus back to and dropping the keyboard user at <body>.\n return showSubtitleInTrigger && !search ? (\n <Tooltip\n text={tooltipLines([\n ['value', cutLines.value && valueText],\n [\n 'subtitle',\n cutLines.subtitle && triggerSubtitle && (\n <ItemSubtitle text={triggerSubtitle} />\n ),\n ],\n ])}\n shouldShow={triggerSubtitle ? measureTruncatedLines : NEVER}\n fill\n describesTrigger={false}\n >\n {trigger}\n </Tooltip>\n ) : (\n trigger\n );\n },\n);\nDropdownTrigger.displayName = 'DropdownTrigger';\n\ninterface DropdownItemComponentProps {\n item: DropdownItem;\n selected: boolean;\n showTooltipOnFocus: boolean;\n subtitleLayout: SubtitleLayout;\n onItemSelected: (item: DropdownItem) => void;\n}\n\nconst DropdownItemComponent = ({\n item,\n selected,\n showTooltipOnFocus,\n subtitleLayout,\n onItemSelected,\n}: DropdownItemComponentProps) => {\n const textColor = selected\n ? 'var(--malachite-accent-foreground, rgb(2, 122, 66))'\n : 'var(--malachite-text-primary, rgb(10, 10, 10))';\n const stacked = subtitleLayout === 'stacked' && !!item.subtitle;\n const optionId = `mal-${useId().replace(/[^a-zA-Z0-9_-]/g, '')}`;\n const optionLabelId = `${optionId}-label`;\n const optionSubtitleId = `${optionId}-subtitle`;\n const optionBadgeId = `${optionId}-badge`;\n const labelRef = useRef<HTMLSpanElement>(null);\n const subtitleRef = useRef<HTMLSpanElement>(null);\n const rightSideRef = useRef<HTMLSpanElement>(null);\n\n // Seeded all-cut: `Tooltip` skips `shouldShow` when its text is empty.\n const [cutLines, setCutLines] = useState({ label: true, subtitle: true, rightSide: true });\n const measureOptionLines = () => {\n const label = isCut(labelRef.current);\n const subtitle = isCut(subtitleRef.current);\n const rightSide = isCut(rightSideRef.current);\n if (!label && !subtitle && !rightSide) {\n return false;\n }\n setCutLines({ label, subtitle, rightSide });\n return true;\n };\n\n // Default to muted so right-side metadata (e.g. category tags) de-emphasises\n // against the primary item label. Consumers can opt back in with 'primary'.\n const rightSideTextColor =\n item.rightSideTextVariant === 'primary'\n ? 'var(--malachite-text-right-side-text-primary, rgb(10, 10, 10))'\n : 'var(--malachite-text-right-side-text-muted, rgb(123, 123, 123))';\n\n const rightSideJustify = item.rightSideTextAlignment === 'left' ? 'flex-start' : 'flex-end';\n\n const option = (\n // `role=\"option\"` would be invalid — nothing here declares a `listbox`, and an\n // orphaned option is dropped from the a11y tree. `aria-current`, not\n // `aria-pressed`: these are one-of-many choices, not toggles. tabIndex={-1}\n // because the portaled panel is outside the trigger's tab order; DropdownPanel\n // focuses an option on open and arrow keys move between them.\n <button\n type=\"button\"\n data-dropdown-option=\"\"\n data-selected={selected}\n aria-current={selected || undefined}\n // Unnamed, the option takes its name from everything inside it — a sentence-length\n // subtitle or a badge included.\n aria-labelledby={item.subtitle || hasBadge(item.badge) ? optionLabelId : undefined}\n // The id sits on the light-DOM wrapper: one inside the badge's shadow root is unreachable.\n aria-describedby={\n [\n item.subtitle ? optionSubtitleId : undefined,\n hasBadge(item.badge) ? optionBadgeId : undefined,\n ]\n .filter(Boolean)\n .join(' ') || undefined\n }\n tabIndex={-1}\n onClick={(e) => {\n e.stopPropagation();\n onItemSelected(item);\n }}\n className=\"malachite-dropdown-option\"\n style={{\n minHeight: 38,\n borderRadius: 8,\n display: 'flex',\n alignItems: 'center',\n padding: 10,\n gap: 12,\n cursor: 'pointer',\n transition: 'background-color 120ms ease',\n // Reset the UA button chrome. Background is deliberately absent — see PANEL_RULES.\n width: '100%',\n border: 'none',\n textAlign: 'left',\n font: 'inherit',\n color: 'inherit',\n }}\n >\n {/* Spans: <button> takes phrasing content only. */}\n <span\n style={{\n flex: 1,\n display: 'flex',\n alignItems: 'center',\n gap: 12,\n minWidth: 0,\n }}\n >\n <span style={{ flex: '1 1 auto', display: 'block', minWidth: 0 }}>\n <span\n style={\n stacked\n ? { display: 'flex', flexDirection: 'column', gap: 2 }\n : { display: 'flex', alignItems: 'center', gap: 8 }\n }\n >\n <LabelRow row={stacked && !!item.icon}>\n {item.icon && (\n <span\n style={{\n display: 'flex',\n alignItems: 'center',\n justifyContent: 'center',\n flexShrink: 0,\n }}\n >\n {item.icon}\n </span>\n )}\n <span\n id={\n item.subtitle || hasBadge(item.badge)\n ? optionLabelId\n : undefined\n }\n ref={labelRef}\n style={{\n fontWeight: 400,\n color: textColor,\n whiteSpace: 'nowrap',\n overflow: 'hidden',\n textOverflow: 'ellipsis',\n minWidth: 0,\n }}\n >\n {item.label}\n </span>\n </LabelRow>\n {item.subtitle &&\n (stacked ? (\n <span\n id={optionSubtitleId}\n ref={subtitleRef}\n style={{\n fontSize: ANNOTATION_FONT_SIZE,\n fontWeight: 400,\n lineHeight: 1.4,\n color: selected\n ? textColor\n : 'var(--malachite-text-dimmed, rgb(161, 161, 161))',\n whiteSpace: 'nowrap',\n overflow: 'hidden',\n textOverflow: 'ellipsis',\n }}\n >\n <ItemSubtitle text={item.subtitle} />\n </span>\n ) : (\n <span\n style={{\n // Zero basis: the subtitle gives way before the label.\n flexGrow: 1,\n flexBasis: 0,\n display: 'flex',\n alignItems: 'center',\n gap: 8,\n minWidth: 0,\n overflow: 'hidden',\n }}\n >\n <span\n style={{\n fontSize: ANNOTATION_FONT_SIZE,\n fontWeight: 400,\n color: 'var(--malachite-text-secondary, rgb(123, 123, 123))',\n flexShrink: 0,\n }}\n >\n |\n </span>\n <span\n id={optionSubtitleId}\n ref={subtitleRef}\n style={{\n fontSize: ANNOTATION_FONT_SIZE,\n fontWeight: 400,\n color: 'var(--malachite-text-secondary, rgb(123, 123, 123))',\n whiteSpace: 'nowrap',\n overflow: 'hidden',\n textOverflow: 'ellipsis',\n minWidth: 0,\n }}\n >\n <ItemSubtitle text={item.subtitle} />\n </span>\n </span>\n ))}\n </span>\n </span>\n <span\n style={{\n // Reserved only when there is something to put there: an empty slot\n // still holding its width truncates the label and subtitle early.\n minWidth: item.rightSideText\n ? 'var(--malachite-text-right-side-text-min-width, 80px)'\n : 0,\n flexShrink: 1,\n display: 'flex',\n justifyContent: rightSideJustify,\n }}\n >\n {item.rightSideText && (\n <span\n ref={rightSideRef}\n style={{\n fontSize: 'var(--malachite-text-right-side-text-font-size, 12px)',\n fontWeight: 400,\n color: rightSideTextColor,\n whiteSpace: 'nowrap',\n overflow: 'hidden',\n textOverflow: 'ellipsis',\n minWidth: 0,\n }}\n >\n {item.rightSideText}\n </span>\n )}\n </span>\n {hasBadge(item.badge) && (\n <span id={optionBadgeId} style={{ flexShrink: 0, display: 'flex' }}>\n <React.Suspense fallback={null}>\n <BadgeHost>{item.badge}</BadgeHost>\n </React.Suspense>\n </span>\n )}\n </span>\n </button>\n );\n\n // Focus lands on the option itself, and focusin does not reach a descendant, so a keyboard\n // user could never open a tooltip mounted inside it.\n return (\n <Tooltip\n text={tooltipLines([\n ['label', cutLines.label && item.label],\n [\n 'subtitle',\n cutLines.subtitle && item.subtitle && <ItemSubtitle text={item.subtitle} />,\n ],\n ['rightSide', cutLines.rightSide && item.rightSideText],\n ])}\n shouldShow={measureOptionLines}\n showOnFocus={showTooltipOnFocus}\n isShrinkable\n describesTrigger={false}\n >\n {option}\n </Tooltip>\n );\n};\n\ninterface DropdownPanelProps {\n items: DropdownItem[];\n onItemSelected: (item?: DropdownItem) => void;\n selectedItem: DropdownItem | undefined;\n menuLoading?: boolean;\n emptyMessage: string;\n /** Focus an option on open. False in search mode, where the input keeps focus. */\n autoFocus: boolean;\n /** Panel has been measured. It renders `visibility: hidden` until then, and a\n * hidden element cannot take focus, so open-time focus has to wait for this. */\n positioned: boolean;\n /** Close the panel and hand focus back to the trigger. */\n onDismiss: () => void;\n keyboardNavigation: boolean;\n onKeyboardNavigation: () => void;\n subtitleLayout: SubtitleLayout;\n size: DropdownSize;\n}\n\nconst DropdownPanel = React.forwardRef<\n HTMLDivElement,\n DropdownPanelProps & { style?: React.CSSProperties }\n>((props, ref) => {\n const {\n items,\n onItemSelected,\n selectedItem,\n menuLoading,\n emptyMessage,\n autoFocus,\n positioned,\n onDismiss,\n keyboardNavigation,\n onKeyboardNavigation,\n subtitleLayout,\n size,\n style,\n } = props;\n const panelRef = useRef<HTMLDivElement | null>(null);\n const popupIdentity = usePopupLayer('dropdown', true, panelRef);\n\n // The panel only mounts while open, so no condition. useInsertionEffect, not layout:\n // it runs before the DOM mutation, so the rules are in place before the rows are inserted.\n useInsertionEffect(() => {\n ensureDropdownPanelStyles();\n }, []);\n\n useTopLayer(panelRef, true);\n\n // Start on the selected option so Enter re-confirms the current value. Not keyed on\n // `items`: re-running as the filtered list changes would yank focus back to the top.\n useEffect(() => {\n if (!autoFocus || !positioned) {\n return;\n }\n const options = panelOptions(panelRef.current);\n const selected = options.find((option) => option.dataset.selected === 'true');\n // Falls back to the panel: with no options nothing else can hold focus, and Tab-dismiss\n // only fires from inside it.\n (selected ?? options[0] ?? panelRef.current)?.focus();\n }, [autoFocus, positioned]);\n\n const handleKeyDown = (event: React.KeyboardEvent<HTMLDivElement>): void => {\n // The panel is portaled to document.body, so the browser's next tab stop bears no\n // relation to the trigger. Dismissing restores trigger focus so Tab resumes there.\n if (event.key === 'Tab') {\n onDismiss();\n return;\n }\n const options = panelOptions(panelRef.current);\n if (options.length === 0) {\n return;\n }\n const current = options.indexOf(document.activeElement as HTMLElement);\n const target = {\n ArrowDown: current + 1,\n ArrowUp: current - 1,\n Home: 0,\n End: options.length - 1,\n }[event.key];\n if (target === undefined) {\n return;\n }\n event.preventDefault();\n onKeyboardNavigation();\n options[Math.min(Math.max(target, 0), options.length - 1)]?.focus();\n };\n\n // Inline styles, not Tailwind: this portals into document.body, outside the\n // Shadow DOM the malachite stylesheet is adopted into.\n return (\n <div\n ref={(node) => {\n panelRef.current = node;\n if (typeof ref === 'function') {\n ref(node);\n } else if (ref) {\n ref.current = node;\n }\n }}\n {...popupIdentity}\n tabIndex={-1}\n onKeyDown={handleKeyDown}\n style={{\n background: MENU_SPECS.standard.background,\n border: MENU_SPECS.standard.border,\n borderRadius: MENU_SPECS.standard.radius,\n boxShadow: MENU_SPECS.standard.shadow,\n maxHeight: MENU_MAX_HEIGHT_PX,\n overflow: 'hidden',\n display: 'flex',\n flexDirection: 'column',\n fontSize: CONTROL_TEXT_SIZE[size],\n ...style,\n }}\n >\n {menuLoading ? (\n <div style={PANEL_MESSAGE_STYLE}>\n <Spinner size=\"xxxsmall\" />\n <span>Loading…</span>\n </div>\n ) : items.length === 0 ? (\n <div style={PANEL_MESSAGE_STYLE}>{emptyMessage}</div>\n ) : (\n <div\n style={{\n display: 'flex',\n flexDirection: 'column',\n gap: 4,\n padding: MENU_SPECS.standard.padding,\n overflowY: 'auto',\n scrollbarWidth: 'thin',\n scrollbarColor:\n 'var(--malachite-text-placeholder, rgb(187, 187, 187)) transparent',\n }}\n >\n {items.map((item, index) => {\n const prev = items[index - 1];\n const showGroupHeader =\n !!item.group && (!prev || prev.group !== item.group);\n return (\n <div key={item.id} style={{ flexShrink: 0 }}>\n {showGroupHeader && (\n <div\n style={{\n padding: '6px 10px 4px',\n fontSize: 12,\n fontWeight: 500,\n color: 'var(--malachite-text-secondary, rgb(123, 123, 123))',\n textTransform: 'none',\n userSelect: 'none',\n }}\n >\n {item.group}\n </div>\n )}\n <DropdownItemComponent\n item={item}\n onItemSelected={onItemSelected}\n subtitleLayout={subtitleLayout}\n selected={item.id === selectedItem?.id || false}\n showTooltipOnFocus={keyboardNavigation}\n />\n </div>\n );\n })}\n </div>\n )}\n </div>\n );\n});\nDropdownPanel.displayName = 'DropdownPanel';\n\nexport const Dropdown = ({\n items,\n onItemSelected,\n defaultValue,\n value,\n disabled = false,\n error,\n tone,\n label,\n hint,\n rightSideContent,\n tooltip,\n name,\n required = false,\n requiredIndicator,\n loading,\n menuLoading,\n formControl,\n description,\n helperText,\n placeholder,\n search = false,\n showSubtitleInTrigger = false,\n subtitleLayout = 'inline',\n clearable = false,\n size = 'large',\n fullWidth = false,\n width,\n minWidth,\n menuAlign = 'start',\n id,\n 'aria-label': ariaLabel,\n 'aria-labelledby': ariaLabelledBy,\n}: DropdownProps) => {\n const { controlId, labelId, descriptionId, hintId, helperTextId } = useFormFieldIds({\n id,\n label,\n description,\n hint,\n helperText: true,\n });\n const [isOpen, setIsOpen] = useState(false);\n // The id, never the resolved item: a cached object goes stale when `items` is rebuilt.\n const [ownValue, setOwnValue] = useState(defaultValue);\n const selectedId = value ?? ownValue;\n const selectedItem = items.find((item) => item.id === selectedId);\n const showClear = clearable && selectedId !== undefined && selectedId !== '' && !disabled;\n const triggerIsStacked = showSubtitleInTrigger && !search && !!selectedItem?.subtitle;\n const clearLabel = `Clear ${label ?? placeholder ?? 'selection'}`;\n\n // `defaultValue` only seeds the state, so a later change has to be pushed in.\n const lastDefaultValueRef = useRef(defaultValue);\n useEffect(() => {\n if (lastDefaultValueRef.current === defaultValue) {\n return;\n }\n lastDefaultValueRef.current = defaultValue;\n setOwnValue(defaultValue);\n }, [defaultValue]);\n const [searchQuery, setSearchQuery] = useState('');\n // Search mode only: set when the panel is opened by ArrowDown, so focus follows the\n // user into the list on mount instead of staying in the input.\n const [focusPanelOnOpen, setFocusPanelOnOpen] = useState(false);\n const [keyboardNavigation, setKeyboardNavigation] = useState(false);\n const dropdownRef = useRef<HTMLDivElement>(null);\n const triggerRef = useRef<HTMLElement>(null);\n const panelRef = useRef<HTMLDivElement>(null);\n const [panelPosition, setPanelPosition] = useState<MenuGeometry | null>(null);\n\n const reopenOnFocusRef = useRef(true);\n\n // In search mode the trigger is a wrapper div; the focusable part is the input.\n const focusTrigger = useCallback(() => {\n const trigger = triggerRef.current;\n const target =\n trigger instanceof HTMLButtonElement\n ? trigger\n : (trigger?.querySelector<HTMLElement>('input') ?? null);\n // A `.focus()` that fires no focus event — an already-focused element, or one that never\n // lands (disabled, hidden, unfocused window) — leaves the latch to eat the next real focus.\n if (!target || target === getDeepActiveElement()) {\n return;\n }\n if (!search) {\n target.focus();\n return;\n }\n reopenOnFocusRef.current = false;\n target.focus();\n if (getDeepActiveElement() !== target) {\n reopenOnFocusRef.current = true;\n }\n }, [search]);\n\n const handleClear = useCallback(\n (event: React.MouseEvent<HTMLButtonElement>) => {\n event.stopPropagation();\n setOwnValue(undefined);\n // The resolver is told the empty this form started the field at; the public\n // callback keeps reporting `undefined` whatever shape that is.\n reportSelectionRef.current?.(reportEmptyRef.current);\n onItemSelected?.(undefined);\n focusTrigger();\n },\n [onItemSelected, focusTrigger],\n );\n\n const updatePanelPosition = useCallback(() => {\n const trigger = triggerRef.current;\n if (!trigger) return;\n\n setPanelPosition(\n measureMenuGeometry(panelRef.current, {\n triggerRect: trigger.getBoundingClientRect(),\n preset: 'standard',\n minWidth,\n align: menuAlign === 'end' ? 'right' : 'left',\n viewportWidth: window.innerWidth,\n viewportHeight: window.innerHeight,\n }),\n );\n }, [minWidth, menuAlign]);\n\n useEffect(() => {\n if (!isOpen) {\n setPanelPosition(null);\n setFocusPanelOnOpen(false);\n return;\n }\n updatePanelPosition();\n const handleClickOutside = (event: MouseEvent) => {\n const path = event.composedPath();\n const trigger = dropdownRef.current;\n const panel = panelRef.current;\n const inTrigger = !!trigger && path.includes(trigger);\n const inPanel = !!panel && path.includes(panel);\n if (!inTrigger && !inPanel) {\n setIsOpen(false);\n if (search) {\n setSearchQuery('');\n }\n if (panelRef.current?.contains(getDeepActiveElement())) {\n focusTrigger();\n }\n // Closing unmounts the option holding focus, so no focusout reaches the wrapper\n // below; when the trigger holds it one does, and reporting here too validates twice.\n if (!dropdownRef.current?.contains(getDeepActiveElement())) {\n reportBlurRef.current?.();\n }\n }\n };\n // ESC via the shared layer stack: closes only the topmost overlay. Focus is\n // restored explicitly — unmounting the option it sits on would drop it to <body>.\n const popEscapeLayer = pushEscapeLayer(() => {\n setIsOpen(false);\n if (search) {\n setSearchQuery('');\n }\n focusTrigger();\n });\n const handleScrollOrResize = () => updatePanelPosition();\n\n // `scroll` is not composed: a window listener never hears a scroller inside a\n // consumer's shadow root, so the trigger's rect is tracked instead.\n let frame = 0;\n let lastRect = '';\n const followTrigger = () => {\n const trigger = triggerRef.current;\n if (trigger) {\n const rect = trigger.getBoundingClientRect();\n\n if (isTriggerOffscreen(rect, window.innerWidth, window.innerHeight)) {\n setIsOpen(false);\n if (search) {\n setSearchQuery('');\n }\n return;\n }\n\n const signature = rectSignature(rect);\n if (signature !== lastRect) {\n lastRect = signature;\n updatePanelPosition();\n }\n }\n frame = requestAnimationFrame(followTrigger);\n };\n frame = requestAnimationFrame(followTrigger);\n\n document.addEventListener('mousedown', handleClickOutside);\n window.addEventListener('scroll', handleScrollOrResize, true);\n window.addEventListener('resize', handleScrollOrResize);\n return () => {\n cancelAnimationFrame(frame);\n document.removeEventListener('mousedown', handleClickOutside);\n popEscapeLayer();\n window.removeEventListener('scroll', handleScrollOrResize, true);\n window.removeEventListener('resize', handleScrollOrResize);\n };\n }, [isOpen, search, updatePanelPosition, focusTrigger]);\n\n useLayoutEffect(() => {\n if (!isOpen) {\n return;\n }\n updatePanelPosition();\n\n const panel = panelRef.current;\n if (!panel || typeof ResizeObserver === 'undefined') {\n return;\n }\n const observer = new ResizeObserver(() => updatePanelPosition());\n observer.observe(panel);\n return () => observer.disconnect();\n }, [isOpen, updatePanelPosition]);\n\n const reportSelectionRef = useRef<((value: unknown) => void) | undefined>(undefined);\n const reportBlurRef = useRef<(() => void) | undefined>(undefined);\n const reportEmptyRef = useRef<unknown>('');\n\n const handleItemSelected = (item?: DropdownItem) => {\n setOwnValue(item?.id);\n reportSelectionRef.current?.(item?.id ?? reportEmptyRef.current);\n setIsOpen(false);\n if (search) {\n setSearchQuery('');\n }\n onItemSelected?.(item?.id);\n focusTrigger();\n };\n\n const dismissPanel = () => {\n setIsOpen(false);\n if (search) {\n setSearchQuery('');\n }\n focusTrigger();\n };\n\n // ArrowDown is the \"take me into the list\" gesture. When it also opens the panel the\n // intent carries over to the mount, so it doesn't cost a second press in search mode.\n const enterPanel = () => {\n setKeyboardNavigation(true);\n const first = panelOptions(panelRef.current)[0];\n if (first) {\n first.focus();\n return;\n }\n setFocusPanelOnOpen(true);\n setIsOpen(true);\n };\n\n const visibleItems =\n search && searchQuery ? items.filter((item) => matchesSearch(item, searchQuery)) : items;\n\n return (\n <BaseFormComponent\n fullWidth={fullWidth}\n label={label}\n hint={hint}\n rightSideContent={rightSideContent}\n tooltip={tooltip}\n name={name}\n required={required}\n requiredIndicator={requiredIndicator}\n loading={loading}\n formControl={formControl}\n description={description}\n controlId={controlId}\n labelId={labelId}\n descriptionId={descriptionId}\n hintId={hintId}\n loadingComponent={\n width === undefined ? (\n <LoadingInput\n heightClass={TRIGGER_SIZE_HEIGHT[size]}\n helperText={!!helperText}\n helperTextMarginTop\n />\n ) : (\n <div style={controlWidthStyle(width)}>\n <LoadingInput\n heightClass={TRIGGER_SIZE_HEIGHT[size]}\n helperText={!!helperText}\n helperTextMarginTop\n />\n </div>\n )\n }\n >\n {({ error: fieldError, message, onFieldChange, onFieldBlur, emptyValue }) => {\n reportSelectionRef.current = onFieldChange;\n reportBlurRef.current = onFieldBlur;\n reportEmptyRef.current = emptyValue;\n const isError = error ?? fieldError;\n // `error={false}` opts out of the resolver entirely, message included: a screen\n // that has dealt with the rejection its own way would otherwise keep reporting it.\n // The message is its own line rather than a replacement for the helper text,\n // matching Input and TextArea: a field that explains what it wants still has to\n // say why what was chosen was rejected.\n const errorMessage = error === false ? undefined : message;\n const errorMessageId = `${helperTextId}-error`;\n const describedBy =\n [\n descriptionId,\n hintId,\n helperText ? helperTextId : undefined,\n errorMessage ? errorMessageId : undefined,\n ]\n .filter(Boolean)\n .join(' ') || undefined;\n\n return (\n <>\n <div\n ref={dropdownRef}\n className={`relative w-full`}\n style={controlWidthStyle(width)}\n // Only leaving the field altogether is a blur `mode: 'onBlur'` should\n // hear. The panel is portaled to the body, so containment has to be\n // asked of it separately — otherwise opening the menu reads as\n // leaving, and the form validates before anything has been chosen.\n onBlur={(event) => {\n const next = event.relatedTarget as Node | null;\n const staysInField =\n event.currentTarget.contains(next) ||\n panelRef.current?.contains(next) === true;\n\n if (!staysInField) {\n reportBlurRef.current?.();\n }\n }}\n >\n {showClear && !search && (\n <button\n type=\"button\"\n onClick={handleClear}\n aria-label={clearLabel}\n className={`absolute ${\n triggerIsStacked\n ? CLEAR_STACKED_TOP_CLASSES[size]\n : 'top-1/2 -translate-y-1/2'\n } z-10 flex items-center\n justify-center rounded-full text-[var(--malachite-text-placeholder)]\n hover:text-[var(--malachite-text-primary)] transition-colors\n focus-visible:[outline:2px_solid_var(--malachite-text-primary)] focus-visible:outline-offset-2 ${CLEAR_OFFSET_CLASSES[size]}`}\n >\n <CloseIcon size={13} />\n </button>\n )}\n <DropdownTrigger\n hasClear={showClear}\n onClear={handleClear}\n clearLabel={clearLabel}\n ref={triggerRef as React.Ref<HTMLElement>}\n isOpen={isOpen}\n onClick={(fromKeyboard) => {\n if (disabled) {\n return;\n }\n setKeyboardNavigation(!!fromKeyboard);\n setIsOpen(!isOpen);\n }}\n selectedItem={selectedItem}\n disabled={disabled}\n error={isError}\n tone={tone}\n placeholder={placeholder}\n search={search}\n showSubtitleInTrigger={showSubtitleInTrigger}\n searchQuery={searchQuery}\n onSearchChange={setSearchQuery}\n onFocusOpen={() => {\n if (!reopenOnFocusRef.current) {\n reopenOnFocusRef.current = true;\n return;\n }\n setIsOpen(true);\n }}\n onArrowDown={() => {\n if (!disabled) {\n enterPanel();\n }\n }}\n onTabAway={() => {\n if (isOpen) {\n dismissPanel();\n }\n }}\n size={size}\n controlId={controlId}\n hasCallerId={!!id}\n labelId={labelId}\n describedBy={describedBy}\n required={required}\n ariaLabel={ariaLabel}\n ariaLabelledBy={ariaLabelledBy}\n />\n {isOpen &&\n createPortal(\n <DropdownPanel\n ref={panelRef}\n style={{\n position: 'fixed',\n top: panelPosition?.top ?? 0,\n left: panelPosition?.left ?? 0,\n width: panelPosition?.width,\n maxHeight: panelPosition?.maxHeight,\n visibility: panelPosition ? 'visible' : 'hidden',\n opacity: panelPosition ? 1 : 0,\n }}\n items={visibleItems}\n onItemSelected={handleItemSelected}\n selectedItem={selectedItem}\n menuLoading={menuLoading}\n emptyMessage={\n items.length === 0\n ? 'No options available'\n : 'No results found'\n }\n subtitleLayout={subtitleLayout}\n size={size}\n autoFocus={!search || focusPanelOnOpen}\n positioned={panelPosition !== null}\n onDismiss={dismissPanel}\n keyboardNavigation={keyboardNavigation}\n onKeyboardNavigation={() => setKeyboardNavigation(true)}\n />,\n document.body,\n )}\n </div>\n {helperText && (\n <div\n id={helperTextId}\n className=\"mt-1 text-[length:var(--malachite-font-size-small,13px)] text-left pl-2 text-[var(--malachite-text-dimmed,rgb(161,161,161))]\"\n >\n {helperText}\n </div>\n )}\n <FieldMessage id={errorMessageId} message={errorMessage} spaced />\n </>\n );\n }}\n </BaseFormComponent>\n );\n};\n\nexport default Dropdown;\n"],"names":["BadgeHost","React","TriggerTag","id","text","disabled","jsx","Tag","INLINE_MARKDOWN_SYNTAX","ItemSubtitle","MarkdownBlock","PANEL_MESSAGE_STYLE","ANNOTATION_FONT_SIZE","OPTION_SELECTOR","panelOptions","panel","subtitleSearchText","subtitle","inlineMarkdownText","matchesSearch","item","query","q","labelMatches","subtitleMatches","rightSideTextMatches","TRIGGER_SIZE_HEIGHT","TRIGGER_SIZE_CLASSES","CONTROL_TEXT_SIZE_CLASS","TRIGGER_SIZE_STACKED_CLASSES","CLEAR_OFFSET_CLASSES","CLEAR_STACKED_TOP_CLASSES","TRIGGER_SIZE_RADIUS","NEVER","ValueRow","wrap","children","Fragment","LabelRow","row","DropdownTrigger","isOpen","onClick","selectedItem","error","tone","placeholder","search","showSubtitleInTrigger","searchQuery","onSearchChange","onFocusOpen","onArrowDown","onTabAway","size","hasClear","onClear","clearLabel","controlId","labelId","describedBy","required","ariaLabel","ariaLabelledBy","hasCallerId","forwardedRef","stacked","sizeClasses","sizeRadius","valueId","subtitleId","tagId","rendersButton","hasTag","showsSearchTag","valueIds","namesItself","labelledBy","tagOutsideName","handleTriggerKeyDown","event","valueTextRef","useRef","subtitleTextRef","triggerVisual","getTriggerVisual","showValueLabel","valueText","triggerSubtitle","isValueTruncated","isCut","cutLines","setCutLines","useState","measureTruncatedLines","value","jsxs","FOCUS_RING_WITHIN_INPUT","DROPDOWN_TRIGGER_ATTR","e","Tooltip","CloseIcon","CaretDownIcon","trigger","FOCUS_RING","tooltipLines","DropdownItemComponent","selected","showTooltipOnFocus","subtitleLayout","onItemSelected","textColor","optionId","useId","optionLabelId","optionSubtitleId","optionBadgeId","labelRef","subtitleRef","rightSideRef","measureOptionLines","label","rightSide","rightSideTextColor","rightSideJustify","option","hasBadge","DropdownPanel","props","ref","items","menuLoading","emptyMessage","autoFocus","positioned","onDismiss","keyboardNavigation","onKeyboardNavigation","style","panelRef","popupIdentity","usePopupLayer","useInsertionEffect","ensureDropdownPanelStyles","useTopLayer","useEffect","options","_a","node","current","target","MENU_SPECS","MENU_MAX_HEIGHT_PX","CONTROL_TEXT_SIZE","Spinner","index","prev","showGroupHeader","Dropdown","defaultValue","hint","rightSideContent","tooltip","name","requiredIndicator","loading","formControl","description","helperText","clearable","fullWidth","width","minWidth","menuAlign","descriptionId","hintId","helperTextId","useFormFieldIds","setIsOpen","ownValue","setOwnValue","selectedId","showClear","triggerIsStacked","lastDefaultValueRef","setSearchQuery","focusPanelOnOpen","setFocusPanelOnOpen","setKeyboardNavigation","dropdownRef","triggerRef","panelPosition","setPanelPosition","reopenOnFocusRef","focusTrigger","useCallback","getDeepActiveElement","handleClear","reportSelectionRef","reportEmptyRef","updatePanelPosition","measureMenuGeometry","handleClickOutside","path","inTrigger","inPanel","_b","_c","reportBlurRef","popEscapeLayer","pushEscapeLayer","handleScrollOrResize","frame","lastRect","followTrigger","rect","isTriggerOffscreen","signature","rectSignature","useLayoutEffect","observer","handleItemSelected","dismissPanel","enterPanel","first","visibleItems","BaseFormComponent","LoadingInput","controlWidthStyle","fieldError","message","onFieldChange","onFieldBlur","emptyValue","isError","errorMessage","errorMessageId","next","fromKeyboard","createPortal","FieldMessage"],"mappings":"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"}
1
+ {"version":3,"file":"Dropdown.js","sources":["../../src/components/Dropdown.tsx"],"sourcesContent":["import React, {\n useId,\n useState,\n useRef,\n useEffect,\n useInsertionEffect,\n useLayoutEffect,\n useCallback,\n} from 'react';\nimport { createPortal } from 'react-dom';\nimport { Control, FieldPath, FieldValues } from 'react-hook-form';\nimport BaseFormComponent, {\n type RequiredIndicator,\n type RightSideContent,\n useFormFieldIds,\n} from './BaseFormComponent';\nimport CaretDownIcon from './CustomIcons/CaretDownIcon';\nimport CloseIcon from './CustomIcons/CloseIcon';\nimport FieldMessage from './FieldMessage';\nimport LoadingInput from './LoadingInput';\nimport Spinner from './Spinner';\nimport Tag from './Tag';\nimport Tooltip from './Tooltip';\nimport MarkdownBlock from './Typography/MarkdownBlock';\nimport { inlineMarkdownText } from './Typography/inlineMarkdown';\nimport { getDeepActiveElement } from './activeElement';\nimport { CONTROL_TEXT_SIZE, CONTROL_TEXT_SIZE_CLASS } from './controlTextSize';\nimport { controlWidthStyle } from './controlWidth';\nimport { DROPDOWN_TRIGGER_ATTR, type DropdownTone, getTriggerVisual } from './dropdownTriggerStyle';\nimport { pushEscapeLayer } from './escapeLayers';\nimport {\n MENU_MAX_HEIGHT_PX,\n MENU_SPECS,\n type MenuGeometry,\n isTriggerOffscreen,\n measureMenuGeometry,\n rectSignature,\n} from './floatingMenuGeometry';\nimport { FOCUS_RING, FOCUS_RING_WITHIN_INPUT } from './focusRing';\nimport { hasBadge } from './hasBadge';\nimport { ensureDropdownPanelStyles } from './optionRowStyles';\nimport { usePopupLayer } from './overlayLayers';\nimport { useTopLayer } from './topLayer';\nimport { isCut, tooltipLines } from './truncatedLines';\n\n// The menu portals into document.body, outside any shadow root, so a Tailwind-styled badge (a Tag)\n// needs a shadow host of its own; loaded only when a badge is passed.\nconst BadgeHost = React.lazy(() => import('./ActionMenuTagHost'));\n\nconst TriggerTag = ({ id, text, disabled }: { id: string; text: string; disabled?: boolean }) => (\n <span\n id={id}\n className={`flex min-w-0 max-w-[40%] [flex-shrink:3] ${disabled ? 'opacity-60' : ''}`}\n >\n <Tag value={text} paddingSize=\"compact\" fontSize=\"xsmall\" textTransform=\"none\" />\n </span>\n);\n\nexport type { DropdownTone };\n\nexport interface DropdownItem {\n id: string;\n label: string;\n icon?: React.ReactNode;\n /** Alternate label shown in the closed trigger when selected (falls back to `label`). */\n triggerLabel?: string;\n /** Short tag shown at the right of the closed trigger while this item is selected. */\n triggerTag?: string;\n /** Items sharing a `group` render under a section header, in first-seen order. */\n group?: string;\n subtitle?: string;\n rightSideText?: string;\n rightSideTextVariant?: 'muted' | 'primary';\n rightSideTextAlignment?: 'left' | 'right';\n /** Right-aligned badge shown in the open menu only (not in the trigger or the search input). */\n badge?: React.ReactNode;\n}\n\ninterface DropdownBaseProps {\n label?: string;\n hint?: string;\n rightSideContent?: RightSideContent;\n tooltip?: string;\n name: FieldPath<FieldValues> | string;\n loading?: boolean;\n menuLoading?: boolean;\n items: DropdownItem[];\n onItemSelected?: (id?: string) => void;\n defaultValue?: string;\n /** Controlled selection. When set, the trigger always reflects this id and the component\n * keeps no selection state of its own. Pass it with `onItemSelected`. */\n value?: string;\n disabled?: boolean;\n error?: boolean;\n /** `pending` marks a value the user still has to supply. Outranks open and selection. */\n tone?: DropdownTone;\n className?: string;\n formControl?: Control<FieldValues, unknown>;\n description?: string;\n required?: boolean;\n requiredIndicator?: RequiredIndicator;\n helperText?: React.ReactNode;\n placeholder?: string;\n subtitleLayout?: SubtitleLayout;\n /** Adds a clear control to the trigger, reported as `onItemSelected(undefined)`. */\n clearable?: boolean;\n /** 'large' (42px) for form inputs; 'medium' (32px) for toolbar chips; 'small' (28px) beside a title. */\n size?: DropdownSize;\n fullWidth?: boolean;\n width?: string | number;\n /**\n * Raises the open menu's floor above the shared 160px one, without widening the trigger.\n * For a control pinned narrow by its column — a role picker in a 160px cell, a member\n * picker in a 200px slot — whose options carry a subtitle the trigger never has to show.\n */\n minWidth?: number;\n /**\n * Which trigger edge a menu wider than its trigger lines up with. `end` grows it leftwards,\n * for a control at the right of its container. Either flips when the viewport has no room.\n */\n menuAlign?: 'start' | 'end';\n /** Names the trigger from the light DOM, where `htmlFor` cannot reach into the shadow root. */\n id?: string;\n 'aria-label'?: string;\n 'aria-labelledby'?: string;\n}\n\n/**\n * The search trigger is a single-line text input with nowhere for a second line, so\n * `showSubtitleInTrigger` is rejected alongside `search` rather than silently ignored.\n */\ntype DropdownTriggerModeProps =\n | {\n search?: false;\n /** Promotes the selected item's `subtitle` into the closed trigger, beneath the value. */\n showSubtitleInTrigger?: boolean;\n }\n | { search: true; showSubtitleInTrigger?: never };\n\nexport type DropdownProps = DropdownBaseProps & DropdownTriggerModeProps;\n\n/**\n * Matches Button and the Figma component library: 28 / 32 / 42px. These names moved up a\n * tier in 0.71 — what was `xsmall`/`small`/`medium` is now `small`/`medium`/`large`.\n */\nexport type DropdownSize = 'small' | 'medium' | 'large';\n\nexport type SubtitleLayout = 'inline' | 'stacked';\n\n// Text without these renders the same parsed or not, so it skips the parser.\nconst INLINE_MARKDOWN_SYNTAX = /[*`[<&\\\\]/;\n\n// Inert links: a <button> takes no interactive content.\nconst ItemSubtitle = ({ text }: { text: string }) =>\n INLINE_MARKDOWN_SYNTAX.test(text) ? (\n <MarkdownBlock\n text={text}\n variant=\"inline\"\n color=\"inherit\"\n size=\"inherit\"\n links=\"inert\"\n omitMargin\n />\n ) : (\n text\n );\n\nconst PANEL_MESSAGE_STYLE: React.CSSProperties = {\n display: 'flex',\n alignItems: 'center',\n justifyContent: 'center',\n gap: 8,\n padding: '24px 16px',\n color: 'var(--malachite-text-dimmed, rgb(161, 161, 161))',\n};\n\n// Figma pins the option's inline annotation at 11px on every tier — unlike the label,\n// it does not ride the ladder (Item Large 68:2617, Item Medium 2343:2134).\nconst ANNOTATION_FONT_SIZE = 'var(--malachite-font-size-xsmall, 11px)';\n\nconst OPTION_SELECTOR = '[data-dropdown-option]';\n\nconst panelOptions = (panel: HTMLElement | null): HTMLElement[] =>\n Array.from(panel?.querySelectorAll<HTMLElement>(OPTION_SELECTOR) ?? []);\n\n// Search what the subtitle shows: link and image text, not their destinations or markers.\nconst subtitleSearchText = (subtitle: string) =>\n INLINE_MARKDOWN_SYNTAX.test(subtitle)\n ? inlineMarkdownText(subtitle)\n : subtitle.replace(/\\s+/g, ' ');\n\nconst matchesSearch = (item: DropdownItem, query: string) => {\n const q = query.toLowerCase();\n const labelMatches = item.label.toLowerCase().includes(q);\n const subtitleMatches = item.subtitle\n ? subtitleSearchText(item.subtitle).toLowerCase().includes(q)\n : false;\n const rightSideTextMatches = item.rightSideText\n ? item.rightSideText.toLowerCase().includes(q)\n : false;\n return labelMatches || subtitleMatches || rightSideTextMatches;\n};\n\nconst TRIGGER_SIZE_HEIGHT: Record<DropdownSize, string> = {\n small: 'h-[var(--malachite-control-height-small,28px)]',\n medium: 'h-[var(--malachite-control-height-medium,32px)]',\n large: 'h-[var(--malachite-control-height-large,42px)]',\n};\n\nconst TRIGGER_SIZE_CLASSES: Record<DropdownSize, string> = {\n small: `${TRIGGER_SIZE_HEIGHT.small} px-2.5 py-1.5 ${CONTROL_TEXT_SIZE_CLASS.small}`,\n medium: `${TRIGGER_SIZE_HEIGHT.medium} px-3 py-1.5 ${CONTROL_TEXT_SIZE_CLASS.medium}`,\n large: `${TRIGGER_SIZE_HEIGHT.large} px-4 py-2.5 ${CONTROL_TEXT_SIZE_CLASS.large}`,\n};\n\nconst TRIGGER_SIZE_STACKED_CLASSES: Record<DropdownSize, string> = {\n small: `min-h-[var(--malachite-control-height-small,28px)] px-2.5 py-1.5 ${CONTROL_TEXT_SIZE_CLASS.small}`,\n medium: `min-h-[var(--malachite-control-height-medium,32px)] px-3 py-1.5 ${CONTROL_TEXT_SIZE_CLASS.medium}`,\n large: `min-h-[var(--malachite-control-height-large,42px)] px-4 py-2.5 ${CONTROL_TEXT_SIZE_CLASS.large}`,\n};\n\nconst CLEAR_OFFSET_CLASSES: Record<DropdownSize, string> = {\n small: 'right-[26px] size-4',\n medium: 'right-[30px] size-4',\n large: 'right-[38px] size-4',\n};\n\nconst CLEAR_STACKED_TOP_CLASSES: Record<DropdownSize, string> = {\n small: 'top-[calc(var(--malachite-control-height-small,28px)/2)] -translate-y-1/2',\n medium: 'top-[calc(var(--malachite-control-height-medium,32px)/2)] -translate-y-1/2',\n large: 'top-[calc(var(--malachite-control-height-large,42px)/2)] -translate-y-1/2',\n};\n\n// Radius tracks the tier in Figma: 10 / 12 / 14. Only 12 has a --malachite-radius-* rung.\nconst TRIGGER_SIZE_RADIUS: Record<DropdownSize, string> = {\n small: 'rounded-[var(--malachite-radius-10,10px)]',\n medium: 'rounded-xl',\n large: 'rounded-[var(--malachite-radius-xxl,14px)]',\n};\n\nconst NEVER = () => false;\n\nconst ValueRow: React.FC<{ wrap: boolean; id?: string; children: React.ReactNode }> = ({\n wrap,\n id,\n children,\n}) =>\n wrap ? (\n <span id={id} className=\"min-w-0 flex items-center gap-2\">\n {children}\n </span>\n ) : (\n <>{children}</>\n );\n\nconst LabelRow: React.FC<{ row: boolean; children: React.ReactNode }> = ({ row, children }) =>\n row ? (\n <span style={{ display: 'flex', alignItems: 'center', gap: 8, minWidth: 0 }}>\n {children}\n </span>\n ) : (\n <>{children}</>\n );\n\ninterface DropdownTriggerProps {\n isOpen: boolean;\n onClick: (fromKeyboard?: boolean) => void;\n selectedItem: DropdownItem | undefined;\n hasClear?: boolean;\n onClear?: (event: React.MouseEvent<HTMLButtonElement>) => void;\n clearLabel?: string;\n disabled?: boolean;\n error?: boolean;\n tone?: DropdownTone;\n placeholder?: string;\n search?: boolean;\n showSubtitleInTrigger?: boolean;\n searchQuery?: string;\n onSearchChange?: (value: string) => void;\n onFocusOpen?: () => void;\n /** ArrowDown on the trigger: opens the menu, or steps into it if already open. */\n onArrowDown?: () => void;\n /** Tab off the trigger: dismisses the panel, which is portaled and would outlive the focus. */\n onTabAway?: () => void;\n size?: DropdownSize;\n controlId: string;\n labelId?: string;\n describedBy?: string;\n required?: boolean;\n ariaLabel?: string;\n ariaLabelledBy?: string;\n /** A caller-supplied id means an external `<label for>` may be naming the control. */\n hasCallerId?: boolean;\n}\n\nconst DropdownTrigger = React.forwardRef<HTMLElement, DropdownTriggerProps>(\n (\n {\n isOpen,\n onClick,\n selectedItem,\n disabled = false,\n error = false,\n tone,\n placeholder,\n search = false,\n showSubtitleInTrigger = false,\n searchQuery = '',\n onSearchChange,\n onFocusOpen,\n onArrowDown,\n onTabAway,\n size = 'large',\n hasClear = false,\n onClear,\n clearLabel,\n controlId,\n labelId,\n describedBy,\n required = false,\n ariaLabel,\n ariaLabelledBy,\n hasCallerId = false,\n },\n forwardedRef,\n ) => {\n const stacked = showSubtitleInTrigger && !search && !!selectedItem?.subtitle;\n const sizeClasses = stacked\n ? TRIGGER_SIZE_STACKED_CLASSES[size]\n : TRIGGER_SIZE_CLASSES[size];\n const sizeRadius = TRIGGER_SIZE_RADIUS[size];\n const valueId = `${controlId}-value`;\n const subtitleId = `${controlId}-subtitle`;\n // aria-labelledby outranks aria-label in the accessible-name algorithm, so the\n // generated label+value pair has to be dropped for a caller's aria-label to apply.\n // Named off nothing, the button takes its name from every descendant — the subtitle\n // included, which `aria-describedby` then repeats. Naming it off the value alone fixes\n // that, but only where nothing else already names the control.\n const tagId = `${controlId}-tag`;\n const rendersButton = !search || disabled;\n const hasTag = rendersButton && !!selectedItem?.triggerTag;\n const showsSearchTag = !rendersButton && !isOpen && !!selectedItem?.triggerTag;\n const valueIds = hasTag ? `${valueId} ${tagId}` : valueId;\n const namesItself = !labelId && !ariaLabel && !hasCallerId && (stacked || hasTag);\n const labelledBy =\n ariaLabelledBy ??\n (labelId && !ariaLabel ? `${labelId} ${valueIds}` : undefined) ??\n (namesItself ? valueIds : undefined);\n const tagOutsideName = hasTag && !labelledBy?.split(' ').includes(tagId);\n\n const handleTriggerKeyDown = (event: React.KeyboardEvent): void => {\n // Not prevented: Tab carries on to the next control. In search mode the trigger keeps\n // focus on open, so this is the panel's only Tab dismissal.\n if (event.key === 'Tab') {\n onTabAway?.();\n return;\n }\n if (event.key !== 'ArrowDown') {\n return;\n }\n event.preventDefault();\n onArrowDown?.();\n };\n\n const valueTextRef = useRef<HTMLSpanElement>(null);\n const subtitleTextRef = useRef<HTMLSpanElement>(null);\n const triggerVisual = getTriggerVisual({ disabled, error, tone, open: isOpen });\n const showValueLabel = !isOpen && !!selectedItem;\n const valueText = selectedItem?.triggerLabel ?? selectedItem?.label;\n const triggerSubtitle = stacked ? selectedItem?.subtitle : undefined;\n const isValueTruncated = () => isCut(valueTextRef.current);\n\n // A tooltip reads its text at render, but which line is cut off is only knowable on\n // hover — so the one measurement pass that decides whether to show also records what\n // to say. The initial value never shows: untruncated, the tooltip refuses to open.\n const [cutLines, setCutLines] = useState({ value: false, subtitle: true });\n const measureTruncatedLines = () => {\n const value = isValueTruncated();\n const subtitle = isCut(subtitleTextRef.current);\n if (!value && !subtitle) {\n return false;\n }\n setCutLines({ value, subtitle });\n return true;\n };\n\n if (search && !disabled) {\n return (\n <div\n ref={forwardedRef as React.Ref<HTMLDivElement>}\n className={`\n relative w-full ${sizeClasses} ${sizeRadius}\n border border-solid\n transition-all duration-200\n flex items-center ${FOCUS_RING_WITHIN_INPUT}\n `}\n style={triggerVisual}\n {...{ [DROPDOWN_TRIGGER_ATTR]: '' }}\n onClick={(e) => e.stopPropagation()}\n >\n {selectedItem?.icon && (\n <span className=\"flex shrink-0 items-center justify-center pr-2\">\n {selectedItem.icon}\n </span>\n )}\n <Tooltip text={valueText} shouldShow={isValueTruncated} isShrinkable fill>\n <div className=\"relative flex-1 flex items-center min-w-0\">\n {showValueLabel && (\n <span\n aria-hidden=\"true\"\n className=\"absolute inset-0 flex items-center pointer-events-none\"\n >\n <span\n ref={valueTextRef}\n className=\"min-w-0 block truncate text-[length:inherit]\n text-[var(--malachite-text-primary)]\"\n >\n {valueText}\n </span>\n </span>\n )}\n <input\n id={controlId}\n type=\"text\"\n aria-label={ariaLabel}\n aria-labelledby={ariaLabelledBy}\n aria-invalid={error || undefined}\n aria-required={required || undefined}\n aria-describedby={\n [describedBy, showsSearchTag ? tagId : undefined]\n .filter(Boolean)\n .join(' ') || undefined\n }\n value={isOpen ? searchQuery : (selectedItem?.label ?? '')}\n onChange={(e) => {\n e.stopPropagation();\n onSearchChange?.(e.target.value);\n if (!isOpen) {\n onClick();\n }\n }}\n onFocus={() => {\n onFocusOpen?.();\n }}\n onKeyDown={handleTriggerKeyDown}\n placeholder={placeholder ?? 'Select Field'}\n className={`flex-1 min-w-0 bg-transparent outline-none\n text-[length:inherit] font-normal\n placeholder:text-[var(--malachite-text-dimmed)] ${\n showValueLabel\n ? 'text-transparent'\n : 'text-[var(--malachite-text-primary)]'\n }`}\n />\n </div>\n </Tooltip>\n {showsSearchTag && selectedItem?.triggerTag && (\n <>\n <span aria-hidden=\"true\" className=\"w-2 shrink-0\" />\n <TriggerTag id={tagId} text={selectedItem.triggerTag} />\n </>\n )}\n {hasClear && (\n <button\n type=\"button\"\n aria-label={clearLabel}\n onClick={onClear}\n className=\"flex shrink-0 items-center justify-center pl-2 cursor-pointer\n bg-transparent border-none p-0 text-[var(--malachite-text-placeholder)]\n hover:text-[var(--malachite-text-primary)] transition-colors\n rounded-full focus-visible:[outline:2px_solid_var(--malachite-text-primary)] focus-visible:outline-offset-2\"\n >\n <CloseIcon size={13} />\n </button>\n )}\n <div className=\"flex items-center justify-center pl-2\">\n {/* Mouse-only affordance: the input beside it already opens the menu on\n click and focus, so this stays out of the tab order to avoid a\n duplicate stop — but it must still be a button, not a click-handling\n span, so it is exposed and activatable rather than invisible. */}\n <button\n type=\"button\"\n tabIndex={-1}\n aria-label={isOpen ? 'Close options' : 'Open options'}\n onClick={(e) => {\n e.stopPropagation();\n onClick();\n }}\n className=\"flex items-center justify-center cursor-pointer bg-transparent border-none p-0\"\n >\n <CaretDownIcon\n size={13}\n style={{\n color: isOpen\n ? 'var(--malachite-text-primary, rgb(10, 10, 10))'\n : 'var(--malachite-text-placeholder, rgb(187, 187, 187))',\n transition: 'transform 0.2s ease, color 0.2s ease',\n transform: isOpen ? 'rotate(180deg)' : 'rotate(0deg)',\n }}\n />\n </button>\n </div>\n </div>\n );\n }\n\n const trigger = (\n <button\n ref={forwardedRef as React.Ref<HTMLButtonElement>}\n id={controlId}\n type=\"button\"\n aria-label={ariaLabel}\n aria-labelledby={labelledBy}\n aria-invalid={error || undefined}\n aria-required={required || undefined}\n aria-describedby={\n [\n describedBy,\n triggerSubtitle ? subtitleId : undefined,\n tagOutsideName ? tagId : undefined,\n ]\n .filter(Boolean)\n .join(' ') || undefined\n }\n onClick={(e) => {\n e.stopPropagation();\n onClick(e.detail === 0);\n }}\n onKeyDown={handleTriggerKeyDown}\n disabled={disabled}\n style={triggerVisual}\n {...{ [DROPDOWN_TRIGGER_ATTR]: '' }}\n className={`\n relative w-full ${sizeClasses} ${sizeRadius}\n border border-solid\n transition-all duration-200\n flex ${stacked ? 'items-start' : 'items-center'} gap-3\n cursor-pointer\n disabled:cursor-not-allowed ${FOCUS_RING}\n `}\n >\n {/* Spans: <button> takes phrasing content only. */}\n <span\n id={triggerSubtitle ? undefined : valueId}\n className={`text-left ${hasTag ? 'flex-[1_1_auto]' : 'flex-1'} min-w-0 flex ${\n triggerSubtitle ? 'flex-col gap-1' : 'items-center gap-2'\n }`}\n >\n {selectedItem ? (\n <>\n <ValueRow wrap={!!triggerSubtitle} id={valueId}>\n {selectedItem.icon && (\n <span className=\"flex items-center justify-center shrink-0\">\n {selectedItem.icon}\n </span>\n )}\n <Tooltip\n text={valueText}\n shouldShow={triggerSubtitle ? NEVER : isValueTruncated}\n triggerAs=\"span\"\n isShrinkable\n >\n <span\n ref={valueTextRef}\n className={`min-w-0 block truncate text-[length:inherit] ${\n disabled\n ? 'text-[var(--malachite-text-placeholder)]'\n : 'text-[var(--malachite-text-primary)]'\n }`}\n >\n {valueText}\n </span>\n </Tooltip>\n </ValueRow>\n {triggerSubtitle && (\n <span\n id={subtitleId}\n ref={subtitleTextRef}\n className=\"min-w-0 block truncate text-[length:var(--malachite-font-size-xsmall,11px)] text-[var(--malachite-text-secondary,rgb(123,123,123))] leading-normal\"\n >\n <ItemSubtitle text={triggerSubtitle} />\n </span>\n )}\n </>\n ) : (\n <span\n className={`flex-1 min-w-0 truncate text-[length:inherit] ${\n disabled\n ? 'text-[var(--malachite-text-placeholder)]'\n : 'text-[var(--malachite-text-dimmed)]'\n }`}\n >\n {placeholder ?? 'Select Field'}\n </span>\n )}\n </span>\n {selectedItem?.triggerTag && (\n <TriggerTag id={tagId} text={selectedItem.triggerTag} disabled={disabled} />\n )}\n {hasClear && <span aria-hidden=\"true\" className=\"shrink-0 w-4\" />}\n <span className=\"flex items-center justify-center shrink-0\">\n <CaretDownIcon\n size={13}\n style={{\n color: isOpen\n ? 'var(--malachite-text-primary, rgb(10, 10, 10))'\n : 'var(--malachite-text-placeholder, rgb(187, 187, 187))',\n transition: 'transform 0.2s ease, color 0.2s ease',\n transform: isOpen ? 'rotate(180deg)' : 'rotate(0deg)',\n }}\n />\n </span>\n </button>\n );\n\n // The button is what takes focus, so the tooltip wraps it rather than a line inside:\n // mounted on a line it could only ever open with a pointer, and nested tooltips opened\n // together on hover. Its text is already in the trigger's name and description, so it\n // repeats it visually only. `fill`, not `isShrinkable`, whose `overflow: hidden` would\n // clip the error ring the button paints outside its border box.\n // Gated on the prop, not on there being a subtitle to show: keyed off the selection the\n // wrapper would appear on the first choice, remounting the button `focusTrigger` has\n // just handed focus back to and dropping the keyboard user at <body>.\n return showSubtitleInTrigger && !search ? (\n <Tooltip\n text={tooltipLines([\n ['value', cutLines.value && valueText],\n [\n 'subtitle',\n cutLines.subtitle && triggerSubtitle && (\n <ItemSubtitle text={triggerSubtitle} />\n ),\n ],\n ])}\n shouldShow={triggerSubtitle ? measureTruncatedLines : NEVER}\n fill\n describesTrigger={false}\n >\n {trigger}\n </Tooltip>\n ) : (\n trigger\n );\n },\n);\nDropdownTrigger.displayName = 'DropdownTrigger';\n\ninterface DropdownItemComponentProps {\n item: DropdownItem;\n selected: boolean;\n showTooltipOnFocus: boolean;\n subtitleLayout: SubtitleLayout;\n onItemSelected: (item: DropdownItem) => void;\n}\n\nconst DropdownItemComponent = ({\n item,\n selected,\n showTooltipOnFocus,\n subtitleLayout,\n onItemSelected,\n}: DropdownItemComponentProps) => {\n const textColor = selected\n ? 'var(--malachite-accent-foreground, rgb(2, 122, 66))'\n : 'var(--malachite-text-primary, rgb(10, 10, 10))';\n const stacked = subtitleLayout === 'stacked' && !!item.subtitle;\n const optionId = `mal-${useId().replace(/[^a-zA-Z0-9_-]/g, '')}`;\n const optionLabelId = `${optionId}-label`;\n const optionSubtitleId = `${optionId}-subtitle`;\n const optionBadgeId = `${optionId}-badge`;\n const labelRef = useRef<HTMLSpanElement>(null);\n const subtitleRef = useRef<HTMLSpanElement>(null);\n const rightSideRef = useRef<HTMLSpanElement>(null);\n\n // Seeded all-cut: `Tooltip` skips `shouldShow` when its text is empty.\n const [cutLines, setCutLines] = useState({ label: true, subtitle: true, rightSide: true });\n const measureOptionLines = () => {\n const label = isCut(labelRef.current);\n const subtitle = isCut(subtitleRef.current);\n const rightSide = isCut(rightSideRef.current);\n if (!label && !subtitle && !rightSide) {\n return false;\n }\n setCutLines({ label, subtitle, rightSide });\n return true;\n };\n\n // Default to muted so right-side metadata (e.g. category tags) de-emphasises\n // against the primary item label. Consumers can opt back in with 'primary'.\n const rightSideTextColor =\n item.rightSideTextVariant === 'primary'\n ? 'var(--malachite-text-right-side-text-primary, rgb(10, 10, 10))'\n : 'var(--malachite-text-right-side-text-muted, rgb(123, 123, 123))';\n\n const rightSideJustify = item.rightSideTextAlignment === 'left' ? 'flex-start' : 'flex-end';\n\n const option = (\n // `role=\"option\"` would be invalid — nothing here declares a `listbox`, and an\n // orphaned option is dropped from the a11y tree. `aria-current`, not\n // `aria-pressed`: these are one-of-many choices, not toggles. tabIndex={-1}\n // because the portaled panel is outside the trigger's tab order; DropdownPanel\n // focuses an option on open and arrow keys move between them.\n <button\n type=\"button\"\n data-dropdown-option=\"\"\n data-selected={selected}\n aria-current={selected || undefined}\n // Unnamed, the option takes its name from everything inside it — a sentence-length\n // subtitle or a badge included.\n aria-labelledby={item.subtitle || hasBadge(item.badge) ? optionLabelId : undefined}\n // The id sits on the light-DOM wrapper: one inside the badge's shadow root is unreachable.\n aria-describedby={\n [\n item.subtitle ? optionSubtitleId : undefined,\n hasBadge(item.badge) ? optionBadgeId : undefined,\n ]\n .filter(Boolean)\n .join(' ') || undefined\n }\n tabIndex={-1}\n onClick={(e) => {\n e.stopPropagation();\n onItemSelected(item);\n }}\n className=\"malachite-dropdown-option\"\n style={{\n minHeight: 38,\n borderRadius: 8,\n display: 'flex',\n alignItems: 'center',\n padding: 10,\n gap: 12,\n cursor: 'pointer',\n transition: 'background-color 120ms ease',\n // Reset the UA button chrome. Background is deliberately absent — see PANEL_RULES.\n width: '100%',\n border: 'none',\n textAlign: 'left',\n font: 'inherit',\n color: 'inherit',\n }}\n >\n {/* Spans: <button> takes phrasing content only. */}\n <span\n style={{\n flex: 1,\n display: 'flex',\n alignItems: 'center',\n gap: 12,\n minWidth: 0,\n }}\n >\n <span style={{ flex: '1 1 auto', display: 'block', minWidth: 0 }}>\n <span\n style={\n stacked\n ? { display: 'flex', flexDirection: 'column', gap: 2 }\n : { display: 'flex', alignItems: 'center', gap: 8 }\n }\n >\n <LabelRow row={stacked && !!item.icon}>\n {item.icon && (\n <span\n style={{\n display: 'flex',\n alignItems: 'center',\n justifyContent: 'center',\n flexShrink: 0,\n }}\n >\n {item.icon}\n </span>\n )}\n <span\n id={\n item.subtitle || hasBadge(item.badge)\n ? optionLabelId\n : undefined\n }\n ref={labelRef}\n style={{\n fontWeight: 400,\n color: textColor,\n whiteSpace: 'nowrap',\n overflow: 'hidden',\n textOverflow: 'ellipsis',\n minWidth: 0,\n }}\n >\n {item.label}\n </span>\n </LabelRow>\n {item.subtitle &&\n (stacked ? (\n <span\n id={optionSubtitleId}\n ref={subtitleRef}\n style={{\n fontSize: ANNOTATION_FONT_SIZE,\n fontWeight: 400,\n lineHeight: 1.4,\n color: selected\n ? textColor\n : 'var(--malachite-text-dimmed, rgb(161, 161, 161))',\n whiteSpace: 'nowrap',\n overflow: 'hidden',\n textOverflow: 'ellipsis',\n }}\n >\n <ItemSubtitle text={item.subtitle} />\n </span>\n ) : (\n <span\n style={{\n // Zero basis: the subtitle gives way before the label.\n flexGrow: 1,\n flexBasis: 0,\n display: 'flex',\n alignItems: 'center',\n gap: 8,\n minWidth: 0,\n overflow: 'hidden',\n }}\n >\n <span\n style={{\n fontSize: ANNOTATION_FONT_SIZE,\n fontWeight: 400,\n color: 'var(--malachite-text-secondary, rgb(123, 123, 123))',\n flexShrink: 0,\n }}\n >\n |\n </span>\n <span\n id={optionSubtitleId}\n ref={subtitleRef}\n style={{\n fontSize: ANNOTATION_FONT_SIZE,\n fontWeight: 400,\n color: 'var(--malachite-text-secondary, rgb(123, 123, 123))',\n whiteSpace: 'nowrap',\n overflow: 'hidden',\n textOverflow: 'ellipsis',\n minWidth: 0,\n }}\n >\n <ItemSubtitle text={item.subtitle} />\n </span>\n </span>\n ))}\n </span>\n </span>\n <span\n style={{\n // Reserved only when there is something to put there: an empty slot\n // still holding its width truncates the label and subtitle early.\n minWidth: item.rightSideText\n ? 'var(--malachite-text-right-side-text-min-width, 80px)'\n : 0,\n flexShrink: 1,\n display: 'flex',\n justifyContent: rightSideJustify,\n }}\n >\n {item.rightSideText && (\n <span\n ref={rightSideRef}\n style={{\n fontSize: 'var(--malachite-text-right-side-text-font-size, 12px)',\n fontWeight: 400,\n color: rightSideTextColor,\n whiteSpace: 'nowrap',\n overflow: 'hidden',\n textOverflow: 'ellipsis',\n minWidth: 0,\n }}\n >\n {item.rightSideText}\n </span>\n )}\n </span>\n {hasBadge(item.badge) && (\n <span id={optionBadgeId} style={{ flexShrink: 0, display: 'flex' }}>\n <React.Suspense fallback={null}>\n <BadgeHost>{item.badge}</BadgeHost>\n </React.Suspense>\n </span>\n )}\n </span>\n </button>\n );\n\n // Focus lands on the option itself, and focusin does not reach a descendant, so a keyboard\n // user could never open a tooltip mounted inside it.\n return (\n <Tooltip\n text={tooltipLines([\n ['label', cutLines.label && item.label],\n [\n 'subtitle',\n cutLines.subtitle && item.subtitle && <ItemSubtitle text={item.subtitle} />,\n ],\n ['rightSide', cutLines.rightSide && item.rightSideText],\n ])}\n shouldShow={measureOptionLines}\n showOnFocus={showTooltipOnFocus}\n isShrinkable\n describesTrigger={false}\n >\n {option}\n </Tooltip>\n );\n};\n\ninterface DropdownPanelProps {\n items: DropdownItem[];\n onItemSelected: (item?: DropdownItem) => void;\n selectedItem: DropdownItem | undefined;\n menuLoading?: boolean;\n emptyMessage: string;\n /** Focus an option on open. False in search mode, where the input keeps focus. */\n autoFocus: boolean;\n /** Panel has been measured. It renders `visibility: hidden` until then, and a\n * hidden element cannot take focus, so open-time focus has to wait for this. */\n positioned: boolean;\n /** Close the panel and hand focus back to the trigger. */\n onDismiss: () => void;\n keyboardNavigation: boolean;\n onKeyboardNavigation: () => void;\n subtitleLayout: SubtitleLayout;\n size: DropdownSize;\n}\n\nconst DropdownPanel = React.forwardRef<\n HTMLDivElement,\n DropdownPanelProps & { style?: React.CSSProperties }\n>((props, ref) => {\n const {\n items,\n onItemSelected,\n selectedItem,\n menuLoading,\n emptyMessage,\n autoFocus,\n positioned,\n onDismiss,\n keyboardNavigation,\n onKeyboardNavigation,\n subtitleLayout,\n size,\n style,\n } = props;\n const panelRef = useRef<HTMLDivElement | null>(null);\n const popupIdentity = usePopupLayer('dropdown', true, panelRef);\n\n // The panel only mounts while open, so no condition. useInsertionEffect, not layout:\n // it runs before the DOM mutation, so the rules are in place before the rows are inserted.\n useInsertionEffect(() => {\n ensureDropdownPanelStyles();\n }, []);\n\n useTopLayer(panelRef, true);\n\n // Start on the selected option so Enter re-confirms the current value. Not keyed on\n // `items`: re-running as the filtered list changes would yank focus back to the top.\n useEffect(() => {\n if (!autoFocus || !positioned) {\n return;\n }\n const options = panelOptions(panelRef.current);\n const selected = options.find((option) => option.dataset.selected === 'true');\n // Falls back to the panel: with no options nothing else can hold focus, and Tab-dismiss\n // only fires from inside it.\n (selected ?? options[0] ?? panelRef.current)?.focus();\n }, [autoFocus, positioned]);\n\n const handleKeyDown = (event: React.KeyboardEvent<HTMLDivElement>): void => {\n // The panel is portaled to document.body, so the browser's next tab stop bears no\n // relation to the trigger. Dismissing restores trigger focus so Tab resumes there.\n if (event.key === 'Tab') {\n onDismiss();\n return;\n }\n const options = panelOptions(panelRef.current);\n if (options.length === 0) {\n return;\n }\n const current = options.indexOf(document.activeElement as HTMLElement);\n const target = {\n ArrowDown: current + 1,\n ArrowUp: current - 1,\n Home: 0,\n End: options.length - 1,\n }[event.key];\n if (target === undefined) {\n return;\n }\n event.preventDefault();\n onKeyboardNavigation();\n options[Math.min(Math.max(target, 0), options.length - 1)]?.focus();\n };\n\n // Inline styles, not Tailwind: this portals into document.body, outside the\n // Shadow DOM the malachite stylesheet is adopted into.\n return (\n <div\n ref={(node) => {\n panelRef.current = node;\n if (typeof ref === 'function') {\n ref(node);\n } else if (ref) {\n ref.current = node;\n }\n }}\n {...popupIdentity}\n tabIndex={-1}\n onKeyDown={handleKeyDown}\n style={{\n background: MENU_SPECS.standard.background,\n border: MENU_SPECS.standard.border,\n borderRadius: MENU_SPECS.standard.radius,\n boxShadow: MENU_SPECS.standard.shadow,\n maxHeight: MENU_MAX_HEIGHT_PX,\n overflow: 'hidden',\n display: 'flex',\n flexDirection: 'column',\n fontSize: CONTROL_TEXT_SIZE[size],\n ...style,\n }}\n >\n {menuLoading ? (\n <div style={PANEL_MESSAGE_STYLE}>\n <Spinner size=\"xxxsmall\" />\n <span>Loading…</span>\n </div>\n ) : items.length === 0 ? (\n <div style={PANEL_MESSAGE_STYLE}>{emptyMessage}</div>\n ) : (\n <div\n style={{\n display: 'flex',\n flexDirection: 'column',\n gap: 4,\n padding: MENU_SPECS.standard.padding,\n overflowY: 'auto',\n scrollbarWidth: 'thin',\n scrollbarColor:\n 'var(--malachite-text-placeholder, rgb(187, 187, 187)) transparent',\n }}\n >\n {items.map((item, index) => {\n const prev = items[index - 1];\n const showGroupHeader =\n !!item.group && (!prev || prev.group !== item.group);\n return (\n <div key={item.id} style={{ flexShrink: 0 }}>\n {showGroupHeader && (\n <div\n style={{\n padding: '6px 10px 4px',\n fontSize: 12,\n fontWeight: 500,\n color: 'var(--malachite-text-secondary, rgb(123, 123, 123))',\n textTransform: 'none',\n userSelect: 'none',\n }}\n >\n {item.group}\n </div>\n )}\n <DropdownItemComponent\n item={item}\n onItemSelected={onItemSelected}\n subtitleLayout={subtitleLayout}\n selected={item.id === selectedItem?.id || false}\n showTooltipOnFocus={keyboardNavigation}\n />\n </div>\n );\n })}\n </div>\n )}\n </div>\n );\n});\nDropdownPanel.displayName = 'DropdownPanel';\n\nexport const Dropdown = ({\n items,\n onItemSelected,\n defaultValue,\n value,\n disabled = false,\n error,\n tone,\n label,\n hint,\n rightSideContent,\n tooltip,\n name,\n required = false,\n requiredIndicator,\n loading,\n menuLoading,\n formControl,\n description,\n helperText,\n placeholder,\n search = false,\n showSubtitleInTrigger = false,\n subtitleLayout = 'inline',\n clearable = false,\n size = 'large',\n fullWidth = false,\n width,\n minWidth,\n menuAlign = 'start',\n id,\n 'aria-label': ariaLabel,\n 'aria-labelledby': ariaLabelledBy,\n}: DropdownProps) => {\n const { controlId, labelId, descriptionId, hintId, helperTextId } = useFormFieldIds({\n id,\n label,\n description,\n hint,\n helperText: true,\n });\n const [isOpen, setIsOpen] = useState(false);\n // The id, never the resolved item: a cached object goes stale when `items` is rebuilt.\n const [ownValue, setOwnValue] = useState(defaultValue);\n const selectedId = value ?? ownValue;\n const selectedItem = items.find((item) => item.id === selectedId);\n const showClear = clearable && selectedId !== undefined && selectedId !== '' && !disabled;\n const triggerIsStacked = showSubtitleInTrigger && !search && !!selectedItem?.subtitle;\n const clearLabel = `Clear ${label ?? placeholder ?? 'selection'}`;\n\n // `defaultValue` only seeds the state, so a later change has to be pushed in.\n const lastDefaultValueRef = useRef(defaultValue);\n useEffect(() => {\n if (lastDefaultValueRef.current === defaultValue) {\n return;\n }\n lastDefaultValueRef.current = defaultValue;\n setOwnValue(defaultValue);\n }, [defaultValue]);\n const [searchQuery, setSearchQuery] = useState('');\n // Search mode only: set when the panel is opened by ArrowDown, so focus follows the\n // user into the list on mount instead of staying in the input.\n const [focusPanelOnOpen, setFocusPanelOnOpen] = useState(false);\n const [keyboardNavigation, setKeyboardNavigation] = useState(false);\n const dropdownRef = useRef<HTMLDivElement>(null);\n const triggerRef = useRef<HTMLElement>(null);\n const panelRef = useRef<HTMLDivElement>(null);\n const [panelPosition, setPanelPosition] = useState<MenuGeometry | null>(null);\n\n const reopenOnFocusRef = useRef(true);\n\n // In search mode the trigger is a wrapper div; the focusable part is the input.\n const focusTrigger = useCallback(() => {\n const trigger = triggerRef.current;\n const target =\n trigger instanceof HTMLButtonElement\n ? trigger\n : (trigger?.querySelector<HTMLElement>('input') ?? null);\n // A `.focus()` that fires no focus event — an already-focused element, or one that never\n // lands (disabled, hidden, unfocused window) — leaves the latch to eat the next real focus.\n if (!target || target === getDeepActiveElement()) {\n return;\n }\n if (!search) {\n target.focus();\n return;\n }\n reopenOnFocusRef.current = false;\n target.focus();\n if (getDeepActiveElement() !== target) {\n reopenOnFocusRef.current = true;\n }\n }, [search]);\n\n const handleClear = useCallback(\n (event: React.MouseEvent<HTMLButtonElement>) => {\n event.stopPropagation();\n setOwnValue(undefined);\n // The resolver is told the empty this form started the field at; the public\n // callback keeps reporting `undefined` whatever shape that is.\n reportSelectionRef.current?.(reportEmptyRef.current);\n onItemSelected?.(undefined);\n focusTrigger();\n },\n [onItemSelected, focusTrigger],\n );\n\n const updatePanelPosition = useCallback(() => {\n const trigger = triggerRef.current;\n if (!trigger) return;\n\n setPanelPosition(\n measureMenuGeometry(panelRef.current, {\n triggerRect: trigger.getBoundingClientRect(),\n preset: 'standard',\n minWidth,\n align: menuAlign === 'end' ? 'right' : 'left',\n viewportWidth: window.innerWidth,\n viewportHeight: window.innerHeight,\n }),\n );\n }, [minWidth, menuAlign]);\n\n useEffect(() => {\n if (!isOpen) {\n setPanelPosition(null);\n setFocusPanelOnOpen(false);\n return;\n }\n updatePanelPosition();\n const handleClickOutside = (event: MouseEvent) => {\n const path = event.composedPath();\n const trigger = dropdownRef.current;\n const panel = panelRef.current;\n const inTrigger = !!trigger && path.includes(trigger);\n const inPanel = !!panel && path.includes(panel);\n if (!inTrigger && !inPanel) {\n setIsOpen(false);\n if (search) {\n setSearchQuery('');\n }\n if (panelRef.current?.contains(getDeepActiveElement())) {\n focusTrigger();\n }\n // Closing unmounts the option holding focus, so no focusout reaches the wrapper\n // below; when the trigger holds it one does, and reporting here too validates twice.\n if (!dropdownRef.current?.contains(getDeepActiveElement())) {\n reportBlurRef.current?.();\n }\n }\n };\n // ESC via the shared layer stack: closes only the topmost overlay. Focus is\n // restored explicitly — unmounting the option it sits on would drop it to <body>.\n const popEscapeLayer = pushEscapeLayer(() => {\n setIsOpen(false);\n if (search) {\n setSearchQuery('');\n }\n focusTrigger();\n });\n const handleScrollOrResize = () => updatePanelPosition();\n\n // `scroll` is not composed: a window listener never hears a scroller inside a\n // consumer's shadow root, so the trigger's rect is tracked instead.\n let frame = 0;\n let lastRect = '';\n const followTrigger = () => {\n const trigger = triggerRef.current;\n if (trigger) {\n const rect = trigger.getBoundingClientRect();\n\n if (isTriggerOffscreen(rect, window.innerWidth, window.innerHeight)) {\n setIsOpen(false);\n if (search) {\n setSearchQuery('');\n }\n return;\n }\n\n const signature = rectSignature(rect);\n if (signature !== lastRect) {\n lastRect = signature;\n updatePanelPosition();\n }\n }\n frame = requestAnimationFrame(followTrigger);\n };\n frame = requestAnimationFrame(followTrigger);\n\n document.addEventListener('mousedown', handleClickOutside);\n window.addEventListener('scroll', handleScrollOrResize, true);\n window.addEventListener('resize', handleScrollOrResize);\n return () => {\n cancelAnimationFrame(frame);\n document.removeEventListener('mousedown', handleClickOutside);\n popEscapeLayer();\n window.removeEventListener('scroll', handleScrollOrResize, true);\n window.removeEventListener('resize', handleScrollOrResize);\n };\n }, [isOpen, search, updatePanelPosition, focusTrigger]);\n\n useLayoutEffect(() => {\n if (!isOpen) {\n return;\n }\n updatePanelPosition();\n\n const panel = panelRef.current;\n if (!panel || typeof ResizeObserver === 'undefined') {\n return;\n }\n const observer = new ResizeObserver(() => updatePanelPosition());\n observer.observe(panel);\n return () => observer.disconnect();\n }, [isOpen, updatePanelPosition]);\n\n const reportSelectionRef = useRef<((value: unknown) => void) | undefined>(undefined);\n const reportBlurRef = useRef<(() => void) | undefined>(undefined);\n const reportEmptyRef = useRef<unknown>('');\n\n const handleItemSelected = (item?: DropdownItem) => {\n setOwnValue(item?.id);\n reportSelectionRef.current?.(item?.id ?? reportEmptyRef.current);\n setIsOpen(false);\n if (search) {\n setSearchQuery('');\n }\n onItemSelected?.(item?.id);\n focusTrigger();\n };\n\n const dismissPanel = () => {\n setIsOpen(false);\n if (search) {\n setSearchQuery('');\n }\n focusTrigger();\n };\n\n // ArrowDown is the \"take me into the list\" gesture. When it also opens the panel the\n // intent carries over to the mount, so it doesn't cost a second press in search mode.\n const enterPanel = () => {\n setKeyboardNavigation(true);\n const first = panelOptions(panelRef.current)[0];\n if (first) {\n first.focus();\n return;\n }\n setFocusPanelOnOpen(true);\n setIsOpen(true);\n };\n\n const visibleItems =\n search && searchQuery ? items.filter((item) => matchesSearch(item, searchQuery)) : items;\n\n return (\n <BaseFormComponent\n fullWidth={fullWidth}\n label={label}\n hint={hint}\n rightSideContent={rightSideContent}\n tooltip={tooltip}\n name={name}\n required={required}\n requiredIndicator={requiredIndicator}\n loading={loading}\n formControl={formControl}\n description={description}\n controlId={controlId}\n labelId={labelId}\n descriptionId={descriptionId}\n hintId={hintId}\n loadingComponent={\n width === undefined ? (\n <LoadingInput\n heightClass={TRIGGER_SIZE_HEIGHT[size]}\n helperText={!!helperText}\n helperTextMarginTop\n />\n ) : (\n <div style={controlWidthStyle(width)}>\n <LoadingInput\n heightClass={TRIGGER_SIZE_HEIGHT[size]}\n helperText={!!helperText}\n helperTextMarginTop\n />\n </div>\n )\n }\n >\n {({ error: fieldError, message, onFieldChange, onFieldBlur, emptyValue }) => {\n reportSelectionRef.current = onFieldChange;\n reportBlurRef.current = onFieldBlur;\n reportEmptyRef.current = emptyValue;\n const isError = error ?? fieldError;\n // `error={false}` opts out of the resolver entirely, message included: a screen\n // that has dealt with the rejection its own way would otherwise keep reporting it.\n // The message is its own line rather than a replacement for the helper text,\n // matching Input and TextArea: a field that explains what it wants still has to\n // say why what was chosen was rejected.\n const errorMessage = error === false ? undefined : message;\n const errorMessageId = `${helperTextId}-error`;\n const describedBy =\n [\n descriptionId,\n hintId,\n helperText ? helperTextId : undefined,\n errorMessage ? errorMessageId : undefined,\n ]\n .filter(Boolean)\n .join(' ') || undefined;\n\n return (\n <>\n <div\n ref={dropdownRef}\n className={`relative w-full`}\n style={controlWidthStyle(width)}\n // Only leaving the field altogether is a blur `mode: 'onBlur'` should\n // hear. The panel is portaled to the body, so containment has to be\n // asked of it separately — otherwise opening the menu reads as\n // leaving, and the form validates before anything has been chosen.\n onBlur={(event) => {\n const next = event.relatedTarget as Node | null;\n const staysInField =\n event.currentTarget.contains(next) ||\n panelRef.current?.contains(next) === true;\n\n if (!staysInField) {\n reportBlurRef.current?.();\n }\n }}\n >\n {showClear && !search && (\n <button\n type=\"button\"\n onClick={handleClear}\n aria-label={clearLabel}\n className={`absolute ${\n triggerIsStacked\n ? CLEAR_STACKED_TOP_CLASSES[size]\n : 'top-1/2 -translate-y-1/2'\n } z-10 flex items-center\n justify-center rounded-full text-[var(--malachite-text-placeholder)]\n hover:text-[var(--malachite-text-primary)] transition-colors\n focus-visible:[outline:2px_solid_var(--malachite-text-primary)] focus-visible:outline-offset-2 ${CLEAR_OFFSET_CLASSES[size]}`}\n >\n <CloseIcon size={13} />\n </button>\n )}\n <DropdownTrigger\n hasClear={showClear}\n onClear={handleClear}\n clearLabel={clearLabel}\n ref={triggerRef as React.Ref<HTMLElement>}\n isOpen={isOpen}\n onClick={(fromKeyboard) => {\n if (disabled) {\n return;\n }\n setKeyboardNavigation(!!fromKeyboard);\n setIsOpen(!isOpen);\n }}\n selectedItem={selectedItem}\n disabled={disabled}\n error={isError}\n tone={tone}\n placeholder={placeholder}\n search={search}\n showSubtitleInTrigger={showSubtitleInTrigger}\n searchQuery={searchQuery}\n onSearchChange={setSearchQuery}\n onFocusOpen={() => {\n if (!reopenOnFocusRef.current) {\n reopenOnFocusRef.current = true;\n return;\n }\n setIsOpen(true);\n }}\n onArrowDown={() => {\n if (!disabled) {\n enterPanel();\n }\n }}\n onTabAway={() => {\n if (isOpen) {\n dismissPanel();\n }\n }}\n size={size}\n controlId={controlId}\n hasCallerId={!!id}\n labelId={labelId}\n describedBy={describedBy}\n required={required}\n ariaLabel={ariaLabel}\n ariaLabelledBy={ariaLabelledBy}\n />\n {isOpen &&\n createPortal(\n <DropdownPanel\n ref={panelRef}\n style={{\n position: 'fixed',\n top: panelPosition?.top ?? 0,\n left: panelPosition?.left ?? 0,\n width: panelPosition?.width,\n maxHeight: panelPosition?.maxHeight,\n visibility: panelPosition ? 'visible' : 'hidden',\n opacity: panelPosition ? 1 : 0,\n }}\n items={visibleItems}\n onItemSelected={handleItemSelected}\n selectedItem={selectedItem}\n menuLoading={menuLoading}\n emptyMessage={\n items.length === 0\n ? 'No options available'\n : 'No results found'\n }\n subtitleLayout={subtitleLayout}\n size={size}\n autoFocus={!search || focusPanelOnOpen}\n positioned={panelPosition !== null}\n onDismiss={dismissPanel}\n keyboardNavigation={keyboardNavigation}\n onKeyboardNavigation={() => setKeyboardNavigation(true)}\n />,\n document.body,\n )}\n </div>\n {helperText && (\n <div\n id={helperTextId}\n className=\"mt-1 text-[length:var(--malachite-font-size-small,13px)] text-left pl-2 text-[var(--malachite-text-dimmed,rgb(161,161,161))]\"\n >\n {helperText}\n </div>\n )}\n <FieldMessage id={errorMessageId} message={errorMessage} spaced />\n </>\n );\n }}\n </BaseFormComponent>\n );\n};\n\nexport default Dropdown;\n"],"names":["BadgeHost","React","TriggerTag","id","text","disabled","jsx","Tag","INLINE_MARKDOWN_SYNTAX","ItemSubtitle","MarkdownBlock","PANEL_MESSAGE_STYLE","ANNOTATION_FONT_SIZE","OPTION_SELECTOR","panelOptions","panel","subtitleSearchText","subtitle","inlineMarkdownText","matchesSearch","item","query","q","labelMatches","subtitleMatches","rightSideTextMatches","TRIGGER_SIZE_HEIGHT","TRIGGER_SIZE_CLASSES","CONTROL_TEXT_SIZE_CLASS","TRIGGER_SIZE_STACKED_CLASSES","CLEAR_OFFSET_CLASSES","CLEAR_STACKED_TOP_CLASSES","TRIGGER_SIZE_RADIUS","NEVER","ValueRow","wrap","children","Fragment","LabelRow","row","DropdownTrigger","isOpen","onClick","selectedItem","error","tone","placeholder","search","showSubtitleInTrigger","searchQuery","onSearchChange","onFocusOpen","onArrowDown","onTabAway","size","hasClear","onClear","clearLabel","controlId","labelId","describedBy","required","ariaLabel","ariaLabelledBy","hasCallerId","forwardedRef","stacked","sizeClasses","sizeRadius","valueId","subtitleId","tagId","rendersButton","hasTag","showsSearchTag","valueIds","namesItself","labelledBy","tagOutsideName","handleTriggerKeyDown","event","valueTextRef","useRef","subtitleTextRef","triggerVisual","getTriggerVisual","showValueLabel","valueText","triggerSubtitle","isValueTruncated","isCut","cutLines","setCutLines","useState","measureTruncatedLines","value","jsxs","FOCUS_RING_WITHIN_INPUT","DROPDOWN_TRIGGER_ATTR","e","Tooltip","CloseIcon","CaretDownIcon","trigger","FOCUS_RING","tooltipLines","DropdownItemComponent","selected","showTooltipOnFocus","subtitleLayout","onItemSelected","textColor","optionId","useId","optionLabelId","optionSubtitleId","optionBadgeId","labelRef","subtitleRef","rightSideRef","measureOptionLines","label","rightSide","rightSideTextColor","rightSideJustify","option","hasBadge","DropdownPanel","props","ref","items","menuLoading","emptyMessage","autoFocus","positioned","onDismiss","keyboardNavigation","onKeyboardNavigation","style","panelRef","popupIdentity","usePopupLayer","useInsertionEffect","ensureDropdownPanelStyles","useTopLayer","useEffect","options","_a","node","current","target","MENU_SPECS","MENU_MAX_HEIGHT_PX","CONTROL_TEXT_SIZE","Spinner","index","prev","showGroupHeader","Dropdown","defaultValue","hint","rightSideContent","tooltip","name","requiredIndicator","loading","formControl","description","helperText","clearable","fullWidth","width","minWidth","menuAlign","descriptionId","hintId","helperTextId","useFormFieldIds","setIsOpen","ownValue","setOwnValue","selectedId","showClear","triggerIsStacked","lastDefaultValueRef","setSearchQuery","focusPanelOnOpen","setFocusPanelOnOpen","setKeyboardNavigation","dropdownRef","triggerRef","panelPosition","setPanelPosition","reopenOnFocusRef","focusTrigger","useCallback","getDeepActiveElement","handleClear","reportSelectionRef","reportEmptyRef","updatePanelPosition","measureMenuGeometry","handleClickOutside","path","inTrigger","inPanel","_b","_c","reportBlurRef","popEscapeLayer","pushEscapeLayer","handleScrollOrResize","frame","lastRect","followTrigger","rect","isTriggerOffscreen","signature","rectSignature","useLayoutEffect","observer","handleItemSelected","dismissPanel","enterPanel","first","visibleItems","BaseFormComponent","LoadingInput","controlWidthStyle","fieldError","message","onFieldChange","onFieldBlur","emptyValue","isError","errorMessage","errorMessageId","next","fromKeyboard","createPortal","FieldMessage"],"mappings":"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"}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@stackone/malachite",
3
- "version": "2.47.0",
3
+ "version": "2.47.1",
4
4
  "description": "StackOne's themeable React component library — Shadow DOM isolated, scoped Tailwind, theme-token driven.",
5
5
  "license": "MIT",
6
6
  "author": "StackOne",