Blazor tutorial
Razor class library components wi parameters, ChildContent
render fragments, attribute splattin, an a bUnit test per component.
Whit ye'll big
A wee contact form — labelled input, submit button,
@bind-Value bindin, real keyboard an screen-reader behaviour — first bare, then styled, in aboot 10 minutes.
Afore ye stairt
Ye need git an the .NET SDK 8 or later. Onie Blazor project wirks — Blazor Web App, Server, or WebAssembly.
Step 1 — Git the code
git clone https://github.com/LilyDesignSystem/lily-design-system
cd lily-design-system/lily-design-system-blazor-headless
dotnet build
dotnet test # bUnit — 1,400+ cases across the catalog
The components live in src/LilyBlazorHeadless/Components/ —
Button.razor, TextInput.razor — ae Razor file ilkane. Reference the project (or copy the files) frae yer Blazor app an add @using LilyBlazorHeadless.Components tae
_Imports.razor.
Step 2 — Yer first component
<Button OnClick="Save">Save</Button>
Renders <button class="button">. The shared parameter conventions: Label (an aria-label owerride),
CssClass (appendit tae the base hook),
ChildContent, an
[Parameter(CaptureUnmatchedValues = true)] attribute splattin sae onie extra HTML attribute passes through.
Step 3 — Compose a wee form
<Form OnSubmit="HandleSubmit">
<Field Label="Full name" Required="true">
<TextInput Id="name" Label="Full name" @bind-Value="name" Required="true" />
</Field>
<Button Type="submit">Save</Button>
</Form>
@code {
private string name = "";
}
Field taks the visible Label as its ain parameter raither than a nestit label component — pass it ance, on
Field, an TextInputon
Label supplies the accessible name.
Verified 2026-08-29: an earlier draft nestit a separate Label component inside Field, which renders twa labels (ane empty) because Field
aareadies renders its ain frae the Label parameter — catcht bi checkin the component source; Form haes nae Label parameter o its ain, sae the earlier draft's uiss o
<Form> wis correctit bi omittin ane raither than inventin an attribute that disnae exist. The
contact-form composed route
is the same pattern, exercised bi real e2e an axe tests.
Check yer wirk: rin the app an the form looks plain — exactly as intendit: styling is still aheid. Press Tab: focus muives through ilka control, the label is announced, an submit wirks. The behaviour is deen; the look is yours, an it's neist.
Step 4 — Style it
Style the class hooks — .button, .text-input,
.label, .field — in app.css, or link a ready-made theme in App.razor /
index.html:
<link rel="stylesheet" href="themes/wireframe.css" />
Step 5 — See it aw wirkin
The Blazor Web example app shaws the full catalog styled an demoed, wi Playwright e2e tests:
git clone https://github.com/LilyDesignSystem/lily-design-system
cd lily-design-system/lily-design-system-blazor-web-examples
dotnet run --project src/LilyBlazorWebExamples
Neist steps
- Theming — runtime switchin wi the Blazor theme-picker helper (a Razor class library on NuGet).
- Preference helpers — leid an text size.
- Component catalog — props, ARIA, an keyboard per component.
Questions alang the wey? The help page is fu o answers — an if a step could be clearer, tell us an we'll gladly improve the tutorial.