package.src.features.Pinning.ts Maven / Gradle / Ivy
Go to download
Show more of this group Show more artifacts with this name
Show all versions of table-core Show documentation
Show all versions of table-core Show documentation
Headless UI for building powerful tables & datagrids for TS/JS.
The newest version!
import { TableFeature } from '../core/table'
import {
OnChangeFn,
Updater,
Table,
Column,
Row,
Cell,
RowData,
} from '../types'
import { makeStateUpdater, memo } from '../utils'
export type ColumnPinningPosition = false | 'left' | 'right'
export interface ColumnPinningState {
left?: string[]
right?: string[]
}
export interface ColumnPinningTableState {
columnPinning: ColumnPinningState
}
export interface ColumnPinningOptions {
onColumnPinningChange?: OnChangeFn
enablePinning?: boolean
}
export interface ColumnPinningDefaultOptions {
onColumnPinningChange: OnChangeFn
}
export interface ColumnPinningColumnDef {
enablePinning?: boolean
}
export interface ColumnPinningColumn {
getCanPin: () => boolean
getPinnedIndex: () => number
getIsPinned: () => ColumnPinningPosition
pin: (position: ColumnPinningPosition) => void
}
export interface ColumnPinningRow {
getLeftVisibleCells: () => Cell[]
getCenterVisibleCells: () => Cell[]
getRightVisibleCells: () => Cell[]
}
export interface ColumnPinningInstance {
setColumnPinning: (updater: Updater) => void
resetColumnPinning: (defaultState?: boolean) => void
getIsSomeColumnsPinned: (position?: ColumnPinningPosition) => boolean
getLeftLeafColumns: () => Column[]
getRightLeafColumns: () => Column[]
getCenterLeafColumns: () => Column[]
}
//
const getDefaultPinningState = (): ColumnPinningState => ({
left: [],
right: [],
})
export const Pinning: TableFeature = {
getInitialState: (state): ColumnPinningTableState => {
return {
columnPinning: getDefaultPinningState(),
...state,
}
},
getDefaultOptions: (
table: Table
): ColumnPinningDefaultOptions => {
return {
onColumnPinningChange: makeStateUpdater('columnPinning', table),
}
},
createColumn: (
column: Column,
table: Table
): ColumnPinningColumn => {
return {
pin: position => {
const columnIds = column
.getLeafColumns()
.map(d => d.id)
.filter(Boolean) as string[]
table.setColumnPinning(old => {
if (position === 'right') {
return {
left: (old?.left ?? []).filter(d => !columnIds?.includes(d)),
right: [
...(old?.right ?? []).filter(d => !columnIds?.includes(d)),
...columnIds,
],
}
}
if (position === 'left') {
return {
left: [
...(old?.left ?? []).filter(d => !columnIds?.includes(d)),
...columnIds,
],
right: (old?.right ?? []).filter(d => !columnIds?.includes(d)),
}
}
return {
left: (old?.left ?? []).filter(d => !columnIds?.includes(d)),
right: (old?.right ?? []).filter(d => !columnIds?.includes(d)),
}
})
},
getCanPin: () => {
const leafColumns = column.getLeafColumns()
return leafColumns.some(
d =>
(d.columnDef.enablePinning ?? true) &&
(table.options.enablePinning ?? true)
)
},
getIsPinned: () => {
const leafColumnIds = column.getLeafColumns().map(d => d.id)
const { left, right } = table.getState().columnPinning
const isLeft = leafColumnIds.some(d => left?.includes(d))
const isRight = leafColumnIds.some(d => right?.includes(d))
return isLeft ? 'left' : isRight ? 'right' : false
},
getPinnedIndex: () => {
const position = column.getIsPinned()
return position
? table.getState().columnPinning?.[position]?.indexOf(column.id) ?? -1
: 0
},
}
},
createRow: (
row: Row,
table: Table
): ColumnPinningRow => {
return {
getCenterVisibleCells: memo(
() => [
row._getAllVisibleCells(),
table.getState().columnPinning.left,
table.getState().columnPinning.right,
],
(allCells, left, right) => {
const leftAndRight: string[] = [...(left ?? []), ...(right ?? [])]
return allCells.filter(d => !leftAndRight.includes(d.column.id))
},
{
key:
process.env.NODE_ENV === 'production' &&
'row.getCenterVisibleCells',
debug: () => table.options.debugAll ?? table.options.debugRows,
}
),
getLeftVisibleCells: memo(
() => [
row._getAllVisibleCells(),
table.getState().columnPinning.left,
,
],
(allCells, left) => {
const cells = (left ?? [])
.map(
columnId => allCells.find(cell => cell.column.id === columnId)!
)
.filter(Boolean)
.map(d => ({ ...d, position: 'left' } as Cell))
return cells
},
{
key:
process.env.NODE_ENV === 'production' && 'row.getLeftVisibleCells',
debug: () => table.options.debugAll ?? table.options.debugRows,
}
),
getRightVisibleCells: memo(
() => [row._getAllVisibleCells(), table.getState().columnPinning.right],
(allCells, right) => {
const cells = (right ?? [])
.map(
columnId => allCells.find(cell => cell.column.id === columnId)!
)
.filter(Boolean)
.map(d => ({ ...d, position: 'right' } as Cell))
return cells
},
{
key:
process.env.NODE_ENV === 'production' && 'row.getRightVisibleCells',
debug: () => table.options.debugAll ?? table.options.debugRows,
}
),
}
},
createTable: (
table: Table
): ColumnPinningInstance => {
return {
setColumnPinning: updater =>
table.options.onColumnPinningChange?.(updater),
resetColumnPinning: defaultState =>
table.setColumnPinning(
defaultState
? getDefaultPinningState()
: table.initialState?.columnPinning ?? getDefaultPinningState()
),
getIsSomeColumnsPinned: position => {
const pinningState = table.getState().columnPinning
if (!position) {
return Boolean(
pinningState.left?.length || pinningState.right?.length
)
}
return Boolean(pinningState[position]?.length)
},
getLeftLeafColumns: memo(
() => [table.getAllLeafColumns(), table.getState().columnPinning.left],
(allColumns, left) => {
return (left ?? [])
.map(columnId => allColumns.find(column => column.id === columnId)!)
.filter(Boolean)
},
{
key: process.env.NODE_ENV === 'development' && 'getLeftLeafColumns',
debug: () => table.options.debugAll ?? table.options.debugColumns,
}
),
getRightLeafColumns: memo(
() => [table.getAllLeafColumns(), table.getState().columnPinning.right],
(allColumns, right) => {
return (right ?? [])
.map(columnId => allColumns.find(column => column.id === columnId)!)
.filter(Boolean)
},
{
key: process.env.NODE_ENV === 'development' && 'getRightLeafColumns',
debug: () => table.options.debugAll ?? table.options.debugColumns,
}
),
getCenterLeafColumns: memo(
() => [
table.getAllLeafColumns(),
table.getState().columnPinning.left,
table.getState().columnPinning.right,
],
(allColumns, left, right) => {
const leftAndRight: string[] = [...(left ?? []), ...(right ?? [])]
return allColumns.filter(d => !leftAndRight.includes(d.id))
},
{
key: process.env.NODE_ENV === 'development' && 'getCenterLeafColumns',
debug: () => table.options.debugAll ?? table.options.debugColumns,
}
),
}
},
}
© 2015 - 2024 Weber Informatics LLC | Privacy Policy