Переключение тем с использованием модулей Less + CSS в React - PullRequest
7 голосов
/ 17 января 2020

В моем проекте я использую CSS Модули с Меньше, что означает, что я получаю лучшее из обоих миров.

Моя папка src выглядит примерно так:

components/
    [all components]
theme/
    themes/
        lightTheme.less
        darkTheme.less
    palette.less

palette.less :

@import './themes/lightTheme.less';

Затем в каждом компоненте, который хочет использовать цвета из темы, я делаю:

component.module. less :

@import '../../theme/palette.less';

.element {
    background-color: @primary;
}

Эта структура позволяет мне редактировать palette.less для импорта темы, которую я хочу использовать. Дело в том, что Я хочу позволить пользователям выбирать предпочитаемую тему самостоятельно. Темы должны быть переключаемыми во время выполнения, а это значит, что мне нужно как-то скомпилировать обе темы.


Я представляю идеальное решение примерно так:

app.less

body {
    @theme: @light-theme;

    &.dark-theme {
        @theme: @dark-theme;
    }
}

А затем каким-то образом импортировать эту переменную @theme в каждый компонент и прочитать свойства из нее (т. Е. @theme[primary]).

К сожалению, меньшая область видимости переменных не работай так.


Я открыт для любого решения, использующего меньше модулей.

Спасибо!

Ответы [ 2 ]

2 голосов
/ 21 января 2020

Я знаю, что вы, вероятно, ищете решение, которое использует модули Less / CSS, но очень вероятно, что ваша ситуация может быть решена исключительно с помощью переменных css (как Морфеус прокомментировал ваш вопрос) .

Как это будет работать?

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

.awesome-div {
  background-color: #fefefe;
}

У вас будет:

:root {
  --awesome-color: #fefefe;
}

.awesome-div {
  background-color: var(--awesome-color);
}

Переключение между светлым и темным

В этом подходе есть два способа изменения тем:

  • Использование ванильного Js кода в React для обновления элемент :root CSS, проверьте этот codepen для получения дополнительной информации;
  • Просто загрузите компонент, содержащий все новые переменные :root в его компоненте. css file;

В React (также в vanilla CSS) вы можете легко иметь несколько компонентов / элементов, объявляющих свои :root в своих файлах. css.

Кроме того, любой новый :root перезапишет конфликтующие значения из предыдущих :root , Например, если в файле app. css у нас есть :root { --color: red; }, а при загрузке другого компонента, например, компонента A, где в component_a. css мы перезаписываем ту же переменную, например, :root { --color: blue; }, которая отображается в нашем браузеры будут из компонента A.

Следуя этой логике c, у вас может быть фиктивный компонент, который делает и ничего не отображает, но вместо этого в этом компоненте. js файл, который вы импортируете. css темы, например:

import './light.css'; // suppose this is the light-theme dummy component

При переключении тем в вашем приложении вам просто нужно удалить фиктивный компонент из сцены и вызвать другой.

I'm не слишком опытный с codepen, чтобы предоставить вам пример, содержащий импорт / модули там, но я надеюсь, что приведенное выше объяснение может дать вам представление о том, что я имею в виду. Тем не менее, вот краткий псевдокод того, что я собираюсь продемонстрировать:


loadTheme() {
  if (this.state.theme === 'dark') return <LightTheme />;
  if (this.state.theme === 'user-3232') return <UserTheme />;
  return <DarkTheme />;
}

render() {
  return (
    <App>
      {this.loadTheme()}
      <OtherContent>
    </App>
  );
}

0 голосов
/ 24 января 2020

Проверьте стилизованные компоненты, он может это сделать.

https://www.npmjs.com/package/styled-components

https://styled-components.com/docs/advanced#theming

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

...