# CCL UI Components (React)

Library source and Vite demo live in this package. **Global install** (no GitHub Packages token for consumers) is done by publishing to the **public npm registry** as `@Crystal-Code-Labs/ccl-ui-components-react`.

## Install in any project

```bash
npm install @Crystal-Code-Labs/ccl-ui-components-react
```

Public packages do **not** require a custom `.npmrc` for `npm install`. Match **React 19** with the library’s peer range.

```ts
import { Button, Input } from '@Crystal-Code-Labs/ccl-ui-components-react';
import '@Crystal-Code-Labs/ccl-ui-components-react/styles.css';
```

## Publish (maintainers)

1. Bump **`version`** in `publish/package.json`.
2. Ensure your npm user is a member of the **npm org** that owns the **`@Crystal-Code-Labs`** scope (create the org on [npmjs.com](https://www.npmjs.com/) if needed).
3. `npm login` (registry defaults to `https://registry.npmjs.org/`).
4. From this directory: **`npm run publish:lib`** (builds `dist/npm` and runs `npm publish --access public`).

`publish/package.json` sets `publishConfig.registry` to the public registry and `access: "public"` so scoped packages are readable worldwide.

### `.npmrc` for publish (optional)

1. Copy **`.npmrc.example`** → **`.npmrc`** in this folder (`.npmrc` is gitignored).
2. Export **`NPM_TOKEN`** (classic npm token with publish rights) before **`npm run publish:lib`**.  
   **`build:lib`** copies `.npmrc` into **`dist/npm/`** when present (same idea as Angular copying `.npmrc` next to the built package).

If you use **`npm login`** only and no token file, you can skip `.npmrc`; publish still works from an interactive session.

## Examples (`examples/react-demo`)

Same pattern as **`ccl-ui-components-angular/examples/angular-demo`**: a small consumer app that depends on the **built** library via **`file:`**.

```bash
# From ccl-ui-components-react/
npm run build:lib
cd examples/react-demo
npm install
npm run dev
```

`examples/react-demo/package.json` uses `"@Crystal-Code-Labs/ccl-ui-components-react": "file:../../dist/npm"`. After you change library code, run **`npm run build:lib`** again, then in the example **`npm install`** (or `npm update`) so the file link picks up the new build.

---

## Demo app (Vite + React + TypeScript)

This template provides a minimal setup to get React working in Vite with HMR and some ESLint rules.

Currently, two official plugins are available:

- [@vitejs/plugin-react](https://github.com/vitejs/vite-plugin-react/blob/main/packages/plugin-react) uses [Oxc](https://oxc.rs)
- [@vitejs/plugin-react-swc](https://github.com/vitejs/vite-plugin-react/blob/main/packages/plugin-react-swc) uses [SWC](https://swc.rs/)

## React Compiler

The React Compiler is not enabled on this template because of its impact on dev & build performances. To add it, see [this documentation](https://react.dev/learn/react-compiler/installation).

## Expanding the ESLint configuration

If you are developing a production application, we recommend updating the configuration to enable type-aware lint rules:

```js
export default defineConfig([
  globalIgnores(['dist']),
  {
    files: ['**/*.{ts,tsx}'],
    extends: [
      // Other configs...

      // Remove tseslint.configs.recommended and replace with this
      tseslint.configs.recommendedTypeChecked,
      // Alternatively, use this for stricter rules
      tseslint.configs.strictTypeChecked,
      // Optionally, add this for stylistic rules
      tseslint.configs.stylisticTypeChecked,

      // Other configs...
    ],
    languageOptions: {
      parserOptions: {
        project: ['./tsconfig.node.json', './tsconfig.app.json'],
        tsconfigRootDir: import.meta.dirname,
      },
      // other options...
    },
  },
])
```

You can also install [eslint-plugin-react-x](https://github.com/Rel1cx/eslint-react/tree/main/packages/plugins/eslint-plugin-react-x) and [eslint-plugin-react-dom](https://github.com/Rel1cx/eslint-react/tree/main/packages/plugins/eslint-plugin-react-dom) for React-specific lint rules:

```js
// eslint.config.js
import reactX from 'eslint-plugin-react-x'
import reactDom from 'eslint-plugin-react-dom'

export default defineConfig([
  globalIgnores(['dist']),
  {
    files: ['**/*.{ts,tsx}'],
    extends: [
      // Other configs...
      // Enable lint rules for React
      reactX.configs['recommended-typescript'],
      // Enable lint rules for React DOM
      reactDom.configs.recommended,
    ],
    languageOptions: {
      parserOptions: {
        project: ['./tsconfig.node.json', './tsconfig.app.json'],
        tsconfigRootDir: import.meta.dirname,
      },
      // other options...
    },
  },
])
```
