我想用样式化的组件来包装我的蚂蚁设计组件,我知道这是可能的(https://gist.github.com/samuelcastro/0ff7db4fd54ce2b80cd1c34a85b40c08),但是我很难用TypeScript做到这一点。
这是我到目前为止所拥有的:
import { Button as AntButton } from 'antd';
import { ButtonProps } from 'antd/lib/button/button';
import styledComponents from 'styled-components';
interface IButtonProps extends ButtonProps {
customProp: string;
}
export const Button = styledComponents<IButtonProps>(AntButton)`
// any custom style here
`;
如您所见,我正在使用as any
定义我的ant-design按钮以使其起作用,否则我会得到一些不兼容的类型,例如:
Argument of type 'typeof Button' is not assignable to parameter of
type 'ComponentType<IButtonProps>'.
Type 'typeof Button' is not assignable to type
'StatelessComponent<IButtonProps>'.
Types of property 'propTypes' are incompatible.
Property 'customProp' is missing in type '{
type: Requireable<string>;
shape: Requireable<string>;
size: Requireable<string>;
htmlType: Requireable<string>;
onClick: ...
etc
}
谢谢。
解决方案:
import { Button as AntButton } from 'antd';
import { NativeButtonProps } from 'antd/lib/button/button';
import * as React from 'react';
import styledComponents from 'styled-components';
export const Button = styledComponents<NativeButtonProps>(props => <AntButton {...props} />)`
// custom-props
`;
答案 0 :(得分:2)
问题的根源似乎是styled-components
希望内部组件(AntButton
)接受 all 指定接口(IButtonProps
中的道具),但AntButton
不接受customProp
。要解决此问题,请遵循文档this section中的最后一个示例,并在调用customProp
之前使用无状态功能组件删除AntButton
。
export const Button = styledComponents<IButtonProps>(
({ customProp, ...rest }) => <AntButton {...rest} />)`
// any custom style here
`;
答案 1 :(得分:2)
上述解决方案对我不起作用,尽管可以解决。
const Button = styled((props: NativeButtonProps) => <AntButton {...props} />)``;
答案 2 :(得分:2)
我找到了这个古老的问题,并尝试以一种简单的方式解决:
import React from 'react';
import styled from 'styled-components';
import { Card } from 'antd';
import { CardProps } from 'antd/lib/card';
export const NewCard: React.FunctionComponent<CardProps> = styled(Card)`
margin-bottom: 24px;
`;
没有渲染道具:D
如果只需要将一个组件包装为功能组件,那么就可以了。但是您将丢失类组件的属性,例如Card.Meta
。
有一种解决方法:
import React from 'react';
import styled from 'styled-components';
import { Card } from 'antd';
import { CardProps } from 'antd/lib/card';
export const NewCard: typeof Card = styled(Card)<CardProps>`
margin-bottom: 24px;
` as any;
一切(也许是XD)都可以作为原始的Antd组件;)
答案 3 :(得分:2)
我的代码在这里。这就是工作。
import React from 'react';
import { Button as AntButton } from 'antd';
import { ButtonProps } from 'antd/lib/button/button';
import styled from 'styled-components';
const Container = styled.div`
font-size: 20px;
`;
const Button: React.FunctionComponent<ButtonProps> = styled(AntButton)`
margin-top: 24px;
margin-left: 30px;
`;
export default function Home() {
return (
<Container>
Hello World
<Button type="primary">test</Button>
</Container>
);
}
答案 4 :(得分:0)
index.tsx(按钮组件)
import { Button as AntButton } from 'antd'
import { NativeButtonProps } from 'antd/lib/button/button'
import 'antd/lib/button/style/css'
import * as React from 'react'
import styledComponents from 'styled-components'
import * as colours from '../colours'
const getColour = (props: any) =>
props.status === 'green'
? colours.STATUS_GREEN
: props.status === 'red'
? colours.STATUS_RED
: props.type === 'primary'
? colours.PRIMARY
: colours.WHITE
export interface ButtonProps extends NativeButtonProps {
status?: string
}
export default styledComponents((props: ButtonProps) => <AntButton {...props} />)`
&:focus,
&:hover
& {
background-color: ${getColour};
border-color: ${getColour};
}
`
<script src="https://cdnjs.cloudflare.com/ajax/libs/react/16.5.2/umd/react.production.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/react-dom/16.5.2/umd/react-dom.production.min.js"></script>
import React from 'react'
import Button, { ButtonProps } from './index'
interface ButtonAsyncSingleSuccessProps extends ButtonProps {
clickFunc: any, // (...args: any[]) => Promise<any>
labelLoading: string,
labelReady: string,
labelSuccess: string,
}
interface ButtonAsyncSingleSuccessState {
label: string,
loading: boolean,
status: string
}
export default class ButtonAsyncSingleSuccess extends React.Component<
ButtonAsyncSingleSuccessProps,
ButtonAsyncSingleSuccessState
> {
constructor (props: any) {
super(props)
this.state = {
label: props.labelReady,
loading: false,
status: ''
}
}
public clickHandler (event: any) {
const { labelLoading, labelReady, labelSuccess, clickFunc } = this.props
this.setState({
label: labelLoading,
loading: true,
status: ''
})
clickFunc(event)
.then(() => {
this.setState({
label: labelSuccess,
loading: false,
status: 'green'
})
})
.catch(() => {
this.setState({
label: labelReady,
loading: false,
status: 'red'
})
})
}
public render () {
const {
labelLoading,
labelReady,
labelSuccess,
clickFunc,
...props
} = this.props
const { label, loading, status } = this.state
if (status === 'red') {
setTimeout(() => this.setState({ status: '' }), 1000) // flash red
}
return (
<Button
{...props}
loading={loading}
status={status}
onClick={(e) => this.clickHandler(e)}
>
{label}
</Button>
)
}
}