Skills on AI 459 skills

Active theme: Light

Lily Design System Blazor

Explains what's available for Blazor in Lily Design System and which of the three real Blazor subprojects an agent needs — the headless component library (the NuGet package you depend on and style yourself), the six *-picker helpers catalog (opinionated, whole-interaction packages for a page-header preference/action or a form control), or the Blazor Web example app (a fully NHS-UK-styled reference you can run to see components working, or copy CSS from). Use when someone asks what Lily offers for Blazor, which Blazor package to install for a given job, how to run the Blazor example app, or wants Blazor Web App hosting-model guidance (Server / WebAssembly / static SSR).

Three real Blazor subprojects exist in the Lily Design System monorepo. This skill is the entry point that maps them and tells an agent which one to reach for; it does not restate any of their contracts in full.

The three subprojects

  • lily-design-system-blazor-headless — the Razor class library you actually depend on. Ships the full 491-component catalog (490/490 recorded parity as of its own spec/index.md) as unstyled Razor components: semantic HTML, ARIA, focus management, keyboard behaviour, no CSS. Published to nuget.org as LilyDesignSystem.Blazor.Headless (namespace LilyBlazorHeadless.Components). Reach for this when you need a component itself — Button, TextInput, BreadcrumbNav, DataTable, and the rest — and intend to style it yourself. Deep dive: lily-design-system-blazor-headless.
  • lily-design-system-blazor-helpers — six opinionated packages that sit alongside the headless library, each owning one whole interaction end to end: theme-picker, locale-picker, text-size-picker, motion-picker (a user preference — selection + DOM application + optional persistence), share-picker (an action — no applying, no persisting), and date-time-picker (a form control — a typeable text field plus a trigger opening a WAI-ARIA APG date-picker dialog). Each is its own NuGet package under namespace LilyDesignSystem.Blazor.Helpers. Reach for one of these when the job is a page-header preference control, a share action, or a date/time form field — not a plain catalog component. Deep dive: lily-design-system-blazor-helpers.
  • lily-design-system-blazor-web-examples — a Blazor Web App (.NET 10) reference application, fully styled against the NHS UK design system's colours, typography, spacing, and focus states. It imports the headless library via ProjectReference and demonstrates every catalog component plus 12 composed pages. Reach for this to run something and see components working, or to copy its CSS as a starting point for your own styling. No sibling skill covers this app — its coverage lives entirely in this skill (below).

The Blazor Web example app

lily-design-system-blazor-web-examples uses Blazor Web App with Interactive Server rendering (SignalR) — not WebAssembly and not static SSR. It follows the general example-app contract every Lily example app carries (root AGENTS/examples.md): a complete stylesheet targeting the kebab-case Lily class names directly (no nhsuk- prefix in markup), CSS custom properties for every design token, no CSS framework dependency, and the required-routes shape below.

Required routes

  • / — home page, links to every example.
  • /components — the full catalog index (its own index.md records 490 components with links to individual demos).
  • /components/{slug} — one live demo per component, with the canonical metadata (description, props, ARIA, keyboard, references).

Composed-page demos

Twelve pages beyond the required routes, each exercising several components together: /contact-form, /dashboard, /dialog-flow, /file-upload-form, /navigation-and-menus, /page-layout, /rating-and-feedback, /search-and-filter, /settings-page, /tabbed-interface, /task-management, /timeline-and-cards. Each page's own AGENTS.md names the exact components it demonstrates.

Running it

dotnet run --project src/LilyBlazorWebExamples

Then open the printed https://localhost:... URL.

Visual reference

NHS UK design system: colours, typography, spacing, and focus states, delivered as CSS custom properties in wwwroot/css/nhs.css (component styling itself comes from the runtime theme, per the app's own AGENTS.md). Keyboard-navigation helpers for the demos live in wwwroot/js/headless-interop.js.

The one Blazor gotcha this app exists to teach

Most lily-design-system-blazor-headless form-field primitives (TextInput, EmailInput, TextAreaInput, Select, Option, RadioInput, CheckboxInput, Form, Field, Fieldset, SummaryListItem, and most others) do not declare Value/ValueChanged, Checked/CheckedChanged, or OnSubmit — passing a PascalCase Value="..." compiles silently into AdditionalAttributes and wires nothing. This silently broke five of this app's own composed pages (ContactForm.razor, SettingsPage.razor, RatingAndFeedback.razor, SearchAndFilter.razor, TaskManagement.razor) until a later fix; the correct idiom is native lowercase attributes (value="@x", checked="@x", name="@x") plus @onchange/@oninput, and novalidate @onsubmit="Handler" on Form — Razor directive attributes always compile to their fixed lowercase DOM event name and splat correctly regardless of what the component declares. BookAnAppointment.razor is this app's own canonical reference for the idiom across every field type. A short list of components genuinely do own a real bindable pair — SwitchButton, Combobox, AccordionCheckbox, and the Dialog/Drawer family (checked individually) — where @bind-X/XChanged works as written. This is the same fact the headless skill teaches from the library side; it is repeated here because it is what actually broke this app in practice.

Conventions spanning all three subprojects

  • .NET 10 / C#, Blazor Razor components throughout — no class components.
  • Namespace split by layer: LilyBlazorHeadless.Components for the headless library, LilyDesignSystem.Blazor.Helpers for every helper package.
  • CssClass, not class, as the styling-hook parameter — Blazor's attribute splat can't merge into a class="" the component itself sets, so every component concatenates its own kebab-case base class with the consumer's CssClass.
  • RenderFragment ChildContent for the default slot; [Parameter(CaptureUnmatchedValues = true)] Dictionary<string, object>? AdditionalAttributes for rest-attribute pass-through, spread via @attributes="AdditionalAttributes".
  • IJSRuntime for any DOM work, gated on OnAfterRenderAsync (never during render) — this is how the helpers stay safe across Blazor Server, Blazor WebAssembly, and static SSR/prerender hosting models, and it is the same pattern the example app's headless-interop.js is invoked through.
  • NuGet Trusted Publishing (OIDC) is how both the headless library and the helpers publish — no long-lived API key.

When this isn't the right skill

  • For the Blazor headless library's own parameter idioms, publish status, and known gotchas in full — use lily-design-system-blazor-headless.
  • For the six *-picker helpers' shared contract, their two exceptions, and the IJSRuntime/SSR implementation pattern in full — use lily-design-system-blazor-helpers.
  • For framework-agnostic Lily concepts (what "headless" means, the 491-component catalog at large, naming conventions, cross-framework composition patterns) — use lily-design-system instead; it doesn't restate Blazor's own idioms, and this skill doesn't restate its concepts.

View lily-design-system-blazor/SKILL.md on GitHub