基于状态在CSS变量之间切换

myzjeezk  于 2022-12-15  发布在  其他
关注(0)|答案(1)|浏览(126)

我正在尝试在我的react应用程序中实现颜色主题,并使用了css-variables,到目前为止,基本的工作已经完成。
不过我也尝试将这个主题应用到一个SVG图标上,这个图标可以根据状态改变颜色,当手机连接到设备上时,它会从灰色变成主题定义的颜色。
我有一个themes.css,看起来像这样:

:root {
    --fillInactive: #7c7c7c;
}

[data-theme='Blue'] {
    --fillHover: #708fa8;
    --fillActive: #3f77a4;
}

[data-theme='Red'] {
    --fillHover: #cd6969;
    --fillActive: #cd2424;

}

[data-theme='Green'] {
    --fillHover: #85b08e;
    --fillActive: #41ad56;
}

[data-theme='White'] {
    --fillHover: #9f9f9f;
    --fillActive: #ffffff;
}

我的topbar.js看起来像这样:

import React from "react";
import { useState, useEffect } from "react";
import "./topbar.scss";
import "../components/themes.scss"

const electron = window.require('electron');
const { ipcRenderer } = electron;

const TopBar = () => {

  const Store = window.require('electron-store');
  const store = new Store();

  const [phoneState, setPhoneState] = useState("#7c7c7c");
  const [theme, setTheme] = useState(store.get("colorTheme"));

  const plugged = () => {
    setPhoneState("#3f77a4");
  }

  const unplugged = () => {
    setPhoneState("#7c7c7c");
  }

  useEffect(() => {
    ipcRenderer.send('statusReq');
    ipcRenderer.on("plugged", plugged);
    ipcRenderer.on("unplugged", unplugged);

    return function cleanup() {
      ipcRenderer.removeListener('plugged',   plugged);
      ipcRenderer.removeListener('unplugged', unplugged);
      
    };
  }, []);

  return (
    <div className="topbar" data-theme={theme}}>
      <div className="topbar__info">
        <svg className="topbar__icon">
          <use xlinkHref="./svg/phone.svg#phone" color={phoneState}></use>
        </svg>
      </div>
    </div>

  );
};

export default TopBar;

我的TopBar.scss看起来像这样:

.topbar {
    display: flex;
    flex-direction: row;
    justify-content: space-between;
    position: absolute;
    top: 0;

    height: 66px;
    width: 100%;
    background: #000000;

    &__info {
      margin-left: 3rem;
    }

    &__icon {
      &__phone {
      }
      margin-top: 1rem;
      margin-right:1rem;
      width:  1rem;
      height: 1rem;
    }
  }

现在我在JS中硬编码了一个蓝色,但是我希望在插入电话时根据所选的主题为SVG设置属性“--fillActive”,当拔出电话时,它应该切换到“--fillInactive”,这样它就会再次变灰。
我希望我的问题足够具体。我试着在谷歌上搜索一个解决方案,但我什至不确定我正在尝试的是正确的方法,因此试图找到一个好的搜索查询是相当困难的。我看到一些解决方案,你可以通过javascript覆盖一个变量。但我希望属性保持原样,我只是在两者之间进行选择,以基于状态设置正确的颜色。
任何帮助或提示都是非常感谢的。

hujrc8aj

hujrc8aj1#

作为一种想法,phoneState可以包含实际的电话状态:插入/拔出:

const [phoneState, setPhoneState] = useState(() => 'unplugged');

然后相应的回调将切换状态:

useEffect(() => {
    ipcRenderer.send('statusReq');
    ipcRenderer.on("plugged", setPhoneState(() => 'plugged'));
    ipcRenderer.on("unplugged", setPhoneState(() => 'unplugged'));

    return function cleanup() { ... },
 []);

在这种情况下,phoneState可用于某个元素的动态类,例如:

return (
    <div className="topbar" data-theme={theme}}>
      <div className={`topbar__info topbar__info--${phoneState}`}>
        <svg className="topbar__icon">
          <use xlinkHref="./svg/phone.svg#phone" ></use>
        </svg>
      </div>
    </div>
  );

然后,当应用css变量时,它们将根据活动主题具有相应的值。

.topbar {
  &__info{
    &--plugged{
      color: var(--fillActive);
    }
    &--unplugged{
      color: var(--fillInactive);
    }
  }
}

相关问题