Skip to main content

pyweft-ui

Ready-made controls for PyWeft: buttons, menus, form fields with validation and input masks, date and date-range pickers, an event calendar, cards, layout, tabs, tables, dialogs, toasts and more, styled and accessible out of the box. Build a good-looking app in Python without writing HTML or CSS.

<template>
  <ui.Theme>
    <ui.AppShell title="Orders">
      <ui.Card title="New order">
        <ui.Column>
          <ui.TextField label="Customer" @bind="customer" required="true" />
          <ui.Select label="Size" options="Small, Medium, Large" @bind="size" />
          <ui.Switch label="Express delivery" @bind="express" />
        </ui.Column>
        <Fill name="footer">
          <ui.Button variant="ghost" @click="reset">Reset</ui.Button>
          <ui.Button variant="primary" icon="send" :loading="saving" @click="submit">
            Place order
          </ui.Button>
        </Fill>
      </ui.Card>
    </ui.AppShell>
  </ui.Theme>
</template>

<code>
from pyweft_ui import ui

customer: str = ""
size: str = "Medium"
express: bool = False
saving: bool = False

def reset(self):
    self.customer, self.size, self.express = "", "Medium", False

async def submit(self):
    ...
</code>

New to the toolkit? Read the guide: page layout, forms with validation, dialogs, themes and building your own components, with complete examples. This README is the compact reference.

Install

Install it into the same environment as PyWeft itself (see PyWeft's quick start):

uv add pyweft-ui

With pip:

pip install pyweft-ui

Then add "pyweft-ui" to the dependencies list in your app's own pyproject.toml (myapp/pyproject.toml), import it in a component's code block with from pyweft_ui import ui, and use the controls as <ui.Name>. pyweft run and pyweft build see that it is installed locally and send it to the browser for you.

Controls

Every control is a PyWeft component: attributes set its fields, @bind connects it to a field of yours, and attributes it doesn't have, such as class, style, id and aria-*, go onto its outer element. Plain attribute values are converted to each field's type, so cols="3" is the number 3 and disabled="true" is True.

Layout

Control Fields Notes
Theme mode (light, dark, auto), primary, radius, font Wrap your app in it to set colours and corners for everything inside. Optional.
AppShell title, width (narrow, normal, wide, full) Header, optional sidebar and content. Fills: brand, actions, nav.
Row gap, align, justify (start, center, end, between), wrap Children side by side.
Column gap, align Children stacked.
Grid cols, min_width, gap Fixed columns, or as many as fit.
Card title, subtitle Fills: title, actions, footer.

Gaps take none, xs, sm, md, lg, xl, or any CSS length.

Form fields

All have label, hint, error, required, disabled, name, and take @bind.

Control Binds Extra fields
TextField str type (text, email, password, search, url, tel, date, time), placeholder, autocomplete, mask ("(999) 999-9999": 9 digit, a letter, * either); emits enter on Enter
TextArea str rows, placeholder
NumberField int or float min, max, step, placeholder
Select the chosen option's value options, placeholder
RadioGroup the chosen option's value options, inline
Checkbox bool
Switch bool
DateRangePicker (start, end) dates or None min, max, min_days, max_days, months, placeholder, format, week_start, align; name sends <name>_start and <name>_end
Calendar datetime.date, or with range="true" (start, end) always open on the page: range, months, min, max, min_days, max_days, week_start
DatePicker datetime.date or None min, max (a date or "YYYY-MM-DD"), placeholder, format (strftime), week_start (monday, sunday), align

options can be a comma-separated string ("Small, Medium, Large"), a list of values, a list of (value, label) pairs or a list of {"value": ..., "label": ...} dicts. The bound field gets the value itself, so [(1, "One"), (2, "Two")] binds an int.

TextField, TextArea, NumberField, Select and DatePicker emit blur when the user leaves them, which is when a form starts showing that field's message.

Data and navigation

Control Fields Notes
Tabs options, label, variant (line, pills) @bind to the chosen option's value. The content between the tags is the panel; tab inside it is the chosen value. Arrow keys, Home and End move between tabs.
EventCalendar events, view (month, week, agenda), months, date, week_start, day_start, day_end, max_per_day, time_format, switcher, label Events (dicts or objects with title, start, end, color) by month, week or day; a date start is all day. Emits select (your event), day (the date or hour clicked), navigate ((first, last) showing).
Table rows, columns, row_key, sortable, sort, striped, dense, caption, empty rows are dicts or objects. Emits select with the clicked row. Fills: cell (with row, column, value, text), empty.

Table columns are field names ("id, customer"), (field, heading) pairs, or dicts with key and optionally label, format (",.2f" or a function), align and sortable. Left out, they come from the first row. sort="-total" starts sorted by total, largest first.

Actions and feedback

Control Fields Notes
Button variant (primary, secondary, ghost, danger), size (sm, md, lg), icon, loading, disabled, block, type Emits click.
Menu label, items, icon, icon_only, variant, align (start, end), caret, disabled A button that opens a list of actions; emits select with the chosen item's value. items: text, (value, label) pairs, or dicts with value, label, icon, danger, disabled; "-" is a divider.
Dialog title, width, dismissible @bind to a bool: open while it is True. Esc, a click outside or the X close it. Keeps Tab inside while open and gives focus back when closed. Fill: footer.
Toaster position (bottom-right, bottom-left, bottom-center, top-left, top-center, top-right), limit Put one on the page; it shows what toast() raises.
Alert kind (info, success, warning, danger), title, dismissible Emits close.
Badge kind (neutral, primary, info, success, warning, danger)
Spinner size, label
Icon name, size check, x, plus, minus, search, info, alert, chevron-up/down/left/right, menu, trash, edit, send, user, home, star, heart, download, upload, external, copy, settings, sun, moon, calendar, more

Checking forms

from pyweft_ui import Form, rules

form = Form(
    email=[rules.required(), rules.email()],
    password=[rules.required(), rules.min_length(8)],
    agreed=rules.accepted("Agree to the terms to continue"),
)

async def submit(self):
    if not self.form.check():     # shows every message, focuses the first field to fix
        return
    ...
<ui.TextField ref="email" label="Email" @bind="email"
              :error="form.error('email')" @blur="form.touch('email')" />

A field's message shows once the user has left it or tried to submit, then follows what they type. Rules: required, accepted, email, url, min_length, max_length, min_value, max_value, pattern, one_of, same_as and check, or any function of the value that returns a message. form.valid, form.errors and form.reset() do what they say. The guide has the details.

Toasts

from pyweft_ui import toast, clear_toasts

toast("Saved")                                   # info, closes after 4 s
toast("Payment failed", "danger", title="Oops")  # kind: info, success, warning, danger
toast("Archived", action="Undo", on_action=undo) # a button that calls undo()
note = toast("Uploading…", duration=None)        # stays until note.close()

Call it from any handler or task; the page's <ui.Toaster /> shows it.

Theming

<ui.Theme mode="auto" primary="#0f766e" radius="12px">
  ...
</ui.Theme>

Every colour is a CSS variable (--ui-primary, --ui-text, --ui-surface, --ui-border, --ui-danger ...), so you can also set them in your own CSS.

gallery/ is a PyWeft app showing every control. From the PyWeft repository:

uv run pyweft run packages/pyweft-ui/gallery

Metadata

Release files for pyweft-ui 0.3.0

For a detailed explanation of source distributions (sdists) and built distributions (wheels), please see the package formats documentation.

Source distribution (sdist)

Source distribution for pyweft-ui 0.3.0
File Size Uploaded Provenance Actions
pyweft_ui-0.3.0.tar.gz 80.7 kB With provenance Details for pyweft_ui-0.3.0.tar.gz

Built distribution (wheel)

Table of built distributions (wheels) for pyweft-ui 0.3.0
File Interpreter ABI Platform Actions
pyweft_ui-0.3.0-py3-none-any.whl Python 3 none any Details for pyweft_ui-0.3.0-py3-none-any.whl

Total release size: 141.3 kB

Release files / pyweft_ui-0.3.0.tar.gz

Download URL pyweft_ui-0.3.0.tar.gz
Size 80.7 kB
Tags Source
SHA-256 checksum
How to use checksums
3e8a04d3c8058539f997b4cb79fbab6a71c51ab62031f472ab45e92a61bf934b
BLAKE2b-256 checksum
How to use checksums
f2b0f6e399eb09392a9cf523a4881e6ca150690dcd25b6c9b2bf40a157902149
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
Yes
Uploaded via twine/7.0.0 CPython/3.13.16

Provenance

Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.

PyPI Publish Attestation

PyPI verified that this artifact, at this checksum, originated from the publisher listed below.

Signed by GitHub Actions, verified by PyPI on Nov 4, 2026.

Transparency log

Release files / pyweft_ui-0.3.0-py3-none-any.whl

Download URL pyweft_ui-0.3.0-py3-none-any.whl
Size 60.6 kB
Tags Python 3
SHA-256 checksum
How to use checksums
65383138812e531e901ba84c8acaaa5547848a35317121acd745a4e66e273232
BLAKE2b-256 checksum
How to use checksums
77562bf3f50e053ba67291a866b3d856c53eca99db24f6be4548141039248e1e
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
Yes
Uploaded via twine/7.0.0 CPython/3.13.16

Provenance

Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.

PyPI Publish Attestation

PyPI verified that this artifact, at this checksum, originated from the publisher listed below.

Signed by GitHub Actions, verified by PyPI on Nov 4, 2026.

Transparency log

Security for pyweft-ui 0.3.0

Provenance

Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.

Full provenance

All 2 files in this release have been uploaded with provenance metadata.

Select from 2 files

Attestation for pyweft_ui-0.3.0.tar.gz

PyPI Publish Attestation

PyPI verified that this artifact, at this checksum, originated from the publisher listed below.

Signed by GitHub Actions, verified by PyPI on Nov 4, 2026.

Transparency log

A note on package security

PyPI is a repository for distributing packages, not a service for auditing them. While third-party security researchers and our staff do their best to detect and remove malicious packages, PyPI cannot guarantee the quality, security or suitability of any given package.

To learn more about protecting yourself from malicious actors, visit our package security documentation.

Anthropic, PBC Visionary sponsor Bloomberg Visionary sponsor Hudson River Trading Visionary sponsor Meta Visionary sponsor NVIDIA Visionary sponsor Microsoft Sustainability sponsor Depot Continuous Integration AWS Cloud computing and Security Sponsor Datadog Monitoring Fastly CDN Google Download Analytics Sentry Error logging StatusPage Status page