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

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,6 @@
1
+ // icons icons icons!
2
+
3
+ export * from './Icon'
4
+ export * from './NotificationIcon'
5
+ export * from './ModuleIcon'
6
+ export * from './icon-data'
@@ -0,0 +1 @@
1
+ export * from './labware'
@@ -0,0 +1 @@
1
+ export * from './measurement-guide'
@@ -0,0 +1,272 @@
1
+ export interface DiagramProps {
2
+ guideType?: string
3
+ category?: string
4
+ insertCategory?: string
5
+ shape?: string
6
+ wellBottomShape?: string
7
+ guideVisible?: boolean
8
+ irregular?: boolean
9
+ isMultiRow?: boolean
10
+ }
11
+
12
+ type Diagrams = Record<string, string[]>
13
+
14
+ const FOOTPRINT_IMAGE_RELATIVE_PATH = './images/dimensions/footprint@3x.png'
15
+ const DIMENSIONS_HEIGHT_PLATE_IMAGE_RELATIVE_PATH =
16
+ './images/dimensions/height-plate-and-reservoir@3x.png'
17
+ const DIMENSIONS_HEIGHT_TIP_RACK_IMAGE_RELATIVE_PATH =
18
+ './images/dimensions/height-tip-rack@3x.png'
19
+
20
+ const DIMENSIONS_HEIGHT_TUBE_RACK_IMAGE_RELATIVE_PATH =
21
+ './images/dimensions/height-tube-rack@3x.png'
22
+
23
+ const DIMENSIONS_HEIGHT_TUBE_RACK_IMAGE_IRREGULAR_RELATIVE_PATH =
24
+ './images/dimensions/height-tube-rack-irregular@3x.png'
25
+
26
+ const HEIGHT_ALUM_BLOCK_TUBES_IMAGE_RELATIVE_PATH =
27
+ './images/dimensions/height-alum-block-tubes@3x.png'
28
+
29
+ const HEIGHT_ALUM_BLOCK_PLATE_IMAGE_RELATIVE_PATH =
30
+ './images/dimensions/height-alum-block-plate@3x.png'
31
+
32
+ const OFFSET_RESEVOIR_IMAGE_RELATIVE_PATH =
33
+ './images/offset/offset-reservoir@3x.png'
34
+
35
+ const SPACING_RESEVOIR_IMAGE_RELATIVE_PATH =
36
+ './images/spacing/spacing-reservoir@3x.png'
37
+
38
+ const SPACING_RESEVOIR_MULTI_ROW_IMAGE_RELATIVE_PATH =
39
+ './images/spacing/spacing-reservoir-multi-row@3x.png'
40
+
41
+ const OFFSET_WELL_CIRCULAR_IMAGE_RELATIVE_PATH =
42
+ './images/offset/offset-well-circular@3x.png'
43
+
44
+ const SPACING_WELL_CIRCULAR_IMAGE_RELATIVE_PATH =
45
+ './images/spacing/spacing-well-circular@3x.png'
46
+
47
+ const OFFSET_WELL_RECTANGULAR_IMAGE_RELATIVE_PATH =
48
+ './images/offset/offset-well-rectangular@3x.png'
49
+
50
+ const SPACING_WELL_RECTANGULAR_IMAGE_RELATIVE_PATH =
51
+ './images/spacing/spacing-well-rectangular@3x.png'
52
+
53
+ const DEPTH_LENGTH_TIP_RACK_IMAGE_RELATIVE_PATH =
54
+ './images/depth/length-tip-rack@3x.png'
55
+
56
+ const SHAPE_CIRCULAR_IMAGE_RELATIVE_PATH =
57
+ './images/shape/shape-circular@3x.png'
58
+
59
+ const DEPTH_PLATE_FLAT_IMAGE_RELATIVE_PATH =
60
+ './images/depth/depth-plate-flat@3x.png'
61
+
62
+ const SHAPE_RECTANGULAR_IMAGE_RELATIVE_PATH =
63
+ './images/shape/shape-rectangular@3x.png'
64
+
65
+ const DEPTH_PLATE_ROUND_IMAGE_RELATIVE_PATH =
66
+ './images/depth/depth-plate-round@3x.png'
67
+
68
+ const DEPTH_PLATE_V_SHAPE_IMAGE_RELATIVE_PATH =
69
+ './images/depth/depth-plate-v@3x.png'
70
+
71
+ const DEPTH_RESEVOIR_AND_TUBES_FLAT_IMAGE_RELATIVE_PATH =
72
+ './images/depth/depth-reservoir-and-tubes-flat@3x.png'
73
+
74
+ const DEPTH_RESEVOIR_AND_TUBES_ROUND_IMAGE_RELATIVE_PATH =
75
+ './images/depth/depth-reservoir-and-tubes-round@3x.png'
76
+
77
+ const DEPTH_RESEVOIR_AND_TUBES_V_SHAPE_IMAGE_RELATIVE_PATH =
78
+ './images/depth/depth-reservoir-and-tubes-v@3x.png'
79
+
80
+ const FOOTPRINT_DIAGRAMS: Diagrams = {
81
+ wellPlate: [
82
+ new URL(FOOTPRINT_IMAGE_RELATIVE_PATH, import.meta.url).href,
83
+ new URL(DIMENSIONS_HEIGHT_PLATE_IMAGE_RELATIVE_PATH, import.meta.url).href,
84
+ ],
85
+ tipRack: [
86
+ new URL(FOOTPRINT_IMAGE_RELATIVE_PATH, import.meta.url).href,
87
+ new URL(DIMENSIONS_HEIGHT_TIP_RACK_IMAGE_RELATIVE_PATH, import.meta.url)
88
+ .href,
89
+ ],
90
+ tubeRack: [
91
+ new URL(FOOTPRINT_IMAGE_RELATIVE_PATH, import.meta.url).href,
92
+ new URL(DIMENSIONS_HEIGHT_TUBE_RACK_IMAGE_RELATIVE_PATH, import.meta.url)
93
+ .href,
94
+ ],
95
+ reservoir: [
96
+ new URL(FOOTPRINT_IMAGE_RELATIVE_PATH, import.meta.url).href,
97
+ new URL(DIMENSIONS_HEIGHT_PLATE_IMAGE_RELATIVE_PATH, import.meta.url).href,
98
+ ],
99
+ irregular: [
100
+ new URL(FOOTPRINT_IMAGE_RELATIVE_PATH, import.meta.url).href,
101
+ new URL(
102
+ DIMENSIONS_HEIGHT_TUBE_RACK_IMAGE_IRREGULAR_RELATIVE_PATH,
103
+ import.meta.url
104
+ ).href,
105
+ ],
106
+ adapter: [
107
+ new URL(FOOTPRINT_IMAGE_RELATIVE_PATH, import.meta.url).href,
108
+ new URL(DIMENSIONS_HEIGHT_PLATE_IMAGE_RELATIVE_PATH, import.meta.url).href,
109
+ ],
110
+ lid: [
111
+ new URL(FOOTPRINT_IMAGE_RELATIVE_PATH, import.meta.url).href,
112
+ new URL(DIMENSIONS_HEIGHT_PLATE_IMAGE_RELATIVE_PATH, import.meta.url).href,
113
+ ],
114
+ }
115
+
116
+ const ALUM_BLOCK_FOOTPRINTS: Diagrams = {
117
+ tubeRack: [
118
+ new URL(FOOTPRINT_IMAGE_RELATIVE_PATH, import.meta.url).href,
119
+ new URL(HEIGHT_ALUM_BLOCK_TUBES_IMAGE_RELATIVE_PATH, import.meta.url).href,
120
+ ],
121
+ wellPlate: [
122
+ new URL(FOOTPRINT_IMAGE_RELATIVE_PATH, import.meta.url).href,
123
+ new URL(HEIGHT_ALUM_BLOCK_PLATE_IMAGE_RELATIVE_PATH, import.meta.url).href,
124
+ ],
125
+ }
126
+
127
+ const RESERVOIR_SPACING_DIAGRAMS: Diagrams = {
128
+ singleRow: [
129
+ new URL(OFFSET_RESEVOIR_IMAGE_RELATIVE_PATH, import.meta.url).href,
130
+ new URL(SPACING_RESEVOIR_IMAGE_RELATIVE_PATH, import.meta.url).href,
131
+ ],
132
+ multiRow: [
133
+ new URL(OFFSET_RESEVOIR_IMAGE_RELATIVE_PATH, import.meta.url).href,
134
+ new URL(SPACING_RESEVOIR_MULTI_ROW_IMAGE_RELATIVE_PATH, import.meta.url)
135
+ .href,
136
+ ],
137
+ }
138
+
139
+ const SPACING_DIAGRAMS: Diagrams = {
140
+ circular: [
141
+ new URL(OFFSET_WELL_CIRCULAR_IMAGE_RELATIVE_PATH, import.meta.url).href,
142
+ new URL(SPACING_WELL_CIRCULAR_IMAGE_RELATIVE_PATH, import.meta.url).href,
143
+ ],
144
+ rectangular: [
145
+ new URL(OFFSET_WELL_RECTANGULAR_IMAGE_RELATIVE_PATH, import.meta.url).href,
146
+ new URL(SPACING_WELL_RECTANGULAR_IMAGE_RELATIVE_PATH, import.meta.url).href,
147
+ ],
148
+ }
149
+
150
+ const TIPRACK_MEASUREMENT_DIAGRAMS: string[] = [
151
+ new URL(DEPTH_LENGTH_TIP_RACK_IMAGE_RELATIVE_PATH, import.meta.url).href,
152
+ new URL(SHAPE_CIRCULAR_IMAGE_RELATIVE_PATH, import.meta.url).href,
153
+ ]
154
+
155
+ type NestedDiagrams = Record<string, Record<string, string[]>>
156
+
157
+ const PLATE_MEASUREMENT_DIAGRAMS: NestedDiagrams = {
158
+ flat: {
159
+ circular: [
160
+ new URL(DEPTH_PLATE_FLAT_IMAGE_RELATIVE_PATH, import.meta.url).href,
161
+ new URL(SHAPE_CIRCULAR_IMAGE_RELATIVE_PATH, import.meta.url).href,
162
+ ],
163
+ rectangular: [
164
+ new URL(DEPTH_PLATE_FLAT_IMAGE_RELATIVE_PATH, import.meta.url).href,
165
+ new URL(SHAPE_RECTANGULAR_IMAGE_RELATIVE_PATH, import.meta.url).href,
166
+ ],
167
+ },
168
+ u: {
169
+ circular: [
170
+ new URL(DEPTH_PLATE_ROUND_IMAGE_RELATIVE_PATH, import.meta.url).href,
171
+ new URL(SHAPE_CIRCULAR_IMAGE_RELATIVE_PATH, import.meta.url).href,
172
+ ],
173
+ rectangular: [
174
+ new URL(DEPTH_PLATE_ROUND_IMAGE_RELATIVE_PATH, import.meta.url).href,
175
+ new URL(SHAPE_RECTANGULAR_IMAGE_RELATIVE_PATH, import.meta.url).href,
176
+ ],
177
+ },
178
+ v: {
179
+ circular: [
180
+ new URL(DEPTH_PLATE_V_SHAPE_IMAGE_RELATIVE_PATH, import.meta.url).href,
181
+ new URL(SHAPE_CIRCULAR_IMAGE_RELATIVE_PATH, import.meta.url).href,
182
+ ],
183
+ rectangular: [
184
+ new URL(DEPTH_PLATE_V_SHAPE_IMAGE_RELATIVE_PATH, import.meta.url).href,
185
+ new URL(SHAPE_RECTANGULAR_IMAGE_RELATIVE_PATH, import.meta.url).href,
186
+ ],
187
+ },
188
+ }
189
+ const MEASUREMENT_DIAGRAMS: NestedDiagrams = {
190
+ flat: {
191
+ circular: [
192
+ new URL(
193
+ DEPTH_RESEVOIR_AND_TUBES_FLAT_IMAGE_RELATIVE_PATH,
194
+ import.meta.url
195
+ ).href,
196
+ new URL(SHAPE_CIRCULAR_IMAGE_RELATIVE_PATH, import.meta.url).href,
197
+ ],
198
+ rectangular: [
199
+ new URL(
200
+ DEPTH_RESEVOIR_AND_TUBES_FLAT_IMAGE_RELATIVE_PATH,
201
+ import.meta.url
202
+ ).href,
203
+ new URL(SHAPE_RECTANGULAR_IMAGE_RELATIVE_PATH, import.meta.url).href,
204
+ ],
205
+ },
206
+ u: {
207
+ circular: [
208
+ new URL(
209
+ DEPTH_RESEVOIR_AND_TUBES_ROUND_IMAGE_RELATIVE_PATH,
210
+ import.meta.url
211
+ ).href,
212
+ new URL(SHAPE_CIRCULAR_IMAGE_RELATIVE_PATH, import.meta.url).href,
213
+ ],
214
+ rectangular: [
215
+ new URL(
216
+ DEPTH_RESEVOIR_AND_TUBES_ROUND_IMAGE_RELATIVE_PATH,
217
+ import.meta.url
218
+ ).href,
219
+ new URL(SHAPE_RECTANGULAR_IMAGE_RELATIVE_PATH, import.meta.url).href,
220
+ ],
221
+ },
222
+ v: {
223
+ circular: [
224
+ new URL(
225
+ DEPTH_RESEVOIR_AND_TUBES_V_SHAPE_IMAGE_RELATIVE_PATH,
226
+ import.meta.url
227
+ ).href,
228
+ new URL(SHAPE_CIRCULAR_IMAGE_RELATIVE_PATH, import.meta.url).href,
229
+ ],
230
+ rectangular: [
231
+ new URL(
232
+ DEPTH_RESEVOIR_AND_TUBES_V_SHAPE_IMAGE_RELATIVE_PATH,
233
+ import.meta.url
234
+ ).href,
235
+ new URL(SHAPE_RECTANGULAR_IMAGE_RELATIVE_PATH, import.meta.url).href,
236
+ ],
237
+ },
238
+ }
239
+
240
+ export function getFootprintDiagram(props: DiagramProps): string[] {
241
+ const { category, insertCategory, irregular } = props
242
+ if (category === 'aluminumBlock') {
243
+ return insertCategory ? ALUM_BLOCK_FOOTPRINTS[insertCategory] : []
244
+ } else if (category === 'tubeRack' && irregular) {
245
+ return FOOTPRINT_DIAGRAMS.irregular
246
+ }
247
+ return category ? FOOTPRINT_DIAGRAMS[category] : []
248
+ }
249
+
250
+ export function getSpacingDiagram(props: DiagramProps): string[] {
251
+ const { category, isMultiRow, shape } = props
252
+ if (category === 'reservoir') {
253
+ return isMultiRow
254
+ ? RESERVOIR_SPACING_DIAGRAMS.multiRow
255
+ : RESERVOIR_SPACING_DIAGRAMS.singleRow
256
+ }
257
+
258
+ return shape ? SPACING_DIAGRAMS[shape] : []
259
+ }
260
+
261
+ export function getMeasurementDiagram(props: DiagramProps): string[] {
262
+ const { category, wellBottomShape, shape } = props
263
+ if (category === 'tipRack') return TIPRACK_MEASUREMENT_DIAGRAMS
264
+ else if (category === 'wellPlate') {
265
+ return wellBottomShape && shape
266
+ ? PLATE_MEASUREMENT_DIAGRAMS[wellBottomShape][shape]
267
+ : []
268
+ }
269
+ return wellBottomShape && shape
270
+ ? MEASUREMENT_DIAGRAMS[wellBottomShape][shape]
271
+ : []
272
+ }
package/src/index.ts ADDED
@@ -0,0 +1,2 @@
1
+ export { ProtocolDeck } from './hardware-sim/ProtocolDeck'
2
+ export { LabwareRender } from './hardware-sim/Labware'
@@ -0,0 +1,42 @@
1
+ import type * as React from 'react'
2
+ import keyBy from 'lodash/keyBy'
3
+ import { getAllPipetteNames, getPipetteNameSpecs } from '@opentrons/shared-data'
4
+
5
+ import { InstrumentDiagram as InstrumentDiagramComponent } from './InstrumentDiagram'
6
+
7
+ import type { Story, Meta } from '@storybook/react'
8
+
9
+ const allPipetteSpecsByDisplayNames = keyBy(
10
+ getAllPipetteNames().map(getPipetteNameSpecs),
11
+ 'displayName'
12
+ )
13
+
14
+ export default {
15
+ title: 'Library/Organisms/Instrument Diagram',
16
+ argTypes: {
17
+ mount: {
18
+ control: {
19
+ type: 'select',
20
+ options: ['left', 'right'],
21
+ },
22
+ defaultValue: 'left',
23
+ },
24
+ pipetteSpecs: {
25
+ control: {
26
+ type: 'select',
27
+ options: Object.keys(allPipetteSpecsByDisplayNames),
28
+ },
29
+ defaultValue: Object.keys(allPipetteSpecsByDisplayNames)[0],
30
+ },
31
+ },
32
+ } as Meta
33
+
34
+ const Template: Story<
35
+ React.ComponentProps<typeof InstrumentDiagramComponent>
36
+ > = ({ pipetteSpecs, ...args }) => (
37
+ <InstrumentDiagramComponent
38
+ {...args}
39
+ pipetteSpecs={allPipetteSpecsByDisplayNames[pipetteSpecs]}
40
+ />
41
+ )
42
+ export const InstrumentDiagram = Template.bind({})
@@ -0,0 +1,58 @@
1
+ import { Flex } from '../primitives'
2
+ import { ALIGN_CENTER, JUSTIFY_CENTER } from '../styles'
3
+ import singleSrc from './single_channel_GEN1_800px.png'
4
+ import multiSrc from './multi-channel_GEN1_800px.png'
5
+ import singleGEN2Src from './single-channel_GEN2_800px.png'
6
+ import multiGEN2Src from './multi-channel_GEN2_800px.png'
7
+ import singleFlexSrc from './single-channel-flex.png'
8
+ import eightChannelFlexSrc from './eight-channel-flex.png'
9
+ import ninetySixSrc from './ninety-six-channel-gen1.png'
10
+
11
+ import type { FlattenSimpleInterpolation } from 'styled-components'
12
+ import type { PipetteV2Specs } from '@opentrons/shared-data'
13
+ import type { Mount } from '../robot-types'
14
+ import type { StyleProps } from '..'
15
+
16
+ export interface InstrumentDiagramProps extends StyleProps {
17
+ mount: Mount
18
+ pipetteSpecs?: Pick<PipetteV2Specs, 'displayCategory' | 'channels'> | null
19
+ className?: string
20
+ imageStyle?: FlattenSimpleInterpolation
21
+ }
22
+
23
+ export function InstrumentDiagram(props: InstrumentDiagramProps): JSX.Element {
24
+ const { mount, pipetteSpecs, className, imageStyle, ...styleProps } = props
25
+ const { displayCategory, channels } = pipetteSpecs || {}
26
+
27
+ let imgSrc
28
+ switch (displayCategory) {
29
+ case 'FLEX': {
30
+ imgSrc = channels === 1 ? singleFlexSrc : eightChannelFlexSrc
31
+ break
32
+ }
33
+ case 'GEN2': {
34
+ imgSrc = channels === 1 ? singleGEN2Src : multiGEN2Src
35
+ break
36
+ }
37
+ case 'GEN1':
38
+ default: {
39
+ imgSrc = channels === 1 ? singleSrc : multiSrc
40
+ }
41
+ }
42
+ return (
43
+ <Flex
44
+ className={className}
45
+ transform={mount === 'right' ? 'scaleX(-1)' : ''}
46
+ filter={mount === 'right' ? 'FlipH' : ''}
47
+ {...styleProps}
48
+ alignItems={ALIGN_CENTER}
49
+ justifyContent={JUSTIFY_CENTER}
50
+ >
51
+ <img
52
+ src={channels === 96 ? ninetySixSrc : imgSrc}
53
+ css={imageStyle}
54
+ height="100%"
55
+ />
56
+ </Flex>
57
+ )
58
+ }
@@ -0,0 +1,88 @@
1
+ import type * as React from 'react'
2
+ import reduce from 'lodash/reduce'
3
+ import keyBy from 'lodash/keyBy'
4
+ import { getAllPipetteNames, getPipetteNameSpecs } from '@opentrons/shared-data'
5
+
6
+ import { InstrumentGroup as InstrumentGroupComponent } from './InstrumentGroup'
7
+
8
+ import type { Story, Meta } from '@storybook/react'
9
+
10
+ const allPipetteSpecsByDisplayNames = keyBy(
11
+ getAllPipetteNames().map(getPipetteNameSpecs),
12
+ 'displayName'
13
+ )
14
+ const leftPipettesByName = reduce(
15
+ allPipetteSpecsByDisplayNames,
16
+ (acc, pipetteSpecs, displayName) => {
17
+ return {
18
+ ...acc,
19
+ [displayName]: {
20
+ mount: 'left',
21
+ description: displayName,
22
+ pipetteSpecs,
23
+ isDisabled: false,
24
+ },
25
+ }
26
+ },
27
+ {}
28
+ )
29
+ const rightPipettesByName = reduce(
30
+ allPipetteSpecsByDisplayNames,
31
+ (acc, pipetteSpecs, displayName) => {
32
+ return {
33
+ ...acc,
34
+ [displayName]: {
35
+ mount: 'right',
36
+ description: displayName,
37
+ pipetteSpecs,
38
+ isDisabled: false,
39
+ },
40
+ }
41
+ },
42
+ {}
43
+ )
44
+
45
+ export default {
46
+ title: 'Library/Organisms/Instrument Group',
47
+ argTypes: {
48
+ left: {
49
+ control: {
50
+ type: 'select',
51
+ options: Object.keys(leftPipettesByName),
52
+ },
53
+ defaultValue: Object.keys(leftPipettesByName)[0],
54
+ },
55
+ right: {
56
+ control: {
57
+ type: 'select',
58
+ options: Object.keys(rightPipettesByName),
59
+ },
60
+ defaultValue: Object.keys(rightPipettesByName)[0],
61
+ },
62
+ },
63
+ } as Meta
64
+
65
+ const Template: Story<
66
+ React.ComponentProps<typeof InstrumentGroupComponent>
67
+ > = ({ left, right, ...args }) => (
68
+ <InstrumentGroupComponent
69
+ {...args}
70
+ left={leftPipettesByName[left]}
71
+ right={rightPipettesByName[right]}
72
+ />
73
+ )
74
+ export const InstrumentGroup = Template.bind({})
75
+ InstrumentGroup.args = {
76
+ left: {
77
+ mount: 'left',
78
+ description: 'p300 8-Channel',
79
+ pipetteSpecs: { channels: 8, displayCategory: 'GEN1' },
80
+ isDisabled: false,
81
+ },
82
+ right: {
83
+ mount: 'right',
84
+ description: 'p10 Single',
85
+ pipetteSpecs: { channels: 1, displayCategory: 'GEN2' },
86
+ isDisabled: true,
87
+ },
88
+ }
@@ -0,0 +1,35 @@
1
+ import { InstrumentInfo } from './InstrumentInfo'
2
+ import styles from './instrument.module.css'
3
+
4
+ import type { InstrumentInfoProps } from './InstrumentInfo'
5
+
6
+ export interface InstrumentGroupProps {
7
+ showMountLabel?: boolean | null | undefined
8
+ left?: InstrumentInfoProps | null | undefined
9
+ right?: InstrumentInfoProps | null | undefined
10
+ }
11
+
12
+ const EMPTY_INSTRUMENT_PROPS = {
13
+ description: 'None',
14
+ tiprackModel: 'N/A',
15
+ isDisabled: false,
16
+ }
17
+
18
+ /**
19
+ * Renders a left and right pipette diagram & info.
20
+ * Takes child `InstrumentInfo` props in `right` and `left` props.
21
+ */
22
+ export function InstrumentGroup(props: InstrumentGroupProps): JSX.Element {
23
+ const { left, right, showMountLabel } = props
24
+
25
+ const leftProps = left || { ...EMPTY_INSTRUMENT_PROPS, mount: 'left' }
26
+ const rightProps = right || { ...EMPTY_INSTRUMENT_PROPS, mount: 'right' }
27
+ return (
28
+ <section className={styles.pipette_group}>
29
+ <InstrumentInfo {...leftProps} showMountLabel={showMountLabel} />
30
+ {leftProps.pipetteSpecs?.channels === 96 ? null : (
31
+ <InstrumentInfo {...rightProps} showMountLabel={showMountLabel} />
32
+ )}
33
+ </section>
34
+ )
35
+ }
@@ -0,0 +1,107 @@
1
+ import type * as React from 'react'
2
+
3
+ import { LEFT, RIGHT } from '@opentrons/shared-data'
4
+ import { Flex } from '../primitives'
5
+ import { SPACING, TYPOGRAPHY } from '../ui-style-constants'
6
+ import { LegacyStyledText } from '../atoms'
7
+ import { DIRECTION_COLUMN, JUSTIFY_CENTER } from '../styles'
8
+ import { InstrumentDiagram } from './InstrumentDiagram'
9
+
10
+ import type { Mount } from '../robot-types'
11
+ import type { InstrumentDiagramProps } from './InstrumentDiagram'
12
+
13
+ import styles from './instrument.module.css'
14
+
15
+ export interface InstrumentInfoProps {
16
+ /** 'left' or 'right' */
17
+ mount: Mount
18
+ /** human-readable description, eg 'p300 Single-channel' */
19
+ description: string
20
+ /** specs of mounted pipette */
21
+ pipetteSpecs?: InstrumentDiagramProps['pipetteSpecs'] | null
22
+ /** paired tiprack models */
23
+ tiprackModels?: string[]
24
+ /** children to display under the info */
25
+ children?: React.ReactNode
26
+ /** if true, show labels 'LEFT PIPETTE' / 'RIGHT PIPETTE' */
27
+ showMountLabel?: boolean | null
28
+ }
29
+
30
+ const MAX_WIDTH = '14rem'
31
+
32
+ export function InstrumentInfo(props: InstrumentInfoProps): JSX.Element {
33
+ const {
34
+ mount,
35
+ showMountLabel,
36
+ description,
37
+ tiprackModels,
38
+ pipetteSpecs,
39
+ children,
40
+ } = props
41
+
42
+ const has96Channel = pipetteSpecs?.channels === 96
43
+ return (
44
+ <Flex justifyContent={JUSTIFY_CENTER} gridGap={SPACING.spacing16}>
45
+ {mount === RIGHT && pipetteSpecs ? (
46
+ <InstrumentDiagram
47
+ pipetteSpecs={pipetteSpecs}
48
+ className={styles.pipette_icon}
49
+ mount={mount}
50
+ />
51
+ ) : null}
52
+ {/* NOTE: the color is our legacy c-font-dark, which matches the other colors in this component **/}
53
+ <Flex
54
+ flexDirection={DIRECTION_COLUMN}
55
+ color="#4a4a4a"
56
+ gridGap={SPACING.spacing8}
57
+ >
58
+ <Flex flexDirection={DIRECTION_COLUMN} gridGap={SPACING.spacing4}>
59
+ <LegacyStyledText
60
+ as="h3"
61
+ fontWeight={TYPOGRAPHY.fontWeightSemiBold}
62
+ textTransform={TYPOGRAPHY.textTransformCapitalize}
63
+ >
64
+ {showMountLabel && !has96Channel ? `${mount} pipette` : 'pipette'}
65
+ </LegacyStyledText>
66
+ <LegacyStyledText as="p" width="max-content" maxWidth={MAX_WIDTH}>
67
+ {description}
68
+ </LegacyStyledText>
69
+ </Flex>
70
+
71
+ <Flex flexDirection={DIRECTION_COLUMN} gridGap={SPACING.spacing4}>
72
+ <LegacyStyledText as="h3" fontWeight={TYPOGRAPHY.fontWeightSemiBold}>
73
+ {'Tip rack'}
74
+ </LegacyStyledText>
75
+ <ul>
76
+ {tiprackModels != null && tiprackModels.length > 0 ? (
77
+ tiprackModels.map((model, index) => (
78
+ <li key={`${model}_${index}`}>
79
+ <LegacyStyledText
80
+ as="p"
81
+ width="max-content"
82
+ maxWidth={MAX_WIDTH}
83
+ >
84
+ {model}
85
+ </LegacyStyledText>
86
+ </li>
87
+ ))
88
+ ) : (
89
+ <LegacyStyledText as="p" width="max-content" maxWidth={MAX_WIDTH}>
90
+ {'None'}
91
+ </LegacyStyledText>
92
+ )}
93
+ </ul>
94
+ </Flex>
95
+ </Flex>
96
+
97
+ {children}
98
+ {mount === LEFT && pipetteSpecs ? (
99
+ <InstrumentDiagram
100
+ pipetteSpecs={pipetteSpecs}
101
+ className={styles.pipette_icon}
102
+ mount={mount}
103
+ />
104
+ ) : null}
105
+ </Flex>
106
+ )
107
+ }