tailwind-styled-v4 4.0.0 → 5.0.1
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/CHANGELOG.md +398 -0
- package/LICENSE +21 -0
- package/README.md +532 -0
- package/dist/analyzer.d.mts +114 -0
- package/dist/analyzer.d.ts +114 -0
- package/dist/analyzer.js +1555 -0
- package/dist/analyzer.js.map +1 -0
- package/dist/analyzer.mjs +1544 -0
- package/dist/analyzer.mjs.map +1 -0
- package/dist/animate.d.mts +46 -0
- package/dist/animate.d.ts +41 -112
- package/dist/animate.js +792 -235
- package/dist/animate.js.map +1 -1
- package/dist/animate.mjs +782 -0
- package/dist/animate.mjs.map +1 -0
- package/dist/atomic.d.mts +18 -0
- package/dist/atomic.d.ts +18 -0
- package/dist/atomic.js +191 -0
- package/dist/atomic.js.map +1 -0
- package/dist/atomic.mjs +185 -0
- package/dist/atomic.mjs.map +1 -0
- package/dist/cli.d.mts +1 -0
- package/dist/cli.d.ts +1 -0
- package/dist/cli.js +6063 -0
- package/dist/cli.js.map +1 -0
- package/dist/cli.mjs +6053 -0
- package/dist/cli.mjs.map +1 -0
- package/dist/{compiler.d.cts → compiler.d.mts} +503 -210
- package/dist/compiler.d.ts +503 -210
- package/dist/compiler.js +1549 -566
- package/dist/compiler.js.map +1 -1
- package/dist/{compiler.cjs → compiler.mjs} +1476 -627
- package/dist/compiler.mjs.map +1 -0
- package/dist/dashboard.d.mts +272 -0
- package/dist/dashboard.d.ts +272 -0
- package/dist/dashboard.js +249 -0
- package/dist/dashboard.js.map +1 -0
- package/dist/dashboard.mjs +239 -0
- package/dist/dashboard.mjs.map +1 -0
- package/dist/devtools.js +336 -211
- package/dist/devtools.js.map +1 -1
- package/dist/{devtools.cjs → devtools.mjs} +331 -220
- package/dist/devtools.mjs.map +1 -0
- package/dist/engine.d.mts +84 -0
- package/dist/engine.d.ts +84 -0
- package/dist/engine.js +3014 -0
- package/dist/engine.js.map +1 -0
- package/dist/engine.mjs +3005 -0
- package/dist/engine.mjs.map +1 -0
- package/dist/{index.d.cts → index.d.mts} +75 -4
- package/dist/index.d.ts +75 -4
- package/dist/index.js +1341 -149
- package/dist/index.js.map +1 -1
- package/dist/index.mjs +2162 -0
- package/dist/index.mjs.map +1 -0
- package/dist/liveTokenEngine-DYN3Zale.d.mts +34 -0
- package/dist/liveTokenEngine-DYN3Zale.d.ts +34 -0
- package/dist/next.d.mts +55 -0
- package/dist/next.d.ts +30 -20
- package/dist/next.js +6947 -149
- package/dist/next.js.map +1 -1
- package/dist/next.mjs +7050 -0
- package/dist/next.mjs.map +1 -0
- package/dist/plugin.d.mts +90 -0
- package/dist/plugin.d.ts +90 -0
- package/dist/plugin.js +185 -0
- package/dist/plugin.js.map +1 -0
- package/dist/plugin.mjs +174 -0
- package/dist/plugin.mjs.map +1 -0
- package/dist/pluginRegistry.d.mts +83 -0
- package/dist/pluginRegistry.d.ts +83 -0
- package/dist/pluginRegistry.js +303 -0
- package/dist/pluginRegistry.js.map +1 -0
- package/dist/pluginRegistry.mjs +298 -0
- package/dist/pluginRegistry.mjs.map +1 -0
- package/dist/{preset.d.cts → preset.d.mts} +29 -2
- package/dist/preset.d.ts +29 -2
- package/dist/preset.js +318 -21
- package/dist/preset.js.map +1 -1
- package/dist/preset.mjs +414 -0
- package/dist/preset.mjs.map +1 -0
- package/dist/rspack.d.mts +33 -0
- package/dist/rspack.d.ts +33 -0
- package/dist/rspack.js +55 -0
- package/dist/rspack.js.map +1 -0
- package/dist/rspack.mjs +45 -0
- package/dist/rspack.mjs.map +1 -0
- package/dist/runtime.d.mts +62 -0
- package/dist/runtime.d.ts +62 -0
- package/dist/runtime.js +207 -0
- package/dist/runtime.js.map +1 -0
- package/dist/runtime.mjs +188 -0
- package/dist/runtime.mjs.map +1 -0
- package/dist/runtimeCss.d.mts +65 -0
- package/dist/runtimeCss.d.ts +65 -0
- package/dist/runtimeCss.js +188 -0
- package/dist/runtimeCss.js.map +1 -0
- package/dist/runtimeCss.mjs +173 -0
- package/dist/runtimeCss.mjs.map +1 -0
- package/dist/scanner.d.mts +25 -0
- package/dist/scanner.d.ts +25 -0
- package/dist/scanner.js +717 -0
- package/dist/scanner.js.map +1 -0
- package/dist/scanner.mjs +703 -0
- package/dist/scanner.mjs.map +1 -0
- package/dist/shared.d.mts +85 -0
- package/dist/shared.d.ts +85 -0
- package/dist/shared.js +255 -0
- package/dist/shared.js.map +1 -0
- package/dist/shared.mjs +233 -0
- package/dist/shared.mjs.map +1 -0
- package/dist/storybookAddon.d.mts +108 -0
- package/dist/storybookAddon.d.ts +108 -0
- package/dist/storybookAddon.js +95 -0
- package/dist/storybookAddon.js.map +1 -0
- package/dist/storybookAddon.mjs +88 -0
- package/dist/storybookAddon.mjs.map +1 -0
- package/dist/svelte.d.mts +114 -0
- package/dist/svelte.d.ts +114 -0
- package/dist/svelte.js +67 -0
- package/dist/svelte.js.map +1 -0
- package/dist/svelte.mjs +59 -0
- package/dist/svelte.mjs.map +1 -0
- package/dist/testing.d.mts +185 -0
- package/dist/testing.d.ts +185 -0
- package/dist/testing.js +173 -0
- package/dist/testing.js.map +1 -0
- package/dist/testing.mjs +158 -0
- package/dist/testing.mjs.map +1 -0
- package/dist/{theme.d.cts → theme.d.mts} +18 -11
- package/dist/theme.d.ts +18 -11
- package/dist/theme.js +205 -19
- package/dist/theme.js.map +1 -1
- package/dist/theme.mjs +311 -0
- package/dist/theme.mjs.map +1 -0
- package/dist/types-DXr2PmGP.d.mts +31 -0
- package/dist/types-DXr2PmGP.d.ts +31 -0
- package/dist/vite.d.mts +51 -0
- package/dist/vite.d.ts +35 -6
- package/dist/vite.js +4254 -57
- package/dist/vite.js.map +1 -1
- package/dist/vite.mjs +4281 -0
- package/dist/vite.mjs.map +1 -0
- package/dist/vue.d.mts +89 -0
- package/dist/vue.d.ts +89 -0
- package/dist/vue.js +104 -0
- package/dist/vue.js.map +1 -0
- package/dist/vue.mjs +96 -0
- package/dist/vue.mjs.map +1 -0
- package/package.json +173 -67
- package/dist/animate.cjs +0 -252
- package/dist/animate.cjs.map +0 -1
- package/dist/animate.d.cts +0 -117
- package/dist/astTransform-ua-eapqs.d.cts +0 -41
- package/dist/astTransform-ua-eapqs.d.ts +0 -41
- package/dist/compiler.cjs.map +0 -1
- package/dist/css.cjs +0 -71
- package/dist/css.cjs.map +0 -1
- package/dist/css.d.cts +0 -45
- package/dist/css.d.ts +0 -45
- package/dist/css.js +0 -62
- package/dist/css.js.map +0 -1
- package/dist/devtools.cjs.map +0 -1
- package/dist/index.cjs +0 -1058
- package/dist/index.cjs.map +0 -1
- package/dist/next.cjs +0 -268
- package/dist/next.cjs.map +0 -1
- package/dist/next.d.cts +0 -45
- package/dist/plugins.cjs +0 -396
- package/dist/plugins.cjs.map +0 -1
- package/dist/plugins.d.cts +0 -231
- package/dist/plugins.d.ts +0 -231
- package/dist/plugins.js +0 -381
- package/dist/plugins.js.map +0 -1
- package/dist/preset.cjs +0 -129
- package/dist/preset.cjs.map +0 -1
- package/dist/theme.cjs +0 -154
- package/dist/theme.cjs.map +0 -1
- package/dist/turbopackLoader.cjs +0 -2689
- package/dist/turbopackLoader.cjs.map +0 -1
- package/dist/turbopackLoader.d.cts +0 -22
- package/dist/turbopackLoader.d.ts +0 -22
- package/dist/turbopackLoader.js +0 -2681
- package/dist/turbopackLoader.js.map +0 -1
- package/dist/vite.cjs +0 -105
- package/dist/vite.cjs.map +0 -1
- package/dist/vite.d.cts +0 -22
- package/dist/webpackLoader.cjs +0 -2670
- package/dist/webpackLoader.cjs.map +0 -1
- package/dist/webpackLoader.d.cts +0 -24
- package/dist/webpackLoader.d.ts +0 -24
- package/dist/webpackLoader.js +0 -2662
- package/dist/webpackLoader.js.map +0 -1
- /package/dist/{devtools.d.cts → devtools.d.mts} +0 -0
package/dist/theme.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../../theme/src/index.ts"],"names":[],"mappings":"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","file":"theme.js","sourcesContent":["/**\n * tailwind-styled-v4 — Multi-Theme Engine\n *\n * Enterprise-grade theming. Support light/dark/brand themes dengan\n * CSS variables. Zero runtime overhead — themes di-resolve via CSS.\n *\n * Fitur:\n * - Multiple named themes (light, dark, brand, high-contrast)\n * - CSS variable output (Tailwind v4 compatible)\n * - Theme contract (TypeScript-safe — missing tokens = TS error)\n * - Per-component theme override\n * - White-label ready\n *\n * @example\n * // 1. Define contract\n * const contract = defineThemeContract({\n * colors: { bg: \"\", fg: \"\", primary: \"\", muted: \"\" },\n * font: { sans: \"\", mono: \"\" },\n * })\n *\n * // 2. Create themes\n * const lightTheme = createTheme(contract, \"light\", {\n * colors: { bg: \"#ffffff\", fg: \"#09090b\", primary: \"#3b82f6\", muted: \"#71717a\" },\n * font: { sans: \"InterVariable, sans-serif\", mono: \"JetBrains Mono, monospace\" },\n * })\n *\n * const darkTheme = createTheme(contract, \"dark\", {\n * colors: { bg: \"#09090b\", fg: \"#fafafa\", primary: \"#60a5fa\", muted: \"#a1a1aa\" },\n * font: { sans: \"InterVariable, sans-serif\", mono: \"JetBrains Mono, monospace\" },\n * })\n *\n * // 3. Use tokens in components\n * const Card = tw.div`bg-[var(--colors-bg)] text-[var(--colors-fg)] p-6`\n *\n * // 4. Apply in layout\n * // <html data-theme=\"dark\"> or inject CSS\n */\n\n// ─────────────────────────────────────────────────────────────────────────────\n// Types\n// ─────────────────────────────────────────────────────────────────────────────\n\nexport type TokenMap = Record<string, Record<string, string>>\n\nexport interface ThemeContract<T extends TokenMap> {\n _contract: T\n _vars: ThemeVars<T>\n}\n\nexport type ThemeVars<T extends TokenMap> = {\n [Group in keyof T]: {\n [Token in keyof T[Group]]: string // \"var(--group-token)\"\n }\n}\n\nexport interface Theme<T extends TokenMap> {\n name: string\n contract: ThemeContract<T>\n values: T\n /** CSS string to inject (`:root` or `[data-theme=\"name\"]`) */\n css: string\n /** CSS variables as a flat record */\n vars: Record<string, string>\n /** Apply this theme to an element via data attribute */\n selector: string\n}\n\n// ─────────────────────────────────────────────────────────────────────────────\n// defineThemeContract\n// ─────────────────────────────────────────────────────────────────────────────\n\n/**\n * Define the shape of your theme. All themes must satisfy this contract.\n * Returns typed CSS variable references for use in tw components.\n *\n * @example\n * const contract = defineThemeContract({\n * colors: { bg: \"\", fg: \"\", primary: \"\" },\n * font: { sans: \"\" },\n * })\n *\n * // Use in components:\n * const Card = tw.div`bg-[${contract._vars.colors.bg}]`\n * // → tw.div`bg-[var(--colors-bg)]`\n */\nexport function defineThemeContract<T extends TokenMap>(shape: T): ThemeContract<T> {\n const vars = {} as ThemeVars<T>\n\n for (const group in shape) {\n ;(vars as any)[group] = {}\n for (const token in shape[group]) {\n ;(vars as any)[group][token] = `var(--${group}-${token})`\n }\n }\n\n return { _contract: shape, _vars: vars }\n}\n\n// ─────────────────────────────────────────────────────────────────────────────\n// createTheme\n// ─────────────────────────────────────────────────────────────────────────────\n\n/**\n * Create a typed theme that satisfies a contract.\n *\n * @param contract - Theme contract from defineThemeContract()\n * @param name - Theme name (\"light\", \"dark\", \"brand\", etc.)\n * @param values - Token values (TypeScript enforces completeness)\n * @param asRoot - If true, use :root selector. Default: false (uses [data-theme])\n */\nexport function createTheme<T extends TokenMap>(\n contract: ThemeContract<T>,\n name: string,\n values: T,\n asRoot = false\n): Theme<T> {\n const flatVars: Record<string, string> = {}\n const cssLines: string[] = []\n\n for (const group in values) {\n for (const token in values[group]) {\n const varName = `--${group}-${token}`\n const value = values[group][token]\n flatVars[varName] = value\n cssLines.push(` ${varName}: ${value};`)\n }\n }\n\n const selector = asRoot ? \":root\" : `[data-theme=\"${name}\"]`\n const css = `${selector} {\\n${cssLines.join(\"\\n\")}\\n}`\n\n return {\n name,\n contract,\n values,\n css,\n vars: flatVars,\n selector,\n }\n}\n\n// ─────────────────────────────────────────────────────────────────────────────\n// ThemeRegistry — manage multiple themes\n// ─────────────────────────────────────────────────────────────────────────────\n\nexport class ThemeRegistry {\n private themes = new Map<string, Theme<any>>()\n private defaultTheme: string | null = null\n\n /** Register a theme */\n register<T extends TokenMap>(theme: Theme<T>, isDefault = false): this {\n this.themes.set(theme.name, theme)\n if (isDefault || !this.defaultTheme) {\n this.defaultTheme = theme.name\n }\n return this\n }\n\n /** Get a theme by name */\n get(name: string): Theme<any> | undefined {\n return this.themes.get(name)\n }\n\n /** Get all theme names */\n names(): string[] {\n return Array.from(this.themes.keys())\n }\n\n /**\n * Generate combined CSS for all themes.\n * Inject into <head> or a .css file.\n *\n * @example\n * // In globals.css or layout.tsx\n * const css = registry.generateCss()\n */\n generateCss(): string {\n return Array.from(this.themes.values())\n .map((t) => t.css)\n .join(\"\\n\\n\")\n }\n\n /**\n * Get the CSS for a specific theme only.\n */\n getThemeCss(name: string): string | null {\n return this.themes.get(name)?.css ?? null\n }\n\n /**\n * Inject all theme CSS into document <head> (browser only).\n * Call once on app init.\n */\n inject(styleId = \"__tw_themes\"): void {\n if (typeof document === \"undefined\") return\n\n let style = document.getElementById(styleId) as HTMLStyleElement | null\n if (!style) {\n style = document.createElement(\"style\")\n style.id = styleId\n document.head.appendChild(style)\n }\n style.textContent = this.generateCss()\n }\n\n /**\n * Switch active theme by setting data-theme on <html>.\n */\n apply(name: string, target: HTMLElement = document.documentElement): void {\n if (typeof document === \"undefined\") return\n if (!this.themes.has(name)) {\n console.warn(`[tailwind-styled-v4] Theme \"${name}\" not registered.`)\n return\n }\n target.dataset.theme = name\n }\n\n /**\n * Get current active theme name from data-theme attribute.\n */\n current(target: HTMLElement = document.documentElement): string | null {\n if (typeof document === \"undefined\") return this.defaultTheme\n return target.dataset.theme ?? this.defaultTheme\n }\n}\n\n// ─────────────────────────────────────────────────────────────────────────────\n// Convenience: createMultiTheme — shorthand for common light/dark setup\n// ─────────────────────────────────────────────────────────────────────────────\n\nexport interface MultiThemeConfig<T extends TokenMap> {\n contract: ThemeContract<T>\n light: T\n dark: T\n /** Additional named themes (brand, high-contrast, etc.) */\n extras?: Record<string, T>\n}\n\n/**\n * Create a ThemeRegistry with light/dark + optional extras in one call.\n *\n * @example\n * const { registry, vars } = createMultiTheme({\n * contract: defineThemeContract({\n * colors: { bg: \"\", fg: \"\", primary: \"\", border: \"\" }\n * }),\n * light: {\n * colors: { bg: \"#fff\", fg: \"#09090b\", primary: \"#3b82f6\", border: \"#e5e7eb\" }\n * },\n * dark: {\n * colors: { bg: \"#09090b\", fg: \"#fafafa\", primary: \"#60a5fa\", border: \"#27272a\" }\n * },\n * })\n *\n * // Inject CSS:\n * registry.inject()\n *\n * // Use tokens in components:\n * const Card = tw.div`bg-[${vars.colors.bg}] text-[${vars.colors.fg}]`\n */\nexport function createMultiTheme<T extends TokenMap>(\n config: MultiThemeConfig<T>\n): {\n registry: ThemeRegistry\n vars: ThemeVars<T>\n light: Theme<T>\n dark: Theme<T>\n} {\n const registry = new ThemeRegistry()\n\n const light = createTheme(config.contract, \"light\", config.light, true) // :root\n const dark = createTheme(config.contract, \"dark\", config.dark, false)\n\n registry.register(light, true)\n registry.register(dark)\n\n for (const [name, values] of Object.entries(config.extras ?? {})) {\n registry.register(createTheme(config.contract, name, values as T))\n }\n\n return {\n registry,\n vars: config.contract._vars,\n light,\n dark,\n }\n}\n\n// ─────────────────────────────────────────────────────────────────────────────\n// Design Token Compiler — generate CSS vars from token object\n// (Enterprise feature: sync with Figma variables)\n// ─────────────────────────────────────────────────────────────────────────────\n\nexport interface DesignTokens {\n [path: string]: string | DesignTokens\n}\n\n/**\n * Flatten nested design token object into CSS variables.\n * Supports Figma-style nested tokens.\n *\n * @example\n * compileDesignTokens({\n * color: {\n * brand: { primary: \"#3b82f6\", secondary: \"#6366f1\" },\n * neutral: { 50: \"#fafafa\", 900: \"#09090b\" }\n * },\n * spacing: { base: \"4px\", lg: \"16px\" }\n * })\n * →\n * :root {\n * --color-brand-primary: #3b82f6;\n * --color-brand-secondary: #6366f1;\n * --color-neutral-50: #fafafa;\n * --color-neutral-900: #09090b;\n * --spacing-base: 4px;\n * --spacing-lg: 16px;\n * }\n */\nexport function compileDesignTokens(tokens: DesignTokens, prefix = \"\"): string {\n const vars: string[] = []\n\n function flatten(obj: DesignTokens, path: string) {\n for (const [key, value] of Object.entries(obj)) {\n const varPath = path ? `${path}-${key}` : key\n if (typeof value === \"string\") {\n vars.push(` --${varPath}: ${value};`)\n } else {\n flatten(value as DesignTokens, varPath)\n }\n }\n }\n\n flatten(tokens, prefix)\n return `:root {\\n${vars.join(\"\\n\")}\\n}`\n}\n"]}
|
|
1
|
+
{"version":3,"sources":["../packages/theme/src/liveTokenEngine.ts","../packages/theme/src/native-bridge.ts","../packages/theme/src/index.ts"],"names":["React","createRequire","path","flatVars"],"mappings":"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","file":"theme.js","sourcesContent":["import React from \"react\"\n\nexport type TokenMap = Record<string, string>\nexport type TokenSubscriber = (tokens: TokenMap) => void\n\nexport interface LiveTokenSet {\n vars: Record<string, string>\n get(name: string): string | undefined\n set(name: string, value: string): void\n setAll(tokens: TokenMap): void\n snapshot(): TokenMap\n}\n\nexport interface LiveTokenEngineBridge {\n getToken(name: string): string | undefined\n getTokens(): TokenMap\n setToken(name: string, value: string): void\n applyTokenSet(tokens: TokenMap): void\n subscribeTokens(fn: TokenSubscriber): () => void\n subscribe?(fn: TokenSubscriber): () => void\n}\n\ndeclare global {\n var __TW_TOKEN_ENGINE__: LiveTokenEngineBridge | undefined\n}\n\nlet _currentTokens: TokenMap = {}\nconst _subscribers = new Set<TokenSubscriber>()\nlet _styleEl: HTMLStyleElement | null = null\n\nexport function tokenVar(name: string): string {\n const normalized = name.replace(/[^a-zA-Z0-9-]/g, \"-\").toLowerCase()\n return `--tw-token-${normalized}`\n}\n\nexport function tokenRef(name: string): string {\n return `var(${tokenVar(name)})`\n}\n\nfunction buildRootCss(tokens: TokenMap): string {\n const vars = Object.entries(tokens)\n .map(([name, value]) => ` ${tokenVar(name)}: ${value};`)\n .join(\"\\n\")\n return `:root {\\n${vars}\\n}`\n}\n\nfunction syncStyleEl(): void {\n if (typeof document === \"undefined\") return\n\n if (!_styleEl) {\n _styleEl = document.createElement(\"style\")\n _styleEl.id = \"tw-live-tokens\"\n _styleEl.setAttribute(\"data-tw-tokens\", \"true\")\n document.head.appendChild(_styleEl)\n }\n\n _styleEl.textContent = buildRootCss(_currentTokens)\n}\n\nfunction notifySubscribers(): void {\n const snapshot = { ..._currentTokens }\n for (const subscriber of _subscribers) {\n try {\n subscriber(snapshot)\n } catch {\n // intentionally ignore subscriber errors\n }\n }\n}\n\nexport function liveToken(tokens: TokenMap): LiveTokenSet {\n _currentTokens = { ..._currentTokens, ...tokens }\n syncStyleEl()\n notifySubscribers()\n\n const vars: Record<string, string> = {}\n for (const name of Object.keys(tokens)) {\n vars[name] = tokenRef(name)\n }\n\n return {\n vars,\n get(name) {\n return _currentTokens[name]\n },\n set(name, value) {\n setToken(name, value)\n },\n setAll(nextTokens) {\n setTokens(nextTokens)\n },\n snapshot() {\n return { ..._currentTokens }\n },\n }\n}\n\nexport function setToken(name: string, value: string): void {\n _currentTokens = { ..._currentTokens, [name]: value }\n\n if (typeof document !== \"undefined\") {\n document.documentElement.style.setProperty(tokenVar(name), value)\n }\n\n notifySubscribers()\n}\n\nexport function setTokens(tokens: TokenMap): void {\n _currentTokens = { ..._currentTokens, ...tokens }\n\n if (typeof document !== \"undefined\") {\n const root = document.documentElement\n for (const [name, value] of Object.entries(tokens)) {\n root.style.setProperty(tokenVar(name), value)\n }\n }\n\n notifySubscribers()\n}\n\nexport function applyTokenSet(tokens: TokenMap): void {\n if (typeof document !== \"undefined\") {\n const root = document.documentElement\n for (const name of Object.keys(_currentTokens)) {\n if (!(name in tokens)) {\n root.style.removeProperty(tokenVar(name))\n }\n }\n }\n\n _currentTokens = { ...tokens }\n syncStyleEl()\n notifySubscribers()\n}\n\nexport function getToken(name: string): string | undefined {\n return _currentTokens[name]\n}\n\nexport function getTokens(): TokenMap {\n return { ..._currentTokens }\n}\n\nexport function subscribeTokens(fn: TokenSubscriber): () => void {\n _subscribers.add(fn)\n return () => {\n _subscribers.delete(fn)\n }\n}\n\nexport function generateTokenCssString(): string {\n return buildRootCss(_currentTokens)\n}\n\nexport function createUseTokens() {\n return function useTokens(): TokenMap {\n const [tokens, setTokensState] = React.useState<TokenMap>({ ..._currentTokens })\n\n React.useEffect(() => {\n setTokensState({ ..._currentTokens })\n return subscribeTokens((nextTokens) => setTokensState({ ...nextTokens }))\n }, [])\n\n return tokens\n }\n}\n\nexport const liveTokenEngine: LiveTokenEngineBridge = {\n getToken,\n getTokens,\n setToken,\n applyTokenSet,\n subscribeTokens,\n subscribe: subscribeTokens,\n}\n\nglobalThis.__TW_TOKEN_ENGINE__ = liveTokenEngine\nif (typeof window !== \"undefined\") {\n ;(window as any).__TW_TOKEN_ENGINE__ = liveTokenEngine\n}\n","/**\n * Theme — Rust native bridge\n */\nimport { createRequire } from \"node:module\"\nimport path from \"node:path\"\n\ninterface NativeThemeBinding {\n compileTheme?: (\n tokensJson: string,\n themeName: string,\n prefix: string\n ) => {\n name: string\n selector: string\n css: string\n tokens: Array<{ key: string; cssVar: string; value: string }>\n } | null\n extractCssVars?: (source: string) => string[] | null\n}\n\nlet _binding: NativeThemeBinding | null | undefined\n\nexport function getNativeThemeBinding(): NativeThemeBinding | null {\n if (_binding !== undefined) return _binding\n if (process.env.TWS_NO_NATIVE === \"1\" || process.env.TWS_NO_RUST === \"1\") {\n return (_binding = null)\n }\n const runtimeDir = typeof __dirname === \"string\" ? __dirname : process.cwd()\n const req =\n typeof require === \"function\" ? require : createRequire(path.join(runtimeDir, \"noop.cjs\"))\n const candidates = [\n path.resolve(process.cwd(), \"native\", \"tailwind_styled_parser.node\"),\n path.resolve(runtimeDir, \"..\", \"..\", \"..\", \"native\", \"tailwind_styled_parser.node\"),\n ]\n for (const c of candidates) {\n try {\n const mod = req(c) as NativeThemeBinding\n if (mod?.compileTheme) return (_binding = mod)\n } catch {\n /* next */\n }\n }\n return (_binding = null)\n}\n","/**\n * tailwind-styled-v5 — Multi-Theme Engine + Live Token Engine\n *\n * Enterprise-grade theming. Support light/dark/brand themes dengan\n * CSS variables. Zero runtime overhead — themes di-resolve via CSS.\n *\n * Live token engine provides runtime token state management with\n * CSS variable sync to document root.\n *\n * Fitur:\n * - Multiple named themes (light, dark, brand, high-contrast)\n * - CSS variable output (Tailwind v4 compatible)\n * - Theme contract (TypeScript-safe — missing tokens = TS error)\n * - Per-component theme override\n * - White-label ready\n * - Live token engine (runtime token state + CSS sync)\n *\n * @example\n * // 1. Define contract\n * const contract = defineThemeContract({\n * colors: { bg: \"\", fg: \"\", primary: \"\", muted: \"\" },\n * font: { sans: \"\", mono: \"\" },\n * })\n *\n * // 2. Create themes\n * const lightTheme = createTheme(contract, \"light\", {\n * colors: { bg: \"#ffffff\", fg: \"#09090b\", primary: \"#3b82f6\", muted: \"#71717a\" },\n * font: { sans: \"InterVariable, sans-serif\", mono: \"JetBrains Mono, monospace\" },\n * })\n *\n * const darkTheme = createTheme(contract, \"dark\", {\n * colors: { bg: \"#09090b\", fg: \"#fafafa\", primary: \"#60a5fa\", muted: \"#a1a1aa\" },\n * font: { sans: \"InterVariable, sans-serif\", mono: \"JetBrains Mono, monospace\" },\n * })\n *\n * // 3. Use tokens in components\n * const Card = tw.div`bg-[var(--colors-bg)] text-[var(--colors-fg)] p-6`\n *\n * // 4. Apply in layout\n * // <html data-theme=\"dark\"> or inject CSS\n */\n\n// ─────────────────────────────────────────────────────────────────────────────\n// Live Token Engine exports\n// ─────────────────────────────────────────────────────────────────────────────\n\nexport type {\n LiveTokenEngineBridge,\n LiveTokenSet,\n TokenMap,\n TokenSubscriber,\n} from \"./liveTokenEngine\"\nexport {\n applyTokenSet,\n createUseTokens,\n generateTokenCssString,\n getToken,\n getTokens,\n liveToken,\n liveTokenEngine,\n setToken,\n setTokens,\n subscribeTokens,\n tokenRef,\n tokenVar,\n} from \"./liveTokenEngine\"\n\n// ─────────────────────────────────────────────────────────────────────────────\n// Theme types\n// ─────────────────────────────────────────────────────────────────────────────\n\nimport { getNativeThemeBinding } from \"./native-bridge\"\n\n// ThemeTokenMap untuk theming (grouped tokens seperti { colors: { bg: \"#fff\" } })\nexport type ThemeTokenMap = Record<string, Record<string, string>>\n\nexport interface ThemeContract<T extends ThemeTokenMap> {\n _contract: T\n _vars: ThemeVars<T>\n}\n\nexport type ThemeVars<T extends ThemeTokenMap> = {\n [Group in keyof T]: {\n [Token in keyof T[Group]]: string // \"var(--group-token)\"\n }\n}\n\nexport interface Theme<T extends ThemeTokenMap> {\n name: string\n contract: ThemeContract<T>\n values: T\n /** CSS string to inject (`:root` or `[data-theme=\"name\"]`) */\n css: string\n /** CSS variables as a flat record */\n vars: Record<string, string>\n /** Apply this theme to an element via data attribute */\n selector: string\n}\n\n// ─────────────────────────────────────────────────────────────────────────────\n// defineThemeContract\n// ─────────────────────────────────────────────────────────────────────────────\n\n/**\n * Define the shape of your theme. All themes must satisfy this contract.\n * Returns typed CSS variable references for use in tw components.\n *\n * @example\n * const contract = defineThemeContract({\n * colors: { bg: \"\", fg: \"\", primary: \"\" },\n * font: { sans: \"\" },\n * })\n *\n * // Use in components:\n * const Card = tw.div`bg-[${contract._vars.colors.bg}]`\n * // → tw.div`bg-[var(--colors-bg)]`\n */\nexport function defineThemeContract<T extends ThemeTokenMap>(shape: T): ThemeContract<T> {\n const vars = {} as ThemeVars<T>\n\n for (const group in shape) {\n ;(vars as any)[group] = {}\n for (const token in shape[group]) {\n ;(vars as any)[group][token] = `var(--${group}-${token})`\n }\n }\n\n return { _contract: shape, _vars: vars }\n}\n\n// ─────────────────────────────────────────────────────────────────────────────\n// createTheme\n// ─────────────────────────────────────────────────────────────────────────────\n\n/**\n * Create a typed theme that satisfies a contract.\n *\n * @param contract - Theme contract from defineThemeContract()\n * @param name - Theme name (\"light\", \"dark\", \"brand\", etc.)\n * @param values - Token values (TypeScript enforces completeness)\n * @param asRoot - If true, use :root selector. Default: false (uses [data-theme])\n */\nexport function createTheme<T extends ThemeTokenMap>(\n contract: ThemeContract<T>,\n name: string,\n values: T,\n asRoot = false\n): Theme<T> {\n // ── Rust fast-path ─────────────────────────────────────────────────────────\n const native = getNativeThemeBinding()\n if (native?.compileTheme) {\n const result = native.compileTheme(JSON.stringify(values), asRoot ? \"light\" : name, \"\")\n if (result) {\n const flatVars: Record<string, string> = {}\n for (const token of result.tokens) {\n flatVars[token.cssVar] = token.value\n }\n return { name, contract, values, css: result.css, vars: flatVars, selector: result.selector }\n }\n }\n\n // ── JS fallback ────────────────────────────────────────────────────────────\n const flatVars: Record<string, string> = {}\n const cssLines: string[] = []\n\n for (const group in values) {\n for (const token in values[group]) {\n const varName = `--${group}-${token}`\n const value = values[group][token]\n flatVars[varName] = value\n cssLines.push(` ${varName}: ${value};`)\n }\n }\n\n const selector = asRoot ? \":root\" : `[data-theme=\"${name}\"]`\n const css = `${selector} {\\n${cssLines.join(\"\\n\")}\\n}`\n\n return { name, contract, values, css, vars: flatVars, selector }\n}\n\n// ─────────────────────────────────────────────────────────────────────────────\n// ThemeRegistry — manage multiple themes\n// ─────────────────────────────────────────────────────────────────────────────\n\nexport class ThemeRegistry {\n private themes = new Map<string, Theme<any>>()\n private defaultTheme: string | null = null\n\n /** Register a theme */\n register<T extends ThemeTokenMap>(theme: Theme<T>, isDefault = false): this {\n this.themes.set(theme.name, theme)\n if (isDefault || !this.defaultTheme) {\n this.defaultTheme = theme.name\n }\n return this\n }\n\n /** Get a theme by name */\n get(name: string): Theme<any> | undefined {\n return this.themes.get(name)\n }\n\n /** Get all theme names */\n names(): string[] {\n return Array.from(this.themes.keys())\n }\n\n /**\n * Generate combined CSS for all themes.\n * Inject into <head> or a .css file.\n *\n * @example\n * // In globals.css or layout.tsx\n * const css = registry.generateCss()\n */\n generateCss(): string {\n return Array.from(this.themes.values())\n .map((t) => t.css)\n .join(\"\\n\\n\")\n }\n\n /**\n * Get the CSS for a specific theme only.\n */\n getThemeCss(name: string): string | null {\n return this.themes.get(name)?.css ?? null\n }\n\n /**\n * Inject all theme CSS into document <head> (browser only).\n * Call once on app init.\n */\n inject(styleId = \"__tw_themes\"): void {\n if (typeof document === \"undefined\") return\n\n let style = document.getElementById(styleId) as HTMLStyleElement | null\n if (!style) {\n style = document.createElement(\"style\")\n style.id = styleId\n document.head.appendChild(style)\n }\n style.textContent = this.generateCss()\n }\n\n /**\n * Switch active theme by setting data-theme on <html>.\n */\n apply(name: string, target: HTMLElement = document.documentElement): void {\n if (typeof document === \"undefined\") return\n if (!this.themes.has(name)) {\n console.warn(`[tailwind-styled-v4] Theme \"${name}\" not registered.`)\n return\n }\n target.dataset.theme = name\n }\n\n /**\n * Get current active theme name from data-theme attribute.\n */\n current(target: HTMLElement = document.documentElement): string | null {\n if (typeof document === \"undefined\") return this.defaultTheme\n return target.dataset.theme ?? this.defaultTheme\n }\n}\n\n// ─────────────────────────────────────────────────────────────────────────────\n// Convenience: createMultiTheme — shorthand for common light/dark setup\n// ─────────────────────────────────────────────────────────────────────────────\n\nexport interface MultiThemeConfig<T extends ThemeTokenMap> {\n contract: ThemeContract<T>\n light: T\n dark: T\n /** Additional named themes (brand, high-contrast, etc.) */\n extras?: Record<string, T>\n}\n\n/**\n * Create a ThemeRegistry with light/dark + optional extras in one call.\n *\n * @example\n * const { registry, vars } = createMultiTheme({\n * contract: defineThemeContract({\n * colors: { bg: \"\", fg: \"\", primary: \"\", border: \"\" }\n * }),\n * light: {\n * colors: { bg: \"#fff\", fg: \"#09090b\", primary: \"#3b82f6\", border: \"#e5e7eb\" }\n * },\n * dark: {\n * colors: { bg: \"#09090b\", fg: \"#fafafa\", primary: \"#60a5fa\", border: \"#27272a\" }\n * },\n * })\n *\n * // Inject CSS:\n * registry.inject()\n *\n * // Use tokens in components:\n * const Card = tw.div`bg-[${vars.colors.bg}] text-[${vars.colors.fg}]`\n */\nexport function createMultiTheme<T extends ThemeTokenMap>(\n config: MultiThemeConfig<T>\n): {\n registry: ThemeRegistry\n vars: ThemeVars<T>\n light: Theme<T>\n dark: Theme<T>\n} {\n const registry = new ThemeRegistry()\n\n const light = createTheme(config.contract, \"light\", config.light, true) // :root\n const dark = createTheme(config.contract, \"dark\", config.dark, false)\n\n registry.register(light, true)\n registry.register(dark)\n\n for (const [name, values] of Object.entries(config.extras ?? {})) {\n registry.register(createTheme(config.contract, name, values as T))\n }\n\n return {\n registry,\n vars: config.contract._vars,\n light,\n dark,\n }\n}\n\n// ─────────────────────────────────────────────────────────────────────────────\n// Design Token Compiler — generate CSS vars from token object\n// (Enterprise feature: sync with Figma variables)\n// ─────────────────────────────────────────────────────────────────────────────\n\nexport interface DesignTokens {\n [path: string]: string | DesignTokens\n}\n\n/**\n * Flatten nested design token object into CSS variables.\n * Supports Figma-style nested tokens.\n *\n * @example\n * compileDesignTokens({\n * color: {\n * brand: { primary: \"#3b82f6\", secondary: \"#6366f1\" },\n * neutral: { 50: \"#fafafa\", 900: \"#09090b\" }\n * },\n * spacing: { base: \"4px\", lg: \"16px\" }\n * })\n * →\n * :root {\n * --color-brand-primary: #3b82f6;\n * --color-brand-secondary: #6366f1;\n * --color-neutral-50: #fafafa;\n * --color-neutral-900: #09090b;\n * --spacing-base: 4px;\n * --spacing-lg: 16px;\n * }\n */\nexport function compileDesignTokens(tokens: DesignTokens, prefix = \"\"): string {\n // ── Rust fast-path ─────────────────────────────────────────────────────────\n const native = getNativeThemeBinding()\n if (native?.compileTheme) {\n const result = native.compileTheme(JSON.stringify(tokens), \"default\", prefix)\n if (result) return result.css\n }\n\n // ── JS fallback ────────────────────────────────────────────────────────────\n const vars: string[] = []\n\n function flatten(obj: DesignTokens, path: string) {\n for (const [key, value] of Object.entries(obj)) {\n const varPath = path ? `${path}-${key}` : key\n if (typeof value === \"string\") {\n vars.push(` --${varPath}: ${value};`)\n } else {\n flatten(value as DesignTokens, varPath)\n }\n }\n }\n\n flatten(tokens, prefix)\n return `:root {\\n${vars.join(\"\\n\")}\\n}`\n}\n"]}
|
package/dist/theme.mjs
ADDED
|
@@ -0,0 +1,311 @@
|
|
|
1
|
+
import React from 'react';
|
|
2
|
+
import { createRequire } from 'module';
|
|
3
|
+
import path from 'path';
|
|
4
|
+
|
|
5
|
+
/* tailwind-styled-v4 v5.0.1 | MIT | https://github.com/dictionar32/tailwind-styled-v4 */
|
|
6
|
+
var __require = /* @__PURE__ */ ((x) => typeof require !== "undefined" ? require : typeof Proxy !== "undefined" ? new Proxy(x, {
|
|
7
|
+
get: (a, b) => (typeof require !== "undefined" ? require : a)[b]
|
|
8
|
+
}) : x)(function(x) {
|
|
9
|
+
if (typeof require !== "undefined") return require.apply(this, arguments);
|
|
10
|
+
throw Error('Dynamic require of "' + x + '" is not supported');
|
|
11
|
+
});
|
|
12
|
+
var _currentTokens = {};
|
|
13
|
+
var _subscribers = /* @__PURE__ */ new Set();
|
|
14
|
+
var _styleEl = null;
|
|
15
|
+
function tokenVar(name) {
|
|
16
|
+
const normalized = name.replace(/[^a-zA-Z0-9-]/g, "-").toLowerCase();
|
|
17
|
+
return `--tw-token-${normalized}`;
|
|
18
|
+
}
|
|
19
|
+
function tokenRef(name) {
|
|
20
|
+
return `var(${tokenVar(name)})`;
|
|
21
|
+
}
|
|
22
|
+
function buildRootCss(tokens) {
|
|
23
|
+
const vars = Object.entries(tokens).map(([name, value]) => ` ${tokenVar(name)}: ${value};`).join("\n");
|
|
24
|
+
return `:root {
|
|
25
|
+
${vars}
|
|
26
|
+
}`;
|
|
27
|
+
}
|
|
28
|
+
function syncStyleEl() {
|
|
29
|
+
if (typeof document === "undefined") return;
|
|
30
|
+
if (!_styleEl) {
|
|
31
|
+
_styleEl = document.createElement("style");
|
|
32
|
+
_styleEl.id = "tw-live-tokens";
|
|
33
|
+
_styleEl.setAttribute("data-tw-tokens", "true");
|
|
34
|
+
document.head.appendChild(_styleEl);
|
|
35
|
+
}
|
|
36
|
+
_styleEl.textContent = buildRootCss(_currentTokens);
|
|
37
|
+
}
|
|
38
|
+
function notifySubscribers() {
|
|
39
|
+
const snapshot = { ..._currentTokens };
|
|
40
|
+
for (const subscriber of _subscribers) {
|
|
41
|
+
try {
|
|
42
|
+
subscriber(snapshot);
|
|
43
|
+
} catch {
|
|
44
|
+
}
|
|
45
|
+
}
|
|
46
|
+
}
|
|
47
|
+
function liveToken(tokens) {
|
|
48
|
+
_currentTokens = { ..._currentTokens, ...tokens };
|
|
49
|
+
syncStyleEl();
|
|
50
|
+
notifySubscribers();
|
|
51
|
+
const vars = {};
|
|
52
|
+
for (const name of Object.keys(tokens)) {
|
|
53
|
+
vars[name] = tokenRef(name);
|
|
54
|
+
}
|
|
55
|
+
return {
|
|
56
|
+
vars,
|
|
57
|
+
get(name) {
|
|
58
|
+
return _currentTokens[name];
|
|
59
|
+
},
|
|
60
|
+
set(name, value) {
|
|
61
|
+
setToken(name, value);
|
|
62
|
+
},
|
|
63
|
+
setAll(nextTokens) {
|
|
64
|
+
setTokens(nextTokens);
|
|
65
|
+
},
|
|
66
|
+
snapshot() {
|
|
67
|
+
return { ..._currentTokens };
|
|
68
|
+
}
|
|
69
|
+
};
|
|
70
|
+
}
|
|
71
|
+
function setToken(name, value) {
|
|
72
|
+
_currentTokens = { ..._currentTokens, [name]: value };
|
|
73
|
+
if (typeof document !== "undefined") {
|
|
74
|
+
document.documentElement.style.setProperty(tokenVar(name), value);
|
|
75
|
+
}
|
|
76
|
+
notifySubscribers();
|
|
77
|
+
}
|
|
78
|
+
function setTokens(tokens) {
|
|
79
|
+
_currentTokens = { ..._currentTokens, ...tokens };
|
|
80
|
+
if (typeof document !== "undefined") {
|
|
81
|
+
const root = document.documentElement;
|
|
82
|
+
for (const [name, value] of Object.entries(tokens)) {
|
|
83
|
+
root.style.setProperty(tokenVar(name), value);
|
|
84
|
+
}
|
|
85
|
+
}
|
|
86
|
+
notifySubscribers();
|
|
87
|
+
}
|
|
88
|
+
function applyTokenSet(tokens) {
|
|
89
|
+
if (typeof document !== "undefined") {
|
|
90
|
+
const root = document.documentElement;
|
|
91
|
+
for (const name of Object.keys(_currentTokens)) {
|
|
92
|
+
if (!(name in tokens)) {
|
|
93
|
+
root.style.removeProperty(tokenVar(name));
|
|
94
|
+
}
|
|
95
|
+
}
|
|
96
|
+
}
|
|
97
|
+
_currentTokens = { ...tokens };
|
|
98
|
+
syncStyleEl();
|
|
99
|
+
notifySubscribers();
|
|
100
|
+
}
|
|
101
|
+
function getToken(name) {
|
|
102
|
+
return _currentTokens[name];
|
|
103
|
+
}
|
|
104
|
+
function getTokens() {
|
|
105
|
+
return { ..._currentTokens };
|
|
106
|
+
}
|
|
107
|
+
function subscribeTokens(fn) {
|
|
108
|
+
_subscribers.add(fn);
|
|
109
|
+
return () => {
|
|
110
|
+
_subscribers.delete(fn);
|
|
111
|
+
};
|
|
112
|
+
}
|
|
113
|
+
function generateTokenCssString() {
|
|
114
|
+
return buildRootCss(_currentTokens);
|
|
115
|
+
}
|
|
116
|
+
function createUseTokens() {
|
|
117
|
+
return function useTokens() {
|
|
118
|
+
const [tokens, setTokensState] = React.useState({ ..._currentTokens });
|
|
119
|
+
React.useEffect(() => {
|
|
120
|
+
setTokensState({ ..._currentTokens });
|
|
121
|
+
return subscribeTokens((nextTokens) => setTokensState({ ...nextTokens }));
|
|
122
|
+
}, []);
|
|
123
|
+
return tokens;
|
|
124
|
+
};
|
|
125
|
+
}
|
|
126
|
+
var liveTokenEngine = {
|
|
127
|
+
getToken,
|
|
128
|
+
getTokens,
|
|
129
|
+
setToken,
|
|
130
|
+
applyTokenSet,
|
|
131
|
+
subscribeTokens,
|
|
132
|
+
subscribe: subscribeTokens
|
|
133
|
+
};
|
|
134
|
+
globalThis.__TW_TOKEN_ENGINE__ = liveTokenEngine;
|
|
135
|
+
if (typeof window !== "undefined") {
|
|
136
|
+
window.__TW_TOKEN_ENGINE__ = liveTokenEngine;
|
|
137
|
+
}
|
|
138
|
+
var _binding;
|
|
139
|
+
function getNativeThemeBinding() {
|
|
140
|
+
if (_binding !== void 0) return _binding;
|
|
141
|
+
if (process.env.TWS_NO_NATIVE === "1" || process.env.TWS_NO_RUST === "1") {
|
|
142
|
+
return _binding = null;
|
|
143
|
+
}
|
|
144
|
+
const runtimeDir = typeof __dirname === "string" ? __dirname : process.cwd();
|
|
145
|
+
const req = typeof __require === "function" ? __require : createRequire(path.join(runtimeDir, "noop.cjs"));
|
|
146
|
+
const candidates = [
|
|
147
|
+
path.resolve(process.cwd(), "native", "tailwind_styled_parser.node"),
|
|
148
|
+
path.resolve(runtimeDir, "..", "..", "..", "native", "tailwind_styled_parser.node")
|
|
149
|
+
];
|
|
150
|
+
for (const c of candidates) {
|
|
151
|
+
try {
|
|
152
|
+
const mod = req(c);
|
|
153
|
+
if (mod?.compileTheme) return _binding = mod;
|
|
154
|
+
} catch {
|
|
155
|
+
}
|
|
156
|
+
}
|
|
157
|
+
return _binding = null;
|
|
158
|
+
}
|
|
159
|
+
|
|
160
|
+
// packages/theme/src/index.ts
|
|
161
|
+
function defineThemeContract(shape) {
|
|
162
|
+
const vars = {};
|
|
163
|
+
for (const group in shape) {
|
|
164
|
+
vars[group] = {};
|
|
165
|
+
for (const token in shape[group]) {
|
|
166
|
+
vars[group][token] = `var(--${group}-${token})`;
|
|
167
|
+
}
|
|
168
|
+
}
|
|
169
|
+
return { _contract: shape, _vars: vars };
|
|
170
|
+
}
|
|
171
|
+
function createTheme(contract, name, values, asRoot = false) {
|
|
172
|
+
const native = getNativeThemeBinding();
|
|
173
|
+
if (native?.compileTheme) {
|
|
174
|
+
const result = native.compileTheme(JSON.stringify(values), asRoot ? "light" : name, "");
|
|
175
|
+
if (result) {
|
|
176
|
+
const flatVars2 = {};
|
|
177
|
+
for (const token of result.tokens) {
|
|
178
|
+
flatVars2[token.cssVar] = token.value;
|
|
179
|
+
}
|
|
180
|
+
return { name, contract, values, css: result.css, vars: flatVars2, selector: result.selector };
|
|
181
|
+
}
|
|
182
|
+
}
|
|
183
|
+
const flatVars = {};
|
|
184
|
+
const cssLines = [];
|
|
185
|
+
for (const group in values) {
|
|
186
|
+
for (const token in values[group]) {
|
|
187
|
+
const varName = `--${group}-${token}`;
|
|
188
|
+
const value = values[group][token];
|
|
189
|
+
flatVars[varName] = value;
|
|
190
|
+
cssLines.push(` ${varName}: ${value};`);
|
|
191
|
+
}
|
|
192
|
+
}
|
|
193
|
+
const selector = asRoot ? ":root" : `[data-theme="${name}"]`;
|
|
194
|
+
const css = `${selector} {
|
|
195
|
+
${cssLines.join("\n")}
|
|
196
|
+
}`;
|
|
197
|
+
return { name, contract, values, css, vars: flatVars, selector };
|
|
198
|
+
}
|
|
199
|
+
var ThemeRegistry = class {
|
|
200
|
+
constructor() {
|
|
201
|
+
this.themes = /* @__PURE__ */ new Map();
|
|
202
|
+
this.defaultTheme = null;
|
|
203
|
+
}
|
|
204
|
+
/** Register a theme */
|
|
205
|
+
register(theme, isDefault = false) {
|
|
206
|
+
this.themes.set(theme.name, theme);
|
|
207
|
+
if (isDefault || !this.defaultTheme) {
|
|
208
|
+
this.defaultTheme = theme.name;
|
|
209
|
+
}
|
|
210
|
+
return this;
|
|
211
|
+
}
|
|
212
|
+
/** Get a theme by name */
|
|
213
|
+
get(name) {
|
|
214
|
+
return this.themes.get(name);
|
|
215
|
+
}
|
|
216
|
+
/** Get all theme names */
|
|
217
|
+
names() {
|
|
218
|
+
return Array.from(this.themes.keys());
|
|
219
|
+
}
|
|
220
|
+
/**
|
|
221
|
+
* Generate combined CSS for all themes.
|
|
222
|
+
* Inject into <head> or a .css file.
|
|
223
|
+
*
|
|
224
|
+
* @example
|
|
225
|
+
* // In globals.css or layout.tsx
|
|
226
|
+
* const css = registry.generateCss()
|
|
227
|
+
*/
|
|
228
|
+
generateCss() {
|
|
229
|
+
return Array.from(this.themes.values()).map((t) => t.css).join("\n\n");
|
|
230
|
+
}
|
|
231
|
+
/**
|
|
232
|
+
* Get the CSS for a specific theme only.
|
|
233
|
+
*/
|
|
234
|
+
getThemeCss(name) {
|
|
235
|
+
return this.themes.get(name)?.css ?? null;
|
|
236
|
+
}
|
|
237
|
+
/**
|
|
238
|
+
* Inject all theme CSS into document <head> (browser only).
|
|
239
|
+
* Call once on app init.
|
|
240
|
+
*/
|
|
241
|
+
inject(styleId = "__tw_themes") {
|
|
242
|
+
if (typeof document === "undefined") return;
|
|
243
|
+
let style = document.getElementById(styleId);
|
|
244
|
+
if (!style) {
|
|
245
|
+
style = document.createElement("style");
|
|
246
|
+
style.id = styleId;
|
|
247
|
+
document.head.appendChild(style);
|
|
248
|
+
}
|
|
249
|
+
style.textContent = this.generateCss();
|
|
250
|
+
}
|
|
251
|
+
/**
|
|
252
|
+
* Switch active theme by setting data-theme on <html>.
|
|
253
|
+
*/
|
|
254
|
+
apply(name, target = document.documentElement) {
|
|
255
|
+
if (typeof document === "undefined") return;
|
|
256
|
+
if (!this.themes.has(name)) {
|
|
257
|
+
console.warn(`[tailwind-styled-v4] Theme "${name}" not registered.`);
|
|
258
|
+
return;
|
|
259
|
+
}
|
|
260
|
+
target.dataset.theme = name;
|
|
261
|
+
}
|
|
262
|
+
/**
|
|
263
|
+
* Get current active theme name from data-theme attribute.
|
|
264
|
+
*/
|
|
265
|
+
current(target = document.documentElement) {
|
|
266
|
+
if (typeof document === "undefined") return this.defaultTheme;
|
|
267
|
+
return target.dataset.theme ?? this.defaultTheme;
|
|
268
|
+
}
|
|
269
|
+
};
|
|
270
|
+
function createMultiTheme(config) {
|
|
271
|
+
const registry = new ThemeRegistry();
|
|
272
|
+
const light = createTheme(config.contract, "light", config.light, true);
|
|
273
|
+
const dark = createTheme(config.contract, "dark", config.dark, false);
|
|
274
|
+
registry.register(light, true);
|
|
275
|
+
registry.register(dark);
|
|
276
|
+
for (const [name, values] of Object.entries(config.extras ?? {})) {
|
|
277
|
+
registry.register(createTheme(config.contract, name, values));
|
|
278
|
+
}
|
|
279
|
+
return {
|
|
280
|
+
registry,
|
|
281
|
+
vars: config.contract._vars,
|
|
282
|
+
light,
|
|
283
|
+
dark
|
|
284
|
+
};
|
|
285
|
+
}
|
|
286
|
+
function compileDesignTokens(tokens, prefix = "") {
|
|
287
|
+
const native = getNativeThemeBinding();
|
|
288
|
+
if (native?.compileTheme) {
|
|
289
|
+
const result = native.compileTheme(JSON.stringify(tokens), "default", prefix);
|
|
290
|
+
if (result) return result.css;
|
|
291
|
+
}
|
|
292
|
+
const vars = [];
|
|
293
|
+
function flatten(obj, path2) {
|
|
294
|
+
for (const [key, value] of Object.entries(obj)) {
|
|
295
|
+
const varPath = path2 ? `${path2}-${key}` : key;
|
|
296
|
+
if (typeof value === "string") {
|
|
297
|
+
vars.push(` --${varPath}: ${value};`);
|
|
298
|
+
} else {
|
|
299
|
+
flatten(value, varPath);
|
|
300
|
+
}
|
|
301
|
+
}
|
|
302
|
+
}
|
|
303
|
+
flatten(tokens, prefix);
|
|
304
|
+
return `:root {
|
|
305
|
+
${vars.join("\n")}
|
|
306
|
+
}`;
|
|
307
|
+
}
|
|
308
|
+
|
|
309
|
+
export { ThemeRegistry, applyTokenSet, compileDesignTokens, createMultiTheme, createTheme, createUseTokens, defineThemeContract, generateTokenCssString, getToken, getTokens, liveToken, liveTokenEngine, setToken, setTokens, subscribeTokens, tokenRef, tokenVar };
|
|
310
|
+
//# sourceMappingURL=theme.mjs.map
|
|
311
|
+
//# sourceMappingURL=theme.mjs.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["../packages/theme/src/liveTokenEngine.ts","../packages/theme/src/native-bridge.ts","../packages/theme/src/index.ts"],"names":["flatVars","path"],"mappings":"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","file":"theme.mjs","sourcesContent":["import React from \"react\"\n\nexport type TokenMap = Record<string, string>\nexport type TokenSubscriber = (tokens: TokenMap) => void\n\nexport interface LiveTokenSet {\n vars: Record<string, string>\n get(name: string): string | undefined\n set(name: string, value: string): void\n setAll(tokens: TokenMap): void\n snapshot(): TokenMap\n}\n\nexport interface LiveTokenEngineBridge {\n getToken(name: string): string | undefined\n getTokens(): TokenMap\n setToken(name: string, value: string): void\n applyTokenSet(tokens: TokenMap): void\n subscribeTokens(fn: TokenSubscriber): () => void\n subscribe?(fn: TokenSubscriber): () => void\n}\n\ndeclare global {\n var __TW_TOKEN_ENGINE__: LiveTokenEngineBridge | undefined\n}\n\nlet _currentTokens: TokenMap = {}\nconst _subscribers = new Set<TokenSubscriber>()\nlet _styleEl: HTMLStyleElement | null = null\n\nexport function tokenVar(name: string): string {\n const normalized = name.replace(/[^a-zA-Z0-9-]/g, \"-\").toLowerCase()\n return `--tw-token-${normalized}`\n}\n\nexport function tokenRef(name: string): string {\n return `var(${tokenVar(name)})`\n}\n\nfunction buildRootCss(tokens: TokenMap): string {\n const vars = Object.entries(tokens)\n .map(([name, value]) => ` ${tokenVar(name)}: ${value};`)\n .join(\"\\n\")\n return `:root {\\n${vars}\\n}`\n}\n\nfunction syncStyleEl(): void {\n if (typeof document === \"undefined\") return\n\n if (!_styleEl) {\n _styleEl = document.createElement(\"style\")\n _styleEl.id = \"tw-live-tokens\"\n _styleEl.setAttribute(\"data-tw-tokens\", \"true\")\n document.head.appendChild(_styleEl)\n }\n\n _styleEl.textContent = buildRootCss(_currentTokens)\n}\n\nfunction notifySubscribers(): void {\n const snapshot = { ..._currentTokens }\n for (const subscriber of _subscribers) {\n try {\n subscriber(snapshot)\n } catch {\n // intentionally ignore subscriber errors\n }\n }\n}\n\nexport function liveToken(tokens: TokenMap): LiveTokenSet {\n _currentTokens = { ..._currentTokens, ...tokens }\n syncStyleEl()\n notifySubscribers()\n\n const vars: Record<string, string> = {}\n for (const name of Object.keys(tokens)) {\n vars[name] = tokenRef(name)\n }\n\n return {\n vars,\n get(name) {\n return _currentTokens[name]\n },\n set(name, value) {\n setToken(name, value)\n },\n setAll(nextTokens) {\n setTokens(nextTokens)\n },\n snapshot() {\n return { ..._currentTokens }\n },\n }\n}\n\nexport function setToken(name: string, value: string): void {\n _currentTokens = { ..._currentTokens, [name]: value }\n\n if (typeof document !== \"undefined\") {\n document.documentElement.style.setProperty(tokenVar(name), value)\n }\n\n notifySubscribers()\n}\n\nexport function setTokens(tokens: TokenMap): void {\n _currentTokens = { ..._currentTokens, ...tokens }\n\n if (typeof document !== \"undefined\") {\n const root = document.documentElement\n for (const [name, value] of Object.entries(tokens)) {\n root.style.setProperty(tokenVar(name), value)\n }\n }\n\n notifySubscribers()\n}\n\nexport function applyTokenSet(tokens: TokenMap): void {\n if (typeof document !== \"undefined\") {\n const root = document.documentElement\n for (const name of Object.keys(_currentTokens)) {\n if (!(name in tokens)) {\n root.style.removeProperty(tokenVar(name))\n }\n }\n }\n\n _currentTokens = { ...tokens }\n syncStyleEl()\n notifySubscribers()\n}\n\nexport function getToken(name: string): string | undefined {\n return _currentTokens[name]\n}\n\nexport function getTokens(): TokenMap {\n return { ..._currentTokens }\n}\n\nexport function subscribeTokens(fn: TokenSubscriber): () => void {\n _subscribers.add(fn)\n return () => {\n _subscribers.delete(fn)\n }\n}\n\nexport function generateTokenCssString(): string {\n return buildRootCss(_currentTokens)\n}\n\nexport function createUseTokens() {\n return function useTokens(): TokenMap {\n const [tokens, setTokensState] = React.useState<TokenMap>({ ..._currentTokens })\n\n React.useEffect(() => {\n setTokensState({ ..._currentTokens })\n return subscribeTokens((nextTokens) => setTokensState({ ...nextTokens }))\n }, [])\n\n return tokens\n }\n}\n\nexport const liveTokenEngine: LiveTokenEngineBridge = {\n getToken,\n getTokens,\n setToken,\n applyTokenSet,\n subscribeTokens,\n subscribe: subscribeTokens,\n}\n\nglobalThis.__TW_TOKEN_ENGINE__ = liveTokenEngine\nif (typeof window !== \"undefined\") {\n ;(window as any).__TW_TOKEN_ENGINE__ = liveTokenEngine\n}\n","/**\n * Theme — Rust native bridge\n */\nimport { createRequire } from \"node:module\"\nimport path from \"node:path\"\n\ninterface NativeThemeBinding {\n compileTheme?: (\n tokensJson: string,\n themeName: string,\n prefix: string\n ) => {\n name: string\n selector: string\n css: string\n tokens: Array<{ key: string; cssVar: string; value: string }>\n } | null\n extractCssVars?: (source: string) => string[] | null\n}\n\nlet _binding: NativeThemeBinding | null | undefined\n\nexport function getNativeThemeBinding(): NativeThemeBinding | null {\n if (_binding !== undefined) return _binding\n if (process.env.TWS_NO_NATIVE === \"1\" || process.env.TWS_NO_RUST === \"1\") {\n return (_binding = null)\n }\n const runtimeDir = typeof __dirname === \"string\" ? __dirname : process.cwd()\n const req =\n typeof require === \"function\" ? require : createRequire(path.join(runtimeDir, \"noop.cjs\"))\n const candidates = [\n path.resolve(process.cwd(), \"native\", \"tailwind_styled_parser.node\"),\n path.resolve(runtimeDir, \"..\", \"..\", \"..\", \"native\", \"tailwind_styled_parser.node\"),\n ]\n for (const c of candidates) {\n try {\n const mod = req(c) as NativeThemeBinding\n if (mod?.compileTheme) return (_binding = mod)\n } catch {\n /* next */\n }\n }\n return (_binding = null)\n}\n","/**\n * tailwind-styled-v5 — Multi-Theme Engine + Live Token Engine\n *\n * Enterprise-grade theming. Support light/dark/brand themes dengan\n * CSS variables. Zero runtime overhead — themes di-resolve via CSS.\n *\n * Live token engine provides runtime token state management with\n * CSS variable sync to document root.\n *\n * Fitur:\n * - Multiple named themes (light, dark, brand, high-contrast)\n * - CSS variable output (Tailwind v4 compatible)\n * - Theme contract (TypeScript-safe — missing tokens = TS error)\n * - Per-component theme override\n * - White-label ready\n * - Live token engine (runtime token state + CSS sync)\n *\n * @example\n * // 1. Define contract\n * const contract = defineThemeContract({\n * colors: { bg: \"\", fg: \"\", primary: \"\", muted: \"\" },\n * font: { sans: \"\", mono: \"\" },\n * })\n *\n * // 2. Create themes\n * const lightTheme = createTheme(contract, \"light\", {\n * colors: { bg: \"#ffffff\", fg: \"#09090b\", primary: \"#3b82f6\", muted: \"#71717a\" },\n * font: { sans: \"InterVariable, sans-serif\", mono: \"JetBrains Mono, monospace\" },\n * })\n *\n * const darkTheme = createTheme(contract, \"dark\", {\n * colors: { bg: \"#09090b\", fg: \"#fafafa\", primary: \"#60a5fa\", muted: \"#a1a1aa\" },\n * font: { sans: \"InterVariable, sans-serif\", mono: \"JetBrains Mono, monospace\" },\n * })\n *\n * // 3. Use tokens in components\n * const Card = tw.div`bg-[var(--colors-bg)] text-[var(--colors-fg)] p-6`\n *\n * // 4. Apply in layout\n * // <html data-theme=\"dark\"> or inject CSS\n */\n\n// ─────────────────────────────────────────────────────────────────────────────\n// Live Token Engine exports\n// ─────────────────────────────────────────────────────────────────────────────\n\nexport type {\n LiveTokenEngineBridge,\n LiveTokenSet,\n TokenMap,\n TokenSubscriber,\n} from \"./liveTokenEngine\"\nexport {\n applyTokenSet,\n createUseTokens,\n generateTokenCssString,\n getToken,\n getTokens,\n liveToken,\n liveTokenEngine,\n setToken,\n setTokens,\n subscribeTokens,\n tokenRef,\n tokenVar,\n} from \"./liveTokenEngine\"\n\n// ─────────────────────────────────────────────────────────────────────────────\n// Theme types\n// ─────────────────────────────────────────────────────────────────────────────\n\nimport { getNativeThemeBinding } from \"./native-bridge\"\n\n// ThemeTokenMap untuk theming (grouped tokens seperti { colors: { bg: \"#fff\" } })\nexport type ThemeTokenMap = Record<string, Record<string, string>>\n\nexport interface ThemeContract<T extends ThemeTokenMap> {\n _contract: T\n _vars: ThemeVars<T>\n}\n\nexport type ThemeVars<T extends ThemeTokenMap> = {\n [Group in keyof T]: {\n [Token in keyof T[Group]]: string // \"var(--group-token)\"\n }\n}\n\nexport interface Theme<T extends ThemeTokenMap> {\n name: string\n contract: ThemeContract<T>\n values: T\n /** CSS string to inject (`:root` or `[data-theme=\"name\"]`) */\n css: string\n /** CSS variables as a flat record */\n vars: Record<string, string>\n /** Apply this theme to an element via data attribute */\n selector: string\n}\n\n// ─────────────────────────────────────────────────────────────────────────────\n// defineThemeContract\n// ─────────────────────────────────────────────────────────────────────────────\n\n/**\n * Define the shape of your theme. All themes must satisfy this contract.\n * Returns typed CSS variable references for use in tw components.\n *\n * @example\n * const contract = defineThemeContract({\n * colors: { bg: \"\", fg: \"\", primary: \"\" },\n * font: { sans: \"\" },\n * })\n *\n * // Use in components:\n * const Card = tw.div`bg-[${contract._vars.colors.bg}]`\n * // → tw.div`bg-[var(--colors-bg)]`\n */\nexport function defineThemeContract<T extends ThemeTokenMap>(shape: T): ThemeContract<T> {\n const vars = {} as ThemeVars<T>\n\n for (const group in shape) {\n ;(vars as any)[group] = {}\n for (const token in shape[group]) {\n ;(vars as any)[group][token] = `var(--${group}-${token})`\n }\n }\n\n return { _contract: shape, _vars: vars }\n}\n\n// ─────────────────────────────────────────────────────────────────────────────\n// createTheme\n// ─────────────────────────────────────────────────────────────────────────────\n\n/**\n * Create a typed theme that satisfies a contract.\n *\n * @param contract - Theme contract from defineThemeContract()\n * @param name - Theme name (\"light\", \"dark\", \"brand\", etc.)\n * @param values - Token values (TypeScript enforces completeness)\n * @param asRoot - If true, use :root selector. Default: false (uses [data-theme])\n */\nexport function createTheme<T extends ThemeTokenMap>(\n contract: ThemeContract<T>,\n name: string,\n values: T,\n asRoot = false\n): Theme<T> {\n // ── Rust fast-path ─────────────────────────────────────────────────────────\n const native = getNativeThemeBinding()\n if (native?.compileTheme) {\n const result = native.compileTheme(JSON.stringify(values), asRoot ? \"light\" : name, \"\")\n if (result) {\n const flatVars: Record<string, string> = {}\n for (const token of result.tokens) {\n flatVars[token.cssVar] = token.value\n }\n return { name, contract, values, css: result.css, vars: flatVars, selector: result.selector }\n }\n }\n\n // ── JS fallback ────────────────────────────────────────────────────────────\n const flatVars: Record<string, string> = {}\n const cssLines: string[] = []\n\n for (const group in values) {\n for (const token in values[group]) {\n const varName = `--${group}-${token}`\n const value = values[group][token]\n flatVars[varName] = value\n cssLines.push(` ${varName}: ${value};`)\n }\n }\n\n const selector = asRoot ? \":root\" : `[data-theme=\"${name}\"]`\n const css = `${selector} {\\n${cssLines.join(\"\\n\")}\\n}`\n\n return { name, contract, values, css, vars: flatVars, selector }\n}\n\n// ─────────────────────────────────────────────────────────────────────────────\n// ThemeRegistry — manage multiple themes\n// ─────────────────────────────────────────────────────────────────────────────\n\nexport class ThemeRegistry {\n private themes = new Map<string, Theme<any>>()\n private defaultTheme: string | null = null\n\n /** Register a theme */\n register<T extends ThemeTokenMap>(theme: Theme<T>, isDefault = false): this {\n this.themes.set(theme.name, theme)\n if (isDefault || !this.defaultTheme) {\n this.defaultTheme = theme.name\n }\n return this\n }\n\n /** Get a theme by name */\n get(name: string): Theme<any> | undefined {\n return this.themes.get(name)\n }\n\n /** Get all theme names */\n names(): string[] {\n return Array.from(this.themes.keys())\n }\n\n /**\n * Generate combined CSS for all themes.\n * Inject into <head> or a .css file.\n *\n * @example\n * // In globals.css or layout.tsx\n * const css = registry.generateCss()\n */\n generateCss(): string {\n return Array.from(this.themes.values())\n .map((t) => t.css)\n .join(\"\\n\\n\")\n }\n\n /**\n * Get the CSS for a specific theme only.\n */\n getThemeCss(name: string): string | null {\n return this.themes.get(name)?.css ?? null\n }\n\n /**\n * Inject all theme CSS into document <head> (browser only).\n * Call once on app init.\n */\n inject(styleId = \"__tw_themes\"): void {\n if (typeof document === \"undefined\") return\n\n let style = document.getElementById(styleId) as HTMLStyleElement | null\n if (!style) {\n style = document.createElement(\"style\")\n style.id = styleId\n document.head.appendChild(style)\n }\n style.textContent = this.generateCss()\n }\n\n /**\n * Switch active theme by setting data-theme on <html>.\n */\n apply(name: string, target: HTMLElement = document.documentElement): void {\n if (typeof document === \"undefined\") return\n if (!this.themes.has(name)) {\n console.warn(`[tailwind-styled-v4] Theme \"${name}\" not registered.`)\n return\n }\n target.dataset.theme = name\n }\n\n /**\n * Get current active theme name from data-theme attribute.\n */\n current(target: HTMLElement = document.documentElement): string | null {\n if (typeof document === \"undefined\") return this.defaultTheme\n return target.dataset.theme ?? this.defaultTheme\n }\n}\n\n// ─────────────────────────────────────────────────────────────────────────────\n// Convenience: createMultiTheme — shorthand for common light/dark setup\n// ─────────────────────────────────────────────────────────────────────────────\n\nexport interface MultiThemeConfig<T extends ThemeTokenMap> {\n contract: ThemeContract<T>\n light: T\n dark: T\n /** Additional named themes (brand, high-contrast, etc.) */\n extras?: Record<string, T>\n}\n\n/**\n * Create a ThemeRegistry with light/dark + optional extras in one call.\n *\n * @example\n * const { registry, vars } = createMultiTheme({\n * contract: defineThemeContract({\n * colors: { bg: \"\", fg: \"\", primary: \"\", border: \"\" }\n * }),\n * light: {\n * colors: { bg: \"#fff\", fg: \"#09090b\", primary: \"#3b82f6\", border: \"#e5e7eb\" }\n * },\n * dark: {\n * colors: { bg: \"#09090b\", fg: \"#fafafa\", primary: \"#60a5fa\", border: \"#27272a\" }\n * },\n * })\n *\n * // Inject CSS:\n * registry.inject()\n *\n * // Use tokens in components:\n * const Card = tw.div`bg-[${vars.colors.bg}] text-[${vars.colors.fg}]`\n */\nexport function createMultiTheme<T extends ThemeTokenMap>(\n config: MultiThemeConfig<T>\n): {\n registry: ThemeRegistry\n vars: ThemeVars<T>\n light: Theme<T>\n dark: Theme<T>\n} {\n const registry = new ThemeRegistry()\n\n const light = createTheme(config.contract, \"light\", config.light, true) // :root\n const dark = createTheme(config.contract, \"dark\", config.dark, false)\n\n registry.register(light, true)\n registry.register(dark)\n\n for (const [name, values] of Object.entries(config.extras ?? {})) {\n registry.register(createTheme(config.contract, name, values as T))\n }\n\n return {\n registry,\n vars: config.contract._vars,\n light,\n dark,\n }\n}\n\n// ─────────────────────────────────────────────────────────────────────────────\n// Design Token Compiler — generate CSS vars from token object\n// (Enterprise feature: sync with Figma variables)\n// ─────────────────────────────────────────────────────────────────────────────\n\nexport interface DesignTokens {\n [path: string]: string | DesignTokens\n}\n\n/**\n * Flatten nested design token object into CSS variables.\n * Supports Figma-style nested tokens.\n *\n * @example\n * compileDesignTokens({\n * color: {\n * brand: { primary: \"#3b82f6\", secondary: \"#6366f1\" },\n * neutral: { 50: \"#fafafa\", 900: \"#09090b\" }\n * },\n * spacing: { base: \"4px\", lg: \"16px\" }\n * })\n * →\n * :root {\n * --color-brand-primary: #3b82f6;\n * --color-brand-secondary: #6366f1;\n * --color-neutral-50: #fafafa;\n * --color-neutral-900: #09090b;\n * --spacing-base: 4px;\n * --spacing-lg: 16px;\n * }\n */\nexport function compileDesignTokens(tokens: DesignTokens, prefix = \"\"): string {\n // ── Rust fast-path ─────────────────────────────────────────────────────────\n const native = getNativeThemeBinding()\n if (native?.compileTheme) {\n const result = native.compileTheme(JSON.stringify(tokens), \"default\", prefix)\n if (result) return result.css\n }\n\n // ── JS fallback ────────────────────────────────────────────────────────────\n const vars: string[] = []\n\n function flatten(obj: DesignTokens, path: string) {\n for (const [key, value] of Object.entries(obj)) {\n const varPath = path ? `${path}-${key}` : key\n if (typeof value === \"string\") {\n vars.push(` --${varPath}: ${value};`)\n } else {\n flatten(value as DesignTokens, varPath)\n }\n }\n }\n\n flatten(tokens, prefix)\n return `:root {\\n${vars.join(\"\\n\")}\\n}`\n}\n"]}
|
|
@@ -0,0 +1,31 @@
|
|
|
1
|
+
type CSSFillMode = "none" | "forwards" | "backwards" | "both";
|
|
2
|
+
type CSSDirection = "normal" | "reverse" | "alternate" | "alternate-reverse";
|
|
3
|
+
type CSSIterationCount = number | "infinite";
|
|
4
|
+
type PresetEasing = "linear" | "ease" | "ease-in" | "ease-out" | "ease-in-out" | "step-start" | "step-end";
|
|
5
|
+
type CubicBezierEasing = `cubic-bezier(${string})`;
|
|
6
|
+
type StepsEasing = `steps(${string})`;
|
|
7
|
+
type CSSEasing = PresetEasing | CubicBezierEasing | StepsEasing;
|
|
8
|
+
interface AnimateOptions {
|
|
9
|
+
from: string;
|
|
10
|
+
to: string;
|
|
11
|
+
duration?: number;
|
|
12
|
+
easing?: CSSEasing;
|
|
13
|
+
delay?: number;
|
|
14
|
+
fill?: CSSFillMode;
|
|
15
|
+
iterations?: CSSIterationCount;
|
|
16
|
+
direction?: CSSDirection;
|
|
17
|
+
name?: string;
|
|
18
|
+
}
|
|
19
|
+
interface KeyframesDefinition {
|
|
20
|
+
[stop: string]: string;
|
|
21
|
+
}
|
|
22
|
+
interface CompiledAnimation {
|
|
23
|
+
className: string;
|
|
24
|
+
keyframesCss: string;
|
|
25
|
+
animationCss: string;
|
|
26
|
+
}
|
|
27
|
+
interface AnimationRegistryOptions {
|
|
28
|
+
cacheLimit?: number;
|
|
29
|
+
}
|
|
30
|
+
|
|
31
|
+
export type { AnimationRegistryOptions as A, CompiledAnimation as C, KeyframesDefinition as K, PresetEasing as P, StepsEasing as S, AnimateOptions as a, CSSDirection as b, CSSEasing as c, CSSFillMode as d, CSSIterationCount as e, CubicBezierEasing as f };
|
|
@@ -0,0 +1,31 @@
|
|
|
1
|
+
type CSSFillMode = "none" | "forwards" | "backwards" | "both";
|
|
2
|
+
type CSSDirection = "normal" | "reverse" | "alternate" | "alternate-reverse";
|
|
3
|
+
type CSSIterationCount = number | "infinite";
|
|
4
|
+
type PresetEasing = "linear" | "ease" | "ease-in" | "ease-out" | "ease-in-out" | "step-start" | "step-end";
|
|
5
|
+
type CubicBezierEasing = `cubic-bezier(${string})`;
|
|
6
|
+
type StepsEasing = `steps(${string})`;
|
|
7
|
+
type CSSEasing = PresetEasing | CubicBezierEasing | StepsEasing;
|
|
8
|
+
interface AnimateOptions {
|
|
9
|
+
from: string;
|
|
10
|
+
to: string;
|
|
11
|
+
duration?: number;
|
|
12
|
+
easing?: CSSEasing;
|
|
13
|
+
delay?: number;
|
|
14
|
+
fill?: CSSFillMode;
|
|
15
|
+
iterations?: CSSIterationCount;
|
|
16
|
+
direction?: CSSDirection;
|
|
17
|
+
name?: string;
|
|
18
|
+
}
|
|
19
|
+
interface KeyframesDefinition {
|
|
20
|
+
[stop: string]: string;
|
|
21
|
+
}
|
|
22
|
+
interface CompiledAnimation {
|
|
23
|
+
className: string;
|
|
24
|
+
keyframesCss: string;
|
|
25
|
+
animationCss: string;
|
|
26
|
+
}
|
|
27
|
+
interface AnimationRegistryOptions {
|
|
28
|
+
cacheLimit?: number;
|
|
29
|
+
}
|
|
30
|
+
|
|
31
|
+
export type { AnimationRegistryOptions as A, CompiledAnimation as C, KeyframesDefinition as K, PresetEasing as P, StepsEasing as S, AnimateOptions as a, CSSDirection as b, CSSEasing as c, CSSFillMode as d, CSSIterationCount as e, CubicBezierEasing as f };
|
package/dist/vite.d.mts
ADDED
|
@@ -0,0 +1,51 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* tailwind-styled-v4 — Vite Plugin v5
|
|
3
|
+
*
|
|
4
|
+
* Usage in vite.config.ts:
|
|
5
|
+
* import { tailwindStyledPlugin } from "@tailwind-styled/vite"
|
|
6
|
+
* export default defineConfig({
|
|
7
|
+
* plugins: [react(), tailwindStyledPlugin()]
|
|
8
|
+
* })
|
|
9
|
+
*
|
|
10
|
+
* v5 Changes:
|
|
11
|
+
* - Simplified API (removed deprecated options)
|
|
12
|
+
* - Uses @tailwind-styled/engine for build
|
|
13
|
+
* - Mode always zero-runtime
|
|
14
|
+
*/
|
|
15
|
+
interface VitePluginOptions {
|
|
16
|
+
/** File patterns to include. Default: /\.(tsx|ts|jsx|js)$/ */
|
|
17
|
+
include?: RegExp;
|
|
18
|
+
/** File patterns to exclude. Default: /node_modules/ */
|
|
19
|
+
exclude?: RegExp;
|
|
20
|
+
/** Directories to scan. Default: ["src"] */
|
|
21
|
+
scanDirs?: string[];
|
|
22
|
+
/** Safelist output path. Default: ".tailwind-styled-safelist.json" */
|
|
23
|
+
safelistOutput?: string;
|
|
24
|
+
/** Generate safelist at build end. Default: true */
|
|
25
|
+
generateSafelist?: boolean;
|
|
26
|
+
/** Scan report output path. Default: ".tailwind-styled-scan-report.json" */
|
|
27
|
+
scanReportOutput?: string;
|
|
28
|
+
/** Run engine build at build end. Default: true */
|
|
29
|
+
useEngineBuild?: boolean;
|
|
30
|
+
/** Enable analyzer for semantic reports. Default: false */
|
|
31
|
+
analyze?: boolean;
|
|
32
|
+
/** Throw error on engine build failure. If true, error will abort Vite build (useful for CI/CD). If false (default), error only shows console.warn. Default: false */
|
|
33
|
+
strict?: boolean;
|
|
34
|
+
/** @deprecated in v5 - mode is always "zero-runtime" */
|
|
35
|
+
mode?: "zero-runtime" | "runtime";
|
|
36
|
+
/** @deprecated in v5 - handled by engine */
|
|
37
|
+
routeCss?: boolean;
|
|
38
|
+
/** @deprecated in v5 - handled by engine with analyze: true */
|
|
39
|
+
deadStyleElimination?: boolean;
|
|
40
|
+
/** @deprecated in v5 - no longer used */
|
|
41
|
+
addDataAttr?: boolean;
|
|
42
|
+
/** @deprecated in v5 - no longer used */
|
|
43
|
+
autoClientBoundary?: boolean;
|
|
44
|
+
/** @deprecated in v5 - no longer used */
|
|
45
|
+
hoist?: boolean;
|
|
46
|
+
/** @deprecated in v5 - no longer used */
|
|
47
|
+
incremental?: boolean;
|
|
48
|
+
}
|
|
49
|
+
declare function tailwindStyledPlugin(opts?: VitePluginOptions): any;
|
|
50
|
+
|
|
51
|
+
export { type VitePluginOptions, tailwindStyledPlugin as default, tailwindStyledPlugin };
|