import { observer } from 'mobx-react-lite'; import { Box, Search, SearchProps, TextButton } from '@wix/design-system'; import React, { CSSProperties, useState, useRef, useCallback, useEffect, } from 'react'; import { FiltersMap } from '@wix/bex-core'; import { useCollectionContext } from '@wix/bex-core/react'; import { useIsMobile } from '../hooks/useIsMobile'; import { useBmHarmonyTheme } from '../hooks/useBmHarmonyTheme'; export interface CollectionSearchProps extends Partial { onSearchChange?: (value: string) => unknown; onSearchClick?: () => unknown; onSearchBlur?: (value: string) => unknown; visibility?: CSSProperties['visibility']; } export const CollectionSearch = observer(function CollectionSearch< T, F extends FiltersMap = FiltersMap, >({ onSearchChange, onSearchClick, onSearchBlur, visibility, expandable, ...rest }: CollectionSearchProps) { const collection = useCollectionContext(); const { query: { search }, translate: t, } = collection; const isMobile = useIsMobile(); const isBmHarmonyTheme = useBmHarmonyTheme(); const [isSearchExpanded, setIsSearchExpanded] = useState(!!search.value); const searchInputRef = useRef(null); useEffect(() => { collection.searchInputRef = { focus: () => { searchInputRef.current?.focus(); }, }; return () => { collection.searchInputRef = null; }; }, [collection]); const handleCancel = useCallback(() => { collection.clearSearch(); onSearchChange?.(''); if (searchInputRef.current) { searchInputRef.current.blur(); setIsSearchExpanded(false); } }, [collection, onSearchChange]); const showCancelButton = isMobile && isSearchExpanded; const searchElement = ( { const value = e.target.value; collection.search(e.target.value, { clearResult: true }); onSearchChange?.(value); }} ref={searchInputRef} value={search.value} onClear={() => { const value = ''; collection.clearSearch(); onSearchChange?.(value); }} expandable={expandable} expandDirection={isMobile ? 'left' : undefined} placeholder={t('cairo.searchPlaceholder', { defaultValue: '' })} border={isBmHarmonyTheme ? 'standard' : undefined} textOverflow="ellipsis" onFocus={() => { setIsSearchExpanded(true); }} onBlur={(e) => { const value = e.target.value; if (!value) { setIsSearchExpanded(false); } onSearchBlur?.(value); }} {...rest} /> ); if (isMobile && expandable) { return ( {searchElement} {showCancelButton && ( {t('cairo.cancel.button')} )} ); } return searchElement; });