@morscherlab/mint-sdk 1.1.25 → 1.2.0-beta.10

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 (403) hide show
  1. package/README.md +44 -12
  2. package/dist/{ExperimentPopover-tLwJ7XF4.js → ExperimentPopover-oL0fg_A0.js} +6 -4
  3. package/dist/ExperimentPopover-oL0fg_A0.js.map +1 -0
  4. package/dist/{ExperimentSelectorModal-B6P2msT4.js → ExperimentSelectorModal-BeEOomw_.js} +5 -5
  5. package/dist/ExperimentSelectorModal-BeEOomw_.js.map +1 -0
  6. package/dist/{SettingsModal-BW3Ar-uy.js → SettingsModal-Dphh3RrI.js} +5 -8
  7. package/dist/SettingsModal-Dphh3RrI.js.map +1 -0
  8. package/dist/{EmptyState-p90quq8Z.js → Skeleton-DxtwJ5gt.js} +111 -93
  9. package/dist/Skeleton-DxtwJ5gt.js.map +1 -0
  10. package/dist/__tests__/components/ExperimentTimeline.test.d.ts +1 -0
  11. package/dist/__tests__/components/PluginWorkspaceView.internal.test.d.ts +1 -0
  12. package/dist/__tests__/components/SecretInput.test.d.ts +1 -0
  13. package/dist/__tests__/components/WellEditPopupInternal.test.d.ts +1 -0
  14. package/dist/__tests__/composables/useEventStream.test.d.ts +1 -0
  15. package/dist/__tests__/composables/useListReorder.test.d.ts +1 -0
  16. package/dist/__tests__/styles/cssTokens.test.d.ts +1 -0
  17. package/dist/components/ActionMenu.vue.d.ts +1 -1
  18. package/dist/components/AppAvatarMenu.vue.d.ts +4 -0
  19. package/dist/components/AppPluginSwitcher.vue.d.ts +2 -0
  20. package/dist/components/AppSidebar.vue.d.ts +1 -1
  21. package/dist/components/AuditTrail.vue.d.ts +13 -0
  22. package/dist/components/BatchProgressList.vue.d.ts +17 -0
  23. package/dist/components/BioTemplateExperimentWorkspaceView.vue.d.ts +1 -1
  24. package/dist/components/DataFrame.vue.d.ts +14 -2
  25. package/dist/components/DatePicker.vue.d.ts +1 -1
  26. package/dist/components/DateTimePicker.vue.d.ts +2 -0
  27. package/dist/components/DropdownButton.vue.d.ts +2 -0
  28. package/dist/components/ExperimentDataViewer.vue.d.ts +26 -1
  29. package/dist/components/ExperimentPopover.vue.d.ts +1 -0
  30. package/dist/components/ExperimentTimeline.vue.d.ts +29 -1
  31. package/dist/components/FitPanel.vue.d.ts +1 -1
  32. package/dist/components/LcmsSequenceTable.vue.d.ts +29 -1
  33. package/dist/components/PluginWorkspaceView.props.d.ts +29 -1
  34. package/dist/components/PluginWorkspaceView.vue.d.ts +5 -5
  35. package/dist/components/ProgressBar.vue.d.ts +1 -1
  36. package/dist/components/ProtocolStepEditor.vue.d.ts +1 -0
  37. package/dist/components/ReagentList.vue.d.ts +29 -1
  38. package/dist/components/SampleHierarchyTree.vue.d.ts +29 -1
  39. package/dist/components/SampleSelector.drag.d.ts +13 -0
  40. package/dist/components/SampleSelector.tree.d.ts +2 -0
  41. package/dist/components/SampleSelector.vue.d.ts +34 -1
  42. package/dist/components/ScheduleCalendar.vue.d.ts +20 -0
  43. package/dist/components/SecretInput.vue.d.ts +28 -0
  44. package/dist/components/SmartGroupFieldRecipe.vue.d.ts +2 -1
  45. package/dist/components/TimePicker.vue.d.ts +1 -0
  46. package/dist/components/WellPlate.geometry.d.ts +15 -0
  47. package/dist/components/WellPlate.interaction.d.ts +13 -0
  48. package/dist/components/WellPlate.vue.d.ts +29 -0
  49. package/dist/components/index.d.ts +9 -0
  50. package/dist/components/index.js +8 -8
  51. package/dist/components/internal/AppTopBarPageSelectorInternal.vue.d.ts +2 -0
  52. package/dist/components/internal/DataStateInternal.vue.d.ts +43 -0
  53. package/dist/components/internal/WellEditPopupInternal.vue.d.ts +3 -1
  54. package/dist/components/internal/WorkspaceControlsInternal.vue.d.ts +23 -0
  55. package/dist/components/internal/WorkspaceShellInternal.vue.d.ts +70 -0
  56. package/dist/components/internal/WorkspaceSidebarInternal.vue.d.ts +43 -0
  57. package/dist/{components-DQt0tcpY.js → components-CgAUzF8F.js} +2491 -2235
  58. package/dist/components-CgAUzF8F.js.map +1 -0
  59. package/dist/composables/controlSchemaTypes.d.ts +34 -0
  60. package/dist/composables/flattenWorkspaceBindings.d.ts +61 -0
  61. package/dist/composables/index.d.ts +8 -2
  62. package/dist/composables/index.js +10 -10
  63. package/dist/composables/pluginWorkspaceModel.d.ts +164 -0
  64. package/dist/composables/useAsync.d.ts +5 -1
  65. package/dist/composables/useBioTemplateWorkspace.d.ts +4 -20
  66. package/dist/composables/useCommandHistory.d.ts +5 -1
  67. package/dist/composables/useDropdownState.d.ts +18 -2
  68. package/dist/composables/useEventStream.d.ts +52 -0
  69. package/dist/composables/useFocusTrap.d.ts +21 -0
  70. package/dist/composables/useJobsStatusTray.d.ts +1 -1
  71. package/dist/composables/useListReorder.d.ts +90 -0
  72. package/dist/composables/useMenuKeyboard.d.ts +29 -0
  73. package/dist/composables/useOptimisticMutation.d.ts +5 -1
  74. package/dist/composables/usePluginClient.d.ts +4 -17
  75. package/dist/composables/usePluginConfig.d.ts +3 -1
  76. package/dist/composables/usePluginWorkspace.d.ts +51 -0
  77. package/dist/composables/useRequestSyncState.d.ts +42 -2
  78. package/dist/composables/useResourceCrud.d.ts +5 -1
  79. package/dist/composables/useRovingFocus.d.ts +24 -0
  80. package/dist/composables/useScheduleDrag.d.ts +1 -0
  81. package/dist/composables/useWellPainting.d.ts +5 -1
  82. package/dist/composables/useWellPlateAdapter.d.ts +5 -1
  83. package/dist/composables/useWellPlateValidation.d.ts +5 -1
  84. package/dist/composables/workspaceRecipes.d.ts +188 -0
  85. package/dist/{composables-CkXDe7nm.js → composables-B_pia3hO.js} +105 -254
  86. package/dist/composables-B_pia3hO.js.map +1 -0
  87. package/dist/{useApi-CDBq6z23.js → errors-_W0-LbA6.js} +102 -3
  88. package/dist/errors-_W0-LbA6.js.map +1 -0
  89. package/dist/{experiment-Y9Iz7KYi.js → experiment-Cwl9AYxw.js} +3 -8
  90. package/dist/experiment-Cwl9AYxw.js.map +1 -0
  91. package/dist/{experiment-utils-CLnzPPq5.js → experiment-utils-DV3DrvE_.js} +70 -51
  92. package/dist/experiment-utils-DV3DrvE_.js.map +1 -0
  93. package/dist/index.d.ts +1 -0
  94. package/dist/index.js +15 -15
  95. package/dist/install.js +2 -7
  96. package/dist/install.js.map +1 -1
  97. package/dist/permissions.d.ts +42 -1
  98. package/dist/permissions.js +20 -10
  99. package/dist/permissions.js.map +1 -1
  100. package/dist/stores/index.d.ts +1 -1
  101. package/dist/stores/index.js +3 -3
  102. package/dist/stores/settings.d.ts +31 -1
  103. package/dist/styles.css +11247 -29501
  104. package/dist/templates/builderReadUtils.d.ts +1 -1
  105. package/dist/templates/index.js +2 -4
  106. package/dist/{templates-CovvRZ-9.js → templates-Qq113pyZ.js} +303 -106
  107. package/dist/templates-Qq113pyZ.js.map +1 -0
  108. package/dist/types/form-builder.d.ts +1 -1
  109. package/dist/{useControlSchema-BhoJzWzx.js → useControlSchema-aMZlb4Sc.js} +684 -1216
  110. package/dist/useControlSchema-aMZlb4Sc.js.map +1 -0
  111. package/dist/{useDropdownState-DSb3BC3N.js → useDropdownState-DitCtrTT.js} +22 -6
  112. package/dist/useDropdownState-DitCtrTT.js.map +1 -0
  113. package/dist/{useExperimentSelector-D0pjj9WH.js → useExperimentSelector-I8HC8hUu.js} +4 -4
  114. package/dist/{useExperimentSelector-D0pjj9WH.js.map → useExperimentSelector-I8HC8hUu.js.map} +1 -1
  115. package/dist/{useFormBuilder-DiEcDis2.js → useFormBuilder-TCxNnqeb.js} +2 -2
  116. package/dist/{useFormBuilder-DiEcDis2.js.map → useFormBuilder-TCxNnqeb.js.map} +1 -1
  117. package/dist/{useProtocolTemplates-DHwSveE6.js → useProtocolTemplates-BmX_iVBR.js} +660 -197
  118. package/dist/useProtocolTemplates-BmX_iVBR.js.map +1 -0
  119. package/dist/utils/color.d.ts +13 -0
  120. package/dist/utils/errors.d.ts +9 -0
  121. package/dist/utils/pluginSecrets.d.ts +53 -0
  122. package/dist/utils/records.d.ts +4 -0
  123. package/package.json +1 -1
  124. package/src/__tests__/components/ActionMenu.test.ts +94 -0
  125. package/src/__tests__/components/AppAvatarMenu.test.ts +123 -0
  126. package/src/__tests__/components/BaseTabs.test.ts +67 -0
  127. package/src/__tests__/components/DataFrame.test.ts +183 -11
  128. package/src/__tests__/components/DataStates.test.ts +176 -0
  129. package/src/__tests__/components/DatePicker.test.ts +76 -0
  130. package/src/__tests__/components/DateTimePicker.test.ts +36 -0
  131. package/src/__tests__/components/DropdownButton.test.ts +134 -0
  132. package/src/__tests__/components/ExperimentTimeline.test.ts +63 -0
  133. package/src/__tests__/components/GeneratedPluginView.test.ts +0 -5
  134. package/src/__tests__/components/GroupAssigner.test.ts +53 -0
  135. package/src/__tests__/components/JobsStatusTray.test.ts +20 -18
  136. package/src/__tests__/components/LcmsSequenceTable.test.ts +22 -0
  137. package/src/__tests__/components/PluginWorkspaceView.internal.test.ts +230 -0
  138. package/src/__tests__/components/RackEditor.test.ts +35 -0
  139. package/src/__tests__/components/ReagentList.test.ts +64 -2
  140. package/src/__tests__/components/RetiredStyles.test.ts +31 -0
  141. package/src/__tests__/components/SampleSelector.drag.test.ts +51 -1
  142. package/src/__tests__/components/ScheduleCalendar.test.ts +63 -0
  143. package/src/__tests__/components/SecretInput.test.ts +87 -0
  144. package/src/__tests__/components/SegmentedControl.test.ts +88 -0
  145. package/src/__tests__/components/TimePicker.test.ts +61 -0
  146. package/src/__tests__/components/WellEditPopupInternal.test.ts +108 -0
  147. package/src/__tests__/components/WellPlate.interaction.test.ts +59 -0
  148. package/src/__tests__/composables/useAuth.test.ts +25 -0
  149. package/src/__tests__/composables/useDropdownState.test.ts +58 -1
  150. package/src/__tests__/composables/useEventStream.test.ts +140 -0
  151. package/src/__tests__/composables/useGeneratedAnalysis.test.ts +103 -0
  152. package/src/__tests__/composables/useJobsStatusTray.test.ts +25 -161
  153. package/src/__tests__/composables/useListReorder.test.ts +145 -0
  154. package/src/__tests__/composables/usePluginClient.test.ts +148 -13
  155. package/src/__tests__/composables/useRequestSyncState.test.ts +140 -0
  156. package/src/__tests__/docs/frontendDocsCatalog.test.ts +55 -2
  157. package/src/__tests__/stores/settings.test.ts +71 -1
  158. package/src/__tests__/styles/cssTokens.test.ts +131 -0
  159. package/src/__tests__/utils/permissions.test.ts +68 -0
  160. package/src/components/ActionMenu.vue +45 -88
  161. package/src/components/AlertBox.vue +0 -4
  162. package/src/components/AppAvatarMenu.vue +26 -7
  163. package/src/components/AppLayout.vue +0 -4
  164. package/src/components/AppPluginSwitcher.story.vue +87 -0
  165. package/src/components/AppPluginSwitcher.vue +2 -5
  166. package/src/components/AppSidebar.vue +0 -4
  167. package/src/components/AppToastContainer.vue +6 -8
  168. package/src/components/AppTopBar.vue +0 -4
  169. package/src/components/ArtifactSaveDialog.vue +0 -4
  170. package/src/components/ArtifactSelectorModal.vue +0 -4
  171. package/src/components/AuditTrail.story.vue +18 -0
  172. package/src/components/AuditTrail.vue +27 -7
  173. package/src/components/AutoGroupModal.vue +0 -4
  174. package/src/components/Avatar.vue +0 -4
  175. package/src/components/BaseButton.vue +0 -4
  176. package/src/components/BaseCheckbox.vue +0 -4
  177. package/src/components/BaseInput.vue +0 -4
  178. package/src/components/BaseModal.vue +8 -60
  179. package/src/components/BasePill.vue +0 -4
  180. package/src/components/BaseRadioGroup.vue +0 -4
  181. package/src/components/BaseSelect.vue +0 -4
  182. package/src/components/BaseSlider.vue +0 -4
  183. package/src/components/BaseTabs.vue +26 -5
  184. package/src/components/BaseTextarea.vue +0 -4
  185. package/src/components/BaseToggle.vue +0 -4
  186. package/src/components/BatchProgressList.story.vue +18 -0
  187. package/src/components/BatchProgressList.vue +32 -4
  188. package/src/components/BioTemplateExperimentWorkspaceView.vue +10 -21
  189. package/src/components/BioTemplatePackWorkspaceView.vue +11 -15
  190. package/src/components/BioTemplatePresetWorkspaceView.vue +8 -13
  191. package/src/components/Breadcrumb.vue +0 -4
  192. package/src/components/Calendar.vue +0 -4
  193. package/src/components/ChartContainer.story.vue +1 -1
  194. package/src/components/ChartContainer.vue +0 -4
  195. package/src/components/ChemicalFormula.vue +0 -4
  196. package/src/components/CollapsibleCard.vue +0 -4
  197. package/src/components/ColorSlider.vue +0 -4
  198. package/src/components/ComponentBindingRenderer.vue +1 -3
  199. package/src/components/ConcentrationInput.vue +0 -4
  200. package/src/components/ConfirmDialog.vue +0 -4
  201. package/src/components/ControlWorkspaceView.vue +11 -22
  202. package/src/components/DataFrame.story.vue +14 -0
  203. package/src/components/DataFrame.vue +97 -23
  204. package/src/components/DatePicker.vue +73 -27
  205. package/src/components/DateTimePicker.vue +45 -17
  206. package/src/components/Divider.vue +0 -4
  207. package/src/components/DoseCalculator.vue +0 -4
  208. package/src/components/DoseDesignWorkspaceView.vue +6 -25
  209. package/src/components/DropdownButton.vue +24 -6
  210. package/src/components/EmptyState.vue +0 -4
  211. package/src/components/ExperimentCodeBadge.vue +0 -4
  212. package/src/components/ExperimentDataViewer.story.vue +3 -0
  213. package/src/components/ExperimentDataViewer.vue +33 -13
  214. package/src/components/ExperimentPopover.vue +2 -5
  215. package/src/components/ExperimentSelectorModal.vue +0 -4
  216. package/src/components/ExperimentTimeline.story.vue +18 -0
  217. package/src/components/ExperimentTimeline.vue +81 -75
  218. package/src/components/FileUploader.vue +0 -4
  219. package/src/components/FitPanel.vue +0 -4
  220. package/src/components/FormActions.story.vue +96 -0
  221. package/src/components/FormActions.vue +0 -4
  222. package/src/components/FormBuilder.vue +0 -4
  223. package/src/components/FormField.vue +0 -4
  224. package/src/components/FormulaInput.vue +0 -4
  225. package/src/components/GeneratedPathInput.story.vue +68 -0
  226. package/src/components/GeneratedPlotlyResult.story.vue +96 -0
  227. package/src/components/GeneratedPlotlyResult.vue +3 -3
  228. package/src/components/GeneratedPluginView.story.vue +145 -0
  229. package/src/components/GeneratedPluginView.vue +10 -10
  230. package/src/components/GeneratedResultRenderer.story.vue +117 -0
  231. package/src/components/GeneratedResultRenderer.vue +4 -4
  232. package/src/components/GroupAssigner.vue +67 -5
  233. package/src/components/IconButton.vue +0 -4
  234. package/src/components/InstrumentAlertLog.vue +0 -4
  235. package/src/components/InstrumentStateBadge.vue +0 -4
  236. package/src/components/InstrumentStatusCard.vue +0 -4
  237. package/src/components/JobsStatusTray.story.vue +6 -10
  238. package/src/components/JobsStatusTray.vue +0 -4
  239. package/src/components/LcmsSequenceTable.vue +81 -50
  240. package/src/components/LoadingSpinner.vue +0 -4
  241. package/src/components/MobileSupportGate.vue +0 -4
  242. package/src/components/MoleculeInput.vue +0 -4
  243. package/src/components/MultiSelect.vue +0 -4
  244. package/src/components/NumberInput.vue +0 -4
  245. package/src/components/PlateMapEditor.vue +3 -14
  246. package/src/components/PluginIcon.vue +0 -4
  247. package/src/components/PluginWorkspaceView.props.ts +38 -0
  248. package/src/components/PluginWorkspaceView.vue +53 -224
  249. package/src/components/ProgressBar.vue +0 -4
  250. package/src/components/ProtocolStepEditor.vue +2 -4
  251. package/src/components/RackEditor.vue +51 -70
  252. package/src/components/ReagentEditor.vue +0 -4
  253. package/src/components/ReagentList.story.vue +18 -0
  254. package/src/components/ReagentList.vue +127 -82
  255. package/src/components/ResourceCard.vue +0 -4
  256. package/src/components/RuntimeUpdateNotice.story.vue +49 -0
  257. package/src/components/RuntimeUpdateNotice.vue +4 -4
  258. package/src/components/SampleHierarchyTree.story.vue +18 -0
  259. package/src/components/SampleHierarchyTree.vue +32 -9
  260. package/src/components/SampleLegend.vue +2 -8
  261. package/src/components/SampleSelector.drag.ts +51 -0
  262. package/src/components/SampleSelector.story.vue +6 -0
  263. package/src/components/SampleSelector.tree.ts +2 -0
  264. package/src/components/SampleSelector.vue +49 -10
  265. package/src/components/SampleSelectorGroupNode.vue +19 -0
  266. package/src/components/ScheduleCalendar.story.vue +6 -0
  267. package/src/components/ScheduleCalendar.vue +82 -7
  268. package/src/components/ScientificNumber.vue +0 -4
  269. package/src/components/SecretInput.story.vue +79 -0
  270. package/src/components/SecretInput.vue +150 -0
  271. package/src/components/SectionCard.vue +0 -4
  272. package/src/components/SegmentedControl.vue +48 -5
  273. package/src/components/SequenceInput.vue +0 -4
  274. package/src/components/SequenceProgressBar.story.vue +110 -0
  275. package/src/components/SequenceProgressBar.vue +0 -4
  276. package/src/components/SettingsModal.vue +0 -4
  277. package/src/components/Skeleton.vue +0 -4
  278. package/src/components/SmartGroupFieldRecipe.vue +8 -6
  279. package/src/components/SmartGroupManual.vue +0 -4
  280. package/src/components/StatusIndicator.vue +0 -4
  281. package/src/components/StepWizard.vue +0 -4
  282. package/src/components/TagsInput.vue +4 -6
  283. package/src/components/ThemeToggle.vue +0 -4
  284. package/src/components/TimePicker.vue +36 -7
  285. package/src/components/TimeRangeInput.vue +0 -4
  286. package/src/components/Tooltip.story.vue +3 -3
  287. package/src/components/Tooltip.vue +0 -4
  288. package/src/components/UnitInput.vue +0 -4
  289. package/src/components/WellPlate.geometry.ts +60 -1
  290. package/src/components/WellPlate.interaction.ts +44 -0
  291. package/src/components/WellPlate.story.vue +8 -0
  292. package/src/components/WellPlate.vue +53 -7
  293. package/src/components/index.ts +9 -0
  294. package/src/components/internal/AppTopBarPageSelectorInternal.vue +2 -5
  295. package/src/components/internal/AppTopBarPillNavInternal.vue +0 -4
  296. package/src/components/internal/DataStateInternal.vue +74 -0
  297. package/src/components/internal/FormSectionRenderer.vue +0 -4
  298. package/src/components/internal/WellEditPopupInternal.vue +20 -5
  299. package/src/components/internal/WorkspaceControlsInternal.vue +20 -0
  300. package/src/components/internal/WorkspaceShellInternal.vue +125 -0
  301. package/src/components/internal/WorkspaceSidebarInternal.vue +82 -0
  302. package/src/composables/controlSchemaTypes.ts +34 -0
  303. package/src/composables/experimentDesignData.ts +1 -3
  304. package/src/composables/flattenWorkspaceBindings.ts +104 -0
  305. package/src/composables/formBuilderRegistry.ts +5 -0
  306. package/src/composables/index.ts +41 -5
  307. package/src/composables/pluginWorkspaceModel.ts +182 -0
  308. package/src/composables/useAsync.ts +5 -1
  309. package/src/composables/useBioTemplatePackWorkspace.ts +15 -9
  310. package/src/composables/useBioTemplatePresetWorkspace.ts +14 -15
  311. package/src/composables/useBioTemplateWorkspace.ts +18 -43
  312. package/src/composables/useCommandHistory.ts +5 -1
  313. package/src/composables/useDropdownState.ts +35 -5
  314. package/src/composables/useEventStream.ts +326 -0
  315. package/src/composables/useFileImport.ts +2 -7
  316. package/src/composables/useFocusTrap.ts +91 -0
  317. package/src/composables/useGeneratedAnalysis.ts +46 -103
  318. package/src/composables/useJobsStatusTray.ts +1 -1
  319. package/src/composables/useListReorder.story.vue +143 -0
  320. package/src/composables/useListReorder.ts +242 -0
  321. package/src/composables/useMenuKeyboard.ts +90 -0
  322. package/src/composables/useOptimisticMutation.ts +6 -16
  323. package/src/composables/usePluginClient.ts +91 -252
  324. package/src/composables/usePluginConfig.ts +3 -1
  325. package/src/composables/usePluginWorkspace.ts +208 -0
  326. package/src/composables/useRackEditor.ts +2 -11
  327. package/src/composables/useRequestSyncState.ts +98 -28
  328. package/src/composables/useResourceCrud.ts +6 -16
  329. package/src/composables/useRovingFocus.ts +66 -0
  330. package/src/composables/useScheduleDrag.ts +37 -0
  331. package/src/composables/useWellPainting.ts +10 -30
  332. package/src/composables/useWellPlateAdapter.ts +5 -1
  333. package/src/composables/useWellPlateEditor.ts +1 -11
  334. package/src/composables/useWellPlateValidation.ts +5 -1
  335. package/src/composables/workspaceRecipes.ts +267 -0
  336. package/src/index.ts +16 -0
  337. package/src/permissions.ts +48 -9
  338. package/src/stores/experiment.ts +2 -7
  339. package/src/stores/index.ts +9 -1
  340. package/src/stores/settings.ts +93 -1
  341. package/src/styles/components/audit-trail.css +5 -5
  342. package/src/styles/components/batch-progress-list.css +7 -0
  343. package/src/styles/components/color-slider.css +2 -2
  344. package/src/styles/components/data-state.css +30 -0
  345. package/src/styles/components/dataframe.css +29 -35
  346. package/src/styles/components/experiment-data-viewer.css +4 -4
  347. package/src/styles/components/experiment-timeline.css +3 -30
  348. package/src/styles/components/form-builder.css +5 -5
  349. package/src/styles/components/lcms-sequence-table.css +16 -1
  350. package/src/styles/components/multi-select.css +1 -1
  351. package/src/styles/components/reagent-list.css +38 -31
  352. package/src/styles/components/sample-hierarchy-tree.css +5 -19
  353. package/src/styles/components/sample-selector.css +9 -2
  354. package/src/styles/components/schedule-calendar.css +8 -0
  355. package/src/styles/components/scientific-number.css +1 -1
  356. package/src/styles/components/secret-input.css +60 -0
  357. package/src/styles/components/well-plate.css +8 -0
  358. package/src/styles/index.css +9 -0
  359. package/src/styles/variables.css +29 -0
  360. package/src/templates/builderPresetControls.ts +1 -1
  361. package/src/templates/builderReadUtils.ts +1 -3
  362. package/src/templates/componentPlateHelpers.ts +3 -1
  363. package/src/templates/componentTargetResolvers.ts +1 -3
  364. package/src/templates/controlSchemaTargets.ts +1 -3
  365. package/src/templates/doseResponseAdapters.ts +2 -13
  366. package/src/templates/elisaAssayCollectionBuilder.ts +2 -2
  367. package/src/templates/plateMapBuilder.ts +2 -2
  368. package/src/templates/qpcrPlateBuilder.ts +1 -1
  369. package/src/templates/templateValidators.ts +1 -1
  370. package/src/templates/timeCourseBuilder.ts +2 -2
  371. package/src/templates/wellPlateScreenCollectionBuilder.ts +2 -2
  372. package/src/types/form-builder.ts +1 -0
  373. package/src/utils/color.ts +51 -0
  374. package/src/utils/errors.ts +29 -0
  375. package/src/utils/formModelSync.ts +1 -3
  376. package/src/utils/pluginIcon.ts +1 -3
  377. package/src/utils/pluginSecrets.ts +102 -0
  378. package/src/utils/records.ts +9 -0
  379. package/dist/EmptyState-p90quq8Z.js.map +0 -1
  380. package/dist/ExperimentPopover-tLwJ7XF4.js.map +0 -1
  381. package/dist/ExperimentSelectorModal-B6P2msT4.js.map +0 -1
  382. package/dist/SettingsModal-BW3Ar-uy.js.map +0 -1
  383. package/dist/components-DQt0tcpY.js.map +0 -1
  384. package/dist/composables/autoGroupConstants.d.ts +0 -1
  385. package/dist/composables/autoGroupGrouping.d.ts +0 -3
  386. package/dist/composables/useAutoGroupInputSources.d.ts +0 -32
  387. package/dist/composables-CkXDe7nm.js.map +0 -1
  388. package/dist/experiment-Y9Iz7KYi.js.map +0 -1
  389. package/dist/experiment-utils-CLnzPPq5.js.map +0 -1
  390. package/dist/templates/builderDefaults.d.ts +0 -1
  391. package/dist/templates/plateGeometry.d.ts +0 -4
  392. package/dist/templates-CovvRZ-9.js.map +0 -1
  393. package/dist/useApi-CDBq6z23.js.map +0 -1
  394. package/dist/useControlSchema-BhoJzWzx.js.map +0 -1
  395. package/dist/useDropdownState-DSb3BC3N.js.map +0 -1
  396. package/dist/useProtocolTemplates-DHwSveE6.js.map +0 -1
  397. package/src/__tests__/composables/useAutoGroupInputSources.test.ts +0 -127
  398. package/src/composables/autoGroupConstants.ts +0 -4
  399. package/src/composables/autoGroupGrouping.ts +0 -148
  400. package/src/composables/useAutoGroupInputSources.ts +0 -147
  401. package/src/templates/builderDefaults.ts +0 -11
  402. package/src/templates/plateGeometry.ts +0 -62
  403. /package/dist/__tests__/{composables/useAutoGroupInputSources.test.d.ts → components/DataStates.test.d.ts} +0 -0
@@ -1,11 +1,12 @@
1
- import { c as formatExperimentDate, f as BaseModal_default, m as BaseButton_default, p as useEventListener } from "./experiment-utils-CLnzPPq5.js";
2
- import { a as BaseSelect_default, i as BasePill_default, n as Skeleton_default, o as normalizeOptionInput, r as useRequestSyncState, s as BaseInput_default, t as EmptyState_default } from "./EmptyState-p90quq8Z.js";
3
- import { t as useDropdownState } from "./useDropdownState-DSb3BC3N.js";
4
- import { r as useApi } from "./useApi-CDBq6z23.js";
1
+ import { c as formatExperimentDate, f as BaseModal_default, h as BaseButton_default, m as useEventListener, p as useFocusTrap } from "./experiment-utils-DV3DrvE_.js";
2
+ import { a as BaseSelect_default, i as BasePill_default, n as useRequestSyncState, o as normalizeOptionInput, r as EmptyState_default, s as BaseInput_default, t as Skeleton_default } from "./Skeleton-DxtwJ5gt.js";
3
+ import { t as useDropdownState } from "./useDropdownState-DitCtrTT.js";
4
+ import { i as useApi, u as tryUseSettingsStore } from "./errors-_W0-LbA6.js";
5
5
  import { hasAllPermissions } from "./permissions.js";
6
- import { Fragment, Teleport, Transition, TransitionGroup, computed, createBlock, createCommentVNode, createElementBlock, createElementVNode, createStaticVNode, createTextVNode, createVNode, defineComponent, isRef, nextTick, normalizeClass, normalizeStyle, onBeforeUnmount, onMounted, onScopeDispose, onUnmounted, openBlock, reactive, ref, renderList, renderSlot, shallowRef, toDisplayString, toValue, unref, useSlots, vModelText, watch, withCtx, withDirectives, withKeys, withModifiers } from "vue";
6
+ import { Fragment, Teleport, Transition, TransitionGroup, computed, createBlock, createCommentVNode, createElementBlock, createElementVNode, createStaticVNode, createTextVNode, createVNode, defineComponent, getCurrentInstance, getCurrentScope, isRef, nextTick, normalizeClass, normalizeStyle, onBeforeUnmount, onMounted, onScopeDispose, onUnmounted, openBlock, reactive, ref, renderList, renderSlot, shallowRef, toDisplayString, toValue, unref, useId, useSlots, vModelText, watch, withCtx, withDirectives, withKeys, withModifiers } from "vue";
7
+ import { autoUpdate, computePosition, flip, offset, shift } from "@floating-ui/dom";
7
8
  //#region src/components/BaseTextarea.vue?vue&type=script&setup=true&lang.ts
8
- var _hoisted_1$21 = [
9
+ var _hoisted_1$22 = [
9
10
  "value",
10
11
  "placeholder",
11
12
  "disabled",
@@ -73,1000 +74,15 @@ var BaseTextarea_default = /* @__PURE__ */ defineComponent({
73
74
  onInput: handleInput,
74
75
  onFocus: _cache[0] || (_cache[0] = ($event) => emit("focus", $event)),
75
76
  onBlur: _cache[1] || (_cache[1] = ($event) => emit("blur", $event))
76
- }, null, 42, _hoisted_1$21);
77
+ }, null, 42, _hoisted_1$22);
77
78
  };
78
79
  }
79
80
  });
80
81
  //#endregion
81
- //#region ../../node_modules/.bun/@floating-ui+utils@0.2.11/node_modules/@floating-ui/utils/dist/floating-ui.utils.mjs
82
- var min = Math.min;
83
- var max = Math.max;
84
- var round = Math.round;
85
- var createCoords = (v) => ({
86
- x: v,
87
- y: v
88
- });
89
- var oppositeSideMap = {
90
- left: "right",
91
- right: "left",
92
- bottom: "top",
93
- top: "bottom"
94
- };
95
- function clamp(start, value, end) {
96
- return max(start, min(value, end));
97
- }
98
- function evaluate(value, param) {
99
- return typeof value === "function" ? value(param) : value;
100
- }
101
- function getSide(placement) {
102
- return placement.split("-")[0];
103
- }
104
- function getAlignment(placement) {
105
- return placement.split("-")[1];
106
- }
107
- function getOppositeAxis(axis) {
108
- return axis === "x" ? "y" : "x";
109
- }
110
- function getAxisLength(axis) {
111
- return axis === "y" ? "height" : "width";
112
- }
113
- function getSideAxis(placement) {
114
- const firstChar = placement[0];
115
- return firstChar === "t" || firstChar === "b" ? "y" : "x";
116
- }
117
- function getAlignmentAxis(placement) {
118
- return getOppositeAxis(getSideAxis(placement));
119
- }
120
- function getAlignmentSides(placement, rects, rtl) {
121
- if (rtl === void 0) rtl = false;
122
- const alignment = getAlignment(placement);
123
- const alignmentAxis = getAlignmentAxis(placement);
124
- const length = getAxisLength(alignmentAxis);
125
- let mainAlignmentSide = alignmentAxis === "x" ? alignment === (rtl ? "end" : "start") ? "right" : "left" : alignment === "start" ? "bottom" : "top";
126
- if (rects.reference[length] > rects.floating[length]) mainAlignmentSide = getOppositePlacement(mainAlignmentSide);
127
- return [mainAlignmentSide, getOppositePlacement(mainAlignmentSide)];
128
- }
129
- function getExpandedPlacements(placement) {
130
- const oppositePlacement = getOppositePlacement(placement);
131
- return [
132
- getOppositeAlignmentPlacement(placement),
133
- oppositePlacement,
134
- getOppositeAlignmentPlacement(oppositePlacement)
135
- ];
136
- }
137
- function getOppositeAlignmentPlacement(placement) {
138
- return placement.includes("start") ? placement.replace("start", "end") : placement.replace("end", "start");
139
- }
140
- var lrPlacement = ["left", "right"];
141
- var rlPlacement = ["right", "left"];
142
- var tbPlacement = ["top", "bottom"];
143
- var btPlacement = ["bottom", "top"];
144
- function getSideList(side, isStart, rtl) {
145
- switch (side) {
146
- case "top":
147
- case "bottom":
148
- if (rtl) return isStart ? rlPlacement : lrPlacement;
149
- return isStart ? lrPlacement : rlPlacement;
150
- case "left":
151
- case "right": return isStart ? tbPlacement : btPlacement;
152
- default: return [];
153
- }
154
- }
155
- function getOppositeAxisPlacements(placement, flipAlignment, direction, rtl) {
156
- const alignment = getAlignment(placement);
157
- let list = getSideList(getSide(placement), direction === "start", rtl);
158
- if (alignment) {
159
- list = list.map((side) => side + "-" + alignment);
160
- if (flipAlignment) list = list.concat(list.map(getOppositeAlignmentPlacement));
161
- }
162
- return list;
163
- }
164
- function getOppositePlacement(placement) {
165
- const side = getSide(placement);
166
- return oppositeSideMap[side] + placement.slice(side.length);
167
- }
168
- function expandPaddingObject(padding) {
169
- return {
170
- top: 0,
171
- right: 0,
172
- bottom: 0,
173
- left: 0,
174
- ...padding
175
- };
176
- }
177
- function getPaddingObject(padding) {
178
- return typeof padding !== "number" ? expandPaddingObject(padding) : {
179
- top: padding,
180
- right: padding,
181
- bottom: padding,
182
- left: padding
183
- };
184
- }
185
- function rectToClientRect(rect) {
186
- const { x, y, width, height } = rect;
187
- return {
188
- width,
189
- height,
190
- top: y,
191
- left: x,
192
- right: x + width,
193
- bottom: y + height,
194
- x,
195
- y
196
- };
197
- }
198
- //#endregion
199
- //#region ../../node_modules/.bun/@floating-ui+core@1.7.5/node_modules/@floating-ui/core/dist/floating-ui.core.mjs
200
- function computeCoordsFromPlacement(_ref, placement, rtl) {
201
- let { reference, floating } = _ref;
202
- const sideAxis = getSideAxis(placement);
203
- const alignmentAxis = getAlignmentAxis(placement);
204
- const alignLength = getAxisLength(alignmentAxis);
205
- const side = getSide(placement);
206
- const isVertical = sideAxis === "y";
207
- const commonX = reference.x + reference.width / 2 - floating.width / 2;
208
- const commonY = reference.y + reference.height / 2 - floating.height / 2;
209
- const commonAlign = reference[alignLength] / 2 - floating[alignLength] / 2;
210
- let coords;
211
- switch (side) {
212
- case "top":
213
- coords = {
214
- x: commonX,
215
- y: reference.y - floating.height
216
- };
217
- break;
218
- case "bottom":
219
- coords = {
220
- x: commonX,
221
- y: reference.y + reference.height
222
- };
223
- break;
224
- case "right":
225
- coords = {
226
- x: reference.x + reference.width,
227
- y: commonY
228
- };
229
- break;
230
- case "left":
231
- coords = {
232
- x: reference.x - floating.width,
233
- y: commonY
234
- };
235
- break;
236
- default: coords = {
237
- x: reference.x,
238
- y: reference.y
239
- };
240
- }
241
- switch (getAlignment(placement)) {
242
- case "start":
243
- coords[alignmentAxis] -= commonAlign * (rtl && isVertical ? -1 : 1);
244
- break;
245
- case "end":
246
- coords[alignmentAxis] += commonAlign * (rtl && isVertical ? -1 : 1);
247
- break;
248
- }
249
- return coords;
250
- }
251
- /**
252
- * Resolves with an object of overflow side offsets that determine how much the
253
- * element is overflowing a given clipping boundary on each side.
254
- * - positive = overflowing the boundary by that number of pixels
255
- * - negative = how many pixels left before it will overflow
256
- * - 0 = lies flush with the boundary
257
- * @see https://floating-ui.com/docs/detectOverflow
258
- */
259
- async function detectOverflow(state, options) {
260
- var _await$platform$isEle;
261
- if (options === void 0) options = {};
262
- const { x, y, platform, rects, elements, strategy } = state;
263
- const { boundary = "clippingAncestors", rootBoundary = "viewport", elementContext = "floating", altBoundary = false, padding = 0 } = evaluate(options, state);
264
- const paddingObject = getPaddingObject(padding);
265
- const element = elements[altBoundary ? elementContext === "floating" ? "reference" : "floating" : elementContext];
266
- const clippingClientRect = rectToClientRect(await platform.getClippingRect({
267
- element: ((_await$platform$isEle = await (platform.isElement == null ? void 0 : platform.isElement(element))) != null ? _await$platform$isEle : true) ? element : element.contextElement || await (platform.getDocumentElement == null ? void 0 : platform.getDocumentElement(elements.floating)),
268
- boundary,
269
- rootBoundary,
270
- strategy
271
- }));
272
- const rect = elementContext === "floating" ? {
273
- x,
274
- y,
275
- width: rects.floating.width,
276
- height: rects.floating.height
277
- } : rects.reference;
278
- const offsetParent = await (platform.getOffsetParent == null ? void 0 : platform.getOffsetParent(elements.floating));
279
- const offsetScale = await (platform.isElement == null ? void 0 : platform.isElement(offsetParent)) ? await (platform.getScale == null ? void 0 : platform.getScale(offsetParent)) || {
280
- x: 1,
281
- y: 1
282
- } : {
283
- x: 1,
284
- y: 1
285
- };
286
- const elementClientRect = rectToClientRect(platform.convertOffsetParentRelativeRectToViewportRelativeRect ? await platform.convertOffsetParentRelativeRectToViewportRelativeRect({
287
- elements,
288
- rect,
289
- offsetParent,
290
- strategy
291
- }) : rect);
292
- return {
293
- top: (clippingClientRect.top - elementClientRect.top + paddingObject.top) / offsetScale.y,
294
- bottom: (elementClientRect.bottom - clippingClientRect.bottom + paddingObject.bottom) / offsetScale.y,
295
- left: (clippingClientRect.left - elementClientRect.left + paddingObject.left) / offsetScale.x,
296
- right: (elementClientRect.right - clippingClientRect.right + paddingObject.right) / offsetScale.x
297
- };
298
- }
299
- var MAX_RESET_COUNT = 50;
300
- /**
301
- * Computes the `x` and `y` coordinates that will place the floating element
302
- * next to a given reference element.
303
- *
304
- * This export does not have any `platform` interface logic. You will need to
305
- * write one for the platform you are using Floating UI with.
306
- */
307
- var computePosition$1 = async (reference, floating, config) => {
308
- const { placement = "bottom", strategy = "absolute", middleware = [], platform } = config;
309
- const platformWithDetectOverflow = platform.detectOverflow ? platform : {
310
- ...platform,
311
- detectOverflow
312
- };
313
- const rtl = await (platform.isRTL == null ? void 0 : platform.isRTL(floating));
314
- let rects = await platform.getElementRects({
315
- reference,
316
- floating,
317
- strategy
318
- });
319
- let { x, y } = computeCoordsFromPlacement(rects, placement, rtl);
320
- let statefulPlacement = placement;
321
- let resetCount = 0;
322
- const middlewareData = {};
323
- for (let i = 0; i < middleware.length; i++) {
324
- const currentMiddleware = middleware[i];
325
- if (!currentMiddleware) continue;
326
- const { name, fn } = currentMiddleware;
327
- const { x: nextX, y: nextY, data, reset } = await fn({
328
- x,
329
- y,
330
- initialPlacement: placement,
331
- placement: statefulPlacement,
332
- strategy,
333
- middlewareData,
334
- rects,
335
- platform: platformWithDetectOverflow,
336
- elements: {
337
- reference,
338
- floating
339
- }
340
- });
341
- x = nextX != null ? nextX : x;
342
- y = nextY != null ? nextY : y;
343
- middlewareData[name] = {
344
- ...middlewareData[name],
345
- ...data
346
- };
347
- if (reset && resetCount < MAX_RESET_COUNT) {
348
- resetCount++;
349
- if (typeof reset === "object") {
350
- if (reset.placement) statefulPlacement = reset.placement;
351
- if (reset.rects) rects = reset.rects === true ? await platform.getElementRects({
352
- reference,
353
- floating,
354
- strategy
355
- }) : reset.rects;
356
- ({x, y} = computeCoordsFromPlacement(rects, statefulPlacement, rtl));
357
- }
358
- i = -1;
359
- }
360
- }
361
- return {
362
- x,
363
- y,
364
- placement: statefulPlacement,
365
- strategy,
366
- middlewareData
367
- };
368
- };
369
- /**
370
- * Optimizes the visibility of the floating element by flipping the `placement`
371
- * in order to keep it in view when the preferred placement(s) will overflow the
372
- * clipping boundary. Alternative to `autoPlacement`.
373
- * @see https://floating-ui.com/docs/flip
374
- */
375
- var flip$1 = function(options) {
376
- if (options === void 0) options = {};
377
- return {
378
- name: "flip",
379
- options,
380
- async fn(state) {
381
- var _middlewareData$arrow, _middlewareData$flip;
382
- const { placement, middlewareData, rects, initialPlacement, platform, elements } = state;
383
- const { mainAxis: checkMainAxis = true, crossAxis: checkCrossAxis = true, fallbackPlacements: specifiedFallbackPlacements, fallbackStrategy = "bestFit", fallbackAxisSideDirection = "none", flipAlignment = true, ...detectOverflowOptions } = evaluate(options, state);
384
- if ((_middlewareData$arrow = middlewareData.arrow) != null && _middlewareData$arrow.alignmentOffset) return {};
385
- const side = getSide(placement);
386
- const initialSideAxis = getSideAxis(initialPlacement);
387
- const isBasePlacement = getSide(initialPlacement) === initialPlacement;
388
- const rtl = await (platform.isRTL == null ? void 0 : platform.isRTL(elements.floating));
389
- const fallbackPlacements = specifiedFallbackPlacements || (isBasePlacement || !flipAlignment ? [getOppositePlacement(initialPlacement)] : getExpandedPlacements(initialPlacement));
390
- const hasFallbackAxisSideDirection = fallbackAxisSideDirection !== "none";
391
- if (!specifiedFallbackPlacements && hasFallbackAxisSideDirection) fallbackPlacements.push(...getOppositeAxisPlacements(initialPlacement, flipAlignment, fallbackAxisSideDirection, rtl));
392
- const placements = [initialPlacement, ...fallbackPlacements];
393
- const overflow = await platform.detectOverflow(state, detectOverflowOptions);
394
- const overflows = [];
395
- let overflowsData = ((_middlewareData$flip = middlewareData.flip) == null ? void 0 : _middlewareData$flip.overflows) || [];
396
- if (checkMainAxis) overflows.push(overflow[side]);
397
- if (checkCrossAxis) {
398
- const sides = getAlignmentSides(placement, rects, rtl);
399
- overflows.push(overflow[sides[0]], overflow[sides[1]]);
400
- }
401
- overflowsData = [...overflowsData, {
402
- placement,
403
- overflows
404
- }];
405
- if (!overflows.every((side) => side <= 0)) {
406
- var _middlewareData$flip2, _overflowsData$filter;
407
- const nextIndex = (((_middlewareData$flip2 = middlewareData.flip) == null ? void 0 : _middlewareData$flip2.index) || 0) + 1;
408
- const nextPlacement = placements[nextIndex];
409
- if (nextPlacement) {
410
- if (!(checkCrossAxis === "alignment" ? initialSideAxis !== getSideAxis(nextPlacement) : false) || overflowsData.every((d) => getSideAxis(d.placement) === initialSideAxis ? d.overflows[0] > 0 : true)) return {
411
- data: {
412
- index: nextIndex,
413
- overflows: overflowsData
414
- },
415
- reset: { placement: nextPlacement }
416
- };
417
- }
418
- let resetPlacement = (_overflowsData$filter = overflowsData.filter((d) => d.overflows[0] <= 0).sort((a, b) => a.overflows[1] - b.overflows[1])[0]) == null ? void 0 : _overflowsData$filter.placement;
419
- if (!resetPlacement) switch (fallbackStrategy) {
420
- case "bestFit": {
421
- var _overflowsData$filter2;
422
- const placement = (_overflowsData$filter2 = overflowsData.filter((d) => {
423
- if (hasFallbackAxisSideDirection) {
424
- const currentSideAxis = getSideAxis(d.placement);
425
- return currentSideAxis === initialSideAxis || currentSideAxis === "y";
426
- }
427
- return true;
428
- }).map((d) => [d.placement, d.overflows.filter((overflow) => overflow > 0).reduce((acc, overflow) => acc + overflow, 0)]).sort((a, b) => a[1] - b[1])[0]) == null ? void 0 : _overflowsData$filter2[0];
429
- if (placement) resetPlacement = placement;
430
- break;
431
- }
432
- case "initialPlacement":
433
- resetPlacement = initialPlacement;
434
- break;
435
- }
436
- if (placement !== resetPlacement) return { reset: { placement: resetPlacement } };
437
- }
438
- return {};
439
- }
440
- };
441
- };
442
- var originSides = /* @__PURE__ */ new Set(["left", "top"]);
443
- async function convertValueToCoords(state, options) {
444
- const { placement, platform, elements } = state;
445
- const rtl = await (platform.isRTL == null ? void 0 : platform.isRTL(elements.floating));
446
- const side = getSide(placement);
447
- const alignment = getAlignment(placement);
448
- const isVertical = getSideAxis(placement) === "y";
449
- const mainAxisMulti = originSides.has(side) ? -1 : 1;
450
- const crossAxisMulti = rtl && isVertical ? -1 : 1;
451
- const rawValue = evaluate(options, state);
452
- let { mainAxis, crossAxis, alignmentAxis } = typeof rawValue === "number" ? {
453
- mainAxis: rawValue,
454
- crossAxis: 0,
455
- alignmentAxis: null
456
- } : {
457
- mainAxis: rawValue.mainAxis || 0,
458
- crossAxis: rawValue.crossAxis || 0,
459
- alignmentAxis: rawValue.alignmentAxis
460
- };
461
- if (alignment && typeof alignmentAxis === "number") crossAxis = alignment === "end" ? alignmentAxis * -1 : alignmentAxis;
462
- return isVertical ? {
463
- x: crossAxis * crossAxisMulti,
464
- y: mainAxis * mainAxisMulti
465
- } : {
466
- x: mainAxis * mainAxisMulti,
467
- y: crossAxis * crossAxisMulti
468
- };
469
- }
470
- /**
471
- * Modifies the placement by translating the floating element along the
472
- * specified axes.
473
- * A number (shorthand for `mainAxis` or distance), or an axes configuration
474
- * object may be passed.
475
- * @see https://floating-ui.com/docs/offset
476
- */
477
- var offset$1 = function(options) {
478
- if (options === void 0) options = 0;
479
- return {
480
- name: "offset",
481
- options,
482
- async fn(state) {
483
- var _middlewareData$offse, _middlewareData$arrow;
484
- const { x, y, placement, middlewareData } = state;
485
- const diffCoords = await convertValueToCoords(state, options);
486
- if (placement === ((_middlewareData$offse = middlewareData.offset) == null ? void 0 : _middlewareData$offse.placement) && (_middlewareData$arrow = middlewareData.arrow) != null && _middlewareData$arrow.alignmentOffset) return {};
487
- return {
488
- x: x + diffCoords.x,
489
- y: y + diffCoords.y,
490
- data: {
491
- ...diffCoords,
492
- placement
493
- }
494
- };
495
- }
496
- };
497
- };
498
- /**
499
- * Optimizes the visibility of the floating element by shifting it in order to
500
- * keep it in view when it will overflow the clipping boundary.
501
- * @see https://floating-ui.com/docs/shift
502
- */
503
- var shift$1 = function(options) {
504
- if (options === void 0) options = {};
505
- return {
506
- name: "shift",
507
- options,
508
- async fn(state) {
509
- const { x, y, placement, platform } = state;
510
- const { mainAxis: checkMainAxis = true, crossAxis: checkCrossAxis = false, limiter = { fn: (_ref) => {
511
- let { x, y } = _ref;
512
- return {
513
- x,
514
- y
515
- };
516
- } }, ...detectOverflowOptions } = evaluate(options, state);
517
- const coords = {
518
- x,
519
- y
520
- };
521
- const overflow = await platform.detectOverflow(state, detectOverflowOptions);
522
- const crossAxis = getSideAxis(getSide(placement));
523
- const mainAxis = getOppositeAxis(crossAxis);
524
- let mainAxisCoord = coords[mainAxis];
525
- let crossAxisCoord = coords[crossAxis];
526
- if (checkMainAxis) {
527
- const minSide = mainAxis === "y" ? "top" : "left";
528
- const maxSide = mainAxis === "y" ? "bottom" : "right";
529
- const min = mainAxisCoord + overflow[minSide];
530
- const max = mainAxisCoord - overflow[maxSide];
531
- mainAxisCoord = clamp(min, mainAxisCoord, max);
532
- }
533
- if (checkCrossAxis) {
534
- const minSide = crossAxis === "y" ? "top" : "left";
535
- const maxSide = crossAxis === "y" ? "bottom" : "right";
536
- const min = crossAxisCoord + overflow[minSide];
537
- const max = crossAxisCoord - overflow[maxSide];
538
- crossAxisCoord = clamp(min, crossAxisCoord, max);
539
- }
540
- const limitedCoords = limiter.fn({
541
- ...state,
542
- [mainAxis]: mainAxisCoord,
543
- [crossAxis]: crossAxisCoord
544
- });
545
- return {
546
- ...limitedCoords,
547
- data: {
548
- x: limitedCoords.x - x,
549
- y: limitedCoords.y - y,
550
- enabled: {
551
- [mainAxis]: checkMainAxis,
552
- [crossAxis]: checkCrossAxis
553
- }
554
- }
555
- };
556
- }
557
- };
558
- };
559
- //#endregion
560
- //#region ../../node_modules/.bun/@floating-ui+utils@0.2.11/node_modules/@floating-ui/utils/dist/floating-ui.utils.dom.mjs
561
- function hasWindow() {
562
- return typeof window !== "undefined";
563
- }
564
- function getNodeName(node) {
565
- if (isNode(node)) return (node.nodeName || "").toLowerCase();
566
- return "#document";
567
- }
568
- function getWindow(node) {
569
- var _node$ownerDocument;
570
- return (node == null || (_node$ownerDocument = node.ownerDocument) == null ? void 0 : _node$ownerDocument.defaultView) || window;
571
- }
572
- function getDocumentElement(node) {
573
- var _ref;
574
- return (_ref = (isNode(node) ? node.ownerDocument : node.document) || window.document) == null ? void 0 : _ref.documentElement;
575
- }
576
- function isNode(value) {
577
- if (!hasWindow()) return false;
578
- return value instanceof Node || value instanceof getWindow(value).Node;
579
- }
580
- function isElement(value) {
581
- if (!hasWindow()) return false;
582
- return value instanceof Element || value instanceof getWindow(value).Element;
583
- }
584
- function isHTMLElement(value) {
585
- if (!hasWindow()) return false;
586
- return value instanceof HTMLElement || value instanceof getWindow(value).HTMLElement;
587
- }
588
- function isShadowRoot(value) {
589
- if (!hasWindow() || typeof ShadowRoot === "undefined") return false;
590
- return value instanceof ShadowRoot || value instanceof getWindow(value).ShadowRoot;
591
- }
592
- function isOverflowElement(element) {
593
- const { overflow, overflowX, overflowY, display } = getComputedStyle$1(element);
594
- return /auto|scroll|overlay|hidden|clip/.test(overflow + overflowY + overflowX) && display !== "inline" && display !== "contents";
595
- }
596
- function isTableElement(element) {
597
- return /^(table|td|th)$/.test(getNodeName(element));
598
- }
599
- function isTopLayer(element) {
600
- try {
601
- if (element.matches(":popover-open")) return true;
602
- } catch (_e) {}
603
- try {
604
- return element.matches(":modal");
605
- } catch (_e) {
606
- return false;
607
- }
608
- }
609
- var willChangeRe = /transform|translate|scale|rotate|perspective|filter/;
610
- var containRe = /paint|layout|strict|content/;
611
- var isNotNone = (value) => !!value && value !== "none";
612
- var isWebKitValue;
613
- function isContainingBlock(elementOrCss) {
614
- const css = isElement(elementOrCss) ? getComputedStyle$1(elementOrCss) : elementOrCss;
615
- return isNotNone(css.transform) || isNotNone(css.translate) || isNotNone(css.scale) || isNotNone(css.rotate) || isNotNone(css.perspective) || !isWebKit() && (isNotNone(css.backdropFilter) || isNotNone(css.filter)) || willChangeRe.test(css.willChange || "") || containRe.test(css.contain || "");
616
- }
617
- function getContainingBlock(element) {
618
- let currentNode = getParentNode(element);
619
- while (isHTMLElement(currentNode) && !isLastTraversableNode(currentNode)) {
620
- if (isContainingBlock(currentNode)) return currentNode;
621
- else if (isTopLayer(currentNode)) return null;
622
- currentNode = getParentNode(currentNode);
623
- }
624
- return null;
625
- }
626
- function isWebKit() {
627
- if (isWebKitValue == null) isWebKitValue = typeof CSS !== "undefined" && CSS.supports && CSS.supports("-webkit-backdrop-filter", "none");
628
- return isWebKitValue;
629
- }
630
- function isLastTraversableNode(node) {
631
- return /^(html|body|#document)$/.test(getNodeName(node));
632
- }
633
- function getComputedStyle$1(element) {
634
- return getWindow(element).getComputedStyle(element);
635
- }
636
- function getNodeScroll(element) {
637
- if (isElement(element)) return {
638
- scrollLeft: element.scrollLeft,
639
- scrollTop: element.scrollTop
640
- };
641
- return {
642
- scrollLeft: element.scrollX,
643
- scrollTop: element.scrollY
644
- };
645
- }
646
- function getParentNode(node) {
647
- if (getNodeName(node) === "html") return node;
648
- const result = node.assignedSlot || node.parentNode || isShadowRoot(node) && node.host || getDocumentElement(node);
649
- return isShadowRoot(result) ? result.host : result;
650
- }
651
- function getNearestOverflowAncestor(node) {
652
- const parentNode = getParentNode(node);
653
- if (isLastTraversableNode(parentNode)) return node.ownerDocument ? node.ownerDocument.body : node.body;
654
- if (isHTMLElement(parentNode) && isOverflowElement(parentNode)) return parentNode;
655
- return getNearestOverflowAncestor(parentNode);
656
- }
657
- function getOverflowAncestors(node, list, traverseIframes) {
658
- var _node$ownerDocument2;
659
- if (list === void 0) list = [];
660
- if (traverseIframes === void 0) traverseIframes = true;
661
- const scrollableAncestor = getNearestOverflowAncestor(node);
662
- const isBody = scrollableAncestor === ((_node$ownerDocument2 = node.ownerDocument) == null ? void 0 : _node$ownerDocument2.body);
663
- const win = getWindow(scrollableAncestor);
664
- if (isBody) {
665
- const frameElement = getFrameElement(win);
666
- return list.concat(win, win.visualViewport || [], isOverflowElement(scrollableAncestor) ? scrollableAncestor : [], frameElement && traverseIframes ? getOverflowAncestors(frameElement) : []);
667
- } else return list.concat(scrollableAncestor, getOverflowAncestors(scrollableAncestor, [], traverseIframes));
668
- }
669
- function getFrameElement(win) {
670
- return win.parent && Object.getPrototypeOf(win.parent) ? win.frameElement : null;
671
- }
672
- //#endregion
673
- //#region ../../node_modules/.bun/@floating-ui+dom@1.7.6/node_modules/@floating-ui/dom/dist/floating-ui.dom.mjs
674
- function getCssDimensions(element) {
675
- const css = getComputedStyle$1(element);
676
- let width = parseFloat(css.width) || 0;
677
- let height = parseFloat(css.height) || 0;
678
- const hasOffset = isHTMLElement(element);
679
- const offsetWidth = hasOffset ? element.offsetWidth : width;
680
- const offsetHeight = hasOffset ? element.offsetHeight : height;
681
- const shouldFallback = round(width) !== offsetWidth || round(height) !== offsetHeight;
682
- if (shouldFallback) {
683
- width = offsetWidth;
684
- height = offsetHeight;
685
- }
686
- return {
687
- width,
688
- height,
689
- $: shouldFallback
690
- };
691
- }
692
- function unwrapElement(element) {
693
- return !isElement(element) ? element.contextElement : element;
694
- }
695
- function getScale(element) {
696
- const domElement = unwrapElement(element);
697
- if (!isHTMLElement(domElement)) return createCoords(1);
698
- const rect = domElement.getBoundingClientRect();
699
- const { width, height, $ } = getCssDimensions(domElement);
700
- let x = ($ ? round(rect.width) : rect.width) / width;
701
- let y = ($ ? round(rect.height) : rect.height) / height;
702
- if (!x || !Number.isFinite(x)) x = 1;
703
- if (!y || !Number.isFinite(y)) y = 1;
704
- return {
705
- x,
706
- y
707
- };
708
- }
709
- var noOffsets = /* @__PURE__ */ createCoords(0);
710
- function getVisualOffsets(element) {
711
- const win = getWindow(element);
712
- if (!isWebKit() || !win.visualViewport) return noOffsets;
713
- return {
714
- x: win.visualViewport.offsetLeft,
715
- y: win.visualViewport.offsetTop
716
- };
717
- }
718
- function shouldAddVisualOffsets(element, isFixed, floatingOffsetParent) {
719
- if (isFixed === void 0) isFixed = false;
720
- if (!floatingOffsetParent || isFixed && floatingOffsetParent !== getWindow(element)) return false;
721
- return isFixed;
722
- }
723
- function getBoundingClientRect(element, includeScale, isFixedStrategy, offsetParent) {
724
- if (includeScale === void 0) includeScale = false;
725
- if (isFixedStrategy === void 0) isFixedStrategy = false;
726
- const clientRect = element.getBoundingClientRect();
727
- const domElement = unwrapElement(element);
728
- let scale = createCoords(1);
729
- if (includeScale) if (offsetParent) {
730
- if (isElement(offsetParent)) scale = getScale(offsetParent);
731
- } else scale = getScale(element);
732
- const visualOffsets = shouldAddVisualOffsets(domElement, isFixedStrategy, offsetParent) ? getVisualOffsets(domElement) : createCoords(0);
733
- let x = (clientRect.left + visualOffsets.x) / scale.x;
734
- let y = (clientRect.top + visualOffsets.y) / scale.y;
735
- let width = clientRect.width / scale.x;
736
- let height = clientRect.height / scale.y;
737
- if (domElement) {
738
- const win = getWindow(domElement);
739
- const offsetWin = offsetParent && isElement(offsetParent) ? getWindow(offsetParent) : offsetParent;
740
- let currentWin = win;
741
- let currentIFrame = getFrameElement(currentWin);
742
- while (currentIFrame && offsetParent && offsetWin !== currentWin) {
743
- const iframeScale = getScale(currentIFrame);
744
- const iframeRect = currentIFrame.getBoundingClientRect();
745
- const css = getComputedStyle$1(currentIFrame);
746
- const left = iframeRect.left + (currentIFrame.clientLeft + parseFloat(css.paddingLeft)) * iframeScale.x;
747
- const top = iframeRect.top + (currentIFrame.clientTop + parseFloat(css.paddingTop)) * iframeScale.y;
748
- x *= iframeScale.x;
749
- y *= iframeScale.y;
750
- width *= iframeScale.x;
751
- height *= iframeScale.y;
752
- x += left;
753
- y += top;
754
- currentWin = getWindow(currentIFrame);
755
- currentIFrame = getFrameElement(currentWin);
756
- }
757
- }
758
- return rectToClientRect({
759
- width,
760
- height,
761
- x,
762
- y
763
- });
764
- }
765
- function getWindowScrollBarX(element, rect) {
766
- const leftScroll = getNodeScroll(element).scrollLeft;
767
- if (!rect) return getBoundingClientRect(getDocumentElement(element)).left + leftScroll;
768
- return rect.left + leftScroll;
769
- }
770
- function getHTMLOffset(documentElement, scroll) {
771
- const htmlRect = documentElement.getBoundingClientRect();
772
- return {
773
- x: htmlRect.left + scroll.scrollLeft - getWindowScrollBarX(documentElement, htmlRect),
774
- y: htmlRect.top + scroll.scrollTop
775
- };
776
- }
777
- function convertOffsetParentRelativeRectToViewportRelativeRect(_ref) {
778
- let { elements, rect, offsetParent, strategy } = _ref;
779
- const isFixed = strategy === "fixed";
780
- const documentElement = getDocumentElement(offsetParent);
781
- const topLayer = elements ? isTopLayer(elements.floating) : false;
782
- if (offsetParent === documentElement || topLayer && isFixed) return rect;
783
- let scroll = {
784
- scrollLeft: 0,
785
- scrollTop: 0
786
- };
787
- let scale = createCoords(1);
788
- const offsets = createCoords(0);
789
- const isOffsetParentAnElement = isHTMLElement(offsetParent);
790
- if (isOffsetParentAnElement || !isOffsetParentAnElement && !isFixed) {
791
- if (getNodeName(offsetParent) !== "body" || isOverflowElement(documentElement)) scroll = getNodeScroll(offsetParent);
792
- if (isOffsetParentAnElement) {
793
- const offsetRect = getBoundingClientRect(offsetParent);
794
- scale = getScale(offsetParent);
795
- offsets.x = offsetRect.x + offsetParent.clientLeft;
796
- offsets.y = offsetRect.y + offsetParent.clientTop;
797
- }
798
- }
799
- const htmlOffset = documentElement && !isOffsetParentAnElement && !isFixed ? getHTMLOffset(documentElement, scroll) : createCoords(0);
800
- return {
801
- width: rect.width * scale.x,
802
- height: rect.height * scale.y,
803
- x: rect.x * scale.x - scroll.scrollLeft * scale.x + offsets.x + htmlOffset.x,
804
- y: rect.y * scale.y - scroll.scrollTop * scale.y + offsets.y + htmlOffset.y
805
- };
806
- }
807
- function getClientRects(element) {
808
- return Array.from(element.getClientRects());
809
- }
810
- function getDocumentRect(element) {
811
- const html = getDocumentElement(element);
812
- const scroll = getNodeScroll(element);
813
- const body = element.ownerDocument.body;
814
- const width = max(html.scrollWidth, html.clientWidth, body.scrollWidth, body.clientWidth);
815
- const height = max(html.scrollHeight, html.clientHeight, body.scrollHeight, body.clientHeight);
816
- let x = -scroll.scrollLeft + getWindowScrollBarX(element);
817
- const y = -scroll.scrollTop;
818
- if (getComputedStyle$1(body).direction === "rtl") x += max(html.clientWidth, body.clientWidth) - width;
819
- return {
820
- width,
821
- height,
822
- x,
823
- y
824
- };
825
- }
826
- var SCROLLBAR_MAX = 25;
827
- function getViewportRect(element, strategy) {
828
- const win = getWindow(element);
829
- const html = getDocumentElement(element);
830
- const visualViewport = win.visualViewport;
831
- let width = html.clientWidth;
832
- let height = html.clientHeight;
833
- let x = 0;
834
- let y = 0;
835
- if (visualViewport) {
836
- width = visualViewport.width;
837
- height = visualViewport.height;
838
- const visualViewportBased = isWebKit();
839
- if (!visualViewportBased || visualViewportBased && strategy === "fixed") {
840
- x = visualViewport.offsetLeft;
841
- y = visualViewport.offsetTop;
842
- }
843
- }
844
- const windowScrollbarX = getWindowScrollBarX(html);
845
- if (windowScrollbarX <= 0) {
846
- const doc = html.ownerDocument;
847
- const body = doc.body;
848
- const bodyStyles = getComputedStyle(body);
849
- const bodyMarginInline = doc.compatMode === "CSS1Compat" ? parseFloat(bodyStyles.marginLeft) + parseFloat(bodyStyles.marginRight) || 0 : 0;
850
- const clippingStableScrollbarWidth = Math.abs(html.clientWidth - body.clientWidth - bodyMarginInline);
851
- if (clippingStableScrollbarWidth <= SCROLLBAR_MAX) width -= clippingStableScrollbarWidth;
852
- } else if (windowScrollbarX <= SCROLLBAR_MAX) width += windowScrollbarX;
853
- return {
854
- width,
855
- height,
856
- x,
857
- y
858
- };
859
- }
860
- function getInnerBoundingClientRect(element, strategy) {
861
- const clientRect = getBoundingClientRect(element, true, strategy === "fixed");
862
- const top = clientRect.top + element.clientTop;
863
- const left = clientRect.left + element.clientLeft;
864
- const scale = isHTMLElement(element) ? getScale(element) : createCoords(1);
865
- return {
866
- width: element.clientWidth * scale.x,
867
- height: element.clientHeight * scale.y,
868
- x: left * scale.x,
869
- y: top * scale.y
870
- };
871
- }
872
- function getClientRectFromClippingAncestor(element, clippingAncestor, strategy) {
873
- let rect;
874
- if (clippingAncestor === "viewport") rect = getViewportRect(element, strategy);
875
- else if (clippingAncestor === "document") rect = getDocumentRect(getDocumentElement(element));
876
- else if (isElement(clippingAncestor)) rect = getInnerBoundingClientRect(clippingAncestor, strategy);
877
- else {
878
- const visualOffsets = getVisualOffsets(element);
879
- rect = {
880
- x: clippingAncestor.x - visualOffsets.x,
881
- y: clippingAncestor.y - visualOffsets.y,
882
- width: clippingAncestor.width,
883
- height: clippingAncestor.height
884
- };
885
- }
886
- return rectToClientRect(rect);
887
- }
888
- function hasFixedPositionAncestor(element, stopNode) {
889
- const parentNode = getParentNode(element);
890
- if (parentNode === stopNode || !isElement(parentNode) || isLastTraversableNode(parentNode)) return false;
891
- return getComputedStyle$1(parentNode).position === "fixed" || hasFixedPositionAncestor(parentNode, stopNode);
892
- }
893
- function getClippingElementAncestors(element, cache) {
894
- const cachedResult = cache.get(element);
895
- if (cachedResult) return cachedResult;
896
- let result = getOverflowAncestors(element, [], false).filter((el) => isElement(el) && getNodeName(el) !== "body");
897
- let currentContainingBlockComputedStyle = null;
898
- const elementIsFixed = getComputedStyle$1(element).position === "fixed";
899
- let currentNode = elementIsFixed ? getParentNode(element) : element;
900
- while (isElement(currentNode) && !isLastTraversableNode(currentNode)) {
901
- const computedStyle = getComputedStyle$1(currentNode);
902
- const currentNodeIsContaining = isContainingBlock(currentNode);
903
- if (!currentNodeIsContaining && computedStyle.position === "fixed") currentContainingBlockComputedStyle = null;
904
- if (elementIsFixed ? !currentNodeIsContaining && !currentContainingBlockComputedStyle : !currentNodeIsContaining && computedStyle.position === "static" && !!currentContainingBlockComputedStyle && (currentContainingBlockComputedStyle.position === "absolute" || currentContainingBlockComputedStyle.position === "fixed") || isOverflowElement(currentNode) && !currentNodeIsContaining && hasFixedPositionAncestor(element, currentNode)) result = result.filter((ancestor) => ancestor !== currentNode);
905
- else currentContainingBlockComputedStyle = computedStyle;
906
- currentNode = getParentNode(currentNode);
907
- }
908
- cache.set(element, result);
909
- return result;
910
- }
911
- function getClippingRect(_ref) {
912
- let { element, boundary, rootBoundary, strategy } = _ref;
913
- const clippingAncestors = [...boundary === "clippingAncestors" ? isTopLayer(element) ? [] : getClippingElementAncestors(element, this._c) : [].concat(boundary), rootBoundary];
914
- const firstRect = getClientRectFromClippingAncestor(element, clippingAncestors[0], strategy);
915
- let top = firstRect.top;
916
- let right = firstRect.right;
917
- let bottom = firstRect.bottom;
918
- let left = firstRect.left;
919
- for (let i = 1; i < clippingAncestors.length; i++) {
920
- const rect = getClientRectFromClippingAncestor(element, clippingAncestors[i], strategy);
921
- top = max(rect.top, top);
922
- right = min(rect.right, right);
923
- bottom = min(rect.bottom, bottom);
924
- left = max(rect.left, left);
925
- }
926
- return {
927
- width: right - left,
928
- height: bottom - top,
929
- x: left,
930
- y: top
931
- };
932
- }
933
- function getDimensions(element) {
934
- const { width, height } = getCssDimensions(element);
935
- return {
936
- width,
937
- height
938
- };
939
- }
940
- function getRectRelativeToOffsetParent(element, offsetParent, strategy) {
941
- const isOffsetParentAnElement = isHTMLElement(offsetParent);
942
- const documentElement = getDocumentElement(offsetParent);
943
- const isFixed = strategy === "fixed";
944
- const rect = getBoundingClientRect(element, true, isFixed, offsetParent);
945
- let scroll = {
946
- scrollLeft: 0,
947
- scrollTop: 0
948
- };
949
- const offsets = createCoords(0);
950
- function setLeftRTLScrollbarOffset() {
951
- offsets.x = getWindowScrollBarX(documentElement);
952
- }
953
- if (isOffsetParentAnElement || !isOffsetParentAnElement && !isFixed) {
954
- if (getNodeName(offsetParent) !== "body" || isOverflowElement(documentElement)) scroll = getNodeScroll(offsetParent);
955
- if (isOffsetParentAnElement) {
956
- const offsetRect = getBoundingClientRect(offsetParent, true, isFixed, offsetParent);
957
- offsets.x = offsetRect.x + offsetParent.clientLeft;
958
- offsets.y = offsetRect.y + offsetParent.clientTop;
959
- } else if (documentElement) setLeftRTLScrollbarOffset();
960
- }
961
- if (isFixed && !isOffsetParentAnElement && documentElement) setLeftRTLScrollbarOffset();
962
- const htmlOffset = documentElement && !isOffsetParentAnElement && !isFixed ? getHTMLOffset(documentElement, scroll) : createCoords(0);
963
- return {
964
- x: rect.left + scroll.scrollLeft - offsets.x - htmlOffset.x,
965
- y: rect.top + scroll.scrollTop - offsets.y - htmlOffset.y,
966
- width: rect.width,
967
- height: rect.height
968
- };
969
- }
970
- function isStaticPositioned(element) {
971
- return getComputedStyle$1(element).position === "static";
972
- }
973
- function getTrueOffsetParent(element, polyfill) {
974
- if (!isHTMLElement(element) || getComputedStyle$1(element).position === "fixed") return null;
975
- if (polyfill) return polyfill(element);
976
- let rawOffsetParent = element.offsetParent;
977
- if (getDocumentElement(element) === rawOffsetParent) rawOffsetParent = rawOffsetParent.ownerDocument.body;
978
- return rawOffsetParent;
979
- }
980
- function getOffsetParent(element, polyfill) {
981
- const win = getWindow(element);
982
- if (isTopLayer(element)) return win;
983
- if (!isHTMLElement(element)) {
984
- let svgOffsetParent = getParentNode(element);
985
- while (svgOffsetParent && !isLastTraversableNode(svgOffsetParent)) {
986
- if (isElement(svgOffsetParent) && !isStaticPositioned(svgOffsetParent)) return svgOffsetParent;
987
- svgOffsetParent = getParentNode(svgOffsetParent);
988
- }
989
- return win;
990
- }
991
- let offsetParent = getTrueOffsetParent(element, polyfill);
992
- while (offsetParent && isTableElement(offsetParent) && isStaticPositioned(offsetParent)) offsetParent = getTrueOffsetParent(offsetParent, polyfill);
993
- if (offsetParent && isLastTraversableNode(offsetParent) && isStaticPositioned(offsetParent) && !isContainingBlock(offsetParent)) return win;
994
- return offsetParent || getContainingBlock(element) || win;
995
- }
996
- var getElementRects = async function(data) {
997
- const getOffsetParentFn = this.getOffsetParent || getOffsetParent;
998
- const getDimensionsFn = this.getDimensions;
999
- const floatingDimensions = await getDimensionsFn(data.floating);
1000
- return {
1001
- reference: getRectRelativeToOffsetParent(data.reference, await getOffsetParentFn(data.floating), data.strategy),
1002
- floating: {
1003
- x: 0,
1004
- y: 0,
1005
- width: floatingDimensions.width,
1006
- height: floatingDimensions.height
1007
- }
1008
- };
1009
- };
1010
- function isRTL(element) {
1011
- return getComputedStyle$1(element).direction === "rtl";
1012
- }
1013
- var platform = {
1014
- convertOffsetParentRelativeRectToViewportRelativeRect,
1015
- getDocumentElement,
1016
- getClippingRect,
1017
- getOffsetParent,
1018
- getElementRects,
1019
- getClientRects,
1020
- getDimensions,
1021
- getScale,
1022
- isElement,
1023
- isRTL
1024
- };
1025
- /**
1026
- * Modifies the placement by translating the floating element along the
1027
- * specified axes.
1028
- * A number (shorthand for `mainAxis` or distance), or an axes configuration
1029
- * object may be passed.
1030
- * @see https://floating-ui.com/docs/offset
1031
- */
1032
- var offset = offset$1;
1033
- /**
1034
- * Optimizes the visibility of the floating element by shifting it in order to
1035
- * keep it in view when it will overflow the clipping boundary.
1036
- * @see https://floating-ui.com/docs/shift
1037
- */
1038
- var shift = shift$1;
1039
- /**
1040
- * Optimizes the visibility of the floating element by flipping the `placement`
1041
- * in order to keep it in view when the preferred placement(s) will overflow the
1042
- * clipping boundary. Alternative to `autoPlacement`.
1043
- * @see https://floating-ui.com/docs/flip
1044
- */
1045
- var flip = flip$1;
1046
- /**
1047
- * Computes the `x` and `y` coordinates that will place the floating element
1048
- * next to a given reference element.
1049
- */
1050
- var computePosition = (reference, floating, options) => {
1051
- const cache = /* @__PURE__ */ new Map();
1052
- const mergedOptions = {
1053
- platform,
1054
- ...options
1055
- };
1056
- const platformWithCache = {
1057
- ...mergedOptions.platform,
1058
- _c: cache
1059
- };
1060
- return computePosition$1(reference, floating, {
1061
- ...mergedOptions,
1062
- platform: platformWithCache
1063
- });
1064
- };
1065
- //#endregion
1066
82
  //#region src/components/Tooltip.vue?vue&type=script&setup=true&lang.ts
1067
- var _hoisted_1$20 = ["aria-describedby"];
1068
- var _hoisted_2$19 = { class: "mint-tooltip__body" };
1069
- var _hoisted_3$17 = {
83
+ var _hoisted_1$21 = ["aria-describedby"];
84
+ var _hoisted_2$20 = { class: "mint-tooltip__body" };
85
+ var _hoisted_3$19 = {
1070
86
  key: 0,
1071
87
  class: "mint-tooltip__shortcut"
1072
88
  };
@@ -1161,13 +177,13 @@ var Tooltip_default = /* @__PURE__ */ defineComponent({
1161
177
  maxWidth: resolvedMaxWidth(__props.maxWidth)
1162
178
  }),
1163
179
  role: "tooltip"
1164
- }, [createElementVNode("span", _hoisted_2$19, toDisplayString(__props.text), 1), __props.shortcut ? (openBlock(), createElementBlock("kbd", _hoisted_3$17, toDisplayString(__props.shortcut), 1)) : createCommentVNode("", true)], 6)) : createCommentVNode("", true)]))], 40, _hoisted_1$20);
180
+ }, [createElementVNode("span", _hoisted_2$20, toDisplayString(__props.text), 1), __props.shortcut ? (openBlock(), createElementBlock("kbd", _hoisted_3$19, toDisplayString(__props.shortcut), 1)) : createCommentVNode("", true)], 6)) : createCommentVNode("", true)]))], 40, _hoisted_1$21);
1165
181
  };
1166
182
  }
1167
183
  });
1168
184
  //#endregion
1169
185
  //#region src/components/BaseCheckbox.vue?vue&type=script&setup=true&lang.ts
1170
- var _hoisted_1$19 = {
186
+ var _hoisted_1$20 = {
1171
187
  key: 0,
1172
188
  class: "mint-checkbox__row-svg",
1173
189
  viewBox: "0 0 24 24",
@@ -1177,8 +193,8 @@ var _hoisted_1$19 = {
1177
193
  "stroke-linecap": "round",
1178
194
  "stroke-linejoin": "round"
1179
195
  };
1180
- var _hoisted_2$18 = ["d"];
1181
- var _hoisted_3$16 = ["d"];
196
+ var _hoisted_2$19 = ["d"];
197
+ var _hoisted_3$18 = ["d"];
1182
198
  var _hoisted_4$15 = {
1183
199
  key: 1,
1184
200
  class: "mint-checkbox__row-text-icon"
@@ -1242,15 +258,15 @@ var BaseCheckbox_default = /* @__PURE__ */ defineComponent({
1242
258
  class: "mint-checkbox__row-icon",
1243
259
  style: normalizeStyle(iconStyle()),
1244
260
  "aria-hidden": "true"
1245
- }, [isSvgIcon(props.icon) ? (openBlock(), createElementBlock("svg", _hoisted_1$19, [Array.isArray(props.icon) ? (openBlock(true), createElementBlock(Fragment, { key: 0 }, renderList(props.icon, (d, i) => {
261
+ }, [isSvgIcon(props.icon) ? (openBlock(), createElementBlock("svg", _hoisted_1$20, [Array.isArray(props.icon) ? (openBlock(true), createElementBlock(Fragment, { key: 0 }, renderList(props.icon, (d, i) => {
1246
262
  return openBlock(), createElementBlock("path", {
1247
263
  key: i,
1248
264
  d
1249
- }, null, 8, _hoisted_2$18);
265
+ }, null, 8, _hoisted_2$19);
1250
266
  }), 128)) : (openBlock(), createElementBlock("path", {
1251
267
  key: 1,
1252
268
  d: props.icon
1253
- }, null, 8, _hoisted_3$16))])) : (openBlock(), createElementBlock("span", _hoisted_4$15, toDisplayString(props.icon), 1))], 4)) : createCommentVNode("", true),
269
+ }, null, 8, _hoisted_3$18))])) : (openBlock(), createElementBlock("span", _hoisted_4$15, toDisplayString(props.icon), 1))], 4)) : createCommentVNode("", true),
1254
270
  props.variant === "row" && props.label ? (openBlock(), createElementBlock("span", _hoisted_5$13, [props.description ? (openBlock(), createBlock(Tooltip_default, {
1255
271
  key: 0,
1256
272
  text: props.description,
@@ -1301,7 +317,7 @@ var BaseCheckbox_default = /* @__PURE__ */ defineComponent({
1301
317
  });
1302
318
  //#endregion
1303
319
  //#region src/components/BaseToggle.vue?vue&type=script&setup=true&lang.ts
1304
- var _hoisted_1$18 = {
320
+ var _hoisted_1$19 = {
1305
321
  key: 0,
1306
322
  class: "mint-toggle__row-svg",
1307
323
  viewBox: "0 0 24 24",
@@ -1311,8 +327,8 @@ var _hoisted_1$18 = {
1311
327
  "stroke-linecap": "round",
1312
328
  "stroke-linejoin": "round"
1313
329
  };
1314
- var _hoisted_2$17 = ["d"];
1315
- var _hoisted_3$15 = ["d"];
330
+ var _hoisted_2$18 = ["d"];
331
+ var _hoisted_3$17 = ["d"];
1316
332
  var _hoisted_4$14 = {
1317
333
  key: 1,
1318
334
  class: "mint-toggle__row-text-icon"
@@ -1389,15 +405,15 @@ var BaseToggle_default = /* @__PURE__ */ defineComponent({
1389
405
  class: "mint-toggle__row-icon",
1390
406
  style: normalizeStyle(iconStyle()),
1391
407
  "aria-hidden": "true"
1392
- }, [isSvgIcon(__props.icon) ? (openBlock(), createElementBlock("svg", _hoisted_1$18, [Array.isArray(__props.icon) ? (openBlock(true), createElementBlock(Fragment, { key: 0 }, renderList(__props.icon, (d, i) => {
408
+ }, [isSvgIcon(__props.icon) ? (openBlock(), createElementBlock("svg", _hoisted_1$19, [Array.isArray(__props.icon) ? (openBlock(true), createElementBlock(Fragment, { key: 0 }, renderList(__props.icon, (d, i) => {
1393
409
  return openBlock(), createElementBlock("path", {
1394
410
  key: i,
1395
411
  d
1396
- }, null, 8, _hoisted_2$17);
412
+ }, null, 8, _hoisted_2$18);
1397
413
  }), 128)) : (openBlock(), createElementBlock("path", {
1398
414
  key: 1,
1399
415
  d: __props.icon
1400
- }, null, 8, _hoisted_3$15))])) : (openBlock(), createElementBlock("span", _hoisted_4$14, toDisplayString(__props.icon), 1))], 4)) : createCommentVNode("", true),
416
+ }, null, 8, _hoisted_3$17))])) : (openBlock(), createElementBlock("span", _hoisted_4$14, toDisplayString(__props.icon), 1))], 4)) : createCommentVNode("", true),
1401
417
  __props.variant === "row" && __props.label ? (openBlock(), createElementBlock("span", _hoisted_5$12, [__props.description ? (openBlock(), createBlock(Tooltip_default, {
1402
418
  key: 0,
1403
419
  text: __props.description,
@@ -1440,7 +456,7 @@ var BaseToggle_default = /* @__PURE__ */ defineComponent({
1440
456
  });
1441
457
  //#endregion
1442
458
  //#region src/components/BaseRadioGroup.vue?vue&type=script&setup=true&lang.ts
1443
- var _hoisted_1$17 = [
459
+ var _hoisted_1$18 = [
1444
460
  "name",
1445
461
  "value",
1446
462
  "checked",
@@ -1448,8 +464,8 @@ var _hoisted_1$17 = [
1448
464
  "aria-describedby",
1449
465
  "onChange"
1450
466
  ];
1451
- var _hoisted_2$16 = { class: "mint-radio-option__content" };
1452
- var _hoisted_3$14 = ["id"];
467
+ var _hoisted_2$17 = { class: "mint-radio-option__content" };
468
+ var _hoisted_3$16 = ["id"];
1453
469
  var _hoisted_4$13 = [
1454
470
  "name",
1455
471
  "value",
@@ -1511,18 +527,18 @@ var BaseRadioGroup_default = /* @__PURE__ */ defineComponent({
1511
527
  "aria-describedby": option.description ? `${props.name}-${option.value}-desc` : void 0,
1512
528
  class: "mint-radio-option__native",
1513
529
  onChange: ($event) => handleChange(option.value)
1514
- }, null, 40, _hoisted_1$17), createElementVNode("div", { class: normalizeClass([
530
+ }, null, 40, _hoisted_1$18), createElementVNode("div", { class: normalizeClass([
1515
531
  "mint-radio-option__circle",
1516
532
  `mint-radio-option__circle--${props.size}`,
1517
533
  props.modelValue === option.value ? "mint-radio-option__circle--checked" : ""
1518
534
  ]) }, [props.modelValue === option.value ? (openBlock(), createElementBlock("div", {
1519
535
  key: 0,
1520
536
  class: normalizeClass(["mint-radio-option__dot", `mint-radio-option__dot--${props.size}`])
1521
- }, null, 2)) : createCommentVNode("", true)], 2)], 2), createElementVNode("div", _hoisted_2$16, [createElementVNode("span", { class: normalizeClass(["mint-radio-option__label", `mint-radio-option__label--${props.size}`]) }, toDisplayString(option.label), 3), option.description ? (openBlock(), createElementBlock("span", {
537
+ }, null, 2)) : createCommentVNode("", true)], 2)], 2), createElementVNode("div", _hoisted_2$17, [createElementVNode("span", { class: normalizeClass(["mint-radio-option__label", `mint-radio-option__label--${props.size}`]) }, toDisplayString(option.label), 3), option.description ? (openBlock(), createElementBlock("span", {
1522
538
  key: 0,
1523
539
  id: `${props.name}-${option.value}-desc`,
1524
540
  class: normalizeClass(["mint-radio-option__description", `mint-radio-option__description--${props.size}`])
1525
- }, toDisplayString(option.description), 11, _hoisted_3$14)) : createCommentVNode("", true)])], 64)) : (openBlock(), createElementBlock(Fragment, { key: 1 }, [
541
+ }, toDisplayString(option.description), 11, _hoisted_3$16)) : createCommentVNode("", true)])], 64)) : (openBlock(), createElementBlock(Fragment, { key: 1 }, [
1526
542
  createElementVNode("input", {
1527
543
  type: "radio",
1528
544
  name: props.name,
@@ -1553,8 +569,8 @@ var BaseRadioGroup_default = /* @__PURE__ */ defineComponent({
1553
569
  });
1554
570
  //#endregion
1555
571
  //#region src/components/BaseSlider.vue?vue&type=script&setup=true&lang.ts
1556
- var _hoisted_1$16 = { class: "mint-slider__container" };
1557
- var _hoisted_2$15 = [
572
+ var _hoisted_1$17 = { class: "mint-slider__container" };
573
+ var _hoisted_2$16 = [
1558
574
  "value",
1559
575
  "min",
1560
576
  "max",
@@ -1565,7 +581,7 @@ var _hoisted_2$15 = [
1565
581
  "aria-valuemax",
1566
582
  "aria-valuenow"
1567
583
  ];
1568
- var _hoisted_3$13 = {
584
+ var _hoisted_3$15 = {
1569
585
  key: 0,
1570
586
  class: "mint-slider__value"
1571
587
  };
@@ -1627,7 +643,7 @@ var BaseSlider_default = /* @__PURE__ */ defineComponent({
1627
643
  emit("update:modelValue", Number(target.value));
1628
644
  }
1629
645
  return (_ctx, _cache) => {
1630
- return openBlock(), createElementBlock("div", { class: normalizeClass(["mint-slider", { "mint-slider--disabled": __props.disabled }]) }, [createElementVNode("div", _hoisted_1$16, [
646
+ return openBlock(), createElementBlock("div", { class: normalizeClass(["mint-slider", { "mint-slider--disabled": __props.disabled }]) }, [createElementVNode("div", _hoisted_1$17, [
1631
647
  createElementVNode("div", {
1632
648
  class: "mint-slider__track",
1633
649
  style: normalizeStyle({ height: `${sizeConfig.value.height}px` })
@@ -1656,7 +672,7 @@ var BaseSlider_default = /* @__PURE__ */ defineComponent({
1656
672
  onMouseup: _cache[1] || (_cache[1] = ($event) => isDragging.value = false),
1657
673
  onTouchstartPassive: _cache[2] || (_cache[2] = ($event) => isDragging.value = true),
1658
674
  onTouchend: _cache[3] || (_cache[3] = ($event) => isDragging.value = false)
1659
- }, null, 40, _hoisted_2$15),
675
+ }, null, 40, _hoisted_2$16),
1660
676
  createElementVNode("div", {
1661
677
  class: normalizeClass(["mint-slider__thumb", { "mint-slider__thumb--dragging": isDragging.value }]),
1662
678
  style: normalizeStyle({
@@ -1665,7 +681,7 @@ var BaseSlider_default = /* @__PURE__ */ defineComponent({
1665
681
  left: thumbPosition.value
1666
682
  })
1667
683
  }, null, 6)
1668
- ]), __props.showValue ? (openBlock(), createElementBlock("span", _hoisted_3$13, toDisplayString(currentValue.value), 1)) : createCommentVNode("", true)], 2);
684
+ ]), __props.showValue ? (openBlock(), createElementBlock("span", _hoisted_3$15, toDisplayString(currentValue.value), 1)) : createCommentVNode("", true)], 2);
1669
685
  };
1670
686
  }
1671
687
  });
@@ -1791,15 +807,15 @@ function uniqueValues(values) {
1791
807
  }
1792
808
  //#endregion
1793
809
  //#region src/components/MultiSelect.vue?vue&type=script&setup=true&lang.ts
1794
- var _hoisted_1$15 = {
810
+ var _hoisted_1$16 = {
1795
811
  key: 0,
1796
812
  class: "mint-multi-select__placeholder"
1797
813
  };
1798
- var _hoisted_2$14 = {
814
+ var _hoisted_2$15 = {
1799
815
  class: "mint-multi-select__options",
1800
816
  role: "group"
1801
817
  };
1802
- var _hoisted_3$12 = [
818
+ var _hoisted_3$14 = [
1803
819
  "aria-checked",
1804
820
  "disabled",
1805
821
  "onClick",
@@ -1871,8 +887,8 @@ var MultiSelect_default = /* @__PURE__ */ defineComponent({
1871
887
  `mint-multi-select--${__props.size}`,
1872
888
  __props.disabled ? "mint-multi-select--disabled" : ""
1873
889
  ]) }, [
1874
- __props.modelValue.length === 0 ? (openBlock(), createElementBlock("div", _hoisted_1$15, toDisplayString(__props.placeholder), 1)) : createCommentVNode("", true),
1875
- createElementVNode("div", _hoisted_2$14, [(openBlock(true), createElementBlock(Fragment, null, renderList(normalizedOptions.value, (option) => {
890
+ __props.modelValue.length === 0 ? (openBlock(), createElementBlock("div", _hoisted_1$16, toDisplayString(__props.placeholder), 1)) : createCommentVNode("", true),
891
+ createElementVNode("div", _hoisted_2$15, [(openBlock(true), createElementBlock(Fragment, null, renderList(normalizedOptions.value, (option) => {
1876
892
  return openBlock(), createElementBlock("button", {
1877
893
  key: String(option.value),
1878
894
  type: "button",
@@ -1888,7 +904,7 @@ var MultiSelect_default = /* @__PURE__ */ defineComponent({
1888
904
  ]),
1889
905
  onClick: ($event) => toggleOption(option),
1890
906
  onKeydown: ($event) => handleKeydown($event, option)
1891
- }, [createElementVNode("span", _hoisted_4$12, toDisplayString(option.label), 1), isSelected(option.value) ? (openBlock(), createElementBlock("svg", _hoisted_5$10, [..._cache[0] || (_cache[0] = [createElementVNode("path", { d: "M20 6 9 17l-5-5" }, null, -1)])])) : createCommentVNode("", true)], 42, _hoisted_3$12);
907
+ }, [createElementVNode("span", _hoisted_4$12, toDisplayString(option.label), 1), isSelected(option.value) ? (openBlock(), createElementBlock("svg", _hoisted_5$10, [..._cache[0] || (_cache[0] = [createElementVNode("path", { d: "M20 6 9 17l-5-5" }, null, -1)])])) : createCommentVNode("", true)], 42, _hoisted_3$14);
1892
908
  }), 128))]),
1893
909
  __props.modelValue.length > 0 ? (openBlock(), createElementBlock("div", _hoisted_6$10, toDisplayString(selectedLabels.value.join(", ")), 1)) : createCommentVNode("", true)
1894
910
  ], 2);
@@ -2001,14 +1017,14 @@ function startOfDay(date) {
2001
1017
  }
2002
1018
  //#endregion
2003
1019
  //#region src/components/internal/CalendarGridPanelInternal.vue?vue&type=script&setup=true&lang.ts
2004
- var _hoisted_1$14 = { class: "mint-calendar-grid-panel" };
2005
- var _hoisted_2$13 = { class: "mint-date-picker__header" };
2006
- var _hoisted_3$11 = ["aria-label"];
1020
+ var _hoisted_1$15 = { class: "mint-calendar-grid-panel" };
1021
+ var _hoisted_2$14 = { class: "mint-date-picker__header" };
1022
+ var _hoisted_3$13 = ["aria-label"];
2007
1023
  var _hoisted_4$11 = { class: "mint-date-picker__month-year" };
2008
1024
  var _hoisted_5$9 = ["aria-label"];
2009
1025
  var _hoisted_6$9 = { class: "mint-date-picker__weekdays" };
2010
1026
  var _hoisted_7$9 = { class: "mint-date-picker__grid" };
2011
- var _hoisted_8$7 = [
1027
+ var _hoisted_8$6 = [
2012
1028
  "disabled",
2013
1029
  "aria-label",
2014
1030
  "aria-selected",
@@ -2052,8 +1068,8 @@ var CalendarGridPanelInternal_default = /* @__PURE__ */ defineComponent({
2052
1068
  });
2053
1069
  }
2054
1070
  return (_ctx, _cache) => {
2055
- return openBlock(), createElementBlock("div", _hoisted_1$14, [
2056
- createElementVNode("div", _hoisted_2$13, [
1071
+ return openBlock(), createElementBlock("div", _hoisted_1$15, [
1072
+ createElementVNode("div", _hoisted_2$14, [
2057
1073
  createElementVNode("button", {
2058
1074
  type: "button",
2059
1075
  class: "mint-date-picker__nav-btn",
@@ -2067,7 +1083,7 @@ var CalendarGridPanelInternal_default = /* @__PURE__ */ defineComponent({
2067
1083
  "stroke-linecap": "round",
2068
1084
  "stroke-linejoin": "round",
2069
1085
  "aria-hidden": "true"
2070
- }, [createElementVNode("path", { d: "m15 18-6-6 6-6" })], -1)])], 8, _hoisted_3$11),
1086
+ }, [createElementVNode("path", { d: "m15 18-6-6 6-6" })], -1)])], 8, _hoisted_3$13),
2071
1087
  createElementVNode("span", _hoisted_4$11, toDisplayString(__props.monthYear), 1),
2072
1088
  createElementVNode("button", {
2073
1089
  type: "button",
@@ -2105,7 +1121,7 @@ var CalendarGridPanelInternal_default = /* @__PURE__ */ defineComponent({
2105
1121
  isToday(day.date) && !isSameDay(day.date, __props.selectedDate) ? "mint-date-picker__day--today" : ""
2106
1122
  ]),
2107
1123
  onClick: ($event) => emit("select", day)
2108
- }, toDisplayString(day.date.getDate()), 11, _hoisted_8$7);
1124
+ }, toDisplayString(day.date.getDate()), 11, _hoisted_8$6);
2109
1125
  }), 128))])
2110
1126
  ]);
2111
1127
  };
@@ -2113,12 +1129,14 @@ var CalendarGridPanelInternal_default = /* @__PURE__ */ defineComponent({
2113
1129
  });
2114
1130
  //#endregion
2115
1131
  //#region src/components/DatePicker.vue?vue&type=script&setup=true&lang.ts
2116
- var _hoisted_1$13 = [
1132
+ var _hoisted_1$14 = { class: "mint-date-picker__input-wrapper" };
1133
+ var _hoisted_2$13 = [
1134
+ "aria-expanded",
2117
1135
  "value",
2118
1136
  "placeholder",
2119
1137
  "disabled"
2120
1138
  ];
2121
- var _hoisted_2$12 = { class: "mint-date-picker__footer" };
1139
+ var _hoisted_3$12 = { class: "mint-date-picker__footer" };
2122
1140
  //#endregion
2123
1141
  //#region src/components/DatePicker.vue
2124
1142
  var DatePicker_default = /* @__PURE__ */ defineComponent({
@@ -2147,10 +1165,13 @@ var DatePicker_default = /* @__PURE__ */ defineComponent({
2147
1165
  /** Input that opens a calendar dropdown for selecting a single date, with clearable support. */
2148
1166
  const props = __props;
2149
1167
  const emit = __emit;
2150
- const inputRef = ref(null);
2151
1168
  const dropdownRef = ref(null);
2152
1169
  const dropdownStyle = ref({});
2153
- const { isOpen, rootRef: containerRef, close, toggle } = useDropdownState({ insideRefs: [dropdownRef] });
1170
+ const { isOpen, rootRef: containerRef, triggerRef, open, close, toggle } = useDropdownState({ insideRefs: [dropdownRef] });
1171
+ useFocusTrap({
1172
+ containerRef: dropdownRef,
1173
+ active: isOpen
1174
+ });
2154
1175
  const { weekDays, monthYear, calendarDays, isDateDisabled, formatDateValue, setCurrentMonthFromDate, prevMonth, nextMonth } = useCalendarGrid({
2155
1176
  min: () => props.min,
2156
1177
  max: () => props.max
@@ -2189,40 +1210,76 @@ var DatePicker_default = /* @__PURE__ */ defineComponent({
2189
1210
  if (props.disabled) return;
2190
1211
  toggle();
2191
1212
  }
2192
- function updateDropdownPosition() {
2193
- if (!inputRef.value) return;
2194
- const rect = inputRef.value.getBoundingClientRect();
1213
+ function handleTriggerKeydown(event) {
1214
+ if (props.disabled || isOpen.value) return;
1215
+ if (event.key === "Enter" || event.key === " " || event.key === "ArrowDown") {
1216
+ event.preventDefault();
1217
+ open();
1218
+ }
1219
+ }
1220
+ let stopAutoUpdate = null;
1221
+ async function updateDropdownPosition() {
1222
+ const trigger = triggerRef.value;
1223
+ const panel = dropdownRef.value;
1224
+ if (!trigger || !panel) return;
1225
+ const { x, y } = await computePosition(trigger, panel, {
1226
+ placement: "bottom-start",
1227
+ strategy: "fixed",
1228
+ middleware: [
1229
+ offset(4),
1230
+ flip(),
1231
+ shift({ padding: 8 })
1232
+ ]
1233
+ });
2195
1234
  dropdownStyle.value = {
2196
1235
  position: "fixed",
2197
- top: `${rect.bottom + 4}px`,
2198
- left: `${rect.left}px`,
2199
- width: `${Math.max(rect.width, 288)}px`,
1236
+ top: `${y}px`,
1237
+ left: `${x}px`,
1238
+ width: `${Math.max(trigger.getBoundingClientRect().width, 288)}px`,
2200
1239
  zIndex: "9999"
2201
1240
  };
2202
1241
  }
2203
- function handleScrollOrResize() {
2204
- close();
2205
- }
2206
- watch(isOpen, (open) => {
2207
- if (open) {
2208
- updateDropdownPosition();
2209
- if (selectedDate.value) setCurrentMonthFromDate(selectedDate.value);
1242
+ function stopPositioning() {
1243
+ stopAutoUpdate?.();
1244
+ stopAutoUpdate = null;
1245
+ }
1246
+ function startPositioning() {
1247
+ const trigger = triggerRef.value;
1248
+ const panel = dropdownRef.value;
1249
+ if (!trigger || !panel) return;
1250
+ stopPositioning();
1251
+ stopAutoUpdate = autoUpdate(trigger, panel, () => void updateDropdownPosition());
1252
+ }
1253
+ /** Moves focus into the calendar grid: selected day, else today, else the first day. */
1254
+ function focusCalendar() {
1255
+ const panel = dropdownRef.value;
1256
+ if (!panel) return;
1257
+ (panel.querySelector(".mint-date-picker__day--selected") ?? panel.querySelector(".mint-date-picker__day--today") ?? panel.querySelector(".mint-date-picker__day:not([disabled])"))?.focus();
1258
+ }
1259
+ watch(isOpen, async (opened) => {
1260
+ if (!opened) {
1261
+ stopPositioning();
1262
+ return;
2210
1263
  }
1264
+ if (selectedDate.value) setCurrentMonthFromDate(selectedDate.value);
1265
+ await nextTick();
1266
+ startPositioning();
1267
+ await nextTick();
1268
+ focusCalendar();
2211
1269
  });
2212
- useEventListener(() => window, "scroll", handleScrollOrResize, true);
2213
- useEventListener(() => window, "resize", handleScrollOrResize);
1270
+ onBeforeUnmount(stopPositioning);
2214
1271
  return (_ctx, _cache) => {
2215
1272
  return openBlock(), createElementBlock("div", {
2216
1273
  ref_key: "containerRef",
2217
1274
  ref: containerRef,
2218
1275
  class: "mint-date-picker"
2219
- }, [createElementVNode("div", {
2220
- ref_key: "inputRef",
2221
- ref: inputRef,
2222
- class: "mint-date-picker__input-wrapper"
2223
- }, [createElementVNode("input", {
1276
+ }, [createElementVNode("div", _hoisted_1$14, [createElementVNode("input", {
1277
+ ref_key: "triggerRef",
1278
+ ref: triggerRef,
2224
1279
  type: "text",
2225
1280
  readonly: "",
1281
+ "aria-haspopup": "dialog",
1282
+ "aria-expanded": unref(isOpen),
2226
1283
  value: displayValue.value,
2227
1284
  placeholder: __props.placeholder || "Select date",
2228
1285
  disabled: __props.disabled,
@@ -2232,8 +1289,9 @@ var DatePicker_default = /* @__PURE__ */ defineComponent({
2232
1289
  __props.error ? "mint-date-picker__input--error" : "",
2233
1290
  __props.disabled ? "mint-date-picker__input--disabled" : ""
2234
1291
  ]),
2235
- onClick: toggleCalendar
2236
- }, null, 10, _hoisted_1$13), _cache[0] || (_cache[0] = createStaticVNode("<div class=\"mint-date-picker__icon\"><svg viewBox=\"0 0 24 24\" fill=\"none\" stroke=\"currentColor\" stroke-width=\"2\" stroke-linecap=\"round\" stroke-linejoin=\"round\"><path d=\"M8 2v4\"></path><path d=\"M16 2v4\"></path><rect width=\"18\" height=\"18\" x=\"3\" y=\"4\" rx=\"2\"></rect><path d=\"M3 10h18\"></path></svg></div>", 1))], 512), (openBlock(), createBlock(Teleport, { to: "body" }, [createVNode(Transition, {
1292
+ onClick: toggleCalendar,
1293
+ onKeydown: handleTriggerKeydown
1294
+ }, null, 42, _hoisted_2$13), _cache[0] || (_cache[0] = createStaticVNode("<div class=\"mint-date-picker__icon\"><svg viewBox=\"0 0 24 24\" fill=\"none\" stroke=\"currentColor\" stroke-width=\"2\" stroke-linecap=\"round\" stroke-linejoin=\"round\"><path d=\"M8 2v4\"></path><path d=\"M16 2v4\"></path><rect width=\"18\" height=\"18\" x=\"3\" y=\"4\" rx=\"2\"></rect><path d=\"M3 10h18\"></path></svg></div>", 1))]), (openBlock(), createBlock(Teleport, { to: "body" }, [createVNode(Transition, {
2237
1295
  "enter-active-class": "mint-date-picker__dropdown-enter-active",
2238
1296
  "enter-from-class": "mint-date-picker__dropdown-enter-from",
2239
1297
  "enter-to-class": "mint-date-picker__dropdown-enter-to",
@@ -2248,7 +1306,6 @@ var DatePicker_default = /* @__PURE__ */ defineComponent({
2248
1306
  class: "mint-date-picker__dropdown",
2249
1307
  style: normalizeStyle(dropdownStyle.value),
2250
1308
  role: "dialog",
2251
- "aria-modal": "true",
2252
1309
  "aria-label": "Date picker"
2253
1310
  }, [createVNode(CalendarGridPanelInternal_default, {
2254
1311
  "week-days": unref(weekDays),
@@ -2265,7 +1322,7 @@ var DatePicker_default = /* @__PURE__ */ defineComponent({
2265
1322
  "selected-date",
2266
1323
  "onPreviousMonth",
2267
1324
  "onNextMonth"
2268
- ]), createElementVNode("div", _hoisted_2$12, [createElementVNode("button", {
1325
+ ]), createElementVNode("div", _hoisted_3$12, [createElementVNode("button", {
2269
1326
  type: "button",
2270
1327
  class: "mint-date-picker__footer-btn mint-date-picker__today-btn",
2271
1328
  onClick: goToToday
@@ -2411,18 +1468,21 @@ function useTimeUtils() {
2411
1468
  }
2412
1469
  //#endregion
2413
1470
  //#region src/components/TimePicker.vue?vue&type=script&setup=true&lang.ts
2414
- var _hoisted_1$12 = { class: "mint-time-picker__input-wrapper" };
2415
- var _hoisted_2$11 = [
1471
+ var _hoisted_1$13 = { class: "mint-time-picker__input-wrapper" };
1472
+ var _hoisted_2$12 = [
2416
1473
  "value",
2417
1474
  "placeholder",
2418
1475
  "disabled",
2419
- "aria-expanded"
1476
+ "aria-expanded",
1477
+ "aria-controls",
1478
+ "aria-activedescendant"
2420
1479
  ];
2421
- var _hoisted_3$10 = {
1480
+ var _hoisted_3$11 = {
2422
1481
  key: 0,
2423
1482
  class: "mint-time-picker__dropdown"
2424
1483
  };
2425
1484
  var _hoisted_4$10 = [
1485
+ "id",
2426
1486
  "aria-selected",
2427
1487
  "aria-disabled",
2428
1488
  "onClick"
@@ -2459,7 +1519,10 @@ var TimePicker_default = /* @__PURE__ */ defineComponent({
2459
1519
  const emit = __emit;
2460
1520
  const listRef = ref(null);
2461
1521
  const highlightedIndex = ref(-1);
2462
- const { isOpen, rootRef, open, close, toggle } = useDropdownState();
1522
+ const listboxId = `mint-time-picker-listbox-${useId().replace(/:/g, "")}`;
1523
+ const { isOpen, rootRef, triggerRef, open, close, toggle } = useDropdownState();
1524
+ /** Id of the highlighted slot, published to the input as `aria-activedescendant`. */
1525
+ const activeSlotId = computed(() => isOpen.value && highlightedIndex.value >= 0 ? `${listboxId}-option-${highlightedIndex.value}` : void 0);
2463
1526
  const slots = computed(() => {
2464
1527
  return generateTimeSlots(props.min ?? "00:00", props.max ?? "23:59", props.step);
2465
1528
  });
@@ -2536,9 +1599,26 @@ var TimePicker_default = /* @__PURE__ */ defineComponent({
2536
1599
  event.preventDefault();
2537
1600
  if (highlightedIndex.value >= 0 && highlightedIndex.value < slots.value.length) selectSlot(slots.value[highlightedIndex.value]);
2538
1601
  break;
1602
+ case "Home": {
1603
+ event.preventDefault();
1604
+ const first = slots.value.findIndex((slot) => !isSlotDisabled(slot));
1605
+ if (first >= 0) {
1606
+ highlightedIndex.value = first;
1607
+ scrollToHighlighted();
1608
+ }
1609
+ break;
1610
+ }
1611
+ case "End":
1612
+ event.preventDefault();
1613
+ for (let index = slots.value.length - 1; index >= 0; index--) if (!isSlotDisabled(slots.value[index])) {
1614
+ highlightedIndex.value = index;
1615
+ scrollToHighlighted();
1616
+ break;
1617
+ }
1618
+ break;
2539
1619
  case "Escape":
2540
1620
  event.preventDefault();
2541
- close();
1621
+ close(true);
2542
1622
  break;
2543
1623
  }
2544
1624
  }
@@ -2564,8 +1644,10 @@ var TimePicker_default = /* @__PURE__ */ defineComponent({
2564
1644
  ref: rootRef,
2565
1645
  class: "mint-time-picker",
2566
1646
  onKeydown: handleKeydown
2567
- }, [createElementVNode("div", _hoisted_1$12, [
1647
+ }, [createElementVNode("div", _hoisted_1$13, [
2568
1648
  createElementVNode("input", {
1649
+ ref_key: "triggerRef",
1650
+ ref: triggerRef,
2569
1651
  type: "text",
2570
1652
  readonly: "",
2571
1653
  value: displayValue.value,
@@ -2580,8 +1662,10 @@ var TimePicker_default = /* @__PURE__ */ defineComponent({
2580
1662
  role: "combobox",
2581
1663
  "aria-haspopup": "listbox",
2582
1664
  "aria-expanded": unref(isOpen),
1665
+ "aria-controls": unref(isOpen) ? listboxId : void 0,
1666
+ "aria-activedescendant": activeSlotId.value,
2583
1667
  onClick: toggleDropdown
2584
- }, null, 10, _hoisted_2$11),
1668
+ }, null, 10, _hoisted_2$12),
2585
1669
  __props.clearable && __props.modelValue ? (openBlock(), createElementBlock("button", {
2586
1670
  key: 0,
2587
1671
  type: "button",
@@ -2616,7 +1700,8 @@ var TimePicker_default = /* @__PURE__ */ defineComponent({
2616
1700
  "leave-from-class": "mint-time-picker__dropdown-leave-from",
2617
1701
  "leave-to-class": "mint-time-picker__dropdown-leave-to"
2618
1702
  }, {
2619
- default: withCtx(() => [unref(isOpen) ? (openBlock(), createElementBlock("div", _hoisted_3$10, [createElementVNode("ul", {
1703
+ default: withCtx(() => [unref(isOpen) ? (openBlock(), createElementBlock("div", _hoisted_3$11, [createElementVNode("ul", {
1704
+ id: listboxId,
2620
1705
  ref_key: "listRef",
2621
1706
  ref: listRef,
2622
1707
  class: "mint-time-picker__list",
@@ -2624,6 +1709,7 @@ var TimePicker_default = /* @__PURE__ */ defineComponent({
2624
1709
  "aria-label": "Available times"
2625
1710
  }, [(openBlock(true), createElementBlock(Fragment, null, renderList(slots.value, (slot, index) => {
2626
1711
  return openBlock(), createElementBlock("li", {
1712
+ id: `${listboxId}-option-${index}`,
2627
1713
  key: slot,
2628
1714
  role: "option",
2629
1715
  "aria-selected": slot === __props.modelValue,
@@ -2644,12 +1730,12 @@ var TimePicker_default = /* @__PURE__ */ defineComponent({
2644
1730
  });
2645
1731
  //#endregion
2646
1732
  //#region src/components/TagsInput.vue?vue&type=script&setup=true&lang.ts
2647
- var _hoisted_1$11 = {
1733
+ var _hoisted_1$12 = {
2648
1734
  key: 0,
2649
1735
  class: "mint-tags-input__categories"
2650
1736
  };
2651
- var _hoisted_2$10 = ["disabled", "onClick"];
2652
- var _hoisted_3$9 = ["aria-label", "onClick"];
1737
+ var _hoisted_2$11 = ["disabled", "onClick"];
1738
+ var _hoisted_3$10 = ["aria-label", "onClick"];
2653
1739
  var _hoisted_4$9 = ["placeholder", "disabled"];
2654
1740
  var _hoisted_5$8 = {
2655
1741
  key: 0,
@@ -2691,9 +1777,8 @@ var TagsInput_default = /* @__PURE__ */ defineComponent({
2691
1777
  const props = __props;
2692
1778
  const emit = __emit;
2693
1779
  const inputValue = ref("");
2694
- const inputRef = ref();
2695
1780
  const highlightedIndex = ref(-1);
2696
- const { isOpen: dropdownOpen, rootRef, open: openDropdown, close: closeDropdown } = useDropdownState({ onClose: () => {
1781
+ const { isOpen: dropdownOpen, rootRef, triggerRef: inputRef, open: openDropdown, close: closeDropdown } = useDropdownState({ onClose: () => {
2697
1782
  highlightedIndex.value = -1;
2698
1783
  } });
2699
1784
  const selectionLimit = useSelectionLimit({
@@ -2751,7 +1836,7 @@ var TagsInput_default = /* @__PURE__ */ defineComponent({
2751
1836
  return;
2752
1837
  }
2753
1838
  if (event.key === "Escape") {
2754
- closeDropdown();
1839
+ closeDropdown(true);
2755
1840
  return;
2756
1841
  }
2757
1842
  if (event.key === "Backspace" && !inputValue.value && props.modelValue.length > 0) removeTag(props.modelValue.length - 1);
@@ -2799,7 +1884,7 @@ var TagsInput_default = /* @__PURE__ */ defineComponent({
2799
1884
  __props.disabled ? "mint-tags-input--disabled" : "",
2800
1885
  __props.categories.length ? "mint-tags-input--categorized" : ""
2801
1886
  ])
2802
- }, [__props.categories.length ? (openBlock(), createElementBlock("div", _hoisted_1$11, [(openBlock(true), createElementBlock(Fragment, null, renderList(__props.categories, (cat) => {
1887
+ }, [__props.categories.length ? (openBlock(), createElementBlock("div", _hoisted_1$12, [(openBlock(true), createElementBlock(Fragment, null, renderList(__props.categories, (cat) => {
2803
1888
  return openBlock(), createElementBlock("button", {
2804
1889
  key: cat.prefix,
2805
1890
  type: "button",
@@ -2810,7 +1895,7 @@ var TagsInput_default = /* @__PURE__ */ defineComponent({
2810
1895
  ]),
2811
1896
  disabled: __props.disabled,
2812
1897
  onClick: ($event) => setCategory(cat.prefix)
2813
- }, toDisplayString(cat.name), 11, _hoisted_2$10);
1898
+ }, toDisplayString(cat.name), 11, _hoisted_2$11);
2814
1899
  }), 128))])) : createCommentVNode("", true), createElementVNode("div", {
2815
1900
  class: "mint-tags-input__field",
2816
1901
  onClick: focusInput
@@ -2837,7 +1922,7 @@ var TagsInput_default = /* @__PURE__ */ defineComponent({
2837
1922
  "stroke-linecap": "round",
2838
1923
  "stroke-linejoin": "round",
2839
1924
  viewBox: "0 0 24 24"
2840
- }, [createElementVNode("path", { d: "M18 6 6 18" }), createElementVNode("path", { d: "m6 6 12 12" })], -1)])], 8, _hoisted_3$9)) : createCommentVNode("", true)], 2);
1925
+ }, [createElementVNode("path", { d: "M18 6 6 18" }), createElementVNode("path", { d: "m6 6 12 12" })], -1)])], 8, _hoisted_3$10)) : createCommentVNode("", true)], 2);
2841
1926
  }), 128)),
2842
1927
  withDirectives(createElementVNode("input", {
2843
1928
  ref_key: "inputRef",
@@ -2866,6 +1951,207 @@ var TagsInput_default = /* @__PURE__ */ defineComponent({
2866
1951
  }
2867
1952
  });
2868
1953
  //#endregion
1954
+ //#region src/utils/pluginSecrets.ts
1955
+ /**
1956
+ * Stable references for plugin secret settings.
1957
+ *
1958
+ * A settings response never carries a secret's value. Every secret leaf is a
1959
+ * marker instead:
1960
+ *
1961
+ * - `{ "$secret": "sec_…", "set": true }` — a stored secret, referenced by a
1962
+ * stable opaque id. Send the marker back unchanged to keep the stored value.
1963
+ * - `null` — nothing stored at that position.
1964
+ * - `{ "$secret": null, "locked": true }` — the effective value comes from the
1965
+ * environment and is never written back.
1966
+ *
1967
+ * On save each secret leaf accepts the reference, a plain string (a new value),
1968
+ * or `null` (clear). Payloads carry `secret_format: "ref"` so a `null` reads as
1969
+ * a deliberate clear rather than the deprecated "unchanged" placeholder.
1970
+ */
1971
+ /** Reserved marker key that references a stored secret. */
1972
+ var PLUGIN_SECRET_REF_KEY = "$secret";
1973
+ /** Reserved payload key declaring which secret wire format a client speaks. */
1974
+ var PLUGIN_SECRET_FORMAT_KEY = "secret_format";
1975
+ /** Wire format published and understood by this SDK. */
1976
+ var PLUGIN_SECRET_FORMAT_REF = "ref";
1977
+ var MARKER_KEYS = new Set([
1978
+ PLUGIN_SECRET_REF_KEY,
1979
+ "set",
1980
+ "locked"
1981
+ ]);
1982
+ /** Return whether one settings value is a `$secret` reference marker. */
1983
+ function isPluginSecretRef(value) {
1984
+ if (!value || typeof value !== "object" || Array.isArray(value)) return false;
1985
+ const record = value;
1986
+ if (!("$secret" in record)) return false;
1987
+ return Object.keys(record).every((key) => MARKER_KEYS.has(key));
1988
+ }
1989
+ /** Return the stored secret id behind a marker, or `null` when nothing is stored. */
1990
+ function pluginSecretId(value) {
1991
+ if (!isPluginSecretRef(value)) return null;
1992
+ return typeof value.$secret === "string" ? value.$secret : null;
1993
+ }
1994
+ /** Classify one secret field for display: stored, unset, or environment-provided. */
1995
+ function pluginSecretState(value) {
1996
+ if (isPluginSecretRef(value)) {
1997
+ if (value.locked) return "environment";
1998
+ return typeof value.$secret === "string" ? "set" : "unset";
1999
+ }
2000
+ return typeof value === "string" && value.length > 0 ? "set" : "unset";
2001
+ }
2002
+ /** Human label for one secret field's state. */
2003
+ function pluginSecretLabel(value) {
2004
+ const state = pluginSecretState(value);
2005
+ if (state === "environment") return "Provided by environment";
2006
+ return state === "set" ? "Set" : "Not set";
2007
+ }
2008
+ /** Whether a secret field is read-only because the environment supplies it. */
2009
+ function isPluginSecretLocked(value) {
2010
+ return isPluginSecretRef(value) && value.locked === true;
2011
+ }
2012
+ /**
2013
+ * Value to submit for an untouched secret field: the reference, unchanged.
2014
+ *
2015
+ * A locked marker round-trips too, which is how the platform keeps a stored
2016
+ * value that an environment variable currently hides.
2017
+ */
2018
+ function keepPluginSecret(current) {
2019
+ if (isPluginSecretRef(current)) return { ...current };
2020
+ return null;
2021
+ }
2022
+ /** Value to submit when the user typed a new secret. */
2023
+ function setPluginSecret(value) {
2024
+ return value;
2025
+ }
2026
+ /** Value to submit when the user cleared a secret. */
2027
+ function clearPluginSecret() {
2028
+ return null;
2029
+ }
2030
+ /** Whether a settings response declares the `$secret` reference wire format. */
2031
+ function usesPluginSecretReferences(response) {
2032
+ if (!response || typeof response !== "object") return false;
2033
+ return response[PLUGIN_SECRET_FORMAT_KEY] === "ref";
2034
+ }
2035
+ //#endregion
2036
+ //#region src/components/SecretInput.vue?vue&type=script&setup=true&lang.ts
2037
+ var _hoisted_1$11 = { class: "mint-secret-input__status" };
2038
+ var _hoisted_2$10 = {
2039
+ key: 0,
2040
+ class: "mint-secret-input__hint"
2041
+ };
2042
+ var _hoisted_3$9 = { class: "mint-secret-input__actions" };
2043
+ //#endregion
2044
+ //#region src/components/SecretInput.vue
2045
+ var SecretInput_default = /* @__PURE__ */ defineComponent({
2046
+ __name: "SecretInput",
2047
+ props: {
2048
+ modelValue: { default: null },
2049
+ placeholder: { default: "Enter a new value" },
2050
+ disabled: {
2051
+ type: Boolean,
2052
+ default: false
2053
+ },
2054
+ error: {
2055
+ type: Boolean,
2056
+ default: false
2057
+ },
2058
+ size: { default: "md" },
2059
+ changeLabel: { default: "Change" },
2060
+ clearLabel: { default: "Clear" }
2061
+ },
2062
+ emits: ["update:modelValue"],
2063
+ setup(__props, { emit: __emit }) {
2064
+ /** Edits one plugin secret setting: shows set / not set / provided by environment, and submits a `$secret` reference, a new value, or `null`. */
2065
+ const props = __props;
2066
+ const emit = __emit;
2067
+ /** The reference this field started from, so an abandoned edit can restore it. */
2068
+ const storedReference = ref(keepPluginSecret(props.modelValue));
2069
+ const isEditing = ref(typeof props.modelValue === "string");
2070
+ watch(() => props.modelValue, (value) => {
2071
+ if (isPluginSecretRef(value)) {
2072
+ storedReference.value = keepPluginSecret(value);
2073
+ isEditing.value = false;
2074
+ }
2075
+ });
2076
+ const state = computed(() => pluginSecretState(props.modelValue));
2077
+ const locked = computed(() => isPluginSecretLocked(props.modelValue) || isPluginSecretLocked(storedReference.value));
2078
+ const statusLabel = computed(() => isEditing.value ? "New value" : pluginSecretLabel(props.modelValue));
2079
+ const typedValue = computed(() => typeof props.modelValue === "string" ? props.modelValue : "");
2080
+ const canClear = computed(() => !locked.value && (state.value === "set" || isEditing.value));
2081
+ function startEditing() {
2082
+ if (props.disabled || locked.value) return;
2083
+ isEditing.value = true;
2084
+ emit("update:modelValue", setPluginSecret(""));
2085
+ }
2086
+ function updateTyped(value) {
2087
+ emit("update:modelValue", setPluginSecret(value == null ? "" : String(value)));
2088
+ }
2089
+ function cancelEditing() {
2090
+ isEditing.value = false;
2091
+ emit("update:modelValue", storedReference.value ? { ...storedReference.value } : null);
2092
+ }
2093
+ function clear() {
2094
+ if (props.disabled || locked.value) return;
2095
+ isEditing.value = false;
2096
+ storedReference.value = null;
2097
+ emit("update:modelValue", clearPluginSecret());
2098
+ }
2099
+ return (_ctx, _cache) => {
2100
+ return openBlock(), createElementBlock("div", { class: normalizeClass(["mint-secret-input", { "mint-secret-input--error": __props.error }]) }, [
2101
+ createElementVNode("div", _hoisted_1$11, [createElementVNode("span", { class: normalizeClass(["mint-secret-input__badge", `mint-secret-input__badge--${isEditing.value ? "pending" : state.value}`]) }, toDisplayString(statusLabel.value), 3), locked.value ? (openBlock(), createElementBlock("span", _hoisted_2$10, " This value comes from the environment and cannot be edited here. ")) : createCommentVNode("", true)]),
2102
+ isEditing.value ? (openBlock(), createBlock(BaseInput_default, {
2103
+ key: 0,
2104
+ type: "password",
2105
+ autocomplete: "new-password",
2106
+ "model-value": typedValue.value,
2107
+ placeholder: __props.placeholder,
2108
+ disabled: __props.disabled,
2109
+ error: __props.error,
2110
+ size: __props.size,
2111
+ "onUpdate:modelValue": updateTyped
2112
+ }, null, 8, [
2113
+ "model-value",
2114
+ "placeholder",
2115
+ "disabled",
2116
+ "error",
2117
+ "size"
2118
+ ])) : createCommentVNode("", true),
2119
+ createElementVNode("div", _hoisted_3$9, [!isEditing.value ? (openBlock(), createBlock(BaseButton_default, {
2120
+ key: 0,
2121
+ type: "button",
2122
+ variant: "secondary",
2123
+ size: __props.size === "lg" ? "md" : "sm",
2124
+ disabled: __props.disabled || locked.value,
2125
+ onClick: startEditing
2126
+ }, {
2127
+ default: withCtx(() => [createTextVNode(toDisplayString(__props.changeLabel), 1)]),
2128
+ _: 1
2129
+ }, 8, ["size", "disabled"])) : (openBlock(), createBlock(BaseButton_default, {
2130
+ key: 1,
2131
+ type: "button",
2132
+ variant: "ghost",
2133
+ size: __props.size === "lg" ? "md" : "sm",
2134
+ disabled: __props.disabled,
2135
+ onClick: cancelEditing
2136
+ }, {
2137
+ default: withCtx(() => [..._cache[0] || (_cache[0] = [createTextVNode(" Cancel ", -1)])]),
2138
+ _: 1
2139
+ }, 8, ["size", "disabled"])), canClear.value ? (openBlock(), createBlock(BaseButton_default, {
2140
+ key: 2,
2141
+ type: "button",
2142
+ variant: "ghost",
2143
+ size: __props.size === "lg" ? "md" : "sm",
2144
+ disabled: __props.disabled,
2145
+ onClick: clear
2146
+ }, {
2147
+ default: withCtx(() => [createTextVNode(toDisplayString(__props.clearLabel), 1)]),
2148
+ _: 1
2149
+ }, 8, ["size", "disabled"])) : createCommentVNode("", true)])
2150
+ ], 2);
2151
+ };
2152
+ }
2153
+ });
2154
+ //#endregion
2869
2155
  //#region src/components/NumberInput.vue?vue&type=script&setup=true&lang.ts
2870
2156
  var _hoisted_1$10 = { class: "mint-number-input__field" };
2871
2157
  var _hoisted_2$9 = [
@@ -3063,7 +2349,7 @@ var _hoisted_6$6 = {
3063
2349
  viewBox: "0 0 24 24"
3064
2350
  };
3065
2351
  var _hoisted_7$6 = { class: "mint-file-uploader__text" };
3066
- var _hoisted_8$6 = {
2352
+ var _hoisted_8$5 = {
3067
2353
  key: 0,
3068
2354
  class: "mint-file-uploader__actions"
3069
2355
  };
@@ -3387,7 +2673,7 @@ var FileUploader_default = /* @__PURE__ */ defineComponent({
3387
2673
  createElementVNode("path", { d: "m16 16-4-4-4 4" }, null, -1),
3388
2674
  createElementVNode("path", { d: "M12 12v9" }, null, -1)
3389
2675
  ])])), createElementVNode("p", _hoisted_7$6, " Drop " + toDisplayString(acceptLabel.value) + " or click ", 1)])], 42, _hoisted_2$8),
3390
- _ctx.$slots.actions ? (openBlock(), createElementBlock("div", _hoisted_8$6, [renderSlot(_ctx.$slots, "actions")])) : createCommentVNode("", true),
2676
+ _ctx.$slots.actions ? (openBlock(), createElementBlock("div", _hoisted_8$5, [renderSlot(_ctx.$slots, "actions")])) : createCommentVNode("", true),
3391
2677
  isFolder.value && folderName.value && selectedFiles.value.length > 0 ? (openBlock(), createElementBlock("div", _hoisted_9$3, [createElementVNode("div", _hoisted_10$3, [_cache[2] || (_cache[2] = createElementVNode("div", { class: "mint-file-uploader__folder-icon-wrapper" }, [createElementVNode("svg", {
3392
2678
  class: "mint-file-uploader__folder-icon",
3393
2679
  fill: "none",
@@ -3492,7 +2778,7 @@ var _hoisted_6$5 = {
3492
2778
  class: "mint-alert__title"
3493
2779
  };
3494
2780
  var _hoisted_7$5 = { class: "mint-alert__message" };
3495
- var _hoisted_8$5 = {
2781
+ var _hoisted_8$4 = {
3496
2782
  key: 4,
3497
2783
  class: "mint-alert__actions"
3498
2784
  };
@@ -3547,7 +2833,7 @@ var AlertBox_default = /* @__PURE__ */ defineComponent({
3547
2833
  createElementVNode("path", { d: "M12 8h.01" }, null, -1)
3548
2834
  ])])),
3549
2835
  createElementVNode("div", _hoisted_5$5, [props.title ? (openBlock(), createElementBlock("h4", _hoisted_6$5, toDisplayString(props.title), 1)) : createCommentVNode("", true), createElementVNode("div", _hoisted_7$5, [renderSlot(_ctx.$slots, "default")])]),
3550
- hasActions() ? (openBlock(), createElementBlock("div", _hoisted_8$5, [renderSlot(_ctx.$slots, "actions", {}, () => [createElementVNode("button", {
2836
+ hasActions() ? (openBlock(), createElementBlock("div", _hoisted_8$4, [renderSlot(_ctx.$slots, "actions", {}, () => [createElementVNode("button", {
3551
2837
  type: "button",
3552
2838
  class: normalizeClass(["mint-alert__action-btn", `mint-alert__action-btn--${props.type}`]),
3553
2839
  onClick: _cache[0] || (_cache[0] = ($event) => emit("action"))
@@ -3579,25 +2865,29 @@ var _plugin_vue_export_helper_default = (sfc, props) => {
3579
2865
  return target;
3580
2866
  };
3581
2867
  //#endregion
2868
+ //#region src/utils/records.ts
2869
+ /** Narrow an unknown value to a plain object (arrays and null excluded). */
2870
+ function isRecord(value) {
2871
+ return typeof value === "object" && value !== null && !Array.isArray(value);
2872
+ }
2873
+ /** Narrow an unknown value to any non-null object, arrays included. */
2874
+ function isObjectLike(value) {
2875
+ return typeof value === "object" && value !== null;
2876
+ }
2877
+ //#endregion
3582
2878
  //#region src/components/DateTimePicker.vue?vue&type=script&setup=true&lang.ts
3583
2879
  var _hoisted_1$7 = { class: "mint-datetime-picker__input-wrapper" };
3584
2880
  var _hoisted_2$6 = [
2881
+ "aria-expanded",
3585
2882
  "value",
3586
2883
  "placeholder",
3587
2884
  "disabled"
3588
2885
  ];
3589
- var _hoisted_3$5 = {
3590
- key: 0,
3591
- class: "mint-datetime-picker__dropdown",
3592
- role: "dialog",
3593
- "aria-modal": "true",
3594
- "aria-label": "Date and time picker"
3595
- };
3596
- var _hoisted_4$5 = { class: "mint-datetime-picker__calendar-section" };
3597
- var _hoisted_5$4 = { class: "mint-datetime-picker__time-section" };
3598
- var _hoisted_6$4 = { class: "mint-datetime-picker__time-grid" };
3599
- var _hoisted_7$4 = ["disabled", "onClick"];
3600
- var _hoisted_8$4 = { class: "mint-datetime-picker__footer" };
2886
+ var _hoisted_3$5 = { class: "mint-datetime-picker__calendar-section" };
2887
+ var _hoisted_4$5 = { class: "mint-datetime-picker__time-section" };
2888
+ var _hoisted_5$4 = { class: "mint-datetime-picker__time-grid" };
2889
+ var _hoisted_6$4 = ["disabled", "onClick"];
2890
+ var _hoisted_7$4 = { class: "mint-datetime-picker__footer" };
3601
2891
  //#endregion
3602
2892
  //#region src/components/DateTimePicker.vue
3603
2893
  var DateTimePicker_default = /* @__PURE__ */ defineComponent({
@@ -3629,7 +2919,12 @@ var DateTimePicker_default = /* @__PURE__ */ defineComponent({
3629
2919
  /** Combined date and time picker with a dropdown calendar, time slots, and 12/24 h format support. */
3630
2920
  const props = __props;
3631
2921
  const emit = __emit;
3632
- const { isOpen, rootRef, close, toggle } = useDropdownState();
2922
+ const dropdownRef = ref(null);
2923
+ const { isOpen, rootRef, triggerRef, open, close, toggle } = useDropdownState();
2924
+ useFocusTrap({
2925
+ containerRef: dropdownRef,
2926
+ active: isOpen
2927
+ });
3633
2928
  const { weekDays, monthYear, calendarDays, formatDateValue, setCurrentMonthFromDate, prevMonth, nextMonth } = useCalendarGrid({
3634
2929
  min: () => props.min,
3635
2930
  max: () => props.max,
@@ -3703,15 +2998,30 @@ var DateTimePicker_default = /* @__PURE__ */ defineComponent({
3703
2998
  if (props.disabled) return;
3704
2999
  toggle();
3705
3000
  }
3706
- watch(isOpen, (open) => {
3707
- if (open && selectedDate.value) {
3708
- setCurrentMonthFromDate(selectedDate.value);
3709
- nextTick(() => {
3710
- const grid = rootRef.value?.querySelector(".mint-datetime-picker__time-grid");
3711
- const active = rootRef.value?.querySelector(".mint-datetime-picker__time-chip--active");
3712
- if (grid && active) active.scrollIntoView({ block: "center" });
3713
- });
3001
+ function handleTriggerKeydown(event) {
3002
+ if (props.disabled || isOpen.value) return;
3003
+ if (event.key === "Enter" || event.key === " " || event.key === "ArrowDown") {
3004
+ event.preventDefault();
3005
+ open();
3714
3006
  }
3007
+ }
3008
+ /** Moves focus into the calendar grid: selected day, else today, else the first day. */
3009
+ function focusCalendar() {
3010
+ const panel = dropdownRef.value;
3011
+ if (!panel) return;
3012
+ (panel.querySelector(".mint-date-picker__day--selected") ?? panel.querySelector(".mint-date-picker__day--today") ?? panel.querySelector(".mint-date-picker__day:not([disabled])"))?.focus();
3013
+ }
3014
+ watch(isOpen, async (opened) => {
3015
+ if (!opened) return;
3016
+ if (selectedDate.value) setCurrentMonthFromDate(selectedDate.value);
3017
+ await nextTick();
3018
+ if (selectedDate.value) {
3019
+ const grid = dropdownRef.value?.querySelector(".mint-datetime-picker__time-grid");
3020
+ const active = dropdownRef.value?.querySelector(".mint-datetime-picker__time-chip--active");
3021
+ if (grid && active) active.scrollIntoView({ block: "center" });
3022
+ }
3023
+ await nextTick();
3024
+ focusCalendar();
3715
3025
  });
3716
3026
  return (_ctx, _cache) => {
3717
3027
  return openBlock(), createElementBlock("div", {
@@ -3730,8 +3040,12 @@ var DateTimePicker_default = /* @__PURE__ */ defineComponent({
3730
3040
  d: "M8 7V3m8 4V3m-9 8h10M5 21h14a2 2 0 002-2V7a2 2 0 00-2-2H5a2 2 0 00-2 2v12a2 2 0 002 2z"
3731
3041
  })])], -1)),
3732
3042
  createElementVNode("input", {
3043
+ ref_key: "triggerRef",
3044
+ ref: triggerRef,
3733
3045
  type: "text",
3734
3046
  readonly: "",
3047
+ "aria-haspopup": "dialog",
3048
+ "aria-expanded": unref(isOpen),
3735
3049
  value: displayValue.value,
3736
3050
  placeholder: __props.placeholder,
3737
3051
  disabled: __props.disabled,
@@ -3742,8 +3056,9 @@ var DateTimePicker_default = /* @__PURE__ */ defineComponent({
3742
3056
  __props.disabled ? "mint-datetime-picker__input--disabled" : ""
3743
3057
  ]),
3744
3058
  "aria-label": "Select date and time",
3745
- onClick: toggleDropdown
3746
- }, null, 10, _hoisted_2$6),
3059
+ onClick: toggleDropdown,
3060
+ onKeydown: handleTriggerKeydown
3061
+ }, null, 42, _hoisted_2$6),
3747
3062
  _cache[1] || (_cache[1] = createElementVNode("div", { class: "mint-datetime-picker__icon-clock" }, [createElementVNode("svg", {
3748
3063
  fill: "none",
3749
3064
  stroke: "currentColor",
@@ -3762,8 +3077,15 @@ var DateTimePicker_default = /* @__PURE__ */ defineComponent({
3762
3077
  "leave-from-class": "mint-datetime-picker__dropdown-leave-from",
3763
3078
  "leave-to-class": "mint-datetime-picker__dropdown-leave-to"
3764
3079
  }, {
3765
- default: withCtx(() => [unref(isOpen) ? (openBlock(), createElementBlock("div", _hoisted_3$5, [
3766
- createElementVNode("div", _hoisted_4$5, [createVNode(CalendarGridPanelInternal_default, {
3080
+ default: withCtx(() => [unref(isOpen) ? (openBlock(), createElementBlock("div", {
3081
+ key: 0,
3082
+ ref_key: "dropdownRef",
3083
+ ref: dropdownRef,
3084
+ class: "mint-datetime-picker__dropdown",
3085
+ role: "dialog",
3086
+ "aria-label": "Date and time picker"
3087
+ }, [
3088
+ createElementVNode("div", _hoisted_3$5, [createVNode(CalendarGridPanelInternal_default, {
3767
3089
  "week-days": unref(weekDays),
3768
3090
  "month-year": unref(monthYear),
3769
3091
  days: unref(calendarDays),
@@ -3782,7 +3104,7 @@ var DateTimePicker_default = /* @__PURE__ */ defineComponent({
3782
3104
  "onNextMonth"
3783
3105
  ])]),
3784
3106
  _cache[3] || (_cache[3] = createElementVNode("div", { class: "mint-datetime-picker__divider" }, null, -1)),
3785
- createElementVNode("div", _hoisted_5$4, [_cache[2] || (_cache[2] = createElementVNode("div", { class: "mint-datetime-picker__time-label" }, "Time", -1)), createElementVNode("div", _hoisted_6$4, [(openBlock(true), createElementBlock(Fragment, null, renderList(timeSlots.value, (time) => {
3107
+ createElementVNode("div", _hoisted_4$5, [_cache[2] || (_cache[2] = createElementVNode("div", { class: "mint-datetime-picker__time-label" }, "Time", -1)), createElementVNode("div", _hoisted_5$4, [(openBlock(true), createElementBlock(Fragment, null, renderList(timeSlots.value, (time) => {
3786
3108
  return openBlock(), createElementBlock("button", {
3787
3109
  key: time,
3788
3110
  type: "button",
@@ -3793,9 +3115,9 @@ var DateTimePicker_default = /* @__PURE__ */ defineComponent({
3793
3115
  isTimeDisabled(time) ? "mint-datetime-picker__time-chip--disabled" : ""
3794
3116
  ]),
3795
3117
  onClick: ($event) => selectTime(time)
3796
- }, toDisplayString(unref(formatTimeSlot)(time, __props.timeFormat)), 11, _hoisted_7$4);
3118
+ }, toDisplayString(unref(formatTimeSlot)(time, __props.timeFormat)), 11, _hoisted_6$4);
3797
3119
  }), 128))])]),
3798
- createElementVNode("div", _hoisted_8$4, [createElementVNode("div", null, [createElementVNode("button", {
3120
+ createElementVNode("div", _hoisted_7$4, [createElementVNode("div", null, [createElementVNode("button", {
3799
3121
  type: "button",
3800
3122
  class: "mint-datetime-picker__footer-btn",
3801
3123
  onClick: goToToday
@@ -3809,13 +3131,215 @@ var DateTimePicker_default = /* @__PURE__ */ defineComponent({
3809
3131
  class: "mint-datetime-picker__footer-btn mint-datetime-picker__footer-btn--muted",
3810
3132
  onClick: clear
3811
3133
  }, " Clear ")) : createCommentVNode("", true)])
3812
- ])) : createCommentVNode("", true)]),
3134
+ ], 512)) : createCommentVNode("", true)]),
3813
3135
  _: 1
3814
3136
  })], 512);
3815
3137
  };
3816
3138
  }
3817
3139
  });
3818
3140
  //#endregion
3141
+ //#region src/composables/useEventStream.ts
3142
+ var EventStreamResponseError = class extends Error {
3143
+ constructor(response, label) {
3144
+ super(`${label} failed with HTTP ${response.status}`);
3145
+ this.response = response;
3146
+ this.name = "EventStreamResponseError";
3147
+ }
3148
+ };
3149
+ /** Parse one complete SSE block without owning connection policy. */
3150
+ function parseEventStreamBlock(block, parseJson) {
3151
+ let event = "message";
3152
+ let id;
3153
+ let retry;
3154
+ const dataLines = [];
3155
+ for (const line of block.split(/\r\n|\r|\n/)) {
3156
+ if (!line || line.startsWith(":")) continue;
3157
+ const separator = line.indexOf(":");
3158
+ const field = separator === -1 ? line : line.slice(0, separator);
3159
+ const value = separator === -1 ? "" : line.slice(separator + 1).replace(/^ /, "");
3160
+ if (field === "event") event = value || "message";
3161
+ if (field === "data") dataLines.push(value);
3162
+ if (field === "id" && !value.includes("\0")) id = value;
3163
+ if (field === "retry" && /^\d+$/.test(value)) retry = Number(value);
3164
+ }
3165
+ if (!dataLines.length && id === void 0 && retry === void 0) return null;
3166
+ const data = dataLines.join("\n");
3167
+ return {
3168
+ message: dataLines.length ? {
3169
+ event,
3170
+ data: parseJson && data ? JSON.parse(data) : data,
3171
+ id,
3172
+ retry,
3173
+ raw: block
3174
+ } : void 0,
3175
+ id,
3176
+ retry
3177
+ };
3178
+ }
3179
+ /** Shared fetch-based SSE lifecycle with cancellation and reconnect safety. */
3180
+ function useEventStream(url, options = {}) {
3181
+ const isConnected = ref(false);
3182
+ const isConnecting = ref(false);
3183
+ const error = ref(null);
3184
+ const lastMessage = shallowRef(null);
3185
+ const lastEventId = ref(null);
3186
+ let controller = null;
3187
+ let reader = null;
3188
+ let reconnectTimer = null;
3189
+ const settings = tryUseSettingsStore();
3190
+ const reconnectEnabled = options.reconnect ?? settings?.wsAutoReconnect ?? true;
3191
+ let reconnectDelayMs = options.reconnectDelayMs ?? settings?.wsReconnectInterval ?? 2e3;
3192
+ let stopped = true;
3193
+ let generation = 0;
3194
+ function clearReconnectTimer() {
3195
+ if (reconnectTimer === null) return;
3196
+ clearTimeout(reconnectTimer);
3197
+ reconnectTimer = null;
3198
+ }
3199
+ function ownsConnection(connectionGeneration, connectionController) {
3200
+ return !stopped && generation === connectionGeneration && controller === connectionController;
3201
+ }
3202
+ function scheduleReconnect(connectionGeneration, cause) {
3203
+ if (stopped || generation !== connectionGeneration) return;
3204
+ if (!reconnectEnabled || options.shouldReconnect?.(cause) === false) {
3205
+ stopped = true;
3206
+ return;
3207
+ }
3208
+ clearReconnectTimer();
3209
+ reconnectTimer = setTimeout(() => {
3210
+ reconnectTimer = null;
3211
+ if (stopped || generation !== connectionGeneration) return;
3212
+ connect(connectionGeneration);
3213
+ }, reconnectDelayMs);
3214
+ }
3215
+ function dispatchBlock(block, connectionGeneration, connectionController) {
3216
+ const parsed = parseEventStreamBlock(block, options.parseJson ?? false);
3217
+ if (!parsed || !ownsConnection(connectionGeneration, connectionController)) return;
3218
+ if (parsed.id !== void 0) {
3219
+ lastEventId.value = parsed.id;
3220
+ if (!ownsConnection(connectionGeneration, connectionController)) return;
3221
+ }
3222
+ if (parsed.retry !== void 0) reconnectDelayMs = parsed.retry;
3223
+ const message = parsed.message;
3224
+ if (!message || !ownsConnection(connectionGeneration, connectionController)) return;
3225
+ lastMessage.value = message;
3226
+ if (!ownsConnection(connectionGeneration, connectionController)) return;
3227
+ options.onMessage?.(message);
3228
+ }
3229
+ async function consume(body, connectionGeneration, connectionController) {
3230
+ const connectionReader = body.getReader();
3231
+ reader = connectionReader;
3232
+ const decoder = new TextDecoder();
3233
+ let buffer = "";
3234
+ try {
3235
+ for (;;) {
3236
+ const { value, done } = await connectionReader.read();
3237
+ if (!ownsConnection(connectionGeneration, connectionController)) return;
3238
+ buffer += decoder.decode(value, { stream: !done });
3239
+ let boundary = /(?:\r\n|\r|\n){2}/.exec(buffer);
3240
+ while (boundary?.index !== void 0) {
3241
+ const block = buffer.slice(0, boundary.index);
3242
+ buffer = buffer.slice(boundary.index + boundary[0].length);
3243
+ dispatchBlock(block, connectionGeneration, connectionController);
3244
+ if (!ownsConnection(connectionGeneration, connectionController)) return;
3245
+ boundary = /(?:\r\n|\r|\n){2}/.exec(buffer);
3246
+ }
3247
+ if (!done) continue;
3248
+ if (buffer) dispatchBlock(buffer, connectionGeneration, connectionController);
3249
+ return;
3250
+ }
3251
+ } finally {
3252
+ if (reader === connectionReader) reader = null;
3253
+ connectionReader.releaseLock();
3254
+ }
3255
+ }
3256
+ async function connect(connectionGeneration) {
3257
+ if (stopped || generation !== connectionGeneration) return;
3258
+ controller?.abort();
3259
+ const connectionController = new AbortController();
3260
+ controller = connectionController;
3261
+ isConnecting.value = true;
3262
+ if (!ownsConnection(connectionGeneration, connectionController)) return;
3263
+ error.value = null;
3264
+ if (!ownsConnection(connectionGeneration, connectionController)) return;
3265
+ let cause;
3266
+ try {
3267
+ const headers = new Headers(options.headers);
3268
+ headers.set("Accept", "text/event-stream");
3269
+ if (lastEventId.value && !headers.has("Last-Event-ID")) headers.set("Last-Event-ID", lastEventId.value);
3270
+ const transport = options.transport ?? globalThis.fetch?.bind(globalThis);
3271
+ if (!transport) throw new Error("[MINT SDK] fetch is required for event streams.");
3272
+ const response = await transport(typeof url === "function" ? url() : url, {
3273
+ method: "GET",
3274
+ headers,
3275
+ credentials: options.credentials ?? "same-origin",
3276
+ signal: connectionController.signal
3277
+ });
3278
+ if (!ownsConnection(connectionGeneration, connectionController)) return;
3279
+ if (!response.ok) throw new EventStreamResponseError(response, options.errorLabel ?? "Event stream");
3280
+ if (!response.body) throw new Error(`${options.errorLabel ?? "Event stream"} response did not include a readable body.`);
3281
+ isConnected.value = true;
3282
+ if (!ownsConnection(connectionGeneration, connectionController)) return;
3283
+ isConnecting.value = false;
3284
+ if (!ownsConnection(connectionGeneration, connectionController)) return;
3285
+ options.onOpen?.();
3286
+ if (!ownsConnection(connectionGeneration, connectionController)) return;
3287
+ await consume(response.body, connectionGeneration, connectionController);
3288
+ } catch (errorCause) {
3289
+ cause = errorCause;
3290
+ if (ownsConnection(connectionGeneration, connectionController) && !isAbortError(errorCause)) {
3291
+ error.value = errorCause instanceof Error ? errorCause.message : `${options.errorLabel ?? "Event stream"} failed`;
3292
+ if (ownsConnection(connectionGeneration, connectionController)) options.onError?.(errorCause);
3293
+ }
3294
+ } finally {
3295
+ if (ownsConnection(connectionGeneration, connectionController)) {
3296
+ isConnecting.value = false;
3297
+ if (!ownsConnection(connectionGeneration, connectionController)) return;
3298
+ isConnected.value = false;
3299
+ if (!ownsConnection(connectionGeneration, connectionController)) return;
3300
+ controller = null;
3301
+ options.onClose?.(cause);
3302
+ if (!stopped && generation === connectionGeneration) scheduleReconnect(connectionGeneration, cause);
3303
+ }
3304
+ }
3305
+ }
3306
+ function start() {
3307
+ if (!stopped) return;
3308
+ stopped = false;
3309
+ clearReconnectTimer();
3310
+ generation += 1;
3311
+ connect(generation);
3312
+ }
3313
+ function stop() {
3314
+ if (stopped) return;
3315
+ stopped = true;
3316
+ generation += 1;
3317
+ clearReconnectTimer();
3318
+ controller?.abort();
3319
+ controller = null;
3320
+ if (reader) reader.cancel().catch(() => void 0);
3321
+ reader = null;
3322
+ isConnecting.value = false;
3323
+ isConnected.value = false;
3324
+ }
3325
+ const currentInstance = getCurrentInstance();
3326
+ if (currentInstance && options.immediate !== false && typeof window === "undefined") onMounted(start);
3327
+ if (getCurrentScope()) onScopeDispose(stop);
3328
+ if (options.immediate !== false && (typeof window !== "undefined" || !currentInstance)) start();
3329
+ return {
3330
+ isConnected,
3331
+ isConnecting,
3332
+ error,
3333
+ lastMessage,
3334
+ lastEventId,
3335
+ start,
3336
+ stop
3337
+ };
3338
+ }
3339
+ function isAbortError(cause) {
3340
+ return cause instanceof DOMException && cause.name === "AbortError";
3341
+ }
3342
+ //#endregion
3819
3343
  //#region src/jobs.ts
3820
3344
  var ACTIVE_JOB_STATUSES = new Set([
3821
3345
  "awaiting_input",
@@ -3877,11 +3401,6 @@ function jobStatusLabel(status) {
3877
3401
  }
3878
3402
  //#endregion
3879
3403
  //#region src/composables/useGeneratedAnalysis.ts
3880
- var ACTIVE_STATUSES = new Set([
3881
- "awaiting_input",
3882
- "queued",
3883
- "running"
3884
- ]);
3885
3404
  var AUTH_TOKEN_KEY = "mint-auth-token";
3886
3405
  var SESSION_NOT_FOUND_DETAIL = "Session not found";
3887
3406
  var MAX_RESULT_CACHE_ENTRIES = 32;
@@ -3945,10 +3464,6 @@ function createPluginJobs(options, manifestPath) {
3945
3464
  const error = shallowRef(null);
3946
3465
  const status = shallowRef("idle");
3947
3466
  let pollTimer;
3948
- let streamReconnectTimer;
3949
- let streamController;
3950
- let streamConnected = false;
3951
- let streamConnecting = false;
3952
3467
  let disposed = false;
3953
3468
  let paused = false;
3954
3469
  let initialized = false;
@@ -3962,6 +3477,17 @@ function createPluginJobs(options, manifestPath) {
3962
3477
  const resultRetryAttempts = /* @__PURE__ */ new Map();
3963
3478
  const resultRetryTimers = /* @__PURE__ */ new Map();
3964
3479
  const downloadRefreshTimers = /* @__PURE__ */ new Map();
3480
+ const jobStream = useEventStream(`${baseUrl}/jobs/events`, {
3481
+ transport,
3482
+ immediate: false,
3483
+ reconnectDelayMs: streamReconnectDelay,
3484
+ parseJson: true,
3485
+ errorLabel: "Job stream",
3486
+ onOpen: clearPoll,
3487
+ onMessage: applyJobStreamMessage,
3488
+ onError: schedulePollForActiveJobs,
3489
+ onClose: schedulePollForActiveJobs
3490
+ });
3965
3491
  const latestResult = computed(() => {
3966
3492
  const job = currentCompletedJob();
3967
3493
  return job ? resultForJob(job.job_id) : null;
@@ -3985,7 +3511,7 @@ function createPluginJobs(options, manifestPath) {
3985
3511
  if (disposed) return;
3986
3512
  initialized = true;
3987
3513
  status.value = paused ? "paused" : "ready";
3988
- if (streamEnabled && !paused) connectJobStream();
3514
+ if (streamEnabled && !paused) jobStream.start();
3989
3515
  })().catch((cause) => {
3990
3516
  if (!disposed) {
3991
3517
  error.value = errorMessage(cause, "Failed to initialize generated analysis");
@@ -4030,7 +3556,7 @@ function createPluginJobs(options, manifestPath) {
4030
3556
  jobInput = await submitToSession(session.value.id, clientRequestId, await stagePathInputs(inputs, session.value.id, definitionId));
4031
3557
  }
4032
3558
  const job = upsertJob(jobInput, definitionId);
4033
- if (!streamConnected) schedulePoll();
3559
+ if (!jobStream.isConnected.value) schedulePoll();
4034
3560
  return job;
4035
3561
  } catch (cause) {
4036
3562
  error.value = errorMessage(cause, "Failed to submit analysis");
@@ -4126,12 +3652,12 @@ function createPluginJobs(options, manifestPath) {
4126
3652
  const pending = request("/jobs", { method: "GET" }).then((payload) => {
4127
3653
  if (disposed) return jobs.value;
4128
3654
  if (revision !== jobsRevision) {
4129
- if (jobs.value.some((job) => ACTIVE_STATUSES.has(job.status))) schedulePoll();
3655
+ if (jobs.value.some((job) => isActiveJobStatus(job.status))) schedulePoll();
4130
3656
  return jobs.value;
4131
3657
  }
4132
3658
  replaceJobs(payload.jobs);
4133
3659
  error.value = null;
4134
- if (!paused && !streamConnected && jobs.value.some((job) => ACTIVE_STATUSES.has(job.status))) schedulePoll();
3660
+ if (!paused && !jobStream.isConnected.value && jobs.value.some((job) => isActiveJobStatus(job.status))) schedulePoll();
4135
3661
  return jobs.value;
4136
3662
  }).finally(() => {
4137
3663
  if (refreshPromise === pending) refreshPromise = void 0;
@@ -4165,7 +3691,7 @@ function createPluginJobs(options, manifestPath) {
4165
3691
  if (options.signal?.aborted) return Promise.reject(pluginJobWaitAbort(options.signal));
4166
3692
  const jobId = jobIdFromReference(job);
4167
3693
  const current = typeof job === "string" ? jobs.value.find((candidate) => candidate.job_id === jobId) : jobs.value.find((candidate) => candidate.job_id === jobId) ?? job;
4168
- if (current && !ACTIVE_STATUSES.has(current.status)) return terminalWaitResult(current, options.rejectOnFailure === true);
3694
+ if (current && !isActiveJobStatus(current.status)) return terminalWaitResult(current, options.rejectOnFailure === true);
4169
3695
  if (paused) return Promise.reject(/* @__PURE__ */ new Error("Plugin jobs runtime is paused"));
4170
3696
  return new Promise((resolve, reject) => {
4171
3697
  const waiter = {
@@ -4185,12 +3711,12 @@ function createPluginJobs(options, manifestPath) {
4185
3711
  waiting.add(waiter);
4186
3712
  jobWaiters.set(jobId, waiting);
4187
3713
  if (!paused) {
4188
- if (streamEnabled) connectJobStream();
4189
- if (!streamConnected) schedulePoll();
3714
+ if (streamEnabled) jobStream.start();
3715
+ if (!jobStream.isConnected.value) schedulePoll();
4190
3716
  }
4191
3717
  getJob(jobId, { signal: options.signal }).catch((cause) => {
4192
3718
  if (current && isRetryableJobLookupError(cause)) {
4193
- if (!streamConnected) schedulePoll();
3719
+ if (!jobStream.isConnected.value) schedulePoll();
4194
3720
  return;
4195
3721
  }
4196
3722
  removeJobWaiter(jobId, waiter);
@@ -4199,7 +3725,7 @@ function createPluginJobs(options, manifestPath) {
4199
3725
  });
4200
3726
  }
4201
3727
  function settleJobWaiters(job) {
4202
- if (ACTIVE_STATUSES.has(job.status)) return;
3728
+ if (isActiveJobStatus(job.status)) return;
4203
3729
  const waiting = jobWaiters.get(job.job_id);
4204
3730
  if (!waiting) return;
4205
3731
  jobWaiters.delete(job.job_id);
@@ -4418,7 +3944,7 @@ function createPluginJobs(options, manifestPath) {
4418
3944
  resultRetryAttempts.delete(jobId);
4419
3945
  }
4420
3946
  function schedulePoll() {
4421
- if (disposed || paused || streamConnected || pollTimer !== void 0) return;
3947
+ if (disposed || paused || jobStream.isConnected.value || pollTimer !== void 0) return;
4422
3948
  pollTimer = setTimeout(async () => {
4423
3949
  pollTimer = void 0;
4424
3950
  if (disposed) return;
@@ -4426,80 +3952,25 @@ function createPluginJobs(options, manifestPath) {
4426
3952
  await refreshJobs();
4427
3953
  } catch (cause) {
4428
3954
  error.value = errorMessage(cause, "Failed to refresh analysis jobs");
4429
- if (jobs.value.some((job) => ACTIVE_STATUSES.has(job.status))) schedulePoll();
3955
+ if (jobs.value.some((job) => isActiveJobStatus(job.status))) schedulePoll();
4430
3956
  }
4431
3957
  }, pollInterval);
4432
3958
  }
4433
- async function connectJobStream() {
4434
- if (disposed || paused || streamConnecting || streamConnected) return;
4435
- streamConnecting = true;
4436
- streamController = new AbortController();
4437
- try {
4438
- const response = await transport(`${baseUrl}/jobs/events`, {
4439
- method: "GET",
4440
- headers: { Accept: "text/event-stream" },
4441
- signal: streamController.signal
4442
- });
4443
- if (!response.ok) throw new Error(`Job stream failed (${response.status})`);
4444
- if (!response.body) throw new Error("Job stream response has no readable body");
4445
- streamConnected = true;
4446
- if (pollTimer !== void 0) {
4447
- clearTimeout(pollTimer);
4448
- pollTimer = void 0;
4449
- }
4450
- await consumeJobStream(response.body);
4451
- } catch (cause) {
4452
- if (!isAbortError(cause) && !disposed) {
4453
- if (jobs.value.some((job) => ACTIVE_STATUSES.has(job.status))) schedulePoll();
4454
- }
4455
- } finally {
4456
- streamConnected = false;
4457
- streamConnecting = false;
4458
- streamController = void 0;
4459
- if (!disposed && !paused) scheduleStreamReconnect();
4460
- }
3959
+ function clearPoll() {
3960
+ if (pollTimer === void 0) return;
3961
+ clearTimeout(pollTimer);
3962
+ pollTimer = void 0;
4461
3963
  }
4462
- async function consumeJobStream(body) {
4463
- const reader = body.getReader();
4464
- const decoder = new TextDecoder();
4465
- let buffer = "";
4466
- try {
4467
- while (!disposed) {
4468
- const { done, value } = await reader.read();
4469
- buffer += decoder.decode(value, { stream: !done });
4470
- const blocks = buffer.split(/\r?\n\r?\n/);
4471
- buffer = blocks.pop() ?? "";
4472
- for (const block of blocks) applyJobStreamEvent(block);
4473
- if (done) {
4474
- if (buffer.trim()) applyJobStreamEvent(buffer);
4475
- return;
4476
- }
4477
- }
4478
- } finally {
4479
- reader.releaseLock();
4480
- }
3964
+ function schedulePollForActiveJobs() {
3965
+ if (jobs.value.some((job) => isActiveJobStatus(job.status))) schedulePoll();
4481
3966
  }
4482
- function applyJobStreamEvent(block) {
4483
- let event = "message";
4484
- const data = [];
4485
- for (const line of block.split(/\r?\n/)) {
4486
- if (!line || line.startsWith(":")) continue;
4487
- if (line.startsWith("event:")) event = line.slice(6).trim();
4488
- if (line.startsWith("data:")) data.push(line.slice(5).trimStart());
4489
- }
4490
- if (!data.length) return;
4491
- const payload = JSON.parse(data.join("\n"));
4492
- if (event === "snapshot" && "jobs" in payload) replaceJobs(payload.jobs);
4493
- else if (event === "job" || event === "terminal") upsertJob(payload);
3967
+ function applyJobStreamMessage(message) {
3968
+ if (message.event === "snapshot" && "jobs" in message.data) {
3969
+ const payload = message.data;
3970
+ replaceJobs(payload.jobs);
3971
+ } else if (message.event === "job" || message.event === "terminal") upsertJob(message.data);
4494
3972
  error.value = null;
4495
3973
  }
4496
- function scheduleStreamReconnect() {
4497
- if (disposed || paused || streamReconnectTimer !== void 0) return;
4498
- streamReconnectTimer = setTimeout(() => {
4499
- streamReconnectTimer = void 0;
4500
- connectJobStream();
4501
- }, streamReconnectDelay);
4502
- }
4503
3974
  async function cancelJob(job) {
4504
3975
  const jobId = typeof job === "string" ? job : job.job_id;
4505
3976
  const revision = beginJobOperation(jobId);
@@ -4534,13 +4005,10 @@ function createPluginJobs(options, manifestPath) {
4534
4005
  if (disposed || paused) return;
4535
4006
  paused = true;
4536
4007
  status.value = "paused";
4537
- if (pollTimer !== void 0) clearTimeout(pollTimer);
4538
- if (streamReconnectTimer !== void 0) clearTimeout(streamReconnectTimer);
4539
- pollTimer = void 0;
4540
- streamReconnectTimer = void 0;
4008
+ clearPoll();
4541
4009
  for (const jobId of resultRetryTimers.keys()) clearResultRetry(jobId);
4542
4010
  for (const jobId of downloadRefreshTimers.keys()) clearManagedDownloadRefresh(jobId);
4543
- streamController?.abort();
4011
+ jobStream.stop();
4544
4012
  }
4545
4013
  function resume() {
4546
4014
  if (disposed || !paused) return;
@@ -4548,18 +4016,15 @@ function createPluginJobs(options, manifestPath) {
4548
4016
  status.value = initialized ? "ready" : "idle";
4549
4017
  if (!initialized) return;
4550
4018
  for (const [jobId, result] of Object.entries(resultCache.value)) scheduleManagedDownloadRefresh(jobId, managedDownloadRefreshDelay(result));
4551
- if (streamEnabled) connectJobStream();
4552
- else if (jobs.value.some((job) => ACTIVE_STATUSES.has(job.status))) schedulePoll();
4019
+ if (streamEnabled) jobStream.start();
4020
+ else if (jobs.value.some((job) => isActiveJobStatus(job.status))) schedulePoll();
4553
4021
  }
4554
4022
  function dispose() {
4555
4023
  if (disposed) return;
4556
4024
  disposed = true;
4557
4025
  paused = true;
4558
4026
  status.value = "disposed";
4559
- if (pollTimer !== void 0) clearTimeout(pollTimer);
4560
- if (streamReconnectTimer !== void 0) clearTimeout(streamReconnectTimer);
4561
- pollTimer = void 0;
4562
- streamReconnectTimer = void 0;
4027
+ clearPoll();
4563
4028
  for (const timer of resultRetryTimers.values()) clearTimeout(timer);
4564
4029
  resultRetryTimers.clear();
4565
4030
  resultRetryAttempts.clear();
@@ -4569,7 +4034,7 @@ function createPluginJobs(options, manifestPath) {
4569
4034
  for (const jobId of jobWaiters.keys()) rejectJobWaiters(jobId, cause);
4570
4035
  jobRevisions.clear();
4571
4036
  pendingJobOperations.clear();
4572
- streamController?.abort();
4037
+ jobStream.stop();
4573
4038
  }
4574
4039
  async function request(path, init) {
4575
4040
  const response = await transport(`${baseUrl}${path}`, {
@@ -4685,9 +4150,6 @@ function createGeneratedSessionStorage(candidate) {
4685
4150
  }
4686
4151
  };
4687
4152
  }
4688
- function isAbortError(error) {
4689
- return error instanceof DOMException && error.name === "AbortError";
4690
- }
4691
4153
  function isSessionNotFoundError(error) {
4692
4154
  return error instanceof GeneratedAnalysisRequestError && error.status === 404 && error.detail === SESSION_NOT_FOUND_DETAIL;
4693
4155
  }
@@ -6802,6 +6264,11 @@ var registry = {
6802
6264
  defaults: { type: "password" },
6803
6265
  vModel: true
6804
6266
  },
6267
+ secret: {
6268
+ component: SecretInput_default,
6269
+ defaults: {},
6270
+ vModel: true
6271
+ },
6805
6272
  tel: {
6806
6273
  component: BaseInput_default,
6807
6274
  defaults: { type: "tel" },
@@ -6926,6 +6393,7 @@ function getTypeDefault(type) {
6926
6393
  case "slider": return;
6927
6394
  case "multiselect":
6928
6395
  case "tags": return [];
6396
+ case "secret": return null;
6929
6397
  default: return "";
6930
6398
  }
6931
6399
  }
@@ -7713,6 +7181,6 @@ function useControlSchema(controls, options = {}) {
7713
7181
  };
7714
7182
  }
7715
7183
  //#endregion
7716
- export { resolveJobCapabilities as $, useConcentrationUnits as A, BaseCheckbox_default as At, currentExperimentFromContext as B, controlsToViewIds as C, DatePicker_default as Ct, getTypeDefault as D, BaseSlider_default as Dt, getFieldRegistryEntry as E, useSelectionLimit as Et, ATOMIC_WEIGHTS as F, shift as Ft, createGeneratedAnalysisTransport as G, parseExperimentId as H, useChemicalFormula as I, BaseTextarea_default as It, isActiveJobStatus as J, useGeneratedAnalysis as K, GeneratedPathInput_default as L, SequenceInput_default as M, computePosition as Mt, useSequenceUtils as N, flip as Nt, ConcentrationInput_default as O, BaseRadioGroup_default as Ot, FormulaInput_default as P, offset as Pt, normalizeJobState as Q, ArtifactSelectorModal_default as R, controlsToTopBarSettingsConfig as S, useTimeUtils as St, getDefaultControlView as T, useListSelection as Tt, resolveCurrentExperimentId as U, getInjectedPlatformContext as V, resolveCurrentPluginId as W, jobStatusLabel as X, isTerminalJobStatus as Y, normalizeJobPercent as Z, controlsToFormSchema as _, isTimeInRange as _t, defineDoseCalculatorControlProps as a, TagsInput_default as at, controlsToSettingsSchema as b, snapToSlot as bt, defineWellPlateDoseComponentBindings as c, compareTime as ct, defineControlModel as d, findNearestTimeSlotIndex as dt, DateTimePicker_default as et, resolveControlModel as f, formatDuration as ft, mergeControlWorkspaceOptions as g, generateTimeSlots as gt, controlValuesToComponentProps as h, fromMinutes as ht, useControlSchema as i, NumberInput_default as it, MoleculeInput_default as j, Tooltip_default as jt, UnitInput_default as k, BaseToggle_default as kt, defineWellPlateDoseControlProps as l, durationMinutes as lt, controlValuesToComponentBindingsById as m, formatTimeSlot as mt, defineControls as n, AlertBox_default as nt, defineDoseDesignControlModel as o, TimePicker_default as ot, controlValuesToComponentBindings as p, formatTime as pt, usePluginJobs as q, getControlDefaults as r, FileUploader_default as rt, defineWellPlateControlProps as s, addMinutes as st, defineControlComponentBindings as t, _plugin_vue_export_helper_default as tt, useControlWorkspace as u, findAvailableSlots as ut, controlsToSectionFormSchema as v, parseTime as vt, controlsToViewItems as w, MultiSelect_default as wt, controlsToSidebarPanels as x, toMinutes as xt, controlsToSectionFormSchemas as y, rangesOverlap as yt, useAnalysisArtifacts as z };
7184
+ export { resolveJobCapabilities as $, useConcentrationUnits as A, formatTimeSlot as At, currentExperimentFromContext as B, MultiSelect_default as Bt, controlsToViewIds as C, addMinutes as Ct, getTypeDefault as D, findNearestTimeSlotIndex as Dt, getFieldRegistryEntry as E, findAvailableSlots as Et, ATOMIC_WEIGHTS as F, rangesOverlap as Ft, createGeneratedAnalysisTransport as G, BaseToggle_default as Gt, parseExperimentId as H, useSelectionLimit as Ht, useChemicalFormula as I, snapToSlot as It, isActiveJobStatus as J, BaseTextarea_default as Jt, useGeneratedAnalysis as K, BaseCheckbox_default as Kt, GeneratedPathInput_default as L, toMinutes as Lt, SequenceInput_default as M, generateTimeSlots as Mt, useSequenceUtils as N, isTimeInRange as Nt, ConcentrationInput_default as O, formatDuration as Ot, FormulaInput_default as P, parseTime as Pt, normalizeJobState as Q, ArtifactSelectorModal_default as R, useTimeUtils as Rt, controlsToTopBarSettingsConfig as S, TimePicker_default as St, getDefaultControlView as T, durationMinutes as Tt, resolveCurrentExperimentId as U, BaseSlider_default as Ut, getInjectedPlatformContext as V, useListSelection as Vt, resolveCurrentPluginId as W, BaseRadioGroup_default as Wt, jobStatusLabel as X, isTerminalJobStatus as Y, normalizeJobPercent as Z, controlsToFormSchema as _, pluginSecretLabel as _t, defineDoseCalculatorControlProps as a, AlertBox_default as at, controlsToSettingsSchema as b, usesPluginSecretReferences as bt, defineWellPlateDoseComponentBindings as c, SecretInput_default as ct, defineControlModel as d, PLUGIN_SECRET_REF_KEY as dt, useEventStream as et, resolveControlModel as f, clearPluginSecret as ft, mergeControlWorkspaceOptions as g, pluginSecretId as gt, controlValuesToComponentProps as h, keepPluginSecret as ht, useControlSchema as i, _plugin_vue_export_helper_default as it, MoleculeInput_default as j, fromMinutes as jt, UnitInput_default as k, formatTime as kt, defineWellPlateDoseControlProps as l, PLUGIN_SECRET_FORMAT_KEY as lt, controlValuesToComponentBindingsById as m, isPluginSecretRef as mt, defineControls as n, isObjectLike as nt, defineDoseDesignControlModel as o, FileUploader_default as ot, controlValuesToComponentBindings as p, isPluginSecretLocked as pt, usePluginJobs as q, Tooltip_default as qt, getControlDefaults as r, isRecord as rt, defineWellPlateControlProps as s, NumberInput_default as st, defineControlComponentBindings as t, DateTimePicker_default as tt, useControlWorkspace as u, PLUGIN_SECRET_FORMAT_REF as ut, controlsToSectionFormSchema as v, pluginSecretState as vt, controlsToViewItems as w, compareTime as wt, controlsToSidebarPanels as x, TagsInput_default as xt, controlsToSectionFormSchemas as y, setPluginSecret as yt, useAnalysisArtifacts as z, DatePicker_default as zt };
7717
7185
 
7718
- //# sourceMappingURL=useControlSchema-BhoJzWzx.js.map
7186
+ //# sourceMappingURL=useControlSchema-aMZlb4Sc.js.map