Giter VIP home page Giter VIP logo

react-scrollbars-custom's Introduction

react-scrollbars-custom

NPM Version NPM Downloads NPM Dependents Build Coverage Types Tree Shaking

× DEMO × LIVE EXAMPLE × CHANGELOG ×

Maintainers Wanted!
If you're interested in helping with project maintenance - please contact me throgh email or twitter (links in profile)


  • Native browser scroll behavior - it don't emulate scrolling, only showing custom scrollbars, scrolling itself still native
  • Cross-browser and cross-platform - does not matter where and how, scrollbars looks the same everywhere
  • Ultimate performance - 60 FPS (using RAF) and highly optimised code
  • No extra stylesheets required - minimum inline styles out of the box or you can style it yourself however you want
  • Fully customizable - want a hippo as a scrollbar thumb? Well.. I don't judge you, you're free to do it!
  • Scrollbars nesting
  • Total tests coverage
  • Momentum scrolling for iOS
  • RTL support (read more)
  • Content sizes translation (read more)
  • Proper page zoom handling (native scrollbars does not show up)

INSTALLATION

npm install react-scrollbars-custom
# or via yarn
yarn add react-scrollbars-custom

INSTALLATION NOTE:
This lib is written in ES6+ and delivering with both, transpiled and untranspiled versions:

  • main field of package.json is pointing to transpiled ES3-compatible version with CJS modules resolution;
  • module field is pointing to transpiled ES3-compatible version with ES modules resolution;
  • esnext field is pointing to the ES6+ version with ES modules resolution;

Depending on your targets you may have to use Webpack and/or Babel to pull untranspiled version of package.
See some tips on wiring thing up: https://2ality.com/2017/06/pkg-esnext.html

USAGE

Underneath react-scrollbars-custom uses requestAnimationFrame loop, which check and update each known scrollbar, and as result - scrollbars updates synchronised with browser's render flow. The <Scrollbar /> component works out of the box, with only need of width and height to be set, inline or via CSS;

import { Scrollbar } from 'react-scrollbars-custom';

<Scrollbar style={{ width: 250, height: 250 }}>
  <p>Hello world!</p>
</Scrollbar>;

Internet Explorer

react-scrollbars-custom is syntax-compatible with IE10, but you'll have to use polyfills - for example @babel/polyfill.

Styling

Probably you'll wish to customize your scrollbars on your own way via CSS - then simply pass noDefaultStyles prop - it will prevent all inline styling from appear.
But some of styles will remain due to their need for proper component work.

Native mode

One more pretty common need is to disable custom scrollbars and fallback to native ones, it can be done by passing native prop. It'll change the generated markup:

// scrollbar.scrollerElement
<div class="ScrollbarsCustom native trackYVisible trackXVisible">
  // scrollbar.contentElement - the one that holds tour content
  <div class="ScrollbarsCustom-Content">// YOUR CONTENT IS HERE</div>
</div>

As you see here - now the root element has the scrollerElement ref, but otherwise its treated as a before (as holder). contentElement behaves as it was before.

Content sizes translation

In some situations you may want to make the scrollbars block of variable sizes - just pass translateContentSize*ToHolder prop and component will automatically translate corresponding contentElement's sizes to the holderElement.
If you are using default styles - it'll be handy to pass disableTracksWidthCompensation props, to avoid infinite shrinking when it's not supposed to.
Note: This wont work for native mode.

RTL support

react-scrollbars-custom supports RTL direction out of the box, you don't have to pass extra parameters to make it work, it'll be detected automatically on first component's render. But you still able to override it through the prop. There are several things you have to know about:

  • Due to performance reasons direction autodetect happens is 3 cases:
    • On component mount;
    • On rtl property change;
    • On state isRtl set to non-boolean value;
  • rtl property has priority over the style or CSS properties;
  • If rtl prop has not been set (undefined) - direction will be detected automatically according to content element's CSS;
  • If rtl prop is true - direction: rtl; style will be applied to hte content element;
  • If rtl prop is false - no style will be applied to holder;

Customization

In some cases you may want to change the default className or tagName of elements or add extra markup or whatever. For these purposes react-scrollbars-custom made fully customizable. You can do absolutely what ever you want y simply passing renderer SFC to the needed props.

IMPORTANT: Renderer will receive elementRef function that expect the DOM element's reference as first parameter.
Furthermore you have to pass the styles, cause they needed to proper component work.

<Scrollbar
  renderer={(props) => {
    const { elementRef, ...restProps } = props;
    return <span {...restProps} ref={elementRef} className="MyAwesomeScrollbarsHolder" />;
  }}
  wrapperProps={{
    renderer: (props) => {
      const { elementRef, ...restProps } = props;
      return <span {...restProps} ref={elementRef} className="MyAwesomeScrollbarsWrapper" />;
    },
  }}
  scrollerProps={{
    renderer: (props) => {
      const { elementRef, ...restProps } = props;
      return <span {...restProps} ref={elementRef} className="MyAwesomeScrollbarsScroller" />;
    },
  }}
  contentProps={{
    renderer: (props) => {
      const { elementRef, ...restProps } = props;
      return <span {...restProps} ref={elementRef} className="Content" />;
    },
  }}
  trackXProps={{
    renderer: (props) => {
      const { elementRef, ...restProps } = props;
      return <span {...restProps} ref={elementRef} className="TrackX" />;
    },
  }}
  trackYProps={{
    renderer: (props) => {
      const { elementRef, ...restProps } = props;
      return <span {...restProps} ref={elementRef} className="trackY" />;
    },
  }}
  thumbXProps={{
    renderer: (props) => {
      const { elementRef, ...restProps } = props;
      return <span {...restProps} ref={elementRef} className="ThUmBX" />;
    },
  }}
  thumbYProps={{
    renderer: (props) => {
      const { elementRef, ...restProps } = props;
      return <span {...restProps} ref={elementRef} className="tHuMbY" />;
    },
  }}
/>

Generated HTML

// scrollbar.holderElement
<div class="ScrollbarsCustom trackYVisible trackXVisible">
  // scrollbar.wrapperElement - the one that hiding native scrollbars
  <div class="ScrollbarsCustom-Wrapper">
    // scrollbar.scrollerElement - the one that actually has browser's scrollbars
    <div class="ScrollbarsCustom-Scroller">
      // scrollbar.contentElement - the one that holds tour content
      <div class="ScrollbarsCustom-Content">// YOUR CONTENT IS HERE</div>
    </div>
  </div>
  // scrollbar.trackYElement
  <div class="ScrollbarsCustom-Track ScrollbarsCustom-TrackY">
    // scrollbar.thumbYElement
    <div class="ScrollbarsCustom-Thumb ScrollbarsCustom-ThumbY" />
  </div>
  // scrollbar.trackXElement
  <div class="ScrollbarsCustom-Track ScrollbarsCustom-TrackX">
    // scrollbar.thumbXElement
    <div class="ScrollbarsCustom-Thumb ScrollbarsCustom-ThumbX" />
  </div>
</div>
  • If scrolling is possible or tracks are shown die to permanentScrollbar* prop - trackYVisible /trackXVisible classnames are applied to the holder element.
  • When thumb is dragged it'll have dragging classname.
  • If direction is RTL - rtl classname will be added to the holder element.
  • By default whole structure described above is rendered in spite of tracks visibility, but it can be changed by passing removeTrackXWhenNotUsed/removeTrackYWhenNotUsed /removeTracksWhenNotUsed props to the component. Respective tracks will not be rendered if it is unnecessary.

API

PROPS

You can pass any HTMLDivElement props to the component - they'll be respectfully passed to the holder element/renderer.

createContext :boolean = undefined
Whether to create context that will contain scrollbar instance reference.

rtl :boolean = undefined
true - set content's direction RTL, false - LTR, undefined - autodetect according content's style.

native :boolean = undefined
Do not use custom scrollbars, use native ones instead.

mobileNative :boolean = undefined
As native but enables only on mobile devices (actually when the scrollbarWidth is 0).

momentum :boolean = true
Whether to use momentum scrolling, suitable for iOS (will add -webkit-overflow-scrolling: touch to the content element).

noDefaultStyles :boolean = undefined
Whether to use default visual styles.
Note: Styles needed to proper component work will be passed regardless of this option.

disableTracksMousewheelScrolling :boolean = undefined
Disable content scrolling while preforming a wheel event over the track.

disableTrackXMousewheelScrolling :boolean = undefined
Disable content scrolling while preforming a wheel event over the track.

disableTrackYMousewheelScrolling :boolean = undefined
Disable content scrolling while preforming a wheel event over the track.

disableTracksWidthCompensation :boolean = undefined
Disable both vertical and horizontal wrapper indents that added in order to not let tracks overlay content. Note: Works only with default styles enabled.

disableTrackXWidthCompensation :boolean = undefined
Disable horizontal wrapper indents that added in order to not let horizontal track overlay content. Note: Works only with default styles enabled.

disableTrackYWidthCompensation :boolean = undefined
Disable vertical wrapper indents that added in order to not let vertical track overlay content. Note: Works only with default styles enabled.

minimalThumbSize :number = 30
Minimal size of both, vertical and horizontal thumbs. This option has priority to minimalThumbXSize/minimalThumbYSize props.

maximalThumbSize :number = undefined
Maximal size of both, vertical and horizontal thumbs. This option has priority to maximalThumbXSize/maximalThumbYSize props.

minimalThumbXSize :number = undefined
Minimal size of horizontal thumb.

maximalThumbXSize :number = undefined
Maximal size of horizontal thumb.

minimalThumbYSize :number = undefined
Minimal size of vertical thumb.

maximalThumbYSize :number = undefined
Maximal size of vertical thumb.

noScroll :boolean = undefined
Whether to disable both vertical and horizontal scrolling.

noScrollX :boolean = undefined
Whether to disable horizontal scrolling.

noScrollY :boolean = undefined
Whether to disable vertical scrolling.

permanentTracks :boolean = undefined
Whether to display both tracks regardless of scrolling ability.

permanentTrackX :boolean = undefined
Whether to display horizontal track regardless of scrolling ability.

permanentTrackY :boolean = undefined
Whether to display vertical track regardless of scrolling ability.

removeTracksWhenNotUsed :boolean = undefined
Whether to remove both vertical and horizontal tracks if scrolling is not possible/blocked and tracks are not permanent.

removeTrackYWhenNotUsed :boolean = undefined
Whether to remove vertical track if scrolling is not possible/blocked and tracks are not permanent.

removeTrackXWhenNotUsed :boolean = undefined
Whether to remove horizontal track if scrolling is not possible/blocked and tracks are not permanent.

translateContentSizesToHolder :boolean = undefined
Pass content's scrollHeight and scrollWidth values to the holder's height and width styles. Not working with native behavior.

translateContentSizeYToHolder :boolean = undefined
Pass content's scrollHeight values to the holder's height style. Not working with native behavior.

translateContentSizeXToHolder :boolean = undefined
Pass content's scrollWidth values to the holder's width style. Not working with native behavior.

trackClickBehavior :string = "jump"
The way scrolling behaves while user clicked the track:

  • jump - will cause straight scroll to the respective position.
  • step - will cause one screen step towards (like PageUp/PageDown) the clicked position.

scrollbarWidth :number = undefined
Scrollbar width value needed to proper native scrollbars hide. While undefined it is detected automatically (once per module require).
This prop is needed generally for testing purposes.

fallbackScrollbarWidth :number = 20
This value will be used in case of falsy scrollbarWidth prop. E.g. it is used for mobile devices, because it is impossible to detect their real scrollbar width (due to their absolute positioning).

scrollTop :number = undefined
Prop that allow you to set vertical scroll.

scrollLeft :number = undefined
Prop that allow you to set horizontal scroll.

scrollDetectionThreshold :number = 100
Amount of seconds after which scrolling will be treated as completed and scrollStop event emitted.

elementRef :function(ref: Scrollbar) = undefined
Function that receive the scrollbar instance as 1st parameter.

renderer :SFC = undefined
SFC used to render the holder. More about renderers usage.

wrapperProps :object = {}
Here you can pass any props for wrapper, which is usually HTMLDivElement plus elementRef props which behaves as holder's elementRef prop.

contentProps :object = {}
Here you can pass any props for content, which is usually HTMLDivElement plus elementRef props which behaves as holder's elementRef prop.

trackXProps :object = {}
Here you can pass any props for trackX, which is usually HTMLDivElement plus elementRef props which behaves as holder's elementRef prop.

trackYProps :object = {}
Here you can pass any props for trackY, which is usually HTMLDivElement plus elementRef props which behaves as holder's elementRef prop.

thumbXProps :object = {}
Here you can pass any props for thumbX, which is usually HTMLDivElement plus elementRef props which behaves as holder's elementRef prop.

thumbYProps :object = {}
Here you can pass any props for thumbY, which is usually HTMLDivElement plus elementRef props which behaves as holder's elementRef prop.

onUpdate :function(scrollValues: ScrollState, prevScrollValues: ScrollState) = undefined
Function called each time any of scroll values changed and component performed an update. It is called after component's update.

onScroll :function(scrollValues: ScrollState, prevScrollValues: ScrollState) = undefined
Function called each time scrollTop or scrollLeft has changed. It is called after component's update and even if scrollTop/scrollLeft has been changed through the code (not by user).

onScrollStart :function(scrollValues: ScrollState) = undefined
Callback that called immediately when user started scrolling (no matter how, thumb dragging, keyboard, mousewheel and etc.).

onScrollStop :function(scrollValues: ScrollState) = undefined Callback that called after props.scrollDetectionThreshold milliseconds after last scroll event.

INSTANCE PROPERTIES

eventEmitter :Emittr
Event emitter that allow you to add events handler for cases when you access Scrollbars through context

holderElement :HTMLDivElement | null
Holder DOM element reference or null if element was not rendered

wrapperElement :HTMLDivElement | null
Wrapper DOM element reference or null if element was not rendered

scrollerElement :HTMLDivElement | null
Scroller DOM element reference or null if element was not rendered

contentElement :HTMLDivElement | null
Content DOM element reference or null if element was not rendered

trackXElement :HTMLDivElement | null
Horizontal track DOM element reference or null if element was not rendered

trackYElement :HTMLDivElement | null
Vertical track DOM element reference or null if element was not rendered

thumbXElement :HTMLDivElement | null
Horizontal thumb DOM element reference or null if element was not rendered

thumbYElement :HTMLDivElement | null
Vertical thumb DOM element reference or null if element was not rendered

(get|set) scrollTop :number
Content's element scroll top

(get|set) scrollLeft :number
Content's element scroll left

(get) scrollHeight :number
Content's element scroll height

(get) scrollWidth :number
Content's element scroll width

(get) clientHeight :number
Content's element client height

(get) clientWidth :number
Content's element client width

INSTANCE METHODS

getScrollState(force:boolean = false) :plain object Current scroll-related values, if force parameter is falsy - returns cached value which updated with RAF loop Returned values:

type ScrollState = {
  /**
   * @description Content's native clientHeight parameter
   */
  clientHeight: number;
  /**
   * @description Content's native clientWidth parameter
   */
  clientWidth: number;
  /**
   * @description Content's native scrollHeight parameter
   */
  scrollHeight: number;
  /**
   * @description Content's native scrollWidth parameter
   */
  scrollWidth: number;
  /**
   * @description Content's native scrollTop parameter
   */
  scrollTop: number;
  /**
   * @description Content's native scrollLeft parameter
   */
  scrollLeft: number;
  /**
   * @description Indicates whether vertical scroll blocked via properties
   */
  scrollYBlocked: boolean;
  /**
   * @description Indicates whether horizontal scroll blocked via properties
   */
  scrollXBlocked: boolean;
  /**
   * @description Indicates whether the content overflows vertically and scrolling not blocked
   */
  scrollYPossible: boolean;
  /**
   * @description Indicates whether the content overflows horizontally and scrolling not blocked
   */
  scrollXPossible: boolean;
  /**
   * @description Indicates whether vertical track is visible
   */
  trackYVisible: boolean;
  /**
   * @description Indicates whether horizontal track is visible
   */
  trackXVisible: boolean;
  /**
   * @description Indicates whether display direction is right-to-left
   */
  isRTL?: boolean;

  /**
   * @description Pages zoom level - it affects scrollbars
   */
  zoomLevel: number;
};

scrollToTop() :this
Scroll to the very top border of scrollable area

scrollToLeft() :this
Scroll to the very left border of scrollable area

scrollToBottom() :this
Scroll to the very bottom border of scrollable area

scrollToRight() :this
Scroll to the very right border of scrollable area

scrollTo(x?: number, y?: number) :this
Set the current scroll at given coordinates. If any value is undefined it'll be left as is.

centerAt(x?: number, y?: number) :this
Center viewport at given coordinates. If any value is undefined it'll be left as is.

react-scrollbars-custom's People

Contributors

aravindballa avatar art-smi avatar dependabot[bot] avatar enomado avatar eugene-ilyin avatar jan-grzegorowski-equinix avatar konekoya avatar newsiberian avatar semantic-release-bot avatar teddriggs avatar xobotyi avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

react-scrollbars-custom's Issues

Live usage example

Hi, despite documentation in README it is always nice to have some live example. I know about DEMO but I don't know any easy way to view React source code, so I've made a minimal example based on your testbench code and my current knowledge.

https://codesandbox.io/s/38k0kxmp75

Feel free to improve it, add it to the README, or ignore this idea. Ideally, I would like to have DEMO page sources to check how to implement presented features.

Dom CSS is not a function using enzyme's mount

Do you want to request a feature or report a bug?
Report a bug
What is the current behavior?

I am trying to test the component with the enzyme's mount but it returns the following error:

TypeError: (0 , _domCss2.default) is not a function

If the current behavior is a bug, please provide the steps to reproduce and if possible a minimal demo of the problem. Paste the link to your JSFiddle (https://jsfiddle.net/Luktwrdm/) or CodeSandbox (https://codesandbox.io/s/new) example below:

import { mount } from 'enzyme';

const mountSubject = () =>
	mount(<React.Fragment>
				<div className="hierarchy-tree-selection-wrapper">
					<Scrollbar
						autoHide={true}
						autoHideTimeout={1000}
						autoHideDuration={200}
						renderThumbHorizontal={this.renderThumb}
						renderThumbVertical={this.renderThumb}
					>
						<div className="hierarchy-tree-selection">{this.files}</div>
					</Scrollbar>
				</div>
			</React.Fragment>
 );

it('should mount hierarchy', () => {
		const renderedComponent = mountSubject();
		const nodes = renderedComponent.find('.component-mode');
		expect(nodes.length).toEqual(12);
	});

What is the expected behavior?
Mount the component

Which versions of library, and which browser / OS are affected by this issue? Did this work in previous versions of library?

react-scrollbars-custom: 3.1.5. I am running it with Jest. I tried to downgrade versions but does not worked.

IE Issue.

Cannot open the demo link in IE 11. Getting "Syntax error" in console same as when I tried adding it to my project.

ie_issue

Problem with SSR

Awesome component.
Problem is, it throws when rendered server-side with document is not defined.
You cannot use isset to check for undefined when the variable does not exist.

#23 - a pull request that resolves the issue

Some props error as not existing

Screen Shot 2019-04-05 at 11 57 06 AM

The props I am having trouble with are:

ScrollToTop (is this the same as scrollTop?)
ScrollToBottom
onScrollStop (is apparently called onScrollEnd mismatch in docs)
wrapperRenderer
trackYRenderer
trackXRenderer
thumbYRenderer
thumbXRenderer
contentRenderer

Native scroll bars become visible when zoomed out

I noticed some ugly white lines in my dark-themed app. (Tested in chrome Version 73.0.3683.86) Seemed the scroll bars were poking into the components, not being fully hidden by the padding. I edited my styles to add a few pixels of padding - but they seemed to appear randomly.

Just realized why. The scroll bars, in chrome at least, are sized independent to the web page's zoom field. This means the 17px of padding to hide the native scroll bars only works on 100%. If you zoom out, the 17px scales, but the scroll bars don't.

You can reproduce it on the Demo page by zooming out a little:

image

It's not much of an issue if you've got a pale background as they blend in until zoom levels that are just silly. But in dark apps (probably a major reason for styling scroll bars to begin with!) even a tiny bit of the scroll bar sticks out like a sore thumb.

Not sure if the 17px could be converted to a zoom-independent CSS unit?

[v4] Missing wrapper element with display: inline-block

Please correct me if I'm wrong but based on the official demo and my own example I see that there is a need for one more wrapper element with display: inline-block style. Without that missing element, content seems to not respect the padding-right style on the absolutely positioned parent element.

Here is my fixed example:
https://codesandbox.io/s/1wrx623273

Before fix (current state):
Screen Shot 2019-04-29 at 10 39 38

With additional wrapper:
Screen Shot 2019-04-29 at 10 40 06

This wrapper element might be a part of a library as it won't work correctly without it. Please tell me what do you think about that idea.

3.0 SSR regression

getScrollbarWidth crashes on Node.js because of let doc = document; on line 2

Pull request - #27

trackXVisible class presented even if horizontal scrolling is unavailable

Do you want to request a feature or report a bug?
bug

What is the current behavior?
trackXVisible class presented even if horizontal scrolling is unavailable

What is the expected behavior?
trackXVisible class should be presented only if horizontal scrollbar is visible

Which versions of library, and which browser / OS are affected by this issue? Did this work in previous versions of library?
3.1.5

Detecting when scroll has reached the bottom

I'm using react-custom-scrollbars in my project, but I have just come across this project and the performance looks great! I've tried to migrate to the library, but I've hit one snag:

I am trying to detect when the user has scrolled to the bottom of the panel using the onScroll prop. Is there enough information in the scrollValues object to work this out?

Enabling permanentScrollbar shouldn't cause thumb to disappear

In the demo, enable "always show track", and note that the thumb disappears despite the fact that the content is scrollable.

Root Cause

L716 refers to scrollY, which isn't a real property. It appears that it was supposed to be referencing noScrollY. The same is true for the horizontal property.

Is there a way to make this work with max-height?

I don't want to have a fixed height, just a max-height. My goal is to create a dropdown list selector which is only as big as it needs to be (depending on how many items it has). But then after reaching a certain max height will display scrollbars. I see this component is already smart enough to only show scrollbars when it needs to. But I don't know how to get it to work with a height based on it's children.

Bonus: Would be cool if it were possible to make is scroll after a certain number of children.

E.g. maxHeight={350} or numChildrenBeforeScroll={5} using whichever comes first.

Momentum missing on mobile

Native scrolling on iOS Safari applies a momentum effect after the touch is released, but this component currently stops as soon as the touch ends. This makes scrolling feel slower with this component when compared to native behavior.

"scroll" event listener appears to leak

In Scrollbar.addListeners, a passive event listener is added on the scroll event. There is no corresponding call to removeEventListener in Scrollbar.removeListeners. I believe that this will cause duplicate handlers to get attached every time noScroll changes from true to false. Per MDN, this will not cause duplicate listeners (source), but it will cause a slow leak.

v3.0 wrapperEl is not defined

v3.0 wrapperEl is not defined

that could be because I'm using a custom wrapperRenderer and maybe did something wrong

really cool rework btw!

nativeScrollbars not functioning

After putting nativeScrollbars prop onto <Scrollbar nativeScrollbars /> and setting it to true, I get the standard react warning:

React does not recognize the 'nativeScrollbars' prop on a DOM element.

Also, setting the prop to true doesn't change the scrollbars to be native, unless there is something I'm missing?

Scroll thumb should not overrun track for negative scroll values

On Safari in the demo, scroll sideways on the "Custom Style" block with finger or trackpad, making sure to keep scrolling past the end of the content.

Expected: The thumb should be stopped at the end of the track. Best case, the length of the thumb shrinks proportional to the overrun, like the native iOS scroll bar.

Observed: The thumb keeps going past the end of the track.

IE support?

Do you want to request a feature or report a bug?
feature
What is the current behavior?
I can't open demo sites in IE (11, 10, 9), does that mean react-scrollbars-custom cannot work in IE? I've tried to use react-scrollbars-custom in my project, but it seems not work well in IE: the width of thumb-x is 0 unless I click the track-x, even after I click the track, the width is still incorrect - smaller than it should be.
If the current behavior is a bug, please provide the steps to reproduce and if possible a minimal demo of the problem. Paste the link to your JSFiddle (https://jsfiddle.net/Luktwrdm/) or CodeSandbox (https://codesandbox.io/s/new) example below:

What is the expected behavior?

Which versions of library, and which browser / OS are affected by this issue? Did this work in previous versions of library?
3.1.5

Warning

Hi,

I get the following warning with the latest alpha (17):

Warning: React does not recognize the compensateScrollbarsWidthprop on a DOM element. If you intentionally want it to appear in the DOM as a custom attribute, spell it as lowercasecompensatescrollbarswidth instead. If you accidentally passed it from a parent component, remove it from the DOM element.

In version v4.0.0alpha13 i did not get this error. Dit anything change?

This is the implementation i'm using:

<Scrollbar
   style={{width: '100%', height: '100%'}}
   ref={ref=>{this.scrollbar = ref}} 
   noScrollX
   trackYProps={{
         renderer: props => {
                    const { elementRef, style, ...restProps } = props;
                     return <div {...restProps} ref={elementRef} style={{...style, width: '5px', top: '3px', height: 'calc(100% - 3px)', background: 'rgba(179, 179, 179, 0.1)'}} />;
         }
   }}
   thumbYProps={{
        renderer: props => {
               const {elementRef, style, ...restProps } = props;
               return <div {...restProps} ref={elementRef} style={{...style, background: 'rgba(0, 0, 0, 0.1)'}} />;
       }
   }}
>
     <Content />
</Scrollbar>```

Add option for track click to move one page towards pointer

In macOS and Ubuntu, clicking on the scrollbar track doesn't center the thumb at the click point. Instead, it moves the thumb one length toward the click point.

Other apps, like VS Code, have the jump-to-click point, so I don't think the behavior should be changed unconditionally. Instead, I'd propose adding a new prop, trackClickBehavior, which is "jump" | "step", with "jump" being the default.

Use overflow: auto instead of scroll

overflow: scroll forces the default scrollbar to be visible at all times, while overflow: auto only shows it when needed.

Too few items to fill whole area:
screenshot_20181018_103703

Enough items to fill the area:
screenshot_20181018_103732

Markup:

<div className="container">
    <Scrollbar style={{ width: '100%', height: '100%', minHeight: 80 }}>
        {...items}
    </Scrollbar>
</div>

Styles:

.container {
    width: 300px;
    height: 300px;
}

Typo in the package name

Hey,
It looks like you forgot a s in the name if the package:
it should be react-scrollbars-custom instead of react-scrollbar-custom

right to left support?

Hi man,

Great library! Really excited about v2.

Any chance you add right-to-left support?

I'm trying to achieve the following effect and I think generic RTL support would be the correct way.

image

Hide the scrollbar thumb after few seconds of inactivity

Do you want to request a feature or report a bug?
Request a feature

What is the current behavior?
The API does not provide a way to hide the scrollbar thumb after inactivity. This is the default behavior for some browsers (on mac OS), the scrollbar is hidden when not used, once you scroll it's visible again.

What is the expected behavior?
Provide a prop to enable this hidding behavior.. And we may also have a property to set the timer after which the scrollbar thumb should appear / disappear.

Thumb hidden on resize.

On resizing the container when there is no scroll the track and thumb gets hidden but on reverting the thumb still has a "display: 'none'" on it's inline. This happens only in IE, works fine in chrome.

customizing with trackXRenderer doesn't work because elementRef is missing in props

Hi, this is a great tool, but I can't seem to figure out how to make the custom render for trackX work. When I get the props like in the example:
trackXRenderer={ props => { const {elementRef, ...restProps} = props; return <span {...restProps} className="MyAwesomeTrackVertical" ref={elementRef}/> } }
props only has children, className, onClick, and style, with no elementRef. As a result the scroll doesn't function.

When I look in the code under dist/Track.js, I see this:
props = _objectWithoutProperties(_this$props, ["className", "renderer", "type", "elementRef", "onClick"]); props.className = "track " + (type === TYPE_X ? "trackX" : "trackY") + (className ? " " + className : ""); props.onClick = this.onClickHandler; return renderer ? renderer(props) : _react.default.createElement("div", _extends({}, props, {

It's clearly stripping out the elementRef property before calling my custom render function.

Is this by design? Am I meant to somehow implement the custom render without the elementRef property?

Thanks,

Nathan

Invalid value for prop `renderer`

I have an error with my customization (version 4.0.0-alpha.13):
Invalid value for prop renderer on <div> tag. Either remove it from the element, or pass a string or number value to keep it in the DOM.

Did you know to fix this?

Sample code of my component:
wrapperProps={{ renderer: (props) => { const { elementRef, ...restProps } = props; return <div ref={elementRef} {...restProps} className={classes.wrapper}/>; }, }}

Content no longer has size in 4.0.0-alpha

After upgrading from 3.1.5 to 4.0.0-alpha.18 content within <Scrollbars/> no longer has the size of the container. This squashed a lot of components that were designed to expand to fill the available width, which I worked around by adding:

contentProps={{ style: {'min-width': '100%'} }}

Old ScrollbarsCustom styles: position: relative; display: flex; and flexed children.

New ScrollbarsCustom styles: position: relative; width: 100%; height: 100%; and ScrollbarsCustom-Content styles: display: inline-block; vertical-align: bottom; (losing the height and width).

Scroll container doesn't shrink when contents shrink

Using 4.0.0-alpha.12
This is roughly what I am doing:

<Scrollbar
  translateContentSizesToHolder={true}
  style={{
    maxWidth: '100%',
    maxHeight: '300px',
  }}
  noScrollX={true}
>
  // test div
  <div style={{width: '100%', height: '300px'}} />
</Scrollbar>

Initially everything looks fine, but if I change the height of the test div to be 100px (for example) the vertical scrollbar disappears as expected but the scroll container retains a 300px height and does not shrink to match the size of its children.

When I inspect what's happening in the browser I notice that the scroll container has a height of 305px, which seems to create a little gap at the bottom. Not sure where that 5px extra is coming from

Enabling maximalThumbsSize prop

Do you want to request a feature or report a bug?
Request a feature

What is the current behavior?
The API does not provide a way to pass maximalThumbsSize as props.
It could be really helpful for UI reasons (sometimes the size of your scrollbar almost fit its track container size)

What is the expected behavior?
Provide the maximalThumbsSize prop. Given that maximalThumbsSize, the scrollbar should change the way the position is computed (I guess).

Expose getBoundingClientRect

Expose getBoundingClientRect or something similar that returns the entire component position. At the moment, since the component is a class, you can't get the rendered component position.

I had to encapsulate my component on a

so I can get it's relative position in my page.

User-provided styles should overrule default styles

Consider the following code:

<Scrollbar trackVerticalStyle={{ background: 'rgba(0, 0, 0, 0)' }}><p>Hello world</p></Scrollbar>

In this case, I'd expect the track to render with no color, making it effectively invisible while still showing the thumb. However, the default style overrules my customization, which means it's impossible to change the color of the track without turning off all default styles, which is overkill.

This can be addressed by flipping the order of the spreads in index.js so that the user provided styles - if they exist - are applied after the defaults but before the styles that are necessary for the library to work.

This change shouldn't be hard, but I'm waiting for a decision on #18 before pushing the PR.

Overlay vs block

Is it possible to have the scrollbars be an overlay on top of the contained content, rather than taking up space from the container?

This would be similar to how macOS handles scrollbars where the scrollbars are transparent (excluding the actual handle).

Add .prettierrc file

This is a minor dev quality-of-life issue; the code formatting at the moment isn't standard and as a result any attempt to auto-format will try to change the entire index.js file. Adding a config for prettier and running auto-formatting would make it easier for others to contribute to the library.

Horizontal scrollbar wrong position

I created a container div that contains a number of elements wrapped by and has to be scrolled horizontally.

It works fine on google chrome (mobile/laptop), but on safari (laptop + mobile ios12) the horizontal scrollbar starts in the middle which makes the scroll feel off.

In both images, the scroll is at the very left (the start).
Chrome:
image

Safari:
bug safari

Clicking on the scrollbar (not the thumb) scrolls to the right position in the container.
Clicking on the srollbar thumb to drag (or on mobile, using finger to scroll) moves weirdly. The scrollbar thumb halves because it seems to think we're in the middle the second I move a bit to the left or right.

Smooth Scroll

Is it possible to implement smooth scroll like in https://github.com/souhe/reactScrollbar?

That component is VERY inneficient and triggers a lot of re-renders, so we are dropping it in place of yours. But my designer would like to have smooth scrolling on some places because we are "emulating" a mobile app.

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.