Expensify/react-native-live-markdown

Web: paste eventListener returns different targets based on markdown input content

Closed this issue · 1 comments

Objective

Paste event listener should always return the main markdown input element as a target.

Current state

If your input has a styled element inside and you trying to paste something, the event target will be set to this styled element (<span>) instead of the main markdown input (<div contentEditable ... />). The event target is different based on the content of the markdown and where are you trying to paste something

Issue reproduction code

import * as React from 'react';

import {StyleSheet, Text, View} from 'react-native';

import {MarkdownTextInput} from '@expensify/react-native-live-markdown';
import type {TextInput} from 'react-native';

const DEFAULT_TEXT = ['Hello, *world*!', 'https://expensify.com', '# Lorem ipsum', '> Hello world', '`foo`', '```\nbar\n```', '@here', '@someone@swmansion.com'].join('\n');

export default function App() {
  const [value, setValue] = React.useState(DEFAULT_TEXT);
  const ref = React.useRef<TextInput>(null);

  function checkTarget(event: ClipboardEvent) {
    console.log(event.target === ref.current);
  }

  React.useEffect(() => {
    document.addEventListener('paste', checkTarget);
    return () => {
      document.removeEventListener('paste', checkTarget);
    };
  }, []);

  return (
    <View style={styles.container}>
      <Text>MarkdownTextInput multiline</Text>
      <MarkdownTextInput
        multiline
        autoCapitalize="none"
        value={value}
        onChangeText={setValue}
        style={styles.input}
        ref={ref}
        markdownStyle={{}}
        placeholder="Type here..."
      />
    </View>
  );
}

const styles = StyleSheet.create({
  container: {
    flex: 1,
    alignItems: 'center',
    marginTop: 60,
  },
  platform: {
    alignItems: 'center',
    marginBottom: 20,
  },
  input: {
    fontSize: 20,
    width: 300,
    padding: 5,
    borderColor: 'gray',
    borderWidth: 1,
    textAlignVertical: 'top',
  },
  text: {
    fontFamily: 'Courier New',
    marginTop: 10,
    height: 100,
  },
});

Issue resolved in #178