# @corva/ui

<a href="https://storybook.dev.corva.ai/" target="_blank"><img src="https://raw.githubusercontent.com/storybooks/brand/master/badge/badge-storybook.svg"></a>
[![npm version](https://img.shields.io/npm/v/@corva/ui/latest?color=green&label=%40latest&style=flat-square)](https://www.npmjs.com/package/@corva/ui)
[![npm version](https://img.shields.io/npm/v/@corva/ui/next?color=yellow&label=%40next&style=flat-square)](https://www.npmjs.com/package/@corva/ui)
[![npm version](https://img.shields.io/npm/v/@corva/ui/dev?color=orange&label=%40dev&style=flat-square)](https://www.npmjs.com/package/@corva/ui)

develop: [![Publish](https://github.com/corva-ai/corva-ui/actions/workflows/publish.yml/badge.svg)](https://github.com/corva-ai/corva-ui/actions/workflows/publish.yml)

This repo contains components/utils which are shared for Corva UI apps.

### When you need some library changes

Currently, `@corva/ui` library is owned by the Dev Center team, but is developed by every Corva FE developer. So, if you
need to make some update in it - you can do it by yourself. For small updates - just make a PR - and someone from the
Dev Center team will review it.

If it's something pretty big - it's better to reach out someone from the Dev Center team first, to tell what you need
and get feedback how to better do it. Otherwise - you risk that your huge PR on which you worked a week can be rejected
because it can be not consistent with the rest of the lib

### Release & deploy of the library

How to bump the version? What should be the branch name? And other more advanced cases, like release/hotfixes. The
guideline for all of these cases can be
found [here (Corva access required)](https://www.notion.so/corva/corva-ui-d510f545ffb74c9bafd6b1bfbc0b99bf)

### Stories for every public component

Every public `@corva/ui` component has a corresponding `.stories.js` file that describes the component. When you work
with
public `@corva/ui`
components - please also update it's `stories.js` file when it's necessary

## AI-Assisted Development (MCP Server)

`@corva/ui` ships an MCP (Model Context Protocol) server that exposes the component library to AI coding agents. Setup
supports Claude Code, Cursor, and Codex CLI. The server provides tools for searching components and viewing component,
hook, theme, constants, and API client documentation.

> If you just generated a fresh project with the latest `create-corva-app`, MCP is already configured for Claude Code,
> Cursor, and Codex CLI — you can skip this section. (Older projects scaffolded before MCP was added to the template
> still need the setup below.)

Quick setup (run from your project root):

```bash
npx -p @corva/ui corva-ui-mcp-setup
```

If `.mcp.json`, `.cursor/mcp.json`, or `.codex/config.toml` already exists, the command extends it — existing MCP server
entries are preserved, and only the `corva-ui` entry is added or updated.

See [MCP Docs](./MCP_README.md) for the full list of tools, per-IDE setup (local / monorepo / global), and
troubleshooting.

## Figma Code Connect

[Code Connect](https://www.figma.com/developers/code-connect) links corva-ui components to their Figma design nodes so that **Dev Mode** in Figma shows real, production-ready code snippets instead of auto-generated stubs.

### Commands

| Command | What it does |
|---|---|
| `yarn figma:publish` | Publish all Code Connect mappings to Figma. Safe to run multiple times — upserts per node, does not touch other nodes' mappings. |
| `yarn figma:publish-file <path>` | Publish a single Code Connect file via the native CLI `--file` flag. In this repo, each file maps one node. |
| `yarn figma:dry-run` | Validate all `.figma.tsx` files locally without publishing — use before merging |
| `yarn figma:dry-run-file <path>` | Validate a single Code Connect file locally via the native CLI `--file` flag. |
| `yarn figma:unpublish` | Remove Code Connect mappings from Figma. Safe to run multiple times — second run is a no-op (logs a warning if nothing was found to delete). |
| `yarn figma:unpublish-file <path>` | Unpublish a single Code Connect file via the native CLI `--file` flag. |
| `yarn figma:unpublish-node-force '<URL>'` | Force-remove a mapping via the REST API. Use when the Figma component has been deleted and `unpublish` fails. |

### Creating a new mapping

Each component that has a Figma counterpart gets a `.figma.tsx` file next to its source:

```
src/componentsV2/Button/Button.figma.tsx
src/components/StatusBadge/StatusBadge.figma.tsx
src/icons/customIcons/icons/Pin.figma.tsx
```

Minimal template:

```tsx
import figma from '@figma/code-connect';
import { MyComponent } from './MyComponent';

figma.connect(
  MyComponent,
  'https://www.figma.com/design/FILEKEY/FILE-NAME?node-id=NODE_ID',
  {
    props: {
      // map Figma properties → component props
    },
    example: ({ ...props }) => <MyComponent {...props} />,
  }
);
```

Use `yarn figma:dry-run` to verify the file is valid before publishing.

### Publishing / unpublishing a single component

To publish or validate a single mapping, use the CLI `--file` flag:

```bash
yarn figma:publish-file src/componentsV2/Button/Button.figma.tsx
yarn figma:dry-run-file src/componentsV2/Button/Button.figma.tsx
yarn figma:unpublish-file src/componentsV2/Button/Button.figma.tsx
```

In this repo, `.figma.tsx` / `.figma.ts` files usually contain a single `figma.connect(...)`, but some files may include multiple mappings, so `--file` operations can affect more than one Figma node.

If the local Code Connect file no longer exists or the Figma component was deleted, use `yarn figma:unpublish-node-force '<URL>'` to remove the stale mapping directly via the API.

### Interactive setup

To scaffold `.figma.tsx` files for unmapped components:

```bash
npx figma connect
```

This runs a **local-only wizard** — it creates or modifies `.figma.tsx` files in the repo but does not publish or delete any existing Figma mappings. Run `yarn figma:publish` afterwards to push the new files.

## Build-time variables

| Name                   | Default Value            | Required |
|------------------------|--------------------------|----------|
| REACT_APP_API_URL      | https://api.qa.corva.ai  | No       |
| REACT_APP_DATA_API_URL | https://data.qa.corva.ai | No       |

## Local development

- `yarn storybook` will launch local storybook server which is convenient to use for components testing when you work on
  public components. That's a playground for building public components.
- `yarn start` will open ExampleApp.js in your browser. That's a playground for building non-public components (such
  components will be moved from @corva/ui soon)

## Link local `@corva/ui` to your app

### Pre-requisite

- Make sure you are using `@corva/ui` with latest updates from `development` branch

- If your app is using `getWebpackConfig` from `@corva/ui` instead of `@corva/dc-platform-shared`, migrate it according
  to [this guide](https://www.notion.so/corva/Migration-to-corva-dc-platform-shared-721cc822e23c4c43a7630b73fdeec3d9)

### Steps to link your local DC app\*\*

1. Run `yarn build-dev` or `yarn build-watch` in @corva/ui repo
   <br/>**\*Note:** `yarn build` will not work for linking\*

2. `cd ./dist` and run `yarn link` in @corva/ui dist folder (only first time)

3. Run `yarn link @corva/ui` in your local DC app root folder

4. Add following parameters to the `config-overrides.js`.<br/>It should avoid the issue of multiple React instances and
   the MUI styling issue

```js
{
  resolve: {
    alias: {
      react: resolve('./node_modules/react'),
      '@material-ui': resolve('./node_modules/@material-ui'),
    }
  }
}
```

5. Run `yarn start` in your local DC app root folder

**\*Note:** npm link will not install `@corva/ui` dependencies in your node modules folder.\*
If you want to debug a change in `@corva/ui` dependencies, you should use `yarn add file:../corva-ui/dist`, this will
install new dependencies.

### Troubleshooting

#### Failed to compile.<br />`Module not found: Can't resolve '@corva/ui' in ...`

Most likely you need to [migrate to
`@corva/dc-platform-shared`](https://www.notion.so/corva/Migration-to-corva-dc-platform-shared-721cc822e23c4c43a7630b73fdeec3d9)
for cjs webpack config usage

#### Error.<br/>`Invalid hook call. Hooks can only be called inside of the body of a function component...`

In that case, your bundler might “see” two Reacts — one in application folder and one in your library folder. Assuming
myapp and mylib are sibling folders, one possible fix is to run npm link ../myapp/node_modules/react from mylib. This
should make the library use the application’s React copy.

Or change the webpack configuration in `config-overrides.js` file in your app. (Don't commit the changes of this file)

```
{
    resolve: {
        alias: {
            react: path.resolve('./node_modules/react')
        }
    }
}
```

#### Material UI styles are corrupted

Add the following parameter to the `config-overrides.js` file in your app

```
{
    resolve: {
        alias: {
            '@material-ui': resolve('./node_modules/@material-ui')
        }
    }
}
```

### CI/CD

#### Stale workflow

To prevent pull request from piling up and save on resources, there is a [stale workflow](./.github/workflows/stale.yml)
running in this repository. It will automatically run on schedule to mark PR's that have not received any updates in 14
days as stale, marking them with label and leaving a comment. More importantly, preview environment for stale PRs are
removed. To "unstale" the PR, you either need to make any change to it, push new commit or just remove the `stale`
label.
If for some reason your PR does need to stay not stale for a long time, you can add `never-stale` label to it.

> [!IMPORTANT]  
> Stale pull requests will be deleted after 180 days!
