11import * as React from 'react' ;
22
3+ import { Plate } from '../Plate' ;
34import { PALETTE } from '../theme' ;
45
56import { EmptyLabware } from './EmptyLabware' ;
@@ -13,13 +14,13 @@ import {
1314 LABWARE_METADATA ,
1415} from './labwareMetadata' ;
1516import {
17+ Labware ,
1618 LabwareConfig ,
1719 LabwareKey ,
1820 LabwareWithStyle ,
1921 TecanLabwares ,
2022} from './types' ;
2123
22- // Scaling constants for fit-to-width behavior
2324const GRID_PADDING = 8 ;
2425const GRID_GAP = 8 ;
2526const COLUMN_COUNT = 5 ;
@@ -51,7 +52,6 @@ const LABWARE_ITEM_BASE_STYLE = {
5152 justifySelf : 'center' ,
5253} as const ;
5354
54- // Shared style for columns that span all 3 grid rows
5555const SPANNING_COLUMN_BASE_STYLE = {
5656 display : 'grid' ,
5757 alignSelf : 'center' ,
@@ -68,38 +68,27 @@ const RIGHT_COLUMN_STYLE = {
6868 gridArea : 'rightColumn' ,
6969} as const ;
7070
71- // Helper functions for dynamic grid sizing
72-
73- /**
74- * Calculates dynamic grid-template-columns based on which columns have content.
75- * Empty columns get minimal width (40-60px), filled columns get proportional sizes
76- * matching physical Tecan deck dimensions (column 1: 0.5fr, columns 2-3: 1fr).
77- */
7871function calculateGridTemplateColumns ( labwares : TecanLabwares ) : string {
7972 const filledByColumn = getFilledLabwaresByColumn ( labwares ) ;
8073
8174 const columnSizes = [
82- ( filledByColumn [ 0 ] ?. length ?? 0 ) > 0 ? 'auto' : 'minmax(40px, 60px)' , // Column 0
83- ( filledByColumn [ 1 ] ?. length ?? 0 ) > 0 ? 'auto' : 'minmax(40px, 60px)' , // Column 1
84- ( filledByColumn [ 2 ] ?. length ?? 0 ) > 0 ? 'auto' : 'minmax(40px, 60px)' , // Column 2
85- ( filledByColumn [ 3 ] ?. length ?? 0 ) > 0 ? 'auto' : 'minmax(40px, 60px)' , // Column 3
86- ( filledByColumn [ 4 ] ?. length ?? 0 ) > 0 ? 'auto' : 'minmax(40px, 60px)' , // Column 4
75+ ( filledByColumn [ 0 ] ?. length ?? 0 ) > 0 ? 'auto' : 'minmax(40px, 60px)' ,
76+ ( filledByColumn [ 1 ] ?. length ?? 0 ) > 0 ? 'auto' : 'minmax(40px, 60px)' ,
77+ ( filledByColumn [ 2 ] ?. length ?? 0 ) > 0 ? 'auto' : 'minmax(40px, 60px)' ,
78+ ( filledByColumn [ 3 ] ?. length ?? 0 ) > 0 ? 'auto' : 'minmax(40px, 60px)' ,
79+ ( filledByColumn [ 4 ] ?. length ?? 0 ) > 0 ? 'auto' : 'minmax(40px, 60px)' ,
8780 ] ;
8881
8982 return columnSizes . join ( ' ' ) ;
9083}
9184
92- /**
93- * Calculates dynamic grid-template-rows based on which rows have content.
94- * Empty rows get minimal height (40-60px), filled rows get auto.
95- */
9685function calculateGridTemplateRows ( labwares : TecanLabwares ) : string {
9786 const filledByRow = getFilledLabwaresByRow ( labwares ) ;
9887
9988 const rowSizes = [
100- ( filledByRow [ 0 ] ?. length ?? 0 ) > 0 ? 'auto' : 'minmax(40px, 60px)' , // Row 0
101- ( filledByRow [ 1 ] ?. length ?? 0 ) > 0 ? 'auto' : 'minmax(40px, 60px)' , // Row 1
102- ( filledByRow [ 2 ] ?. length ?? 0 ) > 0 ? 'auto' : 'minmax(40px, 60px)' , // Row 2
89+ ( filledByRow [ 0 ] ?. length ?? 0 ) > 0 ? 'auto' : 'minmax(40px, 60px)' ,
90+ ( filledByRow [ 1 ] ?. length ?? 0 ) > 0 ? 'auto' : 'minmax(40px, 60px)' ,
91+ ( filledByRow [ 2 ] ?. length ?? 0 ) > 0 ? 'auto' : 'minmax(40px, 60px)' ,
10392 ] ;
10493
10594 return rowSizes . join ( ' ' ) ;
@@ -164,7 +153,7 @@ export function TecanDeckView({ labwares }: { labwares: TecanLabwares }) {
164153 const labware : LabwareWithStyle = {
165154 key,
166155 ...metadata ,
167- content : labwares [ key ] ?. content ,
156+ labware : labwares [ key ] ,
168157 style : {
169158 ...LABWARE_ITEM_BASE_STYLE ,
170159 gridArea : key ,
@@ -190,15 +179,36 @@ export function TecanDeckView({ labwares }: { labwares: TecanLabwares }) {
190179 ) ;
191180 } , [ labwares ] ) ;
192181
193- const renderLabware = ( labware : LabwareConfig ) =>
194- labware . content ? (
182+ const renderLabwareContent = (
183+ labware : Labware ,
184+ coordinateSystem : LabwareConfig [ 'coordinateSystem' ] ,
185+ ) => {
186+ if ( labware . type === 'custom' ) {
187+ return labware . content ;
188+ }
189+
190+ return (
191+ < Plate
192+ coordinateSystem = { coordinateSystem }
193+ data = { labware . data }
194+ loading = { labware . loading }
195+ wellSizing = { labware . wellSizing ?? 'compact' }
196+ />
197+ ) ;
198+ } ;
199+
200+ const renderLabware = ( labwareConfig : LabwareConfig ) =>
201+ labwareConfig . labware ? (
195202 < LabwareDetailItem
196- shortLabel = { labware . shortLabel }
197- content = { labware . content }
198- backgroundColor = { labware . color }
203+ shortLabel = { labwareConfig . shortLabel }
204+ content = { renderLabwareContent (
205+ labwareConfig . labware ,
206+ labwareConfig . coordinateSystem ,
207+ ) }
208+ backgroundColor = { labwareConfig . color }
199209 />
200210 ) : (
201- < EmptyLabware shortLabel = { labware . shortLabel } />
211+ < EmptyLabware shortLabel = { labwareConfig . shortLabel } />
202212 ) ;
203213
204214 return (
0 commit comments