# Migration of components using IButtonProps
**See https://hackmd.io/836e7v9oReGWP6I_Y7CVXg for original discussion.**
Using SpinButton as an example here. It's relatively clean, but in other cases if the actual use of button is inside a sub-component (like in ContextualMenu) it will be messier.
The basic idea is:
- **Leave SpinButton in `@fluentui/react` to avoid circular dependencies**
- Update the prop types to accept new ButtonProps by default
- Add compat prop types which use the old IButtonProps
- In SpinButtonBase, use the new button by default, but add essentially an internal slot prop for overriding which button to use
- Add a compat SpinButton file which uses the compat props and passes through the old IconButton to the button slot
## Details
In `SpinButton.types.ts`, update to use the new `ButtonProps`:
```ts
import { ButtonProps } from '@fluentui/react-button';
export interface ISpinButtonProps /*...*/ {
iconButtonProps?: IButtonProps;
}
// This is mainly a hack to ensure links work on the doc site
/**
* {@docCategory SpinButton}
*/
export type INewSpinButtonProps = ISpinButtonProps;
```
In new `CompatSpinButton.types.ts` (may not use that exact filename), export props which switch back to the old `IButtonProps`:
```ts
import { IButtonProps } from '../../compat/Button';
import { INewSpinButtonProps } from './SpinButton.types';
export interface ISpinButtonProps extends Omit<INewSpinButtonProps, 'iconButtonProps'> {
iconButtonProps?: IButtonProps; // switch type back to old version
}
```
In `SpinButton.base.tsx`, use the new button by default but add (essentially) a slot for passing the compat one through. (Do NOT directly reference the old Button to avoid bundle size issues!)
```tsx
import { Button } from '@fluentui/react-button';
export interface ISpinButtonInternalProps extends ISpinButtonProps {
buttonComponent?: React.ComponentType;
}
export const SpinButtonBase: React.FunctionComponent<ISpinButtonInternalProps> = props => {
// Update references to button as follows:
const { buttonComponent: ButtonComponent = Button, iconButtonProps } = props;
<ButtonComponent {...(iconButtonProps as any)}>
}
```
In new `CompatSpinButton.tsx` (may not use that exact filename), use the slot to pass in the old button:
```tsx
import { ISpinButtonInternalProps, SpinButtonBase } from './SpinButton.base';
import { ISpinButtonProps } from './CompatSpinButton.types';
import { IconButton } from '../../compat/Button';
export const SpinButton: React.FunctionComponent<ISpinButtonProps> = styled<ISpinButtonProps, {}, ISpinButtonStyles>(
SpinButtonBase,
getStyles,
() => {
const internalProps: Partial<ISpinButtonInternalProps> = { buttonComponent: IconButton };
// Use a cast so we don't expose the internal props in the public typings
return internalProps as any;
},
{
scope: 'SpinButton',
},
);
```