nick-keller / react-datasheet-grid

An Airtable-like / Excel-like component to create beautiful spreadsheets.
MIT License
1.77k stars 167 forks source link

[Feature request] - Support for textarea instead of input for cells #263

Open emilemoureau opened 1 year ago

emilemoureau commented 1 year ago

Hello, first of all thank you for this super useful packaging @nick-keller 🤌

I wanted to know if it was planned to add support for textarea to avoid eating line breaks ?

I can work on a PR if it is not planned !

I explored 2 options :

  1. Create a separate cell type
  2. Change the default input tag to a textarea

Both options have some advantages and disadvantages but the second one is the one I implemented for my app ! I simply added the shortcut : Options + input to locate the line break in the textarea instead of in the table !

khanhicetea commented 9 months ago

I tried to implement the TextareaColumn based on source code and docs, try my simple code (sorry, my React isn't good)

const TextAreaComponent = ({
    rowData,
    setRowData,
    focus,
    columnData,
}) => {

    const ref = useRef(null)

    useLayoutEffect(() => {
        if (focus) {
            ref.current?.focus()
        } else {
            ref.current?.blur()
        }
    }, [focus])

    useEffect(() => {
        if (!focus && ref.current) {
            ref.current.value = rowData || ''
        }
    }, [focus, rowData])

    return <textarea
        ref={ref}
        style={{
            flex: 1,
            alignSelf: 'stretch',
            pointerEvents: focus ? undefined : 'none',
            height: '100%',
            border: 'none',
        }}
        disabled={columnData.disabled}
        defaultValue={rowData}
        onChange={(e) => {
            setRowData(e.target.value)
        }}
        onKeyDown={(e) => {
            if (e.key == "Enter" && e.shiftKey) {
                e.stopPropagation()
            }
        }}
    ></textarea>
}

const textareaColumn = {
    component: TextAreaComponent,
    columnData: {},
    disableKeys: true,
    keepFocus: true,
    deleteValue: () => (null),
    copyValue: ({ rowData }) => (rowData ?? ''),
    pasteValue: ({ value }) => (value || null),
    isCellEmpty: ({ rowData }) => rowData === null || rowData === undefined,
}