Skip to content

Commit 2b22e60

Browse files
committed
feat: save
1 parent d750d0f commit 2b22e60

22 files changed

Lines changed: 1074 additions & 232 deletions

File tree

.cursor/rules/global-rules.mdc

Lines changed: 240 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,240 @@
1+
---
2+
description:
3+
globs:
4+
alwaysApply: false
5+
---
6+
---
7+
description: Rules that apply to all packages in the monorepo
8+
globs: **/*.{ts,tsx,js,jsx}
9+
---
10+
# Component Library Generation Context
11+
12+
When generating React component libraries similar to Clerk Elements, follow these principles and patterns to maintain a consistent and developer-friendly experience.
13+
14+
## Core Principles
15+
16+
1. **Compound Components Pattern**
17+
- Components should be namespaced under a single parent (e.g., `FormWizard.Root`, `FormWizard.Step`)
18+
- State should be managed through React Context
19+
- Components must be composable and work together seamlessly
20+
- Components should handle their own state management and validation
21+
22+
2. **Type Safety**
23+
- Always implement full TypeScript support
24+
- Use proper type definitions for all props and refs
25+
- Implement proper generic constraints where necessary
26+
- Export type definitions for public API
27+
- Avoid TypeScript enums due to their runtime overhead and tree-shaking limitations; use const objects or 'as const' assertions instead:
28+
```typescript
29+
// Instead of enum:
30+
enum Status { Active, Inactive }
31+
// Prefer:
32+
const Status = {
33+
Active: 'active',
34+
Inactive: 'inactive'
35+
} as const;
36+
37+
// Or:
38+
const Status = Object.freeze({
39+
Active: 'active',
40+
Inactive: 'inactive'
41+
});
42+
```
43+
44+
3. **Accessibility**
45+
- Support keyboard navigation
46+
- Include proper ARIA attributes
47+
- Support screen readers through semantic markup
48+
- Maintain focus management
49+
50+
4. **Component Structure**
51+
52+
Each component should follow this pattern:
53+
```typescript
54+
import { forwardRef, type ComponentRef, HTMLAttributes, ReactNode } from 'react';
55+
56+
type ComponentElement = ComponentRef<'element_type'>;
57+
type ComponentProps = {
58+
// Required props first
59+
name?: string;
60+
children?: ReactNode;
61+
62+
// Optional features
63+
asChild?: boolean;
64+
className?: string;
65+
66+
// Additional type extensions
67+
} & HTMLAttributes<HTMLElementType>;
68+
69+
export const Component = forwardRef<ComponentElement, ComponentProps>((
70+
{ asChild, children, className, ...props },
71+
ref
72+
) => {
73+
// Implementation
74+
});
75+
```
76+
77+
5. **Error Handling**
78+
- Provide clear error messages for development
79+
- Implement runtime checks for required context/props
80+
- Use descriptive error messages that guide developers
81+
82+
## Component Patterns
83+
84+
### Root Component
85+
- Serves as the main context provider
86+
- Manages global state
87+
- Handles initialization
88+
- Example structure:
89+
```typescript
90+
import { FC } from 'react';
91+
92+
export const Root: FC<RootProps> = ({
93+
children,
94+
...props
95+
}) => {
96+
return (
97+
<Context.Provider value={...}>
98+
{children}
99+
</Context.Provider>
100+
);
101+
};
102+
```
103+
104+
### Child Components
105+
- Must be used within Root component
106+
- Access context through hooks
107+
- Support composition through asChild prop
108+
- Follow consistent prop patterns
109+
110+
### Context Usage
111+
- Create dedicated hooks for context access
112+
- Implement proper error boundaries
113+
- Provide clear error messages for misuse
114+
115+
## Developer Experience
116+
117+
1. **Props Pattern**
118+
- Required props should be listed first
119+
- Optional props should have clear defaults
120+
- Support common HTML attributes
121+
- Allow style customization through className
122+
123+
2. **Composition Support**
124+
- Implement asChild prop using Radix UI's Slot
125+
- Allow component replacement while maintaining functionality
126+
- Support custom styling and rendering
127+
128+
3. **Error Messages**
129+
Provide clear error messages in these scenarios:
130+
- Components used outside of context
131+
- Missing required props
132+
- Invalid prop combinations
133+
- Runtime validation failures
134+
135+
## Documentation Structure
136+
137+
For each component, document:
138+
1. Purpose and use case
139+
2. Required and optional props
140+
3. Context requirements
141+
4. Example usage
142+
5. Common pitfalls
143+
144+
Example documentation format:
145+
```typescript
146+
/**
147+
* The `<Component>` is used for [purpose].
148+
* Must be used within `<Parent>` component.
149+
*
150+
* @param {string} name - Unique identifier for the component
151+
* @param {boolean} [asChild] - Replace the component with a custom element
152+
* @param {string} [className] - Additional CSS classes
153+
*
154+
* @example
155+
* <Parent>
156+
* <Component name="example">
157+
* {...children}
158+
* </Component>
159+
* </Parent>
160+
*/
161+
```
162+
163+
## Implementation Guidelines
164+
165+
1. **State Management**
166+
- Use React Context for global state
167+
- Implement proper state updates
168+
- Handle side effects appropriately
169+
170+
2. **Validation**
171+
- Implement runtime checks
172+
- Validate prop combinations
173+
- Provide clear error messages
174+
175+
3. **Styling**
176+
- Support className prop
177+
- Use data attributes for states
178+
- Allow style customization
179+
180+
4. **Event Handling**
181+
- Support standard DOM events
182+
- Implement custom events when needed
183+
- Handle event propagation properly
184+
185+
## Common Patterns
186+
187+
1. **Context Creation**
188+
```typescript
189+
import { createContext, useContext } from 'react';
190+
191+
const Context = createContext<ContextType | null>(null);
192+
193+
const useComponentContext = () => {
194+
const context = useContext(Context);
195+
if (!context) {
196+
throw new Error(
197+
'Component must be used within Parent'
198+
);
199+
}
200+
return context;
201+
};
202+
```
203+
204+
2. **Component Base**
205+
```typescript
206+
import { forwardRef } from 'react';
207+
208+
export const Component = forwardRef<Element, Props>((
209+
{ asChild, children, className, ...props },
210+
ref
211+
) => {
212+
const Comp = asChild ? Slot : 'div';
213+
return (
214+
<Comp
215+
ref={ref}
216+
className={className}
217+
{...props}
218+
>
219+
{children}
220+
</Comp>
221+
);
222+
});
223+
```
224+
225+
3. **Error Handling**
226+
```typescript
227+
if (!condition) {
228+
throw new Error(
229+
'Clear error message with component name and required context/props'
230+
);
231+
}
232+
```
233+
234+
## Testing Considerations
235+
236+
Guide the LLM to include:
237+
1. Unit tests for components
238+
2. Integration tests for component combinations
239+
3. Accessibility tests
240+
4. Error boundary tests

0 commit comments

Comments
 (0)