Deep-Symmetry / bytefield-svg

Node module that generates byte field diagrams in SVG format
Eclipse Public License 2.0
126 stars 20 forks source link

Support automatic dark mode #45

Closed Timmmm closed 8 months ago

Timmmm commented 8 months ago

It would be nice if you could support automatic dark mode, like this:

<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 64 64">
   <style>
        path {
            fill: black;
        }
        @media (prefers-color-scheme: dark) {
            path { fill: white; }
        }
    </style>
    <path d="..."/>
</svg>

Unfortunately I couldn't find a way to insert arbitrary styles/CSS.

brunchboy commented 8 months ago

The place to investigate this is in the underlying libraries used to generate SVG. It may be possible to accomplish this without any changes to bytefield-svg itself, but if you find a clean enough way to do it (which doesn’t overcomplicate the project for a single feature) I would certainly consider a pull request.

brunchboy commented 8 months ago

Yes, you can call my append-svg function as the first drawing statement in your diagram to add a <style> tag at the start of the diagram, like so (this produces the exact content you desired above):

(append-svg [:style "
path {
    fill: black;
}
@media (prefers-color-scheme: dark) {
    path { fill: white; }
}"])

So once you know all the styles you want to set up to achieve your dark-mode support, this is how you can add them.

Timmmm commented 8 months ago

Ah sweet that works! Although in the end I went for inlining the SVG and using CSS styles with CSS variables:

/* Dark mode SVG. */
svg {
    fill: currentColor;
}

svg > line {
    stroke: currentColor;
}

/* SVG colours */

:root {
    --yellow: #ffffc0;
}

@media (prefers-color-scheme: dark) {
    :root {
        --yellow: #84840a;
    }
}
(defattrs :bg-yellow {:fill "var(--yellow)"})

Thanks!

brunchboy commented 8 months ago

Great, thanks for letting me know, @Timmmm! If you end up using it in a public-facing site, I would be happy if you could share your final code with me, so I can add it as an example to the user guide with a link to your site. I expect other people will be interested in how to do this.