diff --git a/src/components/Hello/Hello.example.js b/src/components/Hello/Hello.example.js
new file mode 100644
index 00000000..b109e6af
--- /dev/null
+++ b/src/components/Hello/Hello.example.js
@@ -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' },
+};
diff --git a/src/components/Hello/Hello.js b/src/components/Hello/Hello.js
new file mode 100644
index 00000000..3cb026de
--- /dev/null
+++ b/src/components/Hello/Hello.js
@@ -0,0 +1,9 @@
+import React, { PropTypes } from 'react';
+
+const Hello = ({ name }) =>
hello, {name}!
;
+
+const { string } = PropTypes;
+
+Hello.propTypes = { name: string.isRequired };
+
+export default Hello;
diff --git a/src/components/examples.js b/src/components/examples.js
new file mode 100644
index 00000000..0d0b9135
--- /dev/null
+++ b/src/components/examples.js
@@ -0,0 +1,4 @@
+/* eslint-disable import/prefer-default-export*/
+import * as Hello from './Hello/Hello.example';
+
+export { Hello };
diff --git a/src/containers/StyleguidePage/StyleguidePage.css b/src/containers/StyleguidePage/StyleguidePage.css
new file mode 100644
index 00000000..b5367cc9
--- /dev/null
+++ b/src/containers/StyleguidePage/StyleguidePage.css
@@ -0,0 +1,6 @@
+.root {
+ & ul {
+ list-style: none;
+ padding: 0;
+ }
+}
diff --git a/src/containers/StyleguidePage/StyleguidePage.js b/src/containers/StyleguidePage/StyleguidePage.js
new file mode 100644
index 00000000..131c291f
--- /dev/null
+++ b/src/containers/StyleguidePage/StyleguidePage.js
@@ -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 ? Description: {description}
: null;
+ return (
+
+
+ {componentName}/
+ {exampleName}
+
+ raw
+ {desc}
+
+
+
+
+ );
+};
+
+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) => (
+
+
+ {
+ map(exmpls, (exmpl, exampleName) => (
+
+ ))
+ }
+
+
+ );
+ return (
+
+ {map(examples, toExamples)}
+
+ );
+};
+
+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 ;
+ } else if (raw) {
+ return No example with filter {component}/{example}/raw
;
+ }
+
+ const html = size(examples) > 0
+ ?
+ : No examples with filter: {component}/{example}
;
+
+ return (
+
+ );
+};
+
+StyleguidePage.propTypes = { params: shape({ component: string, example: string }).isRequired };
+
+export default StyleguidePage;
diff --git a/src/containers/index.js b/src/containers/index.js
index 77df1a0a..c2a99d14 100644
--- a/src/containers/index.js
+++ b/src/containers/index.js
@@ -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,
};
diff --git a/src/routesConfiguration.js b/src/routesConfiguration.js
index 21e6057b..0a8ae658 100644
--- a/src/routesConfiguration.js
+++ b/src/routesConfiguration.js
@@ -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 =>