in uui-components/src/table/DataTableCell.tsx [18:153]
export function DataTableCell<TItem, TId, TCellValue>(props: DataTableCellProps<TItem, TId, TCellValue>) {
const [state, setState] = React.useState<DataTableCellState>({ inFocus: false });
const row = props.rowProps;
const ref = React.useRef<HTMLDivElement>();
const editorRef = React.useRef<HTMLElement>();
const isEditable = !!props.onValueChange;
const isReadonly = props.isReadonly ?? props.rowProps.isReadonly;
const tableFocusContext = useContext<DataTableFocusContextState<TId>>(DataTableFocusContext);
useEffect(() => {
if (isEditable) {
tableFocusContext?.dataTableFocusManager
?.registerCell({ id: row.id, index: row.index }, {
index: props.index,
isDisabled: props.isDisabled,
isReadonly: props.isReadonly,
key: props.key,
focus: () => editorRef.current?.focus(),
});
}
return () => {
if (isEditable) {
tableFocusContext?.dataTableFocusManager
?.unregisterCell(row.id, props.index);
}
};
}, [
tableFocusContext?.dataTableFocusManager,
row.index,
props.index,
props.isDisabled,
props.isReadonly,
isEditable,
]);
let content: React.ReactNode;
const handleEditableCellClick: React.MouseEventHandler<HTMLDivElement> = React.useCallback((e) => {
if (!props.isReadonly && !props.isDisabled
&& (editorRef.current === e.target || editorRef.current.parentNode === e.target)
) {
editorRef.current?.focus();
}
}, []);
if (props.rowProps.isLoading) {
content = props.renderPlaceholder(props);
} else if (props.rowProps.isUnknown) {
content = props.renderUnknown(props);
} else if (isEditable) {
const onFocus = () => {
if (isReadonly) return;
props.rowProps.onSelect?.(props.rowProps);
setState((currentState) => ({ ...currentState, inFocus: true }));
tableFocusContext?.dataTableFocusManager
?.setNewFocusCoordinates(row.id, props.index);
};
// Copy all attributes explicitly, to avoid bypassing unnecessary DataTableCell props
// We don't use any helpers and/or deconstruction syntax, as this is performance-sensitive part of code
const editorProps: RenderEditorProps<TItem, TId, any> = {
value: props.value,
onValueChange: props.onValueChange,
isDisabled: props.isDisabled ?? props.rowProps.isDisabled,
isInvalid: props.isInvalid ?? props.rowProps.isInvalid,
isReadonly: isReadonly,
isRequired: props.isRequired ?? props.rowProps.isRequired,
validationMessage: props.validationMessage ?? props.rowProps.validationMessage,
onFocus,
onBlur: () => setState({ ...state, inFocus: false }),
rowProps: props.rowProps,
mode: 'cell',
ref: editorRef,
};
content = (
<div className={ css.editorWrapper } onClick={ handleEditableCellClick }>
{props.renderEditor(editorProps)}
<DataTableCellOverlay
renderTooltip={ props.renderTooltip }
inFocus={ state.inFocus }
rowIndex={ row.index }
columnIndex={ props.index }
isInvalid={ props.isInvalid ?? props.rowProps.isInvalid }
isReadonly={ isReadonly }
validationMessage={ props.validationMessage ?? props.rowProps.validationMessage }
/>
</div>
);
} else {
content = props.column.render(props.rowProps.value, props.rowProps);
}
let justifyContent = props.column.justifyContent;
if (!justifyContent && props.column.textAlign) {
justifyContent = props.column.textAlign;
}
const { textAlign, alignSelf } = props.column;
const styles = {
textAlign,
alignSelf: alignSelf ?? (isEditable ? 'stretch' : undefined),
justifyContent,
};
const getWrappedContent = () => (
<div style={ styles } className={ css.contentWrapper }>
{content}
</div>
);
const cellStyle = {
...props.style,
justifyContent: !props.isFirstColumn && justifyContent,
};
return (
<DataTableCellContainer
ref={ ref }
column={ props.column }
textAlign={ props.isFirstColumn ? undefined : props.column.textAlign }
alignSelf={ props.isFirstColumn ? undefined : props.column.alignSelf }
rawProps={ { role: 'cell' } }
cx={ [
uuiDataTableCellMarkers.uuiTableCell, css.cell, props.cx, props.isInvalid && uuiMod.invalid, state.inFocus && uuiMod.focus,
] }
style={ cellStyle }
>
{props.addons}
{props.isFirstColumn ? getWrappedContent() : content}
</DataTableCellContainer>
);
}