Metadata-Version: 2.5
Name: spaday-spectrum
Version: 0.3.0
Summary: Spectrum for spaday
Project-URL: Repository, https://github.com/1kbgz/spaday-spectrum
Project-URL: Homepage, https://github.com/1kbgz/spaday-spectrum
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.10.0
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

<a href="https://github.com/1kbgz/spaday-spectrum">
  <picture>
    <source media="(prefers-color-scheme: dark)" srcset="https://github.com/1kbgz/spaday-spectrum/raw/main/docs/img/logo-dark.webp?raw=true">
    <img alt="spaday-spectrum logo, a prism splitting light inside a browser window" src="https://github.com/1kbgz/spaday-spectrum/raw/main/docs/img/logo-light.webp?raw=true" width="1200">
  </picture>
</a>

[Spectrum](https://opensource.adobe.com/spectrum-web-components/) for [spaday](https://1kbgz.github.io/spaday/)

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

[![Preview of Spectrum components in spaday rendering a review board](https://raw.githubusercontent.com/1kbgz/spaday-spectrum/main/docs/img/preview.webp)](https://1kbgz.github.io/spaday-spectrum/lite/)

## Overview

`spaday-spectrum` provides generated Python bindings and a self-contained registration bundle for a
focused first slice of Adobe Spectrum Web Components:

- Theme
- Button, clear button, and close button
- Textfield
- Checkbox and switch
- Tabs, tab panels, and tabs overflow

## Generic controls

Select the `spectrum` design to render spaday's generic button, text input, text area, checkbox, and
switch as Spectrum elements:

```python
from spaday import Button, Column, TextInput
from spaday.backends.starlette import serve

page = Column(
    TextInput(label="Name").bind("value", "name", mode="two-way"),
    Button(label="Save", intent="primary"),
)
app = serve(page, packages=["spectrum"], design="spectrum", store={"name": ""})
```

Controls outside this focused Spectrum package use spaday's marked native fallback. The package's
shared conformance test covers both the Spectrum controls and those substitutions.

## Interactive example

The textfield updates the greeting immediately, the checkbox switches Spectrum themes, and the button
resets state. All three interactions run in the browser through spaday's reactive store.

```python
from spaday import SetField, cond, element, field
from spaday.backends.starlette import serve
from spaday_spectrum import SpButton, SpCheckbox, SpTextfield, SpTheme

page = (
    SpTheme(scale="medium")
    .compute("color", cond(field("dark"), "dark", "light"))
    .style(display="block", max_width="32rem", margin="2rem auto", padding="1.5rem")
    .child(element("h1").text("Spectrum profile"))
    .child(SpTextfield(label="Display name", placeholder="Your name").bind("value", "name", mode="two-way"))
    .child(SpCheckbox().text("Dark theme").bind("checked", "dark", mode="two-way"))
    .child(
        element("p")
        .child("Hello, ")
        .child(element("strong").bind("textContent", "name"))
    )
    .child(SpButton(treatment="fill").text("Reset name").on("click", SetField("name", "Ada")))
)

app = serve(page, packages=["spectrum"], store={"name": "Ada", "dark": False})
```

Save this as `app.py`, then run `pip install spaday-spectrum starlette uvicorn` and
`uvicorn app:app`. Open <http://127.0.0.1:8000>.

Installing this project registers the `spectrum` entry point with spaday. The equivalent explicit
forms are `packages=[spaday_spectrum.package]` and `packages=["spaday_spectrum:package"]`.

The package pins six individual Spectrum packages to `1.12.2`. It deliberately avoids the full
`@spectrum-web-components/bundle`; more components should be added from concrete application needs.

The typed classes are generated from those packages' Custom Elements Manifests with `make catalog`.
Spectrum publishes one package per component, and a published manifest leaves out what an element
inherits from another package — `size`, `disabled`, `href`, and on `sp-switch` even `checked`.
`js/tools/manifests.mjs` resolves each element's superclass and mixins through the manifests of the
packages that declare them and writes the result to `spaday_spectrum/manifests/`, which the classes
are generated from. `base` and `shared` publish no manifest at all, so the few declarations needed
from them are transcribed in `js/tools/unpublished.json`; the tool fails on any class neither covers.

## Browser examples

- [Open the standard app](https://1kbgz.github.io/spaday-spectrum/lite/) ([source](spaday_spectrum/example.py)).
- [Open the complete component gallery](https://1kbgz.github.io/spaday-spectrum/lite/?example=gallery) ([source](spaday_spectrum/gallery.py)).

Both run Python locally through Pyodide; no install or server is required.

## Run examples locally

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

Open `http://127.0.0.1:8028` for the standard creative-review app or `http://127.0.0.1:8029` for the
component gallery. The standard app includes streamed assets, endpoint-backed review decisions and brief
submission, an activity feed, bound fields and switches, tabs, dismissible feedback, and shared Spectrum
color and scale state. The gallery includes every generated component in this focused package and a
highlighted Python snippet for each family.

Both pass the local package descriptor directly, so they do not install or resolve the integration from
GitHub.

> [!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).
