Finish search from header

This commit is contained in:
Tom Raithel
2017-03-21 20:57:20 +01:00
parent fd029dad9e
commit ad2b0e34ad
7 changed files with 102 additions and 43 deletions

View File

@@ -1,10 +1,11 @@
export const NAVIGATE = 'navigate'; export const NAVIGATE = 'navigate';
const actions = { const actions = {
navigate: (pageName, pushToHistory = true) => { navigate: (pageName, pushToHistory = true, pageState = {}) => {
return { return {
type: NAVIGATE, type: NAVIGATE,
pageName, pageName,
pageState,
pushToHistory, pushToHistory,
}; };
}, },

View File

@@ -26,6 +26,6 @@ function App(props) {
} }
export default connect( export default connect(
({ items, releases, pageName }) => ({ items, releases, pageName }), ({ items, releases, pageName, pageState }) => ({ items, releases, pageName, pageState }),
actions actions
)(App); )(App);

View File

@@ -1,16 +1,20 @@
import React from 'react'; import React from 'react';
import classNames from 'classnames'; import classNames from 'classnames';
import { connect } from 'react-redux';
import Branding from './Branding'; import Branding from './Branding';
import Link from './Link'; import Link from './Link';
import LogoLink from './LogoLink'; import LogoLink from './LogoLink';
import Search from './Search'; import Search from './Search';
import { getItemPageNames } from '../../common/config'; import { getItemPageNames } from '../../common/config';
import actions from '../actions';
class Header extends React.Component { class Header extends React.Component {
constructor(...args) { constructor(...args) {
super(...args); super(...args);
this.state = { this.state = {
searchOpen: false, searchOpen: false,
search: '',
}; };
} }
@@ -26,9 +30,29 @@ class Header extends React.Component {
}); });
} }
handleSearchChange = (search) => {
this.setState({
search,
});
}
handleSearchSubmit = () => {
this.props.navigate('overview', true, {
search: this.state.search,
});
this.setState({
searchOpen: false,
search: '',
});
}
handleOpenClick = (e) => { handleOpenClick = (e) => {
e.preventDefault(); e.preventDefault();
this.openSearch(); this.openSearch();
setTimeout(() => {
this.search.focus();
}, 0);
} }
render() { render() {
@@ -56,7 +80,14 @@ class Header extends React.Component {
<span className="icon icon--search icon-link__icon"></span>Search <span className="icon icon--search icon-link__icon"></span>Search
</a> </a>
<div className={classNames('nav__search', { 'is-open': searchOpen })}> <div className={classNames('nav__search', { 'is-open': searchOpen })}>
<Search onClose={this.closeSearch} open={searchOpen} /> <Search
value={this.state.search}
onClose={this.closeSearch}
onSubmit={this.handleSearchSubmit}
onChange={this.handleSearchChange}
open={searchOpen}
ref={(s) => { this.search = s; }}
/>
</div> </div>
</div> </div>
</div> </div>
@@ -65,4 +96,8 @@ class Header extends React.Component {
} }
} }
export default Header;
export default connect(
undefined,
actions
)(Header);

View File

@@ -18,14 +18,23 @@ const containsSearchTerm = (text = '', term = '') => {
class PageOverview extends React.Component { class PageOverview extends React.Component {
constructor(...args) { constructor(props, ...args) {
super(...args); super(props, ...args);
this.state = { this.state = {
ring: rings[0], ring: rings[0],
search: '', search: props.pageState.search || '',
}; };
} }
componentWillReceiveProps(nextProps) {
if (this.search !== nextProps.pageState.search) {
this.setState({
ring: rings[0],
search: nextProps.pageState.search,
});
}
}
handleRingClick = (ring) => (e) => { handleRingClick = (ring) => (e) => {
e.preventDefault(); e.preventDefault();

View File

@@ -1,7 +1,14 @@
import React from 'react'; import React from 'react';
import classNames from 'classnames'; import classNames from 'classnames';
export default function Search({ value, onChange, onClose, open = false, onSubmit = () => {} }) { class Search extends React.Component {
focus() {
this.input.focus();
}
render() {
const { value, onChange, onClose, open = false, onSubmit = () => {} } = this.props;
const closable = typeof onClose === 'function'; const closable = typeof onClose === 'function';
const handleSubmit = (e) => { const handleSubmit = (e) => {
@@ -22,6 +29,7 @@ export default function Search({ value, onChange, onClose, open = false, onSubmi
onChange={(e) => { onChange(e.target.value); }} onChange={(e) => { onChange(e.target.value); }}
className="search__field" className="search__field"
placeholder="What are you looking for?" placeholder="What are you looking for?"
ref={(input) => { this.input = input; }}
/> />
<span className={classNames('search__button', { 'is-open': open })}> <span className={classNames('search__button', { 'is-open': open })}>
<button type="submit" className="button"> <button type="submit" className="button">
@@ -39,3 +47,6 @@ export default function Search({ value, onChange, onClose, open = false, onSubmi
</form> </form>
); );
} }
}
export default Search;

View File

@@ -2,6 +2,7 @@ import { NAVIGATE } from './actions';
const initialState = { const initialState = {
pageName: 'index', pageName: 'index',
pageState: {},
items: [], items: [],
releases: [], releases: [],
}; };
@@ -12,6 +13,7 @@ const appReducer = (state = initialState, action = {}) => {
return { return {
...state, ...state,
pageName: action.pageName, pageName: action.pageName,
pageState: action.pageState,
} }
break; break;
default: default:

View File

@@ -10,7 +10,8 @@ export const renderPage = (radar, pageName) => {
// Create a new Redux store instance // Create a new Redux store instance
const store = createStore(appReducer, { const store = createStore(appReducer, {
...radar, ...radar,
pageName pageName,
pageState: {},
}); });
// Render the component to a string // Render the component to a string