Bug
When a tag function (e.g. H1, Paragraph, Href, Span) receives mixed positional children — strings interleaved with element instances — the strings are concatenated together first and the element children are appended after, regardless of source order. This silently breaks reading order for any inline content that mixes text and elements.
Reproduction
from nitro_ui import H1, Span
print(str(H1("What I learn ", Span("on Friday nights", class_name="accent"), ".")))
Expected:
<h1>What I learn <span class="accent">on Friday nights</span>.</h1>
Actual:
<h1>What I learn .<span class="accent">on Friday nights</span></h1>
The trailing . jumped past the span. Same pattern applies to Paragraph, Href, Footer, etc.
Impact
It's a silent failure: the page still renders, the markup parses, lint passes — the only signal is a visual inspection of the result. Easy to miss in code review and easy to ship.
The natural way to write a stylized headline in Python is exactly this:
H1("Welcome to ", Span("Nitro", class_name="brand"), "!")
…and it produces the wrong DOM.
Workaround
Wrap every string in Span() so all children are elements:
H1(Span("What I learn "), Span("on Friday nights", class_name="accent"), Span("."))
This works but adds noise and an extra <span> per text fragment.
Suggested fix
Preserve the source order of all positional children regardless of type. Render strings as text nodes inline at their position rather than collecting them into a single text-content buffer.
Environment
- nitro-ui (current as of 2026-04-19)
- Python 3.12
Bug
When a tag function (e.g.
H1,Paragraph,Href,Span) receives mixed positional children — strings interleaved with element instances — the strings are concatenated together first and the element children are appended after, regardless of source order. This silently breaks reading order for any inline content that mixes text and elements.Reproduction
Expected:
Actual:
The trailing
.jumped past the span. Same pattern applies toParagraph,Href,Footer, etc.Impact
It's a silent failure: the page still renders, the markup parses, lint passes — the only signal is a visual inspection of the result. Easy to miss in code review and easy to ship.
The natural way to write a stylized headline in Python is exactly this:
…and it produces the wrong DOM.
Workaround
Wrap every string in
Span()so all children are elements:This works but adds noise and an extra
<span>per text fragment.Suggested fix
Preserve the source order of all positional children regardless of type. Render strings as text nodes inline at their position rather than collecting them into a single text-content buffer.
Environment