Skills per mudBlazor

This commit is contained in:
2026-06-05 11:32:56 +02:00
parent fcf0cf0b77
commit 4661922633
2 changed files with 250 additions and 120 deletions
+163
View File
@@ -0,0 +1,163 @@
---
name: blazor
description: |
Builds Blazor WASM components for admin and main UI applications.
Use when: Creating/modifying Razor components, configuring render modes, implementing authentication, managing component state, or working with MudBlazor components.
allowed-tools: Read, Edit, Write, Glob, Grep, Bash, mcp__context7__resolve-library-id, mcp__context7__query-docs
---
# Blazor Skill
Sorcha uses Blazor with hybrid rendering (Server + WebAssembly). The Admin UI (`src/Apps/Sorcha.Admin/`) runs behind YARP API Gateway. Components use MudBlazor for UI and support three render modes: static server, interactive server, and interactive WASM.
## Quick Start
### Render Mode Selection
```razor
@* WASM - Complex interactive pages (Designer, Diagrams) *@
@page "/designer"
@rendermode InteractiveWebAssembly
@attribute [Authorize]
@* Server - Admin pages needing real-time SignalR *@
@page "/admin/audit"
@rendermode @(new InteractiveServerRenderMode(prerender: false))
@attribute [Authorize(Roles = "Administrator")]
@* Static - Public pages (Login) - no @rendermode directive *@
@page "/login"
@attribute [AllowAnonymous]
```
### Component with Loading State
```razor
@inject HttpClient Http
<MudPaper Elevation="2" Class="pa-4">
@if (_isLoading && !_hasLoadedOnce)
{
<MudProgressCircular Indeterminate="true" Size="Size.Small" />
}
else if (_data != null)
{
<MudText>@_data.Title</MudText>
}
else if (_errorMessage != null)
{
<MudAlert Severity="Severity.Error">@_errorMessage</MudAlert>
}
</MudPaper>
@code {
private DataDto? _data;
private string? _errorMessage;
private bool _isLoading;
private bool _hasLoadedOnce;
protected override async Task OnAfterRenderAsync(bool firstRender)
{
if (firstRender)
await LoadDataAsync();
}
private async Task LoadDataAsync()
{
_isLoading = true;
try
{
_data = await Http.GetFromJsonAsync<DataDto>("/api/data");
_hasLoadedOnce = true;
}
catch (Exception ex)
{
_errorMessage = ex.Message;
}
finally
{
_isLoading = false;
StateHasChanged();
}
}
}
```
## Key Concepts
| Concept | Usage | Example |
|---------|-------|---------|
| Render Mode | Control where component runs | `@rendermode InteractiveWebAssembly` |
| CascadingParameter | Receive parent state | `[CascadingParameter] MudBlazor.IDialogReference? MudDialog` |
| OnAfterRenderAsync | Initialize after DOM ready | `if (firstRender) await LoadAsync();` |
| StateHasChanged | Trigger re-render | Call after async state updates |
| NavigationManager | Programmatic navigation | `Navigation.NavigateTo("/", forceLoad: true)` |
## Project Structure
| Project | Purpose | Render Mode |
|---------|---------|-------------|
| `Sorcha.Admin` | Server host, auth, API proxy | Server + prerender |
| `Sorcha.Admin.Client` | WASM components | WebAssembly |
| `Sorcha.UI.Core` | Shared components | Both |
| `Sorcha.UI.Web` | Main UI server | Server |
| `Sorcha.UI.Web.Client` | Main UI WASM | WebAssembly |
## Common Patterns
### MudBlazor Dialog
```razor
<MudDialog DisableSidePadding="false">
<DialogContent>
<MudTextField @bind-Value="_value" Label="Input" />
</DialogContent>
<DialogActions>
<MudButton OnClick="Cancel">Cancel</MudButton>
<MudButton Color="Color.Primary" OnClick="Submit">OK</MudButton>
</DialogActions>
</MudDialog>
@code {
[CascadingParameter] MudBlazor.IDialogReference? MudDialog { get; set; }
private string _value = "";
private void Cancel() => MudDialog?.Close();
private void Submit() => MudDialog?.Close(DialogResult.Ok(_value));
}
```
### Opening Dialog from Parent
```csharp
var dialog = await DialogService.ShowAsync<LoginDialog>("Login");
var result = await dialog.Result;
if (result is { Canceled: false })
{
// Handle success
}
```
## See Also
- [patterns](references/patterns.md) - Component and authentication patterns
- [workflows](references/workflows.md) - Development and deployment workflows
## Related Skills
- See the **aspire** skill for service discovery configuration
- See the **signalr** skill for real-time notifications
- See the **jwt** skill for authentication token handling
- See the **yarp** skill for API Gateway configuration
- See the **mudblazor** skill for component library details
## Documentation Resources
> Fetch latest Blazor/MudBlazor documentation with Context7.
**Library ID:** `/websites/mudblazor` _(MudBlazor component library documentation)_
**Recommended Queries:**
- "MudBlazor dialog service usage"
- "MudBlazor form validation"
- "MudBlazor data grid filtering"
+87 -120
View File
@@ -1,145 +1,112 @@
--- ---
name: frontend-design name: frontend-design
description: Create distinctive, production-grade frontend interfaces with high design quality. Use when the user asks to build web components, pages, or applications and the visual direction matters as much as the code quality. description: |
origin: ECC Styles Blazor WASM components with CSS and responsive design patterns using MudBlazor Material Design.
Use when: Creating new components, styling existing components, implementing responsive layouts, adding animations/transitions, or working with the MudBlazor component library.
allowed-tools: Read, Edit, Write, Glob, Grep, Bash
--- ---
# Frontend Design # Frontend-design Skill
Use this when the task is not just "make it work" but "make it look designed." Sorcha uses **MudBlazor 9.5.0** for Material Design components with **CSS Isolation** as the primary styling approach. The design system follows Material Design 3 with custom extensions for blockchain/workflow visualization.
This skill is for product pages, dashboards, app shells, components, or visual systems that need a clear point of view instead of generic AI-looking UI. ## Quick Start
## When To Use ### Styling a New Component
- building a landing page, dashboard, or app surface from scratch ```razor
- upgrading a bland interface into something intentional and memorable @* MyComponent.razor *@
- translating a product concept into a concrete visual direction <MudPaper Elevation="1" Class="pa-4 mb-3">
- implementing a frontend where typography, composition, and motion matter <MudText Typo="Typo.h6" Class="mb-2">Component Title</MudText>
<MudText Typo="Typo.body2" Color="Color.Secondary">
Description text
</MudText>
</MudPaper>
```
## Core Principle ### Custom Component with CSS Isolation
Pick a direction and commit to it. ```razor
@* MyCard.razor *@
<div class="custom-card @(IsSelected ? "selected" : "")">
<div class="card-header">@Title</div>
<div class="card-content">@ChildContent</div>
</div>
Safe-average UI is usually worse than a strong, coherent aesthetic with a few bold choices. @code {
[Parameter] public string Title { get; set; } = "";
[Parameter] public RenderFragment? ChildContent { get; set; }
[Parameter] public bool IsSelected { get; set; }
}
```
## Design Workflow ```css
/* MyCard.razor.css */
.custom-card {
background: white;
border: 2px solid #1976d2;
border-radius: 10px;
box-shadow: 0 2px 8px rgba(0,0,0,0.12);
transition: all 0.2s ease;
}
### 1. Frame the interface first .custom-card:hover {
box-shadow: 0 4px 12px rgba(0,0,0,0.18);
transform: translateY(-2px);
}
Before coding, settle: .custom-card.selected {
border-color: #0d47a1;
border-width: 3px;
}
```
- purpose ## Key Concepts
- audience
- emotional tone
- visual direction
- one thing the user should remember
Possible directions: | Concept | Usage | Example |
|---------|-------|---------|
| CSS Isolation | Component-scoped styles | `Component.razor.css` |
| MudBlazor Utility | Spacing, flex, alignment | `Class="d-flex pa-4 mb-3"` |
| Color System | Semantic colors | `Color.Primary`, `Color.Error` |
| Typography | Text hierarchy | `Typo.h6`, `Typo.body2` |
| Elevation | Shadow depth | `Elevation="1"` (0-24) |
| Breakpoint | Responsive | `Breakpoint.Sm` (641px) |
- brutally minimal ## Common Patterns
- editorial
- industrial
- luxury
- playful
- geometric
- retro-futurist
- soft and organic
- maximalist
Do not mix directions casually. Choose one and execute it cleanly. ### Flex Layout with Gap
### 2. Build the visual system ```razor
<div class="d-flex align-center gap-2 mb-3">
<MudIcon Icon="@Icons.Material.Filled.Settings" />
<MudText Typo="Typo.body1">Settings</MudText>
<MudSpacer />
<MudChip T="string" Size="Size.Small" Color="Color.Info">Active</MudChip>
</div>
```
Define: ### Panel with Header/Content Pattern
- type hierarchy ```razor
- color variables <MudPaper Elevation="1" Class="panel">
- spacing rhythm <div class="panel-header">
- layout logic <MudText Typo="Typo.subtitle1">Panel Title</MudText>
- motion rules </div>
- surface / border / shadow treatment <div class="panel-content">
@* Content here *@
</div>
</MudPaper>
```
Use CSS variables or the project's token system so the interface stays coherent as it grows. ## See Also
### 3. Compose with intention - [aesthetics](references/aesthetics.md) - Color system, typography, brand identity
- [components](references/components.md) - MudBlazor component patterns
- [layouts](references/layouts.md) - Page structure, responsive grids
- [motion](references/motion.md) - Transitions, hover effects
- [patterns](references/patterns.md) - DO/DON'T design decisions
Prefer: ## Related Skills
- asymmetry when it sharpens hierarchy - See the **blazor** skill for component lifecycle and state management
- overlap when it creates depth - See the **signalr** skill for real-time UI updates
- strong whitespace when it clarifies focus
- dense layouts only when the product benefits from density
Avoid defaulting to a symmetrical card grid unless it is clearly the right fit.
### 4. Make motion meaningful
Use animation to:
- reveal hierarchy
- stage information
- reinforce user action
- create one or two memorable moments
Do not scatter generic micro-interactions everywhere. One well-directed load sequence is usually stronger than twenty random hover effects.
## Strong Defaults
### Typography
- pick fonts with character
- pair a distinctive display face with a readable body face when appropriate
- avoid generic defaults when the page is design-led
### Color
- commit to a clear palette
- one dominant field with selective accents usually works better than evenly weighted rainbow palettes
- avoid cliché purple-gradient-on-white unless the product genuinely calls for it
### Background
Use atmosphere:
- gradients
- meshes
- textures
- subtle noise
- patterns
- layered transparency
Flat empty backgrounds are rarely the best answer for a product-facing page.
### Layout
- break the grid when the composition benefits from it
- use diagonals, offsets, and grouping intentionally
- keep reading flow obvious even when the layout is unconventional
## Anti-Patterns
Never default to:
- interchangeable SaaS hero sections
- generic card piles with no hierarchy
- random accent colors without a system
- placeholder-feeling typography
- motion that exists only because animation was easy to add
## Execution Rules
- preserve the established design system when working inside an existing product
- match technical complexity to the visual idea
- keep accessibility and responsiveness intact
- frontends should feel deliberate on desktop and mobile
## Quality Gate
Before delivering:
- the interface has a clear visual point of view
- typography and spacing feel intentional
- color and motion support the product instead of decorating it randomly
- the result does not read like generic AI UI
- the implementation is production-grade, not just visually interesting