Published
Edited
May 27, 2020
Importers
3 stars
Also listed in…
State
Insert cell
Insert cell
createStore = initStore => {
const keys = Object.keys(initStore);
const s = Object.assign(dispatch(...keys), {
...initStore,
keys: () => keys
});
keys.forEach(k => {
s.on(`${k}.store`, d => {
s[k] = d;
});
});
return s;
}
Insert cell
store = createStore({ x: 20, y: 60 })
Insert cell
Insert cell
function createControl(
store,
key,
dom = html`<input type=range>`,
invalidation = disposal(dom)
) {
// Create the control
const control = dom;
const dispatchId = `${key}.input-control-${randomString()}`;

control.value = store[key];

// Listen to the store changes (store -> control)
store.on(dispatchId, function(d) {
if (this !== control) {
// The change has not been made by this control
control.value = d;
}
});
invalidation.then(() => store.on(dispatchId, null));

// Mutate the store on input (store <- control)
control.oninput = function() {
store.call(key, control, this.value);
};

return control;
}
Insert cell
Insert cell
createControl(store, 'x')
Insert cell
createControl(store, 'x')
Insert cell
Insert cell
createControl(store, 'y')
Insert cell
createControl(store, 'y', html`<input type=number min=0 max=100 step=1>`)
Insert cell
Insert cell
storeGetter = (store, field, invalidation) => {
const view = new View(store[field]);
const dispatchId = `${field}.store-getter-${randomString()}`;
store.on(dispatchId, d => (view.value = d));
invalidation.then(() => store.on(dispatchId, null));
return view;
}
Insert cell
viewof x = storeGetter(store, 'x', invalidation)
Insert cell
x
Insert cell
viewof y = storeGetter(store, 'y', invalidation)
Insert cell
y
Insert cell
Insert cell
stateGetter = (store, invalidation) => {
const keys = store.keys();
const init = keys.reduce((a, c) => {
a[c] = store[c];
return a;
}, {});
const view = new View(init);
for (const k of keys) {
const dispatchId = `${k}.state-getter-${randomString()}`;
store.on(dispatchId, d => {
view.value[k] = d;
view.dispatchEvent(new CustomEvent("input", { detail: view.value }));
});
invalidation.then(() => store.on(dispatchId, null));
}
return view;
}
Insert cell
viewof state = stateGetter(store, invalidation)
Insert cell
state
Insert cell
Insert cell
viewof d = {
// Create the control
const d = XYPad(store.x, store.y);

// Listen to the store changes (store -> XYPad)
store.on(`x.d`, x => (d.x = x));
store.on(`y.d`, y => (d.y = y));
invalidation.then(() => store.on(`x.d`, null));
invalidation.then(() => store.on(`y.d`, null));

// Mutate the store on input (store <- XYPad)
const updateX = () => store.call('x', this, d.x);
const updateY = () => store.call('y', this, d.y);
d.addEventListener("inputX", updateX);
d.addEventListener("inputY", updateY);
invalidation.then(() => d.removeEventListener("input", updateX));
invalidation.then(() => d.removeEventListener("input", updateY));

return d;
}
Insert cell
Insert cell
Insert cell
Insert cell
Insert cell
Insert cell
Insert cell

Purpose-built for displays of data

Observable is your go-to platform for exploring data and creating expressive data visualizations. Use reactive JavaScript notebooks for prototyping and a collaborative canvas for visual data exploration and dashboard creation.
Learn more