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
8 changes: 1 addition & 7 deletions src/components/modal/modal.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -72,13 +72,7 @@ export const Modal: React.FC<ModalProps> = ({
<div
className={`${className} bg-white w-80 shadow-4 sans-serif relative`}
data-testid="ipfs-modal"
style={{
maxWidth: '34em',
position: 'fixed',
top: '50%',
left: '50%',
transform: 'translate(-50%, -50%)'
}}
style={{ maxWidth: '34em' }}
{...props}
>
{onCancel && (
Expand Down
39 changes: 23 additions & 16 deletions src/components/overlay/overlay.tsx
Original file line number Diff line number Diff line change
@@ -1,30 +1,37 @@
import React from 'react'
import { Modal } from 'react-overlays'

type ModalProps = React.ComponentProps<typeof Modal>

export interface OverlayProps extends Omit<ModalProps, 'renderBackdrop' | 'onHide'> {
export interface OverlayProps {
show: boolean
onLeave: () => void
hidden: boolean
hidden?: boolean
className?: string
children?: React.ReactNode
}

const Overlay: React.FC<OverlayProps> = ({ children, show, onLeave, className = '', hidden, ...props }) => {
const renderBackdrop: React.FC<React.HTMLAttributes<HTMLDivElement>> = (props) => (
<div className='fixed top-0 left-0 right-0 bottom-0 bg-black o-50' hidden={hidden} {...props} />
)

const Overlay: React.FC<OverlayProps> = ({ children, show, onLeave, hidden }) => {
return (
// Note: react-overlays Modal manages its own portal and positioning.
// The Modal child component uses fixed positioning to center itself.
// onHide handles both backdrop clicks and escape key presses.
<Modal
{...props}
show={show}
backdrop={true}
className={`${className} z-max`}
renderBackdrop={renderBackdrop}
onHide={onLeave}>
onHide={onLeave}
renderBackdrop={(props) => (
<div className='fixed top-0 left-0 right-0 bottom-0 bg-black o-50 z-max' hidden={hidden} {...props} />
)}
renderDialog={(dialogProps) => (
// eslint-disable-next-line jsx-a11y/no-noninteractive-element-interactions, jsx-a11y/click-events-have-key-events
<div
{...dialogProps}
role='dialog'
className={`${dialogProps.className || ''} fixed top-0 left-0 right-0 bottom-0 flex justify-center items-center z-max`}
style={{ outline: 'none' }}
onClick={(e: React.MouseEvent) => {
if (e.target === e.currentTarget) onLeave()
}}
>
{children}
</div>
)}>
{children}
</Modal>
)
Expand Down
1 change: 0 additions & 1 deletion src/diagnostics/logs-screen/buffer-config-modal.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -63,7 +63,6 @@ export const BufferConfigModal: React.FC<BufferConfigModalProps> = ({
}

return (
// @ts-expect-error - Overlay is not typed
<Overlay show={isOpen} onLeave={handleCancel}>
<Modal onCancel={handleCancel} className="outline-0">
<div className='pa4'>
Expand Down
1 change: 0 additions & 1 deletion src/diagnostics/logs-screen/log-warning-modal.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -83,7 +83,6 @@ const LogWarningModal: React.FC<LogWarningModalProps> = ({
if (warningType == null) return null

return (
// @ts-expect-error - Overlay is not typed
<Overlay show={isOpen} onLeave={onClose}>
<Modal onCancel={onClose} className="outline-0">
<ModalBody>
Expand Down
7 changes: 4 additions & 3 deletions test/e2e/ipns.test.js
Original file line number Diff line number Diff line change
Expand Up @@ -114,6 +114,10 @@ test.describe('IPNS publishing', () => {
const fileRow = page.getByTestId('file-row').filter({ hasText: testFilename })
await expect(fileRow).toBeVisible()

// dismiss import notification before opening the publish modal
// (modal overlay blocks interaction with content behind it)
await dismissImportNotification(page)

// click on the context menu
await page.locator(`.File:has-text('${testFilename}') .file-context-menu`).click()

Expand All @@ -135,9 +139,6 @@ test.describe('IPNS publishing', () => {
// (ipns will fail to publish without peers)
await ipfs.swarm.connect(peerAddr)

// dismiss import notification created earlier in this test
await dismissImportNotification(page)

await publishButton.click()

// IPNS publishing can take time depending on network/DHT conditions
Expand Down