diff --git a/apps/vr-tests-react-components/src/stories/Positioning.stories.tsx b/apps/vr-tests-react-components/src/stories/Positioning.stories.tsx index 011ad534f042e..76fd3be40f30b 100644 --- a/apps/vr-tests-react-components/src/stories/Positioning.stories.tsx +++ b/apps/vr-tests-react-components/src/stories/Positioning.stories.tsx @@ -7,11 +7,12 @@ import { PopperRefHandle, } from '@fluentui/react-positioning'; import { makeStyles, mergeClasses, shorthands } from '@griffel/react'; -import { useMergedRefs } from '@fluentui/react-utilities'; +import { useIsomorphicLayoutEffect, useMergedRefs } from '@fluentui/react-utilities'; import { tokens } from '@fluentui/react-theme'; import { storiesOf } from '@storybook/react'; import { useFluent } from '@fluentui/react-shared-contexts'; import Screener from 'screener-storybook/src/screener'; +import { Portal } from '../../../../packages/react-portal/src/index'; const useStyles = makeStyles({ wrapper: { @@ -77,6 +78,24 @@ const useStyles = makeStyles({ }, }); +const LoremParagraph = () => ( +

+ Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna + aliqua. In fermentum et sollicitudin ac orci phasellus egestas. Facilisi cras fermentum odio eu feugiat pretium nibh + ipsum consequat. Praesent semper feugiat nibh sed pulvinar proin gravida hendrerit lectus. Porta nibh venenatis cras + sed felis eget. Enim sed faucibus turpis in. Non blandit massa enim nec dui nunc mattis. Ut eu sem integer vitae + justo. Lacus vestibulum sed arcu non. Vivamus arcu felis bibendum ut. Sagittis vitae et leo duis ut diam quam nulla + porttitor. Amet est placerat in egestas erat imperdiet. Dapibus ultrices in iaculis nunc sed augue. Risus sed + vulputate odio ut enim blandit volutpat maecenas. Orci dapibus ultrices in iaculis nunc sed augue lacus. Quam + elementum pulvinar etiam non quam. Tempor commodo ullamcorper a lacus vestibulum sed arcu. Nunc non blandit massa + enim nec. Venenatis a condimentum vitae sapien. Sodales ut eu sem integer vitae justo eget magna. In aliquam sem + fringilla ut morbi tincidunt augue. Diam volutpat commodo sed egestas egestas fringilla phasellus faucibus + scelerisque. Semper eget duis at tellus. Diam donec adipiscing tristique risus nec feugiat in fermentum posuere. + Amet volutpat consequat mauris nunc congue nisi vitae. Hendrerit gravida rutrum quisque non tellus. Aliquet eget sit + amet tellus. Libero id faucibus nisl tincidunt. Amet nulla facilisi morbi tempus iaculis urna id. +

+); + const positions = [ ['above', 'start'], ['above', 'center'], @@ -354,20 +373,7 @@ const AutoSize = () => { > - Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore - magna aliqua. In fermentum et sollicitudin ac orci phasellus egestas. Facilisi cras fermentum odio eu feugiat - pretium nibh ipsum consequat. Praesent semper feugiat nibh sed pulvinar proin gravida hendrerit lectus. Porta - nibh venenatis cras sed felis eget. Enim sed faucibus turpis in. Non blandit massa enim nec dui nunc mattis. Ut - eu sem integer vitae justo. Lacus vestibulum sed arcu non. Vivamus arcu felis bibendum ut. Sagittis vitae et leo - duis ut diam quam nulla porttitor. Amet est placerat in egestas erat imperdiet. Dapibus ultrices in iaculis nunc - sed augue. Risus sed vulputate odio ut enim blandit volutpat maecenas. Orci dapibus ultrices in iaculis nunc sed - augue lacus. Quam elementum pulvinar etiam non quam. Tempor commodo ullamcorper a lacus vestibulum sed arcu. - Nunc non blandit massa enim nec. Venenatis a condimentum vitae sapien. Sodales ut eu sem integer vitae justo - eget magna. In aliquam sem fringilla ut morbi tincidunt augue. Diam volutpat commodo sed egestas egestas - fringilla phasellus faucibus scelerisque. Semper eget duis at tellus. Diam donec adipiscing tristique risus nec - feugiat in fermentum posuere. Amet volutpat consequat mauris nunc congue nisi vitae. Hendrerit gravida rutrum - quisque non tellus. Aliquet eget sit amet tellus. Libero id faucibus nisl tincidunt. Amet nulla facilisi morbi - tempus iaculis urna id. + ); @@ -570,3 +576,105 @@ storiesOf('Positioning', module) )) .addStory('arrow', () => , { includeRtl: true }); + +const ScrollJump: React.FC<{ renderPortal?: true }> = ({ renderPortal }) => { + const buttonRef = React.useRef(null); + const [open, setOpen] = React.useState(false); + + useIsomorphicLayoutEffect(() => { + if (open && buttonRef.current) { + buttonRef.current.focus(); + } + }, [open]); + + const { containerRef, targetRef } = usePopper({ + position: 'above', + align: 'start', + }); + + const floating = renderPortal ? ( + + + Focusable element {' '} + + + ) : ( + + Focusable element {' '} + + ); + + return ( +
+ + + + + + + + + + + +

+ This example simulates a scroll jump on autofocus when opening a floating element. The example uses a layout + effect to focus on the content of the floating box before usePopper is called. This results in the focus + executing before the layout effect to position the floating is executed. The scroll jump is fixed internally in + usePopper by using position: fixed on the floating element before it is first positioned. +

+ +

The result should not be 0px

+ +

+ window.scrollY: + px +

+
+ + + + + + + + {open && floating} +
+ + + +
+ ); +}; + +storiesOf('Positioning - no scroll jumps', module) + .addStory('inline', () => { + return ( + + + + ); + }) + .addStory('portal', () => { + return ( + + + + ); + });