Skip to content

Commit ded74d8

Browse files
ItzaMibroccolinisoupmperrotti
authored
[Dialog] Replace deprecated Button for current one (#3084)
* feat(Dialog): use new `Button` + change `DialogButtonProps` to match it + change `autoFocus` logic so first `button` gets focus when navigating with tabs * fix(Dialog): rollback change on `focus` functionality * fix(Dialog): add support to deprecated `normal` `buttonType` * fix(Dialog): override `ButtonProps` `children` * chore(tests): update snapshots * chore(Dialog): changeset * chore(tests): update snapshots * chore(ConfirmationDialog): update tests and snapshot * Update src/__tests__/ConfirmationDialog.test.tsx Co-authored-by: Armağan <[email protected]> * import ActionList and remove unused buttonRef and extra lines * fix the import * Add changed components to .changeset/cool-schools-cheer.md --------- Co-authored-by: Armağan <[email protected]> Co-authored-by: Mike Perrotti <[email protected]>
1 parent 90a145c commit ded74d8

File tree

8 files changed

+263
-96
lines changed

8 files changed

+263
-96
lines changed

.changeset/cool-schools-cheer.md

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,6 @@
1+
---
2+
'@primer/react': minor
3+
---
4+
5+
[Dialog] Replaces deprecated button for current one
6+
<!-- Changed components: Dialog-->

src/Dialog/Dialog.tsx

Lines changed: 7 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
import React, {useCallback, useEffect, useRef, useState} from 'react'
22
import styled from 'styled-components'
3-
import Button, {ButtonPrimary, ButtonDanger, ButtonProps} from '../deprecated/Button'
3+
import {Button, ButtonProps} from '../Button'
44
import Box from '../Box'
55
import {get} from '../constants'
66
import {useOnEscapePress, useProvidedRefOrCreate} from '../hooks'
@@ -20,11 +20,11 @@ const ANIMATION_DURATION = '200ms'
2020
* Props that characterize a button to be rendered into the footer of
2121
* a Dialog.
2222
*/
23-
export type DialogButtonProps = ButtonProps & {
23+
export type DialogButtonProps = Omit<ButtonProps, 'children'> & {
2424
/**
2525
* The type of Button element to use
2626
*/
27-
buttonType?: 'normal' | 'primary' | 'danger'
27+
buttonType?: 'default' | 'primary' | 'danger' | 'normal'
2828

2929
/**
3030
* The Button's inner text
@@ -366,11 +366,6 @@ const Footer = styled.div<SxProp>`
366366
${sx};
367367
`
368368

369-
const buttonTypes = {
370-
normal: Button,
371-
primary: ButtonPrimary,
372-
danger: ButtonDanger,
373-
}
374369
const Buttons: React.FC<React.PropsWithChildren<{buttons: DialogButtonProps[]}>> = ({buttons}) => {
375370
const autoFocusRef = useProvidedRefOrCreate<HTMLButtonElement>(buttons.find(button => button.autoFocus)?.ref)
376371
let autoFocusCount = 0
@@ -387,17 +382,16 @@ const Buttons: React.FC<React.PropsWithChildren<{buttons: DialogButtonProps[]}>>
387382
return (
388383
<>
389384
{buttons.map((dialogButtonProps, index) => {
390-
const {content, buttonType = 'normal', autoFocus = false, ...buttonProps} = dialogButtonProps
391-
const ButtonElement = buttonTypes[buttonType]
385+
const {content, buttonType = 'default', autoFocus = false, ...buttonProps} = dialogButtonProps
392386
return (
393-
<ButtonElement
387+
<Button
394388
key={index}
395389
{...buttonProps}
396-
variant={buttonType}
390+
variant={buttonType === 'normal' ? 'default' : buttonType}
397391
ref={autoFocus && autoFocusCount === 0 ? (autoFocusCount++, autoFocusRef) : null}
398392
>
399393
{content}
400-
</ButtonElement>
394+
</Button>
401395
)
402396
})}
403397
</>

src/SelectPanel/__snapshots__/SelectPanel.test.tsx.snap

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,10 @@ exports[`SelectPanel renders consistently 1`] = `
77
color: #1F2328;
88
}
99
10+
.c2 {
11+
margin-left: 4px;
12+
}
13+
1014
.c1 {
1115
position: relative;
1216
display: inline-block;
@@ -71,10 +75,6 @@ exports[`SelectPanel renders consistently 1`] = `
7175
border-color: rgba(31,35,40,0.15);
7276
}
7377
74-
.c2 {
75-
margin-left: 4px;
76-
}
77-
7878
<div
7979
className="c0"
8080
color="fg.default"

src/__tests__/ConfirmationDialog.test.tsx

Lines changed: 21 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -2,10 +2,11 @@ import {render as HTMLRender, fireEvent} from '@testing-library/react'
22
import {axe} from 'jest-axe'
33
import React, {useCallback, useRef, useState} from 'react'
44

5-
import {ActionMenu} from '../deprecated/ActionMenu'
5+
import {ActionMenu} from '../ActionMenu'
6+
import {ActionList} from '../ActionList'
67
import BaseStyles from '../BaseStyles'
78
import Box from '../Box'
8-
import Button from '../deprecated/Button/Button'
9+
import {Button} from '../Button'
910
import {ConfirmationDialog, useConfirm} from '../Dialog/ConfirmationDialog'
1011
import theme from '../theme'
1112
import {ThemeProvider} from '../ThemeProvider'
@@ -62,10 +63,14 @@ const ShorthandHookFromActionMenu = () => {
6263
<SSRProvider>
6364
<BaseStyles>
6465
<Box display="flex" flexDirection="column" alignItems="flex-start">
65-
<ActionMenu
66-
renderAnchor={props => <Button {...props}>{text}</Button>}
67-
items={[{text: 'Show dialog', onAction: onButtonClick}]}
68-
/>
66+
<ActionMenu>
67+
<ActionMenu.Button>{text}</ActionMenu.Button>
68+
<ActionMenu.Overlay>
69+
<ActionList>
70+
<ActionList.Item onSelect={onButtonClick}>Show dialog</ActionList.Item>
71+
</ActionList>
72+
</ActionMenu.Overlay>
73+
</ActionMenu>
6974
</Box>
7075
</BaseStyles>
7176
</SSRProvider>
@@ -95,36 +100,36 @@ describe('ConfirmationDialog', () => {
95100
})
96101

97102
it('focuses the primary action when opened and the confirmButtonType is not set', async () => {
98-
const {getByText} = HTMLRender(<Basic />)
103+
const {getByText, getByRole} = HTMLRender(<Basic />)
99104
fireEvent.click(getByText('Show dialog'))
100-
expect(getByText('Primary')).toEqual(document.activeElement)
105+
expect(getByRole('button', {name: 'Primary'})).toEqual(document.activeElement)
101106
expect(getByText('Secondary')).not.toEqual(document.activeElement)
102107
})
103108

104109
it('focuses the primary action when opened and the confirmButtonType is not danger', async () => {
105-
const {getByText} = HTMLRender(<Basic confirmButtonType="primary" />)
110+
const {getByText, getByRole} = HTMLRender(<Basic confirmButtonType="primary" />)
106111
fireEvent.click(getByText('Show dialog'))
107-
expect(getByText('Primary')).toEqual(document.activeElement)
112+
expect(getByRole('button', {name: 'Primary'})).toEqual(document.activeElement)
108113
expect(getByText('Secondary')).not.toEqual(document.activeElement)
109114
})
110115

111116
it('focuses the secondary action when opened and the confirmButtonType is danger', async () => {
112-
const {getByText} = HTMLRender(<Basic confirmButtonType="danger" />)
117+
const {getByText, getByRole} = HTMLRender(<Basic confirmButtonType="danger" />)
113118
fireEvent.click(getByText('Show dialog'))
114-
expect(getByText('Primary')).not.toEqual(document.activeElement)
115-
expect(getByText('Secondary')).toEqual(document.activeElement)
119+
expect(getByRole('button', {name: 'Primary'})).not.toEqual(document.activeElement)
120+
expect(getByRole('button', {name: 'Secondary'})).toEqual(document.activeElement)
116121
})
117122

118123
it('supports nested `focusTrap`s', async () => {
119124
const spy = jest.spyOn(console, 'error').mockImplementationOnce(() => {})
120125

121-
const {getByText} = HTMLRender(<ShorthandHookFromActionMenu />)
126+
const {getByText, getByRole} = HTMLRender(<ShorthandHookFromActionMenu />)
122127

123128
fireEvent.click(getByText('Show menu'))
124129
fireEvent.click(getByText('Show dialog'))
125130

126-
expect(getByText('Primary')).toEqual(document.activeElement)
127-
expect(getByText('Secondary')).not.toEqual(document.activeElement)
131+
expect(getByRole('button', {name: 'Primary'})).toEqual(document.activeElement)
132+
expect(getByRole('button', {name: 'Secondary'})).not.toEqual(document.activeElement)
128133

129134
// REACT_VERSION_LATEST should be treated as a constant for the test
130135
// environment

src/__tests__/__snapshots__/AnchoredOverlay.test.tsx.snap

Lines changed: 19 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -100,6 +100,25 @@ exports[`AnchoredOverlay should render consistently when open 1`] = `
100100
color: #1F2328;
101101
}
102102
103+
.c2 {
104+
background-color: #ffffff;
105+
box-shadow: 0 1px 3px rgba(31,35,40,0.12),0 8px 24px rgba(66,74,83,0.12);
106+
position: absolute;
107+
min-width: 192px;
108+
max-width: 640px;
109+
height: auto;
110+
width: auto;
111+
border-radius: 12px;
112+
overflow: hidden;
113+
-webkit-animation: overlay-appear 200ms cubic-bezier(0.33,1,0.68,1);
114+
animation: overlay-appear 200ms cubic-bezier(0.33,1,0.68,1);
115+
visibility: var(--styled-overlay-visibility);
116+
}
117+
118+
.c2:focus {
119+
outline: none;
120+
}
121+
103122
.c1 {
104123
position: relative;
105124
display: inline-block;
@@ -164,25 +183,6 @@ exports[`AnchoredOverlay should render consistently when open 1`] = `
164183
border-color: rgba(31,35,40,0.15);
165184
}
166185
167-
.c2 {
168-
background-color: #ffffff;
169-
box-shadow: 0 1px 3px rgba(31,35,40,0.12),0 8px 24px rgba(66,74,83,0.12);
170-
position: absolute;
171-
min-width: 192px;
172-
max-width: 640px;
173-
height: auto;
174-
width: auto;
175-
border-radius: 12px;
176-
overflow: hidden;
177-
-webkit-animation: overlay-appear 200ms cubic-bezier(0.33,1,0.68,1);
178-
animation: overlay-appear 200ms cubic-bezier(0.33,1,0.68,1);
179-
visibility: var(--styled-overlay-visibility);
180-
}
181-
182-
.c2:focus {
183-
outline: none;
184-
}
185-
186186
@media (forced-colors:active) {
187187
.c2 {
188188
outline: solid 1px transparent;

0 commit comments

Comments
 (0)