网站搜索

reactjs - 如何在 emotion 样式化组件中使用带有自定义属性的 MUI 主题对象的自定义属性?


我已经通过 TypeScript 的模块增强向 MUI 主题添加了一个名为 fTokens 的自定义对象

这就是我的 theme.d.ts 看起来的样子

declare module "@mui/material/styles" {
  interface FPalette { ...
  }

  interface FTokens { ...
  }

  interface FSpacing { ...
  }

  interface Theme {
    fPalette: FPalette;
    fTokens: FTokens;
    fSpacing: FSpacing;
  }

  interface ThemeOptions {
    fPalette: Partial<FPalette>;
    fTokens: Partial<Tokens>;
    fSpacing: Partial<FSpacing>;
  }
}

我正在尝试将自定义属性 rowId 传递给 MUI 的 TableRow

import MUITableRow, { TableRowProps as MUITableRowProps } from "@mui/material/TableRow";
import { styled } from "@mui/system";

interface TableRowProps {
  rowId: number;
}

const TableRow = styled(MUITableRow)<TableRowProps>(({ theme }) => ({
  backgroundColor: theme.fTokens.surfaceHigh,
}));

export default TableRow;

我收到 TypeScript 错误:Property 'fTokens' does not exist on type 'Theme'.ts(2339)

更新 - 我尝试了使用 as 关键字进行类型断言,这对我有效,但我不知道这是否是解决这个问题的最优雅方法?

const TableRow = styled(MUITableRow)<TableRowProps>(({ theme, rowId }) => ({
  backgroundColor:
    rowId % 2 === 0
      ? (theme as Theme).fTokens.surfaceHigh
      : (theme as Theme).fTokens.surfaceHighest,
}));

答案#1

尝试从 '@mui/material/styles' 导入 styled,而不是从 '@mui/system' 导入

import { styled } from '@mui/material/styles';

文档: https://mui.com/system/styled/#import-path

答案#2

theme 的类型是 Theme,这与您可能应该在 ThemeProvider 中声明的类型相同。您可以在官方仓库中这里查看类型声明:https://github.com/mui/material-ui/blob/master/packages/mui-material/src/styles/createTheme.d.ts#L28-L36

正如你所看到的,根据类型声明文件,没有 fTokens,因此抛出了错误。

你想要做的修复方法是从 ThemeProvider 开始,将颜色提供给适当的属性,例如 -- palette,然后你可以使用刚刚添加到 ThemeProvider 的颜色来对 TableRow 进行主题/样式化。

这是示例代码 --

const TableRow = styled(MUITableRow)(({ theme }) => {
  return {
    backgroundColor: theme.fTokens.surfaceHigh
  };
});

export default function App() {
  const outerTheme = createTheme({
    fTokens: { surfaceHigh: orange[500] }
    // palette: { primary: { main: orange[500] } }
  });
  return (
    <div className="App">
      <ThemeProvider theme={outerTheme}>
        <TableRow />
      </ThemeProvider>
    </div>
  );
}

关于 styled 工具的文档在这里:https://mui.com/system/styled/

在 Codesandbox 中的随机测试不会抛出错误(除了 <tr> 不应该是 <div> 的子元素) https://codesandbox.io/s/determined-kowalevski-ppm6zh?file=/src/App.tsx