Skip to content

Commit

Permalink
fix: LSDV-5482: Fix autocomplete Escape in modal (#4692)
Browse files Browse the repository at this point in the history
* fix: LSDV-5482: Fix autocomplete Escape in modal

Don't close modal when Escape is pressed during config editing.

This switches Create Project modal's escape handler from capture to bubble event phase.

* ci: Build frontend

Workflow run: https://github.com/HumanSignal/label-studio/actions/runs/5975239509

---------

Co-authored-by: robot-ci-heartex <robot-ci-heartex@users.noreply.github.com>
  • Loading branch information
hlomzik and robot-ci-heartex committed Aug 25, 2023
1 parent dce718d commit 03c07b4
Show file tree
Hide file tree
Showing 5 changed files with 24 additions and 11 deletions.
2 changes: 1 addition & 1 deletion label_studio/frontend/dist/react-app/index.js

Large diffs are not rendered by default.

2 changes: 1 addition & 1 deletion label_studio/frontend/dist/react-app/index.js.map

Large diffs are not rendered by default.

20 changes: 12 additions & 8 deletions label_studio/frontend/src/components/Modal/ModalPopup.js
Expand Up @@ -7,7 +7,7 @@ import { aroundTransition } from '../../utils/transition';
import { Button } from '../Button/Button';
import "./Modal.styl";

const {Block, Elem} = BemWithSpecifiContext();
const { Block, Elem } = BemWithSpecifiContext();

const ModalContext = createContext();

Expand All @@ -32,11 +32,13 @@ export class Modal extends React.Component {
setTimeout(() => this.show(), 30);
}

document.addEventListener('keydown', this.closeOnEscape, {capture: true});
// with `allowToInterceptEscape` we can prevent closing modal on escape
// by handling it inside modal, before event will be bubbled here
document.addEventListener('keydown', this.closeOnEscape, { capture: !this.props.allowToInterceptEscape });
}

componentWillUnmount() {
document.removeEventListener('keydown', this.closeOnEscape, {capture: true});
document.removeEventListener('keydown', this.closeOnEscape, { capture: !this.props.allowToInterceptEscape });
}

componentDidUpdate(prevProps, prevState) {
Expand Down Expand Up @@ -71,7 +73,7 @@ export class Modal extends React.Component {
});
}

render () {
render() {
if (!this.state.visible) return null;

const bare = this.props.bare;
Expand Down Expand Up @@ -105,7 +107,7 @@ export class Modal extends React.Component {
)}
</Modal.Header>
)}
<Elem name="body" mod={{bare}}>
<Elem name="body" mod={{ bare }}>
{this.body}
</Elem>
{this.props.footer && (
Expand All @@ -124,7 +126,7 @@ export class Modal extends React.Component {

onClickOutside = (e) => {
if (!this.modalRef.current) return;
const {closeOnClickOutside} = this.props;
const { closeOnClickOutside } = this.props;
const allowClose = this.props.allowClose !== false;
const isInModal = this.modalRef.current.contains(e.target);
const content = cn('modal').elem('content').closest(e.target);
Expand Down Expand Up @@ -180,6 +182,7 @@ export class Modal extends React.Component {
get body() {
if (this.state.body) {
const Content = this.state.body;

return Content instanceof Function ? <Content/> : Content;
} else {
return this.props.children;
Expand All @@ -189,6 +192,7 @@ export class Modal extends React.Component {
get footer() {
if (this.state.footer) {
const Content = this.state.footer;

return Content instanceof Function ? <Content/> : Content;
}

Expand All @@ -197,13 +201,13 @@ export class Modal extends React.Component {
}

Modal.Header = ({ children, divided }) => (
<Elem name="header" mod={{divided}}>
<Elem name="header" mod={{ divided }}>
{children}
</Elem>
);

Modal.Footer = ({ children, bare }) => (
<Elem name="footer" mod={{bare}}>
<Elem name="footer" mod={{ bare }}>
{children}
</Elem>
);
Expand Down
Expand Up @@ -444,6 +444,8 @@ const Configurator = ({ columns, config, project, template, setTemplate, onBrows
},
hintOptions: { schemaInfo: tags },
}}
// don't close modal with Escape while editing config
onKeyDown={(editor, e) => { if (e.code === 'Escape') e.stopPropagation(); }}
onChange={(editor, data, value) => onChange(value)}
/>
</div>
Expand Down
Expand Up @@ -141,7 +141,14 @@ export const CreateProject = ({ onClose }) => {
}, [project]);

return (
<Modal onHide={onDelete} fullscreen visible bare closeOnClickOutside={false}>
<Modal
onHide={onDelete}
closeOnClickOutside={false}
allowToInterceptEscape
fullscreen
visible
bare
>
<div className={rootClass}>
<Modal.Header>
<h1>Create Project</h1>
Expand Down

0 comments on commit 03c07b4

Please sign in to comment.