Skip to content
GitHub

API Reference

Any object that can render to an HTML string.

Implemented by Component, Element, and any custom renderable in lexigram-ui. Export this protocol from the UIModule so that other packages can accept UI objects without importing from lexigram-ui implementation modules.


Abstract base for all input components.

Provides:

  • Common props handling (name, value, label, error, disabled, required)
  • Shared CSS class generation
  • Common wrapper rendering (label + error display)

Subclasses must implement:

  • _render_input(): Returns the actual input element
__init__
def __init__(
    name: str,
    value: Any = None,
    label: str | None = None,
    error: str | None = None,
    disabled: bool = False,
    required: bool = False,
    readonly: bool = False,
    **props: Any
) -> None
input_id
property input_id() -> str

Get the input ID (from props or fallback to name).

render
def render() -> Any

Render complete input component.

Calls _render_input() and wraps with label/error if needed.


Base class for all actions (row, header, etc.).

Implements a fluent API for configuration.

Example

Action("approve")
.icon("check")
.color("success")
.requires_confirmation()
__init__
def __init__(
    name: str,
    label: str | None = None
)

Initialize an action.

Parameters
ParameterTypeDescription
`name`strUnique identifier for the action
`label`str | NoneDisplay label (defaults to title-cased name)
icon
def icon(
    icon: str,
    position: str = 'left'
) -> Self

Set action icon.

color
def color(color: str) -> Self

Set button color variant (primary, success, danger, etc.).

danger
def danger() -> Self

Set action color to danger.

success
def success() -> Self

Set action color to success.

warning
def warning() -> Self

Set action color to warning.

info
def info() -> Self

Set action color to info.

gray
def gray() -> Self

Set action color to gray.

url
def url(
    url: str | Callable,
    target: str = '_self'
) -> Self

Set URL for navigation actions.

action
def action(callback: Callable) -> Self

Set backend action handler.

open_modal
def open_modal(component: str | None = None) -> Self

Open a modal when clicked.

slide_over
def slide_over() -> Self

Open in a side panel (SlideOver) when clicked.

requires_confirmation
def requires_confirmation(
    title: str = 'Are you sure?',
    message: str | None = None
) -> Self

Require confirmation before execution.

visible
def visible(visible: bool | Callable = True) -> Self

Control visibility.

disabled
def disabled(disabled: bool | Callable = True) -> Self

Control enabled/disabled state.

hx
def hx(
    get: str | None = None,
    post: str | None = None,
    delete: str | None = None,
    target: str | None = None,
    swap: str | None = None,
    push_url: str | None = None
) -> Self

Configure HTMX attributes manually.

is_visible
def is_visible(
    user: Any = None,
    resource_name: str | None = None,
    record: dict | Any | None = None,
    permission_service: Any = None
) -> bool

Check if action should be visible.

is_disabled
def is_disabled(record: dict | None = None) -> bool

Check if action should be disabled.

get_url
def get_url(record: dict | None = None) -> str | None

Resolve URL if it’s a callable.

get_hx_get
def get_hx_get() -> str | None

Get the HTMX GET URL.

get_hx_post
def get_hx_post() -> str | None

Get the HTMX POST URL.

get_hx_delete
def get_hx_delete() -> str | None

Get the HTMX DELETE URL.

render
def render(
    record: dict | Any | None = None,
    user: Any = None,
    resource_name: str | None = None
) -> Any

Render action as a button using ActionButton.


Standardized action button with icon support and consistent styling.
__init__
def __init__(
    label: str,
    variant: Literal['primary', 'secondary', 'danger', 'ghost', 'link'] = 'primary',
    icon: str | None = None,
    icon_position: Literal['left', 'right'] = 'left',
    size: Literal['sm', 'md', 'lg'] = 'md',
    **props: Any
) -> None

Initialize action button.

Parameters
ParameterTypeDescription
`label`strButton text
`variant`Literal['primary', 'secondary', 'danger', 'ghost', 'link']Button style variant
`icon`str | NoneIcon name (from icons.py)
`icon_position`Literal['left', 'right']Position of icon relative to label
`size`Literal['sm', 'md', 'lg']Button size **props: Additional props (HTMX attributes, type, disabled, etc.)
render
def render() -> Any

Render action button.


Where the action result should be rendered.

__init__
def __init__(
    title: str = 'Recent Activity',
    items: list[dict[str, Any]] | None = None,
    max_items: int = 5,
    **props: Any
) -> None
render
def render() -> Any

ShadCN-styled card for admin dashboard sections.
Parameters
ParameterTypeDescription
`title`Optional card header text.
`content`Card body — a string, htpy element, or Component. **props: Additional HTML attributes applied to the outer div.
__init__
def __init__(
    title: str | Any | None = None,
    content: str | Any | None = None,
    **props: Any
) -> None
render
def render() -> Any

Alert component for notifications and messages.
__init__
def __init__(
    message: str,
    variant: AlertVariant = 'info',
    dismissible: bool = False,
    **props: Any
) -> None
render
def render() -> Any

__init__
def __init__(
    data: list[ChartDataPoint],
    config: ChartConfig | None = None,
    *,
    line_color: str = 'blue'
) -> None

Builder for ARIA attributes.
to_dict
def to_dict() -> dict[str, str]

Convert to HTML attribute dictionary.


ARIA live region politeness settings.

Common ARIA roles for components.

A layout component for asides/sidebars within a page.
__init__
def __init__(
    *children: Any,
    position: str = 'left',
    width: str = 'w-64',
    **props: Any
) -> None
render
def render() -> Any

HTMX polling container that re-fetches *url* every *interval_ms* ms.

The component renders a <div> with hx-get and hx-trigger="every <N>ms" attributes. The polled response should return an HTML fragment that replaces innerHTML of the container.

A “Pause / Resume” toggle button (Alpine.js) lets users stop polling without a page reload.

Parameters
ParameterTypeDescription
`url`Endpoint to poll (HTMX GET).
`interval_ms`Polling interval in milliseconds (default 5000).
`target_id```id`` given to the wrapper element, used as the HTMX target selector for OOB swaps.
`content`Optional initial HTML content rendered before first poll.
`label`Optional label shown next to the pause/resume button.
`show_controls`Whether to render the pause/resume button.
__init__
def __init__(
    url: str,
    interval_ms: int = 5000,
    target_id: str = 'auto-refresh-widget',
    content: Any = '',
    label: str = '',
    show_controls: bool = True,
    **props: Any
) -> None
render
def render() -> Any

Specialized file upload for user avatars.
render
def render() -> Any

Badge component for status indicators.
__init__
def __init__(
    text: str,
    variant: BadgeVariant = 'default',
    **props: Any
) -> None
render
def render() -> Any

Status badge column with color coding.
__init__
def __init__(
    name: str,
    label: str | None = None,
    colors: dict[str, str] | None = None
)

Initialize badge column.

Parameters
ParameterTypeDescription
`name`strColumn field name
`label`str | NoneDisplay label
`colors`dict[str, str] | NoneMapping of values to colors (e.g., {"active": "green", "inactive": "gray"})
colors
def colors(colors: dict[str, str]) -> BadgeColumn

Set color mapping for values.

icons
def icons(icons: dict[str, str]) -> BadgeColumn

Set icon mapping for values (emoji or icon class).

render
def render(
    value: Any,
    record: dict
) -> Any

Render as colored badge using atomic Badge component.


__init__
def __init__(
    data: list[ChartDataPoint],
    config: ChartConfig | None = None
) -> None
render
def render() -> Any

Base configuration for all layouts.

Extends HTMLDocumentConfig with common layout settings.


Base context for all layouts.

Common context data used across layouts.


Select field for BelongsTo relationships.

Links to another resource and can be searchable.

__init__
def __init__(
    name: str,
    resource: str,
    searchable: bool = False,
    **kwargs: Any
) -> None

Boolean column with icons.
__init__
def __init__(
    name: str,
    label: str | None = None
)
true_icon
def true_icon(icon: str) -> BooleanColumn

Set icon for true values.

false_icon
def false_icon(icon: str) -> BooleanColumn

Set icon for false values.

true_color
def true_color(color: str) -> BooleanColumn

Set color for true values.

false_color
def false_color(color: str) -> BooleanColumn

Set color for false values.

render
def render(
    value: Any,
    record: dict
) -> Any

Render as icon with color.


Breadcrumb navigation component with home icon.
Parameters
ParameterTypeDescription
`items`List of dicts with 'label' and 'url'
__init__
def __init__(
    items: list[dict[str, str]],
    **props: Any
) -> None
render
def render() -> Any

A block-based content editor. Allows adding, removing, and reordering structured content blocks.

Data is stored as a JSON array of objects: [ {“type”: “heading”, “data”: {“text”: “Hello”}}, {“type”: “text”, “data”: {“body”: “World”}} ]

__init__
def __init__(
    blocks: list[Any],
    name: str,
    value: list[dict] | str | None = None,
    label: str | None = None,
    **props: Any
) -> None
render
def render() -> Any

Action that applies to multiple selected items.
__init__
def __init__(
    name: str,
    label: str | None = None
)
deselect_after
def deselect_after(deselect: bool = True) -> Self

Deselect all items after action completes.


Button with ShadCN-compatible variants and sizes.
Parameters
ParameterTypeDescription
`label`Button text.
`variant`Visual style variant.
`size`Size variant.
`as_child`If True, renders as first child element. **props: Additional HTML attributes.
__init__
def __init__(
    label: str = '',
    *,
    variant: ButtonVariant = 'default',
    size: ButtonSize = 'default',
    as_child: bool = False,
    **props: Any
) -> None
render
def render() -> Any

Manages CSS asset injection for layout rendering.
__init__
def __init__() -> None

Initialize CSS collections.

add_css
def add_css(
    href: str,
    **attrs: str
) -> None

Add a CSS file link.

Parameters
ParameterTypeDescription
`href`strURL to CSS file **attrs: Additional attributes (media, crossorigin, etc.)
add_inline_style
def add_inline_style(css: str) -> None

Add inline CSS.

Parameters
ParameterTypeDescription
`css`strCSS rules
render_css
def render_css() -> str

Render all CSS as HTML.

Returns
TypeDescription
strHTML string with link and style tags

Refined Card component for better aesthetics.
__init__
def __init__(
    title: str | Any | None = None,
    content: str | Any | None = None,
    footer: Any = None,
    *,
    as_child: bool = False,
    **props: Any
) -> None
render
def render() -> Any




Alias for Toggle for semantic clarity.

Multiple checkboxes for list selection.
__init__
def __init__(
    name: str,
    choices: list[tuple[str, str]],
    inline: bool = False,
    **kwargs: Any
) -> None
render
def render() -> Any

Grid column component (vertical flow).
__init__
def __init__(
    *children: Any,
    gap: int = 4,
    span: int | None = None,
    **props: Any
) -> None
render
def render() -> Any

Color selection input.

Complete Column base class with all functionality.

Base UI Component for lexigram-admin (HTPy-backed).

Subclasses implement render() which returns either a string or an htpy element. render_to_string converts to HTML.

Components support Streamlit-style with usage via context manager methods: entering the context makes the component the current parent for subsequent calls to add_child_to_current or manual appends.

__init__
def __init__(
    *children: Any,
    as_child: bool = False,
    **props: Any
) -> None
on_mount
def on_mount() -> None

Lifecycle hook called when component is instantiated.

add
def add(*children: Any) -> Component

Fluent API to add children to this component.

render
def render() -> str | Any

__init__
def __init__(
    *children: Any,
    **props: Any
) -> None
render
def render() -> Any

Standard Create action implementation (Header Action).
__init__
def __init__(
    name: str = 'create',
    label: str = 'Create'
)
using_form_modal
def using_form_modal() -> Self

Configure to open in a modal.


Currency column with formatting.
__init__
def __init__(
    name: str,
    label: str | None = None,
    currency: str = 'USD'
)
currency
def currency(currency: str) -> CurrencyColumn

Set currency code (USD, EUR, GBP, etc.).

decimals
def decimals(decimals: int) -> CurrencyColumn

Set number of decimal places.

render
def render(
    value: Any,
    record: dict
) -> Any

Render as formatted currency.


Renderer for the client-side Alpine.js logic of the DataTable.
render
def render(all_ids: list[str]) -> Any

Date/datetime column with formatting.
__init__
def __init__(
    name: str,
    label: str | None = None,
    date_format: str = '%Y-%m-%d'
)

Initialize date column.

Parameters
ParameterTypeDescription
`name`strColumn field name
`label`str | NoneDisplay label
`date_format`strstrftime format string
format
def format(date_format: str) -> DateColumn

Set date format string.

date
def date() -> DateColumn

Format as date only (YYYY-MM-DD).

datetime
def datetime() -> DateColumn

Format as datetime (YYYY-MM-DD HH:MM:SS).

time
def time() -> DateColumn

Format as time only (HH:MM:SS).

relative
def relative(relative: bool = True) -> DateColumn

Show relative time (e.g., ‘2 hours ago’).

render
def render(
    value: Any,
    record: dict
) -> Any

Render formatted date.


Year/month/day drill-down filter navigation.

At each level the component renders quick-link buttons:

  • No selection: Shows clickable year links (last 5 years + current).
  • Year selected: Shows clickable month buttons (Jan–Dec).
  • Year + month selected: Shows clickable day buttons for that month.
  • Year + month + day: Shows breadcrumb with ”×” clear button.

HTMX is used to reload the table without a full page refresh.

Parameters
ParameterTypeDescription
`field_name`Model field being filtered (used in URL params as ``{field_name}__year``, etc.).
`year`Currently selected year, or ``None``.
`month`Currently selected month (1–12), or ``None``.
`day`Currently selected day (1–31), or ``None``.
`base_url`Base URL for building drill-down links.
`resource_prefix`HTMX target resource prefix.
`available_years`Explicit list of years to show. If ``None``, defaults to the 5 years before and including the current year from the *year* argument or ``2026``.
__init__
def __init__(
    field_name: str = 'created_at',
    year: int | None = None,
    month: int | None = None,
    day: int | None = None,
    base_url: str = '',
    resource_prefix: str = '',
    available_years: list[int] | None = None,
    **props: Any
) -> None
render
def render() -> Any

Date input with label and error support.
__init__
def __init__(
    name: str,
    min_value: str | None = None,
    max_value: str | None = None,
    input_type: str = 'date',
    **kwargs: Any
) -> None

A simple date range filter with start and end inputs.
__init__
def __init__(
    name_prefix: str = 'date',
    label: str = 'Date Range',
    **props: Any
) -> None
render
def render() -> Any

Configuration for debounced HTMX triggers.
to_trigger
def to_trigger(base_trigger: str = 'input') -> str

Generate HTMX trigger string with debounce.


Standard Delete action implementation.
__init__
def __init__(
    name: str = 'delete',
    label: str = 'Delete'
)

Standard Bulk Delete action.
__init__
def __init__(
    name: str = 'delete',
    label: str = 'Delete Selected'
)

Render a divider line.
Parameters
ParameterTypeDescription
`orientation`'horizontal' or 'vertical'
`class_name`Additional CSS classes
__init__
def __init__(
    orientation: str = 'horizontal',
    class_name: str = '',
    **props: Any
) -> None
render
def render() -> Any

A refined dropdown menu component with positioning control.
__init__
def __init__(
    trigger: str | Any,
    items: list[Any],
    position: str = 'right',
    direction: str = 'down',
    **props: Any
) -> None
render
def render() -> Any

Standard Edit action implementation.
__init__
def __init__(
    name: str = 'edit',
    label: str = 'Edit'
)
using_form_modal
def using_form_modal() -> Self

Configure to open in a modal.


A lightweight, structured HTML element compatible with htpy.

This provides a small subset of behaviour we need: HTML attribute escaping, boolean attributes, self-closing tag handling and a stable __html__/__str__ API so our render_to_string function can consistently produce HTML regardless of whether htpy is present.

__init__
def __init__(
    tag: str,
    *children: Any,
    **attrs: Any
) -> None

Email input - TextInput with type='email'.
__init__
def __init__(
    name: str,
    **kwargs: Any
) -> None

Empty state component for when no data is available.
Parameters
ParameterTypeDescription
`title`Main heading
`message`Descriptive message
`icon`Optional icon name (Lucide, resolved via ``get_icon``) or emoji
`action`Optional action button/link
__init__
def __init__(
    title: str = 'No data available',
    message: str = "There's nothing to display yet.",
    icon: str = '📭',
    action: Any = None,
    **props: Any
) -> None
render
def render() -> Any

Categories of errors with different handling strategies.

Standardized error response for HTMX.
to_toast_html
def to_toast_html() -> str

Render as a toast notification.

to_flash_html
def to_flash_html() -> str

Render as an OOB flash message targeting the flash container.

to_inline_errors_html
def to_inline_errors_html() -> str

Render field errors for form validation.

to_error_state_html
def to_error_state_html() -> str

Render as a full error state component.


Error state component for when something goes wrong.
Parameters
ParameterTypeDescription
`title`Error heading
`message`Error description
`action`Optional retry button/link
__init__
def __init__(
    title: str = 'Something went wrong',
    message: str = 'We encountered an error loading this data.',
    action: Any = None,
    **props: Any
) -> None
render
def render() -> Any

Standard Export action implementation.
__init__
def __init__(
    name: str = 'export',
    label: str = 'Export'
)

Standard Bulk Export action.
__init__
def __init__(
    name: str = 'export',
    label: str = 'Export Selected'
)

Error for a specific form field.

Form field wrapper with label, input, error message, and help text.
__init__
def __init__(
    input_component: Component,
    label: str | None = None,
    error: str | None = None,
    help_text: str | None = None,
    hint: str | None = None,
    required: bool = False,
    hidden: bool = False,
    visible_condition: str | None = None,
    **props: Any
) -> None
render
def render() -> Any

Native fieldset component for grouping form fields with a legend.
Parameters
ParameterTypeDescription
`legend`The title of the fieldset
`description`Optional description text
__init__
def __init__(
    *children: Any,
    legend: str,
    description: str | None = None,
    **props: Any
) -> None
render
def render() -> Any

File upload component with validation and preview.

Example

FileUpload( name=“avatar”, label=“Profile Picture”, accept=“image/*”, max_size=5 * 1024 * 1024, # 5MB preview=True )

__init__
def __init__(
    name: str,
    label: str | None = None,
    accept: str | None = None,
    max_size: int | None = None,
    preview: bool = False,
    required: bool = False,
    disabled: bool = False,
    error: str | None = None,
    help_text: str | None = None,
    **props: Any
) -> None

Initialize file upload component.

Parameters
ParameterTypeDescription
`name`strInput name attribute
`label`str | NoneLabel text
`accept`str | NoneAccepted file types
`max_size`int | NoneMaximum file size in bytes
`preview`boolShow image preview
`required`boolWhether field is required
`disabled`boolWhether field is disabled
`error`str | NoneError message
`help_text`str | NoneHelp text **props: Additional properties
render
def render() -> Any

Render the file upload component.


Slide-over filter panel with stacked filter controls.

Renders a “Filters” trigger button whose badge shows the number of active filters, and a slide-over panel that contains the full filter form. The panel is driven by Alpine.js (filterDrawerOpen state) so it requires no page reload to open/close.

Parameters
ParameterTypeDescription
`filters`Same format as ``FilterBar.filters`` — dict of ``{field_name: {"type": ..., "options": [...], ...}}``.
`current_values`Current active filter values.
`resource_prefix`Resource URL prefix for HTMX ``hx-get`` attributes.
`state`Optional ``TableState`` for building HTMX attrs on apply.
__init__
def __init__(
    filters: list[Any] | dict[str, Any] | None = None,
    current_values: dict[str, Any] | None = None,
    resource_prefix: str | None = None,
    state: Any | None = None,
    **props: Any
) -> None
render
def render() -> Any

A dropdown filter for selecting categories or status.
__init__
def __init__(
    name: str,
    label: str,
    options: list[tuple[str, str]],
    multi: bool = False,
    **props: Any
) -> None
render
def render() -> Any

Configuration for footer.

A footer link.

Renders the admin footer.
__init__
def __init__(config: FooterConfig | None = None)

Initialize the renderer.

Parameters
ParameterTypeDescription
`config`FooterConfig | NoneFooter configuration
render
def render() -> str

Render the footer.

Returns
TypeDescription
strHTML string for footer

A container for form fields with HTMX submission support.
__init__
def __init__(
    action_url: str | None = None,
    method: str = 'post',
    submit_label: str = 'Save',
    hx_target: str = '#main-content',
    hx_swap: str = 'innerHTML',
    autosave: bool = False,
    form_id: str | None = None,
    suppress_submit: bool = False,
    **props: Any
) -> None
render
def render() -> Any

Form actions component for submit/cancel buttons.

Example

FormActions( primary_text=“Save Changes”, secondary_text=“Cancel”, primary_loading=False, cancel_url=“/admin/users” )

__init__
def __init__(
    primary_text: str = 'Save',
    secondary_text: str | None = 'Cancel',
    primary_loading: bool = False,
    primary_disabled: bool = False,
    cancel_url: str | None = None,
    align: str = 'right',
    **props: Any
) -> None

Initialize form actions.

Parameters
ParameterTypeDescription
`primary_text`strPrimary button text
`secondary_text`str | NoneSecondary button text (None to hide)
`primary_loading`boolShow loading state on primary button
`primary_disabled`boolDisable primary button
`cancel_url`str | NoneURL for cancel button (if not provided, uses history.back())
`align`strButton alignment (left, center, right) **props: Additional properties
render
def render() -> Any

Render the form actions.


Form field wrapper with label, input, error message, and help text.
__init__
def __init__(
    input_component: Component,
    label: str | None = None,
    error: str | None = None,
    help_text: str | None = None,
    hint: str | None = None,
    required: bool = False,
    hidden: bool = False,
    visible_condition: str | None = None,
    **props: Any
) -> None
render
def render() -> Any

Generic CSS Grid component.
__init__
def __init__(
    *children: Any,
    cols: int | dict[str, int] = 1,
    gap: int = 4,
    **props: Any
) -> None
render
def render() -> Any

Grouping dropdown switcher for DataTable.

Renders a compact dropdown listing the table columns as grouping options (plus “No grouping”) and emits HTMX requests carrying the group_by query param through the updated TableState.

__init__
def __init__(
    current: str | None = None,
    resource_prefix: str | None = None,
    columns: list[Any] | None = None,
    state: TableState | None = None,
    **props: Any
) -> None
render
def render() -> Any

Abstract base class for HTML document generation.

Provides the basic HTML5 document structure that all layouts build upon. Subclasses implement render_head_content(), render_body_content(), and render_body_end() to customize the document.

Features:

  • DOCTYPE html5
  • Configurable lang, charset, meta tags
  • Extensible head and body sections
  • Escape-safe by default
__init__
def __init__(config: HTMLDocumentConfig | None = None)

Initialize the document.

Parameters
ParameterTypeDescription
`config`HTMLDocumentConfig | NoneDocument configuration
render
def render(
    title: str = '',
    **context: Any
) -> Markup

Render the complete HTML document.

Parameters
ParameterTypeDescription
`title`strDocument title **context: Additional context for subclass rendering
Returns
TypeDescription
MarkupComplete HTML document as Markup
get_body_attributes
def get_body_attributes(**context: Any) -> str

Get body element attributes.

Override in subclasses to add classes, data attributes, etc.

Returns
TypeDescription
strString of HTML attributes
render_head_content
def render_head_content(**context: Any) -> str

Render content for the head section.

Subclasses should implement this to add CSS links, inline styles, etc.

Returns
TypeDescription
strHTML string for head section
render_body_content
def render_body_content(**context: Any) -> str | Markup

Render the main body content.

Subclasses should implement this to render the page content.

Returns
TypeDescription
str | MarkupHTML string or Markup for body content
render_body_end
def render_body_end(**context: Any) -> str

Render content at the end of body (before ).

Subclasses can override to add scripts, etc.

Returns
TypeDescription
strHTML string for body end

Configuration for HTML document generation.

Factory for HTMX attributes.

This class provides convenient static methods for generating HTMX attributes for common use cases. For more control, use HTMXAttrsBuilder directly.

Examples

attrs = HTMXAttrs.for_data_refresh(state, “/admin/users”)

attrs = HTMXAttrs.for_full_refresh(state, “/admin/users”)

attrs = HTMXAttrs.for_delete(“/admin/users/123”, confirm=“Delete this user?”)

attrs = HTMXAttrs.for_bulk_action(“/admin/users/bulk/delete”, “DELETE”)

for_full_refresh
def for_full_refresh(
    state: TableState,
    resource_prefix: str,
    push_url: bool = True,
    **extra_params: Any
) -> dict[str, str]

Generate HTMX attributes for a full table refresh.

Use for: Layout changes, view changes, clearing all filters.

Parameters
ParameterTypeDescription
`state`TableStateCurrent table state
`resource_prefix`strBase URL (e.g., "/admin/users")
`push_url`boolUpdate browser history (default True) **extra_params: Additional query parameters
Returns
TypeDescription
dict[str, str]Dict of hx-* attributes
for_data_refresh
def for_data_refresh(
    state: TableState,
    resource_prefix: str,
    push_url: bool = True,
    **extra_params: Any
) -> dict[str, str]

Generate HTMX attributes for a data zone refresh.

Use for: Filtering, sorting, pagination, search.

Parameters
ParameterTypeDescription
`state`TableStateCurrent table state
`resource_prefix`strBase URL
`push_url`boolUpdate browser history (default True) **extra_params: Additional query parameters
Returns
TypeDescription
dict[str, str]Dict of hx-* attributes
for_modal
def for_modal(url: str) -> dict[str, str]

Generate HTMX attributes for opening a modal.

Parameters
ParameterTypeDescription
`url`strURL to load into modal
Returns
TypeDescription
dict[str, str]Dict of hx-* attributes
for_slide_over
def for_slide_over(url: str) -> dict[str, str]

Generate HTMX attributes for opening a slide-over panel.

Parameters
ParameterTypeDescription
`url`strURL to load into slide-over
Returns
TypeDescription
dict[str, str]Dict of hx-* attributes
for_delete
def for_delete(
    url: str,
    target_zone: Zone | None = None,
    confirm_message: str | None = None
) -> dict[str, str]

Generate HTMX attributes for a delete action.

Parameters
ParameterTypeDescription
`url`strDelete endpoint URL
`target_zone`Zone | NoneZone to update after delete (default: DATA)
`confirm_message`str | NoneOptional confirmation dialog
Returns
TypeDescription
dict[str, str]Dict of hx-* attributes
for_bulk_action
def for_bulk_action(
    url: str,
    method: str = 'POST',
    confirm_message: str | None = None,
    action_name: str | None = None
) -> dict[str, str]

Generate HTMX attributes for a bulk action.

Bulk actions include the checked checkboxes from the table plus the action name so the server can dispatch correctly.

Parameters
ParameterTypeDescription
`url`strBulk action endpoint URL
`method`strHTTP method (POST, DELETE, etc.)
`confirm_message`str | NoneOptional confirmation dialog
`action_name`str | NoneAction identifier sent as ``action`` form value
Returns
TypeDescription
dict[str, str]Dict of hx-* attributes
for_form_submit
def for_form_submit(
    url: str,
    method: str = 'POST',
    target_zone: Zone | None = None,
    _close_on_success: bool = True
) -> dict[str, str]

Generate HTMX attributes for form submission.

Parameters
ParameterTypeDescription
`url`strForm action URL
`method`strHTTP method
`target_zone`Zone | NoneZone to update on success (default: DATA)
`close_on_success`Whether to close modal/slide-over
Returns
TypeDescription
dict[str, str]Dict of hx-* attributes
for_live_table_input
def for_live_table_input(
    _state: TableState,
    resource_prefix: str,
    input_name: str | None = None
) -> dict[str, str]

Generate HTMX attributes for a live table input (search-as-you-type).

Exception to the baked-URL pattern: live inputs use hx-include to send the current input value with each keystroke, rather than baking state into the URL. The input value changes too frequently for URL-based state.

Parameters
ParameterTypeDescription
`state`Current table state (not baked into URL — used for hx-include scope)
`resource_prefix`strBase URL (e.g., "/admin/users")
`input_name`str | NoneOptional custom name attribute for the live input selector. Defaults to the SEARCH zone ID.
Returns
TypeDescription
dict[str, str]Dict of hx-* attributes for a live table input.
merge
def merge(*attr_dicts: dict[str, str]) -> dict[str, str]

Merge multiple HTMX attribute dictionaries.

Later values override earlier ones.

Parameters
ParameterTypeDescription
Returns
TypeDescription
dict[str, str]Merged dictionary

Builder for consistent HTMX attributes.

This class encapsulates the logic for generating correct HTMX attributes for different action types. Use the static methods on HTMXAttrs for convenience unless you need custom configuration.

Attributes: action: The type of action (determines target zone and swap mode) state: The current TableState (used for baked URLs) resource_prefix: The base URL for the resource (e.g., “/admin/users”) extra_params: Additional query parameters to include push_url: Whether to update browser history (default: True for refresh actions) confirm_message: Optional confirmation dialog message

build
def build() -> dict[str, str]

Generate HTMX attributes based on action type.

Returns a dict of hx-* attributes ready to be spread onto an element.


Configuration for head section.

Renders the head section content.
__init__
def __init__(config: HeadConfig | None = None)

Initialize the renderer.

Parameters
ParameterTypeDescription
`config`HeadConfig | NoneHead configuration
render
def render(extra_css: str = '') -> str

Render the head content.

Parameters
ParameterTypeDescription
`extra_css`strAdditional inline CSS to include
Returns
TypeDescription
strHTML string for head section

Hidden input field.
render
def render() -> Any

Builder for HTMX action responses with merged HX-Trigger headers.
Parameters
ParameterTypeDescription
`toast`Optional toast notification to include in the trigger payload.
`trigger`Additional HX-Trigger events to merge alongside the toast.
`status_code`HTTP status code for the response (default 200).

Usage

return HtmxActionResponse(
toast=ToastData(message="User deleted", type=ToastType.SUCCESS),
trigger={"refresh-list": True},
status_code=200,
).to_response()
return HtmxActionResponse(
toast=ToastData(message="User deleted", type=ToastType.SUCCESS),
trigger={"refresh-list": True},
status_code=200,
).to_response()
to_response
def to_response() -> Any

Return a Starlette HTMLResponse with the merged HX-Trigger header.

Returns
TypeDescription
Any``starlette.responses.HTMLResponse`` with empty body and ``HX-Trigger`` header set.

Icon atom that wraps `get_icon` for consistent usage in templates.
Parameters
ParameterTypeDescription
`name`icon name (string or raw node)
`size`Tailwind size classes for icon (default: 'w-5 h-5')
`class_name`extra classes to apply to the icon
`aria_hidden`When True (default), marks icon as decorative with aria-hidden="true". Set to False for meaningful icons and supply an aria_label.
`aria_label`Accessible label for meaningful icons (used when aria_hidden=False).
__init__
def __init__(
    name: str | Any,
    size: str = 'w-5 h-5',
    class_name: str = '',
    aria_hidden: bool = True,
    aria_label: str | None = None,
    **props: Any
) -> None
render
def render() -> Any

Image column with thumbnail preview.
__init__
def __init__(
    name: str,
    label: str | None = None
)
size
def size(size: int) -> ImageColumn

Set image size in Tailwind units (e.g., 10 = 40px).

circular
def circular() -> ImageColumn

Make image circular.

square
def square() -> ImageColumn

Make image square with rounded corners.

render
def render(
    value: Any,
    record: dict
) -> Any

Render as image thumbnail.


A component that triggers an HTMX request when scrolled into view.
__init__
def __init__(
    url: str,
    trigger: str = 'revealed',
    target: str | None = None,
    swap: str = 'afterend',
    select: str | None = None,
    **props: Any
) -> None
render
def render() -> Any

A single labelled entry within an ``InfolistWidget``.


Render a read-only list of labelled entries suitable for detail pages.

Entries are arranged in a configurable-column grid. Supports grouping by section headings.

__init__
def __init__(
    entries: list[InfolistEntry],
    columns: int = 2,
    **props: Any
) -> None
render
def render() -> Element

A table cell whose value can be edited in place.

On click the cell switches to an <input> (or <select> / <textarea>). On blur / Enter it fires PATCH {resource_url} with {field_name}=<new_value>. On Escape it discards the change and reverts.

Parameters
ParameterTypeDescription
`value`Current display value.
`resource_url`URL to PATCH, e.g. ``"/admin/users/42"``.
`field_name`Form field name to send in the PATCH body.
`cell_type```"text"``, ``"number"``, ``"select"``, or ``"textarea"``.
`options`For ``cell_type="select"`` — list of ``{"value": …, "label": …}`` dicts.
`placeholder`Placeholder text for the input.
`css_class`Additional Tailwind classes on the outer container.
`editable`When ``False`` renders a plain non-editable cell.
__init__
def __init__(
    value: str,
    resource_url: str,
    field_name: str,
    *,
    cell_type: str = 'text',
    options: list[dict[str, str]] | None = None,
    placeholder: str = '',
    css_class: str = '',
    editable: bool = True
) -> None
render
def render() -> object

Render the inline-edit cell wrapper.


Toast notification component with Alpine.js auto-dismiss and optional action.

For server-driven toasts (HTMX X-Toast headers, configurable position, stacking), use ServerToastChannel with ToastData instead.

Parameters
ParameterTypeDescription
`message`Notification message.
`toast_type`Severity — ``"info"``, ``"success"``, ``"warning"``, ``"error"``.
`duration`Auto-dismiss delay in milliseconds (default 3000).
`action_label`Optional label for an inline action button.
`action_url`URL the action button links to (``href`` when set).
__init__
def __init__(
    message: str,
    toast_type: str = 'info',
    duration: int = 3000,
    action_label: str = '',
    action_url: str = '',
    **props: Any
) -> None
render
def render() -> Any

Text input with label and error support.
Parameters
ParameterTypeDescription
`name`Input name attribute
`value`Input value
`type`Input type (text, password, email, etc.)
`placeholder`Placeholder text
`label`Optional label text
`error`Error message to display
`disabled`Whether input is disabled
`required`Whether input is required
`readonly`Whether input is readonly **props: Additional HTML attributes (hx_*, data-*, etc.)

Example

TextInput( name=“username”, label=“Username”, placeholder=“Enter username”, required=True )

__init__
def __init__(
    name: str,
    value: str | None = None,
    input_type: str = 'text',
    placeholder: str | None = None,
    **kwargs: Any
) -> None

Input with prefix or suffix add-ons.
__init__
def __init__(
    label: str,
    name: str,
    input_type: str = 'text',
    prefix: str | None = None,
    suffix: str | None = None,
    placeholder: str | None = None,
    value: str = '',
    error: str | None = None,
    **props: Any
) -> None
render
def render() -> Any

Manages JavaScript asset injection for layout rendering.
__init__
def __init__() -> None

Initialize JS collections.

add_js
def add_js(
    src: str,
    defer: bool = False,
    async_: bool = False,
    **attrs: str
) -> None

Add a JavaScript file.

Parameters
ParameterTypeDescription
`src`strURL to JS file
`defer`boolAdd defer attribute
`async_`boolAdd async attribute **attrs: Additional attributes
add_inline_script
def add_inline_script(
    script: str,
    defer: bool = False
) -> None

Add inline JavaScript.

Parameters
ParameterTypeDescription
`script`strJavaScript code
`defer`boolIf True, render at end of body
render_js_head
def render_js_head() -> str

Render JS for head section.

Returns
TypeDescription
strHTML string with script tags
render_js_body_end
def render_js_body_end() -> str

Render deferred JS for end of body.

Returns
TypeDescription
strHTML string with script tags

Component for jumping to a specific page number. Uses Zone-based targeting for consistent HTMX behavior.
__init__
def __init__(
    page: int = 1,
    total_pages: int = 1,
    per_page: int = 20,
    base_url: str = '',
    extra_query: str = '',
    hx_target: str | None = None,
    hx_swap: str = 'innerHTML',
    hx_push_url: str = 'true',
    state: Any | None = None,
    **props: Any
) -> None
render
def render() -> Any

Component for editing key-value pairs (JSON dictionary).
__init__
def __init__(
    name: str,
    key_label: str = 'Key',
    value_label: str = 'Value',
    **kwargs: Any
) -> None
render
def render() -> Any

Accessible label component for form fields and descriptive text.

Can be used as a standalone text label or associated with a form control via the for_ attribute (renders as HTML for).

Example

Label("Email address", for_="email-input", required=True)
Label("Optional note", size="sm", weight="normal")
Label("Email address", for_="email-input", required=True)
Label("Optional note", size="sm", weight="normal")
__init__
def __init__(
    text: str,
    for_: str | None = None,
    required: bool = False,
    size: LabelSize = 'sm',
    weight: LabelWeight = 'medium',
    muted: bool = False,
    **props: Any
) -> None

Initialise a Label atom.

Parameters
ParameterTypeDescription
`text`strThe visible label text.
`for_`str | NoneThe ``id`` of the associated form control (renders as ``for``).
`required`boolWhen ``True`` appends a required indicator asterisk.
`size`LabelSizeText size variant — ``"xs"``, ``"sm"`` (default), ``"md"``, ``"lg"``.
`weight`LabelWeightFont-weight variant.
`muted`boolWhen ``True`` applies a muted/secondary text colour. **props: Additional HTML attributes forwarded to the element.
render
def render() -> Any

Render the label element.


Base layout class for all admin layouts.

Combines HTMLDocument with CSS, JS, HTMX, and theming via composition. Subclasses should implement render_body_content() and optionally override other methods for customization.

Example

class MyLayout(LayoutBase): def render_body_content(self, content: str = "", **context) -> str: return f’

{content}

__init__
def __init__(
    config: BaseLayoutConfig | None = None,
    context: BaseLayoutContext | None = None
)

Initialize the layout.

Parameters
ParameterTypeDescription
`config`BaseLayoutConfig | NoneLayout configuration
`context`BaseLayoutContext | NoneLayout context
add_css
def add_css(
    href: str,
    **attrs: str
) -> None

Add a CSS file link.

Parameters
ParameterTypeDescription
`href`strURL to CSS file **attrs: Additional attributes (media, crossorigin, etc.)
add_inline_style
def add_inline_style(css: str) -> None

Add inline CSS.

Parameters
ParameterTypeDescription
`css`strCSS rules
render_css
def render_css() -> str

Render all CSS as HTML.

Returns
TypeDescription
strHTML string with link and style tags
add_js
def add_js(
    src: str,
    defer: bool = False,
    async_: bool = False,
    **attrs: str
) -> None

Add a JavaScript file.

Parameters
ParameterTypeDescription
`src`strURL to JS file
`defer`boolAdd defer attribute
`async_`boolAdd async attribute **attrs: Additional attributes
add_inline_script
def add_inline_script(
    script: str,
    defer: bool = False
) -> None

Add inline JavaScript.

Parameters
ParameterTypeDescription
`script`strJavaScript code
`defer`boolIf True, render at end of body
render_js_head
def render_js_head() -> str

Render JS for head section.

Returns
TypeDescription
strHTML string with script tags
render_js_body_end
def render_js_body_end() -> str

Render deferred JS for end of body.

Returns
TypeDescription
strHTML string with script tags
get_htmx_config
def get_htmx_config() -> dict[str, Any]

Get HTMX configuration.

Returns
TypeDescription
dict[str, Any]Configuration dict for htmx.config
render_htmx_head
def render_htmx_head() -> str

Render HTMX script tag for head.

Returns
TypeDescription
strHTML string with HTMX script
get_htmx_body_attrs
def get_htmx_body_attrs() -> str

Get HTMX-related body attributes.

Returns
TypeDescription
strString of HTML attributes
get_theme_css_variables
def get_theme_css_variables() -> str

Generate ShadCN-compatible CSS variable declarations.

get_theme_html_attrs
def get_theme_html_attrs() -> str

Get theme-related HTML element attributes.

Returns
TypeDescription
strString of HTML attributes
get_dark_mode_script
def get_dark_mode_script() -> str

Inline script that applies dark class before paint (prevents FOUC).

Must run synchronously in <head> before any CSS paints.

get_alpine_theme_data
def get_alpine_theme_data() -> str

Register Alpine.js theme toggle component data.

render
def render(
    content: str | Markup = '',
    title: str | None = None,
    **extra_context: Any
) -> Markup

Render the complete layout.

Parameters
ParameterTypeDescription
`content`str | MarkupMain page content
`title`str | NonePage title (overrides context title) **extra_context: Additional context
Returns
TypeDescription
MarkupComplete HTML document as Markup
get_body_attributes
def get_body_attributes(**context: Any) -> str

Get body element attributes including theme and HTMX.

render_head_content
def render_head_content(**context: Any) -> str

Render head content (CSS, theme, HTMX).

render_body_content
def render_body_content(
    content: str = '',
    **context: Any
) -> str | Markup

Render body content.

Default implementation just returns content. Subclasses should override to add layout structure.

Parameters
ParameterTypeDescription
`content`strMain content **context: Additional context
Returns
TypeDescription
str | MarkupHTML string or Markup
render_body_end
def render_body_end(**context: Any) -> str

Render content at end of body (deferred scripts).


Simple layout switcher (stack | sidebar) for DataTable.

Renders compact options and uses HTMX to request the table fragment with the chosen layout_type query param.

__init__
def __init__(
    current: str = 'stack',
    resource_prefix: str | None = None,
    state: TableState | None = None,
    **props: Any
) -> None
render
def render() -> Any

Select dropdown that support infinite scroll / lazy loading of options.
__init__
def __init__(
    name: str,
    lazy_url: str,
    choices: list[tuple[str, str]] | None = None,
    page: int = 1,
    **kwargs: Any
) -> None
render_options
def render_options() -> list[Any]

__init__
def __init__(
    data: list[ChartDataPoint],
    config: ChartConfig | None = None,
    *,
    line_color: str = 'blue',
    fill_area: bool = False
) -> None
render
def render() -> Any

Create a consistent styled link element.
Parameters
ParameterTypeDescription
`label`Link text
`href`URL
`variant`Visual style variant
`size`Optional size (sm, md, lg)
__init__
def __init__(
    label: str,
    href: str,
    *,
    as_child: bool = False,
    variant: LinkVariant = 'default',
    size: LinkSize | None = None,
    **props: Any
) -> None
render
def render() -> Any

Column for rendering lists of strings (e.g., tags, categories).
__init__
def __init__(
    name: str,
    label: str | None = None
)
badge
def badge(badge: bool = True) -> ListColumn

Render items as badges.

render
def render(
    value: Any,
    record: dict
) -> Any

Render list items.


A simple counter that updates in real-time.
__init__
def __init__(
    label: str,
    url: str,
    interval: str = '5s',
    **props: Any
)
render
def render() -> Any

Auto-refreshing data table variant.

Convenience subclass with table-appropriate defaults: longer interval and no pause/resume controls by default.

Parameters
ParameterTypeDescription
`url`Endpoint returning updated table HTML fragment.
`interval_ms`Polling interval (default 30 000 ms = 30 s).
`target_id`Wrapper element ID.
`show_controls`Whether to show pause button (default True).
__init__
def __init__(
    url: str,
    interval_ms: int = 30000,
    target_id: str = 'live-data-table',
    show_controls: bool = True,
    **props: Any
) -> None

Full-screen or container loading overlay.
Parameters
ParameterTypeDescription
`message`Optional loading message
`fullscreen`Whether to cover entire screen
__init__
def __init__(
    message: str = 'Loading...',
    fullscreen: bool = True,
    **props: Any
) -> None
render
def render() -> Any

Markdown editor with optional preview toggle. Uses Alpine.js for client-side preview mode switching.
__init__
def __init__(
    name: str,
    value: str | None = None,
    label: str | None = None,
    placeholder: str | None = None,
    error: str | None = None,
    rows: int = 10,
    disabled: bool = False,
    preview: bool = True,
    min_height: int = 300,
    **props: Any
) -> None
render
def render() -> Any

MetricProtocol card for dashboard statistics.

Example

MetricCard( value=“1,234”, label=“Total Users”, trend=“+12%”, trend_direction=“up”, icon=”👥”, color=“success” )

__init__
def __init__(
    value: str | float,
    label: str,
    trend: str | None = None,
    trend_direction: TrendDirection | None = None,
    icon: str | None = None,
    variant: MetricCardVariant = 'default',
    **props: Any
) -> None

Initialize metric card.

Parameters
ParameterTypeDescription
`value`str | floatThe metric value (number or formatted string)
`label`strDescription label
`trend`str | NoneTrend indicator (e.g., "+12%", "-5%")
`trend_direction`TrendDirection | NoneDirection of trend ("up" or "down")
`icon`str | NoneOptional icon (emoji or icon class)
`variant`MetricCardVariantColor variant **props: Additional properties
render
def render() -> Any

Render the metric card.


A single metric data point.

Types of metrics to collect.

Collect and track UI metrics.

This is a simple in-memory collector. For production, integrate with Prometheus, StatsD, or similar.

__init__
def __init__() -> None
inc
def inc(
    name: str,
    value: float = 1.0,
    labels: dict[str, str] | None = None
) -> None

Increment a counter.

observe
def observe(
    name: str,
    value: float,
    labels: dict[str, str] | None = None
) -> None

Record a histogram observation.

set
def set(
    name: str,
    value: float,
    labels: dict[str, str] | None = None
) -> None

Set a gauge value.

get_counter
def get_counter(
    name: str,
    labels: dict[str, str] | None = None
) -> float

Get counter value.

get_histogram_stats
def get_histogram_stats(
    name: str,
    labels: dict[str, str] | None = None
) -> dict[str, float]

Get histogram statistics.

get_gauge
def get_gauge(
    name: str,
    labels: dict[str, str] | None = None
) -> float

Get gauge value.

reset
def reset() -> None

Reset all metrics.

to_dict
def to_dict() -> dict[str, Any]

Export all metrics as dictionary.


__init__
def __init__(
    value: float,
    max_value: float = 100,
    *,
    color: str = 'blue',
    height: int = 8,
    width: int = 60,
    show_value: bool = False
) -> None
render
def render() -> Any

A FAANG-level modal dialog powered by Alpine.js.
__init__
def __init__(
    title: str,
    trigger: str | Any = None,
    footer: list[Any] | None = None,
    is_open: bool = False,
    render_trigger: bool = True,
    max_width: str | None = None,
    max_height: str | None = None,
    **props: Any
) -> None
render
def render() -> Any

Polymorphic relationship selector.

Consisted of two dropdowns: one for the type and one for the ID.

__init__
def __init__(
    name: str,
    type_name: str,
    types: list[tuple[str, str]],
    options_url: str,
    type_value: Any = None,
    **kwargs: Any
) -> None
render
def render() -> Any

Premium multi-file upload with drag and drop.
__init__
def __init__(
    name: str,
    accept: str = '*',
    **kwargs: Any
) -> None
render
def render() -> Any

Premium searchable tags-style multi-select.
__init__
def __init__(
    name: str,
    choices: list[tuple[str, str]],
    placeholder: str = 'Select options...',
    **kwargs: Any
) -> None
render
def render() -> Any

Native browser multiple select dropdown.
__init__
def __init__(
    *args: Any,
    **kwargs: Any
) -> None

In-app notification bell with real-time updates via SSE.

Alpine.js-driven component that loads the persisted inbox from the admin JSON endpoints, displays an unread count badge on the bell icon, and shows a dropdown of recent notifications with mark-as-read support (posting back to the inbox endpoints).

Parameters
ParameterTypeDescription
`sse_url`SSE endpoint URL for real-time notification events.
`inbox_url`Link to the full notification inbox page. The "View all" footer is only rendered when a URL is set.
`inbox_api_url`JSON endpoint returning the persisted inbox (``{"unread_count": ..., "notifications": [...]}``).
`mark_read_url`POST endpoint marking one message read; the literal ``{message_id}`` placeholder is replaced with the message ID.
`mark_all_read_url`POST endpoint marking every message read.
`max_display`Maximum number of notifications shown in the dropdown. **props: Extra HTML attributes forwarded to the root element.
__init__
def __init__(
    sse_url: str = '/admin/_sse/events',
    inbox_url: str | None = None,
    inbox_api_url: str = '/admin/notifications/inbox',
    mark_read_url: str = '/admin/notifications/read/{message_id}',
    mark_all_read_url: str = '/admin/notifications/read-all',
    max_display: int = 10,
    **props: Any
) -> None
render
def render() -> Any

Number input with min/max/step validation.
Parameters
ParameterTypeDescription
`name`Input name attribute
`value`Input value
`min`Minimum allowed value
`max`Maximum allowed value
`step`Step increment
`label`Optional label text
`error`Error message to display **kwargs: Additional props
__init__
def __init__(
    name: str,
    value: float | None = None,
    min_value: float | None = None,
    max_value: float | None = None,
    step: float | None = None,
    placeholder: str | None = None,
    **kwargs: Any
) -> None

Full-page admin layout wrapper with a header bar and content area.
Parameters
ParameterTypeDescription
`title`Page title rendered in the header.
`children`Main page content — string, htpy element, Component, or list thereof.
`actions`Optional list of elements (e.g. Buttons) rendered in the header right side. **props: Additional HTML attributes applied to the outer wrapper div.
__init__
def __init__(
    title: str = '',
    children: Any = None,
    actions: list[Any] | None = None,
    **props: Any
) -> None
render
def render() -> Any

Component for selecting the number of items per page. Uses Zone-based targeting for consistent HTMX behavior.
__init__
def __init__(
    per_page: int = 20,
    base_url: str = '',
    extra_query: str = '',
    hx_target: str | None = None,
    hx_swap: str = 'innerHTML',
    hx_push_url: str = 'true',
    size_options: list[int] | None = None,
    state: Any | None = None,
    **props: Any
) -> None
render
def render() -> Any

Component for rendering numeric page links and navigation buttons. Uses Zone-based targeting for consistent HTMX behavior.
__init__
def __init__(
    page: int = 1,
    total_pages: int = 1,
    per_page: int = 20,
    base_url: str = '',
    extra_query: str = '',
    hx_target: str | None = None,
    hx_swap: str = 'innerHTML',
    hx_push_url: str = 'true',
    state: TableState | None = None,
    **props: Any
) -> None
page_link
def page_link(
    p: int,
    label: str | Any,
    disabled: bool = False,
    active: bool = False,
    extra_cls: str = ''
) -> Any
render
def render() -> Any

Password input - TextInput with type='password'.
__init__
def __init__(
    name: str,
    **kwargs: Any
) -> None

__init__
def __init__(
    data: list[ChartDataPoint],
    config: ChartConfig | None = None,
    *,
    size: int = 160
) -> None
render
def render() -> Any

Popover component for richer content than tooltips.
__init__
def __init__(
    trigger: str | Any,
    position: str = 'bottom',
    width: str = 'md',
    **props: Any
) -> None
render
def render() -> Any

Linear progress bar with percentage display.
Parameters
ParameterTypeDescription
`value`Current progress value
`max`Maximum value (default 100)
`label`Optional label text
`show_percentage`Whether to show percentage text
`size`Height variant (sm, md, lg)
__init__
def __init__(
    value: int,
    max_value: int = 100,
    label: str | None = None,
    show_percentage: bool = True,
    size: Literal['sm', 'md', 'lg'] = 'md',
    **props: Any
) -> None
render
def render() -> Any

Radio button group for single selection.
__init__
def __init__(
    name: str,
    choices: list[tuple[str, str]],
    inline: bool = False,
    **kwargs: Any
) -> None
render
def render() -> Any

Star rating component.
__init__
def __init__(
    name: str,
    max_value: int = 5,
    **kwargs: Any
) -> None
render
def render() -> Any

Wrapper for raw HTML strings that should be included verbatim.

Instances implement __html__ so they are detected as htpy-like elements and their contents are not escaped when inserted as children.

__init__
def __init__(value: str) -> None

A component that polls or uses SSE to update its content in real-time.

Example

feed = RealTimeFeed(
url="/admin//updates",
interval="5s",
content=el("p", "Waiting for updates...")
)
__init__
def __init__(
    url: str,
    interval: str | None = '10s',
    use_sse: bool = False,
    content: Any = None,
    **props: Any
) -> None
render
def render() -> Any

LRU cache for rendered component fragments.

Use for expensive-to-render components that don’t change often.

get
def get(
    component_name: str,
    **kwargs: Any
) -> str | None

Get cached render result if valid.

set
def set(
    component_name: str,
    content: str,
    **kwargs: Any
) -> None

Cache a render result.

invalidate
def invalidate(component_name: str | None = None) -> None

Invalidate cache entries.

cached
def cached(component_name: str | None = None) -> Callable[[Callable[Ellipsis, str]], Callable[Ellipsis, str]]

Decorator for caching render methods.


A component that allows users to add/remove sets of fields. Useful for JSON arrays or HasMany relations.
__init__
def __init__(
    name: str,
    schema: list[Component] | Callable[[], list[Component]],
    value: list[dict] | None = None,
    label: str | None = None,
    add_label: str = 'Add Item',
    item_label: str = 'Item',
    **props: Any
) -> None
render
def render() -> Any

Coalesce rapid-fire requests into single requests.

Useful for batch operations or rapid filter changes.

add
def add(
    key: str,
    value: Any
) -> None

Add a value to coalesce.

flush
def flush() -> dict[str, Any]

Get and clear all pending values.


Optimize HTMX responses with caching and conditional rendering.

Features:

  • ETag-based caching for unchanged content
  • Content hashing to detect changes
  • Conditional response headers
compute_etag
def compute_etag(content: str) -> str

Compute ETag hash for content.

should_return_304
def should_return_304(
    content: str,
    request_etag: str | None
) -> bool

Check if we can return 304 Not Modified.

optimize_response
def optimize_response(
    content: str,
    request_etag: str | None = None
) -> tuple[str, int, dict[str, str]]

Optimize response with caching headers.

Parameters
ParameterTypeDescription
`content`strThe HTML content to return
`request_etag`str | NoneThe If-None-Match header value from request
Returns
TypeDescription
tuple[str, int, dict[str, str]]Tuple of (content, status_code, headers)

WYSIWYG editor using Trix. Requires Trix JS/CSS to be loaded in the page.
__init__
def __init__(
    name: str,
    value: str | None = None,
    label: str | None = None,
    placeholder: str | None = None,
    error: str | None = None,
    disabled: bool = False,
    required: bool = False,
    min_height: int = 300,
    toolbar: str | None = None,
    **props: Any
) -> None
render
def render() -> Any

Full-featured accessible select component powered by Alpine.js.

Supports:

  • Single-select (default) — click an option to choose it; dropdown closes.
  • Multi-select (multi=True) — checkbox-style; multiple values selectable.
  • Grouped options (groups) — render labelled option groups.
  • Async search (search_url) — HTMX hx-get fires on the search input; the response should return a <ul id="{name}-options"> fragment.
  • Client-side filter (no search_url) — shown when there are more than SEARCH_THRESHOLD options or groups are present.
Parameters
ParameterTypeDescription
`label`Visible label for the control.
`name`HTML ``name`` attribute used for form submission.
`options`Flat list of ``{"value": ..., "label": ...}`` dicts.
`multi`Enable multi-select behaviour.
`search_url`HTMX URL for server-side search. Receives ``?q=``.
`groups`Grouped options: ``[{"label": "Group", "options": [...]}]``.
`error`Validation error message shown below the control.
`placeholder`Trigger button placeholder text when nothing is selected.
__init__
def __init__(
    label: str,
    name: str,
    options: list[dict[str, Any]] | None = None,
    multi: bool = False,
    search_url: str = '',
    groups: list[dict[str, Any]] | None = None,
    error: str | None = None,
    placeholder: str = 'Select an option',
    **props: Any
) -> None
render
def render() -> Any

Grid row component (flexible layout).
__init__
def __init__(
    *children: Any,
    cols: int = 1,
    gap: int = 4,
    **props: Any
) -> None
render
def render() -> Any

Reusable search bar with icon and optional clear button.
__init__
def __init__(
    name: str = 'search',
    value: str = '',
    placeholder: str = 'Search...',
    show_icon: bool = True,
    show_clear: bool = False,
    **props: Any
) -> None

Initialize search bar.

Parameters
ParameterTypeDescription
`name`strInput name attribute
`value`strCurrent search value
`placeholder`strPlaceholder text
`show_icon`boolWhether to show search icon
`show_clear`boolWhether to show clear button **props: Additional props (HTMX attributes, etc.)
render
def render() -> Any

Render search bar.


Form section component for grouping related fields.

Example

Section( title=“Personal Information”, description=“Basic details about the user”, Grid( TextInput(“first_name”, label=“First Name”), TextInput(“last_name”, label=“Last Name”), cols=2 ) )

__init__
def __init__(
    *children: Any,
    title: str,
    description: str | None = None,
    icon: str | None = None,
    collapsible: bool = False,
    collapsed: bool = False,
    **props: Any
) -> None

Initialize section component.

Parameters
ParameterTypeDescription
`title`strSection title
`description`str | NoneOptional description
`icon`str | NoneOptional icon (emoji or icon class)
`collapsible`boolWhether section can be collapsed
`collapsed`boolInitial collapsed state **props: Additional properties
render
def render() -> Any

Render the section.


Select dropdown with label and error support.
Parameters
ParameterTypeDescription
`name`Input name attribute
`choices`List of (value, label) tuples
`value`Currently selected value
`label`Optional label text
`error`Error message to display
`multiple`Whether multiple selection is allowed
`disabled`Whether input is disabled
`required`Whether input is required
__init__
def __init__(
    name: str,
    choices: list[tuple[str, str]] | None = None,
    multiple: bool = False,
    **kwargs: Any
) -> None

Renders toast notification container and messages (server-driven via HTMX).
__init__
def __init__(config: ToastConfig | None = None)

Initialize the renderer.

Parameters
ParameterTypeDescription
`config`ToastConfig | NoneToast configuration
render
def render(toasts: list[ToastData]) -> str

Render toast payloads as HTML.

Parameters
ParameterTypeDescription
`toasts`list[ToastData]List of toast data objects
Returns
TypeDescription
strHTML string for the toast container with toasts
render_container
def render_container(toasts: list[ToastData] | None = None) -> str

Render the toast container with optional initial toasts.

Parameters
ParameterTypeDescription
`toasts`list[ToastData] | NoneList of toast messages to show initially
Returns
TypeDescription
strHTML string for toast container
render_toast
def render_toast(toast: ToastData) -> str

Render a single toast notification.

Parameters
ParameterTypeDescription
`toast`ToastDataToast to render
Returns
TypeDescription
strHTML string for toast

Inline alert component for contextual feedback.
Parameters
ParameterTypeDescription
`message`Alert message
`type`Alert type (info, success, warning, error)
`title`Optional alert title
__init__
def __init__(
    message: str,
    alert_type: str = 'info',
    title: str | None = None,
    **props: Any
) -> None
render
def render() -> Any

Prev / Next pagination with no total-count requirement.

Renders only a “Previous” button and a “Next” button, enabling fast pagination without an expensive COUNT(*) query.

Parameters
ParameterTypeDescription
`page`Current (1-based) page number.
`per_page`Items per page.
`has_next_page`Whether a next page exists. Set this by fetching ``per_page + 1`` rows and checking if more than ``per_page`` were returned.
`base_url`Base URL for page links.
`extra_query`Additional query string parameters to append (without leading ``&``).
`hx_target`HTMX target selector (default ``#main-content``).
`hx_push_url`Whether HTMX should push the URL (default ``"true"``).
__init__
def __init__(
    page: int = 1,
    per_page: int = 20,
    has_next_page: bool = False,
    base_url: str = '',
    extra_query: str = '',
    hx_target: str = '#main-content',
    hx_push_url: str = 'true',
    **props: Any
) -> None
render
def render() -> Any

Skeleton loader placeholder for content.
Parameters
ParameterTypeDescription
`variant`Shape variant (text, circular, rectangular)
`width`CSS width value
`height`CSS height value
`count`Number of skeleton lines (for text variant)
__init__
def __init__(
    variant: Literal['text', 'circular', 'rectangular', 'table'] = 'text',
    width: str = '100%',
    height: str | None = None,
    count: int = 1,
    **props: Any
) -> None
render
def render() -> Any

A side-panel drawer component for auxiliary content or editing.
Parameters
ParameterTypeDescription
`size`Panel width — ``sm``, ``md``, ``lg`` (default), ``xl``, ``2xl``, ``full``
`variant```"default"`` (indigo accent) or ``"danger"`` (red accent for delete confirms)
__init__
def __init__(
    title: str,
    trigger: str | Any = None,
    slide_id: str = 'slide-over',
    is_open: bool = False,
    render_trigger: bool = True,
    footer: list[Any] | None = None,
    size: str = 'lg',
    variant: str = 'default',
    subtitle: str | None = None,
    **props: Any
) -> None
render
def render() -> Any

Range slider input.
Parameters
ParameterTypeDescription
`name`Input name attribute
`value`Current value
`min`Minimum value (default: 0)
`max`Maximum value (default: 100)
`step`Step increment (default: 1)
`label`Optional label text **kwargs: Additional props
__init__
def __init__(
    name: str,
    value: float = 0,
    min_value: float = 0,
    max_value: float = 100,
    step: float = 1,
    **kwargs: Any
) -> None
render
def render() -> Any

Custom render with value display.


Drag-n-drop sortable list for reordering records.
Parameters
ParameterTypeDescription
`rows`Sequence of record dicts (or objects with ``__getitem__``).
`id_field`Key used to identify each record (default ``"id"``).
`label_field`Key used as the visible label (default ``"title"``).
`reorder_url`URL for the HTMX PATCH request carrying the new order.
`hx_target`HTMX swap target (default ``"this"``).
`hx_swap`HTMX swap strategy (default ``"none"``).
`handle_class`CSS class to add to the drag handle icon.
`empty_label`Text shown when *rows* is empty.
__init__
def __init__(
    rows: list[Any],
    id_field: str = 'id',
    label_field: str = 'title',
    reorder_url: str = '',
    hx_target: str = 'this',
    hx_swap: str = 'none',
    handle_class: str = '',
    empty_label: str = 'No records to reorder.',
    **props: Any
) -> None
render
def render() -> Any

__init__
def __init__(
    data: list[ChartDataPoint],
    *,
    line_color: str = 'blue',
    height: int = 32,
    width: int = 80,
    show_area: bool = False
) -> None
render
def render() -> Any

Circular loading spinner with size variants.
Parameters
ParameterTypeDescription
`size`Size variant (sm=16px, md=24px, lg=32px, xl=48px)
`aria_label`Accessible label announced to screen readers (default: "Loading...")
__init__
def __init__(
    size: Literal['sm', 'md', 'lg', 'xl'] = 'md',
    aria_label: str = 'Loading...',
    **props: Any
) -> None
render
def render() -> Any

A vertical flex-column layout container.

Stacks its children elements vertically with a Tailwind CSS gap.

Parameters
ParameterTypeDescription
`children`Sequence of child elements to render inside the stack.
`gap`Tailwind spacing unit for ``gap-*`` (e.g. ``6`` → ``gap-6``).
`class_`Additional CSS classes appended to the container element.

Example

content = Stack(
gap=4,
children=[
el("h2", "Title"),
el("p", "Body text"),
],
)
content = Stack(
gap=4,
children=[
el("h2", "Title"),
el("p", "Body text"),
],
)
__init__
def __init__(
    children: list[Any] | None = None,
    gap: int = 4,
    class_: str = ''
) -> None

Dashboard metric card.
__init__
def __init__(
    label: str,
    value: Any,
    delta: str | None = None,
    delta_color: str = 'green',
    icon: str | None = None,
    sparkline_data: list[float] | None = None,
    sparkline_color: str = 'indigo',
    **props: Any
) -> None
render
def render() -> Any

Submit button with automatic loading state.
Parameters
ParameterTypeDescription
`label`Button text.
`variant`Same as Button.
`size`Same as Button.
`disabled`Whether button is disabled. **props: Additional attributes.
__init__
def __init__(
    label: str = 'Submit',
    *,
    loading_label: str = 'Submitting...',
    variant: ButtonVariant = 'default',
    size: ButtonSize = 'default',
    disabled: bool = False,
    **props: Any
) -> None
render
def render() -> Any

Valid HTMX swap modes.

A premium toggle switch component implemented using the shared `Toggle` molecule.
__init__
def __init__(
    label: str,
    name: str,
    value: bool = False,
    description: str | None = None,
    error: str | None = None,
    **props: Any
) -> None
render
def render() -> Any

A compact system menu display for the sidebar footer that mirrors the behavior of `UserBox`. It renders compact icons inline and exposes block-style items (e.g., Settings) in a dropdown for discoverability.
__init__
def __init__(
    system_menu_items: list[dict] | None = None,
    direction: str = 'up',
    user: Any | None = None,
    **props: Any
) -> None
render
def render() -> Any

A single tab within a ``TabGroup``.

Render a set of tabs with Alpine.js-driven switching.

Each tab can hold a list of schema fields (for forms) or arbitrary content (for detail views).

__init__
def __init__(
    tabs: list[Tab],
    default_tab: str | None = None,
    **props: Any
) -> None
render
def render() -> Element

Wrapper for tab content. Automatically shows/hides based on the parent Tabs' state.
__init__
def __init__(
    tab_id: str,
    *children: Any,
    **props: Any
) -> None
render
def render() -> Any

Pagination component with HTMX support and baked URL pattern.

Supports two modes:

  1. State-based (recommended): Pass a TableState for baked URLs
  2. Legacy: Pass page/total/per_page directly
__init__
def __init__(
    page: int = 1,
    total: int = 0,
    per_page: int = 20,
    base_url: str = '',
    state: TableState | None = None,
    show_size_selector: bool = True,
    **props: Any
) -> None
render
def render() -> Any

Encapsulates the complete state of a DataTable. This state is derived from the URL and drives the UI rendering.
__init__
def __init__(**data: Any) -> None
from_request
def from_request(
    cls,
    request: Any,
    defaults: dict | None = None
) -> TableState

Create state from a request object (Starlette/ASGI compatible).

to_query_params
def to_query_params(exclude: list[str] | None = None) -> dict

Export state to dictionary suitable for URL generation. Only includes non-default and non-empty values to keep URLs clean.

to_url
def to_url(base_path: str = '') -> str

Return a canonical URL (path + query) for this TableState.

model_copy
def model_copy(
    *args: Any,
    **kwargs: Any
) -> TableState

Override model_copy to preserve internal defaults.

with_page
def with_page(page: int) -> TableState

Return a copy with a new page number.

Resets cursor for offset-based pagination.

Example

new_state = state.with_page(2) attrs = HTMXAttrs.for_data_refresh(new_state, prefix)

with_per_page
def with_per_page(per_page: int) -> TableState

Return a copy with a new per_page value.

Resets to page 1 since row counts change.

with_search
def with_search(search: str) -> TableState

Return a copy with a new search term.

Resets to page 1 since results change.

with_filter
def with_filter(
    key: str,
    value: Any
) -> TableState

Return a copy with an updated filter value.

Resets to page 1 since results change.

Example

new_state = state.with_filter(“status”, “active”)

without_filter
def without_filter(key: str) -> TableState

Return a copy with a filter removed.

Resets to page 1 since results change.

with_sort
def with_sort(column: str) -> TableState

Return a copy with sort toggled on the given column.

If already sorting by this column, toggles direction. Otherwise, sets ascending sort on the column.

Example

new_state = state.with_sort(“name”) # asc new_state = new_state.with_sort(“name”) # desc

with_view
def with_view(view: Literal['tabular', 'grid', 'calendar', 'stacked']) -> TableState

Return a copy with a new view type.

with_layout
def with_layout(layout: Literal['sidebar', 'stack']) -> TableState

Return a copy with a new layout type.

with_group_by
def with_group_by(group_by: str | None) -> TableState

Return a copy with a new grouping column.

Pass None to clear grouping. Resets to page 1 since grouping changes the result set.

Example

new_state = state.with_group_by(“category”) cleared = state.with_group_by(None)

with_include_deleted
def with_include_deleted(include_deleted: bool) -> TableState

Return a copy with a new include_deleted value.

Resets to page 1 since results change.

Example

new_state = state.with_include_deleted(True)

clear_filters
def clear_filters() -> TableState

Return a copy with all filters and search cleared.

Resets to page 1.

clear_sort
def clear_sort() -> TableState

Return a copy with sorting cleared.

set_resource_prefix
def set_resource_prefix(prefix: str) -> None

Set the resource prefix for URL generation.

get_resource_prefix
def get_resource_prefix() -> str | None

Get the resource prefix for URL generation.

render_hidden_inputs
def render_hidden_inputs(exclude: list[str] | None = None) -> list

Render hidden inputs for state preservation.

Used as a fallback when baked URLs aren’t possible (e.g., form submissions that need to preserve table state).

These inputs should be placed INSIDE the TABLE zone.

Parameters
ParameterTypeDescription
`exclude`list[str] | NoneOptional list of field names to skip (avoid duplication with UI inputs)
Returns
TypeDescription
listList of htpy input elements

A responsive tabbed interface component with smooth animations and client-side switching.
Parameters
ParameterTypeDescription
`tabs`List of (label, id) or (label, url) tuples
`active_tab`Initially active tab ID or label
`client_side`If True, uses Alpine.js for content switching without page load
__init__
def __init__(
    tabs: list[tuple[str, str]],
    active_tab: str | None = None,
    client_side: bool = True,
    **props: Any
) -> None
render
def render() -> Any

Premium tags input using Alpine.js. Allows adding strings as tags/chips.
__init__
def __init__(
    name: str,
    placeholder: str = 'Add tag...',
    **kwargs: Any
) -> None
render
def render() -> Any

Real-time progress tracking component with SSE updates.

Connects to a Server-Sent Events endpoint to display live progress of a background task. Shows progress bar, status, and messages.

Parameters
ParameterTypeDescription
`task_id`Unique identifier for the task
`title`Progress dialog title
`auto_close`Whether to auto-close on completion
`on_complete`URL to redirect to or JS callback on completion
`stream_url`Custom SSE endpoint URL (defaults to /admin/progress/{task_id}/stream)
__init__
def __init__(
    task_id: str,
    title: str = 'Processing...',
    auto_close: bool = False,
    on_complete: str | None = None,
    stream_url: str | None = None,
    **props: Any
) -> None
render
def render() -> Any

Multi-line text input.
Parameters
ParameterTypeDescription
`name`Input name attribute
`value`Input value
`rows`Number of visible rows (default: 3)
`label`Optional label text
`error`Error message to display **kwargs: Additional props
__init__
def __init__(
    name: str,
    value: str | None = None,
    rows: int = 3,
    placeholder: str | None = None,
    **kwargs: Any
) -> None

Simple text column with optional formatting.
__init__
def __init__(
    name: str,
    label: str | None = None
)
color
def color(color: str) -> TextColumn

Set text color (gray, red, blue, green, yellow, etc.).

size
def size(size: str) -> TextColumn

Set text size (xs, sm, base, lg, xl).

weight
def weight(weight: str) -> TextColumn

Set font weight (normal, medium, semibold, bold).

mono
def mono(mono: bool = True) -> TextColumn

Use monospace font.

render
def render(
    value: Any,
    record: dict
) -> Any

Render as styled text.


Text input with label and error support.
Parameters
ParameterTypeDescription
`name`Input name attribute
`value`Input value
`type`Input type (text, password, email, etc.)
`placeholder`Placeholder text
`label`Optional label text
`error`Error message to display
`disabled`Whether input is disabled
`required`Whether input is required
`readonly`Whether input is readonly **props: Additional HTML attributes (hx_*, data-*, etc.)

Example

TextInput( name=“username”, label=“Username”, placeholder=“Enter username”, required=True )

__init__
def __init__(
    name: str,
    value: str | None = None,
    input_type: str = 'text',
    placeholder: str | None = None,
    **kwargs: Any
) -> None

Time selection input.

Deprecated alias for InlineToast. Will be removed in a future release.
__init__
def __init__(
    *args: Any,
    **kwargs: Any
) -> None

Configuration for toast container.

A toast notification message.

Deprecated alias for ServerToastChannel. Will be removed in a future release.
__init__
def __init__(
    *args: Any,
    **kwargs: Any
) -> None

Toast notification types.

Simple checkbox toggle (use Switch from forms.py for premium toggle).
__init__
def __init__(
    name: str,
    value: Any = None,
    checked: bool | None = None,
    **kwargs: Any
) -> None
render
def render() -> Any

Icon-based toggle button useful for theme toggles.
Parameters
ParameterTypeDescription
`icon_on`icon name to show when state var is true
`icon_off`icon name to show when state var is false
`state_var`the JS state variable in scope to toggle (e.g., 'darkMode')
`aria_label`accessible label
__init__
def __init__(
    icon_on: str = 'sun',
    icon_off: str = 'moon',
    state_var: str = 'darkMode',
    aria_label: str = 'Toggle',
    size: str = 'sm',
    **props: Any
) -> None
render
def render() -> Any

Tooltip component with auto-positioning and ARIA accessibility support.

The tooltip element receives role="tooltip" and a stable id. If a trigger element is wired via trigger_id, the wrapper element receives aria-describedby pointing to the tooltip’s id.

Parameters
ParameterTypeDescription
`content`The tooltip text shown on hover.
`position`Visual position hint (default: "top").
`tooltip_id`Explicit ``id`` for the tooltip span. Defaults to a generated value so ``aria-describedby`` always resolves.
`trigger_id`Optional ``id`` of the associated trigger element.
__init__
def __init__(
    content: str,
    position: str = 'top',
    tooltip_id: str | None = None,
    trigger_id: str | None = None,
    **props: Any
) -> None
render
def render() -> Any

Payload fired after a UI component completes rendering.

Attributes: component_name: Qualified name of the component class that rendered.


Configuration for the lexigram-ui provider.

These settings control rendering defaults and are read from the [ui] section of application.yaml (or equivalent config source).

validate_for_environment
def validate_for_environment(env: Environment | None = None) -> list[ConfigIssue]

Check config is safe for the target environment.


Immutable per-request UI rendering context.

Attributes: theme: Active theme name (e.g. "default", "dark"). locale: BCP-47 locale string (e.g. "en", "fr-FR"). user: Optional current user object; application-defined type. extra: Arbitrary extra key-value pairs for application-specific state.


HTMX/htpy component library module.

Call configure to configure and register the UI component system for injection.

Usage

from lexigram.ui.config import UIConfig
@module(
imports=[UIModule.configure(UIConfig(default_theme="default"))]
)
class AppModule(Module):
pass
from lexigram.ui.config import UIConfig
@module(
imports=[UIModule.configure(UIConfig(default_theme="default"))]
)
class AppModule(Module):
pass
configure
def configure(
    cls,
    config: Any | None = None,
    **kwargs: Any
) -> DynamicModule

Create a UIModule with explicit configuration.

Parameters
ParameterTypeDescription
`config`Any | NoneUIConfig or ``None`` to use defaults. **kwargs: Additional keyword arguments forwarded to UIProvider.
Returns
TypeDescription
DynamicModuleA DynamicModule descriptor.
stub
def stub(
    cls,
    config: Any = None
) -> DynamicModule

Return a no-op UIModule for testing.

Registers the UI provider with default configuration. No real rendering backends are configured.

Parameters
ParameterTypeDescription
`config`AnyOptional UIConfig override (passed to UIProvider).
Returns
TypeDescription
DynamicModuleA DynamicModule with default UI configuration.

Registers the lexigram-ui component system.

Bind into your application bootstrap

from lexigram.ui.di import UIProvider
app.add_provider(UIProvider())
from lexigram.ui.di import UIProvider
app.add_provider(UIProvider())

Configuration (application.yaml)

ui:
default_theme: my-theme
debug_components: true
ui:
default_theme: my-theme
debug_components: true

Registered services:

  • UIConfig (singleton) — resolved UI configuration.
  • MetricsCollector (singleton) — in-memory UI metrics collection.
  • ResponseOptimizer (singleton) — ETag-based HTMX response optimization.
  • RenderCache (singleton) — LRU cache for rendered component fragments.
__init__
def __init__(
    config: UIConfig | None = None,
    **kwargs: Any
) -> None
register
async def register(container: ContainerRegistrarProtocol) -> None

Register UI services in the DI container.

Parameters
ParameterTypeDescription
`container`ContainerRegistrarProtocolThe DI container registrar.
boot
async def boot(container: ContainerResolverProtocol) -> None

No boot-time initialisation required for the UI module.

shutdown
async def shutdown() -> None

No shutdown work required for the UI module.

health_check
async def health_check(timeout: float = 5.0) -> HealthCheckResult

Check provider health.

Parameters
ParameterTypeDescription
`timeout`floatMaximum seconds to wait for health check response.
Returns
TypeDescription
HealthCheckResultHealthCheckResult with status and component details.

Payload fired after a template is rendered to its final HTML output.

Attributes: template_name: Name or path of the template that was rendered.


A compact user profile display for headers or sidebars.
__init__
def __init__(
    username: str,
    avatar_url: str | None = None,
    direction: str = 'down',
    position: str = 'right',
    roles: list[str] | None = None,
    user_menu_items: list[dict] | None = None,
    user: Any | None = None,
    **props: Any
) -> None
render
def render() -> Any

Standard View action implementation.
__init__
def __init__(
    name: str = 'view',
    label: str = 'View'
)

Simple view switcher dropdown for DataTable.

Renders a compact dropdown listing available views and emits HTMX requests to the resource with data_view query param.

__init__
def __init__(
    current: str = 'tabular',
    resource_prefix: str | None = None,
    options: list | None = None,
    state: TableState | None = None,
    **props: Any
) -> None
render
def render() -> Any

Component for handling infinite scroll and virtualization.

This uses HTMX ‘revealed’ trigger to load next chunks of data.

__init__
def __init__(
    url: str,
    total_items: int | None = None,
    chunk_size: int = 50,
    target_id: str | None = None,
    placeholder: Any | None = None,
    **props: Any
) -> None
render
def render() -> Any

Definition of a UI zone.

A zone represents a targetable region of the page with specific semantics for how it can be updated via HTMX.

Attributes: id: The HTML element ID for this zone description: Human-readable description of this zone’s purpose swappable: Whether this zone can be targeted by HTMX swaps swap_mode: The default HTMX swap mode for this zone preserve_alpine: Whether Alpine.js state should be preserved on swap oob_only: If True, this zone should only be updated via OOB swaps

selector
property selector() -> str

Return the CSS selector for this zone.


Central registry of all UI zones.

This class provides a single source of truth for all targetable regions in the admin UI. Components should reference these zones rather than hardcoding IDs.

Zone Hierarchy:

TABLE (root scope)
├── TOOLBAR (switchers, header actions) - OOB only
├── SEARCH (search input) - never swap
├── FILTERS (filter bar) - OOB only
└── DATA (rows + pagination) - most common target
DASHBOARD (dashboard page)
└── WIDGET_CONTAINER (per-widget lazy-load target)
MODAL (global, outside table)
SLIDE_OVER (global, outside table)
FLASH (toast notifications)

Usage

from lexigram.ui.core.zones import Zones

attrs = { “hx-target”: Zones.DATA.selector, “hx-swap”: Zones.DATA.swap_mode.value, }

all_zones
def all_zones(cls) -> list[Zone]

Return all registered zones.

swappable
def swappable(cls) -> list[Zone]

Return all zones that can be targeted by HTMX swaps.

get_by_id
def get_by_id(
    cls,
    zone_id: str
) -> Zone | None

Look up a zone by its ID.

Returns None if no zone with that ID exists.

get_by_selector
def get_by_selector(
    cls,
    selector: str
) -> Zone | None

Look up a zone by its CSS selector.

Handles both “#zone-id” and “zone-id” formats.


SkipLink
def SkipLink(
    target_id: str = 'main-content',
    label: str = 'Skip to main content'
) -> str
Return an HTML skip navigation link for accessibility.
Parameters
ParameterTypeDescription
`target_id`strThe ID of the target element to skip to.
`label`strThe link text for the skip link.
Returns
TypeDescription
strAn HTML anchor tag with sr-only CSS class.

add_htmx_timing_header
def add_htmx_timing_header(
    headers: dict[str, str],
    render_time_ms: float
) -> dict[str, str]
Add Server-Timing header for HTMX requests.

announce
def announce(
    message: str,
    priority: AriaLive = AriaLive.POLITE,
    atomic: bool = True
) -> str
Create an invisible live region announcement.

This element will be announced by screen readers when inserted into the DOM. Use for dynamic content updates.

Parameters
ParameterTypeDescription
`message`strThe text to announce
`priority`AriaLivePOLITE (wait for idle) or ASSERTIVE (immediate)
`atomic`boolWhether to announce the entire region or just changes
Returns
TypeDescription
strHTML string for the announcement element

announce_action_complete
def announce_action_complete(
    action: str,
    success: bool = True
) -> str
Create an assertive screen-reader announcement for an action outcome.

Uses ASSERTIVE politeness so the result is announced immediately, interrupting any in-progress speech. Suitable for confirming or reporting the failure of a user-initiated action.

Parameters
ParameterTypeDescription
`action`strHuman-readable description of the action, e.g. ``"User deleted"`` or ``"Export"``.
`success`boolWhen ``True`` (default), appends ``"completed successfully"``; when ``False``, appends ``"failed"``.
Returns
TypeDescription
strAn HTML string containing the invisible announcement element.

announce_selection_change
def announce_selection_change(
    count: int,
    action: str = 'selected'
) -> str
Create a polite screen-reader announcement for a selection state change.
Parameters
ParameterTypeDescription
`count`intNumber of items currently in the selection.
`action`strPast-tense verb describing the selection action, e.g. ``"selected"`` (default) or ``"deselected"``.
Returns
TypeDescription
strAn HTML string containing the invisible announcement element.

announce_table_update
def announce_table_update(
    total: int,
    page: int | None = None,
    search: str | None = None
) -> str
Create a polite screen-reader announcement for a table data refresh.

Composes a human-readable summary of the current table state and emits it as a POLITE live-region element via announce.

Parameters
ParameterTypeDescription
`total`intTotal number of items currently displayed or matching the current filter.
`page`int | NoneCurrent page number when the table is paginated. Omit (or pass ``None``) for unpaginated tables.
`search`str | NoneActive search / filter text. When provided, the message includes ``"filtered by ''"``.
Returns
TypeDescription
strAn HTML string containing the invisible announcement element.

button_aria
def button_aria(
    label: str,
    pressed: bool | None = None,
    expanded: bool | None = None,
    controls: str | None = None,
    haspopup: str | None = None,
    disabled: bool = False
) -> dict[str, str]
Return ARIA attributes for an interactive button element.

Covers toggle buttons, disclosure buttons, and menu-trigger buttons. Pass only the arguments relevant to the button’s role; unused attributes are omitted from the returned dict.

Parameters
ParameterTypeDescription
`label`strAccessible name for the button, mapped to ``aria-label``.
`pressed`bool | NoneFor toggle buttons, the current pressed state. ``True`` maps to ``aria-pressed="true"``, ``False`` to ``"false"``, ``None`` omits the attribute entirely.
`expanded`bool | NoneFor disclosure/accordion buttons, whether the controlled region is currently visible. Maps to ``aria-expanded``.
`controls`str | NoneID of the element this button controls. Maps to ``aria-controls``.
`haspopup`str | NoneType of popup this button opens, e.g. ``"menu"``, ``"listbox"``, ``"dialog"``. Maps to ``aria-haspopup``.
`disabled`boolWhen ``True``, adds ``aria-disabled="true"``.
Returns
TypeDescription
dict[str, str]A ``dict[str, str]`` of HTML attribute names to their string values.

Example

attrs = button_aria("Toggle sidebar", expanded=False, controls="sidebar")
# {"role": "button", "aria-label": "Toggle sidebar",
# "aria-expanded": "false", "aria-controls": "sidebar"}
attrs = button_aria("Toggle sidebar", expanded=False, controls="sidebar")
# {"role": "button", "aria-label": "Toggle sidebar",
# "aria-expanded": "false", "aria-controls": "sidebar"}

cached_render
def cached_render(
    component_name: str | None = None,
    cache: RenderCache | None = None
) -> Callable[[Callable[Ellipsis, str]], Callable[Ellipsis, str]]
Decorator for caching component renders.
Parameters
ParameterTypeDescription
`component_name`str | NoneName for the cached component fragment.
`cache`RenderCache | NoneRenderCache instance to use. When None, returns an identity decorator.

cell_aria
def cell_aria(
    colindex: int | None = None,
    rowindex: int | None = None
) -> dict[str, str]
Return ARIA attributes for an interactive table data cell.

Uses the gridcell role, which is appropriate for cells inside a grid-role container that supports keyboard interaction.

Parameters
ParameterTypeDescription
`colindex`int | None1-based column position within the full column set. Maps to ``aria-colindex``. Required when columns are hidden.
`rowindex`int | None1-based row position within the full dataset. Maps to ``aria-rowindex``. Usually set on the row element instead; provide here only when the row element cannot be annotated.
Returns
TypeDescription
dict[str, str]A ``dict[str, str]`` of HTML attribute names to their string values.

component
def component(
    name: str | None = None,
    *,
    cacheable: bool = False
) -> Callable[[F], F]
Mark a callable as a named UI component and attach component metadata.

Tags the decorated function with __component_name__ and __component_cacheable__ attributes so that component registries, debug tooling, and render pipelines can discover and identify components by name without relying on __qualname__.

This decorator does not register the component in any global registry by itself — registration is handled by the DI container via the UIProvider. The decorator provides the metadata that the provider reads during component discovery.

Parameters
ParameterTypeDescription
`name`str | NoneLogical component name used for registration and cache keys. Defaults to the decorated function's ``__name__``.
`cacheable`boolWhen ``True``, signals that the component's rendered output may be cached by the render pipeline. Defaults to ``False``.
Returns
TypeDescription
Callable[[F], F]Decorator that attaches component metadata to the target callable.

Example

@component("user_card", cacheable=True)
def user_card(user: User) -> str:
return render_to_string(
el("div", {"class": "card"}, user.display_name)
)
@component()
def avatar(src: str, alt: str = "") -> str:
return render_to_string(el("img", {"src": src, "alt": alt}))
@component("user_card", cacheable=True)
def user_card(user: User) -> str:
return render_to_string(
el("div", {"class": "card"}, user.display_name)
)
@component()
def avatar(src: str, alt: str = "") -> str:
return render_to_string(el("img", {"src": src, "alt": alt}))

debounced_search_attrs
def debounced_search_attrs(
    url: str,
    delay_ms: int = 300,
    target: str | None = None
) -> dict[str, str]
Generate HTMX attributes for a debounced search input.
Parameters
ParameterTypeDescription
`url`strURL to search endpoint
`delay_ms`intDebounce delay in milliseconds
`target`str | NoneHTMX target (defaults to Zones.DATA)
Returns
TypeDescription
dict[str, str]Dictionary of HTMX attributes

dialog_aria
def dialog_aria(
    label: str,
    describedby: str | None = None,
    modal: bool = True
) -> dict[str, str]
Return ARIA attributes for a modal or non-modal dialog overlay.
Parameters
ParameterTypeDescription
`label`strAccessible name for the dialog, mapped to ``aria-label``. Use a concise title that describes the dialog's purpose, e.g. ``"Confirm deletion"``.
`describedby`str | NoneID of an element that provides a longer description of the dialog's purpose. Maps to ``aria-describedby``.
`modal`boolWhen ``True`` (default), adds ``aria-modal="true"`` to signal that background content is inert while the dialog is open.
Returns
TypeDescription
dict[str, str]A ``dict[str, str]`` of HTML attribute names to their string values.

Example

attrs = dialog_aria("Delete user", describedby="delete-desc")
# {"role": "dialog", "aria-label": "Delete user",
# "aria-describedby": "delete-desc", "aria-modal": "true"}
attrs = dialog_aria("Delete user", describedby="delete-desc")
# {"role": "dialog", "aria-label": "Delete user",
# "aria-describedby": "delete-desc", "aria-modal": "true"}

el
def el(
    tag: str,
    *children: Any,
    **attrs: Any
) -> Any
Construct an element using `htpy` when available, otherwise return an `Element` fallback that implements `__html__`.

For self-closing tags we prefer our local Element to ensure consistent output (including trailing slash), even when htpy is installed.


flash_to_toast
def flash_to_toast(flash_messages: list[tuple[str, str]] | None) -> list[ToastData]
Convert Flask/Starlette flash messages to toasts.
Parameters
ParameterTypeDescription
`flash_messages`list[tuple[str, str]] | NoneList of (category, message) tuples
Returns
TypeDescription
list[ToastData]List of ToastData objects

get_icon
def get_icon(
    name: str | Any,
    class_name: str = '',
    size: str = 'w-5 h-5',
    **attrs: Any
) -> Any
Render a Lucide icon by name.

get_ui_context
def get_ui_context() -> UIContext | None
Return the current request-scoped UIContext, or ``None`` outside a request.
Returns
TypeDescription
UIContext | NoneThe active UIContext set by set_ui_context, or ``None`` if called outside of a request (e.g. during startup).

header_aria
def header_aria(
    label: str,
    sortable: bool = False,
    sort_direction: str | None = None
) -> dict[str, str]
Return ARIA attributes for a sortable or static column header cell.
Parameters
ParameterTypeDescription
`label`strAccessible name for the column, mapped to ``aria-label``.
`sortable`boolWhen ``True``, adds an ``aria-sort`` attribute to indicate the column participates in sorting. Defaults to ``False``.
`sort_direction`str | NoneCurrent sort direction. Pass ``"asc"`` for ascending, ``"desc"`` for descending, or ``None`` (default) to output ``aria-sort="none"`` when *sortable* is ``True``.
Returns
TypeDescription
dict[str, str]A ``dict[str, str]`` of HTML attribute names to their string values.

Example

attrs = header_aria("Name", sortable=True, sort_direction="asc")
# {"role": "columnheader", "aria-label": "Name", "aria-sort": "ascending"}
attrs = header_aria("Name", sortable=True, sort_direction="asc")
# {"role": "columnheader", "aria-label": "Name", "aria-sort": "ascending"}

htmx_error_response
def htmx_error_response(
    error: ErrorResponse,
    include_flash: bool = True
) -> tuple[str, int, dict]
Build an HTMX-compatible error response.

infinite_scroll_trigger
def infinite_scroll_trigger(
    url: str,
    target: str | None = None,
    swap: str = 'beforeend',
    threshold: str = '200px'
) -> str
Create an infinite scroll trigger element.
Parameters
ParameterTypeDescription
`url`strURL to fetch next page from
`target`str | NoneHTMX target selector (defaults to Zones.DATA)
`swap`strHTMX swap mode
`threshold`strDistance from bottom to trigger load
Returns
TypeDescription
strHTML string for the trigger element

keyboard_navigation_script
def keyboard_navigation_script() -> str
Return a script tag with keyboard navigation helpers.
Returns
TypeDescription
strAn HTML script tag with keyboard navigation JavaScript.

lazy_load_placeholder
def lazy_load_placeholder(
    url: str,
    target_id: str,
    trigger: str = 'load',
    placeholder: str | None = None
) -> str
Create a lazy-load placeholder that fetches content on trigger.
Parameters
ParameterTypeDescription
`url`strURL to fetch content from
`target_id`strID of the element to replace
`trigger`strHTMX trigger (load, revealed, intersect, etc.)
`placeholder`str | NoneOptional placeholder content (defaults to skeleton)
Returns
TypeDescription
strHTML string for the placeholder

live_region_aria
def live_region_aria(
    politeness: AriaLive = AriaLive.POLITE,
    atomic: bool = True
) -> dict[str, str]
Return ARIA attributes for a live region container.

Live regions allow assistive technologies to announce dynamic content changes without requiring user focus. Use announce for one-shot screen-reader announcements; use this function when you need to annotate a persistent container.

Parameters
ParameterTypeDescription
`politeness`AriaLiveInterrupt behaviour for the announcement. Use AriaLive.POLITE (default) to wait until the user is idle, or AriaLive.ASSERTIVE for time-sensitive alerts.
`atomic`boolWhen ``True`` (default), the entire region is re-read on every change rather than just the changed nodes.
Returns
TypeDescription
dict[str, str]A ``dict[str, str]`` of HTML attribute names to their string values.

measure_render_time
def measure_render_time(func: Callable[Ellipsis, str]) -> Callable[Ellipsis, tuple[str, float]]
Decorator to measure render time.

not_found_error
def not_found_error(message: str = 'The requested resource was not found.') -> ErrorResponse
Create a not found error response (404).

optimize_htmx_response
def optimize_htmx_response(
    content: str,
    request_etag: str | None = None,
    optimizer: ResponseOptimizer | None = None
) -> tuple[str, int, dict[str, str]]
Convenience function for response optimization.
Parameters
ParameterTypeDescription
`content`strHTML content to optimize.
`request_etag`str | NoneETag from the incoming request for cache validation.
`optimizer`ResponseOptimizer | NoneResponseOptimizer instance. When None, returns the content unchanged.

permission_error
def permission_error(message: str = "You don't have permission to perform this action.") -> ErrorResponse
Create a permission error response (403).

raw
def raw(value: str) -> RawHTML

render_to_string
def render_to_string(value: str | Any) -> str
Render a component or htpy element to an HTML string.

This performs a best-effort conversion: strings are returned verbatim, htpy elements are converted if they provide a renderer, iterables are flattened by rendering each child and concatenating the results, and component instances are rendered via their render() method.


render_validation_errors
def render_validation_errors(
    errors: list[FieldError] | dict[str, str | list[str]],
    field_name: str | None = None
) -> str
Render validation errors as an HTML string.

reset_ui_context
def reset_ui_context(token: contextvars.Token[UIContext | None]) -> None
Restore the previous UI context using the token returned by set_ui_context.
Parameters
ParameterTypeDescription
`token`contextvars.Token[UIContext | None]The token returned by set_ui_context.

row_aria
def row_aria(
    index: int,
    selected: bool = False,
    expanded: bool | None = None
) -> dict[str, str]
Return ARIA attributes for a table row element.
Parameters
ParameterTypeDescription
`index`int1-based row position within the full dataset (not the current page). Maps to ``aria-rowindex``.
`selected`boolWhether this row is currently selected. Maps to ``aria-selected``.
`expanded`bool | NoneFor tree-grid rows, whether the row is expanded. Pass ``None`` (default) to omit the attribute entirely.
Returns
TypeDescription
dict[str, str]A ``dict[str, str]`` of HTML attribute names to their string values.

search_aria
def search_aria(
    label: str = 'Search',
    controls: str | None = None
) -> dict[str, str]
Return ARIA attributes for a search input field.
Parameters
ParameterTypeDescription
`label`strAccessible name for the search field. Defaults to ``"Search"``.
`controls`str | NoneID of the live region or results container that this input updates. Maps to ``aria-controls`` and helps screen readers announce that results are available.
Returns
TypeDescription
dict[str, str]A ``dict[str, str]`` of HTML attribute names to their string values.

server_error
def server_error(
    message: str = 'An unexpected error occurred. Please try again.',
    retry_url: str | None = None
) -> ErrorResponse
Create a server error response (500).

set_ui_context
def set_ui_context(ctx: UIContext) -> contextvars.Token[UIContext | None]
Bind *ctx* as the active UI context for the current async task.
Parameters
ParameterTypeDescription
`ctx`UIContextThe UIContext to set as active.
Returns
TypeDescription
contextvars.Token[UIContext | None]A Token that can be passed to reset_ui_context to restore the previous value.

shadcn_css
def shadcn_css(
    primary: str | None = None,
    background: str | None = None,
    foreground: str | None = None,
    radius: str | None = None,
    success: str | None = None,
    warning: str | None = None,
    info: str | None = None
) -> str
Generate ShadCN-compatible CSS with optional overrides.
Parameters
ParameterTypeDescription
`primary`str | NoneOverride primary color (oklch or hex value).
`background`str | NoneOverride background color.
`foreground`str | NoneOverride foreground color.
`radius`str | NoneOverride border radius.
`success`str | NoneOverride success color.
`warning`str | NoneOverride warning color.
`info`str | NoneOverride info color.
Returns
TypeDescription
Complete CSS string withroot and .dark variable blocks.

tab_aria
def tab_aria(
    label: str,
    selected: bool = False,
    controls: str | None = None
) -> dict[str, str]
Return ARIA attributes for a tab button within a tab list.

The tab element must be a child of an element with role="tablist" and must reference its associated panel via controls.

Parameters
ParameterTypeDescription
`label`strAccessible name for the tab, mapped to ``aria-label``.
`selected`boolWhether this tab is currently the active tab. Maps to ``aria-selected``.
`controls`str | NoneID of the ``tabpanel`` element this tab reveals. Maps to ``aria-controls``.
Returns
TypeDescription
dict[str, str]A ``dict[str, str]`` of HTML attribute names to their string values.

table_aria
def table_aria(
    label: str,
    rowcount: int | None = None,
    colcount: int | None = None,
    sortable: bool = False
) -> dict[str, str]
Return ARIA attributes for an accessible data table (grid role).

Use on the <table> or wrapper element that contains rows and cells. The grid role is used instead of table to support interactive keyboard navigation patterns expected by Admin UI tables.

Parameters
ParameterTypeDescription
`label`strHuman-readable label describing the table's content, used as ``aria-label``.
`rowcount`int | NoneTotal number of data rows across all pages. Pass the full dataset size when the table is paginated so assistive technologies can announce ``"row N of M"``.
`colcount`int | NoneTotal number of columns. Required when some columns are hidden or the table uses column groups.
`sortable`boolReserved for future use. Pass ``True`` to signal that column headers may carry ``aria-sort`` attributes.
Returns
TypeDescription
dict[str, str]A ``dict[str, str]`` of HTML attribute names to their string values, ready to be spread onto the element.

Example

attrs = table_aria("User list", rowcount=250, colcount=5)
# {"role": "grid", "aria-label": "User list",
# "aria-rowcount": "250", "aria-colcount": "5"}
attrs = table_aria("User list", rowcount=250, colcount=5)
# {"role": "grid", "aria-label": "User list",
# "aria-rowcount": "250", "aria-colcount": "5"}

tabpanel_aria
def tabpanel_aria(
    labelledby: str,
    hidden: bool = False
) -> dict[str, str]
Return ARIA attributes for a tab panel content area.

The panel must be associated with its controlling tab via labelledby.

Parameters
ParameterTypeDescription
`labelledby`strID of the ``tab`` element that controls this panel. Maps to ``aria-labelledby``.
`hidden`boolWhen ``True``, adds ``aria-hidden="true"`` to hide the panel from assistive technologies when its tab is not selected.
Returns
TypeDescription
dict[str, str]A ``dict[str, str]`` of HTML attribute names to their string values.

timeout_error
def timeout_error(
    message: str = 'The request timed out. Please try again.',
    retry_url: str | None = None
) -> ErrorResponse
Create a timeout error response (504).

validation_error
def validation_error(
    message: str = 'Please correct the errors below.',
    field_errors: list[FieldError] | None = None
) -> ErrorResponse
Create a validation error response (422).

Base exception for all UI-domain errors.
__init__
def __init__(
    message: str,
    *,
    code: str | None = None
) -> None