@duskmoon-dev/components 0.5.3 → 0.5.4

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -865,7 +865,7 @@ DmPagination.displayName = "DmPagination";
865
865
  // src/components/dm-search/DmSearch.tsx
866
866
  import {
867
867
  forwardRef as forwardRef7,
868
- useEffect as useEffect3,
868
+ useEffect as useEffect4,
869
869
  useImperativeHandle as useImperativeHandle3,
870
870
  useMemo as useMemo6,
871
871
  useState as useState8
@@ -1996,7 +1996,15 @@ var Input = Object.assign(InputRoot, {
1996
1996
  Group
1997
1997
  });
1998
1998
  // src/components/select/Select.tsx
1999
- import React7, { forwardRef as forwardRef6, useMemo as useMemo5, useState as useState7 } from "react";
1999
+ import React7, {
2000
+ forwardRef as forwardRef6,
2001
+ useCallback,
2002
+ useEffect as useEffect3,
2003
+ useId as useId2,
2004
+ useMemo as useMemo5,
2005
+ useRef as useRef4,
2006
+ useState as useState7
2007
+ } from "react";
2000
2008
 
2001
2009
  // src/classes/select.ts
2002
2010
  var selectContainerClass = "select-container";
@@ -2150,6 +2158,7 @@ var SelectRoot = forwardRef6(({
2150
2158
  "aria-required": ariaRequired,
2151
2159
  children,
2152
2160
  className,
2161
+ defaultOpen = false,
2153
2162
  defaultValue,
2154
2163
  disabled,
2155
2164
  filterOption,
@@ -2157,6 +2166,9 @@ var SelectRoot = forwardRef6(({
2157
2166
  loading,
2158
2167
  mode,
2159
2168
  onChange,
2169
+ onDropdownVisibleChange,
2170
+ onOpenChange,
2171
+ open: openProp,
2160
2172
  options,
2161
2173
  placeholder,
2162
2174
  showSearch,
@@ -2165,10 +2177,60 @@ var SelectRoot = forwardRef6(({
2165
2177
  value,
2166
2178
  ...props
2167
2179
  }, ref) => {
2180
+ const generatedId = useId2();
2181
+ const cleanId = generatedId.replace(/[^a-zA-Z0-9_-]/g, "");
2182
+ const triggerId = id || `select-${cleanId}`;
2183
+ const dropdownId = `select-dropdown-${cleanId}`;
2184
+ const anchorName = `--dm-select-${cleanId}`;
2185
+ const [internalOpen, setInternalOpen] = useState7(Boolean(defaultOpen));
2186
+ const isControlled = openProp !== undefined;
2187
+ const isOpen = isControlled ? Boolean(openProp) : internalOpen;
2188
+ const containerRef = useRef4(null);
2189
+ const dropdownRef = useRef4(null);
2190
+ const setOpenState = useCallback((nextOpen) => {
2191
+ if (!isControlled) {
2192
+ setInternalOpen(nextOpen);
2193
+ }
2194
+ onDropdownVisibleChange?.(nextOpen);
2195
+ onOpenChange?.(nextOpen);
2196
+ }, [isControlled, onDropdownVisibleChange, onOpenChange]);
2197
+ useEffect3(() => {
2198
+ const dropdown = dropdownRef.current;
2199
+ if (!dropdown || typeof dropdown.showPopover !== "function")
2200
+ return;
2201
+ if (isOpen && !dropdown.matches(":popover-open")) {
2202
+ try {
2203
+ dropdown.showPopover();
2204
+ } catch {}
2205
+ } else if (!isOpen && dropdown.matches(":popover-open")) {
2206
+ try {
2207
+ dropdown.hidePopover();
2208
+ } catch {}
2209
+ }
2210
+ }, [isOpen]);
2211
+ useEffect3(() => {
2212
+ if (!isOpen)
2213
+ return;
2214
+ const handlePointerDown = (event) => {
2215
+ const target = event.target;
2216
+ if (!target)
2217
+ return;
2218
+ if (containerRef.current?.contains(target))
2219
+ return;
2220
+ if (dropdownRef.current?.contains(target))
2221
+ return;
2222
+ setOpenState(false);
2223
+ };
2224
+ document.addEventListener("mousedown", handlePointerDown);
2225
+ document.addEventListener("touchstart", handlePointerDown);
2226
+ return () => {
2227
+ document.removeEventListener("mousedown", handlePointerDown);
2228
+ document.removeEventListener("touchstart", handlePointerDown);
2229
+ };
2230
+ }, [isOpen, setOpenState]);
2168
2231
  const multiple = mode === "multiple" || mode === "tags";
2169
2232
  const sourceOptions = useMemo5(() => options ?? optionsFromChildren(children), [children, options]);
2170
2233
  const flatOptions = useMemo5(() => flattenOptions(sourceOptions), [sourceOptions]);
2171
- const [open, setOpen] = useState7(false);
2172
2234
  const [searchValue, setSearchValue] = useState7("");
2173
2235
  const [internalValue, setInternalValue] = useState7(multiple ? normalizeMultiValue(defaultValue) : normalizeSingleValue(defaultValue));
2174
2236
  const controlled = value !== undefined;
@@ -2203,7 +2265,7 @@ var SelectRoot = forwardRef6(({
2203
2265
  emitChange(nextValues);
2204
2266
  } else {
2205
2267
  emitChange(option.value);
2206
- setOpen(false);
2268
+ setOpenState(false);
2207
2269
  }
2208
2270
  setSearchValue("");
2209
2271
  }
@@ -2259,15 +2321,23 @@ var SelectRoot = forwardRef6(({
2259
2321
  }, `group-${index}`);
2260
2322
  });
2261
2323
  }
2324
+ const setRefs = (node) => {
2325
+ containerRef.current = node;
2326
+ if (typeof ref === "function") {
2327
+ ref(node);
2328
+ } else if (ref) {
2329
+ ref.current = node;
2330
+ }
2331
+ };
2262
2332
  const selection = multiple ? selectedOptions.map((option) => /* @__PURE__ */ jsx8("span", {
2263
2333
  className: selectTagClass,
2264
2334
  children: renderValue(option)
2265
2335
  }, valueKey(option.value))) : renderValue(selectedOptions[0]);
2266
2336
  return /* @__PURE__ */ jsxs7("div", {
2267
2337
  ...props,
2268
- ref,
2338
+ ref: setRefs,
2269
2339
  className: getSelectContainerClasses({
2270
- open,
2340
+ open: isOpen,
2271
2341
  loading,
2272
2342
  disabled,
2273
2343
  full: true,
@@ -2276,7 +2346,7 @@ var SelectRoot = forwardRef6(({
2276
2346
  children: [
2277
2347
  /* @__PURE__ */ jsxs7("button", {
2278
2348
  type: "button",
2279
- id,
2349
+ id: triggerId,
2280
2350
  className: getSelectClasses({ size, status, disabled }),
2281
2351
  disabled: disabled || loading,
2282
2352
  "aria-describedby": ariaDescribedBy,
@@ -2286,8 +2356,14 @@ var SelectRoot = forwardRef6(({
2286
2356
  "aria-labelledby": ariaLabelledBy,
2287
2357
  "aria-required": ariaRequired,
2288
2358
  "aria-haspopup": "listbox",
2289
- "aria-expanded": open,
2290
- onClick: () => setOpen((current) => !current),
2359
+ "aria-expanded": isOpen,
2360
+ "aria-controls": dropdownId,
2361
+ style: { anchorName },
2362
+ onClick: () => {
2363
+ if (disabled || loading)
2364
+ return;
2365
+ setOpenState(!isOpen);
2366
+ },
2291
2367
  children: [
2292
2368
  /* @__PURE__ */ jsx8("span", {
2293
2369
  className: selectSelectionClass,
@@ -2335,10 +2411,22 @@ var SelectRoot = forwardRef6(({
2335
2411
  })
2336
2412
  })
2337
2413
  }) : null,
2338
- open ? /* @__PURE__ */ jsxs7("div", {
2339
- className: selectDropdownClass,
2414
+ isOpen ? /* @__PURE__ */ jsxs7("div", {
2415
+ id: dropdownId,
2416
+ ref: dropdownRef,
2417
+ popover: "auto",
2340
2418
  role: "listbox",
2341
2419
  "aria-multiselectable": multiple || undefined,
2420
+ className: selectDropdownClass,
2421
+ style: { positionAnchor: anchorName },
2422
+ onToggle: (event) => {
2423
+ if (event.target !== event.currentTarget)
2424
+ return;
2425
+ const nextOpen = event.nativeEvent?.newState === "open";
2426
+ if (nextOpen !== isOpen) {
2427
+ setOpenState(nextOpen);
2428
+ }
2429
+ },
2342
2430
  children: [
2343
2431
  searchable ? /* @__PURE__ */ jsx8("input", {
2344
2432
  className: selectSearchClass,
@@ -2472,7 +2560,7 @@ var DmSearch = forwardRef7(({
2472
2560
  const controlled = controlledValues !== undefined;
2473
2561
  const values = controlled ? controlledValues : internalValues;
2474
2562
  const visibleItems = collapsed ? allItems.slice(0, 1) : allItems;
2475
- useEffect3(() => {
2563
+ useEffect4(() => {
2476
2564
  if (!controlled)
2477
2565
  setValues(initialValues(allItems, searchParams));
2478
2566
  }, [allItems, searchParams, controlled]);
@@ -3433,9 +3521,9 @@ import {
3433
3521
  cloneElement,
3434
3522
  forwardRef as forwardRef9,
3435
3523
  isValidElement,
3436
- useEffect as useEffect4,
3437
- useId as useId2,
3438
- useRef as useRef4,
3524
+ useEffect as useEffect5,
3525
+ useId as useId3,
3526
+ useRef as useRef5,
3439
3527
  useState as useState11
3440
3528
  } from "react";
3441
3529
 
@@ -3564,11 +3652,11 @@ var DropdownRoot = forwardRef9(({
3564
3652
  const [internalOpen, setInternalOpen] = useState11(Boolean(defaultOpen));
3565
3653
  const [nativeOpen, setNativeOpen] = useState11(Boolean(open ?? defaultOpen));
3566
3654
  const visible = open ?? internalOpen;
3567
- const popupRef = useRef4(null);
3568
- const popupId = useId2();
3655
+ const popupRef = useRef5(null);
3656
+ const popupId = useId3();
3569
3657
  const anchorName = `--dm-dropdown-${popupId.replace(/[^a-zA-Z0-9_-]/g, "")}`;
3570
3658
  const clickTrigger = trigger.includes("click") || trigger.includes("hover");
3571
- useEffect4(() => {
3659
+ useEffect5(() => {
3572
3660
  const popup = popupRef.current;
3573
3661
  if (!popup?.showPopover || !popup?.hidePopover)
3574
3662
  return;
@@ -4,14 +4,14 @@
4
4
  import {
5
5
  forwardRef as forwardRef6,
6
6
  useImperativeHandle as useImperativeHandle4,
7
- useRef as useRef3,
7
+ useRef as useRef4,
8
8
  useState as useState7
9
9
  } from "react";
10
10
 
11
11
  // src/components/dm-search/DmSearch.tsx
12
12
  import {
13
13
  forwardRef as forwardRef5,
14
- useEffect as useEffect2,
14
+ useEffect as useEffect3,
15
15
  useImperativeHandle as useImperativeHandle3,
16
16
  useMemo as useMemo4,
17
17
  useState as useState6
@@ -1494,7 +1494,15 @@ var Input = Object.assign(InputRoot, {
1494
1494
  Group
1495
1495
  });
1496
1496
  // src/components/select/Select.tsx
1497
- import React5, { forwardRef as forwardRef4, useMemo as useMemo3, useState as useState5 } from "react";
1497
+ import React5, {
1498
+ forwardRef as forwardRef4,
1499
+ useCallback,
1500
+ useEffect as useEffect2,
1501
+ useId as useId2,
1502
+ useMemo as useMemo3,
1503
+ useRef as useRef3,
1504
+ useState as useState5
1505
+ } from "react";
1498
1506
 
1499
1507
  // src/classes/select.ts
1500
1508
  var selectContainerClass = "select-container";
@@ -1648,6 +1656,7 @@ var SelectRoot = forwardRef4(({
1648
1656
  "aria-required": ariaRequired,
1649
1657
  children,
1650
1658
  className,
1659
+ defaultOpen = false,
1651
1660
  defaultValue,
1652
1661
  disabled,
1653
1662
  filterOption,
@@ -1655,6 +1664,9 @@ var SelectRoot = forwardRef4(({
1655
1664
  loading,
1656
1665
  mode,
1657
1666
  onChange,
1667
+ onDropdownVisibleChange,
1668
+ onOpenChange,
1669
+ open: openProp,
1658
1670
  options,
1659
1671
  placeholder,
1660
1672
  showSearch,
@@ -1663,10 +1675,60 @@ var SelectRoot = forwardRef4(({
1663
1675
  value,
1664
1676
  ...props
1665
1677
  }, ref) => {
1678
+ const generatedId = useId2();
1679
+ const cleanId = generatedId.replace(/[^a-zA-Z0-9_-]/g, "");
1680
+ const triggerId = id || `select-${cleanId}`;
1681
+ const dropdownId = `select-dropdown-${cleanId}`;
1682
+ const anchorName = `--dm-select-${cleanId}`;
1683
+ const [internalOpen, setInternalOpen] = useState5(Boolean(defaultOpen));
1684
+ const isControlled = openProp !== undefined;
1685
+ const isOpen = isControlled ? Boolean(openProp) : internalOpen;
1686
+ const containerRef = useRef3(null);
1687
+ const dropdownRef = useRef3(null);
1688
+ const setOpenState = useCallback((nextOpen) => {
1689
+ if (!isControlled) {
1690
+ setInternalOpen(nextOpen);
1691
+ }
1692
+ onDropdownVisibleChange?.(nextOpen);
1693
+ onOpenChange?.(nextOpen);
1694
+ }, [isControlled, onDropdownVisibleChange, onOpenChange]);
1695
+ useEffect2(() => {
1696
+ const dropdown = dropdownRef.current;
1697
+ if (!dropdown || typeof dropdown.showPopover !== "function")
1698
+ return;
1699
+ if (isOpen && !dropdown.matches(":popover-open")) {
1700
+ try {
1701
+ dropdown.showPopover();
1702
+ } catch {}
1703
+ } else if (!isOpen && dropdown.matches(":popover-open")) {
1704
+ try {
1705
+ dropdown.hidePopover();
1706
+ } catch {}
1707
+ }
1708
+ }, [isOpen]);
1709
+ useEffect2(() => {
1710
+ if (!isOpen)
1711
+ return;
1712
+ const handlePointerDown = (event) => {
1713
+ const target = event.target;
1714
+ if (!target)
1715
+ return;
1716
+ if (containerRef.current?.contains(target))
1717
+ return;
1718
+ if (dropdownRef.current?.contains(target))
1719
+ return;
1720
+ setOpenState(false);
1721
+ };
1722
+ document.addEventListener("mousedown", handlePointerDown);
1723
+ document.addEventListener("touchstart", handlePointerDown);
1724
+ return () => {
1725
+ document.removeEventListener("mousedown", handlePointerDown);
1726
+ document.removeEventListener("touchstart", handlePointerDown);
1727
+ };
1728
+ }, [isOpen, setOpenState]);
1666
1729
  const multiple = mode === "multiple" || mode === "tags";
1667
1730
  const sourceOptions = useMemo3(() => options ?? optionsFromChildren(children), [children, options]);
1668
1731
  const flatOptions = useMemo3(() => flattenOptions(sourceOptions), [sourceOptions]);
1669
- const [open, setOpen] = useState5(false);
1670
1732
  const [searchValue, setSearchValue] = useState5("");
1671
1733
  const [internalValue, setInternalValue] = useState5(multiple ? normalizeMultiValue(defaultValue) : normalizeSingleValue(defaultValue));
1672
1734
  const controlled = value !== undefined;
@@ -1701,7 +1763,7 @@ var SelectRoot = forwardRef4(({
1701
1763
  emitChange(nextValues);
1702
1764
  } else {
1703
1765
  emitChange(option.value);
1704
- setOpen(false);
1766
+ setOpenState(false);
1705
1767
  }
1706
1768
  setSearchValue("");
1707
1769
  }
@@ -1757,15 +1819,23 @@ var SelectRoot = forwardRef4(({
1757
1819
  }, `group-${index}`);
1758
1820
  });
1759
1821
  }
1822
+ const setRefs = (node) => {
1823
+ containerRef.current = node;
1824
+ if (typeof ref === "function") {
1825
+ ref(node);
1826
+ } else if (ref) {
1827
+ ref.current = node;
1828
+ }
1829
+ };
1760
1830
  const selection = multiple ? selectedOptions.map((option) => /* @__PURE__ */ jsx5("span", {
1761
1831
  className: selectTagClass,
1762
1832
  children: renderValue(option)
1763
1833
  }, valueKey(option.value))) : renderValue(selectedOptions[0]);
1764
1834
  return /* @__PURE__ */ jsxs5("div", {
1765
1835
  ...props,
1766
- ref,
1836
+ ref: setRefs,
1767
1837
  className: getSelectContainerClasses({
1768
- open,
1838
+ open: isOpen,
1769
1839
  loading,
1770
1840
  disabled,
1771
1841
  full: true,
@@ -1774,7 +1844,7 @@ var SelectRoot = forwardRef4(({
1774
1844
  children: [
1775
1845
  /* @__PURE__ */ jsxs5("button", {
1776
1846
  type: "button",
1777
- id,
1847
+ id: triggerId,
1778
1848
  className: getSelectClasses({ size, status, disabled }),
1779
1849
  disabled: disabled || loading,
1780
1850
  "aria-describedby": ariaDescribedBy,
@@ -1784,8 +1854,14 @@ var SelectRoot = forwardRef4(({
1784
1854
  "aria-labelledby": ariaLabelledBy,
1785
1855
  "aria-required": ariaRequired,
1786
1856
  "aria-haspopup": "listbox",
1787
- "aria-expanded": open,
1788
- onClick: () => setOpen((current) => !current),
1857
+ "aria-expanded": isOpen,
1858
+ "aria-controls": dropdownId,
1859
+ style: { anchorName },
1860
+ onClick: () => {
1861
+ if (disabled || loading)
1862
+ return;
1863
+ setOpenState(!isOpen);
1864
+ },
1789
1865
  children: [
1790
1866
  /* @__PURE__ */ jsx5("span", {
1791
1867
  className: selectSelectionClass,
@@ -1833,10 +1909,22 @@ var SelectRoot = forwardRef4(({
1833
1909
  })
1834
1910
  })
1835
1911
  }) : null,
1836
- open ? /* @__PURE__ */ jsxs5("div", {
1837
- className: selectDropdownClass,
1912
+ isOpen ? /* @__PURE__ */ jsxs5("div", {
1913
+ id: dropdownId,
1914
+ ref: dropdownRef,
1915
+ popover: "auto",
1838
1916
  role: "listbox",
1839
1917
  "aria-multiselectable": multiple || undefined,
1918
+ className: selectDropdownClass,
1919
+ style: { positionAnchor: anchorName },
1920
+ onToggle: (event) => {
1921
+ if (event.target !== event.currentTarget)
1922
+ return;
1923
+ const nextOpen = event.nativeEvent?.newState === "open";
1924
+ if (nextOpen !== isOpen) {
1925
+ setOpenState(nextOpen);
1926
+ }
1927
+ },
1840
1928
  children: [
1841
1929
  searchable ? /* @__PURE__ */ jsx5("input", {
1842
1930
  className: selectSearchClass,
@@ -1970,7 +2058,7 @@ var DmSearch = forwardRef5(({
1970
2058
  const controlled = controlledValues !== undefined;
1971
2059
  const values = controlled ? controlledValues : internalValues;
1972
2060
  const visibleItems = collapsed ? allItems.slice(0, 1) : allItems;
1973
- useEffect2(() => {
2061
+ useEffect3(() => {
1974
2062
  if (!controlled)
1975
2063
  setValues(initialValues(allItems, searchParams));
1976
2064
  }, [allItems, searchParams, controlled]);
@@ -2088,7 +2176,7 @@ var DmQuery = forwardRef6(({
2088
2176
  onSearch,
2089
2177
  ...props
2090
2178
  }, ref) => {
2091
- const searchRef = useRef3(null);
2179
+ const searchRef = useRef4(null);
2092
2180
  const [selectedItem, setSelectedItem] = useState7(queryItem[0]);
2093
2181
  const items = selectedItem ? [toSearchItem(selectedItem)] : queryItem.map(toSearchItem);
2094
2182
  useImperativeHandle4(ref, () => ({
@@ -3,7 +3,7 @@
3
3
  // src/components/dm-search/DmSearch.tsx
4
4
  import {
5
5
  forwardRef as forwardRef5,
6
- useEffect as useEffect2,
6
+ useEffect as useEffect3,
7
7
  useImperativeHandle as useImperativeHandle3,
8
8
  useMemo as useMemo4,
9
9
  useState as useState6
@@ -1486,7 +1486,15 @@ var Input = Object.assign(InputRoot, {
1486
1486
  Group
1487
1487
  });
1488
1488
  // src/components/select/Select.tsx
1489
- import React5, { forwardRef as forwardRef4, useMemo as useMemo3, useState as useState5 } from "react";
1489
+ import React5, {
1490
+ forwardRef as forwardRef4,
1491
+ useCallback,
1492
+ useEffect as useEffect2,
1493
+ useId as useId2,
1494
+ useMemo as useMemo3,
1495
+ useRef as useRef3,
1496
+ useState as useState5
1497
+ } from "react";
1490
1498
 
1491
1499
  // src/classes/select.ts
1492
1500
  var selectContainerClass = "select-container";
@@ -1640,6 +1648,7 @@ var SelectRoot = forwardRef4(({
1640
1648
  "aria-required": ariaRequired,
1641
1649
  children,
1642
1650
  className,
1651
+ defaultOpen = false,
1643
1652
  defaultValue,
1644
1653
  disabled,
1645
1654
  filterOption,
@@ -1647,6 +1656,9 @@ var SelectRoot = forwardRef4(({
1647
1656
  loading,
1648
1657
  mode,
1649
1658
  onChange,
1659
+ onDropdownVisibleChange,
1660
+ onOpenChange,
1661
+ open: openProp,
1650
1662
  options,
1651
1663
  placeholder,
1652
1664
  showSearch,
@@ -1655,10 +1667,60 @@ var SelectRoot = forwardRef4(({
1655
1667
  value,
1656
1668
  ...props
1657
1669
  }, ref) => {
1670
+ const generatedId = useId2();
1671
+ const cleanId = generatedId.replace(/[^a-zA-Z0-9_-]/g, "");
1672
+ const triggerId = id || `select-${cleanId}`;
1673
+ const dropdownId = `select-dropdown-${cleanId}`;
1674
+ const anchorName = `--dm-select-${cleanId}`;
1675
+ const [internalOpen, setInternalOpen] = useState5(Boolean(defaultOpen));
1676
+ const isControlled = openProp !== undefined;
1677
+ const isOpen = isControlled ? Boolean(openProp) : internalOpen;
1678
+ const containerRef = useRef3(null);
1679
+ const dropdownRef = useRef3(null);
1680
+ const setOpenState = useCallback((nextOpen) => {
1681
+ if (!isControlled) {
1682
+ setInternalOpen(nextOpen);
1683
+ }
1684
+ onDropdownVisibleChange?.(nextOpen);
1685
+ onOpenChange?.(nextOpen);
1686
+ }, [isControlled, onDropdownVisibleChange, onOpenChange]);
1687
+ useEffect2(() => {
1688
+ const dropdown = dropdownRef.current;
1689
+ if (!dropdown || typeof dropdown.showPopover !== "function")
1690
+ return;
1691
+ if (isOpen && !dropdown.matches(":popover-open")) {
1692
+ try {
1693
+ dropdown.showPopover();
1694
+ } catch {}
1695
+ } else if (!isOpen && dropdown.matches(":popover-open")) {
1696
+ try {
1697
+ dropdown.hidePopover();
1698
+ } catch {}
1699
+ }
1700
+ }, [isOpen]);
1701
+ useEffect2(() => {
1702
+ if (!isOpen)
1703
+ return;
1704
+ const handlePointerDown = (event) => {
1705
+ const target = event.target;
1706
+ if (!target)
1707
+ return;
1708
+ if (containerRef.current?.contains(target))
1709
+ return;
1710
+ if (dropdownRef.current?.contains(target))
1711
+ return;
1712
+ setOpenState(false);
1713
+ };
1714
+ document.addEventListener("mousedown", handlePointerDown);
1715
+ document.addEventListener("touchstart", handlePointerDown);
1716
+ return () => {
1717
+ document.removeEventListener("mousedown", handlePointerDown);
1718
+ document.removeEventListener("touchstart", handlePointerDown);
1719
+ };
1720
+ }, [isOpen, setOpenState]);
1658
1721
  const multiple = mode === "multiple" || mode === "tags";
1659
1722
  const sourceOptions = useMemo3(() => options ?? optionsFromChildren(children), [children, options]);
1660
1723
  const flatOptions = useMemo3(() => flattenOptions(sourceOptions), [sourceOptions]);
1661
- const [open, setOpen] = useState5(false);
1662
1724
  const [searchValue, setSearchValue] = useState5("");
1663
1725
  const [internalValue, setInternalValue] = useState5(multiple ? normalizeMultiValue(defaultValue) : normalizeSingleValue(defaultValue));
1664
1726
  const controlled = value !== undefined;
@@ -1693,7 +1755,7 @@ var SelectRoot = forwardRef4(({
1693
1755
  emitChange(nextValues);
1694
1756
  } else {
1695
1757
  emitChange(option.value);
1696
- setOpen(false);
1758
+ setOpenState(false);
1697
1759
  }
1698
1760
  setSearchValue("");
1699
1761
  }
@@ -1749,15 +1811,23 @@ var SelectRoot = forwardRef4(({
1749
1811
  }, `group-${index}`);
1750
1812
  });
1751
1813
  }
1814
+ const setRefs = (node) => {
1815
+ containerRef.current = node;
1816
+ if (typeof ref === "function") {
1817
+ ref(node);
1818
+ } else if (ref) {
1819
+ ref.current = node;
1820
+ }
1821
+ };
1752
1822
  const selection = multiple ? selectedOptions.map((option) => /* @__PURE__ */ jsx5("span", {
1753
1823
  className: selectTagClass,
1754
1824
  children: renderValue(option)
1755
1825
  }, valueKey(option.value))) : renderValue(selectedOptions[0]);
1756
1826
  return /* @__PURE__ */ jsxs5("div", {
1757
1827
  ...props,
1758
- ref,
1828
+ ref: setRefs,
1759
1829
  className: getSelectContainerClasses({
1760
- open,
1830
+ open: isOpen,
1761
1831
  loading,
1762
1832
  disabled,
1763
1833
  full: true,
@@ -1766,7 +1836,7 @@ var SelectRoot = forwardRef4(({
1766
1836
  children: [
1767
1837
  /* @__PURE__ */ jsxs5("button", {
1768
1838
  type: "button",
1769
- id,
1839
+ id: triggerId,
1770
1840
  className: getSelectClasses({ size, status, disabled }),
1771
1841
  disabled: disabled || loading,
1772
1842
  "aria-describedby": ariaDescribedBy,
@@ -1776,8 +1846,14 @@ var SelectRoot = forwardRef4(({
1776
1846
  "aria-labelledby": ariaLabelledBy,
1777
1847
  "aria-required": ariaRequired,
1778
1848
  "aria-haspopup": "listbox",
1779
- "aria-expanded": open,
1780
- onClick: () => setOpen((current) => !current),
1849
+ "aria-expanded": isOpen,
1850
+ "aria-controls": dropdownId,
1851
+ style: { anchorName },
1852
+ onClick: () => {
1853
+ if (disabled || loading)
1854
+ return;
1855
+ setOpenState(!isOpen);
1856
+ },
1781
1857
  children: [
1782
1858
  /* @__PURE__ */ jsx5("span", {
1783
1859
  className: selectSelectionClass,
@@ -1825,10 +1901,22 @@ var SelectRoot = forwardRef4(({
1825
1901
  })
1826
1902
  })
1827
1903
  }) : null,
1828
- open ? /* @__PURE__ */ jsxs5("div", {
1829
- className: selectDropdownClass,
1904
+ isOpen ? /* @__PURE__ */ jsxs5("div", {
1905
+ id: dropdownId,
1906
+ ref: dropdownRef,
1907
+ popover: "auto",
1830
1908
  role: "listbox",
1831
1909
  "aria-multiselectable": multiple || undefined,
1910
+ className: selectDropdownClass,
1911
+ style: { positionAnchor: anchorName },
1912
+ onToggle: (event) => {
1913
+ if (event.target !== event.currentTarget)
1914
+ return;
1915
+ const nextOpen = event.nativeEvent?.newState === "open";
1916
+ if (nextOpen !== isOpen) {
1917
+ setOpenState(nextOpen);
1918
+ }
1919
+ },
1832
1920
  children: [
1833
1921
  searchable ? /* @__PURE__ */ jsx5("input", {
1834
1922
  className: selectSearchClass,
@@ -1962,7 +2050,7 @@ var DmSearch = forwardRef5(({
1962
2050
  const controlled = controlledValues !== undefined;
1963
2051
  const values = controlled ? controlledValues : internalValues;
1964
2052
  const visibleItems = collapsed ? allItems.slice(0, 1) : allItems;
1965
- useEffect2(() => {
2053
+ useEffect3(() => {
1966
2054
  if (!controlled)
1967
2055
  setValues(initialValues(allItems, searchParams));
1968
2056
  }, [allItems, searchParams, controlled]);