Skip to content

Commit

Permalink
chore(codemod): add supported list migrations
Browse files Browse the repository at this point in the history
  • Loading branch information
mlaursen committed Jul 21, 2024
1 parent 0850a7b commit 84e99b9
Show file tree
Hide file tree
Showing 18 changed files with 659 additions and 18 deletions.
154 changes: 154 additions & 0 deletions apps/docs/src/app/(main)/(markdown)/migration/v5-to-v6/page.mdx
Original file line number Diff line number Diff line change
Expand Up @@ -1342,6 +1342,160 @@ The `Link` component updated the following props:

## List

There are a few breaking changes for the list components:

- The `SimpleListItem` was removed in favor of using an `<li>` with the
`ListItemChildren` component
- The `ListItem` and `ListItemLink` removed support for the ripple props
and updated the following props:
- The `forceAddonWrap` prop was removed in favor of the `leftAddonForceWrap`
and `rightAddonForceWrap`
- The `textChildren` prop was renamed to `disableTextChildren`
- The `ListItemLink` renamed `component` to `as`

> !Warn! For Typescript users, the `ListItemLink` no longer allows
> `{ [key: string]: unknown }` when the `as` component is provided.
### 🔧 update-list-item-props

```sh
npx @react-md/codemod v5-to-v6/list/update-list-item-props
```

Update `textChildren` prop:

```diff
import { type ReactElement } from "react";
import { ListItem } from "react-md";

export default function Example(): ReactElement {
return (
<>
- <ListItem textChildren>Hello, world!</ListItem>
- <ListItem textChildren={false}>Hello, world!</ListItem>
- <ListItem textChildren={true}>Hello, world!</ListItem>
- <ListItem textChildren={textChildren}>Hello, world!</ListItem>
+ <ListItem>Hello, world!</ListItem>
+ <ListItem disableTextChildren>Hello, world!</ListItem>
+ <ListItem>Hello, world!</ListItem>
+ <ListItem disableTextChildren={!textChildren}>Hello, world!</ListItem>
</>
);
}
```

Remove ripple props:

```diff
import { type ReactElement } from "react";
import { ListItem } from "react-md";
import styles from "./styles.module.scss";

export default function Example(): ReactElement {
return (
<ListItem
onClick={() => {
// do something
}}
- disableRipple
- disableProgrammaticRipple
- disableEnterClick
- disableSpacebarClick
- disablePressedFallback
- enablePressedAndRipple
- rippleTimeout={100}
- rippleClassName={styles.ripple}
- rippleClassNames={{ enter: "", exit: "" }}
- rippleContainerClassName="example"
>
Hello, world!
</ListItem>
);
}
```

Rename `component` to `as`:

```diff
export default function Example(): ReactElement {
return (
<>
- <ListItemLink component={CustomLink} to="/some-path">
+ <ListItemLink as={CustomLink} to="/some-path">
Link 1
</ListItemLink>
- <ListItemLink component="a" href="/some-path">
+ <ListItemLink as="a" href="/some-path">
Link 2
</ListItemLink>
</>
```

Remove `SimpleListItem`:

```diff
import type { ReactElement } from "react";
import cn from "classnames";
-import { FavoriteSVGIcon, List, SimpleListItem } from "react-md";
+import { FavoriteSVGIcon, List, ListItemChildren } from "react-md";

import people from "./people";

@@ -12,33 +12,35 @@ export default function Demo(): ReactElement {
<Container>
<List>
{people.slice(0, 10).map((name) => (
- <SimpleListItem
+ <li
key={name}
className={cn(styles.item, styles.dotted, styles.margin)}
>
- {name}
- </SimpleListItem>
+ <ListItemChildren>{name}</ListItemChildren>
+ </li>
))}
</List>
<List className={styles.ordered}>
{people.slice(11, 20).map((name) => (
- <SimpleListItem key={name} className={cn(styles.item, styles.margin)}>
- {name}
- </SimpleListItem>
+ <li key={name} className={cn(styles.item, styles.margin)}>
+ <ListItemChildren>{name}</ListItemChildren>
+ </li>
))}
</List>
<List>
- <SimpleListItem
- primaryText={<span>Primary Text</span>}
- secondaryText={
- <span className={styles.secondary}>Secondary Text</span>
- }
- leftAddon={<FavoriteSVGIcon />}
- rightAddon={<img alt="" src="https://example.com/image.jpeg" />}
- rightAddonType="media"
- >
- Other children
- </SimpleListItem>
+ <li>
+ <ListItemChildren
+ primaryText={<span>Primary Text</span>}
+ secondaryText={
+ <span className={styles.secondary}>Secondary Text</span>
+ }
+ leftAddon={<FavoriteSVGIcon />}
+ rightAddon={<img alt="" src="https://example.com/image.jpeg" />}
+ rightAddonType="media"
+ >
+ Other children
+ </ListItemChildren>
+ </li>
</List>
</Container>
);
```

## Material Icons

## Media
Expand Down
7 changes: 7 additions & 0 deletions packages/codemod/transforms/types.ts
Original file line number Diff line number Diff line change
@@ -1,4 +1,6 @@
import {
type JSXEmptyExpression,
type JSXExpressionContainer,
type ArrayPattern,
type ArrowFunctionExpression,
type AssignmentPattern,
Expand Down Expand Up @@ -73,3 +75,8 @@ export type ComponentDefinition = (
| FunctionDeclaration
| FunctionExpression
) & { body: BlockStatement };

export type NonEmptyJSXExpresson = Exclude<
JSXExpressionContainer["expression"],
JSXEmptyExpression
>;
14 changes: 3 additions & 11 deletions packages/codemod/transforms/utils/isJsxExpressionContainer.ts
Original file line number Diff line number Diff line change
@@ -1,19 +1,11 @@
import {
type JSCodeshift,
type JSXEmptyExpression,
type JSXExpressionContainer,
} from "jscodeshift";

type DefinedExpression = Exclude<
JSXExpressionContainer["expression"],
JSXEmptyExpression
>;
import { type JSCodeshift, type JSXExpressionContainer } from "jscodeshift";
import { type NonEmptyJSXExpresson } from "../types";

export function isJsxExpressionContainer(
j: JSCodeshift,
value: unknown
): value is JSXExpressionContainer & {
expression: DefinedExpression;
expression: NonEmptyJSXExpresson;
} {
return (
j.JSXExpressionContainer.check(value) &&
Expand Down
Original file line number Diff line number Diff line change
@@ -1,18 +1,15 @@
import {
type JSXText,
type Identifier,
type JSXAttribute,
type JSXExpressionContainer,
type Literal,
type NumericLiteral,
type StringLiteral,
type BooleanLiteral,
} from "jscodeshift";
import { type NonEmptyJSXExpresson } from "../types";

export function isPropConditionalExpression(
attr: JSXAttribute
): attr is JSXAttribute & {
value: JSXExpressionContainer & {
expression: Identifier | Literal | StringLiteral | NumericLiteral | JSXText;
expression: Exclude<NonEmptyJSXExpresson, BooleanLiteral>;
};
} {
return (
Expand Down
2 changes: 1 addition & 1 deletion packages/codemod/transforms/v5-to-v6/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -96,7 +96,7 @@ build times by switching to `@react-md/core/{{FILE}}`.
- [x] icon
- [ ] layout
- [x] link
- [ ] list
- [x] list
- [x] material-icons
- [ ] media
- [ ] menu
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,26 @@
import { type ReactElement } from "react";
import { ListItemLink } from "react-md";
import styles from "./styles.module.scss";

export default function Example(): ReactElement {
return (
<ListItemLink
to="/example"
onClick={() => {
// do something
}}
disableRipple
disableProgrammaticRipple
disableEnterClick
disableSpacebarClick
disablePressedFallback
enablePressedAndRipple
rippleTimeout={100}
rippleClassName={styles.ripple}
rippleClassNames={{ enter: "", exit: "" }}
rippleContainerClassName="example"
>
Hello, world!
</ListItemLink>
);
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
import { type ReactElement } from "react";
import { ListItemLink } from "react-md";
import styles from "./styles.module.scss";

export default function Example(): ReactElement {
return (
(<ListItemLink
to="/example"
onClick={() => {
// do something
}}>Hello, world!
</ListItemLink>)
);
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,25 @@
import { type ReactElement } from "react";
import { ListItem } from "react-md";
import styles from "./styles.module.scss";

export default function Example(): ReactElement {
return (
<ListItem
onClick={() => {
// do something
}}
disableRipple
disableProgrammaticRipple
disableEnterClick
disableSpacebarClick
disablePressedFallback
enablePressedAndRipple
rippleTimeout={100}
rippleClassName={styles.ripple}
rippleClassNames={{ enter: "", exit: "" }}
rippleContainerClassName="example"
>
Hello, world!
</ListItem>
);
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
import { type ReactElement } from "react";
import { ListItem } from "react-md";
import styles from "./styles.module.scss";

export default function Example(): ReactElement {
return (
(<ListItem
onClick={() => {
// do something
}}>Hello, world!
</ListItem>)
);
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
import { type ReactElement } from "react";
import { ListItemLink } from "react-md";

import { CustomLink } from "./CustomLink";

export default function Example(): ReactElement {
return (
<>
<ListItemLink component={CustomLink} to="/some-path">
Link 1
</ListItemLink>
<ListItemLink component="a" href="/some-path">
Link 2
</ListItemLink>
</>
);
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
import { type ReactElement } from "react";
import { ListItemLink } from "react-md";

import { CustomLink } from "./CustomLink";

export default function Example(): ReactElement {
return (<>
<ListItemLink as={CustomLink} to="/some-path">
Link 1
</ListItemLink>
<ListItemLink as="a" href="/some-path">
Link 2
</ListItemLink>
</>);
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
import { type ReactElement } from "react";
import { ListItem } from "react-md";

export default function Example(): ReactElement {
return (
<>
<ListItem textChildren>Hello, world!</ListItem>
<ListItem textChildren={false}>Hello, world!</ListItem>
<ListItem textChildren={true}>Hello, world!</ListItem>
<ListItem textChildren={textChildren}>Hello, world!</ListItem>
</>
);
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
import { type ReactElement } from "react";
import { ListItem } from "react-md";

export default function Example(): ReactElement {
return (<>
<ListItem>Hello, world!</ListItem>
<ListItem disableTextChildren>Hello, world!</ListItem>
<ListItem>Hello, world!</ListItem>
<ListItem disableTextChildren={!textChildren}>Hello, world!</ListItem>
</>);
}
Loading

0 comments on commit 84e99b9

Please sign in to comment.