Last active
November 13, 2018 07:59
-
-
Save y-nk/a22a13c14c93ce76e897a4bff7aa81ec to your computer and use it in GitHub Desktop.
non breaking double binding
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
import React from 'react'; | |
import { storiesOf } from '@storybook/react'; | |
import { withKnobs } from '@storybook/addon-knobs'; | |
// =========================================================================== | |
import deepEqual from 'fast-deep-equal'; | |
import { forceReRender } from '@storybook/react'; | |
import { manager } from '@storybook/addon-knobs/dist/registerKnobs'; | |
// 1. we define a constant which will be unique and used to detect the setter case | |
const NULL_SYMBOL = Symbol('null') | |
// 2. we set value to this by default, so when user calls text('label') we can detect it's a getter or not | |
function text(name, value = NULL_SYMBOL, groupId = null) { | |
return manager.knob(name, { type: 'text', value, groupId }); | |
} | |
manager.knob = function(name, options) { | |
this._mayCallChannel(); | |
const { knobStore } = this; | |
const existingKnob = knobStore.get(name); | |
// sorry that i stripped the comments out, but i wanted clarity. | |
// 3a. we keep this case, and consider it now as a getter for existing knob | |
if (existingKnob && deepEqual(options.value, existingKnob.defaultValue)) { | |
return this.getKnobValue(existingKnob); | |
} | |
// 3b. in the same fashion, we create this new case which acts as a setter if value parameter is omitted. we check by using our constant | |
else if (existingKnob && options.value !== NULL_SYMBOL) { | |
knobStore.set(name, { ...existingKnob, value: options.value }) | |
forceReRender() | |
return | |
} | |
// As there are now 2 returns in the above if statement, this below only belongs to create a new knob. | |
// To make sure that there will be no complication if user calls text('newlabel') for the first time, | |
// we use this ternary to secure 'value' and 'defaultValue' | |
const value = options.value !== NULL_SYMBOL ? options.value : ''; | |
const defaultValue = value; | |
const knobInfo = { | |
...options, | |
name, | |
value, | |
defaultValue, | |
}; | |
knobStore.set(name, knobInfo); | |
return this.getKnobValue(knobStore.get(name)); | |
} | |
// ============================================================================ | |
const stories = storiesOf('Knobs demo', module) | |
stories.addDecorator(withKnobs) | |
stories.add('input text', () => ( | |
<input type="text" value={ text('value', 'default value') } onChange={ e => text('value', e.target.value) } /> | |
)); |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment