Skip to content

feat: P3 navigation & layout, theme tokens, overlay portal, and 25 new components - #3

Merged
Shewart merged 20 commits into
mainfrom
feat/p3-navigation-layout
Oct 4, 2026
Merged

Shewart merged 20 commits into
mainfrom
feat/p3-navigation-layout

Conversation

@Shewart

@Shewart Shewart commented Oct 4, 2026

Copy link
Copy Markdown
Contributor

Summary

Started as Phase 1c (P3 navigation/layout) and grew into the full component polish pass:
every MAUI component now draws from theme tokens, overlays float in a page-level layer, and
the form controls that leaned on native chrome are custom-drawn so they look the same on
every platform.

What's in here

New components

  • Navigation & layout (P3): collapsible, accordion, tabs, breadcrumb, skeleton, scroll-area
  • Overlays & feedback: alert-dialog, toast (Toaster + Toast.Show/Success/Error/...),
    tooltip, hover-card, callout, spinner
  • Forms: calendar, combobox, toggle, input-otp
  • Data display: avatar, pagination, empty-state
  • Utility: icon (110 Lucide icons from the ShellIcons catalog, drawn as MAUI paths — no
    font or package), theme-toggle

Theme tokens

  • ShellTheme publishes light and dark palettes as app resources (ShellUI<Token> /
    ShellUI<Token>Brush), mirroring ShellUI's CSS variables. Components bind with
    .Token(property, ShellToken.X); switching theme repaints everything.
  • No hex colors in components — enforced by a test.

Overlay portal

  • ShellPortal keeps one layer above each page. Dialog, drawer, sheet, alert dialog,
    dropdown, popover, select, combobox, date/time pickers, tooltip, hover card and toasts all
    float in it, so they are never clipped by a ScrollView and can be declared next to their
    trigger.
  • Popups flip and clamp to the safe area; click-outside dismisses.
  • ShellDismiss: Escape (Windows) and the Android back button close the overlay on top.

Custom-drawn form controls

  • Select, DatePicker (trigger + Calendar) and TimePicker (hour / minute / AM-PM columns) no
    longer use the native pickers.
  • Input / Textarea: the platform control's own frame, underline and padding are stripped, so
    there is one border at a consistent 40px.

Android

  • Fixed input underlines, Select list size and placement, stock dark BoxView background,
    square progress corners.
  • Page layer is set up as the page appears, so opening the first overlay no longer resets the
    scroll position.
  • Overlays are edge-to-edge with their content kept inside the safe area.
  • Hover Card opens on tap on touch devices.
  • Opt-in ShellTheme.SyncSystemBars (transparent bars, status strip drawn by the page layer,
    bar icons follow the theme).

Tooling

  • scripts/generate-icons.py — builds the icon component from the ShellIcons catalog.
  • scripts/sync-templates.py — regenerates CLI templates and dependencies from the demo's
    component sources (components are developed as real C# in examples/MAUI.Demo).

Other

  • .NET 10 MAUI fixes (nullable Date / Time, obsolete FadeTo).
  • Docs: COMPONENTS.md, COMPONENTS_ROADMAP.md, DEVELOPMENT_PLAN.md updated throughout.

Testing

  • dotnet build ShellUI.Native.slnx — 0 warnings, 0 errors (Windows and Android targets)
  • dotnet test — 408 passed
  • Windows: every component clicked through in the demo, light and dark.
  • Android (Pixel 7 / API 34 emulator, light mode): inputs, select, date picker, calendar,
    progress, dialog, drawer, sheet, dropdown, popover, alert dialog, toast, collapsible,
    accordion, tabs, hover card, input OTP.

Shewart and others added 20 commits August 29, 2026 21:57
First P3 primitive per Phase 1c build order. Establishes the IsOpen/animation
pattern that accordion-item and tabs will build on:

- Collapsible : VerticalStackLayout — holds Open state, exposes SetOpen /
  Toggle, raises OpenChanged for content sync
- CollapsibleTrigger : ContentView — tap toggles the parent. MinimumHeightRequest
  = 40 per the Form Sizing Contract (row-level control).
- CollapsibleContent : ContentView — subscribes to parent OpenChanged, fades
  over 150ms + toggles IsVisible. Chose fade + visibility over height animation
  because MAUI's height animation needs measured child height and is unreliable
  across Windows/Android/iOS; fade + IsVisible is not.

No new tokens introduced. Tests auto-picked up the 3 new components: 199 → 211.

Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
…lies

Completes the Phase 1c P3 tier (11 new components) after collapsible:

- accordion + accordion-item + accordion-trigger + accordion-content
  Single (radio-style) or Multiple type. Accordion holds the open-value set;
  items derive their IsOpen from it and raise their own OpenChanged so triggers
  and content don't need to know about the Accordion above them. Fade+visibility
  animation matches Collapsible.

- tabs + tabs-list + tabs-trigger + tabs-content
  Tabs.Value tracks the active id. Trigger tap sets it; triggers observe
  ValueChanged and switch between the Primary (#2563EB, bold, underline) and
  Muted foreground (#6B7280) states. Content just toggles IsVisible on
  Value match — no fade to avoid trailing animations on rapid tab switches.
  MinimumHeightRequest = 40 per Form Sizing Contract (row-level trigger).

- breadcrumb + breadcrumb-item
  Each item owns its own trailing separator; parent tells the last item to
  hide it via SetSeparatorVisible. Keeps OnChildAdded free of mutating the
  child list. IsCurrent renders bold with foreground color and suppresses tap.

- skeleton
  Pulses Opacity 1.0 <-> 0.5 on a 1200ms sin loop. Restarts on reparenting so
  it survives navigation. CornerRadius bindable, defaults 4.

- scroll-area
  Thin ScrollView subclass. Deliberately minimal at v1 per the roadmap note —
  a named hook for future scrollbar styling / fade-edge, no visual overhead yet.

Tests auto-picked up all 11 new components: 211 -> 259.
No new tokens introduced; every color reuses Primary (#2563EB), Foreground
(#1F2937), Muted foreground (#6B7280), Border/Placeholder (#E5E7EB, #9CA3AF).

Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
Copies the 15 new P3 templates into examples/MAUI.Demo/Components/UI/
(YourProjectNamespace -> MAUI.Demo) and adds demo sections to MainPage.xaml
covering every family:

- Collapsible with a Button trigger + Card content
- Accordion (Single mode) with three items separated by ui:Separator
- Tabs with three panels (overview / details / activity)
- Breadcrumb: Home > Library > Data > Current Page (IsCurrent on last)
- Skeleton: four blocks of varying size + CornerRadius=8 on one
- ScrollArea: 10-line vertical scroll at HeightRequest=140

Wires OnBreadcrumbClicked handler in MainPage.xaml.cs. Fulfills Phase 1c
exit criterion #3 (every new component has a demo section).

Also updates docs/COMPONENTS.md:
- Skeleton section replaces the "planned" placeholder
- New "Navigation Components" section with usage snippets for Tabs, Accordion,
  Collapsible, Breadcrumb, ScrollArea (Collapsible sits here alongside its
  composite parent Accordion for discoverability)
- Auto-install table extended with the 5 new parent -> family mappings
- Component Categories updated: adds Navigation category, moves Skeleton
  under Feedback, moves Collapsible/Accordion/ScrollArea into Layout

Records the installs in examples/MAUI.Demo/shellui-native.json so `shellui-native
list` in the demo reflects reality.

Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
…Border on native pickers

Two live-testing bugs surfaced on Windows 2026-08-30:

1. Dialog / Drawer / Sheet rendered as giant empty inline boxes.
   Root cause: they subclass AbsoluteLayout with an overlay layer set to
   proportional-fill (0,0,1,1). Inside a VerticalStackLayout the parent
   sizes to children while the overlay layer fills the parent — circular
   sizing → huge white box.

   Short-term fix (this commit): restructure MAUI.Demo/MainPage.xaml so
   Dialog / Drawer / Sheet live at page root as siblings of the ScrollView
   inside a wrapping Grid. Only Open* trigger buttons stay inline.

   Proper architectural fix (Phase 1d, feat/p4-overlay-portal): rewrite
   these as ContentView + page-root portal so they drop in anywhere.
   Documented in DEVELOPMENT_PLAN.md.

2. Select / DatePicker / TimePicker: inner border overflowed the outer.
   Root cause: wrapping MAUI's native Picker / DatePicker / TimePicker
   in our own 40px Border. Native control draws its own chrome that
   ignores the outer size — most visible on Windows (WinUI ComboBox /
   CalendarDatePicker / TimePicker).

   Fix (this commit): drop the outer Border on all three templates.
   Set HeightRequest=40 on the native control directly. Regenerated
   demo copies. Loses shadcn ring / rounded corners in exchange for
   correct rendering.

   Proper fix (also Phase 1d): rewrite as Popover-based custom controls
   with our own styling — matches shadcn/nativewind quality.

Form Sizing Contract updated in COMPONENTS_ROADMAP.md; Phase 1d scoped
in DEVELOPMENT_PLAN.md. Tests still 259/259 green.

Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
Live-testing surfaced three CS0266 errors in the demo build that had been
latent in the templates all along — Templates project ships C# as strings,
so it never compiled against a real MAUI reference.

.NET 10 MAUI breaking changes:
- DatePicker.Date is now DateTime? (was DateTime)
- DateChangedEventArgs.NewDate / OldDate are now DateTime? (were DateTime)
- TimePicker.Time is now TimeSpan? (was TimeSpan)

Plus a pre-existing type mismatch that finally surfaced:
- Picker.ItemsSource is System.Collections.IList (non-generic).
  Our IList<string> parameter type doesn't implement it, though most concrete
  IList<string> impls (List<T>, ObservableCollection<T>) do implement IList.

Fixes:
- DatePicker: null-coalesce e.NewDate / e.OldDate against current Date;
  GetValueOrDefault() on the reverse-direction comparison
- TimePicker: same pattern for _picker.Time
- Select: try IList cast first, fall back to `new List<string>(list)` so
  arrays / IReadOnlyList / raw IList<T> callers still work

Regenerated the three demo copies. Tests still 259/259 green.

Note: the fourth build error the user surfaced (Spectre.Console 0.49.1
missing) was the same NuGet-scratch corruption we hit earlier; resolved
by re-restoring the CLI project. Not a code change.

Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
- Accordion/Collapsible content: FadeTo -> FadeToAsync (.NET 10 MAUI
  obsoleted FadeTo; matches Switch's existing TranslateToAsync usage).
  Full slnx build now 0 warnings / 0 errors.
- COMPONENTS.md: drop stale "Tabs (Coming Soon)" section that
  contradicted the real Tabs docs above it.
- DEVELOPMENT_PLAN.md: tick Phase 1c deliverables, mark in review,
  note the demo-blocking fix-forwards that landed on this branch.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
ShellUI.Native.slnx is the canonical solution file; Visual Studio
generated a legacy .sln next to it.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
The demo froze (no scroll, no clicks) after d5b23aa moved the overlays to
page root. Each overlay host is a layout that fills its area; placed after
the ScrollView in the page-root Grid, the three hosts sat on top of all
content, and a MAUI layout on Windows hit-tests even when visually empty.

Host is now InputTransparent while closed (CascadeInputTransparent = false
so an inline trigger stays clickable) and hit-testable while open so the
backdrop catches taps. Applied to templates and demo copies.

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

- Updated AccordionContent to improve visibility and animation handling.
- Refactored AccordionItem to manage open states and child components more effectively.
- Enhanced AccordionTrigger with new properties for better customization.
- Introduced new AlertDialog and Avatar components for improved user interaction.
- Updated Badge and Breadcrumb components to include necessary dependencies and visual improvements.

This commit focuses on refining the Accordion family of components, ensuring better performance and usability, while also adding new components to the library.
…log, toast, spinner, and avatar

- Introduced new components to the ComponentRegistry, enhancing the library's offerings.
- Updated StyleTemplates to reflect changes in theme colors and resource dictionary structure for better design consistency.
- Improved theme resource management for both light and dark modes, ensuring alignment with ShellTheme specifications.

This commit expands the component library and refines theming capabilities, improving overall user experience and design coherence.
…tokens and component specifications

- Revised COMPONENTS_ROADMAP.md to reflect the latest updates on theme tokens, icons, and component polish as of 2026-09-27.
- Enhanced COMPONENTS.md with detailed theming instructions, including the use of theme tokens for color management across components.
- Updated component specifications for Button, Input, Select, DatePicker, and TimePicker to align with new design standards and ensure consistency in height and padding.
- Introduced guidelines for new form controls and menu/list rows to maintain uniformity in design and usability.

This commit improves documentation clarity and aligns component design with the latest theming strategies.
…mproved usability

- Updated Accordion to support both single and multiple item selections with a new Value property.
- Improved AccordionItem to manage open states and child components more effectively, including visual updates for open/closed states.
- Enhanced AccordionTrigger with customizable text and body content, including hover effects.
- Refactored AccordionContent to handle visibility and animations more efficiently.
- Introduced new AlertDialog and Avatar components for better user interaction.
- Updated Badge and Breadcrumb components for improved visual consistency and functionality.

This commit focuses on refining the Accordion family of components, enhancing user experience and interaction while adding new components to the library.
…mproved design consistency

- Revised color tokens for ShellUI theme, enhancing the overall visual design.
- Updated background, foreground, primary, secondary, and accent colors to align with the latest design standards.
- Introduced new color tokens for success, warning, and info states to improve component feedback.
- Streamlined resource dictionary structure for better maintainability and clarity.

This commit focuses on refining the ShellUI theme to ensure a cohesive and modern user interface.
- Added ShellUI theme initialization in App.xaml.cs to ensure proper theming.
- Updated MainPage.xaml to include new styles for labels and set background color.
- Expanded CountrySelect options to include Japan.
- Improved button click handling and reporting for better user feedback.
- Introduced new methods for handling various UI interactions, including alerts and toasts.

This commit enhances the user experience by refining the MainPage layout and functionality, ensuring a more cohesive and interactive demo application.
- Introduced `StyleTemplatesTests` to validate the well-formedness of theme resource dictionaries in XAML.
- Added tests to ensure all shell tokens are defined in the theme dictionaries, preventing missing tokens in XAML.
- Enhanced `TemplateContentTests` to verify that MAUI components utilize theme tokens instead of hardcoded colors.

This commit improves test coverage for theme-related components, ensuring proper XML structure and adherence to theming standards.
- Introduced `generate-icons.py` to create the MAUI `icon` component from the ShellIcons catalog, converting SVG shapes to absolute-coordinate path strings.
- Added `sync-templates.py` to synchronize MAUI templates from demo components, ensuring proper namespace handling and dependency management.
- The new scripts streamline the process of maintaining icon components and their associated templates, enhancing the development workflow.

This commit enhances the tooling for icon management in the MAUI project, facilitating easier updates and consistency across components.
…new components

Overlays
- ShellPortal: one layer above each page, set up as the page appears. Dialogs,
  drawers, sheets, menus, selects, tooltips, hover cards and toasts float in it,
  so they are never clipped by a ScrollView and can be declared anywhere.
- Anchored popups flip and clamp to the safe area; click-outside dismisses.
- Layer is edge-to-edge: backdrops cover the window, panels pad their own
  content with ShellPortal.GetSafeInsets.

Android
- Strip the native underline and padding from text fields.
- Size and place the Select list from real layout.
- BoxViews no longer pick up the stock dark background.
- Opt-in ShellTheme.SyncSystemBars: transparent bars with a status strip drawn
  by the page layer, bar icons follow the theme.
- Hover Card opens on tap on touch devices.

New components: tooltip, hover-card, calendar (custom DatePicker now uses it),
toggle, input-otp, pagination, empty-state. Registered in ComponentRegistry and
generated by scripts/sync-templates.py; registry test guards against dependency
cycles.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Adds Toggle, Input OTP, Pagination, Empty State, Tooltip, Hover Card and
Calendar sections, enables ShellTheme.SyncSystemBars, uses neutral Android
theme colors, and sizes the demo Card to the screen on phones.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
…e/back to close overlays

- callout: Info / Warning / Danger / Tip / Default note on a tinted background.
- combobox: Select with a filter field; Enter picks the first match.
- time-picker: custom trigger with floating hour / minute / AM-PM columns
  (MinuteStep, Is24Hour, Format); the native picker is gone.
- ShellDismiss: tracks open overlays and popups; Escape on Windows and the
  Android back button close the one on top (Alert Dialog treats it as Cancel).
- icon: add lightbulb.
- Demo sections and docs for the above.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
@github-actions github-actions Bot added documentation Improvements or additions to documentation templates examples labels Oct 4, 2026
@Shewart
Shewart merged commit 221224b into main Oct 4, 2026
4 checks passed
@Shewart
Shewart deleted the feat/p3-navigation-layout branch October 6, 2026 17:53
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

documentation Improvements or additions to documentation examples templates

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant