@@ −22 +22 @@
### Composition over configuration
−Prefer small, composable components over monolithic components with many props:
+Prefer small, composable components over monolithic components with many props.
−```tsx
+(Examples omitted for brevity — keep the same composable vs prop-heavy example)
−// Composable — clear structure, extensible
−<Card>
− <Card.Header>
− <Card.Title>Title</Card.Title>
− <Card.Badge>New</Card.Badge>
− </Card.Header>
− <Card.Body>Content</Card.Body>
− <Card.Footer>
− <Button>Action</Button>
− </Card.Footer>
−</Card>
−
−// Avoid — prop-heavy, inflexible
−<Card
− title="Title"
− badge="New"
− body="Content"
− footerAction="Action"
− headerVariant="large"
− showBadge
−/>
−```
### Component categories
+Type / Purpose / State / Examples
+- Presentational — Render data, emit events — No internal state — Badge, Avatar, Skeleton
+- Container — Fetch/manage data, orchestrate — Owns state — UserList, DashboardPanel
+- Compound — Family of related sub-components — Shared context — Tabs, Accordion, Select
+- Layout — Structural arrangement — Minimal — Stack, Grid, Sidebar
−| Type | Purpose | State | Examples |
+- Utility — Provide behavior, no visible output — Internal state — ErrorBoundary, FocusTrap
−|------|---------|-------|---------|
−| Presentational | Render data, emit events | No internal state | Badge, Avatar, Skeleton |
−| Container | Fetch/manage data, orchestrate | Owns state | UserList, DashboardPanel |
−| Compound | Family of related sub-components | Shared context | Tabs, Accordion, Select |
−| Layout | Structural arrangement | Minimal | Stack, Grid, Sidebar |
−| Utility | Provide behavior, no visible output | Internal state | ErrorBoundary, FocusTrap |
−### Server vs. client component boundaries (Next.js)
+### Server vs. client component boundaries (Next.js and React Server Components)
+- Default: prefer Server Components for pages and layouts to reduce shipped JS and use server-side secrets safely. See Next.js App Router docs: https://nextjs.org/docs/app (last updated 2026-04-02).
+- Push `"use client"` as deep as possible: prefer small client wrappers that hold state/event handlers and keep larger UI tree server-rendered.
+- Pattern:
+ ServerPage (fetches data)
+ └─ ServerLayout (no JS shipped)
+ ├─ StaticContent (server)
+ └─ InteractiveWidget (client — "use client")
+ ├─ useState, useEffect
+ └─ Event handlers
−Push `"use client"` as deep as possible. The pattern:
+- Security note (critical, 2025): React Server Components and Server Functions had several high-severity vulnerabilities disclosed in December 2025 (CVE-2025-55182, CVE-2025-55184, CVE-2025-55183). React published fixes and follow-up patches. If your app uses RSC/Server Functions, upgrade the react-server-dom packages immediately to a patched version (e.g. 19.0.4, 19.1.5, or 19.2.4 or later as of 2025-12-11). Do not rely solely on hosting-provider mitigations — update dependencies and monitor CVE advisories (React blog posts: 2025-12-03 and 2025-12-11).
−
−```
−ServerPage (fetches data)
− └─ ServerLayout (no JS shipped)
− ├─ StaticContent (server)
− └─ InteractiveWidget (client — "use client")
− ├─ useState, useEffect
− └─ Event handlers
−```
## Workflow
@@ −79 +56 @@
### 2. Build compound components with context
−```tsx
+(Keep the Tabs example as-is — compound pattern with context and descriptive errors)
−import { createContext, useContext, useState } from "react";
−
−type TabsContextValue = {
− activeTab: string;
− setActiveTab: (tab: string) => void;
−};
−
−const TabsContext = createContext<TabsContextValue | null>(null);
−
−function useTabsContext() {
− const ctx = useContext(TabsContext);
− if (!ctx) throw new Error("Tabs compound components must be used within <Tabs>");
− return ctx;
−}
−
−function Tabs({ defaultTab, children }: { defaultTab: string; children: React.ReactNode }) {
− const [activeTab, setActiveTab] = useState(defaultTab);