Skip to content

feat: color mode toggle (light/dark) — design discussion #1

Description

@ArthurData

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.

Metadata

Metadata

Assignees

No one assigned

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions