@vishu1301/script-writing 0.3.7 → 0.3.9
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.cjs +117 -33
- package/dist/index.cjs.map +1 -1
- package/dist/index.js +117 -33
- package/dist/index.js.map +1 -1
- package/package.json +4 -3
package/dist/index.cjs
CHANGED
|
@@ -48,6 +48,7 @@ var blockStyles = {
|
|
|
48
48
|
inputStyle: {
|
|
49
49
|
textTransform: "uppercase",
|
|
50
50
|
fontWeight: 700,
|
|
51
|
+
maxWidth: "6.0in",
|
|
51
52
|
outline: "none",
|
|
52
53
|
whiteSpace: "pre-wrap",
|
|
53
54
|
overflowWrap: "break-word",
|
|
@@ -56,21 +57,24 @@ var blockStyles = {
|
|
|
56
57
|
},
|
|
57
58
|
ACTION: {
|
|
58
59
|
label: "Action",
|
|
59
|
-
className: "text-zinc-800
|
|
60
|
+
className: "text-zinc-800",
|
|
60
61
|
inputStyle: {
|
|
62
|
+
maxWidth: "6.0in",
|
|
61
63
|
outline: "none",
|
|
62
64
|
whiteSpace: "pre-wrap",
|
|
63
65
|
overflowWrap: "break-word",
|
|
64
66
|
wordBreak: "break-word",
|
|
65
|
-
lineHeight:
|
|
67
|
+
lineHeight: "12pt"
|
|
66
68
|
}
|
|
67
69
|
},
|
|
68
70
|
CHARACTER: {
|
|
69
71
|
label: "Character",
|
|
70
|
-
className: "uppercase font-bold text-
|
|
72
|
+
className: "uppercase font-bold text-zinc-900 tracking-widest",
|
|
71
73
|
inputStyle: {
|
|
72
74
|
textTransform: "uppercase",
|
|
73
|
-
textAlign: "
|
|
75
|
+
textAlign: "left",
|
|
76
|
+
marginLeft: "2.0in",
|
|
77
|
+
maxWidth: "4.0in",
|
|
74
78
|
fontWeight: 700,
|
|
75
79
|
letterSpacing: "0.1em",
|
|
76
80
|
outline: "none",
|
|
@@ -81,37 +85,39 @@ var blockStyles = {
|
|
|
81
85
|
},
|
|
82
86
|
PARENTHETICAL: {
|
|
83
87
|
label: "Parenthetical",
|
|
84
|
-
className: "text-
|
|
88
|
+
className: "text-zinc-600",
|
|
85
89
|
inputStyle: {
|
|
86
90
|
fontStyle: "normal",
|
|
87
|
-
maxWidth: "
|
|
88
|
-
|
|
91
|
+
maxWidth: "3.0in",
|
|
92
|
+
marginLeft: "1.5in",
|
|
93
|
+
textTransform: "lowercase",
|
|
89
94
|
outline: "none",
|
|
90
95
|
whiteSpace: "pre-wrap",
|
|
91
96
|
overflowWrap: "break-word",
|
|
92
97
|
wordBreak: "break-word",
|
|
93
|
-
textAlign: "
|
|
98
|
+
textAlign: "left"
|
|
94
99
|
}
|
|
95
100
|
},
|
|
96
101
|
DIALOGUE: {
|
|
97
102
|
label: "Dialogue",
|
|
98
|
-
className: "text-zinc-900
|
|
103
|
+
className: "text-zinc-900",
|
|
99
104
|
inputStyle: {
|
|
100
|
-
marginLeft: "
|
|
101
|
-
|
|
105
|
+
marginLeft: "1.0in",
|
|
106
|
+
maxWidth: "3.5in",
|
|
102
107
|
outline: "none",
|
|
103
108
|
whiteSpace: "pre-wrap",
|
|
104
109
|
overflowWrap: "break-word",
|
|
105
110
|
wordBreak: "break-word",
|
|
106
111
|
fontSize: "1.05rem",
|
|
107
112
|
textAlign: "left",
|
|
108
|
-
lineHeight:
|
|
113
|
+
lineHeight: "12pt"
|
|
109
114
|
}
|
|
110
115
|
},
|
|
111
116
|
TRANSITION: {
|
|
112
117
|
label: "Transition",
|
|
113
118
|
className: "uppercase font-bold text-right text-zinc-900",
|
|
114
119
|
inputStyle: {
|
|
120
|
+
marginLeft: "4.0in",
|
|
115
121
|
textTransform: "uppercase",
|
|
116
122
|
fontWeight: 600,
|
|
117
123
|
textAlign: "right",
|
|
@@ -187,7 +193,7 @@ function ScreenplayEditorView({
|
|
|
187
193
|
/* @__PURE__ */ jsxRuntime.jsx("div", { className: "flex flex-col gap-12 w-full items-center pb-24", children: pages.map((pageBlocks, pageIndex) => /* @__PURE__ */ jsxRuntime.jsxs(
|
|
188
194
|
"div",
|
|
189
195
|
{
|
|
190
|
-
className: "relative bg-[#fdfdfc] shadow-2xl shadow-zinc-300/60 ring-1 ring-zinc-200/50 rounded-sm md:rounded-md
|
|
196
|
+
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",
|
|
191
197
|
style: {
|
|
192
198
|
fontFamily: "var(--font-courier-prime, 'Courier New', Courier, monospace)"
|
|
193
199
|
},
|
|
@@ -229,7 +235,7 @@ function ScreenplayEditorView({
|
|
|
229
235
|
"aria-haspopup": "listbox",
|
|
230
236
|
"aria-expanded": focusedBlockId === block.id && showSuggestions && locations.length > 0,
|
|
231
237
|
spellCheck: false,
|
|
232
|
-
className: "min-w-[
|
|
238
|
+
className: "min-w-[3rem] py-1 outline-none text-base font-bold uppercase tracking-widest break-all bg-transparent",
|
|
233
239
|
onInput: (e) => handleBlockTextChange(
|
|
234
240
|
block.id,
|
|
235
241
|
e.target.innerText
|
|
@@ -468,6 +474,8 @@ function createNewBlock(type) {
|
|
|
468
474
|
if (type === "SCENE_HEADING") {
|
|
469
475
|
newBlock.sceneType = "INT.";
|
|
470
476
|
newBlock.timeOfDay = "DAY";
|
|
477
|
+
} else if (type === "PARENTHETICAL") {
|
|
478
|
+
newBlock.text = "()";
|
|
471
479
|
}
|
|
472
480
|
return newBlock;
|
|
473
481
|
}
|
|
@@ -607,13 +615,22 @@ function useScreenplayEditor() {
|
|
|
607
615
|
return map;
|
|
608
616
|
}, [blocks]);
|
|
609
617
|
react.useEffect(() => {
|
|
610
|
-
var _a;
|
|
611
618
|
if (newBlockId && refs.current[newBlockId]) {
|
|
612
|
-
|
|
619
|
+
const block = blocks.find((b) => b.id === newBlockId);
|
|
620
|
+
const el = refs.current[newBlockId];
|
|
621
|
+
if (el && block) {
|
|
622
|
+
el.focus();
|
|
623
|
+
el.innerText = block.text;
|
|
624
|
+
if (block.type === "PARENTHETICAL") {
|
|
625
|
+
setTimeout(() => setCaretPosition(el, 1), 0);
|
|
626
|
+
} else {
|
|
627
|
+
setTimeout(() => setCaretPosition(el, block.text.length), 0);
|
|
628
|
+
}
|
|
629
|
+
}
|
|
613
630
|
setFocusedBlockId(newBlockId);
|
|
614
631
|
setNewBlockId(null);
|
|
615
632
|
}
|
|
616
|
-
}, [newBlockId]);
|
|
633
|
+
}, [newBlockId, blocks]);
|
|
617
634
|
react.useEffect(() => {
|
|
618
635
|
blocks.forEach((block) => {
|
|
619
636
|
const element = refs.current[block.id];
|
|
@@ -622,6 +639,22 @@ function useScreenplayEditor() {
|
|
|
622
639
|
}
|
|
623
640
|
});
|
|
624
641
|
}, [blocks, isPageSplitEnabled, pageBreaks]);
|
|
642
|
+
react.useEffect(() => {
|
|
643
|
+
const handleClickOutside = (e) => {
|
|
644
|
+
const target = e.target;
|
|
645
|
+
const isInsideBlock = target.closest("[data-block-id]");
|
|
646
|
+
const isInsideToolbar = target.closest(".sticky");
|
|
647
|
+
const isInsideSuggestions = target.closest('[role="listbox"]');
|
|
648
|
+
if (!isInsideBlock && !isInsideToolbar && !isInsideSuggestions) {
|
|
649
|
+
setFocusedBlockId("");
|
|
650
|
+
setShowSuggestions(false);
|
|
651
|
+
}
|
|
652
|
+
};
|
|
653
|
+
document.addEventListener("mousedown", handleClickOutside);
|
|
654
|
+
return () => {
|
|
655
|
+
document.removeEventListener("mousedown", handleClickOutside);
|
|
656
|
+
};
|
|
657
|
+
}, []);
|
|
625
658
|
react.useEffect(() => {
|
|
626
659
|
if (!isPageSplitEnabled) {
|
|
627
660
|
setPageBreaks([]);
|
|
@@ -714,9 +747,31 @@ function useScreenplayEditor() {
|
|
|
714
747
|
focusStateRef.current = null;
|
|
715
748
|
}
|
|
716
749
|
}, [pages]);
|
|
717
|
-
const handleBlockTextChange = react.useCallback(
|
|
718
|
-
|
|
719
|
-
|
|
750
|
+
const handleBlockTextChange = react.useCallback(
|
|
751
|
+
(id, text) => {
|
|
752
|
+
const block = blocks.find((b) => b.id === id);
|
|
753
|
+
if (!block) return;
|
|
754
|
+
let processedText = text;
|
|
755
|
+
if (block.type === "PARENTHETICAL") {
|
|
756
|
+
const clean = text.replace(/[()]/g, "");
|
|
757
|
+
processedText = `(${clean})`;
|
|
758
|
+
}
|
|
759
|
+
setBlocks(
|
|
760
|
+
(bs) => updateBlock(bs, id, "text", processedText)
|
|
761
|
+
);
|
|
762
|
+
if (text !== processedText) {
|
|
763
|
+
const el = refs.current[id];
|
|
764
|
+
if (el) {
|
|
765
|
+
const offset = getCaretCharacterOffsetWithin(el);
|
|
766
|
+
const charsBeforeCaret = text.substring(0, offset).replace(/[()]/g, "").length;
|
|
767
|
+
const newOffset = 1 + charsBeforeCaret;
|
|
768
|
+
el.innerText = processedText;
|
|
769
|
+
setCaretPosition(el, newOffset);
|
|
770
|
+
}
|
|
771
|
+
}
|
|
772
|
+
},
|
|
773
|
+
[blocks]
|
|
774
|
+
);
|
|
720
775
|
const handleSceneTypeChange = react.useCallback(
|
|
721
776
|
(id, sceneType) => {
|
|
722
777
|
setBlocks(
|
|
@@ -747,8 +802,14 @@ function useScreenplayEditor() {
|
|
|
747
802
|
setTimeout(() => {
|
|
748
803
|
const el = refs.current[focusedBlockId];
|
|
749
804
|
if (el) {
|
|
750
|
-
el.innerText = "";
|
|
751
805
|
el.focus();
|
|
806
|
+
const newBlock = createNewBlock(newType);
|
|
807
|
+
el.innerText = newBlock.text;
|
|
808
|
+
if (newType === "PARENTHETICAL") {
|
|
809
|
+
setCaretPosition(el, 1);
|
|
810
|
+
} else {
|
|
811
|
+
setCaretPosition(el, newBlock.text.length);
|
|
812
|
+
}
|
|
752
813
|
}
|
|
753
814
|
}, 0);
|
|
754
815
|
},
|
|
@@ -767,19 +828,44 @@ function useScreenplayEditor() {
|
|
|
767
828
|
sel.addRange(range);
|
|
768
829
|
};
|
|
769
830
|
const cycleBlockType = (id, direction) => {
|
|
770
|
-
|
|
771
|
-
|
|
772
|
-
|
|
773
|
-
|
|
774
|
-
|
|
775
|
-
|
|
776
|
-
|
|
777
|
-
|
|
778
|
-
|
|
831
|
+
const block = blocks.find((b) => b.id === id);
|
|
832
|
+
if (!block) return;
|
|
833
|
+
const idx = blockTypes.indexOf(block.type);
|
|
834
|
+
let newIdx = direction === "up" ? idx - 1 : idx + 1;
|
|
835
|
+
if (newIdx < 0) newIdx = blockTypes.length - 1;
|
|
836
|
+
if (newIdx >= blockTypes.length) newIdx = 0;
|
|
837
|
+
const newType = blockTypes[newIdx];
|
|
838
|
+
setBlocks((bs) => changeBlockType(bs, id, newType));
|
|
839
|
+
setTimeout(() => {
|
|
840
|
+
const el = refs.current[id];
|
|
841
|
+
if (el) {
|
|
842
|
+
el.focus();
|
|
843
|
+
const newBlock = createNewBlock(newType);
|
|
844
|
+
el.innerText = newBlock.text;
|
|
845
|
+
if (newType === "PARENTHETICAL") {
|
|
846
|
+
setCaretPosition(el, 1);
|
|
847
|
+
} else {
|
|
848
|
+
setCaretPosition(el, el.innerText.length);
|
|
849
|
+
}
|
|
850
|
+
}
|
|
851
|
+
}, 10);
|
|
779
852
|
};
|
|
780
853
|
const handleKeyDown = react.useCallback(
|
|
781
854
|
(e, id, text) => {
|
|
782
855
|
var _a;
|
|
856
|
+
const block = blocks.find((b) => b.id === id);
|
|
857
|
+
if ((block == null ? void 0 : block.type) === "PARENTHETICAL") {
|
|
858
|
+
const offset = getCaretCharacterOffsetWithin(e.currentTarget);
|
|
859
|
+
if (e.key === "Backspace" && (offset <= 1 || text === "()")) {
|
|
860
|
+
e.preventDefault();
|
|
861
|
+
cycleBlockType(id, "up");
|
|
862
|
+
return;
|
|
863
|
+
}
|
|
864
|
+
if (e.key === "Delete" && (offset >= text.length - 1 || text === "()")) {
|
|
865
|
+
e.preventDefault();
|
|
866
|
+
return;
|
|
867
|
+
}
|
|
868
|
+
}
|
|
783
869
|
if ((e.key === "Backspace" || e.key === "Delete") && text.length <= 1) {
|
|
784
870
|
e.preventDefault();
|
|
785
871
|
const { newBlocks, nextFocusedId } = deleteBlock(
|
|
@@ -805,11 +891,9 @@ function useScreenplayEditor() {
|
|
|
805
891
|
} else if (e.key === "ArrowUp" && e.ctrlKey) {
|
|
806
892
|
e.preventDefault();
|
|
807
893
|
cycleBlockType(id, "up");
|
|
808
|
-
requestAnimationFrame(() => focusBlock(id));
|
|
809
894
|
} else if (e.key === "ArrowDown" && e.ctrlKey) {
|
|
810
895
|
e.preventDefault();
|
|
811
896
|
cycleBlockType(id, "down");
|
|
812
|
-
requestAnimationFrame(() => focusBlock(id));
|
|
813
897
|
} else if (e.key === "ArrowUp" && !e.ctrlKey) {
|
|
814
898
|
const selection = window.getSelection();
|
|
815
899
|
if (!selection || !selection.isCollapsed || selection.rangeCount === 0) {
|
|
@@ -886,7 +970,7 @@ function useScreenplayEditor() {
|
|
|
886
970
|
}
|
|
887
971
|
}
|
|
888
972
|
},
|
|
889
|
-
[blocks]
|
|
973
|
+
[blocks, handleBlockTextChange]
|
|
890
974
|
);
|
|
891
975
|
const handleFocus = react.useCallback((id) => {
|
|
892
976
|
if (blurTimeout.current) {
|