@samva/markup 0.9.0 → 0.10.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.
Files changed (88) hide show
  1. package/AGENTS.md +48 -40
  2. package/CHANGELOG.md +345 -0
  3. package/README.md +6 -6
  4. package/dist/{brand-B-0bN_Ir.d.ts → assets-BIsyMQ92.d.ts} +41 -11
  5. package/dist/{email/brand.js → brand-C0MKTwmX.js} +64 -4
  6. package/dist/{theme-css.d.ts → brand.d.ts} +12 -3
  7. package/dist/brand.js +4 -0
  8. package/dist/compiler.d.ts +231 -11
  9. package/dist/compiler.js +1312 -13
  10. package/dist/components-BZCqegS8.js +1864 -0
  11. package/dist/diagnostic-model-DJtqbETd.js +38 -0
  12. package/dist/diagnostic-model-DxthUZBT.d.ts +31 -0
  13. package/dist/{email/diagnostics.js → diagnostics-CnKFefKz.js} +2 -2
  14. package/dist/diagnostics.d.ts +406 -27
  15. package/dist/diagnostics.js +402 -34
  16. package/dist/edit.d.ts +234 -0
  17. package/dist/{channel-edit.js → edit.js} +341 -3
  18. package/dist/email/jsx-dev-runtime.d.ts +1 -1
  19. package/dist/email/jsx-dev-runtime.js +1 -2
  20. package/dist/email/jsx-runtime.d.ts +1 -1
  21. package/dist/email/jsx-runtime.js +1 -85
  22. package/dist/{email/components.d.ts → email.d.ts} +2 -2
  23. package/dist/email.js +2 -0
  24. package/dist/index.d.ts +1 -1
  25. package/dist/index.js +1 -1
  26. package/dist/{cascade-t6kxlgEI.js → ir-CLhlklKV.js} +8 -4
  27. package/dist/jsx-runtime-CBlexoeR.js +98 -0
  28. package/dist/{elements-cqldpaJt.d.ts → jsx-runtime-ylIOnaSf.d.ts} +74 -74
  29. package/dist/{profile-BH-OtdDA.js → profile-pWGtWZXF.js} +153 -20
  30. package/dist/render-BPonDpCl.d.ts +539 -0
  31. package/dist/{email/render.js → render-BQmfh94k.js} +102 -8
  32. package/dist/render.d.ts +35 -0
  33. package/dist/render.js +49 -0
  34. package/dist/sms.d.ts +1 -1
  35. package/dist/sms.js +1 -1
  36. package/dist/{template-_QE_rQND.d.ts → template-DMPwxMSq.d.ts} +2 -2
  37. package/dist/{template.js → template-zLUjcwfF.js} +2 -2
  38. package/dist/{theme-css-hFqcPSar.js → theme-css-JtRCm1fb.js} +2 -2
  39. package/dist/whatsapp.d.ts +1 -1
  40. package/dist/whatsapp.js +1 -1
  41. package/generated/contract.json +16 -10
  42. package/generated/reference.md +17 -10
  43. package/package.json +36 -119
  44. package/samva-brand.d.ts +4 -4
  45. package/skills/sml/SKILL.md +2 -2
  46. package/dist/assets-C5duwTya.d.ts +0 -40
  47. package/dist/channel-edit.d.ts +0 -121
  48. package/dist/channel-specs-B6M_HlaV.js +0 -29
  49. package/dist/compatibility-DbISoFIq.js +0 -589
  50. package/dist/css-BVQKICKC.d.ts +0 -109
  51. package/dist/diagnostic-codes.d.ts +0 -403
  52. package/dist/diagnostic-codes.js +0 -399
  53. package/dist/email/assets.d.ts +0 -2
  54. package/dist/email/assets.js +0 -63
  55. package/dist/email/brand-footer.d.ts +0 -34
  56. package/dist/email/brand-footer.js +0 -63
  57. package/dist/email/brand.d.ts +0 -2
  58. package/dist/email/components.js +0 -275
  59. package/dist/email/diagnostics.d.ts +0 -2
  60. package/dist/email/elements.d.ts +0 -2
  61. package/dist/email/elements.js +0 -299
  62. package/dist/email/html.d.ts +0 -2
  63. package/dist/email/html.js +0 -321
  64. package/dist/email/render.d.ts +0 -40
  65. package/dist/email/text.d.ts +0 -7
  66. package/dist/email/text.js +0 -100
  67. package/dist/html-BJepOwZ4.d.ts +0 -56
  68. package/dist/ir-aaqNE987.d.ts +0 -252
  69. package/dist/ir.d.ts +0 -2
  70. package/dist/ir.js +0 -7
  71. package/dist/preview-Ekdg1dXG.d.ts +0 -100
  72. package/dist/preview.d.ts +0 -2
  73. package/dist/preview.js +0 -160
  74. package/dist/render-ir.d.ts +0 -19
  75. package/dist/render-ir.js +0 -826
  76. package/dist/sms-segments.d.ts +0 -13
  77. package/dist/sms-segments.js +0 -46
  78. package/dist/source-edit.d.ts +0 -116
  79. package/dist/source-edit.js +0 -343
  80. package/dist/source-locations.d.ts +0 -2
  81. package/dist/source-locations.js +0 -16
  82. package/dist/static.d.ts +0 -57
  83. package/dist/static.js +0 -69
  84. package/dist/tailwind-CMYpZf1v.js +0 -614
  85. package/dist/template.d.ts +0 -2
  86. package/dist/theme-css.js +0 -2
  87. package/dist/theme-imports-lvBw3AD1.js +0 -109
  88. package/dist/transform-Ct2OMkFN.d.ts +0 -153
@@ -1,275 +0,0 @@
1
- import { EmailNode, Fragment, jsx, normalizeChildren, rawMarkup, reportEmailDiagnostic } from "./jsx-runtime.js";
2
- import { escapeAttribute, escapeText } from "./html.js";
3
- //#region src/email/components.ts
4
- /** Marks the hidden preview block so the renderer can read it back and the text lane can keep it. */
5
- const PREHEADER_ATTRIBUTE = "data-samva-preheader";
6
- const PREHEADER_PADDING_ATTRIBUTE = "data-samva-preheader-padding";
7
- const PREHEADER_TARGET_LENGTH = 200;
8
- const PREHEADER_PADDING = "\xA0‌​‍‎‏";
9
- const presentation = (table, row, rowProps = {}) => jsx("table", {
10
- role: "presentation",
11
- border: 0,
12
- cellpadding: 0,
13
- cellspacing: 0,
14
- ...table,
15
- children: jsx("tbody", { children: jsx("tr", {
16
- ...rowProps,
17
- children: row
18
- }) })
19
- });
20
- /** The hidden inbox preview block. Padding characters stop the client borrowing body copy. */
21
- const preheaderNode = (text) => jsx("div", {
22
- [PREHEADER_ATTRIBUTE]: text,
23
- style: {
24
- display: "none",
25
- overflow: "hidden",
26
- lineHeight: "1px",
27
- opacity: 0,
28
- maxHeight: 0,
29
- maxWidth: 0
30
- },
31
- children: [text, text.length >= PREHEADER_TARGET_LENGTH ? null : jsx("div", {
32
- [PREHEADER_PADDING_ATTRIBUTE]: true,
33
- children: PREHEADER_PADDING.repeat(Math.ceil((PREHEADER_TARGET_LENGTH - text.length) / 7))
34
- })]
35
- });
36
- /** Document shell: the head every target client needs, plus the body content cell. */
37
- const Email = ({ className, lang = "en", dir = "ltr", title, backgroundColor, style, children }) => jsx("html", {
38
- lang,
39
- dir,
40
- xmlns: "http://www.w3.org/1999/xhtml",
41
- "xmlns:o": "urn:schemas-microsoft-com:office:office",
42
- children: [jsx("head", { children: [
43
- jsx("meta", { charset: "utf-8" }),
44
- jsx("meta", {
45
- "http-equiv": "Content-Type",
46
- content: "text/html; charset=UTF-8"
47
- }),
48
- jsx("meta", {
49
- name: "viewport",
50
- content: "width=device-width, initial-scale=1"
51
- }),
52
- jsx("meta", { name: "x-apple-disable-message-reformatting" }),
53
- jsx("meta", {
54
- name: "color-scheme",
55
- content: "light dark"
56
- }),
57
- jsx("meta", {
58
- name: "supported-color-schemes",
59
- content: "light dark"
60
- }),
61
- title === void 0 ? null : jsx("title", { children: title }),
62
- rawMarkup("<!--[if mso]><xml><o:OfficeDocumentSettings><o:PixelsPerInch>96</o:PixelsPerInch></o:OfficeDocumentSettings></xml><![endif]-->")
63
- ] }), jsx("body", {
64
- style: {
65
- margin: 0,
66
- padding: 0,
67
- ...backgroundColor === void 0 ? {} : { backgroundColor }
68
- },
69
- children: [presentation({
70
- align: "center",
71
- width: "100%",
72
- ...backgroundColor === void 0 ? {} : { bgcolor: backgroundColor }
73
- }, jsx("td", {
74
- className,
75
- ...style === void 0 ? {} : { style },
76
- children
77
- }))]
78
- })]
79
- });
80
- /** A full-width band of content, as the single-cell table every client agrees on. */
81
- const Section = ({ className, align = "center", width = "100%", bgcolor, style, tableStyle, children }) => presentation({
82
- align,
83
- width,
84
- ...bgcolor === void 0 ? {} : { bgcolor },
85
- ...tableStyle === void 0 ? {} : { style: tableStyle }
86
- }, jsx("td", {
87
- className,
88
- ...style === void 0 ? {} : { style },
89
- children
90
- }));
91
- /** The equal share of a row that each of `count` cells takes, whole percent rounded down. */
92
- const equalColumnWidth = (count) => `${Math.floor(100 / count)}%`;
93
- /** Give a `Column` that states no width its equal share, keeping the primitive's attribute order. */
94
- const withColumnWidth = (node, width) => {
95
- if (node.type === "Fragment") return EmailNode.Fragment({ children: node.children.map((child) => withColumnWidth(child, width)) });
96
- if (node.type !== "Element" || node.tag !== "td" || node.props.width !== void 0) return node;
97
- const props = {};
98
- for (const [key, value] of Object.entries(node.props)) {
99
- if (key === "style") props.width = width;
100
- props[key] = value;
101
- }
102
- if (props.width === void 0) props.width = width;
103
- return EmailNode.Element({
104
- ...node,
105
- props
106
- });
107
- };
108
- /**
109
- * A row of side-by-side `Column`s. No flex or grid conversion happens here. With `each` it repeats
110
- * its cells over a list, `per` to a row, and splits the row equally between cells that state no
111
- * width.
112
- */
113
- const Columns = ({ className, align = "center", width = "100%", style, each, per, children }) => {
114
- const table = {
115
- className,
116
- align,
117
- width,
118
- ...style === void 0 ? {} : { style }
119
- };
120
- if (each === void 0 || typeof children !== "function") return presentation(table, children, { style: { width: "100%" } });
121
- if (per !== void 0 && (!Number.isInteger(per) || per < 1)) reportEmailDiagnostic({
122
- code: "invalid-columns-per",
123
- severity: "error",
124
- message: "<Columns per> must be a positive integer."
125
- });
126
- const size = per !== void 0 && Number.isInteger(per) && per >= 1 ? per : void 0;
127
- const chunks = [];
128
- if (size === void 0) chunks.push(each);
129
- else for (let at = 0; at < each.length; at += size) chunks.push(each.slice(at, at + size));
130
- const share = equalColumnWidth(size ?? Math.max(each.length, 1));
131
- return jsx(Fragment, { children: chunks.map((chunk) => presentation(table, chunk.flatMap((item, index) => normalizeChildren(children(item, index)).map((cell) => withColumnWidth(cell, share))), { style: { width: "100%" } })) });
132
- };
133
- /** One cell of a `Columns` row. */
134
- const Column = ({ className, align, valign, width, style, children }) => jsx("td", {
135
- className,
136
- ...align === void 0 ? {} : { align },
137
- ...valign === void 0 ? {} : { valign },
138
- ...width === void 0 ? {} : { width },
139
- ...style === void 0 ? {} : { style },
140
- children
141
- });
142
- const DEFAULT_BUTTON_FONT = "Helvetica, Arial, sans-serif";
143
- /** Average advance of a bold sans-serif glyph, as a fraction of the font size. */
144
- const BOLD_GLYPH_ADVANCE = .6;
145
- const invalidButtonNumber = (name) => reportEmailDiagnostic({
146
- code: "invalid-button-number",
147
- severity: "error",
148
- message: `<Button ${name}> must be a finite number.`
149
- });
150
- const buttonNumber = (name, value, fallback) => {
151
- if (typeof value === "number" && Number.isFinite(value)) return value;
152
- invalidButtonNumber(name);
153
- return fallback;
154
- };
155
- const optionalButtonNumber = (name, value) => {
156
- if (value === void 0) return void 0;
157
- if (typeof value === "number" && Number.isFinite(value)) return value;
158
- invalidButtonNumber(name);
159
- };
160
- const optionalPositiveButtonNumber = (name, value) => {
161
- if (value === void 0) return void 0;
162
- if (typeof value === "number" && Number.isFinite(value) && value > 0) return value;
163
- reportEmailDiagnostic({
164
- code: "invalid-button-number",
165
- severity: "error",
166
- message: `<Button ${name}> must be a positive finite number.`
167
- });
168
- };
169
- /** A link styled as a button, with a VML fallback so classic Outlook draws the shape. */
170
- 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 }) => {
171
- const safeWidth = optionalButtonNumber("width", width);
172
- const safeHeight = optionalPositiveButtonNumber("height", height);
173
- const safePaddingX = buttonNumber("paddingX", paddingX, 16);
174
- const safeBorderRadius = buttonNumber("borderRadius", borderRadius, 0);
175
- const safeBorderWidth = buttonNumber("borderWidth", borderWidth, 0);
176
- const safeFontSize = buttonNumber("fontSize", fontSize, 16);
177
- const label = typeof children === "string" ? children : void 0;
178
- const fallback = safeHeight !== void 0 && label !== void 0;
179
- if (!fallback) reportEmailDiagnostic({
180
- code: "button-outlook-fallback",
181
- severity: "warning",
182
- 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.",
183
- clients: ["outlook-windows"]
184
- });
185
- const arcsize = safeHeight === void 0 ? 0 : Math.round(safeBorderRadius / safeHeight * 100);
186
- const fallbackWidth = safeWidth ?? Math.ceil((label?.length ?? 0) * safeFontSize * BOLD_GLYPH_ADVANCE) + 2 * safePaddingX;
187
- return presentation({
188
- width: "100%",
189
- style: { borderCollapse: "collapse" }
190
- }, jsx("td", {
191
- align,
192
- 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", {
193
- className,
194
- href,
195
- target: "_blank",
196
- rel: "noopener noreferrer",
197
- style: {
198
- backgroundColor,
199
- color,
200
- borderRadius: `${safeBorderRadius}px`,
201
- display: "inline-block",
202
- fontFamily,
203
- fontSize: `${safeFontSize}px`,
204
- fontWeight: "bold",
205
- lineHeight: safeHeight === void 0 ? "120%" : `${safeHeight - 2 * safeBorderWidth}px`,
206
- textAlign: "center",
207
- textDecoration: "none",
208
- ...safeWidth === void 0 ? { padding: `0 ${safePaddingX}px` } : {
209
- width: `${safeWidth}px`,
210
- maxWidth: "100%"
211
- },
212
- ...borderColor === void 0 ? {} : { border: `${safeBorderWidth}px solid ${borderColor}` },
213
- ...fallback ? { msoHide: "all" } : {},
214
- ...style
215
- },
216
- children
217
- })]
218
- }));
219
- };
220
- /** Vertical space that survives clients which collapse margins. */
221
- const Spacer = ({ height }) => presentation({ width: "100%" }, jsx("td", {
222
- height,
223
- style: {
224
- height: `${height}px`,
225
- lineHeight: `${height}px`,
226
- fontSize: "1px"
227
- },
228
- children: "​"
229
- }));
230
- /** A horizontal rule drawn as a cell border, which every target client renders. */
231
- const Divider = ({ className, color = "#e5e7eb", thickness = 1, style }) => presentation({ width: "100%" }, jsx("td", {
232
- className,
233
- style: {
234
- borderTop: `${thickness}px solid ${color}`,
235
- fontSize: "1px",
236
- lineHeight: "1px",
237
- ...style
238
- },
239
- children: "​"
240
- }));
241
- /** An image with the width/height attributes Outlook sizes from before CSS applies. */
242
- const Image = ({ className, src, alt, width, height, align, style }) => jsx("img", {
243
- className,
244
- src,
245
- alt,
246
- border: 0,
247
- ...width === void 0 ? {} : { width },
248
- ...height === void 0 ? {} : { height },
249
- ...align === void 0 ? {} : { align },
250
- style: {
251
- display: "block",
252
- outline: "none",
253
- border: "none",
254
- textDecoration: "none",
255
- maxWidth: "100%",
256
- ...style
257
- }
258
- });
259
- /** A text link that opens outside the client and cannot reach back at the opener. */
260
- const Link = ({ className, href, target = "_blank", rel = "noopener noreferrer", style, children }) => jsx("a", {
261
- className,
262
- href,
263
- target,
264
- rel,
265
- style: {
266
- color: "#067df7",
267
- textDecoration: "none",
268
- ...style
269
- },
270
- children
271
- });
272
- //#endregion
273
- export { Button, Column, Columns, Divider, Email, Image, Link, PREHEADER_ATTRIBUTE, Section, Spacer, equalColumnWidth, preheaderNode };
274
-
275
- //# sourceMappingURL=components.js.map
@@ -1,2 +0,0 @@
1
- import { a as TemplateDiagnostic, i as EmailDiagnosticSeverity, n as EmailCompileError, o as formatEmailDiagnostic, r as EmailDiagnostic, s as hasBlockingDiagnostic, t as EmailCompatibilityAssessment } from "../diagnostics-B-Gym34R.js";
2
- export { EmailCompatibilityAssessment, EmailCompileError, EmailDiagnostic, EmailDiagnosticSeverity, TemplateDiagnostic, formatEmailDiagnostic, hasBlockingDiagnostic };
@@ -1,2 +0,0 @@
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-cqldpaJt.js";
2
- export { EMAIL_ELEMENTS, EMAIL_GLOBAL_ATTRIBUTES, EmailAttributeSpec, EmailElementSpec, EmailGlobalProps, EmailIntrinsicElements, EmailLayout, EmailStyle, EmailTag, emailElement, isUrlAttribute };
@@ -1,299 +0,0 @@
1
- //#region src/email/elements.ts
2
- /** Attributes every supported element accepts. `class`/`className`/`style` are handled separately. */
3
- const EMAIL_GLOBAL_ATTRIBUTES = {
4
- id: { type: "string" },
5
- title: { type: "string" },
6
- lang: { type: "string" },
7
- dir: {
8
- type: "string",
9
- values: [
10
- "ltr",
11
- "rtl",
12
- "auto"
13
- ]
14
- },
15
- role: { type: "string" }
16
- };
17
- const alignment = {
18
- type: "string",
19
- values: [
20
- "left",
21
- "center",
22
- "right"
23
- ]
24
- };
25
- const verticalAlignment = {
26
- type: "string",
27
- values: [
28
- "top",
29
- "middle",
30
- "bottom"
31
- ]
32
- };
33
- const flowAttributes = { align: alignment };
34
- const cellAttributes = {
35
- align: alignment,
36
- valign: verticalAlignment,
37
- width: { type: "measure" },
38
- height: { type: "measure" },
39
- bgcolor: { type: "string" },
40
- colspan: { type: "number" },
41
- rowspan: { type: "number" }
42
- };
43
- const block = (attributes) => ({
44
- content: "flow",
45
- layout: "block",
46
- attributes
47
- });
48
- const inline = () => ({
49
- content: "flow",
50
- layout: "inline",
51
- attributes: {}
52
- });
53
- /** The complete supported vocabulary. Anything outside it is a compile error with a source location. */
54
- const EMAIL_ELEMENTS = {
55
- html: {
56
- content: "flow",
57
- layout: "document",
58
- attributes: {
59
- xmlns: { type: "string" },
60
- "xmlns:o": { type: "string" },
61
- "xmlns:v": { type: "string" },
62
- "xmlns:w": { type: "string" }
63
- },
64
- childElements: ["head", "body"]
65
- },
66
- head: {
67
- content: "flow",
68
- layout: "metadata",
69
- attributes: {},
70
- childElements: [
71
- "title",
72
- "meta",
73
- "style"
74
- ]
75
- },
76
- title: {
77
- content: "text",
78
- layout: "metadata",
79
- attributes: {}
80
- },
81
- style: {
82
- content: "raw",
83
- layout: "metadata",
84
- attributes: { type: { type: "string" } }
85
- },
86
- meta: {
87
- content: "void",
88
- layout: "metadata",
89
- attributes: {
90
- name: { type: "string" },
91
- content: { type: "string" },
92
- charset: { type: "string" },
93
- "http-equiv": { type: "string" }
94
- }
95
- },
96
- body: {
97
- content: "flow",
98
- layout: "block",
99
- attributes: { bgcolor: { type: "string" } }
100
- },
101
- div: block(flowAttributes),
102
- section: block(flowAttributes),
103
- article: block(flowAttributes),
104
- header: block(flowAttributes),
105
- footer: block(flowAttributes),
106
- main: block(flowAttributes),
107
- center: block({}),
108
- p: block(flowAttributes),
109
- blockquote: block(flowAttributes),
110
- pre: {
111
- content: "flow",
112
- layout: "preformatted",
113
- attributes: {}
114
- },
115
- h1: block(flowAttributes),
116
- h2: block(flowAttributes),
117
- h3: block(flowAttributes),
118
- h4: block(flowAttributes),
119
- h5: block(flowAttributes),
120
- h6: block(flowAttributes),
121
- span: inline(),
122
- strong: inline(),
123
- b: inline(),
124
- em: inline(),
125
- i: inline(),
126
- u: inline(),
127
- s: inline(),
128
- small: inline(),
129
- code: inline(),
130
- a: {
131
- content: "flow",
132
- layout: "link",
133
- attributes: {
134
- href: {
135
- type: "url",
136
- required: true
137
- },
138
- target: { type: "string" },
139
- rel: { type: "string" },
140
- name: { type: "string" }
141
- }
142
- },
143
- img: {
144
- content: "void",
145
- layout: "image",
146
- attributes: {
147
- src: {
148
- type: "url",
149
- required: true
150
- },
151
- alt: {
152
- type: "string",
153
- required: true
154
- },
155
- width: { type: "measure" },
156
- height: { type: "measure" },
157
- border: { type: "measure" },
158
- align: alignment
159
- }
160
- },
161
- table: {
162
- content: "flow",
163
- layout: "table",
164
- attributes: {
165
- width: { type: "measure" },
166
- height: { type: "measure" },
167
- border: { type: "measure" },
168
- cellpadding: { type: "measure" },
169
- cellspacing: { type: "measure" },
170
- align: alignment,
171
- bgcolor: { type: "string" }
172
- },
173
- childElements: [
174
- "caption",
175
- "colgroup",
176
- "thead",
177
- "tbody",
178
- "tfoot",
179
- "tr"
180
- ]
181
- },
182
- caption: {
183
- content: "flow",
184
- layout: "block",
185
- attributes: flowAttributes
186
- },
187
- colgroup: {
188
- content: "flow",
189
- layout: "table-section",
190
- attributes: {
191
- span: { type: "number" },
192
- width: { type: "measure" }
193
- },
194
- childElements: ["col"]
195
- },
196
- col: {
197
- content: "void",
198
- layout: "table-section",
199
- attributes: {
200
- span: { type: "number" },
201
- width: { type: "measure" }
202
- }
203
- },
204
- thead: {
205
- content: "flow",
206
- layout: "table-section",
207
- attributes: {
208
- align: alignment,
209
- valign: verticalAlignment,
210
- bgcolor: { type: "string" }
211
- },
212
- childElements: ["tr"]
213
- },
214
- tbody: {
215
- content: "flow",
216
- layout: "table-section",
217
- attributes: {
218
- align: alignment,
219
- valign: verticalAlignment,
220
- bgcolor: { type: "string" }
221
- },
222
- childElements: ["tr"]
223
- },
224
- tfoot: {
225
- content: "flow",
226
- layout: "table-section",
227
- attributes: {
228
- align: alignment,
229
- valign: verticalAlignment,
230
- bgcolor: { type: "string" }
231
- },
232
- childElements: ["tr"]
233
- },
234
- tr: {
235
- content: "flow",
236
- layout: "row",
237
- attributes: {
238
- align: alignment,
239
- valign: verticalAlignment,
240
- bgcolor: { type: "string" },
241
- height: { type: "measure" }
242
- },
243
- childElements: ["td", "th"]
244
- },
245
- td: {
246
- content: "flow",
247
- layout: "cell",
248
- attributes: cellAttributes
249
- },
250
- th: {
251
- content: "flow",
252
- layout: "cell",
253
- attributes: cellAttributes
254
- },
255
- ul: {
256
- content: "flow",
257
- layout: "list",
258
- attributes: {},
259
- childElements: ["li"]
260
- },
261
- ol: {
262
- content: "flow",
263
- layout: "list",
264
- attributes: {
265
- start: { type: "number" },
266
- type: { type: "string" }
267
- },
268
- childElements: ["li"]
269
- },
270
- li: {
271
- content: "flow",
272
- layout: "list-item",
273
- attributes: {}
274
- },
275
- br: {
276
- content: "void",
277
- layout: "break",
278
- attributes: {}
279
- },
280
- hr: {
281
- content: "void",
282
- layout: "rule",
283
- attributes: {
284
- width: { type: "measure" },
285
- size: { type: "number" },
286
- align: alignment
287
- }
288
- }
289
- };
290
- /** Attributes that must carry a URL; these are checked against the safe-scheme rule. */
291
- const isUrlAttribute = (tag, attribute) => {
292
- return EMAIL_ELEMENTS[tag]?.attributes[attribute]?.type === "url";
293
- };
294
- /** Look up one supported element, or `undefined` when the tag is outside the vocabulary. */
295
- const emailElement = (tag) => Object.hasOwn(EMAIL_ELEMENTS, tag) ? EMAIL_ELEMENTS[tag] : void 0;
296
- //#endregion
297
- export { EMAIL_ELEMENTS, EMAIL_GLOBAL_ATTRIBUTES, emailElement, isUrlAttribute };
298
-
299
- //# sourceMappingURL=elements.js.map
@@ -1,2 +0,0 @@
1
- import { a as escapeAttribute, c as serializeEmailHtml, i as declarationValue, l as serializeStyle, n as SerializeEmailOptions, o as escapeText, r as checkAttribute, s as kebab, t as EmailHtmlOutput } from "../html-BJepOwZ4.js";
2
- export { EmailHtmlOutput, SerializeEmailOptions, checkAttribute, declarationValue, escapeAttribute, escapeText, kebab, serializeEmailHtml, serializeStyle };