terrastruct / d2

D2 is a modern diagram scripting language that turns text to diagrams.
https://d2lang.com
Mozilla Public License 2.0
16.19k stars 402 forks source link

Automatic dark mode #831

Open nhooyr opened 1 year ago

nhooyr commented 1 year ago

It would be really nice if the SVGs could be embedded into blogs/documentation and automatically adjust their theme to become dark if the user is on dark mode.

nhooyr commented 1 year ago

Example of what I'd like to avoid:

image

From https://github.com/nhooyr/flappy-bird

alixander commented 1 year ago

https://github.com/terrastruct/d2/pull/613 implements this. it replaces the hardcoded theme colors with css classes like THEME_NEUTRAL_1, and then uses media queries to determine which css color to load. it's nearly there, but the author's back in school or something so i gotta take it over one of these days

vfosnar commented 1 year ago

this can be closed @alixander

nhooyr commented 1 year ago

@alixander Just tested latest master and it doesn't seem to work for me. Remains in light even if I change system to dark mode. Not sure if we didn't add a @media (prefers-color-scheme: dark ) { somewhere.

vfosnar commented 1 year ago

@nhooyr have you tried using these flags

d2 --theme 0 --dark-theme 200 ...
nhooyr commented 1 year ago

Works now, beautiful!

Screenshot 2023-02-24 at 3 43 58 AM

Is there any reason that --dark-theme isn't enabled by default? If we're using meda queries to determine which to render it seems reasonable to have it on by default @alixander

vfosnar commented 1 year ago

I think the only thing is that it is not an expected behavior for many users. Also rendering a PNG will always warn about dark theme being ignored

nhooyr commented 1 year ago

I think the only thing is that it is not an expected behavior for many users.

It's only unexpected because we didn't do it from the start. But now it seems like a strictly better behaviour.

And we should get rid of that warning unless they explicitly pass --dark-theme in which case pngs should be dark too.

alixander commented 1 year ago

But now it seems like a strictly better behaviour.

nah i don't think so. some diagrams make style changes based on the theme staying the way it is. e.g. a color that pairs with the color of their theme. once it switches it dark, it'll look ugly. we can invert the color, as suggested here, https://github.com/terrastruct/d2/issues/885. but i'm not sure how that'll end up looking without testing.

the user should explicitly pass so they don't get surprised their diagram doesn't look a certain way for dark mode users.

nhooyr commented 1 year ago

Why do we need to invert the color? Why can't all themes be required to define the same number of colors? And if more colors are defined, why can't we have a reasonable fallback? This is what Vim/VS Code et all do.

the user should explicitly pass so they don't get surprised their diagram doesn't look a certain way for dark mode users.

Themes are purely aesthetic, I strongly believe the viewers aesthetic overrules the presentor. I can't see a single situation where someone would actually want to lock their users into a light theme unless they were sadistic.

alixander commented 1 year ago

Why do we need to invert the color?

if you defined your label color to be dark, expecting it to be paired with the bright background.

Why can't all themes be required to define the same number of colors?

I'm not talking about inverting themed colors. I'm talking about when users define style.stroke: maroon.

Themes are purely aesthetic

Yeah that's all good, and ofc I agree, if a user prefers dark, forcing them to look at a bright diagram is not good. But the alternative is looking at a diagram which is not legible, when the contrast of colors literally just makes it unreadable, because of custom styles defined when the author's light theme is on.

nhooyr commented 1 year ago

Yeah that's all good, and ofc I agree, if a user prefers dark, forcing them to look at a bright diagram is not good. But the alternative is looking at a diagram which is not legible, when the contrast of colors literally just makes it unreadable, because of custom styles defined when the author's light theme is on.

You missed my point. We can just override their style rules for now until we have syntax to let them specify dark mode styles too. That's the reasonable default.

nhooyr commented 1 year ago

By override I mean stick with the dark mode theme color. Sure the colors may be semantic but if they are and the viewer sees a legend or something, users could just ask them to ensure they're in light mode. Which 99% of the time will not happen.

alixander commented 1 year ago

ohh i see.

that'll require some code changes. some !importants thrown in to dark mode theming.

i'm still not bullish on that change, but I'm not opposed.

I know dark mode is a sacred thing to dark mode enjoyers, but I just don't like the unexpected nature of it. We can document it all we want, but users will be building a diagram up, the entire time seeing it from their system theme, and probably expecting it to be viewed that way. Like how 95% of web devs expect when they build their sites. Nowadays it's a little more common knowledge that browsers will change CSS for dark mode preference, but that expectation won't carry over to our diagrams.

If you're a strong believer this is the way, I'm fine with it.

nhooyr commented 1 year ago

I know dark mode is a sacred thing to dark mode enjoyers, but I just don't like the unexpected nature of it. We can document it all we want, but users will be building a diagram up, the entire time seeing it from their system theme, and probably expecting it to be viewed that way. Like how 95% of web devs expect when they build their sites. Nowadays it's a little more common knowledge that browsers will change CSS for dark mode preference, but that expectation won't carry over to our diagrams.

It's not unexpected in the least. It only applies if you have dark mode enabled, like many websites/apps these days. It's becoming the way of the times.

Yes I'm extremely strong believer that this is the way.

I don't understand why you'd need !important though? Wouldn't it be as simple as having a default theme on the --dark-theme flag?

nhooyr commented 1 year ago

We can document it all we want, but users will be building a diagram up, the entire time seeing it from their system theme, and probably expecting it to be viewed that way. Like how 95% of web devs expect when they build their sites. Nowadays it's a little more common knowledge that browsers will change CSS for dark mode preference, but that expectation won't carry over to our diagrams.

Lol sorry didn't read the whole thing. Ok I see you addressed my point at the bottom there. It may not yet but we should be the trendsetter then, after us, everyone will wonder why diagrams from other tools don't.

nhooyr commented 1 year ago

Also this doesn't preclude a flag to force a specific theme. Like --force-light-theme and --force-dark-theme.

alixander commented 1 year ago

I don't understand why you'd need !important though? Wouldn't it be as simple as having a default theme on the --dark-theme flag?

We slap on class="[color code like N1]" and then include a stylesheet for unstyled elements, otherwise it's style="red" or whatever color you chose. to have this work, we'd have to include both, and just make dark mode's N1 !important.

It may not yet but we should be the trendsetter then, after us, everyone will wonder why diagrams from other tools don't.

my man.

alixander commented 1 year ago

Also this doesn't preclude a flag to force a specific theme. Like --force-light-theme and --force-dark-theme.

no need, just give the same theme ID for light-theme and dark-theme

nhooyr commented 1 year ago

We slap on class="[color code like N1]" and then include a stylesheet for unstyled elements, otherwise it's style="red" or whatever color you chose. to have this work, we'd have to include both, and just make dark mode's N1 !important.

Still not sure what you mean. I don't want dark theme to be default all the time? Light should be the default when no media query is present.

no need, just give the same theme ID for light-theme and dark-theme

clever. Oh we do need --default-theme though where if the browser has no preference for color, that theme is used. then someone could specify I want dark if my user has no preference.

alixander commented 1 year ago

Still not sure what you mean. I don't want dark theme to be default all the time? Light should be the default when no media query is present.

.N1 class normally won't have !important, so the custom style wins. .N1 class under @media prefers-dark-mode will, so it will win

Oh we do need --default-theme

why wouldn't we just treat theme as that? they can pass in a dark theme if they want

bo-ku-ra commented 1 year ago

i think depends on how the d2 output svg is used.

case 1. It is used like one of the homepage's images -> depends on the user's light/dark mode

case 2. it is a document on its own -> it should be displayed in the writer's colouring

i mainly use d2 in case 2.

nhooyr commented 1 year ago

.N1 class normally won't have !important, so the custom style wins. .N1 class under https://github.com/media prefers-dark-mode will, so it will win

Oh I see.

why wouldn't we just treat theme as that? they can pass in a dark theme if they want

If a writer prefers their diagram to be rendered in a dark theme in the absence of a theme preference but doesn't mind if it switches to a light theme if that's what the viewer prefers.

It sounds convulated but people will want it when their blog is dark theme by default and only switches to light if the media query prefers-color-scheme: light activates. i.e the opposite of light default and switch to dark.

nhooyr commented 1 year ago

case 2. it is a document on its own -> it should be displayed in the writer's colouring

We'll have support for setting dark mode style settings eventually in d2 itself so there's no reason you couldn't always be effectively in the writer's coloring.

e.g. maybe style.dark-theme.whatever @alixander?

alixander commented 1 year ago

that'd be so much work to support. i don't want to do that. dark-style would be a be the least-work approach to it. though it'd still be quite a bit.

in general i think this is low enough in priority that we should pocket it for the immediate future. we'll consider having a default dark mode though. i'll see if @katwangy can whip up a default dark mode i'd be excited about to include as everyone's default

nhooyr commented 1 year ago

that'd be so much work to support. i don't want to do that. dark-style would be a be the least-work approach to it. though it'd still be quite a bit.

Why would it be so much work if it's just a matter of shifting which css is under a media query?

in general i think this is low enough in priority that we should pocket it for the immediate future. we'll consider having a default dark mode though. i'll see if @katwangy can whip up a default dark mode i'd be excited about to include as everyone's default

I really like the current dark mode @vfosnar made. Though I'm sure @katwangy will make one even nicer.

nhooyr commented 1 year ago

dark-style would be a be the least-work approach to it. though it'd still be quite a bit.

Neither of them are mutually exclusive?

alixander commented 1 year ago

the css part is easy. the compiler and d2oracle considerations are much. especially with another level of nesting as you suggested.

yeah i don't think it's bad, which is why i'm okay with it being our only dark mode currently. but it's committal to have it be the default everyone's will be in, and i'd want to see if @katwangy has something better

nhooyr commented 1 year ago

the compiler and d2oracle considerations are much. especially with another level of nesting as you suggested.

We don't have to build out dark mode integration with the GUI yet though. That's independant of this issue.

the compiler

Should be very easy with my refactoring of the compiler. We already have all the code sectioned out because we use it separately for fields and edges to a largely similar extent.

yeah i don't think it's bad, which is why i'm okay with it being our only dark mode currently. but it's committal to have it be the default everyone's will be in, and i'd want to see if @katwangy has something better

Sounds good.

nhooyr commented 1 year ago

I just realized this is just a narrow case of the more general problem that all style.* keys are likely theme dependant.

Thus I propose we instead tie themes to diagrams instead of to the CLI. So you would have to define the theme you want the diagram to render as in the diagram via say top level theme: and top level dark-theme:. This way your guaranteed that no matter who renders your diagram, it will render as you intend.

obv more things to detail here about how it'll work but that's the general gist.

alixander commented 1 year ago

This way your guaranteed that no matter who renders your diagram, it will render as you intend.

i don't think this is a property we should care about. what about --sketch, --pad, or in the future, fonts? people should be free to render the same model differently.

vfosnar commented 1 year ago

Edit: I reread the convo and I understand the problem now.

Also yeah, I don't think all style properties are dependant on the theme but user-defined colors are.

nhooyr commented 1 year ago

i don't think this is a property we should care about. what about --sketch, --pad, or in the future, fonts? people should be free to render the same model differently.

Sure they should be able to but like @vfosnar mentioned I'm purely referring to colors. Colors only work in the context of a specific theme and simply do not work otherwise.

nhooyr commented 1 year ago

They should still be able to override the theme if they want but it's not the primary way themes should be set because colors can be semantic enough to diagrams to matter. As long as we support letting a diagram define a light theme and a dark theme and style. colors to go with each.

bo-ku-ra commented 1 year ago

i'm beginning to think we should discuss this issue after we have a transparent background... (#663) i would use the same theme for both LIGHT and DARK if it felt moderate.