Position Draft js emoji popover on top

1.2k views Asked by At

I'm using the @draft-js-plugins/emoji but I'm having problem positioning the emoji popover on top of the editor. Currently it's showing on bottom like this

enter image description here

I want to show this popover on top rather than the bottom.

I found an answer here, but it's not working for me.

const {
    MentionSuggestions,
    EmojiSuggestions,
    EmojiSelect,
    plugins,
  } = useMemo(() => {
    const mentionPlugin = createMentionPlugin();
    // eslint-disable-next-line no-shadow
    const { MentionSuggestions } = mentionPlugin;

    const emojiPlugin = createEmojiPlugin({
      positionSuggestions: (settings) => {
        return {
          left: settings.decoratorRect.left + 'px',
          top: settings.decoratorRect.top - 40 + 'px', // change this value (40) for manage the distance between cursor and bottom edge of popover
          display: 'block',
          transform: 'scale(1) translateY(-100%)', // transition popover on the value of its height
          transformOrigin: '1em 0% 0px',
          transition: 'all 0.25s cubic-bezier(0.3, 1.2, 0.2, 1)',
          position: 'fixed',
        };
      },
      useNativeArt: true,
    });
    // eslint-disable-next-line no-shadow
    const { EmojiSuggestions, EmojiSelect } = emojiPlugin;

    // eslint-disable-next-line no-shadow
    const plugins = [mentionPlugin, emojiPlugin];
    return {
      plugins,
      MentionSuggestions,
      EmojiSuggestions,
      EmojiSelect,
    };
  }, []);

<div className="flex w-100 items-center">
    <div
      className={`${editorStyles.editor} flex w-100 pa2`}
      onClick={() => {
        ref.current!.focus();
      }}
    >
      <Editor
        editorKey={'editor'}
        editorState={editorState}
        handleKeyCommand={(cmd) => handleKeyCommand(cmd)}
        keyBindingFn={myKeyBindingFn}
        onChange={onChange}
        plugins={plugins}
        ref={ref}
        placeholder="Type your message and hit ENTER to send"
      />
      <MentionSuggestions
        open={open}
        onOpenChange={onOpenChange}
        suggestions={suggestions}
        onSearchChange={onSearchChange}
        onAddMention={() => {
          // get the mention object selected
        }}
      />
      <EmojiSuggestions />
    </div>
    <div style={{ margin: '0 .5rem' }}>
      <EmojiSelect closeOnEmojiSelect />
    </div>
    <SendIcon
      className="pointer"
      style={{ color: '#3F61C5', margin: '0 .5rem' }}
      onClick={handleSend}
    />
  </div>

I also inspected the elements, the css I wrote in positionSuggestions are not there. Any way I can place this popover on top?

1

There are 1 answers

1
Yuvraj Chauhan On

I had the same issue and I have resolved it using the CSS option.

  1. Create a copy of this file in your project: https://github.com/draft-js-plugins/draft-js-plugins/blob/master/packages/emoji/src/theme.ts
  2. Find emojiSelectPopover class and replace it with below:
emojiSelectPopover: css`
    padding: 0 0.3em;
    position: absolute;
    z-index: 1000;
    box-sizing: content-box;
    background: #fff;
    border: 1px solid #e0e0e0;
    box-shadow: 0 4px 30px 0 gainsboro;
    transform: scale(1) translateY(-100%);
    transform-origin: 1em 0% 0px;
    top: 65%;
    @media (min-width: 320px) and (max-width: 480px) {
      right: 0;
      top: 50%;
    }
  1. Use your custom theme file(which you have created in #1) in the configuration:
const emojiPlugin = createEmojiPlugin({
    selectButtonContent: '',
    theme: defaultTheme // This should be imported from your created theme file
  });

For your scenario, you need to move right: 0; outside of the media query as your emoji button is close to the right side of the browser.