@ui5/webcomponents-react
Version:
React Wrapper for UI5 Web Components and additional components
157 lines • 4.97 kB
JavaScript
import { useCallback } from 'react';
import { actions, functionalUpdate, useGetLatest, makePropGetter, useMountedLayoutEffect } from '../publicUtils.js';
actions.resetHiddenColumns = 'resetHiddenColumns';
actions.toggleHideColumn = 'toggleHideColumn';
actions.setHiddenColumns = 'setHiddenColumns';
actions.toggleHideAllColumns = 'toggleHideAllColumns';
export const useColumnVisibility = hooks => {
hooks.getToggleHiddenProps = [defaultGetToggleHiddenProps];
hooks.getToggleHideAllColumnsProps = [defaultGetToggleHideAllColumnsProps];
hooks.stateReducers.push(reducer);
hooks.useInstanceBeforeDimensions.push(useInstanceBeforeDimensions);
hooks.headerGroupsDeps.push((deps, {
instance
}) => [...deps, instance.state.hiddenColumns]);
hooks.useInstance.push(useInstance);
};
useColumnVisibility.pluginName = 'useColumnVisibility';
const defaultGetToggleHiddenProps = (props, {
column
}) => [props, {
onChange: e => {
column.toggleHidden(!e.target.checked);
},
style: {
cursor: 'pointer'
},
checked: column.isVisible,
title: 'Toggle Column Visible'
}];
const defaultGetToggleHideAllColumnsProps = (props, {
instance
}) => [props, {
onChange: e => {
instance.toggleHideAllColumns(!e.target.checked);
},
style: {
cursor: 'pointer'
},
checked: !instance.allColumnsHidden && !instance.state.hiddenColumns.length,
title: 'Toggle All Columns Hidden',
indeterminate: !instance.allColumnsHidden && instance.state.hiddenColumns.length
}];
function reducer(state, action, _previousState, instance) {
if (action.type === actions.init) {
return {
hiddenColumns: [],
...state
};
}
if (action.type === actions.resetHiddenColumns) {
return {
...state,
hiddenColumns: instance.initialState.hiddenColumns || []
};
}
if (action.type === actions.toggleHideColumn) {
const should = typeof action.value !== 'undefined' ? action.value : !state.hiddenColumns.includes(action.columnId);
const hiddenColumns = should ? [...state.hiddenColumns, action.columnId] : state.hiddenColumns.filter(d => d !== action.columnId);
return {
...state,
hiddenColumns
};
}
if (action.type === actions.setHiddenColumns) {
return {
...state,
hiddenColumns: functionalUpdate(action.value, state.hiddenColumns)
};
}
if (action.type === actions.toggleHideAllColumns) {
const shouldAll = typeof action.value !== 'undefined' ? action.value : !state.hiddenColumns.length;
return {
...state,
hiddenColumns: shouldAll ? instance.allColumns.map(d => d.id) : []
};
}
}
function useInstanceBeforeDimensions(instance) {
const {
headers,
state: {
hiddenColumns
}
} = instance;
const handleColumn = (column, parentVisible) => {
column.isVisible = parentVisible && !hiddenColumns.includes(column.id);
let totalVisibleHeaderCount = 0;
if (column.headers && column.headers.length) {
column.headers.forEach(subColumn => totalVisibleHeaderCount += handleColumn(subColumn, column.isVisible));
} else {
totalVisibleHeaderCount = column.isVisible ? 1 : 0;
}
column.totalVisibleHeaderCount = totalVisibleHeaderCount;
return totalVisibleHeaderCount;
};
let totalVisibleHeaderCount = 0;
headers.forEach(subHeader => totalVisibleHeaderCount += handleColumn(subHeader, true));
}
function useInstance(instance) {
const {
columns,
flatHeaders,
dispatch,
allColumns,
getHooks,
state: {
hiddenColumns
},
autoResetHiddenColumns = true
} = instance;
const getInstance = useGetLatest(instance);
const allColumnsHidden = allColumns.length === hiddenColumns.length;
const toggleHideColumn = useCallback((columnId, value) => dispatch({
type: actions.toggleHideColumn,
columnId,
value
}), [dispatch]);
const setHiddenColumns = useCallback(value => dispatch({
type: actions.setHiddenColumns,
value
}), [dispatch]);
const toggleHideAllColumns = useCallback(value => dispatch({
type: actions.toggleHideAllColumns,
value
}), [dispatch]);
const getToggleHideAllColumnsProps = makePropGetter(getHooks().getToggleHideAllColumnsProps, {
instance: getInstance()
});
flatHeaders.forEach(column => {
column.toggleHidden = value => {
dispatch({
type: actions.toggleHideColumn,
columnId: column.id,
value
});
};
column.getToggleHiddenProps = makePropGetter(getHooks().getToggleHiddenProps, {
instance: getInstance(),
column
});
});
const getAutoResetHiddenColumns = useGetLatest(autoResetHiddenColumns);
useMountedLayoutEffect(() => {
if (getAutoResetHiddenColumns()) {
dispatch({
type: actions.resetHiddenColumns
});
}
}, [dispatch, columns]);
Object.assign(instance, {
allColumnsHidden,
toggleHideColumn,
setHiddenColumns,
toggleHideAllColumns,
getToggleHideAllColumnsProps
});
}