react-scrollbars-custom

repository·master·Indexed 21 days ago

https://github.com/xobotyi/react-scrollbars-custom

A performant, customizable React component for consistent cross-browser custom scrollbars that maintains native scrolling behavior. It supports RTL layouts, custom renderers for HTML structure, and programmatic control via methods like scrollTo and getScrollState. Version 4.1.1 provides multiple build targets including ES3-compatible CJS/ES modules and an ES6+ version.

Tokens
10.1K
Snippets
21
Records
32
Agent score
72%

What's inside react-scrollbars-custom

  1. Understand the ScrollState Object

    master

    The getScrollState method returns a ScrollState object containing the current dimensions and positions of the content and viewport. This is useful for synchronizing UI or performing calculations based on scroll position.

    type ScrollState = {
      clientHeight: number;
      clientWidth: number;
      scrollHeight: number;
      scrollWidth: number;
      scrollTop: number;
      scrollLeft: number;
      scrollYBlocked: boolean;
      scrollXBlocked: boolean;
      scrollYPossible: boolean;
      scrollXPossible: boolean;
      trackYVisible: boolean;
      trackXVisible: boolean;
      isRTL?: boolean;
      zoomLevel: number;
    };
  2. Install react-scrollbars-custom

    master

    You can install the package using npm or yarn.

    Note on ES6+ Support: This library is written in ES6+ and provides multiple versions in its package.json:

    • main: Transpiled ES3-compatible version with CJS modules.
    • module: Transpiled ES3-compatible version with ES modules.
    • esnext: ES6+ version with ES modules.

    If you are targeting environments that require untranspiled code, you may need to configure Webpack or Babel to resolve the esnext field.

    npm install react-scrollbars-custom
    # or via yarn
    yarn add react-scrollbars-custom
  3. Customize scrollbar elements with custom renderers

    master

    You can fully customize the HTML structure, class names, or tag names by passing a custom renderer (a Stateless Functional Component) to various props.

    Important: The renderer receives a props object containing an elementRef function. You must call this function with the DOM element's reference as the first parameter and spread the remaining restProps onto the element to ensure the component functions correctly.

    <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" />;
        },
      }}
    />
  4. Basic usage of the Scrollbar component

    master

    The <Scrollbar /> component works out of the box. It uses a requestAnimationFrame loop to synchronize scrollbar updates with the browser's render flow. To use it, you must provide a width and height via the style prop or CSS.

    import { Scrollbar } from 'react-scrollbars-custom';
    
    <Scrollbar style={{ width: 250, height: 250 }}>
      <p>Hello world!</p>
    </Scrollbar>;
  5. Configure react-scrollbars-custom via Props

    master

    The react-scrollbars-custom component accepts standard HTMLDivElement props which are passed to the holder/renderer. Additionally, it provides several specialized props for controlling scrollbar behavior, appearance, and events.

    // Example of using various props
    <Scrollbars
      createContext={true}
      momentum={true}
      trackClickBehavior="step"
      minimalThumbSize={30}
      onScroll={(scrollValues, prevScrollValues) => {
        console.log('New scroll position:', scrollValues.scrollTop);
      }}
    >
      <div>Your scrollable content</div>
    </Scrollbars>
  6. Configure RTL (Right-to-Left) support

    master

    The component supports RTL direction automatically by detecting the content element's CSS on the first render. You can also explicitly control this via the rtl prop.

    Behavior details:

    • If rtl is undefined: Direction is detected automatically from the content element's CSS.
    • If rtl={true}: direction: rtl; style is applied to the content element.
    • If rtl={false}: No style is applied to the holder.
    • The rtl prop has priority over CSS or style properties.
    • Autodetection occurs on component mount, on rtl property change, or when the isRtl state is set to a non-boolean value.
    <Scrollbar rtl={true}>
      {/* Content */}
    </Scrollbar>
  7. Translate content sizes to holder

    master

    To make the scrollbar block have variable sizes, use the translateContentSize*ToHolder props (e.g., translateContentSizeWidthToHolder). This automatically translates the contentElement's sizes to the holderElement.

    Tips:

    • If using default styles, pass disableTracksWidthCompensation to avoid infinite shrinking.
    • This feature does not work in native mode.
  8. Enable native scrollbar mode

    master

    If you want to disable custom scrollbars and fallback to the browser's native scrollbars, pass the native prop. This changes the generated markup so that the root element acts as the scrollerElement (the one holding the actual browser scrollbars), while the contentElement behaves as the content holder.

    <Scrollbar native>
      {/* Content */}
    </Scrollbar>
  9. Use Scrollbar Instance Methods

    master

    The scrollbar instance provides methods to programmatically control the scroll position and retrieve the current scroll state.

    ### INSTANCE METHODS
    
    **getScrollState(force:boolean = false)** `plain object`
    Returns current scroll-related values. If `force` is true, it bypasses the cached value updated via RAF loop.
    
    **scrollToTop()** `this`  
    **scrollToLeft()** `this`  
    **scrollToBottom()** `this`  
    **scrollToRight()** `this`  
    **scrollTo(x?: number, y?: number)** `this`  
    **centerAt(x?: number, y?: number)** `this`
  10. Access Scrollbar Instance Properties

    master

    If you have access to the scrollbar instance (e.g., via elementRef or context), you can inspect the following DOM element references and scroll properties:

    ### INSTANCE PROPERTIES
    
    **eventEmitter** `Emittr`  
    **holderElement** `HTMLDivElement | null`  
    **wrapperElement** `HTMLDivElement | null`  
    **scrollerElement** `HTMLDivElement | null`  
    **contentElement** `HTMLDivElement | null`  
    **trackXElement** `HTMLDivElement | null`  
    **trackYElement** `HTMLDivElement | null`  
    **thumbXElement** `HTMLDivElement | null`  
    **thumbYElement** `HTMLDivElement | null`  
    
    (get|set) **scrollTop** `number`  
    (get|set) **scrollLeft** `number`  
    (get) **scrollHeight** `number`  
    (get) **scrollWidth** `number`  
    (get) **clientHeight** `number`  
    (get) **clientWidth** `number`
  11. Configure track click behavior

    master

    The trackClickBehavior prop determines how the scrollbar responds when a user clicks on the track (the area behind the thumb).

    Supported behaviors:

    • TRACK_CLICK_BEHAVIOR.JUMP: The scroll position jumps directly to the clicked location.
    • TRACK_CLICK_BEHAVIOR.STEP: The scroll position moves by one viewport height/width (scrolling forward or backward depending on current position).
    • Default behavior (if not specified as JUMP or STEP) typically follows the component's internal logic for stepping.
  12. Disable track mousewheel scrolling

    master

    To prevent the scrollbar tracks from responding to mouse wheel events, use the following props:

    • disableTracksMousewheelScrolling: Disables mouse wheel scrolling for both X and Y tracks.
    • disableTrackXMousewheelScrolling: Disables mouse wheel scrolling specifically for the horizontal (X) track.
    • disableTrackYMousewheelScrolling: Disables mouse wheel scrolling specifically for the vertical (Y) track.