From fd029dad9e7278edbb9999f8a73e29c3bf39cdde Mon Sep 17 00:00:00 2001 From: Tom Raithel Date: Mon, 20 Mar 2017 22:47:46 +0100 Subject: [PATCH] WIP: Search form in header bar --- assets/icons/close.svg | 1 + js/components/Header.js | 82 +++++++++++++++++++++++++---------- js/components/PageOverview.js | 2 - js/components/Search.js | 20 +++++++-- styles/components/icon.css | 4 ++ styles/components/nav.css | 24 ++++++++++ styles/components/search.css | 34 +++++++++++++++ 7 files changed, 138 insertions(+), 29 deletions(-) create mode 100644 assets/icons/close.svg diff --git a/assets/icons/close.svg b/assets/icons/close.svg new file mode 100644 index 0000000..b01b946 --- /dev/null +++ b/assets/icons/close.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/js/components/Header.js b/js/components/Header.js index cf23918..aed6152 100644 --- a/js/components/Header.js +++ b/js/components/Header.js @@ -1,34 +1,68 @@ import React from 'react'; +import classNames from 'classnames'; import Branding from './Branding'; import Link from './Link'; import LogoLink from './LogoLink'; +import Search from './Search'; import { getItemPageNames } from '../../common/config'; -export default function Header({ pageName }) { +class Header extends React.Component { + constructor(...args) { + super(...args); + this.state = { + searchOpen: false, + }; + } - const smallLogo = pageName !== 'index'; + openSearch = () => { + this.setState({ + searchOpen: true, + }); + } - return ( - } - > -
-
- - How to Use Technology Radar? - + closeSearch = () => { + this.setState({ + searchOpen: false, + }); + } + + handleOpenClick = (e) => { + e.preventDefault(); + this.openSearch(); + } + + render() { + const { pageName } = this.props; + const { searchOpen } = this.state; + const smallLogo = pageName !== 'index'; + + return ( + } + > +
+
+ + How to Use Technology Radar? + +
+
+ + Technologies Overview + +
+
+ + Search + +
+ +
+
-
- - Technologies Overview - -
- -
- - ); + + ); + } } + +export default Header; diff --git a/js/components/PageOverview.js b/js/components/PageOverview.js index 4941360..baeb17d 100644 --- a/js/components/PageOverview.js +++ b/js/components/PageOverview.js @@ -30,7 +30,6 @@ class PageOverview extends React.Component { e.preventDefault(); this.setState({ - ...this.state, ring, }); } @@ -66,7 +65,6 @@ class PageOverview extends React.Component { handleSearchTermChange = (value) => { this.setState({ - ...this.state, search: value, }); }; diff --git a/js/components/Search.js b/js/components/Search.js index eb7082c..9c42eb2 100644 --- a/js/components/Search.js +++ b/js/components/Search.js @@ -1,14 +1,21 @@ import React from 'react'; import classNames from 'classnames'; -export default function Search({ value, onChange, onSubmit = () => {} }) { +export default function Search({ value, onChange, onClose, open = false, onSubmit = () => {} }) { + const closable = typeof onClose === 'function'; + const handleSubmit = (e) => { e.preventDefault(); onSubmit(); }; + const handleClose = (e) => { + e.preventDefault(); + onClose(); + } + return ( -
+ {} }) { className="search__field" placeholder="What are you looking for?" /> - + + { + closable && ( + + + + ) + } ); } diff --git a/styles/components/icon.css b/styles/components/icon.css index 5d35991..863de03 100644 --- a/styles/components/icon.css +++ b/styles/components/icon.css @@ -26,4 +26,8 @@ &--back { background-image: url('/assets/icons/back.svg'); } + + &--close { + background-image: url('/assets/icons/close.svg'); + } } diff --git a/styles/components/nav.css b/styles/components/nav.css index 48ba412..e041f56 100644 --- a/styles/components/nav.css +++ b/styles/components/nav.css @@ -1,9 +1,33 @@ .nav { white-space: nowrap; + &__item { display: inline-flex; + position: relative; & + .nav__item { margin-left: 20px; } } + + &__search { + position: absolute; + right: 0; + top: 50%; + visibility: hidden; + overflow: hidden; + width: 0; + margin-top: -25px; + opacity: 0.8; + transition: + width 400ms cubic-bezier(0.24, 1.12, 0.71, 0.98) 100ms, + visibility 0s linear 500ms, + opacity 200ms linear; + + &.is-open { + opacity: 1; + width: 600px; + visibility: visible; + transition-delay: 0s; + } + } } diff --git a/styles/components/search.css b/styles/components/search.css index 1f63c36..7cf13f6 100644 --- a/styles/components/search.css +++ b/styles/components/search.css @@ -35,4 +35,38 @@ margin-top: -18px; right: 7px; } + + &--closable { + .search { + &__field { + padding-right: 160px; + } + + &__button { + right: 50px; + transform: translateX(20px); + transition: transform 450ms cubic-bezier(0.24, 1.12, 0.71, 0.98) 100ms; + + &.is-open { + transform: translateX(0); + transition-delay: 250ms; + } + } + + &__close { + position: absolute; + padding: 10px; + top: 50%; + margin-top: -21px; + right: 4px; + transform: scale(0.2); + transition: transform 400ms cubic-bezier(0.24, 1.12, 0.71, 0.98); + + &.is-open { + transform: rotate(180deg) scale(1); + transition-delay: 300ms; + } + } + } + } }