@lit-pigeon/editor 0.1.2 → 0.2.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/dist/templates.js CHANGED
@@ -1,11 +1,260 @@
1
- import { LitElement as m, html as o, css as f } from "lit";
2
- import { property as c, state as s, customElement as g } from "lit/decorators.js";
3
- var h = Object.defineProperty, b = Object.getOwnPropertyDescriptor, r = (e, i, p, n) => {
4
- for (var a = n > 1 ? void 0 : n ? b(i, p) : i, l = e.length - 1, d; l >= 0; l--)
5
- (d = e[l]) && (a = (n ? d(i, p, a) : d(a)) || a);
6
- return n && a && h(i, p, a), a;
1
+ import { LitElement as u, html as l, css as v } from "lit";
2
+ import { property as g, state as p, customElement as f } from "lit/decorators.js";
3
+ const m = {
4
+ // toolbar
5
+ "toolbar.undo": "Undo",
6
+ "toolbar.redo": "Redo",
7
+ "toolbar.preview-device": "Preview device",
8
+ "toolbar.desktop-view": "Desktop view",
9
+ "toolbar.tablet-view-title": "Tablet view (768px)",
10
+ "toolbar.tablet-view": "Tablet view",
11
+ "toolbar.mobile-view-title": "Mobile view (375px)",
12
+ "toolbar.mobile-view": "Mobile view",
13
+ "toolbar.fullscreen": "Fullscreen",
14
+ "toolbar.exit-fullscreen": "Exit fullscreen",
15
+ "toolbar.enter-fullscreen": "Enter fullscreen",
16
+ "toolbar.templates": "Templates",
17
+ "toolbar.preview": "Preview",
18
+ "toolbar.export": "Export",
19
+ "toolbar.export-format": "Export format",
20
+ "toolbar.export-html": "Export HTML",
21
+ "toolbar.export-mjml": "Export MJML",
22
+ "toolbar.export-json": "Export JSON",
23
+ // palette
24
+ "palette.label": "Palette",
25
+ "palette.tab.content": "Content",
26
+ "palette.tab.layers": "Layers",
27
+ "palette.tab.brand": "Brand",
28
+ "palette.tab.saved": "Saved",
29
+ // palette — layout section
30
+ "palette.layout.section-content": "Content",
31
+ "palette.layout.section-layout": "Layout",
32
+ "palette.layout.1-col": "1 Column",
33
+ "palette.layout.2-col": "2 Columns",
34
+ "palette.layout.3-col": "3 Columns",
35
+ "palette.layout.4-col": "4 Columns",
36
+ // palette — brand tab
37
+ "palette.brand.colors": "Colors",
38
+ "palette.brand.fonts": "Fonts",
39
+ "palette.brand.logos": "Logos",
40
+ "palette.brand.add": "+ Add",
41
+ "palette.brand.no-colors": "No colors yet",
42
+ "palette.brand.no-fonts": "No fonts yet",
43
+ "palette.brand.no-logos": "No logos yet",
44
+ "palette.brand.color-name-label": "Color name",
45
+ "palette.brand.color-value-label": "Color value",
46
+ "palette.brand.delete-title": "Delete",
47
+ "palette.brand.insert-logo-title": "Insert logo",
48
+ // palette — saved tab
49
+ "palette.saved.empty": "No saved rows yet. Use the bookmark action on a row to save it here.",
50
+ "palette.saved.delete-title": "Delete",
51
+ // preview
52
+ "preview.heading": "Preview",
53
+ "preview.tab-group-label": "Preview format",
54
+ "preview.tab.preview": "Preview",
55
+ "preview.tab.html": "HTML",
56
+ "preview.tab.mjml": "MJML",
57
+ "preview.tab.json": "JSON",
58
+ "preview.device.desktop": "Desktop preview",
59
+ "preview.device.mobile": "Mobile preview",
60
+ "preview.close": "Close preview",
61
+ "preview.loading": "Rendering...",
62
+ // template picker
63
+ "template.heading": "Templates",
64
+ "template.close": "Close",
65
+ "template.section.choose": "Choose a template",
66
+ "template.empty": "No templates available yet.",
67
+ "template.section.save": "Save current as template",
68
+ "template.field.name": "Name",
69
+ "template.field.name-placeholder": "My template",
70
+ "template.field.category": "Category",
71
+ "template.field.description": "Description (optional)",
72
+ "template.field.description-placeholder": "What is this template for?",
73
+ "template.cancel": "Cancel",
74
+ "template.save": "Save template",
75
+ "template.error.name-required": "Name is required",
76
+ // asset manager
77
+ "asset.title": "Select asset",
78
+ "asset.title-upload": "Select image",
79
+ "asset.close": "Close",
80
+ "asset.tab.library": "Library",
81
+ "asset.tab.upload": "Upload",
82
+ "asset.folder.all": "All folders",
83
+ "asset.search": "Search assets",
84
+ "asset.tag-filter-label": "Filter by tag",
85
+ "asset.loading": "Loading…",
86
+ "asset.empty.filtered": "No assets match your filters.",
87
+ "asset.empty.no-assets": "No saved assets yet. Upload one to get started.",
88
+ "asset.drop-zone.label": "Drag & drop an image here",
89
+ "asset.drop-zone.hint": "or click to browse",
90
+ "asset.url.separator": "or enter URL",
91
+ "asset.url.placeholder": "https://example.com/image.jpg",
92
+ "asset.url.use": "Use URL",
93
+ // property panels — shared (common) labels
94
+ "panel.common.backgroundColor": "Background Color",
95
+ "panel.common.padding": "Padding",
96
+ "panel.common.outerPadding": "Outer Padding",
97
+ "panel.common.innerPadding": "Inner Padding",
98
+ "panel.common.alignment": "Alignment",
99
+ "panel.common.fontSize": "Font Size",
100
+ "panel.common.borderRadius": "Border Radius",
101
+ "panel.common.linkUrl": "Link URL",
102
+ "panel.common.urlPlaceholder": "https://example.com",
103
+ "panel.common.contentHtml": "Content (HTML)",
104
+ "panel.common.insertMergeTag": "Insert merge tag",
105
+ "panel.common.tagBtn": "{ } Tag",
106
+ "panel.common.uploadImage": "Upload Image",
107
+ "panel.common.left": "Left",
108
+ "panel.common.center": "Center",
109
+ // property panels — body
110
+ "panel.body.title": "Email Body",
111
+ "panel.body.contentWidth": "Content Width",
112
+ "panel.body.fontFamily": "Font Family",
113
+ "panel.body.contentAlignment": "Content Alignment",
114
+ "panel.body.emailName": "Email Name",
115
+ "panel.body.previewText": "Preview Text",
116
+ "panel.body.previewTextPlaceholder": "Email preview text...",
117
+ // property panels — text
118
+ "panel.text.title": "Text Properties",
119
+ "panel.text.textAlign": "Text Align",
120
+ "panel.text.lineHeight": "Line Height",
121
+ // property panels — button
122
+ "panel.button.title": "Button Properties",
123
+ "panel.button.buttonText": "Button Text",
124
+ "panel.button.textColor": "Text Color",
125
+ "panel.button.fontWeight": "Font Weight",
126
+ "panel.button.fontWeight.normal": "Normal (400)",
127
+ "panel.button.fontWeight.medium": "Medium (500)",
128
+ "panel.button.fontWeight.semibold": "Semibold (600)",
129
+ "panel.button.fontWeight.bold": "Bold (700)",
130
+ "panel.button.fullWidth": "Full Width",
131
+ // property panels — image
132
+ "panel.image.title": "Image Properties",
133
+ "panel.image.imageUrl": "Image URL",
134
+ "panel.image.urlPlaceholder": "https://example.com/image.jpg",
135
+ "panel.image.altText": "Alt Text",
136
+ "panel.image.altPlaceholder": "Image description",
137
+ "panel.image.width": "Width (0 = auto)",
138
+ // property panels — hero
139
+ "panel.hero.title": "Hero Properties",
140
+ "panel.hero.backgroundUrl": "Background URL",
141
+ "panel.hero.backgroundUrlPlaceholder": "https://example.com/hero.jpg",
142
+ "panel.hero.backgroundPosition": "Background Position",
143
+ "panel.hero.mode": "Mode",
144
+ "panel.hero.modeFluidHeight": "Fluid Height",
145
+ "panel.hero.modeFixedHeight": "Fixed Height",
146
+ "panel.hero.height": "Height",
147
+ "panel.hero.width": "Width",
148
+ "panel.hero.verticalAlign": "Vertical Align",
149
+ "panel.hero.verticalAlignTop": "Top",
150
+ "panel.hero.verticalAlignMiddle": "Middle",
151
+ "panel.hero.verticalAlignBottom": "Bottom",
152
+ // property panels — navbar
153
+ "panel.navbar.title": "Navbar Properties",
154
+ "panel.navbar.links": "Links",
155
+ "panel.navbar.linkLabel": "Link",
156
+ "panel.navbar.removeLink": "Remove",
157
+ "panel.navbar.linkText": "Text",
158
+ "panel.navbar.url": "URL",
159
+ "panel.navbar.addLink": "+ Add Link",
160
+ "panel.navbar.hamburger": "Hamburger (mobile)",
161
+ "panel.navbar.hamburgerShow": "Show",
162
+ "panel.navbar.hamburgerHide": "Hide",
163
+ "panel.navbar.linkColor": "Link Color",
164
+ "panel.navbar.linkFontSize": "Link Font Size",
165
+ "panel.navbar.linkPadding": "Link Padding",
166
+ // property panels — divider
167
+ "panel.divider.title": "Divider Properties",
168
+ "panel.divider.style": "Style",
169
+ "panel.divider.styleSolid": "Solid",
170
+ "panel.divider.styleDashed": "Dashed",
171
+ "panel.divider.styleDotted": "Dotted",
172
+ "panel.divider.color": "Color",
173
+ "panel.divider.width": "Width",
174
+ "panel.divider.lineWidth": "Line Width",
175
+ // property panels — spacer
176
+ "panel.spacer.title": "Spacer Properties",
177
+ "panel.spacer.height": "Height",
178
+ // property panels — social
179
+ "panel.social.title": "Social Properties",
180
+ "panel.social.icons": "Icons",
181
+ "panel.social.iconLabel": "Icon",
182
+ "panel.social.removeIcon": "Remove",
183
+ "panel.social.network": "Network",
184
+ "panel.social.url": "URL",
185
+ "panel.social.iconUrl": "Icon URL",
186
+ "panel.social.altText": "Label (alt text)",
187
+ "panel.social.addIcon": "+ Add Icon",
188
+ "panel.social.iconSize": "Icon Size",
189
+ "panel.social.spacing": "Spacing",
190
+ // property panels — html
191
+ "panel.html.title": "HTML Properties",
192
+ "panel.html.rawHtml": "Raw HTML",
193
+ // property panels — row
194
+ "panel.row.title": "Row Properties",
195
+ "panel.row.columnLayout": "Column Layout",
196
+ "panel.row.layout1col": "1 Column",
197
+ "panel.row.layout2col": "2 Equal",
198
+ "panel.row.layout3col": "3 Equal",
199
+ "panel.row.layout4col": "4 Equal",
200
+ "panel.row.backgroundImageUrl": "Background Image URL",
201
+ "panel.row.fullWidth": "Full Width",
202
+ "panel.row.displayCondition": "Display condition",
203
+ // controls — color picker
204
+ "control.color.label": "Color",
205
+ // controls — font picker
206
+ "control.fontPicker.label": "Font Family",
207
+ // controls — link type picker
208
+ "control.linkType.ariaLabel": "Insert a special link",
209
+ "control.linkType.placeholder": "+ Special link",
210
+ "control.linkType.emailPrompt": "Email address",
211
+ "control.linkType.telPrompt": "Phone number",
212
+ // controls — spacing input
213
+ "control.spacing.top": "Top",
214
+ "control.spacing.right": "Right",
215
+ "control.spacing.bottom": "Bottom",
216
+ "control.spacing.left": "Left",
217
+ "control.spacing.topTitle": "Top (px)",
218
+ "control.spacing.rightTitle": "Right (px)",
219
+ "control.spacing.bottomTitle": "Bottom (px)",
220
+ "control.spacing.leftTitle": "Left (px)",
221
+ // controls — alignment picker
222
+ "control.alignment.left": "Align left",
223
+ "control.alignment.center": "Align center",
224
+ "control.alignment.right": "Align right",
225
+ // controls — merge tag picker
226
+ "control.mergeTag.searchPlaceholder": "Search tags...",
227
+ "control.mergeTag.noMatches": "No matching tags",
228
+ // rich text bubble toolbar
229
+ "richtext.bold": "Bold (Cmd+B)",
230
+ "richtext.italic": "Italic (Cmd+I)",
231
+ "richtext.underline": "Underline (Cmd+U)",
232
+ "richtext.strike": "Strike",
233
+ "richtext.code": "Code",
234
+ "richtext.link": "Link",
235
+ "richtext.apply": "Apply",
236
+ "richtext.removeLink": "Remove link",
237
+ "richtext.urlPlaceholder": "https://…"
238
+ }, x = /* @__PURE__ */ new Set(["ar", "he", "fa", "ur", "ps", "sd", "dv", "yi"]);
239
+ let b = "en", h = { en: m };
240
+ function L(e, t) {
241
+ b = e || "en", h = { en: m, ...t ?? {} };
242
+ }
243
+ function o(e) {
244
+ var t;
245
+ return ((t = h[b]) == null ? void 0 : t[e]) ?? m[e] ?? e;
246
+ }
247
+ function T(e, t) {
248
+ if (t) return t;
249
+ const n = (e || "en").toLowerCase().split(/[-_]/)[0];
250
+ return x.has(n) ? "rtl" : "ltr";
251
+ }
252
+ var y = Object.defineProperty, w = Object.getOwnPropertyDescriptor, r = (e, t, n, s) => {
253
+ for (var i = s > 1 ? void 0 : s ? w(t, n) : t, d = e.length - 1, c; d >= 0; d--)
254
+ (c = e[d]) && (i = (s ? c(t, n, i) : c(i)) || i);
255
+ return s && i && y(t, n, i), i;
7
256
  };
8
- const v = [
257
+ const k = [
9
258
  { v: "welcome", l: "Welcome" },
10
259
  { v: "newsletter", l: "Newsletter" },
11
260
  { v: "transactional", l: "Transactional" },
@@ -13,21 +262,21 @@ const v = [
13
262
  { v: "announcement", l: "Announcement" },
14
263
  { v: "other", l: "Other" }
15
264
  ];
16
- let t = class extends m {
265
+ let a = class extends u {
17
266
  constructor() {
18
267
  super(...arguments), this.open = !1, this._templates = [], this._name = "", this._description = "", this._category = "other", this._formError = "", this._close = () => {
19
268
  this.open = !1, this._formError = "";
20
269
  }, this._onSubmit = (e) => {
21
270
  e.preventDefault();
22
- const i = this._name.trim();
23
- if (!i) {
24
- this._formError = "Name is required";
271
+ const t = this._name.trim();
272
+ if (!t) {
273
+ this._formError = o("template.error.name-required");
25
274
  return;
26
275
  }
27
276
  this._formError = "", this.dispatchEvent(
28
277
  new CustomEvent("template-save", {
29
278
  detail: {
30
- name: i,
279
+ name: t,
31
280
  description: this._description.trim() || void 0,
32
281
  category: this._category
33
282
  },
@@ -53,61 +302,61 @@ let t = class extends m {
53
302
  }
54
303
  }
55
304
  render() {
56
- return o`
305
+ return l`
57
306
  <div class="overlay" @click=${this._close}></div>
58
307
  <div class="modal">
59
308
  <div class="header">
60
- <h3>Templates</h3>
61
- <button class="close-btn" title="Close" @click=${this._close}>&times;</button>
309
+ <h3>${o("template.heading")}</h3>
310
+ <button class="close-btn" title=${o("template.close")} @click=${this._close}>&times;</button>
62
311
  </div>
63
312
  <div class="body">
64
313
  <div>
65
- <h4 class="section-title">Choose a template</h4>
66
- ${this._templates.length === 0 ? o`<div class="empty">No templates available yet.</div>` : o`<div class="grid">${this._templates.map((e) => this._renderCard(e))}</div>`}
314
+ <h4 class="section-title">${o("template.section.choose")}</h4>
315
+ ${this._templates.length === 0 ? l`<div class="empty">${o("template.empty")}</div>` : l`<div class="grid">${this._templates.map((e) => this._renderCard(e))}</div>`}
67
316
  </div>
68
317
 
69
318
  <form class="save-form" @submit=${this._onSubmit}>
70
- <h4 class="section-title">Save current as template</h4>
319
+ <h4 class="section-title">${o("template.section.save")}</h4>
71
320
  <div class="save-row">
72
321
  <div class="field">
73
- <label for="template-name">Name</label>
322
+ <label for="template-name">${o("template.field.name")}</label>
74
323
  <input
75
324
  id="template-name"
76
325
  name="template-name"
77
326
  type="text"
78
- placeholder="My template"
327
+ placeholder=${o("template.field.name-placeholder")}
79
328
  .value=${this._name}
80
329
  @input=${(e) => this._name = e.target.value}
81
330
  />
82
331
  </div>
83
332
  <div class="field">
84
- <label for="template-category">Category</label>
333
+ <label for="template-category">${o("template.field.category")}</label>
85
334
  <select
86
335
  id="template-category"
87
336
  name="template-category"
88
337
  .value=${this._category}
89
338
  @change=${(e) => this._category = e.target.value}
90
339
  >
91
- ${v.map(
92
- (e) => o`<option value=${e.v} ?selected=${this._category === e.v}>${e.l}</option>`
340
+ ${k.map(
341
+ (e) => l`<option value=${e.v} ?selected=${this._category === e.v}>${e.l}</option>`
93
342
  )}
94
343
  </select>
95
344
  </div>
96
345
  </div>
97
346
  <div class="field">
98
- <label for="template-description">Description (optional)</label>
347
+ <label for="template-description">${o("template.field.description")}</label>
99
348
  <textarea
100
349
  id="template-description"
101
350
  name="template-description"
102
- placeholder="What is this template for?"
351
+ placeholder=${o("template.field.description-placeholder")}
103
352
  .value=${this._description}
104
353
  @input=${(e) => this._description = e.target.value}
105
354
  ></textarea>
106
355
  </div>
107
- ${this._formError ? o`<div class="error">${this._formError}</div>` : ""}
356
+ ${this._formError ? l`<div class="error">${this._formError}</div>` : ""}
108
357
  <div class="form-actions">
109
- <button type="button" class="secondary" @click=${this._close}>Cancel</button>
110
- <button type="submit">Save template</button>
358
+ <button type="button" class="secondary" @click=${this._close}>${o("template.cancel")}</button>
359
+ <button type="submit">${o("template.save")}</button>
111
360
  </div>
112
361
  </form>
113
362
  </div>
@@ -115,11 +364,11 @@ let t = class extends m {
115
364
  `;
116
365
  }
117
366
  _renderCard(e) {
118
- return o`
367
+ return l`
119
368
  <button class="template-card" @click=${() => this._onPick(e)} title="Load ${e.name}">
120
- ${e.thumbnail ? o`<img class="thumb" src=${e.thumbnail} alt="" />` : o`<div class="thumb-placeholder">${e.category ?? "template"}</div>`}
369
+ ${e.thumbnail ? l`<img class="thumb" src=${e.thumbnail} alt="" />` : l`<div class="thumb-placeholder">${e.category ?? "template"}</div>`}
121
370
  <span class="name">${e.name}</span>
122
- ${e.description ? o`<span class="description">${e.description}</span>` : ""}
371
+ ${e.description ? l`<span class="description">${e.description}</span>` : ""}
123
372
  </button>
124
373
  `;
125
374
  }
@@ -133,7 +382,7 @@ let t = class extends m {
133
382
  );
134
383
  }
135
384
  };
136
- t.styles = f`
385
+ a.styles = v`
137
386
  :host { display: none; }
138
387
  :host([open]) { display: block; position: fixed; inset: 0; z-index: 10000; }
139
388
  .overlay { position: absolute; inset: 0; background: rgba(0,0,0,0.5); }
@@ -246,29 +495,39 @@ t.styles = f`
246
495
  .error { color: var(--pigeon-danger, #ef4444); font-size: 12px; }
247
496
  `;
248
497
  r([
249
- c({ attribute: !1 })
250
- ], t.prototype, "storage", 2);
498
+ g({ attribute: !1 })
499
+ ], a.prototype, "storage", 2);
251
500
  r([
252
- c({ type: Boolean, reflect: !0 })
253
- ], t.prototype, "open", 2);
501
+ g({ type: Boolean, reflect: !0 })
502
+ ], a.prototype, "open", 2);
254
503
  r([
255
- s()
256
- ], t.prototype, "_templates", 2);
504
+ p()
505
+ ], a.prototype, "_templates", 2);
257
506
  r([
258
- s()
259
- ], t.prototype, "_name", 2);
507
+ p()
508
+ ], a.prototype, "_name", 2);
260
509
  r([
261
- s()
262
- ], t.prototype, "_description", 2);
510
+ p()
511
+ ], a.prototype, "_description", 2);
263
512
  r([
264
- s()
265
- ], t.prototype, "_category", 2);
513
+ p()
514
+ ], a.prototype, "_category", 2);
266
515
  r([
267
- s()
268
- ], t.prototype, "_formError", 2);
269
- t = r([
270
- g("pigeon-template-picker")
271
- ], t);
516
+ p()
517
+ ], a.prototype, "_formError", 2);
518
+ a = r([
519
+ f("pigeon-template-picker")
520
+ ], a);
521
+ const C = /* @__PURE__ */ Object.freeze(/* @__PURE__ */ Object.defineProperty({
522
+ __proto__: null,
523
+ get PigeonTemplatePicker() {
524
+ return a;
525
+ }
526
+ }, Symbol.toStringTag, { value: "Module" }));
272
527
  export {
273
- t as PigeonTemplatePicker
528
+ a as P,
529
+ L as c,
530
+ C as p,
531
+ T as r,
532
+ o as t
274
533
  };
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@lit-pigeon/editor",
3
- "version": "0.1.2",
3
+ "version": "0.2.0",
4
4
  "description": "Lit Web Components UI for the Pigeon email editor",
5
5
  "type": "module",
6
6
  "main": "./dist/index.js",
@@ -26,7 +26,7 @@
26
26
  "@tiptap/pm": "^2.10.0",
27
27
  "@tiptap/starter-kit": "^2.10.0",
28
28
  "lit": "^3.1.0",
29
- "@lit-pigeon/core": "^0.1.2"
29
+ "@lit-pigeon/core": "^0.2.0"
30
30
  },
31
31
  "devDependencies": {
32
32
  "happy-dom": "^20.9.0",