Integrate search in default theme

This commit is contained in:
Samy Pesse
2016-09-29 17:20:29 +02:00
parent 7f28379154
commit 6015defe11
9 changed files with 71 additions and 46 deletions
@@ -26,8 +26,8 @@ function createContext(plugins, initialState) {
// Get actions from all plugins
const actions = plugins.reduce((accu, plugin) => {
return { ...accu, ...plugin.actions };
});
return Object.assign(accu, plugin.actions);
}, {});
const store = Redux.createStore(
(state, action) => {
@@ -8,8 +8,12 @@ const TYPES = require('./types');
* @return {Action}
*/
function query(q) {
if (!q) {
return clear();
}
return (dispatch, getState) => {
const handlers = getState().search;
const { handlers } = getState().search;
dispatch({ type: TYPES.UPDATE_QUERY, query: q });
@@ -23,6 +27,14 @@ function query(q) {
};
}
/**
* Clear the whole search
* @return {Action}
*/
function clear() {
return { type: TYPES.CLEAR };
}
/**
* Register a search handler
* @param {String} name
@@ -43,6 +55,7 @@ function unregisterHandler(name) {
}
module.exports = {
clear,
query,
registerHandler,
unregisterHandler
@@ -1,5 +1,6 @@
module.exports = {
CLEAR: 'search/clear',
REGISTER_HANDLER: 'search/register_handler',
UNREGISTER_HANDLER: 'search/unregister_handler',
UPDATE_QUERY: 'search/update_query',
@@ -3,45 +3,33 @@ const { React } = GitBook;
const search = require('../actions/search');
const DEBOUNCE_MS = 600;
const SearchInput = React.createClass({
propTypes: {
query: React.PropTypes.string,
dispatch: React.PropTypes.func
},
onUpdateQuery(q) {
onChange(event) {
const { dispatch } = this.props;
dispatch(search.query(q));
},
onKeyDown(event) {
const { value } = event.currentTarget;
if (this.debouncedSearch) {
clearTimeout(this.debouncedSearch);
}
this.debouncedSearch = setTimeout(() => {
this.debouncedSearch = null;
this.onUpdateQuery(value);
}, DEBOUNCE_MS);
},
componentWillUnmount() {
if (this.debouncedSearch) {
clearTimeout(this.debouncedSearch);
}
dispatch(search.query(value));
},
render() {
const { query } = this.props;
return (
<div className="Search/Input">
<input type="text" placeholder="" onKeyDown={this.onKeyDown} />
<input type="text" value={query} onChange={this.onChange} />
</div>
);
}
});
module.exports = GitBook.connect(SearchInput);
const mapStateToProps = state => {
const { query } = state.search;
return { query };
};
module.exports = GitBook.connect(SearchInput, mapStateToProps);
@@ -20,26 +20,34 @@ const Result = React.createClass({
const SearchResults = React.createClass({
propTypes: {
results: GitBook.Shapes.list
query: React.PropTypes.string,
results: GitBook.Shapes.list,
children: React.PropTypes.node
},
render() {
const { results } = this.props;
const { query, results, children } = this.props;
if (!query) {
return React.Children.only(children);
}
return (
<div className="Search/Results">
{results.map((result, i) => {
return <Result key={i} result={result} />;
})}
<div className="Search/ResultsContainer">
<h1>Results for "{query}"</h1>
<div className="Search/Results">
{results.map((result, i) => {
return <Result key={i} result={result} />;
})}
</div>
</div>
);
}
});
function mapStateToProps(state) {
return {
results: state.search.results
};
}
const mapStateToProps = (state) => {
const { results, query } = state.search;
return { results, query };
};
module.exports = GitBook.connect(SearchResults, mapStateToProps);
@@ -0,0 +1,10 @@
const GitBook = require('gitbook-core');
const { Record } = GitBook.Immutable;
const Result = Record({
url: String(''),
title: String(''),
body: String('')
});
module.exports = Result;
@@ -3,12 +3,6 @@ const { Record, List, OrderedMap } = GitBook.Immutable;
const TYPES = require('../actions/types');
const Result = Record({
url: String(''),
title: String(''),
body: String('')
});
const SearchState = Record({
// Current query
query: String(''),
@@ -21,6 +15,14 @@ const SearchState = Record({
module.exports = (state = SearchState(), action) => {
switch (action.type) {
case TYPES.CLEAR:
return SearchState();
case TYPES.UPDATE_QUERY:
return state.merge({
query: action.query
});
case TYPES.REGISTER_HANDLER:
return state.merge({
handlers: state.handlers.set(action.name, action.handler)
@@ -11,8 +11,10 @@ const Page = React.createClass({
return (
<div className="Page page-wrapper">
<GitBook.InjectedComponent matching={{ role: 'page:container' }} props={this.props}>
<GitBook.HTMLContent html={page.content} />
<GitBook.InjectedComponent matching={{ role: 'search:results' }} props={this.props}>
<GitBook.InjectedComponent matching={{ role: 'page:container' }} props={this.props}>
<GitBook.HTMLContent html={page.content} />
</GitBook.InjectedComponent>
</GitBook.InjectedComponent>
</div>
);
@@ -13,6 +13,7 @@ const Sidebar = React.createClass({
return (
<div className="Sidebar book-summary">
<GitBook.InjectedComponent matching={{ role: 'search:input' }} />
<Summary summary={summary} />
</div>
);