Components Rules
Component props, folder naming, structure consistency, and SVG icons
On This Page
component-props-destructure
Component props must be destructured in the function parameter
Why: Destructured props make it clear what props a component uses
export const Button = ({ label, onClick }) => ( <button onClick={onClick}>{label}</button>);export const Button = (props) => ( <button onClick={props.onClick}>{props.label}</button>);"code-style/component-props-destructure": "error"component-props-inline-type
Enforce inline type annotation for component props instead of interface reference
Why: Inline types keep prop definitions colocated with the component
export const Button = ({ label } : { label: string }) => ( <button>{label}</button>);export const Button = ({ label }: ButtonPropsInterface) => ( <button>{label}</button>);"code-style/component-props-inline-type": "error"folder-based-naming-convention
Enforce naming based on folder: suffix for views/layouts/pages/providers, camelCase for data/constants/strings/reducers/schemas. Services folder function exports drop the Service suffix (Handler from function-naming-convention is enough). Local/private variables are not checked.
Why: Consistent naming based on folder structure makes purpose immediately clear. Service suffix is redundant on function exports because Handler suffix already conveys callability — combining both yields ugly names like getDataServiceHandler when getDataHandler suffices. Plural file names that match the folder suffix (e.g., services/services.js) are deduped to avoid ServicesService.
Options
| Option | Type | Default | Description |
|---|---|---|---|
chainOrder | string | "child-parent" | Order of folder chain in names |
files | array | [] | Per-path chainOrder overrides |
"code-style/folder-based-naming-convention": ["error", { chainOrder: "child-parent", files: [] }]// views/dashboard.tsxexport const DashboardView = () => <div>Dashboard</div>; // services/services.js — function export, no Service suffixexport const getDataHandler = async () => fetch("/api"); // services/user-service.ts — class/object export, Service suffix keptexport class UserService { /* ... */ }// views/dashboard.tsxexport const Dashboard = () => <div>Dashboard</div>; // services/services.js — old behavior produced absurd chainexport const getDataServicesServiceHandlerServicesServiceHandler... = async () => {};"code-style/folder-based-naming-convention": "error"folder-structure-consistency
Enforce consistent folder structure (flat vs wrapped) in module folders
Why: Mixing flat files and wrapped folders creates inconsistency
Options
| Option | Type | Default | Description |
|---|---|---|---|
moduleFolders | string[] | (built-in list) | Module folders to check |
extraModuleFolders | string[] | [] | Additional folders to check |
"code-style/folder-structure-consistency": ["error", { moduleFolders: (built-in list), extraModuleFolders: [] }]atoms/input.tsxatoms/calendar.tsxatoms/input.tsxatoms/calendar/index.tsxatoms/calendar/helpers.ts"code-style/folder-structure-consistency": "error"no-redundant-folder-suffix
Disallow file/folder names that redundantly include the parent folder name as a suffix
Why: The folder already provides context, so the name doesn't need to repeat it
layouts/main.tsxlayouts/main-layout.tsx"code-style/no-redundant-folder-suffix": "error"no-scattered-component-variants
Disallow scattered component variants that share a trailing name token — collapse them into one folder named by the shared token
Why: Siblings like copy-button and icon-button repeat the same suffix on every name; collapsing them into button/{copy,icon}.tsx groups related variants and removes the redundant suffix
Options
| Option | Type | Default | Description |
|---|---|---|---|
moduleFolders | string[] | (built-in list) | Module folders to check |
extraModuleFolders | string[] | [] | Additional folders to check |
"code-style/no-scattered-component-variants": ["error", { moduleFolders: (built-in list), extraModuleFolders: [] }]ui/button/copy.tsxui/copy-button.tsx"code-style/no-scattered-component-variants": "error"svg-icon-naming-convention
SVG components must end with 'Icon' suffix; 'Icon' suffix components must return SVG
Why: Consistent naming makes it clear which components render icons
export const SuccessIcon = () => ( <svg><path d="M9 12l2 2 4-4" /></svg>);export const Success = () => ( <svg><path d="M9 12l2 2 4-4" /></svg>);"code-style/svg-icon-naming-convention": "error"