chatscope / chat-ui-kit-react

Build your own chat UI with React components in few minutes. Chat UI Kit from chatscope is an open source UI toolkit for developing web chat applications.
https://chatscope.io
MIT License
1.34k stars 116 forks source link

Pasting from clipboard replaces text already present in MessageInput #35

Open yevhen-logosha opened 3 years ago

yevhen-logosha commented 3 years ago

Hey @supersnager

Got one more, pasting text into that already contains text, replaces it.. If you do concatenation magic via setState, then there is no way to paste in the middle of the string.

Steps:

  1. copy text from elsewhere
  2. type anything in MessageInput
  3. paste copied text Actual: written text gets replaced Desired: text from clipboard is added after cursor position.

Sandbox here https://codesandbox.io/s/unruffled-booth-de3wb.

Is there a way to have a paste like we get with plain html input ?

Thank you.

supersnager commented 3 years ago

@yevhen-logosha My example is of course very simple and it does not cover all the edge cases. If you want to paste text at the cursor position in the middle of the string, you need to deal manually with the window.getSelection and so on.... https://developer.mozilla.org/pl/docs/Web/API/Window/getSelection.

I remain this issue open, to see if I can do something to support such a case.

Note: This is about this "magic": https://github.com/chatscope/chat-ui-kit-react/issues/22#issuecomment-815653617

iocuydi commented 1 year ago

I spent a while trying to get cursor/text manipulation with window.getSelection to work, but was unsuccessful. It worked for most cases, but when invoking the paste command multiple times in a row, the contents of the MessageInput seem to be invisible to window.getSelection until the cursor is moved/clicked away. (i.e. if I copy "dog" and paste 3 times, the result should be "dogdogdog" but is instead "dog")

This workaround has been working for me so far as an alternative, and also bypasses the need for useEffect setDisabled etc.: onPaste={(evt) => { evt.preventDefault(); document.execCommand('insertText', false, evt.clipboardData.getData("text")); }}

thelokeshgoel00 commented 1 year ago

document.execCommand is deprecated, Any other known way?

viren242 commented 4 months ago

Can someone suggest a way if anyone found a fix for this?

DoaaRadwan commented 3 months ago

Hi all, This is what is working for us atm for removing styles from copied content

<MessageInput
                      value={chatInput}
                      onChange={(value) => setChatInput(value)}
                      onPaste={(e) => {
                        e.preventDefault()
                        const text = e.clipboardData?.getData('text/plain')
                        const selectedRange = window.getSelection()?.getRangeAt(0)
                        if (!selectedRange || !text) {
                          return
                        }
                        selectedRange.deleteContents()
                        selectedRange.insertNode(document.createTextNode(text))
                        selectedRange.setStart(selectedRange.endContainer, selectedRange.endOffset)
                        setChatInput(e.target.textContent)
                      }}
                    />

We found the code in the onPaste from stack overflow, I will put the link once I have found it