tailwind-styled-v4 4.0.0 → 5.0.0

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.
Files changed (77) hide show
  1. package/dist/animate.cjs +754 -235
  2. package/dist/animate.cjs.map +1 -1
  3. package/dist/animate.d.cts +55 -99
  4. package/dist/animate.d.ts +55 -99
  5. package/dist/animate.js +742 -235
  6. package/dist/animate.js.map +1 -1
  7. package/dist/chunk-VZEJV27B.js +11 -0
  8. package/dist/chunk-VZEJV27B.js.map +1 -0
  9. package/dist/chunk-Y5D3E72P.cjs +13 -0
  10. package/dist/chunk-Y5D3E72P.cjs.map +1 -0
  11. package/dist/css.cjs +61 -11
  12. package/dist/css.cjs.map +1 -1
  13. package/dist/css.d.cts +3 -18
  14. package/dist/css.d.ts +3 -18
  15. package/dist/css.js +61 -11
  16. package/dist/css.js.map +1 -1
  17. package/dist/devtools.cjs +200 -88
  18. package/dist/devtools.cjs.map +1 -1
  19. package/dist/devtools.js +200 -88
  20. package/dist/devtools.js.map +1 -1
  21. package/dist/index.cjs +430 -135
  22. package/dist/index.cjs.map +1 -1
  23. package/dist/index.d.cts +74 -3
  24. package/dist/index.d.ts +74 -3
  25. package/dist/index.js +415 -132
  26. package/dist/index.js.map +1 -1
  27. package/dist/next.cjs +118 -138
  28. package/dist/next.cjs.map +1 -1
  29. package/dist/next.d.cts +28 -19
  30. package/dist/next.d.ts +28 -19
  31. package/dist/next.js +111 -131
  32. package/dist/next.js.map +1 -1
  33. package/dist/preset.cjs +312 -18
  34. package/dist/preset.cjs.map +1 -1
  35. package/dist/preset.d.cts +29 -2
  36. package/dist/preset.d.ts +29 -2
  37. package/dist/preset.js +311 -19
  38. package/dist/preset.js.map +1 -1
  39. package/dist/turbopackLoader.cjs +24 -2676
  40. package/dist/turbopackLoader.cjs.map +1 -1
  41. package/dist/turbopackLoader.d.cts +3 -13
  42. package/dist/turbopackLoader.d.ts +3 -13
  43. package/dist/turbopackLoader.js +24 -2670
  44. package/dist/turbopackLoader.js.map +1 -1
  45. package/dist/vite.cjs +90 -57
  46. package/dist/vite.cjs.map +1 -1
  47. package/dist/vite.d.cts +35 -6
  48. package/dist/vite.d.ts +35 -6
  49. package/dist/vite.js +90 -58
  50. package/dist/vite.js.map +1 -1
  51. package/dist/webpackLoader.cjs +27 -2646
  52. package/dist/webpackLoader.cjs.map +1 -1
  53. package/dist/webpackLoader.d.cts +3 -10
  54. package/dist/webpackLoader.d.ts +3 -10
  55. package/dist/webpackLoader.js +27 -2640
  56. package/dist/webpackLoader.js.map +1 -1
  57. package/package.json +31 -28
  58. package/dist/astTransform-ua-eapqs.d.cts +0 -41
  59. package/dist/astTransform-ua-eapqs.d.ts +0 -41
  60. package/dist/compiler.cjs +0 -3594
  61. package/dist/compiler.cjs.map +0 -1
  62. package/dist/compiler.d.cts +0 -716
  63. package/dist/compiler.d.ts +0 -716
  64. package/dist/compiler.js +0 -3535
  65. package/dist/compiler.js.map +0 -1
  66. package/dist/plugins.cjs +0 -396
  67. package/dist/plugins.cjs.map +0 -1
  68. package/dist/plugins.d.cts +0 -231
  69. package/dist/plugins.d.ts +0 -231
  70. package/dist/plugins.js +0 -381
  71. package/dist/plugins.js.map +0 -1
  72. package/dist/theme.cjs +0 -154
  73. package/dist/theme.cjs.map +0 -1
  74. package/dist/theme.d.cts +0 -181
  75. package/dist/theme.d.ts +0 -181
  76. package/dist/theme.js +0 -148
  77. package/dist/theme.js.map +0 -1
@@ -1 +0,0 @@
1
- {"version":3,"sources":["../../theme/src/index.ts"],"names":[],"mappings":"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","file":"theme.cjs","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"]}
package/dist/theme.d.cts DELETED
@@ -1,181 +0,0 @@
1
- /**
2
- * tailwind-styled-v4 — Multi-Theme Engine
3
- *
4
- * Enterprise-grade theming. Support light/dark/brand themes dengan
5
- * CSS variables. Zero runtime overhead — themes di-resolve via CSS.
6
- *
7
- * Fitur:
8
- * - Multiple named themes (light, dark, brand, high-contrast)
9
- * - CSS variable output (Tailwind v4 compatible)
10
- * - Theme contract (TypeScript-safe — missing tokens = TS error)
11
- * - Per-component theme override
12
- * - White-label ready
13
- *
14
- * @example
15
- * // 1. Define contract
16
- * const contract = defineThemeContract({
17
- * colors: { bg: "", fg: "", primary: "", muted: "" },
18
- * font: { sans: "", mono: "" },
19
- * })
20
- *
21
- * // 2. Create themes
22
- * const lightTheme = createTheme(contract, "light", {
23
- * colors: { bg: "#ffffff", fg: "#09090b", primary: "#3b82f6", muted: "#71717a" },
24
- * font: { sans: "InterVariable, sans-serif", mono: "JetBrains Mono, monospace" },
25
- * })
26
- *
27
- * const darkTheme = createTheme(contract, "dark", {
28
- * colors: { bg: "#09090b", fg: "#fafafa", primary: "#60a5fa", muted: "#a1a1aa" },
29
- * font: { sans: "InterVariable, sans-serif", mono: "JetBrains Mono, monospace" },
30
- * })
31
- *
32
- * // 3. Use tokens in components
33
- * const Card = tw.div`bg-[var(--colors-bg)] text-[var(--colors-fg)] p-6`
34
- *
35
- * // 4. Apply in layout
36
- * // <html data-theme="dark"> or inject CSS
37
- */
38
- type TokenMap = Record<string, Record<string, string>>;
39
- interface ThemeContract<T extends TokenMap> {
40
- _contract: T;
41
- _vars: ThemeVars<T>;
42
- }
43
- type ThemeVars<T extends TokenMap> = {
44
- [Group in keyof T]: {
45
- [Token in keyof T[Group]]: string;
46
- };
47
- };
48
- interface Theme<T extends TokenMap> {
49
- name: string;
50
- contract: ThemeContract<T>;
51
- values: T;
52
- /** CSS string to inject (`:root` or `[data-theme="name"]`) */
53
- css: string;
54
- /** CSS variables as a flat record */
55
- vars: Record<string, string>;
56
- /** Apply this theme to an element via data attribute */
57
- selector: string;
58
- }
59
- /**
60
- * Define the shape of your theme. All themes must satisfy this contract.
61
- * Returns typed CSS variable references for use in tw components.
62
- *
63
- * @example
64
- * const contract = defineThemeContract({
65
- * colors: { bg: "", fg: "", primary: "" },
66
- * font: { sans: "" },
67
- * })
68
- *
69
- * // Use in components:
70
- * const Card = tw.div`bg-[${contract._vars.colors.bg}]`
71
- * // → tw.div`bg-[var(--colors-bg)]`
72
- */
73
- declare function defineThemeContract<T extends TokenMap>(shape: T): ThemeContract<T>;
74
- /**
75
- * Create a typed theme that satisfies a contract.
76
- *
77
- * @param contract - Theme contract from defineThemeContract()
78
- * @param name - Theme name ("light", "dark", "brand", etc.)
79
- * @param values - Token values (TypeScript enforces completeness)
80
- * @param asRoot - If true, use :root selector. Default: false (uses [data-theme])
81
- */
82
- declare function createTheme<T extends TokenMap>(contract: ThemeContract<T>, name: string, values: T, asRoot?: boolean): Theme<T>;
83
- declare class ThemeRegistry {
84
- private themes;
85
- private defaultTheme;
86
- /** Register a theme */
87
- register<T extends TokenMap>(theme: Theme<T>, isDefault?: boolean): this;
88
- /** Get a theme by name */
89
- get(name: string): Theme<any> | undefined;
90
- /** Get all theme names */
91
- names(): string[];
92
- /**
93
- * Generate combined CSS for all themes.
94
- * Inject into <head> or a .css file.
95
- *
96
- * @example
97
- * // In globals.css or layout.tsx
98
- * const css = registry.generateCss()
99
- */
100
- generateCss(): string;
101
- /**
102
- * Get the CSS for a specific theme only.
103
- */
104
- getThemeCss(name: string): string | null;
105
- /**
106
- * Inject all theme CSS into document <head> (browser only).
107
- * Call once on app init.
108
- */
109
- inject(styleId?: string): void;
110
- /**
111
- * Switch active theme by setting data-theme on <html>.
112
- */
113
- apply(name: string, target?: HTMLElement): void;
114
- /**
115
- * Get current active theme name from data-theme attribute.
116
- */
117
- current(target?: HTMLElement): string | null;
118
- }
119
- interface MultiThemeConfig<T extends TokenMap> {
120
- contract: ThemeContract<T>;
121
- light: T;
122
- dark: T;
123
- /** Additional named themes (brand, high-contrast, etc.) */
124
- extras?: Record<string, T>;
125
- }
126
- /**
127
- * Create a ThemeRegistry with light/dark + optional extras in one call.
128
- *
129
- * @example
130
- * const { registry, vars } = createMultiTheme({
131
- * contract: defineThemeContract({
132
- * colors: { bg: "", fg: "", primary: "", border: "" }
133
- * }),
134
- * light: {
135
- * colors: { bg: "#fff", fg: "#09090b", primary: "#3b82f6", border: "#e5e7eb" }
136
- * },
137
- * dark: {
138
- * colors: { bg: "#09090b", fg: "#fafafa", primary: "#60a5fa", border: "#27272a" }
139
- * },
140
- * })
141
- *
142
- * // Inject CSS:
143
- * registry.inject()
144
- *
145
- * // Use tokens in components:
146
- * const Card = tw.div`bg-[${vars.colors.bg}] text-[${vars.colors.fg}]`
147
- */
148
- declare function createMultiTheme<T extends TokenMap>(config: MultiThemeConfig<T>): {
149
- registry: ThemeRegistry;
150
- vars: ThemeVars<T>;
151
- light: Theme<T>;
152
- dark: Theme<T>;
153
- };
154
- interface DesignTokens {
155
- [path: string]: string | DesignTokens;
156
- }
157
- /**
158
- * Flatten nested design token object into CSS variables.
159
- * Supports Figma-style nested tokens.
160
- *
161
- * @example
162
- * compileDesignTokens({
163
- * color: {
164
- * brand: { primary: "#3b82f6", secondary: "#6366f1" },
165
- * neutral: { 50: "#fafafa", 900: "#09090b" }
166
- * },
167
- * spacing: { base: "4px", lg: "16px" }
168
- * })
169
- * →
170
- * :root {
171
- * --color-brand-primary: #3b82f6;
172
- * --color-brand-secondary: #6366f1;
173
- * --color-neutral-50: #fafafa;
174
- * --color-neutral-900: #09090b;
175
- * --spacing-base: 4px;
176
- * --spacing-lg: 16px;
177
- * }
178
- */
179
- declare function compileDesignTokens(tokens: DesignTokens, prefix?: string): string;
180
-
181
- export { type DesignTokens, type MultiThemeConfig, type Theme, type ThemeContract, ThemeRegistry, type ThemeVars, type TokenMap, compileDesignTokens, createMultiTheme, createTheme, defineThemeContract };
package/dist/theme.d.ts DELETED
@@ -1,181 +0,0 @@
1
- /**
2
- * tailwind-styled-v4 — Multi-Theme Engine
3
- *
4
- * Enterprise-grade theming. Support light/dark/brand themes dengan
5
- * CSS variables. Zero runtime overhead — themes di-resolve via CSS.
6
- *
7
- * Fitur:
8
- * - Multiple named themes (light, dark, brand, high-contrast)
9
- * - CSS variable output (Tailwind v4 compatible)
10
- * - Theme contract (TypeScript-safe — missing tokens = TS error)
11
- * - Per-component theme override
12
- * - White-label ready
13
- *
14
- * @example
15
- * // 1. Define contract
16
- * const contract = defineThemeContract({
17
- * colors: { bg: "", fg: "", primary: "", muted: "" },
18
- * font: { sans: "", mono: "" },
19
- * })
20
- *
21
- * // 2. Create themes
22
- * const lightTheme = createTheme(contract, "light", {
23
- * colors: { bg: "#ffffff", fg: "#09090b", primary: "#3b82f6", muted: "#71717a" },
24
- * font: { sans: "InterVariable, sans-serif", mono: "JetBrains Mono, monospace" },
25
- * })
26
- *
27
- * const darkTheme = createTheme(contract, "dark", {
28
- * colors: { bg: "#09090b", fg: "#fafafa", primary: "#60a5fa", muted: "#a1a1aa" },
29
- * font: { sans: "InterVariable, sans-serif", mono: "JetBrains Mono, monospace" },
30
- * })
31
- *
32
- * // 3. Use tokens in components
33
- * const Card = tw.div`bg-[var(--colors-bg)] text-[var(--colors-fg)] p-6`
34
- *
35
- * // 4. Apply in layout
36
- * // <html data-theme="dark"> or inject CSS
37
- */
38
- type TokenMap = Record<string, Record<string, string>>;
39
- interface ThemeContract<T extends TokenMap> {
40
- _contract: T;
41
- _vars: ThemeVars<T>;
42
- }
43
- type ThemeVars<T extends TokenMap> = {
44
- [Group in keyof T]: {
45
- [Token in keyof T[Group]]: string;
46
- };
47
- };
48
- interface Theme<T extends TokenMap> {
49
- name: string;
50
- contract: ThemeContract<T>;
51
- values: T;
52
- /** CSS string to inject (`:root` or `[data-theme="name"]`) */
53
- css: string;
54
- /** CSS variables as a flat record */
55
- vars: Record<string, string>;
56
- /** Apply this theme to an element via data attribute */
57
- selector: string;
58
- }
59
- /**
60
- * Define the shape of your theme. All themes must satisfy this contract.
61
- * Returns typed CSS variable references for use in tw components.
62
- *
63
- * @example
64
- * const contract = defineThemeContract({
65
- * colors: { bg: "", fg: "", primary: "" },
66
- * font: { sans: "" },
67
- * })
68
- *
69
- * // Use in components:
70
- * const Card = tw.div`bg-[${contract._vars.colors.bg}]`
71
- * // → tw.div`bg-[var(--colors-bg)]`
72
- */
73
- declare function defineThemeContract<T extends TokenMap>(shape: T): ThemeContract<T>;
74
- /**
75
- * Create a typed theme that satisfies a contract.
76
- *
77
- * @param contract - Theme contract from defineThemeContract()
78
- * @param name - Theme name ("light", "dark", "brand", etc.)
79
- * @param values - Token values (TypeScript enforces completeness)
80
- * @param asRoot - If true, use :root selector. Default: false (uses [data-theme])
81
- */
82
- declare function createTheme<T extends TokenMap>(contract: ThemeContract<T>, name: string, values: T, asRoot?: boolean): Theme<T>;
83
- declare class ThemeRegistry {
84
- private themes;
85
- private defaultTheme;
86
- /** Register a theme */
87
- register<T extends TokenMap>(theme: Theme<T>, isDefault?: boolean): this;
88
- /** Get a theme by name */
89
- get(name: string): Theme<any> | undefined;
90
- /** Get all theme names */
91
- names(): string[];
92
- /**
93
- * Generate combined CSS for all themes.
94
- * Inject into <head> or a .css file.
95
- *
96
- * @example
97
- * // In globals.css or layout.tsx
98
- * const css = registry.generateCss()
99
- */
100
- generateCss(): string;
101
- /**
102
- * Get the CSS for a specific theme only.
103
- */
104
- getThemeCss(name: string): string | null;
105
- /**
106
- * Inject all theme CSS into document <head> (browser only).
107
- * Call once on app init.
108
- */
109
- inject(styleId?: string): void;
110
- /**
111
- * Switch active theme by setting data-theme on <html>.
112
- */
113
- apply(name: string, target?: HTMLElement): void;
114
- /**
115
- * Get current active theme name from data-theme attribute.
116
- */
117
- current(target?: HTMLElement): string | null;
118
- }
119
- interface MultiThemeConfig<T extends TokenMap> {
120
- contract: ThemeContract<T>;
121
- light: T;
122
- dark: T;
123
- /** Additional named themes (brand, high-contrast, etc.) */
124
- extras?: Record<string, T>;
125
- }
126
- /**
127
- * Create a ThemeRegistry with light/dark + optional extras in one call.
128
- *
129
- * @example
130
- * const { registry, vars } = createMultiTheme({
131
- * contract: defineThemeContract({
132
- * colors: { bg: "", fg: "", primary: "", border: "" }
133
- * }),
134
- * light: {
135
- * colors: { bg: "#fff", fg: "#09090b", primary: "#3b82f6", border: "#e5e7eb" }
136
- * },
137
- * dark: {
138
- * colors: { bg: "#09090b", fg: "#fafafa", primary: "#60a5fa", border: "#27272a" }
139
- * },
140
- * })
141
- *
142
- * // Inject CSS:
143
- * registry.inject()
144
- *
145
- * // Use tokens in components:
146
- * const Card = tw.div`bg-[${vars.colors.bg}] text-[${vars.colors.fg}]`
147
- */
148
- declare function createMultiTheme<T extends TokenMap>(config: MultiThemeConfig<T>): {
149
- registry: ThemeRegistry;
150
- vars: ThemeVars<T>;
151
- light: Theme<T>;
152
- dark: Theme<T>;
153
- };
154
- interface DesignTokens {
155
- [path: string]: string | DesignTokens;
156
- }
157
- /**
158
- * Flatten nested design token object into CSS variables.
159
- * Supports Figma-style nested tokens.
160
- *
161
- * @example
162
- * compileDesignTokens({
163
- * color: {
164
- * brand: { primary: "#3b82f6", secondary: "#6366f1" },
165
- * neutral: { 50: "#fafafa", 900: "#09090b" }
166
- * },
167
- * spacing: { base: "4px", lg: "16px" }
168
- * })
169
- * →
170
- * :root {
171
- * --color-brand-primary: #3b82f6;
172
- * --color-brand-secondary: #6366f1;
173
- * --color-neutral-50: #fafafa;
174
- * --color-neutral-900: #09090b;
175
- * --spacing-base: 4px;
176
- * --spacing-lg: 16px;
177
- * }
178
- */
179
- declare function compileDesignTokens(tokens: DesignTokens, prefix?: string): string;
180
-
181
- export { type DesignTokens, type MultiThemeConfig, type Theme, type ThemeContract, ThemeRegistry, type ThemeVars, type TokenMap, compileDesignTokens, createMultiTheme, createTheme, defineThemeContract };
package/dist/theme.js DELETED
@@ -1,148 +0,0 @@
1
- /* tailwind-styled-v4 v4 | MIT | https://github.com/dictionar32/tailwind-styled-v4 */
2
-
3
- // ../theme/src/index.ts
4
- function defineThemeContract(shape) {
5
- const vars = {};
6
- for (const group in shape) {
7
- vars[group] = {};
8
- for (const token in shape[group]) {
9
- vars[group][token] = `var(--${group}-${token})`;
10
- }
11
- }
12
- return { _contract: shape, _vars: vars };
13
- }
14
- function createTheme(contract, name, values, asRoot = false) {
15
- const flatVars = {};
16
- const cssLines = [];
17
- for (const group in values) {
18
- for (const token in values[group]) {
19
- const varName = `--${group}-${token}`;
20
- const value = values[group][token];
21
- flatVars[varName] = value;
22
- cssLines.push(` ${varName}: ${value};`);
23
- }
24
- }
25
- const selector = asRoot ? ":root" : `[data-theme="${name}"]`;
26
- const css = `${selector} {
27
- ${cssLines.join("\n")}
28
- }`;
29
- return {
30
- name,
31
- contract,
32
- values,
33
- css,
34
- vars: flatVars,
35
- selector
36
- };
37
- }
38
- var ThemeRegistry = class {
39
- constructor() {
40
- this.themes = /* @__PURE__ */ new Map();
41
- this.defaultTheme = null;
42
- }
43
- /** Register a theme */
44
- register(theme, isDefault = false) {
45
- this.themes.set(theme.name, theme);
46
- if (isDefault || !this.defaultTheme) {
47
- this.defaultTheme = theme.name;
48
- }
49
- return this;
50
- }
51
- /** Get a theme by name */
52
- get(name) {
53
- return this.themes.get(name);
54
- }
55
- /** Get all theme names */
56
- names() {
57
- return Array.from(this.themes.keys());
58
- }
59
- /**
60
- * Generate combined CSS for all themes.
61
- * Inject into <head> or a .css file.
62
- *
63
- * @example
64
- * // In globals.css or layout.tsx
65
- * const css = registry.generateCss()
66
- */
67
- generateCss() {
68
- return Array.from(this.themes.values()).map((t) => t.css).join("\n\n");
69
- }
70
- /**
71
- * Get the CSS for a specific theme only.
72
- */
73
- getThemeCss(name) {
74
- var _a, _b;
75
- return (_b = (_a = this.themes.get(name)) == null ? void 0 : _a.css) != null ? _b : null;
76
- }
77
- /**
78
- * Inject all theme CSS into document <head> (browser only).
79
- * Call once on app init.
80
- */
81
- inject(styleId = "__tw_themes") {
82
- if (typeof document === "undefined") return;
83
- let style = document.getElementById(styleId);
84
- if (!style) {
85
- style = document.createElement("style");
86
- style.id = styleId;
87
- document.head.appendChild(style);
88
- }
89
- style.textContent = this.generateCss();
90
- }
91
- /**
92
- * Switch active theme by setting data-theme on <html>.
93
- */
94
- apply(name, target = document.documentElement) {
95
- if (typeof document === "undefined") return;
96
- if (!this.themes.has(name)) {
97
- console.warn(`[tailwind-styled-v4] Theme "${name}" not registered.`);
98
- return;
99
- }
100
- target.dataset.theme = name;
101
- }
102
- /**
103
- * Get current active theme name from data-theme attribute.
104
- */
105
- current(target = document.documentElement) {
106
- var _a;
107
- if (typeof document === "undefined") return this.defaultTheme;
108
- return (_a = target.dataset.theme) != null ? _a : this.defaultTheme;
109
- }
110
- };
111
- function createMultiTheme(config) {
112
- var _a;
113
- const registry = new ThemeRegistry();
114
- const light = createTheme(config.contract, "light", config.light, true);
115
- const dark = createTheme(config.contract, "dark", config.dark, false);
116
- registry.register(light, true);
117
- registry.register(dark);
118
- for (const [name, values] of Object.entries((_a = config.extras) != null ? _a : {})) {
119
- registry.register(createTheme(config.contract, name, values));
120
- }
121
- return {
122
- registry,
123
- vars: config.contract._vars,
124
- light,
125
- dark
126
- };
127
- }
128
- function compileDesignTokens(tokens, prefix = "") {
129
- const vars = [];
130
- function flatten(obj, path) {
131
- for (const [key, value] of Object.entries(obj)) {
132
- const varPath = path ? `${path}-${key}` : key;
133
- if (typeof value === "string") {
134
- vars.push(` --${varPath}: ${value};`);
135
- } else {
136
- flatten(value, varPath);
137
- }
138
- }
139
- }
140
- flatten(tokens, prefix);
141
- return `:root {
142
- ${vars.join("\n")}
143
- }`;
144
- }
145
-
146
- export { ThemeRegistry, compileDesignTokens, createMultiTheme, createTheme, defineThemeContract };
147
- //# sourceMappingURL=theme.js.map
148
- //# sourceMappingURL=theme.js.map
package/dist/theme.js.map DELETED
@@ -1 +0,0 @@
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"]}