/** @jsxImportSource @emotion/react */ import type { CSSObject, SerializedStyles } from '@emotion/react'; import { css } from '@emotion/react'; import { useCallback, useEffect, useMemo } from 'react'; import type { HighlightEventSource } from '../../../highlight/index.js'; import { useHighlight } from '../../../highlight/index.js'; import { ContextMenu } from '../../ContextMenuBluePrint.js'; import type { BaseRowStyle, TableContextMenuProps } from '../ReactTable.js'; function getRowStyle( isActive: boolean, rowStyle: BaseRowStyle = {}, disableDefaultRowStyle?: boolean, ): SerializedStyles { const { hover = {}, active = {}, base = {}, activated = {} } = rowStyle; const hoverStyle = disableDefaultRowStyle ? (hover as CSSObject) : { backgroundColor: '#ff6f0091', ...hover }; const activeStyle = disableDefaultRowStyle ? (active as CSSObject) : { backgroundColor: '#ff6f0070', ...active }; const baseStyle = disableDefaultRowStyle ? (base as object) : { backgroundColor: 'white', ...base }; return css([ { ...baseStyle, ...(isActive && { backgroundColor: '#ff6f0070', ...activated }), }, { ':hover': hoverStyle, ':active': activeStyle }, ]); } export interface ClickEvent { onClick?: (event: Event, data: unknown) => void; } interface ReactTableRowProps extends ClickEvent, TableContextMenuProps { row: any; highlightedSource?: HighlightEventSource; isRowActive: boolean; rowStyle: BaseRowStyle | undefined; disableDefaultRowStyle?: boolean; } function getIDs(row: any): string[] { const id = row.original.id; if (id) { if (Array.isArray(id)) { return id; } else { return [String(id)]; } } return ['']; } function ReactTableRow(props: ReactTableRowProps) { const { row, highlightedSource = 'UNKNOWN', onContextMenuSelect, contextMenu = [], onClick, isRowActive = false, rowStyle, disableDefaultRowStyle, } = props; const data = useMemo( () => ({ type: highlightedSource, extra: row.original, }), [highlightedSource, row], ); const highlight = useHighlight(getIDs(row), data); useEffect(() => { return () => { highlight.hide(); }; // TODO: avoid this hack. // eslint-disable-next-line react-hooks/exhaustive-deps }, []); const clickHandler = useCallback( (event: Event) => { onClick?.(event, row); }, [onClick, row], ); const { key: rowKey, ...otherKeyProps } = row.getRowProps(); return ( onContextMenuSelect?.(selected, row.original)} as="tr" style={{ position: 'static' }} key={rowKey} css={getRowStyle( highlight.isActive || isRowActive, rowStyle, disableDefaultRowStyle, )} {...otherKeyProps} {...highlight.onHover} > {row.cells.map((cell: any) => { const { column: { style }, isRowSpanned, } = cell; if (isRowSpanned) { return null; } else { const { key: columnKey, ...otherColumnProps } = cell.getCellProps(); return ( { e.preventDefault(); return false; }} style={style} onClick={clickHandler} > {cell.render('Cell')} ); } })} ); } export default ReactTableRow;