Skip to content

Commit 60d7870

Browse files
YousefEDclaude
andcommitted
fix: save file caption/name on every keystroke instead of on close
Previously, caption/name values were stored in local state and only saved to the block on Enter. Clicking outside the popover discarded input, and Enter didn't close the popover. Now handleChange calls editor.updateBlock directly, input reads from block props, and the popover is controlled so Enter closes it. Co-Authored-By: Claude Opus 4.6 <[email protected]>
1 parent 0e94795 commit 60d7870

File tree

2 files changed

+38
-51
lines changed

2 files changed

+38
-51
lines changed

packages/react/src/components/FormattingToolbar/DefaultButtons/FileCaptionButton.tsx

Lines changed: 19 additions & 25 deletions
Original file line numberDiff line numberDiff line change
@@ -9,7 +9,6 @@ import {
99
ChangeEvent,
1010
KeyboardEvent,
1111
useCallback,
12-
useEffect,
1312
useState,
1413
} from "react";
1514
import { RiInputField } from "react-icons/ri";
@@ -59,54 +58,49 @@ export const FileCaptionButton = () => {
5958
},
6059
});
6160

62-
const [currentEditingCaption, setCurrentEditingCaption] = useState<string>();
63-
64-
useEffect(() => {
65-
if (block === undefined) {
66-
return;
67-
}
68-
setCurrentEditingCaption(block.props.caption);
69-
}, [block]);
61+
const [popoverOpen, setPopoverOpen] = useState(false);
7062

7163
const handleChange = useCallback(
72-
(event: ChangeEvent<HTMLInputElement>) =>
73-
setCurrentEditingCaption(event.currentTarget.value),
74-
[],
75-
);
76-
77-
const handleEnter = useCallback(
78-
(event: KeyboardEvent) => {
64+
(event: ChangeEvent<HTMLInputElement>) => {
7965
if (
8066
block !== undefined &&
8167
editorHasBlockWithType(editor, block.type, {
8268
caption: "string",
83-
}) &&
84-
event.key === "Enter" &&
85-
!event.nativeEvent.isComposing
69+
})
8670
) {
87-
event.preventDefault();
8871
editor.updateBlock(block.id, {
8972
props: {
90-
caption: currentEditingCaption,
73+
caption: event.currentTarget.value,
9174
},
9275
});
9376
}
9477
},
95-
[block, currentEditingCaption, editor],
78+
[block, editor],
9679
);
9780

81+
const handleKeyDown = useCallback((event: KeyboardEvent) => {
82+
if (event.key === "Enter" && !event.nativeEvent.isComposing) {
83+
event.preventDefault();
84+
setPopoverOpen(false);
85+
}
86+
}, []);
87+
9888
if (block === undefined) {
9989
return null;
10090
}
10191

10292
return (
103-
<Components.Generic.Popover.Root>
93+
<Components.Generic.Popover.Root
94+
open={popoverOpen}
95+
onOpenChange={setPopoverOpen}
96+
>
10497
<Components.Generic.Popover.Trigger>
10598
<Components.FormattingToolbar.Button
10699
className={"bn-button"}
107100
label={dict.formatting_toolbar.file_caption.tooltip}
108101
mainTooltip={dict.formatting_toolbar.file_caption.tooltip}
109102
icon={<RiInputField />}
103+
onClick={() => setPopoverOpen((open) => !open)}
110104
/>
111105
</Components.Generic.Popover.Trigger>
112106
<Components.Generic.Popover.Content
@@ -117,10 +111,10 @@ export const FileCaptionButton = () => {
117111
<Components.Generic.Form.TextInput
118112
name={"file-caption"}
119113
icon={<RiInputField />}
120-
value={currentEditingCaption || ""}
114+
value={block.props.caption}
121115
autoFocus={true}
122116
placeholder={dict.formatting_toolbar.file_caption.input_placeholder}
123-
onKeyDown={handleEnter}
117+
onKeyDown={handleKeyDown}
124118
onChange={handleChange}
125119
/>
126120
</Components.Generic.Form.Root>

packages/react/src/components/FormattingToolbar/DefaultButtons/FileRenameButton.tsx

Lines changed: 19 additions & 26 deletions
Original file line numberDiff line numberDiff line change
@@ -9,7 +9,6 @@ import {
99
ChangeEvent,
1010
KeyboardEvent,
1111
useCallback,
12-
useEffect,
1312
useState,
1413
} from "react";
1514
import { RiFontFamily } from "react-icons/ri";
@@ -59,49 +58,42 @@ export const FileRenameButton = () => {
5958
},
6059
});
6160

62-
const [currentEditingName, setCurrentEditingName] = useState<string>();
63-
64-
useEffect(() => {
65-
if (block === undefined) {
66-
return;
67-
}
68-
69-
setCurrentEditingName(block.props.name);
70-
}, [block]);
61+
const [popoverOpen, setPopoverOpen] = useState(false);
7162

7263
const handleChange = useCallback(
73-
(event: ChangeEvent<HTMLInputElement>) =>
74-
setCurrentEditingName(event.currentTarget.value),
75-
[],
76-
);
77-
78-
const handleEnter = useCallback(
79-
(event: KeyboardEvent) => {
64+
(event: ChangeEvent<HTMLInputElement>) => {
8065
if (
8166
block !== undefined &&
8267
editorHasBlockWithType(editor, block.type, {
8368
name: "string",
84-
}) &&
85-
event.key === "Enter" &&
86-
!event.nativeEvent.isComposing
69+
})
8770
) {
88-
event.preventDefault();
8971
editor.updateBlock(block.id, {
9072
props: {
91-
name: currentEditingName,
73+
name: event.currentTarget.value,
9274
},
9375
});
9476
}
9577
},
96-
[block, currentEditingName, editor],
78+
[block, editor],
9779
);
9880

81+
const handleKeyDown = useCallback((event: KeyboardEvent) => {
82+
if (event.key === "Enter" && !event.nativeEvent.isComposing) {
83+
event.preventDefault();
84+
setPopoverOpen(false);
85+
}
86+
}, []);
87+
9988
if (block === undefined) {
10089
return null;
10190
}
10291

10392
return (
104-
<Components.Generic.Popover.Root>
93+
<Components.Generic.Popover.Root
94+
open={popoverOpen}
95+
onOpenChange={setPopoverOpen}
96+
>
10597
<Components.Generic.Popover.Trigger>
10698
<Components.FormattingToolbar.Button
10799
className={"bn-button"}
@@ -114,6 +106,7 @@ export const FileRenameButton = () => {
114106
dict.formatting_toolbar.file_rename.tooltip["file"]
115107
}
116108
icon={<RiFontFamily />}
109+
onClick={() => setPopoverOpen((open) => !open)}
117110
/>
118111
</Components.Generic.Popover.Trigger>
119112
<Components.Generic.Popover.Content
@@ -124,14 +117,14 @@ export const FileRenameButton = () => {
124117
<Components.Generic.Form.TextInput
125118
name={"file-name"}
126119
icon={<RiFontFamily />}
127-
value={currentEditingName || ""}
120+
value={block.props.name}
128121
autoFocus={true}
129122
placeholder={
130123
dict.formatting_toolbar.file_rename.input_placeholder[
131124
block.type
132125
] || dict.formatting_toolbar.file_rename.input_placeholder["file"]
133126
}
134-
onKeyDown={handleEnter}
127+
onKeyDown={handleKeyDown}
135128
onChange={handleChange}
136129
/>
137130
</Components.Generic.Form.Root>

0 commit comments

Comments
 (0)