@kgalexander/mcreate 0.0.15 → 0.0.17
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/{chunk-XSQHR5MC.mjs → chunk-GZLWB3EZ.mjs} +1488 -779
- package/dist/{core-66YYN7ME.mjs → core-JDSYY73O.mjs} +1 -1
- package/dist/index.d.mts +11 -2
- package/dist/index.d.ts +11 -2
- package/dist/index.js +5963 -3688
- package/dist/index.mjs +4209 -2710
- package/package.json +1 -1
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
// src/core/index.tsx
|
|
2
|
-
import { useMemo as
|
|
2
|
+
import { useMemo as useMemo18, useState as useState17, useEffect as useEffect16, useCallback as useCallback20, useRef as useRef12 } from "react";
|
|
3
3
|
import { cloneDeep as cloneDeep2, isEqual, debounce } from "lodash";
|
|
4
4
|
|
|
5
5
|
// src/core/utils/idx.ts
|
|
@@ -212,6 +212,117 @@ function formatOpenHouseTime(time24) {
|
|
|
212
212
|
return `${hour12}${period}`;
|
|
213
213
|
}
|
|
214
214
|
|
|
215
|
+
// src/core/editor/constant/configuration.ts
|
|
216
|
+
import { AlignCenterIcon, AlignJustifyIcon, AlignLeftIcon, AlignRightIcon, Heading1Icon, Heading2Icon, Heading3Icon, LinkIcon, ListIcon, ListOrderedIcon, MailIcon, PhoneIcon, Pilcrow } from "lucide-react";
|
|
217
|
+
var MAX_TEMPLATE_SIZE = 50 * 1024;
|
|
218
|
+
var BUTTON_ALIGNMENTS = ["left", "center", "right"];
|
|
219
|
+
var ALIGNMENT_ICONS = {
|
|
220
|
+
left: "https://mzyngaqmbvhpgmmipndy.supabase.co/storage/v1/object/public/Maillow/icons/align-vertical-space-around-left.svg",
|
|
221
|
+
center: "https://mzyngaqmbvhpgmmipndy.supabase.co/storage/v1/object/public/Maillow/icons/align-vertical-space-around-center.svg",
|
|
222
|
+
right: "https://mzyngaqmbvhpgmmipndy.supabase.co/storage/v1/object/public/Maillow/icons/align-vertical-space-around-right.svg"
|
|
223
|
+
};
|
|
224
|
+
var FONTS = [
|
|
225
|
+
"Arial",
|
|
226
|
+
"Helvetica",
|
|
227
|
+
"Times New Roman",
|
|
228
|
+
"Courier New",
|
|
229
|
+
"Verdana",
|
|
230
|
+
"Tahoma",
|
|
231
|
+
"Trebuchet MS",
|
|
232
|
+
"Georgia"
|
|
233
|
+
];
|
|
234
|
+
var TEXT_ALIGNMENT_ICONS = {
|
|
235
|
+
left: AlignLeftIcon,
|
|
236
|
+
center: AlignCenterIcon,
|
|
237
|
+
right: AlignRightIcon,
|
|
238
|
+
justify: AlignJustifyIcon
|
|
239
|
+
};
|
|
240
|
+
var TEXT_TYPE_OPTIONS = [
|
|
241
|
+
{ type: "paragraph", label: "Paragraph", Icon: Pilcrow, disabled: false },
|
|
242
|
+
{ type: "h1", label: "Heading 1", Icon: Heading1Icon, disabled: false },
|
|
243
|
+
{ type: "h2", label: "Heading 2", Icon: Heading2Icon, disabled: false },
|
|
244
|
+
{ type: "h3", label: "Heading 3", Icon: Heading3Icon, disabled: false },
|
|
245
|
+
{ type: "list", label: "Bulleted", Icon: ListIcon, disabled: true },
|
|
246
|
+
{ type: "ordered", label: "Numbered", Icon: ListOrderedIcon, disabled: true }
|
|
247
|
+
];
|
|
248
|
+
var DEFAULT_FONT_SIZE = 14;
|
|
249
|
+
var MIN_FONT_SIZE = 6;
|
|
250
|
+
var MAX_FONT_SIZE = 72;
|
|
251
|
+
var FONT_SIZE_STEP = 1;
|
|
252
|
+
var LINK_TYPES = [
|
|
253
|
+
{
|
|
254
|
+
name: "Email",
|
|
255
|
+
placeholder: "email@example.com",
|
|
256
|
+
icon: MailIcon,
|
|
257
|
+
inputType: "email",
|
|
258
|
+
prefix: "mailto:"
|
|
259
|
+
},
|
|
260
|
+
{
|
|
261
|
+
name: "Website",
|
|
262
|
+
placeholder: "https://example.com",
|
|
263
|
+
icon: LinkIcon,
|
|
264
|
+
inputType: "url",
|
|
265
|
+
prefix: ""
|
|
266
|
+
},
|
|
267
|
+
{
|
|
268
|
+
name: "Phone",
|
|
269
|
+
placeholder: "+1234567890",
|
|
270
|
+
icon: PhoneIcon,
|
|
271
|
+
inputType: "tel",
|
|
272
|
+
prefix: "tel:"
|
|
273
|
+
}
|
|
274
|
+
];
|
|
275
|
+
var LINK_PRESETS = {
|
|
276
|
+
Phone: [
|
|
277
|
+
{ label: "Personal Phone", key: "personal_phone_number" },
|
|
278
|
+
{ label: "Office Phone", key: "office_phone_number" },
|
|
279
|
+
{ label: "Business Phone", key: "business_phone_number" }
|
|
280
|
+
],
|
|
281
|
+
Website: [
|
|
282
|
+
{ label: "Team Website", key: "team_website" },
|
|
283
|
+
{ label: "Brokerage Website", key: "brokerage_website" }
|
|
284
|
+
]
|
|
285
|
+
};
|
|
286
|
+
var detectLinkType = (href) => {
|
|
287
|
+
if (href.startsWith("mailto:")) return LINK_TYPES[0];
|
|
288
|
+
if (href.startsWith("tel:")) return LINK_TYPES[2];
|
|
289
|
+
return LINK_TYPES[1];
|
|
290
|
+
};
|
|
291
|
+
var stripPrefix = (href) => {
|
|
292
|
+
if (href.startsWith("mailto:")) return href.slice(7);
|
|
293
|
+
if (href.startsWith("tel:")) return href.slice(4);
|
|
294
|
+
return href;
|
|
295
|
+
};
|
|
296
|
+
var normalizeWebsiteUrl = (url) => {
|
|
297
|
+
if (!url) return "";
|
|
298
|
+
if (url.match(/^https?:\/\//i)) return url;
|
|
299
|
+
if (url.startsWith("mailto:") || url.startsWith("tel:")) return url;
|
|
300
|
+
return "https://" + url;
|
|
301
|
+
};
|
|
302
|
+
var DEFAULT_LETTER_SPACING = 0;
|
|
303
|
+
var MIN_LETTER_SPACING = -2;
|
|
304
|
+
var MAX_LETTER_SPACING = 10;
|
|
305
|
+
var LETTER_SPACING_STEP = 0.1;
|
|
306
|
+
var DEFAULT_LINE_HEIGHT = 1.4;
|
|
307
|
+
var MIN_LINE_HEIGHT = 0.8;
|
|
308
|
+
var MAX_LINE_HEIGHT = 3;
|
|
309
|
+
var LINE_HEIGHT_STEP = 0.1;
|
|
310
|
+
var HIDDEN_SELECTION_VISUAL_ELEMENTS = ["text", "divider", "column"];
|
|
311
|
+
var NOT_DRAGGABLE_ELEMENTS = ["page", "social-item", "text", "property-card", "property-card-single-two", "property-card-triple", "property-card-triple-item"];
|
|
312
|
+
var EDITOR_COLORS = {
|
|
313
|
+
/** Purple — drag/drop state */
|
|
314
|
+
drag: {
|
|
315
|
+
solid: "rgb(59, 130, 246)",
|
|
316
|
+
half: "rgba(59, 130, 246, 0.5)"
|
|
317
|
+
},
|
|
318
|
+
/** Blue — hover/selection state */
|
|
319
|
+
hover: {
|
|
320
|
+
solid: "rgb(59, 130, 246)",
|
|
321
|
+
half: "rgba(59, 130, 246, 0.5)"
|
|
322
|
+
}
|
|
323
|
+
};
|
|
324
|
+
var DEFAULT_PROPERTY_PLACEHOLDER_IMAGE = "https://cornerstonepropertymgmt.com/wp-content/themes/cornerstone/assets/img/nofeaturedimage.jpg";
|
|
325
|
+
|
|
215
326
|
// src/render/Mockup/mock-property-better.ts
|
|
216
327
|
function propertyCardMockMjml(block, context) {
|
|
217
328
|
const a = block.attributes;
|
|
@@ -225,7 +336,7 @@ function propertyCardMockMjml(block, context) {
|
|
|
225
336
|
const baths = formatNumber(a["baths"] || "");
|
|
226
337
|
const sqft = formatNumber(a["sqft"] || "");
|
|
227
338
|
const description = a["description"] || "";
|
|
228
|
-
const imageSrc = a["image-src"] ||
|
|
339
|
+
const imageSrc = a["image-src"] || DEFAULT_PROPERTY_PLACEHOLDER_IMAGE;
|
|
229
340
|
const imageAlt = a["image-alt"] || "Photo of a Property";
|
|
230
341
|
const status = a["status"] || "Empty";
|
|
231
342
|
const statusColor = a["status-color"] || "#B8B8B8";
|
|
@@ -393,7 +504,7 @@ function propertyCardSingleTwoMockMjml(block, context) {
|
|
|
393
504
|
const baths = formatNumber(a["baths"] || "");
|
|
394
505
|
const sqft = formatNumber(a["sqft"] || "");
|
|
395
506
|
const description = a["description"] || "";
|
|
396
|
-
const imageSrc = a["image-src"] ||
|
|
507
|
+
const imageSrc = a["image-src"] || DEFAULT_PROPERTY_PLACEHOLDER_IMAGE;
|
|
397
508
|
const imageAlt = a["image-alt"] || "Photo of a Property";
|
|
398
509
|
const status = a["status"] || "Empty";
|
|
399
510
|
const statusColor = a["status-color"] || "#B8B8B8";
|
|
@@ -583,7 +694,7 @@ function renderCard(child, childIdx, context, uniqueId, borderRadius, imageHeigh
|
|
|
583
694
|
const baths = formatNumber(attrs["baths"] || "--");
|
|
584
695
|
const sqft = formatNumber(attrs["sqft"] || "--");
|
|
585
696
|
const city = attrs["city"] || "City";
|
|
586
|
-
const imageSrc = attrs["image-src"] ||
|
|
697
|
+
const imageSrc = attrs["image-src"] || DEFAULT_PROPERTY_PLACEHOLDER_IMAGE;
|
|
587
698
|
const childTrackingClasses = context.mode === "editing" ? getTrackingClasses(childIdx, "property-card-triple-item") : "";
|
|
588
699
|
return `
|
|
589
700
|
<table class="property-triple-card-${uniqueId} property-triple-table ${childTrackingClasses}" role="presentation" align="center" cellpadding="0" cellspacing="0" border="0" style="width:100%; border:${border}; border-radius:${borderRadius}; border-collapse:separate;${backgroundColor !== "transparent" ? ` background-color:${backgroundColor};` : ""}">
|
|
@@ -1249,7 +1360,7 @@ function createImageElement(payload) {
|
|
|
1249
1360
|
type: "image",
|
|
1250
1361
|
tagName: "mj-image",
|
|
1251
1362
|
attributes: {
|
|
1252
|
-
src: "https://
|
|
1363
|
+
src: "https://mzyngaqmbvhpgmmipndy.supabase.co/storage/v1/object/public/Maillow/placeholder_image.png",
|
|
1253
1364
|
alt: "",
|
|
1254
1365
|
padding: "0px 0px",
|
|
1255
1366
|
"fluid-on-mobile": "true",
|
|
@@ -1397,7 +1508,7 @@ function createPropertyCardElement(payload) {
|
|
|
1397
1508
|
tagName: "mj-colproperty",
|
|
1398
1509
|
data: { value: {} },
|
|
1399
1510
|
attributes: {
|
|
1400
|
-
"image-src":
|
|
1511
|
+
"image-src": DEFAULT_PROPERTY_PLACEHOLDER_IMAGE,
|
|
1401
1512
|
"image-alt": "Property image",
|
|
1402
1513
|
"price": "$0",
|
|
1403
1514
|
"address": "123 Main Street",
|
|
@@ -1426,7 +1537,7 @@ function createPropertyCardSingleTwoElement(payload) {
|
|
|
1426
1537
|
tagName: "mj-propertysingletwo",
|
|
1427
1538
|
data: { value: {} },
|
|
1428
1539
|
attributes: {
|
|
1429
|
-
"image-src":
|
|
1540
|
+
"image-src": DEFAULT_PROPERTY_PLACEHOLDER_IMAGE,
|
|
1430
1541
|
"image-alt": "Property image",
|
|
1431
1542
|
"price": "$0",
|
|
1432
1543
|
"address": "123 Main Street",
|
|
@@ -1521,7 +1632,7 @@ function createPropertyCardTripleItemElement(payload) {
|
|
|
1521
1632
|
tagName: "mj-propertytripleitem",
|
|
1522
1633
|
data: { value: {} },
|
|
1523
1634
|
attributes: {
|
|
1524
|
-
"image-src": payload?.attributes?.["image-src"] ||
|
|
1635
|
+
"image-src": payload?.attributes?.["image-src"] || DEFAULT_PROPERTY_PLACEHOLDER_IMAGE,
|
|
1525
1636
|
"href": payload?.attributes?.["href"] || "",
|
|
1526
1637
|
"price": payload?.attributes?.["price"] || "$0",
|
|
1527
1638
|
"beds": payload?.attributes?.["beds"] || "--",
|
|
@@ -1685,7 +1796,6 @@ var empty_default = {
|
|
|
1685
1796
|
|
|
1686
1797
|
// src/core/editor/state/editor.ts
|
|
1687
1798
|
var SECTION_INDEX_REGEX = /^content\.children\.\[(\d+)\]/;
|
|
1688
|
-
var MAX_TEMPLATE_SIZE = 50 * 1024;
|
|
1689
1799
|
function calculateTemplateSize(template) {
|
|
1690
1800
|
const str = JSON.stringify(template);
|
|
1691
1801
|
return new Blob([str]).size;
|
|
@@ -1706,6 +1816,7 @@ var useEditorStore = create()(
|
|
|
1706
1816
|
onSave: null,
|
|
1707
1817
|
onToast: null,
|
|
1708
1818
|
onExit: null,
|
|
1819
|
+
onImageUpload: null,
|
|
1709
1820
|
previewMode: false,
|
|
1710
1821
|
focusIdx: null,
|
|
1711
1822
|
hoverIdx: null,
|
|
@@ -1714,6 +1825,7 @@ var useEditorStore = create()(
|
|
|
1714
1825
|
dataTransfer: null,
|
|
1715
1826
|
isScaling: false,
|
|
1716
1827
|
slashCommand: null,
|
|
1828
|
+
mergeFieldSuggestion: null,
|
|
1717
1829
|
textEditing: null,
|
|
1718
1830
|
pendingTextEditRequest: null,
|
|
1719
1831
|
tiptapEditor: null,
|
|
@@ -1732,21 +1844,27 @@ var useEditorStore = create()(
|
|
|
1732
1844
|
// User data
|
|
1733
1845
|
images: [],
|
|
1734
1846
|
userData: null,
|
|
1847
|
+
mergeFields: [],
|
|
1735
1848
|
// Render sync
|
|
1736
1849
|
renderSyncNeeded: 0,
|
|
1737
1850
|
// Initialize store with external template (for npm package usage)
|
|
1738
|
-
initializeWithTemplate: (templateId, template, onSave, onToast, data, onExit) => {
|
|
1851
|
+
initializeWithTemplate: (templateId, template, onSave, onToast, data, onExit, onImageUpload) => {
|
|
1739
1852
|
set((state) => {
|
|
1740
1853
|
state.templateId = templateId;
|
|
1741
1854
|
state.template = template;
|
|
1742
1855
|
state.onSave = onSave ?? null;
|
|
1743
1856
|
state.onToast = onToast ?? null;
|
|
1744
1857
|
state.onExit = onExit ?? null;
|
|
1858
|
+
state.onImageUpload = onImageUpload ?? null;
|
|
1745
1859
|
state.isPaidLevel = data?.isPaidLevel ?? 0;
|
|
1746
1860
|
state.images = data?.images ?? [];
|
|
1747
1861
|
state.userData = data?.userData ?? null;
|
|
1862
|
+
state.mergeFields = (data?.mergefields ?? []).map((f) => ({
|
|
1863
|
+
label: (f.name || "").replace(/_/g, " ").replace(/\b\w/g, (c) => c.toUpperCase()),
|
|
1864
|
+
value: (f.merge_tag || "").replace(/^\{\{|\}\}$/g, "")
|
|
1865
|
+
}));
|
|
1748
1866
|
state.templateSize = calculateTemplateSize(template);
|
|
1749
|
-
state.isAtSizeLimit =
|
|
1867
|
+
state.isAtSizeLimit = state.templateSize >= MAX_TEMPLATE_SIZE;
|
|
1750
1868
|
state.history = [cloneDeep(template)];
|
|
1751
1869
|
state.historyIndex = 0;
|
|
1752
1870
|
state.focusIdx = null;
|
|
@@ -1755,6 +1873,11 @@ var useEditorStore = create()(
|
|
|
1755
1873
|
state.lastSavedSnapshot = JSON.stringify(template);
|
|
1756
1874
|
});
|
|
1757
1875
|
},
|
|
1876
|
+
addImage: (image2) => {
|
|
1877
|
+
set((state) => {
|
|
1878
|
+
state.images.push(castDraft(image2));
|
|
1879
|
+
});
|
|
1880
|
+
},
|
|
1758
1881
|
// Template metadata actions
|
|
1759
1882
|
setTemplateName: (name) => {
|
|
1760
1883
|
set((state) => {
|
|
@@ -1835,6 +1958,17 @@ var useEditorStore = create()(
|
|
|
1835
1958
|
}, 0);
|
|
1836
1959
|
}
|
|
1837
1960
|
},
|
|
1961
|
+
// Merge field suggestion actions
|
|
1962
|
+
setMergeFieldSuggestion: (suggestionState) => {
|
|
1963
|
+
set((state) => {
|
|
1964
|
+
state.mergeFieldSuggestion = suggestionState;
|
|
1965
|
+
});
|
|
1966
|
+
},
|
|
1967
|
+
clearMergeFieldSuggestion: () => {
|
|
1968
|
+
set((state) => {
|
|
1969
|
+
state.mergeFieldSuggestion = null;
|
|
1970
|
+
});
|
|
1971
|
+
},
|
|
1838
1972
|
// Text editing actions (Tiptap overlay)
|
|
1839
1973
|
startTextEditing: (textEditingState) => {
|
|
1840
1974
|
set((state) => {
|
|
@@ -2913,117 +3047,6 @@ function setValueAtPath(template, path, value) {
|
|
|
2913
3047
|
|
|
2914
3048
|
// src/core/editor/components/ShadowDomRenderer.tsx
|
|
2915
3049
|
import { useEffect, useRef, memo } from "react";
|
|
2916
|
-
|
|
2917
|
-
// src/core/editor/constant/configuration.ts
|
|
2918
|
-
import { AlignCenterIcon, AlignJustifyIcon, AlignLeftIcon, AlignRightIcon, Heading1Icon, Heading2Icon, Heading3Icon, LinkIcon, ListIcon, ListOrderedIcon, MailIcon, PhoneIcon, Pilcrow } from "lucide-react";
|
|
2919
|
-
var BUTTON_ALIGNMENTS = ["left", "center", "right"];
|
|
2920
|
-
var ALIGNMENT_ICONS = {
|
|
2921
|
-
left: "https://mzyngaqmbvhpgmmipndy.supabase.co/storage/v1/object/public/Maillow/icons/align-vertical-space-around-left.svg",
|
|
2922
|
-
center: "https://mzyngaqmbvhpgmmipndy.supabase.co/storage/v1/object/public/Maillow/icons/align-vertical-space-around-center.svg",
|
|
2923
|
-
right: "https://mzyngaqmbvhpgmmipndy.supabase.co/storage/v1/object/public/Maillow/icons/align-vertical-space-around-right.svg"
|
|
2924
|
-
};
|
|
2925
|
-
var FONTS = [
|
|
2926
|
-
"Arial",
|
|
2927
|
-
"Helvetica",
|
|
2928
|
-
"Times New Roman",
|
|
2929
|
-
"Courier New",
|
|
2930
|
-
"Verdana",
|
|
2931
|
-
"Tahoma",
|
|
2932
|
-
"Trebuchet MS",
|
|
2933
|
-
"Georgia"
|
|
2934
|
-
];
|
|
2935
|
-
var TEXT_ALIGNMENT_ICONS = {
|
|
2936
|
-
left: AlignLeftIcon,
|
|
2937
|
-
center: AlignCenterIcon,
|
|
2938
|
-
right: AlignRightIcon,
|
|
2939
|
-
justify: AlignJustifyIcon
|
|
2940
|
-
};
|
|
2941
|
-
var TEXT_TYPE_OPTIONS = [
|
|
2942
|
-
{ type: "paragraph", label: "Paragraph", Icon: Pilcrow, disabled: false },
|
|
2943
|
-
{ type: "h1", label: "Heading 1", Icon: Heading1Icon, disabled: false },
|
|
2944
|
-
{ type: "h2", label: "Heading 2", Icon: Heading2Icon, disabled: false },
|
|
2945
|
-
{ type: "h3", label: "Heading 3", Icon: Heading3Icon, disabled: false },
|
|
2946
|
-
{ type: "list", label: "Bulleted", Icon: ListIcon, disabled: true },
|
|
2947
|
-
{ type: "ordered", label: "Numbered", Icon: ListOrderedIcon, disabled: true }
|
|
2948
|
-
];
|
|
2949
|
-
var DEFAULT_FONT_SIZE = 14;
|
|
2950
|
-
var MIN_FONT_SIZE = 6;
|
|
2951
|
-
var MAX_FONT_SIZE = 72;
|
|
2952
|
-
var FONT_SIZE_STEP = 1;
|
|
2953
|
-
var LINK_TYPES = [
|
|
2954
|
-
{
|
|
2955
|
-
name: "Email",
|
|
2956
|
-
placeholder: "email@example.com",
|
|
2957
|
-
icon: MailIcon,
|
|
2958
|
-
inputType: "email",
|
|
2959
|
-
prefix: "mailto:"
|
|
2960
|
-
},
|
|
2961
|
-
{
|
|
2962
|
-
name: "Website",
|
|
2963
|
-
placeholder: "https://example.com",
|
|
2964
|
-
icon: LinkIcon,
|
|
2965
|
-
inputType: "url",
|
|
2966
|
-
prefix: ""
|
|
2967
|
-
},
|
|
2968
|
-
{
|
|
2969
|
-
name: "Phone",
|
|
2970
|
-
placeholder: "+1234567890",
|
|
2971
|
-
icon: PhoneIcon,
|
|
2972
|
-
inputType: "tel",
|
|
2973
|
-
prefix: "tel:"
|
|
2974
|
-
}
|
|
2975
|
-
];
|
|
2976
|
-
var LINK_PRESETS = {
|
|
2977
|
-
Phone: [
|
|
2978
|
-
{ label: "Personal Phone", key: "personal_phone_number" },
|
|
2979
|
-
{ label: "Office Phone", key: "office_phone_number" },
|
|
2980
|
-
{ label: "Business Phone", key: "business_phone_number" }
|
|
2981
|
-
],
|
|
2982
|
-
Website: [
|
|
2983
|
-
{ label: "Team Website", key: "team_website" },
|
|
2984
|
-
{ label: "Brokerage Website", key: "brokerage_website" }
|
|
2985
|
-
]
|
|
2986
|
-
};
|
|
2987
|
-
var detectLinkType = (href) => {
|
|
2988
|
-
if (href.startsWith("mailto:")) return LINK_TYPES[0];
|
|
2989
|
-
if (href.startsWith("tel:")) return LINK_TYPES[2];
|
|
2990
|
-
return LINK_TYPES[1];
|
|
2991
|
-
};
|
|
2992
|
-
var stripPrefix = (href) => {
|
|
2993
|
-
if (href.startsWith("mailto:")) return href.slice(7);
|
|
2994
|
-
if (href.startsWith("tel:")) return href.slice(4);
|
|
2995
|
-
return href;
|
|
2996
|
-
};
|
|
2997
|
-
var normalizeWebsiteUrl = (url) => {
|
|
2998
|
-
if (!url) return "";
|
|
2999
|
-
if (url.match(/^https?:\/\//i)) return url;
|
|
3000
|
-
if (url.startsWith("mailto:") || url.startsWith("tel:")) return url;
|
|
3001
|
-
return "https://" + url;
|
|
3002
|
-
};
|
|
3003
|
-
var DEFAULT_LETTER_SPACING = 0;
|
|
3004
|
-
var MIN_LETTER_SPACING = -2;
|
|
3005
|
-
var MAX_LETTER_SPACING = 10;
|
|
3006
|
-
var LETTER_SPACING_STEP = 0.1;
|
|
3007
|
-
var DEFAULT_LINE_HEIGHT = 1.4;
|
|
3008
|
-
var MIN_LINE_HEIGHT = 0.8;
|
|
3009
|
-
var MAX_LINE_HEIGHT = 3;
|
|
3010
|
-
var LINE_HEIGHT_STEP = 0.1;
|
|
3011
|
-
var HIDDEN_SELECTION_VISUAL_ELEMENTS = ["text", "divider", "column"];
|
|
3012
|
-
var NOT_DRAGGABLE_ELEMENTS = ["page", "social-item", "text", "property-card", "property-card-single-two", "property-card-triple", "property-card-triple-item"];
|
|
3013
|
-
var EDITOR_COLORS = {
|
|
3014
|
-
/** Purple — drag/drop state */
|
|
3015
|
-
drag: {
|
|
3016
|
-
solid: "rgb(59, 130, 246)",
|
|
3017
|
-
half: "rgba(59, 130, 246, 0.5)"
|
|
3018
|
-
},
|
|
3019
|
-
/** Blue — hover/selection state */
|
|
3020
|
-
hover: {
|
|
3021
|
-
solid: "rgb(59, 130, 246)",
|
|
3022
|
-
half: "rgba(59, 130, 246, 0.5)"
|
|
3023
|
-
}
|
|
3024
|
-
};
|
|
3025
|
-
|
|
3026
|
-
// src/core/editor/components/ShadowDomRenderer.tsx
|
|
3027
3050
|
import { Fragment, jsx, jsxs } from "react/jsx-runtime";
|
|
3028
3051
|
var lastSizeLimitToastTime = 0;
|
|
3029
3052
|
var cssCache = /* @__PURE__ */ new Map();
|
|
@@ -3358,6 +3381,19 @@ function getEditorStyles(isDragButtonHovered, textEditingIdx) {
|
|
|
3358
3381
|
}
|
|
3359
3382
|
` : ""}
|
|
3360
3383
|
|
|
3384
|
+
/* Merge field tags - dashed underline for {{variable}} patterns */
|
|
3385
|
+
.merge-field-tag {
|
|
3386
|
+
|
|
3387
|
+
background-color: var(--background);
|
|
3388
|
+
border-radius: 4px;
|
|
3389
|
+
padding: 0px;
|
|
3390
|
+
border: 1px solid var(--border);
|
|
3391
|
+
color: #000000;
|
|
3392
|
+
}
|
|
3393
|
+
.merge-field-tag:hover {
|
|
3394
|
+
cursor: pointer;
|
|
3395
|
+
}
|
|
3396
|
+
|
|
3361
3397
|
/* Company footer - hide selection/hover outlines and make non-interactive */
|
|
3362
3398
|
.is-company-footer,
|
|
3363
3399
|
.is-company-footer .${EMAIL_BLOCK_CLASS_NAME} {
|
|
@@ -3983,6 +4019,7 @@ function isTextContentEmpty(element) {
|
|
|
3983
4019
|
const text2 = element.textContent?.trim() || "";
|
|
3984
4020
|
return text2.length === 0;
|
|
3985
4021
|
}
|
|
4022
|
+
var MERGE_FIELD_REGEX_SHADOW = /\{\{[a-zA-Z_][a-zA-Z0-9_]*\}\}/g;
|
|
3986
4023
|
function isParagraphEmpty(p) {
|
|
3987
4024
|
const text2 = p.textContent || "";
|
|
3988
4025
|
return text2.trim() === "" || text2 === "\xA0" || text2 === " ";
|
|
@@ -4004,6 +4041,40 @@ function injectContentEditable(container) {
|
|
|
4004
4041
|
}
|
|
4005
4042
|
}
|
|
4006
4043
|
});
|
|
4044
|
+
if (contentDiv.textContent?.includes("{{")) {
|
|
4045
|
+
const walker = document.createTreeWalker(contentDiv, NodeFilter.SHOW_TEXT);
|
|
4046
|
+
const textNodes = [];
|
|
4047
|
+
let tNode;
|
|
4048
|
+
while (tNode = walker.nextNode()) {
|
|
4049
|
+
if (tNode.textContent && MERGE_FIELD_REGEX_SHADOW.test(tNode.textContent)) {
|
|
4050
|
+
textNodes.push(tNode);
|
|
4051
|
+
}
|
|
4052
|
+
MERGE_FIELD_REGEX_SHADOW.lastIndex = 0;
|
|
4053
|
+
}
|
|
4054
|
+
for (const textNode of textNodes) {
|
|
4055
|
+
const text2 = textNode.textContent || "";
|
|
4056
|
+
const fragment = document.createDocumentFragment();
|
|
4057
|
+
let lastIndex = 0;
|
|
4058
|
+
MERGE_FIELD_REGEX_SHADOW.lastIndex = 0;
|
|
4059
|
+
let match;
|
|
4060
|
+
while ((match = MERGE_FIELD_REGEX_SHADOW.exec(text2)) !== null) {
|
|
4061
|
+
if (match.index > lastIndex) {
|
|
4062
|
+
fragment.appendChild(document.createTextNode(text2.slice(lastIndex, match.index)));
|
|
4063
|
+
}
|
|
4064
|
+
const span = document.createElement("span");
|
|
4065
|
+
span.className = "merge-field-tag";
|
|
4066
|
+
const fieldName = match[0].slice(2, -2);
|
|
4067
|
+
span.setAttribute("data-tooltip", fieldName.replace(/_/g, " ").replace(/\b\w/g, (c) => c.toUpperCase()));
|
|
4068
|
+
span.textContent = match[0];
|
|
4069
|
+
fragment.appendChild(span);
|
|
4070
|
+
lastIndex = match.index + match[0].length;
|
|
4071
|
+
}
|
|
4072
|
+
if (lastIndex < text2.length) {
|
|
4073
|
+
fragment.appendChild(document.createTextNode(text2.slice(lastIndex)));
|
|
4074
|
+
}
|
|
4075
|
+
textNode.parentNode?.replaceChild(fragment, textNode);
|
|
4076
|
+
}
|
|
4077
|
+
}
|
|
4007
4078
|
}
|
|
4008
4079
|
});
|
|
4009
4080
|
container.querySelectorAll(".node-type-button").forEach((buttonEl) => {
|
|
@@ -4825,20 +4896,172 @@ var ElementsSuggestionsContent = () => {
|
|
|
4825
4896
|
);
|
|
4826
4897
|
};
|
|
4827
4898
|
|
|
4828
|
-
// src/core/editor/components/
|
|
4829
|
-
import {
|
|
4830
|
-
import {
|
|
4831
|
-
import {
|
|
4832
|
-
import
|
|
4833
|
-
|
|
4834
|
-
|
|
4835
|
-
|
|
4836
|
-
|
|
4837
|
-
|
|
4838
|
-
|
|
4839
|
-
|
|
4840
|
-
|
|
4841
|
-
|
|
4899
|
+
// src/core/editor/components/merge-field-suggestions.tsx
|
|
4900
|
+
import { useMemo as useMemo3, useEffect as useEffect4, useRef as useRef3, useState, useCallback as useCallback3 } from "react";
|
|
4901
|
+
import { useFloating as useFloating3, offset as offset3, shift as shift3, flip as flip2 } from "@floating-ui/react";
|
|
4902
|
+
import { BracesIcon } from "lucide-react";
|
|
4903
|
+
import { jsx as jsx14, jsxs as jsxs5 } from "react/jsx-runtime";
|
|
4904
|
+
var MergeFieldSuggestions = () => {
|
|
4905
|
+
const isActive = useEditorStore((state) => state.mergeFieldSuggestion?.isActive);
|
|
4906
|
+
if (!isActive) return null;
|
|
4907
|
+
return /* @__PURE__ */ jsx14(MergeFieldSuggestionsContent, {});
|
|
4908
|
+
};
|
|
4909
|
+
var MergeFieldSuggestionsContent = () => {
|
|
4910
|
+
const mergeFieldSuggestion = useEditorStore((state) => state.mergeFieldSuggestion);
|
|
4911
|
+
const clearMergeFieldSuggestion = useEditorStore((state) => state.clearMergeFieldSuggestion);
|
|
4912
|
+
const tiptapEditor = useEditorStore((state) => state.tiptapEditor);
|
|
4913
|
+
const mergeFields = useEditorStore((state) => state.mergeFields);
|
|
4914
|
+
const containerRef = useRef3(null);
|
|
4915
|
+
const [searchQuery, setSearchQuery] = useState("");
|
|
4916
|
+
useEffect4(() => {
|
|
4917
|
+
if (!tiptapEditor || !mergeFieldSuggestion) return;
|
|
4918
|
+
const updateQuery = () => {
|
|
4919
|
+
const { from } = tiptapEditor.state.selection;
|
|
4920
|
+
const triggerEnd = mergeFieldSuggestion.triggerPosition + 2;
|
|
4921
|
+
if (from > triggerEnd) {
|
|
4922
|
+
const typed = tiptapEditor.state.doc.textBetween(triggerEnd, from);
|
|
4923
|
+
setSearchQuery(typed);
|
|
4924
|
+
} else {
|
|
4925
|
+
setSearchQuery("");
|
|
4926
|
+
}
|
|
4927
|
+
};
|
|
4928
|
+
updateQuery();
|
|
4929
|
+
tiptapEditor.on("selectionUpdate", updateQuery);
|
|
4930
|
+
tiptapEditor.on("update", updateQuery);
|
|
4931
|
+
return () => {
|
|
4932
|
+
tiptapEditor.off("selectionUpdate", updateQuery);
|
|
4933
|
+
tiptapEditor.off("update", updateQuery);
|
|
4934
|
+
};
|
|
4935
|
+
}, [tiptapEditor, mergeFieldSuggestion]);
|
|
4936
|
+
const filteredFields = useMemo3(() => {
|
|
4937
|
+
if (!searchQuery) return mergeFields;
|
|
4938
|
+
const q = searchQuery.toLowerCase();
|
|
4939
|
+
return mergeFields.filter(
|
|
4940
|
+
(f) => f.label.toLowerCase().includes(q) || f.value.toLowerCase().includes(q)
|
|
4941
|
+
);
|
|
4942
|
+
}, [searchQuery, mergeFields]);
|
|
4943
|
+
const handleSelect = useCallback3((fieldValue) => {
|
|
4944
|
+
if (!tiptapEditor || !mergeFieldSuggestion) return;
|
|
4945
|
+
const { from } = tiptapEditor.state.selection;
|
|
4946
|
+
const triggerPos = mergeFieldSuggestion.triggerPosition;
|
|
4947
|
+
tiptapEditor.chain().focus().deleteRange({ from: triggerPos, to: from }).insertContent(`{{${fieldValue}}}`).run();
|
|
4948
|
+
clearMergeFieldSuggestion();
|
|
4949
|
+
}, [tiptapEditor, mergeFieldSuggestion, clearMergeFieldSuggestion]);
|
|
4950
|
+
const virtualReference = useMemo3(() => ({
|
|
4951
|
+
getBoundingClientRect: () => {
|
|
4952
|
+
if (!mergeFieldSuggestion?.cursorRect) {
|
|
4953
|
+
return { x: 0, y: 0, top: 0, left: 0, bottom: 0, right: 0, width: 0, height: 0, toJSON: () => ({}) };
|
|
4954
|
+
}
|
|
4955
|
+
const { top, left, height } = mergeFieldSuggestion.cursorRect;
|
|
4956
|
+
return {
|
|
4957
|
+
x: left,
|
|
4958
|
+
y: top,
|
|
4959
|
+
top,
|
|
4960
|
+
left,
|
|
4961
|
+
bottom: top + height,
|
|
4962
|
+
right: left,
|
|
4963
|
+
width: 0,
|
|
4964
|
+
height,
|
|
4965
|
+
toJSON: () => ({})
|
|
4966
|
+
};
|
|
4967
|
+
}
|
|
4968
|
+
}), [mergeFieldSuggestion?.cursorRect]);
|
|
4969
|
+
const { floatingStyles, refs, update } = useFloating3({
|
|
4970
|
+
placement: "bottom-start",
|
|
4971
|
+
middleware: [
|
|
4972
|
+
offset3(4),
|
|
4973
|
+
flip2({ padding: 8 }),
|
|
4974
|
+
shift3({ padding: 8 })
|
|
4975
|
+
]
|
|
4976
|
+
});
|
|
4977
|
+
const floatingRefsRef = useRef3(refs);
|
|
4978
|
+
useEffect4(() => {
|
|
4979
|
+
floatingRefsRef.current = refs;
|
|
4980
|
+
}, [refs]);
|
|
4981
|
+
useEffect4(() => {
|
|
4982
|
+
if (mergeFieldSuggestion?.cursorRect) {
|
|
4983
|
+
floatingRefsRef.current.setPositionReference(virtualReference);
|
|
4984
|
+
update();
|
|
4985
|
+
}
|
|
4986
|
+
}, [mergeFieldSuggestion?.cursorRect, virtualReference, update]);
|
|
4987
|
+
const clearRef = useRef3(clearMergeFieldSuggestion);
|
|
4988
|
+
useEffect4(() => {
|
|
4989
|
+
clearRef.current = clearMergeFieldSuggestion;
|
|
4990
|
+
}, [clearMergeFieldSuggestion]);
|
|
4991
|
+
useEffect4(() => {
|
|
4992
|
+
const handleClickOutside = (e) => {
|
|
4993
|
+
if (containerRef.current && !containerRef.current.contains(e.target)) {
|
|
4994
|
+
clearRef.current();
|
|
4995
|
+
}
|
|
4996
|
+
};
|
|
4997
|
+
const timeoutId = setTimeout(() => {
|
|
4998
|
+
document.addEventListener("mousedown", handleClickOutside);
|
|
4999
|
+
}, 0);
|
|
5000
|
+
return () => {
|
|
5001
|
+
clearTimeout(timeoutId);
|
|
5002
|
+
document.removeEventListener("mousedown", handleClickOutside);
|
|
5003
|
+
};
|
|
5004
|
+
}, []);
|
|
5005
|
+
useEffect4(() => {
|
|
5006
|
+
const handleEscape = (e) => {
|
|
5007
|
+
if (e.key === "Escape") {
|
|
5008
|
+
clearRef.current();
|
|
5009
|
+
}
|
|
5010
|
+
};
|
|
5011
|
+
document.addEventListener("keydown", handleEscape);
|
|
5012
|
+
return () => document.removeEventListener("keydown", handleEscape);
|
|
5013
|
+
}, []);
|
|
5014
|
+
return /* @__PURE__ */ jsx14(
|
|
5015
|
+
"div",
|
|
5016
|
+
{
|
|
5017
|
+
ref: (node) => {
|
|
5018
|
+
containerRef.current = node;
|
|
5019
|
+
refs.setFloating(node);
|
|
5020
|
+
},
|
|
5021
|
+
style: {
|
|
5022
|
+
...floatingStyles,
|
|
5023
|
+
zIndex: 9999
|
|
5024
|
+
},
|
|
5025
|
+
className: "bg-popover border rounded-md shadow-md overflow-hidden",
|
|
5026
|
+
children: /* @__PURE__ */ jsx14(Command, { className: "w-[240px]", children: /* @__PURE__ */ jsxs5(CommandList, { className: "max-h-[300px]", children: [
|
|
5027
|
+
/* @__PURE__ */ jsx14(CommandEmpty, { children: "No matching fields." }),
|
|
5028
|
+
/* @__PURE__ */ jsx14(CommandGroup, { heading: "Merge fields", children: filteredFields.map(({ label, value }) => /* @__PURE__ */ jsxs5(
|
|
5029
|
+
CommandItem,
|
|
5030
|
+
{
|
|
5031
|
+
value,
|
|
5032
|
+
keywords: [label],
|
|
5033
|
+
className: "flex items-center gap-2 cursor-pointer",
|
|
5034
|
+
onSelect: () => handleSelect(value),
|
|
5035
|
+
onMouseDown: (e) => {
|
|
5036
|
+
e.preventDefault();
|
|
5037
|
+
handleSelect(value);
|
|
5038
|
+
},
|
|
5039
|
+
children: [
|
|
5040
|
+
/* @__PURE__ */ jsx14(BracesIcon, { className: "w-4 h-4" }),
|
|
5041
|
+
label
|
|
5042
|
+
]
|
|
5043
|
+
},
|
|
5044
|
+
value
|
|
5045
|
+
)) })
|
|
5046
|
+
] }) })
|
|
5047
|
+
}
|
|
5048
|
+
);
|
|
5049
|
+
};
|
|
5050
|
+
|
|
5051
|
+
// src/core/editor/components/tiptap-overlay.tsx
|
|
5052
|
+
import { useEditor, EditorContent } from "@tiptap/react";
|
|
5053
|
+
import { BubbleMenu } from "@tiptap/react/menus";
|
|
5054
|
+
import { TextSelection as TextSelection8 } from "@tiptap/pm/state";
|
|
5055
|
+
import StarterKit from "@tiptap/starter-kit";
|
|
5056
|
+
import { TextStyle, FontSize, LineHeight } from "@tiptap/extension-text-style";
|
|
5057
|
+
import { Color } from "@tiptap/extension-color";
|
|
5058
|
+
import TextAlign from "@tiptap/extension-text-align";
|
|
5059
|
+
import Underline from "@tiptap/extension-underline";
|
|
5060
|
+
|
|
5061
|
+
// node_modules/@tiptap/core/dist/index.js
|
|
5062
|
+
import { liftTarget } from "@tiptap/pm/transform";
|
|
5063
|
+
import { createParagraphNear as originalCreateParagraphNear } from "@tiptap/pm/commands";
|
|
5064
|
+
import { TextSelection } from "@tiptap/pm/state";
|
|
4842
5065
|
import { deleteSelection as originalDeleteSelection } from "@tiptap/pm/commands";
|
|
4843
5066
|
import { exitCode as originalExitCode } from "@tiptap/pm/commands";
|
|
4844
5067
|
import { TextSelection as TextSelection2 } from "@tiptap/pm/state";
|
|
@@ -5691,7 +5914,7 @@ function normalizeKeyName(name) {
|
|
|
5691
5914
|
}
|
|
5692
5915
|
let alt;
|
|
5693
5916
|
let ctrl;
|
|
5694
|
-
let
|
|
5917
|
+
let shift5;
|
|
5695
5918
|
let meta;
|
|
5696
5919
|
for (let i = 0; i < parts.length - 1; i += 1) {
|
|
5697
5920
|
const mod = parts[i];
|
|
@@ -5702,7 +5925,7 @@ function normalizeKeyName(name) {
|
|
|
5702
5925
|
} else if (/^(c|ctrl|control)$/i.test(mod)) {
|
|
5703
5926
|
ctrl = true;
|
|
5704
5927
|
} else if (/^s(hift)?$/i.test(mod)) {
|
|
5705
|
-
|
|
5928
|
+
shift5 = true;
|
|
5706
5929
|
} else if (/^mod$/i.test(mod)) {
|
|
5707
5930
|
if (isiOS() || isMacOS()) {
|
|
5708
5931
|
meta = true;
|
|
@@ -5722,7 +5945,7 @@ function normalizeKeyName(name) {
|
|
|
5722
5945
|
if (meta) {
|
|
5723
5946
|
result = `Meta-${result}`;
|
|
5724
5947
|
}
|
|
5725
|
-
if (
|
|
5948
|
+
if (shift5) {
|
|
5726
5949
|
result = `Shift-${result}`;
|
|
5727
5950
|
}
|
|
5728
5951
|
return result;
|
|
@@ -10574,8 +10797,8 @@ var Link = Mark.create({
|
|
|
10574
10797
|
var index_default = Link;
|
|
10575
10798
|
|
|
10576
10799
|
// src/core/editor/components/tiptap-overlay.tsx
|
|
10577
|
-
import { useFloating as
|
|
10578
|
-
import { useEffect as useEffect6, useRef as
|
|
10800
|
+
import { useFloating as useFloating4, autoUpdate as autoUpdate2, offset as offset4 } from "@floating-ui/react";
|
|
10801
|
+
import { useEffect as useEffect6, useRef as useRef5, useMemo as useMemo4, useState as useState3 } from "react";
|
|
10579
10802
|
|
|
10580
10803
|
// src/core/editor/extensions/inverse-placeholder.ts
|
|
10581
10804
|
import { Plugin as Plugin12, PluginKey as PluginKey10 } from "@tiptap/pm/state";
|
|
@@ -10785,25 +11008,69 @@ var HeadingParagraph = Node3.create({
|
|
|
10785
11008
|
}
|
|
10786
11009
|
});
|
|
10787
11010
|
|
|
11011
|
+
// src/core/editor/extensions/merge-field-decoration.ts
|
|
11012
|
+
import { Plugin as Plugin13, PluginKey as PluginKey11 } from "@tiptap/pm/state";
|
|
11013
|
+
import { Decoration as Decoration2, DecorationSet as DecorationSet2 } from "@tiptap/pm/view";
|
|
11014
|
+
var MERGE_FIELD_REGEX = /\{\{[a-zA-Z_][a-zA-Z0-9_]*\}\}/g;
|
|
11015
|
+
var MergeFieldDecoration = Extension.create({
|
|
11016
|
+
name: "mergeFieldDecoration",
|
|
11017
|
+
addProseMirrorPlugins() {
|
|
11018
|
+
let cached = null;
|
|
11019
|
+
return [
|
|
11020
|
+
new Plugin13({
|
|
11021
|
+
key: new PluginKey11("mergeFieldDecoration"),
|
|
11022
|
+
props: {
|
|
11023
|
+
decorations: (state) => {
|
|
11024
|
+
const { doc } = state;
|
|
11025
|
+
const docNodeSize = doc.nodeSize;
|
|
11026
|
+
if (cached && cached.docNodeSize === docNodeSize) {
|
|
11027
|
+
return cached.decorations;
|
|
11028
|
+
}
|
|
11029
|
+
const decorations = [];
|
|
11030
|
+
doc.descendants((node, pos) => {
|
|
11031
|
+
if (!node.isText || !node.text) return;
|
|
11032
|
+
MERGE_FIELD_REGEX.lastIndex = 0;
|
|
11033
|
+
let match;
|
|
11034
|
+
while ((match = MERGE_FIELD_REGEX.exec(node.text)) !== null) {
|
|
11035
|
+
const from = pos + match.index;
|
|
11036
|
+
const to = from + match[0].length;
|
|
11037
|
+
decorations.push(
|
|
11038
|
+
Decoration2.inline(from, to, { class: "merge-field-tag" })
|
|
11039
|
+
);
|
|
11040
|
+
}
|
|
11041
|
+
});
|
|
11042
|
+
const decorationSet = DecorationSet2.create(doc, decorations);
|
|
11043
|
+
cached = { docNodeSize, decorations: decorationSet };
|
|
11044
|
+
return decorationSet;
|
|
11045
|
+
}
|
|
11046
|
+
}
|
|
11047
|
+
})
|
|
11048
|
+
];
|
|
11049
|
+
}
|
|
11050
|
+
});
|
|
11051
|
+
|
|
10788
11052
|
// src/core/editor/hooks/use-editor-store-refs.ts
|
|
10789
|
-
import { useRef as
|
|
11053
|
+
import { useRef as useRef4, useEffect as useEffect5 } from "react";
|
|
10790
11054
|
function useEditorStoreRefs() {
|
|
10791
11055
|
const store = useEditorStore();
|
|
10792
11056
|
const refs = {
|
|
10793
|
-
stopTextEditing:
|
|
10794
|
-
updateElementContent:
|
|
10795
|
-
setSlashCommand:
|
|
10796
|
-
clearSlashCommand:
|
|
10797
|
-
findAdjacentElement:
|
|
10798
|
-
deleteElement:
|
|
10799
|
-
setFocusIdx:
|
|
10800
|
-
requestTextEditingOnElement:
|
|
10801
|
-
clearPendingTextEditRequest:
|
|
10802
|
-
template:
|
|
10803
|
-
slashCommand:
|
|
10804
|
-
|
|
11057
|
+
stopTextEditing: useRef4(store.stopTextEditing),
|
|
11058
|
+
updateElementContent: useRef4(store.updateElementContent),
|
|
11059
|
+
setSlashCommand: useRef4(store.setSlashCommand),
|
|
11060
|
+
clearSlashCommand: useRef4(store.clearSlashCommand),
|
|
11061
|
+
findAdjacentElement: useRef4(store.findAdjacentElement),
|
|
11062
|
+
deleteElement: useRef4(store.deleteElement),
|
|
11063
|
+
setFocusIdx: useRef4(store.setFocusIdx),
|
|
11064
|
+
requestTextEditingOnElement: useRef4(store.requestTextEditingOnElement),
|
|
11065
|
+
clearPendingTextEditRequest: useRef4(store.clearPendingTextEditRequest),
|
|
11066
|
+
template: useRef4(store.template),
|
|
11067
|
+
slashCommand: useRef4(store.slashCommand),
|
|
11068
|
+
mergeFieldSuggestion: useRef4(store.mergeFieldSuggestion),
|
|
11069
|
+
setMergeFieldSuggestion: useRef4(store.setMergeFieldSuggestion),
|
|
11070
|
+
clearMergeFieldSuggestion: useRef4(store.clearMergeFieldSuggestion),
|
|
11071
|
+
pushHistory: useRef4(store.pushHistory)
|
|
10805
11072
|
};
|
|
10806
|
-
|
|
11073
|
+
useEffect5(() => {
|
|
10807
11074
|
refs.stopTextEditing.current = store.stopTextEditing;
|
|
10808
11075
|
refs.updateElementContent.current = store.updateElementContent;
|
|
10809
11076
|
refs.setSlashCommand.current = store.setSlashCommand;
|
|
@@ -10815,6 +11082,9 @@ function useEditorStoreRefs() {
|
|
|
10815
11082
|
refs.clearPendingTextEditRequest.current = store.clearPendingTextEditRequest;
|
|
10816
11083
|
refs.template.current = store.template;
|
|
10817
11084
|
refs.slashCommand.current = store.slashCommand;
|
|
11085
|
+
refs.mergeFieldSuggestion.current = store.mergeFieldSuggestion;
|
|
11086
|
+
refs.setMergeFieldSuggestion.current = store.setMergeFieldSuggestion;
|
|
11087
|
+
refs.clearMergeFieldSuggestion.current = store.clearMergeFieldSuggestion;
|
|
10818
11088
|
refs.pushHistory.current = store.pushHistory;
|
|
10819
11089
|
}, [
|
|
10820
11090
|
store.stopTextEditing,
|
|
@@ -10828,6 +11098,9 @@ function useEditorStoreRefs() {
|
|
|
10828
11098
|
store.clearPendingTextEditRequest,
|
|
10829
11099
|
store.template,
|
|
10830
11100
|
store.slashCommand,
|
|
11101
|
+
store.mergeFieldSuggestion,
|
|
11102
|
+
store.setMergeFieldSuggestion,
|
|
11103
|
+
store.clearMergeFieldSuggestion,
|
|
10831
11104
|
store.pushHistory
|
|
10832
11105
|
]);
|
|
10833
11106
|
return refs;
|
|
@@ -10875,12 +11148,12 @@ function checkElementPosition(template, elementIdx) {
|
|
|
10875
11148
|
|
|
10876
11149
|
// src/components/ui/tooltip.tsx
|
|
10877
11150
|
import * as TooltipPrimitive from "@radix-ui/react-tooltip";
|
|
10878
|
-
import { jsx as
|
|
11151
|
+
import { jsx as jsx15, jsxs as jsxs6 } from "react/jsx-runtime";
|
|
10879
11152
|
function TooltipProvider({
|
|
10880
11153
|
delayDuration = 0,
|
|
10881
11154
|
...props
|
|
10882
11155
|
}) {
|
|
10883
|
-
return /* @__PURE__ */
|
|
11156
|
+
return /* @__PURE__ */ jsx15(
|
|
10884
11157
|
TooltipPrimitive.Provider,
|
|
10885
11158
|
{
|
|
10886
11159
|
"data-slot": "tooltip-provider",
|
|
@@ -10892,12 +11165,12 @@ function TooltipProvider({
|
|
|
10892
11165
|
function Tooltip({
|
|
10893
11166
|
...props
|
|
10894
11167
|
}) {
|
|
10895
|
-
return /* @__PURE__ */
|
|
11168
|
+
return /* @__PURE__ */ jsx15(TooltipProvider, { children: /* @__PURE__ */ jsx15(TooltipPrimitive.Root, { "data-slot": "tooltip", ...props }) });
|
|
10896
11169
|
}
|
|
10897
11170
|
function TooltipTrigger({
|
|
10898
11171
|
...props
|
|
10899
11172
|
}) {
|
|
10900
|
-
return /* @__PURE__ */
|
|
11173
|
+
return /* @__PURE__ */ jsx15(TooltipPrimitive.Trigger, { "data-slot": "tooltip-trigger", ...props });
|
|
10901
11174
|
}
|
|
10902
11175
|
function TooltipContent({
|
|
10903
11176
|
className,
|
|
@@ -10905,7 +11178,7 @@ function TooltipContent({
|
|
|
10905
11178
|
children,
|
|
10906
11179
|
...props
|
|
10907
11180
|
}) {
|
|
10908
|
-
return /* @__PURE__ */
|
|
11181
|
+
return /* @__PURE__ */ jsx15(TooltipPrimitive.Portal, { children: /* @__PURE__ */ jsxs6(
|
|
10909
11182
|
TooltipPrimitive.Content,
|
|
10910
11183
|
{
|
|
10911
11184
|
"data-slot": "tooltip-content",
|
|
@@ -10917,7 +11190,7 @@ function TooltipContent({
|
|
|
10917
11190
|
...props,
|
|
10918
11191
|
children: [
|
|
10919
11192
|
children,
|
|
10920
|
-
/* @__PURE__ */
|
|
11193
|
+
/* @__PURE__ */ jsx15(TooltipPrimitive.Arrow, { className: "bg-foreground fill-foreground z-50 size-2.5 translate-y-[calc(-50%_-_2px)] rotate-45 rounded-[2px]" })
|
|
10921
11194
|
]
|
|
10922
11195
|
}
|
|
10923
11196
|
) });
|
|
@@ -10927,12 +11200,12 @@ function TooltipContent({
|
|
|
10927
11200
|
import { BotIcon } from "lucide-react";
|
|
10928
11201
|
|
|
10929
11202
|
// src/core/editor/components/text-link-menu.tsx
|
|
10930
|
-
import { useState,
|
|
11203
|
+
import { useState as useState2, useCallback as useCallback4 } from "react";
|
|
10931
11204
|
|
|
10932
11205
|
// src/components/ui/input.tsx
|
|
10933
|
-
import { jsx as
|
|
11206
|
+
import { jsx as jsx16 } from "react/jsx-runtime";
|
|
10934
11207
|
function Input({ className, type, ...props }) {
|
|
10935
|
-
return /* @__PURE__ */
|
|
11208
|
+
return /* @__PURE__ */ jsx16(
|
|
10936
11209
|
"input",
|
|
10937
11210
|
{
|
|
10938
11211
|
type,
|
|
@@ -10953,12 +11226,12 @@ import { CheckIcon, CopyIcon, LinkIcon as LinkIcon2, PencilIcon, TrashIcon } fro
|
|
|
10953
11226
|
|
|
10954
11227
|
// src/components/ui/label.tsx
|
|
10955
11228
|
import * as LabelPrimitive from "@radix-ui/react-label";
|
|
10956
|
-
import { jsx as
|
|
11229
|
+
import { jsx as jsx17 } from "react/jsx-runtime";
|
|
10957
11230
|
function Label({
|
|
10958
11231
|
className,
|
|
10959
11232
|
...props
|
|
10960
11233
|
}) {
|
|
10961
|
-
return /* @__PURE__ */
|
|
11234
|
+
return /* @__PURE__ */ jsx17(
|
|
10962
11235
|
LabelPrimitive.Root,
|
|
10963
11236
|
{
|
|
10964
11237
|
"data-slot": "label",
|
|
@@ -10973,14 +11246,14 @@ function Label({
|
|
|
10973
11246
|
|
|
10974
11247
|
// src/components/ui/separator.tsx
|
|
10975
11248
|
import * as SeparatorPrimitive from "@radix-ui/react-separator";
|
|
10976
|
-
import { jsx as
|
|
11249
|
+
import { jsx as jsx18 } from "react/jsx-runtime";
|
|
10977
11250
|
function Separator({
|
|
10978
11251
|
className,
|
|
10979
11252
|
orientation = "horizontal",
|
|
10980
11253
|
decorative = true,
|
|
10981
11254
|
...props
|
|
10982
11255
|
}) {
|
|
10983
|
-
return /* @__PURE__ */
|
|
11256
|
+
return /* @__PURE__ */ jsx18(
|
|
10984
11257
|
SeparatorPrimitive.Root,
|
|
10985
11258
|
{
|
|
10986
11259
|
"data-slot": "separator",
|
|
@@ -11000,16 +11273,16 @@ var floatButtonVariants = "shadow-none transition-none cursor-pointer rounded-fu
|
|
|
11000
11273
|
|
|
11001
11274
|
// src/components/ui/popover.tsx
|
|
11002
11275
|
import * as PopoverPrimitive from "@radix-ui/react-popover";
|
|
11003
|
-
import { jsx as
|
|
11276
|
+
import { jsx as jsx19 } from "react/jsx-runtime";
|
|
11004
11277
|
function Popover({
|
|
11005
11278
|
...props
|
|
11006
11279
|
}) {
|
|
11007
|
-
return /* @__PURE__ */
|
|
11280
|
+
return /* @__PURE__ */ jsx19(PopoverPrimitive.Root, { "data-slot": "popover", ...props });
|
|
11008
11281
|
}
|
|
11009
11282
|
function PopoverTrigger({
|
|
11010
11283
|
...props
|
|
11011
11284
|
}) {
|
|
11012
|
-
return /* @__PURE__ */
|
|
11285
|
+
return /* @__PURE__ */ jsx19(PopoverPrimitive.Trigger, { "data-slot": "popover-trigger", ...props });
|
|
11013
11286
|
}
|
|
11014
11287
|
function PopoverContent({
|
|
11015
11288
|
className,
|
|
@@ -11017,7 +11290,7 @@ function PopoverContent({
|
|
|
11017
11290
|
sideOffset = 4,
|
|
11018
11291
|
...props
|
|
11019
11292
|
}) {
|
|
11020
|
-
return /* @__PURE__ */
|
|
11293
|
+
return /* @__PURE__ */ jsx19(PopoverPrimitive.Portal, { children: /* @__PURE__ */ jsx19(
|
|
11021
11294
|
PopoverPrimitive.Content,
|
|
11022
11295
|
{
|
|
11023
11296
|
"data-slot": "popover-content",
|
|
@@ -11033,21 +11306,22 @@ function PopoverContent({
|
|
|
11033
11306
|
}
|
|
11034
11307
|
|
|
11035
11308
|
// src/core/editor/components/text-link-menu.tsx
|
|
11036
|
-
import { jsx as
|
|
11309
|
+
import { jsx as jsx20, jsxs as jsxs7 } from "react/jsx-runtime";
|
|
11037
11310
|
var TextLinkMenu = ({ editor }) => {
|
|
11038
|
-
const [isOpen, setIsOpen] =
|
|
11039
|
-
const [inputValue, setInputValue] =
|
|
11040
|
-
const [showCopied, setShowCopied] =
|
|
11041
|
-
const [linkType, setLinkType] =
|
|
11042
|
-
const [isLinkTypeOpen, setIsLinkTypeOpen] =
|
|
11311
|
+
const [isOpen, setIsOpen] = useState2(false);
|
|
11312
|
+
const [inputValue, setInputValue] = useState2("");
|
|
11313
|
+
const [showCopied, setShowCopied] = useState2(false);
|
|
11314
|
+
const [linkType, setLinkType] = useState2(LINK_TYPES[1]);
|
|
11315
|
+
const [isLinkTypeOpen, setIsLinkTypeOpen] = useState2(false);
|
|
11043
11316
|
const currentHref = editor.getAttributes("link").href || "";
|
|
11044
11317
|
const hasLink = !!currentHref;
|
|
11045
|
-
|
|
11046
|
-
|
|
11318
|
+
const handleOpenChange = useCallback4((open) => {
|
|
11319
|
+
setIsOpen(open);
|
|
11320
|
+
if (open) {
|
|
11047
11321
|
setLinkType(detectLinkType(currentHref));
|
|
11048
11322
|
setInputValue(stripPrefix(currentHref));
|
|
11049
11323
|
}
|
|
11050
|
-
}, [
|
|
11324
|
+
}, [currentHref]);
|
|
11051
11325
|
const handleInputChange = (e) => {
|
|
11052
11326
|
setInputValue(e.target.value);
|
|
11053
11327
|
};
|
|
@@ -11084,42 +11358,42 @@ var TextLinkMenu = ({ editor }) => {
|
|
|
11084
11358
|
editor.chain().focus().unsetLink().run();
|
|
11085
11359
|
setInputValue("");
|
|
11086
11360
|
};
|
|
11087
|
-
return /* @__PURE__ */
|
|
11088
|
-
/* @__PURE__ */
|
|
11089
|
-
/* @__PURE__ */
|
|
11361
|
+
return /* @__PURE__ */ jsxs7(Popover, { open: isOpen, onOpenChange: handleOpenChange, children: [
|
|
11362
|
+
/* @__PURE__ */ jsxs7(Tooltip, { children: [
|
|
11363
|
+
/* @__PURE__ */ jsx20(TooltipTrigger, { asChild: true, children: /* @__PURE__ */ jsx20(PopoverTrigger, { asChild: true, children: hasLink ? /* @__PURE__ */ jsx20(
|
|
11090
11364
|
Button,
|
|
11091
11365
|
{
|
|
11092
11366
|
variant: "ghost",
|
|
11093
11367
|
size: "icon",
|
|
11094
11368
|
className: floatButtonVariants,
|
|
11095
11369
|
onMouseDown: (e) => e.preventDefault(),
|
|
11096
|
-
children: /* @__PURE__ */
|
|
11370
|
+
children: /* @__PURE__ */ jsx20(PencilIcon, { className: "size-4" })
|
|
11097
11371
|
}
|
|
11098
|
-
) : /* @__PURE__ */
|
|
11372
|
+
) : /* @__PURE__ */ jsxs7(
|
|
11099
11373
|
Button,
|
|
11100
11374
|
{
|
|
11101
11375
|
variant: "ghost",
|
|
11102
11376
|
className: "shadow-none transition-none cursor-pointer rounded-full outline-none h-[34px]",
|
|
11103
11377
|
onMouseDown: (e) => e.preventDefault(),
|
|
11104
11378
|
children: [
|
|
11105
|
-
/* @__PURE__ */
|
|
11106
|
-
/* @__PURE__ */
|
|
11379
|
+
/* @__PURE__ */ jsx20(LinkIcon2, { className: "size-4" }),
|
|
11380
|
+
/* @__PURE__ */ jsx20("p", { children: "Add link" })
|
|
11107
11381
|
]
|
|
11108
11382
|
}
|
|
11109
11383
|
) }) }),
|
|
11110
|
-
/* @__PURE__ */
|
|
11384
|
+
/* @__PURE__ */ jsx20(TooltipContent, { side: "bottom", children: hasLink ? "Edit link" : "Add link" })
|
|
11111
11385
|
] }),
|
|
11112
|
-
/* @__PURE__ */
|
|
11386
|
+
/* @__PURE__ */ jsxs7(
|
|
11113
11387
|
PopoverContent,
|
|
11114
11388
|
{
|
|
11115
11389
|
side: "bottom",
|
|
11116
11390
|
className: "w-[250px] p-3 shadow-lg z-50001",
|
|
11117
11391
|
"data-editor-toolbar": true,
|
|
11118
11392
|
children: [
|
|
11119
|
-
/* @__PURE__ */
|
|
11120
|
-
/* @__PURE__ */
|
|
11121
|
-
/* @__PURE__ */
|
|
11122
|
-
/* @__PURE__ */
|
|
11393
|
+
/* @__PURE__ */ jsxs7("div", { className: "flex flex-col gap-2", children: [
|
|
11394
|
+
/* @__PURE__ */ jsx20(Label, { children: "Enter a link" }),
|
|
11395
|
+
/* @__PURE__ */ jsxs7("div", { className: "relative", children: [
|
|
11396
|
+
/* @__PURE__ */ jsx20(
|
|
11123
11397
|
Input,
|
|
11124
11398
|
{
|
|
11125
11399
|
type: linkType.inputType,
|
|
@@ -11131,12 +11405,12 @@ var TextLinkMenu = ({ editor }) => {
|
|
|
11131
11405
|
autoFocus: true
|
|
11132
11406
|
}
|
|
11133
11407
|
),
|
|
11134
|
-
/* @__PURE__ */
|
|
11135
|
-
/* @__PURE__ */
|
|
11136
|
-
/* @__PURE__ */
|
|
11137
|
-
/* @__PURE__ */
|
|
11408
|
+
/* @__PURE__ */ jsxs7(Popover, { open: isLinkTypeOpen, onOpenChange: setIsLinkTypeOpen, children: [
|
|
11409
|
+
/* @__PURE__ */ jsxs7(Tooltip, { children: [
|
|
11410
|
+
/* @__PURE__ */ jsx20(TooltipTrigger, { asChild: true, children: /* @__PURE__ */ jsx20(PopoverTrigger, { asChild: true, children: /* @__PURE__ */ jsx20(Button, { size: "icon", variant: "ghost", className: "absolute shadow-none rounded-[12px] left-1.5 top-1/2 -translate-y-1/2 h-[34px] w-[34px] cursor-pointer", children: /* @__PURE__ */ jsx20(linkType.icon, {}) }) }) }),
|
|
11411
|
+
/* @__PURE__ */ jsx20(TooltipContent, { side: "top", className: "z-50001", children: "Link Type" })
|
|
11138
11412
|
] }),
|
|
11139
|
-
/* @__PURE__ */
|
|
11413
|
+
/* @__PURE__ */ jsx20(
|
|
11140
11414
|
PopoverContent,
|
|
11141
11415
|
{
|
|
11142
11416
|
side: "bottom",
|
|
@@ -11144,7 +11418,7 @@ var TextLinkMenu = ({ editor }) => {
|
|
|
11144
11418
|
className: "w-[160px] p-1 z-50001",
|
|
11145
11419
|
onPointerDownOutside: (e) => e.preventDefault(),
|
|
11146
11420
|
"data-editor-toolbar": true,
|
|
11147
|
-
children: LINK_TYPES.map((type) => /* @__PURE__ */
|
|
11421
|
+
children: LINK_TYPES.map((type) => /* @__PURE__ */ jsxs7(
|
|
11148
11422
|
Button,
|
|
11149
11423
|
{
|
|
11150
11424
|
variant: "ghost",
|
|
@@ -11155,11 +11429,11 @@ var TextLinkMenu = ({ editor }) => {
|
|
|
11155
11429
|
setIsLinkTypeOpen(false);
|
|
11156
11430
|
},
|
|
11157
11431
|
children: [
|
|
11158
|
-
/* @__PURE__ */
|
|
11159
|
-
/* @__PURE__ */
|
|
11432
|
+
/* @__PURE__ */ jsxs7("span", { className: "flex items-center gap-2", children: [
|
|
11433
|
+
/* @__PURE__ */ jsx20(type.icon, { className: "size-4" }),
|
|
11160
11434
|
type.name
|
|
11161
11435
|
] }),
|
|
11162
|
-
linkType.name === type.name && /* @__PURE__ */
|
|
11436
|
+
linkType.name === type.name && /* @__PURE__ */ jsx20(CheckIcon, { className: "size-4" })
|
|
11163
11437
|
]
|
|
11164
11438
|
},
|
|
11165
11439
|
type.name
|
|
@@ -11169,11 +11443,11 @@ var TextLinkMenu = ({ editor }) => {
|
|
|
11169
11443
|
] })
|
|
11170
11444
|
] })
|
|
11171
11445
|
] }),
|
|
11172
|
-
/* @__PURE__ */
|
|
11173
|
-
/* @__PURE__ */
|
|
11174
|
-
/* @__PURE__ */
|
|
11175
|
-
/* @__PURE__ */
|
|
11176
|
-
/* @__PURE__ */
|
|
11446
|
+
/* @__PURE__ */ jsx20(Separator, { className: "my-2" }),
|
|
11447
|
+
/* @__PURE__ */ jsxs7("div", { className: "flex flex-row justify-between items-center", children: [
|
|
11448
|
+
/* @__PURE__ */ jsxs7("div", { className: "flex flex-row", children: [
|
|
11449
|
+
/* @__PURE__ */ jsxs7(Tooltip, { children: [
|
|
11450
|
+
/* @__PURE__ */ jsx20(TooltipTrigger, { asChild: true, children: /* @__PURE__ */ jsx20(
|
|
11177
11451
|
Button,
|
|
11178
11452
|
{
|
|
11179
11453
|
variant: "ghost",
|
|
@@ -11181,13 +11455,13 @@ var TextLinkMenu = ({ editor }) => {
|
|
|
11181
11455
|
className: "shadow-none transition-none cursor-pointer rounded-full outline-none",
|
|
11182
11456
|
onClick: handleCopy,
|
|
11183
11457
|
disabled: !hasLink,
|
|
11184
|
-
children: showCopied ? /* @__PURE__ */
|
|
11458
|
+
children: showCopied ? /* @__PURE__ */ jsx20(CheckIcon, { className: "text-green-600" }) : /* @__PURE__ */ jsx20(CopyIcon, {})
|
|
11185
11459
|
}
|
|
11186
11460
|
) }),
|
|
11187
|
-
/* @__PURE__ */
|
|
11461
|
+
/* @__PURE__ */ jsx20(TooltipContent, { side: "bottom", className: "z-50001", children: showCopied ? "Copied!" : "Copy link" })
|
|
11188
11462
|
] }),
|
|
11189
|
-
/* @__PURE__ */
|
|
11190
|
-
/* @__PURE__ */
|
|
11463
|
+
/* @__PURE__ */ jsxs7(Tooltip, { children: [
|
|
11464
|
+
/* @__PURE__ */ jsx20(TooltipTrigger, { asChild: true, children: /* @__PURE__ */ jsx20(
|
|
11191
11465
|
Button,
|
|
11192
11466
|
{
|
|
11193
11467
|
variant: "ghost",
|
|
@@ -11195,13 +11469,13 @@ var TextLinkMenu = ({ editor }) => {
|
|
|
11195
11469
|
className: "shadow-none transition-none cursor-pointer rounded-full outline-none",
|
|
11196
11470
|
onClick: handleRemoveLink,
|
|
11197
11471
|
disabled: !hasLink,
|
|
11198
|
-
children: /* @__PURE__ */
|
|
11472
|
+
children: /* @__PURE__ */ jsx20(TrashIcon, {})
|
|
11199
11473
|
}
|
|
11200
11474
|
) }),
|
|
11201
|
-
/* @__PURE__ */
|
|
11475
|
+
/* @__PURE__ */ jsx20(TooltipContent, { side: "bottom", className: "z-50001", children: "Remove link" })
|
|
11202
11476
|
] })
|
|
11203
11477
|
] }),
|
|
11204
|
-
/* @__PURE__ */
|
|
11478
|
+
/* @__PURE__ */ jsx20("div", { children: /* @__PURE__ */ jsx20(
|
|
11205
11479
|
Button,
|
|
11206
11480
|
{
|
|
11207
11481
|
variant: "default",
|
|
@@ -11218,16 +11492,16 @@ var TextLinkMenu = ({ editor }) => {
|
|
|
11218
11492
|
};
|
|
11219
11493
|
|
|
11220
11494
|
// src/core/editor/components/float-link-preview.tsx
|
|
11221
|
-
import { jsx as
|
|
11495
|
+
import { jsx as jsx21, jsxs as jsxs8 } from "react/jsx-runtime";
|
|
11222
11496
|
var FloatLinkPreview = ({ href }) => {
|
|
11223
|
-
return /* @__PURE__ */
|
|
11224
|
-
/* @__PURE__ */
|
|
11225
|
-
/* @__PURE__ */
|
|
11497
|
+
return /* @__PURE__ */ jsxs8(Tooltip, { children: [
|
|
11498
|
+
/* @__PURE__ */ jsx21(TooltipTrigger, { asChild: true, children: /* @__PURE__ */ jsx21("div", { className: "max-w-[150px] min-w-[25px] h-[34px] px-4 hover:bg-accent rounded-full flex items-center justify-start", children: /* @__PURE__ */ jsx21("a", { href, target: "_blank", className: "shadow-none transition-none cursor-pointer outline-none text-[16px] text-blue-400 truncate", children: href }) }) }),
|
|
11499
|
+
/* @__PURE__ */ jsx21(TooltipContent, { side: "bottom", children: href })
|
|
11226
11500
|
] });
|
|
11227
11501
|
};
|
|
11228
11502
|
|
|
11229
11503
|
// src/core/editor/components/tiptap-overlay.tsx
|
|
11230
|
-
import { jsx as
|
|
11504
|
+
import { jsx as jsx22, jsxs as jsxs9 } from "react/jsx-runtime";
|
|
11231
11505
|
var FontFamily = Extension.create({
|
|
11232
11506
|
name: "fontFamily",
|
|
11233
11507
|
addGlobalAttributes() {
|
|
@@ -11405,7 +11679,8 @@ var TIPTAP_EXTENSIONS = [
|
|
|
11405
11679
|
emptyNodeClass: "is-empty-placeholder",
|
|
11406
11680
|
paragraphPlaceholder: "Start typing...",
|
|
11407
11681
|
headingPlaceholder: "Heading"
|
|
11408
|
-
})
|
|
11682
|
+
}),
|
|
11683
|
+
MergeFieldDecoration
|
|
11409
11684
|
];
|
|
11410
11685
|
function isNodeEmpty2(node) {
|
|
11411
11686
|
if (!node) return true;
|
|
@@ -11536,14 +11811,14 @@ function handleBackspaceOrDelete(view, event, currentElementIdx, storeRefs) {
|
|
|
11536
11811
|
var TiptapOverlay = () => {
|
|
11537
11812
|
const textEditing = useEditorStore((s) => s.textEditing);
|
|
11538
11813
|
if (!textEditing) return null;
|
|
11539
|
-
return /* @__PURE__ */
|
|
11814
|
+
return /* @__PURE__ */ jsx22(TiptapOverlayContent, { ...textEditing }, textEditing.idx);
|
|
11540
11815
|
};
|
|
11541
11816
|
var TiptapOverlayContent = ({ idx, getReferenceRect, getShadowElement, initialWidth, initialHeight, clickX, clickY, content, styles, cursorPosition }) => {
|
|
11542
|
-
const containerRef =
|
|
11817
|
+
const containerRef = useRef5(null);
|
|
11543
11818
|
const setTiptapEditor = useEditorStore((s) => s.setTiptapEditor);
|
|
11544
11819
|
const linkColor = useEditorStore((s) => s.template?.content?.[0]?.data?.value?.linkColor) || "#0000ff";
|
|
11545
|
-
const lastSizeLimitToastRef =
|
|
11546
|
-
const hasContentChangedRef =
|
|
11820
|
+
const lastSizeLimitToastRef = useRef5(0);
|
|
11821
|
+
const hasContentChangedRef = useRef5(false);
|
|
11547
11822
|
const storeRefs = useEditorStoreRefs();
|
|
11548
11823
|
useEffect6(() => {
|
|
11549
11824
|
return () => {
|
|
@@ -11571,10 +11846,10 @@ var TiptapOverlayContent = ({ idx, getReferenceRect, getShadowElement, initialWi
|
|
|
11571
11846
|
}
|
|
11572
11847
|
};
|
|
11573
11848
|
}, [getShadowElement]);
|
|
11574
|
-
const cleanedContent =
|
|
11849
|
+
const cleanedContent = useMemo4(() => {
|
|
11575
11850
|
return content.replace(NBSP_P_CONTENT_REGEX, "<p$1></p>").replace(IS_EMPTY_P_CLASS_REGEX, "").replace(IS_EMPTY_HEADING_CLASS_REGEX, "");
|
|
11576
11851
|
}, [content]);
|
|
11577
|
-
const lineHeightRatio =
|
|
11852
|
+
const lineHeightRatio = useMemo4(() => {
|
|
11578
11853
|
const lineHeightPx = parseFloat(styles.lineHeight);
|
|
11579
11854
|
const fontSizePx = parseFloat(styles.fontSize);
|
|
11580
11855
|
if (isNaN(lineHeightPx) || isNaN(fontSizePx) || fontSizePx === 0) {
|
|
@@ -11582,7 +11857,7 @@ var TiptapOverlayContent = ({ idx, getReferenceRect, getShadowElement, initialWi
|
|
|
11582
11857
|
}
|
|
11583
11858
|
return lineHeightPx / fontSizePx;
|
|
11584
11859
|
}, [styles.lineHeight, styles.fontSize]);
|
|
11585
|
-
const virtualReference =
|
|
11860
|
+
const virtualReference = useMemo4(() => ({
|
|
11586
11861
|
getBoundingClientRect: () => {
|
|
11587
11862
|
const rect = getReferenceRect();
|
|
11588
11863
|
if (!rect) {
|
|
@@ -11591,10 +11866,10 @@ var TiptapOverlayContent = ({ idx, getReferenceRect, getShadowElement, initialWi
|
|
|
11591
11866
|
return rect;
|
|
11592
11867
|
}
|
|
11593
11868
|
}), [getReferenceRect]);
|
|
11594
|
-
const { floatingStyles, refs, update } =
|
|
11869
|
+
const { floatingStyles, refs, update } = useFloating4({
|
|
11595
11870
|
placement: "bottom-start",
|
|
11596
11871
|
middleware: [
|
|
11597
|
-
|
|
11872
|
+
offset4(({ rects }) => -rects.reference.height)
|
|
11598
11873
|
// Move up by reference height to overlay exactly
|
|
11599
11874
|
]
|
|
11600
11875
|
});
|
|
@@ -11637,17 +11912,36 @@ var TiptapOverlayContent = ({ idx, getReferenceRect, getShadowElement, initialWi
|
|
|
11637
11912
|
}
|
|
11638
11913
|
}
|
|
11639
11914
|
const isSlashCommandActive = storeRefs.slashCommand.current?.isActive;
|
|
11640
|
-
|
|
11641
|
-
|
|
11642
|
-
|
|
11915
|
+
const isMergeFieldActive = storeRefs.mergeFieldSuggestion.current?.isActive;
|
|
11916
|
+
if (event.key === "Escape") {
|
|
11917
|
+
if (isSlashCommandActive) {
|
|
11918
|
+
storeRefs.clearSlashCommand.current();
|
|
11919
|
+
return true;
|
|
11920
|
+
}
|
|
11921
|
+
if (isMergeFieldActive) {
|
|
11922
|
+
storeRefs.clearMergeFieldSuggestion.current();
|
|
11923
|
+
return true;
|
|
11924
|
+
}
|
|
11643
11925
|
}
|
|
11644
|
-
if (event.key === " "
|
|
11645
|
-
|
|
11646
|
-
|
|
11926
|
+
if (event.key === " ") {
|
|
11927
|
+
if (isSlashCommandActive) {
|
|
11928
|
+
storeRefs.clearSlashCommand.current();
|
|
11929
|
+
return false;
|
|
11930
|
+
}
|
|
11931
|
+
if (isMergeFieldActive) {
|
|
11932
|
+
storeRefs.clearMergeFieldSuggestion.current();
|
|
11933
|
+
return false;
|
|
11934
|
+
}
|
|
11647
11935
|
}
|
|
11648
|
-
if (
|
|
11649
|
-
|
|
11650
|
-
|
|
11936
|
+
if (event.key === "ArrowLeft" || event.key === "ArrowRight" || event.key === "ArrowUp" || event.key === "ArrowDown") {
|
|
11937
|
+
if (isSlashCommandActive) {
|
|
11938
|
+
storeRefs.clearSlashCommand.current();
|
|
11939
|
+
return false;
|
|
11940
|
+
}
|
|
11941
|
+
if (isMergeFieldActive) {
|
|
11942
|
+
storeRefs.clearMergeFieldSuggestion.current();
|
|
11943
|
+
return false;
|
|
11944
|
+
}
|
|
11651
11945
|
}
|
|
11652
11946
|
if (event.key === "/") {
|
|
11653
11947
|
const { from } = view.state.selection;
|
|
@@ -11669,6 +11963,33 @@ var TiptapOverlayContent = ({ idx, getReferenceRect, getShadowElement, initialWi
|
|
|
11669
11963
|
});
|
|
11670
11964
|
}
|
|
11671
11965
|
}
|
|
11966
|
+
if (event.key === "{") {
|
|
11967
|
+
const { from } = view.state.selection;
|
|
11968
|
+
const textBefore = view.state.doc.textBetween(Math.max(0, from - 1), from);
|
|
11969
|
+
if (textBefore === "{") {
|
|
11970
|
+
const coords = view.coordsAtPos(from);
|
|
11971
|
+
if (coords && coords.left > 0 && coords.top > 0) {
|
|
11972
|
+
const lineHeight = parseInt(styles.lineHeight) || 20;
|
|
11973
|
+
storeRefs.setMergeFieldSuggestion.current({
|
|
11974
|
+
isActive: true,
|
|
11975
|
+
cursorRect: { top: coords.top, left: coords.left, height: lineHeight },
|
|
11976
|
+
triggerPosition: from - 1
|
|
11977
|
+
// Position of first "{"
|
|
11978
|
+
});
|
|
11979
|
+
}
|
|
11980
|
+
}
|
|
11981
|
+
}
|
|
11982
|
+
if (event.key === "}" && isMergeFieldActive) {
|
|
11983
|
+
storeRefs.clearMergeFieldSuggestion.current();
|
|
11984
|
+
return false;
|
|
11985
|
+
}
|
|
11986
|
+
if (event.key === "Backspace" && isMergeFieldActive) {
|
|
11987
|
+
const { from } = view.state.selection;
|
|
11988
|
+
const triggerPos = storeRefs.mergeFieldSuggestion.current?.triggerPosition ?? 0;
|
|
11989
|
+
if (from <= triggerPos + 2) {
|
|
11990
|
+
storeRefs.clearMergeFieldSuggestion.current();
|
|
11991
|
+
}
|
|
11992
|
+
}
|
|
11672
11993
|
if (event.key === "Backspace" || event.key === "Delete") {
|
|
11673
11994
|
const handled = handleBackspaceOrDelete(
|
|
11674
11995
|
view,
|
|
@@ -11735,7 +12056,7 @@ var TiptapOverlayContent = ({ idx, getReferenceRect, getShadowElement, initialWi
|
|
|
11735
12056
|
storeRefs.updateElementContent.current(`${idx}.data.value.content`, html);
|
|
11736
12057
|
}
|
|
11737
12058
|
});
|
|
11738
|
-
const [currentLinkHref, setCurrentLinkHref] =
|
|
12059
|
+
const [currentLinkHref, setCurrentLinkHref] = useState3("");
|
|
11739
12060
|
useEffect6(() => {
|
|
11740
12061
|
if (!editor) return;
|
|
11741
12062
|
setTiptapEditor(editor);
|
|
@@ -11802,7 +12123,7 @@ var TiptapOverlayContent = ({ idx, getReferenceRect, getShadowElement, initialWi
|
|
|
11802
12123
|
document.removeEventListener("mousedown", handleClickOutside);
|
|
11803
12124
|
};
|
|
11804
12125
|
}, []);
|
|
11805
|
-
return /* @__PURE__ */
|
|
12126
|
+
return /* @__PURE__ */ jsxs9(
|
|
11806
12127
|
"div",
|
|
11807
12128
|
{
|
|
11808
12129
|
ref: (node) => {
|
|
@@ -11835,7 +12156,7 @@ var TiptapOverlayContent = ({ idx, getReferenceRect, getShadowElement, initialWi
|
|
|
11835
12156
|
boxSizing: "border-box"
|
|
11836
12157
|
},
|
|
11837
12158
|
children: [
|
|
11838
|
-
/* @__PURE__ */
|
|
12159
|
+
/* @__PURE__ */ jsx22("style", { children: `
|
|
11839
12160
|
.tiptap-overlay {
|
|
11840
12161
|
margin: 0;
|
|
11841
12162
|
padding: 0;
|
|
@@ -11901,6 +12222,16 @@ var TiptapOverlayContent = ({ idx, getReferenceRect, getShadowElement, initialWi
|
|
|
11901
12222
|
transform: translateY(-50%);
|
|
11902
12223
|
text-align: inherit;
|
|
11903
12224
|
}
|
|
12225
|
+
.tiptap-overlay .ProseMirror .merge-field-tag {
|
|
12226
|
+
background-color: var(--background);
|
|
12227
|
+
border-radius: 4px;
|
|
12228
|
+
padding: 0px;
|
|
12229
|
+
border: 1px solid var(--border);
|
|
12230
|
+
color: #000000;
|
|
12231
|
+
}
|
|
12232
|
+
.tiptap-overlay .ProseMirror .merge-field-tag:hover {
|
|
12233
|
+
cursor: pointer;
|
|
12234
|
+
}
|
|
11904
12235
|
.tiptap-overlay .ProseMirror a {
|
|
11905
12236
|
color: ${linkColor};
|
|
11906
12237
|
text-decoration: none;
|
|
@@ -11910,36 +12241,36 @@ var TiptapOverlayContent = ({ idx, getReferenceRect, getShadowElement, initialWi
|
|
|
11910
12241
|
text-decoration: underline;
|
|
11911
12242
|
}
|
|
11912
12243
|
` }),
|
|
11913
|
-
/* @__PURE__ */
|
|
12244
|
+
/* @__PURE__ */ jsx22(
|
|
11914
12245
|
EditorContent,
|
|
11915
12246
|
{
|
|
11916
12247
|
editor,
|
|
11917
12248
|
className: "tiptap-overlay"
|
|
11918
12249
|
}
|
|
11919
12250
|
),
|
|
11920
|
-
editor && /* @__PURE__ */
|
|
12251
|
+
editor && /* @__PURE__ */ jsx22(
|
|
11921
12252
|
BubbleMenu,
|
|
11922
12253
|
{
|
|
11923
12254
|
editor,
|
|
11924
12255
|
options: { placement: "top", offset: 8, flip: true },
|
|
11925
12256
|
updateDelay: 0,
|
|
11926
|
-
children: /* @__PURE__ */
|
|
11927
|
-
/* @__PURE__ */
|
|
11928
|
-
/* @__PURE__ */
|
|
12257
|
+
children: /* @__PURE__ */ jsxs9("div", { className: "bg-white flex items-center justify-center border h-[36px] w-fit shadow-md rounded-full text-[16px]", children: [
|
|
12258
|
+
/* @__PURE__ */ jsxs9(Tooltip, { children: [
|
|
12259
|
+
/* @__PURE__ */ jsx22(TooltipTrigger, { asChild: true, children: /* @__PURE__ */ jsxs9(
|
|
11929
12260
|
Button,
|
|
11930
12261
|
{
|
|
11931
12262
|
variant: "ghost",
|
|
11932
12263
|
className: "shadow-none transition-none cursor-pointer rounded-full outline-none h-[34px]",
|
|
11933
12264
|
children: [
|
|
11934
|
-
/* @__PURE__ */
|
|
11935
|
-
/* @__PURE__ */
|
|
12265
|
+
/* @__PURE__ */ jsx22(BotIcon, { className: "size-4" }),
|
|
12266
|
+
/* @__PURE__ */ jsx22("p", { children: "Magic Write" })
|
|
11936
12267
|
]
|
|
11937
12268
|
}
|
|
11938
12269
|
) }),
|
|
11939
|
-
/* @__PURE__ */
|
|
12270
|
+
/* @__PURE__ */ jsx22(TooltipContent, { side: "bottom", children: "Ask Maillow" })
|
|
11940
12271
|
] }),
|
|
11941
|
-
currentLinkHref && /* @__PURE__ */
|
|
11942
|
-
/* @__PURE__ */
|
|
12272
|
+
currentLinkHref && /* @__PURE__ */ jsx22(FloatLinkPreview, { href: currentLinkHref }),
|
|
12273
|
+
/* @__PURE__ */ jsx22(TextLinkMenu, { editor })
|
|
11943
12274
|
] })
|
|
11944
12275
|
}
|
|
11945
12276
|
)
|
|
@@ -11949,12 +12280,12 @@ var TiptapOverlayContent = ({ idx, getReferenceRect, getShadowElement, initialWi
|
|
|
11949
12280
|
};
|
|
11950
12281
|
|
|
11951
12282
|
// src/core/editor/components/element-float.tsx
|
|
11952
|
-
import { useEffect as
|
|
11953
|
-
import { useFloating as
|
|
12283
|
+
import { useEffect as useEffect8, useMemo as useMemo12 } from "react";
|
|
12284
|
+
import { useFloating as useFloating5, offset as offset5, shift as shift4, flip as flip3, autoUpdate as autoUpdate3 } from "@floating-ui/react";
|
|
11954
12285
|
|
|
11955
12286
|
// src/core/editor/components/float-ui/actions/delete-button.tsx
|
|
11956
12287
|
import { TrashIcon as TrashIcon2 } from "lucide-react";
|
|
11957
|
-
import { jsx as
|
|
12288
|
+
import { jsx as jsx23, jsxs as jsxs10 } from "react/jsx-runtime";
|
|
11958
12289
|
var DeleteButton = () => {
|
|
11959
12290
|
const { focusIdx, deleteElement } = useEditorStore();
|
|
11960
12291
|
const handleDelete = () => {
|
|
@@ -11962,23 +12293,23 @@ var DeleteButton = () => {
|
|
|
11962
12293
|
deleteElement(focusIdx);
|
|
11963
12294
|
}
|
|
11964
12295
|
};
|
|
11965
|
-
return /* @__PURE__ */
|
|
11966
|
-
/* @__PURE__ */
|
|
12296
|
+
return /* @__PURE__ */ jsxs10(Tooltip, { children: [
|
|
12297
|
+
/* @__PURE__ */ jsx23(TooltipTrigger, { asChild: true, children: /* @__PURE__ */ jsx23(
|
|
11967
12298
|
Button,
|
|
11968
12299
|
{
|
|
11969
12300
|
variant: "ghost",
|
|
11970
12301
|
className: floatButtonVariants,
|
|
11971
12302
|
onClick: handleDelete,
|
|
11972
|
-
children: /* @__PURE__ */
|
|
12303
|
+
children: /* @__PURE__ */ jsx23(TrashIcon2, { className: "size-4" })
|
|
11973
12304
|
}
|
|
11974
12305
|
) }),
|
|
11975
|
-
/* @__PURE__ */
|
|
12306
|
+
/* @__PURE__ */ jsx23(TooltipContent, { side: "bottom", children: "Delete" })
|
|
11976
12307
|
] });
|
|
11977
12308
|
};
|
|
11978
12309
|
|
|
11979
12310
|
// src/core/editor/components/float-ui/actions/dulicate-button.tsx
|
|
11980
12311
|
import { CopyIcon as CopyIcon2 } from "lucide-react";
|
|
11981
|
-
import { jsx as
|
|
12312
|
+
import { jsx as jsx24, jsxs as jsxs11 } from "react/jsx-runtime";
|
|
11982
12313
|
var DuplicateButton = () => {
|
|
11983
12314
|
const { focusIdx, duplicateElement } = useEditorStore();
|
|
11984
12315
|
const isAtSizeLimit = useEditorStore((state) => state.isAtSizeLimit);
|
|
@@ -11987,42 +12318,42 @@ var DuplicateButton = () => {
|
|
|
11987
12318
|
duplicateElement(focusIdx);
|
|
11988
12319
|
}
|
|
11989
12320
|
};
|
|
11990
|
-
return /* @__PURE__ */
|
|
11991
|
-
/* @__PURE__ */
|
|
12321
|
+
return /* @__PURE__ */ jsxs11(Tooltip, { children: [
|
|
12322
|
+
/* @__PURE__ */ jsx24(TooltipTrigger, { asChild: true, children: /* @__PURE__ */ jsx24(
|
|
11992
12323
|
Button,
|
|
11993
12324
|
{
|
|
11994
12325
|
variant: "ghost",
|
|
11995
12326
|
className: floatButtonVariants,
|
|
11996
12327
|
onClick: handleDuplicate,
|
|
11997
12328
|
disabled: isAtSizeLimit,
|
|
11998
|
-
children: /* @__PURE__ */
|
|
12329
|
+
children: /* @__PURE__ */ jsx24(CopyIcon2, { className: "size-4" })
|
|
11999
12330
|
}
|
|
12000
12331
|
) }),
|
|
12001
|
-
/* @__PURE__ */
|
|
12332
|
+
/* @__PURE__ */ jsx24(TooltipContent, { side: "bottom", children: "Duplicate" })
|
|
12002
12333
|
] });
|
|
12003
12334
|
};
|
|
12004
12335
|
|
|
12005
12336
|
// src/core/editor/components/href-menu.tsx
|
|
12006
|
-
import { useState as
|
|
12337
|
+
import { useState as useState4, useCallback as useCallback6, useMemo as useMemo6 } from "react";
|
|
12007
12338
|
|
|
12008
12339
|
// src/components/ui/dropdown-menu.tsx
|
|
12009
12340
|
import * as DropdownMenuPrimitive from "@radix-ui/react-dropdown-menu";
|
|
12010
12341
|
import { CheckIcon as CheckIcon2, ChevronRightIcon, CircleIcon } from "lucide-react";
|
|
12011
|
-
import { jsx as
|
|
12342
|
+
import { jsx as jsx25, jsxs as jsxs12 } from "react/jsx-runtime";
|
|
12012
12343
|
function DropdownMenu({
|
|
12013
12344
|
...props
|
|
12014
12345
|
}) {
|
|
12015
|
-
return /* @__PURE__ */
|
|
12346
|
+
return /* @__PURE__ */ jsx25(DropdownMenuPrimitive.Root, { "data-slot": "dropdown-menu", ...props });
|
|
12016
12347
|
}
|
|
12017
12348
|
function DropdownMenuPortal({
|
|
12018
12349
|
...props
|
|
12019
12350
|
}) {
|
|
12020
|
-
return /* @__PURE__ */
|
|
12351
|
+
return /* @__PURE__ */ jsx25(DropdownMenuPrimitive.Portal, { "data-slot": "dropdown-menu-portal", ...props });
|
|
12021
12352
|
}
|
|
12022
12353
|
function DropdownMenuTrigger({
|
|
12023
12354
|
...props
|
|
12024
12355
|
}) {
|
|
12025
|
-
return /* @__PURE__ */
|
|
12356
|
+
return /* @__PURE__ */ jsx25(
|
|
12026
12357
|
DropdownMenuPrimitive.Trigger,
|
|
12027
12358
|
{
|
|
12028
12359
|
"data-slot": "dropdown-menu-trigger",
|
|
@@ -12035,7 +12366,7 @@ function DropdownMenuContent({
|
|
|
12035
12366
|
sideOffset = 4,
|
|
12036
12367
|
...props
|
|
12037
12368
|
}) {
|
|
12038
|
-
return /* @__PURE__ */
|
|
12369
|
+
return /* @__PURE__ */ jsx25(DropdownMenuPrimitive.Portal, { children: /* @__PURE__ */ jsx25(
|
|
12039
12370
|
DropdownMenuPrimitive.Content,
|
|
12040
12371
|
{
|
|
12041
12372
|
"data-slot": "dropdown-menu-content",
|
|
@@ -12054,7 +12385,7 @@ function DropdownMenuItem({
|
|
|
12054
12385
|
variant = "default",
|
|
12055
12386
|
...props
|
|
12056
12387
|
}) {
|
|
12057
|
-
return /* @__PURE__ */
|
|
12388
|
+
return /* @__PURE__ */ jsx25(
|
|
12058
12389
|
DropdownMenuPrimitive.Item,
|
|
12059
12390
|
{
|
|
12060
12391
|
"data-slot": "dropdown-menu-item",
|
|
@@ -12072,7 +12403,7 @@ function DropdownMenuSeparator({
|
|
|
12072
12403
|
className,
|
|
12073
12404
|
...props
|
|
12074
12405
|
}) {
|
|
12075
|
-
return /* @__PURE__ */
|
|
12406
|
+
return /* @__PURE__ */ jsx25(
|
|
12076
12407
|
DropdownMenuPrimitive.Separator,
|
|
12077
12408
|
{
|
|
12078
12409
|
"data-slot": "dropdown-menu-separator",
|
|
@@ -12084,7 +12415,7 @@ function DropdownMenuSeparator({
|
|
|
12084
12415
|
function DropdownMenuSub({
|
|
12085
12416
|
...props
|
|
12086
12417
|
}) {
|
|
12087
|
-
return /* @__PURE__ */
|
|
12418
|
+
return /* @__PURE__ */ jsx25(DropdownMenuPrimitive.Sub, { "data-slot": "dropdown-menu-sub", ...props });
|
|
12088
12419
|
}
|
|
12089
12420
|
function DropdownMenuSubTrigger({
|
|
12090
12421
|
className,
|
|
@@ -12092,7 +12423,7 @@ function DropdownMenuSubTrigger({
|
|
|
12092
12423
|
children,
|
|
12093
12424
|
...props
|
|
12094
12425
|
}) {
|
|
12095
|
-
return /* @__PURE__ */
|
|
12426
|
+
return /* @__PURE__ */ jsxs12(
|
|
12096
12427
|
DropdownMenuPrimitive.SubTrigger,
|
|
12097
12428
|
{
|
|
12098
12429
|
"data-slot": "dropdown-menu-sub-trigger",
|
|
@@ -12104,7 +12435,7 @@ function DropdownMenuSubTrigger({
|
|
|
12104
12435
|
...props,
|
|
12105
12436
|
children: [
|
|
12106
12437
|
children,
|
|
12107
|
-
/* @__PURE__ */
|
|
12438
|
+
/* @__PURE__ */ jsx25(ChevronRightIcon, { className: "ml-auto size-4" })
|
|
12108
12439
|
]
|
|
12109
12440
|
}
|
|
12110
12441
|
);
|
|
@@ -12113,7 +12444,7 @@ function DropdownMenuSubContent({
|
|
|
12113
12444
|
className,
|
|
12114
12445
|
...props
|
|
12115
12446
|
}) {
|
|
12116
|
-
return /* @__PURE__ */
|
|
12447
|
+
return /* @__PURE__ */ jsx25(
|
|
12117
12448
|
DropdownMenuPrimitive.SubContent,
|
|
12118
12449
|
{
|
|
12119
12450
|
"data-slot": "dropdown-menu-sub-content",
|
|
@@ -12130,11 +12461,11 @@ function DropdownMenuSubContent({
|
|
|
12130
12461
|
import { CheckIcon as CheckIcon3, CopyIcon as CopyIcon3, LinkIcon as LinkIcon3, PencilIcon as PencilIcon2, TrashIcon as TrashIcon3 } from "lucide-react";
|
|
12131
12462
|
|
|
12132
12463
|
// src/core/editor/hooks/use-href.ts
|
|
12133
|
-
import { useMemo as
|
|
12464
|
+
import { useMemo as useMemo5, useCallback as useCallback5 } from "react";
|
|
12134
12465
|
import { get as lodashGet2 } from "lodash";
|
|
12135
12466
|
var useHref = () => {
|
|
12136
12467
|
const { focusIdx, updateElement, template } = useEditorStore();
|
|
12137
|
-
const { element, href } =
|
|
12468
|
+
const { element, href } = useMemo5(() => {
|
|
12138
12469
|
if (!focusIdx || !template) {
|
|
12139
12470
|
return { element: null, href: "" };
|
|
12140
12471
|
}
|
|
@@ -12145,19 +12476,19 @@ var useHref = () => {
|
|
|
12145
12476
|
href: el?.attributes?.href || ""
|
|
12146
12477
|
};
|
|
12147
12478
|
}, [focusIdx, template]);
|
|
12148
|
-
const setHref =
|
|
12479
|
+
const setHref = useCallback5((url) => {
|
|
12149
12480
|
if (!focusIdx || !element) return;
|
|
12150
12481
|
updateElement(focusIdx, {
|
|
12151
12482
|
attributes: { ...element.attributes, href: url }
|
|
12152
12483
|
});
|
|
12153
12484
|
}, [focusIdx, element, updateElement]);
|
|
12154
|
-
const clearHref =
|
|
12485
|
+
const clearHref = useCallback5(() => {
|
|
12155
12486
|
if (!focusIdx || !element) return;
|
|
12156
12487
|
updateElement(focusIdx, {
|
|
12157
12488
|
attributes: { ...element.attributes, href: "" }
|
|
12158
12489
|
});
|
|
12159
12490
|
}, [focusIdx, element, updateElement]);
|
|
12160
|
-
const copyHref =
|
|
12491
|
+
const copyHref = useCallback5(async () => {
|
|
12161
12492
|
if (href) {
|
|
12162
12493
|
try {
|
|
12163
12494
|
await navigator.clipboard.writeText(href);
|
|
@@ -12177,18 +12508,18 @@ var useHref = () => {
|
|
|
12177
12508
|
};
|
|
12178
12509
|
|
|
12179
12510
|
// src/core/editor/components/href-menu.tsx
|
|
12180
|
-
import { jsx as
|
|
12511
|
+
import { jsx as jsx26, jsxs as jsxs13 } from "react/jsx-runtime";
|
|
12181
12512
|
var HrefMenu = () => {
|
|
12182
12513
|
const { href, setHref, clearHref, copyHref, hasHref } = useHref();
|
|
12183
12514
|
const userData = useEditorStore((s) => s.userData);
|
|
12184
|
-
const [isOpen, setIsOpen] =
|
|
12185
|
-
const [inputValue, setInputValue] =
|
|
12186
|
-
const [showCopied, setShowCopied] =
|
|
12187
|
-
const [linkType, setLinkType] =
|
|
12188
|
-
const [isLinkTypeOpen, setIsLinkTypeOpen] =
|
|
12189
|
-
const [isPresetOpen, setIsPresetOpen] =
|
|
12515
|
+
const [isOpen, setIsOpen] = useState4(false);
|
|
12516
|
+
const [inputValue, setInputValue] = useState4("");
|
|
12517
|
+
const [showCopied, setShowCopied] = useState4(false);
|
|
12518
|
+
const [linkType, setLinkType] = useState4(LINK_TYPES[1]);
|
|
12519
|
+
const [isLinkTypeOpen, setIsLinkTypeOpen] = useState4(false);
|
|
12520
|
+
const [isPresetOpen, setIsPresetOpen] = useState4(false);
|
|
12190
12521
|
console.log("userData", userData);
|
|
12191
|
-
const availablePresets =
|
|
12522
|
+
const availablePresets = useMemo6(() => {
|
|
12192
12523
|
const presetDefs = LINK_PRESETS[linkType.name] ?? [];
|
|
12193
12524
|
if (!userData) return [];
|
|
12194
12525
|
const all = presetDefs.filter((p) => userData[p.key]).map((p) => ({ ...p, value: String(userData[p.key]) }));
|
|
@@ -12196,17 +12527,18 @@ var HrefMenu = () => {
|
|
|
12196
12527
|
const query = inputValue.toLowerCase();
|
|
12197
12528
|
return all.filter((p) => p.value.toLowerCase().includes(query));
|
|
12198
12529
|
}, [linkType.name, userData, inputValue]);
|
|
12199
|
-
const handlePresetSelect =
|
|
12530
|
+
const handlePresetSelect = useCallback6((value) => {
|
|
12200
12531
|
setInputValue(value);
|
|
12201
12532
|
setIsPresetOpen(false);
|
|
12202
12533
|
}, []);
|
|
12203
|
-
|
|
12204
|
-
|
|
12534
|
+
const handleOpenChange = useCallback6((open) => {
|
|
12535
|
+
setIsOpen(open);
|
|
12536
|
+
if (open) {
|
|
12205
12537
|
setLinkType(detectLinkType(href));
|
|
12206
12538
|
setInputValue(stripPrefix(href));
|
|
12207
12539
|
setIsPresetOpen(true);
|
|
12208
12540
|
}
|
|
12209
|
-
}, [
|
|
12541
|
+
}, [href]);
|
|
12210
12542
|
const handleInputChange = (e) => {
|
|
12211
12543
|
setInputValue(e.target.value);
|
|
12212
12544
|
setIsPresetOpen(true);
|
|
@@ -12251,35 +12583,35 @@ var HrefMenu = () => {
|
|
|
12251
12583
|
setHref(buildHref(inputValue));
|
|
12252
12584
|
setIsOpen(false);
|
|
12253
12585
|
};
|
|
12254
|
-
return /* @__PURE__ */
|
|
12255
|
-
/* @__PURE__ */
|
|
12256
|
-
/* @__PURE__ */
|
|
12586
|
+
return /* @__PURE__ */ jsxs13(DropdownMenu, { open: isOpen, onOpenChange: handleOpenChange, children: [
|
|
12587
|
+
/* @__PURE__ */ jsxs13(Tooltip, { children: [
|
|
12588
|
+
/* @__PURE__ */ jsx26(TooltipTrigger, { asChild: true, children: /* @__PURE__ */ jsx26(DropdownMenuTrigger, { asChild: true, children: hasHref ? /* @__PURE__ */ jsx26(
|
|
12257
12589
|
Button,
|
|
12258
12590
|
{
|
|
12259
12591
|
variant: "ghost",
|
|
12260
12592
|
size: "icon",
|
|
12261
12593
|
className: floatButtonVariants,
|
|
12262
|
-
children: /* @__PURE__ */
|
|
12594
|
+
children: /* @__PURE__ */ jsx26(PencilIcon2, { className: "size-4" })
|
|
12263
12595
|
}
|
|
12264
|
-
) : /* @__PURE__ */
|
|
12596
|
+
) : /* @__PURE__ */ jsxs13(
|
|
12265
12597
|
Button,
|
|
12266
12598
|
{
|
|
12267
12599
|
variant: "ghost",
|
|
12268
12600
|
className: "shadow-none transition-none cursor-pointer rounded-full outline-none h-[34px]",
|
|
12269
12601
|
children: [
|
|
12270
|
-
/* @__PURE__ */
|
|
12271
|
-
/* @__PURE__ */
|
|
12602
|
+
/* @__PURE__ */ jsx26(LinkIcon3, { className: "size-4" }),
|
|
12603
|
+
/* @__PURE__ */ jsx26("p", { children: "Add link" })
|
|
12272
12604
|
]
|
|
12273
12605
|
}
|
|
12274
12606
|
) }) }),
|
|
12275
|
-
/* @__PURE__ */
|
|
12607
|
+
/* @__PURE__ */ jsx26(TooltipContent, { side: "bottom", children: hasHref ? `Edit link` : "Add link" })
|
|
12276
12608
|
] }),
|
|
12277
|
-
/* @__PURE__ */
|
|
12278
|
-
/* @__PURE__ */
|
|
12279
|
-
/* @__PURE__ */
|
|
12280
|
-
/* @__PURE__ */
|
|
12281
|
-
/* @__PURE__ */
|
|
12282
|
-
/* @__PURE__ */
|
|
12609
|
+
/* @__PURE__ */ jsxs13(DropdownMenuContent, { side: "bottom", className: "w-[250px] p-3 shadow-lg z-50001", children: [
|
|
12610
|
+
/* @__PURE__ */ jsxs13("div", { className: "flex flex-col gap-2", children: [
|
|
12611
|
+
/* @__PURE__ */ jsx26(Label, { children: "Enter a link" }),
|
|
12612
|
+
/* @__PURE__ */ jsxs13(Popover, { open: isPresetOpen && availablePresets.length > 0, onOpenChange: setIsPresetOpen, children: [
|
|
12613
|
+
/* @__PURE__ */ jsx26(PopoverTrigger, { asChild: true, children: /* @__PURE__ */ jsxs13("div", { className: "relative", children: [
|
|
12614
|
+
/* @__PURE__ */ jsx26(
|
|
12283
12615
|
Input,
|
|
12284
12616
|
{
|
|
12285
12617
|
type: linkType.inputType,
|
|
@@ -12293,19 +12625,19 @@ var HrefMenu = () => {
|
|
|
12293
12625
|
autoFocus: true
|
|
12294
12626
|
}
|
|
12295
12627
|
),
|
|
12296
|
-
/* @__PURE__ */
|
|
12297
|
-
/* @__PURE__ */
|
|
12298
|
-
/* @__PURE__ */
|
|
12299
|
-
/* @__PURE__ */
|
|
12628
|
+
/* @__PURE__ */ jsxs13(Popover, { open: isLinkTypeOpen, onOpenChange: setIsLinkTypeOpen, children: [
|
|
12629
|
+
/* @__PURE__ */ jsxs13(Tooltip, { children: [
|
|
12630
|
+
/* @__PURE__ */ jsx26(TooltipTrigger, { asChild: true, children: /* @__PURE__ */ jsx26(PopoverTrigger, { asChild: true, children: /* @__PURE__ */ jsx26(Button, { size: "icon", variant: "ghost", className: "absolute shadow-none rounded-[12px] left-1.5 top-1/2 -translate-y-1/2 h-[34px] w-[34px] cursor-pointer", children: /* @__PURE__ */ jsx26(linkType.icon, {}) }) }) }),
|
|
12631
|
+
/* @__PURE__ */ jsx26(TooltipContent, { side: "top", className: "z-50001", children: "Link Type" })
|
|
12300
12632
|
] }),
|
|
12301
|
-
/* @__PURE__ */
|
|
12633
|
+
/* @__PURE__ */ jsx26(
|
|
12302
12634
|
PopoverContent,
|
|
12303
12635
|
{
|
|
12304
12636
|
side: "bottom",
|
|
12305
12637
|
align: "start",
|
|
12306
12638
|
className: "w-[160px] p-1 z-50001",
|
|
12307
12639
|
onPointerDownOutside: (e) => e.preventDefault(),
|
|
12308
|
-
children: LINK_TYPES.map((type) => /* @__PURE__ */
|
|
12640
|
+
children: LINK_TYPES.map((type) => /* @__PURE__ */ jsxs13(
|
|
12309
12641
|
Button,
|
|
12310
12642
|
{
|
|
12311
12643
|
variant: "ghost",
|
|
@@ -12316,11 +12648,11 @@ var HrefMenu = () => {
|
|
|
12316
12648
|
setIsLinkTypeOpen(false);
|
|
12317
12649
|
},
|
|
12318
12650
|
children: [
|
|
12319
|
-
/* @__PURE__ */
|
|
12320
|
-
/* @__PURE__ */
|
|
12651
|
+
/* @__PURE__ */ jsxs13("span", { className: "flex items-center gap-2", children: [
|
|
12652
|
+
/* @__PURE__ */ jsx26(type.icon, { className: "size-4" }),
|
|
12321
12653
|
type.name
|
|
12322
12654
|
] }),
|
|
12323
|
-
linkType.name === type.name && /* @__PURE__ */
|
|
12655
|
+
linkType.name === type.name && /* @__PURE__ */ jsx26(CheckIcon3, { className: "size-4" })
|
|
12324
12656
|
]
|
|
12325
12657
|
},
|
|
12326
12658
|
type.name
|
|
@@ -12329,14 +12661,14 @@ var HrefMenu = () => {
|
|
|
12329
12661
|
)
|
|
12330
12662
|
] })
|
|
12331
12663
|
] }) }),
|
|
12332
|
-
/* @__PURE__ */
|
|
12664
|
+
/* @__PURE__ */ jsx26(
|
|
12333
12665
|
PopoverContent,
|
|
12334
12666
|
{
|
|
12335
12667
|
side: "bottom",
|
|
12336
12668
|
align: "start",
|
|
12337
12669
|
className: "w-[var(--radix-popover-trigger-width)] p-0 overflow-hidden z-50001",
|
|
12338
12670
|
onOpenAutoFocus: (e) => e.preventDefault(),
|
|
12339
|
-
children: /* @__PURE__ */
|
|
12671
|
+
children: /* @__PURE__ */ jsx26("div", { className: "flex flex-col max-h-[200px] overflow-y-auto", children: availablePresets.map((preset) => /* @__PURE__ */ jsxs13(
|
|
12340
12672
|
"button",
|
|
12341
12673
|
{
|
|
12342
12674
|
className: `flex items-center justify-between px-3 py-2 text-sm hover:bg-accent cursor-pointer ${inputValue === preset.value ? "bg-accent font-medium" : ""}`,
|
|
@@ -12345,11 +12677,11 @@ var HrefMenu = () => {
|
|
|
12345
12677
|
handlePresetSelect(preset.value);
|
|
12346
12678
|
},
|
|
12347
12679
|
children: [
|
|
12348
|
-
/* @__PURE__ */
|
|
12349
|
-
/* @__PURE__ */
|
|
12350
|
-
/* @__PURE__ */
|
|
12680
|
+
/* @__PURE__ */ jsxs13("div", { className: "flex flex-col items-start gap-0.5", children: [
|
|
12681
|
+
/* @__PURE__ */ jsx26("span", { className: "text-xs text-muted-foreground", children: preset.label }),
|
|
12682
|
+
/* @__PURE__ */ jsx26("span", { className: "text-sm", children: preset.value })
|
|
12351
12683
|
] }),
|
|
12352
|
-
inputValue === preset.value && /* @__PURE__ */
|
|
12684
|
+
inputValue === preset.value && /* @__PURE__ */ jsx26(CheckIcon3, { className: "w-4 h-4 shrink-0" })
|
|
12353
12685
|
]
|
|
12354
12686
|
},
|
|
12355
12687
|
preset.key
|
|
@@ -12358,11 +12690,11 @@ var HrefMenu = () => {
|
|
|
12358
12690
|
)
|
|
12359
12691
|
] })
|
|
12360
12692
|
] }),
|
|
12361
|
-
/* @__PURE__ */
|
|
12362
|
-
/* @__PURE__ */
|
|
12363
|
-
/* @__PURE__ */
|
|
12364
|
-
/* @__PURE__ */
|
|
12365
|
-
/* @__PURE__ */
|
|
12693
|
+
/* @__PURE__ */ jsx26(Separator, { className: "my-2" }),
|
|
12694
|
+
/* @__PURE__ */ jsxs13("div", { className: "flex flex-row justify-between items-center", children: [
|
|
12695
|
+
/* @__PURE__ */ jsxs13("div", { className: "flex flex-row", children: [
|
|
12696
|
+
/* @__PURE__ */ jsxs13(Tooltip, { children: [
|
|
12697
|
+
/* @__PURE__ */ jsx26(TooltipTrigger, { asChild: true, children: /* @__PURE__ */ jsx26(
|
|
12366
12698
|
Button,
|
|
12367
12699
|
{
|
|
12368
12700
|
variant: "ghost",
|
|
@@ -12370,13 +12702,13 @@ var HrefMenu = () => {
|
|
|
12370
12702
|
className: "shadow-none transition-none cursor-pointer rounded-full outline-none",
|
|
12371
12703
|
onClick: handleCopy,
|
|
12372
12704
|
disabled: !hasHref,
|
|
12373
|
-
children: showCopied ? /* @__PURE__ */
|
|
12705
|
+
children: showCopied ? /* @__PURE__ */ jsx26(CheckIcon3, { className: "text-green-600" }) : /* @__PURE__ */ jsx26(CopyIcon3, {})
|
|
12374
12706
|
}
|
|
12375
12707
|
) }),
|
|
12376
|
-
/* @__PURE__ */
|
|
12708
|
+
/* @__PURE__ */ jsx26(TooltipContent, { side: "bottom", className: "z-50001", children: showCopied ? "Copied!" : "Copy link" })
|
|
12377
12709
|
] }),
|
|
12378
|
-
/* @__PURE__ */
|
|
12379
|
-
/* @__PURE__ */
|
|
12710
|
+
/* @__PURE__ */ jsxs13(Tooltip, { children: [
|
|
12711
|
+
/* @__PURE__ */ jsx26(TooltipTrigger, { asChild: true, children: /* @__PURE__ */ jsx26(
|
|
12380
12712
|
Button,
|
|
12381
12713
|
{
|
|
12382
12714
|
variant: "ghost",
|
|
@@ -12384,13 +12716,13 @@ var HrefMenu = () => {
|
|
|
12384
12716
|
className: "shadow-none transition-none cursor-pointer rounded-full outline-none",
|
|
12385
12717
|
onClick: handleClear,
|
|
12386
12718
|
disabled: !href,
|
|
12387
|
-
children: /* @__PURE__ */
|
|
12719
|
+
children: /* @__PURE__ */ jsx26(TrashIcon3, {})
|
|
12388
12720
|
}
|
|
12389
12721
|
) }),
|
|
12390
|
-
/* @__PURE__ */
|
|
12722
|
+
/* @__PURE__ */ jsx26(TooltipContent, { side: "bottom", className: "z-50001", children: "Remove link" })
|
|
12391
12723
|
] })
|
|
12392
12724
|
] }),
|
|
12393
|
-
/* @__PURE__ */
|
|
12725
|
+
/* @__PURE__ */ jsx26("div", { children: /* @__PURE__ */ jsx26(
|
|
12394
12726
|
Button,
|
|
12395
12727
|
{
|
|
12396
12728
|
variant: "default",
|
|
@@ -12405,14 +12737,14 @@ var HrefMenu = () => {
|
|
|
12405
12737
|
};
|
|
12406
12738
|
|
|
12407
12739
|
// src/core/editor/components/element-gear/button/float.tsx
|
|
12408
|
-
import { Fragment as Fragment6, jsx as
|
|
12740
|
+
import { Fragment as Fragment6, jsx as jsx27, jsxs as jsxs14 } from "react/jsx-runtime";
|
|
12409
12741
|
var ButtonFloat = () => {
|
|
12410
12742
|
const { href, hasHref } = useHref();
|
|
12411
|
-
return /* @__PURE__ */
|
|
12412
|
-
hasHref && /* @__PURE__ */
|
|
12413
|
-
/* @__PURE__ */
|
|
12414
|
-
/* @__PURE__ */
|
|
12415
|
-
/* @__PURE__ */
|
|
12743
|
+
return /* @__PURE__ */ jsxs14(Fragment6, { children: [
|
|
12744
|
+
hasHref && /* @__PURE__ */ jsx27(FloatLinkPreview, { href }),
|
|
12745
|
+
/* @__PURE__ */ jsx27(HrefMenu, {}),
|
|
12746
|
+
/* @__PURE__ */ jsx27(DuplicateButton, {}),
|
|
12747
|
+
/* @__PURE__ */ jsx27(DeleteButton, {})
|
|
12416
12748
|
] });
|
|
12417
12749
|
};
|
|
12418
12750
|
|
|
@@ -12420,11 +12752,11 @@ var ButtonFloat = () => {
|
|
|
12420
12752
|
import { ChevronsLeftRightIcon, ChevronsRightLeftIcon, MoreHorizontalIcon } from "lucide-react";
|
|
12421
12753
|
|
|
12422
12754
|
// src/core/editor/hooks/use-full-width-toggle.ts
|
|
12423
|
-
import { useCallback as
|
|
12755
|
+
import { useCallback as useCallback7, useMemo as useMemo7 } from "react";
|
|
12424
12756
|
import { get as lodashGet3 } from "lodash";
|
|
12425
12757
|
function useFullWidthToggle() {
|
|
12426
12758
|
const { focusIdx, template, updateElement } = useEditorStore();
|
|
12427
|
-
const { element, isFullWidth } =
|
|
12759
|
+
const { element, isFullWidth } = useMemo7(() => {
|
|
12428
12760
|
if (!focusIdx || !template) return { element: null, isFullWidth: false };
|
|
12429
12761
|
const path = focusIdx.startsWith("content.") ? focusIdx.replace("content.", "content[0].").replace(/\.\[(\d+)\]/g, "[$1]") : focusIdx;
|
|
12430
12762
|
const el = lodashGet3(template, path);
|
|
@@ -12433,7 +12765,7 @@ function useFullWidthToggle() {
|
|
|
12433
12765
|
isFullWidth: el?.attributes?.["full-width"] === "full-width"
|
|
12434
12766
|
};
|
|
12435
12767
|
}, [focusIdx, template]);
|
|
12436
|
-
const handleToggleFullWidth =
|
|
12768
|
+
const handleToggleFullWidth = useCallback7(() => {
|
|
12437
12769
|
if (!focusIdx || !element) return;
|
|
12438
12770
|
const newAttributes = { ...element.attributes };
|
|
12439
12771
|
if (isFullWidth) {
|
|
@@ -12447,20 +12779,20 @@ function useFullWidthToggle() {
|
|
|
12447
12779
|
}
|
|
12448
12780
|
|
|
12449
12781
|
// src/core/editor/components/element-gear/section/float.tsx
|
|
12450
|
-
import { Fragment as Fragment7, jsx as
|
|
12782
|
+
import { Fragment as Fragment7, jsx as jsx28, jsxs as jsxs15 } from "react/jsx-runtime";
|
|
12451
12783
|
var SectionFloat = () => {
|
|
12452
12784
|
const { isFullWidth, handleToggleFullWidth } = useFullWidthToggle();
|
|
12453
|
-
return /* @__PURE__ */
|
|
12454
|
-
/* @__PURE__ */
|
|
12455
|
-
/* @__PURE__ */
|
|
12456
|
-
/* @__PURE__ */
|
|
12457
|
-
/* @__PURE__ */
|
|
12458
|
-
/* @__PURE__ */
|
|
12459
|
-
/* @__PURE__ */
|
|
12785
|
+
return /* @__PURE__ */ jsxs15(Fragment7, { children: [
|
|
12786
|
+
/* @__PURE__ */ jsx28(DuplicateButton, {}),
|
|
12787
|
+
/* @__PURE__ */ jsx28(DeleteButton, {}),
|
|
12788
|
+
/* @__PURE__ */ jsxs15(DropdownMenu, { children: [
|
|
12789
|
+
/* @__PURE__ */ jsxs15(Tooltip, { children: [
|
|
12790
|
+
/* @__PURE__ */ jsx28(TooltipTrigger, { asChild: true, children: /* @__PURE__ */ jsx28(DropdownMenuTrigger, { asChild: true, children: /* @__PURE__ */ jsx28(Button, { variant: "ghost", size: "icon", className: floatButtonVariants, children: /* @__PURE__ */ jsx28(MoreHorizontalIcon, { className: "w-4 h-4" }) }) }) }),
|
|
12791
|
+
/* @__PURE__ */ jsx28(TooltipContent, { side: "bottom", children: "More" })
|
|
12460
12792
|
] }),
|
|
12461
|
-
/* @__PURE__ */
|
|
12462
|
-
isFullWidth ? /* @__PURE__ */
|
|
12463
|
-
/* @__PURE__ */
|
|
12793
|
+
/* @__PURE__ */ jsx28(DropdownMenuContent, { side: "bottom", className: "w-[200px]", children: /* @__PURE__ */ jsxs15(DropdownMenuItem, { onClick: handleToggleFullWidth, children: [
|
|
12794
|
+
isFullWidth ? /* @__PURE__ */ jsx28(ChevronsRightLeftIcon, { className: "w-4 h-4" }) : /* @__PURE__ */ jsx28(ChevronsLeftRightIcon, { className: "w-4 h-4" }),
|
|
12795
|
+
/* @__PURE__ */ jsx28("p", { children: isFullWidth ? "Reset to original width" : "Expand to full width" })
|
|
12464
12796
|
] }) })
|
|
12465
12797
|
] })
|
|
12466
12798
|
] });
|
|
@@ -12470,11 +12802,11 @@ var SectionFloat = () => {
|
|
|
12470
12802
|
import { CheckIcon as CheckIcon4, ChevronsLeftRightIcon as ChevronsLeftRightIcon2, ChevronsRightLeftIcon as ChevronsRightLeftIcon2, Layers2Icon, MoreHorizontalIcon as MoreHorizontalIcon2 } from "lucide-react";
|
|
12471
12803
|
|
|
12472
12804
|
// src/core/editor/hooks/use-no-wrap.ts
|
|
12473
|
-
import { useCallback as
|
|
12805
|
+
import { useCallback as useCallback8, useMemo as useMemo8 } from "react";
|
|
12474
12806
|
import { get as lodashGet4 } from "lodash";
|
|
12475
12807
|
function useNoWrap() {
|
|
12476
12808
|
const { focusIdx, template, updateElement } = useEditorStore();
|
|
12477
|
-
const { element, noWrap } =
|
|
12809
|
+
const { element, noWrap } = useMemo8(() => {
|
|
12478
12810
|
if (!focusIdx || !template) return { element: null, noWrap: false };
|
|
12479
12811
|
const path = focusIdx.startsWith("content.") ? focusIdx.replace("content.", "content[0].").replace(/\.\[(\d+)\]/g, "[$1]") : focusIdx;
|
|
12480
12812
|
const el = lodashGet4(template, path);
|
|
@@ -12483,7 +12815,7 @@ function useNoWrap() {
|
|
|
12483
12815
|
noWrap: el?.data?.value?.noWrap === true
|
|
12484
12816
|
};
|
|
12485
12817
|
}, [focusIdx, template]);
|
|
12486
|
-
const handleToggleNoWrap =
|
|
12818
|
+
const handleToggleNoWrap = useCallback8(() => {
|
|
12487
12819
|
if (!focusIdx || !element) return;
|
|
12488
12820
|
updateElement(focusIdx, {
|
|
12489
12821
|
data: {
|
|
@@ -12498,30 +12830,30 @@ function useNoWrap() {
|
|
|
12498
12830
|
}
|
|
12499
12831
|
|
|
12500
12832
|
// src/core/editor/components/element-gear/section-column/float.tsx
|
|
12501
|
-
import { Fragment as Fragment8, jsx as
|
|
12833
|
+
import { Fragment as Fragment8, jsx as jsx29, jsxs as jsxs16 } from "react/jsx-runtime";
|
|
12502
12834
|
var SectionColumnFloat = () => {
|
|
12503
12835
|
const { isFullWidth, handleToggleFullWidth } = useFullWidthToggle();
|
|
12504
12836
|
const { noWrap, handleToggleNoWrap } = useNoWrap();
|
|
12505
|
-
return /* @__PURE__ */
|
|
12506
|
-
/* @__PURE__ */
|
|
12507
|
-
/* @__PURE__ */
|
|
12508
|
-
/* @__PURE__ */
|
|
12509
|
-
/* @__PURE__ */
|
|
12510
|
-
/* @__PURE__ */
|
|
12511
|
-
/* @__PURE__ */
|
|
12837
|
+
return /* @__PURE__ */ jsxs16(Fragment8, { children: [
|
|
12838
|
+
/* @__PURE__ */ jsx29(DuplicateButton, {}),
|
|
12839
|
+
/* @__PURE__ */ jsx29(DeleteButton, {}),
|
|
12840
|
+
/* @__PURE__ */ jsxs16(DropdownMenu, { children: [
|
|
12841
|
+
/* @__PURE__ */ jsxs16(Tooltip, { children: [
|
|
12842
|
+
/* @__PURE__ */ jsx29(TooltipTrigger, { asChild: true, children: /* @__PURE__ */ jsx29(DropdownMenuTrigger, { asChild: true, children: /* @__PURE__ */ jsx29(Button, { variant: "ghost", size: "icon", className: floatButtonVariants, children: /* @__PURE__ */ jsx29(MoreHorizontalIcon2, { className: "w-4 h-4" }) }) }) }),
|
|
12843
|
+
/* @__PURE__ */ jsx29(TooltipContent, { side: "bottom", children: "More" })
|
|
12512
12844
|
] }),
|
|
12513
|
-
/* @__PURE__ */
|
|
12514
|
-
/* @__PURE__ */
|
|
12515
|
-
/* @__PURE__ */
|
|
12516
|
-
/* @__PURE__ */
|
|
12517
|
-
/* @__PURE__ */
|
|
12518
|
-
!noWrap && /* @__PURE__ */
|
|
12845
|
+
/* @__PURE__ */ jsxs16(DropdownMenuContent, { side: "bottom", className: "w-[250px]", children: [
|
|
12846
|
+
/* @__PURE__ */ jsxs16(DropdownMenuItem, { onClick: handleToggleNoWrap, children: [
|
|
12847
|
+
/* @__PURE__ */ jsx29(Layers2Icon, { className: "w-4 h-4" }),
|
|
12848
|
+
/* @__PURE__ */ jsxs16("div", { className: "flex items-center gap-2 w-full", children: [
|
|
12849
|
+
/* @__PURE__ */ jsx29("p", { className: "w-full", children: noWrap ? "Columns collapse" : "Columns collapse" }),
|
|
12850
|
+
!noWrap && /* @__PURE__ */ jsx29(CheckIcon4, { className: "w-4 h-4" })
|
|
12519
12851
|
] })
|
|
12520
12852
|
] }),
|
|
12521
|
-
/* @__PURE__ */
|
|
12522
|
-
/* @__PURE__ */
|
|
12523
|
-
isFullWidth ? /* @__PURE__ */
|
|
12524
|
-
/* @__PURE__ */
|
|
12853
|
+
/* @__PURE__ */ jsx29(DropdownMenuSeparator, {}),
|
|
12854
|
+
/* @__PURE__ */ jsxs16(DropdownMenuItem, { onClick: handleToggleFullWidth, children: [
|
|
12855
|
+
isFullWidth ? /* @__PURE__ */ jsx29(ChevronsRightLeftIcon2, { className: "w-4 h-4" }) : /* @__PURE__ */ jsx29(ChevronsLeftRightIcon2, { className: "w-4 h-4" }),
|
|
12856
|
+
/* @__PURE__ */ jsx29("p", { children: isFullWidth ? "Reset to original width" : "Expand to full width" })
|
|
12525
12857
|
] })
|
|
12526
12858
|
] })
|
|
12527
12859
|
] })
|
|
@@ -12529,11 +12861,11 @@ var SectionColumnFloat = () => {
|
|
|
12529
12861
|
};
|
|
12530
12862
|
|
|
12531
12863
|
// src/core/editor/components/element-gear/spacer/float.tsx
|
|
12532
|
-
import { Fragment as Fragment9, jsx as
|
|
12864
|
+
import { Fragment as Fragment9, jsx as jsx30, jsxs as jsxs17 } from "react/jsx-runtime";
|
|
12533
12865
|
var SpacerFloat = () => {
|
|
12534
|
-
return /* @__PURE__ */
|
|
12535
|
-
/* @__PURE__ */
|
|
12536
|
-
/* @__PURE__ */
|
|
12866
|
+
return /* @__PURE__ */ jsxs17(Fragment9, { children: [
|
|
12867
|
+
/* @__PURE__ */ jsx30(DuplicateButton, {}),
|
|
12868
|
+
/* @__PURE__ */ jsx30(DeleteButton, {})
|
|
12537
12869
|
] });
|
|
12538
12870
|
};
|
|
12539
12871
|
|
|
@@ -12541,16 +12873,16 @@ var SpacerFloat = () => {
|
|
|
12541
12873
|
import { MoreHorizontalIcon as MoreHorizontalIcon3, PlusCircleIcon } from "lucide-react";
|
|
12542
12874
|
|
|
12543
12875
|
// src/core/editor/components/email-template-v2/context/sidebar-context.tsx
|
|
12544
|
-
import { createContext, useContext, useState as
|
|
12545
|
-
import { jsx as
|
|
12876
|
+
import { createContext, useContext, useState as useState5 } from "react";
|
|
12877
|
+
import { jsx as jsx31 } from "react/jsx-runtime";
|
|
12546
12878
|
var SidebarContext = createContext(null);
|
|
12547
12879
|
var PICKER_VIEWS = ["color", "images", "add-social"];
|
|
12548
12880
|
function SidebarProvider({ children }) {
|
|
12549
|
-
const [activeView, setActiveViewState] =
|
|
12550
|
-
const [lastView, setLastView] =
|
|
12551
|
-
const [colorType, setColorType] =
|
|
12552
|
-
const [colorTarget, setColorTarget] =
|
|
12553
|
-
const [imageTarget, setImageTarget] =
|
|
12881
|
+
const [activeView, setActiveViewState] = useState5("elements");
|
|
12882
|
+
const [lastView, setLastView] = useState5("elements");
|
|
12883
|
+
const [colorType, setColorType] = useState5("Color");
|
|
12884
|
+
const [colorTarget, setColorTarget] = useState5(null);
|
|
12885
|
+
const [imageTarget, setImageTarget] = useState5(null);
|
|
12554
12886
|
const setActiveView = (view) => {
|
|
12555
12887
|
if (view !== activeView) {
|
|
12556
12888
|
if (!PICKER_VIEWS.includes(activeView)) {
|
|
@@ -12559,7 +12891,7 @@ function SidebarProvider({ children }) {
|
|
|
12559
12891
|
}
|
|
12560
12892
|
setActiveViewState(view);
|
|
12561
12893
|
};
|
|
12562
|
-
return /* @__PURE__ */
|
|
12894
|
+
return /* @__PURE__ */ jsx31(SidebarContext.Provider, { value: { activeView, setActiveView, lastView, colorType, setColorType, colorTarget, setColorTarget, imageTarget, setImageTarget }, children });
|
|
12563
12895
|
}
|
|
12564
12896
|
function useSidebarContext() {
|
|
12565
12897
|
const context = useContext(SidebarContext);
|
|
@@ -12570,33 +12902,33 @@ function useSidebarContext() {
|
|
|
12570
12902
|
}
|
|
12571
12903
|
|
|
12572
12904
|
// src/core/editor/components/element-gear/social/float.tsx
|
|
12573
|
-
import { Fragment as Fragment10, jsx as
|
|
12905
|
+
import { Fragment as Fragment10, jsx as jsx32, jsxs as jsxs18 } from "react/jsx-runtime";
|
|
12574
12906
|
var SocialFloat = () => {
|
|
12575
12907
|
const { setActiveView } = useSidebarContext();
|
|
12576
|
-
return /* @__PURE__ */
|
|
12577
|
-
/* @__PURE__ */
|
|
12578
|
-
/* @__PURE__ */
|
|
12579
|
-
/* @__PURE__ */
|
|
12908
|
+
return /* @__PURE__ */ jsxs18(Fragment10, { children: [
|
|
12909
|
+
/* @__PURE__ */ jsxs18(Tooltip, { children: [
|
|
12910
|
+
/* @__PURE__ */ jsx32(TooltipTrigger, { asChild: true, children: /* @__PURE__ */ jsx32(Button, { variant: "ghost", className: floatButtonVariants, onClick: () => setActiveView("add-social"), children: /* @__PURE__ */ jsx32(PlusCircleIcon, {}) }) }),
|
|
12911
|
+
/* @__PURE__ */ jsx32(TooltipContent, { side: "bottom", children: "Add Social" })
|
|
12580
12912
|
] }),
|
|
12581
|
-
/* @__PURE__ */
|
|
12582
|
-
/* @__PURE__ */
|
|
12583
|
-
/* @__PURE__ */
|
|
12584
|
-
/* @__PURE__ */
|
|
12585
|
-
/* @__PURE__ */
|
|
12586
|
-
/* @__PURE__ */
|
|
12913
|
+
/* @__PURE__ */ jsx32(DuplicateButton, {}),
|
|
12914
|
+
/* @__PURE__ */ jsx32(DeleteButton, {}),
|
|
12915
|
+
/* @__PURE__ */ jsxs18(DropdownMenu, { children: [
|
|
12916
|
+
/* @__PURE__ */ jsxs18(Tooltip, { children: [
|
|
12917
|
+
/* @__PURE__ */ jsx32(TooltipTrigger, { asChild: true, children: /* @__PURE__ */ jsx32(DropdownMenuTrigger, { asChild: true, children: /* @__PURE__ */ jsx32(Button, { variant: "ghost", size: "icon", className: floatButtonVariants, children: /* @__PURE__ */ jsx32(MoreHorizontalIcon3, { className: "w-4 h-4" }) }) }) }),
|
|
12918
|
+
/* @__PURE__ */ jsx32(TooltipContent, { side: "bottom", children: "More" })
|
|
12587
12919
|
] }),
|
|
12588
|
-
/* @__PURE__ */
|
|
12589
|
-
/* @__PURE__ */
|
|
12590
|
-
/* @__PURE__ */
|
|
12920
|
+
/* @__PURE__ */ jsx32(DropdownMenuContent, { side: "bottom", className: "w-[200px]", children: /* @__PURE__ */ jsxs18(DropdownMenuItem, { onClick: () => setActiveView("add-social"), children: [
|
|
12921
|
+
/* @__PURE__ */ jsx32(PlusCircleIcon, { className: "w-4 h-4" }),
|
|
12922
|
+
/* @__PURE__ */ jsx32("p", { children: "Add Social" })
|
|
12591
12923
|
] }) })
|
|
12592
12924
|
] })
|
|
12593
12925
|
] });
|
|
12594
12926
|
};
|
|
12595
12927
|
|
|
12596
12928
|
// src/components/ui/textarea.tsx
|
|
12597
|
-
import { jsx as
|
|
12929
|
+
import { jsx as jsx33 } from "react/jsx-runtime";
|
|
12598
12930
|
function Textarea({ className, ...props }) {
|
|
12599
|
-
return /* @__PURE__ */
|
|
12931
|
+
return /* @__PURE__ */ jsx33(
|
|
12600
12932
|
"textarea",
|
|
12601
12933
|
{
|
|
12602
12934
|
"data-slot": "textarea",
|
|
@@ -12611,38 +12943,39 @@ function Textarea({ className, ...props }) {
|
|
|
12611
12943
|
|
|
12612
12944
|
// src/core/editor/components/element-gear/social-item/float.tsx
|
|
12613
12945
|
import { Accessibility, MoreHorizontalIcon as MoreHorizontalIcon4, TrashIcon as TrashIcon4 } from "lucide-react";
|
|
12614
|
-
import { useState as
|
|
12946
|
+
import { useState as useState7, useCallback as useCallback11 } from "react";
|
|
12615
12947
|
|
|
12616
12948
|
// src/core/editor/components/social-item-menu.tsx
|
|
12617
|
-
import { useState as
|
|
12949
|
+
import { useState as useState6, useMemo as useMemo9, useCallback as useCallback9 } from "react";
|
|
12618
12950
|
import { PencilIcon as PencilIcon3, CheckIcon as CheckIcon5, CopyIcon as CopyIcon4 } from "lucide-react";
|
|
12619
12951
|
import { get as lodashGet5 } from "lodash";
|
|
12620
|
-
import { jsx as
|
|
12952
|
+
import { jsx as jsx34, jsxs as jsxs19 } from "react/jsx-runtime";
|
|
12621
12953
|
var SocialItemMenu = ({ hasHref }) => {
|
|
12622
|
-
const [isOpen, setIsOpen] =
|
|
12623
|
-
const [showCopied, setShowCopied] =
|
|
12624
|
-
const [hrefInputValue, setHrefInputValue] =
|
|
12625
|
-
const [contentInputValue, setContentInputValue] =
|
|
12954
|
+
const [isOpen, setIsOpen] = useState6(false);
|
|
12955
|
+
const [showCopied, setShowCopied] = useState6(false);
|
|
12956
|
+
const [hrefInputValue, setHrefInputValue] = useState6("");
|
|
12957
|
+
const [contentInputValue, setContentInputValue] = useState6("");
|
|
12626
12958
|
const { href, setHref, copyHref } = useHref();
|
|
12627
12959
|
const { focusIdx, template, updateElement } = useEditorStore();
|
|
12628
|
-
const element =
|
|
12960
|
+
const element = useMemo9(() => {
|
|
12629
12961
|
if (!focusIdx || !template) return null;
|
|
12630
12962
|
const path = focusIdx.startsWith("content.") ? focusIdx.replace("content.", "content[0].").replace(/\.?\[(\d+)\]/g, "[$1]") : focusIdx;
|
|
12631
12963
|
return lodashGet5(template, path);
|
|
12632
12964
|
}, [focusIdx, template]);
|
|
12633
12965
|
const content = element?.data?.value?.content || "";
|
|
12634
|
-
|
|
12635
|
-
|
|
12966
|
+
const handleOpenChange = useCallback9((open) => {
|
|
12967
|
+
setIsOpen(open);
|
|
12968
|
+
if (open) {
|
|
12636
12969
|
setHrefInputValue(href);
|
|
12637
12970
|
setContentInputValue(content);
|
|
12638
12971
|
}
|
|
12639
|
-
}, [
|
|
12640
|
-
const handleCopy =
|
|
12972
|
+
}, [href, content]);
|
|
12973
|
+
const handleCopy = useCallback9(async () => {
|
|
12641
12974
|
await copyHref();
|
|
12642
12975
|
setShowCopied(true);
|
|
12643
12976
|
setTimeout(() => setShowCopied(false), 2e3);
|
|
12644
12977
|
}, [copyHref]);
|
|
12645
|
-
const handleDone =
|
|
12978
|
+
const handleDone = useCallback9(() => {
|
|
12646
12979
|
setHref(normalizeWebsiteUrl(hrefInputValue));
|
|
12647
12980
|
if (focusIdx && element) {
|
|
12648
12981
|
updateElement(focusIdx, {
|
|
@@ -12656,33 +12989,33 @@ var SocialItemMenu = ({ hasHref }) => {
|
|
|
12656
12989
|
}
|
|
12657
12990
|
setIsOpen(false);
|
|
12658
12991
|
}, [hrefInputValue, contentInputValue, setHref, focusIdx, element, updateElement]);
|
|
12659
|
-
return /* @__PURE__ */
|
|
12660
|
-
/* @__PURE__ */
|
|
12661
|
-
/* @__PURE__ */
|
|
12992
|
+
return /* @__PURE__ */ jsxs19(DropdownMenu, { open: isOpen, onOpenChange: handleOpenChange, children: [
|
|
12993
|
+
/* @__PURE__ */ jsxs19(Tooltip, { children: [
|
|
12994
|
+
/* @__PURE__ */ jsx34(TooltipTrigger, { asChild: true, children: /* @__PURE__ */ jsx34(DropdownMenuTrigger, { asChild: true, children: hasHref ? /* @__PURE__ */ jsx34(
|
|
12662
12995
|
Button,
|
|
12663
12996
|
{
|
|
12664
12997
|
variant: "ghost",
|
|
12665
12998
|
size: "icon",
|
|
12666
12999
|
className: floatButtonVariants,
|
|
12667
|
-
children: /* @__PURE__ */
|
|
13000
|
+
children: /* @__PURE__ */ jsx34(PencilIcon3, { className: "size-4" })
|
|
12668
13001
|
}
|
|
12669
|
-
) : /* @__PURE__ */
|
|
13002
|
+
) : /* @__PURE__ */ jsxs19(
|
|
12670
13003
|
Button,
|
|
12671
13004
|
{
|
|
12672
13005
|
variant: "ghost",
|
|
12673
13006
|
className: "shadow-none transition-none cursor-pointer rounded-full outline-none",
|
|
12674
13007
|
children: [
|
|
12675
|
-
/* @__PURE__ */
|
|
12676
|
-
/* @__PURE__ */
|
|
13008
|
+
/* @__PURE__ */ jsx34(PencilIcon3, { className: "size-4" }),
|
|
13009
|
+
/* @__PURE__ */ jsx34("p", { children: "Edit" })
|
|
12677
13010
|
]
|
|
12678
13011
|
}
|
|
12679
13012
|
) }) }),
|
|
12680
|
-
/* @__PURE__ */
|
|
13013
|
+
/* @__PURE__ */ jsx34(TooltipContent, { side: "bottom", children: "Edit" })
|
|
12681
13014
|
] }),
|
|
12682
|
-
/* @__PURE__ */
|
|
12683
|
-
/* @__PURE__ */
|
|
12684
|
-
/* @__PURE__ */
|
|
12685
|
-
/* @__PURE__ */
|
|
13015
|
+
/* @__PURE__ */ jsxs19(DropdownMenuContent, { side: "bottom", className: "w-[250px] p-3 shadow-lg z-50001", children: [
|
|
13016
|
+
/* @__PURE__ */ jsxs19("div", { className: "flex flex-col gap-2 mb-2", children: [
|
|
13017
|
+
/* @__PURE__ */ jsx34(Label, { className: "text-xs font-medium", children: "Enter a link" }),
|
|
13018
|
+
/* @__PURE__ */ jsx34(
|
|
12686
13019
|
Input,
|
|
12687
13020
|
{
|
|
12688
13021
|
type: "text",
|
|
@@ -12694,9 +13027,9 @@ var SocialItemMenu = ({ hasHref }) => {
|
|
|
12694
13027
|
}
|
|
12695
13028
|
)
|
|
12696
13029
|
] }),
|
|
12697
|
-
/* @__PURE__ */
|
|
12698
|
-
/* @__PURE__ */
|
|
12699
|
-
/* @__PURE__ */
|
|
13030
|
+
/* @__PURE__ */ jsxs19("div", { className: "flex flex-col gap-2", children: [
|
|
13031
|
+
/* @__PURE__ */ jsx34(Label, { className: "text-xs font-medium", children: "Content" }),
|
|
13032
|
+
/* @__PURE__ */ jsx34(
|
|
12700
13033
|
Input,
|
|
12701
13034
|
{
|
|
12702
13035
|
type: "text",
|
|
@@ -12707,10 +13040,10 @@ var SocialItemMenu = ({ hasHref }) => {
|
|
|
12707
13040
|
}
|
|
12708
13041
|
)
|
|
12709
13042
|
] }),
|
|
12710
|
-
/* @__PURE__ */
|
|
12711
|
-
/* @__PURE__ */
|
|
12712
|
-
/* @__PURE__ */
|
|
12713
|
-
/* @__PURE__ */
|
|
13043
|
+
/* @__PURE__ */ jsx34(Separator, { className: "my-2" }),
|
|
13044
|
+
/* @__PURE__ */ jsxs19("div", { className: "flex flex-row justify-between items-center", children: [
|
|
13045
|
+
/* @__PURE__ */ jsx34("div", { className: "flex flex-row", children: /* @__PURE__ */ jsxs19(Tooltip, { children: [
|
|
13046
|
+
/* @__PURE__ */ jsx34(TooltipTrigger, { asChild: true, children: /* @__PURE__ */ jsx34(
|
|
12714
13047
|
Button,
|
|
12715
13048
|
{
|
|
12716
13049
|
variant: "ghost",
|
|
@@ -12718,12 +13051,12 @@ var SocialItemMenu = ({ hasHref }) => {
|
|
|
12718
13051
|
className: "shadow-none transition-none cursor-pointer rounded-full outline-none",
|
|
12719
13052
|
onClick: handleCopy,
|
|
12720
13053
|
disabled: !hasHref,
|
|
12721
|
-
children: showCopied ? /* @__PURE__ */
|
|
13054
|
+
children: showCopied ? /* @__PURE__ */ jsx34(CheckIcon5, { className: "text-green-600" }) : /* @__PURE__ */ jsx34(CopyIcon4, {})
|
|
12722
13055
|
}
|
|
12723
13056
|
) }),
|
|
12724
|
-
/* @__PURE__ */
|
|
13057
|
+
/* @__PURE__ */ jsx34(TooltipContent, { side: "bottom", className: "z-50001", children: showCopied ? "Copied!" : "Copy link" })
|
|
12725
13058
|
] }) }),
|
|
12726
|
-
/* @__PURE__ */
|
|
13059
|
+
/* @__PURE__ */ jsx34("div", { children: /* @__PURE__ */ jsx34(
|
|
12727
13060
|
Button,
|
|
12728
13061
|
{
|
|
12729
13062
|
variant: "default",
|
|
@@ -12738,11 +13071,11 @@ var SocialItemMenu = ({ hasHref }) => {
|
|
|
12738
13071
|
};
|
|
12739
13072
|
|
|
12740
13073
|
// src/core/editor/hooks/use-alt.ts
|
|
12741
|
-
import { useMemo as
|
|
13074
|
+
import { useMemo as useMemo10, useCallback as useCallback10 } from "react";
|
|
12742
13075
|
import { get as lodashGet6 } from "lodash";
|
|
12743
13076
|
var useAlt = () => {
|
|
12744
13077
|
const { focusIdx, updateElement, template } = useEditorStore();
|
|
12745
|
-
const { element, alt } =
|
|
13078
|
+
const { element, alt } = useMemo10(() => {
|
|
12746
13079
|
if (!focusIdx || !template) {
|
|
12747
13080
|
return { element: null, alt: "" };
|
|
12748
13081
|
}
|
|
@@ -12753,13 +13086,13 @@ var useAlt = () => {
|
|
|
12753
13086
|
alt: el?.attributes?.alt || ""
|
|
12754
13087
|
};
|
|
12755
13088
|
}, [focusIdx, template]);
|
|
12756
|
-
const setAlt =
|
|
13089
|
+
const setAlt = useCallback10((text2) => {
|
|
12757
13090
|
if (!focusIdx || !element) return;
|
|
12758
13091
|
updateElement(focusIdx, {
|
|
12759
13092
|
attributes: { ...element.attributes, alt: text2 }
|
|
12760
13093
|
});
|
|
12761
13094
|
}, [focusIdx, element, updateElement]);
|
|
12762
|
-
const clearAlt =
|
|
13095
|
+
const clearAlt = useCallback10(() => {
|
|
12763
13096
|
if (!focusIdx || !element) return;
|
|
12764
13097
|
updateElement(focusIdx, {
|
|
12765
13098
|
attributes: { ...element.attributes, alt: "" }
|
|
@@ -12775,21 +13108,22 @@ var useAlt = () => {
|
|
|
12775
13108
|
};
|
|
12776
13109
|
|
|
12777
13110
|
// src/core/editor/components/element-gear/social-item/float.tsx
|
|
12778
|
-
import { Fragment as Fragment11, jsx as
|
|
13111
|
+
import { Fragment as Fragment11, jsx as jsx35, jsxs as jsxs20 } from "react/jsx-runtime";
|
|
12779
13112
|
var SocialItemFloat = () => {
|
|
12780
13113
|
const { href, hasHref } = useHref();
|
|
12781
13114
|
const { alt, setAlt } = useAlt();
|
|
12782
13115
|
const { focusIdx, template, deleteElement } = useEditorStore();
|
|
12783
|
-
const [dropdownOpen, setDropdownOpen] =
|
|
12784
|
-
const [altInputValue, setAltInputValue] =
|
|
13116
|
+
const [dropdownOpen, setDropdownOpen] = useState7(false);
|
|
13117
|
+
const [altInputValue, setAltInputValue] = useState7("");
|
|
12785
13118
|
const parentSocial = focusIdx ? getParentByIdx(template, focusIdx) : null;
|
|
12786
13119
|
const childrenCount = parentSocial?.children?.length || 0;
|
|
12787
13120
|
const canDelete = childrenCount > 1;
|
|
12788
|
-
|
|
12789
|
-
|
|
13121
|
+
const handleDropdownOpenChange = useCallback11((open) => {
|
|
13122
|
+
setDropdownOpen(open);
|
|
13123
|
+
if (open) {
|
|
12790
13124
|
setAltInputValue(alt);
|
|
12791
13125
|
}
|
|
12792
|
-
}, [
|
|
13126
|
+
}, [alt]);
|
|
12793
13127
|
const handleSaveAlt = () => {
|
|
12794
13128
|
setAlt(altInputValue);
|
|
12795
13129
|
setDropdownOpen(false);
|
|
@@ -12799,37 +13133,37 @@ var SocialItemFloat = () => {
|
|
|
12799
13133
|
deleteElement(focusIdx);
|
|
12800
13134
|
}
|
|
12801
13135
|
};
|
|
12802
|
-
return /* @__PURE__ */
|
|
12803
|
-
hasHref && /* @__PURE__ */
|
|
12804
|
-
/* @__PURE__ */
|
|
12805
|
-
/* @__PURE__ */
|
|
12806
|
-
/* @__PURE__ */
|
|
13136
|
+
return /* @__PURE__ */ jsxs20(Fragment11, { children: [
|
|
13137
|
+
hasHref && /* @__PURE__ */ jsx35(FloatLinkPreview, { href }),
|
|
13138
|
+
/* @__PURE__ */ jsx35(SocialItemMenu, { hasHref }),
|
|
13139
|
+
/* @__PURE__ */ jsxs20(Tooltip, { children: [
|
|
13140
|
+
/* @__PURE__ */ jsx35(TooltipTrigger, { asChild: true, children: /* @__PURE__ */ jsx35(
|
|
12807
13141
|
Button,
|
|
12808
13142
|
{
|
|
12809
13143
|
variant: "ghost",
|
|
12810
13144
|
className: floatButtonVariants,
|
|
12811
13145
|
onClick: handleDelete,
|
|
12812
13146
|
disabled: !canDelete,
|
|
12813
|
-
children: /* @__PURE__ */
|
|
13147
|
+
children: /* @__PURE__ */ jsx35(TrashIcon4, { className: "size-4" })
|
|
12814
13148
|
}
|
|
12815
13149
|
) }),
|
|
12816
|
-
/* @__PURE__ */
|
|
13150
|
+
/* @__PURE__ */ jsx35(TooltipContent, { side: "bottom", children: canDelete ? "Delete" : "Cannot delete last item" })
|
|
12817
13151
|
] }),
|
|
12818
|
-
/* @__PURE__ */
|
|
12819
|
-
/* @__PURE__ */
|
|
12820
|
-
/* @__PURE__ */
|
|
12821
|
-
/* @__PURE__ */
|
|
13152
|
+
/* @__PURE__ */ jsxs20(DropdownMenu, { open: dropdownOpen, onOpenChange: handleDropdownOpenChange, children: [
|
|
13153
|
+
/* @__PURE__ */ jsxs20(Tooltip, { children: [
|
|
13154
|
+
/* @__PURE__ */ jsx35(TooltipTrigger, { asChild: true, children: /* @__PURE__ */ jsx35(DropdownMenuTrigger, { asChild: true, children: /* @__PURE__ */ jsx35(Button, { variant: "ghost", size: "icon", className: floatButtonVariants, children: /* @__PURE__ */ jsx35(MoreHorizontalIcon4, { className: "w-4 h-4" }) }) }) }),
|
|
13155
|
+
/* @__PURE__ */ jsx35(TooltipContent, { side: "bottom", children: "More" })
|
|
12822
13156
|
] }),
|
|
12823
|
-
/* @__PURE__ */
|
|
12824
|
-
/* @__PURE__ */
|
|
12825
|
-
/* @__PURE__ */
|
|
12826
|
-
/* @__PURE__ */
|
|
13157
|
+
/* @__PURE__ */ jsx35(DropdownMenuContent, { side: "bottom", className: "w-[250px] z-50001", children: /* @__PURE__ */ jsxs20(DropdownMenuSub, { children: [
|
|
13158
|
+
/* @__PURE__ */ jsxs20(DropdownMenuSubTrigger, { children: [
|
|
13159
|
+
/* @__PURE__ */ jsx35(Accessibility, { className: "w-4 h-4" }),
|
|
13160
|
+
/* @__PURE__ */ jsx35("p", { children: "Alternative Text" })
|
|
12827
13161
|
] }),
|
|
12828
|
-
/* @__PURE__ */
|
|
12829
|
-
/* @__PURE__ */
|
|
12830
|
-
/* @__PURE__ */
|
|
12831
|
-
/* @__PURE__ */
|
|
12832
|
-
/* @__PURE__ */
|
|
13162
|
+
/* @__PURE__ */ jsx35(DropdownMenuPortal, { children: /* @__PURE__ */ jsxs20(DropdownMenuSubContent, { className: "p-3 w-[250px] z-50001", children: [
|
|
13163
|
+
/* @__PURE__ */ jsxs20("div", { className: "flex flex-col gap-2 mb-2", children: [
|
|
13164
|
+
/* @__PURE__ */ jsx35(Label, { children: "Alternative Text" }),
|
|
13165
|
+
/* @__PURE__ */ jsxs20("div", { className: "relative", children: [
|
|
13166
|
+
/* @__PURE__ */ jsx35(
|
|
12833
13167
|
Textarea,
|
|
12834
13168
|
{
|
|
12835
13169
|
placeholder: "Icon image alt, for example: 'Facebook icon'",
|
|
@@ -12839,14 +13173,14 @@ var SocialItemFloat = () => {
|
|
|
12839
13173
|
onChange: (e) => setAltInputValue(e.target.value)
|
|
12840
13174
|
}
|
|
12841
13175
|
),
|
|
12842
|
-
/* @__PURE__ */
|
|
13176
|
+
/* @__PURE__ */ jsxs20("span", { className: "bg-white rounded-[12px] p-1 shadow-sm absolute bottom-2 right-2 text-xs text-muted-foreground", children: [
|
|
12843
13177
|
altInputValue.length,
|
|
12844
13178
|
"/250"
|
|
12845
13179
|
] })
|
|
12846
13180
|
] }),
|
|
12847
|
-
/* @__PURE__ */
|
|
13181
|
+
/* @__PURE__ */ jsx35("p", { className: "text-xs text-muted-foreground mb-4", children: "Be descriptive and add context to keep your alt text clear for clients who use screen readers." })
|
|
12848
13182
|
] }),
|
|
12849
|
-
/* @__PURE__ */
|
|
13183
|
+
/* @__PURE__ */ jsx35(
|
|
12850
13184
|
Button,
|
|
12851
13185
|
{
|
|
12852
13186
|
variant: "default",
|
|
@@ -12862,27 +13196,27 @@ var SocialItemFloat = () => {
|
|
|
12862
13196
|
};
|
|
12863
13197
|
|
|
12864
13198
|
// src/core/editor/components/element-gear/divider/float.tsx
|
|
12865
|
-
import { Fragment as Fragment12, jsx as
|
|
13199
|
+
import { Fragment as Fragment12, jsx as jsx36, jsxs as jsxs21 } from "react/jsx-runtime";
|
|
12866
13200
|
var DividerFloat = () => {
|
|
12867
|
-
return /* @__PURE__ */
|
|
12868
|
-
/* @__PURE__ */
|
|
12869
|
-
/* @__PURE__ */
|
|
13201
|
+
return /* @__PURE__ */ jsxs21(Fragment12, { children: [
|
|
13202
|
+
/* @__PURE__ */ jsx36(DuplicateButton, {}),
|
|
13203
|
+
/* @__PURE__ */ jsx36(DeleteButton, {})
|
|
12870
13204
|
] });
|
|
12871
13205
|
};
|
|
12872
13206
|
|
|
12873
13207
|
// src/core/editor/components/element-gear/image/float.tsx
|
|
12874
13208
|
import { Accessibility as Accessibility2, CheckIcon as CheckIcon6, MoreHorizontalIcon as MoreHorizontalIcon5, Proportions } from "lucide-react";
|
|
12875
13209
|
import lodashGet7 from "lodash/get";
|
|
12876
|
-
import { useState as
|
|
12877
|
-
import { Fragment as Fragment13, jsx as
|
|
13210
|
+
import { useState as useState8, useMemo as useMemo11, useCallback as useCallback12 } from "react";
|
|
13211
|
+
import { Fragment as Fragment13, jsx as jsx37, jsxs as jsxs22 } from "react/jsx-runtime";
|
|
12878
13212
|
var ImageFloat = () => {
|
|
12879
13213
|
const { href, hasHref } = useHref();
|
|
12880
13214
|
const { alt, setAlt, hasAlt } = useAlt();
|
|
12881
13215
|
const { focusIdx, updateElement, template } = useEditorStore();
|
|
12882
|
-
const [showMoreView, setShowMoreView] =
|
|
12883
|
-
const [dropdownOpen, setDropdownOpen] =
|
|
12884
|
-
const [altInputValue, setAltInputValue] =
|
|
12885
|
-
const { element, isFluidOnMobile } =
|
|
13216
|
+
const [showMoreView, setShowMoreView] = useState8(null);
|
|
13217
|
+
const [dropdownOpen, setDropdownOpen] = useState8(false);
|
|
13218
|
+
const [altInputValue, setAltInputValue] = useState8("");
|
|
13219
|
+
const { element, isFluidOnMobile } = useMemo11(() => {
|
|
12886
13220
|
if (!focusIdx || !template) return { element: null, isFluidOnMobile: false };
|
|
12887
13221
|
const path = focusIdx.startsWith("content.") ? focusIdx.replace("content.", "content[0].").replace(/\.\[(\d+)\]/g, "[$1]") : focusIdx;
|
|
12888
13222
|
const el = lodashGet7(template, path);
|
|
@@ -12891,7 +13225,7 @@ var ImageFloat = () => {
|
|
|
12891
13225
|
isFluidOnMobile: el?.attributes?.["fluid-on-mobile"] === "true"
|
|
12892
13226
|
};
|
|
12893
13227
|
}, [focusIdx, template]);
|
|
12894
|
-
const toggleFluidOnMobile =
|
|
13228
|
+
const toggleFluidOnMobile = useCallback12(() => {
|
|
12895
13229
|
if (!focusIdx || !element) return;
|
|
12896
13230
|
const newAttributes = { ...element.attributes };
|
|
12897
13231
|
if (isFluidOnMobile) {
|
|
@@ -12901,44 +13235,45 @@ var ImageFloat = () => {
|
|
|
12901
13235
|
}
|
|
12902
13236
|
updateElement(focusIdx, { attributes: newAttributes });
|
|
12903
13237
|
}, [focusIdx, element, isFluidOnMobile, updateElement]);
|
|
12904
|
-
|
|
12905
|
-
|
|
13238
|
+
const handleDropdownOpenChange = useCallback12((open) => {
|
|
13239
|
+
setDropdownOpen(open);
|
|
13240
|
+
if (open) {
|
|
12906
13241
|
setAltInputValue(alt);
|
|
12907
13242
|
}
|
|
12908
|
-
}, [
|
|
13243
|
+
}, [alt]);
|
|
12909
13244
|
const handleSaveAlt = () => {
|
|
12910
13245
|
setAlt(altInputValue);
|
|
12911
13246
|
setDropdownOpen(false);
|
|
12912
13247
|
};
|
|
12913
|
-
return /* @__PURE__ */
|
|
12914
|
-
hasHref && /* @__PURE__ */
|
|
12915
|
-
/* @__PURE__ */
|
|
12916
|
-
/* @__PURE__ */
|
|
12917
|
-
/* @__PURE__ */
|
|
12918
|
-
/* @__PURE__ */
|
|
12919
|
-
/* @__PURE__ */
|
|
12920
|
-
/* @__PURE__ */
|
|
12921
|
-
/* @__PURE__ */
|
|
13248
|
+
return /* @__PURE__ */ jsxs22(Fragment13, { children: [
|
|
13249
|
+
hasHref && /* @__PURE__ */ jsx37(FloatLinkPreview, { href }),
|
|
13250
|
+
/* @__PURE__ */ jsx37(HrefMenu, {}),
|
|
13251
|
+
/* @__PURE__ */ jsx37(DuplicateButton, {}),
|
|
13252
|
+
/* @__PURE__ */ jsx37(DeleteButton, {}),
|
|
13253
|
+
/* @__PURE__ */ jsxs22(DropdownMenu, { open: dropdownOpen, onOpenChange: handleDropdownOpenChange, children: [
|
|
13254
|
+
/* @__PURE__ */ jsxs22(Tooltip, { children: [
|
|
13255
|
+
/* @__PURE__ */ jsx37(TooltipTrigger, { asChild: true, children: /* @__PURE__ */ jsx37(DropdownMenuTrigger, { asChild: true, children: /* @__PURE__ */ jsx37(Button, { variant: "ghost", size: "icon", className: floatButtonVariants, children: /* @__PURE__ */ jsx37(MoreHorizontalIcon5, { className: "w-4 h-4" }) }) }) }),
|
|
13256
|
+
/* @__PURE__ */ jsx37(TooltipContent, { side: "bottom", children: "More" })
|
|
12922
13257
|
] }),
|
|
12923
|
-
/* @__PURE__ */
|
|
12924
|
-
/* @__PURE__ */
|
|
12925
|
-
/* @__PURE__ */
|
|
12926
|
-
/* @__PURE__ */
|
|
12927
|
-
/* @__PURE__ */
|
|
12928
|
-
isFluidOnMobile && /* @__PURE__ */
|
|
13258
|
+
/* @__PURE__ */ jsxs22(DropdownMenuContent, { side: "bottom", className: "w-[250px] z-50001", children: [
|
|
13259
|
+
/* @__PURE__ */ jsxs22(DropdownMenuItem, { onClick: toggleFluidOnMobile, children: [
|
|
13260
|
+
/* @__PURE__ */ jsx37(Proportions, { className: "w-4 h-4" }),
|
|
13261
|
+
/* @__PURE__ */ jsxs22("div", { className: "flex flex-row items-center justify-between gap-2 w-full", children: [
|
|
13262
|
+
/* @__PURE__ */ jsx37("p", { children: "Full width on mobile" }),
|
|
13263
|
+
isFluidOnMobile && /* @__PURE__ */ jsx37(CheckIcon6, { className: "w-4 h-4" })
|
|
12929
13264
|
] })
|
|
12930
13265
|
] }),
|
|
12931
|
-
/* @__PURE__ */
|
|
12932
|
-
/* @__PURE__ */
|
|
12933
|
-
/* @__PURE__ */
|
|
12934
|
-
/* @__PURE__ */
|
|
12935
|
-
/* @__PURE__ */
|
|
13266
|
+
/* @__PURE__ */ jsx37(DropdownMenuSeparator, {}),
|
|
13267
|
+
/* @__PURE__ */ jsxs22(DropdownMenuSub, { children: [
|
|
13268
|
+
/* @__PURE__ */ jsxs22(DropdownMenuSubTrigger, { children: [
|
|
13269
|
+
/* @__PURE__ */ jsx37(Accessibility2, { className: "w-4 h-4" }),
|
|
13270
|
+
/* @__PURE__ */ jsx37("p", { children: "Alternative Text" })
|
|
12936
13271
|
] }),
|
|
12937
|
-
/* @__PURE__ */
|
|
12938
|
-
/* @__PURE__ */
|
|
12939
|
-
/* @__PURE__ */
|
|
12940
|
-
/* @__PURE__ */
|
|
12941
|
-
/* @__PURE__ */
|
|
13272
|
+
/* @__PURE__ */ jsx37(DropdownMenuPortal, { children: /* @__PURE__ */ jsxs22(DropdownMenuSubContent, { className: "p-3 w-[250px] z-50001", children: [
|
|
13273
|
+
/* @__PURE__ */ jsxs22("div", { className: "flex flex-col gap-2 mb-2", children: [
|
|
13274
|
+
/* @__PURE__ */ jsx37(Label, { children: "Alternative Text" }),
|
|
13275
|
+
/* @__PURE__ */ jsxs22("div", { className: "relative", children: [
|
|
13276
|
+
/* @__PURE__ */ jsx37(
|
|
12942
13277
|
Textarea,
|
|
12943
13278
|
{
|
|
12944
13279
|
placeholder: "Spacious living room with hardwood floors, large windows, and a cozy fireplace",
|
|
@@ -12948,14 +13283,14 @@ var ImageFloat = () => {
|
|
|
12948
13283
|
onChange: (e) => setAltInputValue(e.target.value)
|
|
12949
13284
|
}
|
|
12950
13285
|
),
|
|
12951
|
-
/* @__PURE__ */
|
|
13286
|
+
/* @__PURE__ */ jsxs22("span", { className: "bg-white rounded-[12px] p-1 shadow-sm absolute bottom-2 right-2 text-xs text-muted-foreground", children: [
|
|
12952
13287
|
altInputValue.length,
|
|
12953
13288
|
"/250"
|
|
12954
13289
|
] })
|
|
12955
13290
|
] }),
|
|
12956
|
-
/* @__PURE__ */
|
|
13291
|
+
/* @__PURE__ */ jsx37("p", { className: "text-xs text-muted-foreground mb-4", children: "Be descriptive and add context to keep your alt text clear for clients who use screen readers." })
|
|
12957
13292
|
] }),
|
|
12958
|
-
/* @__PURE__ */
|
|
13293
|
+
/* @__PURE__ */ jsx37(
|
|
12959
13294
|
Button,
|
|
12960
13295
|
{
|
|
12961
13296
|
variant: "default",
|
|
@@ -12972,7 +13307,7 @@ var ImageFloat = () => {
|
|
|
12972
13307
|
};
|
|
12973
13308
|
|
|
12974
13309
|
// src/core/editor/components/mlsNumber-menu.tsx
|
|
12975
|
-
import { useState as
|
|
13310
|
+
import { useState as useState9, useEffect as useEffect7 } from "react";
|
|
12976
13311
|
import { HousePlusIcon, TrashIcon as TrashIcon5, XIcon as XIcon2, Loader2Icon } from "lucide-react";
|
|
12977
13312
|
|
|
12978
13313
|
// src/services/repliers/commands.ts
|
|
@@ -12988,16 +13323,16 @@ async function getListingByMlsNumber(mlsNumber) {
|
|
|
12988
13323
|
}
|
|
12989
13324
|
|
|
12990
13325
|
// src/core/editor/components/mlsNumber-menu.tsx
|
|
12991
|
-
import { Fragment as Fragment14, jsx as
|
|
13326
|
+
import { Fragment as Fragment14, jsx as jsx38, jsxs as jsxs23 } from "react/jsx-runtime";
|
|
12992
13327
|
var MlsNumberMenu = () => {
|
|
12993
13328
|
const { focusIdx, template, updateElement, onToast } = useEditorStore();
|
|
12994
|
-
const [isOpen, setIsOpen] =
|
|
12995
|
-
const [inputValue, setInputValue] =
|
|
12996
|
-
const [propertyData, setPropertyData] =
|
|
12997
|
-
const [isLoading, setIsLoading] =
|
|
13329
|
+
const [isOpen, setIsOpen] = useState9(false);
|
|
13330
|
+
const [inputValue, setInputValue] = useState9("");
|
|
13331
|
+
const [propertyData, setPropertyData] = useState9(null);
|
|
13332
|
+
const [isLoading, setIsLoading] = useState9(false);
|
|
12998
13333
|
const propertyElement = focusIdx && template ? getValueByIdx(template, focusIdx) : null;
|
|
12999
13334
|
const currentMlsNumber = propertyElement?.data?.value?.mlsNumber || "";
|
|
13000
|
-
|
|
13335
|
+
useEffect7(() => {
|
|
13001
13336
|
setInputValue(currentMlsNumber);
|
|
13002
13337
|
setPropertyData(null);
|
|
13003
13338
|
}, [focusIdx, currentMlsNumber]);
|
|
@@ -13065,25 +13400,25 @@ var MlsNumberMenu = () => {
|
|
|
13065
13400
|
}
|
|
13066
13401
|
}
|
|
13067
13402
|
};
|
|
13068
|
-
return /* @__PURE__ */
|
|
13069
|
-
/* @__PURE__ */
|
|
13070
|
-
/* @__PURE__ */
|
|
13403
|
+
return /* @__PURE__ */ jsxs23(DropdownMenu, { open: isOpen, onOpenChange: setIsOpen, children: [
|
|
13404
|
+
/* @__PURE__ */ jsxs23(Tooltip, { children: [
|
|
13405
|
+
/* @__PURE__ */ jsx38(TooltipTrigger, { asChild: true, children: /* @__PURE__ */ jsx38(DropdownMenuTrigger, { asChild: true, children: /* @__PURE__ */ jsxs23(
|
|
13071
13406
|
Button,
|
|
13072
13407
|
{
|
|
13073
13408
|
variant: "ghost",
|
|
13074
13409
|
className: "shadow-none transition-none cursor-pointer rounded-full outline-none h-[34px]",
|
|
13075
13410
|
children: [
|
|
13076
|
-
/* @__PURE__ */
|
|
13077
|
-
/* @__PURE__ */
|
|
13411
|
+
/* @__PURE__ */ jsx38(HousePlusIcon, { className: "size-4" }),
|
|
13412
|
+
/* @__PURE__ */ jsx38("p", { children: "MLS" })
|
|
13078
13413
|
]
|
|
13079
13414
|
}
|
|
13080
13415
|
) }) }),
|
|
13081
|
-
/* @__PURE__ */
|
|
13416
|
+
/* @__PURE__ */ jsx38(TooltipContent, { side: "bottom", children: "Enter MLS Number" })
|
|
13082
13417
|
] }),
|
|
13083
|
-
/* @__PURE__ */
|
|
13084
|
-
/* @__PURE__ */
|
|
13085
|
-
/* @__PURE__ */
|
|
13086
|
-
/* @__PURE__ */
|
|
13418
|
+
/* @__PURE__ */ jsxs23(DropdownMenuContent, { side: "bottom", className: "w-[250px] p-3 shadow-lg z-50001", children: [
|
|
13419
|
+
/* @__PURE__ */ jsxs23("div", { className: "flex flex-col gap-2", children: [
|
|
13420
|
+
/* @__PURE__ */ jsx38(Label, { children: "Enter MLS Number" }),
|
|
13421
|
+
/* @__PURE__ */ jsx38(
|
|
13087
13422
|
Input,
|
|
13088
13423
|
{
|
|
13089
13424
|
type: "text",
|
|
@@ -13096,10 +13431,10 @@ var MlsNumberMenu = () => {
|
|
|
13096
13431
|
}
|
|
13097
13432
|
)
|
|
13098
13433
|
] }),
|
|
13099
|
-
/* @__PURE__ */
|
|
13100
|
-
/* @__PURE__ */
|
|
13101
|
-
/* @__PURE__ */
|
|
13102
|
-
/* @__PURE__ */
|
|
13434
|
+
/* @__PURE__ */ jsx38(Separator, { className: "my-2" }),
|
|
13435
|
+
/* @__PURE__ */ jsxs23("div", { className: "flex flex-row justify-between items-center", children: [
|
|
13436
|
+
/* @__PURE__ */ jsx38("div", { className: "flex flex-row", children: /* @__PURE__ */ jsxs23(Tooltip, { children: [
|
|
13437
|
+
/* @__PURE__ */ jsx38(TooltipTrigger, { asChild: true, children: /* @__PURE__ */ jsx38(
|
|
13103
13438
|
Button,
|
|
13104
13439
|
{
|
|
13105
13440
|
variant: "ghost",
|
|
@@ -13107,27 +13442,27 @@ var MlsNumberMenu = () => {
|
|
|
13107
13442
|
className: "shadow-none transition-none cursor-pointer rounded-full outline-none",
|
|
13108
13443
|
onClick: handleClear,
|
|
13109
13444
|
disabled: !inputValue,
|
|
13110
|
-
children: /* @__PURE__ */
|
|
13445
|
+
children: /* @__PURE__ */ jsx38(TrashIcon5, {})
|
|
13111
13446
|
}
|
|
13112
13447
|
) }),
|
|
13113
|
-
/* @__PURE__ */
|
|
13448
|
+
/* @__PURE__ */ jsx38(TooltipContent, { side: "bottom", className: "z-50001", children: "Clear" })
|
|
13114
13449
|
] }) }),
|
|
13115
|
-
/* @__PURE__ */
|
|
13450
|
+
/* @__PURE__ */ jsx38("div", { children: /* @__PURE__ */ jsx38(
|
|
13116
13451
|
Button,
|
|
13117
13452
|
{
|
|
13118
13453
|
variant: "default",
|
|
13119
13454
|
className: "shadow-none transition-none cursor-pointer rounded-[12px] outline-none",
|
|
13120
13455
|
onClick: handleDone,
|
|
13121
13456
|
disabled: isLoading || !inputValue.trim(),
|
|
13122
|
-
children: isLoading ? /* @__PURE__ */
|
|
13457
|
+
children: isLoading ? /* @__PURE__ */ jsx38(Loader2Icon, { className: "size-4 animate-spin" }) : "Done"
|
|
13123
13458
|
}
|
|
13124
13459
|
) })
|
|
13125
13460
|
] }),
|
|
13126
|
-
propertyData && /* @__PURE__ */
|
|
13127
|
-
/* @__PURE__ */
|
|
13128
|
-
/* @__PURE__ */
|
|
13129
|
-
/* @__PURE__ */
|
|
13130
|
-
/* @__PURE__ */
|
|
13461
|
+
propertyData && /* @__PURE__ */ jsxs23(Fragment14, { children: [
|
|
13462
|
+
/* @__PURE__ */ jsx38(Separator, { className: "my-2" }),
|
|
13463
|
+
/* @__PURE__ */ jsxs23("div", { className: "rounded-[12px] border overflow-hidden bg-card", children: [
|
|
13464
|
+
/* @__PURE__ */ jsxs23("div", { className: "relative", children: [
|
|
13465
|
+
/* @__PURE__ */ jsx38(
|
|
13131
13466
|
"img",
|
|
13132
13467
|
{
|
|
13133
13468
|
src: `https://cdn.repliers.io/${propertyData.images?.[0]}`,
|
|
@@ -13135,35 +13470,35 @@ var MlsNumberMenu = () => {
|
|
|
13135
13470
|
className: "w-full h-[120px] object-cover"
|
|
13136
13471
|
}
|
|
13137
13472
|
),
|
|
13138
|
-
/* @__PURE__ */
|
|
13473
|
+
/* @__PURE__ */ jsx38(
|
|
13139
13474
|
Button,
|
|
13140
13475
|
{
|
|
13141
13476
|
variant: "ghost",
|
|
13142
13477
|
size: "icon",
|
|
13143
13478
|
className: "absolute top-1 right-1 h-6 w-6 bg-black/50 hover:bg-black/70 rounded-full",
|
|
13144
13479
|
onClick: handleClearPreview,
|
|
13145
|
-
children: /* @__PURE__ */
|
|
13480
|
+
children: /* @__PURE__ */ jsx38(XIcon2, { className: "size-3 text-white" })
|
|
13146
13481
|
}
|
|
13147
13482
|
)
|
|
13148
13483
|
] }),
|
|
13149
|
-
/* @__PURE__ */
|
|
13150
|
-
/* @__PURE__ */
|
|
13151
|
-
/* @__PURE__ */
|
|
13152
|
-
/* @__PURE__ */
|
|
13484
|
+
/* @__PURE__ */ jsxs23("div", { className: "p-2 flex flex-col gap-1", children: [
|
|
13485
|
+
/* @__PURE__ */ jsxs23("div", { className: "flex items-center justify-between", children: [
|
|
13486
|
+
/* @__PURE__ */ jsx38("span", { className: "font-semibold text-sm", children: formatPrice(String(propertyData.listPrice || 0)) }),
|
|
13487
|
+
/* @__PURE__ */ jsx38("span", { className: "text-xs px-2 py-0.5 rounded-full bg-green-100 text-green-700", children: propertyData.standardStatus || propertyData.status })
|
|
13153
13488
|
] }),
|
|
13154
|
-
/* @__PURE__ */
|
|
13489
|
+
/* @__PURE__ */ jsxs23("div", { className: "text-sm", children: [
|
|
13155
13490
|
propertyData.address?.streetNumber,
|
|
13156
13491
|
" ",
|
|
13157
13492
|
propertyData.address?.streetName
|
|
13158
13493
|
] }),
|
|
13159
|
-
/* @__PURE__ */
|
|
13494
|
+
/* @__PURE__ */ jsxs23("div", { className: "text-xs text-muted-foreground", children: [
|
|
13160
13495
|
propertyData.address?.city,
|
|
13161
13496
|
", ",
|
|
13162
13497
|
propertyData.address?.state,
|
|
13163
13498
|
" ",
|
|
13164
13499
|
propertyData.address?.zip
|
|
13165
13500
|
] }),
|
|
13166
|
-
/* @__PURE__ */
|
|
13501
|
+
/* @__PURE__ */ jsxs23("div", { className: "text-xs text-muted-foreground", children: [
|
|
13167
13502
|
propertyData.details?.numBedrooms,
|
|
13168
13503
|
" bd | ",
|
|
13169
13504
|
propertyData.details?.numBathrooms,
|
|
@@ -13171,8 +13506,8 @@ var MlsNumberMenu = () => {
|
|
|
13171
13506
|
formatNumber(String(propertyData.details?.sqft || "--")),
|
|
13172
13507
|
" sf"
|
|
13173
13508
|
] }),
|
|
13174
|
-
propertyData.office?.brokerageName && /* @__PURE__ */
|
|
13175
|
-
/* @__PURE__ */
|
|
13509
|
+
propertyData.office?.brokerageName && /* @__PURE__ */ jsx38("div", { className: "text-xs text-muted-foreground truncate", children: propertyData.office.brokerageName }),
|
|
13510
|
+
/* @__PURE__ */ jsx38(
|
|
13176
13511
|
Button,
|
|
13177
13512
|
{
|
|
13178
13513
|
variant: "default",
|
|
@@ -13190,34 +13525,34 @@ var MlsNumberMenu = () => {
|
|
|
13190
13525
|
};
|
|
13191
13526
|
|
|
13192
13527
|
// src/core/editor/components/element-gear/property/float.tsx
|
|
13193
|
-
import { Fragment as Fragment15, jsx as
|
|
13528
|
+
import { Fragment as Fragment15, jsx as jsx39, jsxs as jsxs24 } from "react/jsx-runtime";
|
|
13194
13529
|
function PropertyFloat() {
|
|
13195
13530
|
const { href, hasHref } = useHref();
|
|
13196
|
-
return /* @__PURE__ */
|
|
13197
|
-
hasHref && /* @__PURE__ */
|
|
13198
|
-
/* @__PURE__ */
|
|
13199
|
-
/* @__PURE__ */
|
|
13531
|
+
return /* @__PURE__ */ jsxs24(Fragment15, { children: [
|
|
13532
|
+
hasHref && /* @__PURE__ */ jsx39(FloatLinkPreview, { href }),
|
|
13533
|
+
/* @__PURE__ */ jsx39(HrefMenu, {}),
|
|
13534
|
+
/* @__PURE__ */ jsx39(MlsNumberMenu, {})
|
|
13200
13535
|
] });
|
|
13201
13536
|
}
|
|
13202
13537
|
|
|
13203
13538
|
// src/core/editor/components/element-gear/property/triple/float.tsx
|
|
13204
|
-
import { Fragment as Fragment16, jsx as
|
|
13539
|
+
import { Fragment as Fragment16, jsx as jsx40, jsxs as jsxs25 } from "react/jsx-runtime";
|
|
13205
13540
|
var PropertyTripleItemFloat = () => {
|
|
13206
13541
|
const { href, hasHref } = useHref();
|
|
13207
|
-
return /* @__PURE__ */
|
|
13208
|
-
hasHref && /* @__PURE__ */
|
|
13209
|
-
/* @__PURE__ */
|
|
13542
|
+
return /* @__PURE__ */ jsxs25(Fragment16, { children: [
|
|
13543
|
+
hasHref && /* @__PURE__ */ jsx40(FloatLinkPreview, { href }),
|
|
13544
|
+
/* @__PURE__ */ jsx40(HrefMenu, {})
|
|
13210
13545
|
] });
|
|
13211
13546
|
};
|
|
13212
13547
|
|
|
13213
13548
|
// src/core/editor/components/float-ui/container.tsx
|
|
13214
|
-
import { jsx as
|
|
13549
|
+
import { jsx as jsx41 } from "react/jsx-runtime";
|
|
13215
13550
|
var FloatUIContainer = ({ ref, style, className, children }) => {
|
|
13216
|
-
return /* @__PURE__ */
|
|
13551
|
+
return /* @__PURE__ */ jsx41("div", { ref, style, className, children });
|
|
13217
13552
|
};
|
|
13218
13553
|
|
|
13219
13554
|
// src/core/editor/components/element-float.tsx
|
|
13220
|
-
import { jsx as
|
|
13555
|
+
import { jsx as jsx42 } from "react/jsx-runtime";
|
|
13221
13556
|
var FLOAT_COMPONENTS = {
|
|
13222
13557
|
"button": ButtonFloat,
|
|
13223
13558
|
"section": SectionFloat,
|
|
@@ -13241,7 +13576,7 @@ var ElementFloat = ({ getReferenceRect, focusIdx, elementType }) => {
|
|
|
13241
13576
|
if (!focusIdx || isDragging || textEditing) return null;
|
|
13242
13577
|
const FloatComponent = FLOAT_COMPONENTS[elementType];
|
|
13243
13578
|
if (!FloatComponent) return null;
|
|
13244
|
-
return /* @__PURE__ */
|
|
13579
|
+
return /* @__PURE__ */ jsx42(
|
|
13245
13580
|
ElementFloatContent,
|
|
13246
13581
|
{
|
|
13247
13582
|
getReferenceRect,
|
|
@@ -13250,7 +13585,7 @@ var ElementFloat = ({ getReferenceRect, focusIdx, elementType }) => {
|
|
|
13250
13585
|
);
|
|
13251
13586
|
};
|
|
13252
13587
|
var ElementFloatContent = ({ getReferenceRect, FloatComponent }) => {
|
|
13253
|
-
const virtualReference =
|
|
13588
|
+
const virtualReference = useMemo12(() => ({
|
|
13254
13589
|
getBoundingClientRect: () => {
|
|
13255
13590
|
const rect = getReferenceRect();
|
|
13256
13591
|
if (!rect) {
|
|
@@ -13259,18 +13594,18 @@ var ElementFloatContent = ({ getReferenceRect, FloatComponent }) => {
|
|
|
13259
13594
|
return rect;
|
|
13260
13595
|
}
|
|
13261
13596
|
}), [getReferenceRect]);
|
|
13262
|
-
const { floatingStyles, refs, update } =
|
|
13597
|
+
const { floatingStyles, refs, update } = useFloating5({
|
|
13263
13598
|
placement: "top",
|
|
13264
13599
|
middleware: [
|
|
13265
|
-
|
|
13600
|
+
offset5(16),
|
|
13266
13601
|
// 8px above the element
|
|
13267
|
-
|
|
13602
|
+
flip3({ padding: 8 }),
|
|
13268
13603
|
// Flip to bottom if not enough space above
|
|
13269
|
-
|
|
13604
|
+
shift4({ padding: 8 })
|
|
13270
13605
|
// Keep within viewport
|
|
13271
13606
|
]
|
|
13272
13607
|
});
|
|
13273
|
-
|
|
13608
|
+
useEffect8(() => {
|
|
13274
13609
|
const rect = getReferenceRect();
|
|
13275
13610
|
if (!rect || !refs.floating.current) return;
|
|
13276
13611
|
refs.setPositionReference(virtualReference);
|
|
@@ -13285,18 +13620,18 @@ var ElementFloatContent = ({ getReferenceRect, FloatComponent }) => {
|
|
|
13285
13620
|
);
|
|
13286
13621
|
return cleanup;
|
|
13287
13622
|
}, [getReferenceRect, refs, update, virtualReference]);
|
|
13288
|
-
return /* @__PURE__ */
|
|
13623
|
+
return /* @__PURE__ */ jsx42(FloatUIContainer, { ref: refs.setFloating, style: floatingStyles, className: "bg-white flex items-center justify-center border border-1 h-[36px] w-fit shadow-md rounded-full z-50", children: /* @__PURE__ */ jsx42(FloatComponent, {}) });
|
|
13289
13624
|
};
|
|
13290
13625
|
|
|
13291
13626
|
// src/core/editor/components/scaling/divider-scale.tsx
|
|
13292
|
-
import { useMemo as
|
|
13293
|
-
import { useFloating as
|
|
13294
|
-
import { jsx as
|
|
13627
|
+
import { useMemo as useMemo13, useEffect as useEffect9, useState as useState10, useRef as useRef6, useCallback as useCallback14 } from "react";
|
|
13628
|
+
import { useFloating as useFloating6, offset as offset6, autoUpdate as autoUpdate4 } from "@floating-ui/react";
|
|
13629
|
+
import { jsx as jsx43, jsxs as jsxs26 } from "react/jsx-runtime";
|
|
13295
13630
|
var DividerScale = ({ getReferenceRect }) => {
|
|
13296
|
-
const [dimensions, setDimensions] =
|
|
13297
|
-
const [activeSide, setActiveSide] =
|
|
13631
|
+
const [dimensions, setDimensions] = useState10({ width: 0, height: 0 });
|
|
13632
|
+
const [activeSide, setActiveSide] = useState10(null);
|
|
13298
13633
|
const { focusIdx, template, setIsScaling } = useEditorStore();
|
|
13299
|
-
const { currentWidth, currentAlign } =
|
|
13634
|
+
const { currentWidth, currentAlign } = useMemo13(() => {
|
|
13300
13635
|
if (!focusIdx || !template) return { currentWidth: 100, currentAlign: "center" };
|
|
13301
13636
|
const element = getValueByIdx(template, focusIdx);
|
|
13302
13637
|
const rawWidth = element?.attributes?.width;
|
|
@@ -13305,13 +13640,13 @@ var DividerScale = ({ getReferenceRect }) => {
|
|
|
13305
13640
|
const align = element?.attributes?.align || "center";
|
|
13306
13641
|
return { currentWidth: width, currentAlign: align };
|
|
13307
13642
|
}, [focusIdx, template]);
|
|
13308
|
-
const dragRef =
|
|
13309
|
-
const getContainerWidth =
|
|
13643
|
+
const dragRef = useRef6(null);
|
|
13644
|
+
const getContainerWidth = useCallback14(() => {
|
|
13310
13645
|
const rect = getReferenceRect();
|
|
13311
13646
|
if (!rect || currentWidth <= 0) return null;
|
|
13312
13647
|
return rect.width / (currentWidth / 100);
|
|
13313
13648
|
}, [getReferenceRect, currentWidth]);
|
|
13314
|
-
const handlePointerDown =
|
|
13649
|
+
const handlePointerDown = useCallback14((e, side) => {
|
|
13315
13650
|
e.preventDefault();
|
|
13316
13651
|
e.stopPropagation();
|
|
13317
13652
|
const containerWidth = getContainerWidth();
|
|
@@ -13329,7 +13664,7 @@ var DividerScale = ({ getReferenceRect }) => {
|
|
|
13329
13664
|
document.addEventListener("pointermove", handlePointerMove);
|
|
13330
13665
|
document.addEventListener("pointerup", handlePointerUp);
|
|
13331
13666
|
}, [getContainerWidth, currentWidth, currentAlign, setIsScaling]);
|
|
13332
|
-
const handlePointerMove =
|
|
13667
|
+
const handlePointerMove = useCallback14((e) => {
|
|
13333
13668
|
if (!dragRef.current) return;
|
|
13334
13669
|
const { startX, startWidth, containerWidth, side, align } = dragRef.current;
|
|
13335
13670
|
const deltaX = e.clientX - startX;
|
|
@@ -13349,20 +13684,20 @@ var DividerScale = ({ getReferenceRect }) => {
|
|
|
13349
13684
|
}
|
|
13350
13685
|
});
|
|
13351
13686
|
}, []);
|
|
13352
|
-
const handlePointerUp =
|
|
13687
|
+
const handlePointerUp = useCallback14(() => {
|
|
13353
13688
|
setActiveSide(null);
|
|
13354
13689
|
setIsScaling(false);
|
|
13355
13690
|
dragRef.current = null;
|
|
13356
13691
|
document.removeEventListener("pointermove", handlePointerMove);
|
|
13357
13692
|
document.removeEventListener("pointerup", handlePointerUp);
|
|
13358
13693
|
}, [handlePointerMove, setIsScaling]);
|
|
13359
|
-
|
|
13694
|
+
useEffect9(() => {
|
|
13360
13695
|
return () => {
|
|
13361
13696
|
document.removeEventListener("pointermove", handlePointerMove);
|
|
13362
13697
|
document.removeEventListener("pointerup", handlePointerUp);
|
|
13363
13698
|
};
|
|
13364
13699
|
}, [handlePointerMove, handlePointerUp]);
|
|
13365
|
-
const virtualReference =
|
|
13700
|
+
const virtualReference = useMemo13(() => ({
|
|
13366
13701
|
getBoundingClientRect: () => {
|
|
13367
13702
|
const rect = getReferenceRect();
|
|
13368
13703
|
if (!rect) {
|
|
@@ -13371,13 +13706,13 @@ var DividerScale = ({ getReferenceRect }) => {
|
|
|
13371
13706
|
return rect;
|
|
13372
13707
|
}
|
|
13373
13708
|
}), [getReferenceRect]);
|
|
13374
|
-
const { floatingStyles, refs, update } =
|
|
13709
|
+
const { floatingStyles, refs, update } = useFloating6({
|
|
13375
13710
|
placement: "bottom-start",
|
|
13376
13711
|
middleware: [
|
|
13377
|
-
|
|
13712
|
+
offset6(({ rects }) => -rects.reference.height)
|
|
13378
13713
|
]
|
|
13379
13714
|
});
|
|
13380
|
-
|
|
13715
|
+
useEffect9(() => {
|
|
13381
13716
|
const rect = getReferenceRect();
|
|
13382
13717
|
if (!rect || !refs.floating.current) return;
|
|
13383
13718
|
refs.setPositionReference(virtualReference);
|
|
@@ -13404,7 +13739,7 @@ var DividerScale = ({ getReferenceRect }) => {
|
|
|
13404
13739
|
}, [getReferenceRect, refs, update, virtualReference]);
|
|
13405
13740
|
const showLeftHandle = currentAlign !== "left";
|
|
13406
13741
|
const showRightHandle = currentAlign !== "right";
|
|
13407
|
-
return /* @__PURE__ */
|
|
13742
|
+
return /* @__PURE__ */ jsxs26(
|
|
13408
13743
|
"div",
|
|
13409
13744
|
{
|
|
13410
13745
|
ref: refs.setFloating,
|
|
@@ -13416,14 +13751,14 @@ var DividerScale = ({ getReferenceRect }) => {
|
|
|
13416
13751
|
},
|
|
13417
13752
|
className: "relative flex flex-row items-center justify-between",
|
|
13418
13753
|
children: [
|
|
13419
|
-
showLeftHandle && (activeSide === null || activeSide === "left") && /* @__PURE__ */
|
|
13754
|
+
showLeftHandle && (activeSide === null || activeSide === "left") && /* @__PURE__ */ jsx43(
|
|
13420
13755
|
"div",
|
|
13421
13756
|
{
|
|
13422
13757
|
onPointerDown: (e) => handlePointerDown(e, "left"),
|
|
13423
13758
|
className: `w-[18px] h-[18px] cursor-ew-resize bg-background shadow-md border rounded-full absolute -left-[9px] top-1/2 -translate-y-1/2 touch-none select-none ${activeSide === "left" ? "bg-blue-400 border-blue-300" : "hover:bg-blue-400 hover:border-blue-300"}`
|
|
13424
13759
|
}
|
|
13425
13760
|
),
|
|
13426
|
-
showRightHandle && (activeSide === null || activeSide === "right") && /* @__PURE__ */
|
|
13761
|
+
showRightHandle && (activeSide === null || activeSide === "right") && /* @__PURE__ */ jsx43(
|
|
13427
13762
|
"div",
|
|
13428
13763
|
{
|
|
13429
13764
|
onPointerDown: (e) => handlePointerDown(e, "right"),
|
|
@@ -13436,14 +13771,14 @@ var DividerScale = ({ getReferenceRect }) => {
|
|
|
13436
13771
|
};
|
|
13437
13772
|
|
|
13438
13773
|
// src/core/editor/components/scaling/button-scale.tsx
|
|
13439
|
-
import { useMemo as
|
|
13440
|
-
import { useFloating as
|
|
13441
|
-
import { jsx as
|
|
13774
|
+
import { useMemo as useMemo14, useEffect as useEffect10, useState as useState11, useRef as useRef7, useCallback as useCallback15 } from "react";
|
|
13775
|
+
import { useFloating as useFloating7, offset as offset7, autoUpdate as autoUpdate5 } from "@floating-ui/react";
|
|
13776
|
+
import { jsx as jsx44, jsxs as jsxs27 } from "react/jsx-runtime";
|
|
13442
13777
|
var ButtonScale = ({ getReferenceRect }) => {
|
|
13443
|
-
const [dimensions, setDimensions] =
|
|
13444
|
-
const [activeSide, setActiveSide] =
|
|
13778
|
+
const [dimensions, setDimensions] = useState11({ width: 0, height: 0 });
|
|
13779
|
+
const [activeSide, setActiveSide] = useState11(null);
|
|
13445
13780
|
const { focusIdx, template, setIsScaling } = useEditorStore();
|
|
13446
|
-
const { currentWidth, currentHeight, currentAlign } =
|
|
13781
|
+
const { currentWidth, currentHeight, currentAlign } = useMemo14(() => {
|
|
13447
13782
|
if (!focusIdx || !template) {
|
|
13448
13783
|
return { currentWidth: 24, currentHeight: 44, currentAlign: "center" };
|
|
13449
13784
|
}
|
|
@@ -13457,13 +13792,13 @@ var ButtonScale = ({ getReferenceRect }) => {
|
|
|
13457
13792
|
const align = element?.attributes?.align || "center";
|
|
13458
13793
|
return { currentWidth: width, currentHeight: height, currentAlign: align };
|
|
13459
13794
|
}, [focusIdx, template]);
|
|
13460
|
-
const dragRef =
|
|
13461
|
-
const getContainerWidth =
|
|
13795
|
+
const dragRef = useRef7(null);
|
|
13796
|
+
const getContainerWidth = useCallback15(() => {
|
|
13462
13797
|
const rect = getReferenceRect();
|
|
13463
13798
|
if (!rect || currentWidth <= 0) return null;
|
|
13464
13799
|
return rect.width / (currentWidth / 100);
|
|
13465
13800
|
}, [getReferenceRect, currentWidth]);
|
|
13466
|
-
const handlePointerDown =
|
|
13801
|
+
const handlePointerDown = useCallback15((e, side) => {
|
|
13467
13802
|
e.preventDefault();
|
|
13468
13803
|
e.stopPropagation();
|
|
13469
13804
|
if (document.activeElement instanceof HTMLElement) {
|
|
@@ -13485,7 +13820,7 @@ var ButtonScale = ({ getReferenceRect }) => {
|
|
|
13485
13820
|
document.addEventListener("pointermove", handlePointerMove);
|
|
13486
13821
|
document.addEventListener("pointerup", handlePointerUp);
|
|
13487
13822
|
}, [getContainerWidth, currentWidth, currentHeight, currentAlign, setIsScaling]);
|
|
13488
|
-
const handlePointerMove =
|
|
13823
|
+
const handlePointerMove = useCallback15((e) => {
|
|
13489
13824
|
if (!dragRef.current) return;
|
|
13490
13825
|
const { startX, startY, startWidth, startHeight, containerWidth, side, align } = dragRef.current;
|
|
13491
13826
|
const state = useEditorStore.getState();
|
|
@@ -13517,20 +13852,20 @@ var ButtonScale = ({ getReferenceRect }) => {
|
|
|
13517
13852
|
});
|
|
13518
13853
|
}
|
|
13519
13854
|
}, []);
|
|
13520
|
-
const handlePointerUp =
|
|
13855
|
+
const handlePointerUp = useCallback15(() => {
|
|
13521
13856
|
setActiveSide(null);
|
|
13522
13857
|
setIsScaling(false);
|
|
13523
13858
|
dragRef.current = null;
|
|
13524
13859
|
document.removeEventListener("pointermove", handlePointerMove);
|
|
13525
13860
|
document.removeEventListener("pointerup", handlePointerUp);
|
|
13526
13861
|
}, [handlePointerMove, setIsScaling]);
|
|
13527
|
-
|
|
13862
|
+
useEffect10(() => {
|
|
13528
13863
|
return () => {
|
|
13529
13864
|
document.removeEventListener("pointermove", handlePointerMove);
|
|
13530
13865
|
document.removeEventListener("pointerup", handlePointerUp);
|
|
13531
13866
|
};
|
|
13532
13867
|
}, [handlePointerMove, handlePointerUp]);
|
|
13533
|
-
const virtualReference =
|
|
13868
|
+
const virtualReference = useMemo14(() => ({
|
|
13534
13869
|
getBoundingClientRect: () => {
|
|
13535
13870
|
const rect = getReferenceRect();
|
|
13536
13871
|
if (!rect) {
|
|
@@ -13539,13 +13874,13 @@ var ButtonScale = ({ getReferenceRect }) => {
|
|
|
13539
13874
|
return rect;
|
|
13540
13875
|
}
|
|
13541
13876
|
}), [getReferenceRect]);
|
|
13542
|
-
const { floatingStyles, refs, update } =
|
|
13877
|
+
const { floatingStyles, refs, update } = useFloating7({
|
|
13543
13878
|
placement: "bottom-start",
|
|
13544
13879
|
middleware: [
|
|
13545
|
-
|
|
13880
|
+
offset7(({ rects }) => -rects.reference.height)
|
|
13546
13881
|
]
|
|
13547
13882
|
});
|
|
13548
|
-
|
|
13883
|
+
useEffect10(() => {
|
|
13549
13884
|
const rect = getReferenceRect();
|
|
13550
13885
|
if (!rect || !refs.floating.current) return;
|
|
13551
13886
|
refs.setPositionReference(virtualReference);
|
|
@@ -13574,7 +13909,7 @@ var ButtonScale = ({ getReferenceRect }) => {
|
|
|
13574
13909
|
const showRightHandle = currentAlign !== "right";
|
|
13575
13910
|
const handleBaseClass = "bg-background shadow-md border rounded-full absolute touch-none select-none pointer-events-auto";
|
|
13576
13911
|
const getHandleActiveClass = (side) => activeSide === side ? "bg-blue-400 border-blue-300" : "hover:bg-blue-400 hover:border-blue-300";
|
|
13577
|
-
return /* @__PURE__ */
|
|
13912
|
+
return /* @__PURE__ */ jsxs27(
|
|
13578
13913
|
"div",
|
|
13579
13914
|
{
|
|
13580
13915
|
ref: refs.setFloating,
|
|
@@ -13586,28 +13921,28 @@ var ButtonScale = ({ getReferenceRect }) => {
|
|
|
13586
13921
|
},
|
|
13587
13922
|
className: "relative pointer-events-none",
|
|
13588
13923
|
children: [
|
|
13589
|
-
(activeSide === null || activeSide === "top") && /* @__PURE__ */
|
|
13924
|
+
(activeSide === null || activeSide === "top") && /* @__PURE__ */ jsx44(
|
|
13590
13925
|
"div",
|
|
13591
13926
|
{
|
|
13592
13927
|
onPointerDown: (e) => handlePointerDown(e, "top"),
|
|
13593
13928
|
className: `w-[18px] h-[8px] cursor-ns-resize ${handleBaseClass} left-1/2 -translate-x-1/2 -top-[4px] ${getHandleActiveClass("top")}`
|
|
13594
13929
|
}
|
|
13595
13930
|
),
|
|
13596
|
-
showRightHandle && (activeSide === null || activeSide === "right") && /* @__PURE__ */
|
|
13931
|
+
showRightHandle && (activeSide === null || activeSide === "right") && /* @__PURE__ */ jsx44(
|
|
13597
13932
|
"div",
|
|
13598
13933
|
{
|
|
13599
13934
|
onPointerDown: (e) => handlePointerDown(e, "right"),
|
|
13600
13935
|
className: `w-[8px] h-[18px] cursor-ew-resize ${handleBaseClass} top-1/2 -translate-y-1/2 -right-[4px] ${getHandleActiveClass("right")}`
|
|
13601
13936
|
}
|
|
13602
13937
|
),
|
|
13603
|
-
(activeSide === null || activeSide === "bottom") && /* @__PURE__ */
|
|
13938
|
+
(activeSide === null || activeSide === "bottom") && /* @__PURE__ */ jsx44(
|
|
13604
13939
|
"div",
|
|
13605
13940
|
{
|
|
13606
13941
|
onPointerDown: (e) => handlePointerDown(e, "bottom"),
|
|
13607
13942
|
className: `w-[18px] h-[8px] cursor-ns-resize ${handleBaseClass} left-1/2 -translate-x-1/2 -bottom-[4px] ${getHandleActiveClass("bottom")}`
|
|
13608
13943
|
}
|
|
13609
13944
|
),
|
|
13610
|
-
showLeftHandle && (activeSide === null || activeSide === "left") && /* @__PURE__ */
|
|
13945
|
+
showLeftHandle && (activeSide === null || activeSide === "left") && /* @__PURE__ */ jsx44(
|
|
13611
13946
|
"div",
|
|
13612
13947
|
{
|
|
13613
13948
|
onPointerDown: (e) => handlePointerDown(e, "left"),
|
|
@@ -13620,14 +13955,15 @@ var ButtonScale = ({ getReferenceRect }) => {
|
|
|
13620
13955
|
};
|
|
13621
13956
|
|
|
13622
13957
|
// src/core/editor/components/scaling/image-scale.tsx
|
|
13623
|
-
import { useMemo as
|
|
13624
|
-
import { useFloating as
|
|
13625
|
-
import { jsx as
|
|
13958
|
+
import { useMemo as useMemo15, useEffect as useEffect11, useState as useState12, useRef as useRef8, useCallback as useCallback16 } from "react";
|
|
13959
|
+
import { useFloating as useFloating8, offset as offset8, autoUpdate as autoUpdate6 } from "@floating-ui/react";
|
|
13960
|
+
import { jsx as jsx45, jsxs as jsxs28 } from "react/jsx-runtime";
|
|
13961
|
+
var isCorner = (side) => side === "top-left" || side === "top-right" || side === "bottom-left" || side === "bottom-right";
|
|
13626
13962
|
var ImageScale = ({ getReferenceRect }) => {
|
|
13627
|
-
const [dimensions, setDimensions] =
|
|
13628
|
-
const [activeSide, setActiveSide] =
|
|
13963
|
+
const [dimensions, setDimensions] = useState12({ width: 0, height: 0 });
|
|
13964
|
+
const [activeSide, setActiveSide] = useState12(null);
|
|
13629
13965
|
const { focusIdx, template, setIsScaling } = useEditorStore();
|
|
13630
|
-
const { currentWidth, currentHeight, currentAlign } =
|
|
13966
|
+
const { currentWidth, currentHeight, currentAlign } = useMemo15(() => {
|
|
13631
13967
|
if (!focusIdx || !template) {
|
|
13632
13968
|
return { currentWidth: 0, currentHeight: 0, currentAlign: "center" };
|
|
13633
13969
|
}
|
|
@@ -13641,8 +13977,8 @@ var ImageScale = ({ getReferenceRect }) => {
|
|
|
13641
13977
|
const align = element?.attributes?.align || "center";
|
|
13642
13978
|
return { currentWidth: width, currentHeight: height, currentAlign: align };
|
|
13643
13979
|
}, [focusIdx, template]);
|
|
13644
|
-
const dragRef =
|
|
13645
|
-
const handlePointerDown =
|
|
13980
|
+
const dragRef = useRef8(null);
|
|
13981
|
+
const handlePointerDown = useCallback16((e, side) => {
|
|
13646
13982
|
e.preventDefault();
|
|
13647
13983
|
e.stopPropagation();
|
|
13648
13984
|
if (document.activeElement instanceof HTMLElement) {
|
|
@@ -13660,12 +13996,13 @@ var ImageScale = ({ getReferenceRect }) => {
|
|
|
13660
13996
|
startWidth: effectiveWidth,
|
|
13661
13997
|
startHeight: effectiveHeight,
|
|
13662
13998
|
side,
|
|
13663
|
-
align: currentAlign
|
|
13999
|
+
align: currentAlign,
|
|
14000
|
+
aspectRatio: effectiveHeight > 0 ? effectiveWidth / effectiveHeight : 1
|
|
13664
14001
|
};
|
|
13665
14002
|
document.addEventListener("pointermove", handlePointerMove);
|
|
13666
14003
|
document.addEventListener("pointerup", handlePointerUp);
|
|
13667
14004
|
}, [getReferenceRect, currentWidth, currentHeight, currentAlign, setIsScaling]);
|
|
13668
|
-
const handlePointerMove =
|
|
14005
|
+
const handlePointerMove = useCallback16((e) => {
|
|
13669
14006
|
if (!dragRef.current) return;
|
|
13670
14007
|
const { startX, startY, startWidth, startHeight, side, align } = dragRef.current;
|
|
13671
14008
|
const state = useEditorStore.getState();
|
|
@@ -13673,7 +14010,35 @@ var ImageScale = ({ getReferenceRect }) => {
|
|
|
13673
14010
|
if (!currentFocusIdx || !currentTemplate) return;
|
|
13674
14011
|
const element = getValueByIdx(currentTemplate, currentFocusIdx);
|
|
13675
14012
|
if (!element) return;
|
|
13676
|
-
if (side
|
|
14013
|
+
if (isCorner(side)) {
|
|
14014
|
+
const { aspectRatio } = dragRef.current;
|
|
14015
|
+
const deltaX = e.clientX - startX;
|
|
14016
|
+
const deltaY = e.clientY - startY;
|
|
14017
|
+
const signX = side.includes("left") ? -1 : 1;
|
|
14018
|
+
const signY = side.includes("top") ? -1 : 1;
|
|
14019
|
+
const alignMultiplier = align === "center" ? 2 : 1;
|
|
14020
|
+
const absDX = Math.abs(deltaX);
|
|
14021
|
+
const absDY = Math.abs(deltaY);
|
|
14022
|
+
let newWidth;
|
|
14023
|
+
let newHeight;
|
|
14024
|
+
if (absDX >= absDY) {
|
|
14025
|
+
newWidth = startWidth + signX * deltaX * alignMultiplier;
|
|
14026
|
+
newHeight = newWidth / aspectRatio;
|
|
14027
|
+
} else {
|
|
14028
|
+
newHeight = startHeight + signY * deltaY;
|
|
14029
|
+
newWidth = newHeight * aspectRatio;
|
|
14030
|
+
}
|
|
14031
|
+
const clampedWidth = Math.max(20, Math.min(600, newWidth));
|
|
14032
|
+
const clampedHeight = Math.max(20, Math.min(600, clampedWidth / aspectRatio));
|
|
14033
|
+
const finalWidth = clampedHeight * aspectRatio;
|
|
14034
|
+
updateElement(currentFocusIdx, {
|
|
14035
|
+
attributes: {
|
|
14036
|
+
...element.attributes,
|
|
14037
|
+
width: `${Math.round(finalWidth)}px`,
|
|
14038
|
+
height: `${Math.round(clampedHeight)}px`
|
|
14039
|
+
}
|
|
14040
|
+
});
|
|
14041
|
+
} else if (side === "left" || side === "right") {
|
|
13677
14042
|
const deltaX = e.clientX - startX;
|
|
13678
14043
|
const alignMultiplier = align === "center" ? 2 : 1;
|
|
13679
14044
|
const newWidth = side === "left" ? startWidth - deltaX * alignMultiplier : startWidth + deltaX * alignMultiplier;
|
|
@@ -13696,20 +14061,20 @@ var ImageScale = ({ getReferenceRect }) => {
|
|
|
13696
14061
|
});
|
|
13697
14062
|
}
|
|
13698
14063
|
}, []);
|
|
13699
|
-
const handlePointerUp =
|
|
14064
|
+
const handlePointerUp = useCallback16(() => {
|
|
13700
14065
|
setActiveSide(null);
|
|
13701
14066
|
setIsScaling(false);
|
|
13702
14067
|
dragRef.current = null;
|
|
13703
14068
|
document.removeEventListener("pointermove", handlePointerMove);
|
|
13704
14069
|
document.removeEventListener("pointerup", handlePointerUp);
|
|
13705
14070
|
}, [handlePointerMove, setIsScaling]);
|
|
13706
|
-
|
|
14071
|
+
useEffect11(() => {
|
|
13707
14072
|
return () => {
|
|
13708
14073
|
document.removeEventListener("pointermove", handlePointerMove);
|
|
13709
14074
|
document.removeEventListener("pointerup", handlePointerUp);
|
|
13710
14075
|
};
|
|
13711
14076
|
}, [handlePointerMove, handlePointerUp]);
|
|
13712
|
-
const virtualReference =
|
|
14077
|
+
const virtualReference = useMemo15(() => ({
|
|
13713
14078
|
getBoundingClientRect: () => {
|
|
13714
14079
|
const rect = getReferenceRect();
|
|
13715
14080
|
if (!rect) {
|
|
@@ -13718,13 +14083,13 @@ var ImageScale = ({ getReferenceRect }) => {
|
|
|
13718
14083
|
return rect;
|
|
13719
14084
|
}
|
|
13720
14085
|
}), [getReferenceRect]);
|
|
13721
|
-
const { floatingStyles, refs, update } =
|
|
14086
|
+
const { floatingStyles, refs, update } = useFloating8({
|
|
13722
14087
|
placement: "bottom-start",
|
|
13723
14088
|
middleware: [
|
|
13724
|
-
|
|
14089
|
+
offset8(({ rects }) => -rects.reference.height)
|
|
13725
14090
|
]
|
|
13726
14091
|
});
|
|
13727
|
-
|
|
14092
|
+
useEffect11(() => {
|
|
13728
14093
|
const rect = getReferenceRect();
|
|
13729
14094
|
if (!rect || !refs.floating.current) return;
|
|
13730
14095
|
refs.setPositionReference(virtualReference);
|
|
@@ -13751,9 +14116,13 @@ var ImageScale = ({ getReferenceRect }) => {
|
|
|
13751
14116
|
}, [getReferenceRect, refs, update, virtualReference]);
|
|
13752
14117
|
const showLeftHandle = currentAlign !== "left";
|
|
13753
14118
|
const showRightHandle = currentAlign !== "right";
|
|
14119
|
+
const showTopLeft = currentAlign !== "left";
|
|
14120
|
+
const showTopRight = currentAlign !== "right";
|
|
14121
|
+
const showBottomLeft = currentAlign !== "left";
|
|
14122
|
+
const showBottomRight = currentAlign !== "right";
|
|
13754
14123
|
const handleBaseClass = "bg-background shadow-md border rounded-full absolute touch-none select-none pointer-events-auto";
|
|
13755
14124
|
const getHandleActiveClass = (side) => activeSide === side ? "bg-blue-400 border-blue-300" : "hover:bg-blue-400 hover:border-blue-300";
|
|
13756
|
-
return /* @__PURE__ */
|
|
14125
|
+
return /* @__PURE__ */ jsxs28(
|
|
13757
14126
|
"div",
|
|
13758
14127
|
{
|
|
13759
14128
|
ref: refs.setFloating,
|
|
@@ -13765,33 +14134,61 @@ var ImageScale = ({ getReferenceRect }) => {
|
|
|
13765
14134
|
},
|
|
13766
14135
|
className: "relative pointer-events-none",
|
|
13767
14136
|
children: [
|
|
13768
|
-
(activeSide === null || activeSide === "top") && /* @__PURE__ */
|
|
14137
|
+
(activeSide === null || activeSide === "top") && /* @__PURE__ */ jsx45(
|
|
13769
14138
|
"div",
|
|
13770
14139
|
{
|
|
13771
14140
|
onPointerDown: (e) => handlePointerDown(e, "top"),
|
|
13772
14141
|
className: `w-[18px] h-[8px] cursor-ns-resize ${handleBaseClass} left-1/2 -translate-x-1/2 -top-[4px] ${getHandleActiveClass("top")}`
|
|
13773
14142
|
}
|
|
13774
14143
|
),
|
|
13775
|
-
showRightHandle && (activeSide === null || activeSide === "right") && /* @__PURE__ */
|
|
14144
|
+
showRightHandle && (activeSide === null || activeSide === "right") && /* @__PURE__ */ jsx45(
|
|
13776
14145
|
"div",
|
|
13777
14146
|
{
|
|
13778
14147
|
onPointerDown: (e) => handlePointerDown(e, "right"),
|
|
13779
14148
|
className: `w-[8px] h-[18px] cursor-ew-resize ${handleBaseClass} top-1/2 -translate-y-1/2 -right-[4px] ${getHandleActiveClass("right")}`
|
|
13780
14149
|
}
|
|
13781
14150
|
),
|
|
13782
|
-
(activeSide === null || activeSide === "bottom") && /* @__PURE__ */
|
|
14151
|
+
(activeSide === null || activeSide === "bottom") && /* @__PURE__ */ jsx45(
|
|
13783
14152
|
"div",
|
|
13784
14153
|
{
|
|
13785
14154
|
onPointerDown: (e) => handlePointerDown(e, "bottom"),
|
|
13786
14155
|
className: `w-[18px] h-[8px] cursor-ns-resize ${handleBaseClass} left-1/2 -translate-x-1/2 -bottom-[4px] ${getHandleActiveClass("bottom")}`
|
|
13787
14156
|
}
|
|
13788
14157
|
),
|
|
13789
|
-
showLeftHandle && (activeSide === null || activeSide === "left") && /* @__PURE__ */
|
|
14158
|
+
showLeftHandle && (activeSide === null || activeSide === "left") && /* @__PURE__ */ jsx45(
|
|
13790
14159
|
"div",
|
|
13791
14160
|
{
|
|
13792
14161
|
onPointerDown: (e) => handlePointerDown(e, "left"),
|
|
13793
14162
|
className: `w-[8px] h-[18px] cursor-ew-resize ${handleBaseClass} top-1/2 -translate-y-1/2 -left-[4px] ${getHandleActiveClass("left")}`
|
|
13794
14163
|
}
|
|
14164
|
+
),
|
|
14165
|
+
showTopLeft && (activeSide === null || activeSide === "top-left") && /* @__PURE__ */ jsx45(
|
|
14166
|
+
"div",
|
|
14167
|
+
{
|
|
14168
|
+
onPointerDown: (e) => handlePointerDown(e, "top-left"),
|
|
14169
|
+
className: `w-[10px] h-[10px] cursor-nwse-resize ${handleBaseClass} -top-[5px] -left-[5px] ${getHandleActiveClass("top-left")}`
|
|
14170
|
+
}
|
|
14171
|
+
),
|
|
14172
|
+
showTopRight && (activeSide === null || activeSide === "top-right") && /* @__PURE__ */ jsx45(
|
|
14173
|
+
"div",
|
|
14174
|
+
{
|
|
14175
|
+
onPointerDown: (e) => handlePointerDown(e, "top-right"),
|
|
14176
|
+
className: `w-[10px] h-[10px] cursor-nesw-resize ${handleBaseClass} -top-[5px] -right-[5px] ${getHandleActiveClass("top-right")}`
|
|
14177
|
+
}
|
|
14178
|
+
),
|
|
14179
|
+
showBottomLeft && (activeSide === null || activeSide === "bottom-left") && /* @__PURE__ */ jsx45(
|
|
14180
|
+
"div",
|
|
14181
|
+
{
|
|
14182
|
+
onPointerDown: (e) => handlePointerDown(e, "bottom-left"),
|
|
14183
|
+
className: `w-[10px] h-[10px] cursor-nesw-resize ${handleBaseClass} -bottom-[5px] -left-[5px] ${getHandleActiveClass("bottom-left")}`
|
|
14184
|
+
}
|
|
14185
|
+
),
|
|
14186
|
+
showBottomRight && (activeSide === null || activeSide === "bottom-right") && /* @__PURE__ */ jsx45(
|
|
14187
|
+
"div",
|
|
14188
|
+
{
|
|
14189
|
+
onPointerDown: (e) => handlePointerDown(e, "bottom-right"),
|
|
14190
|
+
className: `w-[10px] h-[10px] cursor-nwse-resize ${handleBaseClass} -bottom-[5px] -right-[5px] ${getHandleActiveClass("bottom-right")}`
|
|
14191
|
+
}
|
|
13795
14192
|
)
|
|
13796
14193
|
]
|
|
13797
14194
|
}
|
|
@@ -13799,22 +14196,22 @@ var ImageScale = ({ getReferenceRect }) => {
|
|
|
13799
14196
|
};
|
|
13800
14197
|
|
|
13801
14198
|
// src/core/editor/components/scaling/spacer-scale.tsx
|
|
13802
|
-
import { useMemo as
|
|
13803
|
-
import { useFloating as
|
|
13804
|
-
import { jsx as
|
|
14199
|
+
import { useMemo as useMemo16, useEffect as useEffect12, useState as useState13, useRef as useRef9, useCallback as useCallback17 } from "react";
|
|
14200
|
+
import { useFloating as useFloating9, offset as offset9, autoUpdate as autoUpdate7 } from "@floating-ui/react";
|
|
14201
|
+
import { jsx as jsx46, jsxs as jsxs29 } from "react/jsx-runtime";
|
|
13805
14202
|
var SpacerScale = ({ getReferenceRect }) => {
|
|
13806
|
-
const [dimensions, setDimensions] =
|
|
13807
|
-
const [activeSide, setActiveSide] =
|
|
14203
|
+
const [dimensions, setDimensions] = useState13({ width: 0, height: 0 });
|
|
14204
|
+
const [activeSide, setActiveSide] = useState13(null);
|
|
13808
14205
|
const { focusIdx, template, setIsScaling } = useEditorStore();
|
|
13809
|
-
const currentHeight =
|
|
14206
|
+
const currentHeight = useMemo16(() => {
|
|
13810
14207
|
if (!focusIdx || !template) return 12;
|
|
13811
14208
|
const element = getValueByIdx(template, focusIdx);
|
|
13812
14209
|
const rawHeight = element?.attributes?.height;
|
|
13813
14210
|
const parsedHeight = rawHeight ? parseFloat(rawHeight.replace("px", "")) : 12;
|
|
13814
14211
|
return isNaN(parsedHeight) ? 12 : Math.max(12, Math.min(200, parsedHeight));
|
|
13815
14212
|
}, [focusIdx, template]);
|
|
13816
|
-
const dragRef =
|
|
13817
|
-
const handlePointerDown =
|
|
14213
|
+
const dragRef = useRef9(null);
|
|
14214
|
+
const handlePointerDown = useCallback17((e, side) => {
|
|
13818
14215
|
e.preventDefault();
|
|
13819
14216
|
e.stopPropagation();
|
|
13820
14217
|
if (document.activeElement instanceof HTMLElement) {
|
|
@@ -13830,7 +14227,7 @@ var SpacerScale = ({ getReferenceRect }) => {
|
|
|
13830
14227
|
document.addEventListener("pointermove", handlePointerMove);
|
|
13831
14228
|
document.addEventListener("pointerup", handlePointerUp);
|
|
13832
14229
|
}, [currentHeight, setIsScaling]);
|
|
13833
|
-
const handlePointerMove =
|
|
14230
|
+
const handlePointerMove = useCallback17((e) => {
|
|
13834
14231
|
if (!dragRef.current) return;
|
|
13835
14232
|
const { startY, startHeight, side } = dragRef.current;
|
|
13836
14233
|
const state = useEditorStore.getState();
|
|
@@ -13848,20 +14245,20 @@ var SpacerScale = ({ getReferenceRect }) => {
|
|
|
13848
14245
|
}
|
|
13849
14246
|
});
|
|
13850
14247
|
}, []);
|
|
13851
|
-
const handlePointerUp =
|
|
14248
|
+
const handlePointerUp = useCallback17(() => {
|
|
13852
14249
|
setActiveSide(null);
|
|
13853
14250
|
setIsScaling(false);
|
|
13854
14251
|
dragRef.current = null;
|
|
13855
14252
|
document.removeEventListener("pointermove", handlePointerMove);
|
|
13856
14253
|
document.removeEventListener("pointerup", handlePointerUp);
|
|
13857
14254
|
}, [handlePointerMove, setIsScaling]);
|
|
13858
|
-
|
|
14255
|
+
useEffect12(() => {
|
|
13859
14256
|
return () => {
|
|
13860
14257
|
document.removeEventListener("pointermove", handlePointerMove);
|
|
13861
14258
|
document.removeEventListener("pointerup", handlePointerUp);
|
|
13862
14259
|
};
|
|
13863
14260
|
}, [handlePointerMove, handlePointerUp]);
|
|
13864
|
-
const virtualReference =
|
|
14261
|
+
const virtualReference = useMemo16(() => ({
|
|
13865
14262
|
getBoundingClientRect: () => {
|
|
13866
14263
|
const rect = getReferenceRect();
|
|
13867
14264
|
if (!rect) {
|
|
@@ -13870,13 +14267,13 @@ var SpacerScale = ({ getReferenceRect }) => {
|
|
|
13870
14267
|
return rect;
|
|
13871
14268
|
}
|
|
13872
14269
|
}), [getReferenceRect]);
|
|
13873
|
-
const { floatingStyles, refs, update } =
|
|
14270
|
+
const { floatingStyles, refs, update } = useFloating9({
|
|
13874
14271
|
placement: "bottom-start",
|
|
13875
14272
|
middleware: [
|
|
13876
|
-
|
|
14273
|
+
offset9(({ rects }) => -rects.reference.height)
|
|
13877
14274
|
]
|
|
13878
14275
|
});
|
|
13879
|
-
|
|
14276
|
+
useEffect12(() => {
|
|
13880
14277
|
const rect = getReferenceRect();
|
|
13881
14278
|
if (!rect || !refs.floating.current) return;
|
|
13882
14279
|
refs.setPositionReference(virtualReference);
|
|
@@ -13903,7 +14300,7 @@ var SpacerScale = ({ getReferenceRect }) => {
|
|
|
13903
14300
|
}, [getReferenceRect, refs, update, virtualReference]);
|
|
13904
14301
|
const handleBaseClass = "bg-background shadow-md border rounded-full absolute touch-none select-none pointer-events-auto";
|
|
13905
14302
|
const getHandleActiveClass = (side) => activeSide === side ? "bg-blue-400 border-blue-300" : "hover:bg-blue-400 hover:border-blue-300";
|
|
13906
|
-
return /* @__PURE__ */
|
|
14303
|
+
return /* @__PURE__ */ jsxs29(
|
|
13907
14304
|
"div",
|
|
13908
14305
|
{
|
|
13909
14306
|
ref: refs.setFloating,
|
|
@@ -13915,14 +14312,14 @@ var SpacerScale = ({ getReferenceRect }) => {
|
|
|
13915
14312
|
},
|
|
13916
14313
|
className: "relative pointer-events-none",
|
|
13917
14314
|
children: [
|
|
13918
|
-
(activeSide === null || activeSide === "top") && /* @__PURE__ */
|
|
14315
|
+
(activeSide === null || activeSide === "top") && /* @__PURE__ */ jsx46(
|
|
13919
14316
|
"div",
|
|
13920
14317
|
{
|
|
13921
14318
|
onPointerDown: (e) => handlePointerDown(e, "top"),
|
|
13922
14319
|
className: `w-[18px] h-[8px] cursor-ns-resize ${handleBaseClass} left-1/2 -translate-x-1/2 -top-[4px] ${getHandleActiveClass("top")}`
|
|
13923
14320
|
}
|
|
13924
14321
|
),
|
|
13925
|
-
(activeSide === null || activeSide === "bottom") && /* @__PURE__ */
|
|
14322
|
+
(activeSide === null || activeSide === "bottom") && /* @__PURE__ */ jsx46(
|
|
13926
14323
|
"div",
|
|
13927
14324
|
{
|
|
13928
14325
|
onPointerDown: (e) => handlePointerDown(e, "bottom"),
|
|
@@ -13935,19 +14332,19 @@ var SpacerScale = ({ getReferenceRect }) => {
|
|
|
13935
14332
|
};
|
|
13936
14333
|
|
|
13937
14334
|
// src/core/editor/components/scaling/column-scale.tsx
|
|
13938
|
-
import { useMemo as
|
|
13939
|
-
import { Fragment as Fragment17, jsx as
|
|
14335
|
+
import { useMemo as useMemo17, useEffect as useEffect13, useState as useState14, useRef as useRef10, useCallback as useCallback18 } from "react";
|
|
14336
|
+
import { Fragment as Fragment17, jsx as jsx47 } from "react/jsx-runtime";
|
|
13940
14337
|
var ColumnScale = ({ sectionColumnIdx, shadowRoot }) => {
|
|
13941
|
-
const [activeDivider, setActiveDivider] =
|
|
13942
|
-
const [columnRects, setColumnRects] =
|
|
14338
|
+
const [activeDivider, setActiveDivider] = useState14(null);
|
|
14339
|
+
const [columnRects, setColumnRects] = useState14([]);
|
|
13943
14340
|
const { template, setIsScaling, setFocusIdx, stopTextEditing } = useEditorStore();
|
|
13944
|
-
const columnWidths =
|
|
14341
|
+
const columnWidths = useMemo17(() => {
|
|
13945
14342
|
if (!template) return [];
|
|
13946
14343
|
const sectionColumn = getValueByIdx(template, sectionColumnIdx);
|
|
13947
14344
|
return sectionColumn?.data?.value?.columnWidths || [];
|
|
13948
14345
|
}, [template, sectionColumnIdx]);
|
|
13949
|
-
const dragRef =
|
|
13950
|
-
const updateColumnRects =
|
|
14346
|
+
const dragRef = useRef10(null);
|
|
14347
|
+
const updateColumnRects = useCallback18(() => {
|
|
13951
14348
|
if (!shadowRoot) return;
|
|
13952
14349
|
const allColumns = shadowRoot.querySelectorAll(".node-type-column");
|
|
13953
14350
|
const matchingColumns = [];
|
|
@@ -13979,7 +14376,7 @@ var ColumnScale = ({ sectionColumnIdx, shadowRoot }) => {
|
|
|
13979
14376
|
});
|
|
13980
14377
|
setColumnRects(rects);
|
|
13981
14378
|
}, [shadowRoot, sectionColumnIdx]);
|
|
13982
|
-
|
|
14379
|
+
useEffect13(() => {
|
|
13983
14380
|
updateColumnRects();
|
|
13984
14381
|
let animationId;
|
|
13985
14382
|
const updateLoop = () => {
|
|
@@ -13992,7 +14389,7 @@ var ColumnScale = ({ sectionColumnIdx, shadowRoot }) => {
|
|
|
13992
14389
|
const parseWidth = (width) => {
|
|
13993
14390
|
return parseFloat(width.replace("%", ""));
|
|
13994
14391
|
};
|
|
13995
|
-
const handlePointerDown =
|
|
14392
|
+
const handlePointerDown = useCallback18((e, dividerIndex) => {
|
|
13996
14393
|
e.preventDefault();
|
|
13997
14394
|
e.stopPropagation();
|
|
13998
14395
|
stopTextEditing();
|
|
@@ -14018,7 +14415,7 @@ var ColumnScale = ({ sectionColumnIdx, shadowRoot }) => {
|
|
|
14018
14415
|
document.addEventListener("pointermove", handlePointerMove);
|
|
14019
14416
|
document.addEventListener("pointerup", handlePointerUp);
|
|
14020
14417
|
}, [columnRects, columnWidths, setIsScaling]);
|
|
14021
|
-
const handlePointerMove =
|
|
14418
|
+
const handlePointerMove = useCallback18((e) => {
|
|
14022
14419
|
if (!dragRef.current) return;
|
|
14023
14420
|
const { startX, leftColIndex, rightColIndex, startLeftWidth, startRightWidth, sectionWidth, allWidths } = dragRef.current;
|
|
14024
14421
|
const deltaX = e.clientX - startX;
|
|
@@ -14052,14 +14449,14 @@ var ColumnScale = ({ sectionColumnIdx, shadowRoot }) => {
|
|
|
14052
14449
|
}
|
|
14053
14450
|
});
|
|
14054
14451
|
}, [sectionColumnIdx]);
|
|
14055
|
-
const handlePointerUp =
|
|
14452
|
+
const handlePointerUp = useCallback18(() => {
|
|
14056
14453
|
setActiveDivider(null);
|
|
14057
14454
|
setIsScaling(false);
|
|
14058
14455
|
dragRef.current = null;
|
|
14059
14456
|
document.removeEventListener("pointermove", handlePointerMove);
|
|
14060
14457
|
document.removeEventListener("pointerup", handlePointerUp);
|
|
14061
14458
|
}, [handlePointerMove, setIsScaling]);
|
|
14062
|
-
|
|
14459
|
+
useEffect13(() => {
|
|
14063
14460
|
return () => {
|
|
14064
14461
|
document.removeEventListener("pointermove", handlePointerMove);
|
|
14065
14462
|
document.removeEventListener("pointerup", handlePointerUp);
|
|
@@ -14070,7 +14467,7 @@ var ColumnScale = ({ sectionColumnIdx, shadowRoot }) => {
|
|
|
14070
14467
|
}
|
|
14071
14468
|
const handleBaseClass = "bg-background shadow-md border rounded-full touch-none select-none pointer-events-auto";
|
|
14072
14469
|
const getHandleActiveClass = (index) => activeDivider === index ? "bg-blue-400 border-blue-300" : "hover:bg-blue-400 hover:border-blue-300";
|
|
14073
|
-
return /* @__PURE__ */
|
|
14470
|
+
return /* @__PURE__ */ jsx47(Fragment17, { children: columnRects.slice(0, -1).map((rect, index) => {
|
|
14074
14471
|
const nextRect = columnRects[index + 1];
|
|
14075
14472
|
const handleLeft = rect.right;
|
|
14076
14473
|
const handleTop = Math.min(rect.top, nextRect.top);
|
|
@@ -14078,7 +14475,7 @@ var ColumnScale = ({ sectionColumnIdx, shadowRoot }) => {
|
|
|
14078
14475
|
if (activeDivider !== null && activeDivider !== index) {
|
|
14079
14476
|
return null;
|
|
14080
14477
|
}
|
|
14081
|
-
return /* @__PURE__ */
|
|
14478
|
+
return /* @__PURE__ */ jsx47(
|
|
14082
14479
|
"div",
|
|
14083
14480
|
{
|
|
14084
14481
|
onPointerDown: (e) => handlePointerDown(e, index),
|
|
@@ -14098,9 +14495,9 @@ var ColumnScale = ({ sectionColumnIdx, shadowRoot }) => {
|
|
|
14098
14495
|
};
|
|
14099
14496
|
|
|
14100
14497
|
// src/core/editor/hooks/use-undo-redo-keyboard.ts
|
|
14101
|
-
import { useEffect as
|
|
14498
|
+
import { useEffect as useEffect14 } from "react";
|
|
14102
14499
|
function useUndoRedoKeyboard() {
|
|
14103
|
-
|
|
14500
|
+
useEffect14(() => {
|
|
14104
14501
|
const handler = (e) => {
|
|
14105
14502
|
const isMeta = e.metaKey || e.ctrlKey;
|
|
14106
14503
|
if (!isMeta || e.key.toLowerCase() !== "z") return;
|
|
@@ -14122,9 +14519,9 @@ function useUndoRedoKeyboard() {
|
|
|
14122
14519
|
|
|
14123
14520
|
// src/components/ui/spinner.tsx
|
|
14124
14521
|
import { Loader2Icon as Loader2Icon2 } from "lucide-react";
|
|
14125
|
-
import { jsx as
|
|
14522
|
+
import { jsx as jsx48 } from "react/jsx-runtime";
|
|
14126
14523
|
function Spinner({ className, ...props }) {
|
|
14127
|
-
return /* @__PURE__ */
|
|
14524
|
+
return /* @__PURE__ */ jsx48(
|
|
14128
14525
|
Loader2Icon2,
|
|
14129
14526
|
{
|
|
14130
14527
|
role: "status",
|
|
@@ -14136,10 +14533,10 @@ function Spinner({ className, ...props }) {
|
|
|
14136
14533
|
}
|
|
14137
14534
|
|
|
14138
14535
|
// src/core/editor/components/preview.tsx
|
|
14139
|
-
import { EyeIcon } from "lucide-react";
|
|
14536
|
+
import { EyeIcon, SendIcon, Monitor, Smartphone } from "lucide-react";
|
|
14140
14537
|
|
|
14141
14538
|
// src/render/useMjmlCompiler.ts
|
|
14142
|
-
import { useState as
|
|
14539
|
+
import { useState as useState15, useCallback as useCallback19 } from "react";
|
|
14143
14540
|
async function compileMjml(mjml) {
|
|
14144
14541
|
console.log("Compiling MJML", mjml);
|
|
14145
14542
|
const response = await fetch("/api/mrender", {
|
|
@@ -14156,14 +14553,101 @@ async function compileMjml(mjml) {
|
|
|
14156
14553
|
}
|
|
14157
14554
|
|
|
14158
14555
|
// src/core/editor/components/preview.tsx
|
|
14159
|
-
import { useEffect as
|
|
14160
|
-
|
|
14556
|
+
import { useEffect as useEffect15, useState as useState16, useRef as useRef11 } from "react";
|
|
14557
|
+
|
|
14558
|
+
// src/validate/helpers.ts
|
|
14559
|
+
var MERGE_FIELD_REGEX2 = /\{\{([a-zA-Z_][a-zA-Z0-9_]*)\}\}/g;
|
|
14560
|
+
function extractMergeFields(node) {
|
|
14561
|
+
const fields = [];
|
|
14562
|
+
if (!node || typeof node !== "object") return fields;
|
|
14563
|
+
const content = node?.data?.value?.content;
|
|
14564
|
+
if (typeof content === "string") {
|
|
14565
|
+
let match;
|
|
14566
|
+
MERGE_FIELD_REGEX2.lastIndex = 0;
|
|
14567
|
+
while ((match = MERGE_FIELD_REGEX2.exec(content)) !== null) {
|
|
14568
|
+
fields.push(match[1]);
|
|
14569
|
+
}
|
|
14570
|
+
}
|
|
14571
|
+
if (Array.isArray(node.children)) {
|
|
14572
|
+
for (const child of node.children) {
|
|
14573
|
+
fields.push(...extractMergeFields(child));
|
|
14574
|
+
}
|
|
14575
|
+
}
|
|
14576
|
+
if (Array.isArray(node.content)) {
|
|
14577
|
+
for (const page of node.content) {
|
|
14578
|
+
fields.push(...extractMergeFields(page));
|
|
14579
|
+
}
|
|
14580
|
+
}
|
|
14581
|
+
return fields;
|
|
14582
|
+
}
|
|
14583
|
+
function extractEmptyLinks(node) {
|
|
14584
|
+
const results = [];
|
|
14585
|
+
if (!node || typeof node !== "object") return results;
|
|
14586
|
+
if (node.type === "button" || node.type === "social-item") {
|
|
14587
|
+
const href = node.attributes?.href;
|
|
14588
|
+
if (!href || href.trim() === "") {
|
|
14589
|
+
const label = node.type === "button" ? node.data?.value?.content || "Untitled Button" : node.attributes?.alt || node.data?.value?.socialType || "Social Link";
|
|
14590
|
+
results.push({ type: node.type, label });
|
|
14591
|
+
}
|
|
14592
|
+
}
|
|
14593
|
+
if (Array.isArray(node.children)) {
|
|
14594
|
+
for (const child of node.children) {
|
|
14595
|
+
results.push(...extractEmptyLinks(child));
|
|
14596
|
+
}
|
|
14597
|
+
}
|
|
14598
|
+
if (Array.isArray(node.content)) {
|
|
14599
|
+
for (const page of node.content) {
|
|
14600
|
+
results.push(...extractEmptyLinks(page));
|
|
14601
|
+
}
|
|
14602
|
+
}
|
|
14603
|
+
return results;
|
|
14604
|
+
}
|
|
14605
|
+
|
|
14606
|
+
// src/validate/index.ts
|
|
14607
|
+
var PROPERTY_CARD_TYPES = /* @__PURE__ */ new Set(["property-card", "property-card-single-two", "property-card-triple-item"]);
|
|
14608
|
+
function countPlaceholderPropertyImages(node) {
|
|
14609
|
+
let count = 0;
|
|
14610
|
+
if (!node || typeof node !== "object") return count;
|
|
14611
|
+
if (PROPERTY_CARD_TYPES.has(node.type)) {
|
|
14612
|
+
const imageSrc = node.attributes?.["image-src"];
|
|
14613
|
+
if (!imageSrc || imageSrc === DEFAULT_PROPERTY_PLACEHOLDER_IMAGE) {
|
|
14614
|
+
count++;
|
|
14615
|
+
}
|
|
14616
|
+
}
|
|
14617
|
+
if (Array.isArray(node.children)) {
|
|
14618
|
+
for (const child of node.children) {
|
|
14619
|
+
count += countPlaceholderPropertyImages(child);
|
|
14620
|
+
}
|
|
14621
|
+
}
|
|
14622
|
+
if (Array.isArray(node.content)) {
|
|
14623
|
+
for (const page of node.content) {
|
|
14624
|
+
count += countPlaceholderPropertyImages(page);
|
|
14625
|
+
}
|
|
14626
|
+
}
|
|
14627
|
+
return count;
|
|
14628
|
+
}
|
|
14629
|
+
function validate_editor_onPreview(template, mergeFields) {
|
|
14630
|
+
const usedFields = [...new Set(extractMergeFields(template))];
|
|
14631
|
+
const validValues = new Set(mergeFields.map((f) => f.value));
|
|
14632
|
+
const invalid_merge_fields = usedFields.filter((field) => !validValues.has(field));
|
|
14633
|
+
const missing_links = extractEmptyLinks(template);
|
|
14634
|
+
const placeholder_property_images = countPlaceholderPropertyImages(template);
|
|
14635
|
+
const templateSize = new Blob([JSON.stringify(template)]).size;
|
|
14636
|
+
const is_over_size_limit = templateSize > 50 * 1024;
|
|
14637
|
+
return { invalid_merge_fields, missing_links, is_over_size_limit, placeholder_property_images };
|
|
14638
|
+
}
|
|
14639
|
+
|
|
14640
|
+
// src/core/editor/components/preview.tsx
|
|
14641
|
+
import { jsx as jsx49, jsxs as jsxs30 } from "react/jsx-runtime";
|
|
14161
14642
|
function Preview() {
|
|
14162
|
-
const { template, setPreviewMode, previewMode, isPaidLevel } = useEditorStore();
|
|
14163
|
-
const [html, setHtml] =
|
|
14164
|
-
const [isLoading, setIsLoading] =
|
|
14165
|
-
const lastTemplateRef =
|
|
14166
|
-
|
|
14643
|
+
const { template, setPreviewMode, previewMode, isPaidLevel, mergeFields } = useEditorStore();
|
|
14644
|
+
const [html, setHtml] = useState16("");
|
|
14645
|
+
const [isLoading, setIsLoading] = useState16(false);
|
|
14646
|
+
const lastTemplateRef = useRef11("");
|
|
14647
|
+
const [deviceMode, setDeviceMode] = useState16("desktop");
|
|
14648
|
+
const [preview_validations, setPreviewValidations] = useState16({ invalid_merge_fields: [], missing_links: [], is_over_size_limit: false, placeholder_property_images: 0 });
|
|
14649
|
+
const [mjmlErrors, setMjmlErrors] = useState16([]);
|
|
14650
|
+
useEffect15(() => {
|
|
14167
14651
|
if (typeof window === "undefined" || !previewMode) {
|
|
14168
14652
|
if (!previewMode) {
|
|
14169
14653
|
setHtml("");
|
|
@@ -14177,56 +14661,165 @@ function Preview() {
|
|
|
14177
14661
|
}
|
|
14178
14662
|
lastTemplateRef.current = templateString;
|
|
14179
14663
|
setIsLoading(true);
|
|
14664
|
+
const validatePreview = () => {
|
|
14665
|
+
const validations = validate_editor_onPreview(template, mergeFields);
|
|
14666
|
+
setPreviewValidations(validations);
|
|
14667
|
+
};
|
|
14180
14668
|
const convertMjml = async () => {
|
|
14181
14669
|
try {
|
|
14182
14670
|
const mjmlString = json2mjml(template, "production", { isPaidLevel });
|
|
14183
14671
|
console.log("MJML string:", mjmlString);
|
|
14184
14672
|
const result = await compileMjml(mjmlString);
|
|
14673
|
+
console.log("MJML errors:", result);
|
|
14674
|
+
setMjmlErrors(result.errors ?? []);
|
|
14185
14675
|
if (result.errors?.length > 0) {
|
|
14186
|
-
console.warn("MJML warnings:", result.errors);
|
|
14676
|
+
console.warn("MJML warnings 1:", result.errors);
|
|
14187
14677
|
}
|
|
14188
14678
|
console.log(result.html);
|
|
14189
14679
|
setHtml(result.html);
|
|
14190
14680
|
} catch (error) {
|
|
14191
14681
|
console.error("MJML compilation error:", error);
|
|
14682
|
+
setMjmlErrors([]);
|
|
14192
14683
|
setHtml('<p style="color: red; padding: 20px;">Error generating preview</p>');
|
|
14193
14684
|
} finally {
|
|
14194
14685
|
setIsLoading(false);
|
|
14195
14686
|
}
|
|
14196
14687
|
};
|
|
14688
|
+
validatePreview();
|
|
14197
14689
|
convertMjml();
|
|
14198
14690
|
}, [template, previewMode]);
|
|
14199
|
-
|
|
14200
|
-
|
|
14201
|
-
|
|
14691
|
+
const hasValidations = preview_validations.invalid_merge_fields.length > 0 || preview_validations.missing_links.length > 0 || preview_validations.is_over_size_limit || preview_validations.placeholder_property_images > 0 || mjmlErrors.length > 0;
|
|
14692
|
+
return /* @__PURE__ */ jsxs30(Dialog, { open: previewMode, onOpenChange: setPreviewMode, children: [
|
|
14693
|
+
/* @__PURE__ */ jsxs30(Tooltip, { children: [
|
|
14694
|
+
/* @__PURE__ */ jsx49(TooltipTrigger, { asChild: true, children: /* @__PURE__ */ jsx49(
|
|
14202
14695
|
Button,
|
|
14203
14696
|
{
|
|
14204
14697
|
variant: "ghost",
|
|
14205
14698
|
className: "shadow-none transition-none cursor-pointer",
|
|
14206
14699
|
size: "icon",
|
|
14207
14700
|
onClick: () => setPreviewMode(true),
|
|
14208
|
-
children: /* @__PURE__ */
|
|
14701
|
+
children: /* @__PURE__ */ jsx49(EyeIcon, {})
|
|
14209
14702
|
}
|
|
14210
14703
|
) }),
|
|
14211
|
-
/* @__PURE__ */
|
|
14704
|
+
/* @__PURE__ */ jsx49(TooltipContent, { side: "bottom", className: "z-51", children: "Preview" })
|
|
14212
14705
|
] }),
|
|
14213
|
-
/* @__PURE__ */
|
|
14214
|
-
|
|
14215
|
-
|
|
14216
|
-
|
|
14706
|
+
/* @__PURE__ */ jsxs30(
|
|
14707
|
+
DialogContent,
|
|
14708
|
+
{
|
|
14709
|
+
showCloseButton: true,
|
|
14710
|
+
className: "flex flex-col !fixed !top-14 !left-12 !right-12 !bottom-0 !transform-none !translate-x-0 !translate-y-0 !w-auto !h-auto !max-w-none !max-h-none rounded-b-none p-0 gap-0",
|
|
14711
|
+
children: [
|
|
14712
|
+
/* @__PURE__ */ jsx49(DialogHeader, { className: "border-b p-4", children: /* @__PURE__ */ jsx49(DialogTitle, { children: "Preview" }) }),
|
|
14713
|
+
/* @__PURE__ */ jsxs30("div", { className: "flex gap-2 justify-between border-b p-4", children: [
|
|
14714
|
+
/* @__PURE__ */ jsx49("div", { className: "flex gap-2", children: /* @__PURE__ */ jsxs30(Button, { variant: "ghost", onClick: () => {
|
|
14715
|
+
}, children: [
|
|
14716
|
+
/* @__PURE__ */ jsx49(SendIcon, { className: "w-4 h-4" }),
|
|
14717
|
+
"Send a Test Email"
|
|
14718
|
+
] }) }),
|
|
14719
|
+
/* @__PURE__ */ jsxs30("div", { className: "flex gap-2", children: [
|
|
14720
|
+
/* @__PURE__ */ jsxs30(
|
|
14721
|
+
Button,
|
|
14722
|
+
{
|
|
14723
|
+
variant: deviceMode === "desktop" ? "default" : "ghost",
|
|
14724
|
+
onClick: () => setDeviceMode("desktop"),
|
|
14725
|
+
className: "gap-2 cursor-pointer",
|
|
14726
|
+
children: [
|
|
14727
|
+
/* @__PURE__ */ jsx49(Monitor, { className: "w-4 h-4" }),
|
|
14728
|
+
"Desktop"
|
|
14729
|
+
]
|
|
14730
|
+
}
|
|
14731
|
+
),
|
|
14732
|
+
/* @__PURE__ */ jsxs30(
|
|
14733
|
+
Button,
|
|
14734
|
+
{
|
|
14735
|
+
variant: deviceMode === "mobile" ? "default" : "ghost",
|
|
14736
|
+
onClick: () => setDeviceMode("mobile"),
|
|
14737
|
+
className: "gap-2 cursor-pointer",
|
|
14738
|
+
children: [
|
|
14739
|
+
/* @__PURE__ */ jsx49(Smartphone, { className: "w-4 h-4" }),
|
|
14740
|
+
"Mobile"
|
|
14741
|
+
]
|
|
14742
|
+
}
|
|
14743
|
+
)
|
|
14744
|
+
] })
|
|
14745
|
+
] }),
|
|
14746
|
+
/* @__PURE__ */ jsxs30("div", { className: "flex flex-1 overflow-hidden", children: [
|
|
14747
|
+
/* @__PURE__ */ jsx49(
|
|
14748
|
+
"div",
|
|
14749
|
+
{
|
|
14750
|
+
className: "flex-1 flex items-start justify-center overflow-auto w-full",
|
|
14751
|
+
style: { backgroundColor: template?.content?.[0]?.attributes?.["background-color"] || "#965D5D" },
|
|
14752
|
+
children: isLoading ? /* @__PURE__ */ jsx49("div", { className: "flex items-center justify-center h-full w-full", children: /* @__PURE__ */ jsx49("p", { children: "Generating preview..." }) }) : /* @__PURE__ */ jsx49(
|
|
14753
|
+
"div",
|
|
14754
|
+
{
|
|
14755
|
+
className: "flex items-center justify-center bg-white transition-all duration-300 h-full w-full",
|
|
14756
|
+
children: /* @__PURE__ */ jsx49(
|
|
14757
|
+
"iframe",
|
|
14758
|
+
{
|
|
14759
|
+
srcDoc: html,
|
|
14760
|
+
className: "w-full border-0 transition-all duration-200",
|
|
14761
|
+
style: { height: "100%", minHeight: "600px", width: deviceMode === "desktop" ? "100%" : "360px", maxWidth: deviceMode === "desktop" ? "100%" : "360px" },
|
|
14762
|
+
title: "Email Preview",
|
|
14763
|
+
sandbox: "allow-same-origin"
|
|
14764
|
+
}
|
|
14765
|
+
)
|
|
14766
|
+
}
|
|
14767
|
+
)
|
|
14768
|
+
}
|
|
14769
|
+
),
|
|
14770
|
+
hasValidations && /* @__PURE__ */ jsxs30("div", { className: "w-[300px] border-l p-4 overflow-y-auto flex flex-col gap-4", children: [
|
|
14771
|
+
mjmlErrors.length > 0 && /* @__PURE__ */ jsxs30("div", { className: "w-full rounded-md border border-red-600 p-2", children: [
|
|
14772
|
+
/* @__PURE__ */ jsx49("h3", { className: "text-sm font-semibold text-red-600", children: "MJML Errors" }),
|
|
14773
|
+
/* @__PURE__ */ jsx49("p", { className: "text-sm mt-1 text-red-600", children: "The following errors occurred during email compilation:" }),
|
|
14774
|
+
/* @__PURE__ */ jsx49("ul", { className: "flex flex-col gap-2 my-2", children: mjmlErrors.map((err, i) => /* @__PURE__ */ jsxs30("li", { className: "text-sm font-mono bg-red-100 rounded border border-red-200 text-red-700 p-2", children: [
|
|
14775
|
+
/* @__PURE__ */ jsx49("span", { className: "font-semibold", children: err.tagName }),
|
|
14776
|
+
" (line ",
|
|
14777
|
+
err.line,
|
|
14778
|
+
"): ",
|
|
14779
|
+
err.message
|
|
14780
|
+
] }, i)) }),
|
|
14781
|
+
/* @__PURE__ */ jsx49("p", { className: "text-xs text-red-500 italic", children: "You may need to contact support to fix these errors. You'll still be able to send the email, but it may not look as expected." })
|
|
14782
|
+
] }),
|
|
14783
|
+
preview_validations.is_over_size_limit && /* @__PURE__ */ jsxs30("div", { className: "w-full rounded-md border border-red-300 p-2", children: [
|
|
14784
|
+
/* @__PURE__ */ jsx49("h3", { className: "text-sm font-semibold text-red-600", children: "Template Too Large" }),
|
|
14785
|
+
/* @__PURE__ */ jsx49("p", { className: "text-sm mt-1 text-red-600", children: "This template exceeds the size limit. Reduce your content to use this template, otherwise it will be auto-trimmed." })
|
|
14786
|
+
] }),
|
|
14787
|
+
preview_validations.placeholder_property_images > 0 && /* @__PURE__ */ jsxs30("div", { className: "w-full rounded-md border p-2", children: [
|
|
14788
|
+
/* @__PURE__ */ jsx49("h3", { className: "text-sm font-semibold", children: "Placeholder Property Image" }),
|
|
14789
|
+
/* @__PURE__ */ jsx49("p", { className: "text-sm mt-1", children: preview_validations.placeholder_property_images === 1 ? "1 property card is still using the default placeholder image. Upload an image of the property." : `${preview_validations.placeholder_property_images} property cards are still using the default placeholder image. Upload images for each property.` })
|
|
14790
|
+
] }),
|
|
14791
|
+
preview_validations.invalid_merge_fields.length > 0 && /* @__PURE__ */ jsxs30("div", { className: "w-full rounded-md border p-2", children: [
|
|
14792
|
+
/* @__PURE__ */ jsx49("h3", { className: "text-sm font-semibold", children: "Invalid Merge Fields" }),
|
|
14793
|
+
/* @__PURE__ */ jsx49("p", { className: "text-sm mt-1", children: "The following merge fields are used in the template but don't exist in your merge field data:" }),
|
|
14794
|
+
/* @__PURE__ */ jsx49("ul", { className: "flex flex-wrap gap-2 mt-2 space-y-1", children: preview_validations.invalid_merge_fields.map((field) => /* @__PURE__ */ jsx49("li", { className: "text-sm font-mono flex items-center justify-center no-wrap whitespace-nowrap bg-background text-nowrap text-ellipsis overflow-hidden rounded border border-border text-black p-2 h-[30px]", children: `{{${field}}}` }, field)) })
|
|
14795
|
+
] }),
|
|
14796
|
+
preview_validations.missing_links.length > 0 && /* @__PURE__ */ jsxs30("div", { className: "w-full rounded-md border p-2", children: [
|
|
14797
|
+
/* @__PURE__ */ jsx49("h3", { className: "text-sm font-semibold", children: "Missing Links" }),
|
|
14798
|
+
/* @__PURE__ */ jsx49("p", { className: "text-sm mt-1", children: "The following elements have no link set:" }),
|
|
14799
|
+
/* @__PURE__ */ jsx49("ul", { className: "flex flex-wrap gap-2 mt-2", children: preview_validations.missing_links.map((item, i) => /* @__PURE__ */ jsxs30("li", { className: "text-sm w-full font-mono flex items-center justify-start no-wrap whitespace-nowrap bg-background text-nowrap text-ellipsis overflow-hidden rounded border border-border text-black p-2 h-[30px]", children: [
|
|
14800
|
+
item.type === "button" ? "Button" : "Social",
|
|
14801
|
+
": ",
|
|
14802
|
+
item.label
|
|
14803
|
+
] }, i)) })
|
|
14804
|
+
] })
|
|
14805
|
+
] })
|
|
14806
|
+
] })
|
|
14807
|
+
]
|
|
14808
|
+
}
|
|
14809
|
+
)
|
|
14217
14810
|
] });
|
|
14218
14811
|
}
|
|
14219
14812
|
|
|
14220
14813
|
// src/core/editor/components/history.tsx
|
|
14221
14814
|
import { Redo2Icon, Undo2Icon } from "lucide-react";
|
|
14222
|
-
import { Fragment as Fragment18, jsx as
|
|
14815
|
+
import { Fragment as Fragment18, jsx as jsx50, jsxs as jsxs31 } from "react/jsx-runtime";
|
|
14223
14816
|
var History = () => {
|
|
14224
14817
|
const { undo, redo } = useEditorStore();
|
|
14225
14818
|
const canUndo = useEditorStore((s) => s.historyIndex > 0);
|
|
14226
14819
|
const canRedo = useEditorStore((s) => s.historyIndex < s.history.length - 1);
|
|
14227
|
-
return /* @__PURE__ */
|
|
14228
|
-
/* @__PURE__ */
|
|
14229
|
-
/* @__PURE__ */
|
|
14820
|
+
return /* @__PURE__ */ jsxs31(Fragment18, { children: [
|
|
14821
|
+
/* @__PURE__ */ jsxs31(Tooltip, { children: [
|
|
14822
|
+
/* @__PURE__ */ jsx50(TooltipTrigger, { asChild: true, children: /* @__PURE__ */ jsx50(
|
|
14230
14823
|
Button,
|
|
14231
14824
|
{
|
|
14232
14825
|
variant: "ghost",
|
|
@@ -14234,13 +14827,13 @@ var History = () => {
|
|
|
14234
14827
|
size: "icon",
|
|
14235
14828
|
disabled: !canUndo,
|
|
14236
14829
|
onClick: undo,
|
|
14237
|
-
children: /* @__PURE__ */
|
|
14830
|
+
children: /* @__PURE__ */ jsx50(Undo2Icon, {})
|
|
14238
14831
|
}
|
|
14239
14832
|
) }),
|
|
14240
|
-
/* @__PURE__ */
|
|
14833
|
+
/* @__PURE__ */ jsx50(TooltipContent, { side: "bottom", children: "Undo (Ctrl+Z)" })
|
|
14241
14834
|
] }),
|
|
14242
|
-
/* @__PURE__ */
|
|
14243
|
-
/* @__PURE__ */
|
|
14835
|
+
/* @__PURE__ */ jsxs31(Tooltip, { children: [
|
|
14836
|
+
/* @__PURE__ */ jsx50(TooltipTrigger, { asChild: true, children: /* @__PURE__ */ jsx50(
|
|
14244
14837
|
Button,
|
|
14245
14838
|
{
|
|
14246
14839
|
variant: "ghost",
|
|
@@ -14248,16 +14841,16 @@ var History = () => {
|
|
|
14248
14841
|
size: "icon",
|
|
14249
14842
|
disabled: !canRedo,
|
|
14250
14843
|
onClick: redo,
|
|
14251
|
-
children: /* @__PURE__ */
|
|
14844
|
+
children: /* @__PURE__ */ jsx50(Redo2Icon, {})
|
|
14252
14845
|
}
|
|
14253
14846
|
) }),
|
|
14254
|
-
/* @__PURE__ */
|
|
14847
|
+
/* @__PURE__ */ jsx50(TooltipContent, { side: "bottom", children: "Redo (Ctrl+Shift+Z)" })
|
|
14255
14848
|
] })
|
|
14256
14849
|
] });
|
|
14257
14850
|
};
|
|
14258
14851
|
|
|
14259
14852
|
// src/core/index.tsx
|
|
14260
|
-
import { jsx as
|
|
14853
|
+
import { jsx as jsx51, jsxs as jsxs32 } from "react/jsx-runtime";
|
|
14261
14854
|
var MAILLOW_EMAIL_EDITOR_VERSION = "0.0.1";
|
|
14262
14855
|
function getSectionColumnIdx(idx, template) {
|
|
14263
14856
|
let current = idx;
|
|
@@ -14293,6 +14886,20 @@ function getCompanyFooterSection(template) {
|
|
|
14293
14886
|
}
|
|
14294
14887
|
return null;
|
|
14295
14888
|
}
|
|
14889
|
+
function restoreImagePreview(shadowRoot, targetIdx, originalSrc) {
|
|
14890
|
+
const targetEl = shadowRoot.querySelector(`.node-idx-${CSS.escape(targetIdx)}`);
|
|
14891
|
+
if (!targetEl) return;
|
|
14892
|
+
const bgEl = targetEl.querySelector("td[background], th[background]");
|
|
14893
|
+
if (bgEl) {
|
|
14894
|
+
bgEl.setAttribute("background", originalSrc);
|
|
14895
|
+
bgEl.style.backgroundImage = `url(${originalSrc})`;
|
|
14896
|
+
return;
|
|
14897
|
+
}
|
|
14898
|
+
const img = targetEl.querySelector("img");
|
|
14899
|
+
if (img) {
|
|
14900
|
+
img.src = originalSrc;
|
|
14901
|
+
}
|
|
14902
|
+
}
|
|
14296
14903
|
function Editor({ setEditorLoading }) {
|
|
14297
14904
|
useUndoRedoKeyboard();
|
|
14298
14905
|
const template = useEditorStore((state) => state.template);
|
|
@@ -14323,29 +14930,32 @@ function Editor({ setEditorLoading }) {
|
|
|
14323
14930
|
const startTextEditing = useEditorStore((state) => state.startTextEditing);
|
|
14324
14931
|
const pendingTextEditRequest = useEditorStore((state) => state.pendingTextEditRequest);
|
|
14325
14932
|
const clearPendingTextEditRequest = useEditorStore((state) => state.clearPendingTextEditRequest);
|
|
14326
|
-
const [renderData, setRenderData] =
|
|
14327
|
-
const [isEditing, setIsEditing] =
|
|
14328
|
-
const [dropIndicator, setDropIndicator] =
|
|
14329
|
-
const [dropTargetIdx, setDropTargetIdx] =
|
|
14330
|
-
const shadowRootRef =
|
|
14331
|
-
const [hasSelectedElement, setHasSelectedElement] =
|
|
14332
|
-
const dragParentIdxRef =
|
|
14333
|
-
const dragPositionIndexRef =
|
|
14334
|
-
const createNewSectionRef =
|
|
14335
|
-
const splitAtParagraphRef =
|
|
14336
|
-
const isHorizontalDropRef =
|
|
14337
|
-
const horizontalDropPositionRef =
|
|
14338
|
-
const isSplitSectionDropRef =
|
|
14339
|
-
const splitSectionAtElementRef =
|
|
14340
|
-
const templateCacheRef =
|
|
14341
|
-
const parentSectionCacheRef =
|
|
14342
|
-
const sectionElementCacheRef =
|
|
14343
|
-
const sectionRectCacheRef =
|
|
14344
|
-
const companyFooterCacheRef =
|
|
14345
|
-
const lastSyncedTemplateRef =
|
|
14346
|
-
const prevTextEditingIdxRef =
|
|
14347
|
-
const lastRenderSyncNeededRef =
|
|
14348
|
-
|
|
14933
|
+
const [renderData, setRenderData] = useState17(null);
|
|
14934
|
+
const [isEditing, setIsEditing] = useState17(false);
|
|
14935
|
+
const [dropIndicator, setDropIndicator] = useState17(null);
|
|
14936
|
+
const [dropTargetIdx, setDropTargetIdx] = useState17(null);
|
|
14937
|
+
const shadowRootRef = useRef12(null);
|
|
14938
|
+
const [hasSelectedElement, setHasSelectedElement] = useState17(false);
|
|
14939
|
+
const dragParentIdxRef = useRef12(null);
|
|
14940
|
+
const dragPositionIndexRef = useRef12(0);
|
|
14941
|
+
const createNewSectionRef = useRef12(false);
|
|
14942
|
+
const splitAtParagraphRef = useRef12(null);
|
|
14943
|
+
const isHorizontalDropRef = useRef12(false);
|
|
14944
|
+
const horizontalDropPositionRef = useRef12(null);
|
|
14945
|
+
const isSplitSectionDropRef = useRef12(false);
|
|
14946
|
+
const splitSectionAtElementRef = useRef12(null);
|
|
14947
|
+
const templateCacheRef = useRef12(null);
|
|
14948
|
+
const parentSectionCacheRef = useRef12(/* @__PURE__ */ new Map());
|
|
14949
|
+
const sectionElementCacheRef = useRef12(/* @__PURE__ */ new Map());
|
|
14950
|
+
const sectionRectCacheRef = useRef12(/* @__PURE__ */ new Map());
|
|
14951
|
+
const companyFooterCacheRef = useRef12(void 0);
|
|
14952
|
+
const lastSyncedTemplateRef = useRef12(null);
|
|
14953
|
+
const prevTextEditingIdxRef = useRef12(null);
|
|
14954
|
+
const lastRenderSyncNeededRef = useRef12(0);
|
|
14955
|
+
const hasNotifiedLoadedRef = useRef12(false);
|
|
14956
|
+
const imageReplaceTargetRef = useRef12(null);
|
|
14957
|
+
const imagePreviewOriginalSrcRef = useRef12(null);
|
|
14958
|
+
useEffect16(() => {
|
|
14349
14959
|
const currentIdx = textEditing?.idx ?? null;
|
|
14350
14960
|
const prevIdx = prevTextEditingIdxRef.current;
|
|
14351
14961
|
const switchedTarget = currentIdx !== null && prevIdx !== null && currentIdx !== prevIdx;
|
|
@@ -14360,16 +14970,15 @@ function Editor({ setEditorLoading }) {
|
|
|
14360
14970
|
}
|
|
14361
14971
|
if (!isEqual(template, renderData)) {
|
|
14362
14972
|
setRenderData(cloneDeep2(template));
|
|
14973
|
+
if (!hasNotifiedLoadedRef.current && setEditorLoading) {
|
|
14974
|
+
hasNotifiedLoadedRef.current = true;
|
|
14975
|
+
setEditorLoading(false);
|
|
14976
|
+
}
|
|
14363
14977
|
}
|
|
14364
14978
|
lastSyncedTemplateRef.current = template;
|
|
14365
14979
|
}
|
|
14366
|
-
}, [template, renderData, isEditing, textEditing, renderSyncNeeded]);
|
|
14367
|
-
|
|
14368
|
-
if (renderData && setEditorLoading) {
|
|
14369
|
-
setEditorLoading(false);
|
|
14370
|
-
}
|
|
14371
|
-
}, [renderData, setEditorLoading]);
|
|
14372
|
-
useEffect20(() => {
|
|
14980
|
+
}, [template, renderData, isEditing, textEditing, renderSyncNeeded, setEditorLoading]);
|
|
14981
|
+
useEffect16(() => {
|
|
14373
14982
|
if (!pendingTextEditRequest || !shadowRootRef.current) return;
|
|
14374
14983
|
const { idx, cursorPosition } = pendingTextEditRequest;
|
|
14375
14984
|
const blockNode = shadowRootRef.current.querySelector(`.node-idx-${CSS.escape(idx)}`);
|
|
@@ -14418,7 +15027,7 @@ function Editor({ setEditorLoading }) {
|
|
|
14418
15027
|
startTextEditing({ idx, getReferenceRect: getReferenceRect2, getShadowElement, initialWidth: blockRect.width, initialHeight: blockRect.height, clickX, clickY, content, styles, cursorPosition });
|
|
14419
15028
|
clearPendingTextEditRequest();
|
|
14420
15029
|
}, [pendingTextEditRequest, clearPendingTextEditRequest, startTextEditing]);
|
|
14421
|
-
|
|
15030
|
+
useEffect16(() => {
|
|
14422
15031
|
if (isDragging && dataTransfer) {
|
|
14423
15032
|
const currentTemplate = useEditorStore.getState().template;
|
|
14424
15033
|
templateCacheRef.current = currentTemplate;
|
|
@@ -14434,9 +15043,9 @@ function Editor({ setEditorLoading }) {
|
|
|
14434
15043
|
sectionRectCacheRef.current.clear();
|
|
14435
15044
|
}
|
|
14436
15045
|
}, [isDragging, dataTransfer]);
|
|
14437
|
-
const [html, setHtml] =
|
|
14438
|
-
const lastRenderDataRef =
|
|
14439
|
-
|
|
15046
|
+
const [html, setHtml] = useState17("");
|
|
15047
|
+
const lastRenderDataRef = useRef12("");
|
|
15048
|
+
useEffect16(() => {
|
|
14440
15049
|
if (typeof window === "undefined" || !renderData) {
|
|
14441
15050
|
setHtml("");
|
|
14442
15051
|
lastRenderDataRef.current = "";
|
|
@@ -14463,13 +15072,13 @@ function Editor({ setEditorLoading }) {
|
|
|
14463
15072
|
};
|
|
14464
15073
|
convertMjml();
|
|
14465
15074
|
}, [renderData]);
|
|
14466
|
-
const debouncedUpdateContent =
|
|
15075
|
+
const debouncedUpdateContent = useMemo18(
|
|
14467
15076
|
() => debounce((contentIdx, content) => {
|
|
14468
15077
|
updateElementContent(contentIdx, content);
|
|
14469
15078
|
}, 200),
|
|
14470
15079
|
[updateElementContent]
|
|
14471
15080
|
);
|
|
14472
|
-
const handleElementClick =
|
|
15081
|
+
const handleElementClick = useCallback20(
|
|
14473
15082
|
(idx) => {
|
|
14474
15083
|
if (isInsideCompanyFooter(idx, template)) {
|
|
14475
15084
|
return;
|
|
@@ -14482,7 +15091,7 @@ function Editor({ setEditorLoading }) {
|
|
|
14482
15091
|
},
|
|
14483
15092
|
[setFocusIdx, template]
|
|
14484
15093
|
);
|
|
14485
|
-
const handleElementHover =
|
|
15094
|
+
const handleElementHover = useCallback20(
|
|
14486
15095
|
(idx) => {
|
|
14487
15096
|
if (!isDragging) {
|
|
14488
15097
|
if (idx) {
|
|
@@ -14496,19 +15105,19 @@ function Editor({ setEditorLoading }) {
|
|
|
14496
15105
|
},
|
|
14497
15106
|
[isDragging, setHoverIdx, template]
|
|
14498
15107
|
);
|
|
14499
|
-
const handleContentInput =
|
|
15108
|
+
const handleContentInput = useCallback20(
|
|
14500
15109
|
(contentIdx, content) => {
|
|
14501
15110
|
debouncedUpdateContent(contentIdx, content);
|
|
14502
15111
|
},
|
|
14503
15112
|
[debouncedUpdateContent]
|
|
14504
15113
|
);
|
|
14505
|
-
const handleEditingStart =
|
|
15114
|
+
const handleEditingStart = useCallback20(() => {
|
|
14506
15115
|
setIsEditing(true);
|
|
14507
15116
|
}, []);
|
|
14508
|
-
const handleEditingEnd =
|
|
15117
|
+
const handleEditingEnd = useCallback20(() => {
|
|
14509
15118
|
setIsEditing(false);
|
|
14510
15119
|
}, []);
|
|
14511
|
-
const handleSlashCommand =
|
|
15120
|
+
const handleSlashCommand = useCallback20(
|
|
14512
15121
|
(cursorRect) => {
|
|
14513
15122
|
setSlashCommand({
|
|
14514
15123
|
isActive: true,
|
|
@@ -14523,10 +15132,10 @@ function Editor({ setEditorLoading }) {
|
|
|
14523
15132
|
},
|
|
14524
15133
|
[setSlashCommand]
|
|
14525
15134
|
);
|
|
14526
|
-
const handleSlashCommandClose =
|
|
15135
|
+
const handleSlashCommandClose = useCallback20(() => {
|
|
14527
15136
|
clearSlashCommand();
|
|
14528
15137
|
}, [clearSlashCommand]);
|
|
14529
|
-
const handleTextEditStart =
|
|
15138
|
+
const handleTextEditStart = useCallback20(
|
|
14530
15139
|
(idx, initialWidth, initialHeight, clickX, clickY, content, styles) => {
|
|
14531
15140
|
const getReferenceRect2 = () => {
|
|
14532
15141
|
if (!shadowRootRef.current) return null;
|
|
@@ -14541,11 +15150,11 @@ function Editor({ setEditorLoading }) {
|
|
|
14541
15150
|
},
|
|
14542
15151
|
[startTextEditing]
|
|
14543
15152
|
);
|
|
14544
|
-
const findParentSectionIdx =
|
|
15153
|
+
const findParentSectionIdx = useCallback20((idx) => {
|
|
14545
15154
|
const match = /^(content\.children\.\[\d+\])/.exec(idx);
|
|
14546
15155
|
return match ? match[1] : null;
|
|
14547
15156
|
}, []);
|
|
14548
|
-
const handleDragOver =
|
|
15157
|
+
const handleDragOver = useCallback20(
|
|
14549
15158
|
(_e, dragInfo) => {
|
|
14550
15159
|
const currentDataTransfer = useEditorStore.getState().dataTransfer;
|
|
14551
15160
|
if (!currentDataTransfer) return;
|
|
@@ -14554,6 +15163,11 @@ function Editor({ setEditorLoading }) {
|
|
|
14554
15163
|
setDropIndicator(null);
|
|
14555
15164
|
setDropTargetIdx(null);
|
|
14556
15165
|
splitAtParagraphRef.current = null;
|
|
15166
|
+
if (imageReplaceTargetRef.current && shadowRootRef.current && imagePreviewOriginalSrcRef.current !== null) {
|
|
15167
|
+
restoreImagePreview(shadowRootRef.current, imageReplaceTargetRef.current, imagePreviewOriginalSrcRef.current);
|
|
15168
|
+
}
|
|
15169
|
+
imageReplaceTargetRef.current = null;
|
|
15170
|
+
imagePreviewOriginalSrcRef.current = null;
|
|
14557
15171
|
return;
|
|
14558
15172
|
}
|
|
14559
15173
|
const template2 = templateCacheRef.current || useEditorStore.getState().template;
|
|
@@ -14585,21 +15199,64 @@ function Editor({ setEditorLoading }) {
|
|
|
14585
15199
|
}
|
|
14586
15200
|
}
|
|
14587
15201
|
if (hoveredType === "column" || hoveredType === "property-card" || hoveredType === "property-card-single-two" || hoveredType === "property-card-triple") {
|
|
14588
|
-
const
|
|
14589
|
-
if (
|
|
14590
|
-
const
|
|
14591
|
-
if (
|
|
14592
|
-
const
|
|
14593
|
-
if (
|
|
14594
|
-
|
|
14595
|
-
|
|
14596
|
-
|
|
14597
|
-
|
|
15202
|
+
const isImageReplaceDrop = currentDataTransfer.type === "image" && currentDataTransfer.payload?.attributes?.src && (hoveredType === "property-card" || hoveredType === "property-card-single-two");
|
|
15203
|
+
if (!isImageReplaceDrop) {
|
|
15204
|
+
const columnIdx = hoveredType === "column" ? idx : getParentIdx(idx);
|
|
15205
|
+
if (columnIdx) {
|
|
15206
|
+
const columnParentIdx = getParentIdx(columnIdx);
|
|
15207
|
+
if (columnParentIdx) {
|
|
15208
|
+
const columnParent = getValueByIdx(template2, columnParentIdx);
|
|
15209
|
+
if (columnParent?.type === "section-property-km" || columnParent?.type === "section-property-single-two" || columnParent?.type === "section-property-triple") {
|
|
15210
|
+
setDropIndicator(null);
|
|
15211
|
+
setDropTargetIdx(null);
|
|
15212
|
+
splitAtParagraphRef.current = null;
|
|
15213
|
+
return;
|
|
15214
|
+
}
|
|
14598
15215
|
}
|
|
14599
15216
|
}
|
|
14600
15217
|
}
|
|
14601
15218
|
}
|
|
14602
15219
|
const dragType = currentDataTransfer.type;
|
|
15220
|
+
const hasImagePayload = currentDataTransfer.payload?.attributes?.src;
|
|
15221
|
+
const PROPERTY_CARD_IMAGE_TYPES = ["property-card", "property-card-single-two", "property-card-triple-item"];
|
|
15222
|
+
const isImageReplaceTarget = hoveredType === "image" || PROPERTY_CARD_IMAGE_TYPES.includes(hoveredType);
|
|
15223
|
+
if (dragType === "image" && hasImagePayload && isImageReplaceTarget) {
|
|
15224
|
+
const newSrc = currentDataTransfer.payload.attributes.src;
|
|
15225
|
+
const prevTarget = imageReplaceTargetRef.current;
|
|
15226
|
+
if (prevTarget !== idx) {
|
|
15227
|
+
if (prevTarget && imagePreviewOriginalSrcRef.current !== null && shadowRootRef.current) {
|
|
15228
|
+
restoreImagePreview(shadowRootRef.current, prevTarget, imagePreviewOriginalSrcRef.current);
|
|
15229
|
+
}
|
|
15230
|
+
if (shadowRootRef.current) {
|
|
15231
|
+
const targetEl = shadowRootRef.current.querySelector(`.node-idx-${CSS.escape(idx)}`);
|
|
15232
|
+
if (targetEl) {
|
|
15233
|
+
const img = targetEl.querySelector("img");
|
|
15234
|
+
if (img && hoveredType === "image") {
|
|
15235
|
+
imagePreviewOriginalSrcRef.current = img.src;
|
|
15236
|
+
img.src = newSrc;
|
|
15237
|
+
} else {
|
|
15238
|
+
const bgEl = targetEl.querySelector("td[background], th[background]");
|
|
15239
|
+
if (bgEl) {
|
|
15240
|
+
imagePreviewOriginalSrcRef.current = bgEl.getAttribute("background") || "";
|
|
15241
|
+
bgEl.setAttribute("background", newSrc);
|
|
15242
|
+
bgEl.style.backgroundImage = `url(${newSrc})`;
|
|
15243
|
+
}
|
|
15244
|
+
}
|
|
15245
|
+
}
|
|
15246
|
+
}
|
|
15247
|
+
imageReplaceTargetRef.current = idx;
|
|
15248
|
+
}
|
|
15249
|
+
setDropIndicator(null);
|
|
15250
|
+
setDropTargetIdx(idx);
|
|
15251
|
+
return;
|
|
15252
|
+
}
|
|
15253
|
+
if (imageReplaceTargetRef.current) {
|
|
15254
|
+
if (shadowRootRef.current && imagePreviewOriginalSrcRef.current !== null) {
|
|
15255
|
+
restoreImagePreview(shadowRootRef.current, imageReplaceTargetRef.current, imagePreviewOriginalSrcRef.current);
|
|
15256
|
+
}
|
|
15257
|
+
imageReplaceTargetRef.current = null;
|
|
15258
|
+
imagePreviewOriginalSrcRef.current = null;
|
|
15259
|
+
}
|
|
14603
15260
|
const validParents = VALID_PARENT_TYPES[dragType] || [];
|
|
14604
15261
|
let parentIdx;
|
|
14605
15262
|
let positionIndex;
|
|
@@ -14956,10 +15613,51 @@ function Editor({ setEditorLoading }) {
|
|
|
14956
15613
|
[findParentSectionIdx]
|
|
14957
15614
|
// Only dependency is the helper function
|
|
14958
15615
|
);
|
|
14959
|
-
const handleDrop =
|
|
15616
|
+
const handleDrop = useCallback20(
|
|
14960
15617
|
(_e, _dragInfo) => {
|
|
14961
15618
|
const currentDataTransfer = useEditorStore.getState().dataTransfer;
|
|
14962
15619
|
if (!currentDataTransfer) return;
|
|
15620
|
+
if (imageReplaceTargetRef.current && currentDataTransfer.payload?.attributes?.src) {
|
|
15621
|
+
const targetIdx = imageReplaceTargetRef.current;
|
|
15622
|
+
const newSrc = currentDataTransfer.payload.attributes.src;
|
|
15623
|
+
const template2 = useEditorStore.getState().template;
|
|
15624
|
+
const PROPERTY_CARD_IMAGE_TYPES = ["property-card", "property-card-single-two", "property-card-triple-item"];
|
|
15625
|
+
if (template2) {
|
|
15626
|
+
const targetElement = getValueByIdx(template2, targetIdx);
|
|
15627
|
+
if (targetElement?.type === "image") {
|
|
15628
|
+
useEditorStore.getState().updateElement(targetIdx, {
|
|
15629
|
+
attributes: { ...targetElement.attributes, src: newSrc }
|
|
15630
|
+
});
|
|
15631
|
+
useEditorStore.getState().setFocusIdx(targetIdx);
|
|
15632
|
+
} else if (targetElement && PROPERTY_CARD_IMAGE_TYPES.includes(targetElement.type)) {
|
|
15633
|
+
useEditorStore.getState().updateElement(targetIdx, {
|
|
15634
|
+
attributes: { ...targetElement.attributes, "image-src": newSrc }
|
|
15635
|
+
});
|
|
15636
|
+
useEditorStore.getState().setFocusIdx(targetIdx);
|
|
15637
|
+
}
|
|
15638
|
+
}
|
|
15639
|
+
setDropIndicator(null);
|
|
15640
|
+
setDropTargetIdx(null);
|
|
15641
|
+
setIsDragging(false);
|
|
15642
|
+
setIsDragButtonHovered(false);
|
|
15643
|
+
setDataTransfer(null);
|
|
15644
|
+
setHoverIdx(null);
|
|
15645
|
+
dragParentIdxRef.current = null;
|
|
15646
|
+
dragPositionIndexRef.current = 0;
|
|
15647
|
+
createNewSectionRef.current = false;
|
|
15648
|
+
splitAtParagraphRef.current = null;
|
|
15649
|
+
isHorizontalDropRef.current = false;
|
|
15650
|
+
horizontalDropPositionRef.current = null;
|
|
15651
|
+
isSplitSectionDropRef.current = false;
|
|
15652
|
+
splitSectionAtElementRef.current = null;
|
|
15653
|
+
imageReplaceTargetRef.current = null;
|
|
15654
|
+
imagePreviewOriginalSrcRef.current = null;
|
|
15655
|
+
templateCacheRef.current = null;
|
|
15656
|
+
parentSectionCacheRef.current.clear();
|
|
15657
|
+
sectionElementCacheRef.current.clear();
|
|
15658
|
+
sectionRectCacheRef.current.clear();
|
|
15659
|
+
return;
|
|
15660
|
+
}
|
|
14963
15661
|
if (isHorizontalDropRef.current && horizontalDropPositionRef.current) {
|
|
14964
15662
|
const parentIdx2 = dragParentIdxRef.current;
|
|
14965
15663
|
const dropPosition = horizontalDropPositionRef.current;
|
|
@@ -14980,6 +15678,8 @@ function Editor({ setEditorLoading }) {
|
|
|
14980
15678
|
horizontalDropPositionRef.current = null;
|
|
14981
15679
|
isSplitSectionDropRef.current = false;
|
|
14982
15680
|
splitSectionAtElementRef.current = null;
|
|
15681
|
+
imageReplaceTargetRef.current = null;
|
|
15682
|
+
imagePreviewOriginalSrcRef.current = null;
|
|
14983
15683
|
templateCacheRef.current = null;
|
|
14984
15684
|
parentSectionCacheRef.current.clear();
|
|
14985
15685
|
sectionElementCacheRef.current.clear();
|
|
@@ -15040,6 +15740,8 @@ function Editor({ setEditorLoading }) {
|
|
|
15040
15740
|
splitAtParagraphRef.current = null;
|
|
15041
15741
|
isSplitSectionDropRef.current = false;
|
|
15042
15742
|
splitSectionAtElementRef.current = null;
|
|
15743
|
+
imageReplaceTargetRef.current = null;
|
|
15744
|
+
imagePreviewOriginalSrcRef.current = null;
|
|
15043
15745
|
templateCacheRef.current = null;
|
|
15044
15746
|
parentSectionCacheRef.current.clear();
|
|
15045
15747
|
sectionElementCacheRef.current.clear();
|
|
@@ -15095,7 +15797,7 @@ function Editor({ setEditorLoading }) {
|
|
|
15095
15797
|
},
|
|
15096
15798
|
[addElement, addElementInNewSection, moveElement, moveElementToNewSection, splitTextAndInsertElement, splitSectionAndInsertElement, setIsDragging, setIsDragButtonHovered, setDataTransfer, setHoverIdx]
|
|
15097
15799
|
);
|
|
15098
|
-
const handleDragLeave =
|
|
15800
|
+
const handleDragLeave = useCallback20(() => {
|
|
15099
15801
|
setDropIndicator(null);
|
|
15100
15802
|
setDropTargetIdx(null);
|
|
15101
15803
|
dragParentIdxRef.current = null;
|
|
@@ -15106,18 +15808,23 @@ function Editor({ setEditorLoading }) {
|
|
|
15106
15808
|
horizontalDropPositionRef.current = null;
|
|
15107
15809
|
isSplitSectionDropRef.current = false;
|
|
15108
15810
|
splitSectionAtElementRef.current = null;
|
|
15811
|
+
if (imageReplaceTargetRef.current && shadowRootRef.current && imagePreviewOriginalSrcRef.current !== null) {
|
|
15812
|
+
restoreImagePreview(shadowRootRef.current, imageReplaceTargetRef.current, imagePreviewOriginalSrcRef.current);
|
|
15813
|
+
}
|
|
15814
|
+
imageReplaceTargetRef.current = null;
|
|
15815
|
+
imagePreviewOriginalSrcRef.current = null;
|
|
15109
15816
|
templateCacheRef.current = null;
|
|
15110
15817
|
parentSectionCacheRef.current.clear();
|
|
15111
15818
|
sectionElementCacheRef.current.clear();
|
|
15112
15819
|
sectionRectCacheRef.current.clear();
|
|
15113
15820
|
}, []);
|
|
15114
|
-
const handleShadowRootRef =
|
|
15821
|
+
const handleShadowRootRef = useCallback20((shadowRoot) => {
|
|
15115
15822
|
shadowRootRef.current = shadowRoot;
|
|
15116
15823
|
}, []);
|
|
15117
|
-
const handleSelectionRectChange =
|
|
15824
|
+
const handleSelectionRectChange = useCallback20((rect) => {
|
|
15118
15825
|
setHasSelectedElement(rect !== null);
|
|
15119
15826
|
}, []);
|
|
15120
|
-
const getReferenceRect =
|
|
15827
|
+
const getReferenceRect = useCallback20(() => {
|
|
15121
15828
|
if (!shadowRootRef.current || !focusIdx) return null;
|
|
15122
15829
|
const selectedEl = shadowRootRef.current.querySelector(
|
|
15123
15830
|
`.node-idx-${CSS.escape(focusIdx)}`
|
|
@@ -15145,14 +15852,14 @@ function Editor({ setEditorLoading }) {
|
|
|
15145
15852
|
}, [focusIdx]);
|
|
15146
15853
|
const selectedElement = focusIdx && renderData ? getValueByIdx(renderData, focusIdx) : null;
|
|
15147
15854
|
const canDragSelectedElement = selectedElement && selectedElement.type !== "column" && !(focusIdx && renderData && isInsideCompanyFooter(focusIdx, renderData));
|
|
15148
|
-
const showCompanyFooter =
|
|
15855
|
+
const showCompanyFooter = useMemo18(
|
|
15149
15856
|
() => template.content[0]?.data?.value?.showCompanyFooter ?? true,
|
|
15150
15857
|
[template.content[0]?.data?.value?.showCompanyFooter]
|
|
15151
15858
|
);
|
|
15152
15859
|
if (!html) {
|
|
15153
|
-
return /* @__PURE__ */
|
|
15860
|
+
return /* @__PURE__ */ jsx51("div", { className: "maillow-editor flex items-center justify-center h-[500px]", children: /* @__PURE__ */ jsx51(Spinner, {}) });
|
|
15154
15861
|
}
|
|
15155
|
-
return /* @__PURE__ */
|
|
15862
|
+
return /* @__PURE__ */ jsxs32(
|
|
15156
15863
|
"div",
|
|
15157
15864
|
{
|
|
15158
15865
|
className: "maillow-editor relative ",
|
|
@@ -15163,7 +15870,7 @@ function Editor({ setEditorLoading }) {
|
|
|
15163
15870
|
justifyContent: "center"
|
|
15164
15871
|
},
|
|
15165
15872
|
children: [
|
|
15166
|
-
/* @__PURE__ */
|
|
15873
|
+
/* @__PURE__ */ jsxs32(
|
|
15167
15874
|
"div",
|
|
15168
15875
|
{
|
|
15169
15876
|
className: `editor-container rounded-b-[12px] max-w-[626px] w-[626px] [@media(max-width:950px)]:max-w-[100%] [@media(max-width:950px)]:w-[100%] `,
|
|
@@ -15173,8 +15880,8 @@ function Editor({ setEditorLoading }) {
|
|
|
15173
15880
|
overflow: "auto"
|
|
15174
15881
|
},
|
|
15175
15882
|
children: [
|
|
15176
|
-
/* @__PURE__ */
|
|
15177
|
-
/* @__PURE__ */
|
|
15883
|
+
/* @__PURE__ */ jsx51("div", { className: "w-full h-[2px] bg-black opacity-10" }),
|
|
15884
|
+
/* @__PURE__ */ jsx51(
|
|
15178
15885
|
ShadowDomRenderer,
|
|
15179
15886
|
{
|
|
15180
15887
|
html,
|
|
@@ -15204,9 +15911,10 @@ function Editor({ setEditorLoading }) {
|
|
|
15204
15911
|
]
|
|
15205
15912
|
}
|
|
15206
15913
|
),
|
|
15207
|
-
/* @__PURE__ */
|
|
15208
|
-
/* @__PURE__ */
|
|
15209
|
-
|
|
15914
|
+
/* @__PURE__ */ jsx51(ElementsSuggestions, {}),
|
|
15915
|
+
/* @__PURE__ */ jsx51(MergeFieldSuggestions, {}),
|
|
15916
|
+
/* @__PURE__ */ jsx51(TiptapOverlay, {}),
|
|
15917
|
+
!isDragging && !isScaling && hasSelectedElement && focusIdx && selectedElement?.type && /* @__PURE__ */ jsx51(
|
|
15210
15918
|
ElementFloat,
|
|
15211
15919
|
{
|
|
15212
15920
|
getReferenceRect,
|
|
@@ -15214,7 +15922,7 @@ function Editor({ setEditorLoading }) {
|
|
|
15214
15922
|
elementType: selectedElement.type
|
|
15215
15923
|
}
|
|
15216
15924
|
),
|
|
15217
|
-
!isScaling && hasSelectedElement && focusIdx && canDragSelectedElement && !NOT_DRAGGABLE_ELEMENTS.includes(selectedElement.type) && /* @__PURE__ */
|
|
15925
|
+
!isScaling && hasSelectedElement && focusIdx && canDragSelectedElement && !NOT_DRAGGABLE_ELEMENTS.includes(selectedElement.type) && /* @__PURE__ */ jsx51(
|
|
15218
15926
|
DragButton,
|
|
15219
15927
|
{
|
|
15220
15928
|
getReferenceRect,
|
|
@@ -15223,17 +15931,17 @@ function Editor({ setEditorLoading }) {
|
|
|
15223
15931
|
isDragging
|
|
15224
15932
|
}
|
|
15225
15933
|
),
|
|
15226
|
-
!isDragging && hasSelectedElement && focusIdx && selectedElement?.type === "divider" && /* @__PURE__ */
|
|
15227
|
-
!isDragging && hasSelectedElement && focusIdx && selectedElement?.type === "button" && /* @__PURE__ */
|
|
15228
|
-
!isDragging && hasSelectedElement && focusIdx && selectedElement?.type === "image" && /* @__PURE__ */
|
|
15229
|
-
!isDragging && hasSelectedElement && focusIdx && selectedElement?.type === "space" && /* @__PURE__ */
|
|
15934
|
+
!isDragging && hasSelectedElement && focusIdx && selectedElement?.type === "divider" && /* @__PURE__ */ jsx51(DividerScale, { getReferenceRect }),
|
|
15935
|
+
!isDragging && hasSelectedElement && focusIdx && selectedElement?.type === "button" && /* @__PURE__ */ jsx51(ButtonScale, { getReferenceRect }),
|
|
15936
|
+
!isDragging && hasSelectedElement && focusIdx && selectedElement?.type === "image" && /* @__PURE__ */ jsx51(ImageScale, { getReferenceRect }),
|
|
15937
|
+
!isDragging && hasSelectedElement && focusIdx && selectedElement?.type === "space" && /* @__PURE__ */ jsx51(SpacerScale, { getReferenceRect }),
|
|
15230
15938
|
!isDragging && hasSelectedElement && focusIdx && renderData && (() => {
|
|
15231
15939
|
const sectionColumnIdx = getSectionColumnIdx(focusIdx, renderData);
|
|
15232
15940
|
if (!sectionColumnIdx) return null;
|
|
15233
15941
|
const sectionColumn = getValueByIdx(renderData, sectionColumnIdx);
|
|
15234
15942
|
if (!sectionColumn || sectionColumn.type !== "section-column") return null;
|
|
15235
15943
|
if (!sectionColumn.children || sectionColumn.children.length < 2) return null;
|
|
15236
|
-
return /* @__PURE__ */
|
|
15944
|
+
return /* @__PURE__ */ jsx51(
|
|
15237
15945
|
ColumnScale,
|
|
15238
15946
|
{
|
|
15239
15947
|
sectionColumnIdx,
|
|
@@ -15255,9 +15963,7 @@ export {
|
|
|
15255
15963
|
parseBorder,
|
|
15256
15964
|
formatBorder,
|
|
15257
15965
|
parsePrice,
|
|
15258
|
-
json2mjml,
|
|
15259
15966
|
MAX_TEMPLATE_SIZE,
|
|
15260
|
-
useEditorStore,
|
|
15261
15967
|
BUTTON_ALIGNMENTS,
|
|
15262
15968
|
ALIGNMENT_ICONS,
|
|
15263
15969
|
FONTS,
|
|
@@ -15275,6 +15981,9 @@ export {
|
|
|
15275
15981
|
MIN_LINE_HEIGHT,
|
|
15276
15982
|
MAX_LINE_HEIGHT,
|
|
15277
15983
|
LINE_HEIGHT_STEP,
|
|
15984
|
+
DEFAULT_PROPERTY_PLACEHOLDER_IMAGE,
|
|
15985
|
+
json2mjml,
|
|
15986
|
+
useEditorStore,
|
|
15278
15987
|
setupDragImage,
|
|
15279
15988
|
getElementDisplayName,
|
|
15280
15989
|
cn,
|