Metadata-Version: 2.4
Name: wapyt
Version: 0.2.0
Summary: DHTMLX-free pyTincture widgetset: layouts, forms, tables, trees, chat, terminal, menus, Kanban and more, declared in Python and rendered in the browser.
License: MIT
Project-URL: homepage, https://github.com/WAwesome-AI/wa_pytincture_widgetset
Project-URL: documentation, https://github.com/WAwesome-AI/wa_pytincture_widgetset/wiki
Project-URL: changelog, https://github.com/WAwesome-AI/wa_pytincture_widgetset/wiki/Widget-Catalog#changes
Keywords: pytincture,widgetset,pyodide,wapyt
Requires-Python: >=3.13
Description-Content-Type: text/markdown

# wA PyTincture Widgetset (`wapyt`)

`wapyt` is a lightweight widgetset for [pyTincture](https://github.com/pytincture/pytincture) that avoids the commercial DHTMLX dependency used by the legacy package. It focuses on a DOM-driven layout engine and a set of first-class widgets that can be composed entirely from Python when running inside Pyodide.

## Highlights
- **Theme-aware layout**: Flexbox-based layout manager that mirrors the familiar `LayoutConfig`/`CellConfig` API, supports nested rows/columns, and exposes helper methods such as `attach_html`, `collapse`, `toggle`, `hide`, etc.
- **Widgets that don’t require DHTMLX**: Native Chat, CardPanel, TabWidget, Sidebar, ModalWindow, and ResourceBoard implementations with the streaming/events helpers the PyTincture samples expect.
- **`MainWindow` wrapper**: Thin helper built on top of `Layout` so existing apps can continue to expose a `MainWindow` class with no additional boilerplate.
- **PyTincture metadata**: Exposes `__widgetset__ = "wapyt"` so the platform can auto-discover the package name/version during `***WIDGETSET***` substitution.
- **Test/demo apps**: Located under `tests/` to show how to embed the widgets inside PyTincture applications.

## Widget Catalog
- `Layout` / `MainWindow`: Flexbox-driven layout primitives plus a drop-in `MainWindow` helper that mirrors the legacy PyTincture entrypoint.
- `Chat`: Streaming chat surface with agent metadata, artifact events, and helpers for incremental responses.
- `CardPanel`: Searchable, template-driven card grid with add/view/action callbacks and custom renderers.
- `TabWidget`: Lightweight tab host that supports badges, closable tabs, and attaching HTML or PyTincture components per tab.
- `Sidebar`: Collapsible navigation rail with icons, badges, nested groups (a flyout when collapsed), headings, separators and a spacer for bottom-pinned items; keyboard navigable.
- `ModalWindow`: Simple modal shell that can host arbitrary Layout instances or HTML snippets.
- `ResourceBoard`: Master/detail resource explorer with selectable rows, action hooks, and optional add button wiring.
- `message`: Toasts plus awaitable `alert` / `confirm` / `prompt` dialogs, styled and themed, in place of `window.confirm()`.
- `Toolbar`: Buttons, toggles, one-of-several groups, text, separators and spacers, dropping to icons when space runs out.
- `ContextMenu`: Right-click menus with icons, shortcut hints, danger and disabled items, checkable and radio items, separators and submenus; keyboard accessible.
- `MenuBar`: A File / Edit / View application menu whose titles open ContextMenu dropdowns; full menubar keyboard model.
- `Kanban`: A board of Listbox columns with counts, WIP limits (optionally strict), add-card buttons, collapsible and reorderable columns, a board-wide filter and selection.
- `Listbox`: Rich list items (fields or an escaped template) that can host live widgets, with actions, selection, a filter, and pointer and keyboard drag-and-drop within and between lists; the base for Kanban.
- `Popup` and tooltips: An anchored popover for pickers, help and small forms; styled, keyboard-reachable tooltips that replace native `title` text across the widgets.
- `ProgressBar` / `progress_html`: Determinate or indeterminate bars with active/done/error/paused states, as a live widget or static markup.
- `Pagination`: First/previous/next/last, a page box or numbered buttons, a page-size selector and a "1–50 of 1,234" summary; copes with totals the server could not count.
- `MediaPlayer`: Video and audio with a queue — the picture in place, an audio bar that can dock to the foot of the window, or a compact inline player for a chat message; HLS through bundled hls.js, WebVTT subtitles, items whose URL is resolved only when reached, exclusive groups, keyboard and OS media keys, buttons of the app's own in the bar (`MediaAction`, `on_action`: "add to playlist", "save"), and any media source: files from disk, a CDN, cookies, Bearer headers (`MediaItem(headers=…)`), expiring signed URLs (`refresh()`), live streams (`live=True`) and a Quality menu.

## Runtime Architecture
- Layouts and widgets are declared in Python but render as DOM nodes through the JavaScript bundles under `wapyt/assets/`. Each helper (e.g., `Layout.add_chat`) forwards config dictionaries directly to the matching JS constructor.
- The `wapyt/_runtime.py` bridge exposes `require_js` to lazily inject JS/CSS exactly once per interpreter and `create_proxy` to keep Pyodide callback proxies alive for event handlers.
- Layout cells are plain flexbox containers (`wapyt/assets/layout.js` + `wapyt/assets/wapyt.css`), so attaching raw HTML or third-party widgets is as simple as calling `layout.attach_html(cell_id, markup)`.
- Because everything routes through `window.wapyt`, you can add new widgets by dropping a JS file into `wapyt/assets/`, exporting a constructor, and calling `require_js("MyWidget")` before instantiating it from Python.

## Getting Started

```bash
cd wapyt
uv venv --python 3.13 && source .venv/bin/activate
uv pip install -e .
```

Then run a PyTincture example pointing at this widgetset:

```bash
cd ../pytincture
uv run pytincture launch_service --modules_folder ../wA_pytincture_widgetset/tests --port 8070
```

Open http://localhost:8070/layout_demo in your browser to see the native layout, and swap in `chat_demo` / `cardpanel_demo` / `tabs_demo` to explore the specialized widgets.

## Package Layout

```
wapyt/
  ├── chat/        # Chat widget config + wrapper
  ├── cardpanel/   # CardPanel widget config + wrapper
  ├── layout/      # Layout/MainWindow helpers
  ├── modal/       # ModalWindow + config
  ├── resourceboard/ # ResourceBoard widget + config
  ├── sidebar/     # Sidebar widget config + wrapper
  ├── tabwidget/   # Tab widget config + wrapper
  └── assets/      # JS + CSS evaluated automatically by PyTincture
```


## Development Notes

- The JavaScript bundles define the `window.wapyt` namespace and are evaluated automatically by PyTincture’s loader (see `pytincture/frontend/pytincture.js`).
- Layout styles live in `assets/wapyt.css`; adjust tokens there to integrate with your design system.
- Message content is rendered by the escaping markdown renderer in `assets/chat.js`. If a page also loads
  [`marked`](https://marked.js.org/), the widget uses it **only** when `DOMPurify` is present as well —
  `marked` passes raw HTML through, so without a sanitizer the widget falls back to its own renderer.
- Artifact previews run in `<iframe sandbox="allow-scripts">` with no `allow-same-origin`: artifact code is
  treated as untrusted and cannot reach the host page.
- `tests/` holds two different things: the `*_demo.py` files are small, framework-free PyTincture apps you can
  copy/paste into your own projects, and `test_*.py` are CPython unit tests for the pure-Python half of the
  widgetset. Run the latter with `uv run --group dev pytest tests/` (or `pytest tests/` in an activated venv);
  they need no browser and no demo dependencies, and `tests/conftest.py` puts the repo root on `sys.path` so
  they work from a fresh clone.

## License

MIT – see `pyproject.toml` for details.
