@parathantl/react-email-editor 0.1.5 → 0.1.7

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/index.js CHANGED
@@ -1,5 +1,5 @@
1
1
  // src/components/EmailEditor.tsx
2
- import { forwardRef as forwardRef2, useCallback as useCallback35, useEffect as useEffect17, useImperativeHandle, useRef as useRef21, useState as useState20 } from "react";
2
+ import { forwardRef as forwardRef2, useCallback as useCallback37, useEffect as useEffect18, useImperativeHandle, useRef as useRef24, useState as useState24 } from "react";
3
3
 
4
4
  // src/context/EditorContext.tsx
5
5
  import {
@@ -7,7 +7,8 @@ import {
7
7
  useCallback as useCallback4,
8
8
  useEffect as useEffect3,
9
9
  useMemo as useMemo3,
10
- useRef as useRef4
10
+ useRef as useRef4,
11
+ useState as useState2
11
12
  } from "react";
12
13
 
13
14
  // src/constants.ts
@@ -21,7 +22,8 @@ var DEFAULT_TEXT_PROPERTIES = {
21
22
  align: "left",
22
23
  fontWeight: "normal",
23
24
  textTransform: "none",
24
- letterSpacing: "normal"
25
+ letterSpacing: "normal",
26
+ backgroundColor: "transparent"
25
27
  };
26
28
  var DEFAULT_BUTTON_PROPERTIES = {
27
29
  text: "Click me",
@@ -91,12 +93,13 @@ var DEFAULT_HEADING_PROPERTIES = {
91
93
  fontFamily: "Arial, sans-serif",
92
94
  fontSize: "28px",
93
95
  color: "#000000",
94
- lineHeight: "1.3",
96
+ lineHeight: "1.5",
95
97
  fontWeight: "bold",
96
98
  padding: "10px 25px",
97
99
  align: "left",
98
100
  textTransform: "none",
99
- letterSpacing: "normal"
101
+ letterSpacing: "normal",
102
+ backgroundColor: "transparent"
100
103
  };
101
104
  var DEFAULT_COUNTDOWN_PROPERTIES = {
102
105
  targetDate: new Date(Date.now() + 7 * 24 * 60 * 60 * 1e3).toISOString().slice(0, 16),
@@ -222,7 +225,7 @@ var BLOCK_DEFINITIONS = [
222
225
  {
223
226
  type: "social",
224
227
  label: "Social",
225
- icon: "\u{1F517}",
228
+ icon: "\u{1F465}",
226
229
  description: "Social media links"
227
230
  },
228
231
  {
@@ -1127,6 +1130,10 @@ function useImageAdapter() {
1127
1130
  const { imageUploadAdapter } = useConfigContext();
1128
1131
  return { imageUploadAdapter };
1129
1132
  }
1133
+ function useColorPresets() {
1134
+ const { customColorPresets, addCustomColorPreset, removeCustomColorPreset } = useConfigContext();
1135
+ return { customColorPresets, addCustomColorPreset, removeCustomColorPreset };
1136
+ }
1130
1137
 
1131
1138
  // src/context/EditorContext.tsx
1132
1139
  import { jsx } from "react/jsx-runtime";
@@ -1141,6 +1148,8 @@ function EditorProvider({
1141
1148
  onVariablesChange,
1142
1149
  fontFamilies: fontFamiliesProp,
1143
1150
  fontSizes: fontSizesProp,
1151
+ colorPresets: colorPresetsProp,
1152
+ onColorPresetsChange,
1144
1153
  persistenceKey,
1145
1154
  persistenceAdapter,
1146
1155
  onBlockAdd,
@@ -1156,6 +1165,24 @@ function EditorProvider({
1156
1165
  }) {
1157
1166
  const fontFamilies = fontFamiliesProp ?? FONT_OPTIONS;
1158
1167
  const fontSizes = fontSizesProp ?? DEFAULT_FONT_SIZES;
1168
+ const [customColorPresets, setCustomColorPresets] = useState2(colorPresetsProp ?? []);
1169
+ const onColorPresetsChangeRef = useRef4(onColorPresetsChange);
1170
+ onColorPresetsChangeRef.current = onColorPresetsChange;
1171
+ const addCustomColorPreset = useCallback4((color) => {
1172
+ setCustomColorPresets((prev) => {
1173
+ if (prev.includes(color)) return prev;
1174
+ const next = [...prev, color];
1175
+ onColorPresetsChangeRef.current?.(next);
1176
+ return next;
1177
+ });
1178
+ }, []);
1179
+ const removeCustomColorPreset = useCallback4((color) => {
1180
+ setCustomColorPresets((prev) => {
1181
+ const next = prev.filter((c) => c !== color);
1182
+ onColorPresetsChangeRef.current?.(next);
1183
+ return next;
1184
+ });
1185
+ }, []);
1159
1186
  const resolvedInitial = useMemo3(() => {
1160
1187
  if (persistenceKey) {
1161
1188
  const adapter = persistenceAdapter ?? localStorageAdapter;
@@ -1370,9 +1397,12 @@ function EditorProvider({
1370
1397
  updateVariableChipStyle,
1371
1398
  fontFamilies,
1372
1399
  fontSizes,
1373
- clearPersisted
1400
+ clearPersisted,
1401
+ customColorPresets,
1402
+ addCustomColorPreset,
1403
+ removeCustomColorPreset
1374
1404
  }),
1375
- [allVariables, predefinedVariables, customVariables, imageUploadAdapter, addCustomVariable, removeCustomVariable, variableChipStyle, updateVariableChipStyle, fontFamilies, fontSizes, clearPersisted]
1405
+ [allVariables, predefinedVariables, customVariables, imageUploadAdapter, addCustomVariable, removeCustomVariable, variableChipStyle, updateVariableChipStyle, fontFamilies, fontSizes, clearPersisted, customColorPresets, addCustomColorPreset, removeCustomColorPreset]
1376
1406
  );
1377
1407
  const blockIndexValue = useMemo3(() => state.blockIndex, [state.blockIndex]);
1378
1408
  return /* @__PURE__ */ jsx(DispatchContext.Provider, { value: dispatch, children: /* @__PURE__ */ jsx(MethodsContext.Provider, { value: methodsValue, children: /* @__PURE__ */ jsx(HistoryContext.Provider, { value: historyValue, children: /* @__PURE__ */ jsx(TemplateContext.Provider, { value: templateValue, children: /* @__PURE__ */ jsx(SelectionContext.Provider, { value: selectionValue, children: /* @__PURE__ */ jsx(ConfigContext.Provider, { value: configValue, children: /* @__PURE__ */ jsx(BlockIndexContext.Provider, { value: blockIndexValue, children }) }) }) }) }) }) });
@@ -1506,7 +1536,7 @@ function ConfirmDialog({
1506
1536
  }
1507
1537
 
1508
1538
  // src/components/Toolbar/Toolbar.tsx
1509
- import React3, { useCallback as useCallback6, useRef as useRef6, useState as useState2, useEffect as useEffect5 } from "react";
1539
+ import React3, { useCallback as useCallback6, useRef as useRef6, useState as useState3, useEffect as useEffect5 } from "react";
1510
1540
 
1511
1541
  // src/utils/sanitize.ts
1512
1542
  var ALLOWED_TAGS = /* @__PURE__ */ new Set([
@@ -1694,8 +1724,24 @@ function isSafeURL(url) {
1694
1724
  if (trimmed.startsWith("/") || trimmed.startsWith("#") || trimmed.startsWith("?")) return true;
1695
1725
  return SAFE_URL_PATTERN.test(trimmed);
1696
1726
  }
1727
+ function isSafeImageSrc(url) {
1728
+ if (isSafeURL(url)) return true;
1729
+ const trimmed = url.trim();
1730
+ if (/^data:image\/svg/i.test(trimmed)) return false;
1731
+ return /^data:image\//i.test(trimmed);
1732
+ }
1697
1733
 
1698
1734
  // src/mjml/generator.ts
1735
+ var GOOGLE_FONTS = {
1736
+ "Roboto": "https://fonts.googleapis.com/css?family=Roboto:300,400,500,700",
1737
+ "Open Sans": "https://fonts.googleapis.com/css?family=Open+Sans:300,400,500,700",
1738
+ "Lato": "https://fonts.googleapis.com/css?family=Lato:300,400,700",
1739
+ "Montserrat": "https://fonts.googleapis.com/css?family=Montserrat:300,400,500,700",
1740
+ "Source Sans Pro": "https://fonts.googleapis.com/css?family=Source+Sans+Pro:300,400,600,700",
1741
+ "Oswald": "https://fonts.googleapis.com/css?family=Oswald:300,400,700",
1742
+ "Raleway": "https://fonts.googleapis.com/css?family=Raleway:300,400,500,700",
1743
+ "Merriweather": "https://fonts.googleapis.com/css?family=Merriweather:300,400,700"
1744
+ };
1699
1745
  function generateMJML(template) {
1700
1746
  const { globalStyles, sections } = template;
1701
1747
  const lines = [];
@@ -1708,6 +1754,23 @@ function generateMJML(template) {
1708
1754
  if (headMetadata?.previewText) {
1709
1755
  lines.push(` <mj-preview>${escapeHTML(headMetadata.previewText)}</mj-preview>`);
1710
1756
  }
1757
+ const usedFonts = /* @__PURE__ */ new Set();
1758
+ if (globalStyles.fontFamily) usedFonts.add(globalStyles.fontFamily);
1759
+ for (const section of sections) {
1760
+ for (const column of section.columns) {
1761
+ for (const block of column.blocks) {
1762
+ if (block.properties.fontFamily) {
1763
+ usedFonts.add(block.properties.fontFamily);
1764
+ }
1765
+ }
1766
+ }
1767
+ }
1768
+ for (const font of usedFonts) {
1769
+ const family = font.split(",")[0].trim().replace(/['"]/g, "");
1770
+ if (GOOGLE_FONTS[family]) {
1771
+ lines.push(` <mj-font name="${escapeAttr(family)}" href="${escapeAttr(GOOGLE_FONTS[family])}" />`);
1772
+ }
1773
+ }
1711
1774
  lines.push(" <mj-attributes>");
1712
1775
  lines.push(` <mj-all font-family="${escapeAttr(globalStyles.fontFamily)}" />`);
1713
1776
  lines.push(" </mj-attributes>");
@@ -1830,7 +1893,8 @@ function generateTextBlock(block, indent) {
1830
1893
  align: p.align,
1831
1894
  "font-weight": p.fontWeight && p.fontWeight !== "normal" ? p.fontWeight : void 0,
1832
1895
  "text-transform": p.textTransform && p.textTransform !== "none" ? p.textTransform : void 0,
1833
- "letter-spacing": p.letterSpacing && p.letterSpacing !== "normal" ? p.letterSpacing : void 0
1896
+ "letter-spacing": p.letterSpacing && p.letterSpacing !== "normal" ? p.letterSpacing : void 0,
1897
+ "container-background-color": p.backgroundColor && p.backgroundColor !== "transparent" ? p.backgroundColor : void 0
1834
1898
  });
1835
1899
  const content = resetBlockMargins(stripVariableChips(p.content || ""));
1836
1900
  return `${indent}<mj-text${attrs}>${content}</mj-text>`;
@@ -1857,7 +1921,7 @@ function generateButtonBlock(block, indent) {
1857
1921
  function generateImageBlock(block, indent) {
1858
1922
  const p = block.properties;
1859
1923
  const attrs = buildAttrs({
1860
- src: safeHref(p.src),
1924
+ src: safeSrc(p.src),
1861
1925
  alt: p.alt,
1862
1926
  href: p.href ? safeHref(p.href) : void 0,
1863
1927
  width: p.width,
@@ -1899,12 +1963,14 @@ function generateSocialBlock(block, indent) {
1899
1963
  const lines = [];
1900
1964
  lines.push(`${indent}<mj-social${attrs}>`);
1901
1965
  for (const element of p.elements) {
1966
+ const hasCustomSrc = !!element.src;
1902
1967
  const elAttrs = buildAttrs({
1903
- name: element.name,
1968
+ name: hasCustomSrc ? `custom-${element.name}` : element.name,
1904
1969
  href: safeHref(element.href),
1905
- src: element.src ? safeHref(element.src) : void 0,
1906
- "background-color": element.backgroundColor,
1907
- color: element.color
1970
+ src: hasCustomSrc ? safeSrc(element.src) : void 0,
1971
+ "background-color": element.backgroundColor || (hasCustomSrc ? "transparent" : void 0),
1972
+ color: element.color,
1973
+ "css-class": hasCustomSrc ? `ee-social-${element.name}` : void 0
1908
1974
  });
1909
1975
  const content = element.content ? escapeHTML(element.content) : "";
1910
1976
  lines.push(`${indent} <mj-social-element${elAttrs}>${content}</mj-social-element>`);
@@ -1922,7 +1988,7 @@ function generateVideoBlock(block, indent) {
1922
1988
  const p = block.properties;
1923
1989
  const thumbnailUrl = p.thumbnailUrl || getAutoThumbnail(p.src);
1924
1990
  const attrs = buildAttrs({
1925
- src: safeHref(thumbnailUrl),
1991
+ src: safeSrc(thumbnailUrl),
1926
1992
  href: safeHref(p.src),
1927
1993
  alt: p.alt,
1928
1994
  padding: p.padding,
@@ -1950,6 +2016,7 @@ function generateHeadingBlock(block, indent) {
1950
2016
  "font-weight": p.fontWeight && p.fontWeight !== "normal" ? p.fontWeight : void 0,
1951
2017
  "text-transform": p.textTransform && p.textTransform !== "none" ? p.textTransform : void 0,
1952
2018
  "letter-spacing": p.letterSpacing && p.letterSpacing !== "normal" ? p.letterSpacing : void 0,
2019
+ "container-background-color": p.backgroundColor && p.backgroundColor !== "transparent" ? p.backgroundColor : void 0,
1953
2020
  "css-class": `ee-block-heading ee-heading-${level}`
1954
2021
  });
1955
2022
  const content = resetBlockMargins(stripVariableChips(p.content || ""));
@@ -2034,10 +2101,17 @@ function generateHeroBlock(block, indent) {
2034
2101
  return `${indent}<mj-text${attrs}>${html2}</mj-text>`;
2035
2102
  }
2036
2103
  function stripVariableChips(html2) {
2037
- return html2.replace(
2038
- /<span[^>]*data-variable-key="([^"]*)"[^>]*>[\s\S]*?<\/span>/g,
2039
- (_match, key) => `{{ ${key} }}`
2040
- );
2104
+ if (!html2.includes("ee-variable-chip")) return html2;
2105
+ const div = document.createElement("div");
2106
+ div.innerHTML = html2;
2107
+ const chips = div.querySelectorAll(".ee-variable-chip");
2108
+ chips.forEach((chip) => {
2109
+ const key = chip.getAttribute("data-variable-key");
2110
+ if (key) {
2111
+ chip.replaceWith(`{{ ${key} }}`);
2112
+ }
2113
+ });
2114
+ return div.innerHTML;
2041
2115
  }
2042
2116
  function resetBlockMargins(html2) {
2043
2117
  return html2.replace(
@@ -2064,6 +2138,10 @@ function safeHref(url) {
2064
2138
  if (!url) return "#";
2065
2139
  return isSafeURL(url) ? url : "#";
2066
2140
  }
2141
+ function safeSrc(url) {
2142
+ if (!url) return "#";
2143
+ return isSafeImageSrc(url) ? url : "#";
2144
+ }
2067
2145
 
2068
2146
  // src/mjml/compiler.ts
2069
2147
  var mjmlBrowser = null;
@@ -2183,7 +2261,7 @@ var MJML_DEFAULTS = {
2183
2261
  fontFamily: "Ubuntu, Helvetica, Arial, sans-serif",
2184
2262
  fontSize: "13px",
2185
2263
  color: "#000000",
2186
- lineHeight: "1",
2264
+ lineHeight: "1.5",
2187
2265
  padding: "10px 25px",
2188
2266
  align: "left",
2189
2267
  fontWeight: "normal",
@@ -2569,6 +2647,16 @@ function parseBlockElements(parent) {
2569
2647
  const parser = blockParserRegistry[tagName];
2570
2648
  if (parser) {
2571
2649
  blocks.push(parser(child));
2650
+ } else {
2651
+ const serializer = new XMLSerializer();
2652
+ blocks.push({
2653
+ id: generateBlockId(),
2654
+ type: "html",
2655
+ properties: {
2656
+ content: serializer.serializeToString(child),
2657
+ padding: child.getAttribute("padding") ?? DEFAULT_BLOCK_PROPERTIES.html.padding
2658
+ }
2659
+ });
2572
2660
  }
2573
2661
  }
2574
2662
  return blocks;
@@ -2585,6 +2673,11 @@ function parseTextBlock(el) {
2585
2673
  return parseHtmlFromMjText(el);
2586
2674
  }
2587
2675
  const innerHTML = el.innerHTML?.trim() ?? "";
2676
+ const headingMatch = innerHTML.match(/^<(h[1-4])\b[^>]*>([\s\S]*)<\/\1>\s*$/i);
2677
+ if (headingMatch) {
2678
+ const syntheticCssClass = `ee-block-heading ee-heading-${headingMatch[1].toLowerCase()}`;
2679
+ return parseHeadingFromMjText(el, syntheticCssClass);
2680
+ }
2588
2681
  const d = MJML_DEFAULTS.text;
2589
2682
  return {
2590
2683
  id: generateBlockId(),
@@ -2599,7 +2692,8 @@ function parseTextBlock(el) {
2599
2692
  align: el.getAttribute("align") ?? d.align,
2600
2693
  fontWeight: el.getAttribute("font-weight") ?? d.fontWeight,
2601
2694
  textTransform: el.getAttribute("text-transform") ?? d.textTransform,
2602
- letterSpacing: el.getAttribute("letter-spacing") ?? d.letterSpacing
2695
+ letterSpacing: el.getAttribute("letter-spacing") ?? d.letterSpacing,
2696
+ backgroundColor: el.getAttribute("container-background-color") ?? "transparent"
2603
2697
  }
2604
2698
  };
2605
2699
  }
@@ -2625,7 +2719,8 @@ function parseHeadingFromMjText(el, cssClass) {
2625
2719
  padding: resolvePadding(el, defaults2.padding),
2626
2720
  align: el.getAttribute("align") ?? d.align,
2627
2721
  textTransform: el.getAttribute("text-transform") ?? defaults2.textTransform,
2628
- letterSpacing: el.getAttribute("letter-spacing") ?? defaults2.letterSpacing
2722
+ letterSpacing: el.getAttribute("letter-spacing") ?? defaults2.letterSpacing,
2723
+ backgroundColor: el.getAttribute("container-background-color") ?? "transparent"
2629
2724
  }
2630
2725
  };
2631
2726
  }
@@ -2766,8 +2861,16 @@ function parseSocialBlock(el) {
2766
2861
  const childEls = el.querySelectorAll("mj-social-element");
2767
2862
  for (let i = 0; i < childEls.length; i++) {
2768
2863
  const child = childEls[i];
2864
+ let name = child.getAttribute("name") ?? "";
2865
+ if (name.startsWith("custom-")) {
2866
+ name = name.slice(7);
2867
+ } else if (!name) {
2868
+ const cssClass = child.getAttribute("css-class") ?? "";
2869
+ const nameMatch = cssClass.match(/ee-social-(\w+)/);
2870
+ name = nameMatch ? nameMatch[1] : "web";
2871
+ }
2769
2872
  const element = {
2770
- name: child.getAttribute("name") ?? "web",
2873
+ name,
2771
2874
  href: child.getAttribute("href") ?? "#"
2772
2875
  };
2773
2876
  const src = child.getAttribute("src");
@@ -2843,19 +2946,24 @@ var toolbar_default = {
2843
2946
  "exportDropdown": "exportDropdown",
2844
2947
  "exportDropdownItem": "exportDropdownItem",
2845
2948
  "richTextToolbar": "richTextToolbar",
2949
+ "richTextGroup": "richTextGroup",
2846
2950
  "richTextBtn": "richTextBtn",
2847
2951
  "richTextBtnActive": "richTextBtnActive",
2848
- "richTextSeparator": "richTextSeparator",
2952
+ "richTextBtnWithIndicator": "richTextBtnWithIndicator richTextBtn",
2849
2953
  "richTextSelect": "richTextSelect",
2850
2954
  "richTextSelectSmall": "richTextSelectSmall richTextSelect",
2851
2955
  "richTextColorWrapper": "richTextColorWrapper",
2852
- "richTextColorLabel": "richTextColorLabel",
2853
2956
  "richTextColorIndicator": "richTextColorIndicator",
2854
2957
  "richTextColorDropdown": "richTextColorDropdown",
2958
+ "richTextColorSectionLabel": "richTextColorSectionLabel",
2855
2959
  "richTextColorGrid": "richTextColorGrid",
2856
2960
  "richTextColorSwatch": "richTextColorSwatch",
2857
- "richTextColorActions": "richTextColorActions",
2858
- "richTextColorInput": "richTextColorInput",
2961
+ "richTextColorSwatchActive": "richTextColorSwatchActive",
2962
+ "richTextColorSwatchRemove": "richTextColorSwatchRemove",
2963
+ "richTextColorCustomRow": "richTextColorCustomRow",
2964
+ "richTextColorHexInput": "richTextColorHexInput",
2965
+ "richTextColorApplyBtn": "richTextColorApplyBtn",
2966
+ "richTextColorBottomActions": "richTextColorBottomActions",
2859
2967
  "richTextColorClearBtn": "richTextColorClearBtn",
2860
2968
  "richTextLinkDropdown": "richTextLinkDropdown",
2861
2969
  "richTextLinkLabel": "richTextLinkLabel",
@@ -2863,7 +2971,10 @@ var toolbar_default = {
2863
2971
  "richTextLinkError": "richTextLinkError",
2864
2972
  "richTextLinkActions": "richTextLinkActions",
2865
2973
  "richTextLinkApply": "richTextLinkApply",
2866
- "richTextLinkRemove": "richTextLinkRemove"
2974
+ "richTextLinkRemove": "richTextLinkRemove",
2975
+ "richTextTooltipWrapper": "richTextTooltipWrapper",
2976
+ "richTextTooltip": "richTextTooltip",
2977
+ "richTextTooltipShortcut": "richTextTooltipShortcut"
2867
2978
  };
2868
2979
 
2869
2980
  // src/styles/editor.module.css
@@ -2892,7 +3003,7 @@ var Toolbar = React3.memo(function Toolbar2({ sidebarOpen, propertiesOpen, onTog
2892
3003
  const { canUndo, canRedo } = useHistoryContext();
2893
3004
  const dispatch = useEditorDispatch();
2894
3005
  const fileInputRef = useRef6(null);
2895
- const [exportOpen, setExportOpen] = useState2(false);
3006
+ const [exportOpen, setExportOpen] = useState3(false);
2896
3007
  const templateRef = useRef6(template);
2897
3008
  templateRef.current = template;
2898
3009
  useEffect5(() => {
@@ -3226,11 +3337,11 @@ var BlockPalette = React4.memo(function BlockPalette2({ blockDefinitions }) {
3226
3337
  });
3227
3338
 
3228
3339
  // src/components/Sidebar/VariableList.tsx
3229
- import { useCallback as useCallback8, useEffect as useEffect6, useRef as useRef7, useState as useState3 } from "react";
3340
+ import { useCallback as useCallback8, useEffect as useEffect6, useRef as useRef7, useState as useState4 } from "react";
3230
3341
  import { jsx as jsx6, jsxs as jsxs5 } from "react/jsx-runtime";
3231
3342
  function VariableList() {
3232
3343
  const { variables, customVariables, insertVariable, removeCustomVariable } = useEditorVariables();
3233
- const [flashKey, setFlashKey] = useState3(null);
3344
+ const [flashKey, setFlashKey] = useState4(null);
3234
3345
  const flashTimerRef = useRef7(null);
3235
3346
  useEffect6(() => {
3236
3347
  return () => {
@@ -3299,15 +3410,15 @@ function VariableList() {
3299
3410
  }
3300
3411
 
3301
3412
  // src/components/Sidebar/AddVariableForm.tsx
3302
- import { useState as useState4, useCallback as useCallback9 } from "react";
3413
+ import { useState as useState5, useCallback as useCallback9 } from "react";
3303
3414
  import { jsx as jsx7, jsxs as jsxs6 } from "react/jsx-runtime";
3304
3415
  function AddVariableForm() {
3305
3416
  const { variables, addCustomVariable } = useEditorVariables();
3306
- const [isOpen, setIsOpen] = useState4(false);
3307
- const [key, setKey] = useState4("");
3308
- const [label, setLabel] = useState4("");
3309
- const [group, setGroup] = useState4("Custom");
3310
- const [error, setError] = useState4(null);
3417
+ const [isOpen, setIsOpen] = useState5(false);
3418
+ const [key, setKey] = useState5("");
3419
+ const [label, setLabel] = useState5("");
3420
+ const [group, setGroup] = useState5("Custom");
3421
+ const [error, setError] = useState5(null);
3311
3422
  const resetForm = useCallback9(() => {
3312
3423
  setKey("");
3313
3424
  setLabel("");
@@ -3439,19 +3550,19 @@ function Sidebar({ blockDefinitions }) {
3439
3550
  }
3440
3551
 
3441
3552
  // src/components/Canvas/Canvas.tsx
3442
- import React28, { useCallback as useCallback20, useState as useState15 } from "react";
3553
+ import React30, { useCallback as useCallback22, useState as useState18 } from "react";
3443
3554
 
3444
3555
  // src/components/Canvas/Section.tsx
3445
- import React26, { useCallback as useCallback18, useState as useState13 } from "react";
3556
+ import React28, { useCallback as useCallback20, useState as useState16 } from "react";
3446
3557
 
3447
3558
  // src/components/Canvas/Column.tsx
3448
- import React25, { useCallback as useCallback17, useState as useState12 } from "react";
3559
+ import React27, { useCallback as useCallback19, useState as useState15 } from "react";
3449
3560
 
3450
3561
  // src/components/Canvas/BlockRenderer.tsx
3451
- import React23 from "react";
3562
+ import React25 from "react";
3452
3563
 
3453
3564
  // src/components/Canvas/blocks/TextBlock.tsx
3454
- import React11, { useCallback as useCallback12, useRef as useRef11, useState as useState7, useEffect as useEffect10, useReducer as useReducer2, useMemo as useMemo5 } from "react";
3565
+ import React13, { useCallback as useCallback14, useRef as useRef13, useState as useState10, useEffect as useEffect11, useReducer as useReducer2, useMemo as useMemo5 } from "react";
3455
3566
 
3456
3567
  // src/tiptap/TipTapEditor.tsx
3457
3568
  import { useMemo as useMemo4, useEffect as useEffect8, useRef as useRef9 } from "react";
@@ -19762,7 +19873,7 @@ function canInsertNode(state, nodeType) {
19762
19873
  }
19763
19874
 
19764
19875
  // node_modules/@tiptap/react/dist/index.js
19765
- import React8, { forwardRef, useState as useState5, useDebugValue, useLayoutEffect, useEffect as useEffect7, useRef as useRef8, createContext as createContext8, useContext as useContext8, version, createRef, memo, createElement } from "react";
19876
+ import React8, { forwardRef, useState as useState6, useDebugValue, useLayoutEffect, useEffect as useEffect7, useRef as useRef8, createContext as createContext8, useContext as useContext8, version, createRef, memo, createElement } from "react";
19766
19877
  import ReactDOM, { flushSync } from "react-dom";
19767
19878
  function getDefaultExportFromCjs(x) {
19768
19879
  return x && x.__esModule && Object.prototype.hasOwnProperty.call(x, "default") ? x["default"] : x;
@@ -20136,7 +20247,7 @@ var EditorStateManager = class {
20136
20247
  };
20137
20248
  function useEditorState2(options) {
20138
20249
  var _a;
20139
- const [editorStateManager] = useState5(() => new EditorStateManager(options.editor));
20250
+ const [editorStateManager] = useState6(() => new EditorStateManager(options.editor));
20140
20251
  const selectedState = withSelectorExports.useSyncExternalStoreWithSelector(editorStateManager.subscribe, editorStateManager.getSnapshot, editorStateManager.getServerSnapshot, options.selector, (_a = options.equalityFn) !== null && _a !== void 0 ? _a : deepEqual);
20141
20252
  useIsomorphicLayoutEffect(() => {
20142
20253
  return editorStateManager.watch(options.editor);
@@ -20360,7 +20471,7 @@ var EditorInstanceManager = class _EditorInstanceManager {
20360
20471
  function useEditor(options = {}, deps = []) {
20361
20472
  const mostRecentOptions = useRef8(options);
20362
20473
  mostRecentOptions.current = options;
20363
- const [instanceManager] = useState5(() => new EditorInstanceManager(mostRecentOptions));
20474
+ const [instanceManager] = useState6(() => new EditorInstanceManager(mostRecentOptions));
20364
20475
  const editor = shimExports.useSyncExternalStore(instanceManager.subscribe, instanceManager.getEditor, instanceManager.getServerSnapshot);
20365
20476
  useDebugValue(editor);
20366
20477
  useEffect7(instanceManager.onRender(deps));
@@ -24330,6 +24441,84 @@ var FontFamily = Extension.create({
24330
24441
  }
24331
24442
  });
24332
24443
 
24444
+ // src/tiptap/Indent.ts
24445
+ var INDENT_STEP = 24;
24446
+ var MAX_INDENT = 240;
24447
+ function applyIndent(editor) {
24448
+ const { state, view } = editor;
24449
+ const { tr: tr2 } = state;
24450
+ const { from: from2, to } = state.selection;
24451
+ let changed = false;
24452
+ state.doc.nodesBetween(from2, to, (node, pos) => {
24453
+ if (node.type.name === "paragraph" || node.type.name === "heading") {
24454
+ const current = node.attrs.indent || 0;
24455
+ if (current < MAX_INDENT) {
24456
+ tr2.setNodeMarkup(pos, void 0, { ...node.attrs, indent: current + INDENT_STEP });
24457
+ changed = true;
24458
+ }
24459
+ }
24460
+ });
24461
+ if (changed) view.dispatch(tr2);
24462
+ return changed;
24463
+ }
24464
+ function applyOutdent(editor) {
24465
+ const { state, view } = editor;
24466
+ const { tr: tr2 } = state;
24467
+ const { from: from2, to } = state.selection;
24468
+ let changed = false;
24469
+ state.doc.nodesBetween(from2, to, (node, pos) => {
24470
+ if (node.type.name === "paragraph" || node.type.name === "heading") {
24471
+ const current = node.attrs.indent || 0;
24472
+ if (current > 0) {
24473
+ tr2.setNodeMarkup(pos, void 0, { ...node.attrs, indent: Math.max(0, current - INDENT_STEP) });
24474
+ changed = true;
24475
+ }
24476
+ }
24477
+ });
24478
+ if (changed) view.dispatch(tr2);
24479
+ return changed;
24480
+ }
24481
+ var Indent = Extension.create({
24482
+ name: "indent",
24483
+ addGlobalAttributes() {
24484
+ return [
24485
+ {
24486
+ types: ["paragraph", "heading"],
24487
+ attributes: {
24488
+ indent: {
24489
+ default: 0,
24490
+ parseHTML: (element) => parseInt(element.style.marginLeft, 10) || 0,
24491
+ renderHTML: (attributes) => {
24492
+ if (!attributes.indent) return {};
24493
+ return { style: `margin-left: ${attributes.indent}px` };
24494
+ }
24495
+ }
24496
+ }
24497
+ }
24498
+ ];
24499
+ },
24500
+ addKeyboardShortcuts() {
24501
+ return {
24502
+ Tab: ({ editor }) => {
24503
+ if (editor.isActive("listItem")) {
24504
+ editor.commands.sinkListItem("listItem");
24505
+ return true;
24506
+ }
24507
+ applyIndent(editor);
24508
+ return true;
24509
+ },
24510
+ "Shift-Tab": ({ editor }) => {
24511
+ if (editor.isActive("listItem")) {
24512
+ editor.commands.liftListItem("listItem");
24513
+ return true;
24514
+ }
24515
+ applyOutdent(editor);
24516
+ return true;
24517
+ }
24518
+ };
24519
+ }
24520
+ });
24521
+
24333
24522
  // src/tiptap/extensions.ts
24334
24523
  function getExtensions(placeholder) {
24335
24524
  return [
@@ -24345,9 +24534,23 @@ function getExtensions(placeholder) {
24345
24534
  Color,
24346
24535
  FontSize,
24347
24536
  FontFamily,
24348
- Highlight.configure({
24349
- multicolor: true
24350
- }),
24537
+ Highlight.extend({
24538
+ renderHTML({ HTMLAttributes }) {
24539
+ return ["span", mergeAttributes(this.options.HTMLAttributes, HTMLAttributes), 0];
24540
+ },
24541
+ parseHTML() {
24542
+ return [
24543
+ { tag: "mark" },
24544
+ {
24545
+ tag: "span[style]",
24546
+ getAttrs: (el) => {
24547
+ if (!el.style.backgroundColor) return false;
24548
+ return {};
24549
+ }
24550
+ }
24551
+ ];
24552
+ }
24553
+ }).configure({ multicolor: true }),
24351
24554
  Link.configure({
24352
24555
  openOnClick: false,
24353
24556
  HTMLAttributes: {
@@ -24358,6 +24561,7 @@ function getExtensions(placeholder) {
24358
24561
  Placeholder.configure({
24359
24562
  placeholder: placeholder ?? "Type something..."
24360
24563
  }),
24564
+ Indent,
24361
24565
  VariableNode
24362
24566
  ];
24363
24567
  }
@@ -24374,6 +24578,7 @@ var ALLOWED_TAGS2 = /* @__PURE__ */ new Set([
24374
24578
  "s",
24375
24579
  "a",
24376
24580
  "span",
24581
+ "mark",
24377
24582
  "h1",
24378
24583
  "h2",
24379
24584
  "h3",
@@ -24577,240 +24782,591 @@ function TipTapEditor({
24577
24782
  }
24578
24783
 
24579
24784
  // src/components/Toolbar/RichTextToolbar.tsx
24580
- import { useState as useState6, useCallback as useCallback11, useRef as useRef10, useEffect as useEffect9 } from "react";
24581
- import { jsx as jsx10, jsxs as jsxs8 } from "react/jsx-runtime";
24582
- function preventBlur(e) {
24583
- const target = e.target;
24584
- const tag = target.tagName.toLowerCase();
24585
- if (tag === "select" || tag === "option" || tag === "input" && target.type === "color") {
24586
- return;
24587
- }
24588
- e.preventDefault();
24785
+ import { useState as useState9, useCallback as useCallback13, useRef as useRef12, useEffect as useEffect10 } from "react";
24786
+
24787
+ // src/components/shared/HslColorArea.tsx
24788
+ import { useRef as useRef10, useCallback as useCallback11, useEffect as useEffect9, useState as useState7 } from "react";
24789
+
24790
+ // src/utils/colorConvert.ts
24791
+ function hexToHsl(hex) {
24792
+ const result = /^#?([a-f\d]{2})([a-f\d]{2})([a-f\d]{2})$/i.exec(hex);
24793
+ if (!result) return { h: 0, s: 0, l: 0 };
24794
+ const r = parseInt(result[1], 16) / 255;
24795
+ const g = parseInt(result[2], 16) / 255;
24796
+ const b = parseInt(result[3], 16) / 255;
24797
+ const max = Math.max(r, g, b);
24798
+ const min = Math.min(r, g, b);
24799
+ const l = (max + min) / 2;
24800
+ let h = 0;
24801
+ let s = 0;
24802
+ if (max !== min) {
24803
+ const d = max - min;
24804
+ s = l > 0.5 ? d / (2 - max - min) : d / (max + min);
24805
+ if (max === r) h = ((g - b) / d + (g < b ? 6 : 0)) / 6;
24806
+ else if (max === g) h = ((b - r) / d + 2) / 6;
24807
+ else h = ((r - g) / d + 4) / 6;
24808
+ }
24809
+ return { h: Math.round(h * 360), s: Math.round(s * 100), l: Math.round(l * 100) };
24810
+ }
24811
+ function hslToHex(h, s, l) {
24812
+ const sN = s / 100;
24813
+ const lN = l / 100;
24814
+ const a = sN * Math.min(lN, 1 - lN);
24815
+ const f = (n) => {
24816
+ const k = (n + h / 30) % 12;
24817
+ const color = lN - a * Math.max(Math.min(k - 3, 9 - k, 1), -1);
24818
+ return Math.round(255 * color).toString(16).padStart(2, "0");
24819
+ };
24820
+ return `#${f(0)}${f(8)}${f(4)}`;
24589
24821
  }
24590
- function RichTextToolbar({ editor }) {
24591
- if (!editor) return null;
24592
- return /* @__PURE__ */ jsxs8("div", { className: `ee-richtext-toolbar ${toolbar_default.richTextToolbar}`, onMouseDown: preventBlur, children: [
24593
- /* @__PURE__ */ jsx10(FontFamilySelect, { editor }),
24594
- /* @__PURE__ */ jsx10("div", { className: `ee-richtext-separator ${toolbar_default.richTextSeparator}` }),
24595
- /* @__PURE__ */ jsx10(FontSizeSelect, { editor }),
24596
- /* @__PURE__ */ jsx10("div", { className: `ee-richtext-separator ${toolbar_default.richTextSeparator}` }),
24597
- /* @__PURE__ */ jsx10(
24598
- "button",
24599
- {
24600
- className: `ee-richtext-btn ee-richtext-bold ${toolbar_default.richTextBtn} ${editor.isActive("bold") ? toolbar_default.richTextBtnActive : ""}`,
24601
- onClick: () => editor.chain().focus().toggleBold().run(),
24602
- title: "Bold (Ctrl+B)",
24603
- "aria-label": "Bold (Ctrl+B)",
24604
- "aria-pressed": editor.isActive("bold"),
24605
- children: /* @__PURE__ */ jsx10("strong", { children: "B" })
24606
- }
24607
- ),
24608
- /* @__PURE__ */ jsx10(
24609
- "button",
24610
- {
24611
- className: `ee-richtext-btn ee-richtext-italic ${toolbar_default.richTextBtn} ${editor.isActive("italic") ? toolbar_default.richTextBtnActive : ""}`,
24612
- onClick: () => editor.chain().focus().toggleItalic().run(),
24613
- title: "Italic (Ctrl+I)",
24614
- "aria-label": "Italic (Ctrl+I)",
24615
- "aria-pressed": editor.isActive("italic"),
24616
- children: /* @__PURE__ */ jsx10("em", { children: "I" })
24617
- }
24618
- ),
24619
- /* @__PURE__ */ jsx10(
24620
- "button",
24621
- {
24622
- className: `ee-richtext-btn ee-richtext-underline ${toolbar_default.richTextBtn} ${editor.isActive("underline") ? toolbar_default.richTextBtnActive : ""}`,
24623
- onClick: () => editor.chain().focus().toggleUnderline().run(),
24624
- title: "Underline (Ctrl+U)",
24625
- "aria-label": "Underline (Ctrl+U)",
24626
- "aria-pressed": editor.isActive("underline"),
24627
- children: /* @__PURE__ */ jsx10("u", { children: "U" })
24628
- }
24629
- ),
24630
- /* @__PURE__ */ jsx10(
24631
- "button",
24632
- {
24633
- className: `ee-richtext-btn ee-richtext-strike ${toolbar_default.richTextBtn} ${editor.isActive("strike") ? toolbar_default.richTextBtnActive : ""}`,
24634
- onClick: () => editor.chain().focus().toggleStrike().run(),
24635
- title: "Strikethrough (Ctrl+Shift+X)",
24636
- "aria-label": "Strikethrough (Ctrl+Shift+X)",
24637
- "aria-pressed": editor.isActive("strike"),
24638
- children: /* @__PURE__ */ jsx10("s", { children: "S" })
24639
- }
24640
- ),
24641
- /* @__PURE__ */ jsx10("div", { className: `ee-richtext-separator ${toolbar_default.richTextSeparator}` }),
24642
- /* @__PURE__ */ jsx10(
24643
- InlineColorPicker,
24644
- {
24645
- editor,
24646
- type: "color",
24647
- title: "Text Color",
24648
- label: "A"
24649
- }
24650
- ),
24651
- /* @__PURE__ */ jsx10(
24652
- InlineColorPicker,
24653
- {
24654
- editor,
24655
- type: "highlight",
24656
- title: "Highlight",
24657
- label: "H"
24658
- }
24659
- ),
24660
- /* @__PURE__ */ jsx10("div", { className: `ee-richtext-separator ${toolbar_default.richTextSeparator}` }),
24661
- /* @__PURE__ */ jsx10(
24662
- "button",
24663
- {
24664
- className: `ee-richtext-btn ee-richtext-align-left ${toolbar_default.richTextBtn} ${editor.isActive({ textAlign: "left" }) ? toolbar_default.richTextBtnActive : ""}`,
24665
- onClick: () => editor.chain().focus().setTextAlign("left").run(),
24666
- title: "Align Left",
24667
- "aria-label": "Align Left",
24668
- "aria-pressed": editor.isActive({ textAlign: "left" }),
24669
- children: "L"
24670
- }
24671
- ),
24672
- /* @__PURE__ */ jsx10(
24673
- "button",
24674
- {
24675
- className: `ee-richtext-btn ee-richtext-align-center ${toolbar_default.richTextBtn} ${editor.isActive({ textAlign: "center" }) ? toolbar_default.richTextBtnActive : ""}`,
24676
- onClick: () => editor.chain().focus().setTextAlign("center").run(),
24677
- title: "Align Center",
24678
- "aria-label": "Align Center",
24679
- "aria-pressed": editor.isActive({ textAlign: "center" }),
24680
- children: "C"
24681
- }
24682
- ),
24683
- /* @__PURE__ */ jsx10(
24684
- "button",
24685
- {
24686
- className: `ee-richtext-btn ee-richtext-align-right ${toolbar_default.richTextBtn} ${editor.isActive({ textAlign: "right" }) ? toolbar_default.richTextBtnActive : ""}`,
24687
- onClick: () => editor.chain().focus().setTextAlign("right").run(),
24688
- title: "Align Right",
24689
- "aria-label": "Align Right",
24690
- "aria-pressed": editor.isActive({ textAlign: "right" }),
24691
- children: "R"
24692
- }
24693
- ),
24694
- /* @__PURE__ */ jsx10("div", { className: `ee-richtext-separator ${toolbar_default.richTextSeparator}` }),
24695
- /* @__PURE__ */ jsx10(
24696
- "button",
24697
- {
24698
- className: `ee-richtext-btn ee-richtext-bullet-list ${toolbar_default.richTextBtn} ${editor.isActive("bulletList") ? toolbar_default.richTextBtnActive : ""}`,
24699
- onClick: () => editor.chain().focus().toggleBulletList().run(),
24700
- title: "Bullet List",
24701
- "aria-label": "Bullet List",
24702
- "aria-pressed": editor.isActive("bulletList"),
24703
- children: "\u2022"
24704
- }
24705
- ),
24822
+
24823
+ // src/styles/colorArea.module.css
24824
+ var colorArea_default = {
24825
+ "hslPicker": "hslPicker",
24826
+ "hslArea": "hslArea",
24827
+ "hslAreaThumb": "hslAreaThumb",
24828
+ "hslHueBar": "hslHueBar",
24829
+ "hslHueThumb": "hslHueThumb"
24830
+ };
24831
+
24832
+ // src/components/shared/HslColorArea.tsx
24833
+ import { jsx as jsx10, jsxs as jsxs8 } from "react/jsx-runtime";
24834
+ function HslColorArea({ value, onChange, onChangeEnd }) {
24835
+ const [hsl, setHsl] = useState7(() => hexToHsl(value));
24836
+ const areaRef = useRef10(null);
24837
+ const hueRef = useRef10(null);
24838
+ const draggingArea = useRef10(false);
24839
+ const draggingHue = useRef10(false);
24840
+ const latestHex = useRef10(value);
24841
+ useEffect9(() => {
24842
+ const parsed = hexToHsl(value);
24843
+ setHsl(parsed);
24844
+ }, [value]);
24845
+ const emitColor = useCallback11(
24846
+ (h, s, l) => {
24847
+ setHsl({ h, s, l });
24848
+ const hex = hslToHex(h, s, l);
24849
+ latestHex.current = hex;
24850
+ onChange(hex);
24851
+ },
24852
+ [onChange]
24853
+ );
24854
+ const handleAreaPointer = useCallback11(
24855
+ (e) => {
24856
+ const rect = areaRef.current?.getBoundingClientRect();
24857
+ if (!rect) return;
24858
+ const x = Math.max(0, Math.min(e.clientX - rect.left, rect.width));
24859
+ const y = Math.max(0, Math.min(e.clientY - rect.top, rect.height));
24860
+ const s = Math.round(x / rect.width * 100);
24861
+ const l = Math.round(100 - y / rect.height * 100);
24862
+ emitColor(hsl.h, s, l);
24863
+ },
24864
+ [hsl.h, emitColor]
24865
+ );
24866
+ const onAreaPointerDown = useCallback11(
24867
+ (e) => {
24868
+ e.preventDefault();
24869
+ draggingArea.current = true;
24870
+ e.target.setPointerCapture(e.pointerId);
24871
+ handleAreaPointer(e);
24872
+ },
24873
+ [handleAreaPointer]
24874
+ );
24875
+ const onAreaPointerMove = useCallback11(
24876
+ (e) => {
24877
+ if (!draggingArea.current) return;
24878
+ handleAreaPointer(e);
24879
+ },
24880
+ [handleAreaPointer]
24881
+ );
24882
+ const onAreaPointerUp = useCallback11(() => {
24883
+ draggingArea.current = false;
24884
+ onChangeEnd?.(latestHex.current);
24885
+ }, [onChangeEnd]);
24886
+ const handleHuePointer = useCallback11(
24887
+ (e) => {
24888
+ const rect = hueRef.current?.getBoundingClientRect();
24889
+ if (!rect) return;
24890
+ const x = Math.max(0, Math.min(e.clientX - rect.left, rect.width));
24891
+ const h = Math.round(x / rect.width * 360);
24892
+ emitColor(h, hsl.s, hsl.l);
24893
+ },
24894
+ [hsl.s, hsl.l, emitColor]
24895
+ );
24896
+ const onHuePointerDown = useCallback11(
24897
+ (e) => {
24898
+ e.preventDefault();
24899
+ draggingHue.current = true;
24900
+ e.target.setPointerCapture(e.pointerId);
24901
+ handleHuePointer(e);
24902
+ },
24903
+ [handleHuePointer]
24904
+ );
24905
+ const onHuePointerMove = useCallback11(
24906
+ (e) => {
24907
+ if (!draggingHue.current) return;
24908
+ handleHuePointer(e);
24909
+ },
24910
+ [handleHuePointer]
24911
+ );
24912
+ const onHuePointerUp = useCallback11(() => {
24913
+ draggingHue.current = false;
24914
+ onChangeEnd?.(latestHex.current);
24915
+ }, [onChangeEnd]);
24916
+ const areaBackground = `linear-gradient(to top, #000, transparent), linear-gradient(to right, #fff, hsl(${hsl.h}, 100%, 50%))`;
24917
+ return /* @__PURE__ */ jsxs8("div", { className: colorArea_default.hslPicker, children: [
24706
24918
  /* @__PURE__ */ jsx10(
24707
- "button",
24919
+ "div",
24708
24920
  {
24709
- className: `ee-richtext-btn ee-richtext-ordered-list ${toolbar_default.richTextBtn} ${editor.isActive("orderedList") ? toolbar_default.richTextBtnActive : ""}`,
24710
- onClick: () => editor.chain().focus().toggleOrderedList().run(),
24711
- title: "Ordered List",
24712
- "aria-label": "Ordered List",
24713
- "aria-pressed": editor.isActive("orderedList"),
24714
- children: "1."
24921
+ ref: areaRef,
24922
+ className: colorArea_default.hslArea,
24923
+ style: { background: areaBackground },
24924
+ onPointerDown: onAreaPointerDown,
24925
+ onPointerMove: onAreaPointerMove,
24926
+ onPointerUp: onAreaPointerUp,
24927
+ children: /* @__PURE__ */ jsx10(
24928
+ "div",
24929
+ {
24930
+ className: colorArea_default.hslAreaThumb,
24931
+ style: {
24932
+ left: `${hsl.s}%`,
24933
+ top: `${100 - hsl.l}%`,
24934
+ backgroundColor: value
24935
+ }
24936
+ }
24937
+ )
24715
24938
  }
24716
24939
  ),
24717
- /* @__PURE__ */ jsx10("div", { className: `ee-richtext-separator ${toolbar_default.richTextSeparator}` }),
24718
- /* @__PURE__ */ jsx10(InlineLinkEditor, { editor }),
24719
24940
  /* @__PURE__ */ jsx10(
24720
- "button",
24941
+ "div",
24721
24942
  {
24722
- className: `ee-richtext-btn ee-richtext-clear ${toolbar_default.richTextBtn}`,
24723
- onClick: () => editor.chain().focus().unsetAllMarks().run(),
24724
- title: "Clear Formatting",
24725
- "aria-label": "Clear Formatting",
24726
- children: "\u2716"
24943
+ ref: hueRef,
24944
+ className: colorArea_default.hslHueBar,
24945
+ onPointerDown: onHuePointerDown,
24946
+ onPointerMove: onHuePointerMove,
24947
+ onPointerUp: onHuePointerUp,
24948
+ children: /* @__PURE__ */ jsx10(
24949
+ "div",
24950
+ {
24951
+ className: colorArea_default.hslHueThumb,
24952
+ style: {
24953
+ left: `${hsl.h / 360 * 100}%`,
24954
+ backgroundColor: `hsl(${hsl.h}, 100%, 50%)`
24955
+ }
24956
+ }
24957
+ )
24727
24958
  }
24728
24959
  )
24729
24960
  ] });
24730
24961
  }
24731
- function FontFamilySelect({ editor }) {
24732
- const { fontFamilies } = useEditorFonts();
24733
- const currentFont = editor.getAttributes("textStyle").fontFamily || "";
24734
- const fonts = fontFamilies.slice();
24735
- if (currentFont && !fonts.some((f) => f.toLowerCase() === currentFont.toLowerCase())) {
24736
- fonts.push(currentFont);
24737
- }
24738
- return /* @__PURE__ */ jsxs8(
24739
- "select",
24962
+
24963
+ // src/components/Toolbar/toolbar-icons.tsx
24964
+ import { jsx as jsx11, jsxs as jsxs9 } from "react/jsx-runtime";
24965
+ var BoldIcon = ({ size = 14, color = "currentColor" }) => /* @__PURE__ */ jsxs9("svg", { width: size, height: size, viewBox: "0 0 24 24", fill: "none", stroke: color, strokeWidth: "2", strokeLinecap: "round", strokeLinejoin: "round", xmlns: "http://www.w3.org/2000/svg", children: [
24966
+ /* @__PURE__ */ jsx11("path", { d: "M6 4h8a4 4 0 0 1 4 4 4 4 0 0 1-4 4H6z" }),
24967
+ /* @__PURE__ */ jsx11("path", { d: "M6 12h9a4 4 0 0 1 4 4 4 4 0 0 1-4 4H6z" })
24968
+ ] });
24969
+ var ItalicIcon = ({ size = 14, color = "currentColor" }) => /* @__PURE__ */ jsxs9("svg", { width: size, height: size, viewBox: "0 0 24 24", fill: "none", stroke: color, strokeWidth: "2", strokeLinecap: "round", strokeLinejoin: "round", xmlns: "http://www.w3.org/2000/svg", children: [
24970
+ /* @__PURE__ */ jsx11("line", { x1: "19", y1: "4", x2: "10", y2: "4" }),
24971
+ /* @__PURE__ */ jsx11("line", { x1: "14", y1: "20", x2: "5", y2: "20" }),
24972
+ /* @__PURE__ */ jsx11("line", { x1: "15", y1: "4", x2: "9", y2: "20" })
24973
+ ] });
24974
+ var UnderlineIcon = ({ size = 14, color = "currentColor" }) => /* @__PURE__ */ jsxs9("svg", { width: size, height: size, viewBox: "0 0 24 24", fill: "none", stroke: color, strokeWidth: "2", strokeLinecap: "round", strokeLinejoin: "round", xmlns: "http://www.w3.org/2000/svg", children: [
24975
+ /* @__PURE__ */ jsx11("path", { d: "M6 3v7a6 6 0 0 0 6 6 6 6 0 0 0 6-6V3" }),
24976
+ /* @__PURE__ */ jsx11("line", { x1: "4", y1: "21", x2: "20", y2: "21" })
24977
+ ] });
24978
+ var StrikethroughIcon = ({ size = 14, color = "currentColor" }) => /* @__PURE__ */ jsxs9("svg", { width: size, height: size, viewBox: "0 0 24 24", fill: "none", stroke: color, strokeWidth: "2", strokeLinecap: "round", strokeLinejoin: "round", xmlns: "http://www.w3.org/2000/svg", children: [
24979
+ /* @__PURE__ */ jsx11("path", { d: "M16 4H9a3 3 0 0 0-3 3c0 2 1.5 3 3 3" }),
24980
+ /* @__PURE__ */ jsx11("path", { d: "M12 15c1.5 0 3 1 3 3a3 3 0 0 1-3 3H8" }),
24981
+ /* @__PURE__ */ jsx11("line", { x1: "4", y1: "12", x2: "20", y2: "12" })
24982
+ ] });
24983
+ var AlignLeftIcon = ({ size = 14, color = "currentColor" }) => /* @__PURE__ */ jsxs9("svg", { width: size, height: size, viewBox: "0 0 24 24", fill: "none", stroke: color, strokeWidth: "2", strokeLinecap: "round", strokeLinejoin: "round", xmlns: "http://www.w3.org/2000/svg", children: [
24984
+ /* @__PURE__ */ jsx11("line", { x1: "17", y1: "10", x2: "3", y2: "10" }),
24985
+ /* @__PURE__ */ jsx11("line", { x1: "21", y1: "6", x2: "3", y2: "6" }),
24986
+ /* @__PURE__ */ jsx11("line", { x1: "21", y1: "14", x2: "3", y2: "14" }),
24987
+ /* @__PURE__ */ jsx11("line", { x1: "17", y1: "18", x2: "3", y2: "18" })
24988
+ ] });
24989
+ var AlignCenterIcon = ({ size = 14, color = "currentColor" }) => /* @__PURE__ */ jsxs9("svg", { width: size, height: size, viewBox: "0 0 24 24", fill: "none", stroke: color, strokeWidth: "2", strokeLinecap: "round", strokeLinejoin: "round", xmlns: "http://www.w3.org/2000/svg", children: [
24990
+ /* @__PURE__ */ jsx11("line", { x1: "18", y1: "10", x2: "6", y2: "10" }),
24991
+ /* @__PURE__ */ jsx11("line", { x1: "21", y1: "6", x2: "3", y2: "6" }),
24992
+ /* @__PURE__ */ jsx11("line", { x1: "21", y1: "14", x2: "3", y2: "14" }),
24993
+ /* @__PURE__ */ jsx11("line", { x1: "18", y1: "18", x2: "6", y2: "18" })
24994
+ ] });
24995
+ var AlignRightIcon = ({ size = 14, color = "currentColor" }) => /* @__PURE__ */ jsxs9("svg", { width: size, height: size, viewBox: "0 0 24 24", fill: "none", stroke: color, strokeWidth: "2", strokeLinecap: "round", strokeLinejoin: "round", xmlns: "http://www.w3.org/2000/svg", children: [
24996
+ /* @__PURE__ */ jsx11("line", { x1: "21", y1: "10", x2: "7", y2: "10" }),
24997
+ /* @__PURE__ */ jsx11("line", { x1: "21", y1: "6", x2: "3", y2: "6" }),
24998
+ /* @__PURE__ */ jsx11("line", { x1: "21", y1: "14", x2: "3", y2: "14" }),
24999
+ /* @__PURE__ */ jsx11("line", { x1: "21", y1: "18", x2: "7", y2: "18" })
25000
+ ] });
25001
+ var BulletListIcon = ({ size = 14, color = "currentColor" }) => /* @__PURE__ */ jsxs9("svg", { width: size, height: size, viewBox: "0 0 24 24", fill: "none", stroke: color, strokeWidth: "2", strokeLinecap: "round", strokeLinejoin: "round", xmlns: "http://www.w3.org/2000/svg", children: [
25002
+ /* @__PURE__ */ jsx11("line", { x1: "8", y1: "6", x2: "21", y2: "6" }),
25003
+ /* @__PURE__ */ jsx11("line", { x1: "8", y1: "12", x2: "21", y2: "12" }),
25004
+ /* @__PURE__ */ jsx11("line", { x1: "8", y1: "18", x2: "21", y2: "18" }),
25005
+ /* @__PURE__ */ jsx11("circle", { cx: "4", cy: "6", r: "1", fill: color }),
25006
+ /* @__PURE__ */ jsx11("circle", { cx: "4", cy: "12", r: "1", fill: color }),
25007
+ /* @__PURE__ */ jsx11("circle", { cx: "4", cy: "18", r: "1", fill: color })
25008
+ ] });
25009
+ var OrderedListIcon = ({ size = 14, color = "currentColor" }) => /* @__PURE__ */ jsxs9("svg", { width: size, height: size, viewBox: "0 0 24 24", fill: "none", stroke: color, strokeWidth: "2", strokeLinecap: "round", strokeLinejoin: "round", xmlns: "http://www.w3.org/2000/svg", children: [
25010
+ /* @__PURE__ */ jsx11("line", { x1: "10", y1: "6", x2: "21", y2: "6" }),
25011
+ /* @__PURE__ */ jsx11("line", { x1: "10", y1: "12", x2: "21", y2: "12" }),
25012
+ /* @__PURE__ */ jsx11("line", { x1: "10", y1: "18", x2: "21", y2: "18" }),
25013
+ /* @__PURE__ */ jsx11("text", { x: "2", y: "8", fontSize: "8", fill: color, stroke: "none", fontFamily: "sans-serif", fontWeight: "bold", children: "1" }),
25014
+ /* @__PURE__ */ jsx11("text", { x: "2", y: "14", fontSize: "8", fill: color, stroke: "none", fontFamily: "sans-serif", fontWeight: "bold", children: "2" }),
25015
+ /* @__PURE__ */ jsx11("text", { x: "2", y: "20", fontSize: "8", fill: color, stroke: "none", fontFamily: "sans-serif", fontWeight: "bold", children: "3" })
25016
+ ] });
25017
+ var IndentIcon = ({ size = 14, color = "currentColor" }) => /* @__PURE__ */ jsxs9("svg", { width: size, height: size, viewBox: "0 0 24 24", fill: "none", stroke: color, strokeWidth: "2", strokeLinecap: "round", strokeLinejoin: "round", xmlns: "http://www.w3.org/2000/svg", children: [
25018
+ /* @__PURE__ */ jsx11("line", { x1: "21", y1: "6", x2: "3", y2: "6" }),
25019
+ /* @__PURE__ */ jsx11("line", { x1: "21", y1: "14", x2: "3", y2: "14" }),
25020
+ /* @__PURE__ */ jsx11("line", { x1: "21", y1: "10", x2: "11", y2: "10" }),
25021
+ /* @__PURE__ */ jsx11("line", { x1: "21", y1: "18", x2: "11", y2: "18" }),
25022
+ /* @__PURE__ */ jsx11("polyline", { points: "3 8 7 10 3 12" })
25023
+ ] });
25024
+ var OutdentIcon = ({ size = 14, color = "currentColor" }) => /* @__PURE__ */ jsxs9("svg", { width: size, height: size, viewBox: "0 0 24 24", fill: "none", stroke: color, strokeWidth: "2", strokeLinecap: "round", strokeLinejoin: "round", xmlns: "http://www.w3.org/2000/svg", children: [
25025
+ /* @__PURE__ */ jsx11("line", { x1: "21", y1: "6", x2: "3", y2: "6" }),
25026
+ /* @__PURE__ */ jsx11("line", { x1: "21", y1: "14", x2: "3", y2: "14" }),
25027
+ /* @__PURE__ */ jsx11("line", { x1: "21", y1: "10", x2: "11", y2: "10" }),
25028
+ /* @__PURE__ */ jsx11("line", { x1: "21", y1: "18", x2: "11", y2: "18" }),
25029
+ /* @__PURE__ */ jsx11("polyline", { points: "7 8 3 10 7 12" })
25030
+ ] });
25031
+ var TextColorIcon = ({ size = 14, color = "currentColor" }) => /* @__PURE__ */ jsxs9("svg", { width: size, height: size, viewBox: "0 0 24 24", fill: "none", stroke: color, strokeWidth: "2", strokeLinecap: "round", strokeLinejoin: "round", xmlns: "http://www.w3.org/2000/svg", children: [
25032
+ /* @__PURE__ */ jsx11("path", { d: "M5 18h14", stroke: "none" }),
25033
+ /* @__PURE__ */ jsx11("path", { d: "M9 3L5 15h2l1-3h8l1 3h2L15 3H9z", fill: "none", stroke: color, strokeWidth: "1.5" }),
25034
+ /* @__PURE__ */ jsx11("path", { d: "M9.5 10l2.5-6 2.5 6h-5z", fill: "none" })
25035
+ ] });
25036
+ var HighlightIcon = ({ size = 14, color = "currentColor" }) => /* @__PURE__ */ jsxs9("svg", { width: size, height: size, viewBox: "0 0 24 24", fill: "none", stroke: color, strokeWidth: "2", strokeLinecap: "round", strokeLinejoin: "round", xmlns: "http://www.w3.org/2000/svg", children: [
25037
+ /* @__PURE__ */ jsx11("path", { d: "M12 20h9" }),
25038
+ /* @__PURE__ */ jsx11("path", { d: "M16.5 3.5a2.121 2.121 0 0 1 3 3L7 19l-4 1 1-4L16.5 3.5z" })
25039
+ ] });
25040
+ var LinkIcon = ({ size = 14, color = "currentColor" }) => /* @__PURE__ */ jsxs9("svg", { width: size, height: size, viewBox: "0 0 24 24", fill: "none", stroke: color, strokeWidth: "2", strokeLinecap: "round", strokeLinejoin: "round", xmlns: "http://www.w3.org/2000/svg", children: [
25041
+ /* @__PURE__ */ jsx11("path", { d: "M10 13a5 5 0 0 0 7.54.54l3-3a5 5 0 0 0-7.07-7.07l-1.72 1.71" }),
25042
+ /* @__PURE__ */ jsx11("path", { d: "M14 11a5 5 0 0 0-7.54-.54l-3 3a5 5 0 0 0 7.07 7.07l1.71-1.71" })
25043
+ ] });
25044
+ var ClearFormattingIcon = ({ size = 14, color = "currentColor" }) => /* @__PURE__ */ jsxs9("svg", { width: size, height: size, viewBox: "0 0 24 24", fill: "none", stroke: color, strokeWidth: "2", strokeLinecap: "round", strokeLinejoin: "round", xmlns: "http://www.w3.org/2000/svg", children: [
25045
+ /* @__PURE__ */ jsx11("path", { d: "M6 4h12l-6 16" }),
25046
+ /* @__PURE__ */ jsx11("line", { x1: "2", y1: "2", x2: "22", y2: "22" })
25047
+ ] });
25048
+ var AlignJustifyIcon = ({ size = 14, color = "currentColor" }) => /* @__PURE__ */ jsxs9("svg", { width: size, height: size, viewBox: "0 0 24 24", fill: "none", stroke: color, strokeWidth: "2", strokeLinecap: "round", strokeLinejoin: "round", xmlns: "http://www.w3.org/2000/svg", children: [
25049
+ /* @__PURE__ */ jsx11("line", { x1: "21", y1: "10", x2: "3", y2: "10" }),
25050
+ /* @__PURE__ */ jsx11("line", { x1: "21", y1: "6", x2: "3", y2: "6" }),
25051
+ /* @__PURE__ */ jsx11("line", { x1: "21", y1: "14", x2: "3", y2: "14" }),
25052
+ /* @__PURE__ */ jsx11("line", { x1: "21", y1: "18", x2: "3", y2: "18" })
25053
+ ] });
25054
+ var HorizontalRuleIcon = ({ size = 14, color = "currentColor" }) => /* @__PURE__ */ jsx11("svg", { width: size, height: size, viewBox: "0 0 24 24", fill: "none", stroke: color, strokeWidth: "2", strokeLinecap: "round", strokeLinejoin: "round", xmlns: "http://www.w3.org/2000/svg", children: /* @__PURE__ */ jsx11("line", { x1: "3", y1: "12", x2: "21", y2: "12" }) });
25055
+
25056
+ // src/components/Toolbar/Tooltip.tsx
25057
+ import { useState as useState8, useRef as useRef11, useCallback as useCallback12 } from "react";
25058
+ import { jsx as jsx12, jsxs as jsxs10 } from "react/jsx-runtime";
25059
+ function Tooltip({ label, shortcut, children }) {
25060
+ const [visible, setVisible] = useState8(false);
25061
+ const timerRef = useRef11(null);
25062
+ const show = useCallback12(() => {
25063
+ timerRef.current = setTimeout(() => setVisible(true), 400);
25064
+ }, []);
25065
+ const hide = useCallback12(() => {
25066
+ if (timerRef.current) clearTimeout(timerRef.current);
25067
+ timerRef.current = null;
25068
+ setVisible(false);
25069
+ }, []);
25070
+ return /* @__PURE__ */ jsxs10(
25071
+ "span",
24740
25072
  {
24741
- className: `ee-richtext-font-select ${toolbar_default.richTextSelect}`,
24742
- value: currentFont,
24743
- onChange: (e) => {
24744
- const value = e.target.value;
24745
- if (value) {
24746
- editor.chain().focus().setFontFamily(value).run();
24747
- } else {
24748
- editor.chain().focus().unsetFontFamily().run();
24749
- }
24750
- },
24751
- title: "Font Family",
25073
+ className: toolbar_default.richTextTooltipWrapper,
25074
+ onMouseEnter: show,
25075
+ onMouseLeave: hide,
25076
+ onFocus: show,
25077
+ onBlur: hide,
24752
25078
  children: [
24753
- /* @__PURE__ */ jsx10("option", { value: "", children: "Default" }),
24754
- fonts.map((font) => /* @__PURE__ */ jsx10("option", { value: font, style: { fontFamily: font }, children: font.split(",")[0].trim() }, font))
25079
+ children,
25080
+ visible && /* @__PURE__ */ jsxs10("span", { className: toolbar_default.richTextTooltip, role: "tooltip", children: [
25081
+ /* @__PURE__ */ jsx12("span", { children: label }),
25082
+ shortcut && /* @__PURE__ */ jsx12("kbd", { className: toolbar_default.richTextTooltipShortcut, children: shortcut })
25083
+ ] })
24755
25084
  ]
24756
25085
  }
24757
25086
  );
24758
25087
  }
24759
- function FontSizeSelect({ editor }) {
24760
- const { fontSizes } = useEditorFonts();
24761
- const currentSize = editor.getAttributes("textStyle").fontSize || "";
24762
- const sizes = fontSizes.slice();
24763
- if (currentSize && !sizes.includes(currentSize)) {
24764
- sizes.push(currentSize);
24765
- sizes.sort((a, b) => parseInt(a, 10) - parseInt(b, 10));
25088
+
25089
+ // src/components/Toolbar/RichTextToolbar.tsx
25090
+ import { Fragment as Fragment2, jsx as jsx13, jsxs as jsxs11 } from "react/jsx-runtime";
25091
+ function preventBlur(e) {
25092
+ const target = e.target;
25093
+ const tag = target.tagName.toLowerCase();
25094
+ if (tag === "select" || tag === "option" || tag === "input") {
25095
+ return;
24766
25096
  }
24767
- return /* @__PURE__ */ jsxs8(
24768
- "select",
24769
- {
24770
- className: `ee-richtext-size-select ${toolbar_default.richTextSelectSmall}`,
24771
- value: currentSize,
24772
- onChange: (e) => {
24773
- const value = e.target.value;
24774
- if (value) {
24775
- editor.chain().focus().setFontSize(value).run();
24776
- } else {
24777
- editor.chain().focus().unsetFontSize().run();
24778
- }
24779
- },
24780
- title: "Font Size",
24781
- children: [
24782
- /* @__PURE__ */ jsx10("option", { value: "", children: "Size" }),
24783
- sizes.map((size) => /* @__PURE__ */ jsx10("option", { value: size, children: parseInt(size, 10) }, size))
24784
- ]
24785
- }
24786
- );
25097
+ e.preventDefault();
24787
25098
  }
24788
- function InlineLinkEditor({ editor }) {
24789
- const [isOpen, setIsOpen] = useState6(false);
24790
- const [url, setUrl] = useState6("");
24791
- const wrapperRef = useRef10(null);
24792
- const inputRef = useRef10(null);
24793
- const isActive2 = editor.isActive("link");
24794
- const currentHref = editor.getAttributes("link").href || "";
24795
- useEffect9(() => {
24796
- function handleClickOutside(e) {
24797
- if (wrapperRef.current && !wrapperRef.current.contains(e.target)) {
24798
- setIsOpen(false);
24799
- }
24800
- }
24801
- if (isOpen) {
24802
- document.addEventListener("mousedown", handleClickOutside);
25099
+ function RichTextToolbar({ editor }) {
25100
+ if (!editor) return null;
25101
+ return /* @__PURE__ */ jsxs11("div", { className: `ee-richtext-toolbar ${toolbar_default.richTextToolbar}`, onMouseDown: preventBlur, children: [
25102
+ /* @__PURE__ */ jsxs11("div", { className: `ee-richtext-group ${toolbar_default.richTextGroup}`, children: [
25103
+ /* @__PURE__ */ jsx13(FontFamilySelect, { editor }),
25104
+ /* @__PURE__ */ jsx13(FontSizeSelect, { editor })
25105
+ ] }),
25106
+ /* @__PURE__ */ jsxs11("div", { className: `ee-richtext-group ${toolbar_default.richTextGroup}`, children: [
25107
+ /* @__PURE__ */ jsx13(Tooltip, { label: "Bold", shortcut: "Ctrl+B", children: /* @__PURE__ */ jsx13(
25108
+ "button",
25109
+ {
25110
+ className: `ee-richtext-btn ee-richtext-bold ${toolbar_default.richTextBtn} ${editor.isActive("bold") ? toolbar_default.richTextBtnActive : ""}`,
25111
+ onClick: () => editor.chain().focus().toggleBold().run(),
25112
+ "aria-label": "Bold",
25113
+ "aria-pressed": editor.isActive("bold"),
25114
+ children: /* @__PURE__ */ jsx13(BoldIcon, {})
25115
+ }
25116
+ ) }),
25117
+ /* @__PURE__ */ jsx13(Tooltip, { label: "Italic", shortcut: "Ctrl+I", children: /* @__PURE__ */ jsx13(
25118
+ "button",
25119
+ {
25120
+ className: `ee-richtext-btn ee-richtext-italic ${toolbar_default.richTextBtn} ${editor.isActive("italic") ? toolbar_default.richTextBtnActive : ""}`,
25121
+ onClick: () => editor.chain().focus().toggleItalic().run(),
25122
+ "aria-label": "Italic",
25123
+ "aria-pressed": editor.isActive("italic"),
25124
+ children: /* @__PURE__ */ jsx13(ItalicIcon, {})
25125
+ }
25126
+ ) }),
25127
+ /* @__PURE__ */ jsx13(Tooltip, { label: "Underline", shortcut: "Ctrl+U", children: /* @__PURE__ */ jsx13(
25128
+ "button",
25129
+ {
25130
+ className: `ee-richtext-btn ee-richtext-underline ${toolbar_default.richTextBtn} ${editor.isActive("underline") ? toolbar_default.richTextBtnActive : ""}`,
25131
+ onClick: () => editor.chain().focus().toggleUnderline().run(),
25132
+ "aria-label": "Underline",
25133
+ "aria-pressed": editor.isActive("underline"),
25134
+ children: /* @__PURE__ */ jsx13(UnderlineIcon, {})
25135
+ }
25136
+ ) }),
25137
+ /* @__PURE__ */ jsx13(Tooltip, { label: "Strikethrough", shortcut: "Ctrl+Shift+X", children: /* @__PURE__ */ jsx13(
25138
+ "button",
25139
+ {
25140
+ className: `ee-richtext-btn ee-richtext-strike ${toolbar_default.richTextBtn} ${editor.isActive("strike") ? toolbar_default.richTextBtnActive : ""}`,
25141
+ onClick: () => editor.chain().focus().toggleStrike().run(),
25142
+ "aria-label": "Strikethrough",
25143
+ "aria-pressed": editor.isActive("strike"),
25144
+ children: /* @__PURE__ */ jsx13(StrikethroughIcon, {})
25145
+ }
25146
+ ) })
25147
+ ] }),
25148
+ /* @__PURE__ */ jsxs11("div", { className: `ee-richtext-group ${toolbar_default.richTextGroup}`, children: [
25149
+ /* @__PURE__ */ jsx13(
25150
+ InlineColorPicker,
25151
+ {
25152
+ editor,
25153
+ type: "color",
25154
+ title: "Text Color",
25155
+ icon: /* @__PURE__ */ jsx13(TextColorIcon, {})
25156
+ }
25157
+ ),
25158
+ /* @__PURE__ */ jsx13(
25159
+ InlineColorPicker,
25160
+ {
25161
+ editor,
25162
+ type: "highlight",
25163
+ title: "Highlight",
25164
+ icon: /* @__PURE__ */ jsx13(HighlightIcon, {})
25165
+ }
25166
+ )
25167
+ ] }),
25168
+ /* @__PURE__ */ jsxs11("div", { className: `ee-richtext-group ${toolbar_default.richTextGroup}`, children: [
25169
+ /* @__PURE__ */ jsx13(Tooltip, { label: "Align Left", shortcut: "Ctrl+Shift+L", children: /* @__PURE__ */ jsx13(
25170
+ "button",
25171
+ {
25172
+ className: `ee-richtext-btn ee-richtext-align-left ${toolbar_default.richTextBtn} ${editor.isActive({ textAlign: "left" }) ? toolbar_default.richTextBtnActive : ""}`,
25173
+ onClick: () => editor.chain().focus().setTextAlign("left").run(),
25174
+ "aria-label": "Align Left",
25175
+ "aria-pressed": editor.isActive({ textAlign: "left" }),
25176
+ children: /* @__PURE__ */ jsx13(AlignLeftIcon, {})
25177
+ }
25178
+ ) }),
25179
+ /* @__PURE__ */ jsx13(Tooltip, { label: "Align Center", shortcut: "Ctrl+Shift+E", children: /* @__PURE__ */ jsx13(
25180
+ "button",
25181
+ {
25182
+ className: `ee-richtext-btn ee-richtext-align-center ${toolbar_default.richTextBtn} ${editor.isActive({ textAlign: "center" }) ? toolbar_default.richTextBtnActive : ""}`,
25183
+ onClick: () => editor.chain().focus().setTextAlign("center").run(),
25184
+ "aria-label": "Align Center",
25185
+ "aria-pressed": editor.isActive({ textAlign: "center" }),
25186
+ children: /* @__PURE__ */ jsx13(AlignCenterIcon, {})
25187
+ }
25188
+ ) }),
25189
+ /* @__PURE__ */ jsx13(Tooltip, { label: "Align Right", shortcut: "Ctrl+Shift+R", children: /* @__PURE__ */ jsx13(
25190
+ "button",
25191
+ {
25192
+ className: `ee-richtext-btn ee-richtext-align-right ${toolbar_default.richTextBtn} ${editor.isActive({ textAlign: "right" }) ? toolbar_default.richTextBtnActive : ""}`,
25193
+ onClick: () => editor.chain().focus().setTextAlign("right").run(),
25194
+ "aria-label": "Align Right",
25195
+ "aria-pressed": editor.isActive({ textAlign: "right" }),
25196
+ children: /* @__PURE__ */ jsx13(AlignRightIcon, {})
25197
+ }
25198
+ ) }),
25199
+ /* @__PURE__ */ jsx13(Tooltip, { label: "Justify", shortcut: "Ctrl+Shift+J", children: /* @__PURE__ */ jsx13(
25200
+ "button",
25201
+ {
25202
+ className: `ee-richtext-btn ee-richtext-align-justify ${toolbar_default.richTextBtn} ${editor.isActive({ textAlign: "justify" }) ? toolbar_default.richTextBtnActive : ""}`,
25203
+ onClick: () => editor.chain().focus().setTextAlign("justify").run(),
25204
+ "aria-label": "Justify",
25205
+ "aria-pressed": editor.isActive({ textAlign: "justify" }),
25206
+ children: /* @__PURE__ */ jsx13(AlignJustifyIcon, {})
25207
+ }
25208
+ ) })
25209
+ ] }),
25210
+ /* @__PURE__ */ jsxs11("div", { className: `ee-richtext-group ${toolbar_default.richTextGroup}`, children: [
25211
+ /* @__PURE__ */ jsx13(Tooltip, { label: "Bullet List", shortcut: "Ctrl+Shift+8", children: /* @__PURE__ */ jsx13(
25212
+ "button",
25213
+ {
25214
+ className: `ee-richtext-btn ee-richtext-bullet-list ${toolbar_default.richTextBtn} ${editor.isActive("bulletList") ? toolbar_default.richTextBtnActive : ""}`,
25215
+ onClick: () => editor.chain().focus().toggleBulletList().run(),
25216
+ "aria-label": "Bullet List",
25217
+ "aria-pressed": editor.isActive("bulletList"),
25218
+ children: /* @__PURE__ */ jsx13(BulletListIcon, {})
25219
+ }
25220
+ ) }),
25221
+ /* @__PURE__ */ jsx13(Tooltip, { label: "Ordered List", shortcut: "Ctrl+Shift+7", children: /* @__PURE__ */ jsx13(
25222
+ "button",
25223
+ {
25224
+ className: `ee-richtext-btn ee-richtext-ordered-list ${toolbar_default.richTextBtn} ${editor.isActive("orderedList") ? toolbar_default.richTextBtnActive : ""}`,
25225
+ onClick: () => editor.chain().focus().toggleOrderedList().run(),
25226
+ "aria-label": "Ordered List",
25227
+ "aria-pressed": editor.isActive("orderedList"),
25228
+ children: /* @__PURE__ */ jsx13(OrderedListIcon, {})
25229
+ }
25230
+ ) }),
25231
+ /* @__PURE__ */ jsx13(Tooltip, { label: "Outdent", shortcut: "Shift+Tab", children: /* @__PURE__ */ jsx13(
25232
+ "button",
25233
+ {
25234
+ className: `ee-richtext-btn ee-richtext-outdent ${toolbar_default.richTextBtn}`,
25235
+ onClick: () => {
25236
+ if (editor.isActive("listItem")) {
25237
+ editor.chain().focus().liftListItem("listItem").run();
25238
+ } else {
25239
+ editor.commands.focus();
25240
+ applyOutdent(editor);
25241
+ }
25242
+ },
25243
+ "aria-label": "Outdent",
25244
+ children: /* @__PURE__ */ jsx13(OutdentIcon, {})
25245
+ }
25246
+ ) }),
25247
+ /* @__PURE__ */ jsx13(Tooltip, { label: "Indent", shortcut: "Tab", children: /* @__PURE__ */ jsx13(
25248
+ "button",
25249
+ {
25250
+ className: `ee-richtext-btn ee-richtext-indent ${toolbar_default.richTextBtn}`,
25251
+ onClick: () => {
25252
+ if (editor.isActive("listItem")) {
25253
+ editor.chain().focus().sinkListItem("listItem").run();
25254
+ } else {
25255
+ editor.commands.focus();
25256
+ applyIndent(editor);
25257
+ }
25258
+ },
25259
+ "aria-label": "Indent",
25260
+ children: /* @__PURE__ */ jsx13(IndentIcon, {})
25261
+ }
25262
+ ) })
25263
+ ] }),
25264
+ /* @__PURE__ */ jsxs11("div", { className: `ee-richtext-group ${toolbar_default.richTextGroup}`, children: [
25265
+ /* @__PURE__ */ jsx13(InlineLinkEditor, { editor }),
25266
+ /* @__PURE__ */ jsx13(Tooltip, { label: "Horizontal Rule", children: /* @__PURE__ */ jsx13(
25267
+ "button",
25268
+ {
25269
+ className: `ee-richtext-btn ee-richtext-hr ${toolbar_default.richTextBtn}`,
25270
+ onClick: () => editor.chain().focus().setHorizontalRule().run(),
25271
+ "aria-label": "Horizontal Rule",
25272
+ children: /* @__PURE__ */ jsx13(HorizontalRuleIcon, {})
25273
+ }
25274
+ ) }),
25275
+ /* @__PURE__ */ jsx13(Tooltip, { label: "Clear Formatting", children: /* @__PURE__ */ jsx13(
25276
+ "button",
25277
+ {
25278
+ className: `ee-richtext-btn ee-richtext-clear ${toolbar_default.richTextBtn}`,
25279
+ onClick: () => editor.chain().focus().unsetAllMarks().run(),
25280
+ "aria-label": "Clear Formatting",
25281
+ children: /* @__PURE__ */ jsx13(ClearFormattingIcon, {})
25282
+ }
25283
+ ) })
25284
+ ] })
25285
+ ] });
25286
+ }
25287
+ function FontFamilySelect({ editor }) {
25288
+ const { fontFamilies } = useEditorFonts();
25289
+ const currentFont = editor.getAttributes("textStyle").fontFamily || "";
25290
+ const fonts = fontFamilies.slice();
25291
+ if (currentFont && !fonts.some((f) => f.toLowerCase() === currentFont.toLowerCase())) {
25292
+ fonts.push(currentFont);
25293
+ }
25294
+ return /* @__PURE__ */ jsxs11(
25295
+ "select",
25296
+ {
25297
+ className: `ee-richtext-font-select ${toolbar_default.richTextSelect}`,
25298
+ value: currentFont,
25299
+ onChange: (e) => {
25300
+ const value = e.target.value;
25301
+ if (value) {
25302
+ editor.chain().focus().setFontFamily(value).run();
25303
+ } else {
25304
+ editor.chain().focus().unsetFontFamily().run();
25305
+ }
25306
+ },
25307
+ title: "Font Family",
25308
+ children: [
25309
+ /* @__PURE__ */ jsx13("option", { value: "", children: "Default" }),
25310
+ fonts.map((font) => /* @__PURE__ */ jsx13("option", { value: font, style: { fontFamily: font }, children: font.split(",")[0].trim() }, font))
25311
+ ]
25312
+ }
25313
+ );
25314
+ }
25315
+ function FontSizeSelect({ editor }) {
25316
+ const { fontSizes } = useEditorFonts();
25317
+ const currentSize = editor.getAttributes("textStyle").fontSize || "";
25318
+ const sizes = fontSizes.slice();
25319
+ if (currentSize && !sizes.includes(currentSize)) {
25320
+ sizes.push(currentSize);
25321
+ sizes.sort((a, b) => parseInt(a, 10) - parseInt(b, 10));
25322
+ }
25323
+ return /* @__PURE__ */ jsxs11(
25324
+ "select",
25325
+ {
25326
+ className: `ee-richtext-size-select ${toolbar_default.richTextSelectSmall}`,
25327
+ value: currentSize,
25328
+ onChange: (e) => {
25329
+ const value = e.target.value;
25330
+ if (value) {
25331
+ editor.chain().focus().setFontSize(value).run();
25332
+ } else {
25333
+ editor.chain().focus().unsetFontSize().run();
25334
+ }
25335
+ },
25336
+ title: "Font Size",
25337
+ children: [
25338
+ /* @__PURE__ */ jsx13("option", { value: "", children: "Size" }),
25339
+ sizes.map((size) => /* @__PURE__ */ jsx13("option", { value: size, children: parseInt(size, 10) }, size))
25340
+ ]
25341
+ }
25342
+ );
25343
+ }
25344
+ function InlineLinkEditor({ editor }) {
25345
+ const [isOpen, setIsOpen] = useState9(false);
25346
+ const [url, setUrl] = useState9("");
25347
+ const wrapperRef = useRef12(null);
25348
+ const inputRef = useRef12(null);
25349
+ const isActive2 = editor.isActive("link");
25350
+ const currentHref = editor.getAttributes("link").href || "";
25351
+ useEffect10(() => {
25352
+ function handleClickOutside(e) {
25353
+ if (wrapperRef.current && !wrapperRef.current.contains(e.target)) {
25354
+ setIsOpen(false);
25355
+ }
25356
+ }
25357
+ if (isOpen) {
25358
+ document.addEventListener("mousedown", handleClickOutside);
24803
25359
  return () => document.removeEventListener("mousedown", handleClickOutside);
24804
25360
  }
24805
25361
  }, [isOpen]);
24806
- const handleOpen = useCallback11(() => {
25362
+ const handleOpen = useCallback13(() => {
24807
25363
  setUrl(currentHref);
24808
25364
  setUrlError("");
24809
25365
  setIsOpen(true);
24810
25366
  setTimeout(() => inputRef.current?.focus(), 50);
24811
25367
  }, [currentHref]);
24812
- const [urlError, setUrlError] = useState6("");
24813
- const handleApply = useCallback11(() => {
25368
+ const [urlError, setUrlError] = useState9("");
25369
+ const handleApply = useCallback13(() => {
24814
25370
  const trimmed = url.trim();
24815
25371
  if (trimmed) {
24816
25372
  if (!isSafeURL(trimmed)) {
@@ -24822,12 +25378,12 @@ function InlineLinkEditor({ editor }) {
24822
25378
  }
24823
25379
  setIsOpen(false);
24824
25380
  }, [editor, url]);
24825
- const handleRemove = useCallback11(() => {
25381
+ const handleRemove = useCallback13(() => {
24826
25382
  editor.chain().focus().unsetLink().run();
24827
25383
  setIsOpen(false);
24828
25384
  setUrl("");
24829
25385
  }, [editor]);
24830
- const handleKeyDown2 = useCallback11(
25386
+ const handleKeyDown2 = useCallback13(
24831
25387
  (e) => {
24832
25388
  if (e.key === "Enter") {
24833
25389
  e.preventDefault();
@@ -24838,8 +25394,8 @@ function InlineLinkEditor({ editor }) {
24838
25394
  },
24839
25395
  [handleApply]
24840
25396
  );
24841
- return /* @__PURE__ */ jsxs8("div", { className: `ee-richtext-link ${toolbar_default.richTextColorWrapper}`, ref: wrapperRef, children: [
24842
- /* @__PURE__ */ jsx10(
25397
+ return /* @__PURE__ */ jsxs11("div", { className: `ee-richtext-link ${toolbar_default.richTextColorWrapper}`, ref: wrapperRef, children: [
25398
+ /* @__PURE__ */ jsx13(
24843
25399
  "button",
24844
25400
  {
24845
25401
  className: `ee-richtext-btn ee-richtext-link-btn ${toolbar_default.richTextBtn} ${isActive2 ? toolbar_default.richTextBtnActive : ""}`,
@@ -24847,12 +25403,12 @@ function InlineLinkEditor({ editor }) {
24847
25403
  title: "Link",
24848
25404
  "aria-label": "Link",
24849
25405
  "aria-pressed": isActive2,
24850
- children: "\u{1F517}"
25406
+ children: /* @__PURE__ */ jsx13(LinkIcon, {})
24851
25407
  }
24852
25408
  ),
24853
- isOpen && /* @__PURE__ */ jsxs8("div", { className: `ee-richtext-link-dropdown ${toolbar_default.richTextLinkDropdown}`, children: [
24854
- /* @__PURE__ */ jsx10("label", { className: `ee-richtext-link-label ${toolbar_default.richTextLinkLabel}`, children: "URL" }),
24855
- /* @__PURE__ */ jsx10(
25409
+ isOpen && /* @__PURE__ */ jsxs11("div", { className: `ee-richtext-link-dropdown ${toolbar_default.richTextLinkDropdown}`, children: [
25410
+ /* @__PURE__ */ jsx13("label", { className: `ee-richtext-link-label ${toolbar_default.richTextLinkLabel}`, children: "URL" }),
25411
+ /* @__PURE__ */ jsx13(
24856
25412
  "input",
24857
25413
  {
24858
25414
  ref: inputRef,
@@ -24863,19 +25419,26 @@ function InlineLinkEditor({ editor }) {
24863
25419
  placeholder: "https://, mailto:, or tel:"
24864
25420
  }
24865
25421
  ),
24866
- urlError && /* @__PURE__ */ jsx10("div", { className: `ee-richtext-link-error ${toolbar_default.richTextLinkError}`, children: urlError }),
24867
- /* @__PURE__ */ jsxs8("div", { className: `ee-richtext-link-actions ${toolbar_default.richTextLinkActions}`, children: [
24868
- /* @__PURE__ */ jsx10("button", { className: `ee-richtext-link-apply ${toolbar_default.richTextLinkApply}`, onClick: handleApply, children: "Apply" }),
24869
- isActive2 && /* @__PURE__ */ jsx10("button", { className: `ee-richtext-link-remove ${toolbar_default.richTextLinkRemove}`, onClick: handleRemove, children: "Remove" })
25422
+ urlError && /* @__PURE__ */ jsx13("div", { className: `ee-richtext-link-error ${toolbar_default.richTextLinkError}`, children: urlError }),
25423
+ /* @__PURE__ */ jsxs11("div", { className: `ee-richtext-link-actions ${toolbar_default.richTextLinkActions}`, children: [
25424
+ /* @__PURE__ */ jsx13("button", { className: `ee-richtext-link-apply ${toolbar_default.richTextLinkApply}`, onClick: handleApply, children: "Apply" }),
25425
+ isActive2 && /* @__PURE__ */ jsx13("button", { className: `ee-richtext-link-remove ${toolbar_default.richTextLinkRemove}`, onClick: handleRemove, children: "Remove" })
24870
25426
  ] })
24871
25427
  ] })
24872
25428
  ] });
24873
25429
  }
24874
- function InlineColorPicker({ editor, type, title, label }) {
24875
- const [isOpen, setIsOpen] = useState6(false);
24876
- const wrapperRef = useRef10(null);
25430
+ function InlineColorPicker({ editor, type, title, icon }) {
25431
+ const [isOpen, setIsOpen] = useState9(false);
25432
+ const [hexInput, setHexInput] = useState9("");
25433
+ const wrapperRef = useRef12(null);
25434
+ const { customColorPresets, addCustomColorPreset, removeCustomColorPreset } = useColorPresets();
24877
25435
  const currentColor = type === "color" ? editor.getAttributes("textStyle").color || "#000000" : editor.getAttributes("highlight").color || "";
24878
- useEffect9(() => {
25436
+ useEffect10(() => {
25437
+ if (isOpen) {
25438
+ setHexInput(currentColor || "#000000");
25439
+ }
25440
+ }, [isOpen, currentColor]);
25441
+ useEffect10(() => {
24879
25442
  function handleClickOutside(e) {
24880
25443
  if (wrapperRef.current && !wrapperRef.current.contains(e.target)) {
24881
25444
  setIsOpen(false);
@@ -24886,18 +25449,19 @@ function InlineColorPicker({ editor, type, title, label }) {
24886
25449
  return () => document.removeEventListener("mousedown", handleClickOutside);
24887
25450
  }
24888
25451
  }, [isOpen]);
24889
- const applyColor = useCallback11(
24890
- (color) => {
25452
+ const applyColor = useCallback13(
25453
+ (color, close2 = false) => {
24891
25454
  if (type === "color") {
24892
25455
  editor.chain().focus().setColor(color).run();
24893
25456
  } else {
24894
25457
  editor.chain().focus().toggleHighlight({ color }).run();
24895
25458
  }
24896
- setIsOpen(false);
25459
+ setHexInput(color);
25460
+ if (close2) setIsOpen(false);
24897
25461
  },
24898
25462
  [editor, type]
24899
25463
  );
24900
- const clearColor = useCallback11(() => {
25464
+ const clearColor = useCallback13(() => {
24901
25465
  if (type === "color") {
24902
25466
  editor.chain().focus().unsetColor().run();
24903
25467
  } else {
@@ -24905,19 +25469,41 @@ function InlineColorPicker({ editor, type, title, label }) {
24905
25469
  }
24906
25470
  setIsOpen(false);
24907
25471
  }, [editor, type]);
25472
+ const handleHexApply = useCallback13(() => {
25473
+ const trimmed = hexInput.trim();
25474
+ if (/^#([0-9a-fA-F]{3}|[0-9a-fA-F]{6})$/.test(trimmed)) {
25475
+ applyColor(trimmed, true);
25476
+ }
25477
+ }, [hexInput, applyColor]);
25478
+ const handleHexKeyDown = useCallback13(
25479
+ (e) => {
25480
+ if (e.key === "Enter") {
25481
+ e.preventDefault();
25482
+ handleHexApply();
25483
+ }
25484
+ },
25485
+ [handleHexApply]
25486
+ );
25487
+ const handleSaveCustom = useCallback13(() => {
25488
+ const trimmed = hexInput.trim();
25489
+ if (/^#([0-9a-fA-F]{3}|[0-9a-fA-F]{6})$/.test(trimmed) && !customColorPresets.includes(trimmed)) {
25490
+ addCustomColorPreset(trimmed);
25491
+ }
25492
+ }, [hexInput, customColorPresets, addCustomColorPreset]);
25493
+ const isValidHex = /^#([0-9a-fA-F]{3}|[0-9a-fA-F]{6})$/.test(hexInput.trim());
24908
25494
  const indicatorColor = type === "color" ? currentColor : currentColor || "transparent";
24909
- return /* @__PURE__ */ jsxs8("div", { className: `ee-richtext-color ee-richtext-color--${type} ${toolbar_default.richTextColorWrapper}`, ref: wrapperRef, children: [
24910
- /* @__PURE__ */ jsxs8(
25495
+ return /* @__PURE__ */ jsxs11("div", { className: `ee-richtext-color ee-richtext-color--${type} ${toolbar_default.richTextColorWrapper}`, ref: wrapperRef, children: [
25496
+ /* @__PURE__ */ jsxs11(
24911
25497
  "button",
24912
25498
  {
24913
- className: `ee-richtext-btn ee-richtext-color-btn ${toolbar_default.richTextBtn}`,
25499
+ className: `ee-richtext-btn ee-richtext-color-btn ${toolbar_default.richTextBtnWithIndicator}`,
24914
25500
  onClick: () => setIsOpen(!isOpen),
24915
25501
  title,
24916
25502
  "aria-label": title,
24917
25503
  "aria-expanded": isOpen,
24918
25504
  children: [
24919
- /* @__PURE__ */ jsx10("span", { className: `ee-richtext-color-label ${toolbar_default.richTextColorLabel}`, children: label }),
24920
- /* @__PURE__ */ jsx10(
25505
+ icon,
25506
+ /* @__PURE__ */ jsx13(
24921
25507
  "span",
24922
25508
  {
24923
25509
  className: `ee-richtext-color-indicator ${toolbar_default.richTextColorIndicator}`,
@@ -24927,29 +25513,91 @@ function InlineColorPicker({ editor, type, title, label }) {
24927
25513
  ]
24928
25514
  }
24929
25515
  ),
24930
- isOpen && /* @__PURE__ */ jsxs8("div", { className: `ee-richtext-color-dropdown ${toolbar_default.richTextColorDropdown}`, children: [
24931
- /* @__PURE__ */ jsx10("div", { className: `ee-richtext-color-grid ${toolbar_default.richTextColorGrid}`, children: COLOR_PRESETS.map((color) => /* @__PURE__ */ jsx10(
25516
+ isOpen && /* @__PURE__ */ jsxs11("div", { className: `ee-richtext-color-dropdown ${toolbar_default.richTextColorDropdown}`, children: [
25517
+ /* @__PURE__ */ jsx13("div", { className: `ee-richtext-color-section-label ${toolbar_default.richTextColorSectionLabel}`, children: "Presets" }),
25518
+ /* @__PURE__ */ jsx13("div", { className: `ee-richtext-color-grid ${toolbar_default.richTextColorGrid}`, children: COLOR_PRESETS.map((color) => /* @__PURE__ */ jsx13(
24932
25519
  "button",
24933
25520
  {
24934
- className: `ee-richtext-color-swatch ${toolbar_default.richTextColorSwatch}`,
25521
+ className: `ee-richtext-color-swatch ${toolbar_default.richTextColorSwatch} ${currentColor.toLowerCase() === color.toLowerCase() ? toolbar_default.richTextColorSwatchActive : ""}`,
24935
25522
  style: { backgroundColor: color },
24936
- onClick: () => applyColor(color),
25523
+ onClick: () => applyColor(color, true),
24937
25524
  title: color
24938
25525
  },
24939
25526
  color
24940
25527
  )) }),
24941
- /* @__PURE__ */ jsxs8("div", { className: `ee-richtext-color-actions ${toolbar_default.richTextColorActions}`, children: [
24942
- /* @__PURE__ */ jsx10(
25528
+ customColorPresets.length > 0 && /* @__PURE__ */ jsxs11(Fragment2, { children: [
25529
+ /* @__PURE__ */ jsx13("div", { className: `ee-richtext-color-section-label ${toolbar_default.richTextColorSectionLabel}`, children: "Custom" }),
25530
+ /* @__PURE__ */ jsx13("div", { className: `ee-richtext-color-grid ${toolbar_default.richTextColorGrid}`, children: customColorPresets.map((color) => /* @__PURE__ */ jsx13(
25531
+ "button",
25532
+ {
25533
+ className: `ee-richtext-color-swatch ${toolbar_default.richTextColorSwatch} ${currentColor.toLowerCase() === color.toLowerCase() ? toolbar_default.richTextColorSwatchActive : ""}`,
25534
+ style: { backgroundColor: color },
25535
+ onClick: () => applyColor(color, true),
25536
+ title: color,
25537
+ children: /* @__PURE__ */ jsx13(
25538
+ "span",
25539
+ {
25540
+ className: `ee-richtext-color-swatch-remove ${toolbar_default.richTextColorSwatchRemove}`,
25541
+ onClick: (e) => {
25542
+ e.stopPropagation();
25543
+ removeCustomColorPreset(color);
25544
+ },
25545
+ title: "Remove",
25546
+ children: "\xD7"
25547
+ }
25548
+ )
25549
+ },
25550
+ `custom-${color}`
25551
+ )) })
25552
+ ] }),
25553
+ /* @__PURE__ */ jsx13("div", { style: { borderTop: "1px solid var(--ee-border-color)", paddingTop: "var(--ee-space-sm)" }, children: /* @__PURE__ */ jsx13(
25554
+ HslColorArea,
25555
+ {
25556
+ value: isValidHex ? hexInput.trim() : currentColor || "#000000",
25557
+ onChange: (hex) => {
25558
+ setHexInput(hex);
25559
+ },
25560
+ onChangeEnd: (hex) => {
25561
+ applyColor(hex);
25562
+ }
25563
+ }
25564
+ ) }),
25565
+ /* @__PURE__ */ jsxs11("div", { className: `ee-richtext-color-custom-row ${toolbar_default.richTextColorCustomRow}`, children: [
25566
+ /* @__PURE__ */ jsx13(
24943
25567
  "input",
24944
25568
  {
24945
- type: "color",
24946
- value: currentColor || "#000000",
24947
- onChange: (e) => applyColor(e.target.value),
24948
- className: `ee-richtext-color-input ${toolbar_default.richTextColorInput}`,
24949
- title: "Custom color"
25569
+ className: `ee-richtext-color-hex-input ${toolbar_default.richTextColorHexInput}`,
25570
+ value: hexInput,
25571
+ onChange: (e) => setHexInput(e.target.value),
25572
+ onKeyDown: handleHexKeyDown,
25573
+ placeholder: "#000000",
25574
+ maxLength: 7,
25575
+ spellCheck: false
25576
+ }
25577
+ ),
25578
+ /* @__PURE__ */ jsx13(
25579
+ "button",
25580
+ {
25581
+ className: `ee-richtext-color-apply ${toolbar_default.richTextColorApplyBtn}`,
25582
+ onClick: handleHexApply,
25583
+ disabled: !isValidHex,
25584
+ title: "Apply color",
25585
+ children: "Apply"
25586
+ }
25587
+ )
25588
+ ] }),
25589
+ /* @__PURE__ */ jsxs11("div", { className: `ee-richtext-color-bottom ${toolbar_default.richTextColorBottomActions}`, children: [
25590
+ /* @__PURE__ */ jsx13(
25591
+ "button",
25592
+ {
25593
+ className: `ee-richtext-color-save ${toolbar_default.richTextColorClearBtn}`,
25594
+ onClick: handleSaveCustom,
25595
+ title: "Save this color to your custom presets",
25596
+ disabled: !isValidHex || customColorPresets.includes(hexInput.trim()),
25597
+ children: "+ Save preset"
24950
25598
  }
24951
25599
  ),
24952
- /* @__PURE__ */ jsx10(
25600
+ /* @__PURE__ */ jsx13(
24953
25601
  "button",
24954
25602
  {
24955
25603
  className: `ee-richtext-color-clear ${toolbar_default.richTextColorClearBtn}`,
@@ -24991,6 +25639,8 @@ var blocks_default = {
24991
25639
  "socialLabel": "socialLabel",
24992
25640
  "socialElementsContainer": "socialElementsContainer",
24993
25641
  "socialElementItem": "socialElementItem",
25642
+ "socialIconImage": "socialIconImage",
25643
+ "socialIconPreview": "socialIconPreview",
24994
25644
  "htmlBlock": "htmlBlock",
24995
25645
  "htmlPlaceholder": "htmlPlaceholder",
24996
25646
  "videoBlock": "videoBlock",
@@ -25024,17 +25674,17 @@ var tiptap_default = {
25024
25674
  };
25025
25675
 
25026
25676
  // src/components/Canvas/blocks/TextBlock.tsx
25027
- import { jsx as jsx11, jsxs as jsxs9 } from "react/jsx-runtime";
25677
+ import { jsx as jsx14, jsxs as jsxs12 } from "react/jsx-runtime";
25028
25678
  var TextBlockInner = function TextBlock({ block }) {
25029
25679
  const dispatch = useEditorDispatch();
25030
25680
  const { setActiveEditor } = useMethodsContext();
25031
- const editorRef = useRef11(null);
25032
- const wrapperRef = useRef11(null);
25033
- const blurTimerRef = useRef11(null);
25034
- const [isFocused, setIsFocused] = useState7(false);
25035
- const [editorInstance, setEditorInstance] = useState7(null);
25681
+ const editorRef = useRef13(null);
25682
+ const wrapperRef = useRef13(null);
25683
+ const blurTimerRef = useRef13(null);
25684
+ const [isFocused, setIsFocused] = useState10(false);
25685
+ const [editorInstance, setEditorInstance] = useState10(null);
25036
25686
  const [, forceToolbarUpdate] = useReducer2((c) => c + 1, 0);
25037
- useEffect10(() => {
25687
+ useEffect11(() => {
25038
25688
  if (!editorInstance) return;
25039
25689
  const onStateChange = () => forceToolbarUpdate();
25040
25690
  editorInstance.on("selectionUpdate", onStateChange);
@@ -25044,7 +25694,7 @@ var TextBlockInner = function TextBlock({ block }) {
25044
25694
  editorInstance.off("transaction", onStateChange);
25045
25695
  };
25046
25696
  }, [editorInstance]);
25047
- const handleUpdate = useCallback12(
25697
+ const handleUpdate = useCallback14(
25048
25698
  (html2) => {
25049
25699
  dispatch({
25050
25700
  type: "UPDATE_BLOCK",
@@ -25053,16 +25703,16 @@ var TextBlockInner = function TextBlock({ block }) {
25053
25703
  },
25054
25704
  [dispatch, block.id]
25055
25705
  );
25056
- const handleFocus = useCallback12(() => {
25706
+ const handleFocus = useCallback14(() => {
25057
25707
  setActiveEditor(editorRef.current);
25058
25708
  setIsFocused(true);
25059
25709
  }, [setActiveEditor]);
25060
- useEffect10(() => {
25710
+ useEffect11(() => {
25061
25711
  return () => {
25062
25712
  if (blurTimerRef.current !== null) clearTimeout(blurTimerRef.current);
25063
25713
  };
25064
25714
  }, []);
25065
- const handleBlur = useCallback12(() => {
25715
+ const handleBlur = useCallback14(() => {
25066
25716
  if (blurTimerRef.current !== null) clearTimeout(blurTimerRef.current);
25067
25717
  blurTimerRef.current = setTimeout(() => {
25068
25718
  blurTimerRef.current = null;
@@ -25076,7 +25726,7 @@ var TextBlockInner = function TextBlock({ block }) {
25076
25726
  }
25077
25727
  }, 200);
25078
25728
  }, [setActiveEditor]);
25079
- const handleEditorRef = useCallback12((editor) => {
25729
+ const handleEditorRef = useCallback14((editor) => {
25080
25730
  editorRef.current = editor;
25081
25731
  setEditorInstance(editor);
25082
25732
  }, []);
@@ -25089,11 +25739,12 @@ var TextBlockInner = function TextBlock({ block }) {
25089
25739
  padding: p.padding,
25090
25740
  fontWeight: p.fontWeight,
25091
25741
  textTransform: p.textTransform,
25092
- letterSpacing: p.letterSpacing
25093
- }), [p.fontFamily, p.fontSize, p.color, p.lineHeight, p.padding, p.fontWeight, p.textTransform, p.letterSpacing]);
25094
- return /* @__PURE__ */ jsxs9("div", { className: `ee-block-text ${blocks_default.textBlock}`, ref: wrapperRef, children: [
25095
- isFocused && editorInstance && /* @__PURE__ */ jsx11("div", { className: blocks_default.textBlockToolbar, children: /* @__PURE__ */ jsx11(RichTextToolbar, { editor: editorInstance }) }),
25096
- /* @__PURE__ */ jsx11("div", { style: wrapperStyle, children: /* @__PURE__ */ jsx11(
25742
+ letterSpacing: p.letterSpacing,
25743
+ backgroundColor: p.backgroundColor && p.backgroundColor !== "transparent" ? p.backgroundColor : void 0
25744
+ }), [p.fontFamily, p.fontSize, p.color, p.lineHeight, p.padding, p.fontWeight, p.textTransform, p.letterSpacing, p.backgroundColor]);
25745
+ return /* @__PURE__ */ jsxs12("div", { className: `ee-block-text ${blocks_default.textBlock}`, ref: wrapperRef, children: [
25746
+ isFocused && editorInstance && /* @__PURE__ */ jsx14("div", { className: blocks_default.textBlockToolbar, children: /* @__PURE__ */ jsx14(RichTextToolbar, { editor: editorInstance }) }),
25747
+ /* @__PURE__ */ jsx14("div", { style: wrapperStyle, children: /* @__PURE__ */ jsx14(
25097
25748
  TipTapEditor,
25098
25749
  {
25099
25750
  content: block.properties.content,
@@ -25107,12 +25758,12 @@ var TextBlockInner = function TextBlock({ block }) {
25107
25758
  ) })
25108
25759
  ] });
25109
25760
  };
25110
- var TextBlock2 = React11.memo(TextBlockInner);
25761
+ var TextBlock2 = React13.memo(TextBlockInner);
25111
25762
 
25112
25763
  // src/components/Canvas/blocks/ButtonBlock.tsx
25113
- import React12, { useMemo as useMemo6 } from "react";
25114
- import { jsx as jsx12 } from "react/jsx-runtime";
25115
- var ButtonBlock = React12.memo(function ButtonBlock2({ block }) {
25764
+ import React14, { useMemo as useMemo6 } from "react";
25765
+ import { jsx as jsx15 } from "react/jsx-runtime";
25766
+ var ButtonBlock = React14.memo(function ButtonBlock2({ block }) {
25116
25767
  const p = block.properties;
25117
25768
  const alignClass = p.align === "left" ? blocks_default.buttonBlockLeft : p.align === "right" ? blocks_default.buttonBlockRight : blocks_default.buttonBlockCenter;
25118
25769
  const outerStyle = useMemo6(() => ({ padding: p.padding }), [p.padding]);
@@ -25128,7 +25779,7 @@ var ButtonBlock = React12.memo(function ButtonBlock2({ block }) {
25128
25779
  textTransform: p.textTransform,
25129
25780
  letterSpacing: p.letterSpacing
25130
25781
  }), [p.backgroundColor, p.color, p.fontFamily, p.fontSize, p.borderRadius, p.innerPadding, p.width, p.fontWeight, p.textTransform, p.letterSpacing]);
25131
- return /* @__PURE__ */ jsx12("div", { className: `ee-block-button ${blocks_default.buttonBlock} ${alignClass}`, style: outerStyle, children: /* @__PURE__ */ jsx12(
25782
+ return /* @__PURE__ */ jsx15("div", { className: `ee-block-button ${blocks_default.buttonBlock} ${alignClass}`, style: outerStyle, children: /* @__PURE__ */ jsx15(
25132
25783
  "span",
25133
25784
  {
25134
25785
  className: blocks_default.buttonPreview,
@@ -25139,21 +25790,21 @@ var ButtonBlock = React12.memo(function ButtonBlock2({ block }) {
25139
25790
  });
25140
25791
 
25141
25792
  // src/components/Canvas/blocks/ImageBlock.tsx
25142
- import React13, { useCallback as useCallback14, useRef as useRef13 } from "react";
25793
+ import React15, { useCallback as useCallback16, useRef as useRef15 } from "react";
25143
25794
 
25144
25795
  // src/components/ImageUpload/useImageUpload.ts
25145
- import { useState as useState8, useCallback as useCallback13, useRef as useRef12 } from "react";
25796
+ import { useState as useState11, useCallback as useCallback15, useRef as useRef14 } from "react";
25146
25797
  function useImageUpload({
25147
25798
  adapter,
25148
25799
  blockId,
25149
25800
  onSuccess,
25150
25801
  onError
25151
25802
  }) {
25152
- const [status, setStatus] = useState8("idle");
25153
- const [progress, setProgress] = useState8(0);
25154
- const [error, setError] = useState8(null);
25155
- const controllerRef = useRef12(null);
25156
- const upload = useCallback13(
25803
+ const [status, setStatus] = useState11("idle");
25804
+ const [progress, setProgress] = useState11(0);
25805
+ const [error, setError] = useState11(null);
25806
+ const controllerRef = useRef14(null);
25807
+ const upload = useCallback15(
25157
25808
  async (file) => {
25158
25809
  if (!adapter) {
25159
25810
  setError("No upload adapter configured");
@@ -25198,12 +25849,12 @@ function useImageUpload({
25198
25849
  },
25199
25850
  [adapter, blockId, onSuccess, onError]
25200
25851
  );
25201
- const cancel = useCallback13(() => {
25852
+ const cancel = useCallback15(() => {
25202
25853
  controllerRef.current?.abort();
25203
25854
  setStatus("idle");
25204
25855
  setProgress(0);
25205
25856
  }, []);
25206
- const browse = useCallback13(async () => {
25857
+ const browse = useCallback15(async () => {
25207
25858
  if (!adapter?.browse) return null;
25208
25859
  try {
25209
25860
  const result = await adapter.browse();
@@ -25215,7 +25866,7 @@ function useImageUpload({
25215
25866
  return null;
25216
25867
  }
25217
25868
  }, [adapter, onSuccess]);
25218
- const reset2 = useCallback13(() => {
25869
+ const reset2 = useCallback15(() => {
25219
25870
  setStatus("idle");
25220
25871
  setProgress(0);
25221
25872
  setError(null);
@@ -25224,11 +25875,11 @@ function useImageUpload({
25224
25875
  }
25225
25876
 
25226
25877
  // src/components/Canvas/blocks/ImageBlock.tsx
25227
- import { jsx as jsx13, jsxs as jsxs10 } from "react/jsx-runtime";
25878
+ import { jsx as jsx16, jsxs as jsxs13 } from "react/jsx-runtime";
25228
25879
  var ImageBlockInner = function ImageBlock({ block }) {
25229
25880
  const dispatch = useEditorDispatch();
25230
25881
  const { imageUploadAdapter } = useConfigContext();
25231
- const fileInputRef = useRef13(null);
25882
+ const fileInputRef = useRef15(null);
25232
25883
  const p = block.properties;
25233
25884
  const { upload, status } = useImageUpload({
25234
25885
  adapter: imageUploadAdapter,
@@ -25248,7 +25899,7 @@ var ImageBlockInner = function ImageBlock({ block }) {
25248
25899
  }
25249
25900
  });
25250
25901
  const alignClass = p.align === "left" ? blocks_default.imageBlockLeft : p.align === "right" ? blocks_default.imageBlockRight : blocks_default.imageBlockCenter;
25251
- const handleFileSelect = useCallback14(
25902
+ const handleFileSelect = useCallback16(
25252
25903
  async (e) => {
25253
25904
  const file = e.target.files?.[0];
25254
25905
  if (!file) return;
@@ -25256,11 +25907,11 @@ var ImageBlockInner = function ImageBlock({ block }) {
25256
25907
  },
25257
25908
  [upload]
25258
25909
  );
25259
- const handlePlaceholderClick = useCallback14(() => {
25910
+ const handlePlaceholderClick = useCallback16(() => {
25260
25911
  fileInputRef.current?.click();
25261
25912
  }, []);
25262
- return /* @__PURE__ */ jsxs10("div", { className: `ee-block-image ${blocks_default.imageBlock} ${alignClass}`, style: { padding: p.padding }, children: [
25263
- p.src ? /* @__PURE__ */ jsx13(
25913
+ return /* @__PURE__ */ jsxs13("div", { className: `ee-block-image ${blocks_default.imageBlock} ${alignClass}`, style: { padding: p.padding }, children: [
25914
+ p.src ? /* @__PURE__ */ jsx16(
25264
25915
  "img",
25265
25916
  {
25266
25917
  src: p.src,
@@ -25271,11 +25922,11 @@ var ImageBlockInner = function ImageBlock({ block }) {
25271
25922
  height: p.height !== "auto" ? p.height : void 0
25272
25923
  }
25273
25924
  }
25274
- ) : /* @__PURE__ */ jsxs10("div", { className: blocks_default.imagePlaceholder, onClick: handlePlaceholderClick, children: [
25275
- /* @__PURE__ */ jsx13("span", { className: blocks_default.imagePlaceholderIcon, children: "+" }),
25276
- /* @__PURE__ */ jsx13("span", { children: status === "uploading" ? "Uploading..." : "Click to upload image" })
25925
+ ) : /* @__PURE__ */ jsxs13("div", { className: blocks_default.imagePlaceholder, onClick: handlePlaceholderClick, children: [
25926
+ /* @__PURE__ */ jsx16("span", { className: blocks_default.imagePlaceholderIcon, children: "+" }),
25927
+ /* @__PURE__ */ jsx16("span", { children: status === "uploading" ? "Uploading..." : "Click to upload image" })
25277
25928
  ] }),
25278
- /* @__PURE__ */ jsx13(
25929
+ /* @__PURE__ */ jsx16(
25279
25930
  "input",
25280
25931
  {
25281
25932
  ref: fileInputRef,
@@ -25287,19 +25938,19 @@ var ImageBlockInner = function ImageBlock({ block }) {
25287
25938
  )
25288
25939
  ] });
25289
25940
  };
25290
- var ImageBlock2 = React13.memo(ImageBlockInner);
25941
+ var ImageBlock2 = React15.memo(ImageBlockInner);
25291
25942
 
25292
25943
  // src/components/Canvas/blocks/DividerBlock.tsx
25293
- import React14, { useMemo as useMemo7 } from "react";
25294
- import { jsx as jsx14 } from "react/jsx-runtime";
25295
- var DividerBlock = React14.memo(function DividerBlock2({ block }) {
25944
+ import React16, { useMemo as useMemo7 } from "react";
25945
+ import { jsx as jsx17 } from "react/jsx-runtime";
25946
+ var DividerBlock = React16.memo(function DividerBlock2({ block }) {
25296
25947
  const p = block.properties;
25297
25948
  const outerStyle = useMemo7(() => ({ padding: p.padding }), [p.padding]);
25298
25949
  const hrStyle = useMemo7(() => ({
25299
25950
  width: p.width,
25300
25951
  borderTop: `${p.borderWidth} ${p.borderStyle} ${p.borderColor}`
25301
25952
  }), [p.width, p.borderWidth, p.borderStyle, p.borderColor]);
25302
- return /* @__PURE__ */ jsx14("div", { className: `ee-block-divider ${blocks_default.dividerBlock}`, style: outerStyle, children: /* @__PURE__ */ jsx14(
25953
+ return /* @__PURE__ */ jsx17("div", { className: `ee-block-divider ${blocks_default.dividerBlock}`, style: outerStyle, children: /* @__PURE__ */ jsx17(
25303
25954
  "hr",
25304
25955
  {
25305
25956
  className: blocks_default.dividerLine,
@@ -25309,16 +25960,46 @@ var DividerBlock = React14.memo(function DividerBlock2({ block }) {
25309
25960
  });
25310
25961
 
25311
25962
  // src/components/Canvas/blocks/SpacerBlock.tsx
25312
- import React15 from "react";
25313
- import { jsx as jsx15 } from "react/jsx-runtime";
25314
- var SpacerBlock = React15.memo(function SpacerBlock2({ block }) {
25963
+ import React17 from "react";
25964
+ import { jsx as jsx18 } from "react/jsx-runtime";
25965
+ var SpacerBlock = React17.memo(function SpacerBlock2({ block }) {
25315
25966
  const p = block.properties;
25316
- return /* @__PURE__ */ jsx15("div", { className: `ee-block-spacer ${blocks_default.spacerBlock}`, style: { height: p.height }, children: /* @__PURE__ */ jsx15("span", { className: blocks_default.spacerLabel, children: p.height }) });
25967
+ return /* @__PURE__ */ jsx18("div", { className: `ee-block-spacer ${blocks_default.spacerBlock}`, style: { height: p.height }, children: /* @__PURE__ */ jsx18("span", { className: blocks_default.spacerLabel, children: p.height }) });
25317
25968
  });
25318
25969
 
25319
25970
  // src/components/Canvas/blocks/SocialBlock.tsx
25320
- import React16, { useMemo as useMemo8 } from "react";
25321
- import { jsx as jsx16, jsxs as jsxs11 } from "react/jsx-runtime";
25971
+ import React18, { useMemo as useMemo8 } from "react";
25972
+
25973
+ // src/components/Canvas/blocks/social-icons.tsx
25974
+ import { jsx as jsx19 } from "react/jsx-runtime";
25975
+ var Facebook = ({ size = 20, color = "#ffffff" }) => /* @__PURE__ */ jsx19("svg", { width: size, height: size, viewBox: "0 0 24 24", fill: color, xmlns: "http://www.w3.org/2000/svg", children: /* @__PURE__ */ jsx19("path", { d: "M9.198 21.5h4v-8.01h3.604l.396-3.98h-4V7.5a1 1 0 0 1 1-1h3v-4h-3a5 5 0 0 0-5 5v2.01h-2l-.396 3.98h2.396v8.01Z" }) });
25976
+ var Twitter = ({ size = 20, color = "#ffffff" }) => /* @__PURE__ */ jsx19("svg", { width: size, height: size, viewBox: "0 0 24 24", fill: color, xmlns: "http://www.w3.org/2000/svg", children: /* @__PURE__ */ jsx19("path", { d: "M13.808 10.469 20.88 2h-1.676l-6.142 7.353L8.158 2H2.5l7.418 11.12L2.5 22h1.676l6.486-7.765L15.842 22H21.5l-7.693-11.531Zm-2.296 2.748-.752-1.107L4.78 3.3h2.575l4.826 7.11.751 1.107 6.273 9.242h-2.574l-5.12-7.541Z" }) });
25977
+ var Instagram = ({ size = 20, color = "#ffffff" }) => /* @__PURE__ */ jsx19("svg", { width: size, height: size, viewBox: "0 0 24 24", fill: color, xmlns: "http://www.w3.org/2000/svg", children: /* @__PURE__ */ jsx19("path", { d: "M7.8 2h8.4A5.8 5.8 0 0 1 22 7.8v8.4a5.8 5.8 0 0 1-5.8 5.8H7.8A5.8 5.8 0 0 1 2 16.2V7.8A5.8 5.8 0 0 1 7.8 2Zm-.2 2A3.6 3.6 0 0 0 4 7.6v8.8A3.6 3.6 0 0 0 7.6 20h8.8a3.6 3.6 0 0 0 3.6-3.6V7.6A3.6 3.6 0 0 0 16.4 4H7.6Zm9.65 1.5a1.25 1.25 0 1 1 0 2.5 1.25 1.25 0 0 1 0-2.5ZM12 7a5 5 0 1 1 0 10 5 5 0 0 1 0-10Zm0 2a3 3 0 1 0 0 6 3 3 0 0 0 0-6Z" }) });
25978
+ var LinkedIn = ({ size = 20, color = "#ffffff" }) => /* @__PURE__ */ jsx19("svg", { width: size, height: size, viewBox: "0 0 24 24", fill: color, xmlns: "http://www.w3.org/2000/svg", children: /* @__PURE__ */ jsx19("path", { d: "M6.94 5a2 2 0 1 1-4 0 2 2 0 0 1 4 0ZM7 8.48H3V21h4V8.48Zm6.32 0H9.34V21h3.94v-6.57c0-3.66 4.77-4 4.77 0V21H22v-7.93c0-6.17-7.06-5.94-8.72-2.91l.04-1.68Z" }) });
25979
+ var YouTube = ({ size = 20, color = "#ffffff" }) => /* @__PURE__ */ jsx19("svg", { width: size, height: size, viewBox: "0 0 24 24", fill: color, xmlns: "http://www.w3.org/2000/svg", children: /* @__PURE__ */ jsx19("path", { d: "M23.498 6.186a3.016 3.016 0 0 0-2.122-2.136C19.505 3.545 12 3.545 12 3.545s-7.505 0-9.377.505A3.017 3.017 0 0 0 .502 6.186C0 8.07 0 12 0 12s0 3.93.502 5.814a3.016 3.016 0 0 0 2.122 2.136c1.871.505 9.376.505 9.376.505s7.505 0 9.377-.505a3.015 3.015 0 0 0 2.122-2.136C24 15.93 24 12 24 12s0-3.93-.502-5.814ZM9.545 15.568V8.432L15.818 12l-6.273 3.568Z" }) });
25980
+ var GitHub = ({ size = 20, color = "#ffffff" }) => /* @__PURE__ */ jsx19("svg", { width: size, height: size, viewBox: "0 0 24 24", fill: color, xmlns: "http://www.w3.org/2000/svg", children: /* @__PURE__ */ jsx19("path", { d: "M12 2C6.477 2 2 6.477 2 12c0 4.42 2.865 8.17 6.839 9.49.5.092.682-.217.682-.482 0-.237-.008-.866-.013-1.7-2.782.604-3.369-1.34-3.369-1.34-.454-1.156-1.11-1.464-1.11-1.464-.908-.62.069-.608.069-.608 1.003.07 1.531 1.03 1.531 1.03.892 1.529 2.341 1.087 2.91.832.092-.647.35-1.088.636-1.338-2.22-.253-4.555-1.11-4.555-4.943 0-1.091.39-1.984 1.029-2.683-.103-.253-.446-1.27.098-2.647 0 0 .84-.269 2.75 1.025A9.578 9.578 0 0 1 12 6.836a9.59 9.59 0 0 1 2.504.337c1.909-1.294 2.747-1.025 2.747-1.025.546 1.377.203 2.394.1 2.647.64.699 1.028 1.592 1.028 2.683 0 3.842-2.339 4.687-4.566 4.935.359.309.678.919.678 1.852 0 1.336-.012 2.415-.012 2.743 0 .267.18.578.688.48C19.138 20.167 22 16.418 22 12c0-5.523-4.477-10-10-10Z" }) });
25981
+ var Pinterest = ({ size = 20, color = "#ffffff" }) => /* @__PURE__ */ jsx19("svg", { width: size, height: size, viewBox: "0 0 24 24", fill: color, xmlns: "http://www.w3.org/2000/svg", children: /* @__PURE__ */ jsx19("path", { d: "M12 2C6.477 2 2 6.477 2 12c0 4.237 2.636 7.855 6.356 9.312-.088-.791-.167-2.005.035-2.868.181-.78 1.172-4.97 1.172-4.97s-.299-.598-.299-1.482c0-1.388.806-2.425 1.808-2.425.853 0 1.265.64 1.265 1.408 0 .858-.546 2.14-.828 3.33-.236.995.499 1.806 1.48 1.806 1.778 0 3.144-1.874 3.144-4.58 0-2.393-1.72-4.068-4.177-4.068-2.845 0-4.515 2.134-4.515 4.34 0 .859.331 1.781.745 2.282a.3.3 0 0 1 .069.288l-.278 1.133c-.044.183-.145.222-.335.134-1.249-.581-2.03-2.407-2.03-3.874 0-3.154 2.292-6.052 6.608-6.052 3.469 0 6.165 2.472 6.165 5.776 0 3.447-2.173 6.22-5.19 6.22-1.013 0-1.965-.527-2.291-1.148l-.623 2.378c-.226.869-.835 1.958-1.244 2.621.937.29 1.931.446 2.962.446 5.523 0 10-4.477 10-10S17.523 2 12 2Z" }) });
25982
+ var Snapchat = ({ size = 20, color = "#ffffff" }) => /* @__PURE__ */ jsx19("svg", { width: size, height: size, viewBox: "0 0 24 24", fill: color, xmlns: "http://www.w3.org/2000/svg", children: /* @__PURE__ */ jsx19("path", { d: "M12.166 3c1.672 0 3.036.676 3.95 1.956.662.925.826 1.862.826 2.607 0 .478-.045.913-.098 1.3l-.018.122c.106.048.238.076.387.076.27 0 .496-.1.677-.186a.78.78 0 0 1 .335-.08c.132 0 .352.037.521.201.212.207.233.48.233.588 0 .403-.332.694-.988.866-.094.024-.206.048-.328.074-.338.072-.802.17-.927.441-.074.162-.035.369.115.617l.017.027c.039.063 3.786 6.185-1.135 7.318-.047.01-.08.056-.07.1.059.268.322.41.548.534.11.06.213.117.292.179.303.237.35.488.321.655-.04.224-.236.44-.598.514a3.15 3.15 0 0 1-.638.067c-.258 0-.539-.034-.879-.088a5.106 5.106 0 0 0-.85-.073 3.474 3.474 0 0 0-.534.043c-.254.04-.544.143-.877.261-.535.19-1.199.427-2.089.427-.034 0-.069 0-.107-.002h-.037c-.89 0-1.551-.237-2.087-.427a4.36 4.36 0 0 0-.877-.261 3.494 3.494 0 0 0-.534-.043c-.321 0-.6.03-.85.073-.339.054-.62.088-.879.088a3.15 3.15 0 0 1-.638-.067c-.362-.074-.558-.29-.598-.514-.028-.167.018-.418.321-.655.079-.062.182-.118.292-.18.226-.123.49-.265.548-.533a.086.086 0 0 0-.07-.1c-3.07-.706-1.79-4.432-1.235-5.637l.003-.007c.06-.126.14-.293.169-.363.005-.012.012-.028.017-.04.133-.265.172-.46.115-.597-.125-.271-.59-.37-.928-.441a3.72 3.72 0 0 1-.327-.074c-.709-.186-.99-.496-.99-.866 0-.363.302-.638.594-.714a.808.808 0 0 1 .217-.026c.114 0 .23.028.336.08.24.11.481.186.676.186.149 0 .28-.028.386-.076a10.78 10.78 0 0 1-.116-1.422c0-.745.164-1.682.826-2.607C9.13 3.676 10.494 3 12.166 3Z" }) });
25983
+ var TikTok = ({ size = 20, color = "#ffffff" }) => /* @__PURE__ */ jsx19("svg", { width: size, height: size, viewBox: "0 0 24 24", fill: color, xmlns: "http://www.w3.org/2000/svg", children: /* @__PURE__ */ jsx19("path", { d: "M16.6 5.82A4.278 4.278 0 0 1 15.54 3h-3.09v12.4a2.592 2.592 0 0 1-2.59 2.5c-1.42 0-2.6-1.16-2.6-2.6 0-1.72 1.66-3.01 3.37-2.48V9.66c-3.45-.46-6.47 2.22-6.47 5.64 0 3.33 2.76 5.7 5.69 5.7 3.14 0 5.69-2.55 5.69-5.7V9.01a7.35 7.35 0 0 0 4.3 1.38V7.3s-1.88.09-3.86-1.48h-.02Z" }) });
25984
+ var Web = ({ size = 20, color = "#ffffff" }) => /* @__PURE__ */ jsx19("svg", { width: size, height: size, viewBox: "0 0 24 24", fill: color, xmlns: "http://www.w3.org/2000/svg", children: /* @__PURE__ */ jsx19("path", { d: "M12 2C6.477 2 2 6.477 2 12s4.477 10 10 10 10-4.477 10-10S17.523 2 12 2Zm6.918 6h-3.215a15.876 15.876 0 0 0-1.403-3.846A8.028 8.028 0 0 1 18.918 8ZM12 4.04c.793 1.02 1.44 2.18 1.89 3.46h-3.78c.45-1.28 1.097-2.44 1.89-3.46ZM4.26 14a7.93 7.93 0 0 1 0-4h3.38a16.516 16.516 0 0 0 0 4H4.26Zm.822 2h3.215a15.876 15.876 0 0 0 1.403 3.846A8.028 8.028 0 0 1 5.082 16ZM8.297 8H5.082A8.028 8.028 0 0 1 9.7 4.154 15.876 15.876 0 0 0 8.297 8ZM12 19.96c-.793-1.02-1.44-2.18-1.89-3.46h3.78c-.45 1.28-1.097 2.44-1.89 3.46ZM14.34 14H9.66a14.556 14.556 0 0 1 0-4h4.68a14.556 14.556 0 0 1 0 4Zm.36 5.846A15.876 15.876 0 0 0 16.103 16h3.215a8.029 8.029 0 0 1-4.618 3.846ZM16.36 14a16.516 16.516 0 0 0 0-4h3.38a7.93 7.93 0 0 1 0 4h-3.38Z" }) });
25985
+ var SOCIAL_ICONS = {
25986
+ facebook: Facebook,
25987
+ twitter: Twitter,
25988
+ instagram: Instagram,
25989
+ linkedin: LinkedIn,
25990
+ youtube: YouTube,
25991
+ github: GitHub,
25992
+ pinterest: Pinterest,
25993
+ snapchat: Snapchat,
25994
+ tiktok: TikTok,
25995
+ web: Web
25996
+ };
25997
+ function getSocialIcon(name) {
25998
+ return SOCIAL_ICONS[name.toLowerCase()];
25999
+ }
26000
+
26001
+ // src/components/Canvas/blocks/SocialBlock.tsx
26002
+ import { jsx as jsx20, jsxs as jsxs14 } from "react/jsx-runtime";
25322
26003
  var PLATFORM_COLORS = {
25323
26004
  facebook: "#3b5998",
25324
26005
  twitter: "#1da1f2",
@@ -25331,7 +26012,25 @@ var PLATFORM_COLORS = {
25331
26012
  tiktok: "#000000",
25332
26013
  web: "#4caf50"
25333
26014
  };
25334
- var SocialBlock = React16.memo(function SocialBlock2({ block }) {
26015
+ function SocialIconImage({ src, name, iconSizeNum, iconColor, SvgIcon }) {
26016
+ const [errored, setErrored] = React18.useState(false);
26017
+ if (errored) {
26018
+ if (SvgIcon) return /* @__PURE__ */ jsx20(SvgIcon, { size: Math.round(iconSizeNum * 0.6), color: iconColor });
26019
+ return /* @__PURE__ */ jsx20("span", { style: { color: iconColor, fontSize: Math.max(10, iconSizeNum * 0.5), fontWeight: "bold" }, children: name.charAt(0).toUpperCase() });
26020
+ }
26021
+ return /* @__PURE__ */ jsx20(
26022
+ "img",
26023
+ {
26024
+ src,
26025
+ alt: name,
26026
+ className: blocks_default.socialIconImage,
26027
+ width: iconSizeNum,
26028
+ height: iconSizeNum,
26029
+ onError: () => setErrored(true)
26030
+ }
26031
+ );
26032
+ }
26033
+ var SocialBlock = React18.memo(function SocialBlock2({ block }) {
25335
26034
  const p = block.properties;
25336
26035
  const isVertical = p.mode === "vertical";
25337
26036
  const alignStyle = p.align === "left" ? "flex-start" : p.align === "right" ? "flex-end" : "center";
@@ -25349,21 +26048,39 @@ var SocialBlock = React16.memo(function SocialBlock2({ block }) {
25349
26048
  fontSize: p.fontSize,
25350
26049
  color: p.color
25351
26050
  }), [p.fontSize, p.color]);
25352
- return /* @__PURE__ */ jsx16(
26051
+ return /* @__PURE__ */ jsx20(
25353
26052
  "div",
25354
26053
  {
25355
26054
  className: `ee-block-social ${blocks_default.socialBlock}`,
25356
26055
  style: wrapperStyle,
25357
26056
  children: p.elements.map((element) => {
25358
26057
  const bgColor = element.backgroundColor || PLATFORM_COLORS[element.name] || "#999999";
25359
- const initial = element.name.charAt(0).toUpperCase();
25360
- return /* @__PURE__ */ jsxs11(
26058
+ const iconColor = element.color || "#ffffff";
26059
+ const SvgIcon = getSocialIcon(element.name);
26060
+ let iconContent;
26061
+ if (element.src) {
26062
+ iconContent = /* @__PURE__ */ jsx20(
26063
+ SocialIconImage,
26064
+ {
26065
+ src: element.src,
26066
+ name: element.name,
26067
+ iconSizeNum,
26068
+ iconColor,
26069
+ SvgIcon
26070
+ }
26071
+ );
26072
+ } else if (SvgIcon) {
26073
+ iconContent = /* @__PURE__ */ jsx20(SvgIcon, { size: Math.round(iconSizeNum * 0.6), color: iconColor });
26074
+ } else {
26075
+ iconContent = element.name.charAt(0).toUpperCase();
26076
+ }
26077
+ return /* @__PURE__ */ jsxs14(
25361
26078
  "div",
25362
26079
  {
25363
26080
  className: blocks_default.socialElement,
25364
26081
  style: elementPaddingStyle,
25365
26082
  children: [
25366
- /* @__PURE__ */ jsx16(
26083
+ /* @__PURE__ */ jsx20(
25367
26084
  "span",
25368
26085
  {
25369
26086
  className: blocks_default.socialIcon,
@@ -25372,13 +26089,13 @@ var SocialBlock = React16.memo(function SocialBlock2({ block }) {
25372
26089
  height: iconSizeNum,
25373
26090
  backgroundColor: bgColor,
25374
26091
  borderRadius: p.borderRadius,
25375
- color: element.color || "#ffffff",
26092
+ color: iconColor,
25376
26093
  fontSize: Math.max(10, iconSizeNum * 0.5)
25377
26094
  },
25378
- children: initial
26095
+ children: iconContent
25379
26096
  }
25380
26097
  ),
25381
- element.content && /* @__PURE__ */ jsx16(
26098
+ element.content && /* @__PURE__ */ jsx20(
25382
26099
  "span",
25383
26100
  {
25384
26101
  className: blocks_default.socialLabel,
@@ -25396,7 +26113,7 @@ var SocialBlock = React16.memo(function SocialBlock2({ block }) {
25396
26113
  });
25397
26114
 
25398
26115
  // src/components/Canvas/blocks/HtmlBlock.tsx
25399
- import React17, { useMemo as useMemo9 } from "react";
26116
+ import React19, { useMemo as useMemo9 } from "react";
25400
26117
 
25401
26118
  // node_modules/dompurify/dist/purify.es.mjs
25402
26119
  var {
@@ -26418,8 +27135,8 @@ function createDOMPurify() {
26418
27135
  var purify = createDOMPurify();
26419
27136
 
26420
27137
  // src/components/Canvas/blocks/HtmlBlock.tsx
26421
- import { jsx as jsx17, jsxs as jsxs12 } from "react/jsx-runtime";
26422
- var HtmlBlock = React17.memo(function HtmlBlock2({ block }) {
27138
+ import { jsx as jsx21, jsxs as jsxs15 } from "react/jsx-runtime";
27139
+ var HtmlBlock = React19.memo(function HtmlBlock2({ block }) {
26423
27140
  const p = block.properties;
26424
27141
  const sanitizedContent = useMemo9(() => {
26425
27142
  if (!p.content) return "";
@@ -26429,12 +27146,12 @@ var HtmlBlock = React17.memo(function HtmlBlock2({ block }) {
26429
27146
  });
26430
27147
  }, [p.content]);
26431
27148
  if (!p.content) {
26432
- return /* @__PURE__ */ jsx17("div", { className: `ee-block-html ${blocks_default.htmlBlock}`, style: { padding: p.padding }, children: /* @__PURE__ */ jsxs12("div", { className: blocks_default.htmlPlaceholder, children: [
26433
- /* @__PURE__ */ jsx17("span", { children: "</>" }),
26434
- /* @__PURE__ */ jsx17("span", { children: "Raw HTML Block" })
27149
+ return /* @__PURE__ */ jsx21("div", { className: `ee-block-html ${blocks_default.htmlBlock}`, style: { padding: p.padding }, children: /* @__PURE__ */ jsxs15("div", { className: blocks_default.htmlPlaceholder, children: [
27150
+ /* @__PURE__ */ jsx21("span", { children: "</>" }),
27151
+ /* @__PURE__ */ jsx21("span", { children: "Raw HTML Block" })
26435
27152
  ] }) });
26436
27153
  }
26437
- return /* @__PURE__ */ jsx17(
27154
+ return /* @__PURE__ */ jsx21(
26438
27155
  "div",
26439
27156
  {
26440
27157
  className: `ee-block-html ${blocks_default.htmlBlock}`,
@@ -26445,24 +27162,24 @@ var HtmlBlock = React17.memo(function HtmlBlock2({ block }) {
26445
27162
  });
26446
27163
 
26447
27164
  // src/components/Canvas/blocks/VideoBlock.tsx
26448
- import React18 from "react";
26449
- import { jsx as jsx18, jsxs as jsxs13 } from "react/jsx-runtime";
26450
- var VideoBlock = React18.memo(function VideoBlock2({ block }) {
27165
+ import React20 from "react";
27166
+ import { jsx as jsx22, jsxs as jsxs16 } from "react/jsx-runtime";
27167
+ var VideoBlock = React20.memo(function VideoBlock2({ block }) {
26451
27168
  const p = block.properties;
26452
27169
  const alignClass = p.align === "left" ? blocks_default.videoBlockLeft : p.align === "right" ? blocks_default.videoBlockRight : blocks_default.videoBlockCenter;
26453
27170
  const thumbnailUrl = p.thumbnailUrl || getAutoThumbnail2(p.src);
26454
27171
  if (!thumbnailUrl && !p.src) {
26455
- return /* @__PURE__ */ jsx18("div", { className: `ee-block-video ${blocks_default.videoBlock} ${alignClass}`, style: { padding: p.padding }, children: /* @__PURE__ */ jsxs13("div", { className: blocks_default.videoPlaceholder, children: [
26456
- /* @__PURE__ */ jsx18("span", { style: { fontSize: "32px" }, children: "\u25B6" }),
26457
- /* @__PURE__ */ jsx18("span", { children: "Video Block" })
27172
+ return /* @__PURE__ */ jsx22("div", { className: `ee-block-video ${blocks_default.videoBlock} ${alignClass}`, style: { padding: p.padding }, children: /* @__PURE__ */ jsxs16("div", { className: blocks_default.videoPlaceholder, children: [
27173
+ /* @__PURE__ */ jsx22("span", { style: { fontSize: "32px" }, children: "\u25B6" }),
27174
+ /* @__PURE__ */ jsx22("span", { children: "Video Block" })
26458
27175
  ] }) });
26459
27176
  }
26460
- return /* @__PURE__ */ jsx18("div", { className: `ee-block-video ${blocks_default.videoBlock} ${alignClass}`, style: { padding: p.padding }, children: /* @__PURE__ */ jsxs13("div", { className: blocks_default.videoPreview, children: [
26461
- thumbnailUrl ? /* @__PURE__ */ jsx18("img", { src: thumbnailUrl, alt: p.alt, style: { maxWidth: "100%", display: "block" } }) : /* @__PURE__ */ jsxs13("div", { className: blocks_default.videoPlaceholder, children: [
26462
- /* @__PURE__ */ jsx18("span", { style: { fontSize: "32px" }, children: "\u25B6" }),
26463
- /* @__PURE__ */ jsx18("span", { children: "No thumbnail" })
27177
+ return /* @__PURE__ */ jsx22("div", { className: `ee-block-video ${blocks_default.videoBlock} ${alignClass}`, style: { padding: p.padding }, children: /* @__PURE__ */ jsxs16("div", { className: blocks_default.videoPreview, children: [
27178
+ thumbnailUrl ? /* @__PURE__ */ jsx22("img", { src: thumbnailUrl, alt: p.alt, style: { maxWidth: "100%", display: "block" } }) : /* @__PURE__ */ jsxs16("div", { className: blocks_default.videoPlaceholder, children: [
27179
+ /* @__PURE__ */ jsx22("span", { style: { fontSize: "32px" }, children: "\u25B6" }),
27180
+ /* @__PURE__ */ jsx22("span", { children: "No thumbnail" })
26464
27181
  ] }),
26465
- /* @__PURE__ */ jsx18("div", { className: blocks_default.playOverlay, children: "\u25B6" })
27182
+ /* @__PURE__ */ jsx22("div", { className: blocks_default.playOverlay, children: "\u25B6" })
26466
27183
  ] }) });
26467
27184
  });
26468
27185
  function getAutoThumbnail2(url) {
@@ -26473,8 +27190,8 @@ function getAutoThumbnail2(url) {
26473
27190
  }
26474
27191
 
26475
27192
  // src/components/Canvas/blocks/HeadingBlock.tsx
26476
- import React19, { useCallback as useCallback15, useRef as useRef14, useState as useState9, useEffect as useEffect11, useReducer as useReducer3, useMemo as useMemo10 } from "react";
26477
- import { jsx as jsx19, jsxs as jsxs14 } from "react/jsx-runtime";
27193
+ import React21, { useCallback as useCallback17, useRef as useRef16, useState as useState12, useEffect as useEffect12, useReducer as useReducer3, useMemo as useMemo10 } from "react";
27194
+ import { jsx as jsx23, jsxs as jsxs17 } from "react/jsx-runtime";
26478
27195
  var HEADING_FONT_SIZES = {
26479
27196
  h1: "36px",
26480
27197
  h2: "28px",
@@ -26484,13 +27201,13 @@ var HEADING_FONT_SIZES = {
26484
27201
  var HeadingBlockInner = function HeadingBlock({ block }) {
26485
27202
  const dispatch = useEditorDispatch();
26486
27203
  const { setActiveEditor } = useMethodsContext();
26487
- const editorRef = useRef14(null);
26488
- const wrapperRef = useRef14(null);
26489
- const blurTimerRef = useRef14(null);
26490
- const [isFocused, setIsFocused] = useState9(false);
26491
- const [editorInstance, setEditorInstance] = useState9(null);
27204
+ const editorRef = useRef16(null);
27205
+ const wrapperRef = useRef16(null);
27206
+ const blurTimerRef = useRef16(null);
27207
+ const [isFocused, setIsFocused] = useState12(false);
27208
+ const [editorInstance, setEditorInstance] = useState12(null);
26492
27209
  const [, forceToolbarUpdate] = useReducer3((c) => c + 1, 0);
26493
- useEffect11(() => {
27210
+ useEffect12(() => {
26494
27211
  if (!editorInstance) return;
26495
27212
  const onStateChange = () => forceToolbarUpdate();
26496
27213
  editorInstance.on("selectionUpdate", onStateChange);
@@ -26500,7 +27217,7 @@ var HeadingBlockInner = function HeadingBlock({ block }) {
26500
27217
  editorInstance.off("transaction", onStateChange);
26501
27218
  };
26502
27219
  }, [editorInstance]);
26503
- const handleUpdate = useCallback15(
27220
+ const handleUpdate = useCallback17(
26504
27221
  (html2) => {
26505
27222
  dispatch({
26506
27223
  type: "UPDATE_BLOCK",
@@ -26509,16 +27226,16 @@ var HeadingBlockInner = function HeadingBlock({ block }) {
26509
27226
  },
26510
27227
  [dispatch, block.id]
26511
27228
  );
26512
- const handleFocus = useCallback15(() => {
27229
+ const handleFocus = useCallback17(() => {
26513
27230
  setActiveEditor(editorRef.current);
26514
27231
  setIsFocused(true);
26515
27232
  }, [setActiveEditor]);
26516
- useEffect11(() => {
27233
+ useEffect12(() => {
26517
27234
  return () => {
26518
27235
  if (blurTimerRef.current !== null) clearTimeout(blurTimerRef.current);
26519
27236
  };
26520
27237
  }, []);
26521
- const handleBlur = useCallback15(() => {
27238
+ const handleBlur = useCallback17(() => {
26522
27239
  if (blurTimerRef.current !== null) clearTimeout(blurTimerRef.current);
26523
27240
  blurTimerRef.current = setTimeout(() => {
26524
27241
  blurTimerRef.current = null;
@@ -26532,7 +27249,7 @@ var HeadingBlockInner = function HeadingBlock({ block }) {
26532
27249
  }
26533
27250
  }, 200);
26534
27251
  }, [setActiveEditor]);
26535
- const handleEditorRef = useCallback15((editor) => {
27252
+ const handleEditorRef = useCallback17((editor) => {
26536
27253
  editorRef.current = editor;
26537
27254
  setEditorInstance(editor);
26538
27255
  }, []);
@@ -26546,11 +27263,12 @@ var HeadingBlockInner = function HeadingBlock({ block }) {
26546
27263
  padding: p.padding,
26547
27264
  fontWeight: p.fontWeight,
26548
27265
  textTransform: p.textTransform,
26549
- letterSpacing: p.letterSpacing
26550
- }), [p.fontFamily, fontSize, p.color, p.lineHeight, p.padding, p.fontWeight, p.textTransform, p.letterSpacing]);
26551
- return /* @__PURE__ */ jsxs14("div", { className: `ee-block-heading ${blocks_default.headingBlock}`, ref: wrapperRef, children: [
26552
- isFocused && editorInstance && /* @__PURE__ */ jsx19("div", { className: blocks_default.textBlockToolbar, children: /* @__PURE__ */ jsx19(RichTextToolbar, { editor: editorInstance }) }),
26553
- /* @__PURE__ */ jsx19("div", { style: wrapperStyle, children: /* @__PURE__ */ jsx19(
27266
+ letterSpacing: p.letterSpacing,
27267
+ backgroundColor: p.backgroundColor && p.backgroundColor !== "transparent" ? p.backgroundColor : void 0
27268
+ }), [p.fontFamily, fontSize, p.color, p.lineHeight, p.padding, p.fontWeight, p.textTransform, p.letterSpacing, p.backgroundColor]);
27269
+ return /* @__PURE__ */ jsxs17("div", { className: `ee-block-heading ${blocks_default.headingBlock}`, ref: wrapperRef, children: [
27270
+ isFocused && editorInstance && /* @__PURE__ */ jsx23("div", { className: blocks_default.textBlockToolbar, children: /* @__PURE__ */ jsx23(RichTextToolbar, { editor: editorInstance }) }),
27271
+ /* @__PURE__ */ jsx23("div", { style: wrapperStyle, children: /* @__PURE__ */ jsx23(
26554
27272
  TipTapEditor,
26555
27273
  {
26556
27274
  content: p.content,
@@ -26564,11 +27282,11 @@ var HeadingBlockInner = function HeadingBlock({ block }) {
26564
27282
  ) })
26565
27283
  ] });
26566
27284
  };
26567
- var HeadingBlock2 = React19.memo(HeadingBlockInner);
27285
+ var HeadingBlock2 = React21.memo(HeadingBlockInner);
26568
27286
 
26569
27287
  // src/components/Canvas/blocks/CountdownBlock.tsx
26570
- import React20, { useState as useState10, useEffect as useEffect12, useMemo as useMemo11 } from "react";
26571
- import { jsx as jsx20, jsxs as jsxs15 } from "react/jsx-runtime";
27288
+ import React22, { useState as useState13, useEffect as useEffect13, useMemo as useMemo11 } from "react";
27289
+ import { jsx as jsx24, jsxs as jsxs18 } from "react/jsx-runtime";
26572
27290
  function getTimeRemaining(targetDate) {
26573
27291
  const total = Math.max(0, new Date(targetDate).getTime() - Date.now());
26574
27292
  return {
@@ -26578,10 +27296,10 @@ function getTimeRemaining(targetDate) {
26578
27296
  seconds: Math.floor(total / 1e3 % 60)
26579
27297
  };
26580
27298
  }
26581
- var CountdownBlock = React20.memo(function CountdownBlock2({ block }) {
27299
+ var CountdownBlock = React22.memo(function CountdownBlock2({ block }) {
26582
27300
  const p = block.properties;
26583
- const [time, setTime] = useState10(() => getTimeRemaining(p.targetDate));
26584
- useEffect12(() => {
27301
+ const [time, setTime] = useState13(() => getTimeRemaining(p.targetDate));
27302
+ useEffect13(() => {
26585
27303
  setTime(getTimeRemaining(p.targetDate));
26586
27304
  const interval = setInterval(() => {
26587
27305
  setTime(getTimeRemaining(p.targetDate));
@@ -26614,10 +27332,10 @@ var CountdownBlock = React20.memo(function CountdownBlock2({ block }) {
26614
27332
  const unitLabelStyle = useMemo11(() => ({
26615
27333
  color: p.labelColor
26616
27334
  }), [p.labelColor]);
26617
- return /* @__PURE__ */ jsxs15("div", { className: `ee-block-countdown ${blocks_default.countdownBlock}`, style: wrapperStyle, children: [
26618
- p.label && /* @__PURE__ */ jsx20("div", { className: blocks_default.countdownLabel, style: labelStyle, children: p.label }),
26619
- /* @__PURE__ */ jsx20("div", { className: blocks_default.countdownDigits, style: digitsContainerStyle, children: units.map((unit) => /* @__PURE__ */ jsxs15("div", { className: blocks_default.countdownUnit, children: [
26620
- /* @__PURE__ */ jsx20(
27335
+ return /* @__PURE__ */ jsxs18("div", { className: `ee-block-countdown ${blocks_default.countdownBlock}`, style: wrapperStyle, children: [
27336
+ p.label && /* @__PURE__ */ jsx24("div", { className: blocks_default.countdownLabel, style: labelStyle, children: p.label }),
27337
+ /* @__PURE__ */ jsx24("div", { className: blocks_default.countdownDigits, style: digitsContainerStyle, children: units.map((unit) => /* @__PURE__ */ jsxs18("div", { className: blocks_default.countdownUnit, children: [
27338
+ /* @__PURE__ */ jsx24(
26621
27339
  "div",
26622
27340
  {
26623
27341
  className: blocks_default.countdownDigitBox,
@@ -26625,15 +27343,15 @@ var CountdownBlock = React20.memo(function CountdownBlock2({ block }) {
26625
27343
  children: String(unit.value).padStart(2, "0")
26626
27344
  }
26627
27345
  ),
26628
- /* @__PURE__ */ jsx20("div", { className: blocks_default.countdownUnitLabel, style: unitLabelStyle, children: unit.label })
27346
+ /* @__PURE__ */ jsx24("div", { className: blocks_default.countdownUnitLabel, style: unitLabelStyle, children: unit.label })
26629
27347
  ] }, unit.label)) })
26630
27348
  ] });
26631
27349
  });
26632
27350
 
26633
27351
  // src/components/Canvas/blocks/MenuBlock.tsx
26634
- import React21, { useMemo as useMemo12 } from "react";
26635
- import { jsx as jsx21 } from "react/jsx-runtime";
26636
- var MenuBlock = React21.memo(function MenuBlock2({ block }) {
27352
+ import React23, { useMemo as useMemo12 } from "react";
27353
+ import { jsx as jsx25 } from "react/jsx-runtime";
27354
+ var MenuBlock = React23.memo(function MenuBlock2({ block }) {
26637
27355
  const p = block.properties;
26638
27356
  const alignStyle = p.align === "left" ? "flex-start" : p.align === "right" ? "flex-end" : "center";
26639
27357
  const wrapperStyle = useMemo12(() => ({
@@ -26648,7 +27366,7 @@ var MenuBlock = React21.memo(function MenuBlock2({ block }) {
26648
27366
  fontSize: p.fontSize,
26649
27367
  color: p.color
26650
27368
  }), [p.fontFamily, p.fontSize, p.color]);
26651
- return /* @__PURE__ */ jsx21("div", { className: `ee-block-menu ${blocks_default.menuBlock}`, style: wrapperStyle, children: /* @__PURE__ */ jsx21("div", { className: blocks_default.menuItems, style: itemsStyle, children: p.items.map((item) => /* @__PURE__ */ jsx21(
27369
+ return /* @__PURE__ */ jsx25("div", { className: `ee-block-menu ${blocks_default.menuBlock}`, style: wrapperStyle, children: /* @__PURE__ */ jsx25("div", { className: blocks_default.menuItems, style: itemsStyle, children: p.items.map((item) => /* @__PURE__ */ jsx25(
26652
27370
  "span",
26653
27371
  {
26654
27372
  className: blocks_default.menuItem,
@@ -26660,9 +27378,9 @@ var MenuBlock = React21.memo(function MenuBlock2({ block }) {
26660
27378
  });
26661
27379
 
26662
27380
  // src/components/Canvas/blocks/HeroBlock.tsx
26663
- import React22, { useMemo as useMemo13 } from "react";
26664
- import { jsx as jsx22, jsxs as jsxs16 } from "react/jsx-runtime";
26665
- var HeroBlock = React22.memo(function HeroBlock2({ block }) {
27381
+ import React24, { useMemo as useMemo13 } from "react";
27382
+ import { jsx as jsx26, jsxs as jsxs19 } from "react/jsx-runtime";
27383
+ var HeroBlock = React24.memo(function HeroBlock2({ block }) {
26666
27384
  const p = block.properties;
26667
27385
  const containerStyle = useMemo13(() => ({
26668
27386
  padding: p.padding,
@@ -26686,8 +27404,8 @@ var HeroBlock = React22.memo(function HeroBlock2({ block }) {
26686
27404
  color: p.buttonColor,
26687
27405
  borderRadius: p.buttonBorderRadius
26688
27406
  }), [p.buttonBackgroundColor, p.buttonColor, p.buttonBorderRadius]);
26689
- return /* @__PURE__ */ jsxs16("div", { className: `ee-block-hero ${blocks_default.heroBlock}`, style: containerStyle, children: [
26690
- p.heading && /* @__PURE__ */ jsx22(
27407
+ return /* @__PURE__ */ jsxs19("div", { className: `ee-block-hero ${blocks_default.heroBlock}`, style: containerStyle, children: [
27408
+ p.heading && /* @__PURE__ */ jsx26(
26691
27409
  "h2",
26692
27410
  {
26693
27411
  className: blocks_default.heroHeading,
@@ -26695,7 +27413,7 @@ var HeroBlock = React22.memo(function HeroBlock2({ block }) {
26695
27413
  children: p.heading
26696
27414
  }
26697
27415
  ),
26698
- p.subtext && /* @__PURE__ */ jsx22(
27416
+ p.subtext && /* @__PURE__ */ jsx26(
26699
27417
  "p",
26700
27418
  {
26701
27419
  className: blocks_default.heroSubtext,
@@ -26703,7 +27421,7 @@ var HeroBlock = React22.memo(function HeroBlock2({ block }) {
26703
27421
  children: p.subtext
26704
27422
  }
26705
27423
  ),
26706
- p.buttonText && /* @__PURE__ */ jsx22(
27424
+ p.buttonText && /* @__PURE__ */ jsx26(
26707
27425
  "span",
26708
27426
  {
26709
27427
  className: blocks_default.heroButton,
@@ -26715,7 +27433,7 @@ var HeroBlock = React22.memo(function HeroBlock2({ block }) {
26715
27433
  });
26716
27434
 
26717
27435
  // src/components/Canvas/BlockRenderer.tsx
26718
- import { jsx as jsx23 } from "react/jsx-runtime";
27436
+ import { jsx as jsx27 } from "react/jsx-runtime";
26719
27437
  registerBlockRenderer("text", TextBlock2);
26720
27438
  registerBlockRenderer("button", ButtonBlock);
26721
27439
  registerBlockRenderer("image", ImageBlock2);
@@ -26728,14 +27446,14 @@ registerBlockRenderer("heading", HeadingBlock2);
26728
27446
  registerBlockRenderer("countdown", CountdownBlock);
26729
27447
  registerBlockRenderer("menu", MenuBlock);
26730
27448
  registerBlockRenderer("hero", HeroBlock);
26731
- var BlockRenderer = React23.memo(function BlockRenderer2({ block }) {
27449
+ var BlockRenderer = React25.memo(function BlockRenderer2({ block }) {
26732
27450
  const Component2 = blockRendererRegistry[block.type];
26733
27451
  if (!Component2) return null;
26734
- return /* @__PURE__ */ jsx23(ErrorBoundary, { children: /* @__PURE__ */ jsx23(Component2, { block }) });
27452
+ return /* @__PURE__ */ jsx27(ErrorBoundary, { children: /* @__PURE__ */ jsx27(Component2, { block }) });
26735
27453
  });
26736
27454
 
26737
27455
  // src/components/Canvas/DropZone.tsx
26738
- import React24, { useState as useState11, useCallback as useCallback16, useRef as useRef15 } from "react";
27456
+ import React26, { useState as useState14, useCallback as useCallback18, useRef as useRef17 } from "react";
26739
27457
 
26740
27458
  // src/styles/canvas.module.css
26741
27459
  var canvas_default = {
@@ -26770,12 +27488,12 @@ var canvas_default = {
26770
27488
  };
26771
27489
 
26772
27490
  // src/components/Canvas/DropZone.tsx
26773
- import { jsx as jsx24 } from "react/jsx-runtime";
26774
- var DropZone = React24.memo(function DropZone2({ sectionId, columnId, index, emptyPlaceholder }) {
27491
+ import { jsx as jsx28 } from "react/jsx-runtime";
27492
+ var DropZone = React26.memo(function DropZone2({ sectionId, columnId, index, emptyPlaceholder }) {
26775
27493
  const dispatch = useEditorDispatch();
26776
- const [isOver, setIsOver] = useState11(false);
26777
- const isOverRef = useRef15(false);
26778
- const handleDragOver = useCallback16(
27494
+ const [isOver, setIsOver] = useState14(false);
27495
+ const isOverRef = useRef17(false);
27496
+ const handleDragOver = useCallback18(
26779
27497
  (e) => {
26780
27498
  if (!isDropAllowed(e)) return;
26781
27499
  e.preventDefault();
@@ -26788,7 +27506,7 @@ var DropZone = React24.memo(function DropZone2({ sectionId, columnId, index, emp
26788
27506
  },
26789
27507
  []
26790
27508
  );
26791
- const handleDragLeave = useCallback16((e) => {
27509
+ const handleDragLeave = useCallback18((e) => {
26792
27510
  const rect = e.currentTarget.getBoundingClientRect();
26793
27511
  const { clientX, clientY } = e;
26794
27512
  if (clientX >= rect.left && clientX <= rect.right && clientY >= rect.top && clientY <= rect.bottom) {
@@ -26797,7 +27515,7 @@ var DropZone = React24.memo(function DropZone2({ sectionId, columnId, index, emp
26797
27515
  isOverRef.current = false;
26798
27516
  setIsOver(false);
26799
27517
  }, []);
26800
- const handleDrop2 = useCallback16(
27518
+ const handleDrop2 = useCallback18(
26801
27519
  (e) => {
26802
27520
  e.preventDefault();
26803
27521
  e.stopPropagation();
@@ -26834,7 +27552,7 @@ var DropZone = React24.memo(function DropZone2({ sectionId, columnId, index, emp
26834
27552
  [dispatch, sectionId, columnId, index]
26835
27553
  );
26836
27554
  if (emptyPlaceholder) {
26837
- return /* @__PURE__ */ jsx24(
27555
+ return /* @__PURE__ */ jsx28(
26838
27556
  "div",
26839
27557
  {
26840
27558
  className: `ee-drop-zone ee-drop-zone--empty ${canvas_default.emptyColumn} ${isOver ? canvas_default.emptyColumnActive : ""}`,
@@ -26845,20 +27563,20 @@ var DropZone = React24.memo(function DropZone2({ sectionId, columnId, index, emp
26845
27563
  }
26846
27564
  );
26847
27565
  }
26848
- return /* @__PURE__ */ jsx24(
27566
+ return /* @__PURE__ */ jsx28(
26849
27567
  "div",
26850
27568
  {
26851
27569
  className: `ee-drop-zone ${canvas_default.dropZone} ${isOver ? canvas_default.dropZoneActive : ""}`,
26852
27570
  onDragOver: handleDragOver,
26853
27571
  onDragLeave: handleDragLeave,
26854
27572
  onDrop: handleDrop2,
26855
- children: isOver && /* @__PURE__ */ jsx24("div", { className: canvas_default.dropZoneLabel, children: "Drop here" })
27573
+ children: isOver && /* @__PURE__ */ jsx28("div", { className: canvas_default.dropZoneLabel, children: "Drop here" })
26856
27574
  }
26857
27575
  );
26858
27576
  });
26859
27577
 
26860
27578
  // src/components/Canvas/Column.tsx
26861
- import { jsx as jsx25, jsxs as jsxs17 } from "react/jsx-runtime";
27579
+ import { jsx as jsx29, jsxs as jsxs20 } from "react/jsx-runtime";
26862
27580
  function getBlockData(e) {
26863
27581
  const el = e.currentTarget;
26864
27582
  const blockId = el.dataset.blockId;
@@ -26866,17 +27584,17 @@ function getBlockData(e) {
26866
27584
  if (!blockId || index === void 0) return null;
26867
27585
  return { blockId, index: Number(index) };
26868
27586
  }
26869
- var Column = React25.memo(function Column2({ column, sectionId }) {
27587
+ var Column = React27.memo(function Column2({ column, sectionId }) {
26870
27588
  const selection = useSelectionContext();
26871
27589
  const dispatch = useEditorDispatch();
26872
- const [blockToRemove, setBlockToRemove] = useState12(null);
26873
- const confirmRemoveBlock = useCallback17(
27590
+ const [blockToRemove, setBlockToRemove] = useState15(null);
27591
+ const confirmRemoveBlock = useCallback19(
26874
27592
  (blockId) => {
26875
27593
  setBlockToRemove(blockId);
26876
27594
  },
26877
27595
  []
26878
27596
  );
26879
- const handleConfirmRemove = useCallback17(() => {
27597
+ const handleConfirmRemove = useCallback19(() => {
26880
27598
  if (blockToRemove) {
26881
27599
  dispatch({
26882
27600
  type: "REMOVE_BLOCK",
@@ -26885,7 +27603,7 @@ var Column = React25.memo(function Column2({ column, sectionId }) {
26885
27603
  setBlockToRemove(null);
26886
27604
  }
26887
27605
  }, [dispatch, sectionId, column.id, blockToRemove]);
26888
- const handleBlockClick = useCallback17(
27606
+ const handleBlockClick = useCallback19(
26889
27607
  (e) => {
26890
27608
  e.stopPropagation();
26891
27609
  const data = getBlockData(e);
@@ -26897,7 +27615,7 @@ var Column = React25.memo(function Column2({ column, sectionId }) {
26897
27615
  },
26898
27616
  [dispatch, sectionId, column.id]
26899
27617
  );
26900
- const handleRemoveClick = useCallback17(
27618
+ const handleRemoveClick = useCallback19(
26901
27619
  (e) => {
26902
27620
  e.stopPropagation();
26903
27621
  const wrapper = e.currentTarget.closest("[data-block-id]");
@@ -26905,7 +27623,7 @@ var Column = React25.memo(function Column2({ column, sectionId }) {
26905
27623
  },
26906
27624
  [confirmRemoveBlock]
26907
27625
  );
26908
- const handleDuplicateClick = useCallback17(
27626
+ const handleDuplicateClick = useCallback19(
26909
27627
  (e) => {
26910
27628
  e.stopPropagation();
26911
27629
  const wrapper = e.currentTarget.closest("[data-block-id]");
@@ -26918,7 +27636,7 @@ var Column = React25.memo(function Column2({ column, sectionId }) {
26918
27636
  },
26919
27637
  [dispatch, sectionId, column.id]
26920
27638
  );
26921
- const handleBlockDragStart = useCallback17(
27639
+ const handleBlockDragStart = useCallback19(
26922
27640
  (e) => {
26923
27641
  const data = getBlockData(e);
26924
27642
  if (!data) return;
@@ -26926,8 +27644,8 @@ var Column = React25.memo(function Column2({ column, sectionId }) {
26926
27644
  },
26927
27645
  [sectionId, column.id]
26928
27646
  );
26929
- const [dropTarget, setDropTarget] = useState12(null);
26930
- const handleBlockDragOver = useCallback17(
27647
+ const [dropTarget, setDropTarget] = useState15(null);
27648
+ const handleBlockDragOver = useCallback19(
26931
27649
  (e) => {
26932
27650
  if (!isDropAllowed(e)) return;
26933
27651
  e.preventDefault();
@@ -26945,7 +27663,7 @@ var Column = React25.memo(function Column2({ column, sectionId }) {
26945
27663
  },
26946
27664
  []
26947
27665
  );
26948
- const handleBlockDragLeave = useCallback17((e) => {
27666
+ const handleBlockDragLeave = useCallback19((e) => {
26949
27667
  const rect = e.currentTarget.getBoundingClientRect();
26950
27668
  const { clientX, clientY } = e;
26951
27669
  if (clientX >= rect.left && clientX <= rect.right && clientY >= rect.top && clientY <= rect.bottom) {
@@ -26953,7 +27671,7 @@ var Column = React25.memo(function Column2({ column, sectionId }) {
26953
27671
  }
26954
27672
  setDropTarget(null);
26955
27673
  }, []);
26956
- const handleBlockDrop = useCallback17(
27674
+ const handleBlockDrop = useCallback19(
26957
27675
  (e) => {
26958
27676
  e.preventDefault();
26959
27677
  e.stopPropagation();
@@ -26993,7 +27711,7 @@ var Column = React25.memo(function Column2({ column, sectionId }) {
26993
27711
  },
26994
27712
  [dispatch, sectionId, column.id]
26995
27713
  );
26996
- const handleBlockKeyDown = useCallback17(
27714
+ const handleBlockKeyDown = useCallback19(
26997
27715
  (e) => {
26998
27716
  const target = e.target;
26999
27717
  if (target.isContentEditable || target.tagName === "INPUT" || target.tagName === "TEXTAREA") {
@@ -27017,7 +27735,7 @@ var Column = React25.memo(function Column2({ column, sectionId }) {
27017
27735
  [dispatch, sectionId, column.id, confirmRemoveBlock]
27018
27736
  );
27019
27737
  if (column.blocks.length === 0) {
27020
- return /* @__PURE__ */ jsx25("div", { className: `ee-column ${canvas_default.column}`, style: { width: column.width }, children: /* @__PURE__ */ jsx25(
27738
+ return /* @__PURE__ */ jsx29("div", { className: `ee-column ${canvas_default.column}`, style: { width: column.width }, children: /* @__PURE__ */ jsx29(
27021
27739
  DropZone,
27022
27740
  {
27023
27741
  sectionId,
@@ -27027,10 +27745,10 @@ var Column = React25.memo(function Column2({ column, sectionId }) {
27027
27745
  }
27028
27746
  ) });
27029
27747
  }
27030
- return /* @__PURE__ */ jsxs17("div", { className: `ee-column ${canvas_default.column}`, style: { width: column.width }, children: [
27031
- column.blocks.map((block, index) => /* @__PURE__ */ jsxs17(React25.Fragment, { children: [
27032
- /* @__PURE__ */ jsx25(DropZone, { sectionId, columnId: column.id, index }),
27033
- /* @__PURE__ */ jsxs17(
27748
+ return /* @__PURE__ */ jsxs20("div", { className: `ee-column ${canvas_default.column}`, style: { width: column.width }, children: [
27749
+ column.blocks.map((block, index) => /* @__PURE__ */ jsxs20(React27.Fragment, { children: [
27750
+ /* @__PURE__ */ jsx29(DropZone, { sectionId, columnId: column.id, index }),
27751
+ /* @__PURE__ */ jsxs20(
27034
27752
  "div",
27035
27753
  {
27036
27754
  "data-block-type": block.type,
@@ -27057,8 +27775,8 @@ var Column = React25.memo(function Column2({ column, sectionId }) {
27057
27775
  "aria-selected": selection.blockId === block.id,
27058
27776
  tabIndex: 0,
27059
27777
  children: [
27060
- /* @__PURE__ */ jsxs17("div", { className: `ee-block-actions ${canvas_default.blockOverlay}`, role: "group", "aria-label": "Block actions", children: [
27061
- /* @__PURE__ */ jsx25(
27778
+ /* @__PURE__ */ jsxs20("div", { className: `ee-block-actions ${canvas_default.blockOverlay}`, role: "group", "aria-label": "Block actions", children: [
27779
+ /* @__PURE__ */ jsx29(
27062
27780
  "button",
27063
27781
  {
27064
27782
  className: `ee-block-duplicate ${canvas_default.blockBtn} ${canvas_default.blockBtnDuplicate}`,
@@ -27068,7 +27786,7 @@ var Column = React25.memo(function Column2({ column, sectionId }) {
27068
27786
  children: "\u29C9"
27069
27787
  }
27070
27788
  ),
27071
- /* @__PURE__ */ jsx25(
27789
+ /* @__PURE__ */ jsx29(
27072
27790
  "button",
27073
27791
  {
27074
27792
  className: `ee-block-remove ${canvas_default.blockBtn}`,
@@ -27079,12 +27797,12 @@ var Column = React25.memo(function Column2({ column, sectionId }) {
27079
27797
  }
27080
27798
  )
27081
27799
  ] }),
27082
- /* @__PURE__ */ jsx25(BlockRenderer, { block })
27800
+ /* @__PURE__ */ jsx29(BlockRenderer, { block })
27083
27801
  ]
27084
27802
  }
27085
27803
  )
27086
27804
  ] }, block.id)),
27087
- /* @__PURE__ */ jsx25(
27805
+ /* @__PURE__ */ jsx29(
27088
27806
  DropZone,
27089
27807
  {
27090
27808
  sectionId,
@@ -27092,7 +27810,7 @@ var Column = React25.memo(function Column2({ column, sectionId }) {
27092
27810
  index: column.blocks.length
27093
27811
  }
27094
27812
  ),
27095
- blockToRemove && /* @__PURE__ */ jsx25(
27813
+ blockToRemove && /* @__PURE__ */ jsx29(
27096
27814
  ConfirmDialog,
27097
27815
  {
27098
27816
  title: "Remove Block",
@@ -27105,45 +27823,45 @@ var Column = React25.memo(function Column2({ column, sectionId }) {
27105
27823
  });
27106
27824
 
27107
27825
  // src/components/Canvas/Section.tsx
27108
- import { jsx as jsx26, jsxs as jsxs18 } from "react/jsx-runtime";
27109
- var Section = React26.memo(function Section2({ section }) {
27826
+ import { jsx as jsx30, jsxs as jsxs21 } from "react/jsx-runtime";
27827
+ var Section = React28.memo(function Section2({ section }) {
27110
27828
  const selection = useSelectionContext();
27111
27829
  const dispatch = useEditorDispatch();
27112
27830
  const { template } = useTemplateContext();
27113
27831
  const isSelected = selection.sectionId === section.id && !selection.blockId;
27114
- const [showRemoveConfirm, setShowRemoveConfirm] = useState13(false);
27115
- const handleClick2 = useCallback18(
27832
+ const [showRemoveConfirm, setShowRemoveConfirm] = useState16(false);
27833
+ const handleClick2 = useCallback20(
27116
27834
  (e) => {
27117
27835
  e.stopPropagation();
27118
27836
  dispatch({ type: "SELECT_SECTION", payload: { sectionId: section.id } });
27119
27837
  },
27120
27838
  [dispatch, section.id]
27121
27839
  );
27122
- const handleRemove = useCallback18(
27840
+ const handleRemove = useCallback20(
27123
27841
  (e) => {
27124
27842
  e.stopPropagation();
27125
27843
  setShowRemoveConfirm(true);
27126
27844
  },
27127
27845
  []
27128
27846
  );
27129
- const handleConfirmRemove = useCallback18(() => {
27847
+ const handleConfirmRemove = useCallback20(() => {
27130
27848
  dispatch({ type: "REMOVE_SECTION", payload: { sectionId: section.id } });
27131
27849
  setShowRemoveConfirm(false);
27132
27850
  }, [dispatch, section.id]);
27133
- const handleDuplicate = useCallback18(
27851
+ const handleDuplicate = useCallback20(
27134
27852
  (e) => {
27135
27853
  e.stopPropagation();
27136
27854
  dispatch({ type: "DUPLICATE_SECTION", payload: { sectionId: section.id } });
27137
27855
  },
27138
27856
  [dispatch, section.id]
27139
27857
  );
27140
- const handleDragStart = useCallback18(
27858
+ const handleDragStart = useCallback20(
27141
27859
  (e) => {
27142
27860
  setSectionMoveDragData(e, section.id);
27143
27861
  },
27144
27862
  [section.id]
27145
27863
  );
27146
- const handleDragKeyDown = useCallback18(
27864
+ const handleDragKeyDown = useCallback20(
27147
27865
  (e) => {
27148
27866
  if (e.key !== "ArrowUp" && e.key !== "ArrowDown") return;
27149
27867
  e.preventDefault();
@@ -27157,7 +27875,7 @@ var Section = React26.memo(function Section2({ section }) {
27157
27875
  },
27158
27876
  [dispatch, section.id, template.sections]
27159
27877
  );
27160
- return /* @__PURE__ */ jsxs18(
27878
+ return /* @__PURE__ */ jsxs21(
27161
27879
  "div",
27162
27880
  {
27163
27881
  className: `ee-section ${isSelected ? "ee-section--selected" : ""} ${section.properties.fullWidth ? "ee-section--full-width" : ""} ${canvas_default.section} ${isSelected ? canvas_default.sectionSelected : ""} ${section.properties.fullWidth ? canvas_default.sectionFullWidth : ""}`,
@@ -27174,8 +27892,8 @@ var Section = React26.memo(function Section2({ section }) {
27174
27892
  "aria-label": `Email section${isSelected ? " (selected)" : ""}`,
27175
27893
  "aria-selected": isSelected,
27176
27894
  children: [
27177
- /* @__PURE__ */ jsxs18("div", { className: `ee-section-actions ${canvas_default.sectionOverlay}`, role: "group", "aria-label": "Section actions", children: [
27178
- /* @__PURE__ */ jsx26(
27895
+ /* @__PURE__ */ jsxs21("div", { className: `ee-section-actions ${canvas_default.sectionOverlay}`, role: "group", "aria-label": "Section actions", children: [
27896
+ /* @__PURE__ */ jsx30(
27179
27897
  "span",
27180
27898
  {
27181
27899
  className: `ee-section-drag ${canvas_default.sectionDragHandle}`,
@@ -27189,7 +27907,7 @@ var Section = React26.memo(function Section2({ section }) {
27189
27907
  children: "\u283F"
27190
27908
  }
27191
27909
  ),
27192
- /* @__PURE__ */ jsx26(
27910
+ /* @__PURE__ */ jsx30(
27193
27911
  "button",
27194
27912
  {
27195
27913
  className: `ee-section-duplicate ${canvas_default.sectionBtn} ${canvas_default.sectionBtnDuplicate}`,
@@ -27199,7 +27917,7 @@ var Section = React26.memo(function Section2({ section }) {
27199
27917
  children: "\u29C9"
27200
27918
  }
27201
27919
  ),
27202
- /* @__PURE__ */ jsx26(
27920
+ /* @__PURE__ */ jsx30(
27203
27921
  "button",
27204
27922
  {
27205
27923
  className: `ee-section-remove ${canvas_default.sectionBtn}`,
@@ -27210,8 +27928,8 @@ var Section = React26.memo(function Section2({ section }) {
27210
27928
  }
27211
27929
  )
27212
27930
  ] }),
27213
- /* @__PURE__ */ jsx26("div", { className: canvas_default.sectionContent, children: section.columns.map((column) => /* @__PURE__ */ jsx26(Column, { column, sectionId: section.id }, column.id)) }),
27214
- showRemoveConfirm && /* @__PURE__ */ jsx26(
27931
+ /* @__PURE__ */ jsx30("div", { className: canvas_default.sectionContent, children: section.columns.map((column) => /* @__PURE__ */ jsx30(Column, { column, sectionId: section.id }, column.id)) }),
27932
+ showRemoveConfirm && /* @__PURE__ */ jsx30(
27215
27933
  ConfirmDialog,
27216
27934
  {
27217
27935
  title: "Remove Section",
@@ -27226,13 +27944,13 @@ var Section = React26.memo(function Section2({ section }) {
27226
27944
  });
27227
27945
 
27228
27946
  // src/components/Canvas/SectionDropZone.tsx
27229
- import React27, { useState as useState14, useCallback as useCallback19, useRef as useRef16 } from "react";
27230
- import { jsx as jsx27 } from "react/jsx-runtime";
27231
- var SectionDropZone = React27.memo(function SectionDropZone2({ index }) {
27947
+ import React29, { useState as useState17, useCallback as useCallback21, useRef as useRef18 } from "react";
27948
+ import { jsx as jsx31 } from "react/jsx-runtime";
27949
+ var SectionDropZone = React29.memo(function SectionDropZone2({ index }) {
27232
27950
  const dispatch = useEditorDispatch();
27233
- const [isOver, setIsOver] = useState14(false);
27234
- const isOverRef = useRef16(false);
27235
- const handleDragOver = useCallback19((e) => {
27951
+ const [isOver, setIsOver] = useState17(false);
27952
+ const isOverRef = useRef18(false);
27953
+ const handleDragOver = useCallback21((e) => {
27236
27954
  if (!isSectionDrop(e)) return;
27237
27955
  e.preventDefault();
27238
27956
  e.stopPropagation();
@@ -27242,7 +27960,7 @@ var SectionDropZone = React27.memo(function SectionDropZone2({ index }) {
27242
27960
  setIsOver(true);
27243
27961
  }
27244
27962
  }, []);
27245
- const handleDragLeave = useCallback19((e) => {
27963
+ const handleDragLeave = useCallback21((e) => {
27246
27964
  const rect = e.currentTarget.getBoundingClientRect();
27247
27965
  const { clientX, clientY } = e;
27248
27966
  if (clientX >= rect.left && clientX <= rect.right && clientY >= rect.top && clientY <= rect.bottom) {
@@ -27251,7 +27969,7 @@ var SectionDropZone = React27.memo(function SectionDropZone2({ index }) {
27251
27969
  isOverRef.current = false;
27252
27970
  setIsOver(false);
27253
27971
  }, []);
27254
- const handleDrop2 = useCallback19(
27972
+ const handleDrop2 = useCallback21(
27255
27973
  (e) => {
27256
27974
  e.preventDefault();
27257
27975
  e.stopPropagation();
@@ -27266,37 +27984,37 @@ var SectionDropZone = React27.memo(function SectionDropZone2({ index }) {
27266
27984
  },
27267
27985
  [dispatch, index]
27268
27986
  );
27269
- return /* @__PURE__ */ jsx27(
27987
+ return /* @__PURE__ */ jsx31(
27270
27988
  "div",
27271
27989
  {
27272
27990
  className: `ee-section-drop-zone ${canvas_default.sectionDropZone} ${isOver ? canvas_default.sectionDropZoneActive : ""}`,
27273
27991
  onDragOver: handleDragOver,
27274
27992
  onDragLeave: handleDragLeave,
27275
27993
  onDrop: handleDrop2,
27276
- children: isOver && /* @__PURE__ */ jsx27("div", { className: canvas_default.sectionDropZoneLabel, children: "Move section here" })
27994
+ children: isOver && /* @__PURE__ */ jsx31("div", { className: canvas_default.sectionDropZoneLabel, children: "Move section here" })
27277
27995
  }
27278
27996
  );
27279
27997
  });
27280
27998
 
27281
27999
  // src/components/Canvas/Canvas.tsx
27282
- import { jsx as jsx28, jsxs as jsxs19 } from "react/jsx-runtime";
27283
- var Canvas = React28.memo(function Canvas2() {
28000
+ import { jsx as jsx32, jsxs as jsxs22 } from "react/jsx-runtime";
28001
+ var Canvas = React30.memo(function Canvas2() {
27284
28002
  const { template } = useTemplateContext();
27285
28003
  const dispatch = useEditorDispatch();
27286
- const [isDragOver, setIsDragOver] = useState15(false);
27287
- const handleAddSection = useCallback20(() => {
28004
+ const [isDragOver, setIsDragOver] = useState18(false);
28005
+ const handleAddSection = useCallback22(() => {
27288
28006
  dispatch({ type: "ADD_SECTION", payload: { section: createSection() } });
27289
28007
  }, [dispatch]);
27290
- const handleCanvasClick = useCallback20(() => {
28008
+ const handleCanvasClick = useCallback22(() => {
27291
28009
  dispatch({ type: "DESELECT_ALL" });
27292
28010
  }, [dispatch]);
27293
- const handleBodyDragOver = useCallback20((e) => {
28011
+ const handleBodyDragOver = useCallback22((e) => {
27294
28012
  if (!isDropAllowed(e)) return;
27295
28013
  e.preventDefault();
27296
28014
  e.dataTransfer.dropEffect = "copy";
27297
28015
  setIsDragOver(true);
27298
28016
  }, []);
27299
- const handleBodyDragLeave = useCallback20((e) => {
28017
+ const handleBodyDragLeave = useCallback22((e) => {
27300
28018
  const rect = e.currentTarget.getBoundingClientRect();
27301
28019
  const { clientX, clientY } = e;
27302
28020
  if (clientX >= rect.left && clientX <= rect.right && clientY >= rect.top && clientY <= rect.bottom) {
@@ -27304,7 +28022,7 @@ var Canvas = React28.memo(function Canvas2() {
27304
28022
  }
27305
28023
  setIsDragOver(false);
27306
28024
  }, []);
27307
- const handleBodyDrop = useCallback20(
28025
+ const handleBodyDrop = useCallback22(
27308
28026
  (e) => {
27309
28027
  e.preventDefault();
27310
28028
  setIsDragOver(false);
@@ -27321,7 +28039,7 @@ var Canvas = React28.memo(function Canvas2() {
27321
28039
  },
27322
28040
  [dispatch]
27323
28041
  );
27324
- return /* @__PURE__ */ jsx28("div", { className: `ee-canvas-wrapper ${canvas_default.canvasWrapper}`, onClick: handleCanvasClick, role: "main", "aria-label": "Email canvas", children: /* @__PURE__ */ jsxs19(
28042
+ return /* @__PURE__ */ jsx32("div", { className: `ee-canvas-wrapper ${canvas_default.canvasWrapper}`, onClick: handleCanvasClick, role: "main", "aria-label": "Email canvas", children: /* @__PURE__ */ jsxs22(
27325
28043
  "div",
27326
28044
  {
27327
28045
  className: `ee-canvas-body ${canvas_default.canvasBody} ${isDragOver ? canvas_default.canvasBodyDragOver : ""}`,
@@ -27336,25 +28054,25 @@ var Canvas = React28.memo(function Canvas2() {
27336
28054
  onDrop: handleBodyDrop,
27337
28055
  "aria-label": "Email content area",
27338
28056
  children: [
27339
- template.sections.map((section, index) => /* @__PURE__ */ jsxs19(React28.Fragment, { children: [
27340
- /* @__PURE__ */ jsx28(SectionDropZone, { index }),
27341
- /* @__PURE__ */ jsx28(Section, { section })
28057
+ template.sections.map((section, index) => /* @__PURE__ */ jsxs22(React30.Fragment, { children: [
28058
+ /* @__PURE__ */ jsx32(SectionDropZone, { index }),
28059
+ /* @__PURE__ */ jsx32(Section, { section })
27342
28060
  ] }, section.id)),
27343
- template.sections.length > 0 && /* @__PURE__ */ jsx28(SectionDropZone, { index: template.sections.length }),
27344
- /* @__PURE__ */ jsx28("button", { className: `ee-add-section ${canvas_default.addSectionBtn}`, onClick: handleAddSection, "aria-label": "Add new section", children: "+ Add Section" })
28061
+ template.sections.length > 0 && /* @__PURE__ */ jsx32(SectionDropZone, { index: template.sections.length }),
28062
+ /* @__PURE__ */ jsx32("button", { className: `ee-add-section ${canvas_default.addSectionBtn}`, onClick: handleAddSection, "aria-label": "Add new section", children: "+ Add Section" })
27345
28063
  ]
27346
28064
  }
27347
28065
  ) });
27348
28066
  });
27349
28067
 
27350
28068
  // src/components/Properties/SectionProperties.tsx
27351
- import { useCallback as useCallback25 } from "react";
28069
+ import { useCallback as useCallback27 } from "react";
27352
28070
 
27353
28071
  // src/components/Properties/PropertyField.tsx
27354
- import React33 from "react";
28072
+ import React35 from "react";
27355
28073
 
27356
28074
  // src/components/Properties/controls/ColorPicker.tsx
27357
- import { useState as useState16, useCallback as useCallback21, useRef as useRef17, useEffect as useEffect13 } from "react";
28075
+ import { useState as useState19, useCallback as useCallback23, useRef as useRef19, useEffect as useEffect14 } from "react";
27358
28076
 
27359
28077
  // src/styles/properties.module.css
27360
28078
  var properties_default = {
@@ -27402,16 +28120,18 @@ var properties_default = {
27402
28120
  "fieldInputStacked": "fieldInputStacked fieldInput",
27403
28121
  "checkboxLabel": "checkboxLabel fieldLabel",
27404
28122
  "colorPresetBtnFull": "colorPresetBtnFull",
27405
- "colorNativeInput": "colorNativeInput",
28123
+ "colorPresetSectionLabel": "colorPresetSectionLabel",
28124
+ "colorSavePresetBtn": "colorSavePresetBtn",
27406
28125
  "separator": "separator"
27407
28126
  };
27408
28127
 
27409
28128
  // src/components/Properties/controls/ColorPicker.tsx
27410
- import { jsx as jsx29, jsxs as jsxs20 } from "react/jsx-runtime";
28129
+ import { Fragment as Fragment3, jsx as jsx33, jsxs as jsxs23 } from "react/jsx-runtime";
27411
28130
  function ColorPicker({ label, value, onChange }) {
27412
- const [isOpen, setIsOpen] = useState16(false);
27413
- const wrapperRef = useRef17(null);
27414
- useEffect13(() => {
28131
+ const [isOpen, setIsOpen] = useState19(false);
28132
+ const wrapperRef = useRef19(null);
28133
+ const { customColorPresets, addCustomColorPreset, removeCustomColorPreset } = useColorPresets();
28134
+ useEffect14(() => {
27415
28135
  function handleClickOutside(e) {
27416
28136
  if (wrapperRef.current && !wrapperRef.current.contains(e.target)) {
27417
28137
  setIsOpen(false);
@@ -27422,36 +28142,48 @@ function ColorPicker({ label, value, onChange }) {
27422
28142
  return () => document.removeEventListener("mousedown", handleClickOutside);
27423
28143
  }
27424
28144
  }, [isOpen]);
27425
- const handlePresetClick = useCallback21(
28145
+ const handlePresetClick = useCallback23(
27426
28146
  (color) => {
27427
28147
  onChange(color);
27428
28148
  setIsOpen(false);
27429
28149
  },
27430
28150
  [onChange]
27431
28151
  );
28152
+ const handleSavePreset = useCallback23(() => {
28153
+ if (value && value !== "transparent" && !customColorPresets.includes(value)) {
28154
+ addCustomColorPreset(value);
28155
+ }
28156
+ }, [value, customColorPresets, addCustomColorPreset]);
28157
+ const handlePresetContextMenu = useCallback23(
28158
+ (e, color) => {
28159
+ e.preventDefault();
28160
+ removeCustomColorPreset(color);
28161
+ },
28162
+ [removeCustomColorPreset]
28163
+ );
27432
28164
  const isHex = /^#[0-9a-fA-F]{6}$/.test(value);
27433
- return /* @__PURE__ */ jsxs20("div", { className: `ee-field-group ee-color-picker ${properties_default.fieldGroup}`, children: [
27434
- /* @__PURE__ */ jsx29("label", { className: properties_default.fieldLabel, children: label }),
27435
- /* @__PURE__ */ jsxs20("div", { className: properties_default.colorPickerWrapper, ref: wrapperRef, children: [
27436
- /* @__PURE__ */ jsxs20(
28165
+ return /* @__PURE__ */ jsxs23("div", { className: `ee-field-group ee-color-picker ${properties_default.fieldGroup}`, children: [
28166
+ /* @__PURE__ */ jsx33("label", { className: properties_default.fieldLabel, children: label }),
28167
+ /* @__PURE__ */ jsxs23("div", { className: properties_default.colorPickerWrapper, ref: wrapperRef, children: [
28168
+ /* @__PURE__ */ jsxs23(
27437
28169
  "div",
27438
28170
  {
27439
28171
  className: properties_default.colorPickerTrigger,
27440
28172
  onClick: () => setIsOpen(!isOpen),
27441
28173
  children: [
27442
- /* @__PURE__ */ jsx29(
28174
+ /* @__PURE__ */ jsx33(
27443
28175
  "div",
27444
28176
  {
27445
28177
  className: `${properties_default.colorSwatch} ${value === "transparent" ? properties_default.colorSwatchTransparent : ""}`,
27446
28178
  style: value !== "transparent" ? { backgroundColor: value || "transparent" } : void 0
27447
28179
  }
27448
28180
  ),
27449
- /* @__PURE__ */ jsx29("span", { className: properties_default.colorValue, children: value || "transparent" })
28181
+ /* @__PURE__ */ jsx33("span", { className: properties_default.colorValue, children: value || "transparent" })
27450
28182
  ]
27451
28183
  }
27452
28184
  ),
27453
- isOpen && /* @__PURE__ */ jsxs20("div", { className: properties_default.colorPresets, children: [
27454
- /* @__PURE__ */ jsx29(
28185
+ isOpen && /* @__PURE__ */ jsxs23("div", { className: properties_default.colorPresets, children: [
28186
+ /* @__PURE__ */ jsx33(
27455
28187
  "button",
27456
28188
  {
27457
28189
  className: `ee-color-preset-transparent ${properties_default.colorPresetBtn} ${properties_default.colorPresetBtnTransparent} ${properties_default.colorPresetBtnFull} ${value === "transparent" ? properties_default.colorPresetBtnActive : ""}`,
@@ -27460,7 +28192,7 @@ function ColorPicker({ label, value, onChange }) {
27460
28192
  children: "Transparent"
27461
28193
  }
27462
28194
  ),
27463
- COLOR_PRESETS.map((color) => /* @__PURE__ */ jsx29(
28195
+ COLOR_PRESETS.map((color) => /* @__PURE__ */ jsx33(
27464
28196
  "button",
27465
28197
  {
27466
28198
  className: `${properties_default.colorPresetBtn} ${color === value ? properties_default.colorPresetBtnActive : ""}`,
@@ -27470,23 +28202,47 @@ function ColorPicker({ label, value, onChange }) {
27470
28202
  },
27471
28203
  color
27472
28204
  )),
27473
- /* @__PURE__ */ jsx29(
27474
- "input",
27475
- {
27476
- type: "color",
27477
- className: `ee-color-native-input ${properties_default.colorNativeInput}`,
27478
- value: isHex ? value : "#ffffff",
27479
- onChange: (e) => onChange(e.target.value)
27480
- }
27481
- )
28205
+ customColorPresets.length > 0 && /* @__PURE__ */ jsxs23(Fragment3, { children: [
28206
+ /* @__PURE__ */ jsx33("div", { className: `${properties_default.colorPresetBtnFull} ${properties_default.colorPresetSectionLabel}`, children: "Custom" }),
28207
+ customColorPresets.map((color) => /* @__PURE__ */ jsx33(
28208
+ "button",
28209
+ {
28210
+ className: `${properties_default.colorPresetBtn} ${color === value ? properties_default.colorPresetBtnActive : ""}`,
28211
+ style: { backgroundColor: color },
28212
+ onClick: () => handlePresetClick(color),
28213
+ onContextMenu: (e) => handlePresetContextMenu(e, color),
28214
+ title: `${color} (right-click to remove)`
28215
+ },
28216
+ `custom-${color}`
28217
+ ))
28218
+ ] }),
28219
+ /* @__PURE__ */ jsxs23("div", { className: `${properties_default.colorPresetBtnFull}`, style: { display: "flex", flexDirection: "column", gap: "8px", alignItems: "stretch" }, children: [
28220
+ /* @__PURE__ */ jsx33(
28221
+ HslColorArea,
28222
+ {
28223
+ value: isHex ? value : "#ffffff",
28224
+ onChange
28225
+ }
28226
+ ),
28227
+ /* @__PURE__ */ jsx33(
28228
+ "button",
28229
+ {
28230
+ className: `ee-color-save-preset ${properties_default.colorSavePresetBtn}`,
28231
+ onClick: handleSavePreset,
28232
+ title: "Save current color as preset",
28233
+ disabled: !value || value === "transparent" || customColorPresets.includes(value),
28234
+ children: "+ Save"
28235
+ }
28236
+ )
28237
+ ] })
27482
28238
  ] })
27483
28239
  ] })
27484
28240
  ] });
27485
28241
  }
27486
28242
 
27487
28243
  // src/components/Properties/controls/PaddingInput.tsx
27488
- import { useCallback as useCallback22, useMemo as useMemo14 } from "react";
27489
- import { jsx as jsx30, jsxs as jsxs21 } from "react/jsx-runtime";
28244
+ import { useCallback as useCallback24, useMemo as useMemo14 } from "react";
28245
+ import { jsx as jsx34, jsxs as jsxs24 } from "react/jsx-runtime";
27490
28246
  function parsePadding(value) {
27491
28247
  const parts = value.split(/\s+/).map((p) => p.trim()).filter(Boolean);
27492
28248
  switch (parts.length) {
@@ -27504,7 +28260,7 @@ function parsePadding(value) {
27504
28260
  }
27505
28261
  function PaddingInput({ label, value, onChange }) {
27506
28262
  const [top, right, bottom, left] = useMemo14(() => parsePadding(value), [value]);
27507
- const handleChange = useCallback22(
28263
+ const handleChange = useCallback24(
27508
28264
  (position, newVal) => {
27509
28265
  const parts = parsePadding(value);
27510
28266
  const idx = { top: 0, right: 1, bottom: 2, left: 3 }[position];
@@ -27513,12 +28269,12 @@ function PaddingInput({ label, value, onChange }) {
27513
28269
  },
27514
28270
  [value, onChange]
27515
28271
  );
27516
- return /* @__PURE__ */ jsxs21("div", { className: `ee-field-group ee-padding ${properties_default.fieldGroup}`, children: [
27517
- /* @__PURE__ */ jsx30("label", { className: properties_default.fieldLabel, children: label }),
27518
- /* @__PURE__ */ jsxs21("div", { className: properties_default.paddingGrid, children: [
27519
- /* @__PURE__ */ jsxs21("div", { className: properties_default.paddingField, children: [
27520
- /* @__PURE__ */ jsx30("span", { className: properties_default.paddingLabel, children: "Top" }),
27521
- /* @__PURE__ */ jsx30(
28272
+ return /* @__PURE__ */ jsxs24("div", { className: `ee-field-group ee-padding ${properties_default.fieldGroup}`, children: [
28273
+ /* @__PURE__ */ jsx34("label", { className: properties_default.fieldLabel, children: label }),
28274
+ /* @__PURE__ */ jsxs24("div", { className: properties_default.paddingGrid, children: [
28275
+ /* @__PURE__ */ jsxs24("div", { className: properties_default.paddingField, children: [
28276
+ /* @__PURE__ */ jsx34("span", { className: properties_default.paddingLabel, children: "Top" }),
28277
+ /* @__PURE__ */ jsx34(
27522
28278
  "input",
27523
28279
  {
27524
28280
  className: properties_default.paddingInput,
@@ -27527,9 +28283,9 @@ function PaddingInput({ label, value, onChange }) {
27527
28283
  }
27528
28284
  )
27529
28285
  ] }),
27530
- /* @__PURE__ */ jsxs21("div", { className: properties_default.paddingField, children: [
27531
- /* @__PURE__ */ jsx30("span", { className: properties_default.paddingLabel, children: "Right" }),
27532
- /* @__PURE__ */ jsx30(
28286
+ /* @__PURE__ */ jsxs24("div", { className: properties_default.paddingField, children: [
28287
+ /* @__PURE__ */ jsx34("span", { className: properties_default.paddingLabel, children: "Right" }),
28288
+ /* @__PURE__ */ jsx34(
27533
28289
  "input",
27534
28290
  {
27535
28291
  className: properties_default.paddingInput,
@@ -27538,9 +28294,9 @@ function PaddingInput({ label, value, onChange }) {
27538
28294
  }
27539
28295
  )
27540
28296
  ] }),
27541
- /* @__PURE__ */ jsxs21("div", { className: properties_default.paddingField, children: [
27542
- /* @__PURE__ */ jsx30("span", { className: properties_default.paddingLabel, children: "Bottom" }),
27543
- /* @__PURE__ */ jsx30(
28297
+ /* @__PURE__ */ jsxs24("div", { className: properties_default.paddingField, children: [
28298
+ /* @__PURE__ */ jsx34("span", { className: properties_default.paddingLabel, children: "Bottom" }),
28299
+ /* @__PURE__ */ jsx34(
27544
28300
  "input",
27545
28301
  {
27546
28302
  className: properties_default.paddingInput,
@@ -27549,9 +28305,9 @@ function PaddingInput({ label, value, onChange }) {
27549
28305
  }
27550
28306
  )
27551
28307
  ] }),
27552
- /* @__PURE__ */ jsxs21("div", { className: properties_default.paddingField, children: [
27553
- /* @__PURE__ */ jsx30("span", { className: properties_default.paddingLabel, children: "Left" }),
27554
- /* @__PURE__ */ jsx30(
28308
+ /* @__PURE__ */ jsxs24("div", { className: properties_default.paddingField, children: [
28309
+ /* @__PURE__ */ jsx34("span", { className: properties_default.paddingLabel, children: "Left" }),
28310
+ /* @__PURE__ */ jsx34(
27555
28311
  "input",
27556
28312
  {
27557
28313
  className: properties_default.paddingInput,
@@ -27565,16 +28321,16 @@ function PaddingInput({ label, value, onChange }) {
27565
28321
  }
27566
28322
 
27567
28323
  // src/components/Properties/controls/AlignmentPicker.tsx
27568
- import { jsx as jsx31, jsxs as jsxs22 } from "react/jsx-runtime";
28324
+ import { jsx as jsx35, jsxs as jsxs25 } from "react/jsx-runtime";
27569
28325
  function AlignmentPicker({
27570
28326
  label,
27571
28327
  value,
27572
28328
  onChange,
27573
28329
  options = ["left", "center", "right"]
27574
28330
  }) {
27575
- return /* @__PURE__ */ jsxs22("div", { className: `ee-field-group ee-alignment ${properties_default.fieldGroup}`, children: [
27576
- /* @__PURE__ */ jsx31("label", { className: properties_default.fieldLabel, children: label }),
27577
- /* @__PURE__ */ jsx31("div", { className: properties_default.alignmentPicker, children: options.map((option) => /* @__PURE__ */ jsx31(
28331
+ return /* @__PURE__ */ jsxs25("div", { className: `ee-field-group ee-alignment ${properties_default.fieldGroup}`, children: [
28332
+ /* @__PURE__ */ jsx35("label", { className: properties_default.fieldLabel, children: label }),
28333
+ /* @__PURE__ */ jsx35("div", { className: properties_default.alignmentPicker, children: options.map((option) => /* @__PURE__ */ jsx35(
27578
28334
  "button",
27579
28335
  {
27580
28336
  className: `${properties_default.alignmentBtn} ${value === option ? properties_default.alignmentBtnActive : ""}`,
@@ -27588,25 +28344,25 @@ function AlignmentPicker({
27588
28344
  }
27589
28345
 
27590
28346
  // src/components/Properties/controls/FontPicker.tsx
27591
- import { jsx as jsx32, jsxs as jsxs23 } from "react/jsx-runtime";
28347
+ import { jsx as jsx36, jsxs as jsxs26 } from "react/jsx-runtime";
27592
28348
  function FontPicker({ label, value, onChange }) {
27593
- return /* @__PURE__ */ jsxs23("div", { className: `ee-field-group ee-font-picker ${properties_default.fieldGroup}`, children: [
27594
- /* @__PURE__ */ jsx32("label", { className: properties_default.fieldLabel, children: label }),
27595
- /* @__PURE__ */ jsx32(
28349
+ return /* @__PURE__ */ jsxs26("div", { className: `ee-field-group ee-font-picker ${properties_default.fieldGroup}`, children: [
28350
+ /* @__PURE__ */ jsx36("label", { className: properties_default.fieldLabel, children: label }),
28351
+ /* @__PURE__ */ jsx36(
27596
28352
  "select",
27597
28353
  {
27598
28354
  className: properties_default.fieldSelect,
27599
28355
  value,
27600
28356
  onChange: (e) => onChange(e.target.value),
27601
- children: FONT_OPTIONS.map((font) => /* @__PURE__ */ jsx32("option", { value: font, style: { fontFamily: font }, children: font.split(",")[0].trim() }, font))
28357
+ children: FONT_OPTIONS.map((font) => /* @__PURE__ */ jsx36("option", { value: font, style: { fontFamily: font }, children: font.split(",")[0].trim() }, font))
27602
28358
  }
27603
28359
  )
27604
28360
  ] });
27605
28361
  }
27606
28362
 
27607
28363
  // src/components/Properties/controls/SliderInput.tsx
27608
- import { useCallback as useCallback23 } from "react";
27609
- import { jsx as jsx33, jsxs as jsxs24 } from "react/jsx-runtime";
28364
+ import { useCallback as useCallback25 } from "react";
28365
+ import { jsx as jsx37, jsxs as jsxs27 } from "react/jsx-runtime";
27610
28366
  function SliderInput({
27611
28367
  label,
27612
28368
  value,
@@ -27616,16 +28372,16 @@ function SliderInput({
27616
28372
  unit = "px",
27617
28373
  onChange
27618
28374
  }) {
27619
- const handleChange = useCallback23(
28375
+ const handleChange = useCallback25(
27620
28376
  (e) => {
27621
28377
  onChange(Number(e.target.value));
27622
28378
  },
27623
28379
  [onChange]
27624
28380
  );
27625
- return /* @__PURE__ */ jsxs24("div", { className: `ee-field-group ee-slider ${properties_default.fieldGroup}`, children: [
27626
- /* @__PURE__ */ jsx33("label", { className: properties_default.fieldLabel, children: label }),
27627
- /* @__PURE__ */ jsxs24("div", { className: properties_default.sliderWrapper, children: [
27628
- /* @__PURE__ */ jsx33(
28381
+ return /* @__PURE__ */ jsxs27("div", { className: `ee-field-group ee-slider ${properties_default.fieldGroup}`, children: [
28382
+ /* @__PURE__ */ jsx37("label", { className: properties_default.fieldLabel, children: label }),
28383
+ /* @__PURE__ */ jsxs27("div", { className: properties_default.sliderWrapper, children: [
28384
+ /* @__PURE__ */ jsx37(
27629
28385
  "input",
27630
28386
  {
27631
28387
  type: "range",
@@ -27637,7 +28393,7 @@ function SliderInput({
27637
28393
  onChange: handleChange
27638
28394
  }
27639
28395
  ),
27640
- /* @__PURE__ */ jsxs24("span", { className: properties_default.sliderValue, children: [
28396
+ /* @__PURE__ */ jsxs27("span", { className: properties_default.sliderValue, children: [
27641
28397
  value,
27642
28398
  unit
27643
28399
  ] })
@@ -27646,8 +28402,8 @@ function SliderInput({
27646
28402
  }
27647
28403
 
27648
28404
  // src/components/Properties/controls/LinkInput.tsx
27649
- import { useState as useState17, useCallback as useCallback24, useEffect as useEffect14, useMemo as useMemo15 } from "react";
27650
- import { jsx as jsx34, jsxs as jsxs25 } from "react/jsx-runtime";
28405
+ import { useState as useState20, useCallback as useCallback26, useEffect as useEffect15, useMemo as useMemo15 } from "react";
28406
+ import { jsx as jsx38, jsxs as jsxs28 } from "react/jsx-runtime";
27651
28407
  function validateLink(value, type) {
27652
28408
  if (!value) return null;
27653
28409
  if (type === "email" && !/^[^\s@]+@[^\s@]+\.[^\s@]+$/.test(value)) {
@@ -27677,22 +28433,22 @@ function addPrefix(value, type) {
27677
28433
  return value;
27678
28434
  }
27679
28435
  function LinkInput({ label, value, onChange }) {
27680
- const [type, setType] = useState17(() => detectType(value));
27681
- const [rawValue, setRawValue] = useState17(() => stripPrefix(value, detectType(value)));
28436
+ const [type, setType] = useState20(() => detectType(value));
28437
+ const [rawValue, setRawValue] = useState20(() => stripPrefix(value, detectType(value)));
27682
28438
  const validationError = useMemo15(() => validateLink(rawValue, type), [rawValue, type]);
27683
- useEffect14(() => {
28439
+ useEffect15(() => {
27684
28440
  const detected = detectType(value);
27685
28441
  setType(detected);
27686
28442
  setRawValue(stripPrefix(value, detected));
27687
28443
  }, [value]);
27688
- const handleTypeChange = useCallback24(
28444
+ const handleTypeChange = useCallback26(
27689
28445
  (newType) => {
27690
28446
  setType(newType);
27691
28447
  onChange(addPrefix(rawValue, newType));
27692
28448
  },
27693
28449
  [rawValue, onChange]
27694
28450
  );
27695
- const handleValueChange = useCallback24(
28451
+ const handleValueChange = useCallback26(
27696
28452
  (newValue) => {
27697
28453
  setRawValue(newValue);
27698
28454
  onChange(addPrefix(newValue, type));
@@ -27700,23 +28456,23 @@ function LinkInput({ label, value, onChange }) {
27700
28456
  [type, onChange]
27701
28457
  );
27702
28458
  const placeholder = type === "email" ? "user@example.com" : type === "phone" ? "+1234567890" : "https://";
27703
- return /* @__PURE__ */ jsxs25("div", { className: `ee-field-group ee-link-input ${properties_default.fieldGroup}`, children: [
27704
- /* @__PURE__ */ jsx34("label", { className: properties_default.fieldLabel, children: label }),
27705
- /* @__PURE__ */ jsxs25("div", { className: properties_default.fieldRowCompact, children: [
27706
- /* @__PURE__ */ jsxs25(
28459
+ return /* @__PURE__ */ jsxs28("div", { className: `ee-field-group ee-link-input ${properties_default.fieldGroup}`, children: [
28460
+ /* @__PURE__ */ jsx38("label", { className: properties_default.fieldLabel, children: label }),
28461
+ /* @__PURE__ */ jsxs28("div", { className: properties_default.fieldRowCompact, children: [
28462
+ /* @__PURE__ */ jsxs28(
27707
28463
  "select",
27708
28464
  {
27709
28465
  className: properties_default.fieldSelectNarrow,
27710
28466
  value: type,
27711
28467
  onChange: (e) => handleTypeChange(e.target.value),
27712
28468
  children: [
27713
- /* @__PURE__ */ jsx34("option", { value: "url", children: "URL" }),
27714
- /* @__PURE__ */ jsx34("option", { value: "email", children: "Email" }),
27715
- /* @__PURE__ */ jsx34("option", { value: "phone", children: "Phone" })
28469
+ /* @__PURE__ */ jsx38("option", { value: "url", children: "URL" }),
28470
+ /* @__PURE__ */ jsx38("option", { value: "email", children: "Email" }),
28471
+ /* @__PURE__ */ jsx38("option", { value: "phone", children: "Phone" })
27716
28472
  ]
27717
28473
  }
27718
28474
  ),
27719
- /* @__PURE__ */ jsx34(
28475
+ /* @__PURE__ */ jsx38(
27720
28476
  "input",
27721
28477
  {
27722
28478
  className: properties_default.fieldInputFlex,
@@ -27728,26 +28484,26 @@ function LinkInput({ label, value, onChange }) {
27728
28484
  }
27729
28485
  )
27730
28486
  ] }),
27731
- validationError && /* @__PURE__ */ jsx34("span", { className: `ee-validation-error ${properties_default.validationError}`, role: "alert", children: validationError })
28487
+ validationError && /* @__PURE__ */ jsx38("span", { className: `ee-validation-error ${properties_default.validationError}`, role: "alert", children: validationError })
27732
28488
  ] });
27733
28489
  }
27734
28490
 
27735
28491
  // src/components/Properties/PropertyField.tsx
27736
- import { jsx as jsx35, jsxs as jsxs26 } from "react/jsx-runtime";
27737
- var PropertyField = React33.memo(function PropertyField2(props) {
28492
+ import { jsx as jsx39, jsxs as jsxs29 } from "react/jsx-runtime";
28493
+ var PropertyField = React35.memo(function PropertyField2(props) {
27738
28494
  switch (props.type) {
27739
28495
  case "color":
27740
- return /* @__PURE__ */ jsx35(ColorPicker, { label: props.label, value: props.value, onChange: props.onChange });
28496
+ return /* @__PURE__ */ jsx39(ColorPicker, { label: props.label, value: props.value, onChange: props.onChange });
27741
28497
  case "padding":
27742
- return /* @__PURE__ */ jsx35(PaddingInput, { label: props.label, value: props.value, onChange: props.onChange });
28498
+ return /* @__PURE__ */ jsx39(PaddingInput, { label: props.label, value: props.value, onChange: props.onChange });
27743
28499
  case "alignment":
27744
- return /* @__PURE__ */ jsx35(AlignmentPicker, { label: props.label, value: props.value, onChange: props.onChange, options: props.options });
28500
+ return /* @__PURE__ */ jsx39(AlignmentPicker, { label: props.label, value: props.value, onChange: props.onChange, options: props.options });
27745
28501
  case "font":
27746
- return /* @__PURE__ */ jsx35(FontPicker, { label: props.label, value: props.value, onChange: props.onChange });
28502
+ return /* @__PURE__ */ jsx39(FontPicker, { label: props.label, value: props.value, onChange: props.onChange });
27747
28503
  case "link":
27748
- return /* @__PURE__ */ jsx35(LinkInput, { label: props.label, value: props.value, onChange: props.onChange });
28504
+ return /* @__PURE__ */ jsx39(LinkInput, { label: props.label, value: props.value, onChange: props.onChange });
27749
28505
  case "slider":
27750
- return /* @__PURE__ */ jsx35(
28506
+ return /* @__PURE__ */ jsx39(
27751
28507
  SliderInput,
27752
28508
  {
27753
28509
  label: props.label,
@@ -27760,8 +28516,8 @@ var PropertyField = React33.memo(function PropertyField2(props) {
27760
28516
  }
27761
28517
  );
27762
28518
  case "toggle":
27763
- return /* @__PURE__ */ jsx35("div", { className: properties_default.fieldGroup, children: /* @__PURE__ */ jsxs26("label", { className: `ee-checkbox-label ${properties_default.checkboxLabel}`, children: [
27764
- /* @__PURE__ */ jsx35(
28519
+ return /* @__PURE__ */ jsx39("div", { className: properties_default.fieldGroup, children: /* @__PURE__ */ jsxs29("label", { className: `ee-checkbox-label ${properties_default.checkboxLabel}`, children: [
28520
+ /* @__PURE__ */ jsx39(
27765
28521
  "input",
27766
28522
  {
27767
28523
  type: "checkbox",
@@ -27772,22 +28528,22 @@ var PropertyField = React33.memo(function PropertyField2(props) {
27772
28528
  props.label
27773
28529
  ] }) });
27774
28530
  case "select":
27775
- return /* @__PURE__ */ jsxs26("div", { className: properties_default.fieldGroup, children: [
27776
- /* @__PURE__ */ jsx35("label", { className: properties_default.fieldLabel, children: props.label }),
27777
- /* @__PURE__ */ jsx35(
28531
+ return /* @__PURE__ */ jsxs29("div", { className: properties_default.fieldGroup, children: [
28532
+ /* @__PURE__ */ jsx39("label", { className: properties_default.fieldLabel, children: props.label }),
28533
+ /* @__PURE__ */ jsx39(
27778
28534
  "select",
27779
28535
  {
27780
28536
  className: properties_default.fieldSelect,
27781
28537
  value: props.value,
27782
28538
  onChange: (e) => props.onChange(e.target.value),
27783
- children: props.options.map((opt) => /* @__PURE__ */ jsx35("option", { value: opt.value, children: opt.label }, opt.value))
28539
+ children: props.options.map((opt) => /* @__PURE__ */ jsx39("option", { value: opt.value, children: opt.label }, opt.value))
27784
28540
  }
27785
28541
  )
27786
28542
  ] });
27787
28543
  case "textarea":
27788
- return /* @__PURE__ */ jsxs26("div", { className: properties_default.fieldGroup, children: [
27789
- /* @__PURE__ */ jsx35("label", { className: properties_default.fieldLabel, children: props.label }),
27790
- /* @__PURE__ */ jsx35(
28544
+ return /* @__PURE__ */ jsxs29("div", { className: properties_default.fieldGroup, children: [
28545
+ /* @__PURE__ */ jsx39("label", { className: properties_default.fieldLabel, children: props.label }),
28546
+ /* @__PURE__ */ jsx39(
27791
28547
  "textarea",
27792
28548
  {
27793
28549
  className: props.code ? `ee-code-textarea ${properties_default.fieldTextareaCode}` : properties_default.fieldTextarea,
@@ -27800,9 +28556,9 @@ var PropertyField = React33.memo(function PropertyField2(props) {
27800
28556
  ] });
27801
28557
  case "text":
27802
28558
  default:
27803
- return /* @__PURE__ */ jsxs26("div", { className: properties_default.fieldGroup, children: [
27804
- /* @__PURE__ */ jsx35("label", { className: properties_default.fieldLabel, children: props.label }),
27805
- /* @__PURE__ */ jsx35(
28559
+ return /* @__PURE__ */ jsxs29("div", { className: properties_default.fieldGroup, children: [
28560
+ /* @__PURE__ */ jsx39("label", { className: properties_default.fieldLabel, children: props.label }),
28561
+ /* @__PURE__ */ jsx39(
27806
28562
  "input",
27807
28563
  {
27808
28564
  className: properties_default.fieldInput,
@@ -27815,11 +28571,11 @@ var PropertyField = React33.memo(function PropertyField2(props) {
27815
28571
  }
27816
28572
  });
27817
28573
  function FieldSeparator() {
27818
- return /* @__PURE__ */ jsx35("div", { className: properties_default.separator });
28574
+ return /* @__PURE__ */ jsx39("div", { className: properties_default.separator });
27819
28575
  }
27820
28576
 
27821
28577
  // src/components/Properties/SectionProperties.tsx
27822
- import { jsx as jsx36, jsxs as jsxs27 } from "react/jsx-runtime";
28578
+ import { jsx as jsx40, jsxs as jsxs30 } from "react/jsx-runtime";
27823
28579
  var BG_SIZE_OPTIONS = [
27824
28580
  { value: "cover", label: "Cover" },
27825
28581
  { value: "contain", label: "Contain" },
@@ -27834,41 +28590,41 @@ var BG_REPEAT_OPTIONS = [
27834
28590
  function SectionProperties({ section }) {
27835
28591
  const dispatch = useEditorDispatch();
27836
28592
  const { properties } = section;
27837
- const update = useCallback25(
28593
+ const update = useCallback27(
27838
28594
  (props) => {
27839
28595
  dispatch({ type: "UPDATE_SECTION", payload: { sectionId: section.id, properties: props } });
27840
28596
  },
27841
28597
  [dispatch, section.id]
27842
28598
  );
27843
- return /* @__PURE__ */ jsxs27("div", { className: properties_default.propertiesBody, children: [
27844
- /* @__PURE__ */ jsx36(PropertyField, { type: "color", label: "Background Color", value: properties.backgroundColor, onChange: (v) => update({ backgroundColor: v }) }),
27845
- /* @__PURE__ */ jsx36(PropertyField, { type: "padding", label: "Padding", value: properties.padding, onChange: (v) => update({ padding: v }) }),
27846
- /* @__PURE__ */ jsx36(PropertyField, { type: "text", label: "Border Radius", value: properties.borderRadius, onChange: (v) => update({ borderRadius: v }) }),
27847
- /* @__PURE__ */ jsx36(PropertyField, { type: "toggle", label: "Full Width", value: properties.fullWidth || false, onChange: (v) => update({ fullWidth: v }) }),
27848
- /* @__PURE__ */ jsx36(FieldSeparator, {}),
27849
- /* @__PURE__ */ jsx36(PropertyField, { type: "text", label: "Background Image URL", value: properties.backgroundImage || "", onChange: (v) => update({ backgroundImage: v }), placeholder: "https://..." }),
27850
- /* @__PURE__ */ jsx36(PropertyField, { type: "select", label: "Background Size", value: properties.backgroundSize || "cover", onChange: (v) => update({ backgroundSize: v }), options: BG_SIZE_OPTIONS }),
27851
- /* @__PURE__ */ jsx36(PropertyField, { type: "select", label: "Background Repeat", value: properties.backgroundRepeat || "no-repeat", onChange: (v) => update({ backgroundRepeat: v }), options: BG_REPEAT_OPTIONS })
28599
+ return /* @__PURE__ */ jsxs30("div", { className: properties_default.propertiesBody, children: [
28600
+ /* @__PURE__ */ jsx40(PropertyField, { type: "color", label: "Background Color", value: properties.backgroundColor, onChange: (v) => update({ backgroundColor: v }) }),
28601
+ /* @__PURE__ */ jsx40(PropertyField, { type: "padding", label: "Padding", value: properties.padding, onChange: (v) => update({ padding: v }) }),
28602
+ /* @__PURE__ */ jsx40(PropertyField, { type: "text", label: "Border Radius", value: properties.borderRadius, onChange: (v) => update({ borderRadius: v }) }),
28603
+ /* @__PURE__ */ jsx40(PropertyField, { type: "toggle", label: "Full Width", value: properties.fullWidth || false, onChange: (v) => update({ fullWidth: v }) }),
28604
+ /* @__PURE__ */ jsx40(FieldSeparator, {}),
28605
+ /* @__PURE__ */ jsx40(PropertyField, { type: "text", label: "Background Image URL", value: properties.backgroundImage || "", onChange: (v) => update({ backgroundImage: v }), placeholder: "https://..." }),
28606
+ /* @__PURE__ */ jsx40(PropertyField, { type: "select", label: "Background Size", value: properties.backgroundSize || "cover", onChange: (v) => update({ backgroundSize: v }), options: BG_SIZE_OPTIONS }),
28607
+ /* @__PURE__ */ jsx40(PropertyField, { type: "select", label: "Background Repeat", value: properties.backgroundRepeat || "no-repeat", onChange: (v) => update({ backgroundRepeat: v }), options: BG_REPEAT_OPTIONS })
27852
28608
  ] });
27853
28609
  }
27854
28610
 
27855
28611
  // src/components/Properties/HeadMetadataProperties.tsx
27856
- import { useCallback as useCallback26 } from "react";
27857
- import { jsx as jsx37, jsxs as jsxs28 } from "react/jsx-runtime";
28612
+ import { useCallback as useCallback28 } from "react";
28613
+ import { jsx as jsx41, jsxs as jsxs31 } from "react/jsx-runtime";
27858
28614
  function HeadMetadataProperties() {
27859
28615
  const { template } = useTemplateContext();
27860
28616
  const dispatch = useEditorDispatch();
27861
28617
  const metadata = template.headMetadata ?? { title: "", previewText: "", headStyles: [] };
27862
- const update = useCallback26(
28618
+ const update = useCallback28(
27863
28619
  (props) => {
27864
28620
  dispatch({ type: "UPDATE_HEAD_METADATA", payload: props });
27865
28621
  },
27866
28622
  [dispatch]
27867
28623
  );
27868
- return /* @__PURE__ */ jsxs28("div", { className: properties_default.propertiesBody, children: [
27869
- /* @__PURE__ */ jsx37(PropertyField, { type: "text", label: "Email Title", value: metadata.title, onChange: (v) => update({ title: v }), placeholder: "Email title (mj-title)" }),
27870
- /* @__PURE__ */ jsx37(PropertyField, { type: "text", label: "Preview Text", value: metadata.previewText, onChange: (v) => update({ previewText: v }), placeholder: "Preview text shown in inbox (mj-preview)" }),
27871
- /* @__PURE__ */ jsx37(
28624
+ return /* @__PURE__ */ jsxs31("div", { className: properties_default.propertiesBody, children: [
28625
+ /* @__PURE__ */ jsx41(PropertyField, { type: "text", label: "Email Title", value: metadata.title, onChange: (v) => update({ title: v }), placeholder: "Email title (mj-title)" }),
28626
+ /* @__PURE__ */ jsx41(PropertyField, { type: "text", label: "Preview Text", value: metadata.previewText, onChange: (v) => update({ previewText: v }), placeholder: "Preview text shown in inbox (mj-preview)" }),
28627
+ /* @__PURE__ */ jsx41(
27872
28628
  PropertyField,
27873
28629
  {
27874
28630
  type: "textarea",
@@ -27887,10 +28643,10 @@ function HeadMetadataProperties() {
27887
28643
  }
27888
28644
 
27889
28645
  // src/hooks/useBlockUpdate.ts
27890
- import { useCallback as useCallback27 } from "react";
28646
+ import { useCallback as useCallback29 } from "react";
27891
28647
  function useBlockUpdate(blockId) {
27892
28648
  const dispatch = useEditorDispatch();
27893
- const update = useCallback27(
28649
+ const update = useCallback29(
27894
28650
  (properties) => {
27895
28651
  dispatch({
27896
28652
  type: "UPDATE_BLOCK",
@@ -27903,19 +28659,20 @@ function useBlockUpdate(blockId) {
27903
28659
  }
27904
28660
 
27905
28661
  // src/components/Properties/TextProperties.tsx
27906
- import { jsx as jsx38, jsxs as jsxs29 } from "react/jsx-runtime";
28662
+ import { jsx as jsx42, jsxs as jsxs32 } from "react/jsx-runtime";
27907
28663
  function TextProperties({ block }) {
27908
28664
  const update = useBlockUpdate(block.id);
27909
28665
  const p = block.properties;
27910
- return /* @__PURE__ */ jsxs29("div", { className: properties_default.propertiesBody, children: [
27911
- /* @__PURE__ */ jsx38("p", { className: properties_default.fieldHint, children: "Use the inline toolbar above the text block to format font, size, color, and alignment." }),
27912
- /* @__PURE__ */ jsx38(PropertyField, { type: "text", label: "Line Height", value: p.lineHeight, onChange: (v) => update({ lineHeight: v }) }),
27913
- /* @__PURE__ */ jsx38(PropertyField, { type: "padding", label: "Padding", value: p.padding, onChange: (v) => update({ padding: v }) })
28666
+ return /* @__PURE__ */ jsxs32("div", { className: properties_default.propertiesBody, children: [
28667
+ /* @__PURE__ */ jsx42("p", { className: properties_default.fieldHint, children: "Use the inline toolbar above the text block to format font, size, color, and alignment." }),
28668
+ /* @__PURE__ */ jsx42(PropertyField, { type: "color", label: "Background Color", value: p.backgroundColor || "transparent", onChange: (v) => update({ backgroundColor: v }) }),
28669
+ /* @__PURE__ */ jsx42(PropertyField, { type: "text", label: "Line Height", value: p.lineHeight, onChange: (v) => update({ lineHeight: v }) }),
28670
+ /* @__PURE__ */ jsx42(PropertyField, { type: "padding", label: "Padding", value: p.padding, onChange: (v) => update({ padding: v }) })
27914
28671
  ] });
27915
28672
  }
27916
28673
 
27917
28674
  // src/components/Properties/ButtonProperties.tsx
27918
- import { jsx as jsx39, jsxs as jsxs30 } from "react/jsx-runtime";
28675
+ import { jsx as jsx43, jsxs as jsxs33 } from "react/jsx-runtime";
27919
28676
  var FONT_WEIGHT_OPTIONS = [
27920
28677
  { value: "normal", label: "Normal" },
27921
28678
  { value: "bold", label: "Bold" },
@@ -27938,32 +28695,32 @@ var TEXT_TRANSFORM_OPTIONS = [
27938
28695
  function ButtonProperties({ block }) {
27939
28696
  const update = useBlockUpdate(block.id);
27940
28697
  const p = block.properties;
27941
- return /* @__PURE__ */ jsxs30("div", { className: properties_default.propertiesBody, children: [
27942
- /* @__PURE__ */ jsx39(PropertyField, { type: "text", label: "Button Text", value: p.text, onChange: (v) => update({ text: v }) }),
27943
- /* @__PURE__ */ jsx39(PropertyField, { type: "link", label: "Link URL", value: p.href, onChange: (v) => update({ href: v }) }),
27944
- /* @__PURE__ */ jsx39(FieldSeparator, {}),
27945
- /* @__PURE__ */ jsx39(PropertyField, { type: "color", label: "Background Color", value: p.backgroundColor, onChange: (v) => update({ backgroundColor: v }) }),
27946
- /* @__PURE__ */ jsx39(PropertyField, { type: "color", label: "Text Color", value: p.color, onChange: (v) => update({ color: v }) }),
27947
- /* @__PURE__ */ jsx39(PropertyField, { type: "font", label: "Font Family", value: p.fontFamily, onChange: (v) => update({ fontFamily: v }) }),
27948
- /* @__PURE__ */ jsx39(PropertyField, { type: "text", label: "Font Size", value: p.fontSize, onChange: (v) => update({ fontSize: v }) }),
27949
- /* @__PURE__ */ jsx39(PropertyField, { type: "text", label: "Border Radius", value: p.borderRadius, onChange: (v) => update({ borderRadius: v }) }),
27950
- /* @__PURE__ */ jsx39(PropertyField, { type: "text", label: "Width", value: p.width, onChange: (v) => update({ width: v }), placeholder: "auto" }),
27951
- /* @__PURE__ */ jsx39(PropertyField, { type: "select", label: "Font Weight", value: p.fontWeight || "normal", onChange: (v) => update({ fontWeight: v }), options: FONT_WEIGHT_OPTIONS }),
27952
- /* @__PURE__ */ jsx39(PropertyField, { type: "select", label: "Text Transform", value: p.textTransform || "none", onChange: (v) => update({ textTransform: v }), options: TEXT_TRANSFORM_OPTIONS }),
27953
- /* @__PURE__ */ jsx39(PropertyField, { type: "text", label: "Letter Spacing", value: p.letterSpacing || "normal", onChange: (v) => update({ letterSpacing: v }), placeholder: "normal" }),
27954
- /* @__PURE__ */ jsx39(PropertyField, { type: "alignment", label: "Alignment", value: p.align, onChange: (v) => update({ align: v }) }),
27955
- /* @__PURE__ */ jsx39(PropertyField, { type: "padding", label: "Outer Padding", value: p.padding, onChange: (v) => update({ padding: v }) }),
27956
- /* @__PURE__ */ jsx39(PropertyField, { type: "padding", label: "Inner Padding", value: p.innerPadding, onChange: (v) => update({ innerPadding: v }) })
28698
+ return /* @__PURE__ */ jsxs33("div", { className: properties_default.propertiesBody, children: [
28699
+ /* @__PURE__ */ jsx43(PropertyField, { type: "text", label: "Button Text", value: p.text, onChange: (v) => update({ text: v }) }),
28700
+ /* @__PURE__ */ jsx43(PropertyField, { type: "link", label: "Link URL", value: p.href, onChange: (v) => update({ href: v }) }),
28701
+ /* @__PURE__ */ jsx43(FieldSeparator, {}),
28702
+ /* @__PURE__ */ jsx43(PropertyField, { type: "color", label: "Background Color", value: p.backgroundColor, onChange: (v) => update({ backgroundColor: v }) }),
28703
+ /* @__PURE__ */ jsx43(PropertyField, { type: "color", label: "Text Color", value: p.color, onChange: (v) => update({ color: v }) }),
28704
+ /* @__PURE__ */ jsx43(PropertyField, { type: "font", label: "Font Family", value: p.fontFamily, onChange: (v) => update({ fontFamily: v }) }),
28705
+ /* @__PURE__ */ jsx43(PropertyField, { type: "text", label: "Font Size", value: p.fontSize, onChange: (v) => update({ fontSize: v }) }),
28706
+ /* @__PURE__ */ jsx43(PropertyField, { type: "text", label: "Border Radius", value: p.borderRadius, onChange: (v) => update({ borderRadius: v }) }),
28707
+ /* @__PURE__ */ jsx43(PropertyField, { type: "text", label: "Width", value: p.width, onChange: (v) => update({ width: v }), placeholder: "auto" }),
28708
+ /* @__PURE__ */ jsx43(PropertyField, { type: "select", label: "Font Weight", value: p.fontWeight || "normal", onChange: (v) => update({ fontWeight: v }), options: FONT_WEIGHT_OPTIONS }),
28709
+ /* @__PURE__ */ jsx43(PropertyField, { type: "select", label: "Text Transform", value: p.textTransform || "none", onChange: (v) => update({ textTransform: v }), options: TEXT_TRANSFORM_OPTIONS }),
28710
+ /* @__PURE__ */ jsx43(PropertyField, { type: "text", label: "Letter Spacing", value: p.letterSpacing || "normal", onChange: (v) => update({ letterSpacing: v }), placeholder: "normal" }),
28711
+ /* @__PURE__ */ jsx43(PropertyField, { type: "alignment", label: "Alignment", value: p.align, onChange: (v) => update({ align: v }) }),
28712
+ /* @__PURE__ */ jsx43(PropertyField, { type: "padding", label: "Outer Padding", value: p.padding, onChange: (v) => update({ padding: v }) }),
28713
+ /* @__PURE__ */ jsx43(PropertyField, { type: "padding", label: "Inner Padding", value: p.innerPadding, onChange: (v) => update({ innerPadding: v }) })
27957
28714
  ] });
27958
28715
  }
27959
28716
 
27960
28717
  // src/components/Properties/ImageProperties.tsx
27961
- import { useCallback as useCallback28, useRef as useRef18 } from "react";
27962
- import { jsx as jsx40, jsxs as jsxs31 } from "react/jsx-runtime";
28718
+ import { useCallback as useCallback30, useRef as useRef20 } from "react";
28719
+ import { jsx as jsx44, jsxs as jsxs34 } from "react/jsx-runtime";
27963
28720
  function ImageProperties({ block }) {
27964
28721
  const update = useBlockUpdate(block.id);
27965
28722
  const { imageUploadAdapter } = useImageAdapter();
27966
- const fileInputRef = useRef18(null);
28723
+ const fileInputRef = useRef20(null);
27967
28724
  const p = block.properties;
27968
28725
  const { upload, status, error } = useImageUpload({
27969
28726
  adapter: imageUploadAdapter,
@@ -27976,7 +28733,7 @@ function ImageProperties({ block }) {
27976
28733
  });
27977
28734
  }
27978
28735
  });
27979
- const handleFileSelect = useCallback28(
28736
+ const handleFileSelect = useCallback30(
27980
28737
  async (e) => {
27981
28738
  const file = e.target.files?.[0];
27982
28739
  if (!file) return;
@@ -27984,10 +28741,10 @@ function ImageProperties({ block }) {
27984
28741
  },
27985
28742
  [upload]
27986
28743
  );
27987
- return /* @__PURE__ */ jsxs31("div", { className: properties_default.propertiesBody, children: [
27988
- /* @__PURE__ */ jsx40(PropertyField, { type: "text", label: "Image URL", value: p.src, onChange: (v) => update({ src: v }), placeholder: "https://..." }),
27989
- imageUploadAdapter && /* @__PURE__ */ jsxs31("div", { className: properties_default.fieldGroup, children: [
27990
- /* @__PURE__ */ jsx40(
28744
+ return /* @__PURE__ */ jsxs34("div", { className: properties_default.propertiesBody, children: [
28745
+ /* @__PURE__ */ jsx44(PropertyField, { type: "text", label: "Image URL", value: p.src, onChange: (v) => update({ src: v }), placeholder: "https://..." }),
28746
+ imageUploadAdapter && /* @__PURE__ */ jsxs34("div", { className: properties_default.fieldGroup, children: [
28747
+ /* @__PURE__ */ jsx44(
27991
28748
  "button",
27992
28749
  {
27993
28750
  className: `ee-upload-btn ${status === "uploading" ? properties_default.fieldBtnUploadDisabled : properties_default.fieldBtnUpload}`,
@@ -27996,8 +28753,8 @@ function ImageProperties({ block }) {
27996
28753
  children: status === "uploading" ? "Uploading..." : "Upload Image"
27997
28754
  }
27998
28755
  ),
27999
- error && /* @__PURE__ */ jsx40("span", { className: `ee-upload-error ${properties_default.validationError}`, children: error }),
28000
- /* @__PURE__ */ jsx40(
28756
+ error && /* @__PURE__ */ jsx44("span", { className: `ee-upload-error ${properties_default.validationError}`, children: error }),
28757
+ /* @__PURE__ */ jsx44(
28001
28758
  "input",
28002
28759
  {
28003
28760
  ref: fileInputRef,
@@ -28008,21 +28765,21 @@ function ImageProperties({ block }) {
28008
28765
  }
28009
28766
  )
28010
28767
  ] }),
28011
- /* @__PURE__ */ jsx40(PropertyField, { type: "text", label: "Alt Text", value: p.alt, onChange: (v) => update({ alt: v }), placeholder: "Image description" }),
28012
- /* @__PURE__ */ jsx40(PropertyField, { type: "link", label: "Link URL", value: p.href, onChange: (v) => update({ href: v }) }),
28013
- /* @__PURE__ */ jsx40(FieldSeparator, {}),
28014
- /* @__PURE__ */ jsxs31("div", { className: properties_default.fieldRow, children: [
28015
- /* @__PURE__ */ jsx40("div", { className: properties_default.fieldHalf, children: /* @__PURE__ */ jsx40(PropertyField, { type: "text", label: "Width", value: p.width, onChange: (v) => update({ width: v }) }) }),
28016
- /* @__PURE__ */ jsx40("div", { className: properties_default.fieldHalf, children: /* @__PURE__ */ jsx40(PropertyField, { type: "text", label: "Height", value: p.height, onChange: (v) => update({ height: v }) }) })
28768
+ /* @__PURE__ */ jsx44(PropertyField, { type: "text", label: "Alt Text", value: p.alt, onChange: (v) => update({ alt: v }), placeholder: "Image description" }),
28769
+ /* @__PURE__ */ jsx44(PropertyField, { type: "link", label: "Link URL", value: p.href, onChange: (v) => update({ href: v }) }),
28770
+ /* @__PURE__ */ jsx44(FieldSeparator, {}),
28771
+ /* @__PURE__ */ jsxs34("div", { className: properties_default.fieldRow, children: [
28772
+ /* @__PURE__ */ jsx44("div", { className: properties_default.fieldHalf, children: /* @__PURE__ */ jsx44(PropertyField, { type: "text", label: "Width", value: p.width, onChange: (v) => update({ width: v }) }) }),
28773
+ /* @__PURE__ */ jsx44("div", { className: properties_default.fieldHalf, children: /* @__PURE__ */ jsx44(PropertyField, { type: "text", label: "Height", value: p.height, onChange: (v) => update({ height: v }) }) })
28017
28774
  ] }),
28018
- /* @__PURE__ */ jsx40(PropertyField, { type: "alignment", label: "Alignment", value: p.align, onChange: (v) => update({ align: v }) }),
28019
- /* @__PURE__ */ jsx40(PropertyField, { type: "padding", label: "Padding", value: p.padding, onChange: (v) => update({ padding: v }) }),
28020
- /* @__PURE__ */ jsx40(PropertyField, { type: "toggle", label: "Fluid on Mobile", value: p.fluidOnMobile, onChange: (v) => update({ fluidOnMobile: v }) })
28775
+ /* @__PURE__ */ jsx44(PropertyField, { type: "alignment", label: "Alignment", value: p.align, onChange: (v) => update({ align: v }) }),
28776
+ /* @__PURE__ */ jsx44(PropertyField, { type: "padding", label: "Padding", value: p.padding, onChange: (v) => update({ padding: v }) }),
28777
+ /* @__PURE__ */ jsx44(PropertyField, { type: "toggle", label: "Fluid on Mobile", value: p.fluidOnMobile, onChange: (v) => update({ fluidOnMobile: v }) })
28021
28778
  ] });
28022
28779
  }
28023
28780
 
28024
28781
  // src/components/Properties/DividerProperties.tsx
28025
- import { jsx as jsx41, jsxs as jsxs32 } from "react/jsx-runtime";
28782
+ import { jsx as jsx45, jsxs as jsxs35 } from "react/jsx-runtime";
28026
28783
  var BORDER_STYLE_OPTIONS = [
28027
28784
  { value: "solid", label: "Solid" },
28028
28785
  { value: "dashed", label: "Dashed" },
@@ -28031,26 +28788,26 @@ var BORDER_STYLE_OPTIONS = [
28031
28788
  function DividerProperties({ block }) {
28032
28789
  const update = useBlockUpdate(block.id);
28033
28790
  const p = block.properties;
28034
- return /* @__PURE__ */ jsxs32("div", { className: properties_default.propertiesBody, children: [
28035
- /* @__PURE__ */ jsx41(PropertyField, { type: "color", label: "Border Color", value: p.borderColor, onChange: (v) => update({ borderColor: v }) }),
28036
- /* @__PURE__ */ jsx41(PropertyField, { type: "text", label: "Border Width", value: p.borderWidth, onChange: (v) => update({ borderWidth: v }) }),
28037
- /* @__PURE__ */ jsx41(PropertyField, { type: "select", label: "Border Style", value: p.borderStyle, onChange: (v) => update({ borderStyle: v }), options: BORDER_STYLE_OPTIONS }),
28038
- /* @__PURE__ */ jsx41(PropertyField, { type: "text", label: "Width", value: p.width, onChange: (v) => update({ width: v }) }),
28039
- /* @__PURE__ */ jsx41(PropertyField, { type: "padding", label: "Padding", value: p.padding, onChange: (v) => update({ padding: v }) })
28791
+ return /* @__PURE__ */ jsxs35("div", { className: properties_default.propertiesBody, children: [
28792
+ /* @__PURE__ */ jsx45(PropertyField, { type: "color", label: "Border Color", value: p.borderColor, onChange: (v) => update({ borderColor: v }) }),
28793
+ /* @__PURE__ */ jsx45(PropertyField, { type: "text", label: "Border Width", value: p.borderWidth, onChange: (v) => update({ borderWidth: v }) }),
28794
+ /* @__PURE__ */ jsx45(PropertyField, { type: "select", label: "Border Style", value: p.borderStyle, onChange: (v) => update({ borderStyle: v }), options: BORDER_STYLE_OPTIONS }),
28795
+ /* @__PURE__ */ jsx45(PropertyField, { type: "text", label: "Width", value: p.width, onChange: (v) => update({ width: v }) }),
28796
+ /* @__PURE__ */ jsx45(PropertyField, { type: "padding", label: "Padding", value: p.padding, onChange: (v) => update({ padding: v }) })
28040
28797
  ] });
28041
28798
  }
28042
28799
 
28043
28800
  // src/components/Properties/SpacerProperties.tsx
28044
- import { jsx as jsx42 } from "react/jsx-runtime";
28801
+ import { jsx as jsx46 } from "react/jsx-runtime";
28045
28802
  function SpacerProperties({ block }) {
28046
28803
  const update = useBlockUpdate(block.id);
28047
28804
  const p = block.properties;
28048
28805
  const heightNum = parseInt(p.height, 10) || 20;
28049
- return /* @__PURE__ */ jsx42("div", { className: properties_default.propertiesBody, children: /* @__PURE__ */ jsx42(PropertyField, { type: "slider", label: "Height", value: heightNum, min: 5, max: 200, step: 5, unit: "px", onChange: (v) => update({ height: `${v}px` }) }) });
28806
+ return /* @__PURE__ */ jsx46("div", { className: properties_default.propertiesBody, children: /* @__PURE__ */ jsx46(PropertyField, { type: "slider", label: "Height", value: heightNum, min: 5, max: 200, step: 5, unit: "px", onChange: (v) => update({ height: `${v}px` }) }) });
28050
28807
  }
28051
28808
 
28052
28809
  // src/components/Properties/SocialProperties.tsx
28053
- import { useCallback as useCallback29 } from "react";
28810
+ import { useCallback as useCallback31, useRef as useRef21, useState as useState21 } from "react";
28054
28811
 
28055
28812
  // src/types.ts
28056
28813
  function narrowBlock(block, type) {
@@ -28058,14 +28815,105 @@ function narrowBlock(block, type) {
28058
28815
  }
28059
28816
 
28060
28817
  // src/components/Properties/SocialProperties.tsx
28061
- import { jsx as jsx43, jsxs as jsxs33 } from "react/jsx-runtime";
28818
+ import { Fragment as Fragment4, jsx as jsx47, jsxs as jsxs36 } from "react/jsx-runtime";
28819
+ var ALLOWED_IMAGE_TYPES = ["image/png", "image/jpeg", "image/gif", "image/svg+xml", "image/webp"];
28820
+ var MAX_ICON_SIZE_BYTES = 2 * 1024 * 1024;
28062
28821
  var MODE_OPTIONS = [
28063
28822
  { value: "horizontal", label: "Horizontal" },
28064
28823
  { value: "vertical", label: "Vertical" }
28065
28824
  ];
28825
+ var PLATFORM_COLORS2 = {
28826
+ facebook: "#3b5998",
28827
+ twitter: "#1da1f2",
28828
+ instagram: "#e1306c",
28829
+ linkedin: "#0077b5",
28830
+ youtube: "#ff0000",
28831
+ github: "#333333",
28832
+ pinterest: "#bd081c",
28833
+ snapchat: "#fffc00",
28834
+ tiktok: "#000000",
28835
+ web: "#4caf50"
28836
+ };
28837
+ function SocialElementIconUpload({ element, blockId, onUpdate }) {
28838
+ const { imageUploadAdapter } = useImageAdapter();
28839
+ const fileInputRef = useRef21(null);
28840
+ const [localError, setLocalError] = useState21(null);
28841
+ const { upload, status, error } = useImageUpload({
28842
+ adapter: imageUploadAdapter,
28843
+ blockId,
28844
+ onSuccess: (result) => {
28845
+ onUpdate({ src: result.url });
28846
+ }
28847
+ });
28848
+ const handleFileSelect = useCallback31(
28849
+ async (e) => {
28850
+ const file = e.target.files?.[0];
28851
+ if (!file) return;
28852
+ setLocalError(null);
28853
+ if (!ALLOWED_IMAGE_TYPES.includes(file.type)) {
28854
+ setLocalError("Only PNG, JPG, GIF, SVG, and WebP files are allowed");
28855
+ if (fileInputRef.current) fileInputRef.current.value = "";
28856
+ return;
28857
+ }
28858
+ if (file.size > MAX_ICON_SIZE_BYTES) {
28859
+ setLocalError("File size must be under 2MB");
28860
+ if (fileInputRef.current) fileInputRef.current.value = "";
28861
+ return;
28862
+ }
28863
+ await upload(file);
28864
+ if (fileInputRef.current) fileInputRef.current.value = "";
28865
+ },
28866
+ [upload]
28867
+ );
28868
+ const bgColor = PLATFORM_COLORS2[element.name] || "#999999";
28869
+ const SvgIcon = getSocialIcon(element.name);
28870
+ return /* @__PURE__ */ jsxs36("div", { style: { display: "flex", alignItems: "center", gap: "6px", marginTop: "4px" }, children: [
28871
+ /* @__PURE__ */ jsx47(
28872
+ "div",
28873
+ {
28874
+ className: blocks_default.socialIconPreview,
28875
+ style: { backgroundColor: bgColor },
28876
+ children: element.src ? /* @__PURE__ */ jsx47("img", { src: element.src, alt: element.name }) : SvgIcon ? /* @__PURE__ */ jsx47(SvgIcon, { size: 16, color: element.color || "#ffffff" }) : /* @__PURE__ */ jsx47("span", { style: { color: element.color || "#ffffff", fontSize: "12px", fontWeight: "bold" }, children: element.name.charAt(0).toUpperCase() })
28877
+ }
28878
+ ),
28879
+ imageUploadAdapter && /* @__PURE__ */ jsxs36(Fragment4, { children: [
28880
+ /* @__PURE__ */ jsx47(
28881
+ "button",
28882
+ {
28883
+ className: `ee-upload-btn ${status === "uploading" ? properties_default.fieldBtnUploadDisabled : properties_default.fieldBtnUpload}`,
28884
+ onClick: () => fileInputRef.current?.click(),
28885
+ disabled: status === "uploading",
28886
+ style: { flex: 1, fontSize: "11px", padding: "3px 6px" },
28887
+ children: status === "uploading" ? "Uploading..." : "Upload Icon"
28888
+ }
28889
+ ),
28890
+ /* @__PURE__ */ jsx47(
28891
+ "input",
28892
+ {
28893
+ ref: fileInputRef,
28894
+ type: "file",
28895
+ accept: ".png,.jpg,.jpeg,.gif,.svg,.webp",
28896
+ onChange: handleFileSelect,
28897
+ style: { display: "none" }
28898
+ }
28899
+ )
28900
+ ] }),
28901
+ element.src && /* @__PURE__ */ jsx47(
28902
+ "button",
28903
+ {
28904
+ className: properties_default.itemActionBtnDanger,
28905
+ onClick: () => onUpdate({ src: void 0 }),
28906
+ title: "Reset to default icon",
28907
+ style: { fontSize: "11px", padding: "3px 6px" },
28908
+ children: "Reset"
28909
+ }
28910
+ ),
28911
+ (localError || error) && /* @__PURE__ */ jsx47("span", { className: properties_default.validationError, style: { fontSize: "10px" }, children: localError || error })
28912
+ ] });
28913
+ }
28066
28914
  function SocialProperties({ block }) {
28067
28915
  const update = useBlockUpdate(block.id);
28068
- const updateElement = useCallback29(
28916
+ const updateElement = useCallback31(
28069
28917
  (index, changes) => {
28070
28918
  const elements = [...block.properties.elements];
28071
28919
  elements[index] = { ...elements[index], ...changes };
@@ -28073,18 +28921,18 @@ function SocialProperties({ block }) {
28073
28921
  },
28074
28922
  [block.properties.elements, update]
28075
28923
  );
28076
- const addElement = useCallback29(() => {
28924
+ const addElement = useCallback31(() => {
28077
28925
  const elements = [...block.properties.elements, { id: generateId("se"), name: "web", href: "#" }];
28078
28926
  update({ elements });
28079
28927
  }, [block.properties.elements, update]);
28080
- const removeElement = useCallback29(
28928
+ const removeElement = useCallback31(
28081
28929
  (index) => {
28082
28930
  const elements = block.properties.elements.filter((_, i) => i !== index);
28083
28931
  update({ elements });
28084
28932
  },
28085
28933
  [block.properties.elements, update]
28086
28934
  );
28087
- const moveElement = useCallback29(
28935
+ const moveElement = useCallback31(
28088
28936
  (index, direction) => {
28089
28937
  const elements = [...block.properties.elements];
28090
28938
  const newIndex = index + direction;
@@ -28096,45 +28944,45 @@ function SocialProperties({ block }) {
28096
28944
  );
28097
28945
  if (!narrowBlock(block, "social")) return null;
28098
28946
  const p = block.properties;
28099
- return /* @__PURE__ */ jsxs33("div", { className: properties_default.propertiesBody, children: [
28100
- /* @__PURE__ */ jsx43(PropertyField, { type: "select", label: "Mode", value: p.mode, onChange: (v) => update({ mode: v }), options: MODE_OPTIONS }),
28101
- /* @__PURE__ */ jsx43(PropertyField, { type: "alignment", label: "Alignment", value: p.align, onChange: (v) => update({ align: v }) }),
28102
- /* @__PURE__ */ jsx43(PropertyField, { type: "text", label: "Icon Size", value: p.iconSize, onChange: (v) => update({ iconSize: v }) }),
28103
- /* @__PURE__ */ jsx43(PropertyField, { type: "text", label: "Icon Padding", value: p.iconPadding, onChange: (v) => update({ iconPadding: v }) }),
28104
- /* @__PURE__ */ jsx43(PropertyField, { type: "text", label: "Border Radius", value: p.borderRadius, onChange: (v) => update({ borderRadius: v }) }),
28105
- /* @__PURE__ */ jsx43(PropertyField, { type: "color", label: "Text Color", value: p.color, onChange: (v) => update({ color: v }) }),
28106
- /* @__PURE__ */ jsx43(PropertyField, { type: "text", label: "Font Size", value: p.fontSize, onChange: (v) => update({ fontSize: v }) }),
28107
- /* @__PURE__ */ jsx43(PropertyField, { type: "padding", label: "Padding", value: p.padding, onChange: (v) => update({ padding: v }) }),
28108
- /* @__PURE__ */ jsx43(FieldSeparator, {}),
28109
- /* @__PURE__ */ jsxs33("div", { className: properties_default.fieldGroup, children: [
28110
- /* @__PURE__ */ jsx43("label", { className: properties_default.fieldLabel, children: "Social Elements" }),
28111
- /* @__PURE__ */ jsx43("div", { className: blocks_default.socialElementsContainer, children: p.elements.map((element, index) => /* @__PURE__ */ jsxs33("div", { className: blocks_default.socialElementItem, children: [
28112
- /* @__PURE__ */ jsxs33("div", { className: properties_default.fieldRow, children: [
28113
- /* @__PURE__ */ jsxs33(
28947
+ return /* @__PURE__ */ jsxs36("div", { className: properties_default.propertiesBody, children: [
28948
+ /* @__PURE__ */ jsx47(PropertyField, { type: "select", label: "Mode", value: p.mode, onChange: (v) => update({ mode: v }), options: MODE_OPTIONS }),
28949
+ /* @__PURE__ */ jsx47(PropertyField, { type: "alignment", label: "Alignment", value: p.align, onChange: (v) => update({ align: v }) }),
28950
+ /* @__PURE__ */ jsx47(PropertyField, { type: "text", label: "Icon Size", value: p.iconSize, onChange: (v) => update({ iconSize: v }) }),
28951
+ /* @__PURE__ */ jsx47(PropertyField, { type: "text", label: "Icon Padding", value: p.iconPadding, onChange: (v) => update({ iconPadding: v }) }),
28952
+ /* @__PURE__ */ jsx47(PropertyField, { type: "text", label: "Border Radius", value: p.borderRadius, onChange: (v) => update({ borderRadius: v }) }),
28953
+ /* @__PURE__ */ jsx47(PropertyField, { type: "color", label: "Text Color", value: p.color, onChange: (v) => update({ color: v }) }),
28954
+ /* @__PURE__ */ jsx47(PropertyField, { type: "text", label: "Font Size", value: p.fontSize, onChange: (v) => update({ fontSize: v }) }),
28955
+ /* @__PURE__ */ jsx47(PropertyField, { type: "padding", label: "Padding", value: p.padding, onChange: (v) => update({ padding: v }) }),
28956
+ /* @__PURE__ */ jsx47(FieldSeparator, {}),
28957
+ /* @__PURE__ */ jsxs36("div", { className: properties_default.fieldGroup, children: [
28958
+ /* @__PURE__ */ jsx47("label", { className: properties_default.fieldLabel, children: "Social Elements" }),
28959
+ /* @__PURE__ */ jsx47("div", { className: blocks_default.socialElementsContainer, children: p.elements.map((element, index) => /* @__PURE__ */ jsxs36("div", { className: blocks_default.socialElementItem, children: [
28960
+ /* @__PURE__ */ jsxs36("div", { className: properties_default.fieldRow, children: [
28961
+ /* @__PURE__ */ jsxs36(
28114
28962
  "select",
28115
28963
  {
28116
28964
  className: `${properties_default.fieldSelect} ${properties_default.fieldInputFlex}`,
28117
28965
  value: element.name,
28118
28966
  onChange: (e) => updateElement(index, { name: e.target.value }),
28119
28967
  children: [
28120
- /* @__PURE__ */ jsx43("option", { value: "facebook", children: "Facebook" }),
28121
- /* @__PURE__ */ jsx43("option", { value: "twitter", children: "Twitter" }),
28122
- /* @__PURE__ */ jsx43("option", { value: "instagram", children: "Instagram" }),
28123
- /* @__PURE__ */ jsx43("option", { value: "linkedin", children: "LinkedIn" }),
28124
- /* @__PURE__ */ jsx43("option", { value: "youtube", children: "YouTube" }),
28125
- /* @__PURE__ */ jsx43("option", { value: "github", children: "GitHub" }),
28126
- /* @__PURE__ */ jsx43("option", { value: "pinterest", children: "Pinterest" }),
28127
- /* @__PURE__ */ jsx43("option", { value: "snapchat", children: "Snapchat" }),
28128
- /* @__PURE__ */ jsx43("option", { value: "tiktok", children: "TikTok" }),
28129
- /* @__PURE__ */ jsx43("option", { value: "web", children: "Web" })
28968
+ /* @__PURE__ */ jsx47("option", { value: "facebook", children: "Facebook" }),
28969
+ /* @__PURE__ */ jsx47("option", { value: "twitter", children: "Twitter" }),
28970
+ /* @__PURE__ */ jsx47("option", { value: "instagram", children: "Instagram" }),
28971
+ /* @__PURE__ */ jsx47("option", { value: "linkedin", children: "LinkedIn" }),
28972
+ /* @__PURE__ */ jsx47("option", { value: "youtube", children: "YouTube" }),
28973
+ /* @__PURE__ */ jsx47("option", { value: "github", children: "GitHub" }),
28974
+ /* @__PURE__ */ jsx47("option", { value: "pinterest", children: "Pinterest" }),
28975
+ /* @__PURE__ */ jsx47("option", { value: "snapchat", children: "Snapchat" }),
28976
+ /* @__PURE__ */ jsx47("option", { value: "tiktok", children: "TikTok" }),
28977
+ /* @__PURE__ */ jsx47("option", { value: "web", children: "Web" })
28130
28978
  ]
28131
28979
  }
28132
28980
  ),
28133
- /* @__PURE__ */ jsx43("button", { className: `ee-item-move-up ${properties_default.itemActionBtn}`, onClick: () => moveElement(index, -1), disabled: index === 0, title: "Move up", children: "\u2191" }),
28134
- /* @__PURE__ */ jsx43("button", { className: `ee-item-move-down ${properties_default.itemActionBtn}`, onClick: () => moveElement(index, 1), disabled: index === p.elements.length - 1, title: "Move down", children: "\u2193" }),
28135
- /* @__PURE__ */ jsx43("button", { className: `ee-item-remove ${properties_default.itemActionBtnDanger}`, onClick: () => removeElement(index), title: "Remove", children: "\xD7" })
28981
+ /* @__PURE__ */ jsx47("button", { className: `ee-item-move-up ${properties_default.itemActionBtn}`, onClick: () => moveElement(index, -1), disabled: index === 0, title: "Move up", children: "\u2191" }),
28982
+ /* @__PURE__ */ jsx47("button", { className: `ee-item-move-down ${properties_default.itemActionBtn}`, onClick: () => moveElement(index, 1), disabled: index === p.elements.length - 1, title: "Move down", children: "\u2193" }),
28983
+ /* @__PURE__ */ jsx47("button", { className: `ee-item-remove ${properties_default.itemActionBtnDanger}`, onClick: () => removeElement(index), title: "Remove", children: "\xD7" })
28136
28984
  ] }),
28137
- /* @__PURE__ */ jsx43(
28985
+ /* @__PURE__ */ jsx47(
28138
28986
  "input",
28139
28987
  {
28140
28988
  className: properties_default.fieldInputStacked,
@@ -28143,7 +28991,7 @@ function SocialProperties({ block }) {
28143
28991
  placeholder: "URL"
28144
28992
  }
28145
28993
  ),
28146
- /* @__PURE__ */ jsx43(
28994
+ /* @__PURE__ */ jsx47(
28147
28995
  "input",
28148
28996
  {
28149
28997
  className: properties_default.fieldInputStacked,
@@ -28151,27 +28999,35 @@ function SocialProperties({ block }) {
28151
28999
  onChange: (e) => updateElement(index, { content: e.target.value }),
28152
29000
  placeholder: "Label (optional)"
28153
29001
  }
29002
+ ),
29003
+ /* @__PURE__ */ jsx47(
29004
+ SocialElementIconUpload,
29005
+ {
29006
+ element,
29007
+ blockId: block.id,
29008
+ onUpdate: (changes) => updateElement(index, changes)
29009
+ }
28154
29010
  )
28155
29011
  ] }, element.id ?? `se-${index}`)) }),
28156
- /* @__PURE__ */ jsx43("button", { className: `ee-add-item ${properties_default.addItemBtn}`, onClick: addElement, children: "+ Add Element" })
29012
+ /* @__PURE__ */ jsx47("button", { className: `ee-add-item ${properties_default.addItemBtn}`, onClick: addElement, children: "+ Add Element" })
28157
29013
  ] })
28158
29014
  ] });
28159
29015
  }
28160
29016
 
28161
29017
  // src/components/Properties/HtmlProperties.tsx
28162
- import { jsx as jsx44, jsxs as jsxs34 } from "react/jsx-runtime";
29018
+ import { jsx as jsx48, jsxs as jsxs37 } from "react/jsx-runtime";
28163
29019
  function HtmlProperties({ block }) {
28164
29020
  const update = useBlockUpdate(block.id);
28165
29021
  const p = block.properties;
28166
- return /* @__PURE__ */ jsxs34("div", { className: properties_default.propertiesBody, children: [
28167
- /* @__PURE__ */ jsx44(PropertyField, { type: "textarea", label: "HTML Content", value: p.content, onChange: (v) => update({ content: v }), placeholder: "<p>Enter raw HTML here...</p>", rows: 10, code: true }),
28168
- /* @__PURE__ */ jsx44(PropertyField, { type: "padding", label: "Padding", value: p.padding, onChange: (v) => update({ padding: v }) })
29022
+ return /* @__PURE__ */ jsxs37("div", { className: properties_default.propertiesBody, children: [
29023
+ /* @__PURE__ */ jsx48(PropertyField, { type: "textarea", label: "HTML Content", value: p.content, onChange: (v) => update({ content: v }), placeholder: "<p>Enter raw HTML here...</p>", rows: 10, code: true }),
29024
+ /* @__PURE__ */ jsx48(PropertyField, { type: "padding", label: "Padding", value: p.padding, onChange: (v) => update({ padding: v }) })
28169
29025
  ] });
28170
29026
  }
28171
29027
 
28172
29028
  // src/components/Properties/VideoProperties.tsx
28173
- import { useCallback as useCallback30 } from "react";
28174
- import { jsx as jsx45, jsxs as jsxs35 } from "react/jsx-runtime";
29029
+ import { useCallback as useCallback32 } from "react";
29030
+ import { jsx as jsx49, jsxs as jsxs38 } from "react/jsx-runtime";
28175
29031
  function getAutoThumbnail3(url) {
28176
29032
  if (!url) return "";
28177
29033
  const ytMatch = url.match(/(?:youtube\.com\/watch\?v=|youtu\.be\/)([a-zA-Z0-9_-]{11})/);
@@ -28181,7 +29037,7 @@ function getAutoThumbnail3(url) {
28181
29037
  function VideoProperties({ block }) {
28182
29038
  const update = useBlockUpdate(block.id);
28183
29039
  const p = block.properties;
28184
- const handleVideoUrlChange = useCallback30(
29040
+ const handleVideoUrlChange = useCallback32(
28185
29041
  (src) => {
28186
29042
  const updates = { src };
28187
29043
  if (!p.thumbnailUrl) {
@@ -28192,14 +29048,14 @@ function VideoProperties({ block }) {
28192
29048
  },
28193
29049
  [update, p.thumbnailUrl]
28194
29050
  );
28195
- const handleAutoThumbnail = useCallback30(() => {
29051
+ const handleAutoThumbnail = useCallback32(() => {
28196
29052
  const auto = getAutoThumbnail3(p.src);
28197
29053
  if (auto) update({ thumbnailUrl: auto });
28198
29054
  }, [update, p.src]);
28199
- return /* @__PURE__ */ jsxs35("div", { className: properties_default.propertiesBody, children: [
28200
- /* @__PURE__ */ jsxs35("div", { className: properties_default.fieldGroup, children: [
28201
- /* @__PURE__ */ jsx45("label", { className: properties_default.fieldLabel, children: "Video URL" }),
28202
- /* @__PURE__ */ jsx45(
29055
+ return /* @__PURE__ */ jsxs38("div", { className: properties_default.propertiesBody, children: [
29056
+ /* @__PURE__ */ jsxs38("div", { className: properties_default.fieldGroup, children: [
29057
+ /* @__PURE__ */ jsx49("label", { className: properties_default.fieldLabel, children: "Video URL" }),
29058
+ /* @__PURE__ */ jsx49(
28203
29059
  "input",
28204
29060
  {
28205
29061
  className: properties_default.fieldInput,
@@ -28209,9 +29065,9 @@ function VideoProperties({ block }) {
28209
29065
  }
28210
29066
  )
28211
29067
  ] }),
28212
- /* @__PURE__ */ jsxs35("div", { className: properties_default.fieldGroup, children: [
28213
- /* @__PURE__ */ jsx45("label", { className: properties_default.fieldLabel, children: "Thumbnail URL" }),
28214
- /* @__PURE__ */ jsx45(
29068
+ /* @__PURE__ */ jsxs38("div", { className: properties_default.fieldGroup, children: [
29069
+ /* @__PURE__ */ jsx49("label", { className: properties_default.fieldLabel, children: "Thumbnail URL" }),
29070
+ /* @__PURE__ */ jsx49(
28215
29071
  "input",
28216
29072
  {
28217
29073
  className: properties_default.fieldInput,
@@ -28220,7 +29076,7 @@ function VideoProperties({ block }) {
28220
29076
  placeholder: "https://..."
28221
29077
  }
28222
29078
  ),
28223
- p.src && /* @__PURE__ */ jsx45(
29079
+ p.src && /* @__PURE__ */ jsx49(
28224
29080
  "button",
28225
29081
  {
28226
29082
  className: `ee-auto-thumbnail ${properties_default.fieldBtnUpload} ${properties_default.fieldInputStacked}`,
@@ -28229,15 +29085,15 @@ function VideoProperties({ block }) {
28229
29085
  }
28230
29086
  )
28231
29087
  ] }),
28232
- /* @__PURE__ */ jsx45(PropertyField, { type: "text", label: "Alt Text", value: p.alt, onChange: (v) => update({ alt: v }), placeholder: "Video description" }),
28233
- /* @__PURE__ */ jsx45(PropertyField, { type: "alignment", label: "Alignment", value: p.align, onChange: (v) => update({ align: v }) }),
28234
- /* @__PURE__ */ jsx45(PropertyField, { type: "padding", label: "Padding", value: p.padding, onChange: (v) => update({ padding: v }) })
29088
+ /* @__PURE__ */ jsx49(PropertyField, { type: "text", label: "Alt Text", value: p.alt, onChange: (v) => update({ alt: v }), placeholder: "Video description" }),
29089
+ /* @__PURE__ */ jsx49(PropertyField, { type: "alignment", label: "Alignment", value: p.align, onChange: (v) => update({ align: v }) }),
29090
+ /* @__PURE__ */ jsx49(PropertyField, { type: "padding", label: "Padding", value: p.padding, onChange: (v) => update({ padding: v }) })
28235
29091
  ] });
28236
29092
  }
28237
29093
 
28238
29094
  // src/components/Properties/HeadingProperties.tsx
28239
- import { useCallback as useCallback31 } from "react";
28240
- import { jsx as jsx46, jsxs as jsxs36 } from "react/jsx-runtime";
29095
+ import { useCallback as useCallback33 } from "react";
29096
+ import { jsx as jsx50, jsxs as jsxs39 } from "react/jsx-runtime";
28241
29097
  var LEVEL_OPTIONS = [
28242
29098
  { value: "h1", label: "H1" },
28243
29099
  { value: "h2", label: "H2" },
@@ -28272,38 +29128,39 @@ var LEVEL_DEFAULTS = {
28272
29128
  function HeadingProperties({ block }) {
28273
29129
  const update = useBlockUpdate(block.id);
28274
29130
  const p = block.properties;
28275
- const handleLevelChange = useCallback31(
29131
+ const handleLevelChange = useCallback33(
28276
29132
  (level) => {
28277
29133
  const defaults2 = LEVEL_DEFAULTS[level] || LEVEL_DEFAULTS.h2;
28278
29134
  update({ level, fontSize: defaults2.fontSize, lineHeight: defaults2.lineHeight });
28279
29135
  },
28280
29136
  [update]
28281
29137
  );
28282
- return /* @__PURE__ */ jsxs36("div", { className: properties_default.propertiesBody, children: [
28283
- /* @__PURE__ */ jsx46(PropertyField, { type: "select", label: "Heading Level", value: p.level, onChange: handleLevelChange, options: LEVEL_OPTIONS }),
28284
- /* @__PURE__ */ jsx46(FieldSeparator, {}),
28285
- /* @__PURE__ */ jsx46(PropertyField, { type: "font", label: "Font Family", value: p.fontFamily, onChange: (v) => update({ fontFamily: v }) }),
28286
- /* @__PURE__ */ jsx46(PropertyField, { type: "text", label: "Font Size", value: p.fontSize, onChange: (v) => update({ fontSize: v }) }),
28287
- /* @__PURE__ */ jsx46(PropertyField, { type: "color", label: "Color", value: p.color, onChange: (v) => update({ color: v }) }),
28288
- /* @__PURE__ */ jsx46(PropertyField, { type: "text", label: "Line Height", value: p.lineHeight, onChange: (v) => update({ lineHeight: v }) }),
28289
- /* @__PURE__ */ jsx46(PropertyField, { type: "select", label: "Font Weight", value: p.fontWeight || "bold", onChange: (v) => update({ fontWeight: v }), options: FONT_WEIGHT_OPTIONS2 }),
28290
- /* @__PURE__ */ jsx46(PropertyField, { type: "select", label: "Text Transform", value: p.textTransform || "none", onChange: (v) => update({ textTransform: v }), options: TEXT_TRANSFORM_OPTIONS2 }),
28291
- /* @__PURE__ */ jsx46(PropertyField, { type: "text", label: "Letter Spacing", value: p.letterSpacing || "normal", onChange: (v) => update({ letterSpacing: v }), placeholder: "normal" }),
28292
- /* @__PURE__ */ jsx46(PropertyField, { type: "alignment", label: "Alignment", value: p.align, onChange: (v) => update({ align: v }) }),
28293
- /* @__PURE__ */ jsx46(PropertyField, { type: "padding", label: "Padding", value: p.padding, onChange: (v) => update({ padding: v }) })
29138
+ return /* @__PURE__ */ jsxs39("div", { className: properties_default.propertiesBody, children: [
29139
+ /* @__PURE__ */ jsx50(PropertyField, { type: "select", label: "Heading Level", value: p.level, onChange: handleLevelChange, options: LEVEL_OPTIONS }),
29140
+ /* @__PURE__ */ jsx50(FieldSeparator, {}),
29141
+ /* @__PURE__ */ jsx50(PropertyField, { type: "font", label: "Font Family", value: p.fontFamily, onChange: (v) => update({ fontFamily: v }) }),
29142
+ /* @__PURE__ */ jsx50(PropertyField, { type: "text", label: "Font Size", value: p.fontSize, onChange: (v) => update({ fontSize: v }) }),
29143
+ /* @__PURE__ */ jsx50(PropertyField, { type: "color", label: "Color", value: p.color, onChange: (v) => update({ color: v }) }),
29144
+ /* @__PURE__ */ jsx50(PropertyField, { type: "color", label: "Background Color", value: p.backgroundColor || "transparent", onChange: (v) => update({ backgroundColor: v }) }),
29145
+ /* @__PURE__ */ jsx50(PropertyField, { type: "text", label: "Line Height", value: p.lineHeight, onChange: (v) => update({ lineHeight: v }) }),
29146
+ /* @__PURE__ */ jsx50(PropertyField, { type: "select", label: "Font Weight", value: p.fontWeight || "bold", onChange: (v) => update({ fontWeight: v }), options: FONT_WEIGHT_OPTIONS2 }),
29147
+ /* @__PURE__ */ jsx50(PropertyField, { type: "select", label: "Text Transform", value: p.textTransform || "none", onChange: (v) => update({ textTransform: v }), options: TEXT_TRANSFORM_OPTIONS2 }),
29148
+ /* @__PURE__ */ jsx50(PropertyField, { type: "text", label: "Letter Spacing", value: p.letterSpacing || "normal", onChange: (v) => update({ letterSpacing: v }), placeholder: "normal" }),
29149
+ /* @__PURE__ */ jsx50(PropertyField, { type: "alignment", label: "Alignment", value: p.align, onChange: (v) => update({ align: v }) }),
29150
+ /* @__PURE__ */ jsx50(PropertyField, { type: "padding", label: "Padding", value: p.padding, onChange: (v) => update({ padding: v }) })
28294
29151
  ] });
28295
29152
  }
28296
29153
 
28297
29154
  // src/components/Properties/CountdownProperties.tsx
28298
- import { jsx as jsx47, jsxs as jsxs37 } from "react/jsx-runtime";
29155
+ import { jsx as jsx51, jsxs as jsxs40 } from "react/jsx-runtime";
28299
29156
  function CountdownProperties({ block }) {
28300
29157
  const update = useBlockUpdate(block.id);
28301
29158
  if (!narrowBlock(block, "countdown")) return null;
28302
29159
  const p = block.properties;
28303
- return /* @__PURE__ */ jsxs37("div", { className: properties_default.propertiesBody, children: [
28304
- /* @__PURE__ */ jsxs37("div", { className: properties_default.fieldGroup, children: [
28305
- /* @__PURE__ */ jsx47("label", { className: properties_default.fieldLabel, children: "Target Date" }),
28306
- /* @__PURE__ */ jsx47(
29160
+ return /* @__PURE__ */ jsxs40("div", { className: properties_default.propertiesBody, children: [
29161
+ /* @__PURE__ */ jsxs40("div", { className: properties_default.fieldGroup, children: [
29162
+ /* @__PURE__ */ jsx51("label", { className: properties_default.fieldLabel, children: "Target Date" }),
29163
+ /* @__PURE__ */ jsx51(
28307
29164
  "input",
28308
29165
  {
28309
29166
  className: properties_default.fieldInput,
@@ -28313,27 +29170,27 @@ function CountdownProperties({ block }) {
28313
29170
  }
28314
29171
  )
28315
29172
  ] }),
28316
- /* @__PURE__ */ jsx47(PropertyField, { type: "text", label: "Label", value: p.label, onChange: (v) => update({ label: v }) }),
28317
- /* @__PURE__ */ jsx47(FieldSeparator, {}),
28318
- /* @__PURE__ */ jsx47(PropertyField, { type: "color", label: "Digit Background", value: p.digitBackgroundColor, onChange: (v) => update({ digitBackgroundColor: v }) }),
28319
- /* @__PURE__ */ jsx47(PropertyField, { type: "color", label: "Digit Color", value: p.digitColor, onChange: (v) => update({ digitColor: v }) }),
28320
- /* @__PURE__ */ jsx47(PropertyField, { type: "color", label: "Label Color", value: p.labelColor, onChange: (v) => update({ labelColor: v }) }),
28321
- /* @__PURE__ */ jsx47(PropertyField, { type: "text", label: "Font Size", value: p.fontSize, onChange: (v) => update({ fontSize: v }) }),
28322
- /* @__PURE__ */ jsx47(PropertyField, { type: "alignment", label: "Alignment", value: p.align, onChange: (v) => update({ align: v }) }),
28323
- /* @__PURE__ */ jsx47(PropertyField, { type: "padding", label: "Padding", value: p.padding, onChange: (v) => update({ padding: v }) })
29173
+ /* @__PURE__ */ jsx51(PropertyField, { type: "text", label: "Label", value: p.label, onChange: (v) => update({ label: v }) }),
29174
+ /* @__PURE__ */ jsx51(FieldSeparator, {}),
29175
+ /* @__PURE__ */ jsx51(PropertyField, { type: "color", label: "Digit Background", value: p.digitBackgroundColor, onChange: (v) => update({ digitBackgroundColor: v }) }),
29176
+ /* @__PURE__ */ jsx51(PropertyField, { type: "color", label: "Digit Color", value: p.digitColor, onChange: (v) => update({ digitColor: v }) }),
29177
+ /* @__PURE__ */ jsx51(PropertyField, { type: "color", label: "Label Color", value: p.labelColor, onChange: (v) => update({ labelColor: v }) }),
29178
+ /* @__PURE__ */ jsx51(PropertyField, { type: "text", label: "Font Size", value: p.fontSize, onChange: (v) => update({ fontSize: v }) }),
29179
+ /* @__PURE__ */ jsx51(PropertyField, { type: "alignment", label: "Alignment", value: p.align, onChange: (v) => update({ align: v }) }),
29180
+ /* @__PURE__ */ jsx51(PropertyField, { type: "padding", label: "Padding", value: p.padding, onChange: (v) => update({ padding: v }) })
28324
29181
  ] });
28325
29182
  }
28326
29183
 
28327
29184
  // src/components/Properties/MenuProperties.tsx
28328
- import { useCallback as useCallback32 } from "react";
28329
- import { jsx as jsx48, jsxs as jsxs38 } from "react/jsx-runtime";
29185
+ import { useCallback as useCallback34 } from "react";
29186
+ import { jsx as jsx52, jsxs as jsxs41 } from "react/jsx-runtime";
28330
29187
  var HAMBURGER_OPTIONS = [
28331
29188
  { value: "false", label: "Off" },
28332
29189
  { value: "true", label: "On" }
28333
29190
  ];
28334
29191
  function MenuProperties({ block }) {
28335
29192
  const update = useBlockUpdate(block.id);
28336
- const updateItem = useCallback32(
29193
+ const updateItem = useCallback34(
28337
29194
  (index, changes) => {
28338
29195
  const items = [...block.properties.items];
28339
29196
  items[index] = { ...items[index], ...changes };
@@ -28341,18 +29198,18 @@ function MenuProperties({ block }) {
28341
29198
  },
28342
29199
  [block.properties.items, update]
28343
29200
  );
28344
- const addItem = useCallback32(() => {
29201
+ const addItem = useCallback34(() => {
28345
29202
  const items = [...block.properties.items, { id: generateId("mi"), text: "Link", href: "#" }];
28346
29203
  update({ items });
28347
29204
  }, [block.properties.items, update]);
28348
- const removeItem = useCallback32(
29205
+ const removeItem = useCallback34(
28349
29206
  (index) => {
28350
29207
  const items = block.properties.items.filter((_, i) => i !== index);
28351
29208
  update({ items });
28352
29209
  },
28353
29210
  [block.properties.items, update]
28354
29211
  );
28355
- const moveItem = useCallback32(
29212
+ const moveItem = useCallback34(
28356
29213
  (index, direction) => {
28357
29214
  const items = [...block.properties.items];
28358
29215
  const newIndex = index + direction;
@@ -28364,20 +29221,20 @@ function MenuProperties({ block }) {
28364
29221
  );
28365
29222
  if (!narrowBlock(block, "menu")) return null;
28366
29223
  const p = block.properties;
28367
- return /* @__PURE__ */ jsxs38("div", { className: properties_default.propertiesBody, children: [
28368
- /* @__PURE__ */ jsx48(PropertyField, { type: "font", label: "Font Family", value: p.fontFamily, onChange: (v) => update({ fontFamily: v }) }),
28369
- /* @__PURE__ */ jsx48(PropertyField, { type: "text", label: "Font Size", value: p.fontSize, onChange: (v) => update({ fontSize: v }) }),
28370
- /* @__PURE__ */ jsx48(PropertyField, { type: "color", label: "Text Color", value: p.color, onChange: (v) => update({ color: v }) }),
28371
- /* @__PURE__ */ jsx48(PropertyField, { type: "select", label: "Hamburger Mode", value: p.hamburger ? "true" : "false", onChange: (v) => update({ hamburger: v === "true" }), options: HAMBURGER_OPTIONS }),
28372
- p.hamburger && /* @__PURE__ */ jsx48(PropertyField, { type: "color", label: "Icon Color", value: p.iconColor, onChange: (v) => update({ iconColor: v }) }),
28373
- /* @__PURE__ */ jsx48(PropertyField, { type: "alignment", label: "Alignment", value: p.align, onChange: (v) => update({ align: v }) }),
28374
- /* @__PURE__ */ jsx48(PropertyField, { type: "padding", label: "Padding", value: p.padding, onChange: (v) => update({ padding: v }) }),
28375
- /* @__PURE__ */ jsx48(FieldSeparator, {}),
28376
- /* @__PURE__ */ jsxs38("div", { className: properties_default.fieldGroup, children: [
28377
- /* @__PURE__ */ jsx48("label", { className: properties_default.fieldLabel, children: "Menu Items" }),
28378
- /* @__PURE__ */ jsx48("div", { className: blocks_default.menuItemsContainer, children: p.items.map((item, index) => /* @__PURE__ */ jsxs38("div", { className: blocks_default.menuItemEntry, children: [
28379
- /* @__PURE__ */ jsxs38("div", { className: properties_default.fieldRow, children: [
28380
- /* @__PURE__ */ jsx48(
29224
+ return /* @__PURE__ */ jsxs41("div", { className: properties_default.propertiesBody, children: [
29225
+ /* @__PURE__ */ jsx52(PropertyField, { type: "font", label: "Font Family", value: p.fontFamily, onChange: (v) => update({ fontFamily: v }) }),
29226
+ /* @__PURE__ */ jsx52(PropertyField, { type: "text", label: "Font Size", value: p.fontSize, onChange: (v) => update({ fontSize: v }) }),
29227
+ /* @__PURE__ */ jsx52(PropertyField, { type: "color", label: "Text Color", value: p.color, onChange: (v) => update({ color: v }) }),
29228
+ /* @__PURE__ */ jsx52(PropertyField, { type: "select", label: "Hamburger Mode", value: p.hamburger ? "true" : "false", onChange: (v) => update({ hamburger: v === "true" }), options: HAMBURGER_OPTIONS }),
29229
+ p.hamburger && /* @__PURE__ */ jsx52(PropertyField, { type: "color", label: "Icon Color", value: p.iconColor, onChange: (v) => update({ iconColor: v }) }),
29230
+ /* @__PURE__ */ jsx52(PropertyField, { type: "alignment", label: "Alignment", value: p.align, onChange: (v) => update({ align: v }) }),
29231
+ /* @__PURE__ */ jsx52(PropertyField, { type: "padding", label: "Padding", value: p.padding, onChange: (v) => update({ padding: v }) }),
29232
+ /* @__PURE__ */ jsx52(FieldSeparator, {}),
29233
+ /* @__PURE__ */ jsxs41("div", { className: properties_default.fieldGroup, children: [
29234
+ /* @__PURE__ */ jsx52("label", { className: properties_default.fieldLabel, children: "Menu Items" }),
29235
+ /* @__PURE__ */ jsx52("div", { className: blocks_default.menuItemsContainer, children: p.items.map((item, index) => /* @__PURE__ */ jsxs41("div", { className: blocks_default.menuItemEntry, children: [
29236
+ /* @__PURE__ */ jsxs41("div", { className: properties_default.fieldRow, children: [
29237
+ /* @__PURE__ */ jsx52(
28381
29238
  "input",
28382
29239
  {
28383
29240
  className: properties_default.fieldInputFlex,
@@ -28386,11 +29243,11 @@ function MenuProperties({ block }) {
28386
29243
  placeholder: "Label"
28387
29244
  }
28388
29245
  ),
28389
- /* @__PURE__ */ jsx48("button", { className: `ee-item-move-up ${properties_default.itemActionBtn}`, onClick: () => moveItem(index, -1), disabled: index === 0, title: "Move up", children: "\u2191" }),
28390
- /* @__PURE__ */ jsx48("button", { className: `ee-item-move-down ${properties_default.itemActionBtn}`, onClick: () => moveItem(index, 1), disabled: index === p.items.length - 1, title: "Move down", children: "\u2193" }),
28391
- /* @__PURE__ */ jsx48("button", { className: `ee-item-remove ${properties_default.itemActionBtnDanger}`, onClick: () => removeItem(index), title: "Remove", children: "\xD7" })
29246
+ /* @__PURE__ */ jsx52("button", { className: `ee-item-move-up ${properties_default.itemActionBtn}`, onClick: () => moveItem(index, -1), disabled: index === 0, title: "Move up", children: "\u2191" }),
29247
+ /* @__PURE__ */ jsx52("button", { className: `ee-item-move-down ${properties_default.itemActionBtn}`, onClick: () => moveItem(index, 1), disabled: index === p.items.length - 1, title: "Move down", children: "\u2193" }),
29248
+ /* @__PURE__ */ jsx52("button", { className: `ee-item-remove ${properties_default.itemActionBtnDanger}`, onClick: () => removeItem(index), title: "Remove", children: "\xD7" })
28392
29249
  ] }),
28393
- /* @__PURE__ */ jsx48(
29250
+ /* @__PURE__ */ jsx52(
28394
29251
  "input",
28395
29252
  {
28396
29253
  className: properties_default.fieldInputStacked,
@@ -28400,17 +29257,17 @@ function MenuProperties({ block }) {
28400
29257
  }
28401
29258
  )
28402
29259
  ] }, item.id ?? `mi-${index}`)) }),
28403
- /* @__PURE__ */ jsx48("button", { className: `ee-add-item ${properties_default.addItemBtn}`, onClick: addItem, children: "+ Add Item" })
29260
+ /* @__PURE__ */ jsx52("button", { className: `ee-add-item ${properties_default.addItemBtn}`, onClick: addItem, children: "+ Add Item" })
28404
29261
  ] })
28405
29262
  ] });
28406
29263
  }
28407
29264
 
28408
29265
  // src/components/ImageUpload/ImageUploader.tsx
28409
- import { useCallback as useCallback33, useRef as useRef19 } from "react";
28410
- import { jsx as jsx49, jsxs as jsxs39 } from "react/jsx-runtime";
29266
+ import { useCallback as useCallback35, useRef as useRef22 } from "react";
29267
+ import { jsx as jsx53, jsxs as jsxs42 } from "react/jsx-runtime";
28411
29268
  function ImageUploader({ blockId, onUploadComplete }) {
28412
29269
  const { imageUploadAdapter } = useImageAdapter();
28413
- const fileInputRef = useRef19(null);
29270
+ const fileInputRef = useRef22(null);
28414
29271
  const { status, progress, error, upload, cancel } = useImageUpload({
28415
29272
  adapter: imageUploadAdapter,
28416
29273
  blockId,
@@ -28418,7 +29275,7 @@ function ImageUploader({ blockId, onUploadComplete }) {
28418
29275
  onUploadComplete(result.url, result.alt);
28419
29276
  }
28420
29277
  });
28421
- const handleFileChange = useCallback33(
29278
+ const handleFileChange = useCallback35(
28422
29279
  async (e) => {
28423
29280
  const file = e.target.files?.[0];
28424
29281
  if (file) {
@@ -28427,26 +29284,26 @@ function ImageUploader({ blockId, onUploadComplete }) {
28427
29284
  },
28428
29285
  [upload]
28429
29286
  );
28430
- const handleClick2 = useCallback33(() => {
29287
+ const handleClick2 = useCallback35(() => {
28431
29288
  fileInputRef.current?.click();
28432
29289
  }, []);
28433
- return /* @__PURE__ */ jsxs39("div", { children: [
28434
- status === "uploading" ? /* @__PURE__ */ jsxs39("div", { className: `ee-image-uploading ${blocks_default.imageUploading}`, children: [
28435
- /* @__PURE__ */ jsxs39("div", { className: `ee-image-placeholder ${blocks_default.imagePlaceholder}`, children: [
28436
- /* @__PURE__ */ jsxs39("span", { children: [
29290
+ return /* @__PURE__ */ jsxs42("div", { children: [
29291
+ status === "uploading" ? /* @__PURE__ */ jsxs42("div", { className: `ee-image-uploading ${blocks_default.imageUploading}`, children: [
29292
+ /* @__PURE__ */ jsxs42("div", { className: `ee-image-placeholder ${blocks_default.imagePlaceholder}`, children: [
29293
+ /* @__PURE__ */ jsxs42("span", { children: [
28437
29294
  "Uploading... ",
28438
29295
  Math.round(progress),
28439
29296
  "%"
28440
29297
  ] }),
28441
- /* @__PURE__ */ jsx49("button", { className: "ee-upload-cancel", onClick: cancel, children: "Cancel" })
29298
+ /* @__PURE__ */ jsx53("button", { className: "ee-upload-cancel", onClick: cancel, children: "Cancel" })
28442
29299
  ] }),
28443
- /* @__PURE__ */ jsx49("div", { className: `ee-image-progress ${blocks_default.imageProgress}`, style: { width: `${progress}%` } })
28444
- ] }) : /* @__PURE__ */ jsxs39("div", { className: `ee-image-placeholder ${blocks_default.imagePlaceholder}`, onClick: handleClick2, children: [
28445
- /* @__PURE__ */ jsx49("span", { className: `ee-image-placeholder-icon ${blocks_default.imagePlaceholderIcon}`, children: "+" }),
28446
- /* @__PURE__ */ jsx49("span", { children: "Click to upload image" })
29300
+ /* @__PURE__ */ jsx53("div", { className: `ee-image-progress ${blocks_default.imageProgress}`, style: { width: `${progress}%` } })
29301
+ ] }) : /* @__PURE__ */ jsxs42("div", { className: `ee-image-placeholder ${blocks_default.imagePlaceholder}`, onClick: handleClick2, children: [
29302
+ /* @__PURE__ */ jsx53("span", { className: `ee-image-placeholder-icon ${blocks_default.imagePlaceholderIcon}`, children: "+" }),
29303
+ /* @__PURE__ */ jsx53("span", { children: "Click to upload image" })
28447
29304
  ] }),
28448
- error && /* @__PURE__ */ jsx49("div", { className: `ee-image-error ${blocks_default.imageError}`, children: error }),
28449
- /* @__PURE__ */ jsx49(
29305
+ error && /* @__PURE__ */ jsx53("div", { className: `ee-image-error ${blocks_default.imageError}`, children: error }),
29306
+ /* @__PURE__ */ jsx53(
28450
29307
  "input",
28451
29308
  {
28452
29309
  ref: fileInputRef,
@@ -28460,39 +29317,39 @@ function ImageUploader({ blockId, onUploadComplete }) {
28460
29317
  }
28461
29318
 
28462
29319
  // src/components/Properties/HeroProperties.tsx
28463
- import { jsx as jsx50, jsxs as jsxs40 } from "react/jsx-runtime";
29320
+ import { jsx as jsx54, jsxs as jsxs43 } from "react/jsx-runtime";
28464
29321
  function HeroProperties({ block }) {
28465
29322
  const update = useBlockUpdate(block.id);
28466
29323
  if (!narrowBlock(block, "hero")) return null;
28467
29324
  const p = block.properties;
28468
- return /* @__PURE__ */ jsxs40("div", { className: properties_default.propertiesBody, children: [
28469
- /* @__PURE__ */ jsx50(PropertyField, { type: "text", label: "Heading", value: p.heading, onChange: (v) => update({ heading: v }) }),
28470
- /* @__PURE__ */ jsx50(PropertyField, { type: "textarea", label: "Subtext", value: p.subtext, onChange: (v) => update({ subtext: v }), rows: 3 }),
28471
- /* @__PURE__ */ jsx50(FieldSeparator, {}),
28472
- /* @__PURE__ */ jsx50(PropertyField, { type: "text", label: "Button Text", value: p.buttonText, onChange: (v) => update({ buttonText: v }) }),
28473
- /* @__PURE__ */ jsx50(PropertyField, { type: "link", label: "Button Link", value: p.buttonHref, onChange: (v) => update({ buttonHref: v }) }),
28474
- /* @__PURE__ */ jsx50(FieldSeparator, {}),
28475
- /* @__PURE__ */ jsx50(PropertyField, { type: "color", label: "Heading Color", value: p.headingColor, onChange: (v) => update({ headingColor: v }) }),
28476
- /* @__PURE__ */ jsx50(PropertyField, { type: "text", label: "Heading Font Size", value: p.headingFontSize, onChange: (v) => update({ headingFontSize: v }) }),
28477
- /* @__PURE__ */ jsx50(PropertyField, { type: "color", label: "Subtext Color", value: p.subtextColor, onChange: (v) => update({ subtextColor: v }) }),
28478
- /* @__PURE__ */ jsx50(PropertyField, { type: "text", label: "Subtext Font Size", value: p.subtextFontSize, onChange: (v) => update({ subtextFontSize: v }) }),
28479
- /* @__PURE__ */ jsx50(FieldSeparator, {}),
28480
- /* @__PURE__ */ jsx50(PropertyField, { type: "color", label: "Button Background", value: p.buttonBackgroundColor, onChange: (v) => update({ buttonBackgroundColor: v }) }),
28481
- /* @__PURE__ */ jsx50(PropertyField, { type: "color", label: "Button Text Color", value: p.buttonColor, onChange: (v) => update({ buttonColor: v }) }),
28482
- /* @__PURE__ */ jsx50(PropertyField, { type: "text", label: "Button Border Radius", value: p.buttonBorderRadius, onChange: (v) => update({ buttonBorderRadius: v }) }),
28483
- /* @__PURE__ */ jsx50(PropertyField, { type: "alignment", label: "Alignment", value: p.align, onChange: (v) => update({ align: v }) }),
28484
- /* @__PURE__ */ jsx50(PropertyField, { type: "padding", label: "Padding", value: p.padding, onChange: (v) => update({ padding: v }) }),
28485
- /* @__PURE__ */ jsx50(FieldSeparator, {}),
28486
- /* @__PURE__ */ jsx50(PropertyField, { type: "color", label: "Background Color", value: p.backgroundColor, onChange: (v) => update({ backgroundColor: v }) }),
28487
- /* @__PURE__ */ jsx50(PropertyField, { type: "text", label: "Background Image URL", value: p.backgroundImage, onChange: (v) => update({ backgroundImage: v }), placeholder: "https://example.com/image.jpg" }),
28488
- !p.backgroundImage && /* @__PURE__ */ jsx50(
29325
+ return /* @__PURE__ */ jsxs43("div", { className: properties_default.propertiesBody, children: [
29326
+ /* @__PURE__ */ jsx54(PropertyField, { type: "text", label: "Heading", value: p.heading, onChange: (v) => update({ heading: v }) }),
29327
+ /* @__PURE__ */ jsx54(PropertyField, { type: "textarea", label: "Subtext", value: p.subtext, onChange: (v) => update({ subtext: v }), rows: 3 }),
29328
+ /* @__PURE__ */ jsx54(FieldSeparator, {}),
29329
+ /* @__PURE__ */ jsx54(PropertyField, { type: "text", label: "Button Text", value: p.buttonText, onChange: (v) => update({ buttonText: v }) }),
29330
+ /* @__PURE__ */ jsx54(PropertyField, { type: "link", label: "Button Link", value: p.buttonHref, onChange: (v) => update({ buttonHref: v }) }),
29331
+ /* @__PURE__ */ jsx54(FieldSeparator, {}),
29332
+ /* @__PURE__ */ jsx54(PropertyField, { type: "color", label: "Heading Color", value: p.headingColor, onChange: (v) => update({ headingColor: v }) }),
29333
+ /* @__PURE__ */ jsx54(PropertyField, { type: "text", label: "Heading Font Size", value: p.headingFontSize, onChange: (v) => update({ headingFontSize: v }) }),
29334
+ /* @__PURE__ */ jsx54(PropertyField, { type: "color", label: "Subtext Color", value: p.subtextColor, onChange: (v) => update({ subtextColor: v }) }),
29335
+ /* @__PURE__ */ jsx54(PropertyField, { type: "text", label: "Subtext Font Size", value: p.subtextFontSize, onChange: (v) => update({ subtextFontSize: v }) }),
29336
+ /* @__PURE__ */ jsx54(FieldSeparator, {}),
29337
+ /* @__PURE__ */ jsx54(PropertyField, { type: "color", label: "Button Background", value: p.buttonBackgroundColor, onChange: (v) => update({ buttonBackgroundColor: v }) }),
29338
+ /* @__PURE__ */ jsx54(PropertyField, { type: "color", label: "Button Text Color", value: p.buttonColor, onChange: (v) => update({ buttonColor: v }) }),
29339
+ /* @__PURE__ */ jsx54(PropertyField, { type: "text", label: "Button Border Radius", value: p.buttonBorderRadius, onChange: (v) => update({ buttonBorderRadius: v }) }),
29340
+ /* @__PURE__ */ jsx54(PropertyField, { type: "alignment", label: "Alignment", value: p.align, onChange: (v) => update({ align: v }) }),
29341
+ /* @__PURE__ */ jsx54(PropertyField, { type: "padding", label: "Padding", value: p.padding, onChange: (v) => update({ padding: v }) }),
29342
+ /* @__PURE__ */ jsx54(FieldSeparator, {}),
29343
+ /* @__PURE__ */ jsx54(PropertyField, { type: "color", label: "Background Color", value: p.backgroundColor, onChange: (v) => update({ backgroundColor: v }) }),
29344
+ /* @__PURE__ */ jsx54(PropertyField, { type: "text", label: "Background Image URL", value: p.backgroundImage, onChange: (v) => update({ backgroundImage: v }), placeholder: "https://example.com/image.jpg" }),
29345
+ !p.backgroundImage && /* @__PURE__ */ jsx54(
28489
29346
  ImageUploader,
28490
29347
  {
28491
29348
  blockId: block.id,
28492
29349
  onUploadComplete: (url) => update({ backgroundImage: url })
28493
29350
  }
28494
29351
  ),
28495
- p.backgroundImage && /* @__PURE__ */ jsx50("div", { className: properties_default.fieldGroup, children: /* @__PURE__ */ jsx50(
29352
+ p.backgroundImage && /* @__PURE__ */ jsx54("div", { className: properties_default.fieldGroup, children: /* @__PURE__ */ jsx54(
28496
29353
  "button",
28497
29354
  {
28498
29355
  className: `ee-remove-bg ${properties_default.fieldBtnUpload}`,
@@ -28504,7 +29361,7 @@ function HeroProperties({ block }) {
28504
29361
  }
28505
29362
 
28506
29363
  // src/components/Properties/PropertiesPanel.tsx
28507
- import { jsx as jsx51, jsxs as jsxs41 } from "react/jsx-runtime";
29364
+ import { jsx as jsx55, jsxs as jsxs44 } from "react/jsx-runtime";
28508
29365
  var BUILT_IN_PANELS = {
28509
29366
  text: TextProperties,
28510
29367
  button: ButtonProperties,
@@ -28528,28 +29385,28 @@ function PropertiesPanel() {
28528
29385
  if (selectedBlock) {
28529
29386
  const title = selectedBlock.type.charAt(0).toUpperCase() + selectedBlock.type.slice(1);
28530
29387
  const Component2 = getBlockPanel(selectedBlock.type);
28531
- return /* @__PURE__ */ jsxs41("div", { className: `ee-properties-panel ${properties_default.propertiesInner}`, children: [
28532
- /* @__PURE__ */ jsxs41("div", { className: `ee-properties-header ${properties_default.propertiesHeader}`, children: [
29388
+ return /* @__PURE__ */ jsxs44("div", { className: `ee-properties-panel ${properties_default.propertiesInner}`, children: [
29389
+ /* @__PURE__ */ jsxs44("div", { className: `ee-properties-header ${properties_default.propertiesHeader}`, children: [
28533
29390
  title,
28534
29391
  " Properties"
28535
29392
  ] }),
28536
- Component2 ? /* @__PURE__ */ jsx51(Component2, { block: selectedBlock }) : null
29393
+ Component2 ? /* @__PURE__ */ jsx55(Component2, { block: selectedBlock }) : null
28537
29394
  ] });
28538
29395
  }
28539
29396
  if (selectedSection) {
28540
- return /* @__PURE__ */ jsxs41("div", { className: `ee-properties-panel ${properties_default.propertiesInner}`, children: [
28541
- /* @__PURE__ */ jsx51("div", { className: `ee-properties-header ${properties_default.propertiesHeader}`, children: "Section Properties" }),
28542
- /* @__PURE__ */ jsx51(SectionProperties, { section: selectedSection })
29397
+ return /* @__PURE__ */ jsxs44("div", { className: `ee-properties-panel ${properties_default.propertiesInner}`, children: [
29398
+ /* @__PURE__ */ jsx55("div", { className: `ee-properties-header ${properties_default.propertiesHeader}`, children: "Section Properties" }),
29399
+ /* @__PURE__ */ jsx55(SectionProperties, { section: selectedSection })
28543
29400
  ] });
28544
29401
  }
28545
- return /* @__PURE__ */ jsxs41("div", { className: `ee-properties-panel ${properties_default.propertiesInner}`, children: [
28546
- /* @__PURE__ */ jsx51("div", { className: `ee-properties-header ${properties_default.propertiesHeader}`, children: "Email Settings" }),
28547
- /* @__PURE__ */ jsx51(HeadMetadataProperties, {})
29402
+ return /* @__PURE__ */ jsxs44("div", { className: `ee-properties-panel ${properties_default.propertiesInner}`, children: [
29403
+ /* @__PURE__ */ jsx55("div", { className: `ee-properties-header ${properties_default.propertiesHeader}`, children: "Email Settings" }),
29404
+ /* @__PURE__ */ jsx55(HeadMetadataProperties, {})
28548
29405
  ] });
28549
29406
  }
28550
29407
 
28551
29408
  // src/components/Preview/PreviewPanel.tsx
28552
- import { useEffect as useEffect15, useState as useState18, useRef as useRef20 } from "react";
29409
+ import { useEffect as useEffect16, useState as useState22, useRef as useRef23 } from "react";
28553
29410
 
28554
29411
  // src/styles/preview.module.css
28555
29412
  var preview_default = {
@@ -28564,17 +29421,17 @@ var preview_default = {
28564
29421
  };
28565
29422
 
28566
29423
  // src/components/Preview/PreviewPanel.tsx
28567
- import { jsx as jsx52, jsxs as jsxs42 } from "react/jsx-runtime";
29424
+ import { jsx as jsx56, jsxs as jsxs45 } from "react/jsx-runtime";
28568
29425
  var PREVIEW_WIDTHS = {
28569
29426
  desktop: 600,
28570
29427
  mobile: 375
28571
29428
  };
28572
29429
  function PreviewPanel() {
28573
29430
  const { template } = useTemplateContext();
28574
- const [html2, setHtml] = useState18("");
28575
- const [previewMode, setPreviewMode] = useState18("desktop");
28576
- const iframeRef = useRef20(null);
28577
- useEffect15(() => {
29431
+ const [html2, setHtml] = useState22("");
29432
+ const [previewMode, setPreviewMode] = useState22("desktop");
29433
+ const iframeRef = useRef23(null);
29434
+ useEffect16(() => {
28578
29435
  let cancelled = false;
28579
29436
  const timer = setTimeout(() => {
28580
29437
  async function compile() {
@@ -28591,7 +29448,7 @@ function PreviewPanel() {
28591
29448
  clearTimeout(timer);
28592
29449
  };
28593
29450
  }, [template]);
28594
- useEffect15(() => {
29451
+ useEffect16(() => {
28595
29452
  if (iframeRef.current && html2) {
28596
29453
  const doc3 = iframeRef.current.contentDocument;
28597
29454
  if (doc3) {
@@ -28601,9 +29458,9 @@ function PreviewPanel() {
28601
29458
  }
28602
29459
  }
28603
29460
  }, [html2]);
28604
- return /* @__PURE__ */ jsxs42("div", { className: `ee-preview ${preview_default.preview}`, children: [
28605
- /* @__PURE__ */ jsxs42("div", { className: `ee-preview-toggles ${preview_default.previewToggles}`, role: "group", "aria-label": "Preview size", children: [
28606
- /* @__PURE__ */ jsx52(
29461
+ return /* @__PURE__ */ jsxs45("div", { className: `ee-preview ${preview_default.preview}`, children: [
29462
+ /* @__PURE__ */ jsxs45("div", { className: `ee-preview-toggles ${preview_default.previewToggles}`, role: "group", "aria-label": "Preview size", children: [
29463
+ /* @__PURE__ */ jsx56(
28607
29464
  "button",
28608
29465
  {
28609
29466
  className: `ee-preview-toggle ee-preview-toggle--desktop ${preview_default.previewToggle} ${preview_default.previewToggleDesktop} ${previewMode === "desktop" ? `ee-preview-toggle--active ${preview_default.previewToggleActive}` : ""}`,
@@ -28613,7 +29470,7 @@ function PreviewPanel() {
28613
29470
  children: "Desktop"
28614
29471
  }
28615
29472
  ),
28616
- /* @__PURE__ */ jsx52(
29473
+ /* @__PURE__ */ jsx56(
28617
29474
  "button",
28618
29475
  {
28619
29476
  className: `ee-preview-toggle ee-preview-toggle--mobile ${preview_default.previewToggle} ${preview_default.previewToggleMobile} ${previewMode === "mobile" ? `ee-preview-toggle--active ${preview_default.previewToggleActive}` : ""}`,
@@ -28624,7 +29481,7 @@ function PreviewPanel() {
28624
29481
  }
28625
29482
  )
28626
29483
  ] }),
28627
- /* @__PURE__ */ jsx52("div", { className: `ee-preview-container ${preview_default.previewContainer}`, children: /* @__PURE__ */ jsx52(
29484
+ /* @__PURE__ */ jsx56("div", { className: `ee-preview-container ${preview_default.previewContainer}`, children: /* @__PURE__ */ jsx56(
28628
29485
  "iframe",
28629
29486
  {
28630
29487
  className: `ee-preview-iframe ${preview_default.previewIframe}`,
@@ -28638,7 +29495,7 @@ function PreviewPanel() {
28638
29495
  }
28639
29496
 
28640
29497
  // src/components/SourceEditor/SourceEditor.tsx
28641
- import { useState as useState19, useCallback as useCallback34, useEffect as useEffect16 } from "react";
29498
+ import { useState as useState23, useCallback as useCallback36, useEffect as useEffect17 } from "react";
28642
29499
 
28643
29500
  // src/styles/source-editor.module.css
28644
29501
  var source_editor_default = {
@@ -28651,16 +29508,16 @@ var source_editor_default = {
28651
29508
  };
28652
29509
 
28653
29510
  // src/components/SourceEditor/SourceEditor.tsx
28654
- import { jsx as jsx53, jsxs as jsxs43 } from "react/jsx-runtime";
29511
+ import { jsx as jsx57, jsxs as jsxs46 } from "react/jsx-runtime";
28655
29512
  function SourceEditor() {
28656
29513
  const { template } = useTemplateContext();
28657
29514
  const dispatch = useEditorDispatch();
28658
- const [source, setSource] = useState19("");
28659
- const [error, setError] = useState19(null);
28660
- useEffect16(() => {
29515
+ const [source, setSource] = useState23("");
29516
+ const [error, setError] = useState23(null);
29517
+ useEffect17(() => {
28661
29518
  setSource(generateMJML(template));
28662
29519
  }, [template]);
28663
- const handleApply = useCallback34(() => {
29520
+ const handleApply = useCallback36(() => {
28664
29521
  try {
28665
29522
  const template2 = parseMJML(source);
28666
29523
  dispatch({ type: "SET_TEMPLATE", payload: template2 });
@@ -28669,10 +29526,10 @@ function SourceEditor() {
28669
29526
  setError(err.message);
28670
29527
  }
28671
29528
  }, [source, dispatch]);
28672
- return /* @__PURE__ */ jsxs43("div", { className: `ee-source-editor ${source_editor_default.sourceEditor}`, children: [
28673
- /* @__PURE__ */ jsxs43("div", { className: `ee-source-header ${source_editor_default.sourceHeader}`, children: [
28674
- /* @__PURE__ */ jsx53("span", { className: `ee-source-label ${source_editor_default.sourceLabel}`, children: "MJML Source" }),
28675
- /* @__PURE__ */ jsx53(
29529
+ return /* @__PURE__ */ jsxs46("div", { className: `ee-source-editor ${source_editor_default.sourceEditor}`, children: [
29530
+ /* @__PURE__ */ jsxs46("div", { className: `ee-source-header ${source_editor_default.sourceHeader}`, children: [
29531
+ /* @__PURE__ */ jsx57("span", { className: `ee-source-label ${source_editor_default.sourceLabel}`, children: "MJML Source" }),
29532
+ /* @__PURE__ */ jsx57(
28676
29533
  "button",
28677
29534
  {
28678
29535
  className: `ee-source-apply ${source_editor_default.sourceApply}`,
@@ -28681,8 +29538,8 @@ function SourceEditor() {
28681
29538
  }
28682
29539
  )
28683
29540
  ] }),
28684
- error && /* @__PURE__ */ jsx53("div", { className: `ee-source-error ${source_editor_default.sourceError}`, children: error }),
28685
- /* @__PURE__ */ jsx53(
29541
+ error && /* @__PURE__ */ jsx57("div", { className: `ee-source-error ${source_editor_default.sourceError}`, children: error }),
29542
+ /* @__PURE__ */ jsx57(
28686
29543
  "textarea",
28687
29544
  {
28688
29545
  className: `ee-source-textarea ${source_editor_default.sourceTextarea}`,
@@ -28695,30 +29552,30 @@ function SourceEditor() {
28695
29552
  }
28696
29553
 
28697
29554
  // src/components/EmailEditor.tsx
28698
- import { Fragment as Fragment2, jsx as jsx54, jsxs as jsxs44 } from "react/jsx-runtime";
29555
+ import { Fragment as Fragment5, jsx as jsx58, jsxs as jsxs47 } from "react/jsx-runtime";
28699
29556
  var EditorInner = forwardRef2(function EditorInner2(props, ref) {
28700
29557
  const dispatch = useEditorDispatch();
28701
29558
  const { template, activeTab } = useTemplateContext();
28702
29559
  const selection = useSelectionContext();
28703
29560
  const { clearPersisted } = useConfigContext();
28704
- const containerRef = useRef21(null);
29561
+ const containerRef = useRef24(null);
28705
29562
  const { onReady, onSave } = props;
28706
- const [sidebarOpen, setSidebarOpen] = useState20(false);
28707
- const [propertiesOpen, setPropertiesOpen] = useState20(false);
28708
- const [pendingRemoval, setPendingRemoval] = useState20(null);
28709
- const toggleSidebar = useCallback35(() => {
29563
+ const [sidebarOpen, setSidebarOpen] = useState24(false);
29564
+ const [propertiesOpen, setPropertiesOpen] = useState24(false);
29565
+ const [pendingRemoval, setPendingRemoval] = useState24(null);
29566
+ const toggleSidebar = useCallback37(() => {
28710
29567
  setSidebarOpen((prev) => !prev);
28711
29568
  setPropertiesOpen(false);
28712
29569
  }, []);
28713
- const toggleProperties = useCallback35(() => {
29570
+ const toggleProperties = useCallback37(() => {
28714
29571
  setPropertiesOpen((prev) => !prev);
28715
29572
  setSidebarOpen(false);
28716
29573
  }, []);
28717
- const closeOverlays = useCallback35(() => {
29574
+ const closeOverlays = useCallback37(() => {
28718
29575
  setSidebarOpen(false);
28719
29576
  setPropertiesOpen(false);
28720
29577
  }, []);
28721
- useEffect17(() => {
29578
+ useEffect18(() => {
28722
29579
  if (selection.blockId) {
28723
29580
  if (typeof window !== "undefined" && window.innerWidth < 1024) {
28724
29581
  setPropertiesOpen(true);
@@ -28726,16 +29583,16 @@ var EditorInner = forwardRef2(function EditorInner2(props, ref) {
28726
29583
  }
28727
29584
  }
28728
29585
  }, [selection.blockId]);
28729
- useEffect17(() => {
29586
+ useEffect18(() => {
28730
29587
  onReady?.();
28731
29588
  }, []);
28732
- const templateRef = useRef21(template);
29589
+ const templateRef = useRef24(template);
28733
29590
  templateRef.current = template;
28734
- const selectionRef = useRef21(selection);
29591
+ const selectionRef = useRef24(selection);
28735
29592
  selectionRef.current = selection;
28736
- const onSaveRef = useRef21(onSave);
29593
+ const onSaveRef = useRef24(onSave);
28737
29594
  onSaveRef.current = onSave;
28738
- useEffect17(() => {
29595
+ useEffect18(() => {
28739
29596
  const el = containerRef.current;
28740
29597
  if (!el) return;
28741
29598
  const handler = (e) => {
@@ -28780,7 +29637,7 @@ var EditorInner = forwardRef2(function EditorInner2(props, ref) {
28780
29637
  el.addEventListener("keydown", handler);
28781
29638
  return () => el.removeEventListener("keydown", handler);
28782
29639
  }, [dispatch]);
28783
- const handleConfirmRemoval = useCallback35(() => {
29640
+ const handleConfirmRemoval = useCallback37(() => {
28784
29641
  if (!pendingRemoval) return;
28785
29642
  if (pendingRemoval.type === "block") {
28786
29643
  dispatch({ type: "REMOVE_BLOCK", payload: pendingRemoval });
@@ -28873,8 +29730,8 @@ var EditorInner = forwardRef2(function EditorInner2(props, ref) {
28873
29730
  editor_default.panelOverlay,
28874
29731
  sidebarOpen || propertiesOpen ? editor_default.panelOverlayVisible : ""
28875
29732
  ].filter(Boolean).join(" ");
28876
- return /* @__PURE__ */ jsxs44("div", { ref: containerRef, className: `ee-editor ${editor_default.editorContainer}`, tabIndex: -1, children: [
28877
- pendingRemoval && /* @__PURE__ */ jsx54(
29733
+ return /* @__PURE__ */ jsxs47("div", { ref: containerRef, className: `ee-editor ${editor_default.editorContainer}`, tabIndex: -1, children: [
29734
+ pendingRemoval && /* @__PURE__ */ jsx58(
28878
29735
  ConfirmDialog,
28879
29736
  {
28880
29737
  title: pendingRemoval.type === "block" ? "Remove Block" : "Remove Section",
@@ -28883,7 +29740,7 @@ var EditorInner = forwardRef2(function EditorInner2(props, ref) {
28883
29740
  onCancel: () => setPendingRemoval(null)
28884
29741
  }
28885
29742
  ),
28886
- /* @__PURE__ */ jsx54(
29743
+ /* @__PURE__ */ jsx58(
28887
29744
  Toolbar,
28888
29745
  {
28889
29746
  sidebarOpen,
@@ -28892,18 +29749,18 @@ var EditorInner = forwardRef2(function EditorInner2(props, ref) {
28892
29749
  onToggleProperties: toggleProperties
28893
29750
  }
28894
29751
  ),
28895
- /* @__PURE__ */ jsxs44("div", { className: editor_default.editorBody, children: [
28896
- activeTab === "visual" && /* @__PURE__ */ jsxs44(Fragment2, { children: [
28897
- /* @__PURE__ */ jsx54("div", { className: `ee-sidebar ${sidebarClasses}`, children: /* @__PURE__ */ jsx54(ErrorBoundary, { children: /* @__PURE__ */ jsx54(Sidebar, { blockDefinitions: props.blockDefinitions }) }) }),
28898
- /* @__PURE__ */ jsx54("div", { className: `ee-canvas ${editor_default.editorPanel} ${editor_default.canvasPanel}`, children: /* @__PURE__ */ jsx54(ErrorBoundary, { children: /* @__PURE__ */ jsx54(Canvas, {}) }) }),
28899
- /* @__PURE__ */ jsx54("div", { className: `ee-properties ${propertiesClasses}`, children: /* @__PURE__ */ jsx54(ErrorBoundary, { children: /* @__PURE__ */ jsx54(PropertiesPanel, {}) }) }),
28900
- /* @__PURE__ */ jsx54("div", { className: overlayClasses, onClick: closeOverlays })
29752
+ /* @__PURE__ */ jsxs47("div", { className: editor_default.editorBody, children: [
29753
+ activeTab === "visual" && /* @__PURE__ */ jsxs47(Fragment5, { children: [
29754
+ /* @__PURE__ */ jsx58("div", { className: `ee-sidebar ${sidebarClasses}`, children: /* @__PURE__ */ jsx58(ErrorBoundary, { children: /* @__PURE__ */ jsx58(Sidebar, { blockDefinitions: props.blockDefinitions }) }) }),
29755
+ /* @__PURE__ */ jsx58("div", { className: `ee-canvas ${editor_default.editorPanel} ${editor_default.canvasPanel}`, children: /* @__PURE__ */ jsx58(ErrorBoundary, { children: /* @__PURE__ */ jsx58(Canvas, {}) }) }),
29756
+ /* @__PURE__ */ jsx58("div", { className: `ee-properties ${propertiesClasses}`, children: /* @__PURE__ */ jsx58(ErrorBoundary, { children: /* @__PURE__ */ jsx58(PropertiesPanel, {}) }) }),
29757
+ /* @__PURE__ */ jsx58("div", { className: overlayClasses, onClick: closeOverlays })
28901
29758
  ] }),
28902
- activeTab === "source" && /* @__PURE__ */ jsxs44("div", { className: `ee-source-layout ${editor_default.sourceLayout}`, children: [
28903
- /* @__PURE__ */ jsx54("div", { className: `ee-source-pane ${editor_default.sourcePane}`, children: /* @__PURE__ */ jsx54(ErrorBoundary, { children: /* @__PURE__ */ jsx54(SourceEditor, {}) }) }),
28904
- /* @__PURE__ */ jsx54("div", { className: `ee-preview-pane ${editor_default.sourcePaneDivider}`, children: /* @__PURE__ */ jsx54(ErrorBoundary, { children: /* @__PURE__ */ jsx54(PreviewPanel, {}) }) })
29759
+ activeTab === "source" && /* @__PURE__ */ jsxs47("div", { className: `ee-source-layout ${editor_default.sourceLayout}`, children: [
29760
+ /* @__PURE__ */ jsx58("div", { className: `ee-source-pane ${editor_default.sourcePane}`, children: /* @__PURE__ */ jsx58(ErrorBoundary, { children: /* @__PURE__ */ jsx58(SourceEditor, {}) }) }),
29761
+ /* @__PURE__ */ jsx58("div", { className: `ee-preview-pane ${editor_default.sourcePaneDivider}`, children: /* @__PURE__ */ jsx58(ErrorBoundary, { children: /* @__PURE__ */ jsx58(PreviewPanel, {}) }) })
28905
29762
  ] }),
28906
- activeTab === "preview" && /* @__PURE__ */ jsx54(ErrorBoundary, { children: /* @__PURE__ */ jsx54(PreviewPanel, {}) })
29763
+ activeTab === "preview" && /* @__PURE__ */ jsx58(ErrorBoundary, { children: /* @__PURE__ */ jsx58(PreviewPanel, {}) })
28907
29764
  ] })
28908
29765
  ] });
28909
29766
  });
@@ -28919,6 +29776,8 @@ var EmailEditor = forwardRef2(
28919
29776
  onVariablesChange,
28920
29777
  fontFamilies,
28921
29778
  fontSizes,
29779
+ colorPresets,
29780
+ onColorPresetsChange,
28922
29781
  persistenceKey,
28923
29782
  persistenceAdapter,
28924
29783
  className,
@@ -28940,7 +29799,7 @@ var EmailEditor = forwardRef2(
28940
29799
  template = void 0;
28941
29800
  }
28942
29801
  }
28943
- return /* @__PURE__ */ jsx54(
29802
+ return /* @__PURE__ */ jsx58(
28944
29803
  EditorProvider,
28945
29804
  {
28946
29805
  initialTemplate: template,
@@ -28951,6 +29810,8 @@ var EmailEditor = forwardRef2(
28951
29810
  onVariablesChange,
28952
29811
  fontFamilies,
28953
29812
  fontSizes,
29813
+ colorPresets,
29814
+ onColorPresetsChange,
28954
29815
  persistenceKey,
28955
29816
  persistenceAdapter,
28956
29817
  onBlockAdd,
@@ -28961,7 +29822,7 @@ var EmailEditor = forwardRef2(
28961
29822
  onSelectionChange,
28962
29823
  onTemplateLoad,
28963
29824
  onHistoryChange,
28964
- children: /* @__PURE__ */ jsx54("div", { className: `ee-editor-wrapper ${editor_default.editorWrapper} ${className || ""}`, style: style2, children: /* @__PURE__ */ jsx54(EditorInner, { ref, ...props }) })
29825
+ children: /* @__PURE__ */ jsx58("div", { className: `ee-editor-wrapper ${editor_default.editorWrapper} ${className || ""}`, style: style2, children: /* @__PURE__ */ jsx58(EditorInner, { ref, ...props }) })
28965
29826
  }
28966
29827
  );
28967
29828
  }