@morscherlab/mint-sdk 1.3.11 → 1.4.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 (1056) hide show
  1. package/README.md +152 -177
  2. package/dist/AlertBox-B2Bgr3ei.js +276 -0
  3. package/dist/AlertBox-B2Bgr3ei.js.map +1 -0
  4. package/dist/AppSidebar-mvm--GxN.js +3565 -0
  5. package/dist/AppSidebar-mvm--GxN.js.map +1 -0
  6. package/dist/ConfirmDialog-nbJj51is.js +102 -0
  7. package/dist/ConfirmDialog-nbJj51is.js.map +1 -0
  8. package/dist/ExperimentPopover-5T1fAq2L.js +337 -0
  9. package/dist/ExperimentPopover-5T1fAq2L.js.map +1 -0
  10. package/dist/ExperimentSelectorModal-65peG4Up.js +544 -0
  11. package/dist/ExperimentSelectorModal-65peG4Up.js.map +1 -0
  12. package/dist/SegmentedControl-BtnnjWzs.js +129 -0
  13. package/dist/SegmentedControl-BtnnjWzs.js.map +1 -0
  14. package/dist/SettingsModal-DO3IZ7qz.js +666 -0
  15. package/dist/SettingsModal-DO3IZ7qz.js.map +1 -0
  16. package/dist/analysisArtifactTypes-Cy3D0Ipg.js.map +1 -1
  17. package/dist/auth-SliLnFre.js +65 -0
  18. package/dist/auth-SliLnFre.js.map +1 -0
  19. package/dist/components/ActionMenu.vue.d.ts +1 -1
  20. package/dist/components/AdductText.vue.d.ts +1 -1
  21. package/dist/components/AlertBox.vue.d.ts +3 -3
  22. package/dist/components/AppContainer.vue.d.ts +1 -1
  23. package/dist/components/AppSidebar.vue.d.ts +15 -95
  24. package/dist/components/AppTopBar.vue.d.ts +16 -70
  25. package/dist/components/ArtifactSaveDialog.vue.d.ts +13 -5
  26. package/dist/components/ArtifactSelectorModal.vue.d.ts +4 -4
  27. package/dist/components/AuditTrail.vue.d.ts +2 -2
  28. package/dist/components/BaseButton.vue.d.ts +11 -4
  29. package/dist/components/BaseCheckbox.vue.d.ts +9 -3
  30. package/dist/components/BaseInput.vue.d.ts +13 -9
  31. package/dist/components/BaseModal.vue.d.ts +4 -4
  32. package/dist/components/BasePill.vue.d.ts +15 -8
  33. package/dist/components/BaseRadioGroup.vue.d.ts +2 -2
  34. package/dist/components/BaseSelect.vue.d.ts +51 -19
  35. package/dist/components/BaseTabs.vue.d.ts +6 -5
  36. package/dist/components/BatchProgressList.vue.d.ts +2 -2
  37. package/dist/components/ChartContainer.vue.d.ts +4 -2
  38. package/dist/components/ChemicalFormula.vue.d.ts +2 -2
  39. package/dist/components/CollapsibleCard.vue.d.ts +3 -3
  40. package/dist/components/ComponentBindingRenderer.vue.d.ts +2 -3
  41. package/dist/components/ConcentrationInput.vue.d.ts +2 -2
  42. package/dist/components/ConfirmDialog.vue.d.ts +8 -7
  43. package/dist/components/DataFrame.vue.d.ts +32 -74
  44. package/dist/components/DatePicker.vue.d.ts +24 -2
  45. package/dist/components/DoseCalculator.vue.d.ts +1 -1
  46. package/dist/components/DoseCalculatorVolumeField.vue.d.ts +1 -1
  47. package/dist/components/EmptyState.vue.d.ts +3 -2
  48. package/dist/components/ExperimentPopover.vue.d.ts +18 -0
  49. package/dist/components/ExperimentSelectorModal.vue.d.ts +3 -7
  50. package/dist/components/FilePicker.vue.d.ts +1 -1
  51. package/dist/components/FileUploader.vue.d.ts +2 -2
  52. package/dist/components/FormBuilder.vue.d.ts +17 -74
  53. package/dist/components/FormulaInput.vue.d.ts +2 -2
  54. package/dist/components/GeneratedPluginView.vue.d.ts +1 -1
  55. package/dist/components/GeneratedResultRenderer.vue.d.ts +5 -1
  56. package/dist/components/{StatusIndicator.vue.d.ts → InstrumentStatusPanels.vue.d.ts} +8 -9
  57. package/dist/components/JobsStatusTray.vue.d.ts +2 -9
  58. package/dist/components/LoadingSpinner.vue.d.ts +3 -3
  59. package/dist/components/MoleculeInput.vue.d.ts +2 -2
  60. package/dist/components/NumberInput.vue.d.ts +19 -5
  61. package/dist/components/PlateEditor.vue.d.ts +11 -61
  62. package/dist/components/PlotlyChart.vue.d.ts +2 -2
  63. package/dist/components/PluginIcon.vue.d.ts +5 -1
  64. package/dist/components/PluginWorkspaceView.controls.d.ts +2 -9
  65. package/dist/components/PluginWorkspaceView.navigation.d.ts +1 -7
  66. package/dist/components/PluginWorkspaceView.props.d.ts +18 -137
  67. package/dist/components/PluginWorkspaceView.shell.d.ts +2 -10
  68. package/dist/components/PluginWorkspaceView.vue.d.ts +14 -84
  69. package/dist/components/PresenceAvatars.vue.d.ts +31 -0
  70. package/dist/components/ProgressBar.vue.d.ts +3 -2
  71. package/dist/components/ProtocolStep.presentation.d.ts +0 -1
  72. package/dist/components/SampleHierarchyTree.vue.d.ts +3 -3
  73. package/dist/components/SampleSelector.vue.d.ts +8 -8
  74. package/dist/components/ScheduleCalendar.vue.d.ts +1 -1
  75. package/dist/components/ScientificNumber.vue.d.ts +1 -1
  76. package/dist/components/SecretInput.vue.d.ts +2 -2
  77. package/dist/components/SegmentedControl.vue.d.ts +2 -2
  78. package/dist/components/SequenceInput.vue.d.ts +2 -2
  79. package/dist/components/SequenceProgressBar.vue.d.ts +3 -0
  80. package/dist/components/SettingsModal.vue.d.ts +12 -20
  81. package/dist/components/SmartGroup.types.d.ts +0 -1
  82. package/dist/components/SmartGroupFieldRecipe.vue.d.ts +1 -1
  83. package/dist/components/StaleFormBanner.vue.d.ts +20 -0
  84. package/dist/components/StepWizard.vue.d.ts +3 -0
  85. package/dist/components/TagsInput.vue.d.ts +4 -3
  86. package/dist/components/TimeRangeInput.vue.d.ts +2 -2
  87. package/dist/components/VersionConflictDialog.vue.d.ts +24 -0
  88. package/dist/components/WellPlate.geometry.d.ts +0 -6
  89. package/dist/components/WellPlate.rendering.d.ts +0 -2
  90. package/dist/components/WellPlate.vue.d.ts +7 -52
  91. package/dist/components/index.d.ts +0 -90
  92. package/dist/components/{AutoGroupModal.adapter.d.ts → internal/AutoGroupModalInternal.adapter.d.ts} +6 -6
  93. package/dist/components/{AutoGroupModal.vue.d.ts → internal/AutoGroupModalInternal.vue.d.ts} +6 -6
  94. package/dist/components/{BaseToggle.vue.d.ts → internal/CheckboxSwitchInternal.vue.d.ts} +2 -2
  95. package/dist/components/{MultiSelect.vue.d.ts → internal/DatePickerDateInternal.vue.d.ts} +11 -9
  96. package/dist/components/{DateTimePicker.vue.d.ts → internal/DatePickerDateTimeInternal.vue.d.ts} +2 -2
  97. package/dist/components/{TimePicker.vue.d.ts → internal/DatePickerTimeInternal.vue.d.ts} +4 -4
  98. package/dist/components/internal/FilePickerListInternal.vue.d.ts +2 -2
  99. package/dist/components/internal/FormSchemaInternal.vue.d.ts +95 -0
  100. package/dist/components/{UnitInput.vue.d.ts → internal/NumberUnitInputInternal.vue.d.ts} +6 -14
  101. package/dist/components/internal/PlateEditorBindingInternal.vue.d.ts +3 -2
  102. package/dist/components/internal/ResourcePickerListInternal.vue.d.ts +5 -10
  103. package/dist/components/internal/SelectMultipleInternal.vue.d.ts +27 -0
  104. package/dist/components/{SearchableSelect.vue.d.ts → internal/SelectSearchableInternal.vue.d.ts} +5 -2
  105. package/dist/components/internal/WorkspaceShellInternal.vue.d.ts +1 -15
  106. package/dist/components/internal/WorkspaceSidebarInternal.vue.d.ts +4 -4
  107. package/dist/{composables → components/internal}/autoGroup/classKey.d.ts +1 -1
  108. package/dist/{composables → components/internal}/autoGroup/classify.d.ts +1 -1
  109. package/dist/{composables → components/internal}/autoGroup/columns.d.ts +1 -1
  110. package/dist/{composables → components/internal}/autoGroup/compose.d.ts +1 -1
  111. package/dist/{composables → components/internal}/autoGroup/cooccurrence.d.ts +1 -1
  112. package/dist/{composables → components/internal}/autoGroup/csv-shim.d.ts +1 -1
  113. package/dist/{composables → components/internal}/autoGroup/fingerprint.d.ts +1 -1
  114. package/dist/{composables → components/internal}/autoGroup/template.d.ts +1 -1
  115. package/dist/{composables → components/internal}/autoGroup/tokenLength.d.ts +1 -1
  116. package/dist/components/internal/generatedJobsApi.d.ts +1 -1
  117. package/dist/{composables → components/internal}/useAutoGroup.d.ts +9 -18
  118. package/dist/composables/componentSpecs.d.ts +41 -0
  119. package/dist/composables/controlComponentBindings.d.ts +6 -0
  120. package/dist/composables/controlSchemaAdapters.d.ts +28 -2
  121. package/dist/composables/controlSchemaDoseDesign.d.ts +1 -1
  122. package/dist/composables/controlSchemaModel.d.ts +1 -1
  123. package/dist/composables/controlSchemaTypes.d.ts +35 -23
  124. package/dist/composables/{usePluginClient.d.ts → createClient.d.ts} +22 -49
  125. package/dist/composables/{useEventStream.d.ts → eventStream.d.ts} +2 -2
  126. package/dist/composables/experiment-utils.d.ts +1 -6
  127. package/dist/composables/index.d.ts +7 -59
  128. package/dist/composables/platformContextHelpers.d.ts +0 -11
  129. package/dist/composables/pluginEndpointBuilder.d.ts +2 -2
  130. package/dist/composables/pluginIdentity.d.ts +24 -0
  131. package/dist/composables/pluginWorkspaceModel.d.ts +16 -99
  132. package/dist/composables/useApi.d.ts +1 -3
  133. package/dist/composables/useAppExperiment.d.ts +9 -1
  134. package/dist/composables/{useAnalysisArtifacts.d.ts → useArtifacts.d.ts} +6 -6
  135. package/dist/composables/useCalendarGrid.d.ts +1 -1
  136. package/dist/composables/useExperiment.d.ts +30 -0
  137. package/dist/composables/useExperimentSelector.d.ts +6 -2
  138. package/dist/composables/useFilePicker.d.ts +2 -2
  139. package/dist/composables/useJobCenter.d.ts +63 -0
  140. package/dist/composables/{useGeneratedAnalysis.d.ts → useJobsEndpoint.d.ts} +22 -23
  141. package/dist/composables/useMenuKeyboard.d.ts +1 -1
  142. package/dist/composables/usePlatform.d.ts +64 -0
  143. package/dist/composables/usePluginWorkspace.d.ts +6 -11
  144. package/dist/composables/usePresence.d.ts +41 -0
  145. package/dist/composables/useRackEditor.d.ts +2 -2
  146. package/dist/composables/useRealtime.d.ts +71 -0
  147. package/dist/composables/{useRequestSyncState.d.ts → useRequest.d.ts} +12 -17
  148. package/dist/composables/useToast.d.ts +7 -5
  149. package/dist/composables/useVersionedSave.d.ts +76 -0
  150. package/dist/controlSchemaModel-B8CTXagP.js +95 -0
  151. package/dist/controlSchemaModel-B8CTXagP.js.map +1 -0
  152. package/dist/data-CgILxDLW.js +3865 -0
  153. package/dist/data-CgILxDLW.js.map +1 -0
  154. package/dist/data.d.ts +32 -0
  155. package/dist/data.js +10 -0
  156. package/dist/deprecatedRootExports.d.ts +191 -0
  157. package/dist/experiment-43OJtH7R.js +673 -0
  158. package/dist/experiment-43OJtH7R.js.map +1 -0
  159. package/dist/experimentStatus-Cqp6qNrR.js +60 -0
  160. package/dist/experimentStatus-Cqp6qNrR.js.map +1 -0
  161. package/dist/host.d.ts +10 -0
  162. package/dist/host.js +26 -0
  163. package/dist/host.js.map +1 -0
  164. package/dist/index.d.ts +1 -12
  165. package/dist/index.js +65 -277
  166. package/dist/index.js.map +1 -1
  167. package/dist/install-CsPFJSx3.js +669 -0
  168. package/dist/install-CsPFJSx3.js.map +1 -0
  169. package/dist/install.d.ts +2 -1
  170. package/dist/install.js +1 -21
  171. package/dist/instrument.d.ts +0 -6
  172. package/dist/lab-MHzp-_J8.js +7494 -0
  173. package/dist/lab-MHzp-_J8.js.map +1 -0
  174. package/dist/lab.d.ts +42 -0
  175. package/dist/lab.js +5 -0
  176. package/dist/permissions.d.ts +0 -4
  177. package/dist/permissions.js +1 -20
  178. package/dist/permissions.js.map +1 -1
  179. package/dist/records-B6gpM_3e.js +3268 -0
  180. package/dist/records-B6gpM_3e.js.map +1 -0
  181. package/dist/runtime-8bs8EogX.js +1491 -0
  182. package/dist/runtime-8bs8EogX.js.map +1 -0
  183. package/dist/runtime.d.ts +25 -0
  184. package/dist/runtime.js +8 -0
  185. package/dist/shell-CywENwBT.js +197 -0
  186. package/dist/shell-CywENwBT.js.map +1 -0
  187. package/dist/shell.d.ts +16 -0
  188. package/dist/shell.js +8 -0
  189. package/dist/stores/auth.d.ts +13 -35
  190. package/dist/stores/experiment.d.ts +4 -0
  191. package/dist/stores/index.js +2 -2
  192. package/dist/styles.css +12161 -15036
  193. package/dist/types/analysisArtifactTypes.d.ts +1 -1
  194. package/dist/types/auth.d.ts +0 -8
  195. package/dist/types/componentLabTypes.d.ts +98 -34
  196. package/dist/types/componentWorkflowTypes.d.ts +2 -27
  197. package/dist/types/components.d.ts +145 -74
  198. package/dist/types/form-builder.d.ts +4 -0
  199. package/dist/types/generated/platformContext.d.ts +53 -0
  200. package/dist/types/generated-ui.d.ts +6 -2
  201. package/dist/types/index.d.ts +4 -5
  202. package/dist/types/instrument.d.ts +41 -0
  203. package/dist/types/platform.d.ts +20 -58
  204. package/dist/useDebouncedWatch-BPwyl6eS.js +73 -0
  205. package/dist/useDebouncedWatch-BPwyl6eS.js.map +1 -0
  206. package/dist/{experiment-utils-DTANyVKV.js → useDropdownState-8yWMu-7_.js} +127 -144
  207. package/dist/useDropdownState-8yWMu-7_.js.map +1 -0
  208. package/dist/useExpansionSet-CvoNMZJi.js +68 -0
  209. package/dist/useExpansionSet-CvoNMZJi.js.map +1 -0
  210. package/dist/useExperimentSamples-DHnxKFAF.js +366 -0
  211. package/dist/useExperimentSamples-DHnxKFAF.js.map +1 -0
  212. package/dist/useListReorder-BitdUhxn.js +5294 -0
  213. package/dist/useListReorder-BitdUhxn.js.map +1 -0
  214. package/dist/useRackEditor-DiwCt77M.js +5930 -0
  215. package/dist/useRackEditor-DiwCt77M.js.map +1 -0
  216. package/dist/useRealtime-C3iy9QkU.js +699 -0
  217. package/dist/useRealtime-C3iy9QkU.js.map +1 -0
  218. package/dist/useRequest-D506eHi8.js +244 -0
  219. package/dist/useRequest-D506eHi8.js.map +1 -0
  220. package/dist/utils/color.d.ts +0 -5
  221. package/dist/{composables/useDoseCalculator.d.ts → utils/dose.d.ts} +10 -13
  222. package/dist/utils/experimentStatus.d.ts +9 -0
  223. package/dist/{composables/useChemicalFormula.d.ts → utils/formula.d.ts} +3 -6
  224. package/dist/utils/integrationHost.d.ts +18 -0
  225. package/dist/utils/plotlyTemplate.d.ts +2 -0
  226. package/dist/utils/pluginSecrets.d.ts +12 -12
  227. package/dist/utils/presenceAvatars.d.ts +30 -0
  228. package/dist/utils/records.d.ts +0 -2
  229. package/dist/{composables/useTimeUtils.d.ts → utils/time.d.ts} +7 -18
  230. package/package.json +20 -17
  231. package/src/__tests__/components/ActionMenu.test.ts +0 -13
  232. package/src/__tests__/components/AlertBox.test.ts +1 -1
  233. package/src/__tests__/components/AppSidebar.test.ts +119 -167
  234. package/src/__tests__/components/AppToastContainer.test.ts +2 -2
  235. package/src/__tests__/components/AppTopBar.test.ts +230 -176
  236. package/src/__tests__/components/AppTopBarPillNav.test.ts +35 -0
  237. package/src/__tests__/components/ArtifactSaveDialog.test.ts +83 -3
  238. package/src/__tests__/components/ArtifactSelectorModal.test.ts +6 -4
  239. package/src/__tests__/components/AuditTrail.test.ts +1 -1
  240. package/src/__tests__/components/AutoGroupModal.adapter.test.ts +1 -1
  241. package/src/__tests__/components/AutoGroupModal.anatomy.test.ts +2 -2
  242. package/src/__tests__/components/AutoGroupModal.wiring.test.ts +2 -2
  243. package/src/__tests__/components/BaseButton.test.ts +51 -0
  244. package/src/__tests__/components/{BaseToggle.test.ts → BaseCheckbox.switch.test.ts} +8 -6
  245. package/src/__tests__/components/BaseInput.test.ts +13 -34
  246. package/src/__tests__/components/BaseModal.test.ts +6 -6
  247. package/src/__tests__/components/BasePill.test.ts +33 -39
  248. package/src/__tests__/components/BaseSelect.multiple.test.ts +118 -0
  249. package/src/__tests__/components/{SearchableSelect.test.ts → BaseSelect.searchable.test.ts} +19 -9
  250. package/src/__tests__/components/BaseSelect.test.ts +11 -0
  251. package/src/__tests__/components/BaseTabs.test.ts +13 -13
  252. package/src/__tests__/components/BatchProgressList.test.ts +16 -0
  253. package/src/__tests__/components/CalendarGridPanel.test.ts +2 -2
  254. package/src/__tests__/components/ChartContainer.test.ts +11 -0
  255. package/src/__tests__/components/ChemicalFormula.test.ts +6 -3
  256. package/src/__tests__/components/CollapsibleCard.test.ts +1 -1
  257. package/src/__tests__/components/ComponentBindingRenderer.test.ts +25 -73
  258. package/src/__tests__/components/ConcentrationInput.test.ts +3 -3
  259. package/src/__tests__/components/ConfirmDialog.test.ts +23 -0
  260. package/src/__tests__/components/DataFrame.test.ts +140 -142
  261. package/src/__tests__/components/DataStates.test.ts +6 -22
  262. package/src/__tests__/components/{DateTimePicker.test.ts → DatePicker.datetime.test.ts} +15 -7
  263. package/src/__tests__/components/DatePicker.test.ts +21 -0
  264. package/src/__tests__/components/{TimePicker.test.ts → DatePicker.time.test.ts} +20 -19
  265. package/src/__tests__/components/DoseCalculator.test.ts +12 -7
  266. package/src/__tests__/components/DoseCalculatorVolumeField.test.ts +6 -6
  267. package/src/__tests__/components/EmptyState.test.ts +1 -1
  268. package/src/__tests__/components/ExperimentPopover.test.ts +125 -16
  269. package/src/__tests__/components/ExperimentSelectorModal.test.ts +134 -28
  270. package/src/__tests__/components/FormBuilder.test.ts +49 -167
  271. package/src/__tests__/components/FormSchemaInternal.test.ts +91 -0
  272. package/src/__tests__/components/GeneratedPathInput.test.ts +18 -13
  273. package/src/__tests__/components/GeneratedPluginView.test.ts +60 -25
  274. package/src/__tests__/components/GeneratedResultRenderer.test.ts +6 -4
  275. package/src/__tests__/components/InstrumentStateBadge.test.ts +4 -4
  276. package/src/__tests__/components/InstrumentStatusPanels.test.ts +79 -0
  277. package/src/__tests__/components/JobsStatusTray.test.ts +4 -4
  278. package/src/__tests__/components/NumberInput.test.ts +28 -0
  279. package/src/__tests__/components/{UnitInput.test.ts → NumberInput.units.test.ts} +6 -6
  280. package/src/__tests__/components/PlateEditor.test.ts +108 -108
  281. package/src/__tests__/components/PlateEditorBindingInternal.test.ts +13 -13
  282. package/src/__tests__/components/PlotlyChart.test.ts +1 -1
  283. package/src/__tests__/components/PluginIcon.test.ts +9 -4
  284. package/src/__tests__/components/PluginWorkspaceView.controls.test.ts +16 -29
  285. package/src/__tests__/components/PluginWorkspaceView.internal.test.ts +28 -34
  286. package/src/__tests__/components/PluginWorkspaceView.navigation.test.ts +4 -19
  287. package/src/__tests__/components/PluginWorkspaceView.shell.test.ts +1 -6
  288. package/src/__tests__/components/PluginWorkspaceView.test.ts +183 -155
  289. package/src/__tests__/components/PresenceAvatars.test.ts +90 -0
  290. package/src/__tests__/components/ProtocolStep.presentation.test.ts +1 -3
  291. package/src/__tests__/components/ProtocolStepEditor.test.ts +10 -11
  292. package/src/__tests__/components/ProtocolStepParameterField.test.ts +8 -7
  293. package/src/__tests__/components/ResourcePickerListInternal.test.ts +2 -22
  294. package/src/__tests__/components/RetiredStyles.test.ts +0 -18
  295. package/src/__tests__/components/SampleSelector.test.ts +30 -25
  296. package/src/__tests__/components/SecretInput.test.ts +14 -19
  297. package/src/__tests__/components/SequenceProgressBar.test.ts +12 -0
  298. package/src/__tests__/components/SettingsModal.test.ts +76 -84
  299. package/src/__tests__/components/StaleFormBanner.test.ts +48 -0
  300. package/src/__tests__/components/StepWizard.test.ts +11 -0
  301. package/src/__tests__/components/ThemeToggle.test.ts +1 -1
  302. package/src/__tests__/components/WellPlate.decoration.test.ts +20 -11
  303. package/src/__tests__/components/WellPlate.interaction.test.ts +6 -7
  304. package/src/__tests__/components/WellPlate.keyboard.test.ts +2 -2
  305. package/src/__tests__/components/deprecationTags.test.ts +90 -0
  306. package/src/__tests__/composables/analysisArtifactTarget.test.ts +1 -12
  307. package/src/__tests__/composables/autoGroup/classKey.test.ts +1 -1
  308. package/src/__tests__/composables/autoGroup/classify.test.ts +1 -1
  309. package/src/__tests__/composables/autoGroup/columns.test.ts +1 -1
  310. package/src/__tests__/composables/autoGroup/compose.test.ts +1 -1
  311. package/src/__tests__/composables/autoGroup/cooccurrence.test.ts +1 -1
  312. package/src/__tests__/composables/autoGroup/fieldEdits.test.ts +1 -1
  313. package/src/__tests__/composables/autoGroup/fingerprint.test.ts +1 -1
  314. package/src/__tests__/composables/autoGroup/golden.test.ts +1 -1
  315. package/src/__tests__/composables/autoGroup/groupByOrder.test.ts +1 -1
  316. package/src/__tests__/composables/autoGroup/groupTree.test.ts +1 -1
  317. package/src/__tests__/composables/autoGroup/integration.test.ts +1 -1
  318. package/src/__tests__/composables/autoGroup/template.test.ts +1 -1
  319. package/src/__tests__/composables/autoGroup/tokenLength.test.ts +1 -1
  320. package/src/__tests__/composables/autoGroup/tokenize.test.ts +1 -1
  321. package/src/__tests__/composables/{usePluginClient.test.ts → createClient.test.ts} +84 -222
  322. package/src/__tests__/composables/{useEventStream.test.ts → eventStream.test.ts} +6 -6
  323. package/src/__tests__/composables/experiment-utils.test.ts +13 -14
  324. package/src/__tests__/composables/useApi.test.ts +32 -21
  325. package/src/__tests__/composables/useAppExperiment.test.ts +46 -3
  326. package/src/__tests__/composables/{useAnalysisArtifacts.test.ts → useArtifacts.test.ts} +19 -27
  327. package/src/__tests__/composables/useAutoGroup.test.ts +3 -13
  328. package/src/__tests__/composables/useCalendarGrid.test.ts +4 -2
  329. package/src/__tests__/composables/useControlSchema.test.ts +41 -99
  330. package/src/__tests__/composables/useExperiment.test.ts +63 -0
  331. package/src/__tests__/composables/useExperimentSelector.test.ts +111 -0
  332. package/src/__tests__/composables/useFileBrowser.test.ts +4 -6
  333. package/src/__tests__/composables/{useJobsStatusTray.test.ts → useJobCenter.test.ts} +31 -31
  334. package/src/__tests__/composables/{useGeneratedAnalysis.test.ts → useJobsEndpoint.test.ts} +213 -139
  335. package/src/__tests__/composables/usePlatform.test.ts +102 -0
  336. package/src/__tests__/composables/usePresence.test.ts +164 -0
  337. package/src/__tests__/composables/useRackEditor.test.ts +2 -2
  338. package/src/__tests__/composables/useRealtime.test.ts +196 -0
  339. package/src/__tests__/composables/{useRequestSyncState.test.ts → useRequest.test.ts} +32 -47
  340. package/src/__tests__/composables/useVersionedSave.test.ts +194 -0
  341. package/src/__tests__/docs/extractDocsComponents.test.ts +36 -0
  342. package/src/__tests__/docs/extractDocsParsing.test.ts +2 -2
  343. package/src/__tests__/docs/extractDocsTheme.test.ts +1 -46
  344. package/src/__tests__/docs/frontendDocsCatalog.test.ts +164 -84
  345. package/src/__tests__/styles/baseControlsRules.test.ts +7 -3
  346. package/src/__tests__/styles/controlRefreshRules.test.ts +0 -6
  347. package/src/__tests__/styles/cssTokens.test.ts +2 -2
  348. package/src/__tests__/styles/darkModeRules.test.ts +0 -6
  349. package/src/__tests__/styles/menusShellRefresh.test.ts +14 -10
  350. package/src/__tests__/{composables/useChemicalFormula.test.ts → utils/formula.test.ts} +3 -5
  351. package/src/__tests__/utils/permissions.test.ts +1 -36
  352. package/src/__tests__/utils/plotlyTemplate.test.ts +20 -5
  353. package/src/__tests__/{composables/useTimeUtils.test.ts → utils/time.test.ts} +18 -8
  354. package/src/components/ActionMenu.vue +7 -13
  355. package/src/components/AdductText.story.vue +7 -0
  356. package/src/components/AdductText.vue +1 -1
  357. package/src/components/AlertBox.story.vue +27 -27
  358. package/src/components/AlertBox.vue +22 -20
  359. package/src/components/AppLayout.story.vue +33 -44
  360. package/src/components/AppLayout.vue +1 -1
  361. package/src/components/AppSidebar.story.vue +40 -101
  362. package/src/components/AppSidebar.vue +66 -147
  363. package/src/components/AppToastContainer.story.vue +1 -1
  364. package/src/components/AppTopBar.story.vue +97 -111
  365. package/src/components/AppTopBar.vue +170 -290
  366. package/src/components/ArtifactSaveDialog.story.vue +32 -9
  367. package/src/components/ArtifactSaveDialog.vue +125 -38
  368. package/src/components/ArtifactSelectorModal.story.vue +4 -4
  369. package/src/components/ArtifactSelectorModal.vue +10 -10
  370. package/src/components/AuditTrail.story.vue +6 -5
  371. package/src/components/AuditTrail.vue +5 -24
  372. package/src/components/Avatar.story.vue +2 -3
  373. package/src/components/Avatar.vue +11 -16
  374. package/src/components/BaseButton.story.vue +25 -0
  375. package/src/components/BaseButton.vue +39 -10
  376. package/src/components/BaseCheckbox.story.vue +2 -2
  377. package/src/components/{BaseToggle.story.vue → BaseCheckbox.switch.story.vue} +22 -19
  378. package/src/components/BaseCheckbox.vue +39 -7
  379. package/src/components/BaseInput.story.vue +3 -15
  380. package/src/components/{BaseTextarea.story.vue → BaseInput.textarea.story.vue} +14 -10
  381. package/src/components/BaseInput.vue +53 -26
  382. package/src/components/BaseModal.story.vue +11 -11
  383. package/src/components/BaseModal.vue +8 -8
  384. package/src/components/BasePill.story.vue +48 -28
  385. package/src/components/BasePill.vue +22 -11
  386. package/src/components/BaseRadioGroup.story.vue +4 -4
  387. package/src/components/BaseRadioGroup.vue +3 -3
  388. package/src/components/{MultiSelect.story.vue → BaseSelect.multiple.story.vue} +33 -16
  389. package/src/components/{SearchableSelect.story.vue → BaseSelect.searchable.story.vue} +4 -4
  390. package/src/components/BaseSelect.story.vue +2 -2
  391. package/src/components/BaseSelect.vue +118 -22
  392. package/src/components/BaseTabs.story.vue +20 -20
  393. package/src/components/BaseTabs.vue +17 -9
  394. package/src/components/BatchProgressList.vue +38 -28
  395. package/src/components/ChartContainer.story.vue +9 -13
  396. package/src/components/ChartContainer.vue +10 -8
  397. package/src/components/ChemicalFormula.vue +1 -2
  398. package/src/components/CollapsibleCard.vue +5 -4
  399. package/src/components/ComponentBindingRenderer.story.vue +0 -29
  400. package/src/components/ComponentBindingRenderer.vue +15 -39
  401. package/src/components/ConcentrationInput.story.vue +2 -2
  402. package/src/components/ConcentrationInput.vue +9 -9
  403. package/src/components/ConfirmDialog.story.vue +22 -22
  404. package/src/components/ConfirmDialog.vue +15 -14
  405. package/src/components/DataFrame.story.vue +28 -40
  406. package/src/components/DataFrame.vue +112 -128
  407. package/src/components/{DateTimePicker.story.vue → DatePicker.datetime.story.vue} +19 -14
  408. package/src/components/DatePicker.story.vue +2 -2
  409. package/src/components/{TimePicker.story.vue → DatePicker.time.story.vue} +15 -12
  410. package/src/components/DatePicker.vue +82 -220
  411. package/src/components/DoseCalculator.vue +13 -19
  412. package/src/components/DoseCalculatorVolumeField.vue +6 -6
  413. package/src/components/EmptyState.story.vue +17 -17
  414. package/src/components/EmptyState.vue +6 -5
  415. package/src/components/ExperimentPopover.story.vue +165 -53
  416. package/src/components/ExperimentPopover.vue +172 -190
  417. package/src/components/ExperimentSelectorModal.story.vue +43 -39
  418. package/src/components/ExperimentSelectorModal.vue +134 -122
  419. package/src/components/FilePicker.vue +1 -1
  420. package/src/components/FormBuilder.story.vue +9 -4
  421. package/src/components/FormBuilder.vue +46 -253
  422. package/src/components/FormField.story.vue +9 -50
  423. package/src/components/FormulaInput.story.vue +2 -2
  424. package/src/components/FormulaInput.vue +5 -6
  425. package/src/components/GeneratedPathInput.vue +8 -9
  426. package/src/components/GeneratedPluginView.story.vue +1 -1
  427. package/src/components/GeneratedPluginView.vue +29 -22
  428. package/src/components/GeneratedResultRenderer.vue +16 -17
  429. package/src/components/InstrumentStateBadge.vue +1 -1
  430. package/src/components/InstrumentStatusPanels.story.vue +64 -0
  431. package/src/components/InstrumentStatusPanels.vue +133 -0
  432. package/src/components/JobsStatusTray.story.vue +2 -2
  433. package/src/components/JobsStatusTray.vue +5 -20
  434. package/src/components/LoadingSpinner.story.vue +11 -11
  435. package/src/components/LoadingSpinner.vue +7 -5
  436. package/src/components/MoleculeInput.story.vue +2 -2
  437. package/src/components/MoleculeInput.vue +3 -3
  438. package/src/components/NumberInput.story.vue +55 -15
  439. package/src/components/NumberInput.vue +83 -24
  440. package/src/components/PlateEditor.story.vue +51 -43
  441. package/src/components/PlateEditor.vue +97 -128
  442. package/src/components/PlotlyChart.story.vue +1 -1
  443. package/src/components/PlotlyChart.vue +6 -4
  444. package/src/components/PluginIcon.story.vue +6 -11
  445. package/src/components/PluginIcon.vue +7 -2
  446. package/src/components/PluginWorkspaceView.controls.ts +9 -29
  447. package/src/components/PluginWorkspaceView.navigation.ts +2 -23
  448. package/src/components/PluginWorkspaceView.props.ts +17 -151
  449. package/src/components/PluginWorkspaceView.shell.ts +13 -24
  450. package/src/components/PluginWorkspaceView.story.vue +65 -63
  451. package/src/components/PluginWorkspaceView.vue +21 -78
  452. package/src/components/PresenceAvatars.story.vue +75 -0
  453. package/src/components/PresenceAvatars.vue +114 -0
  454. package/src/components/ProgressBar.story.vue +7 -7
  455. package/src/components/ProgressBar.vue +4 -3
  456. package/src/components/ProtocolStep.presentation.ts +0 -11
  457. package/src/components/ProtocolStepEditor.vue +6 -5
  458. package/src/components/ProtocolStepParameterField.vue +15 -12
  459. package/src/components/RuntimeUpdateNotice.vue +1 -1
  460. package/src/components/SampleSelector.colors.ts +1 -1
  461. package/src/components/SampleSelector.story.vue +1 -1
  462. package/src/components/SampleSelector.vue +33 -43
  463. package/src/components/SampleSelectorGroupNode.vue +1 -1
  464. package/src/components/ScheduleCalendar.vue +4 -4
  465. package/src/components/SecretInput.story.vue +1 -1
  466. package/src/components/SecretInput.vue +16 -25
  467. package/src/components/SectionCard.story.vue +2 -2
  468. package/src/components/SegmentedControl.story.vue +7 -7
  469. package/src/components/SegmentedControl.vue +5 -3
  470. package/src/components/SequenceInput.story.vue +2 -2
  471. package/src/components/SequenceInput.vue +3 -3
  472. package/src/components/SequenceProgressBar.story.vue +9 -0
  473. package/src/components/SequenceProgressBar.vue +6 -1
  474. package/src/components/SettingsModal.schema.ts +1 -1
  475. package/src/components/SettingsModal.story.vue +13 -14
  476. package/src/components/SettingsModal.vue +31 -49
  477. package/src/components/SmartGroup.types.ts +4 -6
  478. package/src/components/SmartGroupFieldRecipe.story.vue +1 -1
  479. package/src/components/SmartGroupFieldRecipe.vue +7 -5
  480. package/src/components/SmartGroupManual.story.vue +1 -1
  481. package/src/components/StaleFormBanner.story.vue +90 -0
  482. package/src/components/StaleFormBanner.vue +83 -0
  483. package/src/components/StepWizard.story.vue +33 -0
  484. package/src/components/StepWizard.vue +8 -1
  485. package/src/components/TagsInput.story.vue +7 -7
  486. package/src/components/TagsInput.vue +7 -6
  487. package/src/components/ThemeToggle.vue +5 -30
  488. package/src/components/TimeRangeInput.story.vue +1 -1
  489. package/src/components/TimeRangeInput.vue +10 -8
  490. package/src/components/VersionConflictDialog.story.vue +60 -0
  491. package/src/components/VersionConflictDialog.vue +79 -0
  492. package/src/components/WellPlate.geometry.ts +0 -38
  493. package/src/components/WellPlate.rendering.ts +0 -13
  494. package/src/components/WellPlate.story.vue +64 -51
  495. package/src/components/WellPlate.vue +68 -87
  496. package/src/components/index.ts +3 -105
  497. package/src/components/internal/AppTopBarPillNavInternal.vue +33 -2
  498. package/src/components/{AutoGroupModal.adapter.ts → internal/AutoGroupModalInternal.adapter.ts} +8 -8
  499. package/src/components/{AutoGroupModal.vue → internal/AutoGroupModalInternal.vue} +23 -23
  500. package/src/components/{BaseToggle.vue → internal/CheckboxSwitchInternal.vue} +8 -8
  501. package/src/components/internal/DataStateInternal.vue +1 -1
  502. package/src/components/internal/DatePickerDateInternal.vue +219 -0
  503. package/src/components/{DateTimePicker.vue → internal/DatePickerDateTimeInternal.vue} +12 -22
  504. package/src/components/{TimePicker.vue → internal/DatePickerTimeInternal.vue} +12 -15
  505. package/src/components/internal/FilePickerListInternal.vue +8 -14
  506. package/src/components/{FormActions.vue → internal/FormActionsInternal.vue} +2 -2
  507. package/src/components/internal/FormFieldRendererInternal.vue +1 -1
  508. package/src/components/internal/FormSchemaInternal.vue +253 -0
  509. package/src/components/{UnitInput.vue → internal/NumberUnitInputInternal.vue} +28 -28
  510. package/src/components/internal/PlateEditorBindingInternal.vue +8 -7
  511. package/src/components/internal/ResourcePickerListInternal.vue +48 -88
  512. package/src/components/internal/SelectMultipleInternal.vue +242 -0
  513. package/src/components/{SearchableSelect.vue → internal/SelectSearchableInternal.vue} +26 -11
  514. package/src/components/internal/WellEditPopupInternal.vue +4 -9
  515. package/src/components/internal/WorkspaceShellInternal.vue +3 -36
  516. package/src/components/internal/WorkspaceSidebarInternal.vue +4 -25
  517. package/src/{composables → components/internal}/autoGroup/classKey.ts +1 -1
  518. package/src/{composables → components/internal}/autoGroup/classify.ts +1 -1
  519. package/src/{composables → components/internal}/autoGroup/columns.ts +1 -1
  520. package/src/{composables → components/internal}/autoGroup/compose.ts +3 -3
  521. package/src/{composables → components/internal}/autoGroup/cooccurrence.ts +1 -1
  522. package/src/{composables → components/internal}/autoGroup/csv-shim.ts +1 -1
  523. package/src/{composables → components/internal}/autoGroup/fingerprint.ts +1 -1
  524. package/src/{composables → components/internal}/autoGroup/index.ts +1 -2
  525. package/src/{composables → components/internal}/autoGroup/template.ts +1 -1
  526. package/src/{composables → components/internal}/autoGroup/tokenLength.ts +1 -1
  527. package/src/components/internal/generatedJobsApi.ts +1 -1
  528. package/src/{composables → components/internal}/useAutoGroup.ts +3 -57
  529. package/src/composables/componentSpecs.ts +62 -0
  530. package/src/composables/controlComponentBindings.ts +7 -0
  531. package/src/composables/controlSchemaAdapters.ts +45 -7
  532. package/src/composables/controlSchemaDoseDesign.ts +16 -5
  533. package/src/composables/controlSchemaModel.ts +1 -1
  534. package/src/composables/controlSchemaTypes.ts +31 -22
  535. package/src/composables/{usePluginClient.ts → createClient.ts} +54 -190
  536. package/src/composables/{useEventStream.ts → eventStream.ts} +3 -3
  537. package/src/composables/experiment-utils.ts +1 -39
  538. package/src/composables/formBuilderRegistry.ts +6 -12
  539. package/src/composables/index.ts +17 -480
  540. package/src/composables/platformContextHelpers.ts +0 -57
  541. package/src/composables/pluginEndpointBuilder.ts +8 -10
  542. package/src/composables/pluginIdentity.ts +31 -0
  543. package/src/composables/pluginWorkspaceModel.ts +16 -107
  544. package/src/composables/useApi.ts +18 -30
  545. package/src/composables/useAppExperiment.ts +26 -5
  546. package/src/composables/{useAnalysisArtifacts.ts → useArtifacts.ts} +18 -19
  547. package/src/composables/useCalendarGrid.ts +4 -3
  548. package/src/composables/useControlSchema.ts +5 -9
  549. package/src/composables/useControlWorkspace.ts +4 -7
  550. package/src/composables/useExperiment.ts +49 -0
  551. package/src/composables/useExperimentData.ts +4 -4
  552. package/src/composables/useExperimentSelector.ts +82 -36
  553. package/src/composables/useFileBrowser.ts +5 -13
  554. package/src/composables/useFilePicker.ts +2 -2
  555. package/src/composables/useFormBuilder.ts +3 -4
  556. package/src/composables/useJobCenter.ts +324 -0
  557. package/src/composables/{useGeneratedAnalysis.ts → useJobsEndpoint.ts} +53 -67
  558. package/src/composables/useMenuKeyboard.ts +1 -1
  559. package/src/composables/usePlatform.ts +95 -0
  560. package/src/composables/usePlatformFilePickerAdapter.ts +2 -1
  561. package/src/composables/usePluginWorkspace.ts +62 -107
  562. package/src/composables/usePresence.ts +110 -0
  563. package/src/composables/useRackEditor.ts +3 -3
  564. package/src/composables/useRealtime.ts +194 -0
  565. package/src/composables/{useRequestSyncState.ts → useRequest.ts} +25 -48
  566. package/src/composables/useScheduleCalendarLayout.ts +1 -1
  567. package/src/composables/useToast.ts +14 -11
  568. package/src/composables/useVersionedSave.ts +165 -0
  569. package/src/data.ts +130 -0
  570. package/src/deprecatedRootExports.ts +226 -0
  571. package/src/generated/schema.ts +1 -0
  572. package/src/host.ts +27 -0
  573. package/src/index.ts +2 -71
  574. package/src/install.ts +15 -2
  575. package/src/instrument.ts +1 -6
  576. package/src/lab.ts +128 -0
  577. package/src/permissions.ts +0 -27
  578. package/src/runtime.ts +145 -0
  579. package/src/shell.ts +103 -0
  580. package/src/stores/auth.ts +26 -162
  581. package/src/stores/experiment.ts +27 -1
  582. package/src/styles/components/action-menu.css +0 -5
  583. package/src/styles/components/adduct-text.css +13 -5
  584. package/src/styles/components/alert-box.css +39 -40
  585. package/src/styles/components/app-layout.css +6 -5
  586. package/src/styles/components/app-page-selector.css +3 -1
  587. package/src/styles/components/app-pill-nav.css +11 -12
  588. package/src/styles/components/app-sidebar.css +9 -18
  589. package/src/styles/components/app-top-bar.css +64 -103
  590. package/src/styles/components/artifact-save-dialog.css +153 -2
  591. package/src/styles/components/audit-trail.css +16 -19
  592. package/src/styles/components/avatar.css +6 -4
  593. package/src/styles/components/batch-progress-list.css +38 -36
  594. package/src/styles/components/button.css +40 -59
  595. package/src/styles/components/calendar.css +12 -12
  596. package/src/styles/components/chart-container.css +34 -23
  597. package/src/styles/components/checkbox.css +3 -13
  598. package/src/styles/components/collapsible-card.css +28 -30
  599. package/src/styles/components/confirm-dialog.css +31 -16
  600. package/src/styles/components/dataframe.css +12 -4
  601. package/src/styles/components/date-picker.css +80 -92
  602. package/src/styles/components/datetime-picker.css +31 -43
  603. package/src/styles/components/divider.css +20 -20
  604. package/src/styles/components/dose-calculator.css +3 -3
  605. package/src/styles/components/empty-state.css +23 -18
  606. package/src/styles/components/experiment-code-badge.css +2 -0
  607. package/src/styles/components/experiment-popover.css +174 -329
  608. package/src/styles/components/experiment-selector-modal.css +75 -56
  609. package/src/styles/components/file-picker.css +4 -4
  610. package/src/styles/components/file-uploader.css +38 -49
  611. package/src/styles/components/form-builder.css +3 -3
  612. package/src/styles/components/formula-input.css +1 -1
  613. package/src/styles/components/icon-button.css +19 -25
  614. package/src/styles/components/input.css +5 -4
  615. package/src/styles/components/instrument-monitor.css +13 -15
  616. package/src/styles/components/jobs-status-tray.css +31 -25
  617. package/src/styles/components/loading-spinner.css +9 -12
  618. package/src/styles/components/modal.css +2 -4
  619. package/src/styles/components/molecule-input.css +2 -2
  620. package/src/styles/components/multi-select.css +65 -112
  621. package/src/styles/components/number-input.css +26 -19
  622. package/src/styles/components/pill.css +43 -37
  623. package/src/styles/components/plate-editor.css +0 -1
  624. package/src/styles/components/plugin-icon.css +34 -22
  625. package/src/styles/components/popover.css +2 -2
  626. package/src/styles/components/presence-avatars.css +194 -0
  627. package/src/styles/components/progress-bar.css +2 -0
  628. package/src/styles/components/protocol-step-editor.css +1 -3
  629. package/src/styles/components/resource-card.css +2 -2
  630. package/src/styles/components/resource-picker-list.css +6 -57
  631. package/src/styles/components/sample-hierarchy-tree.css +4 -4
  632. package/src/styles/components/sample-selector.css +95 -79
  633. package/src/styles/components/schedule-calendar.css +8 -8
  634. package/src/styles/components/searchable-select.css +15 -12
  635. package/src/styles/components/section-card.css +28 -47
  636. package/src/styles/components/segmented-control.css +18 -15
  637. package/src/styles/components/select.css +3 -3
  638. package/src/styles/components/sequence-input.css +2 -2
  639. package/src/styles/components/sequence-progress-bar.css +17 -8
  640. package/src/styles/components/smart-group.css +19 -24
  641. package/src/styles/components/step-wizard.css +52 -16
  642. package/src/styles/components/tabs.css +2 -2
  643. package/src/styles/components/textarea.css +4 -4
  644. package/src/styles/components/time-picker.css +36 -21
  645. package/src/styles/components/toast.css +12 -10
  646. package/src/styles/components/toggle.css +3 -13
  647. package/src/styles/components/tooltip.css +10 -9
  648. package/src/styles/components/unit-input.css +8 -7
  649. package/src/styles/components/version-conflict.css +122 -0
  650. package/src/styles/components/well-plate.css +8 -8
  651. package/src/styles/index.css +2 -11
  652. package/src/styles/variables.css +107 -602
  653. package/src/types/analysisArtifactTypes.ts +1 -1
  654. package/src/types/auth.ts +0 -10
  655. package/src/types/componentLabTypes.ts +103 -53
  656. package/src/types/componentWorkflowTypes.ts +4 -33
  657. package/src/types/components.ts +148 -114
  658. package/src/types/form-builder.ts +4 -0
  659. package/src/types/generated/platformContext.ts +60 -0
  660. package/src/types/generated-ui.ts +6 -2
  661. package/src/types/index.ts +15 -53
  662. package/src/types/instrument.ts +27 -0
  663. package/src/types/platform.ts +25 -89
  664. package/src/utils/color.ts +1 -12
  665. package/src/utils/dose.ts +335 -0
  666. package/src/utils/experimentStatus.ts +43 -0
  667. package/src/utils/formula.ts +292 -0
  668. package/src/utils/integrationHost.ts +27 -0
  669. package/src/utils/plotlyTemplate.ts +6 -0
  670. package/src/utils/pluginSecrets.ts +23 -23
  671. package/src/utils/presenceAvatars.ts +53 -0
  672. package/src/utils/records.ts +0 -5
  673. package/src/{composables/useTimeUtils.ts → utils/time.ts} +21 -21
  674. package/dist/ResourcePickerListInternal-CFAw4vTZ.js +0 -605
  675. package/dist/ResourcePickerListInternal-CFAw4vTZ.js.map +0 -1
  676. package/dist/__tests__/composables/useBioTemplatePackWorkspace.test.d.ts +0 -1
  677. package/dist/__tests__/composables/useBioTemplatePresetWorkspace.test.d.ts +0 -1
  678. package/dist/__tests__/composables/useBioTemplateWorkspace.test.d.ts +0 -1
  679. package/dist/__tests__/composables/useChemicalFormula.test.d.ts +0 -1
  680. package/dist/__tests__/composables/useEventStream.test.d.ts +0 -1
  681. package/dist/__tests__/composables/useExperimentSave.test.d.ts +0 -1
  682. package/dist/__tests__/composables/useGeneratedAnalysis.test.d.ts +0 -1
  683. package/dist/__tests__/composables/useGroupAssignment.test.d.ts +0 -1
  684. package/dist/__tests__/composables/useJobsStatusTray.test.d.ts +0 -1
  685. package/dist/__tests__/composables/useMobileSupportGate.test.d.ts +0 -1
  686. package/dist/__tests__/composables/usePlatformContext.test.d.ts +0 -1
  687. package/dist/__tests__/composables/usePluginClient.test.d.ts +0 -1
  688. package/dist/__tests__/composables/usePresenceHeartbeat.test.d.ts +0 -1
  689. package/dist/__tests__/composables/useRequestSyncState.test.d.ts +0 -1
  690. package/dist/__tests__/composables/useRuntimeAlignment.test.d.ts +0 -1
  691. package/dist/__tests__/composables/useTemplateCollection.test.d.ts +0 -1
  692. package/dist/__tests__/composables/useTimeUtils.test.d.ts +0 -1
  693. package/dist/__tests__/docs/extractDocsTemplates.test.d.ts +0 -1
  694. package/dist/__tests__/templates/templates.test.d.ts +0 -1
  695. package/dist/__tests__/templates/templatesDeprecation.test.d.ts +0 -1
  696. package/dist/__tests__/utils/lcms.test.d.ts +0 -1
  697. package/dist/__tests__/utils/rack.test.d.ts +0 -1
  698. package/dist/components/AppAvatarMenu.vue.d.ts +0 -47
  699. package/dist/components/AppTopBar.navigation.d.ts +0 -10
  700. package/dist/components/BaseTextarea.vue.d.ts +0 -31
  701. package/dist/components/BioTemplateExperimentWorkspaceView.vue.d.ts +0 -112
  702. package/dist/components/BioTemplatePackWorkspaceView.vue.d.ts +0 -86
  703. package/dist/components/BioTemplatePresetWorkspaceView.vue.d.ts +0 -80
  704. package/dist/components/BioTemplateRenderer.vue.d.ts +0 -30
  705. package/dist/components/ControlWorkspaceView.vue.d.ts +0 -138
  706. package/dist/components/DoseDesignWorkspaceView.vue.d.ts +0 -140
  707. package/dist/components/ExperimentDataViewer.vue.d.ts +0 -54
  708. package/dist/components/ExperimentTimeline.vue.d.ts +0 -70
  709. package/dist/components/FitPanel.vue.d.ts +0 -56
  710. package/dist/components/GroupAssigner.vue.d.ts +0 -26
  711. package/dist/components/IconButton.vue.d.ts +0 -30
  712. package/dist/components/MobileSupportGate.vue.d.ts +0 -32
  713. package/dist/components/ReagentEditor.vue.d.ts +0 -31
  714. package/dist/components/ReagentList.presentation.d.ts +0 -17
  715. package/dist/components/ReagentList.vue.d.ts +0 -58
  716. package/dist/components/SampleLegend.vue.d.ts +0 -33
  717. package/dist/components/SmartGroupModal.vue.d.ts +0 -29
  718. package/dist/components/index.js +0 -5
  719. package/dist/components-BOA5e7kb.js +0 -23137
  720. package/dist/components-BOA5e7kb.js.map +0 -1
  721. package/dist/composables/flattenWorkspaceBindings.d.ts +0 -61
  722. package/dist/composables/index.js +0 -7
  723. package/dist/composables/useBioTemplateComponents.d.ts +0 -34
  724. package/dist/composables/useBioTemplateControls.d.ts +0 -10
  725. package/dist/composables/useBioTemplatePackWorkspace.d.ts +0 -56
  726. package/dist/composables/useBioTemplatePresetWorkspace.d.ts +0 -79
  727. package/dist/composables/useBioTemplateWorkspace.d.ts +0 -39
  728. package/dist/composables/useExperimentSave.d.ts +0 -69
  729. package/dist/composables/useGroupAssignment.d.ts +0 -35
  730. package/dist/composables/useJobsStatusTray.d.ts +0 -87
  731. package/dist/composables/useMobileSupportGate.d.ts +0 -14
  732. package/dist/composables/usePlatformContext.d.ts +0 -218
  733. package/dist/composables/usePresenceHeartbeat.d.ts +0 -49
  734. package/dist/composables/useRuntimeAlignment.d.ts +0 -44
  735. package/dist/composables/useTemplateCollection.d.ts +0 -62
  736. package/dist/composables/workspaceRecipes.d.ts +0 -189
  737. package/dist/composables-izSQH8Ky.js +0 -591
  738. package/dist/composables-izSQH8Ky.js.map +0 -1
  739. package/dist/experiment-D49y_Kro.js +0 -459
  740. package/dist/experiment-D49y_Kro.js.map +0 -1
  741. package/dist/experiment-utils-DTANyVKV.js.map +0 -1
  742. package/dist/install.js.map +0 -1
  743. package/dist/lcms.d.ts +0 -38
  744. package/dist/settings-BG6v13Zq.js +0 -341
  745. package/dist/settings-BG6v13Zq.js.map +0 -1
  746. package/dist/tailwind.preset.d.ts +0 -63
  747. package/dist/tailwind.preset.js +0 -71
  748. package/dist/tailwind.preset.js.map +0 -1
  749. package/dist/templates/adapters.d.ts +0 -19
  750. package/dist/templates/assayLookups.d.ts +0 -3
  751. package/dist/templates/assayMatrixAdapters.d.ts +0 -13
  752. package/dist/templates/assayMatrixBuilder.d.ts +0 -3
  753. package/dist/templates/assayNormalizers.d.ts +0 -4
  754. package/dist/templates/builderIdUtils.d.ts +0 -4
  755. package/dist/templates/builderPresetControls.d.ts +0 -11
  756. package/dist/templates/builderReadUtils.d.ts +0 -8
  757. package/dist/templates/builders.d.ts +0 -26
  758. package/dist/templates/calibrationCurveAdapters.d.ts +0 -7
  759. package/dist/templates/calibrationCurveBuilder.d.ts +0 -3
  760. package/dist/templates/calibrationNormalizers.d.ts +0 -5
  761. package/dist/templates/catalog.d.ts +0 -192
  762. package/dist/templates/componentBindingCatalog.d.ts +0 -25
  763. package/dist/templates/componentBindingHelpers.d.ts +0 -17
  764. package/dist/templates/componentBindings.d.ts +0 -97
  765. package/dist/templates/componentDoseResponseProps.d.ts +0 -3
  766. package/dist/templates/componentGenericProps.d.ts +0 -8
  767. package/dist/templates/componentPlateHelpers.d.ts +0 -11
  768. package/dist/templates/componentPlateMapProps.d.ts +0 -3
  769. package/dist/templates/componentPropsFactory.d.ts +0 -3
  770. package/dist/templates/componentQpcrPlateProps.d.ts +0 -3
  771. package/dist/templates/componentTargetResolvers.d.ts +0 -5
  772. package/dist/templates/componentTemplateProps.d.ts +0 -3
  773. package/dist/templates/controlSchemaClone.d.ts +0 -4
  774. package/dist/templates/controlSchemaConstants.d.ts +0 -10
  775. package/dist/templates/controlSchemaMerge.d.ts +0 -3
  776. package/dist/templates/controlSchemaTargets.d.ts +0 -17
  777. package/dist/templates/controlSchemaTypes.d.ts +0 -4
  778. package/dist/templates/controlSchemas.d.ts +0 -34
  779. package/dist/templates/defaultBioTemplateBuilder.d.ts +0 -3
  780. package/dist/templates/doseResponseAdapters.d.ts +0 -6
  781. package/dist/templates/doseResponseBuilder.d.ts +0 -3
  782. package/dist/templates/elisaAssayCollectionBuilder.d.ts +0 -3
  783. package/dist/templates/flowCytometryAssayCollectionBuilder.d.ts +0 -3
  784. package/dist/templates/flowCytometryPanelBuilder.d.ts +0 -3
  785. package/dist/templates/flowNormalizers.d.ts +0 -8
  786. package/dist/templates/flowPanelAdapters.d.ts +0 -7
  787. package/dist/templates/index.d.ts +0 -15
  788. package/dist/templates/index.js +0 -2
  789. package/dist/templates/instrumentRunAdapterHelpers.d.ts +0 -8
  790. package/dist/templates/instrumentRunAdapters.d.ts +0 -19
  791. package/dist/templates/instrumentRunBuilder.d.ts +0 -3
  792. package/dist/templates/lcmsBatchCollectionBuilder.d.ts +0 -3
  793. package/dist/templates/lookup.d.ts +0 -4
  794. package/dist/templates/packs.d.ts +0 -21
  795. package/dist/templates/plateMapAdapters.d.ts +0 -5
  796. package/dist/templates/plateMapBuilder.d.ts +0 -3
  797. package/dist/templates/presetControlSchemas.d.ts +0 -534
  798. package/dist/templates/presets.d.ts +0 -106
  799. package/dist/templates/protocolAdapters.d.ts +0 -9
  800. package/dist/templates/protocolNormalizers.d.ts +0 -6
  801. package/dist/templates/protocolStepsBuilder.d.ts +0 -3
  802. package/dist/templates/qpcrAdapters.d.ts +0 -9
  803. package/dist/templates/qpcrExpressionCollectionBuilder.d.ts +0 -3
  804. package/dist/templates/qpcrPlateBuilder.d.ts +0 -3
  805. package/dist/templates/reagentAdapters.d.ts +0 -9
  806. package/dist/templates/reagentListBuilder.d.ts +0 -3
  807. package/dist/templates/runNormalizers.d.ts +0 -10
  808. package/dist/templates/sampleNormalizers.d.ts +0 -4
  809. package/dist/templates/samplePrepAdapters.d.ts +0 -7
  810. package/dist/templates/samplePrepBuilder.d.ts +0 -3
  811. package/dist/templates/sampleSheetAdapters.d.ts +0 -9
  812. package/dist/templates/sampleSheetBuilder.d.ts +0 -3
  813. package/dist/templates/targetedMetabolomicsCollectionBuilder.d.ts +0 -3
  814. package/dist/templates/targetedMetabolomicsHelpers.d.ts +0 -5
  815. package/dist/templates/templateAdapterTypes.d.ts +0 -48
  816. package/dist/templates/templateControlSchemas.d.ts +0 -400
  817. package/dist/templates/templateCreateOptions.d.ts +0 -165
  818. package/dist/templates/templateEnvelopes.d.ts +0 -17
  819. package/dist/templates/templatePackCollectionBuilder.d.ts +0 -3
  820. package/dist/templates/templatePresetCollectionBuilder.d.ts +0 -20
  821. package/dist/templates/templateQpcrTypes.d.ts +0 -42
  822. package/dist/templates/templateValidators.d.ts +0 -25
  823. package/dist/templates/timeCourseAdapters.d.ts +0 -9
  824. package/dist/templates/timeCourseBuilder.d.ts +0 -3
  825. package/dist/templates/types.d.ts +0 -304
  826. package/dist/templates/wellPlateScreenCollectionBuilder.d.ts +0 -3
  827. package/dist/templates/westernBlotAssayCollectionBuilder.d.ts +0 -3
  828. package/dist/templates-B2DB0MCM.js +0 -12304
  829. package/dist/templates-B2DB0MCM.js.map +0 -1
  830. package/dist/utils/rack.d.ts +0 -63
  831. package/dist/validation-C_eH_vIg.js +0 -7999
  832. package/dist/validation-C_eH_vIg.js.map +0 -1
  833. package/src/__tests__/components/AppAvatarMenu.test.ts +0 -186
  834. package/src/__tests__/components/AppTopBar.navigation.test.ts +0 -68
  835. package/src/__tests__/components/AppTopBarPresence.test.ts +0 -47
  836. package/src/__tests__/components/BioTemplateExperimentWorkspaceView.test.ts +0 -159
  837. package/src/__tests__/components/BioTemplatePackWorkspaceView.test.ts +0 -192
  838. package/src/__tests__/components/BioTemplatePresetWorkspaceView.test.ts +0 -307
  839. package/src/__tests__/components/BioTemplateRenderer.test.ts +0 -96
  840. package/src/__tests__/components/ControlWorkspaceView.test.ts +0 -1100
  841. package/src/__tests__/components/DoseDesignWorkspaceView.test.ts +0 -183
  842. package/src/__tests__/components/ExperimentTimeline.test.ts +0 -108
  843. package/src/__tests__/components/FitPanel.test.ts +0 -96
  844. package/src/__tests__/components/GroupAssigner.test.ts +0 -101
  845. package/src/__tests__/components/MobileSupportGate.test.ts +0 -120
  846. package/src/__tests__/components/MultiSelect.test.ts +0 -54
  847. package/src/__tests__/components/ReagentList.presentation.test.ts +0 -73
  848. package/src/__tests__/components/ReagentList.test.ts +0 -167
  849. package/src/__tests__/components/SampleLegend.test.ts +0 -18
  850. package/src/__tests__/components/SmartGroupModal.test.ts +0 -69
  851. package/src/__tests__/components/WellPlate.sampleTypeIndicator.test.ts +0 -58
  852. package/src/__tests__/components/iconButtonIconSizing.test.ts +0 -18
  853. package/src/__tests__/composables/useBioTemplatePackWorkspace.test.ts +0 -125
  854. package/src/__tests__/composables/useBioTemplatePresetWorkspace.test.ts +0 -199
  855. package/src/__tests__/composables/useBioTemplateWorkspace.test.ts +0 -104
  856. package/src/__tests__/composables/useExperimentSave.test.ts +0 -542
  857. package/src/__tests__/composables/useGroupAssignment.test.ts +0 -73
  858. package/src/__tests__/composables/useMobileSupportGate.test.ts +0 -74
  859. package/src/__tests__/composables/usePlatformContext.test.ts +0 -148
  860. package/src/__tests__/composables/usePresenceHeartbeat.test.ts +0 -164
  861. package/src/__tests__/composables/useRuntimeAlignment.test.ts +0 -145
  862. package/src/__tests__/composables/useTemplateCollection.test.ts +0 -147
  863. package/src/__tests__/docs/extractDocsTemplates.test.ts +0 -53
  864. package/src/__tests__/fixtures/templates/dose-response.json +0 -81
  865. package/src/__tests__/fixtures/templates/plate-map.json +0 -54
  866. package/src/__tests__/fixtures/templates/qpcr-plate.json +0 -96
  867. package/src/__tests__/fixtures/templates/sample-sheet.json +0 -71
  868. package/src/__tests__/templates/templates.test.ts +0 -1235
  869. package/src/__tests__/templates/templatesDeprecation.test.ts +0 -78
  870. package/src/__tests__/utils/lcms.test.ts +0 -73
  871. package/src/__tests__/utils/rack.test.ts +0 -120
  872. package/src/components/AppAvatarMenu.story.vue +0 -155
  873. package/src/components/AppAvatarMenu.vue +0 -154
  874. package/src/components/AppTopBar.navigation.ts +0 -60
  875. package/src/components/AutoGroupModal.story.vue +0 -458
  876. package/src/components/BaseTextarea.vue +0 -58
  877. package/src/components/BioTemplateExperimentWorkspaceView.story.vue +0 -123
  878. package/src/components/BioTemplateExperimentWorkspaceView.vue +0 -339
  879. package/src/components/BioTemplatePackWorkspaceView.story.vue +0 -107
  880. package/src/components/BioTemplatePackWorkspaceView.vue +0 -180
  881. package/src/components/BioTemplatePresetWorkspaceView.story.vue +0 -163
  882. package/src/components/BioTemplatePresetWorkspaceView.vue +0 -403
  883. package/src/components/BioTemplateRenderer.story.vue +0 -57
  884. package/src/components/BioTemplateRenderer.vue +0 -64
  885. package/src/components/ControlWorkspaceView.story.vue +0 -347
  886. package/src/components/ControlWorkspaceView.vue +0 -370
  887. package/src/components/DoseDesignWorkspaceView.story.vue +0 -77
  888. package/src/components/DoseDesignWorkspaceView.vue +0 -243
  889. package/src/components/ExperimentDataViewer.story.vue +0 -177
  890. package/src/components/ExperimentDataViewer.vue +0 -313
  891. package/src/components/ExperimentTimeline.story.vue +0 -208
  892. package/src/components/ExperimentTimeline.vue +0 -383
  893. package/src/components/FitPanel.story.vue +0 -191
  894. package/src/components/FitPanel.vue +0 -168
  895. package/src/components/FormActions.story.vue +0 -96
  896. package/src/components/GroupAssigner.story.vue +0 -83
  897. package/src/components/GroupAssigner.vue +0 -319
  898. package/src/components/IconButton.story.vue +0 -140
  899. package/src/components/IconButton.vue +0 -69
  900. package/src/components/MobileSupportGate.story.vue +0 -52
  901. package/src/components/MobileSupportGate.vue +0 -111
  902. package/src/components/MultiSelect.vue +0 -119
  903. package/src/components/ReagentEditor.story.vue +0 -153
  904. package/src/components/ReagentEditor.vue +0 -414
  905. package/src/components/ReagentList.presentation.ts +0 -106
  906. package/src/components/ReagentList.story.vue +0 -155
  907. package/src/components/ReagentList.vue +0 -438
  908. package/src/components/SampleLegend.story.vue +0 -91
  909. package/src/components/SampleLegend.vue +0 -121
  910. package/src/components/SmartGroupModal.story.vue +0 -61
  911. package/src/components/SmartGroupModal.vue +0 -61
  912. package/src/components/StatusIndicator.story.vue +0 -99
  913. package/src/components/StatusIndicator.vue +0 -36
  914. package/src/components/UnitInput.story.vue +0 -194
  915. package/src/composables/flattenWorkspaceBindings.ts +0 -104
  916. package/src/composables/useBioTemplateComponents.ts +0 -117
  917. package/src/composables/useBioTemplateControls.ts +0 -45
  918. package/src/composables/useBioTemplatePackWorkspace.ts +0 -201
  919. package/src/composables/useBioTemplatePresetWorkspace.ts +0 -329
  920. package/src/composables/useBioTemplateWorkspace.ts +0 -120
  921. package/src/composables/useChemicalFormula.ts +0 -301
  922. package/src/composables/useDoseCalculator.ts +0 -370
  923. package/src/composables/useExperimentSave.ts +0 -348
  924. package/src/composables/useGroupAssignment.ts +0 -152
  925. package/src/composables/useJobsStatusTray.ts +0 -493
  926. package/src/composables/useMobileSupportGate.ts +0 -80
  927. package/src/composables/usePlatformContext.ts +0 -299
  928. package/src/composables/usePresenceHeartbeat.ts +0 -201
  929. package/src/composables/useRuntimeAlignment.ts +0 -184
  930. package/src/composables/useTemplateCollection.ts +0 -233
  931. package/src/composables/workspaceRecipes.ts +0 -268
  932. package/src/lcms.ts +0 -119
  933. package/src/styles/components/app-avatar-menu.css +0 -121
  934. package/src/styles/components/experiment-data-viewer.css +0 -138
  935. package/src/styles/components/experiment-timeline.css +0 -572
  936. package/src/styles/components/fit-panel.css +0 -153
  937. package/src/styles/components/group-assigner.css +0 -198
  938. package/src/styles/components/mobile-support-gate.css +0 -117
  939. package/src/styles/components/reagent-editor.css +0 -501
  940. package/src/styles/components/reagent-list.css +0 -408
  941. package/src/styles/components/sample-legend.css +0 -212
  942. package/src/styles/components/status-indicator.css +0 -66
  943. package/src/styles/components/theme-toggle.css +0 -6
  944. package/src/tailwind.preset.ts +0 -66
  945. package/src/templates/adapters.ts +0 -141
  946. package/src/templates/assayLookups.ts +0 -33
  947. package/src/templates/assayMatrixAdapters.ts +0 -85
  948. package/src/templates/assayMatrixBuilder.ts +0 -60
  949. package/src/templates/assayNormalizers.ts +0 -34
  950. package/src/templates/builderIdUtils.ts +0 -20
  951. package/src/templates/builderPresetControls.ts +0 -166
  952. package/src/templates/builderReadUtils.ts +0 -55
  953. package/src/templates/builders.ts +0 -122
  954. package/src/templates/calibrationCurveAdapters.ts +0 -62
  955. package/src/templates/calibrationCurveBuilder.ts +0 -100
  956. package/src/templates/calibrationNormalizers.ts +0 -60
  957. package/src/templates/catalog.ts +0 -249
  958. package/src/templates/componentBindingCatalog.ts +0 -90
  959. package/src/templates/componentBindingHelpers.ts +0 -93
  960. package/src/templates/componentBindings.ts +0 -279
  961. package/src/templates/componentDoseResponseProps.ts +0 -41
  962. package/src/templates/componentGenericProps.ts +0 -77
  963. package/src/templates/componentPlateHelpers.ts +0 -52
  964. package/src/templates/componentPlateMapProps.ts +0 -34
  965. package/src/templates/componentPropsFactory.ts +0 -21
  966. package/src/templates/componentQpcrPlateProps.ts +0 -27
  967. package/src/templates/componentTargetResolvers.ts +0 -67
  968. package/src/templates/componentTemplateProps.ts +0 -78
  969. package/src/templates/controlSchemaClone.ts +0 -32
  970. package/src/templates/controlSchemaConstants.ts +0 -11
  971. package/src/templates/controlSchemaMerge.ts +0 -40
  972. package/src/templates/controlSchemaTargets.ts +0 -85
  973. package/src/templates/controlSchemaTypes.ts +0 -20
  974. package/src/templates/controlSchemas.ts +0 -113
  975. package/src/templates/defaultBioTemplateBuilder.ts +0 -125
  976. package/src/templates/doseResponseAdapters.ts +0 -36
  977. package/src/templates/doseResponseBuilder.ts +0 -45
  978. package/src/templates/elisaAssayCollectionBuilder.ts +0 -63
  979. package/src/templates/flowCytometryAssayCollectionBuilder.ts +0 -42
  980. package/src/templates/flowCytometryPanelBuilder.ts +0 -54
  981. package/src/templates/flowNormalizers.ts +0 -58
  982. package/src/templates/flowPanelAdapters.ts +0 -61
  983. package/src/templates/index.ts +0 -330
  984. package/src/templates/instrumentRunAdapterHelpers.ts +0 -94
  985. package/src/templates/instrumentRunAdapters.ts +0 -174
  986. package/src/templates/instrumentRunBuilder.ts +0 -98
  987. package/src/templates/lcmsBatchCollectionBuilder.ts +0 -39
  988. package/src/templates/lookup.ts +0 -18
  989. package/src/templates/packs.ts +0 -166
  990. package/src/templates/plateMapAdapters.ts +0 -38
  991. package/src/templates/plateMapBuilder.ts +0 -44
  992. package/src/templates/presetControlSchemas.ts +0 -258
  993. package/src/templates/presets.ts +0 -183
  994. package/src/templates/protocolAdapters.ts +0 -73
  995. package/src/templates/protocolNormalizers.ts +0 -37
  996. package/src/templates/protocolStepsBuilder.ts +0 -37
  997. package/src/templates/qpcrAdapters.ts +0 -108
  998. package/src/templates/qpcrExpressionCollectionBuilder.ts +0 -34
  999. package/src/templates/qpcrPlateBuilder.ts +0 -97
  1000. package/src/templates/reagentAdapters.ts +0 -81
  1001. package/src/templates/reagentListBuilder.ts +0 -31
  1002. package/src/templates/runNormalizers.ts +0 -63
  1003. package/src/templates/sampleNormalizers.ts +0 -58
  1004. package/src/templates/samplePrepAdapters.ts +0 -66
  1005. package/src/templates/samplePrepBuilder.ts +0 -52
  1006. package/src/templates/sampleSheetAdapters.ts +0 -79
  1007. package/src/templates/sampleSheetBuilder.ts +0 -24
  1008. package/src/templates/targetedMetabolomicsCollectionBuilder.ts +0 -80
  1009. package/src/templates/targetedMetabolomicsHelpers.ts +0 -102
  1010. package/src/templates/templateAdapterTypes.ts +0 -58
  1011. package/src/templates/templateControlSchemas.ts +0 -320
  1012. package/src/templates/templateCreateOptions.ts +0 -208
  1013. package/src/templates/templateEnvelopes.ts +0 -145
  1014. package/src/templates/templatePackCollectionBuilder.ts +0 -24
  1015. package/src/templates/templatePresetCollectionBuilder.ts +0 -141
  1016. package/src/templates/templateQpcrTypes.ts +0 -48
  1017. package/src/templates/templateValidators.ts +0 -426
  1018. package/src/templates/timeCourseAdapters.ts +0 -77
  1019. package/src/templates/timeCourseBuilder.ts +0 -65
  1020. package/src/templates/types.ts +0 -493
  1021. package/src/templates/wellPlateScreenCollectionBuilder.ts +0 -37
  1022. package/src/templates/westernBlotAssayCollectionBuilder.ts +0 -69
  1023. package/src/utils/rack.ts +0 -225
  1024. /package/dist/__tests__/components/{AppAvatarMenu.test.d.ts → BaseButton.test.d.ts} +0 -0
  1025. /package/dist/__tests__/components/{AppTopBar.navigation.test.d.ts → BaseCheckbox.switch.test.d.ts} +0 -0
  1026. /package/dist/__tests__/components/{AppTopBarPresence.test.d.ts → BaseSelect.multiple.test.d.ts} +0 -0
  1027. /package/dist/__tests__/components/{BaseToggle.test.d.ts → BaseSelect.searchable.test.d.ts} +0 -0
  1028. /package/dist/__tests__/components/{BioTemplateExperimentWorkspaceView.test.d.ts → ConfirmDialog.test.d.ts} +0 -0
  1029. /package/dist/__tests__/components/{BioTemplatePackWorkspaceView.test.d.ts → DatePicker.datetime.test.d.ts} +0 -0
  1030. /package/dist/__tests__/components/{BioTemplatePresetWorkspaceView.test.d.ts → DatePicker.time.test.d.ts} +0 -0
  1031. /package/dist/__tests__/components/{BioTemplateRenderer.test.d.ts → FormSchemaInternal.test.d.ts} +0 -0
  1032. /package/dist/__tests__/components/{ControlWorkspaceView.test.d.ts → InstrumentStatusPanels.test.d.ts} +0 -0
  1033. /package/dist/__tests__/components/{DateTimePicker.test.d.ts → NumberInput.units.test.d.ts} +0 -0
  1034. /package/dist/__tests__/components/{DoseDesignWorkspaceView.test.d.ts → PresenceAvatars.test.d.ts} +0 -0
  1035. /package/dist/__tests__/components/{ExperimentTimeline.test.d.ts → StaleFormBanner.test.d.ts} +0 -0
  1036. /package/dist/__tests__/components/{FitPanel.test.d.ts → deprecationTags.test.d.ts} +0 -0
  1037. /package/dist/__tests__/{components/GroupAssigner.test.d.ts → composables/createClient.test.d.ts} +0 -0
  1038. /package/dist/__tests__/{components/MobileSupportGate.test.d.ts → composables/eventStream.test.d.ts} +0 -0
  1039. /package/dist/__tests__/{components/MultiSelect.test.d.ts → composables/useArtifacts.test.d.ts} +0 -0
  1040. /package/dist/__tests__/{components/ReagentList.presentation.test.d.ts → composables/useExperiment.test.d.ts} +0 -0
  1041. /package/dist/__tests__/{components/ReagentList.test.d.ts → composables/useJobCenter.test.d.ts} +0 -0
  1042. /package/dist/__tests__/{components/SampleLegend.test.d.ts → composables/useJobsEndpoint.test.d.ts} +0 -0
  1043. /package/dist/__tests__/{components/SearchableSelect.test.d.ts → composables/usePlatform.test.d.ts} +0 -0
  1044. /package/dist/__tests__/{components/SmartGroupModal.test.d.ts → composables/usePresence.test.d.ts} +0 -0
  1045. /package/dist/__tests__/{components/TimePicker.test.d.ts → composables/useRealtime.test.d.ts} +0 -0
  1046. /package/dist/__tests__/{components/UnitInput.test.d.ts → composables/useRequest.test.d.ts} +0 -0
  1047. /package/dist/__tests__/{components/WellPlate.sampleTypeIndicator.test.d.ts → composables/useVersionedSave.test.d.ts} +0 -0
  1048. /package/dist/__tests__/{components/iconButtonIconSizing.test.d.ts → utils/formula.test.d.ts} +0 -0
  1049. /package/dist/__tests__/{composables/useAnalysisArtifacts.test.d.ts → utils/time.test.d.ts} +0 -0
  1050. /package/dist/components/{FormActions.vue.d.ts → internal/FormActionsInternal.vue.d.ts} +0 -0
  1051. /package/dist/{composables → components/internal}/autoGroup/colors.d.ts +0 -0
  1052. /package/dist/{composables → components/internal}/autoGroup/index.d.ts +0 -0
  1053. /package/dist/{composables → components/internal}/autoGroup/tokenize.d.ts +0 -0
  1054. /package/src/{composables → components/internal}/autoGroup/colors.ts +0 -0
  1055. /package/src/{composables → components/internal}/autoGroup/tokenize.ts +0 -0
  1056. /package/src/{composables → components/internal}/autoGroup/vocab.json +0 -0
@@ -0,0 +1,3565 @@
1
+ import { a as BaseButton_default, i as useEventListener, t as useDropdownState } from "./useDropdownState-8yWMu-7_.js";
2
+ import { f as useSettingsStore, n as integrationHost } from "./experiment-43OJtH7R.js";
3
+ import { I as FormField_default, _ as APP_EXPERIMENT_KEY, t as isRecord, z as BaseCheckbox_default } from "./records-B6gpM_3e.js";
4
+ import { F as applySpecDefaults, _ as getFieldRegistryEntry, a as StepWizard_default, d as humanize, f as numericValue, l as normalizeControls, m as orderedUnique, o as usePlatform, s as defaultValueForControl, u as normalizeOption, v as getTypeDefault } from "./useListReorder-BitdUhxn.js";
5
+ import { Fragment, Transition, computed, createBlock, createCommentVNode, createElementBlock, createElementVNode, createSlots, createTextVNode, createVNode, defineAsyncComponent, defineComponent, guardReactiveProps, inject, mergeProps, normalizeClass, normalizeProps, normalizeStyle, onBeforeUnmount, onMounted, openBlock, reactive, readonly, ref, renderList, renderSlot, resolveComponent, resolveDynamicComponent, shallowRef, toDisplayString, toRaw, toValue, unref, useSlots, useTemplateRef, vShow, watch, withCtx, withDirectives, withModifiers } from "vue";
6
+ import { Moon, Sun } from "lucide-vue-next";
7
+ //#region src/composables/useTheme.ts
8
+ /** Reads and toggles the active theme (light/dark/system) with reactivity to OS preference changes. */
9
+ function useTheme() {
10
+ const settings = useSettingsStore();
11
+ settings.initialize();
12
+ const isDark = computed(() => settings.isDark());
13
+ function toggleTheme() {
14
+ settings.theme = isDark.value ? "light" : "dark";
15
+ }
16
+ function setTheme(theme) {
17
+ settings.theme = theme;
18
+ }
19
+ return {
20
+ isDark,
21
+ toggleTheme,
22
+ setTheme
23
+ };
24
+ }
25
+ //#endregion
26
+ //#region src/components/ThemeToggle.vue
27
+ var ThemeToggle_default = /* @__PURE__ */ defineComponent({
28
+ __name: "ThemeToggle",
29
+ props: { size: { default: "md" } },
30
+ setup(__props) {
31
+ /** Icon button that toggles between light and dark mode, swapping sun/moon icons to reflect the active theme. */
32
+ const { isDark, toggleTheme } = useTheme();
33
+ return (_ctx, _cache) => {
34
+ return openBlock(), createBlock(BaseButton_default, {
35
+ class: "mint-theme-toggle",
36
+ variant: "ghost",
37
+ size: __props.size,
38
+ icon: unref(isDark) ? unref(Sun) : unref(Moon),
39
+ label: unref(isDark) ? "Switch to light mode" : "Switch to dark mode",
40
+ onClick: unref(toggleTheme)
41
+ }, null, 8, [
42
+ "size",
43
+ "icon",
44
+ "label",
45
+ "onClick"
46
+ ]);
47
+ };
48
+ }
49
+ });
50
+ //#endregion
51
+ //#region src/components/CollapsibleCard.vue?vue&type=script&setup=true&lang.ts
52
+ var _hoisted_1$10 = { class: "mint-collapsible-card__header-shell" };
53
+ var _hoisted_2$8 = ["disabled", "aria-expanded"];
54
+ var _hoisted_3$8 = { class: "mint-collapsible-card__title-section" };
55
+ var _hoisted_4$7 = ["d"];
56
+ var _hoisted_5$7 = ["d"];
57
+ var _hoisted_6$6 = { class: "mint-collapsible-card__titles" };
58
+ var _hoisted_7$5 = { class: "mint-collapsible-card__title" };
59
+ var _hoisted_8$4 = {
60
+ key: 0,
61
+ class: "mint-collapsible-card__subtitle"
62
+ };
63
+ var _hoisted_9$4 = { class: "mint-collapsible-card__actions" };
64
+ var _hoisted_10$3 = [
65
+ "disabled",
66
+ "aria-label",
67
+ "title",
68
+ "onClick"
69
+ ];
70
+ var _hoisted_11$3 = {
71
+ key: 0,
72
+ class: "mint-collapsible-card__action-icon",
73
+ viewBox: "0 0 24 24",
74
+ fill: "none",
75
+ stroke: "currentColor",
76
+ "stroke-width": "2",
77
+ "stroke-linecap": "round",
78
+ "stroke-linejoin": "round",
79
+ "aria-hidden": "true"
80
+ };
81
+ var _hoisted_12$3 = ["d"];
82
+ var _hoisted_13$3 = ["d"];
83
+ var _hoisted_14$2 = {
84
+ key: 1,
85
+ class: "mint-collapsible-card__action-text-icon"
86
+ };
87
+ var _hoisted_15$2 = [
88
+ "disabled",
89
+ "aria-label",
90
+ "aria-expanded"
91
+ ];
92
+ var _hoisted_16$2 = { class: "mint-collapsible-card__body" };
93
+ var _hoisted_17$2 = { class: "mint-collapsible-card__content" };
94
+ //#endregion
95
+ //#region src/components/CollapsibleCard.vue
96
+ var CollapsibleCard_default = /* @__PURE__ */ defineComponent({
97
+ __name: "CollapsibleCard",
98
+ props: {
99
+ title: {},
100
+ subtitle: {},
101
+ badge: { default: void 0 },
102
+ badgeTone: { default: "cta" },
103
+ defaultOpen: {
104
+ type: Boolean,
105
+ default: false
106
+ },
107
+ disabled: {
108
+ type: Boolean,
109
+ default: false
110
+ },
111
+ dense: {
112
+ type: Boolean,
113
+ default: false
114
+ },
115
+ icon: {},
116
+ iconColor: {},
117
+ iconBg: {},
118
+ actions: { default: () => [] },
119
+ showToggle: {
120
+ type: Boolean,
121
+ default: false
122
+ },
123
+ toggleValue: {
124
+ type: Boolean,
125
+ default: false
126
+ },
127
+ toggleColor: { default: "" }
128
+ },
129
+ emits: ["update:toggleValue", "action"],
130
+ setup(__props, { emit: __emit }) {
131
+ /** Card whose body collapses with a chevron-rotate animation, with an optional inline toggle switch independent of expand state. */
132
+ const props = __props;
133
+ const emit = __emit;
134
+ const isOpen = ref(props.defaultOpen);
135
+ const toggle = () => {
136
+ if (!props.disabled) isOpen.value = !isOpen.value;
137
+ };
138
+ const headerClasses = computed(() => ["mint-collapsible-card__header", props.disabled ? "mint-collapsible-card__header--disabled" : ""]);
139
+ const iconBgStyle = computed(() => ({ backgroundColor: props.iconBg || "var(--color-primary-soft)" }));
140
+ const iconColorStyle = computed(() => ({ color: props.iconColor || "var(--color-primary)" }));
141
+ const isSvgIcon = computed(() => isSvgIconValue(props.icon));
142
+ const toggleColorStyle = computed(() => props.toggleColor ? { "--_cc-toggle-on": props.toggleColor } : void 0);
143
+ const badgeClasses = computed(() => ["mint-collapsible-card__badge", `mint-collapsible-card__badge--${props.badgeTone}`]);
144
+ function isSvgIconValue(icon) {
145
+ if (!icon) return false;
146
+ return Array.isArray(icon) || icon.startsWith("M") || icon.startsWith("m");
147
+ }
148
+ function actionClasses(action) {
149
+ return [
150
+ "mint-collapsible-card__action",
151
+ action.tone ? `mint-collapsible-card__action--${action.tone}` : "",
152
+ action.disabled ? "mint-collapsible-card__action--disabled" : ""
153
+ ];
154
+ }
155
+ function actionStyle(action) {
156
+ return action.iconColor ? { color: action.iconColor } : {};
157
+ }
158
+ function handleActionClick(action) {
159
+ if (props.disabled || action.disabled) return;
160
+ emit("action", action.id);
161
+ }
162
+ return (_ctx, _cache) => {
163
+ return openBlock(), createElementBlock("div", { class: normalizeClass(["mint-collapsible-card", __props.dense ? "mint-collapsible-card--dense" : ""]) }, [createElementVNode("div", _hoisted_1$10, [createElementVNode("button", {
164
+ type: "button",
165
+ class: normalizeClass(headerClasses.value),
166
+ disabled: __props.disabled,
167
+ "aria-expanded": isOpen.value,
168
+ onClick: toggle
169
+ }, [createElementVNode("div", _hoisted_3$8, [__props.icon ? (openBlock(), createElementBlock("div", {
170
+ key: 0,
171
+ class: "mint-collapsible-card__icon-badge",
172
+ style: normalizeStyle(iconBgStyle.value)
173
+ }, [isSvgIcon.value ? (openBlock(), createElementBlock("svg", {
174
+ key: 0,
175
+ class: "mint-collapsible-card__icon",
176
+ style: normalizeStyle(iconColorStyle.value),
177
+ viewBox: "0 0 24 24",
178
+ fill: "none",
179
+ stroke: "currentColor",
180
+ "stroke-width": "2",
181
+ "stroke-linecap": "round",
182
+ "stroke-linejoin": "round"
183
+ }, [Array.isArray(__props.icon) ? (openBlock(true), createElementBlock(Fragment, { key: 0 }, renderList(__props.icon, (d, i) => {
184
+ return openBlock(), createElementBlock("path", {
185
+ key: i,
186
+ d
187
+ }, null, 8, _hoisted_4$7);
188
+ }), 128)) : (openBlock(), createElementBlock("path", {
189
+ key: 1,
190
+ d: __props.icon
191
+ }, null, 8, _hoisted_5$7))], 4)) : (openBlock(), createElementBlock("span", {
192
+ key: 1,
193
+ class: "mint-collapsible-card__icon-text",
194
+ style: normalizeStyle(iconColorStyle.value)
195
+ }, toDisplayString(__props.icon), 5))], 4)) : createCommentVNode("", true), createElementVNode("div", _hoisted_6$6, [createElementVNode("h3", _hoisted_7$5, toDisplayString(__props.title), 1), __props.subtitle ? (openBlock(), createElementBlock("p", _hoisted_8$4, toDisplayString(__props.subtitle), 1)) : createCommentVNode("", true)])])], 10, _hoisted_2$8), createElementVNode("div", _hoisted_9$4, [
196
+ __props.badge !== void 0 ? (openBlock(), createElementBlock("span", {
197
+ key: 0,
198
+ class: normalizeClass(badgeClasses.value)
199
+ }, toDisplayString(__props.badge), 3)) : createCommentVNode("", true),
200
+ (openBlock(true), createElementBlock(Fragment, null, renderList(__props.actions, (action) => {
201
+ return openBlock(), createElementBlock("button", {
202
+ key: action.id,
203
+ type: "button",
204
+ class: normalizeClass(actionClasses(action)),
205
+ style: normalizeStyle(actionStyle(action)),
206
+ disabled: __props.disabled || action.disabled,
207
+ "aria-label": action.label,
208
+ title: action.label,
209
+ onClick: ($event) => handleActionClick(action)
210
+ }, [action.icon && isSvgIconValue(action.icon) ? (openBlock(), createElementBlock("svg", _hoisted_11$3, [Array.isArray(action.icon) ? (openBlock(true), createElementBlock(Fragment, { key: 0 }, renderList(action.icon, (d, i) => {
211
+ return openBlock(), createElementBlock("path", {
212
+ key: i,
213
+ d
214
+ }, null, 8, _hoisted_12$3);
215
+ }), 128)) : (openBlock(), createElementBlock("path", {
216
+ key: 1,
217
+ d: action.icon
218
+ }, null, 8, _hoisted_13$3))])) : action.icon ? (openBlock(), createElementBlock("span", _hoisted_14$2, toDisplayString(action.icon), 1)) : createCommentVNode("", true)], 14, _hoisted_10$3);
219
+ }), 128)),
220
+ __props.showToggle ? (openBlock(), createElementBlock("div", {
221
+ key: 1,
222
+ class: "mint-collapsible-card__toggle",
223
+ style: normalizeStyle(toggleColorStyle.value),
224
+ onClick: _cache[1] || (_cache[1] = withModifiers(() => {}, ["stop"]))
225
+ }, [createVNode(BaseCheckbox_default, {
226
+ type: "switch",
227
+ "model-value": __props.toggleValue,
228
+ "aria-label": __props.title,
229
+ "onUpdate:modelValue": _cache[0] || (_cache[0] = ($event) => emit("update:toggleValue", $event))
230
+ }, null, 8, ["model-value", "aria-label"])], 4)) : createCommentVNode("", true),
231
+ createElementVNode("button", {
232
+ type: "button",
233
+ class: "mint-collapsible-card__chevron-button",
234
+ disabled: __props.disabled,
235
+ "aria-label": isOpen.value ? "Collapse section" : "Expand section",
236
+ "aria-expanded": isOpen.value,
237
+ onClick: toggle
238
+ }, [(openBlock(), createElementBlock("svg", {
239
+ class: normalizeClass(["mint-collapsible-card__chevron", isOpen.value ? "mint-collapsible-card__chevron--open" : ""]),
240
+ fill: "none",
241
+ stroke: "currentColor",
242
+ "stroke-width": "2",
243
+ "stroke-linecap": "round",
244
+ "stroke-linejoin": "round",
245
+ viewBox: "0 0 24 24",
246
+ "aria-hidden": "true"
247
+ }, [..._cache[2] || (_cache[2] = [createElementVNode("path", { d: "m6 9 6 6 6-6" }, null, -1)])], 2))], 8, _hoisted_15$2)
248
+ ])]), createVNode(Transition, { name: "collapse" }, {
249
+ default: withCtx(() => [withDirectives(createElementVNode("div", _hoisted_16$2, [createElementVNode("div", _hoisted_17$2, [renderSlot(_ctx.$slots, "default")])], 512), [[vShow, isOpen.value]])]),
250
+ _: 3
251
+ })], 2);
252
+ };
253
+ }
254
+ });
255
+ //#endregion
256
+ //#region src/composables/controlSchemaFormFields.ts
257
+ function controlToFormField(control) {
258
+ const { name, definition, type } = control;
259
+ const props = fieldProps(definition);
260
+ return {
261
+ name,
262
+ label: definition.label ?? humanize(name),
263
+ type,
264
+ defaultValue: defaultValueForControl(definition, type),
265
+ placeholder: definition.placeholder,
266
+ hint: definition.hint,
267
+ icon: definition.icon,
268
+ iconColor: definition.iconColor,
269
+ iconBg: definition.iconBg,
270
+ size: definition.size,
271
+ disabled: definition.disabled,
272
+ readonly: definition.readonly,
273
+ validation: validationForControl(definition),
274
+ condition: definition.condition,
275
+ access: definition.access,
276
+ colSpan: definition.colSpan,
277
+ props
278
+ };
279
+ }
280
+ function fieldProps(definition) {
281
+ const props = {};
282
+ if (definition.min !== void 0) props.min = numericValue(definition.min);
283
+ if (definition.max !== void 0) props.max = numericValue(definition.max);
284
+ if (definition.options) props.options = definition.options.map(normalizeOption);
285
+ return {
286
+ ...props,
287
+ ...definition.props ?? {}
288
+ };
289
+ }
290
+ function validationForControl(definition) {
291
+ const validation = { ...definition.validation ?? {} };
292
+ if (definition.required !== void 0) validation.required = definition.required;
293
+ if (definition.min !== void 0) validation.min = definition.min;
294
+ if (definition.max !== void 0) validation.max = definition.max;
295
+ if (definition.minLength !== void 0) validation.minLength = definition.minLength;
296
+ if (definition.maxLength !== void 0) validation.maxLength = definition.maxLength;
297
+ if (definition.email !== void 0) validation.email = definition.email;
298
+ if (definition.pattern !== void 0) validation.pattern = definition.pattern;
299
+ return Object.keys(validation).length > 0 ? validation : void 0;
300
+ }
301
+ //#endregion
302
+ //#region src/composables/controlSchemaLayout.ts
303
+ function sectionConfig(sectionId, controls, options) {
304
+ const configured = options.sections?.[sectionId];
305
+ const first = controls[0]?.definition;
306
+ return {
307
+ ...configured,
308
+ id: sectionId,
309
+ label: configured?.label ?? first?.sectionLabel,
310
+ title: configured?.title ?? first?.sectionLabel,
311
+ description: configured?.description ?? first?.sectionDescription,
312
+ subtitle: configured?.subtitle ?? first?.sectionSubtitle
313
+ };
314
+ }
315
+ function firstSidebarConfig(controls) {
316
+ for (const control of controls) {
317
+ const sidebar = control.definition.sidebar;
318
+ if (sidebar && typeof sidebar === "object" && sidebar.enabled !== false) return sidebar;
319
+ }
320
+ }
321
+ function isSidebarEnabled(sidebar) {
322
+ if (sidebar === false) return false;
323
+ if (sidebar && typeof sidebar === "object") return sidebar.enabled !== false;
324
+ return true;
325
+ }
326
+ function controlViewItem(viewId, options) {
327
+ const config = options.views?.[viewId];
328
+ return {
329
+ id: viewId,
330
+ label: config?.label ?? humanize(viewId),
331
+ ...config?.icon !== void 0 ? { icon: config.icon } : {},
332
+ ...config?.to !== void 0 ? { to: config.to } : {},
333
+ ...config?.href !== void 0 ? { href: config.href } : {},
334
+ ...config?.disabled !== void 0 ? { disabled: config.disabled } : {},
335
+ ...config?.children !== void 0 ? { children: config.children } : {}
336
+ };
337
+ }
338
+ //#endregion
339
+ //#region src/composables/controlSchemaAdapters.ts
340
+ /** Convert a compact control schema into a FormBuilder schema. */
341
+ function controlsToFormSchema(controls, options = {}) {
342
+ const normalized = normalizeControls(controls, options);
343
+ return {
344
+ sections: orderedUnique(normalized.map((control) => control.sectionId)).map((sectionId) => {
345
+ const sectionControls = normalized.filter((control) => control.sectionId === sectionId);
346
+ const config = sectionConfig(sectionId, sectionControls, options);
347
+ return {
348
+ id: sectionId,
349
+ title: config.title ?? config.label ?? humanize(sectionId),
350
+ description: config.description,
351
+ columns: config.columns ?? options.columns ?? 1,
352
+ defaultOpen: config.defaultOpen,
353
+ condition: config.condition,
354
+ fields: sectionControls.map(controlToFormField)
355
+ };
356
+ }),
357
+ ...controlFormActions(options.actions)
358
+ };
359
+ }
360
+ function controlFormActions(actions) {
361
+ if (!actions) return {};
362
+ return {
363
+ actions: true,
364
+ ...actions === true ? {} : actions
365
+ };
366
+ }
367
+ /** Convert controls into AppSidebar panels grouped by view and section. */
368
+ function controlsToSidebarPanels(controls, options = {}) {
369
+ const normalized = normalizeControls(controls, options).filter((control) => isSidebarEnabled(control.definition.sidebar));
370
+ const viewIds = orderedUnique(normalized.map((control) => control.viewId));
371
+ const panels = {};
372
+ for (const viewId of viewIds) {
373
+ const viewControls = normalized.filter((control) => control.viewId === viewId);
374
+ panels[viewId] = orderedUnique(viewControls.map((control) => control.sectionId)).map((sectionId) => {
375
+ const sectionControls = viewControls.filter((control) => control.sectionId === sectionId);
376
+ const config = sectionConfig(sectionId, sectionControls, options);
377
+ const sidebarConfig = firstSidebarConfig(sectionControls);
378
+ return {
379
+ id: sectionId,
380
+ label: sidebarConfig?.label ?? config.label ?? config.title ?? humanize(sectionId),
381
+ subtitle: sidebarConfig?.subtitle ?? config.subtitle,
382
+ icon: sidebarConfig?.icon ?? config.icon,
383
+ iconColor: sidebarConfig?.iconColor ?? config.iconColor,
384
+ iconBg: sidebarConfig?.iconBg ?? config.iconBg,
385
+ badge: sidebarConfig?.badge ?? config.badge,
386
+ badgeTone: sidebarConfig?.badgeTone ?? config.badgeTone,
387
+ actions: sidebarConfig?.actions ?? config.actions,
388
+ defaultOpen: sidebarConfig?.defaultOpen ?? config.defaultOpen,
389
+ showToggle: sidebarConfig?.showToggle ?? config.showToggle
390
+ };
391
+ });
392
+ }
393
+ return panels;
394
+ }
395
+ /** Convert controls into a SettingsModal schema grouped by the same sections. */
396
+ function controlsToSettingsSchema(controls, options = {}) {
397
+ const normalized = normalizeControls(controls, options);
398
+ return { groups: orderedUnique(normalized.map((control) => control.sectionId)).map((sectionId) => {
399
+ const sectionControls = normalized.filter((control) => control.sectionId === sectionId);
400
+ const config = sectionConfig(sectionId, sectionControls, options);
401
+ return {
402
+ id: sectionId,
403
+ label: config.label ?? config.title ?? humanize(sectionId),
404
+ description: config.description ?? config.subtitle,
405
+ icon: typeof config.icon === "string" ? config.icon : void 0,
406
+ fields: sectionControls.map(controlToFormField),
407
+ columns: config.columns ?? options.columns ?? 1,
408
+ condition: config.condition,
409
+ access: config.access
410
+ };
411
+ }) };
412
+ }
413
+ /** Convert controls into an AppTopBar settingsConfig object that passes compact controls through to SettingsModal. */
414
+ function controlsToTopBarSettingsConfig(controls, options = {}, config = {}) {
415
+ return {
416
+ ...config,
417
+ spec: {
418
+ controls,
419
+ controlOptions: options
420
+ }
421
+ };
422
+ }
423
+ /** Return generated control view IDs that have at least one sidebar panel. */
424
+ function controlsToViewIds(controls, options = {}) {
425
+ return controlsToViewItems(controls, options).map((item) => item.id);
426
+ }
427
+ /** Return AppTopBar `spec.pills` view items for switching generated control sidebars. */
428
+ function controlsToViewItems(controls, options = {}) {
429
+ return Object.entries(controlsToSidebarPanels(controls, options)).filter(([, sections]) => sections.length > 0).map(([id]) => controlViewItem(id, options));
430
+ }
431
+ /** Return the first generated sidebar view ID, or an empty string when controls render no sidebar panels. */
432
+ function getDefaultControlView(controls, options = {}) {
433
+ return controlsToViewIds(controls, options)[0] ?? "";
434
+ }
435
+ /** Return a headerless single-section FormBuilder schema for rendering inside an AppSidebar section slot. */
436
+ function controlsToSectionFormSchema(controls, sectionId, options = {}) {
437
+ const schema = controlsToFormSchema(controls, options);
438
+ return {
439
+ sections: schema.sections.filter((section) => section.id === sectionId).map((section) => ({
440
+ ...section,
441
+ title: "",
442
+ description: void 0
443
+ })),
444
+ actions: schema.actions,
445
+ submitLabel: schema.submitLabel,
446
+ cancelLabel: schema.cancelLabel,
447
+ showCancel: schema.showCancel
448
+ };
449
+ }
450
+ /** Return headerless FormBuilder schemas keyed by section ID for AppSidebar auto-rendering. */
451
+ function controlsToSectionFormSchemas(controls, options = {}) {
452
+ const schema = controlsToFormSchema(controls, options);
453
+ const schemas = {};
454
+ for (const section of schema.sections) schemas[section.id] = {
455
+ sections: [{
456
+ ...section,
457
+ title: "",
458
+ description: void 0
459
+ }],
460
+ actions: schema.actions,
461
+ submitLabel: schema.submitLabel,
462
+ cancelLabel: schema.cancelLabel,
463
+ showCancel: schema.showCancel
464
+ };
465
+ return schemas;
466
+ }
467
+ var CONTROL_TARGETS = {
468
+ form: controlsToFormSchema,
469
+ sectionForm: controlsToSectionFormSchema,
470
+ sectionForms: controlsToSectionFormSchemas,
471
+ settings: controlsToSettingsSchema,
472
+ sidebarPanels: controlsToSidebarPanels,
473
+ topBarSettings: controlsToTopBarSettingsConfig,
474
+ viewIds: controlsToViewIds,
475
+ viewItems: controlsToViewItems
476
+ };
477
+ /**
478
+ * Build one target shape from a control schema: a FormBuilder schema (`form`,
479
+ * `sectionForm`, `sectionForms`), a settings modal schema (`settings`), sidebar
480
+ * panels (`sidebarPanels`), a top-bar settings config (`topBarSettings`) or the
481
+ * view list (`viewIds`, `viewItems`).
482
+ *
483
+ * @example
484
+ * ```ts
485
+ * const schema = controlsTo('form', controls)
486
+ * const section = controlsTo('sectionForm', controls, 'analysis')
487
+ * ```
488
+ */
489
+ function controlsTo(target, ...args) {
490
+ const build = CONTROL_TARGETS[target];
491
+ return build(...args);
492
+ }
493
+ //#endregion
494
+ //#region src/composables/controlComponentBindings.ts
495
+ /** Map control workspace values into component props for direct `v-bind` usage. */
496
+ function controlValuesToComponentProps(values, mapping) {
497
+ if (mapping === void 0) return { ...values };
498
+ if (Array.isArray(mapping)) {
499
+ const props = {};
500
+ for (const key of mapping) props[key] = values[key];
501
+ return props;
502
+ }
503
+ const props = {};
504
+ for (const [prop, source] of Object.entries(mapping)) props[prop] = typeof source === "function" ? source(values) : values[source];
505
+ return props;
506
+ }
507
+ /** Map control workspace values into named SDK component bindings for direct slot rendering. */
508
+ function controlValuesToComponentBindings(values, bindings) {
509
+ if (bindings === void 0) return [];
510
+ return normalizeControlComponentBindingConfigs(bindings).map((binding) => ({
511
+ id: binding.id,
512
+ component: binding.component,
513
+ props: controlValuesToComponentProps(values, binding.props)
514
+ }));
515
+ }
516
+ /** Map control workspace values into SDK component bindings keyed by binding id. */
517
+ function controlValuesToComponentBindingsById(values, bindings) {
518
+ return Object.fromEntries(controlValuesToComponentBindings(values, bindings).map((binding) => [binding.id, binding]));
519
+ }
520
+ function normalizeControlComponentBindingConfigs(bindings) {
521
+ if (Array.isArray(bindings)) {
522
+ const usedIds = /* @__PURE__ */ new Map();
523
+ return bindings.map((binding) => ({
524
+ id: uniqueComponentBindingId(binding.id ?? binding.component, usedIds),
525
+ component: binding.component,
526
+ props: binding.props
527
+ }));
528
+ }
529
+ return Object.entries(bindings).map(([id, binding]) => ({
530
+ id,
531
+ component: binding.component,
532
+ props: binding.props
533
+ }));
534
+ }
535
+ /** Map control values onto component props (`props`) and component bindings (`list`, `byId`). */
536
+ var controlBindings = {
537
+ props: controlValuesToComponentProps,
538
+ list: controlValuesToComponentBindings,
539
+ byId: controlValuesToComponentBindingsById
540
+ };
541
+ function uniqueComponentBindingId(id, usedIds) {
542
+ const count = usedIds.get(id) ?? 0;
543
+ usedIds.set(id, count + 1);
544
+ return count === 0 ? id : `${id}-${count + 1}`;
545
+ }
546
+ //#endregion
547
+ //#region src/composables/useControlSchema.ts
548
+ /** Preserve literal control keys while marking an object as a MINT control schema. */
549
+ function defineControls(controls) {
550
+ return controls;
551
+ }
552
+ /** Preserve literal SDK component binding ids while marking an object as generated workspace component bindings. */
553
+ function defineControlComponentBindings(bindings) {
554
+ return bindings;
555
+ }
556
+ /** Build default values for a control schema, matching FormBuilder field defaults. */
557
+ function getControlDefaults(controls) {
558
+ const values = {};
559
+ for (const control of normalizeControls(controls)) values[control.name] = defaultValueForControl(control.definition, control.type);
560
+ return values;
561
+ }
562
+ /** Prepare FormBuilder, SettingsModal, AppTopBar settings, AppSidebar, and initial values from one compact control model. */
563
+ function useControlSchema(controls, options = {}) {
564
+ const formSchema = controlsToFormSchema(controls, options);
565
+ const settingsSchema = controlsToSettingsSchema(controls, options);
566
+ const topBarSettingsConfig = controlsToTopBarSettingsConfig(controls, options);
567
+ const sidebarPanels = controlsToSidebarPanels(controls, options);
568
+ const viewItems = controlsToViewItems(controls, options);
569
+ const viewIds = viewItems.map((item) => item.id);
570
+ const defaultView = viewIds[0] ?? "";
571
+ const sectionSchemas = controlsToSectionFormSchemas(controls, options);
572
+ return {
573
+ controls,
574
+ fields: normalizeControls(controls, options).map(controlToFormField),
575
+ formSchema,
576
+ form: { spec: {
577
+ controls,
578
+ controlOptions: options
579
+ } },
580
+ settingsSchema,
581
+ settings: { spec: settingsSchema },
582
+ topBarSettingsConfig,
583
+ topBarSettings: { spec: { settings: topBarSettingsConfig } },
584
+ sidebarPanels,
585
+ viewIds,
586
+ viewItems,
587
+ defaultView,
588
+ sectionSchemas,
589
+ sidebar: {
590
+ spec: {
591
+ panels: sidebarPanels,
592
+ forms: sectionSchemas
593
+ },
594
+ activeView: defaultView
595
+ },
596
+ initialValues: getControlDefaults(controls),
597
+ sectionSchema: (sectionId) => controlsToSectionFormSchema(controls, sectionId, options)
598
+ };
599
+ }
600
+ //#endregion
601
+ //#region src/components/PluginWorkspaceView.controls.ts
602
+ function usePluginWorkspaceControls(options) {
603
+ const resolvedModel = computed(() => options.model());
604
+ const resolvedControls = computed(() => resolvedModel.value?.controls);
605
+ const resolvedControlOptions = computed(() => resolvedModel.value?.controlOptions ?? {});
606
+ const externalControlValues = computed(() => options.values());
607
+ const internalControlValues = reactive({});
608
+ let syncingControlValues = false;
609
+ const generatedControlDefaults = computed(() => {
610
+ if (!resolvedControls.value) return {};
611
+ return {
612
+ ...getControlDefaults(resolvedControls.value),
613
+ ...resolvedControlOptions.value.initialValues ?? {}
614
+ };
615
+ });
616
+ function replaceControlValues(values) {
617
+ for (const key of Object.keys(internalControlValues)) if (!(key in values)) delete internalControlValues[key];
618
+ Object.assign(internalControlValues, values);
619
+ }
620
+ function emitControlValues() {
621
+ options.emitValues({ ...internalControlValues });
622
+ }
623
+ function syncResolvedControlValues() {
624
+ syncingControlValues = true;
625
+ replaceControlValues({
626
+ ...generatedControlDefaults.value,
627
+ ...externalControlValues.value === void 0 ? internalControlValues : externalControlValues.value
628
+ });
629
+ syncingControlValues = false;
630
+ }
631
+ function handleControlValuesUpdate(values) {
632
+ syncingControlValues = true;
633
+ replaceControlValues({
634
+ ...generatedControlDefaults.value,
635
+ ...values
636
+ });
637
+ syncingControlValues = false;
638
+ emitControlValues();
639
+ }
640
+ const resolvedComponentBindings = computed(() => controlValuesToComponentBindings(internalControlValues, resolvedModel.value?.componentBindings));
641
+ const resolvedComponentBindingsById = computed(() => controlValuesToComponentBindingsById(internalControlValues, resolvedModel.value?.componentBindings));
642
+ const resolvedComponentProps = computed(() => {
643
+ const mapping = resolvedModel.value?.componentProps;
644
+ return mapping === void 0 ? {} : controlValuesToComponentProps(internalControlValues, mapping);
645
+ });
646
+ const resolvedComponentPropsById = computed(() => {
647
+ const mappings = resolvedModel.value?.componentPropsById;
648
+ if (mappings === void 0) return {};
649
+ return Object.fromEntries(Object.entries(mappings).map(([id, mapping]) => [id, controlValuesToComponentProps(internalControlValues, mapping)]));
650
+ });
651
+ const generatedPillNav = computed(() => {
652
+ if (!resolvedControls.value) return [];
653
+ return controlsToViewItems(resolvedControls.value, resolvedControlOptions.value);
654
+ });
655
+ const generatedDefaultView = computed(() => {
656
+ if (!resolvedControls.value) return "";
657
+ return getDefaultControlView(resolvedControls.value, resolvedControlOptions.value);
658
+ });
659
+ syncResolvedControlValues();
660
+ watch([generatedControlDefaults, externalControlValues], syncResolvedControlValues, { deep: true });
661
+ watch(internalControlValues, () => {
662
+ if (syncingControlValues) return;
663
+ emitControlValues();
664
+ }, {
665
+ deep: true,
666
+ flush: "sync"
667
+ });
668
+ return {
669
+ resolvedControls,
670
+ resolvedControlOptions,
671
+ generatedPillNav,
672
+ generatedDefaultView,
673
+ internalControlValues,
674
+ resolvedComponentBindings,
675
+ resolvedComponentBindingsById,
676
+ resolvedComponentProps,
677
+ resolvedComponentPropsById,
678
+ handleControlValuesUpdate
679
+ };
680
+ }
681
+ //#endregion
682
+ //#region src/components/PluginWorkspaceView.navigation.ts
683
+ function usePluginWorkspaceNavigation(options) {
684
+ const internalActiveView = ref();
685
+ const resolvedPillNav = computed(() => {
686
+ if (options.pillNav() !== void 0) return options.pillNav();
687
+ return options.generatedPillNav.value.length > 0 ? [...options.generatedPillNav.value] : void 0;
688
+ });
689
+ const firstConfiguredViewId = computed(() => firstItemId(options.pillNav()) ?? options.generatedDefaultView.value ?? options.panelIds()[0] ?? "");
690
+ const resolvedActiveView = computed({
691
+ get: () => options.activeView() ?? options.currentPillId() ?? internalActiveView.value ?? firstConfiguredViewId.value,
692
+ set: (value) => {
693
+ internalActiveView.value = value;
694
+ options.emitActiveView(value);
695
+ }
696
+ });
697
+ const resolvedCurrentPillId = computed(() => options.currentPillId() ?? resolvedActiveView.value);
698
+ function setActiveView(viewId) {
699
+ resolvedActiveView.value = viewId;
700
+ }
701
+ function handlePillSelect(item) {
702
+ setActiveView(item.id);
703
+ options.emitPillSelect(item);
704
+ }
705
+ return {
706
+ resolvedPillNav,
707
+ firstConfiguredViewId,
708
+ resolvedActiveView,
709
+ resolvedCurrentPillId,
710
+ setActiveView,
711
+ handlePillSelect
712
+ };
713
+ }
714
+ function firstItemId(items) {
715
+ const item = items?.[0];
716
+ if (item === void 0) return void 0;
717
+ return typeof item === "string" ? item : item.id;
718
+ }
719
+ //#endregion
720
+ //#region src/components/PluginWorkspaceView.shell.ts
721
+ var topBarForwardedSlots = /* @__PURE__ */ new Set([
722
+ "icon",
723
+ "logo",
724
+ "nav",
725
+ "center",
726
+ "actions",
727
+ "settings-appearance"
728
+ ]);
729
+ var sidebarForwardedSlots = /* @__PURE__ */ new Set([
730
+ "header",
731
+ "collapsed",
732
+ "collapsed-footer",
733
+ "footer"
734
+ ]);
735
+ function getPluginWorkspaceTopBarSlotNames(slots) {
736
+ return Object.keys(slots).filter((name) => topBarForwardedSlots.has(name) || name.startsWith("settings-tab-"));
737
+ }
738
+ function getPluginWorkspaceSidebarSlotNames(slots) {
739
+ return Object.keys(slots).filter((name) => sidebarForwardedSlots.has(name) || name.startsWith("section-"));
740
+ }
741
+ function hasPluginWorkspaceSidebarSurface(options) {
742
+ const { sidebar } = options;
743
+ if (sidebar === false) return false;
744
+ return Object.keys(sidebar.panels ?? {}).length > 0 || Object.keys(sidebar.forms ?? {}).length > 0 || sidebar.controls !== void 0 || Boolean(sidebar.whenEmpty) || sidebar.contentId !== void 0 || sidebar.title !== void 0 || sidebar.subtitle !== void 0 || sidebar.badge !== void 0 || options.hasSidebarSlot || options.sidebarSlotCount > 0;
745
+ }
746
+ //#endregion
747
+ //#region src/composables/usePluginWorkspace.ts
748
+ /**
749
+ * Maps PluginWorkspaceView's `spec` and `v-model`s into the three typed model objects
750
+ * (`shell`, `sidebar`, `controls`) rendered by its internal pieces
751
+ * (WorkspaceShellInternal, WorkspaceSidebarInternal, WorkspaceControlsInternal).
752
+ *
753
+ * @example Recommended
754
+ * ```ts
755
+ * const props = defineProps<PluginWorkspaceViewProps>()
756
+ * const emit = defineEmits<PluginWorkspaceViewEmits>()
757
+ * const slots = useSlots()
758
+ * const { shell, sidebar, controls } = usePluginWorkspace({ props, slots, emit })
759
+ * ```
760
+ */
761
+ function usePluginWorkspace(options) {
762
+ const { props, slots, emit } = options;
763
+ const sidebarSpec = computed(() => props.spec?.sidebar ?? {});
764
+ const topBarSpec = computed(() => props.spec?.topBar === false ? false : applySpecDefaults({
765
+ themeToggle: true,
766
+ settings: {},
767
+ standaloneLabel: false
768
+ }, props.spec?.topBar));
769
+ const controlsState = usePluginWorkspaceControls({
770
+ model: () => sidebarSpec.value === false ? void 0 : sidebarSpec.value.controls,
771
+ values: () => props.values,
772
+ emitValues: (values) => emit("update:values", values)
773
+ });
774
+ const navigationState = usePluginWorkspaceNavigation({
775
+ activeView: () => props.view,
776
+ currentPillId: () => props.pill,
777
+ pillNav: () => topBarSpec.value === false ? void 0 : topBarSpec.value.pills,
778
+ panelIds: () => Object.keys(sidebarSpec.value === false ? {} : sidebarSpec.value.panels ?? {}),
779
+ generatedPillNav: controlsState.generatedPillNav,
780
+ generatedDefaultView: controlsState.generatedDefaultView,
781
+ emitActiveView: (viewId) => emit("update:view", viewId),
782
+ emitPillSelect: (item) => {
783
+ emit("update:pill", item.id);
784
+ emit("pill-select", item);
785
+ }
786
+ });
787
+ const topBarSlotNames = computed(() => getPluginWorkspaceTopBarSlotNames(slots));
788
+ const sidebarSlotNames = computed(() => getPluginWorkspaceSidebarSlotNames(slots));
789
+ const hasSidebarSurface = computed(() => hasPluginWorkspaceSidebarSurface({
790
+ sidebar: sidebarSpec.value,
791
+ hasSidebarSlot: Boolean(slots.sidebar),
792
+ sidebarSlotCount: sidebarSlotNames.value.length
793
+ }));
794
+ const controls = computed(() => ({
795
+ activeView: navigationState.resolvedActiveView.value,
796
+ setActiveView: navigationState.setActiveView,
797
+ values: controlsState.internalControlValues,
798
+ componentBindings: controlsState.resolvedComponentBindings.value,
799
+ componentBindingsById: controlsState.resolvedComponentBindingsById.value,
800
+ componentProps: controlsState.resolvedComponentProps.value,
801
+ componentPropsById: controlsState.resolvedComponentPropsById.value
802
+ }));
803
+ return {
804
+ shell: computed(() => {
805
+ const sidebar = sidebarSpec.value === false ? {} : sidebarSpec.value;
806
+ return {
807
+ sidebarPosition: sidebar.position ?? "left",
808
+ sidebarWidth: sidebar.width,
809
+ floating: props.spec?.floating ?? true,
810
+ responsiveSidebar: sidebar.responsive ?? true,
811
+ sidebarToggleLabel: sidebar.toggleLabel ?? "Open workspace sidebar",
812
+ sidebarCloseLabel: sidebar.closeLabel ?? "Close workspace sidebar",
813
+ hasSidebarSurface: hasSidebarSurface.value,
814
+ title: props.spec?.title,
815
+ subtitle: props.spec?.subtitle,
816
+ topBar: topBarSpec.value === false ? false : {
817
+ ...topBarSpec.value,
818
+ pills: navigationState.resolvedPillNav.value
819
+ },
820
+ pill: navigationState.resolvedCurrentPillId.value,
821
+ topBarSlotNames: topBarSlotNames.value,
822
+ controls: controls.value
823
+ };
824
+ }),
825
+ sidebar: computed(() => {
826
+ const spec = sidebarSpec.value === false ? {} : sidebarSpec.value;
827
+ return {
828
+ spec: {
829
+ ...spec,
830
+ floating: false,
831
+ collapsible: spec.collapsible ?? true,
832
+ whenEmpty: (spec.whenEmpty ?? false) || spec.contentId !== void 0
833
+ },
834
+ activeView: navigationState.resolvedActiveView.value,
835
+ values: controlsState.internalControlValues,
836
+ collapsed: props.sidebarCollapsed,
837
+ formLoading: props.formLoading ?? false,
838
+ formDisabled: props.formDisabled ?? false,
839
+ formReadonly: props.formReadonly ?? false,
840
+ slotNames: sidebarSlotNames.value
841
+ };
842
+ }),
843
+ controls,
844
+ hasSidebarSurface,
845
+ handleControlValuesUpdate: controlsState.handleControlValuesUpdate,
846
+ handlePillSelect: navigationState.handlePillSelect
847
+ };
848
+ }
849
+ //#endregion
850
+ //#region src/components/AppLayout.vue?vue&type=script&setup=true&lang.ts
851
+ var _hoisted_1$9 = {
852
+ key: 0,
853
+ class: "mint-layout__topbar"
854
+ };
855
+ var _hoisted_2$7 = { class: "mint-layout__body" };
856
+ var _hoisted_3$7 = ["aria-label", "aria-expanded"];
857
+ var _hoisted_4$6 = {
858
+ key: 0,
859
+ class: "mint-layout__sidebar-toggle-icon",
860
+ viewBox: "0 0 24 24",
861
+ fill: "none",
862
+ stroke: "currentColor",
863
+ "stroke-width": "2",
864
+ "stroke-linecap": "round",
865
+ "stroke-linejoin": "round",
866
+ "aria-hidden": "true"
867
+ };
868
+ var _hoisted_5$6 = {
869
+ key: 1,
870
+ class: "mint-layout__sidebar-toggle-icon",
871
+ viewBox: "0 0 24 24",
872
+ fill: "none",
873
+ stroke: "currentColor",
874
+ "stroke-width": "2",
875
+ "stroke-linecap": "round",
876
+ "stroke-linejoin": "round",
877
+ "aria-hidden": "true"
878
+ };
879
+ var _hoisted_6$5 = { class: "mint-layout__main" };
880
+ //#endregion
881
+ //#region src/components/AppLayout.vue
882
+ var AppLayout_default = /* @__PURE__ */ defineComponent({
883
+ __name: "AppLayout",
884
+ props: {
885
+ sidebarPosition: { default: "left" },
886
+ sidebarWidth: { default: "auto" },
887
+ floating: {
888
+ type: Boolean,
889
+ default: false
890
+ },
891
+ responsiveSidebar: {
892
+ type: Boolean,
893
+ default: false
894
+ },
895
+ sidebarOpen: {
896
+ type: Boolean,
897
+ default: void 0
898
+ },
899
+ defaultSidebarOpen: {
900
+ type: Boolean,
901
+ default: false
902
+ },
903
+ sidebarToggleLabel: { default: "Open sidebar" },
904
+ sidebarCloseLabel: { default: "Close sidebar" }
905
+ },
906
+ emits: ["update:sidebarOpen"],
907
+ setup(__props, { emit: __emit }) {
908
+ /**
909
+ * AppLayout - Page layout shell with topbar, sidebar, and main content slots
910
+ *
911
+ * Provides a responsive application layout structure with optional topbar and sidebar.
912
+ * The sidebar slot is a simple pass-through on desktop. When responsiveSidebar is
913
+ * enabled, AppLayout owns the mobile toggle/backdrop shell around the sidebar.
914
+ *
915
+ * @example
916
+ * ```vue
917
+ * <AppLayout sidebar-position="right" floating>
918
+ * <template #topbar>
919
+ * <AppTopBar title="My App" />
920
+ * </template>
921
+ * <template #sidebar>
922
+ * <AppSidebar :spec="{ panels: toolPanels }" :active-view="activeTab">
923
+ * <template #section-params>...</template>
924
+ * </AppSidebar>
925
+ * </template>
926
+ * <main-content />
927
+ * </AppLayout>
928
+ * ```
929
+ */
930
+ const props = __props;
931
+ const emit = __emit;
932
+ const internalSidebarOpen = ref(props.defaultSidebarOpen);
933
+ const sidebarOpenModel = computed({
934
+ get: () => props.sidebarOpen ?? internalSidebarOpen.value,
935
+ set: (value) => {
936
+ internalSidebarOpen.value = value;
937
+ emit("update:sidebarOpen", value);
938
+ }
939
+ });
940
+ const layoutClasses = computed(() => [
941
+ "mint-layout",
942
+ props.sidebarPosition === "right" ? "mint-layout--sidebar-right" : "",
943
+ props.floating ? "mint-layout--floating" : "",
944
+ props.responsiveSidebar ? "mint-layout--responsive-sidebar" : "",
945
+ sidebarOpenModel.value ? "mint-layout--sidebar-open" : ""
946
+ ]);
947
+ const sidebarStyle = computed(() => {
948
+ return props.sidebarWidth !== "auto" ? { width: props.sidebarWidth } : void 0;
949
+ });
950
+ function toggleSidebar() {
951
+ sidebarOpenModel.value = !sidebarOpenModel.value;
952
+ }
953
+ function closeSidebar() {
954
+ sidebarOpenModel.value = false;
955
+ }
956
+ return (_ctx, _cache) => {
957
+ return openBlock(), createElementBlock("div", { class: normalizeClass(layoutClasses.value) }, [_ctx.$slots.topbar ? (openBlock(), createElementBlock("div", _hoisted_1$9, [renderSlot(_ctx.$slots, "topbar")])) : createCommentVNode("", true), createElementVNode("div", _hoisted_2$7, [
958
+ __props.responsiveSidebar && _ctx.$slots.sidebar ? (openBlock(), createElementBlock("button", {
959
+ key: 0,
960
+ type: "button",
961
+ class: "mint-layout__sidebar-toggle",
962
+ "aria-label": sidebarOpenModel.value ? __props.sidebarCloseLabel : __props.sidebarToggleLabel,
963
+ "aria-expanded": sidebarOpenModel.value,
964
+ onClick: toggleSidebar
965
+ }, [!sidebarOpenModel.value ? (openBlock(), createElementBlock("svg", _hoisted_4$6, [..._cache[0] || (_cache[0] = [createElementVNode("path", { d: "M4 6h16M4 12h16M4 18h16" }, null, -1)])])) : (openBlock(), createElementBlock("svg", _hoisted_5$6, [..._cache[1] || (_cache[1] = [createElementVNode("path", { d: "M6 18 18 6M6 6l12 12" }, null, -1)])]))], 8, _hoisted_3$7)) : createCommentVNode("", true),
966
+ __props.responsiveSidebar && _ctx.$slots.sidebar && sidebarOpenModel.value ? (openBlock(), createElementBlock("div", {
967
+ key: 1,
968
+ class: "mint-layout__sidebar-backdrop",
969
+ onClick: closeSidebar
970
+ })) : createCommentVNode("", true),
971
+ _ctx.$slots.sidebar ? (openBlock(), createElementBlock("div", {
972
+ key: 2,
973
+ class: "mint-layout__sidebar",
974
+ style: normalizeStyle(sidebarStyle.value)
975
+ }, [renderSlot(_ctx.$slots, "sidebar")], 4)) : createCommentVNode("", true),
976
+ createElementVNode("main", _hoisted_6$5, [renderSlot(_ctx.$slots, "default")])
977
+ ])], 2);
978
+ };
979
+ }
980
+ });
981
+ //#endregion
982
+ //#region src/utils/items.ts
983
+ function normalizeItemInput(item) {
984
+ if (typeof item === "object") return item;
985
+ return {
986
+ id: item,
987
+ label: item
988
+ };
989
+ }
990
+ function normalizeLabelItemInput(item) {
991
+ if (typeof item === "object") return item;
992
+ return { label: item };
993
+ }
994
+ //#endregion
995
+ //#region src/utils/pluginIcon.ts
996
+ var PLUGIN_ICON_FALLBACK_PATH = "M14 7v4a1 1 0 0 0 1 1h4M5 3h9l5 5v11a2 2 0 0 1-2 2H5a2 2 0 0 1-2-2V5a2 2 0 0 1 2-2z";
997
+ var PATH_REGEX = /^[Mm][\s,\d\-.]/;
998
+ var RASTER_DATA_URL_REGEX = /^data:image\/(png|jpeg|jpg|gif|webp);/;
999
+ var SAME_ORIGIN_ASSET_URL_REGEX = /^\/(?!\/)[^\s?#]+\.(?:svg|png|jpe?g|gif|webp)(?:[?#].*)?$/i;
1000
+ var VIEW_BOX_REGEX = /^-?\d+(?:\.\d+)?\s+-?\d+(?:\.\d+)?\s+\d+(?:\.\d+)?\s+\d+(?:\.\d+)?$/;
1001
+ var COLOR_REGEX = /^(#(?:[0-9a-f]{3}|[0-9a-f]{4}|[0-9a-f]{6}|[0-9a-f]{8})|currentColor|white|black|none)$/i;
1002
+ var MAX_STRUCTURED_ICON_LENGTH = 8e3;
1003
+ var MAX_PATHS = 8;
1004
+ var MAX_STOPS = 8;
1005
+ function normalizePluginIconSource(icon) {
1006
+ return (icon ?? "").replace(/^[\s]+/, "");
1007
+ }
1008
+ function detectPluginIcon(icon) {
1009
+ const raw = normalizePluginIconSource(icon);
1010
+ if (!raw) return {
1011
+ format: "fallback",
1012
+ value: PLUGIN_ICON_FALLBACK_PATH
1013
+ };
1014
+ const structured = parseStructuredPluginIcon(raw);
1015
+ if (structured) return {
1016
+ format: "structured",
1017
+ value: structured
1018
+ };
1019
+ if (PATH_REGEX.test(raw)) return {
1020
+ format: "path",
1021
+ value: raw
1022
+ };
1023
+ if (RASTER_DATA_URL_REGEX.test(raw)) return {
1024
+ format: "data-url",
1025
+ value: raw
1026
+ };
1027
+ if (raw.startsWith("https://") || SAME_ORIGIN_ASSET_URL_REGEX.test(raw)) return {
1028
+ format: "asset-url",
1029
+ value: raw
1030
+ };
1031
+ return {
1032
+ format: "fallback",
1033
+ value: PLUGIN_ICON_FALLBACK_PATH
1034
+ };
1035
+ }
1036
+ function isPluginIconFormat(icon) {
1037
+ const raw = normalizePluginIconSource(icon);
1038
+ return !!raw && detectPluginIcon(raw).format !== "fallback";
1039
+ }
1040
+ function parseStructuredPluginIcon(raw) {
1041
+ if (!raw.startsWith("{") || raw.length > MAX_STRUCTURED_ICON_LENGTH) return void 0;
1042
+ let parsed;
1043
+ try {
1044
+ parsed = JSON.parse(raw);
1045
+ } catch {
1046
+ return;
1047
+ }
1048
+ if (!isRecord(parsed) || parsed.type !== "mint-icon") return void 0;
1049
+ const viewBox = typeof parsed.viewBox === "string" && VIEW_BOX_REGEX.test(parsed.viewBox) ? parsed.viewBox : "0 0 24 24";
1050
+ const paths = parseStructuredPaths(parsed.paths);
1051
+ if (!paths.length) return void 0;
1052
+ const gradient = parseStructuredGradient(parsed.gradient);
1053
+ const background = parseStructuredBackground(parsed.background, gradient);
1054
+ return {
1055
+ type: "mint-icon",
1056
+ viewBox,
1057
+ ...background ? { background } : {},
1058
+ ...gradient ? { gradient } : {},
1059
+ paths
1060
+ };
1061
+ }
1062
+ function parseStructuredPaths(value) {
1063
+ if (!Array.isArray(value)) return [];
1064
+ return value.slice(0, MAX_PATHS).flatMap((item) => {
1065
+ if (!isRecord(item) || typeof item.d !== "string" || !item.d.trim()) return [];
1066
+ const path = { d: item.d.slice(0, 2e3) };
1067
+ if (isSafeColor(item.fill)) path.fill = item.fill;
1068
+ if (isSafeColor(item.stroke)) path.stroke = item.stroke;
1069
+ if (isFiniteNumber(item.strokeWidth, 0, 24)) path.strokeWidth = item.strokeWidth;
1070
+ if (isFiniteNumber(item.opacity, 0, 1)) path.opacity = item.opacity;
1071
+ return [path];
1072
+ });
1073
+ }
1074
+ function parseStructuredGradient(value) {
1075
+ if (!isRecord(value) || value.type !== "linear") return void 0;
1076
+ const stops = parseStructuredStops(value.stops);
1077
+ if (stops.length < 2 && isSafeColor(value.from) && isSafeColor(value.to)) stops.push({
1078
+ offset: "0%",
1079
+ color: value.from
1080
+ }, {
1081
+ offset: "100%",
1082
+ color: value.to
1083
+ });
1084
+ if (stops.length < 2) return void 0;
1085
+ return {
1086
+ type: "linear",
1087
+ angle: isFiniteNumber(value.angle, 0, 360) ? value.angle : 135,
1088
+ stops
1089
+ };
1090
+ }
1091
+ function parseStructuredStops(value) {
1092
+ if (!Array.isArray(value)) return [];
1093
+ return value.slice(0, MAX_STOPS).flatMap((item) => {
1094
+ if (!isRecord(item) || !isSafeColor(item.color)) return [];
1095
+ const offset = parseOffset(item.offset);
1096
+ if (!offset) return [];
1097
+ return [{
1098
+ offset,
1099
+ color: item.color,
1100
+ ...isFiniteNumber(item.opacity, 0, 1) ? { opacity: item.opacity } : {}
1101
+ }];
1102
+ });
1103
+ }
1104
+ function parseStructuredBackground(value, gradient) {
1105
+ if (!isRecord(value)) return void 0;
1106
+ const fill = value.fill === "gradient" && gradient ? "gradient" : isSafeColor(value.fill) ? value.fill : void 0;
1107
+ if (!fill) return void 0;
1108
+ return {
1109
+ fill,
1110
+ radius: isFiniteNumber(value.radius, 0, 12) ? value.radius : 5
1111
+ };
1112
+ }
1113
+ function parseOffset(value) {
1114
+ if (isFiniteNumber(value, 0, 1)) return String(value);
1115
+ if (typeof value !== "string") return void 0;
1116
+ if (/^(?:100|(?:[1-9]?\d)(?:\.\d+)?)%$/.test(value)) return value;
1117
+ }
1118
+ function isSafeColor(value) {
1119
+ return typeof value === "string" && COLOR_REGEX.test(value);
1120
+ }
1121
+ function isFiniteNumber(value, min, max) {
1122
+ return typeof value === "number" && Number.isFinite(value) && value >= min && value <= max;
1123
+ }
1124
+ //#endregion
1125
+ //#region src/components/internal/ActionItemInternal.vue?vue&type=script&setup=true&lang.ts
1126
+ var _hoisted_1$8 = [
1127
+ "href",
1128
+ "aria-disabled",
1129
+ "tabindex"
1130
+ ];
1131
+ var _hoisted_2$6 = [
1132
+ "href",
1133
+ "aria-disabled",
1134
+ "tabindex",
1135
+ "onClick"
1136
+ ];
1137
+ var _hoisted_3$6 = ["type", "disabled"];
1138
+ //#endregion
1139
+ //#region src/components/internal/ActionItemInternal.vue
1140
+ var ActionItemInternal_default = /* @__PURE__ */ defineComponent({
1141
+ inheritAttrs: false,
1142
+ __name: "ActionItemInternal",
1143
+ props: {
1144
+ href: {},
1145
+ to: {},
1146
+ disabled: {
1147
+ type: Boolean,
1148
+ default: false
1149
+ },
1150
+ type: { default: "button" }
1151
+ },
1152
+ emits: ["click"],
1153
+ setup(__props, { emit: __emit }) {
1154
+ /** Private routable action primitive for SDK nav and menu components. */
1155
+ const props = __props;
1156
+ const emit = __emit;
1157
+ function blockDisabledEvent(event) {
1158
+ event.preventDefault();
1159
+ event.stopImmediatePropagation();
1160
+ }
1161
+ function handleClick(event) {
1162
+ if (props.disabled) {
1163
+ blockDisabledEvent(event);
1164
+ return;
1165
+ }
1166
+ emit("click", event);
1167
+ }
1168
+ function handleRouterClick(event, navigate) {
1169
+ if (props.disabled) {
1170
+ blockDisabledEvent(event);
1171
+ return;
1172
+ }
1173
+ emit("click", event);
1174
+ navigate(event);
1175
+ }
1176
+ return (_ctx, _cache) => {
1177
+ const _component_router_link = resolveComponent("router-link");
1178
+ return __props.href ? (openBlock(), createElementBlock("a", mergeProps({ key: 0 }, _ctx.$attrs, {
1179
+ href: __props.disabled ? void 0 : __props.href,
1180
+ "aria-disabled": __props.disabled || void 0,
1181
+ tabindex: __props.disabled ? -1 : void 0,
1182
+ onClick: handleClick
1183
+ }), [renderSlot(_ctx.$slots, "default")], 16, _hoisted_1$8)) : __props.to ? (openBlock(), createBlock(_component_router_link, {
1184
+ key: 1,
1185
+ to: __props.to,
1186
+ custom: ""
1187
+ }, {
1188
+ default: withCtx(({ href: routerHref, navigate }) => [createElementVNode("a", mergeProps(_ctx.$attrs, {
1189
+ href: __props.disabled ? void 0 : routerHref,
1190
+ "aria-disabled": __props.disabled || void 0,
1191
+ tabindex: __props.disabled ? -1 : void 0,
1192
+ onClick: ($event) => handleRouterClick($event, navigate)
1193
+ }), [renderSlot(_ctx.$slots, "default")], 16, _hoisted_2$6)]),
1194
+ _: 3
1195
+ }, 8, ["to"])) : (openBlock(), createElementBlock("button", mergeProps({ key: 2 }, _ctx.$attrs, {
1196
+ type: __props.type,
1197
+ disabled: __props.disabled,
1198
+ onClick: handleClick
1199
+ }), [renderSlot(_ctx.$slots, "default")], 16, _hoisted_3$6));
1200
+ };
1201
+ }
1202
+ });
1203
+ //#endregion
1204
+ //#region src/components/PluginIcon.vue?vue&type=script&setup=true&lang.ts
1205
+ var _hoisted_1$7 = ["viewBox"];
1206
+ var _hoisted_2$5 = { key: 0 };
1207
+ var _hoisted_3$5 = [
1208
+ "id",
1209
+ "x1",
1210
+ "y1",
1211
+ "x2",
1212
+ "y2"
1213
+ ];
1214
+ var _hoisted_4$5 = [
1215
+ "offset",
1216
+ "stop-color",
1217
+ "stop-opacity"
1218
+ ];
1219
+ var _hoisted_5$5 = [
1220
+ "x",
1221
+ "y",
1222
+ "width",
1223
+ "height",
1224
+ "rx",
1225
+ "fill"
1226
+ ];
1227
+ var _hoisted_6$4 = [
1228
+ "d",
1229
+ "fill",
1230
+ "stroke",
1231
+ "stroke-width",
1232
+ "opacity"
1233
+ ];
1234
+ var _hoisted_7$4 = {
1235
+ key: 1,
1236
+ class: "mint-plugin-icon__svg",
1237
+ viewBox: "0 0 24 24",
1238
+ fill: "none",
1239
+ stroke: "currentColor",
1240
+ "stroke-width": "2",
1241
+ "stroke-linecap": "round",
1242
+ "stroke-linejoin": "round",
1243
+ "aria-hidden": "true"
1244
+ };
1245
+ var _hoisted_8$3 = ["d"];
1246
+ var _hoisted_9$3 = ["src"];
1247
+ //#endregion
1248
+ //#region src/components/PluginIcon.vue
1249
+ var PluginIcon_default = /* @__PURE__ */ defineComponent({
1250
+ name: "PluginIcon",
1251
+ __name: "PluginIcon",
1252
+ props: {
1253
+ icon: {},
1254
+ size: { default: "md" },
1255
+ variant: { default: "solid" },
1256
+ tone: {},
1257
+ color: {}
1258
+ },
1259
+ setup(__props) {
1260
+ /** Renders a plugin's icon as a sized chip. Auto-detects format:
1261
+ * - Structured MINT icon JSON ({"type":"mint-icon",...}) → controlled multi-color SVG
1262
+ * - SVG path data (e.g. "M13 10V3...") → inline <svg><path>
1263
+ * - Raster data URL (data:image/png|jpeg|jpg|gif|webp;...) → <img>
1264
+ * - https:// URL or root-relative static image/SVG asset → <img> with no-referrer + lazy loading
1265
+ * - Anything else → MINT canonical plugin placeholder path
1266
+ *
1267
+ * http://, protocol-relative, and data:image/svg+xml URLs are deliberately rejected
1268
+ * (mixed-content + XSS, see spec 2026-05-04-plugin-icon-component-design.md). */
1269
+ const props = __props;
1270
+ const detected = computed(() => detectPluginIcon(props.icon));
1271
+ const structuredIcon = computed(() => detected.value.format === "structured" ? detected.value.value : void 0);
1272
+ const iconValue = computed(() => typeof detected.value.value === "string" ? detected.value.value : "");
1273
+ const gradientId = computed(() => {
1274
+ const source = props.icon ?? "";
1275
+ let hash = 0;
1276
+ for (let index = 0; index < source.length; index += 1) hash = (hash << 5) - hash + source.charCodeAt(index) | 0;
1277
+ return `mint-plugin-icon-gradient-${Math.abs(hash)}`;
1278
+ });
1279
+ const gradientCoords = computed(() => {
1280
+ const radians = ((structuredIcon.value?.gradient?.angle ?? 135) - 90) * Math.PI / 180;
1281
+ const x = Math.cos(radians) * 50;
1282
+ const y = Math.sin(radians) * 50;
1283
+ return {
1284
+ x1: `${50 - x}%`,
1285
+ y1: `${50 - y}%`,
1286
+ x2: `${50 + x}%`,
1287
+ y2: `${50 + y}%`
1288
+ };
1289
+ });
1290
+ const structuredViewBox = computed(() => {
1291
+ const parts = structuredIcon.value?.viewBox.split(/\s+/).map(Number) ?? [
1292
+ 0,
1293
+ 0,
1294
+ 24,
1295
+ 24
1296
+ ];
1297
+ return {
1298
+ x: parts[0],
1299
+ y: parts[1],
1300
+ width: parts[2],
1301
+ height: parts[3]
1302
+ };
1303
+ });
1304
+ const backgroundFill = computed(() => structuredIcon.value?.background?.fill === "gradient" ? `url(#${gradientId.value})` : structuredIcon.value?.background?.fill);
1305
+ const rootClasses = computed(() => [
1306
+ "mint-plugin-icon",
1307
+ `mint-plugin-icon--${props.size}`,
1308
+ `mint-plugin-icon--${props.variant}`,
1309
+ props.tone ? `mint-plugin-icon--${props.tone}` : ""
1310
+ ]);
1311
+ const rootStyle = computed(() => props.color ? { "--mint-plugin-icon-tone": props.color } : void 0);
1312
+ return (_ctx, _cache) => {
1313
+ return openBlock(), createElementBlock("span", {
1314
+ class: normalizeClass(rootClasses.value),
1315
+ style: normalizeStyle(rootStyle.value)
1316
+ }, [structuredIcon.value ? (openBlock(), createElementBlock("svg", {
1317
+ key: 0,
1318
+ class: "mint-plugin-icon__svg mint-plugin-icon__svg--structured",
1319
+ viewBox: structuredIcon.value.viewBox,
1320
+ "aria-hidden": "true"
1321
+ }, [
1322
+ structuredIcon.value.gradient ? (openBlock(), createElementBlock("defs", _hoisted_2$5, [createElementVNode("linearGradient", {
1323
+ id: gradientId.value,
1324
+ x1: gradientCoords.value.x1,
1325
+ y1: gradientCoords.value.y1,
1326
+ x2: gradientCoords.value.x2,
1327
+ y2: gradientCoords.value.y2
1328
+ }, [(openBlock(true), createElementBlock(Fragment, null, renderList(structuredIcon.value.gradient.stops, (stop) => {
1329
+ return openBlock(), createElementBlock("stop", {
1330
+ key: `${stop.offset}-${stop.color}`,
1331
+ offset: stop.offset,
1332
+ "stop-color": stop.color,
1333
+ "stop-opacity": stop.opacity
1334
+ }, null, 8, _hoisted_4$5);
1335
+ }), 128))], 8, _hoisted_3$5)])) : createCommentVNode("", true),
1336
+ structuredIcon.value.background ? (openBlock(), createElementBlock("rect", {
1337
+ key: 1,
1338
+ x: structuredViewBox.value.x,
1339
+ y: structuredViewBox.value.y,
1340
+ width: structuredViewBox.value.width,
1341
+ height: structuredViewBox.value.height,
1342
+ rx: structuredIcon.value.background.radius,
1343
+ fill: backgroundFill.value
1344
+ }, null, 8, _hoisted_5$5)) : createCommentVNode("", true),
1345
+ (openBlock(true), createElementBlock(Fragment, null, renderList(structuredIcon.value.paths, (path, index) => {
1346
+ return openBlock(), createElementBlock("path", {
1347
+ key: index,
1348
+ d: path.d,
1349
+ fill: path.fill ?? "none",
1350
+ stroke: path.stroke,
1351
+ "stroke-width": path.strokeWidth,
1352
+ opacity: path.opacity,
1353
+ "stroke-linecap": "round",
1354
+ "stroke-linejoin": "round"
1355
+ }, null, 8, _hoisted_6$4);
1356
+ }), 128))
1357
+ ], 8, _hoisted_1$7)) : detected.value.format === "path" || detected.value.format === "fallback" ? (openBlock(), createElementBlock("svg", _hoisted_7$4, [createElementVNode("path", { d: iconValue.value }, null, 8, _hoisted_8$3)])) : (openBlock(), createElementBlock("img", {
1358
+ key: 2,
1359
+ class: "mint-plugin-icon__img",
1360
+ src: iconValue.value,
1361
+ alt: "",
1362
+ referrerpolicy: "no-referrer",
1363
+ loading: "lazy"
1364
+ }, null, 8, _hoisted_9$3))], 6);
1365
+ };
1366
+ }
1367
+ });
1368
+ //#endregion
1369
+ //#region src/components/internal/AppTopBarPageSelectorInternal.vue?vue&type=script&setup=true&lang.ts
1370
+ var _hoisted_1$6 = ["aria-expanded"];
1371
+ var _hoisted_2$4 = {
1372
+ key: 1,
1373
+ class: "mint-page-selector__icon-fallback"
1374
+ };
1375
+ var _hoisted_3$4 = { class: "mint-page-selector__label" };
1376
+ var _hoisted_4$4 = {
1377
+ class: "mint-page-selector__chevron-wrap",
1378
+ "aria-hidden": "true"
1379
+ };
1380
+ var _hoisted_5$4 = {
1381
+ key: 0,
1382
+ class: "mint-page-selector__menu",
1383
+ role: "menu"
1384
+ };
1385
+ var _hoisted_6$3 = {
1386
+ key: 1,
1387
+ class: "mint-page-selector__icon-fallback"
1388
+ };
1389
+ var _hoisted_7$3 = { class: "mint-page-selector__item-label" };
1390
+ //#endregion
1391
+ //#region src/components/internal/AppTopBarPageSelectorInternal.vue
1392
+ var AppTopBarPageSelectorInternal_default = /* @__PURE__ */ defineComponent({
1393
+ __name: "AppTopBarPageSelectorInternal",
1394
+ props: {
1395
+ pages: {},
1396
+ currentPageId: {},
1397
+ placeholder: { default: "Go to…" },
1398
+ minWidth: { default: "11.25rem" }
1399
+ },
1400
+ emits: ["select"],
1401
+ setup(__props, { emit: __emit }) {
1402
+ /** Dropdown trigger that switches between named pages, closing on outside click or Escape. */
1403
+ const props = __props;
1404
+ const emit = __emit;
1405
+ const { isOpen, close, toggle } = useDropdownState({
1406
+ rootRef: useTemplateRef("root"),
1407
+ triggerRef: useTemplateRef("trigger")
1408
+ });
1409
+ const normalizedPages = computed(() => props.pages.map(normalizeItemInput));
1410
+ const current = computed(() => normalizedPages.value.find((p) => p.id === props.currentPageId) ?? normalizedPages.value[0]);
1411
+ function handleSelect(page) {
1412
+ if (page.disabled) return;
1413
+ if (page.href || page.to) {
1414
+ close();
1415
+ return;
1416
+ }
1417
+ emit("select", page);
1418
+ close();
1419
+ }
1420
+ return (_ctx, _cache) => {
1421
+ return openBlock(), createElementBlock("div", {
1422
+ ref: "root",
1423
+ class: "mint-page-selector",
1424
+ style: normalizeStyle({ minWidth: __props.minWidth })
1425
+ }, [createElementVNode("button", {
1426
+ ref: "trigger",
1427
+ type: "button",
1428
+ class: normalizeClass(["mint-page-selector__trigger", { "mint-page-selector__trigger--open": unref(isOpen) }]),
1429
+ "aria-expanded": unref(isOpen),
1430
+ "aria-haspopup": "menu",
1431
+ onClick: _cache[0] || (_cache[0] = withModifiers((...args) => unref(toggle) && unref(toggle)(...args), ["stop"]))
1432
+ }, [
1433
+ current.value ? (openBlock(), createElementBlock("span", {
1434
+ key: 0,
1435
+ class: normalizeClass(["mint-page-selector__icon", { "mint-page-selector__icon--metadata": unref(isPluginIconFormat)(current.value.icon) }])
1436
+ }, [renderSlot(_ctx.$slots, "icon", { page: current.value }, () => [unref(isPluginIconFormat)(current.value.icon) ? (openBlock(), createBlock(PluginIcon_default, {
1437
+ key: 0,
1438
+ class: "mint-page-selector__trigger-metadata-icon",
1439
+ icon: current.value.icon,
1440
+ size: "sm",
1441
+ variant: "solid"
1442
+ }, null, 8, ["icon"])) : (openBlock(), createElementBlock("span", _hoisted_2$4, toDisplayString(current.value.label.charAt(0)), 1))])], 2)) : createCommentVNode("", true),
1443
+ createElementVNode("span", _hoisted_3$4, toDisplayString(current.value?.label ?? __props.placeholder), 1),
1444
+ createElementVNode("span", _hoisted_4$4, [(openBlock(), createElementBlock("svg", {
1445
+ class: normalizeClass(["mint-page-selector__chevron", { "mint-page-selector__chevron--open": unref(isOpen) }]),
1446
+ viewBox: "0 0 24 24",
1447
+ fill: "none",
1448
+ stroke: "currentColor",
1449
+ "stroke-width": "2",
1450
+ "stroke-linecap": "round",
1451
+ "stroke-linejoin": "round"
1452
+ }, [..._cache[1] || (_cache[1] = [createElementVNode("path", { d: "m6 9 6 6 6-6" }, null, -1)])], 2))])
1453
+ ], 10, _hoisted_1$6), unref(isOpen) ? (openBlock(), createElementBlock("div", _hoisted_5$4, [_cache[2] || (_cache[2] = createElementVNode("div", { class: "mint-page-selector__menu-title" }, "Go to", -1)), (openBlock(true), createElementBlock(Fragment, null, renderList(normalizedPages.value, (page) => {
1454
+ return openBlock(), createBlock(ActionItemInternal_default, {
1455
+ key: page.id,
1456
+ href: page.href,
1457
+ to: page.to,
1458
+ disabled: page.disabled,
1459
+ class: normalizeClass([
1460
+ "mint-page-selector__item",
1461
+ { "mint-page-selector__item--active": page.id === current.value?.id },
1462
+ { "mint-page-selector__item--disabled": page.disabled }
1463
+ ]),
1464
+ role: "menuitem",
1465
+ onClick: ($event) => handleSelect(page)
1466
+ }, {
1467
+ default: withCtx(() => [createElementVNode("span", { class: normalizeClass(["mint-page-selector__item-icon", { "mint-page-selector__item-icon--metadata": unref(isPluginIconFormat)(page.icon) }]) }, [renderSlot(_ctx.$slots, "item-icon", { page }, () => [unref(isPluginIconFormat)(page.icon) ? (openBlock(), createBlock(PluginIcon_default, {
1468
+ key: 0,
1469
+ class: "mint-page-selector__metadata-icon",
1470
+ icon: page.icon,
1471
+ size: "sm",
1472
+ variant: "solid"
1473
+ }, null, 8, ["icon"])) : (openBlock(), createElementBlock("span", _hoisted_6$3, toDisplayString(page.label.charAt(0)), 1))])], 2), createElementVNode("span", _hoisted_7$3, toDisplayString(page.label), 1)]),
1474
+ _: 2
1475
+ }, 1032, [
1476
+ "href",
1477
+ "to",
1478
+ "disabled",
1479
+ "class",
1480
+ "onClick"
1481
+ ]);
1482
+ }), 128))])) : createCommentVNode("", true)], 4);
1483
+ };
1484
+ }
1485
+ });
1486
+ //#endregion
1487
+ //#region src/components/internal/AppTopBarPillNavInternal.vue?vue&type=script&setup=true&lang.ts
1488
+ var _hoisted_1$5 = {
1489
+ class: "mint-pill-nav",
1490
+ "aria-label": "Primary"
1491
+ };
1492
+ var _hoisted_2$3 = [
1493
+ "disabled",
1494
+ "aria-expanded",
1495
+ "onClick"
1496
+ ];
1497
+ var _hoisted_3$3 = {
1498
+ key: 0,
1499
+ class: "mint-pill-nav__icon",
1500
+ viewBox: "0 0 24 24",
1501
+ fill: "none",
1502
+ stroke: "currentColor",
1503
+ "stroke-width": "2",
1504
+ "stroke-linecap": "round",
1505
+ "stroke-linejoin": "round",
1506
+ "aria-hidden": "true"
1507
+ };
1508
+ var _hoisted_4$3 = ["d"];
1509
+ var _hoisted_5$3 = ["d"];
1510
+ var _hoisted_6$2 = {
1511
+ key: 1,
1512
+ class: "mint-pill-nav__dot",
1513
+ role: "img",
1514
+ "aria-label": "Needs attention"
1515
+ };
1516
+ var _hoisted_7$2 = {
1517
+ key: 0,
1518
+ class: "mint-pill-nav__icon",
1519
+ viewBox: "0 0 24 24",
1520
+ fill: "none",
1521
+ stroke: "currentColor",
1522
+ "stroke-width": "2",
1523
+ "stroke-linecap": "round",
1524
+ "stroke-linejoin": "round",
1525
+ "aria-hidden": "true"
1526
+ };
1527
+ var _hoisted_8$2 = ["d"];
1528
+ var _hoisted_9$2 = ["d"];
1529
+ var _hoisted_10$2 = {
1530
+ key: 1,
1531
+ class: "mint-pill-nav__dot",
1532
+ role: "img",
1533
+ "aria-label": "Needs attention"
1534
+ };
1535
+ var _hoisted_11$2 = {
1536
+ key: 2,
1537
+ class: "mint-popover mint-pill-nav__dropdown",
1538
+ role: "menu"
1539
+ };
1540
+ var _hoisted_12$2 = { class: "mint-pill-nav__dropdown-label" };
1541
+ var _hoisted_13$2 = {
1542
+ key: 0,
1543
+ class: "mint-pill-nav__dropdown-description"
1544
+ };
1545
+ var MAX_VISIBLE_ITEMS = 4;
1546
+ var MORE_ITEM_ID = "__mint-pill-nav-more";
1547
+ //#endregion
1548
+ //#region src/components/internal/AppTopBarPillNavInternal.vue
1549
+ var AppTopBarPillNavInternal_default = /* @__PURE__ */ defineComponent({
1550
+ __name: "AppTopBarPillNavInternal",
1551
+ props: {
1552
+ items: {},
1553
+ currentItemId: {}
1554
+ },
1555
+ emits: ["select", "option-select"],
1556
+ setup(__props, { emit: __emit }) {
1557
+ /** Horizontal pill-style navigation bar that emits select events and supports href, router-link, button, or dropdown items. */
1558
+ const props = __props;
1559
+ const emit = __emit;
1560
+ const openItemId = ref(null);
1561
+ const itemRefs = ref(/* @__PURE__ */ new Map());
1562
+ /** The bar shows this many items; the rest fold into a More dropdown. */
1563
+ const allItems = computed(() => props.items.map(normalizePillNavItem));
1564
+ const normalizedItems = computed(() => {
1565
+ if (allItems.value.length <= MAX_VISIBLE_ITEMS) return allItems.value;
1566
+ const folded = allItems.value.slice(MAX_VISIBLE_ITEMS);
1567
+ return [...allItems.value.slice(0, MAX_VISIBLE_ITEMS), {
1568
+ id: MORE_ITEM_ID,
1569
+ label: "More",
1570
+ dot: folded.some((item) => item.dot),
1571
+ children: folded.flatMap((item) => item.children?.length ? item.children : [item])
1572
+ }];
1573
+ });
1574
+ function handleClick(item) {
1575
+ if (item.disabled) return;
1576
+ if (item.children?.length) {
1577
+ toggleDropdown(item.id);
1578
+ return;
1579
+ }
1580
+ if (item.href || item.to) return;
1581
+ emit("select", item);
1582
+ }
1583
+ function handleOptionClick(option, item) {
1584
+ if (option.disabled) return;
1585
+ openItemId.value = null;
1586
+ if (option.href || option.to) return;
1587
+ if (item.id !== MORE_ITEM_ID) {
1588
+ emit("option-select", option, item);
1589
+ return;
1590
+ }
1591
+ const folded = allItems.value.find((candidate) => candidate.id === option.id && !candidate.children?.length);
1592
+ if (folded) {
1593
+ emit("select", folded);
1594
+ return;
1595
+ }
1596
+ const group = allItems.value.find((candidate) => candidate.children?.some((child) => child.id === option.id));
1597
+ if (group) emit("option-select", option, group);
1598
+ }
1599
+ function normalizePillNavItem(item) {
1600
+ const normalized = normalizeItemInput(item);
1601
+ return {
1602
+ ...normalized,
1603
+ children: normalized.children?.map(normalizeItemInput)
1604
+ };
1605
+ }
1606
+ function toggleDropdown(itemId) {
1607
+ openItemId.value = openItemId.value === itemId ? null : itemId;
1608
+ }
1609
+ function setItemRef(el, itemId) {
1610
+ if (el) itemRefs.value.set(itemId, el);
1611
+ else itemRefs.value.delete(itemId);
1612
+ }
1613
+ function handleClickOutside(event) {
1614
+ const target = event.target;
1615
+ if (!Array.from(itemRefs.value.values()).some((el) => el.contains(target))) openItemId.value = null;
1616
+ }
1617
+ const activeChild = (item) => item.children?.find((child) => child.id === props.currentItemId);
1618
+ function isSvgIcon(icon) {
1619
+ if (!icon) return false;
1620
+ return Array.isArray(icon) || icon.startsWith("M") || icon.startsWith("m");
1621
+ }
1622
+ useEventListener(() => document, "click", handleClickOutside);
1623
+ return (_ctx, _cache) => {
1624
+ return openBlock(), createElementBlock("nav", _hoisted_1$5, [(openBlock(true), createElementBlock(Fragment, null, renderList(normalizedItems.value, (item) => {
1625
+ return openBlock(), createElementBlock("div", {
1626
+ key: item.id,
1627
+ ref_for: true,
1628
+ ref: (el) => setItemRef(el, item.id),
1629
+ class: "mint-pill-nav__item-wrap"
1630
+ }, [item.children?.length ? (openBlock(), createElementBlock("button", {
1631
+ key: 0,
1632
+ type: "button",
1633
+ class: normalizeClass([
1634
+ "mint-pill-nav__item",
1635
+ { "mint-pill-nav__item--active": item.id === __props.currentItemId || activeChild(item) !== void 0 },
1636
+ { "mint-pill-nav__item--disabled": item.disabled }
1637
+ ]),
1638
+ disabled: item.disabled,
1639
+ "aria-expanded": openItemId.value === item.id,
1640
+ "aria-haspopup": "menu",
1641
+ onClick: withModifiers(($event) => handleClick(item), ["stop"])
1642
+ }, [
1643
+ isSvgIcon(item.icon) ? (openBlock(), createElementBlock("svg", _hoisted_3$3, [Array.isArray(item.icon) ? (openBlock(true), createElementBlock(Fragment, { key: 0 }, renderList(item.icon, (d, index) => {
1644
+ return openBlock(), createElementBlock("path", {
1645
+ key: index,
1646
+ d
1647
+ }, null, 8, _hoisted_4$3);
1648
+ }), 128)) : (openBlock(), createElementBlock("path", {
1649
+ key: 1,
1650
+ d: item.icon
1651
+ }, null, 8, _hoisted_5$3))])) : createCommentVNode("", true),
1652
+ createTextVNode(" " + toDisplayString(activeChild(item)?.label ?? item.label) + " ", 1),
1653
+ item.dot ? (openBlock(), createElementBlock("span", _hoisted_6$2)) : createCommentVNode("", true),
1654
+ (openBlock(), createElementBlock("svg", {
1655
+ class: normalizeClass(["mint-pill-nav__chevron", { "mint-pill-nav__chevron--open": openItemId.value === item.id }]),
1656
+ viewBox: "0 0 24 24",
1657
+ fill: "none",
1658
+ stroke: "currentColor",
1659
+ "stroke-width": "2",
1660
+ "stroke-linecap": "round",
1661
+ "stroke-linejoin": "round",
1662
+ "aria-hidden": "true"
1663
+ }, [..._cache[0] || (_cache[0] = [createElementVNode("path", { d: "m6 9 6 6 6-6" }, null, -1)])], 2))
1664
+ ], 10, _hoisted_2$3)) : (openBlock(), createBlock(ActionItemInternal_default, {
1665
+ key: 1,
1666
+ href: item.href,
1667
+ to: item.to,
1668
+ disabled: item.disabled,
1669
+ class: normalizeClass([
1670
+ "mint-pill-nav__item",
1671
+ { "mint-pill-nav__item--active": item.id === __props.currentItemId },
1672
+ { "mint-pill-nav__item--disabled": item.disabled }
1673
+ ]),
1674
+ onClick: ($event) => handleClick(item)
1675
+ }, {
1676
+ default: withCtx(() => [
1677
+ isSvgIcon(item.icon) ? (openBlock(), createElementBlock("svg", _hoisted_7$2, [Array.isArray(item.icon) ? (openBlock(true), createElementBlock(Fragment, { key: 0 }, renderList(item.icon, (d, index) => {
1678
+ return openBlock(), createElementBlock("path", {
1679
+ key: index,
1680
+ d
1681
+ }, null, 8, _hoisted_8$2);
1682
+ }), 128)) : (openBlock(), createElementBlock("path", {
1683
+ key: 1,
1684
+ d: item.icon
1685
+ }, null, 8, _hoisted_9$2))])) : createCommentVNode("", true),
1686
+ createTextVNode(" " + toDisplayString(item.label) + " ", 1),
1687
+ item.dot ? (openBlock(), createElementBlock("span", _hoisted_10$2)) : createCommentVNode("", true)
1688
+ ]),
1689
+ _: 2
1690
+ }, 1032, [
1691
+ "href",
1692
+ "to",
1693
+ "disabled",
1694
+ "class",
1695
+ "onClick"
1696
+ ])), item.children?.length && openItemId.value === item.id ? (openBlock(), createElementBlock("div", _hoisted_11$2, [(openBlock(true), createElementBlock(Fragment, null, renderList(item.children, (option) => {
1697
+ return openBlock(), createBlock(ActionItemInternal_default, {
1698
+ key: option.id,
1699
+ href: option.href,
1700
+ to: option.to,
1701
+ disabled: option.disabled,
1702
+ class: normalizeClass([
1703
+ "mint-menu-item mint-pill-nav__dropdown-item",
1704
+ { "mint-menu-item--selected mint-pill-nav__dropdown-item--active": option.id === __props.currentItemId },
1705
+ { "mint-pill-nav__dropdown-item--disabled": option.disabled }
1706
+ ]),
1707
+ role: "menuitem",
1708
+ onClick: ($event) => handleOptionClick(option, item)
1709
+ }, {
1710
+ default: withCtx(() => [
1711
+ createElementVNode("span", _hoisted_12$2, toDisplayString(option.label), 1),
1712
+ option.description ? (openBlock(), createElementBlock("span", _hoisted_13$2, toDisplayString(option.description), 1)) : createCommentVNode("", true),
1713
+ _cache[1] || (_cache[1] = createElementVNode("svg", {
1714
+ class: "mint-menu-item__check",
1715
+ viewBox: "0 0 16 16",
1716
+ fill: "none",
1717
+ stroke: "currentColor",
1718
+ "stroke-width": "2",
1719
+ "stroke-linecap": "round",
1720
+ "stroke-linejoin": "round",
1721
+ "aria-hidden": "true"
1722
+ }, [createElementVNode("path", { d: "M3.5 8.5l3 3 6-7" })], -1))
1723
+ ]),
1724
+ _: 2
1725
+ }, 1032, [
1726
+ "href",
1727
+ "to",
1728
+ "disabled",
1729
+ "class",
1730
+ "onClick"
1731
+ ]);
1732
+ }), 128))])) : createCommentVNode("", true)]);
1733
+ }), 128))]);
1734
+ };
1735
+ }
1736
+ });
1737
+ //#endregion
1738
+ //#region src/composables/pluginIdentity.ts
1739
+ var identity = reactive({});
1740
+ /** The seeded identity AppTopBar shows in standalone mode. Internal: not exported from the package. */
1741
+ var pluginIdentity = readonly(identity);
1742
+ /**
1743
+ * Seed the standalone AppTopBar with the plugin name, subtitle and icon. In integrated
1744
+ * mode the platform supplies them. Explicit `title`/`subtitle` props and the `#icon` slot still win.
1745
+ *
1746
+ * @example
1747
+ * ```typescript
1748
+ * import { providePluginIdentity } from '@morscherlab/mint-sdk'
1749
+ * import { contract } from './generated/mint-plugin'
1750
+ *
1751
+ * providePluginIdentity(contract)
1752
+ * ```
1753
+ */
1754
+ function providePluginIdentity(contract) {
1755
+ const { plugin } = contract;
1756
+ identity.name = plugin.displayName || plugin.name || void 0;
1757
+ identity.subtitle = plugin.subtitle || plugin.description || void 0;
1758
+ identity.icon = plugin.icon || void 0;
1759
+ }
1760
+ //#endregion
1761
+ //#region src/components/AppTopBar.toastOffset.ts
1762
+ /**
1763
+ * Publishes the top-most mounted AppTopBar's bottom edge as `--mint-toast-offset-top`
1764
+ * on `<html>`, so the teleported toast container starts below the top bar.
1765
+ */
1766
+ var TOAST_OFFSET_PROPERTY = "--mint-toast-offset-top";
1767
+ var LISTENER_OPTIONS = {
1768
+ capture: true,
1769
+ passive: true
1770
+ };
1771
+ var topBars = /* @__PURE__ */ new Set();
1772
+ var observer;
1773
+ function syncToastOffset() {
1774
+ const style = document.documentElement.style;
1775
+ if (topBars.size === 0) {
1776
+ style.removeProperty(TOAST_OFFSET_PROPERTY);
1777
+ return;
1778
+ }
1779
+ const header = [...topBars].map((el) => el.getBoundingClientRect()).reduce((top, rect) => rect.top < top.top ? rect : top);
1780
+ style.setProperty(TOAST_OFFSET_PROPERTY, `calc(${Math.max(0, Math.round(header.bottom))}px + 1rem)`);
1781
+ }
1782
+ /** Track a top bar element; returns the cleanup to call on unmount. */
1783
+ function trackTopBarForToasts(el) {
1784
+ if (topBars.size === 0) {
1785
+ window.addEventListener("scroll", syncToastOffset, LISTENER_OPTIONS);
1786
+ window.addEventListener("resize", syncToastOffset, LISTENER_OPTIONS);
1787
+ if (typeof ResizeObserver !== "undefined") observer = new ResizeObserver(syncToastOffset);
1788
+ }
1789
+ topBars.add(el);
1790
+ observer?.observe(el);
1791
+ syncToastOffset();
1792
+ return () => {
1793
+ topBars.delete(el);
1794
+ observer?.unobserve(el);
1795
+ if (topBars.size === 0) {
1796
+ window.removeEventListener("scroll", syncToastOffset, LISTENER_OPTIONS);
1797
+ window.removeEventListener("resize", syncToastOffset, LISTENER_OPTIONS);
1798
+ observer?.disconnect();
1799
+ observer = void 0;
1800
+ }
1801
+ syncToastOffset();
1802
+ };
1803
+ }
1804
+ //#endregion
1805
+ //#region src/components/AppTopBar.vue?vue&type=script&setup=true&lang.ts
1806
+ var _hoisted_1$4 = { class: "mint-topbar__container" };
1807
+ var _hoisted_2$2 = { class: "mint-topbar__start" };
1808
+ var _hoisted_3$2 = { class: "mint-topbar__brand" };
1809
+ var _hoisted_4$2 = ["href"];
1810
+ var _hoisted_5$2 = {
1811
+ key: 0,
1812
+ class: "mint-topbar__identity"
1813
+ };
1814
+ var _hoisted_6$1 = {
1815
+ key: 0,
1816
+ class: "mint-topbar__logo"
1817
+ };
1818
+ var _hoisted_7$1 = {
1819
+ key: 0,
1820
+ class: "mint-topbar__identity"
1821
+ };
1822
+ var _hoisted_8$1 = {
1823
+ key: 0,
1824
+ class: "mint-topbar__logo"
1825
+ };
1826
+ var _hoisted_9$1 = {
1827
+ key: 0,
1828
+ class: "mint-topbar__identity"
1829
+ };
1830
+ var _hoisted_10$1 = {
1831
+ key: 0,
1832
+ class: "mint-topbar__logo"
1833
+ };
1834
+ var _hoisted_11$1 = {
1835
+ key: 0,
1836
+ class: "mint-topbar__plugin-identity"
1837
+ };
1838
+ var _hoisted_12$1 = { class: "mint-topbar__plugin-name" };
1839
+ var _hoisted_13$1 = {
1840
+ key: 0,
1841
+ class: "mint-topbar__plugin-subtitle"
1842
+ };
1843
+ var _hoisted_14$1 = {
1844
+ key: 3,
1845
+ class: "mint-topbar-title-group"
1846
+ };
1847
+ var _hoisted_15$1 = { class: "mint-topbar-title" };
1848
+ var _hoisted_16$1 = { class: "mint-topbar-subtitle" };
1849
+ var _hoisted_17$1 = {
1850
+ key: 4,
1851
+ class: "mint-topbar__title-only"
1852
+ };
1853
+ var _hoisted_18$1 = {
1854
+ key: 0,
1855
+ class: "mint-topbar__center"
1856
+ };
1857
+ var _hoisted_19$1 = { class: "mint-topbar__right" };
1858
+ var _hoisted_20$1 = {
1859
+ key: 0,
1860
+ class: "mint-topbar__standalone-badge"
1861
+ };
1862
+ //#endregion
1863
+ //#region src/components/AppTopBar.vue
1864
+ var AppTopBar_default = /* @__PURE__ */ defineComponent({
1865
+ __name: "AppTopBar",
1866
+ props: {
1867
+ title: {},
1868
+ subtitle: {},
1869
+ spec: { default: () => ({}) },
1870
+ pill: {},
1871
+ pageSelector: {},
1872
+ currentPageSelectorId: {}
1873
+ },
1874
+ emits: [
1875
+ "page-selector-select",
1876
+ "update:pill",
1877
+ "pill-select",
1878
+ "pill-option-select",
1879
+ "settings-values-change"
1880
+ ],
1881
+ setup(__props, { emit: __emit }) {
1882
+ /**
1883
+ * Full application top bar with brand logo, static plugin identity, page selector, centered pill nav, experiment popover, and an account slot.
1884
+ *
1885
+ * The `#icon` slot applies in standalone mode only; integrated branding comes from `Metadata.icon`.
1886
+ */
1887
+ const props = __props;
1888
+ const config = computed(() => applySpecDefaults({
1889
+ variant: "card",
1890
+ homePath: "/",
1891
+ logo: true,
1892
+ themeToggle: false,
1893
+ settings: false,
1894
+ standaloneLabel: "Standalone"
1895
+ }, props.spec));
1896
+ const settingsConfig = computed(() => toValue(config.value.settings) || void 0);
1897
+ const showSettings = computed(() => settingsConfig.value !== void 0);
1898
+ const SettingsModal = defineAsyncComponent(() => import("./SettingsModal-DO3IZ7qz.js").then((n) => n.n));
1899
+ const ExperimentPopover = defineAsyncComponent(() => import("./ExperimentPopover-5T1fAq2L.js").then((n) => n.n));
1900
+ const ExperimentSelectorModal = defineAsyncComponent(() => import("./ExperimentSelectorModal-65peG4Up.js").then((n) => n.n));
1901
+ const emit = __emit;
1902
+ const settingsOpen = ref(false);
1903
+ const headerEl = ref(null);
1904
+ let untrackToastOffset;
1905
+ onMounted(() => {
1906
+ if (headerEl.value) untrackToastOffset = trackTopBarForToasts(headerEl.value);
1907
+ });
1908
+ onBeforeUnmount(() => untrackToastOffset?.());
1909
+ const { integrated: isIntegrated, plugin } = usePlatform();
1910
+ const isStandalone = computed(() => !isIntegrated.value);
1911
+ const appExperiment = inject(APP_EXPERIMENT_KEY, null);
1912
+ const canBindExperiment = computed(() => plugin.value?.plugin_type !== "static");
1913
+ const slots = useSlots();
1914
+ const pluginIcon = computed(() => plugin.value?.icon || (slots.logo ? void 0 : pluginIdentity.icon));
1915
+ const seeded = computed(() => isStandalone.value && !props.title && !props.subtitle);
1916
+ const titleText = computed(() => props.title || (seeded.value ? pluginIdentity.name : void 0));
1917
+ const subtitleText = computed(() => props.subtitle || (seeded.value ? pluginIdentity.subtitle : void 0));
1918
+ const hasPlatformPageSelector = computed(() => props.pageSelector === void 0 && (plugin.value?.nav_items?.length ?? 0) > 1);
1919
+ const hasPropPageSelector = computed(() => (props.pageSelector?.length ?? 0) > 1);
1920
+ const hasPageSelector = computed(() => hasPropPageSelector.value || hasPlatformPageSelector.value);
1921
+ const platformPageSelectorEl = ref(null);
1922
+ watch(platformPageSelectorEl, (element, _previous, onCleanup) => {
1923
+ const unmount = element ? integrationHost()?.mountPageSelector(element) : void 0;
1924
+ if (unmount) onCleanup(unmount);
1925
+ }, { flush: "sync" });
1926
+ /** Integrated plugins show their name as a static identity in place of the title; the page selector replaces it. */
1927
+ const identityName = computed(() => isIntegrated.value && !hasPageSelector.value ? plugin.value?.display_name || plugin.value?.name : void 0);
1928
+ const identitySubtitle = computed(() => plugin.value?.subtitle || plugin.value?.description);
1929
+ const hasPillNav = computed(() => !!config.value.pills?.length);
1930
+ const hasTitleGroup = computed(() => !hasPageSelector.value && !identityName.value && !!titleText.value && !!subtitleText.value);
1931
+ const hasTitleOnly = computed(() => !hasPageSelector.value && !identityName.value && !hasTitleGroup.value && !!titleText.value);
1932
+ const normalizedPageSelector = computed(() => props.pageSelector?.map(normalizeItemInput) ?? []);
1933
+ const normalizedPillNav = computed(() => config.value.pills ?? []);
1934
+ function handlePillSelect(item) {
1935
+ emit("update:pill", item.id);
1936
+ emit("pill-select", item);
1937
+ }
1938
+ const normalizedSettingsTabs = computed(() => settingsConfig.value?.tabs?.map(normalizeItemInput) ?? []);
1939
+ return (_ctx, _cache) => {
1940
+ const _component_router_link = resolveComponent("router-link");
1941
+ return openBlock(), createElementBlock(Fragment, null, [
1942
+ createElementVNode("header", {
1943
+ ref_key: "headerEl",
1944
+ ref: headerEl,
1945
+ class: normalizeClass(["mint-topbar", `mint-topbar--${config.value.variant}`])
1946
+ }, [createElementVNode("div", _hoisted_1$4, [
1947
+ createElementVNode("div", _hoisted_2$2, [
1948
+ createElementVNode("div", _hoisted_3$2, [config.value.homePath && (config.value.homePath.startsWith("http") || config.value.homePath.startsWith("/")) ? (openBlock(), createElementBlock("a", {
1949
+ key: 0,
1950
+ href: config.value.homePath,
1951
+ class: "mint-topbar-home-link"
1952
+ }, [unref(isIntegrated) || _ctx.$slots.icon || _ctx.$slots.logo || pluginIcon.value || config.value.logo ? (openBlock(), createElementBlock("span", _hoisted_5$2, [unref(isIntegrated) ? (openBlock(), createBlock(PluginIcon_default, {
1953
+ key: 0,
1954
+ class: "mint-topbar__plugin-icon",
1955
+ icon: unref(plugin)?.icon,
1956
+ size: "topbar",
1957
+ variant: "solid"
1958
+ }, null, 8, ["icon"])) : renderSlot(_ctx.$slots, "icon", {}, () => [pluginIcon.value ? (openBlock(), createBlock(PluginIcon_default, {
1959
+ key: 0,
1960
+ class: "mint-topbar__plugin-icon",
1961
+ icon: pluginIcon.value,
1962
+ size: "topbar",
1963
+ variant: "solid"
1964
+ }, null, 8, ["icon"])) : renderSlot(_ctx.$slots, "logo", {}, () => [config.value.logo ? (openBlock(), createElementBlock("div", _hoisted_6$1, [..._cache[9] || (_cache[9] = [createElementVNode("div", { class: "mint-topbar__logo-icon" }, [createElementVNode("span", { class: "mint-topbar__logo-text" }, "M")], -1)])])) : createCommentVNode("", true)], void 0, 1)], void 0, 1)])) : createCommentVNode("", true)], 8, _hoisted_4$2)) : config.value.homePath ? (openBlock(), createBlock(_component_router_link, {
1965
+ key: 1,
1966
+ to: config.value.homePath,
1967
+ class: "mint-topbar-home-link"
1968
+ }, {
1969
+ default: withCtx(() => [unref(isIntegrated) || _ctx.$slots.icon || _ctx.$slots.logo || pluginIcon.value || config.value.logo ? (openBlock(), createElementBlock("span", _hoisted_7$1, [unref(isIntegrated) ? (openBlock(), createBlock(PluginIcon_default, {
1970
+ key: 0,
1971
+ class: "mint-topbar__plugin-icon",
1972
+ icon: unref(plugin)?.icon,
1973
+ size: "topbar",
1974
+ variant: "solid"
1975
+ }, null, 8, ["icon"])) : renderSlot(_ctx.$slots, "icon", {}, () => [pluginIcon.value ? (openBlock(), createBlock(PluginIcon_default, {
1976
+ key: 0,
1977
+ class: "mint-topbar__plugin-icon",
1978
+ icon: pluginIcon.value,
1979
+ size: "topbar",
1980
+ variant: "solid"
1981
+ }, null, 8, ["icon"])) : renderSlot(_ctx.$slots, "logo", {}, () => [config.value.logo ? (openBlock(), createElementBlock("div", _hoisted_8$1, [..._cache[10] || (_cache[10] = [createElementVNode("div", { class: "mint-topbar__logo-icon" }, [createElementVNode("span", { class: "mint-topbar__logo-text" }, "M")], -1)])])) : createCommentVNode("", true)], void 0, 1)], void 0, 1)])) : createCommentVNode("", true)]),
1982
+ _: 3
1983
+ }, 8, ["to"])) : (openBlock(), createElementBlock(Fragment, { key: 2 }, [unref(isIntegrated) || _ctx.$slots.icon || _ctx.$slots.logo || pluginIcon.value || config.value.logo ? (openBlock(), createElementBlock("span", _hoisted_9$1, [unref(isIntegrated) ? (openBlock(), createBlock(PluginIcon_default, {
1984
+ key: 0,
1985
+ class: "mint-topbar__plugin-icon",
1986
+ icon: unref(plugin)?.icon,
1987
+ size: "topbar",
1988
+ variant: "solid"
1989
+ }, null, 8, ["icon"])) : renderSlot(_ctx.$slots, "icon", {}, () => [pluginIcon.value ? (openBlock(), createBlock(PluginIcon_default, {
1990
+ key: 0,
1991
+ class: "mint-topbar__plugin-icon",
1992
+ icon: pluginIcon.value,
1993
+ size: "topbar",
1994
+ variant: "solid"
1995
+ }, null, 8, ["icon"])) : renderSlot(_ctx.$slots, "logo", {}, () => [config.value.logo ? (openBlock(), createElementBlock("div", _hoisted_10$1, [..._cache[11] || (_cache[11] = [createElementVNode("div", { class: "mint-topbar__logo-icon" }, [createElementVNode("span", { class: "mint-topbar__logo-text" }, "M")], -1)])])) : createCommentVNode("", true)], void 0, 1)], void 0, 1)])) : createCommentVNode("", true)], 64))]),
1996
+ identityName.value ? (openBlock(), createElementBlock("span", _hoisted_11$1, [createElementVNode("span", _hoisted_12$1, toDisplayString(identityName.value), 1), identitySubtitle.value ? (openBlock(), createElementBlock("span", _hoisted_13$1, toDisplayString(identitySubtitle.value), 1)) : createCommentVNode("", true)])) : createCommentVNode("", true),
1997
+ hasPlatformPageSelector.value ? (openBlock(), createElementBlock("span", {
1998
+ key: 1,
1999
+ ref_key: "platformPageSelectorEl",
2000
+ ref: platformPageSelectorEl,
2001
+ class: "mint-topbar__platform-page-selector"
2002
+ }, null, 512)) : hasPropPageSelector.value ? (openBlock(), createBlock(AppTopBarPageSelectorInternal_default, {
2003
+ key: 2,
2004
+ pages: normalizedPageSelector.value,
2005
+ "current-page-id": __props.currentPageSelectorId,
2006
+ onSelect: _cache[0] || (_cache[0] = ($event) => emit("page-selector-select", $event))
2007
+ }, createSlots({ _: 2 }, [_ctx.$slots["page-selector-icon"] ? {
2008
+ name: "icon",
2009
+ fn: withCtx((slotProps) => [renderSlot(_ctx.$slots, "page-selector-icon", normalizeProps(guardReactiveProps(slotProps)))]),
2010
+ key: "0"
2011
+ } : void 0, _ctx.$slots["page-selector-item-icon"] ? {
2012
+ name: "item-icon",
2013
+ fn: withCtx((slotProps) => [renderSlot(_ctx.$slots, "page-selector-item-icon", normalizeProps(guardReactiveProps(slotProps)))]),
2014
+ key: "1"
2015
+ } : void 0]), 1032, ["pages", "current-page-id"])) : createCommentVNode("", true),
2016
+ hasTitleGroup.value ? (openBlock(), createElementBlock("div", _hoisted_14$1, [createElementVNode("span", _hoisted_15$1, toDisplayString(titleText.value), 1), createElementVNode("span", _hoisted_16$1, toDisplayString(subtitleText.value), 1)])) : hasTitleOnly.value ? (openBlock(), createElementBlock("span", _hoisted_17$1, toDisplayString(titleText.value), 1)) : createCommentVNode("", true),
2017
+ renderSlot(_ctx.$slots, "nav")
2018
+ ]),
2019
+ hasPillNav.value || _ctx.$slots.center ? (openBlock(), createElementBlock("div", _hoisted_18$1, [renderSlot(_ctx.$slots, "center", {}, () => [hasPillNav.value ? (openBlock(), createBlock(AppTopBarPillNavInternal_default, {
2020
+ key: 0,
2021
+ items: normalizedPillNav.value,
2022
+ "current-item-id": __props.pill,
2023
+ onSelect: handlePillSelect,
2024
+ onOptionSelect: _cache[1] || (_cache[1] = (option, item) => emit("pill-option-select", option, item))
2025
+ }, null, 8, ["items", "current-item-id"])) : createCommentVNode("", true)])])) : createCommentVNode("", true),
2026
+ createElementVNode("div", _hoisted_19$1, [
2027
+ config.value.standaloneLabel !== false && isStandalone.value ? (openBlock(), createElementBlock("span", _hoisted_20$1, toDisplayString(config.value.standaloneLabel), 1)) : createCommentVNode("", true),
2028
+ unref(appExperiment) && !isStandalone.value && canBindExperiment.value ? (openBlock(), createBlock(unref(ExperimentPopover), mergeProps({ key: 1 }, unref(appExperiment).popover.value, {
2029
+ onSelect: _cache[2] || (_cache[2] = ($event) => unref(appExperiment).openModal()),
2030
+ onSave: _cache[3] || (_cache[3] = ($event) => unref(appExperiment).handleSave()),
2031
+ onDetach: _cache[4] || (_cache[4] = ($event) => unref(appExperiment).handleDetach())
2032
+ }), null, 16)) : createCommentVNode("", true),
2033
+ renderSlot(_ctx.$slots, "actions"),
2034
+ config.value.themeToggle ? (openBlock(), createBlock(ThemeToggle_default, {
2035
+ key: 2,
2036
+ size: "sm"
2037
+ })) : createCommentVNode("", true),
2038
+ showSettings.value ? (openBlock(), createElementBlock("button", {
2039
+ key: 3,
2040
+ type: "button",
2041
+ class: "mint-topbar__settings-btn",
2042
+ "aria-label": "Open settings",
2043
+ onClick: _cache[5] || (_cache[5] = ($event) => settingsOpen.value = true)
2044
+ }, [..._cache[12] || (_cache[12] = [createElementVNode("svg", {
2045
+ class: "mint-topbar__settings-icon",
2046
+ viewBox: "0 0 24 24",
2047
+ fill: "none",
2048
+ stroke: "currentColor",
2049
+ "stroke-width": "2",
2050
+ "stroke-linecap": "round",
2051
+ "stroke-linejoin": "round"
2052
+ }, [createElementVNode("path", { d: "M9.671 4.136a2.34 2.34 0 0 1 4.659 0 2.34 2.34 0 0 0 3.319 1.915 2.34 2.34 0 0 1 2.33 4.033 2.34 2.34 0 0 0 0 3.831 2.34 2.34 0 0 1-2.33 4.033 2.34 2.34 0 0 0-3.319 1.915 2.34 2.34 0 0 1-4.659 0 2.34 2.34 0 0 0-3.32-1.915 2.34 2.34 0 0 1-2.33-4.033 2.34 2.34 0 0 0 0-3.831A2.34 2.34 0 0 1 6.35 6.051a2.34 2.34 0 0 0 3.319-1.915" }), createElementVNode("circle", {
2053
+ cx: "12",
2054
+ cy: "12",
2055
+ r: "3"
2056
+ })], -1)])])) : createCommentVNode("", true),
2057
+ renderSlot(_ctx.$slots, "account")
2058
+ ])
2059
+ ])], 2),
2060
+ showSettings.value && settingsOpen.value ? (openBlock(), createBlock(unref(SettingsModal), {
2061
+ key: 0,
2062
+ open: settingsOpen.value,
2063
+ "onUpdate:open": _cache[6] || (_cache[6] = ($event) => settingsOpen.value = $event),
2064
+ title: settingsConfig.value?.title,
2065
+ tabs: normalizedSettingsTabs.value,
2066
+ "show-appearance": settingsConfig.value?.showAppearance ?? true,
2067
+ "appearance-first": settingsConfig.value?.appearanceFirst,
2068
+ size: settingsConfig.value?.size,
2069
+ layout: settingsConfig.value?.layout,
2070
+ spec: settingsConfig.value?.spec,
2071
+ values: settingsConfig.value?.values,
2072
+ "user-type": settingsConfig.value?.userType,
2073
+ "onUpdate:values": _cache[7] || (_cache[7] = ($event) => emit("settings-values-change", $event))
2074
+ }, createSlots({
2075
+ appearance: withCtx(() => [renderSlot(_ctx.$slots, "settings-appearance")]),
2076
+ _: 2
2077
+ }, [renderList(normalizedSettingsTabs.value, (tab) => {
2078
+ return {
2079
+ name: `tab-${tab.id}`,
2080
+ fn: withCtx(() => [renderSlot(_ctx.$slots, `settings-tab-${tab.id}`)])
2081
+ };
2082
+ })]), 1032, [
2083
+ "open",
2084
+ "title",
2085
+ "tabs",
2086
+ "show-appearance",
2087
+ "appearance-first",
2088
+ "size",
2089
+ "layout",
2090
+ "spec",
2091
+ "values",
2092
+ "user-type"
2093
+ ])) : createCommentVNode("", true),
2094
+ unref(appExperiment) && !isStandalone.value && canBindExperiment.value && unref(appExperiment).selectorModal.value.open ? (openBlock(), createBlock(unref(ExperimentSelectorModal), mergeProps({ key: 1 }, unref(appExperiment).selectorModal.value, { "onUpdate:open": _cache[8] || (_cache[8] = ($event) => $event ? unref(appExperiment).openModal() : unref(appExperiment).closeModal()) }), null, 16)) : createCommentVNode("", true)
2095
+ ], 64);
2096
+ };
2097
+ }
2098
+ });
2099
+ //#endregion
2100
+ //#region src/composables/useFormValidation.ts
2101
+ var validators = {
2102
+ required: (value, message = "This field is required") => {
2103
+ if (value === null || value === void 0 || value === "") return message;
2104
+ if (Array.isArray(value) && value.length === 0) return message;
2105
+ return null;
2106
+ },
2107
+ minLength: (value, min, message) => {
2108
+ if (typeof value !== "string") return null;
2109
+ if (value.length < min) return message || `Must be at least ${min} characters`;
2110
+ return null;
2111
+ },
2112
+ maxLength: (value, max, message) => {
2113
+ if (typeof value !== "string") return null;
2114
+ if (value.length > max) return message || `Must be at most ${max} characters`;
2115
+ return null;
2116
+ },
2117
+ min: (value, min, message) => {
2118
+ if (typeof value !== "number") return null;
2119
+ if (value < min) return message || `Must be at least ${min}`;
2120
+ return null;
2121
+ },
2122
+ max: (value, max, message) => {
2123
+ if (typeof value !== "number") return null;
2124
+ if (value > max) return message || `Must be at most ${max}`;
2125
+ return null;
2126
+ },
2127
+ pattern: (value, pattern, message) => {
2128
+ if (typeof value !== "string") return null;
2129
+ if (!pattern.test(value)) return message || "Invalid format";
2130
+ return null;
2131
+ },
2132
+ email: (value, message = "Invalid email address") => {
2133
+ if (typeof value !== "string" || !value) return null;
2134
+ if (!/^[^\s@]+@[^\s@]+\.[^\s@]+$/.test(value)) return message;
2135
+ return null;
2136
+ }
2137
+ };
2138
+ function validateFieldValue(value, fieldRules, formData) {
2139
+ if (!fieldRules) return null;
2140
+ if (fieldRules.required) {
2141
+ const message = typeof fieldRules.required === "string" ? fieldRules.required : void 0;
2142
+ const error = validators.required(value, message);
2143
+ if (error) return error;
2144
+ }
2145
+ if (value === null || value === void 0 || value === "") return null;
2146
+ if (fieldRules.minLength !== void 0) {
2147
+ const config = typeof fieldRules.minLength === "number" ? {
2148
+ value: fieldRules.minLength,
2149
+ message: void 0
2150
+ } : fieldRules.minLength;
2151
+ const error = validators.minLength(value, config.value, config.message);
2152
+ if (error) return error;
2153
+ }
2154
+ if (fieldRules.maxLength !== void 0) {
2155
+ const config = typeof fieldRules.maxLength === "number" ? {
2156
+ value: fieldRules.maxLength,
2157
+ message: void 0
2158
+ } : fieldRules.maxLength;
2159
+ const error = validators.maxLength(value, config.value, config.message);
2160
+ if (error) return error;
2161
+ }
2162
+ if (fieldRules.min !== void 0) {
2163
+ const config = typeof fieldRules.min === "number" ? {
2164
+ value: fieldRules.min,
2165
+ message: void 0
2166
+ } : fieldRules.min;
2167
+ const error = validators.min(value, config.value, config.message);
2168
+ if (error) return error;
2169
+ }
2170
+ if (fieldRules.max !== void 0) {
2171
+ const config = typeof fieldRules.max === "number" ? {
2172
+ value: fieldRules.max,
2173
+ message: void 0
2174
+ } : fieldRules.max;
2175
+ const error = validators.max(value, config.value, config.message);
2176
+ if (error) return error;
2177
+ }
2178
+ if (fieldRules.pattern !== void 0) {
2179
+ const config = fieldRules.pattern instanceof RegExp ? {
2180
+ value: fieldRules.pattern,
2181
+ message: void 0
2182
+ } : fieldRules.pattern;
2183
+ const error = validators.pattern(value, config.value, config.message);
2184
+ if (error) return error;
2185
+ }
2186
+ if (fieldRules.email) {
2187
+ const message = typeof fieldRules.email === "string" ? fieldRules.email : void 0;
2188
+ const error = validators.email(value, message);
2189
+ if (error) return error;
2190
+ }
2191
+ if (fieldRules.custom) {
2192
+ const customRules = Array.isArray(fieldRules.custom) ? fieldRules.custom : [fieldRules.custom];
2193
+ for (const rule of customRules) {
2194
+ const error = rule(value, formData);
2195
+ if (error) return error;
2196
+ }
2197
+ }
2198
+ return null;
2199
+ }
2200
+ //#endregion
2201
+ //#region src/composables/useForm.ts
2202
+ /**
2203
+ * Form state management composable with validation.
2204
+ *
2205
+ * @param initialValues - Initial form values
2206
+ * @param rules - Validation rules for each field
2207
+ *
2208
+ * @example
2209
+ * ```typescript
2210
+ * const { data, errors, isValid, handleSubmit, getFieldProps } = useForm(
2211
+ * { email: '', password: '' },
2212
+ * {
2213
+ * email: { required: true, email: true },
2214
+ * password: { required: true, minLength: 8 },
2215
+ * }
2216
+ * )
2217
+ *
2218
+ * // In template
2219
+ * <BaseInput v-bind="getFieldProps('email')" label="Email" />
2220
+ * <BaseInput v-bind="getFieldProps('password')" type="password" label="Password" />
2221
+ * <BaseButton @click="handleSubmit(onSubmit)" :disabled="!isValid">Submit</BaseButton>
2222
+ * ```
2223
+ */
2224
+ /** Reactive form state with field-level validation, dirty tracking, and submit handling. */
2225
+ function useForm(initialValues, rules = {}) {
2226
+ const cloneableInitialValues = deepToRaw(initialValues);
2227
+ let _initialValues = structuredClone(cloneableInitialValues);
2228
+ const data = reactive(structuredClone(cloneableInitialValues));
2229
+ const errors = reactive(Object.keys(initialValues).reduce((acc, key) => {
2230
+ acc[key] = null;
2231
+ return acc;
2232
+ }, {}));
2233
+ const touched = reactive(Object.keys(initialValues).reduce((acc, key) => {
2234
+ acc[key] = false;
2235
+ return acc;
2236
+ }, {}));
2237
+ const dirty = reactive(Object.keys(initialValues).reduce((acc, key) => {
2238
+ acc[key] = false;
2239
+ return acc;
2240
+ }, {}));
2241
+ const isSubmitting = ref(false);
2242
+ watch(() => ({ ...data }), (newData) => {
2243
+ for (const key of Object.keys(newData)) dirty[key] = newData[key] !== _initialValues[key];
2244
+ }, { deep: true });
2245
+ function validateField(field) {
2246
+ const value = data[field];
2247
+ const fieldRules = rules[field];
2248
+ const error = validateFieldValue(value, fieldRules, data);
2249
+ errors[field] = error;
2250
+ return error === null;
2251
+ }
2252
+ function validate() {
2253
+ let isAllValid = true;
2254
+ for (const field of Object.keys(data)) if (!validateField(field)) isAllValid = false;
2255
+ return isAllValid;
2256
+ }
2257
+ const isValid = computed(() => {
2258
+ return Object.values(errors).every((error) => error === null);
2259
+ });
2260
+ const isDirty = computed(() => {
2261
+ return Object.values(dirty).some((d) => d);
2262
+ });
2263
+ function setFieldValue(field, value) {
2264
+ data[field] = value;
2265
+ if (touched[field]) validateField(field);
2266
+ }
2267
+ function setFieldError(field, error) {
2268
+ errors[field] = error;
2269
+ }
2270
+ function setFieldTouched(field, isTouched = true) {
2271
+ touched[field] = isTouched;
2272
+ if (isTouched) validateField(field);
2273
+ }
2274
+ function reset(values) {
2275
+ const resetValues = values ? {
2276
+ ..._initialValues,
2277
+ ...values
2278
+ } : _initialValues;
2279
+ for (const key of Object.keys(data)) {
2280
+ data[key] = structuredClone(deepToRaw(resetValues[key]));
2281
+ errors[key] = null;
2282
+ touched[key] = false;
2283
+ dirty[key] = false;
2284
+ }
2285
+ }
2286
+ function replaceState(values) {
2287
+ const nextValues = structuredClone(deepToRaw(values));
2288
+ _initialValues = structuredClone(nextValues);
2289
+ for (const key of Object.keys(data)) {
2290
+ if (key in nextValues) continue;
2291
+ delete data[key];
2292
+ delete errors[key];
2293
+ delete touched[key];
2294
+ delete dirty[key];
2295
+ }
2296
+ for (const key of Object.keys(nextValues)) {
2297
+ data[key] = structuredClone(deepToRaw(nextValues[key]));
2298
+ errors[key] = null;
2299
+ touched[key] = false;
2300
+ dirty[key] = false;
2301
+ }
2302
+ }
2303
+ function handleSubmit(onSubmit) {
2304
+ return async (e) => {
2305
+ e?.preventDefault();
2306
+ for (const field of Object.keys(data)) touched[field] = true;
2307
+ if (!validate()) return;
2308
+ isSubmitting.value = true;
2309
+ try {
2310
+ await onSubmit(data);
2311
+ } finally {
2312
+ isSubmitting.value = false;
2313
+ }
2314
+ };
2315
+ }
2316
+ function getFieldProps(field) {
2317
+ const fieldStr = field;
2318
+ return {
2319
+ modelValue: data[field],
2320
+ "onUpdate:modelValue": (value) => setFieldValue(field, value),
2321
+ onBlur: () => setFieldTouched(fieldStr),
2322
+ error: touched[fieldStr] ? errors[fieldStr] : null
2323
+ };
2324
+ }
2325
+ return {
2326
+ data,
2327
+ errors,
2328
+ touched,
2329
+ dirty,
2330
+ isValid,
2331
+ isDirty,
2332
+ isSubmitting,
2333
+ setFieldValue,
2334
+ setFieldError,
2335
+ setFieldTouched,
2336
+ validateField,
2337
+ validate,
2338
+ reset,
2339
+ replaceState,
2340
+ handleSubmit,
2341
+ getFieldProps
2342
+ };
2343
+ }
2344
+ function deepToRaw(value) {
2345
+ const raw = toRaw(value);
2346
+ if (Array.isArray(raw)) return raw.map((item) => deepToRaw(item));
2347
+ if (isPlainRecord(raw)) return Object.fromEntries(Object.entries(raw).map(([key, item]) => [key, deepToRaw(item)]));
2348
+ return raw;
2349
+ }
2350
+ function isPlainRecord(value) {
2351
+ return Object.prototype.toString.call(value) === "[object Object]";
2352
+ }
2353
+ //#endregion
2354
+ //#region src/composables/formBuilderSchema.ts
2355
+ /**
2356
+ * Evaluate a JSON-serializable field condition against the current form data.
2357
+ *
2358
+ * Supports logical operators (`and`, `or`, `not`) and comparison operators
2359
+ * (`eq`, `neq`, `gt`, `lt`, `gte`, `lte`, `in`, `notIn`, `truthy`, `falsy`,
2360
+ * `contains`). Returns `true` if the condition passes.
2361
+ */
2362
+ function evaluateCondition(condition, data) {
2363
+ if ("and" in condition) return condition.and.every((c) => evaluateCondition(c, data));
2364
+ if ("or" in condition) return condition.or.some((c) => evaluateCondition(c, data));
2365
+ if ("not" in condition) return !evaluateCondition(condition.not, data);
2366
+ const value = data[condition.field];
2367
+ if ("eq" in condition) return value === condition.eq;
2368
+ if ("neq" in condition) return value !== condition.neq;
2369
+ if ("gt" in condition) return typeof value === "number" && value > condition.gt;
2370
+ if ("lt" in condition) return typeof value === "number" && value < condition.lt;
2371
+ if ("gte" in condition) return typeof value === "number" && value >= condition.gte;
2372
+ if ("lte" in condition) return typeof value === "number" && value <= condition.lte;
2373
+ if ("in" in condition) return condition.in.includes(value);
2374
+ if ("notIn" in condition) return !condition.notIn.includes(value);
2375
+ if ("truthy" in condition) return !!value;
2376
+ if ("falsy" in condition) return !value;
2377
+ if ("contains" in condition) {
2378
+ if (typeof value === "string") return value.includes(condition.contains);
2379
+ if (Array.isArray(value)) return value.includes(condition.contains);
2380
+ return false;
2381
+ }
2382
+ return true;
2383
+ }
2384
+ /** Return all sections across steps (wizard) or directly from a flat schema. */
2385
+ function collectSections(schema) {
2386
+ return schema.steps ? schema.steps.flatMap((step) => step.sections) : schema.sections;
2387
+ }
2388
+ /** Return all field schemas in schema order, flattening sections and steps. */
2389
+ function flattenFields(schema) {
2390
+ return collectSections(schema).flatMap((section) => section.fields);
2391
+ }
2392
+ /** Convert a JSON-safe `FieldValidation` descriptor to a runtime `FieldRules` object. */
2393
+ function convertValidation(v) {
2394
+ const rules = {};
2395
+ if (v.required !== void 0) rules.required = v.required;
2396
+ if (v.minLength !== void 0) rules.minLength = v.minLength;
2397
+ if (v.maxLength !== void 0) rules.maxLength = v.maxLength;
2398
+ if (v.min !== void 0) rules.min = v.min;
2399
+ if (v.max !== void 0) rules.max = v.max;
2400
+ if (v.email !== void 0) rules.email = v.email;
2401
+ if (v.pattern !== void 0) rules.pattern = typeof v.pattern === "string" ? new RegExp(v.pattern) : {
2402
+ value: new RegExp(v.pattern.value),
2403
+ message: v.pattern.message
2404
+ };
2405
+ return rules;
2406
+ }
2407
+ function buildInitialValues(fields, initialData) {
2408
+ const initialValues = {};
2409
+ for (const field of fields) {
2410
+ const key = field.name;
2411
+ if (initialData && hasOwnKey(initialData, key)) initialValues[key] = initialData[key];
2412
+ else if (field.defaultValue !== void 0) initialValues[key] = field.defaultValue;
2413
+ else initialValues[key] = getTypeDefault(field.type);
2414
+ }
2415
+ return initialValues;
2416
+ }
2417
+ function buildRules(fields, enhancements) {
2418
+ const rules = {};
2419
+ for (const field of fields) {
2420
+ const base = field.validation ? convertValidation(field.validation) : {};
2421
+ const enhancement = enhancements?.fields?.[field.name];
2422
+ const customValidators = [];
2423
+ if (enhancement?.validate) {
2424
+ const fn = enhancement.validate;
2425
+ customValidators.push((value, formData) => fn(value, formData));
2426
+ }
2427
+ if (customValidators.length > 0) base.custom = customValidators;
2428
+ if (Object.keys(base).length > 0) rules[field.name] = base;
2429
+ }
2430
+ return rules;
2431
+ }
2432
+ function replaceArray(target, values) {
2433
+ target.splice(0, target.length, ...values);
2434
+ }
2435
+ function replaceRecord(target, source) {
2436
+ for (const key of Object.keys(target)) delete target[key];
2437
+ Object.assign(target, source);
2438
+ }
2439
+ function hasOwnKey(source, key) {
2440
+ return Object.prototype.hasOwnProperty.call(source, key);
2441
+ }
2442
+ //#endregion
2443
+ //#region src/composables/useFormBuilder.ts
2444
+ /**
2445
+ * Drive a `FormSchema` as reactive form state.
2446
+ *
2447
+ * Builds initial values from schema defaults and `initialData`, derives
2448
+ * validation rules from `FieldValidation` descriptors and enhancement
2449
+ * validators, evaluates `FieldCondition` expressions for field/section
2450
+ * visibility, and wires wizard step navigation when `schema.steps` is set.
2451
+ *
2452
+ * @param schema - Declarative form or wizard schema.
2453
+ * @param initialData - Values that override schema defaults.
2454
+ * @param enhancements - TypeScript-only callbacks (dynamic options, validators,
2455
+ * submit handler, transform, field-change watcher).
2456
+ */
2457
+ /** Drives a declarative FormSchema as reactive state with conditional fields, wizard steps, and validation. */
2458
+ function useFormBuilder(schema, initialData, enhancements) {
2459
+ const currentSchema = shallowRef(schema);
2460
+ const fields = reactive(flattenFields(schema));
2461
+ const sections = reactive(collectSections(schema));
2462
+ const rules = reactive(buildRules(fields, enhancements));
2463
+ const form = useForm(buildInitialValues(fields, initialData), rules);
2464
+ function isFieldVisible(name) {
2465
+ const enhancement = enhancements?.fields?.[name];
2466
+ if (enhancement?.visible) return enhancement.visible(form.data);
2467
+ const field = fields.find((f) => f.name === name);
2468
+ if (field?.condition) return evaluateCondition(field.condition, form.data);
2469
+ return true;
2470
+ }
2471
+ function isSectionVisible(id) {
2472
+ const section = sections.find((s) => s.id === id);
2473
+ if (section?.condition) return evaluateCondition(section.condition, form.data);
2474
+ return true;
2475
+ }
2476
+ function getResolvedFieldProps(field) {
2477
+ const entry = getFieldRegistryEntry(field.type);
2478
+ const formProps = form.getFieldProps(field.name);
2479
+ const merged = {
2480
+ ...entry.defaults,
2481
+ ...field.props ?? {}
2482
+ };
2483
+ const enhancement = enhancements?.fields?.[field.name];
2484
+ if (enhancement?.props) Object.assign(merged, enhancement.props(form.data));
2485
+ const options = getFieldOptions(field.name);
2486
+ if (options) merged.options = options;
2487
+ if (entry.vModel) {
2488
+ merged.modelValue = formProps.modelValue;
2489
+ merged["onUpdate:modelValue"] = formProps["onUpdate:modelValue"];
2490
+ }
2491
+ merged.onBlur = formProps.onBlur;
2492
+ if (formProps.error) merged.invalid = true;
2493
+ if (field.placeholder) merged.placeholder = field.placeholder;
2494
+ if (field.size) merged.size = field.size;
2495
+ if (field.disabled) merged.disabled = true;
2496
+ if (field.readonly) merged.readonly = true;
2497
+ if (field.type === "radio" && !merged.name) merged.name = field.name;
2498
+ return merged;
2499
+ }
2500
+ function getFieldOptions(name) {
2501
+ const enhancement = enhancements?.fields?.[name];
2502
+ if (enhancement?.options) return enhancement.options(form.data);
2503
+ const field = fields.find((f) => f.name === name);
2504
+ if (field?.props?.options) return field.props.options;
2505
+ }
2506
+ const currentStep = ref(0);
2507
+ const isCurrentStepValid = computed(() => {
2508
+ if (!currentSchema.value.steps) return form.isValid.value;
2509
+ const step = currentSchema.value.steps[currentStep.value];
2510
+ if (!step) return true;
2511
+ for (const section of step.sections) {
2512
+ if (!isSectionVisible(section.id)) continue;
2513
+ for (const field of section.fields) {
2514
+ if (!isFieldVisible(field.name)) continue;
2515
+ if (!form.validateField(field.name)) return false;
2516
+ }
2517
+ }
2518
+ return true;
2519
+ });
2520
+ function goNext() {
2521
+ if (!currentSchema.value.steps) return false;
2522
+ const step = currentSchema.value.steps[currentStep.value];
2523
+ if (!step) return false;
2524
+ let valid = true;
2525
+ for (const section of step.sections) {
2526
+ if (!isSectionVisible(section.id)) continue;
2527
+ for (const field of section.fields) {
2528
+ if (!isFieldVisible(field.name)) continue;
2529
+ form.setFieldTouched(field.name, true);
2530
+ if (!form.validateField(field.name)) valid = false;
2531
+ }
2532
+ }
2533
+ if (!valid) return false;
2534
+ if (currentStep.value < currentSchema.value.steps.length - 1) currentStep.value++;
2535
+ return true;
2536
+ }
2537
+ function goBack() {
2538
+ if (currentStep.value > 0) currentStep.value--;
2539
+ }
2540
+ function goToStep(index) {
2541
+ if (!currentSchema.value.steps) return;
2542
+ if (index >= 0 && index < currentSchema.value.steps.length) currentStep.value = index;
2543
+ }
2544
+ function validate() {
2545
+ let allValid = true;
2546
+ for (const field of fields) {
2547
+ if (!isFieldVisible(field.name)) continue;
2548
+ form.setFieldTouched(field.name, true);
2549
+ if (!form.validateField(field.name)) allValid = false;
2550
+ }
2551
+ return allValid;
2552
+ }
2553
+ async function submit() {
2554
+ if (!validate()) return;
2555
+ let submitData = {};
2556
+ for (const field of fields) if (isFieldVisible(field.name)) submitData[field.name] = form.data[field.name];
2557
+ if (enhancements?.transform) submitData = enhancements.transform(submitData);
2558
+ if (enhancements?.onSubmit) {
2559
+ form.isSubmitting.value = true;
2560
+ try {
2561
+ await enhancements.onSubmit(submitData);
2562
+ } finally {
2563
+ form.isSubmitting.value = false;
2564
+ }
2565
+ }
2566
+ }
2567
+ function reset(values) {
2568
+ form.reset(values);
2569
+ currentStep.value = 0;
2570
+ }
2571
+ function updateSchema(nextSchema, nextData) {
2572
+ currentSchema.value = nextSchema;
2573
+ const nextFields = flattenFields(nextSchema);
2574
+ replaceArray(fields, nextFields);
2575
+ replaceArray(sections, collectSections(nextSchema));
2576
+ replaceRecord(rules, buildRules(nextFields, enhancements));
2577
+ form.replaceState(buildInitialValues(nextFields, nextData));
2578
+ currentStep.value = 0;
2579
+ }
2580
+ if (enhancements?.onFieldChange) {
2581
+ const callback = enhancements.onFieldChange;
2582
+ watch(() => ({ ...form.data }), (newData, oldData) => {
2583
+ if (!oldData) return;
2584
+ for (const key of Object.keys(newData)) if (newData[key] !== oldData[key]) callback(key, newData[key], newData);
2585
+ }, { deep: true });
2586
+ }
2587
+ return {
2588
+ form,
2589
+ rules,
2590
+ isFieldVisible,
2591
+ isSectionVisible,
2592
+ fields,
2593
+ getResolvedFieldProps,
2594
+ getFieldOptions,
2595
+ currentStep,
2596
+ isCurrentStepValid,
2597
+ goNext,
2598
+ goBack,
2599
+ goToStep,
2600
+ validate,
2601
+ reset,
2602
+ submit,
2603
+ updateSchema
2604
+ };
2605
+ }
2606
+ //#endregion
2607
+ //#region src/utils/formModelSync.ts
2608
+ function recordValuesEqualForKeys(left, right, keys) {
2609
+ for (const key of keys) if (!valuesEqual(left[key], right[key])) return false;
2610
+ return true;
2611
+ }
2612
+ function pickRecordKeys(source, keys) {
2613
+ return Object.fromEntries(keys.map((key) => [key, source[key]]));
2614
+ }
2615
+ function pickExistingRecordKeys(source, keys) {
2616
+ return Object.fromEntries(keys.filter((key) => Object.prototype.hasOwnProperty.call(source, key)).map((key) => [key, source[key]]));
2617
+ }
2618
+ function formSchemaFieldNames(schema) {
2619
+ return (schema.steps ? schema.steps.flatMap((step) => step.sections) : schema.sections).flatMap((section) => section.fields.map((field) => field.name));
2620
+ }
2621
+ function valuesEqual(left, right) {
2622
+ if (Object.is(left, right)) return true;
2623
+ if (Array.isArray(left) && Array.isArray(right)) return left.length === right.length && left.every((item, index) => valuesEqual(item, right[index]));
2624
+ if (isRecord(left) && isRecord(right)) return recordValuesEqualForKeys(left, right, [.../* @__PURE__ */ new Set([...Object.keys(left), ...Object.keys(right)])]);
2625
+ return false;
2626
+ }
2627
+ //#endregion
2628
+ //#region src/components/internal/FormFieldRendererInternal.vue
2629
+ var FormFieldRendererInternal_default = /* @__PURE__ */ defineComponent({
2630
+ __name: "FormFieldRendererInternal",
2631
+ props: {
2632
+ field: {},
2633
+ resolvedProps: {},
2634
+ form: {}
2635
+ },
2636
+ setup(__props) {
2637
+ const props = __props;
2638
+ const entry = computed(() => getFieldRegistryEntry(props.field.type));
2639
+ const isChoiceField = computed(() => props.field.type === "checkbox" || props.field.type === "toggle");
2640
+ const componentProps = computed(() => {
2641
+ if (props.field.type === "multiselect") {
2642
+ const values = Array.isArray(props.resolvedProps.modelValue) ? props.resolvedProps.modelValue : [];
2643
+ return {
2644
+ ...props.resolvedProps,
2645
+ modelValue: values
2646
+ };
2647
+ }
2648
+ if (props.field.type === "tags") {
2649
+ const values = Array.isArray(props.resolvedProps.modelValue) ? props.resolvedProps.modelValue : [];
2650
+ const onUpdate = props.resolvedProps["onUpdate:modelValue"];
2651
+ return {
2652
+ ...props.resolvedProps,
2653
+ modelValue: values.map(String),
2654
+ "onUpdate:modelValue": (next) => onUpdate?.(props.field.itemType === "number" && Array.isArray(next) ? next.map(Number) : next)
2655
+ };
2656
+ }
2657
+ if (!isChoiceField.value) return props.resolvedProps;
2658
+ return {
2659
+ layout: "row",
2660
+ label: props.field.label,
2661
+ description: props.field.hint,
2662
+ icon: props.field.icon,
2663
+ iconColor: props.field.iconColor,
2664
+ iconBg: props.field.iconBg,
2665
+ ...props.resolvedProps
2666
+ };
2667
+ });
2668
+ const errorMessage = computed(() => {
2669
+ const name = props.field.name;
2670
+ return props.form.touched[name] ? props.form.errors[name] : null;
2671
+ });
2672
+ function handleUpload(files) {
2673
+ props.form.setFieldValue(props.field.name, files);
2674
+ }
2675
+ return (_ctx, _cache) => {
2676
+ return openBlock(), createBlock(FormField_default, {
2677
+ label: isChoiceField.value ? void 0 : __props.field.label,
2678
+ error: errorMessage.value ?? void 0,
2679
+ hint: isChoiceField.value ? void 0 : __props.field.hint,
2680
+ required: !!__props.field.validation?.required,
2681
+ "html-for": isChoiceField.value ? void 0 : __props.field.name
2682
+ }, {
2683
+ default: withCtx(() => [renderSlot(_ctx.$slots, `field:${__props.field.name}`, {
2684
+ field: __props.field,
2685
+ form: __props.form,
2686
+ fieldProps: __props.form.getFieldProps(__props.field.name)
2687
+ }, () => [entry.value.vModel ? (openBlock(), createBlock(resolveDynamicComponent(entry.value.component), normalizeProps(mergeProps({ key: 0 }, componentProps.value)), null, 16)) : (openBlock(), createBlock(resolveDynamicComponent(entry.value.component), mergeProps({ key: 1 }, componentProps.value, { onUpload: handleUpload }), null, 16))])]),
2688
+ _: 3
2689
+ }, 8, [
2690
+ "label",
2691
+ "error",
2692
+ "hint",
2693
+ "required",
2694
+ "html-for"
2695
+ ]);
2696
+ };
2697
+ }
2698
+ });
2699
+ //#endregion
2700
+ //#region src/components/internal/FormSectionRenderer.vue?vue&type=script&setup=true&lang.ts
2701
+ var _hoisted_1$3 = {
2702
+ key: 0,
2703
+ class: "mint-form-section"
2704
+ };
2705
+ var _hoisted_2$1 = {
2706
+ key: 1,
2707
+ class: "mint-form-section--static"
2708
+ };
2709
+ var _hoisted_3$1 = {
2710
+ key: 0,
2711
+ class: "mint-form-section__header"
2712
+ };
2713
+ var _hoisted_4$1 = {
2714
+ key: 0,
2715
+ class: "mint-form-section__title"
2716
+ };
2717
+ var _hoisted_5$1 = {
2718
+ key: 1,
2719
+ class: "mint-form-section__description"
2720
+ };
2721
+ //#endregion
2722
+ //#region src/components/internal/FormSectionRenderer.vue
2723
+ var FormSectionRenderer_default = /* @__PURE__ */ defineComponent({
2724
+ __name: "FormSectionRenderer",
2725
+ props: {
2726
+ section: {},
2727
+ builder: {}
2728
+ },
2729
+ setup(__props) {
2730
+ const props = __props;
2731
+ const visibleFields = computed(() => props.section.fields.filter((f) => props.builder.isFieldVisible(f.name)));
2732
+ const gridStyle = computed(() => ({ gridTemplateColumns: `repeat(${props.section.columns ?? 1}, 1fr)` }));
2733
+ return (_ctx, _cache) => {
2734
+ return visibleFields.value.length > 0 ? (openBlock(), createElementBlock("div", _hoisted_1$3, [renderSlot(_ctx.$slots, `section:${__props.section.id}`, {
2735
+ section: __props.section,
2736
+ form: __props.builder.form
2737
+ }, () => [__props.section.collapsible ? (openBlock(), createBlock(CollapsibleCard_default, {
2738
+ key: 0,
2739
+ title: __props.section.title,
2740
+ subtitle: __props.section.description,
2741
+ "default-open": __props.section.defaultOpen ?? true
2742
+ }, {
2743
+ default: withCtx(() => [createElementVNode("div", {
2744
+ class: "mint-form-section__grid",
2745
+ style: normalizeStyle(gridStyle.value)
2746
+ }, [(openBlock(true), createElementBlock(Fragment, null, renderList(visibleFields.value, (field) => {
2747
+ return openBlock(), createElementBlock("div", {
2748
+ key: field.name,
2749
+ style: normalizeStyle(field.colSpan ? { gridColumn: `span ${field.colSpan}` } : void 0)
2750
+ }, [renderSlot(_ctx.$slots, `field:${field.name}`, {
2751
+ field,
2752
+ form: __props.builder.form,
2753
+ fieldProps: __props.builder.form.getFieldProps(field.name)
2754
+ }, () => [createVNode(FormFieldRendererInternal_default, {
2755
+ field,
2756
+ "resolved-props": __props.builder.getResolvedFieldProps(field),
2757
+ form: __props.builder.form
2758
+ }, null, 8, [
2759
+ "field",
2760
+ "resolved-props",
2761
+ "form"
2762
+ ])])], 4);
2763
+ }), 128))], 4)]),
2764
+ _: 3
2765
+ }, 8, [
2766
+ "title",
2767
+ "subtitle",
2768
+ "default-open"
2769
+ ])) : (openBlock(), createElementBlock("div", _hoisted_2$1, [__props.section.title || __props.section.description ? (openBlock(), createElementBlock("div", _hoisted_3$1, [__props.section.title ? (openBlock(), createElementBlock("h3", _hoisted_4$1, toDisplayString(__props.section.title), 1)) : createCommentVNode("", true), __props.section.description ? (openBlock(), createElementBlock("p", _hoisted_5$1, toDisplayString(__props.section.description), 1)) : createCommentVNode("", true)])) : createCommentVNode("", true), createElementVNode("div", {
2770
+ class: "mint-form-section__grid",
2771
+ style: normalizeStyle(gridStyle.value)
2772
+ }, [(openBlock(true), createElementBlock(Fragment, null, renderList(visibleFields.value, (field) => {
2773
+ return openBlock(), createElementBlock("div", {
2774
+ key: field.name,
2775
+ style: normalizeStyle(field.colSpan ? { gridColumn: `span ${field.colSpan}` } : void 0)
2776
+ }, [renderSlot(_ctx.$slots, `field:${field.name}`, {
2777
+ field,
2778
+ form: __props.builder.form,
2779
+ fieldProps: __props.builder.form.getFieldProps(field.name)
2780
+ }, () => [createVNode(FormFieldRendererInternal_default, {
2781
+ field,
2782
+ "resolved-props": __props.builder.getResolvedFieldProps(field),
2783
+ form: __props.builder.form
2784
+ }, null, 8, [
2785
+ "field",
2786
+ "resolved-props",
2787
+ "form"
2788
+ ])])], 4);
2789
+ }), 128))], 4)]))]), renderSlot(_ctx.$slots, `section:${__props.section.id}:after`, { form: __props.builder.form })])) : createCommentVNode("", true);
2790
+ };
2791
+ }
2792
+ });
2793
+ //#endregion
2794
+ //#region src/components/internal/FormActionsInternal.vue?vue&type=script&setup=true&lang.ts
2795
+ var _hoisted_1$2 = { class: "mint-form-actions" };
2796
+ //#endregion
2797
+ //#region src/components/internal/FormActionsInternal.vue
2798
+ var FormActionsInternal_default = /* @__PURE__ */ defineComponent({
2799
+ __name: "FormActionsInternal",
2800
+ props: {
2801
+ isWizard: {
2802
+ type: Boolean,
2803
+ default: false
2804
+ },
2805
+ isFirst: {
2806
+ type: Boolean,
2807
+ default: true
2808
+ },
2809
+ isLast: {
2810
+ type: Boolean,
2811
+ default: true
2812
+ },
2813
+ canProceed: {
2814
+ type: Boolean,
2815
+ default: true
2816
+ },
2817
+ loading: {
2818
+ type: Boolean,
2819
+ default: false
2820
+ },
2821
+ disabled: {
2822
+ type: Boolean,
2823
+ default: false
2824
+ },
2825
+ submitLabel: { default: "Submit" },
2826
+ cancelLabel: { default: "Cancel" },
2827
+ showCancel: {
2828
+ type: Boolean,
2829
+ default: false
2830
+ }
2831
+ },
2832
+ emits: [
2833
+ "submit",
2834
+ "cancel",
2835
+ "back",
2836
+ "next"
2837
+ ],
2838
+ setup(__props, { emit: __emit }) {
2839
+ /**
2840
+ * Action bar rendered at the bottom of a FormBuilder (`actions` in the control model).
2841
+ *
2842
+ * Supports two modes:
2843
+ * - Flat form: shows an optional Cancel button and a Submit button.
2844
+ * - Wizard (`isWizard=true`): shows Back / Next on intermediate steps and
2845
+ * Submit only on the last step. Back is hidden on the first step.
2846
+ *
2847
+ * The `canProceed` prop gates the primary action (Next or Submit) to prevent
2848
+ * advancing when the current step has validation errors.
2849
+ */
2850
+ const emit = __emit;
2851
+ return (_ctx, _cache) => {
2852
+ return openBlock(), createElementBlock("div", _hoisted_1$2, [
2853
+ __props.showCancel ? (openBlock(), createBlock(BaseButton_default, {
2854
+ key: 0,
2855
+ variant: "ghost",
2856
+ disabled: __props.loading || __props.disabled,
2857
+ onClick: _cache[0] || (_cache[0] = ($event) => emit("cancel"))
2858
+ }, {
2859
+ default: withCtx(() => [createTextVNode(toDisplayString(__props.cancelLabel), 1)]),
2860
+ _: 1
2861
+ }, 8, ["disabled"])) : createCommentVNode("", true),
2862
+ _cache[6] || (_cache[6] = createElementVNode("div", { style: { "flex": "1" } }, null, -1)),
2863
+ __props.isWizard && !__props.isFirst ? (openBlock(), createBlock(BaseButton_default, {
2864
+ key: 1,
2865
+ variant: "secondary",
2866
+ disabled: __props.loading || __props.disabled,
2867
+ onClick: _cache[1] || (_cache[1] = ($event) => emit("back"))
2868
+ }, {
2869
+ default: withCtx(() => [..._cache[4] || (_cache[4] = [createTextVNode(" Back ", -1)])]),
2870
+ _: 1
2871
+ }, 8, ["disabled"])) : createCommentVNode("", true),
2872
+ __props.isWizard && !__props.isLast ? (openBlock(), createBlock(BaseButton_default, {
2873
+ key: 2,
2874
+ variant: "primary",
2875
+ disabled: !__props.canProceed || __props.loading || __props.disabled,
2876
+ onClick: _cache[2] || (_cache[2] = ($event) => emit("next"))
2877
+ }, {
2878
+ default: withCtx(() => [..._cache[5] || (_cache[5] = [createTextVNode(" Next ", -1)])]),
2879
+ _: 1
2880
+ }, 8, ["disabled"])) : createCommentVNode("", true),
2881
+ !__props.isWizard || __props.isLast ? (openBlock(), createBlock(BaseButton_default, {
2882
+ key: 3,
2883
+ variant: "primary",
2884
+ loading: __props.loading,
2885
+ disabled: !__props.canProceed || __props.loading || __props.disabled,
2886
+ onClick: _cache[3] || (_cache[3] = ($event) => emit("submit"))
2887
+ }, {
2888
+ default: withCtx(() => [createTextVNode(toDisplayString(__props.submitLabel), 1)]),
2889
+ _: 1
2890
+ }, 8, ["loading", "disabled"])) : createCommentVNode("", true)
2891
+ ]);
2892
+ };
2893
+ }
2894
+ });
2895
+ //#endregion
2896
+ //#region src/components/internal/FormSchemaInternal.vue?vue&type=script&setup=true&lang.ts
2897
+ var _hoisted_1$1 = { class: "mint-form-builder__step" };
2898
+ //#endregion
2899
+ //#region src/components/internal/FormSchemaInternal.vue
2900
+ var FormSchemaInternal_default = /* @__PURE__ */ defineComponent({
2901
+ __name: "FormSchemaInternal",
2902
+ props: {
2903
+ schema: {},
2904
+ defaults: { default: () => ({}) },
2905
+ modelValue: {},
2906
+ enhancements: {},
2907
+ loading: {
2908
+ type: Boolean,
2909
+ default: false
2910
+ },
2911
+ disabled: {
2912
+ type: Boolean,
2913
+ default: false
2914
+ },
2915
+ size: {},
2916
+ readonly: {
2917
+ type: Boolean,
2918
+ default: false
2919
+ }
2920
+ },
2921
+ emits: [
2922
+ "update:modelValue",
2923
+ "submit",
2924
+ "cancel"
2925
+ ],
2926
+ setup(__props, { expose: __expose, emit: __emit }) {
2927
+ /**
2928
+ * FormSchema renderer behind FormBuilder and the sidebar forms: flat sections
2929
+ * or a multi-step wizard, with the action bar when `schema.actions` is set.
2930
+ *
2931
+ * Slots:
2932
+ * - `field:<name>` — override a single field's input component
2933
+ * - `section:<id>` — replace an entire section body
2934
+ * - `section:<id>:after` — inject content after a section
2935
+ * - `actions` — replace the default action bar
2936
+ */
2937
+ const props = __props;
2938
+ const emit = __emit;
2939
+ const resolvedSchema = computed(() => props.schema);
2940
+ const resolvedModelValue = computed(() => ({
2941
+ ...props.defaults,
2942
+ ...props.modelValue ?? {}
2943
+ }));
2944
+ const builder = useFormBuilder(resolvedSchema.value, resolvedModelValue.value, props.enhancements);
2945
+ watch(resolvedSchema, (schema) => {
2946
+ const fieldNames = formSchemaFieldNames(schema);
2947
+ const schemaValues = pickExistingRecordKeys(resolvedModelValue.value, fieldNames);
2948
+ const existingValues = pickExistingRecordKeys(builder.form.data, fieldNames);
2949
+ const nextValues = props.modelValue === void 0 ? {
2950
+ ...schemaValues,
2951
+ ...existingValues
2952
+ } : schemaValues;
2953
+ builder.updateSchema(schema, nextValues);
2954
+ }, { deep: true });
2955
+ watch(() => props.modelValue, () => {
2956
+ const data = resolvedModelValue.value;
2957
+ const fieldNames = builderFieldNames();
2958
+ if (recordValuesEqualForKeys(data, builder.form.data, fieldNames)) return;
2959
+ builder.reset(pickExistingRecordKeys(data, fieldNames));
2960
+ }, { deep: true });
2961
+ watch(() => ({ ...builder.form.data }), (data) => emit("update:modelValue", data), { deep: true });
2962
+ const isWizard = computed(() => !!resolvedSchema.value.steps);
2963
+ const wizardRef = ref(null);
2964
+ const wizardSteps = computed(() => {
2965
+ if (!resolvedSchema.value.steps) return [];
2966
+ return resolvedSchema.value.steps.map((step) => ({
2967
+ id: step.id,
2968
+ label: step.label,
2969
+ description: step.description,
2970
+ icon: step.icon,
2971
+ optional: step.optional
2972
+ }));
2973
+ });
2974
+ watch(() => builder.isCurrentStepValid.value, (valid) => {
2975
+ wizardRef.value?.setStepValid(builder.currentStep.value, valid);
2976
+ });
2977
+ function handleNext() {
2978
+ if (builder.goNext()) wizardRef.value?.setStepValid(builder.currentStep.value - 1, true);
2979
+ }
2980
+ async function handleSubmit() {
2981
+ await builder.submit();
2982
+ const formData = builder.form.data;
2983
+ const visibleData = Object.fromEntries(builder.fields.filter((f) => builder.isFieldVisible(f.name)).map((f) => [f.name, formData[f.name]]));
2984
+ emit("submit", visibleData);
2985
+ }
2986
+ function handleCancel() {
2987
+ emit("cancel");
2988
+ }
2989
+ function builderFieldNames() {
2990
+ return builder.fields.map((field) => field.name);
2991
+ }
2992
+ __expose({
2993
+ form: builder.form,
2994
+ validate: builder.validate,
2995
+ reset: builder.reset,
2996
+ updateSchema: builder.updateSchema,
2997
+ goNext: builder.goNext,
2998
+ goBack: builder.goBack,
2999
+ goToStep: builder.goToStep,
3000
+ builder
3001
+ });
3002
+ return (_ctx, _cache) => {
3003
+ return openBlock(), createElementBlock("div", { class: normalizeClass(["mint-form-builder", __props.size ? `mint-form-builder--${__props.size}` : ""]) }, [isWizard.value && resolvedSchema.value.steps ? (openBlock(), createBlock(StepWizard_default, {
3004
+ key: 0,
3005
+ ref_key: "wizardRef",
3006
+ ref: wizardRef,
3007
+ steps: wizardSteps.value,
3008
+ "model-value": unref(builder).currentStep.value,
3009
+ "onUpdate:modelValue": _cache[0] || (_cache[0] = ($event) => unref(builder).goToStep($event))
3010
+ }, createSlots({ _: 2 }, [renderList(resolvedSchema.value.steps, (step) => {
3011
+ return {
3012
+ name: `step-${step.id}`,
3013
+ fn: withCtx(() => [createElementVNode("div", _hoisted_1$1, [(openBlock(true), createElementBlock(Fragment, null, renderList(step.sections, (section) => {
3014
+ return openBlock(), createElementBlock(Fragment, { key: section.id }, [unref(builder).isSectionVisible(section.id) ? (openBlock(), createBlock(FormSectionRenderer_default, {
3015
+ key: 0,
3016
+ section,
3017
+ builder: unref(builder)
3018
+ }, createSlots({
3019
+ [`section:${section.id}`]: withCtx((slotProps) => [renderSlot(_ctx.$slots, `section:${section.id}`, mergeProps({ ref_for: true }, slotProps))]),
3020
+ [`section:${section.id}:after`]: withCtx((slotProps) => [renderSlot(_ctx.$slots, `section:${section.id}:after`, mergeProps({ ref_for: true }, slotProps))]),
3021
+ _: 2
3022
+ }, [renderList(section.fields, (field) => {
3023
+ return {
3024
+ name: `field:${field.name}`,
3025
+ fn: withCtx((slotProps) => [renderSlot(_ctx.$slots, `field:${field.name}`, mergeProps({ ref_for: true }, slotProps))])
3026
+ };
3027
+ })]), 1032, ["section", "builder"])) : createCommentVNode("", true)], 64);
3028
+ }), 128))])])
3029
+ };
3030
+ }), resolvedSchema.value.actions ? {
3031
+ name: "navigation",
3032
+ fn: withCtx(({ isFirst, isLast }) => [renderSlot(_ctx.$slots, "actions", {
3033
+ form: unref(builder).form,
3034
+ builder: unref(builder)
3035
+ }, () => [createVNode(FormActionsInternal_default, {
3036
+ "is-wizard": "",
3037
+ "is-first": isFirst,
3038
+ "is-last": isLast,
3039
+ "can-proceed": unref(builder).isCurrentStepValid.value,
3040
+ loading: __props.loading || unref(builder).form.isSubmitting.value,
3041
+ disabled: __props.disabled,
3042
+ "submit-label": resolvedSchema.value.submitLabel ?? "Submit",
3043
+ "cancel-label": resolvedSchema.value.cancelLabel ?? "Cancel",
3044
+ "show-cancel": resolvedSchema.value.showCancel ?? false,
3045
+ onNext: handleNext,
3046
+ onBack: unref(builder).goBack,
3047
+ onSubmit: handleSubmit,
3048
+ onCancel: handleCancel
3049
+ }, null, 8, [
3050
+ "is-first",
3051
+ "is-last",
3052
+ "can-proceed",
3053
+ "loading",
3054
+ "disabled",
3055
+ "submit-label",
3056
+ "cancel-label",
3057
+ "show-cancel",
3058
+ "onBack"
3059
+ ])])]),
3060
+ key: "0"
3061
+ } : void 0]), 1032, ["steps", "model-value"])) : resolvedSchema.value.sections ? (openBlock(), createElementBlock(Fragment, { key: 1 }, [(openBlock(true), createElementBlock(Fragment, null, renderList(resolvedSchema.value.sections, (section) => {
3062
+ return openBlock(), createElementBlock(Fragment, { key: section.id }, [unref(builder).isSectionVisible(section.id) ? (openBlock(), createBlock(FormSectionRenderer_default, {
3063
+ key: 0,
3064
+ section,
3065
+ builder: unref(builder)
3066
+ }, createSlots({
3067
+ [`section:${section.id}`]: withCtx((slotProps) => [renderSlot(_ctx.$slots, `section:${section.id}`, mergeProps({ ref_for: true }, slotProps))]),
3068
+ [`section:${section.id}:after`]: withCtx((slotProps) => [renderSlot(_ctx.$slots, `section:${section.id}:after`, mergeProps({ ref_for: true }, slotProps))]),
3069
+ _: 2
3070
+ }, [renderList(section.fields, (field) => {
3071
+ return {
3072
+ name: `field:${field.name}`,
3073
+ fn: withCtx((slotProps) => [renderSlot(_ctx.$slots, `field:${field.name}`, mergeProps({ ref_for: true }, slotProps))])
3074
+ };
3075
+ })]), 1032, ["section", "builder"])) : createCommentVNode("", true)], 64);
3076
+ }), 128)), resolvedSchema.value.actions ? renderSlot(_ctx.$slots, "actions", {
3077
+ form: unref(builder).form,
3078
+ builder: unref(builder)
3079
+ }, () => [createVNode(FormActionsInternal_default, {
3080
+ loading: __props.loading || unref(builder).form.isSubmitting.value,
3081
+ disabled: __props.disabled,
3082
+ "submit-label": resolvedSchema.value.submitLabel ?? "Submit",
3083
+ "cancel-label": resolvedSchema.value.cancelLabel ?? "Cancel",
3084
+ "show-cancel": resolvedSchema.value.showCancel ?? false,
3085
+ onSubmit: handleSubmit,
3086
+ onCancel: handleCancel
3087
+ }, null, 8, [
3088
+ "loading",
3089
+ "disabled",
3090
+ "submit-label",
3091
+ "cancel-label",
3092
+ "show-cancel"
3093
+ ])], void 0, 0) : createCommentVNode("", true)], 64)) : createCommentVNode("", true)], 2);
3094
+ };
3095
+ }
3096
+ });
3097
+ //#endregion
3098
+ //#region src/components/AppSidebar.vue?vue&type=script&setup=true&lang.ts
3099
+ var _hoisted_1 = {
3100
+ key: 0,
3101
+ class: "mint-sidebar__header"
3102
+ };
3103
+ var _hoisted_2 = {
3104
+ key: 0,
3105
+ class: "mint-sidebar__heading"
3106
+ };
3107
+ var _hoisted_3 = { class: "mint-sidebar__heading-copy" };
3108
+ var _hoisted_4 = {
3109
+ key: 0,
3110
+ class: "mint-sidebar__title"
3111
+ };
3112
+ var _hoisted_5 = {
3113
+ key: 1,
3114
+ class: "mint-sidebar__subtitle"
3115
+ };
3116
+ var _hoisted_6 = {
3117
+ key: 0,
3118
+ class: "mint-sidebar__badge"
3119
+ };
3120
+ var _hoisted_7 = ["aria-label", "aria-expanded"];
3121
+ var _hoisted_8 = ["id"];
3122
+ var _hoisted_9 = { class: "mint-sidebar__group-head" };
3123
+ var _hoisted_10 = ["aria-expanded", "onClick"];
3124
+ var _hoisted_11 = {
3125
+ key: 0,
3126
+ class: "mint-sidebar__group-svg",
3127
+ viewBox: "0 0 24 24",
3128
+ fill: "none",
3129
+ stroke: "currentColor",
3130
+ "stroke-width": "2",
3131
+ "stroke-linecap": "round",
3132
+ "stroke-linejoin": "round",
3133
+ "aria-hidden": "true"
3134
+ };
3135
+ var _hoisted_12 = ["d"];
3136
+ var _hoisted_13 = ["d"];
3137
+ var _hoisted_14 = {
3138
+ key: 1,
3139
+ class: "mint-sidebar__group-text-icon"
3140
+ };
3141
+ var _hoisted_15 = { class: "mint-sidebar__group-copy" };
3142
+ var _hoisted_16 = { class: "mint-sidebar__group-label" };
3143
+ var _hoisted_17 = {
3144
+ key: 0,
3145
+ class: "mint-sidebar__group-subtitle"
3146
+ };
3147
+ var _hoisted_18 = { class: "mint-sidebar__group-tail" };
3148
+ var _hoisted_19 = [
3149
+ "disabled",
3150
+ "aria-label",
3151
+ "title",
3152
+ "onClick"
3153
+ ];
3154
+ var _hoisted_20 = {
3155
+ key: 0,
3156
+ class: "mint-sidebar__group-action-icon",
3157
+ viewBox: "0 0 24 24",
3158
+ fill: "none",
3159
+ stroke: "currentColor",
3160
+ "stroke-width": "2",
3161
+ "stroke-linecap": "round",
3162
+ "stroke-linejoin": "round",
3163
+ "aria-hidden": "true"
3164
+ };
3165
+ var _hoisted_21 = ["d"];
3166
+ var _hoisted_22 = ["d"];
3167
+ var _hoisted_23 = { key: 1 };
3168
+ var _hoisted_24 = [
3169
+ "aria-checked",
3170
+ "aria-label",
3171
+ "onClick"
3172
+ ];
3173
+ var _hoisted_25 = [
3174
+ "aria-label",
3175
+ "aria-expanded",
3176
+ "onClick"
3177
+ ];
3178
+ var _hoisted_26 = { class: "mint-sidebar__group-body" };
3179
+ var _hoisted_27 = {
3180
+ key: 2,
3181
+ class: "mint-sidebar__collapsed"
3182
+ };
3183
+ var _hoisted_28 = {
3184
+ key: 3,
3185
+ class: "mint-sidebar__collapsed mint-sidebar__collapsed--default"
3186
+ };
3187
+ var _hoisted_29 = ["aria-label", "title"];
3188
+ var _hoisted_30 = {
3189
+ key: 0,
3190
+ class: "mint-sidebar__rail-svg",
3191
+ viewBox: "0 0 24 24",
3192
+ fill: "none",
3193
+ stroke: "currentColor",
3194
+ "stroke-width": "2",
3195
+ "stroke-linecap": "round",
3196
+ "stroke-linejoin": "round",
3197
+ "aria-hidden": "true"
3198
+ };
3199
+ var _hoisted_31 = ["d"];
3200
+ var _hoisted_32 = ["d"];
3201
+ var _hoisted_33 = {
3202
+ key: 1,
3203
+ class: "mint-sidebar__rail-text-icon"
3204
+ };
3205
+ var _hoisted_34 = {
3206
+ key: 4,
3207
+ class: "mint-sidebar__footer"
3208
+ };
3209
+ var _hoisted_35 = {
3210
+ key: 5,
3211
+ class: "mint-sidebar__footer mint-sidebar__footer--collapsed"
3212
+ };
3213
+ //#endregion
3214
+ //#region src/components/AppSidebar.vue
3215
+ var AppSidebar_default = /* @__PURE__ */ defineComponent({
3216
+ __name: "AppSidebar",
3217
+ props: {
3218
+ spec: { default: () => ({}) },
3219
+ activeView: { default: "" },
3220
+ values: { default: () => ({}) },
3221
+ collapsed: {
3222
+ type: Boolean,
3223
+ default: void 0
3224
+ },
3225
+ toggleState: { default: () => ({}) },
3226
+ formLoading: {
3227
+ type: Boolean,
3228
+ default: false
3229
+ },
3230
+ formDisabled: {
3231
+ type: Boolean,
3232
+ default: false
3233
+ },
3234
+ formReadonly: {
3235
+ type: Boolean,
3236
+ default: false
3237
+ }
3238
+ },
3239
+ emits: [
3240
+ "update:toggle",
3241
+ "update:values",
3242
+ "update:collapsed",
3243
+ "section-action",
3244
+ "form-submit",
3245
+ "form-cancel"
3246
+ ],
3247
+ setup(__props, { emit: __emit }) {
3248
+ /**
3249
+ * AppSidebar - Context-sensitive toolkit panel
3250
+ *
3251
+ * Shows tool sections relevant to the active view. Sections come from the
3252
+ * spec: a `controls` model built with `defineControlModel()` generates them,
3253
+ * and hand-written `panels` are merged over the generated ones. Each section
3254
+ * renders as a flat group (header row + hairline, no nested card). Controls
3255
+ * can be provided through named slots or auto-rendered from the section forms.
3256
+ *
3257
+ * When activeView is omitted, the first non-empty panel view is selected.
3258
+ * When no view has matching panels, the sidebar hides entirely.
3259
+ *
3260
+ * @example Recommended
3261
+ * ```vue
3262
+ * <AppSidebar v-model:values="values" :spec="{ title: 'Parameters', controls: sidebarModel }" />
3263
+ * ```
3264
+ */
3265
+ const props = __props;
3266
+ const config = computed(() => applySpecDefaults({
3267
+ panels: {},
3268
+ forms: {},
3269
+ floating: true,
3270
+ dense: true,
3271
+ width: "280px",
3272
+ position: "left",
3273
+ whenEmpty: false,
3274
+ formSize: "sm",
3275
+ collapsible: false,
3276
+ collapsedWidth: "3rem",
3277
+ collapseButtonLabel: "Collapse sidebar",
3278
+ expandButtonLabel: "Expand sidebar"
3279
+ }, props.spec));
3280
+ const emit = __emit;
3281
+ const slots = useSlots();
3282
+ const internalCollapsed = ref(false);
3283
+ const collapsedModel = computed({
3284
+ get: () => props.collapsed ?? internalCollapsed.value,
3285
+ set: (value) => {
3286
+ internalCollapsed.value = value;
3287
+ emit("update:collapsed", value);
3288
+ }
3289
+ });
3290
+ const openState = ref({});
3291
+ function isSectionOpen(section) {
3292
+ return openState.value[section.id] ?? section.defaultOpen !== false;
3293
+ }
3294
+ function toggleSection(section) {
3295
+ openState.value[section.id] = !isSectionOpen(section);
3296
+ }
3297
+ const controlModel = computed(() => config.value.controls);
3298
+ const generatedPanels = computed(() => {
3299
+ const model = controlModel.value;
3300
+ return model ? controlsToSidebarPanels(model.controls, model.controlOptions) : {};
3301
+ });
3302
+ const generatedForms = computed(() => {
3303
+ const model = controlModel.value;
3304
+ return model ? controlsToSectionFormSchemas(model.controls, model.controlOptions) : {};
3305
+ });
3306
+ const generatedDefaults = computed(() => {
3307
+ const model = controlModel.value;
3308
+ if (!model) return {};
3309
+ return {
3310
+ ...getControlDefaults(model.controls),
3311
+ ...model.controlOptions.initialValues ?? {}
3312
+ };
3313
+ });
3314
+ const resolvedPanels = computed(() => mergeSidebarPanels(generatedPanels.value, config.value.panels));
3315
+ const resolvedForms = computed(() => ({
3316
+ ...generatedForms.value,
3317
+ ...config.value.forms
3318
+ }));
3319
+ const resolvedValues = computed(() => ({
3320
+ ...generatedDefaults.value,
3321
+ ...props.values
3322
+ }));
3323
+ const resolvedActiveView = computed(() => {
3324
+ if (props.activeView) return props.activeView;
3325
+ return firstVisibleViewId(resolvedPanels.value);
3326
+ });
3327
+ const activeSections = computed(() => {
3328
+ if (!resolvedActiveView.value || !resolvedPanels.value[resolvedActiveView.value]) return [];
3329
+ return resolvedPanels.value[resolvedActiveView.value];
3330
+ });
3331
+ const isVisible = computed(() => activeSections.value.length > 0 || config.value.whenEmpty || Boolean(slots.default));
3332
+ const sidebarClasses = computed(() => [
3333
+ "mint-sidebar",
3334
+ `mint-sidebar--${config.value.position}`,
3335
+ config.value.floating ? "mint-sidebar--floating" : "mint-sidebar--static",
3336
+ config.value.dense ? "" : "mint-sidebar--comfortable",
3337
+ config.value.collapsible ? "mint-sidebar--collapsible" : "",
3338
+ collapsedModel.value ? "mint-sidebar--collapsed" : "",
3339
+ !isVisible.value ? "mint-sidebar--hidden" : ""
3340
+ ]);
3341
+ const sidebarStyle = computed(() => ({ width: collapsedModel.value ? config.value.collapsedWidth : config.value.width }));
3342
+ function handleFormUpdate(values) {
3343
+ emit("update:values", {
3344
+ ...resolvedValues.value,
3345
+ ...values
3346
+ });
3347
+ }
3348
+ function handleFormSubmit(sectionId, values) {
3349
+ emit("form-submit", sectionId, values);
3350
+ }
3351
+ function handleFormCancel(sectionId) {
3352
+ emit("form-cancel", sectionId);
3353
+ }
3354
+ function toggleCollapsed() {
3355
+ collapsedModel.value = !collapsedModel.value;
3356
+ }
3357
+ function expandCollapsed() {
3358
+ collapsedModel.value = false;
3359
+ }
3360
+ function handleSectionAction(sectionId, actionId) {
3361
+ emit("section-action", sectionId, actionId);
3362
+ }
3363
+ function isSvgIcon(icon) {
3364
+ if (!icon) return false;
3365
+ return Array.isArray(icon) || icon.startsWith("M") || icon.startsWith("m");
3366
+ }
3367
+ function sectionInitial(section) {
3368
+ return section.label.trim().charAt(0).toUpperCase() || "?";
3369
+ }
3370
+ function railIconStyle(section) {
3371
+ return {
3372
+ backgroundColor: section.iconBg ?? "var(--color-primary-soft)",
3373
+ color: section.iconColor ?? "var(--color-primary)"
3374
+ };
3375
+ }
3376
+ function badgeToneClass(section) {
3377
+ return `mint-sidebar__rail-badge--${section.badgeTone ?? "cta"}`;
3378
+ }
3379
+ function tagToneClass(section) {
3380
+ return `mint-sidebar__tag--${section.badgeTone ?? "cta"}`;
3381
+ }
3382
+ function actionClasses(action) {
3383
+ return ["mint-sidebar__group-action", action.tone ? `mint-sidebar__group-action--${action.tone}` : ""];
3384
+ }
3385
+ function mergeSidebarPanels(generated, explicit) {
3386
+ const merged = {};
3387
+ const viewIds = /* @__PURE__ */ new Set([...Object.keys(generated), ...Object.keys(explicit)]);
3388
+ for (const viewId of viewIds) {
3389
+ const sectionsById = /* @__PURE__ */ new Map();
3390
+ for (const section of generated[viewId] ?? []) sectionsById.set(section.id, section);
3391
+ for (const section of explicit[viewId] ?? []) sectionsById.set(section.id, section);
3392
+ merged[viewId] = [...sectionsById.values()];
3393
+ }
3394
+ return merged;
3395
+ }
3396
+ function firstVisibleViewId(panels) {
3397
+ for (const [viewId, sections] of Object.entries(panels)) if (sections.length > 0) return viewId;
3398
+ return "";
3399
+ }
3400
+ return (_ctx, _cache) => {
3401
+ return openBlock(), createElementBlock("aside", {
3402
+ class: normalizeClass(sidebarClasses.value),
3403
+ style: normalizeStyle(sidebarStyle.value)
3404
+ }, [
3405
+ _ctx.$slots.header || config.value.title || config.value.subtitle || config.value.badge !== void 0 || config.value.collapsible ? (openBlock(), createElementBlock("div", _hoisted_1, [renderSlot(_ctx.$slots, "header", {
3406
+ collapsed: collapsedModel.value,
3407
+ toggleCollapsed
3408
+ }, () => [!collapsedModel.value ? (openBlock(), createElementBlock("div", _hoisted_2, [createElementVNode("div", _hoisted_3, [config.value.title ? (openBlock(), createElementBlock("h2", _hoisted_4, toDisplayString(config.value.title), 1)) : createCommentVNode("", true), config.value.subtitle ? (openBlock(), createElementBlock("p", _hoisted_5, toDisplayString(config.value.subtitle), 1)) : createCommentVNode("", true)]), config.value.badge !== void 0 ? (openBlock(), createElementBlock("span", _hoisted_6, toDisplayString(config.value.badge), 1)) : createCommentVNode("", true)])) : createCommentVNode("", true), config.value.collapsible ? (openBlock(), createElementBlock("button", {
3409
+ key: 1,
3410
+ type: "button",
3411
+ class: "mint-sidebar__collapse-button",
3412
+ "aria-label": collapsedModel.value ? config.value.expandButtonLabel : config.value.collapseButtonLabel,
3413
+ "aria-expanded": !collapsedModel.value,
3414
+ onClick: toggleCollapsed
3415
+ }, [(openBlock(), createElementBlock("svg", {
3416
+ class: normalizeClass(["mint-sidebar__collapse-icon", { "mint-sidebar__collapse-icon--collapsed": collapsedModel.value }]),
3417
+ viewBox: "0 0 24 24",
3418
+ fill: "none",
3419
+ stroke: "currentColor",
3420
+ "stroke-width": "2",
3421
+ "stroke-linecap": "round",
3422
+ "stroke-linejoin": "round",
3423
+ "aria-hidden": "true"
3424
+ }, [..._cache[0] || (_cache[0] = [createElementVNode("path", { d: "M11 19l-7-7 7-7m8 14l-7-7 7-7" }, null, -1)])], 2))], 8, _hoisted_7)) : createCommentVNode("", true)])])) : createCommentVNode("", true),
3425
+ !collapsedModel.value ? (openBlock(), createElementBlock("div", {
3426
+ key: 1,
3427
+ id: config.value.contentId,
3428
+ class: "mint-sidebar__sections"
3429
+ }, [(openBlock(true), createElementBlock(Fragment, null, renderList(activeSections.value, (section) => {
3430
+ return openBlock(), createElementBlock("div", {
3431
+ key: section.id,
3432
+ class: normalizeClass(["mint-sidebar__group", isSectionOpen(section) ? "mint-sidebar__group--open" : "mint-sidebar__group--closed"])
3433
+ }, [createElementVNode("div", _hoisted_9, [createElementVNode("button", {
3434
+ type: "button",
3435
+ class: "mint-sidebar__group-toggle",
3436
+ "aria-expanded": isSectionOpen(section),
3437
+ onClick: ($event) => toggleSection(section)
3438
+ }, [section.icon ? (openBlock(), createElementBlock("span", {
3439
+ key: 0,
3440
+ class: "mint-sidebar__group-icon",
3441
+ style: normalizeStyle(railIconStyle(section))
3442
+ }, [isSvgIcon(section.icon) ? (openBlock(), createElementBlock("svg", _hoisted_11, [Array.isArray(section.icon) ? (openBlock(true), createElementBlock(Fragment, { key: 0 }, renderList(section.icon, (d, i) => {
3443
+ return openBlock(), createElementBlock("path", {
3444
+ key: i,
3445
+ d
3446
+ }, null, 8, _hoisted_12);
3447
+ }), 128)) : (openBlock(), createElementBlock("path", {
3448
+ key: 1,
3449
+ d: section.icon
3450
+ }, null, 8, _hoisted_13))])) : (openBlock(), createElementBlock("span", _hoisted_14, toDisplayString(section.icon), 1))], 4)) : createCommentVNode("", true), createElementVNode("span", _hoisted_15, [createElementVNode("span", _hoisted_16, toDisplayString(section.label), 1), section.subtitle ? (openBlock(), createElementBlock("span", _hoisted_17, toDisplayString(section.subtitle), 1)) : createCommentVNode("", true)])], 8, _hoisted_10), createElementVNode("div", _hoisted_18, [
3451
+ section.badge !== void 0 ? (openBlock(), createElementBlock("span", {
3452
+ key: 0,
3453
+ class: normalizeClass(["mint-sidebar__tag", tagToneClass(section)])
3454
+ }, toDisplayString(section.badge), 3)) : createCommentVNode("", true),
3455
+ (openBlock(true), createElementBlock(Fragment, null, renderList(section.actions ?? [], (action) => {
3456
+ return openBlock(), createElementBlock("button", {
3457
+ key: action.id,
3458
+ type: "button",
3459
+ class: normalizeClass(actionClasses(action)),
3460
+ style: normalizeStyle(action.iconColor ? { color: action.iconColor } : void 0),
3461
+ disabled: action.disabled,
3462
+ "aria-label": action.label,
3463
+ title: action.label,
3464
+ onClick: ($event) => handleSectionAction(section.id, action.id)
3465
+ }, [action.icon && isSvgIcon(action.icon) ? (openBlock(), createElementBlock("svg", _hoisted_20, [Array.isArray(action.icon) ? (openBlock(true), createElementBlock(Fragment, { key: 0 }, renderList(action.icon, (d, i) => {
3466
+ return openBlock(), createElementBlock("path", {
3467
+ key: i,
3468
+ d
3469
+ }, null, 8, _hoisted_21);
3470
+ }), 128)) : (openBlock(), createElementBlock("path", {
3471
+ key: 1,
3472
+ d: action.icon
3473
+ }, null, 8, _hoisted_22))])) : action.icon ? (openBlock(), createElementBlock("span", _hoisted_23, toDisplayString(action.icon), 1)) : createCommentVNode("", true)], 14, _hoisted_19);
3474
+ }), 128)),
3475
+ section.showToggle ? (openBlock(), createElementBlock("button", {
3476
+ key: 1,
3477
+ type: "button",
3478
+ role: "switch",
3479
+ "aria-checked": __props.toggleState[section.id] ?? false,
3480
+ "aria-label": `Enable ${section.label}`,
3481
+ class: normalizeClass(["mint-sidebar__switch", __props.toggleState[section.id] ?? false ? "mint-sidebar__switch--on" : ""]),
3482
+ onClick: ($event) => emit("update:toggle", section.id, !(__props.toggleState[section.id] ?? false))
3483
+ }, [..._cache[1] || (_cache[1] = [createElementVNode("span", { class: "mint-sidebar__switch-knob" }, null, -1)])], 10, _hoisted_24)) : createCommentVNode("", true),
3484
+ createElementVNode("button", {
3485
+ type: "button",
3486
+ class: "mint-sidebar__chevron-button",
3487
+ "aria-label": isSectionOpen(section) ? "Collapse section" : "Expand section",
3488
+ "aria-expanded": isSectionOpen(section),
3489
+ onClick: ($event) => toggleSection(section)
3490
+ }, [(openBlock(), createElementBlock("svg", {
3491
+ class: normalizeClass(["mint-sidebar__chevron", isSectionOpen(section) ? "mint-sidebar__chevron--open" : ""]),
3492
+ viewBox: "0 0 24 24",
3493
+ fill: "none",
3494
+ stroke: "currentColor",
3495
+ "stroke-width": "2",
3496
+ "stroke-linecap": "round",
3497
+ "stroke-linejoin": "round",
3498
+ "aria-hidden": "true"
3499
+ }, [..._cache[2] || (_cache[2] = [createElementVNode("path", { d: "m6 9 6 6 6-6" }, null, -1)])], 2))], 8, _hoisted_25)
3500
+ ])]), createVNode(Transition, { name: "collapse" }, {
3501
+ default: withCtx(() => [withDirectives(createElementVNode("div", _hoisted_26, [renderSlot(_ctx.$slots, `section-${section.id}`, {}, () => [resolvedForms.value[section.id] ? (openBlock(), createBlock(FormSchemaInternal_default, {
3502
+ key: 0,
3503
+ "model-value": resolvedValues.value,
3504
+ schema: resolvedForms.value[section.id],
3505
+ enhancements: config.value.controls?.controlOptions.enhancements,
3506
+ loading: __props.formLoading,
3507
+ disabled: __props.formDisabled,
3508
+ readonly: __props.formReadonly,
3509
+ size: config.value.formSize,
3510
+ "onUpdate:modelValue": handleFormUpdate,
3511
+ onSubmit: ($event) => handleFormSubmit(section.id, $event),
3512
+ onCancel: ($event) => handleFormCancel(section.id)
3513
+ }, null, 8, [
3514
+ "model-value",
3515
+ "schema",
3516
+ "enhancements",
3517
+ "loading",
3518
+ "disabled",
3519
+ "readonly",
3520
+ "size",
3521
+ "onSubmit",
3522
+ "onCancel"
3523
+ ])) : createCommentVNode("", true)])], 512), [[vShow, isSectionOpen(section)]])]),
3524
+ _: 2
3525
+ }, 1024)], 2);
3526
+ }), 128)), renderSlot(_ctx.$slots, "default", {
3527
+ sections: activeSections.value,
3528
+ activeView: resolvedActiveView.value,
3529
+ values: resolvedValues.value
3530
+ })], 8, _hoisted_8)) : _ctx.$slots.collapsed ? (openBlock(), createElementBlock("div", _hoisted_27, [renderSlot(_ctx.$slots, "collapsed", {
3531
+ sections: activeSections.value,
3532
+ expand: expandCollapsed
3533
+ })])) : (openBlock(), createElementBlock("div", _hoisted_28, [(openBlock(true), createElementBlock(Fragment, null, renderList(activeSections.value, (section) => {
3534
+ return openBlock(), createElementBlock("button", {
3535
+ key: section.id,
3536
+ type: "button",
3537
+ class: "mint-sidebar__rail-item",
3538
+ "aria-label": `Expand ${section.label}`,
3539
+ title: section.label,
3540
+ onClick: expandCollapsed
3541
+ }, [createElementVNode("span", {
3542
+ class: "mint-sidebar__rail-icon",
3543
+ style: normalizeStyle(railIconStyle(section))
3544
+ }, [section.icon && isSvgIcon(section.icon) ? (openBlock(), createElementBlock("svg", _hoisted_30, [Array.isArray(section.icon) ? (openBlock(true), createElementBlock(Fragment, { key: 0 }, renderList(section.icon, (d, i) => {
3545
+ return openBlock(), createElementBlock("path", {
3546
+ key: i,
3547
+ d
3548
+ }, null, 8, _hoisted_31);
3549
+ }), 128)) : (openBlock(), createElementBlock("path", {
3550
+ key: 1,
3551
+ d: section.icon
3552
+ }, null, 8, _hoisted_32))])) : (openBlock(), createElementBlock("span", _hoisted_33, toDisplayString(section.icon || sectionInitial(section)), 1))], 4), section.badge !== void 0 ? (openBlock(), createElementBlock("span", {
3553
+ key: 0,
3554
+ class: normalizeClass(["mint-sidebar__rail-badge", badgeToneClass(section)])
3555
+ }, toDisplayString(section.badge), 3)) : createCommentVNode("", true)], 8, _hoisted_29);
3556
+ }), 128))])),
3557
+ !collapsedModel.value && _ctx.$slots.footer ? (openBlock(), createElementBlock("div", _hoisted_34, [renderSlot(_ctx.$slots, "footer")])) : collapsedModel.value && _ctx.$slots["collapsed-footer"] ? (openBlock(), createElementBlock("div", _hoisted_35, [renderSlot(_ctx.$slots, "collapsed-footer")])) : createCommentVNode("", true)
3558
+ ], 6);
3559
+ };
3560
+ }
3561
+ });
3562
+ //#endregion
3563
+ export { getDefaultControlView as A, controlBindings as C, controlsTo as D, controlValuesToComponentProps as E, ThemeToggle_default as M, useTheme as N, controlsToFormSchema as O, useControlSchema as S, controlValuesToComponentBindingsById as T, AppLayout_default as _, pickExistingRecordKeys as a, defineControls as b, valuesEqual as c, useForm as d, AppTopBar_default as f, normalizeLabelItemInput as g, normalizeItemInput as h, formSchemaFieldNames as i, CollapsibleCard_default as j, controlsToSettingsSchema as k, useFormBuilder as l, PluginIcon_default as m, FormSchemaInternal_default as n, pickRecordKeys as o, providePluginIdentity as p, FormFieldRendererInternal_default as r, recordValuesEqualForKeys as s, AppSidebar_default as t, evaluateCondition as u, usePluginWorkspace as v, controlValuesToComponentBindings as w, getControlDefaults as x, defineControlComponentBindings as y };
3564
+
3565
+ //# sourceMappingURL=AppSidebar-mvm--GxN.js.map