Skip to content

Commit

Permalink
Fix cursor jumping bug in tree and comment renaming (#7390)
Browse files Browse the repository at this point in the history
* fix cursor jumping bug

* update comment

* update changelog

---------

Co-authored-by: Daniel <daniel.werner@scalableminds.com>
  • Loading branch information
philippotto and daniel-wer committed Oct 16, 2023
1 parent 0fb478f commit dec2382
Show file tree
Hide file tree
Showing 2 changed files with 31 additions and 20 deletions.
1 change: 1 addition & 0 deletions CHANGELOG.unreleased.md
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,7 @@ For upgrade instructions, please check the [migration guide](MIGRATIONS.released
### Fixed
- Fixed that some segment (group) actions were not properly disabled for non-editable segmentation layers. [#7207](https://github.com/scalableminds/webknossos/issues/7207)
- Fixed a bug where data from zarr2 datasets that have a channel axis was broken. [#7374](https://github.com/scalableminds/webknossos/pull/7374)
- Fixed a bug which changed the cursor position while editing the name of a tree or the comment of a node. [#7390](#https://github.com/scalableminds/webknossos/pull/7390)

### Removed

Expand Down
50 changes: 30 additions & 20 deletions frontend/javascripts/oxalis/view/components/input_component.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -2,14 +2,22 @@ import { Input, InputProps, InputRef, Tooltip } from "antd";
import * as React from "react";
import _ from "lodash";

type InputComponentState = {
currentValue: React.InputHTMLAttributes<HTMLInputElement>["value"];
};

/*
* A lightweight wrapper around <Input> which does:
* - automatically blur on Escape
* - maintain the cursor position / selection even when mutating the input value
* A lightweight wrapper around <Input> which:
* - automatically blurs on Escape
* - fixes cursor-jumping bugs by keeping a local copy of the input's value
* within state.currentValue. Without it, editing the name of trees or
* comments would always move the cursor to the input's end after each key press.
* The fix is inspired by https://github.com/facebook/react/issues/955#issuecomment-281802381
* - maintains the cursor position / selection even when mutating the input value
* while it's focused (mainly necessary when mutating the value on arrow-keypresses)
*/

class InputComponent extends React.PureComponent<InputProps, {}> {
class InputComponent extends React.PureComponent<InputProps, InputComponentState> {
inputRef = React.createRef<InputRef>();
static defaultProps: InputProps = {
onChange: _.noop,
Expand All @@ -18,6 +26,10 @@ class InputComponent extends React.PureComponent<InputProps, {}> {
style: {},
};

state = {
currentValue: this.props.value,
};

getSnapshotBeforeUpdate(_prevProps: InputProps, _prevState: {}): [number | null, number | null] {
// Remember the selection within the input before updating it.
try {
Expand All @@ -33,10 +45,16 @@ class InputComponent extends React.PureComponent<InputProps, {}> {
}

componentDidUpdate(
_prevProps: InputProps,
prevProps: InputProps,
_prevState: {},
snapshot: [number | null, number | null],
) {
if (prevProps.value !== this.props.value) {
this.setState({
currentValue: this.props.value,
});
}

// Restore the remembered selection when necessary
try {
// @ts-ignore
Expand All @@ -47,32 +65,24 @@ class InputComponent extends React.PureComponent<InputProps, {}> {
}

handleChange = (e: React.ChangeEvent<HTMLInputElement>) => {
this.setState({
currentValue: e.target.value,
});
if (this.props.onChange) {
this.props.onChange(e);
}
};

handleFocus = (e: React.FocusEvent<HTMLInputElement>) => {
this.setState({
isFocused: true,
});

if (this.props.onFocus) {
this.props.onFocus(e);
}
};

handleBlur = (e: React.FocusEvent<HTMLInputElement>) => {
this.setState(
{
isFocused: false,
},
() => {
if (this.props.onBlur) {
this.props.onBlur(e);
}
},
);
if (this.props.onBlur) {
this.props.onBlur(e);
}
};

blurYourself = () =>
Expand All @@ -98,7 +108,7 @@ class InputComponent extends React.PureComponent<InputProps, {}> {
onChange={this.handleChange}
onFocus={this.handleFocus}
onBlur={this.handleBlur}
value={this.props.value}
value={this.state.currentValue}
onKeyDown={this.blurOnEscape}
/>
);
Expand Down

0 comments on commit dec2382

Please sign in to comment.