diff options
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; |