@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,40 @@
1
+ import * as React from 'react'
2
+ import { PipetteSelect as PipetteSelectComponent } from './PipetteSelect'
3
+
4
+ import type { Story, Meta } from '@storybook/react'
5
+
6
+ export default {
7
+ title: 'Library/Organisms/Pipette Select',
8
+ } as Meta
9
+
10
+ const Template: Story<React.ComponentProps<typeof PipetteSelectComponent>> = ({
11
+ pipetteName,
12
+ ...args
13
+ }) => {
14
+ const [pipetteNameControlled, setPipetteNameControlled] = React.useState(
15
+ pipetteName
16
+ )
17
+ const handleChange = (pipName: string): unknown => {
18
+ setPipetteNameControlled(pipName)
19
+ }
20
+ return (
21
+ <PipetteSelectComponent
22
+ {...args}
23
+ pipetteName={pipetteNameControlled}
24
+ onPipetteChange={handleChange}
25
+ />
26
+ )
27
+ }
28
+ export const PipetteSelect = Template.bind({})
29
+ PipetteSelect.args = {
30
+ nameBlocklist: [
31
+ 'p20_multi_gen2',
32
+ 'p300_multi_gen2',
33
+ 'p20_single_flex',
34
+ 'p300_single_flex',
35
+ 'p1000_single_flex',
36
+ 'p1000_multi_flex',
37
+ 'p50_multi_flex',
38
+ ],
39
+ enableNoneOption: true,
40
+ }
@@ -0,0 +1,170 @@
1
+ import groupBy from 'lodash/groupBy'
2
+ import {
3
+ getAllPipetteNames,
4
+ getPipetteNameSpecs,
5
+ GEN1,
6
+ GEN2,
7
+ FLEX,
8
+ } from '@opentrons/shared-data'
9
+ import { Flex } from '../primitives'
10
+ import { Select, CONTEXT_VALUE } from '../forms'
11
+ import styles from './PipetteSelect.module.css'
12
+ import type { PipetteNameSpecs } from '@opentrons/shared-data'
13
+ import type { ActionMeta, SingleValue, MultiValue } from 'react-select'
14
+ import type { SelectOption } from '../forms'
15
+ export interface PipetteSelectProps {
16
+ /** currently selected value, optional in case selecting triggers immediate action */
17
+ pipetteName?: string | null
18
+ /** react-select change handler */
19
+ onPipetteChange: (
20
+ pipetteName: string | null,
21
+ e: ActionMeta<SelectOption>
22
+ ) => void
23
+ /** list of pipette names to omit */
24
+ nameBlocklist?: string[]
25
+ /** whether or not "None" shows up as the default option */
26
+ enableNoneOption?: boolean
27
+ /** input tabIndex */
28
+ tabIndex?: string | number
29
+ /** classes to apply to the top-level component */
30
+ className?: string
31
+ /** custom id to be applied. likely to be used as a data test id for e2e testing */
32
+ id?: string
33
+ disabled?: boolean
34
+ }
35
+
36
+ // TODO(mc, 2019-10-14): i18n
37
+ const NONE = 'None'
38
+ const OPTION_NONE = { value: '', label: NONE }
39
+
40
+ const PIPETTE_SORT = ['maxVolume', 'channels'] as const
41
+
42
+ // @ts-expect-error(mc, 2021-04-27): use TS type guard for filter
43
+ const allPipetteNameSpecs: PipetteNameSpecs[] = getAllPipetteNames(
44
+ ...PIPETTE_SORT
45
+ )
46
+ .map(getPipetteNameSpecs)
47
+ .filter(Boolean)
48
+
49
+ const specsByCategory = groupBy(allPipetteNameSpecs, 'displayCategory')
50
+
51
+ const specToOption = ({
52
+ name,
53
+ displayName,
54
+ }: PipetteNameSpecs): { value: string; label: string } => ({
55
+ value: name,
56
+ label: displayName,
57
+ })
58
+
59
+ export const PipetteSelect = (props: PipetteSelectProps): JSX.Element => {
60
+ const {
61
+ tabIndex,
62
+ className,
63
+ enableNoneOption,
64
+ id,
65
+ nameBlocklist = [],
66
+ disabled = false,
67
+ } = props
68
+ const allowlist = ({ value }: SelectOption): boolean => {
69
+ return !nameBlocklist.some(n => n === value)
70
+ }
71
+ const flexOptions = specsByCategory[FLEX].map(specToOption).filter(allowlist)
72
+ const gen2Options = specsByCategory[GEN2].map(specToOption).filter(allowlist)
73
+ const gen1Options = specsByCategory[GEN1].map(specToOption).filter(allowlist)
74
+ const groupedOptions = [
75
+ ...(enableNoneOption ? [OPTION_NONE] : []),
76
+ ...(flexOptions.length > 0 ? [{ options: flexOptions }] : []),
77
+ ...(gen2Options.length > 0 ? [{ options: gen2Options }] : []),
78
+ ...(gen1Options.length > 0 ? [{ options: gen1Options }] : []),
79
+ ]
80
+ const defaultValue = enableNoneOption ? OPTION_NONE : null
81
+ const value =
82
+ allPipetteNameSpecs
83
+ .filter(s => s.name === props.pipetteName)
84
+ .map(specToOption)[0] || defaultValue
85
+
86
+ return (
87
+ <Select
88
+ isSearchable={false}
89
+ menuPosition="fixed"
90
+ className={className}
91
+ options={groupedOptions}
92
+ value={value}
93
+ isDisabled={disabled}
94
+ defaultValue={defaultValue}
95
+ tabIndex={tabIndex as number}
96
+ id={id}
97
+ onChange={(
98
+ option: SingleValue<SelectOption> | MultiValue<SelectOption>,
99
+ e: ActionMeta<SelectOption>
100
+ ) => {
101
+ const value = (option as SelectOption).value
102
+ ? (option as SelectOption).value
103
+ : null
104
+ props.onPipetteChange(value, e)
105
+ }}
106
+ formatOptionLabel={(option, { context }) => {
107
+ const { value } = option
108
+ const label = option.label || value
109
+ const specs = allPipetteNameSpecs.find(s => s.name === value)
110
+
111
+ return context === CONTEXT_VALUE || value === '' || !specs ? (
112
+ label
113
+ ) : (
114
+ <PipetteNameItem {...specs} />
115
+ )
116
+ }}
117
+ />
118
+ )
119
+ }
120
+
121
+ const PipetteNameItem = (props: PipetteNameSpecs): JSX.Element => {
122
+ const { channels, name, displayCategory } = props
123
+ const volumeClassMaybeMatch = name && name.match(/p(\d+)/i)
124
+ const volumeClass = volumeClassMaybeMatch ? volumeClassMaybeMatch[1] : ''
125
+ let displayChannels = ''
126
+ if (channels === 1) {
127
+ displayChannels = 'Single-Channel'
128
+ } else if (channels === 8) {
129
+ displayChannels = '8-Channel'
130
+ } else if (channels === 96) {
131
+ displayChannels = '96-Channel'
132
+ }
133
+ return (
134
+ <Flex
135
+ data-test={dataIdFormat(
136
+ 'PipetteNameItem',
137
+ volumeClass,
138
+ channels,
139
+ displayCategory
140
+ )}
141
+ >
142
+ <div className={styles.pipette_volume_class}>{volumeClass}</div>
143
+ <div className={styles.pipette_channels}>{displayChannels}</div>
144
+ <div className={styles.pipette_category}>
145
+ {channels === 96 ? 'FLEX' : displayCategory}
146
+ </div>
147
+ </Flex>
148
+ )
149
+ }
150
+
151
+ const dataIdFormat = (
152
+ componentName: string,
153
+ volumeClass: string,
154
+ channels: number,
155
+ displayCategory: string
156
+ ): string => {
157
+ let dataIdFormatChannels
158
+ if (channels === 1) {
159
+ dataIdFormatChannels = 'SingleChannel'
160
+ } else if (channels === 8) {
161
+ dataIdFormatChannels = 'MultiChannel'
162
+ } else {
163
+ dataIdFormatChannels = '96-Channel'
164
+ }
165
+ const dataIdFormatVolumeClass = volumeClass.toLowerCase()
166
+ const dataIdFormatDisplayCategory =
167
+ displayCategory.charAt(0) + displayCategory.slice(1).toLowerCase()
168
+
169
+ return `${componentName}_${dataIdFormatVolumeClass}${dataIdFormatChannels}${dataIdFormatDisplayCategory}`
170
+ }
@@ -0,0 +1,4 @@
1
+ export * from './InstrumentDiagram'
2
+ export * from './InstrumentGroup'
3
+ export * from './InstrumentInfo'
4
+ export * from './PipetteSelect'
Binary file
Binary file
@@ -0,0 +1,57 @@
1
+ import * as React from 'react'
2
+
3
+ interface ClickOutsideChildParams {
4
+ ref: React.RefCallback<Element>
5
+ }
6
+ export interface ClickOutsideProps {
7
+ onClickOutside: ((e: MouseEvent) => void) | undefined | null
8
+ children: (params: ClickOutsideChildParams) => JSX.Element
9
+ }
10
+
11
+ // TODO: BC: 2019-05-10 this would be much cleaner as a custom hook
12
+ export class ClickOutside extends React.Component<ClickOutsideProps> {
13
+ // TODO(mc, 2019-04-19): switch to ref object
14
+ wrapperRef: Element | null
15
+
16
+ constructor(props: ClickOutsideProps) {
17
+ super(props)
18
+ this.wrapperRef = null
19
+ }
20
+
21
+ componentDidMount(): void {
22
+ document.addEventListener('mousedown', this.handleClickOutside)
23
+ }
24
+
25
+ componentWillUnmount(): void {
26
+ document.removeEventListener('mousedown', this.handleClickOutside)
27
+ }
28
+
29
+ setWrapperRef: (el: Element | null) => void = el => {
30
+ this.wrapperRef = el
31
+ }
32
+
33
+ handleClickOutside = (event: MouseEvent): void => {
34
+ const clickedElem = event.target
35
+
36
+ if (!(clickedElem instanceof Node)) {
37
+ // NOTE: this is some flow type checking funkiness
38
+ // TODO Ian 2018-05-24 use assert.
39
+ console.warn(
40
+ 'expected clicked element to be Node - something went wrong in ClickOutside'
41
+ )
42
+ return
43
+ }
44
+
45
+ if (
46
+ this.props.onClickOutside &&
47
+ this.wrapperRef &&
48
+ !this.wrapperRef.contains(clickedElem)
49
+ ) {
50
+ this.props.onClickOutside(event)
51
+ }
52
+ }
53
+
54
+ render(): JSX.Element {
55
+ return this.props.children({ ref: this.setWrapperRef })
56
+ }
57
+ }
@@ -0,0 +1,69 @@
1
+ import * as React from 'react'
2
+ export interface KeypressHandler {
3
+ key: string
4
+ shiftKey?: boolean | null | undefined
5
+ onPress: () => unknown
6
+ }
7
+
8
+ export interface HandleKeypressProps {
9
+ /** array of keypress handlers to attach to the window */
10
+ handlers: KeypressHandler[]
11
+ /** optionally call event.preventDefault if keypress is handled */
12
+ preventDefault?: boolean | null | undefined
13
+ /** wrapped children */
14
+ children?: React.ReactNode
15
+ }
16
+
17
+ const matchHandler = (e: KeyboardEvent) => (h: KeypressHandler) =>
18
+ h.key === e.key && (h.shiftKey == null || h.shiftKey === e.shiftKey)
19
+
20
+ /**
21
+ * Keypress handler wrapper component. Takes an array of keypress handlers
22
+ * to call when a given key is pressed on the keyboard. Handler is called on
23
+ * `keyup` event. `event.preventDefault` will be called if a key is handled
24
+ * and `props.preventDefault` is true.
25
+ */
26
+ export class HandleKeypress extends React.Component<HandleKeypressProps> {
27
+ handlePressIfKey = (event: KeyboardEvent): void => {
28
+ const pressHandlers = this.props.handlers.filter(matchHandler(event))
29
+
30
+ // Check if any element is currently focused
31
+ const focusedElement = document.activeElement as HTMLElement
32
+
33
+ if (pressHandlers.length > 0) {
34
+ if (
35
+ focusedElement &&
36
+ event.key === 'Enter' &&
37
+ focusedElement.matches(':focus-visible')
38
+ ) {
39
+ focusedElement.click()
40
+ } else if (!focusedElement || !focusedElement.matches(':focus-visible')) {
41
+ pressHandlers.forEach(h => h.onPress())
42
+ }
43
+ }
44
+ }
45
+
46
+ preventDefaultIfKey = (event: KeyboardEvent): void => {
47
+ if (!this.props.preventDefault) return
48
+
49
+ const pressHandled = this.props.handlers.some(matchHandler(event))
50
+
51
+ if (pressHandled) event.preventDefault()
52
+ }
53
+
54
+ componentDidMount(): void {
55
+ window.addEventListener('keyup', this.handlePressIfKey)
56
+ window.addEventListener('keyup', this.preventDefaultIfKey)
57
+ window.addEventListener('keydown', this.preventDefaultIfKey)
58
+ }
59
+
60
+ componentWillUnmount(): void {
61
+ window.removeEventListener('keyup', this.handlePressIfKey)
62
+ window.removeEventListener('keyup', this.preventDefaultIfKey)
63
+ window.removeEventListener('keydown', this.preventDefaultIfKey)
64
+ }
65
+
66
+ render(): JSX.Element {
67
+ return <>{this.props.children}</>
68
+ }
69
+ }
@@ -0,0 +1,4 @@
1
+ export * from './ClickOutside'
2
+ export * from './HandleKeypress'
3
+ export * from './useOnClickOutside'
4
+ export * from './useHover'
@@ -0,0 +1,84 @@
1
+ import { useState, useEffect, useCallback, useMemo, useRef } from 'react'
2
+
3
+ export interface UseHoverOptions {
4
+ enterDelay?: number
5
+ leaveDelay?: number
6
+ }
7
+
8
+ export interface HoverHandlers {
9
+ onPointerEnter: () => unknown
10
+ onPointerLeave: () => unknown
11
+ }
12
+
13
+ export type UseHoverResult = [boolean, HoverHandlers]
14
+
15
+ /**
16
+ * Hook to track hover state of an element
17
+ *
18
+ * @param {UseHoverOptions} [options={}] (add an `enterDelay` or `leaveDelay` to the hover state change)
19
+ * @returns {UseHoverResult}
20
+ * @example
21
+ * ```js
22
+ * import { useHover } from '@opentrons/components'
23
+ *
24
+ * export function HoverComponent() {
25
+ * const [hovered, hoverHandlers] = useHover({
26
+ * enterDelay: 300,
27
+ * leaveDelay: 100
28
+ * })
29
+ *
30
+ * return (
31
+ * <span {...hoverHandlers}>
32
+ * {hovered ? 'Hovered!' : 'Not hovered!'}
33
+ * </span>
34
+ * )
35
+ * }
36
+ * ```
37
+ */
38
+ export function useHover(options: UseHoverOptions = {}): UseHoverResult {
39
+ const { enterDelay, leaveDelay } = options
40
+ const [hovered, setHovered] = useState(false)
41
+ const timeoutRef = useRef<number>()
42
+
43
+ const handleHoverChange = useCallback(
44
+ (value: boolean, delay: number | undefined) => {
45
+ clearTimeout(timeoutRef.current)
46
+ if (delay) {
47
+ timeoutRef.current = setTimeout(
48
+ // TODO(mc, 2021-03-08): use window.setTimeout or a separate const
49
+ // for the handler to tell TS that we're using DOM setTimeout, not Node.js
50
+ // eslint-disable-next-line @typescript-eslint/no-implied-eval
51
+ (() => {
52
+ setHovered(value)
53
+ }) as TimerHandler,
54
+ delay
55
+ )
56
+ } else {
57
+ setHovered(value)
58
+ }
59
+ },
60
+ []
61
+ )
62
+
63
+ const handlers = useMemo(
64
+ () => ({
65
+ onPointerEnter: () => {
66
+ handleHoverChange(true, enterDelay)
67
+ },
68
+ onPointerLeave: () => {
69
+ handleHoverChange(false, leaveDelay)
70
+ },
71
+ }),
72
+ [handleHoverChange, enterDelay, leaveDelay]
73
+ )
74
+
75
+ // cleanup timeout on unmount
76
+ useEffect(
77
+ () => () => {
78
+ clearTimeout(timeoutRef.current)
79
+ },
80
+ []
81
+ )
82
+
83
+ return [hovered, handlers]
84
+ }
@@ -0,0 +1,42 @@
1
+ import { useEffect, useRef } from 'react'
2
+
3
+ import type { RefObject } from 'react'
4
+
5
+ export interface UseOnClickOutsideOptions {
6
+ onClickOutside?: (e: MouseEvent) => unknown
7
+ }
8
+
9
+ export const useOnClickOutside = <E extends Element>(
10
+ options: UseOnClickOutsideOptions
11
+ ): RefObject<E> => {
12
+ const { onClickOutside } = options
13
+ const node = useRef<E>(null)
14
+
15
+ useEffect(() => {
16
+ const handleClickOutside = (event: MouseEvent): void => {
17
+ const clickedElem = event.target
18
+
19
+ console.assert(
20
+ clickedElem instanceof Node,
21
+ 'expected clicked element to be Node - something went wrong in onClickOutside hook'
22
+ )
23
+
24
+ if (
25
+ onClickOutside != null &&
26
+ node != null &&
27
+ node.current != null &&
28
+ node.current.contains != null &&
29
+ !node.current.contains(clickedElem as Node)
30
+ ) {
31
+ onClickOutside(event)
32
+ }
33
+ }
34
+ document.addEventListener('mousedown', handleClickOutside)
35
+
36
+ return () => {
37
+ document.removeEventListener('mousedown', handleClickOutside)
38
+ }
39
+ }, [onClickOutside])
40
+
41
+ return node
42
+ }
@@ -0,0 +1,22 @@
1
+ import cx from 'classnames'
2
+ import styles from './LabwareNameOverlay.module.css'
3
+
4
+ export interface LabwareNameOverlayProps {
5
+ title: string
6
+ subtitle?: string | null | undefined
7
+ className?: string
8
+ }
9
+
10
+ /** @deprecated use LabwareDisplayName or custom RobotCoordsForeignDiv */
11
+ export function LabwareNameOverlay(
12
+ props: LabwareNameOverlayProps
13
+ ): JSX.Element {
14
+ const { title, subtitle, className } = props
15
+
16
+ return (
17
+ <div className={cx(styles.name_overlay, className)}>
18
+ <p className={styles.display_name}> {title} </p>
19
+ {subtitle && <p>{subtitle}</p>}
20
+ </div>
21
+ )
22
+ }
@@ -0,0 +1,145 @@
1
+ import cx from 'classnames'
2
+
3
+ import {
4
+ getModuleDisplayName,
5
+ MAGNETIC_MODULE_V1,
6
+ MAGNETIC_MODULE_V2,
7
+ TEMPERATURE_MODULE_V1,
8
+ TEMPERATURE_MODULE_V2,
9
+ THERMOCYCLER_MODULE_V1,
10
+ } from '@opentrons/shared-data'
11
+
12
+ import { Icon } from '../icons'
13
+ import { RobotCoordsForeignDiv } from '../hardware-sim/Deck'
14
+ import styles from './ModuleItem.module.css'
15
+
16
+ import type { IconName } from '../icons'
17
+ import type { ModuleModel, DeckSlot } from '@opentrons/shared-data'
18
+
19
+ const FLIPPED_SLOTS = ['3', '6', '9']
20
+ export interface ModuleProps {
21
+ /** module model */
22
+ model: ModuleModel
23
+ /** display mode: 'default', 'present', 'missing', or 'info' */
24
+ mode: 'default' | 'present' | 'missing' | 'info'
25
+ /** slot details of the location of this module */
26
+ slot: DeckSlot
27
+ /** USB port detail of the connected module */
28
+ usbInfoString?: string
29
+ }
30
+
31
+ /**
32
+ * Legacy App-specific Module Rendering. Removable after Protocol Upload Revamp release
33
+ *
34
+ * @deprecated Use {@link Module}
35
+ */
36
+ export function ModuleItem(props: ModuleProps): JSX.Element {
37
+ const { model, slot } = props
38
+ let x = 0
39
+ let y = 0
40
+ let { xDimension: width, yDimension: height } = slot.boundingBox
41
+ const shouldFlip = FLIPPED_SLOTS.includes(slot.id)
42
+
43
+ // TODO: BC 2019-7-23 get these from shared-data module defs, once available
44
+ switch (model) {
45
+ case MAGNETIC_MODULE_V1:
46
+ case MAGNETIC_MODULE_V2: {
47
+ width = 137
48
+ height = 91
49
+ x = -7
50
+ y = 4
51
+ break
52
+ }
53
+ case TEMPERATURE_MODULE_V1:
54
+ case TEMPERATURE_MODULE_V2: {
55
+ width = 196
56
+ height = 91
57
+ x = -66
58
+ y = 4
59
+ break
60
+ }
61
+ case THERMOCYCLER_MODULE_V1: {
62
+ // TODO: BC 2019-07-24 these are taken from snapshots of the cad file, they should
63
+ // be included in the module spec schema and added to the data
64
+ width = 172
65
+ height = 259.7
66
+ x = -22.125
67
+ }
68
+ }
69
+
70
+ return (
71
+ <RobotCoordsForeignDiv
72
+ width={width}
73
+ height={height}
74
+ x={x}
75
+ y={y - height}
76
+ transformWithSVG
77
+ extraTransform={`rotate(${shouldFlip ? 180 : 0}, ${
78
+ slot.boundingBox.xDimension / 2
79
+ }, ${slot.boundingBox.yDimension / -2})`}
80
+ innerDivProps={{
81
+ className: cx(styles.module, { [styles.flipped]: shouldFlip }),
82
+ }}
83
+ >
84
+ <ModuleItemContents {...props} shouldFlip={shouldFlip} />
85
+ </RobotCoordsForeignDiv>
86
+ )
87
+ }
88
+
89
+ interface ModuleItemContentsProps extends ModuleProps {
90
+ shouldFlip: boolean
91
+ }
92
+
93
+ function ModuleItemContents(props: ModuleItemContentsProps): JSX.Element {
94
+ const { mode, model, usbInfoString, shouldFlip } = props
95
+ const displayName = getModuleDisplayName(model)
96
+
97
+ const iconClassName = cx(styles.module_review_icon, {
98
+ [styles.module_review_icon_missing]: mode === 'missing',
99
+ [styles.module_review_icon_present]: mode === 'present',
100
+ })
101
+
102
+ const iconNameByMode: Record<string, IconName> = {
103
+ missing: 'alert-circle',
104
+ present: 'check-circle',
105
+ info: 'usb',
106
+ default: 'usb',
107
+ }
108
+
109
+ return (
110
+ <>
111
+ <div
112
+ className={
113
+ shouldFlip ? styles.flipped_module_wrapper : styles.module_wrapper
114
+ }
115
+ >
116
+ {mode !== 'missing' && usbInfoString && (
117
+ <p
118
+ key="usbPortInfo"
119
+ className={
120
+ usbInfoString.includes('N/A')
121
+ ? styles.module_port_text_na
122
+ : styles.module_port_text
123
+ }
124
+ >
125
+ {usbInfoString}
126
+ </p>
127
+ )}
128
+ <p key="displayName" className={styles.module_review_text}>
129
+ {displayName}
130
+ </p>
131
+ <div className={styles.module_connect_info_wrapper}>
132
+ <Icon
133
+ key="icon"
134
+ className={iconClassName}
135
+ x="8"
136
+ y="0"
137
+ svgWidth="12"
138
+ name={iconNameByMode[mode] || 'usb'}
139
+ />
140
+ <p>{mode === 'missing' ? 'Not connected' : 'Connected'}</p>
141
+ </div>
142
+ </div>
143
+ </>
144
+ )
145
+ }
@@ -0,0 +1,2 @@
1
+ export * from './LabwareNameOverlay'
2
+ export * from './ModuleItem' // legacy App module rendering