Skip to content

Commit 64b2e57

Browse files
authored
Merge pull request #738 from AClerbois/skill/fluentui-blazor
Add fluentui-blazor skill
2 parents 76b1c55 + dc484e4 commit 64b2e57

File tree

6 files changed

+799
-0
lines changed

6 files changed

+799
-0
lines changed

docs/README.skills.md

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -36,6 +36,7 @@ Skills differ from other primitives by supporting bundled assets (scripts, code
3636
| [create-web-form](../skills/create-web-form/SKILL.md) | Create robust, accessible web forms with best practices for HTML structure, CSS styling, JavaScript interactivity, form validation, and server-side processing. Use when asked to "create a form", "build a web form", "add a contact form", "make a signup form", or when building any HTML form with data handling. Covers PHP and Python backends, MySQL database integration, REST APIs, XML data exchange, accessibility (ARIA), and progressive web apps. | `references/accessibility.md`<br />`references/aria-form-role.md`<br />`references/css-styling.md`<br />`references/form-basics.md`<br />`references/form-controls.md`<br />`references/form-data-handling.md`<br />`references/html-form-elements.md`<br />`references/html-form-example.md`<br />`references/hypertext-transfer-protocol.md`<br />`references/javascript.md`<br />`references/php-cookies.md`<br />`references/php-forms.md`<br />`references/php-json.md`<br />`references/php-mysql-database.md`<br />`references/progressive-web-app.md`<br />`references/python-as-web-framework.md`<br />`references/python-contact-form.md`<br />`references/python-flask-app.md`<br />`references/python-flask.md`<br />`references/security.md`<br />`references/styling-web-forms.md`<br />`references/web-api.md`<br />`references/web-performance.md`<br />`references/xml.md` |
3737
| [excalidraw-diagram-generator](../skills/excalidraw-diagram-generator/SKILL.md) | Generate Excalidraw diagrams from natural language descriptions. Use when asked to "create a diagram", "make a flowchart", "visualize a process", "draw a system architecture", "create a mind map", or "generate an Excalidraw file". Supports flowcharts, relationship diagrams, mind maps, and system architecture diagrams. Outputs .excalidraw JSON files that can be opened directly in Excalidraw. | `references/element-types.md`<br />`references/excalidraw-schema.md`<br />`scripts/.gitignore`<br />`scripts/README.md`<br />`scripts/add-arrow.py`<br />`scripts/add-icon-to-diagram.py`<br />`scripts/split-excalidraw-library.py`<br />`templates/business-flow-swimlane-template.excalidraw`<br />`templates/class-diagram-template.excalidraw`<br />`templates/data-flow-diagram-template.excalidraw`<br />`templates/er-diagram-template.excalidraw`<br />`templates/flowchart-template.excalidraw`<br />`templates/mindmap-template.excalidraw`<br />`templates/relationship-template.excalidraw`<br />`templates/sequence-diagram-template.excalidraw` |
3838
| [finnish-humanizer](../skills/finnish-humanizer/SKILL.md) | Detect and remove AI-generated markers from Finnish text, making it sound like a native Finnish speaker wrote it. Use when asked to "humanize", "naturalize", or "remove AI feel" from Finnish text, or when editing .md/.txt files containing Finnish content. Identifies 26 patterns (12 Finnish-specific + 14 universal) and 4 style markers. | `references/patterns.md` |
39+
| [fluentui-blazor](../skills/fluentui-blazor/SKILL.md) | Guide for using the Microsoft Fluent UI Blazor component library (Microsoft.FluentUI.AspNetCore.Components NuGet package) in Blazor applications. Use this when the user is building a Blazor app with Fluent UI components, setting up the library, using FluentUI components like FluentButton, FluentDataGrid, FluentDialog, FluentToast, FluentNavMenu, FluentTextField, FluentSelect, FluentAutocomplete, FluentDesignTheme, or any component prefixed with "Fluent". Also use when troubleshooting missing providers, JS interop issues, or theming. | `references/DATAGRID.md`<br />`references/LAYOUT-AND-NAVIGATION.md`<br />`references/SETUP.md`<br />`references/THEMING.md` |
3940
| [gh-cli](../skills/gh-cli/SKILL.md) | GitHub CLI (gh) comprehensive reference for repositories, issues, pull requests, Actions, projects, releases, gists, codespaces, organizations, extensions, and all GitHub operations from the command line. | None |
4041
| [git-commit](../skills/git-commit/SKILL.md) | Execute git commit with conventional commit message analysis, intelligent staging, and message generation. Use when user asks to commit changes, create a git commit, or mentions "/commit". Supports: (1) Auto-detecting type and scope from changes, (2) Generating conventional commit messages from diff, (3) Interactive commit with optional type/scope/description overrides, (4) Intelligent file staging for logical grouping | None |
4142
| [github-issues](../skills/github-issues/SKILL.md) | Create, update, and manage GitHub issues using MCP tools. Use this skill when users want to create bug reports, feature requests, or task issues, update existing issues, add labels/assignees/milestones, or manage issue workflows. Triggers on requests like "create an issue", "file a bug", "request a feature", "update issue X", or any GitHub issue management task. | `references/templates.md` |

skills/fluentui-blazor/SKILL.md

Lines changed: 231 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,231 @@
1+
---
2+
name: fluentui-blazor
3+
description: >
4+
Guide for using the Microsoft Fluent UI Blazor component library
5+
(Microsoft.FluentUI.AspNetCore.Components NuGet package) in Blazor applications.
6+
Use this when the user is building a Blazor app with Fluent UI components,
7+
setting up the library, using FluentUI components like FluentButton, FluentDataGrid,
8+
FluentDialog, FluentToast, FluentNavMenu, FluentTextField, FluentSelect,
9+
FluentAutocomplete, FluentDesignTheme, or any component prefixed with "Fluent".
10+
Also use when troubleshooting missing providers, JS interop issues, or theming.
11+
---
12+
13+
# Fluent UI Blazor — Consumer Usage Guide
14+
15+
This skill teaches how to correctly use the **Microsoft.FluentUI.AspNetCore.Components** (version 4) NuGet package in Blazor applications.
16+
17+
## Critical Rules
18+
19+
### 1. No manual `<script>` or `<link>` tags needed
20+
21+
The library auto-loads all CSS and JS via Blazor's static web assets and JS initializers. **Never tell users to add `<script>` or `<link>` tags for the core library.**
22+
23+
### 2. Providers are mandatory for service-based components
24+
25+
These provider components **MUST** be added to the root layout (e.g. `MainLayout.razor`) for their corresponding services to work. Without them, service calls **fail silently** (no error, no UI).
26+
27+
```razor
28+
<FluentToastProvider />
29+
<FluentDialogProvider />
30+
<FluentMessageBarProvider />
31+
<FluentTooltipProvider />
32+
<FluentKeyCodeProvider />
33+
```
34+
35+
### 3. Service registration in Program.cs
36+
37+
```csharp
38+
builder.Services.AddFluentUIComponents();
39+
40+
// Or with configuration:
41+
builder.Services.AddFluentUIComponents(options =>
42+
{
43+
options.UseTooltipServiceProvider = true; // default: true
44+
options.ServiceLifetime = ServiceLifetime.Scoped; // default
45+
});
46+
```
47+
48+
**ServiceLifetime rules:**
49+
- `ServiceLifetime.Scoped` — for Blazor Server / Interactive (default)
50+
- `ServiceLifetime.Singleton` — for Blazor WebAssembly standalone
51+
- `ServiceLifetime.Transient`**throws `NotSupportedException`**
52+
53+
### 4. Icons require a separate NuGet package
54+
55+
```
56+
dotnet add package Microsoft.FluentUI.AspNetCore.Components.Icons
57+
```
58+
59+
Usage with a `@using` alias:
60+
61+
```razor
62+
@using Icons = Microsoft.FluentUI.AspNetCore.Components.Icons
63+
64+
<FluentIcon Value="@(Icons.Regular.Size24.Save)" />
65+
<FluentIcon Value="@(Icons.Filled.Size20.Delete)" Color="@Color.Error" />
66+
```
67+
68+
Pattern: `Icons.[Variant].[Size].[Name]`
69+
- Variants: `Regular`, `Filled`
70+
- Sizes: `Size12`, `Size16`, `Size20`, `Size24`, `Size28`, `Size32`, `Size48`
71+
72+
Custom image: `Icon.FromImageUrl("/path/to/image.png")`
73+
74+
**Never use string-based icon names** — icons are strongly-typed classes.
75+
76+
### 5. List component binding model
77+
78+
`FluentSelect<TOption>`, `FluentCombobox<TOption>`, `FluentListbox<TOption>`, and `FluentAutocomplete<TOption>` do NOT work like `<InputSelect>`. They use:
79+
80+
- `Items` — the data source (`IEnumerable<TOption>`)
81+
- `OptionText``Func<TOption, string?>` to extract display text
82+
- `OptionValue``Func<TOption, string?>` to extract the value string
83+
- `SelectedOption` / `SelectedOptionChanged` — for single selection binding
84+
- `SelectedOptions` / `SelectedOptionsChanged` — for multi-selection binding
85+
86+
```razor
87+
<FluentSelect Items="@countries"
88+
OptionText="@(c => c.Name)"
89+
OptionValue="@(c => c.Code)"
90+
@bind-SelectedOption="@selectedCountry"
91+
Label="Country" />
92+
```
93+
94+
**NOT** like this (wrong pattern):
95+
```razor
96+
@* WRONG — do not use InputSelect pattern *@
97+
<FluentSelect @bind-Value="@selectedValue">
98+
<option value="1">One</option>
99+
</FluentSelect>
100+
```
101+
102+
### 6. FluentAutocomplete specifics
103+
104+
- Use `ValueText` (NOT `Value` — it's obsolete) for the search input text
105+
- `OnOptionsSearch` is the required callback to filter options
106+
- Default is `Multiple="true"`
107+
108+
```razor
109+
<FluentAutocomplete TOption="Person"
110+
OnOptionsSearch="@OnSearch"
111+
OptionText="@(p => p.FullName)"
112+
@bind-SelectedOptions="@selectedPeople"
113+
Label="Search people" />
114+
115+
@code {
116+
private void OnSearch(OptionsSearchEventArgs<Person> args)
117+
{
118+
args.Items = allPeople.Where(p =>
119+
p.FullName.Contains(args.Text, StringComparison.OrdinalIgnoreCase));
120+
}
121+
}
122+
```
123+
124+
### 7. Dialog service pattern
125+
126+
**Do NOT toggle visibility of `<FluentDialog>` tags.** The service pattern is:
127+
128+
1. Create a content component implementing `IDialogContentComponent<TData>`:
129+
130+
```csharp
131+
public partial class EditPersonDialog : IDialogContentComponent<Person>
132+
{
133+
[Parameter] public Person Content { get; set; } = default!;
134+
135+
[CascadingParameter] public FluentDialog Dialog { get; set; } = default!;
136+
137+
private async Task SaveAsync()
138+
{
139+
await Dialog.CloseAsync(Content);
140+
}
141+
142+
private async Task CancelAsync()
143+
{
144+
await Dialog.CancelAsync();
145+
}
146+
}
147+
```
148+
149+
2. Show the dialog via `IDialogService`:
150+
151+
```csharp
152+
[Inject] private IDialogService DialogService { get; set; } = default!;
153+
154+
private async Task ShowEditDialog()
155+
{
156+
var dialog = await DialogService.ShowDialogAsync<EditPersonDialog, Person>(
157+
person,
158+
new DialogParameters
159+
{
160+
Title = "Edit Person",
161+
PrimaryAction = "Save",
162+
SecondaryAction = "Cancel",
163+
Width = "500px",
164+
PreventDismissOnOverlayClick = true,
165+
});
166+
167+
var result = await dialog.Result;
168+
if (!result.Cancelled)
169+
{
170+
var updatedPerson = result.Data as Person;
171+
}
172+
}
173+
```
174+
175+
For convenience dialogs:
176+
```csharp
177+
await DialogService.ShowConfirmationAsync("Are you sure?", "Yes", "No");
178+
await DialogService.ShowSuccessAsync("Done!");
179+
await DialogService.ShowErrorAsync("Something went wrong.");
180+
```
181+
182+
### 8. Toast notifications
183+
184+
```csharp
185+
[Inject] private IToastService ToastService { get; set; } = default!;
186+
187+
ToastService.ShowSuccess("Item saved successfully");
188+
ToastService.ShowError("Failed to save");
189+
ToastService.ShowWarning("Check your input");
190+
ToastService.ShowInfo("New update available");
191+
```
192+
193+
`FluentToastProvider` parameters: `Position` (default `TopRight`), `Timeout` (default 7000ms), `MaxToastCount` (default 4).
194+
195+
### 9. Design tokens and themes work only after render
196+
197+
Design tokens rely on JS interop. **Never set them in `OnInitialized`** — use `OnAfterRenderAsync`.
198+
199+
```razor
200+
<FluentDesignTheme Mode="DesignThemeModes.System"
201+
OfficeColor="OfficeColor.Teams"
202+
StorageName="mytheme" />
203+
```
204+
205+
### 10. FluentEditForm vs EditForm
206+
207+
`FluentEditForm` is only needed inside `FluentWizard` steps (per-step validation). For regular forms, use standard `EditForm` with Fluent form components:
208+
209+
```razor
210+
<EditForm Model="@model" OnValidSubmit="HandleSubmit">
211+
<DataAnnotationsValidator />
212+
<FluentTextField @bind-Value="@model.Name" Label="Name" Required />
213+
<FluentSelect Items="@options"
214+
OptionText="@(o => o.Label)"
215+
@bind-SelectedOption="@model.Category"
216+
Label="Category" />
217+
<FluentValidationSummary />
218+
<FluentButton Type="ButtonType.Submit" Appearance="Appearance.Accent">Save</FluentButton>
219+
</EditForm>
220+
```
221+
222+
Use `FluentValidationMessage` and `FluentValidationSummary` instead of standard Blazor validation components for Fluent styling.
223+
224+
## Reference files
225+
226+
For detailed guidance on specific topics, see:
227+
228+
- [Setup and configuration](references/SETUP.md)
229+
- [Layout and navigation](references/LAYOUT-AND-NAVIGATION.md)
230+
- [Data grid](references/DATAGRID.md)
231+
- [Theming](references/THEMING.md)

0 commit comments

Comments
 (0)