Use original docs components and styling inside gatsby

- get rid of sections concept temporarily
- markdown is already parsed to HTML by gatsby
This commit is contained in:
Michael Shilman 2017-05-02 16:29:08 +10:00
parent 1443d41314
commit 531b15aea3
17 changed files with 298 additions and 310 deletions

View File

@ -1,3 +1 @@
import { register } from './notes_addon';
register();
require('@kadira/storybook/addons');

View File

@ -1,9 +1,10 @@
import { configure } from '@kadira/storybook';
import 'bootstrap/dist/css/bootstrap.css';
import '../src/index.css';
import '../css/main.css';
function loadStories() {
require('../src/stories');
require('../stories')
}
configure(loadStories, module);

View File

@ -6,17 +6,6 @@ import Content from '../Content';
import './style.css';
class Container extends React.Component {
renderTopNav(cat) {
const { selectedCatId } = this.props;
const path = `/docs/${cat.id}`;
if (selectedCatId === cat.id) {
return <li className="selected" key={cat.id}>{cat.title}</li>;
}
return <a key={cat.id} href={path}><li>{cat.title}</li></a>;
}
render() {
const {
categories,
@ -29,18 +18,10 @@ class Container extends React.Component {
const gitHubRepoUrl = 'https://github.com/storybooks/storybooks.github.io';
const docPath = `${selectedCatId}/${selectedSectionId}/${selectedItemId}`;
const gitHubRepoDocUrl = `${gitHubRepoUrl}/tree/source/src/docs/${docPath}.js`;
const gitHubRepoDocUrl = `${gitHubRepoUrl}/tree/source/pages/docs/${docPath}/index.md`;
return (
<div id="docs-container" className="row">
<div className="row">
<div className="col-xs-12">
<ul className="top-nav">
{categories.map(this.renderTopNav.bind(this))}
</ul>
</div>
</div>
<div className="nav col-sm-3 col-md-3 hidden-xs">
<Nav
selectedCatId={selectedCatId}

View File

@ -1,6 +1,6 @@
import PropTypes from 'prop-types';
import React from 'react';
import Highlight from '../../../lib/highlight.js';
// import Highlight from '../../../lib/highlight.js';
import marked from 'marked';
import 'highlight.js/styles/github-gist.css';
import './style.css';
@ -22,11 +22,7 @@ const DocsContent = ({ title, content, editUrl }) => (
<h2 className="title">{title}</h2>
<p><a className="edit-link" href={editUrl} target="_blank">Edit this page</a></p>
<div className="markdown">
<Highlight>
{marked(content)}
</Highlight>
</div>
<div className="markdown" dangerouslySetInnerHTML={{ __html: content }} />
</div>
</div>
);

View File

@ -13,13 +13,16 @@ class Nav extends React.Component {
}
changeRoute(selectedCatId, selectedSectionId, selectedItemId) {
const url = `/docs/${selectedCatId}/${selectedSectionId}/${selectedItemId}`;
const url = `/docs/${selectedCatId}/${selectedSectionId}/${selectedItemId}/`;
browserHistory.push(url);
}
handleHeadingChange(evt) {
const { selectedCatId } = this.props;
this.changeRoute(selectedCatId, evt.target.value, '');
const { selectedCatId, sections } = this.props;
const selectedSectionId = evt.target.value
const section = sections.find(section => section.id === selectedSectionId)
const itemId = section.items[0].id
this.changeRoute(selectedCatId, selectedSectionId, itemId);
}
handleNavChange(evt) {

View File

@ -9,7 +9,7 @@ class Nav extends React.Component {
? 'selected'
: '';
const url = `/docs/${selectedCatId}/${section.id}/${item.id}`;
const url = `/docs/${selectedCatId}/${section.id}/${item.id}/`;
return (
<li key={item.id}>

View File

@ -1,9 +1,9 @@
import PropTypes from 'prop-types';
import React from 'react';
import Helmet from 'react-helmet';
import Header from '../Homepage/Header';
import Header from '../Header';
import Container from './Container';
import Footer from '../Homepage/Footer';
import Footer from '../Footer';
import './style.css';
class Docs extends React.Component {

View File

@ -1,168 +1,54 @@
import React from 'react';
import PropTypes from 'prop-types';
import { Link } from 'react-router'
import { Container, Grid, Span } from 'react-responsive-grid'
import { prefixLink } from 'gatsby-helpers'
import includes from 'underscore.string/include'
import { rhythm, adjustFontSizeTo } from 'utils/typography'
import { colors, activeColors } from 'utils/colors'
import { config } from 'config'
import storybookLogo from '../../design/homepage/storybook-logo.png';
import React from 'react';
import './style.css';
const Header = ({ location }) => {
const homeActive = location.pathname === prefixLink('/')
const docsActive = includes(location.pathname, '/docs/')
const examplesActive = includes(location.pathname, '/examples/')
import storybookLogo from '../../design/homepage/storybook-logo.png';
return (
<div
style={{
background: colors.bg,
color: colors.fg,
marginBottom: rhythm(1.5),
}}
>
<Container
style={{
maxWidth: 960,
paddingLeft: rhythm(3/4),
}}
>
<Grid
columns={12}
style={{
padding: `${rhythm(3/4)} 0`,
}}
>
<Span
columns={4}
style={{
height: 24, // Ugly hack. How better to constrain height of div?
}}
>
{
homeActive
? null
: (
<Link
to={prefixLink('/')}
style={{
textDecoration: 'none',
color: colors.fg,
fontSize: adjustFontSizeTo('25.5px').fontSize,
}}
>
<img className="sb-title" src={storybookLogo} alt="Storybook Logo" />
</Link>
)
}
</Span>
<Span columns={8} last>
<a
style={{
float: 'right',
color: colors.fg,
textDecoration: 'none',
marginLeft: rhythm(1/2),
}}
href="https://github.com/storybooks/storybook"
>
Github
const sections = [
{ id: 'home', caption: 'Home', href: '/' },
{ id: 'docs', caption: 'Docs', href: '/docs/react-storybook/basics/introduction/' },
];
class Header extends React.Component {
renderSections() {
return sections.map(section => {
const { currentSection } = this.props;
const className = currentSection === section.id ? 'selected' : '';
return (
<a className={className} key={section.href} href={section.href}>
{section.caption}
</a>
);
});
}
render() {
const { currentSection } = this.props;
let titleClassname = 'pull-left';
if (currentSection === 'home') {
titleClassname += ' hide';
}
return (
<div id="header" className="row">
<div className="col-xs-12">
<div id="header-title" className={titleClassname}>
<a href="/">
<img className="sb-title" src={storybookLogo} alt="Storybook Logo" />
</a>
<Link
to={prefixLink('/examples/')}
style={{
background: examplesActive ? activeColors.bg : colors.bg,
color: examplesActive ? activeColors.fg : colors.fg,
float: 'right',
textDecoration: 'none',
paddingLeft: rhythm(1/2),
paddingRight: rhythm(1/2),
paddingBottom: rhythm(3/4),
marginBottom: rhythm(-1),
paddingTop: rhythm(1),
marginTop: rhythm(-1),
}}
>
Examples
</Link>
<Link
to={prefixLink('/docs/react-storybook/basics/introduction/')}
style={{
background: docsActive ? activeColors.bg : colors.bg,
color: docsActive ? activeColors.fg : colors.fg,
float: 'right',
textDecoration: 'none',
paddingLeft: rhythm(1/2),
paddingRight: rhythm(1/2),
paddingBottom: rhythm(3/4),
marginBottom: rhythm(-1),
paddingTop: rhythm(1),
marginTop: rhythm(-1),
}}
>
Docs
</Link>
</Span>
</Grid>
</Container>
</div>
)
</div>
<div id="header-links" className="pull-right">
{this.renderSections()}
</div>
</div>
</div>
);
}
}
Header.propTypes = {
location: PropTypes.object,
}
currentSection: PropTypes.string,
};
export default Header
// const sections = [
// { id: 'home', caption: 'Home', href: '/' },
// { id: 'docs', caption: 'Docs', href: '/docs' },
// ];
//
// class Header extends React.Component {
// renderSections() {
// return sections.map(section => {
// const { currentSection } = this.props;
// const className = currentSection === section.id ? 'selected' : '';
//
// return (
// <a className={className} key={section.href} href={section.href}>
// {section.caption}
// </a>
// );
// });
// }
//
// render() {
// const { currentSection } = this.props;
// let titleClassname = 'pull-left';
// if (currentSection === 'home') {
// titleClassname += ' hide';
// }
//
// return (
// <div id="header" className="row">
// <div className="col-xs-12">
// <div id="header-title" className={titleClassname}>
// <a href="/">
// </a>
// </div>
// <div id="header-links" className="pull-right">
// {this.renderSections()}
// </div>
// </div>
// </div>
// );
// }
// }
//
// Header.propTypes = {
// currentSection: PropTypes.string,
// };
//
// export default Header;
export default Header;

View File

@ -1,7 +1,7 @@
import PropTypes from 'prop-types';
import React from 'react';
import Helmet from 'react-helmet';
import './style.css';
import Header from '../Header';
import Heading from './Heading';
import Demo from './Demo';
@ -10,8 +10,6 @@ import MainLinks from './MainLinks';
import Featured from './Featured';
import Footer from '../Footer';
import './style.css';
const featuredStorybooks = [
{
owner: 'https://avatars0.githubusercontent.com/u/698437?v=3&s=200',
@ -44,11 +42,13 @@ const featuredStorybooks = [
const Homepage = () => (
<div className="container">
<Helmet title="Storybook - UI dev environment you'll love to use" />
<Header currentSection="home" />
<Heading />
<Demo />
<Platforms />
<MainLinks />
<Featured featuredStorybooks={featuredStorybooks} />
<Footer />
</div>
);

View File

@ -11,7 +11,7 @@ basics = [
"/docs/react-storybook/basics/exporting-storybook/",
"/docs/react-storybook/basics/faq/",
]
configuration = [
configurations = [
"/docs/react-storybook/configurations/default-config/",
"/docs/react-storybook/configurations/custom-webpack-config/",
"/docs/react-storybook/configurations/custom-babel-config/",

View File

@ -3,7 +3,6 @@ import PropTypes from 'prop-types'
import DocumentTitle from 'react-document-title'
import { prefixLink } from 'gatsby-helpers'
import { TypographyStyle, GoogleFont } from 'react-typography'
import typography from './utils/typography'
import { colors } from 'utils/colors'
@ -28,8 +27,6 @@ class HTML extends Component {
content="width=device-width, initial-scale=1.0"
/>
<title>{title}</title>
<TypographyStyle typography={typography} />
<GoogleFont typography={typography} />
{css}
</head>
<body>

View File

@ -4,10 +4,12 @@
"description": "storybooks.js.org documentation",
"version": "1.0.0",
"dependencies": {
"bootstrap": "^3.3.7",
"chroma-js": "^0.7.2",
"color-pairs-picker": "^1.3.5",
"gatsby": "^0.12.45",
"lodash": "^4.17.2",
"marked": "^0.3.6",
"react-document-title": "^2.0.3",
"react-helmet": "^5.0.3",
"react-motion": "^0.1.0",
@ -18,6 +20,7 @@
"underscore.string": "^3.2.2"
},
"devDependencies": {
"@kadira/storybook": "^2.35.3",
"gh-pages": "^0.12.0"
},
"keywords": [
@ -27,9 +30,11 @@
"license": "MIT",
"main": "n/a",
"scripts": {
"test": "echo \"Error: no test specified\" && exit 1",
"develop": "gatsby develop",
"build-storybook": "build-storybook",
"build": "gatsby build",
"deploy": "gh-pages -r git@github.com:storybooks/storybooks.github.io.git -d public -o origin -b master"
"deploy": "gh-pages -r git@github.com:storybooks/storybooks.github.io.git -d public -o origin -b master",
"develop": "gatsby develop",
"storybook": "start-storybook -p 9009",
"test": "echo \"Error: no test specified\" && exit 1"
}
}

View File

@ -5,12 +5,11 @@ import { colors, activeColors } from 'utils/colors'
import { rhythm, adjustFontSizeTo } from 'utils/typography'
import { config } from 'config'
import Header from 'components/Header'
import Footer from 'components/Footer'
// Import styles.
import 'css/main.css'
import 'css/github.css'
import 'bootstrap/dist/css/bootstrap.css'
const PageTemplate = ({ children, location }) => (
<div>
@ -21,7 +20,6 @@ const PageTemplate = ({ children, location }) => (
</svg>
</a>
<Header location={location} />
<Container
style={{
maxWidth: 960,
@ -31,7 +29,6 @@ const PageTemplate = ({ children, location }) => (
>
{children}
</Container>
<Footer />
</div>
)

View File

@ -1,114 +1,80 @@
import React, { Component } from 'react'
import React from 'react';
import PropTypes from 'prop-types'
import { Link } from 'react-router'
import Header from 'components/Header'
import Breakpoint from 'components/Breakpoint'
import find from 'lodash/find'
import { flatten, values } from 'lodash'
import { prefixLink } from 'gatsby-helpers'
import capitalize from 'lodash/capitalize'
import Docs from 'components/Docs';
import { config } from 'config'
import typography from 'utils/typography'
const { rhythm } = typography
const categories = [{
id: 'react-storybook',
title: 'React Storybook',
}]
class DocPage extends Component {
handleTopicChange (e) {
return this.context.router.push(e.target.value)
}
const getSections = (catId, config, pages) => {
// FIXME: use catId
const sections = Object.keys(config.docSections)
return sections.map(key => ({
id: key,
heading: capitalize(key),
items: config.docSections[key].map((path) => {
const page = pages.find(p => p.path === path)
return page.data
})
}))
}
render () {
const { route, location } = this.props
const childPages = flatten(values(config.docSections)).map((p) => {
const page = find(route.pages, (_p) => _p.path === p)
return {
title: page.data.title,
path: page.path,
}
})
const docOptions = childPages.map((child) =>
<option
key={prefixLink(child.path)}
value={prefixLink(child.path)}
>
{child.title}
</option>
)
const docPages = childPages.map((child) => {
const isActive = prefixLink(child.path) === location.pathname
return (
<li
key={child.path}
style={{
marginBottom: rhythm(1/2),
}}
>
<Link
to={prefixLink(child.path)}
style={{
textDecoration: 'none',
}}
>
{isActive ? <strong>{child.title}</strong> : child.title}
</Link>
</li>
)
})
return (
<div>
<Breakpoint
mobile
>
<div
style={{
overflowY: 'auto',
paddingRight: `calc(${rhythm(1/2)} - 1px)`,
position: 'absolute',
width: `calc(${rhythm(8)} - 1px)`,
borderRight: '1px solid lightgrey',
}}
>
<ul
style={{
listStyle: 'none',
marginLeft: 0,
marginTop: rhythm(1/2),
}}
>
{docPages}
</ul>
</div>
<div
style={{
padding: `0 ${rhythm(1)}`,
paddingLeft: `calc(${rhythm(8)} + ${rhythm(1)})`,
}}
>
{this.props.children}
</div>
</Breakpoint>
<Breakpoint>
<strong>Topics:</strong>
{' '}
<select
defaultValue={this.props.location.pathname}
onChange={this.handleTopicChange}
>
{docOptions}
</select>
<br />
<br />
{this.props.children}
</Breakpoint>
</div>
)
const getSelectedItem = (children, sectionId) => {
const { data } = children.props.route.page
return {
id: data.id,
section: sectionId,
title: data.title,
content: data.body
}
}
DocPage.propTypes = {
const getCategories = () => {
const sections = Object.keys(config.docSections)
return sections.map(key => ({
id: key,
title: key.toUpperCase(),
}))
}
const parsePath = (path) => {
const comps = path.split('/')
const [empty, itemId, sectionId, catId, ...rest] = comps.reverse()
return { catId, sectionId, itemId }
}
class DocsContainer extends React.Component {
render() {
const { pages, path } = this.props.route
const { children } = this.props
const { catId, sectionId, itemId } = parsePath(children.props.route.path)
const props = {
categories,
selectedCatId: catId,
sections: getSections(catId, config, pages),
selectedItem: getSelectedItem(children, sectionId),
selectedSectionId: sectionId,
selectedItemId: itemId,
}
console.log('props', props)
return <Docs {...props} />
}
}
DocsContainer.propTypes = {
location: PropTypes.object,
route: PropTypes.object,
}
DocPage.contextTypes = {
DocsContainer.contextTypes = {
router: PropTypes.object.isRequired,
}
export default DocPage
export default DocsContainer;

90
stories/data.js Normal file
View File

@ -0,0 +1,90 @@
import marked from 'marked'
export const docsData = {
categories: [
{
id: 'cat-1',
title: 'CAT 1',
},
{
id: 'cat-2',
title: 'CAT 2',
},
],
sections: [
{
id: 'basics',
heading: 'Basics',
items: [
{ id: 'getting-started', title: 'Getting Started' },
{ id: 'writing-stories', title: 'Writing Stories' },
{ id: 'build-as-a-static-app', title: 'Build as a Static App' },
],
},
{
id: 'configurations',
heading: 'Configuations',
items: [
{ id: 'default-config', title: 'Default Config' },
{ id: 'webpack', title: 'Webpack' },
{ id: 'babel', title: 'Babel' },
],
},
],
selectedItem: {
id: 'writing-stories',
section: 'basics',
title: 'Writing Stories',
content: marked(`
You need to write stories to show your components inside React Storybook.<br/>
We've a set of APIs allows you to write stories and do more with them.
When you are writing stories, you can follow these guidelines<br/>
to write great stories.
* Write UI components by passing data via props.
* In this way, you can isolate UI components easilly.
* Do not write app-specific code inside your UI components.
~~~js
import { linkTo } from @kadira/Storybook
storiesOf('Toggle', module)
.add('on', () => {
return <Toggle value={true} onChange={linkTo('Toggle', 'off')} />
})
.add('off', () => {
return <Toggle value={false} onChange={linkTo('Toggle', 'on')} />
});
~~~
`),
},
featuredStorybooks: [
{
owner: 'https://avatars0.githubusercontent.com/u/698437?v=3&s=200',
storybook: {
name: 'React Dates',
link: 'http://airbnb.io/react-dates/',
},
source: 'https://github.com/airbnb/react-dates',
},
{
owner: 'https://avatars3.githubusercontent.com/u/239676?v=3&s=460',
storybook: {
name: 'React Native Web',
link: 'https://necolas.github.io/react-native-web/storybook',
},
source: 'https://github.com/necolas/react-native-web',
},
{
owner: 'https://avatars1.githubusercontent.com/u/15616844?v=3&s=200',
storybook: {
name: 'React Button',
link: 'http://kadira-samples.github.io/react-button/',
},
source: 'https://github.com/kadira-samples/react-button',
},
],
};

View File

@ -0,0 +1,52 @@
import React from 'react';
import Homepage from '../components/Homepage';
import Header from '../components/Header';
import Heading from '../components/Homepage/Heading';
import Demo from '../components/Homepage/Demo';
import Platforms from '../components/Homepage/Platforms';
import MainLinks from '../components/Homepage/MainLinks';
import Featured from '../components/Homepage/Featured';
import Footer from '../components/Footer';
import Docs from '../components/Docs';
import DocsContainer from '../components/Docs/Container';
import DocsContent from '../components/Docs/Content';
import DocsNav from '../components/Docs/Nav';
import { docsData } from './data';
export default {
'Homepage.page': <Homepage featuredStorybooks={docsData.featuredStorybooks} />,
'Homepage.header': <Header />,
'Homepage.heading': <Heading />,
'Homepage.demo': <Demo />,
'Homepage.built-for': <Platforms />,
'Homepage.main-links': <MainLinks />,
'Homepage.featured-storybooks': <Featured featuredStorybooks={docsData.featuredStorybooks} />,
'Homepage.footer': <Footer />,
'Docs.page': (
<Docs
sections={docsData.sections}
selectedItem={docsData.selectedItem}
categories={docsData.categories}
selectedCatId={'cat-2'}
/>
),
'Docs.docs-container': (
<DocsContainer
sections={docsData.sections}
selectedItem={docsData.selectedItem}
categories={docsData.categories}
selectedCatId={'cat-2'}
/>
),
'Docs.docs-content': (
<DocsContent title={docsData.selectedItem.title} content={docsData.selectedItem.content} />
),
'Docs.docs-nav': (
<DocsNav
sections={docsData.sections}
selectedSection={docsData.selectedItem.sectionId}
selectedItem={docsData.selectedItem.id}
/>
),
};

16
stories/index.js Normal file
View File

@ -0,0 +1,16 @@
import React from 'react';
import { storiesOf } from '@kadira/storybook';
import implementations from './implementations';
const storyGroups = {};
for (const key in implementations) {
const [groupName, itemName] = key.split('.');
const implementation = implementations[key];
if (!storyGroups[groupName]) {
storyGroups[groupName] = storiesOf(groupName, module);
}
storyGroups[groupName].add(itemName, () => implementation);
}