@kgalexander/mcreate 0.0.15 → 0.0.16
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-L3OWFBEU.mjs} +1474 -770
- package/dist/{core-66YYN7ME.mjs → core-AMEHYBIM.mjs} +1 -1
- package/dist/index.d.mts +11 -2
- package/dist/index.d.ts +11 -2
- package/dist/index.js +5662 -2987
- package/dist/index.mjs +3904 -2000
- 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 useEffect21, useCallback as useCallback18, 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: 4px;
|
|
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
|
|
10800
|
+
import { useFloating as useFloating4, autoUpdate as autoUpdate2, offset as offset4 } from "@floating-ui/react";
|
|
10801
|
+
import { useEffect as useEffect7, 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, useEffect as
|
|
11203
|
+
import { useState as useState2, useEffect as useEffect6 } 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,16 +11306,16 @@ 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
|
-
|
|
11318
|
+
useEffect6(() => {
|
|
11046
11319
|
if (isOpen) {
|
|
11047
11320
|
setLinkType(detectLinkType(currentHref));
|
|
11048
11321
|
setInputValue(stripPrefix(currentHref));
|
|
@@ -11084,42 +11357,42 @@ var TextLinkMenu = ({ editor }) => {
|
|
|
11084
11357
|
editor.chain().focus().unsetLink().run();
|
|
11085
11358
|
setInputValue("");
|
|
11086
11359
|
};
|
|
11087
|
-
return /* @__PURE__ */
|
|
11088
|
-
/* @__PURE__ */
|
|
11089
|
-
/* @__PURE__ */
|
|
11360
|
+
return /* @__PURE__ */ jsxs7(Popover, { open: isOpen, onOpenChange: setIsOpen, children: [
|
|
11361
|
+
/* @__PURE__ */ jsxs7(Tooltip, { children: [
|
|
11362
|
+
/* @__PURE__ */ jsx20(TooltipTrigger, { asChild: true, children: /* @__PURE__ */ jsx20(PopoverTrigger, { asChild: true, children: hasLink ? /* @__PURE__ */ jsx20(
|
|
11090
11363
|
Button,
|
|
11091
11364
|
{
|
|
11092
11365
|
variant: "ghost",
|
|
11093
11366
|
size: "icon",
|
|
11094
11367
|
className: floatButtonVariants,
|
|
11095
11368
|
onMouseDown: (e) => e.preventDefault(),
|
|
11096
|
-
children: /* @__PURE__ */
|
|
11369
|
+
children: /* @__PURE__ */ jsx20(PencilIcon, { className: "size-4" })
|
|
11097
11370
|
}
|
|
11098
|
-
) : /* @__PURE__ */
|
|
11371
|
+
) : /* @__PURE__ */ jsxs7(
|
|
11099
11372
|
Button,
|
|
11100
11373
|
{
|
|
11101
11374
|
variant: "ghost",
|
|
11102
11375
|
className: "shadow-none transition-none cursor-pointer rounded-full outline-none h-[34px]",
|
|
11103
11376
|
onMouseDown: (e) => e.preventDefault(),
|
|
11104
11377
|
children: [
|
|
11105
|
-
/* @__PURE__ */
|
|
11106
|
-
/* @__PURE__ */
|
|
11378
|
+
/* @__PURE__ */ jsx20(LinkIcon2, { className: "size-4" }),
|
|
11379
|
+
/* @__PURE__ */ jsx20("p", { children: "Add link" })
|
|
11107
11380
|
]
|
|
11108
11381
|
}
|
|
11109
11382
|
) }) }),
|
|
11110
|
-
/* @__PURE__ */
|
|
11383
|
+
/* @__PURE__ */ jsx20(TooltipContent, { side: "bottom", children: hasLink ? "Edit link" : "Add link" })
|
|
11111
11384
|
] }),
|
|
11112
|
-
/* @__PURE__ */
|
|
11385
|
+
/* @__PURE__ */ jsxs7(
|
|
11113
11386
|
PopoverContent,
|
|
11114
11387
|
{
|
|
11115
11388
|
side: "bottom",
|
|
11116
11389
|
className: "w-[250px] p-3 shadow-lg z-50001",
|
|
11117
11390
|
"data-editor-toolbar": true,
|
|
11118
11391
|
children: [
|
|
11119
|
-
/* @__PURE__ */
|
|
11120
|
-
/* @__PURE__ */
|
|
11121
|
-
/* @__PURE__ */
|
|
11122
|
-
/* @__PURE__ */
|
|
11392
|
+
/* @__PURE__ */ jsxs7("div", { className: "flex flex-col gap-2", children: [
|
|
11393
|
+
/* @__PURE__ */ jsx20(Label, { children: "Enter a link" }),
|
|
11394
|
+
/* @__PURE__ */ jsxs7("div", { className: "relative", children: [
|
|
11395
|
+
/* @__PURE__ */ jsx20(
|
|
11123
11396
|
Input,
|
|
11124
11397
|
{
|
|
11125
11398
|
type: linkType.inputType,
|
|
@@ -11131,12 +11404,12 @@ var TextLinkMenu = ({ editor }) => {
|
|
|
11131
11404
|
autoFocus: true
|
|
11132
11405
|
}
|
|
11133
11406
|
),
|
|
11134
|
-
/* @__PURE__ */
|
|
11135
|
-
/* @__PURE__ */
|
|
11136
|
-
/* @__PURE__ */
|
|
11137
|
-
/* @__PURE__ */
|
|
11407
|
+
/* @__PURE__ */ jsxs7(Popover, { open: isLinkTypeOpen, onOpenChange: setIsLinkTypeOpen, children: [
|
|
11408
|
+
/* @__PURE__ */ jsxs7(Tooltip, { children: [
|
|
11409
|
+
/* @__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, {}) }) }) }),
|
|
11410
|
+
/* @__PURE__ */ jsx20(TooltipContent, { side: "top", className: "z-50001", children: "Link Type" })
|
|
11138
11411
|
] }),
|
|
11139
|
-
/* @__PURE__ */
|
|
11412
|
+
/* @__PURE__ */ jsx20(
|
|
11140
11413
|
PopoverContent,
|
|
11141
11414
|
{
|
|
11142
11415
|
side: "bottom",
|
|
@@ -11144,7 +11417,7 @@ var TextLinkMenu = ({ editor }) => {
|
|
|
11144
11417
|
className: "w-[160px] p-1 z-50001",
|
|
11145
11418
|
onPointerDownOutside: (e) => e.preventDefault(),
|
|
11146
11419
|
"data-editor-toolbar": true,
|
|
11147
|
-
children: LINK_TYPES.map((type) => /* @__PURE__ */
|
|
11420
|
+
children: LINK_TYPES.map((type) => /* @__PURE__ */ jsxs7(
|
|
11148
11421
|
Button,
|
|
11149
11422
|
{
|
|
11150
11423
|
variant: "ghost",
|
|
@@ -11155,11 +11428,11 @@ var TextLinkMenu = ({ editor }) => {
|
|
|
11155
11428
|
setIsLinkTypeOpen(false);
|
|
11156
11429
|
},
|
|
11157
11430
|
children: [
|
|
11158
|
-
/* @__PURE__ */
|
|
11159
|
-
/* @__PURE__ */
|
|
11431
|
+
/* @__PURE__ */ jsxs7("span", { className: "flex items-center gap-2", children: [
|
|
11432
|
+
/* @__PURE__ */ jsx20(type.icon, { className: "size-4" }),
|
|
11160
11433
|
type.name
|
|
11161
11434
|
] }),
|
|
11162
|
-
linkType.name === type.name && /* @__PURE__ */
|
|
11435
|
+
linkType.name === type.name && /* @__PURE__ */ jsx20(CheckIcon, { className: "size-4" })
|
|
11163
11436
|
]
|
|
11164
11437
|
},
|
|
11165
11438
|
type.name
|
|
@@ -11169,11 +11442,11 @@ var TextLinkMenu = ({ editor }) => {
|
|
|
11169
11442
|
] })
|
|
11170
11443
|
] })
|
|
11171
11444
|
] }),
|
|
11172
|
-
/* @__PURE__ */
|
|
11173
|
-
/* @__PURE__ */
|
|
11174
|
-
/* @__PURE__ */
|
|
11175
|
-
/* @__PURE__ */
|
|
11176
|
-
/* @__PURE__ */
|
|
11445
|
+
/* @__PURE__ */ jsx20(Separator, { className: "my-2" }),
|
|
11446
|
+
/* @__PURE__ */ jsxs7("div", { className: "flex flex-row justify-between items-center", children: [
|
|
11447
|
+
/* @__PURE__ */ jsxs7("div", { className: "flex flex-row", children: [
|
|
11448
|
+
/* @__PURE__ */ jsxs7(Tooltip, { children: [
|
|
11449
|
+
/* @__PURE__ */ jsx20(TooltipTrigger, { asChild: true, children: /* @__PURE__ */ jsx20(
|
|
11177
11450
|
Button,
|
|
11178
11451
|
{
|
|
11179
11452
|
variant: "ghost",
|
|
@@ -11181,13 +11454,13 @@ var TextLinkMenu = ({ editor }) => {
|
|
|
11181
11454
|
className: "shadow-none transition-none cursor-pointer rounded-full outline-none",
|
|
11182
11455
|
onClick: handleCopy,
|
|
11183
11456
|
disabled: !hasLink,
|
|
11184
|
-
children: showCopied ? /* @__PURE__ */
|
|
11457
|
+
children: showCopied ? /* @__PURE__ */ jsx20(CheckIcon, { className: "text-green-600" }) : /* @__PURE__ */ jsx20(CopyIcon, {})
|
|
11185
11458
|
}
|
|
11186
11459
|
) }),
|
|
11187
|
-
/* @__PURE__ */
|
|
11460
|
+
/* @__PURE__ */ jsx20(TooltipContent, { side: "bottom", className: "z-50001", children: showCopied ? "Copied!" : "Copy link" })
|
|
11188
11461
|
] }),
|
|
11189
|
-
/* @__PURE__ */
|
|
11190
|
-
/* @__PURE__ */
|
|
11462
|
+
/* @__PURE__ */ jsxs7(Tooltip, { children: [
|
|
11463
|
+
/* @__PURE__ */ jsx20(TooltipTrigger, { asChild: true, children: /* @__PURE__ */ jsx20(
|
|
11191
11464
|
Button,
|
|
11192
11465
|
{
|
|
11193
11466
|
variant: "ghost",
|
|
@@ -11195,13 +11468,13 @@ var TextLinkMenu = ({ editor }) => {
|
|
|
11195
11468
|
className: "shadow-none transition-none cursor-pointer rounded-full outline-none",
|
|
11196
11469
|
onClick: handleRemoveLink,
|
|
11197
11470
|
disabled: !hasLink,
|
|
11198
|
-
children: /* @__PURE__ */
|
|
11471
|
+
children: /* @__PURE__ */ jsx20(TrashIcon, {})
|
|
11199
11472
|
}
|
|
11200
11473
|
) }),
|
|
11201
|
-
/* @__PURE__ */
|
|
11474
|
+
/* @__PURE__ */ jsx20(TooltipContent, { side: "bottom", className: "z-50001", children: "Remove link" })
|
|
11202
11475
|
] })
|
|
11203
11476
|
] }),
|
|
11204
|
-
/* @__PURE__ */
|
|
11477
|
+
/* @__PURE__ */ jsx20("div", { children: /* @__PURE__ */ jsx20(
|
|
11205
11478
|
Button,
|
|
11206
11479
|
{
|
|
11207
11480
|
variant: "default",
|
|
@@ -11218,16 +11491,16 @@ var TextLinkMenu = ({ editor }) => {
|
|
|
11218
11491
|
};
|
|
11219
11492
|
|
|
11220
11493
|
// src/core/editor/components/float-link-preview.tsx
|
|
11221
|
-
import { jsx as
|
|
11494
|
+
import { jsx as jsx21, jsxs as jsxs8 } from "react/jsx-runtime";
|
|
11222
11495
|
var FloatLinkPreview = ({ href }) => {
|
|
11223
|
-
return /* @__PURE__ */
|
|
11224
|
-
/* @__PURE__ */
|
|
11225
|
-
/* @__PURE__ */
|
|
11496
|
+
return /* @__PURE__ */ jsxs8(Tooltip, { children: [
|
|
11497
|
+
/* @__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 }) }) }),
|
|
11498
|
+
/* @__PURE__ */ jsx21(TooltipContent, { side: "bottom", children: href })
|
|
11226
11499
|
] });
|
|
11227
11500
|
};
|
|
11228
11501
|
|
|
11229
11502
|
// src/core/editor/components/tiptap-overlay.tsx
|
|
11230
|
-
import { jsx as
|
|
11503
|
+
import { jsx as jsx22, jsxs as jsxs9 } from "react/jsx-runtime";
|
|
11231
11504
|
var FontFamily = Extension.create({
|
|
11232
11505
|
name: "fontFamily",
|
|
11233
11506
|
addGlobalAttributes() {
|
|
@@ -11405,7 +11678,8 @@ var TIPTAP_EXTENSIONS = [
|
|
|
11405
11678
|
emptyNodeClass: "is-empty-placeholder",
|
|
11406
11679
|
paragraphPlaceholder: "Start typing...",
|
|
11407
11680
|
headingPlaceholder: "Heading"
|
|
11408
|
-
})
|
|
11681
|
+
}),
|
|
11682
|
+
MergeFieldDecoration
|
|
11409
11683
|
];
|
|
11410
11684
|
function isNodeEmpty2(node) {
|
|
11411
11685
|
if (!node) return true;
|
|
@@ -11536,16 +11810,16 @@ function handleBackspaceOrDelete(view, event, currentElementIdx, storeRefs) {
|
|
|
11536
11810
|
var TiptapOverlay = () => {
|
|
11537
11811
|
const textEditing = useEditorStore((s) => s.textEditing);
|
|
11538
11812
|
if (!textEditing) return null;
|
|
11539
|
-
return /* @__PURE__ */
|
|
11813
|
+
return /* @__PURE__ */ jsx22(TiptapOverlayContent, { ...textEditing }, textEditing.idx);
|
|
11540
11814
|
};
|
|
11541
11815
|
var TiptapOverlayContent = ({ idx, getReferenceRect, getShadowElement, initialWidth, initialHeight, clickX, clickY, content, styles, cursorPosition }) => {
|
|
11542
|
-
const containerRef =
|
|
11816
|
+
const containerRef = useRef5(null);
|
|
11543
11817
|
const setTiptapEditor = useEditorStore((s) => s.setTiptapEditor);
|
|
11544
11818
|
const linkColor = useEditorStore((s) => s.template?.content?.[0]?.data?.value?.linkColor) || "#0000ff";
|
|
11545
|
-
const lastSizeLimitToastRef =
|
|
11546
|
-
const hasContentChangedRef =
|
|
11819
|
+
const lastSizeLimitToastRef = useRef5(0);
|
|
11820
|
+
const hasContentChangedRef = useRef5(false);
|
|
11547
11821
|
const storeRefs = useEditorStoreRefs();
|
|
11548
|
-
|
|
11822
|
+
useEffect7(() => {
|
|
11549
11823
|
return () => {
|
|
11550
11824
|
const isUndoRedoAction = useEditorStore.getState().isUndoRedoAction;
|
|
11551
11825
|
if (hasContentChangedRef.current && !isUndoRedoAction) {
|
|
@@ -11553,7 +11827,7 @@ var TiptapOverlayContent = ({ idx, getReferenceRect, getShadowElement, initialWi
|
|
|
11553
11827
|
}
|
|
11554
11828
|
};
|
|
11555
11829
|
}, []);
|
|
11556
|
-
|
|
11830
|
+
useEffect7(() => {
|
|
11557
11831
|
const container = containerRef.current;
|
|
11558
11832
|
if (!container) return;
|
|
11559
11833
|
const observer = new ResizeObserver(() => {
|
|
@@ -11571,10 +11845,10 @@ var TiptapOverlayContent = ({ idx, getReferenceRect, getShadowElement, initialWi
|
|
|
11571
11845
|
}
|
|
11572
11846
|
};
|
|
11573
11847
|
}, [getShadowElement]);
|
|
11574
|
-
const cleanedContent =
|
|
11848
|
+
const cleanedContent = useMemo4(() => {
|
|
11575
11849
|
return content.replace(NBSP_P_CONTENT_REGEX, "<p$1></p>").replace(IS_EMPTY_P_CLASS_REGEX, "").replace(IS_EMPTY_HEADING_CLASS_REGEX, "");
|
|
11576
11850
|
}, [content]);
|
|
11577
|
-
const lineHeightRatio =
|
|
11851
|
+
const lineHeightRatio = useMemo4(() => {
|
|
11578
11852
|
const lineHeightPx = parseFloat(styles.lineHeight);
|
|
11579
11853
|
const fontSizePx = parseFloat(styles.fontSize);
|
|
11580
11854
|
if (isNaN(lineHeightPx) || isNaN(fontSizePx) || fontSizePx === 0) {
|
|
@@ -11582,7 +11856,7 @@ var TiptapOverlayContent = ({ idx, getReferenceRect, getShadowElement, initialWi
|
|
|
11582
11856
|
}
|
|
11583
11857
|
return lineHeightPx / fontSizePx;
|
|
11584
11858
|
}, [styles.lineHeight, styles.fontSize]);
|
|
11585
|
-
const virtualReference =
|
|
11859
|
+
const virtualReference = useMemo4(() => ({
|
|
11586
11860
|
getBoundingClientRect: () => {
|
|
11587
11861
|
const rect = getReferenceRect();
|
|
11588
11862
|
if (!rect) {
|
|
@@ -11591,14 +11865,14 @@ var TiptapOverlayContent = ({ idx, getReferenceRect, getShadowElement, initialWi
|
|
|
11591
11865
|
return rect;
|
|
11592
11866
|
}
|
|
11593
11867
|
}), [getReferenceRect]);
|
|
11594
|
-
const { floatingStyles, refs, update } =
|
|
11868
|
+
const { floatingStyles, refs, update } = useFloating4({
|
|
11595
11869
|
placement: "bottom-start",
|
|
11596
11870
|
middleware: [
|
|
11597
|
-
|
|
11871
|
+
offset4(({ rects }) => -rects.reference.height)
|
|
11598
11872
|
// Move up by reference height to overlay exactly
|
|
11599
11873
|
]
|
|
11600
11874
|
});
|
|
11601
|
-
|
|
11875
|
+
useEffect7(() => {
|
|
11602
11876
|
const rect = getReferenceRect();
|
|
11603
11877
|
if (!rect || !refs.floating.current) return;
|
|
11604
11878
|
refs.setPositionReference(virtualReference);
|
|
@@ -11637,17 +11911,36 @@ var TiptapOverlayContent = ({ idx, getReferenceRect, getShadowElement, initialWi
|
|
|
11637
11911
|
}
|
|
11638
11912
|
}
|
|
11639
11913
|
const isSlashCommandActive = storeRefs.slashCommand.current?.isActive;
|
|
11640
|
-
|
|
11641
|
-
|
|
11642
|
-
|
|
11914
|
+
const isMergeFieldActive = storeRefs.mergeFieldSuggestion.current?.isActive;
|
|
11915
|
+
if (event.key === "Escape") {
|
|
11916
|
+
if (isSlashCommandActive) {
|
|
11917
|
+
storeRefs.clearSlashCommand.current();
|
|
11918
|
+
return true;
|
|
11919
|
+
}
|
|
11920
|
+
if (isMergeFieldActive) {
|
|
11921
|
+
storeRefs.clearMergeFieldSuggestion.current();
|
|
11922
|
+
return true;
|
|
11923
|
+
}
|
|
11643
11924
|
}
|
|
11644
|
-
if (event.key === " "
|
|
11645
|
-
|
|
11646
|
-
|
|
11925
|
+
if (event.key === " ") {
|
|
11926
|
+
if (isSlashCommandActive) {
|
|
11927
|
+
storeRefs.clearSlashCommand.current();
|
|
11928
|
+
return false;
|
|
11929
|
+
}
|
|
11930
|
+
if (isMergeFieldActive) {
|
|
11931
|
+
storeRefs.clearMergeFieldSuggestion.current();
|
|
11932
|
+
return false;
|
|
11933
|
+
}
|
|
11647
11934
|
}
|
|
11648
|
-
if (
|
|
11649
|
-
|
|
11650
|
-
|
|
11935
|
+
if (event.key === "ArrowLeft" || event.key === "ArrowRight" || event.key === "ArrowUp" || event.key === "ArrowDown") {
|
|
11936
|
+
if (isSlashCommandActive) {
|
|
11937
|
+
storeRefs.clearSlashCommand.current();
|
|
11938
|
+
return false;
|
|
11939
|
+
}
|
|
11940
|
+
if (isMergeFieldActive) {
|
|
11941
|
+
storeRefs.clearMergeFieldSuggestion.current();
|
|
11942
|
+
return false;
|
|
11943
|
+
}
|
|
11651
11944
|
}
|
|
11652
11945
|
if (event.key === "/") {
|
|
11653
11946
|
const { from } = view.state.selection;
|
|
@@ -11669,6 +11962,33 @@ var TiptapOverlayContent = ({ idx, getReferenceRect, getShadowElement, initialWi
|
|
|
11669
11962
|
});
|
|
11670
11963
|
}
|
|
11671
11964
|
}
|
|
11965
|
+
if (event.key === "{") {
|
|
11966
|
+
const { from } = view.state.selection;
|
|
11967
|
+
const textBefore = view.state.doc.textBetween(Math.max(0, from - 1), from);
|
|
11968
|
+
if (textBefore === "{") {
|
|
11969
|
+
const coords = view.coordsAtPos(from);
|
|
11970
|
+
if (coords && coords.left > 0 && coords.top > 0) {
|
|
11971
|
+
const lineHeight = parseInt(styles.lineHeight) || 20;
|
|
11972
|
+
storeRefs.setMergeFieldSuggestion.current({
|
|
11973
|
+
isActive: true,
|
|
11974
|
+
cursorRect: { top: coords.top, left: coords.left, height: lineHeight },
|
|
11975
|
+
triggerPosition: from - 1
|
|
11976
|
+
// Position of first "{"
|
|
11977
|
+
});
|
|
11978
|
+
}
|
|
11979
|
+
}
|
|
11980
|
+
}
|
|
11981
|
+
if (event.key === "}" && isMergeFieldActive) {
|
|
11982
|
+
storeRefs.clearMergeFieldSuggestion.current();
|
|
11983
|
+
return false;
|
|
11984
|
+
}
|
|
11985
|
+
if (event.key === "Backspace" && isMergeFieldActive) {
|
|
11986
|
+
const { from } = view.state.selection;
|
|
11987
|
+
const triggerPos = storeRefs.mergeFieldSuggestion.current?.triggerPosition ?? 0;
|
|
11988
|
+
if (from <= triggerPos + 2) {
|
|
11989
|
+
storeRefs.clearMergeFieldSuggestion.current();
|
|
11990
|
+
}
|
|
11991
|
+
}
|
|
11672
11992
|
if (event.key === "Backspace" || event.key === "Delete") {
|
|
11673
11993
|
const handled = handleBackspaceOrDelete(
|
|
11674
11994
|
view,
|
|
@@ -11735,8 +12055,8 @@ var TiptapOverlayContent = ({ idx, getReferenceRect, getShadowElement, initialWi
|
|
|
11735
12055
|
storeRefs.updateElementContent.current(`${idx}.data.value.content`, html);
|
|
11736
12056
|
}
|
|
11737
12057
|
});
|
|
11738
|
-
const [currentLinkHref, setCurrentLinkHref] =
|
|
11739
|
-
|
|
12058
|
+
const [currentLinkHref, setCurrentLinkHref] = useState3("");
|
|
12059
|
+
useEffect7(() => {
|
|
11740
12060
|
if (!editor) return;
|
|
11741
12061
|
setTiptapEditor(editor);
|
|
11742
12062
|
const updateLinkHref = () => {
|
|
@@ -11751,7 +12071,7 @@ var TiptapOverlayContent = ({ idx, getReferenceRect, getShadowElement, initialWi
|
|
|
11751
12071
|
editor.off("transaction", updateLinkHref);
|
|
11752
12072
|
};
|
|
11753
12073
|
}, [editor, setTiptapEditor]);
|
|
11754
|
-
|
|
12074
|
+
useEffect7(() => {
|
|
11755
12075
|
if (editor) {
|
|
11756
12076
|
const timer = setTimeout(() => {
|
|
11757
12077
|
if (cursorPosition === "end") {
|
|
@@ -11780,7 +12100,7 @@ var TiptapOverlayContent = ({ idx, getReferenceRect, getShadowElement, initialWi
|
|
|
11780
12100
|
return () => clearTimeout(timer);
|
|
11781
12101
|
}
|
|
11782
12102
|
}, [editor, clickX, clickY, cursorPosition]);
|
|
11783
|
-
|
|
12103
|
+
useEffect7(() => {
|
|
11784
12104
|
const handleClickOutside = (e) => {
|
|
11785
12105
|
const target = e.target;
|
|
11786
12106
|
if (containerRef.current && containerRef.current.contains(target)) {
|
|
@@ -11802,7 +12122,7 @@ var TiptapOverlayContent = ({ idx, getReferenceRect, getShadowElement, initialWi
|
|
|
11802
12122
|
document.removeEventListener("mousedown", handleClickOutside);
|
|
11803
12123
|
};
|
|
11804
12124
|
}, []);
|
|
11805
|
-
return /* @__PURE__ */
|
|
12125
|
+
return /* @__PURE__ */ jsxs9(
|
|
11806
12126
|
"div",
|
|
11807
12127
|
{
|
|
11808
12128
|
ref: (node) => {
|
|
@@ -11835,7 +12155,7 @@ var TiptapOverlayContent = ({ idx, getReferenceRect, getShadowElement, initialWi
|
|
|
11835
12155
|
boxSizing: "border-box"
|
|
11836
12156
|
},
|
|
11837
12157
|
children: [
|
|
11838
|
-
/* @__PURE__ */
|
|
12158
|
+
/* @__PURE__ */ jsx22("style", { children: `
|
|
11839
12159
|
.tiptap-overlay {
|
|
11840
12160
|
margin: 0;
|
|
11841
12161
|
padding: 0;
|
|
@@ -11901,6 +12221,16 @@ var TiptapOverlayContent = ({ idx, getReferenceRect, getShadowElement, initialWi
|
|
|
11901
12221
|
transform: translateY(-50%);
|
|
11902
12222
|
text-align: inherit;
|
|
11903
12223
|
}
|
|
12224
|
+
.tiptap-overlay .ProseMirror .merge-field-tag {
|
|
12225
|
+
background-color: var(--background);
|
|
12226
|
+
border-radius: 4px;
|
|
12227
|
+
padding: 4px;
|
|
12228
|
+
border: 1px solid var(--border);
|
|
12229
|
+
color: #000000;
|
|
12230
|
+
}
|
|
12231
|
+
.tiptap-overlay .ProseMirror .merge-field-tag:hover {
|
|
12232
|
+
cursor: pointer;
|
|
12233
|
+
}
|
|
11904
12234
|
.tiptap-overlay .ProseMirror a {
|
|
11905
12235
|
color: ${linkColor};
|
|
11906
12236
|
text-decoration: none;
|
|
@@ -11910,36 +12240,36 @@ var TiptapOverlayContent = ({ idx, getReferenceRect, getShadowElement, initialWi
|
|
|
11910
12240
|
text-decoration: underline;
|
|
11911
12241
|
}
|
|
11912
12242
|
` }),
|
|
11913
|
-
/* @__PURE__ */
|
|
12243
|
+
/* @__PURE__ */ jsx22(
|
|
11914
12244
|
EditorContent,
|
|
11915
12245
|
{
|
|
11916
12246
|
editor,
|
|
11917
12247
|
className: "tiptap-overlay"
|
|
11918
12248
|
}
|
|
11919
12249
|
),
|
|
11920
|
-
editor && /* @__PURE__ */
|
|
12250
|
+
editor && /* @__PURE__ */ jsx22(
|
|
11921
12251
|
BubbleMenu,
|
|
11922
12252
|
{
|
|
11923
12253
|
editor,
|
|
11924
12254
|
options: { placement: "top", offset: 8, flip: true },
|
|
11925
12255
|
updateDelay: 0,
|
|
11926
|
-
children: /* @__PURE__ */
|
|
11927
|
-
/* @__PURE__ */
|
|
11928
|
-
/* @__PURE__ */
|
|
12256
|
+
children: /* @__PURE__ */ jsxs9("div", { className: "bg-white flex items-center justify-center border h-[36px] w-fit shadow-md rounded-full text-[16px]", children: [
|
|
12257
|
+
/* @__PURE__ */ jsxs9(Tooltip, { children: [
|
|
12258
|
+
/* @__PURE__ */ jsx22(TooltipTrigger, { asChild: true, children: /* @__PURE__ */ jsxs9(
|
|
11929
12259
|
Button,
|
|
11930
12260
|
{
|
|
11931
12261
|
variant: "ghost",
|
|
11932
12262
|
className: "shadow-none transition-none cursor-pointer rounded-full outline-none h-[34px]",
|
|
11933
12263
|
children: [
|
|
11934
|
-
/* @__PURE__ */
|
|
11935
|
-
/* @__PURE__ */
|
|
12264
|
+
/* @__PURE__ */ jsx22(BotIcon, { className: "size-4" }),
|
|
12265
|
+
/* @__PURE__ */ jsx22("p", { children: "Magic Write" })
|
|
11936
12266
|
]
|
|
11937
12267
|
}
|
|
11938
12268
|
) }),
|
|
11939
|
-
/* @__PURE__ */
|
|
12269
|
+
/* @__PURE__ */ jsx22(TooltipContent, { side: "bottom", children: "Ask Maillow" })
|
|
11940
12270
|
] }),
|
|
11941
|
-
currentLinkHref && /* @__PURE__ */
|
|
11942
|
-
/* @__PURE__ */
|
|
12271
|
+
currentLinkHref && /* @__PURE__ */ jsx22(FloatLinkPreview, { href: currentLinkHref }),
|
|
12272
|
+
/* @__PURE__ */ jsx22(TextLinkMenu, { editor })
|
|
11943
12273
|
] })
|
|
11944
12274
|
}
|
|
11945
12275
|
)
|
|
@@ -11949,12 +12279,12 @@ var TiptapOverlayContent = ({ idx, getReferenceRect, getShadowElement, initialWi
|
|
|
11949
12279
|
};
|
|
11950
12280
|
|
|
11951
12281
|
// src/core/editor/components/element-float.tsx
|
|
11952
|
-
import { useEffect as
|
|
11953
|
-
import { useFloating as
|
|
12282
|
+
import { useEffect as useEffect13, useMemo as useMemo12 } from "react";
|
|
12283
|
+
import { useFloating as useFloating5, offset as offset5, shift as shift4, flip as flip3, autoUpdate as autoUpdate3 } from "@floating-ui/react";
|
|
11954
12284
|
|
|
11955
12285
|
// src/core/editor/components/float-ui/actions/delete-button.tsx
|
|
11956
12286
|
import { TrashIcon as TrashIcon2 } from "lucide-react";
|
|
11957
|
-
import { jsx as
|
|
12287
|
+
import { jsx as jsx23, jsxs as jsxs10 } from "react/jsx-runtime";
|
|
11958
12288
|
var DeleteButton = () => {
|
|
11959
12289
|
const { focusIdx, deleteElement } = useEditorStore();
|
|
11960
12290
|
const handleDelete = () => {
|
|
@@ -11962,23 +12292,23 @@ var DeleteButton = () => {
|
|
|
11962
12292
|
deleteElement(focusIdx);
|
|
11963
12293
|
}
|
|
11964
12294
|
};
|
|
11965
|
-
return /* @__PURE__ */
|
|
11966
|
-
/* @__PURE__ */
|
|
12295
|
+
return /* @__PURE__ */ jsxs10(Tooltip, { children: [
|
|
12296
|
+
/* @__PURE__ */ jsx23(TooltipTrigger, { asChild: true, children: /* @__PURE__ */ jsx23(
|
|
11967
12297
|
Button,
|
|
11968
12298
|
{
|
|
11969
12299
|
variant: "ghost",
|
|
11970
12300
|
className: floatButtonVariants,
|
|
11971
12301
|
onClick: handleDelete,
|
|
11972
|
-
children: /* @__PURE__ */
|
|
12302
|
+
children: /* @__PURE__ */ jsx23(TrashIcon2, { className: "size-4" })
|
|
11973
12303
|
}
|
|
11974
12304
|
) }),
|
|
11975
|
-
/* @__PURE__ */
|
|
12305
|
+
/* @__PURE__ */ jsx23(TooltipContent, { side: "bottom", children: "Delete" })
|
|
11976
12306
|
] });
|
|
11977
12307
|
};
|
|
11978
12308
|
|
|
11979
12309
|
// src/core/editor/components/float-ui/actions/dulicate-button.tsx
|
|
11980
12310
|
import { CopyIcon as CopyIcon2 } from "lucide-react";
|
|
11981
|
-
import { jsx as
|
|
12311
|
+
import { jsx as jsx24, jsxs as jsxs11 } from "react/jsx-runtime";
|
|
11982
12312
|
var DuplicateButton = () => {
|
|
11983
12313
|
const { focusIdx, duplicateElement } = useEditorStore();
|
|
11984
12314
|
const isAtSizeLimit = useEditorStore((state) => state.isAtSizeLimit);
|
|
@@ -11987,42 +12317,42 @@ var DuplicateButton = () => {
|
|
|
11987
12317
|
duplicateElement(focusIdx);
|
|
11988
12318
|
}
|
|
11989
12319
|
};
|
|
11990
|
-
return /* @__PURE__ */
|
|
11991
|
-
/* @__PURE__ */
|
|
12320
|
+
return /* @__PURE__ */ jsxs11(Tooltip, { children: [
|
|
12321
|
+
/* @__PURE__ */ jsx24(TooltipTrigger, { asChild: true, children: /* @__PURE__ */ jsx24(
|
|
11992
12322
|
Button,
|
|
11993
12323
|
{
|
|
11994
12324
|
variant: "ghost",
|
|
11995
12325
|
className: floatButtonVariants,
|
|
11996
12326
|
onClick: handleDuplicate,
|
|
11997
12327
|
disabled: isAtSizeLimit,
|
|
11998
|
-
children: /* @__PURE__ */
|
|
12328
|
+
children: /* @__PURE__ */ jsx24(CopyIcon2, { className: "size-4" })
|
|
11999
12329
|
}
|
|
12000
12330
|
) }),
|
|
12001
|
-
/* @__PURE__ */
|
|
12331
|
+
/* @__PURE__ */ jsx24(TooltipContent, { side: "bottom", children: "Duplicate" })
|
|
12002
12332
|
] });
|
|
12003
12333
|
};
|
|
12004
12334
|
|
|
12005
12335
|
// src/core/editor/components/href-menu.tsx
|
|
12006
|
-
import { useState as
|
|
12336
|
+
import { useState as useState4, useEffect as useEffect8, useCallback as useCallback5, useMemo as useMemo6 } from "react";
|
|
12007
12337
|
|
|
12008
12338
|
// src/components/ui/dropdown-menu.tsx
|
|
12009
12339
|
import * as DropdownMenuPrimitive from "@radix-ui/react-dropdown-menu";
|
|
12010
12340
|
import { CheckIcon as CheckIcon2, ChevronRightIcon, CircleIcon } from "lucide-react";
|
|
12011
|
-
import { jsx as
|
|
12341
|
+
import { jsx as jsx25, jsxs as jsxs12 } from "react/jsx-runtime";
|
|
12012
12342
|
function DropdownMenu({
|
|
12013
12343
|
...props
|
|
12014
12344
|
}) {
|
|
12015
|
-
return /* @__PURE__ */
|
|
12345
|
+
return /* @__PURE__ */ jsx25(DropdownMenuPrimitive.Root, { "data-slot": "dropdown-menu", ...props });
|
|
12016
12346
|
}
|
|
12017
12347
|
function DropdownMenuPortal({
|
|
12018
12348
|
...props
|
|
12019
12349
|
}) {
|
|
12020
|
-
return /* @__PURE__ */
|
|
12350
|
+
return /* @__PURE__ */ jsx25(DropdownMenuPrimitive.Portal, { "data-slot": "dropdown-menu-portal", ...props });
|
|
12021
12351
|
}
|
|
12022
12352
|
function DropdownMenuTrigger({
|
|
12023
12353
|
...props
|
|
12024
12354
|
}) {
|
|
12025
|
-
return /* @__PURE__ */
|
|
12355
|
+
return /* @__PURE__ */ jsx25(
|
|
12026
12356
|
DropdownMenuPrimitive.Trigger,
|
|
12027
12357
|
{
|
|
12028
12358
|
"data-slot": "dropdown-menu-trigger",
|
|
@@ -12035,7 +12365,7 @@ function DropdownMenuContent({
|
|
|
12035
12365
|
sideOffset = 4,
|
|
12036
12366
|
...props
|
|
12037
12367
|
}) {
|
|
12038
|
-
return /* @__PURE__ */
|
|
12368
|
+
return /* @__PURE__ */ jsx25(DropdownMenuPrimitive.Portal, { children: /* @__PURE__ */ jsx25(
|
|
12039
12369
|
DropdownMenuPrimitive.Content,
|
|
12040
12370
|
{
|
|
12041
12371
|
"data-slot": "dropdown-menu-content",
|
|
@@ -12054,7 +12384,7 @@ function DropdownMenuItem({
|
|
|
12054
12384
|
variant = "default",
|
|
12055
12385
|
...props
|
|
12056
12386
|
}) {
|
|
12057
|
-
return /* @__PURE__ */
|
|
12387
|
+
return /* @__PURE__ */ jsx25(
|
|
12058
12388
|
DropdownMenuPrimitive.Item,
|
|
12059
12389
|
{
|
|
12060
12390
|
"data-slot": "dropdown-menu-item",
|
|
@@ -12072,7 +12402,7 @@ function DropdownMenuSeparator({
|
|
|
12072
12402
|
className,
|
|
12073
12403
|
...props
|
|
12074
12404
|
}) {
|
|
12075
|
-
return /* @__PURE__ */
|
|
12405
|
+
return /* @__PURE__ */ jsx25(
|
|
12076
12406
|
DropdownMenuPrimitive.Separator,
|
|
12077
12407
|
{
|
|
12078
12408
|
"data-slot": "dropdown-menu-separator",
|
|
@@ -12084,7 +12414,7 @@ function DropdownMenuSeparator({
|
|
|
12084
12414
|
function DropdownMenuSub({
|
|
12085
12415
|
...props
|
|
12086
12416
|
}) {
|
|
12087
|
-
return /* @__PURE__ */
|
|
12417
|
+
return /* @__PURE__ */ jsx25(DropdownMenuPrimitive.Sub, { "data-slot": "dropdown-menu-sub", ...props });
|
|
12088
12418
|
}
|
|
12089
12419
|
function DropdownMenuSubTrigger({
|
|
12090
12420
|
className,
|
|
@@ -12092,7 +12422,7 @@ function DropdownMenuSubTrigger({
|
|
|
12092
12422
|
children,
|
|
12093
12423
|
...props
|
|
12094
12424
|
}) {
|
|
12095
|
-
return /* @__PURE__ */
|
|
12425
|
+
return /* @__PURE__ */ jsxs12(
|
|
12096
12426
|
DropdownMenuPrimitive.SubTrigger,
|
|
12097
12427
|
{
|
|
12098
12428
|
"data-slot": "dropdown-menu-sub-trigger",
|
|
@@ -12104,7 +12434,7 @@ function DropdownMenuSubTrigger({
|
|
|
12104
12434
|
...props,
|
|
12105
12435
|
children: [
|
|
12106
12436
|
children,
|
|
12107
|
-
/* @__PURE__ */
|
|
12437
|
+
/* @__PURE__ */ jsx25(ChevronRightIcon, { className: "ml-auto size-4" })
|
|
12108
12438
|
]
|
|
12109
12439
|
}
|
|
12110
12440
|
);
|
|
@@ -12113,7 +12443,7 @@ function DropdownMenuSubContent({
|
|
|
12113
12443
|
className,
|
|
12114
12444
|
...props
|
|
12115
12445
|
}) {
|
|
12116
|
-
return /* @__PURE__ */
|
|
12446
|
+
return /* @__PURE__ */ jsx25(
|
|
12117
12447
|
DropdownMenuPrimitive.SubContent,
|
|
12118
12448
|
{
|
|
12119
12449
|
"data-slot": "dropdown-menu-sub-content",
|
|
@@ -12130,11 +12460,11 @@ function DropdownMenuSubContent({
|
|
|
12130
12460
|
import { CheckIcon as CheckIcon3, CopyIcon as CopyIcon3, LinkIcon as LinkIcon3, PencilIcon as PencilIcon2, TrashIcon as TrashIcon3 } from "lucide-react";
|
|
12131
12461
|
|
|
12132
12462
|
// src/core/editor/hooks/use-href.ts
|
|
12133
|
-
import { useMemo as
|
|
12463
|
+
import { useMemo as useMemo5, useCallback as useCallback4 } from "react";
|
|
12134
12464
|
import { get as lodashGet2 } from "lodash";
|
|
12135
12465
|
var useHref = () => {
|
|
12136
12466
|
const { focusIdx, updateElement, template } = useEditorStore();
|
|
12137
|
-
const { element, href } =
|
|
12467
|
+
const { element, href } = useMemo5(() => {
|
|
12138
12468
|
if (!focusIdx || !template) {
|
|
12139
12469
|
return { element: null, href: "" };
|
|
12140
12470
|
}
|
|
@@ -12145,19 +12475,19 @@ var useHref = () => {
|
|
|
12145
12475
|
href: el?.attributes?.href || ""
|
|
12146
12476
|
};
|
|
12147
12477
|
}, [focusIdx, template]);
|
|
12148
|
-
const setHref =
|
|
12478
|
+
const setHref = useCallback4((url) => {
|
|
12149
12479
|
if (!focusIdx || !element) return;
|
|
12150
12480
|
updateElement(focusIdx, {
|
|
12151
12481
|
attributes: { ...element.attributes, href: url }
|
|
12152
12482
|
});
|
|
12153
12483
|
}, [focusIdx, element, updateElement]);
|
|
12154
|
-
const clearHref =
|
|
12484
|
+
const clearHref = useCallback4(() => {
|
|
12155
12485
|
if (!focusIdx || !element) return;
|
|
12156
12486
|
updateElement(focusIdx, {
|
|
12157
12487
|
attributes: { ...element.attributes, href: "" }
|
|
12158
12488
|
});
|
|
12159
12489
|
}, [focusIdx, element, updateElement]);
|
|
12160
|
-
const copyHref =
|
|
12490
|
+
const copyHref = useCallback4(async () => {
|
|
12161
12491
|
if (href) {
|
|
12162
12492
|
try {
|
|
12163
12493
|
await navigator.clipboard.writeText(href);
|
|
@@ -12177,18 +12507,18 @@ var useHref = () => {
|
|
|
12177
12507
|
};
|
|
12178
12508
|
|
|
12179
12509
|
// src/core/editor/components/href-menu.tsx
|
|
12180
|
-
import { jsx as
|
|
12510
|
+
import { jsx as jsx26, jsxs as jsxs13 } from "react/jsx-runtime";
|
|
12181
12511
|
var HrefMenu = () => {
|
|
12182
12512
|
const { href, setHref, clearHref, copyHref, hasHref } = useHref();
|
|
12183
12513
|
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] =
|
|
12514
|
+
const [isOpen, setIsOpen] = useState4(false);
|
|
12515
|
+
const [inputValue, setInputValue] = useState4("");
|
|
12516
|
+
const [showCopied, setShowCopied] = useState4(false);
|
|
12517
|
+
const [linkType, setLinkType] = useState4(LINK_TYPES[1]);
|
|
12518
|
+
const [isLinkTypeOpen, setIsLinkTypeOpen] = useState4(false);
|
|
12519
|
+
const [isPresetOpen, setIsPresetOpen] = useState4(false);
|
|
12190
12520
|
console.log("userData", userData);
|
|
12191
|
-
const availablePresets =
|
|
12521
|
+
const availablePresets = useMemo6(() => {
|
|
12192
12522
|
const presetDefs = LINK_PRESETS[linkType.name] ?? [];
|
|
12193
12523
|
if (!userData) return [];
|
|
12194
12524
|
const all = presetDefs.filter((p) => userData[p.key]).map((p) => ({ ...p, value: String(userData[p.key]) }));
|
|
@@ -12196,11 +12526,11 @@ var HrefMenu = () => {
|
|
|
12196
12526
|
const query = inputValue.toLowerCase();
|
|
12197
12527
|
return all.filter((p) => p.value.toLowerCase().includes(query));
|
|
12198
12528
|
}, [linkType.name, userData, inputValue]);
|
|
12199
|
-
const handlePresetSelect =
|
|
12529
|
+
const handlePresetSelect = useCallback5((value) => {
|
|
12200
12530
|
setInputValue(value);
|
|
12201
12531
|
setIsPresetOpen(false);
|
|
12202
12532
|
}, []);
|
|
12203
|
-
|
|
12533
|
+
useEffect8(() => {
|
|
12204
12534
|
if (isOpen) {
|
|
12205
12535
|
setLinkType(detectLinkType(href));
|
|
12206
12536
|
setInputValue(stripPrefix(href));
|
|
@@ -12251,35 +12581,35 @@ var HrefMenu = () => {
|
|
|
12251
12581
|
setHref(buildHref(inputValue));
|
|
12252
12582
|
setIsOpen(false);
|
|
12253
12583
|
};
|
|
12254
|
-
return /* @__PURE__ */
|
|
12255
|
-
/* @__PURE__ */
|
|
12256
|
-
/* @__PURE__ */
|
|
12584
|
+
return /* @__PURE__ */ jsxs13(DropdownMenu, { open: isOpen, onOpenChange: setIsOpen, children: [
|
|
12585
|
+
/* @__PURE__ */ jsxs13(Tooltip, { children: [
|
|
12586
|
+
/* @__PURE__ */ jsx26(TooltipTrigger, { asChild: true, children: /* @__PURE__ */ jsx26(DropdownMenuTrigger, { asChild: true, children: hasHref ? /* @__PURE__ */ jsx26(
|
|
12257
12587
|
Button,
|
|
12258
12588
|
{
|
|
12259
12589
|
variant: "ghost",
|
|
12260
12590
|
size: "icon",
|
|
12261
12591
|
className: floatButtonVariants,
|
|
12262
|
-
children: /* @__PURE__ */
|
|
12592
|
+
children: /* @__PURE__ */ jsx26(PencilIcon2, { className: "size-4" })
|
|
12263
12593
|
}
|
|
12264
|
-
) : /* @__PURE__ */
|
|
12594
|
+
) : /* @__PURE__ */ jsxs13(
|
|
12265
12595
|
Button,
|
|
12266
12596
|
{
|
|
12267
12597
|
variant: "ghost",
|
|
12268
12598
|
className: "shadow-none transition-none cursor-pointer rounded-full outline-none h-[34px]",
|
|
12269
12599
|
children: [
|
|
12270
|
-
/* @__PURE__ */
|
|
12271
|
-
/* @__PURE__ */
|
|
12600
|
+
/* @__PURE__ */ jsx26(LinkIcon3, { className: "size-4" }),
|
|
12601
|
+
/* @__PURE__ */ jsx26("p", { children: "Add link" })
|
|
12272
12602
|
]
|
|
12273
12603
|
}
|
|
12274
12604
|
) }) }),
|
|
12275
|
-
/* @__PURE__ */
|
|
12605
|
+
/* @__PURE__ */ jsx26(TooltipContent, { side: "bottom", children: hasHref ? `Edit link` : "Add link" })
|
|
12276
12606
|
] }),
|
|
12277
|
-
/* @__PURE__ */
|
|
12278
|
-
/* @__PURE__ */
|
|
12279
|
-
/* @__PURE__ */
|
|
12280
|
-
/* @__PURE__ */
|
|
12281
|
-
/* @__PURE__ */
|
|
12282
|
-
/* @__PURE__ */
|
|
12607
|
+
/* @__PURE__ */ jsxs13(DropdownMenuContent, { side: "bottom", className: "w-[250px] p-3 shadow-lg z-50001", children: [
|
|
12608
|
+
/* @__PURE__ */ jsxs13("div", { className: "flex flex-col gap-2", children: [
|
|
12609
|
+
/* @__PURE__ */ jsx26(Label, { children: "Enter a link" }),
|
|
12610
|
+
/* @__PURE__ */ jsxs13(Popover, { open: isPresetOpen && availablePresets.length > 0, onOpenChange: setIsPresetOpen, children: [
|
|
12611
|
+
/* @__PURE__ */ jsx26(PopoverTrigger, { asChild: true, children: /* @__PURE__ */ jsxs13("div", { className: "relative", children: [
|
|
12612
|
+
/* @__PURE__ */ jsx26(
|
|
12283
12613
|
Input,
|
|
12284
12614
|
{
|
|
12285
12615
|
type: linkType.inputType,
|
|
@@ -12293,19 +12623,19 @@ var HrefMenu = () => {
|
|
|
12293
12623
|
autoFocus: true
|
|
12294
12624
|
}
|
|
12295
12625
|
),
|
|
12296
|
-
/* @__PURE__ */
|
|
12297
|
-
/* @__PURE__ */
|
|
12298
|
-
/* @__PURE__ */
|
|
12299
|
-
/* @__PURE__ */
|
|
12626
|
+
/* @__PURE__ */ jsxs13(Popover, { open: isLinkTypeOpen, onOpenChange: setIsLinkTypeOpen, children: [
|
|
12627
|
+
/* @__PURE__ */ jsxs13(Tooltip, { children: [
|
|
12628
|
+
/* @__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, {}) }) }) }),
|
|
12629
|
+
/* @__PURE__ */ jsx26(TooltipContent, { side: "top", className: "z-50001", children: "Link Type" })
|
|
12300
12630
|
] }),
|
|
12301
|
-
/* @__PURE__ */
|
|
12631
|
+
/* @__PURE__ */ jsx26(
|
|
12302
12632
|
PopoverContent,
|
|
12303
12633
|
{
|
|
12304
12634
|
side: "bottom",
|
|
12305
12635
|
align: "start",
|
|
12306
12636
|
className: "w-[160px] p-1 z-50001",
|
|
12307
12637
|
onPointerDownOutside: (e) => e.preventDefault(),
|
|
12308
|
-
children: LINK_TYPES.map((type) => /* @__PURE__ */
|
|
12638
|
+
children: LINK_TYPES.map((type) => /* @__PURE__ */ jsxs13(
|
|
12309
12639
|
Button,
|
|
12310
12640
|
{
|
|
12311
12641
|
variant: "ghost",
|
|
@@ -12316,11 +12646,11 @@ var HrefMenu = () => {
|
|
|
12316
12646
|
setIsLinkTypeOpen(false);
|
|
12317
12647
|
},
|
|
12318
12648
|
children: [
|
|
12319
|
-
/* @__PURE__ */
|
|
12320
|
-
/* @__PURE__ */
|
|
12649
|
+
/* @__PURE__ */ jsxs13("span", { className: "flex items-center gap-2", children: [
|
|
12650
|
+
/* @__PURE__ */ jsx26(type.icon, { className: "size-4" }),
|
|
12321
12651
|
type.name
|
|
12322
12652
|
] }),
|
|
12323
|
-
linkType.name === type.name && /* @__PURE__ */
|
|
12653
|
+
linkType.name === type.name && /* @__PURE__ */ jsx26(CheckIcon3, { className: "size-4" })
|
|
12324
12654
|
]
|
|
12325
12655
|
},
|
|
12326
12656
|
type.name
|
|
@@ -12329,14 +12659,14 @@ var HrefMenu = () => {
|
|
|
12329
12659
|
)
|
|
12330
12660
|
] })
|
|
12331
12661
|
] }) }),
|
|
12332
|
-
/* @__PURE__ */
|
|
12662
|
+
/* @__PURE__ */ jsx26(
|
|
12333
12663
|
PopoverContent,
|
|
12334
12664
|
{
|
|
12335
12665
|
side: "bottom",
|
|
12336
12666
|
align: "start",
|
|
12337
12667
|
className: "w-[var(--radix-popover-trigger-width)] p-0 overflow-hidden z-50001",
|
|
12338
12668
|
onOpenAutoFocus: (e) => e.preventDefault(),
|
|
12339
|
-
children: /* @__PURE__ */
|
|
12669
|
+
children: /* @__PURE__ */ jsx26("div", { className: "flex flex-col max-h-[200px] overflow-y-auto", children: availablePresets.map((preset) => /* @__PURE__ */ jsxs13(
|
|
12340
12670
|
"button",
|
|
12341
12671
|
{
|
|
12342
12672
|
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 +12675,11 @@ var HrefMenu = () => {
|
|
|
12345
12675
|
handlePresetSelect(preset.value);
|
|
12346
12676
|
},
|
|
12347
12677
|
children: [
|
|
12348
|
-
/* @__PURE__ */
|
|
12349
|
-
/* @__PURE__ */
|
|
12350
|
-
/* @__PURE__ */
|
|
12678
|
+
/* @__PURE__ */ jsxs13("div", { className: "flex flex-col items-start gap-0.5", children: [
|
|
12679
|
+
/* @__PURE__ */ jsx26("span", { className: "text-xs text-muted-foreground", children: preset.label }),
|
|
12680
|
+
/* @__PURE__ */ jsx26("span", { className: "text-sm", children: preset.value })
|
|
12351
12681
|
] }),
|
|
12352
|
-
inputValue === preset.value && /* @__PURE__ */
|
|
12682
|
+
inputValue === preset.value && /* @__PURE__ */ jsx26(CheckIcon3, { className: "w-4 h-4 shrink-0" })
|
|
12353
12683
|
]
|
|
12354
12684
|
},
|
|
12355
12685
|
preset.key
|
|
@@ -12358,11 +12688,11 @@ var HrefMenu = () => {
|
|
|
12358
12688
|
)
|
|
12359
12689
|
] })
|
|
12360
12690
|
] }),
|
|
12361
|
-
/* @__PURE__ */
|
|
12362
|
-
/* @__PURE__ */
|
|
12363
|
-
/* @__PURE__ */
|
|
12364
|
-
/* @__PURE__ */
|
|
12365
|
-
/* @__PURE__ */
|
|
12691
|
+
/* @__PURE__ */ jsx26(Separator, { className: "my-2" }),
|
|
12692
|
+
/* @__PURE__ */ jsxs13("div", { className: "flex flex-row justify-between items-center", children: [
|
|
12693
|
+
/* @__PURE__ */ jsxs13("div", { className: "flex flex-row", children: [
|
|
12694
|
+
/* @__PURE__ */ jsxs13(Tooltip, { children: [
|
|
12695
|
+
/* @__PURE__ */ jsx26(TooltipTrigger, { asChild: true, children: /* @__PURE__ */ jsx26(
|
|
12366
12696
|
Button,
|
|
12367
12697
|
{
|
|
12368
12698
|
variant: "ghost",
|
|
@@ -12370,13 +12700,13 @@ var HrefMenu = () => {
|
|
|
12370
12700
|
className: "shadow-none transition-none cursor-pointer rounded-full outline-none",
|
|
12371
12701
|
onClick: handleCopy,
|
|
12372
12702
|
disabled: !hasHref,
|
|
12373
|
-
children: showCopied ? /* @__PURE__ */
|
|
12703
|
+
children: showCopied ? /* @__PURE__ */ jsx26(CheckIcon3, { className: "text-green-600" }) : /* @__PURE__ */ jsx26(CopyIcon3, {})
|
|
12374
12704
|
}
|
|
12375
12705
|
) }),
|
|
12376
|
-
/* @__PURE__ */
|
|
12706
|
+
/* @__PURE__ */ jsx26(TooltipContent, { side: "bottom", className: "z-50001", children: showCopied ? "Copied!" : "Copy link" })
|
|
12377
12707
|
] }),
|
|
12378
|
-
/* @__PURE__ */
|
|
12379
|
-
/* @__PURE__ */
|
|
12708
|
+
/* @__PURE__ */ jsxs13(Tooltip, { children: [
|
|
12709
|
+
/* @__PURE__ */ jsx26(TooltipTrigger, { asChild: true, children: /* @__PURE__ */ jsx26(
|
|
12380
12710
|
Button,
|
|
12381
12711
|
{
|
|
12382
12712
|
variant: "ghost",
|
|
@@ -12384,13 +12714,13 @@ var HrefMenu = () => {
|
|
|
12384
12714
|
className: "shadow-none transition-none cursor-pointer rounded-full outline-none",
|
|
12385
12715
|
onClick: handleClear,
|
|
12386
12716
|
disabled: !href,
|
|
12387
|
-
children: /* @__PURE__ */
|
|
12717
|
+
children: /* @__PURE__ */ jsx26(TrashIcon3, {})
|
|
12388
12718
|
}
|
|
12389
12719
|
) }),
|
|
12390
|
-
/* @__PURE__ */
|
|
12720
|
+
/* @__PURE__ */ jsx26(TooltipContent, { side: "bottom", className: "z-50001", children: "Remove link" })
|
|
12391
12721
|
] })
|
|
12392
12722
|
] }),
|
|
12393
|
-
/* @__PURE__ */
|
|
12723
|
+
/* @__PURE__ */ jsx26("div", { children: /* @__PURE__ */ jsx26(
|
|
12394
12724
|
Button,
|
|
12395
12725
|
{
|
|
12396
12726
|
variant: "default",
|
|
@@ -12405,14 +12735,14 @@ var HrefMenu = () => {
|
|
|
12405
12735
|
};
|
|
12406
12736
|
|
|
12407
12737
|
// src/core/editor/components/element-gear/button/float.tsx
|
|
12408
|
-
import { Fragment as Fragment6, jsx as
|
|
12738
|
+
import { Fragment as Fragment6, jsx as jsx27, jsxs as jsxs14 } from "react/jsx-runtime";
|
|
12409
12739
|
var ButtonFloat = () => {
|
|
12410
12740
|
const { href, hasHref } = useHref();
|
|
12411
|
-
return /* @__PURE__ */
|
|
12412
|
-
hasHref && /* @__PURE__ */
|
|
12413
|
-
/* @__PURE__ */
|
|
12414
|
-
/* @__PURE__ */
|
|
12415
|
-
/* @__PURE__ */
|
|
12741
|
+
return /* @__PURE__ */ jsxs14(Fragment6, { children: [
|
|
12742
|
+
hasHref && /* @__PURE__ */ jsx27(FloatLinkPreview, { href }),
|
|
12743
|
+
/* @__PURE__ */ jsx27(HrefMenu, {}),
|
|
12744
|
+
/* @__PURE__ */ jsx27(DuplicateButton, {}),
|
|
12745
|
+
/* @__PURE__ */ jsx27(DeleteButton, {})
|
|
12416
12746
|
] });
|
|
12417
12747
|
};
|
|
12418
12748
|
|
|
@@ -12420,11 +12750,11 @@ var ButtonFloat = () => {
|
|
|
12420
12750
|
import { ChevronsLeftRightIcon, ChevronsRightLeftIcon, MoreHorizontalIcon } from "lucide-react";
|
|
12421
12751
|
|
|
12422
12752
|
// src/core/editor/hooks/use-full-width-toggle.ts
|
|
12423
|
-
import { useCallback as
|
|
12753
|
+
import { useCallback as useCallback6, useMemo as useMemo7 } from "react";
|
|
12424
12754
|
import { get as lodashGet3 } from "lodash";
|
|
12425
12755
|
function useFullWidthToggle() {
|
|
12426
12756
|
const { focusIdx, template, updateElement } = useEditorStore();
|
|
12427
|
-
const { element, isFullWidth } =
|
|
12757
|
+
const { element, isFullWidth } = useMemo7(() => {
|
|
12428
12758
|
if (!focusIdx || !template) return { element: null, isFullWidth: false };
|
|
12429
12759
|
const path = focusIdx.startsWith("content.") ? focusIdx.replace("content.", "content[0].").replace(/\.\[(\d+)\]/g, "[$1]") : focusIdx;
|
|
12430
12760
|
const el = lodashGet3(template, path);
|
|
@@ -12433,7 +12763,7 @@ function useFullWidthToggle() {
|
|
|
12433
12763
|
isFullWidth: el?.attributes?.["full-width"] === "full-width"
|
|
12434
12764
|
};
|
|
12435
12765
|
}, [focusIdx, template]);
|
|
12436
|
-
const handleToggleFullWidth =
|
|
12766
|
+
const handleToggleFullWidth = useCallback6(() => {
|
|
12437
12767
|
if (!focusIdx || !element) return;
|
|
12438
12768
|
const newAttributes = { ...element.attributes };
|
|
12439
12769
|
if (isFullWidth) {
|
|
@@ -12447,20 +12777,20 @@ function useFullWidthToggle() {
|
|
|
12447
12777
|
}
|
|
12448
12778
|
|
|
12449
12779
|
// src/core/editor/components/element-gear/section/float.tsx
|
|
12450
|
-
import { Fragment as Fragment7, jsx as
|
|
12780
|
+
import { Fragment as Fragment7, jsx as jsx28, jsxs as jsxs15 } from "react/jsx-runtime";
|
|
12451
12781
|
var SectionFloat = () => {
|
|
12452
12782
|
const { isFullWidth, handleToggleFullWidth } = useFullWidthToggle();
|
|
12453
|
-
return /* @__PURE__ */
|
|
12454
|
-
/* @__PURE__ */
|
|
12455
|
-
/* @__PURE__ */
|
|
12456
|
-
/* @__PURE__ */
|
|
12457
|
-
/* @__PURE__ */
|
|
12458
|
-
/* @__PURE__ */
|
|
12459
|
-
/* @__PURE__ */
|
|
12783
|
+
return /* @__PURE__ */ jsxs15(Fragment7, { children: [
|
|
12784
|
+
/* @__PURE__ */ jsx28(DuplicateButton, {}),
|
|
12785
|
+
/* @__PURE__ */ jsx28(DeleteButton, {}),
|
|
12786
|
+
/* @__PURE__ */ jsxs15(DropdownMenu, { children: [
|
|
12787
|
+
/* @__PURE__ */ jsxs15(Tooltip, { children: [
|
|
12788
|
+
/* @__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" }) }) }) }),
|
|
12789
|
+
/* @__PURE__ */ jsx28(TooltipContent, { side: "bottom", children: "More" })
|
|
12460
12790
|
] }),
|
|
12461
|
-
/* @__PURE__ */
|
|
12462
|
-
isFullWidth ? /* @__PURE__ */
|
|
12463
|
-
/* @__PURE__ */
|
|
12791
|
+
/* @__PURE__ */ jsx28(DropdownMenuContent, { side: "bottom", className: "w-[200px]", children: /* @__PURE__ */ jsxs15(DropdownMenuItem, { onClick: handleToggleFullWidth, children: [
|
|
12792
|
+
isFullWidth ? /* @__PURE__ */ jsx28(ChevronsRightLeftIcon, { className: "w-4 h-4" }) : /* @__PURE__ */ jsx28(ChevronsLeftRightIcon, { className: "w-4 h-4" }),
|
|
12793
|
+
/* @__PURE__ */ jsx28("p", { children: isFullWidth ? "Reset to original width" : "Expand to full width" })
|
|
12464
12794
|
] }) })
|
|
12465
12795
|
] })
|
|
12466
12796
|
] });
|
|
@@ -12470,11 +12800,11 @@ var SectionFloat = () => {
|
|
|
12470
12800
|
import { CheckIcon as CheckIcon4, ChevronsLeftRightIcon as ChevronsLeftRightIcon2, ChevronsRightLeftIcon as ChevronsRightLeftIcon2, Layers2Icon, MoreHorizontalIcon as MoreHorizontalIcon2 } from "lucide-react";
|
|
12471
12801
|
|
|
12472
12802
|
// src/core/editor/hooks/use-no-wrap.ts
|
|
12473
|
-
import { useCallback as
|
|
12803
|
+
import { useCallback as useCallback7, useMemo as useMemo8 } from "react";
|
|
12474
12804
|
import { get as lodashGet4 } from "lodash";
|
|
12475
12805
|
function useNoWrap() {
|
|
12476
12806
|
const { focusIdx, template, updateElement } = useEditorStore();
|
|
12477
|
-
const { element, noWrap } =
|
|
12807
|
+
const { element, noWrap } = useMemo8(() => {
|
|
12478
12808
|
if (!focusIdx || !template) return { element: null, noWrap: false };
|
|
12479
12809
|
const path = focusIdx.startsWith("content.") ? focusIdx.replace("content.", "content[0].").replace(/\.\[(\d+)\]/g, "[$1]") : focusIdx;
|
|
12480
12810
|
const el = lodashGet4(template, path);
|
|
@@ -12483,7 +12813,7 @@ function useNoWrap() {
|
|
|
12483
12813
|
noWrap: el?.data?.value?.noWrap === true
|
|
12484
12814
|
};
|
|
12485
12815
|
}, [focusIdx, template]);
|
|
12486
|
-
const handleToggleNoWrap =
|
|
12816
|
+
const handleToggleNoWrap = useCallback7(() => {
|
|
12487
12817
|
if (!focusIdx || !element) return;
|
|
12488
12818
|
updateElement(focusIdx, {
|
|
12489
12819
|
data: {
|
|
@@ -12498,30 +12828,30 @@ function useNoWrap() {
|
|
|
12498
12828
|
}
|
|
12499
12829
|
|
|
12500
12830
|
// src/core/editor/components/element-gear/section-column/float.tsx
|
|
12501
|
-
import { Fragment as Fragment8, jsx as
|
|
12831
|
+
import { Fragment as Fragment8, jsx as jsx29, jsxs as jsxs16 } from "react/jsx-runtime";
|
|
12502
12832
|
var SectionColumnFloat = () => {
|
|
12503
12833
|
const { isFullWidth, handleToggleFullWidth } = useFullWidthToggle();
|
|
12504
12834
|
const { noWrap, handleToggleNoWrap } = useNoWrap();
|
|
12505
|
-
return /* @__PURE__ */
|
|
12506
|
-
/* @__PURE__ */
|
|
12507
|
-
/* @__PURE__ */
|
|
12508
|
-
/* @__PURE__ */
|
|
12509
|
-
/* @__PURE__ */
|
|
12510
|
-
/* @__PURE__ */
|
|
12511
|
-
/* @__PURE__ */
|
|
12835
|
+
return /* @__PURE__ */ jsxs16(Fragment8, { children: [
|
|
12836
|
+
/* @__PURE__ */ jsx29(DuplicateButton, {}),
|
|
12837
|
+
/* @__PURE__ */ jsx29(DeleteButton, {}),
|
|
12838
|
+
/* @__PURE__ */ jsxs16(DropdownMenu, { children: [
|
|
12839
|
+
/* @__PURE__ */ jsxs16(Tooltip, { children: [
|
|
12840
|
+
/* @__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" }) }) }) }),
|
|
12841
|
+
/* @__PURE__ */ jsx29(TooltipContent, { side: "bottom", children: "More" })
|
|
12512
12842
|
] }),
|
|
12513
|
-
/* @__PURE__ */
|
|
12514
|
-
/* @__PURE__ */
|
|
12515
|
-
/* @__PURE__ */
|
|
12516
|
-
/* @__PURE__ */
|
|
12517
|
-
/* @__PURE__ */
|
|
12518
|
-
!noWrap && /* @__PURE__ */
|
|
12843
|
+
/* @__PURE__ */ jsxs16(DropdownMenuContent, { side: "bottom", className: "w-[250px]", children: [
|
|
12844
|
+
/* @__PURE__ */ jsxs16(DropdownMenuItem, { onClick: handleToggleNoWrap, children: [
|
|
12845
|
+
/* @__PURE__ */ jsx29(Layers2Icon, { className: "w-4 h-4" }),
|
|
12846
|
+
/* @__PURE__ */ jsxs16("div", { className: "flex items-center gap-2 w-full", children: [
|
|
12847
|
+
/* @__PURE__ */ jsx29("p", { className: "w-full", children: noWrap ? "Columns collapse" : "Columns collapse" }),
|
|
12848
|
+
!noWrap && /* @__PURE__ */ jsx29(CheckIcon4, { className: "w-4 h-4" })
|
|
12519
12849
|
] })
|
|
12520
12850
|
] }),
|
|
12521
|
-
/* @__PURE__ */
|
|
12522
|
-
/* @__PURE__ */
|
|
12523
|
-
isFullWidth ? /* @__PURE__ */
|
|
12524
|
-
/* @__PURE__ */
|
|
12851
|
+
/* @__PURE__ */ jsx29(DropdownMenuSeparator, {}),
|
|
12852
|
+
/* @__PURE__ */ jsxs16(DropdownMenuItem, { onClick: handleToggleFullWidth, children: [
|
|
12853
|
+
isFullWidth ? /* @__PURE__ */ jsx29(ChevronsRightLeftIcon2, { className: "w-4 h-4" }) : /* @__PURE__ */ jsx29(ChevronsLeftRightIcon2, { className: "w-4 h-4" }),
|
|
12854
|
+
/* @__PURE__ */ jsx29("p", { children: isFullWidth ? "Reset to original width" : "Expand to full width" })
|
|
12525
12855
|
] })
|
|
12526
12856
|
] })
|
|
12527
12857
|
] })
|
|
@@ -12529,11 +12859,11 @@ var SectionColumnFloat = () => {
|
|
|
12529
12859
|
};
|
|
12530
12860
|
|
|
12531
12861
|
// src/core/editor/components/element-gear/spacer/float.tsx
|
|
12532
|
-
import { Fragment as Fragment9, jsx as
|
|
12862
|
+
import { Fragment as Fragment9, jsx as jsx30, jsxs as jsxs17 } from "react/jsx-runtime";
|
|
12533
12863
|
var SpacerFloat = () => {
|
|
12534
|
-
return /* @__PURE__ */
|
|
12535
|
-
/* @__PURE__ */
|
|
12536
|
-
/* @__PURE__ */
|
|
12864
|
+
return /* @__PURE__ */ jsxs17(Fragment9, { children: [
|
|
12865
|
+
/* @__PURE__ */ jsx30(DuplicateButton, {}),
|
|
12866
|
+
/* @__PURE__ */ jsx30(DeleteButton, {})
|
|
12537
12867
|
] });
|
|
12538
12868
|
};
|
|
12539
12869
|
|
|
@@ -12541,16 +12871,16 @@ var SpacerFloat = () => {
|
|
|
12541
12871
|
import { MoreHorizontalIcon as MoreHorizontalIcon3, PlusCircleIcon } from "lucide-react";
|
|
12542
12872
|
|
|
12543
12873
|
// src/core/editor/components/email-template-v2/context/sidebar-context.tsx
|
|
12544
|
-
import { createContext, useContext, useState as
|
|
12545
|
-
import { jsx as
|
|
12874
|
+
import { createContext, useContext, useState as useState5 } from "react";
|
|
12875
|
+
import { jsx as jsx31 } from "react/jsx-runtime";
|
|
12546
12876
|
var SidebarContext = createContext(null);
|
|
12547
12877
|
var PICKER_VIEWS = ["color", "images", "add-social"];
|
|
12548
12878
|
function SidebarProvider({ children }) {
|
|
12549
|
-
const [activeView, setActiveViewState] =
|
|
12550
|
-
const [lastView, setLastView] =
|
|
12551
|
-
const [colorType, setColorType] =
|
|
12552
|
-
const [colorTarget, setColorTarget] =
|
|
12553
|
-
const [imageTarget, setImageTarget] =
|
|
12879
|
+
const [activeView, setActiveViewState] = useState5("elements");
|
|
12880
|
+
const [lastView, setLastView] = useState5("elements");
|
|
12881
|
+
const [colorType, setColorType] = useState5("Color");
|
|
12882
|
+
const [colorTarget, setColorTarget] = useState5(null);
|
|
12883
|
+
const [imageTarget, setImageTarget] = useState5(null);
|
|
12554
12884
|
const setActiveView = (view) => {
|
|
12555
12885
|
if (view !== activeView) {
|
|
12556
12886
|
if (!PICKER_VIEWS.includes(activeView)) {
|
|
@@ -12559,7 +12889,7 @@ function SidebarProvider({ children }) {
|
|
|
12559
12889
|
}
|
|
12560
12890
|
setActiveViewState(view);
|
|
12561
12891
|
};
|
|
12562
|
-
return /* @__PURE__ */
|
|
12892
|
+
return /* @__PURE__ */ jsx31(SidebarContext.Provider, { value: { activeView, setActiveView, lastView, colorType, setColorType, colorTarget, setColorTarget, imageTarget, setImageTarget }, children });
|
|
12563
12893
|
}
|
|
12564
12894
|
function useSidebarContext() {
|
|
12565
12895
|
const context = useContext(SidebarContext);
|
|
@@ -12570,33 +12900,33 @@ function useSidebarContext() {
|
|
|
12570
12900
|
}
|
|
12571
12901
|
|
|
12572
12902
|
// src/core/editor/components/element-gear/social/float.tsx
|
|
12573
|
-
import { Fragment as Fragment10, jsx as
|
|
12903
|
+
import { Fragment as Fragment10, jsx as jsx32, jsxs as jsxs18 } from "react/jsx-runtime";
|
|
12574
12904
|
var SocialFloat = () => {
|
|
12575
12905
|
const { setActiveView } = useSidebarContext();
|
|
12576
|
-
return /* @__PURE__ */
|
|
12577
|
-
/* @__PURE__ */
|
|
12578
|
-
/* @__PURE__ */
|
|
12579
|
-
/* @__PURE__ */
|
|
12906
|
+
return /* @__PURE__ */ jsxs18(Fragment10, { children: [
|
|
12907
|
+
/* @__PURE__ */ jsxs18(Tooltip, { children: [
|
|
12908
|
+
/* @__PURE__ */ jsx32(TooltipTrigger, { asChild: true, children: /* @__PURE__ */ jsx32(Button, { variant: "ghost", className: floatButtonVariants, onClick: () => setActiveView("add-social"), children: /* @__PURE__ */ jsx32(PlusCircleIcon, {}) }) }),
|
|
12909
|
+
/* @__PURE__ */ jsx32(TooltipContent, { side: "bottom", children: "Add Social" })
|
|
12580
12910
|
] }),
|
|
12581
|
-
/* @__PURE__ */
|
|
12582
|
-
/* @__PURE__ */
|
|
12583
|
-
/* @__PURE__ */
|
|
12584
|
-
/* @__PURE__ */
|
|
12585
|
-
/* @__PURE__ */
|
|
12586
|
-
/* @__PURE__ */
|
|
12911
|
+
/* @__PURE__ */ jsx32(DuplicateButton, {}),
|
|
12912
|
+
/* @__PURE__ */ jsx32(DeleteButton, {}),
|
|
12913
|
+
/* @__PURE__ */ jsxs18(DropdownMenu, { children: [
|
|
12914
|
+
/* @__PURE__ */ jsxs18(Tooltip, { children: [
|
|
12915
|
+
/* @__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" }) }) }) }),
|
|
12916
|
+
/* @__PURE__ */ jsx32(TooltipContent, { side: "bottom", children: "More" })
|
|
12587
12917
|
] }),
|
|
12588
|
-
/* @__PURE__ */
|
|
12589
|
-
/* @__PURE__ */
|
|
12590
|
-
/* @__PURE__ */
|
|
12918
|
+
/* @__PURE__ */ jsx32(DropdownMenuContent, { side: "bottom", className: "w-[200px]", children: /* @__PURE__ */ jsxs18(DropdownMenuItem, { onClick: () => setActiveView("add-social"), children: [
|
|
12919
|
+
/* @__PURE__ */ jsx32(PlusCircleIcon, { className: "w-4 h-4" }),
|
|
12920
|
+
/* @__PURE__ */ jsx32("p", { children: "Add Social" })
|
|
12591
12921
|
] }) })
|
|
12592
12922
|
] })
|
|
12593
12923
|
] });
|
|
12594
12924
|
};
|
|
12595
12925
|
|
|
12596
12926
|
// src/components/ui/textarea.tsx
|
|
12597
|
-
import { jsx as
|
|
12927
|
+
import { jsx as jsx33 } from "react/jsx-runtime";
|
|
12598
12928
|
function Textarea({ className, ...props }) {
|
|
12599
|
-
return /* @__PURE__ */
|
|
12929
|
+
return /* @__PURE__ */ jsx33(
|
|
12600
12930
|
"textarea",
|
|
12601
12931
|
{
|
|
12602
12932
|
"data-slot": "textarea",
|
|
@@ -12611,38 +12941,38 @@ function Textarea({ className, ...props }) {
|
|
|
12611
12941
|
|
|
12612
12942
|
// src/core/editor/components/element-gear/social-item/float.tsx
|
|
12613
12943
|
import { Accessibility, MoreHorizontalIcon as MoreHorizontalIcon4, TrashIcon as TrashIcon4 } from "lucide-react";
|
|
12614
|
-
import { useState as
|
|
12944
|
+
import { useState as useState7, useEffect as useEffect10 } from "react";
|
|
12615
12945
|
|
|
12616
12946
|
// src/core/editor/components/social-item-menu.tsx
|
|
12617
|
-
import { useState as
|
|
12947
|
+
import { useState as useState6, useEffect as useEffect9, useMemo as useMemo9, useCallback as useCallback8 } from "react";
|
|
12618
12948
|
import { PencilIcon as PencilIcon3, CheckIcon as CheckIcon5, CopyIcon as CopyIcon4 } from "lucide-react";
|
|
12619
12949
|
import { get as lodashGet5 } from "lodash";
|
|
12620
|
-
import { jsx as
|
|
12950
|
+
import { jsx as jsx34, jsxs as jsxs19 } from "react/jsx-runtime";
|
|
12621
12951
|
var SocialItemMenu = ({ hasHref }) => {
|
|
12622
|
-
const [isOpen, setIsOpen] =
|
|
12623
|
-
const [showCopied, setShowCopied] =
|
|
12624
|
-
const [hrefInputValue, setHrefInputValue] =
|
|
12625
|
-
const [contentInputValue, setContentInputValue] =
|
|
12952
|
+
const [isOpen, setIsOpen] = useState6(false);
|
|
12953
|
+
const [showCopied, setShowCopied] = useState6(false);
|
|
12954
|
+
const [hrefInputValue, setHrefInputValue] = useState6("");
|
|
12955
|
+
const [contentInputValue, setContentInputValue] = useState6("");
|
|
12626
12956
|
const { href, setHref, copyHref } = useHref();
|
|
12627
12957
|
const { focusIdx, template, updateElement } = useEditorStore();
|
|
12628
|
-
const element =
|
|
12958
|
+
const element = useMemo9(() => {
|
|
12629
12959
|
if (!focusIdx || !template) return null;
|
|
12630
12960
|
const path = focusIdx.startsWith("content.") ? focusIdx.replace("content.", "content[0].").replace(/\.?\[(\d+)\]/g, "[$1]") : focusIdx;
|
|
12631
12961
|
return lodashGet5(template, path);
|
|
12632
12962
|
}, [focusIdx, template]);
|
|
12633
12963
|
const content = element?.data?.value?.content || "";
|
|
12634
|
-
|
|
12964
|
+
useEffect9(() => {
|
|
12635
12965
|
if (isOpen) {
|
|
12636
12966
|
setHrefInputValue(href);
|
|
12637
12967
|
setContentInputValue(content);
|
|
12638
12968
|
}
|
|
12639
12969
|
}, [isOpen, href, content]);
|
|
12640
|
-
const handleCopy =
|
|
12970
|
+
const handleCopy = useCallback8(async () => {
|
|
12641
12971
|
await copyHref();
|
|
12642
12972
|
setShowCopied(true);
|
|
12643
12973
|
setTimeout(() => setShowCopied(false), 2e3);
|
|
12644
12974
|
}, [copyHref]);
|
|
12645
|
-
const handleDone =
|
|
12975
|
+
const handleDone = useCallback8(() => {
|
|
12646
12976
|
setHref(normalizeWebsiteUrl(hrefInputValue));
|
|
12647
12977
|
if (focusIdx && element) {
|
|
12648
12978
|
updateElement(focusIdx, {
|
|
@@ -12656,33 +12986,33 @@ var SocialItemMenu = ({ hasHref }) => {
|
|
|
12656
12986
|
}
|
|
12657
12987
|
setIsOpen(false);
|
|
12658
12988
|
}, [hrefInputValue, contentInputValue, setHref, focusIdx, element, updateElement]);
|
|
12659
|
-
return /* @__PURE__ */
|
|
12660
|
-
/* @__PURE__ */
|
|
12661
|
-
/* @__PURE__ */
|
|
12989
|
+
return /* @__PURE__ */ jsxs19(DropdownMenu, { open: isOpen, onOpenChange: setIsOpen, children: [
|
|
12990
|
+
/* @__PURE__ */ jsxs19(Tooltip, { children: [
|
|
12991
|
+
/* @__PURE__ */ jsx34(TooltipTrigger, { asChild: true, children: /* @__PURE__ */ jsx34(DropdownMenuTrigger, { asChild: true, children: hasHref ? /* @__PURE__ */ jsx34(
|
|
12662
12992
|
Button,
|
|
12663
12993
|
{
|
|
12664
12994
|
variant: "ghost",
|
|
12665
12995
|
size: "icon",
|
|
12666
12996
|
className: floatButtonVariants,
|
|
12667
|
-
children: /* @__PURE__ */
|
|
12997
|
+
children: /* @__PURE__ */ jsx34(PencilIcon3, { className: "size-4" })
|
|
12668
12998
|
}
|
|
12669
|
-
) : /* @__PURE__ */
|
|
12999
|
+
) : /* @__PURE__ */ jsxs19(
|
|
12670
13000
|
Button,
|
|
12671
13001
|
{
|
|
12672
13002
|
variant: "ghost",
|
|
12673
13003
|
className: "shadow-none transition-none cursor-pointer rounded-full outline-none",
|
|
12674
13004
|
children: [
|
|
12675
|
-
/* @__PURE__ */
|
|
12676
|
-
/* @__PURE__ */
|
|
13005
|
+
/* @__PURE__ */ jsx34(PencilIcon3, { className: "size-4" }),
|
|
13006
|
+
/* @__PURE__ */ jsx34("p", { children: "Edit" })
|
|
12677
13007
|
]
|
|
12678
13008
|
}
|
|
12679
13009
|
) }) }),
|
|
12680
|
-
/* @__PURE__ */
|
|
13010
|
+
/* @__PURE__ */ jsx34(TooltipContent, { side: "bottom", children: "Edit" })
|
|
12681
13011
|
] }),
|
|
12682
|
-
/* @__PURE__ */
|
|
12683
|
-
/* @__PURE__ */
|
|
12684
|
-
/* @__PURE__ */
|
|
12685
|
-
/* @__PURE__ */
|
|
13012
|
+
/* @__PURE__ */ jsxs19(DropdownMenuContent, { side: "bottom", className: "w-[250px] p-3 shadow-lg z-50001", children: [
|
|
13013
|
+
/* @__PURE__ */ jsxs19("div", { className: "flex flex-col gap-2 mb-2", children: [
|
|
13014
|
+
/* @__PURE__ */ jsx34(Label, { className: "text-xs font-medium", children: "Enter a link" }),
|
|
13015
|
+
/* @__PURE__ */ jsx34(
|
|
12686
13016
|
Input,
|
|
12687
13017
|
{
|
|
12688
13018
|
type: "text",
|
|
@@ -12694,9 +13024,9 @@ var SocialItemMenu = ({ hasHref }) => {
|
|
|
12694
13024
|
}
|
|
12695
13025
|
)
|
|
12696
13026
|
] }),
|
|
12697
|
-
/* @__PURE__ */
|
|
12698
|
-
/* @__PURE__ */
|
|
12699
|
-
/* @__PURE__ */
|
|
13027
|
+
/* @__PURE__ */ jsxs19("div", { className: "flex flex-col gap-2", children: [
|
|
13028
|
+
/* @__PURE__ */ jsx34(Label, { className: "text-xs font-medium", children: "Content" }),
|
|
13029
|
+
/* @__PURE__ */ jsx34(
|
|
12700
13030
|
Input,
|
|
12701
13031
|
{
|
|
12702
13032
|
type: "text",
|
|
@@ -12707,10 +13037,10 @@ var SocialItemMenu = ({ hasHref }) => {
|
|
|
12707
13037
|
}
|
|
12708
13038
|
)
|
|
12709
13039
|
] }),
|
|
12710
|
-
/* @__PURE__ */
|
|
12711
|
-
/* @__PURE__ */
|
|
12712
|
-
/* @__PURE__ */
|
|
12713
|
-
/* @__PURE__ */
|
|
13040
|
+
/* @__PURE__ */ jsx34(Separator, { className: "my-2" }),
|
|
13041
|
+
/* @__PURE__ */ jsxs19("div", { className: "flex flex-row justify-between items-center", children: [
|
|
13042
|
+
/* @__PURE__ */ jsx34("div", { className: "flex flex-row", children: /* @__PURE__ */ jsxs19(Tooltip, { children: [
|
|
13043
|
+
/* @__PURE__ */ jsx34(TooltipTrigger, { asChild: true, children: /* @__PURE__ */ jsx34(
|
|
12714
13044
|
Button,
|
|
12715
13045
|
{
|
|
12716
13046
|
variant: "ghost",
|
|
@@ -12718,12 +13048,12 @@ var SocialItemMenu = ({ hasHref }) => {
|
|
|
12718
13048
|
className: "shadow-none transition-none cursor-pointer rounded-full outline-none",
|
|
12719
13049
|
onClick: handleCopy,
|
|
12720
13050
|
disabled: !hasHref,
|
|
12721
|
-
children: showCopied ? /* @__PURE__ */
|
|
13051
|
+
children: showCopied ? /* @__PURE__ */ jsx34(CheckIcon5, { className: "text-green-600" }) : /* @__PURE__ */ jsx34(CopyIcon4, {})
|
|
12722
13052
|
}
|
|
12723
13053
|
) }),
|
|
12724
|
-
/* @__PURE__ */
|
|
13054
|
+
/* @__PURE__ */ jsx34(TooltipContent, { side: "bottom", className: "z-50001", children: showCopied ? "Copied!" : "Copy link" })
|
|
12725
13055
|
] }) }),
|
|
12726
|
-
/* @__PURE__ */
|
|
13056
|
+
/* @__PURE__ */ jsx34("div", { children: /* @__PURE__ */ jsx34(
|
|
12727
13057
|
Button,
|
|
12728
13058
|
{
|
|
12729
13059
|
variant: "default",
|
|
@@ -12738,11 +13068,11 @@ var SocialItemMenu = ({ hasHref }) => {
|
|
|
12738
13068
|
};
|
|
12739
13069
|
|
|
12740
13070
|
// src/core/editor/hooks/use-alt.ts
|
|
12741
|
-
import { useMemo as
|
|
13071
|
+
import { useMemo as useMemo10, useCallback as useCallback9 } from "react";
|
|
12742
13072
|
import { get as lodashGet6 } from "lodash";
|
|
12743
13073
|
var useAlt = () => {
|
|
12744
13074
|
const { focusIdx, updateElement, template } = useEditorStore();
|
|
12745
|
-
const { element, alt } =
|
|
13075
|
+
const { element, alt } = useMemo10(() => {
|
|
12746
13076
|
if (!focusIdx || !template) {
|
|
12747
13077
|
return { element: null, alt: "" };
|
|
12748
13078
|
}
|
|
@@ -12753,13 +13083,13 @@ var useAlt = () => {
|
|
|
12753
13083
|
alt: el?.attributes?.alt || ""
|
|
12754
13084
|
};
|
|
12755
13085
|
}, [focusIdx, template]);
|
|
12756
|
-
const setAlt =
|
|
13086
|
+
const setAlt = useCallback9((text2) => {
|
|
12757
13087
|
if (!focusIdx || !element) return;
|
|
12758
13088
|
updateElement(focusIdx, {
|
|
12759
13089
|
attributes: { ...element.attributes, alt: text2 }
|
|
12760
13090
|
});
|
|
12761
13091
|
}, [focusIdx, element, updateElement]);
|
|
12762
|
-
const clearAlt =
|
|
13092
|
+
const clearAlt = useCallback9(() => {
|
|
12763
13093
|
if (!focusIdx || !element) return;
|
|
12764
13094
|
updateElement(focusIdx, {
|
|
12765
13095
|
attributes: { ...element.attributes, alt: "" }
|
|
@@ -12775,17 +13105,17 @@ var useAlt = () => {
|
|
|
12775
13105
|
};
|
|
12776
13106
|
|
|
12777
13107
|
// src/core/editor/components/element-gear/social-item/float.tsx
|
|
12778
|
-
import { Fragment as Fragment11, jsx as
|
|
13108
|
+
import { Fragment as Fragment11, jsx as jsx35, jsxs as jsxs20 } from "react/jsx-runtime";
|
|
12779
13109
|
var SocialItemFloat = () => {
|
|
12780
13110
|
const { href, hasHref } = useHref();
|
|
12781
13111
|
const { alt, setAlt } = useAlt();
|
|
12782
13112
|
const { focusIdx, template, deleteElement } = useEditorStore();
|
|
12783
|
-
const [dropdownOpen, setDropdownOpen] =
|
|
12784
|
-
const [altInputValue, setAltInputValue] =
|
|
13113
|
+
const [dropdownOpen, setDropdownOpen] = useState7(false);
|
|
13114
|
+
const [altInputValue, setAltInputValue] = useState7("");
|
|
12785
13115
|
const parentSocial = focusIdx ? getParentByIdx(template, focusIdx) : null;
|
|
12786
13116
|
const childrenCount = parentSocial?.children?.length || 0;
|
|
12787
13117
|
const canDelete = childrenCount > 1;
|
|
12788
|
-
|
|
13118
|
+
useEffect10(() => {
|
|
12789
13119
|
if (dropdownOpen) {
|
|
12790
13120
|
setAltInputValue(alt);
|
|
12791
13121
|
}
|
|
@@ -12799,37 +13129,37 @@ var SocialItemFloat = () => {
|
|
|
12799
13129
|
deleteElement(focusIdx);
|
|
12800
13130
|
}
|
|
12801
13131
|
};
|
|
12802
|
-
return /* @__PURE__ */
|
|
12803
|
-
hasHref && /* @__PURE__ */
|
|
12804
|
-
/* @__PURE__ */
|
|
12805
|
-
/* @__PURE__ */
|
|
12806
|
-
/* @__PURE__ */
|
|
13132
|
+
return /* @__PURE__ */ jsxs20(Fragment11, { children: [
|
|
13133
|
+
hasHref && /* @__PURE__ */ jsx35(FloatLinkPreview, { href }),
|
|
13134
|
+
/* @__PURE__ */ jsx35(SocialItemMenu, { hasHref }),
|
|
13135
|
+
/* @__PURE__ */ jsxs20(Tooltip, { children: [
|
|
13136
|
+
/* @__PURE__ */ jsx35(TooltipTrigger, { asChild: true, children: /* @__PURE__ */ jsx35(
|
|
12807
13137
|
Button,
|
|
12808
13138
|
{
|
|
12809
13139
|
variant: "ghost",
|
|
12810
13140
|
className: floatButtonVariants,
|
|
12811
13141
|
onClick: handleDelete,
|
|
12812
13142
|
disabled: !canDelete,
|
|
12813
|
-
children: /* @__PURE__ */
|
|
13143
|
+
children: /* @__PURE__ */ jsx35(TrashIcon4, { className: "size-4" })
|
|
12814
13144
|
}
|
|
12815
13145
|
) }),
|
|
12816
|
-
/* @__PURE__ */
|
|
13146
|
+
/* @__PURE__ */ jsx35(TooltipContent, { side: "bottom", children: canDelete ? "Delete" : "Cannot delete last item" })
|
|
12817
13147
|
] }),
|
|
12818
|
-
/* @__PURE__ */
|
|
12819
|
-
/* @__PURE__ */
|
|
12820
|
-
/* @__PURE__ */
|
|
12821
|
-
/* @__PURE__ */
|
|
13148
|
+
/* @__PURE__ */ jsxs20(DropdownMenu, { open: dropdownOpen, onOpenChange: setDropdownOpen, children: [
|
|
13149
|
+
/* @__PURE__ */ jsxs20(Tooltip, { children: [
|
|
13150
|
+
/* @__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" }) }) }) }),
|
|
13151
|
+
/* @__PURE__ */ jsx35(TooltipContent, { side: "bottom", children: "More" })
|
|
12822
13152
|
] }),
|
|
12823
|
-
/* @__PURE__ */
|
|
12824
|
-
/* @__PURE__ */
|
|
12825
|
-
/* @__PURE__ */
|
|
12826
|
-
/* @__PURE__ */
|
|
13153
|
+
/* @__PURE__ */ jsx35(DropdownMenuContent, { side: "bottom", className: "w-[250px] z-50001", children: /* @__PURE__ */ jsxs20(DropdownMenuSub, { children: [
|
|
13154
|
+
/* @__PURE__ */ jsxs20(DropdownMenuSubTrigger, { children: [
|
|
13155
|
+
/* @__PURE__ */ jsx35(Accessibility, { className: "w-4 h-4" }),
|
|
13156
|
+
/* @__PURE__ */ jsx35("p", { children: "Alternative Text" })
|
|
12827
13157
|
] }),
|
|
12828
|
-
/* @__PURE__ */
|
|
12829
|
-
/* @__PURE__ */
|
|
12830
|
-
/* @__PURE__ */
|
|
12831
|
-
/* @__PURE__ */
|
|
12832
|
-
/* @__PURE__ */
|
|
13158
|
+
/* @__PURE__ */ jsx35(DropdownMenuPortal, { children: /* @__PURE__ */ jsxs20(DropdownMenuSubContent, { className: "p-3 w-[250px] z-50001", children: [
|
|
13159
|
+
/* @__PURE__ */ jsxs20("div", { className: "flex flex-col gap-2 mb-2", children: [
|
|
13160
|
+
/* @__PURE__ */ jsx35(Label, { children: "Alternative Text" }),
|
|
13161
|
+
/* @__PURE__ */ jsxs20("div", { className: "relative", children: [
|
|
13162
|
+
/* @__PURE__ */ jsx35(
|
|
12833
13163
|
Textarea,
|
|
12834
13164
|
{
|
|
12835
13165
|
placeholder: "Icon image alt, for example: 'Facebook icon'",
|
|
@@ -12839,14 +13169,14 @@ var SocialItemFloat = () => {
|
|
|
12839
13169
|
onChange: (e) => setAltInputValue(e.target.value)
|
|
12840
13170
|
}
|
|
12841
13171
|
),
|
|
12842
|
-
/* @__PURE__ */
|
|
13172
|
+
/* @__PURE__ */ jsxs20("span", { className: "bg-white rounded-[12px] p-1 shadow-sm absolute bottom-2 right-2 text-xs text-muted-foreground", children: [
|
|
12843
13173
|
altInputValue.length,
|
|
12844
13174
|
"/250"
|
|
12845
13175
|
] })
|
|
12846
13176
|
] }),
|
|
12847
|
-
/* @__PURE__ */
|
|
13177
|
+
/* @__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
13178
|
] }),
|
|
12849
|
-
/* @__PURE__ */
|
|
13179
|
+
/* @__PURE__ */ jsx35(
|
|
12850
13180
|
Button,
|
|
12851
13181
|
{
|
|
12852
13182
|
variant: "default",
|
|
@@ -12862,27 +13192,27 @@ var SocialItemFloat = () => {
|
|
|
12862
13192
|
};
|
|
12863
13193
|
|
|
12864
13194
|
// src/core/editor/components/element-gear/divider/float.tsx
|
|
12865
|
-
import { Fragment as Fragment12, jsx as
|
|
13195
|
+
import { Fragment as Fragment12, jsx as jsx36, jsxs as jsxs21 } from "react/jsx-runtime";
|
|
12866
13196
|
var DividerFloat = () => {
|
|
12867
|
-
return /* @__PURE__ */
|
|
12868
|
-
/* @__PURE__ */
|
|
12869
|
-
/* @__PURE__ */
|
|
13197
|
+
return /* @__PURE__ */ jsxs21(Fragment12, { children: [
|
|
13198
|
+
/* @__PURE__ */ jsx36(DuplicateButton, {}),
|
|
13199
|
+
/* @__PURE__ */ jsx36(DeleteButton, {})
|
|
12870
13200
|
] });
|
|
12871
13201
|
};
|
|
12872
13202
|
|
|
12873
13203
|
// src/core/editor/components/element-gear/image/float.tsx
|
|
12874
13204
|
import { Accessibility as Accessibility2, CheckIcon as CheckIcon6, MoreHorizontalIcon as MoreHorizontalIcon5, Proportions } from "lucide-react";
|
|
12875
13205
|
import lodashGet7 from "lodash/get";
|
|
12876
|
-
import { useState as
|
|
12877
|
-
import { Fragment as Fragment13, jsx as
|
|
13206
|
+
import { useState as useState8, useEffect as useEffect11, useMemo as useMemo11, useCallback as useCallback10 } from "react";
|
|
13207
|
+
import { Fragment as Fragment13, jsx as jsx37, jsxs as jsxs22 } from "react/jsx-runtime";
|
|
12878
13208
|
var ImageFloat = () => {
|
|
12879
13209
|
const { href, hasHref } = useHref();
|
|
12880
13210
|
const { alt, setAlt, hasAlt } = useAlt();
|
|
12881
13211
|
const { focusIdx, updateElement, template } = useEditorStore();
|
|
12882
|
-
const [showMoreView, setShowMoreView] =
|
|
12883
|
-
const [dropdownOpen, setDropdownOpen] =
|
|
12884
|
-
const [altInputValue, setAltInputValue] =
|
|
12885
|
-
const { element, isFluidOnMobile } =
|
|
13212
|
+
const [showMoreView, setShowMoreView] = useState8(null);
|
|
13213
|
+
const [dropdownOpen, setDropdownOpen] = useState8(false);
|
|
13214
|
+
const [altInputValue, setAltInputValue] = useState8("");
|
|
13215
|
+
const { element, isFluidOnMobile } = useMemo11(() => {
|
|
12886
13216
|
if (!focusIdx || !template) return { element: null, isFluidOnMobile: false };
|
|
12887
13217
|
const path = focusIdx.startsWith("content.") ? focusIdx.replace("content.", "content[0].").replace(/\.\[(\d+)\]/g, "[$1]") : focusIdx;
|
|
12888
13218
|
const el = lodashGet7(template, path);
|
|
@@ -12891,7 +13221,7 @@ var ImageFloat = () => {
|
|
|
12891
13221
|
isFluidOnMobile: el?.attributes?.["fluid-on-mobile"] === "true"
|
|
12892
13222
|
};
|
|
12893
13223
|
}, [focusIdx, template]);
|
|
12894
|
-
const toggleFluidOnMobile =
|
|
13224
|
+
const toggleFluidOnMobile = useCallback10(() => {
|
|
12895
13225
|
if (!focusIdx || !element) return;
|
|
12896
13226
|
const newAttributes = { ...element.attributes };
|
|
12897
13227
|
if (isFluidOnMobile) {
|
|
@@ -12901,7 +13231,7 @@ var ImageFloat = () => {
|
|
|
12901
13231
|
}
|
|
12902
13232
|
updateElement(focusIdx, { attributes: newAttributes });
|
|
12903
13233
|
}, [focusIdx, element, isFluidOnMobile, updateElement]);
|
|
12904
|
-
|
|
13234
|
+
useEffect11(() => {
|
|
12905
13235
|
if (dropdownOpen) {
|
|
12906
13236
|
setAltInputValue(alt);
|
|
12907
13237
|
}
|
|
@@ -12910,35 +13240,35 @@ var ImageFloat = () => {
|
|
|
12910
13240
|
setAlt(altInputValue);
|
|
12911
13241
|
setDropdownOpen(false);
|
|
12912
13242
|
};
|
|
12913
|
-
return /* @__PURE__ */
|
|
12914
|
-
hasHref && /* @__PURE__ */
|
|
12915
|
-
/* @__PURE__ */
|
|
12916
|
-
/* @__PURE__ */
|
|
12917
|
-
/* @__PURE__ */
|
|
12918
|
-
/* @__PURE__ */
|
|
12919
|
-
/* @__PURE__ */
|
|
12920
|
-
/* @__PURE__ */
|
|
12921
|
-
/* @__PURE__ */
|
|
13243
|
+
return /* @__PURE__ */ jsxs22(Fragment13, { children: [
|
|
13244
|
+
hasHref && /* @__PURE__ */ jsx37(FloatLinkPreview, { href }),
|
|
13245
|
+
/* @__PURE__ */ jsx37(HrefMenu, {}),
|
|
13246
|
+
/* @__PURE__ */ jsx37(DuplicateButton, {}),
|
|
13247
|
+
/* @__PURE__ */ jsx37(DeleteButton, {}),
|
|
13248
|
+
/* @__PURE__ */ jsxs22(DropdownMenu, { open: dropdownOpen, onOpenChange: setDropdownOpen, children: [
|
|
13249
|
+
/* @__PURE__ */ jsxs22(Tooltip, { children: [
|
|
13250
|
+
/* @__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" }) }) }) }),
|
|
13251
|
+
/* @__PURE__ */ jsx37(TooltipContent, { side: "bottom", children: "More" })
|
|
12922
13252
|
] }),
|
|
12923
|
-
/* @__PURE__ */
|
|
12924
|
-
/* @__PURE__ */
|
|
12925
|
-
/* @__PURE__ */
|
|
12926
|
-
/* @__PURE__ */
|
|
12927
|
-
/* @__PURE__ */
|
|
12928
|
-
isFluidOnMobile && /* @__PURE__ */
|
|
13253
|
+
/* @__PURE__ */ jsxs22(DropdownMenuContent, { side: "bottom", className: "w-[250px] z-50001", children: [
|
|
13254
|
+
/* @__PURE__ */ jsxs22(DropdownMenuItem, { onClick: toggleFluidOnMobile, children: [
|
|
13255
|
+
/* @__PURE__ */ jsx37(Proportions, { className: "w-4 h-4" }),
|
|
13256
|
+
/* @__PURE__ */ jsxs22("div", { className: "flex flex-row items-center justify-between gap-2 w-full", children: [
|
|
13257
|
+
/* @__PURE__ */ jsx37("p", { children: "Full width on mobile" }),
|
|
13258
|
+
isFluidOnMobile && /* @__PURE__ */ jsx37(CheckIcon6, { className: "w-4 h-4" })
|
|
12929
13259
|
] })
|
|
12930
13260
|
] }),
|
|
12931
|
-
/* @__PURE__ */
|
|
12932
|
-
/* @__PURE__ */
|
|
12933
|
-
/* @__PURE__ */
|
|
12934
|
-
/* @__PURE__ */
|
|
12935
|
-
/* @__PURE__ */
|
|
13261
|
+
/* @__PURE__ */ jsx37(DropdownMenuSeparator, {}),
|
|
13262
|
+
/* @__PURE__ */ jsxs22(DropdownMenuSub, { children: [
|
|
13263
|
+
/* @__PURE__ */ jsxs22(DropdownMenuSubTrigger, { children: [
|
|
13264
|
+
/* @__PURE__ */ jsx37(Accessibility2, { className: "w-4 h-4" }),
|
|
13265
|
+
/* @__PURE__ */ jsx37("p", { children: "Alternative Text" })
|
|
12936
13266
|
] }),
|
|
12937
|
-
/* @__PURE__ */
|
|
12938
|
-
/* @__PURE__ */
|
|
12939
|
-
/* @__PURE__ */
|
|
12940
|
-
/* @__PURE__ */
|
|
12941
|
-
/* @__PURE__ */
|
|
13267
|
+
/* @__PURE__ */ jsx37(DropdownMenuPortal, { children: /* @__PURE__ */ jsxs22(DropdownMenuSubContent, { className: "p-3 w-[250px] z-50001", children: [
|
|
13268
|
+
/* @__PURE__ */ jsxs22("div", { className: "flex flex-col gap-2 mb-2", children: [
|
|
13269
|
+
/* @__PURE__ */ jsx37(Label, { children: "Alternative Text" }),
|
|
13270
|
+
/* @__PURE__ */ jsxs22("div", { className: "relative", children: [
|
|
13271
|
+
/* @__PURE__ */ jsx37(
|
|
12942
13272
|
Textarea,
|
|
12943
13273
|
{
|
|
12944
13274
|
placeholder: "Spacious living room with hardwood floors, large windows, and a cozy fireplace",
|
|
@@ -12948,14 +13278,14 @@ var ImageFloat = () => {
|
|
|
12948
13278
|
onChange: (e) => setAltInputValue(e.target.value)
|
|
12949
13279
|
}
|
|
12950
13280
|
),
|
|
12951
|
-
/* @__PURE__ */
|
|
13281
|
+
/* @__PURE__ */ jsxs22("span", { className: "bg-white rounded-[12px] p-1 shadow-sm absolute bottom-2 right-2 text-xs text-muted-foreground", children: [
|
|
12952
13282
|
altInputValue.length,
|
|
12953
13283
|
"/250"
|
|
12954
13284
|
] })
|
|
12955
13285
|
] }),
|
|
12956
|
-
/* @__PURE__ */
|
|
13286
|
+
/* @__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
13287
|
] }),
|
|
12958
|
-
/* @__PURE__ */
|
|
13288
|
+
/* @__PURE__ */ jsx37(
|
|
12959
13289
|
Button,
|
|
12960
13290
|
{
|
|
12961
13291
|
variant: "default",
|
|
@@ -12972,7 +13302,7 @@ var ImageFloat = () => {
|
|
|
12972
13302
|
};
|
|
12973
13303
|
|
|
12974
13304
|
// src/core/editor/components/mlsNumber-menu.tsx
|
|
12975
|
-
import { useState as
|
|
13305
|
+
import { useState as useState9, useEffect as useEffect12 } from "react";
|
|
12976
13306
|
import { HousePlusIcon, TrashIcon as TrashIcon5, XIcon as XIcon2, Loader2Icon } from "lucide-react";
|
|
12977
13307
|
|
|
12978
13308
|
// src/services/repliers/commands.ts
|
|
@@ -12988,16 +13318,16 @@ async function getListingByMlsNumber(mlsNumber) {
|
|
|
12988
13318
|
}
|
|
12989
13319
|
|
|
12990
13320
|
// src/core/editor/components/mlsNumber-menu.tsx
|
|
12991
|
-
import { Fragment as Fragment14, jsx as
|
|
13321
|
+
import { Fragment as Fragment14, jsx as jsx38, jsxs as jsxs23 } from "react/jsx-runtime";
|
|
12992
13322
|
var MlsNumberMenu = () => {
|
|
12993
13323
|
const { focusIdx, template, updateElement, onToast } = useEditorStore();
|
|
12994
|
-
const [isOpen, setIsOpen] =
|
|
12995
|
-
const [inputValue, setInputValue] =
|
|
12996
|
-
const [propertyData, setPropertyData] =
|
|
12997
|
-
const [isLoading, setIsLoading] =
|
|
13324
|
+
const [isOpen, setIsOpen] = useState9(false);
|
|
13325
|
+
const [inputValue, setInputValue] = useState9("");
|
|
13326
|
+
const [propertyData, setPropertyData] = useState9(null);
|
|
13327
|
+
const [isLoading, setIsLoading] = useState9(false);
|
|
12998
13328
|
const propertyElement = focusIdx && template ? getValueByIdx(template, focusIdx) : null;
|
|
12999
13329
|
const currentMlsNumber = propertyElement?.data?.value?.mlsNumber || "";
|
|
13000
|
-
|
|
13330
|
+
useEffect12(() => {
|
|
13001
13331
|
setInputValue(currentMlsNumber);
|
|
13002
13332
|
setPropertyData(null);
|
|
13003
13333
|
}, [focusIdx, currentMlsNumber]);
|
|
@@ -13065,25 +13395,25 @@ var MlsNumberMenu = () => {
|
|
|
13065
13395
|
}
|
|
13066
13396
|
}
|
|
13067
13397
|
};
|
|
13068
|
-
return /* @__PURE__ */
|
|
13069
|
-
/* @__PURE__ */
|
|
13070
|
-
/* @__PURE__ */
|
|
13398
|
+
return /* @__PURE__ */ jsxs23(DropdownMenu, { open: isOpen, onOpenChange: setIsOpen, children: [
|
|
13399
|
+
/* @__PURE__ */ jsxs23(Tooltip, { children: [
|
|
13400
|
+
/* @__PURE__ */ jsx38(TooltipTrigger, { asChild: true, children: /* @__PURE__ */ jsx38(DropdownMenuTrigger, { asChild: true, children: /* @__PURE__ */ jsxs23(
|
|
13071
13401
|
Button,
|
|
13072
13402
|
{
|
|
13073
13403
|
variant: "ghost",
|
|
13074
13404
|
className: "shadow-none transition-none cursor-pointer rounded-full outline-none h-[34px]",
|
|
13075
13405
|
children: [
|
|
13076
|
-
/* @__PURE__ */
|
|
13077
|
-
/* @__PURE__ */
|
|
13406
|
+
/* @__PURE__ */ jsx38(HousePlusIcon, { className: "size-4" }),
|
|
13407
|
+
/* @__PURE__ */ jsx38("p", { children: "MLS" })
|
|
13078
13408
|
]
|
|
13079
13409
|
}
|
|
13080
13410
|
) }) }),
|
|
13081
|
-
/* @__PURE__ */
|
|
13411
|
+
/* @__PURE__ */ jsx38(TooltipContent, { side: "bottom", children: "Enter MLS Number" })
|
|
13082
13412
|
] }),
|
|
13083
|
-
/* @__PURE__ */
|
|
13084
|
-
/* @__PURE__ */
|
|
13085
|
-
/* @__PURE__ */
|
|
13086
|
-
/* @__PURE__ */
|
|
13413
|
+
/* @__PURE__ */ jsxs23(DropdownMenuContent, { side: "bottom", className: "w-[250px] p-3 shadow-lg z-50001", children: [
|
|
13414
|
+
/* @__PURE__ */ jsxs23("div", { className: "flex flex-col gap-2", children: [
|
|
13415
|
+
/* @__PURE__ */ jsx38(Label, { children: "Enter MLS Number" }),
|
|
13416
|
+
/* @__PURE__ */ jsx38(
|
|
13087
13417
|
Input,
|
|
13088
13418
|
{
|
|
13089
13419
|
type: "text",
|
|
@@ -13096,10 +13426,10 @@ var MlsNumberMenu = () => {
|
|
|
13096
13426
|
}
|
|
13097
13427
|
)
|
|
13098
13428
|
] }),
|
|
13099
|
-
/* @__PURE__ */
|
|
13100
|
-
/* @__PURE__ */
|
|
13101
|
-
/* @__PURE__ */
|
|
13102
|
-
/* @__PURE__ */
|
|
13429
|
+
/* @__PURE__ */ jsx38(Separator, { className: "my-2" }),
|
|
13430
|
+
/* @__PURE__ */ jsxs23("div", { className: "flex flex-row justify-between items-center", children: [
|
|
13431
|
+
/* @__PURE__ */ jsx38("div", { className: "flex flex-row", children: /* @__PURE__ */ jsxs23(Tooltip, { children: [
|
|
13432
|
+
/* @__PURE__ */ jsx38(TooltipTrigger, { asChild: true, children: /* @__PURE__ */ jsx38(
|
|
13103
13433
|
Button,
|
|
13104
13434
|
{
|
|
13105
13435
|
variant: "ghost",
|
|
@@ -13107,27 +13437,27 @@ var MlsNumberMenu = () => {
|
|
|
13107
13437
|
className: "shadow-none transition-none cursor-pointer rounded-full outline-none",
|
|
13108
13438
|
onClick: handleClear,
|
|
13109
13439
|
disabled: !inputValue,
|
|
13110
|
-
children: /* @__PURE__ */
|
|
13440
|
+
children: /* @__PURE__ */ jsx38(TrashIcon5, {})
|
|
13111
13441
|
}
|
|
13112
13442
|
) }),
|
|
13113
|
-
/* @__PURE__ */
|
|
13443
|
+
/* @__PURE__ */ jsx38(TooltipContent, { side: "bottom", className: "z-50001", children: "Clear" })
|
|
13114
13444
|
] }) }),
|
|
13115
|
-
/* @__PURE__ */
|
|
13445
|
+
/* @__PURE__ */ jsx38("div", { children: /* @__PURE__ */ jsx38(
|
|
13116
13446
|
Button,
|
|
13117
13447
|
{
|
|
13118
13448
|
variant: "default",
|
|
13119
13449
|
className: "shadow-none transition-none cursor-pointer rounded-[12px] outline-none",
|
|
13120
13450
|
onClick: handleDone,
|
|
13121
13451
|
disabled: isLoading || !inputValue.trim(),
|
|
13122
|
-
children: isLoading ? /* @__PURE__ */
|
|
13452
|
+
children: isLoading ? /* @__PURE__ */ jsx38(Loader2Icon, { className: "size-4 animate-spin" }) : "Done"
|
|
13123
13453
|
}
|
|
13124
13454
|
) })
|
|
13125
13455
|
] }),
|
|
13126
|
-
propertyData && /* @__PURE__ */
|
|
13127
|
-
/* @__PURE__ */
|
|
13128
|
-
/* @__PURE__ */
|
|
13129
|
-
/* @__PURE__ */
|
|
13130
|
-
/* @__PURE__ */
|
|
13456
|
+
propertyData && /* @__PURE__ */ jsxs23(Fragment14, { children: [
|
|
13457
|
+
/* @__PURE__ */ jsx38(Separator, { className: "my-2" }),
|
|
13458
|
+
/* @__PURE__ */ jsxs23("div", { className: "rounded-[12px] border overflow-hidden bg-card", children: [
|
|
13459
|
+
/* @__PURE__ */ jsxs23("div", { className: "relative", children: [
|
|
13460
|
+
/* @__PURE__ */ jsx38(
|
|
13131
13461
|
"img",
|
|
13132
13462
|
{
|
|
13133
13463
|
src: `https://cdn.repliers.io/${propertyData.images?.[0]}`,
|
|
@@ -13135,35 +13465,35 @@ var MlsNumberMenu = () => {
|
|
|
13135
13465
|
className: "w-full h-[120px] object-cover"
|
|
13136
13466
|
}
|
|
13137
13467
|
),
|
|
13138
|
-
/* @__PURE__ */
|
|
13468
|
+
/* @__PURE__ */ jsx38(
|
|
13139
13469
|
Button,
|
|
13140
13470
|
{
|
|
13141
13471
|
variant: "ghost",
|
|
13142
13472
|
size: "icon",
|
|
13143
13473
|
className: "absolute top-1 right-1 h-6 w-6 bg-black/50 hover:bg-black/70 rounded-full",
|
|
13144
13474
|
onClick: handleClearPreview,
|
|
13145
|
-
children: /* @__PURE__ */
|
|
13475
|
+
children: /* @__PURE__ */ jsx38(XIcon2, { className: "size-3 text-white" })
|
|
13146
13476
|
}
|
|
13147
13477
|
)
|
|
13148
13478
|
] }),
|
|
13149
|
-
/* @__PURE__ */
|
|
13150
|
-
/* @__PURE__ */
|
|
13151
|
-
/* @__PURE__ */
|
|
13152
|
-
/* @__PURE__ */
|
|
13479
|
+
/* @__PURE__ */ jsxs23("div", { className: "p-2 flex flex-col gap-1", children: [
|
|
13480
|
+
/* @__PURE__ */ jsxs23("div", { className: "flex items-center justify-between", children: [
|
|
13481
|
+
/* @__PURE__ */ jsx38("span", { className: "font-semibold text-sm", children: formatPrice(String(propertyData.listPrice || 0)) }),
|
|
13482
|
+
/* @__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
13483
|
] }),
|
|
13154
|
-
/* @__PURE__ */
|
|
13484
|
+
/* @__PURE__ */ jsxs23("div", { className: "text-sm", children: [
|
|
13155
13485
|
propertyData.address?.streetNumber,
|
|
13156
13486
|
" ",
|
|
13157
13487
|
propertyData.address?.streetName
|
|
13158
13488
|
] }),
|
|
13159
|
-
/* @__PURE__ */
|
|
13489
|
+
/* @__PURE__ */ jsxs23("div", { className: "text-xs text-muted-foreground", children: [
|
|
13160
13490
|
propertyData.address?.city,
|
|
13161
13491
|
", ",
|
|
13162
13492
|
propertyData.address?.state,
|
|
13163
13493
|
" ",
|
|
13164
13494
|
propertyData.address?.zip
|
|
13165
13495
|
] }),
|
|
13166
|
-
/* @__PURE__ */
|
|
13496
|
+
/* @__PURE__ */ jsxs23("div", { className: "text-xs text-muted-foreground", children: [
|
|
13167
13497
|
propertyData.details?.numBedrooms,
|
|
13168
13498
|
" bd | ",
|
|
13169
13499
|
propertyData.details?.numBathrooms,
|
|
@@ -13171,8 +13501,8 @@ var MlsNumberMenu = () => {
|
|
|
13171
13501
|
formatNumber(String(propertyData.details?.sqft || "--")),
|
|
13172
13502
|
" sf"
|
|
13173
13503
|
] }),
|
|
13174
|
-
propertyData.office?.brokerageName && /* @__PURE__ */
|
|
13175
|
-
/* @__PURE__ */
|
|
13504
|
+
propertyData.office?.brokerageName && /* @__PURE__ */ jsx38("div", { className: "text-xs text-muted-foreground truncate", children: propertyData.office.brokerageName }),
|
|
13505
|
+
/* @__PURE__ */ jsx38(
|
|
13176
13506
|
Button,
|
|
13177
13507
|
{
|
|
13178
13508
|
variant: "default",
|
|
@@ -13190,34 +13520,34 @@ var MlsNumberMenu = () => {
|
|
|
13190
13520
|
};
|
|
13191
13521
|
|
|
13192
13522
|
// src/core/editor/components/element-gear/property/float.tsx
|
|
13193
|
-
import { Fragment as Fragment15, jsx as
|
|
13523
|
+
import { Fragment as Fragment15, jsx as jsx39, jsxs as jsxs24 } from "react/jsx-runtime";
|
|
13194
13524
|
function PropertyFloat() {
|
|
13195
13525
|
const { href, hasHref } = useHref();
|
|
13196
|
-
return /* @__PURE__ */
|
|
13197
|
-
hasHref && /* @__PURE__ */
|
|
13198
|
-
/* @__PURE__ */
|
|
13199
|
-
/* @__PURE__ */
|
|
13526
|
+
return /* @__PURE__ */ jsxs24(Fragment15, { children: [
|
|
13527
|
+
hasHref && /* @__PURE__ */ jsx39(FloatLinkPreview, { href }),
|
|
13528
|
+
/* @__PURE__ */ jsx39(HrefMenu, {}),
|
|
13529
|
+
/* @__PURE__ */ jsx39(MlsNumberMenu, {})
|
|
13200
13530
|
] });
|
|
13201
13531
|
}
|
|
13202
13532
|
|
|
13203
13533
|
// src/core/editor/components/element-gear/property/triple/float.tsx
|
|
13204
|
-
import { Fragment as Fragment16, jsx as
|
|
13534
|
+
import { Fragment as Fragment16, jsx as jsx40, jsxs as jsxs25 } from "react/jsx-runtime";
|
|
13205
13535
|
var PropertyTripleItemFloat = () => {
|
|
13206
13536
|
const { href, hasHref } = useHref();
|
|
13207
|
-
return /* @__PURE__ */
|
|
13208
|
-
hasHref && /* @__PURE__ */
|
|
13209
|
-
/* @__PURE__ */
|
|
13537
|
+
return /* @__PURE__ */ jsxs25(Fragment16, { children: [
|
|
13538
|
+
hasHref && /* @__PURE__ */ jsx40(FloatLinkPreview, { href }),
|
|
13539
|
+
/* @__PURE__ */ jsx40(HrefMenu, {})
|
|
13210
13540
|
] });
|
|
13211
13541
|
};
|
|
13212
13542
|
|
|
13213
13543
|
// src/core/editor/components/float-ui/container.tsx
|
|
13214
|
-
import { jsx as
|
|
13544
|
+
import { jsx as jsx41 } from "react/jsx-runtime";
|
|
13215
13545
|
var FloatUIContainer = ({ ref, style, className, children }) => {
|
|
13216
|
-
return /* @__PURE__ */
|
|
13546
|
+
return /* @__PURE__ */ jsx41("div", { ref, style, className, children });
|
|
13217
13547
|
};
|
|
13218
13548
|
|
|
13219
13549
|
// src/core/editor/components/element-float.tsx
|
|
13220
|
-
import { jsx as
|
|
13550
|
+
import { jsx as jsx42 } from "react/jsx-runtime";
|
|
13221
13551
|
var FLOAT_COMPONENTS = {
|
|
13222
13552
|
"button": ButtonFloat,
|
|
13223
13553
|
"section": SectionFloat,
|
|
@@ -13241,7 +13571,7 @@ var ElementFloat = ({ getReferenceRect, focusIdx, elementType }) => {
|
|
|
13241
13571
|
if (!focusIdx || isDragging || textEditing) return null;
|
|
13242
13572
|
const FloatComponent = FLOAT_COMPONENTS[elementType];
|
|
13243
13573
|
if (!FloatComponent) return null;
|
|
13244
|
-
return /* @__PURE__ */
|
|
13574
|
+
return /* @__PURE__ */ jsx42(
|
|
13245
13575
|
ElementFloatContent,
|
|
13246
13576
|
{
|
|
13247
13577
|
getReferenceRect,
|
|
@@ -13250,7 +13580,7 @@ var ElementFloat = ({ getReferenceRect, focusIdx, elementType }) => {
|
|
|
13250
13580
|
);
|
|
13251
13581
|
};
|
|
13252
13582
|
var ElementFloatContent = ({ getReferenceRect, FloatComponent }) => {
|
|
13253
|
-
const virtualReference =
|
|
13583
|
+
const virtualReference = useMemo12(() => ({
|
|
13254
13584
|
getBoundingClientRect: () => {
|
|
13255
13585
|
const rect = getReferenceRect();
|
|
13256
13586
|
if (!rect) {
|
|
@@ -13259,18 +13589,18 @@ var ElementFloatContent = ({ getReferenceRect, FloatComponent }) => {
|
|
|
13259
13589
|
return rect;
|
|
13260
13590
|
}
|
|
13261
13591
|
}), [getReferenceRect]);
|
|
13262
|
-
const { floatingStyles, refs, update } =
|
|
13592
|
+
const { floatingStyles, refs, update } = useFloating5({
|
|
13263
13593
|
placement: "top",
|
|
13264
13594
|
middleware: [
|
|
13265
|
-
|
|
13595
|
+
offset5(16),
|
|
13266
13596
|
// 8px above the element
|
|
13267
|
-
|
|
13597
|
+
flip3({ padding: 8 }),
|
|
13268
13598
|
// Flip to bottom if not enough space above
|
|
13269
|
-
|
|
13599
|
+
shift4({ padding: 8 })
|
|
13270
13600
|
// Keep within viewport
|
|
13271
13601
|
]
|
|
13272
13602
|
});
|
|
13273
|
-
|
|
13603
|
+
useEffect13(() => {
|
|
13274
13604
|
const rect = getReferenceRect();
|
|
13275
13605
|
if (!rect || !refs.floating.current) return;
|
|
13276
13606
|
refs.setPositionReference(virtualReference);
|
|
@@ -13285,18 +13615,18 @@ var ElementFloatContent = ({ getReferenceRect, FloatComponent }) => {
|
|
|
13285
13615
|
);
|
|
13286
13616
|
return cleanup;
|
|
13287
13617
|
}, [getReferenceRect, refs, update, virtualReference]);
|
|
13288
|
-
return /* @__PURE__ */
|
|
13618
|
+
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
13619
|
};
|
|
13290
13620
|
|
|
13291
13621
|
// src/core/editor/components/scaling/divider-scale.tsx
|
|
13292
|
-
import { useMemo as
|
|
13293
|
-
import { useFloating as
|
|
13294
|
-
import { jsx as
|
|
13622
|
+
import { useMemo as useMemo13, useEffect as useEffect14, useState as useState10, useRef as useRef6, useCallback as useCallback12 } from "react";
|
|
13623
|
+
import { useFloating as useFloating6, offset as offset6, autoUpdate as autoUpdate4 } from "@floating-ui/react";
|
|
13624
|
+
import { jsx as jsx43, jsxs as jsxs26 } from "react/jsx-runtime";
|
|
13295
13625
|
var DividerScale = ({ getReferenceRect }) => {
|
|
13296
|
-
const [dimensions, setDimensions] =
|
|
13297
|
-
const [activeSide, setActiveSide] =
|
|
13626
|
+
const [dimensions, setDimensions] = useState10({ width: 0, height: 0 });
|
|
13627
|
+
const [activeSide, setActiveSide] = useState10(null);
|
|
13298
13628
|
const { focusIdx, template, setIsScaling } = useEditorStore();
|
|
13299
|
-
const { currentWidth, currentAlign } =
|
|
13629
|
+
const { currentWidth, currentAlign } = useMemo13(() => {
|
|
13300
13630
|
if (!focusIdx || !template) return { currentWidth: 100, currentAlign: "center" };
|
|
13301
13631
|
const element = getValueByIdx(template, focusIdx);
|
|
13302
13632
|
const rawWidth = element?.attributes?.width;
|
|
@@ -13305,13 +13635,13 @@ var DividerScale = ({ getReferenceRect }) => {
|
|
|
13305
13635
|
const align = element?.attributes?.align || "center";
|
|
13306
13636
|
return { currentWidth: width, currentAlign: align };
|
|
13307
13637
|
}, [focusIdx, template]);
|
|
13308
|
-
const dragRef =
|
|
13309
|
-
const getContainerWidth =
|
|
13638
|
+
const dragRef = useRef6(null);
|
|
13639
|
+
const getContainerWidth = useCallback12(() => {
|
|
13310
13640
|
const rect = getReferenceRect();
|
|
13311
13641
|
if (!rect || currentWidth <= 0) return null;
|
|
13312
13642
|
return rect.width / (currentWidth / 100);
|
|
13313
13643
|
}, [getReferenceRect, currentWidth]);
|
|
13314
|
-
const handlePointerDown =
|
|
13644
|
+
const handlePointerDown = useCallback12((e, side) => {
|
|
13315
13645
|
e.preventDefault();
|
|
13316
13646
|
e.stopPropagation();
|
|
13317
13647
|
const containerWidth = getContainerWidth();
|
|
@@ -13329,7 +13659,7 @@ var DividerScale = ({ getReferenceRect }) => {
|
|
|
13329
13659
|
document.addEventListener("pointermove", handlePointerMove);
|
|
13330
13660
|
document.addEventListener("pointerup", handlePointerUp);
|
|
13331
13661
|
}, [getContainerWidth, currentWidth, currentAlign, setIsScaling]);
|
|
13332
|
-
const handlePointerMove =
|
|
13662
|
+
const handlePointerMove = useCallback12((e) => {
|
|
13333
13663
|
if (!dragRef.current) return;
|
|
13334
13664
|
const { startX, startWidth, containerWidth, side, align } = dragRef.current;
|
|
13335
13665
|
const deltaX = e.clientX - startX;
|
|
@@ -13349,20 +13679,20 @@ var DividerScale = ({ getReferenceRect }) => {
|
|
|
13349
13679
|
}
|
|
13350
13680
|
});
|
|
13351
13681
|
}, []);
|
|
13352
|
-
const handlePointerUp =
|
|
13682
|
+
const handlePointerUp = useCallback12(() => {
|
|
13353
13683
|
setActiveSide(null);
|
|
13354
13684
|
setIsScaling(false);
|
|
13355
13685
|
dragRef.current = null;
|
|
13356
13686
|
document.removeEventListener("pointermove", handlePointerMove);
|
|
13357
13687
|
document.removeEventListener("pointerup", handlePointerUp);
|
|
13358
13688
|
}, [handlePointerMove, setIsScaling]);
|
|
13359
|
-
|
|
13689
|
+
useEffect14(() => {
|
|
13360
13690
|
return () => {
|
|
13361
13691
|
document.removeEventListener("pointermove", handlePointerMove);
|
|
13362
13692
|
document.removeEventListener("pointerup", handlePointerUp);
|
|
13363
13693
|
};
|
|
13364
13694
|
}, [handlePointerMove, handlePointerUp]);
|
|
13365
|
-
const virtualReference =
|
|
13695
|
+
const virtualReference = useMemo13(() => ({
|
|
13366
13696
|
getBoundingClientRect: () => {
|
|
13367
13697
|
const rect = getReferenceRect();
|
|
13368
13698
|
if (!rect) {
|
|
@@ -13371,13 +13701,13 @@ var DividerScale = ({ getReferenceRect }) => {
|
|
|
13371
13701
|
return rect;
|
|
13372
13702
|
}
|
|
13373
13703
|
}), [getReferenceRect]);
|
|
13374
|
-
const { floatingStyles, refs, update } =
|
|
13704
|
+
const { floatingStyles, refs, update } = useFloating6({
|
|
13375
13705
|
placement: "bottom-start",
|
|
13376
13706
|
middleware: [
|
|
13377
|
-
|
|
13707
|
+
offset6(({ rects }) => -rects.reference.height)
|
|
13378
13708
|
]
|
|
13379
13709
|
});
|
|
13380
|
-
|
|
13710
|
+
useEffect14(() => {
|
|
13381
13711
|
const rect = getReferenceRect();
|
|
13382
13712
|
if (!rect || !refs.floating.current) return;
|
|
13383
13713
|
refs.setPositionReference(virtualReference);
|
|
@@ -13404,7 +13734,7 @@ var DividerScale = ({ getReferenceRect }) => {
|
|
|
13404
13734
|
}, [getReferenceRect, refs, update, virtualReference]);
|
|
13405
13735
|
const showLeftHandle = currentAlign !== "left";
|
|
13406
13736
|
const showRightHandle = currentAlign !== "right";
|
|
13407
|
-
return /* @__PURE__ */
|
|
13737
|
+
return /* @__PURE__ */ jsxs26(
|
|
13408
13738
|
"div",
|
|
13409
13739
|
{
|
|
13410
13740
|
ref: refs.setFloating,
|
|
@@ -13416,14 +13746,14 @@ var DividerScale = ({ getReferenceRect }) => {
|
|
|
13416
13746
|
},
|
|
13417
13747
|
className: "relative flex flex-row items-center justify-between",
|
|
13418
13748
|
children: [
|
|
13419
|
-
showLeftHandle && (activeSide === null || activeSide === "left") && /* @__PURE__ */
|
|
13749
|
+
showLeftHandle && (activeSide === null || activeSide === "left") && /* @__PURE__ */ jsx43(
|
|
13420
13750
|
"div",
|
|
13421
13751
|
{
|
|
13422
13752
|
onPointerDown: (e) => handlePointerDown(e, "left"),
|
|
13423
13753
|
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
13754
|
}
|
|
13425
13755
|
),
|
|
13426
|
-
showRightHandle && (activeSide === null || activeSide === "right") && /* @__PURE__ */
|
|
13756
|
+
showRightHandle && (activeSide === null || activeSide === "right") && /* @__PURE__ */ jsx43(
|
|
13427
13757
|
"div",
|
|
13428
13758
|
{
|
|
13429
13759
|
onPointerDown: (e) => handlePointerDown(e, "right"),
|
|
@@ -13436,14 +13766,14 @@ var DividerScale = ({ getReferenceRect }) => {
|
|
|
13436
13766
|
};
|
|
13437
13767
|
|
|
13438
13768
|
// src/core/editor/components/scaling/button-scale.tsx
|
|
13439
|
-
import { useMemo as
|
|
13440
|
-
import { useFloating as
|
|
13441
|
-
import { jsx as
|
|
13769
|
+
import { useMemo as useMemo14, useEffect as useEffect15, useState as useState11, useRef as useRef7, useCallback as useCallback13 } from "react";
|
|
13770
|
+
import { useFloating as useFloating7, offset as offset7, autoUpdate as autoUpdate5 } from "@floating-ui/react";
|
|
13771
|
+
import { jsx as jsx44, jsxs as jsxs27 } from "react/jsx-runtime";
|
|
13442
13772
|
var ButtonScale = ({ getReferenceRect }) => {
|
|
13443
|
-
const [dimensions, setDimensions] =
|
|
13444
|
-
const [activeSide, setActiveSide] =
|
|
13773
|
+
const [dimensions, setDimensions] = useState11({ width: 0, height: 0 });
|
|
13774
|
+
const [activeSide, setActiveSide] = useState11(null);
|
|
13445
13775
|
const { focusIdx, template, setIsScaling } = useEditorStore();
|
|
13446
|
-
const { currentWidth, currentHeight, currentAlign } =
|
|
13776
|
+
const { currentWidth, currentHeight, currentAlign } = useMemo14(() => {
|
|
13447
13777
|
if (!focusIdx || !template) {
|
|
13448
13778
|
return { currentWidth: 24, currentHeight: 44, currentAlign: "center" };
|
|
13449
13779
|
}
|
|
@@ -13457,13 +13787,13 @@ var ButtonScale = ({ getReferenceRect }) => {
|
|
|
13457
13787
|
const align = element?.attributes?.align || "center";
|
|
13458
13788
|
return { currentWidth: width, currentHeight: height, currentAlign: align };
|
|
13459
13789
|
}, [focusIdx, template]);
|
|
13460
|
-
const dragRef =
|
|
13461
|
-
const getContainerWidth =
|
|
13790
|
+
const dragRef = useRef7(null);
|
|
13791
|
+
const getContainerWidth = useCallback13(() => {
|
|
13462
13792
|
const rect = getReferenceRect();
|
|
13463
13793
|
if (!rect || currentWidth <= 0) return null;
|
|
13464
13794
|
return rect.width / (currentWidth / 100);
|
|
13465
13795
|
}, [getReferenceRect, currentWidth]);
|
|
13466
|
-
const handlePointerDown =
|
|
13796
|
+
const handlePointerDown = useCallback13((e, side) => {
|
|
13467
13797
|
e.preventDefault();
|
|
13468
13798
|
e.stopPropagation();
|
|
13469
13799
|
if (document.activeElement instanceof HTMLElement) {
|
|
@@ -13485,7 +13815,7 @@ var ButtonScale = ({ getReferenceRect }) => {
|
|
|
13485
13815
|
document.addEventListener("pointermove", handlePointerMove);
|
|
13486
13816
|
document.addEventListener("pointerup", handlePointerUp);
|
|
13487
13817
|
}, [getContainerWidth, currentWidth, currentHeight, currentAlign, setIsScaling]);
|
|
13488
|
-
const handlePointerMove =
|
|
13818
|
+
const handlePointerMove = useCallback13((e) => {
|
|
13489
13819
|
if (!dragRef.current) return;
|
|
13490
13820
|
const { startX, startY, startWidth, startHeight, containerWidth, side, align } = dragRef.current;
|
|
13491
13821
|
const state = useEditorStore.getState();
|
|
@@ -13517,20 +13847,20 @@ var ButtonScale = ({ getReferenceRect }) => {
|
|
|
13517
13847
|
});
|
|
13518
13848
|
}
|
|
13519
13849
|
}, []);
|
|
13520
|
-
const handlePointerUp =
|
|
13850
|
+
const handlePointerUp = useCallback13(() => {
|
|
13521
13851
|
setActiveSide(null);
|
|
13522
13852
|
setIsScaling(false);
|
|
13523
13853
|
dragRef.current = null;
|
|
13524
13854
|
document.removeEventListener("pointermove", handlePointerMove);
|
|
13525
13855
|
document.removeEventListener("pointerup", handlePointerUp);
|
|
13526
13856
|
}, [handlePointerMove, setIsScaling]);
|
|
13527
|
-
|
|
13857
|
+
useEffect15(() => {
|
|
13528
13858
|
return () => {
|
|
13529
13859
|
document.removeEventListener("pointermove", handlePointerMove);
|
|
13530
13860
|
document.removeEventListener("pointerup", handlePointerUp);
|
|
13531
13861
|
};
|
|
13532
13862
|
}, [handlePointerMove, handlePointerUp]);
|
|
13533
|
-
const virtualReference =
|
|
13863
|
+
const virtualReference = useMemo14(() => ({
|
|
13534
13864
|
getBoundingClientRect: () => {
|
|
13535
13865
|
const rect = getReferenceRect();
|
|
13536
13866
|
if (!rect) {
|
|
@@ -13539,13 +13869,13 @@ var ButtonScale = ({ getReferenceRect }) => {
|
|
|
13539
13869
|
return rect;
|
|
13540
13870
|
}
|
|
13541
13871
|
}), [getReferenceRect]);
|
|
13542
|
-
const { floatingStyles, refs, update } =
|
|
13872
|
+
const { floatingStyles, refs, update } = useFloating7({
|
|
13543
13873
|
placement: "bottom-start",
|
|
13544
13874
|
middleware: [
|
|
13545
|
-
|
|
13875
|
+
offset7(({ rects }) => -rects.reference.height)
|
|
13546
13876
|
]
|
|
13547
13877
|
});
|
|
13548
|
-
|
|
13878
|
+
useEffect15(() => {
|
|
13549
13879
|
const rect = getReferenceRect();
|
|
13550
13880
|
if (!rect || !refs.floating.current) return;
|
|
13551
13881
|
refs.setPositionReference(virtualReference);
|
|
@@ -13574,7 +13904,7 @@ var ButtonScale = ({ getReferenceRect }) => {
|
|
|
13574
13904
|
const showRightHandle = currentAlign !== "right";
|
|
13575
13905
|
const handleBaseClass = "bg-background shadow-md border rounded-full absolute touch-none select-none pointer-events-auto";
|
|
13576
13906
|
const getHandleActiveClass = (side) => activeSide === side ? "bg-blue-400 border-blue-300" : "hover:bg-blue-400 hover:border-blue-300";
|
|
13577
|
-
return /* @__PURE__ */
|
|
13907
|
+
return /* @__PURE__ */ jsxs27(
|
|
13578
13908
|
"div",
|
|
13579
13909
|
{
|
|
13580
13910
|
ref: refs.setFloating,
|
|
@@ -13586,28 +13916,28 @@ var ButtonScale = ({ getReferenceRect }) => {
|
|
|
13586
13916
|
},
|
|
13587
13917
|
className: "relative pointer-events-none",
|
|
13588
13918
|
children: [
|
|
13589
|
-
(activeSide === null || activeSide === "top") && /* @__PURE__ */
|
|
13919
|
+
(activeSide === null || activeSide === "top") && /* @__PURE__ */ jsx44(
|
|
13590
13920
|
"div",
|
|
13591
13921
|
{
|
|
13592
13922
|
onPointerDown: (e) => handlePointerDown(e, "top"),
|
|
13593
13923
|
className: `w-[18px] h-[8px] cursor-ns-resize ${handleBaseClass} left-1/2 -translate-x-1/2 -top-[4px] ${getHandleActiveClass("top")}`
|
|
13594
13924
|
}
|
|
13595
13925
|
),
|
|
13596
|
-
showRightHandle && (activeSide === null || activeSide === "right") && /* @__PURE__ */
|
|
13926
|
+
showRightHandle && (activeSide === null || activeSide === "right") && /* @__PURE__ */ jsx44(
|
|
13597
13927
|
"div",
|
|
13598
13928
|
{
|
|
13599
13929
|
onPointerDown: (e) => handlePointerDown(e, "right"),
|
|
13600
13930
|
className: `w-[8px] h-[18px] cursor-ew-resize ${handleBaseClass} top-1/2 -translate-y-1/2 -right-[4px] ${getHandleActiveClass("right")}`
|
|
13601
13931
|
}
|
|
13602
13932
|
),
|
|
13603
|
-
(activeSide === null || activeSide === "bottom") && /* @__PURE__ */
|
|
13933
|
+
(activeSide === null || activeSide === "bottom") && /* @__PURE__ */ jsx44(
|
|
13604
13934
|
"div",
|
|
13605
13935
|
{
|
|
13606
13936
|
onPointerDown: (e) => handlePointerDown(e, "bottom"),
|
|
13607
13937
|
className: `w-[18px] h-[8px] cursor-ns-resize ${handleBaseClass} left-1/2 -translate-x-1/2 -bottom-[4px] ${getHandleActiveClass("bottom")}`
|
|
13608
13938
|
}
|
|
13609
13939
|
),
|
|
13610
|
-
showLeftHandle && (activeSide === null || activeSide === "left") && /* @__PURE__ */
|
|
13940
|
+
showLeftHandle && (activeSide === null || activeSide === "left") && /* @__PURE__ */ jsx44(
|
|
13611
13941
|
"div",
|
|
13612
13942
|
{
|
|
13613
13943
|
onPointerDown: (e) => handlePointerDown(e, "left"),
|
|
@@ -13620,14 +13950,15 @@ var ButtonScale = ({ getReferenceRect }) => {
|
|
|
13620
13950
|
};
|
|
13621
13951
|
|
|
13622
13952
|
// src/core/editor/components/scaling/image-scale.tsx
|
|
13623
|
-
import { useMemo as
|
|
13624
|
-
import { useFloating as
|
|
13625
|
-
import { jsx as
|
|
13953
|
+
import { useMemo as useMemo15, useEffect as useEffect16, useState as useState12, useRef as useRef8, useCallback as useCallback14 } from "react";
|
|
13954
|
+
import { useFloating as useFloating8, offset as offset8, autoUpdate as autoUpdate6 } from "@floating-ui/react";
|
|
13955
|
+
import { jsx as jsx45, jsxs as jsxs28 } from "react/jsx-runtime";
|
|
13956
|
+
var isCorner = (side) => side === "top-left" || side === "top-right" || side === "bottom-left" || side === "bottom-right";
|
|
13626
13957
|
var ImageScale = ({ getReferenceRect }) => {
|
|
13627
|
-
const [dimensions, setDimensions] =
|
|
13628
|
-
const [activeSide, setActiveSide] =
|
|
13958
|
+
const [dimensions, setDimensions] = useState12({ width: 0, height: 0 });
|
|
13959
|
+
const [activeSide, setActiveSide] = useState12(null);
|
|
13629
13960
|
const { focusIdx, template, setIsScaling } = useEditorStore();
|
|
13630
|
-
const { currentWidth, currentHeight, currentAlign } =
|
|
13961
|
+
const { currentWidth, currentHeight, currentAlign } = useMemo15(() => {
|
|
13631
13962
|
if (!focusIdx || !template) {
|
|
13632
13963
|
return { currentWidth: 0, currentHeight: 0, currentAlign: "center" };
|
|
13633
13964
|
}
|
|
@@ -13641,8 +13972,8 @@ var ImageScale = ({ getReferenceRect }) => {
|
|
|
13641
13972
|
const align = element?.attributes?.align || "center";
|
|
13642
13973
|
return { currentWidth: width, currentHeight: height, currentAlign: align };
|
|
13643
13974
|
}, [focusIdx, template]);
|
|
13644
|
-
const dragRef =
|
|
13645
|
-
const handlePointerDown =
|
|
13975
|
+
const dragRef = useRef8(null);
|
|
13976
|
+
const handlePointerDown = useCallback14((e, side) => {
|
|
13646
13977
|
e.preventDefault();
|
|
13647
13978
|
e.stopPropagation();
|
|
13648
13979
|
if (document.activeElement instanceof HTMLElement) {
|
|
@@ -13660,12 +13991,13 @@ var ImageScale = ({ getReferenceRect }) => {
|
|
|
13660
13991
|
startWidth: effectiveWidth,
|
|
13661
13992
|
startHeight: effectiveHeight,
|
|
13662
13993
|
side,
|
|
13663
|
-
align: currentAlign
|
|
13994
|
+
align: currentAlign,
|
|
13995
|
+
aspectRatio: effectiveHeight > 0 ? effectiveWidth / effectiveHeight : 1
|
|
13664
13996
|
};
|
|
13665
13997
|
document.addEventListener("pointermove", handlePointerMove);
|
|
13666
13998
|
document.addEventListener("pointerup", handlePointerUp);
|
|
13667
13999
|
}, [getReferenceRect, currentWidth, currentHeight, currentAlign, setIsScaling]);
|
|
13668
|
-
const handlePointerMove =
|
|
14000
|
+
const handlePointerMove = useCallback14((e) => {
|
|
13669
14001
|
if (!dragRef.current) return;
|
|
13670
14002
|
const { startX, startY, startWidth, startHeight, side, align } = dragRef.current;
|
|
13671
14003
|
const state = useEditorStore.getState();
|
|
@@ -13673,7 +14005,35 @@ var ImageScale = ({ getReferenceRect }) => {
|
|
|
13673
14005
|
if (!currentFocusIdx || !currentTemplate) return;
|
|
13674
14006
|
const element = getValueByIdx(currentTemplate, currentFocusIdx);
|
|
13675
14007
|
if (!element) return;
|
|
13676
|
-
if (side
|
|
14008
|
+
if (isCorner(side)) {
|
|
14009
|
+
const { aspectRatio } = dragRef.current;
|
|
14010
|
+
const deltaX = e.clientX - startX;
|
|
14011
|
+
const deltaY = e.clientY - startY;
|
|
14012
|
+
const signX = side.includes("left") ? -1 : 1;
|
|
14013
|
+
const signY = side.includes("top") ? -1 : 1;
|
|
14014
|
+
const alignMultiplier = align === "center" ? 2 : 1;
|
|
14015
|
+
const absDX = Math.abs(deltaX);
|
|
14016
|
+
const absDY = Math.abs(deltaY);
|
|
14017
|
+
let newWidth;
|
|
14018
|
+
let newHeight;
|
|
14019
|
+
if (absDX >= absDY) {
|
|
14020
|
+
newWidth = startWidth + signX * deltaX * alignMultiplier;
|
|
14021
|
+
newHeight = newWidth / aspectRatio;
|
|
14022
|
+
} else {
|
|
14023
|
+
newHeight = startHeight + signY * deltaY;
|
|
14024
|
+
newWidth = newHeight * aspectRatio;
|
|
14025
|
+
}
|
|
14026
|
+
const clampedWidth = Math.max(20, Math.min(600, newWidth));
|
|
14027
|
+
const clampedHeight = Math.max(20, Math.min(600, clampedWidth / aspectRatio));
|
|
14028
|
+
const finalWidth = clampedHeight * aspectRatio;
|
|
14029
|
+
updateElement(currentFocusIdx, {
|
|
14030
|
+
attributes: {
|
|
14031
|
+
...element.attributes,
|
|
14032
|
+
width: `${Math.round(finalWidth)}px`,
|
|
14033
|
+
height: `${Math.round(clampedHeight)}px`
|
|
14034
|
+
}
|
|
14035
|
+
});
|
|
14036
|
+
} else if (side === "left" || side === "right") {
|
|
13677
14037
|
const deltaX = e.clientX - startX;
|
|
13678
14038
|
const alignMultiplier = align === "center" ? 2 : 1;
|
|
13679
14039
|
const newWidth = side === "left" ? startWidth - deltaX * alignMultiplier : startWidth + deltaX * alignMultiplier;
|
|
@@ -13696,20 +14056,20 @@ var ImageScale = ({ getReferenceRect }) => {
|
|
|
13696
14056
|
});
|
|
13697
14057
|
}
|
|
13698
14058
|
}, []);
|
|
13699
|
-
const handlePointerUp =
|
|
14059
|
+
const handlePointerUp = useCallback14(() => {
|
|
13700
14060
|
setActiveSide(null);
|
|
13701
14061
|
setIsScaling(false);
|
|
13702
14062
|
dragRef.current = null;
|
|
13703
14063
|
document.removeEventListener("pointermove", handlePointerMove);
|
|
13704
14064
|
document.removeEventListener("pointerup", handlePointerUp);
|
|
13705
14065
|
}, [handlePointerMove, setIsScaling]);
|
|
13706
|
-
|
|
14066
|
+
useEffect16(() => {
|
|
13707
14067
|
return () => {
|
|
13708
14068
|
document.removeEventListener("pointermove", handlePointerMove);
|
|
13709
14069
|
document.removeEventListener("pointerup", handlePointerUp);
|
|
13710
14070
|
};
|
|
13711
14071
|
}, [handlePointerMove, handlePointerUp]);
|
|
13712
|
-
const virtualReference =
|
|
14072
|
+
const virtualReference = useMemo15(() => ({
|
|
13713
14073
|
getBoundingClientRect: () => {
|
|
13714
14074
|
const rect = getReferenceRect();
|
|
13715
14075
|
if (!rect) {
|
|
@@ -13718,13 +14078,13 @@ var ImageScale = ({ getReferenceRect }) => {
|
|
|
13718
14078
|
return rect;
|
|
13719
14079
|
}
|
|
13720
14080
|
}), [getReferenceRect]);
|
|
13721
|
-
const { floatingStyles, refs, update } =
|
|
14081
|
+
const { floatingStyles, refs, update } = useFloating8({
|
|
13722
14082
|
placement: "bottom-start",
|
|
13723
14083
|
middleware: [
|
|
13724
|
-
|
|
14084
|
+
offset8(({ rects }) => -rects.reference.height)
|
|
13725
14085
|
]
|
|
13726
14086
|
});
|
|
13727
|
-
|
|
14087
|
+
useEffect16(() => {
|
|
13728
14088
|
const rect = getReferenceRect();
|
|
13729
14089
|
if (!rect || !refs.floating.current) return;
|
|
13730
14090
|
refs.setPositionReference(virtualReference);
|
|
@@ -13751,9 +14111,13 @@ var ImageScale = ({ getReferenceRect }) => {
|
|
|
13751
14111
|
}, [getReferenceRect, refs, update, virtualReference]);
|
|
13752
14112
|
const showLeftHandle = currentAlign !== "left";
|
|
13753
14113
|
const showRightHandle = currentAlign !== "right";
|
|
14114
|
+
const showTopLeft = currentAlign !== "left";
|
|
14115
|
+
const showTopRight = currentAlign !== "right";
|
|
14116
|
+
const showBottomLeft = currentAlign !== "left";
|
|
14117
|
+
const showBottomRight = currentAlign !== "right";
|
|
13754
14118
|
const handleBaseClass = "bg-background shadow-md border rounded-full absolute touch-none select-none pointer-events-auto";
|
|
13755
14119
|
const getHandleActiveClass = (side) => activeSide === side ? "bg-blue-400 border-blue-300" : "hover:bg-blue-400 hover:border-blue-300";
|
|
13756
|
-
return /* @__PURE__ */
|
|
14120
|
+
return /* @__PURE__ */ jsxs28(
|
|
13757
14121
|
"div",
|
|
13758
14122
|
{
|
|
13759
14123
|
ref: refs.setFloating,
|
|
@@ -13765,33 +14129,61 @@ var ImageScale = ({ getReferenceRect }) => {
|
|
|
13765
14129
|
},
|
|
13766
14130
|
className: "relative pointer-events-none",
|
|
13767
14131
|
children: [
|
|
13768
|
-
(activeSide === null || activeSide === "top") && /* @__PURE__ */
|
|
14132
|
+
(activeSide === null || activeSide === "top") && /* @__PURE__ */ jsx45(
|
|
13769
14133
|
"div",
|
|
13770
14134
|
{
|
|
13771
14135
|
onPointerDown: (e) => handlePointerDown(e, "top"),
|
|
13772
14136
|
className: `w-[18px] h-[8px] cursor-ns-resize ${handleBaseClass} left-1/2 -translate-x-1/2 -top-[4px] ${getHandleActiveClass("top")}`
|
|
13773
14137
|
}
|
|
13774
14138
|
),
|
|
13775
|
-
showRightHandle && (activeSide === null || activeSide === "right") && /* @__PURE__ */
|
|
14139
|
+
showRightHandle && (activeSide === null || activeSide === "right") && /* @__PURE__ */ jsx45(
|
|
13776
14140
|
"div",
|
|
13777
14141
|
{
|
|
13778
14142
|
onPointerDown: (e) => handlePointerDown(e, "right"),
|
|
13779
14143
|
className: `w-[8px] h-[18px] cursor-ew-resize ${handleBaseClass} top-1/2 -translate-y-1/2 -right-[4px] ${getHandleActiveClass("right")}`
|
|
13780
14144
|
}
|
|
13781
14145
|
),
|
|
13782
|
-
(activeSide === null || activeSide === "bottom") && /* @__PURE__ */
|
|
14146
|
+
(activeSide === null || activeSide === "bottom") && /* @__PURE__ */ jsx45(
|
|
13783
14147
|
"div",
|
|
13784
14148
|
{
|
|
13785
14149
|
onPointerDown: (e) => handlePointerDown(e, "bottom"),
|
|
13786
14150
|
className: `w-[18px] h-[8px] cursor-ns-resize ${handleBaseClass} left-1/2 -translate-x-1/2 -bottom-[4px] ${getHandleActiveClass("bottom")}`
|
|
13787
14151
|
}
|
|
13788
14152
|
),
|
|
13789
|
-
showLeftHandle && (activeSide === null || activeSide === "left") && /* @__PURE__ */
|
|
14153
|
+
showLeftHandle && (activeSide === null || activeSide === "left") && /* @__PURE__ */ jsx45(
|
|
13790
14154
|
"div",
|
|
13791
14155
|
{
|
|
13792
14156
|
onPointerDown: (e) => handlePointerDown(e, "left"),
|
|
13793
14157
|
className: `w-[8px] h-[18px] cursor-ew-resize ${handleBaseClass} top-1/2 -translate-y-1/2 -left-[4px] ${getHandleActiveClass("left")}`
|
|
13794
14158
|
}
|
|
14159
|
+
),
|
|
14160
|
+
showTopLeft && (activeSide === null || activeSide === "top-left") && /* @__PURE__ */ jsx45(
|
|
14161
|
+
"div",
|
|
14162
|
+
{
|
|
14163
|
+
onPointerDown: (e) => handlePointerDown(e, "top-left"),
|
|
14164
|
+
className: `w-[10px] h-[10px] cursor-nwse-resize ${handleBaseClass} -top-[5px] -left-[5px] ${getHandleActiveClass("top-left")}`
|
|
14165
|
+
}
|
|
14166
|
+
),
|
|
14167
|
+
showTopRight && (activeSide === null || activeSide === "top-right") && /* @__PURE__ */ jsx45(
|
|
14168
|
+
"div",
|
|
14169
|
+
{
|
|
14170
|
+
onPointerDown: (e) => handlePointerDown(e, "top-right"),
|
|
14171
|
+
className: `w-[10px] h-[10px] cursor-nesw-resize ${handleBaseClass} -top-[5px] -right-[5px] ${getHandleActiveClass("top-right")}`
|
|
14172
|
+
}
|
|
14173
|
+
),
|
|
14174
|
+
showBottomLeft && (activeSide === null || activeSide === "bottom-left") && /* @__PURE__ */ jsx45(
|
|
14175
|
+
"div",
|
|
14176
|
+
{
|
|
14177
|
+
onPointerDown: (e) => handlePointerDown(e, "bottom-left"),
|
|
14178
|
+
className: `w-[10px] h-[10px] cursor-nesw-resize ${handleBaseClass} -bottom-[5px] -left-[5px] ${getHandleActiveClass("bottom-left")}`
|
|
14179
|
+
}
|
|
14180
|
+
),
|
|
14181
|
+
showBottomRight && (activeSide === null || activeSide === "bottom-right") && /* @__PURE__ */ jsx45(
|
|
14182
|
+
"div",
|
|
14183
|
+
{
|
|
14184
|
+
onPointerDown: (e) => handlePointerDown(e, "bottom-right"),
|
|
14185
|
+
className: `w-[10px] h-[10px] cursor-nwse-resize ${handleBaseClass} -bottom-[5px] -right-[5px] ${getHandleActiveClass("bottom-right")}`
|
|
14186
|
+
}
|
|
13795
14187
|
)
|
|
13796
14188
|
]
|
|
13797
14189
|
}
|
|
@@ -13799,22 +14191,22 @@ var ImageScale = ({ getReferenceRect }) => {
|
|
|
13799
14191
|
};
|
|
13800
14192
|
|
|
13801
14193
|
// src/core/editor/components/scaling/spacer-scale.tsx
|
|
13802
|
-
import { useMemo as
|
|
13803
|
-
import { useFloating as
|
|
13804
|
-
import { jsx as
|
|
14194
|
+
import { useMemo as useMemo16, useEffect as useEffect17, useState as useState13, useRef as useRef9, useCallback as useCallback15 } from "react";
|
|
14195
|
+
import { useFloating as useFloating9, offset as offset9, autoUpdate as autoUpdate7 } from "@floating-ui/react";
|
|
14196
|
+
import { jsx as jsx46, jsxs as jsxs29 } from "react/jsx-runtime";
|
|
13805
14197
|
var SpacerScale = ({ getReferenceRect }) => {
|
|
13806
|
-
const [dimensions, setDimensions] =
|
|
13807
|
-
const [activeSide, setActiveSide] =
|
|
14198
|
+
const [dimensions, setDimensions] = useState13({ width: 0, height: 0 });
|
|
14199
|
+
const [activeSide, setActiveSide] = useState13(null);
|
|
13808
14200
|
const { focusIdx, template, setIsScaling } = useEditorStore();
|
|
13809
|
-
const currentHeight =
|
|
14201
|
+
const currentHeight = useMemo16(() => {
|
|
13810
14202
|
if (!focusIdx || !template) return 12;
|
|
13811
14203
|
const element = getValueByIdx(template, focusIdx);
|
|
13812
14204
|
const rawHeight = element?.attributes?.height;
|
|
13813
14205
|
const parsedHeight = rawHeight ? parseFloat(rawHeight.replace("px", "")) : 12;
|
|
13814
14206
|
return isNaN(parsedHeight) ? 12 : Math.max(12, Math.min(200, parsedHeight));
|
|
13815
14207
|
}, [focusIdx, template]);
|
|
13816
|
-
const dragRef =
|
|
13817
|
-
const handlePointerDown =
|
|
14208
|
+
const dragRef = useRef9(null);
|
|
14209
|
+
const handlePointerDown = useCallback15((e, side) => {
|
|
13818
14210
|
e.preventDefault();
|
|
13819
14211
|
e.stopPropagation();
|
|
13820
14212
|
if (document.activeElement instanceof HTMLElement) {
|
|
@@ -13830,7 +14222,7 @@ var SpacerScale = ({ getReferenceRect }) => {
|
|
|
13830
14222
|
document.addEventListener("pointermove", handlePointerMove);
|
|
13831
14223
|
document.addEventListener("pointerup", handlePointerUp);
|
|
13832
14224
|
}, [currentHeight, setIsScaling]);
|
|
13833
|
-
const handlePointerMove =
|
|
14225
|
+
const handlePointerMove = useCallback15((e) => {
|
|
13834
14226
|
if (!dragRef.current) return;
|
|
13835
14227
|
const { startY, startHeight, side } = dragRef.current;
|
|
13836
14228
|
const state = useEditorStore.getState();
|
|
@@ -13848,20 +14240,20 @@ var SpacerScale = ({ getReferenceRect }) => {
|
|
|
13848
14240
|
}
|
|
13849
14241
|
});
|
|
13850
14242
|
}, []);
|
|
13851
|
-
const handlePointerUp =
|
|
14243
|
+
const handlePointerUp = useCallback15(() => {
|
|
13852
14244
|
setActiveSide(null);
|
|
13853
14245
|
setIsScaling(false);
|
|
13854
14246
|
dragRef.current = null;
|
|
13855
14247
|
document.removeEventListener("pointermove", handlePointerMove);
|
|
13856
14248
|
document.removeEventListener("pointerup", handlePointerUp);
|
|
13857
14249
|
}, [handlePointerMove, setIsScaling]);
|
|
13858
|
-
|
|
14250
|
+
useEffect17(() => {
|
|
13859
14251
|
return () => {
|
|
13860
14252
|
document.removeEventListener("pointermove", handlePointerMove);
|
|
13861
14253
|
document.removeEventListener("pointerup", handlePointerUp);
|
|
13862
14254
|
};
|
|
13863
14255
|
}, [handlePointerMove, handlePointerUp]);
|
|
13864
|
-
const virtualReference =
|
|
14256
|
+
const virtualReference = useMemo16(() => ({
|
|
13865
14257
|
getBoundingClientRect: () => {
|
|
13866
14258
|
const rect = getReferenceRect();
|
|
13867
14259
|
if (!rect) {
|
|
@@ -13870,13 +14262,13 @@ var SpacerScale = ({ getReferenceRect }) => {
|
|
|
13870
14262
|
return rect;
|
|
13871
14263
|
}
|
|
13872
14264
|
}), [getReferenceRect]);
|
|
13873
|
-
const { floatingStyles, refs, update } =
|
|
14265
|
+
const { floatingStyles, refs, update } = useFloating9({
|
|
13874
14266
|
placement: "bottom-start",
|
|
13875
14267
|
middleware: [
|
|
13876
|
-
|
|
14268
|
+
offset9(({ rects }) => -rects.reference.height)
|
|
13877
14269
|
]
|
|
13878
14270
|
});
|
|
13879
|
-
|
|
14271
|
+
useEffect17(() => {
|
|
13880
14272
|
const rect = getReferenceRect();
|
|
13881
14273
|
if (!rect || !refs.floating.current) return;
|
|
13882
14274
|
refs.setPositionReference(virtualReference);
|
|
@@ -13903,7 +14295,7 @@ var SpacerScale = ({ getReferenceRect }) => {
|
|
|
13903
14295
|
}, [getReferenceRect, refs, update, virtualReference]);
|
|
13904
14296
|
const handleBaseClass = "bg-background shadow-md border rounded-full absolute touch-none select-none pointer-events-auto";
|
|
13905
14297
|
const getHandleActiveClass = (side) => activeSide === side ? "bg-blue-400 border-blue-300" : "hover:bg-blue-400 hover:border-blue-300";
|
|
13906
|
-
return /* @__PURE__ */
|
|
14298
|
+
return /* @__PURE__ */ jsxs29(
|
|
13907
14299
|
"div",
|
|
13908
14300
|
{
|
|
13909
14301
|
ref: refs.setFloating,
|
|
@@ -13915,14 +14307,14 @@ var SpacerScale = ({ getReferenceRect }) => {
|
|
|
13915
14307
|
},
|
|
13916
14308
|
className: "relative pointer-events-none",
|
|
13917
14309
|
children: [
|
|
13918
|
-
(activeSide === null || activeSide === "top") && /* @__PURE__ */
|
|
14310
|
+
(activeSide === null || activeSide === "top") && /* @__PURE__ */ jsx46(
|
|
13919
14311
|
"div",
|
|
13920
14312
|
{
|
|
13921
14313
|
onPointerDown: (e) => handlePointerDown(e, "top"),
|
|
13922
14314
|
className: `w-[18px] h-[8px] cursor-ns-resize ${handleBaseClass} left-1/2 -translate-x-1/2 -top-[4px] ${getHandleActiveClass("top")}`
|
|
13923
14315
|
}
|
|
13924
14316
|
),
|
|
13925
|
-
(activeSide === null || activeSide === "bottom") && /* @__PURE__ */
|
|
14317
|
+
(activeSide === null || activeSide === "bottom") && /* @__PURE__ */ jsx46(
|
|
13926
14318
|
"div",
|
|
13927
14319
|
{
|
|
13928
14320
|
onPointerDown: (e) => handlePointerDown(e, "bottom"),
|
|
@@ -13935,19 +14327,19 @@ var SpacerScale = ({ getReferenceRect }) => {
|
|
|
13935
14327
|
};
|
|
13936
14328
|
|
|
13937
14329
|
// src/core/editor/components/scaling/column-scale.tsx
|
|
13938
|
-
import { useMemo as
|
|
13939
|
-
import { Fragment as Fragment17, jsx as
|
|
14330
|
+
import { useMemo as useMemo17, useEffect as useEffect18, useState as useState14, useRef as useRef10, useCallback as useCallback16 } from "react";
|
|
14331
|
+
import { Fragment as Fragment17, jsx as jsx47 } from "react/jsx-runtime";
|
|
13940
14332
|
var ColumnScale = ({ sectionColumnIdx, shadowRoot }) => {
|
|
13941
|
-
const [activeDivider, setActiveDivider] =
|
|
13942
|
-
const [columnRects, setColumnRects] =
|
|
14333
|
+
const [activeDivider, setActiveDivider] = useState14(null);
|
|
14334
|
+
const [columnRects, setColumnRects] = useState14([]);
|
|
13943
14335
|
const { template, setIsScaling, setFocusIdx, stopTextEditing } = useEditorStore();
|
|
13944
|
-
const columnWidths =
|
|
14336
|
+
const columnWidths = useMemo17(() => {
|
|
13945
14337
|
if (!template) return [];
|
|
13946
14338
|
const sectionColumn = getValueByIdx(template, sectionColumnIdx);
|
|
13947
14339
|
return sectionColumn?.data?.value?.columnWidths || [];
|
|
13948
14340
|
}, [template, sectionColumnIdx]);
|
|
13949
|
-
const dragRef =
|
|
13950
|
-
const updateColumnRects =
|
|
14341
|
+
const dragRef = useRef10(null);
|
|
14342
|
+
const updateColumnRects = useCallback16(() => {
|
|
13951
14343
|
if (!shadowRoot) return;
|
|
13952
14344
|
const allColumns = shadowRoot.querySelectorAll(".node-type-column");
|
|
13953
14345
|
const matchingColumns = [];
|
|
@@ -13979,7 +14371,7 @@ var ColumnScale = ({ sectionColumnIdx, shadowRoot }) => {
|
|
|
13979
14371
|
});
|
|
13980
14372
|
setColumnRects(rects);
|
|
13981
14373
|
}, [shadowRoot, sectionColumnIdx]);
|
|
13982
|
-
|
|
14374
|
+
useEffect18(() => {
|
|
13983
14375
|
updateColumnRects();
|
|
13984
14376
|
let animationId;
|
|
13985
14377
|
const updateLoop = () => {
|
|
@@ -13992,7 +14384,7 @@ var ColumnScale = ({ sectionColumnIdx, shadowRoot }) => {
|
|
|
13992
14384
|
const parseWidth = (width) => {
|
|
13993
14385
|
return parseFloat(width.replace("%", ""));
|
|
13994
14386
|
};
|
|
13995
|
-
const handlePointerDown =
|
|
14387
|
+
const handlePointerDown = useCallback16((e, dividerIndex) => {
|
|
13996
14388
|
e.preventDefault();
|
|
13997
14389
|
e.stopPropagation();
|
|
13998
14390
|
stopTextEditing();
|
|
@@ -14018,7 +14410,7 @@ var ColumnScale = ({ sectionColumnIdx, shadowRoot }) => {
|
|
|
14018
14410
|
document.addEventListener("pointermove", handlePointerMove);
|
|
14019
14411
|
document.addEventListener("pointerup", handlePointerUp);
|
|
14020
14412
|
}, [columnRects, columnWidths, setIsScaling]);
|
|
14021
|
-
const handlePointerMove =
|
|
14413
|
+
const handlePointerMove = useCallback16((e) => {
|
|
14022
14414
|
if (!dragRef.current) return;
|
|
14023
14415
|
const { startX, leftColIndex, rightColIndex, startLeftWidth, startRightWidth, sectionWidth, allWidths } = dragRef.current;
|
|
14024
14416
|
const deltaX = e.clientX - startX;
|
|
@@ -14052,14 +14444,14 @@ var ColumnScale = ({ sectionColumnIdx, shadowRoot }) => {
|
|
|
14052
14444
|
}
|
|
14053
14445
|
});
|
|
14054
14446
|
}, [sectionColumnIdx]);
|
|
14055
|
-
const handlePointerUp =
|
|
14447
|
+
const handlePointerUp = useCallback16(() => {
|
|
14056
14448
|
setActiveDivider(null);
|
|
14057
14449
|
setIsScaling(false);
|
|
14058
14450
|
dragRef.current = null;
|
|
14059
14451
|
document.removeEventListener("pointermove", handlePointerMove);
|
|
14060
14452
|
document.removeEventListener("pointerup", handlePointerUp);
|
|
14061
14453
|
}, [handlePointerMove, setIsScaling]);
|
|
14062
|
-
|
|
14454
|
+
useEffect18(() => {
|
|
14063
14455
|
return () => {
|
|
14064
14456
|
document.removeEventListener("pointermove", handlePointerMove);
|
|
14065
14457
|
document.removeEventListener("pointerup", handlePointerUp);
|
|
@@ -14070,7 +14462,7 @@ var ColumnScale = ({ sectionColumnIdx, shadowRoot }) => {
|
|
|
14070
14462
|
}
|
|
14071
14463
|
const handleBaseClass = "bg-background shadow-md border rounded-full touch-none select-none pointer-events-auto";
|
|
14072
14464
|
const getHandleActiveClass = (index) => activeDivider === index ? "bg-blue-400 border-blue-300" : "hover:bg-blue-400 hover:border-blue-300";
|
|
14073
|
-
return /* @__PURE__ */
|
|
14465
|
+
return /* @__PURE__ */ jsx47(Fragment17, { children: columnRects.slice(0, -1).map((rect, index) => {
|
|
14074
14466
|
const nextRect = columnRects[index + 1];
|
|
14075
14467
|
const handleLeft = rect.right;
|
|
14076
14468
|
const handleTop = Math.min(rect.top, nextRect.top);
|
|
@@ -14078,7 +14470,7 @@ var ColumnScale = ({ sectionColumnIdx, shadowRoot }) => {
|
|
|
14078
14470
|
if (activeDivider !== null && activeDivider !== index) {
|
|
14079
14471
|
return null;
|
|
14080
14472
|
}
|
|
14081
|
-
return /* @__PURE__ */
|
|
14473
|
+
return /* @__PURE__ */ jsx47(
|
|
14082
14474
|
"div",
|
|
14083
14475
|
{
|
|
14084
14476
|
onPointerDown: (e) => handlePointerDown(e, index),
|
|
@@ -14098,9 +14490,9 @@ var ColumnScale = ({ sectionColumnIdx, shadowRoot }) => {
|
|
|
14098
14490
|
};
|
|
14099
14491
|
|
|
14100
14492
|
// src/core/editor/hooks/use-undo-redo-keyboard.ts
|
|
14101
|
-
import { useEffect as
|
|
14493
|
+
import { useEffect as useEffect19 } from "react";
|
|
14102
14494
|
function useUndoRedoKeyboard() {
|
|
14103
|
-
|
|
14495
|
+
useEffect19(() => {
|
|
14104
14496
|
const handler = (e) => {
|
|
14105
14497
|
const isMeta = e.metaKey || e.ctrlKey;
|
|
14106
14498
|
if (!isMeta || e.key.toLowerCase() !== "z") return;
|
|
@@ -14122,9 +14514,9 @@ function useUndoRedoKeyboard() {
|
|
|
14122
14514
|
|
|
14123
14515
|
// src/components/ui/spinner.tsx
|
|
14124
14516
|
import { Loader2Icon as Loader2Icon2 } from "lucide-react";
|
|
14125
|
-
import { jsx as
|
|
14517
|
+
import { jsx as jsx48 } from "react/jsx-runtime";
|
|
14126
14518
|
function Spinner({ className, ...props }) {
|
|
14127
|
-
return /* @__PURE__ */
|
|
14519
|
+
return /* @__PURE__ */ jsx48(
|
|
14128
14520
|
Loader2Icon2,
|
|
14129
14521
|
{
|
|
14130
14522
|
role: "status",
|
|
@@ -14136,10 +14528,10 @@ function Spinner({ className, ...props }) {
|
|
|
14136
14528
|
}
|
|
14137
14529
|
|
|
14138
14530
|
// src/core/editor/components/preview.tsx
|
|
14139
|
-
import { EyeIcon } from "lucide-react";
|
|
14531
|
+
import { EyeIcon, SendIcon, Monitor, Smartphone } from "lucide-react";
|
|
14140
14532
|
|
|
14141
14533
|
// src/render/useMjmlCompiler.ts
|
|
14142
|
-
import { useState as
|
|
14534
|
+
import { useState as useState15, useCallback as useCallback17 } from "react";
|
|
14143
14535
|
async function compileMjml(mjml) {
|
|
14144
14536
|
console.log("Compiling MJML", mjml);
|
|
14145
14537
|
const response = await fetch("/api/mrender", {
|
|
@@ -14156,14 +14548,101 @@ async function compileMjml(mjml) {
|
|
|
14156
14548
|
}
|
|
14157
14549
|
|
|
14158
14550
|
// src/core/editor/components/preview.tsx
|
|
14159
|
-
import { useEffect as
|
|
14160
|
-
|
|
14551
|
+
import { useEffect as useEffect20, useState as useState16, useRef as useRef11 } from "react";
|
|
14552
|
+
|
|
14553
|
+
// src/validate/helpers.ts
|
|
14554
|
+
var MERGE_FIELD_REGEX2 = /\{\{([a-zA-Z_][a-zA-Z0-9_]*)\}\}/g;
|
|
14555
|
+
function extractMergeFields(node) {
|
|
14556
|
+
const fields = [];
|
|
14557
|
+
if (!node || typeof node !== "object") return fields;
|
|
14558
|
+
const content = node?.data?.value?.content;
|
|
14559
|
+
if (typeof content === "string") {
|
|
14560
|
+
let match;
|
|
14561
|
+
MERGE_FIELD_REGEX2.lastIndex = 0;
|
|
14562
|
+
while ((match = MERGE_FIELD_REGEX2.exec(content)) !== null) {
|
|
14563
|
+
fields.push(match[1]);
|
|
14564
|
+
}
|
|
14565
|
+
}
|
|
14566
|
+
if (Array.isArray(node.children)) {
|
|
14567
|
+
for (const child of node.children) {
|
|
14568
|
+
fields.push(...extractMergeFields(child));
|
|
14569
|
+
}
|
|
14570
|
+
}
|
|
14571
|
+
if (Array.isArray(node.content)) {
|
|
14572
|
+
for (const page of node.content) {
|
|
14573
|
+
fields.push(...extractMergeFields(page));
|
|
14574
|
+
}
|
|
14575
|
+
}
|
|
14576
|
+
return fields;
|
|
14577
|
+
}
|
|
14578
|
+
function extractEmptyLinks(node) {
|
|
14579
|
+
const results = [];
|
|
14580
|
+
if (!node || typeof node !== "object") return results;
|
|
14581
|
+
if (node.type === "button" || node.type === "social-item") {
|
|
14582
|
+
const href = node.attributes?.href;
|
|
14583
|
+
if (!href || href.trim() === "") {
|
|
14584
|
+
const label = node.type === "button" ? node.data?.value?.content || "Untitled Button" : node.attributes?.alt || node.data?.value?.socialType || "Social Link";
|
|
14585
|
+
results.push({ type: node.type, label });
|
|
14586
|
+
}
|
|
14587
|
+
}
|
|
14588
|
+
if (Array.isArray(node.children)) {
|
|
14589
|
+
for (const child of node.children) {
|
|
14590
|
+
results.push(...extractEmptyLinks(child));
|
|
14591
|
+
}
|
|
14592
|
+
}
|
|
14593
|
+
if (Array.isArray(node.content)) {
|
|
14594
|
+
for (const page of node.content) {
|
|
14595
|
+
results.push(...extractEmptyLinks(page));
|
|
14596
|
+
}
|
|
14597
|
+
}
|
|
14598
|
+
return results;
|
|
14599
|
+
}
|
|
14600
|
+
|
|
14601
|
+
// src/validate/index.ts
|
|
14602
|
+
var PROPERTY_CARD_TYPES = /* @__PURE__ */ new Set(["property-card", "property-card-single-two", "property-card-triple-item"]);
|
|
14603
|
+
function countPlaceholderPropertyImages(node) {
|
|
14604
|
+
let count = 0;
|
|
14605
|
+
if (!node || typeof node !== "object") return count;
|
|
14606
|
+
if (PROPERTY_CARD_TYPES.has(node.type)) {
|
|
14607
|
+
const imageSrc = node.attributes?.["image-src"];
|
|
14608
|
+
if (!imageSrc || imageSrc === DEFAULT_PROPERTY_PLACEHOLDER_IMAGE) {
|
|
14609
|
+
count++;
|
|
14610
|
+
}
|
|
14611
|
+
}
|
|
14612
|
+
if (Array.isArray(node.children)) {
|
|
14613
|
+
for (const child of node.children) {
|
|
14614
|
+
count += countPlaceholderPropertyImages(child);
|
|
14615
|
+
}
|
|
14616
|
+
}
|
|
14617
|
+
if (Array.isArray(node.content)) {
|
|
14618
|
+
for (const page of node.content) {
|
|
14619
|
+
count += countPlaceholderPropertyImages(page);
|
|
14620
|
+
}
|
|
14621
|
+
}
|
|
14622
|
+
return count;
|
|
14623
|
+
}
|
|
14624
|
+
function validate_editor_onPreview(template, mergeFields) {
|
|
14625
|
+
const usedFields = [...new Set(extractMergeFields(template))];
|
|
14626
|
+
const validValues = new Set(mergeFields.map((f) => f.value));
|
|
14627
|
+
const invalid_merge_fields = usedFields.filter((field) => !validValues.has(field));
|
|
14628
|
+
const missing_links = extractEmptyLinks(template);
|
|
14629
|
+
const placeholder_property_images = countPlaceholderPropertyImages(template);
|
|
14630
|
+
const templateSize = new Blob([JSON.stringify(template)]).size;
|
|
14631
|
+
const is_over_size_limit = templateSize > 50 * 1024;
|
|
14632
|
+
return { invalid_merge_fields, missing_links, is_over_size_limit, placeholder_property_images };
|
|
14633
|
+
}
|
|
14634
|
+
|
|
14635
|
+
// src/core/editor/components/preview.tsx
|
|
14636
|
+
import { jsx as jsx49, jsxs as jsxs30 } from "react/jsx-runtime";
|
|
14161
14637
|
function Preview() {
|
|
14162
|
-
const { template, setPreviewMode, previewMode, isPaidLevel } = useEditorStore();
|
|
14163
|
-
const [html, setHtml] =
|
|
14164
|
-
const [isLoading, setIsLoading] =
|
|
14165
|
-
const lastTemplateRef =
|
|
14166
|
-
|
|
14638
|
+
const { template, setPreviewMode, previewMode, isPaidLevel, mergeFields } = useEditorStore();
|
|
14639
|
+
const [html, setHtml] = useState16("");
|
|
14640
|
+
const [isLoading, setIsLoading] = useState16(false);
|
|
14641
|
+
const lastTemplateRef = useRef11("");
|
|
14642
|
+
const [deviceMode, setDeviceMode] = useState16("desktop");
|
|
14643
|
+
const [preview_validations, setPreviewValidations] = useState16({ invalid_merge_fields: [], missing_links: [], is_over_size_limit: false, placeholder_property_images: 0 });
|
|
14644
|
+
const [mjmlErrors, setMjmlErrors] = useState16([]);
|
|
14645
|
+
useEffect20(() => {
|
|
14167
14646
|
if (typeof window === "undefined" || !previewMode) {
|
|
14168
14647
|
if (!previewMode) {
|
|
14169
14648
|
setHtml("");
|
|
@@ -14177,56 +14656,165 @@ function Preview() {
|
|
|
14177
14656
|
}
|
|
14178
14657
|
lastTemplateRef.current = templateString;
|
|
14179
14658
|
setIsLoading(true);
|
|
14659
|
+
const validatePreview = () => {
|
|
14660
|
+
const validations = validate_editor_onPreview(template, mergeFields);
|
|
14661
|
+
setPreviewValidations(validations);
|
|
14662
|
+
};
|
|
14180
14663
|
const convertMjml = async () => {
|
|
14181
14664
|
try {
|
|
14182
14665
|
const mjmlString = json2mjml(template, "production", { isPaidLevel });
|
|
14183
14666
|
console.log("MJML string:", mjmlString);
|
|
14184
14667
|
const result = await compileMjml(mjmlString);
|
|
14668
|
+
console.log("MJML errors:", result);
|
|
14669
|
+
setMjmlErrors(result.errors ?? []);
|
|
14185
14670
|
if (result.errors?.length > 0) {
|
|
14186
|
-
console.warn("MJML warnings:", result.errors);
|
|
14671
|
+
console.warn("MJML warnings 1:", result.errors);
|
|
14187
14672
|
}
|
|
14188
14673
|
console.log(result.html);
|
|
14189
14674
|
setHtml(result.html);
|
|
14190
14675
|
} catch (error) {
|
|
14191
14676
|
console.error("MJML compilation error:", error);
|
|
14677
|
+
setMjmlErrors([]);
|
|
14192
14678
|
setHtml('<p style="color: red; padding: 20px;">Error generating preview</p>');
|
|
14193
14679
|
} finally {
|
|
14194
14680
|
setIsLoading(false);
|
|
14195
14681
|
}
|
|
14196
14682
|
};
|
|
14683
|
+
validatePreview();
|
|
14197
14684
|
convertMjml();
|
|
14198
14685
|
}, [template, previewMode]);
|
|
14199
|
-
|
|
14200
|
-
|
|
14201
|
-
|
|
14686
|
+
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;
|
|
14687
|
+
return /* @__PURE__ */ jsxs30(Dialog, { open: previewMode, onOpenChange: setPreviewMode, children: [
|
|
14688
|
+
/* @__PURE__ */ jsxs30(Tooltip, { children: [
|
|
14689
|
+
/* @__PURE__ */ jsx49(TooltipTrigger, { asChild: true, children: /* @__PURE__ */ jsx49(
|
|
14202
14690
|
Button,
|
|
14203
14691
|
{
|
|
14204
14692
|
variant: "ghost",
|
|
14205
14693
|
className: "shadow-none transition-none cursor-pointer",
|
|
14206
14694
|
size: "icon",
|
|
14207
14695
|
onClick: () => setPreviewMode(true),
|
|
14208
|
-
children: /* @__PURE__ */
|
|
14696
|
+
children: /* @__PURE__ */ jsx49(EyeIcon, {})
|
|
14209
14697
|
}
|
|
14210
14698
|
) }),
|
|
14211
|
-
/* @__PURE__ */
|
|
14699
|
+
/* @__PURE__ */ jsx49(TooltipContent, { side: "bottom", className: "z-51", children: "Preview" })
|
|
14212
14700
|
] }),
|
|
14213
|
-
/* @__PURE__ */
|
|
14214
|
-
|
|
14215
|
-
|
|
14216
|
-
|
|
14701
|
+
/* @__PURE__ */ jsxs30(
|
|
14702
|
+
DialogContent,
|
|
14703
|
+
{
|
|
14704
|
+
showCloseButton: true,
|
|
14705
|
+
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",
|
|
14706
|
+
children: [
|
|
14707
|
+
/* @__PURE__ */ jsx49(DialogHeader, { className: "border-b p-4", children: /* @__PURE__ */ jsx49(DialogTitle, { children: "Preview" }) }),
|
|
14708
|
+
/* @__PURE__ */ jsxs30("div", { className: "flex gap-2 justify-between border-b p-4", children: [
|
|
14709
|
+
/* @__PURE__ */ jsx49("div", { className: "flex gap-2", children: /* @__PURE__ */ jsxs30(Button, { variant: "ghost", onClick: () => {
|
|
14710
|
+
}, children: [
|
|
14711
|
+
/* @__PURE__ */ jsx49(SendIcon, { className: "w-4 h-4" }),
|
|
14712
|
+
"Send a Test Email"
|
|
14713
|
+
] }) }),
|
|
14714
|
+
/* @__PURE__ */ jsxs30("div", { className: "flex gap-2", children: [
|
|
14715
|
+
/* @__PURE__ */ jsxs30(
|
|
14716
|
+
Button,
|
|
14717
|
+
{
|
|
14718
|
+
variant: deviceMode === "desktop" ? "default" : "ghost",
|
|
14719
|
+
onClick: () => setDeviceMode("desktop"),
|
|
14720
|
+
className: "gap-2 cursor-pointer",
|
|
14721
|
+
children: [
|
|
14722
|
+
/* @__PURE__ */ jsx49(Monitor, { className: "w-4 h-4" }),
|
|
14723
|
+
"Desktop"
|
|
14724
|
+
]
|
|
14725
|
+
}
|
|
14726
|
+
),
|
|
14727
|
+
/* @__PURE__ */ jsxs30(
|
|
14728
|
+
Button,
|
|
14729
|
+
{
|
|
14730
|
+
variant: deviceMode === "mobile" ? "default" : "ghost",
|
|
14731
|
+
onClick: () => setDeviceMode("mobile"),
|
|
14732
|
+
className: "gap-2 cursor-pointer",
|
|
14733
|
+
children: [
|
|
14734
|
+
/* @__PURE__ */ jsx49(Smartphone, { className: "w-4 h-4" }),
|
|
14735
|
+
"Mobile"
|
|
14736
|
+
]
|
|
14737
|
+
}
|
|
14738
|
+
)
|
|
14739
|
+
] })
|
|
14740
|
+
] }),
|
|
14741
|
+
/* @__PURE__ */ jsxs30("div", { className: "flex flex-1 overflow-hidden", children: [
|
|
14742
|
+
/* @__PURE__ */ jsx49(
|
|
14743
|
+
"div",
|
|
14744
|
+
{
|
|
14745
|
+
className: "flex-1 flex items-start justify-center overflow-auto w-full",
|
|
14746
|
+
style: { backgroundColor: template?.content?.[0]?.attributes?.["background-color"] || "#965D5D" },
|
|
14747
|
+
children: isLoading ? /* @__PURE__ */ jsx49("div", { className: "flex items-center justify-center h-full w-full", children: /* @__PURE__ */ jsx49("p", { children: "Generating preview..." }) }) : /* @__PURE__ */ jsx49(
|
|
14748
|
+
"div",
|
|
14749
|
+
{
|
|
14750
|
+
className: "flex items-center justify-center bg-white transition-all duration-300 h-full w-full",
|
|
14751
|
+
children: /* @__PURE__ */ jsx49(
|
|
14752
|
+
"iframe",
|
|
14753
|
+
{
|
|
14754
|
+
srcDoc: html,
|
|
14755
|
+
className: "w-full border-0 transition-all duration-200",
|
|
14756
|
+
style: { height: "100%", minHeight: "600px", width: deviceMode === "desktop" ? "100%" : "360px", maxWidth: deviceMode === "desktop" ? "100%" : "360px" },
|
|
14757
|
+
title: "Email Preview",
|
|
14758
|
+
sandbox: "allow-same-origin"
|
|
14759
|
+
}
|
|
14760
|
+
)
|
|
14761
|
+
}
|
|
14762
|
+
)
|
|
14763
|
+
}
|
|
14764
|
+
),
|
|
14765
|
+
hasValidations && /* @__PURE__ */ jsxs30("div", { className: "w-[300px] border-l p-4 overflow-y-auto flex flex-col gap-4", children: [
|
|
14766
|
+
mjmlErrors.length > 0 && /* @__PURE__ */ jsxs30("div", { className: "w-full rounded-md border border-red-600 p-2", children: [
|
|
14767
|
+
/* @__PURE__ */ jsx49("h3", { className: "text-sm font-semibold text-red-600", children: "MJML Errors" }),
|
|
14768
|
+
/* @__PURE__ */ jsx49("p", { className: "text-sm mt-1 text-red-600", children: "The following errors occurred during email compilation:" }),
|
|
14769
|
+
/* @__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: [
|
|
14770
|
+
/* @__PURE__ */ jsx49("span", { className: "font-semibold", children: err.tagName }),
|
|
14771
|
+
" (line ",
|
|
14772
|
+
err.line,
|
|
14773
|
+
"): ",
|
|
14774
|
+
err.message
|
|
14775
|
+
] }, i)) }),
|
|
14776
|
+
/* @__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." })
|
|
14777
|
+
] }),
|
|
14778
|
+
preview_validations.is_over_size_limit && /* @__PURE__ */ jsxs30("div", { className: "w-full rounded-md border border-red-300 p-2", children: [
|
|
14779
|
+
/* @__PURE__ */ jsx49("h3", { className: "text-sm font-semibold text-red-600", children: "Template Too Large" }),
|
|
14780
|
+
/* @__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." })
|
|
14781
|
+
] }),
|
|
14782
|
+
preview_validations.placeholder_property_images > 0 && /* @__PURE__ */ jsxs30("div", { className: "w-full rounded-md border p-2", children: [
|
|
14783
|
+
/* @__PURE__ */ jsx49("h3", { className: "text-sm font-semibold", children: "Placeholder Property Image" }),
|
|
14784
|
+
/* @__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.` })
|
|
14785
|
+
] }),
|
|
14786
|
+
preview_validations.invalid_merge_fields.length > 0 && /* @__PURE__ */ jsxs30("div", { className: "w-full rounded-md border p-2", children: [
|
|
14787
|
+
/* @__PURE__ */ jsx49("h3", { className: "text-sm font-semibold", children: "Invalid Merge Fields" }),
|
|
14788
|
+
/* @__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:" }),
|
|
14789
|
+
/* @__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)) })
|
|
14790
|
+
] }),
|
|
14791
|
+
preview_validations.missing_links.length > 0 && /* @__PURE__ */ jsxs30("div", { className: "w-full rounded-md border p-2", children: [
|
|
14792
|
+
/* @__PURE__ */ jsx49("h3", { className: "text-sm font-semibold", children: "Missing Links" }),
|
|
14793
|
+
/* @__PURE__ */ jsx49("p", { className: "text-sm mt-1", children: "The following elements have no link set:" }),
|
|
14794
|
+
/* @__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: [
|
|
14795
|
+
item.type === "button" ? "Button" : "Social",
|
|
14796
|
+
": ",
|
|
14797
|
+
item.label
|
|
14798
|
+
] }, i)) })
|
|
14799
|
+
] })
|
|
14800
|
+
] })
|
|
14801
|
+
] })
|
|
14802
|
+
]
|
|
14803
|
+
}
|
|
14804
|
+
)
|
|
14217
14805
|
] });
|
|
14218
14806
|
}
|
|
14219
14807
|
|
|
14220
14808
|
// src/core/editor/components/history.tsx
|
|
14221
14809
|
import { Redo2Icon, Undo2Icon } from "lucide-react";
|
|
14222
|
-
import { Fragment as Fragment18, jsx as
|
|
14810
|
+
import { Fragment as Fragment18, jsx as jsx50, jsxs as jsxs31 } from "react/jsx-runtime";
|
|
14223
14811
|
var History = () => {
|
|
14224
14812
|
const { undo, redo } = useEditorStore();
|
|
14225
14813
|
const canUndo = useEditorStore((s) => s.historyIndex > 0);
|
|
14226
14814
|
const canRedo = useEditorStore((s) => s.historyIndex < s.history.length - 1);
|
|
14227
|
-
return /* @__PURE__ */
|
|
14228
|
-
/* @__PURE__ */
|
|
14229
|
-
/* @__PURE__ */
|
|
14815
|
+
return /* @__PURE__ */ jsxs31(Fragment18, { children: [
|
|
14816
|
+
/* @__PURE__ */ jsxs31(Tooltip, { children: [
|
|
14817
|
+
/* @__PURE__ */ jsx50(TooltipTrigger, { asChild: true, children: /* @__PURE__ */ jsx50(
|
|
14230
14818
|
Button,
|
|
14231
14819
|
{
|
|
14232
14820
|
variant: "ghost",
|
|
@@ -14234,13 +14822,13 @@ var History = () => {
|
|
|
14234
14822
|
size: "icon",
|
|
14235
14823
|
disabled: !canUndo,
|
|
14236
14824
|
onClick: undo,
|
|
14237
|
-
children: /* @__PURE__ */
|
|
14825
|
+
children: /* @__PURE__ */ jsx50(Undo2Icon, {})
|
|
14238
14826
|
}
|
|
14239
14827
|
) }),
|
|
14240
|
-
/* @__PURE__ */
|
|
14828
|
+
/* @__PURE__ */ jsx50(TooltipContent, { side: "bottom", children: "Undo (Ctrl+Z)" })
|
|
14241
14829
|
] }),
|
|
14242
|
-
/* @__PURE__ */
|
|
14243
|
-
/* @__PURE__ */
|
|
14830
|
+
/* @__PURE__ */ jsxs31(Tooltip, { children: [
|
|
14831
|
+
/* @__PURE__ */ jsx50(TooltipTrigger, { asChild: true, children: /* @__PURE__ */ jsx50(
|
|
14244
14832
|
Button,
|
|
14245
14833
|
{
|
|
14246
14834
|
variant: "ghost",
|
|
@@ -14248,16 +14836,16 @@ var History = () => {
|
|
|
14248
14836
|
size: "icon",
|
|
14249
14837
|
disabled: !canRedo,
|
|
14250
14838
|
onClick: redo,
|
|
14251
|
-
children: /* @__PURE__ */
|
|
14839
|
+
children: /* @__PURE__ */ jsx50(Redo2Icon, {})
|
|
14252
14840
|
}
|
|
14253
14841
|
) }),
|
|
14254
|
-
/* @__PURE__ */
|
|
14842
|
+
/* @__PURE__ */ jsx50(TooltipContent, { side: "bottom", children: "Redo (Ctrl+Shift+Z)" })
|
|
14255
14843
|
] })
|
|
14256
14844
|
] });
|
|
14257
14845
|
};
|
|
14258
14846
|
|
|
14259
14847
|
// src/core/index.tsx
|
|
14260
|
-
import { jsx as
|
|
14848
|
+
import { jsx as jsx51, jsxs as jsxs32 } from "react/jsx-runtime";
|
|
14261
14849
|
var MAILLOW_EMAIL_EDITOR_VERSION = "0.0.1";
|
|
14262
14850
|
function getSectionColumnIdx(idx, template) {
|
|
14263
14851
|
let current = idx;
|
|
@@ -14293,6 +14881,20 @@ function getCompanyFooterSection(template) {
|
|
|
14293
14881
|
}
|
|
14294
14882
|
return null;
|
|
14295
14883
|
}
|
|
14884
|
+
function restoreImagePreview(shadowRoot, targetIdx, originalSrc) {
|
|
14885
|
+
const targetEl = shadowRoot.querySelector(`.node-idx-${CSS.escape(targetIdx)}`);
|
|
14886
|
+
if (!targetEl) return;
|
|
14887
|
+
const bgEl = targetEl.querySelector("td[background], th[background]");
|
|
14888
|
+
if (bgEl) {
|
|
14889
|
+
bgEl.setAttribute("background", originalSrc);
|
|
14890
|
+
bgEl.style.backgroundImage = `url(${originalSrc})`;
|
|
14891
|
+
return;
|
|
14892
|
+
}
|
|
14893
|
+
const img = targetEl.querySelector("img");
|
|
14894
|
+
if (img) {
|
|
14895
|
+
img.src = originalSrc;
|
|
14896
|
+
}
|
|
14897
|
+
}
|
|
14296
14898
|
function Editor({ setEditorLoading }) {
|
|
14297
14899
|
useUndoRedoKeyboard();
|
|
14298
14900
|
const template = useEditorStore((state) => state.template);
|
|
@@ -14323,29 +14925,31 @@ function Editor({ setEditorLoading }) {
|
|
|
14323
14925
|
const startTextEditing = useEditorStore((state) => state.startTextEditing);
|
|
14324
14926
|
const pendingTextEditRequest = useEditorStore((state) => state.pendingTextEditRequest);
|
|
14325
14927
|
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
|
-
|
|
14928
|
+
const [renderData, setRenderData] = useState17(null);
|
|
14929
|
+
const [isEditing, setIsEditing] = useState17(false);
|
|
14930
|
+
const [dropIndicator, setDropIndicator] = useState17(null);
|
|
14931
|
+
const [dropTargetIdx, setDropTargetIdx] = useState17(null);
|
|
14932
|
+
const shadowRootRef = useRef12(null);
|
|
14933
|
+
const [hasSelectedElement, setHasSelectedElement] = useState17(false);
|
|
14934
|
+
const dragParentIdxRef = useRef12(null);
|
|
14935
|
+
const dragPositionIndexRef = useRef12(0);
|
|
14936
|
+
const createNewSectionRef = useRef12(false);
|
|
14937
|
+
const splitAtParagraphRef = useRef12(null);
|
|
14938
|
+
const isHorizontalDropRef = useRef12(false);
|
|
14939
|
+
const horizontalDropPositionRef = useRef12(null);
|
|
14940
|
+
const isSplitSectionDropRef = useRef12(false);
|
|
14941
|
+
const splitSectionAtElementRef = useRef12(null);
|
|
14942
|
+
const templateCacheRef = useRef12(null);
|
|
14943
|
+
const parentSectionCacheRef = useRef12(/* @__PURE__ */ new Map());
|
|
14944
|
+
const sectionElementCacheRef = useRef12(/* @__PURE__ */ new Map());
|
|
14945
|
+
const sectionRectCacheRef = useRef12(/* @__PURE__ */ new Map());
|
|
14946
|
+
const companyFooterCacheRef = useRef12(void 0);
|
|
14947
|
+
const lastSyncedTemplateRef = useRef12(null);
|
|
14948
|
+
const prevTextEditingIdxRef = useRef12(null);
|
|
14949
|
+
const lastRenderSyncNeededRef = useRef12(0);
|
|
14950
|
+
const imageReplaceTargetRef = useRef12(null);
|
|
14951
|
+
const imagePreviewOriginalSrcRef = useRef12(null);
|
|
14952
|
+
useEffect21(() => {
|
|
14349
14953
|
const currentIdx = textEditing?.idx ?? null;
|
|
14350
14954
|
const prevIdx = prevTextEditingIdxRef.current;
|
|
14351
14955
|
const switchedTarget = currentIdx !== null && prevIdx !== null && currentIdx !== prevIdx;
|
|
@@ -14364,12 +14968,12 @@ function Editor({ setEditorLoading }) {
|
|
|
14364
14968
|
lastSyncedTemplateRef.current = template;
|
|
14365
14969
|
}
|
|
14366
14970
|
}, [template, renderData, isEditing, textEditing, renderSyncNeeded]);
|
|
14367
|
-
|
|
14971
|
+
useEffect21(() => {
|
|
14368
14972
|
if (renderData && setEditorLoading) {
|
|
14369
14973
|
setEditorLoading(false);
|
|
14370
14974
|
}
|
|
14371
14975
|
}, [renderData, setEditorLoading]);
|
|
14372
|
-
|
|
14976
|
+
useEffect21(() => {
|
|
14373
14977
|
if (!pendingTextEditRequest || !shadowRootRef.current) return;
|
|
14374
14978
|
const { idx, cursorPosition } = pendingTextEditRequest;
|
|
14375
14979
|
const blockNode = shadowRootRef.current.querySelector(`.node-idx-${CSS.escape(idx)}`);
|
|
@@ -14418,7 +15022,7 @@ function Editor({ setEditorLoading }) {
|
|
|
14418
15022
|
startTextEditing({ idx, getReferenceRect: getReferenceRect2, getShadowElement, initialWidth: blockRect.width, initialHeight: blockRect.height, clickX, clickY, content, styles, cursorPosition });
|
|
14419
15023
|
clearPendingTextEditRequest();
|
|
14420
15024
|
}, [pendingTextEditRequest, clearPendingTextEditRequest, startTextEditing]);
|
|
14421
|
-
|
|
15025
|
+
useEffect21(() => {
|
|
14422
15026
|
if (isDragging && dataTransfer) {
|
|
14423
15027
|
const currentTemplate = useEditorStore.getState().template;
|
|
14424
15028
|
templateCacheRef.current = currentTemplate;
|
|
@@ -14434,9 +15038,9 @@ function Editor({ setEditorLoading }) {
|
|
|
14434
15038
|
sectionRectCacheRef.current.clear();
|
|
14435
15039
|
}
|
|
14436
15040
|
}, [isDragging, dataTransfer]);
|
|
14437
|
-
const [html, setHtml] =
|
|
14438
|
-
const lastRenderDataRef =
|
|
14439
|
-
|
|
15041
|
+
const [html, setHtml] = useState17("");
|
|
15042
|
+
const lastRenderDataRef = useRef12("");
|
|
15043
|
+
useEffect21(() => {
|
|
14440
15044
|
if (typeof window === "undefined" || !renderData) {
|
|
14441
15045
|
setHtml("");
|
|
14442
15046
|
lastRenderDataRef.current = "";
|
|
@@ -14463,13 +15067,13 @@ function Editor({ setEditorLoading }) {
|
|
|
14463
15067
|
};
|
|
14464
15068
|
convertMjml();
|
|
14465
15069
|
}, [renderData]);
|
|
14466
|
-
const debouncedUpdateContent =
|
|
15070
|
+
const debouncedUpdateContent = useMemo18(
|
|
14467
15071
|
() => debounce((contentIdx, content) => {
|
|
14468
15072
|
updateElementContent(contentIdx, content);
|
|
14469
15073
|
}, 200),
|
|
14470
15074
|
[updateElementContent]
|
|
14471
15075
|
);
|
|
14472
|
-
const handleElementClick =
|
|
15076
|
+
const handleElementClick = useCallback18(
|
|
14473
15077
|
(idx) => {
|
|
14474
15078
|
if (isInsideCompanyFooter(idx, template)) {
|
|
14475
15079
|
return;
|
|
@@ -14482,7 +15086,7 @@ function Editor({ setEditorLoading }) {
|
|
|
14482
15086
|
},
|
|
14483
15087
|
[setFocusIdx, template]
|
|
14484
15088
|
);
|
|
14485
|
-
const handleElementHover =
|
|
15089
|
+
const handleElementHover = useCallback18(
|
|
14486
15090
|
(idx) => {
|
|
14487
15091
|
if (!isDragging) {
|
|
14488
15092
|
if (idx) {
|
|
@@ -14496,19 +15100,19 @@ function Editor({ setEditorLoading }) {
|
|
|
14496
15100
|
},
|
|
14497
15101
|
[isDragging, setHoverIdx, template]
|
|
14498
15102
|
);
|
|
14499
|
-
const handleContentInput =
|
|
15103
|
+
const handleContentInput = useCallback18(
|
|
14500
15104
|
(contentIdx, content) => {
|
|
14501
15105
|
debouncedUpdateContent(contentIdx, content);
|
|
14502
15106
|
},
|
|
14503
15107
|
[debouncedUpdateContent]
|
|
14504
15108
|
);
|
|
14505
|
-
const handleEditingStart =
|
|
15109
|
+
const handleEditingStart = useCallback18(() => {
|
|
14506
15110
|
setIsEditing(true);
|
|
14507
15111
|
}, []);
|
|
14508
|
-
const handleEditingEnd =
|
|
15112
|
+
const handleEditingEnd = useCallback18(() => {
|
|
14509
15113
|
setIsEditing(false);
|
|
14510
15114
|
}, []);
|
|
14511
|
-
const handleSlashCommand =
|
|
15115
|
+
const handleSlashCommand = useCallback18(
|
|
14512
15116
|
(cursorRect) => {
|
|
14513
15117
|
setSlashCommand({
|
|
14514
15118
|
isActive: true,
|
|
@@ -14523,10 +15127,10 @@ function Editor({ setEditorLoading }) {
|
|
|
14523
15127
|
},
|
|
14524
15128
|
[setSlashCommand]
|
|
14525
15129
|
);
|
|
14526
|
-
const handleSlashCommandClose =
|
|
15130
|
+
const handleSlashCommandClose = useCallback18(() => {
|
|
14527
15131
|
clearSlashCommand();
|
|
14528
15132
|
}, [clearSlashCommand]);
|
|
14529
|
-
const handleTextEditStart =
|
|
15133
|
+
const handleTextEditStart = useCallback18(
|
|
14530
15134
|
(idx, initialWidth, initialHeight, clickX, clickY, content, styles) => {
|
|
14531
15135
|
const getReferenceRect2 = () => {
|
|
14532
15136
|
if (!shadowRootRef.current) return null;
|
|
@@ -14541,11 +15145,11 @@ function Editor({ setEditorLoading }) {
|
|
|
14541
15145
|
},
|
|
14542
15146
|
[startTextEditing]
|
|
14543
15147
|
);
|
|
14544
|
-
const findParentSectionIdx =
|
|
15148
|
+
const findParentSectionIdx = useCallback18((idx) => {
|
|
14545
15149
|
const match = /^(content\.children\.\[\d+\])/.exec(idx);
|
|
14546
15150
|
return match ? match[1] : null;
|
|
14547
15151
|
}, []);
|
|
14548
|
-
const handleDragOver =
|
|
15152
|
+
const handleDragOver = useCallback18(
|
|
14549
15153
|
(_e, dragInfo) => {
|
|
14550
15154
|
const currentDataTransfer = useEditorStore.getState().dataTransfer;
|
|
14551
15155
|
if (!currentDataTransfer) return;
|
|
@@ -14554,6 +15158,11 @@ function Editor({ setEditorLoading }) {
|
|
|
14554
15158
|
setDropIndicator(null);
|
|
14555
15159
|
setDropTargetIdx(null);
|
|
14556
15160
|
splitAtParagraphRef.current = null;
|
|
15161
|
+
if (imageReplaceTargetRef.current && shadowRootRef.current && imagePreviewOriginalSrcRef.current !== null) {
|
|
15162
|
+
restoreImagePreview(shadowRootRef.current, imageReplaceTargetRef.current, imagePreviewOriginalSrcRef.current);
|
|
15163
|
+
}
|
|
15164
|
+
imageReplaceTargetRef.current = null;
|
|
15165
|
+
imagePreviewOriginalSrcRef.current = null;
|
|
14557
15166
|
return;
|
|
14558
15167
|
}
|
|
14559
15168
|
const template2 = templateCacheRef.current || useEditorStore.getState().template;
|
|
@@ -14585,21 +15194,64 @@ function Editor({ setEditorLoading }) {
|
|
|
14585
15194
|
}
|
|
14586
15195
|
}
|
|
14587
15196
|
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
|
-
|
|
15197
|
+
const isImageReplaceDrop = currentDataTransfer.type === "image" && currentDataTransfer.payload?.attributes?.src && (hoveredType === "property-card" || hoveredType === "property-card-single-two");
|
|
15198
|
+
if (!isImageReplaceDrop) {
|
|
15199
|
+
const columnIdx = hoveredType === "column" ? idx : getParentIdx(idx);
|
|
15200
|
+
if (columnIdx) {
|
|
15201
|
+
const columnParentIdx = getParentIdx(columnIdx);
|
|
15202
|
+
if (columnParentIdx) {
|
|
15203
|
+
const columnParent = getValueByIdx(template2, columnParentIdx);
|
|
15204
|
+
if (columnParent?.type === "section-property-km" || columnParent?.type === "section-property-single-two" || columnParent?.type === "section-property-triple") {
|
|
15205
|
+
setDropIndicator(null);
|
|
15206
|
+
setDropTargetIdx(null);
|
|
15207
|
+
splitAtParagraphRef.current = null;
|
|
15208
|
+
return;
|
|
15209
|
+
}
|
|
14598
15210
|
}
|
|
14599
15211
|
}
|
|
14600
15212
|
}
|
|
14601
15213
|
}
|
|
14602
15214
|
const dragType = currentDataTransfer.type;
|
|
15215
|
+
const hasImagePayload = currentDataTransfer.payload?.attributes?.src;
|
|
15216
|
+
const PROPERTY_CARD_IMAGE_TYPES = ["property-card", "property-card-single-two", "property-card-triple-item"];
|
|
15217
|
+
const isImageReplaceTarget = hoveredType === "image" || PROPERTY_CARD_IMAGE_TYPES.includes(hoveredType);
|
|
15218
|
+
if (dragType === "image" && hasImagePayload && isImageReplaceTarget) {
|
|
15219
|
+
const newSrc = currentDataTransfer.payload.attributes.src;
|
|
15220
|
+
const prevTarget = imageReplaceTargetRef.current;
|
|
15221
|
+
if (prevTarget !== idx) {
|
|
15222
|
+
if (prevTarget && imagePreviewOriginalSrcRef.current !== null && shadowRootRef.current) {
|
|
15223
|
+
restoreImagePreview(shadowRootRef.current, prevTarget, imagePreviewOriginalSrcRef.current);
|
|
15224
|
+
}
|
|
15225
|
+
if (shadowRootRef.current) {
|
|
15226
|
+
const targetEl = shadowRootRef.current.querySelector(`.node-idx-${CSS.escape(idx)}`);
|
|
15227
|
+
if (targetEl) {
|
|
15228
|
+
const img = targetEl.querySelector("img");
|
|
15229
|
+
if (img && hoveredType === "image") {
|
|
15230
|
+
imagePreviewOriginalSrcRef.current = img.src;
|
|
15231
|
+
img.src = newSrc;
|
|
15232
|
+
} else {
|
|
15233
|
+
const bgEl = targetEl.querySelector("td[background], th[background]");
|
|
15234
|
+
if (bgEl) {
|
|
15235
|
+
imagePreviewOriginalSrcRef.current = bgEl.getAttribute("background") || "";
|
|
15236
|
+
bgEl.setAttribute("background", newSrc);
|
|
15237
|
+
bgEl.style.backgroundImage = `url(${newSrc})`;
|
|
15238
|
+
}
|
|
15239
|
+
}
|
|
15240
|
+
}
|
|
15241
|
+
}
|
|
15242
|
+
imageReplaceTargetRef.current = idx;
|
|
15243
|
+
}
|
|
15244
|
+
setDropIndicator(null);
|
|
15245
|
+
setDropTargetIdx(idx);
|
|
15246
|
+
return;
|
|
15247
|
+
}
|
|
15248
|
+
if (imageReplaceTargetRef.current) {
|
|
15249
|
+
if (shadowRootRef.current && imagePreviewOriginalSrcRef.current !== null) {
|
|
15250
|
+
restoreImagePreview(shadowRootRef.current, imageReplaceTargetRef.current, imagePreviewOriginalSrcRef.current);
|
|
15251
|
+
}
|
|
15252
|
+
imageReplaceTargetRef.current = null;
|
|
15253
|
+
imagePreviewOriginalSrcRef.current = null;
|
|
15254
|
+
}
|
|
14603
15255
|
const validParents = VALID_PARENT_TYPES[dragType] || [];
|
|
14604
15256
|
let parentIdx;
|
|
14605
15257
|
let positionIndex;
|
|
@@ -14956,10 +15608,51 @@ function Editor({ setEditorLoading }) {
|
|
|
14956
15608
|
[findParentSectionIdx]
|
|
14957
15609
|
// Only dependency is the helper function
|
|
14958
15610
|
);
|
|
14959
|
-
const handleDrop =
|
|
15611
|
+
const handleDrop = useCallback18(
|
|
14960
15612
|
(_e, _dragInfo) => {
|
|
14961
15613
|
const currentDataTransfer = useEditorStore.getState().dataTransfer;
|
|
14962
15614
|
if (!currentDataTransfer) return;
|
|
15615
|
+
if (imageReplaceTargetRef.current && currentDataTransfer.payload?.attributes?.src) {
|
|
15616
|
+
const targetIdx = imageReplaceTargetRef.current;
|
|
15617
|
+
const newSrc = currentDataTransfer.payload.attributes.src;
|
|
15618
|
+
const template2 = useEditorStore.getState().template;
|
|
15619
|
+
const PROPERTY_CARD_IMAGE_TYPES = ["property-card", "property-card-single-two", "property-card-triple-item"];
|
|
15620
|
+
if (template2) {
|
|
15621
|
+
const targetElement = getValueByIdx(template2, targetIdx);
|
|
15622
|
+
if (targetElement?.type === "image") {
|
|
15623
|
+
useEditorStore.getState().updateElement(targetIdx, {
|
|
15624
|
+
attributes: { ...targetElement.attributes, src: newSrc }
|
|
15625
|
+
});
|
|
15626
|
+
useEditorStore.getState().setFocusIdx(targetIdx);
|
|
15627
|
+
} else if (targetElement && PROPERTY_CARD_IMAGE_TYPES.includes(targetElement.type)) {
|
|
15628
|
+
useEditorStore.getState().updateElement(targetIdx, {
|
|
15629
|
+
attributes: { ...targetElement.attributes, "image-src": newSrc }
|
|
15630
|
+
});
|
|
15631
|
+
useEditorStore.getState().setFocusIdx(targetIdx);
|
|
15632
|
+
}
|
|
15633
|
+
}
|
|
15634
|
+
setDropIndicator(null);
|
|
15635
|
+
setDropTargetIdx(null);
|
|
15636
|
+
setIsDragging(false);
|
|
15637
|
+
setIsDragButtonHovered(false);
|
|
15638
|
+
setDataTransfer(null);
|
|
15639
|
+
setHoverIdx(null);
|
|
15640
|
+
dragParentIdxRef.current = null;
|
|
15641
|
+
dragPositionIndexRef.current = 0;
|
|
15642
|
+
createNewSectionRef.current = false;
|
|
15643
|
+
splitAtParagraphRef.current = null;
|
|
15644
|
+
isHorizontalDropRef.current = false;
|
|
15645
|
+
horizontalDropPositionRef.current = null;
|
|
15646
|
+
isSplitSectionDropRef.current = false;
|
|
15647
|
+
splitSectionAtElementRef.current = null;
|
|
15648
|
+
imageReplaceTargetRef.current = null;
|
|
15649
|
+
imagePreviewOriginalSrcRef.current = null;
|
|
15650
|
+
templateCacheRef.current = null;
|
|
15651
|
+
parentSectionCacheRef.current.clear();
|
|
15652
|
+
sectionElementCacheRef.current.clear();
|
|
15653
|
+
sectionRectCacheRef.current.clear();
|
|
15654
|
+
return;
|
|
15655
|
+
}
|
|
14963
15656
|
if (isHorizontalDropRef.current && horizontalDropPositionRef.current) {
|
|
14964
15657
|
const parentIdx2 = dragParentIdxRef.current;
|
|
14965
15658
|
const dropPosition = horizontalDropPositionRef.current;
|
|
@@ -14980,6 +15673,8 @@ function Editor({ setEditorLoading }) {
|
|
|
14980
15673
|
horizontalDropPositionRef.current = null;
|
|
14981
15674
|
isSplitSectionDropRef.current = false;
|
|
14982
15675
|
splitSectionAtElementRef.current = null;
|
|
15676
|
+
imageReplaceTargetRef.current = null;
|
|
15677
|
+
imagePreviewOriginalSrcRef.current = null;
|
|
14983
15678
|
templateCacheRef.current = null;
|
|
14984
15679
|
parentSectionCacheRef.current.clear();
|
|
14985
15680
|
sectionElementCacheRef.current.clear();
|
|
@@ -15040,6 +15735,8 @@ function Editor({ setEditorLoading }) {
|
|
|
15040
15735
|
splitAtParagraphRef.current = null;
|
|
15041
15736
|
isSplitSectionDropRef.current = false;
|
|
15042
15737
|
splitSectionAtElementRef.current = null;
|
|
15738
|
+
imageReplaceTargetRef.current = null;
|
|
15739
|
+
imagePreviewOriginalSrcRef.current = null;
|
|
15043
15740
|
templateCacheRef.current = null;
|
|
15044
15741
|
parentSectionCacheRef.current.clear();
|
|
15045
15742
|
sectionElementCacheRef.current.clear();
|
|
@@ -15095,7 +15792,7 @@ function Editor({ setEditorLoading }) {
|
|
|
15095
15792
|
},
|
|
15096
15793
|
[addElement, addElementInNewSection, moveElement, moveElementToNewSection, splitTextAndInsertElement, splitSectionAndInsertElement, setIsDragging, setIsDragButtonHovered, setDataTransfer, setHoverIdx]
|
|
15097
15794
|
);
|
|
15098
|
-
const handleDragLeave =
|
|
15795
|
+
const handleDragLeave = useCallback18(() => {
|
|
15099
15796
|
setDropIndicator(null);
|
|
15100
15797
|
setDropTargetIdx(null);
|
|
15101
15798
|
dragParentIdxRef.current = null;
|
|
@@ -15106,18 +15803,23 @@ function Editor({ setEditorLoading }) {
|
|
|
15106
15803
|
horizontalDropPositionRef.current = null;
|
|
15107
15804
|
isSplitSectionDropRef.current = false;
|
|
15108
15805
|
splitSectionAtElementRef.current = null;
|
|
15806
|
+
if (imageReplaceTargetRef.current && shadowRootRef.current && imagePreviewOriginalSrcRef.current !== null) {
|
|
15807
|
+
restoreImagePreview(shadowRootRef.current, imageReplaceTargetRef.current, imagePreviewOriginalSrcRef.current);
|
|
15808
|
+
}
|
|
15809
|
+
imageReplaceTargetRef.current = null;
|
|
15810
|
+
imagePreviewOriginalSrcRef.current = null;
|
|
15109
15811
|
templateCacheRef.current = null;
|
|
15110
15812
|
parentSectionCacheRef.current.clear();
|
|
15111
15813
|
sectionElementCacheRef.current.clear();
|
|
15112
15814
|
sectionRectCacheRef.current.clear();
|
|
15113
15815
|
}, []);
|
|
15114
|
-
const handleShadowRootRef =
|
|
15816
|
+
const handleShadowRootRef = useCallback18((shadowRoot) => {
|
|
15115
15817
|
shadowRootRef.current = shadowRoot;
|
|
15116
15818
|
}, []);
|
|
15117
|
-
const handleSelectionRectChange =
|
|
15819
|
+
const handleSelectionRectChange = useCallback18((rect) => {
|
|
15118
15820
|
setHasSelectedElement(rect !== null);
|
|
15119
15821
|
}, []);
|
|
15120
|
-
const getReferenceRect =
|
|
15822
|
+
const getReferenceRect = useCallback18(() => {
|
|
15121
15823
|
if (!shadowRootRef.current || !focusIdx) return null;
|
|
15122
15824
|
const selectedEl = shadowRootRef.current.querySelector(
|
|
15123
15825
|
`.node-idx-${CSS.escape(focusIdx)}`
|
|
@@ -15145,14 +15847,14 @@ function Editor({ setEditorLoading }) {
|
|
|
15145
15847
|
}, [focusIdx]);
|
|
15146
15848
|
const selectedElement = focusIdx && renderData ? getValueByIdx(renderData, focusIdx) : null;
|
|
15147
15849
|
const canDragSelectedElement = selectedElement && selectedElement.type !== "column" && !(focusIdx && renderData && isInsideCompanyFooter(focusIdx, renderData));
|
|
15148
|
-
const showCompanyFooter =
|
|
15850
|
+
const showCompanyFooter = useMemo18(
|
|
15149
15851
|
() => template.content[0]?.data?.value?.showCompanyFooter ?? true,
|
|
15150
15852
|
[template.content[0]?.data?.value?.showCompanyFooter]
|
|
15151
15853
|
);
|
|
15152
15854
|
if (!html) {
|
|
15153
|
-
return /* @__PURE__ */
|
|
15855
|
+
return /* @__PURE__ */ jsx51("div", { className: "maillow-editor flex items-center justify-center h-[500px]", children: /* @__PURE__ */ jsx51(Spinner, {}) });
|
|
15154
15856
|
}
|
|
15155
|
-
return /* @__PURE__ */
|
|
15857
|
+
return /* @__PURE__ */ jsxs32(
|
|
15156
15858
|
"div",
|
|
15157
15859
|
{
|
|
15158
15860
|
className: "maillow-editor relative ",
|
|
@@ -15163,7 +15865,7 @@ function Editor({ setEditorLoading }) {
|
|
|
15163
15865
|
justifyContent: "center"
|
|
15164
15866
|
},
|
|
15165
15867
|
children: [
|
|
15166
|
-
/* @__PURE__ */
|
|
15868
|
+
/* @__PURE__ */ jsxs32(
|
|
15167
15869
|
"div",
|
|
15168
15870
|
{
|
|
15169
15871
|
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 +15875,8 @@ function Editor({ setEditorLoading }) {
|
|
|
15173
15875
|
overflow: "auto"
|
|
15174
15876
|
},
|
|
15175
15877
|
children: [
|
|
15176
|
-
/* @__PURE__ */
|
|
15177
|
-
/* @__PURE__ */
|
|
15878
|
+
/* @__PURE__ */ jsx51("div", { className: "w-full h-[2px] bg-black opacity-10" }),
|
|
15879
|
+
/* @__PURE__ */ jsx51(
|
|
15178
15880
|
ShadowDomRenderer,
|
|
15179
15881
|
{
|
|
15180
15882
|
html,
|
|
@@ -15204,9 +15906,10 @@ function Editor({ setEditorLoading }) {
|
|
|
15204
15906
|
]
|
|
15205
15907
|
}
|
|
15206
15908
|
),
|
|
15207
|
-
/* @__PURE__ */
|
|
15208
|
-
/* @__PURE__ */
|
|
15209
|
-
|
|
15909
|
+
/* @__PURE__ */ jsx51(ElementsSuggestions, {}),
|
|
15910
|
+
/* @__PURE__ */ jsx51(MergeFieldSuggestions, {}),
|
|
15911
|
+
/* @__PURE__ */ jsx51(TiptapOverlay, {}),
|
|
15912
|
+
!isDragging && !isScaling && hasSelectedElement && focusIdx && selectedElement?.type && /* @__PURE__ */ jsx51(
|
|
15210
15913
|
ElementFloat,
|
|
15211
15914
|
{
|
|
15212
15915
|
getReferenceRect,
|
|
@@ -15214,7 +15917,7 @@ function Editor({ setEditorLoading }) {
|
|
|
15214
15917
|
elementType: selectedElement.type
|
|
15215
15918
|
}
|
|
15216
15919
|
),
|
|
15217
|
-
!isScaling && hasSelectedElement && focusIdx && canDragSelectedElement && !NOT_DRAGGABLE_ELEMENTS.includes(selectedElement.type) && /* @__PURE__ */
|
|
15920
|
+
!isScaling && hasSelectedElement && focusIdx && canDragSelectedElement && !NOT_DRAGGABLE_ELEMENTS.includes(selectedElement.type) && /* @__PURE__ */ jsx51(
|
|
15218
15921
|
DragButton,
|
|
15219
15922
|
{
|
|
15220
15923
|
getReferenceRect,
|
|
@@ -15223,17 +15926,17 @@ function Editor({ setEditorLoading }) {
|
|
|
15223
15926
|
isDragging
|
|
15224
15927
|
}
|
|
15225
15928
|
),
|
|
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__ */
|
|
15929
|
+
!isDragging && hasSelectedElement && focusIdx && selectedElement?.type === "divider" && /* @__PURE__ */ jsx51(DividerScale, { getReferenceRect }),
|
|
15930
|
+
!isDragging && hasSelectedElement && focusIdx && selectedElement?.type === "button" && /* @__PURE__ */ jsx51(ButtonScale, { getReferenceRect }),
|
|
15931
|
+
!isDragging && hasSelectedElement && focusIdx && selectedElement?.type === "image" && /* @__PURE__ */ jsx51(ImageScale, { getReferenceRect }),
|
|
15932
|
+
!isDragging && hasSelectedElement && focusIdx && selectedElement?.type === "space" && /* @__PURE__ */ jsx51(SpacerScale, { getReferenceRect }),
|
|
15230
15933
|
!isDragging && hasSelectedElement && focusIdx && renderData && (() => {
|
|
15231
15934
|
const sectionColumnIdx = getSectionColumnIdx(focusIdx, renderData);
|
|
15232
15935
|
if (!sectionColumnIdx) return null;
|
|
15233
15936
|
const sectionColumn = getValueByIdx(renderData, sectionColumnIdx);
|
|
15234
15937
|
if (!sectionColumn || sectionColumn.type !== "section-column") return null;
|
|
15235
15938
|
if (!sectionColumn.children || sectionColumn.children.length < 2) return null;
|
|
15236
|
-
return /* @__PURE__ */
|
|
15939
|
+
return /* @__PURE__ */ jsx51(
|
|
15237
15940
|
ColumnScale,
|
|
15238
15941
|
{
|
|
15239
15942
|
sectionColumnIdx,
|
|
@@ -15255,9 +15958,7 @@ export {
|
|
|
15255
15958
|
parseBorder,
|
|
15256
15959
|
formatBorder,
|
|
15257
15960
|
parsePrice,
|
|
15258
|
-
json2mjml,
|
|
15259
15961
|
MAX_TEMPLATE_SIZE,
|
|
15260
|
-
useEditorStore,
|
|
15261
15962
|
BUTTON_ALIGNMENTS,
|
|
15262
15963
|
ALIGNMENT_ICONS,
|
|
15263
15964
|
FONTS,
|
|
@@ -15275,6 +15976,9 @@ export {
|
|
|
15275
15976
|
MIN_LINE_HEIGHT,
|
|
15276
15977
|
MAX_LINE_HEIGHT,
|
|
15277
15978
|
LINE_HEIGHT_STEP,
|
|
15979
|
+
DEFAULT_PROPERTY_PLACEHOLDER_IMAGE,
|
|
15980
|
+
json2mjml,
|
|
15981
|
+
useEditorStore,
|
|
15278
15982
|
setupDragImage,
|
|
15279
15983
|
getElementDisplayName,
|
|
15280
15984
|
cn,
|