Material UI React Typescript - 扩展主题颜色 - 无法修复 Typescript 问题
我是 Typescript 的新手,非常困惑,有人能帮忙吗? 所以我在 React 项目中将 Material-ui 与 Typescript 结合使用。如果有人想以“正确”的方式添加新颜色,他们必须将其添加到主题中:
const theme = createMuiTheme({
palette: {
primary: {
main: blue[400]
},
secondary: {
main: green[500]
},
neutral: {
main: "#abcdef" // <-- NEW COLOR
}
}
})
然后,每当您想使用主题时,都可以在 ThemeProvider 包装器组件中使用它。直接来自文档。但是,如果受害者也试图使用 Typescript,他们必须扩展 Palette 接口(文档再次以此为例)..
declare module "@material-ui/core/styles/createPalette" {
interface Palette {
neutral: Palette["primary"]
}
interface PaletteOptions {
neutral: PaletteOptions["primary"]
}
}
同样,只是从文档中复制/粘贴。似乎有道理!现在 Typescript 不再抱怨调色板中的新属性。现在,是时候试试我的新颜色了!但是,当我尝试在组件中使用它时:
<IconButton color="neutral" onClick={onClose}> {/* big problem!! */}
<CloseIcon />
</IconButton>
这就是我感到困惑的地方。Typescript 会抱怨!我的意思是,我想抱怨是 Typescript 的工作,但我不知道如何处理它。'color' 上有一个红色波浪线,因为 color prop 的类型没有“netural”选项。
但当然,我是新手,我可能会错过一些显而易见的东西。 因此,就像我说的,组件的 props 被定义为“类型”,而不是接口或类似的东西,而“颜色”是其中的另一种类型,它只接受某些刺痛,我只需要让它识别“中性”,但我不知道。有办法吗?(不使用 ts-ignore)
{/*
// @ts-ignore */}
<IconButton color="neutral" ...
(不想这样做)
我觉得如果我要以“正确”的方式使用颜色,应该有一个简单的解决方法……但我只是没有看到它。请帮忙!!
请记住,您不能将
color
属性的任意值传递给
IconButton
以及任何其他material-ui的
Button
。只能重新定义现有的主题颜色:
primary
和
secondary
。此行为是
硬编码
(4.x),并且在可预见的
未来
(5.x)内不会发生变化。
仅 className/classes 覆盖,如所提议的Barryman9000。
至于类型,我认为没有简单的方法来覆盖 4.x 的
PropTypes.Color
类型定义。但从 5.x(@next) 开始,您可以通过合并
IconButtonPropsColorOverrides
接口来
扩展或限制
IconButton
的
color
prop 可接受值:
interface IconButtonPropsColorOverrides {
neutral: true // allow `neutral` to be used as a color prop value
primary: false // forbid using `primary`
}
但您仍必须为这些值实现实际的行为逻辑。它们不会立即起作用(截至当前(2021-05)@next 代码的状态)
我遇到过这种情况。我认为问题在于您只是扩展了主题对象,但
<IconButton />
组件的
color
prop 属于
PropTypes.Color
类型,其中
Color
是联合类型,并且仅接受这四个值
export namespace PropTypes {
type Color = 'inherit' | 'primary' | 'secondary' | 'default';
}
我使用了几种不同的方法来解决这个问题。使用
useTheme()
钩子,您可以从组件中的调色板访问
neutral
主题颜色,也可以创建样式化组件并从那里访问调色板
在您的组件中
const MyComponent = () => {
const { palette } = useTheme();
return (
<IconButton
color={palette.neutral.main}
>...</IconButton>)
}
styled-component
const MyStyledComponent = styled(IconButton)(({ theme }) => ({
color: theme.palette.neutral.main
}));