Skip to content

Commit

Permalink
feat: update migration script
Browse files Browse the repository at this point in the history
  • Loading branch information
shadcn committed Nov 4, 2024
1 parent bd02e24 commit 98ccd73
Show file tree
Hide file tree
Showing 3 changed files with 164 additions and 17 deletions.
158 changes: 158 additions & 0 deletions packages/shadcn/src/migrations/migrate-icons.test.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,158 @@
import { describe, expect, it } from "vitest"

import { migrateIconsFile } from "./migrate-icons"

describe("migrateIconsFile", () => {
it("should replace radix icons with lucide icons", async () => {
const input = `
import { CheckIcon, CloseIcon } from "@radix-ui/react-icons"
import { Something } from "other-package"
export function Component() {
return (
<div>
<CheckIcon className="w-4 h-4" />
<CloseIcon />
</div>
)
}`

expect(
await migrateIconsFile(input, "radix", "lucide", {
Check: {
lucide: "Check",
radix: "CheckIcon",
},
X: {
lucide: "X",
radix: "CloseIcon",
},
})
).toMatchInlineSnapshot(`
"import { Something } from "other-package"
import { Check, X } from "lucide-react";
export function Component() {
return (
<div>
<Check className="w-4 h-4" />
<X />
</div>
)
}"
`)
})

it("should return null if no radix icons are found", async () => {
const input = `
import { Something } from "other-package"
export function Component() {
return <div>No icons here</div>
}`

expect(await migrateIconsFile(input, "lucide", "radix", {}))
.toMatchInlineSnapshot(`
"import { Something } from "other-package"
export function Component() {
return <div>No icons here</div>
}"
`)
})

it("should handle mixed icon imports from different packages", async () => {
const input = `
import { CheckIcon } from "@radix-ui/react-icons"
import { AlertCircle } from "lucide-react"
import { Something } from "other-package"
import { Cross2Icon } from "@radix-ui/react-icons"
export function Component() {
return (
<div>
<CheckIcon className="w-4 h-4" />
<AlertCircle />
<Cross2Icon />
</div>
)
}`

expect(
await migrateIconsFile(input, "radix", "lucide", {
Check: {
lucide: "Check",
radix: "CheckIcon",
},
X: {
lucide: "X",
radix: "Cross2Icon",
},
})
).toMatchInlineSnapshot(`
"import { AlertCircle } from "lucide-react"
import { Something } from "other-package"
import { Check, X } from "lucide-react";
export function Component() {
return (
<div>
<Check className="w-4 h-4" />
<AlertCircle />
<X />
</div>
)
}"
`)
})

it("should preserve all props and children on icons", async () => {
const input = `
import { CheckIcon, Cross2Icon } from "@radix-ui/react-icons"
export function Component() {
return (
<div>
<CheckIcon
className="w-4 h-4"
onClick={handleClick}
data-testid="check-icon"
>
<span>Child content</span>
</CheckIcon>
<Cross2Icon style={{ color: 'red' }} aria-label="Close" />
</div>
)
}`

expect(
await migrateIconsFile(input, "radix", "lucide", {
Check: {
lucide: "Check",
radix: "CheckIcon",
},
X: {
lucide: "X",
radix: "Cross2Icon",
},
})
).toMatchInlineSnapshot(`
"import { Check, X } from "lucide-react";
export function Component() {
return (
<div>
<CheckIcon
className="w-4 h-4"
onClick={handleClick}
data-testid="check-icon"
>
<span>Child content</span>
</CheckIcon>
<X style={{ color: 'red' }} aria-label="Close" />
</div>
)
}"
`)
})
})
20 changes: 3 additions & 17 deletions packages/shadcn/src/migrations/migrate-icons.ts
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,6 @@ import { promises as fs } from "fs"
import { tmpdir } from "os"
import path from "path"
import { Config } from "@/src/utils/get-config"
import { getPackageInfo } from "@/src/utils/get-package-info"
import { highlighter } from "@/src/utils/highlighter"
import { logger } from "@/src/utils/logger"
import { getRegistryIcons } from "@/src/utils/registry"
Expand Down Expand Up @@ -39,35 +38,22 @@ export async function migrateIcons(config: Config) {
throw new Error("Something went wrong fetching the registry icons.")
}

const packageInfo = getPackageInfo(config.resolvedPaths.cwd)

const projectIconLibraries = packageInfo ? _getIconLibraries(packageInfo) : []

const libraryChoices = Object.entries(iconLibraries).map(
([name, packageName]) => ({
title: packageName,
value: name,
})
)

let initialSourceLibrary = projectIconLibraries.includes(
"@radix-ui/react-icons"
)
? libraryChoices.findIndex((choice) => choice.value === "radix")
: 0
let initialTargetLibrary = projectIconLibraries.includes("lucide-react")
? libraryChoices.findIndex((choice) => choice.value === "lucide")
: 0

const migrateOptions = await prompts([
{
type: "select",
name: "sourceLibrary",
message: `Which icon library would you like to ${highlighter.info(
"migrate from"
)}?`,
choices: libraryChoices,
initial: initialSourceLibrary,
choices: [...libraryChoices].reverse(),
initial: 0,
},
{
type: "select",
Expand All @@ -76,7 +62,7 @@ export async function migrateIcons(config: Config) {
"migrate to"
)}?`,
choices: libraryChoices,
initial: initialTargetLibrary,
initial: 0,
},
])

Expand Down
3 changes: 3 additions & 0 deletions vitest.workspace.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
import { defineWorkspace } from "vitest/config"

export default defineWorkspace(["./vitest.config.ts"])

0 comments on commit 98ccd73

Please sign in to comment.