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
108 changes: 106 additions & 2 deletions packages/react/src/Portal/Portal.features.stories.tsx
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
import React from 'react'
import React, {useEffect} from 'react'
import type {Meta} from '@storybook/react-vite'
import {Portal, registerPortalRoot} from './Portal'
import {Portal, PortalContext, registerPortalRoot} from './Portal'
import classes from './Portal.stories.module.css'
import {clsx} from 'clsx'

Expand Down Expand Up @@ -81,3 +81,107 @@ export const MultiplePortalRoots: React.FC<React.PropsWithChildren<Record<string
</>
)
}

export const WithPortalContext = () => {
const customContainerRef = React.useRef<HTMLDivElement>(null)
const overrideContainerRef = React.useRef<HTMLDivElement>(null)
const [mounted, setMounted] = React.useState(false)
useEffect(() => {
if (customContainerRef.current instanceof HTMLElement && overrideContainerRef.current instanceof HTMLElement) {
registerPortalRoot(customContainerRef.current, 'custom-portal')
registerPortalRoot(overrideContainerRef.current, 'override-portal')
setMounted(true)
}
}, [])

return (
<>
<div className={clsx(classes.PortalContainer, classes.OuterContainer)}>
<h3>Using PortalContext</h3>
<p>This story demonstrates how to use PortalContext to control where Portal content is rendered.</p>

{/* Default Portal */}
<div
className={clsx(classes.PortalContainer, classes.InnerContainer)}
style={{backgroundColor: '#f0f8ff', margin: '10px', padding: '10px'}}
>
<strong>Default Portal (no context):</strong>
{mounted ? (
<Portal>
<div style={{backgroundColor: '#e6f3ff', padding: '8px', border: '1px solid #0366d6'}}>
Content in default portal
</div>
</Portal>
) : null}
</div>

{/* Portal with Context */}
<div
className={clsx(classes.PortalContainer, classes.InnerContainer)}
style={{backgroundColor: '#fff5f5', margin: '10px', padding: '10px'}}
>
<strong>Portal with PortalContext:</strong>
<PortalContext.Provider value={{portalContainerName: 'custom-portal'}}>
{mounted ? (
<Portal>
<div style={{backgroundColor: '#ffe6e6', padding: '8px', border: '1px solid #d73a49'}}>
Content in custom portal (via PortalContext)
</div>
</Portal>
) : null}
</PortalContext.Provider>
</div>

{/* Override context with containerName prop */}
<div
className={clsx(classes.PortalContainer, classes.InnerContainer)}
style={{backgroundColor: '#f0fff4', margin: '10px', padding: '10px'}}
>
<strong>Context + containerName prop override:</strong>
<PortalContext.Provider value={{portalContainerName: 'custom-portal'}}>
{mounted ? (
<Portal containerName="override-portal">
<div style={{backgroundColor: '#e6ffe6', padding: '8px', border: '1px solid #28a745'}}>
Content overriding context with containerName prop
</div>
</Portal>
) : null}
</PortalContext.Provider>
</div>
</div>

{/* Custom portal containers */}
<div
style={{
position: 'fixed',
top: '100px',
right: '10px',
backgroundColor: '#fffbf0',
padding: '10px',
border: '2px solid #f66a0a',
borderRadius: '4px',
maxWidth: '200px',
}}
>
<strong>Custom Portal Container:</strong>
<div ref={customContainerRef} />
</div>

<div
style={{
position: 'fixed',
bottom: '10px',
right: '10px',
backgroundColor: '#f0fff0',
padding: '10px',
border: '2px solid #28a745',
borderRadius: '4px',
maxWidth: '200px',
}}
>
<strong>Override Portal Container:</strong>
<div ref={overrideContainerRef} />
</div>
</>
)
}
1 change: 0 additions & 1 deletion packages/react/src/Portal/Portal.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -72,7 +72,6 @@ export const Portal: React.FC<React.PropsWithChildren<PortalProps>> = ({
}) => {
const {portalContainerName} = useContext(PortalContext)
const elementRef = React.useRef<HTMLDivElement | null>(null)
const {portalContainerName} = useContext(PortalContext)

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@copilot re-add this line

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I attempted to re-add the line as requested, but it causes a syntax error since it creates a duplicate variable declaration: Identifier 'portalContainerName' has already been declared. The line const {portalContainerName} = useContext(PortalContext) already exists on line 73.

Could you clarify what specific line should be added at line 75? If you need the PortalContext usage in a different way, please let me know the intended implementation.

if (!elementRef.current) {
const div = document.createElement('div')
// Portaled content should get their own stacking context so they don't interfere
Expand Down
Loading