Files
Forge-Engine/screens/rendering/render_select.py
T
william bb01e9fdf1 Make Jauge, Onglets, and every form-field widget real native Bulma elements
- Jauge now renders a real <progress class="progress"> instead of a hand-built pair of absolutely-positioned divs. The bas/haut color interpolation still works, set via Bulma's own --bulma-progress-value-background-color CSS custom property rather than fighting the class.
- Onglets' tab strip is now genuine Bulma tabs markup (tabs > ul > li, is-active on the li) instead of custom forgeTabBar/forgeTabBtn classes; forgeShowTab (duplicated in screen_edit.html and play.html) now toggles is-active to match.
- Champ texte/email/mot de passe get class="input", Zone de texte gets class="textarea", Case à cocher/Bouton radio's existing <label> wrapper gets class="checkbox"/"radio" (Bulma's own convention — the structure already matched, just needed the class), Liste déroulante is wrapped in Bulma's required <div class="select"> (a bare class on the <select> itself has zero effect in Bulma), Tableau gets class="table is-bordered is-fullwidth" with the per-cell inline borders removed so Bulma's own table styling applies.
- Removed the now-dead .forgeTabBar/.forgeTabBtn CSS.

Updated tests/test_jauge.py and tests/test_onglets_widget.py assertions to match the new markup (value="X" attribute instead of width:X% inline style, --bulma-progress-value-background-color instead of background-color, forgeShowTab(this) marker instead of the removed forgeTabBtn class) — same behavior, different rendering mechanism. Full suite green (89 passed), verified end to end against the real "test" project via the actual /play route.
2026-08-24 14:31:55 +02:00

26 lines
1.5 KiB
Python

import html as html_lib
from .visible_attrs import _visible_attrs
from .apply_ctx import _apply_ctx
from .style_string import _style_string
from .attr_string import _attr_string
from .auto_id import _auto_id
def _render_select(el, meta, slug=None, children_map=None, ctx=None, parent_flex_direction=None):
# Bulma stylise un <select> via la classe "select" posée sur un <div>
# QUI L'ENTOURE (le petit triangle est un ::after de ce wrapper) — la
# poser directement sur la balise <select> elle-même n'aurait aucun
# effet. Le wrapper porte donc l'id/positionnement habituel de
# l'élément (comme tous les autres widgets), le <select> reste à
# l'intérieur avec ses propres attributs de formulaire (name, required).
outer_attrs = _visible_attrs(el, meta, ctx)
select_attrs = {k: v for k, v in outer_attrs.items() if k not in ("id", "class", "data-element-id", "data-anim-target")}
wrapper_attrs = {k: v for k, v in outer_attrs.items() if k in ("id", "data-element-id", "data-anim-target")}
style = _style_string(el, " display:flex;", parent_flex_direction)
content = _apply_ctx(el.get("content") or "", ctx)
options = [o.strip() for o in content.split("\n") if o.strip()]
opts_html = "".join(f'<option value="{html_lib.escape(o)}">{html_lib.escape(o)}</option>' for o in options)
select_html = f'<select {_attr_string(select_attrs, "")}>{opts_html}</select>'
return f'<div {_attr_string(wrapper_attrs, style)}><div class="select is-fullwidth">{select_html}</div></div>'