@morscherlab/mint-sdk 1.0.0-beta.1 → 1.0.0-beta.3

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 (421) hide show
  1. package/README.md +218 -6
  2. package/dist/__tests__/components/ActionItem.test.d.ts +1 -0
  3. package/dist/__tests__/components/AppAvatarMenu.test.d.ts +1 -0
  4. package/dist/__tests__/components/AppPageSelector.test.d.ts +1 -0
  5. package/dist/__tests__/components/AppPillNav.test.d.ts +1 -0
  6. package/dist/__tests__/components/AppPluginSwitcher.test.d.ts +1 -0
  7. package/dist/__tests__/components/AppToastContainer.test.d.ts +1 -0
  8. package/dist/__tests__/components/BaseRadioGroup.test.d.ts +1 -0
  9. package/dist/__tests__/components/BaseSelect.test.d.ts +1 -0
  10. package/dist/__tests__/components/BaseTabs.test.d.ts +1 -0
  11. package/dist/__tests__/components/BatchProgressList.test.d.ts +1 -0
  12. package/dist/__tests__/components/BioTemplateExperimentWorkspaceView.test.d.ts +1 -0
  13. package/dist/__tests__/components/BioTemplatePackWorkspaceView.test.d.ts +1 -0
  14. package/dist/__tests__/components/BioTemplatePresetWorkspaceView.test.d.ts +1 -0
  15. package/dist/__tests__/components/BioTemplateRenderer.test.d.ts +1 -0
  16. package/dist/__tests__/components/Breadcrumb.test.d.ts +1 -0
  17. package/dist/__tests__/components/CalendarGridPanel.test.d.ts +1 -0
  18. package/dist/__tests__/components/ConcentrationInput.test.d.ts +1 -0
  19. package/dist/__tests__/components/ControlWorkspaceView.test.d.ts +1 -0
  20. package/dist/__tests__/components/DatePicker.test.d.ts +1 -0
  21. package/dist/__tests__/components/DateTimePicker.test.d.ts +1 -0
  22. package/dist/__tests__/components/EmptyState.test.d.ts +1 -0
  23. package/dist/__tests__/components/ExperimentPopover.test.d.ts +1 -0
  24. package/dist/__tests__/components/FormBuilder.test.d.ts +1 -0
  25. package/dist/__tests__/components/FormCompatibility.test.d.ts +1 -0
  26. package/dist/__tests__/components/GroupAssigner.test.d.ts +1 -0
  27. package/dist/__tests__/components/GroupingModal.test.d.ts +1 -0
  28. package/dist/__tests__/components/MultiSelect.test.d.ts +1 -0
  29. package/dist/__tests__/components/PluginIcon.test.d.ts +1 -0
  30. package/dist/__tests__/components/ProtocolStepEditor.test.d.ts +1 -0
  31. package/dist/__tests__/components/ReagentList.test.d.ts +1 -0
  32. package/dist/__tests__/components/SampleHierarchyTree.test.d.ts +1 -0
  33. package/dist/__tests__/components/SampleSelector.test.d.ts +1 -0
  34. package/dist/__tests__/components/SegmentedControl.test.d.ts +1 -0
  35. package/dist/__tests__/components/SettingsButton.test.d.ts +1 -0
  36. package/dist/__tests__/components/SettingsModal.test.d.ts +1 -0
  37. package/dist/__tests__/components/TagsInput.test.d.ts +1 -0
  38. package/dist/__tests__/components/ThemeToggle.test.d.ts +1 -0
  39. package/dist/__tests__/components/TimePicker.test.d.ts +1 -0
  40. package/dist/__tests__/composables/useBioTemplatePackWorkspace.test.d.ts +1 -0
  41. package/dist/__tests__/composables/useBioTemplatePresetWorkspace.test.d.ts +1 -0
  42. package/dist/__tests__/composables/useBioTemplateWorkspace.test.d.ts +1 -0
  43. package/dist/__tests__/composables/useCalendarGrid.test.d.ts +1 -0
  44. package/dist/__tests__/composables/useControlSchema.test.d.ts +1 -0
  45. package/dist/__tests__/composables/useDebouncedWatch.test.d.ts +1 -0
  46. package/dist/__tests__/composables/useDropdownState.test.d.ts +1 -0
  47. package/dist/__tests__/composables/useEventListener.test.d.ts +1 -0
  48. package/dist/__tests__/composables/useExpansionSet.test.d.ts +1 -0
  49. package/dist/__tests__/composables/useExperimentData.test.d.ts +1 -0
  50. package/dist/__tests__/composables/useExperimentSelector.test.d.ts +1 -0
  51. package/dist/__tests__/composables/useGroupAssignment.test.d.ts +1 -0
  52. package/dist/__tests__/composables/useListSelection.test.d.ts +1 -0
  53. package/dist/__tests__/composables/usePluginClient.test.d.ts +1 -0
  54. package/dist/__tests__/composables/usePluginConfig.test.d.ts +1 -0
  55. package/dist/__tests__/composables/useRequestSyncState.test.d.ts +1 -0
  56. package/dist/__tests__/composables/useSampleGroups.test.d.ts +1 -0
  57. package/dist/__tests__/composables/useSelectionLimit.test.d.ts +1 -0
  58. package/dist/__tests__/composables/useSortedItems.test.d.ts +1 -0
  59. package/dist/__tests__/composables/useTemplateCollection.test.d.ts +1 -0
  60. package/dist/__tests__/composables/useTextSearch.test.d.ts +1 -0
  61. package/dist/__tests__/composables/useTheme.test.d.ts +1 -0
  62. package/dist/__tests__/composables/useTimeUtils.test.d.ts +1 -0
  63. package/dist/__tests__/docs/frontendDocsCatalog.test.d.ts +1 -0
  64. package/dist/__tests__/templates/templates.test.d.ts +1 -0
  65. package/dist/{auth-DsI0rQ7_.js → auth-QQj2kkze.js} +12 -5
  66. package/dist/auth-QQj2kkze.js.map +1 -0
  67. package/dist/components/ActionItem.vue.d.ts +32 -0
  68. package/dist/components/AppAvatarMenu.vue.d.ts +2 -7
  69. package/dist/components/AppPageSelector.vue.d.ts +3 -6
  70. package/dist/components/AppPillNav.vue.d.ts +2 -2
  71. package/dist/components/AppSidebar.vue.d.ts +56 -3
  72. package/dist/components/AppToastContainer.vue.d.ts +2 -0
  73. package/dist/components/AppTopBar.vue.d.ts +43 -10
  74. package/dist/components/BaseButton.vue.d.ts +2 -2
  75. package/dist/components/BaseCheckbox.vue.d.ts +1 -1
  76. package/dist/components/BaseInput.vue.d.ts +2 -2
  77. package/dist/components/BasePill.vue.d.ts +3 -3
  78. package/dist/components/BaseRadioGroup.vue.d.ts +4 -4
  79. package/dist/components/BaseSelect.vue.d.ts +4 -4
  80. package/dist/components/BaseSlider.vue.d.ts +1 -1
  81. package/dist/components/BaseTabs.vue.d.ts +2 -2
  82. package/dist/components/BaseTextarea.vue.d.ts +2 -2
  83. package/dist/components/BaseToggle.vue.d.ts +1 -1
  84. package/dist/components/BioTemplateExperimentWorkspaceView.vue.d.ts +117 -0
  85. package/dist/components/BioTemplatePackWorkspaceView.vue.d.ts +92 -0
  86. package/dist/components/BioTemplatePresetWorkspaceView.vue.d.ts +82 -0
  87. package/dist/components/BioTemplateRenderer.vue.d.ts +29 -0
  88. package/dist/components/Breadcrumb.vue.d.ts +2 -2
  89. package/dist/components/Calendar.vue.d.ts +1 -1
  90. package/dist/components/CalendarGridPanel.vue.d.ts +25 -0
  91. package/dist/components/CollapsibleCard.vue.d.ts +1 -1
  92. package/dist/components/ColorSlider.vue.d.ts +1 -1
  93. package/dist/components/ConcentrationInput.vue.d.ts +2 -2
  94. package/dist/components/ConfirmDialog.vue.d.ts +2 -2
  95. package/dist/components/ControlWorkspaceView.vue.d.ts +130 -0
  96. package/dist/components/DatePicker.vue.d.ts +2 -2
  97. package/dist/components/DateTimePicker.vue.d.ts +3 -3
  98. package/dist/components/DropdownButton.vue.d.ts +4 -4
  99. package/dist/components/EmptyState.vue.d.ts +1 -2
  100. package/dist/components/ExperimentDataViewer.vue.d.ts +1 -1
  101. package/dist/components/ExperimentTimeline.vue.d.ts +2 -2
  102. package/dist/components/FileUploader.vue.d.ts +2 -2
  103. package/dist/components/FitPanel.vue.d.ts +1 -1
  104. package/dist/components/FormActions.vue.d.ts +4 -4
  105. package/dist/components/FormBuilder.vue.d.ts +22 -8
  106. package/dist/components/FormFieldRenderer.vue.d.ts +7 -10
  107. package/dist/components/FormSection.vue.d.ts +11 -24
  108. package/dist/components/FormulaInput.vue.d.ts +2 -2
  109. package/dist/components/IconButton.vue.d.ts +1 -1
  110. package/dist/components/LoadingSpinner.vue.d.ts +1 -1
  111. package/dist/components/MoleculeInput.vue.d.ts +2 -2
  112. package/dist/components/MultiSelect.vue.d.ts +3 -3
  113. package/dist/components/NumberInput.vue.d.ts +2 -2
  114. package/dist/components/PluginIcon.vue.d.ts +11 -0
  115. package/dist/components/ProgressBar.vue.d.ts +2 -2
  116. package/dist/components/ProtocolStepEditor.vue.d.ts +3 -1
  117. package/dist/components/RackEditor.vue.d.ts +2 -2
  118. package/dist/components/ReagentEditor.vue.d.ts +1 -1
  119. package/dist/components/ResourceCard.vue.d.ts +1 -1
  120. package/dist/components/SampleLegend.vue.d.ts +2 -2
  121. package/dist/components/SampleSelector.vue.d.ts +1 -1
  122. package/dist/components/ScheduleCalendar.vue.d.ts +2 -2
  123. package/dist/components/ScientificNumber.vue.d.ts +1 -1
  124. package/dist/components/SegmentedControl.vue.d.ts +3 -3
  125. package/dist/components/SequenceInput.vue.d.ts +3 -3
  126. package/dist/components/SettingsButton.vue.d.ts +2 -2
  127. package/dist/components/SettingsModal.vue.d.ts +32 -4
  128. package/dist/components/StatusIndicator.vue.d.ts +1 -1
  129. package/dist/components/TagsInput.vue.d.ts +3 -2
  130. package/dist/components/TimePicker.vue.d.ts +3 -3
  131. package/dist/components/TimeRangeInput.vue.d.ts +2 -2
  132. package/dist/components/UnitInput.vue.d.ts +2 -2
  133. package/dist/components/WellPlate.vue.d.ts +8 -8
  134. package/dist/components/index.d.ts +12 -1
  135. package/dist/components/index.js +3 -3
  136. package/dist/components/internal/FormFieldRendererInternal.vue.d.ts +31 -0
  137. package/dist/components/internal/FormSectionRenderer.vue.d.ts +43 -0
  138. package/dist/{components-CzbQQPCb.js → components-D_Sr0adg.js} +9629 -8647
  139. package/dist/components-D_Sr0adg.js.map +1 -0
  140. package/dist/composables/index.d.ts +21 -2
  141. package/dist/composables/index.js +4 -3
  142. package/dist/composables/platformContextHelpers.d.ts +14 -0
  143. package/dist/composables/useBioTemplateComponents.d.ts +20 -0
  144. package/dist/composables/useBioTemplateControls.d.ts +6 -0
  145. package/dist/composables/useBioTemplatePackWorkspace.d.ts +45 -0
  146. package/dist/composables/useBioTemplatePresetWorkspace.d.ts +74 -0
  147. package/dist/composables/useBioTemplateWorkspace.d.ts +50 -0
  148. package/dist/composables/useCalendarGrid.d.ts +26 -0
  149. package/dist/composables/useControlSchema.d.ts +321 -0
  150. package/dist/composables/useDebouncedWatch.d.ts +20 -0
  151. package/dist/composables/useDropdownState.d.ts +19 -0
  152. package/dist/composables/useEventListener.d.ts +13 -0
  153. package/dist/composables/useExpansionSet.d.ts +21 -0
  154. package/dist/composables/useExperimentData.d.ts +10 -0
  155. package/dist/composables/useExperimentSave.d.ts +31 -2
  156. package/dist/composables/useExperimentSelector.d.ts +20 -0
  157. package/dist/composables/useForm.d.ts +2 -0
  158. package/dist/composables/useGroupAssignment.d.ts +31 -0
  159. package/dist/composables/useListSelection.d.ts +35 -0
  160. package/dist/composables/usePlatformContext.d.ts +24 -3
  161. package/dist/composables/usePluginApi.d.ts +7 -14
  162. package/dist/composables/usePluginClient.d.ts +109 -0
  163. package/dist/composables/usePluginConfig.d.ts +12 -0
  164. package/dist/composables/useRequestSyncState.d.ts +34 -0
  165. package/dist/composables/useSampleGroups.d.ts +32 -0
  166. package/dist/composables/useSelectionLimit.d.ts +17 -0
  167. package/dist/composables/useSortedItems.d.ts +32 -0
  168. package/dist/composables/useTemplateCollection.d.ts +58 -0
  169. package/dist/composables/useTextSearch.d.ts +18 -0
  170. package/dist/composables/useTimeUtils.d.ts +8 -0
  171. package/dist/{composables-BXklV5ii.js → composables-C3dpXQN5.js} +228 -146
  172. package/dist/composables-C3dpXQN5.js.map +1 -0
  173. package/dist/index.d.ts +12 -3
  174. package/dist/index.js +6 -5
  175. package/dist/install.d.ts +7 -2
  176. package/dist/install.js +2 -2
  177. package/dist/install.js.map +1 -1
  178. package/dist/stores/auth.d.ts +1 -1
  179. package/dist/stores/index.js +1 -1
  180. package/dist/stores/settings.d.ts +4 -1
  181. package/dist/styles.css +5255 -5654
  182. package/dist/templates/adapters.d.ts +43 -0
  183. package/dist/templates/builders.d.ts +63 -0
  184. package/dist/templates/catalog.d.ts +188 -0
  185. package/dist/templates/componentBindings.d.ts +58 -0
  186. package/dist/templates/controlSchemas.d.ts +25 -0
  187. package/dist/templates/index.d.ts +15 -0
  188. package/dist/templates/index.js +2 -0
  189. package/dist/templates/lookup.d.ts +4 -0
  190. package/dist/templates/packs.d.ts +18 -0
  191. package/dist/templates/presets.d.ts +90 -0
  192. package/dist/templates/types.d.ts +531 -0
  193. package/dist/templates-50NPjaxL.js +9333 -0
  194. package/dist/templates-50NPjaxL.js.map +1 -0
  195. package/dist/types/components.d.ts +62 -1
  196. package/dist/types/form-builder.d.ts +6 -8
  197. package/dist/types/index.d.ts +2 -2
  198. package/dist/types/platform.d.ts +8 -1
  199. package/dist/useScheduleDrag-D4oWdh41.js +4371 -0
  200. package/dist/useScheduleDrag-D4oWdh41.js.map +1 -0
  201. package/dist/utils/formModelSync.d.ts +5 -0
  202. package/dist/utils/items.d.ts +8 -0
  203. package/dist/utils/options.d.ts +6 -0
  204. package/dist/utils/pluginIcon.d.ts +9 -0
  205. package/package.json +7 -2
  206. package/src/__tests__/components/ActionItem.test.ts +99 -0
  207. package/src/__tests__/components/AppAvatarMenu.test.ts +27 -0
  208. package/src/__tests__/components/AppPageSelector.test.ts +134 -0
  209. package/src/__tests__/components/AppPillNav.test.ts +78 -0
  210. package/src/__tests__/components/AppPluginSwitcher.test.ts +44 -0
  211. package/src/__tests__/components/AppSidebar.test.ts +370 -0
  212. package/src/__tests__/components/AppToastContainer.test.ts +48 -0
  213. package/src/__tests__/components/AppTopBar.test.ts +414 -13
  214. package/src/__tests__/components/BaseRadioGroup.test.ts +25 -0
  215. package/src/__tests__/components/BaseSelect.test.ts +21 -0
  216. package/src/__tests__/components/BaseTabs.test.ts +25 -0
  217. package/src/__tests__/components/BatchProgressList.test.ts +52 -0
  218. package/src/__tests__/components/BioTemplateExperimentWorkspaceView.test.ts +153 -0
  219. package/src/__tests__/components/BioTemplatePackWorkspaceView.test.ts +161 -0
  220. package/src/__tests__/components/BioTemplatePresetWorkspaceView.test.ts +281 -0
  221. package/src/__tests__/components/BioTemplateRenderer.test.ts +71 -0
  222. package/src/__tests__/components/Breadcrumb.test.ts +23 -0
  223. package/src/__tests__/components/CalendarGridPanel.test.ts +36 -0
  224. package/src/__tests__/components/ConcentrationInput.test.ts +45 -0
  225. package/src/__tests__/components/ControlWorkspaceView.test.ts +1031 -0
  226. package/src/__tests__/components/DataFrame.test.ts +11 -0
  227. package/src/__tests__/components/DatePicker.test.ts +45 -0
  228. package/src/__tests__/components/DateTimePicker.test.ts +48 -0
  229. package/src/__tests__/components/DropdownButton.test.ts +23 -0
  230. package/src/__tests__/components/EmptyState.test.ts +23 -0
  231. package/src/__tests__/components/ExperimentPopover.test.ts +56 -0
  232. package/src/__tests__/components/FormBuilder.test.ts +296 -0
  233. package/src/__tests__/components/FormCompatibility.test.ts +94 -0
  234. package/src/__tests__/components/GroupAssigner.test.ts +30 -0
  235. package/src/__tests__/components/GroupingModal.test.ts +73 -0
  236. package/src/__tests__/components/MultiSelect.test.ts +48 -0
  237. package/src/__tests__/components/PluginIcon.test.ts +119 -0
  238. package/src/__tests__/components/ProtocolStepEditor.test.ts +33 -0
  239. package/src/__tests__/components/ReagentList.test.ts +82 -0
  240. package/src/__tests__/components/SampleHierarchyTree.test.ts +53 -0
  241. package/src/__tests__/components/SampleSelector.test.ts +60 -0
  242. package/src/__tests__/components/SegmentedControl.test.ts +24 -0
  243. package/src/__tests__/components/SettingsButton.test.ts +44 -0
  244. package/src/__tests__/components/SettingsModal.test.ts +296 -0
  245. package/src/__tests__/components/TagsInput.test.ts +75 -0
  246. package/src/__tests__/components/ThemeToggle.test.ts +47 -0
  247. package/src/__tests__/components/TimePicker.test.ts +38 -0
  248. package/src/__tests__/composables/useBioTemplatePackWorkspace.test.ts +122 -0
  249. package/src/__tests__/composables/useBioTemplatePresetWorkspace.test.ts +199 -0
  250. package/src/__tests__/composables/useBioTemplateWorkspace.test.ts +99 -0
  251. package/src/__tests__/composables/useCalendarGrid.test.ts +38 -0
  252. package/src/__tests__/composables/useControlSchema.test.ts +919 -0
  253. package/src/__tests__/composables/useDebouncedWatch.test.ts +93 -0
  254. package/src/__tests__/composables/useDropdownState.test.ts +95 -0
  255. package/src/__tests__/composables/useEventListener.test.ts +116 -0
  256. package/src/__tests__/composables/useExpansionSet.test.ts +62 -0
  257. package/src/__tests__/composables/useExperimentData.test.ts +4 -0
  258. package/src/__tests__/composables/useExperimentSave.test.ts +203 -8
  259. package/src/__tests__/composables/useExperimentSelector.test.ts +164 -0
  260. package/src/__tests__/composables/useForm.test.ts +58 -0
  261. package/src/__tests__/composables/useFormBuilder.test.ts +77 -0
  262. package/src/__tests__/composables/useGroupAssignment.test.ts +73 -0
  263. package/src/__tests__/composables/useListSelection.test.ts +66 -0
  264. package/src/__tests__/composables/usePluginClient.test.ts +444 -0
  265. package/src/__tests__/composables/usePluginConfig.test.ts +5 -0
  266. package/src/__tests__/composables/useRequestSyncState.test.ts +92 -0
  267. package/src/__tests__/composables/useSampleGroups.test.ts +66 -0
  268. package/src/__tests__/composables/useSelectionLimit.test.ts +41 -0
  269. package/src/__tests__/composables/useSortedItems.test.ts +87 -0
  270. package/src/__tests__/composables/useTemplateCollection.test.ts +147 -0
  271. package/src/__tests__/composables/useTextSearch.test.ts +55 -0
  272. package/src/__tests__/composables/useTheme.test.ts +91 -0
  273. package/src/__tests__/composables/useTimeUtils.test.ts +35 -0
  274. package/src/__tests__/docs/frontendDocsCatalog.test.ts +229 -0
  275. package/src/__tests__/fixtures/templates/dose-response.json +81 -0
  276. package/src/__tests__/fixtures/templates/plate-map.json +54 -0
  277. package/src/__tests__/fixtures/templates/qpcr-plate.json +96 -0
  278. package/src/__tests__/fixtures/templates/sample-sheet.json +71 -0
  279. package/src/__tests__/templates/templates.test.ts +1043 -0
  280. package/src/components/ActionItem.vue +82 -0
  281. package/src/components/AppAvatarMenu.vue +15 -69
  282. package/src/components/AppLayout.story.vue +25 -25
  283. package/src/components/AppPageSelector.vue +63 -94
  284. package/src/components/AppPillNav.vue +44 -39
  285. package/src/components/AppPluginSwitcher.vue +41 -145
  286. package/src/components/AppSidebar.story.vue +94 -0
  287. package/src/components/AppSidebar.vue +187 -12
  288. package/src/components/{ToastNotification.story.vue → AppToastContainer.story.vue} +6 -6
  289. package/src/components/AppToastContainer.vue +62 -0
  290. package/src/components/AppTopBar.story.vue +7 -30
  291. package/src/components/AppTopBar.vue +283 -84
  292. package/src/components/BaseModal.vue +3 -5
  293. package/src/components/BaseRadioGroup.vue +7 -3
  294. package/src/components/BaseSelect.vue +11 -7
  295. package/src/components/BaseTabs.vue +6 -4
  296. package/src/components/BatchProgressList.vue +5 -8
  297. package/src/components/BioTemplateExperimentWorkspaceView.story.vue +123 -0
  298. package/src/components/BioTemplateExperimentWorkspaceView.vue +337 -0
  299. package/src/components/BioTemplatePackWorkspaceView.story.vue +107 -0
  300. package/src/components/BioTemplatePackWorkspaceView.vue +176 -0
  301. package/src/components/BioTemplatePresetWorkspaceView.story.vue +151 -0
  302. package/src/components/BioTemplatePresetWorkspaceView.vue +392 -0
  303. package/src/components/BioTemplateRenderer.story.vue +57 -0
  304. package/src/components/BioTemplateRenderer.vue +269 -0
  305. package/src/components/Breadcrumb.vue +14 -8
  306. package/src/components/CalendarGridPanel.vue +120 -0
  307. package/src/components/ConcentrationInput.vue +27 -64
  308. package/src/components/ControlWorkspaceView.story.vue +336 -0
  309. package/src/components/ControlWorkspaceView.vue +347 -0
  310. package/src/components/DataFrame.vue +34 -50
  311. package/src/components/DatePicker.vue +59 -192
  312. package/src/components/DateTimePicker.vue +50 -171
  313. package/src/components/DropdownButton.vue +14 -32
  314. package/src/components/EmptyState.vue +4 -2
  315. package/src/components/ExperimentPopover.vue +5 -22
  316. package/src/components/FormBuilder.vue +124 -27
  317. package/src/components/FormFieldRenderer.vue +15 -38
  318. package/src/components/FormSection.vue +20 -73
  319. package/src/components/GroupAssigner.vue +24 -56
  320. package/src/components/GroupingModal.story.vue +3 -3
  321. package/src/components/GroupingModal.vue +30 -391
  322. package/src/components/MultiSelect.vue +17 -12
  323. package/src/components/PlateMapEditor.vue +3 -8
  324. package/src/components/PluginIcon.story.vue +71 -0
  325. package/src/components/PluginIcon.vue +68 -0
  326. package/src/components/ProtocolStepEditor.vue +13 -22
  327. package/src/components/ReagentList.vue +25 -33
  328. package/src/components/SampleHierarchyTree.vue +12 -23
  329. package/src/components/SampleSelector.vue +42 -122
  330. package/src/components/SegmentedControl.vue +7 -3
  331. package/src/components/SettingsButton.story.vue +1 -1
  332. package/src/components/SettingsButton.vue +15 -27
  333. package/src/components/SettingsModal.story.vue +337 -45
  334. package/src/components/SettingsModal.vue +344 -66
  335. package/src/components/TagsInput.vue +29 -14
  336. package/src/components/ThemeToggle.vue +9 -7
  337. package/src/components/TimePicker.vue +19 -41
  338. package/src/components/ToastNotification.vue +4 -57
  339. package/src/components/Tooltip.vue +7 -12
  340. package/src/components/WellEditPopup.vue +3 -8
  341. package/src/components/WellPlate.vue +4 -10
  342. package/src/components/index.ts +12 -1
  343. package/src/components/internal/FormFieldRendererInternal.vue +50 -0
  344. package/src/components/internal/FormSectionRenderer.vue +78 -0
  345. package/src/composables/index.ts +212 -0
  346. package/src/composables/platformContextHelpers.ts +74 -0
  347. package/src/composables/useBioTemplateComponents.ts +93 -0
  348. package/src/composables/useBioTemplateControls.ts +41 -0
  349. package/src/composables/useBioTemplatePackWorkspace.ts +181 -0
  350. package/src/composables/useBioTemplatePresetWorkspace.ts +337 -0
  351. package/src/composables/useBioTemplateWorkspace.ts +139 -0
  352. package/src/composables/useCalendarGrid.ts +140 -0
  353. package/src/composables/useControlSchema.ts +1274 -0
  354. package/src/composables/useDebouncedWatch.ts +119 -0
  355. package/src/composables/useDropdownState.ts +83 -0
  356. package/src/composables/useEventListener.ts +111 -0
  357. package/src/composables/useExpansionSet.ts +117 -0
  358. package/src/composables/useExperimentData.ts +20 -11
  359. package/src/composables/useExperimentSave.ts +202 -50
  360. package/src/composables/useExperimentSelector.ts +86 -72
  361. package/src/composables/useForm.ts +49 -4
  362. package/src/composables/useFormBuilder.ts +93 -42
  363. package/src/composables/useGroupAssignment.ts +148 -0
  364. package/src/composables/useListSelection.ts +158 -0
  365. package/src/composables/usePluginApi.ts +7 -14
  366. package/src/composables/usePluginClient.ts +425 -0
  367. package/src/composables/usePluginConfig.ts +34 -13
  368. package/src/composables/useRequestSyncState.ts +126 -0
  369. package/src/composables/useSampleGroups.ts +126 -0
  370. package/src/composables/useSelectionLimit.ts +57 -0
  371. package/src/composables/useSortedItems.ts +118 -0
  372. package/src/composables/useTemplateCollection.ts +229 -0
  373. package/src/composables/useTextSearch.ts +60 -0
  374. package/src/composables/useTheme.ts +2 -28
  375. package/src/composables/useTimeUtils.ts +26 -2
  376. package/src/composables/useWellPlateEditor.ts +13 -9
  377. package/src/index.ts +228 -4
  378. package/src/install.ts +11 -4
  379. package/src/stores/settings.ts +13 -9
  380. package/src/styles/components/app-page-selector.css +23 -0
  381. package/src/styles/components/app-pill-nav.css +8 -2
  382. package/src/styles/components/app-top-bar.css +35 -2
  383. package/src/styles/components/button.css +3 -7
  384. package/src/styles/components/concentration-input.css +3 -142
  385. package/src/styles/components/dropdown-button.css +4 -4
  386. package/src/styles/components/empty-state.css +0 -16
  387. package/src/styles/components/input.css +4 -5
  388. package/src/styles/components/number-input.css +3 -3
  389. package/src/styles/components/plugin-icon.css +38 -0
  390. package/src/styles/components/segmented-control.css +4 -7
  391. package/src/styles/components/settings-button.css +3 -66
  392. package/src/styles/components/settings-modal.css +184 -0
  393. package/src/styles/components/tabs.css +1 -2
  394. package/src/styles/components/textarea.css +4 -5
  395. package/src/styles/components/theme-toggle.css +3 -66
  396. package/src/styles/components/unit-input.css +3 -3
  397. package/src/styles/index.css +0 -1
  398. package/src/templates/adapters.ts +785 -0
  399. package/src/templates/builders.ts +2149 -0
  400. package/src/templates/catalog.ts +245 -0
  401. package/src/templates/componentBindings.ts +615 -0
  402. package/src/templates/controlSchemas.ts +718 -0
  403. package/src/templates/index.ts +314 -0
  404. package/src/templates/lookup.ts +18 -0
  405. package/src/templates/packs.ts +156 -0
  406. package/src/templates/presets.ts +146 -0
  407. package/src/templates/types.ts +668 -0
  408. package/src/types/components.ts +80 -1
  409. package/src/types/form-builder.ts +7 -2
  410. package/src/types/index.ts +17 -0
  411. package/src/types/platform.ts +8 -1
  412. package/src/utils/formModelSync.ts +52 -0
  413. package/src/utils/items.ts +28 -0
  414. package/src/utils/options.ts +23 -0
  415. package/src/utils/pluginIcon.ts +30 -0
  416. package/dist/auth-DsI0rQ7_.js.map +0 -1
  417. package/dist/components-CzbQQPCb.js.map +0 -1
  418. package/dist/composables-BXklV5ii.js.map +0 -1
  419. package/dist/useScheduleDrag-CxBeqYcu.js +0 -7181
  420. package/dist/useScheduleDrag-CxBeqYcu.js.map +0 -1
  421. package/src/styles/components/grouping-modal.css +0 -323
@@ -1,7 +1,13 @@
1
1
  <script setup lang="ts">
2
2
  /** Input that opens a scrollable time-slot dropdown in 12h or 24h format, with min/max range. */
3
- import { ref, computed, watch, nextTick, onMounted, onUnmounted } from 'vue'
4
- import { generateTimeSlots, formatTime, parseTime, compareTime } from '../composables/useTimeUtils'
3
+ import { ref, computed, watch, nextTick } from 'vue'
4
+ import { useDropdownState } from '../composables/useDropdownState'
5
+ import {
6
+ compareTime,
7
+ findNearestTimeSlotIndex,
8
+ formatTimeSlot,
9
+ generateTimeSlots,
10
+ } from '../composables/useTimeUtils'
5
11
 
6
12
  interface Props {
7
13
  modelValue?: string
@@ -30,10 +36,9 @@ const emit = defineEmits<{
30
36
  'update:modelValue': [value: string | undefined]
31
37
  }>()
32
38
 
33
- const isOpen = ref(false)
34
- const containerRef = ref<HTMLDivElement>()
35
- const listRef = ref<HTMLUListElement>()
39
+ const listRef = ref<HTMLUListElement | null>(null)
36
40
  const highlightedIndex = ref(-1)
41
+ const { isOpen, rootRef, open, close, toggle } = useDropdownState()
37
42
 
38
43
  const slots = computed(() => {
39
44
  const start = props.min ?? '00:00'
@@ -43,8 +48,7 @@ const slots = computed(() => {
43
48
 
44
49
  const displayValue = computed(() => {
45
50
  if (!props.modelValue) return ''
46
- const { hour, minute } = parseTime(props.modelValue)
47
- return formatTime(hour, minute, props.format)
51
+ return formatTimeSlot(props.modelValue, props.format)
48
52
  })
49
53
 
50
54
  function isSlotDisabled(slot: string): boolean {
@@ -56,23 +60,17 @@ function isSlotDisabled(slot: string): boolean {
56
60
  function selectSlot(slot: string) {
57
61
  if (isSlotDisabled(slot) || props.disabled) return
58
62
  emit('update:modelValue', slot)
59
- isOpen.value = false
63
+ close()
60
64
  }
61
65
 
62
66
  function clear() {
63
67
  emit('update:modelValue', undefined)
64
- isOpen.value = false
68
+ close()
65
69
  }
66
70
 
67
71
  function toggleDropdown() {
68
72
  if (props.disabled) return
69
- isOpen.value = !isOpen.value
70
- }
71
-
72
- function handleClickOutside(event: MouseEvent) {
73
- if (containerRef.value && !containerRef.value.contains(event.target as Node)) {
74
- isOpen.value = false
75
- }
73
+ toggle()
76
74
  }
77
75
 
78
76
  function scrollToActiveSlot() {
@@ -95,26 +93,14 @@ function scrollToActiveSlot() {
95
93
  }
96
94
 
97
95
  function findNearestSlotIndex(time: string): number {
98
- if (slots.value.length === 0) return -1
99
- let bestIndex = 0
100
- let bestDiff = Infinity
101
- for (let i = 0; i < slots.value.length; i++) {
102
- const { hour: h1, minute: m1 } = parseTime(slots.value[i])
103
- const { hour: h2, minute: m2 } = parseTime(time)
104
- const minuteDiff = Math.abs((h1 * 60 + m1) - (h2 * 60 + m2))
105
- if (minuteDiff < bestDiff) {
106
- bestDiff = minuteDiff
107
- bestIndex = i
108
- }
109
- }
110
- return bestIndex
96
+ return findNearestTimeSlotIndex(time, slots.value)
111
97
  }
112
98
 
113
99
  function handleKeydown(event: KeyboardEvent) {
114
100
  if (!isOpen.value) {
115
101
  if (event.key === 'Enter' || event.key === ' ' || event.key === 'ArrowDown') {
116
102
  event.preventDefault()
117
- isOpen.value = true
103
+ open()
118
104
  return
119
105
  }
120
106
  return
@@ -150,7 +136,7 @@ function handleKeydown(event: KeyboardEvent) {
150
136
  }
151
137
  case 'Escape': {
152
138
  event.preventDefault()
153
- isOpen.value = false
139
+ close()
154
140
  break
155
141
  }
156
142
  }
@@ -180,18 +166,10 @@ watch(isOpen, (open) => {
180
166
  highlightedIndex.value = -1
181
167
  }
182
168
  })
183
-
184
- onMounted(() => {
185
- document.addEventListener('click', handleClickOutside)
186
- })
187
-
188
- onUnmounted(() => {
189
- document.removeEventListener('click', handleClickOutside)
190
- })
191
169
  </script>
192
170
 
193
171
  <template>
194
- <div ref="containerRef" class="mint-time-picker" @keydown="handleKeydown">
172
+ <div ref="rootRef" class="mint-time-picker" @keydown="handleKeydown">
195
173
  <div class="mint-time-picker__input-wrapper">
196
174
  <input
197
175
  type="text"
@@ -260,7 +238,7 @@ onUnmounted(() => {
260
238
  ]"
261
239
  @click="selectSlot(slot)"
262
240
  >
263
- {{ formatTime(parseTime(slot).hour, parseTime(slot).minute, format) }}
241
+ {{ formatTimeSlot(slot, format) }}
264
242
  </li>
265
243
  </ul>
266
244
  </div>
@@ -1,62 +1,9 @@
1
+ <!-- @deprecated Use AppToastContainer instead -->
1
2
  <script setup lang="ts">
2
- /** Teleported toast stack driven by useToast, with auto-dismiss progress bar and click-to-close on each notification. */
3
- import { useToast } from '../composables/useToast'
4
- import type { Toast } from '../types'
5
-
6
- const { toasts, dismiss } = useToast()
7
-
8
- const accentColors: Record<Toast['type'], string> = {
9
- success: '#10B981',
10
- error: '#EF4444',
11
- warning: '#F59E0B',
12
- info: '#3B82F6',
13
- }
3
+ /** @deprecated Compatibility wrapper for the legacy toast container export. Use AppToastContainer instead. */
4
+ import AppToastContainer from './AppToastContainer.vue'
14
5
  </script>
15
6
 
16
7
  <template>
17
- <Teleport to="body">
18
- <div class="mint-toast__container">
19
- <TransitionGroup name="toast">
20
- <div
21
- v-for="toast in toasts"
22
- :key="toast.id"
23
- :class="['mint-toast__item', `mint-toast__item--${toast.type}`]"
24
- :style="{
25
- borderLeftColor: accentColors[toast.type],
26
- }"
27
- role="alert"
28
- @click="dismiss(toast.id)"
29
- >
30
- <!-- Lucide circle-check -->
31
- <svg v-if="toast.type === 'success'" class="mint-toast__icon" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" :style="{ color: accentColors[toast.type] }">
32
- <circle cx="12" cy="12" r="10" /><path d="m9 12 2 2 4-4" />
33
- </svg>
34
- <!-- Lucide circle-x -->
35
- <svg v-else-if="toast.type === 'error'" class="mint-toast__icon" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" :style="{ color: accentColors[toast.type] }">
36
- <circle cx="12" cy="12" r="10" /><path d="m15 9-6 6" /><path d="m9 9 6 6" />
37
- </svg>
38
- <!-- Lucide triangle-alert -->
39
- <svg v-else-if="toast.type === 'warning'" class="mint-toast__icon" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" :style="{ color: accentColors[toast.type] }">
40
- <path d="m21.73 18-8-14a2 2 0 0 0-3.48 0l-8 14A2 2 0 0 0 4 21h16a2 2 0 0 0 1.73-3" /><path d="M12 9v4" /><path d="M12 17h.01" />
41
- </svg>
42
- <!-- Lucide info -->
43
- <svg v-else class="mint-toast__icon" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" :style="{ color: accentColors[toast.type] }">
44
- <circle cx="12" cy="12" r="10" /><path d="M12 16v-4" /><path d="M12 8h.01" />
45
- </svg>
46
- <span class="mint-toast__message">{{ toast.message }}</span>
47
- <span
48
- class="mint-toast__progress"
49
- :style="{
50
- backgroundColor: accentColors[toast.type],
51
- animationDuration: `${toast.duration ?? 3500}ms`,
52
- }"
53
- />
54
- </div>
55
- </TransitionGroup>
56
- </div>
57
- </Teleport>
8
+ <AppToastContainer />
58
9
  </template>
59
-
60
- <style>
61
- @import '../styles/components/toast.css';
62
- </style>
@@ -2,6 +2,7 @@
2
2
  /** Floating tooltip using @floating-ui with auto-flip, delay, optional keyboard shortcut badge, and body Teleport. */
3
3
  import { ref, onBeforeUnmount, nextTick } from 'vue'
4
4
  import { computePosition, flip, offset, shift, type Placement } from '@floating-ui/dom'
5
+ import { useEventListener } from '../composables/useEventListener'
5
6
 
6
7
  interface Props {
7
8
  text: string
@@ -42,22 +43,18 @@ async function updatePosition() {
42
43
  actualPlacement.value = placement
43
44
  }
44
45
 
45
- function addListeners() {
46
- window.addEventListener('scroll', updatePosition, { passive: true, capture: true })
47
- window.addEventListener('resize', updatePosition)
48
- }
49
-
50
- function removeListeners() {
51
- window.removeEventListener('scroll', updatePosition, { capture: true })
52
- window.removeEventListener('resize', updatePosition)
53
- }
46
+ useEventListener(() => window, 'scroll', updatePosition, {
47
+ passive: true,
48
+ capture: true,
49
+ enabled: visible,
50
+ })
51
+ useEventListener(() => window, 'resize', updatePosition, { enabled: visible })
54
52
 
55
53
  async function show() {
56
54
  timeoutId = setTimeout(async () => {
57
55
  visible.value = true
58
56
  await nextTick()
59
57
  await updatePosition()
60
- addListeners()
61
58
  }, props.delay)
62
59
  }
63
60
 
@@ -65,12 +62,10 @@ function hide() {
65
62
  clearTimeout(timeoutId)
66
63
  timeoutId = undefined
67
64
  visible.value = false
68
- removeListeners()
69
65
  }
70
66
 
71
67
  onBeforeUnmount(() => {
72
68
  clearTimeout(timeoutId)
73
- removeListeners()
74
69
  })
75
70
 
76
71
  function resolvedMaxWidth(value: string | number | undefined): string | undefined {
@@ -1,6 +1,7 @@
1
1
  <script setup lang="ts">
2
- import { ref, watch, computed, onMounted, onUnmounted } from 'vue'
2
+ import { ref, watch, computed } from 'vue'
3
3
  import type { Well, WellEditData, WellEditField } from '../types'
4
+ import { useEventListener } from '../composables/useEventListener'
4
5
 
5
6
  interface Props {
6
7
  wellId: string
@@ -83,13 +84,7 @@ function handleKeydown(e: KeyboardEvent) {
83
84
  if (e.key === 'Escape') close()
84
85
  }
85
86
 
86
- onMounted(() => {
87
- document.addEventListener('keydown', handleKeydown)
88
- })
89
-
90
- onUnmounted(() => {
91
- document.removeEventListener('keydown', handleKeydown)
92
- })
87
+ useEventListener(() => document, 'keydown', handleKeydown)
93
88
 
94
89
  const sampleTypeButtons = [
95
90
  { type: 'sample', label: 'S', tooltip: 'Sample' },
@@ -1,7 +1,8 @@
1
1
  <script setup lang="ts">
2
2
  /** Interactive 96/384-well plate grid with drag-to-select, heatmap overlays, per-well editing, and sample-color mapping. */
3
- import { ref, computed, onMounted, onUnmounted } from 'vue'
3
+ import { ref, computed } from 'vue'
4
4
  import type { WellPlateFormat, WellPlateSelectionMode, WellPlateSize, Well, HeatmapConfig, WellShape, WellEditField, WellEditData, WellLegendItem, ColumnCondition, RowCondition } from '../types'
5
+ import { useEventListener } from '../composables/useEventListener'
5
6
  import WellEditPopup from './WellEditPopup.vue'
6
7
 
7
8
  interface Props {
@@ -562,15 +563,8 @@ function handleKeyDown(event: KeyboardEvent) {
562
563
  }
563
564
  }
564
565
 
565
- onMounted(() => {
566
- document.addEventListener('mouseup', handleMouseUp)
567
- document.addEventListener('keydown', handleKeyDown)
568
- })
569
-
570
- onUnmounted(() => {
571
- document.removeEventListener('mouseup', handleMouseUp)
572
- document.removeEventListener('keydown', handleKeyDown)
573
- })
566
+ useEventListener(() => document, 'mouseup', handleMouseUp)
567
+ useEventListener(() => document, 'keydown', handleKeyDown)
574
568
 
575
569
  const containerStyle = computed(() =>
576
570
  isFillMode.value ? {} : {
@@ -27,12 +27,14 @@ export { default as FileUploader } from './FileUploader.vue'
27
27
 
28
28
  // Feedback components
29
29
  export { default as AlertBox } from './AlertBox.vue'
30
+ /** @deprecated Use AppToastContainer instead. */
30
31
  export { default as ToastNotification } from './ToastNotification.vue'
31
- export { default as AppToastContainer } from './ToastNotification.vue'
32
+ export { default as AppToastContainer } from './AppToastContainer.vue'
32
33
 
33
34
  // Action components
34
35
  export { default as IconButton } from './IconButton.vue'
35
36
  export { default as ThemeToggle } from './ThemeToggle.vue'
37
+ /** @deprecated Use AppTopBar instead. */
36
38
  export { default as SettingsButton } from './SettingsButton.vue'
37
39
 
38
40
  // Layout components
@@ -44,7 +46,9 @@ export { default as AppAvatarMenu } from './AppAvatarMenu.vue'
44
46
  export { default as AppPluginSwitcher } from './AppPluginSwitcher.vue'
45
47
  export { default as AppSidebar } from './AppSidebar.vue'
46
48
  export { default as AppLayout } from './AppLayout.vue'
49
+ export { default as ControlWorkspaceView } from './ControlWorkspaceView.vue'
47
50
  export { default as AppContainer } from './AppContainer.vue'
51
+ export { default as PluginIcon } from './PluginIcon.vue'
48
52
 
49
53
  // Utility components
50
54
  export { default as Skeleton } from './Skeleton.vue'
@@ -61,6 +65,10 @@ export { default as ChartContainer } from './ChartContainer.vue'
61
65
  export { default as SettingsModal } from './SettingsModal.vue'
62
66
 
63
67
  // Biological experiment components
68
+ export { default as BioTemplateRenderer } from './BioTemplateRenderer.vue'
69
+ export { default as BioTemplateExperimentWorkspaceView } from './BioTemplateExperimentWorkspaceView.vue'
70
+ export { default as BioTemplatePackWorkspaceView } from './BioTemplatePackWorkspaceView.vue'
71
+ export { default as BioTemplatePresetWorkspaceView } from './BioTemplatePresetWorkspaceView.vue'
64
72
  export { default as WellPlate } from './WellPlate.vue'
65
73
  export { default as RackEditor } from './RackEditor.vue'
66
74
  export { default as SampleLegend } from './SampleLegend.vue'
@@ -69,6 +77,7 @@ export { default as ExperimentTimeline } from './ExperimentTimeline.vue'
69
77
 
70
78
  // Sample management components
71
79
  export { default as SampleSelector } from './SampleSelector.vue'
80
+ /** @deprecated Use AutoGroupModal instead. */
72
81
  export { default as GroupingModal } from './GroupingModal.vue'
73
82
  export { default as AutoGroupModal } from './AutoGroupModal.vue'
74
83
  export { default as GroupAssigner } from './GroupAssigner.vue'
@@ -98,8 +107,10 @@ export { default as BatchProgressList } from './BatchProgressList.vue'
98
107
 
99
108
  // Form builder components
100
109
  export { default as FormBuilder } from './FormBuilder.vue'
110
+ /** @deprecated Use FormBuilder instead. */
101
111
  export { default as FormSection } from './FormSection.vue'
102
112
  export { default as FormActions } from './FormActions.vue'
113
+ /** @deprecated Use FormBuilder instead. */
103
114
  export { default as FormFieldRenderer } from './FormFieldRenderer.vue'
104
115
 
105
116
  // Experiment data display components
@@ -0,0 +1,50 @@
1
+ <script setup lang="ts">
2
+ import { computed } from 'vue'
3
+ import type { FormFieldSchema } from '../../types/form-builder'
4
+ import type { UseFormReturn } from '../../composables/useForm'
5
+ import { getFieldRegistryEntry } from '../../composables/formBuilderRegistry'
6
+ import FormField from '../FormField.vue'
7
+
8
+ interface Props {
9
+ field: FormFieldSchema
10
+ resolvedProps: Record<string, unknown>
11
+ form: UseFormReturn<Record<string, unknown>>
12
+ }
13
+
14
+ const props = defineProps<Props>()
15
+
16
+ const entry = computed(() => getFieldRegistryEntry(props.field.type))
17
+
18
+ const errorMessage = computed(() => {
19
+ const name = props.field.name
20
+ return props.form.touched[name] ? props.form.errors[name] : null
21
+ })
22
+
23
+ function handleUpload(files: File[]) {
24
+ props.form.setFieldValue(props.field.name, files)
25
+ }
26
+ </script>
27
+
28
+ <template>
29
+ <FormField
30
+ :label="field.label"
31
+ :error="errorMessage ?? undefined"
32
+ :hint="field.hint"
33
+ :required="!!field.validation?.required"
34
+ :html-for="field.name"
35
+ >
36
+ <slot :name="`field:${field.name}`" :field="field" :form="form" :field-props="form.getFieldProps(field.name)">
37
+ <component
38
+ :is="entry.component"
39
+ v-if="entry.vModel"
40
+ v-bind="resolvedProps"
41
+ />
42
+ <component
43
+ :is="entry.component"
44
+ v-else
45
+ v-bind="resolvedProps"
46
+ @upload="handleUpload"
47
+ />
48
+ </slot>
49
+ </FormField>
50
+ </template>
@@ -0,0 +1,78 @@
1
+ <script setup lang="ts">
2
+ import { computed } from 'vue'
3
+ import type { FormSectionSchema, UseFormBuilderReturn } from '../../types/form-builder'
4
+ import CollapsibleCard from '../CollapsibleCard.vue'
5
+ import FormFieldRendererInternal from './FormFieldRendererInternal.vue'
6
+
7
+ interface Props {
8
+ section: FormSectionSchema
9
+ builder: UseFormBuilderReturn<Record<string, unknown>>
10
+ }
11
+
12
+ const props = defineProps<Props>()
13
+
14
+ const visibleFields = computed(() =>
15
+ props.section.fields.filter((f) => props.builder.isFieldVisible(f.name)),
16
+ )
17
+
18
+ const gridStyle = computed(() => ({
19
+ gridTemplateColumns: `repeat(${props.section.columns ?? 1}, 1fr)`,
20
+ }))
21
+ </script>
22
+
23
+ <template>
24
+ <div v-if="visibleFields.length > 0" class="mint-form-section">
25
+ <slot :name="`section:${section.id}`" :section="section" :form="builder.form">
26
+ <CollapsibleCard
27
+ v-if="section.collapsible"
28
+ :title="section.title"
29
+ :subtitle="section.description"
30
+ :default-open="section.defaultOpen ?? true"
31
+ >
32
+ <div class="mint-form-section__grid" :style="gridStyle">
33
+ <div
34
+ v-for="field in visibleFields"
35
+ :key="field.name"
36
+ :style="field.colSpan ? { gridColumn: `span ${field.colSpan}` } : undefined"
37
+ >
38
+ <slot :name="`field:${field.name}`" :field="field" :form="builder.form" :field-props="builder.form.getFieldProps(field.name)">
39
+ <FormFieldRendererInternal
40
+ :field="field"
41
+ :resolved-props="builder.getResolvedFieldProps(field)"
42
+ :form="builder.form"
43
+ />
44
+ </slot>
45
+ </div>
46
+ </div>
47
+ </CollapsibleCard>
48
+
49
+ <div v-else class="mint-form-section--static">
50
+ <div v-if="section.title || section.description" class="mint-form-section__header">
51
+ <h3 v-if="section.title" class="mint-form-section__title">{{ section.title }}</h3>
52
+ <p v-if="section.description" class="mint-form-section__description">{{ section.description }}</p>
53
+ </div>
54
+ <div class="mint-form-section__grid" :style="gridStyle">
55
+ <div
56
+ v-for="field in visibleFields"
57
+ :key="field.name"
58
+ :style="field.colSpan ? { gridColumn: `span ${field.colSpan}` } : undefined"
59
+ >
60
+ <slot :name="`field:${field.name}`" :field="field" :form="builder.form" :field-props="builder.form.getFieldProps(field.name)">
61
+ <FormFieldRendererInternal
62
+ :field="field"
63
+ :resolved-props="builder.getResolvedFieldProps(field)"
64
+ :form="builder.form"
65
+ />
66
+ </slot>
67
+ </div>
68
+ </div>
69
+ </div>
70
+ </slot>
71
+
72
+ <slot :name="`section:${section.id}:after`" :form="builder.form" />
73
+ </div>
74
+ </template>
75
+
76
+ <style>
77
+ @import '../../styles/components/form-builder.css';
78
+ </style>