bits-ui 1.0.0-next.6 → 1.0.0-next.61

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 (760) hide show
  1. package/dist/app.d.ts +15 -0
  2. package/dist/bits/accordion/accordion.svelte.d.ts +7 -9
  3. package/dist/bits/accordion/accordion.svelte.js +25 -19
  4. package/dist/bits/accordion/components/accordion-content.svelte +3 -4
  5. package/dist/bits/accordion/components/accordion-header.svelte +2 -3
  6. package/dist/bits/accordion/components/accordion-item.svelte +2 -3
  7. package/dist/bits/accordion/components/accordion-trigger.svelte +2 -3
  8. package/dist/bits/accordion/components/accordion.svelte +5 -6
  9. package/dist/bits/accordion/components/accordion.svelte.d.ts +2 -2
  10. package/dist/bits/accordion/exports.d.ts +6 -0
  11. package/dist/bits/accordion/exports.js +5 -0
  12. package/dist/bits/accordion/index.d.ts +1 -6
  13. package/dist/bits/accordion/index.js +1 -5
  14. package/dist/bits/accordion/types.d.ts +9 -9
  15. package/dist/bits/alert-dialog/components/alert-dialog-action.svelte +7 -9
  16. package/dist/bits/alert-dialog/components/alert-dialog-action.svelte.d.ts +1 -1
  17. package/dist/bits/alert-dialog/components/alert-dialog-cancel.svelte +6 -5
  18. package/dist/bits/alert-dialog/components/alert-dialog-cancel.svelte.d.ts +1 -1
  19. package/dist/bits/alert-dialog/components/alert-dialog-content.svelte +20 -17
  20. package/dist/bits/alert-dialog/components/alert-dialog.svelte +3 -3
  21. package/dist/bits/alert-dialog/exports.d.ts +10 -0
  22. package/dist/bits/alert-dialog/exports.js +9 -0
  23. package/dist/bits/alert-dialog/index.d.ts +1 -10
  24. package/dist/bits/alert-dialog/index.js +1 -9
  25. package/dist/bits/alert-dialog/types.d.ts +1 -1
  26. package/dist/bits/aspect-ratio/aspect-ratio.svelte.js +1 -1
  27. package/dist/bits/aspect-ratio/components/aspect-ratio.svelte +4 -5
  28. package/dist/bits/aspect-ratio/components/aspect-ratio.svelte.d.ts +2 -2
  29. package/dist/bits/aspect-ratio/exports.d.ts +2 -0
  30. package/dist/bits/aspect-ratio/exports.js +1 -0
  31. package/dist/bits/aspect-ratio/index.d.ts +1 -2
  32. package/dist/bits/aspect-ratio/index.js +1 -1
  33. package/dist/bits/aspect-ratio/types.d.ts +3 -3
  34. package/dist/bits/avatar/avatar.svelte.d.ts +9 -7
  35. package/dist/bits/avatar/avatar.svelte.js +37 -27
  36. package/dist/bits/avatar/components/avatar-fallback.svelte +4 -5
  37. package/dist/bits/avatar/components/avatar-fallback.svelte.d.ts +2 -2
  38. package/dist/bits/avatar/components/avatar-image.svelte +14 -5
  39. package/dist/bits/avatar/components/avatar-image.svelte.d.ts +2 -2
  40. package/dist/bits/avatar/components/avatar.svelte +4 -5
  41. package/dist/bits/avatar/components/avatar.svelte.d.ts +2 -2
  42. package/dist/bits/avatar/exports.d.ts +4 -0
  43. package/dist/bits/avatar/exports.js +3 -0
  44. package/dist/bits/avatar/index.d.ts +1 -4
  45. package/dist/bits/avatar/index.js +1 -3
  46. package/dist/bits/avatar/types.d.ts +4 -4
  47. package/dist/bits/button/components/button.svelte +2 -2
  48. package/dist/bits/button/components/button.svelte.d.ts +3 -3
  49. package/dist/bits/button/exports.d.ts +2 -0
  50. package/dist/bits/button/exports.js +1 -0
  51. package/dist/bits/button/index.d.ts +1 -2
  52. package/dist/bits/button/index.js +1 -1
  53. package/dist/bits/button/types.d.ts +4 -4
  54. package/dist/bits/calendar/calendar.svelte.d.ts +24 -71
  55. package/dist/bits/calendar/calendar.svelte.js +55 -77
  56. package/dist/bits/calendar/components/calendar-cell.svelte +4 -5
  57. package/dist/bits/calendar/components/calendar-cell.svelte.d.ts +2 -2
  58. package/dist/bits/calendar/components/calendar-day.svelte +10 -5
  59. package/dist/bits/calendar/components/calendar-day.svelte.d.ts +2 -2
  60. package/dist/bits/calendar/components/calendar-grid-body.svelte +4 -5
  61. package/dist/bits/calendar/components/calendar-grid-body.svelte.d.ts +2 -2
  62. package/dist/bits/calendar/components/calendar-grid-head.svelte +4 -5
  63. package/dist/bits/calendar/components/calendar-grid-head.svelte.d.ts +2 -2
  64. package/dist/bits/calendar/components/calendar-grid-row.svelte +4 -5
  65. package/dist/bits/calendar/components/calendar-grid-row.svelte.d.ts +2 -2
  66. package/dist/bits/calendar/components/calendar-grid.svelte +4 -5
  67. package/dist/bits/calendar/components/calendar-grid.svelte.d.ts +2 -2
  68. package/dist/bits/calendar/components/calendar-head-cell.svelte +4 -5
  69. package/dist/bits/calendar/components/calendar-head-cell.svelte.d.ts +2 -2
  70. package/dist/bits/calendar/components/calendar-header.svelte +4 -5
  71. package/dist/bits/calendar/components/calendar-header.svelte.d.ts +2 -2
  72. package/dist/bits/calendar/components/calendar-heading.svelte +4 -5
  73. package/dist/bits/calendar/components/calendar-heading.svelte.d.ts +2 -2
  74. package/dist/bits/calendar/components/calendar-next-button.svelte +4 -5
  75. package/dist/bits/calendar/components/calendar-next-button.svelte.d.ts +2 -2
  76. package/dist/bits/calendar/components/calendar-prev-button.svelte +4 -5
  77. package/dist/bits/calendar/components/calendar-prev-button.svelte.d.ts +2 -2
  78. package/dist/bits/calendar/components/calendar.svelte +22 -8
  79. package/dist/bits/calendar/components/calendar.svelte.d.ts +2 -2
  80. package/dist/bits/calendar/exports.d.ts +13 -0
  81. package/dist/bits/calendar/exports.js +12 -0
  82. package/dist/bits/calendar/index.d.ts +1 -13
  83. package/dist/bits/calendar/index.js +1 -12
  84. package/dist/bits/calendar/types.d.ts +15 -15
  85. package/dist/bits/checkbox/checkbox.svelte.d.ts +8 -5
  86. package/dist/bits/checkbox/checkbox.svelte.js +29 -17
  87. package/dist/bits/checkbox/components/checkbox.svelte +26 -6
  88. package/dist/bits/checkbox/components/checkbox.svelte.d.ts +3 -3
  89. package/dist/bits/checkbox/exports.d.ts +2 -0
  90. package/dist/bits/checkbox/exports.js +1 -0
  91. package/dist/bits/checkbox/index.d.ts +1 -2
  92. package/dist/bits/checkbox/index.js +1 -1
  93. package/dist/bits/checkbox/types.d.ts +25 -6
  94. package/dist/bits/collapsible/collapsible.svelte.d.ts +4 -4
  95. package/dist/bits/collapsible/collapsible.svelte.js +31 -14
  96. package/dist/bits/collapsible/components/collapsible-content.svelte +3 -4
  97. package/dist/bits/collapsible/components/collapsible-content.svelte.d.ts +3 -3
  98. package/dist/bits/collapsible/components/collapsible-trigger.svelte +4 -5
  99. package/dist/bits/collapsible/components/collapsible-trigger.svelte.d.ts +2 -2
  100. package/dist/bits/collapsible/components/collapsible.svelte +5 -6
  101. package/dist/bits/collapsible/components/collapsible.svelte.d.ts +3 -3
  102. package/dist/bits/collapsible/exports.d.ts +4 -0
  103. package/dist/bits/collapsible/exports.js +3 -0
  104. package/dist/bits/collapsible/index.d.ts +1 -4
  105. package/dist/bits/collapsible/index.js +1 -3
  106. package/dist/bits/collapsible/types.d.ts +6 -6
  107. package/dist/bits/combobox/components/combobox-input.svelte +6 -7
  108. package/dist/bits/combobox/components/combobox-input.svelte.d.ts +2 -2
  109. package/dist/bits/combobox/components/combobox-trigger.svelte +8 -8
  110. package/dist/bits/combobox/components/combobox-trigger.svelte.d.ts +2 -2
  111. package/dist/bits/combobox/components/combobox.svelte +17 -13
  112. package/dist/bits/combobox/components/combobox.svelte.d.ts +1 -1
  113. package/dist/bits/combobox/exports.d.ts +15 -0
  114. package/dist/bits/combobox/exports.js +14 -0
  115. package/dist/bits/combobox/index.d.ts +1 -8
  116. package/dist/bits/combobox/index.js +1 -7
  117. package/dist/bits/combobox/types.d.ts +3 -3
  118. package/dist/bits/command/command.svelte.d.ts +5 -13
  119. package/dist/bits/command/command.svelte.js +30 -47
  120. package/dist/bits/command/components/_command-label.svelte +2 -2
  121. package/dist/bits/command/components/_command-label.svelte.d.ts +2 -2
  122. package/dist/bits/command/components/command-empty.svelte +4 -5
  123. package/dist/bits/command/components/command-empty.svelte.d.ts +2 -2
  124. package/dist/bits/command/components/command-group-heading.svelte +4 -5
  125. package/dist/bits/command/components/command-group-heading.svelte.d.ts +2 -2
  126. package/dist/bits/command/components/command-group-items.svelte +4 -5
  127. package/dist/bits/command/components/command-group-items.svelte.d.ts +2 -2
  128. package/dist/bits/command/components/command-group.svelte +2 -3
  129. package/dist/bits/command/components/command-input.svelte +4 -5
  130. package/dist/bits/command/components/command-input.svelte.d.ts +2 -2
  131. package/dist/bits/command/components/command-item.svelte +5 -6
  132. package/dist/bits/command/components/command-item.svelte.d.ts +2 -2
  133. package/dist/bits/command/components/command-link-item.svelte +5 -6
  134. package/dist/bits/command/components/command-link-item.svelte.d.ts +2 -2
  135. package/dist/bits/command/components/command-list.svelte +4 -5
  136. package/dist/bits/command/components/command-list.svelte.d.ts +2 -2
  137. package/dist/bits/command/components/command-loading.svelte +4 -5
  138. package/dist/bits/command/components/command-loading.svelte.d.ts +2 -2
  139. package/dist/bits/command/components/command-separator.svelte +4 -5
  140. package/dist/bits/command/components/command-separator.svelte.d.ts +2 -2
  141. package/dist/bits/command/components/command-viewport.svelte +3 -3
  142. package/dist/bits/command/components/command-viewport.svelte.d.ts +2 -2
  143. package/dist/bits/command/components/command.svelte +5 -6
  144. package/dist/bits/command/components/command.svelte.d.ts +2 -2
  145. package/dist/bits/command/exports.d.ts +13 -0
  146. package/dist/bits/command/exports.js +12 -0
  147. package/dist/bits/command/index.d.ts +1 -13
  148. package/dist/bits/command/index.js +1 -12
  149. package/dist/bits/command/types.d.ts +13 -13
  150. package/dist/bits/context-menu/components/context-menu-content-static.svelte +80 -45
  151. package/dist/bits/context-menu/components/context-menu-content-static.svelte.d.ts +2 -2
  152. package/dist/bits/context-menu/components/context-menu-content.svelte +75 -51
  153. package/dist/bits/context-menu/components/context-menu-content.svelte.d.ts +2 -2
  154. package/dist/bits/context-menu/components/context-menu-trigger.svelte +4 -5
  155. package/dist/bits/context-menu/components/context-menu-trigger.svelte.d.ts +2 -2
  156. package/dist/bits/context-menu/components/context-menu.svelte +6 -6
  157. package/dist/bits/context-menu/components/context-menu.svelte.d.ts +1 -2
  158. package/dist/bits/context-menu/exports.d.ts +18 -0
  159. package/dist/bits/context-menu/exports.js +17 -0
  160. package/dist/bits/context-menu/index.d.ts +1 -18
  161. package/dist/bits/context-menu/index.js +1 -17
  162. package/dist/bits/context-menu/types.d.ts +3 -3
  163. package/dist/bits/date-field/components/date-field-input.svelte +4 -5
  164. package/dist/bits/date-field/components/date-field-input.svelte.d.ts +2 -2
  165. package/dist/bits/date-field/components/date-field-label.svelte +4 -5
  166. package/dist/bits/date-field/components/date-field-label.svelte.d.ts +2 -2
  167. package/dist/bits/date-field/components/date-field-segment.svelte +4 -5
  168. package/dist/bits/date-field/components/date-field-segment.svelte.d.ts +2 -2
  169. package/dist/bits/date-field/components/date-field.svelte +4 -4
  170. package/dist/bits/date-field/date-field.svelte.d.ts +43 -49
  171. package/dist/bits/date-field/date-field.svelte.js +94 -97
  172. package/dist/bits/date-field/exports.d.ts +5 -0
  173. package/dist/bits/date-field/exports.js +4 -0
  174. package/dist/bits/date-field/index.d.ts +1 -5
  175. package/dist/bits/date-field/index.js +1 -4
  176. package/dist/bits/date-field/types.d.ts +6 -7
  177. package/dist/bits/date-picker/components/date-picker-calendar.svelte +4 -5
  178. package/dist/bits/date-picker/components/date-picker-calendar.svelte.d.ts +2 -2
  179. package/dist/bits/date-picker/components/date-picker-content-static.svelte +8 -4
  180. package/dist/bits/date-picker/components/date-picker-content-static.svelte.d.ts +2 -2
  181. package/dist/bits/date-picker/components/date-picker-content.svelte +4 -4
  182. package/dist/bits/date-picker/components/date-picker-content.svelte.d.ts +2 -2
  183. package/dist/bits/date-picker/components/date-picker-trigger.svelte +7 -4
  184. package/dist/bits/date-picker/components/date-picker-trigger.svelte.d.ts +2 -2
  185. package/dist/bits/date-picker/components/date-picker.svelte +4 -4
  186. package/dist/bits/date-picker/date-picker.svelte.d.ts +2 -2
  187. package/dist/bits/date-picker/date-picker.svelte.js +1 -1
  188. package/dist/bits/date-picker/exports.d.ts +22 -0
  189. package/dist/bits/date-picker/exports.js +21 -0
  190. package/dist/bits/date-picker/index.d.ts +1 -22
  191. package/dist/bits/date-picker/index.js +1 -21
  192. package/dist/bits/date-picker/types.d.ts +4 -4
  193. package/dist/bits/date-range-field/components/date-range-field-input.svelte +4 -5
  194. package/dist/bits/date-range-field/components/date-range-field-input.svelte.d.ts +2 -2
  195. package/dist/bits/date-range-field/components/date-range-field-label.svelte +4 -5
  196. package/dist/bits/date-range-field/components/date-range-field-label.svelte.d.ts +2 -2
  197. package/dist/bits/date-range-field/components/date-range-field.svelte +6 -7
  198. package/dist/bits/date-range-field/components/date-range-field.svelte.d.ts +2 -2
  199. package/dist/bits/date-range-field/date-range-field.svelte.d.ts +5 -25
  200. package/dist/bits/date-range-field/date-range-field.svelte.js +30 -51
  201. package/dist/bits/date-range-field/exports.d.ts +5 -0
  202. package/dist/bits/date-range-field/exports.js +4 -0
  203. package/dist/bits/date-range-field/index.d.ts +1 -5
  204. package/dist/bits/date-range-field/index.js +1 -4
  205. package/dist/bits/date-range-field/types.d.ts +6 -6
  206. package/dist/bits/date-range-picker/components/date-range-picker-calendar.svelte +4 -5
  207. package/dist/bits/date-range-picker/components/date-range-picker-calendar.svelte.d.ts +2 -2
  208. package/dist/bits/date-range-picker/components/date-range-picker-trigger.svelte +7 -4
  209. package/dist/bits/date-range-picker/components/date-range-picker-trigger.svelte.d.ts +2 -2
  210. package/dist/bits/date-range-picker/components/date-range-picker.svelte +9 -10
  211. package/dist/bits/date-range-picker/components/date-range-picker.svelte.d.ts +2 -2
  212. package/dist/bits/date-range-picker/date-range-picker.svelte.d.ts +2 -2
  213. package/dist/bits/date-range-picker/date-range-picker.svelte.js +1 -1
  214. package/dist/bits/date-range-picker/exports.d.ts +21 -0
  215. package/dist/bits/date-range-picker/exports.js +20 -0
  216. package/dist/bits/date-range-picker/index.d.ts +1 -21
  217. package/dist/bits/date-range-picker/index.js +1 -20
  218. package/dist/bits/date-range-picker/types.d.ts +5 -6
  219. package/dist/bits/dialog/components/dialog-close.svelte +6 -5
  220. package/dist/bits/dialog/components/dialog-content.svelte +20 -17
  221. package/dist/bits/dialog/components/dialog-content.svelte.d.ts +2 -2
  222. package/dist/bits/dialog/components/dialog-description.svelte +4 -5
  223. package/dist/bits/dialog/components/dialog-description.svelte.d.ts +2 -2
  224. package/dist/bits/dialog/components/dialog-overlay.svelte +4 -5
  225. package/dist/bits/dialog/components/dialog-overlay.svelte.d.ts +2 -2
  226. package/dist/bits/dialog/components/dialog-title.svelte +4 -5
  227. package/dist/bits/dialog/components/dialog-title.svelte.d.ts +2 -2
  228. package/dist/bits/dialog/components/dialog-trigger.svelte +6 -5
  229. package/dist/bits/dialog/components/dialog-trigger.svelte.d.ts +2 -2
  230. package/dist/bits/dialog/components/dialog.svelte +3 -3
  231. package/dist/bits/dialog/dialog.svelte.d.ts +35 -14
  232. package/dist/bits/dialog/dialog.svelte.js +133 -39
  233. package/dist/bits/dialog/exports.d.ts +9 -0
  234. package/dist/bits/dialog/exports.js +8 -0
  235. package/dist/bits/dialog/index.d.ts +1 -9
  236. package/dist/bits/dialog/index.js +1 -8
  237. package/dist/bits/dialog/types.d.ts +9 -10
  238. package/dist/bits/dropdown-menu/components/dropdown-menu-content-static.svelte +67 -33
  239. package/dist/bits/dropdown-menu/components/dropdown-menu-content-static.svelte.d.ts +2 -2
  240. package/dist/bits/dropdown-menu/components/dropdown-menu-content.svelte +64 -34
  241. package/dist/bits/dropdown-menu/components/dropdown-menu-content.svelte.d.ts +2 -2
  242. package/dist/bits/dropdown-menu/exports.d.ts +18 -0
  243. package/dist/bits/dropdown-menu/exports.js +17 -0
  244. package/dist/bits/dropdown-menu/index.d.ts +1 -18
  245. package/dist/bits/dropdown-menu/index.js +1 -17
  246. package/dist/bits/dropdown-menu/types.d.ts +1 -1
  247. package/dist/bits/index.d.ts +37 -38
  248. package/dist/bits/index.js +37 -38
  249. package/dist/bits/label/components/label.svelte +4 -5
  250. package/dist/bits/label/components/label.svelte.d.ts +2 -2
  251. package/dist/bits/label/exports.d.ts +2 -0
  252. package/dist/bits/label/exports.js +1 -0
  253. package/dist/bits/label/index.d.ts +1 -2
  254. package/dist/bits/label/index.js +1 -1
  255. package/dist/bits/label/label.svelte.js +1 -1
  256. package/dist/bits/label/types.d.ts +2 -2
  257. package/dist/bits/link-preview/components/link-preview-content-static.svelte +92 -34
  258. package/dist/bits/link-preview/components/link-preview-content-static.svelte.d.ts +2 -2
  259. package/dist/bits/link-preview/components/link-preview-content.svelte +71 -35
  260. package/dist/bits/link-preview/components/link-preview-content.svelte.d.ts +2 -2
  261. package/dist/bits/link-preview/components/link-preview-trigger.svelte +4 -5
  262. package/dist/bits/link-preview/components/link-preview-trigger.svelte.d.ts +2 -2
  263. package/dist/bits/link-preview/components/link-preview.svelte +3 -3
  264. package/dist/bits/link-preview/exports.d.ts +7 -0
  265. package/dist/bits/link-preview/exports.js +6 -0
  266. package/dist/bits/link-preview/index.d.ts +1 -7
  267. package/dist/bits/link-preview/index.js +1 -6
  268. package/dist/bits/link-preview/link-preview.svelte.d.ts +4 -3
  269. package/dist/bits/link-preview/link-preview.svelte.js +23 -16
  270. package/dist/bits/link-preview/types.d.ts +6 -6
  271. package/dist/bits/menu/components/menu-arrow.svelte +5 -5
  272. package/dist/bits/menu/components/menu-checkbox-item.svelte +23 -8
  273. package/dist/bits/menu/components/menu-checkbox-item.svelte.d.ts +3 -3
  274. package/dist/bits/menu/components/menu-content-static.svelte +73 -48
  275. package/dist/bits/menu/components/menu-content-static.svelte.d.ts +2 -2
  276. package/dist/bits/menu/components/menu-content.svelte +70 -48
  277. package/dist/bits/menu/components/menu-content.svelte.d.ts +2 -2
  278. package/dist/bits/menu/components/menu-group-heading.svelte +4 -5
  279. package/dist/bits/menu/components/menu-group-heading.svelte.d.ts +2 -2
  280. package/dist/bits/menu/components/menu-group.svelte +4 -5
  281. package/dist/bits/menu/components/menu-group.svelte.d.ts +2 -2
  282. package/dist/bits/menu/components/menu-item.svelte +7 -6
  283. package/dist/bits/menu/components/menu-item.svelte.d.ts +2 -2
  284. package/dist/bits/menu/components/menu-radio-group.svelte +5 -6
  285. package/dist/bits/menu/components/menu-radio-group.svelte.d.ts +2 -2
  286. package/dist/bits/menu/components/menu-radio-item.svelte +7 -6
  287. package/dist/bits/menu/components/menu-radio-item.svelte.d.ts +2 -2
  288. package/dist/bits/menu/components/menu-separator.svelte +4 -5
  289. package/dist/bits/menu/components/menu-separator.svelte.d.ts +2 -2
  290. package/dist/bits/menu/components/menu-sub-content-static.svelte +88 -53
  291. package/dist/bits/menu/components/menu-sub-content-static.svelte.d.ts +2 -2
  292. package/dist/bits/menu/components/menu-sub-content.svelte +82 -51
  293. package/dist/bits/menu/components/menu-sub-content.svelte.d.ts +2 -2
  294. package/dist/bits/menu/components/menu-sub-trigger.svelte +7 -8
  295. package/dist/bits/menu/components/menu-sub-trigger.svelte.d.ts +2 -2
  296. package/dist/bits/menu/components/menu-sub.svelte +6 -6
  297. package/dist/bits/menu/components/menu-sub.svelte.d.ts +1 -2
  298. package/dist/bits/menu/components/menu-trigger.svelte +7 -8
  299. package/dist/bits/menu/components/menu-trigger.svelte.d.ts +2 -2
  300. package/dist/bits/menu/components/menu.svelte +6 -6
  301. package/dist/bits/menu/menu.svelte.d.ts +22 -43
  302. package/dist/bits/menu/menu.svelte.js +94 -134
  303. package/dist/bits/menu/types.d.ts +62 -23
  304. package/dist/bits/menubar/components/menubar-content-static.svelte +4 -5
  305. package/dist/bits/menubar/components/menubar-content-static.svelte.d.ts +2 -2
  306. package/dist/bits/menubar/components/menubar-content.svelte +4 -5
  307. package/dist/bits/menubar/components/menubar-content.svelte.d.ts +2 -2
  308. package/dist/bits/menubar/components/menubar-menu.svelte +3 -3
  309. package/dist/bits/menubar/components/menubar-trigger.svelte +4 -5
  310. package/dist/bits/menubar/components/menubar-trigger.svelte.d.ts +2 -2
  311. package/dist/bits/menubar/components/menubar.svelte +5 -6
  312. package/dist/bits/menubar/components/menubar.svelte.d.ts +2 -2
  313. package/dist/bits/menubar/exports.d.ts +19 -0
  314. package/dist/bits/menubar/exports.js +17 -0
  315. package/dist/bits/menubar/index.d.ts +1 -19
  316. package/dist/bits/menubar/index.js +1 -17
  317. package/dist/bits/menubar/menubar.svelte.d.ts +2 -5
  318. package/dist/bits/menubar/menubar.svelte.js +8 -19
  319. package/dist/bits/menubar/types.d.ts +5 -5
  320. package/dist/bits/navigation-menu/components/navigation-menu-content.svelte +5 -6
  321. package/dist/bits/navigation-menu/components/navigation-menu-content.svelte.d.ts +2 -2
  322. package/dist/bits/navigation-menu/components/navigation-menu-indicator.svelte +4 -5
  323. package/dist/bits/navigation-menu/components/navigation-menu-indicator.svelte.d.ts +2 -2
  324. package/dist/bits/navigation-menu/components/navigation-menu-item.svelte +4 -5
  325. package/dist/bits/navigation-menu/components/navigation-menu-item.svelte.d.ts +2 -2
  326. package/dist/bits/navigation-menu/components/navigation-menu-link.svelte +5 -6
  327. package/dist/bits/navigation-menu/components/navigation-menu-link.svelte.d.ts +2 -2
  328. package/dist/bits/navigation-menu/components/navigation-menu-list.svelte +4 -5
  329. package/dist/bits/navigation-menu/components/navigation-menu-list.svelte.d.ts +2 -2
  330. package/dist/bits/navigation-menu/components/navigation-menu-trigger.svelte +4 -5
  331. package/dist/bits/navigation-menu/components/navigation-menu-trigger.svelte.d.ts +2 -2
  332. package/dist/bits/navigation-menu/components/navigation-menu-viewport.svelte +4 -5
  333. package/dist/bits/navigation-menu/components/navigation-menu-viewport.svelte.d.ts +2 -2
  334. package/dist/bits/navigation-menu/components/navigation-menu.svelte +5 -6
  335. package/dist/bits/navigation-menu/components/navigation-menu.svelte.d.ts +2 -2
  336. package/dist/bits/navigation-menu/exports.d.ts +9 -0
  337. package/dist/bits/navigation-menu/exports.js +8 -0
  338. package/dist/bits/navigation-menu/index.d.ts +1 -9
  339. package/dist/bits/navigation-menu/index.js +1 -8
  340. package/dist/bits/navigation-menu/navigation-menu.svelte.d.ts +4 -14
  341. package/dist/bits/navigation-menu/navigation-menu.svelte.js +21 -57
  342. package/dist/bits/navigation-menu/types.d.ts +11 -12
  343. package/dist/bits/pagination/components/pagination-next-button.svelte +6 -5
  344. package/dist/bits/pagination/components/pagination-next-button.svelte.d.ts +2 -2
  345. package/dist/bits/pagination/components/pagination-page.svelte +6 -5
  346. package/dist/bits/pagination/components/pagination-page.svelte.d.ts +2 -2
  347. package/dist/bits/pagination/components/pagination-prev-button.svelte +6 -5
  348. package/dist/bits/pagination/components/pagination-prev-button.svelte.d.ts +2 -2
  349. package/dist/bits/pagination/components/pagination.svelte +5 -6
  350. package/dist/bits/pagination/components/pagination.svelte.d.ts +3 -3
  351. package/dist/bits/pagination/exports.d.ts +5 -0
  352. package/dist/bits/pagination/exports.js +4 -0
  353. package/dist/bits/pagination/index.d.ts +1 -5
  354. package/dist/bits/pagination/index.js +1 -4
  355. package/dist/bits/pagination/pagination.svelte.d.ts +14 -7
  356. package/dist/bits/pagination/pagination.svelte.js +76 -20
  357. package/dist/bits/pagination/types.d.ts +6 -5
  358. package/dist/bits/pin-input/components/pin-input-cell.svelte +4 -5
  359. package/dist/bits/pin-input/components/pin-input-cell.svelte.d.ts +2 -2
  360. package/dist/bits/pin-input/components/pin-input.svelte +7 -8
  361. package/dist/bits/pin-input/components/pin-input.svelte.d.ts +2 -2
  362. package/dist/bits/pin-input/exports.d.ts +3 -0
  363. package/dist/bits/pin-input/exports.js +2 -0
  364. package/dist/bits/pin-input/index.d.ts +1 -3
  365. package/dist/bits/pin-input/index.js +1 -2
  366. package/dist/bits/pin-input/pin-input.svelte.d.ts +5 -3
  367. package/dist/bits/pin-input/pin-input.svelte.js +58 -10
  368. package/dist/bits/pin-input/types.d.ts +3 -3
  369. package/dist/bits/pin-input/usePasswordManager.svelte.js +6 -6
  370. package/dist/bits/popover/components/popover-arrow.svelte +4 -4
  371. package/dist/bits/popover/components/popover-close.svelte +4 -5
  372. package/dist/bits/popover/components/popover-close.svelte.d.ts +2 -2
  373. package/dist/bits/popover/components/popover-content-static.svelte +73 -35
  374. package/dist/bits/popover/components/popover-content-static.svelte.d.ts +2 -2
  375. package/dist/bits/popover/components/popover-content.svelte +69 -35
  376. package/dist/bits/popover/components/popover-content.svelte.d.ts +2 -2
  377. package/dist/bits/popover/components/popover-trigger.svelte +9 -8
  378. package/dist/bits/popover/components/popover-trigger.svelte.d.ts +2 -2
  379. package/dist/bits/popover/components/popover.svelte +6 -6
  380. package/dist/bits/popover/exports.d.ts +9 -0
  381. package/dist/bits/popover/exports.js +7 -0
  382. package/dist/bits/popover/index.d.ts +1 -9
  383. package/dist/bits/popover/index.js +1 -7
  384. package/dist/bits/popover/popover.svelte.d.ts +12 -7
  385. package/dist/bits/popover/popover.svelte.js +40 -20
  386. package/dist/bits/popover/types.d.ts +8 -8
  387. package/dist/bits/progress/components/progress.svelte +4 -5
  388. package/dist/bits/progress/components/progress.svelte.d.ts +2 -2
  389. package/dist/bits/progress/exports.d.ts +2 -0
  390. package/dist/bits/progress/exports.js +1 -0
  391. package/dist/bits/progress/index.d.ts +1 -2
  392. package/dist/bits/progress/index.js +1 -1
  393. package/dist/bits/progress/progress.svelte.js +1 -1
  394. package/dist/bits/progress/types.d.ts +2 -2
  395. package/dist/bits/radio-group/components/radio-group-item.svelte +4 -5
  396. package/dist/bits/radio-group/components/radio-group-item.svelte.d.ts +2 -2
  397. package/dist/bits/radio-group/components/radio-group.svelte +6 -6
  398. package/dist/bits/radio-group/components/radio-group.svelte.d.ts +2 -2
  399. package/dist/bits/radio-group/exports.d.ts +3 -0
  400. package/dist/bits/radio-group/exports.js +2 -0
  401. package/dist/bits/radio-group/index.d.ts +1 -3
  402. package/dist/bits/radio-group/index.js +1 -2
  403. package/dist/bits/radio-group/radio-group.svelte.d.ts +8 -8
  404. package/dist/bits/radio-group/radio-group.svelte.js +26 -17
  405. package/dist/bits/radio-group/types.d.ts +3 -3
  406. package/dist/bits/range-calendar/components/range-calendar-cell.svelte +4 -5
  407. package/dist/bits/range-calendar/components/range-calendar-cell.svelte.d.ts +2 -2
  408. package/dist/bits/range-calendar/components/range-calendar-day.svelte +10 -5
  409. package/dist/bits/range-calendar/components/range-calendar-day.svelte.d.ts +2 -2
  410. package/dist/bits/range-calendar/components/range-calendar.svelte +6 -9
  411. package/dist/bits/range-calendar/components/range-calendar.svelte.d.ts +2 -2
  412. package/dist/bits/range-calendar/exports.d.ts +13 -0
  413. package/dist/bits/range-calendar/exports.js +12 -0
  414. package/dist/bits/range-calendar/index.d.ts +1 -13
  415. package/dist/bits/range-calendar/index.js +1 -12
  416. package/dist/bits/range-calendar/range-calendar.svelte.d.ts +7 -19
  417. package/dist/bits/range-calendar/range-calendar.svelte.js +32 -49
  418. package/dist/bits/range-calendar/types.d.ts +3 -4
  419. package/dist/bits/scroll-area/components/scroll-area-corner-impl.svelte +3 -4
  420. package/dist/bits/scroll-area/components/scroll-area-corner-impl.svelte.d.ts +2 -2
  421. package/dist/bits/scroll-area/components/scroll-area-corner.svelte +3 -3
  422. package/dist/bits/scroll-area/components/scroll-area-corner.svelte.d.ts +2 -2
  423. package/dist/bits/scroll-area/components/scroll-area-scrollbar-auto.svelte +2 -2
  424. package/dist/bits/scroll-area/components/scroll-area-scrollbar-hover.svelte +2 -2
  425. package/dist/bits/scroll-area/components/scroll-area-scrollbar-scroll.svelte +2 -2
  426. package/dist/bits/scroll-area/components/scroll-area-scrollbar-shared.svelte +1 -1
  427. package/dist/bits/scroll-area/components/scroll-area-scrollbar-x.svelte +2 -3
  428. package/dist/bits/scroll-area/components/scroll-area-scrollbar-y.svelte +2 -3
  429. package/dist/bits/scroll-area/components/scroll-area-scrollbar.svelte +3 -3
  430. package/dist/bits/scroll-area/components/scroll-area-scrollbar.svelte.d.ts +2 -2
  431. package/dist/bits/scroll-area/components/scroll-area-thumb-impl.svelte +3 -4
  432. package/dist/bits/scroll-area/components/scroll-area-thumb-impl.svelte.d.ts +2 -2
  433. package/dist/bits/scroll-area/components/scroll-area-thumb.svelte +4 -4
  434. package/dist/bits/scroll-area/components/scroll-area-thumb.svelte.d.ts +2 -2
  435. package/dist/bits/scroll-area/components/scroll-area-viewport.svelte +18 -5
  436. package/dist/bits/scroll-area/components/scroll-area-viewport.svelte.d.ts +2 -2
  437. package/dist/bits/scroll-area/components/scroll-area.svelte +4 -5
  438. package/dist/bits/scroll-area/components/scroll-area.svelte.d.ts +2 -2
  439. package/dist/bits/scroll-area/exports.d.ts +6 -0
  440. package/dist/bits/scroll-area/exports.js +5 -0
  441. package/dist/bits/scroll-area/index.d.ts +1 -6
  442. package/dist/bits/scroll-area/index.js +1 -5
  443. package/dist/bits/scroll-area/scroll-area.svelte.d.ts +15 -21
  444. package/dist/bits/scroll-area/scroll-area.svelte.js +40 -68
  445. package/dist/bits/scroll-area/types.d.ts +6 -6
  446. package/dist/bits/select/components/select-content-static.svelte +103 -0
  447. package/dist/bits/{listbox/components/listbox-group-label.svelte.d.ts → select/components/select-content-static.svelte.d.ts} +4 -4
  448. package/dist/bits/select/components/select-content.svelte +83 -36
  449. package/dist/bits/select/components/select-content.svelte.d.ts +2 -2
  450. package/dist/bits/select/components/select-group-heading.svelte +7 -8
  451. package/dist/bits/select/components/select-group-heading.svelte.d.ts +2 -2
  452. package/dist/bits/select/components/select-group.svelte +7 -7
  453. package/dist/bits/select/components/select-group.svelte.d.ts +2 -2
  454. package/dist/bits/{listbox/components/listbox-hidden-input.svelte → select/components/select-hidden-input.svelte} +4 -4
  455. package/dist/bits/{listbox/components/listbox-hidden-input.svelte.d.ts → select/components/select-hidden-input.svelte.d.ts} +4 -4
  456. package/dist/bits/select/components/select-item.svelte +24 -13
  457. package/dist/bits/select/components/select-item.svelte.d.ts +2 -2
  458. package/dist/bits/select/components/select-scroll-down-button.svelte +22 -12
  459. package/dist/bits/select/components/select-scroll-down-button.svelte.d.ts +2 -2
  460. package/dist/bits/select/components/select-scroll-up-button.svelte +24 -14
  461. package/dist/bits/select/components/select-scroll-up-button.svelte.d.ts +2 -2
  462. package/dist/bits/select/components/select-trigger.svelte +7 -9
  463. package/dist/bits/select/components/select-trigger.svelte.d.ts +2 -2
  464. package/dist/bits/select/components/select-viewport.svelte +14 -5
  465. package/dist/bits/select/components/select-viewport.svelte.d.ts +2 -2
  466. package/dist/bits/select/components/select.svelte +59 -59
  467. package/dist/bits/select/components/select.svelte.d.ts +1 -1
  468. package/dist/bits/select/exports.d.ts +12 -0
  469. package/dist/bits/select/exports.js +11 -0
  470. package/dist/bits/select/index.d.ts +1 -15
  471. package/dist/bits/select/index.js +1 -14
  472. package/dist/bits/select/select.svelte.d.ts +282 -271
  473. package/dist/bits/select/select.svelte.js +796 -872
  474. package/dist/bits/select/types.d.ts +137 -83
  475. package/dist/bits/separator/components/separator.svelte +4 -5
  476. package/dist/bits/separator/components/separator.svelte.d.ts +2 -2
  477. package/dist/bits/separator/exports.d.ts +2 -0
  478. package/dist/bits/separator/exports.js +1 -0
  479. package/dist/bits/separator/index.d.ts +1 -2
  480. package/dist/bits/separator/index.js +1 -1
  481. package/dist/bits/separator/separator.svelte.js +1 -1
  482. package/dist/bits/separator/types.d.ts +2 -2
  483. package/dist/bits/slider/components/slider-range.svelte +4 -5
  484. package/dist/bits/slider/components/slider-range.svelte.d.ts +2 -2
  485. package/dist/bits/slider/components/slider-thumb.svelte +4 -5
  486. package/dist/bits/slider/components/slider-thumb.svelte.d.ts +2 -2
  487. package/dist/bits/slider/components/slider-tick.svelte +4 -5
  488. package/dist/bits/slider/components/slider-tick.svelte.d.ts +2 -2
  489. package/dist/bits/slider/components/slider.svelte +7 -8
  490. package/dist/bits/slider/components/slider.svelte.d.ts +2 -2
  491. package/dist/bits/slider/exports.d.ts +5 -0
  492. package/dist/bits/slider/exports.js +4 -0
  493. package/dist/bits/slider/index.d.ts +1 -5
  494. package/dist/bits/slider/index.js +1 -4
  495. package/dist/bits/slider/slider.svelte.d.ts +6 -8
  496. package/dist/bits/slider/slider.svelte.js +19 -22
  497. package/dist/bits/slider/types.d.ts +8 -7
  498. package/dist/bits/switch/components/switch-thumb.svelte +4 -5
  499. package/dist/bits/switch/components/switch-thumb.svelte.d.ts +2 -2
  500. package/dist/bits/switch/components/switch.svelte +5 -6
  501. package/dist/bits/switch/components/switch.svelte.d.ts +2 -2
  502. package/dist/bits/switch/exports.d.ts +3 -0
  503. package/dist/bits/switch/exports.js +2 -0
  504. package/dist/bits/switch/index.d.ts +1 -3
  505. package/dist/bits/switch/index.js +1 -2
  506. package/dist/bits/switch/switch.svelte.d.ts +3 -5
  507. package/dist/bits/switch/switch.svelte.js +6 -13
  508. package/dist/bits/switch/types.d.ts +3 -3
  509. package/dist/bits/tabs/components/tabs-content.svelte +4 -5
  510. package/dist/bits/tabs/components/tabs-content.svelte.d.ts +2 -2
  511. package/dist/bits/tabs/components/tabs-list.svelte +4 -5
  512. package/dist/bits/tabs/components/tabs-list.svelte.d.ts +2 -2
  513. package/dist/bits/tabs/components/tabs-trigger.svelte +4 -5
  514. package/dist/bits/tabs/components/tabs-trigger.svelte.d.ts +2 -2
  515. package/dist/bits/tabs/components/tabs.svelte +5 -6
  516. package/dist/bits/tabs/components/tabs.svelte.d.ts +2 -2
  517. package/dist/bits/tabs/exports.d.ts +5 -0
  518. package/dist/bits/tabs/exports.js +4 -0
  519. package/dist/bits/tabs/index.d.ts +1 -5
  520. package/dist/bits/tabs/index.js +1 -4
  521. package/dist/bits/tabs/tabs.svelte.d.ts +6 -8
  522. package/dist/bits/tabs/tabs.svelte.js +17 -24
  523. package/dist/bits/tabs/types.d.ts +5 -5
  524. package/dist/bits/toggle/components/toggle.svelte +5 -6
  525. package/dist/bits/toggle/components/toggle.svelte.d.ts +2 -2
  526. package/dist/bits/toggle/exports.d.ts +2 -0
  527. package/dist/bits/toggle/exports.js +1 -0
  528. package/dist/bits/toggle/index.d.ts +1 -2
  529. package/dist/bits/toggle/index.js +1 -1
  530. package/dist/bits/toggle/toggle.svelte.d.ts +3 -3
  531. package/dist/bits/toggle/toggle.svelte.js +3 -7
  532. package/dist/bits/toggle/types.d.ts +2 -2
  533. package/dist/bits/toggle-group/components/toggle-group-item.svelte +4 -5
  534. package/dist/bits/toggle-group/components/toggle-group-item.svelte.d.ts +2 -2
  535. package/dist/bits/toggle-group/components/toggle-group.svelte +5 -5
  536. package/dist/bits/toggle-group/components/toggle-group.svelte.d.ts +2 -2
  537. package/dist/bits/toggle-group/exports.d.ts +3 -0
  538. package/dist/bits/toggle-group/exports.js +2 -0
  539. package/dist/bits/toggle-group/index.d.ts +1 -3
  540. package/dist/bits/toggle-group/index.js +1 -2
  541. package/dist/bits/toggle-group/toggle-group.svelte.d.ts +5 -5
  542. package/dist/bits/toggle-group/toggle-group.svelte.js +16 -8
  543. package/dist/bits/toggle-group/types.d.ts +5 -5
  544. package/dist/bits/toolbar/components/toolbar-button.svelte +4 -5
  545. package/dist/bits/toolbar/components/toolbar-button.svelte.d.ts +2 -2
  546. package/dist/bits/toolbar/components/toolbar-group-item.svelte +4 -5
  547. package/dist/bits/toolbar/components/toolbar-group.svelte +5 -5
  548. package/dist/bits/toolbar/components/toolbar-group.svelte.d.ts +2 -2
  549. package/dist/bits/toolbar/components/toolbar-link.svelte +4 -5
  550. package/dist/bits/toolbar/components/toolbar-link.svelte.d.ts +2 -2
  551. package/dist/bits/toolbar/components/toolbar.svelte +4 -5
  552. package/dist/bits/toolbar/components/toolbar.svelte.d.ts +2 -2
  553. package/dist/bits/toolbar/exports.d.ts +6 -0
  554. package/dist/bits/toolbar/exports.js +5 -0
  555. package/dist/bits/toolbar/index.d.ts +1 -6
  556. package/dist/bits/toolbar/index.js +1 -5
  557. package/dist/bits/toolbar/toolbar.svelte.d.ts +4 -8
  558. package/dist/bits/toolbar/toolbar.svelte.js +28 -28
  559. package/dist/bits/toolbar/types.d.ts +5 -5
  560. package/dist/bits/tooltip/components/tooltip-arrow.svelte +4 -4
  561. package/dist/bits/tooltip/components/tooltip-content-static.svelte +90 -33
  562. package/dist/bits/tooltip/components/tooltip-content-static.svelte.d.ts +2 -2
  563. package/dist/bits/tooltip/components/tooltip-content.svelte +67 -33
  564. package/dist/bits/tooltip/components/tooltip-content.svelte.d.ts +2 -2
  565. package/dist/bits/tooltip/components/tooltip-provider.svelte +2 -2
  566. package/dist/bits/tooltip/components/tooltip-provider.svelte.d.ts +1 -2
  567. package/dist/bits/tooltip/components/tooltip-trigger.svelte +7 -8
  568. package/dist/bits/tooltip/components/tooltip-trigger.svelte.d.ts +2 -2
  569. package/dist/bits/tooltip/components/tooltip.svelte +9 -9
  570. package/dist/bits/tooltip/components/tooltip.svelte.d.ts +1 -2
  571. package/dist/bits/tooltip/exports.d.ts +9 -0
  572. package/dist/bits/tooltip/exports.js +7 -0
  573. package/dist/bits/tooltip/index.d.ts +1 -9
  574. package/dist/bits/tooltip/index.js +1 -7
  575. package/dist/bits/tooltip/tooltip.svelte.d.ts +12 -10
  576. package/dist/bits/tooltip/tooltip.svelte.js +13 -18
  577. package/dist/bits/tooltip/types.d.ts +7 -7
  578. package/dist/bits/utilities/arrow/arrow.svelte +3 -3
  579. package/dist/bits/utilities/arrow/types.d.ts +2 -2
  580. package/dist/bits/utilities/dismissible-layer/dismissible-layer.svelte +0 -2
  581. package/dist/bits/utilities/dismissible-layer/types.d.ts +3 -14
  582. package/dist/bits/utilities/dismissible-layer/useDismissibleLayer.svelte.js +86 -69
  583. package/dist/bits/utilities/escape-layer/useEscapeLayer.svelte.js +5 -5
  584. package/dist/bits/utilities/floating-layer/components/floating-layer-arrow.svelte +2 -3
  585. package/dist/bits/utilities/floating-layer/components/floating-layer-content.svelte +2 -3
  586. package/dist/bits/utilities/floating-layer/useFloatingLayer.svelte.d.ts +10 -13
  587. package/dist/bits/utilities/floating-layer/useFloatingLayer.svelte.js +10 -22
  588. package/dist/bits/utilities/focus-scope/focus-scope-stack.svelte.js +2 -2
  589. package/dist/bits/utilities/focus-scope/focus-scope.svelte +3 -1
  590. package/dist/bits/utilities/focus-scope/types.d.ts +4 -0
  591. package/dist/bits/utilities/focus-scope/useFocusScope.svelte.d.ts +5 -1
  592. package/dist/bits/utilities/focus-scope/useFocusScope.svelte.js +63 -48
  593. package/dist/bits/utilities/mounted.svelte +1 -1
  594. package/dist/bits/utilities/popper-layer/popper-layer-force-mount.svelte +85 -0
  595. package/dist/bits/{select/components/select-provider.svelte.d.ts → utilities/popper-layer/popper-layer-force-mount.svelte.d.ts} +5 -7
  596. package/dist/bits/utilities/popper-layer/popper-layer-inner.svelte +126 -0
  597. package/dist/bits/{listbox/components/listbox-group.svelte.d.ts → utilities/popper-layer/popper-layer-inner.svelte.d.ts} +7 -5
  598. package/dist/bits/utilities/popper-layer/popper-layer.svelte +23 -67
  599. package/dist/bits/utilities/popper-layer/types.d.ts +2 -2
  600. package/dist/bits/utilities/presence-layer/usePresence.svelte.d.ts +1 -1
  601. package/dist/bits/utilities/presence-layer/usePresence.svelte.js +50 -42
  602. package/dist/bits/utilities/scroll-lock/index.d.ts +10 -0
  603. package/dist/bits/utilities/scroll-lock/scroll-lock.svelte +3 -3
  604. package/dist/bits/utilities/text-selection-layer/useTextSelectionLayer.svelte.js +7 -10
  605. package/dist/bits/utilities/visually-hidden/types.d.ts +2 -2
  606. package/dist/bits/utilities/visually-hidden/visually-hidden.svelte +1 -1
  607. package/dist/internal/arrays.d.ts +23 -0
  608. package/dist/internal/arrays.js +35 -0
  609. package/dist/internal/attrs.d.ts +1 -1
  610. package/dist/internal/attrs.js +3 -3
  611. package/dist/internal/{createEventHook.svelte.js → create-event-hook.svelte.js} +1 -1
  612. package/dist/{shared/date → internal/date-time}/announcer.js +3 -14
  613. package/dist/{shared/date → internal/date-time}/calendar-helpers.svelte.d.ts +3 -6
  614. package/dist/{shared/date → internal/date-time}/calendar-helpers.svelte.js +15 -15
  615. package/dist/{shared/date → internal/date-time}/field/helpers.d.ts +2 -1
  616. package/dist/{shared/date → internal/date-time}/field/helpers.js +15 -15
  617. package/dist/{shared/date/field.js → internal/date-time/field/segments.js} +4 -5
  618. package/dist/{shared/date → internal/date-time}/formatter.d.ts +2 -1
  619. package/dist/{shared/date → internal/date-time}/formatter.js +3 -2
  620. package/dist/{shared/date → internal/date-time}/utils.d.ts +1 -1
  621. package/dist/internal/kbd-constants.d.ts +40 -0
  622. package/dist/internal/kbd-constants.js +40 -0
  623. package/dist/internal/kbd.d.ts +1 -77
  624. package/dist/internal/kbd.js +1 -79
  625. package/dist/internal/should-trap-focus.d.ts +6 -0
  626. package/dist/internal/should-trap-focus.js +6 -0
  627. package/dist/internal/types.d.ts +28 -0
  628. package/dist/internal/{useBodyScrollLock.svelte.d.ts → use-body-scroll-lock.svelte.d.ts} +2 -1
  629. package/dist/internal/use-body-scroll-lock.svelte.js +110 -0
  630. package/dist/internal/use-data-typeahead.svelte.d.ts +12 -0
  631. package/dist/internal/use-data-typeahead.svelte.js +30 -0
  632. package/dist/internal/use-dom-typeahead.svelte.d.ts +11 -0
  633. package/dist/internal/use-dom-typeahead.svelte.js +30 -0
  634. package/dist/internal/use-grace-area.svelte.d.ts +5 -0
  635. package/dist/internal/{useGraceArea.svelte.js → use-grace-area.svelte.js} +11 -13
  636. package/dist/internal/{useRovingFocus.svelte.d.ts → use-roving-focus.svelte.d.ts} +1 -1
  637. package/dist/internal/{useRovingFocus.svelte.js → use-roving-focus.svelte.js} +8 -2
  638. package/dist/internal/{useSize.svelte.d.ts → use-size.svelte.d.ts} +1 -1
  639. package/dist/internal/{useSize.svelte.js → use-size.svelte.js} +1 -1
  640. package/dist/internal/{useTimeoutFn.svelte.js → use-timeout-fn.svelte.js} +1 -2
  641. package/dist/shared/attributes.d.ts +28 -28
  642. package/dist/shared/date/types.d.ts +25 -0
  643. package/dist/shared/index.d.ts +5 -9
  644. package/dist/shared/index.js +3 -2
  645. package/dist/types.d.ts +1 -1
  646. package/package.json +16 -25
  647. package/dist/bits/listbox/components/listbox-content-static.svelte +0 -69
  648. package/dist/bits/listbox/components/listbox-content-static.svelte.d.ts +0 -19
  649. package/dist/bits/listbox/components/listbox-content.svelte +0 -77
  650. package/dist/bits/listbox/components/listbox-content.svelte.d.ts +0 -19
  651. package/dist/bits/listbox/components/listbox-group-label.svelte +0 -33
  652. package/dist/bits/listbox/components/listbox-group.svelte +0 -33
  653. package/dist/bits/listbox/components/listbox-item.svelte +0 -44
  654. package/dist/bits/listbox/components/listbox-item.svelte.d.ts +0 -19
  655. package/dist/bits/listbox/components/listbox-label.svelte +0 -33
  656. package/dist/bits/listbox/components/listbox-label.svelte.d.ts +0 -18
  657. package/dist/bits/listbox/components/listbox-scroll-down-button.svelte +0 -40
  658. package/dist/bits/listbox/components/listbox-scroll-down-button.svelte.d.ts +0 -19
  659. package/dist/bits/listbox/components/listbox-scroll-up-button.svelte +0 -40
  660. package/dist/bits/listbox/components/listbox-scroll-up-button.svelte.d.ts +0 -19
  661. package/dist/bits/listbox/components/listbox-trigger.svelte +0 -36
  662. package/dist/bits/listbox/components/listbox-trigger.svelte.d.ts +0 -19
  663. package/dist/bits/listbox/components/listbox-viewport.svelte +0 -55
  664. package/dist/bits/listbox/components/listbox-viewport.svelte.d.ts +0 -19
  665. package/dist/bits/listbox/components/listbox.svelte +0 -81
  666. package/dist/bits/listbox/components/listbox.svelte.d.ts +0 -18
  667. package/dist/bits/listbox/index.d.ts +0 -13
  668. package/dist/bits/listbox/index.js +0 -12
  669. package/dist/bits/listbox/listbox.svelte.d.ts +0 -414
  670. package/dist/bits/listbox/listbox.svelte.js +0 -1023
  671. package/dist/bits/listbox/types.d.ts +0 -177
  672. package/dist/bits/navigation-menu/components/navigation-menu-sub.svelte +0 -48
  673. package/dist/bits/navigation-menu/components/navigation-menu-sub.svelte.d.ts +0 -18
  674. package/dist/bits/select/components/select-arrow.svelte +0 -22
  675. package/dist/bits/select/components/select-arrow.svelte.d.ts +0 -18
  676. package/dist/bits/select/components/select-content-floating.svelte +0 -73
  677. package/dist/bits/select/components/select-content-floating.svelte.d.ts +0 -34
  678. package/dist/bits/select/components/select-content-impl.svelte +0 -90
  679. package/dist/bits/select/components/select-content-impl.svelte.d.ts +0 -90
  680. package/dist/bits/select/components/select-content-item-aligned.svelte +0 -38
  681. package/dist/bits/select/components/select-content-item-aligned.svelte.d.ts +0 -29
  682. package/dist/bits/select/components/select-icon.svelte +0 -37
  683. package/dist/bits/select/components/select-icon.svelte.d.ts +0 -19
  684. package/dist/bits/select/components/select-item-text.svelte +0 -40
  685. package/dist/bits/select/components/select-item-text.svelte.d.ts +0 -19
  686. package/dist/bits/select/components/select-native.svelte +0 -36
  687. package/dist/bits/select/components/select-native.svelte.d.ts +0 -30
  688. package/dist/bits/select/components/select-provider.svelte +0 -10
  689. package/dist/bits/select/components/select-scroll-down-button-mounted.svelte +0 -33
  690. package/dist/bits/select/components/select-scroll-down-button-mounted.svelte.d.ts +0 -29
  691. package/dist/bits/select/components/select-scroll-up-button-mounted.svelte +0 -33
  692. package/dist/bits/select/components/select-scroll-up-button-mounted.svelte.d.ts +0 -29
  693. package/dist/bits/select/components/select-separator.svelte +0 -33
  694. package/dist/bits/select/components/select-separator.svelte.d.ts +0 -19
  695. package/dist/bits/select/components/select-value.svelte +0 -35
  696. package/dist/bits/select/components/select-value.svelte.d.ts +0 -19
  697. package/dist/internal/afterSleep.d.ts +0 -4
  698. package/dist/internal/afterSleep.js +0 -6
  699. package/dist/internal/afterTick.d.ts +0 -5
  700. package/dist/internal/afterTick.js +0 -7
  701. package/dist/internal/callbacks.d.ts +0 -11
  702. package/dist/internal/callbacks.js +0 -21
  703. package/dist/internal/composeHandlers.d.ts +0 -8
  704. package/dist/internal/composeHandlers.js +0 -21
  705. package/dist/internal/cssToStyleObj.d.ts +0 -2
  706. package/dist/internal/cssToStyleObj.js +0 -23
  707. package/dist/internal/executeCallbacks.d.ts +0 -7
  708. package/dist/internal/executeCallbacks.js +0 -15
  709. package/dist/internal/mergeProps.d.ts +0 -22
  710. package/dist/internal/mergeProps.js +0 -98
  711. package/dist/internal/onDestroyEffect.svelte.d.ts +0 -1
  712. package/dist/internal/onDestroyEffect.svelte.js +0 -7
  713. package/dist/internal/strings.d.ts +0 -3
  714. package/dist/internal/strings.js +0 -70
  715. package/dist/internal/style.d.ts +0 -3
  716. package/dist/internal/style.js +0 -16
  717. package/dist/internal/styleToCSS.d.ts +0 -1
  718. package/dist/internal/styleToCSS.js +0 -23
  719. package/dist/internal/useBodyScrollLock.svelte.js +0 -88
  720. package/dist/internal/useGraceArea.svelte.d.ts +0 -5
  721. package/dist/internal/useRefById.svelte.d.ts +0 -28
  722. package/dist/internal/useRefById.svelte.js +0 -27
  723. package/dist/internal/useTypeahead.svelte.d.ts +0 -34
  724. package/dist/internal/useTypeahead.svelte.js +0 -64
  725. package/dist/shared/date/field/types.js +0 -1
  726. package/dist/shared/date/index.d.ts +0 -7
  727. package/dist/shared/date/index.js +0 -7
  728. /package/dist/bits/menu/{index.d.ts → exports.d.ts} +0 -0
  729. /package/dist/bits/menu/{index.js → exports.js} +0 -0
  730. /package/dist/internal/{boxAutoReset.svelte.d.ts → box-auto-reset.svelte.d.ts} +0 -0
  731. /package/dist/internal/{boxAutoReset.svelte.js → box-auto-reset.svelte.js} +0 -0
  732. /package/dist/internal/{createContext.d.ts → create-context.d.ts} +0 -0
  733. /package/dist/internal/{createContext.js → create-context.js} +0 -0
  734. /package/dist/internal/{createEventHook.svelte.d.ts → create-event-hook.svelte.d.ts} +0 -0
  735. /package/dist/internal/{createSharedHook.svelte.d.ts → create-shared-hook.svelte.d.ts} +0 -0
  736. /package/dist/internal/{createSharedHook.svelte.js → create-shared-hook.svelte.js} +0 -0
  737. /package/dist/{shared/date → internal/date-time}/announcer.d.ts +0 -0
  738. /package/dist/{shared/date → internal/date-time}/field/parts.d.ts +0 -0
  739. /package/dist/{shared/date → internal/date-time}/field/parts.js +0 -0
  740. /package/dist/{shared/date/field.d.ts → internal/date-time/field/segments.d.ts} +0 -0
  741. /package/dist/{shared/date → internal/date-time}/field/types.d.ts +0 -0
  742. /package/dist/{bits/listbox → internal/date-time/field}/types.js +0 -0
  743. /package/dist/{shared/date → internal/date-time}/placeholders.d.ts +0 -0
  744. /package/dist/{shared/date → internal/date-time}/placeholders.js +0 -0
  745. /package/dist/{shared/date → internal/date-time}/utils.js +0 -0
  746. /package/dist/internal/floating-svelte/{useFloating.svelte.d.ts → use-floating.svelte.d.ts} +0 -0
  747. /package/dist/internal/floating-svelte/{useFloating.svelte.js → use-floating.svelte.js} +0 -0
  748. /package/dist/internal/{getDirectionalKeys.d.ts → get-directional-keys.d.ts} +0 -0
  749. /package/dist/internal/{getDirectionalKeys.js → get-directional-keys.js} +0 -0
  750. /package/dist/internal/{useArrowNavigation.d.ts → use-arrow-navigation.d.ts} +0 -0
  751. /package/dist/internal/{useArrowNavigation.js → use-arrow-navigation.js} +0 -0
  752. /package/dist/internal/{useFormControl.svelte.d.ts → use-form-control.svelte.d.ts} +0 -0
  753. /package/dist/internal/{useFormControl.svelte.js → use-form-control.svelte.js} +0 -0
  754. /package/dist/internal/{useId.d.ts → use-id.d.ts} +0 -0
  755. /package/dist/internal/{useId.js → use-id.js} +0 -0
  756. /package/dist/internal/{useResizeObserver.svelte.d.ts → use-resize-observer.svelte.d.ts} +0 -0
  757. /package/dist/internal/{useResizeObserver.svelte.js → use-resize-observer.svelte.js} +0 -0
  758. /package/dist/internal/{useStateMachine.svelte.d.ts → use-state-machine.svelte.d.ts} +0 -0
  759. /package/dist/internal/{useStateMachine.svelte.js → use-state-machine.svelte.js} +0 -0
  760. /package/dist/internal/{useTimeoutFn.svelte.d.ts → use-timeout-fn.svelte.d.ts} +0 -0
@@ -1,153 +1,559 @@
1
- /**
2
- * This logic is adapted from Radix UI's Select component.
3
- * https://github.com/radix-ui/primitives/blob/main/packages/react/select/src/Select.tsx
4
- * Credit to the Radix UI team for the original implementation.
5
- */
6
- import { box } from "svelte-toolbelt";
7
- import { SvelteMap } from "svelte/reactivity";
1
+ import { Previous } from "runed";
8
2
  import { untrack } from "svelte";
9
- import { useId } from "../../internal/useId.js";
10
- import { createContext } from "../../internal/createContext.js";
11
- import { useFormControl } from "../../internal/useFormControl.svelte.js";
12
- import { useRefById } from "../../internal/useRefById.svelte.js";
13
- import { useTypeahead } from "../../internal/useTypeahead.svelte.js";
14
- import { getAriaDisabled, getAriaExpanded, getAriaHidden, getAriaRequired, getAriaSelected, getDataChecked, getDataDisabled, getDataOpenClosed, } from "../../internal/attrs.js";
3
+ import { afterTick, srOnlyStyles, styleToString, useRefById } from "svelte-toolbelt";
4
+ import { backward, forward, next, prev } from "../../internal/arrays.js";
5
+ import { getAriaExpanded, getAriaHidden, getDataDisabled, getDataOpenClosed, getDisabled, getRequired, } from "../../internal/attrs.js";
6
+ import { createContext } from "../../internal/create-context.js";
15
7
  import { kbd } from "../../internal/kbd.js";
16
- import { afterTick } from "../../internal/afterTick.js";
17
- import { clamp } from "../../internal/clamp.js";
18
- import { noop } from "../../internal/callbacks.js";
8
+ import { noop } from "../../internal/noop.js";
19
9
  import { addEventListener } from "../../internal/events.js";
20
- import { sleep } from "../../internal/sleep.js";
21
- import { afterSleep } from "../../internal/afterSleep.js";
22
- export const OPEN_KEYS = [kbd.SPACE, kbd.ENTER, kbd.ARROW_UP, kbd.ARROW_DOWN];
23
- export const SELECTION_KEYS = [" ", kbd.ENTER];
10
+ import { useDOMTypeahead } from "../../internal/use-dom-typeahead.svelte.js";
11
+ import { useDataTypeahead } from "../../internal/use-data-typeahead.svelte.js";
12
+ // prettier-ignore
13
+ export const INTERACTION_KEYS = [kbd.ARROW_LEFT, kbd.ESCAPE, kbd.ARROW_RIGHT, kbd.SHIFT, kbd.CAPS_LOCK, kbd.CONTROL, kbd.ALT, kbd.META, kbd.ENTER, kbd.F1, kbd.F2, kbd.F3, kbd.F4, kbd.F5, kbd.F6, kbd.F7, kbd.F8, kbd.F9, kbd.F10, kbd.F11, kbd.F12];
14
+ export const FIRST_KEYS = [kbd.ARROW_DOWN, kbd.PAGE_UP, kbd.HOME];
15
+ export const LAST_KEYS = [kbd.ARROW_UP, kbd.PAGE_DOWN, kbd.END];
16
+ export const FIRST_LAST_KEYS = [...FIRST_KEYS, ...LAST_KEYS];
17
+ export const SELECTION_KEYS = [kbd.ENTER, kbd.SPACE];
24
18
  export const CONTENT_MARGIN = 10;
25
- const TRIGGER_ATTR = "data-select-trigger";
26
- const CONTENT_ATTR = "data-select-content";
27
- const ITEM_ATTR = "data-select-item";
28
- const VIEWPORT_ATTR = "data-select-viewport";
29
- const VALUE_ATTR = "data-select-value";
30
- const ITEM_TEXT_ATTR = "data-select-item-text";
31
- const CONTENT_WRAPPER_ATTR = "data-select-content-wrapper";
32
- const SCROLL_UP_BUTTON_ATTR = "data-select-scroll-up-button";
33
- const SCROLL_DOWN_BUTTON_ATTR = "data-select-scroll-down-button";
34
- const GROUP_ATTR = "data-select-group";
35
- const GROUP_LABEL_ATTR = "data-select-group-label";
36
- const SEPARATOR_ATTR = "data-select-separator";
37
- const ARROW_ATTR = "data-select-arrow";
38
- const ICON_ATTR = "data-select-icon";
39
- export const [setSelectRootContext, getSelectRootContext] = createContext("Select.Root");
40
- export const [setSelectTriggerContext] = createContext("Select.Trigger");
41
- export const [setSelectContentContext, getSelectContentContext] = createContext("Select.Content");
42
- export const [setSelectItemContext, getSelectItemContext] = createContext("Select.Item");
43
- export const [setSelectContentItemAlignedContext, getSelectContentItemAlignedContext] = createContext("Select.ContentItemAligned");
44
- const [setSelectGroupContext, getSelectGroupContext] = createContext("Select.Group");
45
- export class SelectRootState {
46
- open;
47
- value;
48
- dir;
19
+ class SelectBaseRootState {
49
20
  disabled;
50
21
  required;
51
- triggerNode = $state(null);
52
- valueId = box(useId());
53
- valueNodeHasChildren = box(false);
54
- valueNode = $state(null);
22
+ name;
23
+ loop;
24
+ open;
25
+ scrollAlignment;
26
+ items;
27
+ allowDeselect;
28
+ touchedInput = $state(false);
29
+ inputValue = $state("");
30
+ inputNode = $state(null);
55
31
  contentNode = $state(null);
56
- contentId = $state(undefined);
57
- triggerPointerDownPos = box({ x: 0, y: 0 });
58
- contentFragment = $state(null);
59
- // A set of all the native options we'll use to render the native select element under the hood
60
- #nativeOptionsSet = new SvelteMap();
61
- // A key we'll use to rerender the native select when the options change to keep it in sync
62
- nativeSelectKey = $derived.by(() => {
63
- return Array.from(this.#nativeOptionsSet.values())
64
- .map((opt) => opt.current.value)
65
- .join(";");
32
+ triggerNode = $state(null);
33
+ valueId = $state("");
34
+ highlightedNode = $state(null);
35
+ highlightedValue = $derived.by(() => {
36
+ if (!this.highlightedNode)
37
+ return null;
38
+ return this.highlightedNode.getAttribute("data-value");
39
+ });
40
+ highlightedId = $derived.by(() => {
41
+ if (!this.highlightedNode)
42
+ return undefined;
43
+ return this.highlightedNode.id;
66
44
  });
67
- nativeOptionsArr = $derived.by(() => Array.from(this.#nativeOptionsSet.values()));
68
- isFormControl = useFormControl(() => this.triggerNode);
45
+ highlightedLabel = $derived.by(() => {
46
+ if (!this.highlightedNode)
47
+ return null;
48
+ return this.highlightedNode.getAttribute("data-label");
49
+ });
50
+ isUsingKeyboard = $state(false);
51
+ isCombobox = $state(false);
52
+ bitsAttrs;
53
+ triggerPointerDownPos = $state.raw({ x: 0, y: 0 });
69
54
  constructor(props) {
70
- this.open = props.open;
71
- this.value = props.value;
72
- this.dir = props.dir;
73
55
  this.disabled = props.disabled;
74
56
  this.required = props.required;
57
+ this.name = props.name;
58
+ this.loop = props.loop;
59
+ this.open = props.open;
60
+ this.scrollAlignment = props.scrollAlignment;
61
+ this.isCombobox = props.isCombobox;
62
+ this.items = props.items;
63
+ this.allowDeselect = props.allowDeselect;
64
+ this.bitsAttrs = getSelectBitsAttrs(this);
65
+ $effect.pre(() => {
66
+ if (!this.open.current) {
67
+ this.setHighlightedNode(null);
68
+ }
69
+ });
75
70
  }
76
- handleClose = () => {
77
- this.open.current = false;
78
- this.focusTriggerNode();
71
+ setHighlightedNode = (node) => {
72
+ this.highlightedNode = node;
73
+ if (node) {
74
+ if (this.isUsingKeyboard) {
75
+ node.scrollIntoView({ block: "nearest" });
76
+ }
77
+ }
79
78
  };
80
- focusTriggerNode = (preventScroll = true) => {
81
- const node = this.triggerNode;
79
+ getCandidateNodes = () => {
80
+ const node = this.contentNode;
82
81
  if (!node)
82
+ return [];
83
+ const nodes = Array.from(node.querySelectorAll(`[${this.bitsAttrs.item}]:not([data-disabled])`));
84
+ return nodes;
85
+ };
86
+ setHighlightedToFirstCandidate = () => {
87
+ this.setHighlightedNode(null);
88
+ const candidateNodes = this.getCandidateNodes();
89
+ if (!candidateNodes.length)
83
90
  return;
84
- afterSleep(1, () => {
85
- node.focus({ preventScroll });
86
- });
91
+ this.setHighlightedNode(candidateNodes[0]);
87
92
  };
88
- onNativeOptionAdd = (option) => {
89
- this.#nativeOptionsSet.set(option.current.value, option);
93
+ getNodeByValue = (value) => {
94
+ const candidateNodes = this.getCandidateNodes();
95
+ return candidateNodes.find((node) => node.dataset.value === value) ?? null;
90
96
  };
91
- onNativeOptionRemove = (option) => {
92
- this.#nativeOptionsSet.delete(option.current.value);
97
+ setOpen = (open) => {
98
+ this.open.current = open;
93
99
  };
94
- getTriggerTypeaheadCandidateNodes = () => {
95
- const node = this.contentFragment;
96
- if (!node)
97
- return [];
98
- return Array.from(node.querySelectorAll(`[${ITEM_ATTR}]:not([data-disabled])`));
100
+ toggleOpen = () => {
101
+ this.open.current = !this.open.current;
99
102
  };
100
- getCandidateNodes = () => {
101
- const node = this.contentNode;
102
- if (!node)
103
- return [];
104
- return Array.from(node.querySelectorAll(`[${ITEM_ATTR}]:not([data-disabled])`));
103
+ handleOpen = () => {
104
+ this.setOpen(true);
105
+ };
106
+ handleClose = () => {
107
+ this.setHighlightedNode(null);
108
+ this.setOpen(false);
105
109
  };
106
- createTrigger(props) {
107
- return new SelectTriggerState(props, this);
110
+ toggleMenu = () => {
111
+ this.toggleOpen();
112
+ };
113
+ }
114
+ class SelectSingleRootState extends SelectBaseRootState {
115
+ value;
116
+ isMulti = false;
117
+ hasValue = $derived.by(() => this.value.current !== "");
118
+ currentLabel = $derived.by(() => {
119
+ if (!this.items.current.length)
120
+ return "";
121
+ const match = this.items.current.find((item) => item.value === this.value.current)?.label;
122
+ return match ?? "";
123
+ });
124
+ candidateLabels = $derived.by(() => {
125
+ if (!this.items.current.length)
126
+ return [];
127
+ const filteredItems = this.items.current.filter((item) => !item.disabled);
128
+ return filteredItems.map((item) => item.label);
129
+ });
130
+ dataTypeaheadEnabled = $derived.by(() => {
131
+ if (this.isMulti)
132
+ return false;
133
+ if (this.items.current.length === 0)
134
+ return false;
135
+ return true;
136
+ });
137
+ constructor(props) {
138
+ super(props);
139
+ this.value = props.value;
140
+ $effect(() => {
141
+ if (!this.open.current && this.highlightedNode) {
142
+ this.setHighlightedNode(null);
143
+ }
144
+ });
145
+ $effect(() => {
146
+ if (!this.open.current)
147
+ return;
148
+ afterTick(() => {
149
+ this.setInitialHighlightedNode();
150
+ });
151
+ });
108
152
  }
109
- createValue() {
110
- return new SelectValueState(this);
153
+ includesItem = (itemValue) => {
154
+ return this.value.current === itemValue;
155
+ };
156
+ toggleItem = (itemValue, itemLabel = itemValue) => {
157
+ this.value.current = this.includesItem(itemValue) ? "" : itemValue;
158
+ this.inputValue = itemLabel;
159
+ };
160
+ setInitialHighlightedNode = () => {
161
+ if (this.highlightedNode && document.contains(this.highlightedNode))
162
+ return;
163
+ if (this.value.current !== "") {
164
+ const node = this.getNodeByValue(this.value.current);
165
+ if (node) {
166
+ this.setHighlightedNode(node);
167
+ return;
168
+ }
169
+ }
170
+ // if no value is set, we want to highlight the first item
171
+ const firstCandidate = this.getCandidateNodes()[0];
172
+ if (!firstCandidate)
173
+ return;
174
+ this.setHighlightedNode(firstCandidate);
175
+ };
176
+ }
177
+ class SelectMultipleRootState extends SelectBaseRootState {
178
+ value;
179
+ isMulti = true;
180
+ hasValue = $derived.by(() => this.value.current.length > 0);
181
+ constructor(props) {
182
+ super(props);
183
+ this.value = props.value;
184
+ $effect(() => {
185
+ if (!this.open.current)
186
+ return;
187
+ afterTick(() => {
188
+ if (!this.highlightedNode) {
189
+ this.setInitialHighlightedNode();
190
+ }
191
+ });
192
+ });
111
193
  }
112
- createContent() {
113
- return new SelectContentFragState(this);
194
+ includesItem = (itemValue) => {
195
+ return this.value.current.includes(itemValue);
196
+ };
197
+ toggleItem = (itemValue, itemLabel = itemValue) => {
198
+ if (this.includesItem(itemValue)) {
199
+ this.value.current = this.value.current.filter((v) => v !== itemValue);
200
+ }
201
+ else {
202
+ this.value.current = [...this.value.current, itemValue];
203
+ }
204
+ this.inputValue = itemLabel;
205
+ };
206
+ setInitialHighlightedNode = () => {
207
+ if (this.highlightedNode)
208
+ return;
209
+ if (this.value.current.length && this.value.current[0] !== "") {
210
+ const node = this.getNodeByValue(this.value.current[0]);
211
+ if (node) {
212
+ this.setHighlightedNode(node);
213
+ return;
214
+ }
215
+ }
216
+ // if no value is set, we want to highlight the first item
217
+ const firstCandidate = this.getCandidateNodes()[0];
218
+ if (!firstCandidate)
219
+ return;
220
+ this.setHighlightedNode(firstCandidate);
221
+ };
222
+ }
223
+ class SelectInputState {
224
+ #id;
225
+ #ref;
226
+ root;
227
+ constructor(props, root) {
228
+ this.root = root;
229
+ this.#id = props.id;
230
+ this.#ref = props.ref;
231
+ useRefById({
232
+ id: this.#id,
233
+ ref: this.#ref,
234
+ onRefChange: (node) => {
235
+ this.root.inputNode = node;
236
+ },
237
+ });
114
238
  }
115
- createContentImpl(props) {
116
- return new SelectContentState(props, this);
239
+ #onkeydown = async (e) => {
240
+ this.root.isUsingKeyboard = true;
241
+ if (e.key === kbd.ESCAPE)
242
+ return;
243
+ const open = this.root.open.current;
244
+ const inputValue = this.root.inputValue;
245
+ // prevent arrow up/down from moving the position of the cursor in the input
246
+ if (e.key === kbd.ARROW_UP || e.key === kbd.ARROW_DOWN)
247
+ e.preventDefault();
248
+ if (!open) {
249
+ if (INTERACTION_KEYS.includes(e.key))
250
+ return;
251
+ if (e.key === kbd.TAB)
252
+ return;
253
+ if (e.key === kbd.BACKSPACE && inputValue === "")
254
+ return;
255
+ this.root.handleOpen();
256
+ // we need to wait for a tick after the menu opens to ensure the highlighted nodes are
257
+ // set correctly.
258
+ afterTick(() => {
259
+ if (this.root.hasValue)
260
+ return;
261
+ const candidateNodes = this.root.getCandidateNodes();
262
+ if (!candidateNodes.length)
263
+ return;
264
+ if (e.key === kbd.ARROW_DOWN) {
265
+ const firstCandidate = candidateNodes[0];
266
+ this.root.setHighlightedNode(firstCandidate);
267
+ }
268
+ else if (e.key === kbd.ARROW_UP) {
269
+ const lastCandidate = candidateNodes[candidateNodes.length - 1];
270
+ this.root.setHighlightedNode(lastCandidate);
271
+ }
272
+ });
273
+ return;
274
+ }
275
+ if (e.key === kbd.TAB) {
276
+ this.root.handleClose();
277
+ return;
278
+ }
279
+ if (e.key === kbd.ENTER && !e.isComposing) {
280
+ e.preventDefault();
281
+ const highlightedValue = this.root.highlightedValue;
282
+ const isCurrentSelectedValue = highlightedValue === this.root.value.current;
283
+ if (!this.root.allowDeselect.current && isCurrentSelectedValue && !this.root.isMulti) {
284
+ this.root.handleClose();
285
+ return;
286
+ }
287
+ if (highlightedValue) {
288
+ this.root.toggleItem(highlightedValue, this.root.highlightedLabel ?? undefined);
289
+ }
290
+ if (!this.root.isMulti && !isCurrentSelectedValue) {
291
+ this.root.handleClose();
292
+ }
293
+ }
294
+ if (e.key === kbd.ARROW_UP && e.altKey) {
295
+ this.root.handleClose();
296
+ }
297
+ if (FIRST_LAST_KEYS.includes(e.key)) {
298
+ e.preventDefault();
299
+ const candidateNodes = this.root.getCandidateNodes();
300
+ const currHighlightedNode = this.root.highlightedNode;
301
+ const currIndex = currHighlightedNode
302
+ ? candidateNodes.indexOf(currHighlightedNode)
303
+ : -1;
304
+ const loop = this.root.loop.current;
305
+ let nextItem;
306
+ if (e.key === kbd.ARROW_DOWN) {
307
+ nextItem = next(candidateNodes, currIndex, loop);
308
+ }
309
+ else if (e.key === kbd.ARROW_UP) {
310
+ nextItem = prev(candidateNodes, currIndex, loop);
311
+ }
312
+ else if (e.key === kbd.PAGE_DOWN) {
313
+ nextItem = forward(candidateNodes, currIndex, 10, loop);
314
+ }
315
+ else if (e.key === kbd.PAGE_UP) {
316
+ nextItem = backward(candidateNodes, currIndex, 10, loop);
317
+ }
318
+ else if (e.key === kbd.HOME) {
319
+ nextItem = candidateNodes[0];
320
+ }
321
+ else if (e.key === kbd.END) {
322
+ nextItem = candidateNodes[candidateNodes.length - 1];
323
+ }
324
+ if (!nextItem)
325
+ return;
326
+ this.root.setHighlightedNode(nextItem);
327
+ return;
328
+ }
329
+ if (INTERACTION_KEYS.includes(e.key))
330
+ return;
331
+ if (!this.root.highlightedNode) {
332
+ this.root.setHighlightedToFirstCandidate();
333
+ }
334
+ // this.root.setHighlightedToFirstCandidate();
335
+ };
336
+ #oninput = (e) => {
337
+ this.root.inputValue = e.currentTarget.value;
338
+ afterTick(() => {
339
+ this.root.setHighlightedToFirstCandidate();
340
+ });
341
+ };
342
+ props = $derived.by(() => ({
343
+ id: this.#id.current,
344
+ role: "combobox",
345
+ disabled: this.root.disabled.current ? true : undefined,
346
+ "aria-activedescendant": this.root.highlightedId,
347
+ "aria-autocomplete": "list",
348
+ "aria-expanded": getAriaExpanded(this.root.open.current),
349
+ "data-state": getDataOpenClosed(this.root.open.current),
350
+ "data-disabled": getDataDisabled(this.root.disabled.current),
351
+ onkeydown: this.#onkeydown,
352
+ oninput: this.#oninput,
353
+ [this.root.bitsAttrs.input]: "",
354
+ }));
355
+ }
356
+ class SelectComboTriggerState {
357
+ #id;
358
+ #ref;
359
+ root;
360
+ constructor(props, root) {
361
+ this.root = root;
362
+ this.#id = props.id;
363
+ this.#ref = props.ref;
364
+ useRefById({
365
+ id: this.#id,
366
+ ref: this.#ref,
367
+ });
117
368
  }
369
+ #onkeydown = (e) => {
370
+ if (e.key === kbd.ENTER || e.key === kbd.SPACE) {
371
+ e.preventDefault();
372
+ if (document.activeElement !== this.root.inputNode) {
373
+ this.root.inputNode?.focus();
374
+ }
375
+ this.root.toggleMenu();
376
+ }
377
+ };
378
+ /**
379
+ * `pointerdown` fires before the `focus` event, so we can prevent the default
380
+ * behavior of focusing the button and keep focus on the input.
381
+ */
382
+ #onpointerdown = (e) => {
383
+ if (this.root.disabled.current)
384
+ return;
385
+ e.preventDefault();
386
+ if (document.activeElement !== this.root.inputNode) {
387
+ this.root.inputNode?.focus();
388
+ }
389
+ this.root.toggleMenu();
390
+ };
391
+ props = $derived.by(() => ({
392
+ id: this.#id.current,
393
+ disabled: this.root.disabled.current ? true : undefined,
394
+ "aria-haspopup": "listbox",
395
+ "data-state": getDataOpenClosed(this.root.open.current),
396
+ "data-disabled": getDataDisabled(this.root.disabled.current),
397
+ [this.root.bitsAttrs.trigger]: "",
398
+ onpointerdown: this.#onpointerdown,
399
+ onkeydown: this.#onkeydown,
400
+ }));
118
401
  }
119
402
  class SelectTriggerState {
120
- #root;
121
403
  #id;
122
404
  #ref;
123
- #disabled;
124
- #typeahead;
125
- #isDisabled = $derived.by(() => {
126
- return this.#root.disabled.current || this.#disabled.current;
127
- });
405
+ root;
406
+ #domTypeahead;
407
+ #dataTypeahead;
128
408
  constructor(props, root) {
409
+ this.root = root;
129
410
  this.#id = props.id;
130
411
  this.#ref = props.ref;
131
- this.#root = root;
132
- this.#disabled = props.disabled;
133
412
  useRefById({
134
413
  id: this.#id,
135
414
  ref: this.#ref,
136
415
  onRefChange: (node) => {
137
- this.#root.triggerNode = node;
416
+ this.root.triggerNode = node;
417
+ },
418
+ });
419
+ this.#domTypeahead = useDOMTypeahead({
420
+ getCurrentItem: () => this.root.highlightedNode,
421
+ onMatch: (node) => {
422
+ this.root.setHighlightedNode(node);
423
+ },
424
+ });
425
+ this.#dataTypeahead = useDataTypeahead({
426
+ getCurrentItem: () => {
427
+ if (this.root.isMulti)
428
+ return "";
429
+ return this.root.currentLabel;
138
430
  },
431
+ onMatch: (label) => {
432
+ if (this.root.isMulti)
433
+ return;
434
+ if (!this.root.items.current)
435
+ return;
436
+ const matchedItem = this.root.items.current.find((item) => item.label === label);
437
+ if (!matchedItem)
438
+ return;
439
+ this.root.value.current = matchedItem.value;
440
+ },
441
+ enabled: !this.root.isMulti && this.root.dataTypeaheadEnabled,
139
442
  });
140
- this.#typeahead = useTypeahead();
141
443
  }
142
- #handleOpen = () => {
143
- if (this.#isDisabled)
444
+ #onkeydown = (e) => {
445
+ this.root.isUsingKeyboard = true;
446
+ if (e.key === kbd.ARROW_UP || e.key === kbd.ARROW_DOWN)
447
+ e.preventDefault();
448
+ if (!this.root.open.current) {
449
+ if (e.key === kbd.ENTER ||
450
+ e.key === kbd.SPACE ||
451
+ e.key === kbd.ARROW_DOWN ||
452
+ e.key === kbd.ARROW_UP) {
453
+ e.preventDefault();
454
+ this.root.handleOpen();
455
+ }
456
+ else if (!this.root.isMulti && this.root.dataTypeaheadEnabled) {
457
+ this.#dataTypeahead.handleTypeaheadSearch(e.key, this.root.candidateLabels);
458
+ return;
459
+ }
460
+ // we need to wait for a tick after the menu opens to ensure
461
+ // the highlighted nodes are set correctly
462
+ afterTick(() => {
463
+ if (this.root.hasValue)
464
+ return;
465
+ const candidateNodes = this.root.getCandidateNodes();
466
+ if (!candidateNodes.length)
467
+ return;
468
+ if (e.key === kbd.ARROW_DOWN) {
469
+ const firstCandidate = candidateNodes[0];
470
+ this.root.setHighlightedNode(firstCandidate);
471
+ }
472
+ else if (e.key === kbd.ARROW_UP) {
473
+ const lastCandidate = candidateNodes[candidateNodes.length - 1];
474
+ this.root.setHighlightedNode(lastCandidate);
475
+ }
476
+ });
477
+ return;
478
+ }
479
+ if (e.key === kbd.TAB) {
480
+ this.root.handleClose();
481
+ return;
482
+ }
483
+ if ((e.key === kbd.ENTER || e.key === kbd.SPACE) && !e.isComposing) {
484
+ e.preventDefault();
485
+ const highlightedValue = this.root.highlightedValue;
486
+ const isCurrentSelectedValue = highlightedValue === this.root.value.current;
487
+ if (!this.root.allowDeselect.current && isCurrentSelectedValue && !this.root.isMulti) {
488
+ this.root.handleClose();
489
+ return;
490
+ }
491
+ if (highlightedValue) {
492
+ this.root.toggleItem(highlightedValue, this.root.highlightedLabel ?? undefined);
493
+ }
494
+ if (!this.root.isMulti && !isCurrentSelectedValue) {
495
+ this.root.handleClose();
496
+ }
497
+ }
498
+ if (e.key === kbd.ARROW_UP && e.altKey) {
499
+ this.root.handleClose();
500
+ }
501
+ if (FIRST_LAST_KEYS.includes(e.key)) {
502
+ e.preventDefault();
503
+ const candidateNodes = this.root.getCandidateNodes();
504
+ const currHighlightedNode = this.root.highlightedNode;
505
+ const currIndex = currHighlightedNode
506
+ ? candidateNodes.indexOf(currHighlightedNode)
507
+ : -1;
508
+ const loop = this.root.loop.current;
509
+ let nextItem;
510
+ if (e.key === kbd.ARROW_DOWN) {
511
+ nextItem = next(candidateNodes, currIndex, loop);
512
+ }
513
+ else if (e.key === kbd.ARROW_UP) {
514
+ nextItem = prev(candidateNodes, currIndex, loop);
515
+ }
516
+ else if (e.key === kbd.PAGE_DOWN) {
517
+ nextItem = forward(candidateNodes, currIndex, 10, loop);
518
+ }
519
+ else if (e.key === kbd.PAGE_UP) {
520
+ nextItem = backward(candidateNodes, currIndex, 10, loop);
521
+ }
522
+ else if (e.key === kbd.HOME) {
523
+ nextItem = candidateNodes[0];
524
+ }
525
+ else if (e.key === kbd.END) {
526
+ nextItem = candidateNodes[candidateNodes.length - 1];
527
+ }
528
+ if (!nextItem)
529
+ return;
530
+ this.root.setHighlightedNode(nextItem);
531
+ return;
532
+ }
533
+ const isModifierKey = e.ctrlKey || e.altKey || e.metaKey;
534
+ const isCharacterKey = e.key.length === 1;
535
+ // prevent space from being considered with typeahead
536
+ if (e.code === "Space")
537
+ return;
538
+ const candidateNodes = this.root.getCandidateNodes();
539
+ if (e.key === kbd.TAB)
540
+ return;
541
+ if (!isModifierKey && isCharacterKey) {
542
+ this.#domTypeahead.handleTypeaheadSearch(e.key, candidateNodes);
144
543
  return;
145
- this.#root.open.current = true;
146
- this.#typeahead.resetTypeahead();
544
+ }
545
+ if (!this.root.highlightedNode) {
546
+ this.root.setHighlightedToFirstCandidate();
547
+ }
548
+ };
549
+ #handleOpen = () => {
550
+ this.root.open.current = true;
551
+ this.#dataTypeahead.resetTypeahead();
552
+ this.#domTypeahead.resetTypeahead();
147
553
  };
148
554
  #handlePointerOpen = (e) => {
149
555
  this.#handleOpen();
150
- this.#root.triggerPointerDownPos.current = {
556
+ this.root.triggerPointerDownPos = {
151
557
  x: Math.round(e.pageX),
152
558
  y: Math.round(e.pageY),
153
559
  };
@@ -161,9 +567,14 @@ class SelectTriggerState {
161
567
  const currTarget = e.currentTarget;
162
568
  currTarget.focus();
163
569
  };
570
+ /**
571
+ * `pointerdown` fires before the `focus` event, so we can prevent the default
572
+ * behavior of focusing the button and keep focus on the input.
573
+ */
164
574
  #onpointerdown = (e) => {
165
- // prevent opening on touch down which can be triggered
166
- // when scrolling on touch devices (unexpected)
575
+ if (this.root.disabled.current)
576
+ return;
577
+ // prevent opening on touch down which can be triggered when scrolling on touch devices
167
578
  if (e.pointerType === "touch")
168
579
  return e.preventDefault();
169
580
  // prevent implicit pointer capture
@@ -174,12 +585,12 @@ class SelectTriggerState {
174
585
  // only call the handle if it's a left click, since pointerdown is triggered
175
586
  // by right clicks as well, but not when ctrl is pressed
176
587
  if (e.button === 0 && e.ctrlKey === false) {
177
- if (this.#root.open.current === false) {
588
+ if (this.root.open.current === false) {
178
589
  this.#handlePointerOpen(e);
179
590
  e.preventDefault();
180
591
  }
181
592
  else {
182
- this.#root.handleClose();
593
+ this.root.handleClose();
183
594
  }
184
595
  }
185
596
  };
@@ -189,684 +600,285 @@ class SelectTriggerState {
189
600
  this.#handlePointerOpen(e);
190
601
  }
191
602
  };
192
- #onkeydown = (e) => {
193
- const isTypingAhead = this.#typeahead.search.current !== "";
194
- const isModifierKey = e.ctrlKey || e.altKey || e.metaKey;
195
- if (!isModifierKey && e.key.length === 1) {
196
- if (isTypingAhead && e.key === " ")
197
- return;
198
- }
199
- const newItem = this.#typeahead.handleTypeaheadSearch(e.key, this.#root.getTriggerTypeaheadCandidateNodes());
200
- if (newItem && newItem.dataset.value) {
201
- this.#root.value.current = newItem.dataset.value;
202
- }
203
- if (OPEN_KEYS.includes(e.key)) {
204
- this.#handleOpen();
205
- e.preventDefault();
206
- }
207
- };
208
603
  props = $derived.by(() => ({
209
604
  id: this.#id.current,
210
- disabled: this.#isDisabled,
211
- role: "combobox",
212
- type: "button",
213
- "aria-controls": this.#root.contentId,
214
- "aria-expanded": getAriaExpanded(this.#root.open.current),
215
- "aria-required": getAriaRequired(this.#root.required.current),
216
- "aria-autocomplete": "none",
217
- dir: this.#root.dir.current,
218
- "data-state": getDataOpenClosed(this.#root.open.current),
219
- "data-disabled": getDataDisabled(this.#isDisabled),
220
- "data-placeholder": shouldShowPlaceholder(this.#root.value.current)
221
- ? ""
222
- : undefined,
223
- [TRIGGER_ATTR]: "",
224
- onclick: this.#onclick,
225
- onpointerdown: this.#onpointerdown,
226
- onpointerup: this.#onpointerup,
227
- onkeydown: this.#onkeydown,
228
- }));
229
- }
230
- class SelectValueState {
231
- root;
232
- showPlaceholder = $derived.by(() => shouldShowPlaceholder(this.root.value.current));
233
- ref = box(null);
234
- constructor(root) {
235
- this.root = root;
236
- useRefById({
237
- id: this.root.valueId,
238
- ref: this.ref,
239
- onRefChange: (node) => {
240
- this.root.valueNode = node;
241
- },
242
- });
243
- }
244
- props = $derived.by(() => ({
245
- id: this.root.valueId.current,
605
+ disabled: this.root.disabled.current ? true : undefined,
606
+ "aria-haspopup": "listbox",
246
607
  "data-state": getDataOpenClosed(this.root.open.current),
247
608
  "data-disabled": getDataDisabled(this.root.disabled.current),
248
- [VALUE_ATTR]: "",
249
- style: {
250
- pointerEvents: "none",
251
- },
609
+ "data-placeholder": this.root.hasValue ? undefined : "",
610
+ [this.root.bitsAttrs.trigger]: "",
611
+ onpointerdown: this.#onpointerdown,
612
+ onkeydown: this.#onkeydown,
613
+ onclick: this.#onclick,
614
+ onpointerup: this.#onpointerup,
615
+ // onclick: this.#onclick,
252
616
  }));
253
617
  }
254
- class SelectContentFragState {
255
- root;
256
- constructor(root) {
257
- this.root = root;
258
- $effect(() => {
259
- this.root.contentFragment = new DocumentFragment();
260
- });
261
- }
262
- }
263
- export class SelectContentState {
618
+ class SelectContentState {
264
619
  id;
265
620
  ref;
266
- root;
267
621
  viewportNode = $state(null);
268
- selectedItemId = box(useId());
269
- selectedItemTextId = box(useId());
270
- selectedItemText = box(null);
271
- position;
272
- isPositioned = box(false);
273
- firstValidItemFound = box(false);
274
- typeahead;
275
- alignedPositionState = null;
622
+ root;
623
+ isPositioned = $state(false);
276
624
  constructor(props, root) {
277
- this.position = props.position;
625
+ this.root = root;
278
626
  this.id = props.id;
279
627
  this.ref = props.ref;
280
- this.root = root;
281
- this.typeahead = useTypeahead();
282
628
  useRefById({
283
629
  id: this.id,
284
630
  ref: this.ref,
285
- condition: () => this.root.open.current,
286
631
  onRefChange: (node) => {
287
632
  this.root.contentNode = node;
288
- this.root.contentId = node?.id;
289
633
  },
634
+ deps: () => this.root.open.current,
290
635
  });
291
636
  $effect(() => {
292
- this.root.open.current;
293
- untrack(() => {
294
- let cleanup = [noop];
295
- afterTick(() => {
296
- const node = document.getElementById(this.id.current);
297
- if (!node)
298
- return;
299
- let pointerMoveDelta = { x: 0, y: 0 };
300
- const handlePointerMove = (e) => {
301
- pointerMoveDelta = {
302
- x: Math.abs(Math.round(e.pageX) -
303
- (this.root.triggerPointerDownPos.current?.x ?? 0)),
304
- y: Math.abs(Math.round(e.pageY) -
305
- (this.root.triggerPointerDownPos.current?.y ?? 0)),
306
- };
307
- };
308
- const handlePointerUp = (e) => {
309
- if (e.pointerType === "touch")
310
- return;
311
- if (pointerMoveDelta.x <= 10 && pointerMoveDelta.y <= 10) {
312
- e.preventDefault();
313
- }
314
- else {
315
- if (!this.root.contentNode?.contains(e.target)) {
316
- this.root.handleClose();
317
- }
318
- }
319
- document.removeEventListener("pointermove", handlePointerMove);
320
- this.root.triggerPointerDownPos.current = null;
321
- };
322
- if (this.root.triggerPointerDownPos.current !== null) {
323
- const pointerMove = addEventListener(document, "pointermove", handlePointerMove);
324
- const pointerUp = addEventListener(document, "pointerup", handlePointerUp, {
325
- capture: true,
326
- once: true,
327
- });
328
- for (const cleanupFn of cleanup)
329
- cleanupFn();
330
- cleanup = [pointerMove, pointerUp];
331
- }
332
- return () => {
333
- for (const cleanupFn of cleanup)
334
- cleanupFn();
335
- };
336
- });
337
- });
338
- });
339
- $effect(() => {
340
- if (this.isPositioned.current) {
341
- this.focusSelectedItem();
342
- }
637
+ return () => {
638
+ this.root.contentNode = null;
639
+ };
343
640
  });
344
641
  $effect(() => {
345
642
  if (this.root.open.current === false) {
346
- this.isPositioned.current = false;
643
+ this.isPositioned = false;
347
644
  }
348
645
  });
349
646
  }
350
- focusFirst = (candidates) => {
351
- const [firstItem, ...restItems] = this.root.getCandidateNodes();
352
- const [lastItem] = restItems.slice(-1);
353
- const PREV_FOCUSED_ELEMENT = document.activeElement;
354
- for (const candidate of candidates) {
355
- if (candidate === PREV_FOCUSED_ELEMENT)
356
- return;
357
- candidate?.scrollIntoView({ block: "nearest" });
358
- // viewport might have padding so scroll to the edge when focusing first/last
359
- const viewport = this.viewportNode;
360
- if (candidate === firstItem && viewport) {
361
- viewport.scrollTop = 0;
362
- }
363
- if (candidate === lastItem && viewport) {
364
- viewport.scrollTop = viewport.scrollHeight;
365
- }
366
- candidate?.focus();
367
- if (document.activeElement !== PREV_FOCUSED_ELEMENT)
368
- return;
369
- }
370
- };
371
- onItemLeave = () => {
372
- this.root.contentNode?.focus();
647
+ #onpointermove = () => {
648
+ this.root.isUsingKeyboard = false;
373
649
  };
374
- getSelectedItem = () => {
375
- const candidates = this.root.getCandidateNodes();
376
- const selectedItemNode = candidates.find((node) => node?.dataset.value === this.root.value.current) ?? null;
377
- const first = candidates[0] ?? null;
378
- if (selectedItemNode) {
379
- const selectedItemTextNode = selectedItemNode.querySelector(`[${ITEM_TEXT_ATTR}]`);
650
+ #styles = $derived.by(() => {
651
+ if (this.root.isCombobox) {
380
652
  return {
381
- selectedItemNode,
382
- selectedItemTextNode,
653
+ "--bits-combobox-content-transform-origin": "var(--bits-floating-transform-origin)",
654
+ "--bits-combobox-content-available-width": "var(--bits-floating-available-width)",
655
+ "--bits-combobox-content-available-height": "var(--bits-floating-available-height)",
656
+ "--bits-combobox-anchor-width": "var(--bits-floating-anchor-width)",
657
+ "--bits-combobox-anchor-height": "var(--bits-floating-anchor-height)",
383
658
  };
384
659
  }
385
660
  else {
386
- if (first) {
387
- const firstItemText = first.querySelector(`[${ITEM_TEXT_ATTR}]`);
388
- return {
389
- selectedItemNode: first,
390
- selectedItemTextNode: firstItemText,
391
- };
392
- }
393
- }
394
- return {
395
- selectedItemNode: null,
396
- selectedItemTextNode: null,
397
- };
398
- };
399
- focusSelectedItem = () => {
400
- afterTick(() => {
401
- const candidates = this.root.getCandidateNodes();
402
- const selected = candidates.find((node) => node?.dataset.value === this.root.value.current) ?? null;
403
- const first = candidates[0] ?? null;
404
- this.focusFirst([selected, first]);
405
- });
406
- };
407
- itemRegister = (value, disabled) => {
408
- const isFirstValidItem = !this.firstValidItemFound.current && !disabled;
409
- const isSelectedItem = this.root.value.current !== undefined && this.root.value.current === value;
410
- if (isSelectedItem || isFirstValidItem) {
411
- if (isFirstValidItem) {
412
- this.firstValidItemFound.current = true;
413
- }
414
- }
415
- };
416
- itemTextRegister = (node, value, disabled) => {
417
- const isFirstValidItem = !this.firstValidItemFound.current && !disabled;
418
- const isSelectedItem = this.root.value.current !== undefined && this.root.value.current === value;
419
- if (isSelectedItem || isFirstValidItem) {
420
- this.selectedItemText.current = node;
421
- }
422
- };
423
- #onkeydown = (e) => {
424
- const isModifierKey = e.ctrlKey || e.altKey || e.metaKey;
425
- if (e.key === "Tab")
426
- e.preventDefault();
427
- if (!isModifierKey && e.key.length === 1) {
428
- this.typeahead.handleTypeaheadSearch(e.key, this.root.getCandidateNodes());
661
+ return {
662
+ "--bits-select-content-transform-origin": "var(--bits-floating-transform-origin)",
663
+ "--bits-select-content-available-width": "var(--bits-floating-available-width)",
664
+ "--bits-select-content-available-height": "var(--bits-floating-available-height)",
665
+ "--bits-select-anchor-width": "var(--bits-floating-anchor-width)",
666
+ "--bits-select-anchor-height": "var(--bits-floating-anchor-height)",
667
+ };
429
668
  }
430
- if ([kbd.ARROW_UP, kbd.ARROW_DOWN, kbd.HOME, kbd.END].includes(e.key)) {
431
- let candidateNodes = this.root.getCandidateNodes();
432
- if (e.key === kbd.ARROW_UP || e.key === kbd.END) {
433
- candidateNodes = candidateNodes.slice().reverse();
434
- }
435
- if (e.key === kbd.ARROW_UP || e.key === kbd.ARROW_DOWN) {
436
- const currElement = e.target;
437
- const currIndex = candidateNodes.indexOf(currElement);
438
- candidateNodes = candidateNodes.slice(currIndex + 1);
439
- }
440
- setTimeout(() => this.focusFirst(candidateNodes));
669
+ });
670
+ handleInteractOutside = (e) => {
671
+ if (e.target === this.root.triggerNode || e.target === this.root.inputNode) {
441
672
  e.preventDefault();
442
673
  }
443
674
  };
444
- #oncontextmenu = (e) => {
445
- e.preventDefault();
446
- };
675
+ snippetProps = $derived.by(() => ({ open: this.root.open.current }));
447
676
  props = $derived.by(() => ({
448
677
  id: this.id.current,
449
678
  role: "listbox",
450
679
  "data-state": getDataOpenClosed(this.root.open.current),
680
+ [this.root.bitsAttrs.content]: "",
451
681
  style: {
452
682
  display: "flex",
453
683
  flexDirection: "column",
454
684
  outline: "none",
685
+ boxSizing: "border-box",
686
+ pointerEvents: "auto",
687
+ ...this.#styles,
455
688
  },
456
- oncontextmenu: this.#oncontextmenu,
457
- onkeydown: this.#onkeydown,
458
- tabIndex: -1,
459
- [CONTENT_ATTR]: "",
689
+ onpointermove: this.#onpointermove,
460
690
  }));
461
- createItem(props) {
462
- return new SelectItemState(props, this);
463
- }
464
- createViewport(props) {
465
- return new SelectViewportState(props, this);
466
- }
467
- createItemAlignedPosition(props) {
468
- return new SelectItemAlignedPositionState(props, this);
469
- }
470
- createFloatingPosition() {
471
- return new SelectFloatingPositionState(this);
472
- }
473
- createScrollDownButton(props) {
474
- const state = new SelectScrollButtonImplState(props, this);
475
- return new SelectScrollDownButtonState(state);
476
- }
477
- createScrollUpButton(props) {
478
- const state = new SelectScrollButtonImplState(props, this);
479
- return new SelectScrollUpButtonState(state);
480
- }
481
691
  }
482
692
  class SelectItemState {
483
693
  #id;
484
694
  #ref;
485
695
  root;
486
- content;
487
- textId = box(undefined);
488
696
  value;
697
+ label;
698
+ onHighlight;
699
+ onUnhighlight;
489
700
  disabled;
490
- textValue;
491
- isSelected = $derived.by(() => this.root.value.current === this.value.current);
492
- isFocused = box(false);
493
- node = box(null);
494
- trueTextValue = box("");
495
- constructor(props, content) {
496
- this.#id = props.id;
497
- this.#ref = props.ref;
498
- this.root = content.root;
499
- this.content = content;
701
+ isSelected = $derived.by(() => this.root.includesItem(this.value.current));
702
+ isHighlighted = $derived.by(() => this.root.highlightedValue === this.value.current);
703
+ prevHighlighted = new Previous(() => this.isHighlighted);
704
+ textId = $state("");
705
+ mounted = $state(false);
706
+ constructor(props, root) {
707
+ this.root = root;
500
708
  this.value = props.value;
501
709
  this.disabled = props.disabled;
502
- this.textValue = props.textValue;
503
- useRefById({
504
- id: this.#id,
505
- ref: this.#ref,
506
- });
710
+ this.label = props.label;
711
+ this.onHighlight = props.onHighlight;
712
+ this.onUnhighlight = props.onUnhighlight;
713
+ this.#id = props.id;
714
+ this.#ref = props.ref;
507
715
  $effect(() => {
508
- const node = this.#ref.current;
509
- if (!node)
510
- return;
511
- this.content.itemRegister(this.value.current, this.disabled.current);
716
+ if (this.isHighlighted) {
717
+ this.onHighlight.current();
718
+ }
719
+ else if (this.prevHighlighted.current) {
720
+ this.onUnhighlight.current();
721
+ }
512
722
  });
513
- }
514
- onItemTextChange = (node) => {
515
- this.trueTextValue.current = ((this.textValue?.current || node?.textContent) ?? "").trim();
516
- };
517
- setTextId = (id) => {
518
- this.textId.current = id;
519
- };
520
- handleSelect = async (e) => {
521
- if (e?.defaultPrevented)
522
- return;
523
- if (!this.disabled.current) {
524
- this.root.value.current = this.value.current;
525
- this.root.handleClose();
526
- }
527
- };
528
- #onpointermove = async (e) => {
529
- if (e.defaultPrevented)
530
- return;
531
- if (this.disabled.current) {
532
- this.content.onItemLeave();
533
- }
534
- else {
535
- e.currentTarget.focus({ preventScroll: true });
536
- }
537
- };
538
- #onpointerleave = async (e) => {
539
- if (e.defaultPrevented)
540
- return;
541
- if (e.currentTarget === document.activeElement) {
542
- this.content.onItemLeave();
543
- }
544
- };
723
+ useRefById({
724
+ id: this.#id,
725
+ ref: this.#ref,
726
+ });
727
+ $effect(() => {
728
+ if (!this.mounted)
729
+ return;
730
+ untrack(() => this.root.setInitialHighlightedNode());
731
+ });
732
+ }
733
+ snippetProps = $derived.by(() => ({
734
+ selected: this.isSelected,
735
+ highlighted: this.isHighlighted,
736
+ }));
545
737
  #onpointerdown = (e) => {
546
- e.currentTarget.focus({ preventScroll: true });
547
- };
548
- #onpointerup = async (e) => {
549
- await this.handleSelect(e);
738
+ // prevent focus from leaving the combobox
739
+ e.preventDefault();
550
740
  };
551
- #onkeydown = async (e) => {
741
+ /**
742
+ * Using `pointerup` instead of `click` allows power users to pointerdown
743
+ * the trigger, then release pointerup on an item to select it vs having to do
744
+ * multiple clicks.
745
+ */
746
+ #onpointerup = (e) => {
552
747
  if (e.defaultPrevented)
553
748
  return;
554
- const isTypingAhead = this.content.typeahead.search.current !== "";
555
- if (isTypingAhead && e.key === kbd.SPACE)
749
+ // prevent any default behavior
750
+ e.preventDefault();
751
+ if (this.disabled.current)
752
+ return;
753
+ const isCurrentSelectedValue = this.value.current === this.root.value.current;
754
+ // if allowDeselect is false and the item is already selected and we're not in a
755
+ // multi select, do nothing and close the menu
756
+ if (!this.root.allowDeselect.current && isCurrentSelectedValue && !this.root.isMulti) {
757
+ this.root.handleClose();
556
758
  return;
557
- if (SELECTION_KEYS.includes(e.key)) {
558
- this.handleSelect();
559
759
  }
560
- // prevent page scroll on space
561
- if (e.key === kbd.SPACE)
562
- e.preventDefault();
563
- };
564
- #onfocus = () => {
565
- this.isFocused.current = true;
760
+ // otherwise, toggle the item and if we're not in a multi select, close the menu
761
+ this.root.toggleItem(this.value.current, this.label.current);
762
+ if (!this.root.isMulti && !isCurrentSelectedValue) {
763
+ this.root.handleClose();
764
+ }
566
765
  };
567
- #onblur = () => {
568
- this.isFocused.current = false;
766
+ #onpointermove = (_) => {
767
+ if (this.root.highlightedNode !== this.#ref.current) {
768
+ this.root.setHighlightedNode(this.#ref.current);
769
+ }
569
770
  };
570
- #ontouchend = (e) => {
571
- e.preventDefault();
572
- e.stopPropagation();
771
+ setTextId = (id) => {
772
+ this.textId = id;
573
773
  };
574
774
  props = $derived.by(() => ({
575
775
  id: this.#id.current,
576
776
  role: "option",
577
- "aria-labelledby": this.textId.current ?? undefined,
578
- "data-highlighted": this.isFocused.current ? "" : undefined,
579
- "aria-selected": getAriaSelected(this.isSelected),
580
- "data-state": getDataChecked(this.isSelected),
581
- "aria-disabled": getAriaDisabled(this.disabled.current),
582
- "data-disabled": getDataDisabled(this.disabled.current),
583
- "data-selected": this.isSelected ? "" : undefined,
777
+ "aria-selected": this.root.includesItem(this.value.current) ? "true" : undefined,
584
778
  "data-value": this.value.current,
585
- tabindex: this.disabled.current ? undefined : -1,
586
- [ITEM_ATTR]: "",
587
- //
588
- onfocus: this.#onfocus,
779
+ "data-disabled": getDataDisabled(this.disabled.current),
780
+ "data-highlighted": this.root.highlightedValue === this.value.current ? "" : undefined,
781
+ "data-selected": this.root.includesItem(this.value.current) ? "" : undefined,
782
+ "data-label": this.label.current,
783
+ [this.root.bitsAttrs.item]: "",
589
784
  onpointermove: this.#onpointermove,
590
- onpointerleave: this.#onpointerleave,
591
785
  onpointerdown: this.#onpointerdown,
592
786
  onpointerup: this.#onpointerup,
593
- onkeydown: this.#onkeydown,
594
- onblur: this.#onblur,
595
- ontouchend: this.#ontouchend,
596
787
  }));
597
- createText(props) {
598
- return new SelectItemTextState(props, this);
599
- }
600
788
  }
601
- class SelectItemTextState {
602
- item;
789
+ class SelectGroupState {
603
790
  #id;
604
791
  #ref;
605
- node = box(null);
606
- nativeOption = box.with(() => ({
607
- key: this.item.value.current,
608
- value: this.item.value.current,
609
- disabled: this.item.disabled.current,
610
- innerHTML: this.node.current?.textContent,
611
- }));
612
- constructor(props, item) {
792
+ root;
793
+ labelNode = $state(null);
794
+ constructor(props, root) {
613
795
  this.#id = props.id;
614
796
  this.#ref = props.ref;
615
- this.item = item;
616
- this.item.setTextId(this.#id.current);
797
+ this.root = root;
617
798
  useRefById({
618
799
  id: this.#id,
619
800
  ref: this.#ref,
620
801
  });
621
- $effect(() => {
622
- this.item.setTextId(this.#id.current);
623
- });
624
- $effect(() => {
625
- untrack(() => {
626
- const textNode = this.item.root.contentFragment?.getElementById(this.#id.current);
627
- if (!textNode)
628
- return;
629
- this.item.onItemTextChange(textNode);
630
- this.item.content.itemTextRegister(textNode, this.item.value.current, this.item.disabled.current);
631
- this.item.root.onNativeOptionAdd(box.with(() => ({
632
- key: this.item.value.current,
633
- value: this.item.value.current,
634
- disabled: this.item.disabled.current,
635
- innerHTML: textNode?.textContent,
636
- })));
637
- });
638
- });
639
- $effect(() => {
640
- return () => {
641
- this.item.root.onNativeOptionRemove(this.nativeOption);
642
- };
643
- });
644
802
  }
645
803
  props = $derived.by(() => ({
646
804
  id: this.#id.current,
647
- [ITEM_TEXT_ATTR]: "",
805
+ role: "group",
806
+ [this.root.bitsAttrs.group]: "",
807
+ "aria-labelledby": this.labelNode?.id ?? undefined,
648
808
  }));
649
809
  }
650
- class SelectItemAlignedPositionState {
651
- root;
652
- content;
653
- shouldExpandOnScroll = $state(false);
654
- shouldReposition = $state(false);
655
- contentWrapperId = $state(useId());
656
- onPlaced;
657
- contentZIndex = $state("");
658
- constructor(props, content) {
659
- this.root = content.root;
660
- this.content = content;
661
- this.onPlaced = props.onPlaced;
662
- $effect(() => {
663
- afterTick(() => {
664
- this.position();
665
- const contentNode = document.getElementById(this.content.id.current);
666
- if (contentNode) {
667
- this.contentZIndex = window.getComputedStyle(contentNode).zIndex;
668
- }
669
- });
810
+ class SelectGroupHeadingState {
811
+ #id;
812
+ #ref;
813
+ group;
814
+ constructor(props, group) {
815
+ this.#id = props.id;
816
+ this.#ref = props.ref;
817
+ this.group = group;
818
+ useRefById({
819
+ id: this.#id,
820
+ ref: this.#ref,
821
+ onRefChange: (node) => {
822
+ group.labelNode = node;
823
+ },
670
824
  });
671
825
  }
672
- position = () => {
673
- afterTick(() => {
674
- const { selectedItemNode, selectedItemTextNode } = this.content.getSelectedItem();
675
- const contentNode = this.root.contentNode;
676
- const contentWrapperNode = document.getElementById(this.contentWrapperId);
677
- const viewportNode = this.content.viewportNode;
678
- const triggerNode = this.root.triggerNode;
679
- const valueNode = document.getElementById(this.root.valueId.current);
680
- if (!contentNode ||
681
- !contentWrapperNode ||
682
- !viewportNode ||
683
- !selectedItemNode ||
684
- !selectedItemTextNode ||
685
- !triggerNode ||
686
- !valueNode) {
687
- return;
688
- }
689
- const triggerRect = triggerNode.getBoundingClientRect();
690
- // horizontal positioning
691
- const contentRect = contentNode.getBoundingClientRect();
692
- const valueRect = valueNode.getBoundingClientRect();
693
- const itemTextRect = selectedItemTextNode.getBoundingClientRect();
694
- if (this.root.dir.current === "rtl") {
695
- const itemTextOffset = itemTextRect.left - contentRect.left;
696
- const left = valueRect.left - itemTextOffset;
697
- const leftDelta = triggerRect.left - left;
698
- const minContentWidth = triggerRect.width + leftDelta;
699
- const contentWidth = Math.max(minContentWidth, contentRect.width);
700
- const rightEdge = window.innerWidth - CONTENT_MARGIN;
701
- const clampedLeft = clamp(left, CONTENT_MARGIN, rightEdge - contentWidth);
702
- contentWrapperNode.style.minWidth = `${minContentWidth}px`;
703
- contentWrapperNode.style.left = `${clampedLeft}px`;
704
- }
705
- else {
706
- const itemTextOffset = contentRect.right - itemTextRect.right;
707
- const right = window.innerWidth - valueRect.right - itemTextOffset;
708
- const rightDelta = window.innerWidth - triggerRect.right - right;
709
- const minContentWidth = triggerRect.width + rightDelta;
710
- const contentWidth = Math.max(minContentWidth, contentRect.width);
711
- const leftEdge = window.innerWidth - CONTENT_MARGIN;
712
- const clampedRight = clamp(right, CONTENT_MARGIN, leftEdge - contentWidth);
713
- contentWrapperNode.style.minWidth = `${minContentWidth}px`;
714
- contentWrapperNode.style.right = `${clampedRight}px`;
715
- }
716
- // vertical positioning
717
- const items = this.root.getCandidateNodes();
718
- const availableHeight = window.innerHeight - CONTENT_MARGIN * 2;
719
- const itemsHeight = viewportNode.scrollHeight;
720
- const contentStyles = window.getComputedStyle(contentNode);
721
- const contentBorderTopWidth = Number.parseInt(contentStyles.borderTopWidth, 10);
722
- const contentPaddingTop = Number.parseInt(contentStyles.paddingTop, 10);
723
- const contentBorderBottomWidth = Number.parseInt(contentStyles.borderBottomWidth, 10);
724
- const contentPaddingBottom = Number.parseInt(contentStyles.paddingBottom, 10);
725
- const fullContentHeight = contentBorderTopWidth +
726
- contentPaddingTop +
727
- itemsHeight +
728
- contentPaddingBottom +
729
- contentBorderBottomWidth;
730
- const minContentHeight = Math.min(selectedItemNode.offsetHeight * 5, fullContentHeight);
731
- const viewportStyles = window.getComputedStyle(viewportNode);
732
- const viewportPaddingTop = Number.parseInt(viewportStyles.paddingTop, 10);
733
- const viewportPaddingBottom = Number.parseInt(viewportStyles.paddingBottom, 10);
734
- const topEdgeToTriggerMiddle = triggerRect.top + triggerRect.height / 2 - CONTENT_MARGIN;
735
- const triggerMiddleToBottomEdge = availableHeight - topEdgeToTriggerMiddle;
736
- const selectedItemHalfHeight = selectedItemNode.offsetHeight / 2;
737
- const itemOffsetMiddle = selectedItemNode.offsetTop + selectedItemHalfHeight;
738
- const contentTopToItemMiddle = contentBorderTopWidth + contentPaddingTop + itemOffsetMiddle;
739
- const itemMiddleToContentBottom = fullContentHeight - contentTopToItemMiddle;
740
- const willAlignWithoutTopOverflow = contentTopToItemMiddle <= topEdgeToTriggerMiddle;
741
- if (willAlignWithoutTopOverflow) {
742
- const isLastItem = selectedItemNode === items[items.length - 1];
743
- contentWrapperNode.style.bottom = `${0}px`;
744
- const viewportOffsetBottom = contentNode.clientHeight - viewportNode.offsetTop - viewportNode.offsetHeight;
745
- const clampedTriggerMiddleToBottomEdge = Math.max(triggerMiddleToBottomEdge, selectedItemHalfHeight +
746
- // viewport might have padding bottom, include it to avoid a scrollable viewport
747
- (isLastItem ? viewportPaddingBottom : 0) +
748
- viewportOffsetBottom +
749
- contentBorderBottomWidth);
750
- const height = contentTopToItemMiddle + clampedTriggerMiddleToBottomEdge;
751
- contentWrapperNode.style.height = `${height}px`;
752
- }
753
- else {
754
- const isFirstItem = selectedItemNode === items[0];
755
- contentWrapperNode.style.top = `${0}px`;
756
- const clampedTopEdgeToTriggerMiddle = Math.max(topEdgeToTriggerMiddle, contentBorderTopWidth +
757
- viewportNode.offsetTop +
758
- // viewport might have padding top, include it to avoid a scrollable viewport
759
- (isFirstItem ? viewportPaddingTop : 0) +
760
- selectedItemHalfHeight);
761
- const height = clampedTopEdgeToTriggerMiddle + itemMiddleToContentBottom;
762
- contentWrapperNode.style.height = `${height}px`;
763
- viewportNode.scrollTop =
764
- contentTopToItemMiddle - topEdgeToTriggerMiddle + viewportNode.offsetTop;
765
- }
766
- contentWrapperNode.style.margin = `${CONTENT_MARGIN}px 0`;
767
- contentWrapperNode.style.minHeight = `${minContentHeight}px`;
768
- contentWrapperNode.style.maxHeight = `${availableHeight}px`;
769
- this.onPlaced.current();
770
- });
771
- requestAnimationFrame(() => (this.shouldExpandOnScroll = true));
772
- };
773
- handleScrollButtonChange = (id) => {
774
- afterTick(() => {
775
- const node = document.getElementById(id);
776
- if (!node)
777
- return;
778
- if (!this.shouldReposition)
779
- return;
780
- this.position();
781
- this.content.focusSelectedItem();
782
- this.shouldReposition = false;
783
- });
784
- };
785
- wrapperProps = $derived.by(() => ({
786
- id: this.contentWrapperId,
787
- style: {
788
- display: "flex",
789
- flexDirection: "column",
790
- position: "fixed",
791
- zIndex: this.contentZIndex,
792
- },
793
- [CONTENT_WRAPPER_ATTR]: "",
794
- }));
795
826
  props = $derived.by(() => ({
796
- id: this.content.id.current,
797
- style: {
798
- boxSizing: "border-box",
799
- maxHeight: "100%",
800
- },
827
+ id: this.#id.current,
828
+ [this.group.root.bitsAttrs["group-label"]]: "",
801
829
  }));
802
830
  }
803
- class SelectFloatingPositionState {
831
+ class SelectHiddenInputState {
832
+ #value;
804
833
  root;
805
- content;
806
- constructor(content) {
807
- this.root = content.root;
808
- this.content = content;
834
+ shouldRender = $derived.by(() => this.root.name.current !== "");
835
+ constructor(props, root) {
836
+ this.root = root;
837
+ this.#value = props.value;
809
838
  }
810
- props = {
811
- style: {
812
- boxSizing: "border-box",
813
- "--bits-select-content-transform-origin": "var(--bits-floating-transform-origin)",
814
- "--bits-select-content-available-width": "var(--bits-floating-available-width)",
815
- "--bits-select-content-available-height": "var(--bits-floating-available-height)",
816
- "--bits-select-anchor-width": "var(--bits-floating-anchor-width)",
817
- "--bits-select-anchor-height": "var(--bits-floating-anchor-height)",
818
- },
839
+ #onfocus = (e) => {
840
+ e.preventDefault();
841
+ if (!this.root.isCombobox) {
842
+ this.root.triggerNode?.focus();
843
+ }
844
+ else {
845
+ this.root.inputNode?.focus();
846
+ }
819
847
  };
848
+ props = $derived.by(() => ({
849
+ disabled: getDisabled(this.root.disabled.current),
850
+ required: getRequired(this.root.required.current),
851
+ name: this.root.name.current,
852
+ value: this.#value.current,
853
+ style: styleToString(srOnlyStyles),
854
+ tabindex: -1,
855
+ onfocus: this.#onfocus,
856
+ }));
820
857
  }
821
858
  class SelectViewportState {
822
- id;
823
- ref;
859
+ #id;
860
+ #ref;
861
+ root;
824
862
  content;
825
863
  prevScrollTop = $state(0);
826
864
  constructor(props, content) {
827
- this.id = props.id;
865
+ this.#id = props.id;
866
+ this.#ref = props.ref;
828
867
  this.content = content;
829
- this.ref = props.ref;
868
+ this.root = content.root;
830
869
  useRefById({
831
- id: this.id,
832
- ref: this.ref,
870
+ id: this.#id,
871
+ ref: this.#ref,
833
872
  onRefChange: (node) => {
834
873
  this.content.viewportNode = node;
835
874
  },
836
- condition: () => this.content.root.open.current,
875
+ deps: () => this.root.open.current,
837
876
  });
838
877
  }
839
- #onscroll = (e) => {
840
- afterTick(() => {
841
- const viewport = e.currentTarget;
842
- const shouldExpandOnScroll = this.content.alignedPositionState?.shouldExpandOnScroll ?? undefined;
843
- const contentWrapper = document.getElementById(this.content.alignedPositionState?.contentWrapperId ?? "");
844
- if (shouldExpandOnScroll && contentWrapper) {
845
- const scrolledBy = Math.abs(this.prevScrollTop - viewport.scrollTop);
846
- if (scrolledBy > 0) {
847
- const availableHeight = window.innerHeight - CONTENT_MARGIN * 2;
848
- const cssMinHeight = Number.parseFloat(contentWrapper.style.minHeight);
849
- const cssHeight = Number.parseFloat(contentWrapper.style.height);
850
- const prevHeight = Math.max(cssMinHeight, cssHeight);
851
- if (prevHeight < availableHeight) {
852
- const nextHeight = prevHeight + scrolledBy;
853
- const clampedNextHeight = Math.min(availableHeight, nextHeight);
854
- const heightDiff = nextHeight - clampedNextHeight;
855
- contentWrapper.style.height = `${clampedNextHeight}px`;
856
- if (contentWrapper.style.bottom === "0px") {
857
- viewport.scrollTop = heightDiff > 0 ? heightDiff : 0;
858
- contentWrapper.style.justifyContent = "flex-end";
859
- }
860
- }
861
- }
862
- }
863
- this.prevScrollTop = viewport.scrollTop;
864
- });
865
- };
866
878
  props = $derived.by(() => ({
867
- id: this.id.current,
879
+ id: this.#id.current,
868
880
  role: "presentation",
869
- [VIEWPORT_ATTR]: "",
881
+ [this.root.bitsAttrs.viewport]: "",
870
882
  style: {
871
883
  // we use position: 'relative' here on the `viewport` so that when we call
872
884
  // `selectedItem.offsetTop` in calculations, the offset is relative to the viewport
@@ -875,47 +887,39 @@ class SelectViewportState {
875
887
  flex: 1,
876
888
  overflow: "auto",
877
889
  },
878
- onscroll: this.#onscroll,
879
890
  }));
880
891
  }
881
892
  class SelectScrollButtonImplState {
882
893
  id;
883
894
  ref;
884
895
  content;
885
- alignedPositionState;
896
+ root;
886
897
  autoScrollTimer = $state(null);
887
898
  onAutoScroll = noop;
888
899
  mounted;
889
900
  constructor(props, content) {
890
- this.content = content;
891
901
  this.ref = props.ref;
892
- this.alignedPositionState = content.alignedPositionState;
893
902
  this.id = props.id;
894
903
  this.mounted = props.mounted;
904
+ this.content = content;
905
+ this.root = content.root;
895
906
  useRefById({
896
907
  id: this.id,
897
908
  ref: this.ref,
898
- condition: () => this.mounted.current,
909
+ deps: () => this.mounted.current,
899
910
  });
900
911
  $effect(() => {
901
- if (this.mounted.current) {
902
- const activeItem = this.content.root
903
- .getCandidateNodes()
904
- .find((node) => node === document.activeElement);
905
- activeItem?.scrollIntoView({ block: "nearest" });
906
- }
907
- });
908
- $effect(() => {
909
- return () => {
910
- this.clearAutoScrollTimer();
911
- };
912
+ if (!this.mounted.current)
913
+ return;
914
+ const activeItem = untrack(() => this.root.highlightedNode);
915
+ activeItem?.scrollIntoView({ block: "nearest" });
912
916
  });
913
917
  }
914
918
  clearAutoScrollTimer = () => {
915
- if (this.autoScrollTimer !== null) {
916
- window.clearInterval(this.autoScrollTimer);
917
- this.autoScrollTimer = null;
918
- }
919
+ if (this.autoScrollTimer === null)
920
+ return;
921
+ window.clearInterval(this.autoScrollTimer);
922
+ this.autoScrollTimer = null;
919
923
  };
920
924
  #onpointerdown = () => {
921
925
  if (this.autoScrollTimer !== null)
@@ -925,7 +929,6 @@ class SelectScrollButtonImplState {
925
929
  }, 50);
926
930
  };
927
931
  #onpointermove = () => {
928
- this.content.onItemLeave?.();
929
932
  if (this.autoScrollTimer !== null)
930
933
  return;
931
934
  this.autoScrollTimer = window.setInterval(() => {
@@ -937,7 +940,7 @@ class SelectScrollButtonImplState {
937
940
  };
938
941
  props = $derived.by(() => ({
939
942
  id: this.id.current,
940
- "aria-hidden": "true",
943
+ "aria-hidden": getAriaHidden(true),
941
944
  style: {
942
945
  flexShrink: 0,
943
946
  },
@@ -949,247 +952,168 @@ class SelectScrollButtonImplState {
949
952
  class SelectScrollDownButtonState {
950
953
  state;
951
954
  content;
955
+ root;
952
956
  canScrollDown = $state(false);
953
957
  constructor(state) {
954
958
  this.state = state;
955
959
  this.content = state.content;
960
+ this.root = state.root;
956
961
  this.state.onAutoScroll = this.handleAutoScroll;
957
962
  $effect(() => {
958
963
  const viewport = this.content.viewportNode;
959
- const isPositioned = this.content.isPositioned.current;
964
+ const isPositioned = this.content.isPositioned;
960
965
  if (!viewport || !isPositioned)
961
966
  return;
962
967
  let cleanup = noop;
963
968
  untrack(() => {
964
969
  const handleScroll = () => {
965
- const maxScroll = viewport.scrollHeight - viewport.clientHeight;
966
- this.canScrollDown = Math.ceil(viewport.scrollTop) < maxScroll;
970
+ afterTick(() => {
971
+ const maxScroll = viewport.scrollHeight - viewport.clientHeight;
972
+ const paddingTop = Number.parseInt(getComputedStyle(viewport).paddingTop, 10);
973
+ this.canScrollDown = Math.ceil(viewport.scrollTop) < maxScroll - paddingTop;
974
+ });
967
975
  };
968
976
  handleScroll();
969
977
  cleanup = addEventListener(viewport, "scroll", handleScroll);
970
978
  });
971
- return () => {
972
- cleanup();
973
- };
979
+ return cleanup;
974
980
  });
975
981
  $effect(() => {
976
- if (this.state.mounted.current) {
977
- this.state.alignedPositionState?.handleScrollButtonChange(this.state.id.current);
978
- }
979
- });
980
- $effect(() => {
981
- if (!this.state.mounted.current) {
982
- this.state.clearAutoScrollTimer();
983
- }
982
+ if (this.state.mounted.current)
983
+ return;
984
+ this.state.clearAutoScrollTimer();
984
985
  });
985
986
  }
986
987
  handleAutoScroll = () => {
987
988
  afterTick(() => {
988
989
  const viewport = this.content.viewportNode;
989
- const selectedItem = this.content.getSelectedItem().selectedItemNode;
990
- if (!viewport || !selectedItem) {
990
+ const selectedItem = this.root.highlightedNode;
991
+ if (!viewport || !selectedItem)
991
992
  return;
992
- }
993
993
  viewport.scrollTop = viewport.scrollTop + selectedItem.offsetHeight;
994
994
  });
995
995
  };
996
- props = $derived.by(() => ({ ...this.state.props, [SCROLL_DOWN_BUTTON_ATTR]: "" }));
996
+ props = $derived.by(() => ({ ...this.state.props, [this.root.bitsAttrs["scroll-down-button"]]: "" }));
997
997
  }
998
998
  class SelectScrollUpButtonState {
999
999
  state;
1000
1000
  content;
1001
+ root;
1001
1002
  canScrollUp = $state(false);
1002
1003
  constructor(state) {
1003
1004
  this.state = state;
1004
1005
  this.content = state.content;
1006
+ this.root = state.root;
1005
1007
  this.state.onAutoScroll = this.handleAutoScroll;
1006
1008
  $effect(() => {
1007
- let cleanup = noop;
1008
- cleanup();
1009
1009
  const viewport = this.content.viewportNode;
1010
- const isPositioned = this.content.isPositioned.current;
1010
+ const isPositioned = this.content.isPositioned;
1011
1011
  if (!viewport || !isPositioned)
1012
1012
  return;
1013
- const handleScroll = () => {
1014
- this.canScrollUp = viewport.scrollTop > 0;
1015
- };
1016
- handleScroll();
1017
- cleanup = addEventListener(viewport, "scroll", handleScroll);
1018
- return () => {
1019
- cleanup();
1020
- };
1021
- });
1022
- $effect(() => {
1023
- if (this.state.mounted.current) {
1024
- this.state.alignedPositionState?.handleScrollButtonChange(this.state.id.current);
1025
- }
1013
+ let cleanup = noop;
1014
+ untrack(() => {
1015
+ const handleScroll = () => {
1016
+ const paddingTop = Number.parseInt(getComputedStyle(viewport).paddingTop, 10);
1017
+ this.canScrollUp = viewport.scrollTop - paddingTop > 0;
1018
+ };
1019
+ handleScroll();
1020
+ cleanup = addEventListener(viewport, "scroll", handleScroll);
1021
+ });
1022
+ return cleanup;
1026
1023
  });
1027
1024
  $effect(() => {
1028
- if (!this.state.mounted.current) {
1029
- this.state.clearAutoScrollTimer();
1030
- }
1025
+ if (this.state.mounted.current)
1026
+ return;
1027
+ this.state.clearAutoScrollTimer();
1031
1028
  });
1032
1029
  }
1033
1030
  handleAutoScroll = () => {
1034
1031
  afterTick(() => {
1035
1032
  const viewport = this.content.viewportNode;
1036
- const selectedItem = this.content.getSelectedItem().selectedItemNode;
1033
+ const selectedItem = this.root.highlightedNode;
1037
1034
  if (!viewport || !selectedItem)
1038
1035
  return;
1039
1036
  viewport.scrollTop = viewport.scrollTop - selectedItem.offsetHeight;
1040
1037
  });
1041
1038
  };
1042
- props = $derived.by(() => ({ ...this.state.props, [SCROLL_UP_BUTTON_ATTR]: "" }));
1043
- }
1044
- class SelectGroupState {
1045
- #id;
1046
- #ref;
1047
- labelNode = $state(null);
1048
- constructor(props) {
1049
- this.#id = props.id;
1050
- this.#ref = props.ref;
1051
- useRefById({
1052
- id: this.#id,
1053
- ref: this.#ref,
1054
- });
1055
- }
1056
- props = $derived.by(() => ({
1057
- id: this.#id.current,
1058
- role: "group",
1059
- "aria-labelledby": this.labelNode?.id ?? undefined,
1060
- [GROUP_ATTR]: "",
1061
- }));
1062
- createGroupHeading(props) {
1063
- return new SelectGroupHeading(props, this);
1064
- }
1065
- }
1066
- class SelectGroupHeading {
1067
- #id;
1068
- #ref;
1069
- group;
1070
- constructor(props, group) {
1071
- this.#ref = props.ref;
1072
- this.#id = props.id;
1073
- this.group = group;
1074
- useRefById({
1075
- id: this.#id,
1076
- ref: this.#ref,
1077
- onRefChange: (node) => {
1078
- this.group.labelNode = node;
1079
- },
1080
- });
1081
- }
1082
- props = $derived.by(() => ({
1083
- id: this.#id.current,
1084
- [GROUP_LABEL_ATTR]: "",
1085
- }));
1086
- }
1087
- class SelectSeparatorState {
1088
- #id;
1089
- #ref;
1090
- constructor(props) {
1091
- this.#id = props.id;
1092
- this.#ref = props.ref;
1093
- useRefById({
1094
- id: this.#id,
1095
- ref: this.#ref,
1096
- });
1097
- }
1098
- props = $derived.by(() => ({
1099
- id: this.#id.current,
1100
- [SEPARATOR_ATTR]: "",
1101
- "aria-hidden": getAriaHidden(true),
1102
- }));
1103
- }
1104
- class SelectArrowState {
1105
- #id;
1106
- #ref;
1107
- constructor(props) {
1108
- this.#id = props.id;
1109
- this.#ref = props.ref;
1110
- useRefById({
1111
- id: this.#id,
1112
- ref: this.#ref,
1113
- });
1114
- }
1115
- props = $derived.by(() => ({
1116
- id: this.#id.current,
1117
- [ARROW_ATTR]: "",
1118
- "aria-hidden": getAriaHidden(true),
1119
- }));
1120
- }
1121
- class SelectIconState {
1122
- #id;
1123
- #ref;
1124
- constructor(props) {
1125
- this.#id = props.id;
1126
- this.#ref = props.ref;
1127
- useRefById({
1128
- id: this.#id,
1129
- ref: this.#ref,
1130
- });
1131
- }
1132
- props = $derived.by(() => ({
1133
- id: this.#id.current,
1134
- [ICON_ATTR]: "",
1135
- "aria-hidden": getAriaHidden(true),
1136
- }));
1039
+ props = $derived.by(() => ({ ...this.state.props, [this.root.bitsAttrs["scroll-up-button"]]: "" }));
1137
1040
  }
1041
+ const [setSelectRootContext, getSelectRootContext] = createContext([
1042
+ "Select.Root",
1043
+ "Combobox.Root",
1044
+ ]);
1045
+ const [setSelectGroupContext, getSelectGroupContext] = createContext([
1046
+ "Select.Group",
1047
+ "Combobox.Group",
1048
+ ]);
1049
+ const [setSelectContentContext, getSelectContentContext] = createContext([
1050
+ "Select.Content",
1051
+ "Combobox.Content",
1052
+ ]);
1138
1053
  export function useSelectRoot(props) {
1139
- return setSelectRootContext(new SelectRootState(props));
1054
+ const { type, ...rest } = props;
1055
+ const rootState = type === "single"
1056
+ ? new SelectSingleRootState(rest)
1057
+ : new SelectMultipleRootState(rest);
1058
+ return setSelectRootContext(rootState);
1140
1059
  }
1141
- export function useSelectContentFrag() {
1142
- return getSelectRootContext().createContent();
1060
+ export function useSelectInput(props) {
1061
+ return new SelectInputState(props, getSelectRootContext());
1143
1062
  }
1144
1063
  export function useSelectContent(props) {
1145
- return setSelectContentContext(getSelectRootContext().createContentImpl(props));
1146
- }
1147
- export function useSelectItemAlignedPosition(props) {
1148
- const contentContext = getSelectContentContext();
1149
- const alignedPositionState = contentContext.createItemAlignedPosition(props);
1150
- contentContext.alignedPositionState = alignedPositionState;
1151
- return setSelectContentItemAlignedContext(alignedPositionState);
1152
- }
1153
- export function useSelectFloatingPosition() {
1154
- return getSelectContentContext().createFloatingPosition();
1064
+ return setSelectContentContext(new SelectContentState(props, getSelectRootContext()));
1155
1065
  }
1156
1066
  export function useSelectTrigger(props) {
1157
- return getSelectRootContext().createTrigger(props);
1067
+ return new SelectTriggerState(props, getSelectRootContext());
1158
1068
  }
1159
- export function useSelectValue() {
1160
- return getSelectRootContext().createValue();
1069
+ export function useSelectComboTrigger(props) {
1070
+ return new SelectComboTriggerState(props, getSelectRootContext());
1161
1071
  }
1162
1072
  export function useSelectItem(props) {
1163
- return setSelectItemContext(getSelectContentContext().createItem(props));
1164
- }
1165
- export function useSelectItemText(props) {
1166
- return getSelectItemContext().createText(props);
1073
+ return new SelectItemState(props, getSelectRootContext());
1167
1074
  }
1168
1075
  export function useSelectViewport(props) {
1169
- return getSelectContentContext().createViewport(props);
1076
+ return new SelectViewportState(props, getSelectContentContext());
1170
1077
  }
1171
1078
  export function useSelectScrollUpButton(props) {
1172
- return getSelectContentContext().createScrollUpButton(props);
1079
+ return new SelectScrollUpButtonState(new SelectScrollButtonImplState(props, getSelectContentContext()));
1173
1080
  }
1174
1081
  export function useSelectScrollDownButton(props) {
1175
- return getSelectContentContext().createScrollDownButton(props);
1082
+ return new SelectScrollDownButtonState(new SelectScrollButtonImplState(props, getSelectContentContext()));
1176
1083
  }
1177
1084
  export function useSelectGroup(props) {
1178
- return setSelectGroupContext(new SelectGroupState(props));
1085
+ return setSelectGroupContext(new SelectGroupState(props, getSelectRootContext()));
1179
1086
  }
1180
1087
  export function useSelectGroupHeading(props) {
1181
- return getSelectGroupContext().createGroupHeading(props);
1182
- }
1183
- export function useSelectArrow(props) {
1184
- return new SelectArrowState(props);
1088
+ return new SelectGroupHeadingState(props, getSelectGroupContext());
1185
1089
  }
1186
- export function useSelectSeparator(props) {
1187
- return new SelectSeparatorState(props);
1090
+ export function useSelectHiddenInput(props) {
1091
+ return new SelectHiddenInputState(props, getSelectRootContext());
1188
1092
  }
1189
- export function useSelectIcon(props) {
1190
- return new SelectIconState(props);
1191
- }
1192
- //
1193
- export function shouldShowPlaceholder(value) {
1194
- return value === "" || value === undefined;
1093
+ ////////////////////////////////////
1094
+ // Helpers
1095
+ ////////////////////////////////////
1096
+ const selectParts = [
1097
+ "trigger",
1098
+ "content",
1099
+ "item",
1100
+ "viewport",
1101
+ "scroll-up-button",
1102
+ "scroll-down-button",
1103
+ "group",
1104
+ "group-label",
1105
+ "separator",
1106
+ "arrow",
1107
+ "input",
1108
+ "content-wrapper",
1109
+ "item-text",
1110
+ "value",
1111
+ ];
1112
+ export function getSelectBitsAttrs(root) {
1113
+ const isCombobox = root.isCombobox;
1114
+ const attrObj = {};
1115
+ for (const part of selectParts) {
1116
+ attrObj[part] = isCombobox ? `data-combobox-${part}` : `data-select-${part}`;
1117
+ }
1118
+ return attrObj;
1195
1119
  }