Skip to content

Latest commit

 

History

History
310 lines (217 loc) · 6.5 KB

File metadata and controls

310 lines (217 loc) · 6.5 KB

Agent Notes - Button Component

Overview

A React button component for the Isolate UI library. This is a presentational component built with React 19 and TypeScript.

Project Structure

libs/react/button/
├── src/
│   ├── index.ts                 # Public API exports
│   └── lib/
│       ├── button.tsx           # Button component
│       ├── button.spec.tsx      # Component tests
│       └── button.module.css    # Component styles
├── vite.config.mts              # Vite + Vitest configuration
├── tsconfig.json                # TypeScript config
├── tsconfig.lib.json            # Build config
├── tsconfig.spec.json           # Test config
└── package.json

Development

Running Tests

# Run tests for this component
nx test react-button

# Run tests in watch mode
nx test react-button --watch

# Run tests with UI
nx test react-button --ui

# Run tests with coverage
nx test react-button --coverage

Building

# Build the component library
nx build react-button

# Build outputs to: dist/libs/react/button/

Development Server

Test the component in isolation with Storybook:

# Start Storybook dev server (http://localhost:6006)
nx storybook react-button

# Build Storybook for static deployment
nx build-storybook react-button
# Output: dist/storybook/react-button/

Linting

# Lint the component
nx lint react-button

# Lint with auto-fix
nx lint react-button --fix

Publishing

# Publish to npm (CI)
nx release publish

To publish to a local Verdaccio instance for testing, add the following to .npmrc before running:

@isolate-ui:registry=http://localhost:4873

Remove the .npmrc entry before committing or publishing to npm.

Component API

ButtonProps

interface ButtonProps extends HTMLAttributes<HTMLButtonElement> {
  // Extends all standard HTML button attributes
}

Usage

import { Button } from '@isolate-ui/button';

function App() {
  return <Button onClick={() => console.log('clicked')}>Click me</Button>;
}

Configuration

Vite Configuration

vite.config.mts is configured with:

  • React plugin: JSX transformation and Fast Refresh
  • TypeScript: Type declarations generated via vite-plugin-dts
  • Build format: ESM (ES modules)
  • Externals: React and React DOM are not bundled

Vitest Configuration

Test configuration in vite.config.mts:

  • Environment: jsdom (simulates browser environment)
  • Globals: true - no need to import describe, it, expect
  • Test pattern: {src,tests}/**/*.{test,spec}.{js,mjs,cjs,ts,mts,cts,jsx,tsx}
  • Coverage: Reports to ../../../coverage/libs/react/button

TypeScript Configuration

  • Strict mode: Enabled for type safety
  • JSX: React 19 JSX transform
  • Path mappings: Import as @isolate-ui/button
  • React types: Includes @types/react and @types/react-dom

Adding Features

Modifying the Component

  1. Update the component:

    // src/lib/button.tsx
    export interface ButtonProps extends HTMLAttributes<HTMLButtonElement> {
      variant?: 'primary' | 'secondary';
    }
    
    export function Button({ variant = 'primary', children, ...props }: ButtonProps) {
      return (
        <button className={variant} {...props}>
          {children}
        </button>
      );
    }
  2. Update tests:

    // src/lib/button.spec.tsx
    describe('Button', () => {
      it('should render with primary variant', () => {
        const { getByRole } = render(<Button variant="primary">Click</Button>);
        expect(getByRole('button')).toHaveClass('primary');
      });
    });
  3. Run tests:

    nx test react-button

Adding Styles

The component uses CSS modules for styling:

/* src/lib/button.module.css */
.button {
  padding: 8px 16px;
  border-radius: 4px;
}

.primary {
  background: blue;
  color: white;
}
// src/lib/button.tsx
import styles from './button.module.css';

export function Button({ children, ...props }: ButtonProps) {
  return (
    <button className={styles.button} {...props}>
      {children}
    </button>
  );
}

Testing Guidelines

Unit Tests

  • Render tests: Verify component renders correctly
  • Prop tests: Test different prop combinations
  • Event tests: Test click handlers and other events
  • Accessibility: Test ARIA attributes and keyboard navigation
  • Snapshot tests: Optionally use snapshots for complex markup

Testing Library

Tests use @testing-library/react:

import { render, fireEvent } from '@testing-library/react';
import Button from './button';

describe('Button', () => {
  it('should call onClick when clicked', () => {
    const handleClick = vi.fn();
    const { getByRole } = render(<Button onClick={handleClick}>Click</Button>);

    fireEvent.click(getByRole('button'));

    expect(handleClick).toHaveBeenCalledTimes(1);
  });
});

Dependencies

Peer Dependencies

The component requires these in consuming applications:

  • react: ^19.0.0
  • react-dom: ^19.0.0

Internal Dependencies

Can depend on other workspace libraries:

import { utils } from '@isolate-ui/utils';

Build Output

The build creates:

  • ESM bundle: dist/libs/react/button/index.js
  • Type declarations: dist/libs/react/button/index.d.ts
  • Source maps: For debugging

Usage in Applications

# In a consuming app
pnpm add @isolate-ui/button
import { Button } from '@isolate-ui/button';

function App() {
  return <Button>Hello World</Button>;
}

CI/CD

Tests and builds are automatically run:

  • On every commit (via Nx affected)
  • In pull requests
  • Before releases

Troubleshooting

Tests failing with "document is not defined"

Make sure environment: 'jsdom' is set in the test config

React hooks errors

Ensure React version matches across all packages (use pnpm's peer dependency resolution)

Import errors

Check that the component is exported from src/index.ts

Type errors

Run nx typecheck react-button to see all type errors

Related Documentation


Last updated: March 4, 2026