Adds a shared bulma_variants.py (color/size option lists) and expands BULMA_*_CONTROLS in bulma_controls.py to cover each component's full modifier set: Bouton (colour incl. white/light/dark/black/text, light-shade toggle, size, rounded, outlined, inverted, static, loading, fullwidth), Titre (Bulma size is-1..is-6 independent of heading level, is-spaced), Jauge (size), Tableau (bordered/fullwidth/striped/hoverable/narrow, now toggleable instead of hardcoded), Onglets (alignment, boxed/toggle/toggle-rounded style, size, fullwidth), and every form field — champ_texte/email/mot_de_passe, zone_texte, liste_deroulante (colour, size, rounded, static). render_select.py/render_onglets.py/render_jauge.py now redirect the merged "class" from _visible_attrs to the actual Bulma sub-element (the .select wrapper, the .tabs div, the <progress> tag) instead of the outer positioning wrapper, since that's what needs to carry the modifier classes. Also fixed a real latent bug found while wiring this up: a checkbox control with default=True (e.g. Tableau's "Première ligne = en-tête") was never actually applied on a freshly created element — default_style_and_attributes unconditionally skipped ALL checkbox types at creation, so the panel showed it checked while the element itself had nothing set. Now a checkbox's default=True is frozen at creation like any other meaningful default; default=False (the common case) is unaffected. Verified end to end: every widget's variant controls save and render the right class tokens (spot-checked titre/tableau/onglets/champ_texte/liste_deroulante/jauge), full suite green (89 passed).
67 lines
3.1 KiB
Python
67 lines
3.1 KiB
Python
import html as html_lib
|
|
|
|
from .visible_attrs import _visible_attrs
|
|
from .style_string import _style_string
|
|
from .parent_flex_direction import _parent_flex_direction
|
|
from .auto_id import _auto_id
|
|
from .attr_string import _attr_string
|
|
|
|
|
|
def _render_onglets(el, meta, slug, children_map=None, ctx=None, parent_flex_direction=None):
|
|
"""Élément à onglets : chaque onglet est un vrai conteneur posé comme
|
|
enfant (voir screens/elements/add_tab.py) — ça réutilise tel quel tout
|
|
ce qui existe déjà pour un conteneur normal (ajouter du contenu dedans
|
|
via "Ajouter DANS ce conteneur", le renommer pour changer le libellé
|
|
affiché sur l'onglet, le supprimer via la poubelle standard) plutôt que
|
|
d'inventer un stockage séparé pour les onglets. Un seul panneau visible
|
|
à la fois, basculé par un petit script embarqué qui marche aussi bien
|
|
dans l'éditeur qu'en jeu (voir forgeShowTab dans screen_edit.html et
|
|
play.html)."""
|
|
from .render_element_html import render_element_html
|
|
|
|
tabs = (children_map or {}).get(el["id"], [])
|
|
attrs = _visible_attrs(el, meta, ctx)
|
|
# Les variantes Bulma (alignement/style/taille... voir BULMA_TABS_CONTROLS)
|
|
# calculées par _visible_attrs atterrissent dans "class" — c'est le
|
|
# <div class="tabs"> qui doit les porter, pas ce wrapper de positionnement.
|
|
tabs_extra_classes = attrs.pop("class", "")
|
|
style = _style_string(el, " display:flex; flex-direction:column;", parent_flex_direction)
|
|
group_id = _auto_id(el)
|
|
|
|
if not tabs:
|
|
return (
|
|
f'<div {_attr_string(attrs, style)}>'
|
|
f'<em style="opacity:.6;">Onglets — ajoute au moins un onglet dans ses réglages.</em></div>'
|
|
)
|
|
|
|
flex_dir = _parent_flex_direction(el)
|
|
bar_items = []
|
|
panels = []
|
|
for i, tab in enumerate(tabs):
|
|
label = tab.get("name") or f"Onglet {i + 1}"
|
|
active = i == 0
|
|
tab_html = render_element_html(tab, slug, children_map, ctx, parent_flex_direction=flex_dir)
|
|
target_id = f"tabpanel-{tab['id']}"
|
|
# <li> Bulma natif ("tabs" > "ul" > "li", "is-active" sur le <li> —
|
|
# pas le <a> — pour l'onglet en cours) : le <li> porte le clic ET les
|
|
# data-attributes ciblés par forgeShowTab (voir screen_edit.html /
|
|
# play.html), le <a> imbriqué n'est là que pour le rendu visuel Bulma.
|
|
bar_items.append(
|
|
f'<li class="{"is-active" if active else ""}" '
|
|
f'data-tab-btn="{group_id}" data-tab-target="{target_id}" '
|
|
f'onclick="forgeShowTab(this)"><a>{html_lib.escape(str(label))}</a></li>'
|
|
)
|
|
hidden_style = "" if active else ' style="display:none;"'
|
|
panels.append(
|
|
f'<div class="forgeTabPanel" id="{target_id}" data-tab-group="{group_id}"{hidden_style}>'
|
|
f'{tab_html}</div>'
|
|
)
|
|
|
|
tabs_class = html_lib.escape(("tabs " + tabs_extra_classes).strip())
|
|
return (
|
|
f'<div {_attr_string(attrs, style)}>'
|
|
f'<div class="{tabs_class}"><ul>{"".join(bar_items)}</ul></div>'
|
|
f'<div class="forgeTabPanels" style="flex:1 1 auto; min-height:0;">{"".join(panels)}</div>'
|
|
f"</div>"
|
|
)
|