@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,81 @@
1
+ import { css } from 'styled-components'
2
+
3
+ import { BORDERS, COLORS } from '../../helix-design-system'
4
+ import { ALIGN_CENTER, DISPLAY_FLEX, JUSTIFY_CENTER } from '../../styles'
5
+ import { RESPONSIVENESS, SPACING } from '../../ui-style-constants'
6
+
7
+ /**
8
+ * These are Flex deck configurator-only values to position a foreign object
9
+ * Position is relative to deck definition slot positions and a custom stroke applied to the single slot fixture SVG
10
+ */
11
+ export const FIXTURE_HEIGHT = 102.0
12
+ export const THERMOCYCLER_FIXTURE_HEIGHT = 290.0
13
+ export const COLUMN_1_SINGLE_SLOT_FIXTURE_WIDTH = 243.5
14
+ export const COLUMN_2_SINGLE_SLOT_FIXTURE_WIDTH = 159.0
15
+ export const COLUMN_3_SINGLE_SLOT_FIXTURE_WIDTH = 243.5
16
+ export const STAGING_AREA_FIXTURE_WIDTH = 314.5
17
+
18
+ export const COLUMN_1_X_ADJUSTMENT = -100
19
+ export const COLUMN_2_X_ADJUSTMENT = -15.5
20
+ export const COLUMN_3_X_ADJUSTMENT = -15.5
21
+ export const Y_ADJUSTMENT = -8
22
+
23
+ export const STAGING_AREA_DISPLAY_NAME = 'Staging area'
24
+ export const TRASH_BIN_DISPLAY_NAME = 'Trash bin'
25
+ export const WASTE_CHUTE_DISPLAY_NAME = 'Waste chute'
26
+
27
+ // common config styles for staging area, trash bin, waste chute
28
+ export const CONFIG_STYLE_READ_ONLY = css`
29
+ display: ${DISPLAY_FLEX};
30
+ align-items: ${ALIGN_CENTER};
31
+ background-color: ${COLORS.grey50};
32
+ border-radius: ${BORDERS.borderRadius4};
33
+ color: ${COLORS.white};
34
+ grid-gap: ${SPACING.spacing8};
35
+ justify-content: ${JUSTIFY_CENTER};
36
+ width: 100%;
37
+ @media ${RESPONSIVENESS.touchscreenMediaQuerySpecs} {
38
+ background-color: ${COLORS.grey55};
39
+ }
40
+ `
41
+
42
+ export const CONFIG_STYLE_EDITABLE = css`
43
+ ${CONFIG_STYLE_READ_ONLY}
44
+
45
+ &:active {
46
+ background-color: ${COLORS.grey60};
47
+ }
48
+
49
+ &:hover {
50
+ background-color: ${COLORS.grey55};
51
+ }
52
+
53
+ &:focus-visible {
54
+ border: 3px solid ${COLORS.yellow50};
55
+ background-color: ${COLORS.grey55};
56
+ @media ${RESPONSIVENESS.touchscreenMediaQuerySpecs} {
57
+ background-color: ${COLORS.grey60};
58
+ }
59
+ }
60
+ `
61
+
62
+ export const CONFIG_STYLE_SELECTED = css`
63
+ ${CONFIG_STYLE_EDITABLE}
64
+ background-color: ${COLORS.blue50};
65
+
66
+ &:active {
67
+ background-color: ${COLORS.blue60};
68
+ }
69
+
70
+ &:hover {
71
+ background-color: ${COLORS.blue55};
72
+ }
73
+
74
+ &:focus-visible {
75
+ border: 3px solid ${COLORS.yellow50};
76
+ background-color: ${COLORS.blue55};
77
+ @media ${RESPONSIVENESS.touchscreenMediaQuerySpecs} {
78
+ background-color: ${COLORS.blue60};
79
+ }
80
+ }
81
+ `
@@ -0,0 +1,285 @@
1
+ import type * as React from 'react'
2
+
3
+ import {
4
+ getDeckDefFromRobotType,
5
+ FLEX_ROBOT_TYPE,
6
+ SINGLE_SLOT_FIXTURES,
7
+ STAGING_AREA_RIGHT_SLOT_FIXTURE,
8
+ TRASH_BIN_ADAPTER_FIXTURE,
9
+ WASTE_CHUTE_ONLY_FIXTURES,
10
+ WASTE_CHUTE_STAGING_AREA_FIXTURES,
11
+ THERMOCYCLER_V2_FRONT_FIXTURE,
12
+ HEATERSHAKER_MODULE_V1_FIXTURE,
13
+ TEMPERATURE_MODULE_V2_FIXTURE,
14
+ MAGNETIC_BLOCK_V1_FIXTURE,
15
+ ABSORBANCE_READER_V1_FIXTURE,
16
+ STAGING_AREA_SLOT_WITH_MAGNETIC_BLOCK_V1_FIXTURE,
17
+ THERMOCYCLER_MODULE_CUTOUTS,
18
+ } from '@opentrons/shared-data'
19
+
20
+ import { COLORS } from '../../helix-design-system'
21
+ import { SingleSlotFixture } from '../BaseDeck/SingleSlotFixture'
22
+ import { SlotLabels } from '../Deck'
23
+ import { RobotCoordinateSpace } from '../RobotCoordinateSpace'
24
+ import { EmptyConfigFixture } from './EmptyConfigFixture'
25
+ import { StagingAreaConfigFixture } from './StagingAreaConfigFixture'
26
+ import { TrashBinConfigFixture } from './TrashBinConfigFixture'
27
+ import { WasteChuteConfigFixture } from './WasteChuteConfigFixture'
28
+ import { StaticFixture } from './StaticFixture'
29
+
30
+ import type {
31
+ CutoutFixtureId,
32
+ CutoutId,
33
+ DeckConfiguration,
34
+ } from '@opentrons/shared-data'
35
+ import { TemperatureModuleFixture } from './TemperatureModuleFixture'
36
+ import { HeaterShakerFixture } from './HeaterShakerFixture'
37
+ import { MagneticBlockFixture } from './MagneticBlockFixture'
38
+ import { ThermocyclerFixture } from './ThermocyclerFixture'
39
+ import { AbsorbanceReaderFixture } from './AbsorbanceReaderFixture'
40
+
41
+ interface DeckConfiguratorProps {
42
+ deckConfig: DeckConfiguration
43
+ handleClickAdd: (cutoutId: CutoutId) => void
44
+ handleClickRemove: (
45
+ cutoutId: CutoutId,
46
+ cutoutFixtureId: CutoutFixtureId
47
+ ) => void
48
+ lightFill?: string
49
+ darkFill?: string
50
+ editableCutoutIds?: CutoutId[]
51
+ showExpansion?: boolean
52
+ children?: React.ReactNode
53
+ additionalStaticFixtures?: Array<{ location: CutoutId; label: string }>
54
+ height?: string
55
+ selectedCutoutId?: CutoutId
56
+ }
57
+
58
+ export function DeckConfigurator(props: DeckConfiguratorProps): JSX.Element {
59
+ const {
60
+ deckConfig,
61
+ handleClickAdd,
62
+ handleClickRemove,
63
+ additionalStaticFixtures,
64
+ children,
65
+ selectedCutoutId,
66
+ lightFill = COLORS.grey35,
67
+ darkFill = COLORS.black90,
68
+ editableCutoutIds = deckConfig.map(({ cutoutId }) => cutoutId),
69
+ showExpansion = true,
70
+ height = '455px',
71
+ } = props
72
+ const deckDef = getDeckDefFromRobotType(FLEX_ROBOT_TYPE)
73
+
74
+ const stagingAreaFixtures = deckConfig.filter(
75
+ ({ cutoutFixtureId }) => cutoutFixtureId === STAGING_AREA_RIGHT_SLOT_FIXTURE
76
+ )
77
+ const wasteChuteFixtures = deckConfig.filter(
78
+ ({ cutoutFixtureId }) =>
79
+ cutoutFixtureId != null &&
80
+ WASTE_CHUTE_ONLY_FIXTURES.includes(cutoutFixtureId)
81
+ )
82
+ const wasteChuteStagingAreaFixtures = deckConfig.filter(
83
+ ({ cutoutFixtureId }) =>
84
+ cutoutFixtureId != null &&
85
+ WASTE_CHUTE_STAGING_AREA_FIXTURES.includes(cutoutFixtureId)
86
+ )
87
+ const emptyCutouts = deckConfig.filter(
88
+ ({ cutoutFixtureId, cutoutId }) =>
89
+ editableCutoutIds.includes(cutoutId) &&
90
+ cutoutFixtureId != null &&
91
+ SINGLE_SLOT_FIXTURES.includes(cutoutFixtureId)
92
+ )
93
+ const trashBinFixtures = deckConfig.filter(
94
+ ({ cutoutFixtureId }) => cutoutFixtureId === TRASH_BIN_ADAPTER_FIXTURE
95
+ )
96
+ const thermocyclerFixtures = deckConfig.filter(
97
+ ({ cutoutFixtureId }) => cutoutFixtureId === THERMOCYCLER_V2_FRONT_FIXTURE
98
+ )
99
+ const heaterShakerFixtures = deckConfig.filter(
100
+ ({ cutoutFixtureId }) => cutoutFixtureId === HEATERSHAKER_MODULE_V1_FIXTURE
101
+ )
102
+ const temperatureModuleFixtures = deckConfig.filter(
103
+ ({ cutoutFixtureId }) => cutoutFixtureId === TEMPERATURE_MODULE_V2_FIXTURE
104
+ )
105
+ const magneticBlockFixtures = deckConfig.filter(({ cutoutFixtureId }) =>
106
+ ([
107
+ MAGNETIC_BLOCK_V1_FIXTURE,
108
+ STAGING_AREA_SLOT_WITH_MAGNETIC_BLOCK_V1_FIXTURE,
109
+ ] as CutoutFixtureId[]).includes(cutoutFixtureId)
110
+ )
111
+ const absorbanceReaderFixtures = deckConfig.filter(
112
+ ({ cutoutFixtureId }) => cutoutFixtureId === ABSORBANCE_READER_V1_FIXTURE
113
+ )
114
+ const magneticBlockStagingAreaFixtures = deckConfig.filter(
115
+ ({ cutoutFixtureId }) =>
116
+ cutoutFixtureId === STAGING_AREA_SLOT_WITH_MAGNETIC_BLOCK_V1_FIXTURE
117
+ )
118
+
119
+ return (
120
+ <RobotCoordinateSpace
121
+ height={height}
122
+ viewBox={`${deckDef.cornerOffsetFromOrigin[0]} ${deckDef.cornerOffsetFromOrigin[1]} ${deckDef.dimensions[0]} ${deckDef.dimensions[1]}`}
123
+ >
124
+ {deckDef.locations.cutouts.map(cutout => (
125
+ // give the outside of the base fixture svgs a stroke for extra spacing
126
+ <g key={cutout.id} stroke={COLORS.white} strokeWidth="4">
127
+ <SingleSlotFixture
128
+ cutoutId={cutout.id}
129
+ deckDefinition={deckDef}
130
+ slotClipColor={COLORS.transparent}
131
+ fixtureBaseColor={lightFill}
132
+ showExpansion={showExpansion}
133
+ />
134
+ </g>
135
+ ))}
136
+ {stagingAreaFixtures.map(({ cutoutId, cutoutFixtureId }) => (
137
+ <StagingAreaConfigFixture
138
+ key={cutoutId}
139
+ deckDefinition={deckDef}
140
+ handleClickRemove={
141
+ editableCutoutIds.includes(cutoutId) ? handleClickRemove : undefined
142
+ }
143
+ fixtureLocation={cutoutId}
144
+ cutoutFixtureId={cutoutFixtureId}
145
+ selected={cutoutId === selectedCutoutId}
146
+ />
147
+ ))}
148
+ {emptyCutouts.map(({ cutoutId }) => (
149
+ <EmptyConfigFixture
150
+ key={cutoutId}
151
+ deckDefinition={deckDef}
152
+ handleClickAdd={handleClickAdd}
153
+ fixtureLocation={cutoutId}
154
+ />
155
+ ))}
156
+ {wasteChuteFixtures.map(({ cutoutId, cutoutFixtureId }) => (
157
+ <WasteChuteConfigFixture
158
+ key={cutoutId}
159
+ deckDefinition={deckDef}
160
+ handleClickRemove={
161
+ editableCutoutIds.includes(cutoutId) ? handleClickRemove : undefined
162
+ }
163
+ fixtureLocation={cutoutId}
164
+ cutoutFixtureId={cutoutFixtureId}
165
+ selected={cutoutId === selectedCutoutId}
166
+ />
167
+ ))}
168
+ {wasteChuteStagingAreaFixtures.map(({ cutoutId, cutoutFixtureId }) => (
169
+ <WasteChuteConfigFixture
170
+ key={cutoutId}
171
+ deckDefinition={deckDef}
172
+ handleClickRemove={
173
+ editableCutoutIds.includes(cutoutId) ? handleClickRemove : undefined
174
+ }
175
+ fixtureLocation={cutoutId}
176
+ cutoutFixtureId={cutoutFixtureId}
177
+ selected={cutoutId === selectedCutoutId}
178
+ hasStagingAreas
179
+ />
180
+ ))}
181
+ {trashBinFixtures.map(({ cutoutId, cutoutFixtureId }) => (
182
+ <TrashBinConfigFixture
183
+ key={cutoutId}
184
+ deckDefinition={deckDef}
185
+ handleClickRemove={
186
+ editableCutoutIds.includes(cutoutId) ? handleClickRemove : undefined
187
+ }
188
+ fixtureLocation={cutoutId}
189
+ cutoutFixtureId={cutoutFixtureId}
190
+ selected={cutoutId === selectedCutoutId}
191
+ />
192
+ ))}
193
+ {temperatureModuleFixtures.map(({ cutoutId, cutoutFixtureId }) => (
194
+ <TemperatureModuleFixture
195
+ key={cutoutId}
196
+ deckDefinition={deckDef}
197
+ handleClickRemove={
198
+ editableCutoutIds.includes(cutoutId) ? handleClickRemove : undefined
199
+ }
200
+ fixtureLocation={cutoutId}
201
+ cutoutFixtureId={cutoutFixtureId}
202
+ selected={cutoutId === selectedCutoutId}
203
+ />
204
+ ))}
205
+ {heaterShakerFixtures.map(({ cutoutId, cutoutFixtureId }) => (
206
+ <HeaterShakerFixture
207
+ key={cutoutId}
208
+ deckDefinition={deckDef}
209
+ handleClickRemove={
210
+ editableCutoutIds.includes(cutoutId) ? handleClickRemove : undefined
211
+ }
212
+ fixtureLocation={cutoutId}
213
+ cutoutFixtureId={cutoutFixtureId}
214
+ selected={cutoutId === selectedCutoutId}
215
+ />
216
+ ))}
217
+ {magneticBlockFixtures.map(({ cutoutId, cutoutFixtureId }) => (
218
+ <MagneticBlockFixture
219
+ key={cutoutId}
220
+ deckDefinition={deckDef}
221
+ handleClickRemove={
222
+ editableCutoutIds.includes(cutoutId) ? handleClickRemove : undefined
223
+ }
224
+ fixtureLocation={cutoutId}
225
+ cutoutFixtureId={cutoutFixtureId}
226
+ selected={cutoutId === selectedCutoutId}
227
+ hasStagingArea={
228
+ cutoutFixtureId === STAGING_AREA_SLOT_WITH_MAGNETIC_BLOCK_V1_FIXTURE
229
+ }
230
+ />
231
+ ))}
232
+ {thermocyclerFixtures.map(({ cutoutId, cutoutFixtureId }) => {
233
+ return (
234
+ <ThermocyclerFixture
235
+ key={cutoutId}
236
+ deckDefinition={deckDef}
237
+ handleClickRemove={
238
+ editableCutoutIds.includes(cutoutId)
239
+ ? handleClickRemove
240
+ : undefined
241
+ }
242
+ fixtureLocation={cutoutId}
243
+ cutoutFixtureId={cutoutFixtureId}
244
+ selected={
245
+ selectedCutoutId != null &&
246
+ THERMOCYCLER_MODULE_CUTOUTS.includes(selectedCutoutId) &&
247
+ THERMOCYCLER_MODULE_CUTOUTS.includes(cutoutId)
248
+ }
249
+ />
250
+ )
251
+ })}
252
+ {absorbanceReaderFixtures.map(({ cutoutId, cutoutFixtureId }) => (
253
+ <AbsorbanceReaderFixture
254
+ key={cutoutId}
255
+ deckDefinition={deckDef}
256
+ handleClickRemove={
257
+ editableCutoutIds.includes(cutoutId) ? handleClickRemove : undefined
258
+ }
259
+ fixtureLocation={cutoutId}
260
+ cutoutFixtureId={cutoutFixtureId}
261
+ selected={cutoutId === selectedCutoutId}
262
+ />
263
+ ))}
264
+ {additionalStaticFixtures?.map(staticFixture => (
265
+ <StaticFixture
266
+ key={staticFixture.location}
267
+ deckDefinition={deckDef}
268
+ label={staticFixture.label}
269
+ fixtureLocation={staticFixture.location}
270
+ />
271
+ ))}
272
+ <SlotLabels
273
+ robotType={FLEX_ROBOT_TYPE}
274
+ color={darkFill}
275
+ show4thColumn={
276
+ stagingAreaFixtures.length > 0 ||
277
+ wasteChuteStagingAreaFixtures.length > 0 ||
278
+ magneticBlockStagingAreaFixtures.length > 0 ||
279
+ absorbanceReaderFixtures.length > 0
280
+ }
281
+ />
282
+ {children}
283
+ </RobotCoordinateSpace>
284
+ )
285
+ }
@@ -0,0 +1,88 @@
1
+ import type * as React from 'react'
2
+ import {
3
+ getPositionFromSlotId,
4
+ OT2_ROBOT_TYPE,
5
+ ot2DeckDefV5,
6
+ } from '@opentrons/shared-data'
7
+
8
+ import { SlotBase } from '../BaseDeck/SlotBase'
9
+
10
+ import type {
11
+ DeckDefinition,
12
+ DeckSlot,
13
+ RobotType,
14
+ } from '@opentrons/shared-data'
15
+
16
+ interface LegacyDeckSlotLocationProps extends React.SVGProps<SVGGElement> {
17
+ robotType: RobotType
18
+ slotName: DeckSlot['id']
19
+ slotBaseColor?: React.SVGProps<SVGPathElement>['fill']
20
+ slotClipColor?: React.SVGProps<SVGPathElement>['stroke']
21
+ }
22
+
23
+ type AddressableAreaFromDeckDef = typeof ot2DeckDefV5.locations.addressableAreas[number]
24
+
25
+ // dimensions of the OT-2 fixed trash, not in deck definition
26
+ export const OT2_FIXED_TRASH_X_DIMENSION = 172.86
27
+ export const OT2_FIXED_TRASH_Y_DIMENSION = 165.86
28
+
29
+ /**
30
+ * This is a legacy component for rendering an OT-2 deck slot by reference to the V4 deck definition
31
+ */
32
+ export function LegacyDeckSlotLocation(
33
+ props: LegacyDeckSlotLocationProps
34
+ ): JSX.Element | null {
35
+ const {
36
+ robotType,
37
+ slotName,
38
+ slotBaseColor,
39
+ slotClipColor,
40
+ ...restProps
41
+ } = props
42
+
43
+ if (robotType !== OT2_ROBOT_TYPE) return null
44
+
45
+ const slotDef = ot2DeckDefV5.locations.addressableAreas.find(
46
+ (s: AddressableAreaFromDeckDef) => s.id === slotName
47
+ )
48
+ if (slotDef == null) {
49
+ console.warn(
50
+ `cannot render DeckSlotLocation, no deck slot named: ${slotName} in OT-2 deck definition`
51
+ )
52
+ return null
53
+ }
54
+
55
+ const slotPosition = getPositionFromSlotId(
56
+ slotName,
57
+ (ot2DeckDefV5 as unknown) as DeckDefinition
58
+ )
59
+
60
+ const isFixedTrash = slotName === 'fixedTrash'
61
+
62
+ const [xPosition, yPosition] = slotPosition ?? [0, 0]
63
+ const { xDimension, yDimension } = isFixedTrash
64
+ ? {
65
+ xDimension: OT2_FIXED_TRASH_X_DIMENSION,
66
+ yDimension: OT2_FIXED_TRASH_Y_DIMENSION,
67
+ }
68
+ : slotDef.boundingBox
69
+ const [xOffset, yOffset] = slotDef.offsetFromCutoutFixture
70
+
71
+ // adjust the fixed trash position and dimension to fit inside deck SVG
72
+ const fixedTrashPositionAdjustment = isFixedTrash ? 7 : 0
73
+ const fixedTrashDimensionAdjustment = isFixedTrash ? -9 : 0
74
+
75
+ const adjustedXPosition = xPosition + fixedTrashPositionAdjustment - xOffset
76
+ const adjustedYPosition = yPosition + fixedTrashPositionAdjustment - yOffset
77
+ const adjustedXDimension = xDimension + fixedTrashDimensionAdjustment
78
+ const adjustedYDimension = yDimension + fixedTrashDimensionAdjustment
79
+
80
+ return (
81
+ <g {...restProps}>
82
+ <SlotBase
83
+ fill={slotBaseColor}
84
+ d={`M${adjustedXPosition},${adjustedYPosition}h${adjustedXDimension}v${adjustedYDimension}h${-adjustedXDimension}v${-adjustedYDimension}z`}
85
+ />
86
+ </g>
87
+ )
88
+ }
@@ -0,0 +1,173 @@
1
+ import * as React from 'react'
2
+ import styled from 'styled-components'
3
+ import map from 'lodash/map'
4
+
5
+ import { COLORS } from '../../helix-design-system'
6
+
7
+ import {
8
+ LabwareOutline,
9
+ LabwareWellLabels,
10
+ STYLE_BY_WELL_CONTENTS,
11
+ Well,
12
+ } from './labwareInternals'
13
+ import { LabwareAdapter, labwareAdapterLoadNames } from './LabwareAdapter'
14
+
15
+ import type { LabwareDefinition2, LabwareWell } from '@opentrons/shared-data'
16
+ import type {
17
+ HighlightedWellLabels,
18
+ WellMouseEvent,
19
+ WellFill,
20
+ WellStroke,
21
+ } from './labwareInternals/types'
22
+ import type { LabwareAdapterLoadName } from './LabwareAdapter'
23
+
24
+ export interface LabwareProps {
25
+ /** Labware definition to render */
26
+ definition: LabwareDefinition2
27
+ /** Opional Prop for labware on heater shakers sitting on right side of the deck */
28
+ shouldRotateAdapterOrientation?: boolean
29
+ /** boolean to show well labels */
30
+ showLabels?: boolean
31
+ /** color to render well labels */
32
+ wellLabelColor?: string
33
+ /** option to highlight well labels with specified color */
34
+ highlightedWellLabels?: HighlightedWellLabels
35
+ /** CSS color to fill specified wells */
36
+ wellFill?: WellFill
37
+ /** CSS color to stroke specified wells */
38
+ wellStroke?: WellStroke
39
+ /** adds thicker blue border with blur to labware */
40
+ highlight?: boolean
41
+ /** Optional callback, called with WellMouseEvent args onMouseEnter */
42
+ onMouseEnterWell?: (e: WellMouseEvent) => unknown
43
+ /** Optional callback, called with WellMouseEvent args onMouseLeave */
44
+ onMouseLeaveWell?: (e: WellMouseEvent) => unknown
45
+ gRef?: React.RefObject<SVGGElement>
46
+ onLabwareClick?: () => void
47
+ /** Hide labware outline */
48
+ hideOutline?: boolean
49
+ /** Provides well data attribute */
50
+ isInteractive?: boolean
51
+ }
52
+
53
+ const TipDecoration = React.memo(function TipDecoration(props: {
54
+ well: LabwareWell
55
+ }) {
56
+ const { well } = props
57
+ if (well.shape === 'circular') {
58
+ const radius = well.diameter / 2
59
+ return (
60
+ <circle
61
+ {...STYLE_BY_WELL_CONTENTS.tipPresent}
62
+ cx={well.x}
63
+ cy={well.y}
64
+ r={radius - 1}
65
+ />
66
+ )
67
+ }
68
+ return null
69
+ })
70
+
71
+ const LabwareDetailGroup = styled.g`
72
+ fill: none;
73
+ stroke: ${COLORS.black90};
74
+ stroke-width: 1;
75
+ `
76
+
77
+ /**
78
+ * a refactor of the legacy LabwareRender component intended to provide predictable styling
79
+ * initial use in ODD well selection component with ODD-specific well label styling
80
+ * consider adding additional styled wells props if used elsewhere
81
+ * @param props
82
+ * @returns
83
+ */
84
+ export const Labware = (props: LabwareProps): JSX.Element => {
85
+ const {
86
+ definition,
87
+ gRef,
88
+ hideOutline = false,
89
+ highlight,
90
+ highlightedWellLabels,
91
+ isInteractive,
92
+ onLabwareClick,
93
+ onMouseEnterWell,
94
+ onMouseLeaveWell,
95
+ showLabels = false,
96
+ wellFill = {},
97
+ wellLabelColor,
98
+ wellStroke = {},
99
+ } = props
100
+
101
+ const cornerOffsetFromSlot = definition.cornerOffsetFromSlot
102
+ const labwareLoadName = definition.parameters.loadName
103
+
104
+ if (labwareAdapterLoadNames.includes(labwareLoadName)) {
105
+ const { shouldRotateAdapterOrientation = false } = props
106
+ const { xDimension, yDimension } = definition.dimensions
107
+
108
+ return (
109
+ <g
110
+ transform={
111
+ shouldRotateAdapterOrientation
112
+ ? `rotate(180, ${xDimension / 2}, ${yDimension / 2})`
113
+ : 'rotate(0, 0, 0)'
114
+ }
115
+ >
116
+ <g
117
+ transform={`translate(${cornerOffsetFromSlot.x}, ${cornerOffsetFromSlot.y})`}
118
+ ref={gRef}
119
+ >
120
+ <LabwareAdapter
121
+ labwareLoadName={labwareLoadName as LabwareAdapterLoadName}
122
+ />
123
+ </g>
124
+ </g>
125
+ )
126
+ }
127
+
128
+ const { isTiprack } = definition.parameters
129
+
130
+ return (
131
+ <g
132
+ transform={`translate(${cornerOffsetFromSlot.x}, ${cornerOffsetFromSlot.y})`}
133
+ ref={gRef}
134
+ >
135
+ <g onClick={onLabwareClick}>
136
+ {!hideOutline ? (
137
+ <LabwareDetailGroup>
138
+ <LabwareOutline definition={definition} highlight={highlight} />
139
+ </LabwareDetailGroup>
140
+ ) : null}
141
+ <g>
142
+ {map(definition.wells, (well, wellName) => {
143
+ return (
144
+ <React.Fragment key={wellName}>
145
+ <Well
146
+ wellName={wellName}
147
+ well={well}
148
+ onMouseEnterWell={onMouseEnterWell}
149
+ onMouseLeaveWell={onMouseLeaveWell}
150
+ isInteractive={isInteractive}
151
+ {...(isTiprack
152
+ ? STYLE_BY_WELL_CONTENTS.tipPresent
153
+ : STYLE_BY_WELL_CONTENTS.defaultWell)}
154
+ fill={wellFill[wellName]}
155
+ stroke={wellStroke[wellName]}
156
+ />
157
+
158
+ {isTiprack ? <TipDecoration well={well} /> : null}
159
+ </React.Fragment>
160
+ )
161
+ })}
162
+ </g>
163
+ </g>
164
+ {showLabels && definition.metadata.displayCategory !== 'adapter' ? (
165
+ <LabwareWellLabels
166
+ definition={definition}
167
+ wellLabelColor={wellLabelColor}
168
+ highlightedWellLabels={highlightedWellLabels}
169
+ />
170
+ ) : null}
171
+ </g>
172
+ )
173
+ }