@maizzle/framework 6.0.0-rc.15 → 6.0.0-rc.17

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 (250) hide show
  1. package/README.md +3 -3
  2. package/dist/{build.d.mts → build.d.ts} +2 -2
  3. package/dist/build.d.ts.map +1 -0
  4. package/dist/build.mjs +1 -1
  5. package/dist/build.mjs.map +1 -1
  6. package/dist/components/Body.vue +9 -2
  7. package/dist/components/Button.vue +13 -8
  8. package/dist/components/Column.vue +22 -8
  9. package/dist/components/Container.vue +9 -5
  10. package/dist/components/Html.vue +7 -2
  11. package/dist/components/Layout.vue +30 -15
  12. package/dist/components/Overlap.vue +8 -3
  13. package/dist/components/Raw.vue +28 -0
  14. package/dist/components/Row.vue +23 -11
  15. package/dist/components/Section.vue +9 -5
  16. package/dist/components/Spacer.vue +9 -4
  17. package/dist/components/Tailwind.vue +43 -0
  18. package/dist/components/{utils.d.mts → utils.d.ts} +12 -2
  19. package/dist/components/utils.d.ts.map +1 -0
  20. package/dist/components/utils.mjs +11 -1
  21. package/dist/components/utils.mjs.map +1 -1
  22. package/dist/components/utils.ts +12 -0
  23. package/dist/composables/{defineConfig.d.mts → defineConfig.d.ts} +2 -2
  24. package/dist/composables/defineConfig.d.ts.map +1 -0
  25. package/dist/composables/{renderContext.d.mts → renderContext.d.ts} +11 -5
  26. package/dist/composables/renderContext.d.ts.map +1 -0
  27. package/dist/composables/renderContext.mjs.map +1 -1
  28. package/dist/composables/{useConfig.d.mts → useConfig.d.ts} +2 -2
  29. package/dist/composables/useConfig.d.ts.map +1 -0
  30. package/dist/composables/{useDoctype.d.mts → useDoctype.d.ts} +1 -1
  31. package/dist/composables/useDoctype.d.ts.map +1 -0
  32. package/dist/composables/{useEvent.d.mts → useEvent.d.ts} +2 -2
  33. package/dist/composables/useEvent.d.ts.map +1 -0
  34. package/dist/composables/{useFont.d.mts → useFont.d.ts} +1 -1
  35. package/dist/composables/useFont.d.ts.map +1 -0
  36. package/dist/composables/useOutlookFallback.d.ts +21 -0
  37. package/dist/composables/useOutlookFallback.d.ts.map +1 -0
  38. package/dist/composables/useOutlookFallback.mjs +30 -0
  39. package/dist/composables/useOutlookFallback.mjs.map +1 -0
  40. package/dist/composables/{usePlaintext.d.mts → usePlaintext.d.ts} +1 -1
  41. package/dist/composables/usePlaintext.d.ts.map +1 -0
  42. package/dist/composables/{usePreheader.d.mts → usePreheader.d.ts} +1 -1
  43. package/dist/composables/usePreheader.d.ts.map +1 -0
  44. package/dist/config/{defaults.d.mts → defaults.d.ts} +2 -2
  45. package/dist/config/defaults.d.ts.map +1 -0
  46. package/dist/config/{index.d.mts → index.d.ts} +4 -4
  47. package/dist/config/index.d.ts.map +1 -0
  48. package/dist/events/{index.d.mts → index.d.ts} +2 -2
  49. package/dist/events/index.d.ts.map +1 -0
  50. package/dist/index.d.ts +34 -0
  51. package/dist/index.mjs +2 -1
  52. package/dist/{plaintext.d.mts → plaintext.d.ts} +1 -1
  53. package/dist/plaintext.d.ts.map +1 -0
  54. package/dist/{plugin.d.mts → plugin.d.ts} +2 -2
  55. package/dist/plugin.d.ts.map +1 -0
  56. package/dist/plugins/postcss/{mergeMediaQueries.d.mts → mergeMediaQueries.d.ts} +2 -2
  57. package/dist/plugins/postcss/mergeMediaQueries.d.ts.map +1 -0
  58. package/dist/plugins/postcss/{pruneVars.d.mts → pruneVars.d.ts} +1 -1
  59. package/dist/plugins/postcss/pruneVars.d.ts.map +1 -0
  60. package/dist/plugins/postcss/{quoteFontFamilies.d.mts → quoteFontFamilies.d.ts} +1 -1
  61. package/dist/plugins/postcss/quoteFontFamilies.d.ts.map +1 -0
  62. package/dist/plugins/postcss/{removeDeclarations.d.mts → removeDeclarations.d.ts} +1 -1
  63. package/dist/plugins/postcss/removeDeclarations.d.ts.map +1 -0
  64. package/dist/plugins/postcss/resolveMaizzleImports.d.ts +16 -0
  65. package/dist/plugins/postcss/resolveMaizzleImports.d.ts.map +1 -0
  66. package/dist/plugins/postcss/resolveMaizzleImports.mjs +40 -0
  67. package/dist/plugins/postcss/resolveMaizzleImports.mjs.map +1 -0
  68. package/dist/plugins/postcss/{resolveProps.d.mts → resolveProps.d.ts} +1 -1
  69. package/dist/plugins/postcss/resolveProps.d.ts.map +1 -0
  70. package/dist/plugins/postcss/{tailwindCleanup.d.mts → tailwindCleanup.d.ts} +2 -2
  71. package/dist/plugins/postcss/tailwindCleanup.d.ts.map +1 -0
  72. package/dist/{prepare.d.mts → prepare.d.ts} +1 -1
  73. package/dist/prepare.d.ts.map +1 -0
  74. package/dist/render/{createRenderer.d.mts → createRenderer.d.ts} +4 -3
  75. package/dist/render/createRenderer.d.ts.map +1 -0
  76. package/dist/render/createRenderer.mjs +9 -76
  77. package/dist/render/createRenderer.mjs.map +1 -1
  78. package/dist/render/index.d.ts +18 -0
  79. package/dist/render/index.d.ts.map +1 -0
  80. package/dist/render/index.mjs +13 -14
  81. package/dist/render/index.mjs.map +1 -1
  82. package/dist/render/{injectFonts.d.mts → injectFonts.d.ts} +2 -2
  83. package/dist/render/injectFonts.d.ts.map +1 -0
  84. package/dist/render/plugins/codeBlockExtract.d.ts +14 -0
  85. package/dist/render/plugins/codeBlockExtract.d.ts.map +1 -0
  86. package/dist/render/plugins/codeBlockExtract.mjs +34 -0
  87. package/dist/render/plugins/codeBlockExtract.mjs.map +1 -0
  88. package/dist/render/plugins/markdownExtract.d.ts +12 -0
  89. package/dist/render/plugins/markdownExtract.d.ts.map +1 -0
  90. package/dist/render/plugins/markdownExtract.mjs +50 -0
  91. package/dist/render/plugins/markdownExtract.mjs.map +1 -0
  92. package/dist/render/plugins/rawExtract.d.ts +14 -0
  93. package/dist/render/plugins/rawExtract.d.ts.map +1 -0
  94. package/dist/render/plugins/rawExtract.mjs +34 -0
  95. package/dist/render/plugins/rawExtract.mjs.map +1 -0
  96. package/dist/render/plugins/{rowSourceLocation.d.mts → rowSourceLocation.d.ts} +1 -1
  97. package/dist/render/plugins/rowSourceLocation.d.ts.map +1 -0
  98. package/dist/{serve.d.mts → serve.d.ts} +2 -2
  99. package/dist/serve.d.ts.map +1 -0
  100. package/dist/serve.mjs +15 -6
  101. package/dist/serve.mjs.map +1 -1
  102. package/dist/server/{compatibility.d.mts → compatibility.d.ts} +2 -2
  103. package/dist/server/compatibility.d.ts.map +1 -0
  104. package/dist/server/{email.d.mts → email.d.ts} +2 -2
  105. package/dist/server/email.d.ts.map +1 -0
  106. package/dist/server/{linter.d.mts → linter.d.ts} +2 -2
  107. package/dist/server/linter.d.ts.map +1 -0
  108. package/dist/server/{sfc-utils.d.mts → sfc-utils.d.ts} +1 -1
  109. package/dist/server/sfc-utils.d.ts.map +1 -0
  110. package/dist/server/ui/App.vue +47 -2
  111. package/dist/server/ui/pages/Preview.vue +110 -22
  112. package/dist/transformers/{addAttributes.d.mts → addAttributes.d.ts} +2 -2
  113. package/dist/transformers/addAttributes.d.ts.map +1 -0
  114. package/dist/transformers/{attributeToStyle.d.mts → attributeToStyle.d.ts} +2 -2
  115. package/dist/transformers/attributeToStyle.d.ts.map +1 -0
  116. package/dist/transformers/{base.d.mts → base.d.ts} +2 -2
  117. package/dist/transformers/base.d.ts.map +1 -0
  118. package/dist/transformers/{columnWidth.d.mts → columnWidth.d.ts} +10 -10
  119. package/dist/transformers/columnWidth.d.ts.map +1 -0
  120. package/dist/transformers/columnWidth.mjs +422 -41
  121. package/dist/transformers/columnWidth.mjs.map +1 -1
  122. package/dist/transformers/{entities.d.mts → entities.d.ts} +2 -2
  123. package/dist/transformers/entities.d.ts.map +1 -0
  124. package/dist/transformers/filters/{defaults.d.mts → defaults.d.ts} +1 -1
  125. package/dist/transformers/filters/defaults.d.ts.map +1 -0
  126. package/dist/transformers/filters/{index.d.mts → index.d.ts} +2 -2
  127. package/dist/transformers/filters/index.d.ts.map +1 -0
  128. package/dist/transformers/{format.d.mts → format.d.ts} +2 -2
  129. package/dist/transformers/format.d.ts.map +1 -0
  130. package/dist/transformers/{index.d.mts → index.d.ts} +4 -3
  131. package/dist/transformers/index.d.ts.map +1 -0
  132. package/dist/transformers/index.mjs +3 -1
  133. package/dist/transformers/index.mjs.map +1 -1
  134. package/dist/transformers/{inlineCSS.d.mts → inlineCSS.d.ts} +2 -2
  135. package/dist/transformers/inlineCSS.d.ts.map +1 -0
  136. package/dist/transformers/inlineCSS.mjs +7 -1
  137. package/dist/transformers/inlineCSS.mjs.map +1 -1
  138. package/dist/transformers/{inlineLink.d.mts → inlineLink.d.ts} +1 -1
  139. package/dist/transformers/inlineLink.d.ts.map +1 -0
  140. package/dist/transformers/{minify.d.mts → minify.d.ts} +2 -2
  141. package/dist/transformers/minify.d.ts.map +1 -0
  142. package/dist/transformers/{msoWidthFromClass.d.mts → msoWidthFromClass.d.ts} +1 -1
  143. package/dist/transformers/msoWidthFromClass.d.ts.map +1 -0
  144. package/dist/transformers/{purgeCSS.d.mts → purgeCSS.d.ts} +2 -2
  145. package/dist/transformers/purgeCSS.d.ts.map +1 -0
  146. package/dist/transformers/purgeCSS.mjs +44 -2
  147. package/dist/transformers/purgeCSS.mjs.map +1 -1
  148. package/dist/transformers/{removeAttributes.d.mts → removeAttributes.d.ts} +2 -2
  149. package/dist/transformers/removeAttributes.d.ts.map +1 -0
  150. package/dist/transformers/{replaceStrings.d.mts → replaceStrings.d.ts} +2 -2
  151. package/dist/transformers/replaceStrings.d.ts.map +1 -0
  152. package/dist/transformers/{safeClassNames.d.mts → safeClassNames.d.ts} +2 -2
  153. package/dist/transformers/safeClassNames.d.ts.map +1 -0
  154. package/dist/transformers/{shorthandCSS.d.mts → shorthandCSS.d.ts} +2 -2
  155. package/dist/transformers/shorthandCSS.d.ts.map +1 -0
  156. package/dist/transformers/{sixHex.d.mts → sixHex.d.ts} +2 -2
  157. package/dist/transformers/sixHex.d.ts.map +1 -0
  158. package/dist/transformers/tailwindComponent.d.ts +16 -0
  159. package/dist/transformers/tailwindComponent.d.ts.map +1 -0
  160. package/dist/transformers/tailwindComponent.mjs +93 -0
  161. package/dist/transformers/tailwindComponent.mjs.map +1 -0
  162. package/dist/transformers/{tailwindcss.d.mts → tailwindcss.d.ts} +2 -2
  163. package/dist/transformers/tailwindcss.d.ts.map +1 -0
  164. package/dist/transformers/tailwindcss.mjs +2 -54
  165. package/dist/transformers/tailwindcss.mjs.map +1 -1
  166. package/dist/transformers/{urlQuery.d.mts → urlQuery.d.ts} +2 -2
  167. package/dist/transformers/urlQuery.d.ts.map +1 -0
  168. package/dist/types/{config.d.mts → config.d.ts} +2 -2
  169. package/dist/types/config.d.ts.map +1 -0
  170. package/dist/types/{index.d.mts → index.d.ts} +1 -1
  171. package/dist/utils/ast/index.d.ts +4 -0
  172. package/dist/utils/ast/{parser.d.mts → parser.d.ts} +1 -1
  173. package/dist/utils/ast/parser.d.ts.map +1 -0
  174. package/dist/utils/ast/{serializer.d.mts → serializer.d.ts} +1 -1
  175. package/dist/utils/ast/serializer.d.ts.map +1 -0
  176. package/dist/utils/ast/{walker.d.mts → walker.d.ts} +1 -1
  177. package/dist/utils/ast/walker.d.ts.map +1 -0
  178. package/dist/utils/compileTailwindCss.d.ts +16 -0
  179. package/dist/utils/compileTailwindCss.d.ts.map +1 -0
  180. package/dist/utils/compileTailwindCss.mjs +55 -0
  181. package/dist/utils/compileTailwindCss.mjs.map +1 -0
  182. package/dist/utils/{decodeStyleEntities.d.mts → decodeStyleEntities.d.ts} +1 -1
  183. package/dist/utils/decodeStyleEntities.d.ts.map +1 -0
  184. package/dist/utils/{detect.d.mts → detect.d.ts} +1 -1
  185. package/dist/utils/detect.d.ts.map +1 -0
  186. package/dist/utils/{url.d.mts → url.d.ts} +1 -1
  187. package/dist/utils/url.d.ts.map +1 -0
  188. package/package.json +13 -6
  189. package/dist/build.d.mts.map +0 -1
  190. package/dist/components/utils.d.mts.map +0 -1
  191. package/dist/composables/defineConfig.d.mts.map +0 -1
  192. package/dist/composables/renderContext.d.mts.map +0 -1
  193. package/dist/composables/useConfig.d.mts.map +0 -1
  194. package/dist/composables/useDoctype.d.mts.map +0 -1
  195. package/dist/composables/useEvent.d.mts.map +0 -1
  196. package/dist/composables/useFont.d.mts.map +0 -1
  197. package/dist/composables/usePlaintext.d.mts.map +0 -1
  198. package/dist/composables/usePreheader.d.mts.map +0 -1
  199. package/dist/config/defaults.d.mts.map +0 -1
  200. package/dist/config/index.d.mts.map +0 -1
  201. package/dist/events/index.d.mts.map +0 -1
  202. package/dist/index.d.mts +0 -33
  203. package/dist/plaintext.d.mts.map +0 -1
  204. package/dist/plugin.d.mts.map +0 -1
  205. package/dist/plugins/postcss/mergeMediaQueries.d.mts.map +0 -1
  206. package/dist/plugins/postcss/pruneVars.d.mts.map +0 -1
  207. package/dist/plugins/postcss/quoteFontFamilies.d.mts.map +0 -1
  208. package/dist/plugins/postcss/removeDeclarations.d.mts.map +0 -1
  209. package/dist/plugins/postcss/resolveProps.d.mts.map +0 -1
  210. package/dist/plugins/postcss/tailwindCleanup.d.mts.map +0 -1
  211. package/dist/prepare.d.mts.map +0 -1
  212. package/dist/render/createRenderer.d.mts.map +0 -1
  213. package/dist/render/index.d.mts +0 -26
  214. package/dist/render/index.d.mts.map +0 -1
  215. package/dist/render/injectFonts.d.mts.map +0 -1
  216. package/dist/render/plugins/rowSourceLocation.d.mts.map +0 -1
  217. package/dist/serve.d.mts.map +0 -1
  218. package/dist/server/compatibility.d.mts.map +0 -1
  219. package/dist/server/email.d.mts.map +0 -1
  220. package/dist/server/linter.d.mts.map +0 -1
  221. package/dist/server/sfc-utils.d.mts.map +0 -1
  222. package/dist/transformers/addAttributes.d.mts.map +0 -1
  223. package/dist/transformers/attributeToStyle.d.mts.map +0 -1
  224. package/dist/transformers/base.d.mts.map +0 -1
  225. package/dist/transformers/columnWidth.d.mts.map +0 -1
  226. package/dist/transformers/entities.d.mts.map +0 -1
  227. package/dist/transformers/filters/defaults.d.mts.map +0 -1
  228. package/dist/transformers/filters/index.d.mts.map +0 -1
  229. package/dist/transformers/format.d.mts.map +0 -1
  230. package/dist/transformers/index.d.mts.map +0 -1
  231. package/dist/transformers/inlineCSS.d.mts.map +0 -1
  232. package/dist/transformers/inlineLink.d.mts.map +0 -1
  233. package/dist/transformers/minify.d.mts.map +0 -1
  234. package/dist/transformers/msoWidthFromClass.d.mts.map +0 -1
  235. package/dist/transformers/purgeCSS.d.mts.map +0 -1
  236. package/dist/transformers/removeAttributes.d.mts.map +0 -1
  237. package/dist/transformers/replaceStrings.d.mts.map +0 -1
  238. package/dist/transformers/safeClassNames.d.mts.map +0 -1
  239. package/dist/transformers/shorthandCSS.d.mts.map +0 -1
  240. package/dist/transformers/sixHex.d.mts.map +0 -1
  241. package/dist/transformers/tailwindcss.d.mts.map +0 -1
  242. package/dist/transformers/urlQuery.d.mts.map +0 -1
  243. package/dist/types/config.d.mts.map +0 -1
  244. package/dist/utils/ast/index.d.mts +0 -4
  245. package/dist/utils/ast/parser.d.mts.map +0 -1
  246. package/dist/utils/ast/serializer.d.mts.map +0 -1
  247. package/dist/utils/ast/walker.d.mts.map +0 -1
  248. package/dist/utils/decodeStyleEntities.d.mts.map +0 -1
  249. package/dist/utils/detect.d.mts.map +0 -1
  250. package/dist/utils/url.d.mts.map +0 -1
@@ -0,0 +1,93 @@
1
+ import { walk } from "../utils/ast/walker.mjs";
2
+ import "../utils/ast/index.mjs";
3
+ import { compileTailwindCss } from "../utils/compileTailwindCss.mjs";
4
+ import { resolve } from "node:path";
5
+
6
+ //#region src/transformers/tailwindComponent.ts
7
+ const DEFAULT_SEED = "@import \"@maizzle/tailwindcss\";";
8
+ const OPEN_RE = /^mz-tw:(\S+)$/;
9
+ const CLOSE_RE = /^\/mz-tw:(\S+)$/;
10
+ /**
11
+ * Compile Tailwind CSS for each top-level <Tailwind> block in the render
12
+ * context. Nested <Tailwind> instances are flattened: their classes flow
13
+ * up to the outermost block, their `#config` slot (if any) is ignored.
14
+ * One <style> per outermost block is appended to <head>; marker comments
15
+ * are stripped after.
16
+ */
17
+ async function tailwindComponent(dom, blocks, config, filePath) {
18
+ if (!blocks.length) return dom;
19
+ const map = /* @__PURE__ */ new Map();
20
+ for (const b of blocks) map.set(b.id, {
21
+ id: b.id,
22
+ configCss: b.css,
23
+ nested: false,
24
+ classes: /* @__PURE__ */ new Set()
25
+ });
26
+ const stack = [];
27
+ const markers = [];
28
+ walk(dom, (node) => {
29
+ if (node.type === "comment") {
30
+ const data = node.data;
31
+ const open = data.match(OPEN_RE);
32
+ const close = data.match(CLOSE_RE);
33
+ if (open) {
34
+ const id = open[1];
35
+ const meta = map.get(id);
36
+ if (meta && stack.length > 0) meta.nested = true;
37
+ if (meta) stack.push(id);
38
+ markers.push(node);
39
+ } else if (close) {
40
+ const id = close[1];
41
+ if (stack[stack.length - 1] === id) stack.pop();
42
+ markers.push(node);
43
+ }
44
+ return;
45
+ }
46
+ const el = node;
47
+ if (el.attribs?.class && stack.length > 0) map.get(stack[0]).classes.add(el.attribs.class);
48
+ });
49
+ const fromPath = filePath ?? resolve(process.cwd(), "template.vue");
50
+ let head;
51
+ walk(dom, (n) => {
52
+ if (!head && n.name === "head") head = n;
53
+ });
54
+ if (!head) throw new Error("`Tailwind` component requires `Head` component to be present in the template.");
55
+ for (const meta of map.values()) {
56
+ if (meta.nested) continue;
57
+ const css = (await compileTailwindCss(buildCssInput(meta.configCss, meta.classes), config, `${fromPath}?tw=${meta.id}`)).trim();
58
+ if (!css) continue;
59
+ const styleNode = {
60
+ type: "tag",
61
+ name: "style",
62
+ attribs: { raw: "" },
63
+ children: [],
64
+ parent: head,
65
+ prev: null,
66
+ next: null
67
+ };
68
+ styleNode.children = [{
69
+ type: "text",
70
+ data: css,
71
+ parent: styleNode,
72
+ prev: null,
73
+ next: null
74
+ }];
75
+ head.children.push(styleNode);
76
+ }
77
+ for (const c of markers) {
78
+ const parent = c.parent;
79
+ if (!parent?.children) continue;
80
+ const i = parent.children.indexOf(c);
81
+ if (i >= 0) parent.children.splice(i, 1);
82
+ }
83
+ return dom;
84
+ }
85
+ function buildCssInput(configCss, classes) {
86
+ const seed = configCss ?? DEFAULT_SEED;
87
+ if (!classes.size) return seed;
88
+ return `${seed}\n@source inline("${[...classes].join(" ").replace(/"/g, "\\\"")}");`;
89
+ }
90
+
91
+ //#endregion
92
+ export { tailwindComponent };
93
+ //# sourceMappingURL=tailwindComponent.mjs.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"tailwindComponent.mjs","names":[],"sources":["../../src/transformers/tailwindComponent.ts"],"sourcesContent":["import { resolve } from 'node:path'\nimport type { ChildNode, Element, Comment } from 'domhandler'\nimport { walk } from '../utils/ast/index.ts'\nimport { compileTailwindCss } from '../utils/compileTailwindCss.ts'\nimport type { TailwindBlock } from '../composables/renderContext.ts'\nimport type { MaizzleConfig } from '../types/config.ts'\n\nconst DEFAULT_SEED = '@import \"@maizzle/tailwindcss\";'\n\ninterface BlockMeta {\n id: string\n configCss?: string\n nested: boolean\n classes: Set<string>\n}\n\nconst OPEN_RE = /^mz-tw:(\\S+)$/\nconst CLOSE_RE = /^\\/mz-tw:(\\S+)$/\n\n/**\n * Compile Tailwind CSS for each top-level <Tailwind> block in the render\n * context. Nested <Tailwind> instances are flattened: their classes flow\n * up to the outermost block, their `#config` slot (if any) is ignored.\n * One <style> per outermost block is appended to <head>; marker comments\n * are stripped after.\n */\nexport async function tailwindComponent(\n dom: ChildNode[],\n blocks: TailwindBlock[],\n config: MaizzleConfig,\n filePath?: string,\n): Promise<ChildNode[]> {\n if (!blocks.length) return dom\n\n const map = new Map<string, BlockMeta>()\n for (const b of blocks) {\n map.set(b.id, { id: b.id, configCss: b.css, nested: false, classes: new Set() })\n }\n\n const stack: string[] = []\n const markers: Comment[] = []\n\n walk(dom, (node) => {\n if (node.type === 'comment') {\n const data = (node as Comment).data\n const open = data.match(OPEN_RE)\n const close = data.match(CLOSE_RE)\n if (open) {\n const id = open[1]\n const meta = map.get(id)\n if (meta && stack.length > 0) meta.nested = true\n if (meta) stack.push(id)\n markers.push(node as Comment)\n } else if (close) {\n const id = close[1]\n if (stack[stack.length - 1] === id) stack.pop()\n markers.push(node as Comment)\n }\n return\n }\n\n const el = node as Element\n // Always assign to the OUTERMOST active marker (stack[0]) so nested\n // <Tailwind> blocks merge their classes into the parent's scope.\n if (el.attribs?.class && stack.length > 0) {\n map.get(stack[0])!.classes.add(el.attribs.class)\n }\n })\n\n const fromPath = filePath ?? resolve(process.cwd(), 'template.vue')\n\n let head: Element | undefined\n walk(dom, (n) => {\n if (!head && (n as Element).name === 'head') head = n as Element\n })\n\n if (!head) {\n throw new Error('`Tailwind` component requires `Head` component to be present in the template.')\n }\n\n // Compile + inject one <style raw> per outermost block. `raw` opts the\n // existing tailwindcss transformer out of recompiling already-compiled CSS.\n for (const meta of map.values()) {\n if (meta.nested) continue\n\n const cssInput = buildCssInput(meta.configCss, meta.classes)\n const css = (await compileTailwindCss(cssInput, config, `${fromPath}?tw=${meta.id}`)).trim()\n if (!css) continue\n\n const styleNode: Element = {\n type: 'tag',\n name: 'style',\n attribs: { raw: '' },\n children: [],\n parent: head,\n prev: null,\n next: null,\n } as any\n\n const textNode = {\n type: 'text',\n data: css,\n parent: styleNode,\n prev: null,\n next: null,\n } as any\n\n styleNode.children = [textNode]\n head.children.push(styleNode)\n }\n\n // Strip marker comments from their parents\n for (const c of markers) {\n const parent = c.parent as Element | null\n if (!parent?.children) continue\n const i = parent.children.indexOf(c)\n if (i >= 0) parent.children.splice(i, 1)\n }\n\n return dom\n}\n\nfunction buildCssInput(configCss: string | undefined, classes: Set<string>): string {\n const seed = configCss ?? DEFAULT_SEED\n\n if (!classes.size) return seed\n\n const inline = [...classes].join(' ').replace(/\"/g, '\\\\\"')\n return `${seed}\\n@source inline(\"${inline}\");`\n}\n"],"mappings":";;;;;;AAOA,MAAM,eAAe;AASrB,MAAM,UAAU;AAChB,MAAM,WAAW;;;;;;;;AASjB,eAAsB,kBACpB,KACA,QACA,QACA,UACsB;AACtB,KAAI,CAAC,OAAO,OAAQ,QAAO;CAE3B,MAAM,sBAAM,IAAI,KAAwB;AACxC,MAAK,MAAM,KAAK,OACd,KAAI,IAAI,EAAE,IAAI;EAAE,IAAI,EAAE;EAAI,WAAW,EAAE;EAAK,QAAQ;EAAO,yBAAS,IAAI,KAAK;EAAE,CAAC;CAGlF,MAAM,QAAkB,EAAE;CAC1B,MAAM,UAAqB,EAAE;AAE7B,MAAK,MAAM,SAAS;AAClB,MAAI,KAAK,SAAS,WAAW;GAC3B,MAAM,OAAQ,KAAiB;GAC/B,MAAM,OAAO,KAAK,MAAM,QAAQ;GAChC,MAAM,QAAQ,KAAK,MAAM,SAAS;AAClC,OAAI,MAAM;IACR,MAAM,KAAK,KAAK;IAChB,MAAM,OAAO,IAAI,IAAI,GAAG;AACxB,QAAI,QAAQ,MAAM,SAAS,EAAG,MAAK,SAAS;AAC5C,QAAI,KAAM,OAAM,KAAK,GAAG;AACxB,YAAQ,KAAK,KAAgB;cACpB,OAAO;IAChB,MAAM,KAAK,MAAM;AACjB,QAAI,MAAM,MAAM,SAAS,OAAO,GAAI,OAAM,KAAK;AAC/C,YAAQ,KAAK,KAAgB;;AAE/B;;EAGF,MAAM,KAAK;AAGX,MAAI,GAAG,SAAS,SAAS,MAAM,SAAS,EACtC,KAAI,IAAI,MAAM,GAAG,CAAE,QAAQ,IAAI,GAAG,QAAQ,MAAM;GAElD;CAEF,MAAM,WAAW,YAAY,QAAQ,QAAQ,KAAK,EAAE,eAAe;CAEnE,IAAI;AACJ,MAAK,MAAM,MAAM;AACf,MAAI,CAAC,QAAS,EAAc,SAAS,OAAQ,QAAO;GACpD;AAEF,KAAI,CAAC,KACH,OAAM,IAAI,MAAM,gFAAgF;AAKlG,MAAK,MAAM,QAAQ,IAAI,QAAQ,EAAE;AAC/B,MAAI,KAAK,OAAQ;EAGjB,MAAM,OAAO,MAAM,mBADF,cAAc,KAAK,WAAW,KAAK,QAAQ,EACZ,QAAQ,GAAG,SAAS,MAAM,KAAK,KAAK,EAAE,MAAM;AAC5F,MAAI,CAAC,IAAK;EAEV,MAAM,YAAqB;GACzB,MAAM;GACN,MAAM;GACN,SAAS,EAAE,KAAK,IAAI;GACpB,UAAU,EAAE;GACZ,QAAQ;GACR,MAAM;GACN,MAAM;GACP;AAUD,YAAU,WAAW,CARJ;GACf,MAAM;GACN,MAAM;GACN,QAAQ;GACR,MAAM;GACN,MAAM;GACP,CAE8B;AAC/B,OAAK,SAAS,KAAK,UAAU;;AAI/B,MAAK,MAAM,KAAK,SAAS;EACvB,MAAM,SAAS,EAAE;AACjB,MAAI,CAAC,QAAQ,SAAU;EACvB,MAAM,IAAI,OAAO,SAAS,QAAQ,EAAE;AACpC,MAAI,KAAK,EAAG,QAAO,SAAS,OAAO,GAAG,EAAE;;AAG1C,QAAO;;AAGT,SAAS,cAAc,WAA+B,SAA8B;CAClF,MAAM,OAAO,aAAa;AAE1B,KAAI,CAAC,QAAQ,KAAM,QAAO;AAG1B,QAAO,GAAG,KAAK,oBADA,CAAC,GAAG,QAAQ,CAAC,KAAK,IAAI,CAAC,QAAQ,MAAM,OAAM,CAChB"}
@@ -1,4 +1,4 @@
1
- import { MaizzleConfig } from "../types/config.mjs";
1
+ import { MaizzleConfig } from "../types/config.js";
2
2
  import { ChildNode } from "domhandler";
3
3
 
4
4
  //#region src/transformers/tailwindcss.d.ts
@@ -21,4 +21,4 @@ import { ChildNode } from "domhandler";
21
21
  declare function tailwindcss(dom: ChildNode[], config: MaizzleConfig, filePath?: string): Promise<ChildNode[]>;
22
22
  //#endregion
23
23
  export { tailwindcss };
24
- //# sourceMappingURL=tailwindcss.d.mts.map
24
+ //# sourceMappingURL=tailwindcss.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"tailwindcss.d.ts","names":[],"sources":["../../src/transformers/tailwindcss.ts"],"mappings":";;;;;;AA0EA;;;;;;;;;;;;;;iBAAsB,WAAA,CAAY,GAAA,EAAK,SAAA,IAAa,MAAA,EAAQ,aAAA,EAAe,QAAA,YAAoB,OAAA,CAAQ,SAAA"}
@@ -1,31 +1,10 @@
1
1
  import { walk } from "../utils/ast/walker.mjs";
2
2
  import "../utils/ast/index.mjs";
3
- import resolveProps_default from "../plugins/postcss/resolveProps.mjs";
4
- import pruneVars_default from "../plugins/postcss/pruneVars.mjs";
5
- import { tailwindCleanup } from "../plugins/postcss/tailwindCleanup.mjs";
6
- import { mergeMediaQueries } from "../plugins/postcss/mergeMediaQueries.mjs";
7
- import { quoteFontFamilies } from "../plugins/postcss/quoteFontFamilies.mjs";
3
+ import { compileTailwindCss } from "../utils/compileTailwindCss.mjs";
8
4
  import { decodeStyleEntities } from "../utils/decodeStyleEntities.mjs";
9
5
  import { dirname, relative, resolve } from "node:path";
10
- import postcss from "postcss";
11
- import tailwindcssPostcss from "@tailwindcss/postcss";
12
- import postcssCalc from "postcss-calc";
13
- import safeParser from "postcss-safe-parser";
14
- import { transform } from "lightningcss";
15
6
 
16
7
  //#region src/transformers/tailwindcss.ts
17
- function createProcessor(config) {
18
- return postcss([
19
- tailwindcssPostcss({
20
- base: config.css?.base,
21
- transformAssetUrls: false,
22
- optimize: false
23
- }),
24
- resolveProps_default(),
25
- postcssCalc({}),
26
- pruneVars_default()
27
- ]);
28
- }
29
8
  /**
30
9
  * Check if CSS content uses Tailwind features that require source scanning.
31
10
  *
@@ -37,33 +16,6 @@ function usesTailwind(css) {
37
16
  return /((@import|@reference)\s+["'](tailwindcss|@maizzle\/tailwindcss)|@tailwind\s)/.test(css);
38
17
  }
39
18
  /**
40
- * Lower modern CSS syntax using lightningcss.
41
- *
42
- * Targets IE 1 to maximize syntax lowering — converts modern features
43
- * like nesting, oklch(), color-mix(), @property, etc. into simple CSS
44
- * that email clients can understand.
45
- */
46
- function lowerSyntax(css) {
47
- return transform({
48
- filename: "email.css",
49
- code: Buffer.from(css),
50
- minify: false,
51
- targets: { ie: 128 }
52
- }).code.toString();
53
- }
54
- /**
55
- * Run cleanup and media query merging on the compiled CSS.
56
- *
57
- * Removes unwanted selectors (:host, :lang) and at-rules (@layer, @property),
58
- * then sorts and merges media queries.
59
- */
60
- async function optimizeCss(css, config) {
61
- const plugins = [...tailwindCleanup(config), quoteFontFamilies()];
62
- const mediaPlugin = mergeMediaQueries(config);
63
- if (mediaPlugin) plugins.push(mediaPlugin);
64
- return (await postcss(plugins).process(css, { from: void 0 })).css;
65
- }
66
- /**
67
19
  * Build @source directives for Tailwind CSS scanning.
68
20
  *
69
21
  * Configures two types of sources:
@@ -121,17 +73,13 @@ async function tailwindcss(dom, config, filePath) {
121
73
  const fromPath = filePath ?? resolve(process.cwd(), "template.vue");
122
74
  const fromDir = dirname(fromPath);
123
75
  const sourceDirectives = styleTags.some(({ cssContent }) => usesTailwind(cssContent)) ? buildSourceDirectives(dom, config, fromDir) : "";
124
- const processor = createProcessor(config);
125
76
  for (let i = 0; i < styleTags.length; i++) {
126
77
  const { node, cssContent } = styleTags[i];
127
78
  const fullCss = usesTailwind(cssContent) ? `${cssContent}\n${sourceDirectives}` : cssContent;
128
79
  try {
129
80
  node.children = [{
130
81
  type: "text",
131
- data: await optimizeCss(lowerSyntax((await processor.process(fullCss, {
132
- from: `${fromPath}?style=${i}`,
133
- parser: safeParser
134
- })).css), config),
82
+ data: await compileTailwindCss(fullCss, config, `${fromPath}?style=${i}`),
135
83
  parent: node
136
84
  }];
137
85
  } catch {
@@ -1 +1 @@
1
- {"version":3,"file":"tailwindcss.mjs","names":["resolveProps","pruneVars"],"sources":["../../src/transformers/tailwindcss.ts"],"sourcesContent":["import postcss from 'postcss'\nimport tailwindcssPostcss from '@tailwindcss/postcss'\nimport postcssCalc from 'postcss-calc'\nimport resolveProps from '../plugins/postcss/resolveProps.ts'\nimport pruneVars from '../plugins/postcss/pruneVars.ts'\nimport safeParser from 'postcss-safe-parser'\nimport { transform } from 'lightningcss'\nimport { resolve, dirname, relative } from 'node:path'\nimport type { ChildNode, Element } from 'domhandler'\nimport { walk } from '../utils/ast/index.ts'\nimport { tailwindCleanup } from '../plugins/postcss/tailwindCleanup.ts'\nimport { mergeMediaQueries } from '../plugins/postcss/mergeMediaQueries.ts'\nimport { quoteFontFamilies } from '../plugins/postcss/quoteFontFamilies.ts'\nimport { decodeStyleEntities } from '../utils/decodeStyleEntities.ts'\nimport type { MaizzleConfig } from '../types/config.ts'\n\nfunction createProcessor(config: MaizzleConfig) {\n return postcss([\n tailwindcssPostcss({\n base: config.css?.base,\n transformAssetUrls: false,\n optimize: false, // we run Lightning CSS manually\n }),\n resolveProps(),\n postcssCalc({}),\n pruneVars(),\n ])\n}\n\n/**\n * Check if CSS content uses Tailwind features that require source scanning.\n *\n * Only CSS that imports Tailwind (or @maizzle/tailwindcss) needs @source\n * directives. Plain CSS without Tailwind imports doesn't need scanning\n * and would pass through @source directives unconsumed.\n */\nfunction usesTailwind(css: string): boolean {\n return /((@import|@reference)\\s+[\"'](tailwindcss|@maizzle\\/tailwindcss)|@tailwind\\s)/.test(css)\n}\n\n/**\n * Lower modern CSS syntax using lightningcss.\n *\n * Targets IE 1 to maximize syntax lowering — converts modern features\n * like nesting, oklch(), color-mix(), @property, etc. into simple CSS\n * that email clients can understand.\n */\nfunction lowerSyntax(css: string): string {\n const result = transform({\n filename: 'email.css',\n code: Buffer.from(css),\n minify: false,\n targets: {\n ie: 4 << 5,\n },\n })\n\n return result.code.toString()\n}\n\n/**\n * Run cleanup and media query merging on the compiled CSS.\n *\n * Removes unwanted selectors (:host, :lang) and at-rules (@layer, @property),\n * then sorts and merges media queries.\n */\nasync function optimizeCss(css: string, config: MaizzleConfig): Promise<string> {\n const plugins: postcss.Plugin[] = [...tailwindCleanup(config), quoteFontFamilies()]\n\n const mediaPlugin = mergeMediaQueries(config)\n if (mediaPlugin) plugins.push(mediaPlugin)\n\n const result = await postcss(plugins).process(css, { from: undefined })\n\n return result.css\n}\n\n/**\n * Build @source directives for Tailwind CSS scanning.\n *\n * Configures two types of sources:\n * 1. Exclusions for output dir and user-configured paths\n * 2. Inline source with all class attribute values from the rendered DOM,\n * capturing classes from all components (built-in + user), dynamic\n * expressions, and the template itself — Tailwind's scanner handles\n * the actual class extraction from these raw values\n */\nfunction buildSourceDirectives(dom: ChildNode[], config: MaizzleConfig, fromDir: string): string {\n const directives: string[] = []\n\n // Exclude output dir and user-configured paths\n const excludePaths = [\n resolve(config.output?.path ?? 'dist'),\n ...(config.css?.exclude ?? []).map(p => resolve(p)),\n ]\n\n for (const p of excludePaths) {\n directives.push(`@source not \"${relative(fromDir, resolve(p))}\";`)\n }\n\n // Inline source: collect all class attribute values from the rendered DOM.\n // After Vue SSR, the DOM contains every class from every component\n // (built-in framework components, user components, dynamic bindings).\n // We pass these raw values to Tailwind's scanner via @source inline().\n const classes: string[] = []\n walk(dom, (n) => {\n const cls = (n as Element).attribs?.class\n if (cls) classes.push(cls)\n })\n\n if (classes.length) {\n directives.push(`@source inline(\"${classes.join(' ')}\");`)\n }\n\n return directives.join('\\n')\n}\n\n/**\n * Tailwind CSS transformer.\n *\n * Compiles CSS inside <style> tags in the DOM using\n * @tailwindcss/postcss, then lowers modern CSS syntax with lightningcss.\n *\n * Configures Tailwind sources to scan:\n * - Rendered class attributes (via `@source inline`) for all classes from all components\n * - User project files (via Tailwind's auto-detection from base/from path)\n *\n * User `@source` and `@source not directives` in style tags are preserved.\n * Source directives are only added to style tags that import Tailwind.\n *\n * Runs as the first transformer in the pipeline so that subsequent\n * transformers (inliner, purge, etc.) work with fully compiled CSS.\n */\nexport async function tailwindcss(dom: ChildNode[], config: MaizzleConfig, filePath?: string): Promise<ChildNode[]> {\n const styleTags: { node: Element; cssContent: string }[] = []\n\n walk(dom, (node) => {\n if ((node as Element).name !== 'style') return\n\n const el = node as Element\n const attrs = el.attribs || {}\n\n // `raw` opts out of compilation entirely (marker is consumed here).\n // `embed`/`data-embed` only signal \"preserve tag after inlining\" — they\n // still need to go through compile so Tailwind/@apply resolves.\n if ('raw' in attrs) {\n delete el.attribs.raw\n return\n }\n\n // Get text content from children and decode HTML entities\n const rawContent = el.children\n .filter(child => child.type === 'text')\n .map(child => (child as any).data)\n .join('')\n\n if (!rawContent.trim()) return\n\n styleTags.push({ node: el, cssContent: decodeStyleEntities(rawContent) })\n })\n\n if (!styleTags.length) return dom\n\n const fromPath = filePath ?? resolve(process.cwd(), 'template.vue')\n const fromDir = dirname(fromPath)\n\n // Only compute source directives if at least one style tag uses Tailwind\n const hasTailwindStyles = styleTags.some(({ cssContent }) => usesTailwind(cssContent))\n const sourceDirectives = hasTailwindStyles\n ? buildSourceDirectives(dom, config, fromDir)\n : ''\n\n // Create processor once — reused for all style tags in this template\n const processor = createProcessor(config)\n\n for (let i = 0; i < styleTags.length; i++) {\n const { node, cssContent } = styleTags[i]\n\n // Only add source directives to style tags that import Tailwind —\n // plain CSS doesn't need them and @tailwindcss/postcss would leave\n // the directives unconsumed in the output\n const fullCss = usesTailwind(cssContent)\n ? `${cssContent}\\n${sourceDirectives}`\n : cssContent\n\n try {\n const result = await processor.process(\n fullCss,\n {\n from: `${fromPath}?style=${i}`,\n parser: safeParser,\n }\n )\n\n const lowered = lowerSyntax(result.css)\n const optimized = await optimizeCss(lowered, config)\n\n // Replace the style tag's children with the compiled CSS\n node.children = [{\n type: 'text',\n data: optimized,\n parent: node,\n } as any]\n } catch {\n // If CSS processing fails, still replace with decoded content\n // so HTML entities don't break the CSS\n node.children = [{\n type: 'text',\n data: cssContent,\n parent: node,\n } as any]\n }\n }\n\n return dom\n}\n"],"mappings":"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"}
1
+ {"version":3,"file":"tailwindcss.mjs","names":[],"sources":["../../src/transformers/tailwindcss.ts"],"sourcesContent":["import { resolve, dirname, relative } from 'node:path'\nimport type { ChildNode, Element } from 'domhandler'\nimport { walk } from '../utils/ast/index.ts'\nimport { decodeStyleEntities } from '../utils/decodeStyleEntities.ts'\nimport { compileTailwindCss } from '../utils/compileTailwindCss.ts'\nimport type { MaizzleConfig } from '../types/config.ts'\n\n/**\n * Check if CSS content uses Tailwind features that require source scanning.\n *\n * Only CSS that imports Tailwind (or @maizzle/tailwindcss) needs @source\n * directives. Plain CSS without Tailwind imports doesn't need scanning\n * and would pass through @source directives unconsumed.\n */\nfunction usesTailwind(css: string): boolean {\n return /((@import|@reference)\\s+[\"'](tailwindcss|@maizzle\\/tailwindcss)|@tailwind\\s)/.test(css)\n}\n\n/**\n * Build @source directives for Tailwind CSS scanning.\n *\n * Configures two types of sources:\n * 1. Exclusions for output dir and user-configured paths\n * 2. Inline source with all class attribute values from the rendered DOM,\n * capturing classes from all components (built-in + user), dynamic\n * expressions, and the template itself — Tailwind's scanner handles\n * the actual class extraction from these raw values\n */\nfunction buildSourceDirectives(dom: ChildNode[], config: MaizzleConfig, fromDir: string): string {\n const directives: string[] = []\n\n // Exclude output dir and user-configured paths\n const excludePaths = [\n resolve(config.output?.path ?? 'dist'),\n ...(config.css?.exclude ?? []).map(p => resolve(p)),\n ]\n\n for (const p of excludePaths) {\n directives.push(`@source not \"${relative(fromDir, resolve(p))}\";`)\n }\n\n // Inline source: collect all class attribute values from the rendered DOM.\n // After Vue SSR, the DOM contains every class from every component\n // (built-in framework components, user components, dynamic bindings).\n // We pass these raw values to Tailwind's scanner via @source inline().\n const classes: string[] = []\n walk(dom, (n) => {\n const cls = (n as Element).attribs?.class\n if (cls) classes.push(cls)\n })\n\n if (classes.length) {\n directives.push(`@source inline(\"${classes.join(' ')}\");`)\n }\n\n return directives.join('\\n')\n}\n\n/**\n * Tailwind CSS transformer.\n *\n * Compiles CSS inside <style> tags in the DOM using\n * @tailwindcss/postcss, then lowers modern CSS syntax with lightningcss.\n *\n * Configures Tailwind sources to scan:\n * - Rendered class attributes (via `@source inline`) for all classes from all components\n * - User project files (via Tailwind's auto-detection from base/from path)\n *\n * User `@source` and `@source not directives` in style tags are preserved.\n * Source directives are only added to style tags that import Tailwind.\n *\n * Runs as the first transformer in the pipeline so that subsequent\n * transformers (inliner, purge, etc.) work with fully compiled CSS.\n */\nexport async function tailwindcss(dom: ChildNode[], config: MaizzleConfig, filePath?: string): Promise<ChildNode[]> {\n const styleTags: { node: Element; cssContent: string }[] = []\n\n walk(dom, (node) => {\n if ((node as Element).name !== 'style') return\n\n const el = node as Element\n const attrs = el.attribs || {}\n\n // `raw` opts out of compilation entirely (marker is consumed here).\n // `embed`/`data-embed` only signal \"preserve tag after inlining\" — they\n // still need to go through compile so Tailwind/@apply resolves.\n if ('raw' in attrs) {\n delete el.attribs.raw\n return\n }\n\n // Get text content from children and decode HTML entities\n const rawContent = el.children\n .filter(child => child.type === 'text')\n .map(child => (child as any).data)\n .join('')\n\n if (!rawContent.trim()) return\n\n styleTags.push({ node: el, cssContent: decodeStyleEntities(rawContent) })\n })\n\n if (!styleTags.length) return dom\n\n const fromPath = filePath ?? resolve(process.cwd(), 'template.vue')\n const fromDir = dirname(fromPath)\n\n // Only compute source directives if at least one style tag uses Tailwind\n const hasTailwindStyles = styleTags.some(({ cssContent }) => usesTailwind(cssContent))\n const sourceDirectives = hasTailwindStyles\n ? buildSourceDirectives(dom, config, fromDir)\n : ''\n\n for (let i = 0; i < styleTags.length; i++) {\n const { node, cssContent } = styleTags[i]\n\n // Only add source directives to style tags that import Tailwind —\n // plain CSS doesn't need them and @tailwindcss/postcss would leave\n // the directives unconsumed in the output\n const fullCss = usesTailwind(cssContent)\n ? `${cssContent}\\n${sourceDirectives}`\n : cssContent\n\n try {\n const optimized = await compileTailwindCss(fullCss, config, `${fromPath}?style=${i}`)\n\n // Replace the style tag's children with the compiled CSS\n node.children = [{\n type: 'text',\n data: optimized,\n parent: node,\n } as any]\n } catch {\n // If CSS processing fails, still replace with decoded content\n // so HTML entities don't break the CSS\n node.children = [{\n type: 'text',\n data: cssContent,\n parent: node,\n } as any]\n }\n }\n\n return dom\n}\n"],"mappings":";;;;;;;;;;;;;;AAcA,SAAS,aAAa,KAAsB;AAC1C,QAAO,+EAA+E,KAAK,IAAI;;;;;;;;;;;;AAajG,SAAS,sBAAsB,KAAkB,QAAuB,SAAyB;CAC/F,MAAM,aAAuB,EAAE;CAG/B,MAAM,eAAe,CACnB,QAAQ,OAAO,QAAQ,QAAQ,OAAO,EACtC,IAAI,OAAO,KAAK,WAAW,EAAE,EAAE,KAAI,MAAK,QAAQ,EAAE,CAAC,CACpD;AAED,MAAK,MAAM,KAAK,aACd,YAAW,KAAK,gBAAgB,SAAS,SAAS,QAAQ,EAAE,CAAC,CAAC,IAAI;CAOpE,MAAM,UAAoB,EAAE;AAC5B,MAAK,MAAM,MAAM;EACf,MAAM,MAAO,EAAc,SAAS;AACpC,MAAI,IAAK,SAAQ,KAAK,IAAI;GAC1B;AAEF,KAAI,QAAQ,OACV,YAAW,KAAK,mBAAmB,QAAQ,KAAK,IAAI,CAAC,KAAK;AAG5D,QAAO,WAAW,KAAK,KAAK;;;;;;;;;;;;;;;;;;AAmB9B,eAAsB,YAAY,KAAkB,QAAuB,UAAyC;CAClH,MAAM,YAAqD,EAAE;AAE7D,MAAK,MAAM,SAAS;AAClB,MAAK,KAAiB,SAAS,QAAS;EAExC,MAAM,KAAK;AAMX,MAAI,UALU,GAAG,WAAW,EAAE,GAKV;AAClB,UAAO,GAAG,QAAQ;AAClB;;EAIF,MAAM,aAAa,GAAG,SACnB,QAAO,UAAS,MAAM,SAAS,OAAO,CACtC,KAAI,UAAU,MAAc,KAAK,CACjC,KAAK,GAAG;AAEX,MAAI,CAAC,WAAW,MAAM,CAAE;AAExB,YAAU,KAAK;GAAE,MAAM;GAAI,YAAY,oBAAoB,WAAW;GAAE,CAAC;GACzE;AAEF,KAAI,CAAC,UAAU,OAAQ,QAAO;CAE9B,MAAM,WAAW,YAAY,QAAQ,QAAQ,KAAK,EAAE,eAAe;CACnE,MAAM,UAAU,QAAQ,SAAS;CAIjC,MAAM,mBADoB,UAAU,MAAM,EAAE,iBAAiB,aAAa,WAAW,CAAC,GAElF,sBAAsB,KAAK,QAAQ,QAAQ,GAC3C;AAEJ,MAAK,IAAI,IAAI,GAAG,IAAI,UAAU,QAAQ,KAAK;EACzC,MAAM,EAAE,MAAM,eAAe,UAAU;EAKvC,MAAM,UAAU,aAAa,WAAW,GACpC,GAAG,WAAW,IAAI,qBAClB;AAEJ,MAAI;AAIF,QAAK,WAAW,CAAC;IACf,MAAM;IACN,MALgB,MAAM,mBAAmB,SAAS,QAAQ,GAAG,SAAS,SAAS,IAAI;IAMnF,QAAQ;IACT,CAAQ;UACH;AAGN,QAAK,WAAW,CAAC;IACf,MAAM;IACN,MAAM;IACN,QAAQ;IACT,CAAQ;;;AAIb,QAAO"}
@@ -1,4 +1,4 @@
1
- import { UrlConfig } from "../types/config.mjs";
1
+ import { UrlConfig } from "../types/config.js";
2
2
  import { ChildNode } from "domhandler";
3
3
 
4
4
  //#region src/transformers/urlQuery.d.ts
@@ -21,4 +21,4 @@ import { ChildNode } from "domhandler";
21
21
  declare function urlQuery(dom: ChildNode[], config?: UrlConfig): ChildNode[];
22
22
  //#endregion
23
23
  export { urlQuery };
24
- //# sourceMappingURL=urlQuery.d.mts.map
24
+ //# sourceMappingURL=urlQuery.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"urlQuery.d.ts","names":[],"sources":["../../src/transformers/urlQuery.ts"],"mappings":";;;;;;AA0CA;;;;;;;;;;;;;;iBAAgB,QAAA,CAAS,GAAA,EAAK,SAAA,IAAa,MAAA,GAAQ,SAAA,GAAiB,SAAA"}
@@ -1,4 +1,4 @@
1
- import { RemoveValue } from "../plugins/postcss/removeDeclarations.mjs";
1
+ import { RemoveValue } from "../plugins/postcss/removeDeclarations.js";
2
2
  import { Directive, Plugin } from "vue";
3
3
  import { Options } from "juice";
4
4
  import * as oxfmt from "oxfmt";
@@ -596,4 +596,4 @@ interface MaizzleConfig {
596
596
  }
597
597
  //#endregion
598
598
  export { AttributesConfig, CaniemailClient, ChecksConfig, CssConfig, EntitiesConfig, FilterFunction, FiltersConfig, HtmlConfig, MaizzleConfig, MarkdownConfig, PostcssConfig, UrlConfig, UrlQuery, UrlQueryOptions, VueConfig };
599
- //# sourceMappingURL=config.d.mts.map
599
+ //# sourceMappingURL=config.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"config.d.ts","names":[],"sources":["../../src/types/config.ts"],"mappings":"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"}
@@ -1,2 +1,2 @@
1
- import { AttributesConfig, CaniemailClient, ChecksConfig, CssConfig, EntitiesConfig, FilterFunction, FiltersConfig, HtmlConfig, MaizzleConfig, MarkdownConfig, PostcssConfig, UrlConfig, UrlQuery, UrlQueryOptions } from "./config.mjs";
1
+ import { AttributesConfig, CaniemailClient, ChecksConfig, CssConfig, EntitiesConfig, FilterFunction, FiltersConfig, HtmlConfig, MaizzleConfig, MarkdownConfig, PostcssConfig, UrlConfig, UrlQuery, UrlQueryOptions } from "./config.js";
2
2
  export { type AttributesConfig, type CaniemailClient, type ChecksConfig, type CssConfig, type EntitiesConfig, type FilterFunction, type FiltersConfig, type HtmlConfig, type MaizzleConfig, type MarkdownConfig, type PostcssConfig, type UrlConfig, type UrlQuery, type UrlQueryOptions };
@@ -0,0 +1,4 @@
1
+ import { parse } from "./parser.js";
2
+ import { walk } from "./walker.js";
3
+ import { serialize } from "./serializer.js";
4
+ export { parse, serialize, walk };
@@ -4,4 +4,4 @@ import { ChildNode, DomHandlerOptions } from "domhandler";
4
4
  declare function parse(html: string, options?: DomHandlerOptions): ChildNode[];
5
5
  //#endregion
6
6
  export { parse };
7
- //# sourceMappingURL=parser.d.mts.map
7
+ //# sourceMappingURL=parser.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"parser.d.ts","names":[],"sources":["../../../src/utils/ast/parser.ts"],"mappings":";;;iBAIgB,KAAA,CAAM,IAAA,UAAc,OAAA,GAAS,iBAAA,GAAyB,SAAA"}
@@ -5,4 +5,4 @@ import { DomSerializerOptions } from "dom-serializer";
5
5
  declare function serialize(dom: ChildNode[], options?: DomSerializerOptions): string;
6
6
  //#endregion
7
7
  export { serialize };
8
- //# sourceMappingURL=serializer.d.mts.map
8
+ //# sourceMappingURL=serializer.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"serializer.d.ts","names":[],"sources":["../../../src/utils/ast/serializer.ts"],"mappings":";;;;iBA6BgB,SAAA,CAAU,GAAA,EAAK,SAAA,IAAa,OAAA,GAAU,oBAAA"}
@@ -4,4 +4,4 @@ import { ChildNode } from "domhandler";
4
4
  declare function walk(ast: ChildNode[], callback: (node: ChildNode) => void): void;
5
5
  //#endregion
6
6
  export { walk };
7
- //# sourceMappingURL=walker.d.mts.map
7
+ //# sourceMappingURL=walker.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"walker.d.ts","names":[],"sources":["../../../src/utils/ast/walker.ts"],"mappings":";;;iBAEgB,IAAA,CAAK,GAAA,EAAK,SAAA,IAAa,QAAA,GAAW,IAAA,EAAM,SAAA"}
@@ -0,0 +1,16 @@
1
+ import { MaizzleConfig } from "../types/config.js";
2
+ import postcss from "postcss";
3
+
4
+ //#region src/utils/compileTailwindCss.d.ts
5
+ declare function createTailwindProcessor(config: MaizzleConfig): postcss.Processor;
6
+ declare function lowerCssSyntax(css: string): string;
7
+ declare function optimizeTailwindCss(css: string, config: MaizzleConfig): Promise<string>;
8
+ /**
9
+ * Compile a Tailwind CSS source string into final email-safe CSS:
10
+ * runs @tailwindcss/postcss, lowers modern syntax via lightningcss,
11
+ * then applies cleanup + media-query merging.
12
+ */
13
+ declare function compileTailwindCss(cssInput: string, config: MaizzleConfig, from: string): Promise<string>;
14
+ //#endregion
15
+ export { compileTailwindCss, createTailwindProcessor, lowerCssSyntax, optimizeTailwindCss };
16
+ //# sourceMappingURL=compileTailwindCss.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"compileTailwindCss.d.ts","names":[],"sources":["../../src/utils/compileTailwindCss.ts"],"mappings":";;;;iBAagB,uBAAA,CAAwB,MAAA,EAAQ,aAAA,GAAa,OAAA,CAAA,SAAA;AAAA,iBAe7C,cAAA,CAAe,GAAA;AAAA,iBAWT,mBAAA,CAAoB,GAAA,UAAa,MAAA,EAAQ,aAAA,GAAgB,OAAA;;;;;;iBAgBzD,kBAAA,CACpB,QAAA,UACA,MAAA,EAAQ,aAAA,EACR,IAAA,WACC,OAAA"}
@@ -0,0 +1,55 @@
1
+ import resolveProps_default from "../plugins/postcss/resolveProps.mjs";
2
+ import pruneVars_default from "../plugins/postcss/pruneVars.mjs";
3
+ import { tailwindCleanup } from "../plugins/postcss/tailwindCleanup.mjs";
4
+ import { mergeMediaQueries } from "../plugins/postcss/mergeMediaQueries.mjs";
5
+ import { quoteFontFamilies } from "../plugins/postcss/quoteFontFamilies.mjs";
6
+ import { resolveMaizzleImports } from "../plugins/postcss/resolveMaizzleImports.mjs";
7
+ import postcss from "postcss";
8
+ import tailwindcssPostcss from "@tailwindcss/postcss";
9
+ import postcssCalc from "postcss-calc";
10
+ import safeParser from "postcss-safe-parser";
11
+ import { transform } from "lightningcss";
12
+
13
+ //#region src/utils/compileTailwindCss.ts
14
+ function createTailwindProcessor(config) {
15
+ return postcss([
16
+ resolveMaizzleImports(),
17
+ tailwindcssPostcss({
18
+ base: config.css?.base,
19
+ transformAssetUrls: false,
20
+ optimize: false
21
+ }),
22
+ resolveProps_default(),
23
+ postcssCalc({}),
24
+ pruneVars_default()
25
+ ]);
26
+ }
27
+ function lowerCssSyntax(css) {
28
+ return transform({
29
+ filename: "email.css",
30
+ code: Buffer.from(css),
31
+ minify: false,
32
+ targets: { ie: 128 }
33
+ }).code.toString();
34
+ }
35
+ async function optimizeTailwindCss(css, config) {
36
+ const plugins = [...tailwindCleanup(config), quoteFontFamilies()];
37
+ const mediaPlugin = mergeMediaQueries(config);
38
+ if (mediaPlugin) plugins.push(mediaPlugin);
39
+ return (await postcss(plugins).process(css, { from: void 0 })).css;
40
+ }
41
+ /**
42
+ * Compile a Tailwind CSS source string into final email-safe CSS:
43
+ * runs @tailwindcss/postcss, lowers modern syntax via lightningcss,
44
+ * then applies cleanup + media-query merging.
45
+ */
46
+ async function compileTailwindCss(cssInput, config, from) {
47
+ return optimizeTailwindCss(lowerCssSyntax((await createTailwindProcessor(config).process(cssInput, {
48
+ from,
49
+ parser: safeParser
50
+ })).css), config);
51
+ }
52
+
53
+ //#endregion
54
+ export { compileTailwindCss, createTailwindProcessor, lowerCssSyntax, optimizeTailwindCss };
55
+ //# sourceMappingURL=compileTailwindCss.mjs.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"compileTailwindCss.mjs","names":["resolveProps","pruneVars"],"sources":["../../src/utils/compileTailwindCss.ts"],"sourcesContent":["import postcss from 'postcss'\nimport tailwindcssPostcss from '@tailwindcss/postcss'\nimport postcssCalc from 'postcss-calc'\nimport safeParser from 'postcss-safe-parser'\nimport { transform } from 'lightningcss'\nimport resolveProps from '../plugins/postcss/resolveProps.ts'\nimport pruneVars from '../plugins/postcss/pruneVars.ts'\nimport { tailwindCleanup } from '../plugins/postcss/tailwindCleanup.ts'\nimport { mergeMediaQueries } from '../plugins/postcss/mergeMediaQueries.ts'\nimport { quoteFontFamilies } from '../plugins/postcss/quoteFontFamilies.ts'\nimport { resolveMaizzleImports } from '../plugins/postcss/resolveMaizzleImports.ts'\nimport type { MaizzleConfig } from '../types/config.ts'\n\nexport function createTailwindProcessor(config: MaizzleConfig) {\n return postcss([\n // Must run before @tailwindcss/postcss so it sees absolute import paths\n resolveMaizzleImports(),\n tailwindcssPostcss({\n base: config.css?.base,\n transformAssetUrls: false,\n optimize: false,\n }),\n resolveProps(),\n postcssCalc({}),\n pruneVars(),\n ])\n}\n\nexport function lowerCssSyntax(css: string): string {\n const result = transform({\n filename: 'email.css',\n code: Buffer.from(css),\n minify: false,\n targets: { ie: 4 << 5 },\n })\n\n return result.code.toString()\n}\n\nexport async function optimizeTailwindCss(css: string, config: MaizzleConfig): Promise<string> {\n const plugins: postcss.Plugin[] = [...tailwindCleanup(config), quoteFontFamilies()]\n\n const mediaPlugin = mergeMediaQueries(config)\n if (mediaPlugin) plugins.push(mediaPlugin)\n\n const result = await postcss(plugins).process(css, { from: undefined })\n\n return result.css\n}\n\n/**\n * Compile a Tailwind CSS source string into final email-safe CSS:\n * runs @tailwindcss/postcss, lowers modern syntax via lightningcss,\n * then applies cleanup + media-query merging.\n */\nexport async function compileTailwindCss(\n cssInput: string,\n config: MaizzleConfig,\n from: string,\n): Promise<string> {\n const processor = createTailwindProcessor(config)\n const result = await processor.process(cssInput, { from, parser: safeParser })\n const lowered = lowerCssSyntax(result.css)\n return optimizeTailwindCss(lowered, config)\n}\n"],"mappings":";;;;;;;;;;;;;AAaA,SAAgB,wBAAwB,QAAuB;AAC7D,QAAO,QAAQ;EAEb,uBAAuB;EACvB,mBAAmB;GACjB,MAAM,OAAO,KAAK;GAClB,oBAAoB;GACpB,UAAU;GACX,CAAC;EACFA,sBAAc;EACd,YAAY,EAAE,CAAC;EACfC,mBAAW;EACZ,CAAC;;AAGJ,SAAgB,eAAe,KAAqB;AAQlD,QAPe,UAAU;EACvB,UAAU;EACV,MAAM,OAAO,KAAK,IAAI;EACtB,QAAQ;EACR,SAAS,EAAE,IAAI,KAAQ;EACxB,CAAC,CAEY,KAAK,UAAU;;AAG/B,eAAsB,oBAAoB,KAAa,QAAwC;CAC7F,MAAM,UAA4B,CAAC,GAAG,gBAAgB,OAAO,EAAE,mBAAmB,CAAC;CAEnF,MAAM,cAAc,kBAAkB,OAAO;AAC7C,KAAI,YAAa,SAAQ,KAAK,YAAY;AAI1C,SAFe,MAAM,QAAQ,QAAQ,CAAC,QAAQ,KAAK,EAAE,MAAM,QAAW,CAAC,EAEzD;;;;;;;AAQhB,eAAsB,mBACpB,UACA,QACA,MACiB;AAIjB,QAAO,oBADS,gBADD,MADG,wBAAwB,OAAO,CAClB,QAAQ,UAAU;EAAE;EAAM,QAAQ;EAAY,CAAC,EACxC,IAAI,EACN,OAAO"}
@@ -12,4 +12,4 @@
12
12
  declare function decodeStyleEntities(s: string): string;
13
13
  //#endregion
14
14
  export { decodeStyleEntities };
15
- //# sourceMappingURL=decodeStyleEntities.d.mts.map
15
+ //# sourceMappingURL=decodeStyleEntities.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"decodeStyleEntities.d.ts","names":[],"sources":["../../src/utils/decodeStyleEntities.ts"],"mappings":";;AAUA;;;;;;;;;iBAAgB,mBAAA,CAAoB,CAAA"}
@@ -2,4 +2,4 @@
2
2
  declare function isLaravel(cwd?: string): boolean;
3
3
  //#endregion
4
4
  export { isLaravel };
5
- //# sourceMappingURL=detect.d.mts.map
5
+ //# sourceMappingURL=detect.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"detect.d.ts","names":[],"sources":["../../src/utils/detect.ts"],"mappings":";iBAGgB,SAAA,CAAU,GAAA"}
@@ -5,4 +5,4 @@ declare function isAbsoluteUrl(url: string): boolean;
5
5
  declare function processSrcset(srcset: string, baseUrl: string): string;
6
6
  //#endregion
7
7
  export { defaultTags, isAbsoluteUrl, processSrcset, urlAttributes };
8
- //# sourceMappingURL=url.d.mts.map
8
+ //# sourceMappingURL=url.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"url.d.ts","names":[],"sources":["../../src/utils/url.ts"],"mappings":";cAEa,WAAA,EAAa,MAAA;AAAA,cAcb,aAAA;AAAA,iBAEG,aAAA,CAAc,GAAA;AAAA,iBAMd,aAAA,CAAc,MAAA,UAAgB,OAAA"}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@maizzle/framework",
3
- "version": "6.0.0-rc.15",
3
+ "version": "6.0.0-rc.17",
4
4
  "description": "Maizzle is a framework that helps you quickly build HTML emails with Tailwind CSS.",
5
5
  "license": "MIT",
6
6
  "type": "module",
@@ -10,7 +10,7 @@
10
10
  "exports": {
11
11
  ".": {
12
12
  "import": "./dist/index.mjs",
13
- "types": "./dist/index.d.mts"
13
+ "types": "./dist/index.d.ts"
14
14
  }
15
15
  },
16
16
  "bin": {
@@ -33,6 +33,7 @@
33
33
  "maizzle"
34
34
  ],
35
35
  "dependencies": {
36
+ "@maizzle/tailwindcss": "latest",
36
37
  "@tailwindcss/postcss": "^4.2.2",
37
38
  "@tailwindcss/vite": "^4.2.2",
38
39
  "@unhead/vue": "^3.0.4",
@@ -67,19 +68,22 @@
67
68
  "postcss-value-parser": "^4.2.0",
68
69
  "query-string": "^9.3.1",
69
70
  "reka-ui": "^2.9.3",
70
- "shiki": "^4.0.2",
71
71
  "string-strip-html": "^13.5.3",
72
- "tailwind-merge": "^3.5.0",
73
72
  "tinyglobby": "^0.2.15",
74
73
  "tw-animate-css": "^1.4.0",
75
74
  "typescript": "^5.9.3",
76
75
  "unplugin-auto-import": "^21.0.0",
77
76
  "unplugin-vue-components": "^31.0.0",
78
77
  "unplugin-vue-markdown": "^30.0.0",
78
+ "uqr": "^0.1.3",
79
79
  "vite": "^7.3.1",
80
- "vue": "^3.5.28",
81
80
  "vue-router": "^5.0.2"
82
81
  },
82
+ "peerDependencies": {
83
+ "shiki": "^1 || ^2 || ^3 || ^4",
84
+ "tailwind-merge": "^2 || ^3",
85
+ "vue": "^3"
86
+ },
83
87
  "devDependencies": {
84
88
  "@types/js-beautify": "^1.14.3",
85
89
  "@types/node": "^25.2.3",
@@ -88,8 +92,11 @@
88
92
  "@vue/test-utils": "^2.4.6",
89
93
  "happy-dom": "^20.6.3",
90
94
  "oxlint": "^1.50.0",
95
+ "shiki": "^4.0.2",
96
+ "tailwind-merge": "^3.5.0",
91
97
  "tsdown": "^0.20.3",
92
- "vitest": "^4.0.18"
98
+ "vitest": "^4.0.18",
99
+ "vue": "^3.5.28"
93
100
  },
94
101
  "repository": {
95
102
  "type": "git",
@@ -1 +0,0 @@
1
- {"version":3,"file":"build.d.mts","names":[],"sources":["../src/build.ts"],"mappings":";;UAWiB,YAAA;EACf,MAAA,GAAS,OAAA,CAAQ,aAAA;AAAA;AAAA,UAGF,WAAA;EACf,KAAA;EACA,MAAA,EAAQ,aAAA;AAAA;;;;;;AAFV;iBAWsB,KAAA,CAAM,OAAA,GAAS,YAAA,GAAoB,OAAA,CAAQ,WAAA"}
@@ -1 +0,0 @@
1
- {"version":3,"file":"utils.d.mts","names":[],"sources":["../../src/components/utils.ts"],"mappings":";iBAAgB,iBAAA,CAAkB,KAAA;AAAlC;;;;;AAiBA;;;AAjBA,iBAiBgB,MAAA,CAAO,MAAA;AAAA,iBAKP,eAAA,CAAgB,QAAA;AAAA,iBAQhB,eAAA,CAAgB,QAAA;AAAA,iBAIhB,gBAAA,CAAiB,QAAA;AAAA,iBAQjB,gBAAA,CAAiB,QAAA"}
@@ -1 +0,0 @@
1
- {"version":3,"file":"defineConfig.d.mts","names":[],"sources":["../../src/composables/defineConfig.ts"],"mappings":";;;;;AAqBA;;;;;iBAAgB,YAAA,CAAa,IAAA,GAAM,OAAA,CAAQ,aAAA,IAAsB,aAAA"}
@@ -1 +0,0 @@
1
- {"version":3,"file":"renderContext.d.mts","names":[],"sources":["../../src/composables/renderContext.ts"],"mappings":";;;;;;UAKiB,gBAAA;EACf,MAAA;EACA,IAAA;EACA,WAAA;EACA,GAAA;AAAA;AAAA,UAGe,aAAA;EACf,OAAA;EACA,SAAA;IAAc,IAAA;IAAc,WAAA;IAAqB,QAAA;EAAA;EACjD,SAAA,GAAY,aAAA;EACZ,gBAAA,EAAkB,KAAA;IAAQ,IAAA,EAAM,SAAA;IAAW,OAAA,EAAS,QAAA,CAAS,SAAA;EAAA;EAC7D,SAAA,GAAY,mBAAA;EACZ,KAAA,GAAQ,gBAAA;AAAA;AAAA,cAGG,gBAAA,EAAkB,YAAA,CAAa,aAAA"}
@@ -1 +0,0 @@
1
- {"version":3,"file":"useConfig.d.mts","names":[],"sources":["../../src/composables/useConfig.ts"],"mappings":";;;;cAIa,gBAAA,EAAkB,YAAA,CAAa,aAAA;AAAA,iBAE5B,SAAA,CAAA,GAAa,aAAA"}
@@ -1 +0,0 @@
1
- {"version":3,"file":"useDoctype.d.mts","names":[],"sources":["../../src/composables/useDoctype.ts"],"mappings":";;AAWA;;;;;;;iBAAgB,UAAA,CAAW,OAAA"}
@@ -1 +0,0 @@
1
- {"version":3,"file":"useEvent.d.mts","names":[],"sources":["../../src/composables/useEvent.ts"],"mappings":";;;;;AAcA;;;;;;;;iBAAgB,QAAA,WAAmB,SAAA,CAAA,CAAW,IAAA,EAAM,CAAA,EAAG,OAAA,EAAS,QAAA,CAAS,CAAA"}
@@ -1 +0,0 @@
1
- {"version":3,"file":"useFont.d.mts","names":[],"sources":["../../src/composables/useFont.ts"],"mappings":";KA8CY,YAAA;AAAA,UAEK,cAAA;EAFO;;;;AAExB;;EAOE,MAAA;EAoBc;EAlBd,QAAA;EAAA;;;;;EAMA,QAAA,GAAW,YAAA;EAYX;;;;AA+CF;EArDE,GAAA;;EAEA,OAAA;EAmD6C;EAjD7C,OAAA;;EAEA,MAAA,GAAS,KAAA;AAAA;;;;;;;;;;;;;;;;iBA+CK,OAAA,CAAQ,OAAA,EAAS,cAAA"}
@@ -1 +0,0 @@
1
- {"version":3,"file":"usePlaintext.d.mts","names":[],"sources":["../../src/composables/usePlaintext.ts"],"mappings":";UAGiB,mBAAA;EACf,SAAA;EACA,WAAA;AAAA;;;AAaF;;;;;;;;iBAAgB,YAAA,CAAa,OAAA,GAAU,mBAAA"}
@@ -1 +0,0 @@
1
- {"version":3,"file":"usePreheader.d.mts","names":[],"sources":["../../src/composables/usePreheader.ts"],"mappings":";UAGiB,mBAAA;EAAA;EAEf,WAAA;;EAEA,QAAA;AAAA;AAgBF;;;;;;;;;;;;;AAAA,iBAAgB,YAAA,CAAa,IAAA,UAAc,OAAA,GAAU,mBAAA"}
@@ -1 +0,0 @@
1
- {"version":3,"file":"defaults.d.mts","names":[],"sources":["../../src/config/defaults.ts"],"mappings":";;cAEa,QAAA,EAAU,aAAA"}
@@ -1 +0,0 @@
1
- {"version":3,"file":"index.d.mts","names":[],"sources":["../../src/config/index.ts"],"mappings":";;;;;;;;AA8BA;;;iBAAsB,aAAA,CACpB,MAAA,GAAS,OAAA,CAAQ,aAAA,YACjB,GAAA,YACC,OAAA,CAAQ,aAAA"}
@@ -1 +0,0 @@
1
- {"version":3,"file":"index.d.mts","names":[],"sources":["../../src/events/index.ts"],"mappings":";;KAEY,SAAA;AAAA,UAEK,QAAA;EACf,YAAA,GAAe,MAAA;IAAU,MAAA,EAAQ,aAAA;EAAA,aAA2B,OAAA;EAC5D,YAAA,GAAe,MAAA;IAAU,MAAA,EAAQ,aAAA;IAAe,QAAA;EAAA,sBAAuC,OAAA;EACvF,WAAA,GAAc,MAAA;IAAU,MAAA,EAAQ,aAAA;IAAe,QAAA;IAAkB,IAAA;EAAA,sBAAmC,OAAA;EACpG,cAAA,GAAiB,MAAA;IAAU,MAAA,EAAQ,aAAA;IAAe,QAAA;IAAkB,IAAA;EAAA,sBAAmC,OAAA;EACvG,UAAA,GAAa,MAAA;IAAU,KAAA;IAAiB,MAAA,EAAQ,aAAA;EAAA,aAA2B,OAAA;AAAA;;;;;;;;cAUhE,YAAA;EAAA,QACH,QAAA;EAd+E;;;EAmBvF,cAAA,CAAe,MAAA,EAAQ,aAAA;EAlBwB;;;EAgC/C,EAAA,WAAa,SAAA,CAAA,CAAW,IAAA,EAAM,CAAA,EAAG,OAAA,EAAS,QAAA,CAAS,CAAA;EA/BnD;;;EA0CM,gBAAA,CAAiB,MAAA;IAAU,MAAA,EAAQ,aAAA;EAAA,IAAe,OAAA;EA1C+C;;;EAqDjG,gBAAA,CAAiB,MAAA;IAAU,MAAA,EAAQ,aAAA;IAAe,QAAA;EAAA,IAAqB,OAAA;EApDK;;AAUpF;EA6DQ,eAAA,CAAgB,MAAA;IAAU,MAAA,EAAQ,aAAA;IAAe,QAAA;IAAkB,IAAA;EAAA,IAAiB,OAAA;EAzChD;;;EA4DpC,kBAAA,CAAmB,MAAA;IAAU,MAAA,EAAQ,aAAA;IAAe,QAAA;IAAkB,IAAA;EAAA,IAAiB,OAAA;EAAlD;;;EAmBrC,cAAA,CAAe,MAAA;IAAU,KAAA;IAAiB,MAAA,EAAQ,aAAA;EAAA,IAAe,OAAA;EA7FvE;;;EAwGA,gBAAA,CAAA;EA1FG;;;EAsGH,KAAA,CAAA;AAAA"}
package/dist/index.d.mts DELETED
@@ -1,33 +0,0 @@
1
- import { AttributesConfig, CssConfig, EntitiesConfig, FilterFunction, FiltersConfig, HtmlConfig, MaizzleConfig, UrlConfig, UrlQuery, UrlQueryOptions } from "./types/config.mjs";
2
- import { build } from "./build.mjs";
3
- import { defineConfig } from "./composables/defineConfig.mjs";
4
- import { usePlaintext } from "./composables/usePlaintext.mjs";
5
- import { useConfig } from "./composables/useConfig.mjs";
6
- import { useDoctype } from "./composables/useDoctype.mjs";
7
- import { useEvent } from "./composables/useEvent.mjs";
8
- import { useFont } from "./composables/useFont.mjs";
9
- import { resolveConfig } from "./config/index.mjs";
10
- import { maizzle } from "./plugin.mjs";
11
- import { CreateRendererOptions, RenderedTemplate, Renderer, createRenderer } from "./render/createRenderer.mjs";
12
- import { RenderOptions, RenderResult, render } from "./render/index.mjs";
13
- import { serve } from "./serve.mjs";
14
- import { PrepareOptions, prepare } from "./prepare.mjs";
15
- import { createPlaintext } from "./plaintext.mjs";
16
- import { inlineLink } from "./transformers/inlineLink.mjs";
17
- import { urlQuery } from "./transformers/urlQuery.mjs";
18
- import { base } from "./transformers/base.mjs";
19
- import { entities } from "./transformers/entities.mjs";
20
- import { safeClassNames } from "./transformers/safeClassNames.mjs";
21
- import { attributeToStyle } from "./transformers/attributeToStyle.mjs";
22
- import { inlineCSS } from "./transformers/inlineCSS.mjs";
23
- import { shorthandCSS } from "./transformers/shorthandCSS.mjs";
24
- import { sixHex } from "./transformers/sixHex.mjs";
25
- import { removeAttributes } from "./transformers/removeAttributes.mjs";
26
- import { addAttributes } from "./transformers/addAttributes.mjs";
27
- import { purgeCSS } from "./transformers/purgeCSS.mjs";
28
- import { filters } from "./transformers/filters/index.mjs";
29
- import { replaceStrings } from "./transformers/replaceStrings.mjs";
30
- import { format } from "./transformers/format.mjs";
31
- import { minify } from "./transformers/minify.mjs";
32
- import { useHead } from "@unhead/vue";
33
- export { type AttributesConfig, type CreateRendererOptions, type CssConfig, type EntitiesConfig, type FilterFunction, type FiltersConfig, type HtmlConfig, type MaizzleConfig, type PrepareOptions, type RenderOptions, type RenderResult, type RenderedTemplate, type Renderer, type UrlConfig, type UrlQuery, type UrlQueryOptions, addAttributes, attributeToStyle, base, build, createPlaintext, createRenderer, defineConfig, entities, filters, format, inlineCSS, inlineLink, maizzle, minify, prepare, removeAttributes, purgeCSS as removeUnusedCSS, render, replaceStrings, resolveConfig, safeClassNames, serve, shorthandCSS, sixHex, urlQuery, useConfig, useDoctype, useEvent, useFont, useHead, usePlaintext };
@@ -1 +0,0 @@
1
- {"version":3,"file":"plaintext.d.mts","names":[],"sources":["../src/plaintext.ts"],"mappings":";iBAUgB,eAAA,CAAgB,IAAA,UAAc,OAAA,GAAU,MAAA"}
@@ -1 +0,0 @@
1
- {"version":3,"file":"plugin.d.mts","names":[],"sources":["../src/plugin.ts"],"mappings":";;;;;;;AAaA;;;;;;iBAAgB,OAAA,CAAQ,WAAA,GAAc,OAAA,CAAQ,aAAA,IAAiB,MAAA"}
@@ -1 +0,0 @@
1
- {"version":3,"file":"mergeMediaQueries.d.mts","names":[],"sources":["../../../src/plugins/postcss/mergeMediaQueries.ts"],"mappings":";;;;;;AAcA;;;;;;;;iBAAgB,iBAAA,CAAkB,MAAA,EAAQ,aAAA,GAAgB,OAAA,CAAQ,MAAA"}
@@ -1 +0,0 @@
1
- {"version":3,"file":"pruneVars.d.mts","names":[],"sources":["../../../src/plugins/postcss/pruneVars.ts"],"mappings":";;;cAKyD,QAAA,QAYtC,MAAA;AAAA,cA2DN,OAAA"}