@vishu1301/script-writing 0.3.9 → 0.4.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/dist/index.js CHANGED
@@ -115,7 +115,6 @@ var blockStyles = {
115
115
  label: "Transition",
116
116
  className: "uppercase font-bold text-right text-zinc-900",
117
117
  inputStyle: {
118
- marginLeft: "4.0in",
119
118
  textTransform: "uppercase",
120
119
  fontWeight: 600,
121
120
  textAlign: "right",
@@ -134,6 +133,8 @@ function ScreenplayEditorView({
134
133
  refs,
135
134
  focusedBlockId,
136
135
  showSuggestions,
136
+ showExtensionSuggestions,
137
+ characterExtensions,
137
138
  locations,
138
139
  characters,
139
140
  sceneNumbers,
@@ -141,6 +142,7 @@ function ScreenplayEditorView({
141
142
  handleSceneTypeChange,
142
143
  handleTimeOfDayChange,
143
144
  handleBlockTypeChange,
145
+ handleSelectCharacterExtension,
144
146
  handleKeyDown,
145
147
  handleFocus,
146
148
  handleBlur,
@@ -355,6 +357,34 @@ function ScreenplayEditorView({
355
357
  char
356
358
  )) })
357
359
  }
360
+ ),
361
+ focusedBlockId === block.id && block.type === "CHARACTER" && showExtensionSuggestions && characterExtensions && /* @__PURE__ */ jsx(
362
+ "div",
363
+ {
364
+ role: "listbox",
365
+ id: `extension-suggestions-${block.id}`,
366
+ className: "absolute top-[calc(100%+8px)] left-1/2 -translate-x-1/2 w-72 z-50 bg-white border border-slate-200 shadow-2xl shadow-slate-200/60 rounded-xl py-2 overflow-hidden animate-in fade-in zoom-in-95 duration-200",
367
+ children: /* @__PURE__ */ jsx("div", { className: "max-h-56 overflow-y-auto custom-scrollbar", children: characterExtensions.filter((ext) => {
368
+ const openParenIndex = block.text.lastIndexOf("(");
369
+ const query = openParenIndex > -1 ? block.text.substring(openParenIndex + 1).toUpperCase() : "";
370
+ return ext.toUpperCase().includes(query);
371
+ }).map((ext) => /* @__PURE__ */ jsxs(
372
+ "div",
373
+ {
374
+ role: "option",
375
+ className: "group flex items-center px-4 py-2.5 cursor-pointer transition-colors duration-150 hover:bg-slate-50 active:bg-slate-100",
376
+ onMouseDown: (e) => {
377
+ e.preventDefault();
378
+ handleSelectCharacterExtension(ext);
379
+ },
380
+ children: [
381
+ /* @__PURE__ */ jsx("span", { className: "flex-1 text-[11px] font-bold tracking-[0.1em] text-slate-600 uppercase text-left", children: ext }),
382
+ /* @__PURE__ */ jsx(ChevronRight, { className: "w-3 h-3 text-slate-200 opacity-0 group-hover:opacity-100 transition-all -translate-x-1 group-hover:translate-x-0" })
383
+ ]
384
+ },
385
+ ext
386
+ )) })
387
+ }
358
388
  )
359
389
  ] })
360
390
  },
@@ -579,6 +609,7 @@ function useScreenplayEditor() {
579
609
  );
580
610
  const [newBlockId, setNewBlockId] = useState(null);
581
611
  const [showSuggestions, setShowSuggestions] = useState(false);
612
+ const [showExtensionSuggestions, setShowExtensionSuggestions] = useState(false);
582
613
  const blurTimeout = useRef(null);
583
614
  const [isPageSplitEnabled, setIsPageSplitEnabled] = useState(false);
584
615
  const [pageBreaks, setPageBreaks] = useState([]);
@@ -593,12 +624,23 @@ function useScreenplayEditor() {
593
624
  }
594
625
  setIsPageSplitEnabled((prev) => !prev);
595
626
  }, [focusedBlockId]);
627
+ const characterExtensions = useMemo(
628
+ () => ["(V.O.)", "(O.S.)", "(O.C.)", "(SUBTITLE)", "(CONT'D)"],
629
+ []
630
+ );
596
631
  const locations = useMemo(() => {
597
632
  const locs = blocks.filter((b) => b.type === "SCENE_HEADING" && b.text.trim() !== "").map((b) => b.text.trim().toUpperCase());
598
633
  return [...new Set(locs)];
599
634
  }, [blocks]);
600
635
  const characters = useMemo(() => {
601
- const chars = blocks.filter((b) => b.type === "CHARACTER" && b.text.trim() !== "").map((b) => b.text.trim().toUpperCase());
636
+ const chars = blocks.filter((b) => b.type === "CHARACTER" && b.text.trim() !== "").map((b) => {
637
+ const text = b.text.trim().toUpperCase();
638
+ const parenIndex = text.indexOf("(");
639
+ if (parenIndex > -1) {
640
+ return text.substring(0, parenIndex).trim();
641
+ }
642
+ return text;
643
+ }).filter(Boolean);
602
644
  return [...new Set(chars)];
603
645
  }, [blocks]);
604
646
  const sceneNumbers = useMemo(() => {
@@ -646,6 +688,7 @@ function useScreenplayEditor() {
646
688
  if (!isInsideBlock && !isInsideToolbar && !isInsideSuggestions) {
647
689
  setFocusedBlockId("");
648
690
  setShowSuggestions(false);
691
+ setShowExtensionSuggestions(false);
649
692
  }
650
693
  };
651
694
  document.addEventListener("mousedown", handleClickOutside);
@@ -749,6 +792,20 @@ function useScreenplayEditor() {
749
792
  (id, text) => {
750
793
  const block = blocks.find((b) => b.id === id);
751
794
  if (!block) return;
795
+ if (block.type === "CHARACTER") {
796
+ const trimmedText = text.trim();
797
+ const openParenIndex = trimmedText.lastIndexOf("(");
798
+ const closeParenIndex = trimmedText.lastIndexOf(")");
799
+ if (openParenIndex !== -1 && openParenIndex > closeParenIndex) {
800
+ setShowExtensionSuggestions(true);
801
+ setShowSuggestions(false);
802
+ } else {
803
+ setShowExtensionSuggestions(false);
804
+ setShowSuggestions(openParenIndex === -1);
805
+ }
806
+ } else if (showExtensionSuggestions) {
807
+ setShowExtensionSuggestions(false);
808
+ }
752
809
  let processedText = text;
753
810
  if (block.type === "PARENTHETICAL") {
754
811
  const clean = text.replace(/[()]/g, "");
@@ -768,7 +825,7 @@ function useScreenplayEditor() {
768
825
  }
769
826
  }
770
827
  },
771
- [blocks]
828
+ [blocks, showExtensionSuggestions]
772
829
  );
773
830
  const handleSceneTypeChange = useCallback(
774
831
  (id, sceneType) => {
@@ -813,6 +870,35 @@ function useScreenplayEditor() {
813
870
  },
814
871
  [focusedBlockId]
815
872
  );
873
+ const handleSelectCharacterExtension = useCallback(
874
+ (extension) => {
875
+ if (!focusedBlockId) return;
876
+ setBlocks((currentBlocks) => {
877
+ const block = currentBlocks.find((b) => b.id === focusedBlockId);
878
+ if (!block || block.type !== "CHARACTER") return currentBlocks;
879
+ const parenIndex = block.text.indexOf("(");
880
+ const baseText = (parenIndex > -1 ? block.text.substring(0, parenIndex) : block.text).trim();
881
+ const newText = `${baseText} ${extension}`;
882
+ const newBlocks = updateBlock(
883
+ currentBlocks,
884
+ focusedBlockId,
885
+ "text",
886
+ newText
887
+ );
888
+ setTimeout(() => {
889
+ const el = refs.current[focusedBlockId];
890
+ if (el) {
891
+ el.innerText = newText;
892
+ el.focus();
893
+ setCaretPosition(el, newText.length);
894
+ }
895
+ }, 0);
896
+ return newBlocks;
897
+ });
898
+ setShowExtensionSuggestions(false);
899
+ },
900
+ [focusedBlockId]
901
+ );
816
902
  const focusBlock = (id, position = "start") => {
817
903
  const el = refs.current[id];
818
904
  if (!el) return;
@@ -975,11 +1061,29 @@ function useScreenplayEditor() {
975
1061
  clearTimeout(blurTimeout.current);
976
1062
  }
977
1063
  setFocusedBlockId(id);
978
- setShowSuggestions(true);
979
- }, []);
1064
+ const block = blocks.find((b) => b.id === id);
1065
+ if ((block == null ? void 0 : block.type) === "CHARACTER") {
1066
+ const trimmedText = block.text.trim();
1067
+ const openParenIndex = trimmedText.lastIndexOf("(");
1068
+ const closeParenIndex = trimmedText.lastIndexOf(")");
1069
+ if (openParenIndex !== -1 && openParenIndex > closeParenIndex) {
1070
+ setShowExtensionSuggestions(true);
1071
+ setShowSuggestions(false);
1072
+ } else {
1073
+ setShowExtensionSuggestions(false);
1074
+ setShowSuggestions(openParenIndex === -1);
1075
+ }
1076
+ } else {
1077
+ setShowSuggestions(true);
1078
+ setShowExtensionSuggestions(false);
1079
+ }
1080
+ }, [blocks]);
980
1081
  const handleBlur = useCallback((id) => {
981
1082
  if (document.activeElement === refs.current[id]) return;
982
- blurTimeout.current = setTimeout(() => setShowSuggestions(false), 200);
1083
+ blurTimeout.current = setTimeout(() => {
1084
+ setShowSuggestions(false);
1085
+ setShowExtensionSuggestions(false);
1086
+ }, 200);
983
1087
  }, []);
984
1088
  return {
985
1089
  blocks,
@@ -989,6 +1093,8 @@ function useScreenplayEditor() {
989
1093
  refs,
990
1094
  focusedBlockId,
991
1095
  showSuggestions,
1096
+ showExtensionSuggestions,
1097
+ characterExtensions,
992
1098
  locations,
993
1099
  characters,
994
1100
  sceneNumbers,
@@ -996,6 +1102,7 @@ function useScreenplayEditor() {
996
1102
  handleSceneTypeChange,
997
1103
  handleTimeOfDayChange,
998
1104
  handleBlockTypeChange,
1105
+ handleSelectCharacterExtension,
999
1106
  handleKeyDown,
1000
1107
  handleFocus,
1001
1108
  handleBlur
package/dist/index.js.map CHANGED
@@ -1 +1 @@
1
- {"version":3,"sources":["../app/types/screenplay-editor.types.tsx","../app/view/screenplay-editor.view.tsx","../app/service/screenplay-editor.service.ts","../app/hook/use-screenplay-editor.ts"],"names":["jsx","useState","newBlockId"],"mappings":"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","file":"index.js","sourcesContent":["import {\r\n Clapperboard,\r\n Sparkles,\r\n UserRound,\r\n Brackets,\r\n MessageCircle,\r\n ArrowRightLeft,\r\n} from \"lucide-react\";\r\nimport React from \"react\";\r\n\r\nexport type BlockType =\r\n | \"SCENE_HEADING\"\r\n | \"ACTION\"\r\n | \"CHARACTER\"\r\n | \"PARENTHETICAL\"\r\n | \"DIALOGUE\"\r\n | \"TRANSITION\";\r\n\r\nexport type TimeOfDay = \"DAY\" | \"NIGHT\";\r\nexport const timeOfDayOptions: TimeOfDay[] = [\"DAY\", \"NIGHT\"];\r\n\r\nexport interface Block {\r\n id: string;\r\n type: BlockType;\r\n text: string;\r\n sceneType?: \"INT.\" | \"EXT.\" | \"INT/EXT.\";\r\n timeOfDay?: TimeOfDay;\r\n}\r\n\r\nexport const blockTypes: BlockType[] = [\r\n \"SCENE_HEADING\",\r\n \"ACTION\",\r\n \"CHARACTER\",\r\n \"PARENTHETICAL\",\r\n \"DIALOGUE\",\r\n \"TRANSITION\",\r\n];\r\n\r\nexport const uuid = () => Math.random().toString(36).slice(2, 9);\r\n\r\nexport const icons: Record<BlockType, React.ReactNode> = {\r\n SCENE_HEADING: <Clapperboard className=\"w-5 h-5\" />,\r\n ACTION: <Sparkles className=\"w-5 h-5\" />,\r\n CHARACTER: <UserRound className=\"w-5 h-5\" />,\r\n PARENTHETICAL: <Brackets className=\"w-5 h-5\" />,\r\n DIALOGUE: <MessageCircle className=\"w-5 h-5\" />,\r\n TRANSITION: <ArrowRightLeft className=\"w-5 h-5\" />,\r\n};\r\n\r\nexport const blockStyles: Record<\r\n BlockType,\r\n { label: string; className: string; inputStyle: React.CSSProperties }\r\n> = {\r\n SCENE_HEADING: {\r\n label: \"Scene Heading\",\r\n className: \"uppercase font-bold text-zinc-900 flex items-center gap-3\",\r\n inputStyle: {\r\n textTransform: \"uppercase\",\r\n fontWeight: 700,\r\n maxWidth: \"6.0in\",\r\n outline: \"none\",\r\n whiteSpace: \"pre-wrap\",\r\n overflowWrap: \"break-word\",\r\n wordBreak: \"break-word\",\r\n },\r\n },\r\n ACTION: {\r\n label: \"Action\",\r\n className: \"text-zinc-800\",\r\n inputStyle: {\r\n maxWidth: \"6.0in\",\r\n outline: \"none\",\r\n whiteSpace: \"pre-wrap\",\r\n overflowWrap: \"break-word\",\r\n wordBreak: \"break-word\",\r\n lineHeight: \"12pt\",\r\n },\r\n },\r\n CHARACTER: {\r\n label: \"Character\",\r\n className: \"uppercase font-bold text-zinc-900 tracking-widest\",\r\n inputStyle: {\r\n textTransform: \"uppercase\",\r\n textAlign: \"left\",\r\n marginLeft: \"2.0in\",\r\n maxWidth: \"4.0in\",\r\n fontWeight: 700,\r\n letterSpacing: \"0.1em\",\r\n outline: \"none\",\r\n whiteSpace: \"pre-wrap\",\r\n overflowWrap: \"break-word\",\r\n wordBreak: \"break-word\",\r\n },\r\n },\r\n PARENTHETICAL: {\r\n label: \"Parenthetical\",\r\n className: \"text-zinc-600\",\r\n inputStyle: {\r\n fontStyle: \"normal\",\r\n maxWidth: \"3.0in\",\r\n marginLeft: \"1.5in\",\r\n textTransform: \"lowercase\",\r\n outline: \"none\",\r\n whiteSpace: \"pre-wrap\",\r\n overflowWrap: \"break-word\",\r\n wordBreak: \"break-word\",\r\n textAlign: \"left\",\r\n },\r\n },\r\n DIALOGUE: {\r\n label: \"Dialogue\",\r\n className: \"text-zinc-900\",\r\n inputStyle: {\r\n marginLeft: \"1.0in\",\r\n maxWidth: \"3.5in\",\r\n outline: \"none\",\r\n whiteSpace: \"pre-wrap\",\r\n overflowWrap: \"break-word\",\r\n wordBreak: \"break-word\",\r\n fontSize: \"1.05rem\",\r\n textAlign: \"left\",\r\n lineHeight: \"12pt\",\r\n },\r\n },\r\n TRANSITION: {\r\n label: \"Transition\",\r\n className: \"uppercase font-bold text-right text-zinc-900\",\r\n inputStyle: {\r\n marginLeft: \"4.0in\",\r\n textTransform: \"uppercase\",\r\n fontWeight: 600,\r\n textAlign: \"right\",\r\n outline: \"none\",\r\n whiteSpace: \"pre-wrap\",\r\n overflowWrap: \"break-word\",\r\n wordBreak: \"break-word\",\r\n },\r\n },\r\n};\r\n","\"use client\";\r\nimport React, { useState } from \"react\";\r\nimport {\r\n blockStyles,\r\n blockTypes,\r\n icons,\r\n timeOfDayOptions,\r\n} from \"../types/screenplay-editor.types\";\r\nimport { useScreenplayEditor } from \"../hook/use-screenplay-editor\";\r\nimport {\r\n ArrowRight,\r\n ChevronRight,\r\n User,\r\n Cog,\r\n Save,\r\n FileDown,\r\n} from \"lucide-react\";\r\n\r\ntype ScreenplayEditorViewProps = ReturnType<typeof useScreenplayEditor> & {\r\n onSave?: () => void;\r\n onSaveAsPdf?: () => void;\r\n onSyncWithCloud?: () => void;\r\n};\r\nexport function ScreenplayEditorView({\r\n blocks,\r\n pages,\r\n isPageSplitEnabled,\r\n togglePageSplit,\r\n refs,\r\n focusedBlockId,\r\n showSuggestions,\r\n locations,\r\n characters,\r\n sceneNumbers,\r\n handleBlockTextChange,\r\n handleSceneTypeChange,\r\n handleTimeOfDayChange,\r\n handleBlockTypeChange,\r\n handleKeyDown,\r\n handleFocus,\r\n handleBlur,\r\n onSave,\r\n onSaveAsPdf,\r\n onSyncWithCloud,\r\n}: ScreenplayEditorViewProps) {\r\n const [isRulesOpen, setIsRulesOpen] = useState(false);\r\n\r\n return (\r\n <>\r\n <div className=\"sticky top-6 z-50 bg-white backdrop-blur-xl border border-white/10 rounded-full shadow-2xl flex gap-1 max-w-fit p-1.5 mb-12 select-none overflow-x-auto custom-scrollbar\">\r\n {blockTypes.map((type) => {\r\n const selected =\r\n blocks.find((b) => b.id === focusedBlockId)?.type === type;\r\n return (\r\n <button\r\n key={type}\r\n type=\"button\"\r\n className={`flex items-center gap-2 px-4 py-2.5 rounded-full font-medium text-sm transition-all duration-300 ${\r\n selected\r\n ? \"bg-zinc-900 text-white shadow-sm\"\r\n : \"text-zinc-400 hover:bg-zinc-800/10 hover:text-zinc-800\"\r\n }`}\r\n onClick={() => handleBlockTypeChange(type)}\r\n >\r\n <input\r\n type=\"radio\"\r\n name=\"blockType\"\r\n id={`block-type-${type}`}\r\n className=\"sr-only\"\r\n aria-label={blockStyles[type].label}\r\n checked={selected}\r\n readOnly\r\n />\r\n <label\r\n htmlFor={`block-type-${type}`}\r\n className=\"flex items-center gap-2 cursor-pointer\"\r\n >\r\n {icons[type]}\r\n <span className=\"whitespace-nowrap hidden sm:inline\">\r\n {blockStyles[type].label}\r\n </span>\r\n </label>\r\n </button>\r\n );\r\n })}\r\n </div>\r\n\r\n <div className=\"flex flex-col gap-12 w-full items-center pb-24\">\r\n {pages.map((pageBlocks, pageIndex) => (\r\n <div\r\n key={pageIndex}\r\n className=\"relative bg-[#fdfdfc] shadow-2xl shadow-zinc-300/60 ring-1 ring-zinc-200/50 rounded-sm md:rounded-md pl-[1.5in] py-[1in] pr-[1in] flex flex-col w-[210mm] min-h-[297mm] shrink-0\"\r\n style={{\r\n fontFamily:\r\n \"var(--font-courier-prime, 'Courier New', Courier, monospace)\",\r\n }}\r\n >\r\n {pageBlocks.map((block) => (\r\n <div\r\n key={block.id + \"-\" + block.type}\r\n data-block-id={block.id}\r\n className={`relative rounded-sm transition-all duration-200 outline-none ${\r\n focusedBlockId === block.id\r\n ? \"bg-zinc-100/50\"\r\n : \"bg-transparent\"\r\n }`}\r\n >\r\n {block.type === \"SCENE_HEADING\" ? (\r\n <>\r\n <div className=\"flex items-center gap-2 px-4 py-1 bg-transparent\">\r\n <span className=\"absolute -left-16 top-2 w-12 text-right text-zinc-400 font-semibold select-none\">\r\n {String(sceneNumbers[block.id] || 0)}\r\n </span>\r\n <select\r\n className=\"rounded-md text-zinc-800 font-bold px-1.5 py-1 appearance-none bg-transparent hover:bg-zinc-200/50 outline-none cursor-pointer w-fit transition-colors\"\r\n aria-label=\"Scene Type\"\r\n value={block.sceneType ?? \"INT.\"}\r\n onChange={(e) =>\r\n handleSceneTypeChange(block.id, e.target.value as any)\r\n }\r\n >\r\n <option>INT.</option>\r\n <option>EXT.</option>\r\n <option>INT/EXT.</option>\r\n </select>\r\n <div\r\n ref={(el) => {\r\n if (!el) return;\r\n refs.current[block.id] = el;\r\n }}\r\n contentEditable\r\n suppressContentEditableWarning\r\n aria-label={`Scene Heading: ${block.text}`}\r\n aria-haspopup=\"listbox\"\r\n aria-expanded={\r\n focusedBlockId === block.id &&\r\n showSuggestions &&\r\n locations.length > 0\r\n }\r\n spellCheck={false}\r\n className=\"min-w-[3rem] py-1 outline-none text-base font-bold uppercase tracking-widest break-all bg-transparent\"\r\n onInput={(e) =>\r\n handleBlockTextChange(\r\n block.id,\r\n (e.target as HTMLDivElement).innerText,\r\n )\r\n }\r\n onKeyDown={(e) =>\r\n handleKeyDown(e, block.id, block.text)\r\n }\r\n onFocus={() => handleFocus(block.id)}\r\n onBlur={() => handleBlur(block.id)}\r\n ></div>\r\n <span className=\"text-zinc-400/80 font-bold\">-</span>\r\n <select\r\n className=\"rounded-md text-zinc-800 font-bold px-1.5 py-1 appearance-none bg-transparent hover:bg-zinc-200/50 outline-none cursor-pointer transition-colors\"\r\n aria-label=\"Time of Day\"\r\n value={block.timeOfDay ?? \"DAY\"}\r\n onChange={(e) =>\r\n handleTimeOfDayChange(block.id, e.target.value as any)\r\n }\r\n >\r\n {timeOfDayOptions.map((t) => (\r\n <option key={t}>{t}</option>\r\n ))}\r\n </select>\r\n </div>\r\n {focusedBlockId === block.id &&\r\n showSuggestions &&\r\n locations.length > 0 && (\r\n <div\r\n role=\"listbox\"\r\n id={`suggestions-${block.id}`}\r\n className=\"absolute top-[calc(100%+6px)] left-0 min-w-[240px] z-50 bg-white border border-slate-200/80 shadow-xl shadow-slate-200/40 rounded-xl py-1 overflow-hidden animate-in fade-in zoom-in-95 duration-150\"\r\n >\r\n <div className=\"max-h-60 overflow-y-auto custom-scrollbar\">\r\n {locations\r\n .filter(\r\n (loc) =>\r\n loc.startsWith(block.text.toUpperCase()) &&\r\n loc !== block.text.toUpperCase(),\r\n )\r\n .map((loc) => (\r\n <div\r\n role=\"option\"\r\n key={loc}\r\n className=\"group flex items-center justify-between px-4 py-2.5 cursor-pointer transition-all duration-150 hover:bg-slate-50 active:bg-slate-100\"\r\n onMouseDown={(e) => {\r\n e.preventDefault();\r\n const element = refs.current[block.id];\r\n if (element) {\r\n element.innerText = loc;\r\n handleBlockTextChange(block.id, loc);\r\n element.focus();\r\n const range = document.createRange();\r\n const sel = window.getSelection();\r\n range.selectNodeContents(element);\r\n range.collapse(false);\r\n sel?.removeAllRanges();\r\n sel?.addRange(range);\r\n }\r\n handleBlur(block.id);\r\n }}\r\n >\r\n <span className=\"text-[12px] font-semibold tracking-wide text-slate-600 uppercase line-clamp-1\">\r\n {loc}\r\n </span>\r\n\r\n <ArrowRight className=\"w-3.5 h-3.5 text-slate-300 opacity-0 -translate-x-2 group-hover:opacity-100 group-hover:translate-x-0 transition-all duration-200\" />\r\n </div>\r\n ))}\r\n </div>\r\n </div>\r\n )}\r\n </>\r\n ) : (\r\n <>\r\n <div\r\n ref={(el) => {\r\n if (!el) return;\r\n refs.current[block.id] = el;\r\n }}\r\n contentEditable\r\n suppressContentEditableWarning\r\n aria-label={`${blockStyles[block.type].label} text`}\r\n aria-multiline={\r\n block.type === \"ACTION\" || block.type === \"DIALOGUE\"\r\n }\r\n spellCheck={false}\r\n className={`block outline-none w-full min-h-[2.5rem] px-4 py-2 break-words ${\r\n blockStyles[block.type].className\r\n }`}\r\n onInput={(e) =>\r\n handleBlockTextChange(\r\n block.id,\r\n (e.target as HTMLDivElement).innerText,\r\n )\r\n }\r\n onKeyDown={(e) => handleKeyDown(e, block.id, block.text)}\r\n onFocus={() => handleFocus(block.id)}\r\n onBlur={() => handleBlur(block.id)}\r\n style={blockStyles[block.type].inputStyle}\r\n ></div>\r\n {focusedBlockId === block.id &&\r\n block.type === \"CHARACTER\" &&\r\n showSuggestions &&\r\n characters.length > 0 && (\r\n <div\r\n role=\"listbox\"\r\n id={`suggestions-${block.id}`}\r\n className=\"absolute top-[calc(100%+8px)] left-1/2 -translate-x-1/2 w-72 z-50 bg-white border border-slate-200 shadow-2xl shadow-slate-200/60 rounded-xl py-2 overflow-hidden animate-in fade-in zoom-in-95 duration-200\"\r\n >\r\n <div className=\"max-h-56 overflow-y-auto custom-scrollbar\">\r\n {characters\r\n .filter(\r\n (char) =>\r\n char.startsWith(block.text.toUpperCase()) &&\r\n char !== block.text.toUpperCase(),\r\n )\r\n .map((char) => (\r\n <div\r\n role=\"option\"\r\n key={char}\r\n className=\"group flex items-center px-4 py-2.5 cursor-pointer transition-colors duration-150 hover:bg-slate-50 active:bg-slate-100\"\r\n onMouseDown={(e) => {\r\n e.preventDefault();\r\n const element = refs.current[block.id];\r\n if (element) {\r\n element.innerText = char;\r\n handleBlockTextChange(block.id, char);\r\n element.focus();\r\n const range = document.createRange();\r\n const sel = window.getSelection();\r\n range.selectNodeContents(element);\r\n range.collapse(false);\r\n sel?.removeAllRanges();\r\n sel?.addRange(range);\r\n }\r\n handleBlur(block.id);\r\n }}\r\n >\r\n <User className=\"w-3.5 h-3.5 text-slate-300 group-hover:text-sky-500 transition-colors mr-3\" />\r\n\r\n <span className=\"flex-1 text-[11px] font-bold tracking-[0.1em] text-slate-600 uppercase text-left\">\r\n {char}\r\n </span>\r\n\r\n <ChevronRight className=\"w-3 h-3 text-slate-200 opacity-0 group-hover:opacity-100 transition-all -translate-x-1 group-hover:translate-x-0\" />\r\n </div>\r\n ))}\r\n </div>\r\n </div>\r\n )}\r\n </>\r\n )}\r\n </div>\r\n ))}\r\n {isPageSplitEnabled && (\r\n <div className=\"absolute bottom-10 right-16 md:right-20 text-zinc-400 font-semibold text-sm select-none pointer-events-none\">\r\n {pageIndex + 1}.\r\n </div>\r\n )}\r\n </div>\r\n ))}\r\n </div>\r\n <div className=\"fixed bottom-6 right-6 flex flex-col items-end gap-4 z-50\">\r\n {onSave && (\r\n <button\r\n onClick={onSave}\r\n className=\"flex items-center justify-center gap-2 w-auto px-4 h-12 rounded-full bg-zinc-950 text-white shadow-xl shadow-zinc-900/20 border border-white/10 hover:bg-zinc-800 hover:scale-105 active:scale-95 transition-all duration-300\"\r\n aria-label=\"Save Script\"\r\n >\r\n <Save className=\"w-5 h-5\" />\r\n <span className=\"text-sm font-semibold\">Save</span>\r\n </button>\r\n )}\r\n {onSaveAsPdf && (\r\n <button\r\n onClick={onSaveAsPdf}\r\n className=\"flex items-center justify-center gap-2 w-auto px-4 h-12 rounded-full bg-zinc-950 text-white shadow-xl shadow-zinc-900/20 border border-white/10 hover:bg-zinc-800 hover:scale-105 active:scale-95 transition-all duration-300\"\r\n aria-label=\"Save Script as PDF\"\r\n >\r\n <FileDown className=\"w-5 h-5\" />\r\n <span className=\"text-sm font-semibold\">Save as PDF</span>\r\n </button>\r\n )}\r\n {isRulesOpen && (\r\n <div className=\"bg-white/80 backdrop-blur-md rounded-xl shadow-lg border border-zinc-200/50 p-4 text-xs text-zinc-700 select-none font-sans overflow-hidden transition-all duration-300 w-64 origin-bottom-right animate-in fade-in zoom-in-95\">\r\n <h4 className=\"font-bold text-zinc-800 mb-3 text-sm\">\r\n Settings & Shortcuts\r\n </h4>\r\n <div className=\"space-y-4\">\r\n <div className=\"flex items-center justify-between gap-6\">\r\n <span className=\"font-semibold text-zinc-800\">\r\n A4 Page Split\r\n </span>\r\n <button\r\n type=\"button\"\r\n role=\"switch\"\r\n aria-checked={isPageSplitEnabled}\r\n onClick={togglePageSplit}\r\n className={`${\r\n isPageSplitEnabled ? \"bg-zinc-900\" : \"bg-zinc-300\"\r\n } relative inline-flex h-5 w-9 shrink-0 cursor-pointer rounded-full border-2 border-transparent transition-colors duration-200 ease-in-out focus:outline-none`}\r\n >\r\n <span\r\n aria-hidden=\"true\"\r\n className={`${\r\n isPageSplitEnabled ? \"translate-x-4\" : \"translate-x-0\"\r\n } pointer-events-none inline-block h-4 w-4 transform rounded-full bg-white shadow ring-0 transition duration-200 ease-in-out`}\r\n />\r\n </button>\r\n </div>\r\n\r\n <div className=\"space-y-1.5 pt-3 border-t border-zinc-200/50\">\r\n <ul className=\"space-y-1.5\">\r\n <li className=\"flex items-center justify-between gap-6\">\r\n <span>New Block</span>\r\n <kbd className=\"px-2 py-1 text-xs font-semibold text-zinc-800 bg-zinc-200/70 border border-zinc-300/70 rounded-md\">\r\n Enter\r\n </kbd>\r\n </li>\r\n <li className=\"flex items-center justify-between gap-6\">\r\n <span>Delete Block</span>\r\n <kbd className=\"px-2 py-1 text-xs font-semibold text-zinc-800 bg-zinc-200/70 border border-zinc-300/70 rounded-md\">\r\n Backspace\r\n </kbd>\r\n </li>\r\n <li className=\"flex items-center justify-between gap-6\">\r\n <span>Change Type</span>\r\n <div className=\"flex items-center gap-1\">\r\n <kbd className=\"px-2 py-1 text-xs font-semibold text-zinc-800 bg-zinc-200/70 border border-zinc-300/70 rounded-md\">\r\n Ctrl\r\n </kbd>\r\n <span>+</span>\r\n <kbd className=\"px-2 py-1 text-xs font-semibold text-zinc-800 bg-zinc-200/70 border border-zinc-300/70 rounded-md\">\r\n ↑/↓\r\n </kbd>\r\n </div>\r\n </li>\r\n </ul>\r\n </div>\r\n </div>\r\n </div>\r\n )}\r\n <button\r\n onClick={() => setIsRulesOpen(!isRulesOpen)}\r\n className={`flex items-center justify-center w-12 h-12 rounded-full bg-zinc-950 text-white shadow-xl shadow-zinc-900/20 border border-white/10 hover:bg-zinc-800 hover:scale-105 active:scale-95 transition-all duration-300 ${\r\n isRulesOpen ? \"rotate-90\" : \"rotate-0\"\r\n }`}\r\n aria-label=\"Toggle Settings\"\r\n >\r\n <Cog className=\"w-5 h-5\" />\r\n </button>\r\n </div>\r\n </>\r\n );\r\n}\r\n","import { Block, BlockType, uuid } from \"../types/screenplay-editor.types\";\r\n\r\nexport function getNextBlockType(currentType: BlockType): BlockType {\r\n switch (currentType) {\r\n case \"SCENE_HEADING\":\r\n return \"ACTION\";\r\n case \"CHARACTER\":\r\n return \"PARENTHETICAL\";\r\n case \"PARENTHETICAL\":\r\n return \"DIALOGUE\";\r\n case \"DIALOGUE\":\r\n return \"CHARACTER\";\r\n case \"TRANSITION\":\r\n return \"SCENE_HEADING\";\r\n default:\r\n return \"ACTION\";\r\n }\r\n}\r\n\r\nexport function createNewBlock(type: BlockType): Block {\r\n const newBlock: Block = { id: uuid(), type, text: \"\" };\r\n if (type === \"SCENE_HEADING\") {\r\n newBlock.sceneType = \"INT.\";\r\n newBlock.timeOfDay = \"DAY\";\r\n } else if (type === \"PARENTHETICAL\") {\r\n newBlock.text = \"()\";\r\n }\r\n return newBlock;\r\n}\r\n\r\nexport function addBlockAfter(\r\n blocks: Block[],\r\n currentBlockId: string,\r\n): { newBlocks: Block[]; newBlockId: string } {\r\n const currentIndex = blocks.findIndex((b) => b.id === currentBlockId);\r\n if (currentIndex === -1) {\r\n return { newBlocks: blocks, newBlockId: \"\" };\r\n }\r\n\r\n const currentBlock = blocks[currentIndex];\r\n const nextType = getNextBlockType(currentBlock.type);\r\n const newBlock = createNewBlock(nextType);\r\n\r\n const newBlocks = [\r\n ...blocks.slice(0, currentIndex + 1),\r\n newBlock,\r\n ...blocks.slice(currentIndex + 1),\r\n ];\r\n\r\n return { newBlocks, newBlockId: newBlock.id };\r\n}\r\n\r\nexport function deleteBlock(\r\n blocks: Block[],\r\n blockIdToDelete: string,\r\n): { newBlocks: Block[]; nextFocusedId: string | null } {\r\n if (blocks.length <= 1) {\r\n return { newBlocks: blocks, nextFocusedId: blocks[0]?.id || null };\r\n }\r\n\r\n const index = blocks.findIndex((b) => b.id === blockIdToDelete);\r\n if (index === -1) {\r\n return { newBlocks: blocks, nextFocusedId: null };\r\n }\r\n\r\n const newBlocks = [...blocks];\r\n newBlocks.splice(index, 1);\r\n\r\n const nextFocusedId =\r\n newBlocks[index]?.id || newBlocks[index - 1]?.id || null;\r\n\r\n return { newBlocks, nextFocusedId };\r\n}\r\n\r\nexport function updateBlock<K extends keyof Block>(\r\n blocks: Block[],\r\n id: string,\r\n key: K,\r\n value: Block[K],\r\n): Block[] {\r\n return blocks.map((b) => (b.id === id ? { ...b, [key]: value } : b));\r\n}\r\n\r\nexport function changeBlockType(blocks: Block[], id: string, newType: BlockType) {\r\n const newBlock = createNewBlock(newType);\r\n return blocks.map((b) => (b.id === id ? { ...newBlock, id: b.id } : b));\r\n}","\"use client\";\r\nimport React, {\r\n useState,\r\n useRef,\r\n KeyboardEvent,\r\n useEffect,\r\n useMemo,\r\n useCallback,\r\n} from \"react\";\r\nimport {\r\n Block,\r\n BlockType,\r\n TimeOfDay,\r\n uuid,\r\n blockTypes,\r\n} from \"../types/screenplay-editor.types\";\r\nimport * as ScreenplayService from \"../service/screenplay-editor.service\";\r\n\r\nconst initialBlocks: Block[] = [\r\n {\r\n id: uuid(),\r\n type: \"SCENE_HEADING\",\r\n text: \"\",\r\n sceneType: \"INT.\",\r\n timeOfDay: \"DAY\",\r\n },\r\n];\r\n\r\nfunction getCaretCharacterOffsetWithin(element: HTMLElement) {\r\n let caretOffset = 0;\r\n const doc = element.ownerDocument;\r\n const win = doc.defaultView;\r\n const sel = win?.getSelection();\r\n if (sel && sel.rangeCount > 0) {\r\n const range = sel.getRangeAt(0);\r\n const preCaretRange = range.cloneRange();\r\n preCaretRange.selectNodeContents(element);\r\n preCaretRange.setEnd(range.endContainer, range.endOffset);\r\n caretOffset = preCaretRange.toString().length;\r\n }\r\n return caretOffset;\r\n}\r\n\r\nfunction setCaretPosition(element: HTMLElement, offset: number) {\r\n const sel = window.getSelection();\r\n if (!sel) return;\r\n const range = document.createRange();\r\n let currentOffset = 0;\r\n let found = false;\r\n\r\n function traverseNodes(node: Node) {\r\n if (found) return;\r\n if (node.nodeType === Node.TEXT_NODE) {\r\n const length = node.nodeValue?.length || 0;\r\n if (currentOffset + length >= offset) {\r\n range.setStart(node, offset - currentOffset);\r\n range.collapse(true);\r\n found = true;\r\n } else {\r\n currentOffset += length;\r\n }\r\n } else {\r\n for (let i = 0; i < node.childNodes.length; i++) {\r\n traverseNodes(node.childNodes[i]);\r\n if (found) break;\r\n }\r\n }\r\n }\r\n\r\n traverseNodes(element);\r\n\r\n if (!found) {\r\n range.setStart(element, 0);\r\n range.collapse(true);\r\n }\r\n\r\n sel.removeAllRanges();\r\n sel.addRange(range);\r\n}\r\n\r\nexport function useScreenplayEditor() {\r\n const [blocks, setBlocks] = useState<Block[]>(initialBlocks);\r\n const refs = useRef<Record<string, HTMLDivElement | null>>({});\r\n const [focusedBlockId, setFocusedBlockId] = useState<string>(\r\n initialBlocks[0].id,\r\n );\r\n const [newBlockId, setNewBlockId] = useState<string | null>(null);\r\n const [showSuggestions, setShowSuggestions] = useState(false);\r\n const blurTimeout = useRef<NodeJS.Timeout | null>(null);\r\n\r\n const [isPageSplitEnabled, setIsPageSplitEnabled] = useState(false);\r\n const [pageBreaks, setPageBreaks] = useState<string[]>([]);\r\n const focusStateRef = useRef<{ id: string; offset: number } | null>(null);\r\n\r\n const togglePageSplit = useCallback(() => {\r\n if (\r\n focusedBlockId &&\r\n document.activeElement &&\r\n document.activeElement.hasAttribute(\"contenteditable\")\r\n ) {\r\n const el = refs.current[focusedBlockId];\r\n if (el) {\r\n const offset = getCaretCharacterOffsetWithin(el);\r\n focusStateRef.current = { id: focusedBlockId, offset };\r\n }\r\n }\r\n setIsPageSplitEnabled((prev) => !prev);\r\n }, [focusedBlockId]);\r\n\r\n // Derived State\r\n const locations = useMemo(() => {\r\n const locs = blocks\r\n .filter((b) => b.type === \"SCENE_HEADING\" && b.text.trim() !== \"\")\r\n .map((b) => b.text.trim().toUpperCase());\r\n return [...new Set(locs)];\r\n }, [blocks]);\r\n\r\n const characters = useMemo(() => {\r\n const chars = blocks\r\n .filter((b) => b.type === \"CHARACTER\" && b.text.trim() !== \"\")\r\n .map((b) => b.text.trim().toUpperCase());\r\n return [...new Set(chars)];\r\n }, [blocks]);\r\n\r\n const sceneNumbers = useMemo(() => {\r\n const map: Record<string, number> = {};\r\n let count = 0;\r\n blocks.forEach((block) => {\r\n if (block.type === \"SCENE_HEADING\") {\r\n count++;\r\n map[block.id] = count;\r\n }\r\n });\r\n return map;\r\n }, [blocks]);\r\n\r\n // Effects\r\n useEffect(() => {\r\n if (newBlockId && refs.current[newBlockId]) {\r\n const block = blocks.find((b) => b.id === newBlockId);\r\n const el = refs.current[newBlockId];\r\n if (el && block) {\r\n el.focus();\r\n el.innerText = block.text;\r\n if (block.type === \"PARENTHETICAL\") {\r\n setTimeout(() => setCaretPosition(el, 1), 0);\r\n } else {\r\n setTimeout(() => setCaretPosition(el, block.text.length), 0);\r\n }\r\n }\r\n setFocusedBlockId(newBlockId);\r\n setNewBlockId(null);\r\n }\r\n }, [newBlockId, blocks]);\r\n\r\n useEffect(() => {\r\n blocks.forEach((block) => {\r\n const element = refs.current[block.id];\r\n if (\r\n element &&\r\n element.innerText !== block.text &&\r\n document.activeElement !== element\r\n ) {\r\n element.innerText = block.text;\r\n }\r\n });\r\n }, [blocks, isPageSplitEnabled, pageBreaks]);\r\n\r\n useEffect(() => {\r\n const handleClickOutside = (e: MouseEvent) => {\r\n // Check if the clicked element is a contentEditable block or inside the toolbar\r\n const target = e.target as HTMLElement;\r\n const isInsideBlock = target.closest(\"[data-block-id]\");\r\n const isInsideToolbar = target.closest(\".sticky\"); // Adjust selector based on your UI\r\n const isInsideSuggestions = target.closest('[role=\"listbox\"]');\r\n\r\n if (!isInsideBlock && !isInsideToolbar && !isInsideSuggestions) {\r\n setFocusedBlockId(\"\");\r\n setShowSuggestions(false);\r\n }\r\n };\r\n\r\n document.addEventListener(\"mousedown\", handleClickOutside);\r\n return () => {\r\n document.removeEventListener(\"mousedown\", handleClickOutside);\r\n };\r\n }, []);\r\n\r\n useEffect(() => {\r\n if (!isPageSplitEnabled) {\r\n setPageBreaks([]);\r\n return;\r\n }\r\n\r\n const saveFocus = () => {\r\n if (\r\n focusedBlockId &&\r\n document.activeElement &&\r\n document.activeElement.hasAttribute(\"contenteditable\")\r\n ) {\r\n const el = refs.current[focusedBlockId];\r\n if (el) {\r\n const offset = getCaretCharacterOffsetWithin(el);\r\n focusStateRef.current = { id: focusedBlockId, offset };\r\n }\r\n } else {\r\n focusStateRef.current = null;\r\n }\r\n };\r\n\r\n const timeoutId = setTimeout(() => {\r\n let currentHeight = 0;\r\n let hasSceneOnCurrentPage = false;\r\n const A4_HEIGHT = 960; // Approximate content height of A4 inside padding limits\r\n const newPageBreaks: string[] = [];\r\n\r\n blocks.forEach((block) => {\r\n const el = refs.current[block.id];\r\n if (el) {\r\n const measureEl =\r\n document.querySelector(`[data-block-id=\"${block.id}\"]`) || el;\r\n const style = window.getComputedStyle(measureEl);\r\n const marginTop = parseFloat(style.marginTop) || 0;\r\n const marginBottom = parseFloat(style.marginBottom) || 0;\r\n const height =\r\n measureEl.getBoundingClientRect().height + marginTop + marginBottom;\r\n\r\n let breakPage = false;\r\n if (currentHeight + height > A4_HEIGHT) {\r\n breakPage = true;\r\n } else if (block.type === \"SCENE_HEADING\") {\r\n if (hasSceneOnCurrentPage) {\r\n breakPage = true;\r\n } else if (currentHeight > A4_HEIGHT - 120) {\r\n // Widow control for SCENE_HEADING: if near bottom, push to next page\r\n breakPage = true;\r\n }\r\n }\r\n\r\n if (breakPage && currentHeight > 0) {\r\n newPageBreaks.push(block.id);\r\n currentHeight = height;\r\n hasSceneOnCurrentPage = block.type === \"SCENE_HEADING\";\r\n } else {\r\n currentHeight += height;\r\n if (block.type === \"SCENE_HEADING\") {\r\n hasSceneOnCurrentPage = true;\r\n }\r\n }\r\n }\r\n });\r\n\r\n setPageBreaks((prev) => {\r\n if (prev.length !== newPageBreaks.length) {\r\n saveFocus();\r\n return newPageBreaks;\r\n }\r\n for (let i = 0; i < prev.length; i++) {\r\n if (prev[i] !== newPageBreaks[i]) {\r\n saveFocus();\r\n return newPageBreaks;\r\n }\r\n }\r\n return prev;\r\n });\r\n }, 300);\r\n\r\n return () => clearTimeout(timeoutId);\r\n }, [blocks, isPageSplitEnabled, focusedBlockId]);\r\n\r\n const pages = useMemo(() => {\r\n if (!isPageSplitEnabled || pageBreaks.length === 0) return [blocks];\r\n const result: Block[][] = [];\r\n let currentPage: Block[] = [];\r\n for (const block of blocks) {\r\n if (pageBreaks.includes(block.id) && currentPage.length > 0) {\r\n result.push(currentPage);\r\n currentPage = [];\r\n }\r\n currentPage.push(block);\r\n }\r\n if (currentPage.length > 0) result.push(currentPage);\r\n return result;\r\n }, [blocks, isPageSplitEnabled, pageBreaks]);\r\n\r\n useEffect(() => {\r\n if (focusStateRef.current) {\r\n const { id, offset } = focusStateRef.current;\r\n const el = refs.current[id];\r\n if (el && document.activeElement !== el) {\r\n el.focus();\r\n setCaretPosition(el, offset);\r\n }\r\n focusStateRef.current = null;\r\n }\r\n }, [pages]);\r\n\r\n // Handlers\r\n const handleBlockTextChange = useCallback(\r\n (id: string, text: string) => {\r\n const block = blocks.find((b) => b.id === id);\r\n if (!block) return;\r\n\r\n let processedText = text;\r\n if (block.type === \"PARENTHETICAL\") {\r\n const clean = text.replace(/[()]/g, \"\");\r\n processedText = `(${clean})`;\r\n }\r\n\r\n setBlocks((bs) =>\r\n ScreenplayService.updateBlock(bs, id, \"text\", processedText),\r\n );\r\n\r\n if (text !== processedText) {\r\n const el = refs.current[id];\r\n if (el) {\r\n const offset = getCaretCharacterOffsetWithin(el);\r\n const charsBeforeCaret = text.substring(0, offset).replace(/[()]/g, \"\").length;\r\n const newOffset = 1 + charsBeforeCaret;\r\n el.innerText = processedText;\r\n setCaretPosition(el, newOffset);\r\n }\r\n }\r\n },\r\n [blocks],\r\n );\r\n\r\n const handleSceneTypeChange = useCallback(\r\n (id: string, sceneType: \"INT.\" | \"EXT.\" | \"INT/EXT.\") => {\r\n setBlocks((bs) =>\r\n ScreenplayService.updateBlock(bs, id, \"sceneType\", sceneType),\r\n );\r\n setTimeout(() => {\r\n refs.current[id]?.focus();\r\n setFocusedBlockId(id);\r\n }, 10);\r\n },\r\n [],\r\n );\r\n\r\n const handleTimeOfDayChange = useCallback((id: string, time: TimeOfDay) => {\r\n setBlocks((bs) => ScreenplayService.updateBlock(bs, id, \"timeOfDay\", time));\r\n setTimeout(() => {\r\n refs.current[id]?.focus();\r\n setFocusedBlockId(id);\r\n }, 10);\r\n }, []);\r\n\r\n const handleBlockTypeChange = useCallback(\r\n (newType: BlockType) => {\r\n if (!focusedBlockId) return;\r\n setBlocks((bs) =>\r\n ScreenplayService.changeBlockType(bs, focusedBlockId, newType),\r\n );\r\n\r\n setTimeout(() => {\r\n const el = refs.current[focusedBlockId];\r\n if (el) {\r\n el.focus();\r\n const newBlock = ScreenplayService.createNewBlock(newType);\r\n el.innerText = newBlock.text;\r\n if (newType === \"PARENTHETICAL\") {\r\n setCaretPosition(el, 1);\r\n } else {\r\n setCaretPosition(el, newBlock.text.length);\r\n }\r\n }\r\n }, 0);\r\n },\r\n [focusedBlockId],\r\n );\r\n\r\n const focusBlock = (id: string, position: \"start\" | \"end\" = \"start\") => {\r\n const el = refs.current[id];\r\n if (!el) return;\r\n\r\n el.focus();\r\n\r\n const range = document.createRange();\r\n const sel = window.getSelection();\r\n if (!sel) return;\r\n\r\n range.selectNodeContents(el);\r\n range.collapse(position === \"start\");\r\n\r\n sel.removeAllRanges();\r\n sel.addRange(range);\r\n };\r\n\r\n const cycleBlockType = (id: string, direction: \"up\" | \"down\") => {\r\n const block = blocks.find((b) => b.id === id);\r\n if (!block) return;\r\n\r\n const idx = blockTypes.indexOf(block.type);\r\n let newIdx = direction === \"up\" ? idx - 1 : idx + 1;\r\n if (newIdx < 0) newIdx = blockTypes.length - 1;\r\n if (newIdx >= blockTypes.length) newIdx = 0;\r\n\r\n const newType = blockTypes[newIdx];\r\n\r\n setBlocks((bs) => ScreenplayService.changeBlockType(bs, id, newType));\r\n\r\n // Handle the DOM and Caret after the state update\r\n setTimeout(() => {\r\n const el = refs.current[id];\r\n if (el) {\r\n el.focus();\r\n const newBlock = ScreenplayService.createNewBlock(newType);\r\n el.innerText = newBlock.text;\r\n if (newType === \"PARENTHETICAL\") {\r\n setCaretPosition(el, 1);\r\n } else {\r\n setCaretPosition(el, el.innerText.length);\r\n }\r\n }\r\n }, 10);\r\n };\r\n\r\n const handleKeyDown = useCallback(\r\n (e: KeyboardEvent<HTMLDivElement>, id: string, text: string) => {\r\n const block = blocks.find((b) => b.id === id);\r\n\r\n if (block?.type === \"PARENTHETICAL\") {\r\n const offset = getCaretCharacterOffsetWithin(e.currentTarget);\r\n\r\n if (e.key === \"Backspace\" && (offset <= 1 || text === \"()\")) {\r\n e.preventDefault();\r\n cycleBlockType(id, \"up\");\r\n return;\r\n }\r\n if (e.key === \"Delete\" && (offset >= text.length - 1 || text === \"()\")) {\r\n e.preventDefault();\r\n return;\r\n }\r\n }\r\n\r\n if ((e.key === \"Backspace\" || e.key === \"Delete\") && text.length <= 1) {\r\n e.preventDefault();\r\n const { newBlocks, nextFocusedId } = ScreenplayService.deleteBlock(\r\n blocks,\r\n id,\r\n );\r\n setBlocks(newBlocks);\r\n if (nextFocusedId) {\r\n setTimeout(() => {\r\n focusBlock(nextFocusedId, \"end\");\r\n }, 0);\r\n }\r\n return;\r\n }\r\n\r\n if (e.key === \"Enter\" && !e.shiftKey) {\r\n e.preventDefault();\r\n const { newBlocks, newBlockId } = ScreenplayService.addBlockAfter(\r\n blocks,\r\n id,\r\n );\r\n setBlocks(newBlocks);\r\n setNewBlockId(newBlockId);\r\n } else if (e.key === \"ArrowUp\" && e.ctrlKey) {\r\n e.preventDefault();\r\n cycleBlockType(id, \"up\");\r\n } else if (e.key === \"ArrowDown\" && e.ctrlKey) {\r\n e.preventDefault();\r\n cycleBlockType(id, \"down\");\r\n } else if (e.key === \"ArrowUp\" && !e.ctrlKey) {\r\n const selection = window.getSelection();\r\n if (\r\n !selection ||\r\n !selection.isCollapsed ||\r\n selection.rangeCount === 0\r\n ) {\r\n return;\r\n }\r\n\r\n const range = selection.getRangeAt(0);\r\n const contentEditable = e.currentTarget as HTMLDivElement;\r\n\r\n let atStart = false;\r\n if (range.startOffset === 0) {\r\n let node = range.startContainer;\r\n if (node === contentEditable) {\r\n atStart = true;\r\n } else {\r\n let atStartOfParents = true;\r\n while (node !== contentEditable) {\r\n if (node.previousSibling) {\r\n atStartOfParents = false;\r\n break;\r\n }\r\n node = node.parentNode!;\r\n if (!node) {\r\n atStartOfParents = false;\r\n break;\r\n }\r\n }\r\n atStart = atStartOfParents;\r\n }\r\n }\r\n\r\n if (atStart) {\r\n e.preventDefault();\r\n const currentIndex = blocks.findIndex((b) => b.id === id);\r\n if (currentIndex > 0) {\r\n const prevBlockId = blocks[currentIndex - 1].id;\r\n focusBlock(prevBlockId, \"end\");\r\n }\r\n }\r\n } else if (e.key === \"ArrowDown\" && !e.ctrlKey) {\r\n const selection = window.getSelection();\r\n if (\r\n !selection ||\r\n !selection.isCollapsed ||\r\n selection.rangeCount === 0\r\n ) {\r\n return;\r\n }\r\n\r\n const range = selection.getRangeAt(0);\r\n const contentEditable = e.currentTarget as HTMLDivElement;\r\n const container = range.endContainer;\r\n\r\n const isAtEndOffset =\r\n range.endOffset ===\r\n (container.nodeType === Node.TEXT_NODE\r\n ? container.textContent?.length\r\n : container.childNodes.length);\r\n\r\n if (isAtEndOffset) {\r\n let atEnd = false;\r\n let node = container;\r\n if (node === contentEditable) {\r\n atEnd = true;\r\n } else {\r\n let atEndOfParents = true;\r\n while (node !== contentEditable) {\r\n if (node.nextSibling) {\r\n atEndOfParents = false;\r\n break;\r\n }\r\n node = node.parentNode!;\r\n if (!node) {\r\n atEndOfParents = false;\r\n break;\r\n }\r\n }\r\n atEnd = atEndOfParents;\r\n }\r\n\r\n if (atEnd) {\r\n e.preventDefault();\r\n const currentIndex = blocks.findIndex((b) => b.id === id);\r\n if (currentIndex < blocks.length - 1) {\r\n const nextBlockId = blocks[currentIndex + 1].id;\r\n focusBlock(nextBlockId, \"start\");\r\n }\r\n }\r\n }\r\n }\r\n },\r\n [blocks, handleBlockTextChange],\r\n );\r\n\r\n const handleFocus = useCallback((id: string) => {\r\n if (blurTimeout.current) {\r\n clearTimeout(blurTimeout.current);\r\n }\r\n setFocusedBlockId(id);\r\n setShowSuggestions(true);\r\n }, []);\r\n\r\n const handleBlur = useCallback((id: string) => {\r\n if (document.activeElement === refs.current[id]) return;\r\n blurTimeout.current = setTimeout(() => setShowSuggestions(false), 200);\r\n }, []);\r\n\r\n return {\r\n blocks,\r\n pages,\r\n isPageSplitEnabled,\r\n togglePageSplit,\r\n refs,\r\n focusedBlockId,\r\n showSuggestions,\r\n locations,\r\n characters,\r\n sceneNumbers,\r\n handleBlockTextChange,\r\n handleSceneTypeChange,\r\n handleTimeOfDayChange,\r\n handleBlockTypeChange,\r\n handleKeyDown,\r\n handleFocus,\r\n handleBlur,\r\n };\r\n}\r\n"]}
1
+ {"version":3,"sources":["../app/types/screenplay-editor.types.tsx","../app/view/screenplay-editor.view.tsx","../app/service/screenplay-editor.service.ts","../app/hook/use-screenplay-editor.ts"],"names":["jsx","useState","newBlockId"],"mappings":"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","file":"index.js","sourcesContent":["import {\r\n Clapperboard,\r\n Sparkles,\r\n UserRound,\r\n Brackets,\r\n MessageCircle,\r\n ArrowRightLeft,\r\n} from \"lucide-react\";\r\nimport React from \"react\";\r\n\r\nexport type BlockType =\r\n | \"SCENE_HEADING\"\r\n | \"ACTION\"\r\n | \"CHARACTER\"\r\n | \"PARENTHETICAL\"\r\n | \"DIALOGUE\"\r\n | \"TRANSITION\";\r\n\r\nexport type TimeOfDay = \"DAY\" | \"NIGHT\";\r\nexport const timeOfDayOptions: TimeOfDay[] = [\"DAY\", \"NIGHT\"];\r\n\r\nexport interface Block {\r\n id: string;\r\n type: BlockType;\r\n text: string;\r\n sceneType?: \"INT.\" | \"EXT.\" | \"INT/EXT.\";\r\n timeOfDay?: TimeOfDay;\r\n}\r\n\r\nexport const blockTypes: BlockType[] = [\r\n \"SCENE_HEADING\",\r\n \"ACTION\",\r\n \"CHARACTER\",\r\n \"PARENTHETICAL\",\r\n \"DIALOGUE\",\r\n \"TRANSITION\",\r\n];\r\n\r\nexport const uuid = () => Math.random().toString(36).slice(2, 9);\r\n\r\nexport const icons: Record<BlockType, React.ReactNode> = {\r\n SCENE_HEADING: <Clapperboard className=\"w-5 h-5\" />,\r\n ACTION: <Sparkles className=\"w-5 h-5\" />,\r\n CHARACTER: <UserRound className=\"w-5 h-5\" />,\r\n PARENTHETICAL: <Brackets className=\"w-5 h-5\" />,\r\n DIALOGUE: <MessageCircle className=\"w-5 h-5\" />,\r\n TRANSITION: <ArrowRightLeft className=\"w-5 h-5\" />,\r\n};\r\n\r\nexport const blockStyles: Record<\r\n BlockType,\r\n { label: string; className: string; inputStyle: React.CSSProperties }\r\n> = {\r\n SCENE_HEADING: {\r\n label: \"Scene Heading\",\r\n className: \"uppercase font-bold text-zinc-900 flex items-center gap-3\",\r\n inputStyle: {\r\n textTransform: \"uppercase\",\r\n fontWeight: 700,\r\n maxWidth: \"6.0in\",\r\n outline: \"none\",\r\n whiteSpace: \"pre-wrap\",\r\n overflowWrap: \"break-word\",\r\n wordBreak: \"break-word\",\r\n },\r\n },\r\n ACTION: {\r\n label: \"Action\",\r\n className: \"text-zinc-800\",\r\n inputStyle: {\r\n maxWidth: \"6.0in\",\r\n outline: \"none\",\r\n whiteSpace: \"pre-wrap\",\r\n overflowWrap: \"break-word\",\r\n wordBreak: \"break-word\",\r\n lineHeight: \"12pt\",\r\n },\r\n },\r\n CHARACTER: {\r\n label: \"Character\",\r\n className: \"uppercase font-bold text-zinc-900 tracking-widest\",\r\n inputStyle: {\r\n textTransform: \"uppercase\",\r\n textAlign: \"left\",\r\n marginLeft: \"2.0in\",\r\n maxWidth: \"4.0in\",\r\n fontWeight: 700,\r\n letterSpacing: \"0.1em\",\r\n outline: \"none\",\r\n whiteSpace: \"pre-wrap\",\r\n overflowWrap: \"break-word\",\r\n wordBreak: \"break-word\",\r\n },\r\n },\r\n PARENTHETICAL: {\r\n label: \"Parenthetical\",\r\n className: \"text-zinc-600\",\r\n inputStyle: {\r\n fontStyle: \"normal\",\r\n maxWidth: \"3.0in\",\r\n marginLeft: \"1.5in\",\r\n textTransform: \"lowercase\",\r\n outline: \"none\",\r\n whiteSpace: \"pre-wrap\",\r\n overflowWrap: \"break-word\",\r\n wordBreak: \"break-word\",\r\n textAlign: \"left\",\r\n },\r\n },\r\n DIALOGUE: {\r\n label: \"Dialogue\",\r\n className: \"text-zinc-900\",\r\n inputStyle: {\r\n marginLeft: \"1.0in\",\r\n maxWidth: \"3.5in\",\r\n outline: \"none\",\r\n whiteSpace: \"pre-wrap\",\r\n overflowWrap: \"break-word\",\r\n wordBreak: \"break-word\",\r\n fontSize: \"1.05rem\",\r\n textAlign: \"left\",\r\n lineHeight: \"12pt\",\r\n },\r\n },\r\n TRANSITION: {\r\n label: \"Transition\",\r\n className: \"uppercase font-bold text-right text-zinc-900\",\r\n inputStyle: {\r\n textTransform: \"uppercase\",\r\n fontWeight: 600,\r\n textAlign: \"right\",\r\n outline: \"none\",\r\n whiteSpace: \"pre-wrap\",\r\n overflowWrap: \"break-word\",\r\n wordBreak: \"break-word\",\r\n },\r\n },\r\n};\r\n","\"use client\";\r\nimport React, { useState } from \"react\";\r\nimport {\r\n blockStyles,\r\n blockTypes,\r\n icons,\r\n timeOfDayOptions,\r\n} from \"../types/screenplay-editor.types\";\r\nimport { useScreenplayEditor } from \"../hook/use-screenplay-editor\";\r\nimport {\r\n ArrowRight,\r\n ChevronRight,\r\n User,\r\n Cog,\r\n Save,\r\n FileDown,\r\n} from \"lucide-react\";\r\n\r\ntype ScreenplayEditorViewProps = ReturnType<typeof useScreenplayEditor> & {\r\n onSave?: () => void;\r\n onSaveAsPdf?: () => void;\r\n onSyncWithCloud?: () => void;\r\n};\r\nexport function ScreenplayEditorView({\r\n blocks,\r\n pages,\r\n isPageSplitEnabled,\r\n togglePageSplit,\r\n refs,\r\n focusedBlockId,\r\n showSuggestions,\r\n showExtensionSuggestions,\r\n characterExtensions,\r\n locations,\r\n characters,\r\n sceneNumbers,\r\n handleBlockTextChange,\r\n handleSceneTypeChange,\r\n handleTimeOfDayChange,\r\n handleBlockTypeChange,\r\n handleSelectCharacterExtension,\r\n handleKeyDown,\r\n handleFocus,\r\n handleBlur,\r\n onSave,\r\n onSaveAsPdf,\r\n onSyncWithCloud,\r\n}: ScreenplayEditorViewProps) {\r\n const [isRulesOpen, setIsRulesOpen] = useState(false);\r\n return (\r\n <>\r\n <div className=\"sticky top-6 z-50 bg-white backdrop-blur-xl border border-white/10 rounded-full shadow-2xl flex gap-1 max-w-fit p-1.5 mb-12 select-none overflow-x-auto custom-scrollbar\">\r\n {blockTypes.map((type) => {\r\n const selected =\r\n blocks.find((b) => b.id === focusedBlockId)?.type === type;\r\n return (\r\n <button\r\n key={type}\r\n type=\"button\"\r\n className={`flex items-center gap-2 px-4 py-2.5 rounded-full font-medium text-sm transition-all duration-300 ${\r\n selected\r\n ? \"bg-zinc-900 text-white shadow-sm\"\r\n : \"text-zinc-400 hover:bg-zinc-800/10 hover:text-zinc-800\"\r\n }`}\r\n onClick={() => handleBlockTypeChange(type)}\r\n >\r\n <input\r\n type=\"radio\"\r\n name=\"blockType\"\r\n id={`block-type-${type}`}\r\n className=\"sr-only\"\r\n aria-label={blockStyles[type].label}\r\n checked={selected}\r\n readOnly\r\n />\r\n <label\r\n htmlFor={`block-type-${type}`}\r\n className=\"flex items-center gap-2 cursor-pointer\"\r\n >\r\n {icons[type]}\r\n <span className=\"whitespace-nowrap hidden sm:inline\">\r\n {blockStyles[type].label}\r\n </span>\r\n </label>\r\n </button>\r\n );\r\n })}\r\n </div>\r\n\r\n <div className=\"flex flex-col gap-12 w-full items-center pb-24\">\r\n {pages.map((pageBlocks, pageIndex) => (\r\n <div\r\n key={pageIndex}\r\n className=\"relative bg-[#fdfdfc] shadow-2xl shadow-zinc-300/60 ring-1 ring-zinc-200/50 rounded-sm md:rounded-md pl-[1.5in] py-[1in] pr-[1in] flex flex-col w-[210mm] min-h-[297mm] shrink-0\"\r\n style={{\r\n fontFamily:\r\n \"var(--font-courier-prime, 'Courier New', Courier, monospace)\",\r\n }}\r\n >\r\n {pageBlocks.map((block) => (\r\n <div\r\n key={block.id + \"-\" + block.type}\r\n data-block-id={block.id}\r\n className={`relative rounded-sm transition-all duration-200 outline-none ${\r\n focusedBlockId === block.id\r\n ? \"bg-zinc-100/50\"\r\n : \"bg-transparent\"\r\n }`}\r\n >\r\n {block.type === \"SCENE_HEADING\" ? (\r\n <>\r\n <div className=\"flex items-center gap-2 px-4 py-1 bg-transparent\">\r\n <span className=\"absolute -left-16 top-2 w-12 text-right text-zinc-400 font-semibold select-none\">\r\n {String(sceneNumbers[block.id] || 0)}\r\n </span>\r\n <select\r\n className=\"rounded-md text-zinc-800 font-bold px-1.5 py-1 appearance-none bg-transparent hover:bg-zinc-200/50 outline-none cursor-pointer w-fit transition-colors\"\r\n aria-label=\"Scene Type\"\r\n value={block.sceneType ?? \"INT.\"}\r\n onChange={(e) =>\r\n handleSceneTypeChange(block.id, e.target.value as any)\r\n }\r\n >\r\n <option>INT.</option>\r\n <option>EXT.</option>\r\n <option>INT/EXT.</option>\r\n </select>\r\n <div\r\n ref={(el) => {\r\n if (!el) return;\r\n refs.current[block.id] = el;\r\n }}\r\n contentEditable\r\n suppressContentEditableWarning\r\n aria-label={`Scene Heading: ${block.text}`}\r\n aria-haspopup=\"listbox\"\r\n aria-expanded={\r\n focusedBlockId === block.id &&\r\n showSuggestions &&\r\n locations.length > 0\r\n }\r\n spellCheck={false}\r\n className=\"min-w-[3rem] py-1 outline-none text-base font-bold uppercase tracking-widest break-all bg-transparent\"\r\n onInput={(e) =>\r\n handleBlockTextChange(\r\n block.id,\r\n (e.target as HTMLDivElement).innerText,\r\n )\r\n }\r\n onKeyDown={(e) =>\r\n handleKeyDown(e, block.id, block.text)\r\n }\r\n onFocus={() => handleFocus(block.id)}\r\n onBlur={() => handleBlur(block.id)}\r\n ></div>\r\n <span className=\"text-zinc-400/80 font-bold\">-</span>\r\n <select\r\n className=\"rounded-md text-zinc-800 font-bold px-1.5 py-1 appearance-none bg-transparent hover:bg-zinc-200/50 outline-none cursor-pointer transition-colors\"\r\n aria-label=\"Time of Day\"\r\n value={block.timeOfDay ?? \"DAY\"}\r\n onChange={(e) =>\r\n handleTimeOfDayChange(block.id, e.target.value as any)\r\n }\r\n >\r\n {timeOfDayOptions.map((t) => (\r\n <option key={t}>{t}</option>\r\n ))}\r\n </select>\r\n </div>\r\n {focusedBlockId === block.id &&\r\n showSuggestions &&\r\n locations.length > 0 && (\r\n <div\r\n role=\"listbox\"\r\n id={`suggestions-${block.id}`}\r\n className=\"absolute top-[calc(100%+6px)] left-0 min-w-[240px] z-50 bg-white border border-slate-200/80 shadow-xl shadow-slate-200/40 rounded-xl py-1 overflow-hidden animate-in fade-in zoom-in-95 duration-150\"\r\n >\r\n <div className=\"max-h-60 overflow-y-auto custom-scrollbar\">\r\n {locations\r\n .filter(\r\n (loc) =>\r\n loc.startsWith(block.text.toUpperCase()) &&\r\n loc !== block.text.toUpperCase(),\r\n )\r\n .map((loc) => (\r\n <div\r\n role=\"option\"\r\n key={loc}\r\n className=\"group flex items-center justify-between px-4 py-2.5 cursor-pointer transition-all duration-150 hover:bg-slate-50 active:bg-slate-100\"\r\n onMouseDown={(e) => {\r\n e.preventDefault();\r\n const element = refs.current[block.id];\r\n if (element) {\r\n element.innerText = loc;\r\n handleBlockTextChange(block.id, loc);\r\n element.focus();\r\n const range = document.createRange();\r\n const sel = window.getSelection();\r\n range.selectNodeContents(element);\r\n range.collapse(false);\r\n sel?.removeAllRanges();\r\n sel?.addRange(range);\r\n }\r\n handleBlur(block.id);\r\n }}\r\n >\r\n <span className=\"text-[12px] font-semibold tracking-wide text-slate-600 uppercase line-clamp-1\">\r\n {loc}\r\n </span>\r\n\r\n <ArrowRight className=\"w-3.5 h-3.5 text-slate-300 opacity-0 -translate-x-2 group-hover:opacity-100 group-hover:translate-x-0 transition-all duration-200\" />\r\n </div>\r\n ))}\r\n </div>\r\n </div>\r\n )}\r\n </>\r\n ) : (\r\n <>\r\n <div\r\n ref={(el) => {\r\n if (!el) return;\r\n refs.current[block.id] = el;\r\n }}\r\n contentEditable\r\n suppressContentEditableWarning\r\n aria-label={`${blockStyles[block.type].label} text`}\r\n aria-multiline={\r\n block.type === \"ACTION\" || block.type === \"DIALOGUE\"\r\n }\r\n spellCheck={false}\r\n className={`block outline-none w-full min-h-[2.5rem] px-4 py-2 break-words ${\r\n blockStyles[block.type].className\r\n }`}\r\n onInput={(e) =>\r\n handleBlockTextChange(\r\n block.id,\r\n (e.target as HTMLDivElement).innerText,\r\n )\r\n }\r\n onKeyDown={(e) => handleKeyDown(e, block.id, block.text)}\r\n onFocus={() => handleFocus(block.id)}\r\n onBlur={() => handleBlur(block.id)}\r\n style={blockStyles[block.type].inputStyle}\r\n ></div>\r\n {focusedBlockId === block.id &&\r\n block.type === \"CHARACTER\" &&\r\n showSuggestions &&\r\n characters.length > 0 && (\r\n <div\r\n role=\"listbox\"\r\n id={`suggestions-${block.id}`}\r\n className=\"absolute top-[calc(100%+8px)] left-1/2 -translate-x-1/2 w-72 z-50 bg-white border border-slate-200 shadow-2xl shadow-slate-200/60 rounded-xl py-2 overflow-hidden animate-in fade-in zoom-in-95 duration-200\"\r\n >\r\n <div className=\"max-h-56 overflow-y-auto custom-scrollbar\">\r\n {characters\r\n .filter(\r\n (char) =>\r\n char.startsWith(block.text.toUpperCase()) &&\r\n char !== block.text.toUpperCase(),\r\n )\r\n .map((char) => (\r\n <div\r\n role=\"option\"\r\n key={char}\r\n className=\"group flex items-center px-4 py-2.5 cursor-pointer transition-colors duration-150 hover:bg-slate-50 active:bg-slate-100\"\r\n onMouseDown={(e) => {\r\n e.preventDefault();\r\n const element = refs.current[block.id];\r\n if (element) {\r\n element.innerText = char;\r\n handleBlockTextChange(block.id, char);\r\n element.focus();\r\n const range = document.createRange();\r\n const sel = window.getSelection();\r\n range.selectNodeContents(element);\r\n range.collapse(false);\r\n sel?.removeAllRanges();\r\n sel?.addRange(range);\r\n }\r\n handleBlur(block.id);\r\n }}\r\n >\r\n <User className=\"w-3.5 h-3.5 text-slate-300 group-hover:text-sky-500 transition-colors mr-3\" />\r\n\r\n <span className=\"flex-1 text-[11px] font-bold tracking-[0.1em] text-slate-600 uppercase text-left\">\r\n {char}\r\n </span>\r\n\r\n <ChevronRight className=\"w-3 h-3 text-slate-200 opacity-0 group-hover:opacity-100 transition-all -translate-x-1 group-hover:translate-x-0\" />\r\n </div>\r\n ))}\r\n </div>\r\n </div>\r\n )}\r\n {focusedBlockId === block.id &&\r\n block.type === \"CHARACTER\" &&\r\n showExtensionSuggestions &&\r\n characterExtensions && (\r\n <div\r\n role=\"listbox\"\r\n id={`extension-suggestions-${block.id}`}\r\n className=\"absolute top-[calc(100%+8px)] left-1/2 -translate-x-1/2 w-72 z-50 bg-white border border-slate-200 shadow-2xl shadow-slate-200/60 rounded-xl py-2 overflow-hidden animate-in fade-in zoom-in-95 duration-200\"\r\n >\r\n <div className=\"max-h-56 overflow-y-auto custom-scrollbar\">\r\n {characterExtensions\r\n .filter((ext) => {\r\n const openParenIndex =\r\n block.text.lastIndexOf(\"(\");\r\n const query =\r\n openParenIndex > -1\r\n ? block.text\r\n .substring(openParenIndex + 1)\r\n .toUpperCase()\r\n : \"\";\r\n return ext.toUpperCase().includes(query);\r\n })\r\n .map((ext) => (\r\n <div\r\n role=\"option\"\r\n key={ext}\r\n className=\"group flex items-center px-4 py-2.5 cursor-pointer transition-colors duration-150 hover:bg-slate-50 active:bg-slate-100\"\r\n onMouseDown={(e) => {\r\n e.preventDefault();\r\n handleSelectCharacterExtension(ext);\r\n }}\r\n >\r\n <span className=\"flex-1 text-[11px] font-bold tracking-[0.1em] text-slate-600 uppercase text-left\">\r\n {ext}\r\n </span>\r\n <ChevronRight className=\"w-3 h-3 text-slate-200 opacity-0 group-hover:opacity-100 transition-all -translate-x-1 group-hover:translate-x-0\" />\r\n </div>\r\n ))}\r\n </div>\r\n </div>\r\n )}\r\n </>\r\n )}\r\n </div>\r\n ))}\r\n {isPageSplitEnabled && (\r\n <div className=\"absolute bottom-10 right-16 md:right-20 text-zinc-400 font-semibold text-sm select-none pointer-events-none\">\r\n {pageIndex + 1}.\r\n </div>\r\n )}\r\n </div>\r\n ))}\r\n </div>\r\n <div className=\"fixed bottom-6 right-6 flex flex-col items-end gap-4 z-50\">\r\n {onSave && (\r\n <button\r\n onClick={onSave}\r\n className=\"flex items-center justify-center gap-2 w-auto px-4 h-12 rounded-full bg-zinc-950 text-white shadow-xl shadow-zinc-900/20 border border-white/10 hover:bg-zinc-800 hover:scale-105 active:scale-95 transition-all duration-300\"\r\n aria-label=\"Save Script\"\r\n >\r\n <Save className=\"w-5 h-5\" />\r\n <span className=\"text-sm font-semibold\">Save</span>\r\n </button>\r\n )}\r\n {onSaveAsPdf && (\r\n <button\r\n onClick={onSaveAsPdf}\r\n className=\"flex items-center justify-center gap-2 w-auto px-4 h-12 rounded-full bg-zinc-950 text-white shadow-xl shadow-zinc-900/20 border border-white/10 hover:bg-zinc-800 hover:scale-105 active:scale-95 transition-all duration-300\"\r\n aria-label=\"Save Script as PDF\"\r\n >\r\n <FileDown className=\"w-5 h-5\" />\r\n <span className=\"text-sm font-semibold\">Save as PDF</span>\r\n </button>\r\n )}\r\n {isRulesOpen && (\r\n <div className=\"bg-white/80 backdrop-blur-md rounded-xl shadow-lg border border-zinc-200/50 p-4 text-xs text-zinc-700 select-none font-sans overflow-hidden transition-all duration-300 w-64 origin-bottom-right animate-in fade-in zoom-in-95\">\r\n <h4 className=\"font-bold text-zinc-800 mb-3 text-sm\">\r\n Settings & Shortcuts\r\n </h4>\r\n <div className=\"space-y-4\">\r\n <div className=\"flex items-center justify-between gap-6\">\r\n <span className=\"font-semibold text-zinc-800\">\r\n A4 Page Split\r\n </span>\r\n <button\r\n type=\"button\"\r\n role=\"switch\"\r\n aria-checked={isPageSplitEnabled}\r\n onClick={togglePageSplit}\r\n className={`${\r\n isPageSplitEnabled ? \"bg-zinc-900\" : \"bg-zinc-300\"\r\n } relative inline-flex h-5 w-9 shrink-0 cursor-pointer rounded-full border-2 border-transparent transition-colors duration-200 ease-in-out focus:outline-none`}\r\n >\r\n <span\r\n aria-hidden=\"true\"\r\n className={`${\r\n isPageSplitEnabled ? \"translate-x-4\" : \"translate-x-0\"\r\n } pointer-events-none inline-block h-4 w-4 transform rounded-full bg-white shadow ring-0 transition duration-200 ease-in-out`}\r\n />\r\n </button>\r\n </div>\r\n\r\n <div className=\"space-y-1.5 pt-3 border-t border-zinc-200/50\">\r\n <ul className=\"space-y-1.5\">\r\n <li className=\"flex items-center justify-between gap-6\">\r\n <span>New Block</span>\r\n <kbd className=\"px-2 py-1 text-xs font-semibold text-zinc-800 bg-zinc-200/70 border border-zinc-300/70 rounded-md\">\r\n Enter\r\n </kbd>\r\n </li>\r\n <li className=\"flex items-center justify-between gap-6\">\r\n <span>Delete Block</span>\r\n <kbd className=\"px-2 py-1 text-xs font-semibold text-zinc-800 bg-zinc-200/70 border border-zinc-300/70 rounded-md\">\r\n Backspace\r\n </kbd>\r\n </li>\r\n <li className=\"flex items-center justify-between gap-6\">\r\n <span>Change Type</span>\r\n <div className=\"flex items-center gap-1\">\r\n <kbd className=\"px-2 py-1 text-xs font-semibold text-zinc-800 bg-zinc-200/70 border border-zinc-300/70 rounded-md\">\r\n Ctrl\r\n </kbd>\r\n <span>+</span>\r\n <kbd className=\"px-2 py-1 text-xs font-semibold text-zinc-800 bg-zinc-200/70 border border-zinc-300/70 rounded-md\">\r\n ↑/↓\r\n </kbd>\r\n </div>\r\n </li>\r\n </ul>\r\n </div>\r\n </div>\r\n </div>\r\n )}\r\n <button\r\n onClick={() => setIsRulesOpen(!isRulesOpen)}\r\n className={`flex items-center justify-center w-12 h-12 rounded-full bg-zinc-950 text-white shadow-xl shadow-zinc-900/20 border border-white/10 hover:bg-zinc-800 hover:scale-105 active:scale-95 transition-all duration-300 ${\r\n isRulesOpen ? \"rotate-90\" : \"rotate-0\"\r\n }`}\r\n aria-label=\"Toggle Settings\"\r\n >\r\n <Cog className=\"w-5 h-5\" />\r\n </button>\r\n </div>\r\n </>\r\n );\r\n}\r\n","import { Block, BlockType, uuid } from \"../types/screenplay-editor.types\";\r\n\r\nexport function getNextBlockType(currentType: BlockType): BlockType {\r\n switch (currentType) {\r\n case \"SCENE_HEADING\":\r\n return \"ACTION\";\r\n case \"CHARACTER\":\r\n return \"PARENTHETICAL\";\r\n case \"PARENTHETICAL\":\r\n return \"DIALOGUE\";\r\n case \"DIALOGUE\":\r\n return \"CHARACTER\";\r\n case \"TRANSITION\":\r\n return \"SCENE_HEADING\";\r\n default:\r\n return \"ACTION\";\r\n }\r\n}\r\n\r\nexport function createNewBlock(type: BlockType): Block {\r\n const newBlock: Block = { id: uuid(), type, text: \"\" };\r\n if (type === \"SCENE_HEADING\") {\r\n newBlock.sceneType = \"INT.\";\r\n newBlock.timeOfDay = \"DAY\";\r\n } else if (type === \"PARENTHETICAL\") {\r\n newBlock.text = \"()\";\r\n }\r\n return newBlock;\r\n}\r\n\r\nexport function addBlockAfter(\r\n blocks: Block[],\r\n currentBlockId: string,\r\n): { newBlocks: Block[]; newBlockId: string } {\r\n const currentIndex = blocks.findIndex((b) => b.id === currentBlockId);\r\n if (currentIndex === -1) {\r\n return { newBlocks: blocks, newBlockId: \"\" };\r\n }\r\n\r\n const currentBlock = blocks[currentIndex];\r\n const nextType = getNextBlockType(currentBlock.type);\r\n const newBlock = createNewBlock(nextType);\r\n\r\n const newBlocks = [\r\n ...blocks.slice(0, currentIndex + 1),\r\n newBlock,\r\n ...blocks.slice(currentIndex + 1),\r\n ];\r\n\r\n return { newBlocks, newBlockId: newBlock.id };\r\n}\r\n\r\nexport function deleteBlock(\r\n blocks: Block[],\r\n blockIdToDelete: string,\r\n): { newBlocks: Block[]; nextFocusedId: string | null } {\r\n if (blocks.length <= 1) {\r\n return { newBlocks: blocks, nextFocusedId: blocks[0]?.id || null };\r\n }\r\n\r\n const index = blocks.findIndex((b) => b.id === blockIdToDelete);\r\n if (index === -1) {\r\n return { newBlocks: blocks, nextFocusedId: null };\r\n }\r\n\r\n const newBlocks = [...blocks];\r\n newBlocks.splice(index, 1);\r\n\r\n const nextFocusedId =\r\n newBlocks[index]?.id || newBlocks[index - 1]?.id || null;\r\n\r\n return { newBlocks, nextFocusedId };\r\n}\r\n\r\nexport function updateBlock<K extends keyof Block>(\r\n blocks: Block[],\r\n id: string,\r\n key: K,\r\n value: Block[K],\r\n): Block[] {\r\n return blocks.map((b) => (b.id === id ? { ...b, [key]: value } : b));\r\n}\r\n\r\nexport function changeBlockType(blocks: Block[], id: string, newType: BlockType) {\r\n const newBlock = createNewBlock(newType);\r\n return blocks.map((b) => (b.id === id ? { ...newBlock, id: b.id } : b));\r\n}","\"use client\";\r\nimport React, {\r\n useState,\r\n useRef,\r\n KeyboardEvent,\r\n useEffect,\r\n useMemo,\r\n useCallback,\r\n} from \"react\";\r\nimport {\r\n Block,\r\n BlockType,\r\n TimeOfDay,\r\n uuid,\r\n blockTypes,\r\n} from \"../types/screenplay-editor.types\";\r\nimport * as ScreenplayService from \"../service/screenplay-editor.service\";\r\n\r\nconst initialBlocks: Block[] = [\r\n {\r\n id: uuid(),\r\n type: \"SCENE_HEADING\",\r\n text: \"\",\r\n sceneType: \"INT.\",\r\n timeOfDay: \"DAY\",\r\n },\r\n];\r\n\r\nfunction getCaretCharacterOffsetWithin(element: HTMLElement) {\r\n let caretOffset = 0;\r\n const doc = element.ownerDocument;\r\n const win = doc.defaultView;\r\n const sel = win?.getSelection();\r\n if (sel && sel.rangeCount > 0) {\r\n const range = sel.getRangeAt(0);\r\n const preCaretRange = range.cloneRange();\r\n preCaretRange.selectNodeContents(element);\r\n preCaretRange.setEnd(range.endContainer, range.endOffset);\r\n caretOffset = preCaretRange.toString().length;\r\n }\r\n return caretOffset;\r\n}\r\n\r\nfunction setCaretPosition(element: HTMLElement, offset: number) {\r\n const sel = window.getSelection();\r\n if (!sel) return;\r\n const range = document.createRange();\r\n let currentOffset = 0;\r\n let found = false;\r\n\r\n function traverseNodes(node: Node) {\r\n if (found) return;\r\n if (node.nodeType === Node.TEXT_NODE) {\r\n const length = node.nodeValue?.length || 0;\r\n if (currentOffset + length >= offset) {\r\n range.setStart(node, offset - currentOffset);\r\n range.collapse(true);\r\n found = true;\r\n } else {\r\n currentOffset += length;\r\n }\r\n } else {\r\n for (let i = 0; i < node.childNodes.length; i++) {\r\n traverseNodes(node.childNodes[i]);\r\n if (found) break;\r\n }\r\n }\r\n }\r\n\r\n traverseNodes(element);\r\n\r\n if (!found) {\r\n range.setStart(element, 0);\r\n range.collapse(true);\r\n }\r\n\r\n sel.removeAllRanges();\r\n sel.addRange(range);\r\n}\r\n\r\nexport function useScreenplayEditor() {\r\n const [blocks, setBlocks] = useState<Block[]>(initialBlocks);\r\n const refs = useRef<Record<string, HTMLDivElement | null>>({});\r\n const [focusedBlockId, setFocusedBlockId] = useState<string>(\r\n initialBlocks[0].id,\r\n );\r\n const [newBlockId, setNewBlockId] = useState<string | null>(null);\r\n const [showSuggestions, setShowSuggestions] = useState(false);\r\n const [showExtensionSuggestions, setShowExtensionSuggestions] = useState(false);\r\n const blurTimeout = useRef<NodeJS.Timeout | null>(null);\r\n\r\n const [isPageSplitEnabled, setIsPageSplitEnabled] = useState(false);\r\n const [pageBreaks, setPageBreaks] = useState<string[]>([]);\r\n const focusStateRef = useRef<{ id: string; offset: number } | null>(null);\r\n\r\n const togglePageSplit = useCallback(() => {\r\n if (\r\n focusedBlockId &&\r\n document.activeElement &&\r\n document.activeElement.hasAttribute(\"contenteditable\")\r\n ) {\r\n const el = refs.current[focusedBlockId];\r\n if (el) {\r\n const offset = getCaretCharacterOffsetWithin(el);\r\n focusStateRef.current = { id: focusedBlockId, offset };\r\n }\r\n }\r\n setIsPageSplitEnabled((prev) => !prev);\r\n }, [focusedBlockId]);\r\n\r\n const characterExtensions = useMemo(\r\n () => [\"(V.O.)\", \"(O.S.)\", \"(O.C.)\", \"(SUBTITLE)\", \"(CONT'D)\"],\r\n [],\r\n );\r\n\r\n // Derived State\r\n const locations = useMemo(() => {\r\n const locs = blocks\r\n .filter((b) => b.type === \"SCENE_HEADING\" && b.text.trim() !== \"\")\r\n .map((b) => b.text.trim().toUpperCase());\r\n return [...new Set(locs)];\r\n }, [blocks]);\r\n\r\n const characters = useMemo(() => {\r\n const chars = blocks\r\n .filter((b) => b.type === \"CHARACTER\" && b.text.trim() !== \"\")\r\n .map((b) => {\r\n const text = b.text.trim().toUpperCase();\r\n const parenIndex = text.indexOf(\"(\");\r\n if (parenIndex > -1) {\r\n return text.substring(0, parenIndex).trim();\r\n }\r\n return text;\r\n })\r\n .filter(Boolean);\r\n return [...new Set(chars)];\r\n }, [blocks]);\r\n\r\n const sceneNumbers = useMemo(() => {\r\n const map: Record<string, number> = {};\r\n let count = 0;\r\n blocks.forEach((block) => {\r\n if (block.type === \"SCENE_HEADING\") {\r\n count++;\r\n map[block.id] = count;\r\n }\r\n });\r\n return map;\r\n }, [blocks]);\r\n\r\n // Effects\r\n useEffect(() => {\r\n if (newBlockId && refs.current[newBlockId]) {\r\n const block = blocks.find((b) => b.id === newBlockId);\r\n const el = refs.current[newBlockId];\r\n if (el && block) {\r\n el.focus();\r\n el.innerText = block.text;\r\n if (block.type === \"PARENTHETICAL\") {\r\n setTimeout(() => setCaretPosition(el, 1), 0);\r\n } else {\r\n setTimeout(() => setCaretPosition(el, block.text.length), 0);\r\n }\r\n }\r\n setFocusedBlockId(newBlockId);\r\n setNewBlockId(null);\r\n }\r\n }, [newBlockId, blocks]);\r\n\r\n useEffect(() => {\r\n blocks.forEach((block) => {\r\n const element = refs.current[block.id];\r\n if (\r\n element &&\r\n element.innerText !== block.text &&\r\n document.activeElement !== element\r\n ) {\r\n element.innerText = block.text;\r\n }\r\n });\r\n }, [blocks, isPageSplitEnabled, pageBreaks]);\r\n\r\n useEffect(() => {\r\n const handleClickOutside = (e: MouseEvent) => {\r\n // Check if the clicked element is a contentEditable block or inside the toolbar\r\n const target = e.target as HTMLElement;\r\n const isInsideBlock = target.closest(\"[data-block-id]\");\r\n const isInsideToolbar = target.closest(\".sticky\"); // Adjust selector based on your UI\r\n const isInsideSuggestions = target.closest('[role=\"listbox\"]');\r\n\r\n if (!isInsideBlock && !isInsideToolbar && !isInsideSuggestions) {\r\n setFocusedBlockId(\"\");\r\n setShowSuggestions(false);\r\n setShowExtensionSuggestions(false);\r\n }\r\n };\r\n\r\n document.addEventListener(\"mousedown\", handleClickOutside);\r\n return () => {\r\n document.removeEventListener(\"mousedown\", handleClickOutside);\r\n };\r\n }, []);\r\n\r\n useEffect(() => {\r\n if (!isPageSplitEnabled) {\r\n setPageBreaks([]);\r\n return;\r\n }\r\n\r\n const saveFocus = () => {\r\n if (\r\n focusedBlockId &&\r\n document.activeElement &&\r\n document.activeElement.hasAttribute(\"contenteditable\")\r\n ) {\r\n const el = refs.current[focusedBlockId];\r\n if (el) {\r\n const offset = getCaretCharacterOffsetWithin(el);\r\n focusStateRef.current = { id: focusedBlockId, offset };\r\n }\r\n } else {\r\n focusStateRef.current = null;\r\n }\r\n };\r\n\r\n const timeoutId = setTimeout(() => {\r\n let currentHeight = 0;\r\n let hasSceneOnCurrentPage = false;\r\n const A4_HEIGHT = 960; // Approximate content height of A4 inside padding limits\r\n const newPageBreaks: string[] = [];\r\n\r\n blocks.forEach((block) => {\r\n const el = refs.current[block.id];\r\n if (el) {\r\n const measureEl =\r\n document.querySelector(`[data-block-id=\"${block.id}\"]`) || el;\r\n const style = window.getComputedStyle(measureEl);\r\n const marginTop = parseFloat(style.marginTop) || 0;\r\n const marginBottom = parseFloat(style.marginBottom) || 0;\r\n const height =\r\n measureEl.getBoundingClientRect().height + marginTop + marginBottom;\r\n\r\n let breakPage = false;\r\n if (currentHeight + height > A4_HEIGHT) {\r\n breakPage = true;\r\n } else if (block.type === \"SCENE_HEADING\") {\r\n if (hasSceneOnCurrentPage) {\r\n breakPage = true;\r\n } else if (currentHeight > A4_HEIGHT - 120) {\r\n // Widow control for SCENE_HEADING: if near bottom, push to next page\r\n breakPage = true;\r\n }\r\n }\r\n\r\n if (breakPage && currentHeight > 0) {\r\n newPageBreaks.push(block.id);\r\n currentHeight = height;\r\n hasSceneOnCurrentPage = block.type === \"SCENE_HEADING\";\r\n } else {\r\n currentHeight += height;\r\n if (block.type === \"SCENE_HEADING\") {\r\n hasSceneOnCurrentPage = true;\r\n }\r\n }\r\n }\r\n });\r\n\r\n setPageBreaks((prev) => {\r\n if (prev.length !== newPageBreaks.length) {\r\n saveFocus();\r\n return newPageBreaks;\r\n }\r\n for (let i = 0; i < prev.length; i++) {\r\n if (prev[i] !== newPageBreaks[i]) {\r\n saveFocus();\r\n return newPageBreaks;\r\n }\r\n }\r\n return prev;\r\n });\r\n }, 300);\r\n\r\n return () => clearTimeout(timeoutId);\r\n }, [blocks, isPageSplitEnabled, focusedBlockId]);\r\n\r\n const pages = useMemo(() => {\r\n if (!isPageSplitEnabled || pageBreaks.length === 0) return [blocks];\r\n const result: Block[][] = [];\r\n let currentPage: Block[] = [];\r\n for (const block of blocks) {\r\n if (pageBreaks.includes(block.id) && currentPage.length > 0) {\r\n result.push(currentPage);\r\n currentPage = [];\r\n }\r\n currentPage.push(block);\r\n }\r\n if (currentPage.length > 0) result.push(currentPage);\r\n return result;\r\n }, [blocks, isPageSplitEnabled, pageBreaks]);\r\n\r\n useEffect(() => {\r\n if (focusStateRef.current) {\r\n const { id, offset } = focusStateRef.current;\r\n const el = refs.current[id];\r\n if (el && document.activeElement !== el) {\r\n el.focus();\r\n setCaretPosition(el, offset);\r\n }\r\n focusStateRef.current = null;\r\n }\r\n }, [pages]);\r\n\r\n // Handlers\r\n const handleBlockTextChange = useCallback(\r\n (id: string, text: string) => {\r\n const block = blocks.find((b) => b.id === id);\r\n if (!block) return;\r\n\r\n if (block.type === \"CHARACTER\") {\r\n const trimmedText = text.trim();\r\n const openParenIndex = trimmedText.lastIndexOf(\"(\");\r\n const closeParenIndex = trimmedText.lastIndexOf(\")\");\r\n\r\n if (openParenIndex !== -1 && openParenIndex > closeParenIndex) {\r\n setShowExtensionSuggestions(true);\r\n setShowSuggestions(false);\r\n } else {\r\n setShowExtensionSuggestions(false);\r\n setShowSuggestions(openParenIndex === -1);\r\n }\r\n } else if (showExtensionSuggestions) {\r\n setShowExtensionSuggestions(false);\r\n }\r\n\r\n let processedText = text;\r\n if (block.type === \"PARENTHETICAL\") {\r\n const clean = text.replace(/[()]/g, \"\");\r\n processedText = `(${clean})`;\r\n }\r\n\r\n setBlocks((bs) =>\r\n ScreenplayService.updateBlock(bs, id, \"text\", processedText),\r\n );\r\n\r\n if (text !== processedText) {\r\n const el = refs.current[id];\r\n if (el) {\r\n const offset = getCaretCharacterOffsetWithin(el);\r\n const charsBeforeCaret = text.substring(0, offset).replace(/[()]/g, \"\").length;\r\n const newOffset = 1 + charsBeforeCaret;\r\n el.innerText = processedText;\r\n setCaretPosition(el, newOffset);\r\n }\r\n }\r\n },\r\n [blocks, showExtensionSuggestions],\r\n );\r\n\r\n const handleSceneTypeChange = useCallback(\r\n (id: string, sceneType: \"INT.\" | \"EXT.\" | \"INT/EXT.\") => {\r\n setBlocks((bs) =>\r\n ScreenplayService.updateBlock(bs, id, \"sceneType\", sceneType),\r\n );\r\n setTimeout(() => {\r\n refs.current[id]?.focus();\r\n setFocusedBlockId(id);\r\n }, 10);\r\n },\r\n [],\r\n );\r\n\r\n const handleTimeOfDayChange = useCallback((id: string, time: TimeOfDay) => {\r\n setBlocks((bs) => ScreenplayService.updateBlock(bs, id, \"timeOfDay\", time));\r\n setTimeout(() => {\r\n refs.current[id]?.focus();\r\n setFocusedBlockId(id);\r\n }, 10);\r\n }, []);\r\n\r\n const handleBlockTypeChange = useCallback(\r\n (newType: BlockType) => {\r\n if (!focusedBlockId) return;\r\n setBlocks((bs) =>\r\n ScreenplayService.changeBlockType(bs, focusedBlockId, newType),\r\n );\r\n\r\n setTimeout(() => {\r\n const el = refs.current[focusedBlockId];\r\n if (el) {\r\n el.focus();\r\n const newBlock = ScreenplayService.createNewBlock(newType);\r\n el.innerText = newBlock.text;\r\n if (newType === \"PARENTHETICAL\") {\r\n setCaretPosition(el, 1);\r\n } else {\r\n setCaretPosition(el, newBlock.text.length);\r\n }\r\n }\r\n }, 0);\r\n },\r\n [focusedBlockId],\r\n );\r\n\r\n const handleSelectCharacterExtension = useCallback(\r\n (extension: string) => {\r\n if (!focusedBlockId) return;\r\n\r\n setBlocks((currentBlocks) => {\r\n const block = currentBlocks.find((b) => b.id === focusedBlockId);\r\n if (!block || block.type !== \"CHARACTER\") return currentBlocks;\r\n\r\n const parenIndex = block.text.indexOf(\"(\");\r\n const baseText = (\r\n parenIndex > -1\r\n ? block.text.substring(0, parenIndex)\r\n : block.text\r\n ).trim();\r\n const newText = `${baseText} ${extension}`;\r\n\r\n const newBlocks = ScreenplayService.updateBlock(\r\n currentBlocks,\r\n focusedBlockId,\r\n \"text\",\r\n newText,\r\n );\r\n\r\n setTimeout(() => {\r\n const el = refs.current[focusedBlockId];\r\n if (el) {\r\n el.innerText = newText;\r\n el.focus();\r\n setCaretPosition(el, newText.length);\r\n }\r\n }, 0);\r\n return newBlocks;\r\n });\r\n setShowExtensionSuggestions(false);\r\n },\r\n [focusedBlockId],\r\n );\r\n\r\n const focusBlock = (id: string, position: \"start\" | \"end\" = \"start\") => {\r\n const el = refs.current[id];\r\n if (!el) return;\r\n\r\n el.focus();\r\n\r\n const range = document.createRange();\r\n const sel = window.getSelection();\r\n if (!sel) return;\r\n\r\n range.selectNodeContents(el);\r\n range.collapse(position === \"start\");\r\n\r\n sel.removeAllRanges();\r\n sel.addRange(range);\r\n };\r\n\r\n const cycleBlockType = (id: string, direction: \"up\" | \"down\") => {\r\n const block = blocks.find((b) => b.id === id);\r\n if (!block) return;\r\n\r\n const idx = blockTypes.indexOf(block.type);\r\n let newIdx = direction === \"up\" ? idx - 1 : idx + 1;\r\n if (newIdx < 0) newIdx = blockTypes.length - 1;\r\n if (newIdx >= blockTypes.length) newIdx = 0;\r\n\r\n const newType = blockTypes[newIdx];\r\n\r\n setBlocks((bs) => ScreenplayService.changeBlockType(bs, id, newType));\r\n\r\n // Handle the DOM and Caret after the state update\r\n setTimeout(() => {\r\n const el = refs.current[id];\r\n if (el) {\r\n el.focus();\r\n const newBlock = ScreenplayService.createNewBlock(newType);\r\n el.innerText = newBlock.text;\r\n if (newType === \"PARENTHETICAL\") {\r\n setCaretPosition(el, 1);\r\n } else {\r\n setCaretPosition(el, el.innerText.length);\r\n }\r\n }\r\n }, 10);\r\n };\r\n\r\n const handleKeyDown = useCallback(\r\n (e: KeyboardEvent<HTMLDivElement>, id: string, text: string) => {\r\n const block = blocks.find((b) => b.id === id);\r\n\r\n if (block?.type === \"PARENTHETICAL\") {\r\n const offset = getCaretCharacterOffsetWithin(e.currentTarget);\r\n\r\n if (e.key === \"Backspace\" && (offset <= 1 || text === \"()\")) {\r\n e.preventDefault();\r\n cycleBlockType(id, \"up\");\r\n return;\r\n }\r\n if (e.key === \"Delete\" && (offset >= text.length - 1 || text === \"()\")) {\r\n e.preventDefault();\r\n return;\r\n }\r\n }\r\n\r\n if ((e.key === \"Backspace\" || e.key === \"Delete\") && text.length <= 1) {\r\n e.preventDefault();\r\n const { newBlocks, nextFocusedId } = ScreenplayService.deleteBlock(\r\n blocks,\r\n id,\r\n );\r\n setBlocks(newBlocks);\r\n if (nextFocusedId) {\r\n setTimeout(() => {\r\n focusBlock(nextFocusedId, \"end\");\r\n }, 0);\r\n }\r\n return;\r\n }\r\n\r\n if (e.key === \"Enter\" && !e.shiftKey) {\r\n e.preventDefault();\r\n const { newBlocks, newBlockId } = ScreenplayService.addBlockAfter(\r\n blocks,\r\n id,\r\n );\r\n setBlocks(newBlocks);\r\n setNewBlockId(newBlockId);\r\n } else if (e.key === \"ArrowUp\" && e.ctrlKey) {\r\n e.preventDefault();\r\n cycleBlockType(id, \"up\");\r\n } else if (e.key === \"ArrowDown\" && e.ctrlKey) {\r\n e.preventDefault();\r\n cycleBlockType(id, \"down\");\r\n } else if (e.key === \"ArrowUp\" && !e.ctrlKey) {\r\n const selection = window.getSelection();\r\n if (\r\n !selection ||\r\n !selection.isCollapsed ||\r\n selection.rangeCount === 0\r\n ) {\r\n return;\r\n }\r\n\r\n const range = selection.getRangeAt(0);\r\n const contentEditable = e.currentTarget as HTMLDivElement;\r\n\r\n let atStart = false;\r\n if (range.startOffset === 0) {\r\n let node = range.startContainer;\r\n if (node === contentEditable) {\r\n atStart = true;\r\n } else {\r\n let atStartOfParents = true;\r\n while (node !== contentEditable) {\r\n if (node.previousSibling) {\r\n atStartOfParents = false;\r\n break;\r\n }\r\n node = node.parentNode!;\r\n if (!node) {\r\n atStartOfParents = false;\r\n break;\r\n }\r\n }\r\n atStart = atStartOfParents;\r\n }\r\n }\r\n\r\n if (atStart) {\r\n e.preventDefault();\r\n const currentIndex = blocks.findIndex((b) => b.id === id);\r\n if (currentIndex > 0) {\r\n const prevBlockId = blocks[currentIndex - 1].id;\r\n focusBlock(prevBlockId, \"end\");\r\n }\r\n }\r\n } else if (e.key === \"ArrowDown\" && !e.ctrlKey) {\r\n const selection = window.getSelection();\r\n if (\r\n !selection ||\r\n !selection.isCollapsed ||\r\n selection.rangeCount === 0\r\n ) {\r\n return;\r\n }\r\n\r\n const range = selection.getRangeAt(0);\r\n const contentEditable = e.currentTarget as HTMLDivElement;\r\n const container = range.endContainer;\r\n\r\n const isAtEndOffset =\r\n range.endOffset ===\r\n (container.nodeType === Node.TEXT_NODE\r\n ? container.textContent?.length\r\n : container.childNodes.length);\r\n\r\n if (isAtEndOffset) {\r\n let atEnd = false;\r\n let node = container;\r\n if (node === contentEditable) {\r\n atEnd = true;\r\n } else {\r\n let atEndOfParents = true;\r\n while (node !== contentEditable) {\r\n if (node.nextSibling) {\r\n atEndOfParents = false;\r\n break;\r\n }\r\n node = node.parentNode!;\r\n if (!node) {\r\n atEndOfParents = false;\r\n break;\r\n }\r\n }\r\n atEnd = atEndOfParents;\r\n }\r\n\r\n if (atEnd) {\r\n e.preventDefault();\r\n const currentIndex = blocks.findIndex((b) => b.id === id);\r\n if (currentIndex < blocks.length - 1) {\r\n const nextBlockId = blocks[currentIndex + 1].id;\r\n focusBlock(nextBlockId, \"start\");\r\n }\r\n }\r\n }\r\n }\r\n },\r\n [blocks, handleBlockTextChange],\r\n );\r\n\r\n const handleFocus = useCallback((id: string) => {\r\n if (blurTimeout.current) {\r\n clearTimeout(blurTimeout.current);\r\n }\r\n setFocusedBlockId(id);\r\n const block = blocks.find((b) => b.id === id);\r\n if (block?.type === \"CHARACTER\") {\r\n const trimmedText = block.text.trim();\r\n const openParenIndex = trimmedText.lastIndexOf(\"(\");\r\n const closeParenIndex = trimmedText.lastIndexOf(\")\");\r\n\r\n if (openParenIndex !== -1 && openParenIndex > closeParenIndex) {\r\n setShowExtensionSuggestions(true);\r\n setShowSuggestions(false);\r\n } else {\r\n setShowExtensionSuggestions(false);\r\n setShowSuggestions(openParenIndex === -1);\r\n }\r\n } else {\r\n setShowSuggestions(true);\r\n setShowExtensionSuggestions(false);\r\n }\r\n }, [blocks]);\r\n\r\n const handleBlur = useCallback((id: string) => {\r\n if (document.activeElement === refs.current[id]) return;\r\n blurTimeout.current = setTimeout(() => {\r\n setShowSuggestions(false);\r\n setShowExtensionSuggestions(false);\r\n }, 200);\r\n }, []);\r\n\r\n return {\r\n blocks,\r\n pages,\r\n isPageSplitEnabled,\r\n togglePageSplit,\r\n refs,\r\n focusedBlockId,\r\n showSuggestions,\r\n showExtensionSuggestions,\r\n characterExtensions,\r\n locations,\r\n characters,\r\n sceneNumbers,\r\n handleBlockTextChange,\r\n handleSceneTypeChange,\r\n handleTimeOfDayChange,\r\n handleBlockTypeChange,\r\n handleSelectCharacterExtension,\r\n handleKeyDown,\r\n handleFocus,\r\n handleBlur,\r\n };\r\n}\r\n"]}