@dev.smartpricing/message-composer-layer 4.2.3-validations.0 → 4.2.4-maizzle.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.
@@ -44,7 +44,7 @@ const buttonStyles = computed(() => {
44
44
  props.block.settings.shape === 'square'
45
45
  ? '0px'
46
46
  : props.block.settings.shape === 'rounded'
47
- ? '8px'
47
+ ? '4px'
48
48
  : '50px',
49
49
  padding: '12px 24px',
50
50
  border: 'none',
@@ -69,7 +69,7 @@ const containerStyles = computed(() => ({
69
69
  : props.block.settings.alignment === 'center'
70
70
  ? 'center'
71
71
  : 'flex-end',
72
- padding: '16px',
72
+ padding: '0',
73
73
  }))
74
74
 
75
75
  defineOptions({
@@ -35,15 +35,16 @@ const discountCodeStyles = computed(() => {
35
35
  props.block.settings.style === 'square'
36
36
  ? '0px'
37
37
  : props.block.settings.style === 'rounded'
38
- ? '8px'
38
+ ? '4px'
39
39
  : '50px',
40
- padding: '16px 24px',
40
+ padding: '12px 8px',
41
41
  textAlign: 'center',
42
- display: 'inline-block',
43
42
  }
44
43
 
45
44
  if (props.block.settings.width === 'full_width') {
46
45
  styles.width = '100%'
46
+ } else {
47
+ styles.display = 'inline-block'
47
48
  }
48
49
 
49
50
  return styles
@@ -52,7 +53,7 @@ const discountCodeStyles = computed(() => {
52
53
  const containerStyles = computed(() => {
53
54
  return {
54
55
  backgroundColor: props.block.settings.backgroundBlock,
55
- padding: '16px',
56
+ padding: '0',
56
57
  textAlign: 'center' as const,
57
58
  }
58
59
  })
@@ -12,7 +12,6 @@ defineOptions({
12
12
 
13
13
  <template>
14
14
  <div
15
- class="py-4"
16
15
  :style="{ backgroundColor: block.settings.backgroundColor }"
17
16
  :data-testid="dividerBlockTestIds.container"
18
17
  >
@@ -38,7 +38,7 @@ defineOptions({
38
38
 
39
39
  <template>
40
40
  <div
41
- class="rounded p-2 relative"
41
+ class="relative px-[25px]"
42
42
  :style="{ backgroundColor: block.settings.backgroundColor }"
43
43
  :data-testid="footerBlockTestIds.container"
44
44
  >
@@ -72,22 +72,18 @@ defineOptions({
72
72
 
73
73
  <template>
74
74
  <div
75
- class="rounded p-4"
76
75
  :style="{ backgroundColor: block.settings.backgroundColor }"
77
76
  :data-testid="gridBlockTestIds.container"
78
77
  >
79
- <div
80
- class="grid gap-4"
81
- :class="{
82
- 'grid-cols-1': block.settings.columns === 1,
83
- 'grid-cols-2': block.settings.columns === 2,
84
- 'grid-cols-3': block.settings.columns === 3,
85
- }"
86
- >
78
+ <div class="flex items-center">
87
79
  <div
88
80
  v-for="(column, index) in block.settings.columnData"
89
81
  :key="column.id"
90
- class="min-h-32 space-y-2 rounded border border-dashed border-neutral-300 p-2 overflow-hidden"
82
+ class="overflow-hidden [&_img]:w-full self-stretch flex flex-col justify-center"
83
+ :class="
84
+ column.blocks.length === 0 ? 'min-h-32 border border-dashed border-neutral-300/50' : ''
85
+ "
86
+ :style="{ width: `${100 / block.settings.columns}%` }"
91
87
  :data-testid="`${gridBlockTestIds.column}-${column.id}`"
92
88
  >
93
89
  <!-- Column blocks -->
@@ -38,7 +38,7 @@ defineOptions({
38
38
 
39
39
  <template>
40
40
  <div
41
- class="rounded p-2 relative"
41
+ class="relative px-[25px]"
42
42
  :style="{ backgroundColor: block.settings.backgroundColor }"
43
43
  :data-testid="headingBlockTestIds.container"
44
44
  >
@@ -96,10 +96,10 @@ defineOptions({
96
96
  :data-block-id="block.id"
97
97
  :data-block-type="block.type"
98
98
  :data-testid="`${indexBlockTestIds.container}-${block.id}`"
99
- class="group relative rounded border-2 transition-colors"
99
+ class="group relative transition-colors"
100
100
  :class="{
101
- 'border-primary-500': isSelected,
102
- 'border-transparent hover:border-neutral-300': !isSelected,
101
+ 'outline-2 outline-primary-500 outline': isSelected,
102
+ 'outline-transparent hover:outline-2 hover:outline-neutral-300 hover:outline': !isSelected,
103
103
  'cursor-move': showDragHandle,
104
104
  }"
105
105
  @click.stop="handleClick"
@@ -153,3 +153,14 @@ defineOptions({
153
153
  </div>
154
154
  </UPopover>
155
155
  </template>
156
+
157
+ <style scoped>
158
+ :deep(.ProseMirror ul) {
159
+ list-style-type: disc;
160
+ padding-left: 1.5em;
161
+ }
162
+ :deep(.ProseMirror ol) {
163
+ list-style-type: decimal;
164
+ padding-left: 1.5em;
165
+ }
166
+ </style>
@@ -38,7 +38,7 @@ defineOptions({
38
38
 
39
39
  <template>
40
40
  <div
41
- class="rounded p-2 relative"
41
+ class="relative px-[25px]"
42
42
  :style="{ backgroundColor: block.settings.backgroundColor }"
43
43
  :data-testid="paragraphBlockTestIds.container"
44
44
  >
@@ -36,7 +36,7 @@ defineOptions({
36
36
 
37
37
  <template>
38
38
  <div
39
- class="rounded p-2 relative"
39
+ class="relative px-[25px]"
40
40
  :style="{ backgroundColor: block.settings.backgroundColor }"
41
41
  :data-testid="unsubscribeLinkBlockTestIds.container"
42
42
  >
@@ -25,6 +25,7 @@ const iframeWidth = computed(() => {
25
25
  return props.view === 'mobile' ? '400px' : '600px'
26
26
  })
27
27
 
28
+ const { renderer } = useEmailRenderer()
28
29
  const { mutate: preview, data: previewed, isLoading: isPreviewing } = usePreviewEmailMutation()
29
30
 
30
31
  const previewEmail = useDebounceFn(() => {
@@ -38,11 +39,12 @@ const previewEmail = useDebounceFn(() => {
38
39
  logo_url: props.brand.logo_url,
39
40
  }
40
41
  : null,
42
+ renderer: renderer.value,
41
43
  })
42
44
  }, 0)
43
45
 
44
46
  watch(
45
- () => props.message,
47
+ [() => props.message, renderer],
46
48
  () => {
47
49
  previewEmail()
48
50
  },
@@ -27,6 +27,7 @@ const { data: resolvedParams } = useResolvedParametersQuery(
27
27
  () => props.message.language_id,
28
28
  )
29
29
 
30
+ const { renderer } = useEmailRenderer()
30
31
  const { mutate: compile, data: compiled, isLoading: isCompiling } = useCompileEmailMutation()
31
32
 
32
33
  const compileEmail = useDebounceFn(() => {
@@ -37,6 +38,7 @@ const compileEmail = useDebounceFn(() => {
37
38
  language: props.message.language_id,
38
39
  parameters: resolvedParams.value.parameters,
39
40
  brand_id: props.brandId,
41
+ renderer: renderer.value,
40
42
  },
41
43
  })
42
44
  }, 0)
@@ -47,10 +49,7 @@ watch(
47
49
  { immediate: true },
48
50
  )
49
51
 
50
- watch(
51
- () => props.brandId,
52
- () => compileEmail(),
53
- )
52
+ watch([() => props.brandId, renderer], () => compileEmail())
54
53
 
55
54
  // Compilation
56
55
  const iframeContent = ref<string>('')
@@ -85,6 +85,7 @@ const { t } = useI18n()
85
85
  const toast = useToast()
86
86
  const emailEditorStore = useEmailEditorStore()
87
87
  const composerContext = useComposerContext()
88
+ const { renderer } = useEmailRenderer()
88
89
  const { mutate: sendTest, isLoading: isSending, status } = useSendTestEmailMutation()
89
90
 
90
91
  const defaultSenderEmail = computed(
@@ -138,6 +139,7 @@ function onSubmit() {
138
139
  to: state.value.to,
139
140
  brand_id: resolvedBrandId.value,
140
141
  from: state.value.from || undefined,
142
+ renderer: renderer.value,
141
143
  })
142
144
  }
143
145
 
@@ -0,0 +1,23 @@
1
+ import type { EmailRenderer } from '@dev.smartpricing/message-composer-utils/types'
2
+
3
+ /**
4
+ * Session-level toggle for email renderer selection.
5
+ * Defaults to "mjml". Can be driven by A/B flags or dev toggle.
6
+ */
7
+ export function useEmailRenderer() {
8
+ const renderer = useState<EmailRenderer>('email-renderer', () => 'mjml')
9
+
10
+ function toggle() {
11
+ renderer.value = renderer.value === 'mjml' ? 'maizzle' : 'mjml'
12
+ }
13
+
14
+ function setRenderer(value: EmailRenderer) {
15
+ renderer.value = value
16
+ }
17
+
18
+ return {
19
+ renderer: readonly(renderer),
20
+ toggle,
21
+ setRenderer,
22
+ }
23
+ }