@lingjingai/script-editor 0.1.14 → 0.1.16
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/INTEGRATION.md +2 -0
- package/dist/index.d.ts +9 -1
- package/dist/index.js +195 -168
- package/dist/index.js.map +1 -1
- package/dist/style.css +16 -2
- package/package.json +1 -1
package/INTEGRATION.md
CHANGED
|
@@ -66,6 +66,8 @@ function Host({ script, setScript }) {
|
|
|
66
66
|
- `disabled`、`dark`、`className`
|
|
67
67
|
|
|
68
68
|
**HUD(顶栏)**
|
|
69
|
+
- `onTitleChange?(next: string)`:顶栏左侧常驻**剧本标题**(取 `value.title`)。传了它,标题变**点击即改**;不传则只读展示(`value.title` 为空时不显示)。包**不碰存储**——拿到新标题宿主自己持久化(可 `onEdit(p => ({...p, title}))` 写回 `script.json`,或另调重命名接口)。`0.1.16+`
|
|
70
|
+
- `topBarActions?: ReactNode`:顶栏**右侧**(格式切换/撤销重做旁)的**宿主注入槽**,放 stage 级业务按钮(如「删除剧本」「查看中间产物」)。包只渲染传入节点、零业务。`0.1.16+`
|
|
69
71
|
- `saveStatus`:`"idle" | "saving" | "saved" | "error"`
|
|
70
72
|
- `canUndo` / `canRedo` / `onUndo` / `onRedo` —— **Cmd/Ctrl+Z 撤销、Cmd/Ctrl+Shift+Z(或 Ctrl+Y)重做 已内建**(输入框内放行原生撤回),宿主**不要再自己接键盘监听**,否则会双触发(撤销两步)。`0.1.2+`
|
|
71
73
|
|
package/dist/index.d.ts
CHANGED
|
@@ -488,6 +488,14 @@ interface ScriptEditorProps extends ScriptEditorAdapters {
|
|
|
488
488
|
disabled?: boolean;
|
|
489
489
|
className?: string;
|
|
490
490
|
dark?: boolean;
|
|
491
|
+
/** when provided, the script title (value.title) becomes click-to-edit in the
|
|
492
|
+
* top bar; the host persists the new value (the editor never touches storage,
|
|
493
|
+
* matching the value + onEdit contract — just one more delegated hook). Omit →
|
|
494
|
+
* the title shows read-only (or nothing when value.title is empty). */
|
|
495
|
+
onTitleChange?: (next: string) => void;
|
|
496
|
+
/** host-injected actions for the top bar's right edge (e.g. 删除剧本 /
|
|
497
|
+
* 查看中间产物). The package only renders the node — all business stays host-side. */
|
|
498
|
+
topBarActions?: React.ReactNode;
|
|
491
499
|
saveStatus?: SaveStatus;
|
|
492
500
|
canUndo?: boolean;
|
|
493
501
|
canRedo?: boolean;
|
|
@@ -504,7 +512,7 @@ interface ScriptEditorProps extends ScriptEditorAdapters {
|
|
|
504
512
|
* scroll position across editor unmount/remount (tab switch / project nav). */
|
|
505
513
|
scrollScopeKey?: string;
|
|
506
514
|
}
|
|
507
|
-
declare function ScriptEditor({ value, onEdit, selection: controlledSelection, onSelectionChange, format: controlledFormat, onFormatChange, disabled, className, dark, saveStatus, canUndo, canRedo, onUndo, onRedo, onEditingChange, referenceFocusRequest, scrollScopeKey, diff, asset, onAddChatReferences, onRequestAssetDelete, }: ScriptEditorProps): react.JSX.Element;
|
|
515
|
+
declare function ScriptEditor({ value, onEdit, selection: controlledSelection, onSelectionChange, format: controlledFormat, onFormatChange, disabled, className, dark, onTitleChange, topBarActions, saveStatus, canUndo, canRedo, onUndo, onRedo, onEditingChange, referenceFocusRequest, scrollScopeKey, diff, asset, onAddChatReferences, onRequestAssetDelete, }: ScriptEditorProps): react.JSX.Element;
|
|
508
516
|
|
|
509
517
|
/**
|
|
510
518
|
* Pure ScriptProject mutations.
|
package/dist/index.js
CHANGED
|
@@ -608,6 +608,169 @@ function EntityGroup({
|
|
|
608
608
|
)) : null
|
|
609
609
|
] });
|
|
610
610
|
}
|
|
611
|
+
var EditingSignalContext = createContext(null);
|
|
612
|
+
var LIVE_COMMIT_MS = 400;
|
|
613
|
+
function caretOffsetFromPoint(x, y) {
|
|
614
|
+
const d = document;
|
|
615
|
+
if (typeof d.caretRangeFromPoint === "function") {
|
|
616
|
+
const r = d.caretRangeFromPoint(x, y);
|
|
617
|
+
return r ? r.startOffset : null;
|
|
618
|
+
}
|
|
619
|
+
if (typeof d.caretPositionFromPoint === "function") {
|
|
620
|
+
const p = d.caretPositionFromPoint(x, y);
|
|
621
|
+
return p ? p.offset : null;
|
|
622
|
+
}
|
|
623
|
+
return null;
|
|
624
|
+
}
|
|
625
|
+
function EditableText({
|
|
626
|
+
value,
|
|
627
|
+
onSave,
|
|
628
|
+
placeholder,
|
|
629
|
+
multiline = false,
|
|
630
|
+
disabled = false,
|
|
631
|
+
className,
|
|
632
|
+
autoEdit = false,
|
|
633
|
+
onEditEnd,
|
|
634
|
+
spanProps
|
|
635
|
+
}) {
|
|
636
|
+
const [editing, setEditing] = useState(autoEdit);
|
|
637
|
+
const [draft, setDraft] = useState(value);
|
|
638
|
+
const caretRef = useRef(null);
|
|
639
|
+
const inputRef = useRef(null);
|
|
640
|
+
const committedRef = useRef(value);
|
|
641
|
+
const editingSignal = useContext(EditingSignalContext);
|
|
642
|
+
const liveTimerRef = useRef(null);
|
|
643
|
+
const composingRef = useRef(false);
|
|
644
|
+
const draftRef = useRef(value);
|
|
645
|
+
const onSaveRef = useRef(onSave);
|
|
646
|
+
onSaveRef.current = onSave;
|
|
647
|
+
const clearLiveTimer = () => {
|
|
648
|
+
if (liveTimerRef.current) {
|
|
649
|
+
clearTimeout(liveTimerRef.current);
|
|
650
|
+
liveTimerRef.current = null;
|
|
651
|
+
}
|
|
652
|
+
};
|
|
653
|
+
const flushLive = () => {
|
|
654
|
+
clearLiveTimer();
|
|
655
|
+
const next = draftRef.current;
|
|
656
|
+
if (next !== committedRef.current) {
|
|
657
|
+
committedRef.current = next;
|
|
658
|
+
onSaveRef.current(next);
|
|
659
|
+
}
|
|
660
|
+
};
|
|
661
|
+
const scheduleLive = () => {
|
|
662
|
+
clearLiveTimer();
|
|
663
|
+
liveTimerRef.current = setTimeout(() => {
|
|
664
|
+
liveTimerRef.current = null;
|
|
665
|
+
if (composingRef.current) return;
|
|
666
|
+
flushLive();
|
|
667
|
+
}, LIVE_COMMIT_MS);
|
|
668
|
+
};
|
|
669
|
+
useEffect(() => () => flushLive(), []);
|
|
670
|
+
useEffect(() => {
|
|
671
|
+
if (!editing || !editingSignal) return;
|
|
672
|
+
editingSignal.inc();
|
|
673
|
+
return () => editingSignal.dec();
|
|
674
|
+
}, [editing, editingSignal]);
|
|
675
|
+
useEffect(() => {
|
|
676
|
+
if (value === committedRef.current) return;
|
|
677
|
+
const userDiverged = editing && draft !== committedRef.current;
|
|
678
|
+
if (userDiverged) return;
|
|
679
|
+
setDraft(value);
|
|
680
|
+
committedRef.current = value;
|
|
681
|
+
}, [value, editing, draft]);
|
|
682
|
+
useEffect(() => {
|
|
683
|
+
if (autoEdit) setEditing(true);
|
|
684
|
+
}, [autoEdit]);
|
|
685
|
+
useLayoutEffect(() => {
|
|
686
|
+
if (!editing) return;
|
|
687
|
+
const el = inputRef.current;
|
|
688
|
+
if (!el) return;
|
|
689
|
+
if (multiline) autoSize(el);
|
|
690
|
+
el.focus();
|
|
691
|
+
const caret = caretRef.current;
|
|
692
|
+
const pos = caret == null ? el.value.length : Math.min(caret, el.value.length);
|
|
693
|
+
try {
|
|
694
|
+
el.setSelectionRange(pos, pos);
|
|
695
|
+
} catch {
|
|
696
|
+
}
|
|
697
|
+
caretRef.current = null;
|
|
698
|
+
}, [editing, multiline]);
|
|
699
|
+
function beginEdit(e) {
|
|
700
|
+
if (disabled) return;
|
|
701
|
+
const sel = window.getSelection();
|
|
702
|
+
if (sel && !sel.isCollapsed) return;
|
|
703
|
+
caretRef.current = caretOffsetFromPoint(e.clientX, e.clientY);
|
|
704
|
+
setDraft(committedRef.current);
|
|
705
|
+
draftRef.current = committedRef.current;
|
|
706
|
+
setEditing(true);
|
|
707
|
+
}
|
|
708
|
+
function commit() {
|
|
709
|
+
clearLiveTimer();
|
|
710
|
+
setEditing(false);
|
|
711
|
+
onEditEnd?.();
|
|
712
|
+
if (draft !== committedRef.current) {
|
|
713
|
+
committedRef.current = draft;
|
|
714
|
+
onSave(draft);
|
|
715
|
+
}
|
|
716
|
+
}
|
|
717
|
+
function cancel() {
|
|
718
|
+
clearLiveTimer();
|
|
719
|
+
setDraft(committedRef.current);
|
|
720
|
+
draftRef.current = committedRef.current;
|
|
721
|
+
setEditing(false);
|
|
722
|
+
onEditEnd?.();
|
|
723
|
+
}
|
|
724
|
+
if (!editing) {
|
|
725
|
+
return /* @__PURE__ */ jsx(
|
|
726
|
+
"span",
|
|
727
|
+
{
|
|
728
|
+
...spanProps,
|
|
729
|
+
className: "lj-se-editable" + (className ? " " + className : "") + (disabled ? " lj-se-editable--ro" : ""),
|
|
730
|
+
onClick: beginEdit,
|
|
731
|
+
children: value || /* @__PURE__ */ jsx("span", { className: "lj-se-ph", children: placeholder ?? "" })
|
|
732
|
+
}
|
|
733
|
+
);
|
|
734
|
+
}
|
|
735
|
+
const common = {
|
|
736
|
+
ref: inputRef,
|
|
737
|
+
value: draft,
|
|
738
|
+
className: "lj-se-editing" + (className ? " " + className : ""),
|
|
739
|
+
onChange: (e) => {
|
|
740
|
+
const v = e.target.value;
|
|
741
|
+
setDraft(v);
|
|
742
|
+
draftRef.current = v;
|
|
743
|
+
if (multiline) autoSize(e.target);
|
|
744
|
+
if (!composingRef.current) scheduleLive();
|
|
745
|
+
},
|
|
746
|
+
onCompositionStart: () => {
|
|
747
|
+
composingRef.current = true;
|
|
748
|
+
clearLiveTimer();
|
|
749
|
+
},
|
|
750
|
+
onCompositionEnd: (e) => {
|
|
751
|
+
composingRef.current = false;
|
|
752
|
+
draftRef.current = e.currentTarget.value;
|
|
753
|
+
scheduleLive();
|
|
754
|
+
},
|
|
755
|
+
onBlur: commit,
|
|
756
|
+
onKeyDown: (e) => {
|
|
757
|
+
if (e.key === "Escape") {
|
|
758
|
+
e.preventDefault();
|
|
759
|
+
cancel();
|
|
760
|
+
} else if (e.key === "Enter") {
|
|
761
|
+
if (!multiline || e.metaKey || e.ctrlKey) {
|
|
762
|
+
e.preventDefault();
|
|
763
|
+
commit();
|
|
764
|
+
}
|
|
765
|
+
}
|
|
766
|
+
}
|
|
767
|
+
};
|
|
768
|
+
return multiline ? /* @__PURE__ */ jsx("textarea", { ...common, rows: 1 }) : /* @__PURE__ */ jsx("input", { ...common, type: "text" });
|
|
769
|
+
}
|
|
770
|
+
function autoSize(el) {
|
|
771
|
+
el.style.height = "auto";
|
|
772
|
+
el.style.height = el.scrollHeight + "px";
|
|
773
|
+
}
|
|
611
774
|
function FormatToggle({
|
|
612
775
|
value,
|
|
613
776
|
onChange
|
|
@@ -628,22 +791,43 @@ function FormatToggle({
|
|
|
628
791
|
)) });
|
|
629
792
|
}
|
|
630
793
|
function CanvasTopBar({
|
|
794
|
+
title,
|
|
795
|
+
onTitleChange,
|
|
796
|
+
titleDisabled,
|
|
631
797
|
contextLabel,
|
|
632
798
|
format,
|
|
633
799
|
onFormatChange,
|
|
634
800
|
canUndo,
|
|
635
801
|
canRedo,
|
|
636
802
|
onUndo,
|
|
637
|
-
onRedo
|
|
803
|
+
onRedo,
|
|
804
|
+
actions
|
|
638
805
|
}) {
|
|
806
|
+
const hasTitle = onTitleChange != null || (title ?? "").length > 0;
|
|
639
807
|
return /* @__PURE__ */ jsxs("header", { className: "lj-se-topbar", children: [
|
|
640
|
-
/* @__PURE__ */
|
|
808
|
+
/* @__PURE__ */ jsxs("div", { className: "lj-se-topbar-left", children: [
|
|
809
|
+
hasTitle ? onTitleChange ? /* @__PURE__ */ jsx(
|
|
810
|
+
EditableText,
|
|
811
|
+
{
|
|
812
|
+
className: "lj-se-topbar-title",
|
|
813
|
+
value: title ?? "",
|
|
814
|
+
placeholder: "\u672A\u547D\u540D\u5267\u672C",
|
|
815
|
+
disabled: titleDisabled,
|
|
816
|
+
onSave: onTitleChange
|
|
817
|
+
}
|
|
818
|
+
) : /* @__PURE__ */ jsx("span", { className: "lj-se-topbar-title lj-se-topbar-title--ro", children: title }) : null,
|
|
819
|
+
contextLabel ? /* @__PURE__ */ jsxs("span", { className: "lj-se-topbar-ctx", children: [
|
|
820
|
+
hasTitle ? /* @__PURE__ */ jsx("span", { className: "lj-se-topbar-sep", "aria-hidden": true, children: "/" }) : null,
|
|
821
|
+
contextLabel
|
|
822
|
+
] }) : null
|
|
823
|
+
] }),
|
|
641
824
|
/* @__PURE__ */ jsxs("div", { className: "lj-se-topbar-right", children: [
|
|
642
825
|
/* @__PURE__ */ jsx(FormatToggle, { value: format, onChange: onFormatChange }),
|
|
643
826
|
onUndo || onRedo ? /* @__PURE__ */ jsxs("div", { className: "lj-se-topbar-undo", children: [
|
|
644
827
|
/* @__PURE__ */ jsx("button", { type: "button", className: "lj-se-rowbtn", disabled: !canUndo, title: "\u64A4\u9500", onClick: onUndo, children: /* @__PURE__ */ jsx(Undo2, { className: "lj-se-ic-4", strokeWidth: 1.75 }) }),
|
|
645
828
|
/* @__PURE__ */ jsx("button", { type: "button", className: "lj-se-rowbtn", disabled: !canRedo, title: "\u91CD\u505A", onClick: onRedo, children: /* @__PURE__ */ jsx(Redo2, { className: "lj-se-ic-4", strokeWidth: 1.75 }) })
|
|
646
|
-
] }) : null
|
|
829
|
+
] }) : null,
|
|
830
|
+
actions ? /* @__PURE__ */ jsx("div", { className: "lj-se-topbar-actions", children: actions }) : null
|
|
647
831
|
] })
|
|
648
832
|
] });
|
|
649
833
|
}
|
|
@@ -2014,169 +2198,6 @@ function getActorCueVar(actorId, tone = "dialogue") {
|
|
|
2014
2198
|
const idx = hashActorId(id) % PALETTE_SIZE + 1;
|
|
2015
2199
|
return `var(--lj-se-actor-cue-${idx})`;
|
|
2016
2200
|
}
|
|
2017
|
-
var EditingSignalContext = createContext(null);
|
|
2018
|
-
var LIVE_COMMIT_MS = 400;
|
|
2019
|
-
function caretOffsetFromPoint(x, y) {
|
|
2020
|
-
const d = document;
|
|
2021
|
-
if (typeof d.caretRangeFromPoint === "function") {
|
|
2022
|
-
const r = d.caretRangeFromPoint(x, y);
|
|
2023
|
-
return r ? r.startOffset : null;
|
|
2024
|
-
}
|
|
2025
|
-
if (typeof d.caretPositionFromPoint === "function") {
|
|
2026
|
-
const p = d.caretPositionFromPoint(x, y);
|
|
2027
|
-
return p ? p.offset : null;
|
|
2028
|
-
}
|
|
2029
|
-
return null;
|
|
2030
|
-
}
|
|
2031
|
-
function EditableText({
|
|
2032
|
-
value,
|
|
2033
|
-
onSave,
|
|
2034
|
-
placeholder,
|
|
2035
|
-
multiline = false,
|
|
2036
|
-
disabled = false,
|
|
2037
|
-
className,
|
|
2038
|
-
autoEdit = false,
|
|
2039
|
-
onEditEnd,
|
|
2040
|
-
spanProps
|
|
2041
|
-
}) {
|
|
2042
|
-
const [editing, setEditing] = useState(autoEdit);
|
|
2043
|
-
const [draft, setDraft] = useState(value);
|
|
2044
|
-
const caretRef = useRef(null);
|
|
2045
|
-
const inputRef = useRef(null);
|
|
2046
|
-
const committedRef = useRef(value);
|
|
2047
|
-
const editingSignal = useContext(EditingSignalContext);
|
|
2048
|
-
const liveTimerRef = useRef(null);
|
|
2049
|
-
const composingRef = useRef(false);
|
|
2050
|
-
const draftRef = useRef(value);
|
|
2051
|
-
const onSaveRef = useRef(onSave);
|
|
2052
|
-
onSaveRef.current = onSave;
|
|
2053
|
-
const clearLiveTimer = () => {
|
|
2054
|
-
if (liveTimerRef.current) {
|
|
2055
|
-
clearTimeout(liveTimerRef.current);
|
|
2056
|
-
liveTimerRef.current = null;
|
|
2057
|
-
}
|
|
2058
|
-
};
|
|
2059
|
-
const flushLive = () => {
|
|
2060
|
-
clearLiveTimer();
|
|
2061
|
-
const next = draftRef.current;
|
|
2062
|
-
if (next !== committedRef.current) {
|
|
2063
|
-
committedRef.current = next;
|
|
2064
|
-
onSaveRef.current(next);
|
|
2065
|
-
}
|
|
2066
|
-
};
|
|
2067
|
-
const scheduleLive = () => {
|
|
2068
|
-
clearLiveTimer();
|
|
2069
|
-
liveTimerRef.current = setTimeout(() => {
|
|
2070
|
-
liveTimerRef.current = null;
|
|
2071
|
-
if (composingRef.current) return;
|
|
2072
|
-
flushLive();
|
|
2073
|
-
}, LIVE_COMMIT_MS);
|
|
2074
|
-
};
|
|
2075
|
-
useEffect(() => () => flushLive(), []);
|
|
2076
|
-
useEffect(() => {
|
|
2077
|
-
if (!editing || !editingSignal) return;
|
|
2078
|
-
editingSignal.inc();
|
|
2079
|
-
return () => editingSignal.dec();
|
|
2080
|
-
}, [editing, editingSignal]);
|
|
2081
|
-
useEffect(() => {
|
|
2082
|
-
if (value === committedRef.current) return;
|
|
2083
|
-
const userDiverged = editing && draft !== committedRef.current;
|
|
2084
|
-
if (userDiverged) return;
|
|
2085
|
-
setDraft(value);
|
|
2086
|
-
committedRef.current = value;
|
|
2087
|
-
}, [value, editing, draft]);
|
|
2088
|
-
useEffect(() => {
|
|
2089
|
-
if (autoEdit) setEditing(true);
|
|
2090
|
-
}, [autoEdit]);
|
|
2091
|
-
useLayoutEffect(() => {
|
|
2092
|
-
if (!editing) return;
|
|
2093
|
-
const el = inputRef.current;
|
|
2094
|
-
if (!el) return;
|
|
2095
|
-
if (multiline) autoSize(el);
|
|
2096
|
-
el.focus();
|
|
2097
|
-
const caret = caretRef.current;
|
|
2098
|
-
const pos = caret == null ? el.value.length : Math.min(caret, el.value.length);
|
|
2099
|
-
try {
|
|
2100
|
-
el.setSelectionRange(pos, pos);
|
|
2101
|
-
} catch {
|
|
2102
|
-
}
|
|
2103
|
-
caretRef.current = null;
|
|
2104
|
-
}, [editing, multiline]);
|
|
2105
|
-
function beginEdit(e) {
|
|
2106
|
-
if (disabled) return;
|
|
2107
|
-
const sel = window.getSelection();
|
|
2108
|
-
if (sel && !sel.isCollapsed) return;
|
|
2109
|
-
caretRef.current = caretOffsetFromPoint(e.clientX, e.clientY);
|
|
2110
|
-
setDraft(committedRef.current);
|
|
2111
|
-
draftRef.current = committedRef.current;
|
|
2112
|
-
setEditing(true);
|
|
2113
|
-
}
|
|
2114
|
-
function commit() {
|
|
2115
|
-
clearLiveTimer();
|
|
2116
|
-
setEditing(false);
|
|
2117
|
-
onEditEnd?.();
|
|
2118
|
-
if (draft !== committedRef.current) {
|
|
2119
|
-
committedRef.current = draft;
|
|
2120
|
-
onSave(draft);
|
|
2121
|
-
}
|
|
2122
|
-
}
|
|
2123
|
-
function cancel() {
|
|
2124
|
-
clearLiveTimer();
|
|
2125
|
-
setDraft(committedRef.current);
|
|
2126
|
-
draftRef.current = committedRef.current;
|
|
2127
|
-
setEditing(false);
|
|
2128
|
-
onEditEnd?.();
|
|
2129
|
-
}
|
|
2130
|
-
if (!editing) {
|
|
2131
|
-
return /* @__PURE__ */ jsx(
|
|
2132
|
-
"span",
|
|
2133
|
-
{
|
|
2134
|
-
...spanProps,
|
|
2135
|
-
className: "lj-se-editable" + (className ? " " + className : "") + (disabled ? " lj-se-editable--ro" : ""),
|
|
2136
|
-
onClick: beginEdit,
|
|
2137
|
-
children: value || /* @__PURE__ */ jsx("span", { className: "lj-se-ph", children: placeholder ?? "" })
|
|
2138
|
-
}
|
|
2139
|
-
);
|
|
2140
|
-
}
|
|
2141
|
-
const common = {
|
|
2142
|
-
ref: inputRef,
|
|
2143
|
-
value: draft,
|
|
2144
|
-
className: "lj-se-editing" + (className ? " " + className : ""),
|
|
2145
|
-
onChange: (e) => {
|
|
2146
|
-
const v = e.target.value;
|
|
2147
|
-
setDraft(v);
|
|
2148
|
-
draftRef.current = v;
|
|
2149
|
-
if (multiline) autoSize(e.target);
|
|
2150
|
-
if (!composingRef.current) scheduleLive();
|
|
2151
|
-
},
|
|
2152
|
-
onCompositionStart: () => {
|
|
2153
|
-
composingRef.current = true;
|
|
2154
|
-
clearLiveTimer();
|
|
2155
|
-
},
|
|
2156
|
-
onCompositionEnd: (e) => {
|
|
2157
|
-
composingRef.current = false;
|
|
2158
|
-
draftRef.current = e.currentTarget.value;
|
|
2159
|
-
scheduleLive();
|
|
2160
|
-
},
|
|
2161
|
-
onBlur: commit,
|
|
2162
|
-
onKeyDown: (e) => {
|
|
2163
|
-
if (e.key === "Escape") {
|
|
2164
|
-
e.preventDefault();
|
|
2165
|
-
cancel();
|
|
2166
|
-
} else if (e.key === "Enter") {
|
|
2167
|
-
if (!multiline || e.metaKey || e.ctrlKey) {
|
|
2168
|
-
e.preventDefault();
|
|
2169
|
-
commit();
|
|
2170
|
-
}
|
|
2171
|
-
}
|
|
2172
|
-
}
|
|
2173
|
-
};
|
|
2174
|
-
return multiline ? /* @__PURE__ */ jsx("textarea", { ...common, rows: 1 }) : /* @__PURE__ */ jsx("input", { ...common, type: "text" });
|
|
2175
|
-
}
|
|
2176
|
-
function autoSize(el) {
|
|
2177
|
-
el.style.height = "auto";
|
|
2178
|
-
el.style.height = el.scrollHeight + "px";
|
|
2179
|
-
}
|
|
2180
2201
|
function formatStateChangeLabels(item, actorMap, locationMap, propMap) {
|
|
2181
2202
|
const labels = (item.state_changes ?? []).map((change) => {
|
|
2182
2203
|
const kind = change.target_kind?.trim() || "actor";
|
|
@@ -3752,6 +3773,8 @@ function ScriptEditor({
|
|
|
3752
3773
|
disabled = false,
|
|
3753
3774
|
className,
|
|
3754
3775
|
dark,
|
|
3776
|
+
onTitleChange,
|
|
3777
|
+
topBarActions,
|
|
3755
3778
|
saveStatus = "idle",
|
|
3756
3779
|
canUndo,
|
|
3757
3780
|
canRedo,
|
|
@@ -3926,13 +3949,17 @@ function ScriptEditor({
|
|
|
3926
3949
|
/* @__PURE__ */ jsx(
|
|
3927
3950
|
CanvasTopBar,
|
|
3928
3951
|
{
|
|
3952
|
+
title: value.title,
|
|
3953
|
+
onTitleChange: disabled ? void 0 : onTitleChange,
|
|
3954
|
+
titleDisabled: disabled,
|
|
3929
3955
|
contextLabel,
|
|
3930
3956
|
format,
|
|
3931
3957
|
onFormatChange: setFormat,
|
|
3932
3958
|
canUndo,
|
|
3933
3959
|
canRedo,
|
|
3934
3960
|
onUndo,
|
|
3935
|
-
onRedo
|
|
3961
|
+
onRedo,
|
|
3962
|
+
actions: topBarActions
|
|
3936
3963
|
}
|
|
3937
3964
|
),
|
|
3938
3965
|
/* @__PURE__ */ jsxs("div", { className: "lj-se-canvas", ref: canvasRef, children: [
|
|
@@ -3990,7 +4017,7 @@ function buildContextLabel(value, selection) {
|
|
|
3990
4017
|
] });
|
|
3991
4018
|
}
|
|
3992
4019
|
}
|
|
3993
|
-
return
|
|
4020
|
+
return null;
|
|
3994
4021
|
}
|
|
3995
4022
|
function Ctx({ kicker, name }) {
|
|
3996
4023
|
return /* @__PURE__ */ jsxs("span", { className: "lj-se-ctx", children: [
|