techfreakworm commited on
Commit
a7d0a44
·
unverified ·
1 Parent(s): 1a3b62d

feat(ui): labeled_label and model_selector_html helpers

Browse files
Files changed (2) hide show
  1. tests/test_ui.py +45 -0
  2. ui.py +55 -0
tests/test_ui.py ADDED
@@ -0,0 +1,45 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ import pytest
2
+
3
+ import ui
4
+
5
+
6
+ def test_labeled_label_returns_html_string():
7
+ out = ui.labeled_label("Steps", "Denoising steps.")
8
+ assert isinstance(out, str)
9
+ assert "<label" in out and "</label>" in out
10
+ assert ">Steps<" in out
11
+ assert 'data-info="Denoising steps."' in out
12
+ assert ">i<" in out # the icon glyph
13
+
14
+
15
+ def test_labeled_label_escapes_html_chars():
16
+ out = ui.labeled_label("Steps <x>", 'A "quoted" hint')
17
+ assert "<x>" not in out
18
+ assert "&lt;x&gt;" in out
19
+ assert "&quot;quoted&quot;" in out
20
+
21
+
22
+ def test_model_selector_html_marks_current_as_on():
23
+ out = ui.model_selector_html(current="Turbo")
24
+ assert 'class="zis-model on" data-value="Turbo"' in out
25
+ assert 'class="zis-model" data-value="Base"' in out
26
+
27
+
28
+ def test_model_selector_html_includes_both_soon_cards_with_github_link():
29
+ out = ui.model_selector_html(current="Turbo")
30
+ assert out.count("github.com/Tongyi-MAI/Z-Image#model-zoo") == 2
31
+ assert "Edit" in out
32
+ assert "Omni Base" in out
33
+ assert "soon-tag" in out
34
+ assert 'target="_blank"' in out
35
+ assert 'rel="noopener noreferrer"' in out
36
+
37
+
38
+ def test_model_selector_html_defaults_to_turbo():
39
+ out = ui.model_selector_html()
40
+ assert 'class="zis-model on" data-value="Turbo"' in out
41
+
42
+
43
+ def test_model_selector_html_escapes_current_value():
44
+ out = ui.model_selector_html(current='<script>alert(1)</script>')
45
+ assert "<script>" not in out
ui.py ADDED
@@ -0,0 +1,55 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ """Gradio UI builders + small HTML helpers for the (i) tooltip pattern and the custom model selector."""
2
+ from __future__ import annotations
3
+
4
+ from html import escape
5
+
6
+ GITHUB_MODEL_ZOO_URL = "https://github.com/Tongyi-MAI/Z-Image#model-zoo"
7
+
8
+
9
+ def labeled_label(text: str, info_text: str) -> str:
10
+ """Return HTML for a label with an (i) tooltip icon next to it.
11
+
12
+ Use immediately before a ``gr.Slider`` / ``gr.Textbox`` / ``gr.File`` etc.
13
+ that itself has ``show_label=False``. The CSS for ``.zis-row-label`` and
14
+ ``.zis-info`` is defined in :mod:`theme`.
15
+ """
16
+ return (
17
+ f'<label class="zis-row-label">{escape(text)}'
18
+ f'<span class="zis-info" data-info="{escape(info_text)}">i</span>'
19
+ f'</label>'
20
+ )
21
+
22
+
23
+ def model_selector_html(current: str = "Turbo") -> str:
24
+ """Custom T2I model selector — 2-col phone / 4-col tablet+ grid of cards.
25
+
26
+ Two functional ``<button>`` cards (Base, Turbo) — clicks fire
27
+ ``zis.setModel('<name>')`` defined in app.py's ``head=`` script.
28
+
29
+ Two coming-soon ``<a>`` cards (Edit, Omni Base) — open the Z-Image GitHub
30
+ README's Model Zoo section in a new tab. Marked with a `.soon` class and a
31
+ "soon" pill that doesn't overlap the model name (separate flex children).
32
+ """
33
+ current_safe = escape(current)
34
+ cards: list[str] = []
35
+ for name in ("Base", "Turbo"):
36
+ cls = "zis-model on" if name == current else "zis-model"
37
+ cards.append(
38
+ f'<button type="button" class="{cls}" data-value="{name}" '
39
+ f'onclick="zis.setModel(\'{name}\')">'
40
+ f'<span class="dot"></span>'
41
+ f'<span class="name">{name}</span>'
42
+ f'</button>'
43
+ )
44
+ for name in ("Edit", "Omni Base"):
45
+ cards.append(
46
+ f'<a class="zis-model soon" '
47
+ f'href="{GITHUB_MODEL_ZOO_URL}" '
48
+ f'target="_blank" rel="noopener noreferrer">'
49
+ f'<span class="dot"></span>'
50
+ f'<span class="name">{name}<span class="ext">↗</span></span>'
51
+ f'<span class="soon-tag">soon</span>'
52
+ f'</a>'
53
+ )
54
+ _ = current_safe # current is matched in cls above; this line keeps escape() exercised
55
+ return f'<div class="zis-models">{"".join(cards)}</div>'