docs(ui)/feat(tooling): Typography + Button mapping guides and typography codemod (Wave 1) - #30721
Conversation
Bakes in the approved Wave 1 decisions (LEVEL_SIZE_MAP, Button size scale, ghost -> color="tertiary", Tooltip/Space/Tag related decisions) now that the core Typography color prop and Button forwardRef have landed in main. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Drops the standalone codemod (developed ahead of the Wave 0 scaffold merge) into tooling/antd-codemods/, with the LEVEL_SIZE_MAP convention marked approved 2026-07-30. All 37 tests pass (10 move-named-imports + 27 typography). Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
❌ PR checklist incompleteThis PR cannot be merged until the following are addressed on its linked issue:
The fields live on the linked issue in the Shipping project (open the issue → right sidebar → Projects). After you set them, re-run this check (or push a commit) — issue/project changes do not re-trigger it automatically. Maintainers can bypass this check by adding the |
| if (!hasAlias) { | ||
| if (coreImports.size()) { | ||
| coreImports.at(0).get().node.specifiers.push( | ||
| j.importSpecifier(j.identifier('Typography'), j.identifier(CORE_LOCAL_ALIAS)) | ||
| ); | ||
| } else { | ||
| const decl = j.importDeclaration( | ||
| [j.importSpecifier(j.identifier('Typography'), j.identifier(CORE_LOCAL_ALIAS))], | ||
| j.literal(CORE_MODULE) | ||
| ); | ||
| j(typographyImportPath).insertAfter(decl); |
There was a problem hiding this comment.
Partial conversions always introduce the fixed CoreTypography local name, while this check only detects an existing core import with that alias. A file with another binding named CoreTypography will receive a duplicate binding or have converted elements resolve to the wrong identifier, so choose an unused local name before rewriting the elements and import.
| // `ellipsis={{ ... }}` keys with no core equivalent (show-more/less UX). | ||
| const ELLIPSIS_UNSUPPORTED_KEYS = ['expandable', 'symbol', 'onExpand']; |
There was a problem hiding this comment.
💡 Edge Case: ellipsis object: only 3 keys blocked, others silently dropped
convertElement only skips ellipsis objects containing expandable/symbol/onExpand (ELLIPSIS_UNSUPPORTED_KEYS). antd's ellipsis object also supports keys core Typography ignores — e.g. suffix, onEllipsis. An element like ellipsis={{ rows: 2, suffix: '…', onEllipsis: fn }} is converted and the whole object is passed through, so suffix/onEllipsis behavior is silently lost with no warning. Additionally, a spread property inside the ellipsis object (ellipsis={{ ...opts }}) has prop.key undefined, so the hasBadKey check skips it and an object that actually contains expandable could be converted. Consider treating any ellipsis-object key outside {rows, tooltip} (and any spread) as a skip reason.
Was this helpful? React with 👍 / 👎
| root.find(j.JSXElement).forEach((elPath) => { | ||
| const classification = classifyElement(elPath.node); | ||
| if (!classification) { | ||
| return; | ||
| } | ||
| if (classification.matchType === 'bare') { | ||
| bareUsageFound = true; | ||
| return; | ||
| } | ||
| const result = convertElement(elPath.node, classification.kind); | ||
| if (result.skip) { | ||
| skips.push({ file: filePath, kind: classification.kind, reason: result.reason }); | ||
| if (classification.matchType === 'destructured') { | ||
| recordDestructuredUsage(classification.localName, 'skipped'); | ||
| } |
There was a problem hiding this comment.
💡 Edge Case: Destructured names used outside JSX may break on removal
The transform only scans JSXElements to decide whether a destructured sub-component name (e.g. const { Text } = Typography;) is still needed. If that local name is also referenced in a non-JSX position (e.g. const C = Text; or passed to a HOC), destructuredUsage records no usage, the property is removed from the pattern (usage undefined → filtered when converted siblings exist), and the remaining reference becomes an undefined identifier. This is an uncommon pattern but would produce broken output silently; consider bailing out (or keeping the binding) when the local name appears in any non-JSX identifier reference.
Was this helpful? React with 👍 / 👎
Code Review 👍 Approved with suggestions 0 resolved / 2 findingsAdds typography and button migration guides along with a custom codemod for transitioning AntD typography components. Consider addressing the minor ellipsis object and destructured name limitations in the transform script. 💡 Edge Case: ellipsis object: only 3 keys blocked, others silently dropped📄 tooling/antd-codemods/transforms/antd-typography-to-core.js:46-47 📄 tooling/antd-codemods/transforms/antd-typography-to-core.js:193-206 convertElement only skips ellipsis objects containing expandable/symbol/onExpand (ELLIPSIS_UNSUPPORTED_KEYS). antd's ellipsis object also supports keys core Typography ignores — e.g. suffix, onEllipsis. An element like 💡 Edge Case: Destructured names used outside JSX may break on removal📄 tooling/antd-codemods/transforms/antd-typography-to-core.js:330-344 📄 tooling/antd-codemods/transforms/antd-typography-to-core.js:380-394 The transform only scans JSXElements to decide whether a destructured sub-component name (e.g. 🤖 Prompt for agentsOptionsDisplay: compact → Showing less information. Comment with these commands to change the behavior for this request:
Was this helpful? React with 👍 / 👎 | Gitar | Powered by Gitar — free for open source |
✅ Playwright Results — workflow succeededValidated commit ✅ 537 passed · ❌ 0 failed · 🟡 2 flaky · ⏭️ 3 skipped · 🧰 0 lifecycle flaky PerformanceBlocking targets: ✅ met · Optimization targets: 🟡 in progress Shard-job maxima below are not the full workflow wall time; the linked run includes build, fixture, planning, and reporting. 🕒 Full workflow signal wall (to summary) 47m 54s ⏱️ Max setup 2m 52s · max shard execution 15m 48s · max shard-job elapsed before upload 19m 36s · reporting 5s 🌐 202.87 requests/attempt · 2.85 app boots/UI scenario · 15.19% common-shard skew Optimization targets still in progress:
🟡 2 flaky test(s) (passed on retry)
How to debug locally# Download playwright-test-results-<shard> artifact and unzip
npx playwright show-trace path/to/trace.zip # view trace |
Summary
First Wave 1 artifacts for the AntD → ui-core-components migration (#30565, epic #30570), landing now that Wave 0 (#30560) and the core prerequisites (#30664 forwardRef, #30665 Typography color prop — both in main) are merged.
Commit 1 — mapping guides (
docs/antd-migration/typography.md,button.md): the review contracts for the first two sweeps, derived from a three-repo usage survey (~1,160 Typography tags, 1,370 Button instances). All previously-pending design decisions are baked in as approved (2026-07-30):Title level→size: 5→text-md, 4→text-lg, 3→text-xl, 2→display-xs, 1→display-smghost/type="ghost"→color="tertiary"per-site (no new core variant)type="secondary"→ corecolor="secondary"(prop landed in feat(ui-core): add semantic color prop to Typography #30665)Hand-finish punch lists (copyable/expandable/code/keyboard for Typography; Button.Group/ref/shape/border-overrides for Button) are enumerated with file:line.
Commit 2 — typography codemod (
tooling/antd-codemods/transforms/antd-typography-to-core.js): converts Typography.Text/Title/Paragraph/Link (incl. destructured + aliased forms and mocks), maps type→color / strong→weight / underline→className, passes ellipsis through (shapes are identical), and does safe partial conversion — elements with unsupported props stay on antd (aliasedCoreTypographyfor converted siblings) with warnings listing what needs hand-finishing. 27 inline tests; full codemod suite 37/37.Verification
yarn testintooling/antd-codemods: 2 suites, 37/37 green (10 existing + 27 new).colorprop, ButtonforwardRef).Fixes #30720
🤖 Generated with Claude Code
Greptile Summary
Adds Wave 1 Ant Design migration guidance and a Typography codemod.
Confidence Score: 4/5
The PR appears safe to merge, with one non-blocking codemod robustness issue around choosing a collision-free partial-conversion alias.
The documented mappings and covered transformations are coherent, but partial conversion can generate an invalid or incorrect binding when a target file already uses the hard-coded CoreTypography identifier.
Files Needing Attention: tooling/antd-codemods/transforms/antd-typography-to-core.js
Important Files Changed
Flowchart
%%{init: {'theme': 'neutral'}}%% flowchart TD A[Find antd Typography import] --> B[Classify member and destructured JSX] B --> C{Element mechanically supported?} C -->|Yes| D[Rewrite props and element to core Typography] C -->|No| E[Retain antd element and emit warning] D --> F{Any retained antd usage?} E --> F F -->|No| G[Replace or merge Typography import] F -->|Yes| H[Add aliased CoreTypography import]Reviews (1): Last reviewed commit: "feat(tooling): add antd-typography-to-co..." | Re-trigger Greptile