@samva/markup 0.5.0 → 0.6.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.
- package/AGENTS.md +2 -0
- package/dist/{ast-BLybiDxp.d.ts → ast-BrDtApwS.d.ts} +2 -2
- package/dist/ast.d.ts +1 -1
- package/dist/ast.js +1 -1
- package/dist/{catalog-Db0UcCTg.d.ts → catalog-60eaYC7b.d.ts} +2 -2
- package/dist/{checks-CmmITP6j.js → checks-DBweSIPN.js} +12 -14
- package/dist/checks.d.ts +1 -1
- package/dist/checks.js +1 -1
- package/dist/classes.d.ts +1 -1
- package/dist/compile-sms.d.ts +3 -3
- package/dist/compile-whatsapp.d.ts +3 -3
- package/dist/compile.d.ts +2 -2
- package/dist/compiler.d.ts +7 -4
- package/dist/compiler.js +40 -40
- package/dist/components.d.ts +4 -4
- package/dist/conditionals.js +55 -23
- package/dist/{corpus-CM7rKX41.d.ts → corpus-BjYMqOoY.d.ts} +2 -2
- package/dist/{css-DoNc7CiC.d.ts → css-COcFOT1y.d.ts} +3 -3
- package/dist/{diagnostics-eFM9A_TU.d.ts → diagnostics-BMYtBCQk.d.ts} +2 -2
- package/dist/{diagnostics-CqepLcpI.d.ts → diagnostics-OcQKQYSY.d.ts} +4 -2
- package/dist/diagnostics.d.ts +2 -2
- package/dist/diagnostics.js +10 -5
- package/dist/{elements-ChJULZlh.d.ts → elements-BzjjnoCS.d.ts} +3 -3
- package/dist/email/components.d.ts +1 -1
- package/dist/email/components.js +40 -10
- package/dist/email/diagnostics.d.ts +1 -1
- package/dist/email/elements.d.ts +1 -1
- package/dist/email/html.d.ts +2 -2
- package/dist/email/html.js +2 -1
- package/dist/email/jsx-dev-runtime.d.ts +2 -2
- package/dist/email/jsx-runtime.d.ts +1 -1
- package/dist/email/render.d.ts +4 -4
- package/dist/email/render.js +1 -1
- package/dist/email/selection.d.ts +1 -1
- package/dist/email/source-edit.d.ts +1 -1
- package/dist/email/stylesheets.d.ts +1 -1
- package/dist/email/text.d.ts +1 -1
- package/dist/emit.d.ts +2 -2
- package/dist/footer.js +7 -4
- package/dist/jsx-dev-runtime.d.ts +2 -2
- package/dist/{jsx-runtime-BI4gI19E.d.ts → jsx-runtime-I-1nCtl2.d.ts} +3 -3
- package/dist/jsx-runtime.d.ts +1 -1
- package/dist/lexer.js +17 -5
- package/dist/model.d.ts +1 -1
- package/dist/ops-2aiiYO7m.js +630 -0
- package/dist/ops.d.ts +2 -2
- package/dist/ops.js +1 -479
- package/dist/{parser-b_Kp5MT6.d.ts → parser-CQcASEyy.d.ts} +3 -3
- package/dist/parser.d.ts +1 -1
- package/dist/parser.js +1 -1
- package/dist/{predicate-DwXzmqIY.js → predicate-BI6uRRM-.js} +14 -4
- package/dist/{predicate-Bmvgw7Ao.d.ts → predicate-M-05Nd7R.d.ts} +2 -2
- package/dist/predicate.d.ts +1 -1
- package/dist/predicate.js +1 -1
- package/dist/presets/category-mapping.d.ts +1 -1
- package/dist/presets/corpus.d.ts +1 -1
- package/dist/presets/public-gallery.d.ts +2 -2
- package/dist/presets/public-gallery.js +10 -2
- package/dist/presets/public-handoff.d.ts +2 -2
- package/dist/presets/public-preview-artifacts.d.ts +3 -1
- package/dist/presets/public-preview-artifacts.js +1 -0
- package/dist/presets/showcase.d.ts +1 -1
- package/dist/presets.d.ts +1 -1
- package/dist/printer.d.ts +1 -1
- package/dist/{render-T6IFPnP4.js → render-aaJBnsXK.js} +33 -16
- package/dist/render-template.d.ts +5 -5
- package/dist/render-template.js +1 -1
- package/dist/{showcase-dvJMn-Lo.d.ts → showcase-DGZAWn4Z.d.ts} +2 -2
- package/dist/{source-locations-D6Te6Gy1.d.ts → source-locations-DrCM82Ym.d.ts} +2 -2
- package/dist/source-locations.d.ts +1 -1
- package/dist/{template-G-QPcfmn.d.ts → template-DWftqh4x.d.ts} +2 -2
- package/dist/template.d.ts +1 -1
- package/dist/theme-css.d.ts +1 -1
- package/dist/theme.js +25 -2
- package/dist/tsx-tracer.d.ts +1 -1
- package/dist/tsx-tracer.js +1 -1
- package/dist/{variables-BnKs1iqb.d.ts → variables-J_L3qxRa.d.ts} +2 -2
- package/dist/variables.d.ts +1 -1
- package/dist/variables.js +1 -1
- package/package.json +1 -1
package/AGENTS.md
CHANGED
|
@@ -20,6 +20,8 @@ Schema with its validator, so which schema library an author reaches for stays t
|
|
|
20
20
|
Email entries default-export `defineEmail` definitions. SMS and WhatsApp use the structured
|
|
21
21
|
channel runtime at `@samva/markup` and components at `@samva/markup/components`.
|
|
22
22
|
Use documented package subpaths only. Template entry discovery is `.tsx` only.
|
|
23
|
+
`presets/sources.gen.ts` is generated: run `bun run codegen:presets` from this package, never hand-edit
|
|
24
|
+
it.
|
|
23
25
|
|
|
24
26
|
Object email templates use `jsxImportSource: "@samva/markup/email"` and
|
|
25
27
|
`defineEmail` from `@samva/markup/template`. Their render function receives actual validated
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { a as Span } from "./diagnostics-
|
|
1
|
+
import { a as Span } from "./diagnostics-OcQKQYSY.js";
|
|
2
2
|
//#region src/ast.d.ts
|
|
3
3
|
declare const BLOCK_TAGS: readonly ["Email", "Subject", "Preview", "Container", "Section", "Row", "Column", "Heading", "Text", "Button", "Image", "Divider", "Spacer", "List", "ListItem", "If", "Else"];
|
|
4
4
|
declare const INLINE_TAGS: readonly ["strong", "em", "a"];
|
|
@@ -104,4 +104,4 @@ declare const isHiddenNode: (node: ElementNode) => boolean;
|
|
|
104
104
|
declare const collectVariableReferences: (document: SmlDocument) => ReadonlySet<string>;
|
|
105
105
|
//#endregion
|
|
106
106
|
export { nodeLabel as A, TextNode as C, documentChannel as D, componentNameForSmlTag as E, smlTagForComponentName as M, stringAttribute as N, isHiddenNode as O, SmlTag as S, collectVariableReferences as T, RootTag as _, BLOCK_TAGS as a, SmlDocument as b, CHANNEL_TAGS as c, DEFAULT_EMAIL_WIDTH as d, ElementNode as f, ROOT_TAGS as g, InterpolationNode as h, AuxiliaryTag as i, numberAttribute as j, isRootTag as k, Channel as l, InlineTag as m, Attribute as n, BlockTag as o, INLINE_TAGS as p, AttributeValue as r, CHANNEL_BY_ROOT_TAG as s, AUXILIARY_TAGS as t, ChannelTag as u, SML_TAGS as v, attributeValue as w, SmlNode as x, SML_TAG_BY_COMPONENT_NAME as y };
|
|
107
|
-
//# sourceMappingURL=ast-
|
|
107
|
+
//# sourceMappingURL=ast-BrDtApwS.d.ts.map
|
package/dist/ast.d.ts
CHANGED
|
@@ -1,2 +1,2 @@
|
|
|
1
|
-
import { A as nodeLabel, C as TextNode, D as documentChannel, E as componentNameForSmlTag, M as smlTagForComponentName, N as stringAttribute, O as isHiddenNode, S as SmlTag, T as collectVariableReferences, _ as RootTag, a as BLOCK_TAGS, b as SmlDocument, c as CHANNEL_TAGS, d as DEFAULT_EMAIL_WIDTH, f as ElementNode, g as ROOT_TAGS, h as InterpolationNode, i as AuxiliaryTag, j as numberAttribute, k as isRootTag, l as Channel, m as InlineTag, n as Attribute, o as BlockTag, p as INLINE_TAGS, r as AttributeValue, s as CHANNEL_BY_ROOT_TAG, t as AUXILIARY_TAGS, u as ChannelTag, v as SML_TAGS, w as attributeValue, x as SmlNode, y as SML_TAG_BY_COMPONENT_NAME } from "./ast-
|
|
1
|
+
import { A as nodeLabel, C as TextNode, D as documentChannel, E as componentNameForSmlTag, M as smlTagForComponentName, N as stringAttribute, O as isHiddenNode, S as SmlTag, T as collectVariableReferences, _ as RootTag, a as BLOCK_TAGS, b as SmlDocument, c as CHANNEL_TAGS, d as DEFAULT_EMAIL_WIDTH, f as ElementNode, g as ROOT_TAGS, h as InterpolationNode, i as AuxiliaryTag, j as numberAttribute, k as isRootTag, l as Channel, m as InlineTag, n as Attribute, o as BlockTag, p as INLINE_TAGS, r as AttributeValue, s as CHANNEL_BY_ROOT_TAG, t as AUXILIARY_TAGS, u as ChannelTag, v as SML_TAGS, w as attributeValue, x as SmlNode, y as SML_TAG_BY_COMPONENT_NAME } from "./ast-BrDtApwS.js";
|
|
2
2
|
export { AUXILIARY_TAGS, Attribute, AttributeValue, AuxiliaryTag, BLOCK_TAGS, BlockTag, CHANNEL_BY_ROOT_TAG, CHANNEL_TAGS, Channel, ChannelTag, DEFAULT_EMAIL_WIDTH, ElementNode, INLINE_TAGS, InlineTag, InterpolationNode, ROOT_TAGS, RootTag, SML_TAGS, SML_TAG_BY_COMPONENT_NAME, SmlDocument, SmlNode, SmlTag, TextNode, attributeValue, collectVariableReferences, componentNameForSmlTag, documentChannel, isHiddenNode, isRootTag, nodeLabel, numberAttribute, smlTagForComponentName, stringAttribute };
|
package/dist/ast.js
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { i as parsePredicate, n as collectPredicateVariables } from "./predicate-
|
|
1
|
+
import { i as parsePredicate, n as collectPredicateVariables } from "./predicate-BI6uRRM-.js";
|
|
2
2
|
import { Result } from "better-result";
|
|
3
3
|
//#region src/ast.ts
|
|
4
4
|
const BLOCK_TAGS = [
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { l as Channel } from "./ast-
|
|
1
|
+
import { l as Channel } from "./ast-BrDtApwS.js";
|
|
2
2
|
import { o as TokenOverrides } from "./theme-6ApjjiBo.js";
|
|
3
3
|
//#region presets/catalog.d.ts
|
|
4
4
|
type PresetCategory = "transactional" | "digest" | "marketing" | "lifecycle";
|
|
@@ -353,4 +353,4 @@ type EmailPresetVariable = EmailPreset extends (infer Preset) ? Preset extends {
|
|
|
353
353
|
} ? Variable : never : never;
|
|
354
354
|
//#endregion
|
|
355
355
|
export { PresetMeta as a, presetCatalog as c, PresetId as i, EmailPresetVariable as n, PresetVariable as o, PresetCategory as r, RECOMMENDED_THEME as s, EmailPresetId as t };
|
|
356
|
-
//# sourceMappingURL=catalog-
|
|
356
|
+
//# sourceMappingURL=catalog-60eaYC7b.d.ts.map
|
|
@@ -1,5 +1,5 @@
|
|
|
1
|
-
import {
|
|
2
|
-
import { i as parsePredicate } from "./predicate-
|
|
1
|
+
import { createDiagnosticFormatter } from "./diagnostics.js";
|
|
2
|
+
import { i as parsePredicate } from "./predicate-BI6uRRM-.js";
|
|
3
3
|
import { stringAttribute } from "./ast.js";
|
|
4
4
|
import { parseCandidate, splitRoot } from "./candidate.js";
|
|
5
5
|
import { registryRoots, utilityRegistry } from "./registry.js";
|
|
@@ -58830,7 +58830,7 @@ const predicateSource = (source, attribute) => {
|
|
|
58830
58830
|
})
|
|
58831
58831
|
};
|
|
58832
58832
|
};
|
|
58833
|
-
const predicateDiagnosticMessages = (source, document, declaredVariables) => {
|
|
58833
|
+
const predicateDiagnosticMessages = (source, document, declaredVariables, formatDiagnostic) => {
|
|
58834
58834
|
const messages = [];
|
|
58835
58835
|
const declared = declaredVariables === void 0 ? void 0 : new Set(declaredVariables);
|
|
58836
58836
|
const visit = (node) => {
|
|
@@ -58840,9 +58840,9 @@ const predicateDiagnosticMessages = (source, document, declaredVariables) => {
|
|
|
58840
58840
|
if (testAttribute?.value.kind === "string") {
|
|
58841
58841
|
const predicate = predicateSource(source, testAttribute);
|
|
58842
58842
|
const parsed = parsePredicate(predicate.text);
|
|
58843
|
-
if (Result.isError(parsed)) for (const diagnostic of parsed.error) messages.push(`error: ${formatDiagnostic(
|
|
58843
|
+
if (Result.isError(parsed)) for (const diagnostic of parsed.error) messages.push(`error: ${formatDiagnostic(predicate.mapDiagnostic(diagnostic))}`);
|
|
58844
58844
|
else if (declared !== void 0) {
|
|
58845
|
-
for (const reference of collectPredicateVariableReferences(parsed.value)) if (!declared.has(reference.name)) messages.push(`error: ${formatDiagnostic(
|
|
58845
|
+
for (const reference of collectPredicateVariableReferences(parsed.value)) if (!declared.has(reference.name)) messages.push(`error: ${formatDiagnostic({
|
|
58846
58846
|
code: "predicate-unknown-variable",
|
|
58847
58847
|
message: `unknown predicate variable "${reference.name}" in <If test>`,
|
|
58848
58848
|
span: predicate.mapSpan(reference.span)
|
|
@@ -58855,11 +58855,7 @@ const predicateDiagnosticMessages = (source, document, declaredVariables) => {
|
|
|
58855
58855
|
visit(document.root);
|
|
58856
58856
|
return messages;
|
|
58857
58857
|
};
|
|
58858
|
-
const parseFailurePredicateMessages = (
|
|
58859
|
-
const parsed = parseSml(source);
|
|
58860
|
-
if (Result.isOk(parsed)) return [];
|
|
58861
|
-
return parsed.error.diagnostics.filter((diagnostic) => diagnostic.code.startsWith("predicate-")).map((diagnostic) => `error: ${formatDiagnostic(source, diagnostic)}`);
|
|
58862
|
-
};
|
|
58858
|
+
const parseFailurePredicateMessages = (diagnostics, formatDiagnostic) => diagnostics.filter((diagnostic) => diagnostic.code.startsWith("predicate-")).map((diagnostic) => `error: ${formatDiagnostic(diagnostic)}`);
|
|
58863
58859
|
const clientsByDarkBehavior = (profile, behavior) => profile.targets.filter((target) => target.darkBehavior === behavior).map(targetLabel).filter((label, index, labels) => labels.indexOf(label) === index);
|
|
58864
58860
|
const gmailForcedInvertClients = (profile) => profile.targets.filter((target) => target.family === "gmail" && target.darkBehavior === "force-inverts").map(targetLabel);
|
|
58865
58861
|
const formatClientList = (clients) => clients.join(", ");
|
|
@@ -58941,11 +58937,13 @@ function worstCaseArtifactBytes(html) {
|
|
|
58941
58937
|
function checkSmlCompatibility(input) {
|
|
58942
58938
|
const profile = input.profile ?? DEFAULT_EMAIL_TARGET_CLIENT_PROFILE;
|
|
58943
58939
|
const parsed = parseSml(input.source);
|
|
58944
|
-
|
|
58940
|
+
let formatter;
|
|
58941
|
+
const formatDiagnostic = (diagnostic) => (formatter ??= createDiagnosticFormatter(input.source))(diagnostic);
|
|
58942
|
+
if (Result.isError(parsed)) return parseFailurePredicateMessages(parsed.error.diagnostics, formatDiagnostic);
|
|
58945
58943
|
const analysis = analyzeDocument(parsed.value);
|
|
58946
58944
|
return [
|
|
58947
|
-
...predicateDiagnosticMessages(input.source, parsed.value, input.declaredVariables),
|
|
58948
|
-
...checkDeliveryAssetDiagnostics(input.source).map((diagnostic) => `error: ${formatDiagnostic(
|
|
58945
|
+
...predicateDiagnosticMessages(input.source, parsed.value, input.declaredVariables, formatDiagnostic),
|
|
58946
|
+
...checkDeliveryAssetDiagnostics(input.source).map((diagnostic) => `error: ${formatDiagnostic(diagnostic)}`),
|
|
58949
58947
|
...caniemailMessages(analysis.featureSlugs, profile),
|
|
58950
58948
|
...darkModeMessages(analysis, profile)
|
|
58951
58949
|
];
|
|
@@ -58953,4 +58951,4 @@ function checkSmlCompatibility(input) {
|
|
|
58953
58951
|
//#endregion
|
|
58954
58952
|
export { isBreakingCompatibilityCheck as a, collectSmlFeatureSlugs as i, checkDeliveryAssetDiagnostics as n, worstCaseArtifactBytes as o, checkSmlCompatibility as r, DEFAULT_EMAIL_TARGET_CLIENT_PROFILE as t };
|
|
58955
58953
|
|
|
58956
|
-
//# sourceMappingURL=checks-
|
|
58954
|
+
//# sourceMappingURL=checks-DBweSIPN.js.map
|
package/dist/checks.d.ts
CHANGED
package/dist/checks.js
CHANGED
|
@@ -1,2 +1,2 @@
|
|
|
1
|
-
import { a as isBreakingCompatibilityCheck, i as collectSmlFeatureSlugs, n as checkDeliveryAssetDiagnostics, o as worstCaseArtifactBytes, r as checkSmlCompatibility, t as DEFAULT_EMAIL_TARGET_CLIENT_PROFILE } from "./checks-
|
|
1
|
+
import { a as isBreakingCompatibilityCheck, i as collectSmlFeatureSlugs, n as checkDeliveryAssetDiagnostics, o as worstCaseArtifactBytes, r as checkSmlCompatibility, t as DEFAULT_EMAIL_TARGET_CLIENT_PROFILE } from "./checks-DBweSIPN.js";
|
|
2
2
|
export { DEFAULT_EMAIL_TARGET_CLIENT_PROFILE, checkDeliveryAssetDiagnostics, checkSmlCompatibility, collectSmlFeatureSlugs, isBreakingCompatibilityCheck, worstCaseArtifactBytes };
|
package/dist/classes.d.ts
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { a as Span, t as Diagnostic } from "./diagnostics-
|
|
1
|
+
import { a as Span, t as Diagnostic } from "./diagnostics-OcQKQYSY.js";
|
|
2
2
|
import { s as TokenTable } from "./theme-6ApjjiBo.js";
|
|
3
3
|
import { Declaration } from "./registry.js";
|
|
4
4
|
//#region src/classes.d.ts
|
package/dist/compile-sms.d.ts
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
|
-
import { t as Diagnostic } from "./diagnostics-
|
|
2
|
-
import { f as ElementNode } from "./ast-
|
|
3
|
-
import { a as SMS_TAG_SPECS } from "./parser-
|
|
1
|
+
import { t as Diagnostic } from "./diagnostics-OcQKQYSY.js";
|
|
2
|
+
import { f as ElementNode } from "./ast-BrDtApwS.js";
|
|
3
|
+
import { a as SMS_TAG_SPECS } from "./parser-CQcASEyy.js";
|
|
4
4
|
import { t as SmsEncoding } from "./sms-segments-y4FpPilJ.js";
|
|
5
5
|
//#region src/compile-sms.d.ts
|
|
6
6
|
/** Documented worst-case rendered width of one `{{variable}}`. */
|
|
@@ -1,6 +1,6 @@
|
|
|
1
|
-
import { r as SmlCompileError, t as Diagnostic } from "./diagnostics-
|
|
2
|
-
import { f as ElementNode } from "./ast-
|
|
3
|
-
import { l as WHATSAPP_TAG_SPECS } from "./parser-
|
|
1
|
+
import { r as SmlCompileError, t as Diagnostic } from "./diagnostics-OcQKQYSY.js";
|
|
2
|
+
import { f as ElementNode } from "./ast-BrDtApwS.js";
|
|
3
|
+
import { l as WHATSAPP_TAG_SPECS } from "./parser-CQcASEyy.js";
|
|
4
4
|
import { Result } from "better-result";
|
|
5
5
|
//#region src/compile-whatsapp.d.ts
|
|
6
6
|
type WhatsAppSpecs = typeof WHATSAPP_TAG_SPECS;
|
package/dist/compile.d.ts
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
|
-
import { i as SmlParseError, r as SmlCompileError } from "./diagnostics-
|
|
2
|
-
import { b as SmlDocument } from "./ast-
|
|
1
|
+
import { i as SmlParseError, r as SmlCompileError } from "./diagnostics-OcQKQYSY.js";
|
|
2
|
+
import { b as SmlDocument } from "./ast-BrDtApwS.js";
|
|
3
3
|
import { CompiledSms } from "./compile-sms.js";
|
|
4
4
|
import { CompiledWhatsApp } from "./compile-whatsapp.js";
|
|
5
5
|
import { Result } from "better-result";
|
package/dist/compiler.d.ts
CHANGED
|
@@ -1,9 +1,9 @@
|
|
|
1
|
-
import { a as formatEmailDiagnostic, i as EmailDiagnosticSeverity, n as EmailCompileError, o as hasBlockingDiagnostic, r as EmailDiagnostic } from "./diagnostics-
|
|
2
|
-
import { a as EmailGlobalProps, c as EmailStyle, d as isUrlAttribute, i as EmailElementSpec, l as EmailTag, m as EmailNode, n as EMAIL_GLOBAL_ATTRIBUTES, o as EmailIntrinsicElements, r as EmailAttributeSpec, s as EmailLayout, t as EMAIL_ELEMENTS, u as emailElement } from "./elements-
|
|
1
|
+
import { a as formatEmailDiagnostic, i as EmailDiagnosticSeverity, n as EmailCompileError, o as hasBlockingDiagnostic, r as EmailDiagnostic } from "./diagnostics-BMYtBCQk.js";
|
|
2
|
+
import { a as EmailGlobalProps, c as EmailStyle, d as isUrlAttribute, i as EmailElementSpec, l as EmailTag, m as EmailNode, n as EMAIL_GLOBAL_ATTRIBUTES, o as EmailIntrinsicElements, r as EmailAttributeSpec, s as EmailLayout, t as EMAIL_ELEMENTS, u as emailElement } from "./elements-BzjjnoCS.js";
|
|
3
3
|
import { EmailElementSelection, EmittedPosition, INSTANCE_PATH_ATTRIBUTE, emailAuthoringTarget, emailDefinitionInstances, emailSelectionAncestry, emailSelectionIndex, emailSelectionSiblings, emailSelections } from "./email/selection.js";
|
|
4
4
|
import { EmailHtmlOutput, SerializeEmailOptions, escapeAttribute, escapeText, serializeEmailHtml } from "./email/html.js";
|
|
5
5
|
import { deriveEmailText } from "./email/text.js";
|
|
6
|
-
import { a as compileSelector, c as CompiledSelector, d as matchesSelector, i as Stylesheet, l as Compound, n as CssRule, o as parseStylesheet, r as Specificity, s as Ancestry, t as CssDeclaration, u as classListOf } from "./css-
|
|
6
|
+
import { a as compileSelector, c as CompiledSelector, d as matchesSelector, i as Stylesheet, l as Compound, n as CssRule, o as parseStylesheet, r as Specificity, s as Ancestry, t as CssDeclaration, u as classListOf } from "./css-COcFOT1y.js";
|
|
7
7
|
import { EMAIL_DOCTYPE, EmailCompileOutput, RenderedEmail, compileEmail, renderEmail } from "./email/render.js";
|
|
8
8
|
import { collectStylesheets, hasStylesheets, registerStylesheet, resetStylesheets } from "./email/stylesheets.js";
|
|
9
9
|
import { instrumentTsxSourceForPreview } from "./tsx-source-instrumentation.js";
|
|
@@ -104,7 +104,10 @@ declare const isExternalAsset: (reference: string) => boolean;
|
|
|
104
104
|
declare const checkAssetBase: (base: string) => readonly EmailDiagnostic[];
|
|
105
105
|
//#endregion
|
|
106
106
|
//#region src/email/css-values.d.ts
|
|
107
|
-
/**
|
|
107
|
+
/**
|
|
108
|
+
* Expand `var(--x, fallback)` against the collected custom properties.
|
|
109
|
+
* Values whose expansion exceeds the render-time budget are left as authored.
|
|
110
|
+
*/
|
|
108
111
|
declare const resolveVariables: (value: string, variables: Readonly<Record<string, string>>, depth?: number) => string;
|
|
109
112
|
/**
|
|
110
113
|
* Fold a constant `calc()` to a plain value. Tailwind writes every spacing
|
package/dist/compiler.js
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import { n as isObject } from "./guards-eV1qLbf2.js";
|
|
2
|
-
import { a as applyStylesheet, c as downlevelMediaQuery, d as renderHeadCss, f as resolveVariables, i as renderEmail, l as finalizeValue, o as classListOf, r as compileEmail, s as matchesSelector, t as EMAIL_DOCTYPE, u as foldCalc } from "./render-
|
|
2
|
+
import { a as applyStylesheet, c as downlevelMediaQuery, d as renderHeadCss, f as resolveVariables, i as renderEmail, l as finalizeValue, o as classListOf, r as compileEmail, s as matchesSelector, t as EMAIL_DOCTYPE, u as foldCalc } from "./render-aaJBnsXK.js";
|
|
3
3
|
import { EMAIL_ELEMENTS, EMAIL_GLOBAL_ATTRIBUTES, emailElement, isUrlAttribute } from "./email/elements.js";
|
|
4
4
|
import { INSTANCE_PATH_ATTRIBUTE, emailAuthoringTarget, emailDefinitionInstances, emailSelectionAncestry, emailSelectionIndex, emailSelectionSiblings, emailSelections } from "./email/selection.js";
|
|
5
5
|
import { escapeAttribute, escapeText, serializeEmailHtml } from "./email/html.js";
|
|
@@ -895,45 +895,6 @@ const compileSelector = (selector) => {
|
|
|
895
895
|
};
|
|
896
896
|
/** Substitute a nested rule's `&` against its parent selector. */
|
|
897
897
|
const nestSelector = (parent, child) => child.includes("&") ? child.replaceAll("&", parent) : `${parent} ${child}`;
|
|
898
|
-
const selectorFacts = /* @__PURE__ */ new Map();
|
|
899
|
-
/** Everything a rule needs from its selector, computed once per distinct string. */
|
|
900
|
-
const factsFor = (selector) => {
|
|
901
|
-
const cached = selectorFacts.get(selector);
|
|
902
|
-
if (cached !== void 0) return cached;
|
|
903
|
-
let facts;
|
|
904
|
-
try {
|
|
905
|
-
const node = parse$1(selector, {
|
|
906
|
-
context: "selector",
|
|
907
|
-
positions: false
|
|
908
|
-
});
|
|
909
|
-
const classes = /* @__PURE__ */ new Set();
|
|
910
|
-
walk(node, {
|
|
911
|
-
visit: "ClassSelector",
|
|
912
|
-
enter: (part) => {
|
|
913
|
-
classes.add(ident.decode(part.name));
|
|
914
|
-
}
|
|
915
|
-
});
|
|
916
|
-
facts = {
|
|
917
|
-
classes: [...classes],
|
|
918
|
-
specificity: specificityOf(node),
|
|
919
|
-
pseudo: hasPseudo(node),
|
|
920
|
-
matcher: compileSelector(selector)
|
|
921
|
-
};
|
|
922
|
-
} catch {
|
|
923
|
-
facts = {
|
|
924
|
-
classes: [],
|
|
925
|
-
specificity: [
|
|
926
|
-
0,
|
|
927
|
-
0,
|
|
928
|
-
0
|
|
929
|
-
],
|
|
930
|
-
pseudo: true,
|
|
931
|
-
matcher: void 0
|
|
932
|
-
};
|
|
933
|
-
}
|
|
934
|
-
selectorFacts.set(selector, facts);
|
|
935
|
-
return facts;
|
|
936
|
-
};
|
|
937
898
|
/** Parse one stylesheet into rules, keeping layer, order and conditions. */
|
|
938
899
|
const parseStylesheet = (source, options = {}) => {
|
|
939
900
|
const rules = [];
|
|
@@ -942,7 +903,46 @@ const parseStylesheet = (source, options = {}) => {
|
|
|
942
903
|
const conditionalVariables = /* @__PURE__ */ new Set();
|
|
943
904
|
const diagnostics = [];
|
|
944
905
|
const layers = /* @__PURE__ */ new Map();
|
|
906
|
+
const selectorFacts = /* @__PURE__ */ new Map();
|
|
945
907
|
let order = options.startOrder ?? 0;
|
|
908
|
+
/** Everything a rule needs from its selector, computed once per distinct string. */
|
|
909
|
+
const factsFor = (selector) => {
|
|
910
|
+
const cached = selectorFacts.get(selector);
|
|
911
|
+
if (cached !== void 0) return cached;
|
|
912
|
+
let facts;
|
|
913
|
+
try {
|
|
914
|
+
const node = parse$1(selector, {
|
|
915
|
+
context: "selector",
|
|
916
|
+
positions: false
|
|
917
|
+
});
|
|
918
|
+
const classes = /* @__PURE__ */ new Set();
|
|
919
|
+
walk(node, {
|
|
920
|
+
visit: "ClassSelector",
|
|
921
|
+
enter: (part) => {
|
|
922
|
+
classes.add(ident.decode(part.name));
|
|
923
|
+
}
|
|
924
|
+
});
|
|
925
|
+
facts = {
|
|
926
|
+
classes: [...classes],
|
|
927
|
+
specificity: specificityOf(node),
|
|
928
|
+
pseudo: hasPseudo(node),
|
|
929
|
+
matcher: compileSelector(selector)
|
|
930
|
+
};
|
|
931
|
+
} catch {
|
|
932
|
+
facts = {
|
|
933
|
+
classes: [],
|
|
934
|
+
specificity: [
|
|
935
|
+
0,
|
|
936
|
+
0,
|
|
937
|
+
0
|
|
938
|
+
],
|
|
939
|
+
pseudo: true,
|
|
940
|
+
matcher: void 0
|
|
941
|
+
};
|
|
942
|
+
}
|
|
943
|
+
selectorFacts.set(selector, facts);
|
|
944
|
+
return facts;
|
|
945
|
+
};
|
|
946
946
|
let ast;
|
|
947
947
|
try {
|
|
948
948
|
ast = parse$1(source, {
|
package/dist/components.d.ts
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
|
-
import { f as ElementNode } from "./ast-
|
|
2
|
-
import { i as EMAIL_TAG_SPECS, l as WHATSAPP_TAG_SPECS, o as TagSpec, t as AttributeSpec } from "./parser-
|
|
3
|
-
import { r as PredicateRef, s as VariableRef } from "./variables-
|
|
4
|
-
import { s as SmlChildren } from "./jsx-runtime-
|
|
1
|
+
import { f as ElementNode } from "./ast-BrDtApwS.js";
|
|
2
|
+
import { i as EMAIL_TAG_SPECS, l as WHATSAPP_TAG_SPECS, o as TagSpec, t as AttributeSpec } from "./parser-CQcASEyy.js";
|
|
3
|
+
import { r as PredicateRef, s as VariableRef } from "./variables-J_L3qxRa.js";
|
|
4
|
+
import { s as SmlChildren } from "./jsx-runtime-I-1nCtl2.js";
|
|
5
5
|
//#region src/components.d.ts
|
|
6
6
|
/**
|
|
7
7
|
* The scalar type an attribute spec accepts. `level` narrows to the Heading
|
package/dist/conditionals.js
CHANGED
|
@@ -1,31 +1,63 @@
|
|
|
1
|
-
import { i as parsePredicate, r as evaluatePredicate } from "./predicate-
|
|
1
|
+
import { i as parsePredicate, r as evaluatePredicate } from "./predicate-BI6uRRM-.js";
|
|
2
2
|
import { Result } from "better-result";
|
|
3
3
|
//#region src/conditionals.ts
|
|
4
4
|
const IF_MARKER = "<!--sml:if:";
|
|
5
5
|
const MARKER_CLOSE = "-->";
|
|
6
6
|
const resolve = (content, variables) => {
|
|
7
|
-
const
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
7
|
+
const stack = [{
|
|
8
|
+
cursor: 0,
|
|
9
|
+
end: content.length,
|
|
10
|
+
trim: false,
|
|
11
|
+
chunks: []
|
|
12
|
+
}];
|
|
13
|
+
let resolved = content;
|
|
14
|
+
while (stack.length > 0) {
|
|
15
|
+
const frame = stack.at(-1);
|
|
16
|
+
const start = content.indexOf(IF_MARKER, frame.cursor);
|
|
17
|
+
if (start === -1 || start >= frame.end) {
|
|
18
|
+
frame.chunks.push(content.slice(frame.cursor, frame.end));
|
|
19
|
+
const value = frame.trim ? frame.chunks.join("").trim() : frame.chunks.join("");
|
|
20
|
+
stack.pop();
|
|
21
|
+
const parent = stack.at(-1);
|
|
22
|
+
if (parent === void 0) resolved = value;
|
|
23
|
+
else parent.chunks.push(value);
|
|
24
|
+
continue;
|
|
25
|
+
}
|
|
26
|
+
const headEnd = content.indexOf(MARKER_CLOSE, start);
|
|
27
|
+
if (headEnd === -1 || headEnd >= frame.end) {
|
|
28
|
+
frame.chunks.push(content.slice(frame.cursor, frame.end));
|
|
29
|
+
frame.cursor = frame.end;
|
|
30
|
+
continue;
|
|
31
|
+
}
|
|
32
|
+
const header = content.slice(start + 11, headEnd);
|
|
33
|
+
const spaceIndex = header.indexOf(" ");
|
|
34
|
+
const id = spaceIndex === -1 ? header : header.slice(0, spaceIndex);
|
|
35
|
+
const predicateSource = spaceIndex === -1 ? "" : header.slice(spaceIndex + 1);
|
|
36
|
+
const elseMarker = `<!--sml:else:${id}-->`;
|
|
37
|
+
const endMarker = `<!--sml:endif:${id}-->`;
|
|
38
|
+
const bodyStart = headEnd + 3;
|
|
39
|
+
const endIndex = content.indexOf(endMarker, bodyStart);
|
|
40
|
+
if (endIndex === -1 || endIndex + endMarker.length > frame.end) {
|
|
41
|
+
frame.chunks.push(content.slice(frame.cursor, frame.end));
|
|
42
|
+
frame.cursor = frame.end;
|
|
43
|
+
continue;
|
|
44
|
+
}
|
|
45
|
+
const elseCandidate = content.indexOf(elseMarker, bodyStart);
|
|
46
|
+
const elseIndex = elseCandidate !== -1 && elseCandidate < endIndex ? elseCandidate : -1;
|
|
47
|
+
const parsed = parsePredicate(predicateSource);
|
|
48
|
+
const condition = Result.isOk(parsed) && evaluatePredicate(parsed.value, variables);
|
|
49
|
+
const branchStart = condition ? bodyStart : elseIndex === -1 ? endIndex : elseIndex + elseMarker.length;
|
|
50
|
+
const branchEnd = condition && elseIndex !== -1 ? elseIndex : endIndex;
|
|
51
|
+
frame.chunks.push(content.slice(frame.cursor, start));
|
|
52
|
+
frame.cursor = endIndex + endMarker.length;
|
|
53
|
+
stack.push({
|
|
54
|
+
cursor: branchStart,
|
|
55
|
+
end: branchEnd,
|
|
56
|
+
trim: true,
|
|
57
|
+
chunks: []
|
|
58
|
+
});
|
|
59
|
+
}
|
|
60
|
+
return resolved;
|
|
29
61
|
};
|
|
30
62
|
/**
|
|
31
63
|
* Selects <If> branches in a compiled artifact (html or plain-text alt) for
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { n as OwnedShowcaseId, t as BrandRecreationShowcaseId } from "./showcase-
|
|
1
|
+
import { n as OwnedShowcaseId, t as BrandRecreationShowcaseId } from "./showcase-DGZAWn4Z.js";
|
|
2
2
|
import { Result } from "better-result";
|
|
3
3
|
//#region presets/corpus.d.ts
|
|
4
4
|
type TemplateCorpusKind = "owned-editable-sml" | "brand-recreation-sml" | "inspiration-reference";
|
|
@@ -103,4 +103,4 @@ type TemplateFacetQuery = Partial<TemplateFacetSet>;
|
|
|
103
103
|
declare const matchesTemplateFacets: (facets: TemplateFacetSet, query: TemplateFacetQuery) => boolean;
|
|
104
104
|
//#endregion
|
|
105
105
|
export { PublicCorpusRegistrationIssue as a, TemplateFacetQuery as c, matchesTemplateFacets as d, ownedPresetSourcePath as f, templateFacetOptions as h, PublicCorpusRegistration as i, TemplateFacetSet as l, registerPublicCorpusEntry as m, InspirationReference as n, TemplateCorpusKind as o, ownedShowcasePresetSources as p, OwnedEditablePreset as r, TemplateCorpusRecord as s, BrandRecreationPreset as t, brandRecreationProvenance as u };
|
|
106
|
-
//# sourceMappingURL=corpus-
|
|
106
|
+
//# sourceMappingURL=corpus-BjYMqOoY.d.ts.map
|
|
@@ -1,5 +1,5 @@
|
|
|
1
|
-
import { r as EmailDiagnostic } from "./diagnostics-
|
|
2
|
-
import { m as EmailNode } from "./elements-
|
|
1
|
+
import { r as EmailDiagnostic } from "./diagnostics-BMYtBCQk.js";
|
|
2
|
+
import { m as EmailNode } from "./elements-BzjjnoCS.js";
|
|
3
3
|
import "css-tree";
|
|
4
4
|
//#region src/email/selectors.d.ts
|
|
5
5
|
type EmailElementNode = Extract<EmailNode, {
|
|
@@ -80,4 +80,4 @@ declare const parseStylesheet: (source: string, options?: {
|
|
|
80
80
|
}) => Stylesheet;
|
|
81
81
|
//#endregion
|
|
82
82
|
export { compileSelector as a, CompiledSelector as c, matchesSelector as d, Stylesheet as i, Compound as l, CssRule as n, parseStylesheet as o, Specificity as r, Ancestry as s, CssDeclaration as t, classListOf as u };
|
|
83
|
-
//# sourceMappingURL=css-
|
|
83
|
+
//# sourceMappingURL=css-COcFOT1y.d.ts.map
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { i as JsxSourceLocation } from "./source-locations-
|
|
1
|
+
import { i as JsxSourceLocation } from "./source-locations-DrCM82Ym.js";
|
|
2
2
|
//#region src/email/diagnostics.d.ts
|
|
3
3
|
type EmailDiagnosticSeverity = "error" | "warning" | "info";
|
|
4
4
|
/** What the emitted document establishes beyond the client feature matrix. */
|
|
@@ -43,4 +43,4 @@ declare const formatEmailDiagnostic: (diagnostic: EmailDiagnostic) => string;
|
|
|
43
43
|
declare const hasBlockingDiagnostic: (diagnostics: readonly EmailDiagnostic[]) => boolean;
|
|
44
44
|
//#endregion
|
|
45
45
|
export { formatEmailDiagnostic as a, EmailDiagnosticSeverity as i, EmailCompileError as n, hasBlockingDiagnostic as o, EmailDiagnostic as r, EmailCompatibilityAssessment as t };
|
|
46
|
-
//# sourceMappingURL=diagnostics-
|
|
46
|
+
//# sourceMappingURL=diagnostics-BMYtBCQk.d.ts.map
|
|
@@ -40,8 +40,10 @@ declare const lineColumn: (lineMap: ReadonlyArray<number>, offset: number) => {
|
|
|
40
40
|
readonly line: number;
|
|
41
41
|
readonly column: number;
|
|
42
42
|
};
|
|
43
|
+
/** Build one formatter for a batch of diagnostics against the same source. */
|
|
44
|
+
declare const createDiagnosticFormatter: (source: string) => ((diagnostic: Diagnostic) => string);
|
|
43
45
|
/** "line 12:8 unknown class ..." — the shape agents iterate on. */
|
|
44
46
|
declare const formatDiagnostic: (source: string, diagnostic: Diagnostic) => string;
|
|
45
47
|
//#endregion
|
|
46
|
-
export { Span as a,
|
|
47
|
-
//# sourceMappingURL=diagnostics-
|
|
48
|
+
export { Span as a, formatDiagnostic as c, SmlParseError as i, lineColumn as l, DiagnosticRepair as n, buildLineMap as o, SmlCompileError as r, createDiagnosticFormatter as s, Diagnostic as t };
|
|
49
|
+
//# sourceMappingURL=diagnostics-OcQKQYSY.d.ts.map
|
package/dist/diagnostics.d.ts
CHANGED
|
@@ -1,2 +1,2 @@
|
|
|
1
|
-
import { a as Span, c as
|
|
2
|
-
export { Diagnostic, DiagnosticRepair, SmlCompileError, SmlParseError, Span, buildLineMap, formatDiagnostic, lineColumn };
|
|
1
|
+
import { a as Span, c as formatDiagnostic, i as SmlParseError, l as lineColumn, n as DiagnosticRepair, o as buildLineMap, r as SmlCompileError, s as createDiagnosticFormatter, t as Diagnostic } from "./diagnostics-OcQKQYSY.js";
|
|
2
|
+
export { Diagnostic, DiagnosticRepair, SmlCompileError, SmlParseError, Span, buildLineMap, createDiagnosticFormatter, formatDiagnostic, lineColumn };
|
package/dist/diagnostics.js
CHANGED
|
@@ -40,12 +40,17 @@ const lineColumn = (lineMap, offset) => {
|
|
|
40
40
|
column: offset - lineMap[low] + 1
|
|
41
41
|
};
|
|
42
42
|
};
|
|
43
|
-
/**
|
|
44
|
-
const
|
|
45
|
-
const
|
|
46
|
-
return
|
|
43
|
+
/** Build one formatter for a batch of diagnostics against the same source. */
|
|
44
|
+
const createDiagnosticFormatter = (source) => {
|
|
45
|
+
const lineMap = buildLineMap(source);
|
|
46
|
+
return (diagnostic) => {
|
|
47
|
+
const { line, column } = lineColumn(lineMap, diagnostic.span.start);
|
|
48
|
+
return `line ${line}:${column} ${diagnostic.message}`;
|
|
49
|
+
};
|
|
47
50
|
};
|
|
51
|
+
/** "line 12:8 unknown class ..." — the shape agents iterate on. */
|
|
52
|
+
const formatDiagnostic = (source, diagnostic) => createDiagnosticFormatter(source)(diagnostic);
|
|
48
53
|
//#endregion
|
|
49
|
-
export { SmlCompileError, SmlParseError, buildLineMap, formatDiagnostic, lineColumn };
|
|
54
|
+
export { SmlCompileError, SmlParseError, buildLineMap, createDiagnosticFormatter, formatDiagnostic, lineColumn };
|
|
50
55
|
|
|
51
56
|
//# sourceMappingURL=diagnostics.js.map
|
|
@@ -1,5 +1,5 @@
|
|
|
1
|
-
import { i as JsxSourceLocation } from "./source-locations-
|
|
2
|
-
import { r as EmailDiagnostic } from "./diagnostics-
|
|
1
|
+
import { i as JsxSourceLocation } from "./source-locations-DrCM82Ym.js";
|
|
2
|
+
import { r as EmailDiagnostic } from "./diagnostics-BMYtBCQk.js";
|
|
3
3
|
//#region src/email/jsx-runtime.d.ts
|
|
4
4
|
/** Derived authoring tree; source stays canonical. Origins run from inner element to component call sites. */
|
|
5
5
|
type EmailNode = {
|
|
@@ -696,4 +696,4 @@ type ChildrenProp<Content extends EmailElementSpec["content"]> = Content extends
|
|
|
696
696
|
type EmailIntrinsicElements = { readonly [Tag in EmailTag]: EmailGlobalProps & AttributeProps<typeof EMAIL_GLOBAL_ATTRIBUTES> & AttributeProps<(typeof EMAIL_ELEMENTS)[Tag]["attributes"]> & ChildrenProp<(typeof EMAIL_ELEMENTS)[Tag]["content"]>; };
|
|
697
697
|
//#endregion
|
|
698
698
|
export { reportEmailDiagnostic as C, rawMarkup as S, currentEmailOrigins as _, EmailGlobalProps as a, jsxs as b, EmailStyle as c, isUrlAttribute as d, EmailChild as f, JSX as g, Fragment as h, EmailElementSpec as i, EmailTag as l, EmailNode as m, EMAIL_GLOBAL_ATTRIBUTES as n, EmailIntrinsicElements as o, EmailComponent as p, EmailAttributeSpec as r, EmailLayout as s, EMAIL_ELEMENTS as t, emailElement as u, drainEmailDiagnostics as v, normalizeChildren as x, jsx as y };
|
|
699
|
-
//# sourceMappingURL=elements-
|
|
699
|
+
//# sourceMappingURL=elements-BzjjnoCS.d.ts.map
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { c as EmailStyle, f as EmailChild, m as EmailNode } from "../elements-
|
|
1
|
+
import { c as EmailStyle, f as EmailChild, m as EmailNode } from "../elements-BzjjnoCS.js";
|
|
2
2
|
//#region src/email/components.d.ts
|
|
3
3
|
/** Marks the hidden preview block so the renderer can read it back and the text lane can keep it. */
|
|
4
4
|
declare const PREHEADER_ATTRIBUTE = "data-samva-preheader";
|
package/dist/email/components.js
CHANGED
|
@@ -107,24 +107,54 @@ const Column = ({ className, align, valign, width, style, children }) => jsx("td
|
|
|
107
107
|
const DEFAULT_BUTTON_FONT = "Helvetica, Arial, sans-serif";
|
|
108
108
|
/** Average advance of a bold sans-serif glyph, as a fraction of the font size. */
|
|
109
109
|
const BOLD_GLYPH_ADVANCE = .6;
|
|
110
|
+
const invalidButtonNumber = (name) => reportEmailDiagnostic({
|
|
111
|
+
code: "invalid-button-number",
|
|
112
|
+
severity: "error",
|
|
113
|
+
message: `<Button ${name}> must be a finite number.`
|
|
114
|
+
});
|
|
115
|
+
const buttonNumber = (name, value, fallback) => {
|
|
116
|
+
if (typeof value === "number" && Number.isFinite(value)) return value;
|
|
117
|
+
invalidButtonNumber(name);
|
|
118
|
+
return fallback;
|
|
119
|
+
};
|
|
120
|
+
const optionalButtonNumber = (name, value) => {
|
|
121
|
+
if (value === void 0) return void 0;
|
|
122
|
+
if (typeof value === "number" && Number.isFinite(value)) return value;
|
|
123
|
+
invalidButtonNumber(name);
|
|
124
|
+
};
|
|
125
|
+
const optionalPositiveButtonNumber = (name, value) => {
|
|
126
|
+
if (value === void 0) return void 0;
|
|
127
|
+
if (typeof value === "number" && Number.isFinite(value) && value > 0) return value;
|
|
128
|
+
reportEmailDiagnostic({
|
|
129
|
+
code: "invalid-button-number",
|
|
130
|
+
severity: "error",
|
|
131
|
+
message: `<Button ${name}> must be a positive finite number.`
|
|
132
|
+
});
|
|
133
|
+
};
|
|
110
134
|
/** A link styled as a button, with a VML fallback so classic Outlook draws the shape. */
|
|
111
135
|
const Button = ({ className, href, width, height, paddingX = 16, backgroundColor = "#000000", color = "#ffffff", borderRadius = 0, borderColor, borderWidth = 0, fontSize = 16, fontFamily = DEFAULT_BUTTON_FONT, align = "left", style, children }) => {
|
|
136
|
+
const safeWidth = optionalButtonNumber("width", width);
|
|
137
|
+
const safeHeight = optionalPositiveButtonNumber("height", height);
|
|
138
|
+
const safePaddingX = buttonNumber("paddingX", paddingX, 16);
|
|
139
|
+
const safeBorderRadius = buttonNumber("borderRadius", borderRadius, 0);
|
|
140
|
+
const safeBorderWidth = buttonNumber("borderWidth", borderWidth, 0);
|
|
141
|
+
const safeFontSize = buttonNumber("fontSize", fontSize, 16);
|
|
112
142
|
const label = typeof children === "string" ? children : void 0;
|
|
113
|
-
const fallback =
|
|
143
|
+
const fallback = safeHeight !== void 0 && label !== void 0;
|
|
114
144
|
if (!fallback) reportEmailDiagnostic({
|
|
115
145
|
code: "button-outlook-fallback",
|
|
116
146
|
severity: "warning",
|
|
117
147
|
message: "<Button> draws its classic Outlook shape from VML, which needs a height and a plain string label. Without both, classic Windows Outlook shows an unstyled link.",
|
|
118
148
|
clients: ["outlook-windows"]
|
|
119
149
|
});
|
|
120
|
-
const arcsize =
|
|
121
|
-
const fallbackWidth =
|
|
150
|
+
const arcsize = safeHeight === void 0 ? 0 : Math.round(safeBorderRadius / safeHeight * 100);
|
|
151
|
+
const fallbackWidth = safeWidth ?? Math.ceil((label?.length ?? 0) * safeFontSize * BOLD_GLYPH_ADVANCE) + 2 * safePaddingX;
|
|
122
152
|
return presentation({
|
|
123
153
|
width: "100%",
|
|
124
154
|
style: { borderCollapse: "collapse" }
|
|
125
155
|
}, jsx("td", {
|
|
126
156
|
align,
|
|
127
|
-
children: [fallback ? rawMarkup(`<!--[if mso]><v:roundrect xmlns:v="urn:schemas-microsoft-com:vml" xmlns:w="urn:schemas-microsoft-com:office:word" href="${escapeAttribute(href)}" style="height:${
|
|
157
|
+
children: [fallback ? rawMarkup(`<!--[if mso]><v:roundrect xmlns:v="urn:schemas-microsoft-com:vml" xmlns:w="urn:schemas-microsoft-com:office:word" href="${escapeAttribute(href)}" style="height:${safeHeight}px;v-text-anchor:middle;width:${fallbackWidth}px;" arcsize="${arcsize}%" ${borderColor === void 0 ? "stroke=\"false\"" : `strokecolor="${escapeAttribute(borderColor)}" strokeweight="${safeBorderWidth}px"`} fillcolor="${escapeAttribute(backgroundColor)}"><w:anchorlock/><center style="color:${escapeAttribute(color)};font-family:${escapeAttribute(fontFamily)};font-size:${safeFontSize}px;font-weight:bold;">${escapeText(label)}</center></v:roundrect><![endif]-->`) : null, jsx("a", {
|
|
128
158
|
className,
|
|
129
159
|
href,
|
|
130
160
|
target: "_blank",
|
|
@@ -132,19 +162,19 @@ const Button = ({ className, href, width, height, paddingX = 16, backgroundColor
|
|
|
132
162
|
style: {
|
|
133
163
|
backgroundColor,
|
|
134
164
|
color,
|
|
135
|
-
borderRadius: `${
|
|
165
|
+
borderRadius: `${safeBorderRadius}px`,
|
|
136
166
|
display: "inline-block",
|
|
137
167
|
fontFamily,
|
|
138
|
-
fontSize: `${
|
|
168
|
+
fontSize: `${safeFontSize}px`,
|
|
139
169
|
fontWeight: "bold",
|
|
140
|
-
lineHeight:
|
|
170
|
+
lineHeight: safeHeight === void 0 ? "120%" : `${safeHeight - 2 * safeBorderWidth}px`,
|
|
141
171
|
textAlign: "center",
|
|
142
172
|
textDecoration: "none",
|
|
143
|
-
...
|
|
144
|
-
width: `${
|
|
173
|
+
...safeWidth === void 0 ? { padding: `0 ${safePaddingX}px` } : {
|
|
174
|
+
width: `${safeWidth}px`,
|
|
145
175
|
maxWidth: "100%"
|
|
146
176
|
},
|
|
147
|
-
...borderColor === void 0 ? {} : { border: `${
|
|
177
|
+
...borderColor === void 0 ? {} : { border: `${safeBorderWidth}px solid ${borderColor}` },
|
|
148
178
|
...fallback ? { msoHide: "all" } : {},
|
|
149
179
|
...style
|
|
150
180
|
},
|
|
@@ -1,2 +1,2 @@
|
|
|
1
|
-
import { a as formatEmailDiagnostic, i as EmailDiagnosticSeverity, n as EmailCompileError, o as hasBlockingDiagnostic, r as EmailDiagnostic, t as EmailCompatibilityAssessment } from "../diagnostics-
|
|
1
|
+
import { a as formatEmailDiagnostic, i as EmailDiagnosticSeverity, n as EmailCompileError, o as hasBlockingDiagnostic, r as EmailDiagnostic, t as EmailCompatibilityAssessment } from "../diagnostics-BMYtBCQk.js";
|
|
2
2
|
export { EmailCompatibilityAssessment, EmailCompileError, EmailDiagnostic, EmailDiagnosticSeverity, formatEmailDiagnostic, hasBlockingDiagnostic };
|
package/dist/email/elements.d.ts
CHANGED
|
@@ -1,2 +1,2 @@
|
|
|
1
|
-
import { a as EmailGlobalProps, c as EmailStyle, d as isUrlAttribute, i as EmailElementSpec, l as EmailTag, n as EMAIL_GLOBAL_ATTRIBUTES, o as EmailIntrinsicElements, r as EmailAttributeSpec, s as EmailLayout, t as EMAIL_ELEMENTS, u as emailElement } from "../elements-
|
|
1
|
+
import { a as EmailGlobalProps, c as EmailStyle, d as isUrlAttribute, i as EmailElementSpec, l as EmailTag, n as EMAIL_GLOBAL_ATTRIBUTES, o as EmailIntrinsicElements, r as EmailAttributeSpec, s as EmailLayout, t as EMAIL_ELEMENTS, u as emailElement } from "../elements-BzjjnoCS.js";
|
|
2
2
|
export { EMAIL_ELEMENTS, EMAIL_GLOBAL_ATTRIBUTES, EmailAttributeSpec, EmailElementSpec, EmailGlobalProps, EmailIntrinsicElements, EmailLayout, EmailStyle, EmailTag, emailElement, isUrlAttribute };
|
package/dist/email/html.d.ts
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
|
-
import { r as EmailDiagnostic } from "../diagnostics-
|
|
2
|
-
import { m as EmailNode } from "../elements-
|
|
1
|
+
import { r as EmailDiagnostic } from "../diagnostics-BMYtBCQk.js";
|
|
2
|
+
import { m as EmailNode } from "../elements-BzjjnoCS.js";
|
|
3
3
|
import { EmittedPosition } from "./selection.js";
|
|
4
4
|
//#region src/email/html.d.ts
|
|
5
5
|
/** Escape a value for element content. */
|