UNPKG

@sinchsmb/ui-kit

Version:

UI kit for SinchSMB frontend

99 lines (86 loc) 3.42 kB
import { useCallback, useMemo } from 'react'; import { useTranslation } from '../../../core/hooks/useTranslation'; import { useToast } from '../../../core/managers/ToastManager/hooks/useToast'; import { assertUnreachable } from '../../../utils/assertUnreachable'; import { ToastAppearance } from '../../Toast/constants'; import { TableSelectionType } from '../constants'; import { useTableCellContext } from '../contexts/TableCellContext'; import { useTablePropsContext } from '../contexts/TablePropsContext'; import { useTableSelectionContext } from '../contexts/TableSelectionContext'; /** Result of {@link useSingleRowSelection} hook. */ export interface UseSingleRowSelectionResult { /** Flag indicating current row is selected. */ isSingleRowSelected: boolean; /** Function that will toggle current row selection. */ onSingleRowSelectionChange: (selected: boolean) => void; } /** Hook that returns information about current row selection. */ export function useSingleRowSelection(): UseSingleRowSelectionResult { const { t } = useTranslation(); const showToast = useToast(); const { rowNumber } = useTableCellContext(); const { selection, onSelectionChanged } = useTableSelectionContext(); const { rows, rowIdProvider, rowSelectionIncludeLimit, rowSelectionName } = useTablePropsContext(); const headerRowsCount = 1; const rowId = useMemo(() => { const dataRowNumber = rowNumber - headerRowsCount; return rowIdProvider(rows[dataRowNumber]); }, [rowIdProvider, rowNumber, rows]); const onSingleRowSelectionChange = useCallback( (selected: boolean) => { if (!onSelectionChanged) { return; } if (selection?.type === TableSelectionType.Exclude) { const unselectedIds = new Set(selection.unselectedIds); if (selected) { unselectedIds.delete(rowId); } else { unselectedIds.add(rowId); } onSelectionChanged({ type: TableSelectionType.Exclude, unselectedIds: Array.from(unselectedIds), }); } else { const selectedIds = new Set(selection?.selectedIds ?? []); if (selected) { selectedIds.add(rowId); } else { selectedIds.delete(rowId); } if (rowSelectionIncludeLimit && selectedIds.size > rowSelectionIncludeLimit) { const message = t('ui.table.selectionIncludeLimit', { count: rowSelectionIncludeLimit, actionText: t('ui.table.selectAll'), name: rowSelectionName, }); showToast(message, { appearance: ToastAppearance.Warning }); } onSelectionChanged({ type: TableSelectionType.Include, selectedIds: Array.from(selectedIds).slice(0, rowSelectionIncludeLimit), }); } }, [onSelectionChanged, selection, rowId, rowSelectionIncludeLimit, t, rowSelectionName, showToast], ); const isSingleRowSelected = useMemo(() => { if (!selection) { return false; } switch (selection.type) { case TableSelectionType.Exclude: return !selection.unselectedIds.has(rowId); case TableSelectionType.Include: return selection.selectedIds.has(rowId); /* istanbul ignore next */ default: assertUnreachable(selection); } }, [rowId, selection]); return { onSingleRowSelectionChange, isSingleRowSelected, }; }