diff --git a/components/src/hardware-sim/BaseDeck/BaseDeck.tsx b/components/src/hardware-sim/BaseDeck/BaseDeck.tsx index 5dc076b1781..b1aefc968a7 100644 --- a/components/src/hardware-sim/BaseDeck/BaseDeck.tsx +++ b/components/src/hardware-sim/BaseDeck/BaseDeck.tsx @@ -90,6 +90,8 @@ interface BaseDeckProps { svgProps?: React.ComponentProps } +const LABWARE_OFFSET_DISPLAY_THRESHOLD = 2 + export function BaseDeck(props: BaseDeckProps): JSX.Element { const { robotType, @@ -237,6 +239,7 @@ export function BaseDeck(props: BaseDeckProps): JSX.Element { )} <> + {/* render modules, nested labware, and overlays */} {modulesOnDeck.map( ({ moduleModel, @@ -247,7 +250,6 @@ export function BaseDeck(props: BaseDeckProps): JSX.Element { moduleChildren, onLabwareClick, highlightLabware, - stacked = false, }) => { const slotPosition = getPositionFromSlotId( moduleLocation.slotName, @@ -278,11 +280,11 @@ export function BaseDeck(props: BaseDeckProps): JSX.Element { /> ) : null} {moduleChildren} - {stacked ? : null} ) : null } )} + {/* render non-module labware and overlays */} {labwareOnDeck.map( ({ labwareLocation, @@ -292,7 +294,6 @@ export function BaseDeck(props: BaseDeckProps): JSX.Element { missingTips, onLabwareClick, highlight, - stacked = false, }) => { if ( labwareLocation === 'offDeck' || @@ -323,7 +324,72 @@ export function BaseDeck(props: BaseDeckProps): JSX.Element { highlight={highlight} /> {labwareChildren} - {stacked ? : null} + + ) : null + } + )} + {/* render stacked badge on module labware */} + {modulesOnDeck.map( + ({ moduleModel, moduleLocation, stacked = false }) => { + const slotPosition = getPositionFromSlotId( + moduleLocation.slotName, + deckDef + ) + const moduleDef = getModuleDef2(moduleModel) + + const { + x: nestedLabwareOffsetX, + y: nestedLabwareOffsetY, + } = moduleDef.labwareOffset + + // labwareOffset values are more accurate than our SVG renderings, so ignore any deviations under a certain threshold + const clampedLabwareOffsetX = + Math.abs(nestedLabwareOffsetX) > LABWARE_OFFSET_DISPLAY_THRESHOLD + ? nestedLabwareOffsetX + : 0 + const clampedLabwareOffsetY = + Math.abs(nestedLabwareOffsetY) > LABWARE_OFFSET_DISPLAY_THRESHOLD + ? nestedLabwareOffsetY + : 0 + // transform to be applied to children which render within the labware interfacing surface of the module + const childrenTransform = `translate(${clampedLabwareOffsetX}, ${clampedLabwareOffsetY})` + + return slotPosition != null && stacked ? ( + + + + + + ) : null + } + )} + {/* render stacked badge on non-module labware */} + {labwareOnDeck.map( + ({ labwareLocation, definition, stacked = false }) => { + if ( + labwareLocation === 'offDeck' || + !('slotName' in labwareLocation) || + // for legacy protocols that list fixed trash as a labware, do not render + definition.parameters.loadName === + 'opentrons_1_trash_3200ml_fixed' + ) { + return null + } + + const slotPosition = getPositionFromSlotId( + labwareLocation.slotName, + deckDef + ) + + return slotPosition != null && stacked ? ( + + ) : null }