|
| 1 | +# Upgrade prompt: `@open-elements/ui` 0.5.x → 0.6.0 |
| 2 | + |
| 3 | +`@open-elements/ui` 0.6.0 is a purely additive release. It promotes six components that were hardened inside `open-crm` into the shared design system. No `peerDependencies` changed, no exports were removed, no APIs were renamed. |
| 4 | + |
| 5 | +The point of upgrading is twofold: |
| 6 | + |
| 7 | +1. Get the version bump in so the consumer is on the latest line. |
| 8 | +2. Find and delete local copies of these components in the consumer repo, replacing them with imports from `@open-elements/ui`. |
| 9 | + |
| 10 | +This file is a self-contained prompt for an agent (Claude Code, etc.) to run inside a consumer repo. Paste it verbatim. |
| 11 | + |
| 12 | +--- |
| 13 | + |
| 14 | +## Prompt |
| 15 | + |
| 16 | +You are working inside an app that depends on `@open-elements/ui`. Goal: upgrade to `^0.6.0` and replace any local copies of the newly promoted components with imports from the library. |
| 17 | + |
| 18 | +### What changed in 0.6.0 |
| 19 | + |
| 20 | +Six new components are exported from `@open-elements/ui`. They use semantic tokens (`primary`, `destructive`, `muted-foreground`) so brand overrides keep working from `brand.css`. |
| 21 | + |
| 22 | +| Export | Purpose | |
| 23 | +| --- | --- | |
| 24 | +| `ActionIconButton` | Tiny inline icon button with `default` \| `success` tones. Auto-`stopPropagation`, no chrome. Building block for the buttons below. | |
| 25 | +| `CopyToClipboardButton` | Composes `ActionIconButton` with a 2 s `Copy` ↔ `Check` feedback animation. | |
| 26 | +| `MailtoButton` | Opens a `mailto:` URL via `ActionIconButton`. | |
| 27 | +| `ExternalLinkButton` | Opens a URL in a new tab with `noopener,noreferrer`. | |
| 28 | +| `TooltipIconButton` | Ghost icon `Button` wrapped in `Tooltip`, `default` \| `destructive` tones. Includes the disabled-button-needs-`<span>` Tooltip workaround and an `asChild` variant for navigation use cases. Also exports `TooltipIconButtonProps`. | |
| 29 | +| `TablePagination` | `Select` + per-page label + plural-aware total + prev/next (only when `totalPages > 1`). Owns the `localStorage` write for the page-size preference. Also exports `PaginationTranslations`. | |
| 30 | + |
| 31 | +There are **no** breaking changes, **no** removed exports, and **no** dependency manifest changes. If you only bump the version and run `pnpm install`, everything will still work. |
| 32 | + |
| 33 | +### Steps |
| 34 | + |
| 35 | +1. **Find the consumer's frontend package.json.** Usually `package.json` at repo root or under `frontend/`. Confirm `@open-elements/ui` is listed. |
| 36 | + |
| 37 | +2. **Bump `@open-elements/ui` to `^0.6.0`** in that `package.json`, then run: |
| 38 | + |
| 39 | + ```bash |
| 40 | + pnpm install |
| 41 | + ``` |
| 42 | + |
| 43 | +3. **Search for local re-implementations** that should be replaced by the new exports. The `open-crm` repo is the most likely candidate — these components started life there. For each component, grep the source directory: |
| 44 | + |
| 45 | + ```bash |
| 46 | + for name in "ActionIconButton" "CopyToClipboardButton" "MailtoButton" \ |
| 47 | + "ExternalLinkButton" "TooltipIconButton" "TablePagination"; do |
| 48 | + echo "=== $name ===" |
| 49 | + grep -rn "$name" src --include="*.ts" --include="*.tsx" 2>/dev/null |
| 50 | + done |
| 51 | + ``` |
| 52 | + |
| 53 | + For each match, decide: |
| 54 | + - **Local file defines the component** (`export function ActionIconButton`, etc.) → this is a candidate for deletion. Continue with step 4. |
| 55 | + - **Local file imports from `@open-elements/ui`** → already migrated, skip. |
| 56 | + - **Local file imports from a relative path** (`./action-icon-button`, `../components/...`) → the import target is the candidate; rewrite to `@open-elements/ui`. |
| 57 | + |
| 58 | +4. **For each candidate local component, verify behavioural parity** before deleting. Open the local file alongside the library version and confirm: |
| 59 | + |
| 60 | + - Same props, same defaults (`tone = "default"`, etc.). |
| 61 | + - Same className strings / tone tokens. |
| 62 | + - Same side effects (e.g. `event.stopPropagation()`, `noopener,noreferrer`, `localStorage.setItem`). |
| 63 | + - For `TooltipIconButton`: does the local version support the disabled-`<span>` workaround and the `asChild` variant? If your local copy is simpler, the library version is a strict superset — safe to switch. |
| 64 | + - For `TablePagination`: does the local version own the `localStorage` write, hide prev/next when `totalPages <= 1`, and use plural-aware totals via `{count}` interpolation? If yes → drop-in. If your local copy uses a different pluralisation strategy or a different storage key shape, **stop and ask the user** before changing behaviour. |
| 65 | + |
| 66 | + If parity holds: |
| 67 | + - Delete the local component file (and its test file, if any). |
| 68 | + - Rewrite all imports to `import { Foo } from "@open-elements/ui";`. |
| 69 | + |
| 70 | + If parity does **not** hold (the local copy has extra props, different tones, custom analytics hooks, etc.), leave it alone and add a TODO comment pointing at the new library export so the divergence is visible. |
| 71 | + |
| 72 | +5. **Type-only re-exports.** If consumer code imports `TooltipIconButtonProps` or `PaginationTranslations` from a local path, switch those imports to `@open-elements/ui` too — both types are exported from the library. |
| 73 | + |
| 74 | +6. **Verify nothing broke.** All three must pass: |
| 75 | + |
| 76 | + ```bash |
| 77 | + pnpm exec tsc --noEmit |
| 78 | + pnpm test |
| 79 | + pnpm build |
| 80 | + ``` |
| 81 | + |
| 82 | +7. **Commit** with a clear message, e.g.: |
| 83 | + |
| 84 | + ``` |
| 85 | + chore(deps): upgrade @open-elements/ui to 0.6.0 |
| 86 | +
|
| 87 | + Replace local <list> with the promoted exports from the design system. |
| 88 | + ``` |
| 89 | + |
| 90 | + If you only did the version bump and found no local duplicates, say so: |
| 91 | + |
| 92 | + ``` |
| 93 | + chore(deps): upgrade @open-elements/ui to 0.6.0 |
| 94 | +
|
| 95 | + No consumer changes required — purely additive release. |
| 96 | + ``` |
| 97 | + |
| 98 | +### Guard rails |
| 99 | + |
| 100 | +- **Do not** change the public API of the consumer app while doing this upgrade. Replacing a local `TooltipIconButton` with the library one is fine; renaming consumer-facing props or changing UX is out of scope. |
| 101 | +- **Do not** delete a local component just because its name matches a new export. Verify behavioural parity first (step 4). |
| 102 | +- **Do not** remove `peerDependencies` — `peerDependencies` did not change in 0.6.0. If you find peer-dep cleanup work to do, it belongs in the 0.5.0 upgrade pass (`docs/upgrade-to-0.5.md`), not this one. |
| 103 | +- **Do not** bump unrelated dependency versions in the same change. |
| 104 | + |
| 105 | +### Don't do this |
| 106 | + |
| 107 | +- Do not refactor existing components that consume the new exports. Just swap the import; styling and layout stay as-is. |
| 108 | +- Do not edit `@open-elements/ui` from the consumer side. If a local component has extra behaviour that the library version lacks, open an issue against the UI lib instead of monkey-patching. |
| 109 | +- Do not bundle this upgrade with feature work in the same PR. Keep the dependency bump and the local-duplicate cleanup focused. |
0 commit comments