Skip to content

Commit

Permalink
feat: Row Pinning (#5074)
Browse files Browse the repository at this point in the history
* recreate row pinning feature, example and docs

* upgrade example version

* default keepPinnedRows to true

* add some row pinning unit tests

* add row pinning example to config
  • Loading branch information
KevinVandy authored Sep 17, 2023
1 parent 057563f commit 15a425a
Show file tree
Hide file tree
Showing 19 changed files with 1,211 additions and 34 deletions.
132 changes: 129 additions & 3 deletions docs/api/features/column-pinning.md → docs/api/features/pinning.md
Original file line number Diff line number Diff line change
@@ -1,30 +1,44 @@
---
title: Column Pinning
id: column-pinning
title: Pinning
id: pinning
---

## Can-Pin

The ability for a column to be **pinned** is determined by the following:

- `options.enablePinning` is not set to `false`
- `options.enableColumnPinning` is not set to `false`
- `columnDefinition.enablePinning` is not set to `false`

The ability for a row to be **pinned** is determined by the following:

- `options.enableRowPinning` resolves to `true`
- `options.enablePinning` is not set to `false`

## State

Column pinning state is stored on the table using the following shape:
Pinning state is stored on the table using the following shape:

```tsx
export type ColumnPinningPosition = false | 'left' | 'right'
export type RowPinningPosition = false | 'top' | 'bottom'

export type ColumnPinningState = {
left?: string[]
right?: string[]
}
export type RowPinningState = {
top?: boolean
bottom?: boolean
}

export type ColumnPinningTableState = {
columnPinning: ColumnPinningState
}
export type RowPinningRowState = {
rowPinning: RowPinningState
}
```
## Table Options
Expand All @@ -37,6 +51,30 @@ enablePinning?: boolean
Enables/disables all pinning for the table.
### `enableColumnPinning`
```tsx
enableColumnPinning?: boolean
```
Enables/disables column pinning for all columns in the table.
### `enableRowPinning`
```tsx
enableRowPinning?: boolean | ((row: Row<TData>) => boolean)
```
Enables/disables row pinning for all rows in the table.
### `keepPinnedRows`
```tsx
keepPinnedRows?: boolean
```
When `false`, pinned rows will not be visible if they are filtered or paginated out of the table. When `true`, pinned rows will always be visible regardless of filtering or pagination. Defaults to `true`.
### `onColumnPinningChange`
```tsx
Expand All @@ -45,6 +83,14 @@ onColumnPinningChange?: OnChangeFn<ColumnPinningState>
If provided, this function will be called with an `updaterFn` when `state.columnPinning` changes. This overrides the default internal state management, so you will need to persist the state change either fully or partially outside of the table.
### `onRowPinningChange`
```tsx
onRowPinningChange?: OnChangeFn<RowPinningState>
```
If provided, this function will be called with an `updaterFn` when `state.rowPinning` changes. This overrides the default internal state management, so you will need to persist the state change either fully or partially outside of the table.
## Column Def Options
### `enablePinning`
Expand All @@ -65,6 +111,14 @@ setColumnPinning: (updater: Updater<ColumnPinningState>) => void
Sets or updates the `state.columnPinning` state.
### `setRowPinning`
```tsx
setRowPinning: (updater: Updater<RowPinningState>) => void
```
Sets or updates the `state.rowPinning` state.
### `resetColumnPinning`
```tsx
Expand All @@ -73,6 +127,14 @@ resetColumnPinning: (defaultState?: boolean) => void
Resets the **columnPinning** state to `initialState.columnPinning`, or `true` can be passed to force a default blank state reset to `{ left: [], right: [], }`.
### `resetRowPinning`
```tsx
resetRowPinning: (defaultState?: boolean) => void
```
Resets the **rowPinning** state to `initialState.rowPinning`, or `true` can be passed to force a default blank state reset to `{}`.
### `getIsSomeColumnsPinned`
```tsx
Expand All @@ -83,6 +145,14 @@ Returns whether or not any columns are pinned. Optionally specify to only check
_Note: Does not account for column visibility_
### `getIsSomeRowsPinned`
```tsx
getIsSomeRowsPinned: (position?: RowPinningPosition) => boolean
```
Returns whether or not any rows are pinned. Optionally specify to only check for pinned rows in either the `top` or `bottom` position.
### `getLeftHeaderGroups`
```tsx
Expand Down Expand Up @@ -203,6 +273,30 @@ getCenterLeafColumns: () => Column < TData > []
Returns all center pinned (unpinned) leaf columns.
### `getTopRows`
```tsx
getTopRows: () => Row < TData > []
```
Returns all top pinned rows.
### `getBottomRows`
```tsx
getBottomRows: () => Row < TData > []
```
Returns all bottom pinned rows.
### `getCenterRows`
```tsx
getCenterRows: () => Row < TData > []
```
Returns all rows that are not pinned to the top or bottom.
## Column API
### `getCanPin`
Expand Down Expand Up @@ -239,6 +333,38 @@ Pins a column to the `'left'` or `'right'`, or unpins the column to the center i
## Row API
### `pin`
```tsx
pin: (position: RowPinningPosition) => void
```
Pins a row to the `'top'` or `'bottom'`, or unpins the row to the center if `false` is passed.
### `getCanPin`
```tsx
getCanPin: () => boolean
```
Returns whether or not the row can be pinned.
### `getIsPinned`
```tsx
getIsPinned: () => RowPinningPosition
```
Returns the pinned position of the row. (`'top'`, `'bottom'` or `false`)
### `getPinnedIndex`
```tsx
getPinnedIndex: () => number
```
Returns the numeric pinned index of the row within a pinned row group.
### `getLeftVisibleCells`
```tsx
Expand Down
22 changes: 13 additions & 9 deletions docs/config.json
Original file line number Diff line number Diff line change
Expand Up @@ -77,10 +77,6 @@
"label": "Column Ordering",
"to": "guide/column-ordering"
},
{
"label": "Column Pinning",
"to": "guide/column-pinning"
},
{
"label": "Column Sizing",
"to": "guide/column-sizing"
Expand Down Expand Up @@ -109,6 +105,10 @@
"label": "Pagination",
"to": "guide/pagination"
},
{
"label": "Pinning",
"to": "guide/pinning"
},
{
"label": "Row Selection",
"to": "guide/row-selection"
Expand Down Expand Up @@ -155,10 +155,6 @@
"label": "Column Ordering",
"to": "api/features/column-ordering"
},
{
"label": "Column Pinning",
"to": "api/features/column-pinning"
},
{
"label": "Column Sizing",
"to": "api/features/column-sizing"
Expand Down Expand Up @@ -187,6 +183,10 @@
"label": "Pagination",
"to": "api/features/pagination"
},
{
"label": "Pinning",
"to": "api/features/pinning"
},
{
"label": "Row Selection",
"to": "api/features/row-selection"
Expand Down Expand Up @@ -269,6 +269,10 @@
"to": "examples/react/row-dnd",
"label": "Row DnD"
},
{
"to": "examples/react/row-pinning",
"label": "Row Pinning"
},
{
"to": "examples/react/row-selection",
"label": "Row Selection"
Expand Down Expand Up @@ -396,4 +400,4 @@
]
}
]
}
}
10 changes: 8 additions & 2 deletions docs/guide/column-pinning.md → docs/guide/pinning.md
Original file line number Diff line number Diff line change
@@ -1,16 +1,17 @@
---
title: Column Pinning
title: Pinning
---

## Examples

Want to skip to the implementation? Check out these examples:

- [column-pinning](../examples/react/column-pinning)
- [row-pinning](../examples/react/row-pinning)

## API

[Column Pinning API](../api/features/column-pinning)
[Pinning API](../api/features/pinning)

## Overview

Expand All @@ -19,3 +20,8 @@ There are 3 table features that can reorder columns, which happen in the followi
1. **Column Pinning** - If pinning, columns are split into left, center (unpinned), and right pinned columns.
2. Manual [Column Ordering](../guide/column-ordering) - A manually specified column order is applied.
3. [Grouping](../guide/grouping) - If grouping is enabled, a grouping state is active, and `tableOptions.columnGroupingMode` is set to `'reorder' | 'remove'`, then the grouped columns are reordered to the start of the column flow.

There are 2 table features that can reorder rows, which happen in the following order:

1. **Row Pinning** - If pinning, rows are split into top, center (unpinned), and bottom pinned rows.
2. [Sorting](../guide/sorting)
5 changes: 5 additions & 0 deletions examples/react/row-pinning/.gitignore
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
node_modules
.DS_Store
dist
dist-ssr
*.local
6 changes: 6 additions & 0 deletions examples/react/row-pinning/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
# Example

To run this example:

- `npm install` or `yarn`
- `npm run start` or `yarn start`
13 changes: 13 additions & 0 deletions examples/react/row-pinning/index.html
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8" />
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
<title>Vite App</title>
<script type="module" src="https://cdn.skypack.dev/twind/shim"></script>
</head>
<body>
<div id="root"></div>
<script type="module" src="/src/main.tsx"></script>
</body>
</html>
22 changes: 22 additions & 0 deletions examples/react/row-pinning/package.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
{
"name": "tanstack-table-example-row-pinning",
"version": "0.0.0",
"private": true,
"scripts": {
"dev": "vite",
"build": "vite build",
"serve": "vite preview --port 3000",
"start": "vite"
},
"dependencies": {
"@faker-js/faker": "^8.0.2",
"@tanstack/react-table": "8.9.11",
"react": "^18.2.0",
"react-dom": "^18.2.0"
},
"devDependencies": {
"@rollup/plugin-replace": "^5.0.1",
"@vitejs/plugin-react": "^2.2.0",
"vite": "^3.2.3"
}
}
35 changes: 35 additions & 0 deletions examples/react/row-pinning/src/index.css
Original file line number Diff line number Diff line change
@@ -0,0 +1,35 @@
html {
font-family: sans-serif;
font-size: 14px;
}

table {
border: 1px solid lightgray;
}

tbody {
border-bottom: 1px solid lightgray;
}

th {
border-bottom: 1px solid lightgray;
border-right: 1px solid lightgray;
padding: 2px 4px;
}

td {
border-right: 1px solid lightgray;
padding: 2px 4px;
}

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

tfoot {
color: gray;
}

tfoot th {
font-weight: normal;
}
Loading

0 comments on commit 15a425a

Please sign in to comment.