posit-dev / py-shinyswatch

Bootswatch themes for py-shiny
https://posit-dev.github.io/py-shinyswatch/
MIT License
28 stars 3 forks source link

refactor: Avoid needing to directly inspect shiny's `bootstrap_deps()` #32

Closed gadenbuie closed 7 months ago

gadenbuie commented 7 months ago

This PR is pre-work for posit-dev/py-shiny#1282 to avoid errors in Shiny's test suite caused by shinyswatch's assumptions about the now changing structure of bootstrap_deps().

The primary goal is to avoid having to inspect the Bootstrap dependencies provided by Shiny. Instead, we suppress the bootstrap, bootstrap-js and bootstrap-css dependencies in shinyswatch's html dependency.

In posit-dev/py-shiny#1282, Shiny's Bootstrap dependency will switch to bootstrap-js, bootstrap-css and bootstrap-meta, which can be suppressed with a new helper function shiny.ui._html_deps_external.bootstrap_deps_suppress().

The goal of posit-dev/py-shiny#1282 is to introduce shiny.ui.include_bootstrap_css() that could be used by shinyswatch in the future, although it's not strictly required. The approach used by include_bootstrap_css() is quite similar to the one taken here, except that its stated goal is to replace only the CSS and not the entire Bootstrap bundle. That function will also provide additional runtime checks to make sure that Shiny's Bootstrap is compatible.

In a future PR, I'll come back to shinyswatch and explore using the new function. In the mean time, the approach in this PR should work for both current and the expected future implementation in Shiny. As long as this PR doesn't break shinyswatch, I'd like to merge this so that work in Shiny can be tested.

New naming of shinyswatch dependency

The core shinyswatch deps are now named shinyswatch-js and shinyswatch-css. This way, if multiple themes are added, only one bootstrap.bundle.min.js and one bootswatch.min.css are ever loaded.

Re-worked theme picker

The theme picker now uses a separate HTMLDependency to load all of the themes at once. New JavaScript switches themes by replacing the initial theme with a new <link>. We actually add the new CSS and then remove the previous CSS with a slight delay, resulting in a smooth transition between themes.

https://github.com/posit-dev/py-shinyswatch/assets/5420529/80339c35-cdb9-4745-85e0-2c0b741f128f

gadenbuie commented 7 months ago

Moving back to draft temporarily... I'll have a better approach shortly and have a plan to improve the theme picker while I'm here.