@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,49 @@
1
+ import { THERMOCYCLER_MODULE_V1, getModuleDef2 } from '@opentrons/shared-data'
2
+
3
+ import { C_MED_LIGHT_GRAY } from '../../../styles'
4
+ import { COLORS, BORDERS } from '../../../helix-design-system'
5
+
6
+ import { RobotCoordsForeignDiv } from '../../Deck'
7
+ import { ThermocyclerGEN1 } from './ThermocyclerGEN1'
8
+ import { ThermocyclerGEN2 } from './ThermocyclerGEN2'
9
+ import type { ThermocyclerModuleModel } from '@opentrons/shared-data'
10
+
11
+ const ROOM_TEMPERATURE_C = 23 // value taken from TC firmware
12
+ export interface ThermocyclerVizProps {
13
+ lidMotorState: 'open' | 'closed' | 'unknown'
14
+ blockTargetTemp?: number | null
15
+ model: ThermocyclerModuleModel
16
+ }
17
+
18
+ export function Thermocycler(props: ThermocyclerVizProps): JSX.Element {
19
+ const { lidMotorState, blockTargetTemp, model } = props
20
+ const def = getModuleDef2(model)
21
+ if (lidMotorState === 'unknown') {
22
+ // just a rectangle if we don't know the state of the lid
23
+ return (
24
+ <RobotCoordsForeignDiv
25
+ width={def.dimensions.xDimension}
26
+ height={def.dimensions.yDimension}
27
+ innerDivProps={{
28
+ borderRadius: '6px',
29
+ backgroundColor: C_MED_LIGHT_GRAY,
30
+ border: BORDERS.lineBorder,
31
+ width: '100%',
32
+ height: '100%',
33
+ }}
34
+ />
35
+ )
36
+ }
37
+
38
+ let ledLightColor = COLORS.transparent
39
+ if (blockTargetTemp != null) {
40
+ ledLightColor =
41
+ blockTargetTemp <= ROOM_TEMPERATURE_C ? COLORS.blue35 : COLORS.red30
42
+ }
43
+
44
+ return model === THERMOCYCLER_MODULE_V1 ? (
45
+ <ThermocyclerGEN1 {...{ lidMotorState, ledLightColor }} />
46
+ ) : (
47
+ <ThermocyclerGEN2 {...{ lidMotorState, ledLightColor }} />
48
+ )
49
+ }
@@ -0,0 +1,227 @@
1
+ import type * as React from 'react'
2
+ import {
3
+ ABSORBANCE_READER_TYPE,
4
+ getModuleType,
5
+ HEATERSHAKER_MODULE_TYPE,
6
+ MAGNETIC_BLOCK_TYPE,
7
+ MAGNETIC_MODULE_TYPE,
8
+ OT2_STANDARD_DECKID,
9
+ TEMPERATURE_MODULE_TYPE,
10
+ THERMOCYCLER_MODULE_TYPE,
11
+ } from '@opentrons/shared-data'
12
+ import {
13
+ C_DARK_GRAY,
14
+ C_MED_LIGHT_GRAY,
15
+ SPACING_1,
16
+ JUSTIFY_CENTER,
17
+ DISPLAY_FLEX,
18
+ FONT_WEIGHT_SEMIBOLD,
19
+ DIRECTION_COLUMN,
20
+ ALIGN_CENTER,
21
+ } from '../../styles'
22
+ import { RobotCoordsForeignObject } from '../Deck'
23
+ import { multiplyMatrices } from '../utils'
24
+ import { Thermocycler } from './Thermocycler'
25
+ import { HeaterShaker } from './HeaterShaker'
26
+ import { Temperature } from './Temperature'
27
+ import { MagneticBlock } from './MagneticBlock'
28
+ import { MagneticModule } from './MagneticModule'
29
+ import { PlateReader } from './PlateReader'
30
+
31
+ import type {
32
+ ModuleDefinition,
33
+ ThermocyclerModuleModel,
34
+ } from '@opentrons/shared-data'
35
+
36
+ export * from './Thermocycler'
37
+
38
+ const LABWARE_OFFSET_DISPLAY_THRESHOLD = 2
39
+
40
+ interface Props {
41
+ x: number
42
+ y: number
43
+ def: ModuleDefinition
44
+ orientation?: 'left' | 'right'
45
+ innerProps?:
46
+ | React.ComponentProps<typeof Thermocycler>
47
+ | React.ComponentProps<typeof HeaterShaker>
48
+ | React.ComponentProps<typeof Temperature>
49
+ | {}
50
+ statusInfo?: React.ReactNode // contents of small status rectangle, not displayed if absent
51
+ children?: React.ReactNode // contents to be rendered on top of the labware mating surface of the module
52
+ targetSlotId?: string
53
+ targetDeckId?: string
54
+ }
55
+
56
+ const statusInfoWrapperProps = {
57
+ display: DISPLAY_FLEX,
58
+ alignItems: ALIGN_CENTER,
59
+ }
60
+ const statusInfoFlexProps = {
61
+ flexDirection: DIRECTION_COLUMN,
62
+ justifyContent: JUSTIFY_CENTER,
63
+ backgroundColor: C_MED_LIGHT_GRAY,
64
+ padding: SPACING_1,
65
+ fontSize: '0.5rem', // NOTE: this text is rendered into an SVG foreignObject, so sizing is non-standard
66
+ fontWeight: FONT_WEIGHT_SEMIBOLD,
67
+ paddingBottom: SPACING_1,
68
+ }
69
+
70
+ export const Module = (props: Props): JSX.Element => {
71
+ const {
72
+ def,
73
+ x,
74
+ y,
75
+ orientation = 'left',
76
+ innerProps = {},
77
+ statusInfo,
78
+ children,
79
+ targetSlotId,
80
+ targetDeckId = OT2_STANDARD_DECKID,
81
+ } = props
82
+ const moduleType = getModuleType(def.model)
83
+
84
+ const { x: labwareOffsetX, y: labwareOffsetY } = def.labwareOffset
85
+ const {
86
+ x: translateX,
87
+ y: translateY,
88
+ z: translateZ,
89
+ } = def.cornerOffsetFromSlot
90
+ const {
91
+ xDimension,
92
+ yDimension,
93
+ footprintXDimension,
94
+ footprintYDimension,
95
+ labwareInterfaceXDimension,
96
+ labwareInterfaceYDimension,
97
+ } = def.dimensions
98
+
99
+ // apply translation to position module in viewport
100
+ const positionTransform = `translate(${x}, ${y})`
101
+
102
+ // apply translation to compensate for the offset of the overall module's
103
+ // left-bottom-front corner, from the footprint's left-bottom-front corner (slot interface)
104
+ let offsetTransform = `translate(${translateX}, ${translateY})`
105
+
106
+ let nestedLabwareOffsetX = labwareOffsetX
107
+ let nestedLabwareOffsetY = labwareOffsetY
108
+
109
+ // additional transforms to apply to vectors in certain deck/slot combinations
110
+ const transformsForDeckBySlot = def?.slotTransforms?.[targetDeckId]
111
+ const slotTransformsForDeckSlot =
112
+ targetSlotId != null &&
113
+ transformsForDeckBySlot != null &&
114
+ targetSlotId in transformsForDeckBySlot
115
+ ? transformsForDeckBySlot[targetSlotId]
116
+ : null
117
+ const deckSpecificTransforms = slotTransformsForDeckSlot ?? {}
118
+ if (deckSpecificTransforms?.cornerOffsetFromSlot != null) {
119
+ const [
120
+ [slotTranslateX],
121
+ [slotTranslateY],
122
+ ] = multiplyMatrices(deckSpecificTransforms.cornerOffsetFromSlot, [
123
+ [translateX],
124
+ [translateY],
125
+ [translateZ],
126
+ [1],
127
+ ])
128
+ offsetTransform = `translate(${slotTranslateX}, ${slotTranslateY})`
129
+ }
130
+ if (deckSpecificTransforms?.labwareOffset != null) {
131
+ const [
132
+ [slotLabwareOffsetX],
133
+ [slotLabwareOffsetY],
134
+ ] = multiplyMatrices(deckSpecificTransforms.labwareOffset, [
135
+ [labwareOffsetX],
136
+ [labwareOffsetY],
137
+ [1],
138
+ [1],
139
+ ])
140
+ nestedLabwareOffsetX = slotLabwareOffsetX
141
+ nestedLabwareOffsetY = slotLabwareOffsetY
142
+ }
143
+
144
+ // find coordinates of center of footprint, fallback to overall center if not defined
145
+ const rotationCenterX = (footprintXDimension ?? xDimension) / 2
146
+ const rotationCenterY = (footprintYDimension ?? yDimension) / 2
147
+
148
+ const orientationTransform =
149
+ orientation === 'left' || moduleType === ABSORBANCE_READER_TYPE
150
+ ? 'rotate(0, 0, 0)'
151
+ : `rotate(180, ${rotationCenterX}, ${rotationCenterY})`
152
+
153
+ // labwareOffset values are more accurate than our SVG renderings, so ignore any deviations under a certain threshold
154
+ const clampedLabwareOffsetX =
155
+ Math.abs(nestedLabwareOffsetX) > LABWARE_OFFSET_DISPLAY_THRESHOLD
156
+ ? nestedLabwareOffsetX
157
+ : 0
158
+ const clampedLabwareOffsetY =
159
+ Math.abs(nestedLabwareOffsetY) > LABWARE_OFFSET_DISPLAY_THRESHOLD
160
+ ? nestedLabwareOffsetY
161
+ : 0
162
+ // transform to be applied to children which render within the labware interfacing surface of the module
163
+ const childrenTransform = `translate(${clampedLabwareOffsetX}, ${clampedLabwareOffsetY})`
164
+
165
+ const renderStatusInfo = (): JSX.Element | null => {
166
+ if (statusInfo == null) return null
167
+ const statusWidth = (labwareInterfaceXDimension ?? xDimension) / 2
168
+ return (
169
+ <RobotCoordsForeignObject
170
+ x={
171
+ orientation === 'left'
172
+ ? labwareOffsetX - statusWidth
173
+ : labwareOffsetX + (labwareInterfaceXDimension ?? xDimension)
174
+ }
175
+ y={labwareOffsetY}
176
+ height={labwareInterfaceYDimension ?? yDimension}
177
+ width={statusWidth}
178
+ foreignObjectProps={statusInfoWrapperProps}
179
+ flexProps={statusInfoFlexProps}
180
+ >
181
+ {statusInfo}
182
+ </RobotCoordsForeignObject>
183
+ )
184
+ }
185
+
186
+ let moduleViz: JSX.Element | null = null
187
+ if (moduleType === MAGNETIC_BLOCK_TYPE) {
188
+ moduleViz = <MagneticBlock />
189
+ } else if (moduleType === MAGNETIC_MODULE_TYPE) {
190
+ moduleViz = <MagneticModule />
191
+ } else if (moduleType === THERMOCYCLER_MODULE_TYPE) {
192
+ const thermocyclerProps = {
193
+ lidMotorState: 'open' as const,
194
+ ...innerProps,
195
+ model: def.model as ThermocyclerModuleModel,
196
+ }
197
+
198
+ moduleViz = <Thermocycler {...thermocyclerProps} />
199
+ } else if (moduleType === HEATERSHAKER_MODULE_TYPE) {
200
+ moduleViz = (
201
+ <HeaterShaker
202
+ {...(innerProps as React.ComponentProps<typeof HeaterShaker>)}
203
+ />
204
+ )
205
+ } else if (moduleType === TEMPERATURE_MODULE_TYPE) {
206
+ moduleViz = (
207
+ <Temperature
208
+ {...(innerProps as React.ComponentProps<typeof Temperature>)}
209
+ />
210
+ )
211
+ } else if (moduleType === ABSORBANCE_READER_TYPE) {
212
+ moduleViz = <PlateReader />
213
+ }
214
+ return (
215
+ <g transform={positionTransform} data-test={`Module_${moduleType}`}>
216
+ <g transform={orientationTransform}>
217
+ <g transform={offsetTransform} style={{ fill: C_DARK_GRAY }}>
218
+ {moduleViz}
219
+ </g>
220
+ </g>
221
+ {renderStatusInfo()}
222
+ {children != null ? (
223
+ <g transform={childrenTransform}>{children}</g>
224
+ ) : null}
225
+ </g>
226
+ )
227
+ }
@@ -0,0 +1,23 @@
1
+ import { Fragment } from 'react'
2
+ import { EmanatingNozzle } from './EmanatingNozzle'
3
+
4
+ export const EightEmanatingNozzles = (props: {
5
+ cx: number
6
+ initialCy: number
7
+ }): JSX.Element => {
8
+ const { cx, initialCy } = props
9
+ const MULTI_CHANNEL_NOZZLE_SPACING = 9
10
+ return (
11
+ <Fragment>
12
+ {[...Array(8)].map((_, i: number) => {
13
+ return (
14
+ <EmanatingNozzle
15
+ cx={cx}
16
+ cy={initialCy + i * MULTI_CHANNEL_NOZZLE_SPACING}
17
+ key={`Circle_${i}`}
18
+ />
19
+ )
20
+ })}
21
+ </Fragment>
22
+ )
23
+ }
@@ -0,0 +1,52 @@
1
+ import { Fragment } from 'react'
2
+ import { C_SELECTED_DARK, C_TRANSPARENT } from '../../styles'
3
+ import { SINGLE_CHANNEL_PIPETTE_HEIGHT } from './constants'
4
+
5
+ export const EmanatingNozzle = (props: {
6
+ cx: number
7
+ cy: number
8
+ }): JSX.Element => {
9
+ const { cx, cy } = props
10
+ return (
11
+ <Fragment>
12
+ <circle
13
+ data-testid="origin_circle"
14
+ cx={cx}
15
+ cy={cy}
16
+ r={0.5}
17
+ stroke={C_SELECTED_DARK}
18
+ fill={C_SELECTED_DARK}
19
+ ></circle>
20
+ <circle
21
+ data-testid="emanating_circle"
22
+ cx={cx}
23
+ cy={cy}
24
+ r={0.5}
25
+ stroke={C_SELECTED_DARK}
26
+ strokeWidth={'2px'}
27
+ fill={C_TRANSPARENT}
28
+ >
29
+ <animate
30
+ data-testid="radius_animation"
31
+ attributeName="r"
32
+ from={5}
33
+ to={SINGLE_CHANNEL_PIPETTE_HEIGHT / 2}
34
+ begin={0}
35
+ dur={1.1}
36
+ calcMode="ease-out"
37
+ repeatCount="indefinite"
38
+ />
39
+ <animate
40
+ data-testid="opacity_animation"
41
+ attributeName="opacity"
42
+ from={0.7}
43
+ to={0}
44
+ begin={0}
45
+ dur={1.1}
46
+ calcMode="linear"
47
+ repeatCount="indefinite"
48
+ />
49
+ </circle>
50
+ </Fragment>
51
+ )
52
+ }
@@ -0,0 +1,71 @@
1
+ import { Fragment } from 'react'
2
+ import { getAllLabwareDefs, getAllPipetteNames } from '@opentrons/shared-data'
3
+ import { LabwareRender } from '../Labware'
4
+ import { RobotWorkSpace } from '../Deck'
5
+ import { PipetteRender } from './'
6
+
7
+ import type { Story, Meta } from '@storybook/react'
8
+ import type { LabwareDefinition2, PipetteName } from '@opentrons/shared-data'
9
+
10
+ const DECK_MAP_VIEWBOX = '0 -140 230 230'
11
+
12
+ const opentrons300UlTiprack = getAllLabwareDefs().opentrons96Tiprack300UlV1
13
+ const opentrons10UlTiprack = getAllLabwareDefs().opentrons96Tiprack10UlV1
14
+ const nest12Reservoir15ml = getAllLabwareDefs().nest12Reservoir15MlV1
15
+ const axygenReservoir90ml = getAllLabwareDefs().axygen1Reservoir90MlV1
16
+ const opentrons6TuberackNest50mlConical = getAllLabwareDefs()
17
+ .opentrons6TuberackNest50MlConicalV1
18
+
19
+ const labwareDefMap: Record<string, LabwareDefinition2> = {
20
+ [opentrons300UlTiprack.metadata.displayName]: opentrons300UlTiprack,
21
+ [opentrons10UlTiprack.metadata.displayName]: opentrons10UlTiprack,
22
+ [nest12Reservoir15ml.metadata.displayName]: nest12Reservoir15ml,
23
+ [axygenReservoir90ml.metadata.displayName]: axygenReservoir90ml,
24
+ [opentrons6TuberackNest50mlConical.metadata
25
+ .displayName]: opentrons6TuberackNest50mlConical,
26
+ }
27
+ const pipetteNames = Object.keys(getAllPipetteNames()) as PipetteName[]
28
+
29
+ export default {
30
+ title: 'Library/Molecules/Simulation/Pipette/PipetteRender',
31
+ } as Meta
32
+
33
+ const Template: Story<{
34
+ labwareName: string
35
+ pipetteName: PipetteName
36
+ }> = args => {
37
+ const labwareDef = labwareDefMap[args.labwareName]
38
+ return (
39
+ <RobotWorkSpace viewBox={DECK_MAP_VIEWBOX}>
40
+ {() => (
41
+ <Fragment>
42
+ <LabwareRender definition={labwareDef} />
43
+ <PipetteRender
44
+ labwareDef={labwareDef}
45
+ pipetteName={args.pipetteName}
46
+ />
47
+ </Fragment>
48
+ )}
49
+ </RobotWorkSpace>
50
+ )
51
+ }
52
+ export const Pipette = Template.bind({})
53
+
54
+ Pipette.argTypes = {
55
+ labwareName: {
56
+ control: {
57
+ type: 'select',
58
+ options: Object.keys(labwareDefMap).map(
59
+ d => labwareDefMap[d].metadata.displayName
60
+ ),
61
+ },
62
+ defaultValue: opentrons300UlTiprack.metadata.displayName,
63
+ },
64
+ pipetteName: {
65
+ control: {
66
+ type: 'select',
67
+ options: pipetteNames,
68
+ },
69
+ defaultValue: pipetteNames[0],
70
+ },
71
+ }
@@ -0,0 +1,92 @@
1
+ import { getPipetteNameSpecs } from '@opentrons/shared-data'
2
+ import { C_MED_DARK_GRAY, C_MED_GRAY } from '../../styles'
3
+ import { BORDERS } from '../../helix-design-system'
4
+ import { RobotCoordsForeignDiv } from '../Deck/RobotCoordsForeignDiv'
5
+ import {
6
+ MULTI_CHANNEL_PIPETTE_WIDTH,
7
+ SINGLE_CHANNEL_PIPETTE_WIDTH,
8
+ SINGLE_CHANNEL_PIPETTE_HEIGHT,
9
+ MULTI_CHANNEL_PIPETTE_HEIGHT,
10
+ MULTI_CHANNEL_CENTER_Y_NOZZLE,
11
+ MULTI_CHANNEL_Y_OFFSET,
12
+ NINETY_SIX_CHANNEL_PIPETTE_WIDTH,
13
+ } from './constants'
14
+ import { EmanatingNozzle } from './EmanatingNozzle'
15
+ import { EightEmanatingNozzles } from './EightEmanatingNozzles'
16
+ import type { LabwareDefinition2, PipetteName } from '@opentrons/shared-data'
17
+
18
+ interface PipetteRenderProps {
19
+ labwareDef: LabwareDefinition2
20
+ pipetteName: PipetteName
21
+ usingMetalProbe?: boolean
22
+ }
23
+
24
+ export const PipetteRender = (props: PipetteRenderProps): JSX.Element => {
25
+ const { labwareDef, pipetteName, usingMetalProbe = false } = props
26
+ const channels = getPipetteNameSpecs(pipetteName)?.channels
27
+ const cx =
28
+ channels === 1
29
+ ? SINGLE_CHANNEL_PIPETTE_WIDTH / 2
30
+ : MULTI_CHANNEL_PIPETTE_WIDTH / 2
31
+ const cy =
32
+ channels === 1
33
+ ? SINGLE_CHANNEL_PIPETTE_HEIGHT / 2
34
+ : MULTI_CHANNEL_CENTER_Y_NOZZLE
35
+ const x = labwareDef.wells.A1.x - cx
36
+ const y = channels === 1 ? labwareDef.wells.A1.y - cy : MULTI_CHANNEL_Y_OFFSET
37
+
38
+ let boxWidth: number
39
+ let probeOffsetX: number = 0
40
+ let probeOffsetY: number = 0
41
+ if (channels === 1) {
42
+ boxWidth = SINGLE_CHANNEL_PIPETTE_WIDTH
43
+ } else if (channels === 8) {
44
+ boxWidth = MULTI_CHANNEL_PIPETTE_WIDTH
45
+ probeOffsetY = 63
46
+ } else {
47
+ boxWidth = NINETY_SIX_CHANNEL_PIPETTE_WIDTH
48
+ probeOffsetY = 63
49
+ if (Object.keys(labwareDef.wells).length === 1) {
50
+ probeOffsetX = 99 / 2
51
+ }
52
+ }
53
+
54
+ return (
55
+ <RobotCoordsForeignDiv
56
+ width={boxWidth}
57
+ height={
58
+ channels === 1
59
+ ? SINGLE_CHANNEL_PIPETTE_HEIGHT
60
+ : MULTI_CHANNEL_PIPETTE_HEIGHT
61
+ }
62
+ x={x - probeOffsetX}
63
+ y={y}
64
+ outerProps={{ style: { overflow: 'visible' } }}
65
+ innerDivProps={{
66
+ style: {
67
+ width: '100%',
68
+ height: '100%',
69
+ overflow: 'visible',
70
+ boxSizing: 'border-box',
71
+ borderRadius: BORDERS.borderRadius4,
72
+ boxShadow: `inset 0 0 0 1px ${C_MED_DARK_GRAY}`,
73
+ backgroundColor: `${C_MED_GRAY}80`,
74
+ },
75
+ }}
76
+ >
77
+ <svg overflow="visible">
78
+ {channels === 1 || usingMetalProbe ? (
79
+ <EmanatingNozzle
80
+ cx={cx}
81
+ cy={usingMetalProbe ? cy + probeOffsetY : cy}
82
+ />
83
+ ) : (
84
+ <EightEmanatingNozzles
85
+ cx={usingMetalProbe ? cx - probeOffsetX : cx}
86
+ initialCy={usingMetalProbe ? cy + probeOffsetY : cy}
87
+ />
88
+ )}
89
+ </svg>
90
+ </RobotCoordsForeignDiv>
91
+ )
92
+ }
@@ -0,0 +1,10 @@
1
+ // These constants are used only in pipette render in LPC. The values do not necessarily reflect physical pipette dimensions.
2
+ export const SINGLE_CHANNEL_PIPETTE_WIDTH = 18.7
3
+ export const SINGLE_CHANNEL_PIPETTE_HEIGHT = 30.5
4
+
5
+ export const MULTI_CHANNEL_PIPETTE_WIDTH = 18.7
6
+ export const MULTI_CHANNEL_PIPETTE_HEIGHT = 90.3
7
+ export const NINETY_SIX_CHANNEL_PIPETTE_WIDTH = 117.7
8
+
9
+ export const MULTI_CHANNEL_CENTER_Y_NOZZLE = 13.3
10
+ export const MULTI_CHANNEL_Y_OFFSET = -2.5
@@ -0,0 +1 @@
1
+ export * from './PipetteRender'
@@ -0,0 +1,68 @@
1
+ import type * as React from 'react'
2
+ import { css } from 'styled-components'
3
+
4
+ import { RobotCoordsForeignDiv } from '../Deck/RobotCoordsForeignDiv'
5
+ import {
6
+ DISPLAY_FLEX,
7
+ DIRECTION_COLUMN,
8
+ DIRECTION_ROW,
9
+ JUSTIFY_FLEX_END,
10
+ JUSTIFY_SPACE_BETWEEN,
11
+ ALIGN_FLEX_START,
12
+ } from '../../styles'
13
+ import { Box, Flex, Text } from '../../primitives'
14
+ import { TYPOGRAPHY, SPACING } from '../../ui-style-constants'
15
+ import { COLORS } from '../../helix-design-system'
16
+ import type { LabwareDefinition2 } from '@opentrons/shared-data'
17
+
18
+ const labwareDisplayNameStyle = css`
19
+ ${TYPOGRAPHY.labelSemiBold}
20
+ overflow: hidden;
21
+ white-space: initial;
22
+ text-overflow: ellipsis;
23
+ display: -webkit-box;
24
+ -webkit-line-clamp: 2;
25
+ -webkit-box-orient: vertical;
26
+ `
27
+ export function LabwareInfo(props: {
28
+ def: LabwareDefinition2
29
+ children: React.ReactNode
30
+ }): JSX.Element {
31
+ const width = props.def.dimensions.xDimension
32
+ const height = props.def.dimensions.yDimension
33
+ return (
34
+ <RobotCoordsForeignDiv
35
+ x={0}
36
+ y={0}
37
+ {...{ width, height }}
38
+ innerDivProps={{
39
+ display: DISPLAY_FLEX,
40
+ flexDirection: DIRECTION_COLUMN,
41
+ justifyContent: JUSTIFY_FLEX_END,
42
+ }}
43
+ >
44
+ <Box
45
+ backgroundColor="#000000B3"
46
+ borderRadius="0 0 0.4rem 0.4rem"
47
+ fontSize={TYPOGRAPHY.fontSizeCaption}
48
+ padding={SPACING.spacing4}
49
+ color={COLORS.white}
50
+ >
51
+ <Flex
52
+ flexDirection={DIRECTION_ROW}
53
+ justifyContent={JUSTIFY_SPACE_BETWEEN}
54
+ alignItems={ALIGN_FLEX_START}
55
+ gridGap={SPACING.spacing4}
56
+ >
57
+ <Text
58
+ as="h6"
59
+ lineHeight={TYPOGRAPHY.fontSizeCaption}
60
+ css={labwareDisplayNameStyle}
61
+ >
62
+ {props.children}
63
+ </Text>
64
+ </Flex>
65
+ </Box>
66
+ </RobotCoordsForeignDiv>
67
+ )
68
+ }
@@ -0,0 +1,25 @@
1
+ import type * as React from 'react'
2
+ import analysisFileFixture from './__fixtures__/analysis_QIAseqFX24xv4_8.json'
3
+
4
+ import { ProtocolDeck as ProtocolDeckComponent } from './'
5
+
6
+ import type { Meta, StoryObj } from '@storybook/react'
7
+ import type { ProtocolAnalysisOutput } from '@opentrons/shared-data'
8
+
9
+ const meta: Meta<React.ComponentProps<typeof ProtocolDeckComponent>> = {
10
+ component: ProtocolDeckComponent,
11
+ title: 'Library/Molecules/Simulation/ProtocolDeck',
12
+ } as Meta
13
+
14
+ export default meta
15
+ type Story = StoryObj<React.ComponentProps<typeof ProtocolDeckComponent>>
16
+
17
+ export const ProtocolDeck: Story = {
18
+ args: {
19
+ // @ts-expect-error typescript can't import JSON as const
20
+ protocolAnalysis: analysisFileFixture as ProtocolAnalysisOutput,
21
+ },
22
+ render: args => {
23
+ return <ProtocolDeckComponent {...args} />
24
+ },
25
+ }