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

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (403) hide show
  1. package/README.md +44 -12
  2. package/dist/{ExperimentPopover-tLwJ7XF4.js → ExperimentPopover-oL0fg_A0.js} +6 -4
  3. package/dist/ExperimentPopover-oL0fg_A0.js.map +1 -0
  4. package/dist/{ExperimentSelectorModal-B6P2msT4.js → ExperimentSelectorModal-BeEOomw_.js} +5 -5
  5. package/dist/ExperimentSelectorModal-BeEOomw_.js.map +1 -0
  6. package/dist/{SettingsModal-BW3Ar-uy.js → SettingsModal-Dphh3RrI.js} +5 -8
  7. package/dist/SettingsModal-Dphh3RrI.js.map +1 -0
  8. package/dist/{EmptyState-p90quq8Z.js → Skeleton-DxtwJ5gt.js} +111 -93
  9. package/dist/Skeleton-DxtwJ5gt.js.map +1 -0
  10. package/dist/__tests__/components/ExperimentTimeline.test.d.ts +1 -0
  11. package/dist/__tests__/components/PluginWorkspaceView.internal.test.d.ts +1 -0
  12. package/dist/__tests__/components/SecretInput.test.d.ts +1 -0
  13. package/dist/__tests__/components/WellEditPopupInternal.test.d.ts +1 -0
  14. package/dist/__tests__/composables/useEventStream.test.d.ts +1 -0
  15. package/dist/__tests__/composables/useListReorder.test.d.ts +1 -0
  16. package/dist/__tests__/styles/cssTokens.test.d.ts +1 -0
  17. package/dist/components/ActionMenu.vue.d.ts +1 -1
  18. package/dist/components/AppAvatarMenu.vue.d.ts +4 -0
  19. package/dist/components/AppPluginSwitcher.vue.d.ts +2 -0
  20. package/dist/components/AppSidebar.vue.d.ts +1 -1
  21. package/dist/components/AuditTrail.vue.d.ts +13 -0
  22. package/dist/components/BatchProgressList.vue.d.ts +17 -0
  23. package/dist/components/BioTemplateExperimentWorkspaceView.vue.d.ts +1 -1
  24. package/dist/components/DataFrame.vue.d.ts +14 -2
  25. package/dist/components/DatePicker.vue.d.ts +1 -1
  26. package/dist/components/DateTimePicker.vue.d.ts +2 -0
  27. package/dist/components/DropdownButton.vue.d.ts +2 -0
  28. package/dist/components/ExperimentDataViewer.vue.d.ts +26 -1
  29. package/dist/components/ExperimentPopover.vue.d.ts +1 -0
  30. package/dist/components/ExperimentTimeline.vue.d.ts +29 -1
  31. package/dist/components/FitPanel.vue.d.ts +1 -1
  32. package/dist/components/LcmsSequenceTable.vue.d.ts +29 -1
  33. package/dist/components/PluginWorkspaceView.props.d.ts +29 -1
  34. package/dist/components/PluginWorkspaceView.vue.d.ts +5 -5
  35. package/dist/components/ProgressBar.vue.d.ts +1 -1
  36. package/dist/components/ProtocolStepEditor.vue.d.ts +1 -0
  37. package/dist/components/ReagentList.vue.d.ts +29 -1
  38. package/dist/components/SampleHierarchyTree.vue.d.ts +29 -1
  39. package/dist/components/SampleSelector.drag.d.ts +13 -0
  40. package/dist/components/SampleSelector.tree.d.ts +2 -0
  41. package/dist/components/SampleSelector.vue.d.ts +34 -1
  42. package/dist/components/ScheduleCalendar.vue.d.ts +20 -0
  43. package/dist/components/SecretInput.vue.d.ts +28 -0
  44. package/dist/components/SmartGroupFieldRecipe.vue.d.ts +2 -1
  45. package/dist/components/TimePicker.vue.d.ts +1 -0
  46. package/dist/components/WellPlate.geometry.d.ts +15 -0
  47. package/dist/components/WellPlate.interaction.d.ts +13 -0
  48. package/dist/components/WellPlate.vue.d.ts +29 -0
  49. package/dist/components/index.d.ts +9 -0
  50. package/dist/components/index.js +8 -8
  51. package/dist/components/internal/AppTopBarPageSelectorInternal.vue.d.ts +2 -0
  52. package/dist/components/internal/DataStateInternal.vue.d.ts +43 -0
  53. package/dist/components/internal/WellEditPopupInternal.vue.d.ts +3 -1
  54. package/dist/components/internal/WorkspaceControlsInternal.vue.d.ts +23 -0
  55. package/dist/components/internal/WorkspaceShellInternal.vue.d.ts +70 -0
  56. package/dist/components/internal/WorkspaceSidebarInternal.vue.d.ts +43 -0
  57. package/dist/{components-DQt0tcpY.js → components-CgAUzF8F.js} +2491 -2235
  58. package/dist/components-CgAUzF8F.js.map +1 -0
  59. package/dist/composables/controlSchemaTypes.d.ts +34 -0
  60. package/dist/composables/flattenWorkspaceBindings.d.ts +61 -0
  61. package/dist/composables/index.d.ts +8 -2
  62. package/dist/composables/index.js +10 -10
  63. package/dist/composables/pluginWorkspaceModel.d.ts +164 -0
  64. package/dist/composables/useAsync.d.ts +5 -1
  65. package/dist/composables/useBioTemplateWorkspace.d.ts +4 -20
  66. package/dist/composables/useCommandHistory.d.ts +5 -1
  67. package/dist/composables/useDropdownState.d.ts +18 -2
  68. package/dist/composables/useEventStream.d.ts +52 -0
  69. package/dist/composables/useFocusTrap.d.ts +21 -0
  70. package/dist/composables/useJobsStatusTray.d.ts +1 -1
  71. package/dist/composables/useListReorder.d.ts +90 -0
  72. package/dist/composables/useMenuKeyboard.d.ts +29 -0
  73. package/dist/composables/useOptimisticMutation.d.ts +5 -1
  74. package/dist/composables/usePluginClient.d.ts +4 -17
  75. package/dist/composables/usePluginConfig.d.ts +3 -1
  76. package/dist/composables/usePluginWorkspace.d.ts +51 -0
  77. package/dist/composables/useRequestSyncState.d.ts +42 -2
  78. package/dist/composables/useResourceCrud.d.ts +5 -1
  79. package/dist/composables/useRovingFocus.d.ts +24 -0
  80. package/dist/composables/useScheduleDrag.d.ts +1 -0
  81. package/dist/composables/useWellPainting.d.ts +5 -1
  82. package/dist/composables/useWellPlateAdapter.d.ts +5 -1
  83. package/dist/composables/useWellPlateValidation.d.ts +5 -1
  84. package/dist/composables/workspaceRecipes.d.ts +188 -0
  85. package/dist/{composables-CkXDe7nm.js → composables-B_pia3hO.js} +105 -254
  86. package/dist/composables-B_pia3hO.js.map +1 -0
  87. package/dist/{useApi-CDBq6z23.js → errors-_W0-LbA6.js} +102 -3
  88. package/dist/errors-_W0-LbA6.js.map +1 -0
  89. package/dist/{experiment-Y9Iz7KYi.js → experiment-Cwl9AYxw.js} +3 -8
  90. package/dist/experiment-Cwl9AYxw.js.map +1 -0
  91. package/dist/{experiment-utils-CLnzPPq5.js → experiment-utils-DV3DrvE_.js} +70 -51
  92. package/dist/experiment-utils-DV3DrvE_.js.map +1 -0
  93. package/dist/index.d.ts +1 -0
  94. package/dist/index.js +15 -15
  95. package/dist/install.js +2 -7
  96. package/dist/install.js.map +1 -1
  97. package/dist/permissions.d.ts +42 -1
  98. package/dist/permissions.js +20 -10
  99. package/dist/permissions.js.map +1 -1
  100. package/dist/stores/index.d.ts +1 -1
  101. package/dist/stores/index.js +3 -3
  102. package/dist/stores/settings.d.ts +31 -1
  103. package/dist/styles.css +11247 -29501
  104. package/dist/templates/builderReadUtils.d.ts +1 -1
  105. package/dist/templates/index.js +2 -4
  106. package/dist/{templates-CovvRZ-9.js → templates-Qq113pyZ.js} +303 -106
  107. package/dist/templates-Qq113pyZ.js.map +1 -0
  108. package/dist/types/form-builder.d.ts +1 -1
  109. package/dist/{useControlSchema-BhoJzWzx.js → useControlSchema-aMZlb4Sc.js} +684 -1216
  110. package/dist/useControlSchema-aMZlb4Sc.js.map +1 -0
  111. package/dist/{useDropdownState-DSb3BC3N.js → useDropdownState-DitCtrTT.js} +22 -6
  112. package/dist/useDropdownState-DitCtrTT.js.map +1 -0
  113. package/dist/{useExperimentSelector-D0pjj9WH.js → useExperimentSelector-I8HC8hUu.js} +4 -4
  114. package/dist/{useExperimentSelector-D0pjj9WH.js.map → useExperimentSelector-I8HC8hUu.js.map} +1 -1
  115. package/dist/{useFormBuilder-DiEcDis2.js → useFormBuilder-TCxNnqeb.js} +2 -2
  116. package/dist/{useFormBuilder-DiEcDis2.js.map → useFormBuilder-TCxNnqeb.js.map} +1 -1
  117. package/dist/{useProtocolTemplates-DHwSveE6.js → useProtocolTemplates-BmX_iVBR.js} +660 -197
  118. package/dist/useProtocolTemplates-BmX_iVBR.js.map +1 -0
  119. package/dist/utils/color.d.ts +13 -0
  120. package/dist/utils/errors.d.ts +9 -0
  121. package/dist/utils/pluginSecrets.d.ts +53 -0
  122. package/dist/utils/records.d.ts +4 -0
  123. package/package.json +1 -1
  124. package/src/__tests__/components/ActionMenu.test.ts +94 -0
  125. package/src/__tests__/components/AppAvatarMenu.test.ts +123 -0
  126. package/src/__tests__/components/BaseTabs.test.ts +67 -0
  127. package/src/__tests__/components/DataFrame.test.ts +183 -11
  128. package/src/__tests__/components/DataStates.test.ts +176 -0
  129. package/src/__tests__/components/DatePicker.test.ts +76 -0
  130. package/src/__tests__/components/DateTimePicker.test.ts +36 -0
  131. package/src/__tests__/components/DropdownButton.test.ts +134 -0
  132. package/src/__tests__/components/ExperimentTimeline.test.ts +63 -0
  133. package/src/__tests__/components/GeneratedPluginView.test.ts +0 -5
  134. package/src/__tests__/components/GroupAssigner.test.ts +53 -0
  135. package/src/__tests__/components/JobsStatusTray.test.ts +20 -18
  136. package/src/__tests__/components/LcmsSequenceTable.test.ts +22 -0
  137. package/src/__tests__/components/PluginWorkspaceView.internal.test.ts +230 -0
  138. package/src/__tests__/components/RackEditor.test.ts +35 -0
  139. package/src/__tests__/components/ReagentList.test.ts +64 -2
  140. package/src/__tests__/components/RetiredStyles.test.ts +31 -0
  141. package/src/__tests__/components/SampleSelector.drag.test.ts +51 -1
  142. package/src/__tests__/components/ScheduleCalendar.test.ts +63 -0
  143. package/src/__tests__/components/SecretInput.test.ts +87 -0
  144. package/src/__tests__/components/SegmentedControl.test.ts +88 -0
  145. package/src/__tests__/components/TimePicker.test.ts +61 -0
  146. package/src/__tests__/components/WellEditPopupInternal.test.ts +108 -0
  147. package/src/__tests__/components/WellPlate.interaction.test.ts +59 -0
  148. package/src/__tests__/composables/useAuth.test.ts +25 -0
  149. package/src/__tests__/composables/useDropdownState.test.ts +58 -1
  150. package/src/__tests__/composables/useEventStream.test.ts +140 -0
  151. package/src/__tests__/composables/useGeneratedAnalysis.test.ts +103 -0
  152. package/src/__tests__/composables/useJobsStatusTray.test.ts +25 -161
  153. package/src/__tests__/composables/useListReorder.test.ts +145 -0
  154. package/src/__tests__/composables/usePluginClient.test.ts +148 -13
  155. package/src/__tests__/composables/useRequestSyncState.test.ts +140 -0
  156. package/src/__tests__/docs/frontendDocsCatalog.test.ts +55 -2
  157. package/src/__tests__/stores/settings.test.ts +71 -1
  158. package/src/__tests__/styles/cssTokens.test.ts +131 -0
  159. package/src/__tests__/utils/permissions.test.ts +68 -0
  160. package/src/components/ActionMenu.vue +45 -88
  161. package/src/components/AlertBox.vue +0 -4
  162. package/src/components/AppAvatarMenu.vue +26 -7
  163. package/src/components/AppLayout.vue +0 -4
  164. package/src/components/AppPluginSwitcher.story.vue +87 -0
  165. package/src/components/AppPluginSwitcher.vue +2 -5
  166. package/src/components/AppSidebar.vue +0 -4
  167. package/src/components/AppToastContainer.vue +6 -8
  168. package/src/components/AppTopBar.vue +0 -4
  169. package/src/components/ArtifactSaveDialog.vue +0 -4
  170. package/src/components/ArtifactSelectorModal.vue +0 -4
  171. package/src/components/AuditTrail.story.vue +18 -0
  172. package/src/components/AuditTrail.vue +27 -7
  173. package/src/components/AutoGroupModal.vue +0 -4
  174. package/src/components/Avatar.vue +0 -4
  175. package/src/components/BaseButton.vue +0 -4
  176. package/src/components/BaseCheckbox.vue +0 -4
  177. package/src/components/BaseInput.vue +0 -4
  178. package/src/components/BaseModal.vue +8 -60
  179. package/src/components/BasePill.vue +0 -4
  180. package/src/components/BaseRadioGroup.vue +0 -4
  181. package/src/components/BaseSelect.vue +0 -4
  182. package/src/components/BaseSlider.vue +0 -4
  183. package/src/components/BaseTabs.vue +26 -5
  184. package/src/components/BaseTextarea.vue +0 -4
  185. package/src/components/BaseToggle.vue +0 -4
  186. package/src/components/BatchProgressList.story.vue +18 -0
  187. package/src/components/BatchProgressList.vue +32 -4
  188. package/src/components/BioTemplateExperimentWorkspaceView.vue +10 -21
  189. package/src/components/BioTemplatePackWorkspaceView.vue +11 -15
  190. package/src/components/BioTemplatePresetWorkspaceView.vue +8 -13
  191. package/src/components/Breadcrumb.vue +0 -4
  192. package/src/components/Calendar.vue +0 -4
  193. package/src/components/ChartContainer.story.vue +1 -1
  194. package/src/components/ChartContainer.vue +0 -4
  195. package/src/components/ChemicalFormula.vue +0 -4
  196. package/src/components/CollapsibleCard.vue +0 -4
  197. package/src/components/ColorSlider.vue +0 -4
  198. package/src/components/ComponentBindingRenderer.vue +1 -3
  199. package/src/components/ConcentrationInput.vue +0 -4
  200. package/src/components/ConfirmDialog.vue +0 -4
  201. package/src/components/ControlWorkspaceView.vue +11 -22
  202. package/src/components/DataFrame.story.vue +14 -0
  203. package/src/components/DataFrame.vue +97 -23
  204. package/src/components/DatePicker.vue +73 -27
  205. package/src/components/DateTimePicker.vue +45 -17
  206. package/src/components/Divider.vue +0 -4
  207. package/src/components/DoseCalculator.vue +0 -4
  208. package/src/components/DoseDesignWorkspaceView.vue +6 -25
  209. package/src/components/DropdownButton.vue +24 -6
  210. package/src/components/EmptyState.vue +0 -4
  211. package/src/components/ExperimentCodeBadge.vue +0 -4
  212. package/src/components/ExperimentDataViewer.story.vue +3 -0
  213. package/src/components/ExperimentDataViewer.vue +33 -13
  214. package/src/components/ExperimentPopover.vue +2 -5
  215. package/src/components/ExperimentSelectorModal.vue +0 -4
  216. package/src/components/ExperimentTimeline.story.vue +18 -0
  217. package/src/components/ExperimentTimeline.vue +81 -75
  218. package/src/components/FileUploader.vue +0 -4
  219. package/src/components/FitPanel.vue +0 -4
  220. package/src/components/FormActions.story.vue +96 -0
  221. package/src/components/FormActions.vue +0 -4
  222. package/src/components/FormBuilder.vue +0 -4
  223. package/src/components/FormField.vue +0 -4
  224. package/src/components/FormulaInput.vue +0 -4
  225. package/src/components/GeneratedPathInput.story.vue +68 -0
  226. package/src/components/GeneratedPlotlyResult.story.vue +96 -0
  227. package/src/components/GeneratedPlotlyResult.vue +3 -3
  228. package/src/components/GeneratedPluginView.story.vue +145 -0
  229. package/src/components/GeneratedPluginView.vue +10 -10
  230. package/src/components/GeneratedResultRenderer.story.vue +117 -0
  231. package/src/components/GeneratedResultRenderer.vue +4 -4
  232. package/src/components/GroupAssigner.vue +67 -5
  233. package/src/components/IconButton.vue +0 -4
  234. package/src/components/InstrumentAlertLog.vue +0 -4
  235. package/src/components/InstrumentStateBadge.vue +0 -4
  236. package/src/components/InstrumentStatusCard.vue +0 -4
  237. package/src/components/JobsStatusTray.story.vue +6 -10
  238. package/src/components/JobsStatusTray.vue +0 -4
  239. package/src/components/LcmsSequenceTable.vue +81 -50
  240. package/src/components/LoadingSpinner.vue +0 -4
  241. package/src/components/MobileSupportGate.vue +0 -4
  242. package/src/components/MoleculeInput.vue +0 -4
  243. package/src/components/MultiSelect.vue +0 -4
  244. package/src/components/NumberInput.vue +0 -4
  245. package/src/components/PlateMapEditor.vue +3 -14
  246. package/src/components/PluginIcon.vue +0 -4
  247. package/src/components/PluginWorkspaceView.props.ts +38 -0
  248. package/src/components/PluginWorkspaceView.vue +53 -224
  249. package/src/components/ProgressBar.vue +0 -4
  250. package/src/components/ProtocolStepEditor.vue +2 -4
  251. package/src/components/RackEditor.vue +51 -70
  252. package/src/components/ReagentEditor.vue +0 -4
  253. package/src/components/ReagentList.story.vue +18 -0
  254. package/src/components/ReagentList.vue +127 -82
  255. package/src/components/ResourceCard.vue +0 -4
  256. package/src/components/RuntimeUpdateNotice.story.vue +49 -0
  257. package/src/components/RuntimeUpdateNotice.vue +4 -4
  258. package/src/components/SampleHierarchyTree.story.vue +18 -0
  259. package/src/components/SampleHierarchyTree.vue +32 -9
  260. package/src/components/SampleLegend.vue +2 -8
  261. package/src/components/SampleSelector.drag.ts +51 -0
  262. package/src/components/SampleSelector.story.vue +6 -0
  263. package/src/components/SampleSelector.tree.ts +2 -0
  264. package/src/components/SampleSelector.vue +49 -10
  265. package/src/components/SampleSelectorGroupNode.vue +19 -0
  266. package/src/components/ScheduleCalendar.story.vue +6 -0
  267. package/src/components/ScheduleCalendar.vue +82 -7
  268. package/src/components/ScientificNumber.vue +0 -4
  269. package/src/components/SecretInput.story.vue +79 -0
  270. package/src/components/SecretInput.vue +150 -0
  271. package/src/components/SectionCard.vue +0 -4
  272. package/src/components/SegmentedControl.vue +48 -5
  273. package/src/components/SequenceInput.vue +0 -4
  274. package/src/components/SequenceProgressBar.story.vue +110 -0
  275. package/src/components/SequenceProgressBar.vue +0 -4
  276. package/src/components/SettingsModal.vue +0 -4
  277. package/src/components/Skeleton.vue +0 -4
  278. package/src/components/SmartGroupFieldRecipe.vue +8 -6
  279. package/src/components/SmartGroupManual.vue +0 -4
  280. package/src/components/StatusIndicator.vue +0 -4
  281. package/src/components/StepWizard.vue +0 -4
  282. package/src/components/TagsInput.vue +4 -6
  283. package/src/components/ThemeToggle.vue +0 -4
  284. package/src/components/TimePicker.vue +36 -7
  285. package/src/components/TimeRangeInput.vue +0 -4
  286. package/src/components/Tooltip.story.vue +3 -3
  287. package/src/components/Tooltip.vue +0 -4
  288. package/src/components/UnitInput.vue +0 -4
  289. package/src/components/WellPlate.geometry.ts +60 -1
  290. package/src/components/WellPlate.interaction.ts +44 -0
  291. package/src/components/WellPlate.story.vue +8 -0
  292. package/src/components/WellPlate.vue +53 -7
  293. package/src/components/index.ts +9 -0
  294. package/src/components/internal/AppTopBarPageSelectorInternal.vue +2 -5
  295. package/src/components/internal/AppTopBarPillNavInternal.vue +0 -4
  296. package/src/components/internal/DataStateInternal.vue +74 -0
  297. package/src/components/internal/FormSectionRenderer.vue +0 -4
  298. package/src/components/internal/WellEditPopupInternal.vue +20 -5
  299. package/src/components/internal/WorkspaceControlsInternal.vue +20 -0
  300. package/src/components/internal/WorkspaceShellInternal.vue +125 -0
  301. package/src/components/internal/WorkspaceSidebarInternal.vue +82 -0
  302. package/src/composables/controlSchemaTypes.ts +34 -0
  303. package/src/composables/experimentDesignData.ts +1 -3
  304. package/src/composables/flattenWorkspaceBindings.ts +104 -0
  305. package/src/composables/formBuilderRegistry.ts +5 -0
  306. package/src/composables/index.ts +41 -5
  307. package/src/composables/pluginWorkspaceModel.ts +182 -0
  308. package/src/composables/useAsync.ts +5 -1
  309. package/src/composables/useBioTemplatePackWorkspace.ts +15 -9
  310. package/src/composables/useBioTemplatePresetWorkspace.ts +14 -15
  311. package/src/composables/useBioTemplateWorkspace.ts +18 -43
  312. package/src/composables/useCommandHistory.ts +5 -1
  313. package/src/composables/useDropdownState.ts +35 -5
  314. package/src/composables/useEventStream.ts +326 -0
  315. package/src/composables/useFileImport.ts +2 -7
  316. package/src/composables/useFocusTrap.ts +91 -0
  317. package/src/composables/useGeneratedAnalysis.ts +46 -103
  318. package/src/composables/useJobsStatusTray.ts +1 -1
  319. package/src/composables/useListReorder.story.vue +143 -0
  320. package/src/composables/useListReorder.ts +242 -0
  321. package/src/composables/useMenuKeyboard.ts +90 -0
  322. package/src/composables/useOptimisticMutation.ts +6 -16
  323. package/src/composables/usePluginClient.ts +91 -252
  324. package/src/composables/usePluginConfig.ts +3 -1
  325. package/src/composables/usePluginWorkspace.ts +208 -0
  326. package/src/composables/useRackEditor.ts +2 -11
  327. package/src/composables/useRequestSyncState.ts +98 -28
  328. package/src/composables/useResourceCrud.ts +6 -16
  329. package/src/composables/useRovingFocus.ts +66 -0
  330. package/src/composables/useScheduleDrag.ts +37 -0
  331. package/src/composables/useWellPainting.ts +10 -30
  332. package/src/composables/useWellPlateAdapter.ts +5 -1
  333. package/src/composables/useWellPlateEditor.ts +1 -11
  334. package/src/composables/useWellPlateValidation.ts +5 -1
  335. package/src/composables/workspaceRecipes.ts +267 -0
  336. package/src/index.ts +16 -0
  337. package/src/permissions.ts +48 -9
  338. package/src/stores/experiment.ts +2 -7
  339. package/src/stores/index.ts +9 -1
  340. package/src/stores/settings.ts +93 -1
  341. package/src/styles/components/audit-trail.css +5 -5
  342. package/src/styles/components/batch-progress-list.css +7 -0
  343. package/src/styles/components/color-slider.css +2 -2
  344. package/src/styles/components/data-state.css +30 -0
  345. package/src/styles/components/dataframe.css +29 -35
  346. package/src/styles/components/experiment-data-viewer.css +4 -4
  347. package/src/styles/components/experiment-timeline.css +3 -30
  348. package/src/styles/components/form-builder.css +5 -5
  349. package/src/styles/components/lcms-sequence-table.css +16 -1
  350. package/src/styles/components/multi-select.css +1 -1
  351. package/src/styles/components/reagent-list.css +38 -31
  352. package/src/styles/components/sample-hierarchy-tree.css +5 -19
  353. package/src/styles/components/sample-selector.css +9 -2
  354. package/src/styles/components/schedule-calendar.css +8 -0
  355. package/src/styles/components/scientific-number.css +1 -1
  356. package/src/styles/components/secret-input.css +60 -0
  357. package/src/styles/components/well-plate.css +8 -0
  358. package/src/styles/index.css +9 -0
  359. package/src/styles/variables.css +29 -0
  360. package/src/templates/builderPresetControls.ts +1 -1
  361. package/src/templates/builderReadUtils.ts +1 -3
  362. package/src/templates/componentPlateHelpers.ts +3 -1
  363. package/src/templates/componentTargetResolvers.ts +1 -3
  364. package/src/templates/controlSchemaTargets.ts +1 -3
  365. package/src/templates/doseResponseAdapters.ts +2 -13
  366. package/src/templates/elisaAssayCollectionBuilder.ts +2 -2
  367. package/src/templates/plateMapBuilder.ts +2 -2
  368. package/src/templates/qpcrPlateBuilder.ts +1 -1
  369. package/src/templates/templateValidators.ts +1 -1
  370. package/src/templates/timeCourseBuilder.ts +2 -2
  371. package/src/templates/wellPlateScreenCollectionBuilder.ts +2 -2
  372. package/src/types/form-builder.ts +1 -0
  373. package/src/utils/color.ts +51 -0
  374. package/src/utils/errors.ts +29 -0
  375. package/src/utils/formModelSync.ts +1 -3
  376. package/src/utils/pluginIcon.ts +1 -3
  377. package/src/utils/pluginSecrets.ts +102 -0
  378. package/src/utils/records.ts +9 -0
  379. package/dist/EmptyState-p90quq8Z.js.map +0 -1
  380. package/dist/ExperimentPopover-tLwJ7XF4.js.map +0 -1
  381. package/dist/ExperimentSelectorModal-B6P2msT4.js.map +0 -1
  382. package/dist/SettingsModal-BW3Ar-uy.js.map +0 -1
  383. package/dist/components-DQt0tcpY.js.map +0 -1
  384. package/dist/composables/autoGroupConstants.d.ts +0 -1
  385. package/dist/composables/autoGroupGrouping.d.ts +0 -3
  386. package/dist/composables/useAutoGroupInputSources.d.ts +0 -32
  387. package/dist/composables-CkXDe7nm.js.map +0 -1
  388. package/dist/experiment-Y9Iz7KYi.js.map +0 -1
  389. package/dist/experiment-utils-CLnzPPq5.js.map +0 -1
  390. package/dist/templates/builderDefaults.d.ts +0 -1
  391. package/dist/templates/plateGeometry.d.ts +0 -4
  392. package/dist/templates-CovvRZ-9.js.map +0 -1
  393. package/dist/useApi-CDBq6z23.js.map +0 -1
  394. package/dist/useControlSchema-BhoJzWzx.js.map +0 -1
  395. package/dist/useDropdownState-DSb3BC3N.js.map +0 -1
  396. package/dist/useProtocolTemplates-DHwSveE6.js.map +0 -1
  397. package/src/__tests__/composables/useAutoGroupInputSources.test.ts +0 -127
  398. package/src/composables/autoGroupConstants.ts +0 -4
  399. package/src/composables/autoGroupGrouping.ts +0 -148
  400. package/src/composables/useAutoGroupInputSources.ts +0 -147
  401. package/src/templates/builderDefaults.ts +0 -11
  402. package/src/templates/plateGeometry.ts +0 -62
  403. /package/dist/__tests__/{composables/useAutoGroupInputSources.test.d.ts → components/DataStates.test.d.ts} +0 -0
@@ -187,6 +187,23 @@
187
187
  text-align: center;
188
188
  }
189
189
 
190
+ /* Sortable headers are real buttons; strip the native chrome so the cell keeps
191
+ its table-header appearance while staying keyboard-operable. */
192
+ .mint-dataframe__th-button {
193
+ display: block;
194
+ width: 100%;
195
+ margin: 0;
196
+ padding: 0;
197
+ border: 0;
198
+ background: none;
199
+ color: inherit;
200
+ font: inherit;
201
+ letter-spacing: inherit;
202
+ text-transform: inherit;
203
+ text-align: inherit;
204
+ cursor: inherit;
205
+ }
206
+
190
207
  .mint-dataframe__th-content {
191
208
  display: inline-flex;
192
209
  align-items: center;
@@ -308,7 +325,7 @@
308
325
  }
309
326
 
310
327
  .mint-dataframe__row--clickable:focus-visible {
311
- outline: 2px solid var(--focus-ring-color, var(--color-primary));
328
+ outline: 2px solid var(--color-primary);
312
329
  outline-offset: -2px;
313
330
  }
314
331
 
@@ -352,32 +369,15 @@ html.dark .mint-dataframe__row--selected > .mint-dataframe__td {
352
369
  border-bottom: none;
353
370
  }
354
371
 
355
- /* Empty state */
356
- .mint-dataframe__empty {
372
+ /* Empty / error placeholder host (content comes from EmptyState) */
373
+ .mint-dataframe__state {
357
374
  display: flex;
358
- flex-direction: column;
359
375
  align-items: center;
360
376
  justify-content: center;
361
377
  min-height: 12rem;
362
- padding: 2.5rem 2rem;
363
- color: var(--text-muted);
364
378
  background-color: var(--bg-primary);
365
379
  }
366
380
 
367
- .mint-dataframe__empty-icon {
368
- width: 2.5rem;
369
- height: 2.5rem;
370
- opacity: 0.5;
371
- margin-bottom: 0.5rem;
372
- }
373
-
374
- .mint-dataframe__empty-text {
375
- font-size: 0.875rem;
376
- margin-top: 0 !important;
377
- margin-bottom: 0 !important;
378
- padding: 0 !important;
379
- }
380
-
381
381
  /* Loading overlay */
382
382
  .mint-dataframe__loading {
383
383
  position: absolute;
@@ -395,18 +395,6 @@ html.dark .mint-dataframe__loading {
395
395
  background-color: rgba(0, 0, 0, 0.4);
396
396
  }
397
397
 
398
- .mint-dataframe__loading-spinner {
399
- width: 1.5rem;
400
- height: 1.5rem;
401
- color: var(--color-primary);
402
- animation: mint-dataframe-spin 1s linear infinite;
403
- }
404
-
405
- @keyframes mint-dataframe-spin {
406
- from { transform: rotate(0deg); }
407
- to { transform: rotate(360deg); }
408
- }
409
-
410
398
  /* Footer / Pagination */
411
399
  .mint-dataframe__footer {
412
400
  display: flex;
@@ -502,11 +490,17 @@ html.dark .mint-dataframe__loading {
502
490
  transition: background-color 0.15s ease;
503
491
  }
504
492
 
505
- .mint-dataframe__resize-handle:hover::after {
493
+ .mint-dataframe__resize-handle:hover::after,
494
+ .mint-dataframe__resize-handle:focus-visible::after {
506
495
  width: 2px;
507
496
  background-color: var(--color-primary);
508
497
  }
509
498
 
499
+ .mint-dataframe__resize-handle:focus-visible {
500
+ outline: none;
501
+ box-shadow: var(--focus-ring);
502
+ }
503
+
510
504
  /* Row delete action column */
511
505
  .mint-dataframe__th--actions,
512
506
  .mint-dataframe__td--actions {
@@ -539,8 +533,8 @@ html.dark .mint-dataframe__loading {
539
533
  }
540
534
 
541
535
  .mint-dataframe__delete-btn:hover {
542
- background-color: color-mix(in srgb, var(--color-error, #ef4444) 14%, transparent);
543
- color: var(--color-error, #ef4444);
536
+ background-color: color-mix(in srgb, var(--mint-error) 14%, transparent);
537
+ color: var(--mint-error);
544
538
  }
545
539
 
546
540
  .mint-dataframe__delete-btn:focus-visible {
@@ -27,10 +27,10 @@
27
27
  flex-direction: column;
28
28
  gap: 12px;
29
29
  }
30
- .mint-data-viewer__empty {
31
- text-align: center;
32
- padding: 32px;
33
- color: var(--text-muted);
30
+ .mint-data-viewer__state {
31
+ display: flex;
32
+ align-items: center;
33
+ justify-content: center;
34
34
  }
35
35
 
36
36
  /* Summary view */
@@ -291,7 +291,7 @@
291
291
  .mint-timeline__expanded {
292
292
  margin-top: 0.75rem;
293
293
  padding-top: 0.75rem;
294
- border-top: 1px solid rgba(var(--border-color-rgb, 0, 0, 0), 0.5);
294
+ border-top: 1px solid color-mix(in srgb, var(--border-color) 50%, transparent);
295
295
  }
296
296
 
297
297
  .mint-timeline__description {
@@ -434,42 +434,15 @@
434
434
  width: 2rem;
435
435
  }
436
436
 
437
- /* Empty state */
438
- .mint-timeline__empty {
437
+ /* Empty / loading / error placeholder host (content comes from EmptyState) */
438
+ .mint-timeline__state {
439
439
  display: flex;
440
440
  align-items: center;
441
441
  justify-content: center;
442
- padding: 2rem;
443
442
  border: 2px dashed var(--border-color);
444
443
  border-radius: var(--radius-md);
445
444
  }
446
445
 
447
- .mint-timeline__empty-content {
448
- text-align: center;
449
- }
450
-
451
- .mint-timeline__empty-text {
452
- color: var(--text-muted);
453
- margin-top: 0 !important;
454
- margin-bottom: 0.5rem !important;
455
- padding: 0 !important;
456
- }
457
-
458
- .mint-timeline__empty-btn {
459
- padding: 0.375rem 0.75rem;
460
- font-size: 0.875rem;
461
- background-color: var(--color-primary);
462
- color: white;
463
- border: none;
464
- border-radius: var(--radius-md);
465
- cursor: pointer;
466
- transition: background-color 0.15s ease;
467
- }
468
-
469
- .mint-timeline__empty-btn:hover {
470
- opacity: 0.9;
471
- }
472
-
473
446
  /* Add step button (end) */
474
447
  .mint-timeline__add-end {
475
448
  display: flex;
@@ -40,16 +40,16 @@
40
40
  }
41
41
 
42
42
  .mint-form-section__title {
43
- font-size: var(--font-size-base, 0.9375rem);
43
+ font-size: 0.9375rem;
44
44
  font-weight: 600;
45
- color: var(--color-text, #1a1a2e);
45
+ color: var(--text-primary);
46
46
  margin: 0;
47
47
  line-height: 1.4;
48
48
  }
49
49
 
50
50
  .mint-form-section__description {
51
- font-size: var(--font-size-sm, 0.8125rem);
52
- color: var(--color-text-secondary, #6b7280);
51
+ font-size: 0.8125rem;
52
+ color: var(--text-secondary);
53
53
  margin: 0;
54
54
  line-height: 1.5;
55
55
  }
@@ -65,5 +65,5 @@
65
65
  align-items: center;
66
66
  gap: 0.75rem;
67
67
  padding-top: 1rem;
68
- border-top: 1px solid var(--color-border, #e5e7eb);
68
+ border-top: 1px solid var(--border-color);
69
69
  }
@@ -64,7 +64,11 @@
64
64
  padding-right: 0.25rem;
65
65
  }
66
66
 
67
+ /* The handle is a button so it can also take Alt+Arrow keyboard reordering. */
67
68
  .mint-lcms-sequence-table__drag-handle {
69
+ padding: 0;
70
+ border: 0;
71
+ background: none;
68
72
  color: var(--text-muted, #64748b);
69
73
  cursor: grab;
70
74
  font-family: var(--font-mono, 'Fira Code', monospace);
@@ -72,6 +76,11 @@
72
76
  letter-spacing: -0.08em;
73
77
  }
74
78
 
79
+ .mint-lcms-sequence-table__drag-handle:focus-visible {
80
+ outline: none;
81
+ box-shadow: var(--focus-ring);
82
+ }
83
+
75
84
  .mint-lcms-sequence-table__td {
76
85
  min-width: 0;
77
86
  color: var(--text-primary, #0f172a);
@@ -168,7 +177,6 @@
168
177
  background: color-mix(in srgb, var(--mint-error, #ef4444) 10%, transparent);
169
178
  }
170
179
 
171
- .mint-lcms-sequence-table__empty,
172
180
  .mint-lcms-sequence-table__more {
173
181
  color: var(--text-muted, #64748b);
174
182
  font-size: 0.875rem;
@@ -176,6 +184,13 @@
176
184
  text-align: center;
177
185
  }
178
186
 
187
+ /* Empty / loading / error placeholder host (content comes from EmptyState) */
188
+ .mint-lcms-sequence-table__state {
189
+ display: flex;
190
+ align-items: center;
191
+ justify-content: center;
192
+ }
193
+
179
194
  .mint-lcms-sequence-table__more {
180
195
  border-top: 1px solid var(--border-color, #e2e8f0);
181
196
  padding: 0.625rem 1rem;
@@ -64,7 +64,7 @@
64
64
  }
65
65
 
66
66
  .mint-multi-select__chip--active:hover {
67
- background-color: var(--color-primary-dark, #4338ca);
67
+ background-color: var(--color-primary-hover);
68
68
  }
69
69
 
70
70
  .mint-multi-select__chip--disabled {
@@ -138,6 +138,24 @@
138
138
  color: var(--text-secondary);
139
139
  }
140
140
 
141
+ /* Sortable headers are real buttons; strip the native chrome so the cell keeps
142
+ its table-header look while staying keyboard-operable. */
143
+ .mint-reagent-list__sort-btn {
144
+ display: inline-flex;
145
+ align-items: center;
146
+ width: 100%;
147
+ margin: 0;
148
+ padding: 0;
149
+ border: 0;
150
+ background: none;
151
+ color: inherit;
152
+ font: inherit;
153
+ letter-spacing: inherit;
154
+ text-transform: inherit;
155
+ text-align: inherit;
156
+ cursor: inherit;
157
+ }
158
+
141
159
  .mint-reagent-list__sort-icon {
142
160
  display: inline-block;
143
161
  width: 0.75rem;
@@ -332,45 +350,34 @@
332
350
  height: 1rem;
333
351
  }
334
352
 
335
- /* Empty state */
336
- .mint-reagent-list__empty {
337
- padding: 2rem;
338
- text-align: center;
339
- }
340
-
341
- .mint-reagent-list__empty-icon {
342
- width: 2.5rem;
343
- height: 2.5rem;
344
- margin: 0 auto 0.75rem;
345
- color: var(--text-muted);
346
- opacity: 0.5;
353
+ /* Empty / loading / error placeholder host (content comes from EmptyState) */
354
+ .mint-reagent-list__state {
355
+ display: flex;
356
+ align-items: center;
357
+ justify-content: center;
347
358
  }
348
359
 
349
- .mint-reagent-list__empty-text {
350
- font-size: 0.875rem;
351
- color: var(--text-muted);
352
- margin-top: 0 !important;
353
- margin-bottom: 0.75rem !important;
354
- padding: 0 !important;
360
+ /* Drag handle */
361
+ /* The drag handle doubles as the keyboard reorder target (Alt+Arrow). */
362
+ .mint-reagent-list__drag-handle-btn {
363
+ display: inline-flex;
364
+ align-items: center;
365
+ padding: 0;
366
+ border: 0;
367
+ background: none;
368
+ color: inherit;
369
+ cursor: grab;
355
370
  }
356
371
 
357
- .mint-reagent-list__empty-btn {
358
- padding: 0.375rem 0.75rem;
359
- font-size: 0.875rem;
360
- font-weight: 500;
361
- color: white;
362
- background-color: var(--color-primary);
363
- border: none;
364
- border-radius: var(--radius);
365
- cursor: pointer;
366
- transition: background-color 0.15s ease;
372
+ .mint-reagent-list__drag-handle-btn:focus-visible {
373
+ outline: none;
374
+ box-shadow: var(--focus-ring);
367
375
  }
368
376
 
369
- .mint-reagent-list__empty-btn:hover {
370
- background-color: var(--color-primary-hover);
377
+ .mint-reagent-list__drag-handle-btn:focus-visible .mint-reagent-list__drag-handle {
378
+ opacity: 1;
371
379
  }
372
380
 
373
- /* Drag handle */
374
381
  .mint-reagent-list__drag-handle {
375
382
  width: 1rem;
376
383
  color: var(--text-muted);
@@ -288,23 +288,9 @@
288
288
  }
289
289
  }
290
290
 
291
- /* Empty state */
292
- .mint-sample-tree__empty {
293
- padding: 1rem;
294
- text-align: center;
295
- color: var(--text-muted);
296
- }
297
-
298
- .mint-sample-tree__empty-icon {
299
- width: 2rem;
300
- height: 2rem;
301
- margin: 0 auto 0.5rem;
302
- opacity: 0.5;
303
- }
304
-
305
- .mint-sample-tree__empty-text {
306
- font-size: 0.875rem;
307
- margin-top: 0 !important;
308
- margin-bottom: 0 !important;
309
- padding: 0 !important;
291
+ /* Empty / loading / error placeholder host (content comes from EmptyState) */
292
+ .mint-sample-tree__state {
293
+ display: flex;
294
+ align-items: center;
295
+ justify-content: center;
310
296
  }
@@ -468,14 +468,21 @@
468
468
  height: 0.625rem;
469
469
  }
470
470
 
471
- /* Empty State */
472
- .mint-sample-selector__empty {
471
+ /* Inline hint shown inside the grouped/flat sub-lists */
472
+ .mint-sample-selector__hint {
473
473
  text-align: center;
474
474
  padding: 1rem;
475
475
  font-size: 0.875rem;
476
476
  color: var(--text-muted);
477
477
  }
478
478
 
479
+ /* Empty / loading / error placeholder host (content comes from EmptyState) */
480
+ .mint-sample-selector__state {
481
+ display: flex;
482
+ align-items: center;
483
+ justify-content: center;
484
+ }
485
+
479
486
  /* Ungrouped Section */
480
487
  .mint-sample-selector__ungrouped {
481
488
  margin-top: 0.75rem;
@@ -470,3 +470,11 @@
470
470
  .mint-schedule__month-more:hover {
471
471
  text-decoration: underline;
472
472
  }
473
+
474
+ /* Empty / loading / error placeholder host (content comes from EmptyState) */
475
+ .mint-schedule__state {
476
+ display: flex;
477
+ align-items: center;
478
+ justify-content: center;
479
+ min-height: 12rem;
480
+ }
@@ -59,5 +59,5 @@
59
59
  }
60
60
 
61
61
  .mint-sci-number__copy-btn--copied {
62
- color: var(--color-success, #10b981);
62
+ color: var(--mint-success);
63
63
  }
@@ -0,0 +1,60 @@
1
+ /* SecretInput — plugin secret settings field with a set / not set / environment badge. */
2
+
3
+ .mint-secret-input {
4
+ display: flex;
5
+ flex-direction: column;
6
+ gap: 0.5rem;
7
+ }
8
+
9
+ .mint-secret-input__status {
10
+ display: flex;
11
+ align-items: center;
12
+ gap: 0.5rem;
13
+ flex-wrap: wrap;
14
+ }
15
+
16
+ .mint-secret-input__badge {
17
+ display: inline-flex;
18
+ align-items: center;
19
+ border-radius: 999px;
20
+ padding: 0.125rem 0.5rem;
21
+ font-size: 0.75rem;
22
+ font-weight: 500;
23
+ line-height: 1.4;
24
+ border: 1px solid transparent;
25
+ background-color: var(--bg-tertiary);
26
+ color: var(--text-secondary);
27
+ }
28
+
29
+ .mint-secret-input__badge--set {
30
+ background-color: color-mix(in srgb, var(--mint-success) 12%, transparent);
31
+ border-color: color-mix(in srgb, var(--mint-success) 35%, transparent);
32
+ color: var(--mint-success);
33
+ }
34
+
35
+ .mint-secret-input__badge--environment {
36
+ background-color: color-mix(in srgb, var(--mint-info) 12%, transparent);
37
+ border-color: color-mix(in srgb, var(--mint-info) 35%, transparent);
38
+ color: var(--mint-info);
39
+ }
40
+
41
+ .mint-secret-input__badge--pending {
42
+ background-color: color-mix(in srgb, var(--mint-warning) 12%, transparent);
43
+ border-color: color-mix(in srgb, var(--mint-warning) 35%, transparent);
44
+ color: var(--mint-warning);
45
+ }
46
+
47
+ .mint-secret-input__hint {
48
+ font-size: 0.75rem;
49
+ color: var(--text-muted);
50
+ }
51
+
52
+ .mint-secret-input__actions {
53
+ display: flex;
54
+ align-items: center;
55
+ gap: 0.5rem;
56
+ }
57
+
58
+ .mint-secret-input--error .mint-secret-input__badge {
59
+ border-color: color-mix(in srgb, var(--mint-error) 45%, transparent);
60
+ }
@@ -284,3 +284,11 @@
284
284
  font-size: 0.75rem;
285
285
  color: var(--text-muted);
286
286
  }
287
+
288
+ /* Empty / loading / error placeholder host (content comes from EmptyState) */
289
+ .mint-well-plate__state {
290
+ display: flex;
291
+ align-items: center;
292
+ justify-content: center;
293
+ min-height: 12rem;
294
+ }
@@ -30,6 +30,7 @@
30
30
  @import './components/radio-group.css';
31
31
  @import './components/sample-legend.css';
32
32
  @import './components/section-card.css';
33
+ @import './components/secret-input.css';
33
34
  @import './components/select.css';
34
35
  @import './components/skeleton.css';
35
36
  @import './components/slider.css';
@@ -56,6 +57,7 @@
56
57
  @import './components/dropdown-button.css';
57
58
  @import './components/calendar.css';
58
59
  @import './components/dataframe.css';
60
+ @import './components/data-state.css';
59
61
  @import './components/well-edit-popup.css';
60
62
  @import './components/rack-editor.css';
61
63
  @import './components/loading-spinner.css';
@@ -91,3 +93,10 @@
91
93
  @import './components/artifact-save-dialog.css';
92
94
  @import './components/experiment-popover.css';
93
95
  @import './components/fit-panel.css';
96
+ @import './components/app-avatar-menu.css';
97
+ @import './components/app-page-selector.css';
98
+ @import './components/app-pill-nav.css';
99
+ @import './components/app-plugin-switcher.css';
100
+ @import './components/mobile-support-gate.css';
101
+ @import './components/plugin-icon.css';
102
+ @import './components/reagent-editor.css';
@@ -66,6 +66,32 @@
66
66
  /* The MINT 1.1 card system uses exactly one shadow for every card. */
67
67
  --card-shadow: 0 1px 2px 0 rgb(0 0 0 / 0.04), 0 1px 3px 0 rgb(0 0 0 / 0.06);
68
68
 
69
+ /* Categorical sample scale — mirrored by SAMPLE_COLOR_SCALE in
70
+ src/utils/color.ts. The JS constant carries the same hexes as a
71
+ canvas/SVG/persistence-safe fallback; change both together. */
72
+ --mint-sample-1: #3B82F6;
73
+ --mint-sample-2: #10B981;
74
+ --mint-sample-3: #EF4444;
75
+ --mint-sample-4: #F59E0B;
76
+ --mint-sample-5: #8B5CF6;
77
+ --mint-sample-6: #F97316;
78
+ --mint-sample-7: #06B6D4;
79
+ --mint-sample-8: #14B8A6;
80
+ --mint-sample-9: #6B7280;
81
+
82
+ /* Rack / plate slot positions — mirrored by SLOT_COLORS in
83
+ src/utils/color.ts. */
84
+ --mint-slot-r: #ef4444;
85
+ --mint-slot-g: #22c55e;
86
+ --mint-slot-b: #3b82f6;
87
+ --mint-slot-y: #eab308;
88
+
89
+ /* Motion — the SDK's standard easing curve. */
90
+ --mint-ease-out-quart: cubic-bezier(0.25, 1, 0.5, 1);
91
+
92
+ /* Typography — Fira Code for data, code and routes. */
93
+ --font-mono: 'Fira Code', ui-monospace, SFMono-Regular, Menlo, monospace;
94
+
69
95
  /* Border radius */
70
96
  --radius-sm: 0.25rem;
71
97
  --radius: 0.375rem;
@@ -90,6 +116,8 @@
90
116
  --mint-warning-hover: #D97706;
91
117
  --mint-warning-bg: rgba(245, 158, 11, 0.1);
92
118
  --mint-warning-border: rgba(245, 158, 11, 0.3);
119
+ /* Readable warning label on --mint-warning-bg (amber-700, 5.9:1). */
120
+ --mint-warning-text: #B45309;
93
121
  --mint-info: #3B82F6;
94
122
  --mint-info-bg: rgba(59, 130, 246, 0.1);
95
123
  --mint-info-border: rgba(59, 130, 246, 0.3);
@@ -178,6 +206,7 @@ html.dark {
178
206
  --mint-success-bg: rgba(16, 185, 129, 0.15);
179
207
  --mint-error-bg: rgba(239, 68, 68, 0.15);
180
208
  --mint-warning-bg: rgba(245, 158, 11, 0.15);
209
+ --mint-warning-text: #FCD34D;
181
210
  --mint-info-bg: rgba(59, 130, 246, 0.15);
182
211
 
183
212
  /* Focus ring - dark mode offset uses bg-primary instead of white */
@@ -7,7 +7,7 @@ import {
7
7
  readString,
8
8
  readStringList,
9
9
  } from './builderReadUtils'
10
- import { readPlateFormat } from './plateGeometry'
10
+ import { readPlateFormat } from '../components/WellPlate.geometry'
11
11
  import { getBioTemplatePresetInfo } from './presets'
12
12
  import type {
13
13
  CreateElisaAssayCollectionOptions,
@@ -1,6 +1,4 @@
1
- export function isRecord(value: unknown): value is Record<string, unknown> {
2
- return typeof value === 'object' && value !== null && !Array.isArray(value)
3
- }
1
+ export { isRecord } from '../utils/records'
4
2
 
5
3
  export function readStringList(value: unknown, fallback: string[]): string[] {
6
4
  if (Array.isArray(value)) {
@@ -2,6 +2,7 @@ import type {
2
2
  PlateMapEditorState,
3
3
  WellLegendItem,
4
4
  } from '../types'
5
+ import { SAMPLE_COLOR_SCALE } from '../utils/color'
5
6
 
6
7
  export function activePlateFromState(state: PlateMapEditorState) {
7
8
  return state.plates.find(plate => plate.id === state.activePlateId) ?? state.plates[0]
@@ -24,6 +25,7 @@ export function legendItemsFromPlateState(state: PlateMapEditorState): WellLegen
24
25
  }
25
26
 
26
27
  export function colorForIndex(index: number): string {
27
- const colors = ['#3B82F6', '#10B981', '#EF4444', '#F59E0B', '#8B5CF6', '#F97316', '#06B6D4', '#14B8A6']
28
+ // The gray tail of the scale is reserved for "other"; component plates cycle the eight hues.
29
+ const colors = SAMPLE_COLOR_SCALE.slice(0, 8)
28
30
  return colors[index % colors.length]
29
31
  }
@@ -1,3 +1,4 @@
1
+ import { isObjectLike as isRecord } from '../utils/records'
1
2
  import { extractTemplateCollection } from './templateEnvelopes'
2
3
  import { getBioTemplateInfo } from './catalog'
3
4
  import { getBioTemplatePackInfo } from './packs'
@@ -64,6 +65,3 @@ function collectionPackName(value: unknown): string | undefined {
64
65
  return typeof value.metadata.pack === 'string' ? value.metadata.pack : undefined
65
66
  }
66
67
 
67
- function isRecord(value: unknown): value is Record<string, unknown> {
68
- return typeof value === 'object' && value !== null
69
- }
@@ -1,3 +1,4 @@
1
+ import { isObjectLike as isRecord } from '../utils/records'
1
2
  import {
2
3
  getBioTemplateInfo,
3
4
  } from './catalog'
@@ -82,6 +83,3 @@ function collectionPackName(value: unknown): string | undefined {
82
83
  return typeof value.metadata.pack === 'string' ? value.metadata.pack : undefined
83
84
  }
84
85
 
85
- function isRecord(value: unknown): value is Record<string, unknown> {
86
- return typeof value === 'object' && value !== null
87
- }
@@ -2,6 +2,7 @@ import type {
2
2
  PlateCondition,
3
3
  PlateMapEditorState,
4
4
  } from '../types'
5
+ import { SAMPLE_COLOR_SCALE } from '../utils/color'
5
6
  import { toPlateMapEditorState } from './plateMapAdapters'
6
7
  import { getTemplateData } from './templateEnvelopes'
7
8
  import { validateDoseResponseData } from './templateValidators'
@@ -11,18 +12,6 @@ import type {
11
12
  DoseResponseTemplateData,
12
13
  } from './types'
13
14
 
14
- const CONDITION_COLORS = [
15
- '#3B82F6',
16
- '#10B981',
17
- '#EF4444',
18
- '#F59E0B',
19
- '#8B5CF6',
20
- '#F97316',
21
- '#06B6D4',
22
- '#14B8A6',
23
- '#6B7280',
24
- ]
25
-
26
15
  export function toDoseConditions(
27
16
  template: DoseResponseTemplate | DoseResponseTemplateData
28
17
  ): DoseConditionsAdapterResult {
@@ -30,7 +19,7 @@ export function toDoseConditions(
30
19
  validateDoseResponseData(data)
31
20
  return data.compounds.map((compound, index): PlateCondition => ({
32
21
  label: compound.name,
33
- color: String(compound.metadata?.color ?? CONDITION_COLORS[index % CONDITION_COLORS.length]),
22
+ color: String(compound.metadata?.color ?? SAMPLE_COLOR_SCALE[index % SAMPLE_COLOR_SCALE.length]),
34
23
  concentrations: compound.concentrations,
35
24
  unit: data.unit,
36
25
  }))