@thanh01.pmt/presentation-kit 0.2.4 → 0.2.6

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.
@@ -1,6 +1,6 @@
1
1
  import { renderSlide, renderMermaidDiagrams } from '../chunk-JOW4QWKF.js';
2
2
  export { defineTheme, extractMaxClicks, generateClickCss, postprocessClicks, preprocessClicks, renderSlide, renderSlideAsync, resolveTheme } from '../chunk-JOW4QWKF.js';
3
- import { SLIDE_LAYOUT_PRESETS, updateSlideLayoutInMarkdown } from '../chunk-3IKL6SBP.js';
3
+ import { SLIDE_LAYOUT_PRESETS, updateSlideLayoutInMarkdown } from '../chunk-KJA2ZSIC.js';
4
4
  import { useState, useRef, useMemo, useEffect, useCallback } from 'react';
5
5
  import { jsx, jsxs, Fragment } from 'react/jsx-runtime';
6
6
 
@@ -591,6 +591,7 @@ function SlideDesignOverlay({
591
591
  if (!isActive) return null;
592
592
  const [boxes, setBoxes] = useState(layout?.boxes ?? []);
593
593
  const [selectedId, setSelectedId] = useState(null);
594
+ const [editingId, setEditingId] = useState(null);
594
595
  const containerRef = useRef(null);
595
596
  useEffect(() => {
596
597
  setBoxes(layout?.boxes ?? []);
@@ -673,16 +674,21 @@ function SlideDesignOverlay({
673
674
  }
674
675
  }, [dragging, handleMouseMove, handleMouseUp]);
675
676
  const addNewBox = (targetTag) => {
677
+ const isH1 = targetTag === "h1";
676
678
  const newId = `box-${Date.now().toString(36)}`;
677
679
  const newBox = {
678
680
  id: newId,
679
681
  target: targetTag,
680
- pos: [100, 200, 500, 100],
681
- fontSize: targetTag === "h1" ? "2.5rem" : "1.2rem"
682
+ content: isH1 ? "Ti\xEAu \u0111\u1EC1 b\xE0i gi\u1EA3ng" : "Nh\u1EADp n\u1ED9i dung \u0111o\u1EA1n v\u0103n t\u1EA1i \u0111\xE2y...",
683
+ pos: [100, isH1 ? 160 : 300, isH1 ? 700 : 600, isH1 ? 90 : 120],
684
+ fontSize: isH1 ? "2.5rem" : "1.2rem",
685
+ color: isLight ? "#0f172a" : "#f8fafc",
686
+ textAlign: "left"
682
687
  };
683
688
  const updated = [...boxes, newBox];
684
689
  setBoxes(updated);
685
690
  setSelectedId(newId);
691
+ setEditingId(newId);
686
692
  onLayoutChange({ boxes: updated });
687
693
  };
688
694
  const updateSelectedBox = (partial) => {
@@ -824,12 +830,86 @@ function SlideDesignOverlay({
824
830
  height: `${heightPercent}%`,
825
831
  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)",
826
832
  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)",
827
- cursor: "move",
828
- userSelect: "none",
833
+ cursor: editingId === box.id ? "default" : "move",
834
+ userSelect: editingId === box.id ? "text" : "none",
829
835
  boxSizing: "border-box",
830
- zIndex: isSelected ? 40 : 20
836
+ zIndex: isSelected ? 40 : 20,
837
+ display: "flex",
838
+ alignItems: "center",
839
+ overflow: "visible"
831
840
  },
832
841
  children: [
842
+ /* @__PURE__ */ jsx(
843
+ "div",
844
+ {
845
+ style: {
846
+ width: "100%",
847
+ height: "100%",
848
+ padding: "4px 8px",
849
+ boxSizing: "border-box",
850
+ display: "flex",
851
+ alignItems: "center",
852
+ overflow: "hidden"
853
+ },
854
+ children: editingId === box.id ? /* @__PURE__ */ jsx(
855
+ "textarea",
856
+ {
857
+ autoFocus: true,
858
+ value: box.content ?? "",
859
+ placeholder: box.target === "h1" ? "Nh\u1EADp ti\xEAu \u0111\u1EC1..." : "Nh\u1EADp n\u1ED9i dung...",
860
+ onChange: (e) => updateSelectedBox({ content: e.target.value }),
861
+ onBlur: () => setEditingId(null),
862
+ onKeyDown: (e) => {
863
+ if (e.key === "Escape") setEditingId(null);
864
+ },
865
+ onClick: (e) => e.stopPropagation(),
866
+ onMouseDown: (e) => e.stopPropagation(),
867
+ style: {
868
+ width: "100%",
869
+ height: "100%",
870
+ background: "transparent",
871
+ border: "none",
872
+ outline: "none",
873
+ resize: "none",
874
+ fontSize: box.fontSize ?? (box.target === "h1" ? "2.2rem" : "1.1rem"),
875
+ color: box.color ?? (isLight ? "#0f172a" : "#f8fafc"),
876
+ textAlign: box.textAlign ?? "left",
877
+ fontFamily: "Inter, sans-serif",
878
+ fontWeight: box.target === "h1" ? 700 : 400,
879
+ lineHeight: 1.25,
880
+ padding: 0,
881
+ margin: 0
882
+ }
883
+ }
884
+ ) : /* @__PURE__ */ jsx(
885
+ "div",
886
+ {
887
+ onDoubleClick: (e) => {
888
+ e.stopPropagation();
889
+ setSelectedId(box.id);
890
+ setEditingId(box.id);
891
+ },
892
+ style: {
893
+ width: "100%",
894
+ height: "100%",
895
+ fontSize: box.fontSize ?? (box.target === "h1" ? "2.2rem" : "1.1rem"),
896
+ color: box.color ?? (isLight ? "#0f172a" : "#f8fafc"),
897
+ textAlign: box.textAlign ?? "left",
898
+ fontFamily: "Inter, sans-serif",
899
+ fontWeight: box.target === "h1" ? 700 : 400,
900
+ lineHeight: 1.25,
901
+ wordBreak: "break-word",
902
+ userSelect: "none",
903
+ cursor: "pointer",
904
+ display: "flex",
905
+ alignItems: "center"
906
+ },
907
+ title: "Click \u0111\xFAp \u0111\u1EC3 s\u1EEDa ch\u1EEF",
908
+ children: box.content ? /* @__PURE__ */ jsx("span", { children: box.content }) : /* @__PURE__ */ 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)..." })
909
+ }
910
+ )
911
+ }
912
+ ),
833
913
  /* @__PURE__ */ jsxs(
834
914
  "div",
835
915
  {
@@ -882,7 +962,7 @@ function SlideDesignOverlay({
882
962
  pointerEvents: "auto",
883
963
  display: "flex",
884
964
  alignItems: "center",
885
- gap: "12px",
965
+ gap: "10px",
886
966
  padding: "8px 16px",
887
967
  backgroundColor: toolbarBg,
888
968
  backdropFilter: "blur(12px)",
@@ -900,16 +980,54 @@ function SlideDesignOverlay({
900
980
  "Khung: ",
901
981
  selectedBox.target
902
982
  ] }),
983
+ /* @__PURE__ */ jsxs("div", { style: { display: "flex", alignItems: "center", gap: "4px", whiteSpace: "nowrap" }, children: [
984
+ /* @__PURE__ */ jsx("span", { style: { color: subtextColor, fontSize: "11px" }, children: "Ch\u1EEF:" }),
985
+ /* @__PURE__ */ jsx(
986
+ "input",
987
+ {
988
+ type: "text",
989
+ value: selectedBox.content ?? "",
990
+ placeholder: "Nh\u1EADp n\u1ED9i dung...",
991
+ onChange: (e) => updateSelectedBox({ content: e.target.value }),
992
+ style: {
993
+ width: "130px",
994
+ padding: "2px 8px",
995
+ borderRadius: "4px",
996
+ border: isLight ? "1px solid #cbd5e1" : "1px solid #334155",
997
+ backgroundColor: isLight ? "#f8fafc" : "#0f172a",
998
+ color: isLight ? "#0f172a" : "#f8fafc",
999
+ fontSize: "11px"
1000
+ }
1001
+ }
1002
+ )
1003
+ ] }),
1004
+ /* @__PURE__ */ jsx(
1005
+ "button",
1006
+ {
1007
+ type: "button",
1008
+ onClick: () => setEditingId(selectedBox.id),
1009
+ style: {
1010
+ ...btnStyle,
1011
+ backgroundColor: editingId === selectedBox.id ? "#0284c7" : isLight ? "rgba(0,0,0,0.05)" : "rgba(255,255,255,0.05)",
1012
+ color: editingId === selectedBox.id ? "#ffffff" : isLight ? "#0f172a" : "#e2e8f0",
1013
+ height: "24px",
1014
+ padding: "0 8px"
1015
+ },
1016
+ title: "S\u1EEDa ch\u1EEF tr\u1EF1c ti\u1EBFp trong khung",
1017
+ children: "S\u1EEDa ch\u1EEF"
1018
+ }
1019
+ ),
1020
+ /* @__PURE__ */ jsx("div", { style: { width: "1px", height: "14px", backgroundColor: isLight ? "rgba(0,0,0,0.12)" : "rgba(255,255,255,0.15)" } }),
903
1021
  /* @__PURE__ */ jsxs("div", { style: { display: "flex", alignItems: "center", gap: "4px", whiteSpace: "nowrap" }, children: [
904
1022
  /* @__PURE__ */ jsx("span", { style: { color: subtextColor, fontSize: "11px" }, children: "Size:" }),
905
- /* @__PURE__ */ jsx("input", { type: "text", value: selectedBox.fontSize ?? "1.5rem", onChange: (e) => updateSelectedBox({ fontSize: e.target.value }), style: { width: "60px", padding: "2px 6px", borderRadius: "4px", border: isLight ? "1px solid #cbd5e1" : "1px solid #334155", backgroundColor: isLight ? "#f8fafc" : "#0f172a", color: isLight ? "#0f172a" : "#f8fafc", fontSize: "11px" } })
1023
+ /* @__PURE__ */ 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" } })
906
1024
  ] }),
907
1025
  /* @__PURE__ */ jsxs("div", { style: { display: "flex", alignItems: "center", gap: "4px", whiteSpace: "nowrap" }, children: [
908
1026
  /* @__PURE__ */ jsx("span", { style: { color: subtextColor, fontSize: "11px" }, children: "Color:" }),
909
- /* @__PURE__ */ jsx("input", { type: "color", value: selectedBox.color ?? (isLight ? "#0f172a" : "#38bdf8"), onChange: (e) => updateSelectedBox({ color: e.target.value }), style: { width: "24px", height: "24px", padding: "0", border: "none", borderRadius: "4px", cursor: "pointer", backgroundColor: "transparent" } })
1027
+ /* @__PURE__ */ 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" } })
910
1028
  ] }),
911
- /* @__PURE__ */ jsx("div", { style: { display: "flex", alignItems: "center", gap: "2px", whiteSpace: "nowrap" }, children: ["left", "center", "right"].map((align) => /* @__PURE__ */ 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 8px", height: "24px" }, children: align }, align)) }),
912
- /* @__PURE__ */ 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: "24px" }, title: "X\xF3a \u0111\u1ECBnh v\u1ECB t\u1EF1 do c\u1EE7a khung n\xE0y", children: "X\xF3a v\u1ECB tr\xED" })
1029
+ /* @__PURE__ */ jsx("div", { style: { display: "flex", alignItems: "center", gap: "2px", whiteSpace: "nowrap" }, children: ["left", "center", "right"].map((align) => /* @__PURE__ */ 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)) }),
1030
+ /* @__PURE__ */ 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" })
913
1031
  ]
914
1032
  }
915
1033
  )