@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,90 @@
1
+ import { useRef } from 'react'
2
+ import { OT2_ROBOT_TYPE } from '@opentrons/shared-data'
3
+ import { Svg } from '../../primitives'
4
+ import { DeckFromLayers } from './DeckFromLayers'
5
+
6
+ import type { ReactNode } from 'react'
7
+ import type { StyleProps } from '../../primitives'
8
+ import type { DeckDefinition, DeckSlot } from '@opentrons/shared-data'
9
+
10
+ export interface RobotWorkSpaceRenderProps {
11
+ deckSlotsById: { [slotId: string]: DeckSlot }
12
+ getRobotCoordsFromDOMCoords: (
13
+ domX: number,
14
+ domY: number
15
+ ) => { x: number; y: number }
16
+ }
17
+
18
+ export interface RobotWorkSpaceProps extends StyleProps {
19
+ deckDef?: DeckDefinition
20
+ viewBox?: string | null
21
+ children?: (props: RobotWorkSpaceRenderProps) => ReactNode
22
+ deckLayerBlocklist?: string[]
23
+ // optional boolean to show the OT-2 deck from deck defintion layers
24
+ showDeckLayers?: boolean
25
+ id?: string
26
+ }
27
+
28
+ type GetRobotCoordsFromDOMCoords = RobotWorkSpaceRenderProps['getRobotCoordsFromDOMCoords']
29
+
30
+ export function RobotWorkSpace(props: RobotWorkSpaceProps): JSX.Element | null {
31
+ const {
32
+ children,
33
+ deckDef,
34
+ deckLayerBlocklist = [],
35
+ showDeckLayers = false,
36
+ viewBox,
37
+ id,
38
+ ...styleProps
39
+ } = props
40
+ const wrapperRef = useRef<SVGSVGElement>(null)
41
+
42
+ // NOTE: getScreenCTM in Chrome a DOMMatrix type,
43
+ // in Firefox the same fn returns a deprecated SVGMatrix.
44
+ // Until Firefox fixes this and conforms to SVG2 draft,
45
+ // it will suffer from inverted y behavior (ignores css transform)
46
+ const getRobotCoordsFromDOMCoords: GetRobotCoordsFromDOMCoords = (x, y) => {
47
+ if (!wrapperRef.current) return { x: 0, y: 0 }
48
+
49
+ const cursorPoint = wrapperRef.current.createSVGPoint()
50
+
51
+ cursorPoint.x = x
52
+ cursorPoint.y = y
53
+
54
+ return cursorPoint.matrixTransform(
55
+ wrapperRef.current.getScreenCTM()?.inverse()
56
+ )
57
+ }
58
+ if (!deckDef && !viewBox) return null
59
+
60
+ let wholeDeckViewBox
61
+ let deckSlotsById = {}
62
+ if (deckDef != null) {
63
+ const [viewBoxOriginX, viewBoxOriginY] = deckDef.cornerOffsetFromOrigin
64
+ const [deckXDimension, deckYDimension] = deckDef.dimensions
65
+
66
+ deckSlotsById = deckDef.locations.addressableAreas.reduce(
67
+ (acc, deckSlot) => ({ ...acc, [deckSlot.id]: deckSlot }),
68
+ {}
69
+ )
70
+ wholeDeckViewBox = `${viewBoxOriginX} ${viewBoxOriginY} ${deckXDimension} ${deckYDimension}`
71
+ }
72
+ return (
73
+ <Svg
74
+ viewBox={viewBox || wholeDeckViewBox}
75
+ ref={wrapperRef}
76
+ id={id}
77
+ /* reflect horizontally about the center of the DOM elem */
78
+ transform="scale(1, -1)"
79
+ {...styleProps}
80
+ >
81
+ {showDeckLayers ? (
82
+ <DeckFromLayers
83
+ layerBlocklist={deckLayerBlocklist}
84
+ robotType={OT2_ROBOT_TYPE}
85
+ />
86
+ ) : null}
87
+ {children?.({ deckSlotsById, getRobotCoordsFromDOMCoords })}
88
+ </Svg>
89
+ )
90
+ }
@@ -0,0 +1,111 @@
1
+ import { FLEX_ROBOT_TYPE } from '@opentrons/shared-data'
2
+ import { DeckInfoLabel } from '../../molecules/DeckInfoLabel'
3
+ import { Flex } from '../../primitives'
4
+ import { ALIGN_CENTER, DIRECTION_COLUMN, JUSTIFY_CENTER } from '../../styles'
5
+ import { RobotCoordsForeignObject } from './RobotCoordsForeignObject'
6
+
7
+ import type { RobotType } from '@opentrons/shared-data'
8
+ interface SlotLabelsProps {
9
+ robotType: RobotType
10
+ color?: string
11
+ show4thColumn?: boolean
12
+ }
13
+
14
+ /**
15
+ * Component to render Opentrons Flex slot labels
16
+ * For use as a RobotWorkspace child component
17
+ */
18
+ export const SlotLabels = ({
19
+ robotType,
20
+ color,
21
+ show4thColumn = false,
22
+ }: SlotLabelsProps): JSX.Element | null => {
23
+ const widthSmallRem = 10.5
24
+ const widthLargeRem = 15.25
25
+
26
+ return robotType === FLEX_ROBOT_TYPE ? (
27
+ <>
28
+ <RobotCoordsForeignObject
29
+ width="2.5rem"
30
+ height="26.75rem"
31
+ x="-147"
32
+ y="-10"
33
+ >
34
+ <Flex
35
+ alignItems={ALIGN_CENTER}
36
+ flexDirection={DIRECTION_COLUMN}
37
+ flex="1"
38
+ height="100%"
39
+ width="2.5rem"
40
+ >
41
+ <Flex alignItems={ALIGN_CENTER} flex="1">
42
+ <DeckInfoLabel deckLabel="A" height="max-content" width="100%" />
43
+ </Flex>
44
+ <Flex alignItems={ALIGN_CENTER} flex="1">
45
+ <DeckInfoLabel deckLabel="B" height="max-content" width="100%" />
46
+ </Flex>
47
+ <Flex alignItems={ALIGN_CENTER} flex="1">
48
+ <DeckInfoLabel deckLabel="C" height="max-content" width="100%" />
49
+ </Flex>
50
+ <Flex alignItems={ALIGN_CENTER} flex="1">
51
+ <DeckInfoLabel deckLabel="D" height="max-content" width="100%" />
52
+ </Flex>
53
+ </Flex>
54
+ </RobotCoordsForeignObject>
55
+ <RobotCoordsForeignObject
56
+ height="2.5rem"
57
+ width={`${
58
+ show4thColumn
59
+ ? widthSmallRem * 2 + widthLargeRem * 2
60
+ : widthSmallRem + widthLargeRem * 2
61
+ }rem`}
62
+ x="-100"
63
+ y="-55"
64
+ >
65
+ <Flex
66
+ alignItems={ALIGN_CENTER}
67
+ flex="1"
68
+ width={`${
69
+ show4thColumn
70
+ ? widthSmallRem * 2 + widthLargeRem * 2
71
+ : widthSmallRem + widthLargeRem * 2
72
+ }rem`}
73
+ height="2.5rem"
74
+ >
75
+ <Flex
76
+ alignItems={ALIGN_CENTER}
77
+ justifyContent={JUSTIFY_CENTER}
78
+ width={`${widthLargeRem}rem`}
79
+ >
80
+ <DeckInfoLabel deckLabel="1" height="100%" />
81
+ </Flex>
82
+ <Flex
83
+ alignItems={ALIGN_CENTER}
84
+ justifyContent={JUSTIFY_CENTER}
85
+ width={`${widthSmallRem}rem`}
86
+ >
87
+ <DeckInfoLabel deckLabel="2" height="100%" />
88
+ </Flex>
89
+ <Flex
90
+ alignItems={ALIGN_CENTER}
91
+ justifyContent={JUSTIFY_CENTER}
92
+ width={
93
+ show4thColumn ? `${widthSmallRem}rem` : `${widthLargeRem}rem`
94
+ }
95
+ >
96
+ <DeckInfoLabel deckLabel="3" height="100%" />
97
+ </Flex>
98
+ {show4thColumn ? (
99
+ <Flex
100
+ alignItems={ALIGN_CENTER}
101
+ justifyContent={JUSTIFY_CENTER}
102
+ width={`${widthSmallRem}rem`}
103
+ >
104
+ <DeckInfoLabel deckLabel="4" height="100%" />
105
+ </Flex>
106
+ ) : null}
107
+ </Flex>
108
+ </RobotCoordsForeignObject>
109
+ </>
110
+ ) : null
111
+ }
@@ -0,0 +1,29 @@
1
+ import assert from 'assert'
2
+ import path from 'path'
3
+ // replace webpack-specific require.context with Node-based glob in tests
4
+ import glob from 'glob'
5
+ import { vi } from 'vitest'
6
+
7
+ import type { DeckDefinition } from '@opentrons/shared-data'
8
+
9
+ const DECK_FIXTURE_PATTERN = path.join(
10
+ __dirname,
11
+ '../../../../../shared-data/deck/fixtures/3/*.json'
12
+ )
13
+
14
+ const allDecks: unknown[] = glob.sync(DECK_FIXTURE_PATTERN).map(require)
15
+
16
+ assert(
17
+ allDecks.length > 0,
18
+ `no deck fixtures found, is the path correct? ${DECK_FIXTURE_PATTERN}`
19
+ )
20
+
21
+ export const getDeckDefinitions = vi.fn(() =>
22
+ (allDecks as DeckDefinition[]).reduce(
23
+ (acc, deck: DeckDefinition): Record<string, DeckDefinition> => ({
24
+ ...acc,
25
+ [deck.otId]: deck,
26
+ }),
27
+ {}
28
+ )
29
+ )
@@ -0,0 +1,12 @@
1
+ export const ALL_OT2_DECK_LAYERS = [
2
+ 'fixedBase',
3
+ 'fixedTrash',
4
+ 'doorStops',
5
+ 'metalFrame',
6
+ 'removableDeckOutline',
7
+ 'slotRidges',
8
+ 'slotNumbers',
9
+ 'calibrationMarkings',
10
+ 'removalHandle',
11
+ 'screwHoles',
12
+ ] as const
@@ -0,0 +1,8 @@
1
+ export * from './DeckFromLayers'
2
+ export * from './FlexTrash'
3
+ export * from './MoveLabwareOnDeck'
4
+ export * from './RobotCoordsForeignDiv'
5
+ export * from './RobotCoordsForeignObject'
6
+ export * from './RobotCoordsText'
7
+ export * from './RobotWorkSpace'
8
+ export * from './SlotLabels'
@@ -0,0 +1,91 @@
1
+ import { Icon } from '../../icons'
2
+ import { Btn, Text } from '../../primitives'
3
+ import { TYPOGRAPHY } from '../../ui-style-constants'
4
+ import { COLORS } from '../../helix-design-system'
5
+ import { RobotCoordsForeignObject } from '../Deck/RobotCoordsForeignObject'
6
+ import {
7
+ COLUMN_3_X_ADJUSTMENT,
8
+ CONFIG_STYLE_EDITABLE,
9
+ CONFIG_STYLE_READ_ONLY,
10
+ FIXTURE_HEIGHT,
11
+ STAGING_AREA_FIXTURE_WIDTH,
12
+ Y_ADJUSTMENT,
13
+ CONFIG_STYLE_SELECTED,
14
+ } from './constants'
15
+
16
+ import type {
17
+ CutoutFixtureId,
18
+ CutoutId,
19
+ DeckDefinition,
20
+ } from '@opentrons/shared-data'
21
+
22
+ interface AbsorbanceReaderFixtureProps {
23
+ deckDefinition: DeckDefinition
24
+ fixtureLocation: CutoutId
25
+ cutoutFixtureId: CutoutFixtureId
26
+ handleClickRemove?: (
27
+ fixtureLocation: CutoutId,
28
+ cutoutFixtureId: CutoutFixtureId
29
+ ) => void
30
+ selected?: boolean
31
+ }
32
+
33
+ const ABSORBANCE_READER_FIXTURE_DISPLAY_NAME = 'Absorbance'
34
+
35
+ export function AbsorbanceReaderFixture(
36
+ props: AbsorbanceReaderFixtureProps
37
+ ): JSX.Element {
38
+ const {
39
+ deckDefinition,
40
+ handleClickRemove,
41
+ fixtureLocation,
42
+ cutoutFixtureId,
43
+ selected = false,
44
+ } = props
45
+
46
+ const cutoutDef = deckDefinition.locations.cutouts.find(
47
+ cutout => cutout.id === fixtureLocation
48
+ )
49
+
50
+ /**
51
+ * deck definition cutout position is the position of the single slot located within that cutout
52
+ * so, to get the position of the cutout itself we must add an adjustment to the slot position
53
+ * the adjustment for x is different for right side/left side
54
+ */
55
+ const [xSlotPosition = 0, ySlotPosition = 0] = cutoutDef?.position ?? []
56
+
57
+ const x = xSlotPosition + COLUMN_3_X_ADJUSTMENT
58
+
59
+ const y = ySlotPosition + Y_ADJUSTMENT
60
+
61
+ const editableStyle = selected ? CONFIG_STYLE_SELECTED : CONFIG_STYLE_EDITABLE
62
+ return (
63
+ <RobotCoordsForeignObject
64
+ width={STAGING_AREA_FIXTURE_WIDTH}
65
+ height={FIXTURE_HEIGHT}
66
+ x={x}
67
+ y={y}
68
+ flexProps={{ flex: '1' }}
69
+ foreignObjectProps={{ flex: '1' }}
70
+ >
71
+ <Btn
72
+ css={handleClickRemove != null ? editableStyle : CONFIG_STYLE_READ_ONLY}
73
+ cursor={handleClickRemove != null ? 'pointer' : 'default'}
74
+ onClick={
75
+ handleClickRemove != null
76
+ ? () => {
77
+ handleClickRemove(fixtureLocation, cutoutFixtureId)
78
+ }
79
+ : () => {}
80
+ }
81
+ >
82
+ <Text css={TYPOGRAPHY.smallBodyTextSemiBold}>
83
+ {ABSORBANCE_READER_FIXTURE_DISPLAY_NAME}
84
+ </Text>
85
+ {handleClickRemove != null ? (
86
+ <Icon name="remove" color={COLORS.white} size="2rem" />
87
+ ) : null}
88
+ </Btn>
89
+ </RobotCoordsForeignObject>
90
+ )
91
+ }
@@ -0,0 +1,110 @@
1
+ import type * as React from 'react'
2
+
3
+ import {
4
+ SINGLE_CENTER_SLOT_FIXTURE,
5
+ SINGLE_LEFT_SLOT_FIXTURE,
6
+ STAGING_AREA_RIGHT_SLOT_FIXTURE,
7
+ TRASH_BIN_ADAPTER_FIXTURE,
8
+ WASTE_CHUTE_RIGHT_ADAPTER_COVERED_FIXTURE,
9
+ } from '@opentrons/shared-data'
10
+
11
+ import { DeckConfigurator } from '.'
12
+
13
+ import type { Story, Meta } from '@storybook/react'
14
+ import type { CutoutConfig } from '@opentrons/shared-data'
15
+
16
+ export default {
17
+ title: 'Library/Molecules/Simulation/DeckConfigurator',
18
+ } as Meta
19
+
20
+ const Template: Story<React.ComponentProps<typeof DeckConfigurator>> = args => (
21
+ <DeckConfigurator {...args} />
22
+ )
23
+ const deckConfig: CutoutConfig[] = [
24
+ {
25
+ cutoutId: 'cutoutA1',
26
+ cutoutFixtureId: SINGLE_LEFT_SLOT_FIXTURE,
27
+ },
28
+ {
29
+ cutoutId: 'cutoutB1',
30
+ cutoutFixtureId: SINGLE_LEFT_SLOT_FIXTURE,
31
+ },
32
+ {
33
+ cutoutId: 'cutoutC1',
34
+ cutoutFixtureId: SINGLE_LEFT_SLOT_FIXTURE,
35
+ },
36
+ {
37
+ cutoutId: 'cutoutD1',
38
+ cutoutFixtureId: SINGLE_LEFT_SLOT_FIXTURE,
39
+ },
40
+ {
41
+ cutoutFixtureId: SINGLE_CENTER_SLOT_FIXTURE,
42
+ cutoutId: 'cutoutA2',
43
+ },
44
+ {
45
+ cutoutFixtureId: SINGLE_CENTER_SLOT_FIXTURE,
46
+ cutoutId: 'cutoutB2',
47
+ },
48
+ {
49
+ cutoutFixtureId: SINGLE_CENTER_SLOT_FIXTURE,
50
+ cutoutId: 'cutoutC2',
51
+ },
52
+ {
53
+ cutoutFixtureId: SINGLE_CENTER_SLOT_FIXTURE,
54
+ cutoutId: 'cutoutD2',
55
+ },
56
+ {
57
+ cutoutId: 'cutoutA3',
58
+ cutoutFixtureId: TRASH_BIN_ADAPTER_FIXTURE,
59
+ },
60
+ {
61
+ cutoutId: 'cutoutB3',
62
+ cutoutFixtureId: STAGING_AREA_RIGHT_SLOT_FIXTURE,
63
+ },
64
+ {
65
+ cutoutId: 'cutoutC3',
66
+ cutoutFixtureId: STAGING_AREA_RIGHT_SLOT_FIXTURE,
67
+ },
68
+ {
69
+ cutoutId: 'cutoutD3',
70
+ cutoutFixtureId: WASTE_CHUTE_RIGHT_ADAPTER_COVERED_FIXTURE,
71
+ },
72
+ ]
73
+
74
+ const staticFixtures = [
75
+ { location: 'cutoutB2', label: 'Tip rack' },
76
+ { location: 'cutoutC2', label: 'Labware' },
77
+ { location: 'cutoutD2', label: 'Labware' },
78
+ ]
79
+
80
+ export const Default = Template.bind({})
81
+ Default.args = {
82
+ deckConfig,
83
+ handleClickAdd: cutoutId => {
84
+ console.log(`add at ${cutoutId}`)
85
+ },
86
+ handleClickRemove: cutoutId => {
87
+ console.log(`remove at ${cutoutId}`)
88
+ },
89
+ }
90
+
91
+ export const ReadOnly = Template.bind({})
92
+ ReadOnly.args = {
93
+ deckConfig,
94
+ handleClickAdd: cutoutId => {
95
+ console.log(`add at ${cutoutId}`)
96
+ },
97
+ handleClickRemove: cutoutId => {
98
+ console.log(`remove at ${cutoutId}`)
99
+ },
100
+ readOnly: true,
101
+ }
102
+
103
+ export const ReadOnlyWithStaticFixtures = Template.bind({})
104
+ ReadOnlyWithStaticFixtures.args = {
105
+ deckConfig,
106
+ handleClickAdd: () => {},
107
+ handleClickRemove: () => {},
108
+ readOnly: true,
109
+ additionalStaticFixtures: staticFixtures,
110
+ }
@@ -0,0 +1,131 @@
1
+ import { css } from 'styled-components'
2
+
3
+ import { Icon } from '../../icons'
4
+ import { Btn } from '../../primitives'
5
+ import { ALIGN_CENTER, DISPLAY_FLEX, JUSTIFY_CENTER } from '../../styles'
6
+ import { RESPONSIVENESS } from '../../ui-style-constants'
7
+ import { BORDERS, COLORS } from '../../helix-design-system'
8
+ import { RobotCoordsForeignObject } from '../Deck/RobotCoordsForeignObject'
9
+ import {
10
+ COLUMN_1_SINGLE_SLOT_FIXTURE_WIDTH,
11
+ COLUMN_2_SINGLE_SLOT_FIXTURE_WIDTH,
12
+ COLUMN_3_SINGLE_SLOT_FIXTURE_WIDTH,
13
+ COLUMN_1_X_ADJUSTMENT,
14
+ COLUMN_2_X_ADJUSTMENT,
15
+ COLUMN_3_X_ADJUSTMENT,
16
+ FIXTURE_HEIGHT,
17
+ Y_ADJUSTMENT,
18
+ } from './constants'
19
+
20
+ import type { CutoutId, DeckDefinition } from '@opentrons/shared-data'
21
+
22
+ interface EmptyConfigFixtureProps {
23
+ deckDefinition: DeckDefinition
24
+ fixtureLocation: CutoutId
25
+ handleClickAdd: (fixtureLocation: CutoutId) => void
26
+ }
27
+
28
+ export function EmptyConfigFixture(
29
+ props: EmptyConfigFixtureProps
30
+ ): JSX.Element {
31
+ const { deckDefinition, handleClickAdd, fixtureLocation } = props
32
+
33
+ const standardSlotCutout = deckDefinition.locations.cutouts.find(
34
+ cutout => cutout.id === fixtureLocation
35
+ )
36
+
37
+ /**
38
+ * deck definition cutout position is the position of the single slot located within that cutout
39
+ * so, to get the position of the cutout itself we must add an adjustment to the slot position
40
+ * the adjustment for x is different for right side/left side
41
+ */
42
+ const [xSlotPosition = 0, ySlotPosition = 0] =
43
+ standardSlotCutout?.position ?? []
44
+ let x = xSlotPosition
45
+ let width = 0
46
+ switch (fixtureLocation) {
47
+ case 'cutoutA1':
48
+ case 'cutoutB1':
49
+ case 'cutoutC1':
50
+ case 'cutoutD1': {
51
+ x = xSlotPosition + COLUMN_1_X_ADJUSTMENT
52
+ width = COLUMN_1_SINGLE_SLOT_FIXTURE_WIDTH
53
+ break
54
+ }
55
+ case 'cutoutA2':
56
+ case 'cutoutB2':
57
+ case 'cutoutC2':
58
+ case 'cutoutD2': {
59
+ x = xSlotPosition + COLUMN_2_X_ADJUSTMENT
60
+ width = COLUMN_2_SINGLE_SLOT_FIXTURE_WIDTH
61
+ break
62
+ }
63
+ case 'cutoutA3':
64
+ case 'cutoutB3':
65
+ case 'cutoutC3':
66
+ case 'cutoutD3': {
67
+ x = xSlotPosition + COLUMN_3_X_ADJUSTMENT
68
+ width = COLUMN_3_SINGLE_SLOT_FIXTURE_WIDTH
69
+ break
70
+ }
71
+ }
72
+
73
+ const y = ySlotPosition + Y_ADJUSTMENT
74
+
75
+ return (
76
+ <RobotCoordsForeignObject
77
+ width={width}
78
+ height={FIXTURE_HEIGHT}
79
+ x={x}
80
+ y={y}
81
+ flexProps={{ flex: '1' }}
82
+ foreignObjectProps={{ flex: '1' }}
83
+ >
84
+ <Btn
85
+ css={EMPTY_CONFIG_STYLE}
86
+ onClick={() => {
87
+ handleClickAdd(fixtureLocation)
88
+ }}
89
+ >
90
+ <Icon name="add" color={COLORS.blue50} size="2rem" />
91
+ </Btn>
92
+ </RobotCoordsForeignObject>
93
+ )
94
+ }
95
+
96
+ const EMPTY_CONFIG_STYLE = css`
97
+ display: ${DISPLAY_FLEX};
98
+ align-items: ${ALIGN_CENTER};
99
+ justify-content: ${JUSTIFY_CENTER};
100
+ background-color: ${COLORS.blue30};
101
+ border: 3px dashed ${COLORS.blue50};
102
+ border-radius: ${BORDERS.borderRadius4};
103
+ width: 100%;
104
+
105
+ @media ${RESPONSIVENESS.touchscreenMediaQuerySpecs} {
106
+ background-color: ${COLORS.blue35};
107
+ }
108
+
109
+ &:active {
110
+ border: 3px solid ${COLORS.blue50};
111
+ background-color: ${COLORS.blue40};
112
+ }
113
+
114
+ &:focus {
115
+ border: 3px solid ${COLORS.blue50};
116
+ background-color: ${COLORS.blue40};
117
+ }
118
+
119
+ &:hover {
120
+ background-color: ${COLORS.blue35};
121
+ }
122
+
123
+ &:focus-visible {
124
+ border: 3px solid ${COLORS.blue50};
125
+ background-color: ${COLORS.blue35};
126
+
127
+ @media ${RESPONSIVENESS.touchscreenMediaQuerySpecs} {
128
+ background-color: ${COLORS.blue40};
129
+ }
130
+ }
131
+ `
@@ -0,0 +1,102 @@
1
+ import { Icon } from '../../icons'
2
+ import { Btn, Text } from '../../primitives'
3
+ import { TYPOGRAPHY } from '../../ui-style-constants'
4
+ import { COLORS } from '../../helix-design-system'
5
+ import { RobotCoordsForeignObject } from '../Deck/RobotCoordsForeignObject'
6
+ import {
7
+ COLUMN_1_X_ADJUSTMENT,
8
+ COLUMN_3_X_ADJUSTMENT,
9
+ CONFIG_STYLE_EDITABLE,
10
+ CONFIG_STYLE_READ_ONLY,
11
+ FIXTURE_HEIGHT,
12
+ COLUMN_3_SINGLE_SLOT_FIXTURE_WIDTH,
13
+ Y_ADJUSTMENT,
14
+ CONFIG_STYLE_SELECTED,
15
+ } from './constants'
16
+
17
+ import type {
18
+ CutoutFixtureId,
19
+ CutoutId,
20
+ DeckDefinition,
21
+ } from '@opentrons/shared-data'
22
+
23
+ // TODO(BC, 2024-03-21): This component is almost identical to TemperatureModuleFixture, consider consolidating?
24
+
25
+ interface HeaterShakerFixtureProps {
26
+ deckDefinition: DeckDefinition
27
+ fixtureLocation: CutoutId
28
+ cutoutFixtureId: CutoutFixtureId
29
+ handleClickRemove?: (
30
+ fixtureLocation: CutoutId,
31
+ cutoutFixtureId: CutoutFixtureId
32
+ ) => void
33
+ selected?: boolean
34
+ }
35
+
36
+ const HEATER_SHAKER_MODULE_FIXTURE_DISPLAY_NAME = 'Heater-Shaker'
37
+
38
+ export function HeaterShakerFixture(
39
+ props: HeaterShakerFixtureProps
40
+ ): JSX.Element {
41
+ const {
42
+ deckDefinition,
43
+ handleClickRemove,
44
+ fixtureLocation,
45
+ cutoutFixtureId,
46
+ selected = false,
47
+ } = props
48
+
49
+ const cutoutDef = deckDefinition.locations.cutouts.find(
50
+ cutout => cutout.id === fixtureLocation
51
+ )
52
+
53
+ /**
54
+ * deck definition cutout position is the position of the single slot located within that cutout
55
+ * so, to get the position of the cutout itself we must add an adjustment to the slot position
56
+ * the adjustment for x is different for right side/left side
57
+ */
58
+ const [xSlotPosition = 0, ySlotPosition = 0] = cutoutDef?.position ?? []
59
+
60
+ const isColumnOne =
61
+ fixtureLocation === 'cutoutA1' ||
62
+ fixtureLocation === 'cutoutB1' ||
63
+ fixtureLocation === 'cutoutC1' ||
64
+ fixtureLocation === 'cutoutD1'
65
+ const xAdjustment = isColumnOne
66
+ ? COLUMN_1_X_ADJUSTMENT
67
+ : COLUMN_3_X_ADJUSTMENT
68
+ const x = xSlotPosition + xAdjustment
69
+
70
+ const y = ySlotPosition + Y_ADJUSTMENT
71
+
72
+ const editableStyle = selected ? CONFIG_STYLE_SELECTED : CONFIG_STYLE_EDITABLE
73
+ return (
74
+ <RobotCoordsForeignObject
75
+ width={COLUMN_3_SINGLE_SLOT_FIXTURE_WIDTH}
76
+ height={FIXTURE_HEIGHT}
77
+ x={x}
78
+ y={y}
79
+ flexProps={{ flex: '1' }}
80
+ foreignObjectProps={{ flex: '1' }}
81
+ >
82
+ <Btn
83
+ css={handleClickRemove != null ? editableStyle : CONFIG_STYLE_READ_ONLY}
84
+ cursor={handleClickRemove != null ? 'pointer' : 'default'}
85
+ onClick={
86
+ handleClickRemove != null
87
+ ? () => {
88
+ handleClickRemove(fixtureLocation, cutoutFixtureId)
89
+ }
90
+ : () => {}
91
+ }
92
+ >
93
+ <Text css={TYPOGRAPHY.smallBodyTextSemiBold}>
94
+ {HEATER_SHAKER_MODULE_FIXTURE_DISPLAY_NAME}
95
+ </Text>
96
+ {handleClickRemove != null ? (
97
+ <Icon name="remove" color={COLORS.white} size="2rem" />
98
+ ) : null}
99
+ </Btn>
100
+ </RobotCoordsForeignObject>
101
+ )
102
+ }