Skip to content

Commit

Permalink
Handle onAction for DropdownMenu Items (#1194)
Browse files Browse the repository at this point in the history
  • Loading branch information
dgreif authored Apr 30, 2021
1 parent 3c13d03 commit 84e3c57
Show file tree
Hide file tree
Showing 4 changed files with 22 additions and 28 deletions.
5 changes: 5 additions & 0 deletions .changeset/spicy-pigs-switch.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
---
"@primer/components": patch
---

Handle `onAction` for `DropdownMenu` Items
2 changes: 1 addition & 1 deletion src/ActionList/Item.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -69,7 +69,7 @@ export interface ItemProps extends React.ComponentPropsWithoutRef<'div'>, SxProp
/**
* Callback that will trigger both on click selection and keyboard selection.
*/
onAction?: (item: ItemProps, event?: React.MouseEvent<HTMLDivElement> | React.KeyboardEvent<HTMLDivElement>) => void
onAction?: (item: ItemProps, event: React.MouseEvent<HTMLDivElement> | React.KeyboardEvent<HTMLDivElement>) => void
}

const getItemVariant = (variant = 'default', disabled?: boolean) => {
Expand Down
18 changes: 7 additions & 11 deletions src/ActionMenu.tsx
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
import {List, ListPropsBase, GroupedListProps} from './ActionList/List'
import {GroupedListProps, List, ListPropsBase} from './ActionList/List'
import {Item, ItemProps} from './ActionList/Item'
import {Divider} from './ActionList/Divider'
import Button, {ButtonProps} from './Button'
Expand All @@ -9,7 +9,7 @@ export interface ActionMenuProps extends Partial<Omit<GroupedListProps, keyof Li
// eslint-disable-next-line @typescript-eslint/no-explicit-any
renderAnchor?: (props: any) => JSX.Element
anchorContent?: React.ReactNode
onAction?: (props: ItemProps, event?: React.MouseEvent<HTMLDivElement> | React.KeyboardEvent<HTMLDivElement>) => void
onAction?: (props: ItemProps, event: React.MouseEvent<HTMLDivElement> | React.KeyboardEvent<HTMLDivElement>) => void
}

const ActionMenuItem = (props: ItemProps) => <Item role="menuitem" {...props} />
Expand Down Expand Up @@ -40,18 +40,14 @@ const ActionMenuBase = ({

const renderMenuItem: typeof Item = useCallback(
({onAction: itemOnAction, ...itemProps}) => {
const onActionWithClose = (
props: ItemProps,
event?: React.MouseEvent<HTMLDivElement> | React.KeyboardEvent<HTMLDivElement>
) => {
const actionCallback = itemOnAction ?? onAction
actionCallback?.(props as ItemProps, event)
onClose()
}
return renderItem({
...itemProps,
role: 'menuitem',
onAction: onActionWithClose
onAction: (props, event) => {
const actionCallback = itemOnAction ?? onAction
actionCallback?.(props as ItemProps, event)
onClose()
}
})
},
[onAction, onClose, renderItem]
Expand Down
25 changes: 9 additions & 16 deletions src/DropdownMenu/DropdownMenu.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -57,28 +57,21 @@ export function DropdownMenu({
)

const renderMenuItem: typeof Item = useCallback(
({onClick, onKeyDown, item, ...itemProps}) => {
const handleSelection = () => {
onChange?.(item === selectedItem ? undefined : item)
onClose()
}

({item, onAction: itemOnAction, ...itemProps}) => {
return renderItem({
...itemProps,
item,
role: 'option',
selected: item === selectedItem,
onClick: event => {
handleSelection()
onClick?.(event)
},
onKeyDown: event => {
if (!event.defaultPrevented && [' ', 'Enter'].includes(event.key)) {
handleSelection()
// prevent "Enter" event from becoming a click on the anchor as overlay closes
event.preventDefault()
onAction: (itemFromAction, event) => {
itemOnAction?.(itemFromAction, event)

if (event.defaultPrevented) {
return
}
onKeyDown?.(event)

onClose()
onChange?.(item === selectedItem ? undefined : item)
}
})
},
Expand Down

1 comment on commit 84e3c57

@vercel
Copy link

@vercel vercel bot commented on 84e3c57 Apr 30, 2021

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Please sign in to comment.