mirror of
https://github.com/Stremio/stremio-web.git
synced 2026-04-18 04:42:01 +00:00
SearchBar component implemented
This commit is contained in:
parent
39199df1ac
commit
104577e2f6
3 changed files with 115 additions and 0 deletions
64
src/common/NavBar/SearchBar/SearchBar.js
Normal file
64
src/common/NavBar/SearchBar/SearchBar.js
Normal file
|
|
@ -0,0 +1,64 @@
|
|||
const React = require('react');
|
||||
const PropTypes = require('prop-types');
|
||||
const classnames = require('classnames');
|
||||
const UrlUtils = require('url');
|
||||
const Icon = require('stremio-icons/dom');
|
||||
const { Input, useFocusable } = require('stremio-navigation');
|
||||
const useLocationHash = require('../../useLocationHash');
|
||||
const styles = require('./styles');
|
||||
|
||||
const SearchBar = React.memo(({ className }) => {
|
||||
const searchInputRef = React.useRef();
|
||||
const locationHash = useLocationHash();
|
||||
const focusable = useFocusable();
|
||||
const [active, query] = React.useMemo(() => {
|
||||
const locationHashPath = locationHash.startsWith('#') ? locationHash.slice(1) : '';
|
||||
const { pathname: locationPathname, search: locationSearch } = UrlUtils.parse(locationHashPath);
|
||||
const active = locationPathname === '/search';
|
||||
const queryParams = new URLSearchParams(locationSearch);
|
||||
const query = (active && queryParams.has('q')) ? queryParams.get('q') : '';
|
||||
return [active, query];
|
||||
}, [locationHash]);
|
||||
const onQueryInputFocus = React.useCallback(() => {
|
||||
if (!active) {
|
||||
window.location.replace('#/search');
|
||||
}
|
||||
}, [active]);
|
||||
const onQueryInputSubmit = React.useCallback(() => {
|
||||
window.location.replace(`#/search?q=${searchInputRef.current.value}`);
|
||||
}, [searchInputRef]);
|
||||
React.useEffect(() => {
|
||||
if (active && focusable) {
|
||||
searchInputRef.current.focus();
|
||||
}
|
||||
}, [active, focusable]);
|
||||
return (
|
||||
<div className={classnames(className, styles['search-bar-container'], { 'active': active })}>
|
||||
<label className={styles['search-label']}>
|
||||
<Input
|
||||
key={query}
|
||||
ref={searchInputRef}
|
||||
className={styles['search-input']}
|
||||
type={'text'}
|
||||
placeholder={'Search'}
|
||||
autoCorrect={'off'}
|
||||
autoCapitalize={'off'}
|
||||
spellCheck={false}
|
||||
defaultValue={query}
|
||||
onFocus={onQueryInputFocus}
|
||||
onSubmit={onQueryInputSubmit}
|
||||
/>
|
||||
<Input className={styles['submit-button']} type={'button'} tabIndex={-1} onClick={onQueryInputSubmit}>
|
||||
<Icon className={styles['submit-icon']} icon={'ic_search'} />
|
||||
</Input>
|
||||
</label>
|
||||
</div>
|
||||
);
|
||||
});
|
||||
|
||||
SearchBar.displayName = 'SearchBar';
|
||||
SearchBar.propTypes = {
|
||||
className: PropTypes.string
|
||||
};
|
||||
|
||||
module.exports = SearchBar;
|
||||
3
src/common/NavBar/SearchBar/index.js
Normal file
3
src/common/NavBar/SearchBar/index.js
Normal file
|
|
@ -0,0 +1,3 @@
|
|||
const SearchBar = require('./SearchBar');
|
||||
|
||||
module.exports = SearchBar;
|
||||
48
src/common/NavBar/SearchBar/styles.less
Normal file
48
src/common/NavBar/SearchBar/styles.less
Normal file
|
|
@ -0,0 +1,48 @@
|
|||
.search-bar-container {
|
||||
display: flex;
|
||||
flex-direction: row;
|
||||
justify-content: center;
|
||||
align-items: stretch;
|
||||
|
||||
&:global(.active) {
|
||||
.search-label {
|
||||
background-color: var(--color-backgrounddark);
|
||||
}
|
||||
}
|
||||
|
||||
.search-label {
|
||||
flex-grow: 0;
|
||||
flex-basis: calc(var(--nav-bar-height) * 7);
|
||||
display: flex;
|
||||
flex-direction: row;
|
||||
align-items: stretch;
|
||||
background: var(--color-secondary);
|
||||
|
||||
.search-input {
|
||||
flex: 1;
|
||||
padding: 0 0.8em;
|
||||
color: var(--color-surfacelighter);
|
||||
|
||||
&::placeholder {
|
||||
color: var(--color-surfacelighter);
|
||||
}
|
||||
}
|
||||
|
||||
.submit-button {
|
||||
width: var(--nav-bar-height);
|
||||
height: var(--nav-bar-height);
|
||||
display: flex;
|
||||
flex-direction: row;
|
||||
justify-content: center;
|
||||
align-items: center;
|
||||
background-color: var(--color-secondarylight);
|
||||
cursor: pointer;
|
||||
|
||||
.submit-icon {
|
||||
width: 1.1em;
|
||||
height: 1.1em;
|
||||
fill: var(--color-surfacelighter);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
Loading…
Reference in a new issue