# Nova Components React

**Nova Components React** provides an easy way to use [Nova’s native Web Components](https://www.npmjs.com/package/@nova-design-system/nova-webcomponents) within your React applications.

## Key Features

- **Lightweight Integration**: Leverage Nova Web Components with minimal configuration in React.
- **Customizable Styling**: Use Tailwind’s utility classes with the Nova Tailwind theme and plugin for token-driven styling and layouts.
- **Dark Mode Ready**: Toggle dark mode by adding the `dark` class to your `body` element.
- **Nova Font Pro Support**: Easily integrate Nova’s custom font for a consistent design experience.

---

## Installation

Install the necessary packages using the package manager of your choice:

> [!IMPORTANT]
> If you want to set it up in NextJS, please refer to the [Next.js E2E sample](../../e2e/apps/nextjs-e2e/README.md).

```bash
npm install @nova-design-system/nova-webcomponents @nova-design-system/nova-base @nova-design-system/nova-react
```
**or**
```bash
yarn add @nova-design-system/nova-webcomponents @nova-design-system/nova-base @nova-design-system/nova-react
```

> In some case, you might experience SSL certificate issues when working on Developers' VM. As documented in the [Developers' setup guide](https://wiki.eliagroup.eu/spaces/EAing/pages/89296007/2.3.3.10+Developer+Setup#id-2.3.3.10DeveloperSetup-NPMconfig), you need to turn off the SSL certificate verification:

```bash
npm config set strict-ssl false
```

> **Note for Yarn Users**
> Yarn **does not automatically** install peer dependencies. You must install the following peer dependency manually:
> ```bash
> yarn add @stencil/react-output-target
> ```

---

## Setting up Tailwind

Nova React requires Tailwind CSS for styling. Tailwind provides a powerful utility-first workflow and an optimized bundle size. Nova includes a dedicated Tailwind theme and plugin that map Nova’s design tokens to Tailwind’s theme and utilities, enabling consistent, token-driven styling across your app.

> **Tailwind Version**
> This guide is written for Tailwind v4. While compatible with v3, some features may not work as expected.

### About Tailwind and the Nova Plugin

- **What is Tailwind?** A utility-first CSS framework with low-level, composable classes (flex, grid, spacing, color, typography) to rapidly build UIs.
- **Nova Tokens**: Nova ships design tokens as CSS variables (via the Spark and Ocean themes) covering colors, spacing, typography, radii, shadows, and more.
- **Integration**:
  - `novaTailwindTheme` wires Nova tokens into Tailwind’s theme scales.
  - The Nova Tailwind plugin exposes utilities and variants that reference those tokens, so your Tailwind classes resolve to Nova’s token values at runtime.
- **Why import tokens CSS?** Import one token CSS file (`spark.css` or `ocean.css`) so the underlying CSS variables exist at runtime. The Tailwind utilities generated by the plugin read from these variables.
- **How to use**:
  - Build responsive layouts with standard Tailwind utilities (flex, grid, gap, spacing).
  - Customize Nova components by applying classes to `nv-*` elements and their slotted content.
  - Centralize repeated patterns using Tailwind’s `@apply`.
- **Do not mix with legacy utilities**: When using Tailwind, do not import `@nova-design-system/nova-base/dist/css/nova-utils.css` to avoid redundant CSS and larger bundles.

Below is an example setup using Vite + React. If you’re using another framework or bundler, please refer to the [Tailwind Installation Guide](https://tailwindcss.com/docs/installation).

### 1. Install Tailwind CSS and the Vite Plugin

```bash
npm install tailwindcss @tailwindcss/vite
```

> Use the **[Tailwind CSS IntelliSense Extension](https://marketplace.visualstudio.com/items?itemName=bradlc.vscode-tailwindcss)** to get full autocomplete support for Tailwind and Nova tokens.

### 2. Configure the Vite Plugin

Add the tailwindcss plugin to your `vite.config.ts`:

```ts
import { defineConfig } from 'vite'
import tailwindcss from '@tailwindcss/vite'

export default defineConfig({
  plugins: [
    tailwindcss(),
  ],
})
```

### 3. Create `tailwind.config.ts`

In the root of your project, create a `tailwind.config.ts` (or `.js`) file and include the Nova theme:

```ts
import type { Config } from 'tailwindcss'
import { novaTailwindTheme } from "@nova-design-system/nova-base/theme"

export default {
  theme: novaTailwindTheme,
} satisfies Config
```

### 4. Configure Tailwind and Nova Plugin in `index.css`

```css
@import 'tailwindcss';

@config "../tailwind.config.ts";
@plugin "@nova-design-system/nova-base/theme/plugin";
@custom-variant dark (&:where(.dark, .dark *));
```

> **Dark Mode**
> To enable dark mode, add the `dark` class to the `<body>` element.

### 5. Include the Nova Tokens (Spark or Ocean)

In your main entry point (`main.tsx` or `index.tsx`), import one of the Nova tokens CSS files:

```ts
import { StrictMode } from 'react'
import { createRoot } from 'react-dom/client'

import "@nova-design-system/nova-base/dist/css/spark.css"; // or ocean.css
import './index.css'

import App from './App.tsx'

createRoot(document.getElementById('root')!).render(
  <StrictMode>
    <App />
  </StrictMode>
)
```

> When using Tailwind, do not import `@nova-design-system/nova-base/dist/css/nova-utils.css`.

### 6. Use Nova Components with Tailwind Utilities

```tsx
import { useState } from 'react'
import { NvButton } from "@nova-design-system/nova-react"

const MyComponent: React.FC = () => {
  const [count, setCount] = useState(0)

  return (
    <div className="flex items-center justify-center">
      <NvButton danger onClick={() => setCount(count + 1)}>
        Count is {count}
      </NvButton>
    </div>
  )
}

export default MyComponent
```

- Apply Tailwind classes to build layouts (e.g., `flex`, `grid`, `gap-*`, `p-*`, `m-*`).
- Compose classes to customize the look and spacing of Nova components and their content.

### 7. Setup the Nova Font

Follow the steps in the [Nova Font Pro Integration](#nova-font-pro-integration) section below.

---

### Creating Your Own Style Components with Tailwind

If you find you’re repeating the same set of utility classes for certain UI elements (e.g., a card component), you can group them using Tailwind’s `@apply` keyword:

```css
/* any css file */
.card {
  @apply bg-gray-50 dark:bg-gray-500 p-4 rounded-md shadow-sm;
}
```

Then in your markup, instead of:

```jsx
<div className="bg-gray-50 dark:bg-gray-500 p-4 rounded-md shadow-sm">
  {/* Content */}
</div>
<div className="bg-gray-50 dark:bg-gray-500 p-4 rounded-md shadow-sm">
  {/* Content */}
</div>
```

You can use your new `card` class:

```jsx
<div className="card">
  {/* Content */}
</div>
<div className="card">
  {/* Content */}
</div>
```

This ensures consistent styling and keeps your markup clean. Any colors or spacing used will reference the correct Nova Tokens.

---

## Nova Font Pro Integration

> [!WARNING]
> Nova Fonts is a protected asset and is not included in the Nova Base package. You need to include the Nova Fonts CSS file in your project.
> To get the Nova Fonts URL, **please contact us via Teams** or get the URL in the Nova Design System [internal wiki](https://dev.azure.com/elia-digitization/Nova/_wiki/wikis/Nova.wiki/30245/Nova-Font-Pro).

 Once you have the URL, you can integrate it using any of these methods:

### Option 1: Import in Global CSS (Recommended)
In your main CSS file (e.g., `src/index.css`):

```css
@import url('contact-us-for-URL/nova-fonts-pro.css');
```

### Option 2: HTML Integration
In your `index.html`:

```html
<!DOCTYPE html>
<html>
<head>
  <link rel="stylesheet" href="contact-us-for-URL/nova-fonts-pro.css">
</head>
<body>
  <div id="root"></div>
</body>
</html>
```

The `nova-fonts-pro.css` file includes both font definitions and the `font-family` rule for the `body`, automatically applying the fonts across your React application.

