mirror of
https://github.com/LemmyNet/lemmy.git
synced 2024-12-24 11:51:32 +00:00
Modify search button to be expandable.
* Accordingly issue#814. * Input contract if un-focus input element * Search text data persisted when contracted/expanded
This commit is contained in:
parent
e41117c878
commit
2f54532be0
3 changed files with 72 additions and 22 deletions
19
ui/assets/css/main.css
vendored
19
ui/assets/css/main.css
vendored
|
@ -250,10 +250,17 @@ pre {
|
||||||
word-break: keep-all;
|
word-break: keep-all;
|
||||||
}
|
}
|
||||||
|
|
||||||
.search-bar {
|
.form-control.search-input {
|
||||||
flex-basis: 10%;
|
float: right !important;
|
||||||
flex-shrink: 3;
|
transition: width 0.5s ease-out 0s !important;
|
||||||
flex-grow: 0.3;
|
}
|
||||||
max-width: 33%;
|
|
||||||
min-width: 11em;
|
.show-input {
|
||||||
|
width: 13em !important;
|
||||||
|
|
||||||
|
}
|
||||||
|
.hide-input {
|
||||||
|
background: transparent !important;
|
||||||
|
width: 0px !important;
|
||||||
|
padding: 0 !important;
|
||||||
}
|
}
|
71
ui/src/components/navbar.tsx
vendored
71
ui/src/components/navbar.tsx
vendored
|
@ -1,5 +1,5 @@
|
||||||
import { Component, linkEvent } from 'inferno';
|
import { Component, linkEvent, createRef, RefObject } from 'inferno';
|
||||||
import { Link, withRouter } from 'inferno-router';
|
import { Link } from 'inferno-router';
|
||||||
import { Subscription } from 'rxjs';
|
import { Subscription } from 'rxjs';
|
||||||
import { retryWhen, delay, take } from 'rxjs/operators';
|
import { retryWhen, delay, take } from 'rxjs/operators';
|
||||||
import { WebSocketService, UserService } from '../services';
|
import { WebSocketService, UserService } from '../services';
|
||||||
|
@ -45,11 +45,13 @@ interface NavbarState {
|
||||||
siteName: string;
|
siteName: string;
|
||||||
admins: Array<UserView>;
|
admins: Array<UserView>;
|
||||||
searchParam: string;
|
searchParam: string;
|
||||||
|
toggleSearch: boolean;
|
||||||
}
|
}
|
||||||
|
|
||||||
class Navbar extends Component<any, NavbarState> {
|
export class Navbar extends Component<any, NavbarState> {
|
||||||
private wsSub: Subscription;
|
private wsSub: Subscription;
|
||||||
private userSub: Subscription;
|
private userSub: Subscription;
|
||||||
|
private searchTextField: RefObject<HTMLInputElement>;
|
||||||
emptyState: NavbarState = {
|
emptyState: NavbarState = {
|
||||||
isLoggedIn: UserService.Instance.user !== undefined,
|
isLoggedIn: UserService.Instance.user !== undefined,
|
||||||
unreadCount: 0,
|
unreadCount: 0,
|
||||||
|
@ -60,6 +62,7 @@ class Navbar extends Component<any, NavbarState> {
|
||||||
siteName: undefined,
|
siteName: undefined,
|
||||||
admins: [],
|
admins: [],
|
||||||
searchParam: '',
|
searchParam: '',
|
||||||
|
toggleSearch: false,
|
||||||
};
|
};
|
||||||
|
|
||||||
constructor(props: any, context: any) {
|
constructor(props: any, context: any) {
|
||||||
|
@ -92,7 +95,7 @@ class Navbar extends Component<any, NavbarState> {
|
||||||
|
|
||||||
WebSocketService.Instance.getSite();
|
WebSocketService.Instance.getSite();
|
||||||
|
|
||||||
this.handleSearchParam = this.handleSearchParam.bind(this);
|
this.searchTextField = createRef();
|
||||||
}
|
}
|
||||||
|
|
||||||
handleSearchParam(i: Navbar, event: any) {
|
handleSearchParam(i: Navbar, event: any) {
|
||||||
|
@ -101,10 +104,16 @@ class Navbar extends Component<any, NavbarState> {
|
||||||
}
|
}
|
||||||
|
|
||||||
updateUrl() {
|
updateUrl() {
|
||||||
this.props.history.push(
|
const searchParam = this.state.searchParam;
|
||||||
`/search/q/${this.state.searchParam}/type/all/sort/topall/page/1`
|
|
||||||
);
|
|
||||||
this.setState({ 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) {
|
handleSearchSubmit(i: Navbar, event: any) {
|
||||||
|
@ -112,6 +121,24 @@ class Navbar extends Component<any, NavbarState> {
|
||||||
i.updateUrl();
|
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() {
|
render() {
|
||||||
return this.navbar();
|
return this.navbar();
|
||||||
}
|
}
|
||||||
|
@ -199,16 +226,34 @@ class Navbar extends Component<any, NavbarState> {
|
||||||
</Link>
|
</Link>
|
||||||
</li>
|
</li>
|
||||||
</ul>
|
</ul>
|
||||||
{!this.props.history.location.pathname.match(/^\/search/) && (
|
{!this.context.router.history.location.pathname.match(
|
||||||
<div class="nav-item search-bar">
|
/^\/search/
|
||||||
<form onSubmit={linkEvent(this, this.handleSearchSubmit)}>
|
) && (
|
||||||
|
<div class="nav-item my-2">
|
||||||
|
<form
|
||||||
|
class="form-inline"
|
||||||
|
onSubmit={linkEvent(this, this.handleSearchSubmit)}
|
||||||
|
>
|
||||||
<input
|
<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)}
|
onInput={linkEvent(this, this.handleSearchParam)}
|
||||||
value={this.state.searchParam}
|
value={this.state.searchParam}
|
||||||
type="search"
|
ref={this.searchTextField}
|
||||||
|
type="text"
|
||||||
placeholder={i18n.t('search')}
|
placeholder={i18n.t('search')}
|
||||||
|
onBlur={linkEvent(this, this.handleSearchBlur)}
|
||||||
></input>
|
></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>
|
</form>
|
||||||
</div>
|
</div>
|
||||||
)}
|
)}
|
||||||
|
@ -457,5 +502,3 @@ class Navbar extends Component<any, NavbarState> {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
export default withRouter(Navbar);
|
|
||||||
|
|
2
ui/src/index.tsx
vendored
2
ui/src/index.tsx
vendored
|
@ -2,7 +2,7 @@ import { render, Component } from 'inferno';
|
||||||
import { BrowserRouter, Route, Switch } from 'inferno-router';
|
import { BrowserRouter, Route, Switch } from 'inferno-router';
|
||||||
import { Provider } from 'inferno-i18next';
|
import { Provider } from 'inferno-i18next';
|
||||||
import { Main } from './components/main';
|
import { Main } from './components/main';
|
||||||
import Navbar from './components/navbar';
|
import { Navbar } from './components/navbar';
|
||||||
import { Footer } from './components/footer';
|
import { Footer } from './components/footer';
|
||||||
import { Login } from './components/login';
|
import { Login } from './components/login';
|
||||||
import { CreatePost } from './components/create-post';
|
import { CreatePost } from './components/create-post';
|
||||||
|
|
Loading…
Reference in a new issue