DOM
wybthon.dom¶
dom
¶
Lightweight DOM wrapper utilities for Pyodide/browser environments.
This module exposes a thin Pythonic facade over the browser's DOM API, designed to feel familiar to JavaScript developers while integrating cleanly with Wybthon's batched renderer:
Elementwraps a single DOM node and offers ergonomic helpers for attributes, classes, styles, and queries.Refis a mutable container used by the renderer to hand out a reference to a mounted element.
The renderer itself never touches raw DOM nodes; it refers to nodes by
integer ids and batches mutations through wybthon.kernel. Element
is the escape hatch for imperative work: it can be backed by either a
raw node or a kernel node id, and materializes the underlying node on
first access (committing any pending batched ops first, so the node is
guaranteed to exist and be up to date).
The wrapper deliberately mirrors familiar DOM property names (e.g.
value, checked, files) so that event handlers can read state
exactly as they would in JavaScript:
See Also
Classes:
| Name | Description |
|---|---|
Element |
Thin wrapper around a DOM node with convenience methods. |
Ref |
Mutable container holding a reference to a mounted |
Element
¶
Element(tag: str | None = None, existing: bool = False, node: Any = None, node_id: int | None = None)
Thin wrapper around a DOM node with convenience methods.
Element can be constructed in four ways:
- With a tag name to create a brand-new node
(
Element("div")). - With a CSS selector and
existing=Trueto wrap an existing node (Element("#root", existing=True)). - With an opaque
nodevalue to wrap a node returned by another API. - With a kernel
node_id(used internally by the renderer for refs and event targets); the raw node is materialized lazily on first access.
The wrapper proxies common form-input properties (value,
checked, files) so handlers can read state from
e.target.value exactly as in React or SolidJS.
Create a new element, wrap an existing one, or wrap a node handle.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
tag
|
str | None
|
Tag name ( |
None
|
existing
|
bool
|
If |
False
|
node
|
Any
|
Raw underlying DOM node to wrap. When provided,
|
None
|
node_id
|
int | None
|
Kernel node id to wrap. The raw node is fetched
on first |
None
|
Raises:
| Type | Description |
|---|---|
ValueError
|
If neither |
Methods:
| Name | Description |
|---|---|
set_text |
Replace the text content of this element. |
append_to |
Append this element to |
append |
Append an |
remove |
Detach this element from its parent (no-op if already detached). |
load_html |
Fetch HTML from |
set_html |
Replace this element's content with the provided HTML string. |
set_attr |
Set an attribute on this element, with text-node fallbacks. |
get_attr |
Return the attribute value for |
remove_attr |
Remove an attribute from this element. |
set_style |
Set CSS properties using a dict and/or keyword arguments. |
add_class |
Add one or more CSS classes to this element. |
remove_class |
Remove one or more CSS classes from this element. |
toggle_class |
Toggle a CSS class, optionally forcing on/off. |
has_class |
Return |
query |
Query a single element by CSS selector. |
query_all |
Query all matching elements by CSS selector. |
find |
Return the first matching descendant |
find_all |
Return all matching descendant elements as a list. |
attach_ref |
Store this element on |
Attributes:
| Name | Type | Description |
|---|---|---|
element |
Any
|
The raw underlying DOM node, materialized on first access. |
node_id |
int
|
This element's kernel node id, registering the raw node if needed. |
value |
Any
|
Current value of an |
checked |
bool
|
Checked state of a checkbox or radio input. |
files |
Any
|
|
element
property
¶
element: Any
The raw underlying DOM node, materialized on first access.
For id-backed elements this commits pending batched DOM ops first, so the node exists and reflects every queued mutation.
load_html
async
¶
load_html(url: str) -> None
Fetch HTML from url and assign it to innerHTML.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
url
|
str
|
URL to fetch via the browser's |
required |
set_html
¶
set_html(html: str) -> None
Replace this element's content with the provided HTML string.
Caution
This bypasses the renderer's diffing and does not sanitize input. Avoid passing untrusted HTML.
set_attr
¶
get_attr
¶
Return the attribute value for name, or None when absent.
set_style
¶
remove_class
¶
remove_class(*class_names: str) -> None
Remove one or more CSS classes from this element.
toggle_class
¶
has_class
¶
Return True if the element currently has the given class.
query
classmethod
¶
Query a single element by CSS selector.
Commits pending batched DOM ops first so nodes created earlier in the same update are visible to the query.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
selector
|
str
|
CSS selector string. |
required |
within
|
Element | None
|
Optional parent |
None
|
Returns:
| Type | Description |
|---|---|
Element | None
|
The first matching |
query_all
classmethod
¶
Query all matching elements by CSS selector.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
selector
|
str
|
CSS selector string. |
required |
within
|
Element | None
|
Optional parent |
None
|
Returns:
| Type | Description |
|---|---|
list[Element]
|
A list of wrapped |
find_all
¶
Return all matching descendant elements as a list.
Ref
¶
Mutable container holding a reference to a mounted Element.
Pass a Ref to an element's ref= prop. After mount ref.current
is the wrapped element; after unmount it's reset to None. The ref
prop also accepts a callback ref(el) or a list mixing both, so a
component can forward a parent's ref and keep its own:
class FancyInputProps(Props):
ref: Ref | Callable[[Element], Any] | None = None
@component
def FancyInput(props: FancyInputProps):
local = Ref()
on_settled(lambda: local.current.element.focus())
return input_(type="text", ref=[local, props.ref])
Refs are assigned during mount, so read them in
on_settled or an effect, not at the top of
the component body.
What's in this module¶
dom is the imperative escape hatch. The renderer refers to nodes by
integer id and batches every mutation through the kernel;
Element wraps a real node (or a kernel node id,
materialized on first access after committing pending ops) so you can
read a value, focus an input, or call a browser API directly.
Ref is the container the renderer fills in when an
element with ref= mounts.
| Name | Description |
|---|---|
Element |
Thin wrapper over a DOM node: .element (raw node), .node_id, .value, .checked, .files, attribute, class, style, and query helpers. |
Ref |
Holds .current (an Element) after mount; reset to None on unmount. |
Construct an Element four ways: Element("div") creates a node,
Element("#app", existing=True) queries one, Element(node=raw) wraps a
node from another API, and Element(node_id=42) wraps a kernel id
(what refs and event targets hand you).
from wybthon import Props, Ref, component, input_, on_settled
class FancyInputProps(Props):
ref: Ref | None = None # plain field: the parent's Ref, passed through untouched
@component
def FancyInput(props: FancyInputProps):
local = Ref()
def focus():
local.current.element.focus()
on_settled(focus)
# Forward the parent's ref (if any) and keep a local one.
return input_(type="text", ref=[local, props.ref])
Refs are assigned during mount, so read them in
on_settled, an effect, or an event handler, not
at the top of the component body. The ref= prop also accepts a
callback ref(el).
Element.query(selector), .find(selector), and .element commit
pending batched ops first, so nodes created earlier in the same update
are visible to the read.
See also¶
- HTML helpers: the
ref=prop and DOM property rules - Events:
DomEvent.targetandcurrent_targetareElement-backed - Concepts: DOM interop