do not migrate a variant literal behind a conditional
the shadcn variant guard only looked at the text right before the literal so any ternary or nullish branch between variant and the string defeated it and the upgrade rewrote a react prop value as if it were a class braces and commas stay excluded from the new part so the match cannot run past its own value into a neighbouring prop like className
This commit is contained in:
parent
f723e834ad
commit
64201c1f3a
2 changed files with 17 additions and 2 deletions
|
|
@ -119,6 +119,10 @@ describe('is-safe-migration', async () => {
|
|||
[`function Button({ variant='outline' }) {}`, 'outline'],
|
||||
[`Button({ variant: "outline" })`, 'outline'],
|
||||
[`Button({ variant: 'outline' })`, 'outline'],
|
||||
[`Button({ variant: isActive ? "outline" : "ghost" })`, 'outline'],
|
||||
[`<Button variant={first ? "default" : "outline"} />`, 'outline'],
|
||||
[`<Button variant={variant ?? "outline"} />`, 'outline'],
|
||||
[`<Button variant={required ? 'secondary' : 'outline'} />`, 'outline'],
|
||||
])('does not replace classes in invalid positions #%#', async (example, candidate) => {
|
||||
expect(
|
||||
await migrateCandidate(designSystem, {}, candidate, {
|
||||
|
|
@ -142,6 +146,15 @@ describe('is-safe-migration', async () => {
|
|||
|
||||
// Preact-style
|
||||
[`<div enterClass="shadow"></div>`, 'shadow', 'shadow-sm'],
|
||||
|
||||
// A conditional class is still a class, even next to a `variant` prop
|
||||
[`<div className={active ? "shadow" : "none"}></div>`, 'shadow', 'shadow-sm'],
|
||||
[`<Button variant="ghost" className={active ? "shadow" : "none"} />`, 'shadow', 'shadow-sm'],
|
||||
[
|
||||
`Button({ variant: a ? "ghost" : "x", className: b ? "shadow" : "y" })`,
|
||||
'shadow',
|
||||
'shadow-sm',
|
||||
],
|
||||
])('replaces classes in valid positions #%#', async (example, candidate, expected) => {
|
||||
expect(
|
||||
await migrateCandidate(designSystem, {}, candidate, {
|
||||
|
|
|
|||
|
|
@ -17,8 +17,10 @@ const CONDITIONAL_TEMPLATE_SYNTAX = [
|
|||
// Alpine
|
||||
/wire:[^\s]*?$/,
|
||||
|
||||
// shadcn/ui variants
|
||||
/variant\s*[:=]\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*)?['"`]$/,
|
||||
]
|
||||
const NEXT_PLACEHOLDER_PROP = /placeholder=\{?['"`]$/
|
||||
const VUE_3_EMIT = /\b\$?emit\(['"`]$/
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue