Skip to content

Commit cdd6c35

Browse files
Filmbostock
andauthored
dark (#1025)
* dark * Update docs/lib/generators.md --------- Co-authored-by: Mike Bostock <[email protected]>
1 parent 646055a commit cdd6c35

File tree

4 files changed

+51
-0
lines changed

4 files changed

+51
-0
lines changed

docs/lib/generators.md

+36
Original file line numberDiff line numberDiff line change
@@ -74,3 +74,39 @@ const width = Generators.width(document.querySelector("main"));
7474
```js echo
7575
width
7676
```
77+
78+
## dark()
79+
80+
Returns an async generator that yields a boolean indicating whether the page is currently displayed with a dark [color-scheme](https://developer.mozilla.org/en-US/docs/Web/CSS/color-scheme).
81+
82+
If the page supports dark mode (for example with the default Framework themes), the value reflects the user’s preferred color scheme. It will yield if that value changes, and update the charts that depend on it without needing to reload the page — this happens at dusk (if the user settings adapt from light to dark), and conversely at dawn, from dark to light; and of course, when the user is playing with their settings.
83+
84+
If the page does _not_ support dark mode, and only has a light theme, the value is always false, and likewise it is always true if the page only has a dark theme.
85+
86+
```js echo
87+
html`<em>Current theme: ${dark ? "dark" : "light"}</em>`
88+
```
89+
90+
This generator is available by default as `dark` in Markdown. It can be used to pick a [color scheme](https://observablehq.com/plot/features/scales#color-scales) for a chart, or an appropriate [mix-blend-mode](https://developer.mozilla.org/en-US/docs/Web/CSS/mix-blend-mode):
91+
92+
```js echo
93+
Plot.plot({
94+
height: 260,
95+
color: {scheme: dark ? "turbo" : "blues"},
96+
marks: [
97+
Plot.rectY(
98+
olympians,
99+
Plot.binX(
100+
{y2: "count"},
101+
{
102+
x: "weight",
103+
fill: "weight",
104+
z: "sex",
105+
mixBlendMode: dark ? "screen" : "multiply"
106+
}
107+
)
108+
),
109+
Plot.ruleY([0])
110+
]
111+
})
112+
```

src/client/main.js

+1
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,7 @@ import * as sampleDatasets from "./stdlib/sampleDatasets.js";
77
const library = {
88
now: () => Generators.now(),
99
width: () => Generators.width(document.querySelector("main")),
10+
dark: () => Generators.dark(),
1011
resize: () => resize,
1112
FileAttachment: () => FileAttachment,
1213
Generators: () => Generators,

src/client/stdlib/generators/dark.ts

+13
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,13 @@
1+
import {observe} from "./observe.js";
2+
3+
// Watches dark mode based on theme and user preference.
4+
// TODO: in preview, also watch for changes in the theme meta.
5+
export function dark() {
6+
return observe((notify: (dark: boolean) => void) => {
7+
const media = matchMedia("(prefers-color-scheme: dark)");
8+
const changed = () => notify(getComputedStyle(document.body).getPropertyValue("color-scheme") === "dark");
9+
changed();
10+
media.addEventListener("change", changed);
11+
return () => media.removeEventListener("change", changed);
12+
});
13+
}

src/client/stdlib/generators/index.ts

+1
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,4 @@
1+
export {dark} from "./dark.js";
12
export {input} from "./input.js";
23
export {now} from "./now.js";
34
export {observe} from "./observe.js";

0 commit comments

Comments
 (0)