Skip to content

Commit

Permalink
docs(examples): add url sync (#1542)
Browse files Browse the repository at this point in the history
  • Loading branch information
mthuret authored and vvo committed Nov 14, 2016
1 parent ed2ae84 commit b277d31
Show file tree
Hide file tree
Showing 8 changed files with 142 additions and 90 deletions.
37 changes: 20 additions & 17 deletions docgen/src/examples/e-commerce/App.js
Original file line number Diff line number Diff line change
Expand Up @@ -19,25 +19,26 @@ import {
connectHits,
connectMultiRange,
} from 'react-instantsearch/connectors';
import {withUrlSync} from '../urlSync';

export default function App() {
return (
<InstantSearch
className="container-fluid"
appId="latency"
apiKey="6be0576ff61c053d5f9a3225e2a90f76"
indexName="ikea"
>
<div>
<Header />
<div className="content-wrapper">
<Facets />
<CustomResults />
</div>
const App = props =>
<InstantSearch
className="container-fluid"
appId="latency"
apiKey="6be0576ff61c053d5f9a3225e2a90f76"
indexName="ikea"
state={props.state}
createURL={props.createURL.bind(this)}
onStateChange={props.onStateChange.bind(this)}
>
<div>
<Header />
<div className="content-wrapper">
<Facets />
<CustomResults />
</div>
</InstantSearch>
);
}
</div>
</InstantSearch>;

const Header = () =>
<header className="content-wrapper">
Expand Down Expand Up @@ -295,3 +296,5 @@ const PriceRange = ({label, value, onClick}) =>
const ConnectedSearchBox = connectSearchBox(CustomCheckbox);
const ConnectedColorRefinementList = connectRefinementList(CustomColorRefinementList);
const ConnectedHits = connectHits(CustomHits);

export default withUrlSync(App);
4 changes: 2 additions & 2 deletions docgen/src/examples/e-commerce/style.css
Original file line number Diff line number Diff line change
Expand Up @@ -344,7 +344,7 @@ aside .facet-color[data-facet-value="White stained oak effect"] {

.results-wrapper {
position: absolute;
top: 0;
top: 60px;
right: 0;
padding: 70px 10px 10px 240px;
}
Expand Down Expand Up @@ -386,7 +386,7 @@ aside .facet-color[data-facet-value="White stained oak effect"] {
display: inline-block;
}

.ClearAll {
.ais-ClearAll__root {
display: block;
margin-bottom: 16px;
font-size: 13px;
Expand Down
83 changes: 43 additions & 40 deletions docgen/src/examples/material-ui/App.js
Original file line number Diff line number Diff line change
Expand Up @@ -33,23 +33,24 @@ import {
} from 'material-ui';
import {BottomNavigation, BottomNavigationItem} from 'material-ui/BottomNavigation';
import SortIcon from 'material-ui/svg-icons/content/sort';
import {withUrlSync} from '../urlSync';

injectTapEventPlugin();

export default function App() {
return (
<MuiThemeProvider>
<MaterialUiExample />
</MuiThemeProvider>
);
}
const App = props =>
<MuiThemeProvider>
<MaterialUiExample {...props} />
</MuiThemeProvider>;

const MaterialUiExample = () =>
const MaterialUiExample = props =>
<InstantSearch
appId="latency"
apiKey="6be0576ff61c053d5f9a3225e2a90f76"
indexName="ikea">

indexName="ikea"
state={props.state}
createURL={props.createURL.bind(this)}
onStateChange={props.onStateChange.bind(this)}
>
<Content/>
</InstantSearch>;

Expand Down Expand Up @@ -145,16 +146,16 @@ const MaterialUiSearchBox = ({query, refine, marginLeft}) => {
};

const CheckBoxItem = ({item, refine}) =>
<ListItem
primaryText={item.label}
leftCheckbox={
<Checkbox checked={item.isRefined}
onCheck={e => {
e.preventDefault();
refine(item.value);
}}
/>}
/>;
<ListItem
primaryText={item.label}
leftCheckbox={
<Checkbox checked={item.isRefined}
onCheck={e => {
e.preventDefault();
refine(item.value);
}}
/>}
/>;

const MaterialUiCheckBoxRefinementList = ({items, attributeName, refine, createURL}) =>
<List>
Expand All @@ -175,27 +176,27 @@ const MaterialUiNestedList = function ({id, items, refine}) {
<Subheader style={{fontSize: 18}}>{id.toUpperCase()}</Subheader>
{items.map((item, idx) => {
const nestedElements = item.children ? item.children.map((child, childIdx) =>
<ListItem
primaryText={child.label}
key={childIdx}
<ListItem
primaryText={child.label}
key={childIdx}
onClick={e => {
e.preventDefault();
refine(child.value);
}}
style={child.isRefined ? {fontWeight: 700} : {}}
/>
) : [];
return <ListItem
primaryText={item.label}
key={idx}
primaryTogglesNestedList={true}
nestedItems={nestedElements}
onClick={e => {
e.preventDefault();
refine(child.value);
refine(item.value);
}}
style={child.isRefined ? {fontWeight: 700} : {}}
/>
) : [];
return <ListItem
primaryText={item.label}
key={idx}
primaryTogglesNestedList={true}
nestedItems={nestedElements}
onClick={e => {
e.preventDefault();
refine(item.value);
}}
style={item.isRefined ? {fontWeight: 700} : {}}
/>;
style={item.isRefined ? {fontWeight: 700} : {}}
/>;
}
)}
</List>;
Expand Down Expand Up @@ -278,10 +279,10 @@ function CustomHits({hits, marginLeft}) {
);
}

function MaterialUiClearAllFilters({filters, refine}) {
function MaterialUiClearAllFilters({items, refine}) {
return (
<FlatButton
onTouchTap={() => refine(filters)}
onTouchTap={() => refine(items)}
label="Clear All"
style={{height: 48, width: 300, backgroundColor: 'white'}}
/>
Expand Down Expand Up @@ -367,3 +368,5 @@ const ConnectedHits = connectHits(CustomHits);
const ConnectedCurrentRefinements = connectCurrentRefinements(MaterialUiClearAllFilters);

const ConnectedPagination = connectPagination(MaterialUiBottomNavigation);

export default withUrlSync(App);
11 changes: 8 additions & 3 deletions docgen/src/examples/media/App.js
Original file line number Diff line number Diff line change
Expand Up @@ -11,12 +11,16 @@ import {
} from 'react-instantsearch/dom';

import {connectSearchBox, connectRefinementList} from 'react-instantsearch/connectors';
import {withUrlSync} from '../urlSync';

export default function App() {
return <InstantSearch
const App = props =>
<InstantSearch
appId="latency"
apiKey="6be0576ff61c053d5f9a3225e2a90f76"
indexName="movies"
state={props.state}
createURL={props.createURL.bind(this)}
onStateChange={props.onStateChange.bind(this)}
>
<div>
<Header/>
Expand All @@ -26,7 +30,6 @@ export default function App() {
</section>
</div>
</InstantSearch>;
}

const Header = () =>
<header className="row">
Expand Down Expand Up @@ -143,3 +146,5 @@ const RefinementListLinks = connectRefinementList(({items, refine, createURL}) =
</div>
);
});

export default withUrlSync(App);
64 changes: 37 additions & 27 deletions docgen/src/examples/tourism/App.js
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
/* eslint react/prop-types: 0 */
import {
InstantSearch,
SearchBox,
Expand All @@ -15,22 +16,23 @@ import GoogleMap from 'google-map-react';
import {fitBounds} from 'google-map-react/utils';

import Rheostat from 'rheostat';
import {withUrlSync} from '../urlSync';

export default function TourismInstantsearchSample() {
return (
<InstantSearch
appId="latency"
apiKey="6be0576ff61c053d5f9a3225e2a90f76"
indexName="airbnb"
>
<div>
<Header />
<Filters />
<Results />
</div>
</InstantSearch>
);
}
const App = props =>
<InstantSearch
appId="latency"
apiKey="6be0576ff61c053d5f9a3225e2a90f76"
indexName="airbnb"
state={props.state}
createURL={props.createURL.bind(this)}
onStateChange={props.onStateChange.bind(this)}
>
<div>
<Header />
<Filters />
<Results />
</div>
</InstantSearch>;

function Header() {
const containerStyle = {
Expand All @@ -42,7 +44,9 @@ function Header() {
<div className="container-fluid" style={containerStyle}>
<header className="navbar navbar-static-top aisdemo-navbar">
<a href="./" className="is-logo">
<img src="https://res.cloudinary.com/hilnmyskv/image/upload/w_100,h_100,dpr_2.0//v1461180087/logo-instantsearchjs-avatar.png" width={40} />
<img
src="https://res.cloudinary.com/hilnmyskv/image/upload/w_100,h_100,dpr_2.0//v1461180087/logo-instantsearchjs-avatar.png"
width={40}/>
</a>
<a href="./" className="logo">A</a>
<i className="fa fa-search"></i>
Expand All @@ -65,7 +69,7 @@ function Filters() {
attributeName="room_type"
operator="or"
sortBy={['name:asc']}
limitMin={3} />
limitMin={3}/>
<Price />
</div>

Expand All @@ -88,8 +92,12 @@ function CustomMarker() {
<svg width="60" height="102" viewBox="0 0 102 60" className="marker">
<g fill="none" fillRule="evenodd">
<g transform="translate(-60, 0)" stroke="#8962B2" id="pin" viewBox="0 0 100 100">
<path d="M157.39 34.315c0 18.546-33.825 83.958-33.825 83.958S89.74 52.86 89.74 34.315C89.74 15.768 104.885.73 123.565.73c18.68 0 33.825 15.038 33.825 33.585z" strokeWidth="5.53" fill="#E6D2FC"></path>
<path d="M123.565 49.13c-8.008 0-14.496-6.498-14.496-14.52 0-8.017 6.487-14.52 14.495-14.52s14.496 6.503 14.496 14.52c0 8.022-6.487 14.52-14.495 14.52z" strokeWidth="2.765" fill="#FFF"></path>
<path
d="M157.39 34.315c0 18.546-33.825 83.958-33.825 83.958S89.74 52.86 89.74 34.315C89.74 15.768 104.885.73 123.565.73c18.68 0 33.825 15.038 33.825 33.585z"
strokeWidth="5.53" fill="#E6D2FC"></path>
<path
d="M123.565 49.13c-8.008 0-14.496-6.498-14.496-14.52 0-8.017 6.487-14.52 14.495-14.52s14.496 6.503 14.496 14.52c0 8.022-6.487 14.52-14.495 14.52z"
strokeWidth="2.765" fill="#FFF"></path>
</g>
</g>
</svg>);
Expand Down Expand Up @@ -193,8 +201,8 @@ function DatesAndGuest() {
return (
<div className="row aisdemo-filter">
<div className="col-sm-2 aisdemo-filter-title">Dates</div>
<div className="col-sm-3"><input className="date form-control" value="10/30/3015" disabled /></div>
<div className="col-sm-3"><input className="date form-control" value="10/30/3015" disabled /></div>
<div className="col-sm-3"><input className="date form-control" value="10/30/3015" disabled/></div>
<div className="col-sm-3"><input className="date form-control" value="10/30/3015" disabled/></div>
<div className="col-sm-3"></div>
</div>
);
Expand All @@ -215,7 +223,7 @@ const RoomType = connectRefinementList(({items, refine}) => {
type="checkbox"
className="ais-refinement-list--checkbox"
defaultChecked={item.isRefined ? 'checked' : ''}
/>
/>
{item.label}
<span className="ais-refinement-list--count">{item.count}</span>
</label>
Expand Down Expand Up @@ -246,7 +254,7 @@ function Price() {
}

const MyHits = connectHits(({hits}) => {
const hs = hits.map(hit => <HitComponent key={hit.objectID} hit={hit} />);
const hs = hits.map(hit => <HitComponent key={hit.objectID} hit={hit}/>);
return <div id="hits">{hs}</div>;
});

Expand All @@ -256,12 +264,12 @@ function HitComponent({hit}) {
return (
<div className="hit col-sm-3">
<div className="pictures-wrapper">
<img className="picture" src={hit.picture_url} />
<img className="profile" src={hit.user.user.thumbnail_url} />
<img className="picture" src={hit.picture_url}/>
<img className="profile" src={hit.user.user.thumbnail_url}/>
</div>
<div className="infos">
<h4 className="media-heading" dangerouslySetInnerHTML={{__html: title}}></h4>
<p dangerouslySetInnerHTML={{__html: description}}></p>
<h4 className="media-heading" dangerouslySetInnerHTML={{__html: title}}></h4>
<p dangerouslySetInnerHTML={{__html: description}}></p>
</div>
</div>
);
Expand Down Expand Up @@ -310,3 +318,5 @@ const ConnectedRange = connectRange(({min, max, currentRefinement, refine}) => {
</div>
);
});

export default withUrlSync(App);
30 changes: 30 additions & 0 deletions docgen/src/examples/urlSync.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,30 @@
import React, {Component} from 'react';
import qs from 'qs';

export const withUrlSync = App => class extends Component {
constructor() {
super();
this.state = {searchState: qs.parse(window.location.search.slice(1))};
}

onStateChange = nextState => {
const THRESHOLD = 700;
const newPush = Date.now();
this.setState({lastPush: newPush, searchState: nextState});
const search = nextState ? `?${qs.stringify({...qs.parse(window.location.search.slice(1)), ...nextState})}` : '';
if (this.state.lastPush && newPush - this.state.lastPush <= THRESHOLD) {
window.history.replaceState(null, null, search);
} else {
window.history.pushState(null, null, search);
}
};

createURL = state => `?${qs.stringify(state)}`;

render() {
return <App {...this.props}
state={this.state.searchState}
onStateChange={this.onStateChange}
createURL={this.createURL}/>;
}
};
1 change: 1 addition & 0 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -78,6 +78,7 @@
"postcss": "^5.2.5",
"postcss-scss": "^0.3.1",
"pug": "^2.0.0-beta6",
"qs": "^6.3.0",
"react": "^15.3.2",
"react-addons-test-utils": "^15.3.2",
"react-dev-utils": "^0.3.0",
Expand Down
Loading

0 comments on commit b277d31

Please sign in to comment.