diff options
author | Ricardo de Arruda <settiricardo@gmail.com> | 2020-07-03 23:20:44 +0300 |
---|---|---|
committer | Ricardo de Arruda <settiricardo@gmail.com> | 2020-07-03 23:20:44 +0300 |
commit | 2f54532be0da984c0444280ae23e1b3d8bcaf2a2 (patch) | |
tree | 95a3c49007563fceb9db1392a1636e0b9f3a8895 /ui | |
parent | e41117c8785e414f543501dd4c50c96d5485d694 (diff) |
Modify search button to be expandable.
* Accordingly issue#814.
* Input contract if un-focus input element
* Search text data persisted when contracted/expanded
Diffstat (limited to 'ui')
-rw-r--r-- | ui/assets/css/main.css | 21 | ||||
-rw-r--r-- | ui/src/components/navbar.tsx | 71 | ||||
-rw-r--r-- | 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<UserView>; searchParam: string; + toggleSearch: boolean; } -class Navbar extends Component<any, NavbarState> { +export class Navbar extends Component<any, NavbarState> { private wsSub: Subscription; private userSub: Subscription; + private searchTextField: RefObject<HTMLInputElement>; emptyState: NavbarState = { isLoggedIn: UserService.Instance.user !== undefined, unreadCount: 0, @@ -60,6 +62,7 @@ class Navbar extends Component<any, NavbarState> { siteName: undefined, admins: [], searchParam: '', + toggleSearch: false, }; constructor(props: any, context: any) { @@ -92,7 +95,7 @@ class Navbar extends Component<any, NavbarState> { 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<any, NavbarState> { } 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<any, NavbarState> { 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<any, NavbarState> { </Link> </li> </ul> - {!this.props.history.location.pathname.match(/^\/search/) && ( - <div class="nav-item search-bar"> - <form onSubmit={linkEvent(this, this.handleSearchSubmit)}> + {!this.context.router.history.location.pathname.match( + /^\/search/ + ) && ( + <div class="nav-item my-2"> + <form + class="form-inline" + onSubmit={linkEvent(this, this.handleSearchSubmit)} + > <input - class="form-control mr-sm-2" + class={`form-control mr-0 search-input ${ + this.state.toggleSearch ? 'show-input' : 'hide-input' + }`} onInput={linkEvent(this, this.handleSearchParam)} value={this.state.searchParam} - type="search" + ref={this.searchTextField} + type="text" placeholder={i18n.t('search')} + onBlur={linkEvent(this, this.handleSearchBlur)} ></input> + <div class="mx-sm-2"> + <button + name="search-btn" + onClick={linkEvent(this, this.handleSearchBtn)} + class="btn btn-secondary" + > + {i18n.t('search')} + </button> + </div> </form> </div> )} @@ -457,5 +502,3 @@ class Navbar extends Component<any, NavbarState> { } } } - -export default withRouter(Navbar); diff --git a/ui/src/index.tsx b/ui/src/index.tsx index 09d3aec6..8e49df9f 100644 --- a/ui/src/index.tsx +++ b/ui/src/index.tsx @@ -2,7 +2,7 @@ import { render, Component } from 'inferno'; import { BrowserRouter, Route, Switch } from 'inferno-router'; import { Provider } from 'inferno-i18next'; import { Main } from './components/main'; -import Navbar from './components/navbar'; +import { Navbar } from './components/navbar'; import { Footer } from './components/footer'; import { Login } from './components/login'; import { CreatePost } from './components/create-post'; |