Search code examples
javascriptcssreactjsmaterial-uimaterial-table

How to add a fancy scroll-bar on react material-table?


I'm using react material-table and want a decent scroll-bar instead of default Pagination. I have tried react-custom-scroll but it's not working as per my intention. The default scroll-bar of my App is activated. One more thing, how can I just apply this type of scroll on just the table body?

import CustomScroll from 'react-custom-scroll';
.
.
.

<div style={{height:"50vh"}}>
  <CustomScroll heightRelativeToParent="100%">

    <MaterialTable
    .
    .
    options={{
          search: true,
          paging: false,
          toolbarButtonAlignment: "left",
          searchAutoFocus: true,
        }}
    .
    />
  </CustomScroll>  
</div>

Solution

  • Without using CustomScroll, you can do this by setting minimum(minBodyHeight) and maximum(maxBodyHeight) viewport height in the options like this:

    import React from 'react';
    
    import MaterialTable, { MTableToolbar } from 'material-table';
    
    import { Grid } from '@material-ui/core';
    
    export default function App() {
    
      return (
        <MaterialTable
          options={{
            search: true,
            paging: false,
            toolbarButtonAlignment: "left",
            searchAutoFocus: true,
            minBodyHeight: "85vh",
            maxBodyHeight: "85vh"
          }}
          title="Toolbar Overriding Preview"
          columns={[
            { title: 'Name', field: 'name' },
            { title: 'Surname', field: 'surname' },
            { title: 'Birth Year', field: 'birthYear', type: 'numeric' },
            { title: 'Birth City', field: 'birthCity', type: 'numeric' }
          ]}
          data={[
            { name: 'Mehmet', surname: 'Baran', birthYear: 1987, birthCity: 63 },
            { name: 'Mehmet', surname: 'Baran', birthYear: 1987, birthCity: 63 },
            { name: 'Mehmet', surname: 'Baran', birthYear: 1987, birthCity: 63 },
            { name: 'Mehmet', surname: 'Baran', birthYear: 1987, birthCity: 63 },
            { name: 'Mehmet', surname: 'Baran', birthYear: 1987, birthCity: 63 },
            { name: 'Mehmet', surname: 'Baran', birthYear: 1987, birthCity: 63 },
            { name: 'Mehmet', surname: 'Baran', birthYear: 1987, birthCity: 63 },
            { name: 'Mehmet', surname: 'Baran', birthYear: 1987, birthCity: 63 },
            { name: 'Mehmet', surname: 'Baran', birthYear: 1987, birthCity: 63 },
            { name: 'Mehmet', surname: 'Baran', birthYear: 1987, birthCity: 63 },
            { name: 'Zerya Betül', surname: 'Baran', birthYear: 2017, birthCity: 34 },
            { name: 'Zerya Betül', surname: 'Baran', birthYear: 2017, birthCity: 34 },
            { name: 'Zerya Betül', surname: 'Baran', birthYear: 2017, birthCity: 34 },
            { name: 'Zerya Betül', surname: 'Baran', birthYear: 2017, birthCity: 34 },
            { name: 'Zerya Betül', surname: 'Baran', birthYear: 2017, birthCity: 34 },
            { name: 'Zerya Betül', surname: 'Baran', birthYear: 2017, birthCity: 34 },
            { name: 'Zerya Betül', surname: 'Baran', birthYear: 2017, birthCity: 34 },
            { name: 'Zerya Betül', surname: 'Baran', birthYear: 2017, birthCity: 34 },
            { name: 'Zerya Betül', surname: 'Baran', birthYear: 2017, birthCity: 34 },
            { name: 'Zerya Betül', surname: 'Baran', birthYear: 2017, birthCity: 34 },
          ]}
          components={{
            Toolbar: props => {
              // This will let you use your own Title while keeping the search
              const propsCopy = { ...props };
              // Hide default title
              propsCopy.showTitle = false;
              return (
                <Grid container direction="row">
                  <Grid item xs={6}>
                    <h2>Your Own Title</h2>
                  </Grid>
                  <Grid item xs={6}>
                    <MTableToolbar {...propsCopy} />
                  </Grid>
                </Grid>
              );
            }
          }}
        />
      )
    }
    

    Update:

    Install react-custom-scrollbars.

    Save this code into the same directory as test.css file:

    .App {
        height: 800px;
    }
    

    Then follow the code below:

    import React from 'react';
    
    import MaterialTable, { MTableToolbar } from 'material-table';
    
    import { Grid } from '@material-ui/core';
    
    import { Scrollbars } from 'react-custom-scrollbars';
    
    import './test.css';
    
    const renderThumb = ({ style, ...props }) => {
      const thumbStyle = {
        borderRadius: 6,
        backgroundColor: 'rgba(35, 49, 86, 0.8)'
      };
      return <div style={{ ...style, ...thumbStyle }} {...props} />;
    };
    
    const CustomScrollbars = props => (
      <Scrollbars
        renderThumbHorizontal={renderThumb}
        renderThumbVertical={renderThumb}
        {...props}
      />
    );
    
    export default function App() {
    
      return (
        <div className="App">
    
          <CustomScrollbars>
    
            <MaterialTable
              options={{
                search: true,
                paging: false,
                toolbarButtonAlignment: "left",
                searchAutoFocus: true,
              }}
              title="Toolbar Overriding Preview"
              columns={[
                { title: 'Name', field: 'name' },
                { title: 'Surname', field: 'surname' },
                { title: 'Birth Year', field: 'birthYear', type: 'numeric' },
                { title: 'Birth City', field: 'birthCity', type: 'numeric' }
              ]}
              data={[
                { name: 'Mehmet', surname: 'Baran', birthYear: 1987, birthCity: 63 },
                { name: 'Mehmet', surname: 'Baran', birthYear: 1987, birthCity: 63 },
                { name: 'Mehmet', surname: 'Baran', birthYear: 1987, birthCity: 63 },
                { name: 'Mehmet', surname: 'Baran', birthYear: 1987, birthCity: 63 },
                { name: 'Mehmet', surname: 'Baran', birthYear: 1987, birthCity: 63 },
                { name: 'Mehmet', surname: 'Baran', birthYear: 1987, birthCity: 63 },
                { name: 'Mehmet', surname: 'Baran', birthYear: 1987, birthCity: 63 },
                { name: 'Mehmet', surname: 'Baran', birthYear: 1987, birthCity: 63 },
                { name: 'Mehmet', surname: 'Baran', birthYear: 1987, birthCity: 63 },
                { name: 'Mehmet', surname: 'Baran', birthYear: 1987, birthCity: 63 },
                { name: 'Zerya Betül', surname: 'Baran', birthYear: 2017, birthCity: 34 },
                { name: 'Zerya Betül', surname: 'Baran', birthYear: 2017, birthCity: 34 },
                { name: 'Zerya Betül', surname: 'Baran', birthYear: 2017, birthCity: 34 },
                { name: 'Zerya Betül', surname: 'Baran', birthYear: 2017, birthCity: 34 },
                { name: 'Zerya Betül', surname: 'Baran', birthYear: 2017, birthCity: 34 },
                { name: 'Zerya Betül', surname: 'Baran', birthYear: 2017, birthCity: 34 },
                { name: 'Zerya Betül', surname: 'Baran', birthYear: 2017, birthCity: 34 },
                { name: 'Zerya Betül', surname: 'Baran', birthYear: 2017, birthCity: 34 },
                { name: 'Zerya Betül', surname: 'Baran', birthYear: 2017, birthCity: 34 },
                { name: 'Zerya Betül', surname: 'Baran', birthYear: 2017, birthCity: 34 },
              ]}
              components={{
                Toolbar: props => {
                  // This will let you use your own Title while keeping the search
                  const propsCopy = { ...props };
                  // Hide default title
                  propsCopy.showTitle = false;
                  return (
                    <Grid container direction="row">
                      <Grid item xs={6}>
                        <h2>Your Own Title</h2>
                      </Grid>
                      <Grid item xs={6}>
                        <MTableToolbar {...propsCopy} />
                      </Grid>
                    </Grid>
                  );
                }
              }}
            />
          </CustomScrollbars>
        </div>
      )
    }
    

    Update 2

    This is another way you can add a scrollbar on the table body, for that you've to override the table body component, if you do that body will be messed up with the header. That's why you've to override the table header as well and do some styling. Here is the code:

    import React from 'react';
    
    import MaterialTable, { MTableToolbar, MTableBody, MTableHeader } from 'material-table';
    
    import { Grid } from '@material-ui/core';
    
    import { Scrollbars } from 'react-custom-scrollbars';
    
    const renderThumb = ({ style, ...props }) => {
      const thumbStyle = {
        borderRadius: 6,
        backgroundColor: 'rgba(35, 49, 86, 0.8)'
      };
      return <div style={{ ...style, ...thumbStyle }} {...props} />;
    };
    
    const CustomScrollbars = props => (
      <Scrollbars
        renderThumbHorizontal={renderThumb}
        renderThumbVertical={renderThumb}
        {...props}
      />
    );
    
    export default function App() {
    
      return (
    
        <MaterialTable
    
          options={{
            search: true,
            paging: false,
            toolbarButtonAlignment: "left",
            searchAutoFocus: true,
            cellStyle: { minWidth: '100px', maxWidth: '100px' },
          }}
          title="Toolbar Overriding Preview"
          columns={[
            { title: 'Name', field: 'name' },
            { title: 'Surname', field: 'surname' },
            { title: 'Birth Year', field: 'birthYear', type: 'numeric' },
            { title: 'Birth City', field: 'birthCity', type: 'numeric' }
          ]}
          data={[
            { name: 'Mehmet', surname: 'Baran', birthYear: 1987, birthCity: 63 },
            { name: 'Mehmet', surname: 'Baran', birthYear: 1987, birthCity: 63 },
            { name: 'Mehmet', surname: 'Baran', birthYear: 1987, birthCity: 63 },
            { name: 'Mehmet', surname: 'Baran', birthYear: 1987, birthCity: 63 },
            { name: 'Mehmet', surname: 'Baran', birthYear: 1987, birthCity: 63 },
            { name: 'Mehmet', surname: 'Baran', birthYear: 1987, birthCity: 63 },
            { name: 'Mehmet', surname: 'Baran', birthYear: 1987, birthCity: 63 },
            { name: 'Mehmet', surname: 'Baran', birthYear: 1987, birthCity: 63 },
            { name: 'Mehmet', surname: 'Baran', birthYear: 1987, birthCity: 63 },
            { name: 'Mehmet', surname: 'Baran', birthYear: 1987, birthCity: 63 },
            { name: 'Zerya Betül', surname: 'Baran', birthYear: 2017, birthCity: 34 },
            { name: 'Zerya Betül', surname: 'Baran', birthYear: 2017, birthCity: 34 },
            { name: 'Zerya Betül', surname: 'Baran', birthYear: 2017, birthCity: 34 },
            { name: 'Zerya Betül', surname: 'Baran', birthYear: 2017, birthCity: 34 },
            { name: 'Zerya Betül', surname: 'Baran', birthYear: 2017, birthCity: 34 },
            { name: 'Zerya Betül', surname: 'Baran', birthYear: 2017, birthCity: 34 },
            { name: 'Zerya Betül', surname: 'Baran', birthYear: 2017, birthCity: 34 },
            { name: 'Zerya Betül', surname: 'Baran', birthYear: 2017, birthCity: 34 },
            { name: 'Zerya Betül', surname: 'Baran', birthYear: 2017, birthCity: 34 },
            { name: 'Zerya Betül', surname: 'Baran', birthYear: 2017, birthCity: 34 },
          ]}
          components={{
            Toolbar: props => {
              // This will let you use your own Title while keeping the search
              const propsCopy = { ...props };
              // Hide default title
              propsCopy.showTitle = false;
              return (
                <Grid container direction="row">
                  <Grid item xs={6}>
                    <h2>Your Own Title</h2>
                  </Grid>
                  <Grid item xs={6}>
                    <MTableToolbar {...propsCopy} />
                  </Grid>
                </Grid>
              );
            },
            Body: props => {
    
              return (
                <CustomScrollbars style={{ height: '650px' }}>
                  <MTableBody {...props} />
                </CustomScrollbars>
    
              )
            },
            Header: props => (
              <div>
                <MTableHeader {...props} />
              </div>
            )
          }}
        />
      )
    }