Reactjs, Material-UI з JSS.
Material-UI – ReactJS‘s фреймворк, що надає готові google рішення для швидкої і досить простий web розробки.
Material-UI досить велика бібліотека, де ключовою частиною react компонентів і стилізації є @material-ui/core (метою її використання повинен бути немаленький проект).
Цей туториал не включає в себе просунуте використання material-ui. Це міні мануал по стилізації компонентів.
Використовувати material компоненти дійсно не складно, але є нюанси використання стилізації. Про це власне і піде мова.
Розглянемо наступне
- JSS і трохи про синтаксис;
- Стилізація класiв react, material компонентів;
- Стилізація функціональних з використанням хуков react, material компонентів;
- Стилізація за допомогою styledComponent react, material компонентів;
- Провайдер theme;
- Перевизначення material компонентів;
1. JSS і трохи про синтаксис
JSS (бібліотека) – стилізація css мовою JavaScript у декларативному стилі вагою в 6кб, без урахування установки плагінів. JSS НЕ компілюється в inline-style і може повторно перевикористовуватися, уникаючи конфліктів, за рахунок генерації унікальних імен класів. Має можливість працювати за допомогою server-side в nodejs і має розширення [.js]. У JSS немає обмеження на установку стилів для псевдо-селектор або псевдо-елементів та подібному. Описується JSS в стилі camelCase. Однією з ключових можливостей JSS – можливість архітектурного підходу в описі стилів.
Так, і ця штука використовується в material-ui за для семантики.
Для того щоб почати використовувати JSS необхідно викликати його певний метод перекинувши в якості аргументу об’єкт стилів, який поверне функцію, викликавши яку ми отримаємо генератор JSS класів, наприклад:
/src/components/JssComponent
JssComponent.js
import React from "react";
import useStyles from "./style";
export default function JssComponent() {
  const classes = useStyles();
  return (
    <div className={classes.root}>
      <h1>That's JssComponent</h1>
      <h2 className="basic_h2">I use JSS</h2>
      <div className={classes.content_div}>
        Any Text
      </div>
    </div>
  );
}
style.js
import { createUseStyles } from "react-jss";
const rootStyle = {
  width: 400,
  border: "1px solid grey",
  margin: "0px auto",
  padding: 15
};
const fontStyle = {
  fontWeight: "bold",
  fontStyle: "italic"
};
const useStyles = createUseStyles({
  root: {
    ...rootStyle,
    "& h1": {
      textAlign: "center",
      color: "purple"
    },
    "& .basic_h2": {
      textAlign: "right",
      color: "green",
      cursor: "pointer",
      "&:hover": {
        color: "purple"
      }
    }
  },
  content_div: {
    textAlign: "justify",
    ...fontStyle
  }
});
export default useStyles;
2. Стилізація класів react, material компонентів
React не відмовився від підтримки написання інтерфейсів на класах. Наступним чином використовуються стилі в класових material компонентів:
/src/components/ClassComponent
ClassComponent.js
import React from "react";
import { withStyles } from "@material-ui/core/styles";
import Button from "@material-ui/core/Button";
import styles from "./style";
class ClassComponent extends React.Component {
  render() {
    const { classes } = this.props;
    return <Button className={classes.button}>ClassComponent</Button>;
  }
}
export default withStyles(styles)(ClassComponent);
style.js
// Простой js объект описывающий стили компонента
const styles = {
    button: {
      backgroundColor: "grey",
      border: 0,
      borderRadius: 3,
      boxShadow: "0 3px 5px 2px",
      color: "black",
      height: 48,
      padding: "0 30px",
      margin: 10
    }
  };
  
  export default styles;
3. Стилізація функціональних material компонентів з використанням хуков react
Починаючи з 16.8 релізу React з’явилася нова можливість в написанні інтерфейсів на хуках:
/src/components/HookComponent
HookComponent.js
import React from "react";
import Button from "@material-ui/core/Button";
import useStyles from "./style";
const HookComponent = props => {
  const classes = useStyles();
  return <Button className={classes.button}>HookComponent</Button>;
};
export default HookComponent;
style.js
// Импортируем метод для создания функции, вызвав которую мы получим функцию для генерации классов 
import { makeStyles } from "@material-ui/core/styles";
const useStyles = makeStyles({
  button: {
    backgroundColor: "grey",
    border: 0,
    borderRadius: 3,
    boxShadow: "0 3px 5px 2px",
    color: "black",
    height: 48,
    padding: "0 30px",
    margin: 10
  }
});
export default useStyles;
4. Стилізація за допомогою styledComponent react, material компонентів
styledComponent – принцип стилізації компонентів без методу, який повертає функцію для генерації класів.
/src/components/StyledComponent
StyledComponent.js
import React from "react";
// Импортируем метод для стилизации любого типа компонентов
import { styled } from "@material-ui/core/styles";
// Предоставляем компонент для стилизации
import Button from "@material-ui/core/Button";
import styles from './style';
// Стилизованный компонент на все времена
const ButtonComponent = styled(Button)({ ...styles });
export default function StyledComponent() {
  return <ButtonComponent>StyledComponent</ButtonComponent>;
}
style.js
const styles = {
    backgroundColor: "grey",
    border: 0,
    borderRadius: 3,
    boxShadow: "0 3px 5px 2px",
    color: "black",
    height: 48,
    padding: "0 30px",
    margin: 10
  };
  export default styles;
5. Провайдер theme.
Theming – це надання дефолтних стилів проекту, або його частини, з огляду на вкладеність компонентів, концептуально схожий з контекстом в React. У material-ui вже є готовий об’єкт theme заданий за замовчуванням, але ви можете створити його самі під свої потреби, попередньо забезпечивши його доступність через provider, таким чином ви надасте функцію з об’єктом theme як аргумент, для методів material з написання стилів, наприклад :
/src/components
App.js
import React from 'react';
import { ThemeProvider } from "@material-ui/core/styles";
import  ThemedComponent from './ThemedComponent/ThemedComponent';
import theme from './theme';
function App() {
  return (
        <ThemeProvider theme={theme}>
          < ThemedComponent />  
        </ThemeProvider>
  );
}
export default App;
theme.js
// Простой js объект дэфолтных стилей
const theme = {
    button: {
      backgroundColor: "grey",
      border: 0,
      borderRadius: 3,
      boxShadow: "0 3px 5px 2px",
      color: "black",
      height: 48,
      padding: "0 30px"
    }
  };
  export default theme;
/src/components/ThemedComponent
ThemedComponent.js
import React from "react";
import useStyles from "./style";
const ThemedComponent = props => {
  const classes = useStyles();
  return <button className={classes.button}>ThemedComponent</button>;
};
export default ThemedComponent;
style.js
// Метод принимает функцию с агрументом theme
import { makeStyles } from "@material-ui/core/styles";
const useStyles = makeStyles(theme => {
  return {
    button: { ...theme.button, margin: 10 }
  };
});
export default useStyles;
6. Перевизначення material компонентів
У material-ui кожному компоненту вже встановлені відповідні стилі, тобто імпорт будь-якого material компонента надасть вже стилізований компонент з наявними класами. Створення theme за допомогою спеціального api material - createMuiTheme можна не тільки надати theme, але і перевизначати задані дефолтні класи material компонентів за допомогою спеціального властивості overrides, наприклад:
/src/components
App.js
import React from 'react';
import { ThemeProvider } from "@material-ui/core/styles";
import CreatedThemeComponent from './CreatedThemeComponent/CreatedThemeComponent';
import createdTheme from './createdTheme';
function App() {
  return (
        <ThemeProvider theme={createdTheme}>
          <CreatedThemeComponent />  
        </ThemeProvider>
  );
}
export default App;
/ src / components
createdTheme.js
import { createMuiTheme } from "@material-ui/core/styles";
const createdTheme = createMuiTheme({
    overrides: {
      MuiButton: {
        root: {
          color: "red",
          border: "1px solid grey",
          margin: 10
        }
      }
    }
  });
  
export default createdTheme;
/src/components/CreatedThemeComponent
CreatedThemeComponent.js
import React from "react";
import { Button } from "@material-ui/core";
const CreatedThemeComponent = props => {
  return <Button>CreatedThemeComponent</Button>;
};
export default CreatedThemeComponent;
підсумки:
- JSS і його особливості;
- JSS стилізація react,materialкомпонентів за рахунокapi material-ui;
Переклад статті “Reactjs, Material-UI with JSS. Краткий гайд“