Thank you for your interest in contributing to the WithoutBG UI component library!
- Fork the repository
- Clone your fork:
git clone https://github.com/YOUR_USERNAME/ui.git - Install dependencies:
npm install - Create a branch:
git checkout -b feature/your-feature-name
npm run storybookThis starts Storybook at http://localhost:6006 where you can see all components and their variants.
npm run buildThis creates the production build in the dist/ folder.
- Create the component in
src/components/YourComponent.tsx:
import { ReactNode } from 'react';
export interface YourComponentProps {
children: ReactNode;
variant?: 'primary' | 'secondary';
}
export const YourComponent = ({ children, variant = 'primary' }: YourComponentProps) => {
const classes = variant === 'primary' ? 'bg-primary' : 'bg-secondary';
return <div className={classes}>{children}</div>;
};- Export from
src/index.ts:
export { YourComponent } from './components/YourComponent';
export type { YourComponentProps } from './components/YourComponent';- Create stories in
src/stories/YourComponent.stories.tsx:
import type { Meta, StoryObj } from '@storybook/react';
import { YourComponent } from '../components/YourComponent';
const meta: Meta<typeof YourComponent> = {
title: 'Components/YourComponent',
component: YourComponent,
tags: ['autodocs'],
};
export default meta;
type Story = StoryObj<typeof meta>;
export const Primary: Story = {
args: {
children: 'Primary Variant',
variant: 'primary',
},
};
export const Secondary: Story = {
args: {
children: 'Secondary Variant',
variant: 'secondary',
},
};-
Test in Storybook - verify all variants work correctly
-
Build and verify - run
npm run buildto ensure no errors
- Export all prop interfaces/types
- Use explicit return types for complex functions
- Prefer
interfacefor component props - Use
typefor unions and complex types
- Use functional components
- Export named exports (not default)
- Use TypeScript for all components
- Keep components focused and single-purpose
- Use Tailwind CSS classes
- Reference design tokens from
tailwind.preset.js - Support dark mode with
dark:prefix - Use semantic class names for complex styles
- Components: PascalCase (
PrimaryButton.tsx) - Files: Match component name
- Props interfaces:
ComponentNameProps - Stories:
ComponentName.stories.tsx
Follow the WithoutBG design system defined in tailwind.preset.js:
// Primary brand colors
bg-primary // #6C2BD9
bg-primary-hover // #5A23B8
dark:bg-primary-light // #A97BFF (dark mode)
// Text colors
text-primary-text // white on primary
dark:text-primary-text-dark // black on primary-light// Use defined font sizes
text-xs, text-sm, text-base, text-lg, text-xl
text-2xl, text-3xl, text-4xl, text-5xl, text-6xl
// Font weights
font-light, font-normal, font-medium, font-semibold, font-boldFollow Tailwind's default spacing scale.
Every component should:
- ✅ Be fully typed with TypeScript
- ✅ Export prop types
- ✅ Support dark mode where applicable
- ✅ Have Storybook stories
- ✅ Include JSDoc comments for public APIs
- ✅ Follow accessibility best practices
- ✅ Be responsive by default
Currently, we use Storybook for component testing. Future additions may include:
- Unit tests with Vitest
- E2E tests with Playwright
- Visual regression tests
- Update documentation if needed
- Add/update Storybook stories
- Ensure build succeeds:
npm run build - Commit with clear, descriptive messages
- Create PR with description of changes
- Link any related issues
type(scope): short description
Longer description if needed.
- Bullet points for details
- More details
Types: feat, fix, docs, style, refactor, test, chore
Examples:
feat(button): add loading state to PrimaryButton
fix(button): correct dark mode hover color
docs(readme): add installation instructions
Open an issue or discussion on GitHub!
By contributing, you agree that your contributions will be licensed under the MIT License.