Skip to content

Commit

Permalink
chore(Popover): deprecate variant and customIcon props (#4941)
Browse files Browse the repository at this point in the history
* chore(Popover): deprecate variant and customIcon props

* fix(Popover): fix RTL styles

* feat(codemods): add codemod to remove Popover props variant and customIcon

* refactor(codemods): update readme and remove alias references
  • Loading branch information
HeartSquared authored Aug 21, 2024
1 parent 9961e87 commit df16927
Show file tree
Hide file tree
Showing 25 changed files with 252 additions and 224 deletions.
5 changes: 5 additions & 0 deletions .changeset/modern-mails-try.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
---
"@kaizen/components": patch
---

Deprecate `Popover` `variant` and `customIcon` props, and fix RTL styles.
25 changes: 15 additions & 10 deletions packages/components/codemods/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -8,24 +8,29 @@ Install `@kaizen/components`.
## CLI pattern

```
kaizen-codemod {DIR} {CODEMOD_NAME}
kaizen-codemod {DIR} {CODEMOD_NAME}
```

DIR - the directory to run the codemod for. Note that node_modules are excluded.
CODEMOD_NAME - the name of the codemod (refer to list below).

Example:
```
kaizen-codemod src migrateWellVariantToColor
kaizen-codemod src migrateWellVariantToColor
```

## Available codemods
- `migrateBrandMomentMoodToVariant`: Migrates `BrandMoment` component prop from `mood` to `variant`.
- `migrateEmptyStateIllustrationTypeToVariant`: Migrates `EmptyState` component prop from `illustrationType` to `variant`.
- `migrateGlobalNotificationTypeToVariant`: Transforms `GlobalNotification`'s `type` prop to the new `variant` prop.
- `migrateInlineNotificationTypeToVariant`: Transforms `InlineNotification`'s `type` prop to the new `variant` prop.
- `migrateInformationTileMoodToVariant`: Migrates `InformationTile` component prop from `mood` to `variant`.
- `migrateMultiActionTileMoodToVariant`: Migrates `MultiActionTile` component prop from `mood` to `variant`.
- `migrateBrandMomentMoodToVariant`: Migrates `BrandMoment` component prop from `mood` to `variant`
- `migrateCardVariantToColor`: Migrates `Card` component prop from `variant` to `color`
- `migrateConfirmationModalMoodsToVariant`: Migrates `ConfirmationModal` component prop from `mood` to `variant`
- `migrateEmptyStateIllustrationTypeToVariant`: Migrates `EmptyState` component prop from `illustrationType` to `variant`
- `migrateGlobalNotificationTypeToVariant`: Transforms `GlobalNotification`'s `type` prop to the new `variant` prop
- `migrateInformationTileMoodToVariant`: Migrates `InformationTile` component prop from `mood` to `variant`
- `migrateInlineNotificationTypeToVariant`: Transforms `InlineNotification`'s `type` prop to the new `variant` prop
- `migrateMultiActionTileMoodToVariant`: Migrates `MultiActionTile` component prop from `mood` to `variant`
- `migrateProgressBarMoodToColor`: Migrates `ProgressBar` component prop from `mood` to `color`
- `migrateToastNotificationTypeToVariant`: Transforms `ToastNotification`'s `type` prop to the new `variant` prop.
- `migrateWellVariantToColor`: Migrates `Well` component prop from `variant` to `color`.
- `migrateToastNotificationTypeToVariant`: Transforms `ToastNotification`'s `type` prop to the new `variant` prop
- `migrateWellVariantToColor`: Migrates `Well` component prop from `variant` to `color`
- `removeInputEditModalMood`: Removes `InputEditModal` component prop `mood`
- `removePopoverVariant`: Removes `Popover` component props `variant` and `customIcon`
- `updateGuidanceBlockVariantProp`: Updates `GuidanceBlock` import location and updates `variant` prop to `default` or `expert-advice`
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
import type { BrandMomentProps } from "~components/BrandMoment"
import type { BrandMomentProps } from "../../src/BrandMoment"
import { migrateStringProp } from "../utils"

const OLD_PROP_NAME = "mood"
Expand Down
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
import type { CardProps } from "~components/Card"
import type { CardProps } from "../../src/Card"
import { migrateStringProp } from "../utils"

const OLD_PROP_NAME = "variant"
Expand Down
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
import { transformComponentsInDir } from "../utils"
import { transformConfirmationModalMoodsToVariant } from "./transformConfirmationModalMoodsToVariant"
/** This is here as a script runner that migrates Well variant to their color equivalent */
const migrateModalMoodsToVariant = (): void => {

const run = (): void => {
// eslint-disable-next-line no-console
console.log(" ~(-_- ~) Running ConfirmationModal transformer (~ -_-)~")
const targetDir = process.argv[2]
Expand All @@ -16,4 +16,4 @@ const migrateModalMoodsToVariant = (): void => {
)
}

migrateModalMoodsToVariant()
run()
Original file line number Diff line number Diff line change
@@ -1,59 +1,28 @@
import ts from "typescript"
import { getPropValueText } from "../utils/getPropValueText"
import type { ConfirmationModalProps } from "../../src/Modal"
import { migrateStringProp } from "../utils"

/** Recurses through AST to find and update any jsx element that matched the tagName */
export const transformConfirmationModalMoodsToVariant =
(context: ts.TransformationContext, tagName: string) =>
(rootNode: ts.Node): ts.Node => {
function visit(node: ts.Node): ts.Node {
if (ts.isJsxOpeningElement(node) || ts.isJsxSelfClosingElement(node)) {
if (node.tagName.getText() === tagName) {
const newAttributes = node.attributes.properties.map(attr => {
if (ts.isJsxAttribute(attr) && attr.name.getText() === "mood") {
const valueName =
attr.initializer && getPropValueText(attr.initializer)
const OLD_PROP_NAME = "mood"
const NEW_PROP_NAME = "variant"

if (valueName) {
let variantValue: string = ""
switch (valueName) {
case "positive":
variantValue = "success"
break
case "negative":
variantValue = "warning"
break
case "assertive":
variantValue = "cautionary"
break
}
return ts.factory.createJsxAttribute(
ts.factory.createIdentifier("variant"),
ts.factory.createStringLiteral(variantValue)
)
}
}

return attr
})

if (ts.isJsxOpeningElement(node)) {
return ts.factory.updateJsxOpeningElement(
node,
node.tagName,
node.typeArguments,
ts.factory.createJsxAttributes(newAttributes)
)
} else if (ts.isJsxSelfClosingElement(node)) {
return ts.factory.updateJsxSelfClosingElement(
node,
node.tagName,
node.typeArguments,
ts.factory.createJsxAttributes(newAttributes)
)
}
}
}
return ts.visitEachChild(node, visit, context)
}
return ts.visitNode(rootNode, visit)
const getNewVariantValue = (
oldValue: Exclude<ConfirmationModalProps[typeof OLD_PROP_NAME], undefined>
): Exclude<ConfirmationModalProps[typeof NEW_PROP_NAME], undefined> => {
switch (oldValue) {
case "positive":
return "success"
case "informative":
return "informative"
case "negative":
return "warning"
case "cautionary":
return "cautionary"
case "assertive":
return "cautionary"
}
}

export const transformConfirmationModalMoodsToVariant = migrateStringProp(
OLD_PROP_NAME,
NEW_PROP_NAME,
getNewVariantValue
)
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
import type { EmptyStateProps } from "~components/EmptyState"
import type { EmptyStateProps } from "../../src/EmptyState"
import { migrateStringProp } from "../utils"

const OLD_PROP_NAME = "illustrationType"
Expand Down
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
import type { InformationTileProps } from "~components/Tile"
import type { InformationTileProps } from "../../src/Tile"
import { migrateStringProp } from "../utils"

const OLD_PROP_NAME = "mood"
Expand Down
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
import type { MultiActionTileProps } from "~components/Tile"
import type { MultiActionTileProps } from "../../src/Tile"
import { migrateStringProp } from "../utils"

const OLD_PROP_NAME = "mood"
Expand Down
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
import type { GenericNotificationProps } from "~components/Notification/subcomponents/GenericNotification"
import type { GenericNotificationProps } from "../../src/Notification/subcomponents/GenericNotification"
import { migrateStringProp } from "../utils"

const OLD_PROP_NAME = "type"
Expand Down
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
import type { ProgressBarProps } from "~components/ProgressBar"
import type { ProgressBarProps } from "../../src/ProgressBar"
import { migrateStringProp } from "../utils"

const OLD_PROP_NAME = "mood"
Expand Down
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
import { transformComponentsInDir } from "../utils"
import { removeInputEditModalMood } from "./removeInputEditModalMood"
/** This is here as a script runner that migrates Well variant to their color equivalent */
const migrateModalMoodsToVariant = (): void => {
const run = (): void => {
// eslint-disable-next-line no-console
console.log(" ~(-_- ~) Running InputEditModal transformer (~ -_-)~")
const targetDir = process.argv[2]
Expand All @@ -16,4 +16,4 @@ const migrateModalMoodsToVariant = (): void => {
)
}

migrateModalMoodsToVariant()
run()
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@ import { transformSource, printAst } from "../utils"
import { removeInputEditModalMood } from "./removeInputEditModalMood"

describe("removeInputEditModalMood", () => {
it("removed mood", () => {
it("removes mood", () => {
const inputAst = parseJsx(`
export const TestComponent = () => <InputEditModal mood="positive"/>
`)
Expand Down Expand Up @@ -47,34 +47,4 @@ describe("removeInputEditModalMood", () => {
})
expect(transformed).toBe(printAst(outputAst))
})

it("transforms InputEditModal with arbitrary braces", () => {
const inputAst = parseJsx(`
export const TestComponent = () => <div><InputEditModal mood={"positive"}/><InputEditModal mood={'assertive'}/><InputEditModal mood={\`positive\`}/></div>
`)
const outputAst = parseJsx(`
export const TestComponent = () => <div><InputEditModal /><InputEditModal /><InputEditModal /></div>
`)
const transformed = transformSource({
sourceFile: inputAst,
astTransformer: removeInputEditModalMood,
tagName: "InputEditModal",
})
expect(transformed).toBe(printAst(outputAst))
})

it("won't modify variants usings variables", () => {
const inputAst = parseJsx(`
export const TestComponent = () => <div><InputEditModal mood={InputEditModalVariable}/></div>
`)
const outputAst = parseJsx(`
export const TestComponent = () => <div><InputEditModal /></div>
`)
const transformed = transformSource({
sourceFile: inputAst,
astTransformer: removeInputEditModalMood,
tagName: "InputEditModal",
})
expect(transformed).toBe(printAst(outputAst))
})
})
Original file line number Diff line number Diff line change
@@ -1,40 +1,3 @@
import ts from "typescript"
import { removeProps } from "../utils/removeProps"

/** Recurses through AST to find and update any jsx element that matched the tagName */
export const removeInputEditModalMood =
(context: ts.TransformationContext, tagName: string) =>
(rootNode: ts.Node): ts.Node => {
function visit(node: ts.Node): ts.Node {
if (ts.isJsxOpeningElement(node) || ts.isJsxSelfClosingElement(node)) {
if (node.tagName.getText() === tagName) {
const newAttributes = node.attributes.properties.reduce<
ts.JsxAttributeLike[]
>((acc, attr) => {
if (ts.isJsxAttribute(attr) && attr.name.getText() === "mood") {
return acc
}

return [...acc, attr]
}, [])

if (ts.isJsxOpeningElement(node)) {
return ts.factory.updateJsxOpeningElement(
node,
node.tagName,
node.typeArguments,
ts.factory.createJsxAttributes(newAttributes)
)
} else if (ts.isJsxSelfClosingElement(node)) {
return ts.factory.updateJsxSelfClosingElement(
node,
node.tagName,
node.typeArguments,
ts.factory.createJsxAttributes(newAttributes)
)
}
}
}
return ts.visitEachChild(node, visit, context)
}
return ts.visitNode(rootNode, visit)
}
export const removeInputEditModalMood = removeProps(["mood"])
15 changes: 15 additions & 0 deletions packages/components/codemods/removePopoverVariant/index.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
import { transformComponentsInDir } from "../utils"
import { removePopoverVariant } from "./removePopoverVariant"

const run = (): void => {
// eslint-disable-next-line no-console
console.log(" ~(-_- ~) Running Popover transformer (~ -_-)~")
const targetDir = process.argv[2]
if (!targetDir) {
process.exit(1)
}

transformComponentsInDir(targetDir, removePopoverVariant, "Popover")
}

run()
Original file line number Diff line number Diff line change
@@ -0,0 +1,65 @@
import { parseJsx } from "../__tests__/utils"
import { transformSource, printAst } from "../utils"
import { removePopoverVariant } from "./removePopoverVariant"

describe("removePopoverVariant()", () => {
it("removes variant", () => {
const inputAst = parseJsx(`
export const TestComponent = () => <Popover variant="positive" />
`)
const outputAst = parseJsx(`
export const TestComponent = () => <Popover />
`)
const transformed = transformSource({
sourceFile: inputAst,
astTransformer: removePopoverVariant,
tagName: "Popover",
})
expect(transformed).toEqual(printAst(outputAst))
})

it("removes customIcon", () => {
const inputAst = parseJsx(`
export const TestComponent = () => <Popover variant="positive" customIcon={<Icon />} />
`)
const outputAst = parseJsx(`
export const TestComponent = () => <Popover />
`)
const transformed = transformSource({
sourceFile: inputAst,
astTransformer: removePopoverVariant,
tagName: "Popover",
})
expect(transformed).toEqual(printAst(outputAst))
})

it("handles multiple attributes and remove only variant", () => {
const inputAst = parseJsx(`
export const TestComponent = () => <Popover variant="negative" id="123"/>
`)
const outputAst = parseJsx(`
export const TestComponent = () => <Popover id="123"/>
`)
const transformed = transformSource({
sourceFile: inputAst,
astTransformer: removePopoverVariant,
tagName: "Popover",
})
expect(transformed).toBe(printAst(outputAst))
})

it("transforms multiple Popovers", () => {
const inputAst = parseJsx(`
export const TestComponent = () => <div><Popover variant="positive"/><Popover variant="negative" customIcon={<Icon />}/></div>
`)
const outputAst = parseJsx(`
export const TestComponent = () => <div><Popover /><Popover /></div>
`)
const transformed = transformSource({
sourceFile: inputAst,
astTransformer: removePopoverVariant,
tagName: "Popover",
})
expect(transformed).toBe(printAst(outputAst))
})
})
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
import { removeProps } from "../utils/removeProps"

export const removePopoverVariant = removeProps(["variant", "customIcon"])
Original file line number Diff line number Diff line change
Expand Up @@ -120,10 +120,10 @@ describe("transformGuidanceBlockVariantProp", () => {

it("won't modify variants usings variables", () => {
const inputAst = parseJsx(`
export const TestComponent = () => <div><GuidanceBlock variant={wellVariable} /></div>
export const TestComponent = () => <div><GuidanceBlock variant={varName} /></div>
`)
const outputAst = parseJsx(`
export const TestComponent = () => <div><GuidanceBlock variant={wellVariable} /></div>
export const TestComponent = () => <div><GuidanceBlock variant={varName} /></div>
`)
const transformed = transformSource({
sourceFile: inputAst,
Expand Down
Loading

0 comments on commit df16927

Please sign in to comment.