Skip to main content

fluentui-blazor-usage

Provides accurate coding patterns for building Blazor applications with the Microsoft.FluentUI.AspNetCore.Components v5 NuGet package. Covers service registration, theming (CSS-based, no FluentDesignTheme), layout, navigation, dialogs, data grid, forms, icons, and common pitfalls.

Zur Installation springen

Quellinformationen

Repository
markheydon/billdrift-web
Letzte Quellaktivität
1. Juli 2026 um 22:25
Erkannte Sprache von SKILL.md
Englisch
Sterne
0
Forks
0

Installationsoptionen

Standardmäßig ist der Prompt ausgewählt, der zuerst die Quelle prüft. Sie können zu einem direkten Befehl wechseln oder eine lokale Kopie herunterladen.

Quelldateien prüfen

Lesen Sie SKILL.md und alle von SkillsMP angezeigten Begleitdateien, bevor Sie sich für eine Installation entscheiden.

Datei-Explorer
4 Dateien

SKILL.md wird angezeigt

SKILL.md
Quellanweisungen · Schreibgeschützte Vorschau
name
fluentui-blazor-usage
description
Provides accurate coding patterns for building Blazor applications with the Microsoft.FluentUI.AspNetCore.Components v5 NuGet package. Covers service registration, theming (CSS-based, no FluentDesignTheme), layout, navigation, dialogs, data grid, forms, icons, and common pitfalls.
# Fluent UI Blazor v5 — Usage Skill This skill helps AI assistants generate **correct, idiomatic code** for applications that consume the `Microsoft.FluentUI.AspNetCore.Components` **v5** NuGet package. v5 targets **.NET 9+** and wraps `@fluentui/web-components` v3. > **Critical**: v5 is a major rewrite. Many v4 APIs are removed or renamed. > Always verify patterns against this skill before answering. --- ## Quick Setup Checklist ```csharp // Program.cs builder.Services.AddFluentUIComponents(); ``` ```razor @* App.razor / MainLayout.razor — add providers once at root *@ <FluentProviders /> ``` ```html <!-- index.html / _Host.cshtml — required CSS & JS --> <link href="_content/Microsoft.FluentUI.AspNetCore.Components/css/default-fuib.css" rel="stylesheet" /> ``` The `<FluentProviders />` component replaces the need to manually add `<FluentDialogProvider />`, `<FluentTooltipProvider />`, and `<FluentKeyCodeProvider />` separately. --- ## Key v5 Differences from v4 | Area | v4 | v5 | |---|---|---| | Target framework | net8.0 | net9.0 / net10.0 | | Theming | `<FluentDesignTheme>` component | CSS custom properties via JS (`setTheme`), `body[data-theme]` attribute | | Toast / MessageBar | `IToastService`, `IMessageService` | **Removed** — use `FluentToast` component directly or custom solution | | Navigation | `FluentNavMenu`, `FluentNavLink`, `FluentNavGroup` | `FluentNav`, `FluentNavItem`, `FluentNavCategory`, `FluentNavSectionHeader` | | Dialog API | `IDialogContentComponent<T>`, complex reference | Simplified: `IDialogService.ShowDialogAsync<TDialog>(DialogOptions)` | | List binding | `FluentListBase<TOption>`, `SelectedOptions` | `FluentListBase<TOption, TValue>`, `SelectedItems` | | Progress | `FluentProgress` | `FluentProgressBar` (`FluentProgress` = obsolete shim) | | Appearance enum | `Appearance.Accent`, `.Stealth`, etc. | `ButtonAppearance.Primary`, `.Transparent`, etc. | | Switch | `CheckedMessage`/`UncheckedMessage` child content | Removed — label only via `Label` parameter | | Component base | Property injection | Constructor injection of `LibraryConfiguration` | | Margin / Padding | Not on components | Available on **every** component via `Margin` and `Padding` parameters | | Icons packages | Separate NuGet packages | Bundled (core icons), with optional extended packages | --- ## Theming v5 replaces `<FluentDesignTheme>` with a **JavaScript + CSS custom property** model. ### Apply a theme ```razor @inject IJSRuntime JSRuntime <FluentButton OnClick="@SwitchTheme">Toggle theme</FluentButton> @code { private async Task SwitchTheme() { await JSRuntime.InvokeVoidAsync("Blazor.theme.switchTheme"); } } ``` ### Detect current mode ```javascript // body[data-theme="dark"] → dark mode // body without data-theme → light mode Blazor.theme.isDarkMode() // returns boolean Blazor.theme.isSystemDark() // returns boolean ``` ### Conditional rendering by theme ```razor <FluentIcon Class="hidden-if-light" Value="@(new Icons.Filled.Size20.WeatherSunny())" /> <FluentIcon Class="hidden-if-dark" Value="@(new Icons.Filled.Size20.WeatherMoon())" /> ``` ### CSS variables All Fluent design tokens are available as CSS custom properties: `var(--colorBrandBackground)`, `var(--colorNeutralForeground1)`, `var(--fontSizeBase300)`, `var(--borderRadiusMedium)`, etc. C# constants are available via `StylesVariables` and `SystemColors`: ```csharp // In component styles style="@($"background: {SystemColors.Neutral.Background1}")" // Equivalent to: background: var(--colorNeutralBackground1); style="@($"border-radius: {StylesVariables.Borders.Radius.Medium}")" // Equivalent to: border-radius: var(--borderRadiusMedium); ``` --- ## Layout & Navigation ### FluentLayout ```razor <FluentLayout> <FluentLayoutItem Area="LayoutArea.Header"> <FluentLayoutHamburger /> <span>My App</span> </FluentLayoutItem> <FluentLayoutItem Area="LayoutArea.Menu"> <FluentNav> <FluentNavItem Href="/" Icon="@(new Icons.Regular.Size20.Home())"> Home </FluentNavItem> <FluentNavCategory Label="Settings" Icon="@(new Icons.Regular.Size20.Settings())"> <FluentNavItem Href="/settings/profile">Profile</FluentNavItem> <FluentNavItem Href="/settings/account">Account</FluentNavItem> </FluentNavCategory> <FluentNavSectionHeader Label="Admin" /> <FluentNavItem Href="/admin">Dashboard</FluentNavItem> </FluentNav> </FluentLayoutItem> <FluentLayoutItem Area="LayoutArea.Content"> @Body </FluentLayoutItem> <FluentLayoutItem Area="LayoutArea.Footer"> <span>&copy; 2025</span> </FluentLayoutItem> </FluentLayout> ``` > **Common mistake**: Using `FluentNavMenu` / `FluentNavLink` / `FluentNavGroup` (v4 names). These do **not** exist in v5. --- ## Dialogs ### Show a simple dialog ```csharp @inject IDialogService DialogService private async Task OpenDialog() { var options = new DialogOptions { Header = { Title = "Confirm action" }, Size = DialogSize.Medium, Modal = true, }; var result = await DialogService.ShowDialogAsync<ConfirmDialog>(options); if (!result.Cancelled) { // result.Value contains the returned data } } ``` ### Dialog component ```razor @* ConfirmDialog.razor *@ <p>Are you sure you want to proceed?</p> <FluentButton Appearance="ButtonAppearance.Primary" OnClick="@Confirm">Yes</FluentButton> <FluentButton OnClick="@Cancel">No</FluentButton> @code { [CascadingParameter] public IDialogInstance Dialog { get; set; } = default!; private async Task Confirm() => await Dialog.CloseAsync(DialogResult.Ok(true)); private async Task Cancel() => await Dialog.CloseAsync(DialogResult.Cancel()); } ``` ### Show a drawer ```csharp var result = await DialogService.ShowDrawerAsync<DrawerContent>(options => { options.Header.Title = "Settings"; options.Alignment = DialogAlignment.End; options.Size = DialogSize.Small; }); ``` ### Pass parameters to the dialog component ```csharp var options = new DialogOptions { Header = { Title = "Edit item" }, Parameters = new Dictionary<string, object?> { ["ItemId"] = selectedItemId, ["ItemName"] = selectedItemName, }, }; await DialogService.ShowDialogAsync<EditDialog>(options); ``` > **Common mistake**: Implementing `IDialogContentComponent<T>` (v4 pattern). In v5, dialog components are plain Razor components that receive `IDialogInstance` as a cascading parameter. --- ## Data Grid ```razor <FluentDataGrid Items="@people" Pagination="@pagination"> <PropertyColumn Property="@(p => p.Name)" Sortable="true" /> <PropertyColumn Property="@(p => p.Email)" /> <TemplateColumn Title="Actions"> <FluentButton Size="ButtonSize.Small" OnClick="@(() => Edit(context))"> Edit </FluentButton> </TemplateColumn> </FluentDataGrid> <FluentPaginator State="@pagination" /> @code { private IQueryable<Person> people = GetPeople().AsQueryable(); private PaginationState pagination = new() { ItemsPerPage = 10 }; } ``` ### Remote data with ItemsProvider ```csharp <FluentDataGrid ItemsProvider="@dataProvider" Virtualize="true" ItemSize="46"> <PropertyColumn Property="@(p => p.Name)" Sortable="true" /> </FluentDataGrid> @code { private GridItemsProvider<Person> dataProvider = default!; protected override void OnInitialized() { dataProvider = async request => { var result = await Http.GetFromJsonAsync<PagedResult<Person>>( $"api/people?start={request.StartIndex}&count={request.Count}"); return GridItemsProviderResult.From(result!.Items, result.TotalCount); }; } } ``` See [DATAGRID.md](references/DATAGRID.md) for advanced patterns (EF adapter, OData, column options, resize, custom sort). --- ## Forms & Input Components v5 input components extend `InputBase<TValue>` and implement `IFluentField`, providing built-in form validation integration. ```razor <EditForm Model="@model" OnValidSubmit="@Submit"> <DataAnnotationsValidator /> <FluentTextField @bind-Value="model.Name" Label="Name" Required="true" /> <FluentNumberField @bind-Value="model.Age" Label="Age" Min="0" Max="150" /> <FluentSelect TOption="string" TValue="string" Items="@countries" @bind-Value="model.Country" OptionText="@(c => c)" OptionValue="@(c => c)" Label="Country" /> <FluentCheckbox @bind-Value="model.AcceptTerms" Label="I accept the terms" /> <FluentButton Type="ButtonType.Submit" Appearance="ButtonAppearance.Primary"> Submit </FluentButton> </EditForm> ``` ### List components — two type parameters All list-based components (`FluentSelect`, `FluentCombobox`, `FluentListbox`) now take **two** type parameters: `TOption` (the item type) and `TValue` (the bound value type). ```razor <FluentSelect TOption="Country" TValue="int" Items="@countries" @bind-Value="model.CountryId" OptionText="@(c => c.Name)" OptionValue="@(c => c.Id)" Label="Country" /> @* Multiple selection *@ <FluentListbox TOption="string" TValue="string" Items="@tags" Multiple="true" SelectedItems="@selectedTags" SelectedItemsChanged="@(items => selectedTags = items)" OptionText="@(t => t)" OptionValue="@(t => t)" /> ``` > **Common mistake**: Using `SelectedOptions` or `SelectedOptionsChanged` (v4 names). In v5, use `SelectedItems` / `SelectedItemsChanged`. --- ## Icons Icons are instantiated as objects and passed via `Value`, `IconStart`, or `IconEnd` parameters: ```razor @* Standalone icon *@ <FluentIcon Value="@(new Icons.Regular.Size24.Add())" /> @* Icon with color *@ <FluentIcon Value="@(new Icons.Filled.Size20.Heart().WithColor("red"))" /> @* Icon in a button *@ <FluentButton IconStart="@(new Icons.Regular.Size20.Add())" Appearance="ButtonAppearance.Primary"> Add item </FluentButton> @* Icon from image URL *@ <FluentIcon Value="@Icon.FromImageUrl("/images/logo.png")" /> ``` Icon naming: `Icons.{Variant}.{Size}.{Name}` - Variants: `Regular`, `Filled` - Sizes: `Size16`, `Size20`, `Size24`, `Size28`, `Size32`, `Size48` --- ## Margin & Padding (NEW in v5) Every component supports `Margin` and `Padding` parameters using a spacing-utility syntax: ```razor <FluentCard Margin="Margin.All4" Padding="Padding.Horizontal3 Padding.Vertical2"> Content with spacing </FluentCard> ``` --- ## Common Pitfalls
Auf GitHub ansehen
Diese SKILL.md ist sehr gross, daher zeigt SkillsMP hier nur den ersten Abschnitt. Auf GitHub ansehen