Metadata-Version: 2.4
Name: cf-ui
Version: 0.3.1
Summary: CSS framework UI kit for component-framework — Bulma, Bootstrap, Foundation, Fomantic, DaisyUI
Project-URL: Homepage, https://github.com/fsecada01/component-framework-ui
Project-URL: Repository, https://github.com/fsecada01/component-framework-ui
Project-URL: Issues, https://github.com/fsecada01/component-framework-ui/issues
Author-email: Francis Secada <francis.secada@gmail.com>
License: MIT
License-File: LICENSE
Keywords: alpinejs,bulma,components,django,fastapi,htmx,litestar
Classifier: Development Status :: 4 - Beta
Classifier: Framework :: Django
Classifier: Framework :: FastAPI
Classifier: Intended Audience :: Developers
Classifier: License :: OSI Approved :: MIT License
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: Topic :: Internet :: WWW/HTTP :: Dynamic Content
Classifier: Topic :: Software Development :: Libraries :: Python Modules
Classifier: Typing :: Typed
Requires-Python: >=3.11
Requires-Dist: component-framework>=0.6
Requires-Dist: pydantic>=2.0
Provides-Extra: all
Requires-Dist: django-cotton>=2.0; extra == 'all'
Requires-Dist: django>=4.2; extra == 'all'
Requires-Dist: fastapi>=0.109.0; extra == 'all'
Requires-Dist: jinja2>=3.1; extra == 'all'
Requires-Dist: jinjax>=0.41; extra == 'all'
Requires-Dist: litestar>=2.0; extra == 'all'
Requires-Dist: python-multipart>=0.0.5; extra == 'all'
Requires-Dist: uvicorn[standard]>=0.27.0; extra == 'all'
Provides-Extra: bootstrap
Provides-Extra: bulma
Provides-Extra: daisy
Provides-Extra: dev
Requires-Dist: django-cotton>=2.0; extra == 'dev'
Requires-Dist: django>=4.2; extra == 'dev'
Requires-Dist: djlint>=1.43; extra == 'dev'
Requires-Dist: fastapi>=0.109.0; extra == 'dev'
Requires-Dist: httpx>=0.26; extra == 'dev'
Requires-Dist: jinja2>=3.1; extra == 'dev'
Requires-Dist: jinjax>=0.41; extra == 'dev'
Requires-Dist: litestar>=2.0; extra == 'dev'
Requires-Dist: mkdocs-material>=9.5; extra == 'dev'
Requires-Dist: mkdocs>=1.6; extra == 'dev'
Requires-Dist: pre-commit>=3.5; extra == 'dev'
Requires-Dist: pytest-asyncio>=0.21; extra == 'dev'
Requires-Dist: pytest-django>=4.5; extra == 'dev'
Requires-Dist: pytest-playwright>=0.4; extra == 'dev'
Requires-Dist: pytest>=7.4; extra == 'dev'
Requires-Dist: python-multipart>=0.0.5; extra == 'dev'
Requires-Dist: ruff>=0.1; extra == 'dev'
Requires-Dist: ty>=0.0.18; extra == 'dev'
Requires-Dist: uvicorn[standard]>=0.27.0; extra == 'dev'
Provides-Extra: django
Requires-Dist: django-cotton>=2.0; extra == 'django'
Requires-Dist: django>=4.2; extra == 'django'
Provides-Extra: docs
Requires-Dist: mkdocs-material>=9.5; extra == 'docs'
Requires-Dist: mkdocs>=1.6; extra == 'docs'
Provides-Extra: fastapi
Requires-Dist: fastapi>=0.109.0; extra == 'fastapi'
Requires-Dist: jinjax>=0.41; extra == 'fastapi'
Requires-Dist: python-multipart>=0.0.5; extra == 'fastapi'
Requires-Dist: uvicorn[standard]>=0.27.0; extra == 'fastapi'
Provides-Extra: fomantic
Provides-Extra: foundation
Provides-Extra: litestar
Requires-Dist: jinja2>=3.1; extra == 'litestar'
Requires-Dist: jinjax>=0.41; extra == 'litestar'
Requires-Dist: litestar>=2.0; extra == 'litestar'
Description-Content-Type: text/markdown

# component-framework-ui

> CSS framework UI kit for [`component-framework`](https://github.com/fsecada01/component-framework) — Bulma, Bootstrap, Foundation, Fomantic UI, DaisyUI.

[![CI](https://github.com/fsecada01/component-framework-ui/actions/workflows/ci.yml/badge.svg)](https://github.com/fsecada01/component-framework-ui/actions/workflows/ci.yml)
[![Docs](https://github.com/fsecada01/component-framework-ui/actions/workflows/docs.yml/badge.svg)](https://fsecada01.github.io/component-framework-ui/)
[![Python 3.11+](https://img.shields.io/badge/python-3.11+-blue.svg)](https://www.python.org/downloads/)
[![Status: Beta](https://img.shields.io/badge/status-beta-blue.svg)]()

**📖 Full documentation: <https://fsecada01.github.io/component-framework-ui/>**

---

Fourteen ready-to-use components in two first-class template sets:

| Template set | Engine | Web frameworks |
|---|---|---|
| `jinja/` | Jinja2 / JinjaX | FastAPI, Litestar |
| `cotton/` | django-cotton | Django |

Component names are **theme-agnostic** — `<Cf:Card>` and `<c-cf.card>` render
whichever theme is active. Switching CSS frameworks means changing one config
line, not hundreds of templates.

## Install

```bash
pip install "cf-ui[django,bulma]"        # Django + Bulma
pip install "cf-ui[fastapi,daisy]"       # FastAPI + Tailwind/DaisyUI
pip install "cf-ui[litestar,bootstrap]"  # Litestar + Bootstrap 5
```

All template sets ship in every install. Theme selection is runtime config, not
install-time.

→ [Installation guide](https://fsecada01.github.io/component-framework-ui/installation/)

## Thirty-second look

```django
{# Django #}
{% load cf_ui %}
<c-cf.card header="Welcome">Card body content.</c-cf.card>
<c-cf.form-field name="email" label="Email" type="email" />
```

```python
# FastAPI
from jinjax import Catalog

from cf_ui.fastapi import install_cf_ui

catalog = Catalog()
install_cf_ui(catalog, theme="bulma")

html = catalog.render("Cf:Card", header="Welcome", _content="Card body.")
```

→ [Quickstart for all three frameworks](https://fsecada01.github.io/component-framework-ui/quickstart/)

## Themes

| Theme | Status |
|---|---|
| Bulma | ✅ |
| Tailwind + DaisyUI | ✅ — [guide](https://fsecada01.github.io/component-framework-ui/daisyui/) |
| Bootstrap 5 | ✅ — CSS only, no `bootstrap.bundle.js`; [decision record](https://fsecada01.github.io/component-framework-ui/bootstrap/) |
| Foundation 6 | ✅ — CSS only, no jQuery |
| Fomantic UI | ✅ — CSS only, no jQuery |

Switching is one line — `CF_UI_THEME = "daisy"` on Django, `theme="daisy"` on
FastAPI/Litestar — and needs no template edits in the consuming app. An
unimplemented theme name is rejected at startup rather than at first render.

## Documentation

| Page | What's in it |
|---|---|
| [Installation](https://fsecada01.github.io/component-framework-ui/installation/) | Extras, requirements, asset options |
| [Quickstart](https://fsecada01.github.io/component-framework-ui/quickstart/) | Django, FastAPI, and Litestar setups |
| [Getting started](https://fsecada01.github.io/component-framework-ui/getting-started/) | Themes, assets, composition axes, Alpine, escaping |
| [Use cases](https://fsecada01.github.io/component-framework-ui/use-cases/) | HTMX tables, modals, forms with errors |
| [Components](https://fsecada01.github.io/component-framework-ui/components/) | All fourteen, with every prop |
| [Escaping](https://fsecada01.github.io/component-framework-ui/escaping/) | Why cf-ui escapes its own output |
| [Theming](https://fsecada01.github.io/component-framework-ui/theming/) | Composition axes and custom value sets |
| [Tailwind plugin](https://fsecada01.github.io/component-framework-ui/tailwind-plugin/) | Build-time axis validation |
| [Accessibility](https://fsecada01.github.io/component-framework-ui/accessibility/) | Focus management, ARIA, keyboard behavior |

## Development

```bash
git clone https://github.com/fsecada01/component-framework-ui
cd component-framework-ui
uv pip install -e ".[dev]"
playwright install chromium

just test             # unit tests
just test-integration # integration tests
just test-e2e         # E2E Playwright tests (requires chromium)
just test-all         # everything
just lint             # ruff check
just format           # ruff format
just docs             # serve the docs site locally
```

## Requirements

- Python 3.11+
- `component-framework >= 0.4`
- Pydantic 2.0+ *(only mandatory runtime dependency)*

Optional extras:
- `[django]` — Django 4.2+, django-cotton 2.0+
- `[fastapi]` — FastAPI 0.109+, JinjaX 0.41+, uvicorn, python-multipart
- `[litestar]` — Litestar 2.0+, Jinja2 3.1+, JinjaX 0.41+

Jinja2 and JinjaX are layers, not alternatives, which is why the Litestar
extra names both. Litestar's `JinjaTemplateEngine` owns the Jinja2
environment, and cf-ui installs a JinjaX catalog onto it — so `<Cf:Card>`
renders from the same template on both paths. The FastAPI extra omits Jinja2
only because JinjaX pulls it in transitively there, where the catalog owns
the environment outright.

## License

MIT
