--- name: react-component description: Guide for creating React components following project conventions — memo pattern, TypeScript props, Tailwind styling, accessibility. Use when creating new components, refactoring existing ones, or when the user asks about component patterns. --- # React Component Creation ## Component Template Every component follows this pattern: ```tsx import { memo, useCallback } from 'react'; type MyComponentProps = { title: string; onClick?: () => void; className?: string; }; function MyComponentInner({ title, onClick, className = '' }: MyComponentProps) { const handleClick = useCallback(() => { onClick?.(); }, [onClick]); return (

{title}

); } export const MyComponent = memo(MyComponentInner); ``` ## Rules 1. **Naming**: `ComponentNameInner` for the function, `ComponentName` for the memo export 2. **Props**: Use `type` (not `interface`) for props. Always define explicitly — no inline destructuring types 3. **Export**: Named export only. No `export default` (except `App.tsx`) 4. **Memo**: Always wrap with `React.memo` via the `memo` import 5. **Hooks**: Use `useCallback` for handlers in memoized components. Use `useState` with explicit generic type 6. **Imports**: Use `@/` path alias: `import { Button } from '@/components/Button'` 7. **File location**: `src/components/` for reusable components, `src/pages/` for route-level pages ## Accessibility - Add `role` attributes where semantics are unclear (e.g., `role="banner"` on header) - Use `aria-label` on interactive elements without visible text - Mark decorative elements with `aria-hidden` - Use `sr-only` class for screen-reader-only content - Provide `id` + `aria-labelledby` for section headings ## Dark Mode Every component must support both themes: - Pair light/dark classes: `bg-white dark:bg-gray-900`, `text-slate-900 dark:text-white` - Use semantic color tokens from Tailwind config: `text-primary`, `bg-primary`, `text-secondary` - Borders: `border-gray-200 dark:border-gray-800` ## Icons Use Google Material Symbols via class names: ```tsx arrow_forward ``` ## Images - Always include `alt` text in Russian - Add `loading="lazy"` for below-the-fold images - Use external URLs (Google hosted images) or future `/api/files/` endpoint