# Migrating to TVU Design System v1.0

Guide for upgrading consumer products from v0.x to v1.0.

> **Latest published version + v1.0 status**: see [`STATUS.md`](./STATUS.md) (single source of truth for versions) and [`V1_RELEASE_CHECKLIST.md`](./V1_RELEASE_CHECKLIST.md) for outstanding gates.

---

## Quick path summary

| From | Action |
|---|---|
| v0.1.x | Skip ahead to v1.0 via intermediate (v0.4.0 was last non-breaking; v0.5/0.6 introduced removals). Read all sections below. |
| v0.2.x – v0.4.x | Apply v0.5 changes (FormItem.label / Tooltip.content named slots — no removals; new behavior). Then v0.6 changes. |
| v0.5.0 | Apply v0.6 Button breaking changes (variant/size/disabled/loading deletion). |
| v0.6.0 | No code changes needed — v1.0 is currently planned as additive only on top of v0.6 surface. |

---

## v0.5 → v0.6 (BREAKING)

### Button legacy props removed

Props `variant` / `size` / `disabled` / `loading` (all `@deprecated since 0.5.0`) were **deleted in v0.6.0**. Migrate to the separate-axis API exposed by the exported `Button` (source of truth = `src/canonical/ButtonBridge.vue` `defineProps`): `color` / `style` / `size` / `radius` / `fixedWidth` / `status` / `icon` / `theme`. (Note: the appearance axis `style` was renamed to `fill` in the F59 change below.)

```diff
- <Button variant="fill-green" size="l">Save</Button>
+ <Button color="green" size="L">Save</Button>              <!-- `filling` is the default fill -->

- <Button variant="ghost-red">Delete</Button>
+ <Button fill="ghost" color="red">Delete</Button>

- <Button variant="text-gray">Cancel</Button>
+ <Button fill="rimless" color="gray 1">Cancel</Button>

- <Button :disabled="true">N/A</Button>
+ <Button status="disable">N/A</Button>

- <Button :loading="true">Saving</Button>
+ <Button status="loading" icon="loading">Saving</Button>
```

> The diff above already uses `fill` (current API, renamed from `style` in INFRA-F59). If you are on v0.6 and see `:style="'ghost'"` in old docs, apply the F59 rename below.

Mapping table (appearance axis `style` was renamed to `fill` in INFRA-F59 — see below):

| Legacy variant | `fill` | `color` |
|---|---|---|
| `fill-green` | `filling` | `green` |
| `fill-gray` | `filling` | `gray 1` |
| `ghost-green` | `ghost` | `green` |
| `ghost-gray` | `ghost` | `gray 1` |
| `ghost-red` | `ghost` | `red` |
| `text-green` | `rimless` | `green` |
| `text-gray` | `rimless` | `gray 1` |
| `text-red` | `rimless` | `red` |
| `text-orange` | `rimless` | `orange` |

| Legacy size | `size` |
|---|---|
| `xs` | `XS` |
| `s` | `S` |
| `m` | `M` |
| `l` | `L` |

If you use `<ButtonBridge>` (the canonical wrapper) — no changes needed; it has always exposed only the canonical API.

### ESLint plugin (new, opt-in)

v0.6.0 ships an ESLint 9 flat-config plugin via subpath export. **Optional but recommended** for consumer code hygiene:

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

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

Rules enforce:
- `no-hardcoded-color` — use design tokens (`var(--brand)`), not hex literals
- `no-inline-svg` — use TVU icon registry, not raw `<svg>` / Unicode arrows / emoji
- `icon-from-dist` — icon imports must use documented subpath exports
- `no-base-component-import` — use top-level canonical exports, not deep imports

---

## Consumer setup (npmrc)

The package publishes to GitHub Packages registry. To install:

1. Create a [GitHub Personal Access Token](https://github.com/settings/tokens) with `read:packages` scope.
2. Add to your project's `.npmrc`:

   ```
   @nancyzeng0210:registry=https://npm.pkg.github.com
   //npm.pkg.github.com/:_authToken=YOUR_TOKEN
   ```

3. Install:

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

See [GETTING_STARTED.md](../GETTING_STARTED.md) for full setup including style import and Vue plugin registration.

---

## INFRA-F59: 外观变体 prop 全组件统一命名 (BREAKING)

### 改名对照

| 组件 | 旧 prop | 新 prop |
|---|---|---|
| Button | `style` | `fill` |
| Badge | `tag` | `fill` |
| Tab, TabList, TabItem | `type` | `fill` |
| Tab, TabItem | `property2` | `color` |
| TabItem | `property1` | `state` |
| Steps, StepItem | `stepStyle` | `type` |
| StepItem | `style` | (removed) |
| InputNumber | `property1` | `type` |

枚举值不变，仅 code 侧公开 prop 名统一；Figma 属性名不变。

### 迁移示例

```diff
<!-- Button -->
- <Button :style="'ghost'" color="green">Save</Button>
+ <Button fill="ghost" color="green">Save</Button>

<!-- Badge (fill values: Filled | Line) -->
- <Badge tag="Line">New</Badge>
+ <Badge fill="Line">New</Badge>

<!-- Tab (fill values: Line | Text | Filled) -->
- <Tab type="Filled">...</Tab>
+ <Tab fill="Filled">...</Tab>

<!-- Steps (type values: number | icon) -->
- <Steps stepStyle="icon">...</Steps>
+ <Steps type="icon">...</Steps>
```

---

## v0.6 → v1.0 (planned additive only)

v1.0 is currently planned to be **additive** on top of v0.6.0 surface — no Button-style API removals expected. Specific v1.0 deliverables and gating items are in [`V1_RELEASE_CHECKLIST.md`](./V1_RELEASE_CHECKLIST.md).

If outstanding v1.0 work uncovers breakages (e.g. a11y contrast cleanup may shift CSS variable *values*), that will be noted as an addendum here.

---

## Audit / lint tooling reference

Consumer products can run library-provided audits as CI gates:

```bash
# Lint TVU consumer mockup files (Figma file via API)
pnpm audit:consumer-mockup --file <fileKey>            # I1/I2/I3 + C1/C2/C3
pnpm audit:consumer-mockup-binding <fileKey>           # M0/M1/M30 library binding

# Lint consumer product code
pnpm audit:consumer-code --dir src                     # R1/R2/R16 CLI form
# Or use the ESLint plugin (preferred for editor feedback)
```

All audit CLIs ship inside the main `@nancyzeng0210/tvu-design-system` package; no separate install needed.

---

## Getting help

- Component API reference: docs site (run `pnpm dev` locally; deployed docs URL TBD post-v1.0)
- Bug reports / questions: GitHub issues on `NancyZeng0210/TVU-Design-System`
- Design token list: `src/tokens/variables.css` (canonical truth) or `docs/API_STABILITY.md`
