Skip to content

Latest commit

 

History

History
266 lines (190 loc) · 7.67 KB

CONTRIBUTING.md

File metadata and controls

266 lines (190 loc) · 7.67 KB

Contributing to Design System React

Thank you for your interest in contributing! This guide will help you get started.

Table of Contents

Setup

Maintainers with push access to salesforce/design-system-react should clone it directly and push branches there instead of forking, so Chromatic visual review runs on your PR.

Chromatic does not run automatically for PRs from forks. A maintainer who can edit labels (triage access or higher) can run it after reviewing the changes by adding the run-chromatic label. The label is removed whenever new commits are pushed, so it must be re-applied for each update.

  1. Fork this repository (button in upper right)

  2. Clone your fork locally

    git clone git@github.com:[YOUR-USER]/design-system-react.git
    cd design-system-react
  3. Install dependencies (Node >= 24 required; nvm use picks up .nvmrc)

    npm install
    npx playwright install chromium  # browser for the Vitest `browser` project
  4. Start Storybook

    npm run storybook

    View components at http://localhost:6007

  5. Read the Codebase Overview to understand conventions and best practices. If you work with an AI coding agent, it should read AGENTS.md.

Development Workflow

Commands

Command Description
npm run storybook Start Storybook dev server
npm run dev Start Vite dev server
npm test -- --run Run all tests once (bare npm test starts watch mode)
npm run test:ui Run tests with Vitest UI (needs @vitest/ui installed)
npm run lint Lint all files
npm run lint:fix Fix lint issues and format with Prettier
npm run typecheck TypeScript type checking
npm run build Build the library
npm run test:ci Run everything CI runs (typecheck, test, build, lint)

Creating a Feature Branch

git checkout -b feature/my-feature-name

Adding a New Component

1. Propose the Component

Create a GitHub issue with:

  • Component name and description
  • List of proposed props with types
  • Link to SLDS documentation

2. Create the Component Structure

components/
└── my-component/
    ├── index.tsx           # Main component export
    ├── my-component.tsx    # Component implementation
    ├── types.ts            # TypeScript interfaces
    ├── private/            # Internal sub-components
    │   └── sub-component.tsx
    ├── __docs__/
    │   └── MyComponent.stories.tsx  # Storybook stories (.jsx or .tsx)
    └── __tests__/
        └── my-component.test.tsx

3. Component Guidelines

  • Use functional components with hooks
  • Use TypeScript for all new components
  • Add forwardRef for ref handling
  • Add displayName for debugging
  • Export from components/index.js (runtime) and components/index.d.ts (types)

4. Story Requirements

Stories should be in CSF (Component Story Format):

import type { Meta, StoryObj } from '@storybook/react';
import MyComponent from '../';

const meta: Meta<typeof MyComponent> = {
	title: 'Components/MyComponent',
	component: MyComponent,
};

export default meta;
type Story = StoryObj<typeof MyComponent>;

export const Default: Story = {
	args: {
		// props
	},
};

5. Update Story Snapshots

Stories are picked up automatically from components/**/__docs__/*.stories.{jsx,tsx}, and each one (except portal-rendered stories, which can't be server-rendered) is also rendered into an HTML snapshot (components/__tests__/__snapshots__/story-snapshots.test.jsx.snap). After adding or changing stories, regenerate and commit the snapshots:

npm test -- --run -u

Testing

Running Tests

# Run all tests once
npm test -- --run

# Run tests with UI
npm run test:ui

# Run tests for a specific component (does NOT include story snapshots)
npm test -- --run components/button

# Regenerate story HTML snapshots after intentional markup changes
npm test -- --run -u

Writing Tests

Tests use Vitest and React Testing Library:

import { render, screen } from '@testing-library/react';
import userEvent from '@testing-library/user-event';
import { describe, it, expect, vi } from 'vitest';
import MyComponent from '../';

describe('MyComponent', () => {
	it('renders correctly', () => {
		render(<MyComponent label="Test" />);
		expect(screen.getByText('Test')).toBeInTheDocument();
	});

	it('calls onClick when clicked', async () => {
		const onClick = vi.fn();
		render(<MyComponent label="Click me" onClick={onClick} />);
		await userEvent.click(screen.getByRole('button'));
		expect(onClick).toHaveBeenCalled();
	});
});

Test Requirements

  • Test all props
  • Test user interactions (click, keyboard, focus)
  • Test accessibility (ARIA attributes)
  • Aim for 90%+ coverage
  • Story HTML snapshots updated and reviewed whenever stories or rendered markup change

Code Style

Formatting

This project uses Prettier and ESLint:

# Fix all formatting issues
npm run lint:fix

TypeScript

  • Use explicit types for props
  • Avoid any - use unknown or proper types
  • Export types from types.ts files

Naming Conventions

Type Convention Example
Component files kebab-case my-component.tsx
Story files PascalCase MyComponent.stories.jsx / .tsx
Type files lowercase types.ts
Components PascalCase MyComponent
Props interfaces PascalCase + Props MyComponentProps

Pull Request Process

Before Submitting

Run npm run test:ci to do steps 1–4 in one go. A pre-push hook also checks story snapshots.

  1. Run linting: npm run lint
  2. Run type check: npm run typecheck
  3. Run tests: npm test -- --run (unfiltered, so story snapshots are checked)
  4. Run build: npm run build
  5. Test in Storybook: npm run storybook
  6. Rebase on master and resolve any conflicts

PR Requirements

  • Descriptive title and summary
  • Link to related issue
  • Screenshots for visual changes
  • All CI checks passing

Commit Messages

Use conventional commits:

feat: Add new Button variant
fix: Correct Modal focus trap
docs: Update README examples
chore: Update dependencies

Keep lint/format-only changes in a separate style: commit from functional changes so the diff is easy to review.

Review Process

  1. Maintainers will review your PR
  2. Address any feedback
  3. Once approved, your PR will be merged

Accessibility

All components must be accessible:

  • Keyboard navigable
  • Proper ARIA attributes
  • Screen reader compatible
  • WCAG 2.1 AA compliant

Questions?

  • Issues: GitHub Issues
  • Stack Overflow: Tag with design-system-react

Thank you for contributing!