Skip to content

Instantly share code, notes, and snippets.

@oriSomething
Last active January 19, 2018 10:04
Show Gist options
  • Save oriSomething/8c5c9155719f43419da97ca27c5adbdf to your computer and use it in GitHub Desktop.
Save oriSomething/8c5c9155719f43419da97ca27c5adbdf to your computer and use it in GitHub Desktop.
Storybook one way binding updater. So knobs can be used with self update components
import * as React from "react";
type RenderT<State> = (
state: State,
update: <K extends keyof State>(key: K, value: State[K]) => void,
) => React.ReactNode;
interface Props<State> {
state: State;
render: RenderT<State>;
}
export function StorybookOneWayBinding<State>(props: Props<State>) {
const C = StorybookOneWayBinding_ as any;
return <C {...props} />;
}
class StorybookOneWayBinding_<State> extends React.Component<Props<State>, State> {
state: State = this.getState(this.props);
getState(props: Props<State>): State {
return props.state;
}
componentWillReceiveProps(nextProps: Readonly<Props<State>>) {
const nextState = this.getState(nextProps);
for (let key_ of Object.keys(nextState)) {
const key = key_ as keyof State;
if (nextProps.state[key] !== nextState[key]) {
this.setState((): any => {
return {
[key]: nextProps.state[key],
};
});
}
}
}
update = <K extends keyof State>(key: K, value: State[K]) => {
this.setState((): any => {
return {
[key]: value,
};
});
};
render() {
const { render } = this.props;
return render(this.state, this.update);
}
}
import * as React from "react";
import { storiesOf } from "@storybook/react";
import { text } from "@storybook/addon-knobs";
import { TextField } from "../src/TextField";
import { StorybookOneWayBinding } from "./utils/StorybookOneWayBinding";
storiesOf("TextField", module).add("TextField", () => {
const value: string = text("value:", "Hello world");
return (
<StorybookOneWayBinding
state={{ value }}
render={(state, update) => {
return <TextField value={state.value} onChange={value => update("value", value)} />;
}}
/>
);
});
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment