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

Provide a way to handle slide click and cancel it if mouse is moving #309

Open
thomasleduc opened this issue Oct 23, 2020 · 6 comments
Open

Comments

@thomasleduc
Copy link

Describe the feature you'd like:

Today, when I'm implement click on slide of this slider. The click is fired when my users slide left or right the carousel. I would like the Slide onClick to be cancel if the user is sliding or best, I would like a way to know when my user is sliding in my child component.

Suggested implementation:

Put what I understand is the var I'm looking for isBeingMouseDragged (in Slider.jsx) in the Context Provider so I can use it in my component with useContext() :

import { SliderContext } from 'pure-react-carousel';

const InnerSlide : React.FC<{ id: string }> = ({ id }) => {
  const { isUserMouseMoving } = useContext(SliderContext);

  const handleClick = useCallback((e) => {
    if (isUserMouseMoving) { e.preventDefault(); return; }

    // handle the click with props id
  }, [isUserMouseMoving, id]); 

  return <div className="inner" onClick={handleClick}> my super inner slide {id}</div>;
};

Describe alternatives you've considered:

Add a listener on mouse move, mouse down, mouse up on the whole slider and do it myself.
I found it sad as I think it is already done in the pure-react-carousel code.

@tim-steele
Copy link
Contributor

Thanks @thomasleduc - so to understand you just want to know when the carousel is in the transition state, i.e., sliding?

I do think it would make sense for the context, as it contains other information around the carousel. Is this something you are open to submitting a pull request for?

@thomasleduc
Copy link
Author

thomasleduc commented Nov 3, 2020

It's in my todo list. But I'm not sure I have an elegant solution :

  const [isMouseDown, setIsMouseDown] = useState(false);
  const [isMouseDragging, setIsMouseDragging] = useState(false);
  const timeoutRef = useRef<ReturnType<typeof setTimeout> | null>(null);

  const handleMouseDown = useCallback(() => setIsMouseDown(true), []);

  const handleMouseUp = useCallback(() => {
    setIsMouseDown(false);
    timeoutRef.current = setTimeout(() => setIsMouseDragging(false), 0);
  }, []);

  const handleMouseMove = useCallback(
    () => isMouseDown && setIsMouseDragging(true),
    [isMouseDown]
  );

  // component unmount
  useEffect(
    () => () => {
      timeoutRef?.current && clearTimeout(timeoutRef.current);
    },
    []
  );

  return (<PureReactCarouselProvider>
      <div
        onMouseDown={handleMouseDown}
        onMouseUp={handleMouseUp}
        onMouseMove={handleMouseMove}
      >
      { /* ... */ }
      </div>
  </PureReactCarouselProvider>);

The thing is, PureReactCarouselProvider has no access to its children (could be a fragment or a non display:block element).
I don't know how to get a div that cover the entire slider. Plus, I can't use document as there could be many sliders in it.

@mrbinky3000
Copy link
Collaborator

mrbinky3000 commented Nov 3, 2020 via email

@stale
Copy link

stale bot commented Nov 16, 2020

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 Issues that became stale label Nov 16, 2020
@thomasleduc
Copy link
Author

Totally agree @mrbinky3000.
It was a quick launch, and to be honest we have it on the backlog but did not find a correct way to refactor it.
Put the click on the slider would certainly work, even if it is really a shame to have to retrieve the slide clicked and compute a special function for it.

@stale stale bot removed the stale Issues that became stale label Nov 16, 2020
@azurekca
Copy link

Hi, is this issue still being investigated? I am having problems with this as well. I'm using a carousel to display a bunch of products and clicking on a product takes me to the product description. However, I don't want to navigate away from the page if the carousel is being scrolled.

I see in this commit that stopPropagation was taken out of handleOnClickCapture in Slider.jsx. How about adding another Slider prop to ask developers if they would like to stop event propagation?

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

No branches or pull requests

4 participants