@morscherlab/mint-sdk 1.3.8 → 1.4.0-beta.1

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 (966) hide show
  1. package/README.md +152 -177
  2. package/dist/ActionMenu-CScINahU.js +445 -0
  3. package/dist/ActionMenu-CScINahU.js.map +1 -0
  4. package/dist/AppSidebar-BmiiPfz9.js +3514 -0
  5. package/dist/AppSidebar-BmiiPfz9.js.map +1 -0
  6. package/dist/{experiment-utils-DTANyVKV.js → BaseModal-DfRIuVoj.js} +74 -149
  7. package/dist/BaseModal-DfRIuVoj.js.map +1 -0
  8. package/dist/ConfirmDialog-CJ7hqYUP.js +102 -0
  9. package/dist/ConfirmDialog-CJ7hqYUP.js.map +1 -0
  10. package/dist/ExperimentPopover-C4sGw-is.js +359 -0
  11. package/dist/ExperimentPopover-C4sGw-is.js.map +1 -0
  12. package/dist/ExperimentSelectorModal-D-9z7cNx.js +527 -0
  13. package/dist/ExperimentSelectorModal-D-9z7cNx.js.map +1 -0
  14. package/dist/SegmentedControl-DERBN-Xd.js +129 -0
  15. package/dist/SegmentedControl-DERBN-Xd.js.map +1 -0
  16. package/dist/SettingsModal-CSLE31yg.js +666 -0
  17. package/dist/SettingsModal-CSLE31yg.js.map +1 -0
  18. package/dist/analysisArtifactTypes-Cy3D0Ipg.js.map +1 -1
  19. package/dist/auth-SliLnFre.js +65 -0
  20. package/dist/auth-SliLnFre.js.map +1 -0
  21. package/dist/components/ActionMenu.vue.d.ts +1 -1
  22. package/dist/components/AdductText.vue.d.ts +1 -1
  23. package/dist/components/AlertBox.vue.d.ts +3 -3
  24. package/dist/components/AppContainer.vue.d.ts +1 -1
  25. package/dist/components/AppSidebar.vue.d.ts +14 -94
  26. package/dist/components/AppTopBar.vue.d.ts +16 -70
  27. package/dist/components/ArtifactSaveDialog.vue.d.ts +4 -4
  28. package/dist/components/ArtifactSelectorModal.vue.d.ts +4 -4
  29. package/dist/components/AuditTrail.vue.d.ts +2 -2
  30. package/dist/components/BaseButton.vue.d.ts +11 -4
  31. package/dist/components/BaseCheckbox.vue.d.ts +9 -3
  32. package/dist/components/BaseInput.vue.d.ts +13 -9
  33. package/dist/components/BaseModal.vue.d.ts +4 -4
  34. package/dist/components/BasePill.vue.d.ts +15 -8
  35. package/dist/components/BaseRadioGroup.vue.d.ts +2 -2
  36. package/dist/components/BaseSelect.vue.d.ts +51 -19
  37. package/dist/components/BaseTabs.vue.d.ts +6 -5
  38. package/dist/components/BatchProgressList.vue.d.ts +2 -2
  39. package/dist/components/ChartContainer.vue.d.ts +2 -2
  40. package/dist/components/ChemicalFormula.vue.d.ts +2 -2
  41. package/dist/components/CollapsibleCard.vue.d.ts +3 -3
  42. package/dist/components/ComponentBindingRenderer.vue.d.ts +2 -3
  43. package/dist/components/ConcentrationInput.vue.d.ts +2 -2
  44. package/dist/components/ConfirmDialog.vue.d.ts +8 -7
  45. package/dist/components/DataFrame.vue.d.ts +32 -74
  46. package/dist/components/DatePicker.vue.d.ts +24 -2
  47. package/dist/components/DoseCalculator.vue.d.ts +1 -1
  48. package/dist/components/DoseCalculatorVolumeField.vue.d.ts +1 -1
  49. package/dist/components/EmptyState.vue.d.ts +3 -2
  50. package/dist/components/ExperimentSelectorModal.vue.d.ts +3 -3
  51. package/dist/components/FormBuilder.vue.d.ts +17 -74
  52. package/dist/components/FormulaInput.vue.d.ts +2 -2
  53. package/dist/components/GeneratedPluginView.vue.d.ts +1 -1
  54. package/dist/components/GeneratedResultRenderer.vue.d.ts +5 -1
  55. package/dist/components/{StatusIndicator.vue.d.ts → InstrumentStatusPanels.vue.d.ts} +8 -9
  56. package/dist/components/JobsStatusTray.vue.d.ts +2 -9
  57. package/dist/components/LoadingSpinner.vue.d.ts +3 -3
  58. package/dist/components/MoleculeInput.vue.d.ts +2 -2
  59. package/dist/components/NumberInput.vue.d.ts +19 -5
  60. package/dist/components/PlateEditor.vue.d.ts +11 -61
  61. package/dist/components/PlotlyChart.vue.d.ts +2 -2
  62. package/dist/components/PluginIcon.vue.d.ts +5 -1
  63. package/dist/components/PluginWorkspaceView.controls.d.ts +2 -9
  64. package/dist/components/PluginWorkspaceView.navigation.d.ts +1 -7
  65. package/dist/components/PluginWorkspaceView.props.d.ts +18 -137
  66. package/dist/components/PluginWorkspaceView.shell.d.ts +2 -10
  67. package/dist/components/PluginWorkspaceView.vue.d.ts +14 -84
  68. package/dist/components/PresenceAvatars.vue.d.ts +31 -0
  69. package/dist/components/ProgressBar.vue.d.ts +3 -2
  70. package/dist/components/ProtocolStep.presentation.d.ts +0 -1
  71. package/dist/components/SampleHierarchyTree.vue.d.ts +3 -3
  72. package/dist/components/SampleSelector.vue.d.ts +3 -3
  73. package/dist/components/ScheduleCalendar.vue.d.ts +1 -1
  74. package/dist/components/ScientificNumber.vue.d.ts +1 -1
  75. package/dist/components/SecretInput.vue.d.ts +2 -2
  76. package/dist/components/SegmentedControl.vue.d.ts +2 -2
  77. package/dist/components/SequenceInput.vue.d.ts +2 -2
  78. package/dist/components/SettingsModal.vue.d.ts +12 -20
  79. package/dist/components/SmartGroup.types.d.ts +0 -1
  80. package/dist/components/SmartGroupFieldRecipe.vue.d.ts +1 -1
  81. package/dist/components/StaleFormBanner.vue.d.ts +20 -0
  82. package/dist/components/TagsInput.vue.d.ts +4 -3
  83. package/dist/components/TimeRangeInput.vue.d.ts +2 -2
  84. package/dist/components/VersionConflictDialog.vue.d.ts +24 -0
  85. package/dist/components/WellPlate.geometry.d.ts +0 -6
  86. package/dist/components/WellPlate.rendering.d.ts +0 -2
  87. package/dist/components/WellPlate.vue.d.ts +7 -52
  88. package/dist/components/index.d.ts +0 -90
  89. package/dist/components/{AutoGroupModal.adapter.d.ts → internal/AutoGroupModalInternal.adapter.d.ts} +6 -6
  90. package/dist/components/{AutoGroupModal.vue.d.ts → internal/AutoGroupModalInternal.vue.d.ts} +6 -6
  91. package/dist/components/{BaseToggle.vue.d.ts → internal/CheckboxSwitchInternal.vue.d.ts} +2 -2
  92. package/dist/components/internal/DatePickerDateInternal.vue.d.ts +22 -0
  93. package/dist/components/{DateTimePicker.vue.d.ts → internal/DatePickerDateTimeInternal.vue.d.ts} +2 -2
  94. package/dist/components/{TimePicker.vue.d.ts → internal/DatePickerTimeInternal.vue.d.ts} +3 -3
  95. package/dist/components/internal/FilePickerListInternal.vue.d.ts +2 -2
  96. package/dist/components/internal/FormSchemaInternal.vue.d.ts +95 -0
  97. package/dist/components/{UnitInput.vue.d.ts → internal/NumberUnitInputInternal.vue.d.ts} +6 -14
  98. package/dist/components/internal/PlateEditorBindingInternal.vue.d.ts +3 -2
  99. package/dist/components/internal/ResourcePickerListInternal.vue.d.ts +3 -3
  100. package/dist/components/{MultiSelect.vue.d.ts → internal/SelectMultipleInternal.vue.d.ts} +11 -8
  101. package/dist/components/{SearchableSelect.vue.d.ts → internal/SelectSearchableInternal.vue.d.ts} +5 -2
  102. package/dist/components/internal/WorkspaceShellInternal.vue.d.ts +1 -15
  103. package/dist/components/internal/WorkspaceSidebarInternal.vue.d.ts +4 -4
  104. package/dist/{composables → components/internal}/autoGroup/classKey.d.ts +1 -1
  105. package/dist/{composables → components/internal}/autoGroup/classify.d.ts +1 -1
  106. package/dist/{composables → components/internal}/autoGroup/columns.d.ts +1 -1
  107. package/dist/{composables → components/internal}/autoGroup/compose.d.ts +1 -1
  108. package/dist/{composables → components/internal}/autoGroup/cooccurrence.d.ts +1 -1
  109. package/dist/{composables → components/internal}/autoGroup/csv-shim.d.ts +1 -1
  110. package/dist/{composables → components/internal}/autoGroup/fingerprint.d.ts +1 -1
  111. package/dist/{composables → components/internal}/autoGroup/template.d.ts +1 -1
  112. package/dist/{composables → components/internal}/autoGroup/tokenLength.d.ts +1 -1
  113. package/dist/components/internal/generatedJobsApi.d.ts +1 -1
  114. package/dist/{composables → components/internal}/useAutoGroup.d.ts +9 -18
  115. package/dist/composables/componentSpecs.d.ts +41 -0
  116. package/dist/composables/controlComponentBindings.d.ts +6 -0
  117. package/dist/composables/controlSchemaAdapters.d.ts +28 -2
  118. package/dist/composables/controlSchemaDoseDesign.d.ts +1 -1
  119. package/dist/composables/controlSchemaModel.d.ts +1 -1
  120. package/dist/composables/controlSchemaTypes.d.ts +35 -23
  121. package/dist/composables/{usePluginClient.d.ts → createClient.d.ts} +20 -49
  122. package/dist/composables/{useEventStream.d.ts → eventStream.d.ts} +2 -2
  123. package/dist/composables/experiment-utils.d.ts +1 -6
  124. package/dist/composables/index.d.ts +6 -59
  125. package/dist/composables/platformContextHelpers.d.ts +0 -11
  126. package/dist/composables/pluginEndpointBuilder.d.ts +2 -2
  127. package/dist/composables/pluginWorkspaceModel.d.ts +14 -97
  128. package/dist/composables/useApi.d.ts +1 -3
  129. package/dist/composables/useAppExperiment.d.ts +1 -1
  130. package/dist/composables/{useAnalysisArtifacts.d.ts → useArtifacts.d.ts} +6 -6
  131. package/dist/composables/useExperiment.d.ts +30 -0
  132. package/dist/composables/useFilePicker.d.ts +2 -2
  133. package/dist/composables/useJobCenter.d.ts +63 -0
  134. package/dist/composables/{useGeneratedAnalysis.d.ts → useJobsEndpoint.d.ts} +22 -23
  135. package/dist/composables/useMenuKeyboard.d.ts +1 -1
  136. package/dist/composables/usePlatform.d.ts +63 -0
  137. package/dist/composables/usePluginWorkspace.d.ts +6 -11
  138. package/dist/composables/usePresence.d.ts +41 -0
  139. package/dist/composables/useRackEditor.d.ts +2 -2
  140. package/dist/composables/useRealtime.d.ts +71 -0
  141. package/dist/composables/{useRequestSyncState.d.ts → useRequest.d.ts} +12 -17
  142. package/dist/composables/useToast.d.ts +7 -5
  143. package/dist/composables/useVersionedSave.d.ts +76 -0
  144. package/dist/controlSchemaModel-CP5-_nAj.js +95 -0
  145. package/dist/controlSchemaModel-CP5-_nAj.js.map +1 -0
  146. package/dist/data-C2PwI_dn.js +3811 -0
  147. package/dist/data-C2PwI_dn.js.map +1 -0
  148. package/dist/data.d.ts +32 -0
  149. package/dist/data.js +10 -0
  150. package/dist/deprecatedRootExports.d.ts +191 -0
  151. package/dist/experiment-43OJtH7R.js +673 -0
  152. package/dist/experiment-43OJtH7R.js.map +1 -0
  153. package/dist/experimentStatus-BZmU4czV.js +60 -0
  154. package/dist/experimentStatus-BZmU4czV.js.map +1 -0
  155. package/dist/host.d.ts +10 -0
  156. package/dist/host.js +26 -0
  157. package/dist/host.js.map +1 -0
  158. package/dist/index.d.ts +1 -12
  159. package/dist/index.js +65 -277
  160. package/dist/index.js.map +1 -1
  161. package/dist/install-DAID6c2-.js +668 -0
  162. package/dist/install-DAID6c2-.js.map +1 -0
  163. package/dist/install.d.ts +2 -1
  164. package/dist/install.js +1 -21
  165. package/dist/instrument.d.ts +0 -6
  166. package/dist/lab-DLwRl_Ql.js +7513 -0
  167. package/dist/lab-DLwRl_Ql.js.map +1 -0
  168. package/dist/lab.d.ts +42 -0
  169. package/dist/lab.js +4 -0
  170. package/dist/permissions.d.ts +0 -4
  171. package/dist/permissions.js +1 -20
  172. package/dist/permissions.js.map +1 -1
  173. package/dist/records-BzTcxekG.js +3070 -0
  174. package/dist/records-BzTcxekG.js.map +1 -0
  175. package/dist/runtime-D6gVat6r.js +1495 -0
  176. package/dist/runtime-D6gVat6r.js.map +1 -0
  177. package/dist/runtime.d.ts +25 -0
  178. package/dist/runtime.js +8 -0
  179. package/dist/shell-5ju97nOS.js +197 -0
  180. package/dist/shell-5ju97nOS.js.map +1 -0
  181. package/dist/shell.d.ts +16 -0
  182. package/dist/shell.js +8 -0
  183. package/dist/stores/auth.d.ts +13 -35
  184. package/dist/stores/experiment.d.ts +4 -0
  185. package/dist/stores/index.js +2 -2
  186. package/dist/styles.css +12030 -14845
  187. package/dist/types/analysisArtifactTypes.d.ts +1 -1
  188. package/dist/types/auth.d.ts +0 -8
  189. package/dist/types/componentLabTypes.d.ts +98 -34
  190. package/dist/types/componentWorkflowTypes.d.ts +0 -27
  191. package/dist/types/components.d.ts +145 -74
  192. package/dist/types/form-builder.d.ts +4 -0
  193. package/dist/types/generated/platformContext.d.ts +52 -0
  194. package/dist/types/generated-ui.d.ts +2 -2
  195. package/dist/types/index.d.ts +4 -5
  196. package/dist/types/instrument.d.ts +41 -0
  197. package/dist/types/platform.d.ts +20 -58
  198. package/dist/useDebouncedWatch-BPwyl6eS.js +73 -0
  199. package/dist/useDebouncedWatch-BPwyl6eS.js.map +1 -0
  200. package/dist/useExpansionSet-CvoNMZJi.js +68 -0
  201. package/dist/useExpansionSet-CvoNMZJi.js.map +1 -0
  202. package/dist/useExperimentSamples-CxcnxZ8h.js +366 -0
  203. package/dist/useExperimentSamples-CxcnxZ8h.js.map +1 -0
  204. package/dist/useListReorder-CcbEYxX-.js +5462 -0
  205. package/dist/useListReorder-CcbEYxX-.js.map +1 -0
  206. package/dist/useRackEditor-BD5NIo5s.js +5916 -0
  207. package/dist/useRackEditor-BD5NIo5s.js.map +1 -0
  208. package/dist/useRealtime-PalKue84.js +696 -0
  209. package/dist/useRealtime-PalKue84.js.map +1 -0
  210. package/dist/useRequest-D5JDfsgZ.js +76 -0
  211. package/dist/useRequest-D5JDfsgZ.js.map +1 -0
  212. package/dist/utils/color.d.ts +0 -5
  213. package/dist/{composables/useDoseCalculator.d.ts → utils/dose.d.ts} +10 -13
  214. package/dist/utils/experimentStatus.d.ts +9 -0
  215. package/dist/{composables/useChemicalFormula.d.ts → utils/formula.d.ts} +3 -6
  216. package/dist/utils/integrationHost.d.ts +18 -0
  217. package/dist/utils/plotlyTemplate.d.ts +2 -0
  218. package/dist/utils/pluginSecrets.d.ts +12 -12
  219. package/dist/utils/presenceAvatars.d.ts +30 -0
  220. package/dist/utils/records.d.ts +0 -2
  221. package/dist/{composables/useTimeUtils.d.ts → utils/time.d.ts} +0 -18
  222. package/package.json +20 -17
  223. package/src/__tests__/components/ActionMenu.test.ts +0 -13
  224. package/src/__tests__/components/AlertBox.test.ts +1 -1
  225. package/src/__tests__/components/AppSidebar.test.ts +119 -167
  226. package/src/__tests__/components/AppToastContainer.test.ts +2 -2
  227. package/src/__tests__/components/AppTopBar.test.ts +181 -176
  228. package/src/__tests__/components/ArtifactSaveDialog.test.ts +5 -3
  229. package/src/__tests__/components/ArtifactSelectorModal.test.ts +6 -4
  230. package/src/__tests__/components/AuditTrail.test.ts +1 -1
  231. package/src/__tests__/components/AutoGroupModal.adapter.test.ts +1 -1
  232. package/src/__tests__/components/AutoGroupModal.anatomy.test.ts +2 -2
  233. package/src/__tests__/components/AutoGroupModal.wiring.test.ts +2 -2
  234. package/src/__tests__/components/BaseButton.test.ts +51 -0
  235. package/src/__tests__/components/{BaseToggle.test.ts → BaseCheckbox.switch.test.ts} +8 -6
  236. package/src/__tests__/components/BaseInput.test.ts +13 -34
  237. package/src/__tests__/components/BaseModal.test.ts +6 -6
  238. package/src/__tests__/components/BasePill.test.ts +33 -39
  239. package/src/__tests__/components/{MultiSelect.test.ts → BaseSelect.multiple.test.ts} +16 -7
  240. package/src/__tests__/components/{SearchableSelect.test.ts → BaseSelect.searchable.test.ts} +19 -9
  241. package/src/__tests__/components/BaseSelect.test.ts +10 -0
  242. package/src/__tests__/components/BaseTabs.test.ts +13 -13
  243. package/src/__tests__/components/CollapsibleCard.test.ts +1 -1
  244. package/src/__tests__/components/ComponentBindingRenderer.test.ts +25 -73
  245. package/src/__tests__/components/ConcentrationInput.test.ts +3 -3
  246. package/src/__tests__/components/ConfirmDialog.test.ts +23 -0
  247. package/src/__tests__/components/DataFrame.test.ts +140 -142
  248. package/src/__tests__/components/DataStates.test.ts +6 -22
  249. package/src/__tests__/components/{DateTimePicker.test.ts → DatePicker.datetime.test.ts} +9 -7
  250. package/src/__tests__/components/{TimePicker.test.ts → DatePicker.time.test.ts} +18 -17
  251. package/src/__tests__/components/DoseCalculator.test.ts +12 -7
  252. package/src/__tests__/components/DoseCalculatorVolumeField.test.ts +6 -6
  253. package/src/__tests__/components/ExperimentSelectorModal.test.ts +15 -15
  254. package/src/__tests__/components/FormBuilder.test.ts +49 -167
  255. package/src/__tests__/components/FormSchemaInternal.test.ts +91 -0
  256. package/src/__tests__/components/GeneratedPathInput.test.ts +18 -13
  257. package/src/__tests__/components/GeneratedPluginView.test.ts +38 -24
  258. package/src/__tests__/components/GeneratedResultRenderer.test.ts +6 -4
  259. package/src/__tests__/components/InstrumentStatusPanels.test.ts +79 -0
  260. package/src/__tests__/components/JobsStatusTray.test.ts +4 -4
  261. package/src/__tests__/components/NumberInput.test.ts +28 -0
  262. package/src/__tests__/components/{UnitInput.test.ts → NumberInput.units.test.ts} +6 -6
  263. package/src/__tests__/components/PlateEditor.test.ts +108 -108
  264. package/src/__tests__/components/PlateEditorBindingInternal.test.ts +13 -13
  265. package/src/__tests__/components/PlotlyChart.test.ts +1 -1
  266. package/src/__tests__/components/PluginIcon.test.ts +9 -4
  267. package/src/__tests__/components/PluginWorkspaceView.controls.test.ts +16 -29
  268. package/src/__tests__/components/PluginWorkspaceView.internal.test.ts +28 -34
  269. package/src/__tests__/components/PluginWorkspaceView.navigation.test.ts +4 -19
  270. package/src/__tests__/components/PluginWorkspaceView.shell.test.ts +1 -6
  271. package/src/__tests__/components/PluginWorkspaceView.test.ts +176 -155
  272. package/src/__tests__/components/PresenceAvatars.test.ts +90 -0
  273. package/src/__tests__/components/ProtocolStep.presentation.test.ts +1 -3
  274. package/src/__tests__/components/ProtocolStepEditor.test.ts +10 -11
  275. package/src/__tests__/components/ProtocolStepParameterField.test.ts +8 -7
  276. package/src/__tests__/components/ResourcePickerListInternal.test.ts +2 -2
  277. package/src/__tests__/components/RetiredStyles.test.ts +0 -18
  278. package/src/__tests__/components/SampleSelector.test.ts +17 -17
  279. package/src/__tests__/components/SecretInput.test.ts +14 -19
  280. package/src/__tests__/components/SettingsModal.test.ts +76 -84
  281. package/src/__tests__/components/StaleFormBanner.test.ts +48 -0
  282. package/src/__tests__/components/ThemeToggle.test.ts +1 -1
  283. package/src/__tests__/components/WellPlate.decoration.test.ts +10 -8
  284. package/src/__tests__/components/WellPlate.interaction.test.ts +6 -7
  285. package/src/__tests__/components/WellPlate.keyboard.test.ts +2 -2
  286. package/src/__tests__/components/deprecationTags.test.ts +90 -0
  287. package/src/__tests__/composables/analysisArtifactTarget.test.ts +1 -12
  288. package/src/__tests__/composables/autoGroup/classKey.test.ts +1 -1
  289. package/src/__tests__/composables/autoGroup/classify.test.ts +1 -1
  290. package/src/__tests__/composables/autoGroup/columns.test.ts +1 -1
  291. package/src/__tests__/composables/autoGroup/compose.test.ts +1 -1
  292. package/src/__tests__/composables/autoGroup/cooccurrence.test.ts +1 -1
  293. package/src/__tests__/composables/autoGroup/fieldEdits.test.ts +1 -1
  294. package/src/__tests__/composables/autoGroup/fingerprint.test.ts +1 -1
  295. package/src/__tests__/composables/autoGroup/golden.test.ts +1 -1
  296. package/src/__tests__/composables/autoGroup/groupByOrder.test.ts +1 -1
  297. package/src/__tests__/composables/autoGroup/groupTree.test.ts +1 -1
  298. package/src/__tests__/composables/autoGroup/integration.test.ts +1 -1
  299. package/src/__tests__/composables/autoGroup/template.test.ts +1 -1
  300. package/src/__tests__/composables/autoGroup/tokenLength.test.ts +1 -1
  301. package/src/__tests__/composables/autoGroup/tokenize.test.ts +1 -1
  302. package/src/__tests__/composables/{usePluginClient.test.ts → createClient.test.ts} +84 -222
  303. package/src/__tests__/composables/{useEventStream.test.ts → eventStream.test.ts} +6 -6
  304. package/src/__tests__/composables/experiment-utils.test.ts +13 -14
  305. package/src/__tests__/composables/useApi.test.ts +32 -21
  306. package/src/__tests__/composables/useAppExperiment.test.ts +19 -2
  307. package/src/__tests__/composables/{useAnalysisArtifacts.test.ts → useArtifacts.test.ts} +19 -27
  308. package/src/__tests__/composables/useAutoGroup.test.ts +3 -13
  309. package/src/__tests__/composables/useControlSchema.test.ts +41 -99
  310. package/src/__tests__/composables/useExperiment.test.ts +63 -0
  311. package/src/__tests__/composables/useFileBrowser.test.ts +4 -6
  312. package/src/__tests__/composables/{useJobsStatusTray.test.ts → useJobCenter.test.ts} +31 -31
  313. package/src/__tests__/composables/{useGeneratedAnalysis.test.ts → useJobsEndpoint.test.ts} +213 -139
  314. package/src/__tests__/composables/usePlatform.test.ts +102 -0
  315. package/src/__tests__/composables/usePresence.test.ts +164 -0
  316. package/src/__tests__/composables/useRackEditor.test.ts +2 -2
  317. package/src/__tests__/composables/useRealtime.test.ts +196 -0
  318. package/src/__tests__/composables/{useRequestSyncState.test.ts → useRequest.test.ts} +32 -47
  319. package/src/__tests__/composables/useVersionedSave.test.ts +194 -0
  320. package/src/__tests__/docs/extractDocsComponents.test.ts +36 -0
  321. package/src/__tests__/docs/extractDocsParsing.test.ts +2 -2
  322. package/src/__tests__/docs/extractDocsTheme.test.ts +1 -46
  323. package/src/__tests__/docs/frontendDocsCatalog.test.ts +164 -84
  324. package/src/__tests__/styles/baseControlsRules.test.ts +1 -1
  325. package/src/__tests__/styles/darkModeRules.test.ts +0 -6
  326. package/src/__tests__/{composables/useChemicalFormula.test.ts → utils/formula.test.ts} +3 -5
  327. package/src/__tests__/utils/permissions.test.ts +1 -36
  328. package/src/__tests__/utils/plotlyTemplate.test.ts +16 -1
  329. package/src/__tests__/{composables/useTimeUtils.test.ts → utils/time.test.ts} +2 -9
  330. package/src/components/ActionMenu.vue +7 -13
  331. package/src/components/AlertBox.story.vue +25 -25
  332. package/src/components/AlertBox.vue +8 -8
  333. package/src/components/AppLayout.story.vue +33 -44
  334. package/src/components/AppLayout.vue +1 -1
  335. package/src/components/AppSidebar.story.vue +40 -73
  336. package/src/components/AppSidebar.vue +66 -147
  337. package/src/components/AppToastContainer.story.vue +1 -1
  338. package/src/components/AppTopBar.story.vue +51 -100
  339. package/src/components/AppTopBar.vue +74 -198
  340. package/src/components/ArtifactSaveDialog.story.vue +9 -9
  341. package/src/components/ArtifactSaveDialog.vue +23 -26
  342. package/src/components/ArtifactSelectorModal.story.vue +4 -4
  343. package/src/components/ArtifactSelectorModal.vue +10 -10
  344. package/src/components/AuditTrail.story.vue +4 -4
  345. package/src/components/AuditTrail.vue +3 -3
  346. package/src/components/Avatar.story.vue +2 -3
  347. package/src/components/Avatar.vue +1 -2
  348. package/src/components/BaseButton.story.vue +25 -0
  349. package/src/components/BaseButton.vue +39 -10
  350. package/src/components/BaseCheckbox.story.vue +2 -2
  351. package/src/components/{BaseToggle.story.vue → BaseCheckbox.switch.story.vue} +22 -19
  352. package/src/components/BaseCheckbox.vue +39 -7
  353. package/src/components/BaseInput.story.vue +3 -15
  354. package/src/components/{BaseTextarea.story.vue → BaseInput.textarea.story.vue} +14 -10
  355. package/src/components/BaseInput.vue +53 -26
  356. package/src/components/BaseModal.story.vue +11 -11
  357. package/src/components/BaseModal.vue +8 -8
  358. package/src/components/BasePill.story.vue +48 -28
  359. package/src/components/BasePill.vue +22 -11
  360. package/src/components/BaseRadioGroup.story.vue +4 -4
  361. package/src/components/BaseRadioGroup.vue +3 -3
  362. package/src/components/{MultiSelect.story.vue → BaseSelect.multiple.story.vue} +20 -14
  363. package/src/components/{SearchableSelect.story.vue → BaseSelect.searchable.story.vue} +4 -4
  364. package/src/components/BaseSelect.story.vue +2 -2
  365. package/src/components/BaseSelect.vue +117 -22
  366. package/src/components/BaseTabs.story.vue +20 -20
  367. package/src/components/BaseTabs.vue +17 -9
  368. package/src/components/BatchProgressList.vue +3 -3
  369. package/src/components/ChartContainer.story.vue +8 -13
  370. package/src/components/ChartContainer.vue +3 -3
  371. package/src/components/ChemicalFormula.vue +1 -2
  372. package/src/components/CollapsibleCard.vue +5 -4
  373. package/src/components/ComponentBindingRenderer.story.vue +0 -29
  374. package/src/components/ComponentBindingRenderer.vue +15 -39
  375. package/src/components/ConcentrationInput.story.vue +2 -2
  376. package/src/components/ConcentrationInput.vue +9 -9
  377. package/src/components/ConfirmDialog.story.vue +21 -21
  378. package/src/components/ConfirmDialog.vue +15 -14
  379. package/src/components/DataFrame.story.vue +28 -40
  380. package/src/components/DataFrame.vue +112 -128
  381. package/src/components/{DateTimePicker.story.vue → DatePicker.datetime.story.vue} +19 -14
  382. package/src/components/DatePicker.story.vue +2 -2
  383. package/src/components/{TimePicker.story.vue → DatePicker.time.story.vue} +15 -12
  384. package/src/components/DatePicker.vue +82 -220
  385. package/src/components/DoseCalculator.vue +13 -19
  386. package/src/components/DoseCalculatorVolumeField.vue +6 -6
  387. package/src/components/EmptyState.story.vue +17 -17
  388. package/src/components/EmptyState.vue +5 -4
  389. package/src/components/ExperimentPopover.story.vue +1 -1
  390. package/src/components/ExperimentPopover.vue +4 -4
  391. package/src/components/ExperimentSelectorModal.story.vue +5 -5
  392. package/src/components/ExperimentSelectorModal.vue +11 -13
  393. package/src/components/FilePicker.vue +1 -1
  394. package/src/components/FormBuilder.story.vue +9 -4
  395. package/src/components/FormBuilder.vue +46 -253
  396. package/src/components/FormField.story.vue +1 -2
  397. package/src/components/FormulaInput.story.vue +2 -2
  398. package/src/components/FormulaInput.vue +5 -6
  399. package/src/components/GeneratedPathInput.vue +8 -9
  400. package/src/components/GeneratedPluginView.story.vue +1 -1
  401. package/src/components/GeneratedPluginView.vue +23 -22
  402. package/src/components/GeneratedResultRenderer.vue +16 -17
  403. package/src/components/InstrumentStatusPanels.story.vue +64 -0
  404. package/src/components/InstrumentStatusPanels.vue +133 -0
  405. package/src/components/JobsStatusTray.story.vue +2 -2
  406. package/src/components/JobsStatusTray.vue +4 -19
  407. package/src/components/LoadingSpinner.story.vue +11 -11
  408. package/src/components/LoadingSpinner.vue +6 -4
  409. package/src/components/MoleculeInput.story.vue +2 -2
  410. package/src/components/MoleculeInput.vue +3 -3
  411. package/src/components/NumberInput.story.vue +55 -15
  412. package/src/components/NumberInput.vue +80 -18
  413. package/src/components/PlateEditor.story.vue +51 -43
  414. package/src/components/PlateEditor.vue +97 -128
  415. package/src/components/PlotlyChart.story.vue +1 -1
  416. package/src/components/PlotlyChart.vue +6 -4
  417. package/src/components/PluginIcon.story.vue +9 -6
  418. package/src/components/PluginIcon.vue +7 -2
  419. package/src/components/PluginWorkspaceView.controls.ts +9 -29
  420. package/src/components/PluginWorkspaceView.navigation.ts +2 -23
  421. package/src/components/PluginWorkspaceView.props.ts +17 -151
  422. package/src/components/PluginWorkspaceView.shell.ts +13 -24
  423. package/src/components/PluginWorkspaceView.story.vue +64 -62
  424. package/src/components/PluginWorkspaceView.vue +21 -78
  425. package/src/components/PresenceAvatars.story.vue +75 -0
  426. package/src/components/PresenceAvatars.vue +114 -0
  427. package/src/components/ProgressBar.story.vue +7 -7
  428. package/src/components/ProgressBar.vue +4 -3
  429. package/src/components/ProtocolStep.presentation.ts +0 -11
  430. package/src/components/ProtocolStepEditor.vue +6 -5
  431. package/src/components/ProtocolStepParameterField.vue +15 -12
  432. package/src/components/SampleSelector.colors.ts +1 -1
  433. package/src/components/SampleSelector.vue +6 -6
  434. package/src/components/ScheduleCalendar.vue +4 -4
  435. package/src/components/SecretInput.story.vue +1 -1
  436. package/src/components/SecretInput.vue +16 -25
  437. package/src/components/SegmentedControl.story.vue +7 -7
  438. package/src/components/SegmentedControl.vue +5 -3
  439. package/src/components/SequenceInput.story.vue +2 -2
  440. package/src/components/SequenceInput.vue +3 -3
  441. package/src/components/SettingsModal.story.vue +13 -14
  442. package/src/components/SettingsModal.vue +29 -47
  443. package/src/components/SmartGroup.types.ts +4 -6
  444. package/src/components/SmartGroupFieldRecipe.vue +7 -5
  445. package/src/components/StaleFormBanner.story.vue +90 -0
  446. package/src/components/StaleFormBanner.vue +83 -0
  447. package/src/components/TagsInput.story.vue +7 -7
  448. package/src/components/TagsInput.vue +7 -6
  449. package/src/components/ThemeToggle.vue +5 -30
  450. package/src/components/TimeRangeInput.story.vue +1 -1
  451. package/src/components/TimeRangeInput.vue +10 -8
  452. package/src/components/VersionConflictDialog.story.vue +60 -0
  453. package/src/components/VersionConflictDialog.vue +79 -0
  454. package/src/components/WellPlate.geometry.ts +0 -38
  455. package/src/components/WellPlate.rendering.ts +0 -13
  456. package/src/components/WellPlate.story.vue +61 -50
  457. package/src/components/WellPlate.vue +61 -87
  458. package/src/components/index.ts +3 -105
  459. package/src/components/{AutoGroupModal.adapter.ts → internal/AutoGroupModalInternal.adapter.ts} +8 -8
  460. package/src/components/{AutoGroupModal.vue → internal/AutoGroupModalInternal.vue} +23 -23
  461. package/src/components/{BaseToggle.vue → internal/CheckboxSwitchInternal.vue} +8 -8
  462. package/src/components/internal/DataStateInternal.vue +1 -1
  463. package/src/components/internal/DatePickerDateInternal.vue +243 -0
  464. package/src/components/{DateTimePicker.vue → internal/DatePickerDateTimeInternal.vue} +9 -9
  465. package/src/components/{TimePicker.vue → internal/DatePickerTimeInternal.vue} +7 -7
  466. package/src/components/internal/FilePickerListInternal.vue +8 -14
  467. package/src/components/{FormActions.vue → internal/FormActionsInternal.vue} +2 -2
  468. package/src/components/internal/FormFieldRendererInternal.vue +1 -1
  469. package/src/components/internal/FormSchemaInternal.vue +253 -0
  470. package/src/components/{UnitInput.vue → internal/NumberUnitInputInternal.vue} +28 -28
  471. package/src/components/internal/PlateEditorBindingInternal.vue +8 -7
  472. package/src/components/internal/ResourcePickerListInternal.vue +4 -4
  473. package/src/components/{MultiSelect.vue → internal/SelectMultipleInternal.vue} +21 -15
  474. package/src/components/{SearchableSelect.vue → internal/SelectSearchableInternal.vue} +24 -8
  475. package/src/components/internal/WellEditPopupInternal.vue +4 -9
  476. package/src/components/internal/WorkspaceShellInternal.vue +3 -36
  477. package/src/components/internal/WorkspaceSidebarInternal.vue +4 -25
  478. package/src/{composables → components/internal}/autoGroup/classKey.ts +1 -1
  479. package/src/{composables → components/internal}/autoGroup/classify.ts +1 -1
  480. package/src/{composables → components/internal}/autoGroup/columns.ts +1 -1
  481. package/src/{composables → components/internal}/autoGroup/compose.ts +3 -3
  482. package/src/{composables → components/internal}/autoGroup/cooccurrence.ts +1 -1
  483. package/src/{composables → components/internal}/autoGroup/csv-shim.ts +1 -1
  484. package/src/{composables → components/internal}/autoGroup/fingerprint.ts +1 -1
  485. package/src/{composables → components/internal}/autoGroup/index.ts +1 -2
  486. package/src/{composables → components/internal}/autoGroup/template.ts +1 -1
  487. package/src/{composables → components/internal}/autoGroup/tokenLength.ts +1 -1
  488. package/src/components/internal/generatedJobsApi.ts +1 -1
  489. package/src/{composables → components/internal}/useAutoGroup.ts +3 -57
  490. package/src/composables/componentSpecs.ts +62 -0
  491. package/src/composables/controlComponentBindings.ts +7 -0
  492. package/src/composables/controlSchemaAdapters.ts +45 -7
  493. package/src/composables/controlSchemaDoseDesign.ts +16 -5
  494. package/src/composables/controlSchemaModel.ts +1 -1
  495. package/src/composables/controlSchemaTypes.ts +31 -22
  496. package/src/composables/{usePluginClient.ts → createClient.ts} +52 -190
  497. package/src/composables/{useEventStream.ts → eventStream.ts} +3 -3
  498. package/src/composables/experiment-utils.ts +1 -39
  499. package/src/composables/formBuilderRegistry.ts +6 -12
  500. package/src/composables/index.ts +16 -480
  501. package/src/composables/platformContextHelpers.ts +0 -57
  502. package/src/composables/pluginEndpointBuilder.ts +8 -10
  503. package/src/composables/pluginWorkspaceModel.ts +14 -105
  504. package/src/composables/useApi.ts +18 -30
  505. package/src/composables/useAppExperiment.ts +6 -5
  506. package/src/composables/{useAnalysisArtifacts.ts → useArtifacts.ts} +18 -19
  507. package/src/composables/useControlSchema.ts +5 -9
  508. package/src/composables/useControlWorkspace.ts +4 -7
  509. package/src/composables/useExperiment.ts +49 -0
  510. package/src/composables/useExperimentData.ts +4 -4
  511. package/src/composables/useExperimentSelector.ts +5 -5
  512. package/src/composables/useFileBrowser.ts +5 -13
  513. package/src/composables/useFilePicker.ts +2 -2
  514. package/src/composables/useFormBuilder.ts +3 -4
  515. package/src/composables/useJobCenter.ts +324 -0
  516. package/src/composables/{useGeneratedAnalysis.ts → useJobsEndpoint.ts} +53 -67
  517. package/src/composables/useMenuKeyboard.ts +1 -1
  518. package/src/composables/usePlatform.ts +95 -0
  519. package/src/composables/usePlatformFilePickerAdapter.ts +2 -1
  520. package/src/composables/usePluginWorkspace.ts +62 -107
  521. package/src/composables/usePresence.ts +110 -0
  522. package/src/composables/useRackEditor.ts +3 -3
  523. package/src/composables/useRealtime.ts +194 -0
  524. package/src/composables/{useRequestSyncState.ts → useRequest.ts} +25 -48
  525. package/src/composables/useScheduleCalendarLayout.ts +1 -1
  526. package/src/composables/useToast.ts +14 -11
  527. package/src/composables/useVersionedSave.ts +165 -0
  528. package/src/data.ts +130 -0
  529. package/src/deprecatedRootExports.ts +226 -0
  530. package/src/generated/schema.ts +1 -0
  531. package/src/host.ts +27 -0
  532. package/src/index.ts +2 -71
  533. package/src/install.ts +15 -2
  534. package/src/instrument.ts +1 -6
  535. package/src/lab.ts +128 -0
  536. package/src/permissions.ts +0 -27
  537. package/src/runtime.ts +145 -0
  538. package/src/shell.ts +103 -0
  539. package/src/stores/auth.ts +26 -162
  540. package/src/stores/experiment.ts +27 -1
  541. package/src/styles/components/action-menu.css +0 -5
  542. package/src/styles/components/alert-box.css +18 -0
  543. package/src/styles/components/app-top-bar.css +7 -48
  544. package/src/styles/components/button.css +12 -0
  545. package/src/styles/components/checkbox.css +1 -1
  546. package/src/styles/components/collapsible-card.css +1 -1
  547. package/src/styles/components/confirm-dialog.css +18 -2
  548. package/src/styles/components/empty-state.css +4 -2
  549. package/src/styles/components/file-picker.css +1 -1
  550. package/src/styles/components/icon-button.css +1 -1
  551. package/src/styles/components/loading-spinner.css +9 -12
  552. package/src/styles/components/multi-select.css +6 -1
  553. package/src/styles/components/pill.css +40 -35
  554. package/src/styles/components/plugin-icon.css +9 -0
  555. package/src/styles/components/presence-avatars.css +194 -0
  556. package/src/styles/components/progress-bar.css +2 -0
  557. package/src/styles/components/searchable-select.css +3 -0
  558. package/src/styles/components/smart-group.css +1 -6
  559. package/src/styles/components/textarea.css +1 -1
  560. package/src/styles/components/toggle.css +2 -2
  561. package/src/styles/components/version-conflict.css +122 -0
  562. package/src/styles/components/well-plate.css +0 -7
  563. package/src/styles/index.css +2 -11
  564. package/src/styles/variables.css +1 -527
  565. package/src/types/analysisArtifactTypes.ts +1 -1
  566. package/src/types/auth.ts +0 -10
  567. package/src/types/componentLabTypes.ts +103 -53
  568. package/src/types/componentWorkflowTypes.ts +2 -33
  569. package/src/types/components.ts +148 -114
  570. package/src/types/form-builder.ts +4 -0
  571. package/src/types/generated/platformContext.ts +59 -0
  572. package/src/types/generated-ui.ts +2 -2
  573. package/src/types/index.ts +15 -53
  574. package/src/types/instrument.ts +27 -0
  575. package/src/types/platform.ts +25 -89
  576. package/src/utils/color.ts +1 -12
  577. package/src/utils/dose.ts +335 -0
  578. package/src/utils/experimentStatus.ts +43 -0
  579. package/src/utils/formula.ts +292 -0
  580. package/src/utils/integrationHost.ts +27 -0
  581. package/src/utils/plotlyTemplate.ts +6 -0
  582. package/src/utils/pluginSecrets.ts +23 -23
  583. package/src/utils/presenceAvatars.ts +53 -0
  584. package/src/utils/records.ts +0 -5
  585. package/src/{composables/useTimeUtils.ts → utils/time.ts} +0 -21
  586. package/dist/ResourcePickerListInternal-CFAw4vTZ.js +0 -605
  587. package/dist/ResourcePickerListInternal-CFAw4vTZ.js.map +0 -1
  588. package/dist/__tests__/composables/useBioTemplatePackWorkspace.test.d.ts +0 -1
  589. package/dist/__tests__/composables/useBioTemplatePresetWorkspace.test.d.ts +0 -1
  590. package/dist/__tests__/composables/useBioTemplateWorkspace.test.d.ts +0 -1
  591. package/dist/__tests__/composables/useChemicalFormula.test.d.ts +0 -1
  592. package/dist/__tests__/composables/useEventStream.test.d.ts +0 -1
  593. package/dist/__tests__/composables/useExperimentSave.test.d.ts +0 -1
  594. package/dist/__tests__/composables/useGeneratedAnalysis.test.d.ts +0 -1
  595. package/dist/__tests__/composables/useGroupAssignment.test.d.ts +0 -1
  596. package/dist/__tests__/composables/useJobsStatusTray.test.d.ts +0 -1
  597. package/dist/__tests__/composables/useMobileSupportGate.test.d.ts +0 -1
  598. package/dist/__tests__/composables/usePlatformContext.test.d.ts +0 -1
  599. package/dist/__tests__/composables/usePluginClient.test.d.ts +0 -1
  600. package/dist/__tests__/composables/usePresenceHeartbeat.test.d.ts +0 -1
  601. package/dist/__tests__/composables/useRequestSyncState.test.d.ts +0 -1
  602. package/dist/__tests__/composables/useRuntimeAlignment.test.d.ts +0 -1
  603. package/dist/__tests__/composables/useTemplateCollection.test.d.ts +0 -1
  604. package/dist/__tests__/composables/useTimeUtils.test.d.ts +0 -1
  605. package/dist/__tests__/docs/extractDocsTemplates.test.d.ts +0 -1
  606. package/dist/__tests__/templates/templates.test.d.ts +0 -1
  607. package/dist/__tests__/templates/templatesDeprecation.test.d.ts +0 -1
  608. package/dist/__tests__/utils/lcms.test.d.ts +0 -1
  609. package/dist/__tests__/utils/rack.test.d.ts +0 -1
  610. package/dist/components/AppAvatarMenu.vue.d.ts +0 -47
  611. package/dist/components/AppTopBar.navigation.d.ts +0 -10
  612. package/dist/components/BaseTextarea.vue.d.ts +0 -31
  613. package/dist/components/BioTemplateExperimentWorkspaceView.vue.d.ts +0 -112
  614. package/dist/components/BioTemplatePackWorkspaceView.vue.d.ts +0 -86
  615. package/dist/components/BioTemplatePresetWorkspaceView.vue.d.ts +0 -80
  616. package/dist/components/BioTemplateRenderer.vue.d.ts +0 -30
  617. package/dist/components/ControlWorkspaceView.vue.d.ts +0 -138
  618. package/dist/components/DoseDesignWorkspaceView.vue.d.ts +0 -140
  619. package/dist/components/ExperimentDataViewer.vue.d.ts +0 -54
  620. package/dist/components/ExperimentTimeline.vue.d.ts +0 -70
  621. package/dist/components/FitPanel.vue.d.ts +0 -56
  622. package/dist/components/GroupAssigner.vue.d.ts +0 -26
  623. package/dist/components/IconButton.vue.d.ts +0 -30
  624. package/dist/components/MobileSupportGate.vue.d.ts +0 -32
  625. package/dist/components/ReagentEditor.vue.d.ts +0 -31
  626. package/dist/components/ReagentList.presentation.d.ts +0 -17
  627. package/dist/components/ReagentList.vue.d.ts +0 -58
  628. package/dist/components/SampleLegend.vue.d.ts +0 -33
  629. package/dist/components/SmartGroupModal.vue.d.ts +0 -29
  630. package/dist/components/index.js +0 -5
  631. package/dist/components-BOA5e7kb.js +0 -23137
  632. package/dist/components-BOA5e7kb.js.map +0 -1
  633. package/dist/composables/flattenWorkspaceBindings.d.ts +0 -61
  634. package/dist/composables/index.js +0 -7
  635. package/dist/composables/useBioTemplateComponents.d.ts +0 -34
  636. package/dist/composables/useBioTemplateControls.d.ts +0 -10
  637. package/dist/composables/useBioTemplatePackWorkspace.d.ts +0 -56
  638. package/dist/composables/useBioTemplatePresetWorkspace.d.ts +0 -79
  639. package/dist/composables/useBioTemplateWorkspace.d.ts +0 -39
  640. package/dist/composables/useExperimentSave.d.ts +0 -69
  641. package/dist/composables/useGroupAssignment.d.ts +0 -35
  642. package/dist/composables/useJobsStatusTray.d.ts +0 -87
  643. package/dist/composables/useMobileSupportGate.d.ts +0 -14
  644. package/dist/composables/usePlatformContext.d.ts +0 -218
  645. package/dist/composables/usePresenceHeartbeat.d.ts +0 -49
  646. package/dist/composables/useRuntimeAlignment.d.ts +0 -44
  647. package/dist/composables/useTemplateCollection.d.ts +0 -62
  648. package/dist/composables/workspaceRecipes.d.ts +0 -189
  649. package/dist/composables-izSQH8Ky.js +0 -591
  650. package/dist/composables-izSQH8Ky.js.map +0 -1
  651. package/dist/experiment-D49y_Kro.js +0 -459
  652. package/dist/experiment-D49y_Kro.js.map +0 -1
  653. package/dist/experiment-utils-DTANyVKV.js.map +0 -1
  654. package/dist/install.js.map +0 -1
  655. package/dist/lcms.d.ts +0 -38
  656. package/dist/settings-BG6v13Zq.js +0 -341
  657. package/dist/settings-BG6v13Zq.js.map +0 -1
  658. package/dist/tailwind.preset.d.ts +0 -63
  659. package/dist/tailwind.preset.js +0 -71
  660. package/dist/tailwind.preset.js.map +0 -1
  661. package/dist/templates/adapters.d.ts +0 -19
  662. package/dist/templates/assayLookups.d.ts +0 -3
  663. package/dist/templates/assayMatrixAdapters.d.ts +0 -13
  664. package/dist/templates/assayMatrixBuilder.d.ts +0 -3
  665. package/dist/templates/assayNormalizers.d.ts +0 -4
  666. package/dist/templates/builderIdUtils.d.ts +0 -4
  667. package/dist/templates/builderPresetControls.d.ts +0 -11
  668. package/dist/templates/builderReadUtils.d.ts +0 -8
  669. package/dist/templates/builders.d.ts +0 -26
  670. package/dist/templates/calibrationCurveAdapters.d.ts +0 -7
  671. package/dist/templates/calibrationCurveBuilder.d.ts +0 -3
  672. package/dist/templates/calibrationNormalizers.d.ts +0 -5
  673. package/dist/templates/catalog.d.ts +0 -192
  674. package/dist/templates/componentBindingCatalog.d.ts +0 -25
  675. package/dist/templates/componentBindingHelpers.d.ts +0 -17
  676. package/dist/templates/componentBindings.d.ts +0 -97
  677. package/dist/templates/componentDoseResponseProps.d.ts +0 -3
  678. package/dist/templates/componentGenericProps.d.ts +0 -8
  679. package/dist/templates/componentPlateHelpers.d.ts +0 -11
  680. package/dist/templates/componentPlateMapProps.d.ts +0 -3
  681. package/dist/templates/componentPropsFactory.d.ts +0 -3
  682. package/dist/templates/componentQpcrPlateProps.d.ts +0 -3
  683. package/dist/templates/componentTargetResolvers.d.ts +0 -5
  684. package/dist/templates/componentTemplateProps.d.ts +0 -3
  685. package/dist/templates/controlSchemaClone.d.ts +0 -4
  686. package/dist/templates/controlSchemaConstants.d.ts +0 -10
  687. package/dist/templates/controlSchemaMerge.d.ts +0 -3
  688. package/dist/templates/controlSchemaTargets.d.ts +0 -17
  689. package/dist/templates/controlSchemaTypes.d.ts +0 -4
  690. package/dist/templates/controlSchemas.d.ts +0 -34
  691. package/dist/templates/defaultBioTemplateBuilder.d.ts +0 -3
  692. package/dist/templates/doseResponseAdapters.d.ts +0 -6
  693. package/dist/templates/doseResponseBuilder.d.ts +0 -3
  694. package/dist/templates/elisaAssayCollectionBuilder.d.ts +0 -3
  695. package/dist/templates/flowCytometryAssayCollectionBuilder.d.ts +0 -3
  696. package/dist/templates/flowCytometryPanelBuilder.d.ts +0 -3
  697. package/dist/templates/flowNormalizers.d.ts +0 -8
  698. package/dist/templates/flowPanelAdapters.d.ts +0 -7
  699. package/dist/templates/index.d.ts +0 -15
  700. package/dist/templates/index.js +0 -2
  701. package/dist/templates/instrumentRunAdapterHelpers.d.ts +0 -8
  702. package/dist/templates/instrumentRunAdapters.d.ts +0 -19
  703. package/dist/templates/instrumentRunBuilder.d.ts +0 -3
  704. package/dist/templates/lcmsBatchCollectionBuilder.d.ts +0 -3
  705. package/dist/templates/lookup.d.ts +0 -4
  706. package/dist/templates/packs.d.ts +0 -21
  707. package/dist/templates/plateMapAdapters.d.ts +0 -5
  708. package/dist/templates/plateMapBuilder.d.ts +0 -3
  709. package/dist/templates/presetControlSchemas.d.ts +0 -534
  710. package/dist/templates/presets.d.ts +0 -106
  711. package/dist/templates/protocolAdapters.d.ts +0 -9
  712. package/dist/templates/protocolNormalizers.d.ts +0 -6
  713. package/dist/templates/protocolStepsBuilder.d.ts +0 -3
  714. package/dist/templates/qpcrAdapters.d.ts +0 -9
  715. package/dist/templates/qpcrExpressionCollectionBuilder.d.ts +0 -3
  716. package/dist/templates/qpcrPlateBuilder.d.ts +0 -3
  717. package/dist/templates/reagentAdapters.d.ts +0 -9
  718. package/dist/templates/reagentListBuilder.d.ts +0 -3
  719. package/dist/templates/runNormalizers.d.ts +0 -10
  720. package/dist/templates/sampleNormalizers.d.ts +0 -4
  721. package/dist/templates/samplePrepAdapters.d.ts +0 -7
  722. package/dist/templates/samplePrepBuilder.d.ts +0 -3
  723. package/dist/templates/sampleSheetAdapters.d.ts +0 -9
  724. package/dist/templates/sampleSheetBuilder.d.ts +0 -3
  725. package/dist/templates/targetedMetabolomicsCollectionBuilder.d.ts +0 -3
  726. package/dist/templates/targetedMetabolomicsHelpers.d.ts +0 -5
  727. package/dist/templates/templateAdapterTypes.d.ts +0 -48
  728. package/dist/templates/templateControlSchemas.d.ts +0 -400
  729. package/dist/templates/templateCreateOptions.d.ts +0 -165
  730. package/dist/templates/templateEnvelopes.d.ts +0 -17
  731. package/dist/templates/templatePackCollectionBuilder.d.ts +0 -3
  732. package/dist/templates/templatePresetCollectionBuilder.d.ts +0 -20
  733. package/dist/templates/templateQpcrTypes.d.ts +0 -42
  734. package/dist/templates/templateValidators.d.ts +0 -25
  735. package/dist/templates/timeCourseAdapters.d.ts +0 -9
  736. package/dist/templates/timeCourseBuilder.d.ts +0 -3
  737. package/dist/templates/types.d.ts +0 -304
  738. package/dist/templates/wellPlateScreenCollectionBuilder.d.ts +0 -3
  739. package/dist/templates/westernBlotAssayCollectionBuilder.d.ts +0 -3
  740. package/dist/templates-B2DB0MCM.js +0 -12304
  741. package/dist/templates-B2DB0MCM.js.map +0 -1
  742. package/dist/utils/rack.d.ts +0 -63
  743. package/dist/validation-C_eH_vIg.js +0 -7999
  744. package/dist/validation-C_eH_vIg.js.map +0 -1
  745. package/src/__tests__/components/AppAvatarMenu.test.ts +0 -186
  746. package/src/__tests__/components/AppTopBar.navigation.test.ts +0 -68
  747. package/src/__tests__/components/AppTopBarPresence.test.ts +0 -47
  748. package/src/__tests__/components/BioTemplateExperimentWorkspaceView.test.ts +0 -159
  749. package/src/__tests__/components/BioTemplatePackWorkspaceView.test.ts +0 -192
  750. package/src/__tests__/components/BioTemplatePresetWorkspaceView.test.ts +0 -307
  751. package/src/__tests__/components/BioTemplateRenderer.test.ts +0 -96
  752. package/src/__tests__/components/ControlWorkspaceView.test.ts +0 -1100
  753. package/src/__tests__/components/DoseDesignWorkspaceView.test.ts +0 -183
  754. package/src/__tests__/components/ExperimentTimeline.test.ts +0 -108
  755. package/src/__tests__/components/FitPanel.test.ts +0 -96
  756. package/src/__tests__/components/GroupAssigner.test.ts +0 -101
  757. package/src/__tests__/components/MobileSupportGate.test.ts +0 -120
  758. package/src/__tests__/components/ReagentList.presentation.test.ts +0 -73
  759. package/src/__tests__/components/ReagentList.test.ts +0 -167
  760. package/src/__tests__/components/SampleLegend.test.ts +0 -18
  761. package/src/__tests__/components/SmartGroupModal.test.ts +0 -69
  762. package/src/__tests__/components/WellPlate.sampleTypeIndicator.test.ts +0 -58
  763. package/src/__tests__/components/iconButtonIconSizing.test.ts +0 -18
  764. package/src/__tests__/composables/useBioTemplatePackWorkspace.test.ts +0 -125
  765. package/src/__tests__/composables/useBioTemplatePresetWorkspace.test.ts +0 -199
  766. package/src/__tests__/composables/useBioTemplateWorkspace.test.ts +0 -104
  767. package/src/__tests__/composables/useExperimentSave.test.ts +0 -542
  768. package/src/__tests__/composables/useGroupAssignment.test.ts +0 -73
  769. package/src/__tests__/composables/useMobileSupportGate.test.ts +0 -74
  770. package/src/__tests__/composables/usePlatformContext.test.ts +0 -148
  771. package/src/__tests__/composables/usePresenceHeartbeat.test.ts +0 -164
  772. package/src/__tests__/composables/useRuntimeAlignment.test.ts +0 -145
  773. package/src/__tests__/composables/useTemplateCollection.test.ts +0 -147
  774. package/src/__tests__/docs/extractDocsTemplates.test.ts +0 -53
  775. package/src/__tests__/fixtures/templates/dose-response.json +0 -81
  776. package/src/__tests__/fixtures/templates/plate-map.json +0 -54
  777. package/src/__tests__/fixtures/templates/qpcr-plate.json +0 -96
  778. package/src/__tests__/fixtures/templates/sample-sheet.json +0 -71
  779. package/src/__tests__/templates/templates.test.ts +0 -1235
  780. package/src/__tests__/templates/templatesDeprecation.test.ts +0 -78
  781. package/src/__tests__/utils/lcms.test.ts +0 -73
  782. package/src/__tests__/utils/rack.test.ts +0 -120
  783. package/src/components/AppAvatarMenu.story.vue +0 -155
  784. package/src/components/AppAvatarMenu.vue +0 -154
  785. package/src/components/AppTopBar.navigation.ts +0 -60
  786. package/src/components/AutoGroupModal.story.vue +0 -458
  787. package/src/components/BaseTextarea.vue +0 -58
  788. package/src/components/BioTemplateExperimentWorkspaceView.story.vue +0 -123
  789. package/src/components/BioTemplateExperimentWorkspaceView.vue +0 -339
  790. package/src/components/BioTemplatePackWorkspaceView.story.vue +0 -107
  791. package/src/components/BioTemplatePackWorkspaceView.vue +0 -180
  792. package/src/components/BioTemplatePresetWorkspaceView.story.vue +0 -163
  793. package/src/components/BioTemplatePresetWorkspaceView.vue +0 -403
  794. package/src/components/BioTemplateRenderer.story.vue +0 -57
  795. package/src/components/BioTemplateRenderer.vue +0 -64
  796. package/src/components/ControlWorkspaceView.story.vue +0 -347
  797. package/src/components/ControlWorkspaceView.vue +0 -370
  798. package/src/components/DoseDesignWorkspaceView.story.vue +0 -77
  799. package/src/components/DoseDesignWorkspaceView.vue +0 -243
  800. package/src/components/ExperimentDataViewer.story.vue +0 -177
  801. package/src/components/ExperimentDataViewer.vue +0 -313
  802. package/src/components/ExperimentTimeline.story.vue +0 -208
  803. package/src/components/ExperimentTimeline.vue +0 -383
  804. package/src/components/FitPanel.story.vue +0 -191
  805. package/src/components/FitPanel.vue +0 -168
  806. package/src/components/FormActions.story.vue +0 -96
  807. package/src/components/GroupAssigner.story.vue +0 -83
  808. package/src/components/GroupAssigner.vue +0 -319
  809. package/src/components/IconButton.story.vue +0 -140
  810. package/src/components/IconButton.vue +0 -69
  811. package/src/components/MobileSupportGate.story.vue +0 -52
  812. package/src/components/MobileSupportGate.vue +0 -111
  813. package/src/components/ReagentEditor.story.vue +0 -153
  814. package/src/components/ReagentEditor.vue +0 -414
  815. package/src/components/ReagentList.presentation.ts +0 -106
  816. package/src/components/ReagentList.story.vue +0 -155
  817. package/src/components/ReagentList.vue +0 -438
  818. package/src/components/SampleLegend.story.vue +0 -91
  819. package/src/components/SampleLegend.vue +0 -121
  820. package/src/components/SmartGroupModal.story.vue +0 -61
  821. package/src/components/SmartGroupModal.vue +0 -61
  822. package/src/components/StatusIndicator.story.vue +0 -99
  823. package/src/components/StatusIndicator.vue +0 -36
  824. package/src/components/UnitInput.story.vue +0 -194
  825. package/src/composables/flattenWorkspaceBindings.ts +0 -104
  826. package/src/composables/useBioTemplateComponents.ts +0 -117
  827. package/src/composables/useBioTemplateControls.ts +0 -45
  828. package/src/composables/useBioTemplatePackWorkspace.ts +0 -201
  829. package/src/composables/useBioTemplatePresetWorkspace.ts +0 -329
  830. package/src/composables/useBioTemplateWorkspace.ts +0 -120
  831. package/src/composables/useChemicalFormula.ts +0 -301
  832. package/src/composables/useDoseCalculator.ts +0 -370
  833. package/src/composables/useExperimentSave.ts +0 -348
  834. package/src/composables/useGroupAssignment.ts +0 -152
  835. package/src/composables/useJobsStatusTray.ts +0 -493
  836. package/src/composables/useMobileSupportGate.ts +0 -80
  837. package/src/composables/usePlatformContext.ts +0 -299
  838. package/src/composables/usePresenceHeartbeat.ts +0 -201
  839. package/src/composables/useRuntimeAlignment.ts +0 -184
  840. package/src/composables/useTemplateCollection.ts +0 -233
  841. package/src/composables/workspaceRecipes.ts +0 -268
  842. package/src/lcms.ts +0 -119
  843. package/src/styles/components/app-avatar-menu.css +0 -121
  844. package/src/styles/components/experiment-data-viewer.css +0 -138
  845. package/src/styles/components/experiment-timeline.css +0 -572
  846. package/src/styles/components/fit-panel.css +0 -153
  847. package/src/styles/components/group-assigner.css +0 -198
  848. package/src/styles/components/mobile-support-gate.css +0 -117
  849. package/src/styles/components/reagent-editor.css +0 -501
  850. package/src/styles/components/reagent-list.css +0 -408
  851. package/src/styles/components/sample-legend.css +0 -212
  852. package/src/styles/components/status-indicator.css +0 -66
  853. package/src/styles/components/theme-toggle.css +0 -6
  854. package/src/tailwind.preset.ts +0 -66
  855. package/src/templates/adapters.ts +0 -141
  856. package/src/templates/assayLookups.ts +0 -33
  857. package/src/templates/assayMatrixAdapters.ts +0 -85
  858. package/src/templates/assayMatrixBuilder.ts +0 -60
  859. package/src/templates/assayNormalizers.ts +0 -34
  860. package/src/templates/builderIdUtils.ts +0 -20
  861. package/src/templates/builderPresetControls.ts +0 -166
  862. package/src/templates/builderReadUtils.ts +0 -55
  863. package/src/templates/builders.ts +0 -122
  864. package/src/templates/calibrationCurveAdapters.ts +0 -62
  865. package/src/templates/calibrationCurveBuilder.ts +0 -100
  866. package/src/templates/calibrationNormalizers.ts +0 -60
  867. package/src/templates/catalog.ts +0 -249
  868. package/src/templates/componentBindingCatalog.ts +0 -90
  869. package/src/templates/componentBindingHelpers.ts +0 -93
  870. package/src/templates/componentBindings.ts +0 -279
  871. package/src/templates/componentDoseResponseProps.ts +0 -41
  872. package/src/templates/componentGenericProps.ts +0 -77
  873. package/src/templates/componentPlateHelpers.ts +0 -52
  874. package/src/templates/componentPlateMapProps.ts +0 -34
  875. package/src/templates/componentPropsFactory.ts +0 -21
  876. package/src/templates/componentQpcrPlateProps.ts +0 -27
  877. package/src/templates/componentTargetResolvers.ts +0 -67
  878. package/src/templates/componentTemplateProps.ts +0 -78
  879. package/src/templates/controlSchemaClone.ts +0 -32
  880. package/src/templates/controlSchemaConstants.ts +0 -11
  881. package/src/templates/controlSchemaMerge.ts +0 -40
  882. package/src/templates/controlSchemaTargets.ts +0 -85
  883. package/src/templates/controlSchemaTypes.ts +0 -20
  884. package/src/templates/controlSchemas.ts +0 -113
  885. package/src/templates/defaultBioTemplateBuilder.ts +0 -125
  886. package/src/templates/doseResponseAdapters.ts +0 -36
  887. package/src/templates/doseResponseBuilder.ts +0 -45
  888. package/src/templates/elisaAssayCollectionBuilder.ts +0 -63
  889. package/src/templates/flowCytometryAssayCollectionBuilder.ts +0 -42
  890. package/src/templates/flowCytometryPanelBuilder.ts +0 -54
  891. package/src/templates/flowNormalizers.ts +0 -58
  892. package/src/templates/flowPanelAdapters.ts +0 -61
  893. package/src/templates/index.ts +0 -330
  894. package/src/templates/instrumentRunAdapterHelpers.ts +0 -94
  895. package/src/templates/instrumentRunAdapters.ts +0 -174
  896. package/src/templates/instrumentRunBuilder.ts +0 -98
  897. package/src/templates/lcmsBatchCollectionBuilder.ts +0 -39
  898. package/src/templates/lookup.ts +0 -18
  899. package/src/templates/packs.ts +0 -166
  900. package/src/templates/plateMapAdapters.ts +0 -38
  901. package/src/templates/plateMapBuilder.ts +0 -44
  902. package/src/templates/presetControlSchemas.ts +0 -258
  903. package/src/templates/presets.ts +0 -183
  904. package/src/templates/protocolAdapters.ts +0 -73
  905. package/src/templates/protocolNormalizers.ts +0 -37
  906. package/src/templates/protocolStepsBuilder.ts +0 -37
  907. package/src/templates/qpcrAdapters.ts +0 -108
  908. package/src/templates/qpcrExpressionCollectionBuilder.ts +0 -34
  909. package/src/templates/qpcrPlateBuilder.ts +0 -97
  910. package/src/templates/reagentAdapters.ts +0 -81
  911. package/src/templates/reagentListBuilder.ts +0 -31
  912. package/src/templates/runNormalizers.ts +0 -63
  913. package/src/templates/sampleNormalizers.ts +0 -58
  914. package/src/templates/samplePrepAdapters.ts +0 -66
  915. package/src/templates/samplePrepBuilder.ts +0 -52
  916. package/src/templates/sampleSheetAdapters.ts +0 -79
  917. package/src/templates/sampleSheetBuilder.ts +0 -24
  918. package/src/templates/targetedMetabolomicsCollectionBuilder.ts +0 -80
  919. package/src/templates/targetedMetabolomicsHelpers.ts +0 -102
  920. package/src/templates/templateAdapterTypes.ts +0 -58
  921. package/src/templates/templateControlSchemas.ts +0 -320
  922. package/src/templates/templateCreateOptions.ts +0 -208
  923. package/src/templates/templateEnvelopes.ts +0 -145
  924. package/src/templates/templatePackCollectionBuilder.ts +0 -24
  925. package/src/templates/templatePresetCollectionBuilder.ts +0 -141
  926. package/src/templates/templateQpcrTypes.ts +0 -48
  927. package/src/templates/templateValidators.ts +0 -426
  928. package/src/templates/timeCourseAdapters.ts +0 -77
  929. package/src/templates/timeCourseBuilder.ts +0 -65
  930. package/src/templates/types.ts +0 -493
  931. package/src/templates/wellPlateScreenCollectionBuilder.ts +0 -37
  932. package/src/templates/westernBlotAssayCollectionBuilder.ts +0 -69
  933. package/src/utils/rack.ts +0 -225
  934. /package/dist/__tests__/components/{AppAvatarMenu.test.d.ts → BaseButton.test.d.ts} +0 -0
  935. /package/dist/__tests__/components/{AppTopBar.navigation.test.d.ts → BaseCheckbox.switch.test.d.ts} +0 -0
  936. /package/dist/__tests__/components/{AppTopBarPresence.test.d.ts → BaseSelect.multiple.test.d.ts} +0 -0
  937. /package/dist/__tests__/components/{BaseToggle.test.d.ts → BaseSelect.searchable.test.d.ts} +0 -0
  938. /package/dist/__tests__/components/{BioTemplateExperimentWorkspaceView.test.d.ts → ConfirmDialog.test.d.ts} +0 -0
  939. /package/dist/__tests__/components/{BioTemplatePackWorkspaceView.test.d.ts → DatePicker.datetime.test.d.ts} +0 -0
  940. /package/dist/__tests__/components/{BioTemplatePresetWorkspaceView.test.d.ts → DatePicker.time.test.d.ts} +0 -0
  941. /package/dist/__tests__/components/{BioTemplateRenderer.test.d.ts → FormSchemaInternal.test.d.ts} +0 -0
  942. /package/dist/__tests__/components/{ControlWorkspaceView.test.d.ts → InstrumentStatusPanels.test.d.ts} +0 -0
  943. /package/dist/__tests__/components/{DateTimePicker.test.d.ts → NumberInput.units.test.d.ts} +0 -0
  944. /package/dist/__tests__/components/{DoseDesignWorkspaceView.test.d.ts → PresenceAvatars.test.d.ts} +0 -0
  945. /package/dist/__tests__/components/{ExperimentTimeline.test.d.ts → StaleFormBanner.test.d.ts} +0 -0
  946. /package/dist/__tests__/components/{FitPanel.test.d.ts → deprecationTags.test.d.ts} +0 -0
  947. /package/dist/__tests__/{components/GroupAssigner.test.d.ts → composables/createClient.test.d.ts} +0 -0
  948. /package/dist/__tests__/{components/MobileSupportGate.test.d.ts → composables/eventStream.test.d.ts} +0 -0
  949. /package/dist/__tests__/{components/MultiSelect.test.d.ts → composables/useArtifacts.test.d.ts} +0 -0
  950. /package/dist/__tests__/{components/ReagentList.presentation.test.d.ts → composables/useExperiment.test.d.ts} +0 -0
  951. /package/dist/__tests__/{components/ReagentList.test.d.ts → composables/useJobCenter.test.d.ts} +0 -0
  952. /package/dist/__tests__/{components/SampleLegend.test.d.ts → composables/useJobsEndpoint.test.d.ts} +0 -0
  953. /package/dist/__tests__/{components/SearchableSelect.test.d.ts → composables/usePlatform.test.d.ts} +0 -0
  954. /package/dist/__tests__/{components/SmartGroupModal.test.d.ts → composables/usePresence.test.d.ts} +0 -0
  955. /package/dist/__tests__/{components/TimePicker.test.d.ts → composables/useRealtime.test.d.ts} +0 -0
  956. /package/dist/__tests__/{components/UnitInput.test.d.ts → composables/useRequest.test.d.ts} +0 -0
  957. /package/dist/__tests__/{components/WellPlate.sampleTypeIndicator.test.d.ts → composables/useVersionedSave.test.d.ts} +0 -0
  958. /package/dist/__tests__/{components/iconButtonIconSizing.test.d.ts → utils/formula.test.d.ts} +0 -0
  959. /package/dist/__tests__/{composables/useAnalysisArtifacts.test.d.ts → utils/time.test.d.ts} +0 -0
  960. /package/dist/components/{FormActions.vue.d.ts → internal/FormActionsInternal.vue.d.ts} +0 -0
  961. /package/dist/{composables → components/internal}/autoGroup/colors.d.ts +0 -0
  962. /package/dist/{composables → components/internal}/autoGroup/index.d.ts +0 -0
  963. /package/dist/{composables → components/internal}/autoGroup/tokenize.d.ts +0 -0
  964. /package/src/{composables → components/internal}/autoGroup/colors.ts +0 -0
  965. /package/src/{composables → components/internal}/autoGroup/tokenize.ts +0 -0
  966. /package/src/{composables → components/internal}/autoGroup/vocab.json +0 -0
@@ -0,0 +1,3514 @@
1
+ import { i as BaseButton_default, r as useEventListener } from "./BaseModal-DfRIuVoj.js";
2
+ import { f as useSettingsStore, n as integrationHost } from "./experiment-43OJtH7R.js";
3
+ import { D as useDropdownState, O as FormField_default, _ as APP_EXPERIMENT_KEY, j as BaseCheckbox_default, t as isRecord } from "./records-BzTcxekG.js";
4
+ import { _ 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, z as applySpecDefaults } from "./useListReorder-CcbEYxX-.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, 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 ?? "Workspace",
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
+ //#endregion
1546
+ //#region src/components/internal/AppTopBarPillNavInternal.vue
1547
+ var AppTopBarPillNavInternal_default = /* @__PURE__ */ defineComponent({
1548
+ __name: "AppTopBarPillNavInternal",
1549
+ props: {
1550
+ items: {},
1551
+ currentItemId: {}
1552
+ },
1553
+ emits: ["select", "option-select"],
1554
+ setup(__props, { emit: __emit }) {
1555
+ /** Horizontal pill-style navigation bar that emits select events and supports href, router-link, button, or dropdown items. */
1556
+ const props = __props;
1557
+ const emit = __emit;
1558
+ const openItemId = ref(null);
1559
+ const itemRefs = ref(/* @__PURE__ */ new Map());
1560
+ const normalizedItems = computed(() => props.items.map(normalizePillNavItem));
1561
+ function handleClick(item) {
1562
+ if (item.disabled) return;
1563
+ if (item.children?.length) {
1564
+ toggleDropdown(item.id);
1565
+ return;
1566
+ }
1567
+ if (item.href || item.to) return;
1568
+ emit("select", item);
1569
+ }
1570
+ function handleOptionClick(option, item) {
1571
+ if (option.disabled) return;
1572
+ if (!option.href && !option.to) emit("option-select", option, item);
1573
+ openItemId.value = null;
1574
+ }
1575
+ function normalizePillNavItem(item) {
1576
+ const normalized = normalizeItemInput(item);
1577
+ return {
1578
+ ...normalized,
1579
+ children: normalized.children?.map(normalizeItemInput)
1580
+ };
1581
+ }
1582
+ function toggleDropdown(itemId) {
1583
+ openItemId.value = openItemId.value === itemId ? null : itemId;
1584
+ }
1585
+ function setItemRef(el, itemId) {
1586
+ if (el) itemRefs.value.set(itemId, el);
1587
+ else itemRefs.value.delete(itemId);
1588
+ }
1589
+ function handleClickOutside(event) {
1590
+ const target = event.target;
1591
+ if (!Array.from(itemRefs.value.values()).some((el) => el.contains(target))) openItemId.value = null;
1592
+ }
1593
+ const activeChild = (item) => item.children?.find((child) => child.id === props.currentItemId);
1594
+ function isSvgIcon(icon) {
1595
+ if (!icon) return false;
1596
+ return Array.isArray(icon) || icon.startsWith("M") || icon.startsWith("m");
1597
+ }
1598
+ useEventListener(() => document, "click", handleClickOutside);
1599
+ return (_ctx, _cache) => {
1600
+ return openBlock(), createElementBlock("nav", _hoisted_1$5, [(openBlock(true), createElementBlock(Fragment, null, renderList(normalizedItems.value, (item) => {
1601
+ return openBlock(), createElementBlock("div", {
1602
+ key: item.id,
1603
+ ref_for: true,
1604
+ ref: (el) => setItemRef(el, item.id),
1605
+ class: "mint-pill-nav__item-wrap"
1606
+ }, [item.children?.length ? (openBlock(), createElementBlock("button", {
1607
+ key: 0,
1608
+ type: "button",
1609
+ class: normalizeClass([
1610
+ "mint-pill-nav__item",
1611
+ { "mint-pill-nav__item--active": item.id === __props.currentItemId || activeChild(item) !== void 0 },
1612
+ { "mint-pill-nav__item--disabled": item.disabled }
1613
+ ]),
1614
+ disabled: item.disabled,
1615
+ "aria-expanded": openItemId.value === item.id,
1616
+ "aria-haspopup": "menu",
1617
+ onClick: withModifiers(($event) => handleClick(item), ["stop"])
1618
+ }, [
1619
+ isSvgIcon(item.icon) ? (openBlock(), createElementBlock("svg", _hoisted_3$3, [Array.isArray(item.icon) ? (openBlock(true), createElementBlock(Fragment, { key: 0 }, renderList(item.icon, (d, index) => {
1620
+ return openBlock(), createElementBlock("path", {
1621
+ key: index,
1622
+ d
1623
+ }, null, 8, _hoisted_4$3);
1624
+ }), 128)) : (openBlock(), createElementBlock("path", {
1625
+ key: 1,
1626
+ d: item.icon
1627
+ }, null, 8, _hoisted_5$3))])) : createCommentVNode("", true),
1628
+ createTextVNode(" " + toDisplayString(activeChild(item)?.label ?? item.label) + " ", 1),
1629
+ item.dot ? (openBlock(), createElementBlock("span", _hoisted_6$2)) : createCommentVNode("", true),
1630
+ (openBlock(), createElementBlock("svg", {
1631
+ class: normalizeClass(["mint-pill-nav__chevron", { "mint-pill-nav__chevron--open": openItemId.value === item.id }]),
1632
+ viewBox: "0 0 24 24",
1633
+ fill: "none",
1634
+ stroke: "currentColor",
1635
+ "stroke-width": "2",
1636
+ "stroke-linecap": "round",
1637
+ "stroke-linejoin": "round",
1638
+ "aria-hidden": "true"
1639
+ }, [..._cache[0] || (_cache[0] = [createElementVNode("path", { d: "m6 9 6 6 6-6" }, null, -1)])], 2))
1640
+ ], 10, _hoisted_2$3)) : (openBlock(), createBlock(ActionItemInternal_default, {
1641
+ key: 1,
1642
+ href: item.href,
1643
+ to: item.to,
1644
+ disabled: item.disabled,
1645
+ class: normalizeClass([
1646
+ "mint-pill-nav__item",
1647
+ { "mint-pill-nav__item--active": item.id === __props.currentItemId },
1648
+ { "mint-pill-nav__item--disabled": item.disabled }
1649
+ ]),
1650
+ onClick: ($event) => handleClick(item)
1651
+ }, {
1652
+ default: withCtx(() => [
1653
+ isSvgIcon(item.icon) ? (openBlock(), createElementBlock("svg", _hoisted_7$2, [Array.isArray(item.icon) ? (openBlock(true), createElementBlock(Fragment, { key: 0 }, renderList(item.icon, (d, index) => {
1654
+ return openBlock(), createElementBlock("path", {
1655
+ key: index,
1656
+ d
1657
+ }, null, 8, _hoisted_8$2);
1658
+ }), 128)) : (openBlock(), createElementBlock("path", {
1659
+ key: 1,
1660
+ d: item.icon
1661
+ }, null, 8, _hoisted_9$2))])) : createCommentVNode("", true),
1662
+ createTextVNode(" " + toDisplayString(item.label) + " ", 1),
1663
+ item.dot ? (openBlock(), createElementBlock("span", _hoisted_10$2)) : createCommentVNode("", true)
1664
+ ]),
1665
+ _: 2
1666
+ }, 1032, [
1667
+ "href",
1668
+ "to",
1669
+ "disabled",
1670
+ "class",
1671
+ "onClick"
1672
+ ])), item.children?.length && openItemId.value === item.id ? (openBlock(), createElementBlock("div", _hoisted_11$2, [(openBlock(true), createElementBlock(Fragment, null, renderList(item.children, (option) => {
1673
+ return openBlock(), createBlock(ActionItemInternal_default, {
1674
+ key: option.id,
1675
+ href: option.href,
1676
+ to: option.to,
1677
+ disabled: option.disabled,
1678
+ class: normalizeClass([
1679
+ "mint-menu-item mint-pill-nav__dropdown-item",
1680
+ { "mint-menu-item--selected mint-pill-nav__dropdown-item--active": option.id === __props.currentItemId },
1681
+ { "mint-pill-nav__dropdown-item--disabled": option.disabled }
1682
+ ]),
1683
+ role: "menuitem",
1684
+ onClick: ($event) => handleOptionClick(option, item)
1685
+ }, {
1686
+ default: withCtx(() => [
1687
+ createElementVNode("span", _hoisted_12$2, toDisplayString(option.label), 1),
1688
+ option.description ? (openBlock(), createElementBlock("span", _hoisted_13$2, toDisplayString(option.description), 1)) : createCommentVNode("", true),
1689
+ _cache[1] || (_cache[1] = createElementVNode("svg", {
1690
+ class: "mint-menu-item__check",
1691
+ viewBox: "0 0 16 16",
1692
+ fill: "none",
1693
+ stroke: "currentColor",
1694
+ "stroke-width": "2",
1695
+ "stroke-linecap": "round",
1696
+ "stroke-linejoin": "round",
1697
+ "aria-hidden": "true"
1698
+ }, [createElementVNode("path", { d: "M3.5 8.5l3 3 6-7" })], -1))
1699
+ ]),
1700
+ _: 2
1701
+ }, 1032, [
1702
+ "href",
1703
+ "to",
1704
+ "disabled",
1705
+ "class",
1706
+ "onClick"
1707
+ ]);
1708
+ }), 128))])) : createCommentVNode("", true)]);
1709
+ }), 128))]);
1710
+ };
1711
+ }
1712
+ });
1713
+ //#endregion
1714
+ //#region src/components/AppTopBar.toastOffset.ts
1715
+ /**
1716
+ * Publishes the top-most mounted AppTopBar's bottom edge as `--mint-toast-offset-top`
1717
+ * on `<html>`, so the teleported toast container starts below the top bar.
1718
+ */
1719
+ var TOAST_OFFSET_PROPERTY = "--mint-toast-offset-top";
1720
+ var LISTENER_OPTIONS = {
1721
+ capture: true,
1722
+ passive: true
1723
+ };
1724
+ var topBars = /* @__PURE__ */ new Set();
1725
+ var observer;
1726
+ function syncToastOffset() {
1727
+ const style = document.documentElement.style;
1728
+ if (topBars.size === 0) {
1729
+ style.removeProperty(TOAST_OFFSET_PROPERTY);
1730
+ return;
1731
+ }
1732
+ const header = [...topBars].map((el) => el.getBoundingClientRect()).reduce((top, rect) => rect.top < top.top ? rect : top);
1733
+ style.setProperty(TOAST_OFFSET_PROPERTY, `calc(${Math.max(0, Math.round(header.bottom))}px + 1rem)`);
1734
+ }
1735
+ /** Track a top bar element; returns the cleanup to call on unmount. */
1736
+ function trackTopBarForToasts(el) {
1737
+ if (topBars.size === 0) {
1738
+ window.addEventListener("scroll", syncToastOffset, LISTENER_OPTIONS);
1739
+ window.addEventListener("resize", syncToastOffset, LISTENER_OPTIONS);
1740
+ if (typeof ResizeObserver !== "undefined") observer = new ResizeObserver(syncToastOffset);
1741
+ }
1742
+ topBars.add(el);
1743
+ observer?.observe(el);
1744
+ syncToastOffset();
1745
+ return () => {
1746
+ topBars.delete(el);
1747
+ observer?.unobserve(el);
1748
+ if (topBars.size === 0) {
1749
+ window.removeEventListener("scroll", syncToastOffset, LISTENER_OPTIONS);
1750
+ window.removeEventListener("resize", syncToastOffset, LISTENER_OPTIONS);
1751
+ observer?.disconnect();
1752
+ observer = void 0;
1753
+ }
1754
+ syncToastOffset();
1755
+ };
1756
+ }
1757
+ //#endregion
1758
+ //#region src/components/AppTopBar.vue?vue&type=script&setup=true&lang.ts
1759
+ var _hoisted_1$4 = { class: "mint-topbar__container" };
1760
+ var _hoisted_2$2 = { class: "mint-topbar__brand" };
1761
+ var _hoisted_3$2 = ["href"];
1762
+ var _hoisted_4$2 = {
1763
+ key: 0,
1764
+ class: "mint-topbar__identity"
1765
+ };
1766
+ var _hoisted_5$2 = {
1767
+ key: 0,
1768
+ class: "mint-topbar__logo"
1769
+ };
1770
+ var _hoisted_6$1 = {
1771
+ key: 0,
1772
+ class: "mint-topbar__identity"
1773
+ };
1774
+ var _hoisted_7$1 = {
1775
+ key: 0,
1776
+ class: "mint-topbar__logo"
1777
+ };
1778
+ var _hoisted_8$1 = {
1779
+ key: 0,
1780
+ class: "mint-topbar__identity"
1781
+ };
1782
+ var _hoisted_9$1 = {
1783
+ key: 0,
1784
+ class: "mint-topbar__logo"
1785
+ };
1786
+ var _hoisted_10$1 = {
1787
+ key: 0,
1788
+ class: "mint-topbar__plugin-identity"
1789
+ };
1790
+ var _hoisted_11$1 = { class: "mint-topbar__plugin-name" };
1791
+ var _hoisted_12$1 = {
1792
+ key: 3,
1793
+ class: "mint-topbar-title-group"
1794
+ };
1795
+ var _hoisted_13$1 = { class: "mint-topbar-title" };
1796
+ var _hoisted_14$1 = { class: "mint-topbar-subtitle" };
1797
+ var _hoisted_15$1 = {
1798
+ key: 4,
1799
+ class: "mint-topbar__title-only"
1800
+ };
1801
+ var _hoisted_16$1 = {
1802
+ key: 5,
1803
+ class: "mint-topbar__center"
1804
+ };
1805
+ var _hoisted_17$1 = { class: "mint-topbar__right" };
1806
+ var _hoisted_18$1 = {
1807
+ key: 0,
1808
+ class: "mint-topbar__standalone-badge"
1809
+ };
1810
+ //#endregion
1811
+ //#region src/components/AppTopBar.vue
1812
+ var AppTopBar_default = /* @__PURE__ */ defineComponent({
1813
+ __name: "AppTopBar",
1814
+ props: {
1815
+ title: {},
1816
+ subtitle: {},
1817
+ spec: { default: () => ({}) },
1818
+ pill: {},
1819
+ pageSelector: {},
1820
+ currentPageSelectorId: {}
1821
+ },
1822
+ emits: [
1823
+ "page-selector-select",
1824
+ "update:pill",
1825
+ "pill-select",
1826
+ "pill-option-select",
1827
+ "settings-values-change"
1828
+ ],
1829
+ setup(__props, { emit: __emit }) {
1830
+ /** Full application top bar with brand logo, static plugin identity, page selector, centered pill nav, experiment popover, and an account slot. */
1831
+ const props = __props;
1832
+ const config = computed(() => applySpecDefaults({
1833
+ variant: "card",
1834
+ homePath: "/",
1835
+ logo: true,
1836
+ themeToggle: false,
1837
+ settings: false,
1838
+ standaloneLabel: "Standalone"
1839
+ }, props.spec));
1840
+ const settingsConfig = computed(() => toValue(config.value.settings) || void 0);
1841
+ const showSettings = computed(() => settingsConfig.value !== void 0);
1842
+ const SettingsModal = defineAsyncComponent(() => import("./SettingsModal-CSLE31yg.js").then((n) => n.n));
1843
+ const ExperimentPopover = defineAsyncComponent(() => import("./ExperimentPopover-C4sGw-is.js").then((n) => n.n));
1844
+ const ExperimentSelectorModal = defineAsyncComponent(() => import("./ExperimentSelectorModal-D-9z7cNx.js").then((n) => n.n));
1845
+ const emit = __emit;
1846
+ const settingsOpen = ref(false);
1847
+ const headerEl = ref(null);
1848
+ let untrackToastOffset;
1849
+ onMounted(() => {
1850
+ if (headerEl.value) untrackToastOffset = trackTopBarForToasts(headerEl.value);
1851
+ });
1852
+ onBeforeUnmount(() => untrackToastOffset?.());
1853
+ const { integrated: isIntegrated, plugin } = usePlatform();
1854
+ const isStandalone = computed(() => !isIntegrated.value);
1855
+ const appExperiment = inject(APP_EXPERIMENT_KEY, null);
1856
+ const canBindExperiment = computed(() => plugin.value?.plugin_type !== "static");
1857
+ const pluginIcon = computed(() => {
1858
+ const currentPlugin = plugin.value;
1859
+ return currentPlugin?.icon ? {
1860
+ icon: currentPlugin.icon,
1861
+ color: currentPlugin.color
1862
+ } : null;
1863
+ });
1864
+ const hasPlatformPageSelector = computed(() => props.pageSelector === void 0 && (plugin.value?.nav_items?.length ?? 0) > 1);
1865
+ const hasPropPageSelector = computed(() => (props.pageSelector?.length ?? 0) > 1);
1866
+ const hasPageSelector = computed(() => hasPropPageSelector.value || hasPlatformPageSelector.value);
1867
+ const platformPageSelectorEl = ref(null);
1868
+ watch(platformPageSelectorEl, (element, _previous, onCleanup) => {
1869
+ const unmount = element ? integrationHost()?.mountPageSelector(element) : void 0;
1870
+ if (unmount) onCleanup(unmount);
1871
+ }, { flush: "sync" });
1872
+ /** Integrated plugins show their name as a static identity in place of the title; the page selector replaces it. */
1873
+ const identityName = computed(() => isIntegrated.value && !hasPageSelector.value ? plugin.value?.display_name || plugin.value?.name : void 0);
1874
+ const hasPillNav = computed(() => !!config.value.pills?.length);
1875
+ const hasTitleGroup = computed(() => !hasPageSelector.value && !identityName.value && !!props.title && !!props.subtitle);
1876
+ const hasTitleOnly = computed(() => !hasPageSelector.value && !identityName.value && !hasTitleGroup.value && !!props.title);
1877
+ const normalizedPageSelector = computed(() => props.pageSelector?.map(normalizeItemInput) ?? []);
1878
+ const normalizedPillNav = computed(() => config.value.pills ?? []);
1879
+ function handlePillSelect(item) {
1880
+ emit("update:pill", item.id);
1881
+ emit("pill-select", item);
1882
+ }
1883
+ const normalizedSettingsTabs = computed(() => settingsConfig.value?.tabs?.map(normalizeItemInput) ?? []);
1884
+ return (_ctx, _cache) => {
1885
+ const _component_router_link = resolveComponent("router-link");
1886
+ return openBlock(), createElementBlock(Fragment, null, [
1887
+ createElementVNode("header", {
1888
+ ref_key: "headerEl",
1889
+ ref: headerEl,
1890
+ class: normalizeClass(["mint-topbar", `mint-topbar--${config.value.variant}`])
1891
+ }, [createElementVNode("div", _hoisted_1$4, [
1892
+ createElementVNode("div", _hoisted_2$2, [config.value.homePath && (config.value.homePath.startsWith("http") || config.value.homePath.startsWith("/")) ? (openBlock(), createElementBlock("a", {
1893
+ key: 0,
1894
+ href: config.value.homePath,
1895
+ class: "mint-topbar-home-link"
1896
+ }, [unref(isIntegrated) || _ctx.$slots.icon || _ctx.$slots.logo || pluginIcon.value || config.value.logo ? (openBlock(), createElementBlock("span", _hoisted_4$2, [unref(isIntegrated) ? (openBlock(), createBlock(PluginIcon_default, {
1897
+ key: 0,
1898
+ class: "mint-topbar__plugin-icon",
1899
+ icon: unref(plugin)?.icon,
1900
+ color: unref(plugin)?.color,
1901
+ size: "topbar",
1902
+ variant: "solid"
1903
+ }, null, 8, ["icon", "color"])) : renderSlot(_ctx.$slots, "icon", {}, () => [pluginIcon.value ? (openBlock(), createBlock(PluginIcon_default, {
1904
+ key: 0,
1905
+ class: "mint-topbar__plugin-icon",
1906
+ icon: pluginIcon.value.icon,
1907
+ color: pluginIcon.value.color,
1908
+ size: "topbar",
1909
+ variant: "solid"
1910
+ }, null, 8, ["icon", "color"])) : renderSlot(_ctx.$slots, "logo", {}, () => [config.value.logo ? (openBlock(), createElementBlock("div", _hoisted_5$2, [..._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_3$2)) : config.value.homePath ? (openBlock(), createBlock(_component_router_link, {
1911
+ key: 1,
1912
+ to: config.value.homePath,
1913
+ class: "mint-topbar-home-link"
1914
+ }, {
1915
+ default: withCtx(() => [unref(isIntegrated) || _ctx.$slots.icon || _ctx.$slots.logo || pluginIcon.value || config.value.logo ? (openBlock(), createElementBlock("span", _hoisted_6$1, [unref(isIntegrated) ? (openBlock(), createBlock(PluginIcon_default, {
1916
+ key: 0,
1917
+ class: "mint-topbar__plugin-icon",
1918
+ icon: unref(plugin)?.icon,
1919
+ color: unref(plugin)?.color,
1920
+ size: "topbar",
1921
+ variant: "solid"
1922
+ }, null, 8, ["icon", "color"])) : renderSlot(_ctx.$slots, "icon", {}, () => [pluginIcon.value ? (openBlock(), createBlock(PluginIcon_default, {
1923
+ key: 0,
1924
+ class: "mint-topbar__plugin-icon",
1925
+ icon: pluginIcon.value.icon,
1926
+ color: pluginIcon.value.color,
1927
+ size: "topbar",
1928
+ variant: "solid"
1929
+ }, null, 8, ["icon", "color"])) : renderSlot(_ctx.$slots, "logo", {}, () => [config.value.logo ? (openBlock(), createElementBlock("div", _hoisted_7$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)]),
1930
+ _: 3
1931
+ }, 8, ["to"])) : (openBlock(), createElementBlock(Fragment, { key: 2 }, [unref(isIntegrated) || _ctx.$slots.icon || _ctx.$slots.logo || pluginIcon.value || config.value.logo ? (openBlock(), createElementBlock("span", _hoisted_8$1, [unref(isIntegrated) ? (openBlock(), createBlock(PluginIcon_default, {
1932
+ key: 0,
1933
+ class: "mint-topbar__plugin-icon",
1934
+ icon: unref(plugin)?.icon,
1935
+ color: unref(plugin)?.color,
1936
+ size: "topbar",
1937
+ variant: "solid"
1938
+ }, null, 8, ["icon", "color"])) : renderSlot(_ctx.$slots, "icon", {}, () => [pluginIcon.value ? (openBlock(), createBlock(PluginIcon_default, {
1939
+ key: 0,
1940
+ class: "mint-topbar__plugin-icon",
1941
+ icon: pluginIcon.value.icon,
1942
+ color: pluginIcon.value.color,
1943
+ size: "topbar",
1944
+ variant: "solid"
1945
+ }, null, 8, ["icon", "color"])) : renderSlot(_ctx.$slots, "logo", {}, () => [config.value.logo ? (openBlock(), createElementBlock("div", _hoisted_9$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))]),
1946
+ identityName.value ? (openBlock(), createElementBlock("span", _hoisted_10$1, [createElementVNode("span", _hoisted_11$1, toDisplayString(identityName.value), 1)])) : createCommentVNode("", true),
1947
+ hasPlatformPageSelector.value ? (openBlock(), createElementBlock("span", {
1948
+ key: 1,
1949
+ ref_key: "platformPageSelectorEl",
1950
+ ref: platformPageSelectorEl,
1951
+ class: "mint-topbar__platform-page-selector"
1952
+ }, null, 512)) : hasPropPageSelector.value ? (openBlock(), createBlock(AppTopBarPageSelectorInternal_default, {
1953
+ key: 2,
1954
+ pages: normalizedPageSelector.value,
1955
+ "current-page-id": __props.currentPageSelectorId,
1956
+ onSelect: _cache[0] || (_cache[0] = ($event) => emit("page-selector-select", $event))
1957
+ }, createSlots({ _: 2 }, [_ctx.$slots["page-selector-icon"] ? {
1958
+ name: "icon",
1959
+ fn: withCtx((slotProps) => [renderSlot(_ctx.$slots, "page-selector-icon", normalizeProps(guardReactiveProps(slotProps)))]),
1960
+ key: "0"
1961
+ } : void 0, _ctx.$slots["page-selector-item-icon"] ? {
1962
+ name: "item-icon",
1963
+ fn: withCtx((slotProps) => [renderSlot(_ctx.$slots, "page-selector-item-icon", normalizeProps(guardReactiveProps(slotProps)))]),
1964
+ key: "1"
1965
+ } : void 0]), 1032, ["pages", "current-page-id"])) : createCommentVNode("", true),
1966
+ hasTitleGroup.value ? (openBlock(), createElementBlock("div", _hoisted_12$1, [createElementVNode("span", _hoisted_13$1, toDisplayString(__props.title), 1), createElementVNode("span", _hoisted_14$1, toDisplayString(__props.subtitle), 1)])) : hasTitleOnly.value ? (openBlock(), createElementBlock("span", _hoisted_15$1, toDisplayString(__props.title), 1)) : createCommentVNode("", true),
1967
+ renderSlot(_ctx.$slots, "nav"),
1968
+ hasPillNav.value || _ctx.$slots.center ? (openBlock(), createElementBlock("div", _hoisted_16$1, [renderSlot(_ctx.$slots, "center", {}, () => [hasPillNav.value ? (openBlock(), createBlock(AppTopBarPillNavInternal_default, {
1969
+ key: 0,
1970
+ items: normalizedPillNav.value,
1971
+ "current-item-id": __props.pill,
1972
+ onSelect: handlePillSelect,
1973
+ onOptionSelect: _cache[1] || (_cache[1] = (option, item) => emit("pill-option-select", option, item))
1974
+ }, null, 8, ["items", "current-item-id"])) : createCommentVNode("", true)])])) : createCommentVNode("", true),
1975
+ createElementVNode("div", _hoisted_17$1, [
1976
+ config.value.standaloneLabel !== false && isStandalone.value ? (openBlock(), createElementBlock("span", _hoisted_18$1, toDisplayString(config.value.standaloneLabel), 1)) : createCommentVNode("", true),
1977
+ unref(appExperiment) && !isStandalone.value && canBindExperiment.value ? (openBlock(), createBlock(unref(ExperimentPopover), mergeProps({ key: 1 }, unref(appExperiment).popover.value, {
1978
+ onSelect: _cache[2] || (_cache[2] = ($event) => unref(appExperiment).openModal()),
1979
+ onSave: _cache[3] || (_cache[3] = ($event) => unref(appExperiment).handleSave()),
1980
+ onDetach: _cache[4] || (_cache[4] = ($event) => unref(appExperiment).handleDetach())
1981
+ }), null, 16)) : createCommentVNode("", true),
1982
+ renderSlot(_ctx.$slots, "actions"),
1983
+ config.value.themeToggle ? (openBlock(), createBlock(ThemeToggle_default, {
1984
+ key: 2,
1985
+ size: "sm"
1986
+ })) : createCommentVNode("", true),
1987
+ showSettings.value ? (openBlock(), createElementBlock("button", {
1988
+ key: 3,
1989
+ type: "button",
1990
+ class: "mint-topbar__settings-btn",
1991
+ "aria-label": "Open settings",
1992
+ onClick: _cache[5] || (_cache[5] = ($event) => settingsOpen.value = true)
1993
+ }, [..._cache[12] || (_cache[12] = [createElementVNode("svg", {
1994
+ class: "mint-topbar__settings-icon",
1995
+ viewBox: "0 0 24 24",
1996
+ fill: "none",
1997
+ stroke: "currentColor",
1998
+ "stroke-width": "2",
1999
+ "stroke-linecap": "round",
2000
+ "stroke-linejoin": "round"
2001
+ }, [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", {
2002
+ cx: "12",
2003
+ cy: "12",
2004
+ r: "3"
2005
+ })], -1)])])) : createCommentVNode("", true),
2006
+ renderSlot(_ctx.$slots, "account")
2007
+ ])
2008
+ ])], 2),
2009
+ showSettings.value && settingsOpen.value ? (openBlock(), createBlock(unref(SettingsModal), {
2010
+ key: 0,
2011
+ open: settingsOpen.value,
2012
+ "onUpdate:open": _cache[6] || (_cache[6] = ($event) => settingsOpen.value = $event),
2013
+ title: settingsConfig.value?.title,
2014
+ tabs: normalizedSettingsTabs.value,
2015
+ "show-appearance": settingsConfig.value?.showAppearance ?? true,
2016
+ "appearance-first": settingsConfig.value?.appearanceFirst,
2017
+ size: settingsConfig.value?.size,
2018
+ layout: settingsConfig.value?.layout,
2019
+ spec: settingsConfig.value?.spec,
2020
+ values: settingsConfig.value?.values,
2021
+ "user-type": settingsConfig.value?.userType,
2022
+ "onUpdate:values": _cache[7] || (_cache[7] = ($event) => emit("settings-values-change", $event))
2023
+ }, createSlots({
2024
+ appearance: withCtx(() => [renderSlot(_ctx.$slots, "settings-appearance")]),
2025
+ _: 2
2026
+ }, [renderList(normalizedSettingsTabs.value, (tab) => {
2027
+ return {
2028
+ name: `tab-${tab.id}`,
2029
+ fn: withCtx(() => [renderSlot(_ctx.$slots, `settings-tab-${tab.id}`)])
2030
+ };
2031
+ })]), 1032, [
2032
+ "open",
2033
+ "title",
2034
+ "tabs",
2035
+ "show-appearance",
2036
+ "appearance-first",
2037
+ "size",
2038
+ "layout",
2039
+ "spec",
2040
+ "values",
2041
+ "user-type"
2042
+ ])) : createCommentVNode("", true),
2043
+ 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)
2044
+ ], 64);
2045
+ };
2046
+ }
2047
+ });
2048
+ //#endregion
2049
+ //#region src/composables/useFormValidation.ts
2050
+ var validators = {
2051
+ required: (value, message = "This field is required") => {
2052
+ if (value === null || value === void 0 || value === "") return message;
2053
+ if (Array.isArray(value) && value.length === 0) return message;
2054
+ return null;
2055
+ },
2056
+ minLength: (value, min, message) => {
2057
+ if (typeof value !== "string") return null;
2058
+ if (value.length < min) return message || `Must be at least ${min} characters`;
2059
+ return null;
2060
+ },
2061
+ maxLength: (value, max, message) => {
2062
+ if (typeof value !== "string") return null;
2063
+ if (value.length > max) return message || `Must be at most ${max} characters`;
2064
+ return null;
2065
+ },
2066
+ min: (value, min, message) => {
2067
+ if (typeof value !== "number") return null;
2068
+ if (value < min) return message || `Must be at least ${min}`;
2069
+ return null;
2070
+ },
2071
+ max: (value, max, message) => {
2072
+ if (typeof value !== "number") return null;
2073
+ if (value > max) return message || `Must be at most ${max}`;
2074
+ return null;
2075
+ },
2076
+ pattern: (value, pattern, message) => {
2077
+ if (typeof value !== "string") return null;
2078
+ if (!pattern.test(value)) return message || "Invalid format";
2079
+ return null;
2080
+ },
2081
+ email: (value, message = "Invalid email address") => {
2082
+ if (typeof value !== "string" || !value) return null;
2083
+ if (!/^[^\s@]+@[^\s@]+\.[^\s@]+$/.test(value)) return message;
2084
+ return null;
2085
+ }
2086
+ };
2087
+ function validateFieldValue(value, fieldRules, formData) {
2088
+ if (!fieldRules) return null;
2089
+ if (fieldRules.required) {
2090
+ const message = typeof fieldRules.required === "string" ? fieldRules.required : void 0;
2091
+ const error = validators.required(value, message);
2092
+ if (error) return error;
2093
+ }
2094
+ if (value === null || value === void 0 || value === "") return null;
2095
+ if (fieldRules.minLength !== void 0) {
2096
+ const config = typeof fieldRules.minLength === "number" ? {
2097
+ value: fieldRules.minLength,
2098
+ message: void 0
2099
+ } : fieldRules.minLength;
2100
+ const error = validators.minLength(value, config.value, config.message);
2101
+ if (error) return error;
2102
+ }
2103
+ if (fieldRules.maxLength !== void 0) {
2104
+ const config = typeof fieldRules.maxLength === "number" ? {
2105
+ value: fieldRules.maxLength,
2106
+ message: void 0
2107
+ } : fieldRules.maxLength;
2108
+ const error = validators.maxLength(value, config.value, config.message);
2109
+ if (error) return error;
2110
+ }
2111
+ if (fieldRules.min !== void 0) {
2112
+ const config = typeof fieldRules.min === "number" ? {
2113
+ value: fieldRules.min,
2114
+ message: void 0
2115
+ } : fieldRules.min;
2116
+ const error = validators.min(value, config.value, config.message);
2117
+ if (error) return error;
2118
+ }
2119
+ if (fieldRules.max !== void 0) {
2120
+ const config = typeof fieldRules.max === "number" ? {
2121
+ value: fieldRules.max,
2122
+ message: void 0
2123
+ } : fieldRules.max;
2124
+ const error = validators.max(value, config.value, config.message);
2125
+ if (error) return error;
2126
+ }
2127
+ if (fieldRules.pattern !== void 0) {
2128
+ const config = fieldRules.pattern instanceof RegExp ? {
2129
+ value: fieldRules.pattern,
2130
+ message: void 0
2131
+ } : fieldRules.pattern;
2132
+ const error = validators.pattern(value, config.value, config.message);
2133
+ if (error) return error;
2134
+ }
2135
+ if (fieldRules.email) {
2136
+ const message = typeof fieldRules.email === "string" ? fieldRules.email : void 0;
2137
+ const error = validators.email(value, message);
2138
+ if (error) return error;
2139
+ }
2140
+ if (fieldRules.custom) {
2141
+ const customRules = Array.isArray(fieldRules.custom) ? fieldRules.custom : [fieldRules.custom];
2142
+ for (const rule of customRules) {
2143
+ const error = rule(value, formData);
2144
+ if (error) return error;
2145
+ }
2146
+ }
2147
+ return null;
2148
+ }
2149
+ //#endregion
2150
+ //#region src/composables/useForm.ts
2151
+ /**
2152
+ * Form state management composable with validation.
2153
+ *
2154
+ * @param initialValues - Initial form values
2155
+ * @param rules - Validation rules for each field
2156
+ *
2157
+ * @example
2158
+ * ```typescript
2159
+ * const { data, errors, isValid, handleSubmit, getFieldProps } = useForm(
2160
+ * { email: '', password: '' },
2161
+ * {
2162
+ * email: { required: true, email: true },
2163
+ * password: { required: true, minLength: 8 },
2164
+ * }
2165
+ * )
2166
+ *
2167
+ * // In template
2168
+ * <BaseInput v-bind="getFieldProps('email')" label="Email" />
2169
+ * <BaseInput v-bind="getFieldProps('password')" type="password" label="Password" />
2170
+ * <BaseButton @click="handleSubmit(onSubmit)" :disabled="!isValid">Submit</BaseButton>
2171
+ * ```
2172
+ */
2173
+ /** Reactive form state with field-level validation, dirty tracking, and submit handling. */
2174
+ function useForm(initialValues, rules = {}) {
2175
+ const cloneableInitialValues = deepToRaw(initialValues);
2176
+ let _initialValues = structuredClone(cloneableInitialValues);
2177
+ const data = reactive(structuredClone(cloneableInitialValues));
2178
+ const errors = reactive(Object.keys(initialValues).reduce((acc, key) => {
2179
+ acc[key] = null;
2180
+ return acc;
2181
+ }, {}));
2182
+ const touched = reactive(Object.keys(initialValues).reduce((acc, key) => {
2183
+ acc[key] = false;
2184
+ return acc;
2185
+ }, {}));
2186
+ const dirty = reactive(Object.keys(initialValues).reduce((acc, key) => {
2187
+ acc[key] = false;
2188
+ return acc;
2189
+ }, {}));
2190
+ const isSubmitting = ref(false);
2191
+ watch(() => ({ ...data }), (newData) => {
2192
+ for (const key of Object.keys(newData)) dirty[key] = newData[key] !== _initialValues[key];
2193
+ }, { deep: true });
2194
+ function validateField(field) {
2195
+ const value = data[field];
2196
+ const fieldRules = rules[field];
2197
+ const error = validateFieldValue(value, fieldRules, data);
2198
+ errors[field] = error;
2199
+ return error === null;
2200
+ }
2201
+ function validate() {
2202
+ let isAllValid = true;
2203
+ for (const field of Object.keys(data)) if (!validateField(field)) isAllValid = false;
2204
+ return isAllValid;
2205
+ }
2206
+ const isValid = computed(() => {
2207
+ return Object.values(errors).every((error) => error === null);
2208
+ });
2209
+ const isDirty = computed(() => {
2210
+ return Object.values(dirty).some((d) => d);
2211
+ });
2212
+ function setFieldValue(field, value) {
2213
+ data[field] = value;
2214
+ if (touched[field]) validateField(field);
2215
+ }
2216
+ function setFieldError(field, error) {
2217
+ errors[field] = error;
2218
+ }
2219
+ function setFieldTouched(field, isTouched = true) {
2220
+ touched[field] = isTouched;
2221
+ if (isTouched) validateField(field);
2222
+ }
2223
+ function reset(values) {
2224
+ const resetValues = values ? {
2225
+ ..._initialValues,
2226
+ ...values
2227
+ } : _initialValues;
2228
+ for (const key of Object.keys(data)) {
2229
+ data[key] = structuredClone(deepToRaw(resetValues[key]));
2230
+ errors[key] = null;
2231
+ touched[key] = false;
2232
+ dirty[key] = false;
2233
+ }
2234
+ }
2235
+ function replaceState(values) {
2236
+ const nextValues = structuredClone(deepToRaw(values));
2237
+ _initialValues = structuredClone(nextValues);
2238
+ for (const key of Object.keys(data)) {
2239
+ if (key in nextValues) continue;
2240
+ delete data[key];
2241
+ delete errors[key];
2242
+ delete touched[key];
2243
+ delete dirty[key];
2244
+ }
2245
+ for (const key of Object.keys(nextValues)) {
2246
+ data[key] = structuredClone(deepToRaw(nextValues[key]));
2247
+ errors[key] = null;
2248
+ touched[key] = false;
2249
+ dirty[key] = false;
2250
+ }
2251
+ }
2252
+ function handleSubmit(onSubmit) {
2253
+ return async (e) => {
2254
+ e?.preventDefault();
2255
+ for (const field of Object.keys(data)) touched[field] = true;
2256
+ if (!validate()) return;
2257
+ isSubmitting.value = true;
2258
+ try {
2259
+ await onSubmit(data);
2260
+ } finally {
2261
+ isSubmitting.value = false;
2262
+ }
2263
+ };
2264
+ }
2265
+ function getFieldProps(field) {
2266
+ const fieldStr = field;
2267
+ return {
2268
+ modelValue: data[field],
2269
+ "onUpdate:modelValue": (value) => setFieldValue(field, value),
2270
+ onBlur: () => setFieldTouched(fieldStr),
2271
+ error: touched[fieldStr] ? errors[fieldStr] : null
2272
+ };
2273
+ }
2274
+ return {
2275
+ data,
2276
+ errors,
2277
+ touched,
2278
+ dirty,
2279
+ isValid,
2280
+ isDirty,
2281
+ isSubmitting,
2282
+ setFieldValue,
2283
+ setFieldError,
2284
+ setFieldTouched,
2285
+ validateField,
2286
+ validate,
2287
+ reset,
2288
+ replaceState,
2289
+ handleSubmit,
2290
+ getFieldProps
2291
+ };
2292
+ }
2293
+ function deepToRaw(value) {
2294
+ const raw = toRaw(value);
2295
+ if (Array.isArray(raw)) return raw.map((item) => deepToRaw(item));
2296
+ if (isPlainRecord(raw)) return Object.fromEntries(Object.entries(raw).map(([key, item]) => [key, deepToRaw(item)]));
2297
+ return raw;
2298
+ }
2299
+ function isPlainRecord(value) {
2300
+ return Object.prototype.toString.call(value) === "[object Object]";
2301
+ }
2302
+ //#endregion
2303
+ //#region src/composables/formBuilderSchema.ts
2304
+ /**
2305
+ * Evaluate a JSON-serializable field condition against the current form data.
2306
+ *
2307
+ * Supports logical operators (`and`, `or`, `not`) and comparison operators
2308
+ * (`eq`, `neq`, `gt`, `lt`, `gte`, `lte`, `in`, `notIn`, `truthy`, `falsy`,
2309
+ * `contains`). Returns `true` if the condition passes.
2310
+ */
2311
+ function evaluateCondition(condition, data) {
2312
+ if ("and" in condition) return condition.and.every((c) => evaluateCondition(c, data));
2313
+ if ("or" in condition) return condition.or.some((c) => evaluateCondition(c, data));
2314
+ if ("not" in condition) return !evaluateCondition(condition.not, data);
2315
+ const value = data[condition.field];
2316
+ if ("eq" in condition) return value === condition.eq;
2317
+ if ("neq" in condition) return value !== condition.neq;
2318
+ if ("gt" in condition) return typeof value === "number" && value > condition.gt;
2319
+ if ("lt" in condition) return typeof value === "number" && value < condition.lt;
2320
+ if ("gte" in condition) return typeof value === "number" && value >= condition.gte;
2321
+ if ("lte" in condition) return typeof value === "number" && value <= condition.lte;
2322
+ if ("in" in condition) return condition.in.includes(value);
2323
+ if ("notIn" in condition) return !condition.notIn.includes(value);
2324
+ if ("truthy" in condition) return !!value;
2325
+ if ("falsy" in condition) return !value;
2326
+ if ("contains" in condition) {
2327
+ if (typeof value === "string") return value.includes(condition.contains);
2328
+ if (Array.isArray(value)) return value.includes(condition.contains);
2329
+ return false;
2330
+ }
2331
+ return true;
2332
+ }
2333
+ /** Return all sections across steps (wizard) or directly from a flat schema. */
2334
+ function collectSections(schema) {
2335
+ return schema.steps ? schema.steps.flatMap((step) => step.sections) : schema.sections;
2336
+ }
2337
+ /** Return all field schemas in schema order, flattening sections and steps. */
2338
+ function flattenFields(schema) {
2339
+ return collectSections(schema).flatMap((section) => section.fields);
2340
+ }
2341
+ /** Convert a JSON-safe `FieldValidation` descriptor to a runtime `FieldRules` object. */
2342
+ function convertValidation(v) {
2343
+ const rules = {};
2344
+ if (v.required !== void 0) rules.required = v.required;
2345
+ if (v.minLength !== void 0) rules.minLength = v.minLength;
2346
+ if (v.maxLength !== void 0) rules.maxLength = v.maxLength;
2347
+ if (v.min !== void 0) rules.min = v.min;
2348
+ if (v.max !== void 0) rules.max = v.max;
2349
+ if (v.email !== void 0) rules.email = v.email;
2350
+ if (v.pattern !== void 0) rules.pattern = typeof v.pattern === "string" ? new RegExp(v.pattern) : {
2351
+ value: new RegExp(v.pattern.value),
2352
+ message: v.pattern.message
2353
+ };
2354
+ return rules;
2355
+ }
2356
+ function buildInitialValues(fields, initialData) {
2357
+ const initialValues = {};
2358
+ for (const field of fields) {
2359
+ const key = field.name;
2360
+ if (initialData && hasOwnKey(initialData, key)) initialValues[key] = initialData[key];
2361
+ else if (field.defaultValue !== void 0) initialValues[key] = field.defaultValue;
2362
+ else initialValues[key] = getTypeDefault(field.type);
2363
+ }
2364
+ return initialValues;
2365
+ }
2366
+ function buildRules(fields, enhancements) {
2367
+ const rules = {};
2368
+ for (const field of fields) {
2369
+ const base = field.validation ? convertValidation(field.validation) : {};
2370
+ const enhancement = enhancements?.fields?.[field.name];
2371
+ const customValidators = [];
2372
+ if (enhancement?.validate) {
2373
+ const fn = enhancement.validate;
2374
+ customValidators.push((value, formData) => fn(value, formData));
2375
+ }
2376
+ if (customValidators.length > 0) base.custom = customValidators;
2377
+ if (Object.keys(base).length > 0) rules[field.name] = base;
2378
+ }
2379
+ return rules;
2380
+ }
2381
+ function replaceArray(target, values) {
2382
+ target.splice(0, target.length, ...values);
2383
+ }
2384
+ function replaceRecord(target, source) {
2385
+ for (const key of Object.keys(target)) delete target[key];
2386
+ Object.assign(target, source);
2387
+ }
2388
+ function hasOwnKey(source, key) {
2389
+ return Object.prototype.hasOwnProperty.call(source, key);
2390
+ }
2391
+ //#endregion
2392
+ //#region src/composables/useFormBuilder.ts
2393
+ /**
2394
+ * Drive a `FormSchema` as reactive form state.
2395
+ *
2396
+ * Builds initial values from schema defaults and `initialData`, derives
2397
+ * validation rules from `FieldValidation` descriptors and enhancement
2398
+ * validators, evaluates `FieldCondition` expressions for field/section
2399
+ * visibility, and wires wizard step navigation when `schema.steps` is set.
2400
+ *
2401
+ * @param schema - Declarative form or wizard schema.
2402
+ * @param initialData - Values that override schema defaults.
2403
+ * @param enhancements - TypeScript-only callbacks (dynamic options, validators,
2404
+ * submit handler, transform, field-change watcher).
2405
+ */
2406
+ /** Drives a declarative FormSchema as reactive state with conditional fields, wizard steps, and validation. */
2407
+ function useFormBuilder(schema, initialData, enhancements) {
2408
+ const currentSchema = shallowRef(schema);
2409
+ const fields = reactive(flattenFields(schema));
2410
+ const sections = reactive(collectSections(schema));
2411
+ const rules = reactive(buildRules(fields, enhancements));
2412
+ const form = useForm(buildInitialValues(fields, initialData), rules);
2413
+ function isFieldVisible(name) {
2414
+ const enhancement = enhancements?.fields?.[name];
2415
+ if (enhancement?.visible) return enhancement.visible(form.data);
2416
+ const field = fields.find((f) => f.name === name);
2417
+ if (field?.condition) return evaluateCondition(field.condition, form.data);
2418
+ return true;
2419
+ }
2420
+ function isSectionVisible(id) {
2421
+ const section = sections.find((s) => s.id === id);
2422
+ if (section?.condition) return evaluateCondition(section.condition, form.data);
2423
+ return true;
2424
+ }
2425
+ function getResolvedFieldProps(field) {
2426
+ const entry = getFieldRegistryEntry(field.type);
2427
+ const formProps = form.getFieldProps(field.name);
2428
+ const merged = {
2429
+ ...entry.defaults,
2430
+ ...field.props ?? {}
2431
+ };
2432
+ const enhancement = enhancements?.fields?.[field.name];
2433
+ if (enhancement?.props) Object.assign(merged, enhancement.props(form.data));
2434
+ const options = getFieldOptions(field.name);
2435
+ if (options) merged.options = options;
2436
+ if (entry.vModel) {
2437
+ merged.modelValue = formProps.modelValue;
2438
+ merged["onUpdate:modelValue"] = formProps["onUpdate:modelValue"];
2439
+ }
2440
+ merged.onBlur = formProps.onBlur;
2441
+ if (formProps.error) merged.invalid = true;
2442
+ if (field.placeholder) merged.placeholder = field.placeholder;
2443
+ if (field.size) merged.size = field.size;
2444
+ if (field.disabled) merged.disabled = true;
2445
+ if (field.readonly) merged.readonly = true;
2446
+ if (field.type === "radio" && !merged.name) merged.name = field.name;
2447
+ return merged;
2448
+ }
2449
+ function getFieldOptions(name) {
2450
+ const enhancement = enhancements?.fields?.[name];
2451
+ if (enhancement?.options) return enhancement.options(form.data);
2452
+ const field = fields.find((f) => f.name === name);
2453
+ if (field?.props?.options) return field.props.options;
2454
+ }
2455
+ const currentStep = ref(0);
2456
+ const isCurrentStepValid = computed(() => {
2457
+ if (!currentSchema.value.steps) return form.isValid.value;
2458
+ const step = currentSchema.value.steps[currentStep.value];
2459
+ if (!step) return true;
2460
+ for (const section of step.sections) {
2461
+ if (!isSectionVisible(section.id)) continue;
2462
+ for (const field of section.fields) {
2463
+ if (!isFieldVisible(field.name)) continue;
2464
+ if (!form.validateField(field.name)) return false;
2465
+ }
2466
+ }
2467
+ return true;
2468
+ });
2469
+ function goNext() {
2470
+ if (!currentSchema.value.steps) return false;
2471
+ const step = currentSchema.value.steps[currentStep.value];
2472
+ if (!step) return false;
2473
+ let valid = true;
2474
+ for (const section of step.sections) {
2475
+ if (!isSectionVisible(section.id)) continue;
2476
+ for (const field of section.fields) {
2477
+ if (!isFieldVisible(field.name)) continue;
2478
+ form.setFieldTouched(field.name, true);
2479
+ if (!form.validateField(field.name)) valid = false;
2480
+ }
2481
+ }
2482
+ if (!valid) return false;
2483
+ if (currentStep.value < currentSchema.value.steps.length - 1) currentStep.value++;
2484
+ return true;
2485
+ }
2486
+ function goBack() {
2487
+ if (currentStep.value > 0) currentStep.value--;
2488
+ }
2489
+ function goToStep(index) {
2490
+ if (!currentSchema.value.steps) return;
2491
+ if (index >= 0 && index < currentSchema.value.steps.length) currentStep.value = index;
2492
+ }
2493
+ function validate() {
2494
+ let allValid = true;
2495
+ for (const field of fields) {
2496
+ if (!isFieldVisible(field.name)) continue;
2497
+ form.setFieldTouched(field.name, true);
2498
+ if (!form.validateField(field.name)) allValid = false;
2499
+ }
2500
+ return allValid;
2501
+ }
2502
+ async function submit() {
2503
+ if (!validate()) return;
2504
+ let submitData = {};
2505
+ for (const field of fields) if (isFieldVisible(field.name)) submitData[field.name] = form.data[field.name];
2506
+ if (enhancements?.transform) submitData = enhancements.transform(submitData);
2507
+ if (enhancements?.onSubmit) {
2508
+ form.isSubmitting.value = true;
2509
+ try {
2510
+ await enhancements.onSubmit(submitData);
2511
+ } finally {
2512
+ form.isSubmitting.value = false;
2513
+ }
2514
+ }
2515
+ }
2516
+ function reset(values) {
2517
+ form.reset(values);
2518
+ currentStep.value = 0;
2519
+ }
2520
+ function updateSchema(nextSchema, nextData) {
2521
+ currentSchema.value = nextSchema;
2522
+ const nextFields = flattenFields(nextSchema);
2523
+ replaceArray(fields, nextFields);
2524
+ replaceArray(sections, collectSections(nextSchema));
2525
+ replaceRecord(rules, buildRules(nextFields, enhancements));
2526
+ form.replaceState(buildInitialValues(nextFields, nextData));
2527
+ currentStep.value = 0;
2528
+ }
2529
+ if (enhancements?.onFieldChange) {
2530
+ const callback = enhancements.onFieldChange;
2531
+ watch(() => ({ ...form.data }), (newData, oldData) => {
2532
+ if (!oldData) return;
2533
+ for (const key of Object.keys(newData)) if (newData[key] !== oldData[key]) callback(key, newData[key], newData);
2534
+ }, { deep: true });
2535
+ }
2536
+ return {
2537
+ form,
2538
+ rules,
2539
+ isFieldVisible,
2540
+ isSectionVisible,
2541
+ fields,
2542
+ getResolvedFieldProps,
2543
+ getFieldOptions,
2544
+ currentStep,
2545
+ isCurrentStepValid,
2546
+ goNext,
2547
+ goBack,
2548
+ goToStep,
2549
+ validate,
2550
+ reset,
2551
+ submit,
2552
+ updateSchema
2553
+ };
2554
+ }
2555
+ //#endregion
2556
+ //#region src/utils/formModelSync.ts
2557
+ function recordValuesEqualForKeys(left, right, keys) {
2558
+ for (const key of keys) if (!valuesEqual(left[key], right[key])) return false;
2559
+ return true;
2560
+ }
2561
+ function pickRecordKeys(source, keys) {
2562
+ return Object.fromEntries(keys.map((key) => [key, source[key]]));
2563
+ }
2564
+ function pickExistingRecordKeys(source, keys) {
2565
+ return Object.fromEntries(keys.filter((key) => Object.prototype.hasOwnProperty.call(source, key)).map((key) => [key, source[key]]));
2566
+ }
2567
+ function formSchemaFieldNames(schema) {
2568
+ return (schema.steps ? schema.steps.flatMap((step) => step.sections) : schema.sections).flatMap((section) => section.fields.map((field) => field.name));
2569
+ }
2570
+ function valuesEqual(left, right) {
2571
+ if (Object.is(left, right)) return true;
2572
+ if (Array.isArray(left) && Array.isArray(right)) return left.length === right.length && left.every((item, index) => valuesEqual(item, right[index]));
2573
+ if (isRecord(left) && isRecord(right)) return recordValuesEqualForKeys(left, right, [.../* @__PURE__ */ new Set([...Object.keys(left), ...Object.keys(right)])]);
2574
+ return false;
2575
+ }
2576
+ //#endregion
2577
+ //#region src/components/internal/FormFieldRendererInternal.vue
2578
+ var FormFieldRendererInternal_default = /* @__PURE__ */ defineComponent({
2579
+ __name: "FormFieldRendererInternal",
2580
+ props: {
2581
+ field: {},
2582
+ resolvedProps: {},
2583
+ form: {}
2584
+ },
2585
+ setup(__props) {
2586
+ const props = __props;
2587
+ const entry = computed(() => getFieldRegistryEntry(props.field.type));
2588
+ const isChoiceField = computed(() => props.field.type === "checkbox" || props.field.type === "toggle");
2589
+ const componentProps = computed(() => {
2590
+ if (props.field.type === "multiselect") {
2591
+ const values = Array.isArray(props.resolvedProps.modelValue) ? props.resolvedProps.modelValue : [];
2592
+ return {
2593
+ ...props.resolvedProps,
2594
+ modelValue: values
2595
+ };
2596
+ }
2597
+ if (props.field.type === "tags") {
2598
+ const values = Array.isArray(props.resolvedProps.modelValue) ? props.resolvedProps.modelValue : [];
2599
+ const onUpdate = props.resolvedProps["onUpdate:modelValue"];
2600
+ return {
2601
+ ...props.resolvedProps,
2602
+ modelValue: values.map(String),
2603
+ "onUpdate:modelValue": (next) => onUpdate?.(props.field.itemType === "number" && Array.isArray(next) ? next.map(Number) : next)
2604
+ };
2605
+ }
2606
+ if (!isChoiceField.value) return props.resolvedProps;
2607
+ return {
2608
+ layout: "row",
2609
+ label: props.field.label,
2610
+ description: props.field.hint,
2611
+ icon: props.field.icon,
2612
+ iconColor: props.field.iconColor,
2613
+ iconBg: props.field.iconBg,
2614
+ ...props.resolvedProps
2615
+ };
2616
+ });
2617
+ const errorMessage = computed(() => {
2618
+ const name = props.field.name;
2619
+ return props.form.touched[name] ? props.form.errors[name] : null;
2620
+ });
2621
+ function handleUpload(files) {
2622
+ props.form.setFieldValue(props.field.name, files);
2623
+ }
2624
+ return (_ctx, _cache) => {
2625
+ return openBlock(), createBlock(FormField_default, {
2626
+ label: isChoiceField.value ? void 0 : __props.field.label,
2627
+ error: errorMessage.value ?? void 0,
2628
+ hint: isChoiceField.value ? void 0 : __props.field.hint,
2629
+ required: !!__props.field.validation?.required,
2630
+ "html-for": isChoiceField.value ? void 0 : __props.field.name
2631
+ }, {
2632
+ default: withCtx(() => [renderSlot(_ctx.$slots, `field:${__props.field.name}`, {
2633
+ field: __props.field,
2634
+ form: __props.form,
2635
+ fieldProps: __props.form.getFieldProps(__props.field.name)
2636
+ }, () => [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))])]),
2637
+ _: 3
2638
+ }, 8, [
2639
+ "label",
2640
+ "error",
2641
+ "hint",
2642
+ "required",
2643
+ "html-for"
2644
+ ]);
2645
+ };
2646
+ }
2647
+ });
2648
+ //#endregion
2649
+ //#region src/components/internal/FormSectionRenderer.vue?vue&type=script&setup=true&lang.ts
2650
+ var _hoisted_1$3 = {
2651
+ key: 0,
2652
+ class: "mint-form-section"
2653
+ };
2654
+ var _hoisted_2$1 = {
2655
+ key: 1,
2656
+ class: "mint-form-section--static"
2657
+ };
2658
+ var _hoisted_3$1 = {
2659
+ key: 0,
2660
+ class: "mint-form-section__header"
2661
+ };
2662
+ var _hoisted_4$1 = {
2663
+ key: 0,
2664
+ class: "mint-form-section__title"
2665
+ };
2666
+ var _hoisted_5$1 = {
2667
+ key: 1,
2668
+ class: "mint-form-section__description"
2669
+ };
2670
+ //#endregion
2671
+ //#region src/components/internal/FormSectionRenderer.vue
2672
+ var FormSectionRenderer_default = /* @__PURE__ */ defineComponent({
2673
+ __name: "FormSectionRenderer",
2674
+ props: {
2675
+ section: {},
2676
+ builder: {}
2677
+ },
2678
+ setup(__props) {
2679
+ const props = __props;
2680
+ const visibleFields = computed(() => props.section.fields.filter((f) => props.builder.isFieldVisible(f.name)));
2681
+ const gridStyle = computed(() => ({ gridTemplateColumns: `repeat(${props.section.columns ?? 1}, 1fr)` }));
2682
+ return (_ctx, _cache) => {
2683
+ return visibleFields.value.length > 0 ? (openBlock(), createElementBlock("div", _hoisted_1$3, [renderSlot(_ctx.$slots, `section:${__props.section.id}`, {
2684
+ section: __props.section,
2685
+ form: __props.builder.form
2686
+ }, () => [__props.section.collapsible ? (openBlock(), createBlock(CollapsibleCard_default, {
2687
+ key: 0,
2688
+ title: __props.section.title,
2689
+ subtitle: __props.section.description,
2690
+ "default-open": __props.section.defaultOpen ?? true
2691
+ }, {
2692
+ default: withCtx(() => [createElementVNode("div", {
2693
+ class: "mint-form-section__grid",
2694
+ style: normalizeStyle(gridStyle.value)
2695
+ }, [(openBlock(true), createElementBlock(Fragment, null, renderList(visibleFields.value, (field) => {
2696
+ return openBlock(), createElementBlock("div", {
2697
+ key: field.name,
2698
+ style: normalizeStyle(field.colSpan ? { gridColumn: `span ${field.colSpan}` } : void 0)
2699
+ }, [renderSlot(_ctx.$slots, `field:${field.name}`, {
2700
+ field,
2701
+ form: __props.builder.form,
2702
+ fieldProps: __props.builder.form.getFieldProps(field.name)
2703
+ }, () => [createVNode(FormFieldRendererInternal_default, {
2704
+ field,
2705
+ "resolved-props": __props.builder.getResolvedFieldProps(field),
2706
+ form: __props.builder.form
2707
+ }, null, 8, [
2708
+ "field",
2709
+ "resolved-props",
2710
+ "form"
2711
+ ])])], 4);
2712
+ }), 128))], 4)]),
2713
+ _: 3
2714
+ }, 8, [
2715
+ "title",
2716
+ "subtitle",
2717
+ "default-open"
2718
+ ])) : (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", {
2719
+ class: "mint-form-section__grid",
2720
+ style: normalizeStyle(gridStyle.value)
2721
+ }, [(openBlock(true), createElementBlock(Fragment, null, renderList(visibleFields.value, (field) => {
2722
+ return openBlock(), createElementBlock("div", {
2723
+ key: field.name,
2724
+ style: normalizeStyle(field.colSpan ? { gridColumn: `span ${field.colSpan}` } : void 0)
2725
+ }, [renderSlot(_ctx.$slots, `field:${field.name}`, {
2726
+ field,
2727
+ form: __props.builder.form,
2728
+ fieldProps: __props.builder.form.getFieldProps(field.name)
2729
+ }, () => [createVNode(FormFieldRendererInternal_default, {
2730
+ field,
2731
+ "resolved-props": __props.builder.getResolvedFieldProps(field),
2732
+ form: __props.builder.form
2733
+ }, null, 8, [
2734
+ "field",
2735
+ "resolved-props",
2736
+ "form"
2737
+ ])])], 4);
2738
+ }), 128))], 4)]))]), renderSlot(_ctx.$slots, `section:${__props.section.id}:after`, { form: __props.builder.form })])) : createCommentVNode("", true);
2739
+ };
2740
+ }
2741
+ });
2742
+ //#endregion
2743
+ //#region src/components/internal/FormActionsInternal.vue?vue&type=script&setup=true&lang.ts
2744
+ var _hoisted_1$2 = { class: "mint-form-actions" };
2745
+ //#endregion
2746
+ //#region src/components/internal/FormActionsInternal.vue
2747
+ var FormActionsInternal_default = /* @__PURE__ */ defineComponent({
2748
+ __name: "FormActionsInternal",
2749
+ props: {
2750
+ isWizard: {
2751
+ type: Boolean,
2752
+ default: false
2753
+ },
2754
+ isFirst: {
2755
+ type: Boolean,
2756
+ default: true
2757
+ },
2758
+ isLast: {
2759
+ type: Boolean,
2760
+ default: true
2761
+ },
2762
+ canProceed: {
2763
+ type: Boolean,
2764
+ default: true
2765
+ },
2766
+ loading: {
2767
+ type: Boolean,
2768
+ default: false
2769
+ },
2770
+ disabled: {
2771
+ type: Boolean,
2772
+ default: false
2773
+ },
2774
+ submitLabel: { default: "Submit" },
2775
+ cancelLabel: { default: "Cancel" },
2776
+ showCancel: {
2777
+ type: Boolean,
2778
+ default: false
2779
+ }
2780
+ },
2781
+ emits: [
2782
+ "submit",
2783
+ "cancel",
2784
+ "back",
2785
+ "next"
2786
+ ],
2787
+ setup(__props, { emit: __emit }) {
2788
+ /**
2789
+ * Action bar rendered at the bottom of a FormBuilder (`actions` in the control model).
2790
+ *
2791
+ * Supports two modes:
2792
+ * - Flat form: shows an optional Cancel button and a Submit button.
2793
+ * - Wizard (`isWizard=true`): shows Back / Next on intermediate steps and
2794
+ * Submit only on the last step. Back is hidden on the first step.
2795
+ *
2796
+ * The `canProceed` prop gates the primary action (Next or Submit) to prevent
2797
+ * advancing when the current step has validation errors.
2798
+ */
2799
+ const emit = __emit;
2800
+ return (_ctx, _cache) => {
2801
+ return openBlock(), createElementBlock("div", _hoisted_1$2, [
2802
+ __props.showCancel ? (openBlock(), createBlock(BaseButton_default, {
2803
+ key: 0,
2804
+ variant: "ghost",
2805
+ disabled: __props.loading || __props.disabled,
2806
+ onClick: _cache[0] || (_cache[0] = ($event) => emit("cancel"))
2807
+ }, {
2808
+ default: withCtx(() => [createTextVNode(toDisplayString(__props.cancelLabel), 1)]),
2809
+ _: 1
2810
+ }, 8, ["disabled"])) : createCommentVNode("", true),
2811
+ _cache[6] || (_cache[6] = createElementVNode("div", { style: { "flex": "1" } }, null, -1)),
2812
+ __props.isWizard && !__props.isFirst ? (openBlock(), createBlock(BaseButton_default, {
2813
+ key: 1,
2814
+ variant: "secondary",
2815
+ disabled: __props.loading || __props.disabled,
2816
+ onClick: _cache[1] || (_cache[1] = ($event) => emit("back"))
2817
+ }, {
2818
+ default: withCtx(() => [..._cache[4] || (_cache[4] = [createTextVNode(" Back ", -1)])]),
2819
+ _: 1
2820
+ }, 8, ["disabled"])) : createCommentVNode("", true),
2821
+ __props.isWizard && !__props.isLast ? (openBlock(), createBlock(BaseButton_default, {
2822
+ key: 2,
2823
+ variant: "primary",
2824
+ disabled: !__props.canProceed || __props.loading || __props.disabled,
2825
+ onClick: _cache[2] || (_cache[2] = ($event) => emit("next"))
2826
+ }, {
2827
+ default: withCtx(() => [..._cache[5] || (_cache[5] = [createTextVNode(" Next ", -1)])]),
2828
+ _: 1
2829
+ }, 8, ["disabled"])) : createCommentVNode("", true),
2830
+ !__props.isWizard || __props.isLast ? (openBlock(), createBlock(BaseButton_default, {
2831
+ key: 3,
2832
+ variant: "primary",
2833
+ loading: __props.loading,
2834
+ disabled: !__props.canProceed || __props.loading || __props.disabled,
2835
+ onClick: _cache[3] || (_cache[3] = ($event) => emit("submit"))
2836
+ }, {
2837
+ default: withCtx(() => [createTextVNode(toDisplayString(__props.submitLabel), 1)]),
2838
+ _: 1
2839
+ }, 8, ["loading", "disabled"])) : createCommentVNode("", true)
2840
+ ]);
2841
+ };
2842
+ }
2843
+ });
2844
+ //#endregion
2845
+ //#region src/components/internal/FormSchemaInternal.vue?vue&type=script&setup=true&lang.ts
2846
+ var _hoisted_1$1 = { class: "mint-form-builder__step" };
2847
+ //#endregion
2848
+ //#region src/components/internal/FormSchemaInternal.vue
2849
+ var FormSchemaInternal_default = /* @__PURE__ */ defineComponent({
2850
+ __name: "FormSchemaInternal",
2851
+ props: {
2852
+ schema: {},
2853
+ defaults: { default: () => ({}) },
2854
+ modelValue: {},
2855
+ enhancements: {},
2856
+ loading: {
2857
+ type: Boolean,
2858
+ default: false
2859
+ },
2860
+ disabled: {
2861
+ type: Boolean,
2862
+ default: false
2863
+ },
2864
+ size: {},
2865
+ readonly: {
2866
+ type: Boolean,
2867
+ default: false
2868
+ }
2869
+ },
2870
+ emits: [
2871
+ "update:modelValue",
2872
+ "submit",
2873
+ "cancel"
2874
+ ],
2875
+ setup(__props, { expose: __expose, emit: __emit }) {
2876
+ /**
2877
+ * FormSchema renderer behind FormBuilder and the sidebar forms: flat sections
2878
+ * or a multi-step wizard, with the action bar when `schema.actions` is set.
2879
+ *
2880
+ * Slots:
2881
+ * - `field:<name>` — override a single field's input component
2882
+ * - `section:<id>` — replace an entire section body
2883
+ * - `section:<id>:after` — inject content after a section
2884
+ * - `actions` — replace the default action bar
2885
+ */
2886
+ const props = __props;
2887
+ const emit = __emit;
2888
+ const resolvedSchema = computed(() => props.schema);
2889
+ const resolvedModelValue = computed(() => ({
2890
+ ...props.defaults,
2891
+ ...props.modelValue ?? {}
2892
+ }));
2893
+ const builder = useFormBuilder(resolvedSchema.value, resolvedModelValue.value, props.enhancements);
2894
+ watch(resolvedSchema, (schema) => {
2895
+ const fieldNames = formSchemaFieldNames(schema);
2896
+ const schemaValues = pickExistingRecordKeys(resolvedModelValue.value, fieldNames);
2897
+ const existingValues = pickExistingRecordKeys(builder.form.data, fieldNames);
2898
+ const nextValues = props.modelValue === void 0 ? {
2899
+ ...schemaValues,
2900
+ ...existingValues
2901
+ } : schemaValues;
2902
+ builder.updateSchema(schema, nextValues);
2903
+ }, { deep: true });
2904
+ watch(() => props.modelValue, () => {
2905
+ const data = resolvedModelValue.value;
2906
+ const fieldNames = builderFieldNames();
2907
+ if (recordValuesEqualForKeys(data, builder.form.data, fieldNames)) return;
2908
+ builder.reset(pickExistingRecordKeys(data, fieldNames));
2909
+ }, { deep: true });
2910
+ watch(() => ({ ...builder.form.data }), (data) => emit("update:modelValue", data), { deep: true });
2911
+ const isWizard = computed(() => !!resolvedSchema.value.steps);
2912
+ const wizardRef = ref(null);
2913
+ const wizardSteps = computed(() => {
2914
+ if (!resolvedSchema.value.steps) return [];
2915
+ return resolvedSchema.value.steps.map((step) => ({
2916
+ id: step.id,
2917
+ label: step.label,
2918
+ description: step.description,
2919
+ icon: step.icon,
2920
+ optional: step.optional
2921
+ }));
2922
+ });
2923
+ watch(() => builder.isCurrentStepValid.value, (valid) => {
2924
+ wizardRef.value?.setStepValid(builder.currentStep.value, valid);
2925
+ });
2926
+ function handleNext() {
2927
+ if (builder.goNext()) wizardRef.value?.setStepValid(builder.currentStep.value - 1, true);
2928
+ }
2929
+ async function handleSubmit() {
2930
+ await builder.submit();
2931
+ const formData = builder.form.data;
2932
+ const visibleData = Object.fromEntries(builder.fields.filter((f) => builder.isFieldVisible(f.name)).map((f) => [f.name, formData[f.name]]));
2933
+ emit("submit", visibleData);
2934
+ }
2935
+ function handleCancel() {
2936
+ emit("cancel");
2937
+ }
2938
+ function builderFieldNames() {
2939
+ return builder.fields.map((field) => field.name);
2940
+ }
2941
+ __expose({
2942
+ form: builder.form,
2943
+ validate: builder.validate,
2944
+ reset: builder.reset,
2945
+ updateSchema: builder.updateSchema,
2946
+ goNext: builder.goNext,
2947
+ goBack: builder.goBack,
2948
+ goToStep: builder.goToStep,
2949
+ builder
2950
+ });
2951
+ return (_ctx, _cache) => {
2952
+ 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, {
2953
+ key: 0,
2954
+ ref_key: "wizardRef",
2955
+ ref: wizardRef,
2956
+ steps: wizardSteps.value,
2957
+ "model-value": unref(builder).currentStep.value,
2958
+ "onUpdate:modelValue": _cache[0] || (_cache[0] = ($event) => unref(builder).goToStep($event))
2959
+ }, createSlots({ _: 2 }, [renderList(resolvedSchema.value.steps, (step) => {
2960
+ return {
2961
+ name: `step-${step.id}`,
2962
+ fn: withCtx(() => [createElementVNode("div", _hoisted_1$1, [(openBlock(true), createElementBlock(Fragment, null, renderList(step.sections, (section) => {
2963
+ return openBlock(), createElementBlock(Fragment, { key: section.id }, [unref(builder).isSectionVisible(section.id) ? (openBlock(), createBlock(FormSectionRenderer_default, {
2964
+ key: 0,
2965
+ section,
2966
+ builder: unref(builder)
2967
+ }, createSlots({
2968
+ [`section:${section.id}`]: withCtx((slotProps) => [renderSlot(_ctx.$slots, `section:${section.id}`, mergeProps({ ref_for: true }, slotProps))]),
2969
+ [`section:${section.id}:after`]: withCtx((slotProps) => [renderSlot(_ctx.$slots, `section:${section.id}:after`, mergeProps({ ref_for: true }, slotProps))]),
2970
+ _: 2
2971
+ }, [renderList(section.fields, (field) => {
2972
+ return {
2973
+ name: `field:${field.name}`,
2974
+ fn: withCtx((slotProps) => [renderSlot(_ctx.$slots, `field:${field.name}`, mergeProps({ ref_for: true }, slotProps))])
2975
+ };
2976
+ })]), 1032, ["section", "builder"])) : createCommentVNode("", true)], 64);
2977
+ }), 128))])])
2978
+ };
2979
+ }), resolvedSchema.value.actions ? {
2980
+ name: "navigation",
2981
+ fn: withCtx(({ isFirst, isLast }) => [renderSlot(_ctx.$slots, "actions", {
2982
+ form: unref(builder).form,
2983
+ builder: unref(builder)
2984
+ }, () => [createVNode(FormActionsInternal_default, {
2985
+ "is-wizard": "",
2986
+ "is-first": isFirst,
2987
+ "is-last": isLast,
2988
+ "can-proceed": unref(builder).isCurrentStepValid.value,
2989
+ loading: __props.loading || unref(builder).form.isSubmitting.value,
2990
+ disabled: __props.disabled,
2991
+ "submit-label": resolvedSchema.value.submitLabel ?? "Submit",
2992
+ "cancel-label": resolvedSchema.value.cancelLabel ?? "Cancel",
2993
+ "show-cancel": resolvedSchema.value.showCancel ?? false,
2994
+ onNext: handleNext,
2995
+ onBack: unref(builder).goBack,
2996
+ onSubmit: handleSubmit,
2997
+ onCancel: handleCancel
2998
+ }, null, 8, [
2999
+ "is-first",
3000
+ "is-last",
3001
+ "can-proceed",
3002
+ "loading",
3003
+ "disabled",
3004
+ "submit-label",
3005
+ "cancel-label",
3006
+ "show-cancel",
3007
+ "onBack"
3008
+ ])])]),
3009
+ key: "0"
3010
+ } : void 0]), 1032, ["steps", "model-value"])) : resolvedSchema.value.sections ? (openBlock(), createElementBlock(Fragment, { key: 1 }, [(openBlock(true), createElementBlock(Fragment, null, renderList(resolvedSchema.value.sections, (section) => {
3011
+ return openBlock(), createElementBlock(Fragment, { key: section.id }, [unref(builder).isSectionVisible(section.id) ? (openBlock(), createBlock(FormSectionRenderer_default, {
3012
+ key: 0,
3013
+ section,
3014
+ builder: unref(builder)
3015
+ }, createSlots({
3016
+ [`section:${section.id}`]: withCtx((slotProps) => [renderSlot(_ctx.$slots, `section:${section.id}`, mergeProps({ ref_for: true }, slotProps))]),
3017
+ [`section:${section.id}:after`]: withCtx((slotProps) => [renderSlot(_ctx.$slots, `section:${section.id}:after`, mergeProps({ ref_for: true }, slotProps))]),
3018
+ _: 2
3019
+ }, [renderList(section.fields, (field) => {
3020
+ return {
3021
+ name: `field:${field.name}`,
3022
+ fn: withCtx((slotProps) => [renderSlot(_ctx.$slots, `field:${field.name}`, mergeProps({ ref_for: true }, slotProps))])
3023
+ };
3024
+ })]), 1032, ["section", "builder"])) : createCommentVNode("", true)], 64);
3025
+ }), 128)), resolvedSchema.value.actions ? renderSlot(_ctx.$slots, "actions", {
3026
+ form: unref(builder).form,
3027
+ builder: unref(builder)
3028
+ }, () => [createVNode(FormActionsInternal_default, {
3029
+ loading: __props.loading || unref(builder).form.isSubmitting.value,
3030
+ disabled: __props.disabled,
3031
+ "submit-label": resolvedSchema.value.submitLabel ?? "Submit",
3032
+ "cancel-label": resolvedSchema.value.cancelLabel ?? "Cancel",
3033
+ "show-cancel": resolvedSchema.value.showCancel ?? false,
3034
+ onSubmit: handleSubmit,
3035
+ onCancel: handleCancel
3036
+ }, null, 8, [
3037
+ "loading",
3038
+ "disabled",
3039
+ "submit-label",
3040
+ "cancel-label",
3041
+ "show-cancel"
3042
+ ])], void 0, 0) : createCommentVNode("", true)], 64)) : createCommentVNode("", true)], 2);
3043
+ };
3044
+ }
3045
+ });
3046
+ //#endregion
3047
+ //#region src/components/AppSidebar.vue?vue&type=script&setup=true&lang.ts
3048
+ var _hoisted_1 = {
3049
+ key: 0,
3050
+ class: "mint-sidebar__header"
3051
+ };
3052
+ var _hoisted_2 = {
3053
+ key: 0,
3054
+ class: "mint-sidebar__heading"
3055
+ };
3056
+ var _hoisted_3 = { class: "mint-sidebar__heading-copy" };
3057
+ var _hoisted_4 = {
3058
+ key: 0,
3059
+ class: "mint-sidebar__title"
3060
+ };
3061
+ var _hoisted_5 = {
3062
+ key: 1,
3063
+ class: "mint-sidebar__subtitle"
3064
+ };
3065
+ var _hoisted_6 = {
3066
+ key: 0,
3067
+ class: "mint-sidebar__badge"
3068
+ };
3069
+ var _hoisted_7 = ["aria-label", "aria-expanded"];
3070
+ var _hoisted_8 = ["id"];
3071
+ var _hoisted_9 = { class: "mint-sidebar__group-head" };
3072
+ var _hoisted_10 = ["aria-expanded", "onClick"];
3073
+ var _hoisted_11 = {
3074
+ key: 0,
3075
+ class: "mint-sidebar__group-svg",
3076
+ viewBox: "0 0 24 24",
3077
+ fill: "none",
3078
+ stroke: "currentColor",
3079
+ "stroke-width": "2",
3080
+ "stroke-linecap": "round",
3081
+ "stroke-linejoin": "round",
3082
+ "aria-hidden": "true"
3083
+ };
3084
+ var _hoisted_12 = ["d"];
3085
+ var _hoisted_13 = ["d"];
3086
+ var _hoisted_14 = {
3087
+ key: 1,
3088
+ class: "mint-sidebar__group-text-icon"
3089
+ };
3090
+ var _hoisted_15 = { class: "mint-sidebar__group-copy" };
3091
+ var _hoisted_16 = { class: "mint-sidebar__group-label" };
3092
+ var _hoisted_17 = {
3093
+ key: 0,
3094
+ class: "mint-sidebar__group-subtitle"
3095
+ };
3096
+ var _hoisted_18 = { class: "mint-sidebar__group-tail" };
3097
+ var _hoisted_19 = [
3098
+ "disabled",
3099
+ "aria-label",
3100
+ "title",
3101
+ "onClick"
3102
+ ];
3103
+ var _hoisted_20 = {
3104
+ key: 0,
3105
+ class: "mint-sidebar__group-action-icon",
3106
+ viewBox: "0 0 24 24",
3107
+ fill: "none",
3108
+ stroke: "currentColor",
3109
+ "stroke-width": "2",
3110
+ "stroke-linecap": "round",
3111
+ "stroke-linejoin": "round",
3112
+ "aria-hidden": "true"
3113
+ };
3114
+ var _hoisted_21 = ["d"];
3115
+ var _hoisted_22 = ["d"];
3116
+ var _hoisted_23 = { key: 1 };
3117
+ var _hoisted_24 = [
3118
+ "aria-checked",
3119
+ "aria-label",
3120
+ "onClick"
3121
+ ];
3122
+ var _hoisted_25 = [
3123
+ "aria-label",
3124
+ "aria-expanded",
3125
+ "onClick"
3126
+ ];
3127
+ var _hoisted_26 = { class: "mint-sidebar__group-body" };
3128
+ var _hoisted_27 = {
3129
+ key: 2,
3130
+ class: "mint-sidebar__collapsed"
3131
+ };
3132
+ var _hoisted_28 = {
3133
+ key: 3,
3134
+ class: "mint-sidebar__collapsed mint-sidebar__collapsed--default"
3135
+ };
3136
+ var _hoisted_29 = ["aria-label", "title"];
3137
+ var _hoisted_30 = {
3138
+ key: 0,
3139
+ class: "mint-sidebar__rail-svg",
3140
+ viewBox: "0 0 24 24",
3141
+ fill: "none",
3142
+ stroke: "currentColor",
3143
+ "stroke-width": "2",
3144
+ "stroke-linecap": "round",
3145
+ "stroke-linejoin": "round",
3146
+ "aria-hidden": "true"
3147
+ };
3148
+ var _hoisted_31 = ["d"];
3149
+ var _hoisted_32 = ["d"];
3150
+ var _hoisted_33 = {
3151
+ key: 1,
3152
+ class: "mint-sidebar__rail-text-icon"
3153
+ };
3154
+ var _hoisted_34 = {
3155
+ key: 4,
3156
+ class: "mint-sidebar__footer"
3157
+ };
3158
+ var _hoisted_35 = {
3159
+ key: 5,
3160
+ class: "mint-sidebar__footer mint-sidebar__footer--collapsed"
3161
+ };
3162
+ //#endregion
3163
+ //#region src/components/AppSidebar.vue
3164
+ var AppSidebar_default = /* @__PURE__ */ defineComponent({
3165
+ __name: "AppSidebar",
3166
+ props: {
3167
+ spec: { default: () => ({}) },
3168
+ activeView: { default: "" },
3169
+ values: { default: () => ({}) },
3170
+ collapsed: {
3171
+ type: Boolean,
3172
+ default: void 0
3173
+ },
3174
+ toggleState: { default: () => ({}) },
3175
+ formLoading: {
3176
+ type: Boolean,
3177
+ default: false
3178
+ },
3179
+ formDisabled: {
3180
+ type: Boolean,
3181
+ default: false
3182
+ },
3183
+ formReadonly: {
3184
+ type: Boolean,
3185
+ default: false
3186
+ }
3187
+ },
3188
+ emits: [
3189
+ "update:toggle",
3190
+ "update:values",
3191
+ "update:collapsed",
3192
+ "section-action",
3193
+ "form-submit",
3194
+ "form-cancel"
3195
+ ],
3196
+ setup(__props, { emit: __emit }) {
3197
+ /**
3198
+ * AppSidebar - Context-sensitive toolkit panel
3199
+ *
3200
+ * Shows tool sections relevant to the active view. Sections come from the
3201
+ * spec: a `controls` model built with `defineControlModel()` generates them,
3202
+ * and hand-written `panels` are merged over the generated ones. Each section
3203
+ * renders as a flat group (header row + hairline, no nested card). Controls
3204
+ * can be provided through named slots or auto-rendered from the section forms.
3205
+ *
3206
+ * When activeView is omitted, the first non-empty panel view is selected.
3207
+ * When no view has matching panels, the sidebar hides entirely.
3208
+ *
3209
+ * @example Recommended
3210
+ * ```vue
3211
+ * <AppSidebar v-model:values="values" :spec="{ title: 'Parameters', controls: sidebarModel }" />
3212
+ * ```
3213
+ */
3214
+ const props = __props;
3215
+ const config = computed(() => applySpecDefaults({
3216
+ panels: {},
3217
+ forms: {},
3218
+ floating: true,
3219
+ dense: true,
3220
+ width: "280px",
3221
+ position: "left",
3222
+ whenEmpty: false,
3223
+ formSize: "sm",
3224
+ collapsible: false,
3225
+ collapsedWidth: "3rem",
3226
+ collapseButtonLabel: "Collapse sidebar",
3227
+ expandButtonLabel: "Expand sidebar"
3228
+ }, props.spec));
3229
+ const emit = __emit;
3230
+ const slots = useSlots();
3231
+ const internalCollapsed = ref(false);
3232
+ const collapsedModel = computed({
3233
+ get: () => props.collapsed ?? internalCollapsed.value,
3234
+ set: (value) => {
3235
+ internalCollapsed.value = value;
3236
+ emit("update:collapsed", value);
3237
+ }
3238
+ });
3239
+ const openState = ref({});
3240
+ function isSectionOpen(section) {
3241
+ return openState.value[section.id] ?? section.defaultOpen !== false;
3242
+ }
3243
+ function toggleSection(section) {
3244
+ openState.value[section.id] = !isSectionOpen(section);
3245
+ }
3246
+ const controlModel = computed(() => config.value.controls);
3247
+ const generatedPanels = computed(() => {
3248
+ const model = controlModel.value;
3249
+ return model ? controlsToSidebarPanels(model.controls, model.controlOptions) : {};
3250
+ });
3251
+ const generatedForms = computed(() => {
3252
+ const model = controlModel.value;
3253
+ return model ? controlsToSectionFormSchemas(model.controls, model.controlOptions) : {};
3254
+ });
3255
+ const generatedDefaults = computed(() => {
3256
+ const model = controlModel.value;
3257
+ if (!model) return {};
3258
+ return {
3259
+ ...getControlDefaults(model.controls),
3260
+ ...model.controlOptions.initialValues ?? {}
3261
+ };
3262
+ });
3263
+ const resolvedPanels = computed(() => mergeSidebarPanels(generatedPanels.value, config.value.panels));
3264
+ const resolvedForms = computed(() => ({
3265
+ ...generatedForms.value,
3266
+ ...config.value.forms
3267
+ }));
3268
+ const resolvedValues = computed(() => ({
3269
+ ...generatedDefaults.value,
3270
+ ...props.values
3271
+ }));
3272
+ const resolvedActiveView = computed(() => {
3273
+ if (props.activeView) return props.activeView;
3274
+ return firstVisibleViewId(resolvedPanels.value);
3275
+ });
3276
+ const activeSections = computed(() => {
3277
+ if (!resolvedActiveView.value || !resolvedPanels.value[resolvedActiveView.value]) return [];
3278
+ return resolvedPanels.value[resolvedActiveView.value];
3279
+ });
3280
+ const isVisible = computed(() => activeSections.value.length > 0 || config.value.whenEmpty || Boolean(slots.default));
3281
+ const sidebarClasses = computed(() => [
3282
+ "mint-sidebar",
3283
+ `mint-sidebar--${config.value.position}`,
3284
+ config.value.floating ? "mint-sidebar--floating" : "mint-sidebar--static",
3285
+ config.value.dense ? "" : "mint-sidebar--comfortable",
3286
+ config.value.collapsible ? "mint-sidebar--collapsible" : "",
3287
+ collapsedModel.value ? "mint-sidebar--collapsed" : "",
3288
+ !isVisible.value ? "mint-sidebar--hidden" : ""
3289
+ ]);
3290
+ const sidebarStyle = computed(() => ({ width: collapsedModel.value ? config.value.collapsedWidth : config.value.width }));
3291
+ function handleFormUpdate(values) {
3292
+ emit("update:values", {
3293
+ ...resolvedValues.value,
3294
+ ...values
3295
+ });
3296
+ }
3297
+ function handleFormSubmit(sectionId, values) {
3298
+ emit("form-submit", sectionId, values);
3299
+ }
3300
+ function handleFormCancel(sectionId) {
3301
+ emit("form-cancel", sectionId);
3302
+ }
3303
+ function toggleCollapsed() {
3304
+ collapsedModel.value = !collapsedModel.value;
3305
+ }
3306
+ function expandCollapsed() {
3307
+ collapsedModel.value = false;
3308
+ }
3309
+ function handleSectionAction(sectionId, actionId) {
3310
+ emit("section-action", sectionId, actionId);
3311
+ }
3312
+ function isSvgIcon(icon) {
3313
+ if (!icon) return false;
3314
+ return Array.isArray(icon) || icon.startsWith("M") || icon.startsWith("m");
3315
+ }
3316
+ function sectionInitial(section) {
3317
+ return section.label.trim().charAt(0).toUpperCase() || "?";
3318
+ }
3319
+ function railIconStyle(section) {
3320
+ return {
3321
+ backgroundColor: section.iconBg ?? "var(--color-primary-soft)",
3322
+ color: section.iconColor ?? "var(--color-primary)"
3323
+ };
3324
+ }
3325
+ function badgeToneClass(section) {
3326
+ return `mint-sidebar__rail-badge--${section.badgeTone ?? "cta"}`;
3327
+ }
3328
+ function tagToneClass(section) {
3329
+ return `mint-sidebar__tag--${section.badgeTone ?? "cta"}`;
3330
+ }
3331
+ function actionClasses(action) {
3332
+ return ["mint-sidebar__group-action", action.tone ? `mint-sidebar__group-action--${action.tone}` : ""];
3333
+ }
3334
+ function mergeSidebarPanels(generated, explicit) {
3335
+ const merged = {};
3336
+ const viewIds = /* @__PURE__ */ new Set([...Object.keys(generated), ...Object.keys(explicit)]);
3337
+ for (const viewId of viewIds) {
3338
+ const sectionsById = /* @__PURE__ */ new Map();
3339
+ for (const section of generated[viewId] ?? []) sectionsById.set(section.id, section);
3340
+ for (const section of explicit[viewId] ?? []) sectionsById.set(section.id, section);
3341
+ merged[viewId] = [...sectionsById.values()];
3342
+ }
3343
+ return merged;
3344
+ }
3345
+ function firstVisibleViewId(panels) {
3346
+ for (const [viewId, sections] of Object.entries(panels)) if (sections.length > 0) return viewId;
3347
+ return "";
3348
+ }
3349
+ return (_ctx, _cache) => {
3350
+ return openBlock(), createElementBlock("aside", {
3351
+ class: normalizeClass(sidebarClasses.value),
3352
+ style: normalizeStyle(sidebarStyle.value)
3353
+ }, [
3354
+ _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", {
3355
+ collapsed: collapsedModel.value,
3356
+ toggleCollapsed
3357
+ }, () => [!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", {
3358
+ key: 1,
3359
+ type: "button",
3360
+ class: "mint-sidebar__collapse-button",
3361
+ "aria-label": collapsedModel.value ? config.value.expandButtonLabel : config.value.collapseButtonLabel,
3362
+ "aria-expanded": !collapsedModel.value,
3363
+ onClick: toggleCollapsed
3364
+ }, [(openBlock(), createElementBlock("svg", {
3365
+ class: normalizeClass(["mint-sidebar__collapse-icon", { "mint-sidebar__collapse-icon--collapsed": collapsedModel.value }]),
3366
+ viewBox: "0 0 24 24",
3367
+ fill: "none",
3368
+ stroke: "currentColor",
3369
+ "stroke-width": "2",
3370
+ "stroke-linecap": "round",
3371
+ "stroke-linejoin": "round",
3372
+ "aria-hidden": "true"
3373
+ }, [..._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),
3374
+ !collapsedModel.value ? (openBlock(), createElementBlock("div", {
3375
+ key: 1,
3376
+ id: config.value.contentId,
3377
+ class: "mint-sidebar__sections"
3378
+ }, [(openBlock(true), createElementBlock(Fragment, null, renderList(activeSections.value, (section) => {
3379
+ return openBlock(), createElementBlock("div", {
3380
+ key: section.id,
3381
+ class: normalizeClass(["mint-sidebar__group", isSectionOpen(section) ? "mint-sidebar__group--open" : "mint-sidebar__group--closed"])
3382
+ }, [createElementVNode("div", _hoisted_9, [createElementVNode("button", {
3383
+ type: "button",
3384
+ class: "mint-sidebar__group-toggle",
3385
+ "aria-expanded": isSectionOpen(section),
3386
+ onClick: ($event) => toggleSection(section)
3387
+ }, [section.icon ? (openBlock(), createElementBlock("span", {
3388
+ key: 0,
3389
+ class: "mint-sidebar__group-icon",
3390
+ style: normalizeStyle(railIconStyle(section))
3391
+ }, [isSvgIcon(section.icon) ? (openBlock(), createElementBlock("svg", _hoisted_11, [Array.isArray(section.icon) ? (openBlock(true), createElementBlock(Fragment, { key: 0 }, renderList(section.icon, (d, i) => {
3392
+ return openBlock(), createElementBlock("path", {
3393
+ key: i,
3394
+ d
3395
+ }, null, 8, _hoisted_12);
3396
+ }), 128)) : (openBlock(), createElementBlock("path", {
3397
+ key: 1,
3398
+ d: section.icon
3399
+ }, 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, [
3400
+ section.badge !== void 0 ? (openBlock(), createElementBlock("span", {
3401
+ key: 0,
3402
+ class: normalizeClass(["mint-sidebar__tag", tagToneClass(section)])
3403
+ }, toDisplayString(section.badge), 3)) : createCommentVNode("", true),
3404
+ (openBlock(true), createElementBlock(Fragment, null, renderList(section.actions ?? [], (action) => {
3405
+ return openBlock(), createElementBlock("button", {
3406
+ key: action.id,
3407
+ type: "button",
3408
+ class: normalizeClass(actionClasses(action)),
3409
+ style: normalizeStyle(action.iconColor ? { color: action.iconColor } : void 0),
3410
+ disabled: action.disabled,
3411
+ "aria-label": action.label,
3412
+ title: action.label,
3413
+ onClick: ($event) => handleSectionAction(section.id, action.id)
3414
+ }, [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) => {
3415
+ return openBlock(), createElementBlock("path", {
3416
+ key: i,
3417
+ d
3418
+ }, null, 8, _hoisted_21);
3419
+ }), 128)) : (openBlock(), createElementBlock("path", {
3420
+ key: 1,
3421
+ d: action.icon
3422
+ }, null, 8, _hoisted_22))])) : action.icon ? (openBlock(), createElementBlock("span", _hoisted_23, toDisplayString(action.icon), 1)) : createCommentVNode("", true)], 14, _hoisted_19);
3423
+ }), 128)),
3424
+ section.showToggle ? (openBlock(), createElementBlock("button", {
3425
+ key: 1,
3426
+ type: "button",
3427
+ role: "switch",
3428
+ "aria-checked": __props.toggleState[section.id] ?? false,
3429
+ "aria-label": `Enable ${section.label}`,
3430
+ class: normalizeClass(["mint-sidebar__switch", __props.toggleState[section.id] ?? false ? "mint-sidebar__switch--on" : ""]),
3431
+ onClick: ($event) => emit("update:toggle", section.id, !(__props.toggleState[section.id] ?? false))
3432
+ }, [..._cache[1] || (_cache[1] = [createElementVNode("span", { class: "mint-sidebar__switch-knob" }, null, -1)])], 10, _hoisted_24)) : createCommentVNode("", true),
3433
+ createElementVNode("button", {
3434
+ type: "button",
3435
+ class: "mint-sidebar__chevron-button",
3436
+ "aria-label": isSectionOpen(section) ? "Collapse section" : "Expand section",
3437
+ "aria-expanded": isSectionOpen(section),
3438
+ onClick: ($event) => toggleSection(section)
3439
+ }, [(openBlock(), createElementBlock("svg", {
3440
+ class: normalizeClass(["mint-sidebar__chevron", isSectionOpen(section) ? "mint-sidebar__chevron--open" : ""]),
3441
+ viewBox: "0 0 24 24",
3442
+ fill: "none",
3443
+ stroke: "currentColor",
3444
+ "stroke-width": "2",
3445
+ "stroke-linecap": "round",
3446
+ "stroke-linejoin": "round",
3447
+ "aria-hidden": "true"
3448
+ }, [..._cache[2] || (_cache[2] = [createElementVNode("path", { d: "m6 9 6 6 6-6" }, null, -1)])], 2))], 8, _hoisted_25)
3449
+ ])]), createVNode(Transition, { name: "collapse" }, {
3450
+ default: withCtx(() => [withDirectives(createElementVNode("div", _hoisted_26, [renderSlot(_ctx.$slots, `section-${section.id}`, {}, () => [resolvedForms.value[section.id] ? (openBlock(), createBlock(FormSchemaInternal_default, {
3451
+ key: 0,
3452
+ "model-value": resolvedValues.value,
3453
+ schema: resolvedForms.value[section.id],
3454
+ enhancements: config.value.controls?.controlOptions.enhancements,
3455
+ loading: __props.formLoading,
3456
+ disabled: __props.formDisabled,
3457
+ readonly: __props.formReadonly,
3458
+ size: config.value.formSize,
3459
+ "onUpdate:modelValue": handleFormUpdate,
3460
+ onSubmit: ($event) => handleFormSubmit(section.id, $event),
3461
+ onCancel: ($event) => handleFormCancel(section.id)
3462
+ }, null, 8, [
3463
+ "model-value",
3464
+ "schema",
3465
+ "enhancements",
3466
+ "loading",
3467
+ "disabled",
3468
+ "readonly",
3469
+ "size",
3470
+ "onSubmit",
3471
+ "onCancel"
3472
+ ])) : createCommentVNode("", true)])], 512), [[vShow, isSectionOpen(section)]])]),
3473
+ _: 2
3474
+ }, 1024)], 2);
3475
+ }), 128)), renderSlot(_ctx.$slots, "default", {
3476
+ sections: activeSections.value,
3477
+ activeView: resolvedActiveView.value,
3478
+ values: resolvedValues.value
3479
+ })], 8, _hoisted_8)) : _ctx.$slots.collapsed ? (openBlock(), createElementBlock("div", _hoisted_27, [renderSlot(_ctx.$slots, "collapsed", {
3480
+ sections: activeSections.value,
3481
+ expand: expandCollapsed
3482
+ })])) : (openBlock(), createElementBlock("div", _hoisted_28, [(openBlock(true), createElementBlock(Fragment, null, renderList(activeSections.value, (section) => {
3483
+ return openBlock(), createElementBlock("button", {
3484
+ key: section.id,
3485
+ type: "button",
3486
+ class: "mint-sidebar__rail-item",
3487
+ "aria-label": `Expand ${section.label}`,
3488
+ title: section.label,
3489
+ onClick: expandCollapsed
3490
+ }, [createElementVNode("span", {
3491
+ class: "mint-sidebar__rail-icon",
3492
+ style: normalizeStyle(railIconStyle(section))
3493
+ }, [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) => {
3494
+ return openBlock(), createElementBlock("path", {
3495
+ key: i,
3496
+ d
3497
+ }, null, 8, _hoisted_31);
3498
+ }), 128)) : (openBlock(), createElementBlock("path", {
3499
+ key: 1,
3500
+ d: section.icon
3501
+ }, null, 8, _hoisted_32))])) : (openBlock(), createElementBlock("span", _hoisted_33, toDisplayString(section.icon || sectionInitial(section)), 1))], 4), section.badge !== void 0 ? (openBlock(), createElementBlock("span", {
3502
+ key: 0,
3503
+ class: normalizeClass(["mint-sidebar__rail-badge", badgeToneClass(section)])
3504
+ }, toDisplayString(section.badge), 3)) : createCommentVNode("", true)], 8, _hoisted_29);
3505
+ }), 128))])),
3506
+ !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)
3507
+ ], 6);
3508
+ };
3509
+ }
3510
+ });
3511
+ //#endregion
3512
+ export { CollapsibleCard_default as A, controlValuesToComponentBindings as C, controlsToFormSchema as D, controlsTo as E, useTheme as M, controlsToSettingsSchema as O, controlBindings as S, controlValuesToComponentProps as T, usePluginWorkspace as _, pickExistingRecordKeys as a, getControlDefaults as b, valuesEqual as c, useForm as d, AppTopBar_default as f, AppLayout_default as g, normalizeLabelItemInput as h, formSchemaFieldNames as i, ThemeToggle_default as j, getDefaultControlView as k, useFormBuilder as l, normalizeItemInput as m, FormSchemaInternal_default as n, pickRecordKeys as o, PluginIcon_default as p, FormFieldRendererInternal_default as r, recordValuesEqualForKeys as s, AppSidebar_default as t, evaluateCondition as u, defineControlComponentBindings as v, controlValuesToComponentBindingsById as w, useControlSchema as x, defineControls as y };
3513
+
3514
+ //# sourceMappingURL=AppSidebar-BmiiPfz9.js.map