Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
180 changes: 180 additions & 0 deletions .cursor/rules/cleanCode.mdc
Original file line number Diff line number Diff line change
@@ -0,0 +1,180 @@
---
description: Clean code rules for JavaScript (apply only when user explicitly requests via @cleanCode)
alwaysApply: false
---

# Clean Code Rules for LLM (JavaScript)

Behavioral constraints for LLMs modifying or generating JavaScript code.
Ordered by priority — higher rules take precedence when rules conflict.

> **Note**: Apply this rule only when the user explicitly requests it (e.g., by @-mentioning @cleanCode or asking for clean code guidance).

---

## 1. Minimal Change Principle ⚡ Highest Priority

- **Do not touch working code** unless strictly required for the requested behavior.
- **Never refactor, rename, reorder, or restructure** unrelated code.
- Prefer the **smallest possible diff**.
- Assume all existing code is **intentional and correct**.
- **Match the existing structure.** Use the same control flow, naming, patterns, and conventions as the code you're changing or the nearest similar file. Do not introduce new abstractions (wrapper factories, generic helpers) when the existing code uses direct approaches.
- **Preserve intent over style.** Do not rewrite code solely to match these rules. These rules must never override domain meaning or deliberate design choices.

> Change only what is directly linked to the requested behavior — nothing more. When in doubt, keep the same structure as the original.

---

## 2. Clarity Over Performance

- Prefer **simple, explicit, readable code** over micro-optimizations.
- Avoid clever tricks, compressed expressions, or obscure patterns.
- Optimize **only when explicitly requested** or clearly critical.
- Prefer direct boolean forms: `x === 'toggle'` over `x !== 'toggle' ? false : true`.

---

## 3. Control Flow: Flat and Explicit

- Prefer **flattened control flow** over nested `if` trees.
- Unite `if` statements that lead to the same behavior.
- Use **early guard returns** to simplify logic.
- If flattening hurts readability, extract **well-named helpers**.
- Prefer **a single final return** per function; multiple early returns are fine for guards and impossible states.

### Example

❌ Bad

```js
if (a) {
if (b) {
doX();
} else if (c) {
doY();
}
}
```

✅ Better

```js
if (!a) return;
if (b) doX();
if (!b && c) doY();
```

---

## 4. Short, Focused Functions

- Functions should fit on **one screen** (~100 lines max).
- If a function does more than one thing, mixes abstraction levels, or needs explanation → extract helpers.

> If you need comments to explain _what_ a function does, it's too big.

---

## 5. Separation of Concerns

- High-level logic must not contain low-level details.
- Extract validation, parsing, formatting, and calculations into helpers.
- **Helpers are a feature, not a smell.** Prefer named helpers over inline complexity. Names should explain **why**, not **how**.

### Example

❌ Bad

```js
if (user && user.age > 18 && user.status === 'active') { ... }
```

✅ Better

```js
if (isEligibleUser(user)) { ... }
```

> High-level code should read like a story.

---

## 6. Don't Repeat Yourself (DRY)

- Never duplicate logic, conditions, or transformations.
- Extract and reuse — even if the helper feels trivial.

---

## 7. Immutability First

- Always prefer `const` over `let`.
- Avoid mutation unless unavoidable; return new values instead.

---

## 8. Limit Function Arguments

- Avoid more than **4 arguments**. Group related arguments into objects or extract helpers.

> Many arguments signal unclear boundaries or mixed concerns.

---

## 9. Comments: Only When Necessary

- Add comments only when **strictly necessary** (non-obvious workarounds, critical "why" that code/naming cannot express).
- If a comment restates the code, remove it. If it explains _what_, improve the code instead.

---

## 10. Prefer Loose Data Shapes Over Discriminated Unions

- Prefer a **single object with optional properties** over discriminated unions when the code only checks "which keys are present."
- Don't add structure (e.g. a `kind` field) that exists only for the type system.

### Example

❌ Discriminated union

```js
type NotifyConfig =
| { kind: 'scheduled'; at: Date }
| { kind: 'delay'; ms: number }
| { kind: 'immediate' };
```

✅ Optional properties

```js
type NotifyConfig = { at?: Date; ms?: number; immediate?: true };
```

---

## 11. Avoid Unnecessary Parameterization

- Don't add a parameter when the only value ever passed is created in the same scope. Close over it instead.

---

## 12. Declare Variables Near Usage

- Declare variables **close to where they're first used**, not at the top of a block.

---

## Self-Check Before Responding

Before producing code, verify:

1. Did I make the smallest possible change?
2. Did I preserve the original structure and intent?
3. Is the code clear and readable?
4. Is control flow as flat as possible?
5. Did I avoid unnecessary mutation, arguments, or parameters?
6. Are comments limited to what's strictly necessary?
7. Could optional properties replace a discriminated union here?
8. Are variables declared near their usage?

If **any answer is "no"**, revise.
190 changes: 0 additions & 190 deletions packages/interact/src/handlers/click.ts

This file was deleted.

9 changes: 9 additions & 0 deletions packages/interact/src/handlers/constants.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
export const EVENT_TRIGGER_PRESETS = {
click: ['click'] as const,
activate: ['click', 'keydown'] as const,
hover: { enter: ['mouseenter'], leave: ['mouseleave'] } as const,
interest: {
enter: ['mouseenter', 'focusin'],
leave: ['mouseleave', 'focusout'],
} as const,
} as const;
Loading