/********************************************************************************** * Copyright (c) 2025 EclipseSource and others. * * This program and the accompanying materials are made available under the * terms of the MIT License as outlined in the LICENSE file. **********************************************************************************/ import '../../../../../style/tree/editable-string-cell.css'; import { Checkbox, Input, Select } from 'antd'; import type { CheckboxChangeEvent } from 'antd/lib/checkbox'; import React, { useCallback, useEffect, useRef } from 'react'; import { CDTTreeItem, CDTTreeItemResource, EditableCDTTreeTableStringColumn } from '../../../common'; import LabelCell from './LabelCell'; interface EditableLabelCellProps { column: EditableCDTTreeTableStringColumn; record: CDTTreeItem; editing: boolean; autoFocus: boolean; onSubmit: (newValue: string) => void; onCancel: () => void; onEdit?: (edit: boolean) => void; } const EditableLabelCell = ({ column, record, editing, autoFocus, onSubmit, onCancel, onEdit }: EditableLabelCellProps) => { const containerRef = useRef(null); // eslint-disable-next-line @typescript-eslint/no-explicit-any const editorRef = useRef(null); const commitEdit = useCallback( (newValue: string, event?: { stopPropagation: () => void; preventDefault: () => void }) => { event?.stopPropagation(); event?.preventDefault(); onSubmit(newValue); onEdit?.(false); }, [onSubmit] ); const cancelEdit = useCallback(() => { onCancel(); onEdit?.(false); }, [column.edit.value, onCancel, onEdit]); // Cancel the edit only if focus leaves the entire container. const handleBlur = useCallback(() => { setTimeout(() => { if (containerRef.current && document.activeElement && !containerRef.current.contains(document.activeElement)) { cancelEdit(); } }, 0); }, [cancelEdit]); const handleKeyDown = useCallback( (e: React.KeyboardEvent) => { if (e.key === 'Escape') { cancelEdit(); } e.stopPropagation(); }, [cancelEdit] ); // Consume the double-click event so no other handler is triggered. const handleDoubleClick = useCallback( (e: React.MouseEvent) => { e.preventDefault(); e.stopPropagation(); onEdit?.(true); }, [column, onEdit] ); // Focus the editor when entering edit mode. useEffect(() => { if (editing && editorRef.current && autoFocus) { editorRef.current.focus(); } }, [editing, autoFocus]); if (editing) { return (
{(() => { switch (column.edit.type) { case 'text': return ( commitEdit(e.currentTarget.value, e)} onBlur={handleBlur} onClick={e => e.stopPropagation()} onKeyDown={handleKeyDown} /> ); case 'boolean': { const checked = column.edit.value === '1'; return ( commitEdit(e.target.checked ? '1' : '0', e)} onBlur={handleBlur} onClick={e => e.stopPropagation()} onKeyDown={handleKeyDown} /> ); } case 'enum': { return ( ); } default: return null; } })()}
); } return (
); }; export default React.memo(EditableLabelCell);