Skip to content

Commit

Permalink
Dialog Focus Fix (#1235)
Browse files Browse the repository at this point in the history
  • Loading branch information
VanAnderson committed May 20, 2021
1 parent 0d26d2b commit e009e32
Show file tree
Hide file tree
Showing 3 changed files with 39 additions and 4 deletions.
5 changes: 5 additions & 0 deletions .changeset/tasty-mangos-think.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
---
"@primer/components": patch
---

Dialog properly auto-focuses cancel button by default when originating from a FocusZone/FocusTrap.
13 changes: 9 additions & 4 deletions src/Dialog/Dialog.tsx
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
import React, {useCallback, useEffect, useRef} from 'react'
import React, {useCallback, useEffect, useRef, useState} from 'react'
import styled from 'styled-components'
import Button, {ButtonPrimary, ButtonDanger, ButtonProps} from '../Button'
import Flex from '../Flex'
Expand Down Expand Up @@ -341,11 +341,16 @@ const buttonTypes = {
const Buttons: React.FC<{buttons: DialogButtonProps[]}> = ({buttons}) => {
const autoFocusRef = useRef<HTMLButtonElement>(null)
let autoFocusCount = 0
const [hasRendered, setHasRendered] = useState(0)
useEffect(() => {
if (autoFocusRef.current) {
autoFocusRef.current.focus()
// hack to work around dialogs originating from other focus traps.
if (hasRendered === 1) {
autoFocusRef.current?.focus()
} else {
setHasRendered(hasRendered + 1)
}
}, [])
}, [hasRendered])

return (
<>
{buttons.map((dialogButtonProps, index) => {
Expand Down
25 changes: 25 additions & 0 deletions src/stories/ConfirmationDialog.stories.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@ import {Meta} from '@storybook/react'

import {BaseStyles, Button, Flex, ThemeProvider, useTheme} from '..'
import {ConfirmationDialog, useConfirm} from '../Dialog/ConfirmationDialog'
import {ActionMenu} from '../ActionMenu'

export default {
title: 'Internal components/ConfirmationDialog',
Expand Down Expand Up @@ -78,3 +79,27 @@ export const ShorthandHook = () => {
</Flex>
)
}

export const ShorthandHookFromActionMenu = () => {
const confirm = useConfirm()
const [text, setText] = useState('open me')
const onButtonClick = useCallback(async () => {
if (await confirm({title: 'Are you sure?', content: 'Do you really want to do a trick?'})) {
setText('tada!')
}
}, [confirm])

return (
<Flex flexDirection="column" alignItems="flex-start">
<ActionMenu
renderAnchor={props => <Button {...props}>{text}</Button>}
items={[
{
text: 'Do a trick!',
onAction: onButtonClick
}
]}
/>
</Flex>
)
}

1 comment on commit e009e32

@vercel
Copy link

@vercel vercel bot commented on e009e32 May 20, 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.