{
  "schema": "https://ai-atoms.com/schemas/skill-v1.json",
  "type": "skill",
  "id": "skill/plan-ui-change",
  "version": "1.0.1",
  "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.",
  "system_prompt_fragment": "# Plan a Blazor UI Change\n\nWhen 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.\n\n## Planning Workflow\n\n### Step 1 — Map the Visual Regions\n\nRead the request and identify every distinct visual region. Each region that has its own data, behavior, or layout responsibility is a candidate component.\n\nDraw the component tree:\n\n```\nInventoryDashboard          (page — owns data, orchestrates layout)\n├── StockSummaryBar         (read-only stats: total items, low-stock count, value)\n├── InventoryFilters        (search box, category dropdown, stock-level toggle)\n├── InventoryTable          (sortable table of products)\n│   └── InventoryRow        (single product row with inline edit/delete)\n└── AddProductForm          (slide-out form for new products)\n```\n\nRules for identifying components:\n- **Distinct responsibility** — a region owns its own state or behavior → separate component\n- **Repeated structure** — items in a list, cards in a grid → extract the item template\n- **Independent interactivity** — a section that handles user input separately from its siblings → separate component\n- **Size** — any section that would exceed ~150 lines of markup on its own → split it\n\n### Step 2 — Classify Each Component\n\nFor every component in the tree, determine:\n\n| Component | Action | Render Mode | State Owned | Lines (est.) |\n|-----------|--------|-------------|-------------|-------------|\n| InventoryDashboard | Create | InteractiveServer | product list, filter state | ~80 |\n| StockSummaryBar | Create | (inherits) | none — receives data | ~30 |\n| InventoryFilters | Create | (inherits) | search text, selected category | ~60 |\n| InventoryTable | Create | (inherits) | sort column, sort direction | ~50 |\n| InventoryRow | Create | (inherits) | inline-edit mode flag | ~60 |\n| AddProductForm | Create | (inherits) | form model | ~80 |\n\n**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.\n\n### Step 3 — Design Data Flow\n\nIdentify the **state owner** for each piece of data, then map how it flows:\n\n```\nInventoryDashboard (owns: products[], filters)\n  │\n  ├─ [Parameter] products ──→ StockSummaryBar (reads aggregate stats)\n  │\n  ├─ [Parameter] filters ──→ InventoryFilters\n  │   └─ EventCallback<Filters> OnFiltersChanged ──→ InventoryDashboard\n  │\n  ├─ [Parameter] filteredProducts ──→ InventoryTable\n  │   └─ [Parameter] product ──→ InventoryRow\n  │       ├─ EventCallback<Product> OnSave ──→ InventoryTable ──→ InventoryDashboard\n  │       └─ EventCallback<Product> OnDelete ──→ InventoryTable ──→ InventoryDashboard\n  │\n  └─ EventCallback<Product> OnProductAdded ←── AddProductForm\n```\n\nRules:\n- Data always flows **down** through `[Parameter]`\n- Events always flow **up** through `EventCallback<T>`\n- The page/parent **owns the data** and passes filtered/transformed views to children\n- Children **never mutate parameters** — they notify the parent via callbacks\n- If data must cross more than 2 levels without intermediate components needing it, use a cascading value or a scoped service\n\n### Step 4 — Identify Reuse Opportunities\n\nBefore creating a new component, check if an existing component in the project can serve the purpose. Look for:\n- Existing list-item components that match the structure\n- Shared filter/search components already in the project\n- Generic components (e.g., `DataTable<T>`, `Pagination`) that accept templates\n\nIf a component will be used in more than one page, place it in a `Shared/` or `Components/` folder.\n\n### Step 5 — Order the Implementation\n\nBuild bottom-up — leaf components first, then parents that compose them:\n\n1. **Models/DTOs** — define the data shapes\n2. **Services** — data access, business logic (interface + implementation)\n3. **Leaf components** — components with no children (InventoryRow, StockSummaryBar)\n4. **Container components** — components that compose leaves (InventoryTable, InventoryFilters)\n5. **Page component** — wires everything together, registers routes\n6. **Configuration** — DI registration, render mode setup\n\nEach component should be independently compilable. Never reference a component that doesn't exist yet.\n\n## Output Format\n\nPresent 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.\n\n```markdown\n## Component Plan: [Feature Name]\n\n### Component Tree\n[ASCII tree showing parent-child relationships]\n\n### Component Table\n| Component | Action | Render Mode | Purpose | Est. Lines |\n|-----------|--------|-------------|---------|------------|\n| ... | ... | ... | ... | ... |\n\n### Data Flow\n[State owner] → [Parameters down] → [EventCallbacks up]\n\n### Implementation Order\n1. [First file to create — why]\n2. [Second file — why]\n...\n```\n\nAfter outputting the plan, **immediately begin implementing** the components in the order listed. Do not wait for approval or ask \"shall I proceed?\" — the plan is a guide for you to follow, not a proposal for the user to approve.\n\n## Anti-Patterns to Avoid\n\n| Anti-Pattern | Why It's Wrong | Correct Approach |\n|-------------|----------------|-----------------|\n| One page component with 500+ lines | Impossible to test, reuse, or maintain | Decompose into focused components |\n| Passing 10+ parameters through intermediate components | Parameter drilling obscures intent | Use cascading values or a scoped state service |\n| Child component fetching its own data from an API | Multiple components making redundant calls | Parent owns data, passes via parameters |\n| Inline rendering of list items with complex markup | Duplicated logic, no reuse, hard to test | Extract item template into its own component |\n| Building everything in one file then \"refactoring later\" | Refactoring rarely happens; the monolith ships | Plan the decomposition upfront |\n| Generic components for one-off usage | Over-engineering adds complexity | Only extract generics when reuse is proven |\n\n## Guidelines\n\n- **Plan briefly, then implement.** Write a concise component table and data flow map, then immediately create the `.razor` files — never stop at just the plan.\n- **Prefer many small components over one large one.** A component with a single clear purpose is easier to understand, test, and reuse.\n- **State ownership is the first decision.** Before writing fetch logic, decide which component owns the data.\n- **Build bottom-up.** Create leaf components first so parent components can reference them immediately.\n- **Name components after what they render**, not what they do internally: `ProductCard` not `ProductRenderer`, `OrderFilters` not `FilterHandler`.",
  "applicable_domains": [
    "code",
    "dotnet",
    "engineering"
  ],
  "invocation": [
    "/plan-ui-change"
  ],
  "tags": [
    "dotnet-blazor",
    "dotnet",
    "csharp",
    "microsoft"
  ],
  "authored_by": "anthropics",
  "source_url": "https://github.com/dotnet/skills/blob/main/plugins/dotnet-blazor/skills/plan-ui-change/SKILL.md",
  "lifecycle": "stable",
  "category": "dotnet",
  "provenance": {
    "source": "dotnet/skills",
    "source_url": "https://github.com/dotnet/skills/blob/main/plugins/dotnet-blazor/skills/plan-ui-change/SKILL.md",
    "author": "Microsoft / .NET Foundation",
    "license": "MIT",
    "notes": "Imported by scripts/import-anthropic-skills.py."
  }
}