Skip to content

feat: kbd and hotkeys codemods - #3288

Merged
laurenashpole merged 9 commits into
v5-alphafrom
feat/hotkeys-codemod
Oct 30, 2026
Merged

laurenashpole merged 9 commits into
v5-alphafrom
feat/hotkeys-codemod

Conversation

@laurenashpole

@laurenashpole laurenashpole commented Oct 29, 2026 •

Copy link
Copy Markdown

Description

This PR adds codemods for KBD and Hotkeys. For KBD, it moves children to text (if the value is a string, otherwise it warns), removes size which doesn't currently do anything, and transforms the rest of the props to inline styles. For Hotkeys, we've deprecated everything but keys so it removes all those. I didn't try to transform them because they only really make sense if they can be passed into KBD. If a user wants different styling, they'll have to handle that on their own.

It also adds a new helper that can move children into a new attribute. It can either do all children content or can set stringOnly flag to only transform strings and warn about anything else. I swapped it out in Badge too since it seemed like it might be useful behavior there.

What to review

Make sure the codemods are behaving as described. For the new moveChildrenToAttribute function, I had the robot do most of that work since interacting with jscodeshift gets complicated otherwise.

Testing

I wrote tests for the new util and both codemods. I might also try this in Studio once it's published.


Note

Low Risk
Changes are limited to the ui-codemod package and migration tooling; runtime UI behavior is unaffected aside from automated codemod output on consumer codebases.

Overview
Adds latest CLI commands and jscodeshift transforms for KBD and Hotkeys, with new package exports and a patch changeset.

The KBD codemod rewrites imports, drops size, maps fontSize / padding / radius to inline style tokens, and moves static string children to text (non-string children get a UI-CODEMOD TODO). Styled KBD wrappers are handled via the same migration path.

The Hotkeys codemod rewrites imports and strips deprecated layout props (fontSize, padding, radius, gap, space) without trying to remap them to styles.

Shared tooling: new moveChildrenToAttribute helper (with getStaticStringFromChild and getAttributeValue AST support) powers children→**text** migration; the Badge transform now uses it with stringOnly: true, so plain string badge labels auto-migrate instead of only warning.

Reviewed by Cursor Bugbot for commit 8187790. Bugbot is set up for automated code reviews on this repo. Configure here.

@vercel

vercel Bot commented Oct 29, 2026 •

Copy link
Copy Markdown

The latest updates on your projects. Learn more about Vercel for GitHub.

4 Skipped Deployments
Project Deployment Actions Updated
sanity-ui-storybook Ignored Ignored Oct 30, 2026 4:16pm UTC
sanity-ui-workshop Ignored Ignored Oct 30, 2026 4:16pm UTC
ui-docs Ignored Ignored Oct 30, 2026 4:16pm UTC
ui-studio Ignored Ignored Oct 30, 2026 4:16pm UTC

Request Review

@laurenashpole
laurenashpole marked this pull request as ready for review October 29, 2026 14:16

@cursor cursor Bot left a comment •

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

Stale Bugbot comment from a previous run.

@changeset-bot

changeset-bot Bot commented Oct 29, 2026 •

Copy link
Copy Markdown

🦋 Changeset detected

Latest commit: 8187790

The changes in this PR will be included in the next version bump.

This PR includes changesets to release 1 package
Name Type
@sanity/ui-codemod Patch

Not sure what this means? Click here to learn what changesets are.

Click here if you're a maintainer who wants to add another changeset to this PR

@colepeters colepeters left a comment

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.

One very minor nit, and trusting that moveChildrenToAttribute functions as per the test, otherwise LGTM!

// UI-CODEMOD TODO: Move children into the text prop
<Badge><Text>{label}</Text></Badge>
`,
'warns on JSX element child onto the attribute',

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.

Think the description here might be missing a word?

@laurenashpole laurenashpole Oct 29, 2026 •

Copy link
Copy Markdown
Author

Choose a reason for hiding this comment

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

I think I made a copy and paste error here because it should say "warns on JSX element child when stringOnly is true". Updated that.

@colepeters colepeters left a comment

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.

LGTM!

@cursor cursor Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

Cursor Bugbot has reviewed your changes and found 1 potential issue.

Fix All in Cursor

❌ Bugbot Autofix is OFF. To automatically fix reported issues with cloud agents, enable autofix in the Cursor dashboard.

Want fixes drafted automatically? Bugbot Autofix can create code changes for findings. A team admin can enable Autofix in the Cursor dashboard.

Reviewed by Cursor Bugbot for commit 8187790. Configure here.

const element = parentNode
const children = ((element.children ?? []) as JSXElementChild[]).filter(
(child) => !(child.type === 'JSXText' && child.value.trim() === ''),
)

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

Whitespace dropped between moved children

Low Severity

moveChildrenToAttribute filters out every whitespace-only JSXText node before moving children. That is correct for indentation, but when stringOnly is false and several children are wrapped in a fragment, significant spaces between expressions are dropped, so {first} {last} becomes {first}{last}.

Additional Locations (1)
Fix in Cursor Fix in Web

Reviewed by Cursor Bugbot for commit 8187790. Configure here.

@laurenashpole
laurenashpole merged commit 5c24ffd into v5-alpha Oct 30, 2026
15 of 16 checks passed
@laurenashpole
laurenashpole deleted the feat/hotkeys-codemod branch October 30, 2026 16:43
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants