Giter Site home page Giter Site logo

Comments (8)

atomiks avatar atomiks commented on September 26, 2024 1

It is working, it's just you're not updating the position of the virtual element on scroll. getBoundingClientRect() is returning the same values while scrolling as when you clicked, hence the position doesn't change.

The reason this doesn't happen when using a Range is that it's returning fresh values on scroll (getBoundingClientRect: () => range.getBoundingClientRect()). When this gets called on scroll, the browser returns new values and allows anchoring to the range, but this isn't possible with the click one.

The useClientPoint Hook does work however: https://codesandbox.io/p/sandbox/eager-wood-hwcd6z?file=%2Fsrc%2FContextMenu.tsx%3A113%2C69 (still needs to set the reference as the context)

from floating-ui.

atomiks avatar atomiks commented on September 26, 2024

The virtual element needs a contextElement to know when to update when the scrolling element is scrolled:

    setReference({
      // obviously don't do this, but it should be an element 
     // inside the editor being anchored to
      contextElement: document.querySelector("p") as HTMLElement,
      getBoundingClientRect() {
        // ...
      },
    });

You're transitioning transform with a duration of 2.5s which needs to be avoided for it to be positioned 1:1 in layout though. See the note: https://floating-ui.com/docs/useTransition#usetransitionstyles

from floating-ui.

piszczu4 avatar piszczu4 commented on September 26, 2024

@atomiks regarding transform usage, what is the issue with current implementation? I updated duration to 250 (2500 was for testing only). I've put


#floating-wrapper[data-status="open"] {
  transition-property: opacity, transform;
  transition-duration: 250ms;
}

#floating-wrapper[data-status="close"] {
  transition-property: opacity, transform;
  transition-duration: 250ms;
}

on a wrapper to animate it nicely when the selection changes. The animation on inner element are to animate the translateY when menu appear and disapper. I didn't manage to obtain both these effects using only inner element styles. Do you have some suggestions?

Regarding more important topic which is scrolling - I don't think I understand what this contextElement should be. In general the editor is a div with overflow-y: auto. Does this contextElement have to be the dom element that contains the entire rectangle returned by getBoundingClientRect? Here is an official example with the same problem, how to solve it? (https://codesandbox.io/p/sandbox/floating-ui-react-range-selection-forked-flqmfm?file=%2Fsrc%2FApp.tsx%3A21%2C28)

from floating-ui.

atomiks avatar atomiks commented on September 26, 2024

Ok I see!

Do you have some suggestions?

The problem is it lazily adjusts the position on scroll, whereas it needs to be 1:1. You could animate transform only while selecting, or disable it while scrolling.

Here is an official example with the same problem, how to solve it?

The context element needs to be a child of the scrolling container. You can add an empty div with the id/use a ref and it works.

<div style={{ height: "200px", width: "200px", overflow: "auto" }}>
  <div id="context" />
  ...
</div>

from floating-ui.

piszczu4 avatar piszczu4 commented on September 26, 2024

@atomiks thanks a lot, indeed scrolling problem solved with contextElement set to editor.view.dom.firstChild :)
When it comes to transition, I tried to detect scrolling and add a data-scrolling attribute to flloating-wrapper element

  const [scrolling, setScrolling] = useState(true);
  useEffect(() => {
    const handleScroll = () => {
      setScrolling((prev) => true);
      console.log("Calling handle scroll", scrolling);
    };
    const handleScrollEnd = () => {
      setScrolling((prev) => false);
      console.log("Calling handle scroll end", scrolling);
    };
    window.addEventListener("scroll", handleScroll);
    window.addEventListener("scrollend", handleScrollEnd);

    return () => {
      window.removeEventListener("scroll", handleScroll);
      window.removeEventListener("scrollend", handleScrollEnd);
    };
  });

However for some reason scroll event is not fired when the menu is shown (see console). Do you have some ideas what is the reason? For now I only detect window scrolling, I would need to detect editor scrolling as well and the scrolling of any scrollable children of editor so that might be a not perfect solution in the end.

EDIT OK it seems that it's possible to solve problem with whileElementsMounted. Here is the final code, would be great if @atomiks you could check whether from your perspective it looks fine or you see some improper usage of the library :)

from floating-ui.

piszczu4 avatar piszczu4 commented on September 26, 2024

@atomiks also, contextElement seems to not work to attach the context menu to scrolled container and hide it on scroll. I intentionally removed FlaotingOverlay from your official example, added scrolled area and context element, but the context menu still does not move from its initial position. Here is the updated official example, could you have a look?

https://codesandbox.io/p/sandbox/hopeful-ben-gmwfl5?file=%2Fsrc%2FApp.tsx%3A17%2C40

from floating-ui.

piszczu4 avatar piszczu4 commented on September 26, 2024

@atomiks awesome! For some reason context menu became sticky to the top when the container is scrolled down (while for text selection case its scrolled together with the reference and disappear from view), but I used hide() middleware to hide it (unless there is a better slution). Thanks a lot!

from floating-ui.

piszczu4 avatar piszczu4 commented on September 26, 2024

@atomiks OMG there is one more problem. As you could noticed I'm using your library for the floating menu for rich text editor. If I pick a link in my editor, the menu should show it's href etc. The problem is with closing animation. When I choose a text outside link, the menu fade out but the href became empty before menu disappear which is a bad user experience. To make it easier, I show the problemon your official example with Text floating menu. Menu is rerendered on selection update and contains a random number. Unfortunately, when I click somewhere else to close floating menu, new random number is generated when menu is closing. Do you have some suggestions how to fix that?

DEMO: https://codesandbox.io/p/sandbox/floating-ui-react-range-selection-forked-vgn7s8?file=%2Fsrc%2FApp.tsx%3A99%2C13

EDIT Here is the solution using framer-motion: https://codesandbox.io/p/sandbox/floating-ui-react-range-selection-forked-whjrfw?file=%2Fsrc%2FApp.tsx%3A102%2C41

Is it possible to fix that with floating-ui only?

from floating-ui.

Related Issues (20)

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.