Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Generators.dark(*element*) #1638

Draft
wants to merge 2 commits into
base: main
Choose a base branch
from
Draft

Generators.dark(*element*) #1638

wants to merge 2 commits into from

Conversation

Fil
Copy link
Contributor

@Fil Fil commented Sep 4, 2024

We add a CSS transition to the body’s color style and listen to transitionstart. (Trick found in https://github.com/bramus/style-observer.)

This enables us to listen when the actual color starts transitioning, and update dark based on the computed value of color-scheme.

Note that this works with any element within the body, so:

  1. if we want to ensure that the user has not added their own transition definitions to the body, we could use another element — or even create one on purpose.

  2. we can listen to dark mode changes inside a page, say if someone has a block that needs to be in a mode that is toggled separately from the main page, maybe for demonstration purposes. I don't know if that is useful enough in practice, but it doesn't take more code to support this, and it's more consistent with Generators.width(*element*). I've added such an example in the documentation—for testing purposes (I don't plan to ship this example in any case, but it could be documented in pangea as a side show).

If we think the transition might break or not work in all cases, we could keep listening to the user preference (media).

Here is a standalone (user land) version:

---
_theme: light
---

# dark transitions

```js
display(dark);
```

```js echo
const dark = Mutable(null);
const setDark = (value) => dark.value = value;
```

```js echo
const probe = document.body;
probe.style.setProperty("transition-property", "color");
probe.style.setProperty("transition-duration", "0.001s");
const update = () => setDark(getComputedStyle(probe)["color-scheme"]);
update();
probe.addEventListener("transitionstart", update);
invalidation.then(() => probe.removeEventListener("transitionstart", update));
```

closes #1339

@Fil Fil requested a review from mbostock September 4, 2024 07:54
@mbostock
Copy link
Member

mbostock commented Sep 4, 2024

This looks promising. The other thing that was hard about fixing #1339 is that even if we know that we’ve changed the stylesheets, there’s no event (as far as I can tell — load doesn’t work) that lets you listen for when the changed stylesheets have taken effect, at least other than this transitionstart technique that you’ve found. I’m wary of setting a transition on the body though. And technically this only works if color changes at the same time as color-scheme, which isn’t guaranteed. And since this only affects preview in practice I’m not that motivated… 😬

@Fil Fil mentioned this pull request Oct 18, 2024
15 tasks
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

Changing the page theme doesn’t update dark during preview
2 participants