diff --git a/.changeset/cool-schools-cheer.md b/.changeset/cool-schools-cheer.md new file mode 100644 index 00000000000..c4296018733 --- /dev/null +++ b/.changeset/cool-schools-cheer.md @@ -0,0 +1,6 @@ +--- +'@primer/react': minor +--- + +[Dialog] Replaces deprecated button for current one + diff --git a/src/Dialog/Dialog.tsx b/src/Dialog/Dialog.tsx index 1db909aac6e..242a02192f3 100644 --- a/src/Dialog/Dialog.tsx +++ b/src/Dialog/Dialog.tsx @@ -1,6 +1,6 @@ import React, {useCallback, useEffect, useRef, useState} from 'react' import styled from 'styled-components' -import Button, {ButtonPrimary, ButtonDanger, ButtonProps} from '../deprecated/Button' +import {Button, ButtonProps} from '../Button' import Box from '../Box' import {get} from '../constants' import {useOnEscapePress, useProvidedRefOrCreate} from '../hooks' @@ -20,11 +20,11 @@ const ANIMATION_DURATION = '200ms' * Props that characterize a button to be rendered into the footer of * a Dialog. */ -export type DialogButtonProps = ButtonProps & { +export type DialogButtonProps = Omit & { /** * The type of Button element to use */ - buttonType?: 'normal' | 'primary' | 'danger' + buttonType?: 'default' | 'primary' | 'danger' | 'normal' /** * The Button's inner text @@ -366,11 +366,6 @@ const Footer = styled.div` ${sx}; ` -const buttonTypes = { - normal: Button, - primary: ButtonPrimary, - danger: ButtonDanger, -} const Buttons: React.FC> = ({buttons}) => { const autoFocusRef = useProvidedRefOrCreate(buttons.find(button => button.autoFocus)?.ref) let autoFocusCount = 0 @@ -387,17 +382,16 @@ const Buttons: React.FC> return ( <> {buttons.map((dialogButtonProps, index) => { - const {content, buttonType = 'normal', autoFocus = false, ...buttonProps} = dialogButtonProps - const ButtonElement = buttonTypes[buttonType] + const {content, buttonType = 'default', autoFocus = false, ...buttonProps} = dialogButtonProps return ( - {content} - + ) })} diff --git a/src/SelectPanel/__snapshots__/SelectPanel.test.tsx.snap b/src/SelectPanel/__snapshots__/SelectPanel.test.tsx.snap index 1c2aff6eeb8..ed7d0dc6442 100644 --- a/src/SelectPanel/__snapshots__/SelectPanel.test.tsx.snap +++ b/src/SelectPanel/__snapshots__/SelectPanel.test.tsx.snap @@ -7,6 +7,10 @@ exports[`SelectPanel renders consistently 1`] = ` color: #1F2328; } +.c2 { + margin-left: 4px; +} + .c1 { position: relative; display: inline-block; @@ -71,10 +75,6 @@ exports[`SelectPanel renders consistently 1`] = ` border-color: rgba(31,35,40,0.15); } -.c2 { - margin-left: 4px; -} -
{ - } - items={[{text: 'Show dialog', onAction: onButtonClick}]} - /> + + {text} + + + Show dialog + + + @@ -95,36 +100,36 @@ describe('ConfirmationDialog', () => { }) it('focuses the primary action when opened and the confirmButtonType is not set', async () => { - const {getByText} = HTMLRender() + const {getByText, getByRole} = HTMLRender() fireEvent.click(getByText('Show dialog')) - expect(getByText('Primary')).toEqual(document.activeElement) + expect(getByRole('button', {name: 'Primary'})).toEqual(document.activeElement) expect(getByText('Secondary')).not.toEqual(document.activeElement) }) it('focuses the primary action when opened and the confirmButtonType is not danger', async () => { - const {getByText} = HTMLRender() + const {getByText, getByRole} = HTMLRender() fireEvent.click(getByText('Show dialog')) - expect(getByText('Primary')).toEqual(document.activeElement) + expect(getByRole('button', {name: 'Primary'})).toEqual(document.activeElement) expect(getByText('Secondary')).not.toEqual(document.activeElement) }) it('focuses the secondary action when opened and the confirmButtonType is danger', async () => { - const {getByText} = HTMLRender() + const {getByText, getByRole} = HTMLRender() fireEvent.click(getByText('Show dialog')) - expect(getByText('Primary')).not.toEqual(document.activeElement) - expect(getByText('Secondary')).toEqual(document.activeElement) + expect(getByRole('button', {name: 'Primary'})).not.toEqual(document.activeElement) + expect(getByRole('button', {name: 'Secondary'})).toEqual(document.activeElement) }) it('supports nested `focusTrap`s', async () => { const spy = jest.spyOn(console, 'error').mockImplementationOnce(() => {}) - const {getByText} = HTMLRender() + const {getByText, getByRole} = HTMLRender() fireEvent.click(getByText('Show menu')) fireEvent.click(getByText('Show dialog')) - expect(getByText('Primary')).toEqual(document.activeElement) - expect(getByText('Secondary')).not.toEqual(document.activeElement) + expect(getByRole('button', {name: 'Primary'})).toEqual(document.activeElement) + expect(getByRole('button', {name: 'Secondary'})).not.toEqual(document.activeElement) // REACT_VERSION_LATEST should be treated as a constant for the test // environment diff --git a/src/__tests__/__snapshots__/AnchoredOverlay.test.tsx.snap b/src/__tests__/__snapshots__/AnchoredOverlay.test.tsx.snap index c01e1a5cfaf..359244ccee2 100644 --- a/src/__tests__/__snapshots__/AnchoredOverlay.test.tsx.snap +++ b/src/__tests__/__snapshots__/AnchoredOverlay.test.tsx.snap @@ -100,6 +100,25 @@ exports[`AnchoredOverlay should render consistently when open 1`] = ` color: #1F2328; } +.c2 { + background-color: #ffffff; + box-shadow: 0 1px 3px rgba(31,35,40,0.12),0 8px 24px rgba(66,74,83,0.12); + position: absolute; + min-width: 192px; + max-width: 640px; + height: auto; + width: auto; + border-radius: 12px; + overflow: hidden; + -webkit-animation: overlay-appear 200ms cubic-bezier(0.33,1,0.68,1); + animation: overlay-appear 200ms cubic-bezier(0.33,1,0.68,1); + visibility: var(--styled-overlay-visibility); +} + +.c2:focus { + outline: none; +} + .c1 { position: relative; display: inline-block; @@ -164,25 +183,6 @@ exports[`AnchoredOverlay should render consistently when open 1`] = ` border-color: rgba(31,35,40,0.15); } -.c2 { - background-color: #ffffff; - box-shadow: 0 1px 3px rgba(31,35,40,0.12),0 8px 24px rgba(66,74,83,0.12); - position: absolute; - min-width: 192px; - max-width: 640px; - height: auto; - width: auto; - border-radius: 12px; - overflow: hidden; - -webkit-animation: overlay-appear 200ms cubic-bezier(0.33,1,0.68,1); - animation: overlay-appear 200ms cubic-bezier(0.33,1,0.68,1); - visibility: var(--styled-overlay-visibility); -} - -.c2:focus { - outline: none; -} - @media (forced-colors:active) { .c2 { outline: solid 1px transparent; diff --git a/src/__tests__/__snapshots__/ConfirmationDialog.test.tsx.snap b/src/__tests__/__snapshots__/ConfirmationDialog.test.tsx.snap index 1d33d06ccb4..158b2d7dab2 100644 --- a/src/__tests__/__snapshots__/ConfirmationDialog.test.tsx.snap +++ b/src/__tests__/__snapshots__/ConfirmationDialog.test.tsx.snap @@ -7,68 +7,218 @@ exports[`ConfirmationDialog renders consistently 1`] = ` color: #1F2328; } +.c2 { + -webkit-box-pack: center; + -webkit-justify-content: center; + -ms-flex-pack: center; + justify-content: center; +} + .c1 { - position: relative; - display: inline-block; - padding: 6px 16px; + border-radius: 6px; + border: 1px solid; + border-color: rgba(31,35,40,0.15); font-family: inherit; - font-weight: 600; - line-height: 20px; - white-space: nowrap; - vertical-align: middle; + font-weight: 500; + font-size: 14px; cursor: pointer; + -webkit-appearance: none; + -moz-appearance: none; + appearance: none; -webkit-user-select: none; -moz-user-select: none; -ms-user-select: none; user-select: none; - border-radius: 6px; - -webkit-appearance: none; - -moz-appearance: none; - appearance: none; -webkit-text-decoration: none; text-decoration: none; text-align: center; - font-size: 14px; + display: -webkit-box; + display: -webkit-flex; + display: -ms-flexbox; + display: flex; + -webkit-align-items: center; + -webkit-box-align: center; + -ms-flex-align: center; + align-items: center; + -webkit-box-pack: justify; + -webkit-justify-content: space-between; + -ms-flex-pack: justify; + justify-content: space-between; + height: 32px; + padding: 0 12px; + gap: 8px; + min-width: -webkit-max-content; + min-width: -moz-max-content; + min-width: max-content; + -webkit-transition: 80ms cubic-bezier(0.65,0,0.35,1); + transition: 80ms cubic-bezier(0.65,0,0.35,1); + -webkit-transition-property: color,fill,background-color,border-color; + transition-property: color,fill,background-color,border-color; color: #24292f; background-color: #f6f8fa; - border: 1px solid rgba(31,35,40,0.15); box-shadow: 0 1px 0 rgba(31,35,40,0.04),inset 0 1px 0 rgba(255,255,255,0.25); } -.c1:hover { +.c1:focus:not(:disabled) { + box-shadow: none; + outline: 2px solid #0969da; + outline-offset: -2px; +} + +.c1:focus:not(:disabled):not(:focus-visible) { + outline: solid 1px transparent; +} + +.c1:focus-visible:not(:disabled) { + box-shadow: none; + outline: 2px solid #0969da; + outline-offset: -2px; +} + +.c1[href] { + display: -webkit-inline-box; + display: -webkit-inline-flex; + display: -ms-inline-flexbox; + display: inline-flex; +} + +.c1[href]:hover { -webkit-text-decoration: none; text-decoration: none; } -.c1:focus { - outline: none; +.c1:hover { + -webkit-transition-duration: 80ms; + transition-duration: 80ms; +} + +.c1:active { + -webkit-transition: none; + transition: none; } .c1:disabled { - cursor: default; + cursor: not-allowed; + box-shadow: none; + color: #8c959f; } -.c1:disabled svg { - opacity: 0.6; +.c1:disabled [data-component=ButtonCounter] { + color: inherit; } -.c1:hover { +.c1 [data-component=ButtonCounter] { + font-size: 14px; +} + +.c1[data-component=IconButton] { + display: inline-grid; + padding: unset; + place-content: center; + width: 32px; + min-width: unset; +} + +.c1[data-size="small"] { + padding: 0 8px; + height: 28px; + gap: 4px; + font-size: 12px; +} + +.c1[data-size="small"] [data-component="text"] { + line-height: calc(20 / 12); +} + +.c1[data-size="small"] [data-component=ButtonCounter] { + font-size: 12px; +} + +.c1[data-size="small"] [data-component="buttonContent"] > :not(:last-child) { + margin-right: 4px; +} + +.c1[data-size="small"][data-component=IconButton] { + width: 28px; + padding: unset; +} + +.c1[data-size="large"] { + padding: 0 16px; + height: 40px; + gap: 8px; +} + +.c1[data-size="large"] [data-component="buttonContent"] > :not(:last-child) { + margin-right: 8px; +} + +.c1[data-size="large"][data-component=IconButton] { + width: 40px; + padding: unset; +} + +.c1[data-block="block"] { + width: 100%; +} + +.c1 [data-component="leadingVisual"] { + grid-area: leadingVisual; +} + +.c1 [data-component="text"] { + grid-area: text; + line-height: calc(20/14); + white-space: nowrap; +} + +.c1 [data-component="trailingVisual"] { + grid-area: trailingVisual; +} + +.c1 [data-component="trailingAction"] { + margin-right: -4px; +} + +.c1 [data-component="buttonContent"] { + -webkit-flex: 1 0 auto; + -ms-flex: 1 0 auto; + flex: 1 0 auto; + display: grid; + grid-template-areas: "leadingVisual text trailingVisual"; + grid-template-columns: min-content minmax(0,auto) min-content; + -webkit-align-items: center; + -webkit-box-align: center; + -ms-flex-align: center; + align-items: center; + -webkit-align-content: center; + -ms-flex-line-pack: center; + align-content: center; +} + +.c1 [data-component="buttonContent"] > :not(:last-child) { + margin-right: 8px; +} + +.c1:hover:not([disabled]) { background-color: #f3f4f6; border-color: rgba(31,35,40,0.15); } -.c1:focus { - outline: solid 2px #0969da; +.c1:active:not([disabled]) { + background-color: hsla(220,14%,93%,1); + border-color: rgba(31,35,40,0.15); } -.c1:active { - background-color: hsla(220,14%,94%,1); +.c1[aria-expanded=true] { + background-color: hsla(220,14%,93%,1); + border-color: rgba(31,35,40,0.15); } -.c1:disabled { - color: #8c959f; - background-color: #f6f8fa; - border-color: rgba(31,35,40,0.15); +@media (forced-colors:active) { + .c1:focus { + outline: solid 1px transparent; + } }
`; diff --git a/src/__tests__/__snapshots__/Dialog.test.tsx.snap b/src/__tests__/__snapshots__/Dialog.test.tsx.snap index 62d088691e3..c2b293951fa 100644 --- a/src/__tests__/__snapshots__/Dialog.test.tsx.snap +++ b/src/__tests__/__snapshots__/Dialog.test.tsx.snap @@ -61,6 +61,17 @@ exports[`Dialog renders consistently 1`] = ` padding: 16px; } +.c3 { + font-size: 14px; + font-weight: 600; + font-family: sans-serif; + color: #1F2328; +} + +.c5 { + font-family: sans-serif; +} + .c1 { border: none; padding: 0; @@ -81,17 +92,6 @@ exports[`Dialog renders consistently 1`] = ` color: #0969da; } -.c3 { - font-size: 14px; - font-weight: 600; - font-family: sans-serif; - color: #1F2328; -} - -.c5 { - font-family: sans-serif; -} - .c0 { box-shadow: 0 8px 24px rgba(140,149,159,0.2); border-radius: 6px; diff --git a/src/__tests__/deprecated/__snapshots__/DropdownMenu.test.tsx.snap b/src/__tests__/deprecated/__snapshots__/DropdownMenu.test.tsx.snap index eacd73368f9..e8ff59eba75 100644 --- a/src/__tests__/deprecated/__snapshots__/DropdownMenu.test.tsx.snap +++ b/src/__tests__/deprecated/__snapshots__/DropdownMenu.test.tsx.snap @@ -1,6 +1,10 @@ // Jest Snapshot v1, https://goo.gl/fbAQLP exports[`DropdownMenu renders consistently 1`] = ` +.c1 { + margin-left: 4px; +} + .c0 { position: relative; display: inline-block; @@ -65,10 +69,6 @@ exports[`DropdownMenu renders consistently 1`] = ` border-color: rgba(31,35,40,0.15); } -.c1 { - margin-left: 4px; -} -