@spark-ui/components 10.0.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (296) hide show
  1. package/CHANGELOG.md +15 -0
  2. package/LICENSE.md +21 -0
  3. package/README.md +19 -0
  4. package/dist/DialogTrigger-5SI4dvpK.d.mts +142 -0
  5. package/dist/DialogTrigger-5SI4dvpK.d.ts +142 -0
  6. package/dist/Input-g0LpWuv0.d.mts +17 -0
  7. package/dist/Input-g0LpWuv0.d.ts +17 -0
  8. package/dist/InputGroup-aoaZxCLk.d.mts +28 -0
  9. package/dist/InputGroup-aoaZxCLk.d.ts +28 -0
  10. package/dist/InputTrailingIcon-BBp7sE6D.d.mts +20 -0
  11. package/dist/InputTrailingIcon-ZZx8PoJy.d.ts +20 -0
  12. package/dist/LabelRequiredIndicator-DRnCzHMU.d.mts +19 -0
  13. package/dist/LabelRequiredIndicator-DRnCzHMU.d.ts +19 -0
  14. package/dist/accordion/index.d.mts +85 -0
  15. package/dist/accordion/index.d.ts +85 -0
  16. package/dist/accordion/index.js +461 -0
  17. package/dist/accordion/index.js.map +1 -0
  18. package/dist/accordion/index.mjs +249 -0
  19. package/dist/accordion/index.mjs.map +1 -0
  20. package/dist/alert-dialog/index.d.mts +119 -0
  21. package/dist/alert-dialog/index.d.ts +119 -0
  22. package/dist/alert-dialog/index.js +1451 -0
  23. package/dist/alert-dialog/index.js.map +1 -0
  24. package/dist/alert-dialog/index.mjs +177 -0
  25. package/dist/alert-dialog/index.mjs.map +1 -0
  26. package/dist/badge/index.d.mts +47 -0
  27. package/dist/badge/index.d.ts +47 -0
  28. package/dist/badge/index.js +122 -0
  29. package/dist/badge/index.js.map +1 -0
  30. package/dist/badge/index.mjs +95 -0
  31. package/dist/badge/index.mjs.map +1 -0
  32. package/dist/breadcrumb/index.d.mts +64 -0
  33. package/dist/breadcrumb/index.d.ts +64 -0
  34. package/dist/breadcrumb/index.js +326 -0
  35. package/dist/breadcrumb/index.js.map +1 -0
  36. package/dist/breadcrumb/index.mjs +149 -0
  37. package/dist/breadcrumb/index.mjs.map +1 -0
  38. package/dist/button/index.d.mts +40 -0
  39. package/dist/button/index.d.ts +40 -0
  40. package/dist/button/index.js +877 -0
  41. package/dist/button/index.js.map +1 -0
  42. package/dist/button/index.mjs +10 -0
  43. package/dist/button/index.mjs.map +1 -0
  44. package/dist/carousel/index.d.mts +253 -0
  45. package/dist/carousel/index.d.ts +253 -0
  46. package/dist/carousel/index.js +1678 -0
  47. package/dist/carousel/index.js.map +1 -0
  48. package/dist/carousel/index.mjs +716 -0
  49. package/dist/carousel/index.mjs.map +1 -0
  50. package/dist/checkbox/index.d.mts +120 -0
  51. package/dist/checkbox/index.d.ts +120 -0
  52. package/dist/checkbox/index.js +873 -0
  53. package/dist/checkbox/index.js.map +1 -0
  54. package/dist/checkbox/index.mjs +349 -0
  55. package/dist/checkbox/index.mjs.map +1 -0
  56. package/dist/chip/index.d.mts +97 -0
  57. package/dist/chip/index.d.ts +97 -0
  58. package/dist/chip/index.js +905 -0
  59. package/dist/chip/index.js.map +1 -0
  60. package/dist/chip/index.mjs +793 -0
  61. package/dist/chip/index.mjs.map +1 -0
  62. package/dist/chunk-2KPFQEAA.mjs +52 -0
  63. package/dist/chunk-2KPFQEAA.mjs.map +1 -0
  64. package/dist/chunk-4F5DOL57.mjs +26 -0
  65. package/dist/chunk-4F5DOL57.mjs.map +1 -0
  66. package/dist/chunk-6JOA37TZ.mjs +742 -0
  67. package/dist/chunk-6JOA37TZ.mjs.map +1 -0
  68. package/dist/chunk-7PMPYEHJ.mjs +379 -0
  69. package/dist/chunk-7PMPYEHJ.mjs.map +1 -0
  70. package/dist/chunk-AESXFMCC.mjs +68 -0
  71. package/dist/chunk-AESXFMCC.mjs.map +1 -0
  72. package/dist/chunk-B42LOFIZ.mjs +308 -0
  73. package/dist/chunk-B42LOFIZ.mjs.map +1 -0
  74. package/dist/chunk-FGOZHKBT.mjs +97 -0
  75. package/dist/chunk-FGOZHKBT.mjs.map +1 -0
  76. package/dist/chunk-HLXYG643.mjs +52 -0
  77. package/dist/chunk-HLXYG643.mjs.map +1 -0
  78. package/dist/chunk-JKNBJHD5.mjs +601 -0
  79. package/dist/chunk-JKNBJHD5.mjs.map +1 -0
  80. package/dist/chunk-K7VP7DH3.mjs +66 -0
  81. package/dist/chunk-K7VP7DH3.mjs.map +1 -0
  82. package/dist/chunk-MUNDKRAE.mjs +80 -0
  83. package/dist/chunk-MUNDKRAE.mjs.map +1 -0
  84. package/dist/chunk-NBZKMCHF.mjs +36 -0
  85. package/dist/chunk-NBZKMCHF.mjs.map +1 -0
  86. package/dist/chunk-PZWESKAR.mjs +314 -0
  87. package/dist/chunk-PZWESKAR.mjs.map +1 -0
  88. package/dist/collapsible/index.d.mts +60 -0
  89. package/dist/collapsible/index.d.ts +60 -0
  90. package/dist/collapsible/index.js +140 -0
  91. package/dist/collapsible/index.js.map +1 -0
  92. package/dist/collapsible/index.mjs +8 -0
  93. package/dist/collapsible/index.mjs.map +1 -0
  94. package/dist/combobox/index.d.mts +285 -0
  95. package/dist/combobox/index.d.ts +285 -0
  96. package/dist/combobox/index.js +2920 -0
  97. package/dist/combobox/index.js.map +1 -0
  98. package/dist/combobox/index.mjs +1267 -0
  99. package/dist/combobox/index.mjs.map +1 -0
  100. package/dist/dialog/index.d.mts +33 -0
  101. package/dist/dialog/index.d.ts +33 -0
  102. package/dist/dialog/index.js +1286 -0
  103. package/dist/dialog/index.js.map +1 -0
  104. package/dist/dialog/index.mjs +13 -0
  105. package/dist/dialog/index.mjs.map +1 -0
  106. package/dist/divider/index.d.mts +61 -0
  107. package/dist/divider/index.d.ts +61 -0
  108. package/dist/divider/index.js +223 -0
  109. package/dist/divider/index.js.map +1 -0
  110. package/dist/divider/index.mjs +196 -0
  111. package/dist/divider/index.mjs.map +1 -0
  112. package/dist/drawer/index.d.mts +148 -0
  113. package/dist/drawer/index.d.ts +148 -0
  114. package/dist/drawer/index.js +1266 -0
  115. package/dist/drawer/index.js.map +1 -0
  116. package/dist/drawer/index.mjs +299 -0
  117. package/dist/drawer/index.mjs.map +1 -0
  118. package/dist/dropdown/index.d.mts +233 -0
  119. package/dist/dropdown/index.d.ts +233 -0
  120. package/dist/dropdown/index.js +2402 -0
  121. package/dist/dropdown/index.js.map +1 -0
  122. package/dist/dropdown/index.mjs +741 -0
  123. package/dist/dropdown/index.mjs.map +1 -0
  124. package/dist/form-field/index.d.mts +176 -0
  125. package/dist/form-field/index.d.ts +176 -0
  126. package/dist/form-field/index.js +540 -0
  127. package/dist/form-field/index.js.map +1 -0
  128. package/dist/form-field/index.mjs +13 -0
  129. package/dist/form-field/index.mjs.map +1 -0
  130. package/dist/icon/index.d.mts +28 -0
  131. package/dist/icon/index.d.ts +28 -0
  132. package/dist/icon/index.js +127 -0
  133. package/dist/icon/index.js.map +1 -0
  134. package/dist/icon/index.mjs +9 -0
  135. package/dist/icon/index.mjs.map +1 -0
  136. package/dist/icon-button/index.d.mts +16 -0
  137. package/dist/icon-button/index.d.ts +16 -0
  138. package/dist/icon-button/index.js +921 -0
  139. package/dist/icon-button/index.js.map +1 -0
  140. package/dist/icon-button/index.mjs +11 -0
  141. package/dist/icon-button/index.mjs.map +1 -0
  142. package/dist/input/index.d.mts +78 -0
  143. package/dist/input/index.d.ts +78 -0
  144. package/dist/input/index.js +1119 -0
  145. package/dist/input/index.js.map +1 -0
  146. package/dist/input/index.mjs +16 -0
  147. package/dist/input/index.mjs.map +1 -0
  148. package/dist/kbd/index.d.mts +9 -0
  149. package/dist/kbd/index.d.ts +9 -0
  150. package/dist/kbd/index.js +46 -0
  151. package/dist/kbd/index.js.map +1 -0
  152. package/dist/kbd/index.mjs +19 -0
  153. package/dist/kbd/index.mjs.map +1 -0
  154. package/dist/label/index.d.mts +11 -0
  155. package/dist/label/index.d.ts +11 -0
  156. package/dist/label/index.js +78 -0
  157. package/dist/label/index.js.map +1 -0
  158. package/dist/label/index.mjs +7 -0
  159. package/dist/label/index.mjs.map +1 -0
  160. package/dist/link-box/index.d.mts +34 -0
  161. package/dist/link-box/index.d.ts +34 -0
  162. package/dist/link-box/index.js +92 -0
  163. package/dist/link-box/index.js.map +1 -0
  164. package/dist/link-box/index.mjs +58 -0
  165. package/dist/link-box/index.mjs.map +1 -0
  166. package/dist/pagination/index.d.mts +143 -0
  167. package/dist/pagination/index.d.ts +143 -0
  168. package/dist/pagination/index.js +1303 -0
  169. package/dist/pagination/index.js.map +1 -0
  170. package/dist/pagination/index.mjs +326 -0
  171. package/dist/pagination/index.mjs.map +1 -0
  172. package/dist/popover/index.d.mts +93 -0
  173. package/dist/popover/index.d.ts +93 -0
  174. package/dist/popover/index.js +1280 -0
  175. package/dist/popover/index.js.map +1 -0
  176. package/dist/popover/index.mjs +13 -0
  177. package/dist/popover/index.mjs.map +1 -0
  178. package/dist/portal/index.d.mts +13 -0
  179. package/dist/portal/index.d.ts +13 -0
  180. package/dist/portal/index.js +37 -0
  181. package/dist/portal/index.js.map +1 -0
  182. package/dist/portal/index.mjs +10 -0
  183. package/dist/portal/index.mjs.map +1 -0
  184. package/dist/progress/index.d.mts +48 -0
  185. package/dist/progress/index.d.ts +48 -0
  186. package/dist/progress/index.js +201 -0
  187. package/dist/progress/index.js.map +1 -0
  188. package/dist/progress/index.mjs +174 -0
  189. package/dist/progress/index.mjs.map +1 -0
  190. package/dist/progress-tracker/index.d.mts +81 -0
  191. package/dist/progress-tracker/index.d.ts +81 -0
  192. package/dist/progress-tracker/index.js +834 -0
  193. package/dist/progress-tracker/index.js.map +1 -0
  194. package/dist/progress-tracker/index.mjs +716 -0
  195. package/dist/progress-tracker/index.mjs.map +1 -0
  196. package/dist/radio-group/index.d.mts +100 -0
  197. package/dist/radio-group/index.d.ts +100 -0
  198. package/dist/radio-group/index.js +824 -0
  199. package/dist/radio-group/index.js.map +1 -0
  200. package/dist/radio-group/index.mjs +297 -0
  201. package/dist/radio-group/index.mjs.map +1 -0
  202. package/dist/rating/index.d.mts +78 -0
  203. package/dist/rating/index.d.ts +78 -0
  204. package/dist/rating/index.js +362 -0
  205. package/dist/rating/index.js.map +1 -0
  206. package/dist/rating/index.mjs +247 -0
  207. package/dist/rating/index.mjs.map +1 -0
  208. package/dist/scrolling-list/index.d.mts +105 -0
  209. package/dist/scrolling-list/index.d.ts +105 -0
  210. package/dist/scrolling-list/index.js +1367 -0
  211. package/dist/scrolling-list/index.js.map +1 -0
  212. package/dist/scrolling-list/index.mjs +407 -0
  213. package/dist/scrolling-list/index.mjs.map +1 -0
  214. package/dist/select/index.d.mts +167 -0
  215. package/dist/select/index.d.ts +167 -0
  216. package/dist/select/index.js +991 -0
  217. package/dist/select/index.js.map +1 -0
  218. package/dist/select/index.mjs +470 -0
  219. package/dist/select/index.mjs.map +1 -0
  220. package/dist/skeleton/index.d.mts +67 -0
  221. package/dist/skeleton/index.d.ts +67 -0
  222. package/dist/skeleton/index.js +206 -0
  223. package/dist/skeleton/index.js.map +1 -0
  224. package/dist/skeleton/index.mjs +147 -0
  225. package/dist/skeleton/index.mjs.map +1 -0
  226. package/dist/slider/index.d.mts +97 -0
  227. package/dist/slider/index.d.ts +97 -0
  228. package/dist/slider/index.js +209 -0
  229. package/dist/slider/index.js.map +1 -0
  230. package/dist/slider/index.mjs +182 -0
  231. package/dist/slider/index.mjs.map +1 -0
  232. package/dist/slot/index.d.mts +17 -0
  233. package/dist/slot/index.d.ts +17 -0
  234. package/dist/slot/index.js +51 -0
  235. package/dist/slot/index.js.map +1 -0
  236. package/dist/slot/index.mjs +11 -0
  237. package/dist/slot/index.mjs.map +1 -0
  238. package/dist/snackbar/index.d.mts +158 -0
  239. package/dist/snackbar/index.d.ts +158 -0
  240. package/dist/snackbar/index.js +1693 -0
  241. package/dist/snackbar/index.js.map +1 -0
  242. package/dist/snackbar/index.mjs +733 -0
  243. package/dist/snackbar/index.mjs.map +1 -0
  244. package/dist/spinner/index.d.mts +21 -0
  245. package/dist/spinner/index.d.ts +21 -0
  246. package/dist/spinner/index.js +139 -0
  247. package/dist/spinner/index.js.map +1 -0
  248. package/dist/spinner/index.mjs +9 -0
  249. package/dist/spinner/index.mjs.map +1 -0
  250. package/dist/stepper/index.d.mts +82 -0
  251. package/dist/stepper/index.d.ts +82 -0
  252. package/dist/stepper/index.js +2178 -0
  253. package/dist/stepper/index.js.map +1 -0
  254. package/dist/stepper/index.mjs +229 -0
  255. package/dist/stepper/index.mjs.map +1 -0
  256. package/dist/switch/index.d.mts +64 -0
  257. package/dist/switch/index.d.ts +64 -0
  258. package/dist/switch/index.js +768 -0
  259. package/dist/switch/index.js.map +1 -0
  260. package/dist/switch/index.mjs +245 -0
  261. package/dist/switch/index.mjs.map +1 -0
  262. package/dist/tabs/index.d.mts +103 -0
  263. package/dist/tabs/index.d.ts +103 -0
  264. package/dist/tabs/index.js +1315 -0
  265. package/dist/tabs/index.js.map +1 -0
  266. package/dist/tabs/index.mjs +391 -0
  267. package/dist/tabs/index.mjs.map +1 -0
  268. package/dist/tag/index.d.mts +27 -0
  269. package/dist/tag/index.d.ts +27 -0
  270. package/dist/tag/index.js +269 -0
  271. package/dist/tag/index.js.map +1 -0
  272. package/dist/tag/index.mjs +237 -0
  273. package/dist/tag/index.mjs.map +1 -0
  274. package/dist/text-link/index.d.mts +20 -0
  275. package/dist/text-link/index.d.ts +20 -0
  276. package/dist/text-link/index.js +99 -0
  277. package/dist/text-link/index.js.map +1 -0
  278. package/dist/text-link/index.mjs +8 -0
  279. package/dist/text-link/index.mjs.map +1 -0
  280. package/dist/textarea/index.d.mts +47 -0
  281. package/dist/textarea/index.d.ts +47 -0
  282. package/dist/textarea/index.js +1180 -0
  283. package/dist/textarea/index.js.map +1 -0
  284. package/dist/textarea/index.mjs +77 -0
  285. package/dist/textarea/index.mjs.map +1 -0
  286. package/dist/visually-hidden/index.d.mts +16 -0
  287. package/dist/visually-hidden/index.d.ts +16 -0
  288. package/dist/visually-hidden/index.js +67 -0
  289. package/dist/visually-hidden/index.js.map +1 -0
  290. package/dist/visually-hidden/index.mjs +8 -0
  291. package/dist/visually-hidden/index.mjs.map +1 -0
  292. package/global.d.ts +12 -0
  293. package/package.json +75 -0
  294. package/tsconfig.build.json +9 -0
  295. package/tsconfig.json +9 -0
  296. package/tsup.config.ts +11 -0
@@ -0,0 +1,741 @@
1
+ import {
2
+ Popover
3
+ } from "../chunk-B42LOFIZ.mjs";
4
+ import "../chunk-2KPFQEAA.mjs";
5
+ import "../chunk-6JOA37TZ.mjs";
6
+ import "../chunk-MUNDKRAE.mjs";
7
+ import {
8
+ useFormFieldControl
9
+ } from "../chunk-7PMPYEHJ.mjs";
10
+ import "../chunk-HLXYG643.mjs";
11
+ import {
12
+ Icon
13
+ } from "../chunk-AESXFMCC.mjs";
14
+ import {
15
+ VisuallyHidden
16
+ } from "../chunk-NBZKMCHF.mjs";
17
+ import "../chunk-4F5DOL57.mjs";
18
+
19
+ // src/dropdown/DropdownContext.tsx
20
+ import {
21
+ createContext,
22
+ Fragment,
23
+ useContext,
24
+ useEffect,
25
+ useId,
26
+ useState
27
+ } from "react";
28
+
29
+ // src/dropdown/useDropdown.ts
30
+ import { useMultipleSelection, useSelect } from "downshift";
31
+ var useDropdown = ({
32
+ itemsMap,
33
+ defaultValue,
34
+ value,
35
+ onValueChange,
36
+ open,
37
+ onOpenChange,
38
+ defaultOpen,
39
+ multiple,
40
+ id,
41
+ labelId
42
+ }) => {
43
+ const items = [...itemsMap.values()];
44
+ const downshiftMultipleSelection = useMultipleSelection({
45
+ selectedItems: value != null && multiple ? items.filter(
46
+ (item) => multiple ? value.includes(item.value) : value === item.value
47
+ ) : void 0,
48
+ initialSelectedItems: defaultValue != null && multiple ? items.filter(
49
+ (item) => multiple ? defaultValue.includes(item.value) : defaultValue === item.value
50
+ ) : void 0,
51
+ onSelectedItemsChange: ({ selectedItems }) => {
52
+ if (selectedItems != null && multiple) {
53
+ onValueChange?.(selectedItems.map((item) => item.value));
54
+ }
55
+ }
56
+ });
57
+ const stateReducer = (state, { changes, type }) => {
58
+ if (!multiple) return changes;
59
+ const { selectedItems, removeSelectedItem, addSelectedItem } = downshiftMultipleSelection;
60
+ switch (type) {
61
+ case useSelect.stateChangeTypes.ToggleButtonKeyDownEnter:
62
+ case useSelect.stateChangeTypes.ToggleButtonKeyDownSpaceButton:
63
+ case useSelect.stateChangeTypes.ItemClick:
64
+ if (changes.selectedItem != null) {
65
+ const isAlreadySelected = selectedItems.some(
66
+ (selectedItem) => selectedItem.value === changes.selectedItem?.value
67
+ );
68
+ if (isAlreadySelected) removeSelectedItem(changes.selectedItem);
69
+ else addSelectedItem(changes.selectedItem);
70
+ }
71
+ return {
72
+ ...changes,
73
+ isOpen: true,
74
+ // keep the menu open after selection.
75
+ highlightedIndex: state.highlightedIndex
76
+ // preserve highlighted index position
77
+ };
78
+ default:
79
+ return changes;
80
+ }
81
+ };
82
+ const downshift = useSelect({
83
+ items,
84
+ isItemDisabled: (item) => item.disabled,
85
+ itemToString: (item) => item ? item.text : "",
86
+ // a11y attributes
87
+ id,
88
+ labelId,
89
+ // Controlled open state
90
+ isOpen: open,
91
+ // undefined must be passed for stateful behaviour (uncontrolled)
92
+ onIsOpenChange: ({ isOpen }) => {
93
+ if (isOpen != null) onOpenChange?.(isOpen);
94
+ },
95
+ initialIsOpen: defaultOpen ?? false,
96
+ stateReducer,
97
+ // Controlled mode (single selection)
98
+ selectedItem: value != null && !multiple ? itemsMap.get(value) || null : void 0,
99
+ initialSelectedItem: (defaultValue != null || value != null) && !multiple ? itemsMap.get(defaultValue) || null : void 0,
100
+ onSelectedItemChange: ({ selectedItem }) => {
101
+ if (selectedItem?.value != null && !multiple) {
102
+ onValueChange?.(selectedItem?.value);
103
+ }
104
+ },
105
+ /**
106
+ * 1. Downshift default behaviour is to scroll into view the highlighted item when the dropdown opens. This behaviour is not stable and scrolls the dropdown to the bottom of the screen.
107
+ */
108
+ scrollIntoView: (node) => {
109
+ if (node) {
110
+ node.scrollIntoView({ block: "nearest" });
111
+ }
112
+ return void 0;
113
+ }
114
+ });
115
+ return {
116
+ ...downshift,
117
+ ...downshiftMultipleSelection,
118
+ /** There is a Downshift bug in React 19, it duplicates some selectedItems */
119
+ selectedItems: [...new Set(downshiftMultipleSelection.selectedItems)]
120
+ };
121
+ };
122
+
123
+ // src/dropdown/utils.ts
124
+ import { isValidElement, Children } from "react";
125
+ function getIndexByKey(map, targetKey) {
126
+ let index = 0;
127
+ for (const [key] of map.entries()) {
128
+ if (key === targetKey) {
129
+ return index;
130
+ }
131
+ index++;
132
+ }
133
+ return -1;
134
+ }
135
+ var getKeyAtIndex = (map, index) => {
136
+ let i = 0;
137
+ for (const key of map.keys()) {
138
+ if (i === index) return key;
139
+ i++;
140
+ }
141
+ return void 0;
142
+ };
143
+ var getElementByIndex = (map, index) => {
144
+ const key = getKeyAtIndex(map, index);
145
+ return key !== void 0 ? map.get(key) : void 0;
146
+ };
147
+ var getElementDisplayName = (element) => {
148
+ return element ? element.type.displayName : "";
149
+ };
150
+ var getOrderedItems = (children, result = []) => {
151
+ Children.forEach(children, (child) => {
152
+ if (!isValidElement(child)) return;
153
+ if (getElementDisplayName(child) === "Dropdown.Item") {
154
+ const childProps = child.props;
155
+ result.push({
156
+ value: childProps.value,
157
+ disabled: !!childProps.disabled,
158
+ text: getItemText(childProps.children)
159
+ });
160
+ }
161
+ if (child.props.children) {
162
+ getOrderedItems(child.props.children, result);
163
+ }
164
+ });
165
+ return result;
166
+ };
167
+ var getItemText = (children, itemText = "") => {
168
+ if (typeof children === "string") {
169
+ return children;
170
+ }
171
+ Children.forEach(children, (child) => {
172
+ if (!isValidElement(child)) return;
173
+ if (getElementDisplayName(child) === "Dropdown.ItemText") {
174
+ itemText = child.props.children;
175
+ }
176
+ if (child.props.children) {
177
+ getItemText(child.props.children, itemText);
178
+ }
179
+ });
180
+ return itemText;
181
+ };
182
+ var getItemsFromChildren = (children) => {
183
+ const newMap = /* @__PURE__ */ new Map();
184
+ getOrderedItems(children).forEach((itemData) => {
185
+ newMap.set(itemData.value, itemData);
186
+ });
187
+ return newMap;
188
+ };
189
+ var hasChildComponent = (children, displayName) => {
190
+ return Children.toArray(children).some((child) => {
191
+ if (!isValidElement(child)) return false;
192
+ if (getElementDisplayName(child) === displayName) {
193
+ return true;
194
+ } else if (child.props.children) {
195
+ return hasChildComponent(child.props.children, displayName);
196
+ }
197
+ return false;
198
+ });
199
+ };
200
+
201
+ // src/dropdown/DropdownContext.tsx
202
+ import { jsx } from "react/jsx-runtime";
203
+ var DropdownContext = createContext(null);
204
+ var ID_PREFIX = ":dropdown";
205
+ var DropdownProvider = ({
206
+ children,
207
+ defaultValue,
208
+ value,
209
+ onValueChange,
210
+ open,
211
+ onOpenChange,
212
+ defaultOpen,
213
+ multiple = false,
214
+ disabled: disabledProp = false,
215
+ readOnly: readOnlyProp = false,
216
+ state: stateProp
217
+ }) => {
218
+ const [itemsMap, setItemsMap] = useState(getItemsFromChildren(children));
219
+ const [hasPopover, setHasPopover] = useState(
220
+ hasChildComponent(children, "Dropdown.Popover")
221
+ );
222
+ const [lastInteractionType, setLastInteractionType] = useState("mouse");
223
+ const field = useFormFieldControl();
224
+ const state = field.state || stateProp;
225
+ const internalFieldLabelID = `${ID_PREFIX}-label-${useId()}`;
226
+ const internalFieldID = `${ID_PREFIX}-input-${useId()}`;
227
+ const id = field.id || internalFieldID;
228
+ const labelId = field.labelId || internalFieldLabelID;
229
+ const disabled = field.disabled ?? disabledProp;
230
+ const readOnly = field.readOnly ?? readOnlyProp;
231
+ const dropdownState = useDropdown({
232
+ itemsMap,
233
+ defaultValue,
234
+ value,
235
+ onValueChange,
236
+ open,
237
+ onOpenChange,
238
+ defaultOpen,
239
+ multiple,
240
+ id,
241
+ labelId
242
+ });
243
+ useEffect(() => {
244
+ const newMap = getItemsFromChildren(children);
245
+ const previousItems = [...itemsMap.values()];
246
+ const newItems = [...newMap.values()];
247
+ const hasItemsChanges = previousItems.length !== newItems.length || previousItems.some((item, index) => {
248
+ const hasUpdatedValue = item.value !== newItems[index]?.value;
249
+ const hasUpdatedText = item.text !== newItems[index]?.text;
250
+ return hasUpdatedValue || hasUpdatedText;
251
+ });
252
+ if (hasItemsChanges) {
253
+ setItemsMap(newMap);
254
+ }
255
+ }, [children]);
256
+ const [WrapperComponent, wrapperProps] = hasPopover ? [Popover, { open: true }] : [Fragment, {}];
257
+ return /* @__PURE__ */ jsx(
258
+ DropdownContext.Provider,
259
+ {
260
+ value: {
261
+ multiple,
262
+ disabled,
263
+ readOnly,
264
+ ...dropdownState,
265
+ itemsMap,
266
+ highlightedItem: getElementByIndex(itemsMap, dropdownState.highlightedIndex),
267
+ hasPopover,
268
+ setHasPopover,
269
+ state,
270
+ lastInteractionType,
271
+ setLastInteractionType
272
+ },
273
+ children: /* @__PURE__ */ jsx(WrapperComponent, { ...wrapperProps, children })
274
+ }
275
+ );
276
+ };
277
+ var useDropdownContext = () => {
278
+ const context = useContext(DropdownContext);
279
+ if (!context) {
280
+ throw Error("useDropdownContext must be used within a Dropdown provider");
281
+ }
282
+ return context;
283
+ };
284
+
285
+ // src/dropdown/Dropdown.tsx
286
+ import { jsx as jsx2 } from "react/jsx-runtime";
287
+ var Dropdown = ({ children, ...props }) => {
288
+ return /* @__PURE__ */ jsx2(DropdownProvider, { ...props, children });
289
+ };
290
+ Dropdown.displayName = "Dropdown";
291
+
292
+ // src/dropdown/DropdownDivider.tsx
293
+ import { cx } from "class-variance-authority";
294
+ import { jsx as jsx3 } from "react/jsx-runtime";
295
+ var Divider = ({ className, ref: forwardedRef }) => {
296
+ return /* @__PURE__ */ jsx3("div", { ref: forwardedRef, className: cx("my-md border-b-sm border-outline", className) });
297
+ };
298
+ Divider.displayName = "Dropdown.Divider";
299
+
300
+ // src/dropdown/DropdownGroup.tsx
301
+ import { cx as cx2 } from "class-variance-authority";
302
+
303
+ // src/dropdown/DropdownItemsGroupContext.tsx
304
+ import { createContext as createContext2, useContext as useContext2, useId as useId2 } from "react";
305
+ import { jsx as jsx4 } from "react/jsx-runtime";
306
+ var DropdownGroupContext = createContext2(null);
307
+ var DropdownGroupProvider = ({ children }) => {
308
+ const labelId = `${ID_PREFIX}-group-label-${useId2()}`;
309
+ return /* @__PURE__ */ jsx4(DropdownGroupContext.Provider, { value: { labelId }, children });
310
+ };
311
+ var useDropdownGroupContext = () => {
312
+ const context = useContext2(DropdownGroupContext);
313
+ if (!context) {
314
+ throw Error("useDropdownGroupContext must be used within a DropdownGroup provider");
315
+ }
316
+ return context;
317
+ };
318
+
319
+ // src/dropdown/DropdownGroup.tsx
320
+ import { jsx as jsx5 } from "react/jsx-runtime";
321
+ var Group = ({ children, ref: forwardedRef, ...props }) => {
322
+ return /* @__PURE__ */ jsx5(DropdownGroupProvider, { children: /* @__PURE__ */ jsx5(GroupContent, { ref: forwardedRef, ...props, children }) });
323
+ };
324
+ var GroupContent = ({ children, className, ref: forwardedRef }) => {
325
+ const { labelId } = useDropdownGroupContext();
326
+ return /* @__PURE__ */ jsx5("div", { ref: forwardedRef, role: "group", "aria-labelledby": labelId, className: cx2(className), children });
327
+ };
328
+ Group.displayName = "Dropdown.Group";
329
+
330
+ // src/dropdown/DropdownItem.tsx
331
+ import { useMergeRefs } from "@spark-ui/use-merge-refs";
332
+ import { cva, cx as cx3 } from "class-variance-authority";
333
+
334
+ // src/dropdown/DropdownItemContext.tsx
335
+ import {
336
+ createContext as createContext3,
337
+ useContext as useContext3,
338
+ useState as useState2
339
+ } from "react";
340
+ import { jsx as jsx6 } from "react/jsx-runtime";
341
+ var DropdownItemContext = createContext3(null);
342
+ var DropdownItemProvider = ({
343
+ value,
344
+ disabled = false,
345
+ children
346
+ }) => {
347
+ const { multiple, itemsMap, selectedItem, selectedItems } = useDropdownContext();
348
+ const [textId, setTextId] = useState2(void 0);
349
+ const index = getIndexByKey(itemsMap, value);
350
+ const itemData = { disabled, value, text: getItemText(children) };
351
+ const isSelected = multiple ? selectedItems.some((selectedItem2) => selectedItem2.value === value) : selectedItem?.value === value;
352
+ return /* @__PURE__ */ jsx6(
353
+ DropdownItemContext.Provider,
354
+ {
355
+ value: { textId, setTextId, isSelected, itemData, index, disabled },
356
+ children
357
+ }
358
+ );
359
+ };
360
+ var useDropdownItemContext = () => {
361
+ const context = useContext3(DropdownItemContext);
362
+ if (!context) {
363
+ throw Error("useDropdownItemContext must be used within a DropdownItem provider");
364
+ }
365
+ return context;
366
+ };
367
+
368
+ // src/dropdown/DropdownItem.tsx
369
+ import { jsx as jsx7 } from "react/jsx-runtime";
370
+ var Item = ({ children, ref: forwardedRef, ...props }) => {
371
+ const { value, disabled } = props;
372
+ return /* @__PURE__ */ jsx7(DropdownItemProvider, { value, disabled, children: /* @__PURE__ */ jsx7(ItemContent, { ref: forwardedRef, ...props, children }) });
373
+ };
374
+ var styles = cva("px-lg py-md text-body-1", {
375
+ variants: {
376
+ selected: {
377
+ true: "font-bold"
378
+ },
379
+ disabled: {
380
+ true: "opacity-dim-3 cursor-not-allowed",
381
+ false: "cursor-pointer"
382
+ },
383
+ highlighted: {
384
+ true: ""
385
+ },
386
+ interactionType: {
387
+ mouse: "",
388
+ keyboard: ""
389
+ }
390
+ },
391
+ compoundVariants: [
392
+ {
393
+ highlighted: true,
394
+ interactionType: "mouse",
395
+ class: "bg-surface-hovered"
396
+ },
397
+ {
398
+ highlighted: true,
399
+ interactionType: "keyboard",
400
+ class: "u-outline"
401
+ }
402
+ ]
403
+ });
404
+ var ItemContent = ({
405
+ className,
406
+ disabled = false,
407
+ value,
408
+ children,
409
+ ref: forwardedRef
410
+ }) => {
411
+ const { getItemProps, highlightedItem, lastInteractionType } = useDropdownContext();
412
+ const { textId, index, itemData, isSelected } = useDropdownItemContext();
413
+ const isHighlighted = highlightedItem?.value === value;
414
+ const { ref: downshiftRef, ...downshiftItemProps } = getItemProps({ item: itemData, index });
415
+ const ref = useMergeRefs(forwardedRef, downshiftRef);
416
+ return /* @__PURE__ */ jsx7(
417
+ "li",
418
+ {
419
+ ref,
420
+ className: cx3(
421
+ styles({
422
+ selected: isSelected,
423
+ disabled,
424
+ highlighted: isHighlighted,
425
+ interactionType: lastInteractionType,
426
+ className
427
+ })
428
+ ),
429
+ ...downshiftItemProps,
430
+ "aria-selected": isSelected,
431
+ "aria-labelledby": textId,
432
+ children
433
+ },
434
+ value
435
+ );
436
+ };
437
+ Item.displayName = "Dropdown.Item";
438
+
439
+ // src/dropdown/DropdownItemIndicator.tsx
440
+ import { Check } from "@spark-ui/icons/Check";
441
+ import { cx as cx4 } from "class-variance-authority";
442
+ import { jsx as jsx8 } from "react/jsx-runtime";
443
+ var ItemIndicator = ({
444
+ className,
445
+ children,
446
+ label,
447
+ ref: forwardedRef
448
+ }) => {
449
+ const { disabled, isSelected } = useDropdownItemContext();
450
+ const childElement = children || /* @__PURE__ */ jsx8(Icon, { size: "sm", children: /* @__PURE__ */ jsx8(Check, { "aria-label": label }) });
451
+ return /* @__PURE__ */ jsx8(
452
+ "span",
453
+ {
454
+ ref: forwardedRef,
455
+ className: cx4("min-h-sz-16 min-w-sz-16 flex", disabled && "opacity-dim-3", className),
456
+ children: isSelected && childElement
457
+ }
458
+ );
459
+ };
460
+ ItemIndicator.displayName = "Dropdown.ItemIndicator";
461
+
462
+ // src/dropdown/DropdownItems.tsx
463
+ import { useMergeRefs as useMergeRefs2 } from "@spark-ui/use-merge-refs";
464
+ import { cx as cx5 } from "class-variance-authority";
465
+ import { useLayoutEffect, useRef } from "react";
466
+ import { jsx as jsx9 } from "react/jsx-runtime";
467
+ var Items = ({ children, className, ref: forwardedRef, ...props }) => {
468
+ const { isOpen, getMenuProps, hasPopover, setLastInteractionType } = useDropdownContext();
469
+ const { ref: downshiftRef, ...downshiftMenuProps } = getMenuProps({
470
+ onMouseMove: () => {
471
+ setLastInteractionType("mouse");
472
+ }
473
+ });
474
+ const innerRef = useRef(null);
475
+ const ref = useMergeRefs2(forwardedRef, downshiftRef, innerRef);
476
+ useLayoutEffect(() => {
477
+ if (!hasPopover) return;
478
+ if (!innerRef.current) return;
479
+ if (innerRef.current.parentElement) {
480
+ innerRef.current.parentElement.style.pointerEvents = isOpen ? "" : "none";
481
+ innerRef.current.style.pointerEvents = isOpen ? "" : "none";
482
+ }
483
+ }, [isOpen, hasPopover]);
484
+ return /* @__PURE__ */ jsx9(
485
+ "ul",
486
+ {
487
+ ref,
488
+ className: cx5(
489
+ className,
490
+ "flex flex-col",
491
+ isOpen ? "pointer-events-auto! block" : "pointer-events-none invisible absolute opacity-0",
492
+ hasPopover && "p-lg"
493
+ ),
494
+ ...props,
495
+ ...downshiftMenuProps,
496
+ "data-spark-component": "dropdown-items",
497
+ children
498
+ }
499
+ );
500
+ };
501
+ Items.displayName = "Dropdown.Items";
502
+
503
+ // src/dropdown/DropdownItemText.tsx
504
+ import { cx as cx6 } from "class-variance-authority";
505
+ import { useEffect as useEffect2, useId as useId3 } from "react";
506
+ import { jsx as jsx10 } from "react/jsx-runtime";
507
+ var ItemText = ({ children, ref: forwardedRef }) => {
508
+ const id = `${ID_PREFIX}-item-text-${useId3()}`;
509
+ const { setTextId } = useDropdownItemContext();
510
+ useEffect2(() => {
511
+ setTextId(id);
512
+ return () => setTextId(void 0);
513
+ });
514
+ return /* @__PURE__ */ jsx10("span", { id, className: cx6("inline"), ref: forwardedRef, children });
515
+ };
516
+ ItemText.displayName = "Dropdown.ItemText";
517
+
518
+ // src/dropdown/DropdownLabel.tsx
519
+ import { cx as cx7 } from "class-variance-authority";
520
+ import { jsx as jsx11 } from "react/jsx-runtime";
521
+ var Label = ({ children, className, ref: forwardedRef }) => {
522
+ const { labelId } = useDropdownGroupContext();
523
+ return /* @__PURE__ */ jsx11(
524
+ "div",
525
+ {
526
+ ref: forwardedRef,
527
+ id: labelId,
528
+ className: cx7("px-md py-sm text-body-2 text-neutral italic", className),
529
+ children
530
+ }
531
+ );
532
+ };
533
+ Label.displayName = "Dropdown.Label";
534
+
535
+ // src/dropdown/DropdownLeadingIcon.tsx
536
+ import { jsx as jsx12 } from "react/jsx-runtime";
537
+ var LeadingIcon = ({ children }) => {
538
+ return /* @__PURE__ */ jsx12(Icon, { size: "sm", className: "shrink-0", children });
539
+ };
540
+ LeadingIcon.displayName = "Dropdown.LeadingIcon";
541
+
542
+ // src/dropdown/DropdownPopover.tsx
543
+ import { cx as cx8 } from "class-variance-authority";
544
+ import { useEffect as useEffect3 } from "react";
545
+ import { jsx as jsx13 } from "react/jsx-runtime";
546
+ var Popover2 = ({
547
+ children,
548
+ matchTriggerWidth = true,
549
+ sideOffset = 4,
550
+ className,
551
+ elevation = "dropdown",
552
+ ref: forwardedRef,
553
+ ...props
554
+ }) => {
555
+ const ctx = useDropdownContext();
556
+ useEffect3(() => {
557
+ ctx.setHasPopover(true);
558
+ return () => ctx.setHasPopover(false);
559
+ }, []);
560
+ return /* @__PURE__ */ jsx13(
561
+ Popover.Content,
562
+ {
563
+ ref: forwardedRef,
564
+ inset: true,
565
+ asChild: true,
566
+ matchTriggerWidth,
567
+ elevation,
568
+ className: cx8("relative", className),
569
+ sideOffset,
570
+ onOpenAutoFocus: (e) => {
571
+ e.preventDefault();
572
+ },
573
+ ...props,
574
+ "data-spark-component": "dropdown-popover",
575
+ children
576
+ }
577
+ );
578
+ };
579
+ Popover2.displayName = "Dropdown.Popover";
580
+
581
+ // src/dropdown/DropdownPortal.tsx
582
+ import { jsx as jsx14 } from "react/jsx-runtime";
583
+ var Portal = ({ children, ...rest }) => /* @__PURE__ */ jsx14(Popover.Portal, { ...rest, children });
584
+ Portal.displayName = "Dropdown.Portal";
585
+
586
+ // src/dropdown/DropdownTrigger.tsx
587
+ import { ArrowHorizontalDown } from "@spark-ui/icons/ArrowHorizontalDown";
588
+ import { useMergeRefs as useMergeRefs3 } from "@spark-ui/use-merge-refs";
589
+ import { cx as cx9 } from "class-variance-authority";
590
+ import { Fragment as Fragment2 } from "react";
591
+
592
+ // src/dropdown/DropdownTrigger.styles.tsx
593
+ import { cva as cva2 } from "class-variance-authority";
594
+ var styles2 = cva2(
595
+ [
596
+ "flex w-full items-center justify-between",
597
+ "min-h-sz-44 rounded-lg bg-surface text-on-surface px-lg",
598
+ "text-body-1",
599
+ // outline styles
600
+ "ring-1 outline-hidden ring-inset focus:ring-2"
601
+ ],
602
+ {
603
+ variants: {
604
+ state: {
605
+ undefined: "ring-outline focus:ring-outline-high",
606
+ error: "ring-error",
607
+ alert: "ring-alert",
608
+ success: "ring-success"
609
+ },
610
+ disabled: {
611
+ true: "disabled:bg-on-surface/dim-5 cursor-not-allowed text-on-surface/dim-3"
612
+ },
613
+ readOnly: {
614
+ true: "disabled:bg-on-surface/dim-5 cursor-not-allowed text-on-surface/dim-3"
615
+ }
616
+ },
617
+ compoundVariants: [
618
+ {
619
+ disabled: false,
620
+ state: void 0,
621
+ class: "hover:ring-outline-high"
622
+ }
623
+ ]
624
+ }
625
+ );
626
+
627
+ // src/dropdown/DropdownTrigger.tsx
628
+ import { Fragment as Fragment3, jsx as jsx15, jsxs } from "react/jsx-runtime";
629
+ var Trigger = ({
630
+ "aria-label": ariaLabel,
631
+ children,
632
+ className,
633
+ ref: forwardedRef
634
+ }) => {
635
+ const {
636
+ getToggleButtonProps,
637
+ getDropdownProps,
638
+ getLabelProps,
639
+ hasPopover,
640
+ disabled,
641
+ readOnly,
642
+ state,
643
+ setLastInteractionType
644
+ } = useDropdownContext();
645
+ const [WrapperComponent, wrapperProps] = hasPopover ? [Popover.Trigger, { asChild: true }] : [Fragment2, {}];
646
+ const { ref: downshiftRef, ...downshiftTriggerProps } = getToggleButtonProps({
647
+ ...getDropdownProps(),
648
+ onKeyDown: () => {
649
+ setLastInteractionType("keyboard");
650
+ }
651
+ });
652
+ const isExpanded = downshiftTriggerProps["aria-expanded"];
653
+ const ref = useMergeRefs3(forwardedRef, downshiftRef);
654
+ return /* @__PURE__ */ jsxs(Fragment3, { children: [
655
+ ariaLabel && /* @__PURE__ */ jsx15(VisuallyHidden, { children: /* @__PURE__ */ jsx15("label", { ...getLabelProps(), children: ariaLabel }) }),
656
+ /* @__PURE__ */ jsx15(WrapperComponent, { ...wrapperProps, children: /* @__PURE__ */ jsxs(
657
+ "button",
658
+ {
659
+ type: "button",
660
+ ref,
661
+ disabled: disabled || readOnly,
662
+ className: styles2({ className, state, disabled, readOnly }),
663
+ ...downshiftTriggerProps,
664
+ "data-spark-component": "dropdown-trigger",
665
+ children: [
666
+ /* @__PURE__ */ jsx15("span", { className: "gap-md flex items-center justify-start", children }),
667
+ /* @__PURE__ */ jsx15(
668
+ Icon,
669
+ {
670
+ className: cx9("ml-md shrink-0 rotate-0 transition duration-100 ease-in", {
671
+ "rotate-180": isExpanded
672
+ }),
673
+ size: "sm",
674
+ children: /* @__PURE__ */ jsx15(ArrowHorizontalDown, {})
675
+ }
676
+ )
677
+ ]
678
+ }
679
+ ) })
680
+ ] });
681
+ };
682
+ Trigger.displayName = "Dropdown.Trigger";
683
+
684
+ // src/dropdown/DropdownValue.tsx
685
+ import { cx as cx10 } from "class-variance-authority";
686
+ import { jsx as jsx16, jsxs as jsxs2 } from "react/jsx-runtime";
687
+ var Value = ({ children, className, placeholder, ref: forwardedRef }) => {
688
+ const { selectedItem, multiple, selectedItems } = useDropdownContext();
689
+ const hasSelectedItems = !!(multiple ? selectedItems.length : selectedItem);
690
+ const text = multiple ? selectedItems[0]?.text : selectedItem?.text;
691
+ const suffix = selectedItems.length > 1 ? `, +${selectedItems.length - 1}` : "";
692
+ return /* @__PURE__ */ jsxs2("span", { ref: forwardedRef, className: cx10("flex shrink items-center text-left", className), children: [
693
+ /* @__PURE__ */ jsx16(
694
+ "span",
695
+ {
696
+ className: cx10(
697
+ "line-clamp-1 flex-1 overflow-hidden break-all text-ellipsis",
698
+ !hasSelectedItems && "text-on-surface/dim-1"
699
+ ),
700
+ children: !hasSelectedItems ? placeholder : children || text
701
+ }
702
+ ),
703
+ suffix && /* @__PURE__ */ jsx16("span", { children: suffix })
704
+ ] });
705
+ };
706
+ Value.displayName = "Dropdown.Value";
707
+
708
+ // src/dropdown/index.ts
709
+ var Dropdown2 = Object.assign(Dropdown, {
710
+ Group,
711
+ Item,
712
+ Items,
713
+ ItemText,
714
+ ItemIndicator,
715
+ Label,
716
+ Popover: Popover2,
717
+ Divider,
718
+ Trigger,
719
+ Value,
720
+ LeadingIcon,
721
+ Portal
722
+ });
723
+ Dropdown2.displayName = "Dropdown";
724
+ Group.displayName = "Dropdown.Group";
725
+ Items.displayName = "Dropdown.Items";
726
+ Item.displayName = "Dropdown.Item";
727
+ ItemText.displayName = "Dropdown.ItemText";
728
+ ItemIndicator.displayName = "Dropdown.ItemIndicator";
729
+ Label.displayName = "Dropdown.Label";
730
+ Popover2.displayName = "Dropdown.Popover";
731
+ Divider.displayName = "Dropdown.Divider";
732
+ Trigger.displayName = "Dropdown.Trigger";
733
+ Value.displayName = "Dropdown.Value";
734
+ LeadingIcon.displayName = "Dropdown.LeadingIcon";
735
+ Portal.displayName = "Dropdown.Portal";
736
+ export {
737
+ Dropdown2 as Dropdown,
738
+ DropdownProvider,
739
+ useDropdownContext
740
+ };
741
+ //# sourceMappingURL=index.mjs.map