Skip to content

Commit

Permalink
LG-4525: popover-v12 code mod (#2484)
Browse files Browse the repository at this point in the history
* Add addJSXAttributes code mod util

* Update consolidateJSXAttributes util to handle edge case

* Add removeJSXAttributes code mod util

* Fix comment utils

* Export utils from utils/transformations

* Add popover-v12 codemod

* Changeset

* Fix build type

* Clean up comments

* Update docs

* Add commentOverride

* Update transform.config.js
  • Loading branch information
stephl3 authored Oct 25, 2024
1 parent 6c50a53 commit ba96107
Show file tree
Hide file tree
Showing 38 changed files with 1,215 additions and 86 deletions.
22 changes: 22 additions & 0 deletions .changeset/loud-items-thank.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
---
'@lg-tools/codemods': minor
---

[LG-4525](https://jira.mongodb.org/browse/LG-4525) Add `popover-v12` codemod which can be used to refactor popover component instances. It does the following:
1. Adds an explicit `usePortal={true}` declaration if left undefined and consolidates the `usePortal` and `renderMode` props into a single `renderMode` prop for the following components:
- `Combobox`
- `Menu`
- `Popover`
- `Select`
- `SplitButton`
- `Tooltip`
2. Removes `popoverZIndex`, `portalClassName`, `portalContainer`, `portalRef`, `scrollContainer`, and `usePortal` props from the following components:
- `InfoSprinkle`
- `InlineDefinition`
- `NumberInput`
3. Removes `popoverZIndex`, `portalClassName`, `portalContainer`, `portalRef`, and `scrollContainer` props from the following components:
- `DatePicker`
- `GuideCue`
4. Removes `popoverZIndex`, `portalClassName`, `portalContainer`, `scrollContainer`, and `usePortal` props from `Code` component
5. Removes `portalClassName`, `portalContainer`, `portalRef`, `scrollContainer`, and `usePortal` props from `SearchInput` component
6. Removes `shouldTooltipUsePortal` prop from `Copyable` component
89 changes: 39 additions & 50 deletions tools/codemods/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -72,77 +72,66 @@ yarn lg codemod <codemode> <path> --force

## Codemods

**_NOTE:_ These codemods are for testing purposes only**
### `popover-v12`

### `consolidate-props`
This codemod does the following:

This codemod consolidates two props into one.
1. Adds an explicit `usePortal={true}` declaration if left undefined and consolidates the `usePortal` and `renderMode` props into a single `renderMode` prop for the following components:

```jsx
yarn lg codemod codemode-props <path>
```
- `Combobox`
- `Menu`
- `Popover`
- `Select`
- `SplitButton`
- `Tooltip`

E.g.
In this example, the `disabled` props is merged into the `state` prop.
2. Removes `popoverZIndex`, `portalClassName`, `portalContainer`, `portalRef`, `scrollContainer`, and `usePortal` props from the following components:

**Before**:
- `InfoSprinkle`
- `InlineDefinition`
- `NumberInput`

```jsx
<MyComponent disabled={true} state="valid" />
```
3. Removes `popoverZIndex`, `portalClassName`, `portalContainer`, `portalRef`, and `scrollContainer` props from the following components:

**After**:
- `DatePicker`
- `GuideCue`

```jsx
<MyComponent state="disabled" />
```

<hr>

### `rename-component-prop`

This codemod renames a component prop
4. Removes `popoverZIndex`, `portalClassName`, `portalContainer`, `scrollContainer`, and `usePortal` props from `Code` component
5. Removes `portalClassName`, `portalContainer`, `portalRef`, `scrollContainer`, and `usePortal` props from `SearchInput` component
6. Removes `shouldTooltipUsePortal` prop from `Copyable` component

```jsx
yarn lg codemod codemode-component-prop <path>
yarn lg codemod popover-v12 <path>
```

E.g.
In this example, `prop` is renamed to `newProp`.

**Before**:

```jsx
<MyComponent prop="hey" />
```
<Combobox />
<Combobox usePortal={true} />
<Combobox usePortal={false} />

**After**:
<Code portalClassName="portal-class" portalRef={ref} usePortal />
<DatePicker portalContainer={containerRef} scrollContainer={containerRef} />
<InfoSprinkle popoverZIndex={9999} usePortal={false} />

```jsx
<MyComponent newProp="hey" />
```

<hr>

### `update-component-prop-value`

This codemod updates a prop value

```jsx
yarn lg codemod codemode-component-prop-value <path>
<Copyable shouldTooltipUsePortal />
<Copyable shouldTooltipUsePortal={true} />
<Copyable shouldTooltipUsePortal={false} />
```

E.g.
In this example, `value` is updated to `new prop value`.

**Before**:
**After**:

```jsx
<MyComponent prop="value" />
```
<Combobox renderMode="portal" />
<Combobox renderMode="portal" />
<Combobox renderMode="inline" />

**After**:
<Code />
<DatePicker />
<InfoSprinkle />

```jsx
<MyComponent prop="new prop value" />
<Copyable />
<Copyable />
<Copyable />
```
Original file line number Diff line number Diff line change
Expand Up @@ -15,15 +15,15 @@ export const App = () => {

const Test = () => {
return (
/* Please update manually */
/* Please manually update from prop: propToRemove to prop: propToUpdate */
<MyComponent propToRemove="value2" {...props} />
);
};

const TestTwo = () => {
return (
<>
{/* Please update manually */}
{/* Please manually update from prop: propToRemove to prop: propToUpdate */}
<MyComponent propToRemove="value2" {...props} />
</>
);
Expand All @@ -39,7 +39,7 @@ export const App = () => {
</MyComponent>
<MyComponent propToUpdate="value3" />
<MyComponent propToUpdate="value3" />
{/* Please update manually */}
{/* Please manually update from prop: propToRemove to prop: propToUpdate */}
<MyComponent propToRemove="value2" {...props} />
<MyComponent propToUpdate="value3" {...props} />
<MyComponent />
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,65 @@
import React from 'react';

const Combobox = ({ children, ...props }: any) => {
return <div {...props}>{children}</div>;
};

const Menu = ({ children, ...props }: any) => {
return <div {...props}>{children}</div>;
};

const Popover = ({ children, ...props }: any) => {
return <div {...props}>{children}</div>;
};

const Select = ({ children, ...props }: any) => {
return <div {...props}>{children}</div>;
};

const SplitButton = ({ children, ...props }: any) => {
return <div {...props}>{children}</div>;
};

const Tooltip = ({ children, ...props }: any) => {
return <div {...props}>{children}</div>;
};

const Child = (props: any) => {
return <div>{props.children}</div>;
};

export const App = () => {
const spreadProps = {
prop: true,
} as const;

const WrappedPopover = () => {
return <Popover usePortal={false} {...spreadProps} />;
};

const DefaultWrappedPopover = () => {
return <Popover {...spreadProps} />;
};

return (
<>
<Combobox />
<Menu usePortal />
<Popover usePortal={false} />
<Select usePortal={true} />
<SplitButton />
<Tooltip usePortal={false} />
<Popover />
<Popover renderMode="inline" usePortal={false} />
<Popover renderMode="portal" usePortal={true} />
<Popover usePortal>
<Child usePortal={false} />
</Popover>
<Popover usePortal={false} />
<Popover usePortal={true} {...spreadProps} />
<Popover {...spreadProps} />
<WrappedPopover />
<DefaultWrappedPopover />
</>
);
};
Original file line number Diff line number Diff line change
@@ -0,0 +1,73 @@
import React from 'react';

const Combobox = ({ children, ...props }: any) => {
return <div {...props}>{children}</div>;
};

const Menu = ({ children, ...props }: any) => {
return <div {...props}>{children}</div>;
};

const Popover = ({ children, ...props }: any) => {
return <div {...props}>{children}</div>;
};

const Select = ({ children, ...props }: any) => {
return <div {...props}>{children}</div>;
};

const SplitButton = ({ children, ...props }: any) => {
return <div {...props}>{children}</div>;
};

const Tooltip = ({ children, ...props }: any) => {
return <div {...props}>{children}</div>;
};

const Child = (props: any) => {
return <div>{props.children}</div>;
};

export const App = () => {
const spreadProps = {
prop: true,
} as const;

const WrappedPopover = () => {
return (
/* Please manually update from prop: usePortal to prop: renderMode */
<Popover usePortal={false} {...spreadProps} />
);
};

const DefaultWrappedPopover = () => {
return (
/* Please manually add prop: renderMode */
<Popover {...spreadProps} />
);
};

return (
<>
<Combobox renderMode="portal" />
<Menu renderMode="portal" />
<Popover renderMode="inline" />
<Select renderMode="portal" />
<SplitButton renderMode="portal" />
<Tooltip renderMode="inline" />
<Popover renderMode="portal" />
<Popover renderMode="inline" />
<Popover renderMode="portal" />
<Popover renderMode="portal">
<Child usePortal={false} />
</Popover>
<Popover renderMode="inline" />
{/* Please manually update from prop: usePortal to prop: renderMode */}
<Popover usePortal={true} {...spreadProps} />
{/* Please manually add prop: renderMode */}
<Popover {...spreadProps} />
<WrappedPopover />
<DefaultWrappedPopover />
</>
);
};
Original file line number Diff line number Diff line change
@@ -0,0 +1,69 @@
import React from 'react';

const Code = ({ children, ...props }: any) => {
return <div {...props}>{children}</div>;
};

const DatePicker = ({ children, ...props }: any) => {
return <div {...props}>{children}</div>;
};

const GuideCue = ({ children, ...props }: any) => {
return <div {...props}>{children}</div>;
};

const InfoSprinkle = ({ children, ...props }: any) => {
return <div {...props}>{children}</div>;
};

const InlineDefinition = ({ children, ...props }: any) => {
return <div {...props}>{children}</div>;
};

const NumberInput = ({ children, ...props }: any) => {
return <div {...props}>{children}</div>;
};

const SearchInput = ({ children, ...props }: any) => {
return <div {...props}>{children}</div>;
};

const Child = (props: any) => {
return <div>{props.children}</div>;
};

export const App = () => {
const spreadProps = {
prop: true,
} as const;

const WrappedInfoSprinkle = (props: any) => {
return <InfoSprinkle usePortal={false} {...props} />;
};

return (
<>
<Code usePortal />
<DatePicker />
<GuideCue />
<InfoSprinkle usePortal />
<InlineDefinition usePortal={false} />
<NumberInput usePortal={true} />
<SearchInput usePortal />
<InfoSprinkle />
<InfoSprinkle
portalClassName="portal-class"
portalRef={{ current: null }}
/>
<InfoSprinkle
portalContainer={{ current: null }}
scrollContainer={{ current: null }}
/>
<InfoSprinkle popoverZIndex={9999} usePortal>
<Child usePortal={false} />
</InfoSprinkle>
<InfoSprinkle usePortal={true} {...spreadProps} />
<WrappedInfoSprinkle />
</>
);
};
Loading

0 comments on commit ba96107

Please sign in to comment.