npm package: @fastwork/xosmoz-react
Description: React components for the Xosmoz design system
Latest version: 1.0.0

# @fastwork/xosmoz-react

React 18 components for the Xosmoz design system.

## Installation

```bash
npm install @fastwork/xosmoz-react @fastwork/xosmoz-theme @fastwork/xosmoz-css
# or
yarn add @fastwork/xosmoz-react @fastwork/xosmoz-theme @fastwork/xosmoz-css
```

## Requirements

| Package                  | Minimum Version |
| ------------------------ | --------------- |
| `react`                  | `>=18.2.0`      |
| `react-dom`              | `>=18.2.0`      |
| `@fastwork/xosmoz-theme` | `*`             |
| `@fastwork/xosmoz-css`   | `*`             |

## Usage

### 1. Import Styles

Add the required CSS to your app entry point:

```tsx
// In your App.tsx or main entry
import '@fastwork/xosmoz-theme/base.css'
import '@fastwork/xosmoz-theme/themes.css'
import '@fastwork/xosmoz-css/component.css'
```

### 2. Set Theme

Add a `data-theme` attribute to enable theming:

```html
<html data-theme="light">
	<!-- or "dark" -->
</html>
```

### 3. Use Components

```tsx
import { Button } from '@fastwork/xosmoz-react'

function App() {
	return (
		<Button variant="primary" size="medium">
			Click me
		</Button>
	)
}
```

## Components

| Component                         | Description                                           |
| --------------------------------- | ----------------------------------------------------- |
| `Badge`                           | Labels, tags, and status indicators                   |
| `BlankSlate`                      | Empty state with image, heading, description          |
| `Button`                          | Button with variants, sizes, icons, loading state     |
| `ButtonGroup` + `ButtonGroupItem` | Grouped toggle buttons (compound)                     |
| `Checkbox`                        | Checkbox with indeterminate support                   |
| `Chip`                            | Selectable chip/tag                                   |
| `Input`                           | Text input with label, prefix/suffix, password toggle |
| `Link`                            | Styled anchor with variants                           |
| `Loader`                          | Spinner (dot or Fastwork logo)                        |
| `Message`                         | Alert/notification with icon                          |
| `Radio`                           | Radio input                                           |
| `RadioButton`                     | Styled radio button alternative                       |
| `Select`                          | Select dropdown with label and validation             |
| `Switch`                          | Toggle switch                                         |
| `TabList` + `TabListItem`         | Tab navigation (compound)                             |
| `Textarea`                        | Textarea with char count and validation               |

## API Notes (vs Svelte)

Svelte uses two-way binding (`bind:value`). React uses the controlled component pattern:

```tsx
// Controlled input
const [value, setValue] = useState('')
<Input value={value} onValueChange={setValue} />

// Controlled checkbox/switch
const [checked, setChecked] = useState(false)
<Checkbox id="cb" checked={checked} onCheckedChange={setChecked} />

// Compound components use context internally
const [tab, setTab] = useState('tab1')
<TabList value={tab} onValueChange={setTab}>
  <TabListItem value="tab1">Tab 1</TabListItem>
  <TabListItem value="tab2">Tab 2</TabListItem>
</TabList>
```

All components support `forwardRef` and spread `...rest` props to the underlying HTML element.

## Development

### Prerequisites

From the monorepo root:

```bash
yarn install
```

### Build

```bash
# Build react package only
make build-react

# Or from package dir
cd packages/xosmoz-react && yarn build
```

### Storybook

```bash
# From monorepo root (builds theme + css first)
make storybook-react

# Or directly
yarn storybook:react
```

Opens at `http://localhost:6007`

### Lint & Format

```bash
cd packages/xosmoz-react

# ESLint
yarn lint

# Prettier
yarn format          # write
yarn format:check    # check only
```

### Build Storybook

```bash
make storybook-react-build
```

### Publish

```bash
# Interactive local publish
make publish-react

# Or via GitHub Actions: "Publish React Package" workflow
```

### Project Structure

```
packages/xosmoz-react/
  src/
    components/
      badge/          Badge.tsx, Badge.stories.tsx, index.ts
      button/         Button.tsx, Button.stories.tsx, index.ts
      button-group/   ButtonGroup.tsx, ButtonGroupItem.tsx, ButtonGroupContext.ts, index.ts
      checkbox/       ...
      chip/           ...
      input/          ...
      link/           ...
      loader/         ...
      message/        ...
      radio/          ...
      radio-button/   ...
      select/         ...
      switch/         ...
      tab-list/       TabList.tsx, TabListItem.tsx, TabListContext.ts, index.ts
      textarea/       ...
    utils/
      cn.ts           # Class name joining utility
    index.ts          # Barrel exports
  .storybook/         # Storybook config
  eslint.config.js    # ESLint flat config
  tsup.config.ts      # Build config
  tsconfig.json
  package.json
```

## License

MIT