1
0
mirror of https://github.com/oceanprotocol/market.git synced 2024-12-02 05:57:29 +01:00

Global search bar (#690)

* move search bar

Signed-off-by: mihaisc <mihai.scarlat@smartcontrol.ro>

* update search bar

Signed-off-by: mihaisc <mihai@oceanprotocol.com>

* add enter event

Signed-off-by: mihaisc <mihai@oceanprotocol.com>

* fix lint

* small button fixes

* add padding, change media width to rem

* remove comments
This commit is contained in:
mihaisc 2021-07-06 04:55:10 -07:00 committed by GitHub
parent 60addda1cc
commit 3798d80a4d
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
10 changed files with 152 additions and 56 deletions

View File

@ -27,6 +27,13 @@ export interface InputProps {
| ChangeEvent<HTMLSelectElement>
| ChangeEvent<HTMLTextAreaElement>
): void
onKeyPress?(
e:
| React.KeyboardEvent<HTMLInputElement>
| React.KeyboardEvent<HTMLInputElement>
| React.KeyboardEvent<HTMLSelectElement>
| React.KeyboardEvent<HTMLTextAreaElement>
): void
rows?: number
multiple?: boolean
pattern?: string
@ -42,6 +49,7 @@ export interface InputProps {
defaultChecked?: boolean
size?: 'mini' | 'small' | 'large' | 'default'
className?: string
divClassName?: string
}
export default function Input(props: Partial<InputProps>): ReactElement {
@ -50,10 +58,13 @@ export default function Input(props: Partial<InputProps>): ReactElement {
const hasError =
props.form?.touched[field.name] && props.form?.errors[field.name]
const styleClasses = cx({
field: true,
hasError: hasError
})
const styleClasses = cx(
{
field: true,
hasError: hasError
},
props.divClassName
)
return (
<div

View File

@ -9,36 +9,76 @@
.logo {
white-space: nowrap;
display: flex;
flex: 0 0 auto;
flex-direction: row;
justify-content: center;
align-items: center;
order: 1;
}
.navigation {
order: 3;
width: 100%;
margin-top: calc(var(--spacer) / 2);
text-align: center;
border-top: 1px solid var(--border-color);
border-bottom: 1px solid var(--border-color);
margin-left: -1rem;
margin-right: -1rem;
width: calc(100% + 2rem);
width: auto;
margin: 0;
text-align: left;
border: none;
}
.search {
display: flex;
flex: 1 0 auto;
justify-content: center;
align-items: center;
align-self: flex-start;
padding-left: 20px;
margin-left: auto;
}
.actions {
display: flex;
flex: 0 0 auto;
flex-direction: row;
justify-content: center;
align-items: center;
align-self: flex-start;
margin-left: auto;
order: 2;
}
.title {
display: none;
}
@media (max-width: 38rem) {
.actions {
margin-left: auto;
}
.navigation {
order: 3;
display: block;
justify-content: center;
align-items: center;
margin-top: calc(var(--spacer) / 2);
text-align: center;
border-top: 1px solid var(--border-color);
border-bottom: 1px solid var(--border-color);
margin-left: -1rem;
margin-right: -1rem;
width: calc(50% + 2rem);
}
}
@media (max-width: 75rem) {
.navigation {
flex: 1 0 auto;
justify-content: left;
align-items: left;
}
.search {
flex: 0 0 100%;
padding-top: 10px;
order: 4;
}
}
@media screen and (min-width: 42rem) {
.navigation {
order: 2;
width: auto;
margin: 0;
text-align: left;

View File

@ -8,6 +8,7 @@ import UserPreferences from './UserPreferences'
import Badge from '../atoms/Badge'
import Logo from '../atoms/Logo'
import Networks from './UserPreferences/Networks'
import SearchBar from './SearchBar'
const Wallet = loadable(() => import('./Wallet'))
@ -51,6 +52,9 @@ export default function Menu(): ReactElement {
))}
</ul>
<div className={styles.search}>
<SearchBar />
</div>
<div className={styles.actions}>
<Networks />
<Wallet />

View File

@ -1,17 +1,49 @@
.form {
margin-bottom: var(--spacer);
width: 100%;
max-width: 30rem;
.search {
display: flex;
flex: 1 0 auto;
align-self: stretch;
}
.button {
padding: calc(var(--spacer) / 6) calc(var(--spacer) / 3);
cursor: pointer;
border: 1px solid var(--border-color);
border-radius: var(--border-radius);
background-color: var(--background-content);
border-left: none;
white-space: nowrap;
min-width: 4rem;
}
.form > div > div {
.button:hover,
.button:focus {
color: var(--brand-white);
text-decoration: none;
transform: translate3d(0, -0.05rem, 0);
box-shadow: 0 12px 30px 0 rgba(0, 0, 0, 0.1);
}
.input {
height: 36px !important;
border-top-right-radius: 0px;
border-bottom-right-radius: 0px;
}
.searchInput {
flex-grow: 2;
margin-bottom: 0px;
}
.searchIcon {
fill: var(--brand-grey-light);
transition: 0.2s ease-out;
}
.search > div > div {
margin: 0;
}
.form label {
.search label {
display: none;
}
.form input {
.search input {
background-color: var(--background-content);
}

View File

@ -10,5 +10,3 @@ export default {
export const Normal = () => <SearchBar />
export const WithInitialValue = () => <SearchBar initialValue="Water" />
export const WithFilters = () => <SearchBar filters />

View File

@ -1,24 +1,35 @@
import React, { useState, ChangeEvent, FormEvent, ReactElement } from 'react'
import React, {
useState,
useEffect,
ChangeEvent,
FormEvent,
ReactElement
} from 'react'
import { navigate } from 'gatsby'
import queryString from 'query-string'
import styles from './SearchBar.module.css'
import Button from '../atoms/Button'
import Input from '../atoms/Input'
import InputGroup from '../atoms/Input/InputGroup'
import { addExistingParamsToUrl } from '../templates/Search/utils'
import { ReactComponent as SearchIcon } from '../../images/search.svg'
export default function SearchBar({
placeholder,
initialValue,
filters,
size
}: {
placeholder?: string
initialValue?: string
filters?: boolean
size?: 'small' | 'large'
}): ReactElement {
let [value, setValue] = useState(initialValue || '')
const parsed = queryString.parse(location.search)
const { text, owner } = parsed
useEffect(() => {
;(text || owner) && setValue((text || owner) as string)
}, [text, owner])
async function startSearch(e: FormEvent<HTMLButtonElement>) {
e.preventDefault()
if (value === '') value = ' '
@ -50,27 +61,33 @@ export default function SearchBar({
}
return (
<form className={styles.form}>
<InputGroup>
<Input
type="search"
name="search"
placeholder={placeholder || 'What are you looking for?'}
value={value}
onChange={handleChange}
required
size={size}
/>
<Button
onClick={async (e: FormEvent<HTMLButtonElement>) =>
<form className={styles.search}>
<Input
type="search"
name="search"
placeholder={placeholder || 'What are you looking for?'}
value={value}
onChange={handleChange}
required
size="small"
divClassName={styles.searchInput}
className={styles.input}
onKeyPress={async (e: React.KeyboardEvent<HTMLInputElement>) => {
if (e.key === 'Enter') {
await startSearch(e)
}
>
Search
</Button>
</InputGroup>
{filters && <fieldset className={styles.filters}>Type, Price</fieldset>}
}}
/>
<Button
onClick={async (e: FormEvent<HTMLButtonElement>) =>
await startSearch(e)
}
style="text"
size="small"
className={styles.button}
>
<SearchIcon className={styles.searchIcon} />
</Button>
</form>
)
}

View File

@ -1,3 +1,4 @@
.wallet {
display: flex;
align-self: stretch;
}

View File

@ -134,10 +134,6 @@ export default function HomePage(): ReactElement {
return (
<Permission eventType="browse">
<>
<Container narrow className={styles.searchWrap}>
<SearchBar size="large" />
</Container>
<section className={styles.section}>
<h3>Bookmarks</h3>
<Bookmarks />

View File

@ -1,7 +1,6 @@
import React, { ReactElement, useState, useEffect } from 'react'
import Permission from '../../organisms/Permission'
import { QueryResult } from '@oceanprotocol/lib/dist/node/metadatacache/MetadataCache'
import SearchBar from '../../molecules/SearchBar'
import AssetList from '../../organisms/AssetList'
import styles from './index.module.css'
import queryString from 'query-string'
@ -65,9 +64,6 @@ export default function SearchPage({
<Permission eventType="browse">
<>
<div className={styles.search}>
{(text || owner || tags) && (
<SearchBar initialValue={(text || owner) as string} />
)}
<div className={styles.row}>
<ServiceFilter
serviceType={service}

1
src/images/search.svg Normal file
View File

@ -0,0 +1 @@
<svg width="24" height="24" xmlns="http://www.w3.org/2000/svg" fill-rule="evenodd" clip-rule="evenodd"><path d="M15.853 16.56c-1.683 1.517-3.911 2.44-6.353 2.44-5.243 0-9.5-4.257-9.5-9.5s4.257-9.5 9.5-9.5 9.5 4.257 9.5 9.5c0 2.442-.923 4.67-2.44 6.353l7.44 7.44-.707.707-7.44-7.44zm-6.353-15.56c4.691 0 8.5 3.809 8.5 8.5s-3.809 8.5-8.5 8.5-8.5-3.809-8.5-8.5 3.809-8.5 8.5-8.5z"/></svg>

After

Width:  |  Height:  |  Size: 385 B