Fix drag-and-drop interaction with ComposeModal

This commit is contained in:
Alex Gleason 2023-04-21 17:13:40 -05:00
parent c9037f6661
commit 0904b6a2a0
No known key found for this signature in database
GPG Key ID: 7211D1F99744FBB7
5 changed files with 29 additions and 11 deletions

View File

@ -55,10 +55,11 @@ interface IModal {
title?: React.ReactNode title?: React.ReactNode
width?: keyof typeof widths width?: keyof typeof widths
children?: React.ReactNode children?: React.ReactNode
className?: string
} }
/** Displays a modal dialog box. */ /** Displays a modal dialog box. */
const Modal: React.FC<IModal> = ({ const Modal = React.forwardRef<HTMLDivElement, IModal>(({
cancelAction, cancelAction,
cancelText, cancelText,
children, children,
@ -76,7 +77,8 @@ const Modal: React.FC<IModal> = ({
skipFocus = false, skipFocus = false,
title, title,
width = 'xl', width = 'xl',
}) => { className,
}, ref) => {
const intl = useIntl(); const intl = useIntl();
const buttonRef = React.useRef<HTMLButtonElement>(null); const buttonRef = React.useRef<HTMLButtonElement>(null);
@ -87,7 +89,11 @@ const Modal: React.FC<IModal> = ({
}, [skipFocus, buttonRef]); }, [skipFocus, buttonRef]);
return ( return (
<div data-testid='modal' className={clsx('pointer-events-auto mx-auto block w-full rounded-2xl bg-white p-6 text-start align-middle text-gray-900 shadow-xl transition-all dark:bg-primary-900 dark:text-gray-100', widths[width])}> <div
ref={ref}
data-testid='modal'
className={clsx(className, 'pointer-events-auto mx-auto block w-full rounded-2xl bg-white p-6 text-start align-middle text-gray-900 shadow-xl transition-all dark:bg-primary-900 dark:text-gray-100', widths[width])}
>
<div className='w-full justify-between sm:flex sm:items-start'> <div className='w-full justify-between sm:flex sm:items-start'>
<div className='w-full'> <div className='w-full'>
{title && ( {title && (
@ -157,6 +163,6 @@ const Modal: React.FC<IModal> = ({
)} )}
</div> </div>
); );
}; });
export default Modal; export default Modal;

View File

@ -69,7 +69,7 @@ const GroupTimeline: React.FC<IGroupTimeline> = (props) => {
alignItems='start' alignItems='start'
space={4} space={4}
className={clsx('relative rounded-xl transition', { className={clsx('relative rounded-xl transition', {
'border-2 border-primary-600 border-dashed z-[9001] p-4': isDragging, 'border-2 border-primary-600 border-dashed z-[99] p-4': isDragging,
'ring-2 ring-offset-2 ring-primary-600': isDraggedOver, 'ring-2 ring-offset-2 ring-primary-600': isDraggedOver,
})} })}
> >

View File

@ -1,11 +1,12 @@
import React from 'react'; import clsx from 'clsx';
import React, { useRef } from 'react';
import { defineMessages, FormattedMessage, useIntl } from 'react-intl'; import { defineMessages, FormattedMessage, useIntl } from 'react-intl';
import { cancelReplyCompose } from 'soapbox/actions/compose'; import { cancelReplyCompose, uploadCompose } from 'soapbox/actions/compose';
import { openModal, closeModal } from 'soapbox/actions/modals'; import { openModal, closeModal } from 'soapbox/actions/modals';
import { checkComposeContent } from 'soapbox/components/modal-root'; import { checkComposeContent } from 'soapbox/components/modal-root';
import { Modal } from 'soapbox/components/ui'; import { Modal } from 'soapbox/components/ui';
import { useAppDispatch, useCompose } from 'soapbox/hooks'; import { useAppDispatch, useCompose, useDraggedFiles } from 'soapbox/hooks';
import ComposeForm from '../../../compose/components/compose-form'; import ComposeForm from '../../../compose/components/compose-form';
@ -22,11 +23,17 @@ interface IComposeModal {
const ComposeModal: React.FC<IComposeModal> = ({ onClose }) => { const ComposeModal: React.FC<IComposeModal> = ({ onClose }) => {
const intl = useIntl(); const intl = useIntl();
const dispatch = useAppDispatch(); const dispatch = useAppDispatch();
const node = useRef<HTMLDivElement>(null);
const compose = useCompose('compose-modal'); const composeId = 'compose-modal';
const compose = useCompose(composeId);
const { id: statusId, privacy, in_reply_to: inReplyTo, quote } = compose!; const { id: statusId, privacy, in_reply_to: inReplyTo, quote } = compose!;
const { isDragging, isDraggedOver } = useDraggedFiles(node, (files) => {
dispatch(uploadCompose(composeId, files, intl));
});
const onClickClose = () => { const onClickClose = () => {
if (checkComposeContent(compose)) { if (checkComposeContent(compose)) {
dispatch(openModal('CONFIRM', { dispatch(openModal('CONFIRM', {
@ -64,8 +71,13 @@ const ComposeModal: React.FC<IComposeModal> = ({ onClose }) => {
return ( return (
<Modal <Modal
ref={node}
title={renderTitle()} title={renderTitle()}
onClose={onClickClose} onClose={onClickClose}
className={clsx({
'border-2 border-primary-600 border-dashed !z-[99]': isDragging,
'ring-2 ring-offset-2 ring-primary-600': isDraggedOver,
})}
> >
<ComposeForm id='compose-modal' /> <ComposeForm id='compose-modal' />
</Modal> </Modal>

View File

@ -634,7 +634,7 @@ const UI: React.FC<IUI> = ({ children }) => {
<HotKeys keyMap={keyMap} handlers={me ? handlers : undefined} ref={setHotkeysRef} attach={window} focused> <HotKeys keyMap={keyMap} handlers={me ? handlers : undefined} ref={setHotkeysRef} attach={window} focused>
<div ref={node} style={style}> <div ref={node} style={style}>
<div <div
className={clsx('pointer-events-none fixed z-[9000] h-screen w-screen transition', { className={clsx('pointer-events-none fixed z-[90] h-screen w-screen transition', {
'backdrop-blur': isDragging, 'backdrop-blur': isDragging,
})} })}
/> />

View File

@ -56,7 +56,7 @@ const HomePage: React.FC<IHomePage> = ({ children }) => {
{me && ( {me && (
<Card <Card
className={clsx('relative z-[1] transition', { className={clsx('relative z-[1] transition', {
'border-2 border-primary-600 border-dashed z-[9001]': isDragging, 'border-2 border-primary-600 border-dashed z-[99]': isDragging,
'ring-2 ring-offset-2 ring-primary-600': isDraggedOver, 'ring-2 ring-offset-2 ring-primary-600': isDraggedOver,
})} })}
variant='rounded' variant='rounded'