Observable Generators
The Observable standard library includes several generator utilities. These are available by default in Markdown as Generators
, but you can import them explicitly:
import {Generators} from "npm:@observablehq/stdlib";
input(element)
Returns an async generator that yields whenever the given element emits an input event, with the given element’s current value. (It’s a bit fancier than that because we special-case a few element types.) The built-in view
function uses this.
const nameInput = display(document.createElement("input"));
const name = Generators.input(nameInput);
name
observe(change)
Returns an async generator that yields whenever the callback function change is called, with the value passed.
const hash = Generators.observe((change) => {
const changed = () => change(location.hash);
addEventListener("hashchange", changed);
changed();
return () => removeEventListener("hashchange", changed);
});
hash
queue(change)
Returns an async generator that yields whenever the callback function change is called, with the value passed. This is identical to Generators.observe, except that if change is called multiple times before the consumer has a chance to process the yielded result, values will not be dropped; use this if you require that the consumer not miss a yielded value.
const hash = Generators.queue((change) => {
const changed = () => change(location.hash);
addEventListener("hashchange", changed);
changed();
return () => removeEventListener("hashchange", changed);
});
hash
now()
Returns a generator that repeatedly yields Date.now()
, forever. This generator is available by default as now
in Markdown.
const now = Generators.now();
now
width(element)
Returns an async generator that yields the width of the given target element. Using a ResizeObserver, the generator will yield whenever the width of the element changes. This generator for the main
element is available by default as width
in Markdown.
const width = Generators.width(document.querySelector("main"));
width
dark()
Returns an async generator that yields a boolean indicating whether the page is currently displayed with a dark color scheme.
If the page supports both light and dark mode (as with the default theme), the value reflects the user’s preferred color scheme. The generator will yield a new value if the preferred color changes — as when the user changes their system settings, or if the user’s system adapts automatically to the diurnal cycle — allowing you to update the display as needed without requiring a page reload.
If the page only supports light mode, the value is always false; likewise it is always true if the page only has a dark theme.
The current theme is: .
The current theme is: *${dark ? "dark" : "light"}*.
This generator is available by default as dark
in Markdown. It can be used to pick a color scheme for a chart, or an appropriate mix-blend-mode:
Plot.plot({
height: 260,
color: {scheme: dark ? "turbo" : "ylgnbu"},
marks: [
Plot.rectY(
olympians,
Plot.binX(
{y2: "count"},
{
x: "weight",
fill: "weight",
z: "sex",
mixBlendMode: dark ? "screen" : "multiply"
}
)
),
Plot.ruleY([0])
]
})