Thank you for your interest in contributing to AI Native Kit UI! This document provides guidelines and instructions for contributing.
- Code of Conduct
- Getting Started
- Development Workflow
- Component Architecture
- Coding Standards
- Testing
- Documentation
- Pull Request Process
This project follows a Code of Conduct.
- Node.js: >= 20.19.2
- pnpm: >= 9.0.0
# Clone the repository
git clone https://github.com/AINativeKit/chatgpt-apps-sdk-ui.git
cd chatgpt-apps-sdk-ui
# Install dependencies
pnpm install
# Start Storybook
pnpm storybook
# Run tests in watch mode
pnpm test:watchgit checkout -b feature/your-feature-name
# or
git checkout -b fix/issue-description- Write code following our coding standards
- Add tests for new functionality
- Update documentation as needed
- Test your changes in Storybook
# Lint your code
pnpm lint
# Run tests
pnpm test
# Build the library
pnpm buildWe follow Conventional Commits:
git commit -m "feat: add new Button variant"
git commit -m "fix: resolve Icon alignment issue"
git commit -m "docs: update Card component usage"Commit types:
feat: New featurefix: Bug fixdocs: Documentation changesstyle: Code style changes (formatting, etc.)refactor: Code refactoringtest: Adding or updating testschore: Maintenance tasks
Components are organized in three tiers:
primitives → composed → patterns
Rules:
- ✅ Primitives can import: primitives, tokens, icons, utils, hooks
- ✅ Composed can import: primitives, composed, tokens, icons, utils, hooks
- ✅ Patterns can import: primitives, composed, patterns, tokens, icons, utils, hooks
- ❌ Never import higher tiers (enforced by ESLint)
- Primitive: Basic, single-purpose component (Button, Badge)
- Composed: Combines primitives (Card, Carousel)
- Pattern: Complex, domain-specific (Album, Map)
packages/ui/src/components/YourComponent/
├── YourComponent.tsx # Main component
├── YourComponent.module.css # Styles
├── YourComponent.stories.tsx # Storybook documentation
├── YourComponent.test.tsx # Tests
└── index.ts # Exportsimport React from 'react';
import type { ComponentPropsWithoutRef } from 'react';
import { cn } from '../../utils/cn';
import styles from './YourComponent.module.css';
export interface YourComponentProps extends ComponentPropsWithoutRef<'div'> {
/**
* Component variant
* @default 'default'
*/
variant?: 'default' | 'primary';
/**
* Additional description
*/
children: React.ReactNode;
}
/**
* YourComponent provides [brief description].
*
* @example
* ```tsx
* <YourComponent variant="primary">Content</YourComponent>
* ```
*/
export const YourComponent: React.FC<YourComponentProps> = ({
variant = 'default',
children,
className,
...props
}) => {
return (
<div className={cn(styles.root, styles[variant], className)} {...props}>
{children}
</div>
);
};// packages/ui/src/components/index.ts
export { YourComponent } from './YourComponent';
export type { YourComponentProps } from './YourComponent';- Use TypeScript for all files
- Prefer
interfaceovertypefor component props - Export all types alongside components
- Use JSDoc comments for public APIs
- Use CSS Modules for component styles
- Leverage design tokens from
tokens/ - Support light and dark themes
- Use semantic class names
- All interactive elements must be keyboard accessible
- Provide proper ARIA labels and roles
- Test with screen readers when possible
- Include focus styles
- Components: PascalCase (
Button,ImageCard) - Props: camelCase with descriptive names
- CSS classes: camelCase in modules
- Files: Match component name
import { render, screen } from '@testing-library/react';
import { YourComponent } from './YourComponent';
describe('YourComponent', () => {
it('renders with default props', () => {
render(<YourComponent>Content</YourComponent>);
expect(screen.getByText('Content')).toBeInTheDocument();
});
it('applies variant className', () => {
const { container } = render(<YourComponent variant="primary">Content</YourComponent>);
expect(container.firstChild).toHaveClass('primary');
});
});- Aim for >80% coverage for new components
- Test all props and variants
- Test accessibility features
- Test error states
Create comprehensive Storybook stories:
import type { Meta, StoryObj } from '@storybook/react';
import { YourComponent } from './YourComponent';
const meta: Meta<typeof YourComponent> = {
title: 'Primitive Components/YourComponent',
component: YourComponent,
parameters: {
layout: 'padded',
},
};
export default meta;
export const Default: StoryObj<typeof YourComponent> = {
args: {
variant: 'default',
children: 'Example content',
},
};- Component docstring: Brief description and example
- Props documentation: JSDoc for all props
- Storybook story: Interactive examples
- Usage in USAGE.md: If it's a major component
- ✅ All tests pass (
pnpm test) - ✅ Linting passes (
pnpm lint) - ✅ Build succeeds (
pnpm build) - ✅ Storybook works (
pnpm storybook) - ✅ Documentation is updated
- ✅ Commit messages follow conventions
Follow Conventional Commits format:
feat: add Button loading state
fix: resolve Card border radius issue
docs: improve Icon system documentation
## Description
Brief description of changes
## Type of Change
- [ ] Bug fix
- [ ] New feature
- [ ] Breaking change
- [ ] Documentation update
## Testing
- [ ] Added tests
- [ ] All tests passing
- [ ] Tested in Storybook
## Screenshots (if applicable)
[Add screenshots of visual changes]
## Checklist
- [ ] Code follows style guidelines
- [ ] Self-reviewed code
- [ ] Commented complex code
- [ ] Updated documentation
- [ ] No new warnings
- [ ] Added tests with good coverage- Maintainers will review your PR
- Address feedback and update PR
- Once approved, maintainers will merge
- Additional components: Suggest and implement new components
- Accessibility improvements: Enhance A11Y support
- Testing: Increase test coverage
- Documentation: Improve examples and guides
- Performance: Optimize bundle size and runtime
Look for issues tagged with good first issue or help wanted.
- Issues: For bug reports and feature requests
- Discussions: For questions and ideas
- Pull Requests: For code contributions
By contributing, you agree that your contributions will be licensed under the MIT License.
Thank you for contributing to AI Native Kit UI! 🎉