-
Notifications
You must be signed in to change notification settings - Fork 187
fix(app): Always render labware centered over their underlying "slots" #20285
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Changes from all commits
17636e4
253fee8
18cd852
d4614d5
025d609
9e2d976
3474b6c
d5c5211
60e7030
8a7bc00
8c5fe46
a3c8176
65ead1d
e6f991a
b69f92d
74519b0
4144b2d
dcc573e
30ec3b3
d3517c4
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -1,6 +1,11 @@ | ||
| import { useMemo } from 'react' | ||
|
|
||
| import { BaseDeck, Flex, LabwareRender } from '@opentrons/components' | ||
| import { | ||
| BaseDeck, | ||
| CenterLabwareInSlot, | ||
| Flex, | ||
| LabwareRender, | ||
| } from '@opentrons/components' | ||
| import { | ||
| FLEX_ROBOT_TYPE, | ||
| getLabwareDefinitionsByURIForProtocol, | ||
|
|
@@ -52,6 +57,8 @@ export function LabwareMapView(props: LabwareMapViewProps): JSX.Element { | |
| : null | ||
| // TODO: ja 8.27.25: find a better way to find the matching lid def without | ||
| // relying on the lidDisplayNames | ||
| // TODO: mm 12.3.25: deduplicate with other places where we're doing the same thing | ||
| // (grep for matchingLidDef) | ||
| const matchingLidDef = Object.values(definitionsByURI).find( | ||
| uri => uri.metadata.displayName === topLabwareInfo?.lidDisplayName | ||
| ) | ||
|
|
@@ -97,6 +104,10 @@ export function LabwareMapView(props: LabwareMapViewProps): JSX.Element { | |
| topLabwareInfo != null | ||
| ? definitionsByURI[topLabwareInfo.definitionUri] | ||
| : null | ||
| // TODO: ja 8.27.25: find a better way to find the matching lid def without | ||
| // relying on the lidDisplayNames | ||
| // TODO: mm 12.3.25: deduplicate with other places where we're doing the same thing | ||
| // (grep for matchingLidDef) | ||
| const matchingLidDef = Object.values(definitionsByURI).find( | ||
| uri => uri.metadata.displayName === topLabwareInfo?.lidDisplayName | ||
| ) | ||
|
|
@@ -116,15 +127,17 @@ export function LabwareMapView(props: LabwareMapViewProps): JSX.Element { | |
| onLabwareClick: () => { | ||
| handleLabwareClick([slotName, stackedItems]) | ||
| }, | ||
| wellFill: wellFill, | ||
| wellFill, | ||
| highlight: true, | ||
| stacked: isLabwareInStack, | ||
| labwareChildren: | ||
| matchingLidDef != null ? ( | ||
| <LabwareRender | ||
| definition={matchingLidDef} | ||
| positioningMode="passThrough" | ||
| /> | ||
| <CenterLabwareInSlot definition={matchingLidDef}> | ||
| <LabwareRender | ||
| definition={matchingLidDef} | ||
| positioningMode="passThrough" | ||
|
Member
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. do we need positioning modes anymore? what do they do at this point?
Contributor
Author
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. We do, but only for now.
|
||
| /> | ||
| </CenterLabwareInSlot> | ||
| ) : null, | ||
| } | ||
| }) | ||
|
|
||
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This change is basically the gist of this PR.
For context,
BaseDeckwill renderlabwareChildrenat the origin of a deck slot. So, this code was renderingmatchingLidDefat the origin of a deck slot.Historically, for most labware, this has happened to work because it placed the bottom-left of the labware (the origin of the labware) at the bottom-left of the slot (the origin of the slot). However, it does not work for:
cornerOffsetFromSlotcompensated for this, but it's dubious whether that should be specified for things like lids, and as a matter of practicality, it so far hasn't been specified for lids.So the solution is to always insert this intermediate
CenterLabwareInSlottransformation, which understands what's being placed into what, and explicitly takes charge of aligning the child to the middle of the parent. There are different helpers for different circumstances.BaseDeck'slabwareChildrenprop is only one pattern that needed to be fixed here. Codebase-wide, we need to stay vigilant against other patterns that place labware "at the slot origin." This is almost always subtle and implicit, unfortunately, which is one of the reasons I've been so gung-ho about documentation (like howlabwareChildrendocuments the SVG origin) and deduplication (like howBaseDeckalso has anestedLabwareDefsBottomToTopprop that takes the responsibility of doing this kind of thing away from the caller).