entasis 0.10.2 → 0.12.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (841) hide show
  1. package/README.md +1 -1
  2. package/dist/attachments/disclosurePanel.svelte.d.ts +84 -0
  3. package/dist/attachments/disclosurePanel.svelte.js +277 -0
  4. package/dist/attachments/portal.d.ts +17 -1
  5. package/dist/attachments/portal.js +39 -2
  6. package/dist/attachments/spinnerOverlay.svelte.js +12 -0
  7. package/dist/attachments/transitionSize.d.ts +6 -0
  8. package/dist/attachments/transitionSize.js +30 -0
  9. package/dist/components/AIAskUserQuestion/AIAskUserQuestion.svelte +131 -17
  10. package/dist/components/AIAskUserQuestion/AIAskUserQuestionFileStep.svelte +26 -6
  11. package/dist/components/AIAskUserQuestion/AIAskUserQuestionFileStep.svelte.d.ts +6 -0
  12. package/dist/components/AIAskUserQuestion/AIAskUserQuestionFooter.svelte +27 -53
  13. package/dist/components/AIAskUserQuestion/AIAskUserQuestionFooter.svelte.d.ts +3 -4
  14. package/dist/components/AIAskUserQuestion/AIAskUserQuestionHeader.svelte +19 -16
  15. package/dist/components/AIAskUserQuestion/AIAskUserQuestionStep.svelte +180 -21
  16. package/dist/components/AIAskUserQuestion/AIAskUserQuestionStep.svelte.d.ts +9 -1
  17. package/dist/components/AIAskUserQuestion/AIAskUserQuestionSummary.svelte +56 -0
  18. package/dist/components/AIAskUserQuestion/AIAskUserQuestionSummary.svelte.d.ts +4 -0
  19. package/dist/components/AIAskUserQuestion/aiAskUserQuestion.mcp.d.ts +1 -1
  20. package/dist/components/AIAskUserQuestion/aiAskUserQuestion.mcp.js +26 -8
  21. package/dist/components/AIAskUserQuestion/aiAskUserQuestion.props.d.ts +62 -5
  22. package/dist/components/AIAskUserQuestion/aiAskUserQuestion.theme.d.ts +42 -0
  23. package/dist/components/AIAskUserQuestion/aiAskUserQuestion.theme.js +53 -12
  24. package/dist/components/AIAskUserQuestion/aiAskUserQuestionAnswers.d.ts +17 -1
  25. package/dist/components/AIAskUserQuestion/aiAskUserQuestionAnswers.js +56 -8
  26. package/dist/components/AIAskUserQuestion/index.d.ts +3 -1
  27. package/dist/components/AIAskUserQuestion/index.js +2 -0
  28. package/dist/components/AIAskUserQuestion/schemas.d.ts +44 -0
  29. package/dist/components/AIAskUserQuestion/schemas.js +10 -3
  30. package/dist/components/AIChat/AIChat.svelte +10 -0
  31. package/dist/components/AIChat/AIChat.svelte.d.ts +2 -2
  32. package/dist/components/AIChat/AIChatComposerSurface.svelte +23 -5
  33. package/dist/components/AIChat/AIChatComposerSurface.svelte.d.ts +5 -0
  34. package/dist/components/AIChat/AIChatSkeleton.svelte +29 -37
  35. package/dist/components/AIChat/AIChatSurface.svelte +30 -2
  36. package/dist/components/AIChat/AIChatSurface.svelte.d.ts +1 -1
  37. package/dist/components/AIChat/AIChatThreadSurface.svelte +11 -1
  38. package/dist/components/AIChat/AIChatThreadSurface.svelte.d.ts +3 -1
  39. package/dist/components/AIChat/aiChat.mcp.d.ts +1 -1
  40. package/dist/components/AIChat/aiChat.mcp.js +31 -15
  41. package/dist/components/AIChat/aiChat.props.d.ts +36 -10
  42. package/dist/components/AIChat/aiChat.theme.d.ts +9 -0
  43. package/dist/components/AIChat/aiChat.theme.js +21 -4
  44. package/dist/components/AIChat/aiChatSkeleton.props.d.ts +5 -0
  45. package/dist/components/AIChat/index.d.ts +1 -1
  46. package/dist/components/AIComposer/AIComposer.svelte +102 -5
  47. package/dist/components/AIComposer/AIComposer.svelte.d.ts +1 -0
  48. package/dist/components/AIComposer/AIComposerFooter.svelte +54 -12
  49. package/dist/components/AIComposer/AIComposerFooter.svelte.d.ts +2 -0
  50. package/dist/components/AIComposer/AIComposerQueue.svelte +8 -3
  51. package/dist/components/AIComposer/aiComposer.editor.theme.js +13 -2
  52. package/dist/components/AIComposer/aiComposer.mcp.d.ts +1 -1
  53. package/dist/components/AIComposer/aiComposer.mcp.js +15 -7
  54. package/dist/components/AIComposer/aiComposer.props.d.ts +27 -7
  55. package/dist/components/AIComposer/aiComposer.theme.d.ts +42 -3
  56. package/dist/components/AIComposer/aiComposer.theme.js +37 -5
  57. package/dist/components/AIComposer/aiComposerFileController.svelte.d.ts +20 -0
  58. package/dist/components/AIComposer/aiComposerFileController.svelte.js +75 -9
  59. package/dist/components/AIComposer/aiComposerSourceAdapter.js +22 -4
  60. package/dist/components/AIComposer/aiComposerSubmitController.svelte.d.ts +12 -0
  61. package/dist/components/AIComposer/aiComposerSubmitController.svelte.js +16 -6
  62. package/dist/components/AIContext/AIContext.svelte +7 -3
  63. package/dist/components/AIContext/aiContext.mcp.d.ts +1 -1
  64. package/dist/components/AIContext/aiContext.mcp.js +1 -1
  65. package/dist/components/AIContext/aiContext.props.d.ts +4 -1
  66. package/dist/components/AIContext/aiContext.theme.d.ts +3 -0
  67. package/dist/components/AIContext/aiContext.theme.js +7 -2
  68. package/dist/components/AIConversation/AIConversation.svelte.d.ts +2 -2
  69. package/dist/components/AIFilePreview/aiFilePreview.theme.js +1 -1
  70. package/dist/components/AIMarker/AIMarker.svelte +2 -0
  71. package/dist/components/AIMarker/aiMarker.mcp.d.ts +1 -1
  72. package/dist/components/AIMarker/aiMarker.mcp.js +2 -0
  73. package/dist/components/AIMarker/aiMarker.props.d.ts +3 -0
  74. package/dist/components/AIMarker/aiMarker.theme.js +2 -2
  75. package/dist/components/AIMessage/AIMessage.svelte +38 -16
  76. package/dist/components/AIMessage/aiMessage.mcp.d.ts +1 -1
  77. package/dist/components/AIMessage/aiMessage.mcp.js +20 -6
  78. package/dist/components/AIMessage/aiMessage.props.d.ts +18 -2
  79. package/dist/components/AIMessage/aiMessage.theme.d.ts +51 -6
  80. package/dist/components/AIMessage/aiMessage.theme.js +91 -32
  81. package/dist/components/AIMessageActions/AIMessageActions.svelte +19 -9
  82. package/dist/components/AIMessageActions/aiMessageActions.mcp.d.ts +1 -1
  83. package/dist/components/AIMessageActions/aiMessageActions.mcp.js +11 -3
  84. package/dist/components/AIMessageActions/aiMessageActions.theme.js +36 -9
  85. package/dist/components/AIModelSelector/AIModelSelector.svelte +25 -10
  86. package/dist/components/AIModelSelector/aiModelSelector.mcp.d.ts +1 -1
  87. package/dist/components/AIModelSelector/aiModelSelector.mcp.js +1 -1
  88. package/dist/components/AIModelSelector/aiModelSelector.theme.d.ts +3 -0
  89. package/dist/components/AIModelSelector/aiModelSelector.theme.js +7 -3
  90. package/dist/components/AIReasoning/AIReasoning.svelte +135 -38
  91. package/dist/components/AIReasoning/aiReasoning.mcp.d.ts +1 -1
  92. package/dist/components/AIReasoning/aiReasoning.mcp.js +11 -5
  93. package/dist/components/AIReasoning/aiReasoning.props.d.ts +15 -4
  94. package/dist/components/AIReasoning/aiReasoning.theme.d.ts +45 -0
  95. package/dist/components/AIReasoning/aiReasoning.theme.js +47 -7
  96. package/dist/components/AISuggestion/AISuggestion.svelte +2 -1
  97. package/dist/components/AISuggestion/AISuggestions.svelte +2 -1
  98. package/dist/components/AISuggestion/aiSuggestion.mcp.d.ts +1 -1
  99. package/dist/components/AISuggestion/aiSuggestion.mcp.js +8 -1
  100. package/dist/components/AISuggestion/aiSuggestion.props.d.ts +4 -1
  101. package/dist/components/AISuggestion/aiSuggestion.theme.js +1 -1
  102. package/dist/components/AISuggestion/aiSuggestions.props.d.ts +7 -0
  103. package/dist/components/AIThread/AIThread.svelte +378 -95
  104. package/dist/components/AIThread/AIThreadAskUserQuestion.svelte +1 -0
  105. package/dist/components/AIThread/AIThreadItems.svelte +266 -64
  106. package/dist/components/AIThread/AIThreadItems.svelte.d.ts +7 -3
  107. package/dist/components/AIThread/AIThreadMarker.svelte +8 -1
  108. package/dist/components/AIThread/AIThreadMarker.svelte.d.ts +1 -0
  109. package/dist/components/AIThread/aiThread.mcp.d.ts +1 -1
  110. package/dist/components/AIThread/aiThread.mcp.js +34 -20
  111. package/dist/components/AIThread/aiThread.props.d.ts +73 -8
  112. package/dist/components/AIThread/aiThread.theme.d.ts +78 -0
  113. package/dist/components/AIThread/aiThread.theme.js +108 -9
  114. package/dist/components/AIThread/index.d.ts +1 -1
  115. package/dist/components/AIThread/threadAskUserQuestion.d.ts +4 -1
  116. package/dist/components/AIThread/threadAskUserQuestion.js +8 -4
  117. package/dist/components/AIThread/threadRenderItems.d.ts +74 -3
  118. package/dist/components/AIThread/threadRenderItems.js +265 -77
  119. package/dist/components/AIThread/threadScrollController.d.ts +0 -8
  120. package/dist/components/AIThread/threadScrollController.js +2 -39
  121. package/dist/components/AIThread/threadTools.d.ts +11 -0
  122. package/dist/components/AIThread/threadTools.js +79 -0
  123. package/dist/components/AIThreadToc/AIThreadToc.svelte +188 -18
  124. package/dist/components/AIThreadToc/AIThreadTocPreview.svelte +25 -2
  125. package/dist/components/AIThreadToc/AIThreadTocPreview.svelte.d.ts +3 -0
  126. package/dist/components/AIThreadToc/aiThreadToc.d.ts +4 -2
  127. package/dist/components/AIThreadToc/aiThreadToc.js +17 -5
  128. package/dist/components/AIThreadToc/aiThreadToc.mcp.d.ts +1 -1
  129. package/dist/components/AIThreadToc/aiThreadToc.mcp.js +13 -3
  130. package/dist/components/AIThreadToc/aiThreadToc.props.d.ts +11 -0
  131. package/dist/components/AIThreadToc/aiThreadToc.theme.d.ts +3 -0
  132. package/dist/components/AIThreadToc/aiThreadToc.theme.js +15 -6
  133. package/dist/components/AITool/AITool.svelte +56 -21
  134. package/dist/components/AITool/AIToolCallList.svelte +79 -29
  135. package/dist/components/AITool/AIToolCallList.svelte.d.ts +6 -2
  136. package/dist/components/AITool/AIToolStatusMark.svelte +52 -0
  137. package/dist/components/AITool/AIToolStatusMark.svelte.d.ts +14 -0
  138. package/dist/components/AITool/AIToolValueSection.svelte +126 -28
  139. package/dist/components/AITool/AIToolValueSection.svelte.d.ts +6 -2
  140. package/dist/components/AITool/AIToolValueTree.svelte +11 -16
  141. package/dist/components/AITool/AIToolValueTree.svelte.d.ts +2 -3
  142. package/dist/components/AITool/aiTool.mcp.d.ts +1 -1
  143. package/dist/components/AITool/aiTool.mcp.js +36 -8
  144. package/dist/components/AITool/aiTool.props.d.ts +52 -6
  145. package/dist/components/AITool/aiTool.theme.d.ts +117 -39
  146. package/dist/components/AITool/aiTool.theme.js +144 -140
  147. package/dist/components/AITool/aiToolClock.svelte.d.ts +18 -0
  148. package/dist/components/AITool/aiToolClock.svelte.js +62 -0
  149. package/dist/components/AITool/aiToolPrimitiveThemes.d.ts +0 -2
  150. package/dist/components/AITool/aiToolPrimitiveThemes.js +0 -10
  151. package/dist/components/AITool/index.d.ts +2 -1
  152. package/dist/components/AITool/index.js +1 -0
  153. package/dist/components/AITool/toolRendering.d.ts +33 -1
  154. package/dist/components/AITool/toolRendering.js +179 -15
  155. package/dist/components/AITool/toolValueTree.d.ts +14 -1
  156. package/dist/components/AITool/toolValueTree.js +126 -27
  157. package/dist/components/Accordion/Accordion.svelte +109 -109
  158. package/dist/components/Accordion/Accordion.svelte.d.ts +0 -1
  159. package/dist/components/Accordion/AccordionPanel.svelte +64 -0
  160. package/dist/components/Accordion/AccordionPanel.svelte.d.ts +20 -0
  161. package/dist/components/Accordion/accordion.attributes.d.ts +24 -0
  162. package/dist/components/Accordion/accordion.attributes.js +20 -0
  163. package/dist/components/Accordion/accordion.mcp.d.ts +1 -1
  164. package/dist/components/Accordion/accordion.mcp.js +78 -22
  165. package/dist/components/Accordion/accordion.props.d.ts +54 -10
  166. package/dist/components/Accordion/accordion.theme.d.ts +3 -0
  167. package/dist/components/Accordion/accordion.theme.js +4 -0
  168. package/dist/components/Accordion/index.d.ts +1 -0
  169. package/dist/components/Accordion/index.js +1 -0
  170. package/dist/components/AudioPlayer/audioPlayerVolumeControl.slider.theme.d.ts +31 -1
  171. package/dist/components/Avatar/Avatar.svelte +60 -10
  172. package/dist/components/Avatar/AvatarGroup.svelte +9 -0
  173. package/dist/components/Avatar/avatar.mcp.d.ts +1 -1
  174. package/dist/components/Avatar/avatar.mcp.js +13 -5
  175. package/dist/components/Avatar/avatar.props.d.ts +28 -1
  176. package/dist/components/Avatar/avatar.theme.js +3 -3
  177. package/dist/components/Avatar/index.d.ts +1 -1
  178. package/dist/components/Breadcrumbs/breadcrumbs.mcp.d.ts +1 -1
  179. package/dist/components/Breadcrumbs/breadcrumbs.mcp.js +1 -1
  180. package/dist/components/Button/Button.svelte +35 -15
  181. package/dist/components/Button/button.mcp.d.ts +1 -1
  182. package/dist/components/Button/button.mcp.js +8 -4
  183. package/dist/components/Button/button.props.d.ts +23 -8
  184. package/dist/components/Button/button.theme.d.ts +12 -0
  185. package/dist/components/Button/button.theme.js +17 -4
  186. package/dist/components/ButtonGroup/buttonGroup.mcp.d.ts +1 -1
  187. package/dist/components/ButtonGroup/buttonGroup.mcp.js +1 -1
  188. package/dist/components/ButtonGroup/buttonGroup.props.d.ts +4 -1
  189. package/dist/components/Collapsible/Collapsible.svelte +125 -19
  190. package/dist/components/Collapsible/collapsible.attributes.d.ts +21 -0
  191. package/dist/components/Collapsible/collapsible.attributes.js +17 -0
  192. package/dist/components/Collapsible/collapsible.mcp.d.ts +1 -1
  193. package/dist/components/Collapsible/collapsible.mcp.js +62 -12
  194. package/dist/components/Collapsible/collapsible.props.d.ts +39 -8
  195. package/dist/components/Collapsible/collapsible.theme.js +3 -1
  196. package/dist/components/Collapsible/index.d.ts +1 -0
  197. package/dist/components/Collapsible/index.js +1 -0
  198. package/dist/components/Command/Command.svelte +56 -14
  199. package/dist/components/Command/command.mcp.d.ts +1 -1
  200. package/dist/components/Command/command.mcp.js +12 -6
  201. package/dist/components/Command/command.props.d.ts +39 -6
  202. package/dist/components/Command/command.state.svelte.d.ts +40 -11
  203. package/dist/components/Command/command.state.svelte.js +75 -28
  204. package/dist/components/Command/command.theme.js +4 -3
  205. package/dist/components/Confirmation/Confirmation.svelte +72 -31
  206. package/dist/components/Confirmation/confirmation.mcp.d.ts +1 -1
  207. package/dist/components/Confirmation/confirmation.mcp.js +5 -4
  208. package/dist/components/ContextMenu/ContextMenu.svelte +126 -16
  209. package/dist/components/ContextMenu/contextMenu.mcp.d.ts +1 -1
  210. package/dist/components/ContextMenu/contextMenu.mcp.js +10 -7
  211. package/dist/components/ContextMenu/contextMenu.props.d.ts +13 -4
  212. package/dist/components/ContextMenu/contextMenu.theme.d.ts +3 -3
  213. package/dist/components/ContextMenu/contextMenu.theme.js +3 -2
  214. package/dist/components/DataTable/DataTable.svelte +4 -9
  215. package/dist/components/DataTable/DataTableEditor.svelte +5 -0
  216. package/dist/components/DataTable/DataTableFilter.svelte +1 -0
  217. package/dist/components/DataTable/DataTableToolbar.svelte +1 -0
  218. package/dist/components/DataTable/dataTable.mcp.d.ts +1 -1
  219. package/dist/components/DataTable/dataTable.mcp.js +4 -2
  220. package/dist/components/DataTable/dataTable.theme.d.ts +0 -3
  221. package/dist/components/DataTable/dataTable.theme.js +9 -6
  222. package/dist/components/Dialog/Dialog.svelte +120 -35
  223. package/dist/components/Dialog/Dialog.svelte.d.ts +1 -1
  224. package/dist/components/Dialog/DialogBackdrop.svelte +21 -1
  225. package/dist/components/Dialog/dialog.api.d.ts +65 -0
  226. package/dist/components/Dialog/dialog.api.js +1 -0
  227. package/dist/components/Dialog/dialog.attributes.d.ts +23 -0
  228. package/dist/components/Dialog/dialog.attributes.js +19 -0
  229. package/dist/components/Dialog/dialog.indent.d.ts +6 -0
  230. package/dist/components/Dialog/dialog.indent.js +16 -0
  231. package/dist/components/Dialog/dialog.mcp.d.ts +1 -1
  232. package/dist/components/Dialog/dialog.mcp.js +195 -22
  233. package/dist/components/Dialog/dialog.props.d.ts +102 -19
  234. package/dist/components/Dialog/dialog.snap.d.ts +40 -0
  235. package/dist/components/Dialog/dialog.snap.js +78 -0
  236. package/dist/components/Dialog/dialog.state.svelte.d.ts +122 -10
  237. package/dist/components/Dialog/dialog.state.svelte.js +525 -66
  238. package/dist/components/Dialog/dialog.theme.d.ts +48 -0
  239. package/dist/components/Dialog/dialog.theme.js +32 -9
  240. package/dist/components/Dialog/index.d.ts +4 -1
  241. package/dist/components/Dialog/index.js +1 -0
  242. package/dist/components/DocumentViewer/DocumentSearchControl.svelte +5 -3
  243. package/dist/components/DocumentViewer/documentOutput.js +2 -1
  244. package/dist/components/FloatingWindow/FloatingWindow.svelte +20 -32
  245. package/dist/components/FloatingWindow/FloatingWindow.svelte.d.ts +1 -1
  246. package/dist/components/FloatingWindow/floatingWindow.mcp.d.ts +1 -1
  247. package/dist/components/FloatingWindow/floatingWindow.mcp.js +3 -3
  248. package/dist/components/FloatingWindow/floatingWindow.props.d.ts +9 -4
  249. package/dist/components/FloatingWindow/floatingWindow.state.svelte.d.ts +8 -2
  250. package/dist/components/FloatingWindow/floatingWindow.state.svelte.js +18 -7
  251. package/dist/components/Form/Ask/Ask.svelte +9 -13
  252. package/dist/components/Form/Ask/ask.mcp.d.ts +1 -1
  253. package/dist/components/Form/Ask/ask.mcp.js +1 -1
  254. package/dist/components/Form/Ask/ask.props.d.ts +1 -1
  255. package/dist/components/Form/Autocomplete/Autocomplete.svelte +418 -0
  256. package/dist/components/Form/Autocomplete/Autocomplete.svelte.d.ts +4 -0
  257. package/dist/components/Form/Autocomplete/autocomplete.items.d.ts +30 -0
  258. package/dist/components/Form/Autocomplete/autocomplete.items.js +64 -0
  259. package/dist/components/Form/Autocomplete/autocomplete.mcp.d.ts +1 -0
  260. package/dist/components/Form/Autocomplete/autocomplete.mcp.js +134 -0
  261. package/dist/components/Form/Autocomplete/autocomplete.props.d.ts +146 -0
  262. package/dist/components/Form/Autocomplete/autocomplete.props.js +1 -0
  263. package/dist/components/Form/Autocomplete/autocomplete.theme.d.ts +213 -0
  264. package/dist/components/Form/Autocomplete/autocomplete.theme.js +119 -0
  265. package/dist/components/Form/Autocomplete/index.d.ts +3 -0
  266. package/dist/components/Form/Autocomplete/index.js +2 -0
  267. package/dist/components/Form/Calendar/CalendarInput.svelte +9 -0
  268. package/dist/components/Form/Calendar/CalendarMonthYearPicker.svelte +3 -0
  269. package/dist/components/Form/Calendar/CalendarPrimitive.svelte +5 -0
  270. package/dist/components/Form/Calendar/calendar.mcp.d.ts +1 -1
  271. package/dist/components/Form/Calendar/calendar.mcp.js +2 -1
  272. package/dist/components/Form/Calendar/calendarInput.props.d.ts +2 -0
  273. package/dist/components/Form/Calendar/useCalendar.svelte.d.ts +3 -0
  274. package/dist/components/Form/Calendar/useCalendar.svelte.js +3 -0
  275. package/dist/components/Form/Checkbox/Checkbox.svelte +17 -2
  276. package/dist/components/Form/Checkbox/checkbox.mcp.d.ts +1 -1
  277. package/dist/components/Form/Checkbox/checkbox.mcp.js +11 -1
  278. package/dist/components/Form/Checkbox/checkbox.props.d.ts +12 -1
  279. package/dist/components/Form/CheckboxesInput/CheckboxLine.svelte +69 -32
  280. package/dist/components/Form/CheckboxesInput/CheckboxLine.svelte.d.ts +10 -2
  281. package/dist/components/Form/CheckboxesInput/CheckboxesInput.svelte +123 -74
  282. package/dist/components/Form/CheckboxesInput/CheckboxesInput.svelte.d.ts +12 -12
  283. package/dist/components/Form/CheckboxesInput/checkboxesInput.mcp.d.ts +1 -1
  284. package/dist/components/Form/CheckboxesInput/checkboxesInput.mcp.js +11 -7
  285. package/dist/components/Form/CheckboxesInput/checkboxesInput.props.d.ts +25 -9
  286. package/dist/components/Form/CheckboxesInput/checkboxesInput.theme.d.ts +12 -0
  287. package/dist/components/Form/CheckboxesInput/checkboxesInput.theme.js +9 -4
  288. package/dist/components/Form/CheckboxesInput/choiceEnter.d.ts +11 -0
  289. package/dist/components/Form/CheckboxesInput/choiceEnter.js +27 -0
  290. package/dist/components/Form/ColorInput/ColorInput.svelte +12 -3
  291. package/dist/components/Form/ColorInput/colorInput.mcp.d.ts +1 -1
  292. package/dist/components/Form/ColorInput/colorInput.mcp.js +1 -0
  293. package/dist/components/Form/ColorPicker/ColorPicker.svelte +11 -2
  294. package/dist/components/Form/ColorPicker/ColorPickerInput.svelte +9 -0
  295. package/dist/components/Form/ColorPicker/colorPicker.mcp.d.ts +1 -1
  296. package/dist/components/Form/ColorPicker/colorPicker.mcp.js +1 -0
  297. package/dist/components/Form/ColorPicker/colorPicker.props.d.ts +2 -0
  298. package/dist/components/Form/ColorPicker/colorPicker.state.svelte.d.ts +4 -0
  299. package/dist/components/Form/ColorPicker/colorPicker.state.svelte.js +12 -8
  300. package/dist/components/Form/Combobox/Combobox.svelte +145 -185
  301. package/dist/components/Form/Combobox/Combobox.svelte.d.ts +1 -1
  302. package/dist/components/Form/Combobox/ComboboxPopup.svelte +128 -0
  303. package/dist/components/Form/Combobox/ComboboxPopup.svelte.d.ts +28 -0
  304. package/dist/components/Form/Combobox/combobox.attributes.d.ts +34 -0
  305. package/dist/components/Form/Combobox/combobox.attributes.js +25 -0
  306. package/dist/components/Form/Combobox/combobox.items.d.ts +28 -0
  307. package/dist/components/Form/Combobox/combobox.items.js +68 -0
  308. package/dist/components/Form/Combobox/combobox.mcp.d.ts +1 -1
  309. package/dist/components/Form/Combobox/combobox.mcp.js +104 -13
  310. package/dist/components/Form/Combobox/combobox.props.d.ts +113 -19
  311. package/dist/components/Form/Combobox/combobox.state.svelte.d.ts +137 -0
  312. package/dist/components/Form/Combobox/combobox.state.svelte.js +375 -0
  313. package/dist/components/Form/Combobox/combobox.theme.d.ts +63 -0
  314. package/dist/components/Form/Combobox/combobox.theme.js +37 -1
  315. package/dist/components/Form/Combobox/index.d.ts +2 -1
  316. package/dist/components/Form/Combobox/index.js +1 -0
  317. package/dist/components/Form/DateInput/DateInput.svelte +11 -3
  318. package/dist/components/Form/DateInput/dateInput.mcp.d.ts +1 -1
  319. package/dist/components/Form/DateInput/dateInput.mcp.js +5 -0
  320. package/dist/components/Form/DateSelector/DateSelector.svelte +5 -2
  321. package/dist/components/Form/DateSelector/DateSelectorInput.svelte +9 -0
  322. package/dist/components/Form/DateSelector/dateSelector.mcp.d.ts +1 -1
  323. package/dist/components/Form/DateSelector/dateSelector.mcp.js +2 -2
  324. package/dist/components/Form/DateSelector/dateSelector.props.d.ts +2 -0
  325. package/dist/components/Form/Field/Field.svelte +258 -32
  326. package/dist/components/Form/Field/Field.svelte.d.ts +15 -6
  327. package/dist/components/Form/Field/FieldGroup.svelte +29 -0
  328. package/dist/components/Form/Field/FieldGroup.svelte.d.ts +11 -0
  329. package/dist/components/Form/Field/FieldHiddenInputs.svelte +187 -0
  330. package/dist/components/Form/Field/FieldHiddenInputs.svelte.d.ts +26 -0
  331. package/dist/components/Form/Field/field.d.ts +75 -10
  332. package/dist/components/Form/Field/field.mcp.d.ts +1 -1
  333. package/dist/components/Form/Field/field.mcp.js +158 -18
  334. package/dist/components/Form/Field/field.messages.d.ts +47 -0
  335. package/dist/components/Form/Field/field.messages.js +64 -0
  336. package/dist/components/Form/Field/field.state.svelte.d.ts +117 -40
  337. package/dist/components/Form/Field/field.state.svelte.js +525 -16
  338. package/dist/components/Form/Field/field.theme.d.ts +46 -0
  339. package/dist/components/Form/Field/field.theme.js +33 -0
  340. package/dist/components/Form/Field/fieldHiddenInputs.props.d.ts +61 -0
  341. package/dist/components/Form/Field/fieldHiddenInputs.props.js +1 -0
  342. package/dist/components/Form/Field/fieldNativeForm.svelte.d.ts +14 -0
  343. package/dist/components/Form/Field/fieldNativeForm.svelte.js +113 -0
  344. package/dist/components/Form/Field/index.d.ts +5 -2
  345. package/dist/components/Form/Field/index.js +1 -0
  346. package/dist/components/Form/Field/schemas.js +7 -2
  347. package/dist/components/Form/File/FileInput.svelte +24 -3
  348. package/dist/components/Form/File/fileInput.mcp.d.ts +1 -1
  349. package/dist/components/Form/File/fileInput.mcp.js +1 -0
  350. package/dist/components/Form/Form/Form.svelte +49 -15
  351. package/dist/components/Form/Form/FormActions.svelte +3 -1
  352. package/dist/components/Form/Form/FormActions.svelte.d.ts +42 -2
  353. package/dist/components/Form/Form/FormFieldRenderer.svelte +96 -12
  354. package/dist/components/Form/Form/FormFieldRenderer.svelte.d.ts +3 -2
  355. package/dist/components/Form/Form/FormInputRenderer.svelte +7 -0
  356. package/dist/components/Form/Form/form.d.ts +84 -11
  357. package/dist/components/Form/Form/form.mcp.d.ts +1 -1
  358. package/dist/components/Form/Form/form.mcp.js +178 -12
  359. package/dist/components/Form/Form/form.props.d.ts +32 -1
  360. package/dist/components/Form/Form/form.registry.d.ts +28 -0
  361. package/dist/components/Form/Form/form.registry.js +59 -0
  362. package/dist/components/Form/Form/form.state.svelte.d.ts +1186 -420
  363. package/dist/components/Form/Form/form.state.svelte.js +322 -28
  364. package/dist/components/Form/Form/index.d.ts +4 -1
  365. package/dist/components/Form/Form/index.js +1 -0
  366. package/dist/components/Form/Form/visibility.d.ts +3130 -1863
  367. package/dist/components/Form/KeyValueInput/KeyValueInput.svelte +22 -10
  368. package/dist/components/Form/KeyValueInput/keyValueInput.mcp.d.ts +1 -1
  369. package/dist/components/Form/KeyValueInput/keyValueInput.mcp.js +1 -0
  370. package/dist/components/Form/MultiStepForm/MultiStepForm.svelte +12 -5
  371. package/dist/components/Form/MultiStepForm/multiStepForm.mcp.d.ts +1 -1
  372. package/dist/components/Form/MultiStepForm/multiStepForm.mcp.js +5 -3
  373. package/dist/components/Form/MultiStepForm/multiStepForm.props.d.ts +5 -0
  374. package/dist/components/Form/MultiStepForm/multiStepForm.state.svelte.d.ts +1050 -408
  375. package/dist/components/Form/MultiStepForm/multiStepForm.state.svelte.js +48 -24
  376. package/dist/components/Form/NumberInput/NumberInput.svelte +365 -46
  377. package/dist/components/Form/NumberInput/index.d.ts +1 -1
  378. package/dist/components/Form/NumberInput/numberInput.mcp.d.ts +1 -1
  379. package/dist/components/Form/NumberInput/numberInput.mcp.js +55 -30
  380. package/dist/components/Form/NumberInput/numberInput.props.d.ts +64 -4
  381. package/dist/components/Form/PasswordInput/Password.svelte +28 -1
  382. package/dist/components/Form/PasswordInput/index.d.ts +1 -1
  383. package/dist/components/Form/PasswordInput/passwordInput.mcp.d.ts +1 -1
  384. package/dist/components/Form/PasswordInput/passwordInput.mcp.js +20 -2
  385. package/dist/components/Form/PasswordInput/passwordInput.props.d.ts +23 -0
  386. package/dist/components/Form/PhoneInput/PhoneInput.svelte +11 -4
  387. package/dist/components/Form/PhoneInput/PhoneInputCountryPicker.svelte +47 -21
  388. package/dist/components/Form/PhoneInput/phoneInput-cdn.js +2 -1
  389. package/dist/components/Form/PhoneInput/phoneInput.mcp.d.ts +1 -1
  390. package/dist/components/Form/PhoneInput/phoneInput.mcp.js +6 -2
  391. package/dist/components/Form/PhoneInput/phoneInputCountry.d.ts +9 -3
  392. package/dist/components/Form/PhoneInput/phoneInputCountry.js +34 -24
  393. package/dist/components/Form/PinInput/PinInput.svelte +44 -9
  394. package/dist/components/Form/PinInput/PinInputCells.svelte +22 -1
  395. package/dist/components/Form/PinInput/PinInputCells.svelte.d.ts +1 -0
  396. package/dist/components/Form/PinInput/index.d.ts +1 -1
  397. package/dist/components/Form/PinInput/pinInput.mcp.d.ts +1 -1
  398. package/dist/components/Form/PinInput/pinInput.mcp.js +29 -6
  399. package/dist/components/Form/PinInput/pinInput.props.d.ts +38 -4
  400. package/dist/components/Form/PinInput/pinInput.state.svelte.d.ts +41 -0
  401. package/dist/components/Form/PinInput/pinInput.state.svelte.js +227 -24
  402. package/dist/components/Form/PinInput/pinInput.theme.d.ts +39 -3
  403. package/dist/components/Form/PinInput/pinInput.theme.js +27 -1
  404. package/dist/components/Form/RadioInput/RadioInput.svelte +94 -32
  405. package/dist/components/Form/RadioInput/RadioInput.svelte.d.ts +12 -12
  406. package/dist/components/Form/RadioInput/radioInput.mcp.d.ts +1 -1
  407. package/dist/components/Form/RadioInput/radioInput.mcp.js +12 -9
  408. package/dist/components/Form/RadioInput/radioInput.props.d.ts +22 -6
  409. package/dist/components/Form/RadioInput/radioInput.theme.d.ts +12 -0
  410. package/dist/components/Form/RadioInput/radioInput.theme.js +10 -5
  411. package/dist/components/Form/RatingInput/RatingInput.svelte +13 -4
  412. package/dist/components/Form/RatingInput/ratingInput.mcp.d.ts +1 -1
  413. package/dist/components/Form/RatingInput/ratingInput.mcp.js +3 -3
  414. package/dist/components/Form/RatingInput/ratingInput.props.d.ts +1 -1
  415. package/dist/components/Form/Select/Select.svelte +186 -48
  416. package/dist/components/Form/Select/Select.svelte.d.ts +23 -2
  417. package/dist/components/Form/Select/SelectOptionRow.svelte +69 -0
  418. package/dist/components/Form/Select/SelectOptionRow.svelte.d.ts +18 -0
  419. package/dist/components/Form/Select/index.d.ts +2 -1
  420. package/dist/components/Form/Select/index.js +1 -0
  421. package/dist/components/Form/Select/select.align.d.ts +5 -0
  422. package/dist/components/Form/Select/select.align.js +19 -5
  423. package/dist/components/Form/Select/select.attributes.d.ts +36 -0
  424. package/dist/components/Form/Select/select.attributes.js +27 -0
  425. package/dist/components/Form/Select/select.mcp.d.ts +1 -1
  426. package/dist/components/Form/Select/select.mcp.js +103 -18
  427. package/dist/components/Form/Select/select.props.d.ts +87 -10
  428. package/dist/components/Form/Select/select.state.svelte.d.ts +108 -17
  429. package/dist/components/Form/Select/select.state.svelte.js +354 -59
  430. package/dist/components/Form/Select/select.theme.d.ts +21 -0
  431. package/dist/components/Form/Select/select.theme.js +22 -0
  432. package/dist/components/Form/Slider/Slider.svelte +54 -14
  433. package/dist/components/Form/Slider/SliderMarks.svelte +1 -1
  434. package/dist/components/Form/Slider/SliderThumb.svelte +49 -19
  435. package/dist/components/Form/Slider/SliderThumb.svelte.d.ts +8 -2
  436. package/dist/components/Form/Slider/SliderTrack.svelte +33 -12
  437. package/dist/components/Form/Slider/SliderTrack.svelte.d.ts +6 -2
  438. package/dist/components/Form/Slider/index.d.ts +1 -1
  439. package/dist/components/Form/Slider/slider.mcp.d.ts +1 -1
  440. package/dist/components/Form/Slider/slider.mcp.js +55 -11
  441. package/dist/components/Form/Slider/slider.props.d.ts +35 -2
  442. package/dist/components/Form/Slider/slider.state.svelte.d.ts +66 -5
  443. package/dist/components/Form/Slider/slider.state.svelte.js +273 -49
  444. package/dist/components/Form/Slider/slider.theme.d.ts +36 -0
  445. package/dist/components/Form/Slider/slider.theme.js +35 -17
  446. package/dist/components/Form/Switch/Switch.svelte +61 -38
  447. package/dist/components/Form/Switch/switch.mcp.d.ts +1 -1
  448. package/dist/components/Form/Switch/switch.mcp.js +25 -5
  449. package/dist/components/Form/Switch/switch.props.d.ts +14 -1
  450. package/dist/components/Form/Switch/switch.theme.d.ts +12 -0
  451. package/dist/components/Form/Switch/switch.theme.js +8 -3
  452. package/dist/components/Form/TagGroup/TagGroup.svelte +8 -0
  453. package/dist/components/Form/TagGroup/tagGroup.mcp.d.ts +1 -1
  454. package/dist/components/Form/TagGroup/tagGroup.mcp.js +1 -0
  455. package/dist/components/Form/TagsInput/TagsInput.svelte +277 -275
  456. package/dist/components/Form/TagsInput/TagsInput.svelte.d.ts +1 -1
  457. package/dist/components/Form/TagsInput/tagsInput.mcp.d.ts +1 -1
  458. package/dist/components/Form/TagsInput/tagsInput.mcp.js +31 -11
  459. package/dist/components/Form/TagsInput/tagsInput.props.d.ts +6 -26
  460. package/dist/components/Form/TagsInput/tagsInput.theme.d.ts +63 -0
  461. package/dist/components/Form/TagsInput/tagsInput.theme.js +37 -1
  462. package/dist/components/Form/TextArea/TextArea.svelte +8 -0
  463. package/dist/components/Form/TextArea/textArea.mcp.d.ts +1 -1
  464. package/dist/components/Form/TextArea/textArea.mcp.js +1 -0
  465. package/dist/components/Form/TextInput/TextInput.svelte +8 -1
  466. package/dist/components/Form/TextInput/textInput.mcp.d.ts +1 -1
  467. package/dist/components/Form/TextInput/textInput.mcp.js +5 -0
  468. package/dist/components/Form/TimeInput/TimeInput.svelte +9 -1
  469. package/dist/components/Form/TimeInput/timeInput.mcp.d.ts +1 -1
  470. package/dist/components/Form/TimeInput/timeInput.mcp.js +31 -0
  471. package/dist/components/Form/VoiceInput/VoiceInput.svelte +10 -2
  472. package/dist/components/Form/VoiceInput/voiceInput.mcp.d.ts +1 -1
  473. package/dist/components/Form/VoiceInput/voiceInput.mcp.js +1 -0
  474. package/dist/components/GanttChart/GanttDependencyControl.svelte +4 -4
  475. package/dist/components/HoverCard/HoverCard.svelte +100 -10
  476. package/dist/components/HoverCard/hoverCard.attributes.d.ts +33 -0
  477. package/dist/components/HoverCard/hoverCard.attributes.js +24 -0
  478. package/dist/components/HoverCard/hoverCard.mcp.d.ts +1 -1
  479. package/dist/components/HoverCard/hoverCard.mcp.js +61 -2
  480. package/dist/components/HoverCard/hoverCard.props.d.ts +19 -0
  481. package/dist/components/HoverCard/hoverCard.theme.d.ts +12 -0
  482. package/dist/components/HoverCard/hoverCard.theme.js +9 -2
  483. package/dist/components/HoverCard/index.d.ts +1 -0
  484. package/dist/components/HoverCard/index.js +1 -0
  485. package/dist/components/ImageGallery/imageGallery.state.svelte.d.ts +1 -1
  486. package/dist/components/ImageZoom/imageZoom.lightbox.js +40 -6
  487. package/dist/components/ImageZoom/imageZoom.mcp.d.ts +1 -1
  488. package/dist/components/ImageZoom/imageZoom.mcp.js +3 -3
  489. package/dist/components/ImageZoom/imageZoom.props.d.ts +10 -4
  490. package/dist/components/ImageZoom/imageZoom.state.svelte.d.ts +16 -4
  491. package/dist/components/ImageZoom/imageZoom.state.svelte.js +38 -9
  492. package/dist/components/Kanban/kanban.theme.js +7 -3
  493. package/dist/components/Layout/layoutSpacing.d.ts +2 -2
  494. package/dist/components/LinkPreview/LinkPreview.svelte +7 -1
  495. package/dist/components/LinkPreview/linkPreview.mcp.d.ts +1 -1
  496. package/dist/components/LinkPreview/linkPreview.mcp.js +4 -1
  497. package/dist/components/LinkPreview/linkPreview.props.d.ts +15 -0
  498. package/dist/components/LinkPreview/linkPreview.theme.d.ts +12 -0
  499. package/dist/components/LinkPreview/linkPreview.theme.js +9 -2
  500. package/dist/components/Map/maplibre-cdn.js +3 -2
  501. package/dist/components/Markdown/markdown.mcp.d.ts +1 -1
  502. package/dist/components/Markdown/markdown.mcp.js +2 -1
  503. package/dist/components/Markdown/markdown.theme.js +18 -9
  504. package/dist/components/MediaVolume/MediaVolumeControl.svelte +4 -3
  505. package/dist/components/Menu/Menu.svelte +3 -3
  506. package/dist/components/Menu/Menu.svelte.d.ts +1 -1
  507. package/dist/components/Menu/MenuCheckboxItem.svelte +87 -0
  508. package/dist/components/Menu/MenuCheckboxItem.svelte.d.ts +16 -0
  509. package/dist/components/Menu/MenuFloating.svelte +421 -74
  510. package/dist/components/Menu/MenuFloating.svelte.d.ts +1 -1
  511. package/dist/components/Menu/MenuMirroredIcon.svelte +9 -0
  512. package/dist/components/Menu/MenuMirroredIcon.svelte.d.ts +7 -0
  513. package/dist/components/Menu/MenuRadioGroup.svelte +102 -0
  514. package/dist/components/Menu/MenuRadioGroup.svelte.d.ts +18 -0
  515. package/dist/components/Menu/MenuSearchField.svelte +54 -0
  516. package/dist/components/Menu/MenuSearchField.svelte.d.ts +20 -0
  517. package/dist/components/Menu/MenuStacked.svelte +404 -158
  518. package/dist/components/Menu/MenuStacked.svelte.d.ts +1 -1
  519. package/dist/components/Menu/MenuStackedBackHeader.svelte +6 -1
  520. package/dist/components/Menu/index.d.ts +2 -1
  521. package/dist/components/Menu/index.js +1 -0
  522. package/dist/components/Menu/menu.attributes.d.ts +37 -0
  523. package/dist/components/Menu/menu.attributes.js +28 -0
  524. package/dist/components/Menu/menu.filter.svelte.d.ts +52 -0
  525. package/dist/components/Menu/menu.filter.svelte.js +143 -0
  526. package/dist/components/Menu/menu.mcp.d.ts +1 -1
  527. package/dist/components/Menu/menu.mcp.js +227 -17
  528. package/dist/components/Menu/menu.platform.d.ts +5 -0
  529. package/dist/components/Menu/menu.platform.js +11 -0
  530. package/dist/components/Menu/menu.props.d.ts +172 -9
  531. package/dist/components/Menu/menu.theme.d.ts +147 -0
  532. package/dist/components/Menu/menu.theme.js +101 -0
  533. package/dist/components/Menu/menuTree.d.ts +35 -1
  534. package/dist/components/Menu/menuTree.js +158 -1
  535. package/dist/components/MenuBar/menuBar.mcp.d.ts +1 -1
  536. package/dist/components/MenuBar/menuBar.mcp.js +4 -2
  537. package/dist/components/MenuBar/menuBar.state.svelte.js +28 -10
  538. package/dist/components/MenuOption/MenuOption.svelte +5 -1
  539. package/dist/components/MenuOption/menuOption.mcp.d.ts +1 -1
  540. package/dist/components/MenuOption/menuOption.mcp.js +8 -0
  541. package/dist/components/MenuOption/menuOption.props.d.ts +12 -0
  542. package/dist/components/MenuOption/menuOption.theme.d.ts +18 -0
  543. package/dist/components/MenuOption/menuOption.theme.js +24 -4
  544. package/dist/components/Mermaid/mermaid.mcp.d.ts +1 -1
  545. package/dist/components/Mermaid/mermaid.mcp.js +8 -8
  546. package/dist/components/Mermaid/mermaid.props.d.ts +3 -4
  547. package/dist/components/Mermaid/mermaid.state.svelte.d.ts +20 -19
  548. package/dist/components/Mermaid/mermaid.state.svelte.js +80 -243
  549. package/dist/components/Mermaid/mermaid.theme.js +26 -1
  550. package/dist/components/MetadataList/MetadataList.svelte.d.ts +1 -1
  551. package/dist/components/Meter/Meter.svelte +110 -24
  552. package/dist/components/Meter/Meter.svelte.d.ts +12 -12
  553. package/dist/components/Meter/meter.mcp.d.ts +1 -1
  554. package/dist/components/Meter/meter.mcp.js +23 -37
  555. package/dist/components/Meter/meter.props.d.ts +36 -44
  556. package/dist/components/NavigationMenu/NavigationMenu.svelte +181 -0
  557. package/dist/components/NavigationMenu/NavigationMenu.svelte.d.ts +25 -0
  558. package/dist/components/NavigationMenu/NavigationMenuContent.svelte +141 -0
  559. package/dist/components/NavigationMenu/NavigationMenuContent.svelte.d.ts +13 -0
  560. package/dist/components/NavigationMenu/NavigationMenuTrigger.svelte +75 -0
  561. package/dist/components/NavigationMenu/NavigationMenuTrigger.svelte.d.ts +13 -0
  562. package/dist/components/NavigationMenu/index.d.ts +4 -0
  563. package/dist/components/NavigationMenu/index.js +3 -0
  564. package/dist/components/NavigationMenu/navigationMenu.attributes.d.ts +24 -0
  565. package/dist/components/NavigationMenu/navigationMenu.attributes.js +21 -0
  566. package/dist/components/NavigationMenu/navigationMenu.mcp.d.ts +1 -0
  567. package/dist/components/NavigationMenu/navigationMenu.mcp.js +138 -0
  568. package/dist/components/NavigationMenu/navigationMenu.props.d.ts +129 -0
  569. package/dist/components/NavigationMenu/navigationMenu.props.js +1 -0
  570. package/dist/components/NavigationMenu/navigationMenu.state.svelte.d.ts +163 -0
  571. package/dist/components/NavigationMenu/navigationMenu.state.svelte.js +721 -0
  572. package/dist/components/NavigationMenu/navigationMenu.theme.d.ts +326 -0
  573. package/dist/components/NavigationMenu/navigationMenu.theme.js +239 -0
  574. package/dist/components/Overlay/Overlay.svelte +19 -30
  575. package/dist/components/Overlay/index.d.ts +1 -0
  576. package/dist/components/Overlay/index.js +1 -0
  577. package/dist/components/Overlay/overlay.attributes.d.ts +16 -0
  578. package/dist/components/Overlay/overlay.attributes.js +14 -0
  579. package/dist/components/Overlay/overlay.mcp.d.ts +1 -1
  580. package/dist/components/Overlay/overlay.mcp.js +21 -3
  581. package/dist/components/Overlay/overlay.props.d.ts +8 -4
  582. package/dist/components/Popover/Popover.svelte +163 -52
  583. package/dist/components/Popover/Popover.svelte.d.ts +23 -2
  584. package/dist/components/Popover/PopoverSession.svelte +12 -0
  585. package/dist/components/Popover/PopoverSession.svelte.d.ts +7 -0
  586. package/dist/components/Popover/index.d.ts +10 -2
  587. package/dist/components/Popover/index.js +4 -1
  588. package/dist/components/Popover/popover.api.d.ts +83 -0
  589. package/dist/components/Popover/popover.api.js +1 -0
  590. package/dist/components/Popover/popover.attributes.d.ts +32 -0
  591. package/dist/components/Popover/popover.attributes.js +28 -0
  592. package/dist/components/Popover/popover.claims.d.ts +19 -0
  593. package/dist/components/Popover/popover.claims.js +45 -0
  594. package/dist/components/Popover/popover.mcp.d.ts +1 -1
  595. package/dist/components/Popover/popover.mcp.js +163 -31
  596. package/dist/components/Popover/popover.position.d.ts +226 -0
  597. package/dist/components/Popover/popover.position.js +402 -0
  598. package/dist/components/Popover/popover.props.d.ts +179 -24
  599. package/dist/components/Popover/popover.state.svelte.d.ts +169 -37
  600. package/dist/components/Popover/popover.state.svelte.js +1034 -194
  601. package/dist/components/Popover/popover.theme.d.ts +15 -0
  602. package/dist/components/Popover/popover.theme.js +27 -2
  603. package/dist/components/PopupMenu/PopupMenu.svelte +193 -22
  604. package/dist/components/PopupMenu/PopupMenu.svelte.d.ts +2 -2
  605. package/dist/components/PopupMenu/popupMenu.context.d.ts +42 -0
  606. package/dist/components/PopupMenu/popupMenu.context.js +52 -0
  607. package/dist/components/PopupMenu/popupMenu.mcp.d.ts +1 -1
  608. package/dist/components/PopupMenu/popupMenu.mcp.js +46 -6
  609. package/dist/components/PopupMenu/popupMenu.props.d.ts +29 -2
  610. package/dist/components/Progress/Progress.svelte +160 -0
  611. package/dist/components/Progress/Progress.svelte.d.ts +4 -0
  612. package/dist/components/Progress/index.d.ts +3 -0
  613. package/dist/components/Progress/index.js +2 -0
  614. package/dist/components/Progress/progress.mcp.d.ts +1 -0
  615. package/dist/components/Progress/progress.mcp.js +101 -0
  616. package/dist/components/Progress/progress.props.d.ts +79 -0
  617. package/dist/components/Progress/progress.props.js +1 -0
  618. package/dist/components/Progress/progress.theme.d.ts +129 -0
  619. package/dist/components/Progress/progress.theme.js +83 -0
  620. package/dist/components/ProgressCircle/ProgressCircle.svelte +51 -6
  621. package/dist/components/ProgressCircle/progressCircle.mcp.d.ts +1 -1
  622. package/dist/components/ProgressCircle/progressCircle.mcp.js +18 -4
  623. package/dist/components/ProgressCircle/progressCircle.props.d.ts +32 -2
  624. package/dist/components/ProgressCircle/progressCircle.theme.d.ts +15 -3
  625. package/dist/components/ProgressCircle/progressCircle.theme.js +7 -2
  626. package/dist/components/RichTextInput/RichTextInput.svelte +19 -1
  627. package/dist/components/RichTextInput/RichTextInputChrome.svelte +5 -1
  628. package/dist/components/RichTextInput/RichTextInputChrome.svelte.d.ts +2 -0
  629. package/dist/components/RichTextInput/RichTextInputViewport.svelte +3 -1
  630. package/dist/components/RichTextInput/RichTextInputViewport.svelte.d.ts +1 -0
  631. package/dist/components/RichTextInput/richTextInput.mcp.d.ts +1 -1
  632. package/dist/components/RichTextInput/richTextInput.mcp.js +1 -0
  633. package/dist/components/RichTextInput/suggestions.js +2 -0
  634. package/dist/components/ScrollArea/ScrollArea.svelte +166 -27
  635. package/dist/components/ScrollArea/index.d.ts +2 -1
  636. package/dist/components/ScrollArea/index.js +1 -0
  637. package/dist/components/ScrollArea/scrollArea.attributes.d.ts +25 -0
  638. package/dist/components/ScrollArea/scrollArea.attributes.js +21 -0
  639. package/dist/components/ScrollArea/scrollArea.mcp.d.ts +1 -1
  640. package/dist/components/ScrollArea/scrollArea.mcp.js +47 -3
  641. package/dist/components/ScrollArea/scrollArea.props.d.ts +33 -6
  642. package/dist/components/ScrollArea/scrollArea.svelte.d.ts +56 -12
  643. package/dist/components/ScrollArea/scrollArea.svelte.js +281 -71
  644. package/dist/components/ScrollArea/scrollArea.theme.js +5 -2
  645. package/dist/components/SegmentedControl/SegmentedControl.svelte +4 -3
  646. package/dist/components/SegmentedControl/segmentedControl.mcp.d.ts +1 -1
  647. package/dist/components/SegmentedControl/segmentedControl.mcp.js +3 -2
  648. package/dist/components/SelectionMenu/SelectionMenu.svelte +4 -2
  649. package/dist/components/Sidebar/SidebarAction.svelte +13 -3
  650. package/dist/components/Sidebar/SidebarAction.svelte.d.ts +2 -1
  651. package/dist/components/Sidebar/SidebarActivityBar.svelte +14 -7
  652. package/dist/components/Sidebar/SidebarFlyout.svelte +97 -0
  653. package/dist/components/Sidebar/SidebarFlyout.svelte.d.ts +32 -0
  654. package/dist/components/Sidebar/SidebarGroup.svelte +39 -15
  655. package/dist/components/Sidebar/SidebarMenuButton.svelte +6 -3
  656. package/dist/components/Sidebar/SidebarMenuItem.svelte +134 -31
  657. package/dist/components/Sidebar/SidebarMenuSubItem.svelte +30 -14
  658. package/dist/components/Sidebar/SidebarTreeNode.svelte +41 -61
  659. package/dist/components/Sidebar/index.d.ts +1 -0
  660. package/dist/components/Sidebar/index.js +1 -0
  661. package/dist/components/Sidebar/sidebar-position.d.ts +37 -2
  662. package/dist/components/Sidebar/sidebar-position.js +31 -2
  663. package/dist/components/Sidebar/sidebar.attributes.d.ts +33 -0
  664. package/dist/components/Sidebar/sidebar.attributes.js +29 -0
  665. package/dist/components/Sidebar/sidebar.mcp.d.ts +1 -1
  666. package/dist/components/Sidebar/sidebar.mcp.js +45 -10
  667. package/dist/components/Sidebar/sidebar.props.d.ts +28 -7
  668. package/dist/components/Sidebar/sidebar.theme.d.ts +51 -21
  669. package/dist/components/Sidebar/sidebar.theme.js +113 -62
  670. package/dist/components/Sidebar/sidebar.views.svelte.js +11 -18
  671. package/dist/components/Stepper/Stepper.svelte +2 -0
  672. package/dist/components/Stepper/stepper.mcp.d.ts +1 -1
  673. package/dist/components/Stepper/stepper.mcp.js +1 -0
  674. package/dist/components/Stepper/stepper.props.d.ts +5 -0
  675. package/dist/components/Stepper/stepper.state.svelte.d.ts +2 -0
  676. package/dist/components/Stepper/stepper.state.svelte.js +31 -12
  677. package/dist/components/Tabbar/Tabbar.svelte +55 -16
  678. package/dist/components/Tabbar/index.d.ts +1 -1
  679. package/dist/components/Tabbar/tabbar.mcp.d.ts +1 -1
  680. package/dist/components/Tabbar/tabbar.mcp.js +26 -9
  681. package/dist/components/Tabbar/tabbar.props.d.ts +34 -5
  682. package/dist/components/Tabbar/tabbar.selection.svelte.d.ts +79 -0
  683. package/dist/components/Tabbar/tabbar.selection.svelte.js +99 -0
  684. package/dist/components/TableOfContents/tableOfContents.state.svelte.js +9 -7
  685. package/dist/components/Tabs/Tabs.svelte +73 -16
  686. package/dist/components/Tabs/index.d.ts +2 -1
  687. package/dist/components/Tabs/tabs.direction.svelte.d.ts +25 -0
  688. package/dist/components/Tabs/tabs.direction.svelte.js +40 -0
  689. package/dist/components/Tabs/tabs.mcp.d.ts +1 -1
  690. package/dist/components/Tabs/tabs.mcp.js +22 -4
  691. package/dist/components/Tabs/tabs.props.d.ts +39 -12
  692. package/dist/components/Tabs/tabs.theme.js +3 -1
  693. package/dist/components/Theme/Theme.svelte +44 -27
  694. package/dist/components/Theme/helper.d.ts +16 -2
  695. package/dist/components/Theme/helper.js +46 -4
  696. package/dist/components/Theme/theme.mcp.d.ts +1 -1
  697. package/dist/components/Theme/theme.mcp.js +103 -0
  698. package/dist/components/Theme/theme.props.d.ts +16 -0
  699. package/dist/components/Theme/theme.state.svelte.d.ts +14 -1
  700. package/dist/components/Theme/theme.state.svelte.js +18 -1
  701. package/dist/components/Toast/Toast.svelte +184 -39
  702. package/dist/components/Toast/Toaster.svelte +14 -10
  703. package/dist/components/Toast/index.d.ts +1 -0
  704. package/dist/components/Toast/toast.mcp.d.ts +1 -1
  705. package/dist/components/Toast/toast.mcp.js +47 -6
  706. package/dist/components/Toast/toast.state.svelte.d.ts +172 -6
  707. package/dist/components/Toast/toast.state.svelte.js +513 -68
  708. package/dist/components/Toast/toast.theme.js +1 -1
  709. package/dist/components/ToggleButton/ToggleButton.svelte +23 -1
  710. package/dist/components/ToggleButton/toggleButton.mcp.d.ts +1 -1
  711. package/dist/components/ToggleButton/toggleButton.mcp.js +3 -1
  712. package/dist/components/ToggleButton/toggleButton.props.d.ts +13 -1
  713. package/dist/components/ToggleButton/toggleButton.theme.d.ts +12 -0
  714. package/dist/components/ToggleButton/toggleButton.theme.js +15 -3
  715. package/dist/components/ToggleButtonGroup/ToggleButtonGroup.svelte +29 -9
  716. package/dist/components/ToggleButtonGroup/index.d.ts +1 -1
  717. package/dist/components/ToggleButtonGroup/toggleButtonGroup.mcp.d.ts +1 -1
  718. package/dist/components/ToggleButtonGroup/toggleButtonGroup.mcp.js +5 -2
  719. package/dist/components/ToggleButtonGroup/toggleButtonGroup.props.d.ts +19 -1
  720. package/dist/components/ToggleButtonGroup/toggleButtonGroup.theme.d.ts +12 -0
  721. package/dist/components/ToggleButtonGroup/toggleButtonGroup.theme.js +21 -2
  722. package/dist/components/ToggleMenu/ToggleMenu.svelte +57 -43
  723. package/dist/components/ToggleMenu/ToggleMenuGroup.svelte +1 -0
  724. package/dist/components/ToggleMenu/ToggleMenuMenu.svelte +9 -3
  725. package/dist/components/ToggleMenu/ToggleMenuRadioGroup.svelte +7 -2
  726. package/dist/components/ToggleMenu/toggleMenu.mcp.d.ts +1 -1
  727. package/dist/components/ToggleMenu/toggleMenu.mcp.js +3 -2
  728. package/dist/components/ToggleMenu/toggleMenu.props.d.ts +4 -1
  729. package/dist/components/Tooltip/Tooltip.svelte +4 -12
  730. package/dist/components/Tooltip/TooltipHost.svelte +136 -15
  731. package/dist/components/Tooltip/index.d.ts +1 -0
  732. package/dist/components/Tooltip/index.js +1 -0
  733. package/dist/components/Tooltip/tooltip.attachment.svelte.d.ts +5 -0
  734. package/dist/components/Tooltip/tooltip.attachment.svelte.js +215 -33
  735. package/dist/components/Tooltip/tooltip.attributes.d.ts +32 -0
  736. package/dist/components/Tooltip/tooltip.attributes.js +28 -0
  737. package/dist/components/Tooltip/tooltip.mcp.d.ts +1 -1
  738. package/dist/components/Tooltip/tooltip.mcp.js +111 -10
  739. package/dist/components/Tooltip/tooltip.props.d.ts +33 -2
  740. package/dist/components/Tooltip/tooltip.surface.d.ts +24 -0
  741. package/dist/components/Tooltip/tooltip.surface.js +42 -0
  742. package/dist/components/Tree/TreeContextMenuSurface.svelte +16 -3
  743. package/dist/components/Utils/BeforeHydratation.svelte +14 -3
  744. package/dist/components/Utils/BeforeHydratation.svelte.d.ts +2 -0
  745. package/dist/components/VideoPlayer/VideoPlayer.svelte.d.ts +1 -1
  746. package/dist/components/VideoPlayer/VideoPlayerSettings.svelte +2 -0
  747. package/dist/generated/componentAliases.d.ts +3 -0
  748. package/dist/generated/componentAliases.js +3 -0
  749. package/dist/generated/componentContract.d.ts +79 -34
  750. package/dist/generated/componentContract.js +231 -6
  751. package/dist/generated/componentMcpRegistry.js +6 -0
  752. package/dist/i18n/ar.js +107 -3
  753. package/dist/i18n/context.svelte.d.ts +6 -0
  754. package/dist/i18n/context.svelte.js +12 -0
  755. package/dist/i18n/de.js +101 -3
  756. package/dist/i18n/en.d.ts +91 -2
  757. package/dist/i18n/en.js +101 -3
  758. package/dist/i18n/es.js +101 -3
  759. package/dist/i18n/fr.js +101 -3
  760. package/dist/i18n/ja.js +101 -3
  761. package/dist/i18n/pt.js +101 -3
  762. package/dist/i18n/zh.js +101 -3
  763. package/dist/tailwind/geometry.js +7 -0
  764. package/dist/tailwind/global.js +31 -0
  765. package/dist/types/index.d.ts +1 -0
  766. package/dist/types/types.mcp.d.ts +1 -1
  767. package/dist/types/types.mcp.js +23 -0
  768. package/dist/utils/cspNonce.d.ts +16 -0
  769. package/dist/utils/cspNonce.js +39 -0
  770. package/dist/utils/cva/merge.d.ts +5 -1
  771. package/dist/utils/cva/merge.js +6 -4
  772. package/dist/utils/focus.d.ts +34 -0
  773. package/dist/utils/focus.js +93 -0
  774. package/dist/utils/focusHistory.d.ts +21 -0
  775. package/dist/utils/focusHistory.js +99 -0
  776. package/dist/utils/handlers.d.ts +7 -0
  777. package/dist/utils/handlers.js +14 -0
  778. package/dist/utils/hoverIntent.d.ts +42 -0
  779. package/dist/utils/hoverIntent.js +57 -0
  780. package/dist/utils/id.d.ts +7 -0
  781. package/dist/utils/id.js +15 -0
  782. package/dist/utils/layers.svelte.d.ts +32 -4
  783. package/dist/utils/layers.svelte.js +214 -21
  784. package/dist/utils/listFilter.d.ts +44 -0
  785. package/dist/utils/listFilter.js +130 -0
  786. package/dist/utils/match.d.ts +35 -0
  787. package/dist/utils/match.js +36 -0
  788. package/dist/utils/number.d.ts +126 -0
  789. package/dist/utils/number.js +401 -0
  790. package/dist/utils/openChange.d.ts +88 -0
  791. package/dist/utils/openChange.js +71 -0
  792. package/dist/utils/openLifecycle.svelte.d.ts +41 -0
  793. package/dist/utils/openLifecycle.svelte.js +134 -0
  794. package/dist/utils/pointerDrag.d.ts +10 -0
  795. package/dist/utils/pointerDrag.js +37 -2
  796. package/dist/utils/pragmaticDragAndDrop.d.ts +2 -1
  797. package/dist/utils/pragmaticDragAndDrop.js +8 -3
  798. package/dist/utils/range.d.ts +62 -0
  799. package/dist/utils/range.js +70 -0
  800. package/dist/utils/requestNativeSubmit.d.ts +17 -0
  801. package/dist/utils/requestNativeSubmit.js +47 -0
  802. package/dist/utils/safeArea.svelte.d.ts +10 -1
  803. package/dist/utils/safeArea.svelte.js +19 -11
  804. package/dist/utils/stateAttributes.d.ts +108 -0
  805. package/dist/utils/stateAttributes.js +78 -0
  806. package/dist/utils/swipeVelocity.d.ts +32 -0
  807. package/dist/utils/swipeVelocity.js +59 -0
  808. package/dist/utils/timer.svelte.d.ts +65 -2
  809. package/dist/utils/timer.svelte.js +159 -25
  810. package/dist/utils/trigger.d.ts +41 -0
  811. package/dist/utils/trigger.js +103 -0
  812. package/dist/utils/typeahead.d.ts +9 -0
  813. package/dist/utils/typeahead.js +21 -9
  814. package/dist/utils/useDndList.svelte.d.ts +1 -1
  815. package/dist/utils/useDndList.svelte.js +6 -23
  816. package/dist/utils/useFocusScope.svelte.d.ts +29 -0
  817. package/dist/utils/useFocusScope.svelte.js +189 -27
  818. package/dist/utils/useHoverAction.svelte.d.ts +44 -4
  819. package/dist/utils/useHoverAction.svelte.js +161 -51
  820. package/dist/utils/useKeyDown.svelte.d.ts +19 -2
  821. package/dist/utils/useKeyDown.svelte.js +19 -12
  822. package/dist/utils/useListNavigation.svelte.d.ts +94 -13
  823. package/dist/utils/useListNavigation.svelte.js +261 -35
  824. package/dist/utils/useLiveAnnouncer.svelte.d.ts +77 -2
  825. package/dist/utils/useLiveAnnouncer.svelte.js +119 -2
  826. package/dist/utils/useNavigation.svelte.d.ts +36 -3
  827. package/dist/utils/useNavigation.svelte.js +699 -332
  828. package/dist/utils/usePressAndHold.svelte.d.ts +38 -0
  829. package/dist/utils/usePressAndHold.svelte.js +191 -0
  830. package/dist/utils/useScrollLock.svelte.d.ts +20 -1
  831. package/dist/utils/useScrollLock.svelte.js +54 -13
  832. package/dist/utils/useSlidingIndicator.svelte.d.ts +2 -0
  833. package/dist/utils/useSlidingIndicator.svelte.js +27 -5
  834. package/dist/utils/useTabBridge.svelte.d.ts +20 -0
  835. package/dist/utils/useTabBridge.svelte.js +109 -0
  836. package/dist/utils/values.d.ts +15 -0
  837. package/dist/utils/values.js +49 -0
  838. package/package.json +31 -2
  839. package/dist/generated/componentMcpRegistry.d.ts +0 -142
  840. package/dist/utils/useDrag.svelte.d.ts +0 -11
  841. package/dist/utils/useDrag.svelte.js +0 -55
@@ -1,363 +1,686 @@
1
- import { SvelteSet } from 'svelte/reactivity';
1
+ /* eslint-disable svelte/prefer-svelte-reactivity -- the item registry and its index are DOM bookkeeping, not reactive state; `revision` publishes their changes. */
2
2
  import { useKeyDown } from './useKeyDown.svelte.js';
3
3
  import { on } from 'svelte/events';
4
4
  import { onDestroy, untrack } from 'svelte';
5
5
  import { usePointerDown } from './usePointerDown.svelte.js';
6
6
  import { useDirection } from './useDirection.svelte.js';
7
- import { createTypeahead } from './typeahead.js';
7
+ import { createTypeahead, isTextEntry } from './typeahead.js';
8
8
  import { createId } from './id.js';
9
+ import { prefersReducedMotion } from './motion.svelte.js';
10
+ import { clampRovingKey, createRovingRestoreVersion } from './useRovingRegistry.svelte.js';
11
+ // Every live navigation container, so a list ignores keys that a list nested inside it owns.
12
+ const containers = new WeakSet();
13
+ const byDocumentPosition = (a, b) => {
14
+ const position = a.compareDocumentPosition(b);
15
+ if (position & Node.DOCUMENT_POSITION_FOLLOWING)
16
+ return -1;
17
+ if (position & Node.DOCUMENT_POSITION_PRECEDING)
18
+ return 1;
19
+ return 0;
20
+ };
21
+ // A keyed reorder moves nodes: each moved node is removed and added again in one batch.
22
+ const hasMovedNode = (records) => {
23
+ const removed = new Set();
24
+ for (const record of records)
25
+ record.removedNodes.forEach((node) => removed.add(node));
26
+ if (removed.size === 0)
27
+ return false;
28
+ return records.some((record) => Array.from(record.addedNodes).some((node) => removed.has(node)));
29
+ };
30
+ /** An attribute record whose attribute holds the value it had before the write. */
31
+ const isUnchangedAttribute = (record) => record.type === 'attributes' &&
32
+ record.attributeName !== null &&
33
+ record.target instanceof Element &&
34
+ record.oldValue === record.target.getAttribute(record.attributeName);
35
+ /** Writes an attribute only when its value differs, so unchanged items cost a read, not a write. */
36
+ const setAttribute = (node, name, value) => {
37
+ if (node.getAttribute(name) !== value)
38
+ node.setAttribute(name, value);
39
+ };
40
+ const removeAttribute = (node, name) => {
41
+ if (node.hasAttribute(name))
42
+ node.removeAttribute(name);
43
+ };
44
+ // The caret sits at the start or end of a field with nothing selected, so an arrow pointing past
45
+ // that edge has no text left to move through.
46
+ const isCaretAtEdge = (event, edge) => {
47
+ if (event.shiftKey)
48
+ return false; // Shift+arrow extends a selection.
49
+ const field = event.target;
50
+ if (field instanceof HTMLInputElement || field instanceof HTMLTextAreaElement) {
51
+ const { selectionStart, selectionEnd, value } = field;
52
+ // Fields without a caret API (number, date) keep their arrows.
53
+ if (selectionStart === null || selectionEnd === null || selectionStart !== selectionEnd) {
54
+ return false;
55
+ }
56
+ return edge === 'start' ? selectionStart === 0 : selectionEnd === value.length;
57
+ }
58
+ if (!(field instanceof HTMLElement))
59
+ return false;
60
+ const selection = field.ownerDocument.getSelection();
61
+ if (!selection?.isCollapsed || selection.rangeCount === 0)
62
+ return false;
63
+ const caret = selection.getRangeAt(0);
64
+ const rest = field.ownerDocument.createRange();
65
+ rest.selectNodeContents(field);
66
+ if (edge === 'start')
67
+ rest.setEnd(caret.startContainer, caret.startOffset);
68
+ else
69
+ rest.setStart(caret.endContainer, caret.endOffset);
70
+ return rest.toString().length === 0;
71
+ };
9
72
  export const useNavigation = (opts) => {
10
- const itemsSet = new SvelteSet();
73
+ // The registered items in document order, and each one's position in that order. Mounting
74
+ // registers in document order, so registration appends; a registration out of order or a node
75
+ // moved inside the container marks the order stale, and the next read checks it with one pass
76
+ // over adjacent pairs, sorting only when that pass finds a pair out of order.
77
+ const registered = [];
78
+ const positions = new Map();
79
+ let orderStale = false;
80
+ let positionsStale = false;
81
+ // Bumped whenever membership, order or an item's disabled/hidden state changes; every
82
+ // reactive read of the list (the focused index, the attribute sync) depends on it.
83
+ let revision = $state(0);
84
+ let sequence = 0;
11
85
  let containerRef = $state(null);
12
- let focusedIndex = $state(null);
86
+ // The highlighted item: it has DOM focus, or the pointer rests on it, or it is the item the
87
+ // container's aria-activedescendant names. Tracked by element, so it survives insertions,
88
+ // removals and reorders around it.
89
+ let focusedItem = $state.raw(null);
90
+ // Focus sits on the container itself with no item highlighted (a popup opened by pointer).
91
+ let containerHighlighted = $state(false);
92
+ let lastFocusedItem = $state.raw(null);
13
93
  let focusSource = $state(null);
14
94
  let isHovering = $state(false);
15
95
  let isFocused = $state(false);
16
- let lastFocusedIndex = $state(null);
96
+ // The item that holds DOM focus, or held it when focus was lost to nothing during this task
97
+ // (the item was removed). Not reactive: only the removal of that item reads it.
98
+ let focusHolder = null;
99
+ const restoreVersion = createRovingRestoreVersion();
100
+ // The attributes this list last wrote, so a highlight move rewrites only the items it leaves
101
+ // and enters (at most four attribute writes) instead of every item.
102
+ let appliedTabStop = null;
103
+ let appliedHighlight = null;
17
104
  // Enabled by default — `enabled` is an opt-out, checked at event time so it stays reactive.
18
105
  const isEnabled = () => (opts.enabled ? opts.enabled() : true);
19
- $effect(() => {
20
- if (focusedIndex !== null && focusedIndex !== -1) {
21
- lastFocusedIndex = focusedIndex;
22
- }
23
- });
106
+ const keepsDisabledItems = () => opts.disabledItemsFocusable === true || opts.skipDisabled === false;
24
107
  // Generate ID if not provided
25
108
  const baseId = opts.id ?? createId('nav');
26
109
  const getDirection = useDirection(() => containerRef);
110
+ // Get current orientation
111
+ const getOrientation = () => {
112
+ if (typeof opts.orientation === 'function') {
113
+ return opts.orientation();
114
+ }
115
+ return opts.orientation || 'horizontal';
116
+ };
117
+ /** The registered items in document order. */
118
+ const ordered = () => {
119
+ if (orderStale) {
120
+ orderStale = false;
121
+ for (let index = 1; index < registered.length; index += 1) {
122
+ if (byDocumentPosition(registered[index - 1], registered[index]) > 0) {
123
+ registered.sort(byDocumentPosition);
124
+ positionsStale = true;
125
+ break;
126
+ }
127
+ }
128
+ }
129
+ if (positionsStale) {
130
+ positionsStale = false;
131
+ registered.forEach((item, index) => positions.set(item, index));
132
+ }
133
+ return registered;
134
+ };
135
+ const indexOf = (item) => {
136
+ if (!item)
137
+ return -1;
138
+ ordered();
139
+ return positions.get(item) ?? -1;
140
+ };
141
+ // Natively disabled items (a `disabled` attribute, or inside a disabled fieldset) can never
142
+ // take focus, so they are never targets.
143
+ const isNativelyDisabled = (item) => item.hasAttribute('disabled') || item.matches(':disabled');
144
+ // Announced as disabled while still able to take focus.
145
+ const isSoftDisabled = (item) => {
146
+ const dataDisabled = item.getAttribute('data-disabled');
147
+ return (item.getAttribute('aria-disabled') === 'true' ||
148
+ (dataDisabled !== null && dataDisabled !== 'false'));
149
+ };
150
+ /** Never activated: natively disabled, aria-disabled or data-disabled. */
151
+ const isItemDisabled = (item) => isNativelyDisabled(item) || isSoftDisabled(item);
152
+ /** Cannot hold focus or the tab stop. */
153
+ const isUnfocusable = (item) => isNativelyDisabled(item) || (!keepsDisabledItems() && isSoftDisabled(item));
154
+ // CSS-hidden items (`display: none`, a hidden ancestor, inert content) have no box to focus.
155
+ const isRendered = (item) => item.getClientRects().length > 0 && !item.closest('[inert]');
156
+ /** A target for arrow keys, Home/End and type-ahead. */
157
+ const isNavigable = (item) => !isUnfocusable(item) && isRendered(item);
158
+ // The registered item that is or contains `node`; the container itself is no item.
159
+ const itemOf = (node) => {
160
+ let element = node instanceof Element ? node : node instanceof Node ? node.parentElement : null;
161
+ while (element && element !== containerRef) {
162
+ if (element instanceof HTMLElement && positions.has(element))
163
+ return element;
164
+ element = element.parentElement;
165
+ }
166
+ return null;
167
+ };
168
+ const itemIndexOf = (node) => indexOf(itemOf(node));
169
+ // A key typed inside a navigation list nested in this one belongs to that list.
170
+ const ownsKeyTarget = (target) => {
171
+ for (let element = target instanceof Element ? target : null; element && element !== containerRef; element = element.parentElement) {
172
+ if (containers.has(element))
173
+ return false;
174
+ }
175
+ return true;
176
+ };
177
+ // The first navigable item from the start (1) or the end (-1). When nothing is rendered yet
178
+ // (the list sits in a hidden panel), the first item that can take focus once it shows.
179
+ const findEdge = (direction) => {
180
+ const items = ordered();
181
+ let fallback = -1;
182
+ for (let step = 0; step < items.length; step += 1) {
183
+ const index = direction === 1 ? step : items.length - 1 - step;
184
+ if (isUnfocusable(items[index]))
185
+ continue;
186
+ if (isRendered(items[index]))
187
+ return index;
188
+ if (fallback === -1)
189
+ fallback = index;
190
+ }
191
+ return fallback;
192
+ };
193
+ // The next navigable item after `from` in `direction`, or -1 when there is none (the end of a
194
+ // list that does not loop). `from: null` enters the list at the edge the key points away from.
195
+ const findFrom = (from, direction) => {
196
+ if (from === null)
197
+ return findEdge(direction);
198
+ const items = ordered();
199
+ const { loop = true } = opts;
200
+ for (let distance = 1; distance <= items.length; distance += 1) {
201
+ let index = from + direction * distance;
202
+ if (loop) {
203
+ index = ((index % items.length) + items.length) % items.length;
204
+ }
205
+ else if (index < 0 || index >= items.length) {
206
+ return -1;
207
+ }
208
+ if (isNavigable(items[index]))
209
+ return index;
210
+ }
211
+ return -1;
212
+ };
213
+ // The single item reachable with Tab: the highlighted item when there is one, otherwise the
214
+ // default/active item, otherwise the first navigable one. This makes Tab land on the
215
+ // meaningful item WITHOUT any element being DOM-focused on mount (which would flash a focus
216
+ // ring). Virtual focus keeps every item out of the tab order.
217
+ const resolveTabStop = () => {
218
+ if (opts.virtualFocus)
219
+ return null;
220
+ if (focusedItem && !isUnfocusable(focusedItem))
221
+ return focusedItem;
222
+ const items = ordered();
223
+ const preferredIndex = opts.defaultFocusedIndex?.();
224
+ const preferred = preferredIndex == null ? undefined : items[preferredIndex];
225
+ if (preferred && isNavigable(preferred))
226
+ return preferred;
227
+ const edge = findEdge(1);
228
+ if (edge !== -1 && isRendered(items[edge]))
229
+ return items[edge];
230
+ // Nothing is rendered yet: keep the stop where it belongs once the list shows.
231
+ if (preferred && !isUnfocusable(preferred))
232
+ return preferred;
233
+ return items[edge] ?? null;
234
+ };
235
+ /**
236
+ * Brings `tabindex`, `data-highlighted` and the container's `aria-activedescendant` in line
237
+ * with the highlighted item and the tab stop, touching only the items that changed role.
238
+ */
239
+ const sync = () => {
240
+ const tabStop = resolveTabStop();
241
+ if (appliedTabStop && appliedTabStop !== tabStop && positions.has(appliedTabStop)) {
242
+ setAttribute(appliedTabStop, 'tabindex', '-1');
243
+ }
244
+ if (tabStop)
245
+ setAttribute(tabStop, 'tabindex', '0');
246
+ appliedTabStop = tabStop;
247
+ const highlight = focusedItem;
248
+ if (appliedHighlight && appliedHighlight !== highlight) {
249
+ removeAttribute(appliedHighlight, 'data-highlighted');
250
+ }
251
+ if (highlight)
252
+ setAttribute(highlight, 'data-highlighted', 'true');
253
+ appliedHighlight = highlight;
254
+ if (!containerRef)
255
+ return;
256
+ if (highlight?.id)
257
+ setAttribute(containerRef, 'aria-activedescendant', highlight.id);
258
+ else
259
+ removeAttribute(containerRef, 'aria-activedescendant');
260
+ };
261
+ const setFocused = (item, source) => {
262
+ focusedItem = item;
263
+ focusSource = item ? source : null;
264
+ containerHighlighted = false;
265
+ if (item)
266
+ lastFocusedItem = item;
267
+ };
27
268
  const typeahead = opts.typeahead
28
269
  ? createTypeahead({
29
- getItems: () => items,
270
+ getItems: ordered,
30
271
  getText: (item) => typeof opts.typeahead === 'object'
31
272
  ? opts.typeahead.getText(item)
32
273
  : (item.dataset.typeahead ?? item.textContent ?? ''),
33
- getCurrentIndex: () => focusedIndex ?? -1,
274
+ // Search from the focused item, not from the one the pointer highlighted.
275
+ getCurrentIndex: () => {
276
+ const focused = itemIndexOf(document.activeElement);
277
+ return focused !== -1 ? focused : indexOf(focusedItem);
278
+ },
279
+ isItemDisabled: (item) => !isNavigable(item),
34
280
  onMatch: (index) => {
35
- if (!isItemDisabled(items[index]))
36
- moveFocusTo(index);
281
+ const focused = itemIndexOf(document.activeElement);
282
+ moveFocusTo(index, focused !== -1 ? focused : indexOf(focusedItem));
37
283
  }
38
284
  })
39
285
  : null;
40
- // Get current orientation
41
- const getOrientation = () => {
42
- if (typeof opts.orientation === 'function') {
43
- return opts.orientation();
44
- }
45
- return opts.orientation || 'horizontal';
46
- };
286
+ // The focused element, not its index, is what a change reports: an insertion before it moves
287
+ // its index without changing what has focus.
47
288
  $effect(() => {
48
- if (focusedIndex === null)
289
+ const item = focusedItem;
290
+ if (!item)
49
291
  return;
50
- const newFocusedIndex = focusedIndex;
51
292
  untrack(() => {
52
- opts.onChange?.(newFocusedIndex);
293
+ const index = indexOf(item);
294
+ if (index !== -1)
295
+ opts.onChange?.(index);
53
296
  });
54
297
  });
298
+ // Plain functions, not deriveds: a menu switch reads these from sync() while the previous
299
+ // menu's effects are being destroyed, and reading a derived owned by a destroyed effect warns
300
+ // (derived_inert) and may return a stale value. They still track `revision` and the focus
301
+ // state for any reactive caller.
302
+ const readFocusedIndex = () => {
303
+ void revision;
304
+ if (focusedItem) {
305
+ const index = indexOf(focusedItem);
306
+ return index === -1 ? null : index;
307
+ }
308
+ return containerHighlighted ? -1 : null;
309
+ };
310
+ const readLastFocusedIndex = () => {
311
+ void revision;
312
+ const index = indexOf(lastFocusedItem);
313
+ return index === -1 ? null : index;
314
+ };
315
+ let observer = null;
316
+ // A class, style or media-query change can hide an item without touching any watched
317
+ // attribute. Hiding collapses its box, which a ResizeObserver reports; the tab stop then
318
+ // moves to an item that is still rendered. The first report of an item always counts, since an
319
+ // item hidden at mount reports nothing until it shows.
320
+ const renderedItems = new WeakMap();
321
+ let resizeObserver = null;
322
+ const watchRendered = (node) => {
323
+ if (typeof ResizeObserver === 'undefined')
324
+ return;
325
+ resizeObserver ??= new ResizeObserver((entries) => {
326
+ let changed = false;
327
+ for (const { target } of entries) {
328
+ if (!(target instanceof HTMLElement) || !positions.has(target))
329
+ continue;
330
+ const rendered = target.getClientRects().length > 0;
331
+ if (renderedItems.get(target) !== rendered)
332
+ changed = true;
333
+ renderedItems.set(target, rendered);
334
+ }
335
+ if (changed)
336
+ revision += 1;
337
+ });
338
+ resizeObserver.observe(node);
339
+ };
55
340
  const cleanUp = () => {
56
- itemsSet.clear();
341
+ registered.length = 0;
342
+ positions.clear();
343
+ observer?.disconnect();
344
+ observer = null;
345
+ resizeObserver?.disconnect();
346
+ resizeObserver = null;
347
+ typeahead?.reset();
348
+ restoreVersion.bump();
57
349
  containerRef = null;
58
- focusedIndex = null;
350
+ focusedItem = null;
59
351
  focusSource = null;
352
+ containerHighlighted = false;
60
353
  isHovering = false;
61
354
  isFocused = false;
62
- lastFocusedIndex = null;
355
+ lastFocusedItem = null;
356
+ focusHolder = null;
357
+ appliedTabStop = null;
358
+ appliedHighlight = null;
63
359
  };
64
360
  onDestroy(() => {
65
361
  cleanUp();
66
362
  });
67
363
  const focusContainer = () => {
68
364
  if (containerRef) {
69
- focusedIndex = -1;
365
+ setFocused(null, null);
366
+ containerHighlighted = true;
367
+ sync();
70
368
  containerRef.focus();
71
369
  }
72
370
  };
73
- // Derived: Get ordered items by DOM position
74
- const items = $derived.by(() => {
75
- if (itemsSet.size === 0)
76
- return [];
77
- if (containerRef === null)
78
- return [];
79
- const itemsArray = Array.from(itemsSet);
80
- // Sort by DOM position using compareDocumentPosition
81
- return itemsArray.sort((a, b) => {
82
- const position = a.compareDocumentPosition(b);
83
- if (position & Node.DOCUMENT_POSITION_FOLLOWING) {
84
- return -1; // a comes before b
85
- }
86
- else if (position & Node.DOCUMENT_POSITION_PRECEDING) {
87
- return 1; // b comes before a
88
- }
89
- return 0;
90
- });
91
- });
92
- // Check if item is disabled
93
- const isItemDisabled = (item) => {
94
- const dataDisabled = item.getAttribute('data-disabled');
95
- return (item.hasAttribute('disabled') ||
96
- item.getAttribute('aria-disabled') === 'true' ||
97
- (dataDisabled !== null && dataDisabled !== 'false'));
98
- };
99
- // Find next non-disabled index
100
- const findNextIndex = (currentIndex, direction) => {
101
- const { loop = true } = opts;
102
- const total = items.length;
103
- for (let distance = 1; distance <= total; distance += 1) {
104
- let nextIndex = currentIndex + direction * distance;
105
- if (loop) {
106
- nextIndex = ((nextIndex % total) + total) % total;
107
- }
108
- else if (nextIndex < 0 || nextIndex >= total) {
109
- return currentIndex;
110
- }
111
- if (!isItemDisabled(items[nextIndex]))
112
- return nextIndex;
113
- }
114
- return currentIndex;
115
- };
116
- // Find first non-disabled index
117
- const findFirstIndex = () => {
118
- for (let i = 0; i < items.length; i++) {
119
- if (!isItemDisabled(items[i]))
120
- return i;
121
- }
122
- return -1; // No enabled items
123
- };
124
- // Find last non-disabled index
125
- const findLastIndex = () => {
126
- for (let i = items.length - 1; i >= 0; i--) {
127
- if (!isItemDisabled(items[i]))
128
- return i;
129
- }
130
- return -1; // No enabled items
131
- };
132
- // Update ARIA attributes on all items
133
- const updateAriaAttributes = (focusIdx) => {
134
- // The roving tab-stop (the single item reachable with Tab): the focused item
135
- // when there is one, otherwise the default/active item, otherwise the first
136
- // enabled one. This makes Tab land on the meaningful item WITHOUT any element
137
- // being DOM-focused on mount (which would flash a focus ring). Virtual focus
138
- // keeps every item out of the tab order.
139
- const preferredTabStop = focusIdx ?? opts.defaultFocusedIndex?.();
140
- const enabledTabStop = preferredTabStop != null &&
141
- items[preferredTabStop] &&
142
- !isItemDisabled(items[preferredTabStop])
143
- ? preferredTabStop
144
- : findFirstIndex();
145
- const tabStop = opts.virtualFocus ? -1 : enabledTabStop;
146
- items.forEach((item, index) => {
147
- const isFocused = index === focusIdx;
148
- const itemId = `${baseId}-item-${index}`;
149
- // Set ID
150
- if (!item.id) {
151
- item.id = itemId;
152
- }
153
- // Roving tabindex sits on the tab-stop; data-highlighted (below) tracks
154
- // actual keyboard focus, which is a separate concern.
155
- item.setAttribute('tabindex', index === tabStop && !isItemDisabled(item) ? '0' : '-1');
156
- // Set data-highlighted for keyboard focus
157
- if (isFocused) {
158
- item.setAttribute('data-highlighted', 'true');
159
- }
160
- else {
161
- item.removeAttribute('data-highlighted');
162
- }
163
- });
164
- // Update container's aria-activedescendant to focused item
165
- if (containerRef && focusIdx !== null && items[focusIdx]) {
166
- containerRef.setAttribute('aria-activedescendant', items[focusIdx].id);
167
- }
168
- else if (containerRef) {
169
- containerRef.removeAttribute('aria-activedescendant');
170
- }
171
- };
172
- // Move focus to specific index (arrow key navigation)
173
- const moveFocusTo = (index) => {
174
- if (items.length === 0)
371
+ /**
372
+ * Moves the highlight and DOM focus to `index`. `from` marks a key-driven move (the index the
373
+ * key started from, `null` when it entered the list), which reports through `onKeyboardMove`.
374
+ */
375
+ const moveFocusTo = (index, from) => {
376
+ const item = ordered()[index];
377
+ if (!item || isUnfocusable(item))
175
378
  return;
176
- if (index < 0 || index >= items.length)
177
- return;
178
- if (isItemDisabled(items[index]))
179
- return;
180
- focusSource = 'keyboard';
181
- focusedIndex = index;
182
- updateAriaAttributes(index);
183
- if (items[index]) {
184
- const item = items[index];
185
- // Virtual focus (combobox pattern): DOM focus stays put, only the highlight moves.
186
- if (!opts.virtualFocus) {
187
- item.focus();
188
- }
189
- // Scroll the item into view if needed
190
- item.scrollIntoView({
191
- block: 'nearest',
192
- inline: 'nearest',
193
- behavior: 'smooth'
194
- });
379
+ setFocused(item, 'keyboard');
380
+ sync();
381
+ // Virtual focus (combobox pattern): DOM focus stays put, only the highlight moves.
382
+ if (!opts.virtualFocus) {
383
+ item.focus();
195
384
  }
385
+ // Scroll the item into view if needed
386
+ item.scrollIntoView({
387
+ block: 'nearest',
388
+ inline: 'nearest',
389
+ behavior: prefersReducedMotion() ? 'auto' : 'smooth'
390
+ });
391
+ if (from !== undefined && from !== index)
392
+ opts.onKeyboardMove?.(index);
196
393
  };
197
394
  // Click the currently focused item (Enter/Space key)
198
395
  const clickFocused = () => {
199
- if (focusedIndex === null || focusedIndex < 0 || focusedIndex >= items.length)
200
- return;
201
- if (isItemDisabled(items[focusedIndex]))
396
+ if (!focusedItem || isItemDisabled(focusedItem))
202
397
  return;
203
- // Trigger click event on the focused element
204
- items[focusedIndex].click();
398
+ focusedItem.click();
205
399
  };
206
400
  // Clear focus state when container loses focus
207
401
  const clearFocus = () => {
208
- focusedIndex = null;
209
- focusSource = null;
402
+ setFocused(null, null);
210
403
  // Restore the default roving tab stop while removing the active highlight.
211
- updateAriaAttributes(null);
404
+ sync();
212
405
  };
213
406
  // Handle item hover - only set visual focus (no DOM focus yet)
214
- const handleItemHover = (itemElement) => {
215
- // Find the index of the hovered item
216
- const index = items.findIndex((item) => item === itemElement);
217
- if (index === -1)
218
- return;
219
- if (isItemDisabled(items[index]))
407
+ const handleItemHover = (item) => {
408
+ if (!positions.has(item) || isItemDisabled(item))
220
409
  return;
221
410
  // Set visual focus on hovered item (don't manipulate DOM focus)
222
- focusSource = 'pointer';
223
- focusedIndex = index;
224
- updateAriaAttributes(index);
411
+ setFocused(item, 'pointer');
412
+ sync();
225
413
  };
226
- // Handle keyboard events
227
- // Batch update ARIA attributes when items or focusedIndex change
228
- $effect(() => {
229
- if (items.length > 0) {
230
- updateAriaAttributes(focusedIndex);
414
+ // The navigable item nearest to `from`: `from` itself, then the item before it, the one after,
415
+ // and so on outward (the order a tab list picks the tab that replaces a removed one).
416
+ const findNearest = (from) => {
417
+ const items = ordered();
418
+ for (let distance = 0; distance < items.length; distance += 1) {
419
+ for (const index of [from + distance, from - distance - 1]) {
420
+ if (index >= 0 && index < items.length && isNavigable(items[index]))
421
+ return index;
422
+ }
423
+ }
424
+ return -1;
425
+ };
426
+ // Removing the item that had DOM focus would drop focus to <body>. Once the change has settled
427
+ // (replacement items registered), focus moves to the item that took the removed one's place,
428
+ // or the nearest navigable item to it — unless focus has already gone somewhere else.
429
+ const scheduleRestore = (previous, removed) => {
430
+ const version = restoreVersion.bump();
431
+ queueMicrotask(() => {
432
+ if (!restoreVersion.isCurrent(version) || !containerRef)
433
+ return;
434
+ const active = document.activeElement;
435
+ if (active && active !== document.body && active !== document.documentElement)
436
+ return;
437
+ const neighbour = clampRovingKey(previous, removed, ordered());
438
+ const target = neighbour ? findNearest(indexOf(neighbour)) : -1;
439
+ if (target !== -1)
440
+ moveFocusTo(target);
441
+ });
442
+ };
443
+ const register = (node) => {
444
+ const last = registered.at(-1);
445
+ if (last && (!last.isConnected || byDocumentPosition(last, node) > 0))
446
+ orderStale = true;
447
+ positions.set(node, registered.length);
448
+ registered.push(node);
449
+ // Ids are assigned once, at registration: aria-activedescendant names them.
450
+ if (!node.id)
451
+ node.id = `${baseId}-item-${(sequence += 1)}`;
452
+ setAttribute(node, 'tabindex', '-1');
453
+ watchRendered(node);
454
+ revision += 1;
455
+ };
456
+ const unregister = (node) => {
457
+ if (!positions.has(node))
458
+ return;
459
+ const previous = focusHolder === node ? registered.slice() : null;
460
+ const index = registered.indexOf(node);
461
+ if (index !== -1)
462
+ registered.splice(index, 1);
463
+ positions.delete(node);
464
+ positionsStale = true;
465
+ resizeObserver?.unobserve(node);
466
+ renderedItems.delete(node);
467
+ if (appliedTabStop === node)
468
+ appliedTabStop = null;
469
+ if (appliedHighlight === node)
470
+ appliedHighlight = null;
471
+ if (lastFocusedItem === node)
472
+ lastFocusedItem = null;
473
+ if (focusedItem === node)
474
+ setFocused(null, null);
475
+ if (previous) {
476
+ focusHolder = null;
477
+ scheduleRestore(previous, node);
231
478
  }
479
+ revision += 1;
480
+ };
481
+ // Keep the attributes in line after every change to the list, the highlight or the default
482
+ // item. It runs after the DOM updates, so it also wins over a consumer's own `tabindex`.
483
+ $effect(() => {
484
+ void revision;
485
+ sync();
232
486
  });
233
487
  const pointerDown = usePointerDown({
234
488
  isActive: () => true
235
489
  });
236
- // Use the existing useKeyDown hook - pass all possible keys, filter in handleKeyboard
237
- const keyDown = useKeyDown({
238
- isActive: () => {
239
- if (!isEnabled())
240
- return false;
241
- if (isHovering && opts.enableHoverFocus) {
242
- return true;
243
- }
244
- return true;
245
- },
246
- preventDefault: opts.preventKeyboardDefault,
247
- onWindow: () => {
248
- // return false;
249
- return isHovering && !isFocused && opts.enableHoverFocus ? true : false;
250
- },
251
- callback: (event) => {
252
- // Respect the enabled gate per-event: the element listener is attached once at mount and
253
- // never re-checks isActive, so without this a disabled menu (e.g. a parent whose submenu
254
- // is open) would still handle keys that bubble to it and double-navigate.
255
- if (!isEnabled())
256
- return;
257
- // Hover-to-navigate must not hijack when focus already lives inside another menu/listbox
258
- // (e.g. an open submenu portaled elsewhere): stealing focus here would yank the caret out
259
- // of the submenu and navigate this container instead.
260
- const active = document.activeElement;
261
- if (active &&
262
- !containerRef?.contains(active) &&
263
- active.closest('[role="menu"],[role="listbox"]')) {
264
- return;
265
- }
266
- // If hovering but container not focused, focus it first on arrow key
267
- if (isHovering &&
268
- opts.enableHoverFocus &&
269
- containerRef &&
270
- document.activeElement !== containerRef &&
271
- !containerRef.contains(document.activeElement)) {
272
- containerRef.focus();
490
+ // In RTL the inline arrows are mirrored: in a horizontal list ArrowRight goes to the previous
491
+ // item; in a vertical one ArrowLeft opens a level (onNext) and ArrowRight leaves it (onPrevious).
492
+ const resolveKey = (key) => {
493
+ const mirrored = (opts.rtl ?? true) && getDirection() === 'rtl';
494
+ if (mirrored && key === 'ArrowLeft')
495
+ return 'ArrowRight';
496
+ if (mirrored && key === 'ArrowRight')
497
+ return 'ArrowLeft';
498
+ return key;
499
+ };
500
+ // Move with an arrow along the list's axis; a key with nowhere to go still counts as handled,
501
+ // so the page does not scroll under the list.
502
+ const step = (from, direction) => {
503
+ const index = findFrom(from, direction);
504
+ if (index !== -1)
505
+ moveFocusTo(index, from);
506
+ return true;
507
+ };
508
+ /**
509
+ * Move or activate for one (already mirrored) key, starting from `from`: the index of the item
510
+ * the key acts on, or `null` when it comes from outside the items and enters the list at an
511
+ * edge. Returns whether the key did anything.
512
+ */
513
+ const navigate = (key, from) => {
514
+ const orientation = getOrientation();
515
+ switch (key) {
516
+ case 'ArrowLeft':
517
+ case 'ArrowRight': {
518
+ const direction = key === 'ArrowRight' ? 1 : -1;
519
+ if (orientation !== 'vertical')
520
+ return step(from, direction);
521
+ // Cross axis of a vertical list: the item may open (onNext) or leave (onPrevious) a level.
522
+ const item = from === null ? undefined : ordered()[from];
523
+ if (!item)
524
+ return false;
525
+ const node = item;
526
+ const handler = direction === 1 ? node.onNext : node.onPrevious;
527
+ if (typeof handler !== 'function')
528
+ return false;
529
+ return handler.call(node) !== false;
273
530
  }
274
- const orientation = getOrientation();
275
- if (!opts.preventKeyboardDefault && event.key !== 'Escape') {
276
- event.preventDefault();
531
+ case 'ArrowUp':
532
+ case 'ArrowDown':
533
+ if (orientation === 'horizontal')
534
+ return false;
535
+ return step(from, key === 'ArrowDown' ? 1 : -1);
536
+ case 'Home':
537
+ case 'End': {
538
+ const index = findEdge(key === 'Home' ? 1 : -1);
539
+ if (index === -1)
540
+ return false;
541
+ moveFocusTo(index, from);
542
+ return true;
277
543
  }
278
- // In RTL the physical arrows are mirrored: ArrowRight goes to the previous item.
279
- const mirrored = (opts.rtl ?? true) && orientation === 'horizontal' && getDirection() === 'rtl';
280
- const key = mirrored && event.key === 'ArrowLeft'
281
- ? 'ArrowRight'
282
- : mirrored && event.key === 'ArrowRight'
283
- ? 'ArrowLeft'
284
- : event.key;
285
- switch (key) {
286
- case 'ArrowLeft':
287
- if (orientation === 'horizontal') {
288
- const currentIdx = focusedIndex ?? findFirstIndex();
289
- if (currentIdx !== -1) {
290
- moveFocusTo(findNextIndex(currentIdx, -1));
291
- }
292
- }
293
- else if (focusedIndex !== null) {
294
- const node = items[focusedIndex];
295
- if ('onPrevious' in node && typeof node.onPrevious === 'function') {
296
- node.onPrevious();
297
- }
298
- }
299
- break;
300
- case 'ArrowRight':
301
- if (orientation === 'horizontal') {
302
- const currentIdx = focusedIndex ?? findFirstIndex();
303
- if (currentIdx !== -1) {
304
- moveFocusTo(findNextIndex(currentIdx, 1));
305
- }
306
- }
307
- else if (focusedIndex !== null) {
308
- const node = items[focusedIndex];
309
- if ('onNext' in node && typeof node.onNext === 'function') {
310
- node.onNext();
311
- }
312
- }
313
- break;
314
- case 'ArrowUp':
315
- if (orientation === 'vertical') {
316
- const currentIdx = focusedIndex ?? findFirstIndex();
317
- if (currentIdx !== -1) {
318
- moveFocusTo(findNextIndex(currentIdx, -1));
319
- }
320
- else {
321
- moveFocusTo(findLastIndex());
322
- }
323
- }
324
- break;
325
- case 'ArrowDown':
326
- if (orientation === 'vertical') {
327
- const currentIdx = focusedIndex ?? findFirstIndex();
328
- if (currentIdx !== -1) {
329
- moveFocusTo(findNextIndex(currentIdx, 1));
330
- }
331
- else {
332
- moveFocusTo(findFirstIndex());
333
- }
334
- }
335
- break;
336
- case 'Home': {
337
- const firstIndex = findFirstIndex();
338
- if (firstIndex !== -1) {
339
- moveFocusTo(firstIndex);
340
- }
341
- break;
342
- }
343
- case 'End': {
344
- const lastIndex = findLastIndex();
345
- if (lastIndex !== -1) {
346
- moveFocusTo(lastIndex);
347
- }
348
- break;
544
+ case 'Escape':
545
+ if (containerRef?.contains(document.activeElement)) {
546
+ clearFocus();
349
547
  }
350
- case 'Escape': {
351
- if (containerRef?.contains(document.activeElement)) {
352
- clearFocus();
353
- }
354
- break;
355
- }
356
- case 'Enter':
357
- case ' ':
358
- clickFocused();
359
- break;
360
- }
548
+ return true;
549
+ case 'Enter':
550
+ case ' ':
551
+ if (key === 'Enter' && opts.enterActivates === false)
552
+ return false;
553
+ clickFocused();
554
+ return true;
555
+ }
556
+ return false;
557
+ };
558
+ // Keys act where keyboard focus is. Hover moves the highlight without moving DOM focus, so a
559
+ // key typed on a focused item starts from that item, not from the one under the pointer. A key
560
+ // typed on the container itself (a popup menu opened by pointer) keeps the highlighted item,
561
+ // which the container's aria-activedescendant names.
562
+ const syncToKeyTarget = (target) => {
563
+ const item = itemOf(target);
564
+ if (!item || item === focusedItem)
565
+ return;
566
+ setFocused(item, 'keyboard');
567
+ sync();
568
+ };
569
+ // The item a key typed on `target` starts from; null enters the list at an edge.
570
+ const keyOrigin = (target) => {
571
+ const index = itemIndexOf(target);
572
+ if (index !== -1)
573
+ return index;
574
+ if (target !== containerRef)
575
+ return null;
576
+ const highlighted = indexOf(focusedItem);
577
+ return highlighted === -1 ? null : highlighted;
578
+ };
579
+ // A text field keeps its editing keys: Home, End, Space and Enter never leave it. Arrows along
580
+ // the list's axis do, horizontal ones only from the caret edge they point past (a search field
581
+ // in a toolbar), vertical ones from single-line inputs (a filter field above a menu's rows).
582
+ const fieldReleases = (event, key) => {
583
+ const orientation = getOrientation();
584
+ switch (key) {
585
+ case 'ArrowLeft':
586
+ case 'ArrowRight':
587
+ return (orientation !== 'vertical' && isCaretAtEdge(event, key === 'ArrowRight' ? 'end' : 'start'));
588
+ case 'ArrowUp':
589
+ case 'ArrowDown':
590
+ if (orientation === 'horizontal')
591
+ return false;
592
+ return (event.target instanceof HTMLInputElement ||
593
+ isCaretAtEdge(event, key === 'ArrowDown' ? 'end' : 'start'));
594
+ default:
595
+ return false;
596
+ }
597
+ };
598
+ // Content inside the container that is no item (a header field or button) keeps Enter, Space
599
+ // and Escape; arrows along the axis and Home/End enter the list at its start or end.
600
+ const contentReleases = (event, key) => {
601
+ if (isTextEntry(event.target))
602
+ return fieldReleases(event, key);
603
+ const orientation = getOrientation();
604
+ switch (key) {
605
+ case 'Home':
606
+ case 'End':
607
+ return true;
608
+ case 'ArrowLeft':
609
+ case 'ArrowRight':
610
+ return orientation !== 'vertical';
611
+ case 'ArrowUp':
612
+ case 'ArrowDown':
613
+ return orientation !== 'horizontal';
614
+ default:
615
+ return false;
616
+ }
617
+ };
618
+ // Keys typed while focus is inside the container.
619
+ const handleContainerKey = (event) => {
620
+ const target = event.target;
621
+ if (!ownsKeyTarget(target))
622
+ return;
623
+ const key = resolveKey(event.key);
624
+ if (target !== containerRef && !itemOf(target)) {
625
+ if (!isEnabled() || !contentReleases(event, key))
626
+ return;
627
+ event.preventDefault();
628
+ navigate(key, null);
629
+ return;
630
+ }
631
+ if (isTextEntry(target) && key !== 'Escape' && !fieldReleases(event, key))
632
+ return;
633
+ // `preventKeyboardDefault: false` (menus) lets Escape reach the popup that closes on it;
634
+ // every other consumer keeps all of its keys.
635
+ if (opts.preventKeyboardDefault !== false)
636
+ event.preventDefault();
637
+ if (!isEnabled())
638
+ return;
639
+ if (event.key !== 'Escape')
640
+ event.preventDefault();
641
+ syncToKeyTarget(target);
642
+ navigate(key, keyOrigin(target));
643
+ };
644
+ // Only these keys may pull focus into a container the pointer merely rests on.
645
+ const hoverEntryKeys = ['ArrowLeft', 'ArrowRight', 'ArrowUp', 'ArrowDown', 'Home', 'End'];
646
+ // No element has focus: the key was typed on the page itself, not in a field or control.
647
+ const isPageLevel = (node) => {
648
+ const pageTargets = [
649
+ null,
650
+ window,
651
+ document,
652
+ document.body,
653
+ document.documentElement
654
+ ];
655
+ return pageTargets.includes(node);
656
+ };
657
+ // Hover-to-navigate (`enableHoverFocus`): while the pointer rests on the container and nothing
658
+ // on the page has focus, arrows and Home/End move focus into it, from the item highlighted
659
+ // under the pointer or, with none, at the edge the key points to. A key typed anywhere else (a
660
+ // text field, a button, an open submenu or dialog) belongs to that element, and Enter/Space
661
+ // never activate an item that is only highlighted under the pointer.
662
+ const handleHoverKey = (event) => {
663
+ if (event.defaultPrevented || !hoverEntryKeys.includes(event.key))
664
+ return;
665
+ if (!isPageLevel(document.activeElement) || !isPageLevel(event.target))
666
+ return;
667
+ const highlighted = indexOf(focusedItem);
668
+ if (navigate(resolveKey(event.key), highlighted === -1 ? null : highlighted)) {
669
+ event.preventDefault();
670
+ }
671
+ };
672
+ // Alt/Ctrl/Meta + a navigation key is a browser or OS shortcut (Alt+← is Back), never a move.
673
+ // useKeyDown leaves those alone; preventDefault is decided per path above.
674
+ const keyDown = useKeyDown({
675
+ isActive: isEnabled,
676
+ preventDefault: false,
677
+ ignoreModifiers: true,
678
+ onWindow: () => isHovering && !isFocused && !!opts.enableHoverFocus,
679
+ callback: (event, source) => {
680
+ if (source === 'window')
681
+ handleHoverKey(event);
682
+ else
683
+ handleContainerKey(event);
361
684
  },
362
685
  keys: ['Escape', 'ArrowLeft', 'ArrowRight', 'ArrowUp', 'ArrowDown', 'Home', 'End', 'Enter', ' ']
363
686
  });
@@ -365,28 +688,64 @@ export const useNavigation = (opts) => {
365
688
  containerReference: (node) => {
366
689
  return untrack(() => {
367
690
  containerRef = node;
368
- // Make container focusable for keyboard navigation (virtual focus keeps
369
- // DOM focus on the consumer's own element, e.g. a combobox input).
370
- if (!node.hasAttribute('tabindex') && !opts.virtualFocus) {
371
- node.setAttribute('tabindex', '0');
691
+ containers.add(node);
692
+ // Focusable from script (a popup focuses it and names the highlighted item through
693
+ // aria-activedescendant) but never a Tab stop: the roving tab stop is on an item.
694
+ // Virtual focus keeps DOM focus on the consumer's own element (a combobox input).
695
+ if (!node.hasAttribute('tabindex') &&
696
+ !opts.virtualFocus &&
697
+ opts.focusableContainer !== false) {
698
+ node.setAttribute('tabindex', '-1');
699
+ }
700
+ // A keyed reorder moves item nodes without re-running their attachments, and an item can
701
+ // become disabled or hidden without registering again: both re-sync the list. Only a
702
+ // move (a node removed and added again in one batch) can break the order; insertions are
703
+ // placed as they register and removals keep it.
704
+ if (typeof MutationObserver !== 'undefined') {
705
+ observer = new MutationObserver((records) => {
706
+ // Writing an attribute with the value it already has still queues a record (a
707
+ // template re-assigning `button.disabled = true`). Counting it would re-run the
708
+ // attribute sync, which re-runs that template: an endless loop.
709
+ if (records.every(isUnchangedAttribute))
710
+ return;
711
+ if (hasMovedNode(records))
712
+ orderStale = true;
713
+ revision += 1;
714
+ });
715
+ observer.observe(node, {
716
+ childList: true,
717
+ subtree: true,
718
+ attributes: true,
719
+ attributeOldValue: true,
720
+ attributeFilter: ['disabled', 'aria-disabled', 'data-disabled', 'hidden', 'inert']
721
+ });
372
722
  }
373
723
  // Apply keydown reference
374
- const keyDownCleanup = keyDown.reference?.(node);
724
+ const keyDownCleanup = keyDown.reference(node);
375
725
  const typeaheadCleanup = typeahead
376
726
  ? on(node, 'keydown', (event) => {
377
- if (!isEnabled() || event.defaultPrevented)
727
+ if (!isEnabled() || event.defaultPrevented || !ownsKeyTarget(event.target))
378
728
  return;
379
729
  if (typeahead.handleKey(event))
380
730
  event.preventDefault();
381
731
  })
382
732
  : null;
383
- // Handle focus event - set focus to first item when container receives focus
384
- const handleFocus = () => {
733
+ // The container itself receiving focus (from script, or a click between items) moves
734
+ // focus to the default item, unless the pointer is down or a popup focused it on purpose.
735
+ // Focus that lands on an item, or on other content inside the list, stays there.
736
+ const handleFocus = (event) => {
385
737
  isFocused = true;
386
- if (focusedIndex === null && !pointerDown.isDown) {
387
- const firstIndex = opts.defaultFocusedIndex?.() ?? findFirstIndex();
388
- if (firstIndex !== -1) {
389
- moveFocusTo(firstIndex);
738
+ focusHolder = itemOf(event.target);
739
+ if (event.target !== node)
740
+ return;
741
+ if (focusedItem === null && !containerHighlighted && !pointerDown.isDown) {
742
+ const preferred = opts.defaultFocusedIndex?.();
743
+ const items = ordered();
744
+ const index = preferred != null && items[preferred] && isNavigable(items[preferred])
745
+ ? preferred
746
+ : findEdge(1);
747
+ if (index !== -1) {
748
+ moveFocusTo(index);
390
749
  }
391
750
  }
392
751
  };
@@ -394,12 +753,25 @@ export const useNavigation = (opts) => {
394
753
  // Handle blur event - reset focus when container loses focus
395
754
  const handleBlur = (event) => {
396
755
  isFocused = false;
397
- // Check if focus moved outside the container
398
756
  const relatedTarget = event.relatedTarget;
399
- if (!relatedTarget || !node.contains(relatedTarget)) {
400
- // Focus moved outside, clear focus state
401
- clearFocus();
757
+ if (relatedTarget instanceof Node && node.contains(relatedTarget))
758
+ return;
759
+ // Focus left the list: the type-ahead buffer starts over next time.
760
+ typeahead?.reset();
761
+ if (relatedTarget === null) {
762
+ // Lost to nothing. Chromium blurs a focused item while removing it (still connected,
763
+ // so this cannot tell yet), and its unregistration later in the same flush restores
764
+ // focus. An item still in the document afterwards lost focus to the page instead.
765
+ const holder = focusHolder;
766
+ queueMicrotask(() => {
767
+ if (focusHolder === holder && holder?.isConnected)
768
+ focusHolder = null;
769
+ });
770
+ }
771
+ else {
772
+ focusHolder = null;
402
773
  }
774
+ clearFocus();
403
775
  };
404
776
  const blurCleanup = on(node, 'focusout', handleBlur);
405
777
  // Handle container pointer enter - track hovering state
@@ -420,12 +792,12 @@ export const useNavigation = (opts) => {
420
792
  // on mount — a tablist/menu must not steal focus just by existing (it
421
793
  // caused a focus-visible ring on the first tab on page load). Consumers
422
794
  // that want focus-on-mount opt in explicitly (e.g. Menu's `focusOnMount`
423
- // via onMount). Tabbing into the container still focuses the active item
424
- // through the `focusin` handler above, and the roving tab-stop
425
- // (updateAriaAttributes) makes the active item directly Tab-reachable.
795
+ // via onMount). The roving tab-stop (sync) makes the active item directly
796
+ // Tab-reachable.
426
797
  return () => {
798
+ containers.delete(node);
427
799
  cleanUp();
428
- keyDownCleanup?.();
800
+ keyDownCleanup();
429
801
  typeaheadCleanup?.();
430
802
  focusCleanup();
431
803
  blurCleanup();
@@ -437,28 +809,23 @@ export const useNavigation = (opts) => {
437
809
  },
438
810
  itemReference: (node) => {
439
811
  return untrack(() => {
440
- // Add item to set
441
- itemsSet.add(node);
442
- // ARIA attributes are now batch-updated via $effect
812
+ register(node);
443
813
  const handleFocus = () => {
444
- const index = items.findIndex((item) => item === node);
445
- if (index === -1 || isItemDisabled(node))
814
+ if (!positions.has(node) || isUnfocusable(node))
446
815
  return;
447
- focusSource = 'keyboard';
448
- focusedIndex = index;
449
- updateAriaAttributes(index);
816
+ setFocused(node, 'keyboard');
817
+ sync();
450
818
  };
451
819
  const focusCleanup = on(node, 'focus', handleFocus);
452
820
  // Handle hover - only move focus if enabled
453
821
  const handleHover = () => {
454
- if (isEnabled() && opts.enableHoverFocus !== false && !isItemDisabled(node)) {
822
+ if (isEnabled() && opts.enableHoverFocus !== false) {
455
823
  handleItemHover(node);
456
824
  }
457
825
  };
458
826
  const hoverCleanup = on(node, 'pointerenter', handleHover);
459
827
  return () => {
460
- // Remove item from set
461
- itemsSet.delete(node);
828
+ unregister(node);
462
829
  focusCleanup();
463
830
  hoverCleanup();
464
831
  };
@@ -466,22 +833,22 @@ export const useNavigation = (opts) => {
466
833
  },
467
834
  // Expose focused index for external use
468
835
  get focusedIndex() {
469
- return focusedIndex;
836
+ return readFocusedIndex();
470
837
  },
471
838
  // Expose control methods
472
839
  focusItem: (index) => {
473
- if (index >= 0 && index < items.length) {
840
+ if (index >= 0 && index < ordered().length) {
474
841
  moveFocusTo(index);
475
842
  }
476
843
  },
477
844
  focusFirst: () => {
478
- const firstIndex = findFirstIndex();
845
+ const firstIndex = findEdge(1);
479
846
  if (firstIndex !== -1) {
480
847
  moveFocusTo(firstIndex);
481
848
  }
482
849
  },
483
850
  focusLast: () => {
484
- const lastIndex = findLastIndex();
851
+ const lastIndex = findEdge(-1);
485
852
  if (lastIndex !== -1) {
486
853
  moveFocusTo(lastIndex);
487
854
  }
@@ -496,16 +863,16 @@ export const useNavigation = (opts) => {
496
863
  * any) should be highlighted instead of the stale trigger.
497
864
  */
498
865
  syncPointerFocus: () => {
499
- const hovered = items.findIndex((item) => item.matches(':hover') && !isItemDisabled(item));
500
- if (hovered !== -1) {
501
- handleItemHover(items[hovered]);
866
+ const hovered = ordered().find((item) => item.matches(':hover') && !isItemDisabled(item));
867
+ if (hovered) {
868
+ handleItemHover(hovered);
502
869
  }
503
870
  else if (focusSource === 'pointer') {
504
871
  clearFocus();
505
872
  }
506
873
  },
507
874
  get lastFocusedIndex() {
508
- return lastFocusedIndex;
875
+ return readLastFocusedIndex();
509
876
  },
510
877
  focusContainer: focusContainer
511
878
  };