@claudetools/tools 0.9.0 → 0.9.2
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/cli.js +9 -1
- package/dist/codedna/__tests__/examples/mongoose-example.d.ts +6 -0
- package/dist/codedna/__tests__/examples/mongoose-example.js +163 -0
- package/dist/codedna/__tests__/fixtures/typeorm-production-test.d.ts +1 -0
- package/dist/codedna/__tests__/fixtures/typeorm-production-test.js +231 -0
- package/dist/codedna/__tests__/fixtures/typeorm-test.d.ts +1 -0
- package/dist/codedna/__tests__/fixtures/typeorm-test.js +124 -0
- package/dist/codedna/__tests__/laravel-output-review.d.ts +1 -0
- package/dist/codedna/__tests__/laravel-output-review.js +249 -0
- package/dist/codedna/__tests__/mongoose-output-test.d.ts +1 -0
- package/dist/codedna/__tests__/mongoose-output-test.js +178 -0
- package/dist/codedna/examples/radix-example.d.ts +2 -0
- package/dist/codedna/examples/radix-example.js +259 -0
- package/dist/codedna/index.d.ts +5 -3
- package/dist/codedna/index.js +6 -3
- package/dist/codedna/kappa-ast.d.ts +143 -5
- package/dist/codedna/kappa-drizzle-generator.js +8 -5
- package/dist/codedna/kappa-gofiber-generator.d.ts +65 -0
- package/dist/codedna/kappa-gofiber-generator.js +587 -0
- package/dist/codedna/kappa-laravel-generator.d.ts +68 -0
- package/dist/codedna/kappa-laravel-generator.js +741 -0
- package/dist/codedna/kappa-lexer.d.ts +44 -0
- package/dist/codedna/kappa-lexer.js +124 -0
- package/dist/codedna/kappa-mantine-generator.d.ts +65 -0
- package/dist/codedna/kappa-mantine-generator.js +518 -0
- package/dist/codedna/kappa-mongoose-generator.d.ts +44 -0
- package/dist/codedna/kappa-mongoose-generator.js +442 -0
- package/dist/codedna/kappa-parser.d.ts +43 -1
- package/dist/codedna/kappa-parser.js +601 -0
- package/dist/codedna/kappa-radix-generator.d.ts +61 -0
- package/dist/codedna/kappa-radix-generator.js +566 -0
- package/dist/codedna/kappa-typeorm-generator.d.ts +59 -0
- package/dist/codedna/kappa-typeorm-generator.js +723 -0
- package/dist/codedna/kappa-vitest-generator.d.ts +85 -0
- package/dist/codedna/kappa-vitest-generator.js +739 -0
- package/dist/codedna/parser.js +26 -1
- package/dist/codegen/cloud-client.d.ts +160 -0
- package/dist/codegen/cloud-client.js +195 -0
- package/dist/codegen/codegen-tool.d.ts +35 -0
- package/dist/codegen/codegen-tool.js +312 -0
- package/dist/codegen/field-inference.d.ts +24 -0
- package/dist/codegen/field-inference.js +101 -0
- package/dist/codegen/form-parser.d.ts +13 -0
- package/dist/codegen/form-parser.js +186 -0
- package/dist/codegen/index.d.ts +2 -0
- package/dist/codegen/index.js +4 -0
- package/dist/codegen/natural-parser.d.ts +50 -0
- package/dist/codegen/natural-parser.js +769 -0
- package/dist/handlers/codedna-handlers.d.ts +1 -1
- package/dist/handlers/codegen-handlers.d.ts +20 -0
- package/dist/handlers/codegen-handlers.js +60 -0
- package/dist/handlers/kappa-handlers.d.ts +97 -0
- package/dist/handlers/kappa-handlers.js +408 -0
- package/dist/handlers/tool-handlers.js +124 -221
- package/dist/helpers/api-client.js +48 -3
- package/dist/helpers/compact-formatter.d.ts +9 -2
- package/dist/helpers/compact-formatter.js +26 -2
- package/dist/helpers/config.d.ts +7 -2
- package/dist/helpers/config.js +25 -10
- package/dist/helpers/session-validation.d.ts +1 -1
- package/dist/helpers/session-validation.js +2 -4
- package/dist/helpers/tasks.d.ts +21 -0
- package/dist/helpers/tasks.js +52 -0
- package/dist/helpers/workers.d.ts +1 -1
- package/dist/helpers/workers.js +19 -19
- package/dist/setup.d.ts +1 -0
- package/dist/setup.js +228 -3
- package/dist/templates/claude-md.d.ts +1 -1
- package/dist/templates/claude-md.js +37 -152
- package/dist/templates/orchestrator-prompt.d.ts +2 -2
- package/dist/templates/orchestrator-prompt.js +31 -38
- package/dist/templates/self-critique.d.ts +50 -0
- package/dist/templates/self-critique.js +209 -0
- package/dist/templates/worker-prompt.d.ts +3 -3
- package/dist/templates/worker-prompt.js +18 -18
- package/dist/tools.js +77 -413
- package/docs/codedna/generator-testing-summary.md +205 -0
- package/docs/codedna/radix-ui-generator.md +478 -0
- package/docs/kappa-gofiber-generator.md +274 -0
- package/docs/kappa-laravel-fixes.md +172 -0
- package/docs/kappa-mongoose-generator.md +322 -0
- package/docs/kappa-vitest-generator.md +337 -0
- package/package.json +1 -1
- package/dist/context/deduplication.test.d.ts +0 -6
- package/dist/context/deduplication.test.js +0 -84
|
@@ -0,0 +1,205 @@
|
|
|
1
|
+
# Kappa Radix UI and Mantine Generator Testing Summary
|
|
2
|
+
|
|
3
|
+
## Overview
|
|
4
|
+
|
|
5
|
+
Comprehensive testing and fixes applied to the Kappa v2.5 Radix UI and Mantine component generators for production readiness.
|
|
6
|
+
|
|
7
|
+
## Tests Completed
|
|
8
|
+
|
|
9
|
+
### Test Suites
|
|
10
|
+
1. **Radix Generator Tests** (`kappa-radix-generator.test.ts`): 12 tests
|
|
11
|
+
2. **Mantine Generator Tests** (`kappa-mantine-generator.test.ts`): 14 tests ✨ NEW
|
|
12
|
+
3. **Syntax Validation Tests** (`syntax-validation.test.ts`): 5 tests ✨ NEW
|
|
13
|
+
|
|
14
|
+
**Total: 31 tests - All passing ✅**
|
|
15
|
+
|
|
16
|
+
## Issues Found and Fixed
|
|
17
|
+
|
|
18
|
+
### Radix Generator
|
|
19
|
+
|
|
20
|
+
#### 1. Incorrect ref type on simple components
|
|
21
|
+
**Issue:** Used `React.ElementRef<typeof Dialog.Root>` when the ref is actually forwarded to `Dialog.Content`
|
|
22
|
+
|
|
23
|
+
**Fix:**
|
|
24
|
+
```typescript
|
|
25
|
+
// Before
|
|
26
|
+
React.forwardRef<React.ElementRef<typeof Dialog.Root>, Props>
|
|
27
|
+
|
|
28
|
+
// After
|
|
29
|
+
React.forwardRef<React.ElementRef<typeof Dialog.Content>, Props>
|
|
30
|
+
```
|
|
31
|
+
|
|
32
|
+
#### 2. Missing props spread
|
|
33
|
+
**Issue:** Simple components didn't spread remaining props to the Radix component
|
|
34
|
+
|
|
35
|
+
**Fix:**
|
|
36
|
+
```tsx
|
|
37
|
+
// Before
|
|
38
|
+
<Dialog.Content ref={ref} className={cn(className)}>
|
|
39
|
+
|
|
40
|
+
// After
|
|
41
|
+
<Dialog.Content ref={ref} className={cn(className)} {...props}>
|
|
42
|
+
```
|
|
43
|
+
|
|
44
|
+
#### 3. Invalid compound component syntax
|
|
45
|
+
**Issue:** Compound component parts had incorrect forwardRef arrow function syntax
|
|
46
|
+
|
|
47
|
+
**Fix:**
|
|
48
|
+
```typescript
|
|
49
|
+
// Before (invalid syntax)
|
|
50
|
+
>(({ props }: Props, ref) => (
|
|
51
|
+
|
|
52
|
+
// After (correct multi-line format)
|
|
53
|
+
>((
|
|
54
|
+
{ props }: Props,
|
|
55
|
+
ref
|
|
56
|
+
) => (
|
|
57
|
+
```
|
|
58
|
+
|
|
59
|
+
### Mantine Generator
|
|
60
|
+
|
|
61
|
+
#### 1. Invalid initial values for form fields
|
|
62
|
+
**Issue:** Initial values were double-stringified, generating `"''"` instead of `''`
|
|
63
|
+
|
|
64
|
+
**Fix:**
|
|
65
|
+
```typescript
|
|
66
|
+
// Before
|
|
67
|
+
values[field.name] = "''"; // Generates: "email": "''"
|
|
68
|
+
values[field.name] = '0'; // Generates: "age": "0" (string!)
|
|
69
|
+
|
|
70
|
+
// After
|
|
71
|
+
values[field.name] = ''; // Generates: "email": ""
|
|
72
|
+
values[field.name] = 0; // Generates: "age": 0 (number!)
|
|
73
|
+
```
|
|
74
|
+
|
|
75
|
+
#### 2. Missing React imports for compound components
|
|
76
|
+
**Issue:** Compound components use `createContext` and `useContext` but didn't import them
|
|
77
|
+
|
|
78
|
+
**Fix:**
|
|
79
|
+
```typescript
|
|
80
|
+
if (component.compound && component.compound.length > 0) {
|
|
81
|
+
lines.push("import { createContext, useContext } from 'react';");
|
|
82
|
+
}
|
|
83
|
+
```
|
|
84
|
+
|
|
85
|
+
## Test Coverage
|
|
86
|
+
|
|
87
|
+
### Radix Generator
|
|
88
|
+
- ✅ Primitive detection (Dialog, Popover, Accordion)
|
|
89
|
+
- ✅ Simple component generation
|
|
90
|
+
- ✅ Compound component generation
|
|
91
|
+
- ✅ TypeScript/JavaScript toggle
|
|
92
|
+
- ✅ forwardRef usage
|
|
93
|
+
- ✅ Proper Radix UI imports
|
|
94
|
+
- ✅ Accessibility documentation
|
|
95
|
+
- ✅ Tailwind integration with `cn()` utility
|
|
96
|
+
- ✅ Props interface extends correct Radix component
|
|
97
|
+
- ✅ Configuration options (basePath, provenance, a11yDocs)
|
|
98
|
+
|
|
99
|
+
### Mantine Generator
|
|
100
|
+
- ✅ Simple component generation
|
|
101
|
+
- ✅ Compound component generation with Context API
|
|
102
|
+
- ✅ Form generation with Zod validation
|
|
103
|
+
- ✅ All field types (text, textarea, number, email, password, checkbox, select, date, time, datetime, file)
|
|
104
|
+
- ✅ Form layout (grouped fields)
|
|
105
|
+
- ✅ Initial values with correct types (string, number, boolean, array)
|
|
106
|
+
- ✅ TypeScript/JavaScript toggle
|
|
107
|
+
- ✅ forwardRef support
|
|
108
|
+
- ✅ Zod validation toggle
|
|
109
|
+
- ✅ Configuration options (basePath, provenance, zod, forwardRef)
|
|
110
|
+
|
|
111
|
+
### Syntax Validation
|
|
112
|
+
- ✅ TypeScript transpilation validation for all generated code
|
|
113
|
+
- ✅ Validates Radix simple components
|
|
114
|
+
- ✅ Validates Radix compound components
|
|
115
|
+
- ✅ Validates Mantine components
|
|
116
|
+
- ✅ Validates Mantine forms
|
|
117
|
+
|
|
118
|
+
## Production Readiness Checklist
|
|
119
|
+
|
|
120
|
+
### Code Quality
|
|
121
|
+
- ✅ Valid TypeScript syntax
|
|
122
|
+
- ✅ Proper React component patterns
|
|
123
|
+
- ✅ Correct forwardRef usage
|
|
124
|
+
- ✅ Props interfaces extend appropriate base types
|
|
125
|
+
- ✅ Props spread to maintain flexibility
|
|
126
|
+
|
|
127
|
+
### Accessibility
|
|
128
|
+
- ✅ Radix UI primitives provide automatic ARIA attributes
|
|
129
|
+
- ✅ Accessibility documentation comments included
|
|
130
|
+
- ✅ Keyboard navigation support noted
|
|
131
|
+
- ✅ Focus management documented
|
|
132
|
+
|
|
133
|
+
### Component Composition
|
|
134
|
+
- ✅ Compound components use proper pattern
|
|
135
|
+
- ✅ Context API used correctly in Mantine compound components
|
|
136
|
+
- ✅ Radix compound components use Object.assign pattern
|
|
137
|
+
- ✅ Display names set for all components
|
|
138
|
+
|
|
139
|
+
### Form Handling
|
|
140
|
+
- ✅ Mantine useForm integration
|
|
141
|
+
- ✅ Zod validation schemas generated correctly
|
|
142
|
+
- ✅ All field types mapped to Mantine components
|
|
143
|
+
- ✅ Initial values have correct TypeScript types
|
|
144
|
+
- ✅ Form submission handlers with loading states
|
|
145
|
+
- ✅ Error handling patterns
|
|
146
|
+
|
|
147
|
+
### Developer Experience
|
|
148
|
+
- ✅ Provenance comments (can be toggled off)
|
|
149
|
+
- ✅ Clear TypeScript interfaces
|
|
150
|
+
- ✅ Configurable output paths
|
|
151
|
+
- ✅ TypeScript can be disabled for JS projects
|
|
152
|
+
|
|
153
|
+
## Generated Code Examples
|
|
154
|
+
|
|
155
|
+
### Radix Compound Component
|
|
156
|
+
```tsx
|
|
157
|
+
const AccordionItem = React.forwardRef<
|
|
158
|
+
React.ElementRef<typeof Accordion.Item>,
|
|
159
|
+
AccordionItemProps
|
|
160
|
+
>((
|
|
161
|
+
{ className, children, ...props }: AccordionItemProps,
|
|
162
|
+
ref
|
|
163
|
+
) => (
|
|
164
|
+
<Accordion.Item
|
|
165
|
+
ref={ref}
|
|
166
|
+
className={cn('accordion-item', className)}
|
|
167
|
+
{...props}
|
|
168
|
+
>
|
|
169
|
+
{children}
|
|
170
|
+
</Accordion.Item>
|
|
171
|
+
));
|
|
172
|
+
|
|
173
|
+
AccordionItem.displayName = 'AccordionItem';
|
|
174
|
+
```
|
|
175
|
+
|
|
176
|
+
### Mantine Form with Correct Initial Values
|
|
177
|
+
```tsx
|
|
178
|
+
const form = useForm<UserFormData>({
|
|
179
|
+
validate: zodResolver(userSchema),
|
|
180
|
+
initialValues: initialValues ?? {
|
|
181
|
+
"email": "", // Empty string
|
|
182
|
+
"age": 0, // Number zero
|
|
183
|
+
"newsletter": false // Boolean false
|
|
184
|
+
},
|
|
185
|
+
});
|
|
186
|
+
```
|
|
187
|
+
|
|
188
|
+
## Recommendations for Future
|
|
189
|
+
|
|
190
|
+
1. **Add ESLint validation** to test pipeline to catch common React patterns
|
|
191
|
+
2. **Consider Prettier formatting** of generated code
|
|
192
|
+
3. **Add integration tests** that actually compile and render components
|
|
193
|
+
4. **Document edge cases** for unusual Kappa specifications
|
|
194
|
+
5. **Add performance tests** for large-scale generation
|
|
195
|
+
|
|
196
|
+
## Conclusion
|
|
197
|
+
|
|
198
|
+
Both generators are now **production-ready** with:
|
|
199
|
+
- ✅ All existing tests passing
|
|
200
|
+
- ✅ 14 new Mantine tests added
|
|
201
|
+
- ✅ 5 syntax validation tests added
|
|
202
|
+
- ✅ Critical bugs fixed
|
|
203
|
+
- ✅ Valid TypeScript output guaranteed
|
|
204
|
+
- ✅ Proper React patterns enforced
|
|
205
|
+
- ✅ Accessibility considerations met
|
|
@@ -0,0 +1,478 @@
|
|
|
1
|
+
# Radix UI Component Generator
|
|
2
|
+
|
|
3
|
+
**File:** `src/codedna/kappa-radix-generator.ts`
|
|
4
|
+
**Status:** Phase 1 - JS/TS Ecosystem
|
|
5
|
+
**Generated:** 2026-01-03
|
|
6
|
+
|
|
7
|
+
## Overview
|
|
8
|
+
|
|
9
|
+
The Radix UI Component Generator creates React components using [Radix UI](https://www.radix-ui.com/) primitives from Kappa ComponentBlock AST. Radix UI provides unstyled, accessible components that can be composed with Tailwind CSS for complete design control while maintaining accessibility.
|
|
10
|
+
|
|
11
|
+
## Features
|
|
12
|
+
|
|
13
|
+
- **Automatic Primitive Detection** - Infers Radix primitive from component name or structure
|
|
14
|
+
- **Compound Components** - Generates compound component patterns with proper composition
|
|
15
|
+
- **TypeScript Support** - Full type safety with props extending Radix types
|
|
16
|
+
- **Accessibility** - Built-in ARIA attributes and keyboard navigation
|
|
17
|
+
- **ForwardRef** - All components use `React.forwardRef` for ref forwarding
|
|
18
|
+
- **Provenance Tracking** - Comments linking generated code back to spec
|
|
19
|
+
- **Tailwind CSS** - Composable styling with `cn()` utility
|
|
20
|
+
|
|
21
|
+
## Supported Primitives
|
|
22
|
+
|
|
23
|
+
| Kappa Pattern | Radix Primitive | Package | Use Case |
|
|
24
|
+
|---------------|-----------------|---------|----------|
|
|
25
|
+
| Dialog/Modal | Dialog | `@radix-ui/react-dialog` | Modal dialogs, confirmation prompts |
|
|
26
|
+
| Popover | Popover | `@radix-ui/react-popover` | User menus, tooltips with content |
|
|
27
|
+
| Select/Dropdown | Select | `@radix-ui/react-select` | Form selects, dropdowns |
|
|
28
|
+
| Dropdown | DropdownMenu | `@radix-ui/react-dropdown-menu` | Context menus, action menus |
|
|
29
|
+
| Tabs | Tabs | `@radix-ui/react-tabs` | Tabbed interfaces |
|
|
30
|
+
| Accordion | Accordion | `@radix-ui/react-accordion` | Collapsible sections |
|
|
31
|
+
| Tooltip | Tooltip | `@radix-ui/react-tooltip` | Hover tooltips |
|
|
32
|
+
|
|
33
|
+
## Usage
|
|
34
|
+
|
|
35
|
+
### Basic API
|
|
36
|
+
|
|
37
|
+
```typescript
|
|
38
|
+
import { generateRadixComponents } from '@claudetools/tools/codedna/kappa-radix-generator';
|
|
39
|
+
import type { ComponentBlock } from '@claudetools/tools/codedna/kappa-ast';
|
|
40
|
+
|
|
41
|
+
const components: ComponentBlock[] = [
|
|
42
|
+
// ... your component specs
|
|
43
|
+
];
|
|
44
|
+
|
|
45
|
+
const result = generateRadixComponents(components, {
|
|
46
|
+
provenance: true, // Add provenance comments
|
|
47
|
+
typescript: true, // Generate TypeScript
|
|
48
|
+
a11yDocs: true, // Add accessibility docs
|
|
49
|
+
basePath: 'components/ui' // Output path
|
|
50
|
+
});
|
|
51
|
+
|
|
52
|
+
// result.components - Generated component files
|
|
53
|
+
// result.dependencies - Required Radix packages
|
|
54
|
+
```
|
|
55
|
+
|
|
56
|
+
### Example: Simple Dialog
|
|
57
|
+
|
|
58
|
+
**Input (Kappa AST):**
|
|
59
|
+
```typescript
|
|
60
|
+
const dialogSpec: ComponentBlock = {
|
|
61
|
+
kind: 'ComponentBlock',
|
|
62
|
+
name: 'ConfirmDialog',
|
|
63
|
+
props: [
|
|
64
|
+
{ name: 'title', type: 'string', optional: false },
|
|
65
|
+
{ name: 'message', type: 'string', optional: false }
|
|
66
|
+
],
|
|
67
|
+
// ...
|
|
68
|
+
};
|
|
69
|
+
```
|
|
70
|
+
|
|
71
|
+
**Output (Generated TypeScript):**
|
|
72
|
+
```typescript
|
|
73
|
+
// Generated by Kappa v2.5 CodeDNA - Radix UI Generator
|
|
74
|
+
// Component: ConfirmDialog
|
|
75
|
+
// Primitive: Dialog
|
|
76
|
+
|
|
77
|
+
/**
|
|
78
|
+
* ConfirmDialog - Built with Radix UI Dialog
|
|
79
|
+
*
|
|
80
|
+
* Accessibility features:
|
|
81
|
+
* - ARIA attributes automatically applied by Radix UI
|
|
82
|
+
* - Keyboard navigation support
|
|
83
|
+
* - Focus management
|
|
84
|
+
* - Focus trap when open
|
|
85
|
+
* - Scroll lock when open
|
|
86
|
+
*/
|
|
87
|
+
|
|
88
|
+
import * as React from 'react';
|
|
89
|
+
import * as Dialog from '@radix-ui/react-dialog';
|
|
90
|
+
import { cn } from '@/lib/utils';
|
|
91
|
+
|
|
92
|
+
export interface ConfirmDialogProps extends React.ComponentPropsWithoutRef<typeof Dialog.Content> {
|
|
93
|
+
/** title prop */
|
|
94
|
+
title: string;
|
|
95
|
+
/** message prop */
|
|
96
|
+
message: string;
|
|
97
|
+
}
|
|
98
|
+
|
|
99
|
+
export const ConfirmDialog = React.forwardRef<
|
|
100
|
+
React.ElementRef<typeof Dialog.Root>,
|
|
101
|
+
ConfirmDialogProps
|
|
102
|
+
>(({ title, message, className, children, ...props }, ref) => {
|
|
103
|
+
return (
|
|
104
|
+
<Dialog.Root>
|
|
105
|
+
<Dialog.Content ref={ref} className={cn(className)}>
|
|
106
|
+
{children}
|
|
107
|
+
</Dialog.Content>
|
|
108
|
+
</Dialog.Root>
|
|
109
|
+
);
|
|
110
|
+
});
|
|
111
|
+
|
|
112
|
+
ConfirmDialog.displayName = 'ConfirmDialog';
|
|
113
|
+
```
|
|
114
|
+
|
|
115
|
+
### Example: Compound Dialog
|
|
116
|
+
|
|
117
|
+
**Input (Kappa AST):**
|
|
118
|
+
```typescript
|
|
119
|
+
const compoundDialogSpec: ComponentBlock = {
|
|
120
|
+
kind: 'ComponentBlock',
|
|
121
|
+
name: 'CustomDialog',
|
|
122
|
+
props: [
|
|
123
|
+
{ name: 'open', type: 'boolean', optional: true }
|
|
124
|
+
],
|
|
125
|
+
compound: [
|
|
126
|
+
{ name: 'Trigger', element: 'button' },
|
|
127
|
+
{ name: 'Overlay', element: 'div' },
|
|
128
|
+
{ name: 'Content', element: 'div' },
|
|
129
|
+
{ name: 'Title', element: 'h2' },
|
|
130
|
+
{ name: 'Description', element: 'p' },
|
|
131
|
+
{ name: 'Close', element: 'button' }
|
|
132
|
+
],
|
|
133
|
+
// ...
|
|
134
|
+
};
|
|
135
|
+
```
|
|
136
|
+
|
|
137
|
+
**Output (Generated TypeScript):**
|
|
138
|
+
```typescript
|
|
139
|
+
// Root component
|
|
140
|
+
const CustomDialogRoot = React.forwardRef<
|
|
141
|
+
React.ElementRef<typeof Dialog.Root>,
|
|
142
|
+
CustomDialogProps
|
|
143
|
+
>(({ open, className, children, ...props }, ref) => (
|
|
144
|
+
<Dialog.Root ref={ref} className={cn(className)} {...props}>
|
|
145
|
+
{children}
|
|
146
|
+
</Dialog.Root>
|
|
147
|
+
));
|
|
148
|
+
|
|
149
|
+
// Compound parts
|
|
150
|
+
const CustomDialogTrigger = React.forwardRef<
|
|
151
|
+
React.ElementRef<typeof Dialog.Trigger>,
|
|
152
|
+
CustomDialogTriggerProps
|
|
153
|
+
>(({ className, children, ...props }, ref) => (
|
|
154
|
+
<Dialog.Trigger
|
|
155
|
+
ref={ref}
|
|
156
|
+
className={cn('custom-dialog-trigger', className)}
|
|
157
|
+
{...props}
|
|
158
|
+
>
|
|
159
|
+
{children}
|
|
160
|
+
</Dialog.Trigger>
|
|
161
|
+
));
|
|
162
|
+
|
|
163
|
+
// ... other parts
|
|
164
|
+
|
|
165
|
+
// Export compound
|
|
166
|
+
export const CustomDialog = Object.assign(CustomDialogRoot, {
|
|
167
|
+
Trigger: CustomDialogTrigger,
|
|
168
|
+
Overlay: CustomDialogOverlay,
|
|
169
|
+
Content: CustomDialogContent,
|
|
170
|
+
Title: CustomDialogTitle,
|
|
171
|
+
Description: CustomDialogDescription,
|
|
172
|
+
Close: CustomDialogClose,
|
|
173
|
+
});
|
|
174
|
+
```
|
|
175
|
+
|
|
176
|
+
**Usage:**
|
|
177
|
+
```tsx
|
|
178
|
+
<CustomDialog open={open} onOpenChange={setOpen}>
|
|
179
|
+
<CustomDialog.Trigger>Open</CustomDialog.Trigger>
|
|
180
|
+
<CustomDialog.Overlay />
|
|
181
|
+
<CustomDialog.Content>
|
|
182
|
+
<CustomDialog.Title>Confirm</CustomDialog.Title>
|
|
183
|
+
<CustomDialog.Description>Are you sure?</CustomDialog.Description>
|
|
184
|
+
<CustomDialog.Close />
|
|
185
|
+
</CustomDialog.Content>
|
|
186
|
+
</CustomDialog>
|
|
187
|
+
```
|
|
188
|
+
|
|
189
|
+
## Primitive Detection
|
|
190
|
+
|
|
191
|
+
The generator automatically detects which Radix primitive to use:
|
|
192
|
+
|
|
193
|
+
### By Component Name
|
|
194
|
+
```typescript
|
|
195
|
+
// "Dialog" in name → Dialog primitive
|
|
196
|
+
{ name: 'ConfirmDialog' } → Dialog
|
|
197
|
+
|
|
198
|
+
// "Popover" in name → Popover primitive
|
|
199
|
+
{ name: 'UserPopover' } → Popover
|
|
200
|
+
|
|
201
|
+
// "Modal" in name → Dialog primitive
|
|
202
|
+
{ name: 'SettingsModal' } → Dialog
|
|
203
|
+
|
|
204
|
+
// "Tabs" in name → Tabs primitive
|
|
205
|
+
{ name: 'SettingsTabs' } → Tabs
|
|
206
|
+
```
|
|
207
|
+
|
|
208
|
+
### By Compound Parts
|
|
209
|
+
```typescript
|
|
210
|
+
// Trigger + Overlay + Content → Dialog
|
|
211
|
+
compound: [
|
|
212
|
+
{ name: 'Trigger' },
|
|
213
|
+
{ name: 'Overlay' },
|
|
214
|
+
{ name: 'Content' }
|
|
215
|
+
] → Dialog
|
|
216
|
+
|
|
217
|
+
// Trigger + Content (no Overlay) → Popover
|
|
218
|
+
compound: [
|
|
219
|
+
{ name: 'Trigger' },
|
|
220
|
+
{ name: 'Content' }
|
|
221
|
+
] → Popover
|
|
222
|
+
|
|
223
|
+
// List + Trigger + Content → Tabs
|
|
224
|
+
compound: [
|
|
225
|
+
{ name: 'List' },
|
|
226
|
+
{ name: 'Trigger' },
|
|
227
|
+
{ name: 'Content' }
|
|
228
|
+
] → Tabs
|
|
229
|
+
|
|
230
|
+
// Item + Trigger → Accordion
|
|
231
|
+
compound: [
|
|
232
|
+
{ name: 'Item' },
|
|
233
|
+
{ name: 'Trigger' }
|
|
234
|
+
] → Accordion
|
|
235
|
+
```
|
|
236
|
+
|
|
237
|
+
## Accessibility Features
|
|
238
|
+
|
|
239
|
+
All generated components include:
|
|
240
|
+
|
|
241
|
+
1. **ARIA Attributes** - Automatically applied by Radix UI
|
|
242
|
+
2. **Keyboard Navigation** - Tab, Enter, Escape, Arrow keys
|
|
243
|
+
3. **Focus Management** - Proper focus order and trapping
|
|
244
|
+
4. **Screen Reader Support** - Semantic HTML and roles
|
|
245
|
+
5. **Documentation** - JSDoc comments explaining accessibility
|
|
246
|
+
|
|
247
|
+
### Example Accessibility Features by Primitive
|
|
248
|
+
|
|
249
|
+
**Dialog:**
|
|
250
|
+
- Focus trap when open
|
|
251
|
+
- Scroll lock when open
|
|
252
|
+
- `Escape` to close
|
|
253
|
+
- `aria-modal="true"`
|
|
254
|
+
- Focus returns to trigger on close
|
|
255
|
+
|
|
256
|
+
**Popover:**
|
|
257
|
+
- `Escape` to close
|
|
258
|
+
- Click outside to close
|
|
259
|
+
- `aria-haspopup="dialog"`
|
|
260
|
+
- Positioning with collision detection
|
|
261
|
+
|
|
262
|
+
**Select:**
|
|
263
|
+
- `Space`/`Enter` to open
|
|
264
|
+
- Arrow keys to navigate
|
|
265
|
+
- Type-ahead search
|
|
266
|
+
- `aria-expanded` state
|
|
267
|
+
|
|
268
|
+
## TypeScript Integration
|
|
269
|
+
|
|
270
|
+
Generated components extend Radix primitive types:
|
|
271
|
+
|
|
272
|
+
```typescript
|
|
273
|
+
// Props extend Radix's Content props
|
|
274
|
+
export interface CustomDialogProps
|
|
275
|
+
extends React.ComponentPropsWithoutRef<typeof Dialog.Content> {
|
|
276
|
+
// Your custom props
|
|
277
|
+
title: string;
|
|
278
|
+
message: string;
|
|
279
|
+
}
|
|
280
|
+
|
|
281
|
+
// Compound parts extend their Radix counterparts
|
|
282
|
+
export interface CustomDialogTriggerProps
|
|
283
|
+
extends React.ComponentPropsWithoutRef<typeof Dialog.Trigger> {
|
|
284
|
+
// Additional props if needed
|
|
285
|
+
}
|
|
286
|
+
```
|
|
287
|
+
|
|
288
|
+
This ensures:
|
|
289
|
+
- **Type Safety** - All Radix props are typed
|
|
290
|
+
- **IntelliSense** - Auto-complete for Radix props
|
|
291
|
+
- **Forward Compatibility** - New Radix props automatically available
|
|
292
|
+
|
|
293
|
+
## Styling with Tailwind
|
|
294
|
+
|
|
295
|
+
All components support the `cn()` utility for composable Tailwind classes:
|
|
296
|
+
|
|
297
|
+
```typescript
|
|
298
|
+
<CustomDialog className="max-w-md">
|
|
299
|
+
<CustomDialog.Trigger className="btn btn-primary">
|
|
300
|
+
Open
|
|
301
|
+
</CustomDialog.Trigger>
|
|
302
|
+
<CustomDialog.Content className="rounded-lg shadow-xl p-6">
|
|
303
|
+
<CustomDialog.Title className="text-2xl font-bold">
|
|
304
|
+
Confirm Action
|
|
305
|
+
</CustomDialog.Title>
|
|
306
|
+
</CustomDialog.Content>
|
|
307
|
+
</CustomDialog>
|
|
308
|
+
```
|
|
309
|
+
|
|
310
|
+
Default classes can be added to the generator by extending the base component styles.
|
|
311
|
+
|
|
312
|
+
## Options
|
|
313
|
+
|
|
314
|
+
```typescript
|
|
315
|
+
interface RadixGeneratorOptions {
|
|
316
|
+
/** Add provenance comments (default: true) */
|
|
317
|
+
provenance?: boolean;
|
|
318
|
+
|
|
319
|
+
/** Generate TypeScript (default: true) */
|
|
320
|
+
typescript?: boolean;
|
|
321
|
+
|
|
322
|
+
/** Base path for components (default: 'components/ui') */
|
|
323
|
+
basePath?: string;
|
|
324
|
+
|
|
325
|
+
/** Include accessibility documentation (default: true) */
|
|
326
|
+
a11yDocs?: boolean;
|
|
327
|
+
}
|
|
328
|
+
```
|
|
329
|
+
|
|
330
|
+
## Dependencies
|
|
331
|
+
|
|
332
|
+
The generator tracks all required Radix UI packages:
|
|
333
|
+
|
|
334
|
+
```typescript
|
|
335
|
+
const result = generateRadixComponents(components);
|
|
336
|
+
|
|
337
|
+
console.log(result.dependencies);
|
|
338
|
+
// [
|
|
339
|
+
// '@radix-ui/react-dialog',
|
|
340
|
+
// '@radix-ui/react-popover',
|
|
341
|
+
// '@radix-ui/react-tabs'
|
|
342
|
+
// ]
|
|
343
|
+
```
|
|
344
|
+
|
|
345
|
+
Install dependencies:
|
|
346
|
+
```bash
|
|
347
|
+
npm install @radix-ui/react-dialog @radix-ui/react-popover
|
|
348
|
+
```
|
|
349
|
+
|
|
350
|
+
## Testing
|
|
351
|
+
|
|
352
|
+
Tests are located in `src/codedna/__tests__/kappa-radix-generator.test.ts`:
|
|
353
|
+
|
|
354
|
+
```bash
|
|
355
|
+
npm test -- kappa-radix-generator.test.ts
|
|
356
|
+
```
|
|
357
|
+
|
|
358
|
+
Test coverage:
|
|
359
|
+
- ✓ Primitive detection (name-based and structure-based)
|
|
360
|
+
- ✓ Simple component generation
|
|
361
|
+
- ✓ Compound component generation
|
|
362
|
+
- ✓ TypeScript/JavaScript output
|
|
363
|
+
- ✓ Provenance comments
|
|
364
|
+
- ✓ Accessibility documentation
|
|
365
|
+
- ✓ Options handling
|
|
366
|
+
|
|
367
|
+
## Examples
|
|
368
|
+
|
|
369
|
+
Run the examples:
|
|
370
|
+
|
|
371
|
+
```bash
|
|
372
|
+
npm run build
|
|
373
|
+
node dist/codedna/examples/radix-example.js
|
|
374
|
+
```
|
|
375
|
+
|
|
376
|
+
Example components:
|
|
377
|
+
1. **ConfirmDialog** - Simple dialog with title/message props
|
|
378
|
+
2. **CustomDialog** - Compound dialog with all parts
|
|
379
|
+
3. **UserPopover** - Popover with side/align props
|
|
380
|
+
4. **SettingsTabs** - Tabs with List/Trigger/Content
|
|
381
|
+
|
|
382
|
+
## Integration with Kappa
|
|
383
|
+
|
|
384
|
+
The generator integrates with the Kappa v2.5 specification:
|
|
385
|
+
|
|
386
|
+
### Kappa Component Block → Radix Component
|
|
387
|
+
|
|
388
|
+
```kappa
|
|
389
|
+
component ConfirmDialog {
|
|
390
|
+
props {
|
|
391
|
+
title: string
|
|
392
|
+
message: string
|
|
393
|
+
onConfirm: () -> void
|
|
394
|
+
}
|
|
395
|
+
|
|
396
|
+
# Automatically detected as Dialog primitive
|
|
397
|
+
# because "Dialog" is in the name
|
|
398
|
+
}
|
|
399
|
+
```
|
|
400
|
+
|
|
401
|
+
```typescript
|
|
402
|
+
// Generated Radix component with full type safety
|
|
403
|
+
export const ConfirmDialog = React.forwardRef<
|
|
404
|
+
React.ElementRef<typeof Dialog.Content>,
|
|
405
|
+
ConfirmDialogProps
|
|
406
|
+
>(({ title, message, onConfirm, className, children, ...props }, ref) => {
|
|
407
|
+
// ...
|
|
408
|
+
});
|
|
409
|
+
```
|
|
410
|
+
|
|
411
|
+
### Compound Components
|
|
412
|
+
|
|
413
|
+
```kappa
|
|
414
|
+
component DataPopover {
|
|
415
|
+
props {
|
|
416
|
+
data: object
|
|
417
|
+
}
|
|
418
|
+
|
|
419
|
+
compound {
|
|
420
|
+
Trigger: button
|
|
421
|
+
Content: div (side?, align?)
|
|
422
|
+
}
|
|
423
|
+
}
|
|
424
|
+
```
|
|
425
|
+
|
|
426
|
+
```typescript
|
|
427
|
+
// Generated compound component
|
|
428
|
+
export const DataPopover = Object.assign(DataPopoverRoot, {
|
|
429
|
+
Trigger: DataPopoverTrigger,
|
|
430
|
+
Content: DataPopoverContent,
|
|
431
|
+
});
|
|
432
|
+
```
|
|
433
|
+
|
|
434
|
+
## Comparison with Other Generators
|
|
435
|
+
|
|
436
|
+
| Feature | kappa-component-generator | kappa-radix-generator |
|
|
437
|
+
|---------|---------------------------|----------------------|
|
|
438
|
+
| Base Components | Generic React | Radix UI primitives |
|
|
439
|
+
| Accessibility | Manual | Built-in (Radix) |
|
|
440
|
+
| Styling | Tailwind only | Tailwind + Radix styles |
|
|
441
|
+
| Compound Pattern | Context-based | Radix composition |
|
|
442
|
+
| Type Safety | Basic props | Extends Radix types |
|
|
443
|
+
| ForwardRef | Optional | Always |
|
|
444
|
+
| Use Case | Custom components | Standard UI patterns |
|
|
445
|
+
|
|
446
|
+
## Roadmap
|
|
447
|
+
|
|
448
|
+
**Phase 1 (Current):**
|
|
449
|
+
- ✓ Dialog, Popover, Select primitives
|
|
450
|
+
- ✓ Compound component support
|
|
451
|
+
- ✓ TypeScript types
|
|
452
|
+
- ✓ Accessibility docs
|
|
453
|
+
|
|
454
|
+
**Phase 2:**
|
|
455
|
+
- [ ] All Radix primitives (HoverCard, ContextMenu, etc.)
|
|
456
|
+
- [ ] Theme integration (design tokens)
|
|
457
|
+
- [ ] Animation variants
|
|
458
|
+
- [ ] Dark mode support
|
|
459
|
+
|
|
460
|
+
**Phase 3:**
|
|
461
|
+
- [ ] Component composition (nested compounds)
|
|
462
|
+
- [ ] Custom primitive mappings
|
|
463
|
+
- [ ] Style presets (shadcn-compatible)
|
|
464
|
+
|
|
465
|
+
## Related Files
|
|
466
|
+
|
|
467
|
+
- **Generator:** `src/codedna/kappa-radix-generator.ts`
|
|
468
|
+
- **Tests:** `src/codedna/__tests__/kappa-radix-generator.test.ts`
|
|
469
|
+
- **Examples:** `src/codedna/examples/radix-example.ts`
|
|
470
|
+
- **AST Types:** `src/codedna/kappa-ast.ts`
|
|
471
|
+
- **Spec:** `docs/research/2026-01-02-kappa-v2.5-specification.md`
|
|
472
|
+
|
|
473
|
+
## References
|
|
474
|
+
|
|
475
|
+
- [Radix UI Documentation](https://www.radix-ui.com/docs/primitives/overview/introduction)
|
|
476
|
+
- [Radix UI Accessibility](https://www.radix-ui.com/docs/primitives/overview/accessibility)
|
|
477
|
+
- [Kappa v2.5 Specification](../research/2026-01-02-kappa-v2.5-specification.md)
|
|
478
|
+
- [Component Generator Pattern](./component-generator.md)
|