Commit 0b26d21c authored by tom's avatar tom

clear button

parent 45591ba9
...@@ -109,6 +109,11 @@ const SearchResultsPageContent = () => { ...@@ -109,6 +109,11 @@ const SearchResultsPageContent = () => {
inputRef.current?.querySelector('input')?.blur(); inputRef.current?.querySelector('input')?.blur();
}, [ ]); }, [ ]);
const handleClear = React.useCallback(() => {
handleSearchTermChange('');
inputRef.current?.querySelector('input')?.focus();
}, [ handleSearchTermChange ]);
const renderSearchBar = React.useCallback(() => { const renderSearchBar = React.useCallback(() => {
return ( return (
<SearchBarInput <SearchBarInput
...@@ -117,9 +122,10 @@ const SearchResultsPageContent = () => { ...@@ -117,9 +122,10 @@ const SearchResultsPageContent = () => {
onSubmit={ handleSubmit } onSubmit={ handleSubmit }
value={ searchTerm } value={ searchTerm }
onHide={ handelHide } onHide={ handelHide }
onClear={ handleClear }
/> />
); );
}, [ handleSearchTermChange, handleSubmit, searchTerm, handelHide ]); }, [ handleSearchTermChange, handleSubmit, searchTerm, handelHide, handleClear ]);
const renderHeader = React.useCallback(() => { const renderHeader = React.useCallback(() => {
return <Header renderSearchBar={ renderSearchBar }/>; return <Header renderSearchBar={ renderSearchBar }/>;
......
...@@ -5,18 +5,20 @@ import crossIcon from 'icons/cross.svg'; ...@@ -5,18 +5,20 @@ import crossIcon from 'icons/cross.svg';
interface Props { interface Props {
onClick: () => void; onClick: () => void;
className?: string;
} }
const InputClearButton = ({ onClick }: Props) => { const InputClearButton = ({ onClick, className }: Props) => {
const iconColor = useColorModeValue('blackAlpha.600', 'whiteAlpha.600'); const iconColor = useColorModeValue('blackAlpha.600', 'whiteAlpha.600');
return ( return (
<IconButton <IconButton
className={ className }
colorScheme="gray" colorScheme="gray"
aria-label="Clear input" aria-label="Clear input"
title="Clear input" title="Clear input"
boxSize={ 6 } boxSize={ 6 }
icon={ <Icon as={ crossIcon } boxSize={ 4 } color={ iconColor }/> } icon={ <Icon as={ crossIcon } boxSize={ 4 } color={ iconColor } focusable={ false }/> }
size="sm" size="sm"
onClick={ onClick } onClick={ onClick }
/> />
......
...@@ -42,11 +42,17 @@ const SearchBar = ({ isHomepage }: Props) => { ...@@ -42,11 +42,17 @@ const SearchBar = ({ isHomepage }: Props) => {
const handleBlur = React.useCallback((event: FocusEvent<HTMLFormElement>) => { const handleBlur = React.useCallback((event: FocusEvent<HTMLFormElement>) => {
const isFocusInMenu = menuRef.current?.contains(event.relatedTarget); const isFocusInMenu = menuRef.current?.contains(event.relatedTarget);
if (!isFocusInMenu) { const isFocusInInput = inputRef.current?.contains(event.relatedTarget);
if (!isFocusInMenu && !isFocusInInput) {
onClose(); onClose();
} }
}, [ onClose ]); }, [ onClose ]);
const handleClear = React.useCallback(() => {
handleSearchTermChange('');
inputRef.current?.querySelector('input')?.focus();
}, [ handleSearchTermChange ]);
const menuPaddingX = isMobile && !isHomepage ? 32 : 0; const menuPaddingX = isMobile && !isHomepage ? 32 : 0;
const calculateMenuWidth = React.useCallback(() => { const calculateMenuWidth = React.useCallback(() => {
menuWidth.current = (inputRef.current?.getBoundingClientRect().width || 0) - menuPaddingX; menuWidth.current = (inputRef.current?.getBoundingClientRect().width || 0) - menuPaddingX;
...@@ -85,6 +91,7 @@ const SearchBar = ({ isHomepage }: Props) => { ...@@ -85,6 +91,7 @@ const SearchBar = ({ isHomepage }: Props) => {
onFocus={ handleFocus } onFocus={ handleFocus }
onBlur={ handleBlur } onBlur={ handleBlur }
onHide={ handelHide } onHide={ handelHide }
onClear={ handleClear }
isHomepage={ isHomepage } isHomepage={ isHomepage }
value={ searchTerm } value={ searchTerm }
/> />
......
import { InputGroup, Input, InputLeftElement, Icon, chakra, useColorModeValue, forwardRef } from '@chakra-ui/react'; import { InputGroup, Input, InputLeftElement, Icon, chakra, useColorModeValue, forwardRef, InputRightElement } from '@chakra-ui/react';
import throttle from 'lodash/throttle'; import throttle from 'lodash/throttle';
import React from 'react'; import React from 'react';
import type { ChangeEvent, FormEvent, FocusEvent } from 'react'; import type { ChangeEvent, FormEvent, FocusEvent } from 'react';
...@@ -6,18 +6,20 @@ import type { ChangeEvent, FormEvent, FocusEvent } from 'react'; ...@@ -6,18 +6,20 @@ import type { ChangeEvent, FormEvent, FocusEvent } from 'react';
import searchIcon from 'icons/search.svg'; import searchIcon from 'icons/search.svg';
import { useScrollDirection } from 'lib/contexts/scrollDirection'; import { useScrollDirection } from 'lib/contexts/scrollDirection';
import useIsMobile from 'lib/hooks/useIsMobile'; import useIsMobile from 'lib/hooks/useIsMobile';
import InputClearButton from 'ui/shared/InputClearButton';
interface Props { interface Props {
onChange: (event: ChangeEvent<HTMLInputElement>) => void; onChange: (value: string) => void;
onSubmit: (event: FormEvent<HTMLFormElement>) => void; onSubmit: (event: FormEvent<HTMLFormElement>) => void;
onBlur?: (event: FocusEvent<HTMLFormElement>) => void; onBlur?: (event: FocusEvent<HTMLFormElement>) => void;
onFocus?: () => void; onFocus?: () => void;
onHide?: () => void; onHide?: () => void;
onClear: () => void;
isHomepage?: boolean; isHomepage?: boolean;
value: string; value: string;
} }
const SearchBarInput = ({ onChange, onSubmit, isHomepage, onFocus, onBlur, onHide, value }: Props, ref: React.ForwardedRef<HTMLFormElement>) => { const SearchBarInput = ({ onChange, onSubmit, isHomepage, onFocus, onBlur, onHide, onClear, value }: Props, ref: React.ForwardedRef<HTMLFormElement>) => {
const [ isSticky, setIsSticky ] = React.useState(false); const [ isSticky, setIsSticky ] = React.useState(false);
const scrollDirection = useScrollDirection(); const scrollDirection = useScrollDirection();
const isMobile = useIsMobile(); const isMobile = useIsMobile();
...@@ -30,6 +32,10 @@ const SearchBarInput = ({ onChange, onSubmit, isHomepage, onFocus, onBlur, onHid ...@@ -30,6 +32,10 @@ const SearchBarInput = ({ onChange, onSubmit, isHomepage, onFocus, onBlur, onHid
} }
}, [ ]); }, [ ]);
const handleChange = React.useCallback((event: ChangeEvent<HTMLInputElement>) => {
onChange(event.target.value);
}, [ onChange ]);
React.useEffect(() => { React.useEffect(() => {
if (!isMobile || isHomepage) { if (!isMobile || isHomepage) {
return; return;
...@@ -85,16 +91,25 @@ const SearchBarInput = ({ onChange, onSubmit, isHomepage, onFocus, onBlur, onHid ...@@ -85,16 +91,25 @@ const SearchBarInput = ({ onChange, onSubmit, isHomepage, onFocus, onBlur, onHid
sx={{ sx={{
'@media screen and (max-width: 999px)': { '@media screen and (max-width: 999px)': {
paddingLeft: isHomepage ? '50px' : '38px', paddingLeft: isHomepage ? '50px' : '38px',
paddingRight: '36px',
},
'@media screen and (min-width: 1001px)': {
paddingRight: '36px',
}, },
}} }}
placeholder={ isMobile ? 'Search by addresses / ... ' : 'Search by addresses / transactions / block / token... ' } placeholder={ isMobile ? 'Search by addresses / ... ' : 'Search by addresses / transactions / block / token... ' }
onChange={ onChange } onChange={ handleChange }
border={ isHomepage ? 'none' : '2px solid' } border={ isHomepage ? 'none' : '2px solid' }
borderColor={ useColorModeValue('blackAlpha.100', 'whiteAlpha.200') } borderColor={ useColorModeValue('blackAlpha.100', 'whiteAlpha.200') }
_focusWithin={{ _placeholder: { color: 'gray.300' } }} _focusWithin={{ _placeholder: { color: 'gray.300' } }}
color={ useColorModeValue('black', 'white') } color={ useColorModeValue('black', 'white') }
value={ value } value={ value }
/> />
{ value && (
<InputRightElement top={{ base: 2, lg: '18px' }} right={ 2 }>
<InputClearButton onClick={ onClear }/>
</InputRightElement>
) }
</InputGroup> </InputGroup>
</chakra.form> </chakra.form>
); );
......
import { useRouter } from 'next/router'; import { useRouter } from 'next/router';
import type { ChangeEvent } from 'react';
import React from 'react'; import React from 'react';
import useDebounce from 'lib/hooks/useDebounce'; import useDebounce from 'lib/hooks/useDebounce';
...@@ -20,10 +19,6 @@ export default function useSearchQuery(isSearchPage = false) { ...@@ -20,10 +19,6 @@ export default function useSearchQuery(isSearchPage = false) {
options: { enabled: debouncedSearchTerm.trim().length > 0 }, options: { enabled: debouncedSearchTerm.trim().length > 0 },
}); });
const handleSearchTermChange = React.useCallback((event: ChangeEvent<HTMLInputElement>) => {
setSearchTerm(event.target.value);
}, []);
useUpdateValueEffect(() => { useUpdateValueEffect(() => {
if (isSearchPage) { if (isSearchPage) {
query.onFilterChange({ q: debouncedSearchTerm }); query.onFilterChange({ q: debouncedSearchTerm });
...@@ -33,7 +28,7 @@ export default function useSearchQuery(isSearchPage = false) { ...@@ -33,7 +28,7 @@ export default function useSearchQuery(isSearchPage = false) {
return { return {
searchTerm, searchTerm,
debouncedSearchTerm, debouncedSearchTerm,
handleSearchTermChange, handleSearchTermChange: setSearchTerm,
query, query,
}; };
} }
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment