Как реализовать Material-UI ThemeProvider и WithStyles с использованием Typescript - PullRequest
0 голосов
/ 12 марта 2020

Я все больше разочаровываюсь, поскольку последние пару дней я пытался перенести свое приложение реагирования с javascript на tsx. До сих пор мне нравится проверка типов в tsx, но я не уверен, что библиотека material-ui, несмотря на то, что она объясняет, как использовать ее стили с помощью машинописи.

Я следовал руководству здесь https://material-ui.com/guides/typescript/ к письму и создал тему:

import { createMuiTheme } from "@material-ui/core/styles";

export default function theme() {
  return createMuiTheme({
  palette: {
    primary: {
      main: "#607D8B",
      light: "#CFD8DC",
      dark: "#455A64",
      contrastText: "#FFFFFF"
    },
    secondary: {
      main: "#7C4DFF",
      contrastText: "#212121"
    }
  }
})};

, и я создал стиль:

import { green, red } from "@material-ui/core/colors";
import { createStyles, withStyles } from "@material-ui/core/styles";
import { Theme } from '@material-ui/core';

const useStyles = (theme: Theme) => createStyles({
  root: {
    height: "100vh"
  },
  success: {
    backgroundColor: green[600]
  },
  error: {
    backgroundColor: red[800]
  },
  icon: {
    fontSize: 20
  },
  iconVariant: {
    opacity: 0.9,
    marginRight: theme.spacing(1)
  },
  message: {
    display: "flex",
    alignItems: "center"
  },
  image: {
    backgroundImage: "url(https://source.unsplash.com/8WFnEehJWso)",
    backgroundRepeat: "no-repeat",
    backgroundColor: theme.palette.primary.light,
    backgroundSize: "cover",
    backgroundPosition: "center"
  },
  paper: {
    height: "30vh",
    margin: theme.spacing(1.5, 3),
    display: "flex",
    flexDirection: "column",
    alignItems: "center"
  },
  mui_form: {
    width: "100%",
    marginTop: theme.spacing(1)
  },
  submit: {
    margin: theme.spacing(3, 0, 2)
  },
  card: {
    maxWidth: 600
  },
  media: {
    height: 500
  },
  circle: {
    display: "flex",
    "& > * + *": {
      marginLeft: theme.spacing(2)
    },
    align: "center"
  },
  menuButton: {
    marginRight: theme.spacing(2)
  },
  title: {
    flexGrow: 1,
    alignContent: "center"
  },
  pie: {
    height: 250,
    marginBottom: theme.spacing(2)
  },
  avatar: {
    margin: theme.spacing(1),
    backgroundColor: theme.palette.secondary.main
  },
  muiform: {
    width: "100%", // Fix IE 11 issue.
    marginTop: theme.spacing(1),
    "&:focus": {
      borderColor: "primary.dark"
    }
  },
  muisubmit: {
    margin: theme.spacing(3, 0, 2),
    padding: theme.spacing(3, 2),
    background: "primary.main",
    "&:hover": {
      backgroundColor: "primary.dark"
    }
  },
  login: {
    padding: "0 30px",
    height: 200,
    display: "flex",
    flexDirection: "column",
    justifyContent: "center"
  },
  loginImage: {
    backgroundImage: "url(https://source.unsplash.com/rCbdp8VCYhQ)",
    backgroundRepeat: "no-repeat",
    backgroundSize: "cover",
    backgroundPosition: "center",
    height: "100vh"
  },
  loginSurface: {
    height: "40vh",
    padding: "20px 10px",
    display: "flex",
    flexDirection: "column",
    alignItems: "center",
    background: "black"
  },
  table: {
    minWidth: 650
  }
});

export default withStyles(useStyles);

Затем я попытался реализовать это на компоненте:

import DialogContent from "@material-ui/core/DialogContent";
import DialogContentText from "@material-ui/core/DialogContentText";
import DialogTitle from "@material-ui/core/DialogTitle";
import Slide from "@material-ui/core/Slide";
import Table from "@material-ui/core/Table";
import TableBody from "@material-ui/core/TableBody";
import TableCell from "@material-ui/core/TableCell";
import TableContainer from "@material-ui/core/TableContainer";
import TableHead from "@material-ui/core/TableHead";
import TableRow from "@material-ui/core/TableRow";
import Paper from "@material-ui/core/Paper";
import useStyles from "./useStyles";
import { TransitionProps } from "@material-ui/core/transitions";
import { useTheme } from '@material-ui/core/styles';
import { Theme } from '@material-ui/core';

const Transition = React.forwardRef<unknown, TransitionProps>(
  function Transition(props, ref) {
    return <Slide direction="up" ref={ref} {...props} />;
  }
);

export default function GuidanceDialogue(){
  const theme = useTheme<Theme>();
  const [open, setOpen] = React.useState(false);
  const classes = useStyles(theme);

Тема доступна с помощью useTheme и передается с помощью ThemeProvider в root App. js.

Я получаю сообщение об ошибке:

const classes = useStyles(theme);

Аргумент типа 'Theme' не может быть назначен параметру типа 'ComponentType; } >>. Тип «Theme» нельзя назначить типу «FunctionComponent»; } >>. Тип "Theme" не соответствует подписи "(props: PropsWithChildren;} >>, context ?: any): ReactElement <...> | null'.ts (2345)

Если я приведу тип к следующему:

const classes = useStyles<any>(theme);

Таким образом, я могу видеть, действительно ли ошибка типа является проблемой, или есть другие вещи, происходящие далее упоминается, что свойство className, о котором я говорю, например, classes.table, таблица не существует.

Я очень смущен всем этим, могут ли некоторые помочь!

Ответы [ 2 ]

1 голос
/ 13 марта 2020

Решением было написать следующий файл стилей:

 const useStyles = makeStyles((theme: Theme) => createStyles({
  root: {
0 голосов
/ 12 марта 2020

Документация createStyles, makeStyles

Запустив приведенный ниже код, я не смог воспроизвести ошибку вашего типа.

import { Theme, useTheme, makeStyles } from "@material-ui/core";

const useStyles = makeStyles((theme: Theme) => ({
  root: {}
}));

export default function App() {
  const theme = useTheme<Theme>();
  const classes = useStyles(theme);
  return (
    <div className="App">
      <h1 className={classes.root}>Theme</h1>
    </div>
  );
}

Попробуйте онлайн:

Edit kind-robinson-3j05i

...