feat(email-renderer): compile safe semantic styles
This commit is contained in:
1 parent
353cadda60
commit
2428df6e78
3 files changed
+49
-2
No files matched your search
@@ -30,8 +30,38 @@ const html = (value: unknown) =>
|
||||
.replaceAll('"', """)
|
||||
.replaceAll("'", "'");
|
||||
const attrs = (node: BlockNode) => node.props as Record<string, unknown>;
|
||||
const styleBase = (node: BlockNode, key: string) => {
|
||||
const value = (node.styles as Record<string, unknown>)[key];
|
||||
return value && typeof value === "object" && !Array.isArray(value)
|
||||
? (value as Record<string, unknown>).base
|
||||
: undefined;
|
||||
};
|
||||
const safeCssValue = (value: unknown, pattern: RegExp) => {
|
||||
const candidate = String(value ?? "").trim();
|
||||
return candidate.length <= 80 && pattern.test(candidate) ? candidate : "";
|
||||
};
|
||||
const semanticStyle = (node: BlockNode) => {
|
||||
const declarations: string[] = [];
|
||||
const color = safeCssValue(styleBase(node, "color"), /^(#[0-9a-f]{3,8}|rgba?\([0-9., %]+\))$/i);
|
||||
const background = safeCssValue(styleBase(node, "backgroundColor"), /^(#[0-9a-f]{3,8}|rgba?\([0-9., %]+\))$/i);
|
||||
const padding = safeCssValue(styleBase(node, "padding"), /^\d+(?:\.\d+)?(?:px|rem|em|%)?(?:\s+\d+(?:\.\d+)?(?:px|rem|em|%)?){0,3}$/);
|
||||
const margin = safeCssValue(styleBase(node, "margin"), /^\d+(?:\.\d+)?(?:px|rem|em|%)?(?:\s+\d+(?:\.\d+)?(?:px|rem|em|%)?){0,3}$/);
|
||||
const fontSize = safeCssValue(styleBase(node, "fontSize"), /^\d+(?:\.\d+)?(?:px|rem|em|%)$/);
|
||||
const radius = safeCssValue(styleBase(node, "borderRadius"), /^\d+(?:\.\d+)?(?:px|rem|em|%)$/);
|
||||
const align = safeCssValue(styleBase(node, "textAlign"), /^(left|center|right|start|end)$/);
|
||||
const weight = safeCssValue(styleBase(node, "fontWeight"), /^(normal|bold|[1-9]00)$/);
|
||||
if (color) declarations.push(`color:${color}`);
|
||||
if (background) declarations.push(`background-color:${background}`);
|
||||
if (padding) declarations.push(`padding:${padding}`);
|
||||
if (margin) declarations.push(`margin:${margin}`);
|
||||
if (fontSize) declarations.push(`font-size:${fontSize}`);
|
||||
if (radius) declarations.push(`border-radius:${radius}`);
|
||||
if (align) declarations.push(`text-align:${align}`);
|
||||
if (weight) declarations.push(`font-weight:${weight}`);
|
||||
return declarations.join(";");
|
||||
};
|
||||
const emailCell = (body: string, node: BlockNode) =>
|
||||
`<tr><td data-block-id="${html(node.id)}" style="padding:0;">${body}</td></tr>`;
|
||||
`<tr><td data-block-id="${html(node.id)}" style="padding:0;${semanticStyle(node)}">${body}</td></tr>`;
|
||||
|
||||
export const emailDocumentBlock = defineBlock({
|
||||
manifest: {
|
||||
|
||||
Reference in new issue
Block a user