Material-UI Scrollbars
Tiny React wrapper around awesome OverlayScrollbars plugin for more convenient usage with Material-UI applications. OverlayScrollbars is a javascript scrollbar plugin that hides native scrollbars, provides custom styleable overlay scrollbars, and keeps the native functionality and feeling. It enables us to implement stylish scrollbars with consistent appearance across browsers and platforms, and make our UI/UX designers happy.
Scrollable component
The Scrollable
component is just a normal div element wrapped with OverlayScrollbars
plugin. It exposes all div props, OverlayScrollbars props, and has additional 'classes' prop for granular customization.
Basic usage
import React from 'react';
import { makeStyles, Theme } from '@material-ui/core/styles';
import { Scrollable, ScrollableClasses } from '@vdjurdjevic/material-scrollbars';
const useStyles = makeStyles<Theme, keyof ScrollableClasses>({
root: {
width: 100,
height: 100,
borderStyle: 'solid',
borderWidth: '2px'
},
verticalScroll: {
width: 12,
padding: 2,
borderRadius: 4
},
track: {
background: 'green'
},
handle: {
background: 'red'
}
});
export const NiceScrollbars: React.FC = ({ children }) => {
const classes = useStyles();
return <Scrollable classes={classes}>{children}</Scrollable>;
};
Autocomplete integration
When using Scrollable
as custom ListboxComponent
of Autocomplete
, make sure to assign forwarded ref to viewPort element and also to set role to listbox
on view port element.
For that scenario, Scrollable
component exposes viewPortProps
property
import React from 'react';
import { Scrollable } from '@vdjurdjevic/material-scrollbars';
import { Autocomplete } from '@material-ui/lab';
export const AutocompleteScroll = React.forwardRef(({ children, ...rest }, ref) => {
return (
<Scrollable {...rest} viewPortProps={{ ref, role: 'listbox' }}>
{children}
</Scrollable>
);
});
export const ScrollableAutocomplete = props => {
return (
<Autocomplete
{...props}
ListboxComponent: AutocompleteScroll
/>
);
};
ScrollableTextArea component
ScrollableTextArea
shares same API with Scrollable component, but renders textarea element instead of div, and provides 'inputRef' prop that can be used to integrate with FormControl and form libraries like React Hook Form
Text field integration
import { useForm } from 'react-hook-form';
import { TextField } from '@material-ui/core';
import { ScrollableTextArea } from '@vdjurdjevic/material-scrollbars';
const { register } = useForm({
defaultValues: {
message: 'Text area with nice scrollbar'
}
});
<TextField
variant='outlined'
label='Scrollable Text Area'
name='message'
inputRef={register}
InputProps={{
inputComponent: ScrollableTextArea
}}
/>;
Hook
For accessing OverlayScrollbars instance and programmatic scrolling, there is useScrollable
hook that returns ref that can be attached to the scrollable component and has methods for scroll manipulation.
Basic usage
import React from 'react';
import { Buttom } from '@material-ui/core';
import { Scrollable, useScrollable } from '@vdjurdjevic/material-scrollbars';
export const ScrollableHookExample: React.FC = () => {
const scrollable = useScrollable();
return (
<div>
<Scrollable ref={scrollable}>Some scrollable content</Scrollable>
<Button
variant='contained'
onClick={() => scrollable.current.instance().scroll({ y: '+= 40px' })}>
Scroll
</Button>
</div>
);
};
Styling
This library has @material-ui/core
as a peer dependency and uses it's styling solution based on JSS. Unlike with plain OverlayScrollbars, with this wrapper, it's not necessary to import global stylesheet. Global styles are implemented with JSS also, so that components work out of the box, without additional setup.
Docs and Examples
Docs will improve over time, for now please use official OverlayScrollbars and Material UI Docs. If you would like to experiment with it, you can clone the repo, run yarn install
, and yarn run dev
to start storybook and use it as a playground. There are some basic examples to start with, but feel free to add yours and submit a pull request if others can benefit from it.