Share base style syntax between rendering and editor validation
Quality / quality (ubuntu-latest) (push) Failing after 1s
Quality / quality (windows-latest) (push) Canceled after 0s

This commit is contained in:
Clintchiz committed 2026-09-05 19:06:09 +05:30
1 parent 16d804e16f
commit 14669bb4f3
4 files changed
+45 -10

No files matched your search

+9 -8
View File
@@ -12,6 +12,7 @@ import {
type ValueSchema,
} from "@wrnexus/blocks";
import { brandColor, brandFont, brandWidth } from "./brand.ts";
import { emailStyleValue } from "./style-values.ts";
const styles = record(json, { maxKeys: 50 }) as never;
const label = (key: string, fallback: string) => ({ key, fallback });
@@ -87,14 +88,14 @@ const safeCssValue = (value: unknown, pattern: RegExp) => {
};
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)$/);
const color = emailStyleValue("color", styleBase(node, "color"));
const background = emailStyleValue("backgroundColor", styleBase(node, "backgroundColor"));
const padding = emailStyleValue("padding", styleBase(node, "padding"));
const margin = emailStyleValue("margin", styleBase(node, "margin"));
const fontSize = emailStyleValue("fontSize", styleBase(node, "fontSize"));
const radius = emailStyleValue("borderRadius", styleBase(node, "borderRadius"));
const align = emailStyleValue("textAlign", styleBase(node, "textAlign"));
const weight = emailStyleValue("fontWeight", styleBase(node, "fontWeight"));
if (color) declarations.push(`color:${color}`);
if (background) declarations.push(`background-color:${background}`);
if (padding) declarations.push(`padding:${padding}`);
@@ -0,0 +1,20 @@
const color = /^(#[0-9a-f]{3}|#[0-9a-f]{4}|#[0-9a-f]{6}|#[0-9a-f]{8}|rgba?\([0-9., %]+\))$/i;
const spacing = /^(?:0|\d+(?:\.\d+)?(?:px|rem|em|%))(?:\s+(?:0|\d+(?:\.\d+)?(?:px|rem|em|%))){0,3}$/;
const patterns: Record<string, RegExp> = {
color, backgroundColor: color, padding: spacing, margin: spacing,
fontSize: /^\d+(?:\.\d+)?(?:px|rem|em|%)$/,
borderRadius: /^(?:0|\d+(?:\.\d+)?(?:px|rem|em|%))$/,
textAlign: /^(left|center|right|start|end)$/,
fontWeight: /^(normal|bold|[1-9]00)$/,
};
/** Accepted base-value syntax shared by the inspector and semantic style compiler. */
export function emailStyleValue(key: string, value: unknown): string {
if (typeof value !== "string") return "";
const candidate = value.trim();
return candidate.length <= 80 && Object.prototype.hasOwnProperty.call(patterns, key) && patterns[key]!.test(candidate) ? candidate : "";
}
export function validateEmailStyleValue(key: string, value: string): void {
if (!emailStyleValue(key, value)) throw new Error(`styles.${key}: Unsupported style value. Use an email-safe value with units where required.`);
}