diff --git a/packages/react/src/AnchoredOverlay/AnchoredOverlay.features.stories.tsx b/packages/react/src/AnchoredOverlay/AnchoredOverlay.features.stories.tsx index 3f914def820..3ceb3678d15 100644 --- a/packages/react/src/AnchoredOverlay/AnchoredOverlay.features.stories.tsx +++ b/packages/react/src/AnchoredOverlay/AnchoredOverlay.features.stories.tsx @@ -2,7 +2,7 @@ import React, {useEffect, useRef, useState} from 'react' import type {Args, Meta} from '@storybook/react' import {FocusKeys} from '@primer/behaviors' -import {Avatar, Box, Link, Text} from '..' +import {Avatar, Box, Dialog, Link, Spinner, Text} from '..' import {AnchoredOverlay} from '../AnchoredOverlay' import Heading from '../Heading' import Octicon from '../Octicon' @@ -301,3 +301,99 @@ export const OverlayPropsOverrides = () => { ) } + +export const RepositionAfterContentGrows = () => { + const [open, setOpen] = useState(false) + + const [loading, setLoading] = useState(true) + + React.useEffect(() => { + window.setTimeout(() => { + if (open) setLoading(false) + }, 2000) + }, [open]) + + return ( + +
+ What to expect: + +
+ ( + + )} + open={open} + onOpen={() => setOpen(true)} + onClose={() => { + setOpen(false) + setLoading(true) + }} + > + {loading ? ( + <> + + loading for 2000ms + + ) : ( +
content with 300px height
+ )} +
+
+ ) +} + +export const RepositionAfterContentGrowsWithinDialog = () => { + const [open, setOpen] = useState(false) + + const [loading, setLoading] = useState(true) + + React.useEffect(() => { + window.setTimeout(() => { + if (open) setLoading(false) + }, 2000) + }, [open]) + + return ( + {}}> + +
+ What to expect: +
    +
  • The anchored overlay should open below the anchor (default position)
  • +
  • After 2000ms, the amount of content in the overlay grows
  • +
  • the overlay should reposition itself above the anchor so that it stays inside the window
  • +
+
+ ( + + )} + open={open} + onOpen={() => setOpen(true)} + onClose={() => { + setOpen(false) + setLoading(true) + }} + > + {loading ? ( + <> + + loading for 2000ms + + ) : ( +
content with 300px height
+ )} +
+
+
+ ) +} diff --git a/packages/react/src/SelectPanel/SelectPanel.examples.stories.tsx b/packages/react/src/SelectPanel/SelectPanel.examples.stories.tsx index 3e261c6bce3..415800bfd43 100644 --- a/packages/react/src/SelectPanel/SelectPanel.examples.stories.tsx +++ b/packages/react/src/SelectPanel/SelectPanel.examples.stories.tsx @@ -7,6 +7,8 @@ import {SelectPanel} from './SelectPanel' import type {OverlayProps} from '../Overlay' import {TriangleDownIcon} from '@primer/octicons-react' import {ActionList} from '../deprecated/ActionList' +import {Stack} from '../Stack' +import {Dialog} from '../experimental' const meta = { title: 'Components/SelectPanel/Examples', @@ -345,3 +347,72 @@ export const ItemsInScope = () => { ) } + +export const RepositionAfterLoading = () => { + const [selected, setSelected] = React.useState([items[0], items[1]]) + const [open, setOpen] = useState(false) + const [filter, setFilter] = React.useState('') + const filteredItems = items.filter(item => item.text.toLowerCase().startsWith(filter.toLowerCase())) + const [loading, setLoading] = useState(true) + + React.useEffect(() => { + if (!open) setLoading(true) + window.setTimeout(() => { + if (open) setLoading(false) + }, 2000) + }, [open]) + + return ( + <> + +

Reposition panel after loading

+ +
+ + ) +} + +export const SelectPanelRepositionInsideDialog = () => { + const [selected, setSelected] = React.useState([items[0], items[1]]) + const [open, setOpen] = useState(false) + const [filter, setFilter] = React.useState('') + const filteredItems = items.filter(item => item.text.toLowerCase().startsWith(filter.toLowerCase())) + const [loading, setLoading] = useState(true) + + React.useEffect(() => { + if (!open) setLoading(true) + window.setTimeout(() => { + if (open) setLoading(false) + }, 2000) + }, [open]) + + return ( + {}}> + +

other content

+ +
+
+ ) +}