Skip to content

Commit

Permalink
Merge branch 'main' into confirmation-dialog-focus-ring
Browse files Browse the repository at this point in the history
  • Loading branch information
smockle authored May 3, 2021
2 parents b2bdb66 + 7aeb53f commit 6923241
Show file tree
Hide file tree
Showing 2 changed files with 17 additions and 2 deletions.
5 changes: 5 additions & 0 deletions .changeset/twelve-jeans-kneel.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
---
"@primer/components": patch
---

Perform ActionMenu actions after overlay has closed. This allows the action to move focus if so desired, without the ActionMenu focus trap preventing focus from moving away.
14 changes: 12 additions & 2 deletions src/ActionMenu.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@ import {GroupedListProps, List, ListPropsBase} from './ActionList/List'
import {Item, ItemProps} from './ActionList/Item'
import {Divider} from './ActionList/Divider'
import Button, {ButtonProps} from './Button'
import React, {useCallback, useState} from 'react'
import React, {useCallback, useEffect, useRef, useState} from 'react'
import {AnchoredOverlay} from './AnchoredOverlay'

export interface ActionMenuProps extends Partial<Omit<GroupedListProps, keyof ListPropsBase>>, ListPropsBase {
Expand All @@ -26,6 +26,7 @@ const ActionMenuBase = ({
const [open, setOpen] = useState(false)
const onOpen = useCallback(() => setOpen(true), [])
const onClose = useCallback(() => setOpen(false), [])
const pendingActionRef = useRef<() => unknown>()

const renderMenuAnchor = useCallback(
<T extends React.HTMLAttributes<HTMLElement>>(props: T) => {
Expand All @@ -45,14 +46,23 @@ const ActionMenuBase = ({
role: 'menuitem',
onAction: (props, event) => {
const actionCallback = itemOnAction ?? onAction
actionCallback?.(props as ItemProps, event)
pendingActionRef.current = () => actionCallback?.(props as ItemProps, event)
onClose()
}
})
},
[onAction, onClose, renderItem]
)

useEffect(() => {
// Wait until menu has re-rendered in a closed state before triggering action.
// This is needed in scenarios where the action will move focus, which would otherwise be captured by focus trap
if (!open && pendingActionRef.current) {
pendingActionRef.current()
pendingActionRef.current = undefined
}
}, [open])

return (
<AnchoredOverlay renderAnchor={renderMenuAnchor} open={open} onOpen={onOpen} onClose={onClose}>
<List {...listProps} role="menu" renderItem={renderMenuItem} />
Expand Down

0 comments on commit 6923241

Please sign in to comment.