From 99295fb4a58dac1e83e0cba510350b7800e1cce4 Mon Sep 17 00:00:00 2001 From: Andrey Okonetchnikov Date: Thu, 9 Feb 2017 15:13:52 +0100 Subject: [PATCH] Feat: Add showSidebar config option (#310) * Use context instead of passing down `sidebar` prop * Better variable name: singleExample -> isolatedExample * Better prop names: sidebar -> isolatedComponent; sidebar -> hasSidebar --- docs/Configuration.md | 6 ++ loaders/styleguide-loader.js | 1 + scripts/schemas/config.js | 4 ++ src/index.js | 12 ++-- src/rsg-components/Components/Components.js | 7 +-- src/rsg-components/Examples/Examples.spec.js | 2 +- src/rsg-components/Playground/Playground.js | 6 +- .../Playground/PlaygroundRenderer.js | 6 +- .../ReactComponent/ReactComponent.js | 12 ++-- .../ReactComponent/ReactComponent.spec.js | 25 ++++++++ .../ReactComponent/ReactComponentRenderer.js | 10 ++-- .../__snapshots__/ReactComponent.spec.js.snap | 23 ++++---- src/rsg-components/Section/Section.js | 8 +-- src/rsg-components/Sections/Sections.js | 7 +-- src/rsg-components/StyleGuide/StyleGuide.js | 19 +++--- .../StyleGuide/StyleGuide.spec.js | 53 +++++++++++++++++ .../StyleGuide/StyleGuideRenderer.js | 8 +-- .../__snapshots__/StyleGuide.spec.js.snap | 59 +------------------ 18 files changed, 147 insertions(+), 121 deletions(-) diff --git a/docs/Configuration.md b/docs/Configuration.md index fbc1c5fe8..3c9eb2d00 100644 --- a/docs/Configuration.md +++ b/docs/Configuration.md @@ -272,6 +272,12 @@ Type: `Boolean`, default: `false` Show or hide example code initially. It can be toggled in the UI by clicking the show/hide code button before each example. +#### `showSidebar` + +Type: `Boolean`, default: `true` + +Toggle sidebar initially. Sidebar is being hidden when opening components or examples in the isolation mode even if this value is set to `true`. When set to `false`, sidebar will always be hidden. + #### `skipComponentsWithoutExample` Type: `Boolean`, default: `false` diff --git a/loaders/styleguide-loader.js b/loaders/styleguide-loader.js index 89881f8ff..61fdd9d91 100644 --- a/loaders/styleguide-loader.js +++ b/loaders/styleguide-loader.js @@ -17,6 +17,7 @@ const CLIENT_CONFIG_OPTIONS = [ 'title', 'highlightTheme', 'showCode', + 'showSidebar', 'previewDelay', 'theme', 'styles', diff --git a/scripts/schemas/config.js b/scripts/schemas/config.js index 8d25188fa..7eb64a3af 100644 --- a/scripts/schemas/config.js +++ b/scripts/schemas/config.js @@ -106,6 +106,10 @@ module.exports = { type: 'boolean', default: false, }, + showSidebar: { + type: 'boolean', + default: true, + }, skipComponentsWithoutExample: { type: 'boolean', default: false, diff --git a/src/index.js b/src/index.js index a4163a052..283d1f144 100644 --- a/src/index.js +++ b/src/index.js @@ -21,8 +21,8 @@ let codeKey = 0; function renderStyleguide() { const styleguide = require('!!../loaders/styleguide-loader!./index.js'); - let sidebar = true; - let singleExample = false; + let isolatedComponent = false; + let isolatedExample = false; let components = processComponents(styleguide.components); let sections = styleguide.sections; @@ -48,12 +48,12 @@ function renderStyleguide() { ...filterComponentsInSectionsByExactName(sections, targetComponentName), ]; sections = [{ components }]; - sidebar = false; + isolatedComponent = true; // if a single component is filtered and a fenced block index is specified hide the other examples if (components.length === 1 && isFinite(targetComponentIndex)) { components[0] = filterComponentExamples(components[0], targetComponentIndex); - singleExample = true; + isolatedExample = true; } } @@ -63,8 +63,8 @@ function renderStyleguide() { config={styleguide.config} components={components} sections={sections} - sidebar={sidebar} - singleExample={singleExample} + isolatedComponent={isolatedComponent} + isolatedExample={isolatedExample} />, document.getElementById('app') ); diff --git a/src/rsg-components/Components/Components.js b/src/rsg-components/Components/Components.js index b5b980c60..da322aeae 100644 --- a/src/rsg-components/Components/Components.js +++ b/src/rsg-components/Components/Components.js @@ -2,10 +2,7 @@ import React, { PropTypes } from 'react'; import ReactComponent from 'rsg-components/ReactComponent'; import ComponentsRenderer from 'rsg-components/Components/ComponentsRenderer'; -export default function Components({ - components, - sidebar, -}) { +export default function Components({ components }) { return ( { @@ -13,7 +10,6 @@ export default function Components({ )) } @@ -23,5 +19,4 @@ export default function Components({ Components.propTypes = { components: PropTypes.array.isRequired, - sidebar: PropTypes.bool, }; diff --git a/src/rsg-components/Examples/Examples.spec.js b/src/rsg-components/Examples/Examples.spec.js index 31fdaa14a..302dd7cce 100644 --- a/src/rsg-components/Examples/Examples.spec.js +++ b/src/rsg-components/Examples/Examples.spec.js @@ -23,7 +23,7 @@ it('should render examples', () => { { context: { codeKey: 1, - singleExample: false, + isolatedExample: false, }, } ); diff --git a/src/rsg-components/Playground/Playground.js b/src/rsg-components/Playground/Playground.js index a451ccf33..23a5a85f4 100644 --- a/src/rsg-components/Playground/Playground.js +++ b/src/rsg-components/Playground/Playground.js @@ -11,7 +11,7 @@ export default class Playground extends Component { }; static contextTypes = { config: PropTypes.object.isRequired, - singleExample: PropTypes.bool, + isolatedExample: PropTypes.bool, }; constructor(props, context) { @@ -79,14 +79,14 @@ export default class Playground extends Component { render() { const { code, showCode } = this.state; const { evalInContext, index, name } = this.props; - const { singleExample } = this.context; + const { isolatedExample } = this.context; return ( this.handleChange(code)} onCodeToggle={() => this.handleCodeToggle()} diff --git a/src/rsg-components/Playground/PlaygroundRenderer.js b/src/rsg-components/Playground/PlaygroundRenderer.js index 12f904b11..c1e97e8e0 100644 --- a/src/rsg-components/Playground/PlaygroundRenderer.js +++ b/src/rsg-components/Playground/PlaygroundRenderer.js @@ -68,7 +68,7 @@ export function PlaygroundRenderer({ showCode, name, index, - singleExample, + isolatedExample, evalInContext, onChange, onCodeToggle, @@ -78,7 +78,7 @@ export function PlaygroundRenderer({
{name && ( - singleExample ? ( + isolatedExample ? ( ⇽ Exit Isolation ) : ( Open isolated ⇢ @@ -112,7 +112,7 @@ PlaygroundRenderer.propTypes = { onChange: PropTypes.func.isRequired, onCodeToggle: PropTypes.func.isRequired, name: PropTypes.string, - singleExample: PropTypes.bool, + isolatedExample: PropTypes.bool, }; export default Styled(styles)(PlaygroundRenderer); diff --git a/src/rsg-components/ReactComponent/ReactComponent.js b/src/rsg-components/ReactComponent/ReactComponent.js index bc5d5d1d5..9b83938b5 100644 --- a/src/rsg-components/ReactComponent/ReactComponent.js +++ b/src/rsg-components/ReactComponent/ReactComponent.js @@ -5,10 +5,7 @@ import Methods from 'rsg-components/Methods'; import Examples from 'rsg-components/Examples'; import ReactComponentRenderer from 'rsg-components/ReactComponent/ReactComponentRenderer'; -export default function ReactComponent({ - component, - sidebar, -}) { +export default function ReactComponent({ component }, { isolatedComponent = false }) { const { name, pathLine, examples } = component; const { description, props, methods } = component.props; return ( @@ -19,12 +16,15 @@ export default function ReactComponent({ props={props && } methods={methods.length > 0 && } examples={examples && } - sidebar={sidebar} + isolated={isolatedComponent} /> ); } ReactComponent.propTypes = { component: PropTypes.object.isRequired, - sidebar: PropTypes.bool, +}; + +ReactComponent.contextTypes = { + isolatedComponent: PropTypes.bool, }; diff --git a/src/rsg-components/ReactComponent/ReactComponent.spec.js b/src/rsg-components/ReactComponent/ReactComponent.spec.js index 1bf6b4edc..bfe136b3a 100644 --- a/src/rsg-components/ReactComponent/ReactComponent.spec.js +++ b/src/rsg-components/ReactComponent/ReactComponent.spec.js @@ -119,6 +119,31 @@ it('renderer should render component', () => { expect(actual).toMatchSnapshot(); }); +test('should render component not in the isolation mode by default', () => { + const actual = render( + + ); + + expect(actual.find('a').text()).toEqual('Open isolated ⇢'); +}); + +test('should render component in isolation mode', () => { + const actual = render( + + ); + + expect(actual.find('a').text()).toEqual('← Back'); +}); + test('should render props section', () => { const actual = shallow( @@ -70,10 +70,10 @@ export function ReactComponentRenderer({
{pathLine}
- {sidebar ? ( - Open isolated ⇢ - ) : ( + {isolated ? ( ← Back + ) : ( + Open isolated ⇢ )}
@@ -105,7 +105,7 @@ ReactComponentRenderer.propTypes = { props: PropTypes.node, methods: PropTypes.node, examples: PropTypes.node, - sidebar: PropTypes.bool, + isolated: PropTypes.bool, }; export default Styled(styles)(ReactComponentRenderer); diff --git a/src/rsg-components/ReactComponent/__snapshots__/ReactComponent.spec.js.snap b/src/rsg-components/ReactComponent/__snapshots__/ReactComponent.spec.js.snap index ea9f94388..3ed8752e8 100644 --- a/src/rsg-components/ReactComponent/__snapshots__/ReactComponent.spec.js.snap +++ b/src/rsg-components/ReactComponent/__snapshots__/ReactComponent.spec.js.snap @@ -11,8 +11,8 @@ exports[`test renderer should render component 1`] = `
<_class - href="/"> - ← Back + href="#!/Foo"> + Open isolated ⇢
@@ -42,8 +42,8 @@ exports[`test should not render props / methods section if there is no content 1
<_class - href="/"> - ← Back + href="#!/Test"> + Open isolated ⇢
@@ -64,8 +64,8 @@ exports[`test should render both props and methods section 1`] = `
<_class - href="/"> - ← Back + href="#!/Test"> + Open isolated ⇢
@@ -112,6 +112,7 @@ exports[`test should render component renderer 1`] = ` } name="Foo" /> } + isolated={false} methods={false} name="Foo" pathLine="foo/bar.js" /> @@ -128,6 +129,7 @@ exports[`test should render component renderer for component with methods 1`] = examples={Array []} name="Foo" /> } + isolated={false} methods={ <_class methods={ @@ -164,6 +166,7 @@ exports[`test should render component renderer for component with props 1`] = ` examples={Array []} name="Foo" /> } + isolated={false} methods={false} name="Foo" pathLine="foo/bar.js" @@ -196,8 +199,8 @@ exports[`test should render methods section 1`] = `
<_class - href="/"> - ← Back + href="#!/Test"> + Open isolated ⇢
@@ -226,8 +229,8 @@ exports[`test should render props section 1`] = `
<_class - href="/"> - ← Back + href="#!/Test"> + Open isolated ⇢
diff --git a/src/rsg-components/Section/Section.js b/src/rsg-components/Section/Section.js index 642653923..48a9d0fa4 100644 --- a/src/rsg-components/Section/Section.js +++ b/src/rsg-components/Section/Section.js @@ -4,10 +4,7 @@ import Components from 'rsg-components/Components'; import Sections from 'rsg-components/Sections'; import SectionRenderer from 'rsg-components/Section/SectionRenderer'; -export default function Section({ - section, - sidebar, -}) { +export default function Section({ section }) { const { name, content, components, sections } = section; const contentJsx = content && ( @@ -16,13 +13,11 @@ export default function Section({ const componentsJsx = components && ( ); const sectionsJsx = sections && ( ); return ( @@ -37,5 +32,4 @@ export default function Section({ Section.propTypes = { section: PropTypes.object.isRequired, - sidebar: PropTypes.bool, }; diff --git a/src/rsg-components/Sections/Sections.js b/src/rsg-components/Sections/Sections.js index 2ba21a839..fec6a3b6d 100644 --- a/src/rsg-components/Sections/Sections.js +++ b/src/rsg-components/Sections/Sections.js @@ -2,10 +2,7 @@ import React, { PropTypes } from 'react'; import Section from 'rsg-components/Section'; import SectionsRenderer from 'rsg-components/Sections/SectionsRenderer'; -export default function Sections({ - sections, - sidebar, -}) { +export default function Sections({ sections }) { return ( { @@ -13,7 +10,6 @@ export default function Sections({
)) } @@ -23,5 +19,4 @@ export default function Sections({ Sections.propTypes = { sections: PropTypes.array.isRequired, - sidebar: PropTypes.bool, }; diff --git a/src/rsg-components/StyleGuide/StyleGuide.js b/src/rsg-components/StyleGuide/StyleGuide.js index 222bf27d2..6d7b507c7 100644 --- a/src/rsg-components/StyleGuide/StyleGuide.js +++ b/src/rsg-components/StyleGuide/StyleGuide.js @@ -11,37 +11,40 @@ export default class StyleGuide extends Component { codeKey: PropTypes.number.isRequired, config: PropTypes.object.isRequired, sections: PropTypes.array.isRequired, - sidebar: PropTypes.bool, - singleExample: PropTypes.bool, + isolatedComponent: PropTypes.bool, + isolatedExample: PropTypes.bool, }; static childContextTypes = { codeKey: PropTypes.number.isRequired, config: PropTypes.object.isRequired, - singleExample: PropTypes.bool, + isolatedComponent: PropTypes.bool, + isolatedExample: PropTypes.bool, }; static defaultProps = { - sidebar: true, + isolatedComponent: false, }; getChildContext() { return { codeKey: this.props.codeKey, config: this.props.config, - singleExample: this.props.singleExample, + isolatedComponent: this.props.isolatedComponent, + isolatedExample: this.props.isolatedExample, }; } render() { - const { config, sections, sidebar } = this.props; + const { config, sections, isolatedComponent } = this.props; + const { showSidebar = true } = config; const noComponentsFound = isEmpty(sections); return ( } - sidebar={noComponentsFound ? false : sidebar} + hasSidebar={showSidebar && !noComponentsFound && !isolatedComponent} > {noComponentsFound ? ( @@ -49,7 +52,7 @@ export default class StyleGuide extends Component { Check [the `components` and `sections` options]({DOCS_CONFIG}) in your style guide config. ) : ( - + )} ); diff --git a/src/rsg-components/StyleGuide/StyleGuide.spec.js b/src/rsg-components/StyleGuide/StyleGuide.spec.js index 3596f88de..1923d679e 100644 --- a/src/rsg-components/StyleGuide/StyleGuide.spec.js +++ b/src/rsg-components/StyleGuide/StyleGuide.spec.js @@ -50,6 +50,59 @@ it('should render error message when there is no components and sections', () => expect(actual).toMatchSnapshot(); }); +describe('sidebar rendering', () => { + it('renderer should have sidebar if showSidebar is not set', () => { + const wrapper = shallow( + + ); + + expect(wrapper.prop('hasSidebar')).toEqual(true); + }); + + it('renderer should not have sidebar if showSidebar is false', () => { + const wrapper = shallow( + + ); + + expect(wrapper.prop('hasSidebar')).toEqual(false); + }); + + it('renderer should not have sidebar in isolation mode', () => { + const wrapper = shallow( + + ); + + expect(wrapper.prop('hasSidebar')).toEqual(false); + }); + + it('renderer should not have sidebar if there are no sections', () => { + const wrapper = shallow( + + ); + expect(wrapper.prop('hasSidebar')).toEqual(false); + }); +}); + it('renderer should render logo, table of contents and passed children', () => { const actual = shallow( +
{children} @@ -77,7 +77,7 @@ export function StyleGuideRenderer({
- {sidebar && + {hasSidebar &&
{title} @@ -95,7 +95,7 @@ StyleGuideRenderer.propTypes = { homepageUrl: PropTypes.string.isRequired, children: PropTypes.node.isRequired, toc: PropTypes.node.isRequired, - sidebar: PropTypes.bool, + hasSidebar: PropTypes.bool, }; export default Styled(styles)(StyleGuideRenderer); diff --git a/src/rsg-components/StyleGuide/__snapshots__/StyleGuide.spec.js.snap b/src/rsg-components/StyleGuide/__snapshots__/StyleGuide.spec.js.snap index 91272af96..8abeb7ed1 100644 --- a/src/rsg-components/StyleGuide/__snapshots__/StyleGuide.spec.js.snap +++ b/src/rsg-components/StyleGuide/__snapshots__/StyleGuide.spec.js.snap @@ -12,65 +12,13 @@ exports[`test renderer should render logo, table of contents and passed children
-
-
- <_class> - Hello - -
- -
`; exports[`test should render components list 1`] = ` <_class + hasSidebar={true} homepageUrl="https://github.com/styleguidist/react-styleguidist" - sidebar={true} title="Hello" toc={ + } /> `; exports[`test should render error message when there is no components and sections 1`] = ` <_class + hasSidebar={false} homepageUrl="https://github.com/styleguidist/react-styleguidist" - sidebar={false} title="Hello" toc={