Private
Public Access
1
0
Files

119 lines
4.7 KiB
JavaScript

'use client';
import { useEventCallback, useIsomorphicLayoutEffect } from '@fluentui/react-utilities';
import * as React from 'react';
import { columnDefinitionsToState, adjustColumnWidthsToFitContainer, getColumnById, setColumnProperty, getColumnWidth } from '../utils/columnResizeUtils';
const createReducer = (autoFitColumns)=>(state, action)=>{
switch(action.type){
case 'CONTAINER_WIDTH_UPDATED':
return {
...state,
containerWidth: action.containerWidth,
columnWidthState: autoFitColumns ? adjustColumnWidthsToFitContainer(state.columnWidthState, action.containerWidth) : state.columnWidthState
};
case 'COLUMNS_UPDATED':
const newS = columnDefinitionsToState(action.columns, state.columnWidthState, state.columnSizingOptions);
return {
...state,
columns: action.columns,
columnWidthState: autoFitColumns ? adjustColumnWidthsToFitContainer(newS, state.containerWidth) : newS
};
case 'COLUMN_SIZING_OPTIONS_UPDATED':
const newState = columnDefinitionsToState(state.columns, state.columnWidthState, action.columnSizingOptions);
return {
...state,
columnSizingOptions: action.columnSizingOptions,
columnWidthState: autoFitColumns ? adjustColumnWidthsToFitContainer(newState, state.containerWidth) : newState
};
case 'SET_COLUMN_WIDTH':
const { columnId, width } = action;
const { containerWidth } = state;
const column = getColumnById(state.columnWidthState, columnId);
let newColumnWidthState = [
...state.columnWidthState
];
if (!column) {
return state;
}
// Adjust the column width and measure the new total width
newColumnWidthState = setColumnProperty(newColumnWidthState, columnId, 'width', width);
// Set this width as idealWidth, because its a deliberate change, not a recalculation because of container
newColumnWidthState = setColumnProperty(newColumnWidthState, columnId, 'idealWidth', width);
// Adjust the widths to the container size
if (autoFitColumns) {
newColumnWidthState = adjustColumnWidthsToFitContainer(newColumnWidthState, containerWidth);
}
return {
...state,
columnWidthState: newColumnWidthState
};
}
};
export function useTableColumnResizeState(columns, containerWidth, params = {}) {
const { onColumnResize, columnSizingOptions, autoFitColumns = true } = params;
const reducer = React.useMemo(()=>createReducer(autoFitColumns), [
autoFitColumns
]);
const [state, dispatch] = React.useReducer(reducer, {
columns,
containerWidth: 0,
columnWidthState: columnDefinitionsToState(columns, undefined, columnSizingOptions),
columnSizingOptions
});
useIsomorphicLayoutEffect(()=>{
dispatch({
type: 'CONTAINER_WIDTH_UPDATED',
containerWidth
});
}, [
containerWidth
]);
useIsomorphicLayoutEffect(()=>{
dispatch({
type: 'COLUMNS_UPDATED',
columns
});
}, [
columns
]);
useIsomorphicLayoutEffect(()=>{
dispatch({
type: 'COLUMN_SIZING_OPTIONS_UPDATED',
columnSizingOptions
});
}, [
columnSizingOptions
]);
const setColumnWidth = useEventCallback((event, data)=>{
let { width } = data;
const { columnId } = data;
const col = getColumnById(state.columnWidthState, columnId);
if (!col) {
return;
}
width = Math.max(col.minWidth || 0, width);
if (onColumnResize) {
onColumnResize(event, {
columnId,
width
});
}
dispatch({
type: 'SET_COLUMN_WIDTH',
columnId,
width
});
});
return {
getColumnById: React.useCallback((colId)=>getColumnById(state.columnWidthState, colId), [
state.columnWidthState
]),
getColumns: React.useCallback(()=>state.columnWidthState, [
state.columnWidthState
]),
getColumnWidth: React.useCallback((colId)=>getColumnWidth(state.columnWidthState, colId), [
state.columnWidthState
]),
setColumnWidth
};
}