Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Tweak the search field based on design input #689

Merged
merged 8 commits into from
Jul 7, 2023
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions .changelog/689.trivial.md
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
Tweak the search field design and behavior
71 changes: 57 additions & 14 deletions src/app/components/Search/index.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@ import { RouteUtils } from '../../utils/route-utils'
import { useScreenSize } from '../../hooks/useScreensize'
import HighlightOffIcon from '@mui/icons-material/HighlightOff'
import ErrorIcon from '@mui/icons-material/Error'
import WarningIcon from '@mui/icons-material/Warning'
import IconButton from '@mui/material/IconButton'
import { SearchSuggestionsButtons } from './SearchSuggestionsButtons'
import { formHelperTextClasses } from '@mui/material/FormHelperText'
Expand All @@ -19,6 +20,7 @@ import { SearchScope } from '../../../types/searchScope'
import { textSearchMininumLength } from './search-utils'
import Typography from '@mui/material/Typography'
import { isValidBlockHeight } from '../../utils/helpers'
import { typingDelay } from '../../../styles/theme'
import { isValidMnemonic } from '../../utils/helpers'

export type SearchVariant = 'button' | 'icon' | 'expandable'
Expand Down Expand Up @@ -105,6 +107,7 @@ const SearchCmp: FC<SearchProps> = ({ scope, variant, disabled, onFocusChange: o
const [value, setValue] = useState('')
const [isFocused, setIsFocused] = useState(false)
const valueInSearchParams = useSearchParams()[0].get('q') ?? ''
const [isTyping, setIsTyping] = useState(false)

const wordsOfPower = t('search.wordsOfPower')
const hasWordsOfPower = value.trim().toLowerCase().startsWith(wordsOfPower.toLowerCase())
Expand All @@ -124,6 +127,7 @@ const SearchCmp: FC<SearchProps> = ({ scope, variant, disabled, onFocusChange: o

const onChange = (newValue: string) => {
setValue(newValue)
setIsTyping(true)
}

const onFocusChange = (value: boolean) => {
Expand Down Expand Up @@ -154,13 +158,22 @@ const SearchCmp: FC<SearchProps> = ({ scope, variant, disabled, onFocusChange: o
const searchButtonContent =
variant !== 'button' ? <SearchIcon sx={{ color: COLORS.grayMediumLight }} /> : t('search.searchBtnText')

const errorMessage = isTooShort
? t('search.error.tooShort')
: hasPrivacyProblem
const errorMessage = isTooShort ? t('search.error.tooShort') : undefined
const hasError = !!errorMessage

const warningMessage = hasPrivacyProblem
? t('search.error.privacy', { appName: t('appName'), wordsOfPower })
: undefined
const hasWarning = !!warningMessage

const hasError = !!errorMessage
const hasProblem = hasError || hasWarning

useEffect(() => {
const timeout = setTimeout(() => {
setIsTyping(false)
}, typingDelay)
return () => clearTimeout(timeout)
}, [value])

return (
<SearchForm
Expand All @@ -170,9 +183,18 @@ const SearchCmp: FC<SearchProps> = ({ scope, variant, disabled, onFocusChange: o
aria-label={searchPlaceholderTranslated}
>
<TextField
sx={{
...(!isTyping && hasWarning && !hasError
? {
[`& .${outlinedInputClasses.error} .${outlinedInputClasses.notchedOutline}`]: {
borderColor: COLORS.warningColor,
},
}
: {}),
}}
value={value}
onChange={e => onChange(e.target.value)}
error={hasError}
error={!isTyping && hasProblem}
onFocus={() => onFocusChange(true)}
onBlur={() => onFocusChange(false)}
InputProps={{
Expand All @@ -183,12 +205,12 @@ const SearchCmp: FC<SearchProps> = ({ scope, variant, disabled, onFocusChange: o
endAdornment: (
<InputAdornment position="end">
<>
{variant === 'icon' && value && (
{value && (
<IconButton color="inherit" onClick={onClearValue}>
<HighlightOffIcon />
</IconButton>
)}
<SearchButton disabled={disabled || hasError} searchVariant={variant} type="submit">
<SearchButton disabled={disabled || hasProblem} searchVariant={variant} type="submit">
{searchButtonContent}
</SearchButton>
</>
Expand All @@ -208,35 +230,56 @@ const SearchCmp: FC<SearchProps> = ({ scope, variant, disabled, onFocusChange: o
helperText={
value &&
value !== valueInSearchParams && (
<div>
{hasError && (
<>
{!isTyping && hasError && (
<>
<Typography
component="span"
sx={{
display: 'inline-flex',
color: COLORS.errorIndicatorBackground,
background: COLORS.linen,
fontSize: 12,
lineHeight: 2,
alignItems: 'center',
verticalAlign: 'middle',
mb: 3,
mt: 3,
mb: 4,
}}
>
<ErrorIcon />
&nbsp;
<ErrorIcon sx={{ mr: 3 }} />
{errorMessage}
</Typography>
<br />
</>
)}
{!isTyping && hasWarning && (
<>
<Typography
component="span"
sx={{
display: 'inline-flex',
color: COLORS.warningColor,
fontSize: 12,
lineHeight: 2,
alignItems: 'center',
verticalAlign: 'middle',
mt: 3,
mb: 4,
}}
>
<WarningIcon sx={{ mr: 3 }} />
{warningMessage}
</Typography>
<br />
</>
)}
<SearchSuggestionsButtons
scope={scope}
onClickSuggestion={suggestion => {
setValue(suggestion)
}}
/>
</div>
</>
)
}
/>
Expand Down
6 changes: 3 additions & 3 deletions src/locales/en/translation.json
Original file line number Diff line number Diff line change
Expand Up @@ -374,10 +374,10 @@
"soon": "soon"
},
"search": {
"placeholder": "Address, Block, Contract, Txn Hash, Transaction ID, Token name, etc",
"placeholder": "Address, Block, Contract, Transaction hash, Token name, etc.",
"error": {
"tooShort": "Please enter either at least 3 characters or a number in order to perform a search.",
"privacy": "It seems like you might accidentally entered a keyphrase for a wallet. Please note that your mnemonic is a secret key that should never be shared, even not with our {{ pagetitle }}.\nExecuting this search is highly unlikely to return any results. If you want to proceed nonetheless, please add “{{ wordsOfPower }}” in front of your search query to perform the search at your own risk."
"privacy": "It seems like you might accidentally entered a keyphrase for a wallet. Please note that your mnemonic is a secret key that should never be shared, even not with our {{ appName }}.\nExecuting this search is highly unlikely to return any results. If you want to proceed nonetheless, please add “{{ wordsOfPower }}” in front of your search query to perform the search at your own risk."
},
"mobilePlaceholder": "Search Address, Block, Txn, Token, etc",
"noResults": {
Expand Down Expand Up @@ -413,7 +413,7 @@
"moreCount_other": "{{ count }} more results"
},
"searchBtnText": "Search",
"searchSuggestions": "Not sure what to look for? Try out a search: <OptionalBreak><BlockLink><BlockIcon/> Block</BlockLink>, <TransactionLink><TransactionIcon/> Transaction</TransactionLink>, <AccountLink><AccountIcon/> Address</AccountLink>, <TokenLink><TokenIcon/> Token</TokenLink> </OptionalBreak>",
"searchSuggestions": "Not sure what to look for? Try out a search: <OptionalBreak><BlockLink><BlockIcon/> Block</BlockLink>, <TransactionLink><TransactionIcon/> Transaction</TransactionLink>, <AccountLink><AccountIcon/> Address</AccountLink>, <TokenLink><TokenIcon/> Token</TokenLink> </OptionalBreak>.",
"sectionHeader": "Results on {{ scope }}",
"wordsOfPower": "I COMMAND THEE TO SEARCH FOR"
}
Expand Down
3 changes: 0 additions & 3 deletions src/styles/theme/defaultTheme.ts
Original file line number Diff line number Diff line change
Expand Up @@ -654,9 +654,6 @@ export const defaultTheme = createTheme({
[`&.${outlinedInputClasses.focused} .${outlinedInputClasses.notchedOutline}`]: {
borderWidth: '3px',
},
[`&.${outlinedInputClasses.error} .${outlinedInputClasses.notchedOutline}`]: {
borderWidth: '1px !important',
},
},
notchedOutline: {
borderColor: 'transparent',
Expand Down
1 change: 1 addition & 0 deletions src/styles/theme/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@ export { defaultTheme } from './defaultTheme'
export { testnetTheme } from './testnet/theme'

export const tooltipDelay = 500
export const typingDelay = 1000

export const getThemesForNetworks: () => Record<Network, Theme> = () => ({
[Network.mainnet]: defaultTheme,
Expand Down