Skip to content

Commit

Permalink
Finish search from header
Browse files Browse the repository at this point in the history
  • Loading branch information
tomraithel committed Mar 21, 2017
1 parent fd029da commit ad2b0e3
Show file tree
Hide file tree
Showing 7 changed files with 101 additions and 42 deletions.
3 changes: 2 additions & 1 deletion js/actions.js
Original file line number Diff line number Diff line change
@@ -1,10 +1,11 @@
export const NAVIGATE = 'navigate';

const actions = {
navigate: (pageName, pushToHistory = true) => {
navigate: (pageName, pushToHistory = true, pageState = {}) => {
return {
type: NAVIGATE,
pageName,
pageState,
pushToHistory,
};
},
Expand Down
2 changes: 1 addition & 1 deletion js/components/App.js
Original file line number Diff line number Diff line change
Expand Up @@ -26,6 +26,6 @@ function App(props) {
}

export default connect(
({ items, releases, pageName }) => ({ items, releases, pageName }),
({ items, releases, pageName, pageState }) => ({ items, releases, pageName, pageState }),
actions
)(App);
39 changes: 37 additions & 2 deletions js/components/Header.js
Original file line number Diff line number Diff line change
@@ -1,16 +1,20 @@
import React from 'react';
import classNames from 'classnames';
import { connect } from 'react-redux';

import Branding from './Branding';
import Link from './Link';
import LogoLink from './LogoLink';
import Search from './Search';
import { getItemPageNames } from '../../common/config';
import actions from '../actions';

class Header extends React.Component {
constructor(...args) {
super(...args);
this.state = {
searchOpen: false,
search: '',
};
}

Expand All @@ -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) => {
e.preventDefault();
this.openSearch();
setTimeout(() => {
this.search.focus();
}, 0);
}

render() {
Expand Down Expand Up @@ -56,7 +80,14 @@ class Header extends React.Component {
<span className="icon icon--search icon-link__icon"></span>Search
</a>
<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>
Expand All @@ -65,4 +96,8 @@ class Header extends React.Component {
}
}

export default Header;

export default connect(
undefined,
actions
)(Header);
15 changes: 12 additions & 3 deletions js/components/PageOverview.js
Original file line number Diff line number Diff line change
Expand Up @@ -18,14 +18,23 @@ const containsSearchTerm = (text = '', term = '') => {

class PageOverview extends React.Component {

constructor(...args) {
super(...args);
constructor(props, ...args) {
super(props, ...args);
this.state = {
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) => {
e.preventDefault();

Expand Down
79 changes: 45 additions & 34 deletions js/components/Search.js
Original file line number Diff line number Diff line change
@@ -1,41 +1,52 @@
import React from 'react';
import classNames from 'classnames';

export default function Search({ value, onChange, onClose, open = false, onSubmit = () => {} }) {
const closable = typeof onClose === 'function';
class Search extends React.Component {
focus() {
this.input.focus();
}

const handleSubmit = (e) => {
e.preventDefault();
onSubmit();
};
render() {
const { value, onChange, onClose, open = false, onSubmit = () => {} } = this.props;

const handleClose = (e) => {
e.preventDefault();
onClose();
}
const closable = typeof onClose === 'function';

const handleSubmit = (e) => {
e.preventDefault();
onSubmit();
};

return (
<form className={classNames('search', { 'search--closable': closable })} onSubmit={handleSubmit}>
<input
value={value}
type="text"
onChange={(e) => { onChange(e.target.value); }}
className="search__field"
placeholder="What are you looking for?"
/>
<span className={classNames('search__button', { 'is-open': open })}>
<button type="submit" className="button">
<span className="icon icon--search button__icon" />
Search
</button>
</span>
{
closable && (
<a href="#" className={classNames('search__close', { 'is-open': open })} onClick={handleClose}>
<span className="icon icon--close" />
</a>
)
}
</form>
);
const handleClose = (e) => {
e.preventDefault();
onClose();
}

return (
<form className={classNames('search', { 'search--closable': closable })} onSubmit={handleSubmit}>
<input
value={value}
type="text"
onChange={(e) => { onChange(e.target.value); }}
className="search__field"
placeholder="What are you looking for?"
ref={(input) => { this.input = input; }}
/>
<span className={classNames('search__button', { 'is-open': open })}>
<button type="submit" className="button">
<span className="icon icon--search button__icon" />
Search
</button>
</span>
{
closable && (
<a href="#" className={classNames('search__close', { 'is-open': open })} onClick={handleClose}>
<span className="icon icon--close" />
</a>
)
}
</form>
);
}
}

export default Search;
2 changes: 2 additions & 0 deletions js/reducer.js
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@ import { NAVIGATE } from './actions';

const initialState = {
pageName: 'index',
pageState: {},
items: [],
releases: [],
};
Expand All @@ -12,6 +13,7 @@ const appReducer = (state = initialState, action = {}) => {
return {
...state,
pageName: action.pageName,
pageState: action.pageState,
}
break;
default:
Expand Down
3 changes: 2 additions & 1 deletion js/server.js
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,8 @@ export const renderPage = (radar, pageName) => {
// Create a new Redux store instance
const store = createStore(appReducer, {
...radar,
pageName
pageName,
pageState: {},
});

// Render the component to a string
Expand Down

0 comments on commit ad2b0e3

Please sign in to comment.