diff --git a/docs/getting-started/quickstart.md b/docs/getting-started/quickstart.md index 20d981c..9dd7032 100644 --- a/docs/getting-started/quickstart.md +++ b/docs/getting-started/quickstart.md @@ -1,6 +1,6 @@ --- -title: Generate PDFs in Python with components or HTML and CSS -description: Create your first PDF with reusable Python components or HTML/CSS. Copy either complete example, use bundled fonts, and render the same invoice. +title: Generate PDFs in Python with HTML/CSS or components +description: Create your first PDF from HTML/CSS or Python components. Copy either complete example, use bundled fonts, and render the same invoice. --- # Create your first PDF in Python @@ -8,8 +8,8 @@ Prefer to try it before setting up Python? [Open the browser playground](../play to edit HTML/CSS and download a PDF or runnable project. Use the [invoice notebook](notebook.md) to work with Python data in Colab. -Choose **Python components** to compose a document with functions, or -**HTML/CSS** to bring a template. Both examples below use the stable API, embed +Choose **HTML/CSS** to bring a template, or **Python components** to compose +a document with functions. Both examples below use the stable API, embed the bundled Inter font, and write the same one-page invoice. Install Fullbleed in your Python environment. If you need an isolated environment, @@ -23,6 +23,25 @@ python -m pip install fullbleed Choose one tab and save its complete example as `hello.py`. These examples are checked with Fullbleed **2.5.34**. +=== "HTML/CSS" + + ```python + from importlib.resources import files + from pathlib import Path + import fullbleed + + font = files("fullbleed_assets").joinpath("fonts/Inter-Variable.ttf") + engine = fullbleed.PdfEngine(font_files=[str(font)]) + html = '

Invoice INV-1042

Consulting: USD 1,200.00

' + css = """ + @page { size: A4; margin: 20mm; } + body { font-family: Inter; color: #203a36; } + .invoice-title { color: #175c52; } + """ + pdf = engine.render_pdf(html, css) + Path("invoice.pdf").write_bytes(pdf) + ``` + === "Python components" ```python @@ -51,26 +70,7 @@ checked with Fullbleed **2.5.34**. Path("invoice.pdf").write_bytes(invoice.render_pdf(engine)) ``` -=== "HTML/CSS" - - ```python - from importlib.resources import files - from pathlib import Path - import fullbleed - - font = files("fullbleed_assets").joinpath("fonts/Inter-Variable.ttf") - engine = fullbleed.PdfEngine(font_files=[str(font)]) - html = '

Invoice INV-1042

Consulting: USD 1,200.00

' - css = """ - @page { size: A4; margin: 20mm; } - body { font-family: Inter; color: #203a36; } - .invoice-title { color: #175c52; } - """ - pdf = engine.render_pdf(html, css) - Path("invoice.pdf").write_bytes(pdf) - ``` - -`Invoice(...)` receives ordinary Python arguments. `@Document(styles=...)` +In the component example, `Invoice(...)` receives ordinary Python arguments. `@Document(styles=...)` attaches the stylesheet to its result. The heading's `class_name="invoice-title"` matches the `.invoice-title` rule; the HTML/CSS example uses the same class and values. @@ -89,7 +89,8 @@ or the [designed HTML/CSS invoice](../guides/invoices.md). The separate [component alpha](../guides/component-preview-11.md) adds portable component styles, themes, named parts, and styled/unstyled HTML export. It has its own explicit installation instructions; the examples above use the stable -`fullbleed.ui` API. +`fullbleed.ui` API. The [release-status guide](../guides/component-status.md) +explains the distinction and the remaining stabilization work. ## Start with a complete project diff --git a/docs/guides/component-preview-11.md b/docs/guides/component-preview-11.md index a8ae15f..a3d9826 100644 --- a/docs/guides/component-preview-11.md +++ b/docs/guides/component-preview-11.md @@ -24,6 +24,8 @@ authored accessible community guide. Use Python 3.10 or later in a virtual environment. The kit pins `fullbleed==2.6.0a11`; ordinary `pip install fullbleed` selects the stable channel. Components under `fullbleed.ui.experimental` may change. + The alpha is merged into `master`; [merging and stabilization are separate + milestones](component-status.md). The existing `fullbleed.ui` API remains supported. ## Run the complete report diff --git a/docs/guides/component-status.md b/docs/guides/component-status.md new file mode 100644 index 0000000..c4fee72 --- /dev/null +++ b/docs/guides/component-status.md @@ -0,0 +1,75 @@ +--- +title: Python component release status and stabilization +description: Choose the stable Fullbleed Python component API or its opt-in 2.6 alpha. See what is verified and what remains before the new API becomes stable. +--- + +# Python component release status + +Reviewed **20 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` | + +Start with the [Python quickstart](../getting-started/quickstart.md) for either +HTML/CSS or stable components. Both examples produce the same invoice. +The [stable component guide](python-components.md) explains function components, +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. + +For interactive walkthroughs, [Explore the versioned component notebook](../getting-started/component-notebook.md) +or [Try the current styling notebook](../getting-started/component-styling.md). +Each notebook states its own package pin and includes downloadable output. + +## Decision: retain the alpha + +The alpha is **merged into `master` and published on PyPI**. It is not an +unmerged prototype. Merging it makes the implementation available for development; +it does not make the new API a stable compatibility promise. Ordinary +`pip install fullbleed` continues to select the stable channel. + +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) +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: + +| 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. | + +These are bounded API decisions, not a requirement to implement every CSS feature +before a stable release. The earlier +[implementation review](https://github.com/fullbleed-engine/fullbleed-official/blob/master/docs/component-authoring-design.md) +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. + +## 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). +- 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) + records the tested cases and limits. + +JavaScript and .NET packages have their own versions and API coverage. Their +component APIs do not inherit the Python alpha's stability label or imply +cross-language feature parity. diff --git a/docs/index.md b/docs/index.md index 8741eff..ee1340e 100644 --- a/docs/index.md +++ b/docs/index.md @@ -1,20 +1,20 @@ --- -title: PDF components and HTML/CSS for Python, JavaScript, Rust, and C# -description: Build PDFs with Python, JavaScript or C# components and optional JSX, or use HTML/CSS from Python, Rust, Node.js, C#, and browsers. Reusable templates, bundled fonts, and local output. +title: PDF generation for Python, Rust, JavaScript, and C# +description: Generate PDFs from HTML/CSS in Python, Rust, JavaScript, and C#. Build invoices, reports, and print documents with bundled fonts, reusable templates, and local output. hide: - toc ---
-

Components + HTML/CSS to PDF · MIT licensed

+

HTML/CSS to PDF · MIT licensed

# Your data. Your design. Your PDF. -

Compose invoices, reports, and print documents with Python components, JavaScript and JSX, C# components, or existing HTML/CSS templates. One Rust print engine, in your application.

+

Generate invoices, reports, and print documents from HTML/CSS. Keep your templates, fonts, and data in your application, with a deterministic Rust engine handling layout and PDF output.

-[Try PDF components](assets/react-demo/index.html){ .md-button .md-button--primary } -[Choose your language](#choose-your-language){ .md-button } +[Choose your language](#choose-your-language){ .md-button .md-button--primary } +[Try the PDF playground](playground.md){ .md-button } Python, Rust, Node.js, C#, and browser JavaScript. One print engine.
@@ -24,7 +24,7 @@ Python, Rust, Node.js, C#, and browser JavaScript. One print engine.
-

Reusable components   /   Explicit fonts and assets   /   Repeatable output   /   Free for commercial use under MIT

+

HTML/CSS templates   /   Explicit fonts and assets   /   Repeatable output   /   Free for commercial use under MIT

Building a store? [Try the WooCommerce editor in a sample store](guides/woocommerce.md), then [evaluate an automated order workflow](guides/woocommerce.md#evaluate-an-automated-workflow) @@ -32,60 +32,6 @@ for email attachments or customer downloads. -## Compose PDFs with Python components - -Functions, props, children, lists and conditionals—familiar building blocks for -your print documents. Use named elements and Python style mappings to build a -complete invoice without writing HTML strings. -The component workflow below requires Fullbleed 2.5.25 or later. - -```python -from importlib.resources import files -from pathlib import Path -import fullbleed -from fullbleed.ui import Document, Heading, Paragraph, Stack, Strong, component - -@component -def Line(label, amount): - return Paragraph(Strong(label), ": ", amount) - -@Document(title="Invoice", styles={ - "@page": {"size": "A4", "margin": "18mm"}, - "body": {"font_family": "Inter"}, -}) -def Invoice(): - return Stack(Heading("Made for you", level=1), Line("Design", "$120"), gap="12pt") - -font = files("fullbleed_assets").joinpath("fonts/Inter-Variable.ttf") -engine = fullbleed.PdfEngine(font_files=[str(font)]) -Path("component-invoice.pdf").write_bytes(Invoice().render_pdf(engine)) -``` - -[Build with Python components](guides/python-components.md){ .md-button .md-button--primary } -[Download the designed invoice](assets/components/project.zip){ .md-button } - -Prefer JavaScript? [Compose the same kind of document with functions or JSX/TSX](guides/javascript-components.md). -Named components, typed props and reusable styles work with the Node and browser -renderers. [Try the live component invoice](assets/react-demo/index.html) or -[connect it to your React application](guides/react-pdf.md). Ordinary JavaScript functions need no build step or React runtime. - -Using C#? [Compose PDFs with typed methods, LINQ and style objects](guides/csharp-components.md), -or [download the component invoice](assets/dotnet-components/project.zip). - -Want to try the next Python authoring API? The -[component alpha](guides/component-preview-11.md) includes reusable styles, -named component parts, data tables, static Bootstrap helpers and repeating page -bands, with PDF and styled or unstyled HTML output. [Explore the versioned component -notebook](getting-started/component-notebook.md) in Colab or Jupyter, or download -the current source kit from the alpha guide. - -[Try the current styling notebook](getting-started/component-styling.md) to -change theme colors, named parts and `class_name` rules, then compare PDF with -styled and unstyled HTML. - -Building a web application? [Render PDFs in a browser worker](guides/browser-pdf.md) with -editable templates, previews, and downloads. [Try the live starter](assets/browser-demo/index.html). - ## Choose your language Pick your application stack. Generate a PDF locally or download one from the browser app. @@ -292,6 +238,19 @@ Pick your application stack. Generate a PDF locally or download one from the bro [C# and .NET quickstart →](getting-started/dotnet.md) · [Components and styles](guides/csharp-components.md) · [LINQ and variable data](https://github.com/fullbleed-engine/fullbleed-dotnet/tree/v0.2.0/samples/FullBleed.DotNet.LinqVdp) + + +!!! tip "Prefer to author with components?" + Build reusable document functions with [Python components](guides/python-components.md), + [JavaScript and JSX](guides/javascript-components.md), or + [C# components](guides/csharp-components.md). Pass data and children, attach styles, + and render through the same print engine. + + [Try the live component invoice](assets/react-demo/index.html) or + [compare HTML/CSS and component versions of the showcase](guides/showcase-authoring.md). + The existing Python API is stable; its newer authoring API is an opt-in alpha. + [See the release status and remaining stabilization work](guides/component-status.md). + ## Pick a document to build
diff --git a/mkdocs.yml b/mkdocs.yml index 5696113..bb10088 100644 --- a/mkdocs.yml +++ b/mkdocs.yml @@ -1,6 +1,6 @@ site_name: Fullbleed site_url: https://docs.fullbleed.dev/ -site_description: Build PDFs with Python, JavaScript or C# components and optional JSX, or use HTML/CSS from Python, Rust, Node.js, C#, and browsers. MIT licensed. +site_description: Generate PDFs from HTML/CSS in Python, Rust, JavaScript, and C#. Build invoices, reports, and print documents with bundled fonts and local output. MIT licensed. site_author: Fullbleed Engine repo_url: https://github.com/fullbleed-engine/fullbleed-official repo_name: Fullbleed on GitHub @@ -84,6 +84,7 @@ nav: - Examples and downloads: examples.md - Build a document: - Python components: guides/python-components.md + - Component release status: guides/component-status.md - One design, two authoring paths: guides/showcase-authoring.md - Accessible component showcase: guides/accessible-showcase.md - JavaScript components and JSX: guides/javascript-components.md diff --git a/tools/check_component_notebook_ui.py b/tools/check_component_notebook_ui.py index 42d4f7b..5473dd3 100644 --- a/tools/check_component_notebook_ui.py +++ b/tools/check_component_notebook_ui.py @@ -105,7 +105,7 @@ def log_message(self, *a): if "unstyled" in filename: assert page.locator("style, [style], link[rel=stylesheet]").count() == 0 for path, label_text in ( - ("/", "Explore the versioned component notebook"), + ("/guides/component-status/", "Explore the versioned component notebook"), ("/getting-started/notebook/", "Try the component notebook"), ("/guides/bootstrap-components-preview/", "Try the component notebook"), ): diff --git a/tools/check_component_styling_ui.py b/tools/check_component_styling_ui.py index 4da6e92..6c3c83e 100644 --- a/tools/check_component_styling_ui.py +++ b/tools/check_component_styling_ui.py @@ -132,7 +132,7 @@ def log_message(self, *a): page.screenshot(path=str(out / f"{label}-{'styled' if styled else 'unstyled'}-html.png"), animations="disabled", full_page=True) for path, title in ( - ("/", "Try the current styling notebook"), + ("/guides/component-status/", "Try the current styling notebook"), ("/guides/component-preview-11/", "Try the styling notebook"), ("/guides/python-components/", "edit the styling notebook"), ): diff --git a/tools/verify_component_starter.py b/tools/verify_component_starter.py index 50535a9..3731dd9 100644 --- a/tools/verify_component_starter.py +++ b/tools/verify_component_starter.py @@ -46,7 +46,6 @@ def main(): assert rendered["ok"] and rendered["pages"] == 1 and rendered["repeated_pdf_equal"] documentation_examples = [] for page, output, required in [ - ("index.md", "component-invoice.pdf", ["Made for you", "Design", "$120"]), ("guides/python-components.md", "invoice.pdf", ["Maple & Finch", "Design", "Review", "$120.00", "$40.00"]), ]: source = (ROOT / "docs" / page).read_text(encoding="utf-8") diff --git a/tools/verify_quickstarts.py b/tools/verify_quickstarts.py index d77be25..3ac429c 100644 --- a/tools/verify_quickstarts.py +++ b/tools/verify_quickstarts.py @@ -84,16 +84,20 @@ def inspect(path, page_texts=None, embedded_font=False): for page, output, required, embedded_font in FIXTURES: source = (ROOT / "docs" / page).read_text(encoding="utf-8") blocks = re.findall(r"```python\n(.*?)```", source, flags=re.S) - # The first home-page example uses the newer component API. Its own - # Windows/Linux gate runs it with the component starter's pinned release. expected_blocks = 2 if page in ( - "index.md", "engine/assets.md", "getting-started/quickstart.md" + "engine/assets.md", "getting-started/quickstart.md" ) else 1 assert len(blocks) == expected_blocks, (page, len(blocks)) if page == "getting-started/quickstart.md": assert f"Fullbleed **{QUICKSTART_RELEASE}**" in source paired = [] - for authoring, block in zip(("components", "html-css"), blocks): + tabs = re.findall( + r'^=== "(HTML/CSS|Python components)"\n\s*\n ```python\n(.*?) ```', + source, flags=re.M | re.S, + ) + assert len(tabs) == 2 and {label for label, _ in tabs} == {"HTML/CSS", "Python components"} + for label, block in tabs: + authoring = {"HTML/CSS": "html-css", "Python components": "components"}[label] folder = workspace / ("getting-started_quickstart_" + authoring) folder.mkdir() code = dedent(block) @@ -119,7 +123,7 @@ def inspect(path, page_texts=None, embedded_font=False): continue folder = workspace / page.removesuffix(".md").replace("/", "_") folder.mkdir() - code = dedent(blocks[1] if page == "index.md" else blocks[0]) + code = dedent(blocks[0]) # This API snippet returns bytes; retain them without changing its example. retained = code if page == "engine/assets.md": @@ -152,7 +156,7 @@ def inspect(path, page_texts=None, embedded_font=False): assert (folder / "report.py").is_file(), folder result = {"ok": True, "engine": installed, "reference_commit": reference["commit"], - "quickstart_authoring_paths": ["components", "html-css"], + "quickstart_authoring_paths": ["html-css", "components"], "quickstart_pdf_and_previews_identical": True, "platform": sys.platform, "python": sys.version, "snippets": snippets, "capability_snippets": capability_snippets,