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/src/components/navbar.tsx | 71 +++++++++++++++++++++++++++++++++++--------- 1 file changed, 57 insertions(+), 14 deletions(-) (limited to 'ui/src/components/navbar.tsx') 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/) && ( -