From 3847778c0171a435d0b463ef2a38e10dbc76cad0 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Oddbj=C3=B8rn=20=C3=98vernes?= Date: Wed, 28 Aug 2024 13:31:13 +0200 Subject: [PATCH] =?UTF-8?q?=E2=9C=A8Popover:=20implement=20native=20[popov?= =?UTF-8?q?er]=20(#3601)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit and deprecated withinPortal --- .../components/Popover/Popover.stories.tsx | 6 -- .../src/components/Popover/Popover.test.tsx | 12 +-- .../src/components/Popover/Popover.tsx | 90 ++++++++++--------- .../__snapshots__/Popover.test.tsx.snap | 6 +- 4 files changed, 55 insertions(+), 59 deletions(-) diff --git a/packages/eds-core-react/src/components/Popover/Popover.stories.tsx b/packages/eds-core-react/src/components/Popover/Popover.stories.tsx index 4da13239e2..3041cad6e0 100644 --- a/packages/eds-core-react/src/components/Popover/Popover.stories.tsx +++ b/packages/eds-core-react/src/components/Popover/Popover.stories.tsx @@ -148,7 +148,6 @@ export const ActivateOnClick: StoryFn = () => { onClose={closePopover} open={isOpen} placement="top" - withinPortal > Title @@ -199,7 +198,6 @@ export const ActivateOnHover: StoryFn = () => { onClose={handleClose} open={isOpen} placement="top" - withinPortal > Title @@ -237,7 +235,6 @@ export const WithCloseButton: StoryFn = () => { open={isOpen} placement="top" trapFocus - withinPortal > Title @@ -297,7 +294,6 @@ export const PersistentPopover: StoryFn = () => { open={isOpen} placement="top" trapFocus - withinPortal > With Autocomplete @@ -345,7 +341,6 @@ PersistentPopover.storyName = 'Persistent popover' onClose={closePopover} open={isOpen} placement="top" - withinPortal > Title @@ -404,7 +399,6 @@ export const AppLauncher: StoryFn = () => { onClose={closePopover} placement="top" trapFocus - withinPortal > diff --git a/packages/eds-core-react/src/components/Popover/Popover.test.tsx b/packages/eds-core-react/src/components/Popover/Popover.test.tsx index 48847abe05..19d6a5cee8 100644 --- a/packages/eds-core-react/src/components/Popover/Popover.test.tsx +++ b/packages/eds-core-react/src/components/Popover/Popover.test.tsx @@ -62,19 +62,15 @@ describe('Popover', () => { await waitFor(() => expect(container).toHaveStyleRule('background', 'red')) }) - it('is visible when open is true & anchorEl is set', async () => { + it('is visible when open is true & anchorEl is set', () => { render(
some random content
, ) - const container = screen.getByTestId('popover') - await waitFor(() => { - expect(container).toBeDefined() - }) - await waitFor(() => { - expect(container).toHaveAttribute('open') - }) + const container = screen.queryByTestId('popover') + expect(container).toBeDefined() + expect(container).toBeVisible() }) it('has rendered Popover Title', async () => { diff --git a/packages/eds-core-react/src/components/Popover/Popover.tsx b/packages/eds-core-react/src/components/Popover/Popover.tsx index bf9e2b6f75..080dfb7fcd 100644 --- a/packages/eds-core-react/src/components/Popover/Popover.tsx +++ b/packages/eds-core-react/src/components/Popover/Popover.tsx @@ -14,7 +14,7 @@ import { mergeRefs, useToken, outlineTemplate, - useIsInDialog, + useIsomorphicLayoutEffect, } from '@equinor/eds-utils' import { popover as popoverToken } from './Popover.tokens' import { useEds } from '../EdsProvider' @@ -28,7 +28,6 @@ import { useFloating, useInteractions, useDismiss, - FloatingPortal, FloatingFocusManager, } from '@floating-ui/react' @@ -38,22 +37,35 @@ const PopoverPaper = styled(Paper)(({ theme }) => { } = theme return css` + position: relative; ${typographyTemplate(theme.typography)} background: ${theme.background}; ${bordersTemplate(theme.border)} - z-index: 1400; &:focus-visible { ${outlineTemplate(paper.states.focus.outline)} } ` }) +const StyledPopover = styled('div').withConfig({ + shouldForwardProp: () => true, //workaround to avoid warning until popover gets added to react types +})<{ popover: string }>` + inset: unset; + border: 0; + padding: 0; + margin: 0; + overflow: visible; + background-color: transparent; + &::backdrop { + background-color: transparent; + } +` + const ArrowWrapper = styled.div(({ theme }) => { return css` position: absolute; width: ${theme.entities.arrow.width}; height: ${theme.entities.arrow.height}; - z-index: -1; ` }) @@ -91,7 +103,9 @@ export type PopoverProps = { anchorEl?: HTMLElement | null /** Is Popover open */ open: boolean - /** initializes react portal for dropdown, default to false. */ + /** + * @deprecated Popover now uses the native popover api instead of react portal. This prop will be removed in a future version + */ withinPortal?: boolean /** Determines whether focus should be trapped within dropdown, * default to false. */ @@ -113,6 +127,11 @@ export const Popover = forwardRef( }, ref, ) { + if (withinPortal) { + console.warn( + 'Popover "withinPortal" prop has been deprecated. Popover now uses the native popover api', + ) + } const arrowRef = useRef(null) const { @@ -146,6 +165,14 @@ export const Popover = forwardRef( const { getFloatingProps } = useInteractions([useDismiss(context)]) + useIsomorphicLayoutEffect(() => { + if (open) { + refs.floating.current?.showPopover() + } else { + refs.floating.current?.hidePopover() + } + }, [open, refs.floating]) + useEffect(() => { if (arrowRef.current) { const staticSide = { @@ -183,21 +210,16 @@ export const Popover = forwardRef( }, [arrowRef.current, arrowX, arrowY, finalPlacement]) const props = { - open, ...rest, } const { density } = useEds() const token = useToken({ density }, popoverToken) - //temporary fix when inside dialog. Should be replaced by popover api when it is ready - const inDialog = useIsInDialog(anchorEl) - const popover = ( - ( }, })} > - - - - - - {children} - + + + + + + + {children} + + ) return ( <> - {withinPortal && !inDialog ? ( - - {open && trapFocus - ? open && ( - - {popover} - - ) - : open && popover} - - ) : ( - <> - {trapFocus - ? open && ( - - {popover} - - ) - : open && popover} - - )} + {trapFocus + ? open && ( + + {popover} + + ) + : open && popover} ) }, diff --git a/packages/eds-core-react/src/components/Popover/__snapshots__/Popover.test.tsx.snap b/packages/eds-core-react/src/components/Popover/__snapshots__/Popover.test.tsx.snap index 01d66032ee..ffb83dd980 100644 --- a/packages/eds-core-react/src/components/Popover/__snapshots__/Popover.test.tsx.snap +++ b/packages/eds-core-react/src/components/Popover/__snapshots__/Popover.test.tsx.snap @@ -7,6 +7,7 @@ exports[`Popover Matches snapshot 1`] = ` } .c1 { + position: relative; margin: 0; color: var(--eds_ui__accordion_header_color, rgba(61, 61, 61, 1)); font-family: Equinor; @@ -16,7 +17,6 @@ exports[`Popover Matches snapshot 1`] = ` text-align: left; background: var(--eds_ui_background__default, rgba(255, 255, 255, 1)); border-radius: 4px; - z-index: 1400; } .c1:focus-visible { @@ -28,7 +28,6 @@ exports[`Popover Matches snapshot 1`] = ` position: absolute; width: 6px; height: 8px; - z-index: -1; } .c5 { @@ -55,9 +54,6 @@ exports[`Popover Matches snapshot 1`] = `