I would like to extend the props of the Button component from Material-UI using typescript to be able pass additional props to it's children.
import { NavLink } from 'react-router-dom';
import { Button } from 'material-ui';
<Button
component={NavLink}
// NavLink props that needs to be added to typescript declarations
activeClassName={classes.activeButton}
exact={true}
to={to}
>
{title}
</Button>
I've tried to add the following declarations in ./app/types/material_ui.d.ts:
declare module 'material-ui' {
interface Button {
activeClassName?: any;
exact?: boolean;
to?: string;
}
}
Which throws the error "TS2693: 'Button' only refers to a type, but is being used as a value here.".
I've also tried the declaration:
import * as React from 'react';
import { PropTypes, StyledComponent } from 'material-ui';
import { ButtonBaseProps } from 'material-ui/ButtonBase';
declare module 'material-ui' {
export interface ButtonProps extends ButtonBaseProps {
color?: PropTypes.Color | 'contrast';
component?: React.ReactNode;
dense?: boolean;
disabled?: boolean;
disableFocusRipple?: boolean;
disableRipple?: boolean;
fab?: boolean;
href?: string;
raised?: boolean;
type?: string;
activeClassName?: any;
exact?: boolean;
to?: string;
}
export class Button extends StyledComponent<ButtonProps> { }
}
Which throws the error "TS2323: Cannot redeclare exported variable 'Button'".
My tsconfig.json looks like this:
{
"compilerOptions": {
...
"paths": {
"history": ["./node_modules/@types/history/index"],
"redux": ["./node_modules/@types/redux/index"],
"react": ["./node_modules/@types/react/index"],
"*": ["./app/types/*", "*"]
},
},
...
}
Finally the original type definition from Material-UI:
import * as React from 'react';
import { StyledComponent, PropTypes } from '..';
import { ButtonBaseProps } from '../ButtonBase';
export interface ButtonProps extends ButtonBaseProps {
color?: PropTypes.Color | 'contrast';
component?: React.ReactNode;
dense?: boolean;
disabled?: boolean;
disableFocusRipple?: boolean;
disableRipple?: boolean;
fab?: boolean;
href?: string;
raised?: boolean;
type?: string;
}
export default class Button extends StyledComponent<ButtonProps> {}
I am using material-ui 1.0.0-beta.8 with react 15.6.1, react-router-dom 4.2.2 and typescript 2.5.2.
MUI requires a minimum version of TypeScript 3.5. Have a look at the Create React App with TypeScript example. The strict mode options are the same that are required for every types package published in the @types/ namespace.
To customize a specific part of a component, you can use the class name provided by Material UI inside the sx prop. As an example, let's say you want to change the Slider component's thumb from a circle to a square. First, use your browser's dev tools to identify the class for the component slot you want to override.
import React, { FC } from 'react';
import { Button, ButtonProps } from '@material-ui/core';
interface IProps extends ButtonProps {} // your custom props
const ButtonHco: FC<IProps> = ({
variant,
color,
children,
size,
disabled
}) => {
return (
<Button variant={variant} color={color} size={size} disabled={disabled}>
{children}
</Button>
);
};
export default ButtonHco;
The following code works for me
import { Button, StyledComponent } from 'material-ui';
import { ButtonProps } from 'material-ui/Button';
declare module 'material-ui' {
export interface MyProps {
exact?: boolean;
to?: string;
}
export class Button extends StyledComponent<ButtonProps & MyProps> {
}
}
I don't have the problem with "TS2693: 'Button' only refers to a type, but is being used as a value here.
and I'm also using Typescript 2.5.2
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With