Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
43 changes: 17 additions & 26 deletions src/components/Popups/ReplyField/ReplyField.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -45,33 +45,16 @@ export default class ReplyField extends React.Component<Props, State> {
value: '',
};

editorRef: React.MutableRefObject<Editor | null> = React.createRef<Editor | null>();

constructor(props: Props) {
super(props);

const { value, cursorPosition } = props;
const contentState = ContentState.createFromText(value as string);
let prevEditorState = withMentionDecorator(EditorState.createWithContent(contentState));
let selectionState = prevEditorState.getSelection();

selectionState = selectionState.merge({
anchorOffset: cursorPosition,
focusOffset: cursorPosition,
}) as SelectionState;
prevEditorState = EditorState.forceSelection(prevEditorState, selectionState);

this.state = {
activeItemIndex: 0,
editorState: prevEditorState,
editorState: this.restoreEditor(),
popupReference: null,
};
}

componentDidMount(): void {
this.focusEditor();
}

componentWillUnmount(): void {
this.saveCursorPosition();
}
Expand Down Expand Up @@ -140,13 +123,6 @@ export default class ReplyField extends React.Component<Props, State> {
this.setState({ popupReference: activeMention ? this.getVirtualElement(activeMention) : null });
};

focusEditor = (): void => {
const { current: editor } = this.editorRef;
if (editor) {
editor.focus();
}
};

saveCursorPosition = (): void => {
const { setCursorPosition } = this.props;
const { editorState } = this.state;
Expand Down Expand Up @@ -230,6 +206,22 @@ export default class ReplyField extends React.Component<Props, State> {
this.setPopupListActiveItem(activeItemIndex === length - 1 ? 0 : activeItemIndex + 1);
};

restoreEditor(): EditorState {
const { cursorPosition: prevCursorPosition, value } = this.props;
const contentState = ContentState.createFromText(value as string);
const prevEditorState = withMentionDecorator(EditorState.createWithContent(contentState));
const cursorPosition = value ? prevCursorPosition : 0;

return EditorState.forceSelection(
prevEditorState,
prevEditorState.getSelection().merge({
anchorOffset: cursorPosition,
focusOffset: cursorPosition,
hasFocus: true,
}) as SelectionState,
);
}

render(): JSX.Element {
const { className, isDisabled, itemRowAs, placeholder, ...rest } = this.props;
const { activeItemIndex, editorState, popupReference } = this.state;
Expand All @@ -238,7 +230,6 @@ export default class ReplyField extends React.Component<Props, State> {
<div className={classnames(className, 'ba-ReplyField')}>
<Editor
{...rest}
ref={this.editorRef}
editorState={editorState}
handleReturn={this.handleReturn}
onChange={this.handleChange}
Expand Down
34 changes: 18 additions & 16 deletions src/components/Popups/ReplyField/__tests__/ReplyField-test.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -42,6 +42,24 @@ describe('components/Popups/ReplyField', () => {
const getWrapper = (props = {}): ShallowWrapper<Props, State, ReplyField> =>
shallow(<ReplyField {...defaults} {...props} />);

describe('restoreEditor()', () => {
test('should restore value and cursor position', () => {
const wrapper = getWrapper({ cursorPosition: 1, value: 'test' });

const editorState = wrapper.instance().restoreEditor();

expect(editorState.getCurrentContent().getPlainText()).toEqual('test');
expect(editorState.getSelection().getFocusOffset()).toEqual(1);
});

test('should reset cursor position if value is empty', () => {
const wrapper = getWrapper({ cursorPosition: 1 });
const editorState = wrapper.instance().restoreEditor();

expect(editorState.getSelection().getFocusOffset()).toEqual(0);
});
});

describe('render()', () => {
test('should render the editor with right props', () => {
const wrapper = getWrapper();
Expand Down Expand Up @@ -238,22 +256,6 @@ describe('components/Popups/ReplyField', () => {
});
});

describe('focusEditor()', () => {
test('should call editor ref focus', () => {
const wrapper = getWrapper();
const instance = wrapper.instance();

const editorRef = ({
focus: jest.fn(),
} as unknown) as Editor;

instance.editorRef = { current: editorRef };
instance.focusEditor();

expect(editorRef.focus).toBeCalled();
});
});

describe('saveCursorPosition()', () => {
test('should call setCursorPosition with cursor position', () => {
const wrapper = getWrapper();
Expand Down