Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

docs(examples): add url sync #1542

Merged
merged 1 commit into from
Nov 14, 2016
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
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