Skip to content

docs: add component-architecture.md cursor rule#943

Merged
georgewrmarshall merged 12 commits into
mainfrom
docs/component-architecture-cursor-rule
Feb 27, 2026
Merged

docs: add component-architecture.md cursor rule#943
georgewrmarshall merged 12 commits into
mainfrom
docs/component-architecture-cursor-rule

Conversation

@georgewrmarshall

@georgewrmarshall georgewrmarshall commented Feb 26, 2026

Copy link
Copy Markdown
Contributor

Description

Adds component-architecture.md cursor rule establishing foundational architectural patterns for design system components. This rule documents ADR-0003 (const objects over TypeScript enums) and ADR-0004 (centralized types architecture) patterns.

Key patterns documented:

  • Two-file export structure: .types.ts for imports only, index.ts for exports only
  • Const objects with as const instead of TypeScript enums
  • Centralized types in @metamask/design-system-shared package
  • Layered architecture with one-way dependencies (shared → platform packages)
  • Cross-platform consistency between React and React Native

Why this matters:
We need to ensure our components are consistent across platforms and use the most up to date typescript conventions

References:

Related issues

Fixes: https://consensyssoftware.atlassian.net/browse/DSYS-339

Manual testing steps

  1. Review the cursor rule file: .cursor/rules/component-architecture.md
  2. Check out the BadgeCount PR refactor: migrate BadgeCount to union and shared types #942
  3. Verify CLAUDE.md includes reference to this new rule

Screenshots/Recordings

N/A - Documentation only

Pre-merge author checklist

  • I've followed MetaMask Contributor Docs
  • I've completed the PR template to the best of my ability
  • I've included tests if applicable (N/A - documentation)
  • I've documented my code using JSDoc format if applicable (N/A - markdown)
  • I've applied the right labels on the PR (see labeling guidelines). Not required for external contributors.

Pre-merge reviewer checklist

  • I've manually tested the PR (e.g. pull and build branch, run the app, test code being changed).
  • I confirm that this PR addresses all acceptance criteria described in the ticket it closes and includes the necessary testing evidence such as recordings and or screenshots.

Note

Low Risk
Low risk documentation-only change that updates AI agent rules and references; no runtime code or build logic is modified.

Overview
Adds a new Cursor rule, component-architecture.md, documenting required design-system component patterns (ADR-0003 const-object string unions, ADR-0004 centralized shared types, and layered shared vs platform props/export conventions).

Updates supporting docs to reference the new rule and clarify guidance: expands Storybook story naming examples in component-documentation.md, adds the rule link and create-component:react-native command in CLAUDE.md, and updates docs/ai-agents.md to list the current rule files.

Written by Cursor Bugbot for commit cfcffc1. This will update automatically on new commits. Configure here.

georgewrmarshall and others added 9 commits February 24, 2026 16:31
## Changes

### Critical Fixes
- Fix `interface` → `type` inconsistency in component-architecture.md
  - All shared props now use `type` not `interface` (aligns with ESLint rule)
  - Updated 6 instances across the file

- Replace duplicated BadgeStatus examples with @ references
  - Removed ~125 lines of duplicated code across files
  - Now references actual implementation as SOURCE OF TRUTH

### Code Duplication Reduction
- Consolidate Button type examples across 3 files
  - Reference BadgeStatus golden path instead of duplicating patterns

- Consolidate styling examples
  - Reference WalletHome.stories.tsx and styling.md instead of duplicating

### Clarity Improvements
- Add prominent BadgeStatus golden path callouts
  - Clearly marked as "THE proof-of-concept" and "SOURCE OF TRUTH"
  - Added in component-architecture.md, component-creation.md, component-enum-union-migration.md

- Add warnings to template references
  - ⚠️ callouts explaining templates are NOT ADR-compliant
  - 4 transformation steps required after scaffolding

- Enhance story naming examples
  - Added 5 concrete examples (variant → Variant, size → Size, etc.)

## Benefits
- Reduced maintenance: Code examples reference actual implementations
- Single source of truth: BadgeStatus is THE canonical example
- Consistency: All docs use same patterns
- Clarity: AI agents get non-contradictory guidance
- Up-to-date: References stay current automatically

## Files Modified
- .cursor/rules/component-architecture.md
- .cursor/rules/component-creation.md
- .cursor/rules/component-migration.md
- .cursor/rules/component-enum-union-migration.md
- .cursor/rules/component-documentation.md

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude <noreply@anthropic.com>
Address PR review feedback from georgewrmarshall:
- Add ADR links in Purpose section of component-architecture.md
- Update all ADR references from PR links to main branch document links
- Ensures documentation remains accessible even after PRs are merged

Changes:
- component-architecture.md: Added clickable ADR links in Purpose section (lines 9-10)
- Updated ADR-0003 reference from PR #127 to document link (line 58)
- Updated ADR-0004 reference from PR #128 to document link (line 166)
- Updated References section ADR links (lines 398-399)
- component-creation.md: Updated ADR links in MetaMask Standards section
- component-migration.md: Updated ADR links in Architecture Decision Records section
- component-enum-union-migration.md: Updated ADR links in Architecture Decision Records section

All ADR references now point to:
- https://github.com/MetaMask/decisions/blob/main/decisions/design-system/0003-enum-to-string-union-migration.md
- https://github.com/MetaMask/decisions/blob/main/decisions/design-system/0004-centralized-types-architecture.md

Related: #911 (review comments)
Following ai-agents.md principle: '200-400 lines per file (checklists, not novels)'

Changes:
- component-creation.md: 661 → 355 lines (46% reduction)
  - Replaced full code examples with references to BadgeStatus
  - Merged React/React Native steps (95% identical)
  - Condensed tutorials to actionable checklists

- component-migration.md: 440 → 332 lines (24% reduction)
  - Condensed audit phase tutorial to checklist
  - Referenced component-creation.md and styling.md for implementation
  - Collapsed scenarios to decision tree

- component-enum-union-migration.md: 403 → 218 lines (46% reduction)
  - Referenced component-architecture.md for all patterns
  - Removed duplicated type examples
  - Converted steps to workflow checklist

- figma-integration.md: 423 → 303 lines (28% reduction)
  - Combined six prop mapping examples into one comprehensive
  - Removed repetitive wizard steps
  - Streamlined critical rules to checklist

Total: 2,730 → 2,011 lines (26% reduction, 719 lines saved)

All files now closer to 200-400 line target while maintaining effectiveness
as AI agent guardrails using 'reference over duplication' principle.
Following ai-agents.md principle: '200-400 lines per file (checklists, not novels)'

Changes:
- component-architecture.md: 410 → 168 lines (59% reduction)

Condensation strategies:
- Removed ADR benefits/usage sections, linked to ADRs instead
- Condensed full three-layer example to minimal pattern + reference
- Merged decision table + quick rules - removed redundancy
- Kept BadgeStatus references prominent

Final status: ALL cursor rules files now within 200-400 line target:
  109 component-documentation.md
  168 component-architecture.md ✅
  224 component-enum-union-migration.md
  284 styling.md
  306 figma-integration.md
  342 component-migration.md
  357 component-creation.md
  1790 total (was 2730, saved 940 lines / 34% reduction)
Updated cursor rules to document correct export pattern:
- Component index.ts exports directly from @metamask/design-system-shared
- Platform src/types/index.ts should NOT re-export shared types
- Added verification checklist items for correct pattern

Files updated:
- component-enum-union-migration.md: Updated step 4, added step 5
- component-architecture.md: Added "Component Index Export Pattern" section
- component-creation.md: Added checklist item for export pattern

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude <noreply@anthropic.com>
Updated component creation documentation to prevent duplicate enum exports
that reduce test coverage:

- component-creation.md: Added critical warning that .types.ts files should
  ONLY import, never re-export enums. Enums exported from index.ts only.
- component-enum-union-migration.md: Clarified migration pattern with
  explicit examples showing .types.ts import-only pattern.
- Added anti-pattern sections showing the exact issue that caused BadgeCount
  coverage loss.

Pattern:
- .types.ts: Import only (prevents duplicate exports)
- index.ts: Single export location for enums (single source of truth)

This prevents Jest coverage failures from uncovered duplicate export paths.
Replaced "enum" terminology with "const object" throughout documentation
to accurately reflect ADR-0003 pattern and avoid confusion with TypeScript
enums.

Updated terminology:
- "enum exports" → "const object exports"
- "enum re-exports" → "const object re-exports"
- "design token enums" → "design token const objects"

Preserved "enum" only when referring to:
- TypeScript enums in anti-pattern examples
- File names (component-enum-union-migration.md)
- ADR-0003 title references
- Old TypeScript enums being migrated/removed

This clarifies that we're working with const objects (as const), not
TypeScript enums, making the documentation more precise and educational.
Establishes foundational architectural patterns for components:
- ADR-0003: Const objects over TypeScript enums
- ADR-0004: Centralized types in shared package
- Layered architecture with one-way dependencies
- Two-file export pattern preventing test coverage loss

This rule provides the foundation that other cursor rules reference.
Validated through BadgeCount migration (PR #942) which demonstrated
the coverage issue when duplicate exports exist.

References BadgeStatus as the golden path proof-of-concept for
these patterns.
@github-actions

Copy link
Copy Markdown
Contributor

📖 Storybook Preview

@georgewrmarshall georgewrmarshall self-assigned this Feb 26, 2026

@georgewrmarshall georgewrmarshall left a comment

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

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

Left some comments

Comment thread .cursor/rules/component-architecture.md Outdated
Comment thread .cursor/rules/figma-integration.md
@github-actions

Copy link
Copy Markdown
Contributor

📖 Storybook Preview

- Platform-Specific Props: Layered architecture pattern
- Cross-platform consistency principles

**This is the foundation** - other component rules reference these patterns.

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

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

Foundation file establishing architectural patterns that other component rules reference. Consolidates ADR-0003 (const objects), ADR-0004 (centralized types), and layered architecture into single source of truth.

**Event handlers:**

- ❌ NO unified handlers in shared (no `onAction`)
- ✅ React: `onClick` from `ComponentProps<'element'>`

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

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

Critical decision: Platform packages use idiomatic APIs (onClick vs onPress) rather than unified abstractions. Maintains platform conventions and developer familiarity at the cost of slight duplication.


// ❌ Wrong - Separate type exports cause duplicate identifier errors
export { BadgeStatusStatus, BadgeStatusSize } from '...';
export type { BadgeStatusStatus, BadgeStatusSize } from '...'; // Error!

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

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

Export pattern prevents TypeScript duplicate identifier errors when const object and type share the same name. Inline type keyword is required for safe re-exports.

// ❌ Wrong - Don't re-export through src/types/index.ts
// packages/design-system-react/src/components/BadgeStatus/index.ts
export { BadgeStatusStatus, BadgeStatusSize } from '../../types';
export { BadgeStatus } from './BadgeStatus';

@georgewrmarshall georgewrmarshall Feb 26, 2026

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

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

src/types/index.ts was an intermediary step introduced to prevent circular dependencies. With the new shared package architecture, it is no longer needed.


- @packages/design-system-shared/src/types/BadgeStatus/ (Shared types - SOURCE OF TRUTH)
- @packages/design-system-react/src/components/BadgeStatus/ (React implementation)
- @packages/design-system-react-native/src/components/BadgeStatus/ (React Native implementation)

@georgewrmarshall georgewrmarshall Feb 26, 2026

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

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

BadgeStatus is the only component currently following ADR-0003 and ADR-0004 we can use it as the golden path here

- `size` prop → `Size` story
- `isDisabled` prop → `IsDisabled` story
- `isLoading` prop → `IsLoading` story
- `status` prop → `Status` story

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

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

Clarifies story naming convention with concrete examples. Each prop gets its own story named in PascalCase for consistency and discoverability.

Comment thread CLAUDE.md

- @.cursor/rules/styling.md
- @.cursor/rules/component-documentation.md
- @.cursor/rules/component-architecture.md

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

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

Integrates component-architecture.md into Claude Code session loading. This file serves as the foundation that other component rules reference.

Comment thread CLAUDE.md

# Component Creation
yarn create-component:react --name ComponentName --description "Brief description"
yarn create-component:react-native --name ComponentName --description "Brief description"

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

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

Documents available React Native component creation script. Previously only React script was mentioned but both platforms support automated scaffolding.

Comment thread docs/ai-agents.md
- `cross-platform.md` - Cross platform consistency and shared types
- `component-documentation.md` - Storybook and README standards
- `figma-integration.md` - Code Connect

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

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

Updates AI agent documentation to reflect current state of cursor rules. Component-architecture.md and related workflow files have been added to guide AI agents on component patterns.

@georgewrmarshall georgewrmarshall marked this pull request as ready for review February 26, 2026 21:13
@georgewrmarshall georgewrmarshall requested a review from a team as a code owner February 26, 2026 21:13
georgewrmarshall added a commit that referenced this pull request Feb 26, 2026
- Remove Box/Button examples (align with PR #943 - these components don't follow ADR-0003/0004 yet)
- Add Step 11: Verify Coverage section with critical warning about duplicate exports
- Add coverage check to verification checklist
- Clarify type vs interface rule with composition/intersection rationale
- Reference BadgeCount PR #942 coverage issue as real-world example

Addresses review feedback from PR #944 code review
@georgewrmarshall georgewrmarshall enabled auto-merge (squash) February 27, 2026 00:30
@github-actions

Copy link
Copy Markdown
Contributor

📖 Storybook Preview

@georgewrmarshall georgewrmarshall merged commit 901b71a into main Feb 27, 2026
43 checks passed
@georgewrmarshall georgewrmarshall deleted the docs/component-architecture-cursor-rule branch February 27, 2026 00:33
georgewrmarshall added a commit that referenced this pull request Mar 3, 2026
## **Description**

Adds `component-architecture.md` cursor rule establishing foundational
architectural patterns for design system components. This rule documents
[ADR-0003](https://github.com/MetaMask/decisions/blob/main/decisions/design-system/0003-enum-to-string-union-migration.md)
(const objects over TypeScript enums) and
[ADR-0004](https://github.com/MetaMask/decisions/blob/main/decisions/design-system/0004-centralized-types-architecture.md)
(centralized types architecture) patterns.

**Key patterns documented:**
- Two-file export structure: `.types.ts` for imports only, `index.ts`
for exports only
- Const objects with `as const` instead of TypeScript enums
- Centralized types in `@metamask/design-system-shared` package
- Layered architecture with one-way dependencies (shared → platform
packages)
- Cross-platform consistency between React and React Native

**Why this matters:**
We need to ensure our components are consistent across platforms and use
the most up to date typescript conventions

**References:**
- Golden path: BadgeStatus component implementation
- Validation: BadgeCount PR #942 was created using
component-architecture.md, component-creation.md, component-migration.md

## **Related issues**

Fixes: https://consensyssoftware.atlassian.net/browse/DSYS-339

## **Manual testing steps**

1. Review the cursor rule file:
`.cursor/rules/component-architecture.md`
2. Check out the BadgeCount PR #942
3. Verify CLAUDE.md includes reference to this new rule

## **Screenshots/Recordings**

N/A - Documentation only

## **Pre-merge author checklist**

- [x] I've followed [MetaMask Contributor
Docs](https://github.com/MetaMask/contributor-docs)
- [x] I've completed the PR template to the best of my ability
- [x] I've included tests if applicable (N/A - documentation)
- [x] I've documented my code using [JSDoc](https://jsdoc.app/) format
if applicable (N/A - markdown)
- [ ] I've applied the right labels on the PR (see [labeling
guidelines](https://github.com/MetaMask/metamask-extension/blob/develop/.github/guidelines/LABELING_GUIDELINES.md)).
Not required for external contributors.

## **Pre-merge reviewer checklist**

- [ ] I've manually tested the PR (e.g. pull and build branch, run the
app, test code being changed).
- [ ] I confirm that this PR addresses all acceptance criteria described
in the ticket it closes and includes the necessary testing evidence such
as recordings and or screenshots.

<!-- CURSOR_SUMMARY -->
---

> [!NOTE]
> **Low Risk**
> Low risk documentation-only change that doesn’t affect runtime
behavior. Risk is limited to developers/agents following the new
guidance incorrectly.
> 
> **Overview**
> Adds a new Cursor rule, `.cursor/rules/component-architecture.md`,
documenting the design-system component architecture standards (ADR-0003
const-object string unions over enums, ADR-0004 centralized shared
types, and layered shared vs platform props), including export/re-export
patterns and a cross-platform verification checklist.
> 
> Updates AI-agent docs to reference the new rule (`CLAUDE.md`,
`docs/ai-agents.md`) and clarifies Storybook story naming conventions in
`.cursor/rules/component-documentation.md` with explicit prop-to-story
examples.
> 
> <sup>Written by [Cursor
Bugbot](https://cursor.com/dashboard?tab=bugbot) for commit
bc55943. This will update automatically
on new commits. Configure
[here](https://cursor.com/dashboard?tab=bugbot).</sup>
<!-- /CURSOR_SUMMARY -->

---------

Co-authored-by: Claude <noreply@anthropic.com>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants