我正在尝试创建一个动态组件,它可以是标签、按钮或链接。现在我想添加另一个组件,它是
Component
的孩子。但是打字稿错误使我无法完成它。有人可以帮我吗?
import { css } from '@emotion/react';
import React, { ReactNode } from 'react';
import { Link } from 'react-router-dom';
const sizes = {
sm: 'font-size: 1.2rem; padding: 0.8rem 2rem;',
md: 'font-size: 1.4rem; padding: 0.8rem 2rem;',
lg: 'font-size: 2rem; padding: 0.8rem 2rem;',
};
type RemoveDuplicatedProps<ComponentProps, PassedProps> = Omit<ComponentProps, keyof PassedProps>;
type GetPropsWithOverride<Root extends ButtonRoots, Props> = {
as?: Root;
} & Props &
RemoveDuplicatedProps<React.ComponentProps<Root>, Props>;
type ButtonRoots = 'a' | 'button' | typeof Link;
interface BaseButton<Props> {
<Root extends ButtonRoots>(props: GetPropsWithOverride<Root, Props>): JSX.Element;
(props: Props): JSX.Element;
}
type ButtonProps = {
className?: string;
children?: ReactNode;
disabled?: boolean;
size?: keyof typeof sizes;
text?: boolean;
rounded?: boolean;
};
const Button: BaseButton<ButtonProps> = ({
as: Component = 'button',
size = 'md',
text = false,
disabled = false,
rounded = false,
...props
}) => {
const tmpProps = { ...props };
if (disabled) {
Object.keys(props).forEach((propKey) => {
if (propKey.startsWith('on') && typeof props[propKey] === 'function') {
delete tmpProps[propKey];
}
});
}
return <Component css={buttonCss(disabled, rounded, text, size as keyof typeof sizes)} {...tmpProps} />;
};
const buttonCss = (disabled: boolean, rounded: boolean, text: boolean, size: keyof typeof sizes) => css`
& {
width: max-content;
display: inline-flex;
align-items: center;
outline: none;
text-decoration: transparent;
transition: all linear 0.1s;
${sizes[size]}
color: ${text ? 'var(--black-color)' : 'var(--white-color)'};
background: ${text ? 'transparent' : 'var(--primary-color)'};
${disabled ? 'opacity: 0.5; cursor: auto;' : 'cursor: pointer;'};
${rounded && !text && 'border-radius: 4px'};
}
&:hover {
${!disabled && 'opacity: 0.8;'}
}
&:active {
${!disabled && 'opacity: 1'}
}
`;
export default Button;