Text size short-hand rename codemod

Migrates the short-hand size props on Pluma typography components (Text, Heading, Paragraph) for the v3 token rename. The single-letter size short-hands are expanded to two letters, and the product-ps text style is renamed:

table
BeforeAfter
size="s"size="sm"
size="m"size="md"
size="l"size="lg"
text="product-ps"text="product-psm"
text="product-ps-active"text="product-psm-active"

Extended sizes (xs, xl, xxs, xxl, xxxl) and other text styles (product-pxs, product-p, …) are not changed — they aren't short-hands and their names are unaffected by the rename.

There are two transforms — one for React (.tsx/.ts/.jsx/.js) and one for Ember (.gts/.gjs/.hbs). Run whichever apply to your app.

Running it

Run it through the Pluma CLI from inside your consuming app. Always start with a dry run to review the diff and warning summary before applying:

# from the root of your consuming app

# Dry run first (no writes; per-file diff printed inline)
pnx @customerio/pluma-cli@latest upgrade --codemod text-size-shorthand-rename react --dry ./src
pnx @customerio/pluma-cli@latest upgrade --codemod text-size-shorthand-rename ember --dry ./app

# Then apply for real
pnx @customerio/pluma-cli@latest upgrade --codemod text-size-shorthand-rename react ./src
pnx @customerio/pluma-cli@latest upgrade --codemod text-size-shorthand-rename ember ./app ./addon

Both frameworks accept --dry / -d. The React path also forwards standard jscodeshift flags, so -p prints transformed output.

What gets matched

React. Only JSX elements whose tag resolves (via the import in the same file) to Text, Heading, or Paragraph from @customerio/pluma-components/react (or the bare @customerio/pluma-components entry). Aliased imports (import { Text as T } from …) are handled. A local component named Text that wasn't imported from Pluma is left alone.

Inline string literals are always rewritten (size="s", size={'s'}, size={'s' as const}). The codemod also follows result-position expressions — branches of a ?:, the right-hand side of ?? / || / &&:

<Text size={condensed ? 's' : 'm'} />
<Text size={override ?? 's'} />

Each short-hand literal in a value position is rewritten under the fixed map; non-literal branches (identifiers, calls, member access) are left alone and reported as warnings.

Ember. Only <PlumaText …>, <PlumaHeading …>, and <PlumaParagraph …> element nodes are touched. Inline literals — @size="s", @size={{"s"}} — are always rewritten, along with result-position literals inside the if / unless / or / and helpers (@size={{if cond 's' 'm'}}).

Warnings — values that need manual review

Both transforms print a summary at the end listing every size / text value they recognized but couldn't resolve to a literal — dynamic expressions, identifiers/consts, class members ({{this.x}}), component arguments ({{@arg}}), and unknown helper calls. Unlike the button-variant-rename codemod, this one does not rewrite indirect bindings automatically; it reports them so you can rename them by hand where they hold a short-hand value.

After running, you can also grep for any leftover size="s", size="m", size="l", or "product-ps" to catch anything the warnings might have missed.

Working on the codemod itself

There's a test suite under tests/ covering the React and Ember transforms. It ships as part of @customerio/pluma-cli. After pnpm install at the repo root:

pnpm --filter @customerio/pluma-cli run test:transforms

It uses Node's built-in test runner (node --test).