@feugene/granularity-tokens

中文文档
2.5.0发布于 2026/10/28LicenseRef-Granularity-EUC-1.1TypeScriptES Module零依赖构建来源已验证近 30 天下载 2240

Design tokens and themes of @feugene/granularity: the token registry, theme data by mode and the theme builder.

原始使用文档
文档目录5 节
  1. Что внутри
  2. Реестр и значения
  3. Своя тема
  4. Как подключить
  5. Лицензия

@feugene/granularity-tokens

Словарь токенов и темы дизайн-системы @feugene/granularity: какие токены есть, какие значения у них в каждой теме и режиме, и чем собрать свою тему так, чтобы она не развалилась при следующем выпуске пакета.

Тема здесь — дизайн-язык целиком: примитивы, роли и производные состояния. Светлый и тёмный — её режимы. Что входит в тему, что есть у режима, что такое пара и тема сборки — docs/concepts.md. Пакет не знает о компонентах: его читают ядро, спутники, портал, инструменты и автор своей темы, и никому из них не нужен UI-кит, чтобы узнать цвет роли.

yarn add @feugene/granularity-tokens

Приложению на ядре ставить его отдельно не нужно — он приходит зависимостью @feugene/granularity. Явно он нужен, когда вы собираете свою тему или читаете токены как данные.

Что внутри

ЧтоГдеПодпуть
Реестр без значений: примитивы, роли, формулы производныхtokens/*.json@feugene/granularity-tokens
Каталог тем: id, название, версия, целевые пакеты, режимы, ссылка на дизайн-системуthemes/*/theme.json@feugene/granularity-tokens (grThemeCatalog)
Данные темы со значениями, значениями компонентов и фолбэкамиthemes/<slug>/@feugene/granularity-tokens/themes/<slug>/theme.json; по выбору в рантайме — loadThemeData(id)
Сборка темы и режима: defineTheme, extendMode, createMode, tone, проверкиsrc/theme/@feugene/granularity-tokens/theme
Тема из папки: loadTheme — загрузчик granum и defineThemesrc/theme/node.ts@feugene/granularity-tokens/theme/node
Копия темы: theme:copyscripts/theme-copy.mjsбинарь gr-theme-copy
Подключение готового CSS в браузереsrc/theme/apply.ts@feugene/granularity-tokens/theme/apply

Каталог тем и раскладка папки темы — themes/README.md. Что тема обязана объявить, какие роли где применяются, ловушки контраста, свой режим и своя тема — docs/themes.md. Справочник всех токенов со значениями каждой пары «тема × режим» — docs/tokens.md.

Реестр и значения

Реестр не тащит значений: каталог тем растёт, а бандл того, кто читает имена, — нет. Значения подключаются по требованию.

import { grRoleTokens, type GrThemeData, resolveModes } from '@feugene/granularity-tokens'
import slateData from '@feugene/granularity-tokens/themes/slate/theme.json'

// JSON типизируется по содержимому: `colorScheme` в нём просто строка.
const slate = slateData as GrThemeData
const dark = resolveModes(slate).get('dark')!
const surfaces = grRoleTokens
  .filter(token => token.section === 'Surface roles')
  .map(token => ({ name: token.name, value: dark[token.name.slice(2)] }))

Ключи в данных темы — без -- (gr-bg), как их ждёт granum; в реестре имя полное (--gr-bg).

Тему, которую выбирают в рантайме, — страница показывает значения той темы, что включена сейчас, — грузит loadThemeData: у каждой темы каталога свой чанк, и загружается только запрошенная. Тема не из каталога — отказ со списком тем.

import { loadThemeData, resolveModes } from '@feugene/granularity-tokens'

const clay = await loadThemeData('clay')
const light = resolveModes(clay).get('light')!

Своя тема

Папка темы — исходник темы granum, та же раскладка, что у встроенных: theme.json, root.json, modes/<режим>.json, значения компонентов в components/<пакет>/<Компонент>/. С "extends": "slate" объявляются только отличия, остальное дотягивается из базы и идёт за её правками; копия — gr-theme-copy slate <id> — независима от источника.

import { loadTheme } from '@feugene/granularity-tokens/theme/node'

const brand = loadTheme(new URL('./src/themes/brand/', import.meta.url))

loadTheme проверяет полноту по реестру, контраст по WCAG и различимость тонов в каждом режиме и падает с именем токена и режима — неполная или нечитаемая тема не доезжает до пользователя. В sources он отдаёт прочитанные файлы: правка любого из них обязана пересобрать тему. В extends — тема каталога в цепочке: granum дополняет тему её данными. Результат идёт в themes конфига granum — основной или дополнительной темой. @feugene/granum — необязательная peer-зависимость: её требуют только theme/node и gr-theme-copy.

Режим поверх готового — extendMode (с нуля — createMode), семья ролей тона из одного цвета — tone. Базой может быть режим встроенной темы, { theme, mode } любой темы или другой режим:

import { extendMode, tone } from '@feugene/granularity-tokens/theme'

const surfaces = { '--gr-bg': '#041e2b', '--gr-fg': '#e8f4fa', '--gr-card': '#0a2f42' }

export const ocean = extendMode({
  name: 'ocean',
  base: 'dark',
  tokens: { ...surfaces, ...tone('azure', '#38bdf8', { base: surfaces }) },
})

ocean.definition // → modes.define.ocean записи темы в конфиге granum: extends, colorScheme, только отличия
ocean.fallbacks // → modes.define.ocean.fallbacks: hover и active от ролей режима
ocean.css // CSS под парой slate-ocean — для подключения без granum

Как подключить

Пакет — провайдер granum без компонентов, владелец каталога тем: ядро @feugene/granularity объявляет его зависимостью, и приложению достаточно провайдера ядра. Темы сборки, их режимы и основную тему перечисляет themes конфига granum ([{ theme: '<slug>', modes: ['light', 'dark'] }]); темы по умолчанию у каталога нет, и сборка без themes — ошибка со списком тем. Тема и режим включаются парой data-theme="<slug>-<режим>", переключает их useTheme() ядра. Без granum ядро отдаёт готовый CSS темы — @feugene/granularity/themes/<slug>.css.

Лицензия

LicenseRef-Granularity-EUC-1.1.

版本与发布记录

@feugene/granularity-tokens 共发布 14 个版本,首次发布于 2026/10/20;过去 12 个月发布了 14 个版本。最新版本附带 npm provenance 构建来源证明,可追溯到公开的 CI 构建记录。

版本发布日期距今
2.5.0latest2026/10/2817 天前
2.4.02026/10/2817 天前
2.3.12026/10/2817 天前
2.3.02026/10/2619 天前
2.2.02026/10/2223 天前
2.1.02026/10/2223 天前

关于 @feugene/granularity-tokens 的常见问题

@feugene/granularity-tokens 是什么?

Design tokens and themes of @feugene/granularity: the token registry, theme data by mode and the theme builder.

如何安装 @feugene/granularity-tokens?

在项目目录运行 npm install @feugene/granularity-tokens,或使用 pnpm add / yarn add / bun add。它还提供命令行工具 gr-theme-copy,可以用 npx gr-theme-copy 直接运行。

@feugene/granularity-tokens 支持 TypeScript 吗?

支持。包内自带 TypeScript 类型声明(package.json 声明了 types 入口),安装后即可获得类型提示,无需再安装 @types 包。

@feugene/granularity-tokens 支持 ESM 还是 CommonJS?

以 ES Module 形式发布,推荐使用 import 引入。在 CommonJS 项目中,Node.js 20.19+ / 22.12+ 可以直接 require() 不含顶层 await 的 ES Module,更早的版本需要改用动态 import()。

@feugene/granularity-tokens 需要什么版本的 Node.js?

package.json 的 engines 字段要求 Node.js >=22。版本不符时 npm 默认只给出警告,开启 engine-strict 后会拒绝安装。

@feugene/granularity-tokens 可以商用吗?

@feugene/granularity-tokens 使用 LicenseRef-Granularity-EUC-1.1 许可。声明的许可为 LicenseRef-Granularity-EUC-1.1,请阅读许可原文确认使用条件。以上为概括,不构成法律意见,请以许可原文为准。

@feugene/granularity-tokens 的下载量有多少?

根据 npm 官方下载统计,@feugene/granularity-tokens 在 2026/10/15 – 2026/11/13 这 30 天内被下载 2,240 次,日均约 75 次。下载量会把 CI 构建、镜像同步和作为其他包依赖的安装一并计入,适合横向比较热度,不能直接等同于使用人数。

@feugene/granularity-tokens 还在维护吗?

最新版本 2.5.0 发布于 2026/10/28(17 天前);至今共发布 14 个版本,其中过去 12 个月发布了 14 个;首次发布于 2026/10/20。发布频率只是参考信号:功能稳定的工具可能很少需要更新,建议结合源码仓库的 issue 和提交记录判断。