import { useCallback , useMemo } from 'react' ; import { Cell , WorksheetItem } from '../../types' ; import { useStore } from '../useStore' ; interface Coordinate { columnIndex : number ; rowIndex : number ; } type Navigate = ( offset : Coordinate ) => void ; export const useNavigation = < T extends WorksheetItem > ( selectedCell ) => { const rows = useStore ( useMemo ( ( ) => ( state ) => state . rows , [ ] ) ) ; const columns = useStore ( useMemo ( ( ) => ( state ) => state . columns , [ ] ) ) ; const hiddenRows = useStore ( useMemo ( ( ) => ( state ) => state . hiddenRows , [ ] ) ) ; const setSelectedCells = useStore ( ( state ) => state . setSelectedCells ) ; const setSelectedRows = useStore ( ( state ) => state . setSelectedRows ) ; const isValidPosition = useCallback ( ( position ) => { const rowLength = rows . length ; const columnsLength = columns . length ; return ( position . rowIndex >= 0 && position . rowIndex < rowLength && position . columnIndex >= 0 && position . columnIndex < columnsLength ) ; } , [ columns , rows ] ) ; const isHidden = useCallback ( ( rowIndex ) => { const row = rows [ rowIndex ] ; const { id } = row ; return hiddenRows . includes ( id ) ; } , [ hiddenRows , rows ] ) ; const getNextOffset = useCallback ( ( { columnIndex , rowIndex } ) => { if ( rowIndex === 0 ) { if ( columnIndex > 0 ) { return { columnIndex : ++ columnIndex , rowIndex } ; } return { columnIndex : -- columnIndex , rowIndex } ; } if ( rowIndex > 0 ) { return { rowIndex : ++ rowIndex , columnIndex } ; } return { rowIndex : -- rowIndex , columnIndex } ; } , [ ] ) ; const navigate = useCallback ( ( offset ) => { if ( ! selectedCell ) { return ; } const newPosition = { columnIndex : selectedCell . columnIndex + offset . columnIndex , rowIndex : selectedCell . rowIndex + offset . rowIndex } ; if ( isValidPosition ( newPosition ) ) { if ( isHidden ( newPosition . rowIndex ) ) { return navigate ( getNextOffset ( offset ) ) ; } const hash = columns [ newPosition . columnIndex ] . hash ; const type = columns [ newPosition . columnIndex ] . type || 'text' ; const value = rows [ newPosition . rowIndex ] [ hash ] ; const disabled = columns [ newPosition . columnIndex ] . disabled || false ; const cell = { ... newPosition , disabled , hash , type , value } ; setSelectedCells ( [ cell ] ) ; setSelectedRows ( [ newPosition . rowIndex ] ) ; } } , [ columns , getNextOffset , isHidden , isValidPosition , rows , selectedCell , setSelectedCells , setSelectedRows ] ) ; return useMemo ( ( ) => ( { navigate } ) , [ navigate ] ) ; } ;