@maizzle/framework 6.0.0-rc.2 → 6.0.0-rc.21
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.
- package/README.md +3 -3
- package/bin/maizzle.mjs +1 -1
- package/dist/build.d.ts +20 -0
- package/dist/build.d.ts.map +1 -0
- package/dist/build.js +163 -0
- package/dist/build.js.map +1 -0
- package/dist/components/Body.vue +128 -0
- package/dist/components/Button.vue +148 -52
- package/dist/components/CodeBlock.vue +69 -0
- package/dist/components/CodeInline.vue +49 -0
- package/dist/components/Column.vue +108 -0
- package/dist/components/Container.vue +123 -0
- package/dist/components/Font.vue +96 -0
- package/dist/components/Head.vue +30 -0
- package/dist/components/Heading.vue +28 -0
- package/dist/components/Hr.vue +33 -0
- package/dist/components/Html.vue +137 -0
- package/dist/components/Img.vue +70 -0
- package/dist/components/Layout.vue +143 -0
- package/dist/components/Link.vue +26 -0
- package/dist/components/Markdown.vue +89 -0
- package/dist/components/MarkdownLayout.vue +39 -0
- package/dist/components/NotPlaintext.vue +14 -0
- package/dist/components/Outlook.vue +74 -11
- package/dist/components/OutlookBg.vue +241 -0
- package/dist/components/Overlap.vue +156 -0
- package/dist/components/Plaintext.vue +14 -0
- package/dist/components/Preheader.vue +15 -0
- package/dist/components/QrCode.vue +157 -0
- package/dist/components/Raw.vue +28 -0
- package/dist/components/Row.vue +184 -0
- package/dist/components/Section.vue +124 -0
- package/dist/components/Spacer.vue +70 -21
- package/dist/components/Tailwind.vue +43 -0
- package/dist/components/Text.vue +29 -0
- package/dist/components/utils.d.ts +28 -0
- package/dist/components/utils.d.ts.map +1 -0
- package/dist/components/utils.js +50 -0
- package/dist/components/utils.js.map +1 -0
- package/dist/components/utils.ts +51 -0
- package/dist/composables/{defineConfig.d.mts → defineConfig.d.ts} +2 -2
- package/dist/composables/defineConfig.d.ts.map +1 -0
- package/dist/composables/{defineConfig.mjs → defineConfig.js} +4 -5
- package/dist/composables/defineConfig.js.map +1 -0
- package/dist/composables/renderContext.d.ts +37 -0
- package/dist/composables/renderContext.d.ts.map +1 -0
- package/dist/composables/{renderContext.mjs → renderContext.js} +2 -2
- package/dist/composables/renderContext.js.map +1 -0
- package/dist/composables/useBaseUrl.d.ts +19 -0
- package/dist/composables/useBaseUrl.d.ts.map +1 -0
- package/dist/composables/useBaseUrl.js +26 -0
- package/dist/composables/useBaseUrl.js.map +1 -0
- package/dist/composables/{useConfig.d.mts → useConfig.d.ts} +2 -2
- package/dist/composables/useConfig.d.ts.map +1 -0
- package/dist/composables/{useConfig.mjs → useConfig.js} +2 -3
- package/dist/composables/useConfig.js.map +1 -0
- package/dist/composables/useCurrentTemplate.d.ts +31 -0
- package/dist/composables/useCurrentTemplate.d.ts.map +1 -0
- package/dist/composables/useCurrentTemplate.js +35 -0
- package/dist/composables/useCurrentTemplate.js.map +1 -0
- package/dist/composables/{useDoctype.d.mts → useDoctype.d.ts} +1 -1
- package/dist/composables/useDoctype.d.ts.map +1 -0
- package/dist/composables/{useDoctype.mjs → useDoctype.js} +3 -4
- package/dist/composables/useDoctype.js.map +1 -0
- package/dist/composables/{useEvent.d.mts → useEvent.d.ts} +3 -3
- package/dist/composables/useEvent.d.ts.map +1 -0
- package/dist/composables/{useEvent.mjs → useEvent.js} +4 -5
- package/dist/composables/useEvent.js.map +1 -0
- package/dist/composables/useFont.d.ts +50 -0
- package/dist/composables/useFont.d.ts.map +1 -0
- package/dist/composables/useFont.js +92 -0
- package/dist/composables/useFont.js.map +1 -0
- package/dist/composables/useOutlookFallback.d.ts +21 -0
- package/dist/composables/useOutlookFallback.d.ts.map +1 -0
- package/dist/composables/useOutlookFallback.js +29 -0
- package/dist/composables/useOutlookFallback.js.map +1 -0
- package/dist/composables/{usePlaintext.d.mts → usePlaintext.d.ts} +3 -1
- package/dist/composables/usePlaintext.d.ts.map +1 -0
- package/dist/composables/{usePlaintext.mjs → usePlaintext.js} +4 -4
- package/dist/composables/usePlaintext.js.map +1 -0
- package/dist/composables/usePreheader.d.ts +24 -0
- package/dist/composables/usePreheader.d.ts.map +1 -0
- package/dist/composables/usePreheader.js +28 -0
- package/dist/composables/usePreheader.js.map +1 -0
- package/dist/composables/useTransformers.d.ts +34 -0
- package/dist/composables/useTransformers.d.ts.map +1 -0
- package/dist/composables/useTransformers.js +48 -0
- package/dist/composables/useTransformers.js.map +1 -0
- package/dist/composables/useUrlQuery.d.ts +19 -0
- package/dist/composables/useUrlQuery.d.ts.map +1 -0
- package/dist/composables/useUrlQuery.js +26 -0
- package/dist/composables/useUrlQuery.js.map +1 -0
- package/dist/config/{defaults.d.mts → defaults.d.ts} +2 -2
- package/dist/config/defaults.d.ts.map +1 -0
- package/dist/config/{defaults.mjs → defaults.js} +10 -6
- package/dist/config/defaults.js.map +1 -0
- package/dist/config/{index.d.mts → index.d.ts} +4 -4
- package/dist/config/index.d.ts.map +1 -0
- package/dist/config/{index.mjs → index.js} +12 -10
- package/dist/config/index.js.map +1 -0
- package/dist/events/{index.d.mts → index.d.ts} +30 -12
- package/dist/events/index.d.ts.map +1 -0
- package/dist/events/{index.mjs → index.js} +26 -13
- package/dist/events/index.js.map +1 -0
- package/dist/index.d.ts +39 -0
- package/dist/index.js +38 -0
- package/dist/{plaintext.d.mts → plaintext.d.ts} +1 -1
- package/dist/plaintext.d.ts.map +1 -0
- package/dist/{plaintext.mjs → plaintext.js} +4 -5
- package/dist/plaintext.js.map +1 -0
- package/dist/{plugin.d.mts → plugin.d.ts} +2 -2
- package/dist/plugin.d.ts.map +1 -0
- package/dist/plugin.js +57 -0
- package/dist/plugin.js.map +1 -0
- package/dist/plugins/postcss/{mergeMediaQueries.d.mts → mergeMediaQueries.d.ts} +2 -2
- package/dist/plugins/postcss/mergeMediaQueries.d.ts.map +1 -0
- package/dist/plugins/postcss/{mergeMediaQueries.mjs → mergeMediaQueries.js} +2 -3
- package/dist/plugins/postcss/mergeMediaQueries.js.map +1 -0
- package/dist/plugins/postcss/{pruneVars.d.mts → pruneVars.d.ts} +1 -1
- package/dist/plugins/postcss/pruneVars.d.ts.map +1 -0
- package/dist/plugins/postcss/{pruneVars.mjs → pruneVars.js} +2 -2
- package/dist/plugins/postcss/pruneVars.js.map +1 -0
- package/dist/plugins/postcss/quoteFontFamilies.d.ts +13 -0
- package/dist/plugins/postcss/quoteFontFamilies.d.ts.map +1 -0
- package/dist/plugins/postcss/quoteFontFamilies.js +84 -0
- package/dist/plugins/postcss/quoteFontFamilies.js.map +1 -0
- package/dist/plugins/postcss/{removeDeclarations.d.mts → removeDeclarations.d.ts} +1 -1
- package/dist/plugins/postcss/removeDeclarations.d.ts.map +1 -0
- package/dist/plugins/postcss/{removeDeclarations.mjs → removeDeclarations.js} +2 -2
- package/dist/plugins/postcss/removeDeclarations.js.map +1 -0
- package/dist/plugins/postcss/resolveMaizzleImports.d.ts +16 -0
- package/dist/plugins/postcss/resolveMaizzleImports.d.ts.map +1 -0
- package/dist/plugins/postcss/resolveMaizzleImports.js +39 -0
- package/dist/plugins/postcss/resolveMaizzleImports.js.map +1 -0
- package/dist/plugins/postcss/resolveProps.d.ts +8 -0
- package/dist/plugins/postcss/resolveProps.d.ts.map +1 -0
- package/dist/plugins/postcss/resolveProps.js +144 -0
- package/dist/plugins/postcss/resolveProps.js.map +1 -0
- package/dist/plugins/postcss/{tailwindCleanup.d.mts → tailwindCleanup.d.ts} +2 -2
- package/dist/plugins/postcss/tailwindCleanup.d.ts.map +1 -0
- package/dist/plugins/postcss/tailwindCleanup.js +68 -0
- package/dist/plugins/postcss/tailwindCleanup.js.map +1 -0
- package/dist/prepare.d.ts +17 -0
- package/dist/prepare.d.ts.map +1 -0
- package/dist/prepare.js +44 -0
- package/dist/prepare.js.map +1 -0
- package/dist/render/active.d.ts +8 -0
- package/dist/render/active.d.ts.map +1 -0
- package/dist/render/active.js +12 -0
- package/dist/render/active.js.map +1 -0
- package/dist/render/{createRenderer.d.mts → createRenderer.d.ts} +15 -7
- package/dist/render/createRenderer.d.ts.map +1 -0
- package/dist/render/createRenderer.js +320 -0
- package/dist/render/createRenderer.js.map +1 -0
- package/dist/render/index.d.ts +18 -0
- package/dist/render/index.d.ts.map +1 -0
- package/dist/render/index.js +53 -0
- package/dist/render/index.js.map +1 -0
- package/dist/render/injectFonts.d.ts +15 -0
- package/dist/render/injectFonts.d.ts.map +1 -0
- package/dist/render/injectFonts.js +45 -0
- package/dist/render/injectFonts.js.map +1 -0
- package/dist/render/plugins/codeBlockExtract.d.ts +14 -0
- package/dist/render/plugins/codeBlockExtract.d.ts.map +1 -0
- package/dist/render/plugins/codeBlockExtract.js +34 -0
- package/dist/render/plugins/codeBlockExtract.js.map +1 -0
- package/dist/render/plugins/markdownExtract.d.ts +12 -0
- package/dist/render/plugins/markdownExtract.d.ts.map +1 -0
- package/dist/render/plugins/markdownExtract.js +49 -0
- package/dist/render/plugins/markdownExtract.js.map +1 -0
- package/dist/render/plugins/rawExtract.d.ts +14 -0
- package/dist/render/plugins/rawExtract.d.ts.map +1 -0
- package/dist/render/plugins/rawExtract.js +34 -0
- package/dist/render/plugins/rawExtract.js.map +1 -0
- package/dist/render/plugins/rowSourceLocation.d.ts +18 -0
- package/dist/render/plugins/rowSourceLocation.d.ts.map +1 -0
- package/dist/render/plugins/rowSourceLocation.js +45 -0
- package/dist/render/plugins/rowSourceLocation.js.map +1 -0
- package/dist/{serve.d.mts → serve.d.ts} +4 -2
- package/dist/serve.d.ts.map +1 -0
- package/dist/{serve.mjs → serve.js} +203 -78
- package/dist/serve.js.map +1 -0
- package/dist/server/compatibility.d.ts +59 -0
- package/dist/server/compatibility.d.ts.map +1 -0
- package/dist/server/compatibility.js +911 -0
- package/dist/server/compatibility.js.map +1 -0
- package/dist/server/email.d.ts +17 -0
- package/dist/server/email.d.ts.map +1 -0
- package/dist/server/email.js +40 -0
- package/dist/server/email.js.map +1 -0
- package/dist/server/linter.d.ts +20 -0
- package/dist/server/linter.d.ts.map +1 -0
- package/dist/server/linter.js +339 -0
- package/dist/server/linter.js.map +1 -0
- package/dist/server/sfc-utils.d.ts +21 -0
- package/dist/server/sfc-utils.d.ts.map +1 -0
- package/dist/server/sfc-utils.js +198 -0
- package/dist/server/sfc-utils.js.map +1 -0
- package/dist/server/ui/App.vue +253 -77
- package/dist/server/ui/components/SidebarClose.vue +12 -0
- package/dist/server/ui/components/ui/checkbox/Checkbox.vue +35 -0
- package/dist/server/ui/components/ui/checkbox/index.ts +1 -0
- package/dist/server/ui/components/ui/command/Command.vue +5 -1
- package/dist/server/ui/components/ui/command/CommandDialog.vue +1 -1
- package/dist/server/ui/components/ui/command/CommandInput.vue +19 -1
- package/dist/server/ui/components/ui/command/CommandItem.vue +1 -1
- package/dist/server/ui/components/ui/command/CommandList.vue +1 -1
- package/dist/server/ui/components/ui/command/CommandShortcut.vue +1 -1
- package/dist/server/ui/components/ui/dialog/DialogOverlay.vue +9 -1
- package/dist/server/ui/components/ui/dropdown-menu/DropdownMenuItem.vue +1 -1
- package/dist/server/ui/components/ui/input/Input.vue +1 -1
- package/dist/server/ui/components/ui/scroll-area/ScrollBar.vue +1 -1
- package/dist/server/ui/components/ui/sheet/SheetContent.vue +1 -1
- package/dist/server/ui/components/ui/sheet/SheetOverlay.vue +9 -1
- package/dist/server/ui/components/ui/sidebar/Sidebar.vue +8 -1
- package/dist/server/ui/components/ui/sidebar/SidebarProvider.vue +1 -1
- package/dist/server/ui/components/ui/sidebar/SidebarTrigger.vue +5 -4
- package/dist/server/ui/components/ui/tags-input/TagsInput.vue +26 -0
- package/dist/server/ui/components/ui/tags-input/TagsInputInput.vue +17 -0
- package/dist/server/ui/components/ui/tags-input/TagsInputItem.vue +19 -0
- package/dist/server/ui/components/ui/tags-input/TagsInputItemDelete.vue +22 -0
- package/dist/server/ui/components/ui/tags-input/TagsInputItemText.vue +17 -0
- package/dist/server/ui/components/ui/tags-input/index.ts +5 -0
- package/dist/server/ui/components/ui/toggle/index.ts +3 -3
- package/dist/server/ui/components/ui/toggle-group/ToggleGroup.vue +1 -1
- package/dist/server/ui/components/ui/toggle-group/ToggleGroupItem.vue +2 -2
- package/dist/server/ui/lib/emulated-dark-mode.ts +131 -0
- package/dist/server/ui/main.css +20 -20
- package/dist/server/ui/pages/Home.vue +12 -5
- package/dist/server/ui/pages/Preview.vue +716 -276
- package/dist/tests/render/_helpers.d.ts +6 -0
- package/dist/tests/render/_helpers.d.ts.map +1 -0
- package/dist/tests/render/_helpers.js +16 -0
- package/dist/tests/render/_helpers.js.map +1 -0
- package/dist/transformers/{addAttributes.d.mts → addAttributes.d.ts} +2 -2
- package/dist/transformers/addAttributes.d.ts.map +1 -0
- package/dist/transformers/{addAttributes.mjs → addAttributes.js} +16 -13
- package/dist/transformers/addAttributes.js.map +1 -0
- package/dist/transformers/attributeToStyle.d.ts +38 -0
- package/dist/transformers/attributeToStyle.d.ts.map +1 -0
- package/dist/transformers/attributeToStyle.js +94 -0
- package/dist/transformers/attributeToStyle.js.map +1 -0
- package/dist/transformers/base.d.ts +71 -0
- package/dist/transformers/base.d.ts.map +1 -0
- package/dist/transformers/{base.mjs → base.js} +56 -30
- package/dist/transformers/base.js.map +1 -0
- package/dist/transformers/columnWidth.d.ts +31 -0
- package/dist/transformers/columnWidth.d.ts.map +1 -0
- package/dist/transformers/columnWidth.js +546 -0
- package/dist/transformers/columnWidth.js.map +1 -0
- package/dist/transformers/entities.d.ts +37 -0
- package/dist/transformers/entities.d.ts.map +1 -0
- package/dist/transformers/entities.js +73 -0
- package/dist/transformers/entities.js.map +1 -0
- package/dist/transformers/filters/defaults.d.ts +6 -0
- package/dist/transformers/filters/defaults.d.ts.map +1 -0
- package/dist/transformers/filters/defaults.js +78 -0
- package/dist/transformers/filters/defaults.js.map +1 -0
- package/dist/transformers/filters/index.d.ts +43 -0
- package/dist/transformers/filters/index.d.ts.map +1 -0
- package/dist/transformers/filters/index.js +89 -0
- package/dist/transformers/filters/index.js.map +1 -0
- package/dist/transformers/format.d.ts +22 -0
- package/dist/transformers/format.d.ts.map +1 -0
- package/dist/transformers/format.js +30 -0
- package/dist/transformers/format.js.map +1 -0
- package/dist/transformers/{index.d.mts → index.d.ts} +14 -11
- package/dist/transformers/index.d.ts.map +1 -0
- package/dist/transformers/index.js +133 -0
- package/dist/transformers/index.js.map +1 -0
- package/dist/transformers/inlineCss.d.ts +84 -0
- package/dist/transformers/inlineCss.d.ts.map +1 -0
- package/dist/transformers/inlineCss.js +91 -0
- package/dist/transformers/inlineCss.js.map +1 -0
- package/dist/transformers/inlineLink.d.ts +35 -0
- package/dist/transformers/inlineLink.d.ts.map +1 -0
- package/dist/transformers/{inlineLink.mjs → inlineLink.js} +34 -10
- package/dist/transformers/inlineLink.js.map +1 -0
- package/dist/transformers/minify.d.ts +21 -0
- package/dist/transformers/minify.d.ts.map +1 -0
- package/dist/transformers/minify.js +25 -0
- package/dist/transformers/minify.js.map +1 -0
- package/dist/transformers/msoPlaceholders.d.ts +28 -0
- package/dist/transformers/msoPlaceholders.d.ts.map +1 -0
- package/dist/transformers/msoPlaceholders.js +88 -0
- package/dist/transformers/msoPlaceholders.js.map +1 -0
- package/dist/transformers/purgeCss.d.ts +43 -0
- package/dist/transformers/purgeCss.d.ts.map +1 -0
- package/dist/transformers/purgeCss.js +181 -0
- package/dist/transformers/purgeCss.js.map +1 -0
- package/dist/transformers/removeAttributes.d.ts +54 -0
- package/dist/transformers/removeAttributes.d.ts.map +1 -0
- package/dist/transformers/removeAttributes.js +70 -0
- package/dist/transformers/removeAttributes.js.map +1 -0
- package/dist/transformers/{replaceStrings.d.mts → replaceStrings.d.ts} +2 -2
- package/dist/transformers/replaceStrings.d.ts.map +1 -0
- package/dist/transformers/{replaceStrings.mjs → replaceStrings.js} +2 -2
- package/dist/transformers/replaceStrings.js.map +1 -0
- package/dist/transformers/{safeClassNames.d.mts → safeClassNames.d.ts} +2 -2
- package/dist/transformers/safeClassNames.d.ts.map +1 -0
- package/dist/transformers/{safeClassNames.mjs → safeClassNames.js} +4 -5
- package/dist/transformers/safeClassNames.js.map +1 -0
- package/dist/transformers/shorthandCss.d.ts +47 -0
- package/dist/transformers/shorthandCss.d.ts.map +1 -0
- package/dist/transformers/shorthandCss.js +61 -0
- package/dist/transformers/shorthandCss.js.map +1 -0
- package/dist/transformers/sixHex.d.ts +25 -0
- package/dist/transformers/sixHex.d.ts.map +1 -0
- package/dist/transformers/sixHex.js +42 -0
- package/dist/transformers/sixHex.js.map +1 -0
- package/dist/transformers/tailwindComponent.d.ts +16 -0
- package/dist/transformers/tailwindComponent.d.ts.map +1 -0
- package/dist/transformers/tailwindComponent.js +92 -0
- package/dist/transformers/tailwindComponent.js.map +1 -0
- package/dist/transformers/{tailwindcss.d.mts → tailwindcss.d.ts} +8 -4
- package/dist/transformers/tailwindcss.d.ts.map +1 -0
- package/dist/transformers/tailwindcss.js +97 -0
- package/dist/transformers/tailwindcss.js.map +1 -0
- package/dist/transformers/urlQuery.d.ts +36 -0
- package/dist/transformers/urlQuery.d.ts.map +1 -0
- package/dist/transformers/urlQuery.js +77 -0
- package/dist/transformers/urlQuery.js.map +1 -0
- package/dist/types/config.d.ts +737 -0
- package/dist/types/config.d.ts.map +1 -0
- package/dist/types/config.js +1 -0
- package/dist/types/index.d.ts +2 -0
- package/dist/types/index.js +1 -0
- package/dist/utils/ast/index.d.ts +4 -0
- package/dist/utils/ast/index.js +4 -0
- package/dist/utils/ast/{parser.d.mts → parser.d.ts} +1 -1
- package/dist/utils/ast/parser.d.ts.map +1 -0
- package/dist/utils/ast/{parser.mjs → parser.js} +2 -3
- package/dist/utils/ast/parser.js.map +1 -0
- package/dist/utils/ast/serializer.d.ts +8 -0
- package/dist/utils/ast/serializer.d.ts.map +1 -0
- package/dist/utils/ast/serializer.js +36 -0
- package/dist/utils/ast/serializer.js.map +1 -0
- package/dist/utils/ast/{walker.d.mts → walker.d.ts} +1 -1
- package/dist/utils/ast/walker.d.ts.map +1 -0
- package/dist/utils/ast/{walker.mjs → walker.js} +2 -2
- package/dist/utils/ast/walker.js.map +1 -0
- package/dist/utils/compileTailwindCss.d.ts +16 -0
- package/dist/utils/compileTailwindCss.d.ts.map +1 -0
- package/dist/utils/compileTailwindCss.js +54 -0
- package/dist/utils/compileTailwindCss.js.map +1 -0
- package/dist/utils/componentSources.d.ts +50 -0
- package/dist/utils/componentSources.d.ts.map +1 -0
- package/dist/utils/componentSources.js +50 -0
- package/dist/utils/componentSources.js.map +1 -0
- package/dist/utils/decodeStyleEntities.d.ts +15 -0
- package/dist/utils/decodeStyleEntities.d.ts.map +1 -0
- package/dist/utils/decodeStyleEntities.js +18 -0
- package/dist/utils/decodeStyleEntities.js.map +1 -0
- package/dist/utils/detect.d.ts +5 -0
- package/dist/utils/detect.d.ts.map +1 -0
- package/dist/utils/detect.js +10 -0
- package/dist/utils/detect.js.map +1 -0
- package/dist/utils/output-markers.d.ts +29 -0
- package/dist/utils/output-markers.d.ts.map +1 -0
- package/dist/utils/output-markers.js +68 -0
- package/dist/utils/output-markers.js.map +1 -0
- package/dist/utils/{url.d.mts → url.d.ts} +1 -1
- package/dist/utils/url.d.ts.map +1 -0
- package/dist/utils/{url.mjs → url.js} +2 -3
- package/dist/utils/url.js.map +1 -0
- package/dist/utils/watchPaths.d.ts +11 -0
- package/dist/utils/watchPaths.d.ts.map +1 -0
- package/dist/utils/watchPaths.js +19 -0
- package/dist/utils/watchPaths.js.map +1 -0
- package/node_modules/@clack/core/CHANGELOG.md +8 -0
- package/node_modules/@clack/core/dist/index.d.mts +18 -4
- package/node_modules/@clack/core/dist/index.mjs +16 -10
- package/node_modules/@clack/core/dist/index.mjs.map +1 -1
- package/node_modules/@clack/core/package.json +5 -2
- package/node_modules/@clack/prompts/CHANGELOG.md +15 -0
- package/node_modules/@clack/prompts/README.md +107 -2
- package/node_modules/@clack/prompts/dist/index.d.mts +16 -11
- package/node_modules/@clack/prompts/dist/index.mjs +114 -107
- package/node_modules/@clack/prompts/dist/index.mjs.map +1 -1
- package/node_modules/@clack/prompts/package.json +7 -4
- package/node_modules/fast-string-truncated-width/dist/index.js +36 -96
- package/node_modules/fast-string-truncated-width/dist/types.d.ts +0 -3
- package/node_modules/fast-string-truncated-width/dist/utils.d.ts +3 -3
- package/node_modules/fast-string-truncated-width/dist/utils.js +14 -9
- package/node_modules/fast-string-truncated-width/package.json +1 -1
- package/node_modules/fast-string-truncated-width/readme.md +2 -3
- package/node_modules/fast-string-width/package.json +2 -2
- package/node_modules/fast-string-width/readme.md +0 -3
- package/node_modules/fast-wrap-ansi/lib/main.js +4 -1
- package/node_modules/fast-wrap-ansi/lib/main.js.map +1 -1
- package/node_modules/fast-wrap-ansi/package.json +2 -2
- package/node_modules/maizzle/README.md +24 -0
- package/node_modules/maizzle/dist/commands/make/component.mjs +1 -1
- package/node_modules/maizzle/dist/commands/make/config.mjs +1 -1
- package/node_modules/maizzle/dist/commands/make/layout.mjs +3 -3
- package/node_modules/maizzle/dist/commands/make/scaffold.mjs +1 -1
- package/node_modules/maizzle/dist/commands/make/stubs/Layout.vue +146 -0
- package/node_modules/maizzle/dist/commands/make/stubs/component.vue +2 -4
- package/node_modules/maizzle/dist/commands/make/stubs/config.ts +1 -5
- package/node_modules/maizzle/dist/commands/make/template.mjs +1 -1
- package/node_modules/maizzle/dist/commands/new.mjs +32 -52
- package/node_modules/maizzle/dist/index.d.mts +1 -0
- package/node_modules/maizzle/dist/index.mjs +30 -7
- package/node_modules/maizzle/package.json +4 -3
- package/node_modules/nypm/dist/cli.mjs +28 -5
- package/node_modules/nypm/dist/index.d.mts +0 -8
- package/node_modules/nypm/dist/index.mjs +27 -4
- package/node_modules/nypm/package.json +12 -12
- package/node_modules/tinyexec/README.md +1 -1
- package/node_modules/tinyexec/dist/main.d.mts +6 -6
- package/node_modules/tinyexec/dist/main.mjs +126 -134
- package/node_modules/tinyexec/package.json +9 -9
- package/package.json +31 -21
- package/dist/build.d.mts +0 -19
- package/dist/build.d.mts.map +0 -1
- package/dist/build.mjs +0 -139
- package/dist/build.mjs.map +0 -1
- package/dist/components/Divider.vue +0 -105
- package/dist/components/Vml.vue +0 -89
- package/dist/components/utils.d.mts +0 -5
- package/dist/components/utils.d.mts.map +0 -1
- package/dist/components/utils.mjs +0 -9
- package/dist/components/utils.mjs.map +0 -1
- package/dist/composables/defineConfig.d.mts.map +0 -1
- package/dist/composables/defineConfig.mjs.map +0 -1
- package/dist/composables/renderContext.d.mts +0 -19
- package/dist/composables/renderContext.d.mts.map +0 -1
- package/dist/composables/renderContext.mjs.map +0 -1
- package/dist/composables/useConfig.d.mts.map +0 -1
- package/dist/composables/useConfig.mjs.map +0 -1
- package/dist/composables/useDoctype.d.mts.map +0 -1
- package/dist/composables/useDoctype.mjs.map +0 -1
- package/dist/composables/useEvent.d.mts.map +0 -1
- package/dist/composables/useEvent.mjs.map +0 -1
- package/dist/composables/usePlaintext.d.mts.map +0 -1
- package/dist/composables/usePlaintext.mjs.map +0 -1
- package/dist/config/defaults.d.mts.map +0 -1
- package/dist/config/defaults.mjs.map +0 -1
- package/dist/config/index.d.mts.map +0 -1
- package/dist/config/index.mjs.map +0 -1
- package/dist/events/index.d.mts.map +0 -1
- package/dist/events/index.mjs.map +0 -1
- package/dist/index.d.mts +0 -29
- package/dist/index.mjs +0 -29
- package/dist/plaintext.d.mts.map +0 -1
- package/dist/plaintext.mjs.map +0 -1
- package/dist/plugin.d.mts.map +0 -1
- package/dist/plugin.mjs +0 -41
- package/dist/plugin.mjs.map +0 -1
- package/dist/plugins/postcss/mergeMediaQueries.d.mts.map +0 -1
- package/dist/plugins/postcss/mergeMediaQueries.mjs.map +0 -1
- package/dist/plugins/postcss/pruneVars.d.mts.map +0 -1
- package/dist/plugins/postcss/pruneVars.mjs.map +0 -1
- package/dist/plugins/postcss/removeDeclarations.d.mts.map +0 -1
- package/dist/plugins/postcss/removeDeclarations.mjs.map +0 -1
- package/dist/plugins/postcss/tailwindCleanup.d.mts.map +0 -1
- package/dist/plugins/postcss/tailwindCleanup.mjs +0 -35
- package/dist/plugins/postcss/tailwindCleanup.mjs.map +0 -1
- package/dist/render/createRenderer.d.mts.map +0 -1
- package/dist/render/createRenderer.mjs +0 -155
- package/dist/render/createRenderer.mjs.map +0 -1
- package/dist/render/index.d.mts +0 -26
- package/dist/render/index.d.mts.map +0 -1
- package/dist/render/index.mjs +0 -44
- package/dist/render/index.mjs.map +0 -1
- package/dist/serve.d.mts.map +0 -1
- package/dist/serve.mjs.map +0 -1
- package/dist/server/compatibility.d.mts +0 -6
- package/dist/server/compatibility.d.mts.map +0 -1
- package/dist/server/compatibility.mjs +0 -83
- package/dist/server/compatibility.mjs.map +0 -1
- package/dist/server/linter.d.mts +0 -6
- package/dist/server/linter.d.mts.map +0 -1
- package/dist/server/linter.mjs +0 -200
- package/dist/server/linter.mjs.map +0 -1
- package/dist/server/ui/components/ui/resizable/ResizableHandle.vue +0 -30
- package/dist/server/ui/components/ui/resizable/ResizablePanel.vue +0 -21
- package/dist/server/ui/components/ui/resizable/ResizablePanelGroup.vue +0 -25
- package/dist/server/ui/components/ui/resizable/index.ts +0 -3
- package/dist/transformers/addAttributes.d.mts.map +0 -1
- package/dist/transformers/addAttributes.mjs.map +0 -1
- package/dist/transformers/attributeToStyle.d.mts +0 -25
- package/dist/transformers/attributeToStyle.d.mts.map +0 -1
- package/dist/transformers/attributeToStyle.mjs +0 -80
- package/dist/transformers/attributeToStyle.mjs.map +0 -1
- package/dist/transformers/base.d.mts +0 -8
- package/dist/transformers/base.d.mts.map +0 -1
- package/dist/transformers/base.mjs.map +0 -1
- package/dist/transformers/entities.d.mts +0 -8
- package/dist/transformers/entities.d.mts.map +0 -1
- package/dist/transformers/entities.mjs +0 -38
- package/dist/transformers/entities.mjs.map +0 -1
- package/dist/transformers/format.d.mts +0 -15
- package/dist/transformers/format.d.mts.map +0 -1
- package/dist/transformers/format.mjs +0 -26
- package/dist/transformers/format.mjs.map +0 -1
- package/dist/transformers/index.d.mts.map +0 -1
- package/dist/transformers/index.mjs +0 -73
- package/dist/transformers/index.mjs.map +0 -1
- package/dist/transformers/inlineCSS.d.mts +0 -30
- package/dist/transformers/inlineCSS.d.mts.map +0 -1
- package/dist/transformers/inlineCSS.mjs +0 -79
- package/dist/transformers/inlineCSS.mjs.map +0 -1
- package/dist/transformers/inlineLink.d.mts +0 -14
- package/dist/transformers/inlineLink.d.mts.map +0 -1
- package/dist/transformers/inlineLink.mjs.map +0 -1
- package/dist/transformers/minify.d.mts +0 -17
- package/dist/transformers/minify.d.mts.map +0 -1
- package/dist/transformers/minify.mjs +0 -24
- package/dist/transformers/minify.mjs.map +0 -1
- package/dist/transformers/purgeCSS.d.mts +0 -23
- package/dist/transformers/purgeCSS.d.mts.map +0 -1
- package/dist/transformers/purgeCSS.mjs +0 -66
- package/dist/transformers/purgeCSS.mjs.map +0 -1
- package/dist/transformers/removeAttributes.d.mts +0 -31
- package/dist/transformers/removeAttributes.d.mts.map +0 -1
- package/dist/transformers/removeAttributes.mjs +0 -63
- package/dist/transformers/removeAttributes.mjs.map +0 -1
- package/dist/transformers/replaceStrings.d.mts.map +0 -1
- package/dist/transformers/replaceStrings.mjs.map +0 -1
- package/dist/transformers/safeClassNames.d.mts.map +0 -1
- package/dist/transformers/safeClassNames.mjs.map +0 -1
- package/dist/transformers/shorthandCSS.d.mts +0 -24
- package/dist/transformers/shorthandCSS.d.mts.map +0 -1
- package/dist/transformers/shorthandCSS.mjs +0 -48
- package/dist/transformers/shorthandCSS.mjs.map +0 -1
- package/dist/transformers/tailwindcss.d.mts.map +0 -1
- package/dist/transformers/tailwindcss.mjs +0 -136
- package/dist/transformers/tailwindcss.mjs.map +0 -1
- package/dist/transformers/urlQuery.d.mts +0 -24
- package/dist/transformers/urlQuery.d.mts.map +0 -1
- package/dist/transformers/urlQuery.mjs +0 -65
- package/dist/transformers/urlQuery.mjs.map +0 -1
- package/dist/types/config.d.mts +0 -149
- package/dist/types/config.d.mts.map +0 -1
- package/dist/types/config.mjs +0 -1
- package/dist/types/index.d.mts +0 -2
- package/dist/types/index.mjs +0 -1
- package/dist/utils/ast/index.d.mts +0 -4
- package/dist/utils/ast/index.mjs +0 -5
- package/dist/utils/ast/parser.d.mts.map +0 -1
- package/dist/utils/ast/parser.mjs.map +0 -1
- package/dist/utils/ast/serializer.d.mts +0 -7
- package/dist/utils/ast/serializer.d.mts.map +0 -1
- package/dist/utils/ast/serializer.mjs +0 -13
- package/dist/utils/ast/serializer.mjs.map +0 -1
- package/dist/utils/ast/walker.d.mts.map +0 -1
- package/dist/utils/ast/walker.mjs.map +0 -1
- package/dist/utils/url.d.mts.map +0 -1
- package/dist/utils/url.mjs.map +0 -1
- package/node_modules/maizzle/dist/commands/make/stubs/layout.vue +0 -39
package/README.md
CHANGED
|
@@ -7,7 +7,7 @@
|
|
|
7
7
|
</picture>
|
|
8
8
|
</a>
|
|
9
9
|
</p>
|
|
10
|
-
<p>
|
|
10
|
+
<p>The modern email development framework</p>
|
|
11
11
|
<div>
|
|
12
12
|
|
|
13
13
|
[![Version][npm-version-shield]][npm]
|
|
@@ -20,9 +20,9 @@
|
|
|
20
20
|
|
|
21
21
|
## About
|
|
22
22
|
|
|
23
|
-
> **Note:** This repository contains the core code of the Maizzle framework. If you want to
|
|
23
|
+
> **Note:** This repository contains the core code of the Maizzle framework. If you want to start building HTML emails using Maizzle, visit the [Starter repository](https://github.com/maizzle/maizzle).
|
|
24
24
|
|
|
25
|
-
Maizzle is a framework
|
|
25
|
+
Maizzle is a Vite-powered framework for building HTML emails with Vue and Tailwind CSS.
|
|
26
26
|
|
|
27
27
|
## Documentation
|
|
28
28
|
|
package/bin/maizzle.mjs
CHANGED
|
@@ -5,6 +5,6 @@ import { fileURLToPath } from 'node:url'
|
|
|
5
5
|
|
|
6
6
|
const jiti = createJiti(fileURLToPath(import.meta.url), { interopDefault: true })
|
|
7
7
|
const { default: bootstrap } = await jiti.import('maizzle')
|
|
8
|
-
const framework = await jiti.import('../dist/index.
|
|
8
|
+
const framework = await jiti.import('../dist/index.js')
|
|
9
9
|
|
|
10
10
|
await bootstrap(framework)
|
package/dist/build.d.ts
ADDED
|
@@ -0,0 +1,20 @@
|
|
|
1
|
+
import { MaizzleConfig } from "./types/config.js";
|
|
2
|
+
//#region src/build.d.ts
|
|
3
|
+
interface BuildResult {
|
|
4
|
+
files: string[];
|
|
5
|
+
config: MaizzleConfig;
|
|
6
|
+
}
|
|
7
|
+
/**
|
|
8
|
+
* Build all SFC email templates to HTML files.
|
|
9
|
+
*
|
|
10
|
+
* Creates a single Renderer instance, then loops through each template
|
|
11
|
+
* calling render → transformers → write to disk.
|
|
12
|
+
*
|
|
13
|
+
* Pass a `Partial<MaizzleConfig>` to override config inline, or a string
|
|
14
|
+
* to load config from a specific file path. Omit to load `maizzle.config`
|
|
15
|
+
* from the working directory.
|
|
16
|
+
*/
|
|
17
|
+
declare function build(configInput?: Partial<MaizzleConfig> | string): Promise<BuildResult>;
|
|
18
|
+
//#endregion
|
|
19
|
+
export { BuildResult, build };
|
|
20
|
+
//# sourceMappingURL=build.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"build.d.ts","names":[],"sources":["../src/build.ts"],"mappings":";;UAeiB,WAAA;EACf,KAAA;EACA,MAAA,EAAQ,aAAA;AAAA;;;;;;;;;AAaV;;iBAAsB,KAAA,CAAM,WAAA,GAAc,OAAA,CAAQ,aAAA,aAA0B,OAAA,CAAQ,WAAA"}
|
package/dist/build.js
ADDED
|
@@ -0,0 +1,163 @@
|
|
|
1
|
+
import { resolveConfig } from "./config/index.js";
|
|
2
|
+
import { EventManager } from "./events/index.js";
|
|
3
|
+
import { runTransformers } from "./transformers/index.js";
|
|
4
|
+
import { normalizeComponentSources } from "./utils/componentSources.js";
|
|
5
|
+
import { createRenderer } from "./render/createRenderer.js";
|
|
6
|
+
import { createPlaintext } from "./plaintext.js";
|
|
7
|
+
import { stripForHtml, stripForPlaintext } from "./utils/output-markers.js";
|
|
8
|
+
import { _setCurrentTemplate } from "./composables/useCurrentTemplate.js";
|
|
9
|
+
import { cpSync, existsSync, mkdirSync, readFileSync, rmSync, writeFileSync } from "node:fs";
|
|
10
|
+
import { basename, dirname, join, parse, relative, resolve } from "node:path";
|
|
11
|
+
import { glob } from "tinyglobby";
|
|
12
|
+
import ora from "ora";
|
|
13
|
+
import defu from "defu";
|
|
14
|
+
//#region src/build.ts
|
|
15
|
+
/**
|
|
16
|
+
* Build all SFC email templates to HTML files.
|
|
17
|
+
*
|
|
18
|
+
* Creates a single Renderer instance, then loops through each template
|
|
19
|
+
* calling render → transformers → write to disk.
|
|
20
|
+
*
|
|
21
|
+
* Pass a `Partial<MaizzleConfig>` to override config inline, or a string
|
|
22
|
+
* to load config from a specific file path. Omit to load `maizzle.config`
|
|
23
|
+
* from the working directory.
|
|
24
|
+
*/
|
|
25
|
+
async function build(configInput) {
|
|
26
|
+
const start = Date.now();
|
|
27
|
+
const spinner = ora({
|
|
28
|
+
text: "Building templates...",
|
|
29
|
+
spinner: "circleHalves"
|
|
30
|
+
}).start();
|
|
31
|
+
const config = await resolveConfig(configInput);
|
|
32
|
+
const events = new EventManager();
|
|
33
|
+
events.registerConfig(config);
|
|
34
|
+
await events.fireBeforeCreate({ config });
|
|
35
|
+
const outputPath = resolve(config.output?.path ?? "dist");
|
|
36
|
+
const outputExtension = config.output?.extension ?? "html";
|
|
37
|
+
const contentPatterns = config.content ?? ["emails/**/*.vue"];
|
|
38
|
+
const contentBase = computeContentBase(contentPatterns);
|
|
39
|
+
const templateFiles = await glob(contentPatterns);
|
|
40
|
+
if (templateFiles.length === 0) {
|
|
41
|
+
spinner.succeed("No templates found");
|
|
42
|
+
return {
|
|
43
|
+
files: [],
|
|
44
|
+
config
|
|
45
|
+
};
|
|
46
|
+
}
|
|
47
|
+
if (existsSync(outputPath)) rmSync(outputPath, {
|
|
48
|
+
recursive: true,
|
|
49
|
+
force: true
|
|
50
|
+
});
|
|
51
|
+
const renderer = await createRenderer({
|
|
52
|
+
markdown: config.markdown,
|
|
53
|
+
root: config.root,
|
|
54
|
+
componentDirs: normalizeComponentSources(config.components?.source, process.cwd()),
|
|
55
|
+
vite: config.vite
|
|
56
|
+
});
|
|
57
|
+
const outputFiles = [];
|
|
58
|
+
try {
|
|
59
|
+
for (const templatePath of templateFiles) {
|
|
60
|
+
const absolutePath = resolve(templatePath);
|
|
61
|
+
const parsedPath = parse(absolutePath);
|
|
62
|
+
const template = {
|
|
63
|
+
source: readFileSync(absolutePath, "utf-8"),
|
|
64
|
+
path: parsedPath
|
|
65
|
+
};
|
|
66
|
+
_setCurrentTemplate(parsedPath);
|
|
67
|
+
try {
|
|
68
|
+
await events.fireBeforeRender({
|
|
69
|
+
config,
|
|
70
|
+
template
|
|
71
|
+
});
|
|
72
|
+
const rendered = await renderer.render(absolutePath, config);
|
|
73
|
+
for (const { name, handler } of rendered.sfcEventHandlers) events.on(name, handler);
|
|
74
|
+
let html = await events.fireAfterRender({
|
|
75
|
+
config,
|
|
76
|
+
template,
|
|
77
|
+
html: rendered.html
|
|
78
|
+
});
|
|
79
|
+
const templateConfig = rendered.templateConfig;
|
|
80
|
+
const doctype = rendered.doctype ?? templateConfig.doctype ?? "<!DOCTYPE html>";
|
|
81
|
+
if (templateConfig.useTransformers !== false) html = await runTransformers(html, templateConfig, absolutePath, doctype, rendered.tailwindBlocks);
|
|
82
|
+
html = await events.fireAfterTransform({
|
|
83
|
+
config,
|
|
84
|
+
template,
|
|
85
|
+
html
|
|
86
|
+
});
|
|
87
|
+
html = `${doctype}\n${html}`;
|
|
88
|
+
const htmlOut = stripForHtml(html);
|
|
89
|
+
const outputFilePath = resolveOutputPath(templatePath, outputPath, outputExtension, contentBase);
|
|
90
|
+
mkdirSync(dirname(outputFilePath), { recursive: true });
|
|
91
|
+
writeFileSync(outputFilePath, htmlOut);
|
|
92
|
+
outputFiles.push(outputFilePath);
|
|
93
|
+
const globalPlaintext = templateConfig.plaintext;
|
|
94
|
+
const sfcPlaintext = rendered.plaintext;
|
|
95
|
+
if (globalPlaintext || sfcPlaintext) {
|
|
96
|
+
const globalCfg = typeof globalPlaintext === "object" ? globalPlaintext : {};
|
|
97
|
+
const stripOptions = defu(sfcPlaintext?.options, globalCfg.options);
|
|
98
|
+
const plaintext = createPlaintext(stripForPlaintext(html), stripOptions);
|
|
99
|
+
const ptExtension = sfcPlaintext?.extension ?? globalCfg.extension ?? "txt";
|
|
100
|
+
let ptOutputPath;
|
|
101
|
+
if (sfcPlaintext?.destination) {
|
|
102
|
+
const name = basename(templatePath).replace(/\.(vue|md)$/, "");
|
|
103
|
+
ptOutputPath = join(resolve(sfcPlaintext.destination), `${name}.${ptExtension}`);
|
|
104
|
+
} else if (globalCfg.destination) ptOutputPath = resolveOutputPath(templatePath, resolve(globalCfg.destination), ptExtension, contentBase);
|
|
105
|
+
else ptOutputPath = resolveOutputPath(templatePath, outputPath, ptExtension, contentBase);
|
|
106
|
+
mkdirSync(dirname(ptOutputPath), { recursive: true });
|
|
107
|
+
writeFileSync(ptOutputPath, plaintext);
|
|
108
|
+
}
|
|
109
|
+
} finally {
|
|
110
|
+
_setCurrentTemplate(void 0);
|
|
111
|
+
events.clearSfcHandlers();
|
|
112
|
+
}
|
|
113
|
+
}
|
|
114
|
+
await copyStatic(config, outputPath);
|
|
115
|
+
await events.fireAfterBuild({
|
|
116
|
+
files: outputFiles,
|
|
117
|
+
config
|
|
118
|
+
});
|
|
119
|
+
} finally {
|
|
120
|
+
await renderer.close();
|
|
121
|
+
}
|
|
122
|
+
const duration = ((Date.now() - start) / 1e3).toFixed(2);
|
|
123
|
+
const count = outputFiles.length;
|
|
124
|
+
spinner.stopAndPersist({
|
|
125
|
+
symbol: "✅",
|
|
126
|
+
text: `Built ${count} template${count !== 1 ? "s" : ""} in ${duration}s`
|
|
127
|
+
});
|
|
128
|
+
return {
|
|
129
|
+
files: outputFiles,
|
|
130
|
+
config
|
|
131
|
+
};
|
|
132
|
+
}
|
|
133
|
+
/**
|
|
134
|
+
* Extract the static (non-glob) prefix from content patterns.
|
|
135
|
+
*
|
|
136
|
+
* For example, `['/abs/path/emails/**\/*.vue']` → `'/abs/path/emails'`
|
|
137
|
+
*
|
|
138
|
+
* This is used to strip the content base from template paths
|
|
139
|
+
* so the output preserves only the subdirectory structure.
|
|
140
|
+
*/
|
|
141
|
+
function computeContentBase(patterns) {
|
|
142
|
+
const staticPart = (patterns.find((p) => !p.startsWith("!")) ?? patterns[0]).split(/[*{?[]/)[0];
|
|
143
|
+
return resolve(staticPart.endsWith("/") ? staticPart : dirname(staticPart));
|
|
144
|
+
}
|
|
145
|
+
function resolveOutputPath(templatePath, outputDir, extension, contentBase) {
|
|
146
|
+
const name = basename(templatePath).replace(/\.(vue|md)$/, "");
|
|
147
|
+
return join(outputDir, relative(contentBase, dirname(resolve(templatePath))), `${name}.${extension}`);
|
|
148
|
+
}
|
|
149
|
+
async function copyStatic(config, outputPath) {
|
|
150
|
+
const sources = config.static?.source ?? ["public/**/*.*"];
|
|
151
|
+
const destination = config.static?.destination ?? "public";
|
|
152
|
+
const files = await glob(sources);
|
|
153
|
+
for (const file of files) {
|
|
154
|
+
const destPath = join(outputPath, destination, relative(dirname(sources[0]).replace(/\*.*$/, ""), file));
|
|
155
|
+
const destDir = dirname(destPath);
|
|
156
|
+
if (!existsSync(destDir)) mkdirSync(destDir, { recursive: true });
|
|
157
|
+
cpSync(file, destPath);
|
|
158
|
+
}
|
|
159
|
+
}
|
|
160
|
+
//#endregion
|
|
161
|
+
export { build };
|
|
162
|
+
|
|
163
|
+
//# sourceMappingURL=build.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"build.js","names":["parsePath"],"sources":["../src/build.ts"],"sourcesContent":["import { readFileSync, writeFileSync, mkdirSync, cpSync, existsSync, rmSync } from 'node:fs'\nimport { resolve, dirname, basename, relative, join, parse as parsePath } from 'node:path'\nimport { glob } from 'tinyglobby'\nimport ora from 'ora'\nimport { resolveConfig } from './config/index.ts'\nimport { EventManager } from './events/index.ts'\nimport { runTransformers } from './transformers/index.ts'\nimport { createRenderer } from './render/createRenderer.ts'\nimport { createPlaintext } from './plaintext.ts'\nimport { stripForHtml, stripForPlaintext } from './utils/output-markers.ts'\nimport { normalizeComponentSources } from './utils/componentSources.ts'\nimport { _setCurrentTemplate } from './composables/useCurrentTemplate.ts'\nimport defu from 'defu'\nimport type { MaizzleConfig } from './types/index.ts'\n\nexport interface BuildResult {\n files: string[]\n config: MaizzleConfig\n}\n\n/**\n * Build all SFC email templates to HTML files.\n *\n * Creates a single Renderer instance, then loops through each template\n * calling render → transformers → write to disk.\n *\n * Pass a `Partial<MaizzleConfig>` to override config inline, or a string\n * to load config from a specific file path. Omit to load `maizzle.config`\n * from the working directory.\n */\nexport async function build(configInput?: Partial<MaizzleConfig> | string): Promise<BuildResult> {\n const start = Date.now()\n const spinner = ora({ text: 'Building templates...', spinner: 'circleHalves' }).start()\n\n const config = await resolveConfig(configInput)\n\n const events = new EventManager()\n events.registerConfig(config)\n await events.fireBeforeCreate({ config })\n\n const outputPath = resolve(config.output?.path ?? 'dist')\n const outputExtension = config.output?.extension ?? 'html'\n\n const contentPatterns = config.content ?? ['emails/**/*.vue']\n const contentBase = computeContentBase(contentPatterns)\n const templateFiles = await glob(contentPatterns)\n\n if (templateFiles.length === 0) {\n spinner.succeed('No templates found')\n return { files: [], config }\n }\n\n // Clear the output directory before writing fresh output\n if (existsSync(outputPath)) {\n rmSync(outputPath, { recursive: true, force: true })\n }\n\n const renderer = await createRenderer({ markdown: config.markdown, root: config.root, componentDirs: normalizeComponentSources(config.components?.source, process.cwd()), vite: config.vite })\n const outputFiles: string[] = []\n\n try {\n for (const templatePath of templateFiles) {\n const absolutePath = resolve(templatePath)\n const parsedPath = parsePath(absolutePath)\n const template = { source: readFileSync(absolutePath, 'utf-8'), path: parsedPath }\n\n _setCurrentTemplate(parsedPath)\n\n try {\n await events.fireBeforeRender({ config, template })\n\n const rendered = await renderer.render(absolutePath, config)\n\n // Register SFC event handlers collected during render so they participate\n // in the post-render events (afterRender / afterTransform). They're cleared\n // at the end of the iteration so they don't leak into the next template.\n for (const { name, handler } of rendered.sfcEventHandlers) {\n events.on(name, handler)\n }\n\n let html = await events.fireAfterRender({ config, template, html: rendered.html })\n\n // Use the per-template merged config (from defineConfig() in the SFC) so that\n // template-level overrides like css.safe: false are respected by transformers.\n const templateConfig = rendered.templateConfig\n\n const doctype = rendered.doctype ?? templateConfig.doctype ?? '<!DOCTYPE html>'\n\n if (templateConfig.useTransformers !== false) {\n html = await runTransformers(html, templateConfig, absolutePath, doctype, rendered.tailwindBlocks)\n }\n\n html = await events.fireAfterTransform({ config, template, html })\n html = `${doctype}\\n${html}`\n\n const htmlOut = stripForHtml(html)\n const outputFilePath = resolveOutputPath(templatePath, outputPath, outputExtension, contentBase)\n mkdirSync(dirname(outputFilePath), { recursive: true })\n writeFileSync(outputFilePath, htmlOut)\n outputFiles.push(outputFilePath)\n\n // Generate plaintext version if configured\n const globalPlaintext = templateConfig.plaintext\n const sfcPlaintext = rendered.plaintext\n\n if (globalPlaintext || sfcPlaintext) {\n const globalCfg = typeof globalPlaintext === 'object' ? globalPlaintext : {}\n const stripOptions = defu(sfcPlaintext?.options, globalCfg.options)\n const plaintext = createPlaintext(stripForPlaintext(html), stripOptions)\n const ptExtension = sfcPlaintext?.extension ?? globalCfg.extension ?? 'txt'\n\n let ptOutputPath: string\n\n if (sfcPlaintext?.destination) {\n const name = basename(templatePath).replace(/\\.(vue|md)$/, '')\n ptOutputPath = join(resolve(sfcPlaintext.destination), `${name}.${ptExtension}`)\n } else if (globalCfg.destination) {\n ptOutputPath = resolveOutputPath(templatePath, resolve(globalCfg.destination), ptExtension, contentBase)\n } else {\n ptOutputPath = resolveOutputPath(templatePath, outputPath, ptExtension, contentBase)\n }\n\n mkdirSync(dirname(ptOutputPath), { recursive: true })\n writeFileSync(ptOutputPath, plaintext)\n }\n } finally {\n _setCurrentTemplate(undefined)\n events.clearSfcHandlers()\n }\n }\n\n await copyStatic(config, outputPath)\n await events.fireAfterBuild({ files: outputFiles, config })\n } finally {\n await renderer.close()\n }\n\n const duration = ((Date.now() - start) / 1000).toFixed(2)\n const count = outputFiles.length\n spinner.stopAndPersist({\n symbol: '✅',\n text: `Built ${count} template${count !== 1 ? 's' : ''} in ${duration}s`,\n })\n\n return { files: outputFiles, config }\n}\n\n/**\n * Extract the static (non-glob) prefix from content patterns.\n *\n * For example, `['/abs/path/emails/**\\/*.vue']` → `'/abs/path/emails'`\n *\n * This is used to strip the content base from template paths\n * so the output preserves only the subdirectory structure.\n */\nfunction computeContentBase(patterns: string[]): string {\n // Use the first non-negated pattern\n const pattern = patterns.find(p => !p.startsWith('!')) ?? patterns[0]\n\n // Split on first glob character (* { ? [) and take the directory part\n const staticPart = pattern.split(/[*{?[]/)[0]\n\n // Ensure we have a clean directory path (not a partial segment)\n return resolve(staticPart.endsWith('/') ? staticPart : dirname(staticPart))\n}\n\nfunction resolveOutputPath(templatePath: string, outputDir: string, extension: string, contentBase: string): string {\n const name = basename(templatePath).replace(/\\.(vue|md)$/, '')\n const absTemplate = resolve(templatePath)\n const rel = relative(contentBase, dirname(absTemplate))\n\n return join(outputDir, rel, `${name}.${extension}`)\n}\n\nasync function copyStatic(config: MaizzleConfig, outputPath: string): Promise<void> {\n const sources = config.static?.source ?? ['public/**/*.*']\n const destination = config.static?.destination ?? 'public'\n\n const files = await glob(sources)\n\n for (const file of files) {\n const destPath = join(outputPath, destination, relative(dirname(sources[0]).replace(/\\*.*$/, ''), file))\n const destDir = dirname(destPath)\n\n if (!existsSync(destDir)) {\n mkdirSync(destDir, { recursive: true })\n }\n\n cpSync(file, destPath)\n }\n}\n"],"mappings":"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"}
|
|
@@ -0,0 +1,128 @@
|
|
|
1
|
+
<script setup lang="ts">
|
|
2
|
+
import { createStaticVNode, inject, useAttrs, useSlots } from 'vue'
|
|
3
|
+
import type { PropType } from 'vue'
|
|
4
|
+
import { outlookFallbackProp } from './utils.ts'
|
|
5
|
+
import { useOutlookFallback } from '../composables/useOutlookFallback'
|
|
6
|
+
|
|
7
|
+
defineOptions({ inheritAttrs: false })
|
|
8
|
+
|
|
9
|
+
const attrs = useAttrs()
|
|
10
|
+
const slots = useSlots()
|
|
11
|
+
|
|
12
|
+
const props = defineProps({
|
|
13
|
+
/**
|
|
14
|
+
* Language code for the `xml:lang` attribute on `<body>`.
|
|
15
|
+
*
|
|
16
|
+
* Inherited from the parent `Html` component's `lang` prop by default.
|
|
17
|
+
*
|
|
18
|
+
* @example 'fr'
|
|
19
|
+
*/
|
|
20
|
+
xmlLang: {
|
|
21
|
+
type: String as PropType<
|
|
22
|
+
| 'af' | 'ar' | 'az'
|
|
23
|
+
| 'be' | 'bg' | 'bs'
|
|
24
|
+
| 'ca' | 'cs' | 'cy'
|
|
25
|
+
| 'da' | 'de' | 'dv'
|
|
26
|
+
| 'el' | 'en' | 'es' | 'et' | 'eu'
|
|
27
|
+
| 'fa' | 'fi' | 'fo' | 'fr'
|
|
28
|
+
| 'gl' | 'gu'
|
|
29
|
+
| 'he' | 'hi' | 'hr' | 'hu' | 'hy'
|
|
30
|
+
| 'id' | 'is' | 'it'
|
|
31
|
+
| 'ja'
|
|
32
|
+
| 'ka' | 'kk' | 'kn' | 'ko' | 'ky'
|
|
33
|
+
| 'lt' | 'lv'
|
|
34
|
+
| 'mk' | 'mn' | 'mr' | 'ms' | 'mt'
|
|
35
|
+
| 'nb' | 'nl' | 'nn' | 'no'
|
|
36
|
+
| 'pa' | 'pl' | 'pt'
|
|
37
|
+
| 'ro' | 'ru'
|
|
38
|
+
| 'sa' | 'se' | 'sk' | 'sl' | 'sq' | 'sr' | 'sv' | 'sw'
|
|
39
|
+
| 'ta' | 'te' | 'th' | 'tr' | 'tt'
|
|
40
|
+
| 'uk' | 'ur' | 'uz'
|
|
41
|
+
| 'vi'
|
|
42
|
+
| 'zh'
|
|
43
|
+
| (string & {})
|
|
44
|
+
>,
|
|
45
|
+
default: undefined
|
|
46
|
+
},
|
|
47
|
+
/**
|
|
48
|
+
* Text direction of the body.
|
|
49
|
+
*
|
|
50
|
+
* - `ltr` — left to right (default)
|
|
51
|
+
* - `rtl` — right to left
|
|
52
|
+
*
|
|
53
|
+
* @default 'ltr'
|
|
54
|
+
*/
|
|
55
|
+
dir: {
|
|
56
|
+
type: String as PropType<'ltr' | 'rtl'>,
|
|
57
|
+
default: 'ltr'
|
|
58
|
+
},
|
|
59
|
+
/**
|
|
60
|
+
* Accessible label for the email article wrapper.
|
|
61
|
+
*
|
|
62
|
+
* Used as the `aria-label` on the inner `<div role="article">`.
|
|
63
|
+
* Helps screen readers identify the email content.
|
|
64
|
+
*
|
|
65
|
+
* @example 'Order confirmation'
|
|
66
|
+
*/
|
|
67
|
+
ariaLabel: {
|
|
68
|
+
type: String,
|
|
69
|
+
default: undefined
|
|
70
|
+
},
|
|
71
|
+
/**
|
|
72
|
+
* Toggle Outlook (MSO) and VML fallback markup for this
|
|
73
|
+
* component and all descendants.
|
|
74
|
+
*
|
|
75
|
+
* When `false`, skips MSO ghost tables, VML shapes,
|
|
76
|
+
* `xmlns:v`/`xmlns:o` attributes, and mso-specific CSS
|
|
77
|
+
* in all built-in components.
|
|
78
|
+
*
|
|
79
|
+
* @default true
|
|
80
|
+
*/
|
|
81
|
+
outlookFallback: outlookFallbackProp,
|
|
82
|
+
})
|
|
83
|
+
|
|
84
|
+
const outlookFallback = useOutlookFallback(props.outlookFallback)
|
|
85
|
+
|
|
86
|
+
const htmlLang = inject<string>('htmlLang', 'en')
|
|
87
|
+
|
|
88
|
+
const render = () => {
|
|
89
|
+
const extraAttrs = Object.entries(attrs)
|
|
90
|
+
.map(([key, value]) => value === true ? key : `${key}="${value}"`)
|
|
91
|
+
.join(' ')
|
|
92
|
+
|
|
93
|
+
const lang = props.xmlLang ?? htmlLang
|
|
94
|
+
|
|
95
|
+
const parts = [
|
|
96
|
+
`dir="${props.dir}"`,
|
|
97
|
+
'style="margin: 0; padding: 0; width: 100%; word-break: break-word;"',
|
|
98
|
+
]
|
|
99
|
+
if (outlookFallback) {
|
|
100
|
+
parts.unshift(`xml:lang="${lang}"`)
|
|
101
|
+
}
|
|
102
|
+
|
|
103
|
+
if (extraAttrs) {
|
|
104
|
+
parts.push(extraAttrs)
|
|
105
|
+
}
|
|
106
|
+
|
|
107
|
+
const articleParts = [
|
|
108
|
+
'role="article"',
|
|
109
|
+
'aria-roledescription="email"',
|
|
110
|
+
props.ariaLabel ? `aria-label="${props.ariaLabel}"` : '',
|
|
111
|
+
`lang="${lang}"`,
|
|
112
|
+
`dir="${props.dir}"`,
|
|
113
|
+
'style="font-size: medium; font-size: max(16px, 1rem)"',
|
|
114
|
+
].filter(Boolean).join(' ')
|
|
115
|
+
|
|
116
|
+
return [
|
|
117
|
+
createStaticVNode(`<body ${parts.join(' ')}>`, 1),
|
|
118
|
+
createStaticVNode(`<div ${articleParts}>`, 1),
|
|
119
|
+
slots.default?.(),
|
|
120
|
+
createStaticVNode('</div>', 1),
|
|
121
|
+
createStaticVNode('</body>', 1),
|
|
122
|
+
]
|
|
123
|
+
}
|
|
124
|
+
</script>
|
|
125
|
+
|
|
126
|
+
<template>
|
|
127
|
+
<render />
|
|
128
|
+
</template>
|
|
@@ -1,7 +1,9 @@
|
|
|
1
1
|
<script setup lang="ts">
|
|
2
|
-
import { computed, useAttrs } from 'vue'
|
|
2
|
+
import { computed, useAttrs, createStaticVNode } from 'vue'
|
|
3
|
+
import type { PropType } from 'vue'
|
|
3
4
|
import { twMerge } from 'tailwind-merge'
|
|
4
|
-
import
|
|
5
|
+
import { outlookFallbackProp } from './utils.ts'
|
|
6
|
+
import { useOutlookFallback } from '../composables/useOutlookFallback'
|
|
5
7
|
|
|
6
8
|
defineOptions({ inheritAttrs: false })
|
|
7
9
|
|
|
@@ -9,69 +11,127 @@ const attrs = useAttrs()
|
|
|
9
11
|
|
|
10
12
|
const props = defineProps({
|
|
11
13
|
/** The URL the button links to. */
|
|
12
|
-
href:
|
|
13
|
-
type: {
|
|
14
|
+
href: {
|
|
14
15
|
type: String,
|
|
15
|
-
|
|
16
|
+
required: true
|
|
16
17
|
},
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
18
|
+
/**
|
|
19
|
+
* The button style variant.
|
|
20
|
+
* - `solid` — filled background (default)
|
|
21
|
+
* - `outline` — transparent background with a border
|
|
22
|
+
* - `ghost` — transparent background, no border
|
|
23
|
+
* - `link` — plain anchor with no button chrome
|
|
24
|
+
* @default 'solid'
|
|
25
|
+
*/
|
|
26
|
+
variant: {
|
|
27
|
+
type: String as PropType<'solid' | 'outline' | 'ghost' | 'link'>,
|
|
28
|
+
default: 'solid' as const
|
|
24
29
|
},
|
|
25
|
-
|
|
26
|
-
|
|
30
|
+
/**
|
|
31
|
+
* Horizontal alignment of the button wrapper.
|
|
32
|
+
* Accepts `'left'`, `'center'`, or `'right'`.
|
|
33
|
+
* @default null
|
|
34
|
+
*/
|
|
35
|
+
align: {
|
|
36
|
+
type: String as PropType<'left' | 'center' | 'right' | null>,
|
|
27
37
|
default: null
|
|
28
38
|
},
|
|
39
|
+
/**
|
|
40
|
+
* `mso-text-raise` value applied to the inner `<span>` elements.
|
|
41
|
+
* Controls vertical text alignment inside the button in old Outlook.
|
|
42
|
+
* @default '16px'
|
|
43
|
+
*/
|
|
29
44
|
msoPt: {
|
|
30
45
|
type: String,
|
|
31
46
|
default: '16px'
|
|
32
47
|
},
|
|
48
|
+
/**
|
|
49
|
+
* `mso-text-raise` value applied to the spacer `<i>` element rendered for Outlook.
|
|
50
|
+
* Adjusts the bottom spacing that old Outlook uses to simulate padding.
|
|
51
|
+
* @default '31px'
|
|
52
|
+
*/
|
|
33
53
|
msoPb: {
|
|
34
54
|
type: String,
|
|
35
55
|
default: '31px'
|
|
36
56
|
},
|
|
57
|
+
/**
|
|
58
|
+
* URL or path to an icon image displayed alongside the button label.
|
|
59
|
+
* @default null
|
|
60
|
+
*/
|
|
37
61
|
icon: {
|
|
38
62
|
type: String,
|
|
39
63
|
default: null
|
|
40
64
|
},
|
|
65
|
+
/**
|
|
66
|
+
* Width of the icon image in pixels.
|
|
67
|
+
* @default 12
|
|
68
|
+
*/
|
|
41
69
|
iconWidth: {
|
|
42
70
|
type: [String, Number],
|
|
43
71
|
default: 12
|
|
44
72
|
},
|
|
73
|
+
/**
|
|
74
|
+
* Side on which the icon is placed relative to the button label.
|
|
75
|
+
* Accepts `'left'` or `'right'`.
|
|
76
|
+
* @default 'right'
|
|
77
|
+
*/
|
|
45
78
|
iconPosition: {
|
|
46
|
-
type: String
|
|
47
|
-
default: 'right'
|
|
79
|
+
type: String as PropType<'left' | 'right'>,
|
|
80
|
+
default: 'right' as const
|
|
48
81
|
},
|
|
82
|
+
/**
|
|
83
|
+
* Additional CSS classes applied to the icon `<img>` element.
|
|
84
|
+
* @default ''
|
|
85
|
+
*/
|
|
49
86
|
iconClass: {
|
|
50
87
|
type: String,
|
|
51
88
|
default: ''
|
|
52
|
-
}
|
|
89
|
+
},
|
|
90
|
+
/**
|
|
91
|
+
* Alt text for the icon image.
|
|
92
|
+
* @default ''
|
|
93
|
+
*/
|
|
94
|
+
iconAlt: {
|
|
95
|
+
type: String,
|
|
96
|
+
default: ''
|
|
97
|
+
},
|
|
98
|
+
/**
|
|
99
|
+
* Horizontal padding in old Outlook, applied as `mso-font-width` on the
|
|
100
|
+
* outer spacer `<i>` elements. Accepts a number, a numeric string, or a
|
|
101
|
+
* string with `%`. Bare numbers are treated as percentages. Effective
|
|
102
|
+
* range up to 500%.
|
|
103
|
+
* @default 150
|
|
104
|
+
*/
|
|
105
|
+
msoPx: {
|
|
106
|
+
type: [String, Number],
|
|
107
|
+
default: 150
|
|
108
|
+
},
|
|
109
|
+
/**
|
|
110
|
+
* Toggle Outlook (MSO) and VML fallback markup for this
|
|
111
|
+
* component and all descendants.
|
|
112
|
+
*
|
|
113
|
+
* When `false`, skips MSO ghost tables, VML shapes,
|
|
114
|
+
* `xmlns:v`/`xmlns:o` attributes, and mso-specific CSS
|
|
115
|
+
* in all built-in components.
|
|
116
|
+
*
|
|
117
|
+
* @default true
|
|
118
|
+
*/
|
|
119
|
+
outlookFallback: outlookFallbackProp,
|
|
53
120
|
})
|
|
54
121
|
|
|
122
|
+
const outlookFallback = useOutlookFallback(props.outlookFallback)
|
|
123
|
+
|
|
55
124
|
const parsedIconWidth = computed(() => parseInt(String(props.iconWidth), 10))
|
|
56
125
|
|
|
57
|
-
const alignClass = computed(() => ({
|
|
126
|
+
const alignClass = computed(() => props.align ? ({
|
|
58
127
|
left: 'text-left',
|
|
59
128
|
center: 'text-center',
|
|
60
129
|
right: 'text-right',
|
|
61
|
-
})[props.align] || '')
|
|
62
|
-
|
|
63
|
-
const textColor = computed(() => {
|
|
64
|
-
if (props.color) return props.color
|
|
65
|
-
|
|
66
|
-
return props.type === 'solid' ? '#fffffe' : props.bgColor
|
|
67
|
-
})
|
|
130
|
+
})[props.align] || '' : '')
|
|
68
131
|
|
|
69
132
|
const styles = computed(() => {
|
|
70
|
-
if (props.
|
|
71
|
-
return
|
|
72
|
-
'text-decoration: none;',
|
|
73
|
-
`color: ${textColor.value};`,
|
|
74
|
-
].join('')
|
|
133
|
+
if (props.variant === 'link') {
|
|
134
|
+
return 'text-decoration: none; color: #4338ca;'
|
|
75
135
|
}
|
|
76
136
|
|
|
77
137
|
const base = [
|
|
@@ -81,57 +141,93 @@ const styles = computed(() => {
|
|
|
81
141
|
'font-size: 16px;',
|
|
82
142
|
'line-height: 1;',
|
|
83
143
|
'border-radius: 4px;',
|
|
84
|
-
`color: ${textColor.value};`,
|
|
85
144
|
]
|
|
86
145
|
|
|
87
|
-
if (props.
|
|
146
|
+
if (props.variant === 'outline') {
|
|
147
|
+
base.push(
|
|
148
|
+
'background-color: transparent;',
|
|
149
|
+
'border: 1px solid #4338ca;',
|
|
150
|
+
'color: #4338ca;',
|
|
151
|
+
)
|
|
152
|
+
} else if (props.variant === 'ghost') {
|
|
88
153
|
base.push(
|
|
89
154
|
'background-color: transparent;',
|
|
90
|
-
|
|
155
|
+
'color: #4338ca;',
|
|
91
156
|
)
|
|
92
|
-
} else if (props.type === 'ghost') {
|
|
93
|
-
base.push('background-color: transparent;')
|
|
94
157
|
} else {
|
|
95
|
-
base.push(
|
|
158
|
+
base.push(
|
|
159
|
+
'background-color: #4338ca;',
|
|
160
|
+
'color: #fffffe;',
|
|
161
|
+
)
|
|
96
162
|
}
|
|
97
163
|
|
|
98
164
|
return base.join('')
|
|
99
165
|
})
|
|
100
166
|
|
|
101
|
-
const isLink = computed(() => props.
|
|
167
|
+
const isLink = computed(() => props.variant === 'link')
|
|
168
|
+
|
|
169
|
+
const variantClasses = computed(() =>
|
|
170
|
+
props.variant === 'ghost' ? 'hover:bg-indigo-50' : '',
|
|
171
|
+
)
|
|
172
|
+
|
|
173
|
+
const mergedClass = computed(() => twMerge(variantClasses.value, attrs.class as string))
|
|
102
174
|
|
|
103
|
-
const
|
|
104
|
-
|
|
105
|
-
|
|
175
|
+
const textSpanStyle = computed(() =>
|
|
176
|
+
outlookFallback ? `mso-text-raise: ${props.msoPt};` : undefined,
|
|
177
|
+
)
|
|
178
|
+
|
|
179
|
+
const msoPx = computed(() => {
|
|
180
|
+
const v = String(props.msoPx).trim()
|
|
181
|
+
// Bare number → percentage. Anything with a unit passes through.
|
|
182
|
+
return /^\d+(\.\d+)?$/.test(v) ? `${v}%` : v
|
|
106
183
|
})
|
|
107
184
|
|
|
108
|
-
|
|
185
|
+
/**
|
|
186
|
+
* Outlook spacer `<i>` elements rendered as raw HTML inside MSO conditional
|
|
187
|
+
* comments. JS strings keep ` ` / `​` from being decoded by
|
|
188
|
+
* Vue's template parser; htmlparser2 then preserves the comment
|
|
189
|
+
* data verbatim because conditional comments are opaque.
|
|
190
|
+
*/
|
|
191
|
+
const MsoSpacerLeft = () => createStaticVNode(
|
|
192
|
+
`<!--[if mso]><i style="mso-font-width: ${msoPx.value}; mso-text-raise: ${props.msoPb};" hidden> </i><![endif]-->`,
|
|
193
|
+
1,
|
|
194
|
+
)
|
|
195
|
+
|
|
196
|
+
const MsoSpacerRight = () => createStaticVNode(
|
|
197
|
+
`<!--[if mso]><i style="mso-font-width: ${msoPx.value};" hidden> ​</i><![endif]-->`,
|
|
198
|
+
1,
|
|
199
|
+
)
|
|
200
|
+
|
|
201
|
+
const MsoIconGap = () => createStaticVNode(
|
|
202
|
+
`<!--[if mso]><i style="mso-font-width: 30%;" hidden> ​</i><![endif]-->`,
|
|
203
|
+
1,
|
|
204
|
+
)
|
|
109
205
|
</script>
|
|
110
206
|
|
|
111
207
|
<template>
|
|
112
208
|
<div :class="alignClass">
|
|
113
209
|
<a
|
|
114
|
-
v-bind="{ ...$attrs, class: undefined }"
|
|
210
|
+
v-bind="{ ...$attrs, class: undefined, style: undefined }"
|
|
115
211
|
:href="href"
|
|
116
|
-
:style="styles"
|
|
212
|
+
:style="[styles, $attrs.style as any]"
|
|
117
213
|
:class="mergedClass"
|
|
118
214
|
>
|
|
119
215
|
<template v-if="!isLink">
|
|
120
|
-
<
|
|
216
|
+
<MsoSpacerLeft v-if="outlookFallback" />
|
|
121
217
|
<template v-if="icon && iconPosition === 'left'">
|
|
122
|
-
<span :style="
|
|
123
|
-
<img :src="icon" :width="parsedIconWidth" :
|
|
218
|
+
<span :style="textSpanStyle">
|
|
219
|
+
<img :src="icon" :width="parsedIconWidth" :alt="iconAlt" style="vertical-align: baseline; max-width: 100%;" :class="iconClass">
|
|
124
220
|
</span>
|
|
125
|
-
<
|
|
221
|
+
<MsoIconGap v-if="outlookFallback" />
|
|
126
222
|
</template>
|
|
127
|
-
<span :
|
|
223
|
+
<span :style="textSpanStyle"><slot /></span>
|
|
128
224
|
<template v-if="icon && iconPosition === 'right'">
|
|
129
|
-
<
|
|
130
|
-
<span :style="
|
|
131
|
-
<img :src="icon" :width="parsedIconWidth" :
|
|
225
|
+
<MsoIconGap v-if="outlookFallback" />
|
|
226
|
+
<span :style="textSpanStyle">
|
|
227
|
+
<img :src="icon" :width="parsedIconWidth" :alt="iconAlt" style="vertical-align: baseline; max-width: 100%;" :class="iconClass">
|
|
132
228
|
</span>
|
|
133
229
|
</template>
|
|
134
|
-
<
|
|
230
|
+
<MsoSpacerRight v-if="outlookFallback" />
|
|
135
231
|
</template>
|
|
136
232
|
<template v-else>
|
|
137
233
|
<slot />
|