بنقرة واحدة
add-component
Create a reusable UI component with factory pattern, theme compatibility, and proper cleanup
التثبيت باستخدام Codex أو Claude انسخ هذا Prompt والصقه في Codex أو Claude أو مساعد آخر ليراجع صفحة Skill ويثبّتها لك.
القائمة
Create a reusable UI component with factory pattern, theme compatibility, and proper cleanup
التثبيت باستخدام Codex أو Claude انسخ هذا Prompt والصقه في Codex أو Claude أو مساعد آخر ليراجع صفحة Skill ويثبّتها لك.
استنادا إلى تصنيف SOC المهني
| name | add-component |
| description | Create a reusable UI component with factory pattern, theme compatibility, and proper cleanup |
| aliases | ["new-component","create-component"] |
/add-component <ComponentName>
Does an existing component cover ~80% of the need?
→ Check src/ui/components/ before creating new
Existing: ArcadeButton, BasePetCard, GeminiIconButton, Modal, ProgressBar, SegmentedControl, SeeMore, SoundPicker, Tab, TeamListItem
Brief description (1 sentence):
What options does it need?
- Required: ___________
- Optional with defaults: ___________
- Event handlers: ___________
Does it display game sprites? → MGSprite.toCanvas()
Does it need reactive updates?
A) Manual setters only (setLabel, setDisabled, setValue, etc.)
B) Reactive to Globals (subscribe to myInventory, currentTile, weather, etc.)
C) Both
If B/C: Component subscribes to Globals and auto-updates UI
→ Remember to unsubscribe in destroy()!
Does this component need sub-components?
→ REUSE existing components, never recreate!
Available:
- ArcadeButton, GeminiIconButton → Buttons
- Modal → Dialogs/popups
- ProgressBar → Progress indicators
- SegmentedControl → Tab-like selection
- Tab → Tabs
- SoundPicker → Audio selection
- BasePetCard, TeamListItem → List items
- SeeMore → Expandable content
Example: A "SettingsPanel" component might use:
- SegmentedControl for sections
- Toggle for on/off settings
- ArcadeButton for actions
src/ui/components/<ComponentName>/
├── <ComponentName>.ts # Logic + factory function
├── <componentName>.css.ts # Styles (CSS string)
└── index.ts # Re-exports
Read existing components for templates: src/ui/components/*/
export interface <ComponentName>Options {
// Required (no default)
label: string;
// Optional (have defaults)
variant?: 'primary' | 'secondary';
disabled?: boolean;
// Event handlers
onClick?: () => void;
}
export interface <ComponentName>Handle {
root: HTMLElement; // REQUIRED
set<Property>(value): void; // Public setters (minimal)
destroy(): void; // REQUIRED - cleanup
}
export function create<ComponentName>(options: <ComponentName>Options): <ComponentName>Handle
/* NO hardcoded colors */
background: var(--color-bg);
color: var(--color-text);
border: 1px solid var(--color-border);
min-height: 44px; /* Touch-friendly */
width: 100%; /* Flexible, not fixed */
max-width: 300px; /* Constraint if needed */
/* Prefix all classes with component name */
.component-name { }
.component-name__label { }
.component-name--variant { }
src/ui/components/index.tsexport { create<ComponentName> } from './<ComponentName>/<ComponentName>';
export type { <ComponentName>Options, <ComponentName>Handle } from './<ComponentName>/<ComponentName>';
root: HTMLElement in Handledestroy() removes ALL listeners/observers/intervals:focus-visible)root, not document.headdestroy() called in parent's destroy()MGSprite.toCanvas() (never hardcoded paths)destroy() (memory leak otherwise!)import { createProgressBar, createArcadeButton } from '../index';
// In factory:
const progressBar = createProgressBar({ ... });
root.appendChild(progressBar.root);
// In destroy:
destroy() {
progressBar.destroy();
root.remove();
}
import { getMyInventory } from '../../../globals/variables/myInventory';
// In factory:
const unsub = getMyInventory().subscribe((inventory) => {
// Update UI when inventory changes
updateItemCount(inventory.items.length);
});
// In destroy - CRITICAL!
destroy() {
unsub(); // Unsubscribe from Global
root.remove();
}
.claude/rules/ui/components.mdsrc/ui/components/*/src/ui/theme/.claude/workflows/ui/component/reuse-existing-component.mdCreate a new card part within a section with factory/class pattern, Card wrapper, and proper cleanup
Add a new Jotai atom to the state system with type definitions, registry, and Store API access
Scaffold a new toggleable feature with full structure, storage, API exposure, and bootstrap registration
Create a reactive global variable that derives from atoms with subscription support
Create a game UI injection that modifies existing game elements with proper cleanup
Create a new core infrastructure module with standard API, lazy init, and proper structure