summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorSamy Pesse <samypesse@gmail.com>2016-09-24 23:24:47 +0200
committerSamy Pesse <samypesse@gmail.com>2016-09-24 23:24:47 +0200
commitfab88bb47e71ad47c928198ddbf7a4d0527e81bb (patch)
treed218193c775e125e0043d21ee216eed531f01b1b
parentfa7cf3a65f7a19b2870e6d92c2e110e2356189ae (diff)
downloadgitbook-fab88bb47e71ad47c928198ddbf7a4d0527e81bb.zip
gitbook-fab88bb47e71ad47c928198ddbf7a4d0527e81bb.tar.gz
gitbook-fab88bb47e71ad47c928198ddbf7a4d0527e81bb.tar.bz2
Add flex box components
-rw-r--r--docs/api/components.md11
-rw-r--r--packages/gitbook-core/package.json3
-rw-r--r--packages/gitbook-core/src/composeReducer.js16
-rw-r--r--packages/gitbook-core/src/createReducer.js2
-rw-r--r--packages/gitbook-core/src/createStore.js9
-rw-r--r--packages/gitbook-core/src/index.js5
-rw-r--r--packages/gitbook-plugin-theme-default/less/Sidebar.less3
-rw-r--r--packages/gitbook-plugin-theme-default/less/main.less4
-rw-r--r--packages/gitbook-plugin-theme-default/less/reset.less396
-rw-r--r--packages/gitbook-plugin-theme-default/less/variables.less2
-rw-r--r--packages/gitbook-plugin-theme-default/package.json14
-rw-r--r--packages/gitbook-plugin-theme-default/src/actions/sidebar.js13
-rw-r--r--packages/gitbook-plugin-theme-default/src/actions/types.js4
-rw-r--r--packages/gitbook-plugin-theme-default/src/components/Body.js24
-rw-r--r--packages/gitbook-plugin-theme-default/src/components/Page.js (renamed from packages/gitbook-plugin-theme-default/src/Page.js)0
-rw-r--r--packages/gitbook-plugin-theme-default/src/components/Sidebar.js (renamed from packages/gitbook-plugin-theme-default/src/Sidebar.js)0
-rw-r--r--packages/gitbook-plugin-theme-default/src/components/Summary.js (renamed from packages/gitbook-plugin-theme-default/src/Summary.js)0
-rw-r--r--packages/gitbook-plugin-theme-default/src/components/Toolbar.js (renamed from packages/gitbook-plugin-theme-default/src/Toolbar.js)14
-rw-r--r--packages/gitbook-plugin-theme-default/src/index.js38
-rw-r--r--packages/gitbook-plugin-theme-default/src/reducers/index.js5
-rw-r--r--packages/gitbook-plugin-theme-default/src/reducers/sidebar.js17
21 files changed, 557 insertions, 23 deletions
diff --git a/docs/api/components.md b/docs/api/components.md
index 64185a2..6f7be53 100644
--- a/docs/api/components.md
+++ b/docs/api/components.md
@@ -72,3 +72,14 @@ Same API as `InjectedComponentSet` but render the matching components in chain i
```
**Warning:** Children are discarded.
+
+#### `GitBook.FlexLayout` and `GitBook.FlexBox`
+
+A simple wrapper that provides a Flexbox layout with the given direction and style. Any additional props you set on the Flexbox are rendered.
+
+```js
+<GitBook.FlexLayout column>
+ <GitBook.FlexBox>First column</GitBook.FlexBox>
+ <GitBook.FlexBox>Second column</GitBook.FlexBox>
+</GitBook.FlexLayout>
+```
diff --git a/packages/gitbook-core/package.json b/packages/gitbook-core/package.json
index 1137d32..c00c6cc 100644
--- a/packages/gitbook-core/package.json
+++ b/packages/gitbook-core/package.json
@@ -13,7 +13,8 @@
"react-redux": "^4.4.5",
"react-safe-html": "^0.3.0",
"redux": "^3.5.2",
- "redux-thunk": "^2.1.0"
+ "redux-thunk": "^2.1.0",
+ "reflexbox": "^2.2.2"
},
"devDependencies": {
"babel-cli": "^6.14.0",
diff --git a/packages/gitbook-core/src/composeReducer.js b/packages/gitbook-core/src/composeReducer.js
new file mode 100644
index 0000000..fa2a589
--- /dev/null
+++ b/packages/gitbook-core/src/composeReducer.js
@@ -0,0 +1,16 @@
+
+/**
+ * Compose multiple reducers into one
+ * @param {Function} reducers
+ * @return {Function}
+ */
+function composeReducer(...reducers) {
+ return (state, action) => {
+ return reducers.reduce(
+ (newState, reducer) => reducer(newState, action),
+ state
+ );
+ };
+}
+
+module.exports = composeReducer;
diff --git a/packages/gitbook-core/src/createReducer.js b/packages/gitbook-core/src/createReducer.js
index 4af6373..6860277 100644
--- a/packages/gitbook-core/src/createReducer.js
+++ b/packages/gitbook-core/src/createReducer.js
@@ -7,7 +7,7 @@
* @return {Function(state, action): state}
*/
function createReducer(name, reduce) {
- return function(state, action) {
+ return (state, action) => {
const value = state[name];
state[name] = reduce(value, action);
return state;
diff --git a/packages/gitbook-core/src/createStore.js b/packages/gitbook-core/src/createStore.js
index 6f90b77..201a647 100644
--- a/packages/gitbook-core/src/createStore.js
+++ b/packages/gitbook-core/src/createStore.js
@@ -2,6 +2,7 @@ const Redux = require('redux');
const ReduxThunk = require('redux-thunk').default;
const coreReducers = require('./reducers');
+const composeReducer = require('./composeReducer');
/**
* Create a new redux store from an initial state and a list of plugins.
@@ -13,12 +14,12 @@ const coreReducers = require('./reducers');
*/
function createStore(plugins, initialState) {
const pluginReducers = plugins.map(plugin => plugin.onReduceState);
+ const reducer = composeReducer(...[coreReducers].concat(pluginReducers));
+
const store = Redux.createStore(
(state, action) => {
- return pluginReducers.reduce(
- (newState, reducer) => reducer(newState, action),
- coreReducers(state, action)
- );
+ console.log('[store]', action.type);
+ return reducer(state, action);
},
initialState,
Redux.compose(Redux.applyMiddleware(ReduxThunk))
diff --git a/packages/gitbook-core/src/index.js b/packages/gitbook-core/src/index.js
index 46892e4..0a5d8c5 100644
--- a/packages/gitbook-core/src/index.js
+++ b/packages/gitbook-core/src/index.js
@@ -1,5 +1,6 @@
const Head = require('react-helmet');
const { Provider } = require('react-redux');
+const { Flex, Box } = require('reflexbox');
const { InjectedComponent, InjectedComponentSet } = require('./components/InjectedComponent');
const { ImportLink, ImportScript, ImportCSS } = require('./components/Import');
@@ -13,6 +14,7 @@ const connect = require('./connect');
const createPlugin = require('./createPlugin');
const createReducer = require('./createReducer');
const createStore = require('./createStore');
+const composeReducer = require('./composeReducer');
const bootstrap = require('./bootstrap');
const renderWithStore = require('./renderWithStore');
@@ -24,6 +26,7 @@ module.exports = {
createPlugin,
createReducer,
createStore,
+ composeReducer,
registerComponent,
// React Components
InjectedComponent,
@@ -34,6 +37,8 @@ module.exports = {
ImportLink,
ImportScript,
ImportCSS,
+ FlexLayout: Flex,
+ FlexBox: Box,
// Utilities
Shapes
};
diff --git a/packages/gitbook-plugin-theme-default/less/Sidebar.less b/packages/gitbook-plugin-theme-default/less/Sidebar.less
new file mode 100644
index 0000000..2ef01d7
--- /dev/null
+++ b/packages/gitbook-plugin-theme-default/less/Sidebar.less
@@ -0,0 +1,3 @@
+.Sidebar {
+ width: @sidebar-width;
+}
diff --git a/packages/gitbook-plugin-theme-default/less/main.less b/packages/gitbook-plugin-theme-default/less/main.less
new file mode 100644
index 0000000..b6229c6
--- /dev/null
+++ b/packages/gitbook-plugin-theme-default/less/main.less
@@ -0,0 +1,4 @@
+@import "../node_modules/preboot/less/preboot.less";
+
+@import "reset.less";
+@import "variables.less";
diff --git a/packages/gitbook-plugin-theme-default/less/reset.less b/packages/gitbook-plugin-theme-default/less/reset.less
new file mode 100644
index 0000000..a9c6f52
--- /dev/null
+++ b/packages/gitbook-plugin-theme-default/less/reset.less
@@ -0,0 +1,396 @@
+/*! normalize.css v2.1.0 | MIT License | git.io/normalize */
+
+/* ==========================================================================
+ HTML5 display definitions
+ ========================================================================== */
+
+/**
+ * Correct `block` display not defined in IE 8/9.
+ */
+
+article,
+aside,
+details,
+figcaption,
+figure,
+footer,
+header,
+hgroup,
+main,
+nav,
+section,
+summary {
+ display: block;
+}
+
+/**
+ * Correct `inline-block` display not defined in IE 8/9.
+ */
+
+audio,
+canvas,
+video {
+ display: inline-block;
+}
+
+/**
+ * Prevent modern browsers from displaying `audio` without controls.
+ * Remove excess height in iOS 5 devices.
+ */
+
+audio:not([controls]) {
+ display: none;
+ height: 0;
+}
+
+/**
+ * Address styling not present in IE 8/9.
+ */
+
+[hidden] {
+ display: none;
+}
+
+/* ==========================================================================
+ Base
+ ========================================================================== */
+
+/**
+ * 1. Set default font family to sans-serif.
+ * 2. Prevent iOS text size adjust after orientation change, without disabling
+ * user zoom.
+ */
+
+html {
+ font-family: sans-serif; /* 1 */
+ -webkit-text-size-adjust: 100%; /* 2 */
+ -ms-text-size-adjust: 100%; /* 2 */
+}
+
+/**
+ * Remove default margin.
+ */
+
+body {
+ margin: 0;
+}
+
+/* ==========================================================================
+ Links
+ ========================================================================== */
+
+/**
+ * Address `outline` inconsistency between Chrome and other browsers.
+ */
+
+a:focus {
+ outline: thin dotted;
+}
+
+/**
+ * Improve readability when focused and also mouse hovered in all browsers.
+ */
+
+a:active,
+a:hover {
+ outline: 0;
+}
+
+/* ==========================================================================
+ Typography
+ ========================================================================== */
+
+/**
+ * Address variable `h1` font-size and margin within `section` and `article`
+ * contexts in Firefox 4+, Safari 5, and Chrome.
+ */
+
+h1 {
+ font-size: 2em;
+ margin: 0.67em 0;
+}
+
+/**
+ * Address styling not present in IE 8/9, Safari 5, and Chrome.
+ */
+
+abbr[title] {
+ border-bottom: 1px dotted;
+}
+
+/**
+ * Address style set to `bolder` in Firefox 4+, Safari 5, and Chrome.
+ */
+
+b,
+strong {
+ font-weight: bold;
+}
+
+/**
+ * Address styling not present in Safari 5 and Chrome.
+ */
+
+dfn {
+ font-style: italic;
+}
+
+/**
+ * Address differences between Firefox and other browsers.
+ */
+
+hr {
+ -moz-box-sizing: content-box;
+ box-sizing: content-box;
+ height: 0;
+}
+
+/**
+ * Address styling not present in IE 8/9.
+ */
+
+mark {
+ background: #ff0;
+ color: #000;
+}
+
+/**
+ * Correct font family set oddly in Safari 5 and Chrome.
+ */
+
+code,
+kbd,
+pre,
+samp {
+ font-family: monospace, serif;
+ font-size: 1em;
+}
+
+/**
+ * Improve readability of pre-formatted text in all browsers.
+ */
+
+pre {
+ white-space: pre-wrap;
+}
+
+/**
+ * Set consistent quote types.
+ */
+
+q {
+ quotes: "\201C" "\201D" "\2018" "\2019";
+}
+
+/**
+ * Address inconsistent and variable font size in all browsers.
+ */
+
+small {
+ font-size: 80%;
+}
+
+/**
+ * Prevent `sub` and `sup` affecting `line-height` in all browsers.
+ */
+
+sub,
+sup {
+ font-size: 75%;
+ line-height: 0;
+ position: relative;
+ vertical-align: baseline;
+}
+
+sup {
+ top: -0.5em;
+}
+
+sub {
+ bottom: -0.25em;
+}
+
+/* ==========================================================================
+ Embedded content
+ ========================================================================== */
+
+/**
+ * Remove border when inside `a` element in IE 8/9.
+ */
+
+img {
+ border: 0;
+}
+
+/**
+ * Correct overflow displayed oddly in IE 9.
+ */
+
+svg:not(:root) {
+ overflow: hidden;
+}
+
+/* ==========================================================================
+ Figures
+ ========================================================================== */
+
+/**
+ * Address margin not present in IE 8/9 and Safari 5.
+ */
+
+figure {
+ margin: 0;
+}
+
+/* ==========================================================================
+ Forms
+ ========================================================================== */
+
+/**
+ * Define consistent border, margin, and padding.
+ */
+
+fieldset {
+ border: 1px solid #c0c0c0;
+ margin: 0 2px;
+ padding: 0.35em 0.625em 0.75em;
+}
+
+/**
+ * 1. Correct `color` not being inherited in IE 8/9.
+ * 2. Remove padding so people aren't caught out if they zero out fieldsets.
+ */
+
+legend {
+ border: 0; /* 1 */
+ padding: 0; /* 2 */
+}
+
+/**
+ * 1. Correct font family not being inherited in all browsers.
+ * 2. Correct font size not being inherited in all browsers.
+ * 3. Address margins set differently in Firefox 4+, Safari 5, and Chrome.
+ */
+
+button,
+input,
+select,
+textarea {
+ font-family: inherit; /* 1 */
+ font-size: 100%; /* 2 */
+ margin: 0; /* 3 */
+}
+
+/**
+ * Address Firefox 4+ setting `line-height` on `input` using `!important` in
+ * the UA stylesheet.
+ */
+
+button,
+input {
+ line-height: normal;
+}
+
+/**
+ * Address inconsistent `text-transform` inheritance for `button` and `select`.
+ * All other form control elements do not inherit `text-transform` values.
+ * Correct `button` style inheritance in Chrome, Safari 5+, and IE 8+.
+ * Correct `select` style inheritance in Firefox 4+ and Opera.
+ */
+
+button,
+select {
+ text-transform: none;
+}
+
+/**
+ * 1. Avoid the WebKit bug in Android 4.0.* where (2) destroys native `audio`
+ * and `video` controls.
+ * 2. Correct inability to style clickable `input` types in iOS.
+ * 3. Improve usability and consistency of cursor style between image-type
+ * `input` and others.
+ */
+
+button,
+html input[type="button"], /* 1 */
+input[type="reset"],
+input[type="submit"] {
+ -webkit-appearance: button; /* 2 */
+ cursor: pointer; /* 3 */
+}
+
+/**
+ * Re-set default cursor for disabled elements.
+ */
+
+button[disabled],
+html input[disabled] {
+ cursor: default;
+}
+
+/**
+ * 1. Address box sizing set to `content-box` in IE 8/9.
+ * 2. Remove excess padding in IE 8/9.
+ */
+
+input[type="checkbox"],
+input[type="radio"] {
+ box-sizing: border-box; /* 1 */
+ padding: 0; /* 2 */
+}
+
+/**
+ * 1. Address `appearance` set to `searchfield` in Safari 5 and Chrome.
+ * 2. Address `box-sizing` set to `border-box` in Safari 5 and Chrome
+ * (include `-moz` to future-proof).
+ */
+
+input[type="search"] {
+ -webkit-appearance: textfield; /* 1 */
+ -moz-box-sizing: content-box;
+ -webkit-box-sizing: content-box; /* 2 */
+ box-sizing: content-box;
+}
+
+/**
+ * Remove inner padding and search cancel button in Safari 5 and Chrome
+ * on OS X.
+ */
+
+input[type="search"]::-webkit-search-cancel-button,
+input[type="search"]::-webkit-search-decoration {
+ -webkit-appearance: none;
+}
+
+/**
+ * Remove inner padding and border in Firefox 4+.
+ */
+
+button::-moz-focus-inner,
+input::-moz-focus-inner {
+ border: 0;
+ padding: 0;
+}
+
+/**
+ * 1. Remove default vertical scrollbar in IE 8/9.
+ * 2. Improve readability and alignment in all browsers.
+ */
+
+textarea {
+ overflow: auto; /* 1 */
+ vertical-align: top; /* 2 */
+}
+
+/* ==========================================================================
+ Tables
+ ========================================================================== */
+
+/**
+ * Remove most spacing between table cells.
+ */
+
+table {
+ border-collapse: collapse;
+ border-spacing: 0;
+}
diff --git a/packages/gitbook-plugin-theme-default/less/variables.less b/packages/gitbook-plugin-theme-default/less/variables.less
new file mode 100644
index 0000000..d169719
--- /dev/null
+++ b/packages/gitbook-plugin-theme-default/less/variables.less
@@ -0,0 +1,2 @@
+// Sidebar
+@sidebar-width: 200px;
diff --git a/packages/gitbook-plugin-theme-default/package.json b/packages/gitbook-plugin-theme-default/package.json
index 42ff1b6..04c0862 100644
--- a/packages/gitbook-plugin-theme-default/package.json
+++ b/packages/gitbook-plugin-theme-default/package.json
@@ -8,14 +8,20 @@
"gitbook": ">=3.0.0"
},
"dependencies": {
- "gitbook-core": "^0.0.0",
- "react": "^15.3.1"
+ "gitbook-core": "^0.0.0",
+ "react": "^15.3.1"
},
"devDependencies": {
- "gitbook-plugin": "*"
+ "font-awesome": "^4.6.3",
+ "gitbook-markdown-css": "^1.0.1",
+ "gitbook-plugin": "*",
+ "less": "^2.7.1",
+ "preboot": "git+https://github.com/mdo/preboot.git#4aab4edd85f076d50609cbe28e4fe66cc0771701"
},
"scripts": {
- "prepublish": "gitbook-plugin build ./src/index.js ./assets/theme.js"
+ "build-css": "lessc -clean-css ./less/main.less ./_assets/website/theme.css",
+ "build-js": "gitbook-plugin build ./src/index.js ./assets/theme.js",
+ "prepublish": "npm run build-css && npm run build-js"
},
"repository": {
"type": "git",
diff --git a/packages/gitbook-plugin-theme-default/src/actions/sidebar.js b/packages/gitbook-plugin-theme-default/src/actions/sidebar.js
new file mode 100644
index 0000000..52f8422
--- /dev/null
+++ b/packages/gitbook-plugin-theme-default/src/actions/sidebar.js
@@ -0,0 +1,13 @@
+const ActionTypes = require('./types');
+
+/**
+ * Toggle the sidebar
+ * @return {Action}
+ */
+function toggle() {
+ return { type: ActionTypes.TOGGLE_SIDEBAR };
+}
+
+module.exports = {
+ toggle
+};
diff --git a/packages/gitbook-plugin-theme-default/src/actions/types.js b/packages/gitbook-plugin-theme-default/src/actions/types.js
new file mode 100644
index 0000000..7cffba1
--- /dev/null
+++ b/packages/gitbook-plugin-theme-default/src/actions/types.js
@@ -0,0 +1,4 @@
+
+module.exports = {
+ TOGGLE_SIDEBAR: 'sidebar:toggle'
+};
diff --git a/packages/gitbook-plugin-theme-default/src/components/Body.js b/packages/gitbook-plugin-theme-default/src/components/Body.js
new file mode 100644
index 0000000..de97b5c
--- /dev/null
+++ b/packages/gitbook-plugin-theme-default/src/components/Body.js
@@ -0,0 +1,24 @@
+const React = require('react');
+const GitBook = require('gitbook-core');
+
+const Page = require('./Page');
+const Toolbar = require('./Toolbar');
+
+const Body = React.createClass({
+ propTypes: {
+ page: GitBook.Shapes.Page
+ },
+
+ render() {
+ const { page } = this.props;
+
+ return (
+ <div className="Body page-wrapper">
+ <Toolbar />
+ <Page page={page} />
+ </div>
+ );
+ }
+});
+
+module.exports = Body;
diff --git a/packages/gitbook-plugin-theme-default/src/Page.js b/packages/gitbook-plugin-theme-default/src/components/Page.js
index dda8eba..dda8eba 100644
--- a/packages/gitbook-plugin-theme-default/src/Page.js
+++ b/packages/gitbook-plugin-theme-default/src/components/Page.js
diff --git a/packages/gitbook-plugin-theme-default/src/Sidebar.js b/packages/gitbook-plugin-theme-default/src/components/Sidebar.js
index ff4fcbf..ff4fcbf 100644
--- a/packages/gitbook-plugin-theme-default/src/Sidebar.js
+++ b/packages/gitbook-plugin-theme-default/src/components/Sidebar.js
diff --git a/packages/gitbook-plugin-theme-default/src/Summary.js b/packages/gitbook-plugin-theme-default/src/components/Summary.js
index e95b4b4..e95b4b4 100644
--- a/packages/gitbook-plugin-theme-default/src/Summary.js
+++ b/packages/gitbook-plugin-theme-default/src/components/Summary.js
diff --git a/packages/gitbook-plugin-theme-default/src/Toolbar.js b/packages/gitbook-plugin-theme-default/src/components/Toolbar.js
index b3fd059..de89f97 100644
--- a/packages/gitbook-plugin-theme-default/src/Toolbar.js
+++ b/packages/gitbook-plugin-theme-default/src/components/Toolbar.js
@@ -1,10 +1,22 @@
const React = require('react');
const GitBook = require('gitbook-core');
+const sidebar = require('../actions/sidebar');
+
const Toolbar = React.createClass({
+ propTypes: {
+ dispatch: React.PropTypes.func
+ },
+
+ onToggle() {
+ const { dispatch } = this.props;
+ dispatch(sidebar.toggle());
+ },
+
render() {
return (
<div className="Toolbar book-toolbar">
+ <button onClick={this.onToggle}>Toggle</button>
<GitBook.InjectedComponentSet matching={{ role: 'toolbar:buttons:left' }} />
<GitBook.InjectedComponentSet matching={{ role: 'toolbar:buttons:right' }} />
</div>
@@ -12,4 +24,4 @@ const Toolbar = React.createClass({
}
});
-module.exports = Toolbar;
+module.exports = GitBook.connect(Toolbar);
diff --git a/packages/gitbook-plugin-theme-default/src/index.js b/packages/gitbook-plugin-theme-default/src/index.js
index 33ca405..4eed252 100644
--- a/packages/gitbook-plugin-theme-default/src/index.js
+++ b/packages/gitbook-plugin-theme-default/src/index.js
@@ -1,40 +1,54 @@
const React = require('react');
const GitBook = require('gitbook-core');
-const Sidebar = require('./Sidebar');
-const Page = require('./Page');
-const Toolbar = require('./Toolbar');
+const Sidebar = require('./components/Sidebar');
+const Body = require('./components/Body');
+
+const reduceState = require('./reducers');
let ThemeBody = React.createClass({
propTypes: {
+ // State
page: GitBook.Shapes.Page,
summary: GitBook.Shapes.Summary,
+ sidebar: React.PropTypes.object,
+ // Other props
children: React.PropTypes.node
},
render() {
- const { page, summary, children } = this.props;
+ const { page, summary, children, sidebar } = this.props;
return (
- <div className="GitBook book">
+ <GitBook.FlexLayout column className="GitBook book">
<GitBook.Head
title={page.title}
titleTemplate="%s - GitBook" />
<GitBook.ImportCSS href="gitbook/gitbook-plugin-theme-default/theme.css" />
- <Toolbar />
- <Sidebar summary={summary} />
- <Page page={page} />
+ <GitBook.FlexBox>
+ <GitBook.FlexLayout>
+ {sidebar.open ? (
+ <GitBook.FlexBox col={3}>
+ <Sidebar summary={summary} />
+ </GitBook.FlexBox>
+ ) : null}
+ <GitBook.FlexBox col={9}>
+ <Body page={page} />
+ </GitBook.FlexBox>
+ </GitBook.FlexLayout>
+ </GitBook.FlexBox>
{children}
- </div>
+ </GitBook.FlexLayout>
);
}
});
-ThemeBody = GitBook.connect(ThemeBody, ({page, summary}) => {
- return { page, summary };
+ThemeBody = GitBook.connect(ThemeBody, ({page, summary, sidebar}) => {
+ console.log('connect', sidebar.toJS())
+ return { page, summary, sidebar };
});
module.exports = GitBook.createPlugin((dispatch, state) => {
dispatch(GitBook.registerComponent(ThemeBody, { role: 'Body' }));
-});
+}, reduceState);
diff --git a/packages/gitbook-plugin-theme-default/src/reducers/index.js b/packages/gitbook-plugin-theme-default/src/reducers/index.js
new file mode 100644
index 0000000..ac53d3a
--- /dev/null
+++ b/packages/gitbook-plugin-theme-default/src/reducers/index.js
@@ -0,0 +1,5 @@
+const GitBook = require('gitbook-core');
+
+module.exports = GitBook.composeReducer(
+ GitBook.createReducer('sidebar', require('./sidebar'))
+);
diff --git a/packages/gitbook-plugin-theme-default/src/reducers/sidebar.js b/packages/gitbook-plugin-theme-default/src/reducers/sidebar.js
new file mode 100644
index 0000000..7b4eac6
--- /dev/null
+++ b/packages/gitbook-plugin-theme-default/src/reducers/sidebar.js
@@ -0,0 +1,17 @@
+const { Record } = require('immutable');
+const ActionTypes = require('../actions/types');
+
+const SidebarState = Record({
+ open: true
+});
+
+function reduceSidebar(state = SidebarState(), action) {
+ switch (action.type) {
+ case ActionTypes.TOGGLE_SIDEBAR:
+ return state.set('open', !state.get('open'));
+ default:
+ return state;
+ }
+}
+
+module.exports = reduceSidebar;