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.

الانتقال إلى التثبيت

معلومات المصدر

المستودع
markheydon/billdrift-web
آخر نشاط في المصدر
١ يوليو ٢٠٢٦ في ٢٢:٢٥
لغة SKILL.md المكتشفة
الإنجليزية
النجوم
٠
التفرعات
٠

خيارات التثبيت

يُحدَّد Prompt الذي يراجع المصدر أولًا بشكل افتراضي. يمكنك التبديل إلى أمر مباشر أو تنزيل نسخة محلية.

مراجعة ملفات المصدر

اقرأ SKILL.md وأي ملفات مرافقة يعرضها SkillsMP قبل أن تقرر التثبيت.

مستكشف الملفات
4 ملفات

عرض SKILL.md

SKILL.md
تعليمات المصدر · معاينة للقراءة فقط
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
عرض على GitHub
ملف SKILL.md هذا كبير جدا، لذلك يعرض SkillsMP القسم الاول فقط هنا. عرض على GitHub