npm package: @naarni/konsole
Description: EV instrument cluster React widget – use as a microfrontend or embed in any host app
Latest version: 1.0.3

# Konsole

EV instrument cluster React widget – use as a **microfrontend** or embed in any host app. Built with React, Tailwind CSS, Framer Motion, and Zustand.

## As an NPM package

### Install

```bash
npm install konsole
```

Peer dependencies (install if not already present):

```bash
npm install react react-dom framer-motion zustand lucide-react
```

### Use in your app

1. Import the widget and styles.
2. Render `InstrumentClusterWidget` in a sized container (or full viewport).

```tsx
import { InstrumentClusterWidget } from 'konsole'
import 'konsole/style.css'

// Embedded (transparent, fits container) – e.g. microfrontend
function App() {
  return (
    <div style={{ width: 800, height: 320 }}>
      <InstrumentClusterWidget
        fillViewport={false}
        transparentBackground={true}
        vehicleId="VEH-001"
        speedKph={65}
        socPct={78}
      />
    </div>
  )
}

// Standalone (full viewport, dark background)
function FullScreen() {
  return (
    <InstrumentClusterWidget
      fillViewport={true}
      transparentBackground={false}
      vehicleId="FLEET-99"
    />
  )
}
```

### Props (`InstrumentClusterWidgetProps`)

| Prop | Type | Description |
|------|------|-------------|
| `fillViewport` | `boolean` | When `true`, cluster fills the viewport; when `false`, fills the parent (default `false`). |
| `transparentBackground` | `boolean` | When `true`, no stage background/texture and body is transparent for iframe embed (default `false`). |
| `vehicleId` | `string \| null` | Optional vehicle identifier; shown as a badge when set. |
| `speedKph` | `number` | Speed in km/h (0–140). |
| `rpmK` | `number` | RPM in thousands (0–7). |
| `powerPct` | `number` | Power/regen percentage (-100–100). |
| `socPct` | `number` | State of charge (0–100). |
| `gear` | `'P' \| 'R' \| 'N' \| 'D'` | Current gear. |
| `telltales` | `Telltales` | Warning lights state. |
| `designWidth` | `number` | Design width (default 1920). |
| `designHeight` | `number` | Design height (default 720). |

All value props are optional. Missing values use built-in simulation or safe defaults. Types `Gear`, `Telltales`, and `VehicleSignals` are exported from `konsole`.

### Optional: stage texture

For the non-transparent (standalone) look, the cluster can show a subtle texture. To enable it, serve `console.jpeg` at `/console.jpeg` in your app (e.g. put it in your `public/` folder). If not present, the cluster still works; the texture is omitted.

---

## Publish to NPM

1. **Build the library**
   ```bash
   npm run build:lib
   ```
   This produces the `dist/` folder (JS, CSS, and type declarations).

2. **Log in to npm** (one-time)
   ```bash
   npm login
   ```

3. **Publish**
   ```bash
   npm publish
   ```
   - For a **scoped** package (e.g. `@your-username/konsole`), set in `package.json`:
     ```json
     "name": "@your-username/konsole"
     ```
     Then publish with:
     ```bash
     npm publish --access public
     ```
   - Bump `version` in `package.json` for each release.

4. **Optional: keep the repo private and only publish the package**  
   Leave `"private": true` out of `package.json` (or set to `false`) so `npm publish` works. To avoid publishing by mistake, add `"private": true` back when not releasing.

---

## Local development

- **Run the demo app** (with sample embed + standalone examples):
  ```bash
  npm run dev
  ```
- **Build the demo app**:
  ```bash
  npm run build
  npm run preview
  ```

## Deploy to Vercel (demo app)

You can deploy the **demo app** (not the NPM package) to Vercel so others can try the cluster:

1. Push the repo to GitHub and connect it to Vercel.
2. Build command: `npm run build`, output directory: `dist` (or whatever Vite uses; usually `dist` for the app).
3. To use the cluster as a **microfrontend** from another site, embed it in an iframe pointing at your Vercel URL, e.g. `https://your-konsole.vercel.app`, and size the iframe (e.g. 800×320). Use the app with `transparentBackground={true}` and `fillViewport={false}` so only the cluster is visible and the host background shows through.