vite-plugin-themeshift 0.1.1 → 0.1.2
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/index.d.ts +5 -5
- package/dist/index.js +7 -3
- package/dist/index.js.map +1 -1
- package/package.json +6 -3
- package/readme.md +7 -7
package/dist/index.d.ts
CHANGED
|
@@ -1,13 +1,13 @@
|
|
|
1
1
|
import { Plugin } from 'vite';
|
|
2
2
|
|
|
3
|
-
type
|
|
3
|
+
type ThemeShiftPluginOptions = {
|
|
4
4
|
tokensGlob?: string;
|
|
5
5
|
tokensDir?: string;
|
|
6
6
|
watch?: boolean;
|
|
7
7
|
injectSassTokenFn?: boolean;
|
|
8
|
-
platforms?: Array<
|
|
9
|
-
reloadStrategy?:
|
|
8
|
+
platforms?: Array<'css' | 'scss' | 'meta'>;
|
|
9
|
+
reloadStrategy?: 'hmr' | 'full';
|
|
10
10
|
};
|
|
11
|
-
declare function
|
|
11
|
+
declare function themeShiftPlugin(options?: ThemeShiftPluginOptions): Plugin;
|
|
12
12
|
|
|
13
|
-
export { type
|
|
13
|
+
export { type ThemeShiftPluginOptions, themeShiftPlugin };
|
package/dist/index.js
CHANGED
|
@@ -236,7 +236,7 @@ function makeStyleDictionaryConfig() {
|
|
|
236
236
|
}
|
|
237
237
|
|
|
238
238
|
// src/plugin.ts
|
|
239
|
-
function
|
|
239
|
+
function themeShiftPlugin(options = {}) {
|
|
240
240
|
const tokensDir = options.tokensDir ?? "tokens";
|
|
241
241
|
const watch = options.watch ?? true;
|
|
242
242
|
const injectSassTokenFn = options.injectSassTokenFn ?? true;
|
|
@@ -283,7 +283,11 @@ function styleDictionaryThemeShiftPlugin(options = {}) {
|
|
|
283
283
|
cssOutputFile = null;
|
|
284
284
|
return;
|
|
285
285
|
}
|
|
286
|
-
cssOutputFile = path.resolve(
|
|
286
|
+
cssOutputFile = path.resolve(
|
|
287
|
+
root,
|
|
288
|
+
cssPlatform.buildPath,
|
|
289
|
+
cssFile.destination
|
|
290
|
+
);
|
|
287
291
|
}
|
|
288
292
|
async function tryCssHmrUpdate() {
|
|
289
293
|
if (!server || !cssOutputFile) return false;
|
|
@@ -372,6 +376,6 @@ ${String(err)}`
|
|
|
372
376
|
};
|
|
373
377
|
}
|
|
374
378
|
export {
|
|
375
|
-
|
|
379
|
+
themeShiftPlugin
|
|
376
380
|
};
|
|
377
381
|
//# sourceMappingURL=index.js.map
|
package/dist/index.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../src/plugin.ts","../src/sassTokenInjection.ts","../src/sd.ts"],"sourcesContent":["import path from \"node:path\";\nimport type { Plugin, UserConfig, ViteDevServer } from \"vite\";\n\nimport {\n makeSassTokenInjection,\n mergeScssAdditionalData,\n} from \"./sassTokenInjection\";\nimport { makeStyleDictionaryConfig, registerStyleDictionaryThings } from \"./sd\";\n\nexport type StyleDictionaryThemeShiftPluginOptions = {\n tokensGlob?: string; // default: \"tokens/**/*.json\" (watch uses tokensDir)\n tokensDir?: string; // default: \"tokens\"\n watch?: boolean; // default: true\n injectSassTokenFn?: boolean; // default: true\n platforms?: Array<\"css\" | \"scss\" | \"meta\">; // default: all three\n reloadStrategy?: \"hmr\" | \"full\"; // default: \"hmr\"\n};\n\nexport function styleDictionaryThemeShiftPlugin(\n options: StyleDictionaryThemeShiftPluginOptions = {},\n): Plugin {\n const tokensDir = options.tokensDir ?? \"tokens\";\n const watch = options.watch ?? true;\n const injectSassTokenFn = options.injectSassTokenFn ?? true;\n const platforms = options.platforms ?? [\"css\", \"scss\", \"meta\"];\n const reloadStrategy = options.reloadStrategy ?? \"hmr\";\n\n let root = process.cwd();\n let server: ViteDevServer | null = null;\n let cssOutputFile: string | null = null;\n\n // prevent overlapping builds\n let building: Promise<void> | null = null;\n\n async function buildOnce() {\n if (building) return building;\n\n building = (async () => {\n const imported = await import(\"style-dictionary\");\n const StyleDictionary = (imported as any).default ?? imported;\n\n // register transforms/formats (your code)\n registerStyleDictionaryThings(StyleDictionary);\n\n // build using your config (relative paths resolve from cwd; set cwd to root)\n const config = makeStyleDictionaryConfig();\n setCssOutputFile(config);\n\n const sd = await (typeof StyleDictionary.extend === \"function\"\n ? StyleDictionary.extend(config)\n : new StyleDictionary(config));\n\n // Style Dictionary uses process.cwd() for relative globs/buildPath.\n // We temporarily chdir to Vite root for correctness.\n const prev = process.cwd();\n process.chdir(root);\n try {\n for (const p of platforms) {\n await sd.buildPlatform(p);\n }\n } finally {\n process.chdir(prev);\n }\n })().finally(() => {\n building = null;\n });\n\n return building;\n }\n\n function fullReload() {\n server?.ws.send({ type: \"full-reload\" });\n }\n\n function setCssOutputFile(config: ReturnType<typeof makeStyleDictionaryConfig>) {\n if (!platforms.includes(\"css\")) {\n cssOutputFile = null;\n return;\n }\n const cssPlatform = config.platforms?.css;\n const cssFile = cssPlatform?.files?.[0];\n if (!cssPlatform?.buildPath || !cssFile?.destination) {\n cssOutputFile = null;\n return;\n }\n cssOutputFile = path.resolve(root, cssPlatform.buildPath, cssFile.destination);\n }\n\n async function tryCssHmrUpdate(): Promise<boolean> {\n if (!server || !cssOutputFile) return false;\n const rel = path.relative(root, cssOutputFile);\n if (rel.startsWith(\"..\")) return false;\n const url = \"/\" + rel.split(path.sep).join(\"/\");\n const mod = await server.moduleGraph.getModuleByUrl(url);\n if (!mod) return false;\n server.moduleGraph.invalidateModule(mod);\n server.ws.send({\n type: \"update\",\n updates: [\n {\n type: \"css-update\",\n path: url,\n acceptedPath: url,\n timestamp: Date.now(),\n },\n ],\n });\n return true;\n }\n\n async function notifyTokenOutputsUpdated() {\n if (reloadStrategy === \"full\") {\n fullReload();\n return;\n }\n if (!(await tryCssHmrUpdate())) fullReload();\n }\n\n function isTokenJson(file: string) {\n const rel = path.relative(root, file);\n return rel.startsWith(tokensDir + path.sep) && rel.endsWith(\".json\");\n }\n\n return {\n name: \"vite-plugin-style-dictionary-native\",\n enforce: \"pre\",\n\n config(userConfig): UserConfig {\n if (!injectSassTokenFn) return {};\n\n const injection = makeSassTokenInjection();\n const existing =\n userConfig.css?.preprocessorOptions?.scss?.additionalData;\n const merged = mergeScssAdditionalData(existing, injection);\n\n return {\n css: {\n preprocessorOptions: {\n scss: {\n additionalData: merged,\n },\n },\n },\n };\n },\n\n configResolved(resolved) {\n root = resolved.root;\n },\n\n async buildStart() {\n await buildOnce();\n },\n\n async configureServer(_server) {\n server = _server;\n\n // initial build\n try {\n await buildOnce();\n } catch (err) {\n server.config.logger.error(\n `[style-dictionary] initial build failed:\\n${String(err)}`,\n );\n }\n\n if (!watch) return;\n\n server.watcher.add(path.join(root, tokensDir));\n\n const onChange = async (file: string) => {\n if (!isTokenJson(file)) return;\n try {\n await buildOnce();\n await notifyTokenOutputsUpdated();\n } catch (err) {\n server?.config.logger.error(\n `[style-dictionary] build failed:\\n${String(err)}`,\n );\n }\n };\n\n server.watcher.on(\"add\", onChange);\n server.watcher.on(\"change\", onChange);\n server.watcher.on(\"unlink\", onChange);\n },\n };\n}\n","export function makeSassTokenInjection(): string {\n return (\n `\n@use \"sass:string\";\n\n@function _sd_to_css_var_name($path) {\n $out: \"\";\n @for $i from 1 through string.length($path) {\n $ch: string.slice($path, $i, $i);\n @if $ch == \".\" { $out: $out + \"-\"; }\n @else { $out: $out + $ch; }\n }\n @return \"--\" + $out;\n}\n\n@function token($path) {\n @return var(#{_sd_to_css_var_name($path)});\n}\n`.trim() + \"\\n\"\n );\n}\n\nexport function mergeScssAdditionalData(\n existing: unknown,\n injection: string,\n): string | ((source: string, filename: string) => string) {\n if (typeof existing === \"function\") {\n return (source: string, filename: string) =>\n injection + existing(source, filename);\n }\n if (typeof existing === \"string\") return injection + existing;\n return injection;\n}\n","import type { Config } from \"style-dictionary/types\";\n\nexport function registerStyleDictionaryThings(StyleDictionary: any) {\n // Prevent double-registration in dev (Vite can re-run plugin code)\n if (StyleDictionary.__hd_registered) return;\n StyleDictionary.__hd_registered = true;\n\n /**\n * Attribute transform: tag tokens as themed if their path contains light|dark|print.\n */\n StyleDictionary.registerTransform({\n name: \"attribute/theme\",\n type: \"attribute\",\n transform: (token: any) => {\n const existing = token.attributes ?? {};\n const mode = (token.path ?? []).find(\n (p: string) => p === \"light\" || p === \"dark\" || p === \"print\",\n );\n\n return mode ? { ...existing, theme: mode } : existing;\n },\n });\n\n /**\n * Name transform: drop light|dark|print segments so vars collide intentionally.\n */\n StyleDictionary.registerTransform({\n name: \"name/drop-theme-segment\",\n type: \"name\",\n transform: (token: any) => {\n const path = token.path ?? [];\n const normalizedPath = path.filter(\n (p: string) => p !== \"light\" && p !== \"dark\" && p !== \"print\",\n );\n\n return normalizedPath\n .join(\"-\")\n .replace(/_/g, \"-\")\n .replace(/([a-z0-9])([A-Z])/g, \"$1-$2\")\n .toLowerCase();\n },\n });\n\n /**\n * CSS format: your grouped + modes output (unchanged)\n */\n StyleDictionary.registerFormat({\n name: \"css/variables-modes-grouped\",\n format: ({ dictionary }: any) => {\n const all = dictionary.allTokens ?? [];\n const byName = (a: any, b: any) => a.name.localeCompare(b.name);\n\n const isThemedNamespace = (name: string) =>\n name.startsWith(\"theme-\") ||\n name.startsWith(\"component-\") ||\n name.startsWith(\"message-\") ||\n name.startsWith(\"shadow-\");\n\n const base = all\n .filter((t: any) => !t.attributes?.theme)\n .filter((t: any) => !isThemedNamespace(t.name))\n .sort(byName);\n\n const light = all\n .filter((t: any) => t.attributes?.theme === \"light\")\n .sort(byName);\n const dark = all\n .filter((t: any) => t.attributes?.theme === \"dark\")\n .sort(byName);\n const print = all\n .filter((t: any) => t.attributes?.theme === \"print\")\n .sort(byName);\n\n const getValue = (t: any) => t.value ?? t.$value ?? \"\";\n\n const GROUPS = [\n { label: \"Palette\", match: (n: string) => n.startsWith(\"palette-\") },\n { label: \"Raw colors\", match: (n: string) => n.startsWith(\"color-\") },\n { label: \"Typography\", match: (n: string) => n.startsWith(\"font-\") },\n { label: \"Text styles\", match: (n: string) => n.startsWith(\"text-\") },\n\n { label: \"Theme\", match: (n: string) => n.startsWith(\"theme-\") },\n {\n label: \"Components\",\n match: (n: string) => n.startsWith(\"component-\"),\n },\n { label: \"Messages\", match: (n: string) => n.startsWith(\"message-\") },\n { label: \"Shadows\", match: (n: string) => n.startsWith(\"shadow-\") },\n\n { label: \"Other\", match: (_n: string) => true },\n ];\n\n const groupTokens = (tokens: any[]) => {\n const remaining = [...tokens];\n const sections: { label: string; tokens: any[] }[] = [];\n\n for (const g of GROUPS) {\n const picked = remaining.filter((t) => g.match(t.name));\n if (!picked.length) continue;\n\n for (const t of picked) {\n const idx = remaining.indexOf(t);\n if (idx >= 0) remaining.splice(idx, 1);\n }\n\n sections.push({ label: g.label, tokens: picked.sort(byName) });\n }\n\n return sections;\n };\n\n const render = (tokens: any[]) => {\n const sections = groupTokens(tokens);\n return sections\n .map(\n (s) =>\n ` /* ${s.label} */\\n` +\n s.tokens.map((t) => ` --${t.name}: ${getValue(t)};`).join(\"\\n\"),\n )\n .join(\"\\n\\n\");\n };\n\n const renderLines = (tokens: any[]) =>\n tokens.map((t) => ` --${t.name}: ${getValue(t)};`).join(\"\\n\");\n\n const out: string[] = [];\n\n if (base.length) out.push(`:root {\\n${render(base)}\\n}\\n`);\n if (light.length)\n out.push(`\\n:root[data-theme='light'] {\\n${render(light)}\\n}\\n`);\n if (dark.length)\n out.push(`\\n:root[data-theme='dark'] {\\n${render(dark)}\\n}\\n`);\n\n if (light.length || print.length) {\n const lightVars = light.length ? renderLines(light) : \"\";\n const printVars = print.length ? renderLines(print) : \"\";\n\n out.push(\n `\\n:root[data-theme='print'] {\\n${[lightVars, printVars].filter(Boolean).join(\"\\n\")}\\n}\\n`,\n );\n\n out.push(\n `\\n@media print {\\n :root {\\n${[lightVars, printVars].filter(Boolean).join(\"\\n\")}\\n }\\n}\\n`,\n );\n }\n\n return out.join(\"\");\n },\n });\n\n /**\n * SCSS format: static tokens only (unchanged)\n */\n StyleDictionary.registerFormat({\n name: \"scss/static-tokens\",\n format: ({ dictionary }: any) => {\n const all = dictionary.allTokens ?? [];\n const byName = (a: any, b: any) => a.name.localeCompare(b.name);\n\n const ALLOWED_PREFIXES = [\"radius-\", \"spacing-\", \"font-\", \"text-\"];\n\n const isAllowed = (name: string) =>\n ALLOWED_PREFIXES.some((p) => name.startsWith(p));\n\n const tokens = all\n .filter((t: any) => !t.attributes?.theme)\n .filter((t: any) => isAllowed(t.name))\n .sort(byName);\n\n const toSassVar = (cssName: string) => `$${cssName.replace(/-/g, \"_\")}`;\n\n const lines: string[] = [];\n lines.push(\n \"// Auto-generated by Style Dictionary. Do not edit directly.\",\n );\n lines.push(\"\");\n\n for (const t of tokens) {\n lines.push(`${toSassVar(t.name)}: ${t.value ?? t.$value ?? \"\"};`);\n }\n\n const typography = tokens.filter((t: any) =>\n t.name.startsWith(\"text-style-\"),\n );\n if (typography.length) {\n lines.push(\"\");\n lines.push(\"// Typography mixins\");\n for (const t of typography) {\n const mixinName = t.name.replace(/-/g, \"_\");\n lines.push(`@mixin ${mixinName} {`);\n lines.push(` font: ${t.value ?? t.$value ?? \"\"};`);\n lines.push(\"}\");\n }\n }\n\n lines.push(\"\");\n return lines.join(\"\\n\");\n },\n });\n\n StyleDictionary.registerFormat({\n name: \"token/paths-json\",\n format: ({ dictionary }: any) => {\n const paths = dictionary.allTokens.map((t: any) => t.path.join(\".\"));\n paths.sort();\n return JSON.stringify(paths, null, 2);\n },\n });\n\n StyleDictionary.registerFormat({\n name: \"token/paths-ts\",\n format: ({ dictionary }: any) => {\n const paths = dictionary.allTokens\n .map((t: any) => t.path.join(\".\"))\n .sort();\n return `/* auto-generated */\nexport const tokenPaths = ${JSON.stringify(paths, null, 2)} as const;\nexport type TokenPath = (typeof tokenPaths)[number];\n`;\n },\n });\n}\n\nexport function makeStyleDictionaryConfig(): Config {\n return {\n source: [\"tokens/**/*.json\"],\n\n platforms: {\n css: {\n transformGroup: \"css\",\n transforms: [\n \"attribute/cti\",\n \"attribute/theme\",\n \"name/drop-theme-segment\",\n ],\n buildPath: \"src/css/\",\n files: [\n { destination: \"tokens.css\", format: \"css/variables-modes-grouped\" },\n ],\n },\n\n scss: {\n transformGroup: \"scss\",\n transforms: [\n \"attribute/cti\",\n \"attribute/theme\",\n \"name/drop-theme-segment\",\n ],\n buildPath: \"src/sass/\",\n files: [\n { destination: \"_tokens.static.scss\", format: \"scss/static-tokens\" },\n ],\n },\n\n meta: {\n transforms: [\"attribute/cti\", \"name/kebab\"],\n buildPath: \"src/design-tokens/\",\n files: [\n { destination: \"token-paths.json\", format: \"token/paths-json\" },\n { destination: \"token-paths.ts\", format: \"token/paths-ts\" },\n ],\n },\n },\n };\n}\n"],"mappings":"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","names":["path"]}
|
|
1
|
+
{"version":3,"sources":["../src/plugin.ts","../src/sassTokenInjection.ts","../src/sd.ts"],"sourcesContent":["import path from 'node:path';\nimport type { Plugin, UserConfig, ViteDevServer } from 'vite';\n\nimport {\n makeSassTokenInjection,\n mergeScssAdditionalData,\n} from './sassTokenInjection';\nimport { makeStyleDictionaryConfig, registerStyleDictionaryThings } from './sd';\n\nexport type ThemeShiftPluginOptions = {\n tokensGlob?: string; // default: \"tokens/**/*.json\" (watch uses tokensDir)\n tokensDir?: string; // default: \"tokens\"\n watch?: boolean; // default: true\n injectSassTokenFn?: boolean; // default: true\n platforms?: Array<'css' | 'scss' | 'meta'>; // default: all three\n reloadStrategy?: 'hmr' | 'full'; // default: \"hmr\"\n};\n\nexport function themeShiftPlugin(\n options: ThemeShiftPluginOptions = {}\n): Plugin {\n const tokensDir = options.tokensDir ?? 'tokens';\n const watch = options.watch ?? true;\n const injectSassTokenFn = options.injectSassTokenFn ?? true;\n const platforms = options.platforms ?? ['css', 'scss', 'meta'];\n const reloadStrategy = options.reloadStrategy ?? 'hmr';\n\n let root = process.cwd();\n let server: ViteDevServer | null = null;\n let cssOutputFile: string | null = null;\n\n // prevent overlapping builds\n let building: Promise<void> | null = null;\n\n async function buildOnce() {\n if (building) return building;\n\n building = (async () => {\n const imported = await import('style-dictionary');\n const StyleDictionary = (imported as any).default ?? imported;\n\n // register transforms/formats (your code)\n registerStyleDictionaryThings(StyleDictionary);\n\n // build using your config (relative paths resolve from cwd; set cwd to root)\n const config = makeStyleDictionaryConfig();\n setCssOutputFile(config);\n\n const sd = await (typeof StyleDictionary.extend === 'function'\n ? StyleDictionary.extend(config)\n : new StyleDictionary(config));\n\n // Style Dictionary uses process.cwd() for relative globs/buildPath.\n // We temporarily chdir to Vite root for correctness.\n const prev = process.cwd();\n process.chdir(root);\n try {\n for (const p of platforms) {\n await sd.buildPlatform(p);\n }\n } finally {\n process.chdir(prev);\n }\n })().finally(() => {\n building = null;\n });\n\n return building;\n }\n\n function fullReload() {\n server?.ws.send({ type: 'full-reload' });\n }\n\n function setCssOutputFile(\n config: ReturnType<typeof makeStyleDictionaryConfig>\n ) {\n if (!platforms.includes('css')) {\n cssOutputFile = null;\n return;\n }\n const cssPlatform = config.platforms?.css;\n const cssFile = cssPlatform?.files?.[0];\n if (!cssPlatform?.buildPath || !cssFile?.destination) {\n cssOutputFile = null;\n return;\n }\n cssOutputFile = path.resolve(\n root,\n cssPlatform.buildPath,\n cssFile.destination\n );\n }\n\n async function tryCssHmrUpdate(): Promise<boolean> {\n if (!server || !cssOutputFile) return false;\n const rel = path.relative(root, cssOutputFile);\n if (rel.startsWith('..')) return false;\n const url = '/' + rel.split(path.sep).join('/');\n const mod = await server.moduleGraph.getModuleByUrl(url);\n if (!mod) return false;\n server.moduleGraph.invalidateModule(mod);\n server.ws.send({\n type: 'update',\n updates: [\n {\n type: 'css-update',\n path: url,\n acceptedPath: url,\n timestamp: Date.now(),\n },\n ],\n });\n return true;\n }\n\n async function notifyTokenOutputsUpdated() {\n if (reloadStrategy === 'full') {\n fullReload();\n return;\n }\n if (!(await tryCssHmrUpdate())) fullReload();\n }\n\n function isTokenJson(file: string) {\n const rel = path.relative(root, file);\n return rel.startsWith(tokensDir + path.sep) && rel.endsWith('.json');\n }\n\n return {\n name: 'vite-plugin-style-dictionary-native',\n enforce: 'pre',\n\n config(userConfig): UserConfig {\n if (!injectSassTokenFn) return {};\n\n const injection = makeSassTokenInjection();\n const existing =\n userConfig.css?.preprocessorOptions?.scss?.additionalData;\n const merged = mergeScssAdditionalData(existing, injection);\n\n return {\n css: {\n preprocessorOptions: {\n scss: {\n additionalData: merged,\n },\n },\n },\n };\n },\n\n configResolved(resolved) {\n root = resolved.root;\n },\n\n async buildStart() {\n await buildOnce();\n },\n\n async configureServer(_server) {\n server = _server;\n\n // initial build\n try {\n await buildOnce();\n } catch (err) {\n server.config.logger.error(\n `[style-dictionary] initial build failed:\\n${String(err)}`\n );\n }\n\n if (!watch) return;\n\n server.watcher.add(path.join(root, tokensDir));\n\n const onChange = async (file: string) => {\n if (!isTokenJson(file)) return;\n try {\n await buildOnce();\n await notifyTokenOutputsUpdated();\n } catch (err) {\n server?.config.logger.error(\n `[style-dictionary] build failed:\\n${String(err)}`\n );\n }\n };\n\n server.watcher.on('add', onChange);\n server.watcher.on('change', onChange);\n server.watcher.on('unlink', onChange);\n },\n };\n}\n","export function makeSassTokenInjection(): string {\n return (\n `\n@use \"sass:string\";\n\n@function _sd_to_css_var_name($path) {\n $out: \"\";\n @for $i from 1 through string.length($path) {\n $ch: string.slice($path, $i, $i);\n @if $ch == \".\" { $out: $out + \"-\"; }\n @else { $out: $out + $ch; }\n }\n @return \"--\" + $out;\n}\n\n@function token($path) {\n @return var(#{_sd_to_css_var_name($path)});\n}\n`.trim() + '\\n'\n );\n}\n\nexport function mergeScssAdditionalData(\n existing: unknown,\n injection: string\n): string | ((source: string, filename: string) => string) {\n if (typeof existing === 'function') {\n return (source: string, filename: string) =>\n injection + existing(source, filename);\n }\n if (typeof existing === 'string') return injection + existing;\n return injection;\n}\n","import type { Config } from 'style-dictionary/types';\n\nexport function registerStyleDictionaryThings(StyleDictionary: any) {\n // Prevent double-registration in dev (Vite can re-run plugin code)\n if (StyleDictionary.__hd_registered) return;\n StyleDictionary.__hd_registered = true;\n\n /**\n * Attribute transform: tag tokens as themed if their path contains light|dark|print.\n */\n StyleDictionary.registerTransform({\n name: 'attribute/theme',\n type: 'attribute',\n transform: (token: any) => {\n const existing = token.attributes ?? {};\n const mode = (token.path ?? []).find(\n (p: string) => p === 'light' || p === 'dark' || p === 'print'\n );\n\n return mode ? { ...existing, theme: mode } : existing;\n },\n });\n\n /**\n * Name transform: drop light|dark|print segments so vars collide intentionally.\n */\n StyleDictionary.registerTransform({\n name: 'name/drop-theme-segment',\n type: 'name',\n transform: (token: any) => {\n const path = token.path ?? [];\n const normalizedPath = path.filter(\n (p: string) => p !== 'light' && p !== 'dark' && p !== 'print'\n );\n\n return normalizedPath\n .join('-')\n .replace(/_/g, '-')\n .replace(/([a-z0-9])([A-Z])/g, '$1-$2')\n .toLowerCase();\n },\n });\n\n /**\n * CSS format: your grouped + modes output (unchanged)\n */\n StyleDictionary.registerFormat({\n name: 'css/variables-modes-grouped',\n format: ({ dictionary }: any) => {\n const all = dictionary.allTokens ?? [];\n const byName = (a: any, b: any) => a.name.localeCompare(b.name);\n\n const isThemedNamespace = (name: string) =>\n name.startsWith('theme-') ||\n name.startsWith('component-') ||\n name.startsWith('message-') ||\n name.startsWith('shadow-');\n\n const base = all\n .filter((t: any) => !t.attributes?.theme)\n .filter((t: any) => !isThemedNamespace(t.name))\n .sort(byName);\n\n const light = all\n .filter((t: any) => t.attributes?.theme === 'light')\n .sort(byName);\n const dark = all\n .filter((t: any) => t.attributes?.theme === 'dark')\n .sort(byName);\n const print = all\n .filter((t: any) => t.attributes?.theme === 'print')\n .sort(byName);\n\n const getValue = (t: any) => t.value ?? t.$value ?? '';\n\n const GROUPS = [\n { label: 'Palette', match: (n: string) => n.startsWith('palette-') },\n { label: 'Raw colors', match: (n: string) => n.startsWith('color-') },\n { label: 'Typography', match: (n: string) => n.startsWith('font-') },\n { label: 'Text styles', match: (n: string) => n.startsWith('text-') },\n\n { label: 'Theme', match: (n: string) => n.startsWith('theme-') },\n {\n label: 'Components',\n match: (n: string) => n.startsWith('component-'),\n },\n { label: 'Messages', match: (n: string) => n.startsWith('message-') },\n { label: 'Shadows', match: (n: string) => n.startsWith('shadow-') },\n\n { label: 'Other', match: (_n: string) => true },\n ];\n\n const groupTokens = (tokens: any[]) => {\n const remaining = [...tokens];\n const sections: { label: string; tokens: any[] }[] = [];\n\n for (const g of GROUPS) {\n const picked = remaining.filter((t) => g.match(t.name));\n if (!picked.length) continue;\n\n for (const t of picked) {\n const idx = remaining.indexOf(t);\n if (idx >= 0) remaining.splice(idx, 1);\n }\n\n sections.push({ label: g.label, tokens: picked.sort(byName) });\n }\n\n return sections;\n };\n\n const render = (tokens: any[]) => {\n const sections = groupTokens(tokens);\n return sections\n .map(\n (s) =>\n ` /* ${s.label} */\\n` +\n s.tokens.map((t) => ` --${t.name}: ${getValue(t)};`).join('\\n')\n )\n .join('\\n\\n');\n };\n\n const renderLines = (tokens: any[]) =>\n tokens.map((t) => ` --${t.name}: ${getValue(t)};`).join('\\n');\n\n const out: string[] = [];\n\n if (base.length) out.push(`:root {\\n${render(base)}\\n}\\n`);\n if (light.length)\n out.push(`\\n:root[data-theme='light'] {\\n${render(light)}\\n}\\n`);\n if (dark.length)\n out.push(`\\n:root[data-theme='dark'] {\\n${render(dark)}\\n}\\n`);\n\n if (light.length || print.length) {\n const lightVars = light.length ? renderLines(light) : '';\n const printVars = print.length ? renderLines(print) : '';\n\n out.push(\n `\\n:root[data-theme='print'] {\\n${[lightVars, printVars].filter(Boolean).join('\\n')}\\n}\\n`\n );\n\n out.push(\n `\\n@media print {\\n :root {\\n${[lightVars, printVars].filter(Boolean).join('\\n')}\\n }\\n}\\n`\n );\n }\n\n return out.join('');\n },\n });\n\n /**\n * SCSS format: static tokens only (unchanged)\n */\n StyleDictionary.registerFormat({\n name: 'scss/static-tokens',\n format: ({ dictionary }: any) => {\n const all = dictionary.allTokens ?? [];\n const byName = (a: any, b: any) => a.name.localeCompare(b.name);\n\n const ALLOWED_PREFIXES = ['radius-', 'spacing-', 'font-', 'text-'];\n\n const isAllowed = (name: string) =>\n ALLOWED_PREFIXES.some((p) => name.startsWith(p));\n\n const tokens = all\n .filter((t: any) => !t.attributes?.theme)\n .filter((t: any) => isAllowed(t.name))\n .sort(byName);\n\n const toSassVar = (cssName: string) => `$${cssName.replace(/-/g, '_')}`;\n\n const lines: string[] = [];\n lines.push(\n '// Auto-generated by Style Dictionary. Do not edit directly.'\n );\n lines.push('');\n\n for (const t of tokens) {\n lines.push(`${toSassVar(t.name)}: ${t.value ?? t.$value ?? ''};`);\n }\n\n const typography = tokens.filter((t: any) =>\n t.name.startsWith('text-style-')\n );\n if (typography.length) {\n lines.push('');\n lines.push('// Typography mixins');\n for (const t of typography) {\n const mixinName = t.name.replace(/-/g, '_');\n lines.push(`@mixin ${mixinName} {`);\n lines.push(` font: ${t.value ?? t.$value ?? ''};`);\n lines.push('}');\n }\n }\n\n lines.push('');\n return lines.join('\\n');\n },\n });\n\n StyleDictionary.registerFormat({\n name: 'token/paths-json',\n format: ({ dictionary }: any) => {\n const paths = dictionary.allTokens.map((t: any) => t.path.join('.'));\n paths.sort();\n return JSON.stringify(paths, null, 2);\n },\n });\n\n StyleDictionary.registerFormat({\n name: 'token/paths-ts',\n format: ({ dictionary }: any) => {\n const paths = dictionary.allTokens\n .map((t: any) => t.path.join('.'))\n .sort();\n return `/* auto-generated */\nexport const tokenPaths = ${JSON.stringify(paths, null, 2)} as const;\nexport type TokenPath = (typeof tokenPaths)[number];\n`;\n },\n });\n}\n\nexport function makeStyleDictionaryConfig(): Config {\n return {\n source: ['tokens/**/*.json'],\n\n platforms: {\n css: {\n transformGroup: 'css',\n transforms: [\n 'attribute/cti',\n 'attribute/theme',\n 'name/drop-theme-segment',\n ],\n buildPath: 'src/css/',\n files: [\n { destination: 'tokens.css', format: 'css/variables-modes-grouped' },\n ],\n },\n\n scss: {\n transformGroup: 'scss',\n transforms: [\n 'attribute/cti',\n 'attribute/theme',\n 'name/drop-theme-segment',\n ],\n buildPath: 'src/sass/',\n files: [\n { destination: '_tokens.static.scss', format: 'scss/static-tokens' },\n ],\n },\n\n meta: {\n transforms: ['attribute/cti', 'name/kebab'],\n buildPath: 'src/design-tokens/',\n files: [\n { destination: 'token-paths.json', format: 'token/paths-json' },\n { destination: 'token-paths.ts', format: 'token/paths-ts' },\n ],\n },\n },\n };\n}\n"],"mappings":"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","names":["path"]}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "vite-plugin-themeshift",
|
|
3
|
-
"version": "0.1.
|
|
3
|
+
"version": "0.1.2",
|
|
4
4
|
"description": "Vite plugin that makes using Style Dictionary + SASS easy as pie.",
|
|
5
5
|
"license": "MIT",
|
|
6
6
|
"author": "",
|
|
@@ -24,7 +24,8 @@
|
|
|
24
24
|
"build": "tsup",
|
|
25
25
|
"dev": "tsup --watch",
|
|
26
26
|
"playground": "npm -C playground run dev",
|
|
27
|
-
"prepublishOnly": "npm run build"
|
|
27
|
+
"prepublishOnly": "npm run build",
|
|
28
|
+
"test": "vitest run"
|
|
28
29
|
},
|
|
29
30
|
"peerDependencies": {
|
|
30
31
|
"vite": "^5.0.0 || ^6.0.0 || ^7.0.0"
|
|
@@ -34,7 +35,9 @@
|
|
|
34
35
|
},
|
|
35
36
|
"devDependencies": {
|
|
36
37
|
"@types/node": "^22.0.0",
|
|
38
|
+
"prettier": "^3.8.1",
|
|
37
39
|
"tsup": "^8.0.0",
|
|
38
|
-
"typescript": "^5.4.0"
|
|
40
|
+
"typescript": "^5.4.0",
|
|
41
|
+
"vitest": "^4.0.18"
|
|
39
42
|
}
|
|
40
43
|
}
|
package/readme.md
CHANGED
|
@@ -38,12 +38,12 @@ npm install --save-dev vite-plugin-themeshift style-dictionary sass
|
|
|
38
38
|
|
|
39
39
|
```ts
|
|
40
40
|
// vite.config.ts
|
|
41
|
-
import { defineConfig } from
|
|
42
|
-
import react from
|
|
43
|
-
import {
|
|
41
|
+
import { defineConfig } from 'vite';
|
|
42
|
+
import react from '@vitejs/plugin-react';
|
|
43
|
+
import { themeShiftPlugin } from 'vite-plugin-themeshift';
|
|
44
44
|
|
|
45
45
|
export default defineConfig({
|
|
46
|
-
plugins: [react(),
|
|
46
|
+
plugins: [react(), themeShiftPlugin()],
|
|
47
47
|
});
|
|
48
48
|
```
|
|
49
49
|
|
|
@@ -71,13 +71,13 @@ npm run playground
|
|
|
71
71
|
## Plugin options
|
|
72
72
|
|
|
73
73
|
```ts
|
|
74
|
-
type
|
|
74
|
+
type themeShiftPluginOptions = {
|
|
75
75
|
tokensGlob?: string; // default: "tokens/**/*.json" (watch uses tokensDir)
|
|
76
76
|
tokensDir?: string; // default: "tokens"
|
|
77
77
|
watch?: boolean; // default: true
|
|
78
78
|
injectSassTokenFn?: boolean; // default: true
|
|
79
|
-
platforms?: Array<
|
|
80
|
-
reloadStrategy?:
|
|
79
|
+
platforms?: Array<'css' | 'scss' | 'meta'>; // default: all three
|
|
80
|
+
reloadStrategy?: 'hmr' | 'full'; // default: "hmr"
|
|
81
81
|
};
|
|
82
82
|
```
|
|
83
83
|
|