0.0.1 • Published 2 years ago

sunny-theme-switch v0.0.1

Weekly downloads
-
License
MIT
Repository
-
Last release
2 years ago

sunny-theme-switch

npm version npm downloads license

提供一种可按需加载主题的实践

Installation

使用npm安装

npm i sunny-theme-switch

使用yarn安装

yarn add sunny-theme-switch

使用pnpm安装

pnpm add sunny-theme-switch

Usages

简单的单文件多主题用例

style.scss 样式代码

/**
共有样式
注意:在没有css module样式隔离特性加持下,声明样式的作用域很重要
 */
[data-page='SwitchTheme'] {
  .combined-component {
    color: #000;
  }
}

[data-theme='dark'] {
  [data-page='SwitchTheme'] {
    .combined-component {
      background: #ccc;
    }
  }
}

[data-theme='light'] {
  [data-page='SwitchTheme'] {
    .combined-component {
      background: #a1deff;
    }
  }
}

组件代码

import React, { FC } from 'react'
import { changeTheme } from 'sunny-theme-switch'
import './style.scss'

export const ThemesInOnePlainCssFile: FC = () => {
  return (
    <div data-page="SwitchTheme">
      <div className={'combined-component'}>
        多个主题样式都在一个纯css文件里
      </div>
      切换主题按钮
      <button onClick={() => changeTheme('light')}>
        light theme
      </button>
      <button onClick={() => changeTheme('dark')}>
        dark theme
      </button>
    </div>
  )
}

以上是最简用例所需的代码。

除此之外,还准备了四份用例代码,涵盖常见多主题切换需求

样式书写模式一点建议

针对按需加载场景,对于组件来说如果两种主题代码量并不多,其实也可以选择写到一起。 如果单文件内部是按照共享样式、主题1样式、主题2样式...

// 共享样式
body {
  background-color: grey;
}

// 主题1样式
[data-theme=light] {
  body {
    background-color: lightgrey;
  }
}

// 主题2样式
[data-theme=dark] {
  body {
    background-color: darkgrey;
  }
}

类似这种分开书写的代码组织方式,那么将来也会很方便进行多文件拆分不同主题代码,来切换到按需加载。 例如将前面的单文件示例代码拆分到三个样式文件

style.scss

// 共享样式
body {
  background-color: transparent;
}

style.light.scss

// 主题1样式
[data-theme=light] {
  body {
    background-color: white;
  }
}

style.dark.scss

// 主题2样式
[data-theme=dark] {
  body {
    background-color: black;
  }
}

Roadmap

Browser Compatibility

浏览器兼容性

Changelog

See CHANGELOG.md

Q & A

每个组件都有调用addTheme方法,这些添加进加载队列的css文件加载函数,是如何防止重复加载的?

是通过对类似函数() => import()进行toString()作为键名防止重复添加,通关判断Promise是否已经完成 来防止重复加载。

比较有意思的地方是,不同的组件中某些加载函数源码可能完全相同,但并没有影响彼此。 这是因为webpack在编译后,给每个chunk都建立了唯一id。以下我截取一部分编译后的代码:

var g = {
    light: function() {
        return n.e(20).then(n.t.bind(null, "1srq", 7))
    },
    dark: function() {
        return n.e(19).then(n.t.bind(null, "Le6d", 7))
    }
};

只要引用的文件不是同一个,那么上段编译后的代码里面的hash就是不同的。