Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
import {
column_getSize,
getDefaultColumnSizingColumnDef,
header_getSize,
table_setColumnSizing,
} from '../column-sizing/columnSizingFeature.utils'
Expand Down Expand Up @@ -119,6 +120,18 @@ export function header_getResizeHandler<
column_getSize(leafHeader.column),
])

const defaultSizes = getDefaultColumnSizingColumnDef()
const columnSizingConstraints: Record<
string,
{ minSize: number; maxSize: number }
> = {}
header.getLeafHeaders().forEach((leafHeader) => {
columnSizingConstraints[leafHeader.column.id] = {
minSize: leafHeader.column.columnDef.minSize ?? defaultSizes.minSize,
maxSize: leafHeader.column.columnDef.maxSize ?? defaultSizes.maxSize,
}
})

const clientX = isTouchStartEvent(event)
? Math.round(event.touches[0]!.clientX)
: (event as MouseEvent).clientX
Expand All @@ -142,15 +155,16 @@ export function header_getResizeHandler<
)

old.columnSizingStart.forEach(([columnId, headerSize]) => {
const rawSize =
headerSize > 0
? headerSize + headerSize * deltaPercentage
: deltaOffset / old.columnSizingStart.length
const constraints = columnSizingConstraints[columnId]
const minSize = constraints?.minSize ?? 0
const maxSize = constraints?.maxSize ?? Number.MAX_SAFE_INTEGER
newColumnSizing[columnId] =
Math.round(
Math.max(
headerSize > 0
? headerSize + headerSize * deltaPercentage
: deltaOffset / old.columnSizingStart.length,
0,
) * 100,
) / 100
Math.round(Math.min(maxSize, Math.max(minSize, rawSize)) * 100) /
100
})

return {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -422,6 +422,118 @@ describe('header_getResizeHandler', () => {

removeEventListenerSpy.mockRestore()
})

it('should not resize a column below its minSize', () => {
const table = generateTestTableWithData<TestFeatures>(1, {
columnResizeMode: 'onChange',
})

let resizingState = getDefaultColumnResizingState()
table.options.onColumnResizingChange = (updater: any) => {
resizingState =
typeof updater === 'function' ? updater(resizingState) : updater
;(table.store.state as any).columnResizing = resizingState
}

const sizingUpdates: Record<string, number>[] = []
table.options.onColumnSizingChange = (updater: any) => {
if (typeof updater === 'function') {
const result = updater(table.atoms.columnSizing?.get() ?? {})
sizingUpdates.push(result)
} else {
sizingUpdates.push(updater)
}
}

// Column starts at 100px, minSize is 50px
const constrainedColumn = {
...table.getAllColumns()[0],
id: 'firstName',
columnDef: { enableResizing: true, minSize: 50, size: 100 },
table,
}
const header = createTestResizeHeader(table, {
getSize: () => 100,
getLeafHeaders: () => [
{
column: constrainedColumn,
getSize: () => 100,
subHeaders: [],
},
],
})

const handler = header_getResizeHandler(header as any, document)
handler({ type: 'mousedown', clientX: 200 })

// Drag far left — would put column at ~10px without the clamp
const moveEvent = new MouseEvent('mousemove', { clientX: 10 })
document.dispatchEvent(moveEvent)

const lastUpdate = sizingUpdates[sizingUpdates.length - 1]
expect(lastUpdate).toBeDefined()
const newSize = lastUpdate!['firstName']
expect(newSize).toBeGreaterThanOrEqual(50)

const upEvent = new MouseEvent('mouseup', { clientX: 10 })
document.dispatchEvent(upEvent)
})

it('should not resize a column above its maxSize', () => {
const table = generateTestTableWithData<TestFeatures>(1, {
columnResizeMode: 'onChange',
})

let resizingState = getDefaultColumnResizingState()
table.options.onColumnResizingChange = (updater: any) => {
resizingState =
typeof updater === 'function' ? updater(resizingState) : updater
;(table.store.state as any).columnResizing = resizingState
}

const sizingUpdates: Record<string, number>[] = []
table.options.onColumnSizingChange = (updater: any) => {
if (typeof updater === 'function') {
const result = updater(table.atoms.columnSizing?.get() ?? {})
sizingUpdates.push(result)
} else {
sizingUpdates.push(updater)
}
}

// Column starts at 100px, maxSize is 150px
const constrainedColumn = {
...table.getAllColumns()[0],
id: 'firstName',
columnDef: { enableResizing: true, maxSize: 150, size: 100 },
table,
}
const header = createTestResizeHeader(table, {
getSize: () => 100,
getLeafHeaders: () => [
{
column: constrainedColumn,
getSize: () => 100,
subHeaders: [],
},
],
})

const handler = header_getResizeHandler(header as any, document)
handler({ type: 'mousedown', clientX: 100 })

// Drag far right — would put column at ~500px without the clamp
const moveEvent = new MouseEvent('mousemove', { clientX: 600 })
document.dispatchEvent(moveEvent)

const lastUpdate = sizingUpdates[sizingUpdates.length - 1]
expect(lastUpdate).toBeDefined()
const newSize = lastUpdate!['firstName']
expect(newSize).toBeLessThanOrEqual(150)

const upEvent = new MouseEvent('mouseup', { clientX: 600 })
document.dispatchEvent(upEvent)
})
})

describe('passiveEventSupported', () => {
Expand Down