tailwind-styled-v4 5.0.0 → 5.0.2

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (180) hide show
  1. package/CHANGELOG.md +398 -0
  2. package/LICENSE +21 -0
  3. package/README.md +532 -0
  4. package/dist/analyzer.d.mts +114 -0
  5. package/dist/analyzer.d.ts +114 -0
  6. package/dist/analyzer.js +6808 -0
  7. package/dist/analyzer.js.map +1 -0
  8. package/dist/analyzer.mjs +6798 -0
  9. package/dist/analyzer.mjs.map +1 -0
  10. package/dist/{animate.d.cts → animate.d.mts} +3 -30
  11. package/dist/animate.d.ts +3 -30
  12. package/dist/animate.js +7096 -352
  13. package/dist/animate.js.map +1 -1
  14. package/dist/animate.mjs +7482 -0
  15. package/dist/animate.mjs.map +1 -0
  16. package/dist/atomic.d.mts +18 -0
  17. package/dist/atomic.d.ts +18 -0
  18. package/dist/atomic.js +191 -0
  19. package/dist/atomic.js.map +1 -0
  20. package/dist/atomic.mjs +185 -0
  21. package/dist/atomic.mjs.map +1 -0
  22. package/dist/cli.d.mts +1 -0
  23. package/dist/cli.d.ts +1 -0
  24. package/dist/cli.js +45008 -0
  25. package/dist/cli.js.map +1 -0
  26. package/dist/cli.mjs +44980 -0
  27. package/dist/cli.mjs.map +1 -0
  28. package/dist/compiler.d.mts +1009 -0
  29. package/dist/compiler.d.ts +1009 -0
  30. package/dist/compiler.js +4937 -0
  31. package/dist/compiler.js.map +1 -0
  32. package/dist/compiler.mjs +4862 -0
  33. package/dist/compiler.mjs.map +1 -0
  34. package/dist/dashboard.d.mts +272 -0
  35. package/dist/dashboard.d.ts +272 -0
  36. package/dist/dashboard.js +249 -0
  37. package/dist/dashboard.js.map +1 -0
  38. package/dist/dashboard.mjs +239 -0
  39. package/dist/dashboard.mjs.map +1 -0
  40. package/dist/devtools.js +171 -158
  41. package/dist/devtools.js.map +1 -1
  42. package/dist/{devtools.cjs → devtools.mjs} +166 -167
  43. package/dist/devtools.mjs.map +1 -0
  44. package/dist/engine.d.mts +398 -0
  45. package/dist/engine.d.ts +398 -0
  46. package/dist/engine.js +19264 -0
  47. package/dist/engine.js.map +1 -0
  48. package/dist/engine.mjs +19227 -0
  49. package/dist/engine.mjs.map +1 -0
  50. package/dist/{index.d.cts → index.d.mts} +12 -5
  51. package/dist/index.d.ts +12 -5
  52. package/dist/index.js +7178 -27
  53. package/dist/index.js.map +1 -1
  54. package/dist/index.mjs +8408 -0
  55. package/dist/index.mjs.map +1 -0
  56. package/dist/liveTokenEngine-DYN3Zale.d.mts +34 -0
  57. package/dist/liveTokenEngine-DYN3Zale.d.ts +34 -0
  58. package/dist/{next.d.cts → next.d.mts} +2 -1
  59. package/dist/next.d.ts +2 -1
  60. package/dist/next.js +24027 -28
  61. package/dist/next.js.map +1 -1
  62. package/dist/next.mjs +24232 -0
  63. package/dist/next.mjs.map +1 -0
  64. package/dist/plugin.d.mts +90 -0
  65. package/dist/plugin.d.ts +90 -0
  66. package/dist/plugin.js +185 -0
  67. package/dist/plugin.js.map +1 -0
  68. package/dist/plugin.mjs +174 -0
  69. package/dist/plugin.mjs.map +1 -0
  70. package/dist/pluginRegistry.d.mts +83 -0
  71. package/dist/pluginRegistry.d.ts +83 -0
  72. package/dist/pluginRegistry.js +303 -0
  73. package/dist/pluginRegistry.js.map +1 -0
  74. package/dist/pluginRegistry.mjs +298 -0
  75. package/dist/pluginRegistry.mjs.map +1 -0
  76. package/dist/preset.js +9 -4
  77. package/dist/preset.js.map +1 -1
  78. package/dist/{preset.cjs → preset.mjs} +5 -14
  79. package/dist/preset.mjs.map +1 -0
  80. package/dist/rspack.d.mts +33 -0
  81. package/dist/rspack.d.ts +33 -0
  82. package/dist/rspack.js +66 -0
  83. package/dist/rspack.js.map +1 -0
  84. package/dist/rspack.mjs +55 -0
  85. package/dist/rspack.mjs.map +1 -0
  86. package/dist/runtime.d.mts +62 -0
  87. package/dist/runtime.d.ts +62 -0
  88. package/dist/runtime.js +455 -0
  89. package/dist/runtime.js.map +1 -0
  90. package/dist/runtime.mjs +436 -0
  91. package/dist/runtime.mjs.map +1 -0
  92. package/dist/runtimeCss.d.mts +65 -0
  93. package/dist/runtimeCss.d.ts +65 -0
  94. package/dist/{css.cjs → runtimeCss.js} +71 -4
  95. package/dist/runtimeCss.js.map +1 -0
  96. package/dist/{css.js → runtimeCss.mjs} +66 -5
  97. package/dist/runtimeCss.mjs.map +1 -0
  98. package/dist/scanner.d.mts +25 -0
  99. package/dist/scanner.d.ts +25 -0
  100. package/dist/scanner.js +5774 -0
  101. package/dist/scanner.js.map +1 -0
  102. package/dist/scanner.mjs +5760 -0
  103. package/dist/scanner.mjs.map +1 -0
  104. package/dist/shared.d.mts +85 -0
  105. package/dist/shared.d.ts +85 -0
  106. package/dist/shared.js +255 -0
  107. package/dist/shared.js.map +1 -0
  108. package/dist/shared.mjs +233 -0
  109. package/dist/shared.mjs.map +1 -0
  110. package/dist/storybookAddon.d.mts +108 -0
  111. package/dist/storybookAddon.d.ts +108 -0
  112. package/dist/storybookAddon.js +95 -0
  113. package/dist/storybookAddon.js.map +1 -0
  114. package/dist/storybookAddon.mjs +88 -0
  115. package/dist/storybookAddon.mjs.map +1 -0
  116. package/dist/svelte.d.mts +114 -0
  117. package/dist/svelte.d.ts +114 -0
  118. package/dist/svelte.js +67 -0
  119. package/dist/svelte.js.map +1 -0
  120. package/dist/svelte.mjs +59 -0
  121. package/dist/svelte.mjs.map +1 -0
  122. package/dist/testing.d.mts +185 -0
  123. package/dist/testing.d.ts +185 -0
  124. package/dist/testing.js +173 -0
  125. package/dist/testing.js.map +1 -0
  126. package/dist/testing.mjs +158 -0
  127. package/dist/testing.mjs.map +1 -0
  128. package/dist/theme.d.mts +188 -0
  129. package/dist/theme.d.ts +188 -0
  130. package/dist/theme.js +334 -0
  131. package/dist/theme.js.map +1 -0
  132. package/dist/theme.mjs +311 -0
  133. package/dist/theme.mjs.map +1 -0
  134. package/dist/tsconfig.tsbuildinfo +1 -0
  135. package/dist/types-DXr2PmGP.d.mts +31 -0
  136. package/dist/types-DXr2PmGP.d.ts +31 -0
  137. package/dist/vite.js +29611 -17
  138. package/dist/vite.js.map +1 -1
  139. package/dist/vite.mjs +29712 -0
  140. package/dist/vite.mjs.map +1 -0
  141. package/dist/vue.d.mts +89 -0
  142. package/dist/vue.d.ts +89 -0
  143. package/dist/vue.js +104 -0
  144. package/dist/vue.js.map +1 -0
  145. package/dist/vue.mjs +96 -0
  146. package/dist/vue.mjs.map +1 -0
  147. package/package.json +170 -64
  148. package/dist/animate.cjs +0 -771
  149. package/dist/animate.cjs.map +0 -1
  150. package/dist/chunk-VZEJV27B.js +0 -11
  151. package/dist/chunk-VZEJV27B.js.map +0 -1
  152. package/dist/chunk-Y5D3E72P.cjs +0 -13
  153. package/dist/chunk-Y5D3E72P.cjs.map +0 -1
  154. package/dist/css.cjs.map +0 -1
  155. package/dist/css.d.cts +0 -30
  156. package/dist/css.d.ts +0 -30
  157. package/dist/css.js.map +0 -1
  158. package/dist/devtools.cjs.map +0 -1
  159. package/dist/index.cjs +0 -1353
  160. package/dist/index.cjs.map +0 -1
  161. package/dist/next.cjs +0 -248
  162. package/dist/next.cjs.map +0 -1
  163. package/dist/preset.cjs.map +0 -1
  164. package/dist/turbopackLoader.cjs +0 -37
  165. package/dist/turbopackLoader.cjs.map +0 -1
  166. package/dist/turbopackLoader.d.cts +0 -12
  167. package/dist/turbopackLoader.d.ts +0 -12
  168. package/dist/turbopackLoader.js +0 -35
  169. package/dist/turbopackLoader.js.map +0 -1
  170. package/dist/vite.cjs +0 -138
  171. package/dist/vite.cjs.map +0 -1
  172. package/dist/webpackLoader.cjs +0 -51
  173. package/dist/webpackLoader.cjs.map +0 -1
  174. package/dist/webpackLoader.d.cts +0 -17
  175. package/dist/webpackLoader.d.ts +0 -17
  176. package/dist/webpackLoader.js +0 -49
  177. package/dist/webpackLoader.js.map +0 -1
  178. /package/dist/{devtools.d.cts → devtools.d.mts} +0 -0
  179. /package/dist/{preset.d.cts → preset.d.mts} +0 -0
  180. /package/dist/{vite.d.cts → vite.d.mts} +0 -0
@@ -0,0 +1,88 @@
1
+ /* tailwind-styled-v4 v5.0.1 | MIT | https://github.com/dictionar32/tailwind-styled-v4 */
2
+
3
+ // packages/storybook-addon/src/index.ts
4
+ function enumerateVariantProps(matrix) {
5
+ const keys = Object.keys(matrix);
6
+ if (keys.length === 0) return [{}];
7
+ const result = [];
8
+ function walk(index, current) {
9
+ if (index >= keys.length) {
10
+ result.push({ ...current });
11
+ return;
12
+ }
13
+ const key = keys[index];
14
+ for (const value of matrix[key] ?? []) {
15
+ current[key] = value;
16
+ walk(index + 1, current);
17
+ }
18
+ }
19
+ walk(0, {});
20
+ return result;
21
+ }
22
+ function generateArgTypes(config) {
23
+ if (!config.variants) return {};
24
+ const argTypes = {};
25
+ for (const [variantKey, variantValues] of Object.entries(config.variants)) {
26
+ const options = Object.keys(variantValues);
27
+ const defaultValue = config.defaultVariants?.[variantKey];
28
+ argTypes[variantKey] = {
29
+ control: { type: "select" },
30
+ options,
31
+ defaultValue,
32
+ description: `Variant: **${variantKey}**`,
33
+ table: {
34
+ type: { summary: options.join(" | ") },
35
+ defaultValue: defaultValue ? { summary: defaultValue } : void 0,
36
+ category: "Variants"
37
+ }
38
+ };
39
+ }
40
+ return argTypes;
41
+ }
42
+ function generateDefaultArgs(config) {
43
+ return { ...config.defaultVariants ?? void 0 };
44
+ }
45
+ function withTailwindStyled(StoryFn, context) {
46
+ const wrapperClass = context.parameters?.tailwindStyled?.wrapperClass ?? "";
47
+ const padding = context.parameters?.tailwindStyled?.padding ?? "p-8";
48
+ if (typeof document !== "undefined") {
49
+ const wrapper = document.createElement("div");
50
+ wrapper.className = [padding, wrapperClass].filter(Boolean).join(" ");
51
+ return wrapper;
52
+ }
53
+ return StoryFn();
54
+ }
55
+ function createVariantStoryArgs(config) {
56
+ if (!config.variants) return { combinations: [{}], matrix: {} };
57
+ const matrix = {};
58
+ for (const [key, values] of Object.entries(config.variants)) {
59
+ matrix[key] = Object.keys(values);
60
+ }
61
+ return {
62
+ combinations: enumerateVariantProps(matrix),
63
+ matrix
64
+ };
65
+ }
66
+ function getVariantClass(config, props) {
67
+ const classes = [];
68
+ if (config.base) classes.push(config.base);
69
+ if (config.variants) {
70
+ for (const [key, values] of Object.entries(config.variants)) {
71
+ const val = props[key] ?? config.defaultVariants?.[key];
72
+ if (val && values[val]) classes.push(values[val]);
73
+ }
74
+ }
75
+ if (config.compoundVariants) {
76
+ for (const compound of config.compoundVariants) {
77
+ const { class: cls, ...conditions } = compound;
78
+ if (Object.entries(conditions).every(([k, v]) => props[k] === v)) {
79
+ classes.push(cls);
80
+ }
81
+ }
82
+ }
83
+ return classes.join(" ");
84
+ }
85
+
86
+ export { createVariantStoryArgs, enumerateVariantProps, generateArgTypes, generateDefaultArgs, getVariantClass, withTailwindStyled };
87
+ //# sourceMappingURL=storybookAddon.mjs.map
88
+ //# sourceMappingURL=storybookAddon.mjs.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../packages/storybook-addon/src/index.ts"],"names":[],"mappings":"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","file":"storybookAddon.mjs","sourcesContent":["/**\n * tailwind-styled-v4 — Storybook Addon\n *\n * Integrasi Storybook untuk komponen tw().\n * Fitur:\n * - withTailwindStyled decorator: inject className ke story\n * - generateArgTypes: auto-generate controls dari ComponentConfig\n * - enumerateVariantProps: buat semua kombinasi variant untuk testing\n *\n * @example\n * // .storybook/preview.ts\n * import { withTailwindStyled } from '@tailwind-styled/storybook-addon'\n * export const decorators = [withTailwindStyled]\n *\n * // Button.stories.ts\n * import { generateArgTypes } from '@tailwind-styled/storybook-addon'\n * import { buttonConfig } from './Button'\n *\n * export default {\n * title: 'Components/Button',\n * component: Button,\n * argTypes: generateArgTypes(buttonConfig),\n * }\n */\n\n// ─── Types ────────────────────────────────────────────────────────────────────\n\nexport type VariantMatrix = Record<string, Array<string | number | boolean>>\n\nexport interface ComponentConfig {\n base?: string\n variants?: Record<string, Record<string, string>>\n defaultVariants?: Record<string, string>\n compoundVariants?: Array<{ class: string; [key: string]: any }>\n}\n\n// ─── Variant enumeration (core utility) ──────────────────────────────────────\n\n/**\n * Enumerate semua kombinasi variant dari matrix.\n *\n * @example\n * enumerateVariantProps({ size: ['sm','lg'], intent: ['primary','danger'] })\n * // → [{ size:'sm', intent:'primary' }, { size:'sm', intent:'danger' }, ...]\n */\nexport function enumerateVariantProps(\n matrix: VariantMatrix\n): Array<Record<string, string | number | boolean>> {\n const keys = Object.keys(matrix)\n if (keys.length === 0) return [{}]\n\n const result: Array<Record<string, string | number | boolean>> = []\n\n function walk(index: number, current: Record<string, string | number | boolean>) {\n if (index >= keys.length) {\n result.push({ ...current })\n return\n }\n const key = keys[index]!\n for (const value of matrix[key] ?? []) {\n current[key] = value\n walk(index + 1, current)\n }\n }\n\n walk(0, {})\n return result\n}\n\n// ─── Storybook argTypes generator ─────────────────────────────────────────────\n\n/**\n * Generate Storybook argTypes dari ComponentConfig.\n * Otomatis membuat kontrol dropdown untuk setiap variant.\n *\n * @example\n * export default {\n * title: 'Components/Button',\n * argTypes: generateArgTypes({\n * variants: {\n * intent: { primary: '...', danger: '...' },\n * size: { sm: '...', md: '...', lg: '...' },\n * },\n * defaultVariants: { intent: 'primary', size: 'md' },\n * })\n * }\n */\nexport function generateArgTypes(config: ComponentConfig): Record<string, unknown> {\n if (!config.variants) return {}\n\n const argTypes: Record<string, unknown> = {}\n\n for (const [variantKey, variantValues] of Object.entries(config.variants)) {\n const options = Object.keys(variantValues)\n const defaultValue = config.defaultVariants?.[variantKey]\n\n argTypes[variantKey] = {\n control: { type: \"select\" },\n options,\n defaultValue,\n description: `Variant: **${variantKey}**`,\n table: {\n type: { summary: options.join(\" | \") },\n defaultValue: defaultValue ? { summary: defaultValue } : undefined,\n category: \"Variants\",\n },\n }\n }\n\n return argTypes\n}\n\n/**\n * Generate default args dari ComponentConfig.\n *\n * @example\n * export default {\n * args: generateDefaultArgs(buttonConfig),\n * }\n */\nexport function generateDefaultArgs(config: ComponentConfig): Record<string, string> {\n return { ...(config.defaultVariants ?? undefined) }\n}\n\n// ─── Storybook decorator ───────────────────────────────────────────────────────\n\n/**\n * Storybook decorator yang inject className dari args ke story.\n * Compatible dengan Storybook 7+ (CSF3).\n *\n * @example\n * // .storybook/preview.ts\n * import { withTailwindStyled } from '@tailwind-styled/storybook-addon'\n * export const decorators = [withTailwindStyled]\n */\nexport function withTailwindStyled(\n StoryFn: () => unknown,\n context: {\n args?: Record<string, unknown>\n parameters?: { tailwindStyled?: { wrapperClass?: string; padding?: string } }\n }\n): unknown {\n const wrapperClass = context.parameters?.tailwindStyled?.wrapperClass ?? \"\"\n const padding = context.parameters?.tailwindStyled?.padding ?? \"p-8\"\n\n // Wrap story dalam div dengan class dari parameters\n // Ini memungkinkan dark mode testing, custom backgrounds, dll\n if (typeof document !== \"undefined\") {\n const wrapper = document.createElement(\"div\")\n wrapper.className = [padding, wrapperClass].filter(Boolean).join(\" \")\n return wrapper\n }\n\n return StoryFn()\n}\n\n// ─── Story template helpers ────────────────────────────────────────────────────\n\n/**\n * Buat \"All Variants\" story yang menampilkan semua kombinasi variant.\n * Berguna untuk visual regression testing.\n *\n * @example\n * export const AllVariants = createAllVariantsStory(Button, buttonConfig)\n */\nexport function createVariantStoryArgs(config: ComponentConfig): {\n combinations: Array<Record<string, string | number | boolean>>\n matrix: VariantMatrix\n} {\n if (!config.variants) return { combinations: [{}], matrix: {} }\n\n const matrix: VariantMatrix = {}\n for (const [key, values] of Object.entries(config.variants)) {\n matrix[key] = Object.keys(values)\n }\n\n return {\n combinations: enumerateVariantProps(matrix),\n matrix,\n }\n}\n\n/**\n * Extract class string untuk variant props dari config.\n * Berguna untuk manual class lookup di stories.\n *\n * @example\n * const cls = getVariantClass(buttonConfig, { intent: 'primary', size: 'lg' })\n * // → 'bg-blue-500 text-white h-12 text-lg'\n */\nexport function getVariantClass(config: ComponentConfig, props: Record<string, string>): string {\n const classes: string[] = []\n\n if (config.base) classes.push(config.base)\n\n if (config.variants) {\n for (const [key, values] of Object.entries(config.variants)) {\n const val = props[key] ?? config.defaultVariants?.[key]\n if (val && values[val]) classes.push(values[val])\n }\n }\n\n if (config.compoundVariants) {\n for (const compound of config.compoundVariants) {\n const { class: cls, ...conditions } = compound\n if (Object.entries(conditions).every(([k, v]) => props[k] === v)) {\n classes.push(cls)\n }\n }\n }\n\n return classes.join(\" \")\n}\n"]}
@@ -0,0 +1,114 @@
1
+ /**
2
+ * tailwind-styled-v4 — Svelte Adapter
3
+ *
4
+ * Svelte 4+ adapter menggunakan action dan store pattern.
5
+ * Kompatibel dengan Svelte 5 runes mode.
6
+ *
7
+ * Dua pola yang didukung:
8
+ * 1. `tw()` — buat class string resolver untuk dipakai di template
9
+ * 2. `createSvelteComponent()` — buat Svelte component via Svelte API
10
+ *
11
+ * @example
12
+ * <!-- Pola 1: tw() sebagai class resolver -->
13
+ * <script>
14
+ * import { cv } from '@tailwind-styled/svelte'
15
+ *
16
+ * const buttonClass = cv({
17
+ * base: 'px-4 py-2 rounded font-medium',
18
+ * variants: {
19
+ * intent: { primary: 'bg-blue-500 text-white', danger: 'bg-red-500 text-white' },
20
+ * size: { sm: 'h-8 text-sm', lg: 'h-12 text-lg' },
21
+ * },
22
+ * defaultVariants: { intent: 'primary', size: 'sm' },
23
+ * })
24
+ *
25
+ * export let intent = 'primary'
26
+ * export let size = 'sm'
27
+ * </script>
28
+ *
29
+ * <button class={buttonClass({ intent, size })}>
30
+ * <slot />
31
+ * </button>
32
+ */
33
+ interface SvelteComponentConfig {
34
+ base?: string;
35
+ variants?: Record<string, Record<string, string>>;
36
+ compoundVariants?: Array<{
37
+ class: string;
38
+ [key: string]: any;
39
+ }>;
40
+ defaultVariants?: Record<string, string>;
41
+ }
42
+ /**
43
+ * Class variant resolver — pola utama untuk Svelte.
44
+ * Returns fungsi yang menerima props dan mengembalikan class string.
45
+ *
46
+ * Gunakan ini di `<script>` block, lalu panggil di template.
47
+ *
48
+ * @example
49
+ * const button = cv({
50
+ * base: 'px-4 py-2 rounded',
51
+ * variants: { size: { sm: 'h-8', lg: 'h-12' } },
52
+ * })
53
+ *
54
+ * // Di template: class={button({ size: 'lg' })}
55
+ */
56
+ declare function cv(config: SvelteComponentConfig): (props?: Record<string, any>) => string;
57
+ /**
58
+ * Simple class merger — berguna untuk merge class dinamis.
59
+ *
60
+ * @example
61
+ * import { tw } from '@tailwind-styled/svelte'
62
+ *
63
+ * // Merge class string
64
+ * const cls = tw('px-4 py-2', isActive && 'bg-blue-500', className)
65
+ */
66
+ declare function tw(...classes: Array<string | boolean | null | undefined>): string;
67
+ /**
68
+ * Svelte action untuk menerapkan class dinamis.
69
+ *
70
+ * @example
71
+ * <script>
72
+ * import { styled } from '@tailwind-styled/svelte'
73
+ * const buttonConfig = { base: 'px-4 py-2', variants: { size: { sm: 'h-8', lg: 'h-12' } } }
74
+ * </script>
75
+ *
76
+ * <button use:styled={{ config: buttonConfig, props: { size: 'lg' } }}>
77
+ * Click me
78
+ * </button>
79
+ */
80
+ declare function styled(node: HTMLElement, { config, props }: {
81
+ config: SvelteComponentConfig;
82
+ props?: Record<string, any>;
83
+ }): {
84
+ update: ({ config: cfg, props: p, }: {
85
+ config: SvelteComponentConfig;
86
+ props?: Record<string, any>;
87
+ }) => void;
88
+ destroy(): void;
89
+ };
90
+ /**
91
+ * Svelte 5 runes-compatible variant factory.
92
+ * Mengembalikan reactive class string menggunakan $derived pattern.
93
+ *
94
+ * @example
95
+ * // Dalam Svelte 5 component:
96
+ * const { className, variantProps } = createVariants({
97
+ * base: 'px-4 py-2',
98
+ * variants: { size: { sm: 'h-8', lg: 'h-12' } },
99
+ * }, () => ({ size: currentSize }))
100
+ *
101
+ * // className adalah fungsi yang return class string terkini
102
+ */
103
+ declare function createVariants(config: SvelteComponentConfig, getProps: () => Record<string, any>): {
104
+ className: () => string;
105
+ config: SvelteComponentConfig;
106
+ };
107
+ declare const _default: {
108
+ cv: typeof cv;
109
+ tw: typeof tw;
110
+ styled: typeof styled;
111
+ createVariants: typeof createVariants;
112
+ };
113
+
114
+ export { type SvelteComponentConfig, createVariants, cv, _default as default, styled, tw };
@@ -0,0 +1,114 @@
1
+ /**
2
+ * tailwind-styled-v4 — Svelte Adapter
3
+ *
4
+ * Svelte 4+ adapter menggunakan action dan store pattern.
5
+ * Kompatibel dengan Svelte 5 runes mode.
6
+ *
7
+ * Dua pola yang didukung:
8
+ * 1. `tw()` — buat class string resolver untuk dipakai di template
9
+ * 2. `createSvelteComponent()` — buat Svelte component via Svelte API
10
+ *
11
+ * @example
12
+ * <!-- Pola 1: tw() sebagai class resolver -->
13
+ * <script>
14
+ * import { cv } from '@tailwind-styled/svelte'
15
+ *
16
+ * const buttonClass = cv({
17
+ * base: 'px-4 py-2 rounded font-medium',
18
+ * variants: {
19
+ * intent: { primary: 'bg-blue-500 text-white', danger: 'bg-red-500 text-white' },
20
+ * size: { sm: 'h-8 text-sm', lg: 'h-12 text-lg' },
21
+ * },
22
+ * defaultVariants: { intent: 'primary', size: 'sm' },
23
+ * })
24
+ *
25
+ * export let intent = 'primary'
26
+ * export let size = 'sm'
27
+ * </script>
28
+ *
29
+ * <button class={buttonClass({ intent, size })}>
30
+ * <slot />
31
+ * </button>
32
+ */
33
+ interface SvelteComponentConfig {
34
+ base?: string;
35
+ variants?: Record<string, Record<string, string>>;
36
+ compoundVariants?: Array<{
37
+ class: string;
38
+ [key: string]: any;
39
+ }>;
40
+ defaultVariants?: Record<string, string>;
41
+ }
42
+ /**
43
+ * Class variant resolver — pola utama untuk Svelte.
44
+ * Returns fungsi yang menerima props dan mengembalikan class string.
45
+ *
46
+ * Gunakan ini di `<script>` block, lalu panggil di template.
47
+ *
48
+ * @example
49
+ * const button = cv({
50
+ * base: 'px-4 py-2 rounded',
51
+ * variants: { size: { sm: 'h-8', lg: 'h-12' } },
52
+ * })
53
+ *
54
+ * // Di template: class={button({ size: 'lg' })}
55
+ */
56
+ declare function cv(config: SvelteComponentConfig): (props?: Record<string, any>) => string;
57
+ /**
58
+ * Simple class merger — berguna untuk merge class dinamis.
59
+ *
60
+ * @example
61
+ * import { tw } from '@tailwind-styled/svelte'
62
+ *
63
+ * // Merge class string
64
+ * const cls = tw('px-4 py-2', isActive && 'bg-blue-500', className)
65
+ */
66
+ declare function tw(...classes: Array<string | boolean | null | undefined>): string;
67
+ /**
68
+ * Svelte action untuk menerapkan class dinamis.
69
+ *
70
+ * @example
71
+ * <script>
72
+ * import { styled } from '@tailwind-styled/svelte'
73
+ * const buttonConfig = { base: 'px-4 py-2', variants: { size: { sm: 'h-8', lg: 'h-12' } } }
74
+ * </script>
75
+ *
76
+ * <button use:styled={{ config: buttonConfig, props: { size: 'lg' } }}>
77
+ * Click me
78
+ * </button>
79
+ */
80
+ declare function styled(node: HTMLElement, { config, props }: {
81
+ config: SvelteComponentConfig;
82
+ props?: Record<string, any>;
83
+ }): {
84
+ update: ({ config: cfg, props: p, }: {
85
+ config: SvelteComponentConfig;
86
+ props?: Record<string, any>;
87
+ }) => void;
88
+ destroy(): void;
89
+ };
90
+ /**
91
+ * Svelte 5 runes-compatible variant factory.
92
+ * Mengembalikan reactive class string menggunakan $derived pattern.
93
+ *
94
+ * @example
95
+ * // Dalam Svelte 5 component:
96
+ * const { className, variantProps } = createVariants({
97
+ * base: 'px-4 py-2',
98
+ * variants: { size: { sm: 'h-8', lg: 'h-12' } },
99
+ * }, () => ({ size: currentSize }))
100
+ *
101
+ * // className adalah fungsi yang return class string terkini
102
+ */
103
+ declare function createVariants(config: SvelteComponentConfig, getProps: () => Record<string, any>): {
104
+ className: () => string;
105
+ config: SvelteComponentConfig;
106
+ };
107
+ declare const _default: {
108
+ cv: typeof cv;
109
+ tw: typeof tw;
110
+ styled: typeof styled;
111
+ createVariants: typeof createVariants;
112
+ };
113
+
114
+ export { type SvelteComponentConfig, createVariants, cv, _default as default, styled, tw };
package/dist/svelte.js ADDED
@@ -0,0 +1,67 @@
1
+ 'use strict';
2
+
3
+ Object.defineProperty(exports, '__esModule', { value: true });
4
+
5
+ var tailwindMerge = require('tailwind-merge');
6
+
7
+ /* tailwind-styled-v4 v5.0.1 | MIT | https://github.com/dictionar32/tailwind-styled-v4 */
8
+
9
+ function resolveVariants(variants, props, defaults = {}) {
10
+ const classes = [];
11
+ for (const key in variants) {
12
+ const val = props[key] ?? defaults[key];
13
+ if (val !== void 0 && variants[key]?.[String(val)]) {
14
+ classes.push(variants[key][String(val)]);
15
+ }
16
+ }
17
+ return classes.join(" ");
18
+ }
19
+ function resolveCompound(compounds, props) {
20
+ return compounds.filter((c) => {
21
+ const { class: _cls, ...conditions } = c;
22
+ return Object.entries(conditions).every(([k, v]) => props[k] === v);
23
+ }).map((c) => c.class).join(" ");
24
+ }
25
+ function cv(config) {
26
+ return (props = {}) => {
27
+ const { base = "", variants = {}, compoundVariants = [], defaultVariants = {} } = config;
28
+ const merged = { ...defaultVariants, ...props };
29
+ const variantClasses = resolveVariants(variants, merged, defaultVariants);
30
+ const compoundClasses = resolveCompound(compoundVariants, merged);
31
+ return tailwindMerge.twMerge(base, variantClasses, compoundClasses, props.class);
32
+ };
33
+ }
34
+ function tw(...classes) {
35
+ return tailwindMerge.twMerge(...classes.filter(Boolean));
36
+ }
37
+ function styled(node, { config, props = {} }) {
38
+ function update({
39
+ config: cfg,
40
+ props: p = {}
41
+ }) {
42
+ const classes = cv(cfg)(p);
43
+ node.className = classes;
44
+ }
45
+ update({ config, props });
46
+ return {
47
+ update,
48
+ destroy() {
49
+ }
50
+ };
51
+ }
52
+ function createVariants(config, getProps) {
53
+ const resolver = cv(config);
54
+ return {
55
+ className: () => resolver(getProps()),
56
+ config
57
+ };
58
+ }
59
+ var src_default = { cv, tw, styled, createVariants };
60
+
61
+ exports.createVariants = createVariants;
62
+ exports.cv = cv;
63
+ exports.default = src_default;
64
+ exports.styled = styled;
65
+ exports.tw = tw;
66
+ //# sourceMappingURL=svelte.js.map
67
+ //# sourceMappingURL=svelte.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../packages/svelte/src/index.ts"],"names":["twMerge"],"mappings":";;;;;;;;AAkDA,SAAS,eAAA,CACP,QAAA,EACA,KAAA,EACA,QAAA,GAAmC,EAAC,EAC5B;AACR,EAAA,MAAM,UAAoB,EAAC;AAC3B,EAAA,KAAA,MAAW,OAAO,QAAA,EAAU;AAC1B,IAAA,MAAM,GAAA,GAAM,KAAA,CAAM,GAAG,CAAA,IAAK,SAAS,GAAG,CAAA;AACtC,IAAA,IAAI,GAAA,KAAQ,UAAa,QAAA,CAAS,GAAG,IAAI,MAAA,CAAO,GAAG,CAAC,CAAA,EAAG;AACrD,MAAA,OAAA,CAAQ,KAAK,QAAA,CAAS,GAAG,EAAE,MAAA,CAAO,GAAG,CAAC,CAAC,CAAA;AAAA,IACzC;AAAA,EACF;AACA,EAAA,OAAO,OAAA,CAAQ,KAAK,GAAG,CAAA;AACzB;AAEA,SAAS,eAAA,CACP,WACA,KAAA,EACQ;AACR,EAAA,OAAO,SAAA,CACJ,MAAA,CAAO,CAAC,CAAA,KAAM;AACb,IAAA,MAAM,EAAE,KAAA,EAAO,IAAA,EAAM,GAAG,YAAW,GAAI,CAAA;AACvC,IAAA,OAAO,MAAA,CAAO,OAAA,CAAQ,UAAU,CAAA,CAAE,KAAA,CAAM,CAAC,CAAC,CAAA,EAAG,CAAC,CAAA,KAAM,KAAA,CAAM,CAAC,MAAM,CAAC,CAAA;AAAA,EACpE,CAAC,EACA,GAAA,CAAI,CAAC,MAAM,CAAA,CAAE,KAAK,CAAA,CAClB,IAAA,CAAK,GAAG,CAAA;AACb;AAoBO,SAAS,GAAG,MAAA,EAA+B;AAChD,EAAA,OAAO,CAAC,KAAA,GAA6B,EAAC,KAAM;AAC1C,IAAA,MAAM,EAAE,IAAA,GAAO,EAAA,EAAI,QAAA,GAAW,EAAC,EAAG,gBAAA,GAAmB,EAAC,EAAG,eAAA,GAAkB,EAAC,EAAE,GAAI,MAAA;AAElF,IAAA,MAAM,MAAA,GAAS,EAAE,GAAG,eAAA,EAAiB,GAAG,KAAA,EAAM;AAC9C,IAAA,MAAM,cAAA,GAAiB,eAAA,CAAgB,QAAA,EAAU,MAAA,EAAQ,eAAe,CAAA;AACxE,IAAA,MAAM,eAAA,GAAkB,eAAA,CAAgB,gBAAA,EAAkB,MAAM,CAAA;AAEhE,IAAA,OAAOA,qBAAA,CAAQ,IAAA,EAAM,cAAA,EAAgB,eAAA,EAAiB,MAAM,KAAK,CAAA;AAAA,EACnE,CAAA;AACF;AAeO,SAAS,MAAM,OAAA,EAA6D;AACjF,EAAA,OAAOA,qBAAA,CAAQ,GAAI,OAAA,CAAQ,MAAA,CAAO,OAAO,CAAc,CAAA;AACzD;AAmBO,SAAS,OACd,IAAA,EACA,EAAE,QAAQ,KAAA,GAAQ,IAAG,EACrB;AAGA,EAAA,SAAS,MAAA,CAAO;AAAA,IACd,MAAA,EAAQ,GAAA;AAAA,IACR,KAAA,EAAO,IAAI;AAAC,GACd,EAGG;AACD,IAAA,MAAM,OAAA,GAAU,EAAA,CAAG,GAAG,CAAA,CAAE,CAAC,CAAA;AAEzB,IAAA,IAAA,CAAK,SAAA,GAAY,OAAA;AAAA,EACnB;AAGA,EAAA,MAAA,CAAO,EAAE,MAAA,EAAQ,KAAA,EAAO,CAAA;AAExB,EAAA,OAAO;AAAA,IACL,MAAA;AAAA,IACA,OAAA,GAAU;AAAA,IAEV;AAAA,GACF;AACF;AAmBO,SAAS,cAAA,CAAe,QAA+B,QAAA,EAAqC;AACjG,EAAA,MAAM,QAAA,GAAW,GAAG,MAAM,CAAA;AAE1B,EAAA,OAAO;AAAA,IACL,SAAA,EAAW,MAAM,QAAA,CAAS,QAAA,EAAU,CAAA;AAAA,IACpC;AAAA,GACF;AACF;AAEA,IAAO,WAAA,GAAQ,EAAE,EAAA,EAAI,EAAA,EAAI,QAAQ,cAAA","file":"svelte.js","sourcesContent":["/**\n * tailwind-styled-v4 — Svelte Adapter\n *\n * Svelte 4+ adapter menggunakan action dan store pattern.\n * Kompatibel dengan Svelte 5 runes mode.\n *\n * Dua pola yang didukung:\n * 1. `tw()` — buat class string resolver untuk dipakai di template\n * 2. `createSvelteComponent()` — buat Svelte component via Svelte API\n *\n * @example\n * <!-- Pola 1: tw() sebagai class resolver -->\n * <script>\n * import { cv } from '@tailwind-styled/svelte'\n *\n * const buttonClass = cv({\n * base: 'px-4 py-2 rounded font-medium',\n * variants: {\n * intent: { primary: 'bg-blue-500 text-white', danger: 'bg-red-500 text-white' },\n * size: { sm: 'h-8 text-sm', lg: 'h-12 text-lg' },\n * },\n * defaultVariants: { intent: 'primary', size: 'sm' },\n * })\n *\n * export let intent = 'primary'\n * export let size = 'sm'\n * </script>\n *\n * <button class={buttonClass({ intent, size })}>\n * <slot />\n * </button>\n */\n\nimport { twMerge } from \"tailwind-merge\"\n\n// ─────────────────────────────────────────────────────────────────────────────\n// Types\n// ─────────────────────────────────────────────────────────────────────────────\n\nexport interface SvelteComponentConfig {\n base?: string\n variants?: Record<string, Record<string, string>>\n compoundVariants?: Array<{ class: string; [key: string]: any }>\n defaultVariants?: Record<string, string>\n}\n\n// ─────────────────────────────────────────────────────────────────────────────\n// Variant resolvers (framework-agnostic core)\n// ─────────────────────────────────────────────────────────────────────────────\n\nfunction resolveVariants(\n variants: Record<string, Record<string, string>>,\n props: Record<string, any>,\n defaults: Record<string, string> = {}\n): string {\n const classes: string[] = []\n for (const key in variants) {\n const val = props[key] ?? defaults[key]\n if (val !== undefined && variants[key]?.[String(val)]) {\n classes.push(variants[key][String(val)])\n }\n }\n return classes.join(\" \")\n}\n\nfunction resolveCompound(\n compounds: Array<{ class: string; [key: string]: any }>,\n props: Record<string, any>\n): string {\n return compounds\n .filter((c) => {\n const { class: _cls, ...conditions } = c\n return Object.entries(conditions).every(([k, v]) => props[k] === v)\n })\n .map((c) => c.class)\n .join(\" \")\n}\n\n// ─────────────────────────────────────────────────────────────────────────────\n// cv() — Class Variant (utama untuk Svelte)\n// ─────────────────────────────────────────────────────────────────────────────\n\n/**\n * Class variant resolver — pola utama untuk Svelte.\n * Returns fungsi yang menerima props dan mengembalikan class string.\n *\n * Gunakan ini di `<script>` block, lalu panggil di template.\n *\n * @example\n * const button = cv({\n * base: 'px-4 py-2 rounded',\n * variants: { size: { sm: 'h-8', lg: 'h-12' } },\n * })\n *\n * // Di template: class={button({ size: 'lg' })}\n */\nexport function cv(config: SvelteComponentConfig) {\n return (props: Record<string, any> = {}) => {\n const { base = \"\", variants = {}, compoundVariants = [], defaultVariants = {} } = config\n\n const merged = { ...defaultVariants, ...props }\n const variantClasses = resolveVariants(variants, merged, defaultVariants)\n const compoundClasses = resolveCompound(compoundVariants, merged)\n\n return twMerge(base, variantClasses, compoundClasses, props.class)\n }\n}\n\n// ─────────────────────────────────────────────────────────────────────────────\n// tw() — Simple class merger dengan template literal support\n// ─────────────────────────────────────────────────────────────────────────────\n\n/**\n * Simple class merger — berguna untuk merge class dinamis.\n *\n * @example\n * import { tw } from '@tailwind-styled/svelte'\n *\n * // Merge class string\n * const cls = tw('px-4 py-2', isActive && 'bg-blue-500', className)\n */\nexport function tw(...classes: Array<string | boolean | null | undefined>): string {\n return twMerge(...(classes.filter(Boolean) as string[]))\n}\n\n// ─────────────────────────────────────────────────────────────────────────────\n// Svelte action — use:styled\n// ─────────────────────────────────────────────────────────────────────────────\n\n/**\n * Svelte action untuk menerapkan class dinamis.\n *\n * @example\n * <script>\n * import { styled } from '@tailwind-styled/svelte'\n * const buttonConfig = { base: 'px-4 py-2', variants: { size: { sm: 'h-8', lg: 'h-12' } } }\n * </script>\n *\n * <button use:styled={{ config: buttonConfig, props: { size: 'lg' } }}>\n * Click me\n * </button>\n */\nexport function styled(\n node: HTMLElement,\n { config, props = {} }: { config: SvelteComponentConfig; props?: Record<string, any> }\n) {\n const _resolver = cv(config)\n\n function update({\n config: cfg,\n props: p = {},\n }: {\n config: SvelteComponentConfig\n props?: Record<string, any>\n }) {\n const classes = cv(cfg)(p)\n // Hapus class lama yang dikelola action, tambah yang baru\n node.className = classes\n }\n\n // Apply initial classes\n update({ config, props })\n\n return {\n update,\n destroy() {\n // Cleanup tidak diperlukan\n },\n }\n}\n\n// ─────────────────────────────────────────────────────────────────────────────\n// createVariants() — Svelte 5 runes compatible\n// ─────────────────────────────────────────────────────────────────────────────\n\n/**\n * Svelte 5 runes-compatible variant factory.\n * Mengembalikan reactive class string menggunakan $derived pattern.\n *\n * @example\n * // Dalam Svelte 5 component:\n * const { className, variantProps } = createVariants({\n * base: 'px-4 py-2',\n * variants: { size: { sm: 'h-8', lg: 'h-12' } },\n * }, () => ({ size: currentSize }))\n *\n * // className adalah fungsi yang return class string terkini\n */\nexport function createVariants(config: SvelteComponentConfig, getProps: () => Record<string, any>) {\n const resolver = cv(config)\n\n return {\n className: () => resolver(getProps()),\n config,\n }\n}\n\nexport default { cv, tw, styled, createVariants }\n"]}
@@ -0,0 +1,59 @@
1
+ import { twMerge } from 'tailwind-merge';
2
+
3
+ /* tailwind-styled-v4 v5.0.1 | MIT | https://github.com/dictionar32/tailwind-styled-v4 */
4
+
5
+ function resolveVariants(variants, props, defaults = {}) {
6
+ const classes = [];
7
+ for (const key in variants) {
8
+ const val = props[key] ?? defaults[key];
9
+ if (val !== void 0 && variants[key]?.[String(val)]) {
10
+ classes.push(variants[key][String(val)]);
11
+ }
12
+ }
13
+ return classes.join(" ");
14
+ }
15
+ function resolveCompound(compounds, props) {
16
+ return compounds.filter((c) => {
17
+ const { class: _cls, ...conditions } = c;
18
+ return Object.entries(conditions).every(([k, v]) => props[k] === v);
19
+ }).map((c) => c.class).join(" ");
20
+ }
21
+ function cv(config) {
22
+ return (props = {}) => {
23
+ const { base = "", variants = {}, compoundVariants = [], defaultVariants = {} } = config;
24
+ const merged = { ...defaultVariants, ...props };
25
+ const variantClasses = resolveVariants(variants, merged, defaultVariants);
26
+ const compoundClasses = resolveCompound(compoundVariants, merged);
27
+ return twMerge(base, variantClasses, compoundClasses, props.class);
28
+ };
29
+ }
30
+ function tw(...classes) {
31
+ return twMerge(...classes.filter(Boolean));
32
+ }
33
+ function styled(node, { config, props = {} }) {
34
+ function update({
35
+ config: cfg,
36
+ props: p = {}
37
+ }) {
38
+ const classes = cv(cfg)(p);
39
+ node.className = classes;
40
+ }
41
+ update({ config, props });
42
+ return {
43
+ update,
44
+ destroy() {
45
+ }
46
+ };
47
+ }
48
+ function createVariants(config, getProps) {
49
+ const resolver = cv(config);
50
+ return {
51
+ className: () => resolver(getProps()),
52
+ config
53
+ };
54
+ }
55
+ var src_default = { cv, tw, styled, createVariants };
56
+
57
+ export { createVariants, cv, src_default as default, styled, tw };
58
+ //# sourceMappingURL=svelte.mjs.map
59
+ //# sourceMappingURL=svelte.mjs.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../packages/svelte/src/index.ts"],"names":[],"mappings":";;;;AAkDA,SAAS,eAAA,CACP,QAAA,EACA,KAAA,EACA,QAAA,GAAmC,EAAC,EAC5B;AACR,EAAA,MAAM,UAAoB,EAAC;AAC3B,EAAA,KAAA,MAAW,OAAO,QAAA,EAAU;AAC1B,IAAA,MAAM,GAAA,GAAM,KAAA,CAAM,GAAG,CAAA,IAAK,SAAS,GAAG,CAAA;AACtC,IAAA,IAAI,GAAA,KAAQ,UAAa,QAAA,CAAS,GAAG,IAAI,MAAA,CAAO,GAAG,CAAC,CAAA,EAAG;AACrD,MAAA,OAAA,CAAQ,KAAK,QAAA,CAAS,GAAG,EAAE,MAAA,CAAO,GAAG,CAAC,CAAC,CAAA;AAAA,IACzC;AAAA,EACF;AACA,EAAA,OAAO,OAAA,CAAQ,KAAK,GAAG,CAAA;AACzB;AAEA,SAAS,eAAA,CACP,WACA,KAAA,EACQ;AACR,EAAA,OAAO,SAAA,CACJ,MAAA,CAAO,CAAC,CAAA,KAAM;AACb,IAAA,MAAM,EAAE,KAAA,EAAO,IAAA,EAAM,GAAG,YAAW,GAAI,CAAA;AACvC,IAAA,OAAO,MAAA,CAAO,OAAA,CAAQ,UAAU,CAAA,CAAE,KAAA,CAAM,CAAC,CAAC,CAAA,EAAG,CAAC,CAAA,KAAM,KAAA,CAAM,CAAC,MAAM,CAAC,CAAA;AAAA,EACpE,CAAC,EACA,GAAA,CAAI,CAAC,MAAM,CAAA,CAAE,KAAK,CAAA,CAClB,IAAA,CAAK,GAAG,CAAA;AACb;AAoBO,SAAS,GAAG,MAAA,EAA+B;AAChD,EAAA,OAAO,CAAC,KAAA,GAA6B,EAAC,KAAM;AAC1C,IAAA,MAAM,EAAE,IAAA,GAAO,EAAA,EAAI,QAAA,GAAW,EAAC,EAAG,gBAAA,GAAmB,EAAC,EAAG,eAAA,GAAkB,EAAC,EAAE,GAAI,MAAA;AAElF,IAAA,MAAM,MAAA,GAAS,EAAE,GAAG,eAAA,EAAiB,GAAG,KAAA,EAAM;AAC9C,IAAA,MAAM,cAAA,GAAiB,eAAA,CAAgB,QAAA,EAAU,MAAA,EAAQ,eAAe,CAAA;AACxE,IAAA,MAAM,eAAA,GAAkB,eAAA,CAAgB,gBAAA,EAAkB,MAAM,CAAA;AAEhE,IAAA,OAAO,OAAA,CAAQ,IAAA,EAAM,cAAA,EAAgB,eAAA,EAAiB,MAAM,KAAK,CAAA;AAAA,EACnE,CAAA;AACF;AAeO,SAAS,MAAM,OAAA,EAA6D;AACjF,EAAA,OAAO,OAAA,CAAQ,GAAI,OAAA,CAAQ,MAAA,CAAO,OAAO,CAAc,CAAA;AACzD;AAmBO,SAAS,OACd,IAAA,EACA,EAAE,QAAQ,KAAA,GAAQ,IAAG,EACrB;AAGA,EAAA,SAAS,MAAA,CAAO;AAAA,IACd,MAAA,EAAQ,GAAA;AAAA,IACR,KAAA,EAAO,IAAI;AAAC,GACd,EAGG;AACD,IAAA,MAAM,OAAA,GAAU,EAAA,CAAG,GAAG,CAAA,CAAE,CAAC,CAAA;AAEzB,IAAA,IAAA,CAAK,SAAA,GAAY,OAAA;AAAA,EACnB;AAGA,EAAA,MAAA,CAAO,EAAE,MAAA,EAAQ,KAAA,EAAO,CAAA;AAExB,EAAA,OAAO;AAAA,IACL,MAAA;AAAA,IACA,OAAA,GAAU;AAAA,IAEV;AAAA,GACF;AACF;AAmBO,SAAS,cAAA,CAAe,QAA+B,QAAA,EAAqC;AACjG,EAAA,MAAM,QAAA,GAAW,GAAG,MAAM,CAAA;AAE1B,EAAA,OAAO;AAAA,IACL,SAAA,EAAW,MAAM,QAAA,CAAS,QAAA,EAAU,CAAA;AAAA,IACpC;AAAA,GACF;AACF;AAEA,IAAO,WAAA,GAAQ,EAAE,EAAA,EAAI,EAAA,EAAI,QAAQ,cAAA","file":"svelte.mjs","sourcesContent":["/**\n * tailwind-styled-v4 — Svelte Adapter\n *\n * Svelte 4+ adapter menggunakan action dan store pattern.\n * Kompatibel dengan Svelte 5 runes mode.\n *\n * Dua pola yang didukung:\n * 1. `tw()` — buat class string resolver untuk dipakai di template\n * 2. `createSvelteComponent()` — buat Svelte component via Svelte API\n *\n * @example\n * <!-- Pola 1: tw() sebagai class resolver -->\n * <script>\n * import { cv } from '@tailwind-styled/svelte'\n *\n * const buttonClass = cv({\n * base: 'px-4 py-2 rounded font-medium',\n * variants: {\n * intent: { primary: 'bg-blue-500 text-white', danger: 'bg-red-500 text-white' },\n * size: { sm: 'h-8 text-sm', lg: 'h-12 text-lg' },\n * },\n * defaultVariants: { intent: 'primary', size: 'sm' },\n * })\n *\n * export let intent = 'primary'\n * export let size = 'sm'\n * </script>\n *\n * <button class={buttonClass({ intent, size })}>\n * <slot />\n * </button>\n */\n\nimport { twMerge } from \"tailwind-merge\"\n\n// ─────────────────────────────────────────────────────────────────────────────\n// Types\n// ─────────────────────────────────────────────────────────────────────────────\n\nexport interface SvelteComponentConfig {\n base?: string\n variants?: Record<string, Record<string, string>>\n compoundVariants?: Array<{ class: string; [key: string]: any }>\n defaultVariants?: Record<string, string>\n}\n\n// ─────────────────────────────────────────────────────────────────────────────\n// Variant resolvers (framework-agnostic core)\n// ─────────────────────────────────────────────────────────────────────────────\n\nfunction resolveVariants(\n variants: Record<string, Record<string, string>>,\n props: Record<string, any>,\n defaults: Record<string, string> = {}\n): string {\n const classes: string[] = []\n for (const key in variants) {\n const val = props[key] ?? defaults[key]\n if (val !== undefined && variants[key]?.[String(val)]) {\n classes.push(variants[key][String(val)])\n }\n }\n return classes.join(\" \")\n}\n\nfunction resolveCompound(\n compounds: Array<{ class: string; [key: string]: any }>,\n props: Record<string, any>\n): string {\n return compounds\n .filter((c) => {\n const { class: _cls, ...conditions } = c\n return Object.entries(conditions).every(([k, v]) => props[k] === v)\n })\n .map((c) => c.class)\n .join(\" \")\n}\n\n// ─────────────────────────────────────────────────────────────────────────────\n// cv() — Class Variant (utama untuk Svelte)\n// ─────────────────────────────────────────────────────────────────────────────\n\n/**\n * Class variant resolver — pola utama untuk Svelte.\n * Returns fungsi yang menerima props dan mengembalikan class string.\n *\n * Gunakan ini di `<script>` block, lalu panggil di template.\n *\n * @example\n * const button = cv({\n * base: 'px-4 py-2 rounded',\n * variants: { size: { sm: 'h-8', lg: 'h-12' } },\n * })\n *\n * // Di template: class={button({ size: 'lg' })}\n */\nexport function cv(config: SvelteComponentConfig) {\n return (props: Record<string, any> = {}) => {\n const { base = \"\", variants = {}, compoundVariants = [], defaultVariants = {} } = config\n\n const merged = { ...defaultVariants, ...props }\n const variantClasses = resolveVariants(variants, merged, defaultVariants)\n const compoundClasses = resolveCompound(compoundVariants, merged)\n\n return twMerge(base, variantClasses, compoundClasses, props.class)\n }\n}\n\n// ─────────────────────────────────────────────────────────────────────────────\n// tw() — Simple class merger dengan template literal support\n// ─────────────────────────────────────────────────────────────────────────────\n\n/**\n * Simple class merger — berguna untuk merge class dinamis.\n *\n * @example\n * import { tw } from '@tailwind-styled/svelte'\n *\n * // Merge class string\n * const cls = tw('px-4 py-2', isActive && 'bg-blue-500', className)\n */\nexport function tw(...classes: Array<string | boolean | null | undefined>): string {\n return twMerge(...(classes.filter(Boolean) as string[]))\n}\n\n// ─────────────────────────────────────────────────────────────────────────────\n// Svelte action — use:styled\n// ─────────────────────────────────────────────────────────────────────────────\n\n/**\n * Svelte action untuk menerapkan class dinamis.\n *\n * @example\n * <script>\n * import { styled } from '@tailwind-styled/svelte'\n * const buttonConfig = { base: 'px-4 py-2', variants: { size: { sm: 'h-8', lg: 'h-12' } } }\n * </script>\n *\n * <button use:styled={{ config: buttonConfig, props: { size: 'lg' } }}>\n * Click me\n * </button>\n */\nexport function styled(\n node: HTMLElement,\n { config, props = {} }: { config: SvelteComponentConfig; props?: Record<string, any> }\n) {\n const _resolver = cv(config)\n\n function update({\n config: cfg,\n props: p = {},\n }: {\n config: SvelteComponentConfig\n props?: Record<string, any>\n }) {\n const classes = cv(cfg)(p)\n // Hapus class lama yang dikelola action, tambah yang baru\n node.className = classes\n }\n\n // Apply initial classes\n update({ config, props })\n\n return {\n update,\n destroy() {\n // Cleanup tidak diperlukan\n },\n }\n}\n\n// ─────────────────────────────────────────────────────────────────────────────\n// createVariants() — Svelte 5 runes compatible\n// ─────────────────────────────────────────────────────────────────────────────\n\n/**\n * Svelte 5 runes-compatible variant factory.\n * Mengembalikan reactive class string menggunakan $derived pattern.\n *\n * @example\n * // Dalam Svelte 5 component:\n * const { className, variantProps } = createVariants({\n * base: 'px-4 py-2',\n * variants: { size: { sm: 'h-8', lg: 'h-12' } },\n * }, () => ({ size: currentSize }))\n *\n * // className adalah fungsi yang return class string terkini\n */\nexport function createVariants(config: SvelteComponentConfig, getProps: () => Record<string, any>) {\n const resolver = cv(config)\n\n return {\n className: () => resolver(getProps()),\n config,\n }\n}\n\nexport default { cv, tw, styled, createVariants }\n"]}