@opentrons/components 0.1.6-alpha.2 → 0.1.6-alpha.21

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 (373) hide show
  1. package/Makefile +5 -1
  2. package/package.json +6 -7
  3. package/src/__mocks__/file.js +10 -0
  4. package/src/alerts/AlertItem.stories.tsx +49 -0
  5. package/src/alerts/AlertItem.tsx +85 -0
  6. package/src/alerts/index.ts +3 -0
  7. package/src/atoms/Checkbox/Checkbox.stories.tsx +24 -0
  8. package/src/atoms/Checkbox/index.tsx +127 -0
  9. package/src/atoms/CheckboxField/CheckboxField.stories.tsx +30 -0
  10. package/src/atoms/CheckboxField/index.tsx +171 -0
  11. package/src/atoms/Chip/Chip.stories.tsx +59 -0
  12. package/src/atoms/Chip/index.tsx +172 -0
  13. package/src/atoms/Divider/index.tsx +15 -0
  14. package/src/atoms/InputField/InputField.stories.tsx +77 -0
  15. package/src/atoms/InputField/index.tsx +383 -0
  16. package/src/atoms/ListButton/ListButton.stories.tsx +133 -0
  17. package/src/atoms/ListButton/ListButtonChildren/ListButtonAccordion.tsx +65 -0
  18. package/src/atoms/ListButton/ListButtonChildren/ListButtonAccordionContainer.tsx +23 -0
  19. package/src/atoms/ListButton/ListButtonChildren/ListButtonRadioButton.tsx +108 -0
  20. package/src/atoms/ListButton/ListButtonChildren/index.ts +3 -0
  21. package/src/atoms/ListButton/index.tsx +72 -0
  22. package/src/atoms/ListItem/ListItem.stories.tsx +96 -0
  23. package/src/atoms/ListItem/ListItemChildren/ListItemCustomize.tsx +78 -0
  24. package/src/atoms/ListItem/ListItemChildren/ListItemDescriptor.tsx +42 -0
  25. package/src/atoms/ListItem/ListItemChildren/index.ts +2 -0
  26. package/src/atoms/ListItem/index.tsx +89 -0
  27. package/src/atoms/MenuList/MenuItem.stories.tsx +20 -0
  28. package/src/atoms/MenuList/MenuItem.tsx +55 -0
  29. package/src/atoms/MenuList/MenuList.stories.tsx +31 -0
  30. package/src/atoms/MenuList/OverflowBtn.stories.tsx +17 -0
  31. package/src/atoms/MenuList/OverflowBtn.tsx +76 -0
  32. package/src/atoms/MenuList/index.tsx +50 -0
  33. package/src/atoms/Snackbar/Snackbar.stories.tsx +67 -0
  34. package/src/atoms/Snackbar/index.tsx +91 -0
  35. package/src/atoms/StepMeter/index.tsx +53 -0
  36. package/src/atoms/StyledText/LegacyStyledText.stories.tsx +106 -0
  37. package/src/atoms/StyledText/LegacyStyledText.tsx +95 -0
  38. package/src/atoms/StyledText/StyledText.stories.tsx +46 -0
  39. package/src/atoms/StyledText/StyledText.tsx +323 -0
  40. package/src/atoms/StyledText/index.ts +2 -0
  41. package/src/atoms/Tag/Tag.stories.tsx +48 -0
  42. package/src/atoms/Tag/index.tsx +116 -0
  43. package/src/atoms/Toast/ODDToast.stories.tsx +68 -0
  44. package/src/atoms/Toast/Toast.stories.tsx +55 -0
  45. package/src/atoms/Toast/index.tsx +439 -0
  46. package/src/atoms/ToggleGroup/ToggleGroup.stories.tsx +39 -0
  47. package/src/atoms/ToggleGroup/index.tsx +91 -0
  48. package/src/atoms/Tooltip/Tooltip.stories.tsx +99 -0
  49. package/src/atoms/Tooltip/index.tsx +38 -0
  50. package/src/atoms/buttons/AlertPrimaryButton.tsx +26 -0
  51. package/src/atoms/buttons/AltPrimaryButton.tsx +31 -0
  52. package/src/atoms/buttons/EmptySelectorButton.stories.tsx +36 -0
  53. package/src/atoms/buttons/EmptySelectorButton.tsx +83 -0
  54. package/src/atoms/buttons/LargeButton.stories.tsx +99 -0
  55. package/src/atoms/buttons/LargeButton.tsx +320 -0
  56. package/src/atoms/buttons/PrimaryButton.tsx +36 -0
  57. package/src/atoms/buttons/RadioButton.stories.tsx +35 -0
  58. package/src/atoms/buttons/RadioButton.tsx +217 -0
  59. package/src/atoms/buttons/SecondaryButton.tsx +62 -0
  60. package/src/atoms/buttons/buttons.stories.tsx +78 -0
  61. package/src/atoms/buttons/index.ts +6 -0
  62. package/src/atoms/index.ts +20 -0
  63. package/src/barrel.ts +10 -0
  64. package/src/buttons/Button.tsx +96 -0
  65. package/src/buttons/DeprecatedPrimaryButton.tsx +24 -0
  66. package/src/buttons/FlatButton.tsx +21 -0
  67. package/src/buttons/IconButton.tsx +37 -0
  68. package/src/buttons/OutlineButton.tsx +24 -0
  69. package/src/buttons/index.ts +7 -0
  70. package/src/controls/ControlInfo.tsx +13 -0
  71. package/src/controls/LabeledButton.tsx +28 -0
  72. package/src/controls/LabeledCheckbox.tsx +35 -0
  73. package/src/controls/LabeledControl.tsx +24 -0
  74. package/src/controls/LabeledRadioGroup.tsx +27 -0
  75. package/src/controls/LabeledSelect.tsx +34 -0
  76. package/src/controls/LabeledToggle.tsx +35 -0
  77. package/src/controls/StackedLabeledControl.tsx +28 -0
  78. package/src/controls/ToggleButton.tsx +25 -0
  79. package/src/controls/index.ts +10 -0
  80. package/src/forms/DeprecatedCheckboxField.stories.tsx +31 -0
  81. package/src/forms/DeprecatedCheckboxField.tsx +94 -0
  82. package/src/forms/DropdownField.stories.tsx +44 -0
  83. package/src/forms/DropdownField.tsx +106 -0
  84. package/src/forms/FormGroup.stories.tsx +31 -0
  85. package/src/forms/FormGroup.tsx +53 -0
  86. package/src/forms/InputField.stories.tsx +41 -0
  87. package/src/forms/LegacyInputField.tsx +123 -0
  88. package/src/forms/RadioGroup.stories.tsx +44 -0
  89. package/src/forms/RadioGroup.tsx +87 -0
  90. package/src/forms/Select.stories.tsx +117 -0
  91. package/src/forms/Select.tsx +132 -0
  92. package/src/forms/SelectField.tsx +94 -0
  93. package/src/forms/ToggleField.stories.tsx +31 -0
  94. package/src/forms/ToggleField.tsx +59 -0
  95. package/src/forms/index.ts +8 -0
  96. package/src/hardware-sim/BaseDeck/BaseDeck.stories.tsx +94 -0
  97. package/src/hardware-sim/BaseDeck/BaseDeck.tsx +423 -0
  98. package/src/hardware-sim/BaseDeck/SingleSlotFixture.tsx +199 -0
  99. package/src/hardware-sim/BaseDeck/SlotBase.tsx +5 -0
  100. package/src/hardware-sim/BaseDeck/SlotClip.tsx +15 -0
  101. package/src/hardware-sim/BaseDeck/StagingAreaFixture.tsx +114 -0
  102. package/src/hardware-sim/BaseDeck/WasteChuteFixture.tsx +114 -0
  103. package/src/hardware-sim/BaseDeck/WasteChuteStagingAreaFixture.tsx +68 -0
  104. package/src/hardware-sim/BaseDeck/__fixtures__/index.ts +165 -0
  105. package/src/hardware-sim/BaseDeck/index.ts +5 -0
  106. package/src/hardware-sim/BaseDeck/something.test.tsx +7 -0
  107. package/src/hardware-sim/Deck/DeckFromLayers.tsx +58 -0
  108. package/src/hardware-sim/Deck/FlexTrash.tsx +128 -0
  109. package/src/hardware-sim/Deck/MoveLabwareOnDeck.stories.tsx +97 -0
  110. package/src/hardware-sim/Deck/MoveLabwareOnDeck.tsx +251 -0
  111. package/src/hardware-sim/Deck/OT2Layers.tsx +153 -0
  112. package/src/hardware-sim/Deck/RobotCoordsForeignDiv.tsx +46 -0
  113. package/src/hardware-sim/Deck/RobotCoordsForeignObject.tsx +42 -0
  114. package/src/hardware-sim/Deck/RobotCoordsText.tsx +32 -0
  115. package/src/hardware-sim/Deck/RobotWorkSpace.tsx +90 -0
  116. package/src/hardware-sim/Deck/SlotLabels.tsx +111 -0
  117. package/src/hardware-sim/Deck/__mocks__/getDeckDefinitions.ts +29 -0
  118. package/src/hardware-sim/Deck/constants.ts +12 -0
  119. package/src/hardware-sim/Deck/index.tsx +8 -0
  120. package/src/hardware-sim/DeckConfigurator/AbsorbanceReaderFixture.tsx +91 -0
  121. package/src/hardware-sim/DeckConfigurator/DeckConfigurator.stories.tsx +110 -0
  122. package/src/hardware-sim/DeckConfigurator/EmptyConfigFixture.tsx +131 -0
  123. package/src/hardware-sim/DeckConfigurator/HeaterShakerFixture.tsx +102 -0
  124. package/src/hardware-sim/DeckConfigurator/MagneticBlockFixture.tsx +130 -0
  125. package/src/hardware-sim/DeckConfigurator/StagingAreaConfigFixture.tsx +89 -0
  126. package/src/hardware-sim/DeckConfigurator/StaticFixture.tsx +54 -0
  127. package/src/hardware-sim/DeckConfigurator/TemperatureModuleFixture.tsx +103 -0
  128. package/src/hardware-sim/DeckConfigurator/ThermocyclerFixture.tsx +89 -0
  129. package/src/hardware-sim/DeckConfigurator/TrashBinConfigFixture.tsx +99 -0
  130. package/src/hardware-sim/DeckConfigurator/WasteChuteConfigFixture.tsx +96 -0
  131. package/src/hardware-sim/DeckConfigurator/constants.ts +81 -0
  132. package/src/hardware-sim/DeckConfigurator/index.tsx +285 -0
  133. package/src/hardware-sim/DeckSlotLocation/index.tsx +88 -0
  134. package/src/hardware-sim/Labware/Labware.tsx +173 -0
  135. package/src/hardware-sim/Labware/LabwareAdapter/Opentrons96DeepWellAdapter.tsx +23 -0
  136. package/src/hardware-sim/Labware/LabwareAdapter/Opentrons96FlatBottomAdapter.tsx +7 -0
  137. package/src/hardware-sim/Labware/LabwareAdapter/OpentronsAluminumFlatBottomPlate.tsx +13 -0
  138. package/src/hardware-sim/Labware/LabwareAdapter/OpentronsAutoclavableDeckRiser.tsx +100 -0
  139. package/src/hardware-sim/Labware/LabwareAdapter/OpentronsFlex96TiprackAdapter.tsx +13 -0
  140. package/src/hardware-sim/Labware/LabwareAdapter/OpentronsToughPCRAutoSealingLid.tsx +83 -0
  141. package/src/hardware-sim/Labware/LabwareAdapter/OpentronsUniversalFlatAdapter.tsx +13 -0
  142. package/src/hardware-sim/Labware/LabwareAdapter/index.tsx +73 -0
  143. package/src/hardware-sim/Labware/LabwareRender.stories.tsx +96 -0
  144. package/src/hardware-sim/Labware/LabwareRender.tsx +173 -0
  145. package/src/hardware-sim/Labware/LabwareStackRender.tsx +272 -0
  146. package/src/hardware-sim/Labware/index.ts +6 -0
  147. package/src/hardware-sim/Labware/labwareInternals/FilledWells.tsx +39 -0
  148. package/src/hardware-sim/Labware/labwareInternals/LabwareOutline.tsx +133 -0
  149. package/src/hardware-sim/Labware/labwareInternals/LabwareWellLabels.tsx +118 -0
  150. package/src/hardware-sim/Labware/labwareInternals/StaticLabware.tsx +121 -0
  151. package/src/hardware-sim/Labware/labwareInternals/StrokedWells.tsx +38 -0
  152. package/src/hardware-sim/Labware/labwareInternals/StyledWells.tsx +77 -0
  153. package/src/hardware-sim/Labware/labwareInternals/Well.tsx +74 -0
  154. package/src/hardware-sim/Labware/labwareInternals/WellLabels.tsx +121 -0
  155. package/src/hardware-sim/Labware/labwareInternals/index.ts +8 -0
  156. package/src/hardware-sim/Labware/labwareInternals/types.ts +18 -0
  157. package/src/hardware-sim/Module/HeaterShaker.tsx +83 -0
  158. package/src/hardware-sim/Module/MagneticBlock.tsx +49 -0
  159. package/src/hardware-sim/Module/MagneticModule.tsx +51 -0
  160. package/src/hardware-sim/Module/Module.stories.tsx +90 -0
  161. package/src/hardware-sim/Module/ModuleTag.tsx +38 -0
  162. package/src/hardware-sim/Module/PlateReader.tsx +208 -0
  163. package/src/hardware-sim/Module/Temperature.tsx +54 -0
  164. package/src/hardware-sim/Module/Thermocycler/ThermocyclerGEN1.tsx +248 -0
  165. package/src/hardware-sim/Module/Thermocycler/ThermocyclerGEN2.tsx +286 -0
  166. package/src/hardware-sim/Module/Thermocycler/index.tsx +49 -0
  167. package/src/hardware-sim/Module/index.tsx +227 -0
  168. package/src/hardware-sim/Pipette/EightEmanatingNozzles.tsx +23 -0
  169. package/src/hardware-sim/Pipette/EmanatingNozzle.tsx +52 -0
  170. package/src/hardware-sim/Pipette/PipetteRender.stories.tsx +71 -0
  171. package/src/hardware-sim/Pipette/PipetteRender.tsx +92 -0
  172. package/src/hardware-sim/Pipette/constants.ts +10 -0
  173. package/src/hardware-sim/Pipette/index.ts +1 -0
  174. package/src/hardware-sim/ProtocolDeck/LabwareInfo.tsx +68 -0
  175. package/src/hardware-sim/ProtocolDeck/ProtocolDeck.stories.tsx +25 -0
  176. package/src/hardware-sim/ProtocolDeck/__fixtures__/analysis_QIAseqFX24xv4_8.json +47145 -0
  177. package/src/hardware-sim/ProtocolDeck/index.tsx +174 -0
  178. package/src/hardware-sim/ProtocolDeck/types.ts +6 -0
  179. package/src/hardware-sim/ProtocolDeck/utils/getInitiallyLoadedLabwareByAdapter.ts +33 -0
  180. package/src/hardware-sim/ProtocolDeck/utils/getLabwareInSlots.ts +155 -0
  181. package/src/hardware-sim/ProtocolDeck/utils/getLabwareInfoByLiquidId.ts +42 -0
  182. package/src/hardware-sim/ProtocolDeck/utils/getModulesInSlots.ts +129 -0
  183. package/src/hardware-sim/ProtocolDeck/utils/getStandardDeckViewLayerBlockList.ts +29 -0
  184. package/src/hardware-sim/ProtocolDeck/utils/getWellFillFromLabwareId.ts +30 -0
  185. package/src/hardware-sim/ProtocolDeck/utils/index.ts +3 -0
  186. package/src/hardware-sim/RobotCoordinateSpace/RobotCoordinateSpace.tsx +28 -0
  187. package/src/hardware-sim/RobotCoordinateSpace/RobotCoordinateSpaceWithRef.tsx +52 -0
  188. package/src/hardware-sim/RobotCoordinateSpace/index.ts +2 -0
  189. package/src/hardware-sim/index.ts +11 -0
  190. package/src/hardware-sim/utils.ts +18 -0
  191. package/src/helix-design-system/borders.ts +32 -0
  192. package/src/helix-design-system/colors.ts +100 -0
  193. package/src/helix-design-system/index.ts +4 -0
  194. package/src/helix-design-system/product/index.ts +1 -0
  195. package/src/helix-design-system/product/typography.ts +151 -0
  196. package/src/helix-design-system/style.ts +2 -0
  197. package/src/hooks/index.ts +15 -0
  198. package/src/hooks/useConditionalConfirm.ts +70 -0
  199. package/src/hooks/useDrag.ts +90 -0
  200. package/src/hooks/useIdle.ts +68 -0
  201. package/src/hooks/useInterval.ts +38 -0
  202. package/src/hooks/useLongPress.ts +83 -0
  203. package/src/hooks/useMenuHandleClickOutside.tsx +46 -0
  204. package/src/hooks/useMountEffect.ts +12 -0
  205. package/src/hooks/usePrevious.ts +19 -0
  206. package/src/hooks/useScrolling.ts +33 -0
  207. package/src/hooks/useSelectDeckLocation/SelectDeckLocation.stories.tsx +55 -0
  208. package/src/hooks/useSelectDeckLocation/index.tsx +331 -0
  209. package/src/hooks/useSwipe.ts +86 -0
  210. package/src/hooks/useTimeout.ts +33 -0
  211. package/src/hooks/useToggle.ts +27 -0
  212. package/src/icons/Icon.stories.tsx +37 -0
  213. package/src/icons/Icon.tsx +79 -0
  214. package/src/icons/IconList.stories.tsx +108 -0
  215. package/src/icons/ModuleIcon.tsx +48 -0
  216. package/src/icons/NotificationIcon.tsx +41 -0
  217. package/src/icons/icon-data.ts +821 -0
  218. package/src/icons/index.ts +6 -0
  219. package/src/images/index.ts +1 -0
  220. package/src/images/labware/index.ts +1 -0
  221. package/src/images/labware/measurement-guide/images/depth/depth-plate-flat@3x.png +0 -0
  222. package/src/images/labware/measurement-guide/images/depth/depth-plate-round@3x.png +0 -0
  223. package/src/images/labware/measurement-guide/images/depth/depth-plate-v@3x.png +0 -0
  224. package/src/images/labware/measurement-guide/images/depth/depth-reservoir-and-tubes-flat@3x.png +0 -0
  225. package/src/images/labware/measurement-guide/images/depth/depth-reservoir-and-tubes-round@3x.png +0 -0
  226. package/src/images/labware/measurement-guide/images/depth/depth-reservoir-and-tubes-v@3x.png +0 -0
  227. package/src/images/labware/measurement-guide/images/depth/length-tip-rack@3x.png +0 -0
  228. package/src/images/labware/measurement-guide/images/dimensions/footprint@3x.png +0 -0
  229. package/src/images/labware/measurement-guide/images/dimensions/height-alum-block-plate@3x.png +0 -0
  230. package/src/images/labware/measurement-guide/images/dimensions/height-alum-block-tubes@3x.png +0 -0
  231. package/src/images/labware/measurement-guide/images/dimensions/height-plate-and-reservoir@3x.png +0 -0
  232. package/src/images/labware/measurement-guide/images/dimensions/height-tip-rack@3x.png +0 -0
  233. package/src/images/labware/measurement-guide/images/dimensions/height-tube-rack-irregular@3x.png +0 -0
  234. package/src/images/labware/measurement-guide/images/dimensions/height-tube-rack@3x.png +0 -0
  235. package/src/images/labware/measurement-guide/images/offset/offset-reservoir@3x.png +0 -0
  236. package/src/images/labware/measurement-guide/images/offset/offset-well-circular@3x.png +0 -0
  237. package/src/images/labware/measurement-guide/images/offset/offset-well-rectangular@3x.png +0 -0
  238. package/src/images/labware/measurement-guide/images/shape/shape-circular@3x.png +0 -0
  239. package/src/images/labware/measurement-guide/images/shape/shape-rectangular@3x.png +0 -0
  240. package/src/images/labware/measurement-guide/images/spacing/spacing-reservoir-multi-row@3x.png +0 -0
  241. package/src/images/labware/measurement-guide/images/spacing/spacing-reservoir@3x.png +0 -0
  242. package/src/images/labware/measurement-guide/images/spacing/spacing-well-circular@3x.png +0 -0
  243. package/src/images/labware/measurement-guide/images/spacing/spacing-well-rectangular@3x.png +0 -0
  244. package/src/images/labware/measurement-guide/index.ts +272 -0
  245. package/src/index.ts +2 -0
  246. package/src/instrument/InstrumentDiagram.stories.tsx +42 -0
  247. package/src/instrument/InstrumentDiagram.tsx +58 -0
  248. package/src/instrument/InstrumentGroup.stories.tsx +88 -0
  249. package/src/instrument/InstrumentGroup.tsx +35 -0
  250. package/src/instrument/InstrumentInfo.tsx +107 -0
  251. package/src/instrument/PipetteSelect.stories.tsx +40 -0
  252. package/src/instrument/PipetteSelect.tsx +170 -0
  253. package/src/instrument/eight-channel-flex.png +0 -0
  254. package/src/instrument/index.ts +4 -0
  255. package/src/instrument/multi-channel_GEN1_800px.png +0 -0
  256. package/src/instrument/multi-channel_GEN2_800px.png +0 -0
  257. package/src/instrument/ninety-six-channel-gen1.png +0 -0
  258. package/src/instrument/pipetteGEN2Multi.png +0 -0
  259. package/src/instrument/pipetteGEN2Single.png +0 -0
  260. package/src/instrument/pipetteMulti.png +0 -0
  261. package/src/instrument/pipetteSingle.png +0 -0
  262. package/src/instrument/single-channel-flex.png +0 -0
  263. package/src/instrument/single-channel_GEN2_800px.png +0 -0
  264. package/src/instrument/single_channel_GEN1_800px.png +0 -0
  265. package/src/interaction-enhancers/ClickOutside.ts +57 -0
  266. package/src/interaction-enhancers/HandleKeypress.tsx +69 -0
  267. package/src/interaction-enhancers/index.ts +4 -0
  268. package/src/interaction-enhancers/useHover.ts +84 -0
  269. package/src/interaction-enhancers/useOnClickOutside.ts +42 -0
  270. package/src/legacy-hardware-sim/LabwareNameOverlay.tsx +22 -0
  271. package/src/legacy-hardware-sim/ModuleItem.tsx +145 -0
  272. package/src/legacy-hardware-sim/index.ts +2 -0
  273. package/src/lists/SidePanelGroup.tsx +48 -0
  274. package/src/lists/TitledList.tsx +155 -0
  275. package/src/lists/index.ts +3 -0
  276. package/src/modals/AlertModal.tsx +89 -0
  277. package/src/modals/ContinueModal.tsx +32 -0
  278. package/src/modals/LegacyModal.tsx +59 -0
  279. package/src/modals/Modal.stories.tsx +52 -0
  280. package/src/modals/Modal.tsx +96 -0
  281. package/src/modals/ModalHeader.tsx +100 -0
  282. package/src/modals/ModalShell.tsx +155 -0
  283. package/src/modals/Overlay.tsx +38 -0
  284. package/src/modals/SpinnerModal.tsx +35 -0
  285. package/src/modals/SpinnerModalPage.tsx +30 -0
  286. package/src/modals/index.ts +10 -0
  287. package/src/molecules/Banner/Banner.stories.tsx +41 -0
  288. package/src/molecules/Banner/index.tsx +147 -0
  289. package/src/molecules/DeckInfoLabel/DeckInfoLabel.stories.tsx +65 -0
  290. package/src/molecules/DeckInfoLabel/index.tsx +95 -0
  291. package/src/molecules/DeckLabel/DeckLabel.stories.tsx +31 -0
  292. package/src/molecules/DeckLabel/index.tsx +80 -0
  293. package/src/molecules/DropdownMenu/DropdownMenu.stories.tsx +30 -0
  294. package/src/molecules/DropdownMenu/index.tsx +343 -0
  295. package/src/molecules/InfoScreen/InfoScreen.stories.tsx +50 -0
  296. package/src/molecules/InfoScreen/index.tsx +54 -0
  297. package/src/molecules/LiquidIcon/LiquidIcon.stories.tsx +53 -0
  298. package/src/molecules/LiquidIcon/index.tsx +68 -0
  299. package/src/molecules/ParametersTable/ParametersTable.stories.tsx +172 -0
  300. package/src/molecules/ParametersTable/index.tsx +198 -0
  301. package/src/molecules/Tabs/Tabs.stories.tsx +74 -0
  302. package/src/molecules/Tabs/index.tsx +94 -0
  303. package/src/molecules/index.ts +8 -0
  304. package/src/nav/SidePanel.stories.tsx +29 -0
  305. package/src/nav/SidePanel.tsx +21 -0
  306. package/src/nav/index.ts +2 -0
  307. package/src/organisms/DeckLabelSet/DeckLabelSet.stories.tsx +46 -0
  308. package/src/organisms/DeckLabelSet/index.tsx +69 -0
  309. package/src/organisms/EndUserAgreementFooter/index.tsx +49 -0
  310. package/src/organisms/Toolbox/Toolbox.stories.tsx +23 -0
  311. package/src/organisms/Toolbox/index.tsx +160 -0
  312. package/src/organisms/index.ts +3 -0
  313. package/src/primitives/Box.stories.tsx +25 -0
  314. package/src/primitives/Box.tsx +17 -0
  315. package/src/primitives/Btn.stories.tsx +105 -0
  316. package/src/primitives/Btn.tsx +266 -0
  317. package/src/primitives/Flex.stories.tsx +50 -0
  318. package/src/primitives/Flex.tsx +17 -0
  319. package/src/primitives/ForeignObject.tsx +70 -0
  320. package/src/primitives/Link.stories.tsx +27 -0
  321. package/src/primitives/Link.tsx +32 -0
  322. package/src/primitives/README.md +188 -0
  323. package/src/primitives/Svg.stories.tsx +36 -0
  324. package/src/primitives/Svg.tsx +68 -0
  325. package/src/primitives/Text.stories.tsx +17 -0
  326. package/src/primitives/Text.tsx +18 -0
  327. package/src/primitives/index.ts +10 -0
  328. package/src/primitives/style-props.ts +197 -0
  329. package/src/primitives/types.ts +120 -0
  330. package/src/robot-types.ts +4 -0
  331. package/src/slotmap/OT2SlotMap.tsx +73 -0
  332. package/src/slotmap/index.ts +1 -0
  333. package/src/structure/Card.stories.tsx +28 -0
  334. package/src/structure/Card.tsx +64 -0
  335. package/src/structure/LabeledValue.stories.tsx +17 -0
  336. package/src/structure/LabeledValue.tsx +31 -0
  337. package/src/structure/Pill.tsx +43 -0
  338. package/src/structure/Splash.stories.tsx +24 -0
  339. package/src/structure/Splash.tsx +22 -0
  340. package/src/structure/TitleBar.stories.tsx +42 -0
  341. package/src/structure/TitleBar.tsx +81 -0
  342. package/src/structure/index.ts +7 -0
  343. package/src/styles/borders.ts +16 -0
  344. package/src/styles/colors.ts +58 -0
  345. package/src/styles/cursor.ts +12 -0
  346. package/src/styles/flexbox.ts +39 -0
  347. package/src/styles/index.ts +8 -0
  348. package/src/styles/layout.ts +31 -0
  349. package/src/styles/position.ts +5 -0
  350. package/src/styles/spacing.ts +11 -0
  351. package/src/styles/typography.ts +90 -0
  352. package/src/testing/utils/index.ts +2 -0
  353. package/src/testing/utils/matchers.ts +31 -0
  354. package/src/testing/utils/renderWithProviders.tsx +53 -0
  355. package/src/tooltips/DeprecatedTooltip.tsx +105 -0
  356. package/src/tooltips/HoverTooltip.tsx +83 -0
  357. package/src/tooltips/LegacyTooltip.stories.tsx +98 -0
  358. package/src/tooltips/LegacyTooltip.tsx +151 -0
  359. package/src/tooltips/constants.ts +28 -0
  360. package/src/tooltips/index.ts +10 -0
  361. package/src/tooltips/styles.ts +20 -0
  362. package/src/tooltips/types.ts +73 -0
  363. package/src/tooltips/useHoverTooltip.ts +47 -0
  364. package/src/tooltips/usePopper.ts +87 -0
  365. package/src/tooltips/useTooltip.ts +100 -0
  366. package/src/ui-style-constants/index.ts +4 -0
  367. package/src/ui-style-constants/responsiveness.ts +15 -0
  368. package/src/ui-style-constants/spacing.ts +18 -0
  369. package/src/ui-style-constants/typography.ts +258 -0
  370. package/src/ui-style-constants/viewport.ts +18 -0
  371. package/src/utils.ts +56 -0
  372. package/{vite.config.ts → vite.config.mts} +2 -0
  373. package/lib/index.mjs +0 -19869
@@ -0,0 +1,174 @@
1
+ import type * as React from 'react'
2
+
3
+ import {
4
+ FLEX_ROBOT_TYPE,
5
+ getLabwareDisplayName,
6
+ getSimplestDeckConfigForProtocol,
7
+ getTopLabwareInfo,
8
+ } from '@opentrons/shared-data'
9
+
10
+ import { BaseDeck } from '../BaseDeck/BaseDeck'
11
+ import { LabwareInfo } from './LabwareInfo'
12
+ import { getStandardDeckViewLayerBlockList } from './utils/getStandardDeckViewLayerBlockList'
13
+ import { getLabwareInfoByLiquidId } from './utils/getLabwareInfoByLiquidId'
14
+ import { getTopMostLabwareInSlots } from './utils/getLabwareInSlots'
15
+ import { getModulesInSlots } from './utils/getModulesInSlots'
16
+ import { getWellFillFromLabwareId } from './utils/getWellFillFromLabwareId'
17
+
18
+ import type {
19
+ CompletedProtocolAnalysis,
20
+ LabwareDefinition2,
21
+ ProtocolAnalysisOutput,
22
+ RunTimeCommand,
23
+ LoadLabwareRunTimeCommand,
24
+ } from '@opentrons/shared-data'
25
+
26
+ export * from './utils/getStandardDeckViewLayerBlockList'
27
+
28
+ interface ProtocolDeckProps {
29
+ protocolAnalysis: CompletedProtocolAnalysis | ProtocolAnalysisOutput | null
30
+ /** defaults to false, when set labware nicknames will appear on top level labware. If no nickname specified in protocol, falls back to labware definition display name */
31
+ showLabwareInfo?: boolean
32
+ /** optional labware click handler, highlights labware */
33
+ handleLabwareClick?: (
34
+ labwareDef: LabwareDefinition2,
35
+ labwareId: string
36
+ ) => void
37
+ /** extra props to pass through to BaseDeck component */
38
+ baseDeckProps?: Partial<React.ComponentProps<typeof BaseDeck>>
39
+ }
40
+
41
+ export function ProtocolDeck(props: ProtocolDeckProps): JSX.Element | null {
42
+ const {
43
+ protocolAnalysis,
44
+ baseDeckProps,
45
+ handleLabwareClick,
46
+ showLabwareInfo = false,
47
+ } = props
48
+
49
+ if (protocolAnalysis == null || (protocolAnalysis?.errors ?? []).length > 0)
50
+ return null
51
+ const commands: RunTimeCommand[] = protocolAnalysis.commands
52
+ const loadLabwareCommands = commands?.filter(
53
+ (command): command is LoadLabwareRunTimeCommand =>
54
+ command.commandType === 'loadLabware'
55
+ )
56
+
57
+ const robotType = protocolAnalysis.robotType ?? FLEX_ROBOT_TYPE
58
+ const deckConfig = getSimplestDeckConfigForProtocol(protocolAnalysis)
59
+ const labwareByLiquidId = getLabwareInfoByLiquidId(protocolAnalysis.commands)
60
+
61
+ const modulesInSlots = getModulesInSlots(protocolAnalysis)
62
+ const modulesOnDeck = modulesInSlots.map(
63
+ ({
64
+ moduleModel,
65
+ moduleLocation,
66
+ nestedLabwareId,
67
+ nestedLabwareDef,
68
+ nestedLabwareNickName,
69
+ }) => {
70
+ const { topLabwareId, topLabwareDefinition } = getTopLabwareInfo(
71
+ nestedLabwareId ?? '',
72
+ loadLabwareCommands
73
+ )
74
+
75
+ return {
76
+ moduleModel,
77
+ moduleLocation,
78
+ nestedLabwareDef,
79
+ nestedLabwareWellFill: getWellFillFromLabwareId(
80
+ nestedLabwareId ?? '',
81
+ protocolAnalysis.liquids,
82
+ labwareByLiquidId
83
+ ),
84
+ moduleChildren:
85
+ showLabwareInfo &&
86
+ nestedLabwareDef != null &&
87
+ !(nestedLabwareDef.allowedRoles ?? []).includes('adapter') ? (
88
+ <LabwareInfo def={nestedLabwareDef}>
89
+ {nestedLabwareNickName ?? getLabwareDisplayName(nestedLabwareDef)}
90
+ </LabwareInfo>
91
+ ) : null,
92
+ highlightLabware: handleLabwareClick != null,
93
+ highlightShadowLabware:
94
+ handleLabwareClick != null &&
95
+ topLabwareDefinition != null &&
96
+ topLabwareId != null,
97
+ onLabwareClick:
98
+ handleLabwareClick != null &&
99
+ topLabwareDefinition != null &&
100
+ topLabwareId != null
101
+ ? () => {
102
+ handleLabwareClick(topLabwareDefinition, topLabwareId)
103
+ }
104
+ : undefined,
105
+ stacked:
106
+ handleLabwareClick != null &&
107
+ topLabwareDefinition != null &&
108
+ topLabwareId != null,
109
+ }
110
+ }
111
+ )
112
+
113
+ // this function gets the top labware assuming a stack of max 2 labware
114
+ const topMostLabwareInSlots = getTopMostLabwareInSlots(protocolAnalysis)
115
+ const labwareOnDeck = topMostLabwareInSlots.map(
116
+ ({ labwareId, labwareDef, labwareNickName, location }) => {
117
+ // this gets the very top of the stack in case there is a stack
118
+ // of many like items, such as TC lids
119
+ const { topLabwareId, topLabwareDefinition } = getTopLabwareInfo(
120
+ labwareId,
121
+ loadLabwareCommands
122
+ )
123
+ const isLabwareInStack = protocolAnalysis?.commands.some(
124
+ command =>
125
+ command.commandType === 'loadLabware' &&
126
+ command.result?.labwareId === labwareId &&
127
+ typeof command.params.location === 'object' &&
128
+ ('moduleId' in command.params.location ||
129
+ 'labwareId' in command.params.location)
130
+ )
131
+
132
+ return {
133
+ definition: labwareDef,
134
+ labwareLocation: location,
135
+ wellFill: getWellFillFromLabwareId(
136
+ labwareId,
137
+ protocolAnalysis.liquids,
138
+ labwareByLiquidId
139
+ ),
140
+ labwareChildren: showLabwareInfo ? (
141
+ <LabwareInfo def={labwareDef}>
142
+ {labwareNickName ?? getLabwareDisplayName(labwareDef)}
143
+ </LabwareInfo>
144
+ ) : null,
145
+ highlight: handleLabwareClick != null,
146
+ highlightShadow: handleLabwareClick != null && isLabwareInStack,
147
+ onLabwareClick:
148
+ handleLabwareClick != null && topLabwareDefinition != null
149
+ ? () => {
150
+ handleLabwareClick(topLabwareDefinition, topLabwareId)
151
+ }
152
+ : undefined,
153
+ stacked: handleLabwareClick != null && isLabwareInStack,
154
+ }
155
+ }
156
+ )
157
+
158
+ return (
159
+ <BaseDeck
160
+ deckConfig={deckConfig}
161
+ deckLayerBlocklist={getStandardDeckViewLayerBlockList(robotType)}
162
+ robotType={robotType}
163
+ labwareOnDeck={labwareOnDeck}
164
+ modulesOnDeck={modulesOnDeck}
165
+ {...{
166
+ svgProps: {
167
+ 'aria-label': 'protocol deck map',
168
+ ...(baseDeckProps?.svgProps ?? {}),
169
+ },
170
+ ...baseDeckProps,
171
+ }}
172
+ />
173
+ )
174
+ }
@@ -0,0 +1,6 @@
1
+ export interface LabwareByLiquidId {
2
+ [liquidId: string]: Array<{
3
+ labwareId: string
4
+ volumeByWell: { [well: string]: number }
5
+ }>
6
+ }
@@ -0,0 +1,33 @@
1
+ import reduce from 'lodash/reduce'
2
+ import type {
3
+ LoadLabwareRunTimeCommand,
4
+ RunTimeCommand,
5
+ } from '@opentrons/shared-data'
6
+
7
+ export interface LoadedLabwareByAdapter {
8
+ [labwareId: string]: LoadLabwareRunTimeCommand
9
+ }
10
+ export function getInitialLoadedLabwareByAdapter(
11
+ commands: RunTimeCommand[]
12
+ ): LoadedLabwareByAdapter {
13
+ const loadLabwareCommandsReversed = commands
14
+ .filter(
15
+ (command): command is LoadLabwareRunTimeCommand =>
16
+ command.commandType === 'loadLabware'
17
+ )
18
+ .reverse()
19
+ return reduce<LoadLabwareRunTimeCommand, LoadedLabwareByAdapter>(
20
+ loadLabwareCommandsReversed,
21
+ (acc, command) => {
22
+ if (
23
+ typeof command.params.location === 'object' &&
24
+ 'labwareId' in command.params.location
25
+ ) {
26
+ return { ...acc, [command.params.location.labwareId]: command }
27
+ } else {
28
+ return acc
29
+ }
30
+ },
31
+ {}
32
+ )
33
+ }
@@ -0,0 +1,155 @@
1
+ import { getInitialLoadedLabwareByAdapter } from './getInitiallyLoadedLabwareByAdapter'
2
+ import type {
3
+ CompletedProtocolAnalysis,
4
+ LoadLabwareRunTimeCommand,
5
+ MoveLabwareRunTimeCommand,
6
+ ProtocolAnalysisOutput,
7
+ LabwareDefinition2,
8
+ } from '@opentrons/shared-data'
9
+
10
+ interface LabwareInSlot {
11
+ labwareId: string
12
+ labwareDef: LabwareDefinition2
13
+ labwareNickName: string | null
14
+ location: { slotName: string }
15
+ }
16
+
17
+ export const getInitialAndMovedLabwareInSlots = (
18
+ protocolAnalysis: CompletedProtocolAnalysis | ProtocolAnalysisOutput
19
+ ): LabwareInSlot[] => {
20
+ const { commands } = protocolAnalysis
21
+ const initialLoadedLabwareByAdapter = getInitialLoadedLabwareByAdapter(
22
+ commands
23
+ )
24
+ const topMostLabwareInSlots = getTopMostLabwareInSlots(protocolAnalysis)
25
+
26
+ return commands
27
+ .filter(
28
+ (command): command is MoveLabwareRunTimeCommand =>
29
+ command.commandType === 'moveLabware'
30
+ )
31
+ .reduce<LabwareInSlot[]>((acc, command) => {
32
+ const labwareId = command.params.labwareId
33
+ const location = command.params.newLocation
34
+
35
+ const originalLabware = topMostLabwareInSlots.find(
36
+ labware => labware.labwareId === labwareId
37
+ )
38
+ const labwareDef = originalLabware?.labwareDef
39
+
40
+ if (
41
+ location === 'offDeck' ||
42
+ 'moduleId' in location ||
43
+ 'labwareId' in location
44
+ )
45
+ return acc
46
+ if (labwareId == null) {
47
+ console.warn('expected to find labware id but could not')
48
+ return acc
49
+ }
50
+ if (labwareDef == null) {
51
+ console.warn(
52
+ `expected to find labware def for labware id ${String(
53
+ labwareId
54
+ )} but could not`
55
+ )
56
+ return acc
57
+ }
58
+
59
+ const slotName =
60
+ 'addressableAreaName' in location
61
+ ? location.addressableAreaName
62
+ : location.slotName
63
+
64
+ // if list of labware already includes slotName, return acc
65
+ if (acc.find(labware => labware.location.slotName === slotName) != null) {
66
+ return acc
67
+ }
68
+
69
+ const labwareInAdapter = initialLoadedLabwareByAdapter[labwareId]
70
+
71
+ // NOTE: only grabbing the labware on top most layer so
72
+ // either the adapter or the labware but not both
73
+ const topLabwareDefinition =
74
+ labwareInAdapter?.result?.definition ?? labwareDef
75
+ const topLabwareId = labwareInAdapter?.result?.labwareId ?? labwareId
76
+ const topLabwareNickName =
77
+ labwareInAdapter?.params?.displayName ??
78
+ originalLabware?.labwareNickName ??
79
+ null
80
+
81
+ return [
82
+ ...acc,
83
+ {
84
+ labwareId: topLabwareId,
85
+ labwareDef: topLabwareDefinition,
86
+ labwareNickName: topLabwareNickName,
87
+ location: { slotName },
88
+ },
89
+ ]
90
+ }, topMostLabwareInSlots)
91
+ }
92
+
93
+ export const getTopMostLabwareInSlots = (
94
+ protocolAnalysis: CompletedProtocolAnalysis | ProtocolAnalysisOutput
95
+ ): LabwareInSlot[] => {
96
+ const { commands } = protocolAnalysis
97
+ const initialLoadedLabwareByAdapter = getInitialLoadedLabwareByAdapter(
98
+ commands
99
+ )
100
+ return commands
101
+ .filter(
102
+ (command): command is LoadLabwareRunTimeCommand =>
103
+ command.commandType === 'loadLabware'
104
+ )
105
+ .reduce<LabwareInSlot[]>((acc, command) => {
106
+ const labwareId = command.result?.labwareId
107
+ const location = command.params.location
108
+ const labwareDef = command.result?.definition
109
+ if (
110
+ location === 'offDeck' ||
111
+ 'moduleId' in location ||
112
+ 'labwareId' in location
113
+ )
114
+ return acc
115
+ if (labwareId == null) {
116
+ console.warn('expected to find labware id but could not')
117
+ return acc
118
+ }
119
+ if (labwareDef == null) {
120
+ console.warn(
121
+ `expected to find labware def for labware id ${String(
122
+ labwareId
123
+ )} but could not`
124
+ )
125
+ return acc
126
+ }
127
+
128
+ const slotName =
129
+ 'addressableAreaName' in location
130
+ ? location.addressableAreaName
131
+ : location.slotName
132
+
133
+ const labwareInAdapter = initialLoadedLabwareByAdapter[labwareId]
134
+
135
+ // NOTE: only grabbing the labware on top most layer so
136
+ // either the adapter or the labware but not both
137
+ const topLabwareDefinition =
138
+ labwareInAdapter?.result?.definition ?? labwareDef
139
+ const topLabwareId = labwareInAdapter?.result?.labwareId ?? labwareId
140
+ const topLabwareNickName =
141
+ labwareInAdapter?.params?.displayName ??
142
+ command.params.displayName ??
143
+ null
144
+
145
+ return [
146
+ ...acc,
147
+ {
148
+ labwareId: topLabwareId,
149
+ labwareDef: topLabwareDefinition,
150
+ labwareNickName: topLabwareNickName,
151
+ location: { slotName },
152
+ },
153
+ ]
154
+ }, [])
155
+ }
@@ -0,0 +1,42 @@
1
+ import reduce from 'lodash/reduce'
2
+ import type {
3
+ LoadLiquidRunTimeCommand,
4
+ RunTimeCommand,
5
+ } from '@opentrons/shared-data'
6
+ import type { LabwareByLiquidId } from '../types'
7
+
8
+ export function getLabwareInfoByLiquidId(
9
+ commands: RunTimeCommand[]
10
+ ): LabwareByLiquidId {
11
+ const loadLiquidCommands =
12
+ commands.length !== 0
13
+ ? commands.filter(
14
+ (command): command is LoadLiquidRunTimeCommand =>
15
+ command.commandType === 'loadLiquid'
16
+ )
17
+ : []
18
+
19
+ return reduce<LoadLiquidRunTimeCommand, LabwareByLiquidId>(
20
+ loadLiquidCommands,
21
+ (acc, command) => {
22
+ if (!(command.params.liquidId in acc)) {
23
+ acc[command.params.liquidId] = []
24
+ }
25
+ const labwareId = command.params.labwareId
26
+ const volumeByWell = command.params.volumeByWell
27
+ const labwareIndex = acc[command.params.liquidId].findIndex(
28
+ i => i.labwareId === labwareId
29
+ )
30
+ if (labwareIndex >= 0) {
31
+ acc[command.params.liquidId][labwareIndex].volumeByWell = {
32
+ ...acc[command.params.liquidId][labwareIndex].volumeByWell,
33
+ ...volumeByWell,
34
+ }
35
+ } else {
36
+ acc[command.params.liquidId].push({ labwareId, volumeByWell })
37
+ }
38
+ return acc
39
+ },
40
+ {}
41
+ )
42
+ }
@@ -0,0 +1,129 @@
1
+ import {
2
+ SPAN7_8_10_11_SLOT,
3
+ getModuleDef2,
4
+ getLoadedLabwareDefinitionsByUri,
5
+ } from '@opentrons/shared-data'
6
+ import type {
7
+ CompletedProtocolAnalysis,
8
+ LoadLabwareRunTimeCommand,
9
+ ProtocolAnalysisOutput,
10
+ LoadModuleRunTimeCommand,
11
+ RunTimeCommand,
12
+ ModuleLocation,
13
+ ModuleModel,
14
+ LabwareDefinition2,
15
+ } from '@opentrons/shared-data'
16
+ import { getInitialLoadedLabwareByAdapter } from './getInitiallyLoadedLabwareByAdapter'
17
+
18
+ interface ModuleInSlot {
19
+ moduleModel: ModuleModel
20
+ moduleLocation: ModuleLocation
21
+ nestedLabwareId: string | null
22
+ nestedLabwareDef: LabwareDefinition2 | null
23
+ nestedLabwareNickName: string | null
24
+ }
25
+ export const getModulesInSlots = (
26
+ protocolAnalysis: ProtocolAnalysisOutput | CompletedProtocolAnalysis
27
+ ): ModuleInSlot[] => {
28
+ if (protocolAnalysis != null && 'modules' in protocolAnalysis) {
29
+ const { commands, modules, labware } = protocolAnalysis
30
+ const initialLoadedLabwareByAdapter = getInitialLoadedLabwareByAdapter(
31
+ commands
32
+ )
33
+ return modules.reduce<ModuleInSlot[]>((acc, module) => {
34
+ const moduleDef = getModuleDef2(module.model)
35
+ const nestedLabwareId =
36
+ commands
37
+ .filter(
38
+ (command): command is LoadLabwareRunTimeCommand =>
39
+ command.commandType === 'loadLabware'
40
+ )
41
+ .find(
42
+ (command: LoadLabwareRunTimeCommand) =>
43
+ typeof command.params.location === 'object' &&
44
+ 'moduleId' in command.params.location &&
45
+ command.params.location.moduleId === module.id
46
+ )?.result?.labwareId ?? null
47
+ const nestedLabware = labware.find(
48
+ item => nestedLabwareId != null && item.id === nestedLabwareId
49
+ )
50
+ const labwareDefinitionsByUri = getLoadedLabwareDefinitionsByUri(commands)
51
+ const nestedLabwareDef =
52
+ nestedLabware != null
53
+ ? labwareDefinitionsByUri[nestedLabware.definitionUri]
54
+ : null
55
+ const moduleInitialLoadInfo = getModuleInitialLoadInfo(
56
+ module.id,
57
+ commands
58
+ )
59
+ let slotName = moduleInitialLoadInfo.location.slotName
60
+ // Note: this is because PD for OT2 represents the slot the TC sits in as a made up slot. We want it to be rendered in slot 7
61
+ if (slotName === SPAN7_8_10_11_SLOT) {
62
+ slotName = '7'
63
+ }
64
+
65
+ const labwareInAdapterInMod =
66
+ nestedLabwareId != null
67
+ ? initialLoadedLabwareByAdapter[nestedLabwareId]
68
+ : null
69
+ // NOTE: only rendering the labware on top most layer so
70
+ // either the adapter or the labware are rendered but not both
71
+ const topLabwareDefinition =
72
+ labwareInAdapterInMod?.result?.definition ?? nestedLabwareDef
73
+ const topLabwareId =
74
+ labwareInAdapterInMod?.result?.labwareId ?? nestedLabwareId
75
+ const topLabwareDisplayName =
76
+ labwareInAdapterInMod != null
77
+ ? labwareInAdapterInMod.params.displayName?.toString() ?? null
78
+ : nestedLabware?.displayName?.toString() ?? null
79
+ return [
80
+ ...acc,
81
+ {
82
+ moduleModel: moduleDef.model,
83
+ moduleLocation: { slotName },
84
+ nestedLabwareId: topLabwareId,
85
+ nestedLabwareDef: topLabwareDefinition,
86
+ nestedLabwareNickName: topLabwareDisplayName,
87
+ },
88
+ ]
89
+ }, [])
90
+ }
91
+
92
+ return []
93
+ }
94
+
95
+ function getModuleInitialLoadInfo(
96
+ moduleId: string,
97
+ commands: RunTimeCommand[]
98
+ ): {
99
+ location: ModuleLocation
100
+ protocolLoadOrder: number
101
+ } {
102
+ const moduleLoadIndex = commands.findIndex(
103
+ (command: RunTimeCommand): command is LoadModuleRunTimeCommand =>
104
+ command.commandType === 'loadModule' &&
105
+ command.result?.moduleId === moduleId
106
+ )
107
+
108
+ if (moduleLoadIndex === -1) {
109
+ throw new Error(
110
+ 'expected to be able to find module location, but could not'
111
+ )
112
+ }
113
+
114
+ const protocolLoadOrder = commands
115
+ .slice(0, moduleLoadIndex)
116
+ .reduce(
117
+ (moduleLoadCount, command) =>
118
+ command.commandType === 'loadModule'
119
+ ? moduleLoadCount + 1
120
+ : moduleLoadCount,
121
+ 0
122
+ )
123
+
124
+ return {
125
+ location: (commands[moduleLoadIndex] as LoadModuleRunTimeCommand).params
126
+ .location,
127
+ protocolLoadOrder,
128
+ }
129
+ }
@@ -0,0 +1,29 @@
1
+ import type { RobotType } from '@opentrons/shared-data'
2
+
3
+ const OT2_STANDARD_DECK_VIEW_LAYER_BLOCK_LIST: string[] = [
4
+ 'calibrationMarkings',
5
+ 'fixedBase',
6
+ 'doorStops',
7
+ 'metalFrame',
8
+ 'removalHandle',
9
+ 'removableDeckOutline',
10
+ 'screwHoles',
11
+ ]
12
+
13
+ const OT3_STANDARD_DECK_VIEW_LAYER_BLOCK_LIST: string[] = [
14
+ 'DECK_BASE',
15
+ 'BARCODE_COVERS',
16
+ ]
17
+
18
+ export const getStandardDeckViewLayerBlockList = (
19
+ robotType: RobotType
20
+ ): string[] => {
21
+ switch (robotType) {
22
+ case 'OT-2 Standard':
23
+ return OT2_STANDARD_DECK_VIEW_LAYER_BLOCK_LIST
24
+ case 'OT-3 Standard':
25
+ return OT3_STANDARD_DECK_VIEW_LAYER_BLOCK_LIST
26
+ default:
27
+ return []
28
+ }
29
+ }
@@ -0,0 +1,30 @@
1
+ import type { Liquid } from '@opentrons/shared-data'
2
+ import type { WellFill } from '../../Labware'
3
+ import type { LabwareByLiquidId } from '../types'
4
+
5
+ export function getWellFillFromLabwareId(
6
+ labwareId: string,
7
+ liquidsInLoadOrder: Liquid[],
8
+ labwareByLiquidId: LabwareByLiquidId
9
+ ): WellFill {
10
+ let labwareWellFill: WellFill = {}
11
+ const liquidIds = Object.keys(labwareByLiquidId)
12
+ const labwareInfo = Object.values(labwareByLiquidId)
13
+
14
+ labwareInfo.forEach((labwareArray, index) => {
15
+ labwareArray.forEach(labware => {
16
+ if (labware.labwareId === labwareId) {
17
+ const liquidId = liquidIds[index]
18
+ const liquid = liquidsInLoadOrder.find(liquid => liquid.id === liquidId)
19
+ const wellFill: {
20
+ [well: string]: string
21
+ } = {}
22
+ Object.keys(labware.volumeByWell).forEach(key => {
23
+ wellFill[key] = liquid?.displayColor ?? ''
24
+ })
25
+ labwareWellFill = { ...labwareWellFill, ...wellFill }
26
+ }
27
+ })
28
+ })
29
+ return labwareWellFill
30
+ }
@@ -0,0 +1,3 @@
1
+ export * from './getLabwareInSlots'
2
+ export * from './getStandardDeckViewLayerBlockList'
3
+ export * from './getLabwareInfoByLiquidId'
@@ -0,0 +1,28 @@
1
+ import styled from 'styled-components'
2
+ import { animated } from '@react-spring/web'
3
+ import type * as React from 'react'
4
+ import { Svg } from '../../primitives'
5
+
6
+ interface RobotCoordinateSpaceProps extends React.ComponentProps<typeof Svg> {
7
+ animated?: boolean
8
+ }
9
+ export function RobotCoordinateSpace(
10
+ props: RobotCoordinateSpaceProps
11
+ ): JSX.Element {
12
+ const { animated = false, children, ...restProps } = props
13
+ const allPassThroughProps = {
14
+ transform: 'scale(1, -1)',
15
+ ...restProps,
16
+ }
17
+ return animated ? (
18
+ <AnimatedSvg {...allPassThroughProps}>{children}</AnimatedSvg>
19
+ ) : (
20
+ <Svg {...allPassThroughProps}>{children}</Svg>
21
+ )
22
+ }
23
+
24
+ /**
25
+ * These animated components needs to be split out because react-spring and styled-components don't play nice
26
+ * @see https://github.com/pmndrs/react-spring/issues/1515 */
27
+ // @ts-expect-error Type instantiation is excessively deep and possibly infinite
28
+ const AnimatedSvg = styled(animated.svg)<typeof animated.svg>``
@@ -0,0 +1,52 @@
1
+ import { useRef } from 'react'
2
+ import { Svg } from '../../primitives'
3
+
4
+ import type { ReactNode } from 'react'
5
+ import type { DeckDefinition, DeckSlot } from '@opentrons/shared-data'
6
+
7
+ export interface RobotCoordinateSpaceWithRefRenderProps {
8
+ deckSlotsById: { [slotId: string]: DeckSlot }
9
+ }
10
+
11
+ interface RobotCoordinateSpaceWithRefProps
12
+ extends React.ComponentProps<typeof Svg> {
13
+ viewBox?: string | null
14
+ deckDef?: DeckDefinition
15
+ zoomed?: boolean
16
+ children?: (props: RobotCoordinateSpaceWithRefRenderProps) => ReactNode
17
+ }
18
+
19
+ export function RobotCoordinateSpaceWithRef(
20
+ props: RobotCoordinateSpaceWithRefProps
21
+ ): JSX.Element | null {
22
+ const { children, deckDef, viewBox, zoomed = false, ...restProps } = props
23
+ const wrapperRef = useRef<SVGSVGElement>(null)
24
+
25
+ if (deckDef == null && viewBox == null) return null
26
+
27
+ let wholeDeckViewBox
28
+ let deckSlotsById = {}
29
+ if (deckDef != null) {
30
+ const [viewBoxOriginX, viewBoxOriginY] = deckDef.cornerOffsetFromOrigin
31
+ const [deckXDimension, deckYDimension] = deckDef.dimensions
32
+
33
+ deckSlotsById = deckDef.locations.addressableAreas.reduce(
34
+ (acc, deckSlot) => ({ ...acc, [deckSlot.id]: deckSlot }),
35
+ {}
36
+ )
37
+ wholeDeckViewBox = `${viewBoxOriginX} ${viewBoxOriginY} ${deckXDimension} ${deckYDimension}`
38
+ }
39
+
40
+ return (
41
+ <Svg
42
+ viewBox={zoomed ? viewBox : wholeDeckViewBox}
43
+ ref={wrapperRef}
44
+ transform="scale(1, -1)"
45
+ width="100%"
46
+ height="100%"
47
+ {...restProps}
48
+ >
49
+ {children?.({ deckSlotsById })}
50
+ </Svg>
51
+ )
52
+ }
@@ -0,0 +1,2 @@
1
+ export * from './RobotCoordinateSpaceWithRef'
2
+ export * from './RobotCoordinateSpace'