npm package discovery and stats viewer.

Discover Tips

  • General search

    [free text search, go nuts!]

  • Package details

    pkg:[package-name]

  • User packages

    @[username]

Sponsor

Optimize Toolset

I’ve always been into building performant and accessible sites, but lately I’ve been taking it extremely seriously. So much so that I’ve been building a tool to help me optimize and monitor the sites that I build to make sure that I’m making an attempt to offer the best experience to those who visit them. If you’re into performant, accessible and SEO friendly sites, you might like it too! You can check it out at Optimize Toolset.

About

Hi, 👋, I’m Ryan Hefner  and I built this site for me, and you! The goal of this site was to provide an easy way for me to check the stats on my npm packages, both for prioritizing issues and updates, and to give me a little kick in the pants to keep up on stuff.

As I was building it, I realized that I was actually using the tool to build the tool, and figured I might as well put this out there and hopefully others will find it to be a fast and useful way to search and browse npm packages as I have.

If you’re interested in other things I’m working on, follow me on Twitter or check out the open source projects I’ve been publishing on GitHub.

I am also working on a Twitter bot for this site to tweet the most popular, newest, random packages from npm. Please follow that account now and it will start sending out packages soon–ish.

Open Software & Tools

This site wouldn’t be possible without the immense generosity and tireless efforts from the people who make contributions to the world and share their work via open source initiatives. Thank you 🙏

© 2026 – Pkg Stats / Ryan Hefner

@soybeanjs/theme

v0.50.0-beta.1

Published

A lightweight theme engine for Soybean UI: minimal core tokens, deterministic derivation, and light/dark level offsets.

Readme

@soybeanjs/theme

Soybean UI 的轻量主题引擎:最小核心 token → 确定性派生 → 确定性 CSS 生成 → 运行时注入 / SSR 同步

它不依赖运行时魔法,也不做副作用的 DOM 操作。输入一组 ThemeOptions,输出一段可直接注入的 CSS 字符串,并附带一套可选的持久化 / SSR 工具,供 @soybeanjs/uiSConfigProvider 在运行时注入主题。

特性

  • 最小核心 token:只需 base(中性色)+ primary(主色)两个 Seed,即可派生出完整色板。
  • 确定性派生:亮色 / 暗色模式、lightLevel / darkLevel 偏移、menuColor / menuAccent 均由同一套纯函数生成,结果可复现、可快照测试。
  • 多种输出格式hsloklch,适配不同设计体系。
  • 自定义 preset:既支持内联写入自定义颜色,也支持 { name } 引用持久化表。
  • SSR 友好/ssr 子路径提供 cookie 解析、createThemeInitScriptcreateThemeStore,保证服务端与客户端首帧一致、无闪烁(FOUC)。
  • 零 UI 依赖:纯逻辑 + 单依赖 @soybeanjs/colord,可独立使用。

安装

pnpm add @soybeanjs/theme

快速开始

最直接的使用方式:调用 createTheme 生成 CSS 并注入。

import { createTheme } from '@soybeanjs/theme';

const css = createTheme({
  base: 'zinc',
  primary: 'indigo',
  radius: 'md',
  size: 'md',
  darkSelector: 'class',
  styleTarget: ':root',
  format: 'hsl'
});

// → 返回一段 CSS 字符串,注入到 <style> 即可生效
document.head.insertAdjacentHTML('beforeend', `<style>${css}</style>`);
@soybeanjs/ui 中使用

大多数场景下你不需要手动调用 createThemeSConfigProvider 已内置主题注入,只要你传入 theme 配置即可:

<script setup lang="ts">
import { SConfigProvider } from '@soybeanjs/ui';
</script>

<template>
  <SConfigProvider
    :theme="{
      base: 'zinc',
      primary: 'indigo',
      radius: 'md',
      size: 'md'
    }"
  >
    <slot />
  </SConfigProvider>
</template>

核心概念

Seed 派生

引擎从两个 Seed 出发,派生出完整色板:

  • base:中性色(zinc / neutral / stone …),决定背景、前景、边框、input 等。
  • primary:品牌主色(indigo / blue / emerald …),决定 primary / ring / chart 等强调色。

亮暗偏移

  • lightLevel(0–2):亮色模式表面亮度偏移,数值越大表面越深。
  • darkLevel(0–3):暗色模式背景亮度偏移,数值越大背景越浅。

自定义 preset

两种方式:

// 1) 内联自定义颜色(直接覆盖)
createTheme({
  base: 'zinc',
  primary: 'indigo',
  preset: {
    light: { primary: 'blue.600', ring: 'blue.500' },
    dark: { primary: 'blue.400', ring: 'blue.300' }
  }
});

// 2) 引用持久化 preset(需配合 ConfigProvider 的 persistTheme)
//    引擎内部只消费内联值;{ name } 由 ConfigProvider 解析后再传入。
createTheme({
  base: 'zinc',
  primary: 'indigo',
  preset: { name: 'my-brand' }
});

API 参考

主入口 @soybeanjs/theme

| 导出 | 说明 | | ---------------------------------------------------- | ----------------------------------------------- | | createTheme | 根据 ThemeOptions 生成 CSS 字符串(核心函数) | | DEFAULT_PRESET_OPTIONS | 默认主题选项(zinc / indigo / md / md) | | THEME_SIZE / themeSizeKeys | 尺寸枚举与合法键列表(xs…2xl) | | THEME_RADIUS / themeRadiusKeys | 圆角枚举与合法键列表(2xs…2xl) | | builtinBasePresetKeys / builtinPrimaryPresetKeys | 内置 base / primary 色板键列表 |

类型:ThemeOptionsThemeConfigStateThemeColorThemeSizeThemeRadiusMenuColorMenuAccentCustomThemeColorPresetStoredThemePresetThemePresetInput … 等。

子路径 @soybeanjs/theme/storage

本地存储持久化(localStorage,SSR-safe)。

| 导出 | 说明 | | --------------------------------------------------------------------------- | --------------------------------------------- | | THEME_STORAGE_KEY | 默认主题 localStorage 键(__SOYBEAN_THEME) | | stringifyThemeConfig / parseThemeConfig | 主题配置序列化 / 反序列化(带校验) | | getStoredThemeConfig / setStoredThemeConfig / removeStoredThemeConfig | 主题配置读写 | | THEME_CSS_STORAGE_KEY | 主题 CSS 快照键(__SOYBEAN_THEME_CSS) | | getStoredThemeCss / setStoredThemeCss / removeStoredThemeCss | 主题 CSS 快照读写(供首帧内联脚本使用) | | THEME_PRESETS_STORAGE_KEY | 自定义 preset 表 localStorage 键 | | getStoredThemePresets | 读取 preset 表 | | setStoredThemePreset / removeStoredThemePreset | 增删单个 preset |

子路径 @soybeanjs/theme/ssr

SSR/SSG 兼容工具。

| 导出 | 说明 | | ----------------------- | -------------------------------------------- | | isServerRuntime | 运行时检测服务端(window/document 缺失) | | createThemeInitScript | 生成首帧前内联脚本,避免主题闪烁(FOUC) | | THEME_INIT_STYLE_ID | 首帧注入的 <style> 元素 id |

SSR 指南

1. 客户端首帧前避免闪烁

主题只持久化在 localStorage(不下发 cookie)。服务端首帧渲染默认主题,随后由内联脚本在浏览器首帧前读取 localStorage 并应用,因此无主题闪烁:

<script>
  // 由 createThemeInitScript() 生成,放在 <head> 最前
  // 读取 localStorage 中持久化的主题,把 .dark 类与 data-theme 应用到 <html>
</script>

内联脚本只能直接应用 data-theme 与暗色 class;颜色 / 圆角 / 尺寸等派生 token 无法在脚本里重算。需要连派生 token 也首帧生效时,开启 injectCss:应用会把 createTheme() 生成的 CSS 快照写入 localStorage(SConfigProviderpersistTheme 负责),脚本读取后以 !important 注入 <style id="__SOYBEAN_THEME_INIT">,压过 SSR 渲染的默认主题;客户端应用响应式主题样式后由 SConfigProvider 移除该样式,运行时切换不受影响。

createThemeInitScript({ injectCss: true });

2. 推荐:直接交给 SConfigProvider

上述逻辑在 @soybeanjs/uiSConfigProvider 中已全部封装。应用只需传入环境标志:

<template>
  <SConfigProvider :is-server="import.meta.server" persist-theme>
    <slot />
  </SConfigProvider>
</template>

设置持久化、CSS 注入、暗色 class 切换均由内部完成;如需首帧应用持久化主题,可在 <head> 内联 createThemeInitScript()

@soybeanjs/ui 集成

  • 运行时主题注入入口:SConfigProvider(唯一入口,不额外提供独立 ThemeProvider)。
  • 持久化:设置 persist-theme 后,主题状态写入 localStorage;{ name } 引用解析依赖 persistTheme
  • 主题 UI 消费:在 SConfigProvider 后代中使用 useTheme(来自 @soybeanjs/ui)读取/修改 base / primary / radius / size / mode 与 preset,无需 prop drilling。

目录结构

packages/theme/src/
  index.ts        # 主入口:createTheme + 枚举 + 类型
  core.ts         # createTheme:合并默认值 → 派生 → 生成 CSS
  defaults.ts     # DEFAULT_PRESET_OPTIONS
  preset.ts       # 色板派生(base / primary / feedback / sidebar)
  derive.ts       # 色值派生工具
  css.ts          # CSS 生成(base + color + 调色板)
  tokens.ts       # 尺寸 / 圆角枚举
  variables.ts    # CSS 变量集合
  types.ts        # 全部公开类型
  storage.ts      # /storage:localStorage 持久化
  ssr.ts          # /ssr:服务端工具 + 首帧内联脚本
  shared.ts       # 内部工具(merge / darkSelector)

测试

pnpm --filter @soybeanjs/theme test

覆盖核心派生确定性、级别偏移、SSR 解析、存储读写等,含快照测试。

License

MIT