Broiler.UI
0.1.0-preview.5
See the version list below for details.
dotnet add package Broiler.UI --version 0.1.0-preview.5
NuGet\Install-Package Broiler.UI -Version 0.1.0-preview.5
<PackageReference Include="Broiler.UI" Version="0.1.0-preview.5" />
<PackageVersion Include="Broiler.UI" Version="0.1.0-preview.5" />
<PackageReference Include="Broiler.UI" />
paket add Broiler.UI --version 0.1.0-preview.5
#r "nuget: Broiler.UI, 0.1.0-preview.5"
#:package Broiler.UI@0.1.0-preview.5
#addin nuget:?package=Broiler.UI&version=0.1.0-preview.5&prerelease
#tool nuget:?package=Broiler.UI&version=0.1.0-preview.5&prerelease
Broiler.UI
Broiler.UI is the platform-neutral retained-mode UI component for Broiler application chrome and general-purpose widgets. It owns the neutral UI root, the shared Standard control infrastructure, and one contract/implementation pair per control type — each in its own assembly, so an application takes only the controls it uses.
Controls draw through the platform-neutral Broiler.Graphics core and take input through
the Broiler.Input abstractions. No UI runtime assembly references a native backend.
Preview release.
0.1.0-preview.1is the first published preview. Public APIs and behaviour are not frozen and may change before1.0. Substantial implementation work was AI-assisted, and human-review approval is revision-scoped — consult HUMAN_REVIEW.md, which is currentlyPENDING, before describing a checkout as approved. See the roadmap for what is still open.
Installation
Preview packages need an explicit prerelease opt-in:
dotnet add package Broiler.UI --prerelease
Broiler.UI is the neutral root: element tree, session, layout, input routing, and host
contracts. It contains no controls. Add the contract package for each control type you
use, plus the matching .Standard implementation:
dotnet add package Broiler.UI.Button.Standard --prerelease
An implementation package depends on its own contract package and on
Broiler.UI.Standard, so a single .Standard reference pulls in everything that control
needs. To take the whole toolkit at once:
dotnet add package Broiler.UI.All --prerelease
Consuming Broiler packages from GitHub Packages
NuGet.config in the repository root pins two sources — nuget.org and the
Broiler-Platform GitHub Packages feed — and clears whatever the machine has configured,
so a restore resolves identically everywhere. Package source mapping sends Broiler.* to
either feed and everything else to nuget.org only.
Broiler dependencies are versioned NuGet references. The more specific Broiler.*
mapping selects GitHub Packages, which requires authentication even for public packages.
Configure credentials below before restoring; CI supplies its built-in token. To use
nuget.org exclusively, use a separate config containing only that source.
To actually pull Broiler.* from GitHub Packages you need a personal access token with
the read:packages scope. Put it in your user-level config, never in the committed
one:
dotnet nuget update source broiler-github --username <github-user> --password <pat> --store-password-in-clear-text --configfile "$APPDATA/NuGet/NuGet.Config"
In GitHub Actions use secrets.GITHUB_TOKEN rather than a personal token.
Packages
60 packages, all net10.0. Every one ships XML documentation and a .snupkg symbol
package, and is built deterministically with SourceLink.
| Package | Role |
|---|---|
Broiler.UI |
Neutral root: element tree, UiSession, layout protocol, input routing, host and accessibility contracts. No controls. |
Broiler.UI.Standard |
Shared Standard-control infrastructure — theme tokens, visual states, painting and service plumbing. Exposes no concrete control. |
Broiler.UI.All |
Meta-package: every contract and its Standard implementation. Dependencies only, no assembly. |
Each control type ships as a contract package and a .Standard implementation
(Broiler.UI.Button and Broiler.UI.Button.Standard, and so on):
| Family | Controls |
|---|---|
| Shell | Window, Dialog, AboutDialog, Tooltip, FileDialog, FontDialog |
| Layout | Panel, ScrollView, Splitter, TabView |
| Content | Label, ImageView, ProgressBar |
| Commands | Button, ToggleButton, Toolbar, Menu |
| Value and selection | CheckBox, RadioButton, Slider, SpinBox, ListView, ComboBox, TreeView |
| Text | Edit, CodeEditor, RichEdit, FormatCodeView |
Broiler.UI.RichEdit.Rtf sits outside the pairing: it is an optional integration that
adds RTF load and save to Broiler.UI.RichEdit through Broiler.Documents.Rtf.
The rich-text and formatting-code packages depend on Broiler.Documents as well as
Broiler.Graphics, so that component has to be on the feed you restore from.
Dependency direction
Broiler.UI.<Control>.Standard -> Broiler.UI.<Control> -> Broiler.UI -> Broiler.Graphics
-> Broiler.UI.Standard -> Broiler.UI -> Broiler.Input[.Keyboard|.Mouse|.Pen|.Text|.Touch]
Broiler.UI references only the platform-neutral Broiler.Graphics core and the neutral
Broiler.Input abstractions. Broiler.UI.Standard holds shared infrastructure only and
exposes no public concrete controls; type-specific controls live in their own .Standard
assemblies. An abstraction never references an implementation.
Graphics boundary
Broiler.UI standard controls draw through the platform-neutral Broiler.Graphics core.
UI runtime assemblies must not reference Broiler.Graphics.Windows, Direct2D, Win32,
WPF, WinForms, COM, HWND, or any other native UI backend. Applications compose the
selected Graphics backend outside Broiler.UI.
This is enforced, not just documented: Broiler.UI.Tests walks every project in src/
and fails the build on a platform-specific reference, a project in the wrong directory,
an implementation reference from an abstraction, or a native handle on a public surface.
Windows, dialogs, and chrome
StandardAboutDialog (in Broiler.UI.AboutDialog.Standard) displays application metadata
and a scrollable list of loaded Broiler component versions. The galleries open it from
Help → About controls. OK or Enter accepts; Escape cancels; the title-bar close button
closes the dialog.
var about = new StandardAboutDialog();
about.ProductName = "My application"; // optional override
await about.ShowModal(mainWindow);
The product name and version default to the entry assembly. Component versions are a
snapshot of loaded Broiler.* assemblies, using informational version (including prerelease
labels), then file version, then assembly version. Build metadata such as commit hashes is
omitted. Unused dependencies are not loaded just to list their versions. For plugins or
other libraries, call PopulateFromAssemblies(productAssembly, componentAssemblies) with
an explicit assembly list, or assign ComponentVersions. Assigning a dictionary copies it;
assign again after changing the source. Calling PopulateFromAssemblies() refreshes the
defaults and replaces manual overrides.
An owned window or a dialog breaks out into its own native top-level window by default — it is a real OS window the user can move onto another monitor and manage from the taskbar (ADR 0025, 0026):
var dialog = new StandardDialog { Title = "Options" };
await dialog.ShowModal(mainWindow); // its own OS window where the host allows it
Break-out needs the optional IUiWindowHost host capability. A host that does not
implement it is unaffected: the window stays a logical subwindow rendered inside its
owner, exactly as before. Per window, BreakOutMode opts back out:
var inspector = new StandardDialog { BreakOutMode = UiWindowBreakOutMode.Manual };
Popups, menus, and tooltips never break out automatically.
Broiler.UI also draws the title bar itself — title, icon, and the minimize, maximize, and close buttons — so a window looks the same wherever it is hosted and a broken-out window never ends up with two stacked title bars:
window.Title = "Broiler";
window.Icon = new UiWindowIcon(iconHandle, iconPixels); // pixels are for the taskbar icon
window.CanMinimize = true;
Who actually draws the frame is resolved per host through UiWindow.Chrome, which
defaults to UiWindowChrome.Auto: owner-drawn for a logical subwindow, and for a
top-level window only when its host reports UiHostWindowChrome.Owner from the optional
IUiWindowChromeHost capability. A host that keeps its platform title bar gets no second
one painted underneath. UiWindowChrome.Owner and UiWindowChrome.None force it either
way.
A host implements IUiWindowChromeHost to suppress its platform frame and let the UI run
the window: it reports the chrome mode and window state, and the framework calls
SetWindowState, SetTitle, SetIcon, BeginMoveDrag, and BeginResizeDrag on it.
Moves and resizes are handed to the window manager rather than simulated, so snapping and
the drag loop stay native. No native handle crosses the boundary.
Broiler.UI.Win32.Demo shows the whole arrangement on Direct2D.
Repository layout
src/Foundation/ Broiler.UI and Broiler.UI.Standard
src/Abstractions/<family>/ one contract assembly per control type
src/Implementations/Standard/ one Standard implementation per contract
src/Integrations/ optional host integrations (RichEdit RTF)
src/Bundles/ the Broiler.UI.All meta-package
src/tests/ xUnit suites, grouped by family
src/samples/ Win32, Linux, WebAssembly, and RichEdit sample hosts
eng/ vendored packaging metadata and package icon
docs/ roadmap and ADRs
.github/workflows/ CI and publish pipelines
Broiler.UI.slnx solution over every project in src/
Cross-component runtime dependencies come from NuGet packages. Project references stay inside Broiler.UI. The browser source demo is separate; see its README for prerequisites.
eng/Broiler.Dependencies.props holds the Broiler dependency version pins, including
separate versions for runtime libraries and sample backends. Projects still declare
their own dependencies. Shared test SDK and xUnit references live in
src/tests/Directory.Build.props.
Building and testing
Clone normally, install the .NET 10 SDK, and configure the package feed credentials:
git clone https://github.com/Broiler-Platform/Broiler.UI.git
The solution defines six configurations. Debug/Release build every packable assembly
and every test suite. The -Windows and -Linux variants add the sample host for that
platform and select the matching runtime identifier; they build the same neutral set
otherwise.
dotnet build Broiler.UI.slnx -c Release
dotnet test Broiler.UI.slnx -c Release
Tests are xUnit suites, so dotnet test discovers them directly. Alongside the
behavioural suites, Broiler.UI.Tests, Broiler.UI.Standard.Tests, and
Broiler.UI.Toolbar.Tests carry the architecture and topology tests that pin the
repository layout and the approved project and package dependencies —
they fail if a directory moves without the rules moving with it.
Samples
dotnet run --project src/samples/Linux/Broiler.UI.Linux.Demo -c Release-Linux -- --window --input --interactive
Broiler.UI.Linux.Demo hosts standard controls through Broiler.Graphics.Linux.OpenGL
and can bridge first-round keyboard/mouse input from evdev when an X11 window has focus.
Windows-only camera and microphone previews stay outside this Linux pass.
Broiler.UI.WebAssembly.Demo has its own solution under src/samples/WebAssembly.
It still consumes the Graphics browser backend and replay module from source and is
excluded from the main package-based solution and CI until those assets ship as a
package. See the browser demo README.
dotnet run --project src/samples/RichEdit.Win32/Broiler.UI.RichEdit.Win32.Demo -c Release-Windows
Broiler.UI.RichEdit.Win32.Demo hosts the rich-text editor on Direct2D and builds under
the -Windows configurations.
dotnet run --project src/samples/Win32/Broiler.UI.Win32.Demo -c Release-Windows
Broiler.UI.Win32.Demo is the control gallery, and the reference host for owner-drawn
window chrome: its main window is frameless, so the title bar, icon, and minimize,
maximize, and close buttons you see are drawn by Broiler.UI, not by Windows. Opening a
dialog from it shows the other half of ADR 0026 — the dialog becomes its own OS window,
with the same single owner-drawn title bar. File > Show logical dialog opens one that
opts out and stays inside the main window.
Packaging
Every Broiler.UI package is a plain net10.0 library. Build, test, then pack and
verify the full set (PowerShell 7):
dotnet build Broiler.UI.slnx -c Release
./eng/run-tests.ps1
./eng/pack.ps1
eng/pack.ps1 checks package identities, versions, internal dependencies, README,
icon, assemblies, XML documentation, and symbol packages. Use an empty output directory;
it rejects stale packages. Tests and samples never pack.
Continuous integration and releases
CI builds and tests Release on a single Ubuntu runner, checks the project graph,
verifies every test suite produced a nonempty TRX report, and attaches test reports.
The same runner packs and verifies all 60 platform-neutral NuGet packages once.
Platform-specific sample configurations remain available for local builds; CI runs
the platform-neutral Release solution. External Broiler dependencies restore using
GITHUB_TOKEN; no submodule initialization is needed.
Publish reuses that CI workflow with one resolved preview version, then downloads its validated packages instead of rebuilding. Before a push, an isolated consumer restore checks that the packages' external dependencies exist on the selected destination feed.
Run Publish manually to choose GitHub Packages or nuget.org; the default is a dry run.
The version resolver uses eng/Broiler.Packaging.props as a version floor, checks all
shipping package IDs on nuget.org (and GitHub Packages when selected), and chooses the
next unused X.Y.Z-preview.N. An optional preview.N suffix or v* tag must be unused,
use the configured release line, and be at least that next preview. Tag pushes publish
to nuget.org. Stable releases are not supported by this preview workflow.
Publish runs are serialized across refs. Only the push job gets package write access;
nuget.org needs the NUGET_API_KEY repository secret. Duplicate versions fail rather
than being silently skipped. External Broiler dependency versions remain the versions
specified in each project; they do not advance with UI's preview number.
Preview status
This is first-preview software, and the warnings recorded in HUMAN_REVIEW.md apply to any published preview:
- The component is preview software and is neither fully optimized nor final.
- Public APIs and behaviour may change while the global refactoring continues.
- Text editing, IME, clipboard, and password/privacy handling have not been reviewed
against an attributable human sign-off;
HUMAN_REVIEW.mdisPENDING. - Accessibility semantics, keyboard-only operation, and screen-reader behaviour have no recorded evidence yet. Do not rely on them for an accessibility conformance claim.
- Rendering and resource ownership under large or adversarial element trees has not been fuzzed or load-tested.
- No dedicated fuzzing campaign, SAST report, dependency scan, or independent security audit is recorded. This is not a production security audit.
Broiler.UI is an independent Broiler component. It is not part of, maintained by, or endorsed by HTML Renderer or Yantra JS.
Documentation
Completed implementation-phase records are not maintained as current documentation.
License
Broiler.UI is licensed under the Apache License 2.0. Third-party material, if present, retains the license identified with that material. The license provides the software on an "AS IS" basis, without warranties or conditions.
| Product | Versions Compatible and additional computed target framework versions. |
|---|---|
| .NET | net10.0 is compatible. net10.0-android was computed. net10.0-browser was computed. net10.0-ios was computed. net10.0-maccatalyst was computed. net10.0-macos was computed. net10.0-tvos was computed. net10.0-windows was computed. |
-
net10.0
- Broiler.Graphics (>= 0.1.0-preview.3)
- Broiler.Input (>= 0.1.0-preview.4)
- Broiler.Input.Keyboard (>= 0.1.0-preview.4)
- Broiler.Input.Mouse (>= 0.1.0-preview.4)
- Broiler.Input.Pen (>= 0.1.0-preview.4)
- Broiler.Input.Text (>= 0.1.0-preview.4)
- Broiler.Input.Touch (>= 0.1.0-preview.4)
NuGet packages (28)
Showing the top 5 NuGet packages that depend on Broiler.UI:
| Package | Downloads |
|---|---|
|
Broiler.UI.Standard
Shared platform-neutral retained-mode UI infrastructure for Broiler standard controls. |
|
|
Broiler.UI.Button
Platform-neutral Broiler button abstraction. |
|
|
Broiler.UI.Window
Platform-neutral Broiler logical window abstraction. |
|
|
Broiler.UI.ListView
Platform-neutral Broiler list view abstraction. |
|
|
Broiler.UI.Edit
Platform-neutral Broiler edit abstraction. |
GitHub repositories
This package is not used by any popular GitHub repositories.
| Version | Downloads | Last Updated |
|---|---|---|
| 0.1.0-preview.20 | 0 | 10/11/2026 |
| 0.1.0-preview.19 | 621 | 10/7/2026 |
| 0.1.0-preview.18 | 702 | 10/5/2026 |
| 0.1.0-preview.17 | 610 | 10/3/2026 |
| 0.1.0-preview.16 | 314 | 10/3/2026 |
| 0.1.0-preview.15 | 308 | 10/2/2026 |
| 0.1.0-preview.14 | 314 | 10/2/2026 |
| 0.1.0-preview.13 | 303 | 10/2/2026 |
| 0.1.0-preview.12 | 493 | 10/2/2026 |
| 0.1.0-preview.11 | 369 | 10/1/2026 |
| 0.1.0-preview.10 | 444 | 9/28/2026 |
| 0.1.0-preview.9 | 511 | 9/24/2026 |
| 0.1.0-preview.8 | 422 | 9/23/2026 |
| 0.1.0-preview.7 | 383 | 9/22/2026 |
| 0.1.0-preview.6 | 538 | 9/22/2026 |
| 0.1.0-preview.5 | 283 | 9/22/2026 |
Initial preview release of Broiler.UI (0.1.0-preview.1): platform-neutral retained-mode UI component for Broiler application chrome and widgets, standard control implementations, RichEdit, and Formatting Codes view.