Aller au contenu

Les composants interactifs

Objectif : ajouter un accordéon, un menu déroulant et une modale de confirmation, sans aucun framework JavaScript.

Ce que vous allez apprendre : components/interactive.html s'appuie sur les éléments natifs <details> (accordéon, menu) et <dialog> (modale).
Fidèle à la charte : pas de magie, pas de dépendance JS imposée.

Accordéon (zéro JS)

{% from "components/interactive.html" import accordion %}

{% call accordion("Coordonnées détaillées") %}
  Adresse, téléphone et notes du contact.
{% endcall %}

L'ouverture et la fermeture sont natives (<details>), sans une ligne de JavaScript.

{% from "components/interactive.html" import dropdown, menu_item %}

{% call dropdown("Actions") %}
  {{ menu_item("Modifier", "/showcase") }}
  {{ menu_item("Archiver", "/showcase") }}
{% endcall %}

Modale de confirmation

La modale utilise l'élément natif <dialog> : un bouton l'ouvre via showModal() (méthode native, pas un framework), et le formulaire method="dialog" la ferme sans JavaScript.

{% from "components/interactive.html" import modal, modal_trigger %}

{{ modal_trigger("confirm-suppr", "Supprimer", variant="ghost") }}

{% call modal("confirm-suppr", "Confirmer la suppression") %}
  <p>Cette action est définitive.</p>
  <div class="mt-4 flex justify-end gap-2">
    <form method="dialog"><button class="px-4 py-2 text-sm">Annuler</button></form>
    <form method="post" action="/showcase/delete">
      {% include "partials/csrf.html" %}
      <button class="px-4 py-2 text-sm font-semibold text-white bg-teal rounded-[10px]">Supprimer</button>
    </form>
  </div>
{% endcall %}

Côté contrôleur, branchez la route de suppression (l'action <form> ci-dessus) :

    @staticmethod
    def delete(request: Request) -> Response:
        email = request.form("email", default="")
        _CONTACTS[:] = [c for c in _CONTACTS if c["email"] != email]
        return BaseController.redirect("/showcase", request=request, flash="Contact supprimé.")
public.add("POST", "/showcase/delete", ShowcaseController.delete, name="showcase-delete")

La modale confirme, le formulaire poste vers /showcase/delete, et le flash « Contact supprimé.
»
s'affiche au retour (via flash_messages).

À retenir
  • accordion et dropdown reposent sur <details> : zéro JavaScript.
  • modal repose sur <dialog> : ouverture via showModal() natif, fermeture via <form method="dialog">.
  • Les versions animées (htmx / alpine) relèveront d'un choix frontend séparé ; le squelette n'impose aucun framework.

Voir le bilan du parcours