sstur / react-rte

Pure React rich text WYSIWYG editor based on draft-js.
https://react-rte.org
ISC License
2.86k stars 429 forks source link

Supporting onBlur event #339

Open Vladimir-Romanets opened 5 years ago

Vladimir-Romanets commented 5 years ago

I think this will be a useful listener.

Thank you!

erikt9 commented 5 years ago

This works for me. As the documentation states:

All the props you can pass to Draft.js Editor can be passed to RichTextEditor

Draft.js properties can be found here: https://draftjs.org/docs/api-reference-editor

And include onBlur. I've tried the property in my own code and it seems to work.

Vladimir-Romanets commented 5 years ago

@erikt9 I've tried Unfortunately it isn't working for me. I use TypeScript and I've got a mistake:

Property 'onBlur' does not exist on type 'IntrinsicAttributes & IntrinsicClassAttributes<RichTextEditor> & Readonly<Props> & Readonly<{ children?: ReactNode; }>'. TS2322

githubmaha commented 4 years ago

Hey, I'm having the same issue as Vladimir, could you add the onBlur property to the Props definition for the Typescript type

<RichTextEditor
            // eslint-disable-next-line @typescript-eslint/ban-ts-ignore
            // @ts-ignore
            onBlur={() => {}}
          />

The error prevents compilation, I have to explicitly ignore it. The change should be simple just make the following adjustment:

interface Props {
    className?: string;
    toolbarClassName?: string;
    editorClassName?: string;
    value: EditorValue;
    onChange?: ChangeHandler;
    placeholder?: string;
    customStyleMap?: { [style: string]: { [key: string]: any } };
    handleReturn?: (event: object) => boolean;
    customControls?: CustomControl[];
    readOnly?: boolean;
    disabled?: boolean; // Alias of readOnly
    toolbarConfig?: ToolbarConfig;
    blockStyleFn?: (block: ContentBlock) => string | undefined;
    autoFocus?: boolean;
    keyBindingFn?: (event: object) => string | undefined;
    rootStyle?: object;
    editorStyle?: object;
    toolbarStyle?: object;
    // Add this here
    onBlur?: () => void;
  }
machineghost commented 4 years ago

I'm having a different problem: onBlur seems to be firing way too often (but since onBlur seems like it's a "new feature", I figured it was better to mention it here than start a new ticket ... though I'd be happy to re-file it separately, if desired).

When I refresh the page and start with a fresh editor, the moment I focus on it ... the onBlur is triggered :( Similarly, if I am focused on the editor and I do something to re-focus it (eg. I highlight some text first, then click on that text ... never leaving the RTE), the onBlur fires. This is all easy to see: just throw a debugger or console.log inside your onBlur prop, and you'll see it go off whenever focus is (re-)gained.

This should probably go without saying, but onBlur should only fire when focus is lost ... it should never fire at any other time (eg. when focus is gained, or "re-gained" ... without losing it in the first place).

machineghost commented 4 years ago

P.S. Just looking at the code, it looks like it is blindly passing onChange (as part of otherProps) directly to the Draft.js Editor component, without modification. In other words, this library doesn't appear to be "breaking" it in any way.

Instead, I suspect the problem has to do with a lack of using Draft.js's special focus-handling feature: https://draftjs.org/docs/advanced-topics-managing-focus/. Specifically, I'm referring to the "Translating container clicks to focus" section: I didn't look at the source extensively, but it didn't seem like it was following this:

It is therefore recommended that you use a click listener on your container component, and use the focus() method described above to apply focus to your editor.

If this library isn't focusing Draft.js as it expects, by using an onClick on either (or both?) of it's wrapping <div>s to focus the editor:

    // Notice how neither of these divs has an onClick?
    <div className={cx(styles.root, className)} style={rootStyle}>
      { !toolbarOnBottom && editorToolbar }
      <div className={combinedEditorClassName} style={editorStyle}>
         <Editor
          {...otherProps}

... it could explain why that component would trigger false blur events.