Skip to content

Navigation Menu

Sign in
Appearance settings

Search code, repositories, users, issues, pull requests...

Provide feedback

We read every piece of feedback, and take your input very seriously.

Saved searches

Use saved searches to filter your results more quickly

Sign up
Appearance settings

docs: improve CLAUDE.md structure with modular rules system#598

Open
MaxLee-dev wants to merge 6 commits into
main from
improve-claude-md
Open

docs: improve CLAUDE.md structure with modular rules system #598
MaxLee-dev wants to merge 6 commits into
main from
improve-claude-md

Conversation

@MaxLee-dev

@MaxLee-dev MaxLee-dev commented May 27, 2026
edited
Loading

Copy link
Copy Markdown
Contributor

Summary

  • Add root `CLAUDE.md` covering monorepo structure, workspace-wide commands, release workflow, and commit conventions
  • Rewrite `packages/core/CLAUDE.md` to focus on architecture-critical information (component patterns, rendering flow, styling system, test strategy) instead of a Gemini styleguide translation
  • Add 5 detailed rule files under `.claude/rules/` (`component-api.md`, `styling.md`, `typescript.md`, `testing.md`, `docs.md`) that Claude Code loads on demand
  • Expand `.claude/rules/typescript.md` with `React.FC` rationale, detailed `type` vs `interface` guidance, and namespace import naming convention

Why

The previous `packages/core/CLAUDE.md` was essentially a translated copy of `.gemini/styleguide.md` — it mixed generic coding conventions with package-specific rules, had no root-level CLAUDE.md, and lacked the architectural context Claude Code needs most (compound component patterns, RSC-safe export structure, Vanilla Extract styling primitives). This led to repeated mistakes such as using `Object.assign` for compound exports, hard-coded style values, and incorrect prop types.

The new structure separates concerns:

  • `CLAUDE.md` (root) → monorepo overview, commands, conventions
  • `packages/core/CLAUDE.md` → architecture overview + pointers to rule files
  • `.claude/rules/*.md` → deep-dive rules loaded only when relevant, keeping context window usage efficient

Key decisions documented

  • No `Object.assign` for compound exports: `Object.assign` in `index.ts` forces a direct reference to implementation files, collapsing the RSC `'use client'` boundary. The 3-file pattern (`index.ts` → `index.parts.ts` → `component.tsx`) keeps the entrypoint free of client directives.
  • Storybook `TestBed` story: serves as the visual regression baseline for Playwright — must remain stable and represent all variant combinations.
  • Rendering flow: `resolveStyles` → `cn(recipe, className)` → `` is the invariant pattern every component follows.
  • No `React.FC`: implicitly adds `children?: ReactNode` to all components regardless of intent, breaks with `defaultProps`, doesn't support generics, and was removed from the CRA TypeScript template in React 18. Use plain function with an explicit props interface instead.
  • `interface` over `type` for props: `type &` intersection silently produces `never` for conflicting property types and only surfaces the error at the use site; `interface extends` catches the conflict at definition time. `interface` is also faster for the TypeScript compiler when inheritance is involved.

Test plan

  • Verify `.claude/rules/` files are loaded correctly in Claude Code sessions
  • Confirm no existing component tests regressed (`pnpm core test`)

🤖 Generated with Claude Code

vercel Bot commented May 27, 2026
edited
Loading

Copy link
Copy Markdown
Contributor

The latest updates on your projects. Learn more about Vercel for GitHub.

Project Deployment Actions Updated (UTC)
vapor-ui Ready Ready Preview, Comment May 28, 2026 1:34am

Request Review

changeset-bot Bot commented May 27, 2026
edited
Loading

Copy link
Copy Markdown

⚠️ No Changeset found

Latest commit: d42414b

Merging this PR will not cause a version bump for any packages. If these changes should not result in a new version, you're good to go. If these changes should result in a version bump, you need to add a changeset.

This PR includes no changesets

When changesets are added to this PR, you'll see the packages that this PR includes changesets for and the associated semver types

Click here to learn what changesets are, and how to add one.

Click here if you're a maintainer who wants to add a changeset to this PR

coderabbitai Bot commented May 27, 2026
edited
Loading

Copy link
Copy Markdown

Warning

Review limit reached

@MaxLee-dev, we couldn't start this review because you've reached your PR review rate limit.

More reviews will be available in 34 minutes and 53 seconds. Learn how PR review limits work.

Your organization has run out of usage credits. Purchase more in the billing tab.

⌛ How to resolve this issue?

After more reviews become available, a review can be triggered using the @coderabbitai review command as a PR comment. Alternatively, push new commits to this PR.

We recommend that you space out your commits to avoid hitting the rate limit.

🚦 How do rate limits work?

CodeRabbit enforces hourly rate limits for each developer per organization.

Our paid plans include higher PR review limits than trial, open-source, and free plans. In all cases, reviews become available again over time. During sustained high-volume PR review activity, CodeRabbit may temporarily slow when the next review becomes available.

Please see our Fair Usage Limits Policy for further information.

i️ Review info
⚙️ Run configuration

Configuration used: Path: .coderabbit.yaml

Review profile: CHILL

Plan: Pro

Run ID: fcc9bc47-ab02-45b1-9b0b-f5f260c89740

📥 Commits

Reviewing files that changed from the base of the PR and between 29eba5b and d42414b.

⛔ Files ignored due to path filters (1)
  • .gemini/styleguide.md is excluded by !**/.gemini/**
📒 Files selected for processing (7)
  • .claude/rules/component-api.md
  • .claude/rules/docs.md
  • .claude/rules/styling.md
  • .claude/rules/testing.md
  • .claude/rules/typescript.md
  • CLAUDE.md
  • packages/core/CLAUDE.md
📝 Walkthrough

Walkthrough

This pull request establishes comprehensive Claude Code guidance and development conventions for the @vapor-ui/core package. It adds a root CLAUDE.md repository guide, rewrites the package-specific guide, and introduces five detailed rules files covering component API design, styling patterns, testing standards, TypeScript conventions, and documentation practices.

Changes

Component Development Standards for @vapor-ui/core

Layer / File(s) Summary
Repository & Package Context
CLAUDE.md, packages/core/CLAUDE.md
Root repository guide documents monorepo structure, dev environment, pnpm commands, Changesets release workflow, and Conventional Commits. Package guide refocuses from general conventions to Claude-specific guidance for component structure, props typing, Vanilla Extract styling, testing setup, import aliases, and Rollup build outputs.
Component API & Architecture
.claude/rules/component-api.md
Components must use kebab-case folder names with ~/ import aliases. Standalone components export directly; compound components use 3-file pattern (parts, namespace export via index.parts.ts, avoiding Object.assign). Props typed via VaporUIComponentProps with compound part props derived from Base UI. Composition via Base UI render, React.forwardRef, WAI-ARIA patterns, uncontrolled-first with controlled value/onChange support, and separated overlay parts. Public API examples show expected imports and namespace usage.
Styling Conventions with Vanilla Extract
.claude/rules/styling.md
Runtime flow: resolveStyles normalizes $css/deprecated props to className/style, then cn() merges recipe/sprinkles/user classes. Three Vanilla Extract primitives: componentRecipe (variants in @layer vapor.components), componentStyle (static), interaction() mixin (hover/active/focus). Variants passed directly via createSplitProps or via Context for compounds. Component-scoped CSS variables via createVar. State selectors use logical-state helpers, avoiding :disabled/:checked pseudo-classes. Design tokens via vars object only. $css prop accepts token-aware values as classNames; arbitrary values fall to inline style. User className without layer overrides component-layer styles.
Testing Conventions & Coverage
.claude/rules/testing.md
Every public component must test keyboard/pointer interactions, focus behavior, overlay/dialog/menu lifecycles, controlled vs uncontrolled patterns, and accessibility via vitest-axe. Fake timers use standardized beforeEach/afterEach pattern with example advancing timers for tooltip delay. Tests colocate with components. Example structure demonstrates rendering, interaction testing, and accessibility checks.
TypeScript & Code Style Conventions
.claude/rules/typescript.md
Naming: camelCase for variables/functions, PascalCase for components/interfaces/types/enums, CONSTANT_CASE for constants, kebab-case for files/directories. Use interface for props/object shapes; type for unions/intersections. Prefer undefined over null with optional chaining/nullish coalescing. Array syntax T[] over Array<T>. Enums use PascalCase members; prefer as const objects for strings. Constants use CONSTANT_CASE ... as const. Code style: 4-space indentation, semicolons required, single quotes, early return when nesting exceeds 3 levels, object parameters for 3+ parameter functions.
Documentation & Storybook Patterns
.claude/rules/docs.md
Storybook Docs generated automatically via autodocs; no manual setup. Test Bed story serves as stable Playwright visual regression baseline. Stories must colocate with components in packages/core/src/ with example showing component folder containing *.stories.tsx.

Estimated code review effort

🎯 2 (Simple) | ⏱️ ~12 minutes

Possibly related PRs

  • goorm-dev/vapor-ui#524: Introduces the initial packages/core/CLAUDE.md that this PR significantly rewrites with more specific component architecture and implementation guidelines.
🚥 Pre-merge checks | ✅ 4
✅ Passed checks (4 passed)
Check name Status Explanation
Title check ✅ Passed The title clearly summarizes the main change: modularizing CLAUDE.md documentation into a structured rules system with both root and package-level guides plus detailed rule files.
Linked Issues check ✅ Passed Check skipped because no linked issues were found for this pull request.
Out of Scope Changes check ✅ Passed Check skipped because no linked issues were found for this pull request.
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.

✏️ Tip: You can configure your own custom pre-merge checks in the settings.

✨ Finishing Touches
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Commit unit tests in branch improve-claude-md

Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

Comment @coderabbitai help to get the list of available commands and usage tips.

@coderabbitai coderabbitai Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 7

🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.
Inline comments:
In @.claude/rules/component-api.md:
- Around line 14-21: The fenced code block showing the component folder
structure is missing a language tag and triggers markdownlint MD040; update the
block in component-api.md (the block with the lines listing
src/components/button/ etc.) to include a language identifier (for example use
```text or ```bash) immediately after the opening backticks so the fence is
labeled and MD040 is resolved.
In @.claude/rules/docs.md:
- Around line 16-20: The fenced code block showing the folder structure (the
block containing "src/components/button/" and its files) is unlabeled which
triggers markdownlint MD040; fix it by adding a language label after the opening
backticks (e.g., use "text" or "bash") so the block becomes a labeled fenced
code block and the lint rule is satisfied.
In @.claude/rules/styling.md:
- Around line 16-25: The markdown fenced code blocks shown (the block containing
the snippets for resolveStyles, cn, and BaseComponent) are missing language
tags; update those fenced blocks by adding an explicit language label (e.g.,
```text or ```markdown) so they pass MD040 linting—specifically edit the block
that documents resolveStyles, cn, and <BaseComponent .../> and the similar block
around lines 193–199 to prepend the appropriate language identifier.
In @.claude/rules/testing.md:
- Around line 66-70: The fenced code block showing the file tree
("src/components/button/" with "button.tsx" and "button.test.tsx") is missing a
language tag which triggers MD040; update the opening fence from ``` to include
a language (e.g., ```text or ```bash) so the block is language-qualified; ensure
the same fence content (the file tree) remains unchanged and commit the markdown
edit.
In `@CLAUDE.md`:
- Around line 88-90: Update the fenced code block containing "<type>(<scope>):
<subject>" to specify a language for markdownlint (MD040); change the opening
fence from ``` to ```text so the block reads as a text code block and resolves
the linter warning.
In `@packages/core/CLAUDE.md`:
- Around line 27-34: Several fenced code blocks in the CLAUDE.md file are
missing language identifiers (e.g., the block that starts with
"src/components/button/"); update each unlabeled fenced block by adding an
appropriate language tag (for example use ```text or ```bash for file
trees/terminal snippets, or ```tsx/```tsx for React code) so that the blocks
that contain the "src/components/button/" listing and the other unlabeled blocks
are annotated with the correct language identifier.
- Around line 15-19: Update the malformed rule file paths in CLAUDE.md by
replacing the incorrect `@.claude/...` prefixes with the repo-conventional
`.claude/...` versions (e.g. change `@.claude/rules/component-api.md`,
`@.claude/rules/styling.md`, `@.claude/rules/typescript.md`,
`@.claude/rules/testing.md`, `@.claude/rules/docs.md` to
`.claude/rules/component-api.md`, `.claude/rules/styling.md`,
`.claude/rules/typescript.md`, `.claude/rules/testing.md`,
`.claude/rules/docs.md`) so the links match the actual `.claude/rules/`
directory at the repo root.
🪄 Autofix (Beta)

Fix all unresolved CodeRabbit comments on this PR:

  • Push a commit to this branch (recommended)
  • Create a new PR with the fixes

i️ Review info
⚙️ Run configuration

Configuration used: Path: .coderabbit.yaml

Review profile: CHILL

Plan: Pro

Run ID: be792c6b-b5b7-469e-854b-f74a86305352

📥 Commits

Reviewing files that changed from the base of the PR and between 7d4732c and 29eba5b.

📒 Files selected for processing (7)
  • .claude/rules/component-api.md
  • .claude/rules/docs.md
  • .claude/rules/styling.md
  • .claude/rules/testing.md
  • .claude/rules/typescript.md
  • CLAUDE.md
  • packages/core/CLAUDE.md

Comment thread .claude/rules/component-api.md Outdated
Comment thread .claude/rules/docs.md Outdated
Comment thread .claude/rules/styling.md Outdated
Comment thread .claude/rules/testing.md Outdated
Comment thread CLAUDE.md Outdated
Comment thread packages/core/CLAUDE.md
Comment thread packages/core/CLAUDE.md Outdated

vapor-ui commented May 27, 2026
edited
Loading

Copy link
Copy Markdown
Collaborator

All tests passed!

Tests Passed Failed Duration Report
156 156 0 m 0s Open report ↗︎

Click here if you need to update snapshots.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
Add language tags to fenced code blocks (MD040) across CLAUDE.md and
.claude/rules/* files.
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
... interface detail
Co-Authored-By: Claude Sonnet 4.6 (1M context) <noreply@anthropic.com>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Reviewers

@coderabbitai coderabbitai[bot] coderabbitai[bot] requested changes

@noahchoii noahchoii Awaiting requested review from noahchoii noahchoii is a code owner

Assignees

No one assigned

Labels

None yet

Projects

None yet

Milestone

No milestone

Development

Successfully merging this pull request may close these issues.

AltStyle によって変換されたページ (->オリジナル) /