Skip to content

Commit d937276

Browse files
committed
refactor: enhance persistent menu handling and maintain text selection state
1 parent 1523510 commit d937276

File tree

1 file changed

+38
-10
lines changed

1 file changed

+38
-10
lines changed

src/webchat-ui/components/plugins/input/base/BaseInput.tsx

+38-10
Original file line numberDiff line numberDiff line change
@@ -13,6 +13,7 @@ import { IFile } from "../../../../../webchat/store/input/input-reducer";
1313
import MediaQuery from "react-responsive";
1414
import PersistentMenu from "../menu/PersistentMenu";
1515
import IconButton from "../../../presentational/IconButton";
16+
import { IPersistentMenuItem } from "../../../../../common/interfaces/webchat-config";
1617

1718
const InputWrapper = styled.div(() => ({
1819
display: "flex",
@@ -140,6 +141,8 @@ const SubmitButton = styled(Button)(({ theme }) => iconButtonStyles);
140141

141142
export interface TextInputState {
142143
text: string;
144+
selectionStart: number;
145+
selectionEnd: number;
143146
}
144147

145148
interface ISpeechInputState {
@@ -215,6 +218,8 @@ export class BaseInput extends React.PureComponent<IBaseInputProps, IBaseInputSt
215218
speechResult: "",
216219
isFinalResult: false,
217220
isMenuOpen: false,
221+
selectionStart: 0,
222+
selectionEnd: 0,
218223
} as IBaseInputState;
219224
}
220225

@@ -418,10 +423,40 @@ export class BaseInput extends React.PureComponent<IBaseInputProps, IBaseInputSt
418423
}, 200);
419424
};
420425

421-
handleBlur = () => {
426+
handleBlur: React.FocusEventHandler<HTMLTextAreaElement> = e => {
422427
setTimeout(() => {
423428
this.props.onSetTextActive(false);
424429
}, 200);
430+
this.setState({
431+
selectionStart: e.target.selectionStart,
432+
selectionEnd: e.target.selectionEnd,
433+
});
434+
};
435+
436+
togglePeristentMenu = () => {
437+
this.setState(
438+
prevState => ({
439+
isMenuOpen: !prevState.isMenuOpen,
440+
}),
441+
() => {
442+
if (!this.state.isMenuOpen) {
443+
if (this.inputRef.current) {
444+
this.inputRef.current?.setSelectionRange(
445+
this.state.selectionStart,
446+
this.state.selectionEnd,
447+
);
448+
this.inputRef.current.focus();
449+
}
450+
}
451+
},
452+
);
453+
};
454+
455+
onSelectPersistentMenuItem = (item: IPersistentMenuItem) => {
456+
this.togglePeristentMenu();
457+
this.props.onSendMessage(item.payload, null, {
458+
label: item.title,
459+
});
425460
};
426461

427462
render() {
@@ -456,7 +491,7 @@ export class BaseInput extends React.PureComponent<IBaseInputProps, IBaseInputSt
456491
>
457492
{showPersistentMenu && (
458493
<MenuButton
459-
onClick={() => this.setState({ isMenuOpen: !isMenuOpen })}
494+
onClick={this.togglePeristentMenu}
460495
aria-label="Toggle persistent menu"
461496
aria-expanded={isMenuOpen}
462497
className="webchat-input-persistent-menu-button"
@@ -471,14 +506,7 @@ export class BaseInput extends React.PureComponent<IBaseInputProps, IBaseInputSt
471506
<PersistentMenu
472507
title={persistentMenu.title}
473508
menuItems={persistentMenu.menuItems}
474-
onSelect={item => {
475-
this.setState({ isMenuOpen: false });
476-
this.props.onSendMessage(item.payload, null, {
477-
label: item.title,
478-
});
479-
480-
if (this.inputRef.current) this.inputRef.current.focus();
481-
}}
509+
onSelect={this.onSelectPersistentMenuItem}
482510
/>
483511
) : (
484512
<>

0 commit comments

Comments
 (0)