sstur / react-rte

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

Configuration / UI option for target=_blank #244

Open williamhoos opened 6 years ago

williamhoos commented 6 years ago

--moving this from issue 228 where it was buried in a comment---

What does the community think about creating two options for the target=_blank functionality:

  1. When setting up react-rte, a default configuration option to specify whether links will be rendered with or without the new tab/window target?
  2. A UI option to allow users to control the new target - Have a default configuration option for whether to allow a user to change the setting. The most logical place for this option seems to be a checkbox in the WYSIWYG link button for "open in new window" - if there is this UI option, then a configuration option at the gem level for whether to enable the checkbox and the checkbox default value would be the default value in 1 above.

If acceptable to the project, anyone want to code it or I'll try to find a way to get it done. If someone could point to generally where these code changes are needed, it would help in implementing.

ghost commented 6 years ago

I think it should be possible/easy to add arbitrary configurable attributes to links and other types of elements created by the editor.

For example, we use react-rte as the basic RTE for our CMS and we want to give users the ability to toggle the link's rel attribute to "nofollow" for SEO purposes. Would it make sense to make this configurable via the toolbarConfig prop? E.g.:

render() {
  const toolbarConfig = {
    display: ['INLINE_STYLE_BUTTONS', 'BLOCK_TYPE_BUTTONS', 'LINK_BUTTONS', 'BLOCK_TYPE_DROPDOWN', 'HISTORY_BUTTONS'],
    LINK_BUTTONS: [
      {label: 'Link'},
      {label: 'Unlink'},
      {label: 'Nofollow', type: 'TOGGLE', onChange: checked => (checked ? { rel: 'nofollow' } : {})}
    ]
  };
  return (
    <RichTextEditor toolbarConfig={toolbarConfig} />
  );
}

Or would it make more sense to use a render prop? Maybe something like:

import RTE, { ButtonGroup, PopoverIconButton, IconButton } from 'react-rte'

const CustomLinkButtons = ({
  name,
  toolbarConfig,
  editorState,
  showLinkInput,
  toggleShowLinkInput,
  isCursorOnLink,
  shouldShowLinkButton,
  defaultValue,
  setLink,
  removeLink,
  attributes,
  setAttribute,
  removeAttribute
}) => (
  <ButtonGroup key={name}>
    <PopoverIconButton
      label="Link"
      iconName="link"
      isDisabled={!shouldShowLinkButton}
      showPopover={showLinkInput}
      onTogglePopover={toggleShowLinkInput}
      defaultValue={defaultValue}
      onSubmit={setLink}
    />

    <IconButton
      {...toolbarConfig.extraProps}
      label="Remove Link"
      iconName="remove-link"
      isDisabled={!isCursorOnLink}
      onClick={removeLink}
      focusOnClick={false}
    />

    <input
      type="checkbox"
      id="toggleNofollow"
      defaultValue={attributes.rel === 'nofollow'}
      onChange={event => {
        if (event && event.target && event.target.checked) {
          setAttribute('rel', 'nofollow')
        } else {
          removeAttribute('rel')
        }
      }}
    />
    <label for="toggleNofollow">
      Nofollow
    </label>
  </ButtonGroup>
)

const RichTextEditor = props => (
  <RTE
    { ...props }
    LinkButtons={CustomLinkButtons}  // maybe `renderLinkButtons` instead to be more consistent with the existing code?
  />
)

I personally prefer the latter as it allows for a wider range of possibilities, but I would be glad to submit a PR for whichever approach makes the most sense.

williamhoos commented 6 years ago

Did this get implemented?

ghost commented 6 years ago

I'm glad to do it but I would first like to know what @sstur thinks. Which approach would be better?

The-Code-Monkey commented 5 years ago

@timbur i think this is a great way and would much prefer the first option @sstur what do you think?

leomendizabal commented 2 years ago

any update on this?