Merge pull request #18 from sharetribe/styleguide

Styleguide
This commit is contained in:
Kimmo Puputti 2017-01-25 08:39:52 +02:00 committed by GitHub
commit fb87c06b0b
7 changed files with 174 additions and 1 deletions

View file

@ -0,0 +1,13 @@
import Hello from './Hello';
export const HelloWorld = {
component: Hello,
description: 'Hello to world',
props: { name: 'world' },
};
export const HelloMars = {
component: Hello,
description: 'Hello to mars',
props: { name: 'mars' },
};

View file

@ -0,0 +1,9 @@
import React, { PropTypes } from 'react';
const Hello = ({ name }) => <p>hello, {name}!</p>;
const { string } = PropTypes;
Hello.propTypes = { name: string.isRequired };
export default Hello;

View file

@ -0,0 +1,4 @@
/* eslint-disable import/prefer-default-export*/
import * as Hello from './Hello/Hello.example';
export { Hello };

View file

@ -0,0 +1,6 @@
.root {
& ul {
list-style: none;
padding: 0;
}
}

View file

@ -0,0 +1,114 @@
import React, { PropTypes } from 'react';
import { Link } from 'react-router';
import { map, size } from 'lodash';
import * as allExamples from '../../components/examples';
import css from './StyleguidePage.css';
const ALL = '*';
const Example = props => {
const {
componentName,
exampleName,
component: ExampleComponent,
description,
props: exampleProps,
} = props;
const desc = description ? <p>Description: {description}</p> : null;
return (
<li>
<h2>
<Link to={`/styleguide/${componentName}`}>{componentName}</Link>/
<Link to={`/styleguide/${componentName}/${exampleName}`}>{exampleName}</Link>
</h2>
<span><Link to={`/styleguide/${componentName}/${exampleName}/raw`}>raw</Link></span>
{desc}
<div>
<ExampleComponent {...exampleProps} />
</div>
</li>
);
};
const { string, oneOfType, func, node, object, objectOf, shape } = PropTypes;
Example.defaultProps = { description: null, props: {} };
Example.propTypes = {
componentName: string.isRequired,
exampleName: string.isRequired,
component: oneOfType([ func, node ]).isRequired,
description: string,
props: object,
};
const Examples = props => {
const { examples } = props;
const toExamples = (exmpls, name) => (
<li key={name}>
<ul>
{
map(exmpls, (exmpl, exampleName) => (
<Example key={exampleName} componentName={name} exampleName={exampleName} {...exmpl} />
))
}
</ul>
</li>
);
return (
<ul>
{map(examples, toExamples)}
</ul>
);
};
Examples.propTypes = { examples: objectOf(objectOf(object)).isRequired };
const examplesFor = (examples, componentName, exampleName) => {
// All components, all examples
if (componentName === ALL) {
return examples;
}
// Specific component, all examples
const component = examples[componentName];
if (exampleName === ALL) {
return component ? { [componentName]: component } : {};
}
// Specific component, specific example
const example = component ? component[exampleName] : null;
return example ? { [componentName]: { [exampleName]: example } } : {};
};
const StyleguidePage = props => {
const { params } = props;
const component = params.component || ALL;
const example = params.example || ALL;
const raw = params.type === 'raw';
const examples = examplesFor(allExamples, component, example);
// Raw examples are rendered without any wrapper
if (raw && examples[component] && examples[component][example]) {
const { component: ExampleComponent, props: exampleProps } = examples[component][example];
return <ExampleComponent {...exampleProps} />;
} else if (raw) {
return <p>No example with filter {component}/{example}/raw</p>;
}
const html = size(examples) > 0
? <Examples examples={examples} />
: <p>No examples with filter: {component}/{example}</p>;
return (
<section className={css.root}>
<h1><Link to="/styleguide">Styleguide</Link></h1>
{html}
</section>
);
};
StyleguidePage.propTypes = { params: shape({ component: string, example: string }).isRequired };
export default StyleguidePage;

View file

@ -6,6 +6,7 @@ import InboxPage from './InboxPage/InboxPage';
import LandingPage from './LandingPage/LandingPage';
import ListingPage from './ListingPage/ListingPage';
import ManageListingsPage from './ManageListingsPage/ManageListingsPage';
import NotFoundPage from './NotFoundPage/NotFoundPage';
import OrderPage from './OrderPage/OrderPage';
import PasswordChangePage from './PasswordChangePage/PasswordChangePage';
import PasswordForgottenPage from './PasswordForgottenPage/PasswordForgottenPage';
@ -14,7 +15,7 @@ import ProfilePage from './ProfilePage/ProfilePage';
import SalesConversationPage from './SalesConversationPage/SalesConversationPage';
import SearchPage from './SearchPage/SearchPage';
import SecurityPage from './SecurityPage/SecurityPage';
import NotFoundPage from './NotFoundPage/NotFoundPage';
import StyleguidePage from './StyleguidePage/StyleguidePage';
import Topbar from './Topbar/Topbar';
export {
@ -35,5 +36,6 @@ export {
SalesConversationPage,
SearchPage,
SecurityPage,
StyleguidePage,
Topbar,
};

View file

@ -19,6 +19,7 @@ import {
SalesConversationPage,
SearchPage,
SecurityPage,
StyleguidePage,
} from './containers';
// This is only used for testing that redirects work correct in the
@ -196,6 +197,30 @@ const routesConfiguration = [
},
],
},
{
pattern: '/styleguide',
exactly: true,
name: 'Styleguide',
component: StyleguidePage,
},
{
pattern: '/styleguide/:component',
exactly: true,
name: 'StyleguideComponent',
component: StyleguidePage,
},
{
pattern: '/styleguide/:component/:example',
exactly: true,
name: 'StyleguideComponentExample',
component: StyleguidePage,
},
{
pattern: '/styleguide/:component/:example/:type',
exactly: true,
name: 'StyleguideComponentExampleRaw',
component: StyleguidePage,
},
];
const flattenRoutes = routesArray =>