Skip to content

Commit

Permalink
v1.2.1 object selector
Browse files Browse the repository at this point in the history
Adding object param-type selector
  • Loading branch information
NoamELB authored Oct 13, 2017
2 parents 689ec54 + 8bfdf50 commit 6fb2e2e
Show file tree
Hide file tree
Showing 7 changed files with 126 additions and 25 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -2,11 +2,9 @@ import React from 'react';
import _ from 'underscore';

import TextField from '../../../UI/TextField';
import Tooltip from '../../../UI/Tooltip';
import ErrorIndicator from '../../../UI/ErrorIndicator';
import jsxToString from '../../../../services/jsx-to-string';

import './index.scss';

const DEBOUNCE_AMOUNT = 500;
const START_WITH_TAG_REGEX = /^\s*</;

Expand Down Expand Up @@ -98,28 +96,17 @@ export default class ParamSelectorJSX extends React.Component {
onChange(null, compiledValue);
}

/**
* Create an error tooltip to show the latest compilation error in a tooltip
*/
renderErrorTooltip() {
return (
<div className="library-_-error-indicator-wrapper">
<Tooltip tooltip={<pre>{this.state.error.toString()}</pre>}>
<div className="library-_-error-indicator" />
</Tooltip>
</div>
);
}

render() {
return (
<div className="library-_-jsx-selector-wrapper">
{this.state.error ? this.renderErrorTooltip() : null}
<TextField
value={this.state.value}
onChange={this.onChange}
placeholder="<div>JSX</div>" />
</div>
<ErrorIndicator error={this.state.error}>
<div className="library-_-jsx-selector-wrapper library-_-tooltip-error-indicator-wrapper">
{this.state.error ? this.renderErrorTooltip() : null}
<TextField
value={this.state.value}
onChange={this.onChange}
placeholder="<div>JSX</div>" />
</div>
</ErrorIndicator>
);
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,75 @@
import React from 'react';
import _ from 'underscore';

import TextField from '../../../UI/TextField';
import ErrorIndicator from '../../../UI/ErrorIndicator';

const DEBOUNCE_AMOUNT = 300;

/**
* @description
* open input for object values. will try to eval value and fallback to undefined.
*
* @param {function} onChange
*/
export default class ParamSelectorObject extends React.Component {
constructor(props) {
super(props);
this.state = {error: null};
this.onChange = this.onChange.bind(this);
this.reportChangeBounced = _.debounce(val => this.reportChange(val), DEBOUNCE_AMOUNT);
}

/**
* A bit of a hack - it puts initial Object to the TextField but free it right after
* (by setting it immediately after to undefined)
*/
componentDidMount() {
let value = JSON.stringify(this.props.selectedValue);
if (value) {
this.setState(
state => _.extend({}, state, {value}),
() => this.setState(state => _.extend({}, state, {value: undefined}))
);
}
}

/**
* Will update the new value from the event.
* sadly the event cannot be sent to the parent onChange because we debounce the onChange
* @param {event} e
*/
onChange(e) {
const newValue = e.target.value;
this.reportChangeBounced(newValue);
}

/**
* report to parent onChange, this function is debounced to be reportChangeBounced
* @param {string} val
*/
reportChange(val) {
const {name, compiler = _.noop, onChange = _.noop} = this.props;
let obj, error = null;
try {
obj = compiler(`Object(${val})`);
} catch (e) {
error = e;
}
this.setState(state => _.extend({}, state, {error}));
onChange(null, obj);
}

render() {
return (
<ErrorIndicator error={this.state.error}>
<div className="library-_-object-selector-wrapper">
<TextField
value={this.state.value}
onChange={this.onChange}
placeholder="{ object: ... }" />
</div>
</ErrorIndicator>
);
}
}
2 changes: 2 additions & 0 deletions client/Components/ComponentParams/ParamSelector/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -7,12 +7,14 @@ import ParamSelectorVariant from './ParamSelectorVariant';
import ParamSelectorJSON from './ParamSelectorJSON';
import ParamSelectorFunction from './ParamSelectorFunction';
import ParamSelectorJSX from './ParamSelectorJSX';
import ParamSelectorObject from './ParamSelectorObject';

const paramTypeToComponent = {
'bool': ParamSelectorBoolean,
'variant': ParamSelectorVariant,
'function' : ParamSelectorFunction,
'node': ParamSelectorJSX,
'object': ParamSelectorObject,
'default': ParamSelectorJSON,
};

Expand Down
35 changes: 35 additions & 0 deletions client/Components/UI/ErrorIndicator/index.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,35 @@
import React from 'react';

import Tooltip from '../Tooltip';
import './index.scss';

/**
* @name
* ErrorIndicator
*
* @module
* Content
*
* @description
* Show an error tooltip on a container
*
* @example
* <ErrorIndicator error={new Error('message')}>
* My error-full content
* </ErrorIndicator>
*
* @param {node} children
* @param {String|Error} [error]
*/
export default function ErrorIndicator ({children, error}) {
return (
<div className="library-_-tooltip-error-indicator-wrapper">
{error ? (<div className="library-_-error-indicator-wrapper">
<Tooltip tooltip={<pre>{error.toString && error.toString()}</pre>}>
<div className="library-_-error-indicator" />
</Tooltip>
</div>) : null}
{children}
</div>
);
}
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
.library-_-jsx-selector-wrapper {
.library-_-tooltip-error-indicator-wrapper {
position: relative;
pre {
white-space: pre-wrap;
Expand Down
2 changes: 2 additions & 0 deletions client/components.js
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
import Card from './Components/UI/Card';
import CodeCard from './Components/UI/CodeCard';
import ErrorIndicator from './Components/UI/ErrorIndicator';
import Menu from './Components/UI/Menu';
import RaisedButton from './Components/UI/RaisedButton';
import MenuItem from './Components/UI/MenuItem';
Expand All @@ -12,6 +13,7 @@ import Modal from './Components/UI/Modal';
export default {
Card,
CodeCard,
ErrorIndicator,
Menu,
MenuItem,
RaisedButton,
Expand Down
2 changes: 1 addition & 1 deletion client/documentation.js

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

0 comments on commit 6fb2e2e

Please sign in to comment.