Loaders, skeleton screens, overlays et indicateurs HTMX pour Django.
Project description
xeolux-loadingkit
Package Django léger pour ajouter des loaders, skeleton screens, overlays, toasts et indicateurs HTMX dans n'importe quel projet.
Fait partie de la suite Xeolux — packages Django minimalistes et réutilisables.
Fonctionnalités
| Template tag | Description |
|---|---|
{% xeolux_loadingkit_css %} |
Injecte la feuille CSS du package |
{% xeolux_loadingkit_js %} |
Injecte le JS optionnel (XeoluxLoadingKit API) |
{% xeolux_loader %} |
Spinner animé (sm / md / lg) avec texte optionnel |
{% xeolux_overlay %} |
Overlay plein écran avec backdrop blur |
{% xeolux_skeleton %} |
Skeleton shimmer — 15 types |
{% xeolux_htmx_indicator %} |
Indicateur compatible HTMX |
{% xeolux_progress %} |
Barre de progression déterminée |
{% xeolux_topbar %} |
Barre fine en haut de page (style NProgress) |
{% xeolux_toast %} |
Notification toast (info / success / warning / error) |
Tout composant accepte un paramètre theme="dark" ou theme="light" pour forcer le thème localement, indépendamment du système.
Installation
pip install xeolux-loadingkit
Ajout dans INSTALLED_APPS
# settings.py
INSTALLED_APPS = [
...
"xeolux_loadingkit",
]
django.contrib.staticfilesdoit également être présent (il l'est par défaut).
Utilisation
1. Injecter le CSS (et le JS optionnel)
{% load xeolux_loadingkit %}
<head>
{% xeolux_loadingkit_css %}
</head>
<body>
...
{% xeolux_loadingkit_js %} {# optionnel — active l'API XeoluxLoadingKit #}
</body>
2. Loader (spinner)
{% xeolux_loader %}
{% xeolux_loader size="sm" %}
{% xeolux_loader size="lg" text="Veuillez patienter" %}
{% xeolux_loader size="md" theme="dark" %}
| Paramètre | Type | Défaut | Description |
|---|---|---|---|
size |
str |
"md" |
"sm", "md" ou "lg" |
text |
str|None |
None |
Texte à côté du spinner |
theme |
str|None |
None |
"dark" ou "light" pour forcer le thème |
3. Overlay
{% xeolux_overlay %}
{% xeolux_overlay text="Traitement en cours..." active=True %}
// Via JS — ou avec {% xeolux_loadingkit_js %}
XeoluxLoadingKit.overlay.show("Sauvegarde...");
XeoluxLoadingKit.overlay.hide();
| Paramètre | Type | Défaut | Description |
|---|---|---|---|
text |
str |
"Chargement en cours..." |
Texte de l'overlay |
active |
bool |
False |
Visible au rendu |
theme |
str|None |
None |
"dark" ou "light" |
4. Skeleton — 15 types
{% xeolux_skeleton %} {# text #}
{% xeolux_skeleton type="card" %}
{% xeolux_skeleton type="avatar" %}
{% xeolux_skeleton type="table" lines=4 rows=5 %}
{% xeolux_skeleton type="form" lines=3 %}
{% xeolux_skeleton type="list" lines=5 %}
{% xeolux_skeleton type="list-detail" lines=4 %} {# avatar + titre + sous-titre + meta #}
{% xeolux_skeleton type="image" format="portrait" %}
{% xeolux_skeleton type="nav" %}
{% xeolux_skeleton type="footer" lines=4 %}
{% xeolux_skeleton type="dashboard" lines=3 %}
{% xeolux_skeleton type="product" %}
{% xeolux_skeleton type="profile" %}
{% xeolux_skeleton type="hero" lines=2 %} {# section hero pleine largeur #}
{% xeolux_skeleton type="sidebar" lines=6 %} {# navigation latérale #}
| Paramètre | Type | Défaut | Description |
|---|---|---|---|
type |
str |
"text" |
15 types — voir ci-dessus |
lines |
int |
3 |
Lignes / items selon le type (1–20) |
rows |
int |
4 |
Rangées pour "table" (1–50) |
format |
str |
"landscape" |
Format image : "square", "landscape", "portrait", "panoramic", "thumbnail" |
theme |
str|None |
None |
"dark" ou "light" |
5. Indicateur HTMX
<button hx-post="/save/" hx-indicator="#xeolux-htmx-loader">
Enregistrer
</button>
{% xeolux_htmx_indicator text="Enregistrement..." %}
| Paramètre | Type | Défaut | Description |
|---|---|---|---|
text |
str |
"Chargement..." |
Texte pendant la requête |
theme |
str|None |
None |
"dark" ou "light" |
6. Barre de progression
{% xeolux_progress value=65 label="Upload" %}
{% xeolux_progress value=80 striped=True animated=True %}
{% xeolux_progress value=100 animated=False %}
| Paramètre | Type | Défaut | Description |
|---|---|---|---|
value |
int|float |
0 |
Valeur 0–100 |
label |
str|None |
None |
Texte au-dessus de la barre |
animated |
bool |
True |
Effet shimmer |
striped |
bool |
False |
Motif rayé |
theme |
str|None |
None |
"dark" ou "light" |
7. Topbar
{# Rendu dans le <body> — invisible par défaut #}
{% xeolux_topbar %}
{# Déterminé — progression à 60% #}
{% xeolux_topbar active=True value=60 %}
// Via JS (nécessite {% xeolux_loadingkit_js %})
XeoluxLoadingKit.topbar.start(); // indéterminé (s'arrête à 90%)
XeoluxLoadingKit.topbar.set(70); // progression déterminée
XeoluxLoadingKit.topbar.done(); // 100% puis disparaît
XeoluxLoadingKit.topbar.reset(); // réinitialise silencieusement
| Paramètre | Type | Défaut | Description |
|---|---|---|---|
active |
bool |
False |
En cours de chargement |
done |
bool |
False |
Complété — disparaît après 700 ms |
animated |
bool |
True |
Effet shimmer |
value |
int|float|None |
None |
Progression déterminée 0–100 |
theme |
str|None |
None |
"dark" ou "light" |
8. Toast
{# Dans un template Django — rendu statique #}
{% xeolux_toast message="Sauvegardé !" type="success" %}
{% xeolux_toast message="Erreur réseau." type="error" dismissible=False %}
{% xeolux_toast message="Mise à jour disponible." type="info" %}
{% xeolux_toast message="Vérifiez vos données." type="warning" theme="dark" %}
// Via JS (nécessite {% xeolux_loadingkit_js %})
XeoluxLoadingKit.toast.show("Sauvegardé !", "success");
XeoluxLoadingKit.toast.show("Erreur réseau", "error", { duration: 6000 });
XeoluxLoadingKit.toast.show("Info", "info", { dismissible: false });
| Paramètre | Type | Défaut | Description |
|---|---|---|---|
message |
str |
"" |
Texte de la notification |
type |
str |
"info" |
"info", "success", "warning", "error" |
dismissible |
bool |
True |
Bouton de fermeture |
theme |
str|None |
None |
"dark" ou "light" |
Exemple Django complet (avec HTMX)
views.py
from django.views.generic import TemplateView
from django.http import HttpResponse
import time
class DashboardView(TemplateView):
template_name = "dashboard.html"
def save_profile(request):
# Simule un traitement
time.sleep(0.5)
return HttpResponse('<p id="result" class="text-green-600">Profil sauvegardé !</p>')
dashboard.html
{% load xeolux_loadingkit %}
<!DOCTYPE html>
<html lang="fr">
<head>
<meta charset="UTF-8">
{% xeolux_loadingkit_css %}
<script src="https://unpkg.com/htmx.org@1.9.12"></script>
</head>
<body>
{# Topbar — initialisée par JS #}
{% xeolux_topbar %}
{# Overlay — contrôlé par JS ou HTMX events #}
{% xeolux_overlay text="Chargement du tableau de bord..." %}
{# Contenu principal #}
<main>
<h1>Tableau de bord</h1>
{# Skeleton affiché pendant le chargement (swappé par HTMX) #}
<div id="stats"
hx-get="/api/stats/"
hx-trigger="load"
hx-indicator="#xeolux-htmx-loader">
{% xeolux_skeleton type="dashboard" lines=4 %}
</div>
{# Formulaire avec barre de progression #}
<form hx-post="/save-profile/"
hx-target="#result"
hx-on::before-request="XeoluxLoadingKit.topbar.start()"
hx-on::after-request="XeoluxLoadingKit.topbar.done()">
{% csrf_token %}
<input type="text" name="name">
<button type="submit">Sauvegarder</button>
</form>
<div id="result"></div>
{# Indicateur HTMX #}
{% xeolux_htmx_indicator text="Enregistrement..." %}
</main>
{% xeolux_loadingkit_js %}
<script>
// Démarrer la topbar au chargement de la page
document.addEventListener("DOMContentLoaded", function () {
XeoluxLoadingKit.topbar.start();
window.addEventListener("load", function () {
XeoluxLoadingKit.topbar.done();
});
});
</script>
</body>
</html>
Personnalisation CSS
:root {
--xlk-primary: #3b6cf7; /* Couleur principale */
--xlk-bg: #ffffff; /* Fond des composants */
--xlk-muted: #e2e6f0; /* Fond des skeletons / track */
--xlk-text: #374151; /* Couleur du texte */
--xlk-overlay-bg: rgba(15, 20, 40, 0.55);
--xlk-radius: 0.5rem; /* Border-radius global */
--xlk-speed: 0.7s; /* Vitesse des animations */
--xlk-font: inherit; /* Police des composants */
}
Le dark mode est automatique via prefers-color-scheme: dark.
Pour forcer un thème sur un composant, utilisez le paramètre theme="dark" ou theme="light".
API JavaScript (XeoluxLoadingKit)
Disponible après {% xeolux_loadingkit_js %} :
// Topbar
XeoluxLoadingKit.topbar.start() // démarrer (indéterminé, s'arrête à 90%)
XeoluxLoadingKit.topbar.set(70) // progression à 70%
XeoluxLoadingKit.topbar.done() // 100% + disparaît
XeoluxLoadingKit.topbar.reset() // réinitialiser silencieusement
// Overlay
XeoluxLoadingKit.overlay.show() // afficher
XeoluxLoadingKit.overlay.show("Sauvegarde...") // avec texte
XeoluxLoadingKit.overlay.hide() // masquer
// Toast
XeoluxLoadingKit.toast.show("Sauvegardé !", "success")
XeoluxLoadingKit.toast.show("Erreur", "error", { duration: 6000 })
XeoluxLoadingKit.toast.show("Info", "info", { dismissible: false })
// duration=0 → toast permanent (dismissible seulement)
Lancer les tests
pip install -e ".[dev]"
python -m pytest tests/ -v
Build & Publication PyPI
pip install build twine
rm -rf dist/ build/ *.egg-info
python -m build
twine check dist/*
twine upload dist/*
Structure du projet
xeolux-loadingkit/
├── .github/workflows/ci.yml ← CI GitHub Actions
├── xeolux_loadingkit/
│ ├── __init__.py
│ ├── apps.py
│ ├── py.typed ← PEP 561 type marker
│ ├── templatetags/
│ │ └── xeolux_loadingkit.py ← 9 template tags
│ ├── templates/xeolux_loadingkit/
│ │ ├── loader.html
│ │ ├── overlay.html
│ │ ├── skeleton.html ← 15 types
│ │ ├── htmx_indicator.html
│ │ ├── progress.html
│ │ ├── topbar.html
│ │ └── toast.html
│ └── static/xeolux_loadingkit/
│ ├── css/loadingkit.css
│ └── js/loadingkit.js ← API JS optionnelle
├── tests/test_template_tags.py
├── demo/index.html
├── CHANGELOG.md
├── README.md
├── pyproject.toml
├── LICENSE
└── MANIFEST.in
Compatibilité
| Django | Python |
|---|---|
| 4.2 | 3.10, 3.11, 3.12 |
| 5.0 | 3.10, 3.11, 3.12 |
| 5.1 | 3.10, 3.11, 3.12 |
Licence
MIT © Xeolux
Fonctionnalités
| Template tag | Description |
|---|---|
{% xeolux_loadingkit_css %} |
Injecte la feuille CSS du package |
{% xeolux_loader %} |
Spinner animé (sm / md / lg) avec texte optionnel |
{% xeolux_overlay %} |
Overlay plein écran avec backdrop blur |
{% xeolux_skeleton %} |
Skeleton shimmer (text / card / avatar / table / form) |
{% xeolux_htmx_indicator %} |
Indicateur compatible HTMX |
Installation
pip install xeolux-loadingkit
Ajout dans INSTALLED_APPS
# settings.py
INSTALLED_APPS = [
...
"xeolux_loadingkit",
]
django.contrib.staticfilesdoit également être présent (il l'est par défaut).
Utilisation
1. Injecter le CSS
Placez ce tag dans le <head> de votre template de base, après avoir chargé la bibliothèque :
{% load xeolux_loadingkit %}
<head>
{% xeolux_loadingkit_css %}
</head>
2. Loader (spinner)
{# Taille par défaut (md) #}
{% xeolux_loader %}
{# Avec taille et texte #}
{% xeolux_loader size="sm" %}
{% xeolux_loader size="md" text="Chargement..." %}
{% xeolux_loader size="lg" text="Veuillez patienter" %}
Paramètres :
| Paramètre | Type | Défaut | Description |
|---|---|---|---|
size |
str |
"md" |
"sm", "md" ou "lg" |
text |
str|None |
None |
Texte affiché à côté du spinner |
3. Overlay
{# Overlay inactif (caché) #}
{% xeolux_overlay %}
{# Overlay actif (visible) #}
{% xeolux_overlay text="Traitement en cours..." active=True %}
Pour l'activer dynamiquement via JavaScript :
document.querySelector('.xlk-overlay').classList.add('xlk-overlay--active');
Paramètres :
| Paramètre | Type | Défaut | Description |
|---|---|---|---|
text |
str |
"Chargement en cours..." |
Texte de l'overlay |
active |
bool |
False |
Si True, l'overlay est visible au chargement |
4. Skeleton
{# Texte (défaut) #}
{% xeolux_skeleton %}
{% xeolux_skeleton type="text" lines=4 %}
{# Card #}
{% xeolux_skeleton type="card" %}
{# Avatar #}
{% xeolux_skeleton type="avatar" %}
{# Tableau #}
{% xeolux_skeleton type="table" lines=4 rows=5 %}
{# Formulaire #}
{% xeolux_skeleton type="form" lines=3 %}
Paramètres :
| Paramètre | Type | Défaut | Description |
|---|---|---|---|
type |
str |
"text" |
"text", "card", "avatar", "table", "form" |
lines |
int |
3 |
Nombre de lignes (text / form) ou colonnes (table) |
rows |
int |
4 |
Nombre de lignes pour le type "table" |
5. Indicateur HTMX
{% xeolux_htmx_indicator text="Chargement..." %}
L'indicateur est masqué par défaut et devient visible pendant une requête HTMX grâce à la classe .htmx-indicator standard.
Exemple complet avec HTMX
<button
hx-post="/save/"
hx-target="#result"
hx-indicator="#xeolux-htmx-loader">
Enregistrer
</button>
{% xeolux_htmx_indicator text="Enregistrement..." %}
Paramètres :
| Paramètre | Type | Défaut | Description |
|---|---|---|---|
text |
str |
"Chargement..." |
Texte affiché pendant la requête |
Personnalisation CSS
Toutes les valeurs visuelles sont contrôlées par des variables CSS. Surchargez-les dans votre propre feuille de style :
:root {
--xlk-primary: #3b6cf7; /* Couleur principale (spinner, accents) */
--xlk-bg: #ffffff; /* Fond de l'overlay intérieur */
--xlk-muted: #e2e6f0; /* Fond des skeletons et du spinner */
--xlk-text: #374151; /* Couleur du texte */
--xlk-overlay-bg: rgba(15, 20, 40, 0.55); /* Fond de l'overlay plein écran */
--xlk-radius: 0.5rem; /* Border-radius global */
--xlk-speed: 0.7s; /* Vitesse des animations */
}
Tester dans un projet Django
- Installez le package en mode éditable depuis la racine du repo :
pip install -e /chemin/vers/xeolux-loadingkit
-
Ajoutez
"xeolux_loadingkit"dansINSTALLED_APPS. -
Dans n'importe quel template :
{% load xeolux_loadingkit %}
{% xeolux_loadingkit_css %}
{% xeolux_loader size="md" text="Chargement..." %}
- Lancez
python manage.py collectstaticsi vous êtes en production.
Lancer les tests
# Depuis la racine du repo
pip install django pytest pytest-django
python -m pytest tests/ -v
Build & Publication PyPI
Build local
pip install build twine
python -m build
Les fichiers .tar.gz et .whl seront générés dans dist/.
Vérifier le package
twine check dist/*
Publier sur TestPyPI (recommandé avant la vraie publication)
twine upload --repository testpypi dist/*
Tester l'installation depuis TestPyPI :
pip install --index-url https://test.pypi.org/simple/ xeolux-loadingkit
Publier sur PyPI
twine upload dist/*
Vous aurez besoin d'un compte PyPI et d'un token API.
Configurez~/.pypircou utilisez la variable d'environnementTWINE_PASSWORD.
Structure du projet
xeolux-loadingkit/
├── xeolux_loadingkit/
│ ├── __init__.py
│ ├── apps.py
│ ├── templatetags/
│ │ ├── __init__.py
│ │ └── xeolux_loadingkit.py
│ ├── templates/
│ │ └── xeolux_loadingkit/
│ │ ├── loader.html
│ │ ├── overlay.html
│ │ ├── skeleton.html
│ │ └── htmx_indicator.html
│ └── static/
│ └── xeolux_loadingkit/
│ └── css/
│ └── loadingkit.css
├── tests/
│ └── test_template_tags.py
├── README.md
├── pyproject.toml
├── LICENSE
└── MANIFEST.in
Compatibilité
| Django | Python |
|---|---|
| 4.2 | 3.10, 3.11, 3.12 |
| 5.0 | 3.10, 3.11, 3.12 |
| 5.1 | 3.10, 3.11, 3.12 |
Licence
MIT © Xeolux
Project details
Download files
Download the file for your platform. If you're not sure which to choose, learn more about installing packages.
Source Distribution
Built Distribution
Filter files by name, interpreter, ABI, and platform.
If you're not sure about the file name format, learn more about wheel file names.
Copy a direct link to the current filters
File details
Details for the file xeolux_loadingkit-0.6.0.tar.gz.
File metadata
- Download URL: xeolux_loadingkit-0.6.0.tar.gz
- Upload date:
- Size: 26.5 kB
- Tags: Source
- Uploaded using Trusted Publishing? No
- Uploaded via: twine/6.2.0 CPython/3.14.3
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
54594ab5b7485e3e9a05af711878668a9ee3f5f5d7e1c6abfee1d3abe33cb658
|
|
| MD5 |
b621e202cb9e0c6b3f45cba605977d67
|
|
| BLAKE2b-256 |
894a724227f51392972fa77aee0ac013fefc36ca121046a26bd18457f3d1e699
|
File details
Details for the file xeolux_loadingkit-0.6.0-py3-none-any.whl.
File metadata
- Download URL: xeolux_loadingkit-0.6.0-py3-none-any.whl
- Upload date:
- Size: 22.0 kB
- Tags: Python 3
- Uploaded using Trusted Publishing? No
- Uploaded via: twine/6.2.0 CPython/3.14.3
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
2f842dce261119ce210e596e30c43215dab2f3777328113ea785430d83f16afc
|
|
| MD5 |
89997063f0a907faeeabc0092d510c28
|
|
| BLAKE2b-256 |
b9252b0038817e08aabe3c84aab060e15a333d04ad525d84f348fd063b52ee96
|