@seliseblocks/mailcraft 0.2.18 → 0.2.19

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.
@@ -28,11 +28,11 @@
28
28
  <tr>
29
29
  <td style="padding:16px 18px; border-bottom:1px solid #e1e8ef;">
30
30
  <p style="margin:0 0 4px; font-family:Arial, Helvetica, sans-serif; font-size:11px; font-weight:bold; letter-spacing:0.12em; text-transform:uppercase; color:#8194a7;">Carrier</p>
31
- <p style="margin:0; font-family:Arial, Helvetica, sans-serif; font-size:14px; color:#10243c;">DHL Express</p>
31
+ <p style="margin:0; font-family:Arial, Helvetica, sans-serif; font-size:14px; color:#10243c;">Express Courier</p>
32
32
  </td>
33
33
  <td style="padding:16px 18px; border-bottom:1px solid #e1e8ef;">
34
34
  <p style="margin:0 0 4px; font-family:Arial, Helvetica, sans-serif; font-size:11px; font-weight:bold; letter-spacing:0.12em; text-transform:uppercase; color:#8194a7;">Tracking number</p>
35
- <p style="margin:0; font-family:'Courier New', Courier, monospace; font-size:14px; color:#10243c;">JD014669321DE</p>
35
+ <p style="margin:0; font-family:'Courier New', Courier, monospace; font-size:14px; color:#10243c;">EC4821397205XX</p>
36
36
  </td>
37
37
  </tr>
38
38
  <tr>
@@ -165,7 +165,7 @@
165
165
  <div class="field">
166
166
  <label for="font-select">Font</label>
167
167
  <select id="font-select">
168
- <option value="">Default (Manrope)</option>
168
+ <option value="">Default (editor font)</option>
169
169
  <option value="inherit">Match host app</option>
170
170
  <option value="Georgia, 'Times New Roman', serif">Serif</option>
171
171
  <option value="Verdana, Geneva, sans-serif">Verdana</option>
@@ -1254,11 +1254,11 @@
1254
1254
  <tr>
1255
1255
  <td style="padding:16px 18px; border-bottom:1px solid #e1e8ef;">
1256
1256
  <p style="margin:0 0 4px; font-family:Arial, Helvetica, sans-serif; font-size:11px; font-weight:bold; letter-spacing:0.12em; text-transform:uppercase; color:#8194a7;">Carrier</p>
1257
- <p style="margin:0; font-family:Arial, Helvetica, sans-serif; font-size:14px; color:#10243c;">DHL Express</p>
1257
+ <p style="margin:0; font-family:Arial, Helvetica, sans-serif; font-size:14px; color:#10243c;">Express Courier</p>
1258
1258
  </td>
1259
1259
  <td style="padding:16px 18px; border-bottom:1px solid #e1e8ef;">
1260
1260
  <p style="margin:0 0 4px; font-family:Arial, Helvetica, sans-serif; font-size:11px; font-weight:bold; letter-spacing:0.12em; text-transform:uppercase; color:#8194a7;">Tracking number</p>
1261
- <p style="margin:0; font-family:'Courier New', Courier, monospace; font-size:14px; color:#10243c;">JD014669321DE</p>
1261
+ <p style="margin:0; font-family:'Courier New', Courier, monospace; font-size:14px; color:#10243c;">EC4821397205XX</p>
1262
1262
  </td>
1263
1263
  </tr>
1264
1264
  <tr>
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@seliseblocks/mailcraft",
3
- "version": "0.2.18",
3
+ "version": "0.2.19",
4
4
  "description": "Framework-agnostic drag-and-drop email template editor, packaged as a zero-dependency Web Component.",
5
5
  "license": "MIT",
6
6
  "author": "SELISE Digital Platforms",
@@ -167,7 +167,7 @@ export const GROUPS = {
167
167
  row.cols[0].blocks = [
168
168
  blk('divider', { py: 0 }),
169
169
  blk('social', { align: 'center', size: 18, shape: 'bare' }),
170
- blk('text', { html: '<strong>MailCraft, Inc.</strong><br />220 Foundry Street, Suite 4, Portland OR 97209<br />You are receiving this because you signed up at mailcraft.co.', size: 11.5, align: 'center', py: 6 }),
170
+ blk('text', { html: '<strong>Selise Group</strong><br />You are receiving this because you signed up at selisegroup.com.', size: 11.5, align: 'center', py: 6 }),
171
171
  blk('text', { html: '<a href="{{ unsubscribe_url }}">Unsubscribe</a> · <a href="#">Update preferences</a>', size: 11.5, align: 'center', py: 0 }),
172
172
  ];
173
173
  return [row];
@@ -1,83 +1,83 @@
1
- import { EN as ENBase } from './en.js';
2
-
3
- /**
4
- * Builds a translator. `overrides` is whatever a host passes as `.messages`
5
- * on the element -- a host's own table, an imported locale, or both merged
6
- * via `defineMessages` below.
7
- *
8
- * Three deliberate properties:
9
- * 1. English always resolves. A locale is an overlay, never a replacement,
10
- * so a partial or missing translation shows English rather than a gap.
11
- * 2. Params interpolate `{name}`.
12
- * 3. A truly missing key (not in `overrides`, not in `EN`) renders as the
13
- * key itself, not an empty string -- a visible `toast.deleted` in the UI
14
- * is obviously wrong and names the exact key to add, where blank text
15
- * just looks like a broken build.
16
- */
17
- export function createTranslator(overrides) {
18
- const table = overrides || {};
19
- return function t(key, params) {
20
- const template = table[key] ?? ENBase[key] ?? key;
21
- if (!params) return template;
22
- return template.replace(/\{(\w+)\}/g, (whole, name) => (name in params ? String(params[name]) : whole));
23
- };
24
- }
25
-
26
- /** Merges a locale over a base, for a host assembling its own table -- the documented way to combine a shipped locale with a few product-specific overrides. */
27
- export function defineMessages(base, overrides) {
28
- return Object.assign({}, base, overrides);
29
- }
30
-
31
- /** Keys in `base` that `locale` does not translate. What a translator has left to do. */
32
- export function missingKeys(locale, base) {
33
- const source = base || ENBase;
34
- return Object.keys(source).filter((key) => locale[key] === undefined).sort();
35
- }
36
-
37
- /**
38
- * Every locale that ships, for a host building a language switcher.
39
- * Metadata only -- no message tables -- so listing the locales never pulls
40
- * every translation file into a consumer's bundle; a host deep-imports the
41
- * one it wants, e.g. `mailcraft-editor/src/core/i18n/bn.js`.
42
- */
43
- export const LOCALES = [
44
- { tag: 'en', name: 'English' },
45
- { tag: 'ar', name: 'Arabic', rtl: true },
46
- { tag: 'bn', name: 'Bangla' },
47
- { tag: 'dz', name: 'Dzongkha' },
48
- { tag: 'bg', name: 'Bulgarian' },
49
- { tag: 'ca', name: 'Catalan' },
50
- { tag: 'cs', name: 'Czech' },
51
- { tag: 'da', name: 'Danish' },
52
- { tag: 'de', name: 'German' },
53
- { tag: 'de-CH', name: 'Swiss German' },
54
- { tag: 'el', name: 'Greek' },
55
- { tag: 'es', name: 'Spanish' },
56
- { tag: 'et', name: 'Estonian' },
57
- { tag: 'fi', name: 'Finnish' },
58
- { tag: 'fr', name: 'French' },
59
- { tag: 'hr', name: 'Croatian' },
60
- { tag: 'hu', name: 'Hungarian' },
61
- { tag: 'it', name: 'Italian' },
62
- { tag: 'lt', name: 'Lithuanian' },
63
- { tag: 'lv', name: 'Latvian' },
64
- { tag: 'nb', name: 'Norwegian Bokmål' },
65
- { tag: 'nl', name: 'Dutch' },
66
- { tag: 'pl', name: 'Polish' },
67
- { tag: 'pt', name: 'Portuguese' },
68
- { tag: 'ro', name: 'Romanian' },
69
- { tag: 'ru', name: 'Russian' },
70
- { tag: 'sk', name: 'Slovak' },
71
- { tag: 'sl', name: 'Slovenian' },
72
- { tag: 'sv', name: 'Swedish' },
73
- { tag: 'tr', name: 'Turkish' },
74
- { tag: 'uk', name: 'Ukrainian' },
75
- ];
76
-
77
- /** `true` when the tag is written right to left. Metadata only -- `dir` is still what actually flips the layout. */
78
- export function isRtl(tag) {
79
- const entry = LOCALES.find((l) => l.tag === tag);
80
- return entry ? entry.rtl === true : false;
81
- }
82
-
83
- export { EN, MESSAGE_KEYS } from './en.js';
1
+ import { EN as ENBase } from './en.js';
2
+
3
+ /**
4
+ * Builds a translator. `overrides` is whatever a host passes as `.messages`
5
+ * on the element -- a host's own table, an imported locale, or both merged
6
+ * via `defineMessages` below.
7
+ *
8
+ * Three deliberate properties:
9
+ * 1. English always resolves. A locale is an overlay, never a replacement,
10
+ * so a partial or missing translation shows English rather than a gap.
11
+ * 2. Params interpolate `{name}`.
12
+ * 3. A truly missing key (not in `overrides`, not in `EN`) renders as the
13
+ * key itself, not an empty string -- a visible `toast.deleted` in the UI
14
+ * is obviously wrong and names the exact key to add, where blank text
15
+ * just looks like a broken build.
16
+ */
17
+ export function createTranslator(overrides) {
18
+ const table = overrides || {};
19
+ return function t(key, params) {
20
+ const template = table[key] ?? ENBase[key] ?? key;
21
+ if (!params) return template;
22
+ return template.replace(/\{(\w+)\}/g, (whole, name) => (name in params ? String(params[name]) : whole));
23
+ };
24
+ }
25
+
26
+ /** Merges a locale over a base, for a host assembling its own table -- the documented way to combine a shipped locale with a few product-specific overrides. */
27
+ export function defineMessages(base, overrides) {
28
+ return Object.assign({}, base, overrides);
29
+ }
30
+
31
+ /** Keys in `base` that `locale` does not translate. What a translator has left to do. */
32
+ export function missingKeys(locale, base) {
33
+ const source = base || ENBase;
34
+ return Object.keys(source).filter((key) => locale[key] === undefined).sort();
35
+ }
36
+
37
+ /**
38
+ * Every locale that ships, for a host building a language switcher.
39
+ * Metadata only -- no message tables -- so listing the locales never pulls
40
+ * every translation file into a consumer's bundle; a host deep-imports the
41
+ * one it wants, e.g. `mailcraft-editor/src/core/i18n/bn.js`.
42
+ */
43
+ export const LOCALES = [
44
+ { tag: 'en', name: 'English' },
45
+ { tag: 'ar', name: 'Arabic', rtl: true },
46
+ { tag: 'bn', name: 'Bangla' },
47
+ { tag: 'dz', name: 'Dzongkha' },
48
+ { tag: 'bg', name: 'Bulgarian' },
49
+ { tag: 'ca', name: 'Catalan' },
50
+ { tag: 'cs', name: 'Czech' },
51
+ { tag: 'da', name: 'Danish' },
52
+ { tag: 'de', name: 'German' },
53
+ { tag: 'de-CH', name: 'Swiss German' },
54
+ { tag: 'el', name: 'Greek' },
55
+ { tag: 'es', name: 'Spanish' },
56
+ { tag: 'et', name: 'Estonian' },
57
+ { tag: 'fi', name: 'Finnish' },
58
+ { tag: 'fr', name: 'French' },
59
+ { tag: 'hr', name: 'Croatian' },
60
+ { tag: 'hu', name: 'Hungarian' },
61
+ { tag: 'it', name: 'Italian' },
62
+ { tag: 'lt', name: 'Lithuanian' },
63
+ { tag: 'lv', name: 'Latvian' },
64
+ { tag: 'nb', name: 'Norwegian Bokmål' },
65
+ { tag: 'nl', name: 'Dutch' },
66
+ { tag: 'pl', name: 'Polish' },
67
+ { tag: 'pt', name: 'Portuguese' },
68
+ { tag: 'ro', name: 'Romanian' },
69
+ { tag: 'ru', name: 'Russian' },
70
+ { tag: 'sk', name: 'Slovak' },
71
+ { tag: 'sl', name: 'Slovenian' },
72
+ { tag: 'sv', name: 'Swedish' },
73
+ { tag: 'tr', name: 'Turkish' },
74
+ { tag: 'uk', name: 'Ukrainian' },
75
+ ];
76
+
77
+ /** `true` when the tag is written right to left. Metadata only -- `dir` is still what actually flips the layout. */
78
+ export function isRtl(tag) {
79
+ const entry = LOCALES.find((l) => l.tag === tag);
80
+ return entry ? entry.rtl === true : false;
81
+ }
82
+
83
+ export { EN, MESSAGE_KEYS } from './en.js';
package/src/core/icons.js CHANGED
@@ -1,4 +1,10 @@
1
- /** Thin-stroke icon set (Lucide grammar, stroke 1.5), ported path-for-path from the original prototype. */
1
+ /**
2
+ * Thin-stroke icon set, stroke 1.5 on a 24 grid. The shapes are this
3
+ * project's own, carried over path-for-path from its earlier prototype;
4
+ * the thin-stroke grammar follows the convention Lucide popularised, but
5
+ * no path data is taken from Lucide or any other set. Keep it that way --
6
+ * new glyphs get drawn here, not pasted in.
7
+ */
2
8
  const ICONS = {
3
9
  text: ['M4 6h16', 'M4 12h12', 'M4 18h9'],
4
10
  image: [['rect', 3, 4, 18, 16], ['circle', 8.5, 9.5, 1.5], 'M3 17l5-5 4 4 3-3 6 6'],
@@ -53,6 +59,7 @@ const ICONS = {
53
59
  formatClear: ['M5 18 11 5h2l4 9', 'M7.5 13h7', 'M16 17l5 5', 'M21 17l-5 5'],
54
60
  chevronDown: ['M7 9l5 5 5-5'],
55
61
  x: ['M4 4l16 16', 'M20 4L4 20'],
62
+ xSocial: [['rect', 3, 3, 18, 18], 'M8.5 8.5l7 7', 'M15.5 8.5l-7 7'],
56
63
  instagram: [['rect', 3, 3, 18, 18], ['circle', 12, 12, 4], ['circle', 17, 7, 0.9]],
57
64
  linkedin: [['rect', 3, 3, 18, 18], 'M8 10v7', ['circle', 8, 7.2, 0.9], 'M12 17v-4a2.5 2.5 0 0 1 5 0v4'],
58
65
  facebook: [['rect', 3, 3, 18, 18], 'M15 8h-1.5A2.5 2.5 0 0 0 11 10.5V21', 'M8.5 13h5'],
@@ -103,31 +110,6 @@ const ICONS = {
103
110
  dribbble: [['circle', 12, 12, 9], 'M4 10c4 1.2 12 1.2 16.5 0', 'M8.5 4.5c2.5 3 5 8.5 5 14.5', 'M9 20c2-4 7-6 11.5-5'],
104
111
  };
105
112
 
106
- /**
107
- * Official brand glyphs (Simple Icons, CC0), rendered as filled paths --
108
- * the hand-drawn stroke approximations they replace read as amateur at
109
- * social-strip sizes. Kept separate from ICONS because these render
110
- * fill-based (icon() is a stroke builder) and because the key 'x' must not
111
- * shadow the ✕ close icon; resolve through brandIcon(), never icon().
112
- */
113
- const BRAND_GLYPHS = {
114
- behance: 'M16.969 16.927a2.561 2.561 0 0 0 1.901.677 2.501 2.501 0 0 0 1.531-.475c.362-.235.636-.584.779-.99h2.585a5.091 5.091 0 0 1-1.9 2.896 5.292 5.292 0 0 1-3.091.88 5.839 5.839 0 0 1-2.284-.433 4.871 4.871 0 0 1-1.723-1.211 5.657 5.657 0 0 1-1.08-1.874 7.057 7.057 0 0 1-.383-2.393c-.005-.8.129-1.595.396-2.349a5.313 5.313 0 0 1 5.088-3.604 4.87 4.87 0 0 1 2.376.563c.661.362 1.231.87 1.668 1.485a6.2 6.2 0 0 1 .943 2.133c.194.821.263 1.666.205 2.508h-7.699c-.063.79.184 1.574.688 2.187ZM6.947 4.084a8.065 8.065 0 0 1 1.928.198 4.29 4.29 0 0 1 1.49.638c.418.303.748.711.958 1.182.241.579.357 1.203.341 1.83a3.506 3.506 0 0 1-.506 1.961 3.726 3.726 0 0 1-1.503 1.287 3.588 3.588 0 0 1 2.027 1.437c.464.747.697 1.615.67 2.494a4.593 4.593 0 0 1-.423 2.032 3.945 3.945 0 0 1-1.163 1.413 5.114 5.114 0 0 1-1.683.807 7.135 7.135 0 0 1-1.928.259H0V4.084h6.947Zm-.235 12.9c.308.004.616-.029.916-.099a2.18 2.18 0 0 0 .766-.332c.228-.158.411-.371.534-.619.142-.317.208-.663.191-1.009a2.08 2.08 0 0 0-.642-1.715 2.618 2.618 0 0 0-1.696-.505h-3.54v4.279h3.471Zm13.635-5.967a2.13 2.13 0 0 0-1.654-.619 2.336 2.336 0 0 0-1.163.259 2.474 2.474 0 0 0-.738.62 2.359 2.359 0 0 0-.396.792c-.074.239-.12.485-.137.734h4.769a3.239 3.239 0 0 0-.679-1.785l-.002-.001Zm-13.813-.648a2.254 2.254 0 0 0 1.423-.433c.399-.355.607-.88.56-1.413a1.916 1.916 0 0 0-.178-.891 1.298 1.298 0 0 0-.495-.533 1.851 1.851 0 0 0-.711-.274 3.966 3.966 0 0 0-.835-.073H3.241v3.631h3.293v-.014ZM21.62 5.122h-5.976v1.527h5.976V5.122Z',
115
- discord: 'M20.317 4.3698a19.7913 19.7913 0 00-4.8851-1.5152.0741.0741 0 00-.0785.0371c-.211.3753-.4447.8648-.6083 1.2495-1.8447-.2762-3.68-.2762-5.4868 0-.1636-.3933-.4058-.8742-.6177-1.2495a.077.077 0 00-.0785-.037 19.7363 19.7363 0 00-4.8852 1.515.0699.0699 0 00-.0321.0277C.5334 9.0458-.319 13.5799.0992 18.0578a.0824.0824 0 00.0312.0561c2.0528 1.5076 4.0413 2.4228 5.9929 3.0294a.0777.0777 0 00.0842-.0276c.4616-.6304.8731-1.2952 1.226-1.9942a.076.076 0 00-.0416-.1057c-.6528-.2476-1.2743-.5495-1.8722-.8923a.077.077 0 01-.0076-.1277c.1258-.0943.2517-.1923.3718-.2914a.0743.0743 0 01.0776-.0105c3.9278 1.7933 8.18 1.7933 12.0614 0a.0739.0739 0 01.0785.0095c.1202.099.246.1981.3728.2924a.077.077 0 01-.0066.1276 12.2986 12.2986 0 01-1.873.8914.0766.0766 0 00-.0407.1067c.3604.698.7719 1.3628 1.225 1.9932a.076.076 0 00.0842.0286c1.961-.6067 3.9495-1.5219 6.0023-3.0294a.077.077 0 00.0313-.0552c.5004-5.177-.8382-9.6739-3.5485-13.6604a.061.061 0 00-.0312-.0286zM8.02 15.3312c-1.1825 0-2.1569-1.0857-2.1569-2.419 0-1.3332.9555-2.4189 2.157-2.4189 1.2108 0 2.1757 1.0952 2.1568 2.419 0 1.3332-.9555 2.4189-2.1569 2.4189zm7.9748 0c-1.1825 0-2.1569-1.0857-2.1569-2.419 0-1.3332.9554-2.4189 2.1569-2.4189 1.2108 0 2.1757 1.0952 2.1568 2.419 0 1.3332-.946 2.4189-2.1568 2.4189Z',
116
- dribbble: 'M12 24C5.385 24 0 18.615 0 12S5.385 0 12 0s12 5.385 12 12-5.385 12-12 12zm10.12-10.358c-.35-.11-3.17-.953-6.384-.438 1.34 3.684 1.887 6.684 1.992 7.308 2.3-1.555 3.936-4.02 4.395-6.87zm-6.115 7.808c-.153-.9-.75-4.032-2.19-7.77l-.066.02c-5.79 2.015-7.86 6.025-8.04 6.4 1.73 1.358 3.92 2.166 6.29 2.166 1.42 0 2.77-.29 4-.814zm-11.62-2.58c.232-.4 3.045-5.055 8.332-6.765.135-.045.27-.084.405-.12-.26-.585-.54-1.167-.832-1.74C7.17 11.775 2.206 11.71 1.756 11.7l-.004.312c0 2.633.998 5.037 2.634 6.855zm-2.42-8.955c.46.008 4.683.026 9.477-1.248-1.698-3.018-3.53-5.558-3.8-5.928-2.868 1.35-5.01 3.99-5.676 7.17zM9.6 2.052c.282.38 2.145 2.914 3.822 6 3.645-1.365 5.19-3.44 5.373-3.702-1.81-1.61-4.19-2.586-6.795-2.586-.825 0-1.63.1-2.4.285zm10.335 3.483c-.218.29-1.935 2.493-5.724 4.04.24.49.47.985.68 1.486.08.18.15.36.22.53 3.41-.43 6.8.26 7.14.33-.02-2.42-.88-4.64-2.31-6.38z',
117
- facebook: 'M9.101 23.691v-7.98H6.627v-3.667h2.474v-1.58c0-4.085 1.848-5.978 5.858-5.978.401 0 .955.042 1.468.103a8.68 8.68 0 0 1 1.141.195v3.325a8.623 8.623 0 0 0-.653-.036 26.805 26.805 0 0 0-.733-.009c-.707 0-1.259.096-1.675.309a1.686 1.686 0 0 0-.679.622c-.258.42-.374.995-.374 1.752v1.297h3.919l-.386 2.103-.287 1.564h-3.246v8.245C19.396 23.238 24 18.179 24 12.044c0-6.627-5.373-12-12-12s-12 5.373-12 12c0 5.628 3.874 10.35 9.101 11.647Z',
118
- instagram: 'M7.0301.084c-1.2768.0602-2.1487.264-2.911.5634-.7888.3075-1.4575.72-2.1228 1.3877-.6652.6677-1.075 1.3368-1.3802 2.127-.2954.7638-.4956 1.6365-.552 2.914-.0564 1.2775-.0689 1.6882-.0626 4.947.0062 3.2586.0206 3.6671.0825 4.9473.061 1.2765.264 2.1482.5635 2.9107.308.7889.72 1.4573 1.388 2.1228.6679.6655 1.3365 1.0743 2.1285 1.38.7632.295 1.6361.4961 2.9134.552 1.2773.056 1.6884.069 4.9462.0627 3.2578-.0062 3.668-.0207 4.9478-.0814 1.28-.0607 2.147-.2652 2.9098-.5633.7889-.3086 1.4578-.72 2.1228-1.3881.665-.6682 1.0745-1.3378 1.3795-2.1284.2957-.7632.4966-1.636.552-2.9124.056-1.2809.0692-1.6898.063-4.948-.0063-3.2583-.021-3.6668-.0817-4.9465-.0607-1.2797-.264-2.1487-.5633-2.9117-.3084-.7889-.72-1.4568-1.3876-2.1228C21.2982 1.33 20.628.9208 19.8378.6165 19.074.321 18.2017.1197 16.9244.0645 15.6471.0093 15.236-.005 11.977.0014 8.718.0076 8.31.0215 7.0301.0839m.1402 21.6932c-1.17-.0509-1.8053-.2453-2.2287-.408-.5606-.216-.96-.4771-1.3819-.895-.422-.4178-.6811-.8186-.9-1.378-.1644-.4234-.3624-1.058-.4171-2.228-.0595-1.2645-.072-1.6442-.079-4.848-.007-3.2037.0053-3.583.0607-4.848.05-1.169.2456-1.805.408-2.2282.216-.5613.4762-.96.895-1.3816.4188-.4217.8184-.6814 1.3783-.9003.423-.1651 1.0575-.3614 2.227-.4171 1.2655-.06 1.6447-.072 4.848-.079 3.2033-.007 3.5835.005 4.8495.0608 1.169.0508 1.8053.2445 2.228.408.5608.216.96.4754 1.3816.895.4217.4194.6816.8176.9005 1.3787.1653.4217.3617 1.056.4169 2.2263.0602 1.2655.0739 1.645.0796 4.848.0058 3.203-.0055 3.5834-.061 4.848-.051 1.17-.245 1.8055-.408 2.2294-.216.5604-.4763.96-.8954 1.3814-.419.4215-.8181.6811-1.3783.9-.4224.1649-1.0577.3617-2.2262.4174-1.2656.0595-1.6448.072-4.8493.079-3.2045.007-3.5825-.006-4.848-.0608M16.953 5.5864A1.44 1.44 0 1 0 18.39 4.144a1.44 1.44 0 0 0-1.437 1.4424M5.8385 12.012c.0067 3.4032 2.7706 6.1557 6.173 6.1493 3.4026-.0065 6.157-2.7701 6.1506-6.1733-.0065-3.4032-2.771-6.1565-6.174-6.1498-3.403.0067-6.156 2.771-6.1496 6.1738M8 12.0077a4 4 0 1 1 4.008 3.9921A3.9996 3.9996 0 0 1 8 12.0077',
119
- linkedin: 'M20.447 20.452h-3.554v-5.569c0-1.328-.027-3.037-1.852-3.037-1.853 0-2.136 1.445-2.136 2.939v5.667H9.351V9h3.414v1.561h.046c.477-.9 1.637-1.85 3.37-1.85 3.601 0 4.267 2.37 4.267 5.455v6.286zM5.337 7.433c-1.144 0-2.063-.926-2.063-2.065 0-1.138.92-2.063 2.063-2.063 1.14 0 2.064.925 2.064 2.063 0 1.139-.925 2.065-2.064 2.065zm1.782 13.019H3.555V9h3.564v11.452zM22.225 0H1.771C.792 0 0 .774 0 1.729v20.542C0 23.227.792 24 1.771 24h20.451C23.2 24 24 23.227 24 22.271V1.729C24 .774 23.2 0 22.222 0h.003z',
120
- pinterest: 'M12.017 0C5.396 0 .029 5.367.029 11.987c0 5.079 3.158 9.417 7.618 11.162-.105-.949-.199-2.403.041-3.439.219-.937 1.406-5.957 1.406-5.957s-.359-.72-.359-1.781c0-1.663.967-2.911 2.168-2.911 1.024 0 1.518.769 1.518 1.688 0 1.029-.653 2.567-.992 3.992-.285 1.193.6 2.165 1.775 2.165 2.128 0 3.768-2.245 3.768-5.487 0-2.861-2.063-4.869-5.008-4.869-3.41 0-5.409 2.562-5.409 5.199 0 1.033.394 2.143.889 2.741.099.12.112.225.085.345-.09.375-.293 1.199-.334 1.363-.053.225-.172.271-.401.165-1.495-.69-2.433-2.878-2.433-4.646 0-3.776 2.748-7.252 7.92-7.252 4.158 0 7.392 2.967 7.392 6.923 0 4.135-2.607 7.462-6.233 7.462-1.214 0-2.354-.629-2.758-1.379l-.749 2.848c-.269 1.045-1.004 2.352-1.498 3.146 1.123.345 2.306.535 3.55.535 6.607 0 11.985-5.365 11.985-11.987C23.97 5.39 18.592.026 11.985.026L12.017 0z',
121
- reddit: 'M12 0C5.373 0 0 5.373 0 12c0 3.314 1.343 6.314 3.515 8.485l-2.286 2.286C.775 23.225 1.097 24 1.738 24H12c6.627 0 12-5.373 12-12S18.627 0 12 0Zm4.388 3.199c1.104 0 1.999.895 1.999 1.999 0 1.105-.895 2-1.999 2-.946 0-1.739-.657-1.947-1.539v.002c-1.147.162-2.032 1.15-2.032 2.341v.007c1.776.067 3.4.567 4.686 1.363.473-.363 1.064-.58 1.707-.58 1.547 0 2.802 1.254 2.802 2.802 0 1.117-.655 2.081-1.601 2.531-.088 3.256-3.637 5.876-7.997 5.876-4.361 0-7.905-2.617-7.998-5.87-.954-.447-1.614-1.415-1.614-2.538 0-1.548 1.255-2.802 2.803-2.802.645 0 1.239.218 1.712.585 1.275-.79 2.881-1.291 4.64-1.365v-.01c0-1.663 1.263-3.034 2.88-3.207.188-.911.993-1.595 1.959-1.595Zm-8.085 8.376c-.784 0-1.459.78-1.506 1.797-.047 1.016.64 1.429 1.426 1.429.786 0 1.371-.369 1.418-1.385.047-1.017-.553-1.841-1.338-1.841Zm7.406 0c-.786 0-1.385.824-1.338 1.841.047 1.017.634 1.385 1.418 1.385.785 0 1.473-.413 1.426-1.429-.046-1.017-.721-1.797-1.506-1.797Zm-3.703 4.013c-.974 0-1.907.048-2.77.135-.147.015-.241.168-.183.305.483 1.154 1.622 1.964 2.953 1.964 1.33 0 2.47-.81 2.953-1.964.057-.137-.037-.29-.184-.305-.863-.087-1.795-.135-2.769-.135Z',
122
- snapchat: 'M12.206.793c.99 0 4.347.276 5.93 3.821.529 1.193.403 3.219.299 4.847l-.003.06c-.012.18-.022.345-.03.51.075.045.203.09.401.09.3-.016.659-.12 1.033-.301.165-.088.344-.104.464-.104.182 0 .359.029.509.09.45.149.734.479.734.838.015.449-.39.839-1.213 1.168-.089.029-.209.075-.344.119-.45.135-1.139.36-1.333.81-.09.224-.061.524.12.868l.015.015c.06.136 1.526 3.475 4.791 4.014.255.044.435.27.42.509 0 .075-.015.149-.045.225-.24.569-1.273.988-3.146 1.271-.059.091-.12.375-.164.57-.029.179-.074.36-.134.553-.076.271-.27.405-.555.405h-.03c-.135 0-.313-.031-.538-.074-.36-.075-.765-.135-1.273-.135-.3 0-.599.015-.913.074-.6.104-1.123.464-1.723.884-.853.599-1.826 1.288-3.294 1.288-.06 0-.119-.015-.18-.015h-.149c-1.468 0-2.427-.675-3.279-1.288-.599-.42-1.107-.779-1.707-.884-.314-.045-.629-.074-.928-.074-.54 0-.958.089-1.272.149-.211.043-.391.074-.54.074-.374 0-.523-.224-.583-.42-.061-.192-.09-.389-.135-.567-.046-.181-.105-.494-.166-.57-1.918-.222-2.95-.642-3.189-1.226-.031-.063-.052-.15-.055-.225-.015-.243.165-.465.42-.509 3.264-.54 4.73-3.879 4.791-4.02l.016-.029c.18-.345.224-.645.119-.869-.195-.434-.884-.658-1.332-.809-.121-.029-.24-.074-.346-.119-1.107-.435-1.257-.93-1.197-1.273.09-.479.674-.793 1.168-.793.146 0 .27.029.383.074.42.194.789.3 1.104.3.234 0 .384-.06.465-.105l-.046-.569c-.098-1.626-.225-3.651.307-4.837C7.392 1.077 10.739.807 11.727.807l.419-.015h.06z',
123
- spotify: 'M12 0C5.4 0 0 5.4 0 12s5.4 12 12 12 12-5.4 12-12S18.66 0 12 0zm5.521 17.34c-.24.359-.66.48-1.021.24-2.82-1.74-6.36-2.101-10.561-1.141-.418.122-.779-.179-.899-.539-.12-.421.18-.78.54-.9 4.56-1.021 8.52-.6 11.64 1.32.42.18.479.659.301 1.02zm1.44-3.3c-.301.42-.841.6-1.262.3-3.239-1.98-8.159-2.58-11.939-1.38-.479.12-1.02-.12-1.14-.6-.12-.48.12-1.021.6-1.141C9.6 9.9 15 10.561 18.72 12.84c.361.181.54.78.241 1.2zm.12-3.36C15.24 8.4 8.82 8.16 5.16 9.301c-.6.179-1.2-.181-1.38-.721-.18-.601.18-1.2.72-1.381 4.26-1.26 11.28-1.02 15.721 1.621.539.3.719 1.02.419 1.56-.299.421-1.02.599-1.559.3z',
124
- telegram: 'M11.944 0A12 12 0 0 0 0 12a12 12 0 0 0 12 12 12 12 0 0 0 12-12A12 12 0 0 0 12 0a12 12 0 0 0-.056 0zm4.962 7.224c.1-.002.321.023.465.14a.506.506 0 0 1 .171.325c.016.093.036.306.02.472-.18 1.898-.962 6.502-1.36 8.627-.168.9-.499 1.201-.82 1.23-.696.065-1.225-.46-1.9-.902-1.056-.693-1.653-1.124-2.678-1.8-1.185-.78-.417-1.21.258-1.91.177-.184 3.247-2.977 3.307-3.23.007-.032.014-.15-.056-.212s-.174-.041-.249-.024c-.106.024-1.793 1.14-5.061 3.345-.48.33-.913.49-1.302.48-.428-.008-1.252-.241-1.865-.44-.752-.245-1.349-.374-1.297-.789.027-.216.325-.437.893-.663 3.498-1.524 5.83-2.529 6.998-3.014 3.332-1.386 4.025-1.627 4.476-1.635z',
125
- threads: 'M12.186 24h-.007c-3.581-.024-6.334-1.205-8.184-3.509C2.35 18.44 1.5 15.586 1.472 12.01v-.017c.03-3.579.879-6.43 2.525-8.482C5.845 1.205 8.6.024 12.18 0h.014c2.746.02 5.043.725 6.826 2.098 1.677 1.29 2.858 3.13 3.509 5.467l-2.04.569c-1.104-3.96-3.898-5.984-8.304-6.015-2.91.022-5.11.936-6.54 2.717C4.307 6.504 3.616 8.914 3.589 12c.027 3.086.718 5.496 2.057 7.164 1.43 1.783 3.631 2.698 6.54 2.717 2.623-.02 4.358-.631 5.8-2.045 1.647-1.613 1.618-3.593 1.09-4.798-.31-.71-.873-1.3-1.634-1.75-.192 1.352-.622 2.446-1.284 3.272-.886 1.102-2.14 1.704-3.73 1.79-1.202.065-2.361-.218-3.259-.801-1.063-.689-1.685-1.74-1.752-2.964-.065-1.19.408-2.285 1.33-3.082.88-.76 2.119-1.207 3.583-1.291a13.853 13.853 0 0 1 3.02.142c-.126-.742-.375-1.332-.75-1.757-.513-.586-1.308-.883-2.359-.89h-.029c-.844 0-1.992.232-2.721 1.32L7.734 7.847c.98-1.454 2.568-2.256 4.478-2.256h.044c3.194.02 5.097 1.975 5.287 5.388.108.046.216.094.321.142 1.49.7 2.58 1.761 3.154 3.07.797 1.82.871 4.79-1.548 7.158-1.85 1.81-4.094 2.628-7.277 2.65Zm1.003-11.69c-.242 0-.487.007-.739.021-1.836.103-2.98.946-2.916 2.143.067 1.256 1.452 1.839 2.784 1.767 1.224-.065 2.818-.543 3.086-3.71a10.5 10.5 0 0 0-2.215-.221z',
126
- tiktok: 'M12.525.02c1.31-.02 2.61-.01 3.91-.02.08 1.53.63 3.09 1.75 4.17 1.12 1.11 2.7 1.62 4.24 1.79v4.03c-1.44-.05-2.89-.35-4.2-.97-.57-.26-1.1-.59-1.62-.93-.01 2.92.01 5.84-.02 8.75-.08 1.4-.54 2.79-1.35 3.94-1.31 1.92-3.58 3.17-5.91 3.21-1.43.08-2.86-.31-4.08-1.03-2.02-1.19-3.44-3.37-3.65-5.71-.02-.5-.03-1-.01-1.49.18-1.9 1.12-3.72 2.58-4.96 1.66-1.44 3.98-2.13 6.15-1.72.02 1.48-.04 2.96-.04 4.44-.99-.32-2.15-.23-3.02.37-.63.41-1.11 1.04-1.36 1.75-.21.51-.15 1.07-.14 1.61.24 1.64 1.82 3.02 3.5 2.87 1.12-.01 2.19-.66 2.77-1.61.19-.33.4-.67.41-1.06.1-1.79.06-3.57.07-5.36.01-4.03-.01-8.05.02-12.07z',
127
- whatsapp: 'M17.472 14.382c-.297-.149-1.758-.867-2.03-.967-.273-.099-.471-.148-.67.15-.197.297-.767.966-.94 1.164-.173.199-.347.223-.644.075-.297-.15-1.255-.463-2.39-1.475-.883-.788-1.48-1.761-1.653-2.059-.173-.297-.018-.458.13-.606.134-.133.298-.347.446-.52.149-.174.198-.298.298-.497.099-.198.05-.371-.025-.52-.075-.149-.669-1.612-.916-2.207-.242-.579-.487-.5-.669-.51-.173-.008-.371-.01-.57-.01-.198 0-.52.074-.792.372-.272.297-1.04 1.016-1.04 2.479 0 1.462 1.065 2.875 1.213 3.074.149.198 2.096 3.2 5.077 4.487.709.306 1.262.489 1.694.625.712.227 1.36.195 1.871.118.571-.085 1.758-.719 2.006-1.413.248-.694.248-1.289.173-1.413-.074-.124-.272-.198-.57-.347m-5.421 7.403h-.004a9.87 9.87 0 01-5.031-1.378l-.361-.214-3.741.982.998-3.648-.235-.374a9.86 9.86 0 01-1.51-5.26c.001-5.45 4.436-9.884 9.888-9.884 2.64 0 5.122 1.03 6.988 2.898a9.825 9.825 0 012.893 6.994c-.003 5.45-4.437 9.884-9.885 9.884m8.413-18.297A11.815 11.815 0 0012.05 0C5.495 0 .16 5.335.157 11.892c0 2.096.547 4.142 1.588 5.945L.057 24l6.305-1.654a11.882 11.882 0 005.683 1.448h.005c6.554 0 11.89-5.335 11.893-11.893a11.821 11.821 0 00-3.48-8.413Z',
128
- x: 'M18.901 1.153h3.68l-8.04 9.19L24 22.846h-7.406l-5.8-7.584-6.638 7.584H.474l8.6-9.83L0 1.154h7.594l5.243 6.932ZM17.61 20.644h2.039L6.486 3.24H4.298Z',
129
- youtube: 'M23.498 6.186a3.016 3.016 0 0 0-2.122-2.136C19.505 3.545 12 3.545 12 3.545s-7.505 0-9.377.505A3.017 3.017 0 0 0 .502 6.186C0 8.07 0 12 0 12s0 3.93.502 5.814a3.016 3.016 0 0 0 2.122 2.136c1.871.505 9.376.505 9.376.505s7.505 0 9.377-.505a3.015 3.015 0 0 0 2.122-2.136C24 15.93 24 12 24 12s0-3.93-.502-5.814zM9.545 15.568V8.432L15.818 12l-6.273 3.568z',
130
- };
131
113
 
132
114
  /** One representative brand hex per platform, for the social block's "Brand" palette mode. Flat approximations, not exact brand-guideline swatches. */
133
115
  export const SOCIAL_BRAND = {
@@ -169,26 +151,18 @@ export function icon(name, size) {
169
151
  return svg;
170
152
  }
171
153
 
154
+ /** Social keys whose glyph differs from the same-named UI icon. */
155
+ const SOCIAL_ALIAS = { x: 'xSocial' };
156
+
172
157
  /**
173
- * Social-platform icon: the official filled brand glyph when we have one,
174
- * falling back to the stroke set (mail, globe, link, unknown labels).
175
- * Fill inherits currentColor exactly like the stroke icons, so the social
176
- * block's palette/contrast logic and the export round-trip are unchanged.
158
+ * Social-platform icon. Every glyph resolves into the same in-house stroke
159
+ * set as the rest of the chrome -- geometric marks that identify where a
160
+ * link goes without reproducing anyone's registered logo artwork. Kept as
161
+ * its own entry point because the social key 'x' must not resolve to the
162
+ * UI's close glyph; resolve through brandIcon(), never icon().
177
163
  */
178
164
  export function brandIcon(name, size) {
179
- const d = BRAND_GLYPHS[name];
180
- if (!d) return icon(name, size);
181
- const svg = document.createElementNS(SVG_NS, 'svg');
182
- svg.setAttribute('width', String(size || 18));
183
- svg.setAttribute('height', String(size || 18));
184
- svg.setAttribute('viewBox', '0 0 24 24');
185
- svg.setAttribute('fill', 'currentColor');
186
- svg.style.display = 'block';
187
- svg.style.flex = 'none';
188
- const p = document.createElementNS(SVG_NS, 'path');
189
- p.setAttribute('d', d);
190
- svg.appendChild(p);
191
- return svg;
165
+ return icon(SOCIAL_ALIAS[name] || name, size);
192
166
  }
193
167
 
194
168
  function shapeNode(shape) {
package/src/core/ids.js CHANGED
@@ -1 +1 @@
1
- export const uid = () => Math.random().toString(36).slice(2, 9);
1
+ export const uid = () => Math.random().toString(36).slice(2, 9);
package/src/core/parse.js CHANGED
@@ -1,10 +1,10 @@
1
- export function parseItems(s) {
2
- return String(s || '').split('\n').map((l) => l.trim()).filter(Boolean).map((l) => {
3
- const i = l.indexOf('|');
4
- return i < 0 ? { label: l, href: '#' } : { label: l.slice(0, i).trim(), href: l.slice(i + 1).trim() };
5
- });
6
- }
7
-
8
- export function cellsOf(p) {
9
- return String(p.data || '').split('\n').filter((l) => l.trim()).map((l) => l.split('|').map((c) => c.trim()));
10
- }
1
+ export function parseItems(s) {
2
+ return String(s || '').split('\n').map((l) => l.trim()).filter(Boolean).map((l) => {
3
+ const i = l.indexOf('|');
4
+ return i < 0 ? { label: l, href: '#' } : { label: l.slice(0, i).trim(), href: l.slice(i + 1).trim() };
5
+ });
6
+ }
7
+
8
+ export function cellsOf(p) {
9
+ return String(p.data || '').split('\n').filter((l) => l.trim()).map((l) => l.split('|').map((c) => c.trim()));
10
+ }
@@ -1,15 +1,15 @@
1
- /** Data-URI placeholder image generator, ported verbatim from the original. */
2
- function enc(s) {
3
- return encodeURIComponent(s).replace(/\(/g, '%28').replace(/\)/g, '%29');
4
- }
5
-
6
- export function PH(label, w, ht) {
7
- return 'data:image/svg+xml;utf8,' + enc(
8
- '<svg xmlns="http://www.w3.org/2000/svg" width="' + w + '" height="' + ht + '">' +
9
- '<defs><pattern id="s" width="9" height="9" patternTransform="rotate(45)" patternUnits="userSpaceOnUse">' +
10
- '<rect width="9" height="9" fill="#ececed"/><line x1="0" y1="0" x2="0" y2="9" stroke="#cfd3d8" stroke-width="3"/></pattern></defs>' +
11
- '<rect width="100%" height="100%" fill="url(#s)"/>' +
12
- '<rect x="0.5" y="0.5" width="' + (w - 1) + '" height="' + (ht - 1) + '" fill="none" stroke="#9aa2ab"/>' +
13
- '<text x="50%" y="50%" dy="4" text-anchor="middle" font-family="ui-monospace,monospace" font-size="' + Math.max(11, Math.round(w / 40)) + '" fill="#5b6672">' + label + '</text></svg>',
14
- );
15
- }
1
+ /** Data-URI placeholder image generator, ported verbatim from the original. */
2
+ function enc(s) {
3
+ return encodeURIComponent(s).replace(/\(/g, '%28').replace(/\)/g, '%29');
4
+ }
5
+
6
+ export function PH(label, w, ht) {
7
+ return 'data:image/svg+xml;utf8,' + enc(
8
+ '<svg xmlns="http://www.w3.org/2000/svg" width="' + w + '" height="' + ht + '">' +
9
+ '<defs><pattern id="s" width="9" height="9" patternTransform="rotate(45)" patternUnits="userSpaceOnUse">' +
10
+ '<rect width="9" height="9" fill="#ececed"/><line x1="0" y1="0" x2="0" y2="9" stroke="#cfd3d8" stroke-width="3"/></pattern></defs>' +
11
+ '<rect width="100%" height="100%" fill="url(#s)"/>' +
12
+ '<rect x="0.5" y="0.5" width="' + (w - 1) + '" height="' + (ht - 1) + '" fill="none" stroke="#9aa2ab"/>' +
13
+ '<text x="50%" y="50%" dy="4" text-anchor="middle" font-family="ui-monospace,monospace" font-size="' + Math.max(11, Math.round(w / 40)) + '" fill="#5b6672">' + label + '</text></svg>',
14
+ );
15
+ }
@@ -1,11 +1,11 @@
1
- export const DEFAULT_VARS = 'first_name\nlast_name\nemail\ncompany\ncity\norder_id\nplan\ndiscount\nunsubscribe_url';
2
- export const TOKEN = (t) => '{' + '{ ' + t + ' }' + '}';
3
-
4
- /** Variables are supplied by the host application -- the editor only ever shows the tokens, never a substituted value. */
5
- export function vars(raw) {
6
- const list = Array.isArray(raw) ? raw : String(raw == null ? DEFAULT_VARS : raw).split(/[\n,]/);
7
- return list.map((v) => String(v).trim().replace(/^\{\{\s*|\s*\}\}$/g, '')).filter(Boolean);
8
- }
9
-
10
- /** Which prop field a merge tag lands in when inserted from the Data tab, keyed by the selected block's type. */
11
- export const INSERT_KEYS = { text: 'html', heading: 'text', button: 'label', html: 'code', codeblock: 'code', quote: 'text', list: 'items', table: 'data' };
1
+ export const DEFAULT_VARS = 'first_name\nlast_name\nemail\ncompany\ncity\norder_id\nplan\ndiscount\nunsubscribe_url';
2
+ export const TOKEN = (t) => '{' + '{ ' + t + ' }' + '}';
3
+
4
+ /** Variables are supplied by the host application -- the editor only ever shows the tokens, never a substituted value. */
5
+ export function vars(raw) {
6
+ const list = Array.isArray(raw) ? raw : String(raw == null ? DEFAULT_VARS : raw).split(/[\n,]/);
7
+ return list.map((v) => String(v).trim().replace(/^\{\{\s*|\s*\}\}$/g, '')).filter(Boolean);
8
+ }
9
+
10
+ /** Which prop field a merge tag lands in when inserted from the Data tab, keyed by the selected block's type. */
11
+ export const INSERT_KEYS = { text: 'html', heading: 'text', button: 'label', html: 'code', codeblock: 'code', quote: 'text', list: 'items', table: 'data' };
@@ -89,7 +89,9 @@ function tip(node, label, dir, align) {
89
89
  * chrome; while present the built-in toggle is hidden), `footer` ("none" to
90
90
  * remove the attribution strip, or any string to replace its text).
91
91
  * Properties: `.variables`, `.toolbar` (which parts of the top bar are shown),
92
- * `.aiProvider` (optional async fn, replaces the original's `window.claude.complete`),
92
+ * `.aiProvider` (optional async fn -- the host's own model call; the AI
93
+ * features stay hidden until one is set, since the package ships no client
94
+ * and talks to no model service of its own),
93
95
  * `.iconProvider` (optional social-icon override), `.storageProvider` (host-supplied
94
96
  * file storage -- see `core/storage.js`), `.storageLimits` (host-set upload ceilings,
95
97
  * required whenever a provider is set), `.messages` (UI string overrides --