@aglyn/plugins-email 1.0.0-beta.252 → 1.0.0-beta.253

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/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@aglyn/plugins-email",
3
- "version": "1.0.0-beta.252",
3
+ "version": "1.0.0-beta.253",
4
4
  "license": "Apache-2.0",
5
5
  "homepage": "https://aglyn.com",
6
6
  "repository": {
@@ -25,21 +25,21 @@
25
25
  "./package.json": "./package.json"
26
26
  },
27
27
  "dependencies": {
28
- "@aglyn/aglyn": "1.0.0-beta.252",
29
- "@aglyn/shared-data-enums": "1.0.0-beta.252",
30
- "@aglyn/shared-data-mdi": "1.0.0-beta.252",
31
- "@aglyn/shared-data-types": "1.0.0-beta.252",
32
- "@aglyn/shared-ui-jsx": "1.0.0-beta.252",
33
- "@aglyn/shared-ui-jsx-forms": "1.0.0-beta.252",
34
- "@aglyn/shared-ui-next": "1.0.0-beta.252",
35
- "@aglyn/shared-ui-snackstack": "1.0.0-beta.252",
36
- "@aglyn/shared-ui-theme": "1.0.0-beta.252",
37
- "@aglyn/shared-util-email": "1.0.0-beta.252",
38
- "@aglyn/shared-util-http": "1.0.0-beta.252",
39
- "@aglyn/shared-util-timestamp": "1.0.0-beta.252",
40
- "@aglyn/shared-util-tools": "1.0.0-beta.252",
41
- "@aglyn/tenant-data-admin": "1.0.0-beta.252",
42
- "@aglyn/tenant-feature-instance": "1.0.0-beta.252",
28
+ "@aglyn/aglyn": "1.0.0-beta.253",
29
+ "@aglyn/shared-data-enums": "1.0.0-beta.253",
30
+ "@aglyn/shared-data-mdi": "1.0.0-beta.253",
31
+ "@aglyn/shared-data-types": "1.0.0-beta.253",
32
+ "@aglyn/shared-ui-jsx": "1.0.0-beta.253",
33
+ "@aglyn/shared-ui-jsx-forms": "1.0.0-beta.253",
34
+ "@aglyn/shared-ui-next": "1.0.0-beta.253",
35
+ "@aglyn/shared-ui-snackstack": "1.0.0-beta.253",
36
+ "@aglyn/shared-ui-theme": "1.0.0-beta.253",
37
+ "@aglyn/shared-util-email": "1.0.0-beta.253",
38
+ "@aglyn/shared-util-http": "1.0.0-beta.253",
39
+ "@aglyn/shared-util-timestamp": "1.0.0-beta.253",
40
+ "@aglyn/shared-util-tools": "1.0.0-beta.253",
41
+ "@aglyn/tenant-data-admin": "1.0.0-beta.253",
42
+ "@aglyn/tenant-feature-instance": "1.0.0-beta.253",
43
43
  "@swc/helpers": "0.5.23"
44
44
  },
45
45
  "peerDependencies": {
@@ -19,6 +19,7 @@ import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
19
19
  */ import * as Aglyn from "@aglyn/aglyn";
20
20
  import { mdiCardTextOutline, mdiEmailOutline, mdiFormatText, mdiImageOutline, mdiMinus, mdiPackageVariantClosed, mdiPageLayoutFooter, mdiPageLayoutHeader, mdiArrowExpandVertical, mdiGestureTapButton, mdiCodeTags } from "@aglyn/shared-data-mdi";
21
21
  import { sanitizeAuthorHtml } from "@aglyn/aglyn/app-utils/author-html";
22
+ import { EMAIL_BLOCK_STARTER_TREES } from "@aglyn/aglyn/app-utils/email-block-starters";
22
23
  import { mergeSxProps } from "@aglyn/shared-ui-theme";
23
24
  import Box from "@mui/material/Box";
24
25
  import Typography from "@mui/material/Typography";
@@ -732,46 +733,9 @@ export const emailHtmlSchema = {
732
733
  color: '#f57c00'
733
734
  }
734
735
  },
735
- data: {
736
- $id: null,
737
- componentId: SECTION_ID,
738
- pluginId: BUNDLE_ID,
739
- // Marks the band as the email's header, so the sender's own header is
740
- // not drawn above it (AGL-3372).
741
- props: {
742
- align: 'center',
743
- padding: 24,
744
- emailRole: 'header'
745
- },
746
- nodes: [
747
- {
748
- $id: null,
749
- componentId: IMAGE_ID,
750
- pluginId: BUNDLE_ID,
751
- props: {
752
- alt: 'Your company logo',
753
- width: 160,
754
- align: 'center'
755
- }
756
- },
757
- {
758
- $id: null,
759
- componentId: TEXT_ID,
760
- pluginId: BUNDLE_ID,
761
- props: {
762
- children: 'Your company',
763
- variant: 'subheading',
764
- align: 'center'
765
- }
766
- }
767
- ]
768
- }
736
+ // The same tree the Components page and the native apps start a block from.
737
+ data: EMAIL_BLOCK_STARTER_TREES.header
769
738
  };
770
- /**
771
- * The Footer's small print, a muted gray that still reads at 5:1 on white.
772
- * A literal on purpose: it is written into the sent mail's own HTML, where no
773
- * theme token resolves.
774
- */ const FOOTER_TEXT_COLOR = '#6b6b6b';
775
739
  /** See {@link EMAIL_HEADER_PRESET}. */ export const EMAIL_FOOTER_PRESET = {
776
740
  $id: Aglyn.REUSABLE_EMAIL_BLOCK_STARTER_PRESET_IDS.footer,
777
741
  type: Aglyn.NodeType.PRESET,
@@ -791,48 +755,8 @@ export const emailHtmlSchema = {
791
755
  color: '#f57c00'
792
756
  }
793
757
  },
794
- data: {
795
- $id: null,
796
- componentId: SECTION_ID,
797
- pluginId: BUNDLE_ID,
798
- // Marks the band as the email's footer, so the sender's own footer is
799
- // not drawn under it (AGL-3372).
800
- props: {
801
- align: 'center',
802
- padding: 24,
803
- emailRole: 'footer'
804
- },
805
- nodes: [
806
- {
807
- $id: null,
808
- componentId: DIVIDER_ID,
809
- pluginId: BUNDLE_ID,
810
- props: {}
811
- },
812
- {
813
- $id: null,
814
- componentId: TEXT_ID,
815
- pluginId: BUNDLE_ID,
816
- props: {
817
- children: 'Your company · 123 Main St, City',
818
- variant: 'caption',
819
- align: 'center',
820
- color: FOOTER_TEXT_COLOR
821
- }
822
- },
823
- {
824
- $id: null,
825
- componentId: TEXT_ID,
826
- pluginId: BUNDLE_ID,
827
- props: {
828
- children: "You're receiving this because you're a customer of Your company.",
829
- variant: 'caption',
830
- align: 'center',
831
- color: FOOTER_TEXT_COLOR
832
- }
833
- }
834
- ]
835
- }
758
+ // The same tree the Components page and the native apps start a block from.
759
+ data: EMAIL_BLOCK_STARTER_TREES.footer
836
760
  };
837
761
  export const emailPresets = [
838
762
  {
@@ -1 +1 @@
1
- {"version":3,"sources":["../../../../../../../libs/plugins/email/src/lib/components/email-blocks.tsx"],"sourcesContent":["/**\n * @license\n * Copyright 2026 Aglyn LLC\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\nimport * as Aglyn from '@aglyn/aglyn'\nimport {\n mdiCardTextOutline,\n mdiEmailOutline,\n mdiFormatText,\n mdiImageOutline,\n mdiMinus,\n mdiPackageVariantClosed,\n mdiPageLayoutFooter,\n mdiPageLayoutHeader,\n mdiArrowExpandVertical,\n mdiGestureTapButton,\n mdiCodeTags,\n} from '@aglyn/shared-data-mdi'\nimport { sanitizeAuthorHtml } from '@aglyn/aglyn/app-utils/author-html'\nimport { mergeSxProps } from '@aglyn/shared-ui-theme'\nimport Box from '@mui/material/Box'\nimport type { SxProps, Theme } from '@mui/material/styles'\nimport Typography from '@mui/material/Typography'\nimport { forwardRef } from 'react'\nimport { BUNDLE_ID } from '../constants/bundle-common'\nimport { generatePresetId } from '../utils/generate-preset-id'\n\n/**\n * Email-safe blocks (AGL-346): the besigner canvas renders these web\n * previews; the render pipeline (email-render.ts in app-utils) converts\n * the same nodes to inline-styled table HTML for email clients. Merge\n * tokens like {{contact.firstName}} substitute at send time.\n *\n * Component ids are persisted in screen documents; never rename.\n *\n * Every block pulls `sx` out of its props and composes it AFTER its own\n * defaults with MUI array composition (AGL-587): the renderer's Leaf\n * passes the node-level sx (styles-panel output) through props.sx, and a\n * literal `sx={{...}}` after `{...rest}` used to silently discard it.\n */\n\ninterface EmailBlockStyleProps {\n /** Node-level styles merged by the renderer; wins over block defaults. */\n sx?: SxProps<Theme>\n}\n\n// ---------------------------------------------------------------- section\nexport const SECTION_ID: Aglyn.ComponentId = 'emailSection'\n\nexport interface EmailSectionProps extends EmailBlockStyleProps {\n backgroundColor?: string\n /**\n * `header` or `footer` when the section is the email's own band of that\n * kind (AGL-3372): the send then leaves the sender's matching band out.\n * Set by the Header and Footer presets; draws nothing itself.\n */\n emailRole?: 'header' | 'footer'\n /** Inner padding in px (default 24). */\n padding?: number\n align?: 'left' | 'center' | 'right'\n children?: JSX.Children\n}\n\nexport const EmailSection = forwardRef<HTMLDivElement, EmailSectionProps>(\n (props, ref) => {\n // `emailRole` is read at send time and must not reach the DOM.\n const { backgroundColor, padding, align, children, sx, emailRole: _emailRole, ...rest } =\n props\n return (\n <Box\n ref={ref}\n {...rest}\n sx={mergeSxProps(\n {\n maxWidth: 600,\n mx: 'auto',\n backgroundColor: backgroundColor || '#ffffff',\n p: `${padding ?? 24}px`,\n textAlign: align ?? 'left',\n },\n sx,\n )}\n >\n {children}\n </Box>\n )\n },\n)\nEmailSection.displayName = 'EmailSection'\n\nexport const emailSectionSchema: Aglyn.ComponentSchema<EmailSectionProps> = {\n $id: SECTION_ID,\n pluginId: BUNDLE_ID,\n displayName: 'Email section',\n description: 'An email-safe band with its own background color and padding.',\n category: Aglyn.ComponentCategory.LAYOUT,\n icon: { path: mdiEmailOutline.path, sx: { color: '#f57c00' } },\n attributes: [\n {\n name: 'backgroundColor',\n label: 'Background color',\n description: 'Solid colors only — gradients are unreliable in email.',\n component: Aglyn.FieldComponentType.COLOR_PICKER,\n },\n {\n name: 'padding',\n label: 'Padding (px)',\n description: 'Inner spacing around the section content.',\n component: Aglyn.FieldComponentType.TEXT_FIELD,\n type: 'number',\n },\n {\n name: 'align',\n label: 'Content alignment',\n description:\n 'How every block inside this section lines up. Each block can still ' +\n 'override it with its own alignment.',\n component: Aglyn.FieldComponentType.SELECT,\n options: [\n { value: 'left', label: 'Left' },\n { value: 'center', label: 'Center' },\n { value: 'right', label: 'Right' },\n ],\n },\n ],\n}\n\n// ------------------------------------------------------------------- text\nexport const TEXT_ID: Aglyn.ComponentId = 'emailText'\n\nexport interface EmailTextProps extends EmailBlockStyleProps {\n children?: string\n variant?: 'heading' | 'subheading' | 'body' | 'caption'\n color?: string\n align?: 'left' | 'center' | 'right'\n}\n\nconst TEXT_PRESETS: Record<\n NonNullable<EmailTextProps['variant']>,\n { fontSize: number; fontWeight: number; lineHeight: number }\n> = {\n heading: { fontSize: 28, fontWeight: 700, lineHeight: 1.25 },\n subheading: { fontSize: 20, fontWeight: 600, lineHeight: 1.3 },\n body: { fontSize: 15, fontWeight: 400, lineHeight: 1.55 },\n caption: { fontSize: 12, fontWeight: 400, lineHeight: 1.4 },\n}\n\nexport const EmailText = forwardRef<HTMLDivElement, EmailTextProps>(\n (props, ref) => {\n const { children, variant, color, align, sx, ...rest } = props\n const preset = TEXT_PRESETS[variant ?? 'body']\n return (\n <Typography\n ref={ref}\n component=\"div\"\n {...rest}\n sx={mergeSxProps(\n {\n fontSize: preset.fontSize,\n fontWeight: preset.fontWeight,\n lineHeight: preset.lineHeight,\n color: color || '#1a1a1a',\n textAlign: align ?? 'left',\n fontFamily: 'Helvetica, Arial, sans-serif',\n mb: 1,\n },\n sx,\n )}\n >\n {children ?? 'Email text'}\n </Typography>\n )\n },\n)\nEmailText.displayName = 'EmailText'\n\nexport const emailTextSchema: Aglyn.ComponentSchema<EmailTextProps> = {\n $id: TEXT_ID,\n pluginId: BUNDLE_ID,\n displayName: 'Email text',\n description: 'A paragraph of email copy in one of the preset styles.',\n category: Aglyn.ComponentCategory.DATA_DISPLAY,\n icon: { path: mdiFormatText.path, sx: { color: '#f57c00' } },\n flags: { textEditable: Aglyn.FEATURE_FLAG.ENABLED },\n attributes: [\n {\n name: 'children',\n label: 'Text',\n description:\n 'Supports merge tokens: {{contact.firstName}}, {{contact.email}}, ' +\n '{{org.name}}, {{unsubscribeUrl}}.',\n component: Aglyn.FieldComponentType.TEXTAREA,\n },\n {\n name: 'variant',\n label: 'Style',\n description:\n 'Size and weight of this text — Heading and Subheading also give it ' +\n 'the spacing above and below that a heading needs.',\n component: Aglyn.FieldComponentType.SELECT,\n options: [\n { value: 'heading', label: 'Heading' },\n { value: 'subheading', label: 'Subheading' },\n { value: 'body', label: 'Body' },\n { value: 'caption', label: 'Caption' },\n ],\n },\n {\n name: 'color',\n label: 'Color',\n description:\n 'Text color. Keep it dark on a light background: many clients ' +\n 'ignore dark mode overrides and show your color as-is.',\n component: Aglyn.FieldComponentType.COLOR_PICKER,\n },\n {\n name: 'align',\n label: 'Alignment',\n description: 'How this block of text lines up within the section.',\n component: Aglyn.FieldComponentType.SELECT,\n options: [\n { value: 'left', label: 'Left' },\n { value: 'center', label: 'Center' },\n { value: 'right', label: 'Right' },\n ],\n },\n ],\n}\n\n// --------------------------------------------------------------- richtext\nexport const RICHTEXT_ID: Aglyn.ComponentId = 'emailRichtext'\n\nexport interface EmailRichtextProps extends EmailBlockStyleProps {\n /** HTML fragment; sanitized with the custom-html policy (AGL-320). */\n html?: string\n}\n\nexport const EmailRichtext = forwardRef<HTMLDivElement, EmailRichtextProps>(\n (props, ref) => {\n const { html, sx, ...rest } = props\n if (!html?.trim()) {\n return (\n <Box\n ref={ref}\n {...rest}\n sx={mergeSxProps(\n {\n p: 2,\n border: '1px dashed',\n borderColor: 'divider',\n color: 'text.secondary',\n fontSize: 13,\n },\n sx,\n )}\n >\n {'Rich text — add HTML in the attributes panel'}\n </Box>\n )\n }\n return (\n <Box\n ref={ref}\n {...rest}\n sx={mergeSxProps(\n { fontFamily: 'Helvetica, Arial, sans-serif', fontSize: 15 },\n sx,\n )}\n // Sanitized on every render — same policy as the custom HTML block.\n // The `typeof window` guard this replaced existed only because that\n // policy was DOMPurify, which needs a DOM; it is now a pure function\n // (AGL-1901), so the body survives a server render instead of being\n // blanked — which for an email is the render that gets SENT.\n dangerouslySetInnerHTML={{ __html: sanitizeAuthorHtml(html) }}\n />\n )\n },\n)\nEmailRichtext.displayName = 'EmailRichtext'\n\nexport const emailRichtextSchema: Aglyn.ComponentSchema<EmailRichtextProps> = {\n $id: RICHTEXT_ID,\n pluginId: BUNDLE_ID,\n displayName: 'Email rich text',\n description: 'An HTML fragment in an email, sanitised on render.',\n category: Aglyn.ComponentCategory.DATA_DISPLAY,\n icon: { path: mdiCardTextOutline.path, sx: { color: '#f57c00' } },\n flags: { selfClosing: Aglyn.FEATURE_FLAG.ENABLED },\n attributes: [\n {\n name: 'html',\n label: 'HTML',\n description:\n 'Formatted content (p, b, i, a, ul/ol, h1-h4). Scripts and forms ' +\n 'are stripped; keep styling simple for email clients. Merge ' +\n 'tokens work here too.',\n component: Aglyn.FieldComponentType.TEXTAREA,\n },\n ],\n}\n\n// ------------------------------------------------------------------ image\nexport const IMAGE_ID: Aglyn.ComponentId = 'emailImage'\n\nexport interface EmailImageProps extends EmailBlockStyleProps {\n src?: string\n alt?: string\n /** Rendered width in px (max 600). */\n width?: number\n href?: string\n align?: 'left' | 'center' | 'right'\n}\n\nexport const EmailImage = forwardRef<HTMLDivElement, EmailImageProps>(\n (props, ref) => {\n const { src: storedSrc, alt, width, href, align, sx, ...rest } = props\n // A media-picker target, so it can hold a media reference (AGL-1215).\n // This is the CANVAS preview only — the sent HTML is built by\n // `email-render`, which needs an absolute URL and cannot resolve either\n // a reference or the relative CDN path it replaces.\n const src = Aglyn.resolveMediaSrc(storedSrc)\n return (\n <Box\n ref={ref}\n {...rest}\n sx={mergeSxProps({ textAlign: align ?? 'center', my: 1 }, sx)}\n >\n {src ? (\n <Box\n component=\"img\"\n src={src}\n alt={alt ?? ''}\n sx={{ maxWidth: '100%', width: width ? `${width}px` : '100%' }}\n />\n ) : (\n <Box\n sx={{\n height: 120,\n display: 'flex',\n alignItems: 'center',\n justifyContent: 'center',\n border: '1px dashed',\n borderColor: 'divider',\n color: 'text.secondary',\n fontSize: 13,\n }}\n >\n {'Image — pick from the media library'}\n </Box>\n )}\n </Box>\n )\n },\n)\nEmailImage.displayName = 'EmailImage'\n\nexport const emailImageSchema: Aglyn.ComponentSchema<EmailImageProps> = {\n $id: IMAGE_ID,\n pluginId: BUNDLE_ID,\n displayName: 'Email image',\n description: 'An email-safe image, capped at 600px wide, optionally linked.',\n category: Aglyn.ComponentCategory.DATA_DISPLAY,\n icon: { path: mdiImageOutline.path, sx: { color: '#f57c00' } },\n flags: { selfClosing: Aglyn.FEATURE_FLAG.ENABLED },\n attributes: [\n {\n name: 'src',\n label: 'Source URL',\n description: 'Use an absolute URL — email clients cannot resolve relative paths.',\n component: Aglyn.FieldComponentType.TEXT_FIELD,\n },\n {\n name: 'alt',\n label: 'Alt text',\n // AGL-1896: the same \"Browse media\" default the site Image element\n // gets. It matters MORE here — most clients block images by default,\n // so for most recipients the alt text IS the block.\n description:\n 'Shown while images are blocked — most clients block by default. ' +\n 'Filled in from the media library when you pick a file that has ' +\n 'alt text.',\n component: Aglyn.FieldComponentType.TEXT_FIELD,\n },\n {\n name: 'width',\n label: 'Width (px)',\n description:\n 'How wide the image renders. Blank fills the section — which is ' +\n 'usually right, since a phone is narrower than any number you pick.',\n component: Aglyn.FieldComponentType.TEXT_FIELD,\n type: 'number',\n },\n {\n name: 'href',\n label: 'Link URL',\n description:\n 'Where the image goes when it is clicked. Blank leaves it as a ' +\n 'plain picture.',\n component: Aglyn.FieldComponentType.TEXT_FIELD,\n },\n {\n name: 'align',\n label: 'Alignment',\n description: 'Where the image sits when it is narrower than the section.',\n component: Aglyn.FieldComponentType.SELECT,\n options: [\n { value: 'left', label: 'Left' },\n { value: 'center', label: 'Center' },\n { value: 'right', label: 'Right' },\n ],\n },\n ],\n}\n\n// ----------------------------------------------------------------- button\nexport const BUTTON_ID: Aglyn.ComponentId = 'emailButton'\n\nexport interface EmailButtonProps extends EmailBlockStyleProps {\n children?: string\n href?: string\n backgroundColor?: string\n color?: string\n align?: 'left' | 'center' | 'right'\n}\n\nexport const EmailButton = forwardRef<HTMLDivElement, EmailButtonProps>(\n (props, ref) => {\n const { children, href, backgroundColor, color, align, sx, ...rest } =\n props\n return (\n <Box\n ref={ref}\n {...rest}\n sx={mergeSxProps({ textAlign: align ?? 'center', my: 1.5 }, sx)}\n >\n <Box\n component=\"span\"\n sx={{\n display: 'inline-block',\n px: 3,\n py: 1.25,\n borderRadius: 1,\n // The theme's accent when nothing was picked, as the sent email\n // resolves it (AGL-3370): the canvas and the inbox agree.\n backgroundColor: backgroundColor || 'primary.main',\n color: color || 'primary.contrastText',\n fontFamily: 'Helvetica, Arial, sans-serif',\n fontSize: 15,\n fontWeight: 600,\n }}\n >\n {children ?? 'Call to action'}\n </Box>\n </Box>\n )\n },\n)\nEmailButton.displayName = 'EmailButton'\n\nexport const emailButtonSchema: Aglyn.ComponentSchema<EmailButtonProps> = {\n $id: BUTTON_ID,\n pluginId: BUNDLE_ID,\n displayName: 'Email button',\n description: 'A call-to-action button that survives every mail client.',\n category: Aglyn.ComponentCategory.INPUT,\n icon: { path: mdiGestureTapButton.path, sx: { color: '#f57c00' } },\n flags: { textEditable: Aglyn.FEATURE_FLAG.ENABLED },\n attributes: [\n {\n name: 'children',\n label: 'Label',\n description:\n 'The words on the button. Say what happens next — \"See the report\" ' +\n 'reads as a destination where \"Click here\" does not.',\n component: Aglyn.FieldComponentType.TEXT_FIELD,\n },\n {\n name: 'href',\n label: 'Link URL',\n description: 'Absolute URL (https://…). Merge tokens allowed.',\n component: Aglyn.FieldComponentType.TEXT_FIELD,\n },\n {\n name: 'backgroundColor',\n label: 'Button color',\n description:\n 'The fill behind the label. Check it against the label color — a ' +\n 'button nobody can read is a link nobody clicks.',\n component: Aglyn.FieldComponentType.COLOR_PICKER,\n },\n {\n name: 'color',\n label: 'Label color',\n description: 'The color of the words on the button.',\n component: Aglyn.FieldComponentType.COLOR_PICKER,\n },\n {\n name: 'align',\n label: 'Alignment',\n description: 'Where the button sits across the width of the section.',\n component: Aglyn.FieldComponentType.SELECT,\n options: [\n { value: 'left', label: 'Left' },\n { value: 'center', label: 'Center' },\n { value: 'right', label: 'Right' },\n ],\n },\n ],\n}\n\n// ---------------------------------------------------------------- divider\nexport const DIVIDER_ID: Aglyn.ComponentId = 'emailDivider'\n\nexport interface EmailDividerProps extends EmailBlockStyleProps {\n color?: string\n}\n\nexport const EmailDivider = forwardRef<HTMLHRElement, EmailDividerProps>(\n (props, ref) => {\n const { color, sx, ...rest } = props\n return (\n <Box\n ref={ref}\n component=\"hr\"\n {...rest}\n sx={mergeSxProps(\n {\n border: 0,\n // Split shorthand so a palette token path from the theme-\n // reference color picker (AGL-588) resolves through the sx\n // system instead of dying inside a template string.\n borderTopStyle: 'solid',\n borderTopWidth: 1,\n borderTopColor: color || '#e0e0e0',\n my: 2,\n },\n sx,\n )}\n />\n )\n },\n)\nEmailDivider.displayName = 'EmailDivider'\n\nexport const emailDividerSchema: Aglyn.ComponentSchema<EmailDividerProps> = {\n $id: DIVIDER_ID,\n pluginId: BUNDLE_ID,\n displayName: 'Email divider',\n description: 'A horizontal rule between email sections.',\n category: Aglyn.ComponentCategory.LAYOUT,\n icon: { path: mdiMinus.path, sx: { color: '#f57c00' } },\n flags: { selfClosing: Aglyn.FEATURE_FLAG.ENABLED },\n attributes: [\n {\n name: 'color',\n label: 'Line color',\n description:\n 'The color of the rule. A light grey separates sections without ' +\n 'drawing the eye to the line itself.',\n component: Aglyn.FieldComponentType.COLOR_PICKER,\n },\n ],\n}\n\n// ----------------------------------------------------------------- spacer\nexport const SPACER_ID: Aglyn.ComponentId = 'emailSpacer'\n\nexport interface EmailSpacerProps extends EmailBlockStyleProps {\n /** Height in px (default 24). */\n height?: number\n}\n\nexport const EmailSpacer = forwardRef<HTMLDivElement, EmailSpacerProps>(\n (props, ref) => {\n const { height, sx, ...rest } = props\n return (\n <Box\n ref={ref}\n {...rest}\n sx={mergeSxProps({ height: height ?? 24 }, sx)}\n />\n )\n },\n)\nEmailSpacer.displayName = 'EmailSpacer'\n\nexport const emailSpacerSchema: Aglyn.ComponentSchema<EmailSpacerProps> = {\n $id: SPACER_ID,\n pluginId: BUNDLE_ID,\n displayName: 'Email spacer',\n description: 'Fixed vertical whitespace between email blocks.',\n category: Aglyn.ComponentCategory.LAYOUT,\n icon: { path: mdiArrowExpandVertical.path, sx: { color: '#f57c00' } },\n flags: { selfClosing: Aglyn.FEATURE_FLAG.ENABLED },\n attributes: [\n {\n name: 'height',\n label: 'Height (px)',\n description:\n 'How much empty vertical space this block adds. Email clients drop ' +\n 'CSS margins, so a spacer is how you get reliable breathing room.',\n component: Aglyn.FieldComponentType.TEXT_FIELD,\n type: 'number',\n },\n ],\n}\n\n// ---------------------------------------------------------------- product\nexport const PRODUCT_ID: Aglyn.ComponentId = 'emailProduct'\n\nexport interface EmailProductProps extends EmailBlockStyleProps {\n /** Product id — resolved server-side at render (rename-safe). */\n productId?: string\n buttonLabel?: string\n}\n\nexport const EmailProduct = forwardRef<HTMLDivElement, EmailProductProps>(\n (props, ref) => {\n const { productId, buttonLabel, sx, ...rest } = props\n return (\n <Box\n ref={ref}\n {...rest}\n sx={mergeSxProps(\n {\n border: '1px solid',\n borderColor: 'divider',\n borderRadius: 1,\n p: 2,\n my: 1,\n textAlign: 'center',\n color: 'text.secondary',\n fontSize: 13,\n },\n sx,\n )}\n >\n {productId\n ? `Product card (${productId}) — name, price, image fill in at send`\n : 'Product card — pick a product in the attributes panel'}\n <Box sx={{ mt: 1, fontWeight: 600 }}>\n {buttonLabel ?? 'Shop now'}\n </Box>\n </Box>\n )\n },\n)\nEmailProduct.displayName = 'EmailProduct'\n\nexport const emailProductSchema: Aglyn.ComponentSchema<EmailProductProps> = {\n $id: PRODUCT_ID,\n pluginId: BUNDLE_ID,\n displayName: 'Email product',\n description: 'A product card resolved at send time, so it never goes stale.',\n category: Aglyn.ComponentCategory.DATA_DISPLAY,\n icon: { path: mdiPackageVariantClosed.path, sx: { color: '#f57c00' } },\n flags: { selfClosing: Aglyn.FEATURE_FLAG.ENABLED },\n attributes: [\n {\n name: 'productId',\n label: 'Product',\n description:\n 'Stored by id — the current name, price, and image render at send.',\n component: Aglyn.FieldComponentType.PRODUCT_SELECT,\n },\n {\n name: 'buttonLabel',\n label: 'Button label',\n description:\n 'The words on the card’s button. Blank uses the block’s default, ' +\n 'and the link always points at this product’s page.',\n component: Aglyn.FieldComponentType.TEXT_FIELD,\n },\n ],\n}\n\n// ------------------------------------------------------------ custom html\nexport const HTML_ID: Aglyn.ComponentId = 'emailHtml'\n\nexport interface EmailHtmlProps extends EmailBlockStyleProps {\n html?: string\n}\n\nexport const EmailHtml = forwardRef<HTMLDivElement, EmailHtmlProps>(\n (props, ref) => {\n const { html, sx, ...rest } = props\n return (\n <Box\n ref={ref}\n {...rest}\n sx={mergeSxProps({ fontFamily: 'Helvetica, Arial, sans-serif' }, sx)}\n // No `typeof window` guard any more (AGL-1901): the sanitizer needs\n // no DOM, so a server-rendered email keeps its custom HTML.\n dangerouslySetInnerHTML={{\n __html: html ? sanitizeAuthorHtml(html) : '',\n }}\n />\n )\n },\n)\nEmailHtml.displayName = 'EmailHtml'\n\nexport const emailHtmlSchema: Aglyn.ComponentSchema<EmailHtmlProps> = {\n $id: HTML_ID,\n pluginId: BUNDLE_ID,\n displayName: 'Email custom HTML',\n description: 'Hand-written HTML for an email, used as-is.',\n category: Aglyn.ComponentCategory.DATA_DISPLAY,\n icon: { path: mdiCodeTags.path, sx: { color: '#f57c00' } },\n flags: { selfClosing: Aglyn.FEATURE_FLAG.ENABLED },\n attributes: [\n {\n name: 'html',\n label: 'HTML',\n description:\n 'Raw table markup for advanced layouts. Sanitized with the ' +\n 'custom-html policy; the render pipeline passes it through as-is ' +\n 'after sanitization.',\n component: Aglyn.FieldComponentType.TEXTAREA,\n },\n ],\n}\n\n/**\n * The two bands most emails a site sends begin and end with (AGL-3287).\n *\n * Each drops into any email like the blocks above, and the Components page\n * starts a reusable Header or Footer email block from these same trees, by\n * the ids core names in `REUSABLE_EMAIL_BLOCK_STARTER_PRESET_IDS` — one tree\n * each, wherever it is started from.\n *\n * The words are placeholders to replace. No merge token names the company in\n * both kinds of email — a campaign supplies `{{org.name}}`, and no token is\n * supplied by every one of a site's own emails — while a token an email does\n * not supply is blanked before sending, which would leave the header with no\n * name at all.\n *\n * The footer carries no unsubscribe link: a campaign send appends its own,\n * and a second one would do the same thing twice.\n */\nexport const EMAIL_HEADER_PRESET: Aglyn.PresetSchema = {\n $id: Aglyn.REUSABLE_EMAIL_BLOCK_STARTER_PRESET_IDS.header,\n type: Aglyn.NodeType.PRESET,\n displayName: 'Header',\n description:\n 'Your logo above your company name, for the top of an email. Pick the ' +\n 'logo from your media library — until you do, the picture shows nothing ' +\n 'in a sent email.',\n pluginId: BUNDLE_ID,\n category: Aglyn.ComponentCategory.BLOCKS,\n tags: ['logo', 'masthead', 'top', 'brand'],\n icon: { path: mdiPageLayoutHeader.path, sx: { color: '#f57c00' } },\n data: {\n $id: null,\n componentId: SECTION_ID,\n pluginId: BUNDLE_ID,\n // Marks the band as the email's header, so the sender's own header is\n // not drawn above it (AGL-3372).\n props: { align: 'center', padding: 24, emailRole: 'header' },\n nodes: [\n {\n $id: null,\n componentId: IMAGE_ID,\n pluginId: BUNDLE_ID,\n props: { alt: 'Your company logo', width: 160, align: 'center' },\n },\n {\n $id: null,\n componentId: TEXT_ID,\n pluginId: BUNDLE_ID,\n props: {\n children: 'Your company',\n variant: 'subheading',\n align: 'center',\n },\n },\n ],\n },\n}\n\n/**\n * The Footer's small print, a muted gray that still reads at 5:1 on white.\n * A literal on purpose: it is written into the sent mail's own HTML, where no\n * theme token resolves.\n */\nconst FOOTER_TEXT_COLOR = '#6b6b6b'\n\n/** See {@link EMAIL_HEADER_PRESET}. */\nexport const EMAIL_FOOTER_PRESET: Aglyn.PresetSchema = {\n $id: Aglyn.REUSABLE_EMAIL_BLOCK_STARTER_PRESET_IDS.footer,\n type: Aglyn.NodeType.PRESET,\n displayName: 'Footer',\n description:\n 'Your company name and address, and why the reader gets your emails, for ' +\n 'the bottom of an email. Campaign emails add the unsubscribe link for you.',\n pluginId: BUNDLE_ID,\n category: Aglyn.ComponentCategory.BLOCKS,\n tags: ['address', 'bottom', 'contact', 'legal'],\n icon: { path: mdiPageLayoutFooter.path, sx: { color: '#f57c00' } },\n data: {\n $id: null,\n componentId: SECTION_ID,\n pluginId: BUNDLE_ID,\n // Marks the band as the email's footer, so the sender's own footer is\n // not drawn under it (AGL-3372).\n props: { align: 'center', padding: 24, emailRole: 'footer' },\n nodes: [\n {\n $id: null,\n componentId: DIVIDER_ID,\n pluginId: BUNDLE_ID,\n props: {},\n },\n {\n $id: null,\n componentId: TEXT_ID,\n pluginId: BUNDLE_ID,\n props: {\n children: 'Your company · 123 Main St, City',\n variant: 'caption',\n align: 'center',\n color: FOOTER_TEXT_COLOR,\n },\n },\n {\n $id: null,\n componentId: TEXT_ID,\n pluginId: BUNDLE_ID,\n props: {\n children:\n \"You're receiving this because you're a customer of Your company.\",\n variant: 'caption',\n align: 'center',\n color: FOOTER_TEXT_COLOR,\n },\n },\n ],\n },\n}\n\nexport const emailPresets: Aglyn.PresetSchema[] = [\n {\n $id: generatePresetId(SECTION_ID),\n type: Aglyn.NodeType.PRESET,\n displayName: 'Email section',\n pluginId: BUNDLE_ID,\n category: Aglyn.ComponentCategory.LAYOUT,\n icon: { path: mdiEmailOutline.path, sx: { color: '#f57c00' } },\n data: {\n $id: null,\n componentId: SECTION_ID,\n pluginId: BUNDLE_ID,\n props: {},\n },\n },\n {\n $id: generatePresetId(TEXT_ID),\n type: Aglyn.NodeType.PRESET,\n displayName: 'Email text',\n pluginId: BUNDLE_ID,\n category: Aglyn.ComponentCategory.DATA_DISPLAY,\n icon: { path: mdiFormatText.path, sx: { color: '#f57c00' } },\n data: {\n $id: null,\n componentId: TEXT_ID,\n pluginId: BUNDLE_ID,\n props: { children: 'Hello {{contact.firstName}},', variant: 'body' },\n },\n },\n {\n $id: generatePresetId(RICHTEXT_ID),\n type: Aglyn.NodeType.PRESET,\n displayName: 'Email rich text',\n pluginId: BUNDLE_ID,\n category: Aglyn.ComponentCategory.DATA_DISPLAY,\n icon: { path: mdiCardTextOutline.path, sx: { color: '#f57c00' } },\n data: {\n $id: null,\n componentId: RICHTEXT_ID,\n pluginId: BUNDLE_ID,\n props: {},\n },\n },\n {\n $id: generatePresetId(IMAGE_ID),\n type: Aglyn.NodeType.PRESET,\n displayName: 'Email image',\n pluginId: BUNDLE_ID,\n category: Aglyn.ComponentCategory.DATA_DISPLAY,\n icon: { path: mdiImageOutline.path, sx: { color: '#f57c00' } },\n data: {\n $id: null,\n componentId: IMAGE_ID,\n pluginId: BUNDLE_ID,\n props: {},\n },\n },\n {\n $id: generatePresetId(BUTTON_ID),\n type: Aglyn.NodeType.PRESET,\n displayName: 'Email button',\n pluginId: BUNDLE_ID,\n category: Aglyn.ComponentCategory.INPUT,\n icon: { path: mdiGestureTapButton.path, sx: { color: '#f57c00' } },\n data: {\n $id: null,\n componentId: BUTTON_ID,\n pluginId: BUNDLE_ID,\n props: { children: 'Shop now' },\n },\n },\n {\n $id: generatePresetId(DIVIDER_ID),\n type: Aglyn.NodeType.PRESET,\n displayName: 'Email divider',\n pluginId: BUNDLE_ID,\n category: Aglyn.ComponentCategory.LAYOUT,\n icon: { path: mdiMinus.path, sx: { color: '#f57c00' } },\n data: {\n $id: null,\n componentId: DIVIDER_ID,\n pluginId: BUNDLE_ID,\n props: {},\n },\n },\n {\n $id: generatePresetId(SPACER_ID),\n type: Aglyn.NodeType.PRESET,\n displayName: 'Email spacer',\n pluginId: BUNDLE_ID,\n category: Aglyn.ComponentCategory.LAYOUT,\n icon: { path: mdiArrowExpandVertical.path, sx: { color: '#f57c00' } },\n data: {\n $id: null,\n componentId: SPACER_ID,\n pluginId: BUNDLE_ID,\n props: {},\n },\n },\n {\n $id: generatePresetId(PRODUCT_ID),\n type: Aglyn.NodeType.PRESET,\n displayName: 'Email product',\n pluginId: BUNDLE_ID,\n category: Aglyn.ComponentCategory.DATA_DISPLAY,\n icon: { path: mdiPackageVariantClosed.path, sx: { color: '#f57c00' } },\n data: {\n $id: null,\n componentId: PRODUCT_ID,\n pluginId: BUNDLE_ID,\n props: {},\n },\n },\n {\n $id: generatePresetId(HTML_ID),\n type: Aglyn.NodeType.PRESET,\n displayName: 'Email custom HTML',\n pluginId: BUNDLE_ID,\n category: Aglyn.ComponentCategory.DATA_DISPLAY,\n icon: { path: mdiCodeTags.path, sx: { color: '#f57c00' } },\n data: {\n $id: null,\n componentId: HTML_ID,\n pluginId: BUNDLE_ID,\n props: {},\n },\n },\n EMAIL_HEADER_PRESET,\n EMAIL_FOOTER_PRESET,\n]\n"],"names":["Aglyn","mdiCardTextOutline","mdiEmailOutline","mdiFormatText","mdiImageOutline","mdiMinus","mdiPackageVariantClosed","mdiPageLayoutFooter","mdiPageLayoutHeader","mdiArrowExpandVertical","mdiGestureTapButton","mdiCodeTags","sanitizeAuthorHtml","mergeSxProps","Box","Typography","forwardRef","BUNDLE_ID","generatePresetId","SECTION_ID","EmailSection","props","ref","backgroundColor","padding","align","children","sx","emailRole","_emailRole","rest","maxWidth","mx","p","textAlign","displayName","emailSectionSchema","$id","pluginId","description","category","ComponentCategory","LAYOUT","icon","path","color","attributes","name","label","component","FieldComponentType","COLOR_PICKER","TEXT_FIELD","type","SELECT","options","value","TEXT_ID","TEXT_PRESETS","heading","fontSize","fontWeight","lineHeight","subheading","body","caption","EmailText","variant","preset","fontFamily","mb","emailTextSchema","DATA_DISPLAY","flags","textEditable","FEATURE_FLAG","ENABLED","TEXTAREA","RICHTEXT_ID","EmailRichtext","html","trim","border","borderColor","dangerouslySetInnerHTML","__html","emailRichtextSchema","selfClosing","IMAGE_ID","EmailImage","src","storedSrc","alt","width","href","resolveMediaSrc","my","height","display","alignItems","justifyContent","emailImageSchema","BUTTON_ID","EmailButton","px","py","borderRadius","emailButtonSchema","INPUT","DIVIDER_ID","EmailDivider","borderTopStyle","borderTopWidth","borderTopColor","emailDividerSchema","SPACER_ID","EmailSpacer","emailSpacerSchema","PRODUCT_ID","EmailProduct","productId","buttonLabel","mt","emailProductSchema","PRODUCT_SELECT","HTML_ID","EmailHtml","emailHtmlSchema","EMAIL_HEADER_PRESET","REUSABLE_EMAIL_BLOCK_STARTER_PRESET_IDS","header","NodeType","PRESET","BLOCKS","tags","data","componentId","nodes","FOOTER_TEXT_COLOR","EMAIL_FOOTER_PRESET","footer","emailPresets"],"mappings":"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"}
1
+ {"version":3,"sources":["../../../../../../../libs/plugins/email/src/lib/components/email-blocks.tsx"],"sourcesContent":["/**\n * @license\n * Copyright 2026 Aglyn LLC\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\nimport * as Aglyn from '@aglyn/aglyn'\nimport {\n mdiCardTextOutline,\n mdiEmailOutline,\n mdiFormatText,\n mdiImageOutline,\n mdiMinus,\n mdiPackageVariantClosed,\n mdiPageLayoutFooter,\n mdiPageLayoutHeader,\n mdiArrowExpandVertical,\n mdiGestureTapButton,\n mdiCodeTags,\n} from '@aglyn/shared-data-mdi'\nimport { sanitizeAuthorHtml } from '@aglyn/aglyn/app-utils/author-html'\nimport { EMAIL_BLOCK_STARTER_TREES } from '@aglyn/aglyn/app-utils/email-block-starters'\nimport { mergeSxProps } from '@aglyn/shared-ui-theme'\nimport Box from '@mui/material/Box'\nimport type { SxProps, Theme } from '@mui/material/styles'\nimport Typography from '@mui/material/Typography'\nimport { forwardRef } from 'react'\nimport { BUNDLE_ID } from '../constants/bundle-common'\nimport { generatePresetId } from '../utils/generate-preset-id'\n\n/**\n * Email-safe blocks (AGL-346): the besigner canvas renders these web\n * previews; the render pipeline (email-render.ts in app-utils) converts\n * the same nodes to inline-styled table HTML for email clients. Merge\n * tokens like {{contact.firstName}} substitute at send time.\n *\n * Component ids are persisted in screen documents; never rename.\n *\n * Every block pulls `sx` out of its props and composes it AFTER its own\n * defaults with MUI array composition (AGL-587): the renderer's Leaf\n * passes the node-level sx (styles-panel output) through props.sx, and a\n * literal `sx={{...}}` after `{...rest}` used to silently discard it.\n */\n\ninterface EmailBlockStyleProps {\n /** Node-level styles merged by the renderer; wins over block defaults. */\n sx?: SxProps<Theme>\n}\n\n// ---------------------------------------------------------------- section\nexport const SECTION_ID: Aglyn.ComponentId = 'emailSection'\n\nexport interface EmailSectionProps extends EmailBlockStyleProps {\n backgroundColor?: string\n /**\n * `header` or `footer` when the section is the email's own band of that\n * kind (AGL-3372): the send then leaves the sender's matching band out.\n * Set by the Header and Footer presets; draws nothing itself.\n */\n emailRole?: 'header' | 'footer'\n /** Inner padding in px (default 24). */\n padding?: number\n align?: 'left' | 'center' | 'right'\n children?: JSX.Children\n}\n\nexport const EmailSection = forwardRef<HTMLDivElement, EmailSectionProps>(\n (props, ref) => {\n // `emailRole` is read at send time and must not reach the DOM.\n const { backgroundColor, padding, align, children, sx, emailRole: _emailRole, ...rest } =\n props\n return (\n <Box\n ref={ref}\n {...rest}\n sx={mergeSxProps(\n {\n maxWidth: 600,\n mx: 'auto',\n backgroundColor: backgroundColor || '#ffffff',\n p: `${padding ?? 24}px`,\n textAlign: align ?? 'left',\n },\n sx,\n )}\n >\n {children}\n </Box>\n )\n },\n)\nEmailSection.displayName = 'EmailSection'\n\nexport const emailSectionSchema: Aglyn.ComponentSchema<EmailSectionProps> = {\n $id: SECTION_ID,\n pluginId: BUNDLE_ID,\n displayName: 'Email section',\n description: 'An email-safe band with its own background color and padding.',\n category: Aglyn.ComponentCategory.LAYOUT,\n icon: { path: mdiEmailOutline.path, sx: { color: '#f57c00' } },\n attributes: [\n {\n name: 'backgroundColor',\n label: 'Background color',\n description: 'Solid colors only — gradients are unreliable in email.',\n component: Aglyn.FieldComponentType.COLOR_PICKER,\n },\n {\n name: 'padding',\n label: 'Padding (px)',\n description: 'Inner spacing around the section content.',\n component: Aglyn.FieldComponentType.TEXT_FIELD,\n type: 'number',\n },\n {\n name: 'align',\n label: 'Content alignment',\n description:\n 'How every block inside this section lines up. Each block can still ' +\n 'override it with its own alignment.',\n component: Aglyn.FieldComponentType.SELECT,\n options: [\n { value: 'left', label: 'Left' },\n { value: 'center', label: 'Center' },\n { value: 'right', label: 'Right' },\n ],\n },\n ],\n}\n\n// ------------------------------------------------------------------- text\nexport const TEXT_ID: Aglyn.ComponentId = 'emailText'\n\nexport interface EmailTextProps extends EmailBlockStyleProps {\n children?: string\n variant?: 'heading' | 'subheading' | 'body' | 'caption'\n color?: string\n align?: 'left' | 'center' | 'right'\n}\n\nconst TEXT_PRESETS: Record<\n NonNullable<EmailTextProps['variant']>,\n { fontSize: number; fontWeight: number; lineHeight: number }\n> = {\n heading: { fontSize: 28, fontWeight: 700, lineHeight: 1.25 },\n subheading: { fontSize: 20, fontWeight: 600, lineHeight: 1.3 },\n body: { fontSize: 15, fontWeight: 400, lineHeight: 1.55 },\n caption: { fontSize: 12, fontWeight: 400, lineHeight: 1.4 },\n}\n\nexport const EmailText = forwardRef<HTMLDivElement, EmailTextProps>(\n (props, ref) => {\n const { children, variant, color, align, sx, ...rest } = props\n const preset = TEXT_PRESETS[variant ?? 'body']\n return (\n <Typography\n ref={ref}\n component=\"div\"\n {...rest}\n sx={mergeSxProps(\n {\n fontSize: preset.fontSize,\n fontWeight: preset.fontWeight,\n lineHeight: preset.lineHeight,\n color: color || '#1a1a1a',\n textAlign: align ?? 'left',\n fontFamily: 'Helvetica, Arial, sans-serif',\n mb: 1,\n },\n sx,\n )}\n >\n {children ?? 'Email text'}\n </Typography>\n )\n },\n)\nEmailText.displayName = 'EmailText'\n\nexport const emailTextSchema: Aglyn.ComponentSchema<EmailTextProps> = {\n $id: TEXT_ID,\n pluginId: BUNDLE_ID,\n displayName: 'Email text',\n description: 'A paragraph of email copy in one of the preset styles.',\n category: Aglyn.ComponentCategory.DATA_DISPLAY,\n icon: { path: mdiFormatText.path, sx: { color: '#f57c00' } },\n flags: { textEditable: Aglyn.FEATURE_FLAG.ENABLED },\n attributes: [\n {\n name: 'children',\n label: 'Text',\n description:\n 'Supports merge tokens: {{contact.firstName}}, {{contact.email}}, ' +\n '{{org.name}}, {{unsubscribeUrl}}.',\n component: Aglyn.FieldComponentType.TEXTAREA,\n },\n {\n name: 'variant',\n label: 'Style',\n description:\n 'Size and weight of this text — Heading and Subheading also give it ' +\n 'the spacing above and below that a heading needs.',\n component: Aglyn.FieldComponentType.SELECT,\n options: [\n { value: 'heading', label: 'Heading' },\n { value: 'subheading', label: 'Subheading' },\n { value: 'body', label: 'Body' },\n { value: 'caption', label: 'Caption' },\n ],\n },\n {\n name: 'color',\n label: 'Color',\n description:\n 'Text color. Keep it dark on a light background: many clients ' +\n 'ignore dark mode overrides and show your color as-is.',\n component: Aglyn.FieldComponentType.COLOR_PICKER,\n },\n {\n name: 'align',\n label: 'Alignment',\n description: 'How this block of text lines up within the section.',\n component: Aglyn.FieldComponentType.SELECT,\n options: [\n { value: 'left', label: 'Left' },\n { value: 'center', label: 'Center' },\n { value: 'right', label: 'Right' },\n ],\n },\n ],\n}\n\n// --------------------------------------------------------------- richtext\nexport const RICHTEXT_ID: Aglyn.ComponentId = 'emailRichtext'\n\nexport interface EmailRichtextProps extends EmailBlockStyleProps {\n /** HTML fragment; sanitized with the custom-html policy (AGL-320). */\n html?: string\n}\n\nexport const EmailRichtext = forwardRef<HTMLDivElement, EmailRichtextProps>(\n (props, ref) => {\n const { html, sx, ...rest } = props\n if (!html?.trim()) {\n return (\n <Box\n ref={ref}\n {...rest}\n sx={mergeSxProps(\n {\n p: 2,\n border: '1px dashed',\n borderColor: 'divider',\n color: 'text.secondary',\n fontSize: 13,\n },\n sx,\n )}\n >\n {'Rich text — add HTML in the attributes panel'}\n </Box>\n )\n }\n return (\n <Box\n ref={ref}\n {...rest}\n sx={mergeSxProps(\n { fontFamily: 'Helvetica, Arial, sans-serif', fontSize: 15 },\n sx,\n )}\n // Sanitized on every render — same policy as the custom HTML block.\n // The `typeof window` guard this replaced existed only because that\n // policy was DOMPurify, which needs a DOM; it is now a pure function\n // (AGL-1901), so the body survives a server render instead of being\n // blanked — which for an email is the render that gets SENT.\n dangerouslySetInnerHTML={{ __html: sanitizeAuthorHtml(html) }}\n />\n )\n },\n)\nEmailRichtext.displayName = 'EmailRichtext'\n\nexport const emailRichtextSchema: Aglyn.ComponentSchema<EmailRichtextProps> = {\n $id: RICHTEXT_ID,\n pluginId: BUNDLE_ID,\n displayName: 'Email rich text',\n description: 'An HTML fragment in an email, sanitised on render.',\n category: Aglyn.ComponentCategory.DATA_DISPLAY,\n icon: { path: mdiCardTextOutline.path, sx: { color: '#f57c00' } },\n flags: { selfClosing: Aglyn.FEATURE_FLAG.ENABLED },\n attributes: [\n {\n name: 'html',\n label: 'HTML',\n description:\n 'Formatted content (p, b, i, a, ul/ol, h1-h4). Scripts and forms ' +\n 'are stripped; keep styling simple for email clients. Merge ' +\n 'tokens work here too.',\n component: Aglyn.FieldComponentType.TEXTAREA,\n },\n ],\n}\n\n// ------------------------------------------------------------------ image\nexport const IMAGE_ID: Aglyn.ComponentId = 'emailImage'\n\nexport interface EmailImageProps extends EmailBlockStyleProps {\n src?: string\n alt?: string\n /** Rendered width in px (max 600). */\n width?: number\n href?: string\n align?: 'left' | 'center' | 'right'\n}\n\nexport const EmailImage = forwardRef<HTMLDivElement, EmailImageProps>(\n (props, ref) => {\n const { src: storedSrc, alt, width, href, align, sx, ...rest } = props\n // A media-picker target, so it can hold a media reference (AGL-1215).\n // This is the CANVAS preview only — the sent HTML is built by\n // `email-render`, which needs an absolute URL and cannot resolve either\n // a reference or the relative CDN path it replaces.\n const src = Aglyn.resolveMediaSrc(storedSrc)\n return (\n <Box\n ref={ref}\n {...rest}\n sx={mergeSxProps({ textAlign: align ?? 'center', my: 1 }, sx)}\n >\n {src ? (\n <Box\n component=\"img\"\n src={src}\n alt={alt ?? ''}\n sx={{ maxWidth: '100%', width: width ? `${width}px` : '100%' }}\n />\n ) : (\n <Box\n sx={{\n height: 120,\n display: 'flex',\n alignItems: 'center',\n justifyContent: 'center',\n border: '1px dashed',\n borderColor: 'divider',\n color: 'text.secondary',\n fontSize: 13,\n }}\n >\n {'Image — pick from the media library'}\n </Box>\n )}\n </Box>\n )\n },\n)\nEmailImage.displayName = 'EmailImage'\n\nexport const emailImageSchema: Aglyn.ComponentSchema<EmailImageProps> = {\n $id: IMAGE_ID,\n pluginId: BUNDLE_ID,\n displayName: 'Email image',\n description: 'An email-safe image, capped at 600px wide, optionally linked.',\n category: Aglyn.ComponentCategory.DATA_DISPLAY,\n icon: { path: mdiImageOutline.path, sx: { color: '#f57c00' } },\n flags: { selfClosing: Aglyn.FEATURE_FLAG.ENABLED },\n attributes: [\n {\n name: 'src',\n label: 'Source URL',\n description: 'Use an absolute URL — email clients cannot resolve relative paths.',\n component: Aglyn.FieldComponentType.TEXT_FIELD,\n },\n {\n name: 'alt',\n label: 'Alt text',\n // AGL-1896: the same \"Browse media\" default the site Image element\n // gets. It matters MORE here — most clients block images by default,\n // so for most recipients the alt text IS the block.\n description:\n 'Shown while images are blocked — most clients block by default. ' +\n 'Filled in from the media library when you pick a file that has ' +\n 'alt text.',\n component: Aglyn.FieldComponentType.TEXT_FIELD,\n },\n {\n name: 'width',\n label: 'Width (px)',\n description:\n 'How wide the image renders. Blank fills the section — which is ' +\n 'usually right, since a phone is narrower than any number you pick.',\n component: Aglyn.FieldComponentType.TEXT_FIELD,\n type: 'number',\n },\n {\n name: 'href',\n label: 'Link URL',\n description:\n 'Where the image goes when it is clicked. Blank leaves it as a ' +\n 'plain picture.',\n component: Aglyn.FieldComponentType.TEXT_FIELD,\n },\n {\n name: 'align',\n label: 'Alignment',\n description: 'Where the image sits when it is narrower than the section.',\n component: Aglyn.FieldComponentType.SELECT,\n options: [\n { value: 'left', label: 'Left' },\n { value: 'center', label: 'Center' },\n { value: 'right', label: 'Right' },\n ],\n },\n ],\n}\n\n// ----------------------------------------------------------------- button\nexport const BUTTON_ID: Aglyn.ComponentId = 'emailButton'\n\nexport interface EmailButtonProps extends EmailBlockStyleProps {\n children?: string\n href?: string\n backgroundColor?: string\n color?: string\n align?: 'left' | 'center' | 'right'\n}\n\nexport const EmailButton = forwardRef<HTMLDivElement, EmailButtonProps>(\n (props, ref) => {\n const { children, href, backgroundColor, color, align, sx, ...rest } =\n props\n return (\n <Box\n ref={ref}\n {...rest}\n sx={mergeSxProps({ textAlign: align ?? 'center', my: 1.5 }, sx)}\n >\n <Box\n component=\"span\"\n sx={{\n display: 'inline-block',\n px: 3,\n py: 1.25,\n borderRadius: 1,\n // The theme's accent when nothing was picked, as the sent email\n // resolves it (AGL-3370): the canvas and the inbox agree.\n backgroundColor: backgroundColor || 'primary.main',\n color: color || 'primary.contrastText',\n fontFamily: 'Helvetica, Arial, sans-serif',\n fontSize: 15,\n fontWeight: 600,\n }}\n >\n {children ?? 'Call to action'}\n </Box>\n </Box>\n )\n },\n)\nEmailButton.displayName = 'EmailButton'\n\nexport const emailButtonSchema: Aglyn.ComponentSchema<EmailButtonProps> = {\n $id: BUTTON_ID,\n pluginId: BUNDLE_ID,\n displayName: 'Email button',\n description: 'A call-to-action button that survives every mail client.',\n category: Aglyn.ComponentCategory.INPUT,\n icon: { path: mdiGestureTapButton.path, sx: { color: '#f57c00' } },\n flags: { textEditable: Aglyn.FEATURE_FLAG.ENABLED },\n attributes: [\n {\n name: 'children',\n label: 'Label',\n description:\n 'The words on the button. Say what happens next — \"See the report\" ' +\n 'reads as a destination where \"Click here\" does not.',\n component: Aglyn.FieldComponentType.TEXT_FIELD,\n },\n {\n name: 'href',\n label: 'Link URL',\n description: 'Absolute URL (https://…). Merge tokens allowed.',\n component: Aglyn.FieldComponentType.TEXT_FIELD,\n },\n {\n name: 'backgroundColor',\n label: 'Button color',\n description:\n 'The fill behind the label. Check it against the label color — a ' +\n 'button nobody can read is a link nobody clicks.',\n component: Aglyn.FieldComponentType.COLOR_PICKER,\n },\n {\n name: 'color',\n label: 'Label color',\n description: 'The color of the words on the button.',\n component: Aglyn.FieldComponentType.COLOR_PICKER,\n },\n {\n name: 'align',\n label: 'Alignment',\n description: 'Where the button sits across the width of the section.',\n component: Aglyn.FieldComponentType.SELECT,\n options: [\n { value: 'left', label: 'Left' },\n { value: 'center', label: 'Center' },\n { value: 'right', label: 'Right' },\n ],\n },\n ],\n}\n\n// ---------------------------------------------------------------- divider\nexport const DIVIDER_ID: Aglyn.ComponentId = 'emailDivider'\n\nexport interface EmailDividerProps extends EmailBlockStyleProps {\n color?: string\n}\n\nexport const EmailDivider = forwardRef<HTMLHRElement, EmailDividerProps>(\n (props, ref) => {\n const { color, sx, ...rest } = props\n return (\n <Box\n ref={ref}\n component=\"hr\"\n {...rest}\n sx={mergeSxProps(\n {\n border: 0,\n // Split shorthand so a palette token path from the theme-\n // reference color picker (AGL-588) resolves through the sx\n // system instead of dying inside a template string.\n borderTopStyle: 'solid',\n borderTopWidth: 1,\n borderTopColor: color || '#e0e0e0',\n my: 2,\n },\n sx,\n )}\n />\n )\n },\n)\nEmailDivider.displayName = 'EmailDivider'\n\nexport const emailDividerSchema: Aglyn.ComponentSchema<EmailDividerProps> = {\n $id: DIVIDER_ID,\n pluginId: BUNDLE_ID,\n displayName: 'Email divider',\n description: 'A horizontal rule between email sections.',\n category: Aglyn.ComponentCategory.LAYOUT,\n icon: { path: mdiMinus.path, sx: { color: '#f57c00' } },\n flags: { selfClosing: Aglyn.FEATURE_FLAG.ENABLED },\n attributes: [\n {\n name: 'color',\n label: 'Line color',\n description:\n 'The color of the rule. A light grey separates sections without ' +\n 'drawing the eye to the line itself.',\n component: Aglyn.FieldComponentType.COLOR_PICKER,\n },\n ],\n}\n\n// ----------------------------------------------------------------- spacer\nexport const SPACER_ID: Aglyn.ComponentId = 'emailSpacer'\n\nexport interface EmailSpacerProps extends EmailBlockStyleProps {\n /** Height in px (default 24). */\n height?: number\n}\n\nexport const EmailSpacer = forwardRef<HTMLDivElement, EmailSpacerProps>(\n (props, ref) => {\n const { height, sx, ...rest } = props\n return (\n <Box\n ref={ref}\n {...rest}\n sx={mergeSxProps({ height: height ?? 24 }, sx)}\n />\n )\n },\n)\nEmailSpacer.displayName = 'EmailSpacer'\n\nexport const emailSpacerSchema: Aglyn.ComponentSchema<EmailSpacerProps> = {\n $id: SPACER_ID,\n pluginId: BUNDLE_ID,\n displayName: 'Email spacer',\n description: 'Fixed vertical whitespace between email blocks.',\n category: Aglyn.ComponentCategory.LAYOUT,\n icon: { path: mdiArrowExpandVertical.path, sx: { color: '#f57c00' } },\n flags: { selfClosing: Aglyn.FEATURE_FLAG.ENABLED },\n attributes: [\n {\n name: 'height',\n label: 'Height (px)',\n description:\n 'How much empty vertical space this block adds. Email clients drop ' +\n 'CSS margins, so a spacer is how you get reliable breathing room.',\n component: Aglyn.FieldComponentType.TEXT_FIELD,\n type: 'number',\n },\n ],\n}\n\n// ---------------------------------------------------------------- product\nexport const PRODUCT_ID: Aglyn.ComponentId = 'emailProduct'\n\nexport interface EmailProductProps extends EmailBlockStyleProps {\n /** Product id — resolved server-side at render (rename-safe). */\n productId?: string\n buttonLabel?: string\n}\n\nexport const EmailProduct = forwardRef<HTMLDivElement, EmailProductProps>(\n (props, ref) => {\n const { productId, buttonLabel, sx, ...rest } = props\n return (\n <Box\n ref={ref}\n {...rest}\n sx={mergeSxProps(\n {\n border: '1px solid',\n borderColor: 'divider',\n borderRadius: 1,\n p: 2,\n my: 1,\n textAlign: 'center',\n color: 'text.secondary',\n fontSize: 13,\n },\n sx,\n )}\n >\n {productId\n ? `Product card (${productId}) — name, price, image fill in at send`\n : 'Product card — pick a product in the attributes panel'}\n <Box sx={{ mt: 1, fontWeight: 600 }}>\n {buttonLabel ?? 'Shop now'}\n </Box>\n </Box>\n )\n },\n)\nEmailProduct.displayName = 'EmailProduct'\n\nexport const emailProductSchema: Aglyn.ComponentSchema<EmailProductProps> = {\n $id: PRODUCT_ID,\n pluginId: BUNDLE_ID,\n displayName: 'Email product',\n description: 'A product card resolved at send time, so it never goes stale.',\n category: Aglyn.ComponentCategory.DATA_DISPLAY,\n icon: { path: mdiPackageVariantClosed.path, sx: { color: '#f57c00' } },\n flags: { selfClosing: Aglyn.FEATURE_FLAG.ENABLED },\n attributes: [\n {\n name: 'productId',\n label: 'Product',\n description:\n 'Stored by id — the current name, price, and image render at send.',\n component: Aglyn.FieldComponentType.PRODUCT_SELECT,\n },\n {\n name: 'buttonLabel',\n label: 'Button label',\n description:\n 'The words on the card’s button. Blank uses the block’s default, ' +\n 'and the link always points at this product’s page.',\n component: Aglyn.FieldComponentType.TEXT_FIELD,\n },\n ],\n}\n\n// ------------------------------------------------------------ custom html\nexport const HTML_ID: Aglyn.ComponentId = 'emailHtml'\n\nexport interface EmailHtmlProps extends EmailBlockStyleProps {\n html?: string\n}\n\nexport const EmailHtml = forwardRef<HTMLDivElement, EmailHtmlProps>(\n (props, ref) => {\n const { html, sx, ...rest } = props\n return (\n <Box\n ref={ref}\n {...rest}\n sx={mergeSxProps({ fontFamily: 'Helvetica, Arial, sans-serif' }, sx)}\n // No `typeof window` guard any more (AGL-1901): the sanitizer needs\n // no DOM, so a server-rendered email keeps its custom HTML.\n dangerouslySetInnerHTML={{\n __html: html ? sanitizeAuthorHtml(html) : '',\n }}\n />\n )\n },\n)\nEmailHtml.displayName = 'EmailHtml'\n\nexport const emailHtmlSchema: Aglyn.ComponentSchema<EmailHtmlProps> = {\n $id: HTML_ID,\n pluginId: BUNDLE_ID,\n displayName: 'Email custom HTML',\n description: 'Hand-written HTML for an email, used as-is.',\n category: Aglyn.ComponentCategory.DATA_DISPLAY,\n icon: { path: mdiCodeTags.path, sx: { color: '#f57c00' } },\n flags: { selfClosing: Aglyn.FEATURE_FLAG.ENABLED },\n attributes: [\n {\n name: 'html',\n label: 'HTML',\n description:\n 'Raw table markup for advanced layouts. Sanitized with the ' +\n 'custom-html policy; the render pipeline passes it through as-is ' +\n 'after sanitization.',\n component: Aglyn.FieldComponentType.TEXTAREA,\n },\n ],\n}\n\n/**\n * The two bands most emails a site sends begin and end with (AGL-3287).\n *\n * Each drops into any email like the blocks above, and the Components page\n * starts a reusable Header or Footer email block from these same trees, by\n * the ids core names in `REUSABLE_EMAIL_BLOCK_STARTER_PRESET_IDS` — one tree\n * each, wherever it is started from.\n *\n * The words are placeholders to replace. No merge token names the company in\n * both kinds of email — a campaign supplies `{{org.name}}`, and no token is\n * supplied by every one of a site's own emails — while a token an email does\n * not supply is blanked before sending, which would leave the header with no\n * name at all.\n *\n * The footer carries no unsubscribe link: a campaign send appends its own,\n * and a second one would do the same thing twice.\n */\nexport const EMAIL_HEADER_PRESET: Aglyn.PresetSchema = {\n $id: Aglyn.REUSABLE_EMAIL_BLOCK_STARTER_PRESET_IDS.header,\n type: Aglyn.NodeType.PRESET,\n displayName: 'Header',\n description:\n 'Your logo above your company name, for the top of an email. Pick the ' +\n 'logo from your media library — until you do, the picture shows nothing ' +\n 'in a sent email.',\n pluginId: BUNDLE_ID,\n category: Aglyn.ComponentCategory.BLOCKS,\n tags: ['logo', 'masthead', 'top', 'brand'],\n icon: { path: mdiPageLayoutHeader.path, sx: { color: '#f57c00' } },\n // The same tree the Components page and the native apps start a block from.\n data: EMAIL_BLOCK_STARTER_TREES.header as Aglyn.PresetSchema['data'],\n}\n\n/** See {@link EMAIL_HEADER_PRESET}. */\nexport const EMAIL_FOOTER_PRESET: Aglyn.PresetSchema = {\n $id: Aglyn.REUSABLE_EMAIL_BLOCK_STARTER_PRESET_IDS.footer,\n type: Aglyn.NodeType.PRESET,\n displayName: 'Footer',\n description:\n 'Your company name and address, and why the reader gets your emails, for ' +\n 'the bottom of an email. Campaign emails add the unsubscribe link for you.',\n pluginId: BUNDLE_ID,\n category: Aglyn.ComponentCategory.BLOCKS,\n tags: ['address', 'bottom', 'contact', 'legal'],\n icon: { path: mdiPageLayoutFooter.path, sx: { color: '#f57c00' } },\n // The same tree the Components page and the native apps start a block from.\n data: EMAIL_BLOCK_STARTER_TREES.footer as Aglyn.PresetSchema['data'],\n}\n\nexport const emailPresets: Aglyn.PresetSchema[] = [\n {\n $id: generatePresetId(SECTION_ID),\n type: Aglyn.NodeType.PRESET,\n displayName: 'Email section',\n pluginId: BUNDLE_ID,\n category: Aglyn.ComponentCategory.LAYOUT,\n icon: { path: mdiEmailOutline.path, sx: { color: '#f57c00' } },\n data: {\n $id: null,\n componentId: SECTION_ID,\n pluginId: BUNDLE_ID,\n props: {},\n },\n },\n {\n $id: generatePresetId(TEXT_ID),\n type: Aglyn.NodeType.PRESET,\n displayName: 'Email text',\n pluginId: BUNDLE_ID,\n category: Aglyn.ComponentCategory.DATA_DISPLAY,\n icon: { path: mdiFormatText.path, sx: { color: '#f57c00' } },\n data: {\n $id: null,\n componentId: TEXT_ID,\n pluginId: BUNDLE_ID,\n props: { children: 'Hello {{contact.firstName}},', variant: 'body' },\n },\n },\n {\n $id: generatePresetId(RICHTEXT_ID),\n type: Aglyn.NodeType.PRESET,\n displayName: 'Email rich text',\n pluginId: BUNDLE_ID,\n category: Aglyn.ComponentCategory.DATA_DISPLAY,\n icon: { path: mdiCardTextOutline.path, sx: { color: '#f57c00' } },\n data: {\n $id: null,\n componentId: RICHTEXT_ID,\n pluginId: BUNDLE_ID,\n props: {},\n },\n },\n {\n $id: generatePresetId(IMAGE_ID),\n type: Aglyn.NodeType.PRESET,\n displayName: 'Email image',\n pluginId: BUNDLE_ID,\n category: Aglyn.ComponentCategory.DATA_DISPLAY,\n icon: { path: mdiImageOutline.path, sx: { color: '#f57c00' } },\n data: {\n $id: null,\n componentId: IMAGE_ID,\n pluginId: BUNDLE_ID,\n props: {},\n },\n },\n {\n $id: generatePresetId(BUTTON_ID),\n type: Aglyn.NodeType.PRESET,\n displayName: 'Email button',\n pluginId: BUNDLE_ID,\n category: Aglyn.ComponentCategory.INPUT,\n icon: { path: mdiGestureTapButton.path, sx: { color: '#f57c00' } },\n data: {\n $id: null,\n componentId: BUTTON_ID,\n pluginId: BUNDLE_ID,\n props: { children: 'Shop now' },\n },\n },\n {\n $id: generatePresetId(DIVIDER_ID),\n type: Aglyn.NodeType.PRESET,\n displayName: 'Email divider',\n pluginId: BUNDLE_ID,\n category: Aglyn.ComponentCategory.LAYOUT,\n icon: { path: mdiMinus.path, sx: { color: '#f57c00' } },\n data: {\n $id: null,\n componentId: DIVIDER_ID,\n pluginId: BUNDLE_ID,\n props: {},\n },\n },\n {\n $id: generatePresetId(SPACER_ID),\n type: Aglyn.NodeType.PRESET,\n displayName: 'Email spacer',\n pluginId: BUNDLE_ID,\n category: Aglyn.ComponentCategory.LAYOUT,\n icon: { path: mdiArrowExpandVertical.path, sx: { color: '#f57c00' } },\n data: {\n $id: null,\n componentId: SPACER_ID,\n pluginId: BUNDLE_ID,\n props: {},\n },\n },\n {\n $id: generatePresetId(PRODUCT_ID),\n type: Aglyn.NodeType.PRESET,\n displayName: 'Email product',\n pluginId: BUNDLE_ID,\n category: Aglyn.ComponentCategory.DATA_DISPLAY,\n icon: { path: mdiPackageVariantClosed.path, sx: { color: '#f57c00' } },\n data: {\n $id: null,\n componentId: PRODUCT_ID,\n pluginId: BUNDLE_ID,\n props: {},\n },\n },\n {\n $id: generatePresetId(HTML_ID),\n type: Aglyn.NodeType.PRESET,\n displayName: 'Email custom HTML',\n pluginId: BUNDLE_ID,\n category: Aglyn.ComponentCategory.DATA_DISPLAY,\n icon: { path: mdiCodeTags.path, sx: { color: '#f57c00' } },\n data: {\n $id: null,\n componentId: HTML_ID,\n pluginId: BUNDLE_ID,\n props: {},\n },\n },\n EMAIL_HEADER_PRESET,\n EMAIL_FOOTER_PRESET,\n]\n"],"names":["Aglyn","mdiCardTextOutline","mdiEmailOutline","mdiFormatText","mdiImageOutline","mdiMinus","mdiPackageVariantClosed","mdiPageLayoutFooter","mdiPageLayoutHeader","mdiArrowExpandVertical","mdiGestureTapButton","mdiCodeTags","sanitizeAuthorHtml","EMAIL_BLOCK_STARTER_TREES","mergeSxProps","Box","Typography","forwardRef","BUNDLE_ID","generatePresetId","SECTION_ID","EmailSection","props","ref","backgroundColor","padding","align","children","sx","emailRole","_emailRole","rest","maxWidth","mx","p","textAlign","displayName","emailSectionSchema","$id","pluginId","description","category","ComponentCategory","LAYOUT","icon","path","color","attributes","name","label","component","FieldComponentType","COLOR_PICKER","TEXT_FIELD","type","SELECT","options","value","TEXT_ID","TEXT_PRESETS","heading","fontSize","fontWeight","lineHeight","subheading","body","caption","EmailText","variant","preset","fontFamily","mb","emailTextSchema","DATA_DISPLAY","flags","textEditable","FEATURE_FLAG","ENABLED","TEXTAREA","RICHTEXT_ID","EmailRichtext","html","trim","border","borderColor","dangerouslySetInnerHTML","__html","emailRichtextSchema","selfClosing","IMAGE_ID","EmailImage","src","storedSrc","alt","width","href","resolveMediaSrc","my","height","display","alignItems","justifyContent","emailImageSchema","BUTTON_ID","EmailButton","px","py","borderRadius","emailButtonSchema","INPUT","DIVIDER_ID","EmailDivider","borderTopStyle","borderTopWidth","borderTopColor","emailDividerSchema","SPACER_ID","EmailSpacer","emailSpacerSchema","PRODUCT_ID","EmailProduct","productId","buttonLabel","mt","emailProductSchema","PRODUCT_SELECT","HTML_ID","EmailHtml","emailHtmlSchema","EMAIL_HEADER_PRESET","REUSABLE_EMAIL_BLOCK_STARTER_PRESET_IDS","header","NodeType","PRESET","BLOCKS","tags","data","EMAIL_FOOTER_PRESET","footer","emailPresets","componentId"],"mappings":"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"}