Uh oh!
There was an error while loading. Please reload this page.
- Notifications
You must be signed in to change notification settings - Fork 677
experimental/SelectPanel: Update anchored position after showModal#4396
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Uh oh!
There was an error while loading. Please reload this page.
Changes from all commits
84565647e0147027613160dc5ca915c0853File filter
Filter by extension
Conversations
Uh oh!
There was an error while loading. Please reload this page.
Jump to
Uh oh!
There was an error while loading. Please reload this page.
Diff view
Diff view
There are no files selected for viewing
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,5 @@ | ||
| --- | ||
| "@primer/react": patch | ||
| --- | ||
| exerimental/SelectPanel: Fix anchored position when close to the edge of browser window |
| Original file line number | Diff line number | Diff line change | ||||
|---|---|---|---|---|---|---|
| @@ -164,11 +164,31 @@ const Panel: React.FC<SelectPanelProps> = ({ | ||||||
| /* Dialog */ | ||||||
| const dialogRef = React.useRef<HTMLDialogElement>(null) | ||||||
| /* Anchored position */ | ||||||
MemberAuthor There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Note for reviewer: This function already existed, just moved it above | ||||||
| const {position, updatePosition} = useAnchoredPosition( | ||||||
| { | ||||||
| anchorElementRef: anchorRef, | ||||||
| floatingElementRef: dialogRef, | ||||||
| side: 'outside-bottom', | ||||||
| align: 'start', | ||||||
| }, | ||||||
| [ | ||||||
| /* | ||||||
| Because we call dialog.showModal() to open the dialog, | ||||||
| we need to wait until the browser opens the dialog (giving it dimensions) | ||||||
| before updating position. (it is 0px by 0px until opened) | ||||||
| This is why we explicitly call updatePosition instead of using dependencies. | ||||||
| */ | ||||||
| ], | ||||||
| ) | ||||||
| // sync dialog open state (imperative) with internal component state | ||||||
| React.useEffect(() => { | ||||||
| if (internalOpen) dialogRef.current?.showModal() | ||||||
| else if (dialogRef.current?.open) dialogRef.current.close() | ||||||
| }, [internalOpen]) | ||||||
| if (internalOpen) { | ||||||
| dialogRef.current?.showModal() | ||||||
| updatePosition() // update the position once the dialog is open | ||||||
| } else if (dialogRef.current?.open) dialogRef.current.close() | ||||||
| ||||||
| }elseif(dialogRef.current?.open)dialogRef.current.close() | |
| }elsedialogRef.current?.close() |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Note for reviewer: This isn't scientific at all, but we need to pick a number, so based it off a 60Hz refresh rate 😅
From https://developer.mozilla.org/en-US/docs/Web/API/window/requestAnimationFrame,
The frequency of calls to the callback function will generally match the display refresh rate. The most common refresh rate is 60hz, (60 cycles/frames per second), though 75hz, 120hz, and 144hz are also widely used. requestAnimationFrame() calls are paused in most browsers when running in background tabs or hidden iframes, in order to improve performance and battery life.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
An alternative approach would be to "watch" for dialog open. Either in a recursive timeout or intersection observer, but that felt overkill!
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Note for reviewer: Need to add this if we want to delay animation