Skip to content

UIRoot: registerComponents, the tag components to register (3.1.6) - #59

Merged
gmpassos merged 2 commits into
masterfrom
register-components
Oct 18, 2026
Merged

gmpassos merged 2 commits into
masterfrom
register-components

Conversation

@gmpassos

@gmpassos gmpassos commented Oct 18, 2026 •

Copy link
Copy Markdown
Contributor

The first UIRoot registers every component markup can create by tag (<ui-button>, <ui-document>, <ui-dialog>, <ui-svg>...). Whatever is registered is compiled in, so every app ships all of them; <ui-document> alone brings in the markdown package and its HTML-entity tables.

  • New UIRoot(..., registerComponents: ...): the components to register. Without it all of them are, as before (new static UIRoot.registerAllComponents).
  • An app that writes none of those tags passes () {}; one that uses a few passes those (UIDialog.register). Every UIRoot of the app must pass it.
  • UIConsole.get() still runs unconditionally: it sets up logging, it is not a tag component.

Why a nullable parameter, not an overridable method or a default value: dart2js keeps a method that every instantiated subclass overrides, and keeps a default-value tear-off too; checked in a toy program and in the app. It does drop the registerComponents ?? registerAllComponents fallback once inference sees every call site passes one.

Measured in UnyCities (four roots, its only component a dialog created in code): main.dart.js went from 484,964 to 398,322 bytes gzipped, 18% smaller (1,608,618 to 1,335,230 raw). Its 500 browser tests pass on dart2js and dart2wasm.

Tests:

  • bones_ui_root_register_components_test.dart (browser): a root registering only UIDialog has ui-dialog and none of the other built-in tags; the registration runs once, before the first render. In rendered markup, a registered <ui-dialog> becomes its component, an unregistered <ui-document> stays a plain element (its text as written, no <h1>), and a dialog created in code needs no registration.

  • bones_ui_root_register_all_components_test.dart (browser): without registerComponents every tag component is registered, and <ui-document> renders its markdown. A separate file because registration happens once per app.

  • register_components_tree_shaking_test.dart (VM, integration): compiles four minimal apps in test/register_components/ with dart compile js -O2 and checks what is in the output:

    app gzipped markdown ui-document, ui-svg...
    registers all (default) 309,510 in in
    registers none 218,698 out out
    registers UIDialog only 221,439 out only ui-dialog
    one root () {}, one default 309,722 in in

    The last row is the documented caveat: every UIRoot must pass it.

Full suite passes locally: VM (34), Chrome dart2wasm (551) and dart2js (551); format, analyze (--fatal-infos --fatal-warnings) and dependency_validator are clean.

🤖 Generated with Claude Code

….1.6

The first UIRoot registered every component markup can create by tag,
and whatever is registered is compiled in: `<ui-document>` alone brings
in the `markdown` package. An app that writes none of those tags can now
pass `registerComponents: () {}`, or register only those it uses.
Without it all of them are registered, as before.

A nullable parameter, not an overridable method: dart2js keeps a method
every subclass overrides (and a default-value tear-off too), but drops
the `?? registerAllComponents` branch once every call site passes one.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
@codecov

codecov Bot commented Oct 18, 2026 •

Copy link
Copy Markdown

Codecov Report

✅ All modified and coverable lines are covered by tests.
✅ Project coverage is 92.89%. Comparing base (5629f1c) to head (e2d756b).

Additional details and impacted files
@@           Coverage Diff           @@
##           master      #59   +/-   ##
=======================================
  Coverage   92.89%   92.89%           
=======================================
  Files          34       34           
  Lines        9420     9422    +2     
=======================================
+ Hits         8751     8753    +2     
  Misses        669      669           
Flag Coverage Δ
unittests 92.89% <100.00%> (+<0.01%) ⬆️

Flags with carried forward coverage won't be shown. Click here to find out more.

☔ View full report in Codecov by Harness.
📢 Have feedback on the report? Share it here.

🚀 New features to boost your workflow:
  • ❄️ Test Analytics: Detect flaky tests, report on failures, and find test suite problems.

- bones_ui_root_register_components_test.dart: every built-in tag but the
  one registered is absent; the registration runs once, before the first
  render; a registered <ui-dialog> becomes its component, an unregistered
  <ui-document> stays a plain element, a dialog made in code needs none.
- bones_ui_root_register_all_components_test.dart: the default registers
  every tag component, and <ui-document> renders its markdown.
- register_components_tree_shaking_test.dart (VM): compiles four minimal
  apps with dart2js. Registering none drops every component and the
  markdown package (309,510 to 218,698 bytes gzipped); registering UIDialog
  keeps only it; one root without registerComponents keeps them all.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
@gmpassos
gmpassos merged commit ebffa1f into master Oct 18, 2026
5 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant