Trying to extend the Material-ui Button component to add new props.
Purpose is to add a new prop: fontSize
which has three options - small
, medium
, large
.
<Button variant="outlined" color="primary" fontSize="small"> button_small </Button>
and to use it in css to make the required changes.
As per the material ui documentation for typescript theme customisation, I have already customised the theme and it works fine.
Only problem is trying to update the prop types for Button doesn't work.
And I get this error for no overload match which is obvious because material ui Button component doesn't know about the "fontSize" new props.
error TS2769: No overload matches this call.
Overload 1 of 3, '(props: { href: string; } & { children?: ReactNode; color?: Color | undefined; disabled?: boolean | undefined; disableElevation?: boolean | undefined; disableFocusRipple?: boolean | undefined; ... 5 more ...; variant?: "text" | ... 2 more ... | undefined; } & { ...; } & CommonProps<...> & Pick<...>): Element', gave the following error. Type '{ children: string; variant: "outlined"; color: "primary"; fontSize: string; }' is not assignable to type 'IntrinsicAttributes & { href: string; } & { children?: ReactNode; color?: Color | undefined; disabled?: boolean | undefined; disableElevation?: boolean | undefined; ... 6 more ...; variant?: "text" | ... 2 more ... | undefined; } & { ...; } & CommonProps<...> & Pick<...>'. Property 'fontSize' does not exist on type 'IntrinsicAttributes & { href: string; } & { children?: ReactNode; color?: Color | undefined; disabled?: boolean | undefined; disableElevation?: boolean | undefined; ... 6 more ...; variant?: "text" | ... 2 more ... | undefined; } & { ...; } & CommonProps<...> & Pick<...>'.
Overload 2 of 3, '(props: { component: ElementType; } & { children?: ReactNode; color?: Color | undefined; disabled?: boolean | undefined; disableElevation?: boolean | undefined; ... 6 more ...; variant?: "text" | ... 2 more ... | undefined; } & { ...; } & CommonProps<...> & Pick<...>): Element', gave the following error. Property 'component' is missing in type '{ children: string; variant: "outlined"; color: "primary"; fontSize: string; }' but required in type '{ component: ElementType; }'.
Overload 3 of 3, '(props: DefaultComponentProps<ExtendButtonBaseTypeMap<ButtonTypeMap<{}, "button">>>): Element', gave the following error. Type '{ children: string; variant: "outlined"; color: "primary"; fontSize: string; }' is not assignable to type 'IntrinsicAttributes & { children?: ReactNode; color?: Color | undefined; disabled?: boolean | undefined; disableElevation?: boolean | undefined; ... 6 more ...; variant?: "text" | ... 2 more ... | undefined; } & { ...; } & CommonProps<...> & Pick<...>'. Property 'fontSize' does not exist on type 'IntrinsicAttributes & { children?: ReactNode; color?: Color | undefined; disabled?: boolean | undefined; disableElevation?: boolean | undefined; ... 6 more ...; variant?: "text" | ... 2 more ... | undefined; } & { ...; } & CommonProps<...> & Pick<...>'.
Attempt 1: Following the answer from this stack-overflow question I tried to redeclare the Button, but it throws a typescript error (https://github.com/Microsoft/TypeScript/issues/17547) which seems to be unresolved.
declare module '@material-ui/core' {
export interface MyButtonProps {
fontSize: 'small' | 'medium' | 'large';
}
export class Button extends StyledComponent<ButtonProps & MyProps> {
}
}
Attempt2: Trying to overwrite the ButtonTypeMap instead of the Button but that doesn't help either.
declare module '@material-ui/core/Button' {
export type ButtonTypeMap<P = {}, D extends React.ElementType<any> = "button"> = ExtendButtonBaseTypeMap<{
props: P & {
children?: React.ReactNode;
color?: CustomColors;
disabled?: boolean;
disableElevation?: boolean;
disableFocusRipple?: boolean;
endIcon?: React.ReactNode;
fullWidth?: boolean;
href?: string;
size?: 'small' | 'medium' | 'large';
startIcon?: React.ReactNode;
variant?: 'text' | 'contained';
fontSize: 'small' | 'medium' | 'large';
};
defaultComponent: D;
classKey: ButtonClassKey;
}>
// The next line throws error with 'Button' is already declared in the upper scope
// declare const Button: ExtendButtonBase<ButtonTypeMap>;
}
Versions:
typescript: 4.2.4
@material-ui/core: 4.11.4
Edit: There are a few answers here (https://stackoverflow.com/a/65344567/2860486) which adds a Custom HOC which extends material-ui component to achieve desired behaviour but I want to overwrite the material UI component itself just to be consistent with importing component from "material-ui
" not from my local custom-component folder.