@kgalexander/mcreate 0.0.16 → 0.0.17

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/dist/index.mjs CHANGED
@@ -60,7 +60,7 @@ import {
60
60
  setupDragImage,
61
61
  useEditorStore,
62
62
  useSidebarContext
63
- } from "./chunk-L3OWFBEU.mjs";
63
+ } from "./chunk-GZLWB3EZ.mjs";
64
64
 
65
65
  // src/core/editor/components/email-template-v2/header.tsx
66
66
  import { ArrowLeftIcon, CopyIcon, MegaphoneIcon, MoreHorizontalIcon, PencilIcon, SendIcon, TrashIcon } from "lucide-react";
@@ -2742,22 +2742,55 @@ var ColorPicker = ({
2742
2742
  );
2743
2743
  const [alpha, setAlpha] = useState6(selectedColor.alpha() * 100 || defaultColor.alpha() * 100);
2744
2744
  const [mode, setMode] = useState6("hex");
2745
+ const hueRef = useRef3(hue);
2746
+ const saturationRef = useRef3(saturation);
2747
+ const lightnessRef = useRef3(lightness);
2748
+ const alphaRef = useRef3(alpha);
2749
+ hueRef.current = hue;
2750
+ saturationRef.current = saturation;
2751
+ lightnessRef.current = lightness;
2752
+ alphaRef.current = alpha;
2745
2753
  useEffect3(() => {
2746
2754
  if (value) {
2747
- const color = Color.rgb(value).rgb().object();
2748
- setHue(color.r);
2749
- setSaturation(color.g);
2750
- setLightness(color.b);
2751
- setAlpha(color.a);
2755
+ const color = Color(value);
2756
+ const hsl = color.hsl().object();
2757
+ setHue(hsl.h);
2758
+ setSaturation(hsl.s);
2759
+ setLightness(hsl.l);
2760
+ setAlpha(color.alpha() * 100);
2761
+ hueRef.current = hsl.h;
2762
+ saturationRef.current = hsl.s;
2763
+ lightnessRef.current = hsl.l;
2764
+ alphaRef.current = color.alpha() * 100;
2752
2765
  }
2753
2766
  }, [value]);
2754
- useEffect3(() => {
2767
+ const updateColor = useCallback15((updates) => {
2768
+ const newH = updates.h ?? hueRef.current;
2769
+ const newS = updates.s ?? saturationRef.current;
2770
+ const newL = updates.l ?? lightnessRef.current;
2771
+ const newA = updates.a ?? alphaRef.current;
2772
+ if (updates.h !== void 0) {
2773
+ setHue(updates.h);
2774
+ hueRef.current = updates.h;
2775
+ }
2776
+ if (updates.s !== void 0) {
2777
+ setSaturation(updates.s);
2778
+ saturationRef.current = updates.s;
2779
+ }
2780
+ if (updates.l !== void 0) {
2781
+ setLightness(updates.l);
2782
+ lightnessRef.current = updates.l;
2783
+ }
2784
+ if (updates.a !== void 0) {
2785
+ setAlpha(updates.a);
2786
+ alphaRef.current = updates.a;
2787
+ }
2755
2788
  if (onChange) {
2756
- const color = Color.hsl(hue, saturation, lightness).alpha(alpha / 100);
2789
+ const color = Color.hsl(newH, newS, newL).alpha(newA / 100);
2757
2790
  const rgba = color.rgb().array();
2758
- onChange([rgba[0], rgba[1], rgba[2], alpha / 100]);
2791
+ onChange([rgba[0], rgba[1], rgba[2], newA / 100]);
2759
2792
  }
2760
- }, [hue, saturation, lightness, alpha, onChange]);
2793
+ }, [onChange]);
2761
2794
  return /* @__PURE__ */ jsx25(
2762
2795
  ColorPickerContext.Provider,
2763
2796
  {
@@ -2767,10 +2800,7 @@ var ColorPicker = ({
2767
2800
  lightness,
2768
2801
  alpha,
2769
2802
  mode,
2770
- setHue,
2771
- setSaturation,
2772
- setLightness,
2773
- setAlpha,
2803
+ updateColor,
2774
2804
  setMode
2775
2805
  },
2776
2806
  children: /* @__PURE__ */ jsx25("div", { className: cn("flex size-full flex-col gap-4", className), ...props })
@@ -2782,7 +2812,7 @@ var ColorPickerSelection = memo(({ className, ...props }) => {
2782
2812
  const [isDragging, setIsDragging] = useState6(false);
2783
2813
  const [positionX, setPositionX] = useState6(0);
2784
2814
  const [positionY, setPositionY] = useState6(0);
2785
- const { hue, setSaturation, setLightness } = useColorPicker();
2815
+ const { hue, updateColor } = useColorPicker();
2786
2816
  const backgroundGradient = useMemo4(() => {
2787
2817
  return `linear-gradient(0deg, rgba(0,0,0,1), rgba(0,0,0,0)),
2788
2818
  linear-gradient(90deg, rgba(255,255,255,1), rgba(255,255,255,0)),
@@ -2798,12 +2828,12 @@ var ColorPickerSelection = memo(({ className, ...props }) => {
2798
2828
  const y = Math.max(0, Math.min(1, (event.clientY - rect.top) / rect.height));
2799
2829
  setPositionX(x);
2800
2830
  setPositionY(y);
2801
- setSaturation(x * 100);
2831
+ const newSaturation = x * 100;
2802
2832
  const topLightness = x < 0.01 ? 100 : 50 + 50 * (1 - x);
2803
- const lightness = topLightness * (1 - y);
2804
- setLightness(lightness);
2833
+ const newLightness = topLightness * (1 - y);
2834
+ updateColor({ s: newSaturation, l: newLightness });
2805
2835
  },
2806
- [isDragging, setSaturation, setLightness]
2836
+ [isDragging, updateColor]
2807
2837
  );
2808
2838
  useEffect3(() => {
2809
2839
  const handlePointerUp = () => setIsDragging(false);
@@ -2846,13 +2876,13 @@ var ColorPickerSelection = memo(({ className, ...props }) => {
2846
2876
  });
2847
2877
  ColorPickerSelection.displayName = "ColorPickerSelection";
2848
2878
  var ColorPickerHue = ({ className, ...props }) => {
2849
- const { hue, setHue } = useColorPicker();
2879
+ const { hue, updateColor } = useColorPicker();
2850
2880
  return /* @__PURE__ */ jsxs23(
2851
2881
  Slider.Root,
2852
2882
  {
2853
2883
  className: cn("relative flex h-4 w-full touch-none", className),
2854
2884
  max: 360,
2855
- onValueChange: ([hue2]) => setHue(hue2),
2885
+ onValueChange: ([h]) => updateColor({ h }),
2856
2886
  step: 1,
2857
2887
  value: [hue],
2858
2888
  ...props,
@@ -2864,17 +2894,14 @@ var ColorPickerHue = ({ className, ...props }) => {
2864
2894
  );
2865
2895
  };
2866
2896
  var ColorPickerEyeDropper = ({ className, ...props }) => {
2867
- const { setHue, setSaturation, setLightness, setAlpha } = useColorPicker();
2897
+ const { updateColor } = useColorPicker();
2868
2898
  const handleEyeDropper = async () => {
2869
2899
  try {
2870
2900
  const eyeDropper = new EyeDropper();
2871
2901
  const result = await eyeDropper.open();
2872
2902
  const color = Color(result.sRGBHex);
2873
2903
  const [h, s, l] = color.hsl().array();
2874
- setHue(h);
2875
- setSaturation(s);
2876
- setLightness(l);
2877
- setAlpha(100);
2904
+ updateColor({ h, s, l, a: 100 });
2878
2905
  } catch (error) {
2879
2906
  console.error("EyeDropper failed:", error);
2880
2907
  }
@@ -4037,11 +4064,13 @@ function TemplateSidebar({ editorLoading }) {
4037
4064
  attributes: { ...element.attributes, [attributeName]: imageSrc }
4038
4065
  });
4039
4066
  }, [imageTarget]);
4040
- useEffect4(() => {
4067
+ const prevActiveViewRef = useRef6(activeView);
4068
+ if (activeView !== prevActiveViewRef.current) {
4069
+ prevActiveViewRef.current = activeView;
4041
4070
  if (PICKER_VIEWS.has(activeView)) {
4042
4071
  setOpenSidebar(true);
4043
4072
  }
4044
- }, [activeView]);
4073
+ }
4045
4074
  const handleCloseSidebar = () => setOpenSidebar(!openSidebar);
4046
4075
  const handleViewClick = (view) => {
4047
4076
  setActiveView(view);
@@ -4309,7 +4338,7 @@ var PlainToolbar = () => {
4309
4338
  };
4310
4339
 
4311
4340
  // src/core/editor/components/element-gear/text/toolbar.tsx
4312
- import { useEffect as useEffect10, useState as useState16, useCallback as useCallback26, useMemo as useMemo14 } from "react";
4341
+ import { useEffect as useEffect6, useState as useState17, useCallback as useCallback27, useMemo as useMemo14 } from "react";
4313
4342
  import { BoldIcon, BracesIcon, CaseUpperIcon, CheckIcon as CheckIcon5, EllipsisIcon, HighlighterIcon, ItalicIcon, Strikethrough, Underline } from "lucide-react";
4314
4343
 
4315
4344
  // src/core/editor/components/paragraph-text-settings.tsx
@@ -4377,12 +4406,78 @@ function Slider2({
4377
4406
  }
4378
4407
 
4379
4408
  // src/core/editor/components/paragraph-text-settings.tsx
4380
- import { useState as useState11, useEffect as useEffect5, useMemo as useMemo11, useCallback as useCallback21, memo as memo2 } from "react";
4409
+ import { useState as useState12, useEffect as useEffect5, useMemo as useMemo11, useCallback as useCallback22, memo as memo2 } from "react";
4410
+
4411
+ // src/core/editor/hooks/use-editable-value.ts
4412
+ import { useState as useState11, useCallback as useCallback21 } from "react";
4413
+ function useEditableValue(options) {
4414
+ const { externalValue, onChange, toLocal, toExternal } = options;
4415
+ const convert = toLocal ?? String;
4416
+ const [localValue, setLocalValue] = useState11(convert(externalValue));
4417
+ const [isFocused, setIsFocused] = useState11(false);
4418
+ const displayValue = isFocused ? localValue : convert(externalValue);
4419
+ const handleFocus = useCallback21(() => {
4420
+ setLocalValue(convert(externalValue));
4421
+ setIsFocused(true);
4422
+ }, [externalValue, convert]);
4423
+ const handleBlur = useCallback21(() => {
4424
+ setIsFocused(false);
4425
+ if (toExternal) {
4426
+ const parsed = toExternal(localValue);
4427
+ if (parsed !== null) {
4428
+ onChange(parsed);
4429
+ }
4430
+ } else {
4431
+ onChange(localValue);
4432
+ }
4433
+ }, [localValue, toExternal, onChange]);
4434
+ const handleKeyDown = useCallback21((e) => {
4435
+ if (e.key === "Enter") {
4436
+ e.currentTarget.blur();
4437
+ }
4438
+ }, []);
4439
+ return {
4440
+ displayValue,
4441
+ setLocalValue,
4442
+ handleFocus,
4443
+ handleBlur,
4444
+ handleKeyDown,
4445
+ isFocused
4446
+ };
4447
+ }
4448
+ function useEditableNumber(options) {
4449
+ const { value, onChange, min = -Infinity, max = Infinity } = options;
4450
+ return useEditableValue({
4451
+ externalValue: value,
4452
+ onChange,
4453
+ toLocal: (n) => n.toString(),
4454
+ toExternal: (s) => {
4455
+ const parsed = parseInt(s, 10);
4456
+ if (isNaN(parsed)) return null;
4457
+ return Math.max(min, Math.min(max, parsed));
4458
+ }
4459
+ });
4460
+ }
4461
+ function useEditableFloat(options) {
4462
+ const { value, onChange, min = -Infinity, max = Infinity } = options;
4463
+ return useEditableValue({
4464
+ externalValue: value,
4465
+ onChange,
4466
+ toLocal: (n) => n.toString(),
4467
+ toExternal: (s) => {
4468
+ const parsed = parseFloat(s);
4469
+ if (isNaN(parsed) || s === "") return null;
4470
+ return Math.max(min, Math.min(max, parsed));
4471
+ }
4472
+ });
4473
+ }
4474
+
4475
+ // src/core/editor/components/paragraph-text-settings.tsx
4381
4476
  import { jsx as jsx39, jsxs as jsxs31 } from "react/jsx-runtime";
4382
4477
  var ParagraphTextSettings = memo2(function ParagraphTextSettings2() {
4383
- const [isOpen, setIsOpen] = useState11(false);
4478
+ const [isOpen, setIsOpen] = useState12(false);
4384
4479
  const tiptapEditor = useEditorStore((s) => s.tiptapEditor);
4385
- const [updateCounter, forceUpdate] = useState11(0);
4480
+ const [updateCounter, forceUpdate] = useState12(0);
4386
4481
  useEffect5(() => {
4387
4482
  if (!tiptapEditor) return;
4388
4483
  const handler = () => forceUpdate((n) => n + 1);
@@ -4409,92 +4504,34 @@ var ParagraphTextSettings = memo2(function ParagraphTextSettings2() {
4409
4504
  }
4410
4505
  return DEFAULT_LINE_HEIGHT;
4411
4506
  }, [tiptapEditor, updateCounter]);
4412
- const [letterSpacingInputValue, setLetterSpacingInputValue] = useState11(
4413
- String(currentLetterSpacing)
4414
- );
4415
- const [isLetterSpacingInputFocused, setIsLetterSpacingInputFocused] = useState11(false);
4416
- const [lineHeightInputValue, setLineHeightInputValue] = useState11(
4417
- String(currentLineHeight)
4418
- );
4419
- const [isLineHeightInputFocused, setIsLineHeightInputFocused] = useState11(false);
4420
- useEffect5(() => {
4421
- if (!isLetterSpacingInputFocused) {
4422
- setLetterSpacingInputValue(String(currentLetterSpacing));
4423
- }
4424
- }, [currentLetterSpacing, isLetterSpacingInputFocused]);
4425
- useEffect5(() => {
4426
- if (!isLineHeightInputFocused) {
4427
- setLineHeightInputValue(String(currentLineHeight));
4428
- }
4429
- }, [currentLineHeight, isLineHeightInputFocused]);
4430
- const handleLetterSpacingSliderChange = useCallback21((values) => {
4507
+ const commitLetterSpacing = useCallback22((value) => {
4431
4508
  if (!tiptapEditor) return;
4432
- const value = values[0];
4433
- setLetterSpacingInputValue(String(value));
4434
4509
  tiptapEditor.chain().setLetterSpacing(`${value}px`).run();
4435
4510
  forceUpdate((n) => n + 1);
4436
4511
  }, [tiptapEditor]);
4437
- const handleLetterSpacingInputChange = useCallback21((e) => {
4438
- setLetterSpacingInputValue(e.target.value);
4439
- }, []);
4440
- const applyLetterSpacing = useCallback21(() => {
4441
- if (!tiptapEditor) return;
4442
- const parsed = parseFloat(letterSpacingInputValue);
4443
- if (isNaN(parsed) || letterSpacingInputValue === "") {
4444
- setLetterSpacingInputValue(String(currentLetterSpacing));
4445
- tiptapEditor.chain().focus().run();
4446
- return;
4447
- }
4448
- const clampedValue = Math.max(MIN_LETTER_SPACING, Math.min(parsed, MAX_LETTER_SPACING));
4449
- setLetterSpacingInputValue(String(clampedValue));
4450
- tiptapEditor.chain().focus().setLetterSpacing(`${clampedValue}px`).run();
4451
- forceUpdate((n) => n + 1);
4452
- }, [tiptapEditor, letterSpacingInputValue, currentLetterSpacing]);
4453
- const handleLetterSpacingInputBlur = useCallback21(() => {
4454
- setIsLetterSpacingInputFocused(false);
4455
- applyLetterSpacing();
4456
- }, [applyLetterSpacing]);
4457
- const handleLetterSpacingInputKeyDown = useCallback21((e) => {
4458
- if (e.key === "Enter") {
4459
- e.preventDefault();
4460
- applyLetterSpacing();
4461
- e.target.blur();
4462
- }
4463
- }, [applyLetterSpacing]);
4464
- const handleLineHeightSliderChange = useCallback21((values) => {
4512
+ const commitLineHeight = useCallback22((value) => {
4465
4513
  if (!tiptapEditor) return;
4466
- const value = values[0];
4467
- setLineHeightInputValue(String(value));
4468
4514
  tiptapEditor.chain().setLineHeight(String(value)).run();
4469
4515
  forceUpdate((n) => n + 1);
4470
4516
  }, [tiptapEditor]);
4471
- const handleLineHeightInputChange = useCallback21((e) => {
4472
- setLineHeightInputValue(e.target.value);
4473
- }, []);
4474
- const applyLineHeight = useCallback21(() => {
4475
- if (!tiptapEditor) return;
4476
- const parsed = parseFloat(lineHeightInputValue);
4477
- if (isNaN(parsed) || lineHeightInputValue === "") {
4478
- setLineHeightInputValue(String(currentLineHeight));
4479
- tiptapEditor.chain().focus().run();
4480
- return;
4481
- }
4482
- const clampedValue = Math.max(MIN_LINE_HEIGHT, Math.min(parsed, MAX_LINE_HEIGHT));
4483
- setLineHeightInputValue(String(clampedValue));
4484
- tiptapEditor.chain().focus().setLineHeight(String(clampedValue)).run();
4485
- forceUpdate((n) => n + 1);
4486
- }, [tiptapEditor, lineHeightInputValue, currentLineHeight]);
4487
- const handleLineHeightInputBlur = useCallback21(() => {
4488
- setIsLineHeightInputFocused(false);
4489
- applyLineHeight();
4490
- }, [applyLineHeight]);
4491
- const handleLineHeightInputKeyDown = useCallback21((e) => {
4492
- if (e.key === "Enter") {
4493
- e.preventDefault();
4494
- applyLineHeight();
4495
- e.target.blur();
4496
- }
4497
- }, [applyLineHeight]);
4517
+ const letterSpacingInput = useEditableFloat({
4518
+ value: currentLetterSpacing,
4519
+ onChange: commitLetterSpacing,
4520
+ min: MIN_LETTER_SPACING,
4521
+ max: MAX_LETTER_SPACING
4522
+ });
4523
+ const lineHeightInput = useEditableFloat({
4524
+ value: currentLineHeight,
4525
+ onChange: commitLineHeight,
4526
+ min: MIN_LINE_HEIGHT,
4527
+ max: MAX_LINE_HEIGHT
4528
+ });
4529
+ const handleLetterSpacingSliderChange = useCallback22((values) => {
4530
+ commitLetterSpacing(values[0]);
4531
+ }, [commitLetterSpacing]);
4532
+ const handleLineHeightSliderChange = useCallback22((values) => {
4533
+ commitLineHeight(values[0]);
4534
+ }, [commitLineHeight]);
4498
4535
  return /* @__PURE__ */ jsxs31(Tooltip, { children: [
4499
4536
  /* @__PURE__ */ jsxs31(Popover, { open: isOpen, onOpenChange: setIsOpen, children: [
4500
4537
  /* @__PURE__ */ jsx39(PopoverTrigger, { asChild: true, children: /* @__PURE__ */ jsx39(TooltipTrigger, { asChild: true, children: /* @__PURE__ */ jsx39(
@@ -4531,11 +4568,11 @@ var ParagraphTextSettings = memo2(function ParagraphTextSettings2() {
4531
4568
  Input,
4532
4569
  {
4533
4570
  type: "number",
4534
- value: letterSpacingInputValue,
4535
- onChange: handleLetterSpacingInputChange,
4536
- onFocus: () => setIsLetterSpacingInputFocused(true),
4537
- onBlur: handleLetterSpacingInputBlur,
4538
- onKeyDown: handleLetterSpacingInputKeyDown,
4571
+ value: letterSpacingInput.displayValue,
4572
+ onChange: (e) => letterSpacingInput.setLocalValue(e.target.value),
4573
+ onFocus: letterSpacingInput.handleFocus,
4574
+ onBlur: letterSpacingInput.handleBlur,
4575
+ onKeyDown: letterSpacingInput.handleKeyDown,
4539
4576
  className: "w-25 shadow-none rounded-[12px]",
4540
4577
  min: MIN_LETTER_SPACING,
4541
4578
  max: MAX_LETTER_SPACING,
@@ -4562,11 +4599,11 @@ var ParagraphTextSettings = memo2(function ParagraphTextSettings2() {
4562
4599
  Input,
4563
4600
  {
4564
4601
  type: "number",
4565
- value: lineHeightInputValue,
4566
- onChange: handleLineHeightInputChange,
4567
- onFocus: () => setIsLineHeightInputFocused(true),
4568
- onBlur: handleLineHeightInputBlur,
4569
- onKeyDown: handleLineHeightInputKeyDown,
4602
+ value: lineHeightInput.displayValue,
4603
+ onChange: (e) => lineHeightInput.setLocalValue(e.target.value),
4604
+ onFocus: lineHeightInput.handleFocus,
4605
+ onBlur: lineHeightInput.handleBlur,
4606
+ onKeyDown: lineHeightInput.handleKeyDown,
4570
4607
  className: "w-25 shadow-none rounded-[12px]",
4571
4608
  min: MIN_LINE_HEIGHT,
4572
4609
  max: MAX_LINE_HEIGHT,
@@ -4630,7 +4667,7 @@ var FontFamilyDropdown = ({
4630
4667
  };
4631
4668
 
4632
4669
  // src/core/editor/components/font-size-control.tsx
4633
- import { useState as useState12, useEffect as useEffect6, useCallback as useCallback22, memo as memo3 } from "react";
4670
+ import { useState as useState13, useCallback as useCallback23, memo as memo3 } from "react";
4634
4671
 
4635
4672
  // src/components/ui/button-group.tsx
4636
4673
  import { Slot as Slot2 } from "@radix-ui/react-slot";
@@ -4772,59 +4809,37 @@ var FontSizeControl = memo3(function FontSizeControl2({
4772
4809
  max = MAX_FONT_SIZE,
4773
4810
  step = FONT_SIZE_STEP
4774
4811
  }) {
4775
- const [inputValue, setInputValue] = useState12(String(value));
4776
- const [isFocused, setIsFocused] = useState12(false);
4777
- const [isPopoverOpen, setIsPopoverOpen] = useState12(false);
4778
- useEffect6(() => {
4779
- if (!isFocused) {
4780
- setInputValue(String(value));
4781
- }
4782
- }, [value, isFocused]);
4783
- const applySize = useCallback22(() => {
4784
- const parsed = parseInt(inputValue, 10);
4785
- if (isNaN(parsed) || inputValue === "") {
4786
- setInputValue(String(value));
4787
- return;
4788
- }
4789
- const clampedSize = Math.max(min, Math.min(parsed, max));
4790
- setInputValue(String(clampedSize));
4791
- onChange(clampedSize);
4792
- }, [inputValue, value, min, max, onChange]);
4793
- const handleIncrease = useCallback22(() => {
4812
+ const [isPopoverOpen, setIsPopoverOpen] = useState13(false);
4813
+ const input = useEditableNumber({ value, onChange, min, max });
4814
+ const handleIncrease = useCallback23(() => {
4794
4815
  const newSize = Math.min(value + step, max);
4795
4816
  onChange(newSize);
4796
4817
  }, [value, step, max, onChange]);
4797
- const handleDecrease = useCallback22(() => {
4818
+ const handleDecrease = useCallback23(() => {
4798
4819
  const newSize = Math.max(value - step, min);
4799
4820
  onChange(newSize);
4800
4821
  }, [value, step, min, onChange]);
4801
- const handleInputChange = useCallback22((e) => {
4802
- setInputValue(e.target.value);
4803
- }, []);
4804
- const handleFocus = useCallback22(() => {
4805
- setIsFocused(true);
4822
+ const handleFocus = useCallback23(() => {
4823
+ input.handleFocus();
4806
4824
  setIsPopoverOpen(true);
4807
- }, []);
4808
- const handleBlur = useCallback22(() => {
4809
- setIsFocused(false);
4810
- applySize();
4825
+ }, [input.handleFocus]);
4826
+ const handleBlur = useCallback23(() => {
4827
+ input.handleBlur();
4811
4828
  setTimeout(() => setIsPopoverOpen(false), 150);
4812
- }, [applySize]);
4813
- const handleKeyDown = useCallback22((e) => {
4829
+ }, [input.handleBlur]);
4830
+ const handleKeyDown = useCallback23((e) => {
4814
4831
  if (e.key === "Enter") {
4815
4832
  e.preventDefault();
4816
- applySize();
4817
4833
  setIsPopoverOpen(false);
4818
- e.target.blur();
4834
+ e.currentTarget.blur();
4819
4835
  }
4820
4836
  if (e.key === "Escape") {
4821
4837
  setIsPopoverOpen(false);
4822
- e.target.blur();
4838
+ e.currentTarget.blur();
4823
4839
  }
4824
- }, [applySize]);
4825
- const handlePresetSelect = useCallback22((size) => {
4840
+ }, []);
4841
+ const handlePresetSelect = useCallback23((size) => {
4826
4842
  onChange(size);
4827
- setInputValue(String(size));
4828
4843
  setIsPopoverOpen(false);
4829
4844
  }, [onChange]);
4830
4845
  return /* @__PURE__ */ jsx43("div", { className: "grid w-full max-w-sm gap-6", children: /* @__PURE__ */ jsxs33(ButtonGroup, { children: [
@@ -4851,8 +4866,8 @@ var FontSizeControl = memo3(function FontSizeControl2({
4851
4866
  type: "number",
4852
4867
  className: "text-center w-12 border-0 shadow-none px-0",
4853
4868
  placeholder: "--",
4854
- value: inputValue,
4855
- onChange: handleInputChange,
4869
+ value: input.displayValue,
4870
+ onChange: (e) => input.setLocalValue(e.target.value),
4856
4871
  onFocus: handleFocus,
4857
4872
  onBlur: handleBlur,
4858
4873
  onKeyDown: handleKeyDown,
@@ -4907,10 +4922,10 @@ var FontSizeControl = memo3(function FontSizeControl2({
4907
4922
  });
4908
4923
 
4909
4924
  // src/core/editor/components/element-gear/column-styles.tsx
4910
- import { useCallback as useCallback25, useMemo as useMemo13 } from "react";
4925
+ import { useCallback as useCallback26, useMemo as useMemo13 } from "react";
4911
4926
 
4912
4927
  // src/core/editor/components/border-radius.tsx
4913
- import { useState as useState13, useEffect as useEffect7 } from "react";
4928
+ import { useState as useState14 } from "react";
4914
4929
  import { SquareRoundCorner } from "lucide-react";
4915
4930
  import { jsx as jsx44, jsxs as jsxs34 } from "react/jsx-runtime";
4916
4931
  var BorderRadius = ({
@@ -4919,32 +4934,10 @@ var BorderRadius = ({
4919
4934
  tooltipText = "Border Radius",
4920
4935
  max = 100
4921
4936
  }) => {
4922
- const [inputValue, setInputValue] = useState13(value.toString());
4923
- const [isOpen, setIsOpen] = useState13(false);
4924
- useEffect7(() => {
4925
- setInputValue(value.toString());
4926
- }, [value]);
4937
+ const [isOpen, setIsOpen] = useState14(false);
4938
+ const input = useEditableNumber({ value, onChange, min: 0, max });
4927
4939
  const handleSliderChange = (values) => {
4928
- const newValue = values[0];
4929
- onChange(newValue);
4930
- };
4931
- const handleInputChange = (e) => {
4932
- setInputValue(e.target.value);
4933
- };
4934
- const handleInputBlur = () => {
4935
- const parsed = parseInt(inputValue, 10);
4936
- if (isNaN(parsed)) {
4937
- setInputValue(value.toString());
4938
- } else {
4939
- const clamped = Math.max(0, Math.min(max, parsed));
4940
- onChange(clamped);
4941
- setInputValue(clamped.toString());
4942
- }
4943
- };
4944
- const handleInputKeyDown = (e) => {
4945
- if (e.key === "Enter") {
4946
- e.currentTarget.blur();
4947
- }
4940
+ onChange(values[0]);
4948
4941
  };
4949
4942
  return /* @__PURE__ */ jsxs34(Tooltip, { children: [
4950
4943
  /* @__PURE__ */ jsxs34(Popover, { open: isOpen, onOpenChange: setIsOpen, children: [
@@ -4974,10 +4967,11 @@ var BorderRadius = ({
4974
4967
  Input,
4975
4968
  {
4976
4969
  type: "number",
4977
- value: inputValue,
4978
- onChange: handleInputChange,
4979
- onBlur: handleInputBlur,
4980
- onKeyDown: handleInputKeyDown,
4970
+ value: input.displayValue,
4971
+ onChange: (e) => input.setLocalValue(e.target.value),
4972
+ onFocus: input.handleFocus,
4973
+ onBlur: input.handleBlur,
4974
+ onKeyDown: input.handleKeyDown,
4981
4975
  className: "w-25 shadow-none rounded-[12px]",
4982
4976
  min: 0,
4983
4977
  max
@@ -4992,7 +4986,7 @@ var BorderRadius = ({
4992
4986
 
4993
4987
  // src/core/editor/components/stroke-weight.tsx
4994
4988
  import { BanIcon, MinusIcon as MinusIcon2 } from "lucide-react";
4995
- import { useState as useState14, useEffect as useEffect8 } from "react";
4989
+ import { useState as useState15 } from "react";
4996
4990
  import { jsx as jsx45, jsxs as jsxs35 } from "react/jsx-runtime";
4997
4991
  var StrokeWeight = ({
4998
4992
  width,
@@ -5002,32 +4996,10 @@ var StrokeWeight = ({
5002
4996
  tooltipText = "Stroke Weight",
5003
4997
  max = 50
5004
4998
  }) => {
5005
- const [isOpen, setIsOpen] = useState14(false);
5006
- const [inputValue, setInputValue] = useState14(width.toString());
5007
- useEffect8(() => {
5008
- setInputValue(width.toString());
5009
- }, [width]);
4999
+ const [isOpen, setIsOpen] = useState15(false);
5000
+ const input = useEditableNumber({ value: width, onChange: onWidthChange, min: 1, max });
5010
5001
  const handleSliderChange = (values) => {
5011
- const newWidth = values[0];
5012
- onWidthChange(newWidth);
5013
- };
5014
- const handleInputChange = (e) => {
5015
- setInputValue(e.target.value);
5016
- };
5017
- const handleInputBlur = () => {
5018
- const parsed = parseInt(inputValue, 10);
5019
- if (isNaN(parsed)) {
5020
- setInputValue(width.toString());
5021
- } else {
5022
- const clamped = Math.max(1, Math.min(max, parsed));
5023
- onWidthChange(clamped);
5024
- setInputValue(clamped.toString());
5025
- }
5026
- };
5027
- const handleInputKeyDown = (e) => {
5028
- if (e.key === "Enter") {
5029
- e.currentTarget.blur();
5030
- }
5002
+ onWidthChange(values[0]);
5031
5003
  };
5032
5004
  return /* @__PURE__ */ jsxs35(Tooltip, { children: [
5033
5005
  /* @__PURE__ */ jsxs35(Popover, { open: isOpen, onOpenChange: setIsOpen, children: [
@@ -5078,10 +5050,11 @@ var StrokeWeight = ({
5078
5050
  Input,
5079
5051
  {
5080
5052
  type: "number",
5081
- value: inputValue,
5082
- onChange: handleInputChange,
5083
- onBlur: handleInputBlur,
5084
- onKeyDown: handleInputKeyDown,
5053
+ value: input.displayValue,
5054
+ onChange: (e) => input.setLocalValue(e.target.value),
5055
+ onFocus: input.handleFocus,
5056
+ onBlur: input.handleBlur,
5057
+ onKeyDown: input.handleKeyDown,
5085
5058
  className: "w-25 shadow-none rounded-[12px]",
5086
5059
  min: 1,
5087
5060
  max
@@ -5128,10 +5101,10 @@ function CollapsibleContent2({
5128
5101
 
5129
5102
  // src/core/editor/components/better-padding.tsx
5130
5103
  import { ChevronDownIcon as ChevronDownIcon3, PanelBottomDashedIcon, PanelLeftDashedIcon, PanelRightDashedIcon, PanelTopDashedIcon, SquareSquare } from "lucide-react";
5131
- import { useState as useState15, useEffect as useEffect9, useCallback as useCallback24 } from "react";
5104
+ import { useState as useState16, useCallback as useCallback25 } from "react";
5132
5105
 
5133
5106
  // src/core/editor/hooks/use-padding.ts
5134
- import { useMemo as useMemo12, useCallback as useCallback23 } from "react";
5107
+ import { useMemo as useMemo12, useCallback as useCallback24 } from "react";
5135
5108
  import { get as lodashGet3 } from "lodash";
5136
5109
 
5137
5110
  // src/core/editor/utils/padding.ts
@@ -5200,7 +5173,7 @@ var usePadding = (options = {}) => {
5200
5173
  const uniformValue = useMemo12(() => {
5201
5174
  return getUniformValue(parsedPadding);
5202
5175
  }, [parsedPadding]);
5203
- const updatePadding = useCallback23((updates) => {
5176
+ const updatePadding = useCallback24((updates) => {
5204
5177
  if (!effectiveIdx || !template || !element) return;
5205
5178
  const newPadding = {
5206
5179
  ...parsedPadding,
@@ -5213,19 +5186,19 @@ var usePadding = (options = {}) => {
5213
5186
  }
5214
5187
  });
5215
5188
  }, [effectiveIdx, template, element, parsedPadding, updateElement, attributeName]);
5216
- const setTop = useCallback23((value) => {
5189
+ const setTop = useCallback24((value) => {
5217
5190
  updatePadding({ top: value });
5218
5191
  }, [updatePadding]);
5219
- const setRight = useCallback23((value) => {
5192
+ const setRight = useCallback24((value) => {
5220
5193
  updatePadding({ right: value });
5221
5194
  }, [updatePadding]);
5222
- const setBottom = useCallback23((value) => {
5195
+ const setBottom = useCallback24((value) => {
5223
5196
  updatePadding({ bottom: value });
5224
5197
  }, [updatePadding]);
5225
- const setLeft = useCallback23((value) => {
5198
+ const setLeft = useCallback24((value) => {
5226
5199
  updatePadding({ left: value });
5227
5200
  }, [updatePadding]);
5228
- const setUniform = useCallback23((value) => {
5201
+ const setUniform = useCallback24((value) => {
5229
5202
  updatePadding({ top: value, right: value, bottom: value, left: value });
5230
5203
  }, [updatePadding]);
5231
5204
  return {
@@ -5255,19 +5228,19 @@ var BetterPadding = ({
5255
5228
  targetIdx,
5256
5229
  tooltipText = "Padding"
5257
5230
  }) => {
5258
- const [isOpen, setIsOpen] = useState15(false);
5259
- const [openSection, setOpenSection] = useState15(null);
5231
+ const [isOpen, setIsOpen] = useState16(false);
5232
+ const [openSection, setOpenSection] = useState16(null);
5260
5233
  const padding = usePadding({ targetIdx });
5261
5234
  const innerPadding = usePadding({ attributeName: "inner-padding", targetIdx });
5262
5235
  const iconPadding = usePadding({ attributeName: "icon-padding", targetIdx });
5263
5236
  const textPadding = usePadding({ attributeName: "text-padding", targetIdx });
5264
- const handleToggle = useCallback24((section) => {
5237
+ const handleToggle = useCallback25((section) => {
5265
5238
  setOpenSection((prev) => prev === section ? null : section);
5266
5239
  }, []);
5267
- const handleToggleNormal = useCallback24(() => handleToggle("normal"), [handleToggle]);
5268
- const handleToggleInner = useCallback24(() => handleToggle("inner"), [handleToggle]);
5269
- const handleToggleIcon = useCallback24(() => handleToggle("icon"), [handleToggle]);
5270
- const handleToggleText = useCallback24(() => handleToggle("text"), [handleToggle]);
5240
+ const handleToggleNormal = useCallback25(() => handleToggle("normal"), [handleToggle]);
5241
+ const handleToggleInner = useCallback25(() => handleToggle("inner"), [handleToggle]);
5242
+ const handleToggleIcon = useCallback25(() => handleToggle("icon"), [handleToggle]);
5243
+ const handleToggleText = useCallback25(() => handleToggle("text"), [handleToggle]);
5271
5244
  return /* @__PURE__ */ jsxs36(Tooltip, { children: [
5272
5245
  /* @__PURE__ */ jsxs36(Popover, { open: isOpen, onOpenChange: setIsOpen, children: [
5273
5246
  /* @__PURE__ */ jsx47(PopoverTrigger, { asChild: true, children: /* @__PURE__ */ jsx47(TooltipTrigger, { asChild: true, children: /* @__PURE__ */ jsx47(
@@ -5322,105 +5295,14 @@ var BetterPadding = ({
5322
5295
  ] });
5323
5296
  };
5324
5297
  var PaddingSectionUI = ({ label, isOpen, onToggle, data }) => {
5325
- const [sliderValue, setSliderValue] = useState15(data.uniformValue ?? data.top);
5326
- const [sliderInputValue, setSliderInputValue] = useState15((data.uniformValue ?? data.top).toString());
5327
- const [topInput, setTopInput] = useState15(data.top.toString());
5328
- const [rightInput, setRightInput] = useState15(data.right.toString());
5329
- const [bottomInput, setBottomInput] = useState15(data.bottom.toString());
5330
- const [leftInput, setLeftInput] = useState15(data.left.toString());
5331
- useEffect9(() => {
5332
- setSliderValue(data.uniformValue ?? data.top);
5333
- setSliderInputValue((data.uniformValue ?? data.top).toString());
5334
- }, [data.uniformValue, data.top]);
5335
- useEffect9(() => {
5336
- setTopInput(data.top.toString());
5337
- }, [data.top]);
5338
- useEffect9(() => {
5339
- setRightInput(data.right.toString());
5340
- }, [data.right]);
5341
- useEffect9(() => {
5342
- setBottomInput(data.bottom.toString());
5343
- }, [data.bottom]);
5344
- useEffect9(() => {
5345
- setLeftInput(data.left.toString());
5346
- }, [data.left]);
5347
- const handleKeyDown = useCallback24((e) => {
5348
- if (e.key === "Enter") {
5349
- e.currentTarget.blur();
5350
- }
5351
- }, []);
5352
- const handleSliderChange = useCallback24((values) => {
5353
- const newValue = values[0];
5354
- setSliderValue(newValue);
5355
- setSliderInputValue(newValue.toString());
5356
- data.setUniform(newValue);
5298
+ const sliderInput = useEditableNumber({ value: data.uniformValue ?? data.top, onChange: data.setUniform, min: 0, max: PADDING_MAX });
5299
+ const topInput = useEditableNumber({ value: data.top, onChange: data.setTop, min: 0, max: PADDING_MAX });
5300
+ const rightInput = useEditableNumber({ value: data.right, onChange: data.setRight, min: 0, max: PADDING_MAX });
5301
+ const bottomInput = useEditableNumber({ value: data.bottom, onChange: data.setBottom, min: 0, max: PADDING_MAX });
5302
+ const leftInput = useEditableNumber({ value: data.left, onChange: data.setLeft, min: 0, max: PADDING_MAX });
5303
+ const handleSliderChange = useCallback25((values) => {
5304
+ data.setUniform(values[0]);
5357
5305
  }, [data]);
5358
- const handleSliderInputChange = useCallback24((e) => {
5359
- setSliderInputValue(e.target.value);
5360
- }, []);
5361
- const handleSliderInputBlur = useCallback24(() => {
5362
- const parsed = parseInt(sliderInputValue, 10);
5363
- if (isNaN(parsed) || sliderInputValue === "") {
5364
- setSliderInputValue(sliderValue.toString());
5365
- } else {
5366
- const clamped = Math.max(0, Math.min(PADDING_MAX, parsed));
5367
- setSliderValue(clamped);
5368
- setSliderInputValue(clamped.toString());
5369
- data.setUniform(clamped);
5370
- }
5371
- }, [sliderInputValue, sliderValue, data]);
5372
- const handleTopChange = useCallback24((e) => {
5373
- setTopInput(e.target.value);
5374
- }, []);
5375
- const handleTopBlur = useCallback24(() => {
5376
- const parsed = parseInt(topInput, 10);
5377
- if (isNaN(parsed)) {
5378
- setTopInput(data.top.toString());
5379
- } else {
5380
- const clamped = Math.max(0, Math.min(PADDING_MAX, parsed));
5381
- data.setTop(clamped);
5382
- setTopInput(clamped.toString());
5383
- }
5384
- }, [topInput, data]);
5385
- const handleRightChange = useCallback24((e) => {
5386
- setRightInput(e.target.value);
5387
- }, []);
5388
- const handleRightBlur = useCallback24(() => {
5389
- const parsed = parseInt(rightInput, 10);
5390
- if (isNaN(parsed)) {
5391
- setRightInput(data.right.toString());
5392
- } else {
5393
- const clamped = Math.max(0, Math.min(PADDING_MAX, parsed));
5394
- data.setRight(clamped);
5395
- setRightInput(clamped.toString());
5396
- }
5397
- }, [rightInput, data]);
5398
- const handleBottomChange = useCallback24((e) => {
5399
- setBottomInput(e.target.value);
5400
- }, []);
5401
- const handleBottomBlur = useCallback24(() => {
5402
- const parsed = parseInt(bottomInput, 10);
5403
- if (isNaN(parsed)) {
5404
- setBottomInput(data.bottom.toString());
5405
- } else {
5406
- const clamped = Math.max(0, Math.min(PADDING_MAX, parsed));
5407
- data.setBottom(clamped);
5408
- setBottomInput(clamped.toString());
5409
- }
5410
- }, [bottomInput, data]);
5411
- const handleLeftChange = useCallback24((e) => {
5412
- setLeftInput(e.target.value);
5413
- }, []);
5414
- const handleLeftBlur = useCallback24(() => {
5415
- const parsed = parseInt(leftInput, 10);
5416
- if (isNaN(parsed)) {
5417
- setLeftInput(data.left.toString());
5418
- } else {
5419
- const clamped = Math.max(0, Math.min(PADDING_MAX, parsed));
5420
- data.setLeft(clamped);
5421
- setLeftInput(clamped.toString());
5422
- }
5423
- }, [leftInput, data]);
5424
5306
  return /* @__PURE__ */ jsxs36(Collapsible, { open: isOpen, onOpenChange: onToggle, children: [
5425
5307
  /* @__PURE__ */ jsx47(CollapsibleTrigger2, { asChild: true, children: /* @__PURE__ */ jsx47(Button, { variant: "outline", className: "w-full shadow-none rounded-[12px]", children: /* @__PURE__ */ jsxs36("div", { className: "w-full flex flex-row items-center justify-between gap-2", children: [
5426
5308
  /* @__PURE__ */ jsx47("p", { children: label }),
@@ -5431,7 +5313,7 @@ var PaddingSectionUI = ({ label, isOpen, onToggle, data }) => {
5431
5313
  /* @__PURE__ */ jsx47(
5432
5314
  Slider2,
5433
5315
  {
5434
- value: [sliderValue],
5316
+ value: [data.uniformValue ?? data.top],
5435
5317
  onValueChange: handleSliderChange,
5436
5318
  min: 0,
5437
5319
  max: PADDING_MAX,
@@ -5442,10 +5324,11 @@ var PaddingSectionUI = ({ label, isOpen, onToggle, data }) => {
5442
5324
  Input,
5443
5325
  {
5444
5326
  type: "number",
5445
- value: sliderInputValue,
5446
- onChange: handleSliderInputChange,
5447
- onBlur: handleSliderInputBlur,
5448
- onKeyDown: handleKeyDown,
5327
+ value: sliderInput.displayValue,
5328
+ onChange: (e) => sliderInput.setLocalValue(e.target.value),
5329
+ onFocus: sliderInput.handleFocus,
5330
+ onBlur: sliderInput.handleBlur,
5331
+ onKeyDown: sliderInput.handleKeyDown,
5449
5332
  className: "w-25 shadow-none rounded-[12px]",
5450
5333
  min: 0,
5451
5334
  max: PADDING_MAX
@@ -5460,10 +5343,11 @@ var PaddingSectionUI = ({ label, isOpen, onToggle, data }) => {
5460
5343
  Input,
5461
5344
  {
5462
5345
  type: "number",
5463
- value: topInput,
5464
- onChange: handleTopChange,
5465
- onBlur: handleTopBlur,
5466
- onKeyDown: handleKeyDown,
5346
+ value: topInput.displayValue,
5347
+ onChange: (e) => topInput.setLocalValue(e.target.value),
5348
+ onFocus: topInput.handleFocus,
5349
+ onBlur: topInput.handleBlur,
5350
+ onKeyDown: topInput.handleKeyDown,
5467
5351
  className: "w-20 shadow-none rounded-[12px]",
5468
5352
  min: 0,
5469
5353
  max: PADDING_MAX
@@ -5476,10 +5360,11 @@ var PaddingSectionUI = ({ label, isOpen, onToggle, data }) => {
5476
5360
  Input,
5477
5361
  {
5478
5362
  type: "number",
5479
- value: bottomInput,
5480
- onChange: handleBottomChange,
5481
- onBlur: handleBottomBlur,
5482
- onKeyDown: handleKeyDown,
5363
+ value: bottomInput.displayValue,
5364
+ onChange: (e) => bottomInput.setLocalValue(e.target.value),
5365
+ onFocus: bottomInput.handleFocus,
5366
+ onBlur: bottomInput.handleBlur,
5367
+ onKeyDown: bottomInput.handleKeyDown,
5483
5368
  className: "w-20 shadow-none rounded-[12px]",
5484
5369
  min: 0,
5485
5370
  max: PADDING_MAX
@@ -5494,10 +5379,11 @@ var PaddingSectionUI = ({ label, isOpen, onToggle, data }) => {
5494
5379
  Input,
5495
5380
  {
5496
5381
  type: "number",
5497
- value: leftInput,
5498
- onChange: handleLeftChange,
5499
- onBlur: handleLeftBlur,
5500
- onKeyDown: handleKeyDown,
5382
+ value: leftInput.displayValue,
5383
+ onChange: (e) => leftInput.setLocalValue(e.target.value),
5384
+ onFocus: leftInput.handleFocus,
5385
+ onBlur: leftInput.handleBlur,
5386
+ onKeyDown: leftInput.handleKeyDown,
5501
5387
  className: "w-20 shadow-none rounded-[12px]",
5502
5388
  min: 0,
5503
5389
  max: PADDING_MAX
@@ -5510,10 +5396,11 @@ var PaddingSectionUI = ({ label, isOpen, onToggle, data }) => {
5510
5396
  Input,
5511
5397
  {
5512
5398
  type: "number",
5513
- value: rightInput,
5514
- onChange: handleRightChange,
5515
- onBlur: handleRightBlur,
5516
- onKeyDown: handleKeyDown,
5399
+ value: rightInput.displayValue,
5400
+ onChange: (e) => rightInput.setLocalValue(e.target.value),
5401
+ onFocus: rightInput.handleFocus,
5402
+ onBlur: rightInput.handleBlur,
5403
+ onKeyDown: rightInput.handleKeyDown,
5517
5404
  className: "w-20 shadow-none rounded-[12px]",
5518
5405
  min: 0,
5519
5406
  max: PADDING_MAX
@@ -5597,24 +5484,24 @@ var ColumnStyles = () => {
5597
5484
  const paddingUniformValue = useMemo13(() => {
5598
5485
  return getUniformValue(padding);
5599
5486
  }, [padding]);
5600
- const handleOpenBgColorPicker = useCallback25(() => {
5487
+ const handleOpenBgColorPicker = useCallback26(() => {
5601
5488
  setColorType("Column color");
5602
5489
  setColorTarget("columnBgColor");
5603
5490
  setActiveView("color");
5604
5491
  }, [setColorType, setColorTarget, setActiveView]);
5605
- const handleOpenStrokeColorPicker = useCallback25(() => {
5492
+ const handleOpenStrokeColorPicker = useCallback26(() => {
5606
5493
  setColorType("Column Stroke");
5607
5494
  setColorTarget("columnStrokeColor");
5608
5495
  setActiveView("color");
5609
5496
  }, [setColorType, setColorTarget, setActiveView]);
5610
- const handleStrokeWidthChange = useCallback25((width) => {
5497
+ const handleStrokeWidthChange = useCallback26((width) => {
5611
5498
  if (!columnIdx || !column) return;
5612
5499
  const newBorder = formatBorder({ ...border, width });
5613
5500
  updateElement(columnIdx, {
5614
5501
  attributes: { ...column.attributes, border: newBorder }
5615
5502
  });
5616
5503
  }, [columnIdx, column, border, updateElement]);
5617
- const handleStrokeEnabledChange = useCallback25((enabled) => {
5504
+ const handleStrokeEnabledChange = useCallback26((enabled) => {
5618
5505
  if (!columnIdx || !column) return;
5619
5506
  const newBorder = formatBorder({
5620
5507
  ...border,
@@ -5624,32 +5511,32 @@ var ColumnStyles = () => {
5624
5511
  attributes: { ...column.attributes, border: newBorder }
5625
5512
  });
5626
5513
  }, [columnIdx, column, border, updateElement]);
5627
- const handleBorderRadiusChange = useCallback25((value) => {
5514
+ const handleBorderRadiusChange = useCallback26((value) => {
5628
5515
  if (!columnIdx || !column) return;
5629
5516
  updateElement(columnIdx, {
5630
5517
  attributes: { ...column.attributes, "border-radius": formatBorderRadius(value) }
5631
5518
  });
5632
5519
  }, [columnIdx, column, updateElement]);
5633
- const updatePadding = useCallback25((updates) => {
5520
+ const updatePadding = useCallback26((updates) => {
5634
5521
  if (!columnIdx || !column) return;
5635
5522
  const newPadding = { ...padding, ...updates };
5636
5523
  updateElement(columnIdx, {
5637
5524
  attributes: { ...column.attributes, padding: formatPadding(newPadding) }
5638
5525
  });
5639
5526
  }, [columnIdx, column, padding, updateElement]);
5640
- const handlePaddingTopChange = useCallback25((value) => {
5527
+ const handlePaddingTopChange = useCallback26((value) => {
5641
5528
  updatePadding({ top: value });
5642
5529
  }, [updatePadding]);
5643
- const handlePaddingRightChange = useCallback25((value) => {
5530
+ const handlePaddingRightChange = useCallback26((value) => {
5644
5531
  updatePadding({ right: value });
5645
5532
  }, [updatePadding]);
5646
- const handlePaddingBottomChange = useCallback25((value) => {
5533
+ const handlePaddingBottomChange = useCallback26((value) => {
5647
5534
  updatePadding({ bottom: value });
5648
5535
  }, [updatePadding]);
5649
- const handlePaddingLeftChange = useCallback25((value) => {
5536
+ const handlePaddingLeftChange = useCallback26((value) => {
5650
5537
  updatePadding({ left: value });
5651
5538
  }, [updatePadding]);
5652
- const handlePaddingUniformChange = useCallback25((value) => {
5539
+ const handlePaddingUniformChange = useCallback26((value) => {
5653
5540
  updatePadding({ top: value, right: value, bottom: value, left: value });
5654
5541
  }, [updatePadding]);
5655
5542
  return /* @__PURE__ */ jsxs38(Fragment3, { children: [
@@ -5737,8 +5624,8 @@ var TextToolbar = () => {
5737
5624
  const template = useEditorStore((s) => s.template);
5738
5625
  const mergeFields = useEditorStore((s) => s.mergeFields);
5739
5626
  const { activeView, colorTarget, setActiveView, setColorType, setColorTarget } = useSidebarContext();
5740
- const [updateCounter, forceUpdate] = useState16(0);
5741
- const [overflowOpen, setOverflowOpen] = useState16(false);
5627
+ const [updateCounter, forceUpdate] = useState17(0);
5628
+ const [overflowOpen, setOverflowOpen] = useState17(false);
5742
5629
  const isInSectionColumn = useMemo14(() => {
5743
5630
  if (!focusIdx || !template) return false;
5744
5631
  const columnIdx = getParentIdx(focusIdx);
@@ -5748,7 +5635,7 @@ var TextToolbar = () => {
5748
5635
  const section = getValueByIdx(template, sectionIdx);
5749
5636
  return section?.type === "section-column";
5750
5637
  }, [focusIdx, template]);
5751
- useEffect10(() => {
5638
+ useEffect6(() => {
5752
5639
  if (!tiptapEditor) return;
5753
5640
  const handler = () => forceUpdate((n) => n + 1);
5754
5641
  tiptapEditor.on("selectionUpdate", handler);
@@ -5783,7 +5670,7 @@ var TextToolbar = () => {
5783
5670
  const multiplier = HEADING_MULTIPLIERS[activeType] || 1;
5784
5671
  return Math.round(baseFontSize * multiplier);
5785
5672
  }, [tiptapEditor, updateCounter, activeType, baseFontSize]);
5786
- const handleFontSizeChange = useCallback26((size) => {
5673
+ const handleFontSizeChange = useCallback27((size) => {
5787
5674
  if (!tiptapEditor) return;
5788
5675
  tiptapEditor.chain().focus().setFontSize(`${size}px`).run();
5789
5676
  forceUpdate((n) => n + 1);
@@ -5794,7 +5681,7 @@ var TextToolbar = () => {
5794
5681
  if (paragraphAttrs.textAlign) return paragraphAttrs.textAlign;
5795
5682
  return "left";
5796
5683
  }, [tiptapEditor, updateCounter]);
5797
- const handleCycleAlignment = useCallback26(() => {
5684
+ const handleCycleAlignment = useCallback27(() => {
5798
5685
  if (!tiptapEditor) return;
5799
5686
  const currentIndex = ALIGNMENTS.indexOf(currentAlignment);
5800
5687
  const nextIndex = (currentIndex + 1) % ALIGNMENTS.length;
@@ -5802,30 +5689,30 @@ var TextToolbar = () => {
5802
5689
  tiptapEditor.chain().focus().setTextAlign(nextAlignment).run();
5803
5690
  forceUpdate((n) => n + 1);
5804
5691
  }, [tiptapEditor, currentAlignment]);
5805
- const handleCycleList = useCallback26(() => {
5692
+ const handleCycleList = useCallback27(() => {
5806
5693
  }, [tiptapEditor]);
5807
5694
  const isInHeading = useMemo14(() => {
5808
5695
  if (!tiptapEditor) return false;
5809
5696
  const paragraphAttrs = tiptapEditor.getAttributes("paragraph");
5810
5697
  return (paragraphAttrs.headingLevel || 0) > 0;
5811
5698
  }, [tiptapEditor, updateCounter]);
5812
- const handleToggleBold = useCallback26(() => {
5699
+ const handleToggleBold = useCallback27(() => {
5813
5700
  if (!tiptapEditor) return;
5814
5701
  if (isInHeading) return;
5815
5702
  tiptapEditor.chain().focus().toggleBold().run();
5816
5703
  forceUpdate((n) => n + 1);
5817
5704
  }, [tiptapEditor, isInHeading]);
5818
- const handleToggleItalic = useCallback26(() => {
5705
+ const handleToggleItalic = useCallback27(() => {
5819
5706
  if (!tiptapEditor) return;
5820
5707
  tiptapEditor.chain().focus().toggleItalic().run();
5821
5708
  forceUpdate((n) => n + 1);
5822
5709
  }, [tiptapEditor]);
5823
- const handleToggleUnderline = useCallback26(() => {
5710
+ const handleToggleUnderline = useCallback27(() => {
5824
5711
  if (!tiptapEditor) return;
5825
5712
  tiptapEditor.chain().focus().toggleUnderline().run();
5826
5713
  forceUpdate((n) => n + 1);
5827
5714
  }, [tiptapEditor]);
5828
- const handleToggleStrike = useCallback26(() => {
5715
+ const handleToggleStrike = useCallback27(() => {
5829
5716
  if (!tiptapEditor) return;
5830
5717
  tiptapEditor.chain().focus().toggleStrike().run();
5831
5718
  forceUpdate((n) => n + 1);
@@ -5847,7 +5734,7 @@ var TextToolbar = () => {
5847
5734
  if (!tiptapEditor) return false;
5848
5735
  return tiptapEditor.isActive("strike");
5849
5736
  }, [tiptapEditor, updateCounter]);
5850
- const handleSetType = useCallback26((type) => {
5737
+ const handleSetType = useCallback27((type) => {
5851
5738
  if (!tiptapEditor) return;
5852
5739
  const levelMap = {
5853
5740
  paragraph: 0,
@@ -5867,12 +5754,12 @@ var TextToolbar = () => {
5867
5754
  deleteElement(focusIdx);
5868
5755
  }
5869
5756
  };
5870
- const handleOpenTextColorPicker = useCallback26(() => {
5757
+ const handleOpenTextColorPicker = useCallback27(() => {
5871
5758
  setColorType("Text color");
5872
5759
  setColorTarget("textColor");
5873
5760
  setActiveView("color");
5874
5761
  }, [setColorType, setColorTarget, setActiveView]);
5875
- const handleOpenHighlightColorPicker = useCallback26(() => {
5762
+ const handleOpenHighlightColorPicker = useCallback27(() => {
5876
5763
  setColorType("Highlight color");
5877
5764
  setColorTarget("highlightColor");
5878
5765
  setActiveView("color");
@@ -5885,7 +5772,7 @@ var TextToolbar = () => {
5885
5772
  if (!tiptapEditor) return "transparent";
5886
5773
  return tiptapEditor.getAttributes("textStyle").backgroundColor || "transparent";
5887
5774
  }, [tiptapEditor, updateCounter]);
5888
- const extractKnownFont = useCallback26((fontStack) => {
5775
+ const extractKnownFont = useCallback27((fontStack) => {
5889
5776
  if (!fontStack) return "Arial";
5890
5777
  const fonts = fontStack.split(",").map((f) => f.trim().replace(/['"]/g, ""));
5891
5778
  for (const font of fonts) {
@@ -5902,7 +5789,7 @@ var TextToolbar = () => {
5902
5789
  }
5903
5790
  return extractKnownFont(textEditingStyles?.fontFamily);
5904
5791
  }, [tiptapEditor, updateCounter, textEditingStyles?.fontFamily, extractKnownFont]);
5905
- const handleSetFontFamily = useCallback26((font) => {
5792
+ const handleSetFontFamily = useCallback27((font) => {
5906
5793
  if (!tiptapEditor) return;
5907
5794
  tiptapEditor.chain().focus().setFontFamily(font).run();
5908
5795
  forceUpdate((n) => n + 1);
@@ -6442,12 +6329,12 @@ var MergeFieldItem = ({ isResponsive, isInSectionColumn, tiptapEditor, mergeFiel
6442
6329
  };
6443
6330
 
6444
6331
  // src/core/editor/components/element-gear/button/toolbar.tsx
6445
- import { useCallback as useCallback31, useMemo as useMemo19 } from "react";
6332
+ import { useCallback as useCallback32, useMemo as useMemo19 } from "react";
6446
6333
  import { get as lodashGet7 } from "lodash";
6447
6334
  import { BoldIcon as BoldIcon2, CaseUpperIcon as CaseUpperIcon2, ItalicIcon as ItalicIcon2, Strikethrough as Strikethrough2, Underline as Underline2 } from "lucide-react";
6448
6335
 
6449
6336
  // src/core/editor/hooks/use-border-radius.ts
6450
- import { useMemo as useMemo15, useCallback as useCallback27 } from "react";
6337
+ import { useMemo as useMemo15, useCallback as useCallback28 } from "react";
6451
6338
  import { get as lodashGet4 } from "lodash";
6452
6339
  var useBorderRadius = (options = {}) => {
6453
6340
  const { focusIdx, updateElement, template } = useEditorStore();
@@ -6459,7 +6346,7 @@ var useBorderRadius = (options = {}) => {
6459
6346
  const rawValue = element?.attributes?.[attributeName];
6460
6347
  return parseBorderRadius(rawValue);
6461
6348
  }, [focusIdx, template, attributeName]);
6462
- const handleChange = useCallback27((value) => {
6349
+ const handleChange = useCallback28((value) => {
6463
6350
  if (!focusIdx || !template) return;
6464
6351
  const path = focusIdx.startsWith("content.") ? focusIdx.replace("content.", "content[0].").replace(/\.\[(\d+)\]/g, "[$1]") : focusIdx;
6465
6352
  const element = lodashGet4(template, path);
@@ -6478,7 +6365,7 @@ var useBorderRadius = (options = {}) => {
6478
6365
  };
6479
6366
 
6480
6367
  // src/core/editor/hooks/use-border.ts
6481
- import { useMemo as useMemo16, useCallback as useCallback28 } from "react";
6368
+ import { useMemo as useMemo16, useCallback as useCallback29 } from "react";
6482
6369
  import { get as lodashGet5 } from "lodash";
6483
6370
  var useBorder = (options = {}) => {
6484
6371
  const { focusIdx, updateElement, template } = useEditorStore();
@@ -6495,7 +6382,7 @@ var useBorder = (options = {}) => {
6495
6382
  const width = parsedBorder.width;
6496
6383
  const color = parsedBorder.color;
6497
6384
  const isEnabled = width > 0;
6498
- const updateBorder = useCallback28((updates) => {
6385
+ const updateBorder = useCallback29((updates) => {
6499
6386
  if (!focusIdx || !template || !element) return;
6500
6387
  const newBorder = {
6501
6388
  ...parsedBorder,
@@ -6508,13 +6395,13 @@ var useBorder = (options = {}) => {
6508
6395
  }
6509
6396
  });
6510
6397
  }, [focusIdx, template, element, parsedBorder, updateElement, attributeName]);
6511
- const setWidth = useCallback28((newWidth) => {
6398
+ const setWidth = useCallback29((newWidth) => {
6512
6399
  updateBorder({ width: newWidth });
6513
6400
  }, [updateBorder]);
6514
- const setColor = useCallback28((newColor) => {
6401
+ const setColor = useCallback29((newColor) => {
6515
6402
  updateBorder({ color: newColor });
6516
6403
  }, [updateBorder]);
6517
- const setEnabled = useCallback28((enabled) => {
6404
+ const setEnabled = useCallback29((enabled) => {
6518
6405
  if (enabled) {
6519
6406
  updateBorder({ width: parsedBorder.width === 0 ? 1 : parsedBorder.width });
6520
6407
  } else {
@@ -6532,7 +6419,7 @@ var useBorder = (options = {}) => {
6532
6419
  };
6533
6420
 
6534
6421
  // src/core/editor/hooks/use-size.ts
6535
- import { useMemo as useMemo17, useCallback as useCallback29 } from "react";
6422
+ import { useMemo as useMemo17, useCallback as useCallback30 } from "react";
6536
6423
  import { get as lodashGet6 } from "lodash";
6537
6424
  var parseSize = (value, defaultValue) => {
6538
6425
  if (!value) return defaultValue;
@@ -6560,13 +6447,13 @@ var useSize = (options = {}) => {
6560
6447
  height: parseSize(el?.attributes?.[heightAttribute], defaultHeight)
6561
6448
  };
6562
6449
  }, [focusIdx, template, widthAttribute, heightAttribute, defaultWidth, defaultHeight]);
6563
- const setWidth = useCallback29((value) => {
6450
+ const setWidth = useCallback30((value) => {
6564
6451
  if (!focusIdx || !template || !element) return;
6565
6452
  updateElement(focusIdx, {
6566
6453
  attributes: { ...element.attributes, [widthAttribute]: formatSize(value, widthUnit) }
6567
6454
  });
6568
6455
  }, [focusIdx, template, element, updateElement, widthAttribute, widthUnit]);
6569
- const setHeight = useCallback29((value) => {
6456
+ const setHeight = useCallback30((value) => {
6570
6457
  if (!focusIdx || !template || !element) return;
6571
6458
  updateElement(focusIdx, {
6572
6459
  attributes: { ...element.attributes, [heightAttribute]: formatSize(value, heightUnit) }
@@ -6577,10 +6464,10 @@ var useSize = (options = {}) => {
6577
6464
 
6578
6465
  // src/core/editor/components/button-text-settings.tsx
6579
6466
  import { TypeIcon as TypeIcon2 } from "lucide-react";
6580
- import { useState as useState17, useEffect as useEffect11, useMemo as useMemo18, useCallback as useCallback30, memo as memo4 } from "react";
6467
+ import { useState as useState18, useMemo as useMemo18, useCallback as useCallback31, memo as memo4 } from "react";
6581
6468
  import { jsx as jsx51, jsxs as jsxs40 } from "react/jsx-runtime";
6582
6469
  var ButtonTextSettings = memo4(function ButtonTextSettings2() {
6583
- const [isOpen, setIsOpen] = useState17(false);
6470
+ const [isOpen, setIsOpen] = useState18(false);
6584
6471
  const focusIdx = useEditorStore((s) => s.focusIdx);
6585
6472
  const template = useEditorStore((s) => s.template);
6586
6473
  const updateElement = useEditorStore((s) => s.updateElement);
@@ -6597,114 +6484,40 @@ var ButtonTextSettings = memo4(function ButtonTextSettings2() {
6597
6484
  const parsed = parseFloat(buttonElement.attributes["line-height"]);
6598
6485
  return isNaN(parsed) ? DEFAULT_LINE_HEIGHT : parsed;
6599
6486
  }, [buttonElement]);
6600
- const [letterSpacingInputValue, setLetterSpacingInputValue] = useState17(
6601
- String(currentLetterSpacing)
6602
- );
6603
- const [isLetterSpacingInputFocused, setIsLetterSpacingInputFocused] = useState17(false);
6604
- const [lineHeightInputValue, setLineHeightInputValue] = useState17(
6605
- String(currentLineHeight)
6606
- );
6607
- const [isLineHeightInputFocused, setIsLineHeightInputFocused] = useState17(false);
6608
- useEffect11(() => {
6609
- if (!isLetterSpacingInputFocused) {
6610
- setLetterSpacingInputValue(String(currentLetterSpacing));
6611
- }
6612
- }, [currentLetterSpacing, isLetterSpacingInputFocused]);
6613
- useEffect11(() => {
6614
- if (!isLineHeightInputFocused) {
6615
- setLineHeightInputValue(String(currentLineHeight));
6616
- }
6617
- }, [currentLineHeight, isLineHeightInputFocused]);
6618
- const handleLetterSpacingSliderChange = useCallback30((values) => {
6487
+ const commitLetterSpacing = useCallback31((value) => {
6619
6488
  if (!focusIdx) return;
6620
- const value = values[0];
6621
- setLetterSpacingInputValue(String(value));
6622
6489
  const currentTemplate = useEditorStore.getState().template;
6623
6490
  const element = getValueByIdx(currentTemplate, focusIdx);
6624
6491
  updateElement(focusIdx, {
6625
- attributes: {
6626
- ...element?.attributes,
6627
- "letter-spacing": `${value}px`
6628
- }
6492
+ attributes: { ...element?.attributes, "letter-spacing": `${value}px` }
6629
6493
  });
6630
6494
  }, [focusIdx, updateElement]);
6631
- const handleLetterSpacingInputChange = useCallback30((e) => {
6632
- setLetterSpacingInputValue(e.target.value);
6633
- }, []);
6634
- const applyLetterSpacing = useCallback30(() => {
6635
- if (!focusIdx) return;
6636
- const parsed = parseFloat(letterSpacingInputValue);
6637
- if (isNaN(parsed) || letterSpacingInputValue === "") {
6638
- setLetterSpacingInputValue(String(currentLetterSpacing));
6639
- return;
6640
- }
6641
- const clampedValue = Math.max(MIN_LETTER_SPACING, Math.min(parsed, MAX_LETTER_SPACING));
6642
- setLetterSpacingInputValue(String(clampedValue));
6643
- const currentTemplate = useEditorStore.getState().template;
6644
- const element = getValueByIdx(currentTemplate, focusIdx);
6645
- updateElement(focusIdx, {
6646
- attributes: {
6647
- ...element?.attributes,
6648
- "letter-spacing": `${clampedValue}px`
6649
- }
6650
- });
6651
- }, [focusIdx, letterSpacingInputValue, currentLetterSpacing, updateElement]);
6652
- const handleLetterSpacingInputBlur = useCallback30(() => {
6653
- setIsLetterSpacingInputFocused(false);
6654
- applyLetterSpacing();
6655
- }, [applyLetterSpacing]);
6656
- const handleLetterSpacingInputKeyDown = useCallback30((e) => {
6657
- if (e.key === "Enter") {
6658
- e.preventDefault();
6659
- applyLetterSpacing();
6660
- e.target.blur();
6661
- }
6662
- }, [applyLetterSpacing]);
6663
- const handleLineHeightSliderChange = useCallback30((values) => {
6495
+ const commitLineHeight = useCallback31((value) => {
6664
6496
  if (!focusIdx) return;
6665
- const value = values[0];
6666
- setLineHeightInputValue(String(value));
6667
6497
  const currentTemplate = useEditorStore.getState().template;
6668
6498
  const element = getValueByIdx(currentTemplate, focusIdx);
6669
6499
  updateElement(focusIdx, {
6670
- attributes: {
6671
- ...element?.attributes,
6672
- "line-height": String(value)
6673
- }
6500
+ attributes: { ...element?.attributes, "line-height": String(value) }
6674
6501
  });
6675
6502
  }, [focusIdx, updateElement]);
6676
- const handleLineHeightInputChange = useCallback30((e) => {
6677
- setLineHeightInputValue(e.target.value);
6678
- }, []);
6679
- const applyLineHeight = useCallback30(() => {
6680
- if (!focusIdx) return;
6681
- const parsed = parseFloat(lineHeightInputValue);
6682
- if (isNaN(parsed) || lineHeightInputValue === "") {
6683
- setLineHeightInputValue(String(currentLineHeight));
6684
- return;
6685
- }
6686
- const clampedValue = Math.max(MIN_LINE_HEIGHT, Math.min(parsed, MAX_LINE_HEIGHT));
6687
- setLineHeightInputValue(String(clampedValue));
6688
- const currentTemplate = useEditorStore.getState().template;
6689
- const element = getValueByIdx(currentTemplate, focusIdx);
6690
- updateElement(focusIdx, {
6691
- attributes: {
6692
- ...element?.attributes,
6693
- "line-height": String(clampedValue)
6694
- }
6695
- });
6696
- }, [focusIdx, lineHeightInputValue, currentLineHeight, updateElement]);
6697
- const handleLineHeightInputBlur = useCallback30(() => {
6698
- setIsLineHeightInputFocused(false);
6699
- applyLineHeight();
6700
- }, [applyLineHeight]);
6701
- const handleLineHeightInputKeyDown = useCallback30((e) => {
6702
- if (e.key === "Enter") {
6703
- e.preventDefault();
6704
- applyLineHeight();
6705
- e.target.blur();
6706
- }
6707
- }, [applyLineHeight]);
6503
+ const letterSpacingInput = useEditableFloat({
6504
+ value: currentLetterSpacing,
6505
+ onChange: commitLetterSpacing,
6506
+ min: MIN_LETTER_SPACING,
6507
+ max: MAX_LETTER_SPACING
6508
+ });
6509
+ const lineHeightInput = useEditableFloat({
6510
+ value: currentLineHeight,
6511
+ onChange: commitLineHeight,
6512
+ min: MIN_LINE_HEIGHT,
6513
+ max: MAX_LINE_HEIGHT
6514
+ });
6515
+ const handleLetterSpacingSliderChange = useCallback31((values) => {
6516
+ commitLetterSpacing(values[0]);
6517
+ }, [commitLetterSpacing]);
6518
+ const handleLineHeightSliderChange = useCallback31((values) => {
6519
+ commitLineHeight(values[0]);
6520
+ }, [commitLineHeight]);
6708
6521
  return /* @__PURE__ */ jsxs40(Tooltip, { children: [
6709
6522
  /* @__PURE__ */ jsxs40(Popover, { open: isOpen, onOpenChange: setIsOpen, children: [
6710
6523
  /* @__PURE__ */ jsx51(PopoverTrigger, { asChild: true, children: /* @__PURE__ */ jsx51(TooltipTrigger, { asChild: true, children: /* @__PURE__ */ jsx51(
@@ -6741,11 +6554,11 @@ var ButtonTextSettings = memo4(function ButtonTextSettings2() {
6741
6554
  Input,
6742
6555
  {
6743
6556
  type: "number",
6744
- value: letterSpacingInputValue,
6745
- onChange: handleLetterSpacingInputChange,
6746
- onFocus: () => setIsLetterSpacingInputFocused(true),
6747
- onBlur: handleLetterSpacingInputBlur,
6748
- onKeyDown: handleLetterSpacingInputKeyDown,
6557
+ value: letterSpacingInput.displayValue,
6558
+ onChange: (e) => letterSpacingInput.setLocalValue(e.target.value),
6559
+ onFocus: letterSpacingInput.handleFocus,
6560
+ onBlur: letterSpacingInput.handleBlur,
6561
+ onKeyDown: letterSpacingInput.handleKeyDown,
6749
6562
  className: "w-25 shadow-none rounded-[12px]",
6750
6563
  min: MIN_LETTER_SPACING,
6751
6564
  max: MAX_LETTER_SPACING,
@@ -6772,11 +6585,11 @@ var ButtonTextSettings = memo4(function ButtonTextSettings2() {
6772
6585
  Input,
6773
6586
  {
6774
6587
  type: "number",
6775
- value: lineHeightInputValue,
6776
- onChange: handleLineHeightInputChange,
6777
- onFocus: () => setIsLineHeightInputFocused(true),
6778
- onBlur: handleLineHeightInputBlur,
6779
- onKeyDown: handleLineHeightInputKeyDown,
6588
+ value: lineHeightInput.displayValue,
6589
+ onChange: (e) => lineHeightInput.setLocalValue(e.target.value),
6590
+ onFocus: lineHeightInput.handleFocus,
6591
+ onBlur: lineHeightInput.handleBlur,
6592
+ onKeyDown: lineHeightInput.handleKeyDown,
6780
6593
  className: "w-25 shadow-none rounded-[12px]",
6781
6594
  min: MIN_LINE_HEIGHT,
6782
6595
  max: MAX_LINE_HEIGHT,
@@ -6845,36 +6658,36 @@ var ButtonToolbar = () => {
6845
6658
  deleteElement(focusIdx);
6846
6659
  }
6847
6660
  };
6848
- const handleOpenBgColorPicker = useCallback31(() => {
6661
+ const handleOpenBgColorPicker = useCallback32(() => {
6849
6662
  setColorType("Button Color");
6850
6663
  setColorTarget("buttonBgColor");
6851
6664
  setActiveView("color");
6852
6665
  }, [setColorType, setColorTarget, setActiveView]);
6853
- const handleOpenStrokeColorPicker = useCallback31(() => {
6666
+ const handleOpenStrokeColorPicker = useCallback32(() => {
6854
6667
  setColorType("Stroke Color");
6855
6668
  setColorTarget("buttonStrokeColor");
6856
6669
  setActiveView("color");
6857
6670
  }, [setColorType, setColorTarget, setActiveView]);
6858
- const handleOpenTextColorPicker = useCallback31(() => {
6671
+ const handleOpenTextColorPicker = useCallback32(() => {
6859
6672
  setColorType("Text Color");
6860
6673
  setColorTarget("buttonTextColor");
6861
6674
  setActiveView("color");
6862
6675
  }, [setColorType, setColorTarget, setActiveView]);
6863
- const handleToggleBold = useCallback31(() => {
6676
+ const handleToggleBold = useCallback32(() => {
6864
6677
  if (!focusIdx || !currentElement) return;
6865
6678
  const newWeight = isBold ? "normal" : "bold";
6866
6679
  updateElement(focusIdx, {
6867
6680
  attributes: { ...currentElement.attributes, "font-weight": newWeight }
6868
6681
  });
6869
6682
  }, [focusIdx, currentElement, isBold, updateElement]);
6870
- const handleToggleItalic = useCallback31(() => {
6683
+ const handleToggleItalic = useCallback32(() => {
6871
6684
  if (!focusIdx || !currentElement) return;
6872
6685
  const newStyle = isItalic ? "normal" : "italic";
6873
6686
  updateElement(focusIdx, {
6874
6687
  attributes: { ...currentElement.attributes, "font-style": newStyle }
6875
6688
  });
6876
6689
  }, [focusIdx, currentElement, isItalic, updateElement]);
6877
- const handleToggleUnderline = useCallback31(() => {
6690
+ const handleToggleUnderline = useCallback32(() => {
6878
6691
  if (!focusIdx || !currentElement) return;
6879
6692
  const currentDecoration = currentElement.attributes?.["text-decoration"] || "";
6880
6693
  let newDecoration;
@@ -6887,7 +6700,7 @@ var ButtonToolbar = () => {
6887
6700
  attributes: { ...currentElement.attributes, "text-decoration": newDecoration || "none" }
6888
6701
  });
6889
6702
  }, [focusIdx, currentElement, isUnderline, updateElement]);
6890
- const handleToggleStrike = useCallback31(() => {
6703
+ const handleToggleStrike = useCallback32(() => {
6891
6704
  if (!focusIdx || !currentElement) return;
6892
6705
  const currentDecoration = currentElement.attributes?.["text-decoration"] || "";
6893
6706
  let newDecoration;
@@ -6900,7 +6713,7 @@ var ButtonToolbar = () => {
6900
6713
  attributes: { ...currentElement.attributes, "text-decoration": newDecoration || "none" }
6901
6714
  });
6902
6715
  }, [focusIdx, currentElement, isStrikethrough, updateElement]);
6903
- const handleCycleAlignment = useCallback31(() => {
6716
+ const handleCycleAlignment = useCallback32(() => {
6904
6717
  if (!focusIdx || !currentElement) return;
6905
6718
  const currentIndex = BUTTON_ALIGNMENTS.indexOf(currentAlignment);
6906
6719
  const nextIndex = (currentIndex + 1) % BUTTON_ALIGNMENTS.length;
@@ -6909,7 +6722,7 @@ var ButtonToolbar = () => {
6909
6722
  attributes: { ...currentElement.attributes, "text-align": nextAlignment }
6910
6723
  });
6911
6724
  }, [focusIdx, currentElement, currentAlignment, updateElement]);
6912
- const handleCycleButtonAlign = useCallback31(() => {
6725
+ const handleCycleButtonAlign = useCallback32(() => {
6913
6726
  if (!focusIdx || !currentElement) return;
6914
6727
  const currentIndex = BUTTON_ALIGNMENTS.indexOf(currentButtonAlign);
6915
6728
  const nextIndex = (currentIndex + 1) % BUTTON_ALIGNMENTS.length;
@@ -6918,13 +6731,13 @@ var ButtonToolbar = () => {
6918
6731
  attributes: { ...currentElement.attributes, "align": nextAlign }
6919
6732
  });
6920
6733
  }, [focusIdx, currentElement, currentButtonAlign, updateElement]);
6921
- const handleSetFontFamily = useCallback31((font) => {
6734
+ const handleSetFontFamily = useCallback32((font) => {
6922
6735
  if (!focusIdx || !currentElement) return;
6923
6736
  updateElement(focusIdx, {
6924
6737
  attributes: { ...currentElement.attributes, "font-family": font }
6925
6738
  });
6926
6739
  }, [focusIdx, currentElement, updateElement]);
6927
- const handleFontSizeChange = useCallback31((size2) => {
6740
+ const handleFontSizeChange = useCallback32((size2) => {
6928
6741
  if (!focusIdx || !currentElement) return;
6929
6742
  updateElement(focusIdx, {
6930
6743
  attributes: { ...currentElement.attributes, "font-size": `${size2}px` }
@@ -7112,15 +6925,15 @@ var ButtonToolbar = () => {
7112
6925
  };
7113
6926
 
7114
6927
  // src/core/editor/components/element-gear/section/toolbar.tsx
7115
- import { useCallback as useCallback33, useMemo as useMemo21 } from "react";
6928
+ import { useCallback as useCallback34, useMemo as useMemo21 } from "react";
7116
6929
  import { get as lodashGet9 } from "lodash";
7117
6930
 
7118
6931
  // src/core/editor/components/image-menu.tsx
7119
6932
  import { ImageIcon, TrashIcon as TrashIcon4, UploadIcon } from "lucide-react";
7120
- import { useState as useState18 } from "react";
6933
+ import { useState as useState19 } from "react";
7121
6934
 
7122
6935
  // src/core/editor/hooks/use-image.ts
7123
- import { useMemo as useMemo20, useCallback as useCallback32 } from "react";
6936
+ import { useMemo as useMemo20, useCallback as useCallback33 } from "react";
7124
6937
  import { get as lodashGet8 } from "lodash";
7125
6938
  var useImage = (options = {}) => {
7126
6939
  const { type = "background" } = options;
@@ -7152,13 +6965,13 @@ var useImage = (options = {}) => {
7152
6965
  height: el?.attributes?.["height"] || "auto"
7153
6966
  };
7154
6967
  }, [focusIdx, template, attributeName]);
7155
- const setUrl = useCallback32((newUrl) => {
6968
+ const setUrl = useCallback33((newUrl) => {
7156
6969
  if (!focusIdx || !element) return;
7157
6970
  updateElement(focusIdx, {
7158
6971
  attributes: { ...element.attributes, [attributeName]: newUrl }
7159
6972
  });
7160
6973
  }, [focusIdx, element, updateElement, attributeName]);
7161
- const removeUrl = useCallback32(() => {
6974
+ const removeUrl = useCallback33(() => {
7162
6975
  if (!focusIdx || !element) return;
7163
6976
  if (type === "background") {
7164
6977
  const newAttributes = { ...element.attributes };
@@ -7171,37 +6984,37 @@ var useImage = (options = {}) => {
7171
6984
  });
7172
6985
  }
7173
6986
  }, [focusIdx, element, updateElement, attributeName, type]);
7174
- const setPositionX = useCallback32((value) => {
6987
+ const setPositionX = useCallback33((value) => {
7175
6988
  if (!focusIdx || !element) return;
7176
6989
  updateElement(focusIdx, {
7177
6990
  attributes: { ...element.attributes, "background-position-x": value }
7178
6991
  });
7179
6992
  }, [focusIdx, element, updateElement]);
7180
- const setPositionY = useCallback32((value) => {
6993
+ const setPositionY = useCallback33((value) => {
7181
6994
  if (!focusIdx || !element) return;
7182
6995
  updateElement(focusIdx, {
7183
6996
  attributes: { ...element.attributes, "background-position-y": value }
7184
6997
  });
7185
6998
  }, [focusIdx, element, updateElement]);
7186
- const setBackgroundSize = useCallback32((value) => {
6999
+ const setBackgroundSize = useCallback33((value) => {
7187
7000
  if (!focusIdx || !element) return;
7188
7001
  updateElement(focusIdx, {
7189
7002
  attributes: { ...element.attributes, "background-size": value }
7190
7003
  });
7191
7004
  }, [focusIdx, element, updateElement]);
7192
- const setBackgroundRepeat = useCallback32((value) => {
7005
+ const setBackgroundRepeat = useCallback33((value) => {
7193
7006
  if (!focusIdx || !element) return;
7194
7007
  updateElement(focusIdx, {
7195
7008
  attributes: { ...element.attributes, "background-repeat": value }
7196
7009
  });
7197
7010
  }, [focusIdx, element, updateElement]);
7198
- const setWidth = useCallback32((value) => {
7011
+ const setWidth = useCallback33((value) => {
7199
7012
  if (!focusIdx || !element) return;
7200
7013
  updateElement(focusIdx, {
7201
7014
  attributes: { ...element.attributes, width: value }
7202
7015
  });
7203
7016
  }, [focusIdx, element, updateElement]);
7204
- const setHeight = useCallback32((value) => {
7017
+ const setHeight = useCallback33((value) => {
7205
7018
  if (!focusIdx || !element) return;
7206
7019
  updateElement(focusIdx, {
7207
7020
  attributes: { ...element.attributes, height: value }
@@ -7357,7 +7170,7 @@ var BgImgOptions = () => {
7357
7170
  // src/core/editor/components/image-menu.tsx
7358
7171
  import { Fragment as Fragment5, jsx as jsx55, jsxs as jsxs44 } from "react/jsx-runtime";
7359
7172
  var ImageMenu = ({ type }) => {
7360
- const [isOpen, setIsOpen] = useState18(false);
7173
+ const [isOpen, setIsOpen] = useState19(false);
7361
7174
  const { setActiveView, setImageTarget } = useSidebarContext();
7362
7175
  const { url, removeUrl } = useImage({ type });
7363
7176
  const handleSelectImage = () => {
@@ -7376,9 +7189,9 @@ var ImageMenu = ({ type }) => {
7376
7189
  Button,
7377
7190
  {
7378
7191
  variant: "outline",
7379
- className: "shadow-none transition-none cursor-pointer rounded-[12px]",
7192
+ className: "shadow-none transition-none cursor-pointer rounded-[12px] p-0.5 ",
7380
7193
  size: "icon",
7381
- children: url && !url.includes("placeholder_image.png") && url !== DEFAULT_PROPERTY_PLACEHOLDER_IMAGE ? /* @__PURE__ */ jsx55("img", { src: url, alt: "Background Image", className: "w-full h-full object-cover rounded-[12px]" }) : /* @__PURE__ */ jsx55(ImageIcon, { className: "w-4 h-4" })
7194
+ children: url && !url.includes("placeholder_image.png") && url !== DEFAULT_PROPERTY_PLACEHOLDER_IMAGE ? /* @__PURE__ */ jsx55("img", { src: url, alt: "Background Image", className: "w-full h-full object-cover rounded-[8px]" }) : /* @__PURE__ */ jsx55(ImageIcon, { className: "w-4 h-4" })
7382
7195
  }
7383
7196
  ) }) }),
7384
7197
  /* @__PURE__ */ jsxs44(PopoverContent, { className: "w-64 z-51 mt-1 rounded-[12px] p-3", children: [
@@ -7418,12 +7231,12 @@ var SectionToolbar = () => {
7418
7231
  deleteElement(focusIdx);
7419
7232
  }
7420
7233
  };
7421
- const handleOpenBgColorPicker = useCallback33(() => {
7234
+ const handleOpenBgColorPicker = useCallback34(() => {
7422
7235
  setColorType("Background Color");
7423
7236
  setColorTarget("sectionBgColor");
7424
7237
  setActiveView("color");
7425
7238
  }, [setColorType, setColorTarget, setActiveView]);
7426
- const handleOpenStrokeColorPicker = useCallback33(() => {
7239
+ const handleOpenStrokeColorPicker = useCallback34(() => {
7427
7240
  setColorType("Stroke Color");
7428
7241
  setColorTarget("strokeColor");
7429
7242
  setActiveView("color");
@@ -7486,7 +7299,7 @@ var SectionToolbar = () => {
7486
7299
  };
7487
7300
 
7488
7301
  // src/core/editor/components/element-gear/section-column/toolbar.tsx
7489
- import { useCallback as useCallback34, useMemo as useMemo22, useState as useState19 } from "react";
7302
+ import { useCallback as useCallback35, useMemo as useMemo22, useState as useState20 } from "react";
7490
7303
  import { CheckIcon as CheckIcon6, Columns2Icon, Columns3Icon, Columns4Icon } from "lucide-react";
7491
7304
  import { get as lodashGet10 } from "lodash";
7492
7305
  import { jsx as jsx57, jsxs as jsxs46 } from "react/jsx-runtime";
@@ -7494,8 +7307,8 @@ var VERTICAL_ALIGNMENTS = ["top", "middle", "bottom"];
7494
7307
  var SectionColumnToolbar = () => {
7495
7308
  const { focusIdx, deleteElement, template, setColumnCount, updateElement } = useEditorStore();
7496
7309
  const { activeView, colorTarget, setActiveView, setColorType, setColorTarget } = useSidebarContext();
7497
- const [columnCountOpen, setColumnCountOpen] = useState19(false);
7498
- const [verticalAlignOpen, setVerticalAlignOpen] = useState19(false);
7310
+ const [columnCountOpen, setColumnCountOpen] = useState20(false);
7311
+ const [verticalAlignOpen, setVerticalAlignOpen] = useState20(false);
7499
7312
  const element = useMemo22(() => {
7500
7313
  if (!focusIdx || !template) return null;
7501
7314
  const path = focusIdx.startsWith("content.") ? focusIdx.replace("content.", "content[0].").replace(/\.\[(\d+)\]/g, "[$1]") : focusIdx;
@@ -7515,17 +7328,17 @@ var SectionColumnToolbar = () => {
7515
7328
  deleteElement(focusIdx);
7516
7329
  }
7517
7330
  };
7518
- const handleOpenBgColorPicker = useCallback34(() => {
7331
+ const handleOpenBgColorPicker = useCallback35(() => {
7519
7332
  setColorType("Background Color");
7520
7333
  setColorTarget("sectionBgColor");
7521
7334
  setActiveView("color");
7522
7335
  }, [setColorType, setColorTarget, setActiveView]);
7523
- const handleOpenStrokeColorPicker = useCallback34(() => {
7336
+ const handleOpenStrokeColorPicker = useCallback35(() => {
7524
7337
  setColorType("Stroke Color");
7525
7338
  setColorTarget("strokeColor");
7526
7339
  setActiveView("color");
7527
7340
  }, [setColorType, setColorTarget, setActiveView]);
7528
- const handleVerticalAlignChange = useCallback34((align) => {
7341
+ const handleVerticalAlignChange = useCallback35((align) => {
7529
7342
  if (!focusIdx || !element?.children) return;
7530
7343
  const updatedChildren = element.children.map((child) => ({
7531
7344
  ...child,
@@ -7640,7 +7453,7 @@ var SectionColumnToolbar = () => {
7640
7453
  };
7641
7454
 
7642
7455
  // src/core/editor/components/element-gear/page/toolbar.tsx
7643
- import { useCallback as useCallback35, useMemo as useMemo23 } from "react";
7456
+ import { useCallback as useCallback36, useMemo as useMemo23 } from "react";
7644
7457
  import { jsx as jsx58, jsxs as jsxs47 } from "react/jsx-runtime";
7645
7458
  var PageToolbar = () => {
7646
7459
  const { focusIdx, template } = useEditorStore();
@@ -7650,7 +7463,7 @@ var PageToolbar = () => {
7650
7463
  const page = template.content?.[0];
7651
7464
  return page?.attributes?.["background-color"];
7652
7465
  }, [focusIdx, template]);
7653
- const handleOpenBgColorPicker = useCallback35(() => {
7466
+ const handleOpenBgColorPicker = useCallback36(() => {
7654
7467
  setColorType("Background Color");
7655
7468
  setColorTarget("sectionBgColor");
7656
7469
  setActiveView("color");
@@ -7671,10 +7484,10 @@ var PageToolbar = () => {
7671
7484
  };
7672
7485
 
7673
7486
  // src/core/editor/components/element-gear/spacer/toolbar.tsx
7674
- import { useCallback as useCallback37, useMemo as useMemo25 } from "react";
7487
+ import { useCallback as useCallback38, useMemo as useMemo25 } from "react";
7675
7488
 
7676
7489
  // src/core/editor/hooks/use-height.ts
7677
- import { useMemo as useMemo24, useCallback as useCallback36 } from "react";
7490
+ import { useMemo as useMemo24, useCallback as useCallback37 } from "react";
7678
7491
  import { get as lodashGet11 } from "lodash";
7679
7492
  var useHeight = () => {
7680
7493
  const { focusIdx, updateElement, template } = useEditorStore();
@@ -7687,7 +7500,7 @@ var useHeight = () => {
7687
7500
  const parsed = parseInt(rawValue.replace("px", ""), 10);
7688
7501
  return isNaN(parsed) ? 12 : Math.max(4, parsed);
7689
7502
  }, [focusIdx, template]);
7690
- const handleChange = useCallback36((value) => {
7503
+ const handleChange = useCallback37((value) => {
7691
7504
  if (!focusIdx || !template) return;
7692
7505
  const path = focusIdx.startsWith("content.") ? focusIdx.replace("content.", "content[0].").replace(/\.\[(\d+)\]/g, "[$1]") : focusIdx;
7693
7506
  const element = lodashGet11(template, path);
@@ -7719,7 +7532,7 @@ var SpacerToolbar = () => {
7719
7532
  const element = lodashGet12(template, path);
7720
7533
  return element?.attributes?.["container-background-color"];
7721
7534
  }, [focusIdx, template]);
7722
- const handleOpenBgColorPicker = useCallback37(() => {
7535
+ const handleOpenBgColorPicker = useCallback38(() => {
7723
7536
  setColorType("Background Color");
7724
7537
  setColorTarget("spacerBgColor");
7725
7538
  setActiveView("color");
@@ -7743,14 +7556,14 @@ var SpacerToolbar = () => {
7743
7556
 
7744
7557
  // src/core/editor/components/element-gear/social/toolbar.tsx
7745
7558
  import { AlignCenterIcon, AlignLeftIcon, AlignRightIcon, BoldIcon as BoldIcon3, CaseUpperIcon as CaseUpperIcon3, CheckIcon as CheckIcon7, ItalicIcon as ItalicIcon3, Scan, Strikethrough as Strikethrough3, Underline as Underline3 } from "lucide-react";
7746
- import { useCallback as useCallback39, useMemo as useMemo27 } from "react";
7559
+ import { useCallback as useCallback40, useMemo as useMemo27 } from "react";
7747
7560
 
7748
7561
  // src/core/editor/components/social-line-spacing.tsx
7749
7562
  import { TypeIcon as TypeIcon3 } from "lucide-react";
7750
- import { useState as useState20, useEffect as useEffect12, useMemo as useMemo26, useCallback as useCallback38, memo as memo5 } from "react";
7563
+ import { useState as useState21, useMemo as useMemo26, useCallback as useCallback39, memo as memo5 } from "react";
7751
7564
  import { jsx as jsx60, jsxs as jsxs49 } from "react/jsx-runtime";
7752
7565
  var SocialLineSpacing = memo5(function SocialLineSpacing2() {
7753
- const [isOpen, setIsOpen] = useState20(false);
7566
+ const [isOpen, setIsOpen] = useState21(false);
7754
7567
  const focusIdx = useEditorStore((s) => s.focusIdx);
7755
7568
  const template = useEditorStore((s) => s.template);
7756
7569
  const updateElement = useEditorStore((s) => s.updateElement);
@@ -7762,60 +7575,23 @@ var SocialLineSpacing = memo5(function SocialLineSpacing2() {
7762
7575
  const parsed = parseFloat(socialElement.attributes["line-height"]);
7763
7576
  return isNaN(parsed) ? DEFAULT_LINE_HEIGHT : parsed;
7764
7577
  }, [socialElement]);
7765
- const [lineHeightInputValue, setLineHeightInputValue] = useState20(
7766
- String(currentLineHeight)
7767
- );
7768
- const [isLineHeightInputFocused, setIsLineHeightInputFocused] = useState20(false);
7769
- useEffect12(() => {
7770
- if (!isLineHeightInputFocused) {
7771
- setLineHeightInputValue(String(currentLineHeight));
7772
- }
7773
- }, [currentLineHeight, isLineHeightInputFocused]);
7774
- const handleLineHeightSliderChange = useCallback38((values) => {
7578
+ const commitLineHeight = useCallback39((value) => {
7775
7579
  if (!focusIdx) return;
7776
- const value = values[0];
7777
- setLineHeightInputValue(String(value));
7778
7580
  const currentTemplate = useEditorStore.getState().template;
7779
7581
  const element = getValueByIdx(currentTemplate, focusIdx);
7780
7582
  updateElement(focusIdx, {
7781
- attributes: {
7782
- ...element?.attributes,
7783
- "line-height": String(value)
7784
- }
7583
+ attributes: { ...element?.attributes, "line-height": String(value) }
7785
7584
  });
7786
7585
  }, [focusIdx, updateElement]);
7787
- const handleLineHeightInputChange = useCallback38((e) => {
7788
- setLineHeightInputValue(e.target.value);
7789
- }, []);
7790
- const applyLineHeight = useCallback38(() => {
7791
- if (!focusIdx) return;
7792
- const parsed = parseFloat(lineHeightInputValue);
7793
- if (isNaN(parsed) || lineHeightInputValue === "") {
7794
- setLineHeightInputValue(String(currentLineHeight));
7795
- return;
7796
- }
7797
- const clampedValue = Math.max(MIN_LINE_HEIGHT, Math.min(parsed, MAX_LINE_HEIGHT));
7798
- setLineHeightInputValue(String(clampedValue));
7799
- const currentTemplate = useEditorStore.getState().template;
7800
- const element = getValueByIdx(currentTemplate, focusIdx);
7801
- updateElement(focusIdx, {
7802
- attributes: {
7803
- ...element?.attributes,
7804
- "line-height": String(clampedValue)
7805
- }
7806
- });
7807
- }, [focusIdx, lineHeightInputValue, currentLineHeight, updateElement]);
7808
- const handleLineHeightInputBlur = useCallback38(() => {
7809
- setIsLineHeightInputFocused(false);
7810
- applyLineHeight();
7811
- }, [applyLineHeight]);
7812
- const handleLineHeightInputKeyDown = useCallback38((e) => {
7813
- if (e.key === "Enter") {
7814
- e.preventDefault();
7815
- applyLineHeight();
7816
- e.target.blur();
7817
- }
7818
- }, [applyLineHeight]);
7586
+ const lineHeightInput = useEditableFloat({
7587
+ value: currentLineHeight,
7588
+ onChange: commitLineHeight,
7589
+ min: MIN_LINE_HEIGHT,
7590
+ max: MAX_LINE_HEIGHT
7591
+ });
7592
+ const handleLineHeightSliderChange = useCallback39((values) => {
7593
+ commitLineHeight(values[0]);
7594
+ }, [commitLineHeight]);
7819
7595
  return /* @__PURE__ */ jsxs49(Tooltip, { children: [
7820
7596
  /* @__PURE__ */ jsxs49(Popover, { open: isOpen, onOpenChange: setIsOpen, children: [
7821
7597
  /* @__PURE__ */ jsx60(PopoverTrigger, { asChild: true, children: /* @__PURE__ */ jsx60(TooltipTrigger, { asChild: true, children: /* @__PURE__ */ jsx60(
@@ -7851,11 +7627,11 @@ var SocialLineSpacing = memo5(function SocialLineSpacing2() {
7851
7627
  Input,
7852
7628
  {
7853
7629
  type: "number",
7854
- value: lineHeightInputValue,
7855
- onChange: handleLineHeightInputChange,
7856
- onFocus: () => setIsLineHeightInputFocused(true),
7857
- onBlur: handleLineHeightInputBlur,
7858
- onKeyDown: handleLineHeightInputKeyDown,
7630
+ value: lineHeightInput.displayValue,
7631
+ onChange: (e) => lineHeightInput.setLocalValue(e.target.value),
7632
+ onFocus: lineHeightInput.handleFocus,
7633
+ onBlur: lineHeightInput.handleBlur,
7634
+ onKeyDown: lineHeightInput.handleKeyDown,
7859
7635
  className: "w-25 shadow-none rounded-[12px]",
7860
7636
  min: MIN_LINE_HEIGHT,
7861
7637
  max: MAX_LINE_HEIGHT,
@@ -7927,12 +7703,12 @@ var SocialToolbar = () => {
7927
7703
  const firstChild = socialElement?.children?.[0];
7928
7704
  return firstChild?.attributes?.["align"] || "center";
7929
7705
  }, [socialElement]);
7930
- const handleOpenBgColorPicker = useCallback39(() => {
7706
+ const handleOpenBgColorPicker = useCallback40(() => {
7931
7707
  setColorType("Background Color");
7932
7708
  setColorTarget("socialBgColor");
7933
7709
  setActiveView("color");
7934
7710
  }, [setColorType, setColorTarget, setActiveView]);
7935
- const handleSocialStyleChange = useCallback39((value) => {
7711
+ const handleSocialStyleChange = useCallback40((value) => {
7936
7712
  if (!focusIdx) return;
7937
7713
  const currentTemplate = useEditorStore.getState().template;
7938
7714
  const element = getValueByIdx(currentTemplate, focusIdx);
@@ -7947,7 +7723,7 @@ var SocialToolbar = () => {
7947
7723
  }
7948
7724
  });
7949
7725
  }, [focusIdx, updateElement]);
7950
- const handleIconSizeChange = useCallback39((value) => {
7726
+ const handleIconSizeChange = useCallback40((value) => {
7951
7727
  if (!focusIdx) return;
7952
7728
  const currentTemplate = useEditorStore.getState().template;
7953
7729
  const element = getValueByIdx(currentTemplate, focusIdx);
@@ -7962,7 +7738,7 @@ var SocialToolbar = () => {
7962
7738
  }
7963
7739
  });
7964
7740
  }, [focusIdx, updateElement]);
7965
- const handleIconStyleChange = useCallback39((value) => {
7741
+ const handleIconStyleChange = useCallback40((value) => {
7966
7742
  if (!focusIdx) return;
7967
7743
  const currentTemplate = useEditorStore.getState().template;
7968
7744
  const element = getValueByIdx(currentTemplate, focusIdx);
@@ -7977,7 +7753,7 @@ var SocialToolbar = () => {
7977
7753
  }
7978
7754
  });
7979
7755
  }, [focusIdx, updateElement]);
7980
- const handleIconColorChange = useCallback39((value) => {
7756
+ const handleIconColorChange = useCallback40((value) => {
7981
7757
  if (!focusIdx) return;
7982
7758
  const currentTemplate = useEditorStore.getState().template;
7983
7759
  const element = getValueByIdx(currentTemplate, focusIdx);
@@ -7992,7 +7768,7 @@ var SocialToolbar = () => {
7992
7768
  }
7993
7769
  });
7994
7770
  }, [focusIdx, updateElement]);
7995
- const handleSetFontFamily = useCallback39((font) => {
7771
+ const handleSetFontFamily = useCallback40((font) => {
7996
7772
  if (!focusIdx) return;
7997
7773
  const currentTemplate = useEditorStore.getState().template;
7998
7774
  const element = getValueByIdx(currentTemplate, focusIdx);
@@ -8003,7 +7779,7 @@ var SocialToolbar = () => {
8003
7779
  }
8004
7780
  });
8005
7781
  }, [focusIdx, updateElement]);
8006
- const handleFontSizeChange = useCallback39((size) => {
7782
+ const handleFontSizeChange = useCallback40((size) => {
8007
7783
  if (!focusIdx) return;
8008
7784
  const currentTemplate = useEditorStore.getState().template;
8009
7785
  const element = getValueByIdx(currentTemplate, focusIdx);
@@ -8014,12 +7790,12 @@ var SocialToolbar = () => {
8014
7790
  }
8015
7791
  });
8016
7792
  }, [focusIdx, updateElement]);
8017
- const handleOpenTextColorPicker = useCallback39(() => {
7793
+ const handleOpenTextColorPicker = useCallback40(() => {
8018
7794
  setColorType("Text Color");
8019
7795
  setColorTarget("socialTextColor");
8020
7796
  setActiveView("color");
8021
7797
  }, [setColorType, setColorTarget, setActiveView]);
8022
- const handleToggleBold = useCallback39(() => {
7798
+ const handleToggleBold = useCallback40(() => {
8023
7799
  if (!focusIdx) return;
8024
7800
  const currentTemplate = useEditorStore.getState().template;
8025
7801
  const element = getValueByIdx(currentTemplate, focusIdx);
@@ -8031,7 +7807,7 @@ var SocialToolbar = () => {
8031
7807
  }
8032
7808
  });
8033
7809
  }, [focusIdx, isBold, updateElement]);
8034
- const handleToggleItalic = useCallback39(() => {
7810
+ const handleToggleItalic = useCallback40(() => {
8035
7811
  if (!focusIdx) return;
8036
7812
  const currentTemplate = useEditorStore.getState().template;
8037
7813
  const element = getValueByIdx(currentTemplate, focusIdx);
@@ -8043,7 +7819,7 @@ var SocialToolbar = () => {
8043
7819
  }
8044
7820
  });
8045
7821
  }, [focusIdx, isItalic, updateElement]);
8046
- const handleToggleUnderline = useCallback39(() => {
7822
+ const handleToggleUnderline = useCallback40(() => {
8047
7823
  if (!focusIdx) return;
8048
7824
  const currentTemplate = useEditorStore.getState().template;
8049
7825
  const element = getValueByIdx(currentTemplate, focusIdx);
@@ -8061,7 +7837,7 @@ var SocialToolbar = () => {
8061
7837
  }
8062
7838
  });
8063
7839
  }, [focusIdx, isUnderline, updateElement]);
8064
- const handleToggleStrike = useCallback39(() => {
7840
+ const handleToggleStrike = useCallback40(() => {
8065
7841
  if (!focusIdx) return;
8066
7842
  const currentTemplate = useEditorStore.getState().template;
8067
7843
  const element = getValueByIdx(currentTemplate, focusIdx);
@@ -8079,7 +7855,7 @@ var SocialToolbar = () => {
8079
7855
  }
8080
7856
  });
8081
7857
  }, [focusIdx, isStrikethrough, updateElement]);
8082
- const handleModeChange = useCallback39((mode) => {
7858
+ const handleModeChange = useCallback40((mode) => {
8083
7859
  if (!focusIdx) return;
8084
7860
  const currentTemplate = useEditorStore.getState().template;
8085
7861
  const element = getValueByIdx(currentTemplate, focusIdx);
@@ -8090,7 +7866,7 @@ var SocialToolbar = () => {
8090
7866
  }
8091
7867
  });
8092
7868
  }, [focusIdx, updateElement]);
8093
- const handleCycleAlign = useCallback39(() => {
7869
+ const handleCycleAlign = useCallback40(() => {
8094
7870
  if (!focusIdx) return;
8095
7871
  const currentTemplate = useEditorStore.getState().template;
8096
7872
  const element = getValueByIdx(currentTemplate, focusIdx);
@@ -8109,7 +7885,7 @@ var SocialToolbar = () => {
8109
7885
  children: updatedChildren
8110
7886
  });
8111
7887
  }, [focusIdx, currentAlign, updateElement]);
8112
- const handleCycleSocialItemAlign = useCallback39(() => {
7888
+ const handleCycleSocialItemAlign = useCallback40(() => {
8113
7889
  if (!focusIdx) return;
8114
7890
  const currentTemplate = useEditorStore.getState().template;
8115
7891
  const element = getValueByIdx(currentTemplate, focusIdx);
@@ -8353,7 +8129,7 @@ var SocialToolbar = () => {
8353
8129
 
8354
8130
  // src/core/editor/components/element-gear/social-item/toolbar.tsx
8355
8131
  import { AlignCenterIcon as AlignCenterIcon2, AlignLeftIcon as AlignLeftIcon2, AlignRightIcon as AlignRightIcon2, BoldIcon as BoldIcon4, CaseUpperIcon as CaseUpperIcon4, ItalicIcon as ItalicIcon4, RemoveFormatting, Strikethrough as Strikethrough4, Underline as Underline4 } from "lucide-react";
8356
- import { useCallback as useCallback40, useMemo as useMemo28 } from "react";
8132
+ import { useCallback as useCallback41, useMemo as useMemo28 } from "react";
8357
8133
  import { Fragment as Fragment7, jsx as jsx62, jsxs as jsxs51 } from "react/jsx-runtime";
8358
8134
  var ALIGNMENTS3 = ["left", "center", "right"];
8359
8135
  var SOCIAL_ITEM_ALIGNMENT_ICONS2 = {
@@ -8395,7 +8171,7 @@ var SocialItemToolbar = () => {
8395
8171
  const currentAlign = useMemo28(() => {
8396
8172
  return socialItemElement?.attributes?.["align"] || "center";
8397
8173
  }, [socialItemElement]);
8398
- const handleSetFontFamily = useCallback40((font) => {
8174
+ const handleSetFontFamily = useCallback41((font) => {
8399
8175
  if (!focusIdx) return;
8400
8176
  const currentTemplate = useEditorStore.getState().template;
8401
8177
  const element = getValueByIdx(currentTemplate, focusIdx);
@@ -8406,7 +8182,7 @@ var SocialItemToolbar = () => {
8406
8182
  }
8407
8183
  });
8408
8184
  }, [focusIdx, updateElement]);
8409
- const handleFontSizeChange = useCallback40((size) => {
8185
+ const handleFontSizeChange = useCallback41((size) => {
8410
8186
  if (!focusIdx) return;
8411
8187
  const currentTemplate = useEditorStore.getState().template;
8412
8188
  const element = getValueByIdx(currentTemplate, focusIdx);
@@ -8417,12 +8193,12 @@ var SocialItemToolbar = () => {
8417
8193
  }
8418
8194
  });
8419
8195
  }, [focusIdx, updateElement]);
8420
- const handleOpenTextColorPicker = useCallback40(() => {
8196
+ const handleOpenTextColorPicker = useCallback41(() => {
8421
8197
  setColorType("Text Color");
8422
8198
  setColorTarget("socialItemTextColor");
8423
8199
  setActiveView("color");
8424
8200
  }, [setColorType, setColorTarget, setActiveView]);
8425
- const handleToggleBold = useCallback40(() => {
8201
+ const handleToggleBold = useCallback41(() => {
8426
8202
  if (!focusIdx) return;
8427
8203
  const currentTemplate = useEditorStore.getState().template;
8428
8204
  const element = getValueByIdx(currentTemplate, focusIdx);
@@ -8434,7 +8210,7 @@ var SocialItemToolbar = () => {
8434
8210
  }
8435
8211
  });
8436
8212
  }, [focusIdx, isBold, updateElement]);
8437
- const handleToggleItalic = useCallback40(() => {
8213
+ const handleToggleItalic = useCallback41(() => {
8438
8214
  if (!focusIdx) return;
8439
8215
  const currentTemplate = useEditorStore.getState().template;
8440
8216
  const element = getValueByIdx(currentTemplate, focusIdx);
@@ -8446,7 +8222,7 @@ var SocialItemToolbar = () => {
8446
8222
  }
8447
8223
  });
8448
8224
  }, [focusIdx, isItalic, updateElement]);
8449
- const handleToggleUnderline = useCallback40(() => {
8225
+ const handleToggleUnderline = useCallback41(() => {
8450
8226
  if (!focusIdx) return;
8451
8227
  const currentTemplate = useEditorStore.getState().template;
8452
8228
  const element = getValueByIdx(currentTemplate, focusIdx);
@@ -8464,7 +8240,7 @@ var SocialItemToolbar = () => {
8464
8240
  }
8465
8241
  });
8466
8242
  }, [focusIdx, isUnderline, updateElement]);
8467
- const handleToggleStrike = useCallback40(() => {
8243
+ const handleToggleStrike = useCallback41(() => {
8468
8244
  if (!focusIdx) return;
8469
8245
  const currentTemplate = useEditorStore.getState().template;
8470
8246
  const element = getValueByIdx(currentTemplate, focusIdx);
@@ -8482,7 +8258,7 @@ var SocialItemToolbar = () => {
8482
8258
  }
8483
8259
  });
8484
8260
  }, [focusIdx, isStrikethrough, updateElement]);
8485
- const handleRemoveFormatting = useCallback40(() => {
8261
+ const handleRemoveFormatting = useCallback41(() => {
8486
8262
  if (!focusIdx) return;
8487
8263
  const currentTemplate = useEditorStore.getState().template;
8488
8264
  const element = getValueByIdx(currentTemplate, focusIdx);
@@ -8500,7 +8276,7 @@ var SocialItemToolbar = () => {
8500
8276
  attributes: restAttributes
8501
8277
  });
8502
8278
  }, [focusIdx, updateElement]);
8503
- const handleCycleAlign = useCallback40(() => {
8279
+ const handleCycleAlign = useCallback41(() => {
8504
8280
  if (!focusIdx) return;
8505
8281
  const currentTemplate = useEditorStore.getState().template;
8506
8282
  const element = getValueByIdx(currentTemplate, focusIdx);
@@ -8646,7 +8422,7 @@ var SocialItemToolbar = () => {
8646
8422
 
8647
8423
  // src/core/editor/components/element-gear/divider/_components/stroke-weight.tsx
8648
8424
  import { MinusIcon as MinusIcon4 } from "lucide-react";
8649
- import { useState as useState21, useEffect as useEffect13, useCallback as useCallback41 } from "react";
8425
+ import { useState as useState22, useCallback as useCallback42 } from "react";
8650
8426
  import { jsx as jsx63, jsxs as jsxs52 } from "react/jsx-runtime";
8651
8427
  var StrokeWeight2 = ({
8652
8428
  width,
@@ -8655,34 +8431,11 @@ var StrokeWeight2 = ({
8655
8431
  onStyleChange,
8656
8432
  tooltipText = "Stroke Weight"
8657
8433
  }) => {
8658
- const [isOpen, setIsOpen] = useState21(false);
8659
- const [inputValue, setInputValue] = useState21(width.toString());
8660
- useEffect13(() => {
8661
- setInputValue(width.toString());
8662
- }, [width]);
8663
- const handleSliderChange = useCallback41((values) => {
8664
- const newWidth = values[0];
8665
- setInputValue(newWidth.toString());
8666
- onWidthChange(newWidth);
8434
+ const [isOpen, setIsOpen] = useState22(false);
8435
+ const input = useEditableNumber({ value: width, onChange: onWidthChange, min: 1, max: 50 });
8436
+ const handleSliderChange = useCallback42((values) => {
8437
+ onWidthChange(values[0]);
8667
8438
  }, [onWidthChange]);
8668
- const handleInputChange = useCallback41((e) => {
8669
- setInputValue(e.target.value);
8670
- }, []);
8671
- const handleInputBlur = useCallback41(() => {
8672
- const parsed = parseInt(inputValue, 10);
8673
- if (isNaN(parsed)) {
8674
- setInputValue(width.toString());
8675
- return;
8676
- }
8677
- const clamped = Math.max(1, Math.min(50, parsed));
8678
- setInputValue(clamped.toString());
8679
- onWidthChange(clamped);
8680
- }, [inputValue, width, onWidthChange]);
8681
- const handleInputKeyDown = useCallback41((e) => {
8682
- if (e.key === "Enter") {
8683
- handleInputBlur();
8684
- }
8685
- }, [handleInputBlur]);
8686
8439
  return /* @__PURE__ */ jsxs52(Tooltip, { children: [
8687
8440
  /* @__PURE__ */ jsxs52(Popover, { open: isOpen, onOpenChange: setIsOpen, children: [
8688
8441
  /* @__PURE__ */ jsx63(PopoverTrigger, { asChild: true, children: /* @__PURE__ */ jsx63(TooltipTrigger, { asChild: true, children: /* @__PURE__ */ jsx63(
@@ -8748,10 +8501,11 @@ var StrokeWeight2 = ({
8748
8501
  Input,
8749
8502
  {
8750
8503
  type: "number",
8751
- value: inputValue,
8752
- onChange: handleInputChange,
8753
- onBlur: handleInputBlur,
8754
- onKeyDown: handleInputKeyDown,
8504
+ value: input.displayValue,
8505
+ onChange: (e) => input.setLocalValue(e.target.value),
8506
+ onFocus: input.handleFocus,
8507
+ onBlur: input.handleBlur,
8508
+ onKeyDown: input.handleKeyDown,
8755
8509
  className: "w-25 shadow-none rounded-[12px]",
8756
8510
  min: 1,
8757
8511
  max: 50
@@ -8766,7 +8520,7 @@ var StrokeWeight2 = ({
8766
8520
  };
8767
8521
 
8768
8522
  // src/core/editor/hooks/use-divider-border.ts
8769
- import { useMemo as useMemo29, useCallback as useCallback42 } from "react";
8523
+ import { useMemo as useMemo29, useCallback as useCallback43 } from "react";
8770
8524
  var useDividerBorder = () => {
8771
8525
  const { focusIdx, updateElement, template } = useEditorStore();
8772
8526
  const { element, width, style, color } = useMemo29(() => {
@@ -8787,7 +8541,7 @@ var useDividerBorder = () => {
8787
8541
  color: rawColor
8788
8542
  };
8789
8543
  }, [focusIdx, template]);
8790
- const setWidth = useCallback42((newWidth) => {
8544
+ const setWidth = useCallback43((newWidth) => {
8791
8545
  if (!focusIdx || !template || !element) return;
8792
8546
  const clampedWidth = Math.max(1, Math.min(50, newWidth));
8793
8547
  updateElement(focusIdx, {
@@ -8797,7 +8551,7 @@ var useDividerBorder = () => {
8797
8551
  }
8798
8552
  });
8799
8553
  }, [focusIdx, template, element, updateElement]);
8800
- const setStyle = useCallback42((newStyle) => {
8554
+ const setStyle = useCallback43((newStyle) => {
8801
8555
  if (!focusIdx || !template || !element) return;
8802
8556
  updateElement(focusIdx, {
8803
8557
  attributes: {
@@ -8816,7 +8570,7 @@ var useDividerBorder = () => {
8816
8570
  };
8817
8571
 
8818
8572
  // src/core/editor/hooks/use-width.ts
8819
- import { useMemo as useMemo30, useCallback as useCallback43 } from "react";
8573
+ import { useMemo as useMemo30, useCallback as useCallback44 } from "react";
8820
8574
  var useWidth = () => {
8821
8575
  const { focusIdx, updateElement, template } = useEditorStore();
8822
8576
  const currentValue = useMemo30(() => {
@@ -8827,7 +8581,7 @@ var useWidth = () => {
8827
8581
  const parsed = parseFloat(rawValue.replace("%", ""));
8828
8582
  return isNaN(parsed) ? 100 : Math.max(10, Math.min(100, parsed));
8829
8583
  }, [focusIdx, template]);
8830
- const handleChange = useCallback43((value) => {
8584
+ const handleChange = useCallback44((value) => {
8831
8585
  if (!focusIdx || !template) return;
8832
8586
  const element = getValueByIdx(template, focusIdx);
8833
8587
  if (!element) return;
@@ -8846,7 +8600,7 @@ var useWidth = () => {
8846
8600
  };
8847
8601
 
8848
8602
  // src/core/editor/components/element-gear/divider/toolbar.tsx
8849
- import { useCallback as useCallback44, useMemo as useMemo31 } from "react";
8603
+ import { useCallback as useCallback45, useMemo as useMemo31 } from "react";
8850
8604
  import lodashGet13 from "lodash/get";
8851
8605
  import { jsx as jsx64, jsxs as jsxs53 } from "react/jsx-runtime";
8852
8606
  var DIVIDER_ALIGNMENTS = ["left", "center", "right"];
@@ -8863,17 +8617,17 @@ var DividerToolbar = () => {
8863
8617
  }, [focusIdx, template]);
8864
8618
  const currentAlign = currentElement?.attributes?.align || "center";
8865
8619
  const currentBgColor = currentElement?.attributes?.["container-background-color"];
8866
- const handleOpenBgColorPicker = useCallback44(() => {
8620
+ const handleOpenBgColorPicker = useCallback45(() => {
8867
8621
  setColorType("Background Color");
8868
8622
  setColorTarget("dividerBgColor");
8869
8623
  setActiveView("color");
8870
8624
  }, [setColorType, setColorTarget, setActiveView]);
8871
- const handleOpenStrokeColorPicker = useCallback44(() => {
8625
+ const handleOpenStrokeColorPicker = useCallback45(() => {
8872
8626
  setColorType("Stroke Color");
8873
8627
  setColorTarget("dividerBorderColor");
8874
8628
  setActiveView("color");
8875
8629
  }, [setColorType, setColorTarget, setActiveView]);
8876
- const handleCycleAlign = useCallback44(() => {
8630
+ const handleCycleAlign = useCallback45(() => {
8877
8631
  if (!focusIdx || !currentElement) return;
8878
8632
  const currentIndex = DIVIDER_ALIGNMENTS.indexOf(currentAlign);
8879
8633
  const nextIndex = (currentIndex + 1) % DIVIDER_ALIGNMENTS.length;
@@ -8946,7 +8700,7 @@ var DividerToolbar = () => {
8946
8700
  };
8947
8701
 
8948
8702
  // src/core/editor/components/element-gear/image/toolbar.tsx
8949
- import { useCallback as useCallback45, useMemo as useMemo32 } from "react";
8703
+ import { useCallback as useCallback46, useMemo as useMemo32 } from "react";
8950
8704
  import { get as lodashGet14 } from "lodash";
8951
8705
  import { jsx as jsx65, jsxs as jsxs54 } from "react/jsx-runtime";
8952
8706
  var ImageToolbar = () => {
@@ -8966,17 +8720,17 @@ var ImageToolbar = () => {
8966
8720
  const border = useBorder();
8967
8721
  const borderRadius = useBorderRadius();
8968
8722
  const padding = usePadding();
8969
- const handleOpenBgColorPicker = useCallback45(() => {
8723
+ const handleOpenBgColorPicker = useCallback46(() => {
8970
8724
  setColorType("Background Color");
8971
8725
  setColorTarget("imageBgColor");
8972
8726
  setActiveView("color");
8973
8727
  }, [setColorType, setColorTarget, setActiveView]);
8974
- const handleOpenStrokeColorPicker = useCallback45(() => {
8728
+ const handleOpenStrokeColorPicker = useCallback46(() => {
8975
8729
  setColorType("Stroke Color");
8976
8730
  setColorTarget("strokeColor");
8977
8731
  setActiveView("color");
8978
8732
  }, [setColorType, setColorTarget, setActiveView]);
8979
- const handleCycleAlign = useCallback45(() => {
8733
+ const handleCycleAlign = useCallback46(() => {
8980
8734
  if (!focusIdx || !currentElement) return;
8981
8735
  const currentIndex = BUTTON_ALIGNMENTS.indexOf(currentAlign);
8982
8736
  const nextIndex = (currentIndex + 1) % BUTTON_ALIGNMENTS.length;
@@ -9059,11 +8813,11 @@ var ImageToolbar = () => {
9059
8813
  };
9060
8814
 
9061
8815
  // src/core/editor/components/element-gear/property/toolbar.tsx
9062
- import { useMemo as useMemo34, useCallback as useCallback47 } from "react";
8816
+ import { useMemo as useMemo34, useCallback as useCallback48 } from "react";
9063
8817
 
9064
8818
  // src/core/editor/components/property-edit-menu.tsx
9065
- import { ChevronDownIcon as ChevronDownIcon4, CircleCheckIcon, HouseIcon } from "lucide-react";
9066
- import { useState as useState22, useCallback as useCallback46, useMemo as useMemo33, useEffect as useEffect14 } from "react";
8819
+ import { ChevronDownIcon as ChevronDownIcon4, CircleCheckIcon, SquarePen } from "lucide-react";
8820
+ import { useState as useState23, useCallback as useCallback47, useMemo as useMemo33 } from "react";
9067
8821
 
9068
8822
  // src/components/ui/checkbox.tsx
9069
8823
  import * as CheckboxPrimitive from "@radix-ui/react-checkbox";
@@ -9144,12 +8898,16 @@ var CARD_FEATURES = {
9144
8898
  var PropertyEditMenu = () => {
9145
8899
  const { focusIdx, template, updateElement } = useEditorStore();
9146
8900
  const { activeView, colorTarget, setActiveView, setColorType, setColorTarget } = useSidebarContext();
9147
- const [isOpen, setIsOpen] = useState22(false);
9148
- const [openSection, setOpenSection] = useState22(null);
9149
- const [openhouseEnabled, setOpenhouseEnabled] = useState22(true);
9150
- const [openhouseDate, setOpenhouseDate] = useState22(/* @__PURE__ */ new Date());
9151
- const [openhouseStartTime, setOpenhouseStartTime] = useState22("12:00");
9152
- const [openhouseEndTime, setOpenhouseEndTime] = useState22("13:00");
8901
+ const [isOpen, setIsOpen] = useState23(false);
8902
+ const [openSection, setOpenSection] = useState23(null);
8903
+ const [openhouseDate, setOpenhouseDate] = useState23(/* @__PURE__ */ new Date());
8904
+ const [openhouseStartTime, setOpenhouseStartTime] = useState23("12:00");
8905
+ const [openhouseEndTime, setOpenhouseEndTime] = useState23("13:00");
8906
+ const [addressLine1Input, setAddressLine1Input] = useState23("");
8907
+ const [addressLine2Input, setAddressLine2Input] = useState23("");
8908
+ const [cityInput, setCityInput] = useState23("");
8909
+ const [stateInput, setStateInput] = useState23("");
8910
+ const [zipInput, setZipInput] = useState23("");
9153
8911
  const propertyElement = useMemo33(() => {
9154
8912
  if (!focusIdx || !template) return null;
9155
8913
  return getValueByIdx(template, focusIdx);
@@ -9160,20 +8918,6 @@ var PropertyEditMenu = () => {
9160
8918
  const rawPrice = propertyElement?.attributes?.["price"] || "";
9161
8919
  return parsePrice(rawPrice);
9162
8920
  }, [propertyElement]);
9163
- const [priceInput, setPriceInput] = useState22(currentPrice);
9164
- useEffect14(() => {
9165
- setPriceInput(currentPrice);
9166
- }, [currentPrice]);
9167
- const handlePriceBlur = useCallback46(() => {
9168
- if (!focusIdx || !propertyElement) return;
9169
- if (priceInput === currentPrice) return;
9170
- updateElement(focusIdx, {
9171
- attributes: {
9172
- ...propertyElement.attributes,
9173
- "price": priceInput
9174
- }
9175
- });
9176
- }, [focusIdx, propertyElement, priceInput, currentPrice, updateElement]);
9177
8921
  const currentBeds = useMemo33(() => propertyElement?.attributes?.["beds"] || "", [propertyElement]);
9178
8922
  const currentBaths = useMemo33(() => propertyElement?.attributes?.["baths"] || "", [propertyElement]);
9179
8923
  const currentSqft = useMemo33(() => propertyElement?.attributes?.["sqft"] || "", [propertyElement]);
@@ -9191,200 +8935,57 @@ var PropertyEditMenu = () => {
9191
8935
  const currentAddress = useMemo33(() => propertyElement?.attributes?.["address"] || "", [propertyElement]);
9192
8936
  const currentCity = useMemo33(() => propertyElement?.attributes?.["city"] || "", [propertyElement]);
9193
8937
  const currentCountry = useMemo33(() => propertyElement?.attributes?.["country"] || "USA", [propertyElement]);
9194
- const [bedsInput, setBedsInput] = useState22(currentBeds);
9195
- const [bathsInput, setBathsInput] = useState22(currentBaths);
9196
- const [sqftInput, setSqftInput] = useState22(currentSqft);
9197
- const [descriptionInput, setDescriptionInput] = useState22(currentDescription);
9198
- const [isDescriptionEnabled, setIsDescriptionEnabled] = useState22(!!currentIsDescription);
9199
- const [brokerageInput, setBrokerageInput] = useState22(currentBrokerage);
9200
- const [isBrokerageEnabled, setIsBrokerageEnabled] = useState22(!!currentIsBrokerage);
9201
- const [statusInput, setStatusInput] = useState22(currentStatus);
9202
- const [isStatusEnabled, setIsStatusEnabled] = useState22(!!currentIsStatus);
9203
- const [isNewEnabled, setIsNewEnabled] = useState22(!!currentIsNew);
9204
- const [addressLine1Input, setAddressLine1Input] = useState22("");
9205
- const [addressLine2Input, setAddressLine2Input] = useState22("");
9206
- const [cityInput, setCityInput] = useState22("");
9207
- const [stateInput, setStateInput] = useState22("");
9208
- const [zipInput, setZipInput] = useState22("");
9209
- const [countryInput, setCountryInput] = useState22("USA");
9210
- useEffect14(() => {
9211
- setBedsInput(currentBeds);
9212
- }, [currentBeds]);
9213
- useEffect14(() => {
9214
- setBathsInput(currentBaths);
9215
- }, [currentBaths]);
9216
- useEffect14(() => {
9217
- setSqftInput(currentSqft);
9218
- }, [currentSqft]);
9219
- useEffect14(() => {
9220
- setDescriptionInput(currentDescription);
9221
- }, [currentDescription]);
9222
- useEffect14(() => {
9223
- setIsDescriptionEnabled(!!currentIsDescription);
9224
- }, [currentIsDescription]);
9225
- useEffect14(() => {
9226
- setBrokerageInput(currentBrokerage);
9227
- }, [currentBrokerage]);
9228
- useEffect14(() => {
9229
- setIsBrokerageEnabled(!!currentIsBrokerage);
9230
- }, [currentIsBrokerage]);
9231
- useEffect14(() => {
9232
- setStatusInput(currentStatus);
9233
- }, [currentStatus]);
9234
- useEffect14(() => {
9235
- setIsStatusEnabled(!!currentIsStatus);
9236
- }, [currentIsStatus]);
9237
- useEffect14(() => {
9238
- setIsNewEnabled(!!currentIsNew);
9239
- }, [currentIsNew]);
9240
- useEffect14(() => {
9241
- setOpenhouseEnabled(!!currentIsOpenHouse);
9242
- }, [currentIsOpenHouse]);
9243
- useEffect14(() => {
9244
- if (currentOpenHouseDate) {
9245
- const parsed = new Date(currentOpenHouseDate);
9246
- if (!isNaN(parsed.getTime())) {
9247
- setOpenhouseDate(parsed);
9248
- }
9249
- }
9250
- }, [currentOpenHouseDate]);
9251
- useEffect14(() => {
9252
- if (currentOpenHouseTime) {
9253
- const [start, end] = currentOpenHouseTime.split("-");
9254
- if (start) setOpenhouseStartTime(start);
9255
- if (end) setOpenhouseEndTime(end);
9256
- }
9257
- }, [currentOpenHouseTime]);
9258
- useEffect14(() => {
9259
- setAddressLine1Input(currentAddress);
9260
- setAddressLine2Input("");
9261
- }, [currentAddress]);
9262
- useEffect14(() => {
9263
- const match = currentCity.match(/^(.+),\s*(\w{2})\s*(\d{5})?$/);
9264
- if (match) {
9265
- setCityInput(match[1] || "");
9266
- setStateInput(match[2] || "");
9267
- setZipInput(match[3] || "");
9268
- } else {
9269
- setCityInput(currentCity);
9270
- setStateInput("");
9271
- setZipInput("");
9272
- }
9273
- }, [currentCity]);
9274
- useEffect14(() => {
9275
- setCountryInput(currentCountry);
9276
- }, [currentCountry]);
9277
- const handleBedsBlur = useCallback46(() => {
9278
- if (!focusIdx || !propertyElement) return;
9279
- if (bedsInput === currentBeds) return;
9280
- updateElement(focusIdx, {
9281
- attributes: {
9282
- ...propertyElement.attributes,
9283
- "beds": bedsInput
9284
- }
9285
- });
9286
- }, [focusIdx, propertyElement, bedsInput, currentBeds, updateElement]);
9287
- const handleBathsBlur = useCallback46(() => {
9288
- if (!focusIdx || !propertyElement) return;
9289
- if (bathsInput === currentBaths) return;
9290
- updateElement(focusIdx, {
9291
- attributes: {
9292
- ...propertyElement.attributes,
9293
- "baths": bathsInput
9294
- }
9295
- });
9296
- }, [focusIdx, propertyElement, bathsInput, currentBaths, updateElement]);
9297
- const handleSqftBlur = useCallback46(() => {
9298
- if (!focusIdx || !propertyElement) return;
9299
- if (sqftInput === currentSqft) return;
9300
- updateElement(focusIdx, {
9301
- attributes: {
9302
- ...propertyElement.attributes,
9303
- "sqft": sqftInput
9304
- }
9305
- });
9306
- }, [focusIdx, propertyElement, sqftInput, currentSqft, updateElement]);
9307
- const handleDescriptionBlur = useCallback46(() => {
8938
+ const commitAttribute = useCallback47((key, value) => {
9308
8939
  if (!focusIdx || !propertyElement) return;
9309
- if (descriptionInput === currentDescription) return;
9310
8940
  updateElement(focusIdx, {
9311
- attributes: {
9312
- ...propertyElement.attributes,
9313
- "description": descriptionInput
9314
- }
9315
- });
9316
- }, [focusIdx, propertyElement, descriptionInput, currentDescription, updateElement]);
9317
- const handleIsDescriptionChange = useCallback46((checked) => {
9318
- setIsDescriptionEnabled(checked);
9319
- if (!focusIdx || !propertyElement) return;
9320
- updateElement(focusIdx, {
9321
- attributes: {
9322
- ...propertyElement.attributes,
9323
- "is-description": checked ? "show" : ""
9324
- }
8941
+ attributes: { ...propertyElement.attributes, [key]: value }
9325
8942
  });
9326
8943
  }, [focusIdx, propertyElement, updateElement]);
9327
- const handleBrokerageBlur = useCallback46(() => {
9328
- if (!focusIdx || !propertyElement) return;
9329
- if (brokerageInput === currentBrokerage) return;
9330
- updateElement(focusIdx, {
9331
- attributes: {
9332
- ...propertyElement.attributes,
9333
- "brokerage": brokerageInput
9334
- }
9335
- });
9336
- }, [focusIdx, propertyElement, brokerageInput, currentBrokerage, updateElement]);
9337
- const handleIsBrokerageChange = useCallback46((checked) => {
9338
- setIsBrokerageEnabled(checked);
8944
+ const commitPrice = useCallback47((v) => commitAttribute("price", v), [commitAttribute]);
8945
+ const commitBeds = useCallback47((v) => commitAttribute("beds", v), [commitAttribute]);
8946
+ const commitBaths = useCallback47((v) => commitAttribute("baths", v), [commitAttribute]);
8947
+ const commitSqft = useCallback47((v) => commitAttribute("sqft", v), [commitAttribute]);
8948
+ const commitDescription = useCallback47((v) => commitAttribute("description", v), [commitAttribute]);
8949
+ const commitBrokerage = useCallback47((v) => commitAttribute("brokerage", v), [commitAttribute]);
8950
+ const commitStatus = useCallback47((v) => commitAttribute("status", v), [commitAttribute]);
8951
+ const priceInput = useEditableValue({ externalValue: currentPrice, onChange: commitPrice });
8952
+ const bedsInput = useEditableValue({ externalValue: currentBeds, onChange: commitBeds });
8953
+ const bathsInput = useEditableValue({ externalValue: currentBaths, onChange: commitBaths });
8954
+ const sqftInput = useEditableValue({ externalValue: currentSqft, onChange: commitSqft });
8955
+ const descriptionInput = useEditableValue({ externalValue: currentDescription, onChange: commitDescription });
8956
+ const brokerageInput = useEditableValue({ externalValue: currentBrokerage, onChange: commitBrokerage });
8957
+ const statusInput = useEditableValue({ externalValue: currentStatus, onChange: commitStatus });
8958
+ const handleIsDescriptionChange = useCallback47((checked) => {
9339
8959
  if (!focusIdx || !propertyElement) return;
9340
8960
  updateElement(focusIdx, {
9341
- attributes: {
9342
- ...propertyElement.attributes,
9343
- "is-brokerage": checked ? "show" : ""
9344
- }
8961
+ attributes: { ...propertyElement.attributes, "is-description": checked ? "show" : "" }
9345
8962
  });
9346
8963
  }, [focusIdx, propertyElement, updateElement]);
9347
- const handleStatusBlur = useCallback46(() => {
8964
+ const handleIsBrokerageChange = useCallback47((checked) => {
9348
8965
  if (!focusIdx || !propertyElement) return;
9349
- if (statusInput === currentStatus) return;
9350
8966
  updateElement(focusIdx, {
9351
- attributes: {
9352
- ...propertyElement.attributes,
9353
- "status": statusInput
9354
- }
8967
+ attributes: { ...propertyElement.attributes, "is-brokerage": checked ? "show" : "" }
9355
8968
  });
9356
- }, [focusIdx, propertyElement, statusInput, currentStatus, updateElement]);
9357
- const handleIsStatusChange = useCallback46((checked) => {
9358
- setIsStatusEnabled(checked);
8969
+ }, [focusIdx, propertyElement, updateElement]);
8970
+ const handleIsStatusChange = useCallback47((checked) => {
9359
8971
  if (!focusIdx || !propertyElement) return;
9360
8972
  updateElement(focusIdx, {
9361
- attributes: {
9362
- ...propertyElement.attributes,
9363
- "is-status": checked ? "show" : ""
9364
- }
8973
+ attributes: { ...propertyElement.attributes, "is-status": checked ? "show" : "" }
9365
8974
  });
9366
8975
  }, [focusIdx, propertyElement, updateElement]);
9367
- const handleIsNewChange = useCallback46((checked) => {
9368
- setIsNewEnabled(checked);
8976
+ const handleIsNewChange = useCallback47((checked) => {
9369
8977
  if (!focusIdx || !propertyElement) return;
9370
8978
  updateElement(focusIdx, {
9371
- attributes: {
9372
- ...propertyElement.attributes,
9373
- "is-new": checked ? "show" : ""
9374
- }
8979
+ attributes: { ...propertyElement.attributes, "is-new": checked ? "show" : "" }
9375
8980
  });
9376
8981
  }, [focusIdx, propertyElement, updateElement]);
9377
- const handleIsOpenHouseChange = useCallback46((checked) => {
9378
- setOpenhouseEnabled(checked);
8982
+ const handleIsOpenHouseChange = useCallback47((checked) => {
9379
8983
  if (!focusIdx || !propertyElement) return;
9380
8984
  updateElement(focusIdx, {
9381
- attributes: {
9382
- ...propertyElement.attributes,
9383
- "is-open-house": checked ? "show" : ""
9384
- }
8985
+ attributes: { ...propertyElement.attributes, "is-open-house": checked ? "show" : "" }
9385
8986
  });
9386
8987
  }, [focusIdx, propertyElement, updateElement]);
9387
- const handleOpenHouseDateBlur = useCallback46(() => {
8988
+ const handleOpenHouseDateBlur = useCallback47(() => {
9388
8989
  if (!focusIdx || !propertyElement) return;
9389
8990
  const newDate = openhouseDate ? openhouseDate.toISOString().split("T")[0] : "";
9390
8991
  if (newDate === currentOpenHouseDate) return;
@@ -9395,7 +8996,7 @@ var PropertyEditMenu = () => {
9395
8996
  }
9396
8997
  });
9397
8998
  }, [focusIdx, propertyElement, openhouseDate, currentOpenHouseDate, updateElement]);
9398
- const handleOpenHouseTimeBlur = useCallback46(() => {
8999
+ const handleOpenHouseTimeBlur = useCallback47(() => {
9399
9000
  if (!focusIdx || !propertyElement) return;
9400
9001
  const newTime = `${openhouseStartTime}-${openhouseEndTime}`;
9401
9002
  if (newTime === currentOpenHouseTime) return;
@@ -9406,7 +9007,7 @@ var PropertyEditMenu = () => {
9406
9007
  }
9407
9008
  });
9408
9009
  }, [focusIdx, propertyElement, openhouseStartTime, openhouseEndTime, currentOpenHouseTime, updateElement]);
9409
- const handleAddressBlur = useCallback46(() => {
9010
+ const handleAddressBlur = useCallback47(() => {
9410
9011
  if (!focusIdx || !propertyElement) return;
9411
9012
  const newAddress = addressLine2Input ? `${addressLine1Input}, ${addressLine2Input}` : addressLine1Input;
9412
9013
  if (newAddress === currentAddress) return;
@@ -9417,7 +9018,7 @@ var PropertyEditMenu = () => {
9417
9018
  }
9418
9019
  });
9419
9020
  }, [focusIdx, propertyElement, addressLine1Input, addressLine2Input, currentAddress, updateElement]);
9420
- const handleCityBlur = useCallback46(() => {
9021
+ const handleCityBlur = useCallback47(() => {
9421
9022
  if (!focusIdx || !propertyElement) return;
9422
9023
  const newCity = zipInput ? `${cityInput}, ${stateInput} ${zipInput}` : stateInput ? `${cityInput}, ${stateInput}` : cityInput;
9423
9024
  if (newCity === currentCity) return;
@@ -9428,41 +9029,68 @@ var PropertyEditMenu = () => {
9428
9029
  }
9429
9030
  });
9430
9031
  }, [focusIdx, propertyElement, cityInput, stateInput, zipInput, currentCity, updateElement]);
9431
- const handleCountryChange = useCallback46((value) => {
9432
- setCountryInput(value);
9032
+ const handleCountryChange = useCallback47((value) => {
9433
9033
  if (!focusIdx || !propertyElement) return;
9434
9034
  updateElement(focusIdx, {
9435
- attributes: {
9436
- ...propertyElement.attributes,
9437
- "country": value
9438
- }
9035
+ attributes: { ...propertyElement.attributes, "country": value }
9439
9036
  });
9440
9037
  }, [focusIdx, propertyElement, updateElement]);
9441
- const handleOpenStatusColorPicker = useCallback46(() => {
9038
+ const handleOpenStatusColorPicker = useCallback47(() => {
9442
9039
  setColorType("Status Color");
9443
9040
  setColorTarget("statusColor");
9444
9041
  setActiveView("color");
9445
9042
  }, [setColorType, setColorTarget, setActiveView]);
9446
- const handleToggle = useCallback46((section) => {
9043
+ const handleToggle = useCallback47((section) => {
9447
9044
  setOpenSection((prev) => prev === section ? null : section);
9448
9045
  }, []);
9449
- const handleTogglePrice = useCallback46(() => handleToggle("price"), [handleToggle]);
9450
- const handleToggleDetails = useCallback46(() => handleToggle("details"), [handleToggle]);
9451
- const handleToggleAddress = useCallback46(() => handleToggle("address"), [handleToggle]);
9452
- const handleToggleStatus = useCallback46(() => handleToggle("status"), [handleToggle]);
9453
- const handleToggleOpenhouse = useCallback46(() => handleToggle("openhouse"), [handleToggle]);
9454
- const handleToggleBrokerage = useCallback46(() => handleToggle("brokerage"), [handleToggle]);
9455
- const handleToggleDescription = useCallback46(() => handleToggle("description"), [handleToggle]);
9456
- const handleToggleMLS = useCallback46(() => handleToggle("mls"), [handleToggle]);
9046
+ const handleTogglePrice = useCallback47(() => handleToggle("price"), [handleToggle]);
9047
+ const handleToggleDetails = useCallback47(() => handleToggle("details"), [handleToggle]);
9048
+ const handleToggleAddress = useCallback47(() => {
9049
+ const isOpening = openSection !== "address";
9050
+ handleToggle("address");
9051
+ if (isOpening) {
9052
+ setAddressLine1Input(currentAddress);
9053
+ setAddressLine2Input("");
9054
+ const match = currentCity.match(/^(.+),\s*(\w{2})\s*(\d{5})?$/);
9055
+ if (match) {
9056
+ setCityInput(match[1] || "");
9057
+ setStateInput(match[2] || "");
9058
+ setZipInput(match[3] || "");
9059
+ } else {
9060
+ setCityInput(currentCity);
9061
+ setStateInput("");
9062
+ setZipInput("");
9063
+ }
9064
+ }
9065
+ }, [handleToggle, openSection, currentAddress, currentCity]);
9066
+ const handleToggleStatus = useCallback47(() => handleToggle("status"), [handleToggle]);
9067
+ const handleToggleOpenhouse = useCallback47(() => {
9068
+ const isOpening = openSection !== "openhouse";
9069
+ handleToggle("openhouse");
9070
+ if (isOpening) {
9071
+ if (currentOpenHouseDate) {
9072
+ const parsed = new Date(currentOpenHouseDate);
9073
+ if (!isNaN(parsed.getTime())) setOpenhouseDate(parsed);
9074
+ }
9075
+ if (currentOpenHouseTime) {
9076
+ const [start, end] = currentOpenHouseTime.split("-");
9077
+ if (start) setOpenhouseStartTime(start);
9078
+ if (end) setOpenhouseEndTime(end);
9079
+ }
9080
+ }
9081
+ }, [handleToggle, openSection, currentOpenHouseDate, currentOpenHouseTime]);
9082
+ const handleToggleBrokerage = useCallback47(() => handleToggle("brokerage"), [handleToggle]);
9083
+ const handleToggleDescription = useCallback47(() => handleToggle("description"), [handleToggle]);
9084
+ const handleToggleMLS = useCallback47(() => handleToggle("mls"), [handleToggle]);
9457
9085
  return /* @__PURE__ */ jsxs55(Tooltip, { children: [
9458
9086
  /* @__PURE__ */ jsxs55(Popover, { open: isOpen, onOpenChange: setIsOpen, children: [
9459
9087
  /* @__PURE__ */ jsx68(PopoverTrigger, { asChild: true, children: /* @__PURE__ */ jsx68(TooltipTrigger, { asChild: true, children: /* @__PURE__ */ jsx68(
9460
9088
  Button,
9461
9089
  {
9462
- variant: "outline",
9090
+ variant: "ghost",
9463
9091
  className: "shadow-none transition-none cursor-pointer rounded-[12px]",
9464
9092
  size: "icon",
9465
- children: /* @__PURE__ */ jsx68(HouseIcon, { className: "w-4 h-4" })
9093
+ children: /* @__PURE__ */ jsx68(SquarePen, { className: "w-4 h-4" })
9466
9094
  }
9467
9095
  ) }) }),
9468
9096
  /* @__PURE__ */ jsxs55(PopoverContent, { className: "w-84 z-51 mt-1 rounded-[12px] p-2 gap-2 flex flex-col z-50001", children: [
@@ -9480,9 +9108,11 @@ var PropertyEditMenu = () => {
9480
9108
  type: "number",
9481
9109
  placeholder: "Price",
9482
9110
  className: "w-full shadow-none rounded-[12px]",
9483
- value: priceInput,
9484
- onChange: (e) => setPriceInput(e.target.value),
9485
- onBlur: handlePriceBlur
9111
+ value: priceInput.displayValue,
9112
+ onChange: (e) => priceInput.setLocalValue(e.target.value),
9113
+ onFocus: priceInput.handleFocus,
9114
+ onBlur: priceInput.handleBlur,
9115
+ onKeyDown: priceInput.handleKeyDown
9486
9116
  }
9487
9117
  ) }) })
9488
9118
  ] }),
@@ -9501,9 +9131,11 @@ var PropertyEditMenu = () => {
9501
9131
  type: "number",
9502
9132
  placeholder: "Bd",
9503
9133
  className: "w-1/3 shadow-none rounded-[12px]",
9504
- value: bedsInput,
9505
- onChange: (e) => setBedsInput(e.target.value),
9506
- onBlur: handleBedsBlur
9134
+ value: bedsInput.displayValue,
9135
+ onChange: (e) => bedsInput.setLocalValue(e.target.value),
9136
+ onFocus: bedsInput.handleFocus,
9137
+ onBlur: bedsInput.handleBlur,
9138
+ onKeyDown: bedsInput.handleKeyDown
9507
9139
  }
9508
9140
  ),
9509
9141
  /* @__PURE__ */ jsx68(
@@ -9512,9 +9144,11 @@ var PropertyEditMenu = () => {
9512
9144
  type: "number",
9513
9145
  placeholder: "Ba",
9514
9146
  className: "w-1/3 shadow-none rounded-[12px]",
9515
- value: bathsInput,
9516
- onChange: (e) => setBathsInput(e.target.value),
9517
- onBlur: handleBathsBlur
9147
+ value: bathsInput.displayValue,
9148
+ onChange: (e) => bathsInput.setLocalValue(e.target.value),
9149
+ onFocus: bathsInput.handleFocus,
9150
+ onBlur: bathsInput.handleBlur,
9151
+ onKeyDown: bathsInput.handleKeyDown
9518
9152
  }
9519
9153
  ),
9520
9154
  /* @__PURE__ */ jsx68(
@@ -9523,9 +9157,11 @@ var PropertyEditMenu = () => {
9523
9157
  type: "number",
9524
9158
  placeholder: "Sqft",
9525
9159
  className: "w-2/4 shadow-none rounded-[12px]",
9526
- value: sqftInput,
9527
- onChange: (e) => setSqftInput(e.target.value),
9528
- onBlur: handleSqftBlur
9160
+ value: sqftInput.displayValue,
9161
+ onChange: (e) => sqftInput.setLocalValue(e.target.value),
9162
+ onFocus: sqftInput.handleFocus,
9163
+ onBlur: sqftInput.handleBlur,
9164
+ onKeyDown: sqftInput.handleKeyDown
9529
9165
  }
9530
9166
  )
9531
9167
  ] }) })
@@ -9586,7 +9222,7 @@ var PropertyEditMenu = () => {
9586
9222
  )
9587
9223
  ] }),
9588
9224
  /* @__PURE__ */ jsxs55("div", { className: "flex flex-row items-start justify-start gap-2", children: [
9589
- /* @__PURE__ */ jsxs55(Select, { value: countryInput, onValueChange: handleCountryChange, children: [
9225
+ /* @__PURE__ */ jsxs55(Select, { value: currentCountry, onValueChange: handleCountryChange, children: [
9590
9226
  /* @__PURE__ */ jsx68(SelectTrigger, { className: "w-3/4 shadow-none rounded-[12px]", children: /* @__PURE__ */ jsx68(SelectValue, { placeholder: "Country" }) }),
9591
9227
  /* @__PURE__ */ jsx68(SelectContent, { className: "w-full shadow-none rounded-[12px] z-50001", children: /* @__PURE__ */ jsx68(SelectItem, { value: "USA", children: "United States" }) })
9592
9228
  ] }),
@@ -9616,11 +9252,11 @@ var PropertyEditMenu = () => {
9616
9252
  Checkbox,
9617
9253
  {
9618
9254
  className: " shadow-none rounded-[12px] w-9 h-9",
9619
- checked: isStatusEnabled,
9255
+ checked: !!currentIsStatus,
9620
9256
  onCheckedChange: (checked) => handleIsStatusChange(checked === "indeterminate" ? false : checked)
9621
9257
  }
9622
9258
  ) }),
9623
- /* @__PURE__ */ jsx68(TooltipContent, { side: "bottom", className: "z-50001", children: isStatusEnabled ? "Hide Status" : "Show Status" })
9259
+ /* @__PURE__ */ jsx68(TooltipContent, { side: "bottom", className: "z-50001", children: !!currentIsStatus ? "Hide Status" : "Show Status" })
9624
9260
  ] }),
9625
9261
  /* @__PURE__ */ jsx68(
9626
9262
  BackgroundColorBtn,
@@ -9634,13 +9270,15 @@ var PropertyEditMenu = () => {
9634
9270
  /* @__PURE__ */ jsx68(
9635
9271
  Input,
9636
9272
  {
9637
- disabled: !isStatusEnabled,
9273
+ disabled: !currentIsStatus,
9638
9274
  type: "text",
9639
9275
  placeholder: "Just Listed",
9640
9276
  className: "w-full shadow-none rounded-[12px]",
9641
- value: statusInput,
9642
- onChange: (e) => setStatusInput(e.target.value),
9643
- onBlur: handleStatusBlur
9277
+ value: statusInput.displayValue,
9278
+ onChange: (e) => statusInput.setLocalValue(e.target.value),
9279
+ onFocus: statusInput.handleFocus,
9280
+ onBlur: statusInput.handleBlur,
9281
+ onKeyDown: statusInput.handleKeyDown
9644
9282
  }
9645
9283
  )
9646
9284
  ] }),
@@ -9651,7 +9289,7 @@ var PropertyEditMenu = () => {
9651
9289
  "aria-label": "Toggle new label",
9652
9290
  size: "sm",
9653
9291
  variant: "outline",
9654
- pressed: isNewEnabled,
9292
+ pressed: !!currentIsNew,
9655
9293
  onPressedChange: handleIsNewChange,
9656
9294
  children: [
9657
9295
  /* @__PURE__ */ jsx68(CircleCheckIcon, { className: "group-aria-pressed/toggle:fill-foreground" }),
@@ -9673,16 +9311,16 @@ var PropertyEditMenu = () => {
9673
9311
  Checkbox,
9674
9312
  {
9675
9313
  className: "shadow-none rounded-[12px] w-9 h-9",
9676
- checked: openhouseEnabled,
9314
+ checked: !!currentIsOpenHouse,
9677
9315
  onCheckedChange: (checked) => handleIsOpenHouseChange(checked === "indeterminate" ? false : checked)
9678
9316
  }
9679
9317
  ) }),
9680
- /* @__PURE__ */ jsx68(TooltipContent, { side: "bottom", className: "z-50001", children: openhouseEnabled ? "Disable Open House" : "Enable Open House" })
9318
+ /* @__PURE__ */ jsx68(TooltipContent, { side: "bottom", className: "z-50001", children: !!currentIsOpenHouse ? "Disable Open House" : "Enable Open House" })
9681
9319
  ] }),
9682
9320
  /* @__PURE__ */ jsx68(
9683
9321
  Input,
9684
9322
  {
9685
- disabled: !openhouseEnabled,
9323
+ disabled: !currentIsOpenHouse,
9686
9324
  type: "date",
9687
9325
  value: openhouseDate ? openhouseDate.toISOString().split("T")[0] : "",
9688
9326
  onChange: (e) => setOpenhouseDate(e.target.value ? new Date(e.target.value) : void 0),
@@ -9695,7 +9333,7 @@ var PropertyEditMenu = () => {
9695
9333
  /* @__PURE__ */ jsx68(
9696
9334
  Input,
9697
9335
  {
9698
- disabled: !openhouseEnabled,
9336
+ disabled: !currentIsOpenHouse,
9699
9337
  type: "time",
9700
9338
  value: openhouseStartTime,
9701
9339
  onChange: (e) => setOpenhouseStartTime(e.target.value),
@@ -9706,7 +9344,7 @@ var PropertyEditMenu = () => {
9706
9344
  /* @__PURE__ */ jsx68(
9707
9345
  Input,
9708
9346
  {
9709
- disabled: !openhouseEnabled,
9347
+ disabled: !currentIsOpenHouse,
9710
9348
  type: "time",
9711
9349
  value: openhouseEndTime,
9712
9350
  onChange: (e) => setOpenhouseEndTime(e.target.value),
@@ -9729,22 +9367,24 @@ var PropertyEditMenu = () => {
9729
9367
  Checkbox,
9730
9368
  {
9731
9369
  className: "shadow-none rounded-[12px] w-9 h-9",
9732
- checked: isBrokerageEnabled,
9370
+ checked: !!currentIsBrokerage,
9733
9371
  onCheckedChange: (checked) => handleIsBrokerageChange(checked === "indeterminate" ? false : checked)
9734
9372
  }
9735
9373
  ) }),
9736
- /* @__PURE__ */ jsx68(TooltipContent, { side: "bottom", className: "z-50001", children: isBrokerageEnabled ? "Hide Brokerage" : "Show Brokerage" })
9374
+ /* @__PURE__ */ jsx68(TooltipContent, { side: "bottom", className: "z-50001", children: !!currentIsBrokerage ? "Hide Brokerage" : "Show Brokerage" })
9737
9375
  ] }),
9738
9376
  /* @__PURE__ */ jsx68(
9739
9377
  Input,
9740
9378
  {
9741
- disabled: !isBrokerageEnabled,
9379
+ disabled: !currentIsBrokerage,
9742
9380
  type: "text",
9743
9381
  placeholder: "New Era Real Estate",
9744
9382
  className: "w-full shadow-none rounded-[12px]",
9745
- value: brokerageInput,
9746
- onChange: (e) => setBrokerageInput(e.target.value),
9747
- onBlur: handleBrokerageBlur
9383
+ value: brokerageInput.displayValue,
9384
+ onChange: (e) => brokerageInput.setLocalValue(e.target.value),
9385
+ onFocus: brokerageInput.handleFocus,
9386
+ onBlur: brokerageInput.handleBlur,
9387
+ onKeyDown: brokerageInput.handleKeyDown
9748
9388
  }
9749
9389
  )
9750
9390
  ] }),
@@ -9762,33 +9402,34 @@ var PropertyEditMenu = () => {
9762
9402
  Checkbox,
9763
9403
  {
9764
9404
  className: "shadow-none rounded-[12px] w-9 h-9",
9765
- checked: isDescriptionEnabled,
9405
+ checked: !!currentIsDescription,
9766
9406
  onCheckedChange: (checked) => handleIsDescriptionChange(checked === "indeterminate" ? false : checked)
9767
9407
  }
9768
9408
  ) }),
9769
- /* @__PURE__ */ jsx68(TooltipContent, { side: "bottom", className: "z-50001", children: isDescriptionEnabled ? "Hide Description" : "Show Description" })
9409
+ /* @__PURE__ */ jsx68(TooltipContent, { side: "bottom", className: "z-50001", children: !!currentIsDescription ? "Hide Description" : "Show Description" })
9770
9410
  ] }),
9771
9411
  /* @__PURE__ */ jsx68(
9772
9412
  Textarea,
9773
9413
  {
9774
- disabled: !isDescriptionEnabled,
9414
+ disabled: !currentIsDescription,
9775
9415
  placeholder: "Beautiful home in the heart of the New Jersey Shore",
9776
9416
  className: "w-full shadow-none rounded-[12px] min-h-fit max-h-34",
9777
- value: descriptionInput,
9778
- onChange: (e) => setDescriptionInput(e.target.value),
9779
- onBlur: handleDescriptionBlur
9417
+ value: descriptionInput.displayValue,
9418
+ onChange: (e) => descriptionInput.setLocalValue(e.target.value),
9419
+ onFocus: descriptionInput.handleFocus,
9420
+ onBlur: descriptionInput.handleBlur
9780
9421
  }
9781
9422
  )
9782
9423
  ] }) })
9783
9424
  ] })
9784
9425
  ] })
9785
9426
  ] }),
9786
- /* @__PURE__ */ jsx68(TooltipContent, { side: "bottom", className: "z-50001", children: "Edit" })
9427
+ /* @__PURE__ */ jsx68(TooltipContent, { side: "bottom", className: "z-50001", children: "Information" })
9787
9428
  ] });
9788
9429
  };
9789
9430
 
9790
9431
  // src/core/editor/components/element-gear/property/toolbar.tsx
9791
- import { CaseUpperIcon as CaseUpperIcon6 } from "lucide-react";
9432
+ import { CaseUpperIcon as CaseUpperIcon5 } from "lucide-react";
9792
9433
  import { jsx as jsx69, jsxs as jsxs56 } from "react/jsx-runtime";
9793
9434
  function PropertyToolbar() {
9794
9435
  const { focusIdx, template, updateElement } = useEditorStore();
@@ -9822,22 +9463,22 @@ function PropertyToolbar() {
9822
9463
  const currentTextColor = useMemo34(() => {
9823
9464
  return propertyElement?.attributes?.["text-color"] || "#111116";
9824
9465
  }, [propertyElement]);
9825
- const handleOpenBgColorPicker = useCallback47(() => {
9466
+ const handleOpenBgColorPicker = useCallback48(() => {
9826
9467
  setColorType("Background Color");
9827
9468
  setColorTarget("propertyBgColor");
9828
9469
  setActiveView("color");
9829
9470
  }, [setColorType, setColorTarget, setActiveView]);
9830
- const handleOpenStrokeColorPicker = useCallback47(() => {
9471
+ const handleOpenStrokeColorPicker = useCallback48(() => {
9831
9472
  setColorType("Stroke Color");
9832
9473
  setColorTarget("propertyStrokeColor");
9833
9474
  setActiveView("color");
9834
9475
  }, [setColorType, setColorTarget, setActiveView]);
9835
- const handleOpenTextColorPicker = useCallback47(() => {
9476
+ const handleOpenTextColorPicker = useCallback48(() => {
9836
9477
  setColorType("Text Color");
9837
9478
  setColorTarget("propertyTextColor");
9838
9479
  setActiveView("color");
9839
9480
  }, [setColorType, setColorTarget, setActiveView]);
9840
- const handleFontChange = useCallback47((font) => {
9481
+ const handleFontChange = useCallback48((font) => {
9841
9482
  if (!focusIdx || !propertyElement) return;
9842
9483
  updateElement(focusIdx, {
9843
9484
  attributes: {
@@ -9846,7 +9487,7 @@ function PropertyToolbar() {
9846
9487
  }
9847
9488
  });
9848
9489
  }, [focusIdx, propertyElement, updateElement]);
9849
- const handleBorderWidthChange = useCallback47((width) => {
9490
+ const handleBorderWidthChange = useCallback48((width) => {
9850
9491
  if (!columnIdx || !columnElement || !focusIdx || !propertyElement) return;
9851
9492
  const newBorder = { ...border, width };
9852
9493
  const formattedBorder = formatBorder(newBorder);
@@ -9863,7 +9504,7 @@ function PropertyToolbar() {
9863
9504
  }
9864
9505
  });
9865
9506
  }, [columnIdx, columnElement, focusIdx, propertyElement, border, updateElement]);
9866
- const handleBorderEnabledChange = useCallback47((enabled) => {
9507
+ const handleBorderEnabledChange = useCallback48((enabled) => {
9867
9508
  if (!columnIdx || !columnElement || !focusIdx || !propertyElement) return;
9868
9509
  const newWidth = enabled ? border.width === 0 ? 1 : border.width : 0;
9869
9510
  const newBorder = { ...border, width: newWidth };
@@ -9881,7 +9522,7 @@ function PropertyToolbar() {
9881
9522
  }
9882
9523
  });
9883
9524
  }, [columnIdx, columnElement, focusIdx, propertyElement, border, updateElement]);
9884
- const handleBorderRadiusChange = useCallback47((value) => {
9525
+ const handleBorderRadiusChange = useCallback48((value) => {
9885
9526
  if (!columnIdx || !columnElement || !focusIdx || !propertyElement) return;
9886
9527
  const formattedRadius = formatBorderRadius(value);
9887
9528
  updateElement(columnIdx, {
@@ -9911,6 +9552,7 @@ function PropertyToolbar() {
9911
9552
  }
9912
9553
  ),
9913
9554
  /* @__PURE__ */ jsx69(ImageMenu, { type: "property" }),
9555
+ /* @__PURE__ */ jsx69(PropertyEditMenu, {}),
9914
9556
  /* @__PURE__ */ jsx69(ToolbarSeparator, {}),
9915
9557
  /* @__PURE__ */ jsx69(ToolbarContent, { children: /* @__PURE__ */ jsx69(
9916
9558
  FontFamilyDropdown,
@@ -9929,7 +9571,7 @@ function PropertyToolbar() {
9929
9571
  size: "icon",
9930
9572
  onClick: handleOpenTextColorPicker,
9931
9573
  children: [
9932
- /* @__PURE__ */ jsx69(CaseUpperIcon6, {}),
9574
+ /* @__PURE__ */ jsx69(CaseUpperIcon5, {}),
9933
9575
  /* @__PURE__ */ jsx69(
9934
9576
  "span",
9935
9577
  {
@@ -9981,24 +9623,22 @@ function PropertyToolbar() {
9981
9623
  tooltipText: "Corner Rounding",
9982
9624
  max: 18
9983
9625
  }
9984
- ),
9985
- /* @__PURE__ */ jsx69(ToolbarSeparator, {}),
9986
- /* @__PURE__ */ jsx69(PropertyEditMenu, {})
9626
+ )
9987
9627
  ] })
9988
9628
  ] });
9989
9629
  }
9990
9630
 
9991
9631
  // src/core/editor/components/element-gear/property/triple/toolbar.tsx
9992
- import { useCallback as useCallback49, useMemo as useMemo36 } from "react";
9632
+ import { useCallback as useCallback50, useMemo as useMemo36 } from "react";
9993
9633
 
9994
9634
  // src/core/editor/components/property-triple-edit-menu.tsx
9995
- import { ChevronDownIcon as ChevronDownIcon5, HouseIcon as HouseIcon2 } from "lucide-react";
9996
- import { useState as useState23, useCallback as useCallback48, useMemo as useMemo35, useEffect as useEffect15 } from "react";
9635
+ import { ChevronDownIcon as ChevronDownIcon5, SquarePen as SquarePen2 } from "lucide-react";
9636
+ import { useState as useState24, useCallback as useCallback49, useMemo as useMemo35 } from "react";
9997
9637
  import { jsx as jsx70, jsxs as jsxs57 } from "react/jsx-runtime";
9998
9638
  var PropertyTripleEditMenu = () => {
9999
9639
  const { focusIdx, template, updateElement } = useEditorStore();
10000
- const [isOpen, setIsOpen] = useState23(false);
10001
- const [openSection, setOpenSection] = useState23(null);
9640
+ const [isOpen, setIsOpen] = useState24(false);
9641
+ const [openSection, setOpenSection] = useState24(null);
10002
9642
  const propertyElement = useMemo35(() => {
10003
9643
  if (!focusIdx || !template) return null;
10004
9644
  return getValueByIdx(template, focusIdx);
@@ -10007,95 +9647,41 @@ var PropertyTripleEditMenu = () => {
10007
9647
  const rawPrice = propertyElement?.attributes?.["price"] || "";
10008
9648
  return parsePrice(rawPrice);
10009
9649
  }, [propertyElement]);
10010
- const [priceInput, setPriceInput] = useState23(currentPrice);
10011
- useEffect15(() => {
10012
- setPriceInput(currentPrice);
10013
- }, [currentPrice]);
10014
- const handlePriceBlur = useCallback48(() => {
10015
- if (!focusIdx || !propertyElement) return;
10016
- if (priceInput === currentPrice) return;
10017
- updateElement(focusIdx, {
10018
- attributes: {
10019
- ...propertyElement.attributes,
10020
- "price": priceInput
10021
- }
10022
- });
10023
- }, [focusIdx, propertyElement, priceInput, currentPrice, updateElement]);
10024
9650
  const currentBeds = useMemo35(() => propertyElement?.attributes?.["beds"] || "", [propertyElement]);
10025
9651
  const currentBaths = useMemo35(() => propertyElement?.attributes?.["baths"] || "", [propertyElement]);
10026
9652
  const currentSqft = useMemo35(() => propertyElement?.attributes?.["sqft"] || "", [propertyElement]);
10027
9653
  const currentCity = useMemo35(() => propertyElement?.attributes?.["city"] || "", [propertyElement]);
10028
- const [bedsInput, setBedsInput] = useState23(currentBeds);
10029
- const [bathsInput, setBathsInput] = useState23(currentBaths);
10030
- const [sqftInput, setSqftInput] = useState23(currentSqft);
10031
- const [cityInput, setCityInput] = useState23(currentCity);
10032
- useEffect15(() => {
10033
- setBedsInput(currentBeds);
10034
- }, [currentBeds]);
10035
- useEffect15(() => {
10036
- setBathsInput(currentBaths);
10037
- }, [currentBaths]);
10038
- useEffect15(() => {
10039
- setSqftInput(currentSqft);
10040
- }, [currentSqft]);
10041
- useEffect15(() => {
10042
- setCityInput(currentCity);
10043
- }, [currentCity]);
10044
- const handleBedsBlur = useCallback48(() => {
9654
+ const commitAttribute = useCallback49((key, value) => {
10045
9655
  if (!focusIdx || !propertyElement) return;
10046
- if (bedsInput === currentBeds) return;
10047
9656
  updateElement(focusIdx, {
10048
- attributes: {
10049
- ...propertyElement.attributes,
10050
- "beds": bedsInput
10051
- }
10052
- });
10053
- }, [focusIdx, propertyElement, bedsInput, currentBeds, updateElement]);
10054
- const handleBathsBlur = useCallback48(() => {
10055
- if (!focusIdx || !propertyElement) return;
10056
- if (bathsInput === currentBaths) return;
10057
- updateElement(focusIdx, {
10058
- attributes: {
10059
- ...propertyElement.attributes,
10060
- "baths": bathsInput
10061
- }
9657
+ attributes: { ...propertyElement.attributes, [key]: value }
10062
9658
  });
10063
- }, [focusIdx, propertyElement, bathsInput, currentBaths, updateElement]);
10064
- const handleSqftBlur = useCallback48(() => {
10065
- if (!focusIdx || !propertyElement) return;
10066
- if (sqftInput === currentSqft) return;
10067
- updateElement(focusIdx, {
10068
- attributes: {
10069
- ...propertyElement.attributes,
10070
- "sqft": sqftInput
10071
- }
10072
- });
10073
- }, [focusIdx, propertyElement, sqftInput, currentSqft, updateElement]);
10074
- const handleCityBlur = useCallback48(() => {
10075
- if (!focusIdx || !propertyElement) return;
10076
- if (cityInput === currentCity) return;
10077
- updateElement(focusIdx, {
10078
- attributes: {
10079
- ...propertyElement.attributes,
10080
- "city": cityInput
10081
- }
10082
- });
10083
- }, [focusIdx, propertyElement, cityInput, currentCity, updateElement]);
10084
- const handleToggle = useCallback48((section) => {
9659
+ }, [focusIdx, propertyElement, updateElement]);
9660
+ const commitPrice = useCallback49((v) => commitAttribute("price", v), [commitAttribute]);
9661
+ const commitBeds = useCallback49((v) => commitAttribute("beds", v), [commitAttribute]);
9662
+ const commitBaths = useCallback49((v) => commitAttribute("baths", v), [commitAttribute]);
9663
+ const commitSqft = useCallback49((v) => commitAttribute("sqft", v), [commitAttribute]);
9664
+ const commitCity = useCallback49((v) => commitAttribute("city", v), [commitAttribute]);
9665
+ const priceInput = useEditableValue({ externalValue: currentPrice, onChange: commitPrice });
9666
+ const bedsInput = useEditableValue({ externalValue: currentBeds, onChange: commitBeds });
9667
+ const bathsInput = useEditableValue({ externalValue: currentBaths, onChange: commitBaths });
9668
+ const sqftInput = useEditableValue({ externalValue: currentSqft, onChange: commitSqft });
9669
+ const cityInput = useEditableValue({ externalValue: currentCity, onChange: commitCity });
9670
+ const handleToggle = useCallback49((section) => {
10085
9671
  setOpenSection((prev) => prev === section ? null : section);
10086
9672
  }, []);
10087
- const handleTogglePrice = useCallback48(() => handleToggle("price"), [handleToggle]);
10088
- const handleToggleDetails = useCallback48(() => handleToggle("details"), [handleToggle]);
10089
- const handleToggleAddress = useCallback48(() => handleToggle("address"), [handleToggle]);
9673
+ const handleTogglePrice = useCallback49(() => handleToggle("price"), [handleToggle]);
9674
+ const handleToggleDetails = useCallback49(() => handleToggle("details"), [handleToggle]);
9675
+ const handleToggleAddress = useCallback49(() => handleToggle("address"), [handleToggle]);
10090
9676
  return /* @__PURE__ */ jsxs57(Tooltip, { children: [
10091
9677
  /* @__PURE__ */ jsxs57(Popover, { open: isOpen, onOpenChange: setIsOpen, children: [
10092
9678
  /* @__PURE__ */ jsx70(PopoverTrigger, { asChild: true, children: /* @__PURE__ */ jsx70(TooltipTrigger, { asChild: true, children: /* @__PURE__ */ jsx70(
10093
9679
  Button,
10094
9680
  {
10095
- variant: "outline",
9681
+ variant: "ghost",
10096
9682
  className: "shadow-none transition-none cursor-pointer rounded-[12px]",
10097
9683
  size: "icon",
10098
- children: /* @__PURE__ */ jsx70(HouseIcon2, { className: "w-4 h-4" })
9684
+ children: /* @__PURE__ */ jsx70(SquarePen2, { className: "w-4 h-4" })
10099
9685
  }
10100
9686
  ) }) }),
10101
9687
  /* @__PURE__ */ jsxs57(PopoverContent, { className: "w-84 z-51 mt-1 rounded-[12px] p-2 gap-2 flex flex-col z-50001", children: [
@@ -10113,9 +9699,11 @@ var PropertyTripleEditMenu = () => {
10113
9699
  type: "number",
10114
9700
  placeholder: "Price",
10115
9701
  className: "w-full shadow-none rounded-[12px]",
10116
- value: priceInput,
10117
- onChange: (e) => setPriceInput(e.target.value),
10118
- onBlur: handlePriceBlur
9702
+ value: priceInput.displayValue,
9703
+ onChange: (e) => priceInput.setLocalValue(e.target.value),
9704
+ onFocus: priceInput.handleFocus,
9705
+ onBlur: priceInput.handleBlur,
9706
+ onKeyDown: priceInput.handleKeyDown
10119
9707
  }
10120
9708
  ) }) })
10121
9709
  ] }),
@@ -10134,9 +9722,11 @@ var PropertyTripleEditMenu = () => {
10134
9722
  type: "number",
10135
9723
  placeholder: "Bd",
10136
9724
  className: "w-1/3 shadow-none rounded-[12px]",
10137
- value: bedsInput,
10138
- onChange: (e) => setBedsInput(e.target.value),
10139
- onBlur: handleBedsBlur
9725
+ value: bedsInput.displayValue,
9726
+ onChange: (e) => bedsInput.setLocalValue(e.target.value),
9727
+ onFocus: bedsInput.handleFocus,
9728
+ onBlur: bedsInput.handleBlur,
9729
+ onKeyDown: bedsInput.handleKeyDown
10140
9730
  }
10141
9731
  ),
10142
9732
  /* @__PURE__ */ jsx70(
@@ -10145,9 +9735,11 @@ var PropertyTripleEditMenu = () => {
10145
9735
  type: "number",
10146
9736
  placeholder: "Ba",
10147
9737
  className: "w-1/3 shadow-none rounded-[12px]",
10148
- value: bathsInput,
10149
- onChange: (e) => setBathsInput(e.target.value),
10150
- onBlur: handleBathsBlur
9738
+ value: bathsInput.displayValue,
9739
+ onChange: (e) => bathsInput.setLocalValue(e.target.value),
9740
+ onFocus: bathsInput.handleFocus,
9741
+ onBlur: bathsInput.handleBlur,
9742
+ onKeyDown: bathsInput.handleKeyDown
10151
9743
  }
10152
9744
  ),
10153
9745
  /* @__PURE__ */ jsx70(
@@ -10156,9 +9748,11 @@ var PropertyTripleEditMenu = () => {
10156
9748
  type: "number",
10157
9749
  placeholder: "Sqft",
10158
9750
  className: "w-2/4 shadow-none rounded-[12px]",
10159
- value: sqftInput,
10160
- onChange: (e) => setSqftInput(e.target.value),
10161
- onBlur: handleSqftBlur
9751
+ value: sqftInput.displayValue,
9752
+ onChange: (e) => sqftInput.setLocalValue(e.target.value),
9753
+ onFocus: sqftInput.handleFocus,
9754
+ onBlur: sqftInput.handleBlur,
9755
+ onKeyDown: sqftInput.handleKeyDown
10162
9756
  }
10163
9757
  )
10164
9758
  ] }) })
@@ -10177,20 +9771,22 @@ var PropertyTripleEditMenu = () => {
10177
9771
  type: "text",
10178
9772
  placeholder: "Egg Harbor City",
10179
9773
  className: "w-full shadow-none rounded-[12px]",
10180
- value: cityInput,
10181
- onChange: (e) => setCityInput(e.target.value),
10182
- onBlur: handleCityBlur
9774
+ value: cityInput.displayValue,
9775
+ onChange: (e) => cityInput.setLocalValue(e.target.value),
9776
+ onFocus: cityInput.handleFocus,
9777
+ onBlur: cityInput.handleBlur,
9778
+ onKeyDown: cityInput.handleKeyDown
10183
9779
  }
10184
9780
  ) }) })
10185
9781
  ] })
10186
9782
  ] })
10187
9783
  ] }),
10188
- /* @__PURE__ */ jsx70(TooltipContent, { side: "bottom", className: "z-50001", children: "Edit" })
9784
+ /* @__PURE__ */ jsx70(TooltipContent, { side: "bottom", className: "z-50001", children: "Information" })
10189
9785
  ] });
10190
9786
  };
10191
9787
 
10192
9788
  // src/core/editor/components/element-gear/property/triple/toolbar.tsx
10193
- import { CaseUpperIcon as CaseUpperIcon7 } from "lucide-react";
9789
+ import { CaseUpperIcon as CaseUpperIcon6 } from "lucide-react";
10194
9790
  import { jsx as jsx71, jsxs as jsxs58 } from "react/jsx-runtime";
10195
9791
  var PropertyTripleItemToolbar = () => {
10196
9792
  const focusIdx = useEditorStore((state) => state.focusIdx);
@@ -10222,22 +9818,22 @@ var PropertyTripleItemToolbar = () => {
10222
9818
  const currentFontFamily = useMemo36(() => {
10223
9819
  return parentElement?.attributes?.["font-family"] || "Arial, sans-serif";
10224
9820
  }, [parentElement]);
10225
- const handleOpenBgColorPicker = useCallback49(() => {
9821
+ const handleOpenBgColorPicker = useCallback50(() => {
10226
9822
  setColorType("Background Color");
10227
9823
  setColorTarget("propertyBgColor");
10228
9824
  setActiveView("color");
10229
9825
  }, [setColorType, setColorTarget, setActiveView]);
10230
- const handleOpenStrokeColorPicker = useCallback49(() => {
9826
+ const handleOpenStrokeColorPicker = useCallback50(() => {
10231
9827
  setColorType("Stroke Color");
10232
9828
  setColorTarget("propertyStrokeColor");
10233
9829
  setActiveView("color");
10234
9830
  }, [setColorType, setColorTarget, setActiveView]);
10235
- const handleOpenTextColorPicker = useCallback49(() => {
9831
+ const handleOpenTextColorPicker = useCallback50(() => {
10236
9832
  setColorType("Text Color");
10237
9833
  setColorTarget("propertyTextColor");
10238
9834
  setActiveView("color");
10239
9835
  }, [setColorType, setColorTarget, setActiveView]);
10240
- const handleFontChange = useCallback49((font) => {
9836
+ const handleFontChange = useCallback50((font) => {
10241
9837
  if (!parentIdx || !parentElement) return;
10242
9838
  updateElement(parentIdx, {
10243
9839
  attributes: {
@@ -10246,7 +9842,7 @@ var PropertyTripleItemToolbar = () => {
10246
9842
  }
10247
9843
  });
10248
9844
  }, [parentIdx, parentElement, updateElement]);
10249
- const handleBorderWidthChange = useCallback49((width) => {
9845
+ const handleBorderWidthChange = useCallback50((width) => {
10250
9846
  if (!parentIdx || !parentElement) return;
10251
9847
  const newBorder = { ...border, width };
10252
9848
  const formattedBorder = formatBorder(newBorder);
@@ -10257,7 +9853,7 @@ var PropertyTripleItemToolbar = () => {
10257
9853
  }
10258
9854
  });
10259
9855
  }, [parentIdx, parentElement, border, updateElement]);
10260
- const handleBorderEnabledChange = useCallback49((enabled) => {
9856
+ const handleBorderEnabledChange = useCallback50((enabled) => {
10261
9857
  if (!parentIdx || !parentElement) return;
10262
9858
  const newWidth = enabled ? border.width === 0 ? 1 : border.width : 0;
10263
9859
  const newBorder = { ...border, width: newWidth };
@@ -10269,7 +9865,7 @@ var PropertyTripleItemToolbar = () => {
10269
9865
  }
10270
9866
  });
10271
9867
  }, [parentIdx, parentElement, border, updateElement]);
10272
- const handleBorderRadiusChange = useCallback49((value) => {
9868
+ const handleBorderRadiusChange = useCallback50((value) => {
10273
9869
  if (!parentIdx || !parentElement) return;
10274
9870
  const formattedRadius = formatBorderRadius(value);
10275
9871
  updateElement(parentIdx, {
@@ -10293,6 +9889,7 @@ var PropertyTripleItemToolbar = () => {
10293
9889
  }
10294
9890
  ),
10295
9891
  /* @__PURE__ */ jsx71(ImageMenu, { type: "property" }),
9892
+ /* @__PURE__ */ jsx71(PropertyTripleEditMenu, {}),
10296
9893
  /* @__PURE__ */ jsx71(ToolbarSeparator, {}),
10297
9894
  /* @__PURE__ */ jsx71(
10298
9895
  FontFamilyDropdown,
@@ -10311,7 +9908,7 @@ var PropertyTripleItemToolbar = () => {
10311
9908
  size: "icon",
10312
9909
  onClick: handleOpenTextColorPicker,
10313
9910
  children: [
10314
- /* @__PURE__ */ jsx71(CaseUpperIcon7, {}),
9911
+ /* @__PURE__ */ jsx71(CaseUpperIcon6, {}),
10315
9912
  /* @__PURE__ */ jsx71(
10316
9913
  "span",
10317
9914
  {
@@ -10363,9 +9960,7 @@ var PropertyTripleItemToolbar = () => {
10363
9960
  tooltipText: "Corner Rounding",
10364
9961
  max: 18
10365
9962
  }
10366
- ),
10367
- /* @__PURE__ */ jsx71(ToolbarSeparator, {}),
10368
- /* @__PURE__ */ jsx71(PropertyTripleEditMenu, {})
9963
+ )
10369
9964
  ] })
10370
9965
  ] });
10371
9966
  };
@@ -10444,14 +10039,14 @@ function Skeleton({ className, ...props }) {
10444
10039
  }
10445
10040
 
10446
10041
  // src/core/editor/components/email-template-v2/template-page.tsx
10447
- import { Suspense, useState as useState24, lazy } from "react";
10042
+ import { Suspense, useState as useState25, lazy } from "react";
10448
10043
 
10449
10044
  // src/core/editor/hooks/use-auto-save.ts
10450
- import { useEffect as useEffect16, useRef as useRef7 } from "react";
10045
+ import { useEffect as useEffect7, useRef as useRef7 } from "react";
10451
10046
  var AUTO_SAVE_INTERVAL = 30 * 1e3;
10452
10047
  function useAutoSave() {
10453
10048
  const intervalRef = useRef7(null);
10454
- useEffect16(() => {
10049
+ useEffect7(() => {
10455
10050
  intervalRef.current = setInterval(async () => {
10456
10051
  const { template, templateId, onSave, hasUnsavedChanges, markAsSaved, isSaving, setIsSaving } = useEditorStore.getState();
10457
10052
  if (isSaving || !templateId || !onSave || !hasUnsavedChanges()) {
@@ -10479,7 +10074,7 @@ function useAutoSave() {
10479
10074
  // src/core/editor/components/email-template-v2/template-page.tsx
10480
10075
  import "react-json-view-lite/dist/index.css";
10481
10076
  import { jsx as jsx74, jsxs as jsxs59 } from "react/jsx-runtime";
10482
- var Editor2 = lazy(() => import("./core-AMEHYBIM.mjs").then((module) => ({
10077
+ var Editor2 = lazy(() => import("./core-JDSYY73O.mjs").then((module) => ({
10483
10078
  default: module.Editor
10484
10079
  })));
10485
10080
  function TemplatePage({
@@ -10491,12 +10086,12 @@ function TemplatePage({
10491
10086
  onImageUpload,
10492
10087
  data
10493
10088
  }) {
10494
- useState24(() => {
10089
+ useState25(() => {
10495
10090
  useEditorStore.getState().initializeWithTemplate(templateId, initialTemplate, onSave, onToast, data, onExit, onImageUpload);
10496
10091
  });
10497
10092
  useAutoSave();
10498
- const [editorLoading, setEditorLoading] = useState24(false);
10499
- const [isPageHovered, setIsPageHovered] = useState24(false);
10093
+ const [editorLoading, setEditorLoading] = useState25(false);
10094
+ const [isPageHovered, setIsPageHovered] = useState25(false);
10500
10095
  const previewMode = useEditorStore((state) => state.previewMode);
10501
10096
  const focusIdx = useEditorStore((state) => state.focusIdx);
10502
10097
  const setFocusIdx = useEditorStore((state) => state.setFocusIdx);