@maizzle/framework 6.1.6 → 6.2.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (56) hide show
  1. package/dist/components/Img.vue +10 -4
  2. package/dist/components/Section.vue +1 -1
  3. package/dist/composables/definePreviewProps.d.ts +21 -0
  4. package/dist/composables/definePreviewProps.d.ts.map +1 -0
  5. package/dist/composables/definePreviewProps.js +23 -0
  6. package/dist/composables/definePreviewProps.js.map +1 -0
  7. package/dist/index.d.ts +3 -2
  8. package/dist/index.js +3 -2
  9. package/dist/plugins/postcss/resolveMaizzleImports.js +15 -8
  10. package/dist/plugins/postcss/resolveMaizzleImports.js.map +1 -1
  11. package/dist/render/createRenderer.d.ts.map +1 -1
  12. package/dist/render/createRenderer.js +25 -4
  13. package/dist/render/createRenderer.js.map +1 -1
  14. package/dist/render/index.d.ts +21 -0
  15. package/dist/render/index.d.ts.map +1 -1
  16. package/dist/render/index.js +76 -30
  17. package/dist/render/index.js.map +1 -1
  18. package/dist/render/plugins/previewProps.d.ts +13 -0
  19. package/dist/render/plugins/previewProps.d.ts.map +1 -0
  20. package/dist/render/plugins/previewProps.js +185 -0
  21. package/dist/render/plugins/previewProps.js.map +1 -0
  22. package/dist/render/withPreviewProps.d.ts +15 -0
  23. package/dist/render/withPreviewProps.d.ts.map +1 -0
  24. package/dist/render/withPreviewProps.js +40 -0
  25. package/dist/render/withPreviewProps.js.map +1 -0
  26. package/dist/serve.d.ts.map +1 -1
  27. package/dist/serve.js +4 -1
  28. package/dist/serve.js.map +1 -1
  29. package/dist/server/ui/.vite/deps/@lucide_vue.js +51812 -41607
  30. package/dist/server/ui/.vite/deps/@lucide_vue.js.map +1 -1
  31. package/dist/server/ui/.vite/deps/@vueuse_core.js.map +1 -1
  32. package/dist/server/ui/.vite/deps/@vueuse_shared.js.map +1 -1
  33. package/dist/server/ui/.vite/deps/_metadata.json +13 -13
  34. package/dist/server/ui/.vite/deps/class-variance-authority.js.map +1 -1
  35. package/dist/server/ui/.vite/deps/clsx.js.map +1 -1
  36. package/dist/server/ui/.vite/deps/culori.js.map +1 -1
  37. package/dist/server/ui/.vite/deps/reka-ui.js +240 -73
  38. package/dist/server/ui/.vite/deps/reka-ui.js.map +1 -1
  39. package/dist/server/ui/.vite/deps/tailwind-merge.js +102 -22
  40. package/dist/server/ui/.vite/deps/tailwind-merge.js.map +1 -1
  41. package/dist/server/ui/.vite/deps/vue-router.js +84 -53
  42. package/dist/server/ui/.vite/deps/vue-router.js.map +1 -1
  43. package/dist/server/ui/.vite/deps/vue.runtime.esm-bundler-Dq07uCLt.js.map +1 -1
  44. package/dist/transformers/format.d.ts.map +1 -1
  45. package/dist/transformers/minify.d.ts.map +1 -1
  46. package/dist/transformers/purgeCss.d.ts.map +1 -1
  47. package/dist/transformers/shorthandCss.js +11 -5
  48. package/dist/transformers/shorthandCss.js.map +1 -1
  49. package/dist/transformers/tailwindComponent.js +1 -1
  50. package/dist/transformers/tailwindComponent.js.map +1 -1
  51. package/dist/transformers/tailwindcss.js +8 -4
  52. package/dist/transformers/tailwindcss.js.map +1 -1
  53. package/dist/types/config.d.ts.map +1 -1
  54. package/dist/utils/compileTailwindCss.js +1 -1
  55. package/dist/utils/compileTailwindCss.js.map +1 -1
  56. package/package.json +3 -3
@@ -1 +1 @@
1
- {"version":3,"file":"format.d.ts","names":[],"sources":["../../src/transformers/format.ts"],"mappings":";;;;;;;;;;;;;;;;;wBA2BsB,OAAO,cAAc,UAAS,iBAAoB"}
1
+ {"version":3,"file":"format.d.ts","names":["FormatConfig"],"sources":["../../src/transformers/format.ts"],"mappings":";;;;;;;;;;;;;;;;;wBA2BsB,OAAO,cAAc,UAASA,iBAAoB"}
@@ -1 +1 @@
1
- {"version":3,"file":"minify.d.ts","names":[],"sources":["../../src/transformers/minify.ts"],"mappings":";;;;;;;;;;;;;;;;wBAwBgB,OAAO,cAAc,UAAS,QAAQ"}
1
+ {"version":3,"file":"minify.d.ts","names":["HtmlCrushOptions"],"sources":["../../src/transformers/minify.ts"],"mappings":";;;;;;;;;;;;;;;;wBAwBgB,OAAO,cAAc,UAAS,QAAQA"}
@@ -1 +1 @@
1
- {"version":3,"file":"purgeCss.d.ts","names":[],"sources":["../../src/transformers/purgeCss.ts"],"mappings":";;;;;;iBAsCiB,wBAAwB,QAAQ,KAAK;;;;;;EAMpD;;;;;;;;;;;;;;;;;;;;wBAqBc,SAAS,cAAc,UAAS;;;;;;wBAShC,YAAY,KAAK,aAAa,UAAS,kBAAuB"}
1
+ {"version":3,"file":"purgeCss.d.ts","names":["CombOptions"],"sources":["../../src/transformers/purgeCss.ts"],"mappings":";;;;;;iBAsCiB,wBAAwB,QAAQ,KAAKA;;;;;;EAMpD;;;;;;;;;;;;;;;;;;;;wBAqBc,SAAS,cAAc,UAAS;;;;;;wBAShC,YAAY,KAAK,aAAa,UAAS,kBAAuB"}
@@ -74,20 +74,26 @@ function shorthandCssDom(dom, options = {}) {
74
74
  const allowedTags = options.tags ?? [];
75
75
  const hasTagFilter = allowedTags.length > 0;
76
76
  /**
77
+ * Utility-generated inline styles repeat heavily across elements, so
78
+ * each distinct value only goes through postcss once per call.
79
+ */
80
+ const cache = /* @__PURE__ */ new Map();
81
+ /**
77
82
  * Merge longhand within a single inline-style value. Returns the merged
78
83
  * string when shorter, otherwise the original. Wraps the value in a
79
84
  * dummy selector since postcss-merge-longhand operates on rules.
80
85
  */
81
86
  const mergeStyleValue = (styleValue) => {
87
+ let result = cache.get(styleValue);
88
+ if (result !== void 0) return result;
89
+ result = styleValue;
82
90
  try {
83
91
  const { css } = postcss().use(mergeLonghand).use(mergeBorder).process(`div { ${styleValue} }`, { parser: safeParser });
84
92
  const match = css.match(/div\s*\{\s*([^}]+)\s*\}/);
85
- if (match && match[1]) {
86
- const merged = match[1].trim();
87
- if (merged !== styleValue) return merged;
88
- }
93
+ if (match && match[1]) result = match[1].trim();
89
94
  } catch {}
90
- return styleValue;
95
+ cache.set(styleValue, result);
96
+ return result;
91
97
  };
92
98
  walk(dom, (node) => {
93
99
  /**
@@ -1 +1 @@
1
- {"version":3,"file":"shorthandCss.js","names":[],"sources":["../../src/transformers/shorthandCss.ts"],"sourcesContent":["import postcss, { list, type Declaration, type Plugin } from 'postcss'\nimport safeParser from 'postcss-safe-parser'\nimport mergeLonghand from 'postcss-merge-longhand'\nimport type { ChildNode, Element } from 'domhandler'\nimport { parse, serialize, walk } from '../utils/ast/index.ts'\n\n/**\n * Options for the `shorthandCss` transformer.\n */\nexport interface ShorthandCssOptions {\n /**\n * Restrict the transform to a list of HTML tag names. Omit to apply to\n * every element with a `style` attribute.\n *\n * @example ['td', 'div']\n */\n tags?: string[]\n}\n\n/**\n * Rewrite longhand CSS inside inline `style` attributes with shorthand\n * syntax. Works with margin, padding, and border when all sides are\n * specified.\n *\n * For example:\n * `margin-left: 2px; margin-right: 2px; margin-top: 4px; margin-bottom: 4px`\n * becomes:\n * `margin: 4px 2px`\n *\n * @param html HTML string to transform.\n * @param options Optional Maizzle options (`tags`).\n * @returns The transformed HTML string.\n *\n * @example\n * import { shorthandCss } from '@maizzle/framework'\n *\n * const out = shorthandCss(\n * '<p style=\"margin-top: 4px; margin-right: 2px; margin-bottom: 4px; margin-left: 2px;\">x</p>',\n * { tags: ['p'] },\n * )\n */\n/**\n * Fold `border-width`, `border-style` and `border-color` into `border`.\n *\n * postcss-merge-longhand stopped doing this in 8.0.3 because the\n * shorthand also resets `border-image`. Email clients don't support\n * `border-image`, so the merge is safe for inline styles.\n */\nconst mergeBorder: Plugin = {\n postcssPlugin: 'maizzle-merge-border',\n OnceExit(root) {\n root.walkRules((rule) => {\n const decls: Declaration[] = []\n\n for (const prop of ['border-width', 'border-style', 'border-color']) {\n const found = rule.nodes.filter(\n (node): node is Declaration => node.type === 'decl' && node.prop.toLowerCase() === prop,\n )\n if (found.length !== 1) return\n decls.push(found[0])\n }\n\n const [width, style, color] = decls\n const { important } = width\n\n for (const decl of decls) {\n if (\n decl.important !== important\n || list.space(decl.value).length !== 1\n || /var\\s*\\(/i.test(decl.value)\n ) return\n }\n\n const last = decls.reduce((a, b) => (rule.index(b) > rule.index(a) ? b : a))\n\n last.replaceWith({\n prop: 'border',\n value: `${width.value} ${style.value} ${color.value}`,\n important,\n })\n\n for (const decl of decls) {\n if (decl !== last) decl.remove()\n }\n })\n },\n}\n\nexport function shorthandCss(html: string, options: ShorthandCssOptions = {}): string {\n return serialize(shorthandCssDom(parse(html), options))\n}\n\n/**\n * DOM-form of {@link shorthandCss} used by the internal transformer\n * pipeline. Takes a parsed DOM, returns a parsed DOM — avoids redundant\n * serialize/parse round-trips when chained with other transformers.\n */\nexport function shorthandCssDom(dom: ChildNode[], options: ShorthandCssOptions = {}): ChildNode[] {\n const allowedTags = options.tags ?? []\n const hasTagFilter = allowedTags.length > 0\n\n /**\n * Merge longhand within a single inline-style value. Returns the merged\n * string when shorter, otherwise the original. Wraps the value in a\n * dummy selector since postcss-merge-longhand operates on rules.\n */\n const mergeStyleValue = (styleValue: string): string => {\n try {\n const { css } = postcss()\n .use(mergeLonghand)\n .use(mergeBorder)\n .process(`div { ${styleValue} }`, { parser: safeParser })\n const match = css.match(/div\\s*\\{\\s*([^}]+)\\s*\\}/)\n if (match && match[1]) {\n const merged = match[1].trim()\n if (merged !== styleValue) return merged\n }\n }\n catch {}\n return styleValue\n }\n\n walk(dom, (node) => {\n /**\n * MSO conditional comments carry their own inline-style attributes\n * (e.g. `<!--[if mso]><td style=\"…\"><![endif]-->`) as opaque text.\n * The element walker can't see them, so without this branch the td/\n * v:rect styles inside comments stay longhand even when the visible\n * div has already been merged. Match each `style=\"…\"` substring,\n * run it through mergeLonghand, splice back.\n *\n * Tag filter intentionally bypassed: the user can't address MSO td\n * elements (they don't parse as elements), and these comments\n * always wrap email-layout primitives anyway.\n */\n if (node.type === 'comment') {\n const data = (node as any).data as string\n if (!data || !data.includes('style=\"')) return\n const newData = data.replace(/style=\"([^\"]*)\"/g, (full, value) => {\n const merged = mergeStyleValue(value)\n return merged === value ? full : `style=\"${merged}\"`\n })\n if (newData !== data) (node as any).data = newData\n return\n }\n\n const el = node as Element\n\n if (!el.attribs?.style) return\n if (hasTagFilter && !allowedTags.includes(el.name)) return\n\n const merged = mergeStyleValue(el.attribs.style)\n if (merged !== el.attribs.style) el.attribs.style = merged\n })\n\n return dom\n}\n"],"mappings":";;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;AAgDA,MAAM,cAAsB;CAC1B,eAAe;CACf,SAAS,MAAM;EACb,KAAK,WAAW,SAAS;GACvB,MAAM,QAAuB,CAAC;GAE9B,KAAK,MAAM,QAAQ;IAAC;IAAgB;IAAgB;GAAc,GAAG;IACnE,MAAM,QAAQ,KAAK,MAAM,QACtB,SAA8B,KAAK,SAAS,UAAU,KAAK,KAAK,YAAY,MAAM,IACrF;IACA,IAAI,MAAM,WAAW,GAAG;IACxB,MAAM,KAAK,MAAM,EAAE;GACrB;GAEA,MAAM,CAAC,OAAO,OAAO,SAAS;GAC9B,MAAM,EAAE,cAAc;GAEtB,KAAK,MAAM,QAAQ,OACjB,IACE,KAAK,cAAc,aAChB,KAAK,MAAM,KAAK,KAAK,CAAC,CAAC,WAAW,KAClC,YAAY,KAAK,KAAK,KAAK,GAC9B;GAGJ,MAAM,OAAO,MAAM,QAAQ,GAAG,MAAO,KAAK,MAAM,CAAC,IAAI,KAAK,MAAM,CAAC,IAAI,IAAI,CAAE;GAE3E,KAAK,YAAY;IACf,MAAM;IACN,OAAO,GAAG,MAAM,MAAM,GAAG,MAAM,MAAM,GAAG,MAAM;IAC9C;GACF,CAAC;GAED,KAAK,MAAM,QAAQ,OACjB,IAAI,SAAS,MAAM,KAAK,OAAO;EAEnC,CAAC;CACH;AACF;AAEA,SAAgB,aAAa,MAAc,UAA+B,CAAC,GAAW;CACpF,OAAO,UAAU,gBAAgB,MAAM,IAAI,GAAG,OAAO,CAAC;AACxD;;;;;;AAOA,SAAgB,gBAAgB,KAAkB,UAA+B,CAAC,GAAgB;CAChG,MAAM,cAAc,QAAQ,QAAQ,CAAC;CACrC,MAAM,eAAe,YAAY,SAAS;;;;;;CAO1C,MAAM,mBAAmB,eAA+B;EACtD,IAAI;GACF,MAAM,EAAE,QAAQ,QAAQ,CAAC,CACtB,IAAI,aAAa,CAAC,CAClB,IAAI,WAAW,CAAC,CAChB,QAAQ,SAAS,WAAW,KAAK,EAAE,QAAQ,WAAW,CAAC;GAC1D,MAAM,QAAQ,IAAI,MAAM,yBAAyB;GACjD,IAAI,SAAS,MAAM,IAAI;IACrB,MAAM,SAAS,MAAM,EAAE,CAAC,KAAK;IAC7B,IAAI,WAAW,YAAY,OAAO;GACpC;EACF,QACM,CAAC;EACP,OAAO;CACT;CAEA,KAAK,MAAM,SAAS;;;;;;;;;;;;;EAalB,IAAI,KAAK,SAAS,WAAW;GAC3B,MAAM,OAAQ,KAAa;GAC3B,IAAI,CAAC,QAAQ,CAAC,KAAK,SAAS,UAAS,GAAG;GACxC,MAAM,UAAU,KAAK,QAAQ,qBAAqB,MAAM,UAAU;IAChE,MAAM,SAAS,gBAAgB,KAAK;IACpC,OAAO,WAAW,QAAQ,OAAO,UAAU,OAAO;GACpD,CAAC;GACD,IAAI,YAAY,MAAM,KAAc,OAAO;GAC3C;EACF;EAEA,MAAM,KAAK;EAEX,IAAI,CAAC,GAAG,SAAS,OAAO;EACxB,IAAI,gBAAgB,CAAC,YAAY,SAAS,GAAG,IAAI,GAAG;EAEpD,MAAM,SAAS,gBAAgB,GAAG,QAAQ,KAAK;EAC/C,IAAI,WAAW,GAAG,QAAQ,OAAO,GAAG,QAAQ,QAAQ;CACtD,CAAC;CAED,OAAO;AACT"}
1
+ {"version":3,"file":"shorthandCss.js","names":[],"sources":["../../src/transformers/shorthandCss.ts"],"sourcesContent":["import postcss, { list, type Declaration, type Plugin } from 'postcss'\nimport safeParser from 'postcss-safe-parser'\nimport mergeLonghand from 'postcss-merge-longhand'\nimport type { ChildNode, Element } from 'domhandler'\nimport { parse, serialize, walk } from '../utils/ast/index.ts'\n\n/**\n * Options for the `shorthandCss` transformer.\n */\nexport interface ShorthandCssOptions {\n /**\n * Restrict the transform to a list of HTML tag names. Omit to apply to\n * every element with a `style` attribute.\n *\n * @example ['td', 'div']\n */\n tags?: string[]\n}\n\n/**\n * Rewrite longhand CSS inside inline `style` attributes with shorthand\n * syntax. Works with margin, padding, and border when all sides are\n * specified.\n *\n * For example:\n * `margin-left: 2px; margin-right: 2px; margin-top: 4px; margin-bottom: 4px`\n * becomes:\n * `margin: 4px 2px`\n *\n * @param html HTML string to transform.\n * @param options Optional Maizzle options (`tags`).\n * @returns The transformed HTML string.\n *\n * @example\n * import { shorthandCss } from '@maizzle/framework'\n *\n * const out = shorthandCss(\n * '<p style=\"margin-top: 4px; margin-right: 2px; margin-bottom: 4px; margin-left: 2px;\">x</p>',\n * { tags: ['p'] },\n * )\n */\n/**\n * Fold `border-width`, `border-style` and `border-color` into `border`.\n *\n * postcss-merge-longhand stopped doing this in 8.0.3 because the\n * shorthand also resets `border-image`. Email clients don't support\n * `border-image`, so the merge is safe for inline styles.\n */\nconst mergeBorder: Plugin = {\n postcssPlugin: 'maizzle-merge-border',\n OnceExit(root) {\n root.walkRules((rule) => {\n const decls: Declaration[] = []\n\n for (const prop of ['border-width', 'border-style', 'border-color']) {\n const found = rule.nodes.filter(\n (node): node is Declaration => node.type === 'decl' && node.prop.toLowerCase() === prop,\n )\n if (found.length !== 1) return\n decls.push(found[0])\n }\n\n const [width, style, color] = decls\n const { important } = width\n\n for (const decl of decls) {\n if (\n decl.important !== important\n || list.space(decl.value).length !== 1\n || /var\\s*\\(/i.test(decl.value)\n ) return\n }\n\n const last = decls.reduce((a, b) => (rule.index(b) > rule.index(a) ? b : a))\n\n last.replaceWith({\n prop: 'border',\n value: `${width.value} ${style.value} ${color.value}`,\n important,\n })\n\n for (const decl of decls) {\n if (decl !== last) decl.remove()\n }\n })\n },\n}\n\nexport function shorthandCss(html: string, options: ShorthandCssOptions = {}): string {\n return serialize(shorthandCssDom(parse(html), options))\n}\n\n/**\n * DOM-form of {@link shorthandCss} used by the internal transformer\n * pipeline. Takes a parsed DOM, returns a parsed DOM — avoids redundant\n * serialize/parse round-trips when chained with other transformers.\n */\nexport function shorthandCssDom(dom: ChildNode[], options: ShorthandCssOptions = {}): ChildNode[] {\n const allowedTags = options.tags ?? []\n const hasTagFilter = allowedTags.length > 0\n\n /**\n * Utility-generated inline styles repeat heavily across elements, so\n * each distinct value only goes through postcss once per call.\n */\n const cache = new Map<string, string>()\n\n /**\n * Merge longhand within a single inline-style value. Returns the merged\n * string when shorter, otherwise the original. Wraps the value in a\n * dummy selector since postcss-merge-longhand operates on rules.\n */\n const mergeStyleValue = (styleValue: string): string => {\n let result = cache.get(styleValue)\n if (result !== undefined) return result\n\n result = styleValue\n try {\n const { css } = postcss()\n .use(mergeLonghand)\n .use(mergeBorder)\n .process(`div { ${styleValue} }`, { parser: safeParser })\n const match = css.match(/div\\s*\\{\\s*([^}]+)\\s*\\}/)\n if (match && match[1]) result = match[1].trim()\n }\n catch {}\n\n cache.set(styleValue, result)\n return result\n }\n\n walk(dom, (node) => {\n /**\n * MSO conditional comments carry their own inline-style attributes\n * (e.g. `<!--[if mso]><td style=\"…\"><![endif]-->`) as opaque text.\n * The element walker can't see them, so without this branch the td/\n * v:rect styles inside comments stay longhand even when the visible\n * div has already been merged. Match each `style=\"…\"` substring,\n * run it through mergeLonghand, splice back.\n *\n * Tag filter intentionally bypassed: the user can't address MSO td\n * elements (they don't parse as elements), and these comments\n * always wrap email-layout primitives anyway.\n */\n if (node.type === 'comment') {\n const data = (node as any).data as string\n if (!data || !data.includes('style=\"')) return\n const newData = data.replace(/style=\"([^\"]*)\"/g, (full, value) => {\n const merged = mergeStyleValue(value)\n return merged === value ? full : `style=\"${merged}\"`\n })\n if (newData !== data) (node as any).data = newData\n return\n }\n\n const el = node as Element\n\n if (!el.attribs?.style) return\n if (hasTagFilter && !allowedTags.includes(el.name)) return\n\n const merged = mergeStyleValue(el.attribs.style)\n if (merged !== el.attribs.style) el.attribs.style = merged\n })\n\n return dom\n}\n"],"mappings":";;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;AAgDA,MAAM,cAAsB;CAC1B,eAAe;CACf,SAAS,MAAM;EACb,KAAK,WAAW,SAAS;GACvB,MAAM,QAAuB,CAAC;GAE9B,KAAK,MAAM,QAAQ;IAAC;IAAgB;IAAgB;GAAc,GAAG;IACnE,MAAM,QAAQ,KAAK,MAAM,QACtB,SAA8B,KAAK,SAAS,UAAU,KAAK,KAAK,YAAY,MAAM,IACrF;IACA,IAAI,MAAM,WAAW,GAAG;IACxB,MAAM,KAAK,MAAM,EAAE;GACrB;GAEA,MAAM,CAAC,OAAO,OAAO,SAAS;GAC9B,MAAM,EAAE,cAAc;GAEtB,KAAK,MAAM,QAAQ,OACjB,IACE,KAAK,cAAc,aAChB,KAAK,MAAM,KAAK,KAAK,CAAC,CAAC,WAAW,KAClC,YAAY,KAAK,KAAK,KAAK,GAC9B;GAGJ,MAAM,OAAO,MAAM,QAAQ,GAAG,MAAO,KAAK,MAAM,CAAC,IAAI,KAAK,MAAM,CAAC,IAAI,IAAI,CAAE;GAE3E,KAAK,YAAY;IACf,MAAM;IACN,OAAO,GAAG,MAAM,MAAM,GAAG,MAAM,MAAM,GAAG,MAAM;IAC9C;GACF,CAAC;GAED,KAAK,MAAM,QAAQ,OACjB,IAAI,SAAS,MAAM,KAAK,OAAO;EAEnC,CAAC;CACH;AACF;AAEA,SAAgB,aAAa,MAAc,UAA+B,CAAC,GAAW;CACpF,OAAO,UAAU,gBAAgB,MAAM,IAAI,GAAG,OAAO,CAAC;AACxD;;;;;;AAOA,SAAgB,gBAAgB,KAAkB,UAA+B,CAAC,GAAgB;CAChG,MAAM,cAAc,QAAQ,QAAQ,CAAC;CACrC,MAAM,eAAe,YAAY,SAAS;;;;;CAM1C,MAAM,wBAAQ,IAAI,IAAoB;;;;;;CAOtC,MAAM,mBAAmB,eAA+B;EACtD,IAAI,SAAS,MAAM,IAAI,UAAU;EACjC,IAAI,WAAW,KAAA,GAAW,OAAO;EAEjC,SAAS;EACT,IAAI;GACF,MAAM,EAAE,QAAQ,QAAQ,CAAC,CACtB,IAAI,aAAa,CAAC,CAClB,IAAI,WAAW,CAAC,CAChB,QAAQ,SAAS,WAAW,KAAK,EAAE,QAAQ,WAAW,CAAC;GAC1D,MAAM,QAAQ,IAAI,MAAM,yBAAyB;GACjD,IAAI,SAAS,MAAM,IAAI,SAAS,MAAM,EAAE,CAAC,KAAK;EAChD,QACM,CAAC;EAEP,MAAM,IAAI,YAAY,MAAM;EAC5B,OAAO;CACT;CAEA,KAAK,MAAM,SAAS;;;;;;;;;;;;;EAalB,IAAI,KAAK,SAAS,WAAW;GAC3B,MAAM,OAAQ,KAAa;GAC3B,IAAI,CAAC,QAAQ,CAAC,KAAK,SAAS,UAAS,GAAG;GACxC,MAAM,UAAU,KAAK,QAAQ,qBAAqB,MAAM,UAAU;IAChE,MAAM,SAAS,gBAAgB,KAAK;IACpC,OAAO,WAAW,QAAQ,OAAO,UAAU,OAAO;GACpD,CAAC;GACD,IAAI,YAAY,MAAM,KAAc,OAAO;GAC3C;EACF;EAEA,MAAM,KAAK;EAEX,IAAI,CAAC,GAAG,SAAS,OAAO;EACxB,IAAI,gBAAgB,CAAC,YAAY,SAAS,GAAG,IAAI,GAAG;EAEpD,MAAM,SAAS,gBAAgB,GAAG,QAAQ,KAAK;EAC/C,IAAI,WAAW,GAAG,QAAQ,OAAO,GAAG,QAAQ,QAAQ;CACtD,CAAC;CAED,OAAO;AACT"}
@@ -50,7 +50,7 @@ async function tailwindComponent(dom, blocks, config, filePath, sourceFiles) {
50
50
  */
51
51
  if (el.attribs?.class && stack.length > 0) map.get(stack[0]).classes.add(el.attribs.class);
52
52
  });
53
- const fromPath = filePath ?? resolve(process.cwd(), "template.vue");
53
+ const fromPath = filePath ?? resolve(config.root ?? process.cwd(), "template.vue");
54
54
  let head;
55
55
  walk(dom, (n) => {
56
56
  if (!head && n.name === "head") head = n;
@@ -1 +1 @@
1
- {"version":3,"file":"tailwindComponent.js","names":[],"sources":["../../src/transformers/tailwindComponent.ts"],"sourcesContent":["import { resolve, relative, dirname } from 'pathe'\nimport type { ChildNode, Element, Comment } from 'domhandler'\nimport { walk } from '../utils/ast/index.ts'\nimport { rewriteImportsSourceNone } from './tailwindcss.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\" source(none);'\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 sourceFiles?: 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 /**\n * Always assign to the OUTERMOST active marker (stack[0]) so nested\n * <Tailwind> blocks merge their classes into the parent's scope.\n */\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 /**\n * Compile + inject one <style raw> per outermost block. `raw` opts\n * the existing tailwindcss transformer out of recompiling\n * already-compiled CSS.\n */\n const scoped = config.css?.scopedSources !== false && !!sourceFiles?.length\n\n for (const meta of map.values()) {\n if (meta.nested) continue\n\n const cssInput = buildCssInput(meta.configCss, meta.classes, scoped ? { sourceFiles: sourceFiles!, fromDir: dirname(fromPath) } : undefined)\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(\n configCss: string | undefined,\n classes: Set<string>,\n scope?: { sourceFiles: string[]; fromDir: string },\n): string {\n let seed = configCss ?? DEFAULT_SEED\n\n const parts: string[] = []\n\n /**\n * Scoped mode: disable auto source detection in the user's config\n * CSS and point the scanner at the template's import closure\n * instead, mirroring the main tailwindcss transformer.\n */\n if (scope) {\n seed = rewriteImportsSourceNone(seed)\n for (const file of scope.sourceFiles) {\n parts.push(`@source \"${relative(scope.fromDir, file)}\";`)\n }\n }\n\n if (classes.size) {\n const inline = [...classes].join(' ').replace(/\"/g, '\\\\\"')\n parts.push(`@source inline(\"${inline}\");`)\n }\n\n return parts.length ? `${seed}\\n${parts.join('\\n')}` : seed\n}\n"],"mappings":"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"}
1
+ {"version":3,"file":"tailwindComponent.js","names":[],"sources":["../../src/transformers/tailwindComponent.ts"],"sourcesContent":["import { resolve, relative, dirname } from 'pathe'\nimport type { ChildNode, Element, Comment } from 'domhandler'\nimport { walk } from '../utils/ast/index.ts'\nimport { rewriteImportsSourceNone } from './tailwindcss.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\" source(none);'\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 sourceFiles?: 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 /**\n * Always assign to the OUTERMOST active marker (stack[0]) so nested\n * <Tailwind> blocks merge their classes into the parent's scope.\n */\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(config.root ?? 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 /**\n * Compile + inject one <style raw> per outermost block. `raw` opts\n * the existing tailwindcss transformer out of recompiling\n * already-compiled CSS.\n */\n const scoped = config.css?.scopedSources !== false && !!sourceFiles?.length\n\n for (const meta of map.values()) {\n if (meta.nested) continue\n\n const cssInput = buildCssInput(meta.configCss, meta.classes, scoped ? { sourceFiles: sourceFiles!, fromDir: dirname(fromPath) } : undefined)\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(\n configCss: string | undefined,\n classes: Set<string>,\n scope?: { sourceFiles: string[]; fromDir: string },\n): string {\n let seed = configCss ?? DEFAULT_SEED\n\n const parts: string[] = []\n\n /**\n * Scoped mode: disable auto source detection in the user's config\n * CSS and point the scanner at the template's import closure\n * instead, mirroring the main tailwindcss transformer.\n */\n if (scope) {\n seed = rewriteImportsSourceNone(seed)\n for (const file of scope.sourceFiles) {\n parts.push(`@source \"${relative(scope.fromDir, file)}\";`)\n }\n }\n\n if (classes.size) {\n const inline = [...classes].join(' ').replace(/\"/g, '\\\\\"')\n parts.push(`@source inline(\"${inline}\");`)\n }\n\n return parts.length ? `${seed}\\n${parts.join('\\n')}` : seed\n}\n"],"mappings":"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"}
@@ -141,8 +141,10 @@ function rewriteImportsSourceNone(css) {
141
141
  */
142
142
  async function tailwindcss(dom, config, filePath, sourceFiles) {
143
143
  const styleTags = [];
144
+ let styleCount = 0;
144
145
  walk(dom, (node) => {
145
146
  if (node.name !== "style") return;
147
+ styleCount++;
146
148
  const el = node;
147
149
  /**
148
150
  * `raw` opts out of compilation entirely (marker is consumed here).
@@ -158,11 +160,12 @@ async function tailwindcss(dom, config, filePath, sourceFiles) {
158
160
  if (!rawContent.trim()) return;
159
161
  styleTags.push({
160
162
  node: el,
161
- cssContent: decodeStyleEntities(rawContent)
163
+ cssContent: decodeStyleEntities(rawContent),
164
+ position: styleCount
162
165
  });
163
166
  });
164
167
  if (!styleTags.length) return dom;
165
- const fromPath = filePath ?? resolve(process.cwd(), "template.vue");
168
+ const fromPath = filePath ?? resolve(config.root ?? process.cwd(), "template.vue");
166
169
  const fromDir = dirname(fromPath);
167
170
  const hasTailwindStyles = styleTags.some(({ cssContent }) => usesTailwind(cssContent));
168
171
  const sourceDirectives = hasTailwindStyles ? buildSourceDirectives(dom, config, fromDir, sourceFiles) : "";
@@ -176,7 +179,7 @@ async function tailwindcss(dom, config, filePath, sourceFiles) {
176
179
  const gradientCombos = hasTailwindStyles ? collectGradientCombos(dom) : [];
177
180
  const firstTailwindStyle = styleTags.findIndex(({ cssContent }) => usesTailwind(cssContent));
178
181
  for (let i = 0; i < styleTags.length; i++) {
179
- const { node, cssContent } = styleTags[i];
182
+ const { node, cssContent, position } = styleTags[i];
180
183
  const fullCss = usesTailwind(cssContent) ? `${scoped ? rewriteImportsSourceNone(cssContent) : cssContent}\n${sourceDirectives}` : cssContent;
181
184
  const combos = i === firstTailwindStyle ? gradientCombos : [];
182
185
  try {
@@ -185,7 +188,8 @@ async function tailwindcss(dom, config, filePath, sourceFiles) {
185
188
  data: await compileTailwindCss(fullCss, config, `${fromPath}?style=${i}`, combos),
186
189
  parent: node
187
190
  }];
188
- } catch {
191
+ } catch (error) {
192
+ console.warn(`[maizzle] Failed to compile <style> #${position} in ${filePath ?? "a string template"}, it was left uncompiled: ${error?.message ?? error}`);
189
193
  /**
190
194
  * If CSS processing fails, still replace with decoded content
191
195
  * so HTML entities don't break the CSS.
@@ -1 +1 @@
1
- {"version":3,"file":"tailwindcss.js","names":[],"sources":["../../src/transformers/tailwindcss.ts"],"sourcesContent":["import { resolve, dirname, relative } from 'pathe'\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 { GradientCombo } from '../plugins/postcss/flattenGradients.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, sourceFiles?: string[]): string {\n const directives: string[] = []\n\n const scoped = config.css?.scopedSources !== false && !!sourceFiles?.length\n\n if (scoped) {\n /**\n * Scoped mode: point Tailwind's scanner at exactly the files in\n * this template's import closure instead of auto-detecting from\n * the project root. Auto-detection is disabled by appending\n * `source(none)` to the Tailwind import (see\n * rewriteImportsSourceNone below).\n */\n for (const file of sourceFiles!) {\n directives.push(`@source \"${relative(fromDir, file)}\";`)\n }\n } else {\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\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\n * bindings). We pass these raw values to Tailwind's\n * scanner via @source inline().\n */\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\nconst GRADIENT_FN_RE = /^bg-(linear|radial|conic)\\b/\nconst GRADIENT_GENERATED_RE = /^bg-(linear|radial|conic)-gradient-/\nconst GRADIENT_STOP_RE = /^(from|via|to)-/\n\n/** Rank a stop class so generated names are stable regardless of author order. */\nfunction stopRank(cls: string): number {\n const prefix = cls.startsWith('from-') ? 0 : cls.startsWith('via-') ? 1 : 2\n const isPosition = /^(from|via|to)-\\d+%$/.test(cls) ? 1 : 0\n return prefix * 2 + isPosition\n}\n\n/** Sanitize a class token into a valid, readable CSS class name fragment. */\nfunction sanitize(token: string): string {\n return token\n .replace(/[[\\]#()]/g, '')\n .replace(/[/,.%\\s]+/g, '-')\n .replace(/-+/g, '-')\n .replace(/^-|-$/g, '')\n}\n\n/**\n * Detect Tailwind gradient class combinations on DOM elements.\n *\n * A gradient only works once its `bg-linear/radial/conic` direction class\n * combines with `from-*`/`via-*`/`to-*` stops on the same element. This\n * collects those per-element combos, rewrites each element to a single\n * readable class (e.g. `bg-linear-gradient-to-bl-from-indigo-50-to-indigo-600`),\n * and returns the combos so the flattenGradients plugin can emit one flat\n * `background-image` rule per unique combo.\n */\nfunction collectGradientCombos(dom: ChildNode[]): GradientCombo[] {\n const bySignature = new Map<string, GradientCombo>()\n const usedNames = new Map<string, string>()\n\n walk(dom, (node) => {\n const el = node as Element\n const cls = el.attribs?.class\n if (!cls) return\n\n const tokens = cls.split(/\\s+/).filter(Boolean)\n const fnClass = tokens.find(t => GRADIENT_FN_RE.test(t) && !GRADIENT_GENERATED_RE.test(t))\n if (!fnClass) return\n\n const gradientClasses = tokens.filter(\n t => (GRADIENT_FN_RE.test(t) && !GRADIENT_GENERATED_RE.test(t)) || GRADIENT_STOP_RE.test(t),\n )\n const stops = gradientClasses.filter(t => t !== fnClass).sort((a, b) => stopRank(a) - stopRank(b) || a.localeCompare(b))\n const ordered = [fnClass, ...stops]\n const signature = ordered.join(' ')\n\n let combo = bySignature.get(signature)\n if (!combo) {\n const fn = fnClass.match(GRADIENT_FN_RE)![1]\n const dirRemainder = fnClass.replace(new RegExp(`^bg-${fn}-?`), '')\n const parts = [dirRemainder, ...stops].filter(Boolean).map(sanitize)\n let name = `bg-${fn}-gradient${parts.length ? `-${parts.join('-')}` : ''}`\n\n // Guard against sanitize collisions from distinct combos.\n const existing = usedNames.get(name)\n if (existing && existing !== signature) {\n let n = 2\n while (usedNames.has(`${name}-${n}`)) n++\n name = `${name}-${n}`\n }\n usedNames.set(name, signature)\n\n combo = { className: name, classes: ordered }\n bySignature.set(signature, combo)\n }\n\n // Replace the gradient utilities with the single generated class.\n const rest = tokens.filter(t => !gradientClasses.includes(t))\n el.attribs.class = [...rest, combo.className].join(' ')\n })\n\n return [...bySignature.values()]\n}\n\n/**\n * Append ` source(none)` to Tailwind imports so auto source detection\n * is off and only our explicit `@source` directives apply. Skips\n * imports that already carry a `source(...)` modifier.\n */\nexport function rewriteImportsSourceNone(css: string): string {\n return css.replace(\n /(@import\\s+[\"'](?:@maizzle\\/)?tailwindcss(?:\\/[^\"']*)?[\"'][^;]*);/g,\n (match, stmt) => stmt.includes('source(') ? match : `${stmt} source(none);`,\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 * - The template's module import closure (via `@source` directives), or user\n * project files (via Tailwind's auto-detection) when `css.scopedSources` is off\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, sourceFiles?: 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 /**\n * `raw` opts out of compilation entirely (marker is consumed here).\n * `embed`/`data-embed` only signal \"preserve tag after inlining\"\n * — they still need to go through compile so Tailwind/@apply\n * resolves.\n */\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, sourceFiles)\n : ''\n\n const scoped = config.css?.scopedSources !== false && !!sourceFiles?.length\n\n /**\n * Collect gradient combos and rewrite elements to single classes.\n * Runs after source directives are built (so the utility classes are\n * still scanned) and only feeds the first Tailwind style tag, whose\n * `:root` holds the theme colors the flat rules reference.\n */\n const gradientCombos = hasTailwindStyles ? collectGradientCombos(dom) : []\n const firstTailwindStyle = styleTags.findIndex(({ cssContent }) => usesTailwind(cssContent))\n\n for (let i = 0; i < styleTags.length; i++) {\n const { node, cssContent } = styleTags[i]\n\n /**\n * Only add source directives to style tags that import Tailwind —\n * plain CSS doesn't need them and @tailwindcss/postcss would\n * leave the directives unconsumed in the output.\n */\n const usesTw = usesTailwind(cssContent)\n const fullCss = usesTw\n ? `${scoped ? rewriteImportsSourceNone(cssContent) : cssContent}\\n${sourceDirectives}`\n : cssContent\n\n const combos = i === firstTailwindStyle ? gradientCombos : []\n\n try {\n const optimized = await compileTailwindCss(fullCss, config, `${fromPath}?style=${i}`, combos)\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 /**\n * If CSS processing fails, still replace with decoded content\n * so HTML entities don't break the CSS.\n */\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.js","names":[],"sources":["../../src/transformers/tailwindcss.ts"],"sourcesContent":["import { resolve, dirname, relative } from 'pathe'\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 { GradientCombo } from '../plugins/postcss/flattenGradients.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, sourceFiles?: string[]): string {\n const directives: string[] = []\n\n const scoped = config.css?.scopedSources !== false && !!sourceFiles?.length\n\n if (scoped) {\n /**\n * Scoped mode: point Tailwind's scanner at exactly the files in\n * this template's import closure instead of auto-detecting from\n * the project root. Auto-detection is disabled by appending\n * `source(none)` to the Tailwind import (see\n * rewriteImportsSourceNone below).\n */\n for (const file of sourceFiles!) {\n directives.push(`@source \"${relative(fromDir, file)}\";`)\n }\n } else {\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\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\n * bindings). We pass these raw values to Tailwind's\n * scanner via @source inline().\n */\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\nconst GRADIENT_FN_RE = /^bg-(linear|radial|conic)\\b/\nconst GRADIENT_GENERATED_RE = /^bg-(linear|radial|conic)-gradient-/\nconst GRADIENT_STOP_RE = /^(from|via|to)-/\n\n/** Rank a stop class so generated names are stable regardless of author order. */\nfunction stopRank(cls: string): number {\n const prefix = cls.startsWith('from-') ? 0 : cls.startsWith('via-') ? 1 : 2\n const isPosition = /^(from|via|to)-\\d+%$/.test(cls) ? 1 : 0\n return prefix * 2 + isPosition\n}\n\n/** Sanitize a class token into a valid, readable CSS class name fragment. */\nfunction sanitize(token: string): string {\n return token\n .replace(/[[\\]#()]/g, '')\n .replace(/[/,.%\\s]+/g, '-')\n .replace(/-+/g, '-')\n .replace(/^-|-$/g, '')\n}\n\n/**\n * Detect Tailwind gradient class combinations on DOM elements.\n *\n * A gradient only works once its `bg-linear/radial/conic` direction class\n * combines with `from-*`/`via-*`/`to-*` stops on the same element. This\n * collects those per-element combos, rewrites each element to a single\n * readable class (e.g. `bg-linear-gradient-to-bl-from-indigo-50-to-indigo-600`),\n * and returns the combos so the flattenGradients plugin can emit one flat\n * `background-image` rule per unique combo.\n */\nfunction collectGradientCombos(dom: ChildNode[]): GradientCombo[] {\n const bySignature = new Map<string, GradientCombo>()\n const usedNames = new Map<string, string>()\n\n walk(dom, (node) => {\n const el = node as Element\n const cls = el.attribs?.class\n if (!cls) return\n\n const tokens = cls.split(/\\s+/).filter(Boolean)\n const fnClass = tokens.find(t => GRADIENT_FN_RE.test(t) && !GRADIENT_GENERATED_RE.test(t))\n if (!fnClass) return\n\n const gradientClasses = tokens.filter(\n t => (GRADIENT_FN_RE.test(t) && !GRADIENT_GENERATED_RE.test(t)) || GRADIENT_STOP_RE.test(t),\n )\n const stops = gradientClasses.filter(t => t !== fnClass).sort((a, b) => stopRank(a) - stopRank(b) || a.localeCompare(b))\n const ordered = [fnClass, ...stops]\n const signature = ordered.join(' ')\n\n let combo = bySignature.get(signature)\n if (!combo) {\n const fn = fnClass.match(GRADIENT_FN_RE)![1]\n const dirRemainder = fnClass.replace(new RegExp(`^bg-${fn}-?`), '')\n const parts = [dirRemainder, ...stops].filter(Boolean).map(sanitize)\n let name = `bg-${fn}-gradient${parts.length ? `-${parts.join('-')}` : ''}`\n\n // Guard against sanitize collisions from distinct combos.\n const existing = usedNames.get(name)\n if (existing && existing !== signature) {\n let n = 2\n while (usedNames.has(`${name}-${n}`)) n++\n name = `${name}-${n}`\n }\n usedNames.set(name, signature)\n\n combo = { className: name, classes: ordered }\n bySignature.set(signature, combo)\n }\n\n // Replace the gradient utilities with the single generated class.\n const rest = tokens.filter(t => !gradientClasses.includes(t))\n el.attribs.class = [...rest, combo.className].join(' ')\n })\n\n return [...bySignature.values()]\n}\n\n/**\n * Append ` source(none)` to Tailwind imports so auto source detection\n * is off and only our explicit `@source` directives apply. Skips\n * imports that already carry a `source(...)` modifier.\n */\nexport function rewriteImportsSourceNone(css: string): string {\n return css.replace(\n /(@import\\s+[\"'](?:@maizzle\\/)?tailwindcss(?:\\/[^\"']*)?[\"'][^;]*);/g,\n (match, stmt) => stmt.includes('source(') ? match : `${stmt} source(none);`,\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 * - The template's module import closure (via `@source` directives), or user\n * project files (via Tailwind's auto-detection) when `css.scopedSources` is off\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, sourceFiles?: string[]): Promise<ChildNode[]> {\n const styleTags: { node: Element; cssContent: string; position: number }[] = []\n let styleCount = 0\n\n walk(dom, (node) => {\n if ((node as Element).name !== 'style') return\n\n styleCount++\n const el = node as Element\n const attrs = el.attribs\n\n /**\n * `raw` opts out of compilation entirely (marker is consumed here).\n * `embed`/`data-embed` only signal \"preserve tag after inlining\"\n * — they still need to go through compile so Tailwind/@apply\n * resolves.\n */\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), position: styleCount })\n })\n\n if (!styleTags.length) return dom\n\n const fromPath = filePath ?? resolve(config.root ?? 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, sourceFiles)\n : ''\n\n const scoped = config.css?.scopedSources !== false && !!sourceFiles?.length\n\n /**\n * Collect gradient combos and rewrite elements to single classes.\n * Runs after source directives are built (so the utility classes are\n * still scanned) and only feeds the first Tailwind style tag, whose\n * `:root` holds the theme colors the flat rules reference.\n */\n const gradientCombos = hasTailwindStyles ? collectGradientCombos(dom) : []\n const firstTailwindStyle = styleTags.findIndex(({ cssContent }) => usesTailwind(cssContent))\n\n for (let i = 0; i < styleTags.length; i++) {\n const { node, cssContent, position } = styleTags[i]\n\n /**\n * Only add source directives to style tags that import Tailwind —\n * plain CSS doesn't need them and @tailwindcss/postcss would\n * leave the directives unconsumed in the output.\n */\n const usesTw = usesTailwind(cssContent)\n const fullCss = usesTw\n ? `${scoped ? rewriteImportsSourceNone(cssContent) : cssContent}\\n${sourceDirectives}`\n : cssContent\n\n const combos = i === firstTailwindStyle ? gradientCombos : []\n\n try {\n const optimized = await compileTailwindCss(fullCss, config, `${fromPath}?style=${i}`, combos)\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 (error) {\n console.warn(`[maizzle] Failed to compile <style> #${position} in ${filePath ?? 'a string template'}, it was left uncompiled: ${(error as Error)?.message ?? error}`)\n\n /**\n * If CSS processing fails, still replace with decoded content\n * so HTML entities don't break the CSS.\n */\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 +1 @@
1
- {"version":3,"file":"config.d.ts","names":[],"sources":["../../src/types/config.ts"],"mappings":";;;;;;;KAKK,eAAe,YAAY,kBAAkB;iBAGjC;;;;;;EAMf;;;;;;EAMA;;;;;;EAMA;;;;;;EAMA,KAAK;;YAGK,WAAW;EACrB,WAAW;;iBAGI;;;;;;;;;;;;EAYf,QAAQ;;;;;;;;;;;EAWR;;IAEE;;IAEA,kBAAkB,eAAe;;IAEjC,aAAa;;IAEb;;IAEA;;;iBAIa;;;;;;EAMf;;;;;;;;;;;EAWA;;;;;;;;EAQA,kBAAkB;;;;;;;;;;;;;;EAclB,mBAAmB;;;;;;;IAOjB;;;;;;IAMA;;;;;;;IAOA;;;;;;;;;;;;IAYA,mBAAmB;;;;;;;IAOnB;;;;;;;IAOA;;;;;;;IAOA;;;;;;;IAOA,aAAa;MAAiB;MAAe;;;;;;IAK7C;;;;;;;;;;;;;;EAcF;;;;;;IAME,4CAA4C,WAAW;;;;;;;;;EASzD;;;;;;EAMA,iBAAiB;;;;;;;;EAQjB;IAAwB;;;;;;;;;EAQxB;;;;;;;;;;;EAWA,qBAAqB,eA3BJ;;;;;;;;;;;;;EAwCjB;;iBAGe;;;;;;;;;;;;;;;;;;EAkBf,cAAc,uBAAuB;;;;;;;;;;;;;;;;;;;;;;EAsBrC,SAAS;IAAiB;IAAc,iBAAiB;;;YAG/C,2BAA2B;;;;;;YAO3B;iBAOK;;;;;;EAMf,UAAU;;;;;;;;EAQV;;iBAGe;;;;;;;;;;;EAWf;;;;;;;;;;;EAWA;;iBAGe;;EAEf,aAAa;;;;;;;;EAQb,iBAAiB;;;;;;EAMjB,mCAAmC;;;;;;;;;EASnC,mBAAmB,6BAA6B;;YAGtC,kBAAkB,aAAa;YAC/B,wBAAwB,eAAe;iBAElC,uBAAuB;;;;;;EAMtC,6BAA6B;;iBAGd;;;;;;;;;EASf,UAAU,kBAAkB;;EAE5B,aAAa,eAAe;;EAE5B,mBAAmB;;;;;;;;;;;;;;;EAenB,0BAA0B,mBAAmB,cAAc;;;;;;;;;;;;;;;;;;;;iBAqB5C;EACf;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;;;;;;;;iBASe;;;;;EAKf;;;;;;EAMA;;;;;;EAMA,UAAU,oCAAoC;;;;;;;;;;;;YAapC;;EAIR;;;;;EAKA;;;;;;;;;EASA;;iBAGa;;;;;;;;;;;;;;;EAef;;EAEA,WAAW;;;;;;;;EAQX;;EAEA;;;;;;IAME;;;;;;;;;;;IAWA;;;;;;;;;;;;;;;;;;;EAmBF;IAAuB;IAAkB;;;EAEzC;;;;;;IAME;;;;;;IAMA;;;EAGF;;;;;;;;;;;;;;;;;;;;IAoBE,SAAS,kBAAkB;;;EAG7B;;;;;;IAME;;;;;;;;;;;;;;;IAeA;;;;;;;;;;;IAWA;;;;;;;;;;;;;;;;;;;;IAoBA;;MAEE;;MAEA;;MAEA;;MAEA,YAAY;;;;;;;;;;;;;;;IAed,iBAAiB;;;EAGnB,MAAM;;;;;;;;;;;;;;;EAeN,sBAAsB;;EAEtB,UAAU;;;;;;;;;;;;EAYV,4BAA4B;;;;;;;;;EAS5B,iBAAiB;;;;;;;;;;;;EAYjB,UAAU;;EAEV,MAAM;;EAEN,OAAO;;;;;;;;;;;;;;;;;;;;;;EAsBP,OAAO;;;;;;;;;;;;;;;;EAgBP,MAAM;;;;;;;;;;;;EAYN,QAAQ;;EAKR,gBAAgB;IAAU,QAAQ;eAA2B;;EAE7D,gBAAgB;IAAU,QAAQ;IAAe,UAAU;wBAAmC;;EAE9F,eAAe;IAAU,QAAQ;IAAe,UAAU;IAAc;wBAAmC;;EAE3G,kBAAkB;IAAU,QAAQ;IAAe,UAAU;IAAc;wBAAmC;;EAE9G,cAAc;IAAU;IAAiB,QAAQ;eAA2B;GAG3E"}
1
+ {"version":3,"file":"config.d.ts","names":["_$___plugins_postcss_removeDeclarations_ts0.RemoveValue","MarkdownPluginOptions"],"sources":["../../src/types/config.ts"],"mappings":";;;;;;;KAKK,eAAe,YAAY,kBAAkB;iBAGjC;;;;;;EAMf;;;;;;EAMA;;;;;;EAMA;;;;;;EAMA,KAAK;;YAGK,WAAW;EACrB,WAAW;;iBAGI;;;;;;;;;;;;EAYf,QAAQ;;;;;;;;;;;EAWR;;IAEE;;IAEA,kBAAkB,eAAe;;IAEjC,aAAa;;IAEb;;IAEA;;;iBAIa;;;;;;EAMf;;;;;;;;;;;EAWA;;;;;;;;EAQA,kBAAkB;;;;;;;;;;;;;;EAclB,mBAAmB;;;;;;;IAOjB;;;;;;IAMA;;;;;;;IAOA;;;;;;;;;;;;IAYA,mBAAmB;;;;;;;IAOnB;;;;;;;IAOA;;;;;;;IAOA;;;;;;;IAOA,aAAa;MAAiB;MAAe;;;;;;IAK7C;;;;;;;;;;;;;;EAcF;;;;;;IAME,4CAA4C,WAAW;;;;;;;;;EASzD;;;;;;EAMA,iBAAiB;;;;;;;;EAQjB;IAAwB;;;;;;;;;EAQxB;;;;;;;;;;;EAWA,qBAAqB,eA3BJA;;;;;;;;;;;;;EAwCjB;;iBAGe;;;;;;;;;;;;;;;;;;EAkBf,cAAc,uBAAuB;;;;;;;;;;;;;;;;;;;;;;EAsBrC,SAAS;IAAiB;IAAc,iBAAiB;;;YAG/C,2BAA2B;;;;;;YAO3B;iBAOK;;;;;;EAMf,UAAU;;;;;;;;EAQV;;iBAGe;;;;;;;;;;;EAWf;;;;;;;;;;;EAWA;;iBAGe;;EAEf,aAAa;;;;;;;;EAQb,iBAAiB;;;;;;EAMjB,mCAAmC;;;;;;;;;EASnC,mBAAmB,6BAA6B;;YAGtC,kBAAkB,aAAa;YAC/B,wBAAwB,eAAe;iBAElC,uBAAuBC;;;;;;EAMtC,6BAA6B;;iBAGd;;;;;;;;;EASf,UAAU,kBAAkB;;EAE5B,aAAa,eAAe;;EAE5B,mBAAmB;;;;;;;;;;;;;;;EAenB,0BAA0B,mBAAmB,cAAc;;;;;;;;;;;;;;;;;;;;iBAqB5C;EACf;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;;;;;;;;iBASe;;;;;EAKf;;;;;;EAMA;;;;;;EAMA,UAAU,oCAAoC;;;;;;;;;;;;YAapC;;EAIR;;;;;EAKA;;;;;;;;;EASA;;iBAGa;;;;;;;;;;;;;;;EAef;;EAEA,WAAW;;;;;;;;EAQX;;EAEA;;;;;;IAME;;;;;;;;;;;IAWA;;;;;;;;;;;;;;;;;;;EAmBF;IAAuB;IAAkB;;;EAEzC;;;;;;IAME;;;;;;IAMA;;;EAGF;;;;;;;;;;;;;;;;;;;;IAoBE,SAAS,kBAAkB;;;EAG7B;;;;;;IAME;;;;;;;;;;;;;;;IAeA;;;;;;;;;;;IAWA;;;;;;;;;;;;;;;;;;;;IAoBA;;MAEE;;MAEA;;MAEA;;MAEA,YAAY;;;;;;;;;;;;;;;IAed,iBAAiB;;;EAGnB,MAAM;;;;;;;;;;;;;;;EAeN,sBAAsB;;EAEtB,UAAU;;;;;;;;;;;;EAYV,4BAA4B;;;;;;;;;EAS5B,iBAAiB;;;;;;;;;;;;EAYjB,UAAU;;EAEV,MAAM;;EAEN,OAAO;;;;;;;;;;;;;;;;;;;;;;EAsBP,OAAO;;;;;;;;;;;;;;;;EAgBP,MAAM;;;;;;;;;;;;EAYN,QAAQ;;EAKR,gBAAgB;IAAU,QAAQ;eAA2B;;EAE7D,gBAAgB;IAAU,QAAQ;IAAe,UAAU;wBAAmC;;EAE9F,eAAe;IAAU,QAAQ;IAAe,UAAU;IAAc;wBAAmC;;EAE3G,kBAAkB;IAAU,QAAQ;IAAe,UAAU;IAAc;wBAAmC;;EAE9G,cAAc;IAAU;IAAiB,QAAQ;eAA2B;GAG3E"}
@@ -13,7 +13,7 @@ import { transform } from "lightningcss";
13
13
  //#region src/utils/compileTailwindCss.ts
14
14
  function createTailwindProcessor(config, gradientCombos = []) {
15
15
  return postcss([
16
- resolveMaizzleImports(),
16
+ resolveMaizzleImports(config.root),
17
17
  tailwindcssPostcss({
18
18
  base: config.css?.base,
19
19
  transformAssetUrls: false,
@@ -1 +1 @@
1
- {"version":3,"file":"compileTailwindCss.js","names":["flattenGradients","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 flattenGradients, { type GradientCombo } from '../plugins/postcss/flattenGradients.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, gradientCombos: GradientCombo[] = []) {\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 // Flatten Tailwind's gradient var machinery into email-safe declarations\n // before the var()/color resolution steps run.\n flattenGradients(gradientCombos),\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: new TextEncoder().encode(css),\n minify: false,\n targets: { ie: 4 << 5 },\n })\n\n return new TextDecoder().decode(result.code)\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 gradientCombos: GradientCombo[] = [],\n): Promise<string> {\n const processor = createTailwindProcessor(config, gradientCombos)\n const result = await processor.process(cssInput, { from, parser: safeParser })\n const lowered = lowerCssSyntax(result.css)\n return optimizeTailwindCss(lowered, config)\n}\n"],"mappings":";;;;;;;;;;;;;AAcA,SAAgB,wBAAwB,QAAuB,iBAAkC,CAAC,GAAG;CACnG,OAAO,QAAQ;EAEb,sBAAsB;EACtB,mBAAmB;GACjB,MAAM,OAAO,KAAK;GAClB,oBAAoB;GACpB,UAAU;EACZ,CAAC;EAGDA,yBAAiB,cAAc;EAC/BC,qBAAa;EACb,YAAY,CAAC,CAAC;EACdC,kBAAU;CACZ,CAAC;AACH;AAEA,SAAgB,eAAe,KAAqB;CAClD,MAAM,SAAS,UAAU;EACvB,UAAU;EACV,MAAM,IAAI,YAAY,CAAC,CAAC,OAAO,GAAG;EAClC,QAAQ;EACR,SAAS,EAAE,IAAI,IAAO;CACxB,CAAC;CAED,OAAO,IAAI,YAAY,CAAC,CAAC,OAAO,OAAO,IAAI;AAC7C;AAEA,eAAsB,oBAAoB,KAAa,QAAwC;CAC7F,MAAM,UAA4B,CAAC,GAAG,gBAAgB,MAAM,GAAG,kBAAkB,CAAC;CAElF,MAAM,cAAc,kBAAkB,MAAM;CAC5C,IAAI,aAAa,QAAQ,KAAK,WAAW;CAIzC,QAAO,MAFc,QAAQ,OAAO,CAAC,CAAC,QAAQ,KAAK,EAAE,MAAM,KAAA,EAAU,CAAC,EAAA,CAExD;AAChB;;;;;;AAOA,eAAsB,mBACpB,UACA,QACA,MACA,iBAAkC,CAAC,GAClB;CAIjB,OAAO,oBADS,gBAAe,MAFb,wBAAwB,QAAQ,cACrB,CAAC,CAAC,QAAQ,UAAU;EAAE;EAAM,QAAQ;CAAW,CAAC,EAAA,CACvC,GACL,GAAG,MAAM;AAC5C"}
1
+ {"version":3,"file":"compileTailwindCss.js","names":["flattenGradients","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 flattenGradients, { type GradientCombo } from '../plugins/postcss/flattenGradients.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, gradientCombos: GradientCombo[] = []) {\n return postcss([\n // Must run before @tailwindcss/postcss so it sees absolute import paths\n resolveMaizzleImports(config.root),\n tailwindcssPostcss({\n base: config.css?.base,\n transformAssetUrls: false,\n optimize: false,\n }),\n // Flatten Tailwind's gradient var machinery into email-safe declarations\n // before the var()/color resolution steps run.\n flattenGradients(gradientCombos),\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: new TextEncoder().encode(css),\n minify: false,\n targets: { ie: 4 << 5 },\n })\n\n return new TextDecoder().decode(result.code)\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 gradientCombos: GradientCombo[] = [],\n): Promise<string> {\n const processor = createTailwindProcessor(config, gradientCombos)\n const result = await processor.process(cssInput, { from, parser: safeParser })\n const lowered = lowerCssSyntax(result.css)\n return optimizeTailwindCss(lowered, config)\n}\n"],"mappings":";;;;;;;;;;;;;AAcA,SAAgB,wBAAwB,QAAuB,iBAAkC,CAAC,GAAG;CACnG,OAAO,QAAQ;EAEb,sBAAsB,OAAO,IAAI;EACjC,mBAAmB;GACjB,MAAM,OAAO,KAAK;GAClB,oBAAoB;GACpB,UAAU;EACZ,CAAC;EAGDA,yBAAiB,cAAc;EAC/BC,qBAAa;EACb,YAAY,CAAC,CAAC;EACdC,kBAAU;CACZ,CAAC;AACH;AAEA,SAAgB,eAAe,KAAqB;CAClD,MAAM,SAAS,UAAU;EACvB,UAAU;EACV,MAAM,IAAI,YAAY,CAAC,CAAC,OAAO,GAAG;EAClC,QAAQ;EACR,SAAS,EAAE,IAAI,IAAO;CACxB,CAAC;CAED,OAAO,IAAI,YAAY,CAAC,CAAC,OAAO,OAAO,IAAI;AAC7C;AAEA,eAAsB,oBAAoB,KAAa,QAAwC;CAC7F,MAAM,UAA4B,CAAC,GAAG,gBAAgB,MAAM,GAAG,kBAAkB,CAAC;CAElF,MAAM,cAAc,kBAAkB,MAAM;CAC5C,IAAI,aAAa,QAAQ,KAAK,WAAW;CAIzC,QAAO,MAFc,QAAQ,OAAO,CAAC,CAAC,QAAQ,KAAK,EAAE,MAAM,KAAA,EAAU,CAAC,EAAA,CAExD;AAChB;;;;;;AAOA,eAAsB,mBACpB,UACA,QACA,MACA,iBAAkC,CAAC,GAClB;CAIjB,OAAO,oBADS,gBAAe,MAFb,wBAAwB,QAAQ,cACrB,CAAC,CAAC,QAAQ,UAAU;EAAE;EAAM,QAAQ;CAAW,CAAC,EAAA,CACvC,GACL,GAAG,MAAM;AAC5C"}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@maizzle/framework",
3
- "version": "6.1.6",
3
+ "version": "6.2.0",
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",
@@ -56,9 +56,9 @@
56
56
  "juice": "^12.0.0",
57
57
  "maizzle": "latest",
58
58
  "markdown-exit": "^1.1.0-beta.2",
59
- "nodemailer": "^9.0.0",
59
+ "nodemailer": "^10.0.10",
60
60
  "ora": "^9.3.0",
61
- "oxfmt": "^0.67.0",
61
+ "oxfmt": "^0.68.0",
62
62
  "pathe": "^2.0.3",
63
63
  "postcss": "^8.5.6",
64
64
  "postcss-calc": "^10.1.1",