Reactjs, Material-UI з JSS.

Material-UI – ReactJS‘s фреймворк, що надає готові google рішення для швидкої і досить простий web розробки.

Material-UI досить велика бібліотека, де ключовою частиною react компонентів і стилізації є @material-ui/core (метою її використання повинен бути немаленький проект).

Цей туториал не включає в себе просунуте використання material-ui. Це міні мануал по стилізації компонентів.

Використовувати material компоненти дійсно не складно, але є нюанси використання стилізації. Про це власне і піде мова.

Розглянемо наступне

  1. JSS і трохи про синтаксис;
  2. Стилізація класiв react, material компонентів;
  3. Стилізація функціональних з використанням хуков react, material компонентів;
  4. Стилізація за допомогою styledComponent react, material компонентів;
  5. Провайдер theme;
  6. Перевизначення 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. Краткий гайд