| name | add-section |
| description | Create a new HUD section (tab) with lifecycle, persistent state, and registry registration |
| aliases | ["new-section","create-section"] |
Add Section Skill
Usage
/add-section <SectionName>
Step 1: Ask Questions
1. Section Purpose
Brief description (1 sentence):
What does this section display/manage?
2. Persistent State
What state needs to persist across sessions?
(Must be JSON-serializable: strings, numbers, booleans, arrays, plain objects)
Examples:
- Selected tab/filter
- Sort order
- Collapsed/expanded states
- User preferences
3. Game Data
Does this section need game data?
A) Static data → MGData (plants, items, pets, etc.)
B) Real-time state → Globals (myInventory, myGarden, etc.)
C) Both
D) None
4. Sprites
Does it display game sprites? → MGSprite.toCanvas()
5. Child Components
Does it need existing UI components?
→ REUSE from src/ui/components/
[ ] ArcadeButton, GeminiIconButton → Buttons
[ ] Modal → Dialogs
[ ] ProgressBar → Progress
[ ] SegmentedControl → Tab-like selection
[ ] Tab → Tabs
[ ] SoundPicker → Audio
[ ] Other: ___
6. Complexity
A) Simple - Single file section
B) Complex - Split into parts/ folder
7. Tab Info
- Label (displayed in tab bar): ___________
- Icon (emoji): ___________
Step 2: Create Structure
Simple Section
src/ui/sections/<SectionName>/
├── index.ts # Public exports
├── section.ts # build() / destroy() lifecycle
├── state.ts # Persistent state (createSectionStore)
└── styles.css.ts # Scoped CSS (optional)
Complex Section (with parts)
src/ui/sections/<SectionName>/
├── index.ts
├── section.ts # Assembles parts
├── state.ts
├── styles.css.ts
└── parts/
├── header.ts # Search, filters
├── content.ts # Main content
└── footer.ts # Actions
Read existing sections for templates: src/ui/sections/*/
Step 3: File Responsibilities
| File | Purpose |
|---|
index.ts | Export <Name>Section and types only |
section.ts | build(container), destroy(), cleanups[] |
state.ts | createSectionStore() with stable ID tab-<name> |
styles.css.ts | CSS string with scoped classes |
parts/*.ts | Sub-components with own destroy() |
Key Patterns
state.ts
import { createSectionStore } from '../core/state';
export interface <Name>State {
selectedTab: string;
sortOrder: 'asc' | 'desc';
}
const DEFAULT_STATE: <Name>State = {
selectedTab: 'all',
sortOrder: 'asc',
};
export const state = createSectionStore<<Name>State>('tab-<name>', {
version: 1,
defaults: DEFAULT_STATE,
});
section.ts
export interface SectionDefinition {
build(container: HTMLElement): void;
destroy(): void;
}
let root: HTMLElement | null = null;
const cleanups: (() => void)[] = [];
function build(container: HTMLElement): void {
if (root) return;
root = document.createElement('div');
root.className = '<name>-section';
const style = document.createElement('style');
style.textContent = <name>Css;
root.appendChild(style);
const unsub = state.subscribe((s) => { });
cleanups.push(unsub);
container.appendChild(root);
}
function destroy(): void {
cleanups.forEach(fn => fn());
cleanups.length = 0;
root?.remove();
root = null;
}
export const <Name>Section: SectionDefinition = { build, destroy };
Step 4: Register
Registry → src/ui/sections/registry.ts
import { <Name>Section } from './<SectionName>';
export const sectionRegistry: Record<string, SectionConfig> = {
'tab-<name>': {
id: 'tab-<name>',
label: '<Label>',
icon: '<emoji>',
section: <Name>Section,
},
};
Step 5: Validate
Structure
State
Lifecycle
Styling
Game Data (if applicable)
Components (if applicable)
Registration
Existing Sections
For reference/templates:
Settings - User preferences
AutoFavoriteSettings - Feature config
JournalChecker - Journal progress
Pets - Pet management
Trackers - Stats tracking
Alerts - Notifications config
Dev - Developer tools
Test - Testing section
References
- Rules:
.claude/rules/ui/sections.md
- Existing sections:
src/ui/sections/*/
- Core state:
src/ui/sections/core/state.ts
- UI Components:
src/ui/components/
- Split workflow:
.claude/workflows/ui/section/split-section-into-parts.md