--- name: ogt-docs-rules-code-front description: Define and manage frontend coding standards in docs/rules/code/front/. Use when creating React component rules, state management patterns, styling conventions, hook guidelines, or any frontend-specific code rules. --- # OGT Docs - Rules Code Front Frontend-specific coding standards for React/TypeScript applications. ## Overview Frontend rules establish consistent patterns for React components, state management, styling, and client-side architecture. ```mermaid flowchart TB subgraph front ["docs/rules/code/front/"] COMP["components/"] STATE["state/"] HOOKS["hooks/"] STYLE["styling/"] ROUTE["routing/"] FETCH["data_fetching/"] end COMP --> |patterns| C1["composition"] COMP --> |patterns| C2["props"] STATE --> |patterns| S1["context"] STATE --> |patterns| S2["local"] HOOKS --> |patterns| H1["custom"] STYLE --> |patterns| ST1["css-in-js"] ``` ## When to Use - Creating React component standards - Defining state management patterns - Establishing styling conventions - Writing custom hook guidelines - Setting data fetching patterns - Defining routing conventions ## Folder Structure ``` docs/rules/code/front/ ├── components/ # Component patterns │ ├── composition/ │ │ ├── rule.md │ │ └── examples.md │ ├── props/ │ │ ├── rule.md │ │ └── examples.md │ ├── naming/ │ │ ├── rule.md │ │ └── examples.md │ └── file_structure/ │ ├── rule.md │ └── examples.md │ ├── state/ # State management │ ├── local_state/ │ │ ├── rule.md │ │ └── examples.md │ ├── context/ │ │ ├── rule.md │ │ └── examples.md │ └── derived_state/ │ ├── rule.md │ └── examples.md │ ├── hooks/ # Custom hooks │ ├── naming/ │ │ ├── rule.md │ │ └── examples.md │ ├── dependencies/ │ │ ├── rule.md │ │ └── examples.md │ └── patterns/ │ ├── rule.md │ └── examples.md │ ├── styling/ # CSS/Styling │ ├── approach/ │ │ ├── rule.md │ │ └── examples.md │ ├── naming/ │ │ ├── rule.md │ │ └── examples.md │ └── responsive/ │ ├── rule.md │ └── examples.md │ ├── data_fetching/ # Data fetching │ ├── patterns/ │ │ ├── rule.md │ │ └── examples.md │ └── error_handling/ │ ├── rule.md │ └── examples.md │ └── routing/ # Routing ├── structure/ │ ├── rule.md │ └── examples.md └── navigation/ ├── rule.md └── examples.md ``` --- ## Example: docs/rules/code/front/components/composition/ Component composition patterns. ### rule.md ````markdown # Rule: Component Composition ## Summary Components MUST use composition over prop drilling for flexible, reusable designs. ## Rationale Composition patterns: - Reduce prop drilling - Increase reusability - Improve testability - Enable flexible layouts ## The Rules ### 1. Prefer Children Over Props **SHOULD** pass content via children rather than render props. ```tsx // PREFERRED Title Content // AVOID Title} body={Content} /> ``` ```` ### 2. Use Compound Components **SHOULD** use compound component pattern for related components. ```tsx // CORRECT - compound components // AVOID - array of objects setQuery(e.target.value)} />; } // INCORRECT - state lifted unnecessarily function App() { const [searchQuery, setSearchQuery] = useState(""); return ; } ``` ### 3. Derive Don't Duplicate **MUST** derive state from existing state rather than duplicating. ```tsx // CORRECT - derived const [items, setItems] = useState([]); const completedCount = items.filter((i) => i.completed).length; // INCORRECT - duplicated state const [items, setItems] = useState([]); const [completedCount, setCompletedCount] = useState(0); // Now you have to keep them in sync! ``` ### 4. Use Appropriate Hook | Scenario | Hook | | -------------------------------- | ---------------------------------- | | Simple value | `useState` | | Complex object with many updates | `useReducer` | | Previous value needed | `useRef` + `useState` | | Derived async data | `useMemo` or data fetching library | ## Examples ### Correct: Appropriate State Location ```tsx // Form with local state function ContactForm() { const [name, setName] = useState(""); const [email, setEmail] = useState(""); const [message, setMessage] = useState(""); // Derived state const isValid = name.length > 0 && email.includes("@"); return (
setName(e.target.value)} /> setEmail(e.target.value)} />