@singleton-sd/post-kit-editor 0.3.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (102) hide show
  1. package/LICENSE +21 -0
  2. package/README.md +105 -0
  3. package/dist/canvas/EditorBlock.d.ts +6 -0
  4. package/dist/canvas/EditorBlock.js +25 -0
  5. package/dist/canvas/EditorBlock.js.map +1 -0
  6. package/dist/canvas/EmailBuilderCanvas.d.ts +7 -0
  7. package/dist/canvas/EmailBuilderCanvas.js +15 -0
  8. package/dist/canvas/EmailBuilderCanvas.js.map +1 -0
  9. package/dist/canvas/blocks/ColumnsContainerEditor.d.ts +2 -0
  10. package/dist/canvas/blocks/ColumnsContainerEditor.js +47 -0
  11. package/dist/canvas/blocks/ColumnsContainerEditor.js.map +1 -0
  12. package/dist/canvas/blocks/ColumnsContainerPropsSchema.d.ts +183 -0
  13. package/dist/canvas/blocks/ColumnsContainerPropsSchema.js +19 -0
  14. package/dist/canvas/blocks/ColumnsContainerPropsSchema.js.map +1 -0
  15. package/dist/canvas/blocks/ContainerEditor.d.ts +2 -0
  16. package/dist/canvas/blocks/ContainerEditor.js +39 -0
  17. package/dist/canvas/blocks/ContainerEditor.js.map +1 -0
  18. package/dist/canvas/blocks/ContainerPropsSchema.d.ts +83 -0
  19. package/dist/canvas/blocks/ContainerPropsSchema.js +16 -0
  20. package/dist/canvas/blocks/ContainerPropsSchema.js.map +1 -0
  21. package/dist/canvas/blocks/EmailLayoutEditor.d.ts +2 -0
  22. package/dist/canvas/blocks/EmailLayoutEditor.js +80 -0
  23. package/dist/canvas/blocks/EmailLayoutEditor.js.map +1 -0
  24. package/dist/canvas/blocks/EmailLayoutPropsSchema.d.ts +28 -0
  25. package/dist/canvas/blocks/EmailLayoutPropsSchema.js +33 -0
  26. package/dist/canvas/blocks/EmailLayoutPropsSchema.js.map +1 -0
  27. package/dist/canvas/editor-context.d.ts +22 -0
  28. package/dist/canvas/editor-context.js +55 -0
  29. package/dist/canvas/editor-context.js.map +1 -0
  30. package/dist/canvas/editor-core.d.ts +2910 -0
  31. package/dist/canvas/editor-core.js +87 -0
  32. package/dist/canvas/editor-core.js.map +1 -0
  33. package/dist/canvas/helpers/AddBlockMenu.d.ts +7 -0
  34. package/dist/canvas/helpers/AddBlockMenu.js +23 -0
  35. package/dist/canvas/helpers/AddBlockMenu.js.map +1 -0
  36. package/dist/canvas/helpers/EditorBlockWrapper.d.ts +5 -0
  37. package/dist/canvas/helpers/EditorBlockWrapper.js +36 -0
  38. package/dist/canvas/helpers/EditorBlockWrapper.js.map +1 -0
  39. package/dist/canvas/helpers/EditorChildrenIds.d.ts +11 -0
  40. package/dist/canvas/helpers/EditorChildrenIds.js +38 -0
  41. package/dist/canvas/helpers/EditorChildrenIds.js.map +1 -0
  42. package/dist/canvas/helpers/block-templates.d.ts +7 -0
  43. package/dist/canvas/helpers/block-templates.js +87 -0
  44. package/dist/canvas/helpers/block-templates.js.map +1 -0
  45. package/dist/email-template-editor.d.ts +11 -0
  46. package/dist/email-template-editor.js +32 -0
  47. package/dist/email-template-editor.js.map +1 -0
  48. package/dist/index.d.ts +4 -0
  49. package/dist/index.js +13 -0
  50. package/dist/index.js.map +1 -0
  51. package/dist/insertion-target.d.ts +18 -0
  52. package/dist/insertion-target.js +41 -0
  53. package/dist/insertion-target.js.map +1 -0
  54. package/dist/metadata/MetadataPanel.d.ts +7 -0
  55. package/dist/metadata/MetadataPanel.js +56 -0
  56. package/dist/metadata/MetadataPanel.js.map +1 -0
  57. package/dist/metadata/insert-at-cursor.d.ts +5 -0
  58. package/dist/metadata/insert-at-cursor.js +22 -0
  59. package/dist/metadata/insert-at-cursor.js.map +1 -0
  60. package/dist/metadata/subject-preview.d.ts +2 -0
  61. package/dist/metadata/subject-preview.js +12 -0
  62. package/dist/metadata/subject-preview.js.map +1 -0
  63. package/dist/metadata/template-key.d.ts +4 -0
  64. package/dist/metadata/template-key.js +21 -0
  65. package/dist/metadata/template-key.js.map +1 -0
  66. package/dist/preview/PreviewDataEditor.d.ts +7 -0
  67. package/dist/preview/PreviewDataEditor.js +37 -0
  68. package/dist/preview/PreviewDataEditor.js.map +1 -0
  69. package/dist/preview/PreviewPane.d.ts +7 -0
  70. package/dist/preview/PreviewPane.js +39 -0
  71. package/dist/preview/PreviewPane.js.map +1 -0
  72. package/dist/preview/preview-frame.d.ts +8 -0
  73. package/dist/preview/preview-frame.js +41 -0
  74. package/dist/preview/preview-frame.js.map +1 -0
  75. package/dist/preview/preview-rows.d.ts +10 -0
  76. package/dist/preview/preview-rows.js +54 -0
  77. package/dist/preview/preview-rows.js.map +1 -0
  78. package/dist/preview/render-template-preview.d.ts +10 -0
  79. package/dist/preview/render-template-preview.js +27 -0
  80. package/dist/preview/render-template-preview.js.map +1 -0
  81. package/dist/serialization.d.ts +15 -0
  82. package/dist/serialization.js +128 -0
  83. package/dist/serialization.js.map +1 -0
  84. package/dist/types.d.ts +14 -0
  85. package/dist/types.js +3 -0
  86. package/dist/types.js.map +1 -0
  87. package/dist/variables/VariableCatalogue.d.ts +7 -0
  88. package/dist/variables/VariableCatalogue.js +77 -0
  89. package/dist/variables/VariableCatalogue.js.map +1 -0
  90. package/dist/variables/clipboard.d.ts +3 -0
  91. package/dist/variables/clipboard.js +16 -0
  92. package/dist/variables/clipboard.js.map +1 -0
  93. package/dist/variables/copy-feedback.d.ts +7 -0
  94. package/dist/variables/copy-feedback.js +14 -0
  95. package/dist/variables/copy-feedback.js.map +1 -0
  96. package/dist/variables/resolve-catalogue.d.ts +2 -0
  97. package/dist/variables/resolve-catalogue.js +10 -0
  98. package/dist/variables/resolve-catalogue.js.map +1 -0
  99. package/dist/working-files.d.ts +6 -0
  100. package/dist/working-files.js +25 -0
  101. package/dist/working-files.js.map +1 -0
  102. package/package.json +60 -0
@@ -0,0 +1,4 @@
1
+ export declare const TEMPLATE_KEY_CHARSET_MESSAGE = "Template key may only contain letters, numbers, dots, underscores, and hyphens.";
2
+ export declare const TEMPLATE_KEY_RESERVED_MESSAGE = "Template key cannot be \".\" or \"..\".";
3
+ export declare function templateKeyInputError(value: string): string | null;
4
+ export declare function isAcceptableTemplateKeyInput(value: string): boolean;
@@ -0,0 +1,21 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.TEMPLATE_KEY_RESERVED_MESSAGE = exports.TEMPLATE_KEY_CHARSET_MESSAGE = void 0;
4
+ exports.templateKeyInputError = templateKeyInputError;
5
+ exports.isAcceptableTemplateKeyInput = isAcceptableTemplateKeyInput;
6
+ const SAFE_TEMPLATE_KEY_CHARS = /^[a-zA-Z0-9._-]*$/;
7
+ exports.TEMPLATE_KEY_CHARSET_MESSAGE = 'Template key may only contain letters, numbers, dots, underscores, and hyphens.';
8
+ exports.TEMPLATE_KEY_RESERVED_MESSAGE = 'Template key cannot be "." or "..".';
9
+ function templateKeyInputError(value) {
10
+ if (value === '.' || value === '..') {
11
+ return exports.TEMPLATE_KEY_RESERVED_MESSAGE;
12
+ }
13
+ if (!SAFE_TEMPLATE_KEY_CHARS.test(value)) {
14
+ return exports.TEMPLATE_KEY_CHARSET_MESSAGE;
15
+ }
16
+ return null;
17
+ }
18
+ function isAcceptableTemplateKeyInput(value) {
19
+ return templateKeyInputError(value) === null;
20
+ }
21
+ //# sourceMappingURL=template-key.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"template-key.js","sourceRoot":"","sources":["../../src/metadata/template-key.ts"],"names":[],"mappings":";;;AAoBA,sDAQC;AAMD,oEAEC;AA9BD,MAAM,uBAAuB,GAAG,mBAAmB,CAAC;AAEvC,QAAA,4BAA4B,GACvC,iFAAiF,CAAC;AAEvE,QAAA,6BAA6B,GAAG,qCAAqC,CAAC;AASnF,SAAgB,qBAAqB,CAAC,KAAa;IACjD,IAAI,KAAK,KAAK,GAAG,IAAI,KAAK,KAAK,IAAI,EAAE,CAAC;QACpC,OAAO,qCAA6B,CAAC;IACvC,CAAC;IACD,IAAI,CAAC,uBAAuB,CAAC,IAAI,CAAC,KAAK,CAAC,EAAE,CAAC;QACzC,OAAO,oCAA4B,CAAC;IACtC,CAAC;IACD,OAAO,IAAI,CAAC;AACd,CAAC;AAMD,SAAgB,4BAA4B,CAAC,KAAa;IACxD,OAAO,qBAAqB,CAAC,KAAK,CAAC,KAAK,IAAI,CAAC;AAC/C,CAAC"}
@@ -0,0 +1,7 @@
1
+ import type { TemplatePreviewData } from '@singleton-sd/post-kit-types';
2
+ export interface PreviewDataEditorProps {
3
+ declaredVariables: readonly string[];
4
+ previewData: TemplatePreviewData;
5
+ onChange: (previewData: TemplatePreviewData) => void;
6
+ }
7
+ export declare function PreviewDataEditor({ declaredVariables, previewData, onChange, }: PreviewDataEditorProps): JSX.Element;
@@ -0,0 +1,37 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.PreviewDataEditor = PreviewDataEditor;
4
+ const jsx_runtime_1 = require("react/jsx-runtime");
5
+ const react_1 = require("react");
6
+ const email_template_editor_1 = require("../email-template-editor");
7
+ const preview_rows_1 = require("./preview-rows");
8
+ function PreviewDataEditor({ declaredVariables, previewData, onChange, }) {
9
+ const p = email_template_editor_1.EDITOR_CLASS_PREFIX;
10
+ const rows = (0, preview_rows_1.buildPreviewRows)(declaredVariables, previewData);
11
+ const [newKey, setNewKey] = (0, react_1.useState)('');
12
+ const [addError, setAddError] = (0, react_1.useState)(null);
13
+ const addInputId = (0, react_1.useId)();
14
+ const handleValueChange = (0, react_1.useCallback)((key, value) => {
15
+ onChange((0, preview_rows_1.setPreviewValue)(previewData, key, value));
16
+ }, [onChange, previewData]);
17
+ const handleRemove = (0, react_1.useCallback)((key) => {
18
+ onChange((0, preview_rows_1.removePreviewKey)(previewData, key));
19
+ }, [onChange, previewData]);
20
+ const handleAdd = (0, react_1.useCallback)((event) => {
21
+ event.preventDefault();
22
+ const next = (0, preview_rows_1.addPreviewKey)(previewData, newKey);
23
+ if (next === null) {
24
+ const trimmed = newKey.trim();
25
+ setAddError(trimmed === '' ? 'Enter a variable name.' : `"${trimmed}" is already in preview data.`);
26
+ return;
27
+ }
28
+ setAddError(null);
29
+ setNewKey('');
30
+ onChange(next);
31
+ }, [newKey, onChange, previewData]);
32
+ return ((0, jsx_runtime_1.jsxs)("section", { className: `${p}preview-data`, "data-testid": `${p}preview-data`, children: [(0, jsx_runtime_1.jsx)("h2", { className: `${p}preview-data-heading`, children: "Preview data" }), (0, jsx_runtime_1.jsx)("p", { className: `${p}preview-data-hint`, children: "Sample values only \u2014 never real personal data. These are committed with the template source." }), (0, jsx_runtime_1.jsx)("ul", { className: `${p}preview-data-list`, "data-testid": `${p}preview-data-list`, children: rows.map((row) => ((0, jsx_runtime_1.jsxs)("li", { className: `${p}preview-data-row${row.extra ? ` ${p}preview-data-row-extra` : ''}`, "data-testid": `${p}preview-data-row`, "data-extra": row.extra ? 'true' : 'false', "data-key": row.key, children: [(0, jsx_runtime_1.jsxs)("label", { className: `${p}preview-data-key`, htmlFor: `${p}preview-${row.key}`, children: [row.key, row.extra ? ((0, jsx_runtime_1.jsx)("span", { className: `${p}preview-data-extra-badge`, "data-testid": `${p}preview-extra`, children: "extra" })) : null] }), (0, jsx_runtime_1.jsx)("input", { id: `${p}preview-${row.key}`, className: `${p}preview-data-value`, type: "text", value: row.value, onChange: (event) => handleValueChange(row.key, event.target.value), "data-testid": `${p}preview-value-${row.key}`, autoComplete: "off", spellCheck: false }), (0, jsx_runtime_1.jsx)("button", { type: "button", className: `${p}preview-data-remove`, onClick: () => handleRemove(row.key), "data-testid": `${p}preview-remove-${row.key}`, children: "Remove" })] }, row.key))) }), (0, jsx_runtime_1.jsxs)("form", { className: `${p}preview-data-add`, onSubmit: handleAdd, "data-testid": `${p}preview-data-add`, children: [(0, jsx_runtime_1.jsx)("label", { className: `${p}preview-data-label`, htmlFor: addInputId, children: "Add preview key" }), (0, jsx_runtime_1.jsx)("input", { id: addInputId, className: `${p}preview-data-input`, type: "text", value: newKey, onChange: (event) => {
33
+ setNewKey(event.target.value);
34
+ setAddError(null);
35
+ }, placeholder: "variable.name", autoComplete: "off", spellCheck: false, "data-testid": `${p}preview-add-key` }), (0, jsx_runtime_1.jsx)("button", { type: "submit", className: `${p}preview-data-add-button`, "data-testid": `${p}preview-add`, children: "Add" }), addError ? ((0, jsx_runtime_1.jsx)("p", { className: `${p}preview-data-error`, "data-testid": `${p}preview-add-error`, role: "status", children: addError })) : null] })] }));
36
+ }
37
+ //# sourceMappingURL=PreviewDataEditor.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"PreviewDataEditor.js","sourceRoot":"","sources":["../../src/preview/PreviewDataEditor.tsx"],"names":[],"mappings":"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"}
@@ -0,0 +1,7 @@
1
+ import type { TemplateSourceFiles } from '../types';
2
+ export interface PreviewPaneProps {
3
+ files: TemplateSourceFiles;
4
+ onPreviewRendered?: (html: string) => void;
5
+ debounceMs?: number;
6
+ }
7
+ export declare function PreviewPane({ files, onPreviewRendered, debounceMs, }: PreviewPaneProps): JSX.Element;
@@ -0,0 +1,39 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.PreviewPane = PreviewPane;
4
+ const jsx_runtime_1 = require("react/jsx-runtime");
5
+ const react_1 = require("react");
6
+ const email_template_editor_1 = require("../email-template-editor");
7
+ const preview_frame_1 = require("./preview-frame");
8
+ const render_template_preview_1 = require("./render-template-preview");
9
+ function PreviewPane({ files, onPreviewRendered, debounceMs = render_template_preview_1.PREVIEW_DEBOUNCE_MS, }) {
10
+ const p = email_template_editor_1.EDITOR_CLASS_PREFIX;
11
+ const [result, setResult] = (0, react_1.useState)(null);
12
+ const [pending, setPending] = (0, react_1.useState)(true);
13
+ const onPreviewRenderedRef = (0, react_1.useRef)(onPreviewRendered);
14
+ onPreviewRenderedRef.current = onPreviewRendered;
15
+ const requestIdRef = (0, react_1.useRef)(0);
16
+ (0, react_1.useEffect)(() => {
17
+ setPending(true);
18
+ const requestId = ++requestIdRef.current;
19
+ const timer = setTimeout(() => {
20
+ void (async () => {
21
+ const next = await (0, render_template_preview_1.renderTemplatePreview)(files);
22
+ if (requestId !== requestIdRef.current) {
23
+ return;
24
+ }
25
+ setResult(next);
26
+ setPending(false);
27
+ if (next.ok) {
28
+ onPreviewRenderedRef.current?.(next.html);
29
+ }
30
+ })();
31
+ }, debounceMs);
32
+ return () => {
33
+ clearTimeout(timer);
34
+ requestIdRef.current += 1;
35
+ };
36
+ }, [files, debounceMs]);
37
+ return ((0, jsx_runtime_1.jsxs)("section", { className: `${p}preview-pane`, "data-testid": `${p}preview-pane`, children: [(0, jsx_runtime_1.jsx)("h2", { className: `${p}preview-pane-heading`, children: "Preview" }), result === null ? ((0, jsx_runtime_1.jsx)("p", { className: `${p}preview-pane-status`, "data-testid": `${p}preview-pending`, children: "Rendering preview\u2026" })) : null, pending && result !== null ? ((0, jsx_runtime_1.jsx)("p", { className: `${p}preview-pane-status`, "data-testid": `${p}preview-updating`, children: "Updating preview\u2026" })) : null, result && !result.ok ? (0, jsx_runtime_1.jsx)(preview_frame_1.PreviewErrorBanner, { message: result.error }) : null, result?.ok ? (0, jsx_runtime_1.jsx)(preview_frame_1.PreviewFrame, { html: result.html }) : null] }));
38
+ }
39
+ //# sourceMappingURL=PreviewPane.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"PreviewPane.js","sourceRoot":"","sources":["../../src/preview/PreviewPane.tsx"],"names":[],"mappings":";;AA+BA,kCAsDC;;AArFD,iCAA2D;AAE3D,oEAA+D;AAE/D,mDAAmE;AACnE,uEAImC;AAsBnC,SAAgB,WAAW,CAAC,EAC1B,KAAK,EACL,iBAAiB,EACjB,UAAU,GAAG,6CAAmB,GACf;IACjB,MAAM,CAAC,GAAG,2CAAmB,CAAC;IAC9B,MAAM,CAAC,MAAM,EAAE,SAAS,CAAC,GAAG,IAAA,gBAAQ,EAA6B,IAAI,CAAC,CAAC;IACvE,MAAM,CAAC,OAAO,EAAE,UAAU,CAAC,GAAG,IAAA,gBAAQ,EAAC,IAAI,CAAC,CAAC;IAC7C,MAAM,oBAAoB,GAAG,IAAA,cAAM,EAAC,iBAAiB,CAAC,CAAC;IACvD,oBAAoB,CAAC,OAAO,GAAG,iBAAiB,CAAC;IACjD,MAAM,YAAY,GAAG,IAAA,cAAM,EAAC,CAAC,CAAC,CAAC;IAE/B,IAAA,iBAAS,EAAC,GAAG,EAAE;QACb,UAAU,CAAC,IAAI,CAAC,CAAC;QACjB,MAAM,SAAS,GAAG,EAAE,YAAY,CAAC,OAAO,CAAC;QACzC,MAAM,KAAK,GAAG,UAAU,CAAC,GAAG,EAAE;YAC5B,KAAK,CAAC,KAAK,IAAI,EAAE;gBACf,MAAM,IAAI,GAAG,MAAM,IAAA,+CAAqB,EAAC,KAAK,CAAC,CAAC;gBAEhD,IAAI,SAAS,KAAK,YAAY,CAAC,OAAO,EAAE,CAAC;oBACvC,OAAO;gBACT,CAAC;gBACD,SAAS,CAAC,IAAI,CAAC,CAAC;gBAChB,UAAU,CAAC,KAAK,CAAC,CAAC;gBAClB,IAAI,IAAI,CAAC,EAAE,EAAE,CAAC;oBACZ,oBAAoB,CAAC,OAAO,EAAE,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;gBAC5C,CAAC;YACH,CAAC,CAAC,EAAE,CAAC;QACP,CAAC,EAAE,UAAU,CAAC,CAAC;QAEf,OAAO,GAAG,EAAE;YACV,YAAY,CAAC,KAAK,CAAC,CAAC;YAEpB,YAAY,CAAC,OAAO,IAAI,CAAC,CAAC;QAC5B,CAAC,CAAC;IACJ,CAAC,EAAE,CAAC,KAAK,EAAE,UAAU,CAAC,CAAC,CAAC;IAExB,OAAO,CACL,qCAAS,SAAS,EAAE,GAAG,CAAC,cAAc,iBAAe,GAAG,CAAC,cAAc,aACrE,+BAAI,SAAS,EAAE,GAAG,CAAC,sBAAsB,wBAAc,EACtD,MAAM,KAAK,IAAI,CAAC,CAAC,CAAC,CACjB,8BAAG,SAAS,EAAE,GAAG,CAAC,qBAAqB,iBAAe,GAAG,CAAC,iBAAiB,wCAEvE,CACL,CAAC,CAAC,CAAC,IAAI,EACP,OAAO,IAAI,MAAM,KAAK,IAAI,CAAC,CAAC,CAAC,CAC5B,8BAAG,SAAS,EAAE,GAAG,CAAC,qBAAqB,iBAAe,GAAG,CAAC,kBAAkB,uCAExE,CACL,CAAC,CAAC,CAAC,IAAI,EACP,MAAM,IAAI,CAAC,MAAM,CAAC,EAAE,CAAC,CAAC,CAAC,uBAAC,kCAAkB,IAAC,OAAO,EAAE,MAAM,CAAC,KAAK,GAAI,CAAC,CAAC,CAAC,IAAI,EAC3E,MAAM,EAAE,EAAE,CAAC,CAAC,CAAC,uBAAC,4BAAY,IAAC,IAAI,EAAE,MAAM,CAAC,IAAI,GAAI,CAAC,CAAC,CAAC,IAAI,IAChD,CACX,CAAC;AACJ,CAAC"}
@@ -0,0 +1,8 @@
1
+ export declare const PREVIEW_DOCUMENT_CSP = "default-src 'none'; script-src 'none'; connect-src 'none'; style-src 'unsafe-inline'; img-src data:; font-src data:; object-src 'none'; base-uri 'none'; form-action 'none'; frame-src 'none'";
2
+ export declare function wrapPreviewHtmlWithCsp(html: string): string;
3
+ export declare function PreviewErrorBanner({ message }: {
4
+ message: string;
5
+ }): JSX.Element;
6
+ export declare function PreviewFrame({ html }: {
7
+ html: string;
8
+ }): JSX.Element;
@@ -0,0 +1,41 @@
1
+ "use strict";
2
+ var __importDefault = (this && this.__importDefault) || function (mod) {
3
+ return (mod && mod.__esModule) ? mod : { "default": mod };
4
+ };
5
+ Object.defineProperty(exports, "__esModule", { value: true });
6
+ exports.PREVIEW_DOCUMENT_CSP = void 0;
7
+ exports.wrapPreviewHtmlWithCsp = wrapPreviewHtmlWithCsp;
8
+ exports.PreviewErrorBanner = PreviewErrorBanner;
9
+ exports.PreviewFrame = PreviewFrame;
10
+ const jsx_runtime_1 = require("react/jsx-runtime");
11
+ const react_1 = __importDefault(require("react"));
12
+ const email_template_editor_1 = require("../email-template-editor");
13
+ exports.PREVIEW_DOCUMENT_CSP = "default-src 'none'; script-src 'none'; connect-src 'none'; style-src 'unsafe-inline'; img-src data:; font-src data:; object-src 'none'; base-uri 'none'; form-action 'none'; frame-src 'none'";
14
+ function wrapPreviewHtmlWithCsp(html) {
15
+ const meta = `<meta http-equiv="Content-Security-Policy" content="${exports.PREVIEW_DOCUMENT_CSP}">`;
16
+ const trimmed = html.trim();
17
+ if (/^<!DOCTYPE/i.test(trimmed) || /^<html[\s>]/i.test(trimmed)) {
18
+ if (/<head[\s>]/i.test(trimmed)) {
19
+ return trimmed.replace(/<head([^>]*)>/i, `<head$1>${meta}`);
20
+ }
21
+ return trimmed.replace(/<html([^>]*)>/i, `<html$1><head>${meta}</head>`);
22
+ }
23
+ return `<!DOCTYPE html><html><head>${meta}</head><body>${html}</body></html>`;
24
+ }
25
+ function PreviewErrorBanner({ message }) {
26
+ const p = email_template_editor_1.EDITOR_CLASS_PREFIX;
27
+ return ((0, jsx_runtime_1.jsx)("p", { className: `${p}preview-pane-error`, "data-testid": `${p}preview-error`, role: "alert", children: message }));
28
+ }
29
+ function PreviewFrame({ html }) {
30
+ const p = email_template_editor_1.EDITOR_CLASS_PREFIX;
31
+ const srcDoc = wrapPreviewHtmlWithCsp(html);
32
+ return react_1.default.createElement('iframe', {
33
+ className: `${p}preview-frame`,
34
+ title: 'Email preview',
35
+ sandbox: '',
36
+ srcDoc,
37
+ 'data-testid': `${p}preview-frame`,
38
+ csp: exports.PREVIEW_DOCUMENT_CSP,
39
+ });
40
+ }
41
+ //# sourceMappingURL=preview-frame.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"preview-frame.js","sourceRoot":"","sources":["../../src/preview/preview-frame.tsx"],"names":[],"mappings":";;;;;;AAwBA,wDAUC;AAED,gDAOC;AAED,oCAeC;;AArDD,kDAA0B;AAE1B,oEAA+D;AASlD,QAAA,oBAAoB,GAC/B,+LAA+L,CAAC;AAKlM,SAAgB,sBAAsB,CAAC,IAAY;IACjD,MAAM,IAAI,GAAG,uDAAuD,4BAAoB,IAAI,CAAC;IAC7F,MAAM,OAAO,GAAG,IAAI,CAAC,IAAI,EAAE,CAAC;IAC5B,IAAI,aAAa,CAAC,IAAI,CAAC,OAAO,CAAC,IAAI,cAAc,CAAC,IAAI,CAAC,OAAO,CAAC,EAAE,CAAC;QAChE,IAAI,aAAa,CAAC,IAAI,CAAC,OAAO,CAAC,EAAE,CAAC;YAChC,OAAO,OAAO,CAAC,OAAO,CAAC,gBAAgB,EAAE,WAAW,IAAI,EAAE,CAAC,CAAC;QAC9D,CAAC;QACD,OAAO,OAAO,CAAC,OAAO,CAAC,gBAAgB,EAAE,iBAAiB,IAAI,SAAS,CAAC,CAAC;IAC3E,CAAC;IACD,OAAO,8BAA8B,IAAI,gBAAgB,IAAI,gBAAgB,CAAC;AAChF,CAAC;AAED,SAAgB,kBAAkB,CAAC,EAAE,OAAO,EAAuB;IACjE,MAAM,CAAC,GAAG,2CAAmB,CAAC;IAC9B,OAAO,CACL,8BAAG,SAAS,EAAE,GAAG,CAAC,oBAAoB,iBAAe,GAAG,CAAC,eAAe,EAAE,IAAI,EAAC,OAAO,YACnF,OAAO,GACN,CACL,CAAC;AACJ,CAAC;AAED,SAAgB,YAAY,CAAC,EAAE,IAAI,EAAoB;IACrD,MAAM,CAAC,GAAG,2CAAmB,CAAC;IAC9B,MAAM,MAAM,GAAG,sBAAsB,CAAC,IAAI,CAAC,CAAC;IAE5C,OAAO,eAAK,CAAC,aAAa,CAAC,QAAQ,EAAE;QACnC,SAAS,EAAE,GAAG,CAAC,eAAe;QAC9B,KAAK,EAAE,eAAe;QACtB,OAAO,EAAE,EAAE;QACX,MAAM;QACN,aAAa,EAAE,GAAG,CAAC,eAAe;QAClC,GAAG,EAAE,4BAAoB;KAI1B,CAAC,CAAC;AACL,CAAC"}
@@ -0,0 +1,10 @@
1
+ import type { TemplatePreviewData } from '@singleton-sd/post-kit-types';
2
+ export interface PreviewDataRow {
3
+ key: string;
4
+ value: string;
5
+ extra: boolean;
6
+ }
7
+ export declare function buildPreviewRows(declaredVariables: readonly string[], previewData: TemplatePreviewData): PreviewDataRow[];
8
+ export declare function setPreviewValue(previewData: TemplatePreviewData, key: string, value: string): TemplatePreviewData;
9
+ export declare function removePreviewKey(previewData: TemplatePreviewData, key: string): TemplatePreviewData;
10
+ export declare function addPreviewKey(previewData: TemplatePreviewData, key: string, value?: string): TemplatePreviewData | null;
@@ -0,0 +1,54 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.buildPreviewRows = buildPreviewRows;
4
+ exports.setPreviewValue = setPreviewValue;
5
+ exports.removePreviewKey = removePreviewKey;
6
+ exports.addPreviewKey = addPreviewKey;
7
+ function buildPreviewRows(declaredVariables, previewData) {
8
+ const seenDeclared = new Set();
9
+ const rows = [];
10
+ for (const key of declaredVariables) {
11
+ if (seenDeclared.has(key)) {
12
+ continue;
13
+ }
14
+ seenDeclared.add(key);
15
+ rows.push({
16
+ key,
17
+ value: Object.prototype.hasOwnProperty.call(previewData, key) ? (previewData[key] ?? '') : '',
18
+ extra: false,
19
+ });
20
+ }
21
+ const extras = Object.keys(previewData)
22
+ .filter((key) => !seenDeclared.has(key))
23
+ .sort((a, b) => a.localeCompare(b));
24
+ for (const key of extras) {
25
+ rows.push({
26
+ key,
27
+ value: previewData[key] ?? '',
28
+ extra: true,
29
+ });
30
+ }
31
+ return rows;
32
+ }
33
+ function setPreviewValue(previewData, key, value) {
34
+ return { ...previewData, [key]: value };
35
+ }
36
+ function removePreviewKey(previewData, key) {
37
+ if (!Object.prototype.hasOwnProperty.call(previewData, key)) {
38
+ return previewData;
39
+ }
40
+ const next = { ...previewData };
41
+ delete next[key];
42
+ return next;
43
+ }
44
+ function addPreviewKey(previewData, key, value = '') {
45
+ const trimmed = key.trim();
46
+ if (!trimmed) {
47
+ return null;
48
+ }
49
+ if (Object.prototype.hasOwnProperty.call(previewData, trimmed)) {
50
+ return null;
51
+ }
52
+ return { ...previewData, [trimmed]: value };
53
+ }
54
+ //# sourceMappingURL=preview-rows.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"preview-rows.js","sourceRoot":"","sources":["../../src/preview/preview-rows.ts"],"names":[],"mappings":";;AAuBA,4CAgCC;AAMD,0CAMC;AAMD,4CAUC;AAKD,sCAaC;AA9ED,SAAgB,gBAAgB,CAC9B,iBAAoC,EACpC,WAAgC;IAEhC,MAAM,YAAY,GAAG,IAAI,GAAG,EAAU,CAAC;IACvC,MAAM,IAAI,GAAqB,EAAE,CAAC;IAElC,KAAK,MAAM,GAAG,IAAI,iBAAiB,EAAE,CAAC;QACpC,IAAI,YAAY,CAAC,GAAG,CAAC,GAAG,CAAC,EAAE,CAAC;YAC1B,SAAS;QACX,CAAC;QACD,YAAY,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC;QACtB,IAAI,CAAC,IAAI,CAAC;YACR,GAAG;YACH,KAAK,EAAE,MAAM,CAAC,SAAS,CAAC,cAAc,CAAC,IAAI,CAAC,WAAW,EAAE,GAAG,CAAC,CAAC,CAAC,CAAC,CAAC,WAAW,CAAC,GAAG,CAAC,IAAI,EAAE,CAAC,CAAC,CAAC,CAAC,EAAE;YAC7F,KAAK,EAAE,KAAK;SACb,CAAC,CAAC;IACL,CAAC;IAED,MAAM,MAAM,GAAG,MAAM,CAAC,IAAI,CAAC,WAAW,CAAC;SACpC,MAAM,CAAC,CAAC,GAAG,EAAE,EAAE,CAAC,CAAC,YAAY,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC;SACvC,IAAI,CAAC,CAAC,CAAC,EAAE,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,aAAa,CAAC,CAAC,CAAC,CAAC,CAAC;IAEtC,KAAK,MAAM,GAAG,IAAI,MAAM,EAAE,CAAC;QACzB,IAAI,CAAC,IAAI,CAAC;YACR,GAAG;YACH,KAAK,EAAE,WAAW,CAAC,GAAG,CAAC,IAAI,EAAE;YAC7B,KAAK,EAAE,IAAI;SACZ,CAAC,CAAC;IACL,CAAC;IAED,OAAO,IAAI,CAAC;AACd,CAAC;AAMD,SAAgB,eAAe,CAC7B,WAAgC,EAChC,GAAW,EACX,KAAa;IAEb,OAAO,EAAE,GAAG,WAAW,EAAE,CAAC,GAAG,CAAC,EAAE,KAAK,EAAE,CAAC;AAC1C,CAAC;AAMD,SAAgB,gBAAgB,CAC9B,WAAgC,EAChC,GAAW;IAEX,IAAI,CAAC,MAAM,CAAC,SAAS,CAAC,cAAc,CAAC,IAAI,CAAC,WAAW,EAAE,GAAG,CAAC,EAAE,CAAC;QAC5D,OAAO,WAAW,CAAC;IACrB,CAAC;IACD,MAAM,IAAI,GAAG,EAAE,GAAG,WAAW,EAAE,CAAC;IAChC,OAAO,IAAI,CAAC,GAAG,CAAC,CAAC;IACjB,OAAO,IAAI,CAAC;AACd,CAAC;AAKD,SAAgB,aAAa,CAC3B,WAAgC,EAChC,GAAW,EACX,KAAK,GAAG,EAAE;IAEV,MAAM,OAAO,GAAG,GAAG,CAAC,IAAI,EAAE,CAAC;IAC3B,IAAI,CAAC,OAAO,EAAE,CAAC;QACb,OAAO,IAAI,CAAC;IACd,CAAC;IACD,IAAI,MAAM,CAAC,SAAS,CAAC,cAAc,CAAC,IAAI,CAAC,WAAW,EAAE,OAAO,CAAC,EAAE,CAAC;QAC/D,OAAO,IAAI,CAAC;IACd,CAAC;IACD,OAAO,EAAE,GAAG,WAAW,EAAE,CAAC,OAAO,CAAC,EAAE,KAAK,EAAE,CAAC;AAC9C,CAAC"}
@@ -0,0 +1,10 @@
1
+ import type { TemplateSourceFiles } from '../types';
2
+ export type PreviewRenderResult = {
3
+ ok: true;
4
+ html: string;
5
+ } | {
6
+ ok: false;
7
+ error: string;
8
+ };
9
+ export declare function renderTemplatePreview(files: TemplateSourceFiles): Promise<PreviewRenderResult>;
10
+ export declare const PREVIEW_DEBOUNCE_MS = 300;
@@ -0,0 +1,27 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.PREVIEW_DEBOUNCE_MS = void 0;
4
+ exports.renderTemplatePreview = renderTemplatePreview;
5
+ const preview_1 = require("@singleton-sd/post-kit-compiler/preview");
6
+ async function renderTemplatePreview(files) {
7
+ const source = {
8
+ templateJson: files.templateJson,
9
+ metadata: files.metadata,
10
+ previewData: files.previewData,
11
+ };
12
+ try {
13
+ const html = await (0, preview_1.renderPreview)(source);
14
+ return { ok: true, html };
15
+ }
16
+ catch (err) {
17
+ if (err instanceof preview_1.CompilerError) {
18
+ return { ok: false, error: err.message };
19
+ }
20
+ return {
21
+ ok: false,
22
+ error: err instanceof Error ? err.message : String(err),
23
+ };
24
+ }
25
+ }
26
+ exports.PREVIEW_DEBOUNCE_MS = 300;
27
+ //# sourceMappingURL=render-template-preview.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"render-template-preview.js","sourceRoot":"","sources":["../../src/preview/render-template-preview.ts"],"names":[],"mappings":";;;AAWA,sDAqBC;AA/BD,qEAAuF;AAUhF,KAAK,UAAU,qBAAqB,CACzC,KAA0B;IAE1B,MAAM,MAAM,GAAmB;QAC7B,YAAY,EAAE,KAAK,CAAC,YAAY;QAChC,QAAQ,EAAE,KAAK,CAAC,QAAQ;QACxB,WAAW,EAAE,KAAK,CAAC,WAAW;KAC/B,CAAC;IAEF,IAAI,CAAC;QACH,MAAM,IAAI,GAAG,MAAM,IAAA,uBAAa,EAAC,MAAM,CAAC,CAAC;QACzC,OAAO,EAAE,EAAE,EAAE,IAAI,EAAE,IAAI,EAAE,CAAC;IAC5B,CAAC;IAAC,OAAO,GAAG,EAAE,CAAC;QACb,IAAI,GAAG,YAAY,uBAAa,EAAE,CAAC;YACjC,OAAO,EAAE,EAAE,EAAE,KAAK,EAAE,KAAK,EAAE,GAAG,CAAC,OAAO,EAAE,CAAC;QAC3C,CAAC;QACD,OAAO;YACL,EAAE,EAAE,KAAK;YACT,KAAK,EAAE,GAAG,YAAY,KAAK,CAAC,CAAC,CAAC,GAAG,CAAC,OAAO,CAAC,CAAC,CAAC,MAAM,CAAC,GAAG,CAAC;SACxD,CAAC;IACJ,CAAC;AACH,CAAC;AAGY,QAAA,mBAAmB,GAAG,GAAG,CAAC"}
@@ -0,0 +1,15 @@
1
+ import type { TemplateSourceFiles } from './types';
2
+ export declare class TemplateSourceError extends Error {
3
+ readonly file: 'template.json' | 'metadata.json' | 'preview.json';
4
+ constructor(file: TemplateSourceError['file'], message: string);
5
+ }
6
+ export declare function loadTemplateSource(input: {
7
+ templateJson: unknown;
8
+ metadata: unknown;
9
+ previewData: unknown;
10
+ }): TemplateSourceFiles;
11
+ export declare function serializeTemplateSource(files: TemplateSourceFiles): {
12
+ templateJson: string;
13
+ metadataJson: string;
14
+ previewJson: string;
15
+ };
@@ -0,0 +1,128 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.TemplateSourceError = void 0;
4
+ exports.loadTemplateSource = loadTemplateSource;
5
+ exports.serializeTemplateSource = serializeTemplateSource;
6
+ const post_kit_types_1 = require("@singleton-sd/post-kit-types");
7
+ class TemplateSourceError extends Error {
8
+ constructor(file, message) {
9
+ super(`${file}: ${message}`);
10
+ this.name = 'TemplateSourceError';
11
+ this.file = file;
12
+ }
13
+ }
14
+ exports.TemplateSourceError = TemplateSourceError;
15
+ function isPlainObject(value) {
16
+ return typeof value === 'object' && value !== null && !Array.isArray(value);
17
+ }
18
+ function assertTemplateJson(value) {
19
+ if (!isPlainObject(value)) {
20
+ throw new TemplateSourceError('template.json', 'must be a JSON object');
21
+ }
22
+ if (!('root' in value)) {
23
+ throw new TemplateSourceError('template.json', 'must be an EmailBuilder document object with a root block');
24
+ }
25
+ const root = value.root;
26
+ if (!isPlainObject(root) ||
27
+ typeof root.type !== 'string' ||
28
+ root.type.trim() === '' ||
29
+ !isPlainObject(root.data)) {
30
+ throw new TemplateSourceError('template.json', 'must be an EmailBuilder document object with a root block');
31
+ }
32
+ return value;
33
+ }
34
+ function assertMetadata(value) {
35
+ if (!isPlainObject(value)) {
36
+ throw new TemplateSourceError('metadata.json', 'must be a JSON object');
37
+ }
38
+ const requiredStrings = ['key', 'name', 'subject', 'schemaVersion'];
39
+ for (const field of requiredStrings) {
40
+ if (typeof value[field] !== 'string' || value[field].trim() === '') {
41
+ throw new TemplateSourceError('metadata.json', `metadata.${field} must be a non-empty string`);
42
+ }
43
+ }
44
+ if (value.schemaVersion !== post_kit_types_1.TEMPLATE_SCHEMA_VERSION) {
45
+ throw new TemplateSourceError('metadata.json', `metadata.schemaVersion must be "${post_kit_types_1.TEMPLATE_SCHEMA_VERSION}" (got ${JSON.stringify(value.schemaVersion)})`);
46
+ }
47
+ if (!Array.isArray(value.variables)) {
48
+ throw new TemplateSourceError('metadata.json', 'metadata.variables must be an array');
49
+ }
50
+ for (let i = 0; i < value.variables.length; i++) {
51
+ if (typeof value.variables[i] !== 'string') {
52
+ throw new TemplateSourceError('metadata.json', `metadata.variables[${i}] must be a string`);
53
+ }
54
+ }
55
+ if (value.description !== undefined && typeof value.description !== 'string') {
56
+ throw new TemplateSourceError('metadata.json', 'metadata.description must be a string');
57
+ }
58
+ return value;
59
+ }
60
+ function assertPreviewData(value) {
61
+ if (!isPlainObject(value)) {
62
+ throw new TemplateSourceError('preview.json', 'must be a JSON object');
63
+ }
64
+ for (const [key, entry] of Object.entries(value)) {
65
+ if (typeof entry !== 'string') {
66
+ throw new TemplateSourceError('preview.json', `preview.${key} must be a string`);
67
+ }
68
+ }
69
+ return value;
70
+ }
71
+ function sortKeys(value, preferredOrder = []) {
72
+ if (Array.isArray(value)) {
73
+ return value.map((entry) => sortKeys(entry, preferredOrder));
74
+ }
75
+ if (!isPlainObject(value)) {
76
+ return value;
77
+ }
78
+ const preferred = preferredOrder.filter((key) => key in value);
79
+ const remaining = Object.keys(value)
80
+ .filter((key) => !preferred.includes(key))
81
+ .sort();
82
+ const orderedKeys = [...preferred, ...remaining];
83
+ const sorted = {};
84
+ for (const key of orderedKeys) {
85
+ sorted[key] = sortKeys(value[key], preferredOrder);
86
+ }
87
+ return sorted;
88
+ }
89
+ function stableTemplateJson(value) {
90
+ const ordered = sortKeys(value, ['root']);
91
+ return `${JSON.stringify(ordered, null, 2)}\n`;
92
+ }
93
+ function stableMetadataJson(value) {
94
+ const ordered = sortKeys(value, [
95
+ 'key',
96
+ 'name',
97
+ 'subject',
98
+ 'description',
99
+ 'variables',
100
+ 'schemaVersion',
101
+ ]);
102
+ return `${JSON.stringify(ordered, null, 2)}\n`;
103
+ }
104
+ function stablePreviewJson(value) {
105
+ const ordered = sortKeys(value);
106
+ return `${JSON.stringify(ordered, null, 2)}\n`;
107
+ }
108
+ function loadTemplateSource(input) {
109
+ const templateJson = assertTemplateJson(input.templateJson);
110
+ const metadata = assertMetadata(input.metadata);
111
+ const previewData = assertPreviewData(input.previewData);
112
+ return {
113
+ templateJson: templateJson,
114
+ metadata,
115
+ previewData,
116
+ };
117
+ }
118
+ function serializeTemplateSource(files) {
119
+ if (!isPlainObject(files.templateJson)) {
120
+ throw new TemplateSourceError('template.json', 'must be a JSON object');
121
+ }
122
+ return {
123
+ templateJson: stableTemplateJson(files.templateJson),
124
+ metadataJson: stableMetadataJson(files.metadata),
125
+ previewJson: stablePreviewJson(files.previewData),
126
+ };
127
+ }
128
+ //# sourceMappingURL=serialization.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"serialization.js","sourceRoot":"","sources":["../src/serialization.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,14 @@
1
+ import type { TReaderDocument } from '@usewaypoint/email-builder';
2
+ import type { TemplateSourceMetadata, TemplatePreviewData } from '@singleton-sd/post-kit-types';
3
+ export type EmailBuilderDocument = TReaderDocument & Record<string, unknown>;
4
+ export interface TemplateSourceFiles {
5
+ templateJson: EmailBuilderDocument;
6
+ metadata: TemplateSourceMetadata;
7
+ previewData: TemplatePreviewData;
8
+ }
9
+ export interface TemplateVariable {
10
+ name: string;
11
+ label?: string;
12
+ description?: string;
13
+ example?: string;
14
+ }
package/dist/types.js ADDED
@@ -0,0 +1,3 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ //# sourceMappingURL=types.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"types.js","sourceRoot":"","sources":["../src/types.ts"],"names":[],"mappings":""}
@@ -0,0 +1,7 @@
1
+ import type { TemplateVariable } from '../types';
2
+ export interface VariableCatalogueProps {
3
+ availableVariables?: TemplateVariable[];
4
+ metadataVariables: string[];
5
+ onMetadataVariablesChange: (variables: string[]) => void;
6
+ }
7
+ export declare function VariableCatalogue({ availableVariables, metadataVariables, onMetadataVariablesChange, }: VariableCatalogueProps): JSX.Element;
@@ -0,0 +1,77 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.VariableCatalogue = VariableCatalogue;
4
+ const jsx_runtime_1 = require("react/jsx-runtime");
5
+ const react_1 = require("react");
6
+ const email_template_editor_1 = require("../email-template-editor");
7
+ const insertion_target_1 = require("../insertion-target");
8
+ const insert_at_cursor_1 = require("../metadata/insert-at-cursor");
9
+ const clipboard_1 = require("./clipboard");
10
+ const copy_feedback_1 = require("./copy-feedback");
11
+ const resolve_catalogue_1 = require("./resolve-catalogue");
12
+ function VariableCatalogue({ availableVariables, metadataVariables, onMetadataVariablesChange, }) {
13
+ const p = email_template_editor_1.EDITOR_CLASS_PREFIX;
14
+ const { target } = (0, insertion_target_1.useInsertionTarget)();
15
+ const entries = (0, resolve_catalogue_1.resolveCatalogueVariables)(availableVariables, metadataVariables);
16
+ const [copyFeedback, setCopyFeedback] = (0, react_1.useState)(null);
17
+ const [newVariable, setNewVariable] = (0, react_1.useState)('');
18
+ const [addError, setAddError] = (0, react_1.useState)(null);
19
+ const fallbackSelectRef = (0, react_1.useRef)(null);
20
+ const addInputId = (0, react_1.useId)();
21
+ const handleCopy = (0, react_1.useCallback)(async (name) => {
22
+ const text = (0, insert_at_cursor_1.variablePlaceholder)(name);
23
+ const result = await (0, clipboard_1.copyTextToClipboard)(text);
24
+ const kind = (0, copy_feedback_1.copyFeedbackKind)(result);
25
+ if (kind === 'manual') {
26
+ const el = fallbackSelectRef.current;
27
+ if (el) {
28
+ el.value = text;
29
+ el.focus();
30
+ el.select();
31
+ }
32
+ }
33
+ setCopyFeedback({ name, kind });
34
+ }, []);
35
+ const handleInsert = (0, react_1.useCallback)((name) => {
36
+ if (!target) {
37
+ return;
38
+ }
39
+ target.insert((0, insert_at_cursor_1.variablePlaceholder)(name));
40
+ }, [target]);
41
+ const preserveInsertionTarget = (0, react_1.useCallback)((event) => {
42
+ event.preventDefault();
43
+ }, []);
44
+ const handleAdd = (0, react_1.useCallback)((event) => {
45
+ event.preventDefault();
46
+ const name = newVariable.trim();
47
+ if (!name) {
48
+ setAddError('Enter a variable name.');
49
+ return;
50
+ }
51
+ if (metadataVariables.includes(name)) {
52
+ setAddError(`"${name}" is already declared.`);
53
+ return;
54
+ }
55
+ setAddError(null);
56
+ setNewVariable('');
57
+ onMetadataVariablesChange([...metadataVariables, name]);
58
+ }, [metadataVariables, newVariable, onMetadataVariablesChange]);
59
+ const handleRemove = (0, react_1.useCallback)((name) => {
60
+ onMetadataVariablesChange(metadataVariables.filter((entry) => entry !== name));
61
+ }, [metadataVariables, onMetadataVariablesChange]);
62
+ const insertDisabled = target === null;
63
+ const insertDisabledReason = 'Focus the subject field (or another editable target) before inserting a variable.';
64
+ return ((0, jsx_runtime_1.jsxs)("section", { className: `${p}variables`, "data-testid": `${p}variables`, children: [(0, jsx_runtime_1.jsx)("h2", { className: `${p}variables-heading`, children: "Available variables" }), (0, jsx_runtime_1.jsx)("input", { ref: fallbackSelectRef, className: `${p}variables-clipboard-fallback`, type: "text", readOnly: true, "aria-hidden": "true", tabIndex: -1, "data-testid": `${p}variables-clipboard-fallback` }), entries.length === 0 ? ((0, jsx_runtime_1.jsx)("p", { className: `${p}variables-empty`, children: "No variables declared yet." })) : ((0, jsx_runtime_1.jsx)("ul", { className: `${p}variables-list`, children: entries.map((entry) => {
65
+ const placeholder = (0, insert_at_cursor_1.variablePlaceholder)(entry.name);
66
+ const label = entry.label ?? entry.name;
67
+ return ((0, jsx_runtime_1.jsxs)("li", { className: `${p}variables-item`, children: [(0, jsx_runtime_1.jsxs)("div", { className: `${p}variables-item-main`, children: [(0, jsx_runtime_1.jsx)("span", { className: `${p}variables-item-label`, children: label }), (0, jsx_runtime_1.jsx)("code", { className: `${p}variables-item-placeholder`, children: placeholder }), entry.description ? ((0, jsx_runtime_1.jsx)("span", { className: `${p}variables-item-description`, children: entry.description })) : null] }), (0, jsx_runtime_1.jsxs)("div", { className: `${p}variables-item-actions`, children: [(0, jsx_runtime_1.jsx)("button", { type: "button", className: `${p}variables-copy`, onClick: () => {
68
+ void handleCopy(entry.name);
69
+ }, "data-testid": `${p}variables-copy-${entry.name}`, children: (0, copy_feedback_1.copyButtonLabel)(copyFeedback, entry.name) }), (0, jsx_runtime_1.jsx)("button", { type: "button", className: `${p}variables-insert`, onMouseDown: preserveInsertionTarget, onClick: () => handleInsert(entry.name), disabled: insertDisabled, title: insertDisabled ? insertDisabledReason : `Insert ${placeholder}`, "aria-label": insertDisabled
70
+ ? insertDisabledReason
71
+ : `Insert ${placeholder} into the focused field`, "data-testid": `${p}variables-insert-${entry.name}`, children: "Insert" })] })] }, entry.name));
72
+ }) })), (0, jsx_runtime_1.jsxs)("div", { className: `${p}variables-declared`, children: [(0, jsx_runtime_1.jsx)("h3", { className: `${p}variables-declared-heading`, children: "Declared variables" }), (0, jsx_runtime_1.jsx)("p", { className: `${p}variables-declared-hint`, children: "The declared list is what validation and the compiler use. Removing an entry does not rewrite the subject or document." }), metadataVariables.length > 0 ? ((0, jsx_runtime_1.jsx)("ul", { className: `${p}variables-declared-list`, children: metadataVariables.map((name) => ((0, jsx_runtime_1.jsxs)("li", { className: `${p}variables-declared-item`, children: [(0, jsx_runtime_1.jsx)("code", { children: (0, insert_at_cursor_1.variablePlaceholder)(name) }), (0, jsx_runtime_1.jsx)("button", { type: "button", className: `${p}variables-remove`, onClick: () => handleRemove(name), "data-testid": `${p}variables-remove-${name}`, children: "Remove" })] }, name))) })) : null, (0, jsx_runtime_1.jsxs)("form", { className: `${p}variables-add`, onSubmit: handleAdd, children: [(0, jsx_runtime_1.jsx)("label", { className: `${p}variables-add-label`, htmlFor: addInputId, children: "Add variable" }), (0, jsx_runtime_1.jsx)("input", { id: addInputId, className: `${p}variables-add-input`, type: "text", value: newVariable, onChange: (event) => {
73
+ setNewVariable(event.target.value);
74
+ setAddError(null);
75
+ }, placeholder: "e.g. firstName", "data-testid": `${p}variables-add-input` }), (0, jsx_runtime_1.jsx)("button", { type: "submit", className: `${p}variables-add-submit`, "data-testid": `${p}variables-add-submit`, children: "Add" }), addError ? ((0, jsx_runtime_1.jsx)("p", { className: `${p}variables-add-error`, role: "status", children: addError })) : null] })] })] }));
76
+ }
77
+ //# sourceMappingURL=VariableCatalogue.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"VariableCatalogue.js","sourceRoot":"","sources":["../../src/variables/VariableCatalogue.tsx"],"names":[],"mappings":";;AAsBA,8CAqMC;;AA3ND,iCAAoE;AAEpE,oEAA+D;AAC/D,0DAAyD;AACzD,mEAAmE;AAEnE,2CAAkD;AAClD,mDAAoE;AACpE,2DAAgE;AAchE,SAAgB,iBAAiB,CAAC,EAChC,kBAAkB,EAClB,iBAAiB,EACjB,yBAAyB,GACF;IACvB,MAAM,CAAC,GAAG,2CAAmB,CAAC;IAC9B,MAAM,EAAE,MAAM,EAAE,GAAG,IAAA,qCAAkB,GAAE,CAAC;IACxC,MAAM,OAAO,GAAG,IAAA,6CAAyB,EAAC,kBAAkB,EAAE,iBAAiB,CAAC,CAAC;IACjF,MAAM,CAAC,YAAY,EAAE,eAAe,CAAC,GAAG,IAAA,gBAAQ,EAGtC,IAAI,CAAC,CAAC;IAChB,MAAM,CAAC,WAAW,EAAE,cAAc,CAAC,GAAG,IAAA,gBAAQ,EAAC,EAAE,CAAC,CAAC;IACnD,MAAM,CAAC,QAAQ,EAAE,WAAW,CAAC,GAAG,IAAA,gBAAQ,EAAgB,IAAI,CAAC,CAAC;IAC9D,MAAM,iBAAiB,GAAG,IAAA,cAAM,EAA0B,IAAI,CAAC,CAAC;IAChE,MAAM,UAAU,GAAG,IAAA,aAAK,GAAE,CAAC;IAE3B,MAAM,UAAU,GAAG,IAAA,mBAAW,EAAC,KAAK,EAAE,IAAY,EAAE,EAAE;QACpD,MAAM,IAAI,GAAG,IAAA,sCAAmB,EAAC,IAAI,CAAC,CAAC;QACvC,MAAM,MAAM,GAAG,MAAM,IAAA,+BAAmB,EAAC,IAAI,CAAC,CAAC;QAC/C,MAAM,IAAI,GAAG,IAAA,gCAAgB,EAAC,MAAM,CAAC,CAAC;QACtC,IAAI,IAAI,KAAK,QAAQ,EAAE,CAAC;YACtB,MAAM,EAAE,GAAG,iBAAiB,CAAC,OAAO,CAAC;YACrC,IAAI,EAAE,EAAE,CAAC;gBACP,EAAE,CAAC,KAAK,GAAG,IAAI,CAAC;gBAChB,EAAE,CAAC,KAAK,EAAE,CAAC;gBACX,EAAE,CAAC,MAAM,EAAE,CAAC;YACd,CAAC;QACH,CAAC;QACD,eAAe,CAAC,EAAE,IAAI,EAAE,IAAI,EAAE,CAAC,CAAC;IAClC,CAAC,EAAE,EAAE,CAAC,CAAC;IAEP,MAAM,YAAY,GAAG,IAAA,mBAAW,EAC9B,CAAC,IAAY,EAAE,EAAE;QACf,IAAI,CAAC,MAAM,EAAE,CAAC;YACZ,OAAO;QACT,CAAC;QACD,MAAM,CAAC,MAAM,CAAC,IAAA,sCAAmB,EAAC,IAAI,CAAC,CAAC,CAAC;IAC3C,CAAC,EACD,CAAC,MAAM,CAAC,CACT,CAAC;IAGF,MAAM,uBAAuB,GAAG,IAAA,mBAAW,EAAC,CAAC,KAAuB,EAAE,EAAE;QACtE,KAAK,CAAC,cAAc,EAAE,CAAC;IACzB,CAAC,EAAE,EAAE,CAAC,CAAC;IAEP,MAAM,SAAS,GAAG,IAAA,mBAAW,EAC3B,CAAC,KAAsB,EAAE,EAAE;QACzB,KAAK,CAAC,cAAc,EAAE,CAAC;QACvB,MAAM,IAAI,GAAG,WAAW,CAAC,IAAI,EAAE,CAAC;QAChC,IAAI,CAAC,IAAI,EAAE,CAAC;YACV,WAAW,CAAC,wBAAwB,CAAC,CAAC;YACtC,OAAO;QACT,CAAC;QACD,IAAI,iBAAiB,CAAC,QAAQ,CAAC,IAAI,CAAC,EAAE,CAAC;YACrC,WAAW,CAAC,IAAI,IAAI,wBAAwB,CAAC,CAAC;YAC9C,OAAO;QACT,CAAC;QACD,WAAW,CAAC,IAAI,CAAC,CAAC;QAClB,cAAc,CAAC,EAAE,CAAC,CAAC;QACnB,yBAAyB,CAAC,CAAC,GAAG,iBAAiB,EAAE,IAAI,CAAC,CAAC,CAAC;IAC1D,CAAC,EACD,CAAC,iBAAiB,EAAE,WAAW,EAAE,yBAAyB,CAAC,CAC5D,CAAC;IAEF,MAAM,YAAY,GAAG,IAAA,mBAAW,EAC9B,CAAC,IAAY,EAAE,EAAE;QACf,yBAAyB,CAAC,iBAAiB,CAAC,MAAM,CAAC,CAAC,KAAK,EAAE,EAAE,CAAC,KAAK,KAAK,IAAI,CAAC,CAAC,CAAC;IACjF,CAAC,EACD,CAAC,iBAAiB,EAAE,yBAAyB,CAAC,CAC/C,CAAC;IAEF,MAAM,cAAc,GAAG,MAAM,KAAK,IAAI,CAAC;IACvC,MAAM,oBAAoB,GACxB,mFAAmF,CAAC;IAEtF,OAAO,CACL,qCAAS,SAAS,EAAE,GAAG,CAAC,WAAW,iBAAe,GAAG,CAAC,WAAW,aAC/D,+BAAI,SAAS,EAAE,GAAG,CAAC,mBAAmB,oCAA0B,EAGhE,kCACE,GAAG,EAAE,iBAAiB,EACtB,SAAS,EAAE,GAAG,CAAC,8BAA8B,EAC7C,IAAI,EAAC,MAAM,EACX,QAAQ,uBACI,MAAM,EAClB,QAAQ,EAAE,CAAC,CAAC,iBACC,GAAG,CAAC,8BAA8B,GAC/C,EAED,OAAO,CAAC,MAAM,KAAK,CAAC,CAAC,CAAC,CAAC,CACtB,8BAAG,SAAS,EAAE,GAAG,CAAC,iBAAiB,2CAAgC,CACpE,CAAC,CAAC,CAAC,CACF,+BAAI,SAAS,EAAE,GAAG,CAAC,gBAAgB,YAChC,OAAO,CAAC,GAAG,CAAC,CAAC,KAAK,EAAE,EAAE;oBACrB,MAAM,WAAW,GAAG,IAAA,sCAAmB,EAAC,KAAK,CAAC,IAAI,CAAC,CAAC;oBACpD,MAAM,KAAK,GAAG,KAAK,CAAC,KAAK,IAAI,KAAK,CAAC,IAAI,CAAC;oBACxC,OAAO,CACL,gCAAqB,SAAS,EAAE,GAAG,CAAC,gBAAgB,aAClD,iCAAK,SAAS,EAAE,GAAG,CAAC,qBAAqB,aACvC,iCAAM,SAAS,EAAE,GAAG,CAAC,sBAAsB,YAAG,KAAK,GAAQ,EAC3D,iCAAM,SAAS,EAAE,GAAG,CAAC,4BAA4B,YAAG,WAAW,GAAQ,EACtE,KAAK,CAAC,WAAW,CAAC,CAAC,CAAC,CACnB,iCAAM,SAAS,EAAE,GAAG,CAAC,4BAA4B,YAAG,KAAK,CAAC,WAAW,GAAQ,CAC9E,CAAC,CAAC,CAAC,IAAI,IACJ,EACN,iCAAK,SAAS,EAAE,GAAG,CAAC,wBAAwB,aAC1C,mCACE,IAAI,EAAC,QAAQ,EACb,SAAS,EAAE,GAAG,CAAC,gBAAgB,EAC/B,OAAO,EAAE,GAAG,EAAE;4CACZ,KAAK,UAAU,CAAC,KAAK,CAAC,IAAI,CAAC,CAAC;wCAC9B,CAAC,iBACY,GAAG,CAAC,kBAAkB,KAAK,CAAC,IAAI,EAAE,YAE9C,IAAA,+BAAe,EAAC,YAAY,EAAE,KAAK,CAAC,IAAI,CAAC,GACnC,EACT,mCACE,IAAI,EAAC,QAAQ,EACb,SAAS,EAAE,GAAG,CAAC,kBAAkB,EACjC,WAAW,EAAE,uBAAuB,EACpC,OAAO,EAAE,GAAG,EAAE,CAAC,YAAY,CAAC,KAAK,CAAC,IAAI,CAAC,EACvC,QAAQ,EAAE,cAAc,EACxB,KAAK,EAAE,cAAc,CAAC,CAAC,CAAC,oBAAoB,CAAC,CAAC,CAAC,UAAU,WAAW,EAAE,gBAEpE,cAAc;4CACZ,CAAC,CAAC,oBAAoB;4CACtB,CAAC,CAAC,UAAU,WAAW,yBAAyB,iBAEvC,GAAG,CAAC,oBAAoB,KAAK,CAAC,IAAI,EAAE,uBAG1C,IACL,KAnCC,KAAK,CAAC,IAAI,CAoCd,CACN,CAAC;gBACJ,CAAC,CAAC,GACC,CACN,EAED,iCAAK,SAAS,EAAE,GAAG,CAAC,oBAAoB,aACtC,+BAAI,SAAS,EAAE,GAAG,CAAC,4BAA4B,mCAAyB,EACxE,8BAAG,SAAS,EAAE,GAAG,CAAC,yBAAyB,uIAGvC,EACH,iBAAiB,CAAC,MAAM,GAAG,CAAC,CAAC,CAAC,CAAC,CAC9B,+BAAI,SAAS,EAAE,GAAG,CAAC,yBAAyB,YACzC,iBAAiB,CAAC,GAAG,CAAC,CAAC,IAAI,EAAE,EAAE,CAAC,CAC/B,gCAAe,SAAS,EAAE,GAAG,CAAC,yBAAyB,aACrD,2CAAO,IAAA,sCAAmB,EAAC,IAAI,CAAC,GAAQ,EACxC,mCACE,IAAI,EAAC,QAAQ,EACb,SAAS,EAAE,GAAG,CAAC,kBAAkB,EACjC,OAAO,EAAE,GAAG,EAAE,CAAC,YAAY,CAAC,IAAI,CAAC,iBACpB,GAAG,CAAC,oBAAoB,IAAI,EAAE,uBAGpC,KATF,IAAI,CAUR,CACN,CAAC,GACC,CACN,CAAC,CAAC,CAAC,IAAI,EACR,kCAAM,SAAS,EAAE,GAAG,CAAC,eAAe,EAAE,QAAQ,EAAE,SAAS,aACvD,kCAAO,SAAS,EAAE,GAAG,CAAC,qBAAqB,EAAE,OAAO,EAAE,UAAU,6BAExD,EACR,kCACE,EAAE,EAAE,UAAU,EACd,SAAS,EAAE,GAAG,CAAC,qBAAqB,EACpC,IAAI,EAAC,MAAM,EACX,KAAK,EAAE,WAAW,EAClB,QAAQ,EAAE,CAAC,KAAK,EAAE,EAAE;oCAClB,cAAc,CAAC,KAAK,CAAC,MAAM,CAAC,KAAK,CAAC,CAAC;oCACnC,WAAW,CAAC,IAAI,CAAC,CAAC;gCACpB,CAAC,EACD,WAAW,EAAC,gBAAgB,iBACf,GAAG,CAAC,qBAAqB,GACtC,EACF,mCACE,IAAI,EAAC,QAAQ,EACb,SAAS,EAAE,GAAG,CAAC,sBAAsB,iBACxB,GAAG,CAAC,sBAAsB,oBAGhC,EACR,QAAQ,CAAC,CAAC,CAAC,CACV,8BAAG,SAAS,EAAE,GAAG,CAAC,qBAAqB,EAAE,IAAI,EAAC,QAAQ,YACnD,QAAQ,GACP,CACL,CAAC,CAAC,CAAC,IAAI,IACH,IACH,IACE,CACX,CAAC;AACJ,CAAC"}
@@ -0,0 +1,3 @@
1
+ export declare function copyTextToClipboard(text: string): Promise<{
2
+ ok: boolean;
3
+ }>;
@@ -0,0 +1,16 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.copyTextToClipboard = copyTextToClipboard;
4
+ async function copyTextToClipboard(text) {
5
+ try {
6
+ const clipboard = globalThis.navigator?.clipboard;
7
+ if (clipboard && typeof clipboard.writeText === 'function') {
8
+ await clipboard.writeText(text);
9
+ return { ok: true };
10
+ }
11
+ }
12
+ catch {
13
+ }
14
+ return { ok: false };
15
+ }
16
+ //# sourceMappingURL=clipboard.js.map