@thanh01.pmt/presentation-kit 0.2.3 → 0.2.5

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.
@@ -586,11 +586,13 @@ function SlideDesignOverlay({
586
586
  onLayoutChange,
587
587
  onSave,
588
588
  onClose,
589
- isActive
589
+ isActive,
590
+ theme = "dark"
590
591
  }) {
591
592
  if (!isActive) return null;
592
593
  const [boxes, setBoxes] = react.useState(layout?.boxes ?? []);
593
594
  const [selectedId, setSelectedId] = react.useState(null);
595
+ const [editingId, setEditingId] = react.useState(null);
594
596
  const containerRef = react.useRef(null);
595
597
  react.useEffect(() => {
596
598
  setBoxes(layout?.boxes ?? []);
@@ -623,40 +625,37 @@ function SlideDesignOverlay({
623
625
  let [newX, newY, newW, newH] = [origX, origY, origW, origH];
624
626
  switch (dragging.type) {
625
627
  case "move":
626
- newX = Math.max(0, Math.min(1280 - origW, origX + dx));
627
- newY = Math.max(0, Math.min(720 - origH, origY + dy));
628
+ newX = Math.round(Math.max(0, Math.min(1280 - origW, origX + dx)));
629
+ newY = Math.round(Math.max(0, Math.min(720 - origH, origY + dy)));
628
630
  break;
629
631
  case "se":
630
- newW = Math.max(50, origW + dx);
631
- newH = Math.max(30, origH + dy);
632
+ newW = Math.round(Math.max(100, Math.min(1280 - origX, origW + dx)));
633
+ newH = Math.round(Math.max(40, Math.min(720 - origY, origH + dy)));
632
634
  break;
633
635
  case "e":
634
- newW = Math.max(50, origW + dx);
636
+ newW = Math.round(Math.max(100, Math.min(1280 - origX, origW + dx)));
635
637
  break;
636
638
  case "s":
637
- newH = Math.max(30, origH + dy);
639
+ newH = Math.round(Math.max(40, Math.min(720 - origY, origH + dy)));
638
640
  break;
639
641
  case "sw":
640
- newX = Math.min(origX + origW - 50, origX + dx);
641
- newW = Math.max(50, origW - dx);
642
- newH = Math.max(30, origH + dy);
642
+ newW = Math.round(Math.max(100, origW - dx));
643
+ newX = Math.round(Math.min(origX + origW - 100, origX + dx));
644
+ newH = Math.round(Math.max(40, origH + dy));
643
645
  break;
644
646
  case "ne":
645
- newY = Math.min(origY + origH - 30, origY + dy);
646
- newW = Math.max(50, origW + dx);
647
- newH = Math.max(30, origH - dy);
647
+ newW = Math.round(Math.max(100, origW + dx));
648
+ newH = Math.round(Math.max(40, origH - dy));
649
+ newY = Math.round(Math.min(origY + origH - 40, origY + dy));
648
650
  break;
649
651
  case "nw":
650
- newX = Math.min(origX + origW - 50, origX + dx);
651
- newY = Math.min(origY + origH - 30, origY + dy);
652
- newW = Math.max(50, origW - dx);
653
- newH = Math.max(30, origH - dy);
652
+ newW = Math.round(Math.max(100, origW - dx));
653
+ newX = Math.round(Math.min(origX + origW - 100, origX + dx));
654
+ newH = Math.round(Math.max(40, origH - dy));
655
+ newY = Math.round(Math.min(origY + origH - 40, origY + dy));
654
656
  break;
655
657
  }
656
- return {
657
- ...b,
658
- pos: [Math.round(newX), Math.round(newY), Math.round(newW), Math.round(newH)]
659
- };
658
+ return { ...b, pos: [newX, newY, newW, newH] };
660
659
  });
661
660
  onLayoutChange({ boxes: updated });
662
661
  return updated;
@@ -676,23 +675,27 @@ function SlideDesignOverlay({
676
675
  }
677
676
  }, [dragging, handleMouseMove, handleMouseUp]);
678
677
  const addNewBox = (targetTag) => {
678
+ const isH1 = targetTag === "h1";
679
+ const newId = `box-${Date.now().toString(36)}`;
679
680
  const newBox = {
680
- id: `box-${Date.now().toString(36)}`,
681
+ id: newId,
681
682
  target: targetTag,
682
- pos: [100, 120 + boxes.length * 80, 600, 100],
683
- fontSize: targetTag === "h1" ? "2.5rem" : "1.2rem",
684
- color: targetTag === "h1" ? "#38bdf8" : "#e2e8f0",
683
+ content: isH1 ? "Ti\xEAu \u0111\u1EC1 b\xE0i gi\u1EA3ng" : "Nh\u1EADp n\u1ED9i dung \u0111o\u1EA1n v\u0103n t\u1EA1i \u0111\xE2y...",
684
+ pos: [100, isH1 ? 160 : 300, isH1 ? 700 : 600, isH1 ? 90 : 120],
685
+ fontSize: isH1 ? "2.5rem" : "1.2rem",
686
+ color: isLight ? "#0f172a" : "#f8fafc",
685
687
  textAlign: "left"
686
688
  };
687
689
  const updated = [...boxes, newBox];
688
690
  setBoxes(updated);
689
- setSelectedId(newBox.id);
691
+ setSelectedId(newId);
692
+ setEditingId(newId);
690
693
  onLayoutChange({ boxes: updated });
691
694
  };
692
- const updateSelectedBox = (updates) => {
695
+ const updateSelectedBox = (partial) => {
693
696
  if (!selectedId) return;
694
697
  setBoxes((prev) => {
695
- const updated = prev.map((b) => b.id === selectedId ? { ...b, ...updates } : b);
698
+ const updated = prev.map((b) => b.id === selectedId ? { ...b, ...partial } : b);
696
699
  onLayoutChange({ boxes: updated });
697
700
  return updated;
698
701
  });
@@ -706,6 +709,32 @@ function SlideDesignOverlay({
706
709
  });
707
710
  setSelectedId(null);
708
711
  };
712
+ const isLight = theme === "light";
713
+ const isNavy = theme === "navy";
714
+ const toolbarBg = isLight ? "rgba(255, 255, 255, 0.96)" : isNavy ? "rgba(11, 19, 43, 0.95)" : "rgba(24, 25, 32, 0.95)";
715
+ const toolbarBorder = isLight ? "1px solid rgba(0, 0, 0, 0.12)" : isNavy ? "1px solid rgba(56, 189, 248, 0.35)" : "1px solid rgba(255, 255, 255, 0.15)";
716
+ const toolbarColor = isLight ? "#0f172a" : "#f8fafc";
717
+ const toolbarShadow = isLight ? "0 10px 25px -5px rgba(0, 0, 0, 0.1), 0 8px 10px -6px rgba(0, 0, 0, 0.1)" : "0 12px 30px rgba(0, 0, 0, 0.6)";
718
+ const brandColor = isLight ? "#0284c7" : "#38bdf8";
719
+ const subtextColor = isLight ? "#64748b" : "#94a3b8";
720
+ const btnStyle = {
721
+ height: "28px",
722
+ padding: "0 12px",
723
+ borderRadius: "14px",
724
+ fontSize: "11px",
725
+ fontWeight: 500,
726
+ fontFamily: "inherit",
727
+ border: isLight ? "1px solid rgba(0, 0, 0, 0.1)" : "1px solid rgba(255, 255, 255, 0.15)",
728
+ backgroundColor: isLight ? "rgba(0, 0, 0, 0.04)" : "rgba(255, 255, 255, 0.08)",
729
+ color: isLight ? "#0f172a" : "#f1f5f9",
730
+ cursor: "pointer",
731
+ display: "inline-flex",
732
+ alignItems: "center",
733
+ justifyContent: "center",
734
+ whiteSpace: "nowrap",
735
+ flexShrink: 0,
736
+ transition: "all 0.15s ease"
737
+ };
709
738
  return /* @__PURE__ */ jsxRuntime.jsxs(
710
739
  "div",
711
740
  {
@@ -714,7 +743,6 @@ function SlideDesignOverlay({
714
743
  inset: 0,
715
744
  zIndex: 50,
716
745
  pointerEvents: "none"
717
- // Allow passing through to children that have pointerEvents: 'auto'
718
746
  },
719
747
  children: [
720
748
  /* @__PURE__ */ jsxRuntime.jsxs(
@@ -731,36 +759,21 @@ function SlideDesignOverlay({
731
759
  alignItems: "center",
732
760
  gap: "8px",
733
761
  padding: "6px 14px",
734
- backgroundColor: "#1e1f29",
735
- border: "1px solid rgba(56, 189, 248, 0.4)",
762
+ backgroundColor: toolbarBg,
763
+ backdropFilter: "blur(12px)",
764
+ WebkitBackdropFilter: "blur(12px)",
765
+ border: toolbarBorder,
736
766
  borderRadius: "24px",
737
- boxShadow: "0 8px 30px rgba(0, 0, 0, 0.5)",
738
- color: "#f8fafc",
767
+ boxShadow: toolbarShadow,
768
+ color: toolbarColor,
739
769
  fontSize: "12px",
740
- fontFamily: "Inter, sans-serif"
770
+ fontFamily: "Inter, sans-serif",
771
+ whiteSpace: "nowrap"
741
772
  },
742
773
  children: [
743
- /* @__PURE__ */ jsxRuntime.jsx("span", { style: { fontWeight: 600, color: "#38bdf8" }, children: "Design Canvas:" }),
744
- /* @__PURE__ */ jsxRuntime.jsx(
745
- "button",
746
- {
747
- type: "button",
748
- onClick: () => addNewBox("h1"),
749
- style: toolbarButtonStyle,
750
- title: "Th\xEAm khung v\u1ECB tr\xED Ti\xEAu \u0111\u1EC1",
751
- children: "+ Ti\xEAu \u0111\u1EC1 (H1)"
752
- }
753
- ),
754
- /* @__PURE__ */ jsxRuntime.jsx(
755
- "button",
756
- {
757
- type: "button",
758
- onClick: () => addNewBox("p"),
759
- style: toolbarButtonStyle,
760
- title: "Th\xEAm khung v\u1ECB tr\xED \u0110o\u1EA1n v\u0103n",
761
- children: "+ \u0110o\u1EA1n v\u0103n (P)"
762
- }
763
- ),
774
+ /* @__PURE__ */ jsxRuntime.jsx("span", { style: { fontWeight: 600, color: brandColor, whiteSpace: "nowrap" }, children: "Design Canvas:" }),
775
+ /* @__PURE__ */ jsxRuntime.jsx("button", { type: "button", onClick: () => addNewBox("h1"), style: btnStyle, title: "Th\xEAm khung v\u1ECB tr\xED Ti\xEAu \u0111\u1EC1", children: "+ Ti\xEAu \u0111\u1EC1 (H1)" }),
776
+ /* @__PURE__ */ jsxRuntime.jsx("button", { type: "button", onClick: () => addNewBox("p"), style: btnStyle, title: "Th\xEAm khung v\u1ECB tr\xED \u0110o\u1EA1n v\u0103n", children: "+ \u0110o\u1EA1n v\u0103n (P)" }),
764
777
  /* @__PURE__ */ jsxRuntime.jsxs(
765
778
  "select",
766
779
  {
@@ -774,263 +787,248 @@ function SlideDesignOverlay({
774
787
  },
775
788
  defaultValue: "",
776
789
  style: {
777
- ...toolbarButtonStyle,
790
+ ...btnStyle,
778
791
  cursor: "pointer",
779
792
  outline: "none",
780
- color: "#f8fafc",
781
- border: "1px solid rgba(56, 189, 248, 0.3)"
793
+ color: isLight ? "#0f172a" : "#f8fafc",
794
+ backgroundColor: isLight ? "#ffffff" : "#1e1f29",
795
+ border: isLight ? "1px solid rgba(0, 0, 0, 0.15)" : "1px solid rgba(56, 189, 248, 0.3)",
796
+ maxWidth: "180px"
782
797
  },
783
798
  title: "\xC1p d\u1EE5ng m\u1EABu b\u1ED1 c\u1EE5c c\xF3 s\u1EB5n",
784
799
  children: [
785
- /* @__PURE__ */ jsxRuntime.jsx("option", { value: "", disabled: true, style: { backgroundColor: "#1e1f29", color: "#94a3b8" }, children: "M\u1EABu b\u1ED1 c\u1EE5c (Presets)..." }),
786
- chunkO5MCKVEA_cjs.SLIDE_LAYOUT_PRESETS.map((p) => /* @__PURE__ */ jsxRuntime.jsx("option", { value: p.id, style: { backgroundColor: "#1e1f29", color: "#f8fafc" }, children: p.name }, p.id))
800
+ /* @__PURE__ */ jsxRuntime.jsx("option", { value: "", disabled: true, style: { backgroundColor: isLight ? "#ffffff" : "#1e1f29", color: subtextColor }, children: "M\u1EABu b\u1ED1 c\u1EE5c (Presets)..." }),
801
+ chunkO5MCKVEA_cjs.SLIDE_LAYOUT_PRESETS.map((p) => /* @__PURE__ */ jsxRuntime.jsx("option", { value: p.id, style: { backgroundColor: isLight ? "#ffffff" : "#1e1f29", color: isLight ? "#0f172a" : "#f8fafc" }, children: p.name }, p.id))
787
802
  ]
788
803
  }
789
804
  ),
790
- /* @__PURE__ */ jsxRuntime.jsx("div", { style: { width: "1px", height: "16px", backgroundColor: "rgba(255,255,255,0.2)" } }),
791
- onSave && /* @__PURE__ */ jsxRuntime.jsx(
792
- "button",
793
- {
794
- type: "button",
795
- onClick: () => onSave({ boxes }),
796
- style: {
797
- ...toolbarButtonStyle,
798
- backgroundColor: "#0284c7",
799
- color: "#ffffff",
800
- fontWeight: 600
801
- },
802
- children: "L\u01B0u b\u1ED1 c\u1EE5c"
803
- }
804
- ),
805
- onClose && /* @__PURE__ */ jsxRuntime.jsx(
806
- "button",
807
- {
808
- type: "button",
809
- onClick: onClose,
810
- style: {
811
- ...toolbarButtonStyle,
812
- backgroundColor: "transparent",
813
- color: "#94a3b8"
814
- },
815
- children: "\u0110\xF3ng"
816
- }
817
- )
805
+ /* @__PURE__ */ jsxRuntime.jsx("div", { style: { width: "1px", height: "16px", backgroundColor: isLight ? "rgba(0,0,0,0.15)" : "rgba(255,255,255,0.2)" } }),
806
+ onSave && /* @__PURE__ */ jsxRuntime.jsx("button", { type: "button", onClick: () => onSave({ boxes }), style: { ...btnStyle, backgroundColor: "#0284c7", color: "#ffffff", fontWeight: 600, border: "none" }, children: "L\u01B0u b\u1ED1 c\u1EE5c" }),
807
+ onClose && /* @__PURE__ */ jsxRuntime.jsx("button", { type: "button", onClick: onClose, style: { ...btnStyle, backgroundColor: "transparent", border: "none", color: subtextColor }, children: "\u0110\xF3ng" })
818
808
  ]
819
809
  }
820
810
  ),
821
- /* @__PURE__ */ jsxRuntime.jsx(
822
- "div",
823
- {
824
- ref: containerRef,
825
- style: {
826
- position: "absolute",
827
- inset: 0,
828
- pointerEvents: "auto"
829
- },
830
- onClick: () => setSelectedId(null),
831
- children: boxes.map((box) => {
832
- const [x, y, w, h] = box.pos;
833
- const isSelected = box.id === selectedId;
834
- const leftPercent = x / 1280 * 100;
835
- const topPercent = y / 720 * 100;
836
- const widthPercent = w / 1280 * 100;
837
- const heightPercent = h / 720 * 100;
838
- return /* @__PURE__ */ jsxRuntime.jsxs(
839
- "div",
840
- {
841
- onClick: (e) => {
842
- e.stopPropagation();
843
- setSelectedId(box.id);
844
- },
845
- onMouseDown: (e) => handleMouseDown(e, box, "move"),
846
- style: {
847
- position: "absolute",
848
- left: `${leftPercent}%`,
849
- top: `${topPercent}%`,
850
- width: `${widthPercent}%`,
851
- height: `${heightPercent}%`,
852
- border: isSelected ? "2px solid #38bdf8" : "1px dashed rgba(56, 189, 248, 0.5)",
853
- backgroundColor: isSelected ? "rgba(56, 189, 248, 0.08)" : "rgba(56, 189, 248, 0.03)",
854
- cursor: "move",
855
- userSelect: "none",
856
- boxSizing: "border-box",
857
- zIndex: isSelected ? 40 : 20
858
- },
859
- children: [
860
- /* @__PURE__ */ jsxRuntime.jsxs(
811
+ /* @__PURE__ */ jsxRuntime.jsx("div", { ref: containerRef, style: { position: "absolute", inset: 0, pointerEvents: "auto" }, onClick: () => setSelectedId(null), children: boxes.map((box) => {
812
+ const [x, y, w, h] = box.pos;
813
+ const isSelected = box.id === selectedId;
814
+ const leftPercent = x / 1280 * 100;
815
+ const topPercent = y / 720 * 100;
816
+ const widthPercent = w / 1280 * 100;
817
+ const heightPercent = h / 720 * 100;
818
+ return /* @__PURE__ */ jsxRuntime.jsxs(
819
+ "div",
820
+ {
821
+ onClick: (e) => {
822
+ e.stopPropagation();
823
+ setSelectedId(box.id);
824
+ },
825
+ onMouseDown: (e) => handleMouseDown(e, box, "move"),
826
+ style: {
827
+ position: "absolute",
828
+ left: `${leftPercent}%`,
829
+ top: `${topPercent}%`,
830
+ width: `${widthPercent}%`,
831
+ height: `${heightPercent}%`,
832
+ border: isSelected ? isLight ? "2px solid #0284c7" : "2px solid #38bdf8" : isLight ? "1.5px dashed rgba(2, 132, 199, 0.5)" : "1.5px dashed rgba(56, 189, 248, 0.5)",
833
+ backgroundColor: isSelected ? isLight ? "rgba(2, 132, 199, 0.08)" : "rgba(56, 189, 248, 0.08)" : isLight ? "rgba(2, 132, 199, 0.02)" : "rgba(56, 189, 248, 0.03)",
834
+ cursor: editingId === box.id ? "default" : "move",
835
+ userSelect: editingId === box.id ? "text" : "none",
836
+ boxSizing: "border-box",
837
+ zIndex: isSelected ? 40 : 20,
838
+ display: "flex",
839
+ alignItems: "center",
840
+ overflow: "visible"
841
+ },
842
+ children: [
843
+ /* @__PURE__ */ jsxRuntime.jsx(
844
+ "div",
845
+ {
846
+ style: {
847
+ width: "100%",
848
+ height: "100%",
849
+ padding: "4px 8px",
850
+ boxSizing: "border-box",
851
+ display: "flex",
852
+ alignItems: "center",
853
+ overflow: "hidden"
854
+ },
855
+ children: editingId === box.id ? /* @__PURE__ */ jsxRuntime.jsx(
856
+ "textarea",
857
+ {
858
+ autoFocus: true,
859
+ value: box.content ?? "",
860
+ placeholder: box.target === "h1" ? "Nh\u1EADp ti\xEAu \u0111\u1EC1..." : "Nh\u1EADp n\u1ED9i dung...",
861
+ onChange: (e) => updateSelectedBox({ content: e.target.value }),
862
+ onBlur: () => setEditingId(null),
863
+ onKeyDown: (e) => {
864
+ if (e.key === "Escape") setEditingId(null);
865
+ },
866
+ onClick: (e) => e.stopPropagation(),
867
+ onMouseDown: (e) => e.stopPropagation(),
868
+ style: {
869
+ width: "100%",
870
+ height: "100%",
871
+ background: "transparent",
872
+ border: "none",
873
+ outline: "none",
874
+ resize: "none",
875
+ fontSize: box.fontSize ?? (box.target === "h1" ? "2.2rem" : "1.1rem"),
876
+ color: box.color ?? (isLight ? "#0f172a" : "#f8fafc"),
877
+ textAlign: box.textAlign ?? "left",
878
+ fontFamily: "Inter, sans-serif",
879
+ fontWeight: box.target === "h1" ? 700 : 400,
880
+ lineHeight: 1.25,
881
+ padding: 0,
882
+ margin: 0
883
+ }
884
+ }
885
+ ) : /* @__PURE__ */ jsxRuntime.jsx(
861
886
  "div",
862
887
  {
888
+ onDoubleClick: (e) => {
889
+ e.stopPropagation();
890
+ setSelectedId(box.id);
891
+ setEditingId(box.id);
892
+ },
863
893
  style: {
864
- position: "absolute",
865
- top: "-18px",
866
- left: "0",
867
- fontSize: "10px",
868
- fontWeight: 600,
869
- color: isSelected ? "#38bdf8" : "rgba(56, 189, 248, 0.7)",
870
- backgroundColor: "rgba(0,0,0,0.8)",
871
- padding: "1px 6px",
872
- borderRadius: "3px",
873
- whiteSpace: "nowrap"
894
+ width: "100%",
895
+ height: "100%",
896
+ fontSize: box.fontSize ?? (box.target === "h1" ? "2.2rem" : "1.1rem"),
897
+ color: box.color ?? (isLight ? "#0f172a" : "#f8fafc"),
898
+ textAlign: box.textAlign ?? "left",
899
+ fontFamily: "Inter, sans-serif",
900
+ fontWeight: box.target === "h1" ? 700 : 400,
901
+ lineHeight: 1.25,
902
+ wordBreak: "break-word",
903
+ userSelect: "none",
904
+ cursor: "pointer",
905
+ display: "flex",
906
+ alignItems: "center"
874
907
  },
875
- children: [
876
- box.target || box.id,
877
- " (",
878
- Math.round(x),
879
- ", ",
880
- Math.round(y),
881
- ")"
882
- ]
908
+ title: "Click \u0111\xFAp \u0111\u1EC3 s\u1EEDa ch\u1EEF",
909
+ children: box.content ? /* @__PURE__ */ jsxRuntime.jsx("span", { children: box.content }) : /* @__PURE__ */ jsxRuntime.jsx("span", { style: { opacity: 0.45, fontStyle: "italic", fontSize: "12px" }, children: box.target === "h1" ? "Ti\xEAu \u0111\u1EC1 (Click \u0111\xFAp \u0111\u1EC3 s\u1EEDa)..." : "N\u1ED9i dung (Click \u0111\xFAp \u0111\u1EC3 s\u1EEDa)..." })
883
910
  }
884
- ),
885
- isSelected && /* @__PURE__ */ jsxRuntime.jsxs(jsxRuntime.Fragment, { children: [
886
- /* @__PURE__ */ jsxRuntime.jsx(
887
- "div",
888
- {
889
- style: handleStyle("se"),
890
- onMouseDown: (e) => handleMouseDown(e, box, "se")
891
- }
892
- ),
893
- /* @__PURE__ */ jsxRuntime.jsx(
894
- "div",
895
- {
896
- style: handleStyle("e"),
897
- onMouseDown: (e) => handleMouseDown(e, box, "e")
898
- }
899
- ),
900
- /* @__PURE__ */ jsxRuntime.jsx(
901
- "div",
902
- {
903
- style: handleStyle("s"),
904
- onMouseDown: (e) => handleMouseDown(e, box, "s")
905
- }
906
- ),
907
- /* @__PURE__ */ jsxRuntime.jsx(
908
- "div",
909
- {
910
- style: handleStyle("sw"),
911
- onMouseDown: (e) => handleMouseDown(e, box, "sw")
912
- }
913
- ),
914
- /* @__PURE__ */ jsxRuntime.jsx(
915
- "div",
916
- {
917
- style: handleStyle("ne"),
918
- onMouseDown: (e) => handleMouseDown(e, box, "ne")
919
- }
920
- ),
921
- /* @__PURE__ */ jsxRuntime.jsx(
922
- "div",
923
- {
924
- style: handleStyle("nw"),
925
- onMouseDown: (e) => handleMouseDown(e, box, "nw")
926
- }
927
- )
928
- ] })
929
- ]
930
- },
931
- box.id
932
- );
933
- })
934
- }
935
- ),
911
+ )
912
+ }
913
+ ),
914
+ /* @__PURE__ */ jsxRuntime.jsxs(
915
+ "div",
916
+ {
917
+ style: {
918
+ position: "absolute",
919
+ top: "-20px",
920
+ left: "0",
921
+ fontSize: "10px",
922
+ fontWeight: 600,
923
+ color: isLight ? isSelected ? "#0284c7" : "#475569" : isSelected ? "#38bdf8" : "rgba(56, 189, 248, 0.8)",
924
+ backgroundColor: isLight ? "rgba(255,255,255,0.95)" : "rgba(15,23,42,0.9)",
925
+ border: isLight ? "1px solid rgba(0,0,0,0.1)" : "1px solid rgba(56,189,248,0.3)",
926
+ padding: "1px 6px",
927
+ borderRadius: "4px",
928
+ whiteSpace: "nowrap",
929
+ boxShadow: "0 2px 4px rgba(0,0,0,0.1)"
930
+ },
931
+ children: [
932
+ box.target || box.id,
933
+ " (",
934
+ Math.round(x),
935
+ ", ",
936
+ Math.round(y),
937
+ ")"
938
+ ]
939
+ }
940
+ ),
941
+ isSelected && /* @__PURE__ */ jsxRuntime.jsxs(jsxRuntime.Fragment, { children: [
942
+ /* @__PURE__ */ jsxRuntime.jsx("div", { style: handleStyle("se", isLight), onMouseDown: (e) => handleMouseDown(e, box, "se") }),
943
+ /* @__PURE__ */ jsxRuntime.jsx("div", { style: handleStyle("e", isLight), onMouseDown: (e) => handleMouseDown(e, box, "e") }),
944
+ /* @__PURE__ */ jsxRuntime.jsx("div", { style: handleStyle("s", isLight), onMouseDown: (e) => handleMouseDown(e, box, "s") }),
945
+ /* @__PURE__ */ jsxRuntime.jsx("div", { style: handleStyle("sw", isLight), onMouseDown: (e) => handleMouseDown(e, box, "sw") }),
946
+ /* @__PURE__ */ jsxRuntime.jsx("div", { style: handleStyle("ne", isLight), onMouseDown: (e) => handleMouseDown(e, box, "ne") }),
947
+ /* @__PURE__ */ jsxRuntime.jsx("div", { style: handleStyle("nw", isLight), onMouseDown: (e) => handleMouseDown(e, box, "nw") })
948
+ ] })
949
+ ]
950
+ },
951
+ box.id
952
+ );
953
+ }) }),
936
954
  selectedBox && /* @__PURE__ */ jsxRuntime.jsxs(
937
955
  "div",
938
956
  {
939
957
  style: {
940
958
  position: "absolute",
941
- bottom: "24px",
959
+ bottom: "20px",
942
960
  left: "50%",
943
961
  transform: "translateX(-50%)",
944
962
  zIndex: 60,
945
963
  pointerEvents: "auto",
946
964
  display: "flex",
947
965
  alignItems: "center",
948
- gap: "12px",
966
+ gap: "10px",
949
967
  padding: "8px 16px",
950
- backgroundColor: "#181920",
951
- border: "1px solid rgba(255,255,255,0.15)",
968
+ backgroundColor: toolbarBg,
969
+ backdropFilter: "blur(12px)",
970
+ WebkitBackdropFilter: "blur(12px)",
971
+ border: toolbarBorder,
952
972
  borderRadius: "12px",
953
- boxShadow: "0 10px 30px rgba(0,0,0,0.6)",
954
- color: "#f8fafc",
973
+ boxShadow: toolbarShadow,
974
+ color: toolbarColor,
955
975
  fontSize: "12px",
956
- fontFamily: "Inter, sans-serif"
976
+ fontFamily: "Inter, sans-serif",
977
+ whiteSpace: "nowrap"
957
978
  },
958
979
  children: [
959
- /* @__PURE__ */ jsxRuntime.jsxs("span", { style: { fontWeight: 600, color: "#38bdf8" }, children: [
980
+ /* @__PURE__ */ jsxRuntime.jsxs("span", { style: { fontWeight: 600, color: brandColor, whiteSpace: "nowrap" }, children: [
960
981
  "Khung: ",
961
982
  selectedBox.target
962
983
  ] }),
963
- /* @__PURE__ */ jsxRuntime.jsxs("div", { style: { display: "flex", alignItems: "center", gap: "4px" }, children: [
964
- /* @__PURE__ */ jsxRuntime.jsx("span", { style: { color: "#94a3b8", fontSize: "11px" }, children: "Size:" }),
984
+ /* @__PURE__ */ jsxRuntime.jsxs("div", { style: { display: "flex", alignItems: "center", gap: "4px", whiteSpace: "nowrap" }, children: [
985
+ /* @__PURE__ */ jsxRuntime.jsx("span", { style: { color: subtextColor, fontSize: "11px" }, children: "Ch\u1EEF:" }),
965
986
  /* @__PURE__ */ jsxRuntime.jsx(
966
987
  "input",
967
988
  {
968
989
  type: "text",
969
- value: selectedBox.fontSize ?? "1.5rem",
970
- onChange: (e) => updateSelectedBox({ fontSize: e.target.value }),
990
+ value: selectedBox.content ?? "",
991
+ placeholder: "Nh\u1EADp n\u1ED9i dung...",
992
+ onChange: (e) => updateSelectedBox({ content: e.target.value }),
971
993
  style: {
972
- width: "60px",
973
- padding: "2px 6px",
994
+ width: "130px",
995
+ padding: "2px 8px",
974
996
  borderRadius: "4px",
975
- border: "1px solid #334155",
976
- backgroundColor: "#0f172a",
977
- color: "#f8fafc",
997
+ border: isLight ? "1px solid #cbd5e1" : "1px solid #334155",
998
+ backgroundColor: isLight ? "#f8fafc" : "#0f172a",
999
+ color: isLight ? "#0f172a" : "#f8fafc",
978
1000
  fontSize: "11px"
979
1001
  }
980
1002
  }
981
1003
  )
982
1004
  ] }),
983
- /* @__PURE__ */ jsxRuntime.jsxs("div", { style: { display: "flex", alignItems: "center", gap: "4px" }, children: [
984
- /* @__PURE__ */ jsxRuntime.jsx("span", { style: { color: "#94a3b8", fontSize: "11px" }, children: "Color:" }),
985
- /* @__PURE__ */ jsxRuntime.jsx(
986
- "input",
987
- {
988
- type: "color",
989
- value: selectedBox.color ?? "#38bdf8",
990
- onChange: (e) => updateSelectedBox({ color: e.target.value }),
991
- style: {
992
- width: "24px",
993
- height: "24px",
994
- padding: "0",
995
- border: "none",
996
- borderRadius: "4px",
997
- cursor: "pointer",
998
- backgroundColor: "transparent"
999
- }
1000
- }
1001
- )
1002
- ] }),
1003
- /* @__PURE__ */ jsxRuntime.jsx("div", { style: { display: "flex", alignItems: "center", gap: "2px" }, children: ["left", "center", "right"].map((align) => /* @__PURE__ */ jsxRuntime.jsx(
1004
- "button",
1005
- {
1006
- type: "button",
1007
- onClick: () => updateSelectedBox({ textAlign: align }),
1008
- style: {
1009
- ...toolbarButtonStyle,
1010
- backgroundColor: selectedBox.textAlign === align ? "#0284c7" : "rgba(255,255,255,0.05)",
1011
- textTransform: "capitalize",
1012
- fontSize: "11px",
1013
- padding: "2px 8px"
1014
- },
1015
- children: align
1016
- },
1017
- align
1018
- )) }),
1019
1005
  /* @__PURE__ */ jsxRuntime.jsx(
1020
1006
  "button",
1021
1007
  {
1022
1008
  type: "button",
1023
- onClick: removeSelectedBox,
1009
+ onClick: () => setEditingId(selectedBox.id),
1024
1010
  style: {
1025
- ...toolbarButtonStyle,
1026
- backgroundColor: "rgba(239, 68, 68, 0.2)",
1027
- color: "#f87171",
1028
- borderColor: "rgba(239, 68, 68, 0.4)"
1011
+ ...btnStyle,
1012
+ backgroundColor: editingId === selectedBox.id ? "#0284c7" : isLight ? "rgba(0,0,0,0.05)" : "rgba(255,255,255,0.05)",
1013
+ color: editingId === selectedBox.id ? "#ffffff" : isLight ? "#0f172a" : "#e2e8f0",
1014
+ height: "24px",
1015
+ padding: "0 8px"
1029
1016
  },
1030
- title: "X\xF3a \u0111\u1ECBnh v\u1ECB t\u1EF1 do (tr\u1EDF v\u1EC1 lu\u1ED3ng b\xECnh th\u01B0\u1EDDng)",
1031
- children: "Tr\u1EDF v\u1EC1 lu\u1ED3ng m\u1EB7c \u0111\u1ECBnh"
1017
+ title: "S\u1EEDa ch\u1EEF tr\u1EF1c ti\u1EBFp trong khung",
1018
+ children: "S\u1EEDa ch\u1EEF"
1032
1019
  }
1033
- )
1020
+ ),
1021
+ /* @__PURE__ */ jsxRuntime.jsx("div", { style: { width: "1px", height: "14px", backgroundColor: isLight ? "rgba(0,0,0,0.12)" : "rgba(255,255,255,0.15)" } }),
1022
+ /* @__PURE__ */ jsxRuntime.jsxs("div", { style: { display: "flex", alignItems: "center", gap: "4px", whiteSpace: "nowrap" }, children: [
1023
+ /* @__PURE__ */ jsxRuntime.jsx("span", { style: { color: subtextColor, fontSize: "11px" }, children: "Size:" }),
1024
+ /* @__PURE__ */ jsxRuntime.jsx("input", { type: "text", value: selectedBox.fontSize ?? "1.5rem", onChange: (e) => updateSelectedBox({ fontSize: e.target.value }), style: { width: "55px", padding: "2px 6px", borderRadius: "4px", border: isLight ? "1px solid #cbd5e1" : "1px solid #334155", backgroundColor: isLight ? "#f8fafc" : "#0f172a", color: isLight ? "#0f172a" : "#f8fafc", fontSize: "11px" } })
1025
+ ] }),
1026
+ /* @__PURE__ */ jsxRuntime.jsxs("div", { style: { display: "flex", alignItems: "center", gap: "4px", whiteSpace: "nowrap" }, children: [
1027
+ /* @__PURE__ */ jsxRuntime.jsx("span", { style: { color: subtextColor, fontSize: "11px" }, children: "Color:" }),
1028
+ /* @__PURE__ */ jsxRuntime.jsx("input", { type: "color", value: selectedBox.color ?? (isLight ? "#0f172a" : "#38bdf8"), onChange: (e) => updateSelectedBox({ color: e.target.value }), style: { width: "22px", height: "22px", padding: "0", border: "none", borderRadius: "4px", cursor: "pointer", backgroundColor: "transparent" } })
1029
+ ] }),
1030
+ /* @__PURE__ */ jsxRuntime.jsx("div", { style: { display: "flex", alignItems: "center", gap: "2px", whiteSpace: "nowrap" }, children: ["left", "center", "right"].map((align) => /* @__PURE__ */ jsxRuntime.jsx("button", { type: "button", onClick: () => updateSelectedBox({ textAlign: align }), style: { ...btnStyle, backgroundColor: selectedBox.textAlign === align ? "#0284c7" : isLight ? "rgba(0,0,0,0.05)" : "rgba(255,255,255,0.05)", color: selectedBox.textAlign === align ? "#ffffff" : isLight ? "#0f172a" : "#e2e8f0", textTransform: "capitalize", fontSize: "11px", padding: "2px 6px", height: "22px" }, children: align }, align)) }),
1031
+ /* @__PURE__ */ jsxRuntime.jsx("button", { type: "button", onClick: removeSelectedBox, style: { ...btnStyle, backgroundColor: isLight ? "rgba(239, 68, 68, 0.1)" : "rgba(239, 68, 68, 0.2)", color: isLight ? "#dc2626" : "#f87171", border: isLight ? "1px solid rgba(239, 68, 68, 0.3)" : "1px solid rgba(239, 68, 68, 0.4)", fontWeight: 500, height: "22px", padding: "0 8px" }, title: "X\xF3a \u0111\u1ECBnh v\u1ECB t\u1EF1 do c\u1EE7a khung n\xE0y", children: "X\xF3a v\u1ECB tr\xED" })
1034
1032
  ]
1035
1033
  }
1036
1034
  )
@@ -1038,29 +1036,14 @@ function SlideDesignOverlay({
1038
1036
  }
1039
1037
  );
1040
1038
  }
1041
- var toolbarButtonStyle = {
1042
- height: "26px",
1043
- padding: "0 10px",
1044
- borderRadius: "14px",
1045
- fontSize: "11px",
1046
- fontFamily: "inherit",
1047
- border: "1px solid rgba(255, 255, 255, 0.1)",
1048
- backgroundColor: "rgba(255, 255, 255, 0.08)",
1049
- color: "#e2e8f0",
1050
- cursor: "pointer",
1051
- display: "flex",
1052
- alignItems: "center",
1053
- justifyContent: "center",
1054
- transition: "all 0.15s ease"
1055
- };
1056
- function handleStyle(pos) {
1039
+ function handleStyle(pos, isLight = false) {
1057
1040
  const size = 10;
1058
1041
  const base = {
1059
1042
  position: "absolute",
1060
1043
  width: `${size}px`,
1061
1044
  height: `${size}px`,
1062
- backgroundColor: "#ffffff",
1063
- border: "2px solid #0284c7",
1045
+ backgroundColor: isLight ? "#ffffff" : "#0f172a",
1046
+ border: isLight ? "2px solid #0284c7" : "2px solid #38bdf8",
1064
1047
  borderRadius: "2px",
1065
1048
  boxSizing: "border-box",
1066
1049
  zIndex: 50