diff --git a/.eslintignore b/.eslintignore new file mode 100644 index 0000000..2a73b4f --- /dev/null +++ b/.eslintignore @@ -0,0 +1,3 @@ +node_modules/ +_assets/ +/index.js diff --git a/.eslintrc b/.eslintrc index c306715..b6f4662 100644 --- a/.eslintrc +++ b/.eslintrc @@ -1,20 +1,3 @@ { - "rules": { - "no-extra-boolean-cast": [ 0 ], - "indent": [ 2, 4 ], - "quotes": [ 2, "single" ], - "linebreak-style": [ 2, "unix" ], - "semi": [ 2, "always" ], - "no-unused-vars": [ 2, { - "vars": "all", - "args": "none" - } ], - "spaced-comment": [ 2, "always" ] - }, - "env": { - "node": true, - "mocha": true, - "browser": true - }, - "extends": "eslint:recommended" -} \ No newline at end of file + "extends": "gitbook" +} diff --git a/.gitignore b/.gitignore index 87a4029..390b049 100644 --- a/.gitignore +++ b/.gitignore @@ -1,30 +1,5 @@ -# Logs -logs -*.log - -# Runtime data -pids -*.pid -*.seed - -# Directory for instrumented libs generated by jscoverage/JSCover -lib-cov - -# Coverage directory used by tools like istanbul -coverage - -# Grunt intermediate storage (http://gruntjs.com/creating-plugins#storing-task-files) -.grunt - -# Compiled binary addons (http://nodejs.org/api/addons.html) -build/Release - # Dependency directory -# Deployed apps should consider commenting this line out: -# see https://npmjs.org/doc/faq.html#Should-I-check-my-node_modules-folder-into-git node_modules -# vim swapfile -*.swp - -assets +# Plugin assets +_assets/ diff --git a/.npmignore b/.npmignore index ec955b5..6fcb8dd 100644 --- a/.npmignore +++ b/.npmignore @@ -1,2 +1,2 @@ -# Allow _assets folder -!assets +# Publish assets on NPM +!_assets/ diff --git a/_layouts/website/page.html b/_layouts/website/page.html deleted file mode 100644 index d62b780..0000000 --- a/_layouts/website/page.html +++ /dev/null @@ -1,4 +0,0 @@ -{% extends template.self %} - -{% block book_navigation %} -{% endblock %} \ No newline at end of file diff --git a/index.js b/index.js index a198a6d..0710109 100644 --- a/index.js +++ b/index.js @@ -1,108 +1,56 @@ -var _ = require('lodash'); -var Q = require('q-plus'); -var cheerio = require('cheerio'); +var _ = require('lodash'); +var Promise = require('q-plus'); var DEFAULT_LANGUAGES = require('./languages'); var configLanguages = []; -function generateMethod(book, body, examples) { - // Main container - var $ = cheerio.load('
'), - $apiMethod = $('div.api-method'), - // Method definition - $apiDefinition = $('
'), - // Method code - $apiCode = $('
'); - - // Append elements - $apiMethod.append($apiDefinition); - $apiMethod.append($apiCode); - - // Render method body - return Q() - .then(function() { - return book.renderBlock('markdown', body); - }) - .then(function(apiDefinition) { - $apiDefinition.html(apiDefinition); - - // Set method examples - return Q(examples).eachSeries(function(example) { - var $example; - - // Common text - if (example.type == 'common') { - $example = $('
'); - - } - - // Example code snippet - if (example.type == 'sample') { - $example = $('
'); - } - - return book.renderBlock('markdown', example.body) - .then(function(body) { - $example.html(body); - $apiCode.append($example); - }); - }); - }) - .then(function() { - // Return whole HTML - return $.html('div.api-method'); - }); -} - module.exports = { - book: { - assets: './assets', - js: [ - 'theme-api.js' - ], - css: [ - 'theme-api.css' - ] - }, - blocks: { method: { - blocks: ['sample', 'common'], - process: function(blk) { + blocks: [ 'sample', 'common' ], + process: function(block) { + var book = this; var examples = []; - _.each(blk.blocks, function(_blk) { + return Promise(block.blocks).eachSeries(function(_block) { var languageName; // Search if is user-defined language - if (_blk.name == 'sample') { + if (_block.name == 'sample') { // Sample blocks should have a lang argument - if (!_blk.kwargs.lang) { + if (!_block.kwargs.lang) { throw Error('sample blocks must provide a "lang" argument'); } - var language = _.find(configLanguages, { lang: _blk.kwargs.lang }); + var language = _.find(configLanguages, { lang: _block.kwargs.lang }); if (!!language) { languageName = language.name; } else { // Default to upper-cased lang - languageName = _blk.kwargs.lang.toUpperCase(); + languageName = _block.kwargs.lang.toUpperCase(); } } - examples.push({ - type: _blk.name, - body: _blk.body.trim(), - lang: _blk.kwargs.lang, - name: languageName + return book.renderBlock('markdown', _block.children.trim()) + .then(function(content) { + examples.push({ + type: _block.name, + content: content, + language: _block.kwargs.lang, + name: languageName + }); + }); + }) + .then(function() { + return book.renderBlock('markdown', block.children.trim()) + .then(function(definition) { + return { + definition: definition, + examples: examples + }; }); }); - - return { - parse: true, - body: generateMethod(this, blk.body.trim(), examples) - }; } } }, diff --git a/languages.js b/languages.js index ba5f097..1d64b4d 100644 --- a/languages.js +++ b/languages.js @@ -1027,4 +1027,4 @@ module.exports = [ 'lang': 'zep', 'name': 'Zephir' } -]; \ No newline at end of file +]; diff --git a/package.json b/package.json index b81fa05..a210247 100644 --- a/package.json +++ b/package.json @@ -3,25 +3,34 @@ "description": "Theme for using GitBook as an API documentation", "version": "1.1.2", "engines": { - "gitbook": ">=3.0.4" + "gitbook": ">=4.0.0-alpha" }, "dependencies": { - "cheerio": "0.20.0", - "gitbook-plugin-search": ">=2.0.0", + "gitbook-core": "^4.0.0", "lodash": "4.12.0", "q": "1.4.1", - "q-plus": "0.0.8" + "q-plus": "0.0.8", + "react": "^15.3.1", + "react-dom": "^15.3.1" }, "devDependencies": { - "eslint": "2.9.0", - "less": "2.6.0", + "classnames": "^2.2.5", + "eslint": "^3.7.1", + "eslint-config-gitbook": "^1.3.1", + "gitbook-plugin": "^4.0.0", + "less": "^2.7.1", "less-plugin-clean-css": "^1.5.1", "preboot": "git+https://github.com/mdo/preboot.git#4aab4edd85f076d50609cbe28e4fe66cc0771701", - "uglify-js": "2.6.1" + "react-sticky": "5.0.5" }, "scripts": { - "prepublish": "./src/build.sh" + "build-js": "gitbook-plugin build ./src/index.js ./_assets/plugin.js", + "build-css": "./src/build.sh", + "prepublish": "npm run build-js && npm run build-css" }, + "browser": "./_assets/plugin.js", + "ebook": "./_assets/plugin.js", + "title": "API Theme", "repository": { "type": "git", "url": "https://github.com/GitbookIO/theme-api.git" diff --git a/src/actions/index.js b/src/actions/index.js new file mode 100644 index 0000000..106168e --- /dev/null +++ b/src/actions/index.js @@ -0,0 +1,26 @@ +const ACTIONS_TYPES = require('./types'); + +/** + * Change language from toolbar + * @return {Action} + */ +function selectLanguage(language) { + return { + type: ACTIONS_TYPES.SELECT_LANGUAGE, + language + }; +} + +/** + * Toggle split display mode + */ +function toggleDisplayMode() { + return { + type: ACTIONS_TYPES.TOGGLE_DISPLAY_MODE + }; +} + +module.exports = { + selectLanguage, + toggleDisplayMode +}; diff --git a/src/actions/types.js b/src/actions/types.js new file mode 100644 index 0000000..a301e3f --- /dev/null +++ b/src/actions/types.js @@ -0,0 +1,4 @@ +module.exports = { + SELECT_LANGUAGE: 'theme-api/language/select', + TOGGLE_DISPLAY_MODE: 'theme-api/display/toggle' +}; diff --git a/src/build.sh b/src/build.sh index 99b3db5..6bd6995 100755 --- a/src/build.sh +++ b/src/build.sh @@ -1,13 +1,14 @@ #! /bin/bash +echo "Cleaning up folder..." # Cleanup folder -rm -rf assets +rm -rf _assets/website # Recreate folder -mkdir -p assets - -# Compile JS -uglifyjs -mc -- src/js/theme-api.js > assets/theme-api.js +mkdir -p _assets/website +echo "Compiling LESS sources..." # Compile Website CSS -lessc -clean-css src/less/website.less assets/theme-api.css \ No newline at end of file +lessc -clean-css src/less/website.less _assets/website/theme-api.css + +echo "Done :)" diff --git a/src/components/BodyWrapper.js b/src/components/BodyWrapper.js new file mode 100644 index 0000000..23acc4a --- /dev/null +++ b/src/components/BodyWrapper.js @@ -0,0 +1,19 @@ +const GitBook = require('gitbook-core'); +const { React } = GitBook; +const { StickyContainer } = require('react-sticky'); + +const BodyWrapper = React.createClass({ + propTypes: { + children: React.PropTypes.node.isRequired + }, + + render() { + return ( + + {this.props.children} + + ); + } +}); + +module.exports = BodyWrapper; diff --git a/src/components/DisplayButton.js b/src/components/DisplayButton.js new file mode 100644 index 0000000..0aa2151 --- /dev/null +++ b/src/components/DisplayButton.js @@ -0,0 +1,25 @@ +const GitBook = require('gitbook-core'); +const { React } = GitBook; + +const toggleDisplayMode = require('../actions').toggleDisplayMode; + +const DisplayButton = React.createClass({ + propTypes: { + dispatch: React.PropTypes.func.isRequired + }, + + onClick() { + const { dispatch } = this.props; + dispatch(toggleDisplayMode()); + }, + + render() { + return ( + + + + ); + } +}); + +module.exports = GitBook.connect(DisplayButton); diff --git a/src/components/LanguagesButtons.js b/src/components/LanguagesButtons.js new file mode 100644 index 0000000..2bbcc15 --- /dev/null +++ b/src/components/LanguagesButtons.js @@ -0,0 +1,64 @@ +const GitBook = require('gitbook-core'); +const { React } = GitBook; +const { List } = GitBook.Immutable; +const classNames = require('classnames'); +const selectLanguage = require('../actions').selectLanguage; + +const languageShape = React.PropTypes.shape({ + lang: React.PropTypes.string.isRequired, + name: React.PropTypes.string.isRequired, + default: React.PropTypes.bool +}); + +const LanguageButton = React.createClass({ + propTypes: { + language: languageShape.isRequired, + active: React.PropTypes.bool, + onClick: React.PropTypes.func.isRequired + }, + + render() { + const { language, active, onClick } = this.props; + + const className = classNames('ThemeApi-LanguageButton', { + 'ThemeApi-ActiveButton': active + }); + + return ( + onClick(language.lang)}> + { language.name } + + ); + } +}); + +const LanguagesButtons = React.createClass({ + propTypes: { + dispatch: React.PropTypes.func.isRequired, + languages: React.PropTypes.arrayOf(languageShape).isRequired, + selectedLanguage: React.PropTypes.string.isRequired + }, + + onButtonClick(language) { + const { dispatch } = this.props; + dispatch(selectLanguage(language)); + }, + + render() { + const { languages, selectedLanguage } = this.props; + return ( + + { languages.map((language, i) => ) } + + ); + } +}); + +function mapStateToProps({ config, themeApi }) { + return { + languages: config.getIn(['pluginsConfig', 'theme-api', 'languages'], List()).toJS(), + selectedLanguage: themeApi.get('selectedLanguage') + }; +} + +module.exports = GitBook.connect(LanguagesButtons, mapStateToProps); diff --git a/src/components/MethodBlock.js b/src/components/MethodBlock.js new file mode 100644 index 0000000..f81ac5a --- /dev/null +++ b/src/components/MethodBlock.js @@ -0,0 +1,94 @@ +const GitBook = require('gitbook-core'); +const { React } = GitBook; + +const exampleShape = React.PropTypes.shape({ + type: React.PropTypes.string.isRequired, + content: React.PropTypes.string, + language: React.PropTypes.string, + name: React.PropTypes.string +}); + +const ApiCommon = React.createClass({ + propTypes: { + content: React.PropTypes.string + }, + + render() { + const { content } = this.props; + return ( +
+ +
+ ); + } +}); + +const ApiSample = React.createClass({ + propTypes: { + example: exampleShape, + selectedLanguage: React.PropTypes.string + }, + + render() { + const { example, selectedLanguage } = this.props; + // Don't display if is not selected language + if (selectedLanguage != example.language) { + return null; + } + + return ( +
+ +
+ ); + } +}); + +const ApiExample = React.createClass({ + propTypes: { + example: exampleShape, + selectedLanguage: React.PropTypes.string + }, + + render() { + const { example } = this.props; + + if (example.type == 'common') { + return ; + } + else { + return ; + } + } +}); + +const MethodBlock = React.createClass({ + propTypes: { + definition: React.PropTypes.string, + examples: React.PropTypes.arrayOf(exampleShape), + selectedLanguage: React.PropTypes.string + }, + + render() { + const { definition, examples, selectedLanguage } = this.props; + + return ( +
+
+ +
+
+ { examples.map((example, i) => ) } +
+
+ ); + } +}); + +function mapStateToProps({ themeApi }) { + return { + selectedLanguage: themeApi.get('selectedLanguage') + }; +} + +module.exports = GitBook.connect(MethodBlock, mapStateToProps); diff --git a/src/components/PageContainer.js b/src/components/PageContainer.js new file mode 100644 index 0000000..a56efcb --- /dev/null +++ b/src/components/PageContainer.js @@ -0,0 +1,34 @@ +const GitBook = require('gitbook-core'); +const { React } = GitBook; +const classNames = require('classnames'); + +const PageContainer = React.createClass({ + propTypes: { + page: GitBook.PropTypes.Page, + split: React.PropTypes.bool + }, + + render() { + const { page, split } = this.props; + + const className = classNames({ + 'ThemeApi-TwoColumns': split + }); + + return ( +
+ + +
+ ); + } +}); + +function mapStateToProps({ themeApi, page }) { + return { + split: themeApi.get('split'), + page + }; +} + +module.exports = GitBook.connect(PageContainer, mapStateToProps); diff --git a/src/components/ToolbarWrapper.js b/src/components/ToolbarWrapper.js new file mode 100644 index 0000000..ea48bbd --- /dev/null +++ b/src/components/ToolbarWrapper.js @@ -0,0 +1,19 @@ +const GitBook = require('gitbook-core'); +const { React } = GitBook; +const { Sticky } = require('react-sticky'); + +const ToolbarWrapper = React.createClass({ + propTypes: { + children: React.PropTypes.node.isRequired + }, + + render() { + return ( + + {this.props.children} + + ); + } +}); + +module.exports = ToolbarWrapper; diff --git a/src/index.js b/src/index.js new file mode 100644 index 0000000..0eb0482 --- /dev/null +++ b/src/index.js @@ -0,0 +1,39 @@ +const GitBook = require('gitbook-core'); +const BodyWrapper = require('./components/BodyWrapper'); +const ToolbarWrapper = require('./components/ToolbarWrapper'); +const MethodBlock = require('./components/MethodBlock'); +const PageContainer = require('./components/PageContainer'); +const DisplayButton = require('./components/DisplayButton'); +const LanguagesButtons = require('./components/LanguagesButtons'); + +const actions = require('./actions'); +const reduce = require('./reducers'); + +module.exports = GitBook.createPlugin({ + activate: (dispatch, getState, { Components }) => { + dispatch(Components.registerComponent(BodyWrapper, { role: 'body:wrapper' })); + dispatch(Components.registerComponent(ToolbarWrapper, { role: 'toolbar:wrapper' })); + dispatch(Components.registerComponent(MethodBlock, { role: 'block:method' })); + dispatch(Components.registerComponent(PageContainer, { role: 'page:container' })); + dispatch(Components.registerComponent(DisplayButton, { role: 'toolbar:buttons:left' })); + dispatch(Components.registerComponent(LanguagesButtons, { role: 'toolbar:buttons:right' })); + + // Get default language in config + const configLanguages = getState().config.getIn(['pluginsConfig', 'theme-api', 'languages']); + let defaultLanguage = configLanguages.find((language) => { + return Boolean(language.get('default')); + }); + + // Or use first language in list + if (!defaultLanguage) { + defaultLanguage = configLanguages.get(0); + } + + // Set as selected language + dispatch(actions.selectLanguage(defaultLanguage.get('lang'))); + }, + reduce, + actions: { + ThemeApi: actions + } +}); diff --git a/src/js/theme-api.js b/src/js/theme-api.js deleted file mode 100644 index b670345..0000000 --- a/src/js/theme-api.js +++ /dev/null @@ -1,166 +0,0 @@ -require(['gitbook', 'jquery'], function(gitbook, $) { - var buttonsId = [], - $codes, - themeApi; - - // Default themes - var THEMES = [ - { - config: 'light', - text: 'Light', - id: 0 - }, - { - config: 'dark', - text: 'Dark', - id: 3 - } - ]; - - // Instantiate localStorage - function init(config) { - themeApi = gitbook.storage.get('themeApi', { - split: config.split, - currentLang: null - }); - } - - // Update localStorage settings - function saveSettings() { - gitbook.storage.set('themeApi', themeApi); - updateDisplay(); - } - - // Update display - function updateDisplay() { - // Update layout - $('.book').toggleClass('two-columns', themeApi.split); - - // Update code samples elements - $codes = $('.api-method-sample'); - // Display corresponding code snippets - $codes.each(function() { - // Show corresponding - var hidden = !($(this).data('lang') == themeApi.currentLang); - $(this).toggleClass('hidden', hidden); - }); - } - - // Update code tabs - function updateCodeTabs() { - // Remove languages buttons - gitbook.toolbar.removeButtons(buttonsId); - buttonsId = []; - - // Update code snippets elements - $codes = $('.api-method-sample'); - - // Recreate languages buttons - var languages = [], - hasCurrentLang = false; - - $codes.each(function() { - var isDefault = false, - codeLang = $(this).data('lang'), - codeName = $(this).data('name'), - exists, - found; - - // Check if is current language - if (codeLang == themeApi.currentLang) { - hasCurrentLang = true; - isDefault = true; - } - - // Check if already added - exists = $.grep(languages, function(language) { - return language.name == codeName; - }); - - found = !!exists.length; - - if (!found) { - // Add language - languages.push({ - name: codeName, - lang: codeLang, - default: isDefault - }); - } - }); - - // Set languages in good order - languages.reverse(); - $.each(languages, function(i, language) { - // Set first (last in array) language as active if no default - var isDefault = language.default || (!hasCurrentLang && i == (languages.length - 1)), - buttonId; - - // Create button - buttonId = gitbook.toolbar.createButton({ - text: language.name, - position: 'right', - className: 'lang-switcher' + (isDefault? ' active': ''), - onClick: function(e) { - // Update language - themeApi.currentLang = language.lang; - saveSettings(); - - // Update active button - $('.btn.lang-switcher.active').removeClass('active'); - $(e.currentTarget).addClass('active'); - } - }); - - // Add to list of buttons - buttonsId.push(buttonId); - - // Set as current language if is default - if (isDefault) { - themeApi.currentLang = language.lang; - } - }); - } - - // Initialization - gitbook.events.bind('start', function(e, config) { - var opts = config['theme-api']; - - // Create layout button in toolbar - gitbook.toolbar.createButton({ - icon: 'fa fa-columns', - label: 'Change Layout', - onClick: function() { - // Update layout - themeApi.split = !themeApi.split; - saveSettings(); - } - }); - - // Initialize themes - gitbook.fontsettings.setThemes(THEMES); - - // Set to configured theme - gitbook.fontsettings.setTheme(opts.theme); - - // Init current settings - init(opts); - }); - - // Update state - gitbook.events.on('page.change', function() { - updateCodeTabs(); - // updateComments(); - updateDisplay(); - }); - - // Comments toggled event - gitbook.events.on('comment.toggled', function(e, $from, open) { - // If triggering element is in a definition - if (!!$from.parents('.api-method-definition').length) { - // Add class to wrapper only if comments are open and in two-columns mode - var $wrapper = gitbook.state.$book.find('.page-wrapper'); - $wrapper.toggleClass('comments-open-from-definition', open && themeApi.split); - } - }); -}); diff --git a/src/less/website.less b/src/less/website.less index e24b604..347aa55 100755 --- a/src/less/website.less +++ b/src/less/website.less @@ -2,21 +2,20 @@ @import "website/mixins.less"; @import "website/variables.less"; -@import "website/api-method.less"; +@import "website/ApiMethod.less"; +@import "website/Toolbar.less"; @import "website/header.less"; -@import "website/langswitcher.less"; +@import "website/LanguageButton.less"; @import "website/search.less"; @import "website/comments.less"; @import "themes/themes.less"; -.page-inner { +.PageContainer { max-width: 100%; padding: 0; - margin-top: @header-height; } -.markdown-section { - padding: @markdown-section-padding @api-method-padding 0; +.Page { + padding-left: @api-method-padding + 10; + padding-right: @api-method-padding + 10; } - - diff --git a/src/less/website/ApiMethod.less b/src/less/website/ApiMethod.less new file mode 100644 index 0000000..bf36733 --- /dev/null +++ b/src/less/website/ApiMethod.less @@ -0,0 +1,63 @@ +.ThemeApi-ApiMethod { + margin: @api-method-padding -@api-method-padding; + + &:last-of-type { + margin-bottom: 0; + } + + .ThemeApi-ApiMethodDefinition { + padding: 0 @api-method-padding; + } + + .ThemeApi-ApiMethodCode { + padding: @api-method-padding @api-method-padding @api-method-padding/2; + background-color: @api-code-background; + border-top: @api-method-border; + border-bottom: @api-method-border; + + pre>code { + .white-space(pre-wrap); + word-wrap: break-word; + } + } + + &:after { + clear: both; + } +} + +.ThemeApi-TwoColumns { + .ThemeApi-ApiMethod { + position: relative; + width: calc(~"100% +" 2*@api-method-padding); + + &:after { + content: " "; + display: block; + visibility: hidden; + clear: both; + } + + .ThemeApi-ApiMethodDefinition { + float: left; + width: 50%; + } + + .ThemeApi-ApiMethodCode { + position: relative; + float: left; + width: 50%; + padding: @api-method-padding @api-method-padding @api-method-padding/2; + border-left: @api-method-border; + border-top: none; + border-bottom: none; + transition: opacity 300ms ease; + } + } + + .page-wrapper.comments-open-from-definition { + .ThemeApi-ApiMethodCode { + opacity: 0.1; + } + } +} diff --git a/src/less/website/LanguageButton.less b/src/less/website/LanguageButton.less new file mode 100644 index 0000000..c77cd96 --- /dev/null +++ b/src/less/website/LanguageButton.less @@ -0,0 +1,10 @@ +.ThemeApi-LanguageButton { + text-transform: none; + font-weight: 500; + border-radius: 0; + + &.ThemeApi-ActiveButton { + background-color: @language-button-active-bg-color; + color: @language-button-active-color; + } +} diff --git a/src/less/website/Toolbar.less b/src/less/website/Toolbar.less new file mode 100644 index 0000000..fc8332c --- /dev/null +++ b/src/less/website/Toolbar.less @@ -0,0 +1,4 @@ +.ThemeApi-Toolbar { + background-color: white; + z-index: 300; +} diff --git a/src/less/website/api-method.less b/src/less/website/api-method.less deleted file mode 100644 index 334d4b4..0000000 --- a/src/less/website/api-method.less +++ /dev/null @@ -1,69 +0,0 @@ -.api-method { - margin: @api-method-padding -@api-method-padding; - - &:last-of-type { - margin-bottom: 0; - } - - .api-method-definition { - padding: 0 @api-method-padding; - } - - .api-method-code { - padding: @api-method-padding @api-method-padding @api-method-padding/2; - background-color: @api-code-background; - border-top: @api-method-border; - border-bottom: @api-method-border; - - pre>code { - .white-space(pre-wrap); - word-wrap: break-word; - } - } - - &:after { - clear: both; - } -} - -.book { - &.two-columns { - .api-method { - position: relative; - width: calc(~"100% +" 2*@api-method-padding); - - &:after { - content: " "; - display: block; - visibility: hidden; - clear: both; - } - - .api-method-title { - margin-top: 0; - } - - .api-method-definition { - float: left; - width: 50%; - } - - .api-method-code { - position: relative; - float: left; - width: 50%; - padding: @api-method-padding @api-method-padding @api-method-padding/2; - border-left: @api-method-border; - border-top: none; - border-bottom: none; - transition: opacity 300ms ease; - } - } - - .page-wrapper.comments-open-from-definition { - .api-method-code { - opacity: 0.1; - } - } - } -} \ No newline at end of file diff --git a/src/less/website/langswitcher.less b/src/less/website/langswitcher.less deleted file mode 100644 index b249042..0000000 --- a/src/less/website/langswitcher.less +++ /dev/null @@ -1,11 +0,0 @@ -.book-header .btn.lang-switcher { - /*color: @button-hover-color;*/ - text-transform: none; - font-weight: 500; - border-radius: 0; - - &.active { - background-color: @lang-switcher-active-bg-color; - color: @lang-switcher-active-color; - } -} \ No newline at end of file diff --git a/src/less/website/variables.less b/src/less/website/variables.less index 0ab25d2..a5a5b04 100644 --- a/src/less/website/variables.less +++ b/src/less/website/variables.less @@ -7,9 +7,9 @@ @api-code-background: @color-gray-lightest; @api-method-border: 1px solid @api-soft-grey; -// Language switchers -@lang-switcher-active-bg-color: #03677D; -@lang-switcher-active-color: #FFF; +// Language buttons +@language-button-active-bg-color: #03677D; +@language-button-active-color: #FFF; // Page @markdown-section-padding: 20px; @@ -22,4 +22,4 @@ // Sidebar @sidebar-transition-duration: 250ms; @sidebar-width: 300px; -@sidebar-breakpoint: 600px; \ No newline at end of file +@sidebar-breakpoint: 600px; diff --git a/src/reducers/index.js b/src/reducers/index.js new file mode 100644 index 0000000..7e9aede --- /dev/null +++ b/src/reducers/index.js @@ -0,0 +1,3 @@ +const GitBook = require('gitbook-core'); + +module.exports = GitBook.createReducer('themeApi', require('./themeApi')); diff --git a/src/reducers/themeApi.js b/src/reducers/themeApi.js new file mode 100644 index 0000000..923942c --- /dev/null +++ b/src/reducers/themeApi.js @@ -0,0 +1,25 @@ +const GitBook = require('gitbook-core'); +const { Record } = GitBook.Immutable; + +const ACTIONS_TYPES = require('../actions/types'); + +const ThemeApiState = Record({ + // current displayed language + selectedLanguage: String(''), + // split display + split: Boolean(true) +}); + +module.exports = (state = ThemeApiState(), action) => { + switch (action.type) { + + case ACTIONS_TYPES.SELECT_LANGUAGE: + return state.set('selectedLanguage', action.language); + + case ACTIONS_TYPES.TOGGLE_DISPLAY_MODE: + return state.set('split', !state.get('split')); + + default: + return state; + } +};