d48cda4081
CI / Test (ubuntu-latest, Node 18.x, bun) (push) Failing after 15m1s
CI / Test (ubuntu-latest, Node 18.x, npm) (push) Failing after 15m1s
CI / Test (ubuntu-latest, Node 18.x, pnpm) (push) Failing after 15m1s
CI / Test (ubuntu-latest, Node 18.x, yarn) (push) Failing after 15m1s
CI / Test (ubuntu-latest, Node 20.x, bun) (push) Failing after 17m13s
CI / Test (ubuntu-latest, Node 20.x, npm) (push) Failing after 18m42s
CI / Test (ubuntu-latest, Node 20.x, pnpm) (push) Failing after 15m0s
CI / Test (ubuntu-latest, Node 20.x, yarn) (push) Failing after 49m44s
CI / Test (ubuntu-latest, Node 22.x, bun) (push) Failing after 51m55s
CI / Test (ubuntu-latest, Node 22.x, pnpm) (push) Failing after 21m57s
CI / Test (ubuntu-latest, Node 22.x, npm) (push) Failing after 37m39s
CI / Test (ubuntu-latest, Node 22.x, yarn) (push) Failing after 34m7s
CI / Validate Components (push) Failing after 37m15s
CI / Python Tests (push) Failing after 10m1s
CI / Security Scan (push) Failing after 10m1s
CI / Lint (push) Failing after 17m12s
CI / Coverage (push) Failing after 20m19s
CI / Test (macos-latest, Node 18.x, bun) (push) Has been cancelled
CI / Test (macos-latest, Node 18.x, npm) (push) Has been cancelled
CI / Test (macos-latest, Node 18.x, pnpm) (push) Has been cancelled
CI / Test (macos-latest, Node 18.x, yarn) (push) Has been cancelled
CI / Test (windows-latest, Node 18.x, npm) (push) Has been cancelled
CI / Test (windows-latest, Node 18.x, pnpm) (push) Has been cancelled
CI / Test (windows-latest, Node 18.x, yarn) (push) Has been cancelled
CI / Test (macos-latest, Node 20.x, bun) (push) Has been cancelled
CI / Test (macos-latest, Node 20.x, npm) (push) Has been cancelled
CI / Test (macos-latest, Node 20.x, pnpm) (push) Has been cancelled
CI / Test (macos-latest, Node 20.x, yarn) (push) Has been cancelled
CI / Test (windows-latest, Node 20.x, npm) (push) Has been cancelled
CI / Test (windows-latest, Node 20.x, pnpm) (push) Has been cancelled
CI / Test (windows-latest, Node 20.x, yarn) (push) Has been cancelled
CI / Test (macos-latest, Node 22.x, bun) (push) Has been cancelled
CI / Test (macos-latest, Node 22.x, npm) (push) Has been cancelled
CI / Test (macos-latest, Node 22.x, pnpm) (push) Has been cancelled
CI / Test (macos-latest, Node 22.x, yarn) (push) Has been cancelled
CI / Test (windows-latest, Node 22.x, npm) (push) Has been cancelled
CI / Test (windows-latest, Node 22.x, pnpm) (push) Has been cancelled
CI / Test (windows-latest, Node 22.x, yarn) (push) Has been cancelled
4.3 KiB
4.3 KiB
paths
| paths | ||||||
|---|---|---|---|---|---|---|
|
React Coding Style
This file extends typescript/coding-style.md and common/coding-style.md with React specific content.
File Extensions
.tsxfor any file containing JSX, even one-liner snippets.tsfor pure logic, custom hooks without JSX, type definitions, utilities.test.tsx/.test.tsmirroring the source file- Use
.jsxonly when the project intentionally avoids TypeScript — flag every new untyped React file in review
Naming
- Components:
PascalCasefor both the symbol and the file (UserCard.tsx, default exportUserCard) - Custom hooks:
useCamelCasefor the symbol, kebab-case for the file when the project convention is kebab-case (use-debounce.tsexportsuseDebounce) - Context:
<Domain>Contextsymbol,<Domain>Providerprovider component,use<Domain>consumer hook - Event handlers:
handleClick,handleSubmitinside the component; the prop that receives it isonClick,onSubmit - Boolean props:
isLoading,hasError,canSubmit— neverloadingorerroralone for booleans
Component Shape
type Props = {
user: User;
onSelect: (id: string) => void;
};
export function UserCard({ user, onSelect }: Props) {
return (
<button type="button" onClick={() => onSelect(user.id)}>
{user.name}
</button>
);
}
- Prefer
type Props = {}for closed component prop shapes - Use
interfaceonly when the prop type is extended via declaration merging or exported as a public API extension point - Always destructure props in the parameter list — no
props.useraccess inside the body - Type the return implicitly through JSX (
function Foo(): JSX.Elementonly when the function returns conditionally and the union confuses inference)
JSX
- Self-close tags with no children:
<img />,<UserCard user={u} /> - Use fragments
<>...</>over wrapper<div>when no DOM element is needed - Conditional rendering:
{condition && <Foo />}for booleans, ternary for either/or, early return for guard clauses - Never put logic inline in JSX when it reads as multi-line — extract to a const above the return or a function
// Prefer
const greeting = user.isAdmin ? "Welcome, admin" : `Hello ${user.name}`;
return <h1>{greeting}</h1>;
// Over
return <h1>{user.isAdmin ? "Welcome, admin" : `Hello ${user.name}`}</h1>;
Server / Client Boundary (Next.js App Router, RSC)
- Default a new file to Server Component — only add
"use client"when the file uses state, effects, refs, browser APIs, or event handlers - Place the
"use client"directive on line 1, before any imports - Never import a Client Component file from inside a
"use server"action file - Never re-export server-only code through a client module — the bundler will silently include it
Imports
- React imports first:
import { useState } from "react" - Then third-party libs, then absolute project imports, then relative
- Type-only imports:
import type { ReactNode } from "react"— never mix runtime and type imports in one statement when ESLint'sconsistent-type-importsis configured
Hooks Discipline
See hooks.md for the full ruleset. Style highlights:
- Custom hooks must start with
use— enforced byeslint-plugin-react-hooks - Group all hook calls at the top of the component, before any conditional logic
- Avoid creating ad-hoc hooks for one-line wrappers — inline the call instead
State
- Local first (
useState), lift only when shared - Context for cross-cutting state read by many components (theme, auth, i18n) — not for high-frequency updates
- External store (Zustand, Jotai, Redux Toolkit) when state must persist across route changes, sync across tabs, or be debugged via devtools
- Never duplicate state that can be derived — compute during render
Class Components
Forbidden in new code. Convert legacy class components to function components when touching them for non-trivial changes.
File Layout per Component
components/UserCard/
UserCard.tsx
UserCard.module.css # or styled-components, or Tailwind classes inline
UserCard.test.tsx
index.ts # re-export only
Inline single-file components are fine for trivial presentational pieces.