mirror of
https://github.com/GitbookIO/gitbook.git
synced 2026-09-16 15:45:13 +00:00
Integrate search in default theme
This commit is contained in:
@@ -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>
|
||||
);
|
||||
|
||||
Reference in New Issue
Block a user