Skip to content

Replace AtomUI with TKCode.Arc.Foundation (MIT-only dependency chain) - #27

Merged
239573049 merged 6 commits into
mainfrom
feat/replace-atomui
Oct 29, 2026
Merged

239573049 merged 6 commits into
mainfrom
feat/replace-atomui

Conversation

@239573049

Copy link
Copy Markdown
Member

Closes #25.

Every TKCode.Arc package now depends only on Avalonia and the new MIT package TKCode.Arc.Foundation. AtomUI (LGPL-3.0) no longer appears anywhere in the dependency tree, so closed-source Native AOT single-file apps are no longer constrained by it.

What changed

  • TKCode.Arc.Foundation (new): token declarations plus a source generator, theme runtime (ArcThemeManager, ArcThemeState, scoped themes, presets), lazy control-theme loading, package registration (AppBuilder.UseArc), localization (xlf catalogs, live switching, coverage checks), build-time diagnostics ARCF001–027. Written clean-room from Avalonia's public API.
  • Switch-over: token classes and XAML token references are unchanged; tools/dev/migrate_atomui.py does the mechanical part (usings, x:Class on theme files, project files).
  • Replaced AtomUI pieces: ArcPopup on Avalonia's Popup; ArcImage / TKCode.Arc.ImageSource instead of AsyncImage; ArcOverlayHost; palette generator following @ant-design/colors; ArcBaseTheme for the Avalonia built-ins AtomUI used to style (ScrollViewer/ScrollBar hidden until hover, ItemsControl, PathIcon, TextSelectionHandle, popup hosts, EmbeddableControlRoot, Window), giving way to Fluent/Simple.
  • Gallery: the desktop window draws its own title bar again.
  • Fixes found on the way: toast stack re-entrancy, DataGrid filter / EventLog search boxes without a template, browser root missing its base theme, first ThemeSwitcher reveal in a plain Window, MarkdownHost outline race, pool-thread posts now use the owning control's dispatcher.
  • Docs: guides in three languages, README, AGENTS.md, llms files, and a 0.3 → 0.4 migration guide in the changelog.

Breaking changes (0.4.0)

  • Startup: UseAtomUI(b => b.UseDesktopControls().UseArc()) + partial App → UseArc(arc => arc.UseArcControls()).
  • Themes: ThemeConfigBuilder / IThemeManager → ArcTheme.Apply(t => …) / ArcThemeManager; corners and Pixel are presets (t.Corners(style), t.Pixel()).
  • Localization: AtomUI.Localization → TKCode.Arc.Localization.
  • Images: ImageSource is TKCode.Arc.ImageSource; IsLoaded → IsImageLoaded.
  • Mobile token identities: MobileButton, MobileCheckbox, MobileDialog, MobileSwitch, MobileToast.
  • Mixing with AtomUI controls (shared theme) is no longer supported.

The full old → new table is in the changelog's migration section.

Verification

  • dotnet build TKCode.Arc.slnx: 0 errors, no new warnings.
  • Foundation 66, BaseTheme 27, Core 183, Mobile 108: all pass.
  • Arc tests: 7,993 run, only the 7 pre-existing failures (CornerStyle ×3, UsageForecast off-motion, GalleryBrowserFont, GalleryDocs standard sections, GalleryLlms copied page).
  • Token values: 30 theme variants recorded under AtomUI before the switch, 0 differences after.
  • 256 screenshot pairs against main (light/dark, corner styles, zh-CN/zh-TW): no layout, corner, clipping or text differences; the CodeBlock scroll bar is now hidden at rest (intended).
  • dotnet list package --include-transitive: no AtomUI.
  • Browser (trimmed), desktop Native AOT and single-file publishes succeed and start.

Before release (not in this PR)

  • Check the gallery title bar on real Windows and macOS.
  • Compare gallery cold start and theme-switch frame times with 0.3.
  • Bump to 0.4.0-preview.1 (versions, install lines, changelog date) and publish.

🤖 Generated with Claude Code

239573049 and others added 3 commits October 28, 2026 19:14
…ns, themes and localization

TKCode.Arc.Foundation depends only on Avalonia and provides what Arc took
from AtomUI: token declarations and their source generator (token kinds,
markup extensions, reflection-free writers and override parsers), the theme
runtime (ArcThemeManager, ArcThemeState, scoped themes, presets), lazy
control-theme loading, package registration (AppBuilder.UseArc), and
localization (xlf catalogs, live language switching, coverage checks).
Diagnostics ARCF001-027 report token, theme and translation errors at build
time. NativeAOT and trimming safe; tools/dev/FoundationAotSample checks it.

Written clean-room from Avalonia's public API and Arc's own design docs.

Refs #25

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Every TKCode.Arc package now depends only on Avalonia and the MIT
TKCode.Arc.Foundation; AtomUI (LGPL-3.0) is gone from the dependency tree,
so closed-source NativeAOT single-file apps are no longer constrained by it.

Switch-over (tools/dev/migrate_atomui.py does the mechanical part):
- Token classes and XAML token references are unchanged; theme files get a
  flat x:Class; packages register through ArcBuilder extensions.
- Startup is AppBuilder.UseArc(arc => arc.UseArcControls()...); themes are
  applied with ArcTheme.Apply / ArcThemeManager; Pixel and Corners are presets.
- Localization moves to TKCode.Arc.Localization with the same catalogs.
- Mobile token identities become MobileButton, MobileCheckbox, MobileDialog,
  MobileSwitch and MobileToast.

Replaced AtomUI pieces:
- ArcPopup derives from Avalonia's Popup (ArcPopupFrame, ArcPopupMotion).
- ArcImage and TKCode.Arc.ImageSource replace AsyncImage (IsImageLoaded).
- ArcOverlayHost replaces the scoped overlay layer.
- The palette generator follows @ant-design/colors (MIT).
- ArcBaseTheme supplies ScrollViewer/ScrollBar (hidden until hover, like
  ScrollArea), ItemsControl, PathIcon, TextSelectionHandle, popup hosts,
  EmbeddableControlRoot and Window; it gives way to Fluent and Simple.

Also:
- The gallery desktop window draws its own title bar again.
- Fixes: toast stack re-entrancy while pausing, the DataGrid filter and
  EventLog search boxes had no template, the browser root missed its base
  theme, the first ThemeSwitcher reveal in a plain Window, MarkdownHost's
  outline before the template, and pool-thread posts now go to the owning
  control's dispatcher.
- Tests: token values are checked against a baseline recorded under AtomUI
  (30 variants, no differences); test isolation fixes for GC tests.

BREAKING CHANGE: startup, theme and localization APIs changed; see the
0.3 to 0.4 migration guide in the changelog.

Refs #25

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

Guides (installation, theming, introduction, motion, AI and MCP, changelog)
in all three languages, component pages, README, AGENTS.md, third-party
notices and the llms files now use UseArc / ArcTheme and describe the MIT
dependency chain. The changelog gains a 0.4.0-preview.1 (unreleased) section
with the migration guide; API translations follow the changed summaries.

Refs #25

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
239573049 and others added 3 commits October 28, 2026 23:09
Avalonia's OverlayPopupHost and the LayoutTransformControl in its template
clip by default, and the host is exactly as large as the surface, so the
shadow ArcPopup paints past it was cut to a rectangle and menus, selects and
popovers showed square corners. The base theme turns clipping off on both.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
The inbox now has its title and a live "left to triage" count, an avatar on
every row, Arc's type sizes, two unread messages, and the hint line; Undo and
Reset appear only after a row is removed.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
…text only when needed

- Button: the spinner is created the first time IsLoading turns true instead of
  with every template, so most buttons carry one element less.
- SelectValueRoll: the unconstrained text layout is cached and reused for the
  arranged layout when the text fits, instead of being built twice per pass.
- FieldMessage: an empty message no longer shapes the space and the digits;
  they are measured when a segment needs them.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
@239573049
239573049 merged commit dcc8880 into main Oct 29, 2026
5 of 7 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

1 participant