duck.html.components¶
This module defines HTML components that can be inserted into HTML pages or used to dynamically generate HTML.
These components can be embedded in templates or directly manipulated in Python code.
Template Usage Examples
Jinja2 Template:
{{ Button(
id="btn",
text="Hello world",
)
}}
{# Alternatively: #}
{{ Button(
inner_html="Hello world",
props={
"id": "btn",
},
)
}}
Django Template:
{% Button %}
id="btn",
text="Hello world",
{% endButton %}
{# Alternatively: #}
{% Button %}
inner_html="Hello world",
props={
"id": "btn",
},
{% endButton %}
To leverage these components, ensure the setting ENABLE_COMPONENT_SYSTEM is set to True.
Direct Usage Example
from duck.html.components.button import Button
from duck.html.components.page import Page
from duck.html.core.websocket import LivelyWebSocketView
from duck.html.core.exceptions import JSExecutionError, JSExecutionTimedOut
async def on_click(btn: Button, event: str, value: str, websocket: LivelyWebSocketView):
'''
Button onclick event.
Args:
btn (Button): Button component which received the event.
event (str): The event name.
value (str): The current button value.
websocket (LivelyWebSocketView): The current active websocket connection.
'''
# This handler can also be either asynchronous or synchronous.
if btn.bg_color != "red":
btn.bg_color = "red"
else:
btn.bg_color = "green"
# You can also execute JS on client side like so.
# but the execution will execute first before button changes color.
try:
await websocket.execute_js(
code='alert(`Javascript execution success`);',
timeout=2,
wait_for_result=True, # This will wait for feedback on execution.
) # or you can use get_js_result() for retrieving a variable result after code execution.
except (JSExecutionTimedOut, JSExecutionError):
# JS execution timed out or the code raised an error on client side.
pass
def home(request):
page = Page(request)
btn = Button(
id="some-id",
text="Hello world",
bg_color="green",
color="white",
)
# Add button to body
page.add_to_body(btn)
# Bind an event handler to the button
btn.bind("click", on_click)
print(btn.render()) # Outputs the corresponding HTML
# Return component or ComponentResponee
return page
You can render this component in a template or use it anywhere HTML output is needed.
Defining Your Own Component
Subclassing the component class allows you to create custom components easily.
# This example uses a component that accepts an inner body.
# Use `NoInnerComponent` if you don’t need inner content.
from duck.html.components import InnerComponent
from duck.html.components.button import Button
from duck.shortcuts import to_response
class MyComponent(InnerComponent):
def get_element(self):
# Return the HTML tag name
return "div"
def on_create(self):
# Called after initialization
super().on_create() # Useful for extending base behavior, don't leave this out
# You can access provided extra keyword arguments provided to the component by
# accessing `self.kwargs`
# Do some operations
self.add_child(Button(text="Hi there"))
# In views.py
def home(request):
comp = MyComponent(request=request) # you can provide extra keyword arguments here.
print("request" in comp.kwargs) # Outputs: True
response = to_response(comp) # More control than just returning comp
return response
# Instead of using to_response, you can use duck.http.response.ComponentResponse instead.
Subpackages¶
duck.html.components.coreduck.html.components.core.childrenduck.html.components.core.exceptionsduck.html.components.core.force_updateduck.html.components.core.mutationduck.html.components.core.opcodesduck.html.components.core.propsduck.html.components.core.systemduck.html.components.core.utilsduck.html.components.core.vdomduck.html.components.core.warningsduck.html.components.core.websocket
duck.html.components.extensionsduck.html.components.templatetagsduck.html.components.utils
Submodules¶
duck.html.components.buttonduck.html.components.cardduck.html.components.checkboxduck.html.components.codeduck.html.components.containerduck.html.components.duckduck.html.components.fileinputduck.html.components.footerduck.html.components.formduck.html.components.headingduck.html.components.heroduck.html.components.iconduck.html.components.imageduck.html.components.inputduck.html.components.labelduck.html.components.linkduck.html.components.livelyduck.html.components.modalduck.html.components.navbarduck.html.components.page- Page Component Module
duck.html.components.paragraphduck.html.components.progressbarduck.html.components.scriptduck.html.components.sectionduck.html.components.selectduck.html.components.snackbarduck.html.components.styleduck.html.components.table_of_contentsduck.html.components.textareaduck.html.components.video
Package Contents¶
Classes¶
Base class for all HTML components. |
|
This is the HTML component with Inner Body presence. |
|
This is the HTML component with no Inner Body. |
|
Default Duck theme. |
Functions¶
Returns an html component quoting the provided html as its body. |
|
Returns an html component quoting the provided html as its body. (Same as |
Data¶
API¶
- duck.html.components.Component¶
None
- duck.html.components.ComponentError¶
None
- duck.html.components.ELEMENT_PATTERN¶
‘compile(…)’
- class duck.html.components.HtmlComponent(element: Optional[str] = None, accept_inner_html: bool = False, inner_html: Optional[Union[str, int, float]] = None, properties: Optional[Dict[str, str]] = None, props: Optional[Dict[str, str]] = None, style: Optional[Dict[str, str]] = None, **kwargs)[source]¶
Base class for all HTML components.
This class provides the foundational structure for defining HTML-based UI components in the Lively component system.
Notes:
If the Lively Component System is active, each component is lazily registered. A component is only added to the component registry after
render()orto_string()has been called.To improve performance and reduce re-rendering overhead, heavy components can be pre-rendered. Once pre-rendered, subsequent renders are faster due to internal caching. You can do this by using method
pre_render.All Lively components are validated before any event is sent to the server, this is disabled by adding prop
data-validate=falsein props. Empty props withoutdata-validate=false, default is validation. You can even toggle this by using methodtoggle_validation.
Initialization
Initialize an HTML component.
- Parameters:
element – The HTML element tag name (e.g., textarea, input, button). Can be None, but make sure element is returned by get_element method.
accept_inner_html – Whether the HTML component accepts an inner body (e.g., inner-body-here).
inner_html – Inner html to add to the HTML component. Defaults to None.
properties – Dictionary for properties to initialize the component with.
props – Just same as properties argument (added for simplicity).
style – Dictionary for style to initialize the component with.
**kwargs – Extra keyword arguments
- Raises:
HtmlComponentError – If ‘element’ is not a string or ‘inner_html’ is set but ‘accept_inner_html’ is False.
- __setattr__(key: str, value: Any)[source]¶
Custom attribute setter that protects component references from being overwritten.
- Parameters:
key – The attribute name.
value – The value to set.
- Raises:
ComponentAttributeProtection – If protected component attribute is being modified.
- __str__¶
None
- _copy(shallow: bool = False) duck.html.components.HtmlComponent[source]¶
Returns a copy of the component.
Notes:
Props, style, children are copied.
Iterative copy avoids recursion depth issues.
Shallow copy allowed only on frozen components.
- _on_mutation(mutation: duck.html.components.core.mutation.Mutation)[source]¶
Private entry method to
on_mutationevent.
- static assign_component_uids(root_component: duck.html.components.Component, base_uid: str = '0', force: bool = False) None[source]¶
Assigns deterministic UIDs to the entire component tree using a non-recursive traversal.
- Parameters:
root_component – The root component to start from.
base_uid – The base UID for the root (default is “0”).
force – Whether to force assign component uid’s. By default, if no children structure mutation has happened, no uid assignment is done. This argument overrides this behavior. Defaults to False.
- async async_to_vdom() duck.html.components.core.vdom.VDomNode[source]¶
Asynchronously convert component to
VDOMNode.
- async async_wait_for_load(interval: float = 0.01)[source]¶
This asynchronously waits for the component to complete loading (if component is already being loaded somewhere).
- bind(event: str, event_handler: Callable, force_bind: bool = False, update_targets: Optional[List[duck.html.components.HtmlComponent]] = None, update_self: bool = True) None[source]¶
Bind an event handler to this component for the specified event type.
- Parameters:
event – The name of the event to bind (e.g., “click”, “input”).
event_handler – A callable (preferably async) that handles the event.
force_bind – If True, binds the event even if it’s not in the recognized set.
update_targets – Other components whose state may be modified when this event is triggered. Defaults to None.
update_self – Whether this component’s state may change as a result of the event. If False, only other components will be considered for DOM updates. Defaults to True.
- Raises:
UnknownEventError – If the event is not recognized and
force_bindis False.AssertionError – If the event handler is not a callable.
RedundantUpdate – If any component pair in
update_targetsshare the same root/parent.EventAlreadyBound – If event is already bound before.
… admonition:: Notes
If
update_selfis False and noupdate_targetsare provided, no DOM patch will be sent to the client.This method requires the Lively Component System to be active (i.e., running within a WebSocket context).
- check_component_system_active(inactive_msg: str = None)[source]¶
Checks if the component system responsible for
WebSocketcommunication with the client is active.… admonition:: Notes
The component system sends DOM patches to client using
WebSocketprotocol. It also receives component events so that they can be executed on the server. Sends signals to perform an action to the JS client WebSocket.
- copied_from() Optional[duck.html.components.HtmlComponent][source]¶
Returns the original component that this component was copied from (if applicable else None).
- copy(shallow: bool = False) duck.html.components.HtmlComponent[source]¶
Returns a copy of the component.
Notes:
Props, style, children are copied.
Iterative copy avoids recursion depth issues.
Shallow copy allowed only on frozen components.
- ensure_freeze(*args, **kwargs)[source]¶
This works just like
freeze()but does not raise an exception if component is not yet loaded.It ensures that
freezeis called whenever the component is loaded (if not already loaded) or just freeze the component right away if component is already loaded.
- force_set_component_attr(key: str, value: Any)[source]¶
Forcefully sets an attribute on the component, bypassing attribute protection.
- Parameters:
key – The attribute name to set.
value – The value to assign to the attribute.
This method temporarily disables component attribute protection, allowing internal code to set or overwrite protected attributes.
- get_children_string(childs: duck.html.components.core.children.ChildrenList) str[source]¶
Renders and joins the HTML strings of child components.
- Parameters:
childs – The child components to render.
- Returns:
The rendered HTML string of all children.
- Return type:
str
- get_component_system_data_props() Dict[str, str][source]¶
Returns the
data-*properties for events, actions, and other attributes used internally by theLivelycomponent system (e.g., for client-server sync via WebSocket).This typically includes:
data-uid: The stable component ID or unique ID if a component is a root component.data-events: A comma-separated list of bound event names. (if available)data-validate: Boolean on whether validation must be applied.
- Returns:
A dictionary of
data-*attributes and their corresponding values.- Return type:
Dict[str, str]
- get_css_string(style: duck.html.components.core.props.StyleStore[str, str], add_to_prev_states: bool = True) str[source]¶
Returns a CSS style string from a dictionary of style attributes.
- Parameters:
style – The style attributes (e.g., StyleStore({“color”: “red”, “font-size”: “12px”}) ).
add_to_prev_states – If True, the resulting style string is cached in the component’s previous state.
- Returns:
The computed CSS string.
- Return type:
str
- get_event_info(event: str) Tuple[Callable, Set[duck.html.components.HtmlComponent]][source]¶
Returns the event info in form: (event_handler, update_targets).
- get_partial_string()[source]¶
Returns the partial string containing the style, props & inner body (if applicable).
- get_props_string(props: duck.html.components.core.props.PropertyStore[str, str], add_to_prev_states: bool = True) str[source]¶
Returns an HTML property string from a dictionary of attributes.
- Parameters:
props – HTML attributes (e.g., PropertyStore({“id”: “main”, “class”: “container”}) ).
add_to_prev_states – If True, the resulting style string is cached in the component’s previous state.
- Returns:
A string of HTML element properties.
- Return type:
str
- get_raw_root() duck.html.components.Component[source]¶
Returns the raw root reference without evaluation, even if the root is self (unlike the
rootproperty).
- has_local_updates()[source]¶
Checks if the component itself has local updates excluding those of the children.
… admonition:: Notes
This doesn’t look for any changes to the children but only itself.
- property inner_html: str¶
Returns the inner body (innerHTML) for the component.
- is_a_copy() bool[source]¶
Returns a boolean on whether this component is a copy from another component.
- is_from_cache() bool[source]¶
Returns a boolean on whether this component has been retrieved from cache.
- load()[source]¶
Load the component, pack all descendants (if available).
- Raises:
ComponentError – If this method is used on non-root component or if component
is_loading()is True.
- on_mutation(mutation: duck.html.components.core.mutation.Mutation)[source]¶
This is called on component mutation. Either from props, style or children.
Notes:
This is only called if the component itself is a root component
- on_parent(parent: duck.html.components.Component)[source]¶
Called when the component has got a parent attached.
- on_root_finalized(root: duck.html.components.Component)[source]¶
Called when the component’s root element is permanently assigned.
This method is invoked once the component is fully integrated into its final root within the application’s structure, and this root will not change for the lifetime of the component. Use this hook to perform any final setup or initialization that requires access to the fully realized root element, such as registering with the root’s event system, performing final layout adjustments, or establishing contextual relationships within the application.
- Parameters:
root – The root element to which this component is now permanently attached. This is the final root and will not be reassigned.
- property parent: Optional[duck.html.components.Component]¶
Returns the parent for the html component. This is only resolved if this html component has been added to some html component children.
- pre_render() None[source]¶
Pre-renders this component and optionally its children to optimize future rendering.
- property properties¶
Returns the properties store for the HTML component.
- Returns:
The properties store for the HTML component.
- Return type:
- property props¶
Returns the properties store for the HTML component. (same as
propertiesproperty)- Returns:
The properties store for the HTML component.
- Return type:
- raise_if_not_loaded(message: str)[source]¶
Decorator which raises an exception if component is not loaded.
- Parameters:
message – A custom error message for the exception.
- Raises:
ComponentNotLoadedError – Raised if component is not loaded.
- property root: Optional[duck.html.components.Component]¶
Returns the root html component.
- set_mutation_callbacks()[source]¶
This sets the callbacks that will be executed on prop/style mutation.
- property style¶
Returns the style store for the HTML component.
- Returns:
The style store for the HTML component.
- Return type:
- to_string()[source]¶
Returns the string representation of the HTML component.
- Returns:
The string representation of the HTML component.
- Return type:
str
- to_vdom() duck.html.components.core.vdom.VDomNode[source]¶
Converts the HtmlComponent into a virtual DOM node.
- Returns:
A virtual DOM representation of the HTML component.
- Return type:
- toggle_validation(must_validate: bool)[source]¶
Whether to enable/disable validation on component before server receives an event.
Notes:
Validation is only applied if the JS element has both
checkValidityandreportValidity.
- traverse(func: callable, algorithm: str = 'depth_first_search', reverse: bool = False, include_self: bool = True) None[source]¶
Traverses the component tree and executes a callable on each node.
- Parameters:
func – Function to execute on each component (takes the component as argument).
algorithm – ‘depth_first_search’ or ‘breadth_first_search’.
reverse – If True, DFS visits children from last to first.
include_self – If True, traversal starts at self; otherwise, starts at children.
… admonition:: Notes
Iterative traversal is used to avoid recursion limits.
BFS ignores reverse.
func can read or modify nodes.
- traverse_ancestors(func: callable, include_self: bool = True) None[source]¶
Traverses upward from this component to the root, executing a callable on each ancestor.
- Parameters:
func – A function that takes a single argument (the component) and executes logic.
include_self – If True, starts at the current component; if False, starts at the parent.
Notes:
Stops when the root component (no parent) is reached.
Useful for propagating mutations, marking caches dirty, or other upward operations.
- property uid: str¶
Returns the UID for the component based on the component position.
- Returns:
An assigned component UID based on component position in component tree or a random string.
- Return type:
str
Notes:
This will be auto-assigned on render or when
to_vdomis called. These methods callassign_component_uidsfor assigning determinable UID’s.If a component is a root component, a unique ID will be generated whenever the
uidproperty is accessed.
- unbind(event: str, failsafe: bool = True)[source]¶
Remove/unbind an event from this component.
- Parameters:
event – The event name to unbind.
failsafe – If True (default), silently ignore if the event was never bound. If False, raise UnknownEventError if the event does not exist.
Raises UnknownEventError: If failsafe is False and the event is not bound.
- static vdom_diff(old: duck.html.components.core.vdom.VDomNode, new: duck.html.components.core.vdom.VDomNode) List[list][source]¶
Compute a minimal set of patches to transform one virtual DOM tree into another.
This method performs key-based diffing on children and emits compact patch lists using
vdom.PatchCodes. Each patch is a list optimized for fast encoding with MessagePack.- Parameters:
old – The previous virtual DOM node.
new – The updated virtual DOM node.
- Returns:
A list of compact patch operations (lists) in the format: [opcode, key, …data]
- Return type:
List[list]
- async static vdom_diff_and_act(action: Callable, old: duck.html.components.core.vdom.VDomNode, new: duck.html.components.core.vdom.VDomNode) None[source]¶
Compute a minimal set of patches to transform one virtual DOM tree into another.
This method performs key-based diffing on children and emits compact patch lists using PatchCode. Each patch is a list optimized for fast encoding with MessagePack.
This method diffs and perform an action on every patch rather than returning a list of all computed patches.
- Parameters:
action – A synchronous/asynchronous callable to perform on every patch. The first argument to this must be the patch.
old – The previous virtual DOM node.
new – The updated virtual DOM node.
- Returns:
Nothing to return.
- Return type:
None
- duck.html.components.InnerComponent¶
None
- class duck.html.components.InnerHtmlComponent(element: Optional[str] = None, properties: Optional[Dict[str, str]] = None, props: Optional[Dict[str, str]] = None, style: Optional[Dict[str, str]] = None, inner_html: Optional[Union[str, str, float]] = None, children: Optional[List[duck.html.components.HtmlComponent]] = None, **kwargs)[source]¶
Bases:
duck.html.components.extensions.BasicExtension,duck.html.components.extensions.StyleCompatibilityExtension,duck.html.components.HtmlComponentThis is the HTML component with Inner Body presence.
Form:
<mytag>Text here</mytag>Example:
<p>Text here</p> <h2>Text here</h2> <ol>List elements here</ol>Notes:
The html components that fall in this category are usually basic HTML elements.
Initialization
Initialize an HTML component.
- Parameters:
element – The HTML element tag name (e.g., textarea, input, button). Can be None, but make sure element is returned by get_element method.
accept_inner_html – Whether the HTML component accepts an inner body (e.g., inner-body-here).
inner_html – Inner html to add to the HTML component. Defaults to None.
properties – Dictionary for properties to initialize the component with.
props – Just same as properties argument (added for simplicity).
style – Dictionary for style to initialize the component with.
**kwargs – Extra keyword arguments
- Raises:
HtmlComponentError – If ‘element’ is not a string or ‘inner_html’ is set but ‘accept_inner_html’ is False.
- add_child(child: duck.html.components.HtmlComponent)[source]¶
Adds a child component to this HTML component.
- Parameters:
child – The child component to add.
- add_children(children: List[duck.html.components.HtmlComponent])[source]¶
Adds multiple child components to this HTML component.
- Parameters:
children – The list of child components to add.
- property children: duck.html.components.core.children.ChildrenList[duck.html.components.HtmlComponent]¶
Returns the component children.
- remove_child(child: duck.html.components.HtmlComponent)[source]¶
Removes a child component from this HTML component.
- Parameters:
child – The child component to remove.
- remove_children(children: List[duck.html.components.HtmlComponent])[source]¶
Removes multiple child components to this HTML component.
- Parameters:
children – The list of child components to remove.
- duck.html.components.NoInnerComponent¶
None
- class duck.html.components.NoInnerHtmlComponent(element: Optional[str] = None, properties: Dict[str, str] = None, props: Dict[str, str] = None, style: Dict[str, str] = None, **kwargs)[source]¶
Bases:
duck.html.components.extensions.BasicExtension,duck.html.components.extensions.StyleCompatibilityExtension,duck.html.components.HtmlComponentThis is the HTML component with no Inner Body.
Example:
<input> <!--Input element does not accept inner html (inner body)--> <b/> <!--Same applies with the bold tag-->Notes:
The html components that fall in this category are usually HTML Input elements.
Initialization
Initialize an HTML component.
- Parameters:
element – The HTML element tag name (e.g., textarea, input, button). Can be None, but make sure element is returned by get_element method.
accept_inner_html – Whether the HTML component accepts an inner body (e.g., inner-body-here).
inner_html – Inner html to add to the HTML component. Defaults to None.
properties – Dictionary for properties to initialize the component with.
props – Just same as properties argument (added for simplicity).
style – Dictionary for style to initialize the component with.
**kwargs – Extra keyword arguments
- Raises:
HtmlComponentError – If ‘element’ is not a string or ‘inner_html’ is set but ‘accept_inner_html’ is False.
- class duck.html.components.Theme[source]¶
Default Duck theme.
- background_color¶
‘#FFFFFF’
- border_radius¶
‘15px’
- button_style¶
None
- font_family¶
‘Arial, sans-serif’
- normal_font_size¶
‘16px’
- padding¶
‘10px’
- primary_color¶
‘#4B4E75’
- secondary_color¶
‘#A6B48B’
- text_color¶
‘#333333’
- duck.html.components.quote(html: Optional[str] = None, element: str = 'span', no_closing_tag: bool = False, **kwargs) Union[InnerComponent, NoInnerComponent][source]¶
Returns an html component quoting the provided html as its body.
- Parameters:
html – The html to quote, to set as the new html component body.
element – Element to quote with, Defaults to span.
no_closing_tag – Whether the returned html component does not need a closing tag.
**kwargs – Keyword arguments to parse to component
- Returns:
The html component with closing tags. NoInnerComponent: The html component with no closing tags.
- Return type:
InnerComponent
- duck.html.components.to_component(html: Optional[str] = None, tag: str = 'span', no_closing_tag: bool = False, **kwargs)[source]¶
Returns an html component quoting the provided html as its body. (Same as
quotefunction).- Parameters:
html – The html to quote, to set as the new html component body.
tag – HTML tag to quote with, Defaults to span.
no_closing_tag – Whether the returned html component does not need a closing tag.
**kwargs – Keyword arguments to parse to the component.
- Returns:
The html component with closing tags. NoInnerComponent: The html component with no closing tags.
- Return type:
InnerComponent