feat(logo): Add .to_html()
method for logo resources
#62
Add this suggestion to a batch that can be applied as a single commit.
This suggestion is invalid because no changes were made to the code.
Suggestions cannot be applied while the pull request is closed.
Suggestions cannot be applied while viewing a subset of changes.
Only one suggestion per line can be applied in a batch.
Add this suggestion to a batch that can be applied as a single commit.
Applying suggestions on deleted lines is not supported.
You must change the existing code in this line in order to create a valid suggestion.
Outdated suggestions cannot be applied.
This suggestion has been applied or marked resolved.
Suggestions cannot be applied from pending reviews.
Suggestions cannot be applied on multi-line comments.
Suggestions cannot be applied while the pull request is queued to merge.
Suggestion cannot be applied right now. Please check back later.
Adds a
.to_html()
method tobrand_yml.BrandLogo
,brand_yml.BrandLogoResource
andbrand_yml.BrandLogoLightDarkResource
(all variants ofbrand.logo
,brand.logo.{small, medium, large}
) to help create an<img>
tag or a pair of<img>
tags in the light/dark variant case.When an image includes light/dark variants, we include both images with an additional
data-when-theme="light"
attribute (ordata-when-theme="dark"
) along with inline CSS to hide the light or dark variant when in the opposite color scheme. By default, we use selectors optimized for Quarto and Shiny, but these are customizable via theselectors
optionNotes
There are two design wrinkles in this feature that were helpfully noted in this discussion:
That would certainly work for Shiny – where
data-bs-theme="dark"
signals dark mode – but we also need.quarto-dark
for Quarto scenarios, at least until Quarto uses Bootstrap's newer color mode features.But the real reason I'm not using global CSS is because neither of these approaches work with
@media (prefers-color-scheme: "dark")
in the sense that if the global CSS included rules that use media queries to choose the color scheme, those rules will conflict with the directly-signaled color mode. E.g.: if the OS is set to dark color mode but the page or app is set to light, the light image would be hidden by the media query rules and the dark image would be hidden by the local app setting.Both
data-bs-theme
and.quarto-{dark,light}
are framework-specific color mode signals, but the media query is native web and available in all browsers. Obviously, we're focusing our efforts on developing brand.yml for Quarto and Shiny users, but I want it to be useful anywhere. That means we need users to be able to opt into followingprefers-color-scheme
or to choose their own selectors. That of course then leads to the need for each call tologo.small.to_html()
to work separately – it'd be very confusing if making one call to.to_html()
affected the other uses of the method.Anyway, I very much wanted this to work with a single set of CSS rules but ended up with the inline CSS out of necessity.
Great catch with this as well! I also wanted to use
static_assets
, but unfortunately the way that it works in Shiny for Python makes it available to app authors but not for third-party extension developers. In other words, you as the app author can certainly add something likestatic_assets={"brand": brand.path.parent}
, but I can't register the static directory from the.to_html()
method automatically for the user. (In other words, we don't have a Python equivalent to theshiny::addResourcePath()
that exists in Shiny for R.)I briefly tried using
htmltools.HTMLDependency()
but this isn't a great approach for including static assets because the dependency creator can't control the location of the hosted assets. (I may raise this a feature request.)Ultimately, base64-encoding will work anywhere that HTML is used (i.e. out of the box in Quarto, Shiny, and any other framework that can handle HTML). There a few tradeoffs – it'd certainly be more efficient to host a single file, especially if you re-use the same logo in many places – but the transportability is worth it (for now, I'll still keep thinking about higher-level fixes for this issue).