### Install eslint-plugin-sweepit and ESLint
Source: https://github.com/jjenzz/sweepi/blob/main/packages/eslint-plugin-sweepit/README.md
Installs the necessary packages for using eslint-plugin-sweepit and ESLint as development dependencies.
```bash
npm install --save-dev eslint-plugin-sweepit eslint
```
--------------------------------
### Refactoring Example: Before and After
Source: https://github.com/jjenzz/sweepi/blob/main/packages/eslint-plugin-sweepit/docs/rules/jsx-flat-owner-tree.md
This TypeScript/JSX code provides a side-by-side comparison of a component structure before and after applying the `jsx-flat-owner-tree` rule's principles. The 'before' example shows a deep, problematic chain, while the 'after' example demonstrates the refactored, flatter structure using compound components.
```tsx
// before
function Root() {
return ;
}
function Page() {
return (
);
}
function Header() {
return (
);
}
// after
function Root() {
return (
);
}
```
--------------------------------
### Initialize Sweepi Toolchain CLI
Source: https://context7.com/jjenzz/sweepi/llms.txt
Initializes the Sweepi toolchain in `~/.sweepi` by creating the directory, writing ESLint configuration, and installing necessary dependencies. The `--force` option can be used to reset an existing installation.
```bash
sweepi init
sweepi init --force
```
--------------------------------
### Install Sweepi Globally
Source: https://github.com/jjenzz/sweepi/blob/main/README.md
Install the Sweepi package globally using npm. This is recommended for users who plan to perform audits frequently, as it offers faster execution compared to using npx for each run.
```bash
npm install --global sweepi
```
--------------------------------
### Basic ESLint Flat Config Setup
Source: https://context7.com/jjenzz/sweepi/llms.txt
Configures ESLint using the flat config system by importing and spreading the pre-configured rule sets from the `eslint-plugin-sweepit` package. This setup enables both core and React-specific Sweepi rules.
```javascript
import sweepit from 'eslint-plugin-sweepit';
export default [
...sweepit.configs.core,
...sweepit.configs.react
];
```
--------------------------------
### Example Core ESLint Config Contents
Source: https://context7.com/jjenzz/sweepi/llms.txt
Illustrates the types of rules included in the `sweepit.configs.core` configuration, focusing on TypeScript, functional programming, and general code quality checks. The example code demonstrates how these rules might flag issues like mutable data or uninitialized variables.
```javascript
// What configs.core includes:
// - sonarjs.configs.recommended from eslint-plugin-sonarjs
// - functional/immutable-data with ignoreAccessorPattern: ['*.displayName', '*.current']
// - no-param-reassign with { props: true }
// - prefer-const
// - @typescript-eslint/switch-exhaustiveness-check
// - complexity with { max: 5, variant: 'modified' }
// Example: core config detects these issues
function process(data) {
let result = []; // error: prefer-const
data.items = []; // error: functional/immutable-data
data = null; // error: no-param-reassign
return result;
}
```
--------------------------------
### Initialize Sweepi (Bash)
Source: https://github.com/jjenzz/sweepi/blob/main/packages/sweepi/README.md
Initializes Sweepi by creating the ~/.sweepi directory, writing the default ESLint configuration, and installing necessary dependencies like eslint and eslint-plugin-sweepit. It also adds the Sweepi skill.
```bash
npx sweepi init
```
--------------------------------
### Initialize Sweepi Toolchain (TypeScript)
Source: https://context7.com/jjenzz/sweepi/llms.txt
Initializes the Sweepi toolchain programmatically. Allows customization of the home directory, forces a reset of the installation, and provides a status callback for progress updates. Returns the toolchain directory and installation status.
```typescript
import { initializeToolchain } from 'sweepi';
const result = await initializeToolchain({
homeDirectory: '/custom/home', // optional, defaults to os.homedir()
forceReset: false, // optional, removes existing installation
onStatus: (message) => { // optional, status callback
console.log(message);
},
});
console.log(result.toolchainDirectory); // ~/.sweepi
console.log(result.installedDependencies); // true if fresh install
```
--------------------------------
### Correct JSX handler prop naming examples
Source: https://github.com/jjenzz/sweepi/blob/main/packages/eslint-plugin-sweepit/docs/rules/jsx-on-handler-verb-suffix.md
These examples illustrate correct usage of the 'jsx-on-handler-verb-suffix' rule. They show handler props that adhere to the convention of ending with a verb, such as 'onValueChange' or 'onClick'. This includes standard HTML event handlers and custom ones following the pattern.
```tsx
```
--------------------------------
### JSX Examples for kebab-case props
Source: https://github.com/jjenzz/sweepi/blob/main/packages/eslint-plugin-sweepit/docs/rules/no-custom-kebab-case-props.md
Illustrates incorrect and correct usage of kebab-case props in JSX. Incorrect examples show disallowed custom kebab-case props, while correct examples demonstrate allowed native HTML attributes and camelCase props.
```jsx
// Incorrect
// Correct
```
--------------------------------
### Migration Example: Private Context Hook and Exported Props (TypeScript)
Source: https://github.com/jjenzz/sweepi/blob/main/packages/eslint-plugin-sweepit/docs/rules/no-exported-context-hooks.md
Provides a before-and-after example of migrating an exported context hook to a private one, with exported interface for component props. This demonstrates how to fix violations of the `no-exported-context-hooks` rule.
```typescript
// before
export function useDialogContext() {
return useContext(DialogContext);
}
// after
function useDialogContext() {
return useContext(DialogContext);
}
export interface DialogRootProps {
open: boolean;
onOpenChange: (open: boolean) => void;
}
```
--------------------------------
### Lint All Files CLI
Source: https://context7.com/jjenzz/sweepi/llms.txt
Lints all TypeScript files (`.ts` and `.tsx`) within a specified project directory. This command can be executed directly or via `npx` if Sweepi is not globally installed.
```bash
sweepi ./path/to/project --all
npx sweepi . --all
```
--------------------------------
### Add Sweepi LLM Skill
Source: https://github.com/jjenzz/sweepi/blob/main/README.md
Install the Sweepi LLM skill using npx. This command integrates Sweepi's linting capabilities with your LLM environment, allowing you to prompt the LLM to lint changes.
```bash
npx skills add jjenzz/sweepi
```
--------------------------------
### Run Sweepi CLI
Source: https://github.com/jjenzz/sweepi/blob/main/README.md
Execute the Sweepi command-line interface to lint code. This can be done directly using npx for a single run or after a global installation for repeated use. The CLI accepts a project path as an argument.
```shell
npx sweepi
```
```shell
sweepi ./path/to/project
```
--------------------------------
### Sweepi Skill Workflow Example (Markdown)
Source: https://context7.com/jjenzz/sweepi/llms.txt
This section outlines the workflow for using the Sweepi skill with LLM agents, emphasizing mandatory verification steps for lint-fix operations. It details when to run the skill, the required steps from running the linter to applying fixes, and provides a template for reporting detected lint rules and planned fixes.
```markdown
## When to Run Sweepi Skill
1. User explicitly asks to run `sweepi`
2. About to commit or recommend committing code changes
3. Linting code or user asks to lint
## Required Workflow
1. Run: `sweepi .` (or `npx sweepi .` if not installed)
2. Parse all reported issues
3. For each rule violation, fetch docs from:
https://raw.githubusercontent.com/jjenzz/sweepi/main/packages/eslint-plugin-sweepit/docs/rules/.md
4. Apply fixes matching documented intent
5. Re-run until issues resolved
## Response Template (Before Any Edit)
### Lint Rules Detected
- `sweepit/no-object-props`
- `sweepit/no-boolean-capability-props`
### Rule Analysis
- **Rule:** `sweepit/no-object-props`
- **Doc URL:** ``
- **Key requirement(s):** "Replace object-typed members with explicit primitive members"
- **Planned compliant fix:** Extract user.name and user.email to separate props
- **Behavior preserved:** yes - same data flows, different shape
### Edit Safety Check
- **Functionality removed?** no
- **API changes?** yes - prop shape changes, migration: pass name/email directly
- **Ready to implement?** yes
```
--------------------------------
### Fixing incorrect JSX handler prop naming
Source: https://github.com/jjenzz/sweepi/blob/main/packages/eslint-plugin-sweepit/docs/rules/jsx-on-handler-verb-suffix.md
This example shows the transformation from an incorrect handler prop name to a correct one, as suggested by the 'jsx-on-handler-verb-suffix' rule. It illustrates reordering the suffix to end with a verb, improving consistency and readability.
```tsx
// before
// after
```
--------------------------------
### Correct use of 'use' prefix for hook functions (TypeScript)
Source: https://github.com/jjenzz/sweepi/blob/main/packages/eslint-plugin-sweepit/docs/rules/no-useless-hook.md
Shows examples of functions correctly prefixed with 'use' that incorporate actual React hook calls. These adhere to the convention by using useState, useEffect, or useContext.
```typescript
function useUser() {
const [user, setUser] = useState(null);
useEffect(() => {
fetchUser().then(setUser);
}, []);
return user;
}
const formatDate = (d: Date) => d.toISOString();
function useConfig() {
const config = useContext(ConfigContext);
return config;
}
```
--------------------------------
### Configure no-custom-kebab-case-props rule
Source: https://github.com/jjenzz/sweepi/blob/main/packages/eslint-plugin-sweepit/docs/rules/no-custom-kebab-case-props.md
This JSON configuration demonstrates how to enable and configure the `no-custom-kebab-case-props` rule in a linting setup. It shows how to extend allowed prefixes and specify exact allowed props.
```json
{
"rules": {
"sweepit/no-custom-kebab-case-props": [
"error",
{
"extendPrefixes": ["x-"],
"allowedProps": ["feature-flag-enabled"]
}
]
}
}
```
--------------------------------
### Incorrect JSX handler prop naming examples
Source: https://github.com/jjenzz/sweepi/blob/main/packages/eslint-plugin-sweepit/docs/rules/jsx-on-handler-verb-suffix.md
These examples demonstrate incorrect usage of the 'jsx-on-handler-verb-suffix' rule. They show handler props that do not end with a recognized verb, violating the rule's convention. This includes patterns like 'on{Subject}{Action}' or arbitrary suffixes.
```tsx
```
--------------------------------
### Fixing Async Prop Naming (TypeScript)
Source: https://github.com/jjenzz/sweepi/blob/main/packages/eslint-plugin-sweepit/docs/rules/jsx-server-action-prop-suffix.md
Shows a before and after example of how to refactor a prop to comply with the rule. The 'onSubmit' prop, which had an async return type, is renamed to 'submitAction' to meet the naming convention.
```typescript
// before
interface FormProps {
onSubmit: () => Promise;
}
// after
interface FormProps {
submitAction: () => Promise;
}
```
--------------------------------
### Renaming Utility Function to Comply with 'no-set-prefix-utils'
Source: https://github.com/jjenzz/sweepi/blob/main/packages/eslint-plugin-sweepit/docs/rules/no-set-prefix-utils.md
Provides a before-and-after example of refactoring a utility function to comply with the 'no-set-prefix-utils' ESLint rule. The function's name is changed from 'setPrefix' to 'applyPrefix' to reserve 'set*' for React state setters.
```typescript
// before
const setPrefix = (str: string) => str.toUpperCase();
// after
const applyPrefix = (str: string) => str.toUpperCase();
```
--------------------------------
### Fixing non-hook utility function naming (TypeScript)
Source: https://github.com/jjenzz/sweepi/blob/main/packages/eslint-plugin-sweepit/docs/rules/no-useless-hook.md
Illustrates how to refactor a function that was incorrectly named with the 'use' prefix. The example shows renaming it to a more appropriate name like 'getConfig' when it does not utilize React hooks.
```typescript
// before
function useConfig() {
return { theme: 'dark' };
}
// after (non-hook utility)
function getConfig() {
return { theme: 'dark' };
}
```
--------------------------------
### Correct JSX handler prop naming with custom verbs
Source: https://github.com/jjenzz/sweepi/blob/main/packages/eslint-plugin-sweepit/docs/rules/jsx-on-handler-verb-suffix.md
This example demonstrates correct JSX handler prop naming when custom verbs are extended. It shows a handler prop using a verb ('archived') that has been added to the rule's configuration via 'extendVerbs', adhering to the naming convention.
```tsx
// eslint rule options:
// { extendVerbs: ['archived'] }
```
--------------------------------
### Correct TypeScript `*Props` type definitions
Source: https://github.com/jjenzz/sweepi/blob/main/packages/eslint-plugin-sweepit/docs/rules/no-object-props.md
These TypeScript examples illustrate correct usage that adheres to the `no-object-props` rule. They show alternatives like inheriting from `ComponentPropsWithoutRef`, using `ReactNode` for `children`, defining primitive or function types, and ignoring specific properties via configuration. The `UserOptions` interface is also shown as an example of a type not ending in `Props`, which is not subject to this rule.
```typescript
import type { ComponentPropsWithoutRef } from 'react';
// Prefer inheriting children from composed element/component props.
interface ButtonProps extends ComponentPropsWithoutRef<'button'> {
tone: 'info' | 'warning';
}
// If you must declare it directly, ReactNode is allowed for children.
interface PanelProps {
children?: React.ReactNode;
}
interface CardProps {
tone: 'info' | 'warning';
elevation: number;
open: boolean;
onOpenChange: (open: boolean) => void;
}
// ignored via config
interface InputProps {
ref: { current: HTMLInputElement | null };
}
// not props
interface UserOptions {
user: { id: string; email: string };
}
```
--------------------------------
### Fixing custom kebab-case JSX props
Source: https://github.com/jjenzz/sweepi/blob/main/packages/eslint-plugin-sweepit/docs/rules/no-custom-kebab-case-props.md
Provides a before-and-after code example demonstrating how to fix custom kebab-case JSX props by renaming them to camelCase.
```jsx
// before
// after
```
--------------------------------
### Fixing use* functions returning JSX (TypeScript)
Source: https://github.com/jjenzz/sweepi/blob/main/packages/eslint-plugin-sweepit/docs/rules/no-hook-jsx.md
Provides an example of refactoring code to comply with the 'no-hook-jsx' rule. It shows how to move JSX rendering into a separate PascalCase component while the 'use*' hook focuses on returning data.
```typescript
// before
function useHeader() {
return Title;
}
// after
function useHeaderData() {
return { title: "Title" };
}
function Header() {
const data = useHeaderData();
return {data.title};
}
```
--------------------------------
### Fixing Compound Component Exports (TypeScript)
Source: https://github.com/jjenzz/sweepi/blob/main/packages/eslint-plugin-sweepit/docs/rules/jsx-compound-part-export-naming.md
Provides a before-and-after example in TypeScript demonstrating how to fix incorrect compound component exports to comply with the `jsx-compound-part-export-naming` rule. The fix involves aliasing the main component as 'Root' and parts with their corresponding suffixes.
```typescript
// before
export { ButtonGroup, ButtonGroupItem };
// after
export { ButtonGroup as Root, ButtonGroupItem as Item };
```
--------------------------------
### Incorrect Prop Bundle Example (TypeScript)
Source: https://github.com/jjenzz/sweepi/blob/main/packages/eslint-plugin-sweepit/docs/rules/no-prefixed-prop-bundles.md
Demonstrates an incorrect usage of prop bundles where multiple props share the 'user' prefix, violating the `no-prefixed-prop-bundles` rule. This pattern can lead to over-grouped component contracts and reduced reusability.
```typescript
interface CardProps {
userName: string;
userEmail: string;
userRole: string;
}
```
--------------------------------
### Incorrect Prop Drilling Example in React
Source: https://github.com/jjenzz/sweepi/blob/main/packages/eslint-plugin-sweepit/docs/rules/no-prop-drilling.md
Demonstrates a scenario where prop drilling occurs in React components. The `title` prop is passed unchanged through multiple parent components (`Card` to `Title` to `Heading`), violating the `no-prop-drilling` rule.
```tsx
const Heading = ({ title }: { title: string }) =>
{title}
;
const Title = ({ title }: { title: string }) => ;
const Card = ({ title }: { title: string }) => ;
```
--------------------------------
### JSX Correct camelCase Props Example
Source: https://github.com/jjenzz/sweepi/blob/main/packages/eslint-plugin-sweepit/docs/rules/no-title-case-props.md
Illustrates the correct usage of JSX props with camelCase. This adheres to JSX and DOM conventions, making component APIs predictable. Props like 'someProp' and 'helloWorld' are preferred.
```jsx
```
--------------------------------
### Fixing Prop Drilling by Deriving Values in React
Source: https://github.com/jjenzz/sweepi/blob/main/packages/eslint-plugin-sweepit/docs/rules/no-prop-drilling.md
Shows the transformation from an incorrect prop drilling pattern to a corrected one in React. The example demonstrates how deriving a value (`headingText`) before passing it to the child component resolves the prop drilling issue.
```tsx
// before
function Card({ title }: { title: string }) {
return ;
}
// after
function Card({ title }: { title: string }) {
const headingText = title.toUpperCase();
return ;
}
```
--------------------------------
### Correct Compound Component Exports (TypeScript)
Source: https://github.com/jjenzz/sweepi/blob/main/packages/eslint-plugin-sweepit/docs/rules/jsx-compound-part-export-naming.md
Illustrates correct export patterns for compound components in TypeScript according to the `jsx-compound-part-export-naming` rule. It shows the proper aliasing of the root export as 'Root' and part exports with their respective suffixes. It also includes an example of a non-compound component export.
```typescript
// button-group.tsx
const ButtonGroup = () => null;
const ButtonGroupItem = () => null;
export { ButtonGroup as Root, ButtonGroupItem as Item };
// button.tsx
const Button = () => null;
export { Button };
```
--------------------------------
### Allow element-typed props for children/render (Correct Examples)
Source: https://github.com/jjenzz/sweepi/blob/main/packages/eslint-plugin-sweepit/docs/rules/no-element-props.md
Illustrates the correct way to use `ReactNode` and `ReactElement` for props in TypeScript. It shows that only 'children' and 'render' props are permitted to have `ReactNode` or `ReactElement` types, adhering to the rule's constraints.
```typescript
interface CardProps {
children: ReactNode;
render?: ReactNode;
}
interface ModalProps {
children?: ReactElement;
render?: ReactElement;
}
```
--------------------------------
### Correct Optional Prop Usage with Default Value in React Component
Source: https://github.com/jjenzz/sweepi/blob/main/packages/eslint-plugin-sweepit/docs/rules/no-optional-props-without-defaults.md
This example shows the correct way to use an optional prop in a React component according to the `no-optional-props-without-defaults` rule. The `tone` prop is optional but is provided with a default value ('primary') directly in the destructured parameters of the component. This ensures the prop always has a defined value, strengthening the component contract.
```tsx
interface ButtonProps {
tone?: 'primary' | 'secondary';
}
function Button({ tone = 'primary' }: ButtonProps) {
return tone;
}
```
--------------------------------
### Incorrect Optional Prop Usage in React Component
Source: https://github.com/jjenzz/sweepi/blob/main/packages/eslint-plugin-sweepit/docs/rules/no-optional-props-without-defaults.md
This example demonstrates an incorrect usage of an optional prop in a React component. The `tone` prop is optional but does not have a default value defined in the component's destructured parameters, violating the rule's requirements. This can lead to potential nullability issues if the prop is not provided.
```tsx
interface ButtonProps {
tone?: 'primary' | 'secondary';
}
function Button(props: ButtonProps) {
return props.tone;
}
```
--------------------------------
### Enforce Block-Prefixed Naming for Compound Component Parts (TypeScript)
Source: https://context7.com/jjenzz/sweepi/llms.txt
This rule mandates that exported parts of compound components must be prefixed with the block name. For example, an `Item` component within a `ButtonGroup` block should be named `ButtonGroupItem`. This convention improves code organization and makes it clear which component part belongs to which parent component, especially in larger codebases.
```typescript
// Incorrect - parts not prefixed with block name
// button-group.tsx
const ButtonGroup = () => null;
const Item = () => null; // should be ButtonGroupItem
const GroupItemIcon = () => null; // should be ButtonGroupItemIcon
export { ButtonGroup, Item, GroupItemIcon };
// Correct - all parts prefixed with block
// button-group.tsx
const ButtonGroup = () => null;
const ButtonGroupItem = () => null;
const ButtonGroupItemIcon = () => null;
export { ButtonGroup, ButtonGroupItem, ButtonGroupItemIcon };
```
--------------------------------
### JSX Incorrect TitleCase Props Example
Source: https://github.com/jjenzz/sweepi/blob/main/packages/eslint-plugin-sweepit/docs/rules/no-title-case-props.md
Demonstrates incorrect usage of JSX props with TitleCase. This rule flags props that start with an uppercase letter, such as 'SomeProp' and 'HelloWorld'.
```jsx
```
--------------------------------
### Initialize Sweepi Configuration
Source: https://github.com/jjenzz/sweepi/blob/main/README.md
Initialize Sweepi for the first time to create the necessary configuration files in the user's home directory (~/.sweepi). This step sets up the environment for Sweepi to operate.
```bash
sweepi init
```
--------------------------------
### Usage with Flat Config in JavaScript
Source: https://github.com/jjenzz/sweepi/blob/main/packages/eslint-plugin-sweepit/README.md
Demonstrates how to import and use the core and React configurations from eslint-plugin-sweepit within a JavaScript flat configuration file.
```javascript
import sweepit from 'eslint-plugin-sweepit';
export default [...sweepit.configs.core, ...sweepit.configs.react];
```
--------------------------------
### Sweepi Lint Execution (Bash)
Source: https://github.com/jjenzz/sweepi/blob/main/packages/sweepi/README.md
Demonstrates how Sweepi executes ESLint from its private toolchain directory. This command ensures that project dependencies and lockfiles remain untouched during the linting process.
```bash
~/.sweepi/node_modules/.bin/eslint --config ~/.sweepi/eslint.config.mjs
```
--------------------------------
### Run Sweepi Lint (Bash)
Source: https://github.com/jjenzz/sweepi/blob/main/packages/sweepi/README.md
Executes Sweepi lint rules against a specified project directory. By default, it lints changed files (staged, unstaged, untracked) limited to .ts and .tsx files. Use the --all flag to lint all TypeScript files.
```bash
npx sweepi [project-dir]
npx sweepi [project-dir] --all
```
--------------------------------
### Customize Default Rule Configurations
Source: https://github.com/jjenzz/sweepi/blob/main/packages/eslint-plugin-sweepit/README.md
Shows how to override default rule settings provided by eslint-plugin-sweepit and other integrated plugins. This allows for fine-tuning linting behavior, such as disabling specific rules or adjusting severity levels.
```javascript
import sweepit from 'eslint-plugin-sweepit';
export default [
...sweepit.configs.core,
...sweepit.configs.react,
{
rules: {
// disable a default rule
'react-hooks/exhaustive-deps': 'off',
// tune sweepit rules
'sweepit/no-array-props': 'warn',
'sweepit/no-prefixed-prop-bundles': ['error', { threshold: 4 }],
},
},
];
```
--------------------------------
### Enable TypeScript Project Services for Accuracy
Source: https://github.com/jjenzz/sweepi/blob/main/packages/eslint-plugin-sweepit/README.md
Configures ESLint to use TypeScript project services, which enhances the accuracy of linting rules by leveraging type information. This is particularly useful for rules related to props and exhaustiveness checks.
```javascript
languageOptions: {
parserOptions: {
projectService: true,
tsconfigRootDir: process.cwd(),
},
}
```
--------------------------------
### Custom ESLint React Config with Rule Overrides
Source: https://context7.com/jjenzz/sweepi/llms.txt
Extends the basic React ESLint configuration by including core and React rule sets from `eslint-plugin-sweepit`, and then customizes specific rules. This allows for fine-tuning rule severity (e.g., 'warn', 'error') and applying custom configurations like thresholds for prop-related rules.
```javascript
// What configs.react includes:
// - eslint-plugin-react (jsx-handler-names, jsx-pascal-case, etc.)
// - eslint-plugin-react-hooks recommended
// - eslint-plugin-react-you-might-not-need-an-effect recommended
// - @typescript-eslint/no-floating-promises
// - All sweepit/* rules as errors
// Custom rule configuration
import sweepit from 'eslint-plugin-sweepit';
export default [
...sweepit.configs.core,
...sweepit.configs.react,
{
rules: {
'react-hooks/exhaustive-deps': 'off',
'sweepit/no-array-props': 'warn',
'sweepit/no-prefixed-prop-bundles': ['error', { threshold: 4 }],
'sweepit/max-custom-props': ['error', { threshold: 10 }],
},
},
];
```
--------------------------------
### Correct Usage of 'set*' Prefix with React useState
Source: https://github.com/jjenzz/sweepi/blob/main/packages/eslint-plugin-sweepit/docs/rules/no-set-prefix-utils.md
Illustrates the allowed usage of the 'set*' prefix exclusively for React's `useState` tuple destructuring. It also shows how to correctly name non-state utility functions to avoid prefix conflicts.
```typescript
const [count, setCount] = useState(0);
const [user, setUser] = useState(null);
function updateUserActive(user: User) {
user.active = true;
}
const applyPrefix = (str: string) => str.toUpperCase();
```
--------------------------------
### Configuration Options for max-custom-props Rule
Source: https://github.com/jjenzz/sweepi/blob/main/packages/eslint-plugin-sweepit/docs/rules/max-custom-props.md
Demonstrates the JSON configuration options for the `max-custom-props` ESLint rule. It shows how to set the 'threshold' for the maximum allowed custom props and the 'ignore' array for props to exclude from the count.
```json
{
"threshold": 8,
"ignore": ["children"]
}
```
--------------------------------
### ESLint Configuration for jsx-flat-owner-tree
Source: https://github.com/jjenzz/sweepi/blob/main/packages/eslint-plugin-sweepit/docs/rules/jsx-flat-owner-tree.md
This JSON snippet shows how to configure the `jsx-flat-owner-tree` rule within an ESLint configuration file. It specifies the rule to be enabled with an 'error' severity and sets the `allowedChainDepth` option to 2, meaning chains of depth 3 or more will be reported.
```json
{
"rules": {
"sweepit/jsx-flat-owner-tree": [
"error",
{
"allowedChainDepth": 2
}
]
}
}
```
--------------------------------
### Correct Component Prop Contracts (TypeScript)
Source: https://github.com/jjenzz/sweepi/blob/main/packages/eslint-plugin-sweepit/docs/rules/max-custom-props.md
Examples of refactored TypeScript interfaces for component props that adhere to the `max-custom-props` rule. This demonstrates splitting a large prop contract into smaller, focused interfaces.
```typescript
interface DashboardCardRootProps {
children?: React.ReactNode;
}
interface DashboardCardValueProps {
value: string;
trend: 'up' | 'down';
trendLabel: string;
}
```
--------------------------------
### Correct Component Prop Patterns (TSX)
Source: https://github.com/jjenzz/sweepi/blob/main/packages/eslint-plugin-sweepit/docs/rules/no-componenttype-props.md
Illustrates recommended alternatives for handling component polymorphism in props, such as the `asChild` pattern, render props, or passing `children` for composition.
```tsx
// asChild pattern
interface LayoutProps {
asChild?: boolean;
}
// Render prop
interface LayoutProps {
render?: (props: Props) => ReactNode | React.ReactElement;
}
// Or pass children and let the consumer compose
interface CardProps {
children?: ReactNode;
}
```
--------------------------------
### Run Sweepi ESLint Check (TypeScript)
Source: https://context7.com/jjenzz/sweepi/llms.txt
Runs ESLint with Sweepi rules against a specified project directory. It can optionally lint only changed files and provides a status callback. The function returns an exit code indicating the linting result.
```typescript
import { runSweepi } from 'sweepi';
const exitCode = await runSweepi('./my-project', {
all: false, // lint only changed files (default)
onStatus: (message) => {
console.log(message);
},
});
// exitCode: 0 = clean, 1 = lint errors found
process.exit(exitCode);
```
--------------------------------
### Incorrect Usage of 'set*' Prefix in TypeScript
Source: https://github.com/jjenzz/sweepi/blob/main/packages/eslint-plugin-sweepit/docs/rules/no-set-prefix-utils.md
Demonstrates forbidden function declarations and variable assignments where identifiers start with 'set' and are intended as utility or helper functions. This violates the rule by reusing the 'set*' prefix, which is conventionally reserved for React state setters.
```typescript
function setUserActive(user: User) {
user.active = true;
}
const setPrefix = (str: string) => str.toUpperCase();
const setFormData = function (data: FormData) {
// ...
};
```
--------------------------------
### Correct Component Structure (Shallow Chain)
Source: https://github.com/jjenzz/sweepi/blob/main/packages/eslint-plugin-sweepit/docs/rules/jsx-flat-owner-tree.md
This TypeScript/JSX code illustrates a corrected component structure that adheres to the `jsx-flat-owner-tree` rule. It uses compound components (`Header.Root`, `Header.UserArea`) to flatten the parent chain, improving readability and maintainability. The `allowedChainDepth` is respected by keeping the direct parent-child relationships shallow.
```tsx
function Root() {
return (
);
}
// header.tsx
function Header({ children }: { children: React.ReactNode }) {
return
{children}
;
}
function HeaderUserArea() {
return (
);
}
export { Header as Root, HeaderUserArea as UserArea };
```
--------------------------------
### Signal Composition Pressure with Prefixed Props (TypeScript)
Source: https://context7.com/jjenzz/sweepi/llms.txt
This rule identifies when too many props sharing a common prefix (e.g., `user*`) are used within a single component. It suggests that this pattern might indicate a need for composition, where these related props could be grouped into a separate component or configuration object. The default threshold is 3, meaning four or more prefixed props will trigger a warning.
```typescript
// Incorrect - too many user-prefixed props (default threshold: 3)
interface FormProps {
userName: string;
userEmail: string;
userRole: string;
userAvatar: string; // 4th user* prop triggers error
}
// Correct - extract to compound part or separate component
interface FormProps {
children: React.ReactNode;
}
interface UserFieldsProps {
name: string;
email: string;
role: string;
avatar: string;
}
// Options
// { "threshold": 4 }
```
--------------------------------
### Configure jsx-on-handler-verb-suffix with extended verbs
Source: https://github.com/jjenzz/sweepi/blob/main/packages/eslint-plugin-sweepit/docs/rules/jsx-on-handler-verb-suffix.md
This configuration snippet shows how to extend the built-in verb dictionary for the 'jsx-on-handler-verb-suffix' rule. It allows you to add project-specific verbs to the validation process, ensuring custom handler names are correctly identified. This is useful for domain-specific terminology.
```json
{
"rules": {
"sweepi/jsx-on-handler-verb-suffix": [
"error",
{
"extendVerbs": ["archived"]
}
]
}
}
```
--------------------------------
### Incorrect Component Prop Contract (TypeScript)
Source: https://github.com/jjenzz/sweepi/blob/main/packages/eslint-plugin-sweepit/docs/rules/max-custom-props.md
An example of a TypeScript interface for component props that violates the `max-custom-props` rule due to exceeding the default threshold of 8 custom props. This interface demonstrates a monolithic prop surface.
```typescript
interface DashboardCardProps {
title: string;
subtitle: string;
icon: React.ReactNode;
tone: 'success' | 'warning' | 'danger';
value: string;
trend: 'up' | 'down';
trendLabel: string;
ctaLabel: string;
onCtaClick: () => void;
}
```
--------------------------------
### Correct Async Prop Definitions (TypeScript)
Source: https://github.com/jjenzz/sweepi/blob/main/packages/eslint-plugin-sweepit/docs/rules/jsx-server-action-prop-suffix.md
Illustrates the correct way to define asynchronous function props by naming them 'action' or using the '*Action' suffix. Synchronous props like 'onSubmit' are correctly defined to return void.
```typescript
interface FormProps {
action: (data: FormData) => Promise;
submitAction?: (data: FormData) => Promise;
onSubmit: (event: SubmitEvent) => void;
}
type UploadProps = {
uploadAction?: (() => Promise) | undefined;
onUpload?: (file: File) => void;
};
```
--------------------------------
### Lint Changed Files CLI
Source: https://context7.com/jjenzz/sweepi/llms.txt
Lints only the changed files (staged, unstaged, and untracked) within a specified project directory. This is the default behavior of the Sweepi CLI.
```bash
sweepi .
sweepi ./path/to/project
```
--------------------------------
### Incorrect Compound Component Exports (TypeScript)
Source: https://github.com/jjenzz/sweepi/blob/main/packages/eslint-plugin-sweepit/docs/rules/jsx-compound-part-export-naming.md
Demonstrates incorrect export patterns for compound components in TypeScript. This includes missing root exports, incorrect aliasing of the root export, and using runtime object export APIs for the inferred block. These examples violate the `jsx-compound-part-export-naming` rule.
```typescript
// button-group.tsx
const ButtonGroup = () => null;
const ButtonGroupItem = () => null;
export { ButtonGroupItem as Item }; // missing ButtonGroup as Root
const ButtonGroup = () => null;
const ButtonGroupItem = () => null;
export { ButtonGroup, ButtonGroupItem as Item }; // ButtonGroup must be aliased as Root
const ButtonGroupItem = () => null;
export const ButtonGroup = { Item: ButtonGroupItem };
```
--------------------------------
### Correct handler prop return types (TypeScript)
Source: https://github.com/jjenzz/sweepi/blob/main/packages/eslint-plugin-sweepit/docs/rules/no-handler-return-type.md
Illustrates correct handler prop definitions where all handler props (names starting with 'on') explicitly return 'void'. This adheres to the 'no-handler-return-type' rule, ensuring explicit data flow.
```typescript
interface ComponentProps {
onClose: () => void;
}
type DialogProps = {
onOpen?: (() => void) | undefined;
};
```
--------------------------------
### Fixing element-typed props to use children
Source: https://github.com/jjenzz/sweepi/blob/main/packages/eslint-plugin-sweepit/docs/rules/no-element-props.md
Provides a before-and-after example of refactoring a component's props to comply with the `no-element-props` rule. The 'header' prop, initially typed as `ReactNode`, is replaced with `children` to align with the rule's best practices for handling arbitrary content.
```typescript
// before
interface CardProps {
header: ReactNode;
}
// after
interface CardProps {
children: ReactNode;
}
```
--------------------------------
### Refactoring object props to primitive members
Source: https://github.com/jjenzz/sweepi/blob/main/packages/eslint-plugin-sweepit/docs/rules/no-object-props.md
This TypeScript example demonstrates a refactoring approach to fix violations of the `no-object-props` rule. The `UserRowProps` interface is refactored from accepting a `User` object to accepting explicit primitive members (`name` and `email`) that the component actually needs.
```typescript
// before
interface UserRowProps {
user: User;
}
// after
interface UserRowProps {
name: string;
email: string;
}
```
--------------------------------
### Disallow element-typed props (Incorrect Examples)
Source: https://github.com/jjenzz/sweepi/blob/main/packages/eslint-plugin-sweepit/docs/rules/no-element-props.md
Demonstrates incorrect usage of `ReactNode` and `ReactElement` for props in TypeScript interfaces and types. Props like 'header', 'footer', 'slot', 'title', 'content', and 'header' are shown to be disallowed when typed as `ReactNode` or `ReactElement`, unless they are named 'children' or 'render'.
```typescript
interface CardProps {
header: React.ReactNode; // ReactNode only allowed for children
footer?: ReactNode;
slot: ReactNode; // not allowed
}
type ModalProps = {
title: ReactNode;
content: React.ReactNode;
header: ReactElement; // not allowed
};
```
--------------------------------
### Correct Prop Drilling Handling in React
Source: https://github.com/jjenzz/sweepi/blob/main/packages/eslint-plugin-sweepit/docs/rules/no-prop-drilling.md
Illustrates correct ways to handle props in React to avoid prop drilling. This includes deriving or transforming props before passing them down, using spread props (`...props`), and composing components via `children`. These patterns adhere to the `no-prop-drilling` rule.
```tsx
function Card({ title }: { title: string }) {
const headingText = title.toUpperCase();
return ;
}
const Input: React.FC = ({ type = 'text', ...props }) => (
);
function Dialog({ children }: { children: React.ReactNode }) {
return {children};
}
```
--------------------------------
### Configure NoPropDrillingOptions in TypeScript
Source: https://github.com/jjenzz/sweepi/blob/main/packages/eslint-plugin-sweepit/docs/rules/no-prop-drilling.md
Defines the configuration options for the `no-prop-drilling` rule, including `allowedDepth` for controlling the maximum prop-through chain and `ignorePropsSpread` to optionally bypass spread props analysis. These options help fine-tune the rule's behavior.
```typescript
type NoPropDrillingOptions = {
allowedDepth?: number; // default: 1
ignorePropsSpread?: boolean; // default: true
};
```
--------------------------------
### Incorrect TypeScript `*Props` type definitions
Source: https://github.com/jjenzz/sweepi/blob/main/packages/eslint-plugin-sweepit/docs/rules/no-object-props.md
These TypeScript examples demonstrate incorrect usage of object properties within type definitions ending in `Props`. The `UserCardProps` interface contains a `user` property typed as an object, and `CardProps` has a `config` property typed as an object, both violating the `no-object-props` rule.
```typescript
interface UserCardProps {
user: { id: string; email: string };
}
type CardProps = {
config: { dense: boolean };
};
```
--------------------------------
### Configuration for `no-boolean-capability-props` Rule
Source: https://github.com/jjenzz/sweepi/blob/main/packages/eslint-plugin-sweepit/docs/rules/no-boolean-capability-props.md
This JSON configuration object specifies options for the `no-boolean-capability-props` ESLint rule. It allows users to ignore specific prop names and native boolean attributes to customize the rule's behavior.
```json
{
"ignore": ["asChild"],
"ignoreNativeBooleanProps": true
}
```
--------------------------------
### Disallow JSX Return from React Hooks
Source: https://context7.com/jjenzz/sweepi/llms.txt
Enforces that `use*` functions should return data, not JSX, promoting a clear separation between data fetching/logic and rendering. Components are responsible for rendering UI. This rule is implemented for React hooks and JSX.
```javascript
// Incorrect - hook returns JSX
function useHeader() {
return Title;
}
const useLayout = () => ;
function useList() {
return { List:
}; // JSX in object also forbidden
}
// Correct - separate hook data from component rendering
function useHeaderData() {
const [title, setTitle] = useState('Default');
return { title, setTitle };
}
function Header() {
const { title } = useHeaderData();
return {title};
}
```
--------------------------------
### Correct Usage: Private Context Hooks and Exported Props (TypeScript)
Source: https://github.com/jjenzz/sweepi/blob/main/packages/eslint-plugin-sweepit/docs/rules/no-exported-context-hooks.md
Illustrates the correct way to use context hooks by keeping them private within the module and exporting component props or state contracts instead. This adheres to the `no-exported-context-hooks` rule.
```typescript
function useDialogContext() {
return useContext(DialogContext);
}
interface DialogProps {
open: boolean;
onOpenChange: (open: boolean) => void;
}
```
--------------------------------
### Forbid JSX in Non-PascalCase Render Helpers (TypeScript)
Source: https://context7.com/jjenzz/sweepi/llms.txt
This rule enforces that any function returning JSX must use PascalCase, treating them as React components. It aims to distinguish between regular utility functions and components responsible for rendering UI elements. Using non-PascalCase for functions that render JSX can lead to confusion and violates React's convention for component naming.
```typescript
// Incorrect - JSX in non-PascalCase function
function renderHeader() {
return Title;
}
const getLayout = () => ;
const makeCard = () => (
<>
>
);
// Correct - PascalCase components
function Header() {
return Title;
}
const Layout = () => ;
const Card = () => (
<>
>
);
```
--------------------------------
### Correct use* functions returning non-JSX values (TypeScript)
Source: https://github.com/jjenzz/sweepi/blob/main/packages/eslint-plugin-sweepit/docs/rules/no-hook-jsx.md
Illustrates correct usage where 'use*' functions return non-JSX values such as primitives, objects, or arrays. This adheres to the rule by separating hook logic from component rendering, which should be handled by PascalCase components.
```typescript
function Header() {
return Title;
}
const useUser = () => {
const [user, setUser] = useState(null);
return user;
};
function useToggle(initial: boolean) {
const [on, setOn] = useState(initial);
return [on, () => setOn((v) => !v)] as const;
}
function useData() {
return { items: [], count: 0 };
}
function useItems() {
return [1, 2, 3];
}
```