Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
7 changes: 4 additions & 3 deletions docs/getting-started/component-styling.md
Original file line number Diff line number Diff line change
Expand Up @@ -14,11 +14,12 @@ the content.
[Download the notebook](../assets/styling-notebook-alpha11/component_styling.ipynb){ .md-button download="component_styling.ipynb" }
[View the pinned source](https://github.com/fullbleed-engine/docs/blob/70fd19a7f292ce52bfb466ed782d4c4776a68f12/examples/styling-notebook-alpha11/component_styling.ipynb){ .md-button }

!!! info "Opt-in component preview: 2.6.0a11"
!!! info "This notebook is pinned to 2.6.0a11"
The first cell installs `fullbleed==2.6.0a11`. The API under
`fullbleed.ui.experimental` remains experimental. Ordinary `pip install
fullbleed` selects the stable channel. The [current preview guide](../guides/component-preview-11.md)
includes the complete source kit, API references and release evidence.
fullbleed` selects the stable channel. The [matching preview guide](../guides/component-preview-11.md)
includes its source kit and release evidence. The [current alpha 12 guide](../guides/component-preview-12.md)
introduces `fullbleed.components`; the notebook's earlier import path remains supported.

[![The default Common Ground report, with forest-green typography, a pale metrics panel and a numbered footer.](../assets/styling-notebook-alpha11/default-page-1.png){ width="340" }](../assets/styling-notebook-alpha11/field-notes.pdf)
[![An edited report with smaller headings, violet labels and metric values, a lavender panel and a teal page number.](../assets/styling-notebook-alpha11/edited-page-1.png){ width="340" }](../assets/styling-notebook-alpha11/edited.pdf)
Expand Down
191 changes: 191 additions & 0 deletions docs/guides/component-preview-12.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,191 @@
---
title: Compose styled PDF and HTML with Python components
description: Use Python functions, reusable styles and explicit class names to author PDF and HTML. Try the Fullbleed 2.6.0a12 component namespace and complete migration kit.
---

# Compose documents with Python components

Use Python functions for reusable document sections, pass data as arguments,
and keep each component's default styles with its definition. Export the same
tree as a PDF, styled HTML or unstyled HTML without writing HTML strings.

**2.6.0a12** introduces `fullbleed.components` as the intended public namespace.
It preserves both earlier import paths and adds a complete document migration
example: two implementations produce the same A5 and Letter landscape reports.

[Download the migration source kit](https://github.com/fullbleed-engine/fullbleed-official/releases/download/v2.6.0a12/fullbleed-component-migration-2.6.0a12.zip){ .md-button .md-button--primary }
[Read the migration reference](https://github.com/fullbleed-engine/fullbleed-official/blob/v2.6.0a12/docs/component-namespace.md){ .md-button }

!!! info "The API remains alpha"
Use Python 3.10 or later in a virtual environment and install
`python -m pip install --pre "fullbleed==2.6.0a12"`.
Ordinary `pip install fullbleed` selects the stable channel.
The existing `fullbleed.ui` API remains supported. A public namespace does
not itself make the new API stable; the [release status](component-status.md)
records the remaining decisions.

## Write a component with its own styles

`Summary` below is an ordinary reusable function. `Title` carries its default
appearance, while `.muted` is an explicit stylesheet rule:

```python
from importlib.resources import files
from pathlib import Path
from fullbleed.components import (
Document, Flow, Heading, Page, Paragraph, Renderer, Theme,
component, mm, pt, style, styled,
)

Title = styled(Heading, font_size=pt(24), color="#183e36")

@component
def Summary(title, description):
return Flow(
Title(title, level=1),
Paragraph(description, class_name="muted"),
gap=pt(12),
)

document = Document(
Summary("Project summary", "Prepared by Northstar Studio."),
title="Project summary",
lang="en-US",
page=Page("A5", margin=mm(16)),
theme=Theme(text=style(font_family="Inter", font_size=pt(11))),
styles={".muted": style(color="#50665f")},
)
font = files("fullbleed_assets").joinpath("fonts/Inter-Variable.ttf")
renderer = Renderer(font_files=[str(font)])
Path("summary.pdf").write_bytes(document.render_pdf(renderer))
Path("summary.html").write_text(document.to_html(include_styles=True), encoding="utf-8")
Path("summary.unstyled.html").write_text(
document.to_html(include_styles=False), encoding="utf-8"
)
```

`class_name="muted"` writes the literal class `muted`. The matching `.muted`
rule in `Document(styles=...)` supplies its appearance. The dot belongs in the
selector. A function name or class name does not load a stylesheet automatically.

| Change you want | Where to put it |
| --- | --- |
| Reusable defaults for a heading, box or paragraph | `styled(...)` |
| One component instance | `style=style(...)` or `.with_style(...)` |
| A component's named internal part | `.with_parts(...)` |
| Shared typography and theme values | `Theme(...)` on `Document` |
| A literal CSS class | `class_name="..."` and a matching rule in `Document(styles=...)` |
| Paper size, orientation and margins | `Page(...)` on `Document` |

The [styling notebook](../getting-started/component-styling.md) lets you edit
these style mechanisms in a complete Common Ground report. It keeps its
explicit alpha 11 pin; the earlier import path continues to work in alpha 12.
The [component reference](https://github.com/fullbleed-engine/fullbleed-official/blob/v2.6.0a12/docs/component-bootstrap.md)
covers style precedence, named parts and static Bootstrap 5.0.0 helpers.

## Export with or without styles

`document.to_html(include_styles=True)` embeds component styles, the theme and attached selector
rules. `document.to_html(include_styles=False)` removes generated CSS and inline
styles while keeping semantic content and literal classes, ready for a host
stylesheet. `Flow` gaps work in styled browser HTML.

The default `document.to_html()` keeps the separate-CSS form used with
`document.to_css()`. Choose `include_styles=True` for a complete styled HTML
file, or `False` when another application owns the styles.

PDF uses the explicitly registered font. Browser HTML needs its own font loading
or fallback; registering a font with `Renderer` does not give a browser a font
URL. Continuous browser layout and native PDF pagination are separate outputs.
Bootstrap helpers are static in both: no Bootstrap JavaScript is included.

## Keep existing imports working

If you already use an earlier alpha, change the import prefix when convenient:

```python
# Earlier alpha: still supported.
from fullbleed.ui.experimental import Document, Paragraph

# Intended public namespace for the new API.
from fullbleed.components import Document, Paragraph
from fullbleed.components import bootstrap as bs
```

These two namespaces expose the same objects. Components, styles and Bootstrap
helpers can be composed across them without a second style registry. Both have
the same typed signatures and editor completions.

The older `fullbleed.ui` API is a different authoring model. Its `Document` is
a decorator; the new `Document` is a value that owns its page, theme and metadata.
Changing an import alone does not migrate an existing decorated document.

## Migrate a whole document

Extract the source kit and open its `fullbleed-component-migration` directory:

```sh
python -m venv .venv
# Windows PowerShell:
.venv\Scripts\Activate.ps1
# macOS/Linux: source .venv/bin/activate
python -m pip install -r requirements.txt
python -I examples/component_migration/render.py --out output
```

Compare `output/a5-legacy.pdf` with `output/a5-components.pdf`, then the two
`letter-landscape` PDFs. Each report has three pages. The kit includes the four
saved PDFs in `preview/` for inspection before installation.

Read `legacy_document` and `migrated_document` side by side in `render.py`:

| Existing document setting | New owner |
| --- | --- |
| Page CSS for paper, orientation and margins | `Page(...)` |
| Engine title and language options | `Document(title=..., lang=...)` |
| Body typography | `Theme(text=style(...))` |
| Repeated class-based defaults | `styled(...)`, with explicit selectors where useful |
| Font files and engine options | `Renderer(...)` |

Change `ROWS` for content, `INK` and `MUTED` for colors, or `REPORTS` for page
geometry. Both implementations retain explicit font registration and a fixed
document timestamp.

For gradual adoption, `to_legacy(node, theme=...)` adapts a new component into
an old tree. It does not move the old document's geometry, metadata, renderer
settings or resource-owning kits such as Bootstrap. The
[migration reference](https://github.com/fullbleed-engine/fullbleed-official/blob/v2.6.0a12/docs/component-namespace.md)
explains those boundaries.

## Rich documents and earlier examples

The [alpha 11 showcase kit](component-preview-11.md) retains the Northstar
invoice, Common Ground reports and authored accessible community guide with
its original package pin. It also demonstrates page bands and styled HTML.
The [paired-authoring guide](showcase-authoring.md) shows the HTML/CSS and
component implementations with the same rendered output.

## Verification and scope

The [alpha 12 release evidence](https://github.com/fullbleed-engine/fullbleed-official/releases/tag/v2.6.0a12)
records package provenance, saved outputs and checks. Local qualification
passes 374 focused component tests and 980 full Python tests. Both import paths
are checked with mypy, Pyright and real language-server completions.

The migration kit renders with Fullbleed alone. Its optional verifier checks
page geometry, per-page text, title/language, resolved timestamp, missing glyphs,
repeat bytes and exact PDFium pixels for the two paired reports. These examples
demonstrate an explicit migration, not automatic conversion of arbitrary CSS.

The independent CSS corpus retains known failures. This release does not claim
complete CSS conformance, browser/PDF layout equivalence, independent kit
usability or human accessibility results. Existing accessible specimen results
remain scoped to their exact verified PDFs.

## Help shape the stable API

Try rebranding a report, reusing a component, or adding a table column. Share
a small synthetic example in the [component RFC](https://github.com/fullbleed-engine/fullbleed-official/discussions/86),
including your installed version, the change you wanted and any step that
required raw HTML or knowledge of generated selectors. Those editing experiences
help identify which authoring contracts still need work.
30 changes: 21 additions & 9 deletions docs/guides/component-status.md
Original file line number Diff line number Diff line change
Expand Up @@ -5,13 +5,13 @@ description: Choose the stable Fullbleed Python component API or its opt-in 2.6

# Python component release status

Reviewed **20 October 2026**. Fullbleed's released Python component API is
Reviewed **21 October 2026**. Fullbleed's released Python component API is
available today. The newer API remains an opt-in alpha.

| Channel | Install | Authoring surface |
| --- | --- | --- |
| Stable **2.5.34** | `python -m pip install fullbleed` | HTML/CSS rendering and the existing `fullbleed.ui` components |
| Alpha **2.6.0a11** | `python -m pip install --pre "fullbleed==2.6.0a11"` | New authoring values under `fullbleed.ui.experimental` |
| Alpha **2.6.0a12** | `python -m pip install --pre "fullbleed==2.6.0a12"` | New authoring values under `fullbleed.components`; earlier imports remain supported |

Start with the [Python quickstart](../getting-started/quickstart.md) for either
HTML/CSS or stable components. Both examples produce the same invoice.
Expand All @@ -20,8 +20,8 @@ children, `class_name`, inline styles and attached stylesheets.

The alpha adds component-owned styles, named customization parts, column-based
tables, static Bootstrap helpers, repeating page bands, and HTML export with or
without styles. Its [current preview guide](component-preview-11.md) includes
installation instructions and a complete source kit.
without styles. Its [current preview guide](component-preview-12.md) includes
installation instructions, explicit styling examples and a complete migration kit.

For interactive walkthroughs, [Explore the versioned component notebook](../getting-started/component-notebook.md)
or [Try the current styling notebook](../getting-started/component-styling.md).
Expand All @@ -37,15 +37,22 @@ it does not make the new API a stable compatibility promise. Ordinary
The current release has substantial rendered-output evidence, including paired
HTML/CSS and component showcases, saved PDFs, styled/unstyled HTML, page-band
checks, typing checks and browser layout checks. The
[alpha 11 release](https://github.com/fullbleed-engine/fullbleed-official/releases/tag/v2.6.0a11)
[alpha 12 release](https://github.com/fullbleed-engine/fullbleed-official/releases/tag/v2.6.0a12)
records the exact package and fixture evidence. Passing those checks establishes
the tested behavior; it does not settle how the API should evolve for its callers.

Three stabilization gates remain:
The namespace and migration gate is qualified in alpha 12. The intended public
path is `fullbleed.components`, with static Bootstrap helpers at
`fullbleed.components.bootstrap`. Earlier imports remain supported. The
[complete migration kit](component-preview-12.md#migrate-a-whole-document)
covers styles, geometry, metadata and renderer configuration, retaining the
same output for both authoring paths. This closes the namespace decision, not
the API's remaining stabilization work.

Two stabilization gates remain:

| Gate | Current position | What closes it |
| --- | --- | --- |
| Public namespace and migration | `fullbleed.ui.Document` is a decorator; the experimental `Document` is a document value with explicit page, theme and renderer ownership. `to_legacy` bridges individual nodes. | Choose and document the supported stable import path, preserve existing imports, and qualify whole-document migration examples covering styles, geometry, metadata and renderer configuration. |
| Components from independent kits | Theme tokens are document-wide. Two kits using `token("accent")` share one value. Missing bindings raise `theme.missing`; explicit kit prefixes allow separate palettes. | Settle and qualify a documented kit-dependency convention with two independently authored kits: defaults, required values, conflicting names and local overrides must be clear without inspecting implementation details. A new scoping mechanism is not automatically required. |
| Authoring and customization feedback | Maintainer-authored fixtures cover the intended edits, but retained independent author feedback is still missing. | Have independent authors rebrand a document, reuse a component, add a table column, change page size and diagnose a layout failure. Record where internal selectors or undocumented knowledge are needed, then resolve those contract gaps. |

Expand All @@ -55,19 +62,24 @@ before a stable release. The earlier
and [design follow-up](https://github.com/fullbleed-engine/fullbleed-official/blob/master/docs/component-authoring-next-iteration.md)
retain their dated findings. This page records the current release decision.

To help with the authoring gate, share a small synthetic document and the edit
that was difficult in the [component RFC](https://github.com/fullbleed-engine/fullbleed-official/discussions/86).
Include the installed package version and whether the task required raw HTML
or inspecting internal selectors.

## What you can rely on now

- Existing `fullbleed.ui` imports remain supported. They are not deprecated by the alpha.
- `class_name` adds a literal class; a matching stylesheet supplies its appearance.
See the [stable styling examples](python-components.md#class-names-and-styles)
or the [alpha styling walkthrough](component-preview-11.md).
or the [alpha styling walkthrough](component-preview-12.md#write-a-component-with-its-own-styles).
- The preview exports styled and unstyled HTML. Bootstrap components are static
in both HTML and PDF; no Bootstrap JavaScript is included.
- Token names are explicit, document-wide dependencies. For current reusable
kits, use concrete defaults or supply the complete documented theme with
distinct prefixes where meanings differ.
- Native PDF pagination and continuous browser HTML are different output
contexts. The [preview's verification scope](component-preview-11.md#verification-and-scope)
contexts. The [preview's verification scope](component-preview-12.md#verification-and-scope)
records the tested cases and limits.

JavaScript and .NET packages have their own versions and API coverage. Their
Expand Down
2 changes: 1 addition & 1 deletion docs/guides/python-components.md
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,7 @@ no browser, virtual DOM, hook lifecycle, or JavaScript runtime involved.
The complete workflow below uses Fullbleed **2.5.25**.

!!! tip "Help shape the next authoring model"
The [component alpha](component-preview-11.md) adds components
The [component alpha](component-preview-12.md) adds components
that carry their styles, named customization parts, column-based tables,
static Bootstrap helpers, and styled or unstyled HTML export. Install it
explicitly to try the next API, or [edit the styling notebook](../getting-started/component-styling.md)
Expand Down
2 changes: 1 addition & 1 deletion mkdocs.yml
Original file line number Diff line number Diff line change
Expand Up @@ -131,7 +131,7 @@ nav:
- Engine architecture: engine/overview.md
- Evaluate:
- Component design preview: guides/component-design-preview.md
- Current component preview: guides/component-preview-11.md
- Current component preview: guides/component-preview-12.md
- Bootstrap component alpha: guides/bootstrap-components-preview.md
- Compare Python PDF libraries: guides/comparison.md
- Three-renderer comparison: guides/renderer-comparison.md
Expand Down
Loading