Readiness map for aligning the draft Blazor home page on branch feature/aa/Blazor-Widget-Page
(scaffolded before the design landed) with this component library + domain controls.
Documentation only — the branch is not modified here.
SingleButtonLarge is a content card, not a buttonIn Components/Widget.razor the SingleButtonLarge case renders a MudCard with an image banner (160px) + title + blurb — a content card, used for the "Hotel Request" item. The real buttons (SingleButton1, EmergencyButton) render MudButton. So despite the name, it maps to our Card / CardHero (the Document Hero domain control), not Button. Rename it during alignment (e.g. FeatureCard / HeroCard).
The draft is a dynamic-widget system: a flat WidgetDto (with a string Type) is fed by IWidgetApiService and rendered by a single Widget.razor that switches on WidgetType. That is compatible with this architecture once reframed:
WidgetDto is the raw API representation. Mapping each one to the right scaffold ViewModel is exactly the RawRepresentationFactory<T> + domain-control pattern (D11).DynamicWidgets.razor / Widget.razor become the feed renderer over scaffold components + domain controls — not one mega-switch.WidgetType names just need to reconcile to our universal taxonomy.From Components/WidgetType.cs + the render cases in Components/Widget.razor:
Blazor WidgetType | Renders (Blazor) | Our scaffold | Domain control | Alignment note |
|---|---|---|---|---|
PilotCard | MudCard: title + link | Card (Chevron) | Pilot Card | ✓ aligned — name matches |
SingleButton1 | MudButton (icon + cta) | Button | — | icon button → Button |
SingleButton2 | MudCard tile: icon + cta | Button (icon tile) | — | tappable tile → Button (Icon variant) |
SingleButtonLarge | MudCard: image 160 + title + blurb | CardHero | Document Hero | ⚠ RECLASSIFY — a content card, not a button (see callout) |
ThreeUpButton | MudPaper: 3× icon + label | Button Group | — | 3-up → Button Group |
SliderImages | slider of media + eyebrow + title + blurb cards | Carousel | Home Feed Carousel | with-images variant |
SliderNoImages | slider, no media | Carousel | Home Feed Carousel | no-images variant |
SliderNoImagesEyebrows | slider, no media + eyebrows | Carousel | Home Feed Carousel | no-images + eyebrow variant |
EmergencyButton | MudButton (emergency) | Button | Emergency Hotline | tel: action → Button |
Net: 3 of the 9 WidgetTypes are Buttons (SingleButton1/2, EmergencyButton), 3 are a Carousel (the Slider* trio = Carousel variants), 1 is a Button Group (ThreeUpButton), 1 is a Card (PilotCard), and 1 is a content card mislabeled as a button (SingleButtonLarge).
WidgetDto → RawRepresentationFactoryWidgetDto has been renamed to ItemDto and WidgetComponentFactory to ItemComponentFactory. The Type discriminator is now ItemType and the Background field is now BackgroundToken. This section describes the pre-rename codebase structure being refactored. See D39.
ApiModels/WidgetDto.cs is a flat catch-all (a string Type + every possible field: Title/Blurb/Cta/Icon/ThreeUpButtons/Slider*). Under D11 that DTO is the raw representation; a factory keyed on Type projects it onto the right typed scaffold ViewModel:
// WidgetDto (raw) -> scaffold ViewModel, dispatched by Type
public sealed class WidgetFactory : RawRepresentationFactory<ComponentViewModel>
{
public ComponentViewModel Create(WidgetDto w) => w.Type switch
{
"PilotCard" => pilotCardFactory.Create(...), // CardViewModel
"SingleButtonLarge" => documentHeroFactory.Create(w), // CardHeroViewModel (content card)
"SingleButton1" or "SingleButton2" or "EmergencyButton"
=> buttonFactory.Create(w), // ButtonViewModel
"ThreeUpButton" => buttonGroupFactory.Create(w.ThreeUpButtons), // ButtonGroupViewModel
"SliderImages" or "SliderNoImages" or "SliderNoImagesEyebrows"
=> feedCarouselFactory.Create(w.SliderItems), // CarouselViewModel
_ => throw new NotSupportedException(w.Type),
};
}
Field reconciliation for the reclassified card: SingleButtonLarge → CardHeroViewModel with Title → Title, Blurb → Description, Icon → Image. Keyed services (.NET 8+) can resolve the per-type factory by key instead of the switch.
SingleButtonLarge → content card (Hero/Document); rename off the "button" label. (the headline item)SingleButton1/2 → Button (Icon variant) · ThreeUpButton → Button Group · Slider* → Carousel variants · EmergencyButton → Button (Emergency Hotline).WidgetDto → typed scaffold VMs via the factory above (keep the factory a pure mapper — no IServiceProvider; the async gather stays in the API service).DynamicWidgets/Widget render scaffold components / domain controls, not a mega-switch of inline markup.ALPADocs.Components / ALPADocs.ApiModels vs our universal component names.card-sm nav rows), the section-title headers, and the non-Home components (Menu Text, List).| File | Role |
|---|---|
Components/WidgetType.cs | the 9-value enum (taxonomy to reconcile) |
ApiModels/WidgetDto.cs | flat raw DTO → split via factory |
Components/Widget.razor (+ .razor.cs) | the mega-switch renderer → scaffold components |
Components/Pages/DynamicWidgets.razor | feed renderer (host) |
Services/IWidgetApiService.cs · MockWidgetApiService.cs | data service (async gather — keep here) |
Pages/BlazorPage.xaml (+ .cs) · wwwroot/css/widget.css | MAUI host + styling |