UNPKG

@shopify/polaris

Version:

Shopify’s admin product component library

190 lines (165 loc) 5.23 kB
import {useContext, useRef, useCallback} from 'react'; import {useI18n} from '../i18n'; import { SELECT_ALL_ITEMS, SelectionType, HandleSelectionChange, Range, BulkSelectionDataOptions, HandleBulkSelectionOptions, } from './types'; import { IndexContext, IndexRowContext, IndexSelectionChangeContext, } from './context'; export function useIndexSelectionChange() { const onSelectionChange = useContext(IndexSelectionChangeContext); if (!onSelectionChange) { throw new Error(`Missing IndexProvider context`); } return onSelectionChange; } export function useIndexRow() { const indexRow = useContext(IndexRowContext); if (!indexRow) { throw new Error(`Missing IndexProvider context`); } return indexRow; } export function useIndexValue() { const index = useContext(IndexContext); if (!index) { throw new Error(`Missing IndexProvider context`); } return index; } export function useBulkSelectionData({ selectedItemsCount, itemCount, hasMoreItems, resourceName: passedResourceName, }: BulkSelectionDataOptions) { const i18n = useI18n(); const selectable = Boolean(selectedItemsCount); const selectMode = selectedItemsCount === 'All' || selectedItemsCount > 0; const defaultResourceName = { singular: i18n.translate('Polaris.IndexProvider.defaultItemSingular'), plural: i18n.translate('Polaris.IndexProvider.defaultItemPlural'), }; const resourceName = passedResourceName ? passedResourceName : defaultResourceName; const paginatedSelectAllText = getPaginatedSelectAllText(); const bulkActionsLabel = getBulkActionsLabel(); const bulkActionsAccessibilityLabel = getBulkActionsAccessibilityLabel(); let bulkSelectState: boolean | 'indeterminate' | undefined = 'indeterminate'; if (!selectedItemsCount || selectedItemsCount === 0) { bulkSelectState = undefined; } else if ( selectedItemsCount === SELECT_ALL_ITEMS || selectedItemsCount === itemCount ) { bulkSelectState = true; } return { paginatedSelectAllText, bulkActionsLabel, bulkActionsAccessibilityLabel, resourceName, selectMode, bulkSelectState, selectable, }; function getPaginatedSelectAllText() { if (!selectable || !hasMoreItems) { return; } if (selectedItemsCount === SELECT_ALL_ITEMS) { return i18n.translate('Polaris.IndexProvider.allItemsSelected', { itemsLength: itemCount, resourceNamePlural: resourceName.plural.toLocaleLowerCase(), }); } } function getBulkActionsLabel() { const selectedItemsCountLabel = selectedItemsCount === SELECT_ALL_ITEMS ? `${itemCount}+` : selectedItemsCount; return i18n.translate('Polaris.IndexProvider.selected', { selectedItemsCount: selectedItemsCountLabel, }); } function getBulkActionsAccessibilityLabel() { const totalItemsCount = itemCount; const allSelected = selectedItemsCount === totalItemsCount; if (totalItemsCount === 1 && allSelected) { return i18n.translate( 'Polaris.IndexProvider.a11yCheckboxDeselectAllSingle', { resourceNameSingular: resourceName.singular, }, ); } else if (totalItemsCount === 1) { return i18n.translate( 'Polaris.IndexProvider.a11yCheckboxSelectAllSingle', { resourceNameSingular: resourceName.singular, }, ); } else if (allSelected) { return i18n.translate( 'Polaris.IndexProvider.a11yCheckboxDeselectAllMultiple', { itemsLength: itemCount, resourceNamePlural: resourceName.plural, }, ); } else { return i18n.translate( 'Polaris.IndexProvider.a11yCheckboxSelectAllMultiple', { itemsLength: itemCount, resourceNamePlural: resourceName.plural, }, ); } } } export function useHandleBulkSelection({ onSelectionChange = () => {}, }: HandleBulkSelectionOptions) { const lastSelected = useRef<number | null>(null); const handleSelectionChange: HandleSelectionChange = useCallback( ( selectionType: SelectionType, toggleType: boolean, selection?: string | Range, sortOrder?: number, ) => { const prevSelected = lastSelected.current; if (SelectionType.Multi && typeof sortOrder === 'number') { lastSelected.current = sortOrder; } if ( selectionType === SelectionType.Single || (selectionType === SelectionType.Multi && (typeof prevSelected !== 'number' || typeof sortOrder !== 'number')) ) { onSelectionChange(SelectionType.Single, toggleType, selection); } else if (selectionType === SelectionType.Multi) { const min = Math.min(prevSelected as number, sortOrder as number); const max = Math.max(prevSelected as number, sortOrder as number); onSelectionChange(selectionType, toggleType, [min, max]); } else if ( selectionType === SelectionType.Page || selectionType === SelectionType.All ) { onSelectionChange(selectionType, toggleType); } }, [onSelectionChange], ); return handleSelectionChange; }