From 2f54532be0da984c0444280ae23e1b3d8bcaf2a2 Mon Sep 17 00:00:00 2001 From: Ricardo de Arruda Date: Fri, 3 Jul 2020 23:20:44 +0300 Subject: Modify search button to be expandable. * Accordingly issue#814. * Input contract if un-focus input element * Search text data persisted when contracted/expanded --- ui/assets/css/main.css | 21 ++++++++----- ui/src/components/navbar.tsx | 71 +++++++++++++++++++++++++++++++++++--------- ui/src/index.tsx | 2 +- 3 files changed, 72 insertions(+), 22 deletions(-) diff --git a/ui/assets/css/main.css b/ui/assets/css/main.css index 4d9a099f..a05f5a8b 100644 --- a/ui/assets/css/main.css +++ b/ui/assets/css/main.css @@ -250,10 +250,17 @@ pre { word-break: keep-all; } -.search-bar { - flex-basis: 10%; - flex-shrink: 3; - flex-grow: 0.3; - max-width: 33%; - min-width: 11em; -} \ No newline at end of file +.form-control.search-input { + float: right !important; + transition: width 0.5s ease-out 0s !important; +} + +.show-input { + width: 13em !important; + +} +.hide-input { + background: transparent !important; + width: 0px !important; + padding: 0 !important; + } \ No newline at end of file diff --git a/ui/src/components/navbar.tsx b/ui/src/components/navbar.tsx index 175f590d..7c72d6cd 100644 --- a/ui/src/components/navbar.tsx +++ b/ui/src/components/navbar.tsx @@ -1,5 +1,5 @@ -import { Component, linkEvent } from 'inferno'; -import { Link, withRouter } from 'inferno-router'; +import { Component, linkEvent, createRef, RefObject } from 'inferno'; +import { Link } from 'inferno-router'; import { Subscription } from 'rxjs'; import { retryWhen, delay, take } from 'rxjs/operators'; import { WebSocketService, UserService } from '../services'; @@ -45,11 +45,13 @@ interface NavbarState { siteName: string; admins: Array; searchParam: string; + toggleSearch: boolean; } -class Navbar extends Component { +export class Navbar extends Component { private wsSub: Subscription; private userSub: Subscription; + private searchTextField: RefObject; emptyState: NavbarState = { isLoggedIn: UserService.Instance.user !== undefined, unreadCount: 0, @@ -60,6 +62,7 @@ class Navbar extends Component { siteName: undefined, admins: [], searchParam: '', + toggleSearch: false, }; constructor(props: any, context: any) { @@ -92,7 +95,7 @@ class Navbar extends Component { WebSocketService.Instance.getSite(); - this.handleSearchParam = this.handleSearchParam.bind(this); + this.searchTextField = createRef(); } handleSearchParam(i: Navbar, event: any) { @@ -101,10 +104,16 @@ class Navbar extends Component { } updateUrl() { - this.props.history.push( - `/search/q/${this.state.searchParam}/type/all/sort/topall/page/1` - ); + const searchParam = this.state.searchParam; this.setState({ searchParam: '' }); + this.setState({ toggleSearch: false }); + if (searchParam === '') { + this.context.router.history.push(`/search/`); + } else { + this.context.router.history.push( + `/search/q/${searchParam}/type/all/sort/topall/page/1` + ); + } } handleSearchSubmit(i: Navbar, event: any) { @@ -112,6 +121,24 @@ class Navbar extends Component { i.updateUrl(); } + handleSearchBtn(i: Navbar, event: any) { + event.preventDefault(); + i.setState({ toggleSearch: true }); + + i.searchTextField.current.focus(); + const offsetWidth = i.searchTextField.current.offsetWidth; + if (i.state.searchParam && offsetWidth > 100) { + i.updateUrl(); + } + } + + handleSearchBlur(i: Navbar, event: any) { + if (!(event.relatedTarget && event.relatedTarget.name !== 'search-btn')) { + i.state.toggleSearch = false; + i.setState(i.state); + } + } + render() { return this.navbar(); } @@ -199,16 +226,34 @@ class Navbar extends Component { - {!this.props.history.location.pathname.match(/^\/search/) && ( -