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 implemented as a proper function component
(returning dynamic(...)) rather than a plain helper. 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 reactive scopes (keyed by reference identity); the mapping callback runs only once per unique item.Indexmaintains stable per-index scopes 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 keyed 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.
Can be called in two styles:
Component style (reactive; recommended for dynamic conditions):
Direct call (evaluated once; fine inside an explicit hole):
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 |
|---|---|---|---|
props_or_when
|
Any
|
A props dict (component style) or the |
None
|
children_pos
|
Any
|
Positional |
None
|
**kwargs
|
Any
|
|
{}
|
Returns:
| Type | Description |
|---|---|
Any
|
A reactive |
Any
|
the condition's truthiness changes. |
For
¶
Render a list of items using a keyed mapping function.
Component style (reactive):
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 maintains stable per-item reactive scopes keyed by
reference identity. The mapping callback runs only once per unique
item. When an item leaves the list, its scope (including any
effects or cleanups created inside the callback) is disposed.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
props_or_each
|
Any
|
A props dict (component style) or the |
None
|
children_pos
|
Any
|
Positional |
None
|
**kwargs
|
Any
|
|
{}
|
Returns:
| Type | Description |
|---|---|
Any
|
A reactive |
Any
|
item identity. |
Index
¶
Render a list by index with a stable item getter.
Unlike For, the children callback receives
(item_getter, index) so that the DOM node for each index is reused
even when the underlying data changes.
Index maintains stable per-index reactive scopes. Each slot
has a signal-backed item_getter that updates when the value at
that position changes. Growing the list creates new scopes;
shrinking disposes excess scopes.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
props_or_each
|
Any
|
A props dict (component style) or the |
None
|
children_pos
|
Any
|
Positional |
None
|
**kwargs
|
Any
|
|
{}
|
Returns:
| Type | Description |
|---|---|
Any
|
A reactive |
Any
|
index. |
Match
¶
Declare a branch inside a Switch.
when may be a getter or a plain value. Supports both positional
and keyword calling styles:
Match(True, h("p", {}, "yes")) # positional
Match(when=lambda: x() > 0, children=lambda: p("positive")) # keyword
Must be used inside Switch().
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
when
|
Any
|
Predicate value or zero-arg getter. |
None
|
children
|
Any
|
A |
None
|
**kwargs
|
Any
|
Same keys as the explicit parameters; takes priority over positional values when provided. |
{}
|
Returns:
| Type | Description |
|---|---|
_MatchResult
|
An opaque branch descriptor consumed by |
Switch
¶
Render the first matching Match branch, or fallback.
Component style (reactive):
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
|
Any
|
One or more |
()
|
fallback
|
Any
|
Slot to render when no branch matches. May be a
|
None
|
**kwargs
|
Any
|
Optional |
{}
|
Returns:
| Type | Description |
|---|---|
Any
|
A reactive |
Any
|
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 |
|---|---|
Any
|
A reactive |
Any
|
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(), key=idx())),
)
- Pass getters (the signal accessor itself) to
when/each. childrenmay be aVNode, a callable returning aVNode, or the per-item mapping callback forFor/Index.
See also¶
- Concepts → Components
- Authoring patterns
map_array/index_arrayfor reactive list mapping outside ofFor/Index.