Metadata-Version: 2.5
Name: spaday-vaadin
Version: 0.1.0
Summary: Vaadin for spaday
Project-URL: Repository, https://github.com/1kbgz/spaday-vaadin
Project-URL: Homepage, https://github.com/1kbgz/spaday-vaadin
Author-email: 1kbgz <dev@1kbgz.com>
License: Apache-2.0
License-File: LICENSE
Classifier: Development Status :: 3 - Alpha
Classifier: Programming Language :: Python
Classifier: Programming Language :: Python :: 3
Classifier: Programming Language :: Python :: 3.11
Classifier: Programming Language :: Python :: 3.12
Classifier: Programming Language :: Python :: 3.13
Classifier: Programming Language :: Python :: 3.14
Classifier: Programming Language :: Python :: Implementation :: CPython
Classifier: Programming Language :: Python :: Implementation :: PyPy
Requires-Python: >=3.11
Requires-Dist: spaday<1.0,>=0.8.2
Provides-Extra: develop
Requires-Dist: build; extra == 'develop'
Requires-Dist: bump-my-version; extra == 'develop'
Requires-Dist: check-dist; extra == 'develop'
Requires-Dist: codespell; extra == 'develop'
Requires-Dist: hatch-js; extra == 'develop'
Requires-Dist: hatchling; extra == 'develop'
Requires-Dist: httpx; extra == 'develop'
Requires-Dist: mdformat; extra == 'develop'
Requires-Dist: mdformat-tables>=1; extra == 'develop'
Requires-Dist: pydantic>=2; extra == 'develop'
Requires-Dist: pytest; extra == 'develop'
Requires-Dist: pytest-cov; extra == 'develop'
Requires-Dist: ruff; extra == 'develop'
Requires-Dist: starlette; extra == 'develop'
Requires-Dist: transports; extra == 'develop'
Requires-Dist: twine; extra == 'develop'
Requires-Dist: ty; extra == 'develop'
Requires-Dist: uv; extra == 'develop'
Requires-Dist: uvicorn; extra == 'develop'
Requires-Dist: websockets; extra == 'develop'
Requires-Dist: wheel; extra == 'develop'
Provides-Extra: examples
Requires-Dist: pydantic>=2; extra == 'examples'
Requires-Dist: starlette; extra == 'examples'
Requires-Dist: transports; extra == 'examples'
Requires-Dist: uvicorn; extra == 'examples'
Requires-Dist: websockets; extra == 'examples'
Description-Content-Type: text/markdown

# spaday-vaadin

Typed [Vaadin](https://vaadin.com/docs/latest/components) web components and browser assets for spaday.

[![Build Status](https://github.com/1kbgz/spaday-vaadin/actions/workflows/build.yaml/badge.svg?branch=main&event=push)](https://github.com/1kbgz/spaday-vaadin/actions/workflows/build.yaml)
[![codecov](https://codecov.io/gh/1kbgz/spaday-vaadin/branch/main/graph/badge.svg)](https://codecov.io/gh/1kbgz/spaday-vaadin)
[![License](https://img.shields.io/github/license/1kbgz/spaday-vaadin)](https://github.com/1kbgz/spaday-vaadin)
[![PyPI](https://img.shields.io/pypi/v/spaday-vaadin.svg)](https://pypi.python.org/pypi/spaday-vaadin)

[![Preview of vaadin components in spaday rendering a fulfillment cockpit](https://raw.githubusercontent.com/1kbgz/spaday-vaadin/main/docs/img/preview.webp)](./spaday_vaadin/example.py)

## Overview

```python
from spaday import SetField, element, serve
from spaday_vaadin import VaadinButton, VaadinGrid, VaadinGridColumn, VaadinTextField

page = element("div").child(
    VaadinButton(theme="primary").text("Approve").on("click", SetField("state", "approved")),
    VaadinTextField(label="State", readonly=True).bind("value", "state"),
    VaadinGrid(items=[{"name": "Ada"}, {"name": "Grace"}]).child(VaadinGridColumn(path="name")),
)
serve(page, packages=["vaadin"], store={"state": "pending"})
```

A curated core of Vaadin's free components — button, checkbox, combo box, date picker, dialog, grid
and its columns, notification, select, tabs and text field, 20 elements in all — has typed classes
generated from their Custom Elements Manifests, so props, events and slots are checked when you
author the tree. Array properties such as a grid's `items` are keyword arguments too, set on the
element as properties. Installing the package does not inject assets; select it with
`packages=["vaadin"]` or pass the exported `package` descriptor.

## Run the local example

```bash
python -m pip install -e ".[examples]"
python -m spaday_vaadin.example
```

Open `http://127.0.0.1:8027` for the [fulfillment desk](spaday_vaadin/example.py): a grid of orders
streamed live from Python with selection, sorting and filtering, shipping the selected orders through a
Python endpoint, an order form of combo box, text field, select, date picker and checkbox two-way bound
to spaday state, a dialog confirming what the server created, tabs, Lumo badges, and a dark mode that
re-themes Lumo and the spaday shell together.

## Theming

The elements are styled with Vaadin's Lumo theme, and the stylesheet maps spaday's `--spa-*` shell
palette onto Lumo's properties, so restyling Lumo restyles the shell and every other spaday component
package with it. `TOKENS` lists the properties wired to the palette:

```python
App().css(lumo_primary_color="#0C4253")
```

The theme follows spaday's page mode: a `wa-dark` class (for example
`App(...).bind_root_class("wa-dark", "dark")`) switches Lumo to dark, and a `wa-light` island inside
a dark page stays light.

## Sharing Vaadin with your own library

Vaadin registers global custom element names, so a page can hold only one copy. The package serves
Vaadin's modules under their own bare specifiers — `@vaadin/button`, `@vaadin/grid/…`,
`@vaadin/component-base/…` and the other packages these elements are built from — through the page's
import map. A library that imports or extends them and leaves those imports out of its bundle
(`external: ["@vaadin/*"]` with esbuild) gets this copy.

The served copy carries the opt-out of Vaadin's development-time usage statistics, which its package
normally installs at `npm install` time.

> [!NOTE]
> This library was generated using [copier](https://copier.readthedocs.io/en/stable/) from the [Base Python Project Template repository](https://github.com/python-project-templates/base).
