styled-components ? начинаем

Мы собираемся стилизовать базовую программу create react с помощью styled-components, чтобы выглядеть примерно так:

5dwv10zpqa13wb4pr47l

Но во-первых, преамбула✨: у меня всегда были проблемы со стилизацией сайтов, кажется, это один из аспектов начала веб-разработки, о котором упоминают или умалчивают. До декабря прошлого года мне вообще не нравилось что-то стилизовать с помощью CSS, это была, скорее, работа, чем то, что мне нравилось делать.

Это было до тех пор, пока я не начал использовать styled-components, когда я присоединился к проекту сборки для изучения путешествия Chingu (grad.then() (если вам интересно) мы решили использовать пакет CSS-in-JS. Марина, которая была в моей команде, вдохновила меня, глядя, как стилизуются компоненты, и действительно добавила мне уверенность начать использовать styled-components.

я с css раньше
giphy

Я хочу поделиться тем, что я узнал, пройдя через стиль базовой программы React.

В этом сообщении есть некоторые базовые концепции CSS, о которых я не знал до начала работы со стилизованными компонентами, которые, как я считаю, используются для оформления веб-страниц.

Предполагается стиль основного элемента сайта, поэтому, если вы начинаете с чистого полотна, для всех современных веб-браузеров, которые вы добавляете на свой сайт, есть некоторые параметры по умолчанию, например, оставить размер шрифта 16 пикселей (или 1 rem) или box-sizing: border-box; есть несколько пакетов, чтобы позаботиться об этом за вас.

Установите стилизованные компоненты

Хорошо, давайте загрузим базовую программу React, которую вы получаете при использовании Create React App npxесли у вас уже глобально установлена ​​программа Create React App, вы можете использовать команду без нее npx.

npx create-react-app style-with-styled-components
cd style-with-styled-components/
npm i styled-components

Ладно, теперь у нас есть базовая программа, которую мы можем стилизовать, к счастью, Дэн любезно предоставил нам первоначальные стили, и давайте начнем использовать их из стилизованных компонентов.

Способ расположения CRA CSS предусматривает, что у вас будет соответствующий CSS файл для каждого компонента, который может помочь с поддержкой CSS и предоставляет React идею разделить все ваши файлы на составные части.

Мы можем начать с App.js файл и сопровождающий файл App.css файл. Давайте посмотрим на App.js сначала:

import React, { Component } from 'react';
import logo from './logo.svg';
import './App.css';
class App extends Component {
  render() {
    return (
      <div className="App">
        <header className="App-header">
          <img src={logo} className="App-logo" alt="logo" />
          <h1 className="App-title">Welcome to React</h1>
        </header>
        <p className="App-intro">
          To get started, edit <code>src/App.js</code> and save to reload.
        </p>
      </div>
    );
  }
}
export default App;

В styled-components мы создали бы компоненты для каждого из этих элементов, которые заменяют вышеупомянутые className‘s. Ладно, мы можем начать с перемещения наших стилей в компоненты, давайте сначала сделаем один компонент, чтобы иметь представление о том, куда мы идем с этим.

Во-первых, импорт styled в App.js модуль:

import styled from 'styled-components';

Теперь давайте посмотрим <div className="App">, это div верхнего уровня для этого компонента и его я люблю называть оболочкой для компонента. Давайте дадим ему оригинальное название AppWrapper.

Ссылаясь на App.css есть text-align: center; который относится к этому, следовательно:

const AppWrapper = styled.div`
  text-align: center;
`;

Итак, мы определили AppWrapper const как a styled.div а затем обратные галочки внутри задних галочек, мы можем написать любой обычный CSS с тем же синтаксисом CSS, который вы бы использовали в обычном .css файл.

Теперь, когда у нас есть свой AppWrapper мы можем заменить div верхнего уровня на App.js компонент.

import React, { Component } from 'react';
import styled from 'styled-components';
import logo from './logo.svg';
import './App.css';
class App extends Component {
  render() {
    return (
      <AppWrapper>
        <header className="App-header">
          <img src={logo} className="App-logo" alt="logo" />
          <h1 className="App-title">Welcome to React</h1>
        </header>
        <p className="App-intro">
          To get started, edit <code>src/App.js</code> and save to reload.
        </p>
      </AppWrapper>
    );
  }
}
export default App;

стилизованные компоненты все вещи

Итак, давайте сделаем это для остальных четырех классов CSS и посмотрим, я определю их под AppWrapper здесь:

const rotate360 = keyframes`
  from {
    transform: rotate(0deg);
  }
  to {
    transform: rotate(360deg);
  }
`;
const AppLogo = styled.img`
  animation: ${rotate360} infinite 120s linear;
  height: 80px;
`;
const AppHeader = styled.div`
  background-color: #222;
  height: 150px;
  padding: 20px;
  color: white;
`;
const AppTitle = styled.h1`
  font-size: 1.3em;
`;
const AppIntro = styled.p`
  font-size: large;
`;

Итак, сначала мы создали переменную для анимации React svg, вам нужно будет импортировать keyframes помощник из стилизованных компонентов, таких как:

import styled, { keyframes } from 'styled-components';

теперь это можно использовать повсюду App.js компонент, и мы можем добавить на hover селектор любого из наших стилизованных компонентов в этом модуле. Здесь мы собираемся добавить его к AppLogo чтобы сохранить сладкий вращающийся логотип React.

const AppLogo = styled.img`
  animation: ${rotate360} infinite 120s linear;
  height: 80px;
  &:hover {
    animation: ${rotate360} infinite 1.5s linear;
  }
`;

Ладно, наше приложение не должно выглядеть иначе, поскольку мы не добавили в него наши стилизованные компоненты. render() метод, так что давайте сделаем это сейчас.

Давайте также изменим вводный текст. Вы можете добавить обертку для <code> теги что-то вроде:

const CodeWrapper = styled.code`
  font-size: 1.3rem;
`;

Но если вы хотите, вы можете вкладывать селекторы в компонент, например:

const AppIntro = styled.p`
  color: ${props => props.theme.dark};
  font-size: large;
  code {
    font-size: 1.3rem;
  }
`;

Давайте посмотрим на render() метод сейчас…

render() {
  return (
    <AppWrapper>
      <AppHeader>
        <AppLogo src={logo} alt="logo" />
        <AppTitle>Welcome to React</AppTitle>
      </AppHeader>
      <AppIntro>
        Bootstrapped with <code>create-react-app</code>.
      </AppIntro>
      <AppIntro>
        Components styled with <code>styled-components</code>{' '}
        <EmojiWrapper aria-label="nail polish"></EmojiWrapper>
      </AppIntro>
    </AppWrapper>
  )
}

Теперь все классы, которые первоначально использовались в App.js были заменены, поэтому в них нет нужды import './App.css' отображение, удалите это aaaaand! Все еще без изменений!! Это хорошо, потому что сейчас мы заменяем .css файлы для стилизованных компонентов

Прекрасно, теперь мы заменили весь CSS на styled-components, теперь мы можем посмотреть injectGlobal.

Давайте посмотрим, как App.js файл должен выглядеть, прежде чем двигаться дальше:

import React, { Component } from 'react';
import styled, { keyframes } from 'styled-components';
import logo from './logo.svg';

const AppWrapper = styled.div`
  text-align: center;
`;

const rotate360 = keyframes`
  from {
    transform: rotate(0deg);
  }
  to {
    transform: rotate(360deg);
  }
`;

const AppLogo = styled.img`
  animation: ${rotate360} infinite 120s linear;
  height: 80px;
  &:hover {
    animation: ${rotate360} infinite 1.5s linear;
  }
`;

const AppHeader = styled.div`
  background-color: #222;
  height: 12rem;
  padding: 1rem;
  color: white;
`;

const AppTitle = styled.h1`
  font-weight: 900;
`;

const AppIntro = styled.p`
  font-size: large;
  code {
    font-size: 1.3rem;
  }
`;

const EmojiWrapper = styled.span.attrs({
  role: 'img',
})``;

class App extends Component {
  render() {
    return (
      <AppWrapper>
        <AppHeader>
          <AppLogo src={logo} alt="logo" />
          <AppTitle>Welcome to React</AppTitle>
        </AppHeader>
        <AppIntro>
          Bootstrapped with <code>create-react-app</code>.
        </AppIntro>
        <AppIntro>
          Components styled with <code>styled-components</code> <EmojiWrapper aria-label="nail polish" />
        </AppIntro>
      </AppWrapper>
    );
  }
}

export default App;

Стилизуйте тело с помощью injectGlobal.

Для стилизации тела нашей программы React мы сейчас имеем index.css файл, импортируемый в точку монтирования нашей программы в index.js файл.

Для стилизации тела мы можем использовать injectGlobal из styled-components, который добавляет стили непосредственно в таблицу стилей.

Для этого вы вводите injectGolabl именуемый экспорт из styled-components и добавление ваших стилей между задними галочками.

Текущий index.css выглядит так:

body {
  padding: 0;
  margin: 0;
  font-family: sans-serif;
}

Добавим а theme папку в src каталог и добавьте a globalStyle.js файл, где мы можем хранить все наши стили, которые мы хотим использовать во всей программе, сохранение стилей в одном месте упростит изменения.

в src/theme/globalStyle.js нам нужно будет импортировать injectGlobal именуемый экспорт из styled-components и добавить index.css стиле у него:

import { injectGlobal } from 'styled-components';

injectGlobal`
  body {
    padding: 0;
    margin: 0;
    font-family: sans-serif;
  }
`;

Ладно, теперь мы добавляем стиль тела непосредственно к таблице стилей, поэтому нет нужды в index.css сопоставление файлов, находящегося в index.js теперь это должно выглядеть так:

import React from 'react' import ReactDOM from 'react-dom'

import App from './App'

import registerServiceWorker from './registerServiceWorker'

ReactDOM.render(<App />, document.getElementById('root'))

registerServiceWorker()

Мы все еще должны иметь свою красоту sans-serif шрифт продолжается, но давайте добавим немного хорошего Roboto для основного текста и Montserrat для заголовка в нашем globalStyle.js модуль. Мы можем импортировать шрифты Google с помощью @import в injectGlobal и нанесите Roboto на тело:

injectGlobal`
  @import url(‘
 
  body {
    padding: 0;
    margin: 0;
    font-family: Roboto, sans-serif;
  }
`;

Прекрасно, теперь мы можем добавить наш импортированный шрифт для или заголовок программы, и есть возможность, если мы хотим, чтобы все наши <h1>Чтобы использовать тот же шрифт, мы можем добавить его к injectGlobal в нашем globalStyle.js модуль.

injectGlobal`
  @import url(‘
  body {
    padding: 0;
    margin: 0;
    font-family: Roboto, sans-serif;
  }
  h1 {
    font-family: Montserrat;
  }
`;

Тогда мы можем отрегулировать вес на AppTitle компонент:

const AppTitle = styled.h1`
  font-weight: 900;
`;

Чтобы добавить дополнительные стили для таких шрифтов, как Montserrat и Roboto, вы можете указать их в @import url() вы заметите, что Монсеррат имеет :400,900 после этого, определяющий стили обычный (400) и черный (900), вы можете импортировать сколько угодно шрифтов Google (CDN), но чем больше вы импортируете, тем дольше их будет загружаться, если у вас много шрифтов и стилей, которые вы хотите использовать в своей программе, а затем подумайте о том, чтобы добавить их в папку в проекте, например:

import Montserrat from './fonts/Montserrat-Regular.ttf';

injectGlobal`@font-face { font-family: Montserrat; src: url(${Montserrat}); }`;

Тематика

Темы часто используются для изменения внешнего вида множества вещей одновременно. К примеру, у вас может быть ночной и дневной режимы, как в Twitter. Вы также можете создавать свои темы в styled-components.

gwn8czgagns1n1545zgn

Используйте Styled-components ThemeProvider

Теперь скажем, мы хотим иметь несколько компонентов в нашем приложении, которые используют свойство цвета CSS color: #6e27c5 вместо жесткого кодирования через приложение для каждого использующего его компонента мы можем использовать styled-components ThemeProvider.

Для этого нам нужно будет импортировать ThemeProvider именуемый экспорт из styled-components, затем определите a theme объект, где будет жить наш цвет:

export const theme = {
  primary: '#6e27c5',
};

Добавим новое theme к globalStyle модуль, который мы создали раньше.

Чтобы сделать объект темы доступным во всем компоненте программы, мы завернем наш компонент программы в ThemeProvider и импортируйте нашу прекрасную тему для использования в ThemeProvider:

import React, { Component } from 'react';
import styled, { keyframes, ThemeProvider } from 'styled-components';
import logo from './logo.svg';
import { theme } from './theme/globalStyle';

// our styled-components

class App extends Component {
  render() {
    return <ThemeProvider theme={theme}>{/* all children can access the theme object */}</ThemeProvider>;
  }
}
export default App;

Теперь theme свойства можно использовать в качестве пропсов в наших styled-компонентах, давайте изменим background-color: в AppHeader компонент, пока мы это делаем, давайте добавим a dark: #222 собственности на нашу theme объект и использовать его для color свойство:

const AppHeader = styled.div`
  height: 12rem;
  padding: 1rem;
  color: ${props => props.theme.dark};
  background-color: ${props => props.theme.primary};
`;

Теперь мы можем изменить тему нашего приложения глобально

Хорошо, круто, ты можешь сменить тему?

Это то, о чем я думал, и оказывается, вы можете, на это есть отличный ответ Stack Overflow от Макса.

Это заставило меня подумать, можно ли переключаться между темами, а не определять их для разных разделов, как в ответе SO.

Я начал с определения двух тем (с художественными названиями) в globalStyle.js модуль:

export const theme1 = {
  primary: '#ff0198',
  secondary: '#01c1d6',
  danger: '#eb238e',
  light: '#f4f4f4',
  dark: '#222',
};

export const theme2 = {
  primary: '#6e27c5',
  secondary: '#ffb617',
  danger: '#f16623',
  light: '#f4f4f4',
  dark: '#222',
};

Теперь нам нужен способ переключения между ними theme объектов, воспользуемся для них полем выбора, создадим папку компонентов и создадим в ней a ThemeSelect.js компонент, мы можем беспокоиться о рефакторинге App.js компонент, когда меня здесь нет:

ThemeSelect.js

import React from 'react';
import styled from 'styled-components';

const Select = styled.select`
  margin: 2rem 0.5rem;
  padding: 0rem 0.5rem;
  font-family: Roboto;
  font-size: 1rem;
  border: 1px solid ${props => props.theme.light};
  box-shadow: 0px 0px 0px 1px rgba(0, 0, 0, 0.1);
  background: ${props => props.theme.light};
  border-radius: 2px;
`;

export const SelectOpt = styled.option`
  font-family: Roboto;
  font-size: 1rem;
`;

class ThemeSelect extends React.Component {
  render() {
    return (
      <div>
        <Select onChange={e => this.props.handleThemeChange(e)}>
          <SelectOpt value="theme1">Theme 1</SelectOpt>
          <SelectOpt value="theme2">Theme 2</SelectOpt>
        </Select>
      </div>
    );
  }
}

export default ThemeSelect;

Вы, вероятно, заметили onChange={e => this.props.handleThemeChange(e) события, мы собираемся добавить этот метод к App.js вместе с некоторым состоянием для управления выбранной темой.

App.js

import React, { Component } from 'react';
import styled, { keyframes, ThemeProvider } from 'styled-components';

import logo from './logo.svg';

import { theme1, theme2 } from './theme/globalStyle';
import ThemeSelect from './components/ThemeSelect';

// our lovely styled-components here

class App extends Component {
  state = {
    theme: theme1,
  };
  handleThemeChange = e => {
    let theme = e.target.value;
    theme === 'theme1' ? (theme = theme1) : (theme = theme2);
    this.setState({ theme });
  };
  render() {
    return (
      <ThemeProvider theme={this.state.theme}>
        <AppWrapper>
          <AppHeader>
            <AppLogo src={logo} alt="logo" />
            <AppTitle>Welcome to React</AppTitle>
          </AppHeader>
          <AppIntro>
            Bootstrapped with <code>create-react-app</code>.
          </AppIntro>
          <AppIntro>
            Components styled with <code>styled-components</code> <EmojiWrapper aria-label="nail polish" />
          </AppIntro>
          <ThemeSelect handleThemeChange={this.handleThemeChange} />
        </AppWrapper>
      </ThemeProvider>
    );
  }
}

export default App;

Чтобы подытожить то, что мы сделали App.js вот, добавьте некоторое состояние по умолчанию к теме1, где две темы импортируются как именуемые экспорты globalStyle.js модуль.

Добавьте метод для обработки изменений ThemeSelect.js компонент handleThemeChange здесь мы можем переключаться между ними theme объектов.

Давайте попробуем, у нас должна быть возможность переключаться между двумя темами, которые мы сейчас определили.

Расширение стилизованных компонентов

Пока в нашем приложении не так много схожих стилизованных компонентов, но что, если бы мы добавили несколько кнопок…

export const Button = styled.button`
  font-size: 1rem;
  border-radius: 5px;
  padding: 0.25rem 1rem;
  margin: 0 1rem;
  background: transparent;
  color: ${props => props.theme.primary};
  border: 2px solid ${props => props.theme.primary};
  ${props =>
    props.primary &&
    css`
      background: ${props => props.theme.primary};
      color: white;
    `};
`;

Здесь я добавил a Button компонент к globalStyle.js для использования в App.js компонент. Для удобства мы собираемся добавить его сюда. Вы можете обнаружить, что если у вас есть много подобных компонентов, которые вы повторно используете в своей программе, было бы хорошей идеей добавить их все в components папку.

Мы можем импортировать Button как и любой другой компонент и используйте его в модуле, поскольку мы расширяем его, это означает, что нам нужно только применить определенные стили, которые мы хотим для этой кнопки. Но сначала в App.js компонент, мы можем указать обычную и основную кнопку:

<button>Normal Button</button> <button primary>Primary Button</button>

Теперь, чтобы указать другую кнопку с тем же CSS, что и импортируемая кнопка, мы можем расширить ее, как в этом примере, мы сделаем кнопку занимать 40% ширины экрана и сделаем углы более округлыми:

const BigButt = Button.extend`
  height: 3rem;
  font-size: 2rem;
  width: 40vw;
  border-radius: 30px;
`;

Давайте также применим тему для подчеркивания create-react-app и styled-components добавив в an Underline styled-component:

const Underline = styled.span`
  border-bottom: 4px solid ${props => props.theme.secondary};
`;

Теперь мы можем изменить тему и применить ее к нашим компонентам с помощью темы, аккуратно, правда?

Я поместил все примеры, которые мы рассматривали здесь, в рабочий пример, чтобы вы могли поиграть с тематикой и стилизованными компонентами, наслаждайтесь.

Хотите узнать больше?

Отличным ресурсом для того, чтобы начать работу со styled-components, который мне действительно помог, является список воспроизведения Саймона Врахлиотиса egghead.io styled-components, который является отличным основанием для начала работы со styled-components? первый урок предназначен для профессионалов, но другие пока доступны для просмотра бесплатно.

Есть также сообщество spectrum.chat и, конечно, Stack Overflow.

Спасибо, что прочли

Если я что-то пропустил или если у вас есть лучший способ сделать что-нибудь, дайте мне знать.

Найдите меня в Twitter или Ask Me Anything на GitHub.

Вы можете прочесть другие подобные статьи в моем блоге.

Добавить комментарий

Ваш адрес email не будет опубликован.