@richhtmleditor/templates 1.2.8 → 1.2.9

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/README.md CHANGED
@@ -1,20 +1,29 @@
1
1
  # @richhtmleditor/templates
2
2
 
3
- Document templates plugin for Rich HTML Editor. Adds an **Insert Template** toolbar tool with a gallery of pre-built document templates report, letter, memo, resume, and more. Built on [`@richhtmleditor/core`](https://www.npmjs.com/package/@richhtmleditor/core).
3
+ Document templates plugin for Rich HTML Editor. Adds an **Insert Template** toolbar tool and a **Save as Template** button so users can browse, insert, and manage reusable document templates — including templates they design themselves.
4
4
 
5
- **Current release: 1.2.8** — Depends on `@richhtmleditor/core` **^1.2.8**.
5
+ **Current release: 1.2.9** — Depends on `@richhtmleditor/core` **^1.2.9**.
6
6
 
7
7
  **Repository:** [github.com/rajkishorsahu89/richhtmleditor](https://github.com/rajkishorsahu89/richhtmleditor)
8
8
 
9
9
  **Demo:** [richhtmleditor.stackkitlabs.com](https://richhtmleditor.stackkitlabs.com/) — [demo](https://richhtmleditor.stackkitlabs.com/demo) · [guide](https://richhtmleditor.stackkitlabs.com/guide) · [API](https://richhtmleditor.stackkitlabs.com/api)
10
10
 
11
+ ### What's new in 1.2.9
12
+
13
+ - **User-defined templates** — `allowUserTemplates: true` enables users to save the current editor content as a named, categorised template (stored in `localStorage`)
14
+ - **Save as Template toolbar button** — `saveAsTemplate` tool opens a name/category dialog; enforces configurable `maxUserTemplates` limit (default 20)
15
+ - **My Templates tab** — two-tab modal: "All" (built-in + user) and "My Templates (N/20)"; delete button with custom confirmation dialog on each user card
16
+ - **Export / Import JSON** — download all user templates as `my-templates.json`; import from file (merges, skips duplicates)
17
+ - **Category filter chips** — chips appear below search when templates span 3+ categories; chips reset on tab switch
18
+ - **Append vs Replace** — footer now has **Append** (adds template after current content) and **Replace** (replaces all content) buttons
19
+ - **Custom toast notifications** — replaces all native `alert()` and `confirm()` calls with styled in-app toasts (success / error / info) and a custom delete-confirmation modal
20
+
11
21
  ### What's in 1.2.8
12
22
 
13
23
  - **`createTemplatesPlugin`** — registers the `insertTemplate` toolbar tool
14
- - **Template gallery** — grid of pre-built templates with preview thumbnails
15
- - **Built-in templates** — report, letter, memo, resume, meeting notes
16
- - **Custom templates** — register your own HTML templates with title and thumbnail
17
- - **One-click insert** — select a template to replace or append to the document
24
+ - **Template gallery** — grid of pre-built templates with live HTML preview thumbnails
25
+ - **Search** — real-time filter by name, description, or category
26
+ - **Variable substitution** — `{{variable}}` placeholders resolved at insert time via `variables` map or `getVariables` callback
18
27
 
19
28
  > Community feature — no enterprise licence required.
20
29
 
@@ -36,7 +45,13 @@ import { createTemplatesPlugin } from "@richhtmleditor/templates";
36
45
  const editor = createEditor({
37
46
  element: host,
38
47
  toolbar: { preset: "full" },
39
- plugins: [createTemplatesPlugin()]
48
+ plugins: [
49
+ createTemplatesPlugin({
50
+ templates: myTemplates,
51
+ allowUserTemplates: true,
52
+ maxUserTemplates: 20
53
+ })
54
+ ]
40
55
  });
41
56
  ```
42
57
 
@@ -45,46 +60,96 @@ const editor = createEditor({
45
60
  ```ts
46
61
  import { createTemplatesPlugin } from "@richhtmleditor/templates";
47
62
 
48
- plugins = [createTemplatesPlugin()];
63
+ plugins = [createTemplatesPlugin({
64
+ templates: this.myTemplates,
65
+ allowUserTemplates: true
66
+ })];
49
67
  ```
50
68
 
51
69
  ```html
52
70
  <richhtmleditor [plugins]="plugins" [toolbar]="{ preset: 'full' }" />
53
71
  ```
54
72
 
55
- ### Custom templates
73
+ ### Custom templates with variable substitution
56
74
 
57
75
  ```ts
58
76
  createTemplatesPlugin({
59
77
  templates: [
60
78
  {
61
- id: "invoice",
62
- title: "Invoice",
63
- html: "<h1>Invoice</h1><table>...</table>"
79
+ id: "welcome",
80
+ label: "Welcome Email",
81
+ category: "Email",
82
+ description: "Greeting for new users",
83
+ content: "<p>Dear {{firstName}},</p><p>Welcome to {{company}}!</p>"
64
84
  }
65
- ]
85
+ ],
86
+ variables: { company: "Acme Corp" },
87
+ getVariables: (tmpl) => ({ firstName: currentUser.firstName }),
88
+ onInsert: (tmpl, resolvedHtml) => console.log("Inserted:", tmpl.label)
89
+ })
90
+ ```
91
+
92
+ ### User-defined templates
93
+
94
+ ```ts
95
+ createTemplatesPlugin({
96
+ templates: builtinTemplates,
97
+ allowUserTemplates: true, // enables Save as Template button
98
+ maxUserTemplates: 20, // default: 20
99
+ userTemplateStorageKey: "my-app-templates", // default: "de-user-templates"
100
+ onSaveTemplate: (tpl) => console.log("Saved:", tpl.label),
101
+ onDeleteTemplate: (id) => console.log("Deleted:", id)
66
102
  })
67
103
  ```
68
104
 
69
105
  ## API
70
106
 
71
- ### `createTemplatesPlugin(options?)`
107
+ ### `createTemplatesPlugin(options)`
72
108
 
73
- Returns an `EditorPlugin` that registers the `insertTemplate` toolbar tool.
109
+ Returns an `EditorPlugin` that registers the `insertTemplate` (and optionally `saveAsTemplate`) toolbar tools.
74
110
 
75
- | Option | Type | Description |
76
- | --- | --- | --- |
77
- | `templates` | `TemplateDefinition[]?` | Additional custom templates to include in the gallery. |
78
- | `replaceContent` | `boolean?` | Replace document content on insert (default: `true`). |
111
+ | Option | Type | Default | Description |
112
+ | --- | --- | --- | --- |
113
+ | `templates` | `Template[]` | `[]` | Built-in templates shown in the gallery. |
114
+ | `variables` | `Record<string, string>` | `{}` | Static variable values for `{{key}}` substitution. |
115
+ | `getVariables` | `(tmpl) => Record<string, string>` | — | Dynamic variable resolver called at insert time. |
116
+ | `onInsert` | `(tmpl, html) => void` | — | Called after a template is inserted. |
117
+ | `allowUserTemplates` | `boolean` | `false` | Enable user-defined template save/delete/export/import. |
118
+ | `maxUserTemplates` | `number` | `20` | Maximum number of user-defined templates. |
119
+ | `userTemplateStorageKey` | `string` | `"de-user-templates"` | `localStorage` key for persisting user templates. |
120
+ | `onSaveTemplate` | `(tpl: UserTemplate) => void` | — | Called after a user template is saved. |
121
+ | `onDeleteTemplate` | `(id: string) => void` | — | Called after a user template is deleted. |
79
122
 
80
- ### `TemplateDefinition`
123
+ ### `Template`
81
124
 
82
125
  | Field | Type | Description |
83
126
  | --- | --- | --- |
84
127
  | `id` | `string` | Unique template identifier. |
85
- | `title` | `string` | Display name in the gallery. |
86
- | `html` | `string` | HTML content of the template. |
87
- | `thumbnail` | `string?` | Optional thumbnail image URL or data URL. |
128
+ | `label` | `string` | Display name in the gallery. |
129
+ | `content` | `string` | HTML content. Supports `{{variable}}` placeholders. |
130
+ | `category` | `string?` | Optional category for filter chips. |
131
+ | `description` | `string?` | Short description shown below the preview thumbnail. |
132
+
133
+ ### `UserTemplate`
134
+
135
+ Extends `Template` with:
136
+
137
+ | Field | Type | Description |
138
+ | --- | --- | --- |
139
+ | `isUserDefined` | `true` | Marks this as a user-created template. |
140
+ | `createdAt` | `number` | Unix timestamp (ms) when the template was saved. |
141
+
142
+ ### Utility functions
143
+
144
+ ```ts
145
+ import { applyVariables, extractVariableNames } from "@richhtmleditor/templates";
146
+
147
+ // Replace {{key}} placeholders
148
+ const html = applyVariables(template.content, { firstName: "Alice" });
149
+
150
+ // List all placeholder names in a template
151
+ const names = extractVariableNames(template.content); // ["firstName", "company"]
152
+ ```
88
153
 
89
154
  ## Related packages
90
155
 
@@ -96,4 +161,4 @@ Returns an `EditorPlugin` that registers the `insertTemplate` toolbar tool.
96
161
 
97
162
  ## License
98
163
 
99
- [MIT](./LICENSE)
164
+ [MIT](./LICENSE)
package/dist/index.d.ts CHANGED
@@ -12,6 +12,10 @@ export type Template = {
12
12
  /** Short description shown in the picker */
13
13
  description?: string;
14
14
  };
15
+ export type UserTemplate = Template & {
16
+ isUserDefined: true;
17
+ createdAt: number;
18
+ };
15
19
  export type TemplatesPluginOptions = {
16
20
  /** The templates available for insertion */
17
21
  templates: Template[];
@@ -27,6 +31,16 @@ export type TemplatesPluginOptions = {
27
31
  getVariables?: (template: Template) => Record<string, string> | Promise<Record<string, string>>;
28
32
  /** Called after a template has been inserted. */
29
33
  onInsert?: (template: Template, resolvedHtml: string) => void;
34
+ /** Enable user-defined templates (save current content as template). Default: false */
35
+ allowUserTemplates?: boolean;
36
+ /** Maximum number of user-defined templates. Default: 20 */
37
+ maxUserTemplates?: number;
38
+ /** localStorage key for persisting user templates. Default: "de-user-templates" */
39
+ userTemplateStorageKey?: string;
40
+ /** Called after a user template is saved */
41
+ onSaveTemplate?: (template: UserTemplate) => void;
42
+ /** Called after a user template is deleted */
43
+ onDeleteTemplate?: (templateId: string) => void;
30
44
  };
31
45
  /** Replace `{{key}}` placeholders in html with values from the variables map. */
32
46
  export declare function applyVariables(html: string, variables: Record<string, string>): string;
@@ -35,9 +49,13 @@ export declare function extractVariableNames(html: string): string[];
35
49
  /**
36
50
  * Reusable content templates plugin.
37
51
  *
38
- * Click the toolbar button → modal opens with search, category tabs, template
39
- * cards and an HTML preview pane. Select a card and click **Insert** (or
40
- * double-click the card) to append the template at the current cursor position.
52
+ * Click the toolbar button → modal opens with search, template
53
+ * cards and an HTML preview pane. Select a card and click **Replace Content**
54
+ * (or double-click the card) to replace the editor content with the template.
55
+ *
56
+ * When `allowUserTemplates: true`, users can save the current editor content
57
+ * as a named template (stored in localStorage), delete saved templates, and
58
+ * export/import templates as JSON files.
41
59
  *
42
60
  * Template content supports `{{variable}}` placeholders substituted at insert time.
43
61
  *
@@ -50,7 +68,9 @@ export declare function extractVariableNames(html: string): string[];
50
68
  * description: "Greeting for new users",
51
69
  * content: "<p>Dear {{firstName}},</p><p>Welcome to {{company}}!</p>" }
52
70
  * ],
53
- * variables: { company: "Acme Corp" }
71
+ * variables: { company: "Acme Corp" },
72
+ * allowUserTemplates: true,
73
+ * maxUserTemplates: 20
54
74
  * })]
55
75
  * });
56
76
  * ```
@@ -1 +1 @@
1
- {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAkB,YAAY,EAAE,MAAM,sBAAsB,CAAC;AAEzE,MAAM,MAAM,QAAQ,GAAG;IACrB,EAAE,EAAE,MAAM,CAAC;IACX,KAAK,EAAE,MAAM,CAAC;IACd;;;OAGG;IACH,OAAO,EAAE,MAAM,CAAC;IAChB,sDAAsD;IACtD,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB,4CAA4C;IAC5C,WAAW,CAAC,EAAE,MAAM,CAAC;CACtB,CAAC;AAEF,MAAM,MAAM,sBAAsB,GAAG;IACnC,4CAA4C;IAC5C,SAAS,EAAE,QAAQ,EAAE,CAAC;IACtB;;;OAGG;IACH,SAAS,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;IACnC;;;OAGG;IACH,YAAY,CAAC,EAAE,CAAC,QAAQ,EAAE,QAAQ,KAAK,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,GAAG,OAAO,CAAC,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC,CAAC;IAChG,iDAAiD;IACjD,QAAQ,CAAC,EAAE,CAAC,QAAQ,EAAE,QAAQ,EAAE,YAAY,EAAE,MAAM,KAAK,IAAI,CAAC;CAC/D,CAAC;AAEF,iFAAiF;AACjF,wBAAgB,cAAc,CAAC,IAAI,EAAE,MAAM,EAAE,SAAS,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,GAAG,MAAM,CAEtF;AAED,kFAAkF;AAClF,wBAAgB,oBAAoB,CAAC,IAAI,EAAE,MAAM,GAAG,MAAM,EAAE,CAM3D;AAkMD;;;;;;;;;;;;;;;;;;;;;;GAsBG;AACH,wBAAgB,qBAAqB,CAAC,OAAO,EAAE,sBAAsB,GAAG,YAAY,CAoBnF"}
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAkB,YAAY,EAAE,MAAM,sBAAsB,CAAC;AAEzE,MAAM,MAAM,QAAQ,GAAG;IACrB,EAAE,EAAE,MAAM,CAAC;IACX,KAAK,EAAE,MAAM,CAAC;IACd;;;OAGG;IACH,OAAO,EAAE,MAAM,CAAC;IAChB,sDAAsD;IACtD,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB,4CAA4C;IAC5C,WAAW,CAAC,EAAE,MAAM,CAAC;CACtB,CAAC;AAEF,MAAM,MAAM,YAAY,GAAG,QAAQ,GAAG;IACpC,aAAa,EAAE,IAAI,CAAC;IACpB,SAAS,EAAE,MAAM,CAAC;CACnB,CAAC;AAEF,MAAM,MAAM,sBAAsB,GAAG;IACnC,4CAA4C;IAC5C,SAAS,EAAE,QAAQ,EAAE,CAAC;IACtB;;;OAGG;IACH,SAAS,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;IACnC;;;OAGG;IACH,YAAY,CAAC,EAAE,CAAC,QAAQ,EAAE,QAAQ,KAAK,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,GAAG,OAAO,CAAC,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC,CAAC;IAChG,iDAAiD;IACjD,QAAQ,CAAC,EAAE,CAAC,QAAQ,EAAE,QAAQ,EAAE,YAAY,EAAE,MAAM,KAAK,IAAI,CAAC;IAC9D,uFAAuF;IACvF,kBAAkB,CAAC,EAAE,OAAO,CAAC;IAC7B,4DAA4D;IAC5D,gBAAgB,CAAC,EAAE,MAAM,CAAC;IAC1B,mFAAmF;IACnF,sBAAsB,CAAC,EAAE,MAAM,CAAC;IAChC,4CAA4C;IAC5C,cAAc,CAAC,EAAE,CAAC,QAAQ,EAAE,YAAY,KAAK,IAAI,CAAC;IAClD,8CAA8C;IAC9C,gBAAgB,CAAC,EAAE,CAAC,UAAU,EAAE,MAAM,KAAK,IAAI,CAAC;CACjD,CAAC;AAEF,iFAAiF;AACjF,wBAAgB,cAAc,CAAC,IAAI,EAAE,MAAM,EAAE,SAAS,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,GAAG,MAAM,CAEtF;AAED,kFAAkF;AAClF,wBAAgB,oBAAoB,CAAC,IAAI,EAAE,MAAM,GAAG,MAAM,EAAE,CAM3D;AA8kBD;;;;;;;;;;;;;;;;;;;;;;;;;;;;GA4BG;AACH,wBAAgB,qBAAqB,CAAC,OAAO,EAAE,sBAAsB,GAAG,YAAY,CA6CnF"}
package/dist/index.js CHANGED
@@ -10,6 +10,234 @@ export function extractVariableNames(html) {
10
10
  }
11
11
  return Array.from(found);
12
12
  }
13
+ // ── localStorage helpers ───────────────────────────────────────────────────
14
+ const DEFAULT_STORAGE_KEY = "de-user-templates";
15
+ function loadUserTemplates(storageKey) {
16
+ try {
17
+ const raw = localStorage.getItem(storageKey);
18
+ if (!raw)
19
+ return [];
20
+ const parsed = JSON.parse(raw);
21
+ return Array.isArray(parsed) ? parsed : [];
22
+ }
23
+ catch {
24
+ return [];
25
+ }
26
+ }
27
+ function persistUserTemplates(storageKey, templates) {
28
+ try {
29
+ localStorage.setItem(storageKey, JSON.stringify(templates));
30
+ }
31
+ catch {
32
+ // Storage quota exceeded — silently ignore
33
+ }
34
+ }
35
+ function exportUserTemplates(templates) {
36
+ const json = JSON.stringify(templates, null, 2);
37
+ const blob = new Blob([json], { type: "application/json" });
38
+ const url = URL.createObjectURL(blob);
39
+ const a = document.createElement("a");
40
+ a.href = url;
41
+ a.download = "my-templates.json";
42
+ a.click();
43
+ setTimeout(() => URL.revokeObjectURL(url), 1000);
44
+ }
45
+ function showToast(message, type = "info") {
46
+ const existing = document.querySelector(".de-tpl-toast");
47
+ if (existing)
48
+ existing.remove();
49
+ const colors = {
50
+ success: { bg: "#f0fdf4", border: "#22c55e", text: "#166534", icon: `<svg viewBox="0 0 16 16" fill="none" width="16" height="16"><circle cx="8" cy="8" r="7" stroke="#22c55e" stroke-width="1.3"/><path d="M5 8l2 2 4-4" stroke="#22c55e" stroke-width="1.5" stroke-linecap="round" stroke-linejoin="round"/></svg>` },
51
+ error: { bg: "#fef2f2", border: "#ef4444", text: "#991b1b", icon: `<svg viewBox="0 0 16 16" fill="none" width="16" height="16"><circle cx="8" cy="8" r="7" stroke="#ef4444" stroke-width="1.3"/><path d="M8 5v4M8 11v.5" stroke="#ef4444" stroke-width="1.5" stroke-linecap="round"/></svg>` },
52
+ info: { bg: "#eff6ff", border: "#3b82f6", text: "#1e40af", icon: `<svg viewBox="0 0 16 16" fill="none" width="16" height="16"><circle cx="8" cy="8" r="7" stroke="#3b82f6" stroke-width="1.3"/><path d="M8 7v5M8 5v.5" stroke="#3b82f6" stroke-width="1.5" stroke-linecap="round"/></svg>` },
53
+ };
54
+ const { bg, border, text, icon } = colors[type];
55
+ const toast = document.createElement("div");
56
+ toast.className = "de-tpl-toast";
57
+ toast.style.cssText =
58
+ `position:fixed;bottom:24px;right:24px;z-index:10002;display:flex;align-items:center;gap:10px;` +
59
+ `padding:12px 18px;border-radius:12px;border:1.5px solid ${border};background:${bg};color:${text};` +
60
+ `font-size:.85rem;font-weight:500;box-shadow:0 8px 24px rgba(0,0,0,.12);max-width:340px;animation:de-tpl-slide-in .2s ease;`;
61
+ toast.innerHTML = `${icon}<span>${message.replace(/</g, "&lt;").replace(/>/g, "&gt;")}</span>`;
62
+ if (!document.querySelector("#de-tpl-toast-kf")) {
63
+ const s = document.createElement("style");
64
+ s.id = "de-tpl-toast-kf";
65
+ s.textContent = "@keyframes de-tpl-slide-in{from{opacity:0;transform:translateY(8px)}to{opacity:1;transform:translateY(0)}}";
66
+ document.head.appendChild(s);
67
+ }
68
+ document.body.appendChild(toast);
69
+ setTimeout(() => { toast.style.opacity = "0"; toast.style.transition = "opacity .3s"; setTimeout(() => toast.remove(), 320); }, 2800);
70
+ }
71
+ function importUserTemplatesFromFile(storageKey, max, onImported) {
72
+ const input = document.createElement("input");
73
+ input.type = "file";
74
+ input.accept = ".json,application/json";
75
+ input.onchange = () => {
76
+ const file = input.files?.[0];
77
+ if (!file)
78
+ return;
79
+ const reader = new FileReader();
80
+ reader.onload = () => {
81
+ try {
82
+ const parsed = JSON.parse(reader.result);
83
+ if (!Array.isArray(parsed)) {
84
+ showToast("Invalid file format.", "error");
85
+ return;
86
+ }
87
+ const existing = loadUserTemplates(storageKey);
88
+ const existingIds = new Set(existing.map((t) => t.id));
89
+ const incoming = parsed.filter((t) => t && typeof t.id === "string" && typeof t.label === "string" && typeof t.content === "string");
90
+ const newOnes = incoming.filter((t) => !existingIds.has(t.id));
91
+ const merged = [...existing, ...newOnes].slice(0, max);
92
+ persistUserTemplates(storageKey, merged);
93
+ onImported(merged);
94
+ showToast(`Imported ${newOnes.length} new template${newOnes.length === 1 ? "" : "s"}.`, "success");
95
+ }
96
+ catch {
97
+ showToast("Failed to parse file. Please use a valid JSON template export.", "error");
98
+ }
99
+ };
100
+ reader.readAsText(file);
101
+ };
102
+ input.click();
103
+ }
104
+ // ── Confirm dialog ───────────────────────────────────────────────────────────────────────
105
+ function openConfirmDialog(message, onConfirm) {
106
+ const backdrop = document.createElement("div");
107
+ backdrop.style.cssText =
108
+ "position:fixed;inset:0;background:rgba(15,23,42,.55);z-index:10001;" +
109
+ "display:flex;align-items:center;justify-content:center;padding:20px;";
110
+ const dialog = document.createElement("div");
111
+ dialog.setAttribute("role", "alertdialog");
112
+ dialog.setAttribute("aria-modal", "true");
113
+ dialog.style.cssText =
114
+ "background:#fff;border-radius:16px;width:min(400px,92vw);padding:28px 28px 22px;" +
115
+ "box-shadow:0 24px 64px rgba(0,0,0,.22);display:flex;flex-direction:column;gap:20px;";
116
+ const safeMsg = message.replace(/</g, "&lt;").replace(/>/g, "&gt;");
117
+ dialog.innerHTML =
118
+ `<div style="display:flex;align-items:flex-start;gap:14px;">` +
119
+ `<div style="flex-shrink:0;width:40px;height:40px;border-radius:50%;background:#fef2f2;` +
120
+ `display:flex;align-items:center;justify-content:center;">` +
121
+ `<svg viewBox="0 0 20 20" fill="none" width="20" height="20">` +
122
+ `<path d="M8 4h4M3 6h14M5 6l1 11a1 1 0 001 1h6a1 1 0 001-1l1-11" stroke="#ef4444" stroke-width="1.5" stroke-linecap="round" stroke-linejoin="round"/>` +
123
+ `<path d="M9 10v4M11 10v4" stroke="#ef4444" stroke-width="1.5" stroke-linecap="round"/>` +
124
+ `</svg>` +
125
+ `</div>` +
126
+ `<div>` +
127
+ `<p style="margin:0 0 6px;font-size:1rem;font-weight:700;color:#0f172a;">Delete Template</p>` +
128
+ `<p style="margin:0;font-size:.875rem;color:#64748b;line-height:1.5;">${safeMsg}</p>` +
129
+ `</div>` +
130
+ `</div>` +
131
+ `<div style="display:flex;gap:8px;justify-content:flex-end;">` +
132
+ `<button type="button" class="de-confirm-cancel" style="padding:9px 22px;border:1px solid #e2e8f0;` +
133
+ `background:#fff;border-radius:999px;cursor:pointer;font-size:.875rem;color:#0f172a;font-weight:500;">Cancel</button>` +
134
+ `<button type="button" class="de-confirm-ok" style="padding:9px 22px;background:#ef4444;color:#fff;` +
135
+ `border:none;border-radius:999px;cursor:pointer;font-size:.875rem;font-weight:600;">Delete</button>` +
136
+ `</div>`;
137
+ backdrop.appendChild(dialog);
138
+ document.body.appendChild(backdrop);
139
+ const close = () => backdrop.remove();
140
+ dialog.querySelector(".de-confirm-cancel").addEventListener("click", close);
141
+ dialog.querySelector(".de-confirm-ok").addEventListener("click", () => { close(); onConfirm(); });
142
+ backdrop.addEventListener("click", (e) => { if (e.target === backdrop)
143
+ close(); });
144
+ dialog.addEventListener("keydown", (e) => {
145
+ if (e.key === "Escape")
146
+ close();
147
+ if (e.key === "Enter") {
148
+ dialog.querySelector(".de-confirm-ok").click();
149
+ }
150
+ });
151
+ setTimeout(() => dialog.querySelector(".de-confirm-ok")?.focus(), 50);
152
+ }
153
+ // ── Save-as dialog ─────────────────────────────────────────────────────────
154
+ function openSaveDialog(currentHtml, storageKey, max, options, onSaved) {
155
+ const existing = loadUserTemplates(storageKey);
156
+ if (existing.length >= max) {
157
+ showToast(`Maximum of ${max} templates reached. Delete some before saving new ones.`, "error");
158
+ return;
159
+ }
160
+ const backdrop = document.createElement("div");
161
+ backdrop.style.cssText =
162
+ "position:fixed;inset:0;background:rgba(15,23,42,.55);z-index:10000;" +
163
+ "display:flex;align-items:center;justify-content:center;padding:20px;";
164
+ const dialog = document.createElement("div");
165
+ dialog.setAttribute("role", "dialog");
166
+ dialog.setAttribute("aria-modal", "true");
167
+ dialog.setAttribute("aria-label", "Save template");
168
+ dialog.style.cssText =
169
+ "background:#fff;border-radius:16px;width:min(460px,96vw);padding:28px 28px 24px;" +
170
+ "box-shadow:0 24px 64px rgba(0,0,0,.22);display:flex;flex-direction:column;gap:16px;";
171
+ dialog.innerHTML =
172
+ `<h2 style="margin:0;font-size:1.1rem;font-weight:700;color:#0f172a;">Save as Template</h2>` +
173
+ `<div>` +
174
+ `<label style="display:block;font-size:.82rem;font-weight:600;color:#475569;margin-bottom:6px;">Template Name</label>` +
175
+ `<input type="text" class="de-save-tpl-name" placeholder="My template name"` +
176
+ ` maxlength="80"` +
177
+ ` style="width:100%;box-sizing:border-box;padding:10px 14px;border:1.5px solid #cbd5e1;` +
178
+ `border-radius:10px;font-size:.875rem;outline:none;color:#0f172a;transition:border-color .15s;" />` +
179
+ `</div>` +
180
+ `<div>` +
181
+ `<label style="display:block;font-size:.82rem;font-weight:600;color:#475569;margin-bottom:6px;">Category <span style="font-weight:400;color:#94a3b8;">(optional)</span></label>` +
182
+ `<input type="text" class="de-save-tpl-category" placeholder="e.g. Email, Report"` +
183
+ ` maxlength="40"` +
184
+ ` style="width:100%;box-sizing:border-box;padding:10px 14px;border:1.5px solid #cbd5e1;` +
185
+ `border-radius:10px;font-size:.875rem;outline:none;color:#0f172a;transition:border-color .15s;" />` +
186
+ `</div>` +
187
+ `<p style="margin:0;font-size:.78rem;color:#94a3b8;">${existing.length} / ${max} templates used</p>` +
188
+ `<div style="display:flex;gap:8px;justify-content:flex-end;margin-top:4px;">` +
189
+ `<button type="button" class="de-save-tpl-cancel"` +
190
+ ` style="padding:9px 22px;border:1px solid #e2e8f0;background:#fff;border-radius:999px;` +
191
+ `cursor:pointer;font-size:.875rem;color:#0f172a;font-weight:500;">Cancel</button>` +
192
+ `<button type="button" class="de-save-tpl-confirm"` +
193
+ ` style="padding:9px 22px;background:#2563eb;color:#fff;border:none;border-radius:999px;` +
194
+ `cursor:pointer;font-size:.875rem;font-weight:600;">Save Template</button>` +
195
+ `</div>`;
196
+ backdrop.appendChild(dialog);
197
+ document.body.appendChild(backdrop);
198
+ const nameInput = dialog.querySelector(".de-save-tpl-name");
199
+ const catInput = dialog.querySelector(".de-save-tpl-category");
200
+ const cancelBtn = dialog.querySelector(".de-save-tpl-cancel");
201
+ const confirmBtn = dialog.querySelector(".de-save-tpl-confirm");
202
+ const close = () => backdrop.remove();
203
+ confirmBtn.addEventListener("click", () => {
204
+ const name = nameInput.value.trim();
205
+ if (!name) {
206
+ nameInput.focus();
207
+ nameInput.style.borderColor = "#ef4444";
208
+ return;
209
+ }
210
+ const fresh = loadUserTemplates(storageKey);
211
+ if (fresh.length >= max) {
212
+ close();
213
+ showToast(`Maximum of ${max} templates reached.`, "error");
214
+ return;
215
+ }
216
+ const tpl = {
217
+ id: `user-${Date.now()}-${Math.random().toString(36).slice(2, 7)}`,
218
+ label: name,
219
+ content: currentHtml,
220
+ category: catInput.value.trim() || "My Templates",
221
+ isUserDefined: true,
222
+ createdAt: Date.now(),
223
+ };
224
+ persistUserTemplates(storageKey, [...fresh, tpl]);
225
+ options.onSaveTemplate?.(tpl);
226
+ onSaved(tpl);
227
+ close();
228
+ });
229
+ cancelBtn.addEventListener("click", close);
230
+ backdrop.addEventListener("click", (e) => { if (e.target === backdrop)
231
+ close(); });
232
+ dialog.addEventListener("keydown", (e) => {
233
+ if (e.key === "Escape")
234
+ close();
235
+ if (e.key === "Enter")
236
+ confirmBtn.click();
237
+ });
238
+ setTimeout(() => nameInput.focus(), 50);
239
+ }
240
+ // ── Preview scale constant ─────────────────────────────────────────────────
13
241
  const PREVIEW_SCALE = 0.33;
14
242
  function buildCardPreview(content) {
15
243
  const box = document.createElement("div");
@@ -27,12 +255,20 @@ function buildCardPreview(content) {
27
255
  box.appendChild(inner);
28
256
  return box;
29
257
  }
30
- function openTemplateModal(options, onInsert) {
31
- const templates = options.templates;
32
- if (!templates.length)
258
+ // ── Main modal ────────────────────────────────────────────────────────────
259
+ function openTemplateModal(options, editorHtmlGetter, onInsert) {
260
+ const storageKey = options.userTemplateStorageKey ?? DEFAULT_STORAGE_KEY;
261
+ const maxUser = options.maxUserTemplates ?? 20;
262
+ const allowUser = options.allowUserTemplates ?? false;
263
+ const builtinTemplates = options.templates;
264
+ let userTemplates = allowUser ? loadUserTemplates(storageKey) : [];
265
+ const allTemplates = () => [...builtinTemplates, ...userTemplates];
266
+ if (!builtinTemplates.length && !userTemplates.length)
33
267
  return;
34
268
  let selected = null;
35
- // ── Inject card hover CSS once ───────────────────────────────────
269
+ let activeTab = "all";
270
+ let activeCategory = "All";
271
+ // ── Inject hover CSS once ─────────────────────────────────────────
36
272
  const styleId = "de-tpl-modal-styles";
37
273
  if (!document.getElementById(styleId)) {
38
274
  const s = document.createElement("style");
@@ -40,7 +276,15 @@ function openTemplateModal(options, onInsert) {
40
276
  s.textContent =
41
277
  `.de-tpl-card:hover{border-color:#93c5fd!important;box-shadow:0 0 0 3px rgba(37,99,235,.08)!important;}` +
42
278
  `.de-tpl-card--active{border-color:#2563eb!important;box-shadow:0 0 0 4px rgba(37,99,235,.12)!important;}` +
43
- `.de-tpl-modal__search:focus{border-color:#2563eb!important;box-shadow:0 0 0 3px rgba(37,99,235,.15)!important;}`;
279
+ `.de-tpl-modal__search:focus{border-color:#2563eb!important;box-shadow:0 0 0 3px rgba(37,99,235,.15)!important;}` +
280
+ `.de-tpl-tab{cursor:pointer;padding:7px 16px;border-radius:999px;font-size:.82rem;font-weight:600;` +
281
+ `border:none;background:transparent;color:#64748b;transition:background .15s,color .15s;}` +
282
+ `.de-tpl-tab:hover{background:#f1f5f9;color:#0f172a;}` +
283
+ `.de-tpl-tab--active{background:#2563eb!important;color:#fff!important;}` +
284
+ `.de-tpl-del-btn{position:absolute;top:8px;right:8px;width:22px;height:22px;border-radius:50%;` +
285
+ `background:rgba(239,68,68,.1);border:none;cursor:pointer;font-size:12px;color:#ef4444;` +
286
+ `display:flex;align-items:center;justify-content:center;opacity:0;transition:opacity .15s;}` +
287
+ `.de-tpl-card:hover .de-tpl-del-btn{opacity:1;}`;
44
288
  document.head.appendChild(s);
45
289
  }
46
290
  // ── Backdrop ─────────────────────────────────────────────────────
@@ -59,18 +303,24 @@ function openTemplateModal(options, onInsert) {
59
303
  // ── Header ────────────────────────────────────────────────────────
60
304
  const headerEl = document.createElement("div");
61
305
  headerEl.style.cssText =
62
- "padding:20px 22px 16px;background:#fff;border-bottom:1px solid #e2e8f0;flex-shrink:0;";
306
+ "padding:20px 22px 14px;background:#fff;border-bottom:1px solid #e2e8f0;flex-shrink:0;";
307
+ const tabsHtml = allowUser
308
+ ? `<div style="display:flex;align-items:center;gap:4px;margin-bottom:10px;">` +
309
+ `<button type="button" class="de-tpl-tab de-tpl-tab--active" data-tab="all">All</button>` +
310
+ `<button type="button" class="de-tpl-tab" data-tab="mine">My Templates (<span class="de-tpl-mine-count">${userTemplates.length}</span>/${maxUser})</button>` +
311
+ `</div>`
312
+ : "";
63
313
  headerEl.innerHTML =
64
- `<p style="margin:0 0 12px;font-size:.82rem;color:#64748b;line-height:1.5;">` +
65
- `Preview reusable layouts, search by name, and replace the current editor content with a selected template.</p>` +
314
+ tabsHtml +
66
315
  `<div style="display:flex;align-items:center;gap:10px;">` +
67
316
  `<input type="text" class="de-tpl-modal__search" placeholder="Search templates"` +
68
317
  ` style="flex:1;padding:10px 16px;border:1.5px solid #cbd5e1;border-radius:999px;` +
69
318
  `font-size:.875rem;outline:none;background:#fff;color:#0f172a;transition:border-color .15s,box-shadow .15s;" />` +
70
319
  `<span class="de-tpl-count" style="flex-shrink:0;padding:8px 14px;border:1px solid #e2e8f0;` +
71
320
  `border-radius:999px;font-size:.82rem;color:#64748b;background:#fff;white-space:nowrap;">` +
72
- `${templates.length} template${templates.length === 1 ? "" : "s"}</span>` +
73
- `</div>`;
321
+ `${allTemplates().length} template${allTemplates().length === 1 ? "" : "s"}</span>` +
322
+ `</div>` +
323
+ `<div class="de-tpl-chips" style="display:flex;flex-wrap:wrap;gap:6px;margin-top:10px;"></div>`;
74
324
  // ── Grid ──────────────────────────────────────────────────────────
75
325
  const gridEl = document.createElement("div");
76
326
  gridEl.className = "de-tpl-modal__grid";
@@ -80,16 +330,30 @@ function openTemplateModal(options, onInsert) {
80
330
  const footerEl = document.createElement("div");
81
331
  footerEl.style.cssText =
82
332
  "display:flex;align-items:center;justify-content:space-between;" +
83
- "padding:16px 22px;background:#fff;border-top:1px solid #e2e8f0;flex-shrink:0;";
333
+ "padding:16px 22px;background:#fff;border-top:1px solid #e2e8f0;flex-shrink:0;flex-wrap:wrap;gap:8px;";
334
+ const leftFooterHtml = allowUser
335
+ ? `<div style="display:flex;gap:6px;align-items:center;">` +
336
+ `<button type="button" class="de-tpl-export-btn"` +
337
+ ` style="padding:7px 14px;border:1px solid #e2e8f0;background:#fff;border-radius:999px;` +
338
+ `cursor:pointer;font-size:.78rem;color:#475569;font-weight:500;" title="Export user templates as JSON">Export JSON</button>` +
339
+ `<button type="button" class="de-tpl-import-btn"` +
340
+ ` style="padding:7px 14px;border:1px solid #e2e8f0;background:#fff;border-radius:999px;` +
341
+ `cursor:pointer;font-size:.78rem;color:#475569;font-weight:500;" title="Import user templates from JSON file">Import JSON</button>` +
342
+ `</div>`
343
+ : `<span class="de-tpl-status" style="font-size:.82rem;color:#64748b;">Select a template to replace the current content.</span>`;
84
344
  footerEl.innerHTML =
85
- `<span class="de-tpl-status" style="font-size:.82rem;color:#64748b;">Select a template to replace the current content.</span>` +
86
- `<div style="display:flex;gap:8px;">` +
345
+ leftFooterHtml +
346
+ `<div style="display:flex;gap:8px;align-items:center;">` +
347
+ (allowUser ? `<span class="de-tpl-status" style="font-size:.82rem;color:#64748b;"></span>` : "") +
87
348
  `<button type="button" class="de-tpl-modal__cancel"` +
88
349
  ` style="padding:9px 22px;border:1px solid #e2e8f0;background:#fff;border-radius:999px;` +
89
350
  `cursor:pointer;font-size:.875rem;color:#0f172a;font-weight:500;">Cancel</button>` +
351
+ `<button type="button" class="de-tpl-modal__append" disabled` +
352
+ ` style="padding:9px 22px;background:#fff;color:#2563eb;border:1.5px solid #2563eb;border-radius:999px;` +
353
+ `cursor:pointer;font-size:.875rem;font-weight:600;opacity:.4;transition:opacity .15s;">Append</button>` +
90
354
  `<button type="button" class="de-tpl-modal__insert" disabled` +
91
355
  ` style="padding:9px 22px;background:#2563eb;color:#fff;border:none;border-radius:999px;` +
92
- `cursor:pointer;font-size:.875rem;font-weight:600;opacity:.4;transition:opacity .15s;">Replace Content</button>` +
356
+ `cursor:pointer;font-size:.875rem;font-weight:600;opacity:.4;transition:opacity .15s;">Replace</button>` +
93
357
  `</div>`;
94
358
  panel.appendChild(headerEl);
95
359
  panel.appendChild(gridEl);
@@ -99,41 +363,117 @@ function openTemplateModal(options, onInsert) {
99
363
  const searchEl = headerEl.querySelector(".de-tpl-modal__search");
100
364
  const countEl = headerEl.querySelector(".de-tpl-count");
101
365
  const insertBtn = footerEl.querySelector(".de-tpl-modal__insert");
366
+ const appendBtn = footerEl.querySelector(".de-tpl-modal__append");
102
367
  const cancelBtn = footerEl.querySelector(".de-tpl-modal__cancel");
103
368
  const statusEl = footerEl.querySelector(".de-tpl-status");
369
+ const mineCountEl = headerEl.querySelector(".de-tpl-mine-count");
370
+ const exportBtn = footerEl.querySelector(".de-tpl-export-btn");
371
+ const importBtn = footerEl.querySelector(".de-tpl-import-btn");
104
372
  const close = () => backdrop.remove();
105
373
  // ── Render grid ───────────────────────────────────────────────────
374
+ const renderChips = (source) => {
375
+ const chipsEl = headerEl.querySelector(".de-tpl-chips");
376
+ if (!chipsEl)
377
+ return;
378
+ if (activeTab === "mine") {
379
+ chipsEl.innerHTML = "";
380
+ return;
381
+ }
382
+ const cats = ["All", ...Array.from(new Set(source.map((t) => t.category ?? "General").filter(Boolean))).sort()];
383
+ if (cats.length <= 2) {
384
+ chipsEl.innerHTML = "";
385
+ return;
386
+ }
387
+ chipsEl.replaceChildren();
388
+ for (const cat of cats) {
389
+ const btn = document.createElement("button");
390
+ btn.type = "button";
391
+ btn.dataset.cat = cat;
392
+ btn.textContent = cat;
393
+ const isActive = activeCategory === cat;
394
+ btn.style.cssText = "padding:4px 12px;border-radius:999px;font-size:.76rem;font-weight:600;cursor:pointer;transition:background .12s,color .12s;" +
395
+ (isActive ? "background:#2563eb;color:#fff;border:1.5px solid #2563eb;" : "background:#fff;color:#64748b;border:1.5px solid #e2e8f0;");
396
+ btn.addEventListener("click", () => { activeCategory = cat; renderGrid(searchEl.value); });
397
+ chipsEl.appendChild(btn);
398
+ }
399
+ };
106
400
  const renderGrid = (query) => {
107
401
  const q = query.toLowerCase().trim();
108
- const visible = q
109
- ? templates.filter((t) => t.label.toLowerCase().includes(q) ||
402
+ const source = activeTab === "mine" ? userTemplates : allTemplates();
403
+ renderChips(source);
404
+ let visible = q
405
+ ? source.filter((t) => t.label.toLowerCase().includes(q) ||
110
406
  (t.description ?? "").toLowerCase().includes(q) ||
111
407
  (t.category ?? "").toLowerCase().includes(q))
112
- : templates;
408
+ : source;
409
+ if (activeCategory !== "All" && activeTab !== "mine") {
410
+ visible = visible.filter((t) => (t.category ?? "General") === activeCategory);
411
+ }
113
412
  countEl.textContent = `${visible.length} template${visible.length === 1 ? "" : "s"}`;
114
413
  gridEl.replaceChildren();
115
414
  if (!visible.length) {
116
415
  const empty = document.createElement("p");
117
416
  empty.style.cssText = "grid-column:1/-1;text-align:center;padding:48px;color:#94a3b8;font-size:.9rem;";
118
- empty.textContent = "No templates found";
417
+ empty.textContent = activeTab === "mine"
418
+ ? 'No saved templates yet. Use "Save as Template" to save your current content.'
419
+ : "No templates found";
119
420
  gridEl.appendChild(empty);
120
421
  return;
121
422
  }
122
423
  for (const tmpl of visible) {
424
+ const isUser = tmpl.isUserDefined === true;
123
425
  const card = document.createElement("div");
124
426
  card.className = "de-tpl-card" + (selected?.id === tmpl.id ? " de-tpl-card--active" : "");
125
427
  card.dataset.id = tmpl.id;
126
428
  card.style.cssText =
127
429
  "background:#fff;border-radius:14px;border:2px solid #e2e8f0;" +
128
- "cursor:pointer;padding:14px;transition:border-color .15s,box-shadow .15s;";
430
+ "cursor:pointer;padding:14px;transition:border-color .15s,box-shadow .15s;position:relative;";
129
431
  // HTML preview thumbnail
130
432
  card.appendChild(buildCardPreview(tmpl.content));
131
- // Title
433
+ // Delete button for user templates
434
+ if (isUser && allowUser) {
435
+ const delBtn = document.createElement("button");
436
+ delBtn.type = "button";
437
+ delBtn.className = "de-tpl-del-btn";
438
+ delBtn.title = "Delete template";
439
+ delBtn.textContent = "✕";
440
+ delBtn.addEventListener("click", (e) => {
441
+ e.stopPropagation();
442
+ openConfirmDialog(`Are you sure you want to delete "${tmpl.label}"? This cannot be undone.`, () => {
443
+ userTemplates = userTemplates.filter((t) => t.id !== tmpl.id);
444
+ persistUserTemplates(storageKey, userTemplates);
445
+ options.onDeleteTemplate?.(tmpl.id);
446
+ if (mineCountEl)
447
+ mineCountEl.textContent = String(userTemplates.length);
448
+ if (selected?.id === tmpl.id) {
449
+ selected = null;
450
+ insertBtn.disabled = true;
451
+ insertBtn.style.opacity = ".4";
452
+ if (statusEl)
453
+ statusEl.textContent = "";
454
+ }
455
+ renderGrid(searchEl.value);
456
+ });
457
+ });
458
+ card.appendChild(delBtn);
459
+ }
460
+ // Title row
461
+ const titleRow = document.createElement("div");
462
+ titleRow.style.cssText = "display:flex;align-items:center;gap:6px;margin-bottom:5px;";
132
463
  const titleEl = document.createElement("p");
133
- titleEl.style.cssText = "margin:0 0 5px;font-size:.95rem;font-weight:700;color:#0f172a;";
464
+ titleEl.style.cssText = "margin:0;font-size:.95rem;font-weight:700;color:#0f172a;flex:1;min-width:0;overflow:hidden;text-overflow:ellipsis;white-space:nowrap;";
134
465
  titleEl.textContent = tmpl.label;
135
- card.appendChild(titleEl);
136
- // Description (plain text fallback from content)
466
+ titleRow.appendChild(titleEl);
467
+ if (isUser) {
468
+ const badge = document.createElement("span");
469
+ badge.style.cssText =
470
+ "flex-shrink:0;font-size:.68rem;font-weight:700;padding:2px 7px;border-radius:999px;" +
471
+ "background:#eff6ff;color:#2563eb;border:1px solid #bfdbfe;";
472
+ badge.textContent = "Mine";
473
+ titleRow.appendChild(badge);
474
+ }
475
+ card.appendChild(titleRow);
476
+ // Description
137
477
  const descEl = document.createElement("p");
138
478
  descEl.style.cssText =
139
479
  "margin:0;font-size:.78rem;color:#64748b;line-height:1.45;" +
@@ -146,7 +486,12 @@ function openTemplateModal(options, onInsert) {
146
486
  selected = tmpl;
147
487
  insertBtn.disabled = false;
148
488
  insertBtn.style.opacity = "1";
149
- statusEl.textContent = `"${tmpl.label}" selected.`;
489
+ if (appendBtn) {
490
+ appendBtn.disabled = false;
491
+ appendBtn.style.opacity = "1";
492
+ }
493
+ if (statusEl)
494
+ statusEl.textContent = `"${tmpl.label}" selected.`;
150
495
  gridEl.querySelectorAll(".de-tpl-card").forEach((c) => {
151
496
  c.classList.toggle("de-tpl-card--active", c.dataset.id === tmpl.id);
152
497
  });
@@ -155,7 +500,7 @@ function openTemplateModal(options, onInsert) {
155
500
  gridEl.appendChild(card);
156
501
  }
157
502
  };
158
- const doInsert = async () => {
503
+ const doInsert = async (append = false) => {
159
504
  if (!selected)
160
505
  return;
161
506
  const staticVars = options.variables ?? {};
@@ -163,9 +508,43 @@ function openTemplateModal(options, onInsert) {
163
508
  ? await Promise.resolve(options.getVariables(selected))
164
509
  : {};
165
510
  const resolved = applyVariables(selected.content, { ...staticVars, ...dynamicVars });
166
- onInsert(resolved, selected);
511
+ if (append) {
512
+ const current = editorHtmlGetter();
513
+ onInsert(current + resolved, selected);
514
+ }
515
+ else {
516
+ onInsert(resolved, selected);
517
+ }
167
518
  close();
168
519
  };
520
+ // ── Tab switching ──────────────────────────────────────────────────
521
+ headerEl.addEventListener("click", (e) => {
522
+ const btn = e.target.closest("[data-tab]");
523
+ if (!btn)
524
+ return;
525
+ activeTab = btn.dataset.tab;
526
+ activeCategory = "All";
527
+ headerEl.querySelectorAll(".de-tpl-tab").forEach((b) => {
528
+ b.classList.toggle("de-tpl-tab--active", b.dataset.tab === activeTab);
529
+ });
530
+ renderGrid(searchEl.value);
531
+ });
532
+ // ── Export / Import ───────────────────────────────────────────────
533
+ exportBtn?.addEventListener("click", () => {
534
+ if (!userTemplates.length) {
535
+ showToast("No user templates to export yet.", "info");
536
+ return;
537
+ }
538
+ exportUserTemplates(userTemplates);
539
+ });
540
+ importBtn?.addEventListener("click", () => {
541
+ importUserTemplatesFromFile(storageKey, maxUser, (merged) => {
542
+ userTemplates = merged;
543
+ if (mineCountEl)
544
+ mineCountEl.textContent = String(userTemplates.length);
545
+ renderGrid(searchEl.value);
546
+ });
547
+ });
169
548
  // ── Wire events ───────────────────────────────────────────────────
170
549
  cancelBtn.addEventListener("click", close);
171
550
  backdrop.addEventListener("click", (e) => { if (e.target === backdrop)
@@ -173,6 +552,7 @@ function openTemplateModal(options, onInsert) {
173
552
  panel.addEventListener("keydown", (e) => { if (e.key === "Escape")
174
553
  close(); });
175
554
  insertBtn.addEventListener("click", () => void doInsert());
555
+ appendBtn?.addEventListener("click", () => void doInsert(true));
176
556
  searchEl.addEventListener("input", () => renderGrid(searchEl.value));
177
557
  renderGrid("");
178
558
  setTimeout(() => searchEl.focus(), 50);
@@ -180,9 +560,13 @@ function openTemplateModal(options, onInsert) {
180
560
  /**
181
561
  * Reusable content templates plugin.
182
562
  *
183
- * Click the toolbar button → modal opens with search, category tabs, template
184
- * cards and an HTML preview pane. Select a card and click **Insert** (or
185
- * double-click the card) to append the template at the current cursor position.
563
+ * Click the toolbar button → modal opens with search, template
564
+ * cards and an HTML preview pane. Select a card and click **Replace Content**
565
+ * (or double-click the card) to replace the editor content with the template.
566
+ *
567
+ * When `allowUserTemplates: true`, users can save the current editor content
568
+ * as a named template (stored in localStorage), delete saved templates, and
569
+ * export/import templates as JSON files.
186
570
  *
187
571
  * Template content supports `{{variable}}` placeholders substituted at insert time.
188
572
  *
@@ -195,30 +579,53 @@ function openTemplateModal(options, onInsert) {
195
579
  * description: "Greeting for new users",
196
580
  * content: "<p>Dear {{firstName}},</p><p>Welcome to {{company}}!</p>" }
197
581
  * ],
198
- * variables: { company: "Acme Corp" }
582
+ * variables: { company: "Acme Corp" },
583
+ * allowUserTemplates: true,
584
+ * maxUserTemplates: 20
199
585
  * })]
200
586
  * });
201
587
  * ```
202
588
  */
203
589
  export function createTemplatesPlugin(options) {
204
- return {
205
- id: "richhtmleditor-templates",
206
- tools: [
207
- {
208
- id: "insertTemplate",
209
- type: "button",
210
- label: "Templates",
211
- icon: "template",
212
- display: "icon",
213
- tooltip: "Insert content template",
214
- onClick: (editor) => {
215
- openTemplateModal(options, (resolvedHtml, tmpl) => {
216
- editor.setContent(resolvedHtml);
217
- options.onInsert?.(tmpl, resolvedHtml);
218
- });
590
+ const storageKey = options.userTemplateStorageKey ?? DEFAULT_STORAGE_KEY;
591
+ const maxUser = options.maxUserTemplates ?? 20;
592
+ const allowUser = options.allowUserTemplates ?? false;
593
+ const tools = [
594
+ {
595
+ id: "insertTemplate",
596
+ type: "button",
597
+ label: "Templates",
598
+ icon: "template",
599
+ display: "icon",
600
+ tooltip: "Insert content template",
601
+ onClick: (editor) => {
602
+ openTemplateModal(options, () => editor.getHTML(), (resolvedHtml, tmpl) => {
603
+ editor.setContent(resolvedHtml);
604
+ options.onInsert?.(tmpl, resolvedHtml);
605
+ });
606
+ }
607
+ }
608
+ ];
609
+ if (allowUser) {
610
+ tools.push({
611
+ id: "saveAsTemplate",
612
+ type: "button",
613
+ label: "Save as Template",
614
+ icon: "save-template",
615
+ display: "icon",
616
+ tooltip: "Save current content as a reusable template",
617
+ onClick: (editor) => {
618
+ const html = editor.getHTML();
619
+ if (!html.trim()) {
620
+ showToast("The editor is empty. Add some content first.", "info");
621
+ return;
219
622
  }
623
+ openSaveDialog(html, storageKey, maxUser, options, () => {
624
+ // Optionally notify user
625
+ });
220
626
  }
221
- ]
222
- };
627
+ });
628
+ }
629
+ return { id: "richhtmleditor-templates", tools };
223
630
  }
224
631
  //# sourceMappingURL=index.js.map
package/dist/index.js.map CHANGED
@@ -1 +1 @@
1
- {"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"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"}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@richhtmleditor/templates",
3
- "version": "1.2.8",
3
+ "version": "1.2.9",
4
4
  "description": "Reusable content blocks and template variables plugin for Rich HTML Editor.",
5
5
  "type": "module",
6
6
  "main": "./dist/index.js",