fix: escapes react-select events when drawer is open
This commit is contained in:
@@ -62,6 +62,7 @@ export const Drawer: React.FC<Props> = ({
|
||||
|
||||
return (
|
||||
<Modal
|
||||
trapFocus={false}
|
||||
slug={modalSlug}
|
||||
className={[
|
||||
baseClass,
|
||||
|
||||
40
src/admin/components/elements/ReactSelect/Control/index.tsx
Normal file
40
src/admin/components/elements/ReactSelect/Control/index.tsx
Normal file
@@ -0,0 +1,40 @@
|
||||
import React from 'react';
|
||||
import { components, ControlProps } from 'react-select';
|
||||
import { Option } from '../../../forms/field-types/Relationship/types';
|
||||
|
||||
export const Control: React.FC<ControlProps<Option, any>> = (props) => {
|
||||
const {
|
||||
children,
|
||||
innerProps,
|
||||
selectProps: {
|
||||
selectProps: {
|
||||
drawerIsOpen,
|
||||
},
|
||||
},
|
||||
} = props;
|
||||
|
||||
return (
|
||||
<components.Control
|
||||
{...props}
|
||||
innerProps={{
|
||||
...innerProps,
|
||||
onMouseDown: (e) => {
|
||||
// prevent react-select from hijacking the onMouseDown event while the drawer is open
|
||||
if (!drawerIsOpen) {
|
||||
innerProps.onMouseDown(e);
|
||||
}
|
||||
},
|
||||
// react-select has this typed incorrectly
|
||||
// eslint-disable-next-line @typescript-eslint/ban-ts-comment
|
||||
// @ts-ignore
|
||||
onKeyDown: (e) => {
|
||||
if (drawerIsOpen) {
|
||||
e.stopPropagation();
|
||||
}
|
||||
},
|
||||
}}
|
||||
>
|
||||
{children}
|
||||
</components.Control>
|
||||
);
|
||||
};
|
||||
@@ -1,4 +1,4 @@
|
||||
import React, { MouseEventHandler } from 'react';
|
||||
import React from 'react';
|
||||
import {
|
||||
MultiValueProps,
|
||||
components as SelectComponents,
|
||||
@@ -18,18 +18,18 @@ export const MultiValue: React.FC<MultiValueProps<OptionType>> = (props) => {
|
||||
data: {
|
||||
value,
|
||||
},
|
||||
selectProps: {
|
||||
selectProps,
|
||||
selectProps: {
|
||||
drawerIsOpen,
|
||||
},
|
||||
},
|
||||
} = props;
|
||||
|
||||
const { attributes, listeners, setNodeRef, transform } = useSortable({
|
||||
id: value as string,
|
||||
});
|
||||
|
||||
const onMouseDown: MouseEventHandler<HTMLDivElement> = (e) => {
|
||||
// prevent the dropdown from opening when clicking on the drag handle
|
||||
e.preventDefault();
|
||||
e.stopPropagation();
|
||||
};
|
||||
|
||||
const classes = [
|
||||
baseClass,
|
||||
className,
|
||||
@@ -43,7 +43,13 @@ export const MultiValue: React.FC<MultiValueProps<OptionType>> = (props) => {
|
||||
innerProps={{
|
||||
...innerProps,
|
||||
ref: setNodeRef,
|
||||
onMouseDown,
|
||||
onMouseDown: (e) => {
|
||||
if (!drawerIsOpen) {
|
||||
// prevent the dropdown from opening when clicking on the drag handle but not when the drawer is open
|
||||
e.preventDefault();
|
||||
e.stopPropagation();
|
||||
}
|
||||
},
|
||||
style: {
|
||||
...transform ? {
|
||||
transform: `translate3d(${transform.x}px, ${transform.y}px, 0)`,
|
||||
@@ -51,6 +57,7 @@ export const MultiValue: React.FC<MultiValueProps<OptionType>> = (props) => {
|
||||
},
|
||||
}}
|
||||
selectProps={{
|
||||
...selectProps,
|
||||
// NOTE: pass the draggable props to the label to act as the draggable handle
|
||||
draggableProps: {
|
||||
...attributes,
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
import React, { Fragment } from 'react';
|
||||
import React, { Fragment, useEffect } from 'react';
|
||||
import { components, MultiValueProps } from 'react-select';
|
||||
import { useDocumentDrawer } from '../../DocumentDrawer';
|
||||
import Edit from '../../../icons/Edit';
|
||||
@@ -14,21 +14,28 @@ export const MultiValueLabel: React.FC<MultiValueProps<Option>> = (props) => {
|
||||
relationTo,
|
||||
label,
|
||||
},
|
||||
selectProps,
|
||||
selectProps: {
|
||||
setDrawerIsOpen,
|
||||
draggableProps,
|
||||
},
|
||||
} = props;
|
||||
|
||||
const [DocumentDrawer, DocumentDrawerToggler] = useDocumentDrawer({
|
||||
const [DocumentDrawer, DocumentDrawerToggler, { isDrawerOpen }] = useDocumentDrawer({
|
||||
id: value?.toString(),
|
||||
collectionSlug: relationTo,
|
||||
});
|
||||
|
||||
useEffect(() => {
|
||||
if (typeof setDrawerIsOpen === 'function') setDrawerIsOpen(isDrawerOpen);
|
||||
}, [isDrawerOpen, setDrawerIsOpen]);
|
||||
|
||||
return (
|
||||
<div className={baseClass}>
|
||||
<div className={`${baseClass}__label`}>
|
||||
<components.MultiValueLabel
|
||||
{...props}
|
||||
innerProps={{
|
||||
...selectProps?.draggableProps || {},
|
||||
...draggableProps || {},
|
||||
}}
|
||||
/>
|
||||
</div>
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
import React, { Fragment } from 'react';
|
||||
import React, { Fragment, useEffect } from 'react';
|
||||
import { components, SingleValueProps } from 'react-select';
|
||||
import { useDocumentDrawer } from '../../DocumentDrawer';
|
||||
import Edit from '../../../icons/Edit';
|
||||
@@ -15,13 +15,22 @@ export const SingleValue: React.FC<SingleValueProps<Option>> = (props) => {
|
||||
label,
|
||||
},
|
||||
children,
|
||||
selectProps: {
|
||||
selectProps: {
|
||||
setDrawerIsOpen,
|
||||
},
|
||||
},
|
||||
} = props;
|
||||
|
||||
const [DocumentDrawer, DocumentDrawerToggler] = useDocumentDrawer({
|
||||
const [DocumentDrawer, DocumentDrawerToggler, { isDrawerOpen }] = useDocumentDrawer({
|
||||
id: value.toString(),
|
||||
collectionSlug: relationTo,
|
||||
});
|
||||
|
||||
useEffect(() => {
|
||||
if (typeof setDrawerIsOpen === 'function') setDrawerIsOpen(isDrawerOpen);
|
||||
}, [isDrawerOpen, setDrawerIsOpen]);
|
||||
|
||||
return (
|
||||
<div className={baseClass}>
|
||||
<div className={`${baseClass}__label`}>
|
||||
|
||||
@@ -24,6 +24,7 @@ import { MultiValue } from './MultiValue';
|
||||
import { SingleValue } from './SingleValue';
|
||||
import { ValueContainer } from './ValueContainer';
|
||||
import { ClearIndicator } from './ClearIndicator';
|
||||
import { Control } from './Control';
|
||||
import './index.scss';
|
||||
|
||||
const SelectAdapter: React.FC<Props> = (props) => {
|
||||
@@ -44,8 +45,11 @@ const SelectAdapter: React.FC<Props> = (props) => {
|
||||
onMenuOpen,
|
||||
components,
|
||||
droppableRef,
|
||||
selectProps,
|
||||
} = props;
|
||||
|
||||
const [drawerIsOpen, setDrawerIsOpen] = React.useState(false);
|
||||
|
||||
const classes = [
|
||||
className,
|
||||
'react-select',
|
||||
@@ -69,6 +73,9 @@ const SelectAdapter: React.FC<Props> = (props) => {
|
||||
filterOption={filterOption}
|
||||
onMenuOpen={onMenuOpen}
|
||||
selectProps={{
|
||||
...selectProps,
|
||||
drawerIsOpen,
|
||||
setDrawerIsOpen,
|
||||
droppableRef,
|
||||
}}
|
||||
components={{
|
||||
@@ -78,6 +85,7 @@ const SelectAdapter: React.FC<Props> = (props) => {
|
||||
MultiValueLabel,
|
||||
DropdownIndicator: Chevron,
|
||||
ClearIndicator,
|
||||
Control,
|
||||
...components,
|
||||
}}
|
||||
/>
|
||||
|
||||
@@ -36,4 +36,7 @@ export type Props = {
|
||||
components?: {
|
||||
[key: string]: React.FC<any>
|
||||
}
|
||||
selectProps?: {
|
||||
[key: string]: unknown
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user