Skip to content

Changelog

All six milestones, M0 through M6, shipped this month, landing on version 1.0.0-preview.1 with 59 component families in the catalog.

M0 scaffolded the repo: the token and theme engine (v1), NaviusButton, an STA plus FlaUI test harness, and CI. M1 added the shared interaction substrate and the first Tier A wave. M2 brought the overlay wave, 11 families, along with popup input routing. M3 covered selection and fields, 16 families, behind a gate. M4 added the data and dates wave, 14 families. M5 delivered the styled layer and the distribution path, completing the catalog, including Toolbar.

M6 ran an adversarial audit across every family and fixed more than 40 confirmed disparities, each with a regression test. The headliners: Toolbar had shipped as an unbuilt, silently missing control; Rating had dead Space and Enter keys; NumberField’s keyboard handlers were unreachable; two ValuePattern implementations were unreachable; a canceled Closing event could desync IsOpen from the live overlay; and Field descriptions were invisible to assistive technology despite rendering visually.

M6 also landed RTL and DPI hardening (ADR-0006) and a high-contrast theme (ADR-0007) across the catalog.

An external audit surfaced two defects, each fixed with a regression test: a reopen inside an overlay’s 150ms exit fade could be torn down by the previous close’s stale exit-completion callback (NaviusOverlaySurfaceBase now tracks an engage-generation counter, #3), and several triggers (Accordion, Collapsible, Combobox, NavigationMenu) stayed operable through UIA while disabled, now throwing ElementNotEnabledException from their Invoke/ExpandCollapse providers.

A follow-up pass closed the remaining items from issue #2. NaviusTimeInput.Required now participates in IsInvalidState as a ValueMissing signal, matching the fix already applied to NaviusDateInput. ButtonGroupItem and SidebarItem gained automation peers reporting the Button control type with a dispatcher-queued, command-executing Invoke (they previously shipped no peer at all), and NaviusSpinner gained a peer reporting ProgressBar so its “Loading” name reaches UI Automation. The vendorable core registry item now ships Tokens.HighContrast.xaml alongside Light and Dark, previously dropped silently by registry-sync’s hardcoded file list. ADR-0004 also records the registry policy for third-party-engine adapters: Navius.Wpf.Charts ships as an optional package, not vendorable source, and no registry:chart item type will be added (#4).

A third pass revisited the UIA activation contract on the trigger-shaped controls. Accordion and Collapsible’s Invoke now queues activation on the dispatcher, matching the UIA contract’s requirement that Invoke return immediately, while their ExpandCollapse.Expand/Collapse stay synchronous, matching that provider’s own contract; both paths now route through ButtonBase.OnClick instead of a bare RaiseEvent, so a bound Command actually executes from UIA (#9, #10). NaviusBreadcrumbItem gained the Invoke pattern on a non-current crumb, guarded so a disabled item or the terminal current-page entry, including a UIA client’s cached provider, cannot be activated (#7).

Calendar and DatePicker, previously documented only inside date-range-picker.md, got their own standalone parity docs, closing the last unchecked item in issue #2’s coverage rule that every public registry item gets its own parity document (#5).

1,315 tests are green at the pinned commit.

Two externally reported defects, each fixed with regression tests. NaviusSelect’s Value and Values were CLR-only wrappers over the RawValue/RawValues dependency properties (registered under those names), so Value="{Binding ..., Mode=TwoWay}" threw a XamlParseException at XAML load. Real Value/Values dependency properties are now registered once on NaviusSelectBase, kept in sync with RawValue/RawValues (which remain public and bindable) via reentrancy-guarded callbacks in both directions, covering the object-typed NaviusSelect root and every closed NaviusSelect<TItem> (#19). And NaviusCard’s root template dropped the standard Control.Padding, rendering direct content flush against the hairline border; the template’s border now consumes it via TemplateBinding, with the default remaining zero so existing header/content/footer compositions render unchanged (#20).

Button now ships token-backed Default, Secondary, Outline, Ghost, and Destructive variants plus Default, Small, Large, and 36x36 Icon size presets (#22). Drawer adds PanelWidth (360 by default for left/right sheets) and PanelHeight (280 by default for top/bottom sheets), with the cross-axis remaining stretched/automatic (#23).

The full audit then tightened UIA and distribution contracts: disabled DatePicker, DateRangePicker, Select, TimePicker, and Tree providers reject actions with ElementNotEnabledException; Label rewiring clears stale LabeledBy; Carousel/Pagination gained named actions, visible keyboard focus, RTL-aware navigation, and current-dot status; the Gallery follows system High Contrast and its navigation scrolls; CLI vendoring validates paths and the whole closure before writing; Charts declares its runtime System.IO.Ports dependency and follows live theme changes; the test stack no longer pulls vulnerable legacy BCL packages.

Two architectural follow-ups are resolved in the same release. Carousel collapses inactive slides after its fade (immediately under reduced motion), and a FlaUI regression proves inactive actions leave the UIA tree (#24). Navius.Wpf.Motion now has an injectable Windows-backed MotionPolicy used by SpringTicker, SpringKeyframeBaker, and micro-preset reduction (#25, ADR-0008).

1,373 tests are green: 1,290 primitives/UI, 45 Motion, 23 Charts, 8 CLI/vendoring, and 7 FlaUI E2E.

A Navius.Wpf.Ui-only release (the other packages stay at 1.0.0-preview.4) fixing issue #28. NaviusSidebar relied on the default ItemsControl peer, whose children are only item peers for the Items collection, so FooterContent descendants and the built-in collapse button were missing from the UIA tree entirely; a new NaviusSidebarAutomationPeer (a FrameworkElementAutomationPeer reporting Group, class name NaviusSidebar) restores the default visual-tree child walk, and the collapse button carries a state-aware accessible name (“Collapse sidebar” / “Expand sidebar”), since its visible “Collapse” label hides while collapsed and would otherwise leave it nameless.

The same pass made IsCollapsed inheritance real. The property is re-registered via RegisterAttached (with GetIsCollapsed/SetIsCollapsed accessors), because Register-applied Inherits metadata never propagates beyond the owner type, and the item-label and section-header template triggers re-anchored their condition binding from TemplatedParent to Self, since a template-trigger condition anchors on the templated control itself. Before both fixes, the collapse visuals — label and section-header hiding, icon re-centering — never fired.

A second Navius.Wpf.Ui-only release (the other packages stay at their previous versions). The sidebar’s collapse control and footer now align with the item column (community PR #30): the collapse button’s inner template mirrors NaviusSidebarItem’s 3px-gutter / 20px-icon-slot / label-column grid, so the chevron centers with the item icons in both collapse states, and the footer ContentPresenter lost its extra 4px indent, so footer items sit on the main item column (NaviusSidebar_CollapseButton_AlignsWithItemIconSlots).

NaviusButtonGroup.Orientation inheritance is also now real — the same Register-applied Inherits gap just fixed for NaviusSidebar.IsCollapsed, closed the same way: re-registered via RegisterAttached with GetOrientation/SetOrientation accessors (#31). Items previously read the Horizontal default forever, so vertical groups rendered with the horizontal border pattern (doubled hairlines between stacked segments) because the vertical divider trigger, which moves a non-last item’s open border edge from right to bottom, never fired.

1,379 tests were green at this release’s pin.

A Navius.Wpf.Primitives-only release, its first bump since preview.4 (the 1.0.0-preview.5 release above was Navius.Wpf.Ui-only and did not move Primitives).

NaviusInput and the collapsed NaviusSelect trigger now share one 36px collapsed height (community PR #32). Both theme styles set MinHeight 36 and pin FontSize 14, and the vertical content insets now match: the input keeps its 8,6 Padding, the select trigger’s content margin moved from 12,8 to 12,6, and the input template stopped re-applying Padding as a Margin on its PART_ContentHost ScrollViewer (TextBoxBase already honors Padding inside the content host, so the inset was being applied twice). Previously the two field controls diverged in collapsed height when placed on the same row. Covered by FieldTests.InputAndSelect_HaveMatchingCollapsedHeight, which asserts equal desired heights, the 14px style-supplied font on both, and that the trigger fills the select’s full height.

1,380 tests are green: 1,297 primitives/UI, 45 Motion, 23 Charts, 8 CLI/vendoring, and 7 FlaUI E2E.

A Navius.Wpf.Primitives-only release. Tooltip forwards HorizontalContentAlignment and VerticalContentAlignment to its trigger presenter, previously ignored by the template regardless of what a consumer set (#34), covered by a new two-axis stretch layout regression test.

The navius-wpf CLI’s bundled registry snapshot is refreshed to carry the tooltip content-alignment fix (#34), replacing the previously stale vendored Themes/Tooltip.xaml source.

Button-like ControlTemplates across the catalog now forward HorizontalContentAlignment and VerticalContentAlignment from their ContentPresenter instead of hardcoding centered alignment: the Button, Form, Menu, NavigationMenu, PasswordToggleField, Tabs, Toggle, ToggleGroup, and Toolbar themes (#36). The fix branch’s version bump had targeted 1.0.0-preview.6, but the tooltip-alignment wave (#34, released as preview.6 above) had already published that version by the time this PR merged, so the auto-publish workflow correctly skipped the duplicate and these fixes never shipped under preview.6; the release is 1.0.0-preview.7 instead, the first free version (#37).

The same button-like content-alignment fix (#36) applied to Navius.Wpf.Ui’s ButtonGroup and SplitButton themes: NaviusButtonGroupItem, and NaviusSplitButton’s primary segment, a two-hop fix since the internal PART_Primary style’s ContentPresenter hardcoded the same centered alignment and PART_Primary’s own HorizontalContentAlignment/VerticalContentAlignment were never wired from the outer NaviusSplitButton at all.

The navius-wpf CLI’s bundled registry snapshot is refreshed again to carry the button-like ControlTemplate alignment fix (#36): the eleven theme files it touched — Primitives/Themes/{Button,Form,Menu,NavigationMenu,PasswordToggleField,Tabs,Toggle,ToggleGroup,Toolbar}.xaml and Ui/Themes/{ButtonGroup,SplitButton}.xaml — were previously vendored pre-fix by navius-wpf add (#38).

A Navius.Wpf.Primitives-only release carrying three fixes:

  • Checkbox content foreground contrast (community PR #39 by @oshtz). The default checkbox style assigned Navius.PrimaryForeground to the whole control and template-bound the indicator to that same property, so string content inherited the primary-contrast brush intended for the glyph — white-on-light labels in the light theme. Content now styles with Navius.Foreground; the checked and indeterminate glyphs stay on Navius.PrimaryForeground, pinned by a regression test proving the content and indicator resolve separate theme tokens.
  • The identical radio item fix (#40): NaviusRadioGroupItem had the same whole-control Navius.PrimaryForeground assignment, with the same unreadable-label result and the same split — content on Navius.Foreground, indicator dot on Navius.PrimaryForeground.
  • XAML-declared RadioGroup.Value never pre-checked its item (#42). The XAML parser assigns Content before the content’s own children are attached, so the OnContentChanged sync walked an empty logical tree and a Value set as a XAML attribute (the Gallery’s “Pre-selected” markup) was silently lost. The group now re-syncs in OnInitialized, which fires after the whole subtree is built — including under XamlReader.Parse, with no PresentationSource or layout pass required. Pinned by XamlDeclaredValue_PreChecksMatchingItem, which parses the exact Gallery markup shape.

The release pin also carries a test-only hardening (#41): five tests driving WPF’s native keyboard paths read live per-thread Win32 key state and flaked whenever the suite ran on a machine being actively used; they now neutralize the test thread’s key-state table (SetKeyboardState, calling thread only) inside a short bounded retry. 1,316 tests are green at the pin.

The navius-wpf CLI’s bundled registry snapshot is refreshed to carry the preview.8 wave: Primitives/Themes/{Checkbox,RadioGroup}.xaml (#39, #40) and Primitives/Controls/RadioGroup/NaviusRadioGroup.cs (#42) were previously vendored pre-fix by navius-wpf add (#43).

NaviusAlert gained an automation peer and live region so screen readers announce it. A plain ContentControl shipped no peer, so the callout reached UI Automation with no control type and no live-region politeness, leaving a screen reader no signal to announce it. NaviusAlertAutomationPeer now reports the Group control type and maps Variant to a UIA live setting: the informational Default variant announces Polite, and the urgent Warning and Destructive variants announce Assertive (#45).

A companion Navius.Wpf.Motion fix landed in the same audit: SpringTicker.Retarget now re-arms the render loop when it is called after the spring has already settled. Previously, once a run settled and its rendering hook detached, a retarget silently did nothing; it now re-attaches and resumes from the current value (#46).