API figée
Le contrat : attributs, classes et globales autorisés. Besoin nouveau → d’abord ici, ensuite l’usage.
Source : ui.aubota.xyz/API.md — rendu à la volée, toujours à jour.
Installation
<script src="https://ui.aubota.xyz/js/aubui.js" defer></script>Le script injecte automatiquement le CSS et charge, dans l’ordre : dialog.js, engine.js, theme.js, accent.js, actions.js, aubui-invite.js, puis (mode complet) navbar.js, notifications.js, timepicker.js. Mode léger : window.AubotaNav = { disabled: true } avant le script.
Point d’entrée CSS (si besoin manuel) : https://ui.aubota.xyz/css/aubui/aubui.full.css?v=<AUB_BUILD> avec data-aubui-css="1" (évite le double chargement). aubui.css à la racine reste un alias de compatibilité.
Doc vivante de chaque élément ci-dessous : https://ui.aubota.xyz/
Syntaxe déclarative (recommandée)
Tu écris des attributs. Le moteur ajoute les classes.
Boutons — aub-btn
<button aub-btn primary sm>OK</button>| Attribut | Classe générée |
|---|---|
aub-btn | .aub-btn |
primary | .aub-btn--primary |
ghost | .aub-btn--ghost |
danger | .aub-btn--danger |
success | .aub-btn--success |
sm md lg | .aub-btn--sm etc. |
block | .aub-btn--block |
Cartes — aub-card
<div aub-card pad>
<h3 aub-title>Titre</h3>
<p aub-muted>Corps</p>
</div>| Attribut | Classe |
|---|---|
aub-card | .aub-card |
pad | .aub-card--pad |
aub-title | .aub-card__title |
Champs
| Attribut | Classe |
|---|---|
aub-field | .aub-field |
aub-label | .aub-label |
aub-input | .aub-input |
block (sur input) | .aub-input--block |
aub-hint | .aub-hint |
Alertes & badges
| Attribut | Classe |
|---|---|
aub-alert + info|success|warning|danger | .aub-alert--… |
aub-badge + variante | .aub-badge--… |
Texte
| Attribut | Classe |
|---|---|
aub-muted | .aub-muted |
aub-link | .aub-link |
aub-code | .aub-code |
aub-pre | .aub-pre |
aub-text-sm aub-text-xs aub-text-lg | tailles |
Navbar — aub-nav
<nav aub-nav brand="Feedback" brand-href="/">
<a href="/public">Publics</a>
<a href="/submit">Soumettre</a>
</nav>| Attribut | Rôle |
|---|---|
aub-nav | active le moteur navbar |
brand="…" | texte du brand |
brand-href="…" | lien du brand (défaut /) |
no-notif | n’ajoute pas la cloche |
no-theme | n’ajoute pas le bouton thème |
Généré automatiquement :
.aub-nav__brand.aub-nav__links+.aub-nav__link(+--activeselon l’URL).aub-nav__spacer.aub-nav__actions(cloche + thème + burger)- Drawer mobile (
.aub-nav__drawer) + overlay
Breakpoint hamburger : ≤ 720px
Notifications
Structure générée dans la navbar (ou manuelle) :
| Classe | Rôle |
|---|---|
.aub-notif | conteneur |
.aub-notif__btn | bouton cloche |
.aub-notif__badge | compteur (.is-visible) |
.aub-notif__dropdown | panneau (.is-open) |
.aub-notif__list | liste |
.aub-notif__item | item (.is-unread) |
AubotaNotif.setCount(3);
AubotaNotif.render([
{ id: 'n1', module: 'Hub', title: '…', body: '…', ts: 1760000000, unread: true, href: '/…' }
]);
AubotaNotif.toast({ module, title, body, href, onClick });
AubotaNotif.load();Endpoint : GET → { ok, unread, items[] }, POST { act: 'read', id }. Événements document : aubota:notif-new (émis, {items}), aubota:notif-count (écouté, {unread}), aub-nav-ready (écouté).
Classes classiques (toujours valides)
Tu peux continuer à écrire :
<button class="aub-btn aub-btn--primary aub-btn--sm">OK</button>Utile pour la migration progressive ou le CSS direct.
Boutons — .aub-btn
| Modificateur | Rôle |
|---|---|
--primary | action principale |
--ghost | discret |
--danger | destructif |
--success | validation |
--sm --lg | taille |
--block | pleine largeur |
Champs — .aub-field + .aub-label + .aub-input
| Classe | Rôle |
|---|---|
.aub-field | groupe label + contrôle |
.aub-label | label |
.aub-input | input / select / textarea |
.aub-input--block | largeur 100% |
.aub-hint | aide sous le champ |
.aub-check | checkbox / radio + label |
.aub-check-group | pile de checks |
.aub-check-group--row | en ligne |
.aub-fieldset | groupe / catégorie |
.aub-password-wrap | input + bouton œil (auth) |
Cartes & alertes
| Classe | Rôle |
|---|---|
.aub-card | carte |
.aub-card--pad | padding |
.aub-card__title | titre |
.aub-card__body | corps |
.aub-alert | alerte |
.aub-alert--info|success|warning|danger | variante |
.aub-badge | badge |
Layout utilitaires
.aub-flex .aub-grid .aub-flex-col .aub-items-center .aub-justify-between .aub-gap-2 … .aub-gap-6 .aub-mt-* .aub-mb-* .aub-p-* .aub-stack .aub-stack-lg .aub-max-w-md
Comportements data-aub-*
| Attribut | Effet |
|---|---|
data-aub-action="toggle" + data-aub-target | affiche/masque |
data-aub-action="show|hide" + target | force |
data-aub-action="copy" + data-aub-copy ou data-aub-copy-from | presse-papiers |
data-aub-action="dismiss" | masque [data-aub-dismissible] parent |
data-aub-confirm="Message" (+ data-aub-confirm-title, data-aub-confirm-ok, data-aub-danger) | lightbox AubuiDialog avant clic / envoi (<a>, <button>, <form>) |
data-aub-theme-toggle | dark/light |
data-aub-theme-set="dark|light" | reçoit .is-active quand ce thème est actif |
data-accent-set="blue|yellow|green|coral|purple|teal" | accent (.aub-accent-dot) |
input[type=radio][data-aub-accent-input] | accent au change |
data-aub-accent-picker | picker repliable |
API JS globale
Aubui.process() // re-scan attributs sur tout le document
Aubui.processNav() // re-scan navbars
AubotaNotif.setCount(n)
AubotaNotif.render(items)
AubotaNotif.open()
AubotaNotif.close()
AubotaNotif.load()
AubotaNotif.toast(opts)
AubuiDialog.alert(msg, { title, ok, danger }) // Promise<void>
AubuiDialog.confirm(msg, { title, ok, cancel, danger }) // Promise<boolean>
AubuiDialog.prompt(msg, { value, placeholder, title, ok, cancel, type, multiline }) // Promise<string|null>
AubuiToast.show(msg, { kind, duration, action: { label, onClick } }) // { close() }
AubuiToast.success|error|warning|info(msg, opts)
AubuiTheme.apply('dark'|'light', { persist }) · AubuiTheme.current()
AubuiAccent.apply(name, { persist }) · AubuiAccent.current() · AubuiAccent.accents · AubuiAccent.buildHtml(opts)
AubuiPrefsSync.save({ accent, theme, … }) · AubuiPrefsSync.readCookie()
AubuiTime.scan(root) · AubuiTime.enhance(input)
AubuiSearch.init(input) · AubuiSearch.scan(root)
AubInvite.require({ action, title, body, cta, dismiss, next }) // Promise<boolean>
AubInvite.isDemo() · AubInvite.guard(fn, opts)
AubotaNavMount()Événements document : aubui:dialog-ready, aubui:theme {theme}, aubui:accent {accent}, aubui:prefs-ready, aubui:prefs-saved, aubui:prefs-error {error}. Sur l’input de recherche : aubui:search:select (detail = résultat, annulable).
Interdit dans les modules : alert(), confirm(), prompt() natifs → AubuiDialog / data-aub-confirm.
Pages layout (minces)
/css/aubui/pages/home.css auth.css share.css social.css feedback.css natacha.css — structure seulement.
Feedback — classes page (feedback.css)
| Classe | Rôle |
|---|---|
.aub-feedback | shell body |
.aub-feedback-main | conteneur principal |
.aub-feedback-admin-layout | grille admin |
.aub-feedback-user-list | colonne utilisateurs |
.aub-feedback-list | colonne tickets |
.aub-feedback-ticket | carte ticket |
.aub-feedback-images | galerie captures |
.aub-feedback-reply | bulle réponse |
.aub-feedback-admin-form | zone actions admin |
Natacha — classes page (natacha.css)
| Classe | Rôle |
|---|---|
.aub-natacha | shell body |
.aub-natacha-main | conteneur principal |
.aub-natacha-filters | rangée de filtres / contrôles |
.aub-natacha-tickets | grille liste + détail |
.aub-natacha-tickets__list | colonne tickets |
.aub-natacha-tickets__item (+ .is-active .is-new) | ligne ticket cliquable |
.aub-natacha-tickets__detail | panneau détail |
.aub-natacha-images | galerie captures |
.aub-natacha-reply | bulle réponse |
.aub-natacha-pre | texte multi-ligne |
.aub-natacha-detail-grid | détail : 2 colonnes (≥ 1300px) |
.aub-natacha-progress + __bar | barre d'avancement des tâches |
.aub-natacha-tasks + __row (.is-done) __actions | arbre de tâches |
.aub-natacha-reply.is-team / .is-internal | bulle équipe / annotation interne |
.aub-natacha-log | ligne de journal automatique |
Social — classes page (social.css)
| Classe | Rôle |
|---|---|
.aub-social | shell page |
.aub-social-main .aub-social-main--narrow | conteneur contenu |
.aub-social-search + __results __item __empty | recherche live |
.aub-feed + __loading __empty | grille feed |
.aub-media-card + __media __body __title __meta __desc | carte post |
.aub-garage + __add | grille garage |
.aub-specs | liste specs |
.aub-profile-head + __name __actions | en-tête profil |
.aub-settings-row + __label __value | ligne paramètres |
Navbar globale — navbar.js
Injectée automatiquement par aubui.js (sauf AubotaNav.disabled = true).
<script>
window.AubotaNav = {
site: 'feedback',
user: { loggedIn: true, name: 'fusty' },
links: [
{ href: '/', label: 'Accueil' },
{ href: '/public', label: 'Publics' }
]
};
</script>
<script src="https://ui.aubota.xyz/js/aubui.js" defer></script>| Clé | Rôle |
|---|---|
site | Grand module actif (home, social, feedback, hub…) |
user.loggedIn / user.name | Affiche Connexion ou le pseudo |
links | Sous-nav du module (optionnel) |
disabled | true = pas de navbar (ex. pages auth) |
Structure : barre :AUBOTA + modules · trait accent · sous-nav centrée.
Règle d’or
Toute nouvelle UI = une ligne dans ce fichier + CSS + entrée catalogue + doc.
Concrètement : toute nouveauté Aubui = une section de doc dans pages/ + son entrée (avec sources et news) dans docs/registry.php, livrées avec le code. Voir README, « Règle ».
Time picker — aub-time
Roues heures / minutes (précision 1 min), style curseur central.
<input aub-time name="start_time" value="09:00">
<input aub-time name="end_time" value="" data-aub-time-empty>| Attribut | Rôle |
|---|---|
aub-time | Active le picker (input → hidden + bouton) |
data-aub-time-empty | Autorise vide (bouton Effacer) |
data-aub-time-step | Pas des minutes (défaut 1) |
Chargé automatiquement via aubui.js (mode complet).
Recherche — data-aubui-search (aubui-search.js, non chargé par aubui.js)
<link rel="stylesheet" href="https://ui.aubota.xyz/css/aubui/components/search.css">
<script src="https://ui.aubota.xyz/js/aubui-search.js" defer></script>
<input data-aubui-search data-search-url="/api/search" data-search-params='{"scope":"users"}' data-search-min="2">
<input data-aubui-search data-search-list-var="MES_DONNEES" data-search-fields="label,sub">| Attribut | Rôle |
|---|---|
data-search-url | endpoint GET ?q=&limit= → [{label, sub, href, icon, …}] ou {results: […]} |
data-search-params | JSON ajouté à la requête |
data-search-list-var | nom d’une globale (tableau) pour une recherche locale |
data-search-fields | champs comparés (défaut label,sub) |
data-search-min / data-search-limit | défauts 1 / 12 |
Classes : .aub-search-wrap .aub-search .aub-search-results .aub-search-item (.is-active) .aub-search-ico .aub-search-main .aub-search-label .aub-search-sub .aub-search-empty.
États vides — .aub-empty (Hub seulement pour l’instant)
.aub-empty + __icon __title __text __cta. Squelettes Hub : .hub-skel + --line --title --block. Styles dans hub.aubota.xyz/assets/polish.css, pas encore dans aubui.full.css.