@@ -82,11 +82,17 @@ vi.mock('./table-primitives', () => ({
8282vi . mock ( './data-row' , ( ) => ( {
8383 DataRow : ( {
8484 onDoubleClick,
85+ onCellMouseDown,
8586 } : {
8687 onDoubleClick : ( rowId : string , name : string , key : string ) => void
88+ onCellMouseDown : ( rowIndex : number , colIndex : number , shiftKey : boolean ) => void
8789 } ) => (
8890 < tr >
89- < td data-testid = 'cell' onDoubleClick = { ( ) => onDoubleClick ( 'row-1' , 'value' , 'value' ) } >
91+ < td
92+ data-testid = 'cell'
93+ onMouseDown = { ( ) => onCellMouseDown ( 0 , 0 , false ) }
94+ onDoubleClick = { ( ) => onDoubleClick ( 'row-1' , 'value' , 'value' ) }
95+ >
9096 Cell
9197 </ td >
9298 </ tr >
@@ -204,6 +210,69 @@ describe('TableGrid virtual cells', () => {
204210 container . remove ( )
205211 } )
206212
213+ it . each ( [ 'Enter' , 'F2' , ' ' ] ) ( 'opens the read-only viewer with the %s keyboard path' , ( key ) => {
214+ const container = document . createElement ( 'div' )
215+ document . body . appendChild ( container )
216+ const root = createRoot ( container )
217+
218+ act ( ( ) => {
219+ root . render (
220+ < TableGrid
221+ workspaceId = 'workspace-1'
222+ tableId = 'virtual-table'
223+ remoteSelections = { [ ] }
224+ emitCellSelection = { vi . fn ( ) }
225+ locks = { {
226+ schemaLocked : true ,
227+ insertLocked : true ,
228+ updateLocked : true ,
229+ deleteLocked : true ,
230+ } }
231+ onBlockedAction = { mockBlockedAction }
232+ sidebarReservedPx = { 0 }
233+ onOpenColumnConfig = { vi . fn ( ) }
234+ onOpenWorkflowConfig = { vi . fn ( ) }
235+ onOpenEnrichments = { vi . fn ( ) }
236+ onOpenEnrichmentConfig = { vi . fn ( ) }
237+ onOpenExecutionDetails = { vi . fn ( ) }
238+ onOpenEnrichmentDetails = { vi . fn ( ) }
239+ onOpenRowModal = { vi . fn ( ) }
240+ onRequestDeleteRows = { vi . fn ( ) }
241+ onRequestDeleteAllByFilter = { vi . fn ( ) }
242+ onRequestDeleteColumns = { vi . fn ( ) }
243+ onRunColumn = { vi . fn ( ) }
244+ onRunRow = { vi . fn ( ) }
245+ onRunRows = { vi . fn ( ) }
246+ onStopRows = { vi . fn ( ) }
247+ onStopAllRows = { vi . fn ( ) }
248+ onStopRow = { vi . fn ( ) }
249+ onSelectionChange = { vi . fn ( ) }
250+ queryOptions = { { } }
251+ columnRenameSinkRef = { { current : null } }
252+ afterDeleteRowsSinkRef = { { current : null } }
253+ afterDeleteAllSinkRef = { { current : null } }
254+ confirmDeleteColumnsSinkRef = { { current : null } }
255+ pushTableRenameUndoSinkRef = { { current : null } }
256+ />
257+ )
258+ } )
259+
260+ const cell = container . querySelector < HTMLElement > ( '[data-testid="cell"]' )
261+ const scroll = container . querySelector < HTMLElement > ( '[data-table-scroll]' )
262+ act ( ( ) => {
263+ cell ?. dispatchEvent ( new MouseEvent ( 'mousedown' , { bubbles : true } ) )
264+ } )
265+ act ( ( ) => {
266+ scroll ?. dispatchEvent ( new KeyboardEvent ( 'keydown' , { key, bubbles : true } ) )
267+ } )
268+
269+ expect ( container . querySelector ( '[data-testid="expanded-cell"]' ) ?. textContent ) . toBe ( 'row-1' )
270+ expect ( mockBlockedAction ) . not . toHaveBeenCalled ( )
271+
272+ act ( ( ) => root . unmount ( ) )
273+ container . remove ( )
274+ } )
275+
207276 it ( 'shows row-query failures instead of presenting an empty result' , ( ) => {
208277 const rowsError = new Error ( 'Transcript filtering and sorting are not supported for this table' )
209278 mockUseTable . mockReturnValue ( createUseTableResult ( rowsError ) )
0 commit comments