This repository has been archived by the owner on Dec 21, 2021. It is now read-only.
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
<SearchBar /> is a component that renders an <InputText> and an icon. It needs an 'onChangeHandler' prop that is called whenever the value of the <InputText> changes. This can optionally be debounced by passing an 'emitDelay' prop that takes a value in milliseconds. An initial value can be passed in using the 'query' prop.
- Loading branch information
Showing
4 changed files
with
120 additions
and
0 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,69 @@ | ||
import React from 'react'; | ||
import debounce from 'lodash.debounce'; | ||
import * as Input from './input'; | ||
import * as Icon from './icons'; | ||
|
||
interface SearchBarProps { | ||
query?: string; | ||
emitDelay?: number; | ||
onChangeHandler: (value: string) => void; | ||
} | ||
|
||
interface SearchBarState { | ||
query: string; | ||
} | ||
|
||
class SearchBar extends React.Component<SearchBarProps, SearchBarState> { | ||
static defaultProps = { | ||
emitDelay: 0, | ||
} | ||
|
||
debouncedEmit = (({ onChangeHandler, emitDelay }) => debounce( | ||
onChangeHandler, emitDelay, | ||
))(this.props); | ||
|
||
constructor(props: Readonly<SearchBarProps>) { | ||
super(props); | ||
const { query = '' } = props; | ||
this.state = { | ||
query, | ||
}; | ||
this.onChange = this.onChange.bind(this); | ||
} | ||
|
||
componentDidMount() { | ||
const { query } = this.state; | ||
if (query !== '') { | ||
this.debouncedEmit(query); | ||
} | ||
} | ||
|
||
componentWillUnmount() { | ||
this.debouncedEmit.cancel(); | ||
} | ||
|
||
onChange(event: React.ChangeEvent<HTMLInputElement>) { | ||
const { value: query } = event.target; | ||
|
||
this.setState({ | ||
query, | ||
}); | ||
event.persist(); | ||
this.debouncedEmit(query); | ||
} | ||
|
||
render() { | ||
const { query } = this.state; | ||
const { onChange } = this; | ||
return ( | ||
<div className="search-bar"> | ||
<span className="search-bar__icon"> | ||
<Icon.MagnifierSmall /> | ||
</span> | ||
<Input.Text className="search-bar__input" value={query} onChange={onChange} /> | ||
</div> | ||
); | ||
} | ||
} | ||
|
||
export { SearchBar }; |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,27 @@ | ||
import * as React from 'react'; | ||
/* eslint-disable import/no-extraneous-dependencies */ | ||
import { storiesOf } from '@storybook/react'; | ||
import { withKnobs } from '@storybook/addon-knobs'; | ||
import { action } from '@storybook/addon-actions'; | ||
import styles from '@sambego/storybook-styles'; | ||
/* eslint-enable import/no-extraneous-dependencies */ | ||
|
||
import { SearchBar } from '../components/search_bar'; | ||
|
||
const stories = storiesOf('Search Bar', module); | ||
|
||
stories.addDecorator(withKnobs) | ||
.addDecorator(styles({ | ||
alignItems: 'center', | ||
display: 'flex', | ||
height: '100vh', | ||
justifyContent: 'center', | ||
padding: '2em', | ||
})); | ||
|
||
stories.add('SearchBar', () => ( | ||
<SearchBar | ||
onChangeHandler={action('query')} | ||
emitDelay={500} | ||
/> | ||
)); |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,23 @@ | ||
.search-bar { | ||
display: flex; | ||
} | ||
|
||
.search-bar__icon { | ||
align-items: center; | ||
display: flex; | ||
justify-content: center; | ||
pointer-events: none; | ||
position: relative; | ||
width: 5.5rem; | ||
z-index: 1; | ||
} | ||
|
||
.search-bar__icon > svg { | ||
height: 2rem; | ||
width: 2rem; | ||
} | ||
|
||
.search-bar__input { | ||
margin-left: -5.5rem; | ||
padding-left: 5.5rem; | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters