handle a call in the condition and a parenthesised branch

review pointed out two holes. a comma inside a call like isActive(foo, bar)
ended the match early, and a branch wrapped in parens put a ( between the
operator and the literal

a parenthesised group is now consumed as a unit so its commas stay inside it,
and parens are allowed right before the literal. a bare comma or brace still
ends the match so a neighbouring prop is still out of reach
This commit is contained in:
Huzaifa Iftikhar 2026-08-28 04:38:33 +05:00 • committed by HuzaifaChaudary
parent 64201c1f3a
commit dd31ae0cd6
2 changed files with 7 additions and 3 deletions

View file

@ -123,6 +123,9 @@ describe('is-safe-migration', async () => {
[`<Button variant={first ? "default" : "outline"} />`, 'outline'],
[`<Button variant={variant ?? "outline"} />`, 'outline'],
[`<Button variant={required ? 'secondary' : 'outline'} />`, 'outline'],
[`<Button variant={isActive(foo, bar) ? "outline" : "ghost"} />`, 'outline'],
[`<Button variant={cond ? ("outline") : "ghost"} />`, 'outline'],
[`<Button variant={cond ? "ghost" : ("outline")} />`, 'outline'],
])('does not replace classes in invalid positions #%#', async (example, candidate) => {
expect(
await migrateCandidate(designSystem, {}, candidate, {

View file

@ -18,9 +18,10 @@ const CONDITIONAL_TEMPLATE_SYNTAX = [
/wire:[^\s]*?$/,
// shadcn/ui variants, including a ternary or nullish branch between the prop
// and the literal. Braces and commas are excluded so the match cannot reach
// out of its own value into a neighbouring prop such as `className`.
/variant\s*[:=]\s*\{?(?:[^{},]*?(?:\?\?|\?|:)\s*)?['"`]$/,
// and the literal. A parenthesised group is consumed whole so a call in the
// condition keeps its own commas, while a bare comma or brace still ends the
// match so it cannot reach out into a neighbouring prop such as `className`.
/variant\s*[:=]\s*\{?(?:(?:[^{},()]|\([^()]*\))*?(?:\?\?|\?|:)\s*)?\(*\s*['"`]$/,
]
const NEXT_PLACEHOLDER_PROP = /placeholder=\{?['"`]$/
const VUE_3_EMIT = /\b\$?emit\(['"`]$/