npm package: @pitcher/react-ui
Description: Shared React component library for the Pitcher platform. Built on [Shadcn UI](https://ui.shadcn.com/) + [Radix](https://www.radix-ui.com/) primitives + [Tailwind CSS](https://tailwindcss.com/), it provides the Pitcher design system (colors, typography, ic
Latest version: 1.0.16

# @pitcher/react-ui

Shared React component library for the Pitcher platform. Built on [Shadcn UI](https://ui.shadcn.com/) + [Radix](https://www.radix-ui.com/) primitives + [Tailwind CSS](https://tailwindcss.com/), it provides the Pitcher design system (colors, typography, icons) for all React-based apps.

## Installation

### npm (standalone apps)

```bash
npm install @pitcher/react-ui
```

### Web monorepo

```jsonc
// package.json
{
  "dependencies": {
    "@pitcher/react-ui": "workspace:*"
  }
}
```

## Setup

### 1. Tailwind config

```ts
// tailwind.config.ts
import { pitcherPreset } from '@pitcher/react-ui/tailwind'

export default {
  presets: [pitcherPreset],
  content: [
    './src/**/*.{ts,tsx}',
    // REQUIRED — Tailwind must scan library source for class names
    './node_modules/@pitcher/react-ui/src/**/*.{ts,tsx}', // npm
    // or for monorepo (path relative to your package):
    // '../libs/react-ui/src/**/*.{ts,tsx}',               // from packages/next-core/
    // '../../libs/react-ui/src/**/*.{ts,tsx}',             // from packages/apps/*/
  ],
}
```

> **Important:** The `content` array **must** include the react-ui source path. Without it, Tailwind purges all classes that only appear in library components.

### 2. CSS

Import the global stylesheet **before** Tailwind directives in your main CSS file:

```css
/* globals.css */
@import '@pitcher/react-ui/styles';

@tailwind base;
@tailwind components;
@tailwind utilities;
```

This provides:
- CSS custom properties for light and dark mode (Pitcher palette + Shadcn tokens)
- Font Awesome Pro icon fonts (regular, solid, light, brands)

### 3. Framework-specific config

**Next.js** — add to `next.config.ts`:

```ts
const nextConfig = {
  transpilePackages: ['@pitcher/react-ui'],
}
```

**Vite** — no extra config needed.

## Usage

```tsx
import { Button, FaIcon, Spinner, cn } from '@pitcher/react-ui'

function SaveButton() {
  return (
    <Button aria-label="Save changes">
      <FaIcon icon="fa-regular fa-floppy-disk" className="mr-2" />
      Save
    </Button>
  )
}
```

## Package Exports

| Import path | What it provides |
|---|---|
| `@pitcher/react-ui` | All components, hooks, and the `cn()` utility |
| `@pitcher/react-ui/tailwind` | `pitcherPreset` — Tailwind preset with Pitcher palette, border radius, animations |
| `@pitcher/react-ui/styles` | Global CSS — CSS custom properties (light + dark) + Font Awesome icon fonts |
| `@pitcher/react-ui/fonts/*` | Raw Font Awesome font files (woff2, css) — only needed if CSS import path issues arise |

## Components

### Core

| Component | Description |
|---|---|
| `Button` | Primary, secondary, outline, ghost, link, destructive variants |
| `ButtonGroup` | Grouped button toolbar with separator |
| `Badge` | Status labels and counts |
| `Spinner` | Loading indicator |
| `FaIcon` | Font Awesome icon wrapper (`<FaIcon icon="check" type="fas" />`) |
| `Kbd` | Keyboard shortcut display |
| `Empty` | Empty state placeholder |

### Layout

| Component | Description |
|---|---|
| `Card` | Container with header, content, footer sections |
| `AspectRatio` | Constrained aspect ratio container |
| `Separator` | Horizontal/vertical divider |
| `ScrollArea` | Custom scrollbar container |
| `ResizablePanelGroup` | Draggable resizable panels |
| `Sidebar` | Application sidebar with menu, groups, collapsible sections |

### Navigation

| Component | Description |
|---|---|
| `Tabs` | Tab panels |
| `Accordion` | Collapsible content sections |
| `Breadcrumb` | Breadcrumb trail |
| `NavigationMenu` | Top-level navigation with dropdowns |
| `Pagination` | Page navigation |

### Form

| Component | Description |
|---|---|
| `Input`, `Textarea` | Text inputs |
| `InputGroup` | Input with addons, buttons, or text segments |
| `InputOTP` | One-time password input |
| `Select`, `MultiSelect` | Single and multi-select dropdowns |
| `Checkbox`, `Switch`, `RadioGroup` | Toggle controls |
| `Slider` | Range slider |
| `Label` | Form label |
| `Calendar`, `DateTimePicker`, `TimePicker` | Date/time pickers |
| `Form`, `FormField`, `FormItem` | Form layout with react-hook-form integration |
| `StarRating` | Star rating input |

### Feedback

| Component | Description |
|---|---|
| `Alert` | Inline alert with title, description, actions, close button |
| `Progress` | Progress bar |
| `Skeleton` | Loading placeholder |
| `Toast` + `Toaster` | Radix-based toast notifications (use with `useToast()`) |
| `SonnerToaster` | Sonner-based toast notifications (use with `toast()` from sonner) |

### Overlays

| Component | Description |
|---|---|
| `Dialog` | Modal dialog |
| `AlertDialog` | Confirmation dialog with cancel/confirm |
| `Sheet` | Slide-out panel (top, right, bottom, left) |
| `Drawer` | Bottom drawer (mobile-friendly, powered by vaul) |
| `Popover` | Popover with arrow |
| `HoverCard` | Card shown on hover |
| `Tooltip` | Tooltip on hover/focus |

### Menus

| Component | Description |
|---|---|
| `DropdownMenu` | Dropdown menu with items, checkboxes, radio groups, submenus |
| `ContextMenu` | Right-click context menu |
| `Menubar` | Horizontal menu bar |
| `Command` | Command palette / search (cmdk) |

### Data Display

| Component | Description |
|---|---|
| `Table` | Data table with header, body, footer, caption |
| `Avatar` | User avatar with image + fallback |
| `Carousel` | Carousel slider (embla) |
| `ChartContainer` | Recharts wrapper with Pitcher theme |

### Toggle

| Component | Description |
|---|---|
| `Toggle` | Toggle button |
| `ToggleGroup` | Exclusive or multi-select toggle group |
| `Collapsible` | Expand/collapse content |

## Hooks

| Hook | Description |
|---|---|
| `useToast()` | Radix toast — returns `{ toast, dismiss, toasts }` |
| `useIsMobile()` | Responsive breakpoint detection |
| `useSidebar()` | Sidebar open/close state |
| `useFormField()` | Form field context (errors, validation state) |

## Toast Systems

The library includes two independent toast systems. **Each requires its own provider component** mounted in your React tree:

### Radix Toast (more control, custom actions)

```tsx
import { Button, Toaster, ToastAction, useToast } from '@pitcher/react-ui'

function App() {
  const { toast } = useToast()

  return (
    <>
      <Button onClick={() => toast({
        title: 'Saved',
        description: 'Your changes have been saved.',
        action: <ToastAction altText="Undo">Undo</ToastAction>,
      })}>
        Save
      </Button>
      <Toaster /> {/* Required — renders Radix toasts */}
    </>
  )
}
```

### Sonner Toast (simpler API, built-in variants)

```tsx
import { Button, SonnerToaster } from '@pitcher/react-ui'
import { toast } from 'sonner'

function App() {
  return (
    <>
      <Button onClick={() => toast.success('Saved!')}>Save</Button>
      <SonnerToaster /> {/* Required — renders Sonner toasts */}
    </>
  )
}
```

## Color Palette

The Tailwind preset exposes two color systems via CSS custom properties (light + dark mode):

### Shadcn Semantic Tokens

Standard Shadcn colors mapped to the Pitcher palette:

`bg-primary`, `bg-secondary`, `bg-destructive`, `bg-muted`, `bg-accent`, `bg-card`, `bg-popover`, `text-foreground`, `text-muted-foreground`

### Pitcher Palette (`p-*` prefix)

Direct access to all Pitcher design system colors:

| Token | Light | Usage |
|---|---|---|
| `p-primary` | #29335C | Primary brand |
| `p-primary2` | #4E5983 | Primary variant |
| `p-primary3` | #7E88B1 | Primary light |
| `p-primary4` | #BFC5DF | Primary lighter |
| `p-primary5` | #E0E2ED | Primary subtle |
| `p-primary6` | #F7F8FB | Primary background |
| `p-error` | #BC1637 | Error / destructive |
| `p-error2` | #FEF7F5 | Error background |
| `p-success` | #57A40F | Success |
| `p-success2` | #F9FFE9 | Success background |
| `p-warning` | #E5C302 | Warning |
| `p-warning2` | #FDF9CB | Warning background |
| `p-info` | #5BBFE3 | Info |
| `p-info2` | #F2FDFF | Info background |
| `p-text` | #212121 | Primary text |
| `p-text2` | #757575 | Secondary text |
| `p-text3` | #BDBDBD | Tertiary text |
| `p-base` | #FFFFFF | Base background |

```tsx
// Examples
<div className="bg-p-primary6 text-p-text border border-p-primary5">
  <span className="text-p-error">Error message</span>
  <span className="text-p-success">Success</span>
</div>
```

Dark mode values are automatically applied when the `dark` class is present on a parent element.

## Icons

The library uses **Font Awesome Pro** via the `FaIcon` component. Lucide is not used.

```tsx
import { FaIcon } from '@pitcher/react-ui'

// Font Awesome class syntax
<FaIcon icon="fa-regular fa-star" />
<FaIcon icon="fa-solid fa-check" />

// Shorthand with type prop
<FaIcon icon="star" type="far" />
<FaIcon icon="check" type="fas" />
<FaIcon icon="spinner" type="fal" className="animate-spin" />

// Sizing
<FaIcon icon="star" type="far" size="sm" />
<FaIcon icon="star" type="far" size="lg" />
<FaIcon icon="star" type="far" size="2x" />
```

## Utilities

### `cn()` — Class Name Merging

Combines `clsx` + `tailwind-merge` for conflict-free class composition:

```tsx
import { cn } from '@pitcher/react-ui'

<div className={cn(
  'px-4 py-2 rounded',
  isActive && 'bg-primary text-primary-foreground',
  className // allows consumer overrides
)} />
```

## Adding New Components

Use the [Shadcn CLI](https://ui.shadcn.com/docs/cli) from the react-ui package directory:

```bash
cd packages/libs/react-ui
npx shadcn@latest add <component-name>
```

The CLI reads `components.json` (configured for `new-york` style, Font Awesome icons, no RSC) and places the component in `src/components/`. After adding, export it from `src/index.ts`.

## Building & Publishing

```bash
# From web/ root
yarn publish:react-ui        # Build + publish @latest
yarn publish:react-ui:beta   # Build + publish @beta
```

The library build uses Vite (`yarn lib:build` inside the package). This is for npm publishing only — **not needed during local development** since monorepo consumers resolve TypeScript source directly.

The npm package ships `src/` for Tailwind class scanning and TypeScript source resolution. All consumers (Vite, Next.js, webpack) compile from source directly.

## Example App

An example Pitcher installable app using this library is available at:

```
packages/libs/react-ui/examples/installable-app/
```

It demonstrates all components with a full UI showcase. To run it locally:

```bash
cd packages/libs/react-ui/examples/installable-app
npm install
npm run dev
```

## Peer Dependencies

- `react` ^18.0.0 || ^19.0.0
- `react-dom` ^18.0.0 || ^19.0.0

## License

Proprietary - Pitcher AG