@maizzle/framework 6.0.0-rc.7 → 6.0.0-rc.8
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/dist/components/Body.vue +105 -36
- package/dist/components/Button.vue +4 -1
- package/dist/components/CodeBlock.vue +1 -1
- package/dist/components/CodeInline.vue +6 -1
- package/dist/components/Column.vue +30 -5
- package/dist/components/Container.vue +10 -2
- package/dist/components/Divider.vue +28 -0
- package/dist/components/Head.vue +22 -0
- package/dist/components/Heading.vue +28 -0
- package/dist/components/Html.vue +98 -47
- package/dist/components/Layout.vue +93 -0
- package/dist/components/Link.vue +26 -0
- package/dist/components/Markdown.vue +15 -2
- package/dist/components/Outlook.vue +36 -0
- package/dist/components/Overlap.vue +25 -5
- package/dist/components/Preheader.vue +1 -1
- package/dist/components/Row.vue +16 -5
- package/dist/components/Section.vue +83 -0
- package/dist/components/Text.vue +29 -0
- package/dist/components/Vml.vue +165 -13
- package/dist/render/createRenderer.d.mts.map +1 -1
- package/dist/render/createRenderer.mjs +13 -1
- package/dist/render/createRenderer.mjs.map +1 -1
- package/dist/serve.mjs +1 -1
- package/dist/serve.mjs.map +1 -1
- package/dist/server/compatibility.mjs +15 -1
- package/dist/server/compatibility.mjs.map +1 -1
- package/dist/server/email.mjs +2 -1
- package/dist/server/email.mjs.map +1 -1
- package/dist/server/linter.d.mts +1 -2
- package/dist/server/linter.d.mts.map +1 -1
- package/dist/server/linter.mjs +60 -71
- package/dist/server/linter.mjs.map +1 -1
- package/dist/server/ui/App.vue +9 -9
- package/dist/server/ui/pages/Preview.vue +215 -150
- package/dist/transformers/inlineCSS.d.mts +1 -14
- package/dist/transformers/inlineCSS.d.mts.map +1 -1
- package/dist/transformers/inlineCSS.mjs +16 -34
- package/dist/transformers/inlineCSS.mjs.map +1 -1
- package/dist/types/config.d.mts +11 -27
- package/dist/types/config.d.mts.map +1 -1
- package/package.json +1 -1
|
@@ -20,10 +20,10 @@ export default {
|
|
|
20
20
|
type: String as PropType<BundledTheme>,
|
|
21
21
|
default: 'github-dark-high-contrast'
|
|
22
22
|
},
|
|
23
|
-
/** Wrap output in a div element. @default
|
|
23
|
+
/** Wrap output in a div element. @default false */
|
|
24
24
|
wrapper: {
|
|
25
25
|
type: Boolean,
|
|
26
|
-
default:
|
|
26
|
+
default: false
|
|
27
27
|
},
|
|
28
28
|
},
|
|
29
29
|
inheritAttrs: false,
|
|
@@ -56,6 +56,19 @@ export default {
|
|
|
56
56
|
},
|
|
57
57
|
})
|
|
58
58
|
|
|
59
|
+
const wrapPre = (html: string) =>
|
|
60
|
+
`<table class="w-full"><tr><td class="max-w-0 mso-padding-alt-4">${html}</td></tr></table>\n`
|
|
61
|
+
|
|
62
|
+
const defaultFence = md.renderer.rules.fence!
|
|
63
|
+
md.renderer.rules.fence = (...args) => {
|
|
64
|
+
const result = defaultFence(...args)
|
|
65
|
+
if (typeof result === 'string') return wrapPre(result)
|
|
66
|
+
return result.then(wrapPre)
|
|
67
|
+
}
|
|
68
|
+
|
|
69
|
+
const defaultCodeBlock = md.renderer.rules.code_block!
|
|
70
|
+
md.renderer.rules.code_block = (...args) => wrapPre(defaultCodeBlock(...args) as string)
|
|
71
|
+
|
|
59
72
|
let html = await md.renderAsync(source)
|
|
60
73
|
|
|
61
74
|
if (props.wrapper) {
|
|
@@ -22,11 +22,47 @@ const parseList = (value: string) =>
|
|
|
22
22
|
export default {
|
|
23
23
|
name: 'Outlook',
|
|
24
24
|
props: {
|
|
25
|
+
/**
|
|
26
|
+
* Render content only in the specified Outlook version(s).
|
|
27
|
+
*
|
|
28
|
+
* Comma-separated list of years.
|
|
29
|
+
*
|
|
30
|
+
* @example '2013'
|
|
31
|
+
* @example '2013,2016'
|
|
32
|
+
*/
|
|
25
33
|
only: String,
|
|
34
|
+
/**
|
|
35
|
+
* Render content in all Outlook versions except the specified one(s).
|
|
36
|
+
*
|
|
37
|
+
* Comma-separated list of years.
|
|
38
|
+
*
|
|
39
|
+
* @example '2007'
|
|
40
|
+
* @example '2007,2010'
|
|
41
|
+
*/
|
|
26
42
|
not: String,
|
|
43
|
+
/**
|
|
44
|
+
* Render content in Outlook versions lower than the specified year.
|
|
45
|
+
*
|
|
46
|
+
* @example '2013'
|
|
47
|
+
*/
|
|
27
48
|
lt: String,
|
|
49
|
+
/**
|
|
50
|
+
* Render content in Outlook versions lower than or equal to the specified year.
|
|
51
|
+
*
|
|
52
|
+
* @example '2013'
|
|
53
|
+
*/
|
|
28
54
|
lte: String,
|
|
55
|
+
/**
|
|
56
|
+
* Render content in Outlook versions greater than the specified year.
|
|
57
|
+
*
|
|
58
|
+
* @example '2010'
|
|
59
|
+
*/
|
|
29
60
|
gt: String,
|
|
61
|
+
/**
|
|
62
|
+
* Render content in Outlook versions greater than or equal to the specified year.
|
|
63
|
+
*
|
|
64
|
+
* @example '2010'
|
|
65
|
+
*/
|
|
30
66
|
gte: String
|
|
31
67
|
},
|
|
32
68
|
setup(props, { slots }) {
|
|
@@ -7,22 +7,42 @@ defineOptions({ inheritAttrs: false })
|
|
|
7
7
|
const attrs = useAttrs()
|
|
8
8
|
|
|
9
9
|
const props = defineProps({
|
|
10
|
-
/**
|
|
10
|
+
/**
|
|
11
|
+
* Max height of the background (default slot) content.
|
|
12
|
+
*
|
|
13
|
+
* This constrains the visible area of the background layer.
|
|
14
|
+
*/
|
|
11
15
|
height: {
|
|
12
16
|
type: [String, Number],
|
|
13
17
|
required: true
|
|
14
18
|
},
|
|
15
|
-
/**
|
|
19
|
+
/**
|
|
20
|
+
* Width of the overlay table and VML rectangle.
|
|
21
|
+
*
|
|
22
|
+
* Should match the width of the content being overlapped.
|
|
23
|
+
*/
|
|
16
24
|
width: {
|
|
17
25
|
type: [String, Number],
|
|
18
26
|
required: true
|
|
19
27
|
},
|
|
20
|
-
/**
|
|
28
|
+
/**
|
|
29
|
+
* Height of the VML rectangle in Outlook.
|
|
30
|
+
*
|
|
31
|
+
* Defaults to the `height` prop value. Use this to fine-tune
|
|
32
|
+
* the overlay height specifically for Outlook rendering.
|
|
33
|
+
*/
|
|
21
34
|
msoHeight: {
|
|
22
35
|
type: [String, Number],
|
|
23
36
|
default: null
|
|
24
37
|
},
|
|
25
|
-
/**
|
|
38
|
+
/**
|
|
39
|
+
* VML textbox inset for Outlook positioning.
|
|
40
|
+
*
|
|
41
|
+
* Controls the offset of the overlay content as `top,right,bottom,left`.
|
|
42
|
+
* Use negative values to shift content upward into the background area.
|
|
43
|
+
*
|
|
44
|
+
* @default '0,-60px,0,0'
|
|
45
|
+
*/
|
|
26
46
|
msoInset: {
|
|
27
47
|
type: String,
|
|
28
48
|
default: '0,-60px,0,0'
|
|
@@ -37,7 +57,7 @@ const vmlOpen = computed(() => {
|
|
|
37
57
|
const w = normalizeToPixels(props.width)
|
|
38
58
|
const h = normalizeToPixels(props.msoHeight ?? props.height)
|
|
39
59
|
|
|
40
|
-
return `<!--[if mso]><v:rect xmlns:v="urn:schemas-microsoft-com:vml" stroked="f" filled="f" style="width
|
|
60
|
+
return `<!--[if mso]><v:rect xmlns:v="urn:schemas-microsoft-com:vml" stroked="f" filled="f" style="width: ${w}; height: ${h};"><v:textbox inset="${props.msoInset}"><![endif]-->`
|
|
41
61
|
})
|
|
42
62
|
|
|
43
63
|
const VmlBefore = () => createStaticVNode(vmlOpen.value, 1)
|
|
@@ -15,6 +15,6 @@ defineProps({
|
|
|
15
15
|
|
|
16
16
|
<template>
|
|
17
17
|
<Teleport to="body:start">
|
|
18
|
-
<div style="display:none"><slot /><template v-for="i in fillerCount" :key="'f'+i"> ͏ </template><template v-for="i in shyCount" :key="'s'+i">­ </template> </div>
|
|
18
|
+
<div style="display: none"><slot /><template v-for="i in fillerCount" :key="'f'+i"> ͏ </template><template v-for="i in shyCount" :key="'s'+i">­ </template> </div>
|
|
19
19
|
</Teleport>
|
|
20
20
|
</template>
|
package/dist/components/Row.vue
CHANGED
|
@@ -7,12 +7,23 @@ defineOptions({ inheritAttrs: false })
|
|
|
7
7
|
const attrs = useAttrs()
|
|
8
8
|
|
|
9
9
|
const props = defineProps({
|
|
10
|
-
/**
|
|
10
|
+
/**
|
|
11
|
+
* Override the inherited container width.
|
|
12
|
+
*
|
|
13
|
+
* Used to calculate column widths. Inherited from the
|
|
14
|
+
* parent `Container` by default.
|
|
15
|
+
*/
|
|
11
16
|
width: {
|
|
12
17
|
type: [String, Number],
|
|
13
18
|
default: null
|
|
14
19
|
},
|
|
15
|
-
/**
|
|
20
|
+
/**
|
|
21
|
+
* Override the auto-detected column count.
|
|
22
|
+
*
|
|
23
|
+
* By default, the number of direct child elements is used.
|
|
24
|
+
* Set this when the auto-detection doesn't match your layout
|
|
25
|
+
* (e.g. when using `v-if` or `v-for`).
|
|
26
|
+
*/
|
|
16
27
|
cols: {
|
|
17
28
|
type: Number,
|
|
18
29
|
default: null
|
|
@@ -48,13 +59,13 @@ const rowWidth = computed(() => props.width ?? containerWidth?.value ?? '37.5em'
|
|
|
48
59
|
|
|
49
60
|
function divideValue(value: string | number, divisor: number): string {
|
|
50
61
|
if (typeof value === 'number') {
|
|
51
|
-
return `${value / divisor}px`
|
|
62
|
+
return `${parseFloat((value / divisor).toFixed(2))}px`
|
|
52
63
|
}
|
|
53
64
|
|
|
54
65
|
const num = Number.parseFloat(value)
|
|
55
66
|
const unit = value.replace(String(num), '') || 'px'
|
|
56
67
|
|
|
57
|
-
return `${num / divisor}${unit}`
|
|
68
|
+
return `${parseFloat((num / divisor).toFixed(2))}${unit}`
|
|
58
69
|
}
|
|
59
70
|
|
|
60
71
|
provide('columnMinWidth', computed(() => divideValue(rowWidth.value, columnCount.value)))
|
|
@@ -73,7 +84,7 @@ const MsoAfter = () => createStaticVNode(
|
|
|
73
84
|
|
|
74
85
|
<template>
|
|
75
86
|
<MsoBefore />
|
|
76
|
-
<div v-bind="attrs" style="
|
|
87
|
+
<div v-bind="attrs" style="font-size: 0;">
|
|
77
88
|
<slot />
|
|
78
89
|
</div>
|
|
79
90
|
<MsoAfter />
|
|
@@ -0,0 +1,83 @@
|
|
|
1
|
+
<script setup lang="ts">
|
|
2
|
+
import { computed, createStaticVNode, useAttrs } from 'vue'
|
|
3
|
+
import { normalizeToPixels } from './utils.ts'
|
|
4
|
+
|
|
5
|
+
defineOptions({ inheritAttrs: false })
|
|
6
|
+
|
|
7
|
+
const attrs = useAttrs()
|
|
8
|
+
|
|
9
|
+
const props = defineProps({
|
|
10
|
+
/**
|
|
11
|
+
* Width of the section.
|
|
12
|
+
*
|
|
13
|
+
* Applied as `max-width` on the div and as `width` on the MSO table.
|
|
14
|
+
*
|
|
15
|
+
* @default '100%'
|
|
16
|
+
*/
|
|
17
|
+
width: {
|
|
18
|
+
type: [String, Number],
|
|
19
|
+
default: '100%'
|
|
20
|
+
},
|
|
21
|
+
/**
|
|
22
|
+
* Inline CSS applied only to the MSO `<td>` element.
|
|
23
|
+
*
|
|
24
|
+
* Use for Outlook-specific styling that shouldn't affect other clients.
|
|
25
|
+
*
|
|
26
|
+
* @example 'padding: 10px 20px'
|
|
27
|
+
*/
|
|
28
|
+
msoStyle: {
|
|
29
|
+
type: String,
|
|
30
|
+
default: undefined
|
|
31
|
+
}
|
|
32
|
+
})
|
|
33
|
+
|
|
34
|
+
const hasCustomWidth = computed(() => props.width !== '100%')
|
|
35
|
+
|
|
36
|
+
const userStyle = computed(() => {
|
|
37
|
+
const s = attrs.style
|
|
38
|
+
if (!s) return ''
|
|
39
|
+
return typeof s === 'object'
|
|
40
|
+
? Object.entries(s).map(([k, v]) => `${k.replace(/([A-Z])/g, '-$1').toLowerCase()}: ${v}`).join('; ')
|
|
41
|
+
: String(s)
|
|
42
|
+
})
|
|
43
|
+
|
|
44
|
+
const divStyle = computed(() => {
|
|
45
|
+
const parts: string[] = []
|
|
46
|
+
if (hasCustomWidth.value) parts.push(`max-width: ${normalizeToPixels(props.width)}`)
|
|
47
|
+
if (userStyle.value) parts.push(userStyle.value)
|
|
48
|
+
return parts.length ? parts.join('; ') : undefined
|
|
49
|
+
})
|
|
50
|
+
|
|
51
|
+
const restAttrs = computed(() => {
|
|
52
|
+
const { style: _, ...rest } = attrs
|
|
53
|
+
return rest
|
|
54
|
+
})
|
|
55
|
+
|
|
56
|
+
const tdStyles = computed(() => {
|
|
57
|
+
const parts: string[] = []
|
|
58
|
+
if (userStyle.value) parts.push(userStyle.value)
|
|
59
|
+
if (props.msoStyle) parts.push(props.msoStyle)
|
|
60
|
+
return parts.length ? parts.join('; ') : ''
|
|
61
|
+
})
|
|
62
|
+
|
|
63
|
+
const MsoBefore = () => {
|
|
64
|
+
const tdStyle = tdStyles.value ? ` style="${tdStyles.value}"` : ''
|
|
65
|
+
return createStaticVNode(
|
|
66
|
+
`<!--[if mso]><table role="none" cellpadding="0" cellspacing="0" style="width: ${normalizeToPixels(props.width)}"><tr><td${tdStyle}><![endif]-->`,
|
|
67
|
+
1
|
|
68
|
+
)
|
|
69
|
+
}
|
|
70
|
+
|
|
71
|
+
const MsoAfter = () => createStaticVNode(
|
|
72
|
+
'<!--[if mso]></td></tr></table><![endif]-->',
|
|
73
|
+
1
|
|
74
|
+
)
|
|
75
|
+
</script>
|
|
76
|
+
|
|
77
|
+
<template>
|
|
78
|
+
<MsoBefore />
|
|
79
|
+
<div v-bind="restAttrs" :style="divStyle">
|
|
80
|
+
<slot />
|
|
81
|
+
</div>
|
|
82
|
+
<MsoAfter />
|
|
83
|
+
</template>
|
|
@@ -0,0 +1,29 @@
|
|
|
1
|
+
<script setup lang="ts">
|
|
2
|
+
import { type PropType, computed, useAttrs } from 'vue'
|
|
3
|
+
import { twMerge } from 'tailwind-merge'
|
|
4
|
+
|
|
5
|
+
defineOptions({ inheritAttrs: false })
|
|
6
|
+
|
|
7
|
+
const props = defineProps({
|
|
8
|
+
/**
|
|
9
|
+
* The HTML element to render.
|
|
10
|
+
* @default 'p'
|
|
11
|
+
*/
|
|
12
|
+
as: {
|
|
13
|
+
type: String as PropType<'p' | 'span'>,
|
|
14
|
+
default: 'p',
|
|
15
|
+
validator: (v: string) => ['p', 'span'].includes(v),
|
|
16
|
+
},
|
|
17
|
+
})
|
|
18
|
+
|
|
19
|
+
const attrs = useAttrs()
|
|
20
|
+
|
|
21
|
+
const defaultClass = computed(() => props.as === 'span' ? 'text-base' : 'm-0 my-4 text-base')
|
|
22
|
+
const mergedClass = computed(() => twMerge(defaultClass.value, attrs.class as string))
|
|
23
|
+
</script>
|
|
24
|
+
|
|
25
|
+
<template>
|
|
26
|
+
<component :is="props.as" v-bind="$attrs" :class="mergedClass">
|
|
27
|
+
<slot />
|
|
28
|
+
</component>
|
|
29
|
+
</template>
|
package/dist/components/Vml.vue
CHANGED
|
@@ -1,56 +1,208 @@
|
|
|
1
1
|
<script lang="ts">
|
|
2
2
|
import { computed, createStaticVNode } from 'vue'
|
|
3
|
+
import type { PropType } from 'vue'
|
|
3
4
|
import { normalizeToPixels } from './utils.ts'
|
|
4
5
|
|
|
5
6
|
export default {
|
|
6
7
|
name: 'Vml',
|
|
7
8
|
props: {
|
|
9
|
+
/**
|
|
10
|
+
* Width of the VML rectangle.
|
|
11
|
+
*
|
|
12
|
+
* Accepts a number (treated as pixels) or a string with units.
|
|
13
|
+
*
|
|
14
|
+
* @default '600px'
|
|
15
|
+
*/
|
|
8
16
|
width: {
|
|
9
17
|
type: [String, Number],
|
|
10
18
|
default: '600px'
|
|
11
19
|
},
|
|
20
|
+
/**
|
|
21
|
+
* Height of the VML rectangle.
|
|
22
|
+
*
|
|
23
|
+
* Accepts a number (treated as pixels) or a string with units.
|
|
24
|
+
* When not set, the rectangle auto-sizes to fit its content.
|
|
25
|
+
*/
|
|
12
26
|
height: {
|
|
13
27
|
type: [String, Number],
|
|
14
28
|
default: null
|
|
15
29
|
},
|
|
30
|
+
/**
|
|
31
|
+
* VML fill type that controls how the background image is rendered.
|
|
32
|
+
*
|
|
33
|
+
* - `frame` — scale to fill the rectangle (default)
|
|
34
|
+
* - `tile` — repeat the image to fill the rectangle
|
|
35
|
+
* - `pattern` — tile at original size
|
|
36
|
+
* - `solid` — solid color fill, no image
|
|
37
|
+
* - `gradient` — linear gradient fill
|
|
38
|
+
* - `gradientradial` — radial gradient fill
|
|
39
|
+
*
|
|
40
|
+
* @default 'frame'
|
|
41
|
+
*/
|
|
16
42
|
type: {
|
|
17
|
-
type: String
|
|
43
|
+
type: String as PropType<'solid' | 'gradient' | 'gradientradial' | 'tile' | 'pattern' | 'frame'>,
|
|
18
44
|
default: 'frame'
|
|
19
45
|
},
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
46
|
+
/**
|
|
47
|
+
* Comma-separated dimensions for the fill image.
|
|
48
|
+
*
|
|
49
|
+
* Controls the rendered size of the background image.
|
|
50
|
+
*
|
|
51
|
+
* @example '300px,200px'
|
|
52
|
+
*/
|
|
53
|
+
sizes: {
|
|
54
|
+
type: String,
|
|
55
|
+
validator: (v: string) => /^[\d.]+(px|%|em|rem)?(,[\d.]+(px|%|em|rem)?)+$/.test(v.replace(/\s/g, ''))
|
|
56
|
+
},
|
|
57
|
+
/**
|
|
58
|
+
* Fill origin offset as comma-separated fractional values.
|
|
59
|
+
*
|
|
60
|
+
* Controls where the fill image anchors relative to the shape.
|
|
61
|
+
* Values are fractions of the shape's dimensions, where `0,0` is
|
|
62
|
+
* center and `-0.5,-0.5` is the top-left corner.
|
|
63
|
+
*
|
|
64
|
+
* Overridden by `backgroundPosition` if both are set.
|
|
65
|
+
*
|
|
66
|
+
* @example '0,0'
|
|
67
|
+
* @example '-0.5,-0.5'
|
|
68
|
+
*/
|
|
69
|
+
origin: {
|
|
70
|
+
type: String,
|
|
71
|
+
validator: (v: string) => /^-?[\d.]+(,-?[\d.]+)+$/.test(v.replace(/\s/g, ''))
|
|
72
|
+
},
|
|
73
|
+
/**
|
|
74
|
+
* Fill position offset as comma-separated fractional values.
|
|
75
|
+
*
|
|
76
|
+
* Controls where the fill image is positioned within the shape.
|
|
77
|
+
* Values are fractions of the shape's dimensions, where `0,0` is
|
|
78
|
+
* center and `0.5,0.5` is the bottom-right corner.
|
|
79
|
+
*
|
|
80
|
+
* Overridden by `backgroundPosition` if both are set.
|
|
81
|
+
*
|
|
82
|
+
* @example '0,0'
|
|
83
|
+
* @example '0.5,0.5'
|
|
84
|
+
*/
|
|
85
|
+
position: {
|
|
86
|
+
type: String,
|
|
87
|
+
validator: (v: string) => /^-?[\d.]+(,-?[\d.]+)+$/.test(v.replace(/\s/g, ''))
|
|
88
|
+
},
|
|
89
|
+
/**
|
|
90
|
+
* Background image position as `vertical,horizontal`.
|
|
91
|
+
*
|
|
92
|
+
* First value is the vertical axis: `top`, `center`, or `bottom`.
|
|
93
|
+
* Second value is the horizontal axis: `left`, `center`, or `right`.
|
|
94
|
+
*
|
|
95
|
+
* Convenience prop that maps to VML `origin` and `position` attributes.
|
|
96
|
+
*
|
|
97
|
+
* @example 'top,left'
|
|
98
|
+
* @example 'center,center'
|
|
99
|
+
*/
|
|
100
|
+
backgroundPosition: {
|
|
101
|
+
type: String as PropType<
|
|
102
|
+
| 'top,left' | 'top,center' | 'top,right'
|
|
103
|
+
| 'center,left' | 'center,center' | 'center,right'
|
|
104
|
+
| 'bottom,left' | 'bottom,center' | 'bottom,right'
|
|
105
|
+
>,
|
|
106
|
+
validator: (v: string) => /^(top|center|bottom),(left|center|right)$/.test(v.replace(/\s/g, ''))
|
|
107
|
+
},
|
|
108
|
+
/**
|
|
109
|
+
* Aspect ratio constraint for the fill image.
|
|
110
|
+
*
|
|
111
|
+
* - `atleast` — image is at least as large as the shape
|
|
112
|
+
* - `atmost` — image is at most as large as the shape
|
|
113
|
+
*/
|
|
114
|
+
aspect: {
|
|
115
|
+
type: String as PropType<'atleast' | 'atmost'>,
|
|
116
|
+
},
|
|
117
|
+
/**
|
|
118
|
+
* Fill color used for `solid` and `gradient` fill types.
|
|
119
|
+
*
|
|
120
|
+
* @example '#ffffff'
|
|
121
|
+
*/
|
|
24
122
|
color: String,
|
|
123
|
+
/**
|
|
124
|
+
* Text box inset (padding) as `top,right,bottom,left`.
|
|
125
|
+
*
|
|
126
|
+
* Controls the inner spacing of the `v:textbox` element.
|
|
127
|
+
*
|
|
128
|
+
* @default '0,0,0,0'
|
|
129
|
+
*/
|
|
25
130
|
inset: {
|
|
26
131
|
type: String,
|
|
27
132
|
default: '0,0,0,0'
|
|
28
133
|
},
|
|
134
|
+
/**
|
|
135
|
+
* Whether the VML rectangle has a visible border.
|
|
136
|
+
*
|
|
137
|
+
* @default false
|
|
138
|
+
*/
|
|
29
139
|
stroke: {
|
|
30
|
-
type: String,
|
|
31
|
-
default:
|
|
140
|
+
type: [Boolean, String],
|
|
141
|
+
default: false
|
|
32
142
|
},
|
|
143
|
+
/**
|
|
144
|
+
* Border color for the VML rectangle.
|
|
145
|
+
*
|
|
146
|
+
* Setting this also enables `stroke` automatically.
|
|
147
|
+
*
|
|
148
|
+
* @example '#000000'
|
|
149
|
+
*/
|
|
33
150
|
strokecolor: String,
|
|
151
|
+
/**
|
|
152
|
+
* Whether the VML rectangle has a fill.
|
|
153
|
+
*
|
|
154
|
+
* @default true
|
|
155
|
+
*/
|
|
34
156
|
fill: {
|
|
35
|
-
type: String,
|
|
36
|
-
default:
|
|
157
|
+
type: [Boolean, String],
|
|
158
|
+
default: true
|
|
37
159
|
},
|
|
160
|
+
/**
|
|
161
|
+
* Background color of the VML rectangle.
|
|
162
|
+
*
|
|
163
|
+
* Used as a fallback when the background image cannot be loaded.
|
|
164
|
+
*
|
|
165
|
+
* @default 'none'
|
|
166
|
+
* @example '#3b82f6'
|
|
167
|
+
*/
|
|
38
168
|
fillcolor: {
|
|
39
169
|
type: String,
|
|
40
170
|
default: 'none'
|
|
41
171
|
},
|
|
172
|
+
/**
|
|
173
|
+
* URL of the background image.
|
|
174
|
+
*
|
|
175
|
+
* @default 'https://via.placeholder.com/600x400'
|
|
176
|
+
*/
|
|
42
177
|
src: {
|
|
43
178
|
type: String,
|
|
44
179
|
default: 'https://via.placeholder.com/600x400'
|
|
45
180
|
}
|
|
46
181
|
},
|
|
47
182
|
setup(props, { slots }) {
|
|
183
|
+
const backgroundPositionMap: Record<string, string> = {
|
|
184
|
+
'top,left': '-0.5,-0.5',
|
|
185
|
+
'top,center': '0,-0.5',
|
|
186
|
+
'top,right': '0.5,-0.5',
|
|
187
|
+
'center,left': '-0.5,0',
|
|
188
|
+
'center,center': '0,0',
|
|
189
|
+
'center,right': '0.5,0',
|
|
190
|
+
'bottom,left': '-0.5,0.5',
|
|
191
|
+
'bottom,center': '0,0.5',
|
|
192
|
+
'bottom,right': '0.5,0.5',
|
|
193
|
+
}
|
|
194
|
+
|
|
195
|
+
const resolvedOrigin = computed(() => props.origin ?? (props.backgroundPosition ? backgroundPositionMap[props.backgroundPosition.replace(/\s/g, '')] : undefined))
|
|
196
|
+
const resolvedPosition = computed(() => props.position ?? (props.backgroundPosition ? backgroundPositionMap[props.backgroundPosition.replace(/\s/g, '')] : undefined))
|
|
197
|
+
|
|
48
198
|
const before = computed(() => {
|
|
49
199
|
const width = normalizeToPixels(props.width)
|
|
50
200
|
|
|
201
|
+
const toBool = (v: boolean | string) => v === true || v === 'true' ? 'true' : 'false'
|
|
202
|
+
|
|
51
203
|
const rectAttrs = [
|
|
52
|
-
`fill="${props.fillcolor ? '
|
|
53
|
-
`stroke="${props.strokecolor ? '
|
|
204
|
+
`fill="${props.fillcolor ? 'true' : toBool(props.fill)}"`,
|
|
205
|
+
`stroke="${props.strokecolor ? 'true' : toBool(props.stroke)}"`,
|
|
54
206
|
`style="width: ${width};${props.height ? ` height: ${normalizeToPixels(props.height)};` : ''}"`,
|
|
55
207
|
props.strokecolor ? `strokecolor="${props.strokecolor}"` : '',
|
|
56
208
|
props.fillcolor ? `fillcolor="${props.fillcolor}"` : ''
|
|
@@ -61,8 +213,8 @@ export default {
|
|
|
61
213
|
`src="${props.src}"`,
|
|
62
214
|
props.sizes ? `sizes="${props.sizes}"` : '',
|
|
63
215
|
props.aspect ? `aspect="${props.aspect}"` : '',
|
|
64
|
-
|
|
65
|
-
|
|
216
|
+
resolvedOrigin.value ? `origin="${resolvedOrigin.value}"` : '',
|
|
217
|
+
resolvedPosition.value ? `position="${resolvedPosition.value}"` : '',
|
|
66
218
|
props.color ? `color="${props.color}"` : ''
|
|
67
219
|
].filter(Boolean).join(' ')
|
|
68
220
|
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"createRenderer.d.mts","names":[],"sources":["../../src/render/createRenderer.ts"],"mappings":";;;;;
|
|
1
|
+
{"version":3,"file":"createRenderer.d.mts","names":[],"sources":["../../src/render/createRenderer.ts"],"mappings":";;;;;UAyJiB,gBAAA;EACf,IAAA;EACA,OAAA;EACA,cAAA,EAAgB,aAAA;EAChB,gBAAA,EAAkB,aAAA;EAClB,SAAA,GAAY,aAAA;AAAA;AAAA,UAGG,QAAA;EACf,MAAA,CAAO,KAAA,WAAgB,SAAA,EAAW,MAAA,EAAQ,aAAA,GAAgB,OAAA,CAAQ,gBAAA;EAClE,UAAA,CAAW,QAAA,WAAmB,OAAA;EAC9B,aAAA,IAAiB,OAAA;EACjB,KAAA,IAAS,OAAA;AAAA;AAAA,UAGM,qBAAA;EAZC;EAchB,GAAA;EAbkB;EAelB,QAAA,GAAW,cAAA;EAdC;EAgBZ,IAAA;EAhByB;EAkBzB,aAAA;AAAA;;;;;;;iBASoB,cAAA,CACpB,OAAA,GAAS,qBAAA,GACR,OAAA,CAAQ,QAAA"}
|
|
@@ -125,13 +125,25 @@ async function createRenderer(options = {}) {
|
|
|
125
125
|
Markdown(defu(markdownOptions ?? {}, {
|
|
126
126
|
headEnabled: true,
|
|
127
127
|
wrapperDiv: false,
|
|
128
|
+
wrapperClasses: "prose",
|
|
128
129
|
markdownOptions: { async highlight(code, lang) {
|
|
129
130
|
const { codeToHtml } = await import("shiki");
|
|
130
131
|
return codeToHtml(code, {
|
|
131
132
|
lang,
|
|
132
133
|
theme: shikiTheme
|
|
133
134
|
});
|
|
134
|
-
} }
|
|
135
|
+
} },
|
|
136
|
+
markdownSetup(md) {
|
|
137
|
+
const wrapPre = (html) => `<table class="w-full"><tr><td class="max-w-0 mso-padding-alt-4">${html}</td></tr></table>\n`;
|
|
138
|
+
const defaultFence = md.renderer.rules.fence;
|
|
139
|
+
md.renderer.rules.fence = (...args) => {
|
|
140
|
+
const result = defaultFence(...args);
|
|
141
|
+
if (typeof result === "string") return wrapPre(result);
|
|
142
|
+
return result.then(wrapPre);
|
|
143
|
+
};
|
|
144
|
+
const defaultCodeBlock = md.renderer.rules.code_block;
|
|
145
|
+
md.renderer.rules.code_block = (...args) => wrapPre(defaultCodeBlock(...args));
|
|
146
|
+
}
|
|
135
147
|
})),
|
|
136
148
|
AutoImport({
|
|
137
149
|
dirs: [resolve(__dirname, "../composables"), resolve(__dirname, "../filters")],
|