Skip to content
This repository was archived by the owner on Feb 17, 2022. It is now read-only.
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
12 changes: 12 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -156,6 +156,18 @@ var ComponentExample = React.createClass({
React.render(<ComponentExample/>, mountNode);
```

### hyphenatedClassNames
_React.PropTypes.bool_

Defaults to false. If set to false, allows return the classnames of the component wrapper and rest of them as hyphenated.
You can use this option to have the classnames as hyphenated.

```js
<Playground
hyphenatedClassNames={true}
/>
```

### Comparison to [react-live](https://github.com/FormidableLabs/react-live)

There are multiple options when it comes to live, editable React component environments. Formidable actually has **two** first class projects to help you out: [`component-playground`](https://github.com/FormidableLabs/component-playground) and [`react-live`](https://github.com/FormidableLabs/react-live). Let's briefly look at the libraries, use cases, and factors that might help in deciding which is right for you.
Expand Down
9 changes: 6 additions & 3 deletions src/components/doc.jsx
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
import React, { Component } from "react";
import PropTypes from "prop-types";
import { getHyphenatedClassNames } from "../utils/string";

const propTypesArray = [{
key: "array",
Expand Down Expand Up @@ -65,7 +66,8 @@ class Doc extends Component {
static propTypes = {
componentClass: PropTypes.func,
ignore: PropTypes.array,
propDescriptionMap: PropTypes.object
propDescriptionMap: PropTypes.object,
hyphenatedClassNames: PropTypes.bool
};

render() {
Expand All @@ -74,7 +76,8 @@ class Doc extends Component {
const {
componentClass,
ignore,
propDescriptionMap
propDescriptionMap,
hyphenatedClassNames = false
} = this.props;
for (const propName in componentClass.propTypes) {
if (ignore.indexOf(propName)) {
Expand All @@ -87,7 +90,7 @@ class Doc extends Component {
}

return (
<div className="playgroundDocs">
<div className={getHyphenatedClassNames("playgroundDocs", hyphenatedClassNames)}>
<ul>
{
propTypes.map((propObj) => (
Expand Down
11 changes: 9 additions & 2 deletions src/components/es6-preview.jsx
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@ import React, { Component } from "react";
import PropTypes from "prop-types";
import { render, unmountComponentAtNode } from "react-dom";
import { transform } from "babel-standalone";
import { getHyphenatedClassNames } from "../utils/string";

const getType = function (el) {
let t = typeof el;
Expand Down Expand Up @@ -84,7 +85,8 @@ class EsPreview extends Component {

static propTypes = {
code: PropTypes.string.isRequired,
scope: PropTypes.object.isRequired
scope: PropTypes.object.isRequired,
hyphenatedClassNames: PropTypes.bool
};

_compileCode = () => {
Expand All @@ -108,6 +110,7 @@ class EsPreview extends Component {

_executeCode = () => {
const mountNode = this.mount;
const { hyphenatedClassNames = false } = this.props;

try {
unmountComponentAtNode(mountNode);
Expand Down Expand Up @@ -155,7 +158,11 @@ class EsPreview extends Component {
} catch (err) {
this._setTimeout(() => {
render(
<div className="playgroundError">{err.toString()}</div>,
<div
className={getHyphenatedClassNames("playgroundError", hyphenatedClassNames)}
>
{err.toString()}
</div>,
mountNode
);
}, 500);
Expand Down
38 changes: 30 additions & 8 deletions src/components/playground.jsx
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@ import Editor from "./editor";
import Preview from "./preview";
import EsPreview from "./es6-preview";
import Doc from "./doc";
import { getHyphenatedClassNames } from "../utils/string";

// TODO: refactor to remove componentWillReceiveProps
// eslint-disable-next-line react/no-deprecated
Expand All @@ -30,7 +31,8 @@ class ReactPlayground extends Component {
es6Console: PropTypes.bool,
context: PropTypes.object,
initiallyExpanded: PropTypes.bool,
previewComponent: PropTypes.node
previewComponent: PropTypes.node,
hyphenatedClassNames: PropTypes.node
};

state = {
Expand Down Expand Up @@ -72,20 +74,31 @@ class ReactPlayground extends Component {
propDescriptionMap,
scope,
selectedLines,
theme } = this.props;
theme,
hyphenatedClassNames = false
} = this.props;

return (
<div className={`playground${collapsableCode ? " collapsableCode" : ""}`}>
<div
className={collapsableCode ?
getHyphenatedClassNames("playground collapsableCode", hyphenatedClassNames)
: "playground"}
>
{
docClass ?
<Doc
componentClass={docClass}
propDescriptionMap={propDescriptionMap}
hyphenatedClassNames={hyphenatedClassNames}
/> : null
}
<div className={`playgroundCode${expandedCode ? " expandedCode" : ""}`}>
<div
className={expandedCode ?
getHyphenatedClassNames("playgroundCode expandedCode", hyphenatedClassNames)
: getHyphenatedClassNames("playgroundCode", hyphenatedClassNames)}
>
<Editor
className="playgroundStage"
className={getHyphenatedClassNames("playgroundStage", hyphenatedClassNames)}
codeText={codeText}
external={external}
onChange={this._handleCodeChange}
Expand All @@ -95,25 +108,34 @@ class ReactPlayground extends Component {
</div>
{
collapsableCode ?
<div className="playgroundToggleCodeBar">
<span className="playgroundToggleCodeLink" onClick={this._toggleCode}>
<div
className={getHyphenatedClassNames("playgroundToggleCodeBar", hyphenatedClassNames)}
>
<span
className={
getHyphenatedClassNames("playgroundToggleCodeLink", hyphenatedClassNames)
}
onClick={this._toggleCode}
>
{expandedCode ? "collapse" : "expand"}
</span>
</div> : null
}
<div className="playgroundPreview">
<div className={getHyphenatedClassNames("playgroundPreview", hyphenatedClassNames)}>
{
es6Console ?
<EsPreview
code={code}
scope={scope}
hyphenatedClassNames={hyphenatedClassNames}
/> :
<Preview
context={context}
code={code}
scope={scope}
noRender={noRender}
previewComponent={previewComponent}
hyphenatedClassNames={hyphenatedClassNames}
/>
}
</div>
Expand Down
19 changes: 15 additions & 4 deletions src/components/preview.jsx
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@ import PropTypes from "prop-types";
import { render } from "react-dom";
import ReactDOMServer from "react-dom/server";
import { transform } from "babel-standalone";
import { getHyphenatedClassNames } from "../utils/string";

class Preview extends Component {

Expand All @@ -16,7 +17,8 @@ class Preview extends Component {
scope: PropTypes.object.isRequired,
previewComponent: PropTypes.node,
noRender: PropTypes.bool,
context: PropTypes.object
context: PropTypes.object,
hyphenatedClassNames: PropTypes.bool
};

state = {
Expand Down Expand Up @@ -112,12 +114,21 @@ class Preview extends Component {

render() {
const { error } = this.state;
const { hyphenatedClassNames = false } = this.props;
return (
<div>
{error !== null ?
<div className="playgroundError">{error}</div> :
null}
<div ref={(c) => { this.mount = c; }} className="previewArea"/>
<div
className={getHyphenatedClassNames("playgroundError", hyphenatedClassNames)}
>
{error}
</div> :
null
}
<div
ref={(c) => { this.mount = c; }}
className={getHyphenatedClassNames("previewArea", hyphenatedClassNames)}
/>
</div>
);
}
Expand Down
3 changes: 3 additions & 0 deletions src/utils/string.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
export const getHyphenatedClassNames = (className, flag) => {
return flag ? className.replace(/([a-z])([A-Z])/g, "$1-$2").toLowerCase() : className;
};