Flow control
wybthon.flow¶
flow
¶
SolidJS-style reactive flow control components.
These components create isolated reactive scopes so that only the relevant subtree re-renders when the tracked condition or list changes.
Each flow control is a factory function returning a component VNode; conditions, sources, children, and fallbacks are accepted as getters (zero-arg callables) so that reads happen inside the flow control's own reactive effect, not the parent's.
API rules:
when/each: pass a getter (the signal accessor itself) or a raw value. Getters are called inside the flow control's own scope.children: may be aVNode, a callable returning aVNode, or (forFor/Index) the per-item mapping callback.fallback: same flexibility aschildren.
Fine-grained list primitives:
Formaintains stable per-item rendered subtrees (keyed by reference identity) on top ofmap_array. The mapping callback runs exactly once per unique item; on list changes, existing rows keep their DOM and are only moved, never re-diffed.Indexmaintains stable per-index subtrees on top ofindex_array, with a reactive item signal that updates when the value at that position changes.
Example
Functions:
| Name | Description |
|---|---|
Show |
Conditionally render |
For |
Render a list of items using a per-item mapping function. |
Index |
Render a list by index with a stable item getter. |
Match |
Declare a branch inside a |
Switch |
Render the first matching |
Dynamic |
Render a dynamically-chosen component. |
Show
¶
Conditionally render children when when is truthy.
Behavior:
whenmay be a zero-arg getter or a plain value.children/fallbackmay be aVNode, a callable, or a plain value. Whenchildrenis callable andwhenis truthy, the truthy value is passed as the first argument (matching SolidJS<Show>).
The component creates a keyed conditional scope: when the
truthiness of when changes, the previous branch's scope is
disposed and a new scope is created. This ensures that effects and
cleanups registered inside a branch are properly torn down on
transitions.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
when
|
Any
|
Condition value or zero-arg getter. |
None
|
children
|
Any
|
Slot rendered when the condition is truthy. |
None
|
fallback
|
Any
|
Slot rendered when the condition is falsy. |
None
|
Returns:
| Type | Description |
|---|---|
VNode
|
A component |
VNode
|
condition's truthiness changes. |
For
¶
Render a list of items using a per-item mapping function.
Inside the callback, item is a signal-backed getter returning
the current item value, and index is a signal-backed getter
returning the current integer index, matching SolidJS <For>.
For is built on map_array: the mapping
callback runs exactly once per unique item (keyed by reference
identity), and the rendered subtree is cached. When the list
changes, unchanged rows keep their DOM untouched; the reconciler
only mounts additions, unmounts removals, and moves reordered rows.
When an item leaves the list, its reactive scope (including any
effects or cleanups created inside the callback) is disposed.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
each
|
Any
|
List getter (typically a signal accessor) or plain list. |
None
|
children
|
Any
|
A |
None
|
fallback
|
Any
|
Slot rendered when the list is empty. |
None
|
Returns:
| Type | Description |
|---|---|
VNode
|
A component |
Index
¶
Render a list by index with a stable item getter.
Unlike For, the children callback receives
(item_getter, index) so that the DOM subtree for each index is
reused even when the underlying data changes.
Index is built on index_array: each slot
renders once and owns a signal-backed item_getter that updates
when the value at that position changes. Growing the list creates
and mounts new slots; shrinking disposes and unmounts excess slots.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
each
|
Any
|
List getter (typically a signal accessor) or plain list. |
None
|
children
|
Any
|
A |
None
|
fallback
|
Any
|
Slot rendered when the list is empty. |
None
|
Returns:
| Type | Description |
|---|---|
VNode
|
A component |
Match
¶
Declare a branch inside a Switch.
when may be a getter or a plain value:
Must be used inside Switch().
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
when
|
Any
|
Predicate value or zero-arg getter. |
None
|
children
|
Any
|
A |
None
|
Returns:
| Type | Description |
|---|---|
_MatchResult
|
An opaque branch descriptor consumed by |
Switch
¶
Render the first matching Match branch, or fallback.
Switch(
Match(when=lambda: status() == "loading",
children=lambda: p("Loading...")),
Match(when=lambda: status() == "ready",
children=lambda: p("Ready")),
fallback=lambda: p("Unknown"),
)
Each Match when is evaluated lazily inside the Switch
component's reactive scope.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
*branches
|
_MatchResult
|
One or more |
()
|
fallback
|
Any
|
Slot to render when no branch matches. May be a
|
None
|
Returns:
| Type | Description |
|---|---|
VNode
|
A component |
VNode
|
branch, or the |
Dynamic
¶
Render a dynamically-chosen component.
component may be a string tag name, a component function, or
None (renders nothing). It can also be a getter for reactive
switching.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
component
|
Any
|
Tag name, component callable, getter, or |
None
|
props
|
Optional[Dict[str, Any]]
|
Optional dict of props forwarded to the resolved component. |
None
|
**kwargs
|
Any
|
Additional props (merged on top of |
{}
|
Returns:
| Type | Description |
|---|---|
VNode
|
A component |
VNode
|
the resolved component identity changes. |
What's in this module¶
flow provides SolidJS-style reactive flow control components. They
create isolated reactive scopes so that only the relevant subtree
re-renders when the tracked condition or list changes.
| Component | Use it for |
|---|---|
Show |
Conditional rendering with a single fallback. |
For |
Keyed list rendering with stable per-item scopes. |
Index |
Index-keyed list rendering with reactive item signals. |
Switch / Match |
Multi-branch conditional rendering. |
Dynamic |
Render a component chosen at runtime. |
Idioms¶
from wybthon import (
For, Index, Match, Show, Switch, component, create_signal,
)
from wybthon.html import li, p, ul
@component
def Demo():
items, _ = create_signal(["a", "b", "c"])
is_logged_in, _ = create_signal(False)
return ul(
Show(
when=is_logged_in,
children=lambda: li("Welcome!"),
fallback=lambda: li("Please log in"),
),
For(each=items, children=lambda item, idx: li(item())),
)
- Pass getters (the signal accessor itself) to
when/each. childrenmay be aVNode, a callable returning aVNode, or the per-item mapping callback forFor/Index.- The mapping callback runs once per unique item (
For) or per index slot (Index) and the resulting subtree is cached: list changes mount added items, dispose removed ones, and move existing DOM for reorders. InsideIndex, pass theitemgetter (notitem()) where the slot's value should stay live.
See also¶
- Concepts → Components
- Authoring patterns
map_array/index_arrayfor reactive list mapping outside ofFor/Index.