Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[Suggestion extension]: Can't espace suggestion mode when allowSpaces is enabled #2159

Open
1 of 2 tasks
charesbast opened this issue Nov 12, 2021 · 17 comments
Open
1 of 2 tasks
Labels
Info: Stale The issue or pullrequest has not been updated in a while and might be stale Type: Bug The issue or pullrequest is related to a bug

Comments

@charesbast
Copy link

What’s the bug you are facing?

When allowSpaces option is set to false in Suggestion extension, hitting space allow us to quit the suggestion mode.
But when allowSpaces is set to true, we cannot quit the suggestion mode because space is the only key to escape that mode.

How can we reproduce the bug on our side?

You can reproduce by adding the suggestion extension with allowSpaces at true

Can you provide a CodeSandbox?

No response

What did you expect to happen?

It would be really nice to have multiple ways to espace that mode: escape key, but also clicking anywhere on the editor (or just at the right of the suggestion word if the suggestion is the last thing typed in the editor).

Anything to add? (optional)

Enregistrement.de.l.ecran.2021-11-12.a.14.49.06.mov

Did you update your dependencies?

  • Yes, I’ve updated my dependencies to use the latest version of all packages.

Are you sponsoring us?

  • Yes, I’m a sponsor. 💖
@charesbast charesbast added the Type: Bug The issue or pullrequest is related to a bug label Nov 12, 2021
@jakedolan
Copy link
Sponsor Contributor

For others, here is a reference to possible workaround/fix for this issue #214. But some version of this fix should be implemented in the suggestions package.

@rfgamaral
Copy link
Contributor

@philippkuehn Do you think this and #214 can be addressed soon? IMO, these completely botch a great mentions experience. Maybe @jakedolan suggestion could be turned into a PR?

@filippofilip95
Copy link

Hey guys, our team would be supper happy if you can implement this. We are using quick workaround for now but this would really help us a lot. Thanks !

@rfgamaral
Copy link
Contributor

@filippofilip95 Are you using the workaround from @jakedolan, or something else? If something else, can you share your solution? I was hoping to find a workaround that wouldn't involve having my own fork of the suggestion utility, but I'm not sure that's possible.

@filippofilip95
Copy link

filippofilip95 commented Feb 10, 2022

@rfgamaral We are not using that workaround more less due to same reasons.

What we do, is that we basically have option allowSpaces disabled and we use _ character as replacement for white space character. Then on request we replace _ for white space.

Like this:

    suggestion: {
      // TODO allow space bugfix https://github.com/ueberdosis/tiptap/issues/214#issuecomment-964557956
      // allowSpaces: true,
      items: async ({ query, editor }) => {
        const mentionableUsers = editor.storage.props
          .mentionableUsers as MentionableUsers;

        query = query.replaceAll('_', ' ');

        return mentionableUsers
          .filter((user) => isSubstring(query, user.name))
          .map((user) => ({
            ...user,
            image: user.avatar?.src,
            name: `${user.name} ${user.last_name ?? ''}`,
          }));
      },
      
      ...
    },

This workaround allow us to fake white space and result of mentioning can look like this.

Screenshot 2022-02-10 at 13 25 56

It's maybe not best UX but it works.

You can still always note somewhere that to search for mention of multiple words user should use _ instead of white space.

@rfgamaral
Copy link
Contributor

@filippofilip95 Thank you for sharing that. The UX part is not something we want to go with, we'll have this option disabled for the time being.

@duhaime
Copy link

duhaime commented Feb 16, 2022

@filippofilip95 do you replace the space character with _ as users type? If so, how do you run that transformation?

Edit, I figured out where to run that replacement:

onUpdate(props: SuggestionRenderProps) {
  // replace trailing space with _
  const { editor } = props;
  const { $cursor, state, text } = getSelection(editor);
  const pos = $cursor.pos;
  const last = state.doc.textBetween(pos-1, pos);
  if (last === ' ') {
    editor
    .chain()
    .setTextSelection({ from: pos-1, to: pos })
    .insertContent('_')
    .run()
  }
  tooltip.setProps({
    getReferenceClientRect: props.clientRect,
  });
  reactRenderer.updateProps(extendProps(props));
},

@stale
Copy link

stale bot commented Jul 6, 2022

This issue has been automatically marked as stale because it has not had recent activity. It will be closed if no further activity occurs. Thank you for your contributions.

@stale stale bot added the stale label Jul 6, 2022
@stale stale bot closed this as completed Jul 14, 2022
@rfgamaral rfgamaral mentioned this issue Sep 15, 2022
10 tasks
@bdbch bdbch reopened this Sep 15, 2022
@bdbch bdbch added this to the 2.0.0 milestone Sep 15, 2022
@filippofilip95
Copy link

filippofilip95 commented Feb 8, 2023

@duhaime No I didn't run that transformation.

However, I'd like to do it now according to your example :) But I've got a little problem.

My transformation as user type works, but only if typing is faster. When the user stops at the end of the name and then presses the "spacebar", the function onUpdate is not triggered and the last trailingspace is not detected.

It's probably because the mention with trailing space is no longer valid so suggestionRenderer function onUpdate isn't triggered.

Did you experience the same issue? If yes how did you resolve it? Thanks !

Code looks like this.

    onUpdate(props) {
      // replace trailing space with _
      const { editor } = props;
      const position = editor.state.selection.from;
      const last = editor.state.doc.textBetween(position - 1, position);

      if (last === ' ') {
        editor
          .chain()
          .setTextSelection({ from: position - 1, to: position })
          .insertContent('_')
          .run();
      }
      //....
   }

Video with the behavior.

Screen.Recording.2023-02-08.at.13.51.51.mov

@duhaime
Copy link

duhaime commented Feb 9, 2023

@filippofilip95 ah dang I didn't see that behavior where type speed changes the result. Can you send a minimal full fiddle?

@filippofilip95
Copy link

@duhaime Here's the minimal example with a description.

https://stackblitz.com/edit/react-ts-yhhppl?file=App.tsx

@bdbch bdbch removed this from the 2.0.0 milestone Feb 23, 2023
@github-actions
Copy link
Contributor

This issue is stale because it has been open 45 days with no activity. Remove stale label or comment or this will be closed in 7 days

@github-actions github-actions bot added the Info: Stale The issue or pullrequest has not been updated in a while and might be stale label Jun 19, 2023
@tibetsprague
Copy link

This is still an issue, would so love to see a fix for it

@rfgamaral
Copy link
Contributor

@nperez0111 You've done a lot for us already today, so consider this a side-quest request 😅, but do you think you could put some time into figuring this one out? Not today, not necessarily tomorrow or this week, but "soon", I'd hope. This is not a high priority for us right now, but it's an issue that has been plaguing one of our products since we adopted Tiptap, and we'd love to have it fixed eventually.

I personally spent a lot of time trying to figure out a solution for this in the past, but could never implement one that didn't break current expected behaviour, so maybe you'll have better luck.

@nperez0111
Copy link
Contributor

@rfgamaral obviously can't make any promises 😄

From what I see remirror doing here: https://remirror.vercel.app/?path=/story/react-hooks-usementionatom--including-whitespace they seem to be keeping the decoration (i.e. keep marking it as a suggestion with a decoration whether it actually matched or not)
I think that is the only way to resolve this without a complete rewrite of how suggestions work.

It seems like like lexical only display the suggestion menu based on the cursor position, and does not try to do anything special to the text, which is also a nice tradeoff to make https://playground.lexical.dev/

@cayasso
Copy link

cayasso commented Aug 22, 2024

My temp solution for those using tippy.js, not the best, and also not the most efficient, but for the most part it works, but I haven't tested it extensively, so if some one can try it out and let me know how it works for you would be great.

onUpdate(props) {
  if (renderer) {
    renderer.updateProps(props)
  }

  if (!popup || !props.clientRect) return

  const matches = props?.query?.match(/([\s]+)/g)
  const spacesCount = matches?.length || 0

  if (spacesCount > 1 && props.items === null) {
    popup?.[0]?.hide() // hide popup if we have more than one spaces but no result items (null in my case).
    return
  }

  popup[0].setProps({ getReferenceClientRect: props.clientRect })
},
onKeyDown(props) {
  if (props.event.key === 'Escape') {
    popup?.[0].hide()
    return true
  }

  if (!popup?.[0].state.isShown && !popup?.[0].state.isDestroyed) {
    popup?.[0].show() // display the popup on key down
  }

  return renderer?.ref?.onKeyDown(props)
},

@rfgamaral
Copy link
Contributor

@cayasso Thanks for sharing your workaround.

I have not implemented it myself on our side, but we have something similar to that, i.e. hide popup if there are spaces and 0 results. But IMO the solution should exist in the suggestion utility, one that keeps the implementation on the consumer side as simple as possible.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Info: Stale The issue or pullrequest has not been updated in a while and might be stale Type: Bug The issue or pullrequest is related to a bug
Projects
Status: Triage Done
Development

No branches or pull requests

9 participants