Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
5 changes: 5 additions & 0 deletions .changeset/cold-lions-listen.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
---
'@primer/react': minor
---

Deprecate the `useResponsiveValue` hook.
59 changes: 59 additions & 0 deletions .github/skills/deprecations/SKILL.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,59 @@
---
name: deprecations
description: 'Use when: deprecating Primer React components or hooks. Covers source annotations, docs metadata, changesets, docs page updates, and validation for deprecations.'
---

# Deprecating components and hooks in Primer React

Use this skill when a task involves marking a public Primer React API as deprecated.

## What to update

### Source code

- Add a JSDoc `@deprecated` annotation to the exported component, hook, prop, or type following existing patterns nearby.
- Keep runtime behavior unchanged unless the task explicitly requires more than deprecation signaling.

### Docs metadata

- For components, mark the relevant `*.docs.json` file with `"status": "deprecated"`.
- For hooks, mark the relevant `*.hookDocs.json` file with `"status": "deprecated"`.
- If schema or build tooling does not yet support the docs metadata you need, update the corresponding schema/build files in `packages/react/script/*-json/`.

### Documentation content

- If the deprecated component has a docs page or JSON-backed docs content that supports deprecation guidance, add or update the deprecation guidance and recommended alternative.
- Follow `contributor-docs/deprecating-components.md`.

### Versioning

- Add a changeset for public API deprecations.
- Use the versioning guidance in `contributor-docs/versioning.md` to choose the correct bump.

## Validation

Prefer targeted validation first, then broader validation if needed:

- Format changed files with `npx prettier --write <paths>`
- Lint changed TypeScript files with `npx eslint --fix <paths>`
- Rebuild generated docs metadata when related schema or docs JSON changes:

```bash
npm run build:hooks.json -w @primer/react
```

```bash
npm run build:components.json -w @primer/react
```

- Run targeted tests for the affected API when available
- Run broader repository validation before finalizing if the change touches shared build tooling

## Common files

- `packages/react/src/**/*.docs.json`
- `packages/react/src/**/*.hookDocs.json`
- `packages/react/script/components-json/*`
- `packages/react/script/hooks-json/*`
- `contributor-docs/deprecating-components.md`
- `.changeset/*.md`
3 changes: 2 additions & 1 deletion contributor-docs/deprecating-components.md
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,8 @@ When Primer maintainers are to deprecate a component, they will issue `@deprecat
Issuing a `@deprecated` notice in a minor/patch release includes:

- [ ] Adding a `@deprecated` annotation in the component's source code.
- [ ] Adding a `Deprecation` section to the documentation of the component with the link of the recommended component and provide a diff. See [deprecated ActionList docs](https://primer.style/react/deprecated/ActionList#deprecation) as an example.
- [ ] Marking the component or hook docs metadata as deprecated with `"status": "deprecated"` in the relevant `*.docs.json` or `*.hookDocs.json` file.
- [ ] If the component has a docs page, adding a `Deprecation` section to the documentation with the link of the recommended component and provide a diff. See [deprecated ActionList docs](https://primer.style/react/deprecated/ActionList#deprecation) as an example.
Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

this link does not exist?

Copy link
Copy Markdown
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

My bad, that link was already there. Replaced with a link for a recent deprecated component


## Developing a replacement component

Expand Down
1 change: 1 addition & 0 deletions packages/react/script/hooks-json/build.ts
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@ import Ajv from 'ajv'
// Only includes fields we use in this script
type Hook = {
name: string
status?: 'deprecated'
importPath: '@primer/react' | '@primer/react/experimental'
stories: Array<{id: string}>
}
Expand Down
5 changes: 5 additions & 0 deletions packages/react/script/hooks-json/hook.schema.json
Original file line number Diff line number Diff line change
Expand Up @@ -78,6 +78,11 @@
"type": "string",
"description": "The name of the hook."
},
"status": {
"type": "string",
"enum": ["ready", "deprecated"],
"description": "The status of the hook."
},
Comment on lines +81 to +85
Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

only valid value is deprecated? 🤔

Copy link
Copy Markdown
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yes... because there was no status field so far.

Made it ["ready", "deprecated"] so it doesn't look weird

"importPath": {
"type": "string",
"description": "The path to import the hook from. i.e. '@primer/react/experimental'"
Expand Down
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
{
"name": "useResponsiveValue",
"status": "deprecated",
"importPath": "@primer/react",
"stories": [],
"parameters": [
Expand Down
2 changes: 2 additions & 0 deletions packages/react/src/hooks/useResponsiveValue.ts
Original file line number Diff line number Diff line change
Expand Up @@ -41,6 +41,8 @@ export function isResponsiveValue(value: any): value is ResponsiveValue<any> {
* Resolves responsive values based on the current viewport width.
* For example, if the current viewport width is narrow (less than 768px), the value of `{regular: 'foo', narrow: 'bar'}` will resolve to `'bar'`.
*
* @deprecated Prefer responsive data attributes with `getResponsiveAttributes` and CSS media queries instead.
*
* @example
* const value = useResponsiveValue({regular: 'foo', narrow: 'bar'})
* console.log(value) // 'bar'
Expand Down
Loading