@vishu1301/script-writing 0.3.4 → 0.3.6
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/index.cjs +109 -148
- package/dist/index.cjs.map +1 -1
- package/dist/index.js +55 -92
- package/dist/index.js.map +1 -1
- package/package.json +1 -2
package/dist/index.cjs
CHANGED
|
@@ -1,10 +1,12 @@
|
|
|
1
|
-
|
|
2
|
-
|
|
1
|
+
'use strict';
|
|
2
|
+
|
|
3
|
+
var react = require('react');
|
|
4
|
+
var lucideReact = require('lucide-react');
|
|
5
|
+
var jsxRuntime = require('react/jsx-runtime');
|
|
6
|
+
|
|
3
7
|
var __defProp = Object.defineProperty;
|
|
4
8
|
var __defProps = Object.defineProperties;
|
|
5
|
-
var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
|
|
6
9
|
var __getOwnPropDescs = Object.getOwnPropertyDescriptors;
|
|
7
|
-
var __getOwnPropNames = Object.getOwnPropertyNames;
|
|
8
10
|
var __getOwnPropSymbols = Object.getOwnPropertySymbols;
|
|
9
11
|
var __hasOwnProp = Object.prototype.hasOwnProperty;
|
|
10
12
|
var __propIsEnum = Object.prototype.propertyIsEnumerable;
|
|
@@ -21,39 +23,6 @@ var __spreadValues = (a, b) => {
|
|
|
21
23
|
return a;
|
|
22
24
|
};
|
|
23
25
|
var __spreadProps = (a, b) => __defProps(a, __getOwnPropDescs(b));
|
|
24
|
-
var __export = (target, all) => {
|
|
25
|
-
for (var name in all)
|
|
26
|
-
__defProp(target, name, { get: all[name], enumerable: true });
|
|
27
|
-
};
|
|
28
|
-
var __copyProps = (to, from, except, desc) => {
|
|
29
|
-
if (from && typeof from === "object" || typeof from === "function") {
|
|
30
|
-
for (let key of __getOwnPropNames(from))
|
|
31
|
-
if (!__hasOwnProp.call(to, key) && key !== except)
|
|
32
|
-
__defProp(to, key, { get: () => from[key], enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable });
|
|
33
|
-
}
|
|
34
|
-
return to;
|
|
35
|
-
};
|
|
36
|
-
var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod);
|
|
37
|
-
|
|
38
|
-
// app/index.ts
|
|
39
|
-
var index_exports = {};
|
|
40
|
-
__export(index_exports, {
|
|
41
|
-
ScreenplayEditorView: () => ScreenplayEditorView,
|
|
42
|
-
blockStyles: () => blockStyles,
|
|
43
|
-
blockTypes: () => blockTypes,
|
|
44
|
-
icons: () => icons,
|
|
45
|
-
timeOfDayOptions: () => timeOfDayOptions,
|
|
46
|
-
useScreenplayEditor: () => useScreenplayEditor,
|
|
47
|
-
uuid: () => uuid
|
|
48
|
-
});
|
|
49
|
-
module.exports = __toCommonJS(index_exports);
|
|
50
|
-
|
|
51
|
-
// app/view/screenplay-editor.view.tsx
|
|
52
|
-
var import_react = require("react");
|
|
53
|
-
|
|
54
|
-
// app/types/screenplay-editor.types.tsx
|
|
55
|
-
var import_lucide_react = require("lucide-react");
|
|
56
|
-
var import_jsx_runtime = require("react/jsx-runtime");
|
|
57
26
|
var timeOfDayOptions = ["DAY", "NIGHT"];
|
|
58
27
|
var blockTypes = [
|
|
59
28
|
"SCENE_HEADING",
|
|
@@ -65,12 +34,12 @@ var blockTypes = [
|
|
|
65
34
|
];
|
|
66
35
|
var uuid = () => Math.random().toString(36).slice(2, 9);
|
|
67
36
|
var icons = {
|
|
68
|
-
SCENE_HEADING: /* @__PURE__ */
|
|
69
|
-
ACTION: /* @__PURE__ */
|
|
70
|
-
CHARACTER: /* @__PURE__ */
|
|
71
|
-
PARENTHETICAL: /* @__PURE__ */
|
|
72
|
-
DIALOGUE: /* @__PURE__ */
|
|
73
|
-
TRANSITION: /* @__PURE__ */
|
|
37
|
+
SCENE_HEADING: /* @__PURE__ */ jsxRuntime.jsx(lucideReact.Clapperboard, { className: "w-5 h-5" }),
|
|
38
|
+
ACTION: /* @__PURE__ */ jsxRuntime.jsx(lucideReact.Sparkles, { className: "w-5 h-5" }),
|
|
39
|
+
CHARACTER: /* @__PURE__ */ jsxRuntime.jsx(lucideReact.UserRound, { className: "w-5 h-5" }),
|
|
40
|
+
PARENTHETICAL: /* @__PURE__ */ jsxRuntime.jsx(lucideReact.Brackets, { className: "w-5 h-5" }),
|
|
41
|
+
DIALOGUE: /* @__PURE__ */ jsxRuntime.jsx(lucideReact.MessageCircle, { className: "w-5 h-5" }),
|
|
42
|
+
TRANSITION: /* @__PURE__ */ jsxRuntime.jsx(lucideReact.ArrowRightLeft, { className: "w-5 h-5" })
|
|
74
43
|
};
|
|
75
44
|
var blockStyles = {
|
|
76
45
|
SCENE_HEADING: {
|
|
@@ -153,10 +122,6 @@ var blockStyles = {
|
|
|
153
122
|
}
|
|
154
123
|
}
|
|
155
124
|
};
|
|
156
|
-
|
|
157
|
-
// app/view/screenplay-editor.view.tsx
|
|
158
|
-
var import_lucide_react2 = require("lucide-react");
|
|
159
|
-
var import_jsx_runtime2 = require("react/jsx-runtime");
|
|
160
125
|
function ScreenplayEditorView({
|
|
161
126
|
blocks,
|
|
162
127
|
pages,
|
|
@@ -179,19 +144,19 @@ function ScreenplayEditorView({
|
|
|
179
144
|
onSaveAsPdf,
|
|
180
145
|
onSyncWithCloud
|
|
181
146
|
}) {
|
|
182
|
-
const [isRulesOpen, setIsRulesOpen] =
|
|
183
|
-
return /* @__PURE__ */
|
|
184
|
-
/* @__PURE__ */
|
|
147
|
+
const [isRulesOpen, setIsRulesOpen] = react.useState(false);
|
|
148
|
+
return /* @__PURE__ */ jsxRuntime.jsxs(jsxRuntime.Fragment, { children: [
|
|
149
|
+
/* @__PURE__ */ jsxRuntime.jsx("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", children: blockTypes.map((type) => {
|
|
185
150
|
var _a;
|
|
186
151
|
const selected = ((_a = blocks.find((b) => b.id === focusedBlockId)) == null ? void 0 : _a.type) === type;
|
|
187
|
-
return /* @__PURE__ */
|
|
152
|
+
return /* @__PURE__ */ jsxRuntime.jsxs(
|
|
188
153
|
"button",
|
|
189
154
|
{
|
|
190
155
|
type: "button",
|
|
191
156
|
className: `flex items-center gap-2 px-4 py-2.5 rounded-full font-medium text-sm transition-all duration-300 ${selected ? "bg-zinc-900 text-white shadow-sm" : "text-zinc-400 hover:bg-zinc-800/10 hover:text-zinc-800"}`,
|
|
192
157
|
onClick: () => handleBlockTypeChange(type),
|
|
193
158
|
children: [
|
|
194
|
-
/* @__PURE__ */
|
|
159
|
+
/* @__PURE__ */ jsxRuntime.jsx(
|
|
195
160
|
"input",
|
|
196
161
|
{
|
|
197
162
|
type: "radio",
|
|
@@ -203,14 +168,14 @@ function ScreenplayEditorView({
|
|
|
203
168
|
readOnly: true
|
|
204
169
|
}
|
|
205
170
|
),
|
|
206
|
-
/* @__PURE__ */
|
|
171
|
+
/* @__PURE__ */ jsxRuntime.jsxs(
|
|
207
172
|
"label",
|
|
208
173
|
{
|
|
209
174
|
htmlFor: `block-type-${type}`,
|
|
210
175
|
className: "flex items-center gap-2 cursor-pointer",
|
|
211
176
|
children: [
|
|
212
177
|
icons[type],
|
|
213
|
-
/* @__PURE__ */
|
|
178
|
+
/* @__PURE__ */ jsxRuntime.jsx("span", { className: "whitespace-nowrap hidden sm:inline", children: blockStyles[type].label })
|
|
214
179
|
]
|
|
215
180
|
}
|
|
216
181
|
)
|
|
@@ -219,7 +184,7 @@ function ScreenplayEditorView({
|
|
|
219
184
|
type
|
|
220
185
|
);
|
|
221
186
|
}) }),
|
|
222
|
-
/* @__PURE__ */
|
|
187
|
+
/* @__PURE__ */ jsxRuntime.jsx("div", { className: "flex flex-col gap-12 w-full items-center pb-24", children: pages.map((pageBlocks, pageIndex) => /* @__PURE__ */ jsxRuntime.jsxs(
|
|
223
188
|
"div",
|
|
224
189
|
{
|
|
225
190
|
className: "relative bg-[#fdfdfc] shadow-2xl shadow-zinc-300/60 ring-1 ring-zinc-200/50 rounded-sm md:rounded-md p-16 md:p-20 flex flex-col w-[210mm] min-h-[297mm] shrink-0",
|
|
@@ -229,15 +194,15 @@ function ScreenplayEditorView({
|
|
|
229
194
|
children: [
|
|
230
195
|
pageBlocks.map((block) => {
|
|
231
196
|
var _a, _b;
|
|
232
|
-
return /* @__PURE__ */
|
|
197
|
+
return /* @__PURE__ */ jsxRuntime.jsx(
|
|
233
198
|
"div",
|
|
234
199
|
{
|
|
235
200
|
"data-block-id": block.id,
|
|
236
201
|
className: `relative rounded-sm transition-all duration-200 outline-none ${focusedBlockId === block.id ? "bg-zinc-100/50" : "bg-transparent"}`,
|
|
237
|
-
children: block.type === "SCENE_HEADING" ? /* @__PURE__ */
|
|
238
|
-
/* @__PURE__ */
|
|
239
|
-
/* @__PURE__ */
|
|
240
|
-
/* @__PURE__ */
|
|
202
|
+
children: block.type === "SCENE_HEADING" ? /* @__PURE__ */ jsxRuntime.jsxs(jsxRuntime.Fragment, { children: [
|
|
203
|
+
/* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex items-center gap-2 px-4 py-1 bg-transparent", children: [
|
|
204
|
+
/* @__PURE__ */ jsxRuntime.jsx("span", { className: "absolute -left-16 top-2 w-12 text-right text-zinc-400 font-semibold select-none", children: String(sceneNumbers[block.id] || 0) }),
|
|
205
|
+
/* @__PURE__ */ jsxRuntime.jsxs(
|
|
241
206
|
"select",
|
|
242
207
|
{
|
|
243
208
|
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",
|
|
@@ -245,13 +210,13 @@ function ScreenplayEditorView({
|
|
|
245
210
|
value: (_a = block.sceneType) != null ? _a : "INT.",
|
|
246
211
|
onChange: (e) => handleSceneTypeChange(block.id, e.target.value),
|
|
247
212
|
children: [
|
|
248
|
-
/* @__PURE__ */
|
|
249
|
-
/* @__PURE__ */
|
|
250
|
-
/* @__PURE__ */
|
|
213
|
+
/* @__PURE__ */ jsxRuntime.jsx("option", { children: "INT." }),
|
|
214
|
+
/* @__PURE__ */ jsxRuntime.jsx("option", { children: "EXT." }),
|
|
215
|
+
/* @__PURE__ */ jsxRuntime.jsx("option", { children: "INT/EXT." })
|
|
251
216
|
]
|
|
252
217
|
}
|
|
253
218
|
),
|
|
254
|
-
/* @__PURE__ */
|
|
219
|
+
/* @__PURE__ */ jsxRuntime.jsx(
|
|
255
220
|
"div",
|
|
256
221
|
{
|
|
257
222
|
ref: (el) => {
|
|
@@ -274,27 +239,27 @@ function ScreenplayEditorView({
|
|
|
274
239
|
onBlur: () => handleBlur(block.id)
|
|
275
240
|
}
|
|
276
241
|
),
|
|
277
|
-
/* @__PURE__ */
|
|
278
|
-
/* @__PURE__ */
|
|
242
|
+
/* @__PURE__ */ jsxRuntime.jsx("span", { className: "text-zinc-400/80 font-bold", children: "-" }),
|
|
243
|
+
/* @__PURE__ */ jsxRuntime.jsx(
|
|
279
244
|
"select",
|
|
280
245
|
{
|
|
281
246
|
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",
|
|
282
247
|
"aria-label": "Time of Day",
|
|
283
248
|
value: (_b = block.timeOfDay) != null ? _b : "DAY",
|
|
284
249
|
onChange: (e) => handleTimeOfDayChange(block.id, e.target.value),
|
|
285
|
-
children: timeOfDayOptions.map((t) => /* @__PURE__ */
|
|
250
|
+
children: timeOfDayOptions.map((t) => /* @__PURE__ */ jsxRuntime.jsx("option", { children: t }, t))
|
|
286
251
|
}
|
|
287
252
|
)
|
|
288
253
|
] }),
|
|
289
|
-
focusedBlockId === block.id && showSuggestions && locations.length > 0 && /* @__PURE__ */
|
|
254
|
+
focusedBlockId === block.id && showSuggestions && locations.length > 0 && /* @__PURE__ */ jsxRuntime.jsx(
|
|
290
255
|
"div",
|
|
291
256
|
{
|
|
292
257
|
role: "listbox",
|
|
293
258
|
id: `suggestions-${block.id}`,
|
|
294
259
|
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",
|
|
295
|
-
children: /* @__PURE__ */
|
|
260
|
+
children: /* @__PURE__ */ jsxRuntime.jsx("div", { className: "max-h-60 overflow-y-auto custom-scrollbar", children: locations.filter(
|
|
296
261
|
(loc) => loc.startsWith(block.text.toUpperCase()) && loc !== block.text.toUpperCase()
|
|
297
|
-
).map((loc) => /* @__PURE__ */
|
|
262
|
+
).map((loc) => /* @__PURE__ */ jsxRuntime.jsxs(
|
|
298
263
|
"div",
|
|
299
264
|
{
|
|
300
265
|
role: "option",
|
|
@@ -316,16 +281,16 @@ function ScreenplayEditorView({
|
|
|
316
281
|
handleBlur(block.id);
|
|
317
282
|
},
|
|
318
283
|
children: [
|
|
319
|
-
/* @__PURE__ */
|
|
320
|
-
/* @__PURE__ */
|
|
284
|
+
/* @__PURE__ */ jsxRuntime.jsx("span", { className: "text-[12px] font-semibold tracking-wide text-slate-600 uppercase line-clamp-1", children: loc }),
|
|
285
|
+
/* @__PURE__ */ jsxRuntime.jsx(lucideReact.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" })
|
|
321
286
|
]
|
|
322
287
|
},
|
|
323
288
|
loc
|
|
324
289
|
)) })
|
|
325
290
|
}
|
|
326
291
|
)
|
|
327
|
-
] }) : /* @__PURE__ */
|
|
328
|
-
/* @__PURE__ */
|
|
292
|
+
] }) : /* @__PURE__ */ jsxRuntime.jsxs(jsxRuntime.Fragment, { children: [
|
|
293
|
+
/* @__PURE__ */ jsxRuntime.jsx(
|
|
329
294
|
"div",
|
|
330
295
|
{
|
|
331
296
|
ref: (el) => {
|
|
@@ -348,15 +313,15 @@ function ScreenplayEditorView({
|
|
|
348
313
|
style: blockStyles[block.type].inputStyle
|
|
349
314
|
}
|
|
350
315
|
),
|
|
351
|
-
focusedBlockId === block.id && block.type === "CHARACTER" && showSuggestions && characters.length > 0 && /* @__PURE__ */
|
|
316
|
+
focusedBlockId === block.id && block.type === "CHARACTER" && showSuggestions && characters.length > 0 && /* @__PURE__ */ jsxRuntime.jsx(
|
|
352
317
|
"div",
|
|
353
318
|
{
|
|
354
319
|
role: "listbox",
|
|
355
320
|
id: `suggestions-${block.id}`,
|
|
356
321
|
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",
|
|
357
|
-
children: /* @__PURE__ */
|
|
322
|
+
children: /* @__PURE__ */ jsxRuntime.jsx("div", { className: "max-h-56 overflow-y-auto custom-scrollbar", children: characters.filter(
|
|
358
323
|
(char) => char.startsWith(block.text.toUpperCase()) && char !== block.text.toUpperCase()
|
|
359
|
-
).map((char) => /* @__PURE__ */
|
|
324
|
+
).map((char) => /* @__PURE__ */ jsxRuntime.jsxs(
|
|
360
325
|
"div",
|
|
361
326
|
{
|
|
362
327
|
role: "option",
|
|
@@ -378,9 +343,9 @@ function ScreenplayEditorView({
|
|
|
378
343
|
handleBlur(block.id);
|
|
379
344
|
},
|
|
380
345
|
children: [
|
|
381
|
-
/* @__PURE__ */
|
|
382
|
-
/* @__PURE__ */
|
|
383
|
-
/* @__PURE__ */
|
|
346
|
+
/* @__PURE__ */ jsxRuntime.jsx(lucideReact.User, { className: "w-3.5 h-3.5 text-slate-300 group-hover:text-sky-500 transition-colors mr-3" }),
|
|
347
|
+
/* @__PURE__ */ jsxRuntime.jsx("span", { className: "flex-1 text-[11px] font-bold tracking-[0.1em] text-slate-600 uppercase text-left", children: char }),
|
|
348
|
+
/* @__PURE__ */ jsxRuntime.jsx(lucideReact.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" })
|
|
384
349
|
]
|
|
385
350
|
},
|
|
386
351
|
char
|
|
@@ -392,7 +357,7 @@ function ScreenplayEditorView({
|
|
|
392
357
|
block.id + "-" + block.type
|
|
393
358
|
);
|
|
394
359
|
}),
|
|
395
|
-
isPageSplitEnabled && /* @__PURE__ */
|
|
360
|
+
isPageSplitEnabled && /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "absolute bottom-10 right-16 md:right-20 text-zinc-400 font-semibold text-sm select-none pointer-events-none", children: [
|
|
396
361
|
pageIndex + 1,
|
|
397
362
|
"."
|
|
398
363
|
] })
|
|
@@ -400,37 +365,37 @@ function ScreenplayEditorView({
|
|
|
400
365
|
},
|
|
401
366
|
pageIndex
|
|
402
367
|
)) }),
|
|
403
|
-
/* @__PURE__ */
|
|
404
|
-
onSave && /* @__PURE__ */
|
|
368
|
+
/* @__PURE__ */ jsxRuntime.jsxs("div", { className: "fixed bottom-6 right-6 flex flex-col items-end gap-4 z-50", children: [
|
|
369
|
+
onSave && /* @__PURE__ */ jsxRuntime.jsxs(
|
|
405
370
|
"button",
|
|
406
371
|
{
|
|
407
372
|
onClick: onSave,
|
|
408
373
|
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",
|
|
409
374
|
"aria-label": "Save Script",
|
|
410
375
|
children: [
|
|
411
|
-
/* @__PURE__ */
|
|
412
|
-
/* @__PURE__ */
|
|
376
|
+
/* @__PURE__ */ jsxRuntime.jsx(lucideReact.Save, { className: "w-5 h-5" }),
|
|
377
|
+
/* @__PURE__ */ jsxRuntime.jsx("span", { className: "text-sm font-semibold", children: "Save" })
|
|
413
378
|
]
|
|
414
379
|
}
|
|
415
380
|
),
|
|
416
|
-
onSaveAsPdf && /* @__PURE__ */
|
|
381
|
+
onSaveAsPdf && /* @__PURE__ */ jsxRuntime.jsxs(
|
|
417
382
|
"button",
|
|
418
383
|
{
|
|
419
384
|
onClick: onSaveAsPdf,
|
|
420
385
|
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",
|
|
421
386
|
"aria-label": "Save Script as PDF",
|
|
422
387
|
children: [
|
|
423
|
-
/* @__PURE__ */
|
|
424
|
-
/* @__PURE__ */
|
|
388
|
+
/* @__PURE__ */ jsxRuntime.jsx(lucideReact.FileDown, { className: "w-5 h-5" }),
|
|
389
|
+
/* @__PURE__ */ jsxRuntime.jsx("span", { className: "text-sm font-semibold", children: "Save as PDF" })
|
|
425
390
|
]
|
|
426
391
|
}
|
|
427
392
|
),
|
|
428
|
-
isRulesOpen && /* @__PURE__ */
|
|
429
|
-
/* @__PURE__ */
|
|
430
|
-
/* @__PURE__ */
|
|
431
|
-
/* @__PURE__ */
|
|
432
|
-
/* @__PURE__ */
|
|
433
|
-
/* @__PURE__ */
|
|
393
|
+
isRulesOpen && /* @__PURE__ */ jsxRuntime.jsxs("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", children: [
|
|
394
|
+
/* @__PURE__ */ jsxRuntime.jsx("h4", { className: "font-bold text-zinc-800 mb-3 text-sm", children: "Settings & Shortcuts" }),
|
|
395
|
+
/* @__PURE__ */ jsxRuntime.jsxs("div", { className: "space-y-4", children: [
|
|
396
|
+
/* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex items-center justify-between gap-6", children: [
|
|
397
|
+
/* @__PURE__ */ jsxRuntime.jsx("span", { className: "font-semibold text-zinc-800", children: "A4 Page Split" }),
|
|
398
|
+
/* @__PURE__ */ jsxRuntime.jsx(
|
|
434
399
|
"button",
|
|
435
400
|
{
|
|
436
401
|
type: "button",
|
|
@@ -438,7 +403,7 @@ function ScreenplayEditorView({
|
|
|
438
403
|
"aria-checked": isPageSplitEnabled,
|
|
439
404
|
onClick: togglePageSplit,
|
|
440
405
|
className: `${isPageSplitEnabled ? "bg-zinc-900" : "bg-zinc-300"} 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`,
|
|
441
|
-
children: /* @__PURE__ */
|
|
406
|
+
children: /* @__PURE__ */ jsxRuntime.jsx(
|
|
442
407
|
"span",
|
|
443
408
|
{
|
|
444
409
|
"aria-hidden": "true",
|
|
@@ -448,42 +413,39 @@ function ScreenplayEditorView({
|
|
|
448
413
|
}
|
|
449
414
|
)
|
|
450
415
|
] }),
|
|
451
|
-
/* @__PURE__ */
|
|
452
|
-
/* @__PURE__ */
|
|
453
|
-
/* @__PURE__ */
|
|
454
|
-
/* @__PURE__ */
|
|
416
|
+
/* @__PURE__ */ jsxRuntime.jsx("div", { className: "space-y-1.5 pt-3 border-t border-zinc-200/50", children: /* @__PURE__ */ jsxRuntime.jsxs("ul", { className: "space-y-1.5", children: [
|
|
417
|
+
/* @__PURE__ */ jsxRuntime.jsxs("li", { className: "flex items-center justify-between gap-6", children: [
|
|
418
|
+
/* @__PURE__ */ jsxRuntime.jsx("span", { children: "New Block" }),
|
|
419
|
+
/* @__PURE__ */ jsxRuntime.jsx("kbd", { className: "px-2 py-1 text-xs font-semibold text-zinc-800 bg-zinc-200/70 border border-zinc-300/70 rounded-md", children: "Enter" })
|
|
455
420
|
] }),
|
|
456
|
-
/* @__PURE__ */
|
|
457
|
-
/* @__PURE__ */
|
|
458
|
-
/* @__PURE__ */
|
|
421
|
+
/* @__PURE__ */ jsxRuntime.jsxs("li", { className: "flex items-center justify-between gap-6", children: [
|
|
422
|
+
/* @__PURE__ */ jsxRuntime.jsx("span", { children: "Delete Block" }),
|
|
423
|
+
/* @__PURE__ */ jsxRuntime.jsx("kbd", { className: "px-2 py-1 text-xs font-semibold text-zinc-800 bg-zinc-200/70 border border-zinc-300/70 rounded-md", children: "Backspace" })
|
|
459
424
|
] }),
|
|
460
|
-
/* @__PURE__ */
|
|
461
|
-
/* @__PURE__ */
|
|
462
|
-
/* @__PURE__ */
|
|
463
|
-
/* @__PURE__ */
|
|
464
|
-
/* @__PURE__ */
|
|
465
|
-
/* @__PURE__ */
|
|
425
|
+
/* @__PURE__ */ jsxRuntime.jsxs("li", { className: "flex items-center justify-between gap-6", children: [
|
|
426
|
+
/* @__PURE__ */ jsxRuntime.jsx("span", { children: "Change Type" }),
|
|
427
|
+
/* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex items-center gap-1", children: [
|
|
428
|
+
/* @__PURE__ */ jsxRuntime.jsx("kbd", { className: "px-2 py-1 text-xs font-semibold text-zinc-800 bg-zinc-200/70 border border-zinc-300/70 rounded-md", children: "Ctrl" }),
|
|
429
|
+
/* @__PURE__ */ jsxRuntime.jsx("span", { children: "+" }),
|
|
430
|
+
/* @__PURE__ */ jsxRuntime.jsx("kbd", { className: "px-2 py-1 text-xs font-semibold text-zinc-800 bg-zinc-200/70 border border-zinc-300/70 rounded-md", children: "\u2191/\u2193" })
|
|
466
431
|
] })
|
|
467
432
|
] })
|
|
468
433
|
] }) })
|
|
469
434
|
] })
|
|
470
435
|
] }),
|
|
471
|
-
/* @__PURE__ */
|
|
436
|
+
/* @__PURE__ */ jsxRuntime.jsx(
|
|
472
437
|
"button",
|
|
473
438
|
{
|
|
474
439
|
onClick: () => setIsRulesOpen(!isRulesOpen),
|
|
475
440
|
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 ${isRulesOpen ? "rotate-90" : "rotate-0"}`,
|
|
476
441
|
"aria-label": "Toggle Settings",
|
|
477
|
-
children: /* @__PURE__ */
|
|
442
|
+
children: /* @__PURE__ */ jsxRuntime.jsx(lucideReact.Cog, { className: "w-5 h-5" })
|
|
478
443
|
}
|
|
479
444
|
)
|
|
480
445
|
] })
|
|
481
446
|
] });
|
|
482
447
|
}
|
|
483
448
|
|
|
484
|
-
// app/hook/use-screenplay-editor.ts
|
|
485
|
-
var import_react2 = require("react");
|
|
486
|
-
|
|
487
449
|
// app/service/screenplay-editor.service.ts
|
|
488
450
|
function getNextBlockType(currentType) {
|
|
489
451
|
switch (currentType) {
|
|
@@ -604,18 +566,18 @@ function setCaretPosition(element, offset) {
|
|
|
604
566
|
sel.addRange(range);
|
|
605
567
|
}
|
|
606
568
|
function useScreenplayEditor() {
|
|
607
|
-
const [blocks, setBlocks] =
|
|
608
|
-
const refs =
|
|
609
|
-
const [focusedBlockId, setFocusedBlockId] =
|
|
569
|
+
const [blocks, setBlocks] = react.useState(initialBlocks);
|
|
570
|
+
const refs = react.useRef({});
|
|
571
|
+
const [focusedBlockId, setFocusedBlockId] = react.useState(
|
|
610
572
|
initialBlocks[0].id
|
|
611
573
|
);
|
|
612
|
-
const [newBlockId, setNewBlockId] =
|
|
613
|
-
const [showSuggestions, setShowSuggestions] =
|
|
614
|
-
const blurTimeout =
|
|
615
|
-
const [isPageSplitEnabled, setIsPageSplitEnabled] =
|
|
616
|
-
const [pageBreaks, setPageBreaks] =
|
|
617
|
-
const focusStateRef =
|
|
618
|
-
const togglePageSplit =
|
|
574
|
+
const [newBlockId, setNewBlockId] = react.useState(null);
|
|
575
|
+
const [showSuggestions, setShowSuggestions] = react.useState(false);
|
|
576
|
+
const blurTimeout = react.useRef(null);
|
|
577
|
+
const [isPageSplitEnabled, setIsPageSplitEnabled] = react.useState(false);
|
|
578
|
+
const [pageBreaks, setPageBreaks] = react.useState([]);
|
|
579
|
+
const focusStateRef = react.useRef(null);
|
|
580
|
+
const togglePageSplit = react.useCallback(() => {
|
|
619
581
|
if (focusedBlockId && document.activeElement && document.activeElement.hasAttribute("contenteditable")) {
|
|
620
582
|
const el = refs.current[focusedBlockId];
|
|
621
583
|
if (el) {
|
|
@@ -625,15 +587,15 @@ function useScreenplayEditor() {
|
|
|
625
587
|
}
|
|
626
588
|
setIsPageSplitEnabled((prev) => !prev);
|
|
627
589
|
}, [focusedBlockId]);
|
|
628
|
-
const locations =
|
|
590
|
+
const locations = react.useMemo(() => {
|
|
629
591
|
const locs = blocks.filter((b) => b.type === "SCENE_HEADING" && b.text.trim() !== "").map((b) => b.text.trim().toUpperCase());
|
|
630
592
|
return [...new Set(locs)];
|
|
631
593
|
}, [blocks]);
|
|
632
|
-
const characters =
|
|
594
|
+
const characters = react.useMemo(() => {
|
|
633
595
|
const chars = blocks.filter((b) => b.type === "CHARACTER" && b.text.trim() !== "").map((b) => b.text.trim().toUpperCase());
|
|
634
596
|
return [...new Set(chars)];
|
|
635
597
|
}, [blocks]);
|
|
636
|
-
const sceneNumbers =
|
|
598
|
+
const sceneNumbers = react.useMemo(() => {
|
|
637
599
|
const map = {};
|
|
638
600
|
let count = 0;
|
|
639
601
|
blocks.forEach((block) => {
|
|
@@ -644,7 +606,7 @@ function useScreenplayEditor() {
|
|
|
644
606
|
});
|
|
645
607
|
return map;
|
|
646
608
|
}, [blocks]);
|
|
647
|
-
|
|
609
|
+
react.useEffect(() => {
|
|
648
610
|
var _a;
|
|
649
611
|
if (newBlockId && refs.current[newBlockId]) {
|
|
650
612
|
(_a = refs.current[newBlockId]) == null ? void 0 : _a.focus();
|
|
@@ -652,7 +614,7 @@ function useScreenplayEditor() {
|
|
|
652
614
|
setNewBlockId(null);
|
|
653
615
|
}
|
|
654
616
|
}, [newBlockId]);
|
|
655
|
-
|
|
617
|
+
react.useEffect(() => {
|
|
656
618
|
blocks.forEach((block) => {
|
|
657
619
|
const element = refs.current[block.id];
|
|
658
620
|
if (element && element.innerText !== block.text && document.activeElement !== element) {
|
|
@@ -660,7 +622,7 @@ function useScreenplayEditor() {
|
|
|
660
622
|
}
|
|
661
623
|
});
|
|
662
624
|
}, [blocks, isPageSplitEnabled, pageBreaks]);
|
|
663
|
-
|
|
625
|
+
react.useEffect(() => {
|
|
664
626
|
if (!isPageSplitEnabled) {
|
|
665
627
|
setPageBreaks([]);
|
|
666
628
|
return;
|
|
@@ -727,7 +689,7 @@ function useScreenplayEditor() {
|
|
|
727
689
|
}, 300);
|
|
728
690
|
return () => clearTimeout(timeoutId);
|
|
729
691
|
}, [blocks, isPageSplitEnabled, focusedBlockId]);
|
|
730
|
-
const pages =
|
|
692
|
+
const pages = react.useMemo(() => {
|
|
731
693
|
if (!isPageSplitEnabled || pageBreaks.length === 0) return [blocks];
|
|
732
694
|
const result = [];
|
|
733
695
|
let currentPage = [];
|
|
@@ -741,7 +703,7 @@ function useScreenplayEditor() {
|
|
|
741
703
|
if (currentPage.length > 0) result.push(currentPage);
|
|
742
704
|
return result;
|
|
743
705
|
}, [blocks, isPageSplitEnabled, pageBreaks]);
|
|
744
|
-
|
|
706
|
+
react.useEffect(() => {
|
|
745
707
|
if (focusStateRef.current) {
|
|
746
708
|
const { id, offset } = focusStateRef.current;
|
|
747
709
|
const el = refs.current[id];
|
|
@@ -752,10 +714,10 @@ function useScreenplayEditor() {
|
|
|
752
714
|
focusStateRef.current = null;
|
|
753
715
|
}
|
|
754
716
|
}, [pages]);
|
|
755
|
-
const handleBlockTextChange =
|
|
717
|
+
const handleBlockTextChange = react.useCallback((id, text) => {
|
|
756
718
|
setBlocks((bs) => updateBlock(bs, id, "text", text));
|
|
757
719
|
}, []);
|
|
758
|
-
const handleSceneTypeChange =
|
|
720
|
+
const handleSceneTypeChange = react.useCallback(
|
|
759
721
|
(id, sceneType) => {
|
|
760
722
|
setBlocks(
|
|
761
723
|
(bs) => updateBlock(bs, id, "sceneType", sceneType)
|
|
@@ -768,7 +730,7 @@ function useScreenplayEditor() {
|
|
|
768
730
|
},
|
|
769
731
|
[]
|
|
770
732
|
);
|
|
771
|
-
const handleTimeOfDayChange =
|
|
733
|
+
const handleTimeOfDayChange = react.useCallback((id, time) => {
|
|
772
734
|
setBlocks((bs) => updateBlock(bs, id, "timeOfDay", time));
|
|
773
735
|
setTimeout(() => {
|
|
774
736
|
var _a;
|
|
@@ -776,7 +738,7 @@ function useScreenplayEditor() {
|
|
|
776
738
|
setFocusedBlockId(id);
|
|
777
739
|
}, 10);
|
|
778
740
|
}, []);
|
|
779
|
-
const handleBlockTypeChange =
|
|
741
|
+
const handleBlockTypeChange = react.useCallback(
|
|
780
742
|
(newType) => {
|
|
781
743
|
if (!focusedBlockId) return;
|
|
782
744
|
setBlocks(
|
|
@@ -815,7 +777,7 @@ function useScreenplayEditor() {
|
|
|
815
777
|
return updateBlock(bs, id, "type", blockTypes[newIdx]);
|
|
816
778
|
});
|
|
817
779
|
};
|
|
818
|
-
const handleKeyDown =
|
|
780
|
+
const handleKeyDown = react.useCallback(
|
|
819
781
|
(e, id, text) => {
|
|
820
782
|
var _a;
|
|
821
783
|
if ((e.key === "Backspace" || e.key === "Delete") && text.length <= 1) {
|
|
@@ -926,14 +888,14 @@ function useScreenplayEditor() {
|
|
|
926
888
|
},
|
|
927
889
|
[blocks]
|
|
928
890
|
);
|
|
929
|
-
const handleFocus =
|
|
891
|
+
const handleFocus = react.useCallback((id) => {
|
|
930
892
|
if (blurTimeout.current) {
|
|
931
893
|
clearTimeout(blurTimeout.current);
|
|
932
894
|
}
|
|
933
895
|
setFocusedBlockId(id);
|
|
934
896
|
setShowSuggestions(true);
|
|
935
897
|
}, []);
|
|
936
|
-
const handleBlur =
|
|
898
|
+
const handleBlur = react.useCallback((id) => {
|
|
937
899
|
if (document.activeElement === refs.current[id]) return;
|
|
938
900
|
blurTimeout.current = setTimeout(() => setShowSuggestions(false), 200);
|
|
939
901
|
}, []);
|
|
@@ -957,14 +919,13 @@ function useScreenplayEditor() {
|
|
|
957
919
|
handleBlur
|
|
958
920
|
};
|
|
959
921
|
}
|
|
960
|
-
|
|
961
|
-
|
|
962
|
-
|
|
963
|
-
|
|
964
|
-
|
|
965
|
-
|
|
966
|
-
|
|
967
|
-
|
|
968
|
-
|
|
969
|
-
});
|
|
922
|
+
|
|
923
|
+
exports.ScreenplayEditorView = ScreenplayEditorView;
|
|
924
|
+
exports.blockStyles = blockStyles;
|
|
925
|
+
exports.blockTypes = blockTypes;
|
|
926
|
+
exports.icons = icons;
|
|
927
|
+
exports.timeOfDayOptions = timeOfDayOptions;
|
|
928
|
+
exports.useScreenplayEditor = useScreenplayEditor;
|
|
929
|
+
exports.uuid = uuid;
|
|
930
|
+
//# sourceMappingURL=index.cjs.map
|
|
970
931
|
//# sourceMappingURL=index.cjs.map
|