diff options
-rw-r--r-- | package.json | 2 | ||||
-rw-r--r-- | src/client/react/actions/search.js | 5 | ||||
-rw-r--r-- | src/client/react/components/container/Search.js | 9 | ||||
-rw-r--r-- | src/client/react/components/presentational/Search.jsx | 35 | ||||
-rw-r--r-- | src/client/react/reducers/search.js | 6 | ||||
-rw-r--r-- | src/client/static/bundle.css | 30 | ||||
-rw-r--r-- | src/client/style/index.scss | 41 | ||||
-rw-r--r-- | src/client/views/index.jade | 3 | ||||
-rw-r--r-- | yarn.lock | 14 |
9 files changed, 133 insertions, 12 deletions
diff --git a/package.json b/package.json index 70ae1ff..364cfd6 100644 --- a/package.json +++ b/package.json @@ -16,6 +16,7 @@ "body-parser": "^1.16.0", "browser-request": "^0.3.3", "cheerio": "^0.22.0", + "classnames": "^2.2.5", "compression": "^1.6.2", "cookie-parser": "~1.4.3", "css-loader": "^0.28.7", @@ -36,6 +37,7 @@ "prop-types": "^15.6.0", "react": "^16.2.0", "react-dom": "^16.2.0", + "react-icons": "^2.2.7", "react-redux": "^5.0.6", "redux": "^3.7.2", "request": "^2.74.0", diff --git a/src/client/react/actions/search.js b/src/client/react/actions/search.js index e50d851..53993d3 100644 --- a/src/client/react/actions/search.js +++ b/src/client/react/actions/search.js @@ -3,3 +3,8 @@ export const inputChange = typedValue => ({ type: 'SEARCH/INPUT_CHANGE', typedValue, }); + +export const focusChange = hasFocus => ({ + type: 'SEARCH/FOCUS_CHANGE', + hasFocus, +}); diff --git a/src/client/react/components/container/Search.js b/src/client/react/components/container/Search.js index 2489084..206a6a1 100644 --- a/src/client/react/components/container/Search.js +++ b/src/client/react/components/container/Search.js @@ -1,16 +1,23 @@ import { connect } from 'react-redux'; -import { inputChange } from '../../actions/search'; +import { inputChange, focusChange } from '../../actions/search'; import PresentationalSearch from '../presentational/Search'; const mapStateToProps = state => ({ results: state.search.searchResults, value: state.search.searchInput, + hasFocus: state.search.hasFocus, }); const mapDispatchToProps = dispatch => ({ onInputChange: (event) => { dispatch(inputChange(event.target.value)); }, + onFocus: () => { + dispatch(focusChange(true)); + }, + onBlur: () => { + dispatch(focusChange(false)); + }, }); const Search = connect( diff --git a/src/client/react/components/presentational/Search.jsx b/src/client/react/components/presentational/Search.jsx index a713db4..01c6f7d 100644 --- a/src/client/react/components/presentational/Search.jsx +++ b/src/client/react/components/presentational/Search.jsx @@ -1,13 +1,27 @@ import React from 'react'; import PropTypes from 'prop-types'; +import classnames from 'classnames'; +import SearchIcon from 'react-icons/lib/md/search'; -const Search = ({ onInputChange, value, results }) => ( - <div> - <input - onChange={onInputChange} - value={value} - placeholder="Zoeken" - /> +const Search = ({ + onInputChange, + onFocus, + onBlur, + hasFocus, + value, + results, +}) => ( + <div className={classnames('search', { focus: hasFocus })}> + <div className="search__input-wrapper"> + <div className="search__icon-wrapper"><SearchIcon /></div> + <input + onChange={onInputChange} + value={value} + placeholder="Zoeken" + onFocus={onFocus} + onBlur={onBlur} + /> + </div> <ul> {results.map(result => <li key={result.name}>{result.name}</li>)} </ul> @@ -16,10 +30,13 @@ const Search = ({ onInputChange, value, results }) => ( Search.propTypes = { onInputChange: PropTypes.func.isRequired, + onFocus: PropTypes.func.isRequired, + onBlur: PropTypes.func.isRequired, + hasFocus: PropTypes.bool.isRequired, value: PropTypes.string.isRequired, results: PropTypes.arrayOf(PropTypes.shape({ - name: PropTypes.string.require, - type: PropTypes.string.require, + name: PropTypes.string.isRequired, + type: PropTypes.string.isRequired, })).isRequired, }; diff --git a/src/client/react/reducers/search.js b/src/client/react/reducers/search.js index 08be519..a695184 100644 --- a/src/client/react/reducers/search.js +++ b/src/client/react/reducers/search.js @@ -1,6 +1,7 @@ const DEFAULT_STATE = { searchInput: '', searchResults: [], + hasFocus: false, }; const search = (state = DEFAULT_STATE, action) => { @@ -13,6 +14,11 @@ const search = (state = DEFAULT_STATE, action) => { { type: 's', name: '18561' }, ], }; + case 'SEARCH/FOCUS_CHANGE': + return { + ...state, + hasFocus: action.hasFocus, + }; default: return state; } diff --git a/src/client/static/bundle.css b/src/client/static/bundle.css index ba2197a..d04fba6 100644 --- a/src/client/static/bundle.css +++ b/src/client/static/bundle.css @@ -1,2 +1,30 @@ body { - background-color: black; } + background-color: #ececec; } + +* { + box-sizing: border-box; } + +.search { + width: 580px; + height: 54px; + background-color: white; } + .search.focus { + box-shadow: 0 1px 3px rgba(0, 0, 0, 0.12), 0 1px 2px rgba(0, 0, 0, 0.24); } + .search__icon-wrapper { + height: 54px; + padding: 15px; } + .search__icon-wrapper svg { + height: 24px; + width: 24px; } + .search__input-wrapper { + display: flex; + widows: inherit; + height: 54px; } + .search__input-wrapper input { + border: 0; + background-color: transparent; + flex-grow: 1; + height: inherit; + padding: 16px; + padding-left: 0px; + font-size: 16px; } diff --git a/src/client/style/index.scss b/src/client/style/index.scss index c4d554e..6f1592c 100644 --- a/src/client/style/index.scss +++ b/src/client/style/index.scss @@ -1,3 +1,42 @@ body { - background-color: black; + background-color: #ececec; +} + +* { + box-sizing: border-box; +} + +.search { + width: 580px; + height: 54px; + background-color: white; + + &.focus { + box-shadow: 0 1px 3px rgba(0,0,0,0.12), 0 1px 2px rgba(0,0,0,0.24); + } + + &__icon-wrapper { + height: 54px; + padding: 15px; + svg { + height: 24px; + width: 24px; + } + } + + &__input-wrapper { + display: flex; + widows: inherit; + height: 54px; + + input { + border: 0; + background-color: transparent; + flex-grow: 1; + height: inherit; + padding: 16px; + padding-left: 0px; + font-size: 16px; + } + } } diff --git a/src/client/views/index.jade b/src/client/views/index.jade index a5f1f45..0a057db 100644 --- a/src/client/views/index.jade +++ b/src/client/views/index.jade @@ -1,5 +1,8 @@ extends layout +block head + link(rel='stylesheet', href='/bundle.css') + block content #root @@ -1373,6 +1373,10 @@ clap@^1.0.9: dependencies: chalk "^1.1.3" +classnames@^2.2.5: + version "2.2.5" + resolved "https://registry.yarnpkg.com/classnames/-/classnames-2.2.5.tgz#fb3801d453467649ef3603c7d61a02bd129bde6d" + clean-css@^3.1.9: version "3.4.28" resolved "https://registry.yarnpkg.com/clean-css/-/clean-css-3.4.28.tgz#bf1945e82fc808f55695e6ddeaec01400efd03ff" @@ -5169,6 +5173,16 @@ react-dom@^16.2.0: object-assign "^4.1.1" prop-types "^15.6.0" +react-icon-base@2.1.0: + version "2.1.0" + resolved "https://registry.yarnpkg.com/react-icon-base/-/react-icon-base-2.1.0.tgz#a196e33fdf1e7aaa1fda3aefbb68bdad9e82a79d" + +react-icons@^2.2.7: + version "2.2.7" + resolved "https://registry.yarnpkg.com/react-icons/-/react-icons-2.2.7.tgz#d7860826b258557510dac10680abea5ca23cf650" + dependencies: + react-icon-base "2.1.0" + react-redux@^5.0.6: version "5.0.6" resolved "https://registry.yarnpkg.com/react-redux/-/react-redux-5.0.6.tgz#23ed3a4f986359d68b5212eaaa681e60d6574946" |