Git Product home page Git Product logo

react-table-sticky's Introduction

React Table Sticky



npm package

Sticky hook for React Table v7


npm i react-table-sticky


Documentation

Features

  • sticky header
  • sticky footer
  • sticky columns left and/or right
  • full customizable

Simple example

Steps:

  1. create CSS classes .table .header .body .sticky etc... (check following example)
  2. create HTML elements <div className="table sticky">, <div className="header">, <div className="body"> etc...
  3. add useSticky hook
  4. then, add sticky: 'left' or sticky: 'right' to your column

full example:

import React from 'react';
import styled from 'styled-components';
import { useTable, useBlockLayout } from 'react-table';
import { useSticky } from 'react-table-sticky';

const Styles = styled.div`
  .table {
    border: 1px solid #ddd;

    .tr {
      :last-child {
        .td {
          border-bottom: 0;
        }
      }
    }

    .th,
    .td {
      padding: 5px;
      border-bottom: 1px solid #ddd;
      border-right: 1px solid #ddd;
      background-color: #fff;
      overflow: hidden;

      :last-child {
        border-right: 0;
      }
    }

    &.sticky {
      overflow: scroll;
      .header,
      .footer {
        position: sticky;
        z-index: 1;
        width: fit-content;
      }

      .header {
        top: 0;
        box-shadow: 0px 3px 3px #ccc;
      }

      .footer {
        bottom: 0;
        box-shadow: 0px -3px 3px #ccc;
      }

      .body {
        position: relative;
        z-index: 0;
      }

      [data-sticky-td] {
        position: sticky;
      }

      [data-sticky-last-left-td] {
        box-shadow: 2px 0px 3px #ccc;
      }

      [data-sticky-first-right-td] {
        box-shadow: -2px 0px 3px #ccc;
      }
    }
  }
`;

function TableDemo() {
  const columns = [
    {
      Header: 'First Name',
      accessor: 'firstName',
      sticky: 'left',
    },
    {
      Header: 'Last Name',
      accessor: 'lastName',
      sticky: 'left',
    },
    ...
    {
      Header: 'age',
      accessor: 'age',
      sticky: 'right',
    }
  ]

  const data = [
    ...
  ]

  const {
    getTableProps,
    getTableBodyProps,
    headerGroups,
    rows,
    prepareRow,
  } = useTable(
    {
      columns,
      data,
    },
    useBlockLayout,
    useSticky,
  );

  // Workaround as react-table footerGroups doesn't provide the same internal data than headerGroups
  const footerGroups = headerGroups.slice().reverse();

  return (
    <Styles>
      <div {...getTableProps()} className="table sticky" style={{ width: 1000, height: 500 }}>
        <div className="header">
          {headerGroups.map((headerGroup) => (
            <div {...headerGroup.getHeaderGroupProps()} className="tr">
              {headerGroup.headers.map((column) => (
                <div {...column.getHeaderProps()} className="th">
                  {column.render('Header')}
                </div>
              ))}
            </div>
          ))}
        </div>
        <div {...getTableBodyProps()} className="body">
          {rows.map((row) => {
            prepareRow(row);
            return (
              <div {...row.getRowProps()} className="tr">
                {row.cells.map((cell) => (
                  <div {...cell.getCellProps()} className="td">
                    {cell.render('Cell')}
                  </div>
                ))}
              </div>
            );
          })}
        </div>
        <div className="footer">
          {footerGroups.map((footerGroup) => (
            <div {...footerGroup.getHeaderGroupProps()} className="tr">
              {footerGroup.headers.map((column) => (
                <div {...column.getHeaderProps()} className="td">
                  {column.render('Footer')}
                </div>
              ))}
            </div>
          ))}
        </div>
      </div>
    </Styles>
  );
}

Tips: if your table contain at least one header group, place yours sticky columns into a group too (even with an empty Header name)

const columns = [
  {
    Header: ' ',
    sticky: 'left',
    columns: [
      {
        Header: 'First Name',
        accessor: 'firstName',
      },
      {
        Header: 'Last Name',
        accessor: 'lastName',
      },
    ]
  },
  {
    Header: 'Other group',
    columns: [
      ...
    ]
  }
]

Sticky columns for React Table v6

If you search tool for sticky position in React Table v6, take a look at react-table-hoc-fixed-columns

Browser support

Check CSS sticky support https://caniuse.com/#search=sticky

Contribute

  • git clone https://github.com/guillaumejasmin/react-table-sticky.git
  • npm install
  • npm run demo
  • Go to http://localhost:8080

react-table-sticky's People

Contributors

dependabot[bot] avatar guillaumejasmin avatar hardikmodha 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

react-table-sticky's Issues

Add `isSticky` to cell instance

Currently the only way to check if a cell is sticky is by doing cell.getCellProps()['data-sticky-td'] which feels a bit hacky. It would be nice to add support for cell.isSticky.

sticky doesn't seem to work with react-table integrating react-window

One of the perks to react-table v7 is the ability to integrate react-window's FixedSizeList to create a virtualized table. Unfortunately, it seems react-table-sticky doesn't work when using FixedSizeList as the table body component -- the header cells of sticky: 'left' columns are indeed sticky, but the cells move. With the same setup of react-table-sticky but replacing FixedSizeList with a standard mapping of divs as the body, I can get sticky columns. Is this library meant to handle the FixedSizeList/react-window integration in react-table?

For now, I have a workaround where I am putting two FixedSizeLists adjacent to each other in the body and using their scrollTo/onScroll methods to stay in sync.

'sticky' does not exist in type 'Column<T>'

I have a basic Table component:

import React from "react";
import { useTable, UseTableOptions } from "react-table";
import { useSticky } from "react-table-sticky";

export type TableProps<D extends object = {}> = UseTableOptions<D>;

const Table = <D extends object>(props: TableProps<D>) => {
  const { getTableProps, getTableBodyProps, headerGroups, rows, prepareRow } = useTable(props, useSticky);

  return (
    <table {...getTableProps()}>
      ...
    </table>
  );
};

export default Table;

And this is how I call the component:

<Table columns={columns} data={data}></Table>

The thing is, when I try to statically declare the columns, I get the following error:

type '{ id: string; Header: string; sticky: string; columns: ({ Header: string; accessor: "name"; } | { Header: string; accessor: "status"; } | { Header: string; accessor: "createdAt"; })[]; }' is not assignable to type 'Column<AdvertiserColumns>'.
  Object literal may only specify known properties, and 'sticky' does not exist in type 'Column<AdvertiserColumns>'.ts(2322)

image

Which is correct, because in the end it points to this interface:

export interface UseTableColumnOptions<D extends object> {
    id?: IdType<D>;
    Header?: Renderer<HeaderProps<D>>;
    width?: number | string;
    minWidth?: number;
    maxWidth?: number;
}

I know I can simply remove the typing Column<AdvertiserColumns>[], but then it might lead to some bugs (e.g write header instead of Header). Any ideas?

Why data-sticky-last-left-td has element.style `left: 150px;`

I am trying to make 2 columns left-sticky. The first column is fine, but for some reasons the 2nd one is not right next to the first one. Instead for some reasons it has style left:150px; and ends up on top of the 3rd column, which is not sticky.

Screen Shot 2020-12-27 at 12 04 10 PM

I tried to set left:auto !important for the 2nd column but it is no longer sticky. Really appreciate any help.

IE11 throws exception

I understand that position: sticky does not work in IE11 but there is no reason, when this library is used, not to have a working page. At the moment you load the code in IE11 it throws exeption like this:
image
image
The moment I comment out the useSticky hook, the error is gone.
You can see that IE11 is not very helpful in resolving the issue. Could someone help with that? Do I need some kind of polyfill?

Sticky Header doesnt work

Hey, ive been trying to incorporate the react-table sticky header together with the sticky column from your package however its not working as expected. The stickyheader is overwritten.

In the below screenshot, we can see that the row item is overriding the header row.

image

Stick columns from any position

Take a look on my branch. I changed the logic to stick columns from any position, not only from far left/right. I use it with useFlex hook, it works like charm. However, needs to update tests and demo.

Open PR for core library?

Hi there! Thanks for this library! It's awesome to expand on features of a large libraries.

I'm wondering if you've considered opening a PR to add this feature to the react-table library itself. I don't know what Tanner thinks of the feature, but IMO this seems like a natural addition.

And selfishly, I maintain a component library that will encourage its use with react-table, and it would be nice to point users to react-table only, instead of having to seek out other plugins!

RTL Support

hi . how to handle rtl for your library ?

Cannot read property 'sticky' of undefined when using depth more than 1

react-table-sticky fails with an error

Cannot read property 'sticky' of undefined

when using headergroups with depth having more than 1.

{
  "id": "name_details_container",
  "Header": "Name Details",
  "sticky": "left",
  "Footer": "Name Details",
  "columns": [
    {
      "Header": "Name",
      "Footer": "Name",
      "columns": [
        {
          "Header": "First Name",
          "Footer": "First Name",
          "accessor": "firstName"
        },
        { 
          "Header": "Last Name", 
	  "Footer": "Last Name", 
          "accessor": "lastName" 
        }
      ]
    }
  ]
}

Following is a reproducible example:

https://codesandbox.io/s/react-table-sticky-official-r4hjg?file=/src/App.js

Support for React-window

This library is awesome, was searching for react-table 7 with sticky columns and found this one! 👏 👏 . I need to ask if there is support for react-window with sticky columns or maybe an example? I'm trying to combine react-table + this library + react-window but apparently the react-window styles mess with the styles from this library as far as I can see.

Any recommendation? advice? Maybe it's in the roadmap?

Thanks.

Full width table

Hey - this hook is very useful and should be mentioned on the react-table readme - thank you!

I am trying to modify the example provided and make it go full width, and adapt the width of the columns. Do you have any suggestions for this?

iOS sticky columns headers are jumpy

I noticed that the headers of the sticky columns are jumpy when side-scrolling on iOS devices.
Here's a recording of a slightly modified demo (just removed some of the table structure from the demo).

You can see that only the headers present this behaviour and not the entire sticky column.

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.