# `@nancyzeng0210/tvu-design-system/eslint-plugin`

ESLint plugin for consumer products of the TVU Design System.

Bundled inside the main `@nancyzeng0210/tvu-design-system` npm package; consumers don't install a separate plugin package.

## Install

The plugin ships with the library. Just install the library and add the plugin to your ESLint config.

```bash
pnpm add -D @nancyzeng0210/tvu-design-system eslint
```

## Usage (ESLint 9 flat config)

```js
// eslint.config.js
import tvuPlugin from '@nancyzeng0210/tvu-design-system/eslint-plugin'

export default [
  tvuPlugin.configs.recommended,
]
```

For greenfield TVU products that should not import local/CDN SVG icon assets, use the strict config:

```js
export default [
  tvuPlugin.configs.strict,
]
```

Or pick rules individually:

```js
import tvuPlugin from '@nancyzeng0210/tvu-design-system/eslint-plugin'

export default [
  {
    plugins: { '@nancyzeng0210/tvu-design-system': tvuPlugin },
    rules: {
      '@nancyzeng0210/tvu-design-system/no-hardcoded-color': 'error',
      '@nancyzeng0210/tvu-design-system/no-inline-svg': 'warn',
    },
  },
]
```

## Rules

| Rule | Severity (recommended) | Description |
|---|---|---|
| `no-hardcoded-color` | error | Forbids hex color literals (`#abc`, `#aabbcc`, `#aabbccdd`). Use TVU design tokens (`var(--brand)`, etc.) — see `src/tokens/variables.css` for the full set. Whitelist: `#fff` / `#000`. |
| `no-inline-svg` | error | Forbids inline `<svg>` elements, Unicode arrow glyphs (▲▼←→ etc.), and emoji status markers (🔴✅⚠️ etc.). Use the TVU icon registry: `import { ArrowUpIcon } from '@nancyzeng0210/tvu-design-system/icons/esm'`. |
| `icon-from-dist` | error | Icon asset imports from TVU must use documented subpath exports (`@nancyzeng0210/tvu-design-system/icons/esm` or `/icons/svg/<name>`), not deep imports into `/dist/icons/...` / `/src/icons/...`. In `strict` config only, arbitrary local/CDN SVG icon assets are also forbidden. |
| `no-base-component-import` | error | Disallows importing base/internal components (named `Base*` or from `/components/` / `/src/components/` subpaths). Use top-level canonical exports: `import { Button } from '@nancyzeng0210/tvu-design-system'`. See [AGENTS.md 硬规则 #6](../AGENTS.md). |
| `no-native-element` | error | Forbids hand-rolled native `<button>` / `<input>` / `<select>` / `<textarea>` when the DS has an equivalent — use canonical `Button` / `InputBoxLine\|Filled` / `SelectBoxLine\|Filled` (R15 Library-First). `<input type="hidden\|file">` and PascalCase components are not flagged. |
| `no-hardcoded-spacing` | error | Forbids hardcoded spacing/radius px that has a token equivalent (e.g. `padding: 16px` → `var(--sp-m)`, `border-radius: 8px` → `var(--r-m)`). Only flags spacing/radius properties whose exact value maps to a token; arbitrary px (1px borders, widths, 10px/20px, 24px radius) is left alone. Spacing half of §R2 token discipline. |

## Disable on a single line

```vue
<template>
  <!-- eslint-disable-next-line @nancyzeng0210/tvu-design-system/no-hardcoded-color -->
  <div style="color: #ff0000">Bug repro fixture — do not copy</div>
</template>
```

## Relationship to `audit-product-code.mjs`

The same R1/R2 rules are also available as a standalone CLI for consumers not using ESLint:

```bash
pnpm exec audit-product-code --dir packages/my-app/src
```

ESLint plugin and CLI overlap intentionally — pick whichever fits your tooling. The ESLint plugin is preferred for editor-integrated feedback; the CLI is preferred for CI gates where ESLint is not configured.
