GithubHelp home page GithubHelp logo

Comments (12)

Norserium avatar Norserium commented on May 29, 2024 2

Anyway, I need to understand the relevance of this feature, because I assume it's not easy to implement it in a not confusing way. It's important because I'm currently busy on other projects (especially Vue-related), so I have not much time right now for this library. My resources, alas, are limited .

But I want to say thank you for your effort to resolve this issue. I appreciate it.

from react-indiana-drag-scroll.

Norserium avatar Norserium commented on May 29, 2024 1

@n0099, finally it's possible in the new major version now.

from react-indiana-drag-scroll.

n0099 avatar n0099 commented on May 29, 2024

I've made a pr that allow users to override the internal this.container field by giving an overrideRef prop, user should set overrideRef to a real scrollable element which can be exposed by the child component of <ScrollContainer>, example (not available before pr merged)

from react-indiana-drag-scroll.

Norserium avatar Norserium commented on May 29, 2024

This library is designed to be as simple as it can be. I'm not sure that it's possible to solve your problem without serious rewriting of the code.

I assume for your use case it's better to create the simple hook makeDraggable that adds scroll on mouse drag to an arbitrary element.

from react-indiana-drag-scroll.

n0099 avatar n0099 commented on May 29, 2024

This library is designed to be as simple as it can be. I'm not sure that it's possible to solve your problem without serious rewriting of the code.

The overrideRef prop should be enough to satisfy this situation.

I assume for your use case it's better to create the simple hook makeDraggable that adds scroll on mouse drag to an arbitrary element.

Do you mean set overflow: scroll style when the mouse is dragging on this.container element? But parent container doesn't have any overflowing content since they are in child wrapping elements, so setting el.scrollLeft/Top is unable to scroll into the real overflowing child element.

from react-indiana-drag-scroll.

Norserium avatar Norserium commented on May 29, 2024

Do you mean set overflow: scroll style when the mouse is dragging on this.container element?

No, I said that it's possible better to take the part of this library code and make the corresponding hook.

Anyway, I'm going to find time and test your solution to describe its advantages and disadvantages in details. I'll write later.

from react-indiana-drag-scroll.

Norserium avatar Norserium commented on May 29, 2024

@n0099, I suppose, we should proceed as follows.

You will describe your use-case entirely and I'll try to help you with solving your exact problem (perhaps without changing this library). Then I leave this issue open and we'll look at the relevance of this feature.

My skepticism about this feature is based on the idea that this library just implements the missing scroll-able by mouse component. Nothing more. You add it. You use it.

This feature tries to make this library as a tool to add the scrolling by mouse / touch to an arbitrary component. It's the different approach.

from react-indiana-drag-scroll.

n0099 avatar n0099 commented on May 29, 2024

You will describe your use-case entirely and I'll try to help you with solving your exact problem (perhaps without changing this library). Then I leave this issue open and we'll look at the relevance of this feature.

I'm making a file explorer like web app, there's a material-ui breadcrumb showing the current path on the top, it's set to no-wrap so the user will have to scroll it horizontally to see the full path.
By default there's a browser provided scrollbar when path breadcrumb is overflowed, but it's too big (on desktop chrome) and ugly without custom its appearance through ::-webkit-scroll styles, but firefox doesn't support this and it does still not get standardized in past ten years.
I also have to minus the height of scrollbar from the height of breadcrumb's container using js when the path is overflowed, to keep the container is still align to center vertically as the scrollbar doesn't display when path is short enough to fully displayed, if -webkit-overflow-scrolling style is able to use in chrome's blink, this approach isn't necessary.

So I decided to use a userland scrollbar library, such as simplebar, they are more flexible and cross-browser compatible than tweaking the browser's native scrollbar, for this they have to create multi hierarchical containers to wrap my overflowable breadcrumb in it and draw a scrollbar when overflowing.

I also want mobile user can scroll the whole breadcrumb by dragging horizontally because either simplebar or native scrollbar's default size is too small and hard to drag out the slider for mobile users. In safari and simplebar's default behavior, the scrollbar will get auto hidden when the user is not touching or dragging it, this also adds difficulty for mobile users to scroll.

Then I googled out your library, it's working fine when not using simplebar, but became unable to scroll after wrap <ScrollContainer> outside of <SimpleBar>, later I've noticed that <ScrollContainer> will only take the <Component> rendered by itself as the scrollable container, and suppose it might be overflowing, so I made that pr to solve this, but this approach introduced many new issues on mobile, see #52.

My skepticism about this feature is based on the idea that this library just implements the missing scroll-able by mouse component. Nothing more. You add it. You use it.
This feature tries to make this library a tool to add the scrolling by mouse / touch to an arbitrary component. It's the different approach.

But giving users an escape hatch to scroll any element other than <ScrollConatiner> itself is useful, especially to wrap it over other components.
If it's the user's own component, he can directly add <ScrollConatiner> into it over the right element, although this might mix other concerns into component, make component harder to reuse.
When it's an uncontrolled library component, user is unable to handle this situation since there's no escape hatch.

There's another drag to scroll library in vue environment which have a selector parameter to allow user determine any element to be scrollable.

from react-indiana-drag-scroll.

n0099 avatar n0099 commented on May 29, 2024

In this example, the accuracy scrollable element is under div[data-simplebar] > div.simplebar-wrapper > div.simplebar-mask > div.simplebar-offset > div.simplebar-content-wrapper, not the first level div[data-simplebar] which will be recognized by react-indiana-drag-scroll as store in this.container.current ref.

In fact, this.container.current will only be <ScrollContainer> itself's root element (usually a div.indiana-scroll-container), thus requiring direct child element(s) must be overflowing to scroll, aka larger than <ScrollContainer>.

from react-indiana-drag-scroll.

n0099 avatar n0099 commented on May 29, 2024

I just noticed that simplebar-react have provided a render prop (it's implement) to allow user custom it's children elements, so we can do:

<SimpleBarReact style={{ height: 300, width: 100 }}>
  {({ scrollableNodeRef, contentNodeRef }) => // unused unless u have to change the default class name (.simplebar-content-wrapper and .simplebar-content)
    <ScrollContainer className="simplebar-content-wrapper">
      <div className="simplebar-content">
        {[...Array(50)].map((x, i) => ( // long elements
          <p key={i}>{i + '_'.repeat(15 - i.toString().length * 2) + i}</p>
        ))}
      </div>
    </ScrollContainer>
  }
</SimpleBarReact>

Now the .simplebar-content-wrapper is also the <ScrollContainer>'s container so everything just works.

But it's not once and for all, not every library has provided a render prop or other methods to give the opportunity for changing its children elements, or may have but custom element hierarchy is not outward enough to get touch with the supposed scroll container, so an escape hatch is still necessary.

from react-indiana-drag-scroll.

Norserium avatar Norserium commented on May 29, 2024

@n0099, you found out the the indeed nice solution. I suppose it's better to create hook useDragScroll to make library more flexible:

import { useDragScroll } from 'react-indiana-drag-scroll';
import 'react-indiana-drag-scroll/dist/style.css';

function App() {
  const scrollableNodeRef = React.useRef();

  useDragScroll(scrollableNodeRef, {
     onScroll() {
       console.log('Container was scrolled')
     }
  });

  return (
    <div className="App">
      <h1>SimpleBar React</h1>
      <SimpleBarReact
          scrollableNodeProps={{ ref: scrollableNodeRef }}
          style={{ height: 300, width: 100 }}
      >
          {[...Array(50)].map((x, i) => (
            <p>{i + 10000000000000}</p>
          ))}
      </SimpleBarReact>
    </div>
  );
}

But even in this case it will be not the universal solution. What if you will use the library that don't give you the opportunity to pass the ref to a container? The only way in this case is using of selector, it's not the react style solution, but it's the only solution that close enough to be universal.

For example:

<ScrollContainer target=".some-class">
  ...
</ScrollContainer>

Or as an alternative:

function App() {
  const scrollableNodeRef = React.useRef();
  const { makeScrollable } = useDragScroll({
     onScroll() {
       console.log('Container was scrolled')
     }
  });
  useEffect(() => {
     if (scrollableNodeRef.current) {
        const container = scrollableNodeRef.current.querySelector('.some-class');
        if (container) {
             makeScrollable(container)
        }
     }
  }, [])

  return (
    <div className="App">
      <h1>SimpleBar React</h1>
      <SimpleBarReact
          scrollableNodeProps={{ ref: scrollableNodeRef }}
          style={{ height: 300, width: 100 }}
      >
          {[...Array(50)].map((x, i) => (
            <p>{i + 10000000000000}</p>
          ))}
      </SimpleBarReact>
    </div>
  );
}

from react-indiana-drag-scroll.

n0099 avatar n0099 commented on May 29, 2024

great work

from react-indiana-drag-scroll.

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.