@maizzle/framework 6.0.0-rc.8 → 6.0.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (606) hide show
  1. package/README.md +3 -3
  2. package/bin/maizzle.mjs +1 -1
  3. package/dist/build.d.ts +38 -0
  4. package/dist/build.d.ts.map +1 -0
  5. package/dist/build.js +234 -0
  6. package/dist/build.js.map +1 -0
  7. package/dist/components/Body.vue +32 -3
  8. package/dist/components/Button.vue +91 -62
  9. package/dist/components/CodeBlock.vue +6 -4
  10. package/dist/components/CodeInline.vue +77 -6
  11. package/dist/components/Column.vue +67 -31
  12. package/dist/components/Container.vue +73 -12
  13. package/dist/components/Font.vue +96 -0
  14. package/dist/components/Head.vue +1 -1
  15. package/dist/components/Heading.vue +1 -1
  16. package/dist/components/Hr.vue +33 -0
  17. package/dist/components/Html.vue +36 -3
  18. package/dist/components/Img.vue +332 -0
  19. package/dist/components/Layout.vue +71 -21
  20. package/dist/components/Link.vue +1 -1
  21. package/dist/components/Markdown.vue +56 -23
  22. package/dist/components/MarkdownLayout.vue +39 -0
  23. package/dist/components/NotPlaintext.vue +14 -0
  24. package/dist/components/Outlook.vue +38 -11
  25. package/dist/components/OutlookBg.vue +241 -0
  26. package/dist/components/Plaintext.vue +14 -0
  27. package/dist/components/Preheader.vue +35 -10
  28. package/dist/components/QrCode.vue +157 -0
  29. package/dist/components/Raw.vue +28 -0
  30. package/dist/components/Row.vue +115 -22
  31. package/dist/components/Section.vue +65 -26
  32. package/dist/components/Spacer.vue +35 -29
  33. package/dist/components/Tailwind.vue +45 -0
  34. package/dist/components/Text.vue +3 -3
  35. package/dist/components/Vml.vue +207 -94
  36. package/dist/components/utils.d.ts +53 -0
  37. package/dist/components/utils.d.ts.map +1 -0
  38. package/dist/components/utils.js +80 -0
  39. package/dist/components/utils.js.map +1 -0
  40. package/dist/components/utils.ts +102 -0
  41. package/dist/composables/defineConfig.d.ts +13 -0
  42. package/dist/composables/defineConfig.d.ts.map +1 -0
  43. package/dist/composables/{defineConfig.mjs → defineConfig.js} +7 -9
  44. package/dist/composables/defineConfig.js.map +1 -0
  45. package/dist/composables/renderContext.d.ts +37 -0
  46. package/dist/composables/renderContext.d.ts.map +1 -0
  47. package/dist/composables/renderContext.js +6 -0
  48. package/dist/composables/renderContext.js.map +1 -0
  49. package/dist/composables/useBaseUrl.d.ts +19 -0
  50. package/dist/composables/useBaseUrl.d.ts.map +1 -0
  51. package/dist/composables/useBaseUrl.js +26 -0
  52. package/dist/composables/useBaseUrl.js.map +1 -0
  53. package/dist/composables/useConfig.d.ts +16 -0
  54. package/dist/composables/useConfig.d.ts.map +1 -0
  55. package/dist/composables/useConfig.js +19 -0
  56. package/dist/composables/useConfig.js.map +1 -0
  57. package/dist/composables/useCurrentTemplate.d.ts +31 -0
  58. package/dist/composables/useCurrentTemplate.d.ts.map +1 -0
  59. package/dist/composables/useCurrentTemplate.js +42 -0
  60. package/dist/composables/useCurrentTemplate.js.map +1 -0
  61. package/dist/composables/{useDoctype.d.mts → useDoctype.d.ts} +1 -1
  62. package/dist/composables/useDoctype.d.ts.map +1 -0
  63. package/dist/composables/{useDoctype.mjs → useDoctype.js} +3 -4
  64. package/dist/composables/useDoctype.js.map +1 -0
  65. package/dist/composables/{useEvent.d.mts → useEvent.d.ts} +3 -3
  66. package/dist/composables/useEvent.d.ts.map +1 -0
  67. package/dist/composables/{useEvent.mjs → useEvent.js} +4 -5
  68. package/dist/composables/useEvent.js.map +1 -0
  69. package/dist/composables/useFont.d.ts +50 -0
  70. package/dist/composables/useFont.d.ts.map +1 -0
  71. package/dist/composables/useFont.js +92 -0
  72. package/dist/composables/useFont.js.map +1 -0
  73. package/dist/composables/useOutlookFallback.d.ts +21 -0
  74. package/dist/composables/useOutlookFallback.d.ts.map +1 -0
  75. package/dist/composables/useOutlookFallback.js +29 -0
  76. package/dist/composables/useOutlookFallback.js.map +1 -0
  77. package/dist/composables/useOutputPath.d.ts +17 -0
  78. package/dist/composables/useOutputPath.d.ts.map +1 -0
  79. package/dist/composables/useOutputPath.js +23 -0
  80. package/dist/composables/useOutputPath.js.map +1 -0
  81. package/dist/composables/{usePlaintext.d.mts → usePlaintext.d.ts} +3 -1
  82. package/dist/composables/usePlaintext.d.ts.map +1 -0
  83. package/dist/composables/{usePlaintext.mjs → usePlaintext.js} +4 -4
  84. package/dist/composables/usePlaintext.js.map +1 -0
  85. package/dist/composables/usePreheader.d.ts +25 -0
  86. package/dist/composables/usePreheader.d.ts.map +1 -0
  87. package/dist/composables/usePreheader.js +28 -0
  88. package/dist/composables/usePreheader.js.map +1 -0
  89. package/dist/composables/useTransformers.d.ts +34 -0
  90. package/dist/composables/useTransformers.d.ts.map +1 -0
  91. package/dist/composables/useTransformers.js +48 -0
  92. package/dist/composables/useTransformers.js.map +1 -0
  93. package/dist/composables/useUrlQuery.d.ts +19 -0
  94. package/dist/composables/useUrlQuery.d.ts.map +1 -0
  95. package/dist/composables/useUrlQuery.js +26 -0
  96. package/dist/composables/useUrlQuery.js.map +1 -0
  97. package/dist/config/{defaults.d.mts → defaults.d.ts} +2 -2
  98. package/dist/config/defaults.d.ts.map +1 -0
  99. package/dist/config/{defaults.mjs → defaults.js} +10 -6
  100. package/dist/config/defaults.js.map +1 -0
  101. package/dist/config/index.d.ts +24 -0
  102. package/dist/config/index.d.ts.map +1 -0
  103. package/dist/config/{index.mjs → index.js} +45 -14
  104. package/dist/config/index.js.map +1 -0
  105. package/dist/events/{index.d.mts → index.d.ts} +35 -12
  106. package/dist/events/index.d.ts.map +1 -0
  107. package/dist/events/{index.mjs → index.js} +31 -13
  108. package/dist/events/index.js.map +1 -0
  109. package/dist/index.d.ts +41 -0
  110. package/dist/index.js +40 -0
  111. package/dist/{plaintext.d.mts → plaintext.d.ts} +1 -1
  112. package/dist/plaintext.d.ts.map +1 -0
  113. package/dist/{plaintext.mjs → plaintext.js} +4 -5
  114. package/dist/plaintext.js.map +1 -0
  115. package/dist/{plugin.d.mts → plugin.d.ts} +2 -2
  116. package/dist/plugin.d.ts.map +1 -0
  117. package/dist/{plugin.mjs → plugin.js} +16 -13
  118. package/dist/plugin.js.map +1 -0
  119. package/dist/plugins/postcss/{mergeMediaQueries.d.mts → mergeMediaQueries.d.ts} +2 -2
  120. package/dist/plugins/postcss/mergeMediaQueries.d.ts.map +1 -0
  121. package/dist/plugins/postcss/{mergeMediaQueries.mjs → mergeMediaQueries.js} +2 -3
  122. package/dist/plugins/postcss/mergeMediaQueries.js.map +1 -0
  123. package/dist/plugins/postcss/{pruneVars.d.mts → pruneVars.d.ts} +1 -1
  124. package/dist/plugins/postcss/pruneVars.d.ts.map +1 -0
  125. package/dist/plugins/postcss/{pruneVars.mjs → pruneVars.js} +2 -2
  126. package/dist/plugins/postcss/pruneVars.js.map +1 -0
  127. package/dist/plugins/postcss/quoteFontFamilies.d.ts +13 -0
  128. package/dist/plugins/postcss/quoteFontFamilies.d.ts.map +1 -0
  129. package/dist/plugins/postcss/quoteFontFamilies.js +84 -0
  130. package/dist/plugins/postcss/quoteFontFamilies.js.map +1 -0
  131. package/dist/plugins/postcss/{removeDeclarations.d.mts → removeDeclarations.d.ts} +1 -1
  132. package/dist/plugins/postcss/removeDeclarations.d.ts.map +1 -0
  133. package/dist/plugins/postcss/{removeDeclarations.mjs → removeDeclarations.js} +2 -2
  134. package/dist/plugins/postcss/removeDeclarations.js.map +1 -0
  135. package/dist/plugins/postcss/resolveMaizzleImports.d.ts +16 -0
  136. package/dist/plugins/postcss/resolveMaizzleImports.d.ts.map +1 -0
  137. package/dist/plugins/postcss/resolveMaizzleImports.js +39 -0
  138. package/dist/plugins/postcss/resolveMaizzleImports.js.map +1 -0
  139. package/dist/plugins/postcss/resolveProps.d.ts +8 -0
  140. package/dist/plugins/postcss/resolveProps.d.ts.map +1 -0
  141. package/dist/plugins/postcss/resolveProps.js +155 -0
  142. package/dist/plugins/postcss/resolveProps.js.map +1 -0
  143. package/dist/plugins/postcss/{tailwindCleanup.d.mts → tailwindCleanup.d.ts} +2 -2
  144. package/dist/plugins/postcss/tailwindCleanup.d.ts.map +1 -0
  145. package/dist/plugins/postcss/{tailwindCleanup.mjs → tailwindCleanup.js} +29 -5
  146. package/dist/plugins/postcss/tailwindCleanup.js.map +1 -0
  147. package/dist/prepare.d.ts +17 -0
  148. package/dist/prepare.d.ts.map +1 -0
  149. package/dist/prepare.js +44 -0
  150. package/dist/prepare.js.map +1 -0
  151. package/dist/render/active.d.ts +8 -0
  152. package/dist/render/active.d.ts.map +1 -0
  153. package/dist/render/active.js +12 -0
  154. package/dist/render/active.js.map +1 -0
  155. package/dist/render/buildTemplate.d.ts +49 -0
  156. package/dist/render/buildTemplate.d.ts.map +1 -0
  157. package/dist/render/buildTemplate.js +141 -0
  158. package/dist/render/buildTemplate.js.map +1 -0
  159. package/dist/render/{createRenderer.d.mts → createRenderer.d.ts} +17 -6
  160. package/dist/render/createRenderer.d.ts.map +1 -0
  161. package/dist/render/createRenderer.js +468 -0
  162. package/dist/render/createRenderer.js.map +1 -0
  163. package/dist/render/index.d.ts +18 -0
  164. package/dist/render/index.d.ts.map +1 -0
  165. package/dist/render/index.js +59 -0
  166. package/dist/render/index.js.map +1 -0
  167. package/dist/render/injectFonts.d.ts +15 -0
  168. package/dist/render/injectFonts.d.ts.map +1 -0
  169. package/dist/render/injectFonts.js +45 -0
  170. package/dist/render/injectFonts.js.map +1 -0
  171. package/dist/render/parallel/buildWorker.d.ts +31 -0
  172. package/dist/render/parallel/buildWorker.d.ts.map +1 -0
  173. package/dist/render/parallel/buildWorker.js +66 -0
  174. package/dist/render/parallel/buildWorker.js.map +1 -0
  175. package/dist/render/parallel/worker.mjs +28 -0
  176. package/dist/render/plugins/codeBlockExtract.d.ts +14 -0
  177. package/dist/render/plugins/codeBlockExtract.d.ts.map +1 -0
  178. package/dist/render/plugins/codeBlockExtract.js +38 -0
  179. package/dist/render/plugins/codeBlockExtract.js.map +1 -0
  180. package/dist/render/plugins/markdownExtract.d.ts +12 -0
  181. package/dist/render/plugins/markdownExtract.d.ts.map +1 -0
  182. package/dist/render/plugins/markdownExtract.js +49 -0
  183. package/dist/render/plugins/markdownExtract.js.map +1 -0
  184. package/dist/render/plugins/rawExtract.d.ts +14 -0
  185. package/dist/render/plugins/rawExtract.d.ts.map +1 -0
  186. package/dist/render/plugins/rawExtract.js +34 -0
  187. package/dist/render/plugins/rawExtract.js.map +1 -0
  188. package/dist/render/plugins/rowSourceLocation.d.ts +18 -0
  189. package/dist/render/plugins/rowSourceLocation.d.ts.map +1 -0
  190. package/dist/render/plugins/rowSourceLocation.js +45 -0
  191. package/dist/render/plugins/rowSourceLocation.js.map +1 -0
  192. package/dist/{serve.d.mts → serve.d.ts} +5 -3
  193. package/dist/serve.d.ts.map +1 -0
  194. package/dist/{serve.mjs → serve.js} +207 -106
  195. package/dist/serve.js.map +1 -0
  196. package/dist/server/compatibility.d.ts +59 -0
  197. package/dist/server/compatibility.d.ts.map +1 -0
  198. package/dist/server/compatibility.js +959 -0
  199. package/dist/server/compatibility.js.map +1 -0
  200. package/dist/server/{email.d.mts → email.d.ts} +2 -2
  201. package/dist/server/email.d.ts.map +1 -0
  202. package/dist/server/{email.mjs → email.js} +2 -3
  203. package/dist/server/email.js.map +1 -0
  204. package/dist/server/linter.d.ts +20 -0
  205. package/dist/server/linter.d.ts.map +1 -0
  206. package/dist/server/linter.js +345 -0
  207. package/dist/server/linter.js.map +1 -0
  208. package/dist/server/sfc-utils.d.ts +21 -0
  209. package/dist/server/sfc-utils.d.ts.map +1 -0
  210. package/dist/server/sfc-utils.js +198 -0
  211. package/dist/server/sfc-utils.js.map +1 -0
  212. package/dist/server/ui/.vite/deps/@lucide_vue.js +44967 -0
  213. package/dist/server/ui/.vite/deps/@lucide_vue.js.map +1 -0
  214. package/dist/server/ui/.vite/deps/@vueuse_core.js +8155 -0
  215. package/dist/server/ui/.vite/deps/@vueuse_core.js.map +1 -0
  216. package/dist/server/ui/.vite/deps/@vueuse_shared.js +1859 -0
  217. package/dist/server/ui/.vite/deps/@vueuse_shared.js.map +1 -0
  218. package/dist/server/ui/.vite/deps/_metadata.json +78 -0
  219. package/dist/server/ui/.vite/deps/chunk-EAsCxrDo.js +14 -0
  220. package/dist/server/ui/.vite/deps/class-variance-authority.js +57 -0
  221. package/dist/server/ui/.vite/deps/class-variance-authority.js.map +1 -0
  222. package/dist/server/ui/.vite/deps/clsx.js +18 -0
  223. package/dist/server/ui/.vite/deps/clsx.js.map +1 -0
  224. package/dist/server/ui/.vite/deps/culori.js +4312 -0
  225. package/dist/server/ui/.vite/deps/culori.js.map +1 -0
  226. package/dist/server/ui/.vite/deps/package.json +3 -0
  227. package/dist/server/ui/.vite/deps/reka-ui.js +44464 -0
  228. package/dist/server/ui/.vite/deps/reka-ui.js.map +1 -0
  229. package/dist/server/ui/.vite/deps/tailwind-merge.js +3458 -0
  230. package/dist/server/ui/.vite/deps/tailwind-merge.js.map +1 -0
  231. package/dist/server/ui/.vite/deps/vue-router.js +6383 -0
  232. package/dist/server/ui/.vite/deps/vue-router.js.map +1 -0
  233. package/dist/server/ui/.vite/deps/vue.js +2 -0
  234. package/dist/server/ui/.vite/deps/vue.runtime.esm-bundler-DaqjATE_.js +8785 -0
  235. package/dist/server/ui/.vite/deps/vue.runtime.esm-bundler-DaqjATE_.js.map +1 -0
  236. package/dist/server/ui/App.vue +106 -66
  237. package/dist/server/ui/components/SidebarClose.vue +12 -0
  238. package/dist/server/ui/components/ui/checkbox/Checkbox.vue +1 -1
  239. package/dist/server/ui/components/ui/command/Command.vue +5 -1
  240. package/dist/server/ui/components/ui/command/CommandInput.vue +2 -2
  241. package/dist/server/ui/components/ui/dialog/DialogContent.vue +1 -1
  242. package/dist/server/ui/components/ui/dialog/DialogScrollContent.vue +1 -1
  243. package/dist/server/ui/components/ui/dropdown-menu/DropdownMenuCheckboxItem.vue +1 -1
  244. package/dist/server/ui/components/ui/dropdown-menu/DropdownMenuRadioItem.vue +1 -1
  245. package/dist/server/ui/components/ui/dropdown-menu/DropdownMenuSubTrigger.vue +1 -1
  246. package/dist/server/ui/components/ui/input/Input.vue +1 -1
  247. package/dist/server/ui/components/ui/sheet/SheetContent.vue +1 -1
  248. package/dist/server/ui/components/ui/sidebar/SidebarTrigger.vue +2 -2
  249. package/dist/server/ui/components/ui/tags-input/TagsInputInput.vue +1 -1
  250. package/dist/server/ui/components/ui/tags-input/TagsInputItemDelete.vue +1 -1
  251. package/dist/server/ui/lib/emulated-dark-mode.ts +146 -0
  252. package/dist/server/ui/main.css +25 -0
  253. package/dist/server/ui/pages/Home.vue +1 -1
  254. package/dist/server/ui/pages/Preview.vue +377 -186
  255. package/dist/server/ui/vite-env.d.ts +1 -0
  256. package/dist/tests/render/_helpers.d.ts +6 -0
  257. package/dist/tests/render/_helpers.d.ts.map +1 -0
  258. package/dist/tests/render/_helpers.js +16 -0
  259. package/dist/tests/render/_helpers.js.map +1 -0
  260. package/dist/transformers/addAttributes.d.ts +42 -0
  261. package/dist/transformers/addAttributes.d.ts.map +1 -0
  262. package/dist/transformers/{addAttributes.mjs → addAttributes.js} +40 -24
  263. package/dist/transformers/addAttributes.js.map +1 -0
  264. package/dist/transformers/attributeToStyle.d.ts +38 -0
  265. package/dist/transformers/attributeToStyle.d.ts.map +1 -0
  266. package/dist/transformers/attributeToStyle.js +94 -0
  267. package/dist/transformers/attributeToStyle.js.map +1 -0
  268. package/dist/transformers/base.d.ts +71 -0
  269. package/dist/transformers/base.d.ts.map +1 -0
  270. package/dist/transformers/{base.mjs → base.js} +65 -40
  271. package/dist/transformers/base.js.map +1 -0
  272. package/dist/transformers/columnWidth.d.ts +31 -0
  273. package/dist/transformers/columnWidth.d.ts.map +1 -0
  274. package/dist/transformers/columnWidth.js +527 -0
  275. package/dist/transformers/columnWidth.js.map +1 -0
  276. package/dist/transformers/entities.d.ts +37 -0
  277. package/dist/transformers/entities.d.ts.map +1 -0
  278. package/dist/transformers/entities.js +74 -0
  279. package/dist/transformers/entities.js.map +1 -0
  280. package/dist/transformers/filters/{defaults.d.mts → defaults.d.ts} +1 -1
  281. package/dist/transformers/filters/defaults.d.ts.map +1 -0
  282. package/dist/transformers/filters/{defaults.mjs → defaults.js} +2 -2
  283. package/dist/transformers/filters/defaults.js.map +1 -0
  284. package/dist/transformers/filters/index.d.ts +43 -0
  285. package/dist/transformers/filters/index.d.ts.map +1 -0
  286. package/dist/transformers/filters/index.js +89 -0
  287. package/dist/transformers/filters/index.js.map +1 -0
  288. package/dist/transformers/format.d.ts +22 -0
  289. package/dist/transformers/format.d.ts.map +1 -0
  290. package/dist/transformers/format.js +30 -0
  291. package/dist/transformers/format.js.map +1 -0
  292. package/dist/transformers/imgWidth.d.ts +20 -0
  293. package/dist/transformers/imgWidth.d.ts.map +1 -0
  294. package/dist/transformers/imgWidth.js +76 -0
  295. package/dist/transformers/imgWidth.js.map +1 -0
  296. package/dist/transformers/{index.d.mts → index.d.ts} +14 -12
  297. package/dist/transformers/index.d.ts.map +1 -0
  298. package/dist/transformers/index.js +163 -0
  299. package/dist/transformers/index.js.map +1 -0
  300. package/dist/transformers/inlineCss.d.ts +85 -0
  301. package/dist/transformers/inlineCss.d.ts.map +1 -0
  302. package/dist/transformers/inlineCss.js +112 -0
  303. package/dist/transformers/inlineCss.js.map +1 -0
  304. package/dist/transformers/inlineLink.d.ts +35 -0
  305. package/dist/transformers/inlineLink.d.ts.map +1 -0
  306. package/dist/transformers/{inlineLink.mjs → inlineLink.js} +35 -11
  307. package/dist/transformers/inlineLink.js.map +1 -0
  308. package/dist/transformers/minify.d.ts +21 -0
  309. package/dist/transformers/minify.d.ts.map +1 -0
  310. package/dist/transformers/minify.js +25 -0
  311. package/dist/transformers/minify.js.map +1 -0
  312. package/dist/transformers/minifyCodeInline.d.ts +29 -0
  313. package/dist/transformers/minifyCodeInline.d.ts.map +1 -0
  314. package/dist/transformers/minifyCodeInline.js +36 -0
  315. package/dist/transformers/minifyCodeInline.js.map +1 -0
  316. package/dist/transformers/msoPlaceholders.d.ts +33 -0
  317. package/dist/transformers/msoPlaceholders.d.ts.map +1 -0
  318. package/dist/transformers/msoPlaceholders.js +114 -0
  319. package/dist/transformers/msoPlaceholders.js.map +1 -0
  320. package/dist/transformers/purgeCss.d.ts +43 -0
  321. package/dist/transformers/purgeCss.d.ts.map +1 -0
  322. package/dist/transformers/purgeCss.js +207 -0
  323. package/dist/transformers/purgeCss.js.map +1 -0
  324. package/dist/transformers/removeAttributes.d.ts +54 -0
  325. package/dist/transformers/removeAttributes.d.ts.map +1 -0
  326. package/dist/transformers/removeAttributes.js +72 -0
  327. package/dist/transformers/removeAttributes.js.map +1 -0
  328. package/dist/transformers/{replaceStrings.d.mts → replaceStrings.d.ts} +2 -2
  329. package/dist/transformers/replaceStrings.d.ts.map +1 -0
  330. package/dist/transformers/{replaceStrings.mjs → replaceStrings.js} +2 -2
  331. package/dist/transformers/replaceStrings.js.map +1 -0
  332. package/dist/transformers/safeSelectors.d.ts +37 -0
  333. package/dist/transformers/safeSelectors.d.ts.map +1 -0
  334. package/dist/transformers/{safeClassNames.mjs → safeSelectors.js} +40 -10
  335. package/dist/transformers/safeSelectors.js.map +1 -0
  336. package/dist/transformers/shorthandCss.d.ts +47 -0
  337. package/dist/transformers/shorthandCss.d.ts.map +1 -0
  338. package/dist/transformers/shorthandCss.js +92 -0
  339. package/dist/transformers/shorthandCss.js.map +1 -0
  340. package/dist/transformers/sixHex.d.ts +25 -0
  341. package/dist/transformers/sixHex.d.ts.map +1 -0
  342. package/dist/transformers/sixHex.js +42 -0
  343. package/dist/transformers/sixHex.js.map +1 -0
  344. package/dist/transformers/tailwindComponent.d.ts +16 -0
  345. package/dist/transformers/tailwindComponent.d.ts.map +1 -0
  346. package/dist/transformers/tailwindComponent.js +101 -0
  347. package/dist/transformers/tailwindComponent.js.map +1 -0
  348. package/dist/transformers/{tailwindcss.d.mts → tailwindcss.d.ts} +2 -2
  349. package/dist/transformers/tailwindcss.d.ts.map +1 -0
  350. package/dist/transformers/{tailwindcss.mjs → tailwindcss.js} +33 -74
  351. package/dist/transformers/tailwindcss.js.map +1 -0
  352. package/dist/transformers/urlQuery.d.ts +36 -0
  353. package/dist/transformers/urlQuery.d.ts.map +1 -0
  354. package/dist/transformers/urlQuery.js +77 -0
  355. package/dist/transformers/urlQuery.js.map +1 -0
  356. package/dist/types/{config.d.mts → config.d.ts} +270 -40
  357. package/dist/types/config.d.ts.map +1 -0
  358. package/dist/types/config.js +1 -0
  359. package/dist/types/index.d.ts +2 -0
  360. package/dist/types/index.js +1 -0
  361. package/dist/utils/ast/index.d.ts +4 -0
  362. package/dist/utils/ast/index.js +4 -0
  363. package/dist/utils/ast/{parser.d.mts → parser.d.ts} +1 -1
  364. package/dist/utils/ast/parser.d.ts.map +1 -0
  365. package/dist/utils/ast/{parser.mjs → parser.js} +2 -3
  366. package/dist/utils/ast/parser.js.map +1 -0
  367. package/dist/utils/ast/{serializer.d.mts → serializer.d.ts} +1 -1
  368. package/dist/utils/ast/serializer.d.ts.map +1 -0
  369. package/dist/utils/ast/serializer.js +46 -0
  370. package/dist/utils/ast/serializer.js.map +1 -0
  371. package/dist/utils/ast/{walker.d.mts → walker.d.ts} +1 -1
  372. package/dist/utils/ast/walker.d.ts.map +1 -0
  373. package/dist/utils/ast/{walker.mjs → walker.js} +2 -2
  374. package/dist/utils/ast/walker.js.map +1 -0
  375. package/dist/utils/cloneConfig.d.ts +13 -0
  376. package/dist/utils/cloneConfig.d.ts.map +1 -0
  377. package/dist/utils/cloneConfig.js +21 -0
  378. package/dist/utils/cloneConfig.js.map +1 -0
  379. package/dist/utils/compileTailwindCss.d.ts +16 -0
  380. package/dist/utils/compileTailwindCss.d.ts.map +1 -0
  381. package/dist/utils/compileTailwindCss.js +55 -0
  382. package/dist/utils/compileTailwindCss.js.map +1 -0
  383. package/dist/utils/componentSources.d.ts +50 -0
  384. package/dist/utils/componentSources.d.ts.map +1 -0
  385. package/dist/utils/componentSources.js +50 -0
  386. package/dist/utils/componentSources.js.map +1 -0
  387. package/dist/utils/cssBox.d.ts +42 -0
  388. package/dist/utils/cssBox.d.ts.map +1 -0
  389. package/dist/utils/cssBox.js +151 -0
  390. package/dist/utils/cssBox.js.map +1 -0
  391. package/dist/utils/decodeStyleEntities.d.ts +15 -0
  392. package/dist/utils/decodeStyleEntities.d.ts.map +1 -0
  393. package/dist/utils/decodeStyleEntities.js +18 -0
  394. package/dist/utils/decodeStyleEntities.js.map +1 -0
  395. package/dist/utils/{detect.d.mts → detect.d.ts} +1 -1
  396. package/dist/utils/detect.d.ts.map +1 -0
  397. package/dist/utils/{detect.mjs → detect.js} +2 -3
  398. package/dist/utils/detect.js.map +1 -0
  399. package/dist/utils/output-markers.d.ts +29 -0
  400. package/dist/utils/output-markers.d.ts.map +1 -0
  401. package/dist/utils/output-markers.js +68 -0
  402. package/dist/utils/output-markers.js.map +1 -0
  403. package/dist/utils/{url.d.mts → url.d.ts} +1 -1
  404. package/dist/utils/url.d.ts.map +1 -0
  405. package/dist/utils/{url.mjs → url.js} +2 -3
  406. package/dist/utils/url.js.map +1 -0
  407. package/dist/utils/watchPaths.d.ts +11 -0
  408. package/dist/utils/watchPaths.d.ts.map +1 -0
  409. package/dist/utils/watchPaths.js +19 -0
  410. package/dist/utils/watchPaths.js.map +1 -0
  411. package/node_modules/@clack/core/CHANGELOG.md +44 -0
  412. package/node_modules/@clack/core/dist/index.d.mts +125 -5
  413. package/node_modules/@clack/core/dist/index.mjs +972 -11
  414. package/node_modules/@clack/core/package.json +6 -2
  415. package/node_modules/@clack/prompts/CHANGELOG.md +70 -0
  416. package/node_modules/@clack/prompts/README.md +129 -3
  417. package/node_modules/@clack/prompts/dist/index.d.mts +567 -33
  418. package/node_modules/@clack/prompts/dist/index.mjs +1378 -133
  419. package/node_modules/@clack/prompts/package.json +7 -4
  420. package/node_modules/fast-string-truncated-width/dist/index.js +36 -96
  421. package/node_modules/fast-string-truncated-width/dist/types.d.ts +0 -3
  422. package/node_modules/fast-string-truncated-width/dist/utils.d.ts +3 -3
  423. package/node_modules/fast-string-truncated-width/dist/utils.js +14 -9
  424. package/node_modules/fast-string-truncated-width/package.json +1 -1
  425. package/node_modules/fast-string-truncated-width/readme.md +2 -3
  426. package/node_modules/fast-string-width/package.json +2 -2
  427. package/node_modules/fast-string-width/readme.md +0 -3
  428. package/node_modules/fast-wrap-ansi/lib/main.js +4 -2
  429. package/node_modules/fast-wrap-ansi/package.json +11 -11
  430. package/node_modules/maizzle/README.md +24 -0
  431. package/node_modules/maizzle/dist/commands/make/component.mjs +1 -1
  432. package/node_modules/maizzle/dist/commands/make/config.mjs +8 -7
  433. package/node_modules/maizzle/dist/commands/make/layout.mjs +3 -3
  434. package/node_modules/maizzle/dist/commands/make/scaffold.mjs +1 -1
  435. package/node_modules/maizzle/dist/commands/make/stubs/Layout.vue +146 -0
  436. package/node_modules/maizzle/dist/commands/make/stubs/component.vue +2 -4
  437. package/node_modules/maizzle/dist/commands/make/stubs/config.ts +1 -5
  438. package/node_modules/maizzle/dist/commands/make/template.mjs +1 -1
  439. package/node_modules/maizzle/dist/commands/new.mjs +46 -135
  440. package/node_modules/maizzle/dist/index.d.mts +1 -0
  441. package/node_modules/maizzle/dist/index.mjs +30 -7
  442. package/node_modules/maizzle/package.json +5 -4
  443. package/node_modules/nypm/dist/cli.mjs +28 -5
  444. package/node_modules/nypm/dist/index.d.mts +0 -8
  445. package/node_modules/nypm/dist/index.mjs +27 -4
  446. package/node_modules/nypm/package.json +12 -12
  447. package/node_modules/tinyexec/README.md +9 -1
  448. package/node_modules/tinyexec/dist/main.d.mts +22 -7
  449. package/node_modules/tinyexec/dist/main.mjs +189 -491
  450. package/node_modules/tinyexec/package.json +14 -16
  451. package/package.json +38 -30
  452. package/dist/build.d.mts +0 -19
  453. package/dist/build.d.mts.map +0 -1
  454. package/dist/build.mjs +0 -140
  455. package/dist/build.mjs.map +0 -1
  456. package/dist/components/Divider.vue +0 -133
  457. package/dist/components/Image.vue +0 -70
  458. package/dist/components/Overlap.vue +0 -80
  459. package/dist/components/utils.d.mts +0 -5
  460. package/dist/components/utils.d.mts.map +0 -1
  461. package/dist/components/utils.mjs +0 -9
  462. package/dist/components/utils.mjs.map +0 -1
  463. package/dist/composables/defineConfig.d.mts +0 -14
  464. package/dist/composables/defineConfig.d.mts.map +0 -1
  465. package/dist/composables/defineConfig.mjs.map +0 -1
  466. package/dist/composables/renderContext.d.mts +0 -24
  467. package/dist/composables/renderContext.d.mts.map +0 -1
  468. package/dist/composables/renderContext.mjs +0 -6
  469. package/dist/composables/renderContext.mjs.map +0 -1
  470. package/dist/composables/useConfig.d.mts +0 -9
  471. package/dist/composables/useConfig.d.mts.map +0 -1
  472. package/dist/composables/useConfig.mjs +0 -13
  473. package/dist/composables/useConfig.mjs.map +0 -1
  474. package/dist/composables/useDoctype.d.mts.map +0 -1
  475. package/dist/composables/useDoctype.mjs.map +0 -1
  476. package/dist/composables/useEvent.d.mts.map +0 -1
  477. package/dist/composables/useEvent.mjs.map +0 -1
  478. package/dist/composables/usePlaintext.d.mts.map +0 -1
  479. package/dist/composables/usePlaintext.mjs.map +0 -1
  480. package/dist/composables/usePreviewText.d.mts +0 -24
  481. package/dist/composables/usePreviewText.d.mts.map +0 -1
  482. package/dist/composables/usePreviewText.mjs +0 -29
  483. package/dist/composables/usePreviewText.mjs.map +0 -1
  484. package/dist/config/defaults.d.mts.map +0 -1
  485. package/dist/config/defaults.mjs.map +0 -1
  486. package/dist/config/index.d.mts +0 -15
  487. package/dist/config/index.d.mts.map +0 -1
  488. package/dist/config/index.mjs.map +0 -1
  489. package/dist/events/index.d.mts.map +0 -1
  490. package/dist/events/index.mjs.map +0 -1
  491. package/dist/index.d.mts +0 -30
  492. package/dist/index.mjs +0 -30
  493. package/dist/plaintext.d.mts.map +0 -1
  494. package/dist/plaintext.mjs.map +0 -1
  495. package/dist/plugin.d.mts.map +0 -1
  496. package/dist/plugin.mjs.map +0 -1
  497. package/dist/plugins/postcss/mergeMediaQueries.d.mts.map +0 -1
  498. package/dist/plugins/postcss/mergeMediaQueries.mjs.map +0 -1
  499. package/dist/plugins/postcss/pruneVars.d.mts.map +0 -1
  500. package/dist/plugins/postcss/pruneVars.mjs.map +0 -1
  501. package/dist/plugins/postcss/removeDeclarations.d.mts.map +0 -1
  502. package/dist/plugins/postcss/removeDeclarations.mjs.map +0 -1
  503. package/dist/plugins/postcss/tailwindCleanup.d.mts.map +0 -1
  504. package/dist/plugins/postcss/tailwindCleanup.mjs.map +0 -1
  505. package/dist/render/createRenderer.d.mts.map +0 -1
  506. package/dist/render/createRenderer.mjs +0 -279
  507. package/dist/render/createRenderer.mjs.map +0 -1
  508. package/dist/render/index.d.mts +0 -26
  509. package/dist/render/index.d.mts.map +0 -1
  510. package/dist/render/index.mjs +0 -45
  511. package/dist/render/index.mjs.map +0 -1
  512. package/dist/serve.d.mts.map +0 -1
  513. package/dist/serve.mjs.map +0 -1
  514. package/dist/server/compatibility.d.mts +0 -5
  515. package/dist/server/compatibility.d.mts.map +0 -1
  516. package/dist/server/compatibility.mjs +0 -97
  517. package/dist/server/compatibility.mjs.map +0 -1
  518. package/dist/server/email.d.mts.map +0 -1
  519. package/dist/server/email.mjs.map +0 -1
  520. package/dist/server/linter.d.mts +0 -5
  521. package/dist/server/linter.d.mts.map +0 -1
  522. package/dist/server/linter.mjs +0 -189
  523. package/dist/server/linter.mjs.map +0 -1
  524. package/dist/transformers/addAttributes.d.mts +0 -32
  525. package/dist/transformers/addAttributes.d.mts.map +0 -1
  526. package/dist/transformers/addAttributes.mjs.map +0 -1
  527. package/dist/transformers/attributeToStyle.d.mts +0 -25
  528. package/dist/transformers/attributeToStyle.d.mts.map +0 -1
  529. package/dist/transformers/attributeToStyle.mjs +0 -80
  530. package/dist/transformers/attributeToStyle.mjs.map +0 -1
  531. package/dist/transformers/base.d.mts +0 -8
  532. package/dist/transformers/base.d.mts.map +0 -1
  533. package/dist/transformers/base.mjs.map +0 -1
  534. package/dist/transformers/entities.d.mts +0 -8
  535. package/dist/transformers/entities.d.mts.map +0 -1
  536. package/dist/transformers/entities.mjs +0 -41
  537. package/dist/transformers/entities.mjs.map +0 -1
  538. package/dist/transformers/filters/defaults.d.mts.map +0 -1
  539. package/dist/transformers/filters/defaults.mjs.map +0 -1
  540. package/dist/transformers/filters/index.d.mts +0 -22
  541. package/dist/transformers/filters/index.d.mts.map +0 -1
  542. package/dist/transformers/filters/index.mjs +0 -67
  543. package/dist/transformers/filters/index.mjs.map +0 -1
  544. package/dist/transformers/format.d.mts +0 -15
  545. package/dist/transformers/format.d.mts.map +0 -1
  546. package/dist/transformers/format.mjs +0 -26
  547. package/dist/transformers/format.mjs.map +0 -1
  548. package/dist/transformers/index.d.mts.map +0 -1
  549. package/dist/transformers/index.mjs +0 -78
  550. package/dist/transformers/index.mjs.map +0 -1
  551. package/dist/transformers/inlineCSS.d.mts +0 -17
  552. package/dist/transformers/inlineCSS.d.mts.map +0 -1
  553. package/dist/transformers/inlineCSS.mjs +0 -70
  554. package/dist/transformers/inlineCSS.mjs.map +0 -1
  555. package/dist/transformers/inlineLink.d.mts +0 -14
  556. package/dist/transformers/inlineLink.d.mts.map +0 -1
  557. package/dist/transformers/inlineLink.mjs.map +0 -1
  558. package/dist/transformers/minify.d.mts +0 -17
  559. package/dist/transformers/minify.d.mts.map +0 -1
  560. package/dist/transformers/minify.mjs +0 -24
  561. package/dist/transformers/minify.mjs.map +0 -1
  562. package/dist/transformers/purgeCSS.d.mts +0 -23
  563. package/dist/transformers/purgeCSS.d.mts.map +0 -1
  564. package/dist/transformers/purgeCSS.mjs +0 -132
  565. package/dist/transformers/purgeCSS.mjs.map +0 -1
  566. package/dist/transformers/removeAttributes.d.mts +0 -31
  567. package/dist/transformers/removeAttributes.d.mts.map +0 -1
  568. package/dist/transformers/removeAttributes.mjs +0 -63
  569. package/dist/transformers/removeAttributes.mjs.map +0 -1
  570. package/dist/transformers/replaceStrings.d.mts.map +0 -1
  571. package/dist/transformers/replaceStrings.mjs.map +0 -1
  572. package/dist/transformers/safeClassNames.d.mts +0 -22
  573. package/dist/transformers/safeClassNames.d.mts.map +0 -1
  574. package/dist/transformers/safeClassNames.mjs.map +0 -1
  575. package/dist/transformers/shorthandCSS.d.mts +0 -24
  576. package/dist/transformers/shorthandCSS.d.mts.map +0 -1
  577. package/dist/transformers/shorthandCSS.mjs +0 -48
  578. package/dist/transformers/shorthandCSS.mjs.map +0 -1
  579. package/dist/transformers/tailwindcss.d.mts.map +0 -1
  580. package/dist/transformers/tailwindcss.mjs.map +0 -1
  581. package/dist/transformers/urlQuery.d.mts +0 -24
  582. package/dist/transformers/urlQuery.d.mts.map +0 -1
  583. package/dist/transformers/urlQuery.mjs +0 -65
  584. package/dist/transformers/urlQuery.mjs.map +0 -1
  585. package/dist/types/config.d.mts.map +0 -1
  586. package/dist/types/config.mjs +0 -1
  587. package/dist/types/index.d.mts +0 -2
  588. package/dist/types/index.mjs +0 -1
  589. package/dist/utils/ast/index.d.mts +0 -4
  590. package/dist/utils/ast/index.mjs +0 -5
  591. package/dist/utils/ast/parser.d.mts.map +0 -1
  592. package/dist/utils/ast/parser.mjs.map +0 -1
  593. package/dist/utils/ast/serializer.d.mts.map +0 -1
  594. package/dist/utils/ast/serializer.mjs +0 -37
  595. package/dist/utils/ast/serializer.mjs.map +0 -1
  596. package/dist/utils/ast/walker.d.mts.map +0 -1
  597. package/dist/utils/ast/walker.mjs.map +0 -1
  598. package/dist/utils/detect.d.mts.map +0 -1
  599. package/dist/utils/detect.mjs.map +0 -1
  600. package/dist/utils/url.d.mts.map +0 -1
  601. package/dist/utils/url.mjs.map +0 -1
  602. package/node_modules/@clack/core/dist/index.mjs.map +0 -1
  603. package/node_modules/@clack/prompts/dist/index.mjs.map +0 -1
  604. package/node_modules/fast-wrap-ansi/lib/main.js.map +0 -1
  605. package/node_modules/maizzle/dist/commands/make/stubs/layout.vue +0 -39
  606. package/node_modules/tinyexec/dist/LICENSES.txt +0 -83
@@ -1,8 +1,8 @@
1
1
  <script setup lang="ts">
2
2
  import { ref, computed, onMounted, onUnmounted, watch, watchEffect } from 'vue'
3
3
  import { RouterLink, RouterView, useRoute, useRouter } from 'vue-router'
4
- import { Monitor, CodeXml, Smartphone, ChevronDown, ArrowUp, ArrowDown, CornerDownLeft, Check, Search, Camera, FileCode, FileText, Code, BookText, MailQuestion } from 'lucide-vue-next'
5
- import { toBlob } from 'html-to-image'
4
+ import { Monitor, CodeXml, Smartphone, ChevronDown, ArrowUp, ArrowDown, CornerDownLeft, Check, Search, FileCode, FileText, Code, BookText, MailQuestion, Moon, Sun } from '@lucide/vue'
5
+ import SidebarClose from '@/components/SidebarClose.vue'
6
6
  import logoUrl from '@/logo.svg'
7
7
  import logoGradientUrl from '@/logo-gradient.svg'
8
8
  import { Kbd } from '@/components/ui/kbd'
@@ -24,6 +24,7 @@ import {
24
24
  CommandList,
25
25
  CommandShortcut,
26
26
  } from '@/components/ui/command'
27
+ import { useFilter } from 'reka-ui'
27
28
  import {
28
29
  Sidebar,
29
30
  SidebarContent,
@@ -51,7 +52,13 @@ const route = useRoute()
51
52
 
52
53
  watchEffect(() => {
53
54
  const slug = route.path === '/' ? '' : route.path.split('/').pop()
54
- document.title = slug ? `Maizzle Dev - ${slug}.vue` : 'Maizzle Dev'
55
+ if (!slug) {
56
+ document.title = 'Maizzle Dev'
57
+ return
58
+ }
59
+ const tpl = templates.value.find(t => t.href === route.path)
60
+ const ext = tpl?.path.endsWith('.md') ? '.md' : '.vue'
61
+ document.title = `Maizzle Dev - ${slug}${ext}`
55
62
  })
56
63
 
57
64
  const templates = ref<Template[]>([])
@@ -77,8 +84,13 @@ const devicePresets: DevicePreset[] = [
77
84
 
78
85
  const selectedDevice = ref<DevicePreset | null>(null)
79
86
  const deviceMenuOpen = ref(false)
87
+ const darkMode = ref(false)
80
88
  const panelWidth = ref(0)
81
89
  const panelHeight = ref(0)
90
+ const iframeWidth = ref<number | null>(null)
91
+ const iframeHeight = ref<number | null>(null)
92
+ const maxIframeWidth = ref(0)
93
+ const maxIframeHeight = ref(0)
82
94
  const isDragging = ref(false)
83
95
  const isFullSize = ref(true)
84
96
  const resetKey = ref(0)
@@ -88,6 +100,31 @@ function selectDevice(device: DevicePreset) {
88
100
  viewMode.value = 'preview'
89
101
  }
90
102
 
103
+ /**
104
+ * Writable proxies for the toolbar's size-indicator inputs. Display falls back
105
+ * to the measured panel size when the iframe dimension is null (the axis
106
+ * hasn't been explicitly set yet — e.g. user only dragged one axis).
107
+ * Setter rejects non-finite/non-positive values and clamps to
108
+ * [200, maxIframeWidth] / [100, maxIframeHeight] so users
109
+ * can't push the drag handles off-screen via the input.
110
+ */
111
+ const widthInput = computed<number>({
112
+ get: () => Math.round(iframeWidth.value ?? panelWidth.value),
113
+ set: (v) => {
114
+ if (typeof v !== 'number' || !Number.isFinite(v) || v <= 0) return
115
+ const max = maxIframeWidth.value || v
116
+ iframeWidth.value = Math.max(200, Math.min(max, Math.round(v)))
117
+ },
118
+ })
119
+ const heightInput = computed<number>({
120
+ get: () => Math.round(iframeHeight.value ?? panelHeight.value),
121
+ set: (v) => {
122
+ if (typeof v !== 'number' || !Number.isFinite(v) || v <= 0) return
123
+ const max = maxIframeHeight.value || v
124
+ iframeHeight.value = Math.max(100, Math.min(max, Math.round(v)))
125
+ },
126
+ })
127
+
91
128
  watch(sidebarOpen, (open) => {
92
129
  localStorage.setItem('maizzle:sidebar', open ? 'open' : 'closed')
93
130
  })
@@ -136,32 +173,6 @@ watch(commandOpen, (open) => {
136
173
  if (!open) commandSearch.value = ''
137
174
  })
138
175
 
139
- const screenshotting = ref(false)
140
-
141
- async function copyScreenshot() {
142
- commandOpen.value = false
143
-
144
- const iframe = document.querySelector('iframe') as HTMLIFrameElement | null
145
- const doc = iframe?.contentDocument
146
- if (!doc?.body) return
147
-
148
- screenshotting.value = true
149
-
150
- try {
151
- const blob = await toBlob(doc.body, {
152
- width: doc.body.scrollWidth,
153
- height: doc.body.scrollHeight,
154
- })
155
-
156
- if (blob) {
157
- await navigator.clipboard.write([
158
- new ClipboardItem({ 'image/png': blob })
159
- ])
160
- }
161
- } finally {
162
- screenshotting.value = false
163
- }
164
- }
165
176
 
166
177
  async function copyHtml() {
167
178
  commandOpen.value = false
@@ -203,6 +214,19 @@ const commandGrouped = computed(() => {
203
214
  return groups
204
215
  })
205
216
 
217
+ const { contains } = useFilter({ sensitivity: 'base' })
218
+
219
+ const filteredTemplatesCount = computed(() => {
220
+ const tokens = commandSearch.value.split(/\s+/).filter(Boolean)
221
+ if (tokens.length === 0) return 0
222
+ let count = 0
223
+ for (const t of templates.value) {
224
+ const haystack = `${getFileName(t.path)} ${t.path.split('/').join(' ')}`
225
+ if (tokens.every(token => contains(haystack, token))) count++
226
+ }
227
+ return count
228
+ })
229
+
206
230
 
207
231
  function getFileName(path: string) {
208
232
  return path.split('/').pop() || path
@@ -225,12 +249,6 @@ function onKeydown(e: KeyboardEvent) {
225
249
  return
226
250
  }
227
251
 
228
- if ((e.metaKey || e.ctrlKey) && e.key === 'b') {
229
- e.preventDefault()
230
- sidebarOpen.value = !sidebarOpen.value
231
- return
232
- }
233
-
234
252
  if (e.key === '/' && !isInputFocused()) {
235
253
  e.preventDefault()
236
254
  commandOpen.value = true
@@ -240,10 +258,6 @@ function onKeydown(e: KeyboardEvent) {
240
258
  // Copy shortcuts (Cmd on Mac, Alt on Win/Linux)
241
259
  if ((isMac ? e.metaKey : e.altKey) && !e.shiftKey && isPreviewRoute.value) {
242
260
  switch (e.key.toLowerCase()) {
243
- case 's':
244
- e.preventDefault()
245
- copyScreenshot()
246
- return
247
261
  case 'c':
248
262
  e.preventDefault()
249
263
  copyHtml()
@@ -271,6 +285,11 @@ function onWindowBlur() {
271
285
  deviceMenuOpen.value = false
272
286
  }
273
287
 
288
+ function toggleDarkMode() {
289
+ commandOpen.value = false
290
+ darkMode.value = !darkMode.value
291
+ }
292
+
274
293
  onMounted(() => {
275
294
  document.addEventListener('keydown', onKeydown)
276
295
  window.addEventListener('blur', onWindowBlur)
@@ -289,13 +308,14 @@ onUnmounted(() => {
289
308
  <img :src="logoUrl" alt="Maizzle" class="h-4 dark:hidden">
290
309
  <img :src="logoGradientUrl" alt="Maizzle" class="hidden h-4 dark:block">
291
310
  </RouterLink>
292
- <button class="inline-flex items-center gap-1.5 text-gray-400 hover:text-gray-600 dark:hover:text-gray-300" @click="commandOpen = true">
293
- <Search class="size-3.5" />
311
+ <button class="hidden md:inline-flex items-center gap-1.5 text-gray-400 hover:text-gray-600 dark:hover:text-gray-300" @click="commandOpen = true">
312
+ <Search class="size-3.5 text-gray-500 dark:text-gray-300" :stroke-width="1" />
294
313
  <kbd class="flex items-center gap-0.5 text-[10px] font-sans">
295
314
  <span>{{ modKey }}</span>
296
315
  <span class="text-gray-300 dark:text-gray-600">K</span>
297
316
  </kbd>
298
317
  </button>
318
+ <SidebarClose />
299
319
  </SidebarHeader>
300
320
 
301
321
  <SidebarContent>
@@ -319,10 +339,7 @@ onUnmounted(() => {
319
339
  :is-active="isActive(t.href)"
320
340
  >
321
341
  <RouterLink :to="t.href" class="truncate">
322
- <svg class="size-3 shrink-0 opacity-50" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round">
323
- <path d="M15 2H6a2 2 0 0 0-2 2v16a2 2 0 0 0 2 2h12a2 2 0 0 0 2-2V7Z" />
324
- <path d="M14 2v4a2 2 0 0 0 2 2h4" />
325
- </svg>
342
+ <span class="mz-tpl-icon size-4 shrink-0 opacity-70" :class="t.path.endsWith('.md') ? 'mz-tpl-icon-md' : 'mz-tpl-icon-vue'" />
326
343
  <span class="truncate">{{ t.name }}</span>
327
344
  </RouterLink>
328
345
  </SidebarMenuButton>
@@ -361,9 +378,26 @@ onUnmounted(() => {
361
378
  v-if="isPreviewRoute && (!isFullSize || selectedDevice) && panelWidth"
362
379
  class="hidden min-[430px]:inline text-xs font-medium tabular-nums text-gray-500 dark:text-gray-400 select-none"
363
380
  >
364
- {{ panelWidth }} &times; {{ panelHeight }}
381
+ <input
382
+ v-model.number="widthInput"
383
+ type="number"
384
+ min="200"
385
+ :max="maxIframeWidth || undefined"
386
+ aria-label="Preview width"
387
+ class="bg-transparent border-0 outline-none p-0 m-0 text-inherit font-inherit text-center tabular-nums w-[4.5ch] focus:outline-none focus:ring-0 [appearance:textfield] [&::-webkit-inner-spin-button]:appearance-none [&::-webkit-outer-spin-button]:appearance-none"
388
+ >
389
+ <button class="hover:text-gray-700 dark:hover:text-gray-300" @click="selectedDevice = null; isFullSize = true; viewMode = 'preview'; resetKey++">&times;</button>
390
+ <input
391
+ v-model.number="heightInput"
392
+ type="number"
393
+ min="100"
394
+ :max="maxIframeHeight || undefined"
395
+ aria-label="Preview height"
396
+ class="bg-transparent border-0 outline-none p-0 m-0 text-inherit font-inherit text-center tabular-nums w-[4.5ch] focus:outline-none focus:ring-0 [appearance:textfield] [&::-webkit-inner-spin-button]:appearance-none [&::-webkit-outer-spin-button]:appearance-none"
397
+ >
365
398
  </span>
366
- <DropdownMenu v-if="isPreviewRoute" v-model:open="deviceMenuOpen" :modal="false">
399
+ <div v-if="isPreviewRoute" class="flex items-center gap-1">
400
+ <DropdownMenu v-model:open="deviceMenuOpen" :modal="false">
367
401
  <DropdownMenuTrigger as-child>
368
402
  <Button variant="ghost" size="sm" class="hidden min-[430px]:inline-flex gap-1.5 shadow-none border-none hover:bg-transparent">
369
403
  <Smartphone class="size-4 dark:text-gray-400" :stroke-width="1" />
@@ -387,38 +421,43 @@ onUnmounted(() => {
387
421
  <span class="ml-auto text-[11px] text-gray-400 dark:text-gray-500 tabular-nums tracking-tight">{{ device.width }}&times;{{ device.height }}</span>
388
422
  </DropdownMenuItem>
389
423
  </DropdownMenuContent>
390
- </DropdownMenu>
424
+ </DropdownMenu>
425
+ </div>
391
426
  </div>
392
427
  </header>
393
428
 
394
429
  <!-- Main content -->
395
430
  <div class="flex-1 overflow-hidden">
396
431
  <RouterView v-slot="{ Component }">
397
- <component :is="Component" v-model:view-mode="viewMode" :device="selectedDevice" :reset-key="resetKey" :templates="templates" v-model:panel-width="panelWidth" v-model:panel-height="panelHeight" v-model:is-dragging="isDragging" v-model:is-full-size="isFullSize" @clear-device="selectedDevice = null; isFullSize = false" />
432
+ <component :is="Component" v-model:view-mode="viewMode" :device="selectedDevice" :reset-key="resetKey" :templates="templates" v-model:panel-width="panelWidth" v-model:panel-height="panelHeight" v-model:iframe-width="iframeWidth" v-model:iframe-height="iframeHeight" v-model:max-iframe-width="maxIframeWidth" v-model:max-iframe-height="maxIframeHeight" v-model:is-dragging="isDragging" v-model:is-full-size="isFullSize" v-model:dark-mode="darkMode" @clear-device="selectedDevice = null; isFullSize = false" />
398
433
  </RouterView>
399
434
  </div>
400
435
  </SidebarInset>
401
436
 
402
437
  <CommandDialog v-model:open="commandOpen" title="Command palette" description="Run commands or search emails">
403
438
  <CommandInput v-model="commandSearch" placeholder="Type a command or find an email..." />
404
- <CommandList>
439
+ <CommandList class="max-h-[400px]">
405
440
  <CommandEmpty>No results found.</CommandEmpty>
406
441
 
407
- <!-- Copy to clipboard commands -->
408
- <CommandGroup v-if="isPreviewRoute" heading="Copy to clipboard">
442
+ <!-- Preview commands -->
443
+ <CommandGroup v-if="isPreviewRoute && viewMode === 'preview'" heading="Preview">
409
444
  <CommandItem
410
- value="Screenshot"
411
- @select="copyScreenshot"
445
+ :value="darkMode ? 'Disable dark mode' : 'Emulate dark mode'"
446
+ @select="toggleDarkMode"
412
447
  >
413
- <Camera class="size-3 shrink-0 opacity-50" />
414
- <span>Screenshot</span>
415
- <CommandShortcut>{{ isMac ? '' : 'ALT+' }}S</CommandShortcut>
448
+ <Sun v-if="darkMode" class="size-3 shrink-0 opacity-50" />
449
+ <Moon v-else class="size-3 shrink-0 opacity-50" />
450
+ <span>{{ darkMode ? 'Disable dark mode' : 'Emulate dark mode' }}</span>
416
451
  </CommandItem>
452
+ </CommandGroup>
453
+
454
+ <!-- Copy to clipboard commands -->
455
+ <CommandGroup v-if="isPreviewRoute" heading="Copy to clipboard">
417
456
  <CommandItem
418
457
  value="HTML"
419
458
  @select="copyHtml"
420
459
  >
421
- <FileCode class="size-3 shrink-0 opacity-50" />
460
+ <FileCode class="size-3 shrink-0 opacity-70" :stroke-width="1" />
422
461
  <span>HTML</span>
423
462
  <CommandShortcut>{{ isMac ? '⌘' : 'ALT+' }}C</CommandShortcut>
424
463
  </CommandItem>
@@ -426,7 +465,7 @@ onUnmounted(() => {
426
465
  value="Plaintext"
427
466
  @select="copyPlaintext"
428
467
  >
429
- <FileText class="size-3 shrink-0 opacity-50" />
468
+ <FileText class="size-3 shrink-0 opacity-70" :stroke-width="1" />
430
469
  <span>Plaintext</span>
431
470
  <CommandShortcut>{{ isMac ? '⌘' : 'ALT+' }}P</CommandShortcut>
432
471
  </CommandItem>
@@ -434,7 +473,7 @@ onUnmounted(() => {
434
473
  value="Vue source"
435
474
  @select="copySource"
436
475
  >
437
- <Code class="size-3 shrink-0 opacity-50" />
476
+ <Code class="size-3 shrink-0 opacity-70" :stroke-width="1" />
438
477
  <span>Vue source</span>
439
478
  <CommandShortcut>{{ isMac ? '⌘' : 'ALT+' }}U</CommandShortcut>
440
479
  </CommandItem>
@@ -446,14 +485,14 @@ onUnmounted(() => {
446
485
  value="Documentation"
447
486
  @select="openExternal('https://maizzle.com')"
448
487
  >
449
- <BookText class="size-3 shrink-0 opacity-50" />
488
+ <BookText class="size-3 shrink-0 opacity-70" :stroke-width="1" />
450
489
  <span>Documentation</span>
451
490
  </CommandItem>
452
491
  <CommandItem
453
492
  value="Can I Email"
454
493
  @select="openExternal('https://www.caniemail.com')"
455
494
  >
456
- <MailQuestion class="size-3 shrink-0 opacity-50" />
495
+ <MailQuestion class="size-3 shrink-0 opacity-70" :stroke-width="1" />
457
496
  <span>Can I Email</span>
458
497
  </CommandItem>
459
498
  </CommandGroup>
@@ -467,11 +506,9 @@ onUnmounted(() => {
467
506
  :value="t.path"
468
507
  @select="onCommandSelect(t.href)"
469
508
  >
470
- <svg class="size-3 shrink-0 opacity-50" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round">
471
- <path d="M15 2H6a2 2 0 0 0-2 2v16a2 2 0 0 0 2 2h12a2 2 0 0 0 2-2V7Z" />
472
- <path d="M14 2v4a2 2 0 0 0 2 2h4" />
473
- </svg>
509
+ <span class="mz-tpl-icon size-3 shrink-0 opacity-70" :class="t.path.endsWith('.md') ? 'mz-tpl-icon-md' : 'mz-tpl-icon-vue'" />
474
510
  <span>{{ getFileName(t.path) }}</span>
511
+ <span class="sr-only">{{ ' ' + t.path.split('/').join(' ') }}</span>
475
512
  </CommandItem>
476
513
  </CommandGroup>
477
514
  </template>
@@ -490,6 +527,9 @@ onUnmounted(() => {
490
527
  <Kbd>Esc</Kbd>
491
528
  Close
492
529
  </span>
530
+ <span v-if="commandSearch" class="ml-auto">
531
+ {{ filteredTemplatesCount }} {{ filteredTemplatesCount === 1 ? 'result' : 'results' }}
532
+ </span>
493
533
  </div>
494
534
  </CommandDialog>
495
535
  </SidebarProvider>
@@ -0,0 +1,12 @@
1
+ <script setup lang="ts">
2
+ import { PanelRightOpen } from '@lucide/vue'
3
+ import { useSidebar } from '@/components/ui/sidebar'
4
+
5
+ const { setOpenMobile } = useSidebar()
6
+ </script>
7
+
8
+ <template>
9
+ <button class="md:hidden text-gray-400 hover:text-gray-600 dark:hover:text-gray-300" @click="setOpenMobile(false)">
10
+ <PanelRightOpen class="size-4" :stroke-width="1" />
11
+ </button>
12
+ </template>
@@ -2,7 +2,7 @@
2
2
  import type { CheckboxRootEmits, CheckboxRootProps } from "reka-ui"
3
3
  import type { HTMLAttributes } from "vue"
4
4
  import { reactiveOmit } from "@vueuse/core"
5
- import { Check } from "lucide-vue-next"
5
+ import { Check } from "@lucide/vue"
6
6
  import { CheckboxIndicator, CheckboxRoot, useForwardPropsEmits } from "reka-ui"
7
7
  import { cn } from "@/lib/utils"
8
8
 
@@ -44,9 +44,12 @@ function filterItems() {
44
44
  filterState.filtered.groups = new Set()
45
45
  let itemCount = 0
46
46
 
47
+ // Tokenize the search by whitespace so segments match in any order
48
+ const tokens = filterState.search.split(/\s+/).filter(Boolean)
49
+
47
50
  // Check which items should be included
48
51
  for (const [id, value] of allItems.value) {
49
- const score = contains(value, filterState.search)
52
+ const score = tokens.every(token => contains(value, token))
50
53
  filterState.filtered.items.set(id, score ? 1 : 0)
51
54
  if (score)
52
55
  itemCount++
@@ -80,6 +83,7 @@ provideCommandContext({
80
83
  <ListboxRoot
81
84
  data-slot="command"
82
85
  v-bind="forwarded"
86
+ highlight-on-hover
83
87
  :class="cn('bg-popover text-popover-foreground flex h-full w-full flex-col overflow-hidden rounded-md', props.class)"
84
88
  >
85
89
  <slot />
@@ -3,7 +3,7 @@ import type { ListboxFilterProps } from "reka-ui"
3
3
  import type { HTMLAttributes } from "vue"
4
4
  import { watch } from "vue"
5
5
  import { reactiveOmit } from "@vueuse/core"
6
- import { Search } from "lucide-vue-next"
6
+ import { Search } from "@lucide/vue"
7
7
  import { ListboxFilter, useForwardProps } from "reka-ui"
8
8
  import { cn } from "@/lib/utils"
9
9
  import { useCommand } from "."
@@ -45,7 +45,7 @@ watch(() => filterState.search, (val) => {
45
45
  data-slot="command-input-wrapper"
46
46
  class="flex h-9 items-center gap-2 border-b px-3"
47
47
  >
48
- <Search class="size-4 shrink-0 opacity-50" />
48
+ <Search class="size-4 shrink-0 opacity-70" :stroke-width="1" />
49
49
  <ListboxFilter
50
50
  v-bind="{ ...forwardedProps, ...$attrs }"
51
51
  v-model="filterState.search"
@@ -2,7 +2,7 @@
2
2
  import type { DialogContentEmits, DialogContentProps } from "reka-ui"
3
3
  import type { HTMLAttributes } from "vue"
4
4
  import { reactiveOmit } from "@vueuse/core"
5
- import { X } from "lucide-vue-next"
5
+ import { X } from "@lucide/vue"
6
6
  import {
7
7
  DialogClose,
8
8
  DialogContent,
@@ -2,7 +2,7 @@
2
2
  import type { DialogContentEmits, DialogContentProps } from "reka-ui"
3
3
  import type { HTMLAttributes } from "vue"
4
4
  import { reactiveOmit } from "@vueuse/core"
5
- import { X } from "lucide-vue-next"
5
+ import { X } from "@lucide/vue"
6
6
  import {
7
7
  DialogClose,
8
8
  DialogContent,
@@ -2,7 +2,7 @@
2
2
  import type { DropdownMenuCheckboxItemEmits, DropdownMenuCheckboxItemProps } from "reka-ui"
3
3
  import type { HTMLAttributes } from "vue"
4
4
  import { reactiveOmit } from "@vueuse/core"
5
- import { Check } from "lucide-vue-next"
5
+ import { Check } from "@lucide/vue"
6
6
  import {
7
7
  DropdownMenuCheckboxItem,
8
8
  DropdownMenuItemIndicator,
@@ -2,7 +2,7 @@
2
2
  import type { DropdownMenuRadioItemEmits, DropdownMenuRadioItemProps } from "reka-ui"
3
3
  import type { HTMLAttributes } from "vue"
4
4
  import { reactiveOmit } from "@vueuse/core"
5
- import { Circle } from "lucide-vue-next"
5
+ import { Circle } from "@lucide/vue"
6
6
  import {
7
7
  DropdownMenuItemIndicator,
8
8
  DropdownMenuRadioItem,
@@ -2,7 +2,7 @@
2
2
  import type { DropdownMenuSubTriggerProps } from "reka-ui"
3
3
  import type { HTMLAttributes } from "vue"
4
4
  import { reactiveOmit } from "@vueuse/core"
5
- import { ChevronRight } from "lucide-vue-next"
5
+ import { ChevronRight } from "@lucide/vue"
6
6
  import {
7
7
  DropdownMenuSubTrigger,
8
8
  useForwardProps,
@@ -24,7 +24,7 @@ const modelValue = useVModel(props, "modelValue", emits, {
24
24
  v-model="modelValue"
25
25
  data-slot="input"
26
26
  :class="cn(
27
- 'file:text-foreground placeholder:text-muted-foreground selection:bg-primary selection:text-primary-foreground dark:bg-input/30 border-input h-9 w-full min-w-0 rounded-md border bg-transparent px-3 py-1 text-base shadow-xs transition-[color,box-shadow] outline-none file:inline-flex file:h-7 file:border-0 file:bg-transparent file:text-sm file:font-medium disabled:pointer-events-none disabled:cursor-not-allowed disabled:opacity-50 md:text-sm',
27
+ 'file:text-foreground placeholder:text-gray-400 dark:placeholder:text-gray-500 selection:bg-primary selection:text-primary-foreground dark:bg-input/30 border-input h-9 w-full min-w-0 rounded-md border bg-transparent px-3 py-1 text-base shadow-xs transition-[color,box-shadow] outline-none file:inline-flex file:h-7 file:border-0 file:bg-transparent file:text-sm file:font-medium disabled:pointer-events-none disabled:cursor-not-allowed disabled:opacity-50 md:text-sm',
28
28
  'focus-visible:border-ring focus-visible:ring-ring/50 focus-visible:ring-[3px]',
29
29
  'aria-invalid:ring-destructive/20 dark:aria-invalid:ring-destructive/40 aria-invalid:border-destructive',
30
30
  props.class,
@@ -2,7 +2,7 @@
2
2
  import type { DialogContentEmits, DialogContentProps } from "reka-ui"
3
3
  import type { HTMLAttributes } from "vue"
4
4
  import { reactiveOmit } from "@vueuse/core"
5
- import { X } from "lucide-vue-next"
5
+ import { X } from "@lucide/vue"
6
6
  import {
7
7
  DialogClose,
8
8
  DialogContent,
@@ -1,6 +1,6 @@
1
1
  <script setup lang="ts">
2
2
  import type { HTMLAttributes } from "vue"
3
- import { PanelRightClose, PanelRightOpen } from "lucide-vue-next"
3
+ import { PanelRightClose, PanelRightOpen } from "@lucide/vue"
4
4
  import { cn } from "@/lib/utils"
5
5
  import { Button } from '@/components/ui/button'
6
6
  import { useSidebar } from "./utils"
@@ -21,7 +21,7 @@ const { isMobile, open, toggleSidebar } = useSidebar()
21
21
  :class="cn('h-7 w-7 hover:bg-transparent', props.class)"
22
22
  @click="toggleSidebar"
23
23
  >
24
- <svg v-if="isMobile" class="size-4 dark:text-gray-400" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="1" stroke-linecap="round"><line x1="3" y1="7" x2="21" y2="7" /><line x1="3" y1="12" x2="15" y2="12" /><line x1="3" y1="17" x2="18" y2="17" /></svg>
24
+ <PanelRightClose v-if="isMobile" class="size-4 dark:text-gray-400" :stroke-width="1" />
25
25
  <PanelRightOpen v-else-if="open" class="dark:text-gray-400" :stroke-width="1" />
26
26
  <PanelRightClose v-else class="dark:text-gray-400" :stroke-width="1" />
27
27
  <span class="sr-only">Toggle Sidebar</span>
@@ -13,5 +13,5 @@ const forwardedProps = useForwardProps(delegatedProps)
13
13
  </script>
14
14
 
15
15
  <template>
16
- <TagsInputInput v-bind="forwardedProps" :class="cn('text-sm min-h-5 focus:outline-none flex-1 bg-transparent px-1', props.class)" />
16
+ <TagsInputInput v-bind="forwardedProps" :class="cn('text-sm min-h-5 focus:outline-none flex-1 bg-transparent px-1 placeholder:text-gray-400 dark:placeholder:text-gray-500', props.class)" />
17
17
  </template>
@@ -3,7 +3,7 @@ import type { TagsInputItemDeleteProps } from "reka-ui"
3
3
  import type { HTMLAttributes } from "vue"
4
4
  import { reactiveOmit } from "@vueuse/core"
5
5
  import { TagsInputItemDelete, useForwardProps } from "reka-ui"
6
- import { X } from "lucide-vue-next"
6
+ import { X } from "@lucide/vue"
7
7
  import { cn } from "@/lib/utils"
8
8
 
9
9
  const props = defineProps<TagsInputItemDeleteProps & { class?: HTMLAttributes["class"] }>()
@@ -0,0 +1,146 @@
1
+ import { parse, converter, formatRgb } from 'culori'
2
+
3
+ const toLch = converter('lch')
4
+
5
+ type Mode = 'background' | 'foreground'
6
+
7
+ /**
8
+ * CSS properties whose values contain colors we should invert, mapped to
9
+ * the inversion mode. Kebab-case for <style> decls; inline styles
10
+ * are handled via the same lookup after lowercasing.
11
+ */
12
+ const styleProps = new Map<string, Mode>([
13
+ ['background', 'background'],
14
+ ['background-color', 'background'],
15
+ ['border', 'foreground'],
16
+ ['border-color', 'foreground'],
17
+ ['border-top', 'foreground'],
18
+ ['border-right', 'foreground'],
19
+ ['border-bottom', 'foreground'],
20
+ ['border-left', 'foreground'],
21
+ ['border-top-color', 'foreground'],
22
+ ['border-right-color', 'foreground'],
23
+ ['border-bottom-color', 'foreground'],
24
+ ['border-left-color', 'foreground'],
25
+ ['color', 'foreground'],
26
+ ['outline', 'foreground'],
27
+ ['outline-color', 'foreground'],
28
+ ])
29
+
30
+ // Hex | color function with balanced-enough parens | bare word (possible named color).
31
+ const COLOR_TOKEN = /#[a-f0-9]{3,8}\b|(?:rgba?|hsla?|hwb|lab|lch|oklab|oklch|color)\([^)]*\)|\b[a-z]{3,20}\b/gi
32
+
33
+ // Words that look color-shaped but aren't — skip to avoid a wasted parse().
34
+ const NON_COLOR_KEYWORDS = /^(?:none|transparent|inherit|initial|unset|revert|currentcolor|auto|normal|solid|dashed|dotted|double|groove|ridge|inset|outset|hidden|thin|thick|medium|center|left|right|top|bottom|cover|contain|repeat|no-repeat|fixed|scroll|local|url|var|calc|linear|radial|conic|gradient)$/i
35
+
36
+ function invertOne(color: string, mode: Mode): string {
37
+ try {
38
+ const parsed = parse(color)
39
+ if (!parsed) return color
40
+ const lch = toLch(parsed) as any
41
+ if (!lch || typeof lch.l !== 'number' || Number.isNaN(lch.l)) return color
42
+
43
+ if (mode === 'background' && lch.l >= 50) lch.l = 50 - (lch.l - 50) * 0.75
44
+ if (mode === 'foreground' && lch.l < 50) lch.l = 50 - (lch.l - 50) * 0.75
45
+ if (typeof lch.c === 'number' && !Number.isNaN(lch.c)) lch.c *= 0.8
46
+
47
+ return formatRgb(lch) || color
48
+ } catch {
49
+ return color
50
+ }
51
+ }
52
+
53
+ function invertValue(value: string, mode: Mode): string {
54
+ return value.replace(COLOR_TOKEN, (tok) => {
55
+ if (NON_COLOR_KEYWORDS.test(tok)) return tok
56
+ if (!parse(tok)) return tok
57
+ return invertOne(tok, mode)
58
+ })
59
+ }
60
+
61
+ // Splits an inline style attr by `;` (safe — color functions use `,` not `;`).
62
+ function invertInlineStyle(style: string): string {
63
+ return style.split(';').map((decl) => {
64
+ const i = decl.indexOf(':')
65
+ if (i === -1) return decl
66
+ const prop = decl.slice(0, i).trim().toLowerCase()
67
+ const mode = styleProps.get(prop)
68
+ if (!mode) return decl
69
+ return decl.slice(0, i + 1) + invertValue(decl.slice(i + 1), mode)
70
+ }).join(';')
71
+ }
72
+
73
+ function invertStyleTag(css: string): string {
74
+ try {
75
+ const sheet = new CSSStyleSheet()
76
+ sheet.replaceSync(css)
77
+ const walk = (rules: CSSRuleList) => {
78
+ for (const rule of Array.from(rules)) {
79
+ if (rule instanceof CSSStyleRule) {
80
+ const props = Array.from({ length: rule.style.length }, (_, i) => rule.style.item(i))
81
+ for (const prop of props) {
82
+ const mode = styleProps.get(prop.toLowerCase())
83
+ if (!mode) continue
84
+ const value = rule.style.getPropertyValue(prop)
85
+ const priority = rule.style.getPropertyPriority(prop)
86
+ rule.style.setProperty(prop, invertValue(value, mode), priority)
87
+ }
88
+ } else if ('cssRules' in rule) {
89
+ walk((rule as CSSGroupingRule).cssRules)
90
+ }
91
+ }
92
+ }
93
+ walk(sheet.cssRules)
94
+ return Array.from(sheet.cssRules).map(r => r.cssText).join('\n')
95
+ } catch {
96
+ return css
97
+ }
98
+ }
99
+
100
+ const ORIG_INLINE = 'data-maizzle-orig-style'
101
+ const ORIG_STYLE_TAG = 'data-maizzle-orig-style-content'
102
+ const APPLIED_FLAG = 'data-maizzle-dark-applied'
103
+
104
+ function* walk(root: Node): Generator<Element> {
105
+ if (root.nodeType === 1) yield root as Element
106
+ for (const child of Array.from(root.childNodes)) yield* walk(child)
107
+ }
108
+
109
+ export function applyColorInversion(iframe: HTMLIFrameElement): void {
110
+ const doc = iframe.contentDocument
111
+ if (!doc || !doc.body || doc.body.hasAttribute(APPLIED_FLAG)) return
112
+
113
+ for (const el of walk(doc.documentElement)) {
114
+ const inline = el.getAttribute('style')
115
+ if (inline) {
116
+ el.setAttribute(ORIG_INLINE, inline)
117
+ el.setAttribute('style', invertInlineStyle(inline))
118
+ }
119
+ if (el.tagName === 'STYLE') {
120
+ const original = el.textContent ?? ''
121
+ el.setAttribute(ORIG_STYLE_TAG, original)
122
+ el.textContent = invertStyleTag(original)
123
+ }
124
+ }
125
+
126
+ doc.body.setAttribute(APPLIED_FLAG, '')
127
+ }
128
+
129
+ export function undoColorInversion(iframe: HTMLIFrameElement): void {
130
+ const doc = iframe.contentDocument
131
+ if (!doc || !doc.body || !doc.body.hasAttribute(APPLIED_FLAG)) return
132
+
133
+ for (const el of walk(doc.documentElement)) {
134
+ const origInline = el.getAttribute(ORIG_INLINE)
135
+ if (origInline !== null) {
136
+ el.setAttribute('style', origInline)
137
+ el.removeAttribute(ORIG_INLINE)
138
+ }
139
+ if (el.tagName === 'STYLE' && el.hasAttribute(ORIG_STYLE_TAG)) {
140
+ el.textContent = el.getAttribute(ORIG_STYLE_TAG) ?? ''
141
+ el.removeAttribute(ORIG_STYLE_TAG)
142
+ }
143
+ }
144
+
145
+ doc.body.removeAttribute(APPLIED_FLAG)
146
+ }