Skip to content

TextInput: multiline rich content support #1023

Open

Description

@necolas

Multiline TextInput in React Native supports components as children. Along with #795 and #793, this may require switching to contentEditable for the multiline implementation, if not the single-line input.

Activity

  1. ollyde commented on Dec 6, 2018

    @ollyde

    Slate doesn't play so nice with mobile unfortunately. Same with DraftJS.

    The easiest solution is just wrap each one in it's own native renderer function that spits out the following:

    SubComponent

    <Text>
         <Text style={{ fontWeight: 'bold' }}>Starts </Text>bold.
    </Text>
    

    Web

    <p contentEditable={true} onKeyDown={(e) => this.onChange(e)}>
        <SubComponent />
    </p>
    

    Mobile

    <TextInput 
        multiline={true} 
        onChange={(e) => this.onChange(e)}
    >
        <SubComponent />
    </TextInput>
    

    PS Really awesome library I'm using this to create cross platform apps (Web, Electron, React-Native) and it's going epic. Wish I could donate!

  2. necolas commented on Dec 6, 2018

    @necolas
    OwnerAuthor

    @voidstarfire Thanks! How does React manage when a user edits the contentEditable content that is produced by components React renders? I heard that was one of the difficulties with contentEditable but haven't made time to experiment myself yet. Any more feedback you can include would be really helpful

  3. ollyde commented on Dec 6, 2018

    @ollyde

    I'm playing with that just now.

    It seems to work really well so far. The <Text/> components just wrap around the text. As long as you stick with <Text> only components. No views.

    Seems we have to create some sort of generator to filter out empty text components and fill in styled ones. Should work well with React-native-web.

    I will get back probably mid next week with my results :-)

    Here's some examples if you're interested. @necolas

    I'm actually creating a cross-platform native Markdown editor (Not just viewer) from scratch in React.

    Sub component.

    export default class Editor extends React.Component<Props, State> {
        render () {
            return (
                <Text>
                    <Text>{'This is a sentence' + '\n'}</Text>
                    <Text style={{fontWeight: "bold"}}> with</Text>
                    <Text>one word in bold</Text>
                </Text>
            )
        }
    }
    
    

    Mobile

    export default class MobileRender extends React.Component<Props, State> {
        render() {
            return (
                <TextInput 
                     multiline={true} 
                     style={{ flex: 1, alignSelf: 'stretch' }}
                     onChange={(e) => this.onChange(e)}
                 >
                     <Editor
                         markdown={testMarkdown}
                     />
                </TextInput>
            )
        }
        onChange = (event: NativeSyntheticEvent<any>) => {
            const {name, type, value} = event.nativeEvent;
            debugger
        }
    }
    

    Desktop / Web

    export default class WebRender extends React.Component<Props, State> {
        constructor(props: Props) {
            super(props)
        }
        render() {
            return (
                <p contentEditable={true} onKeyDown={(e) => this.onChange(e)}>
                    <Editor
                        markdown={testMarkdown}
                    />
                </p>
            )
        }
    
        onChange = (event: React.SyntheticEvent<KeyboardEvent>) => {
            
        }
    }
    
  4. necolas commented on Dec 6, 2018

    @necolas
    OwnerAuthor

    Seems we have to create some sort of generator to filter out empty text components and fill in styled ones.

    What does that mean?

  5. ollyde commented on Dec 6, 2018

    @ollyde

    @necolas My bad I was speaking from a Markdown perspective mostly.

    Speaking from a <TextInput> only perspective it seems to work pretty well. The react-native-web <Text> components stack fine and inside contentEditable they seem to work with styles just fine, even when backspacing until you have no content. Although I imagine there will be a lot of empty <Text>{wasContent}</Text> around; hence some sort of filter.

  6. shakeabi commented on Jul 11, 2019

    @shakeabi

    @OllyDixon How is the development going?

  7. ollyde commented on Jul 11, 2019

    @ollyde

    @shakeabi I'm using a library called Quill, worked great for mobile and web :-)

  8. shakeabi commented on Jul 11, 2019

    @shakeabi

    @OllyDixon How are you using quilljs in native cuz there's no native supported quill yet, right? (If webview, then though it may work for various devices, it's still not purely native and can have unexpected behaviour)

  9. ollyde commented on Jul 11, 2019

    @ollyde

    @shakeabi there was no native solution that included an editor.

  10. shakeabi commented on Jul 11, 2019

    @shakeabi

    @OllyDixon It's not that difficult to make a simple native rich text editor. My (partial) solution includes using nested inside . However, react-native-web doesn't support this as it renders either textarea or input tags (neither of them supports children tags). #1380: I've discussed the same in this issue. A probable solution would be to replace the TextInput version (textarea or input) react-native-web to content-editable divs.

  11. ollyde commented on Jul 11, 2019

    @ollyde

    @shakeabi yes I discovered this as well. I no longer do React Native anymore though. Flutter is much better :-)

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Labels

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions