/plan-ui-change
Plan complex Blazor UI features by decomposing them into focused components. USE FOR: building a complex Blazor page with multiple sections, planning component decomposition, designing a multi-section dashboard or layout, breaking down a large UI feature into composable
Claude Code
$ npx -y skills add dotnet/skills --skill plan-ui-change --agent claude-code
Codex
$ npx skills add dotnet/skills --skill plan-ui-change -a codex -y
Cursor
$ npx skills add dotnet/skills --skill plan-ui-change -a cursor -y
Gemini CLI
$ npx skills add dotnet/skills --skill plan-ui-change -a gemini-cli -y
GitHub Copilot
$ npx skills add dotnet/skills --skill plan-ui-change -a github-copilot -y
OpenCode
$ npx skills add dotnet/skills --skill plan-ui-change -a opencode -y
Windsurf
$ npx skills add dotnet/skills --skill plan-ui-change -a windsurf -y
SKILL.md
plan-ui-change.SKILL.mdlicense: MIT
name: plan-ui-change
description: >
Plan complex Blazor UI features by decomposing them into focused components.
USE FOR: building a complex Blazor page with multiple sections, planning
component decomposition, designing a multi-section dashboard or layout,
breaking down a large UI feature into composable components, pages with
sidebars and content panels, any page with 3+ distinct visual sections
or multiple interacting sub-features, identifying parent-child relationships
and data flow.
DO NOT USE FOR: creating new Blazor projects or apps from scratch
(use create-blazor-project), implementing a single individual component
(use author-component), writing component code with parameters and
EventCallback (use author-component), or simple single-component pages.
Plan a Blazor UI Change
When asked to build a complex UI feature, **plan the component decomposition first, then immediately implement it**. A single monolithic page component is almost never the right answer — break the UI into focused, composable components.
Planning Workflow
Step 1 — Map the Visual Regions
Read the request and identify every distinct visual region. Each region that has its own data, behavior, or layout responsibility is a candidate component.
Draw the component tree:
InventoryDashboard (page — owns data, orchestrates layout)
├── StockSummaryBar (read-only stats: total items, low-stock count, value)
├── InventoryFilters (search box, category dropdown, stock-level toggle)
├── InventoryTable (sortable table of products)
│ └── InventoryRow (single product row with inline edit/delete)
└── AddProductForm (slide-out form for new products)
Rules for identifying components:
- **Distinct responsibility** — a region owns its own state or behavior → separate component
- **Repeated structure** — items in a list, cards in a grid → extract the item template
- **Independent interactivity** — a section that handles user input separately from its siblings → separate component
- **Size** — any section that would exceed ~150 lines of markup on its own → split it
Step 2 — Classify Each Component
For every component in the tree, determine:
| Component | Action | Render Mode | State Owned | Lines (est.) | |-----------|--------|-------------|-------------|-------------| | InventoryDashboard | Create | InteractiveServer | product list, filter state | ~80 | | StockSummaryBar | Create | (inherits) | none — receives data | ~30 | | InventoryFilters | Create | (inherits) | search text, selected category | ~60 | | InventoryTable | Create | (inherits) | sort column, sort direction | ~50 | | InventoryRow | Create | (inherits) | inline-edit mode flag | ~60 | | AddProductForm | Create | (inherits) | form model | ~80 |
**A page component that exceeds ~200 lines of combined markup + code is too large.** If your estimate puts a single component above that, split further.
Step 3 — Design Data Flow
Identify the **state owner** for each piece of data, then map how it flows:
InventoryDashboard (owns: products[], filters)
│
├─ [Parameter] products ──→ StockSummaryBar (reads aggregate stats)
│
├─ [Parameter] filters ──→ InventoryFilters
│ └─ EventCallback<Filters> OnFiltersChanged ──→ InventoryDashboard
│
├─ [Parameter] filteredProducts ──→ InventoryTable
│ └─ [Parameter] product ──→ InventoryRow
│ ├─ EventCallback<Product> OnSave ──→ InventoryTable ──→ InventoryDashboard
│ └─ EventCallback<Product> OnDelete ──→ InventoryTable ──→ InventoryDashboard
│
└─ EventCallback<Product> OnProductAdded ←── AddProductForm
Rules:
- Data always flows **down** through `[Parameter]`
- Events always flow **up** through `EventCallback<T>`
- The page/parent **owns the data** and passes filtered/transformed views to children
- Children **never mutate parameters** — they notify the parent via callbacks
- If data must cross more than 2 levels without intermediate components needing it, use a cascading value or a scoped service
Step 4 — Identify Reuse Opportunities
Before creating a new component, check if an existing component in the project can serve the purpose. Look for:
- Existing list-item components that match the structure
- Shared filter/search components already in the project
- Generic components (e.g., `DataTable<T>`, `Pagination`) that accept templates
If a component will be used in more than one page, place it in a `Shared/` or `Components/` folder.
Step 5 — Order the Implementation
Build bottom-up — leaf components first, then parents that compose them:
1. **Models/DTOs** — define the data shapes 2. **Services** — data access, business logic (interface + implementation) 3. **Leaf components** — components with no children (InventoryRow, StockSummaryBar) 4. **Container components** — components that compose leaves (InventoryTable, InventoryFilters) 5. **Page component** — wires everything together, registers routes 6. **Configuration** — DI registration, render mode setup
Each component should be independently compilable. Never reference a component that doesn't exist yet.
Output Format
Present the plan briefly, then **immediately proceed to implement** — never stop at just the plan or ask for confirmation before writing code. The plan is a thinking tool, not a deliverable.
## Component Plan: [Feature Name]
### Component Tree
[ASCII tree showing parent-child relationships]
### Component Table
| Component | Action | Render Mode | Purpose | Est. Lines |
|-----------|--------|-------------|---------|------------|
| ... | ... | ... | ... | ... |
### Data Flow
[State owner] → [Parameters down] → [EventCallbacks up]
### Implementation Order
1. [First file to create — why]
2. [Second file — why]
...
After outputting the plan, **immediately begin implementing** the components in the order listed. Do not wait for approval or ask "shall I proceed?" — the
Read more
license: MIT name: plan-ui-change description: > Plan complex Blazor UI features by decomposing them into focused components. USE FOR: building a complex Blazor page with multiple sections, planning component decomposition, designing a multi-section dashboard or layout, breaking down a large UI feature into composable components, pages with sidebars and content panels, any page with 3+ distinct visual sections or multiple interacting sub-features, identifying parent-child relationships and data flow. DO NOT USE FOR: creating new Blazor projects or apps from scratch (use create-blazor-project), implementing a single individual component (use author-component), writing component code with parameters and EventCallback (use author-component), or simple single-component pages.
Plan a Blazor UI Change
When asked to build a complex UI feature, **plan the component decomposition first, then immediately implement it**. A single monolithic page component is almost never the right answer — break the UI into focused, composable components.
Planning Workflow
Step 1 — Map the Visual Regions
Read the request and identify every distinct visual region. Each region that has its own data, behavior, or layout responsibility is a candidate component.
Draw the component tree:
InventoryDashboard (page — owns data, orchestrates layout) ├── StockSummaryBar (read-only stats: total items, low-stock count, value) ├── InventoryFilters (search box, category dropdown, stock-level toggle) ├── InventoryTable (sortable table of products) │ └── InventoryRow (single product row with inline edit/delete) └── AddProductForm (slide-out form for new products)
Rules for identifying components:
- **Distinct responsibility** — a region owns its own state or behavior → separate component
- **Repeated structure** — items in a list, cards in a grid → extract the item template
- **Independent interactivity** — a section that handles user input separately from its siblings → separate component
- **Size** — any section that would exceed ~150 lines of markup on its own → split it
Step 2 — Classify Each Component
For every component in the tree, determine:
| Component | Action | Render Mode | State Owned | Lines (est.) | |-----------|--------|-------------|-------------|-------------| | InventoryDashboard | Create | InteractiveServer | product list, filter state | ~80 | | StockSummaryBar | Create | (inherits) | none — receives data | ~30 | | InventoryFilters | Create | (inherits) | search text, selected category | ~60 | | InventoryTable | Create | (inherits) | sort column, sort direction | ~50 | | InventoryRow | Create | (inherits) | inline-edit mode flag | ~60 | | AddProductForm | Create | (inherits) | form model | ~80 |
**A page component that exceeds ~200 lines of combined markup + code is too large.** If your estimate puts a single component above that, split further.
Step 3 — Design Data Flow
Identify the **state owner** for each piece of data, then map how it flows:
InventoryDashboard (owns: products[], filters) │ ├─ [Parameter] products ──→ StockSummaryBar (reads aggregate stats) │ ├─ [Parameter] filters ──→ InventoryFilters │ └─ EventCallback<Filters> OnFiltersChanged ──→ InventoryDashboard │ ├─ [Parameter] filteredProducts ──→ InventoryTable │ └─ [Parameter] product ──→ InventoryRow │ ├─ EventCallback<Product> OnSave ──→ InventoryTable ──→ InventoryDashboard │ └─ EventCallback<Product> OnDelete ──→ InventoryTable ──→ InventoryDashboard │ └─ EventCallback<Product> OnProductAdded ←── AddProductForm
Rules:
- Data always flows **down** through `[Parameter]`
- Events always flow **up** through `EventCallback<T>`
- The page/parent **owns the data** and passes filtered/transformed views to children
- Children **never mutate parameters** — they notify the parent via callbacks
- If data must cross more than 2 levels without intermediate components needing it, use a cascading value or a scoped service
Step 4 — Identify Reuse Opportunities
Before creating a new component, check if an existing component in the project can serve the purpose. Look for:
- Existing list-item components that match the structure
- Shared filter/search components already in the project
- Generic components (e.g., `DataTable<T>`, `Pagination`) that accept templates
If a component will be used in more than one page, place it in a `Shared/` or `Components/` folder.
Step 5 — Order the Implementation
Build bottom-up — leaf components first, then parents that compose them:
1. **Models/DTOs** — define the data shapes 2. **Services** — data access, business logic (interface + implementation) 3. **Leaf components** — components with no children (InventoryRow, StockSummaryBar) 4. **Container components** — components that compose leaves (InventoryTable, InventoryFilters) 5. **Page component** — wires everything together, registers routes 6. **Configuration** — DI registration, render mode setup
Each component should be independently compilable. Never reference a component that doesn't exist yet.
Output Format
Present the plan briefly, then **immediately proceed to implement** — never stop at just the plan or ask for confirmation before writing code. The plan is a thinking tool, not a deliverable.
## Component Plan: [Feature Name] ### Component Tree [ASCII tree showing parent-child relationships] ### Component Table | Component | Action | Render Mode | Purpose | Est. Lines | |-----------|--------|-------------|---------|------------| | ... | ... | ... | ... | ... | ### Data Flow [State owner] → [Parameters down] → [EventCallbacks up] ### Implementation Order 1. [First file to create — why] 2. [Second file — why] ...
After outputting the plan, **immediately begin implementing** the components in the order listed. Do not wait for approval or ask "shall I proceed?" — the
This repository contains the .NET team's curated set of portable skills and host-specific custom agents for coding agents. For information about the Agent Skills standard, see agentskills.io.
Other skills on skills.
More skills from other plugins.
brainstorming
You MUST use this before any creative work - creating features, building components, adding functionality, modifying behavior, or…
ask-matt
Ask which skill or flow fits your situation. A router over the skills in this repo.
Questions about plan-ui-change.
- Which coding agents can use plan-ui-change?
- plan-ui-change installs in Claude Code, Codex, Cursor, Gemini CLI, GitHub Copilot, OpenCode and Windsurf with the skills CLI, using each agent's flag shown on this page. Flowy's auto-invocation, which fires a skill when your prompt matches, runs in Claude Code only.

