diff --git a/packages/patternfly-4/react-core/src/components/Button/examples/LinkButton.js b/packages/patternfly-4/react-core/src/components/Button/examples/LinkButton.js
index 76ed1c0e559..3139d2b7f1b 100644
--- a/packages/patternfly-4/react-core/src/components/Button/examples/LinkButton.js
+++ b/packages/patternfly-4/react-core/src/components/Button/examples/LinkButton.js
@@ -2,7 +2,7 @@ import React from 'react';
import { Button } from '@patternfly/react-core';
import getContainerProps from './common/getContainerProps';
-class LinkButtons extends React.Component {
+class LinkButton extends React.Component {
static title = 'Links';
static description = `Links with button styling. Semantic buttons and links are important for usability as well as accessibility. Using an "a" instead of a "button" element to perform user initiated actions should be avoided, unless absolutely necessary.`;
static getContainerProps = getContainerProps;
@@ -21,4 +21,4 @@ class LinkButtons extends React.Component {
}
}
-export default LinkButtons;
+export default LinkButton;
diff --git a/packages/patternfly-4/react-core/src/components/Dropdown/examples/DirectionUpDropdown.js b/packages/patternfly-4/react-core/src/components/Dropdown/examples/DirectionUpDropdown.js
index 17b8e0fa9ae..c733b6f67f3 100644
--- a/packages/patternfly-4/react-core/src/components/Dropdown/examples/DirectionUpDropdown.js
+++ b/packages/patternfly-4/react-core/src/components/Dropdown/examples/DirectionUpDropdown.js
@@ -1,7 +1,7 @@
import React, { Component } from 'react';
import { Dropdown, DropdownToggle, DropdownItem, DropdownSeparator, DropdownDirection } from '@patternfly/react-core';
-export default class ExampleDropdown extends Component {
+export default class DirectionUpDropdown extends Component {
static title = 'Dropdown - direction up';
constructor(props) {
@@ -13,14 +13,12 @@ export default class ExampleDropdown extends Component {
onToggle = isOpen => {
this.setState({
- ...this.state,
isOpen
});
};
onSelect = event => {
this.setState({
- ...this.state,
isOpen: !this.state.isOpen
});
};
diff --git a/packages/patternfly-4/react-core/src/components/Dropdown/examples/KebabDropdown.js b/packages/patternfly-4/react-core/src/components/Dropdown/examples/KebabDropdown.js
index d370e93def2..cd426eb235d 100644
--- a/packages/patternfly-4/react-core/src/components/Dropdown/examples/KebabDropdown.js
+++ b/packages/patternfly-4/react-core/src/components/Dropdown/examples/KebabDropdown.js
@@ -1,7 +1,7 @@
import React, { Component } from 'react';
import { Dropdown, KebabToggle, DropdownItem, DropdownSeparator } from '@patternfly/react-core';
-export default class ExampleDropdown extends Component {
+export default class KebabDropdown extends Component {
static title = 'Kebab';
constructor(props) {
@@ -13,14 +13,12 @@ export default class ExampleDropdown extends Component {
onToggle = isOpen => {
this.setState({
- ...this.state,
isOpen
});
};
onSelect = event => {
this.setState({
- ...this.state,
isOpen: !this.state.isOpen
});
};
diff --git a/packages/patternfly-4/react-core/src/components/Dropdown/examples/PositionRightDropdown.js b/packages/patternfly-4/react-core/src/components/Dropdown/examples/PositionRightDropdown.js
index ed3c251d204..6c17c68269b 100644
--- a/packages/patternfly-4/react-core/src/components/Dropdown/examples/PositionRightDropdown.js
+++ b/packages/patternfly-4/react-core/src/components/Dropdown/examples/PositionRightDropdown.js
@@ -1,7 +1,7 @@
import React, { Component } from 'react';
import { Dropdown, DropdownToggle, DropdownItem, DropdownSeparator, DropdownPosition } from '@patternfly/react-core';
-export default class ExampleDropdown extends Component {
+export default class PositionRightDropdown extends Component {
static title = 'Dropdown - position right';
constructor(props) {
@@ -13,14 +13,12 @@ export default class ExampleDropdown extends Component {
onToggle = isOpen => {
this.setState({
- ...this.state,
isOpen
});
};
onSelect = event => {
this.setState({
- ...this.state,
isOpen: !this.state.isOpen
});
};
diff --git a/packages/patternfly-4/react-core/src/components/Dropdown/examples/SimpleDropdown.js b/packages/patternfly-4/react-core/src/components/Dropdown/examples/SimpleDropdown.js
index 58e2cc0613a..883c4ce504a 100644
--- a/packages/patternfly-4/react-core/src/components/Dropdown/examples/SimpleDropdown.js
+++ b/packages/patternfly-4/react-core/src/components/Dropdown/examples/SimpleDropdown.js
@@ -1,7 +1,7 @@
import React, { Component } from 'react';
import { Dropdown, DropdownToggle, DropdownItem, DropdownSeparator } from '@patternfly/react-core';
-export default class ExampleDropdown extends Component {
+export default class SimpleDropdown extends Component {
static title = 'Simple dropdown';
constructor(props) {
@@ -13,14 +13,12 @@ export default class ExampleDropdown extends Component {
onToggle = isOpen => {
this.setState({
- ...this.state,
isOpen
});
};
onSelect = event => {
this.setState({
- ...this.state,
isOpen: !this.state.isOpen
});
};
diff --git a/packages/patternfly-4/react-docs/.env.development b/packages/patternfly-4/react-docs/.env.development
new file mode 100644
index 00000000000..4c70de32003
--- /dev/null
+++ b/packages/patternfly-4/react-docs/.env.development
@@ -0,0 +1 @@
+LIVE_EXAMPLES=true
diff --git a/packages/patternfly-4/react-docs/.env.production b/packages/patternfly-4/react-docs/.env.production
new file mode 100644
index 00000000000..4c70de32003
--- /dev/null
+++ b/packages/patternfly-4/react-docs/.env.production
@@ -0,0 +1 @@
+LIVE_EXAMPLES=true
diff --git a/packages/patternfly-4/react-docs/gatsby-node.js b/packages/patternfly-4/react-docs/gatsby-node.js
index 5efca0108c5..61347c8f0b6 100644
--- a/packages/patternfly-4/react-docs/gatsby-node.js
+++ b/packages/patternfly-4/react-docs/gatsby-node.js
@@ -54,10 +54,11 @@ exports.onCreateNode = ({ node, boundActionCreators }) => {
exports.createPages = async ({ boundActionCreators, graphql }) => {
const {
- data: { docs, examples }
+ data: { docs, examples, exampleImages }
} = await graphql(`
fragment DocFile on File {
relativePath
+ relativeDirectory
absolutePath
base
name
@@ -78,17 +79,47 @@ exports.createPages = async ({ boundActionCreators, graphql }) => {
}
}
}
+ exampleImages: allFile(filter: { extension: { regex: "/(png|svg)/" } }) {
+ edges {
+ node {
+ ...DocFile
+ }
+ }
+ }
}
`);
const docsComponentPath = path.resolve(__dirname, './src/components/componentDocs');
docs.edges.forEach(({ node: doc }) => {
const filePath = path.resolve(__dirname, '.tmp', doc.base);
+
+ const rawExamples = [];
+ examples.edges.forEach(({ node: example }) => {
+ if (
+ example.relativeDirectory
+ .split('/')
+ .slice(0, 2)
+ .join('/') === doc.relativeDirectory
+ ) {
+ // e.g. components/Alert/examples/DangerAlert.js
+ const examplePath = `../../react-core/src/${example.relativePath}`;
+ rawExamples.push(`{name: '${example.name}', path: '${examplePath}', file: require('!!raw!${examplePath}')}`);
+ }
+ });
+ const allImages = [];
+ exampleImages.edges.forEach(({ node: image }) => {
+ const imagePath = `../../react-core/src/${image.relativePath}`;
+ allImages.push(`{name: '${image.base}', file: require('${imagePath}')}`);
+ });
+
const content = `
import React from 'react';
import docs from '${doc.absolutePath}';
import ComponentDocs from '${docsComponentPath}';
+
+ const rawExamples = [${rawExamples}];
+ const images = [${allImages}];
- export default () =>
+ export default () =>
`;
fs.outputFileSync(filePath, content);
boundActionCreators.createPage({
diff --git a/packages/patternfly-4/react-docs/package.json b/packages/patternfly-4/react-docs/package.json
index 0024e7c6bfc..1fba26f464d 100644
--- a/packages/patternfly-4/react-docs/package.json
+++ b/packages/patternfly-4/react-docs/package.json
@@ -12,7 +12,7 @@
"@patternfly/react-icons": "*",
"@patternfly/react-styles": "^2.0.0",
"@patternfly/react-tokens": "^1.0.0",
- "babel-plugin-react-docgen": "^v1.9.0",
+ "babel-standalone": "^6.26.0",
"emotion": "^9.2.9",
"emotion-server": "^9.2.9",
"gatsby": "^1.9.247",
@@ -27,7 +27,8 @@
"prop-types": "^15.6.1",
"react": "^16.3.2",
"react-dom": "^16.3.2",
- "react-helmet": "^5.2.0"
+ "react-helmet": "^5.2.0",
+ "react-live": "^1.11.0"
},
"keywords": [
"gatsby"
diff --git a/packages/patternfly-4/react-docs/src/components/componentDocs/componentDocs.js b/packages/patternfly-4/react-docs/src/components/componentDocs/componentDocs.js
index 2471a5f1b19..4ac63ff3c05 100644
--- a/packages/patternfly-4/react-docs/src/components/componentDocs/componentDocs.js
+++ b/packages/patternfly-4/react-docs/src/components/componentDocs/componentDocs.js
@@ -13,31 +13,41 @@ const propTypes = {
description: PropTypes.string,
examples: PropTypes.arrayOf(PropTypes.func),
components: PropTypes.objectOf(PropTypes.func),
- enumValues: PropTypes.objectOf(PropTypes.arrayOf(PropTypes.any))
+ enumValues: PropTypes.objectOf(PropTypes.arrayOf(PropTypes.any)),
+ rawExamples: PropTypes.array,
+ images: PropTypes.array
};
const defaultProps = {
description: '',
examples: [],
components: {},
- enumValues: {}
+ enumValues: {},
+ rawExamples: [],
+ images: []
};
-const ComponentDocs = ({ title, description, examples, components, enumValues }) => (
+const ComponentDocs = ({ title, description, examples, components, enumValues, rawExamples, images }) => (
{title}
{Boolean(description) && {description}
}
- {examples.map((ComponentExample, i) => (
-
-
-
- ))}
+ {examples.map((ComponentExample, i) => {
+ const { __docgenInfo: componentDocs } = ComponentExample;
+ const rawExample = rawExamples.find(example => example.name === componentDocs.displayName);
+ return (
+
+
+
+ );
+ })}
{Object.entries(components).map(([componentName, { __docgenInfo: componentDocs }]) => (
diff --git a/packages/patternfly-4/react-docs/src/components/example/example.js b/packages/patternfly-4/react-docs/src/components/example/example.js
index 57e0bfb8873..bdbd61a4a7d 100644
--- a/packages/patternfly-4/react-docs/src/components/example/example.js
+++ b/packages/patternfly-4/react-docs/src/components/example/example.js
@@ -3,26 +3,37 @@ import { css } from '@patternfly/react-styles';
import styles from './example.styles';
import PropTypes from 'prop-types';
import { Title } from '@patternfly/react-core';
+import LiveDemo from './liveDemo';
const propTypes = {
children: PropTypes.node.isRequired,
title: PropTypes.string.isRequired,
description: PropTypes.string,
- className: PropTypes.string
+ className: PropTypes.string,
+ raw: PropTypes.string,
+ images: PropTypes.array
};
const defaultProps = {
className: '',
- description: ''
+ description: '',
+ raw: '',
+ images: []
};
-const Example = ({ children, title, className, description, ...props }) => (
+const LIVE_EXAMPLES = /true/i.test(process.env.LIVE_EXAMPLES);
+
+const Example = ({ children, title, className, description, raw, images, ...props }) => (
-
{title}
+
{title}
{Boolean(description) &&
{description}
}
-
- {children}
-
+ {LIVE_EXAMPLES ? (
+
+ ) : (
+
+ {children}
+
+ )}
);
diff --git a/packages/patternfly-4/react-docs/src/components/example/liveDemo.js b/packages/patternfly-4/react-docs/src/components/example/liveDemo.js
new file mode 100644
index 00000000000..d9affdd27bd
--- /dev/null
+++ b/packages/patternfly-4/react-docs/src/components/example/liveDemo.js
@@ -0,0 +1,67 @@
+import React from 'react';
+import { css } from '@patternfly/react-styles';
+import styles from './example.styles';
+import PropTypes from 'prop-types';
+import * as CoreComponents from '@patternfly/react-core';
+import * as CoreIcons from '@patternfly/react-icons';
+import { LiveProvider, LiveEditor, LiveError, LivePreview, withLive } from 'react-live';
+import { transform } from 'babel-standalone';
+
+const propTypes = {
+ className: PropTypes.string,
+ raw: PropTypes.string.isRequired,
+ images: PropTypes.array
+};
+
+const defaultProps = {
+ className: '',
+ images: []
+};
+
+const scopePlayground = { React, ...CoreComponents, ...CoreIcons };
+
+const transformCode = code => {
+ try {
+ // LiveEditor doesn't work properly with these so need to remove
+ code = code.replace(/^\s*import.*$/gm, '');
+ code = code.replace(/^\s*export default class/gm, 'class');
+ code = code.replace(/extends Component/gm, 'extends React.Component');
+ code = code.replace(/^\s*export.*$/gm, '');
+ code = code.replace(/^\s*static.*$/gm, '');
+ const transformedCode = transform(code, {
+ presets: ['react', 'stage-2']
+ }).code;
+ return transformedCode;
+ } catch (e) {
+ console.log(e);
+ // todo: handle error
+ return code;
+ }
+};
+
+const LiveDemo = ({ className, raw, images, ...props }) => {
+ const scope = {
+ ...scopePlayground
+ };
+ for (const image of images) {
+ const searchIndex = raw.search(image.name);
+ if (searchIndex > -1) {
+ const startIndex = raw.lastIndexOf('import', searchIndex);
+ const importName = raw.substring(startIndex, searchIndex).split(' ')[1];
+ scope[importName] = image.file;
+ }
+ }
+
+ return (
+
+
+
+
+
+ );
+};
+
+LiveDemo.propTypes = propTypes;
+LiveDemo.defaultProps = defaultProps;
+
+export default withLive(LiveDemo);
diff --git a/packages/patternfly-4/react-docs/src/layouts/index.js b/packages/patternfly-4/react-docs/src/layouts/index.js
index 53aadf56eb8..8acb0d4d1c5 100644
--- a/packages/patternfly-4/react-docs/src/layouts/index.js
+++ b/packages/patternfly-4/react-docs/src/layouts/index.js
@@ -32,12 +32,13 @@ const Layout = ({ children, data }) => {
return (
-
+
+
+
+
+
+
+
}
diff --git a/yarn.lock b/yarn.lock
index 41a808f1e8f..8c92b4a5e53 100644
--- a/yarn.lock
+++ b/yarn.lock
@@ -1927,7 +1927,7 @@ babel-plugin-minify-type-constructors@^0.3.0:
dependencies:
babel-helper-is-void-0 "^0.3.0"
-babel-plugin-react-docgen@^1.9.0, babel-plugin-react-docgen@^v1.9.0:
+babel-plugin-react-docgen@^1.9.0:
version "1.9.0"
resolved "https://registry.yarnpkg.com/babel-plugin-react-docgen/-/babel-plugin-react-docgen-1.9.0.tgz#2e79aeed2f93b53a172398f93324fdcf9f02e01f"
dependencies:
@@ -3058,6 +3058,19 @@ btoa-lite@^1.0.0:
version "1.0.0"
resolved "https://registry.yarnpkg.com/btoa-lite/-/btoa-lite-1.0.0.tgz#337766da15801210fdd956c22e9c6891ab9d0337"
+buble@^0.19.3:
+ version "0.19.3"
+ resolved "https://registry.yarnpkg.com/buble/-/buble-0.19.3.tgz#01e9412062cff1da6f20342b6ecd72e7bf699d02"
+ dependencies:
+ acorn "^5.4.1"
+ acorn-dynamic-import "^3.0.0"
+ acorn-jsx "^4.1.1"
+ chalk "^2.3.1"
+ magic-string "^0.22.4"
+ minimist "^1.2.0"
+ os-homedir "^1.0.1"
+ vlq "^1.0.0"
+
buffer-alloc-unsafe@^1.1.0:
version "1.1.0"
resolved "https://registry.yarnpkg.com/buffer-alloc-unsafe/-/buffer-alloc-unsafe-1.1.0.tgz#bd7dc26ae2972d0eda253be061dba992349c19f0"
@@ -3337,7 +3350,7 @@ chalk@2.4.0:
escape-string-regexp "^1.0.5"
supports-color "^5.3.0"
-chalk@2.4.1, chalk@^2.0.0, chalk@^2.0.1, chalk@^2.1.0, chalk@^2.3.0, chalk@^2.3.2, chalk@^2.4.1:
+chalk@2.4.1, chalk@^2.0.0, chalk@^2.0.1, chalk@^2.1.0, chalk@^2.3.0, chalk@^2.3.1, chalk@^2.3.2, chalk@^2.4.1:
version "2.4.1"
resolved "https://registry.yarnpkg.com/chalk/-/chalk-2.4.1.tgz#18c49ab16a037b6eb0152cc83e3471338215b66e"
dependencies:
@@ -3553,6 +3566,14 @@ cli-width@^2.0.0:
version "2.2.0"
resolved "https://registry.yarnpkg.com/cli-width/-/cli-width-2.2.0.tgz#ff19ede8a9a5e579324147b0c11f0fbcbabed639"
+clipboard@^1.5.5:
+ version "1.7.1"
+ resolved "https://registry.yarnpkg.com/clipboard/-/clipboard-1.7.1.tgz#360d6d6946e99a7a1fef395e42ba92b5e9b5a16b"
+ dependencies:
+ good-listener "^1.2.2"
+ select "^1.1.2"
+ tiny-emitter "^2.0.0"
+
clipboard@^2.0.0:
version "2.0.1"
resolved "https://registry.yarnpkg.com/clipboard/-/clipboard-2.0.1.tgz#a12481e1c13d8a50f5f036b0560fe5d16d74e46a"
@@ -3828,6 +3849,14 @@ component-inherit@0.0.3:
version "0.0.3"
resolved "https://registry.yarnpkg.com/component-inherit/-/component-inherit-0.0.3.tgz#645fc4adf58b72b649d5cae65135619db26ff143"
+component-props@1.1.1:
+ version "1.1.1"
+ resolved "https://registry.yarnpkg.com/component-props/-/component-props-1.1.1.tgz#f9b7df9b9927b6e6d97c9bd272aa867670f34944"
+
+component-xor@0.0.4:
+ version "0.0.4"
+ resolved "https://registry.yarnpkg.com/component-xor/-/component-xor-0.0.4.tgz#c55d83ccc1b94cd5089a4e93fa7891c7263e59aa"
+
compressible@~2.0.13:
version "2.0.13"
resolved "https://registry.yarnpkg.com/compressible/-/compressible-2.0.13.tgz#0d1020ab924b2fdb4d6279875c7d6daba6baa7a9"
@@ -4988,6 +5017,13 @@ dom-helpers@^3.2.0, dom-helpers@^3.2.1, dom-helpers@^3.3.1:
version "3.3.1"
resolved "https://registry.yarnpkg.com/dom-helpers/-/dom-helpers-3.3.1.tgz#fc1a4e15ffdf60ddde03a480a9c0fece821dd4a6"
+dom-iterator@^1.0.0:
+ version "1.0.0"
+ resolved "https://registry.yarnpkg.com/dom-iterator/-/dom-iterator-1.0.0.tgz#9c09899846ec41c2d257adc4d6015e4759ef05ad"
+ dependencies:
+ component-props "1.1.1"
+ component-xor "0.0.4"
+
dom-serializer@0, dom-serializer@~0.1.0:
version "0.1.0"
resolved "https://registry.yarnpkg.com/dom-serializer/-/dom-serializer-0.1.0.tgz#073c697546ce0780ce23be4a28e293e40bc30c82"
@@ -9812,6 +9848,12 @@ ltcdr@^2.2.1:
version "2.2.1"
resolved "https://registry.yarnpkg.com/ltcdr/-/ltcdr-2.2.1.tgz#5ab87ad1d4c1dab8e8c08bbf037ee0c1902287cf"
+magic-string@^0.22.4:
+ version "0.22.5"
+ resolved "http://registry.npmjs.org/magic-string/-/magic-string-0.22.5.tgz#8e9cf5afddf44385c1da5bc2a6a0dbd10b03657e"
+ dependencies:
+ vlq "^0.2.2"
+
make-dir@^1.0.0:
version "1.3.0"
resolved "https://registry.yarnpkg.com/make-dir/-/make-dir-1.3.0.tgz#79c1033b80515bd6d24ec9933e860ca75ee27f0c"
@@ -12225,6 +12267,12 @@ pretty-format@^23.6.0:
ansi-regex "^3.0.0"
ansi-styles "^3.2.0"
+prismjs@1.6:
+ version "1.6.0"
+ resolved "https://registry.yarnpkg.com/prismjs/-/prismjs-1.6.0.tgz#118d95fb7a66dba2272e343b345f5236659db365"
+ optionalDependencies:
+ clipboard "^1.5.5"
+
prismjs@^1.8.4, prismjs@~1.14.0:
version "1.14.0"
resolved "https://registry.yarnpkg.com/prismjs/-/prismjs-1.14.0.tgz#bbccfdb8be5d850d26453933cb50122ca0362ae0"
@@ -12769,6 +12817,17 @@ react-lifecycles-compat@^3.0.0:
version "3.0.4"
resolved "https://registry.yarnpkg.com/react-lifecycles-compat/-/react-lifecycles-compat-3.0.4.tgz#4f1a273afdfc8f3488a8c516bfda78f872352362"
+react-live@^1.11.0:
+ version "1.11.0"
+ resolved "https://registry.yarnpkg.com/react-live/-/react-live-1.11.0.tgz#257b54abb64df250bc40b0572c21acd600ecdd5c"
+ dependencies:
+ buble "^0.19.3"
+ core-js "^2.4.1"
+ dom-iterator "^1.0.0"
+ prismjs "1.6"
+ prop-types "^15.5.8"
+ unescape "^0.2.0"
+
react-modal@^3.3.2:
version "3.4.4"
resolved "https://registry.yarnpkg.com/react-modal/-/react-modal-3.4.4.tgz#e9dde25e9e85a59c76831f2a2b468712a546aded"
@@ -15527,6 +15586,10 @@ underscore@~1.6.0:
version "1.6.0"
resolved "https://registry.yarnpkg.com/underscore/-/underscore-1.6.0.tgz#8b38b10cacdef63337b8b24e4ff86d45aea529a8"
+unescape@^0.2.0:
+ version "0.2.0"
+ resolved "https://registry.yarnpkg.com/unescape/-/unescape-0.2.0.tgz#b78b9b60c86f1629df181bf53eee3bc8d6367ddf"
+
unherit@^1.0.4:
version "1.1.1"
resolved "https://registry.yarnpkg.com/unherit/-/unherit-1.1.1.tgz#132748da3e88eab767e08fabfbb89c5e9d28628c"
@@ -15854,6 +15917,14 @@ viewport-dimensions@^0.2.0:
version "0.2.0"
resolved "https://registry.yarnpkg.com/viewport-dimensions/-/viewport-dimensions-0.2.0.tgz#de740747db5387fd1725f5175e91bac76afdf36c"
+vlq@^0.2.2:
+ version "0.2.3"
+ resolved "https://registry.yarnpkg.com/vlq/-/vlq-0.2.3.tgz#8f3e4328cf63b1540c0d67e1b2778386f8975b26"
+
+vlq@^1.0.0:
+ version "1.0.0"
+ resolved "https://registry.yarnpkg.com/vlq/-/vlq-1.0.0.tgz#8101be90843422954c2b13eb27f2f3122bdcc806"
+
vm-browserify@0.0.4:
version "0.0.4"
resolved "https://registry.yarnpkg.com/vm-browserify/-/vm-browserify-0.0.4.tgz#5d7ea45bbef9e4a6ff65f95438e0a87c357d5a73"