From 0d421ef203ea9778485ab3f59f2d62cdc0ca0c22 Mon Sep 17 00:00:00 2001 From: Adrien Zheng Date: Mon, 30 Mar 2026 14:55:45 -0400 Subject: [PATCH 1/3] chore: deprecate old card 1. derpecated Card and related components and types 2. added derepcate-cds-api-skill --- .claude/skills/deprecate-cds-api/SKILL.md | 130 +++++++++++++++++++ packages/common/src/types/CardHeaderProps.ts | 4 + packages/common/src/types/CardMediaProps.ts | 4 + packages/mobile/src/cards/Card.tsx | 4 + packages/mobile/src/cards/CardBody.tsx | 4 + packages/mobile/src/cards/CardFooter.tsx | 4 + packages/mobile/src/cards/CardHeader.tsx | 8 ++ packages/mobile/src/cards/CardMedia.tsx | 8 ++ packages/web/src/cards/Card.tsx | 4 + packages/web/src/cards/CardBody.tsx | 3 + packages/web/src/cards/CardFooter.tsx | 4 + packages/web/src/cards/CardHeader.tsx | 4 + packages/web/src/cards/CardMedia.tsx | 4 + 13 files changed, 185 insertions(+) create mode 100644 .claude/skills/deprecate-cds-api/SKILL.md diff --git a/.claude/skills/deprecate-cds-api/SKILL.md b/.claude/skills/deprecate-cds-api/SKILL.md new file mode 100644 index 0000000000..dcf78e24c4 --- /dev/null +++ b/.claude/skills/deprecate-cds-api/SKILL.md @@ -0,0 +1,130 @@ +--- +name: deprecate-cds-api +description: | + Deprecates a CDS component, hook, or other exported symbol with consistent JSDoc, version tags, + and docsite metadata across every public export path (web, mobile, common, visualization), not only + the original package. Use whenever the user asks to deprecate a CDS component or API, mark something + as deprecated, add @deprecated / @deprecationExpectedRemoval, or update deprecation warnings in + apps/docs metadata under components or hooks (webMetadata.json / mobileMetadata.json / metadata.json). + Also use when replacing a component or hook and sunsetting the old one. +allowed-tools: Read, Grep, Glob, StrReplace +argument-hint: ' — replacement (e.g. Tabs) — [optional notes]' +--- + +# Deprecate CDS public API + +Automate the standard CDS deprecation workflow for symbols exported from `packages/web`, `packages/mobile`, `packages/common`, `packages/web-visualization`, or `packages/mobile-visualization`. + +## Inputs to confirm first + +1. **What is being deprecated?** Component name, hook, prop, or other exported symbol. +2. **What should consumers use instead?** The replacement must be named in JSDoc and in docs `warning` text. + +--- + +## Step 0 — Discover every public export (all packages) + +**Deprecate the symbol everywhere it is publicly reachable**, not only where it is first implemented. + +1. For each CDS package (`web`, `mobile`, `common`, `web-visualization`, `mobile-visualization`), trace the symbol from that package’s `package.json` **`exports`** map → barrel / `index` files → the module that declares or re-exports the symbol. +2. **`Grep`** for the symbol name under `packages//src` (e.g. `export { Foo`, `export * from`, `Foo as`) to catch re-exports and alternate entry paths. +3. **Every** package that publicly exports the symbol must end up with deprecation coverage: primary implementation **and** any re-export site where your tooling or consumers would not see JSDoc from the source file (add JSDoc on the re-export line or duplicate the tags as needed so imports from `@coinbase/cds-web`, `@coinbase/cds-mobile`, `@coinbase/cds-common`, etc. all surface the deprecation). + +Do **not** skip a package because the symbol is “originally” defined elsewhere—if consumers can import it from that package, it must be deprecated there too. + +--- + +## Step 1 — JSDoc on the deprecated symbol + +Add or extend JSDoc immediately above the deprecated export (component, function, type alias, const, interface field, etc.). + +Use the **standard JSDoc tag `@deprecated`** (not `@deprecate`). + +**Required shape:** + +```ts +/** + * …existing description if any… + * + * @deprecated . This will be removed in a future major release. + * @deprecationExpectedRemoval v + */ +``` + +Rules: + +- The `@deprecated` line must end with exactly: `This will be removed in a future major release.` (same sentence as the rest of the deprecation message, as in existing CDS examples). +- `@deprecationExpectedRemoval` must be a single token like `v9` (lowercase `v` + major number only, no minor/patch). + +--- + +## Step 2 — Next major version for `@deprecationExpectedRemoval` + +**`packages/web`, `packages/mobile`, and `packages/common` always share the same semver.** Read the **`version`** field from any one of `packages/web/package.json`, `packages/mobile/package.json`, or `packages/common/package.json` — they match. + +1. Take **`version`** (e.g. `8.60.0`). +2. Let **current major** be the first segment (`8` in `8.60.0`). +3. Set **`NEXT_MAJOR = current major + 1`** and use `@deprecationExpectedRemoval v` (e.g. current `8.x` → `v9`). + +For symbols owned only by **`packages/web-visualization`** or **`packages/mobile-visualization`**, read that package’s `package.json` instead (those packages version independently from web/mobile/common). + +--- + +## Step 3 — Consistency across export surfaces + +- Use the **same** `@deprecated` guidance and **`@deprecationExpectedRemoval v`** value everywhere the symbol is exported (adjust wording only if a platform’s API genuinely differs). +- **Components** and **hooks** that exist as separate web and mobile implementations: deprecate **both** when both packages export the symbol. +- **Shared** symbols in `packages/common` that are **also** re-exported from web or mobile: follow Step 0 — ensure deprecation is visible on **every** public import path (common barrels **and** web/mobile re-exports if applicable). +- **Visualization** packages: same rules whenever those packages export the symbol. + +--- + +## Step 4 — Docsite metadata (`apps/docs/docs`) + +Only when the symbol has **existing** docs under the docs app. **Do not** add new doc folders unless the docs workflow already expects them. + +### Components (`apps/docs/docs/components/`) + +1. Locate the folder, e.g. `apps/docs/docs/components///`. +2. If present, edit **`webMetadata.json`** and/or **`mobileMetadata.json`** (some components have both; some only one). +3. Add or update the top-level **`warning`** string: + +```json +"warning": "This component is deprecated. Please use {replacement} instead." +``` + +Examples: + +- `"Please use Tabs instead."` +- `"Please use MediaCard instead."` + +Match the tone of existing deprecations when the replacement is not a single component name (e.g. “Use indeterminate ProgressCircle for loading indicators instead.”) — still keep the opening: **This component is deprecated.** + +### Hooks (`apps/docs/docs/hooks/`) + +1. Locate the hook folder, e.g. `apps/docs/docs/hooks//`. +2. Hooks may use **`webMetadata.json`** and **`mobileMetadata.json`**, or a single shared **`metadata.json`** — update whichever file(s) exist for that hook. +3. Add or update the top-level **`warning`** string using **hook** wording: + +```json +"warning": "This hook is deprecated. Please use {replacement} instead." +``` + +Use the same `{replacement}` phrasing as in JSDoc. If the replacement is not a single hook name, adapt the sentence but keep the opening: **This hook is deprecated.** + +--- + +## Step 5 — Verification checklist + +- [ ] Every **public export path** across packages that expose the symbol has been found (Step 0) and carries deprecation (implementation and re-exports as needed). +- [ ] `@deprecated` includes replacement guidance and the exact closing sentence about future major removal. +- [ ] `@deprecationExpectedRemoval v` reflects **next major** from current version (any of web/mobile/common `package.json` for core CDS; visualization packages use their own `package.json`). +- [ ] **Web + mobile** implementations and metadata (when applicable) are updated; nothing skipped because the symbol was “only” defined in common or another package. +- [ ] `warning` in metadata matches the replacement story: **this component is deprecated** for component docs, **this hook is deprecated** for hook docs (`apps/docs/docs/hooks/`). + +--- + +## Reference examples in-repo + +- JSDoc: search for `@deprecationExpectedRemoval` under `packages/web/src` (e.g. `TabNavigation.tsx`, `Spinner.tsx`). +- Metadata: search for `"warning": "This component is deprecated` under `apps/docs/docs/components`; hook docs live under `apps/docs/docs/hooks/` (use **This hook is deprecated** for hook `warning` text). diff --git a/packages/common/src/types/CardHeaderProps.ts b/packages/common/src/types/CardHeaderProps.ts index 924564b48b..6d8540f7bc 100644 --- a/packages/common/src/types/CardHeaderProps.ts +++ b/packages/common/src/types/CardHeaderProps.ts @@ -1,5 +1,9 @@ import type { SharedProps } from './SharedProps'; +/** + * @deprecated Use ContentCardHeaderProps instead. This will be removed in a future major release. + * @deprecationExpectedRemoval v9 + */ export type CardHeaderProps = { /** Absolute or Relative path to Avatar */ avatar?: string; diff --git a/packages/common/src/types/CardMediaProps.ts b/packages/common/src/types/CardMediaProps.ts index aec5461eb1..db33441c3b 100644 --- a/packages/common/src/types/CardMediaProps.ts +++ b/packages/common/src/types/CardMediaProps.ts @@ -15,6 +15,10 @@ export type CardMediaImageSizeObject = aspectRatio: AspectRatio; }; +/** + * @deprecated Use SpotSquare when `type` is "spotSquare", Pictogram when `type` is "pictogram", or RemoteImage when `type` is "image". This will be removed in a future major release. + * @deprecationExpectedRemoval v9 + */ export type CardMediaProps = { /** Informs how to auto-magically size the media. */ placement: CardMediaPlacement; diff --git a/packages/mobile/src/cards/Card.tsx b/packages/mobile/src/cards/Card.tsx index 96678f0013..4f7ae2b49a 100644 --- a/packages/mobile/src/cards/Card.tsx +++ b/packages/mobile/src/cards/Card.tsx @@ -58,6 +58,10 @@ const getBorderRadiusPinStyle = (borderRadius: number) => ({ all: {}, }); +/** + * @deprecated Use ContentCard instead. This will be removed in a future major release. + * @deprecationExpectedRemoval v9 + */ export const Card = memo(function OldCard({ children, background = 'bg', diff --git a/packages/mobile/src/cards/CardBody.tsx b/packages/mobile/src/cards/CardBody.tsx index 13748f95ca..c6f8006640 100644 --- a/packages/mobile/src/cards/CardBody.tsx +++ b/packages/mobile/src/cards/CardBody.tsx @@ -92,6 +92,10 @@ const CardBodyAction = memo(function CardBodyAction({ ); }); +/** + * @deprecated Use ContentCardBody instead. This will be removed in a future major release. + * @deprecationExpectedRemoval v9 + */ export const CardBody = memo(function CardBody({ testID = 'card-body', title, diff --git a/packages/mobile/src/cards/CardFooter.tsx b/packages/mobile/src/cards/CardFooter.tsx index c55ec5518c..d6360baf41 100644 --- a/packages/mobile/src/cards/CardFooter.tsx +++ b/packages/mobile/src/cards/CardFooter.tsx @@ -16,6 +16,10 @@ export type CardFooterBaseProps = Pick< export type CardFooterProps = CardFooterBaseProps & Omit; +/** + * @deprecated Use ContentCardFooter instead. This will be removed in a future major release. + * @deprecationExpectedRemoval v9 + */ export const CardFooter = memo(function CardFooter({ children, paddingBottom = 2, diff --git a/packages/mobile/src/cards/CardHeader.tsx b/packages/mobile/src/cards/CardHeader.tsx index 0c868ed308..2481370eee 100644 --- a/packages/mobile/src/cards/CardHeader.tsx +++ b/packages/mobile/src/cards/CardHeader.tsx @@ -5,8 +5,16 @@ import { HStack } from '../layout/HStack'; import { RemoteImage } from '../media/RemoteImage'; import { Text } from '../typography/Text'; +/** + * @deprecated Use ContentCardHeaderProps instead. This will be removed in a future major release. + * @deprecationExpectedRemoval v9 + */ export type CardHeaderProps = CardHeaderBaseProps; +/** + * @deprecated Use ContentCardHeader instead. This will be removed in a future major release. + * @deprecationExpectedRemoval v9 + */ export const CardHeader = memo( ({ avatar, metaData, description, action, testID }: CardHeaderProps) => { return ( diff --git a/packages/mobile/src/cards/CardMedia.tsx b/packages/mobile/src/cards/CardMedia.tsx index f7bb277370..5d3952558f 100644 --- a/packages/mobile/src/cards/CardMedia.tsx +++ b/packages/mobile/src/cards/CardMedia.tsx @@ -13,6 +13,10 @@ import type { import { Pictogram, SpotSquare } from '../illustrations'; import { getSource, RemoteImage } from '../media/RemoteImage'; +/** + * @deprecated Use SpotSquare when `type` is "spotSquare", Pictogram when `type` is "pictogram", or RemoteImage when `type` is "image". This will be removed in a future major release. + * @deprecationExpectedRemoval v9 + */ export type CardMediaProps = CommonCardMediaProps; const imageProps: Record = { @@ -27,6 +31,10 @@ const imageProps: Record = { end: defaultMediaSize, }; +/** + * @deprecated Use SpotSquare when `type` is "spotSquare", Pictogram when `type` is "pictogram", or RemoteImage when `type` is "image". This will be removed in a future major release. + * @deprecationExpectedRemoval v9 + */ export const CardMedia = memo(function CardMedia({ placement = 'end', ...props }: CardMediaProps) { switch (props.type) { case 'spotSquare': diff --git a/packages/web/src/cards/Card.tsx b/packages/web/src/cards/Card.tsx index d26005bddc..20f289b0ea 100644 --- a/packages/web/src/cards/Card.tsx +++ b/packages/web/src/cards/Card.tsx @@ -20,6 +20,10 @@ export type CardBaseProps = Pick & export type CardProps = CardBaseProps & Omit, 'onClick' | 'onKeyDown' | 'onKeyUp' | 'background'>; +/** + * @deprecated Use ContentCard instead. This will be removed in a future major release. + * @deprecationExpectedRemoval v9 + */ export const Card = memo(function Card({ children, background = 'bg', diff --git a/packages/web/src/cards/CardBody.tsx b/packages/web/src/cards/CardBody.tsx index 56683db4fd..c663daa467 100644 --- a/packages/web/src/cards/CardBody.tsx +++ b/packages/web/src/cards/CardBody.tsx @@ -62,6 +62,9 @@ export type CardBodyProps = CardBodyBaseProps & Omit /** * Provides an opinionated layout for the typical content of a Card: a title, description, media, and action + * + * @deprecated Use ContentCardBody instead. This will be removed in a future major release. + * @deprecationExpectedRemoval v9 */ export const CardBody = memo(function CardBody({ testID = 'card-body', diff --git a/packages/web/src/cards/CardFooter.tsx b/packages/web/src/cards/CardFooter.tsx index 4740515388..6b81e42b5c 100644 --- a/packages/web/src/cards/CardFooter.tsx +++ b/packages/web/src/cards/CardFooter.tsx @@ -13,6 +13,10 @@ export type CardFooterBaseProps = Pick & export type CardFooterProps = CardFooterBaseProps & Omit, 'children'>; +/** + * @deprecated Use ContentCardFooter instead. This will be removed in a future major release. + * @deprecationExpectedRemoval v9 + */ export const CardFooter: React.FC> = memo( function CardFooter({ children, paddingBottom = 2, paddingX = gutter, testID, ...otherProps }) { return ( diff --git a/packages/web/src/cards/CardHeader.tsx b/packages/web/src/cards/CardHeader.tsx index b575bd0881..6227b559e5 100644 --- a/packages/web/src/cards/CardHeader.tsx +++ b/packages/web/src/cards/CardHeader.tsx @@ -7,6 +7,10 @@ import { VStack } from '../layout/VStack'; import { Avatar } from '../media/Avatar'; import { Text } from '../typography/Text'; +/** + * @deprecated Use ContentCardHeader instead. This will be removed in a future major release. + * @deprecationExpectedRemoval v9 + */ export const CardHeader = memo(function CardHeader({ avatar, metaData, diff --git a/packages/web/src/cards/CardMedia.tsx b/packages/web/src/cards/CardMedia.tsx index 42b70225e8..71984dd12d 100644 --- a/packages/web/src/cards/CardMedia.tsx +++ b/packages/web/src/cards/CardMedia.tsx @@ -26,6 +26,10 @@ const imageProps: Record = { end: defaultMediaSize, }; +/** + * @deprecated Use SpotSquare when `type` is "spotSquare", Pictogram when `type` is "pictogram", or RemoteImage when `type` is "image". This will be removed in a future major release. + * @deprecationExpectedRemoval v9 + */ export const CardMedia = memo(function CardMedia({ placement = 'end', ...props }: CardMediaProps) { if (props.type === 'spotSquare') { return ( From 4233cf00d8f4efbb1d48740d860cd4366815ef91 Mon Sep 17 00:00:00 2001 From: Adrien Zheng Date: Mon, 30 Mar 2026 14:59:44 -0400 Subject: [PATCH 2/3] update changelogs --- packages/common/CHANGELOG.md | 6 ++++++ packages/mobile/CHANGELOG.md | 4 ++++ packages/web/CHANGELOG.md | 4 ++++ 3 files changed, 14 insertions(+) diff --git a/packages/common/CHANGELOG.md b/packages/common/CHANGELOG.md index d5852f4788..7f08986c31 100644 --- a/packages/common/CHANGELOG.md +++ b/packages/common/CHANGELOG.md @@ -8,6 +8,12 @@ All notable changes to this project will be documented in this file. +## Unreleased + +#### 📘 Misc + +- Deprecate Card-related types. [[#562](https://github.com/coinbase/cds/pull/562)] + ## 8.60.0 (3/29/2026 PST) #### 🚀 Updates diff --git a/packages/mobile/CHANGELOG.md b/packages/mobile/CHANGELOG.md index dacd500bf1..cc21a04190 100644 --- a/packages/mobile/CHANGELOG.md +++ b/packages/mobile/CHANGELOG.md @@ -12,6 +12,10 @@ All notable changes to this project will be documented in this file. #### 📘 Misc +- Deprecate Card and its sub-components. [[#562](https://github.com/coinbase/cds/pull/562)] + +#### 📘 Misc + - Chore: deprecate CardGroup. [[#560](https://github.com/coinbase/cds/pull/560)] ## 8.60.0 (3/29/2026 PST) diff --git a/packages/web/CHANGELOG.md b/packages/web/CHANGELOG.md index ab67ca2fec..68f6d8bb71 100644 --- a/packages/web/CHANGELOG.md +++ b/packages/web/CHANGELOG.md @@ -12,6 +12,10 @@ All notable changes to this project will be documented in this file. #### 📘 Misc +- Deprecate Card and its sub-components. [[#562](https://github.com/coinbase/cds/pull/562)] + +#### 📘 Misc + - Chore: deprecate CardGroup. [[#560](https://github.com/coinbase/cds/pull/560)] ## 8.60.0 (3/29/2026 PST) From 409234860d902ef82a32764b44fd76b00ec183b2 Mon Sep 17 00:00:00 2001 From: Adrien Zheng Date: Mon, 30 Mar 2026 15:15:11 -0400 Subject: [PATCH 3/3] tweaks --- .claude/skills/deprecate-cds-api/SKILL.md | 44 +++++++++++++++----- packages/common/src/types/CardHeaderProps.ts | 2 +- packages/common/src/types/CardMediaProps.ts | 2 +- packages/mobile/src/cards/Card.tsx | 2 +- packages/mobile/src/cards/CardBody.tsx | 2 +- packages/mobile/src/cards/CardFooter.tsx | 2 +- packages/mobile/src/cards/CardHeader.tsx | 4 +- packages/mobile/src/cards/CardMedia.tsx | 4 +- packages/web/src/cards/Card.tsx | 2 +- packages/web/src/cards/CardBody.tsx | 2 +- packages/web/src/cards/CardFooter.tsx | 2 +- packages/web/src/cards/CardHeader.tsx | 2 +- packages/web/src/cards/CardMedia.tsx | 2 +- 13 files changed, 47 insertions(+), 25 deletions(-) diff --git a/.claude/skills/deprecate-cds-api/SKILL.md b/.claude/skills/deprecate-cds-api/SKILL.md index dcf78e24c4..8dbc95f9f6 100644 --- a/.claude/skills/deprecate-cds-api/SKILL.md +++ b/.claude/skills/deprecate-cds-api/SKILL.md @@ -6,9 +6,10 @@ description: | the original package. Use whenever the user asks to deprecate a CDS component or API, mark something as deprecated, add @deprecated / @deprecationExpectedRemoval, or update deprecation warnings in apps/docs metadata under components or hooks (webMetadata.json / mobileMetadata.json / metadata.json). - Also use when replacing a component or hook and sunsetting the old one. -allowed-tools: Read, Grep, Glob, StrReplace -argument-hint: ' — replacement (e.g. Tabs) — [optional notes]' + Also use when replacing a component or hook and sunsetting the old one. Always finish by running + `yarn nx run :lint` on modified packages so `internal/deprecated-jsdoc-has-removal-version` passes. +allowed-tools: Read, Grep, Glob, StrReplace, Bash(yarn nx run:*) +argument-hint: ' — replacement — [@deprecationExpectedRemoval major e.g. v10] — [optional notes]' --- # Deprecate CDS public API @@ -19,6 +20,7 @@ Automate the standard CDS deprecation workflow for symbols exported from `packag 1. **What is being deprecated?** Component name, hook, prop, or other exported symbol. 2. **What should consumers use instead?** The replacement must be named in JSDoc and in docs `warning` text. +3. **Which major should `@deprecationExpectedRemoval` use?** (e.g. `v9`, `v10`.) **Ask the user to confirm** if they have not already stated it. If they want a default, **suggest** the next major from the relevant `package.json` (see Step 2) and confirm they accept it before editing. --- @@ -54,19 +56,23 @@ Use the **standard JSDoc tag `@deprecated`** (not `@deprecate`). Rules: - The `@deprecated` line must end with exactly: `This will be removed in a future major release.` (same sentence as the rest of the deprecation message, as in existing CDS examples). -- `@deprecationExpectedRemoval` must be a single token like `v9` (lowercase `v` + major number only, no minor/patch). +- `@deprecationExpectedRemoval` must match `v` + version (e.g. `v9` or `v9.0.0`; full semver is allowed by ESLint). + +The repo’s ESLint rule **`internal/deprecated-jsdoc-has-removal-version`** (`libs/eslint-plugin-internal`) enforces the prose ending and the presence of `@deprecationExpectedRemoval`; **lint must pass** after edits (see **Step 6**). --- -## Step 2 — Next major version for `@deprecationExpectedRemoval` +## Step 2 — Removal version for `@deprecationExpectedRemoval` -**`packages/web`, `packages/mobile`, and `packages/common` always share the same semver.** Read the **`version`** field from any one of `packages/web/package.json`, `packages/mobile/package.json`, or `packages/common/package.json` — they match. +The tag must satisfy `@deprecationExpectedRemoval v…` as enforced by ESLint (e.g. `v10` or `v10.0.0`). -1. Take **`version`** (e.g. `8.60.0`). -2. Let **current major** be the first segment (`8` in `8.60.0`). -3. Set **`NEXT_MAJOR = current major + 1`** and use `@deprecationExpectedRemoval v` (e.g. current `8.x` → `v9`). +1. **Confirm with the user** which major **`N`** to use, unless they already specified it in **Inputs** (e.g. “remove in v10” → use `v10`). +2. **Default suggestion** when the user wants a recommendation: read the **`version`** field from the relevant `package.json` and set **`N = current major + 1`**. + - **`packages/web`**, **`packages/mobile`**, and **`packages/common`** always share the same semver — read **`version`** from any one of them (e.g. `8.60.0` → suggest **`v9`**). + - Symbols owned only by **`packages/web-visualization`** or **`packages/mobile-visualization`**: read **that** package’s `package.json` (those versions are independent from web/mobile/common). +3. After agreeing on **`N`**, use **`@deprecationExpectedRemoval v`** everywhere for this deprecation (same **Step 3**). -For symbols owned only by **`packages/web-visualization`** or **`packages/mobile-visualization`**, read that package’s `package.json` instead (those packages version independently from web/mobile/common). +Do **not** assume the default without checking—either the user names **`N`**, or they accept the suggested next-major after you show the current **`version`**. --- @@ -118,13 +124,29 @@ Use the same `{replacement}` phrasing as in JSDoc. If the replacement is not a s - [ ] Every **public export path** across packages that expose the symbol has been found (Step 0) and carries deprecation (implementation and re-exports as needed). - [ ] `@deprecated` includes replacement guidance and the exact closing sentence about future major removal. -- [ ] `@deprecationExpectedRemoval v` reflects **next major** from current version (any of web/mobile/common `package.json` for core CDS; visualization packages use their own `package.json`). +- [ ] **`@deprecationExpectedRemoval v`** matches the **confirmed** removal major (Step 2), not an unverified default. - [ ] **Web + mobile** implementations and metadata (when applicable) are updated; nothing skipped because the symbol was “only” defined in common or another package. - [ ] `warning` in metadata matches the replacement story: **this component is deprecated** for component docs, **this hook is deprecated** for hook docs (`apps/docs/docs/hooks/`). +- [ ] **`yarn nx run :lint`** has been run for every touched project (**Step 6**) and passes. + +--- + +## Step 6 — Run ESLint (required) + +After all edits, **run the `lint` target** on **every Nx project** that contains changed source files so **`internal/deprecated-jsdoc-has-removal-version`** (and the rest of the package lint config) passes. + +Use the workspace convention: + +```bash +yarn nx run :lint +``` + +Examples: `web`, `mobile`, `common`, `web-visualization`, `mobile-visualization` — run **each** project you touched. Fix any reported issues before finishing (most often: missing `@deprecationExpectedRemoval`, or `@deprecated` text not ending with the standard sentence). --- ## Reference examples in-repo - JSDoc: search for `@deprecationExpectedRemoval` under `packages/web/src` (e.g. `TabNavigation.tsx`, `Spinner.tsx`). +- ESLint: `libs/eslint-plugin-internal` — rule **`deprecated-jsdoc-has-removal-version`** (exposed as **`internal/deprecated-jsdoc-has-removal-version`** in the root `eslint.config.mjs`). - Metadata: search for `"warning": "This component is deprecated` under `apps/docs/docs/components`; hook docs live under `apps/docs/docs/hooks/` (use **This hook is deprecated** for hook `warning` text). diff --git a/packages/common/src/types/CardHeaderProps.ts b/packages/common/src/types/CardHeaderProps.ts index 6d8540f7bc..892be22370 100644 --- a/packages/common/src/types/CardHeaderProps.ts +++ b/packages/common/src/types/CardHeaderProps.ts @@ -2,7 +2,7 @@ import type { SharedProps } from './SharedProps'; /** * @deprecated Use ContentCardHeaderProps instead. This will be removed in a future major release. - * @deprecationExpectedRemoval v9 + * @deprecationExpectedRemoval v10 */ export type CardHeaderProps = { /** Absolute or Relative path to Avatar */ diff --git a/packages/common/src/types/CardMediaProps.ts b/packages/common/src/types/CardMediaProps.ts index db33441c3b..2352881153 100644 --- a/packages/common/src/types/CardMediaProps.ts +++ b/packages/common/src/types/CardMediaProps.ts @@ -17,7 +17,7 @@ export type CardMediaImageSizeObject = /** * @deprecated Use SpotSquare when `type` is "spotSquare", Pictogram when `type` is "pictogram", or RemoteImage when `type` is "image". This will be removed in a future major release. - * @deprecationExpectedRemoval v9 + * @deprecationExpectedRemoval v10 */ export type CardMediaProps = { /** Informs how to auto-magically size the media. */ diff --git a/packages/mobile/src/cards/Card.tsx b/packages/mobile/src/cards/Card.tsx index 4f7ae2b49a..a3acd00297 100644 --- a/packages/mobile/src/cards/Card.tsx +++ b/packages/mobile/src/cards/Card.tsx @@ -60,7 +60,7 @@ const getBorderRadiusPinStyle = (borderRadius: number) => ({ /** * @deprecated Use ContentCard instead. This will be removed in a future major release. - * @deprecationExpectedRemoval v9 + * @deprecationExpectedRemoval v10 */ export const Card = memo(function OldCard({ children, diff --git a/packages/mobile/src/cards/CardBody.tsx b/packages/mobile/src/cards/CardBody.tsx index c6f8006640..c42de534c0 100644 --- a/packages/mobile/src/cards/CardBody.tsx +++ b/packages/mobile/src/cards/CardBody.tsx @@ -94,7 +94,7 @@ const CardBodyAction = memo(function CardBodyAction({ /** * @deprecated Use ContentCardBody instead. This will be removed in a future major release. - * @deprecationExpectedRemoval v9 + * @deprecationExpectedRemoval v10 */ export const CardBody = memo(function CardBody({ testID = 'card-body', diff --git a/packages/mobile/src/cards/CardFooter.tsx b/packages/mobile/src/cards/CardFooter.tsx index d6360baf41..d122674aaf 100644 --- a/packages/mobile/src/cards/CardFooter.tsx +++ b/packages/mobile/src/cards/CardFooter.tsx @@ -18,7 +18,7 @@ export type CardFooterProps = CardFooterBaseProps & Omit; /** * @deprecated Use ContentCardFooter instead. This will be removed in a future major release. - * @deprecationExpectedRemoval v9 + * @deprecationExpectedRemoval v10 */ export const CardFooter = memo(function CardFooter({ children, diff --git a/packages/mobile/src/cards/CardHeader.tsx b/packages/mobile/src/cards/CardHeader.tsx index 2481370eee..e0259c5cdf 100644 --- a/packages/mobile/src/cards/CardHeader.tsx +++ b/packages/mobile/src/cards/CardHeader.tsx @@ -7,13 +7,13 @@ import { Text } from '../typography/Text'; /** * @deprecated Use ContentCardHeaderProps instead. This will be removed in a future major release. - * @deprecationExpectedRemoval v9 + * @deprecationExpectedRemoval v10 */ export type CardHeaderProps = CardHeaderBaseProps; /** * @deprecated Use ContentCardHeader instead. This will be removed in a future major release. - * @deprecationExpectedRemoval v9 + * @deprecationExpectedRemoval v10 */ export const CardHeader = memo( ({ avatar, metaData, description, action, testID }: CardHeaderProps) => { diff --git a/packages/mobile/src/cards/CardMedia.tsx b/packages/mobile/src/cards/CardMedia.tsx index 5d3952558f..ab726cec0a 100644 --- a/packages/mobile/src/cards/CardMedia.tsx +++ b/packages/mobile/src/cards/CardMedia.tsx @@ -15,7 +15,7 @@ import { getSource, RemoteImage } from '../media/RemoteImage'; /** * @deprecated Use SpotSquare when `type` is "spotSquare", Pictogram when `type` is "pictogram", or RemoteImage when `type` is "image". This will be removed in a future major release. - * @deprecationExpectedRemoval v9 + * @deprecationExpectedRemoval v10 */ export type CardMediaProps = CommonCardMediaProps; @@ -33,7 +33,7 @@ const imageProps: Record = { /** * @deprecated Use SpotSquare when `type` is "spotSquare", Pictogram when `type` is "pictogram", or RemoteImage when `type` is "image". This will be removed in a future major release. - * @deprecationExpectedRemoval v9 + * @deprecationExpectedRemoval v10 */ export const CardMedia = memo(function CardMedia({ placement = 'end', ...props }: CardMediaProps) { switch (props.type) { diff --git a/packages/web/src/cards/Card.tsx b/packages/web/src/cards/Card.tsx index 20f289b0ea..43f676b497 100644 --- a/packages/web/src/cards/Card.tsx +++ b/packages/web/src/cards/Card.tsx @@ -22,7 +22,7 @@ export type CardProps = CardBaseProps & /** * @deprecated Use ContentCard instead. This will be removed in a future major release. - * @deprecationExpectedRemoval v9 + * @deprecationExpectedRemoval v10 */ export const Card = memo(function Card({ children, diff --git a/packages/web/src/cards/CardBody.tsx b/packages/web/src/cards/CardBody.tsx index c663daa467..74b7702346 100644 --- a/packages/web/src/cards/CardBody.tsx +++ b/packages/web/src/cards/CardBody.tsx @@ -64,7 +64,7 @@ export type CardBodyProps = CardBodyBaseProps & Omit * Provides an opinionated layout for the typical content of a Card: a title, description, media, and action * * @deprecated Use ContentCardBody instead. This will be removed in a future major release. - * @deprecationExpectedRemoval v9 + * @deprecationExpectedRemoval v10 */ export const CardBody = memo(function CardBody({ testID = 'card-body', diff --git a/packages/web/src/cards/CardFooter.tsx b/packages/web/src/cards/CardFooter.tsx index 6b81e42b5c..5f5dfcb1d2 100644 --- a/packages/web/src/cards/CardFooter.tsx +++ b/packages/web/src/cards/CardFooter.tsx @@ -15,7 +15,7 @@ export type CardFooterProps = CardFooterBaseProps & Omit> = memo( function CardFooter({ children, paddingBottom = 2, paddingX = gutter, testID, ...otherProps }) { diff --git a/packages/web/src/cards/CardHeader.tsx b/packages/web/src/cards/CardHeader.tsx index 6227b559e5..cc227015ce 100644 --- a/packages/web/src/cards/CardHeader.tsx +++ b/packages/web/src/cards/CardHeader.tsx @@ -9,7 +9,7 @@ import { Text } from '../typography/Text'; /** * @deprecated Use ContentCardHeader instead. This will be removed in a future major release. - * @deprecationExpectedRemoval v9 + * @deprecationExpectedRemoval v10 */ export const CardHeader = memo(function CardHeader({ avatar, diff --git a/packages/web/src/cards/CardMedia.tsx b/packages/web/src/cards/CardMedia.tsx index 71984dd12d..e661c491ed 100644 --- a/packages/web/src/cards/CardMedia.tsx +++ b/packages/web/src/cards/CardMedia.tsx @@ -28,7 +28,7 @@ const imageProps: Record = { /** * @deprecated Use SpotSquare when `type` is "spotSquare", Pictogram when `type` is "pictogram", or RemoteImage when `type` is "image". This will be removed in a future major release. - * @deprecationExpectedRemoval v9 + * @deprecationExpectedRemoval v10 */ export const CardMedia = memo(function CardMedia({ placement = 'end', ...props }: CardMediaProps) { if (props.type === 'spotSquare') {