Custom Editor
For writing a custom editor, you can use the useInfiniteColumnEditor
hook.
For any column (or column type - which can then get applied to multiple columns), you can specify a custom editor component to be used for editing the column’s value, via the column.components.editor
property.
const columns: InfiniteTablePropColumns<Developer> = {
id: {
field: 'id',
defaultEditable: false,
},
firstName: {
field: 'firstName',
components: {
// this is using a custom editor component
editor: CustomEditor,
},
},
age: {
field: 'age',
type: 'number',
defaultEditable: false,
},
stack: { field: 'stack' },
currency: { field: 'currency' },
};
The editor component should use the useInfiniteColumnEditor
hook to have access to cell-related information and to confirm, cancel or reject the edit.
CustomEditor.tsx
import { useInfiniteColumnEditor } from '@infinite-table/infinite-react'
const CustomEditor = () => {
const { initialValue, confirmEdit, cancelEdit } = useInfiniteColumnEditor();
const domRef = React.useRef<HTMLInputElement>(null);
const onKeyDown = useCallback((event: React.KeyboardEvent) => {
const { key } = event;
if (key === 'Enter' || key === 'Tab') {
confirmEdit(domRef.current?.value );
} else if (key === 'Escape') {
cancelEdit();
} else {
event.stopPropagation();
}
}, []);
return (
<div>
<input
style={{ width: '100%' }}
autoFocus
ref={domRef}
defaultValue={initialValue}
onKeyDown={onKeyDown}
/>
</div>
);
};
Using a custom editor
In this example, the salary
column is configured with a custom editor component.
View Mode
Fork Forkimport { InfiniteTable, DataSource, InfiniteTablePropColumns, useInfiniteColumnEditor, } from '@infinite-table/infinite-react'; import { useRef, useCallback } from 'react'; type Developer = { id: number; firstName: string; currency: string; stack: string; hobby: string; salary: string; }; const dataSource: Developer[] = [ { id: 1, firstName: 'John', currency: 'USD', stack: 'frontend', hobby: 'gaming', salary: 'USD 1000', }, { id: 2, firstName: 'Jane', currency: 'EUR', stack: 'backend', hobby: 'reading', salary: 'EUR 2000', }, { id: 3, firstName: 'Jack', currency: 'GBP', stack: 'frontend', hobby: 'gaming', salary: 'GBP 3000', }, { id: 4, firstName: 'Jill', currency: 'USD', stack: 'backend', hobby: 'reading', salary: 'USD 4000', }, ]; const CustomEditor = () => { const { initialValue, confirmEdit, cancelEdit } = useInfiniteColumnEditor(); const domRef = useRef<HTMLInputElement>(null); const onKeyDown = useCallback((event: React.KeyboardEvent) => { const { key } = event; if (key === 'Enter' || key === 'Tab') { confirmEdit(domRef.current?.value); } else if (key === 'Escape') { cancelEdit(); } else { event.stopPropagation(); } }, []); return ( <div style={{ background: '#ad1', padding: 5, width: '100%', height: '100%', position: 'absolute', left: 0, top: 0, }} > <input style={{ width: '100%', height: '100%' }} autoFocus ref={domRef} defaultValue={initialValue} onKeyDown={onKeyDown} /> </div> ); }; const columns: InfiniteTablePropColumns<Developer> = { id: { field: 'id', defaultWidth: 80, defaultEditable: false }, salary: { components: { // reference to the custom editor component Editor: CustomEditor, }, defaultWidth: 320, field: 'salary', header: 'Salary - edit accepts numbers only', style: { color: 'tomato' }, getValueToEdit: ({ value }) => { return parseInt(value.substr(4), 10); }, getValueToPersist: ({ value, data }) => { return `${data!.currency} ${parseInt(value, 10)}`; }, shouldAcceptEdit: ({ value }) => { return parseInt(value, 10) == value; }, }, firstName: { field: 'firstName', header: 'Name', }, currency: { field: 'currency', header: 'Currency', }, }; export default function InlineEditingExample() { return ( <> <DataSource<Developer> primaryKey="id" data={dataSource}> <InfiniteTable<Developer> columns={columns} columnDefaultEditable /> </DataSource> </>