@hitachivantara/uikit-react-core
Version:
UI Kit Core React components.
318 lines (317 loc) • 13.1 kB
JavaScript
import { useLabels } from "../../hooks/useLabels.js";
import { HvCheckBox } from "../../CheckBox/CheckBox.js";
import { useCallback, useMemo } from "react";
import { jsx } from "react/jsx-runtime";
import { actions, ensurePluginOrder, makePropGetter, useGetLatest, useMountedLayoutEffect } from "react-table";
//#region src/Table/hooks/useHvRowSelection.tsx
actions.resetSelectedRows = "resetSelectedRows";
actions.toggleAllRowsSelected = "toggleAllRowsSelected";
actions.toggleRowSelected = "toggleRowSelected";
actions.toggleAllPageRowsSelected = "toggleAllPageRowsSelected";
actions.resetLockedSelectionRows = "resetLockedSelectionRows";
actions.toggleRowLockedSelection = "toggleRowLockedSelection";
var DEFAULT_LABELS = { selectRowCheckBoxAriaLabel: "Select this row" };
var hideHeaderVariants = ["checkbox", "actions"];
var CellWithCheckBox = ({ row, labels: labelsProp }) => {
const labels = useLabels(DEFAULT_LABELS, labelsProp);
const { onChange, checked, disabled, indeterminate } = row.getToggleRowSelectedProps();
return /* @__PURE__ */ jsx(HvCheckBox, {
onChange,
checked,
disabled,
indeterminate,
"aria-label": labels.selectRowCheckBoxAriaLabel
});
};
var visibleColumnsHook = (columns) => {
return [{
id: "_hv_selection",
variant: "checkbox",
width: 32,
sticky: "left",
disableGlobalFilter: true,
Cell: CellWithCheckBox
}, ...columns];
};
var getHeaderPropsHook = (props, { column }) => {
const nextProps = {};
if (hideHeaderVariants.includes(column.variant)) nextProps["aria-hidden"] = true;
return [props, nextProps];
};
var getRowPropsHook = (props, { row }) => {
return [props, { selected: row.isSelected }];
};
var defaultGetToggleRowSelectedProps = (props, meta) => {
const { instance, row } = meta;
const { manualRowSelectedKey = "isSelected" } = instance;
let checked = false;
if (row.original?.[manualRowSelectedKey]) checked = true;
else checked = row.isSelected;
return [props, {
onChange: (e, check) => {
row.toggleRowSelected(check ?? e?.target?.checked);
},
disabled: row.isSelectionLocked,
checked,
indeterminate: row.isSomeSelected
}];
};
var defaultGetToggleAllRowsSelectedProps = (props, { instance }) => [props, {
onChange: (e) => {
instance.toggleAllRowsSelected(e.target.checked);
},
checked: instance.isAllRowsSelected,
indeterminate: Boolean(!instance.isAllRowsSelected && Object.keys(instance.state.selectedRowIds).length)
}];
var defaultGetToggleAllPageRowsSelectedProps = (props, { instance }) => [props, {
onChange(e) {
instance.toggleAllPageRowsSelected(e.target.checked);
},
checked: instance.isAllPageRowsSelected,
indeterminate: Boolean(!instance.isAllPageRowsSelected && instance.page.some(({ id }) => instance.state.selectedRowIds[id]))
}];
function reducer(state, action, previousState, instance) {
if (action.type === actions.init) return {
selectedRowIds: {},
lockedSelectionRowIds: {},
...state
};
if (action.type === actions.resetSelectedRows) return {
...state,
selectedRowIds: instance.initialState.selectedRowIds || {}
};
if (action.type === actions.toggleAllRowsSelected) {
const { value: setSelected } = action;
const { isAllRowsSelected, rowsById, initialRowsById, nonGroupedRowsById = rowsById, applyToggleAllRowsSelectedToPrefilteredRows } = instance;
const rowsToSelect = applyToggleAllRowsSelectedToPrefilteredRows ? initialRowsById : nonGroupedRowsById;
const selectAll = setSelected ?? !isAllRowsSelected;
const selectedRowIds = { ...state.selectedRowIds };
if (selectAll) Object.keys(rowsToSelect).forEach((rowId) => {
if (!state.lockedSelectionRowIds[rowId]) selectedRowIds[rowId] = true;
});
else Object.keys(rowsToSelect).forEach((rowId) => {
if (!state.lockedSelectionRowIds[rowId]) delete selectedRowIds[rowId];
});
return {
...state,
selectedRowIds
};
}
if (action.type === actions.toggleRowSelected) {
const { id, value: setSelected } = action;
if (state.lockedSelectionRowIds[id]) return state;
const { rowsById, selectSubRows = true, getSubRows } = instance;
const isSelected = state.selectedRowIds[id];
const shouldExist = setSelected ?? !isSelected;
if (isSelected === shouldExist) return state;
const newSelectedRowIds = { ...state.selectedRowIds };
const handleRowById = (rowId) => {
const row = rowsById[rowId];
if (!row.isGrouped) if (shouldExist) newSelectedRowIds[rowId] = true;
else delete newSelectedRowIds[rowId];
if (selectSubRows && getSubRows(row)) getSubRows(row).forEach((subrow) => {
handleRowById(subrow.id);
});
};
handleRowById(id);
return {
...state,
selectedRowIds: newSelectedRowIds
};
}
if (action.type === actions.toggleAllPageRowsSelected) {
const { value: setSelected } = action;
const { page, rowsById, selectSubRows = true, isAllPageRowsSelected, getSubRows } = instance;
const selectAll = setSelected ?? !isAllPageRowsSelected;
const newSelectedRowIds = { ...state.selectedRowIds };
const handleRowById = (rowId) => {
const row = rowsById[rowId];
if (!state.lockedSelectionRowIds[rowId] && !row.isGrouped) if (selectAll) newSelectedRowIds[rowId] = true;
else delete newSelectedRowIds[rowId];
if (selectSubRows && getSubRows(row)) getSubRows(row).forEach((subrow) => {
handleRowById(subrow.id);
});
};
page.forEach((row) => handleRowById(row.id));
return {
...state,
selectedRowIds: newSelectedRowIds
};
}
if (action.type === actions.resetLockedSelectionRows) return {
...state,
lockedSelectionRowIds: instance.initialState.lockedSelectionRowIds || {}
};
if (action.type === actions.toggleRowLockedSelection) {
const { id, value: setLockedSelection } = action;
const { rowsById, selectSubRows = true, getSubRows } = instance;
const isLockedSelection = state.lockedSelectionRowIds[id];
const shouldExist = setLockedSelection ?? !isLockedSelection;
if (isLockedSelection === shouldExist) return state;
const newLockedSelectionRowIds = { ...state.lockedSelectionRowIds };
const handleRowById = (rowId) => {
const row = rowsById[rowId];
if (!row.isGrouped) if (shouldExist) newLockedSelectionRowIds[rowId] = true;
else delete newLockedSelectionRowIds[rowId];
if (selectSubRows && getSubRows(row)) getSubRows(row).forEach((subrow) => {
handleRowById(subrow.id);
});
};
handleRowById(id);
return {
...state,
lockedSelectionRowIds: newLockedSelectionRowIds
};
}
return state;
}
function getRowIsSelected(row, selectedRowIds, getSubRows) {
if (selectedRowIds[row.id]) return true;
const subRows = getSubRows(row);
if (subRows?.length) {
let allChildrenSelected = true;
let someSelected = false;
subRows.forEach((subRow) => {
if (someSelected && !allChildrenSelected) return;
if (getRowIsSelected(subRow, selectedRowIds, getSubRows)) someSelected = true;
else allChildrenSelected = false;
});
if (allChildrenSelected) return true;
if (someSelected) return null;
}
return false;
}
function useInstance(instance) {
const { data, rows, getHooks, plugins, rowsById, initialRowsById, nonGroupedRowsById = rowsById, autoResetSelectedRows = true, autoResetLockedSelectionRows = true, state: { selectedRowIds, lockedSelectionRowIds }, selectSubRows = true, dispatch, page, getSubRows, applyToggleAllRowsSelectedToPrefilteredRows } = instance;
ensurePluginOrder(plugins, [
"useFilters",
"useGroupBy",
"useSortBy",
"useExpanded",
"usePagination"
], "useHvRowSelection");
const rowsToSelect = applyToggleAllRowsSelectedToPrefilteredRows ? initialRowsById : nonGroupedRowsById;
const selectedFlatRows = useMemo(() => {
const selectedRows = [];
rows.forEach((row) => {
const isSelected = selectSubRows ? getRowIsSelected(row, selectedRowIds, getSubRows) : !!selectedRowIds[row.id];
row.isSelected = !!isSelected;
row.isSomeSelected = isSelected === null;
if (isSelected) selectedRows.push(row);
});
return selectedRows;
}, [
rows,
selectSubRows,
selectedRowIds,
getSubRows
]);
const existsLockedRows = !!Object.keys(lockedSelectionRowIds).length;
const isNoRowsSelected = !(Object.keys(rowsToSelect).length && selectedFlatRows.length);
let isNoPageRowsSelected;
let isAllRowsSelected;
let isAllPageRowsSelected;
let isAllSelectableRowsUnselected;
let isAllSelectablePageRowsUnselected;
let isAllSelectableRowsSelected;
let isAllSelectablePageRowsSelected;
if (isNoRowsSelected) {
isAllRowsSelected = false;
isAllPageRowsSelected = false;
isAllSelectableRowsSelected = existsLockedRows && !Object.keys(rowsToSelect).some((id) => !lockedSelectionRowIds[id]);
isAllSelectablePageRowsSelected = isAllSelectableRowsSelected;
isAllSelectableRowsUnselected = isAllSelectableRowsSelected;
isAllSelectablePageRowsUnselected = isAllSelectableRowsSelected;
isNoPageRowsSelected = true;
} else {
isAllRowsSelected = !Object.keys(rowsToSelect).some((id) => !selectedRowIds[id]);
if (isAllRowsSelected) {
isAllSelectableRowsSelected = true;
isAllSelectablePageRowsSelected = true;
isAllSelectableRowsUnselected = existsLockedRows && Object.keys(rowsToSelect).filter((id) => !lockedSelectionRowIds[id]).length === 0;
isAllSelectablePageRowsUnselected = isAllSelectableRowsUnselected;
isNoPageRowsSelected = false;
isAllPageRowsSelected = true;
} else {
isAllSelectableRowsSelected = existsLockedRows && !Object.keys(rowsToSelect).filter((id) => !lockedSelectionRowIds[id]).some((id) => !selectedRowIds[id]);
isAllSelectableRowsUnselected = !existsLockedRows || !Object.keys(rowsToSelect).filter((id) => !lockedSelectionRowIds[id]).some((id) => selectedRowIds[id]);
isAllPageRowsSelected = !(page?.length && page.some(({ id }) => !selectedRowIds[id]));
if (isAllPageRowsSelected) {
isAllSelectablePageRowsSelected = true;
isAllSelectablePageRowsUnselected = existsLockedRows && page && page.length && page.filter(({ id }) => !lockedSelectionRowIds[id]).length === 0;
isNoPageRowsSelected = false;
} else {
isAllSelectablePageRowsSelected = existsLockedRows && !(page?.length && page.filter(({ id }) => !lockedSelectionRowIds[id]).some(({ id }) => !selectedRowIds[id]));
isAllSelectablePageRowsUnselected = !existsLockedRows || !(page?.length && page.filter(({ id }) => !lockedSelectionRowIds[id]).some(({ id }) => selectedRowIds[id]));
isNoPageRowsSelected = !(page?.length && page.some(({ id }) => selectedRowIds[id]));
}
}
}
const getAutoResetSelectedRows = useGetLatest(autoResetSelectedRows);
const getAutoResetLockedSelectionRows = useGetLatest(autoResetLockedSelectionRows);
useMountedLayoutEffect(() => {
if (getAutoResetSelectedRows()) dispatch({ type: actions.resetSelectedRows });
if (getAutoResetLockedSelectionRows()) dispatch({ type: actions.resetLockedSelectionRows });
}, [dispatch, data]);
const toggleAllRowsSelected = useCallback((value) => dispatch({
type: actions.toggleAllRowsSelected,
value
}), [dispatch]);
const toggleAllPageRowsSelected = useCallback((value) => dispatch({
type: actions.toggleAllPageRowsSelected,
value
}), [dispatch]);
const toggleRowSelected = useCallback((id, value) => dispatch({
type: actions.toggleRowSelected,
id,
value
}), [dispatch]);
const getInstance = useGetLatest(instance);
const getToggleAllRowsSelectedProps = makePropGetter(getHooks().getToggleAllRowsSelectedProps, { instance: getInstance() });
const getToggleAllPageRowsSelectedProps = makePropGetter(getHooks().getToggleAllPageRowsSelectedProps, { instance: getInstance() });
const toggleRowLockedSelection = useCallback((id, value) => dispatch({
type: actions.toggleRowLockedSelection,
id,
value
}), [dispatch]);
Object.assign(instance, {
selectedFlatRows,
isNoRowsSelected,
isNoPageRowsSelected,
isAllRowsSelected,
isAllPageRowsSelected,
isAllSelectableRowsSelected,
isAllSelectablePageRowsSelected,
isAllSelectableRowsUnselected,
isAllSelectablePageRowsUnselected,
toggleRowSelected,
toggleAllRowsSelected,
getToggleAllRowsSelectedProps,
getToggleAllPageRowsSelectedProps,
toggleAllPageRowsSelected,
toggleRowLockedSelection
});
}
function prepareRow(row, { instance }) {
row.toggleRowSelected = (set) => instance.toggleRowSelected(row.id, set);
row.getToggleRowSelectedProps = makePropGetter(instance.getHooks().getToggleRowSelectedProps, {
instance,
row
});
row.toggleRowLockedSelection = (set) => instance.toggleRowLockedSelection(row.id, set);
row.isSelectionLocked = instance.state?.lockedSelectionRowIds?.[row.id] || false;
}
var useHvRowSelection = (hooks) => {
hooks.visibleColumns.push(visibleColumnsHook);
hooks.getRowProps.push(getRowPropsHook);
hooks.getHeaderProps.push(getHeaderPropsHook);
hooks.getToggleRowSelectedProps = [defaultGetToggleRowSelectedProps];
hooks.getToggleAllRowsSelectedProps = [defaultGetToggleAllRowsSelectedProps];
hooks.getToggleAllPageRowsSelectedProps = [defaultGetToggleAllPageRowsSelectedProps];
hooks.stateReducers.push(reducer);
hooks.useInstance.push(useInstance);
hooks.prepareRow.push(prepareRow);
};
useHvRowSelection.pluginName = "useHvRowSelection";
//#endregion
export { useHvRowSelection };