diff --git a/src/components/Panel.js b/src/components/Panel.js index 97b7880b5563..9a02ec3834fc 100644 --- a/src/components/Panel.js +++ b/src/components/Panel.js @@ -39,66 +39,69 @@ export default class Panel extends React.Component { super(props); this._handleChange = this.handleChange.bind(this); this._setFields = this.setFields.bind(this); + this._checkUrlAndsetFields = this.checkUrlAndsetFields.bind(this); this._reset = this.reset.bind(this); - this._setInitialFields = this.setInitialFields.bind(this); - this._indicateReady = this.indicateReady.bind(this); this.state = { fields: {} }; this.api = this.props.api; } componentWillMount() { - const urlState = this.api.getQueryParam('knobs'); - - if (urlState && urlState.length > 0) { - this.initialFields = JSON.parse(urlState); - } - - if (this.initialFields) { - this.props.channel.on('addon:knobs:helloFromStory', this._setInitialFields); - this.setState({ fields: this.initialFields }); - } else { - this.props.channel.on('addon:knobs:helloFromStory', this._indicateReady); - } + this.props.channel.on('addon:knobs:setFields', this._checkUrlAndsetFields); } componentDidMount() { this.stopOnStory = this.api.onStory(() => { this.api.setQueryParams({ knobs: null }); }); - - this.props.channel.on('addon:knobs:setFields', this._setFields); - this.props.channel.emit('addon:knobs:helloFromPanel'); } componentWillUnmount() { this.props.channel.removeListener('addon:knobs:setFields', this._setFields); - this.props.channel.removeListener('addon:knobs:helloFromStory', this._indicateReady); - this.props.channel.removeListener('addon:knobs:helloFromStory', this._setInitialFields); this.stopOnStory(); } - setInitialFields() { - this.props.channel.emit('addon:knobs:initialFields', this.initialFields); - this.props.channel.removeListener('addon:knobs:helloFromStory', this._setInitialFields); - this.props.channel.on('addon:knobs:helloFromStory', this._indicateReady); - } - setFields(_fields) { const fields = _fields; + const queryParams = {}; for (const f in fields) { if (fields.hasOwnProperty(f)) { + queryParams[`knob-${f}`] = fields[f].value; if (fields[f].type === 'object') { fields[f].value = beautify(tosource(fields[f].value)); } } } + this.api.setQueryParams(queryParams); this.setState({ fields }); - this.api.setQueryParams({ knobs: JSON.stringify(fields) }); } - indicateReady() { - this.props.channel.emit('addon:knobs:panelReady'); + checkUrlAndsetFields(_fields) { + const fields = _fields; + for (const name in fields) { + if (fields.hasOwnProperty(name)) { + let urlValue = this.api.getQueryParam(`knob-${name}`); + if (urlValue !== undefined) { + // When saved in url the information of whether number or string or bool is lost + // so have to convert numbers and booleans back. + switch (fields[name].type) { + case 'boolean': + urlValue = (urlValue === 'true'); + break; + case 'number': + urlValue = Number(urlValue); + break; + default: + } + + fields[name].value = urlValue; + this.props.channel.emit('addon:knobs:knobChange', { name, value: urlValue }); + } + } + } + this.props.channel.removeListener('addon:knobs:setFields', this._checkUrlAndsetFields); + this.props.channel.on('addon:knobs:setFields', this._setFields); + this.setFields(fields); } reset() { @@ -106,16 +109,39 @@ export default class Panel extends React.Component { } handleChange(change) { - const { name, value } = change; + const { name, value, type } = change; const fields = this.state.fields; const changedField = {}; changedField[name] = { ...fields[name], ...{ value } }; const newFields = { ...fields, ...changedField }; this.setState({ fields: newFields }); - this.api.setQueryParams({ knobs: JSON.stringify(newFields) }); - this.props.channel.emit('addon:knobs:knobChange', change); + let formatedValue = value; + switch (type) { + case 'object': + try { + formatedValue = eval(`(${value})`); // eslint-disable-line no-eval + } catch (e) { + return; + } + break; + case 'number': + try { + formatedValue = Number(value); + } catch (e) { + return; + } + break; + default: + formatedValue = value; + } + + const queryParams = {}; + queryParams[`knob-${name}`] = formatedValue; + this.api.setQueryParams(queryParams); + + this.props.channel.emit('addon:knobs:knobChange', { name, value: formatedValue }); } render() { diff --git a/src/components/PropField.js b/src/components/PropField.js index 2c001176b107..c621025aa876 100644 --- a/src/components/PropField.js +++ b/src/components/PropField.js @@ -57,15 +57,15 @@ export default class PropField extends React.Component { } onChange(e) { - this.props.onChange(this.props.name, e.target.value); + this.props.onChange(e.target.value); } onChangeBool(e) { - this.props.onChange(this.props.name, e.target.checked); + this.props.onChange(e.target.checked); } onChangeObj(value) { - this.props.onChange(this.props.name, value); + this.props.onChange(value); } render() { diff --git a/src/components/PropForm.js b/src/components/PropForm.js index c67b18bfbb20..49bd45faa8f1 100644 --- a/src/components/PropForm.js +++ b/src/components/PropForm.js @@ -23,8 +23,8 @@ export default class propForm extends React.Component { this._onFieldChange = this.onFieldChange.bind(this); } - onFieldChange(name, value) { - const change = { name, value }; + onFieldChange(name, type, value) { + const change = { name, type, value }; this.props.onFieldChange(change); } @@ -43,7 +43,7 @@ export default class propForm extends React.Component { name={field.name} type={field.type} value={field.value} - onChange={this._onFieldChange} + onChange={this._onFieldChange.bind(null, field.name, field.type)} /> ))} diff --git a/src/components/Wrap.js b/src/components/Wrap.js index 5436a936113d..0a7b0ec5ada6 100644 --- a/src/components/Wrap.js +++ b/src/components/Wrap.js @@ -7,29 +7,20 @@ export default class Wrap extends React.Component { this._knobChanged = this.knobChanged.bind(this); this._resetKnobs = this.resetKnobs.bind(this); this._knobsAreReset = false; - this.gotHello = () => { - this.props.channel.emit('addon:knobs:helloFromStory'); - }; this.setPanelFields = () => { this.props.channel.emit('addon:knobs:setFields', this.props.store); }; } componentDidMount() { - this.props.channel.on('addon:knobs:initialFields', this._initialPropsReceived); this.props.channel.on('addon:knobs:knobChange', this._knobChanged); this.props.channel.on('addon:knobs:reset', this._resetKnobs); - this.props.channel.on('addon:knobs:helloFromPanel', this.gotHello); - this.props.channel.on('addon:knobs:panelReady', this.setPanelFields); - this.props.channel.emit('addon:knobs:helloFromStory'); + this.setPanelFields(); } componentWillUnmount() { - this.props.channel.removeListener('addon:knobs:initialFields', this._initialPropsReceived); this.props.channel.removeListener('addon:knobs:knobChange', this._knobChanged); this.props.channel.removeListener('addon:knobs:reset', this._resetKnobs); - this.props.channel.removeListener('addon:knobs:helloFromPanel', this.gotHello); - this.props.channel.removeListener('addon:knobs:panelReady', this.setPanelFields); } initialPropsReceived(initialProps) { @@ -41,29 +32,8 @@ export default class Wrap extends React.Component { knobChanged(change) { const { name, value } = change; - const { type } = this.props.store[name]; - - let formatedValue = value; - switch (type) { - case 'object': - try { - formatedValue = eval(`(${value})`); // eslint-disable-line no-eval - } catch (e) { - return; - } - break; - case 'number': - try { - formatedValue = Number(value); - } catch (e) { - return; - } - break; - default: - formatedValue = value; - } - this.props.store[name].value = formatedValue; + this.props.store[name].value = value; this.forceUpdate(); }