import { isSameBoardWord } from '@scrabble-solver/types'; import classNames from 'classnames'; import { type FunctionComponent, useCallback, useEffect, useMemo } from 'react'; import { useDispatch } from 'react-redux'; import { List } from 'react-window'; import { EmptyState } from '@/components/EmptyState'; import { Header, HeaderButton, Search } from '@/components/Table'; import { useIsCompactLayout } from '@/hooks/useIsCompactLayout'; import { useIsTouchDevice } from '@/hooks/useIsTouchDevice'; import { LOCALE_FEATURES } from '@/i18n/constants'; import GeoAlt from '@/icons/GeoAlt.svg'; import QuestionSquare from '@/icons/QuestionSquare.svg'; import { RESULTS_ITEM_HEIGHT, RESULTS_OVERSCAN_COUNT } from '@/parameters'; import { hoveredWordSlice, selectHoveredWord, selectLocale, selectProcessedWords, selectWordsQuery, selectWordsSort, useTranslate, useTypedSelector, verifySlice, } from '@/state'; import { WordColumnId } from '@/types'; import { WordRow, type WordRowData } from './WordRow'; import styles from './WordsTable.module.scss'; interface Props { className?: string; isOpen: boolean; onPreview: () => void; } export const WordsTable: FunctionComponent = ({ className, isOpen, onPreview }) => { const dispatch = useDispatch(); const translate = useTranslate(); const isTouchDevice = useIsTouchDevice(); const isCompactLayout = useIsCompactLayout(); const highlightFollowsPointer = !isTouchDevice && !isCompactLayout; const locale = useTypedSelector(selectLocale); const { direction } = LOCALE_FEATURES[locale]; const words = useTypedSelector(selectProcessedWords); const query = useTypedSelector(selectWordsQuery); const sort = useTypedSelector(selectWordsSort); const hoveredWord = useTypedSelector(selectHoveredWord); const highlightedIndex = hoveredWord ? words.findIndex((word) => isSameBoardWord(word, hoveredWord)) : -1; const rowProps = useMemo( () => ({ highlightFollowsPointer, highlightedIndex, isTouchDevice, words, onPreview }), [highlightFollowsPointer, highlightedIndex, isTouchDevice, words, onPreview], ); const handleSort = useCallback( (columnId: WordColumnId) => { dispatch(verifySlice.actions.sort(columnId)); }, [dispatch], ); const handleQueryChange = useCallback( (newQuery: string) => { dispatch(verifySlice.actions.changeQuery(newQuery)); }, [dispatch], ); const handleMouseLeave = useCallback(() => { dispatch(hoveredWordSlice.actions.clear()); }, [dispatch]); useEffect(() => { if (isOpen && isCompactLayout && words.length > 0 && highlightedIndex === -1) { dispatch(hoveredWordSlice.actions.set(words[0])); } }, [dispatch, highlightedIndex, isOpen, isCompactLayout, words]); return (
{words.length === 0 && {translate('words.empty-state.no-words')}} {words.length > 0 && (
)}
{words.length > 0 && ( )}
); };