mirror of
https://github.com/omnivore-app/omnivore.git
synced 2026-03-11 08:54:26 +00:00
Merge pull request #1162 from omnivore-app/feat/1078
Search - Recent Searches
This commit is contained in:
commit
3ca1d9b6a7
4 changed files with 210 additions and 83 deletions
|
|
@ -1,102 +1,215 @@
|
|||
import { useState, useEffect } from 'react'
|
||||
import { Clock, Sliders, X } from 'phosphor-react'
|
||||
import Downshift from 'downshift'
|
||||
|
||||
import { HStack, SpanBox, VStack } from './../../elements/LayoutPrimitives'
|
||||
import { useState } from 'react'
|
||||
import { FormInput } from '../../elements/FormElements'
|
||||
import { Button } from '../../elements/Button'
|
||||
import { Sliders, SlidersHorizontal, X } from 'phosphor-react'
|
||||
import { theme } from '../../tokens/stitches.config'
|
||||
import { styled, theme } from '../../tokens/stitches.config'
|
||||
import { SearchCoordinator } from './LibraryContainer'
|
||||
|
||||
// Styles
|
||||
const List = styled('ul', {
|
||||
width: '91%',
|
||||
maxHeight: '400px',
|
||||
overflow: 'auto',
|
||||
top: '65px',
|
||||
left: '-32px',
|
||||
color: 'var(--colors-utilityTextDefault)',
|
||||
backgroundColor: 'var(--colors-grayBase)',
|
||||
position: 'absolute',
|
||||
zIndex: '2',
|
||||
'@smDown': {
|
||||
fontSize: 16,
|
||||
},
|
||||
})
|
||||
|
||||
const Item = styled('li', {
|
||||
listStyleType: 'none',
|
||||
m: '8px',
|
||||
borderRadius: '5px',
|
||||
width: '100%',
|
||||
})
|
||||
|
||||
export type LibrarySearchBarProps = {
|
||||
coordinator: SearchCoordinator
|
||||
}
|
||||
|
||||
export function LibrarySearchBar(props: LibrarySearchBarProps): JSX.Element {
|
||||
const [searchTerm, setSearchTerm] = useState('')
|
||||
const [recentSearches, setRecentSearches] = useState(Array<[]>())
|
||||
|
||||
useEffect(() => {
|
||||
setRecentSearches(Object.values(localStorage))
|
||||
}, [])
|
||||
|
||||
return (
|
||||
<>
|
||||
<VStack alignment="start" distribution="start" css={{ pl: '32px', width: '100%', height: '100%' }}>
|
||||
<HStack alignment="start" distribution="start" css={{ width: '100%', borderBottom: 'solid 1px $grayBorder' }}>
|
||||
<form
|
||||
style={{ width: '100%' }}
|
||||
onSubmit={(event) => {
|
||||
event.preventDefault()
|
||||
// props.applySearchQuery(searchTerm || '')
|
||||
// inputRef.current?.blur()
|
||||
}}
|
||||
<Downshift itemToString={(item) => (item ? item : '')}>
|
||||
{({
|
||||
getInputProps,
|
||||
getRootProps,
|
||||
getMenuProps,
|
||||
getItemProps,
|
||||
isOpen,
|
||||
highlightedIndex,
|
||||
inputValue,
|
||||
clearSelection,
|
||||
openMenu,
|
||||
}) => (
|
||||
<VStack
|
||||
alignment="start"
|
||||
distribution="start"
|
||||
css={{ pl: '32px', width: '100%', height: '100%' }}
|
||||
>
|
||||
<HStack
|
||||
alignment="start"
|
||||
distribution="start"
|
||||
css={{ width: '100%', borderBottom: 'solid 1px $grayBorder' }}
|
||||
{...getRootProps({ refKey: 'ref' }, { suppressRefError: true })}
|
||||
>
|
||||
<FormInput
|
||||
css={{
|
||||
width: '100%',
|
||||
height: '80px',
|
||||
fontSize: '24px',
|
||||
fontFamily: 'Inter',
|
||||
}}
|
||||
type="text"
|
||||
tabIndex={0}
|
||||
value={searchTerm}
|
||||
placeholder="Search"
|
||||
onChange={(event) => {
|
||||
setSearchTerm(event.target.value)
|
||||
}}
|
||||
/>
|
||||
</form>
|
||||
{!searchTerm && (
|
||||
<Button
|
||||
style="plainIcon"
|
||||
onClick={(event) => {
|
||||
// Display the advanced search sheet
|
||||
}}
|
||||
css={{
|
||||
display: 'flex',
|
||||
flexDirection: 'row',
|
||||
height: '100%',
|
||||
alignItems: 'center',
|
||||
}}
|
||||
>
|
||||
<Sliders size={24} color={theme.colors.utilityTextDefault.toString()} />
|
||||
</Button>
|
||||
)}
|
||||
{searchTerm && (
|
||||
<HStack alignment="center" distribution="start" css={{ height: '100%' }}>
|
||||
<Button
|
||||
style="plainIcon"
|
||||
onClick={(event) => {
|
||||
// event.preventDefault()
|
||||
// setSearchTerm('')
|
||||
// props.applySearchQuery('')
|
||||
<form
|
||||
style={{ width: '100%' }}
|
||||
onSubmit={(event) => {
|
||||
event.preventDefault()
|
||||
// props.applySearchQuery(searchTerm || '')
|
||||
// inputRef.current?.blur()
|
||||
}}
|
||||
css={{
|
||||
display: 'flex',
|
||||
flexDirection: 'row',
|
||||
mr: '16px',
|
||||
height: '100%',
|
||||
alignItems: 'center',
|
||||
}}
|
||||
{...getRootProps()}
|
||||
>
|
||||
<X
|
||||
width={24}
|
||||
height={24}
|
||||
color={theme.colors.grayTextContrast.toString()}
|
||||
<FormInput
|
||||
css={{
|
||||
width: '77%',
|
||||
height: '80px',
|
||||
fontSize: '24px',
|
||||
fontFamily: 'Inter',
|
||||
}}
|
||||
type="text"
|
||||
tabIndex={0}
|
||||
value={inputValue}
|
||||
placeholder="Search"
|
||||
onFocus={(event: any) => {
|
||||
event.preventDefault()
|
||||
openMenu()
|
||||
//props.applySearchQuery('')
|
||||
// inputRef.current?.blur()
|
||||
}}
|
||||
onChange={(event: any) => {
|
||||
event.preventDefault()
|
||||
}}
|
||||
{...getInputProps()}
|
||||
/>
|
||||
</Button>
|
||||
|
||||
<Button
|
||||
style="ctaDarkYellow"
|
||||
onClick={(event) => {
|
||||
// event.preventDefault()
|
||||
// setSearchTerm('')
|
||||
// props.applySearchQuery('')
|
||||
// inputRef.current?.blur()
|
||||
}}
|
||||
>
|
||||
Search
|
||||
</Button>
|
||||
{/* {searchTerm && ( */}
|
||||
<HStack
|
||||
alignment="center"
|
||||
distribution="start"
|
||||
css={{
|
||||
height: '100%',
|
||||
display: 'flex',
|
||||
justifyContent: 'right',
|
||||
alignItems: 'center',
|
||||
margin: '-57px 0 10px',
|
||||
}}
|
||||
>
|
||||
<Button
|
||||
style="plainIcon"
|
||||
onClick={(event) => {
|
||||
event.preventDefault()
|
||||
clearSelection()
|
||||
//props.applySearchQuery('')
|
||||
// inputRef.current?.blur()
|
||||
}}
|
||||
css={{
|
||||
mr: '15px',
|
||||
}}
|
||||
>
|
||||
<X
|
||||
width={24}
|
||||
height={24}
|
||||
color={theme.colors.grayTextContrast.toString()}
|
||||
/>
|
||||
</Button>
|
||||
|
||||
<Button
|
||||
style="ctaDarkYellow"
|
||||
type="submit"
|
||||
css={{
|
||||
mr: '15px',
|
||||
}}
|
||||
onClick={(event) => {
|
||||
event.preventDefault()
|
||||
if (inputValue && inputValue.length > 0) {
|
||||
localStorage.setItem(inputValue, inputValue)
|
||||
setRecentSearches(Object.values(localStorage))
|
||||
}
|
||||
// props.applySearchQuery('')
|
||||
// inputRef.current?.blur()
|
||||
}}
|
||||
>
|
||||
Search
|
||||
</Button>
|
||||
{/* )} */}
|
||||
{/* {!searchTerm && ( */}
|
||||
<Button
|
||||
style="plainIcon"
|
||||
onClick={(event) => {
|
||||
// Display the advanced search sheet
|
||||
}}
|
||||
>
|
||||
<Sliders
|
||||
size={24}
|
||||
color={theme.colors.utilityTextDefault.toString()}
|
||||
/>
|
||||
</Button>
|
||||
{/* )} */}
|
||||
</HStack>
|
||||
|
||||
<List>
|
||||
{isOpen &&
|
||||
recentSearches
|
||||
.filter((item) => !inputValue || item.includes(inputValue))
|
||||
.map((item, index) => (
|
||||
<SpanBox
|
||||
{...getMenuProps()}
|
||||
key={item}
|
||||
css={{
|
||||
paddingLeft: '15px',
|
||||
display: 'flex',
|
||||
alignItems: 'center',
|
||||
borderBottom: '1px solid $grayBorder',
|
||||
'& svg': {
|
||||
margin: '10px',
|
||||
},
|
||||
backgroundColor:
|
||||
index === highlightedIndex
|
||||
? 'var(--colors-grayBg)'
|
||||
: 'transparent',
|
||||
}}
|
||||
>
|
||||
<Clock size={20} />
|
||||
<Item
|
||||
{...getItemProps({
|
||||
item,
|
||||
index,
|
||||
})}
|
||||
>
|
||||
{item}
|
||||
</Item>
|
||||
<X
|
||||
width={20}
|
||||
height={20}
|
||||
color={theme.colors.grayTextContrast.toString()}
|
||||
onClick={() => {
|
||||
localStorage.removeItem(`${item}`)
|
||||
setRecentSearches(Object.values(localStorage))
|
||||
}}
|
||||
/>
|
||||
</SpanBox>
|
||||
))}
|
||||
</List>
|
||||
</form>
|
||||
</HStack>
|
||||
)}
|
||||
</HStack>
|
||||
</VStack>
|
||||
</>
|
||||
</VStack>
|
||||
)}
|
||||
</Downshift>
|
||||
)
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -32,6 +32,7 @@
|
|||
"color2k": "^2.0.0",
|
||||
"cookie": "^0.5.0",
|
||||
"diff-match-patch": "^1.0.5",
|
||||
"downshift": "^6.1.9",
|
||||
"graphql-request": "^3.6.1",
|
||||
"kbar": "^0.1.0-beta.35",
|
||||
"nanoid": "^3.1.29",
|
||||
|
|
|
|||
|
|
@ -1,5 +1,7 @@
|
|||
/* Menu Override styles */
|
||||
|
||||
.pro-sidebar {
|
||||
z-index: 1;
|
||||
}
|
||||
.pro-sidebar > .pro-sidebar-inner,
|
||||
.pro-menu,
|
||||
.pro-menu > ul > .pro-sub-menu > .pro-inner-list-item,
|
||||
|
|
|
|||
11
yarn.lock
11
yarn.lock
|
|
@ -12596,6 +12596,17 @@ downshift@^6.0.15:
|
|||
react-is "^17.0.2"
|
||||
tslib "^2.3.0"
|
||||
|
||||
downshift@^6.1.9:
|
||||
version "6.1.12"
|
||||
resolved "https://registry.yarnpkg.com/downshift/-/downshift-6.1.12.tgz#f14476b41a6f6fd080c340bad1ddf449f7143f6f"
|
||||
integrity sha512-7XB/iaSJVS4T8wGFT3WRXmSF1UlBHAA40DshZtkrIscIN+VC+Lh363skLxFTvJwtNgHxAMDGEHT4xsyQFWL+UA==
|
||||
dependencies:
|
||||
"@babel/runtime" "^7.14.8"
|
||||
compute-scroll-into-view "^1.0.17"
|
||||
prop-types "^15.7.2"
|
||||
react-is "^17.0.2"
|
||||
tslib "^2.3.0"
|
||||
|
||||
dset@^3.1.0, dset@^3.1.1, dset@^3.1.2:
|
||||
version "3.1.2"
|
||||
resolved "https://registry.yarnpkg.com/dset/-/dset-3.1.2.tgz#89c436ca6450398396dc6538ea00abc0c54cd45a"
|
||||
|
|
|
|||
Loading…
Reference in a new issue