Contexte
Bootstrap 5.3 introduit les color modes via l'attribut
data-bs-theme sur
<html> (ou tout conteneur). hx_bs_page(color_mode = "dark")
permet déjà de
définir le mode initial côté serveur.
htmxr.bootstrap doitil fournir un mécanisme pour basculer entre les modes à l'exécution ?
Mécanisme Bootstrap
Le toggle se résume à changer data-bs-theme à l'exécution :
document.documentElement.setAttribute('data-bs-theme', 'dark')
Options envisagées
Option A — Alpine.js via alpiner (split écosystème propre)
hx_bs_page(
html_attrs = list(
"x-data" = "{ theme: localStorage.getItem('theme') ||
'light' }",
":data-bs-theme" = "theme"
),
tags$button(
"@click" = "theme = theme === 'light' ? 'dark' : 'light';
localStorage.setItem('theme', theme)",
"Toggle theme"
)
)
alpiner gère l'état réactif, htmxr.bootstrap génère uniquement le HTML Bootstrap. Séparation des responsabilités claire.
- Avantages : idiomatique pour l'écosystème, pas de JS dans
htmxr.bootstrap
- Inconvénients : requiert alpiner dans l'app
Option B — hx_bs_color_mode_toggle() avec vanilla JS
Une fonction qui génère un bouton Bootstrap + injecte un <script> minimal :
hx_bs_color_mode_toggle <- function(label_light = "Light",
label_dark = "Dark", ...) {
# bouton + script localStorage autonome
}
Pas de dépendance Alpine, zéro round-trip serveur.
- Avantages : autonome, aligné sur les exemples Bootstrap docs officiels
- Inconvénients : htmxr.bootstrap embarque du JS inline (hors scope core)
Option C — htmx server-side
[clic bouton] → GET /set-theme?mode=dark → cookie → full page
re-render
Persiste côté serveur. Mais re-rend toute la page à chaque toggle. /!\ lourd
Position actuelle
Responsabilité: Mode initial au chargement
Package: htmxr.bootstrap (color_mode param) ✅
────────────────────────────────────────
Responsabilité: État réactif client (toggle)
Package: alpiner
────────────────────────────────────────
Responsabilité: Persistance (cookie/session)
Package: l'app
La philosophie de htmxr.bootstrap est CSS/HTML — pas JS.
Le toggle runtime implique du JS, ce qui est la frontière naturelle du package.
L'Option B reste légitime si on considère qu'un wrapper Bootstrap complet (à la bslib) devrait proposer un dark mode switcher clé-en-main.
À réfléchir.
Contexte
Bootstrap 5.3 introduit les color modes via l'attribut
data-bs-themesur<html>(ou tout conteneur).hx_bs_page(color_mode = "dark")permet déjà de
définir le mode initial côté serveur.
htmxr.bootstrapdoitil fournir un mécanisme pour basculer entre les modes à l'exécution ?Mécanisme Bootstrap
Le toggle se résume à changer
data-bs-themeà l'exécution :Options envisagées
Option A — Alpine.js via alpiner (split écosystème propre)
alpinergère l'état réactif, htmxr.bootstrap génère uniquement le HTML Bootstrap. Séparation des responsabilités claire.htmxr.bootstrap
Option B — hx_bs_color_mode_toggle() avec vanilla JS
Une fonction qui génère un bouton Bootstrap + injecte un
<script>minimal :Pas de dépendance Alpine, zéro round-trip serveur.
Option C — htmx server-side
Persiste côté serveur. Mais re-rend toute la page à chaque toggle. /!\ lourd
Position actuelle
Responsabilité: Mode initial au chargement
Package: htmxr.bootstrap (color_mode param) ✅
────────────────────────────────────────
Responsabilité: État réactif client (toggle)
Package: alpiner
────────────────────────────────────────
Responsabilité: Persistance (cookie/session)
Package: l'app
La philosophie de htmxr.bootstrap est CSS/HTML — pas JS.
Le toggle runtime implique du JS, ce qui est la frontière naturelle du package.
L'Option B reste légitime si on considère qu'un wrapper Bootstrap complet (à la bslib) devrait proposer un dark mode switcher clé-en-main.
À réfléchir.