Merge branch 'feature/search_postcode_on_mobile'

This commit is contained in:
Tom Russell 2019-07-07 18:10:56 +01:00
commit 1ffb5b185a
4 changed files with 96 additions and 14 deletions

View File

@ -5,7 +5,7 @@ import React from 'react'
import { library } from '@fortawesome/fontawesome-svg-core'
import { FontAwesomeIcon } from '@fortawesome/react-fontawesome'
import { faQuestionCircle, faPaintBrush, faInfoCircle, faTimes, faCheck, faCheckDouble,
faAngleLeft, faCaretDown } from '@fortawesome/free-solid-svg-icons'
faAngleLeft, faCaretDown, faSearch } from '@fortawesome/free-solid-svg-icons'
library.add(
faQuestionCircle,
@ -15,7 +15,8 @@ library.add(
faCheck,
faCheckDouble,
faAngleLeft,
faCaretDown
faCaretDown,
faSearch
);
const HelpIcon = () => (
@ -44,10 +45,14 @@ const SaveDoneIcon = () => (
const BackIcon = () => (
<FontAwesomeIcon icon="angle-left" />
)
);
const DownIcon = () => (
<FontAwesomeIcon icon="caret-down" />
)
);
export { HelpIcon, InfoIcon, EditIcon, CloseIcon, SaveIcon, SaveDoneIcon, BackIcon, DownIcon };
const SearchIcon = () => (
<FontAwesomeIcon icon="search" />
);
export { HelpIcon, InfoIcon, EditIcon, CloseIcon, SaveIcon, SaveDoneIcon, BackIcon, DownIcon, SearchIcon };

View File

@ -5,9 +5,8 @@
border-radius: 4px;
z-index: 1000;
position: absolute;
left: 25.5rem;
top: 0.5rem;
box-shadow: 0px 0px 1px 1px #222;
visibility: hidden;
}
.leaflet-container {
position: absolute;
@ -23,3 +22,11 @@
.leaflet-grab {
cursor: crosshair;
}
@media (min-width: 768px){
/* Only show the "Click a building ..." notice for larger screens */
.map-notice {
left: 25.5rem;
top: 0.5rem;
visibility: visible;
}
}

View File

@ -1,8 +1,9 @@
.search-box {
position: absolute;
top: 3.625rem;
left: 25.5rem;
top: 0.5rem;
left: 0.5rem;
z-index: 1000;
max-width:80%;
}
.building.search-box {
top: 0.5rem;
@ -27,3 +28,31 @@
padding: 0.25rem 0.5rem;
border-bottom: 1px solid #eee;
}
.collapse-btn {
position: absolute;
top: 0.5rem;
left: 0.5rem;
z-index: 1000;
background: #fff;
border-radius: 2px;
box-shadow: 0px 0px 1px 1px #222222;
}
.form-control {
padding: 0.1rem 0.1rem;
width: 180px;
}
.btn {
padding: 0.25rem 0.2rem;
margin-right: 0.1rem;
}
@media (min-width: 768px) {
/* for large screens adopt the conventional search box position */
.search-box{
top: 3.625rem;
left: 25.5rem;
}
/* The following is a fix (?) for the truncation of the "Search for postcode" text */
.form-inline .form-control {
width: 200px;
}
}

View File

@ -2,7 +2,7 @@ import React, { Component } from 'react';
import PropTypes from 'prop-types';
import './search-box.css';
import { SearchIcon } from './icons';
/**
* Search for location
*/
@ -13,13 +13,19 @@ class SearchBox extends Component {
this.state = {
q: '',
results: [],
fetching: false
fetching: false,
//track the state of the search box i.e. collapsed or expanded. Default to true
collapsedSearch: true,
//is this a small screen device? if not we will disable collapse option
smallScreen: false
}
this.handleChange = this.handleChange.bind(this);
this.search = this.search.bind(this);
this.handleKeyPress = this.handleKeyPress.bind(this);
this.clearResults = this.clearResults.bind(this);
this.clearQuery = this.clearQuery.bind(this);
this.expandSearch = this.expandSearch.bind(this);
this.onResize= this.onResize.bind(this);
}
// Update search term
@ -54,6 +60,12 @@ class SearchBox extends Component {
});
}
expandSearch(e){
this.setState(state => ({
collapsedSearch: !state.collapsedSearch
}));
}
// Query search endpoint
search(e) {
e.preventDefault();
@ -89,7 +101,34 @@ class SearchBox extends Component {
})
}
componentDidMount() {
window.addEventListener('resize', this.onResize);
if (window && window.outerHeight) {
// if we're in the browser, pass in as though from event to initialise
this.onResize({target: window});
}
}
componentWillUnmount() {
window.removeEventListener('resize', this.onResize);
}
// On a real mobile device onResize() gets called when the virtual keyboard pops up (e.g. when entering search text)
// so be careful what states are changed in this method (i.e. don't collapse the search box here)
onResize(e) {
this.setState({smallScreen: (e.target.outerWidth < 768)});
}
render() {
// if the current state is collapsed (and a mobile device) just render the icon
if(this.state.collapsedSearch && this.state.smallScreen){
return(
<div className="collapse-btn" onClick={this.expandSearch}>
<SearchIcon />
</div>
)
}
const resultsList = this.state.results.length?
<ul className="search-box-results">
{
@ -117,8 +156,10 @@ class SearchBox extends Component {
: null;
return (
<div className={`search-box ${this.props.isBuilding? 'building' : ''}`} onKeyDown={this.handleKeyPress}>
<form action="/search" method="GET" onSubmit={this.search}
className="form-inline">
<form action="/search" method="GET" onSubmit={this.search} className="form-inline">
<div onClick={this.state.smallScreen ? this.expandSearch : null}>
<SearchIcon/>
</div>
<input
className="form-control"
type="search"
@ -129,7 +170,7 @@ class SearchBox extends Component {
aria-label="Search for a postcode"
onChange={this.handleChange}
/>
<button className="btn btn-outline-dark" type="submit">Search</button>
<button className="btn btn-outline-dark" type="submit">Search</button>
</form>
{ resultsList }
</div>