diff --git a/.changeset/shy-squids-study.md b/.changeset/shy-squids-study.md new file mode 100644 index 00000000000..e1199fb4e25 --- /dev/null +++ b/.changeset/shy-squids-study.md @@ -0,0 +1,5 @@ +--- +"@primer/react": patch +--- + +ButtonGroup CSS fixes for mixed types diff --git a/.playwright/snapshots/components/ButtonGroup.test.ts-snapshots/ButtonGroup-Overrides-dark-colorblind-linux.png b/.playwright/snapshots/components/ButtonGroup.test.ts-snapshots/ButtonGroup-Overrides-dark-colorblind-linux.png new file mode 100644 index 00000000000..3731c61b332 Binary files /dev/null and b/.playwright/snapshots/components/ButtonGroup.test.ts-snapshots/ButtonGroup-Overrides-dark-colorblind-linux.png differ diff --git a/.playwright/snapshots/components/ButtonGroup.test.ts-snapshots/ButtonGroup-Overrides-dark-dimmed-linux.png b/.playwright/snapshots/components/ButtonGroup.test.ts-snapshots/ButtonGroup-Overrides-dark-dimmed-linux.png new file mode 100644 index 00000000000..251f7e14587 Binary files /dev/null and b/.playwright/snapshots/components/ButtonGroup.test.ts-snapshots/ButtonGroup-Overrides-dark-dimmed-linux.png differ diff --git a/.playwright/snapshots/components/ButtonGroup.test.ts-snapshots/ButtonGroup-Overrides-dark-high-contrast-linux.png b/.playwright/snapshots/components/ButtonGroup.test.ts-snapshots/ButtonGroup-Overrides-dark-high-contrast-linux.png new file mode 100644 index 00000000000..9d830ba5a2f Binary files /dev/null and b/.playwright/snapshots/components/ButtonGroup.test.ts-snapshots/ButtonGroup-Overrides-dark-high-contrast-linux.png differ diff --git a/.playwright/snapshots/components/ButtonGroup.test.ts-snapshots/ButtonGroup-Overrides-dark-linux.png b/.playwright/snapshots/components/ButtonGroup.test.ts-snapshots/ButtonGroup-Overrides-dark-linux.png new file mode 100644 index 00000000000..3731c61b332 Binary files /dev/null and b/.playwright/snapshots/components/ButtonGroup.test.ts-snapshots/ButtonGroup-Overrides-dark-linux.png differ diff --git a/.playwright/snapshots/components/ButtonGroup.test.ts-snapshots/ButtonGroup-Overrides-dark-tritanopia-linux.png b/.playwright/snapshots/components/ButtonGroup.test.ts-snapshots/ButtonGroup-Overrides-dark-tritanopia-linux.png new file mode 100644 index 00000000000..3731c61b332 Binary files /dev/null and b/.playwright/snapshots/components/ButtonGroup.test.ts-snapshots/ButtonGroup-Overrides-dark-tritanopia-linux.png differ diff --git a/.playwright/snapshots/components/ButtonGroup.test.ts-snapshots/ButtonGroup-Overrides-light-colorblind-linux.png b/.playwright/snapshots/components/ButtonGroup.test.ts-snapshots/ButtonGroup-Overrides-light-colorblind-linux.png new file mode 100644 index 00000000000..b6cad81ef4b Binary files /dev/null and b/.playwright/snapshots/components/ButtonGroup.test.ts-snapshots/ButtonGroup-Overrides-light-colorblind-linux.png differ diff --git a/.playwright/snapshots/components/ButtonGroup.test.ts-snapshots/ButtonGroup-Overrides-light-high-contrast-linux.png b/.playwright/snapshots/components/ButtonGroup.test.ts-snapshots/ButtonGroup-Overrides-light-high-contrast-linux.png new file mode 100644 index 00000000000..85999dcdcbd Binary files /dev/null and b/.playwright/snapshots/components/ButtonGroup.test.ts-snapshots/ButtonGroup-Overrides-light-high-contrast-linux.png differ diff --git a/.playwright/snapshots/components/ButtonGroup.test.ts-snapshots/ButtonGroup-Overrides-light-linux.png b/.playwright/snapshots/components/ButtonGroup.test.ts-snapshots/ButtonGroup-Overrides-light-linux.png new file mode 100644 index 00000000000..b6cad81ef4b Binary files /dev/null and b/.playwright/snapshots/components/ButtonGroup.test.ts-snapshots/ButtonGroup-Overrides-light-linux.png differ diff --git a/.playwright/snapshots/components/ButtonGroup.test.ts-snapshots/ButtonGroup-Overrides-light-tritanopia-linux.png b/.playwright/snapshots/components/ButtonGroup.test.ts-snapshots/ButtonGroup-Overrides-light-tritanopia-linux.png new file mode 100644 index 00000000000..b6cad81ef4b Binary files /dev/null and b/.playwright/snapshots/components/ButtonGroup.test.ts-snapshots/ButtonGroup-Overrides-light-tritanopia-linux.png differ diff --git a/.playwright/snapshots/components/ButtonGroup.test.ts-snapshots/ButtonGroup-SX-Prop-dark-colorblind-linux.png b/.playwright/snapshots/components/ButtonGroup.test.ts-snapshots/ButtonGroup-SX-Prop-dark-colorblind-linux.png index 37061d02921..0d98488a13b 100644 Binary files a/.playwright/snapshots/components/ButtonGroup.test.ts-snapshots/ButtonGroup-SX-Prop-dark-colorblind-linux.png and b/.playwright/snapshots/components/ButtonGroup.test.ts-snapshots/ButtonGroup-SX-Prop-dark-colorblind-linux.png differ diff --git a/.playwright/snapshots/components/ButtonGroup.test.ts-snapshots/ButtonGroup-SX-Prop-dark-dimmed-linux.png b/.playwright/snapshots/components/ButtonGroup.test.ts-snapshots/ButtonGroup-SX-Prop-dark-dimmed-linux.png index 69ec67fb461..c1aa5490e02 100644 Binary files a/.playwright/snapshots/components/ButtonGroup.test.ts-snapshots/ButtonGroup-SX-Prop-dark-dimmed-linux.png and b/.playwright/snapshots/components/ButtonGroup.test.ts-snapshots/ButtonGroup-SX-Prop-dark-dimmed-linux.png differ diff --git a/.playwright/snapshots/components/ButtonGroup.test.ts-snapshots/ButtonGroup-SX-Prop-dark-high-contrast-linux.png b/.playwright/snapshots/components/ButtonGroup.test.ts-snapshots/ButtonGroup-SX-Prop-dark-high-contrast-linux.png index 9b45f91ec50..bcf4048a588 100644 Binary files a/.playwright/snapshots/components/ButtonGroup.test.ts-snapshots/ButtonGroup-SX-Prop-dark-high-contrast-linux.png and b/.playwright/snapshots/components/ButtonGroup.test.ts-snapshots/ButtonGroup-SX-Prop-dark-high-contrast-linux.png differ diff --git a/.playwright/snapshots/components/ButtonGroup.test.ts-snapshots/ButtonGroup-SX-Prop-dark-linux.png b/.playwright/snapshots/components/ButtonGroup.test.ts-snapshots/ButtonGroup-SX-Prop-dark-linux.png index 37061d02921..0d98488a13b 100644 Binary files a/.playwright/snapshots/components/ButtonGroup.test.ts-snapshots/ButtonGroup-SX-Prop-dark-linux.png and b/.playwright/snapshots/components/ButtonGroup.test.ts-snapshots/ButtonGroup-SX-Prop-dark-linux.png differ diff --git a/.playwright/snapshots/components/ButtonGroup.test.ts-snapshots/ButtonGroup-SX-Prop-dark-tritanopia-linux.png b/.playwright/snapshots/components/ButtonGroup.test.ts-snapshots/ButtonGroup-SX-Prop-dark-tritanopia-linux.png index 37061d02921..0d98488a13b 100644 Binary files a/.playwright/snapshots/components/ButtonGroup.test.ts-snapshots/ButtonGroup-SX-Prop-dark-tritanopia-linux.png and b/.playwright/snapshots/components/ButtonGroup.test.ts-snapshots/ButtonGroup-SX-Prop-dark-tritanopia-linux.png differ diff --git a/.playwright/snapshots/components/ButtonGroup.test.ts-snapshots/ButtonGroup-SX-Prop-light-colorblind-linux.png b/.playwright/snapshots/components/ButtonGroup.test.ts-snapshots/ButtonGroup-SX-Prop-light-colorblind-linux.png index 6ef721d7adb..0a4942ddf89 100644 Binary files a/.playwright/snapshots/components/ButtonGroup.test.ts-snapshots/ButtonGroup-SX-Prop-light-colorblind-linux.png and b/.playwright/snapshots/components/ButtonGroup.test.ts-snapshots/ButtonGroup-SX-Prop-light-colorblind-linux.png differ diff --git a/.playwright/snapshots/components/ButtonGroup.test.ts-snapshots/ButtonGroup-SX-Prop-light-high-contrast-linux.png b/.playwright/snapshots/components/ButtonGroup.test.ts-snapshots/ButtonGroup-SX-Prop-light-high-contrast-linux.png index 8ff90a243af..2359588a9c5 100644 Binary files a/.playwright/snapshots/components/ButtonGroup.test.ts-snapshots/ButtonGroup-SX-Prop-light-high-contrast-linux.png and b/.playwright/snapshots/components/ButtonGroup.test.ts-snapshots/ButtonGroup-SX-Prop-light-high-contrast-linux.png differ diff --git a/.playwright/snapshots/components/ButtonGroup.test.ts-snapshots/ButtonGroup-SX-Prop-light-linux.png b/.playwright/snapshots/components/ButtonGroup.test.ts-snapshots/ButtonGroup-SX-Prop-light-linux.png index 6ef721d7adb..0a4942ddf89 100644 Binary files a/.playwright/snapshots/components/ButtonGroup.test.ts-snapshots/ButtonGroup-SX-Prop-light-linux.png and b/.playwright/snapshots/components/ButtonGroup.test.ts-snapshots/ButtonGroup-SX-Prop-light-linux.png differ diff --git a/.playwright/snapshots/components/ButtonGroup.test.ts-snapshots/ButtonGroup-SX-Prop-light-tritanopia-linux.png b/.playwright/snapshots/components/ButtonGroup.test.ts-snapshots/ButtonGroup-SX-Prop-light-tritanopia-linux.png index 6ef721d7adb..0a4942ddf89 100644 Binary files a/.playwright/snapshots/components/ButtonGroup.test.ts-snapshots/ButtonGroup-SX-Prop-light-tritanopia-linux.png and b/.playwright/snapshots/components/ButtonGroup.test.ts-snapshots/ButtonGroup-SX-Prop-light-tritanopia-linux.png differ diff --git a/e2e/components/ButtonGroup.test.ts b/e2e/components/ButtonGroup.test.ts index 4b9b3de07f4..f77bfdee26d 100644 --- a/e2e/components/ButtonGroup.test.ts +++ b/e2e/components/ButtonGroup.test.ts @@ -23,6 +23,10 @@ const stories = [ title: 'SX Prop', id: 'components-buttongroup-dev--sx-prop', }, + { + title: 'Overrides', + id: 'components-buttongroup-dev--link-button-with-icon-buttons', + }, ] as const test.describe('ButtonGroup', () => { diff --git a/packages/react/src/ButtonGroup/ButtonGroup.dev.stories.tsx b/packages/react/src/ButtonGroup/ButtonGroup.dev.stories.tsx index 7726324ad32..9a3cd9fe68f 100644 --- a/packages/react/src/ButtonGroup/ButtonGroup.dev.stories.tsx +++ b/packages/react/src/ButtonGroup/ButtonGroup.dev.stories.tsx @@ -1,12 +1,68 @@ import React from 'react' import type {Meta} from '@storybook/react' import ButtonGroup from './ButtonGroup' -import {Button} from '../Button' +import {Button, IconButton, LinkButton} from '../Button' +import {CopilotIcon} from '@primer/octicons-react' +import {Box, Tooltip, ThemeProvider, BaseStyles} from '..' -export default { +const meta: Meta = { title: 'Components/ButtonGroup/Dev', component: ButtonGroup, -} as Meta + decorators: [ + Story => { + // Add some padding to the wrapper box to make sure tooltip v1 is always in the viewport + return ( + + + {Story()} + + + ) + }, + ], +} + +export default meta + +export const LinkAndButtonWithTooltip2 = () => ( + + + + + + +) + +export const ButtonAndLinkWithTooltip2 = () => ( + + + + + + +) + +export const ButtonGroupSingleButton = () => ( + + +
+
+) + +export const LinkButtonWithIconButtons = () => ( + + + Small link + + + + + +) export const SxProp = () => ( diff --git a/packages/react/src/ButtonGroup/ButtonGroup.features.stories.tsx b/packages/react/src/ButtonGroup/ButtonGroup.features.stories.tsx index 211e09ad17e..da2b99ff6e6 100644 --- a/packages/react/src/ButtonGroup/ButtonGroup.features.stories.tsx +++ b/packages/react/src/ButtonGroup/ButtonGroup.features.stories.tsx @@ -1,10 +1,11 @@ -import React, {useState} from 'react' +import React from 'react' import type {Meta} from '@storybook/react' import ButtonGroup from './ButtonGroup' import {IconButton, Button} from '../Button' import {PlusIcon, DashIcon, TriangleDownIcon} from '@primer/octicons-react' import {ActionMenu} from '../ActionMenu' import {ActionList} from '../ActionList' +import {Tooltip} from '../next' export default { title: 'Components/ButtonGroup/Features', @@ -14,26 +15,84 @@ export default { export const IconButtons = () => ( {/* We can remove these unsafe props after we resolve https://github.com/primer/react/issues/4129 */} - {/* eslint-disable-next-line primer-react/a11y-remove-disable-tooltip */} - - {/* eslint-disable-next-line primer-react/a11y-remove-disable-tooltip */} - + + ) export const LoadingButtons = () => { - const [isLoading, setIsLoading] = useState(false) - - const handleClick = () => { - setIsLoading(true) - } + const handleClick = () => {} return ( - - + + + + + ) +} + +export const IconButtonsWithTooltip = () => ( + + + + +) +export const ButtonAndLink = () => ( + + + + +) + +export const LinksWithTooltip = () => ( + + + + + + + + +) + +export const InactiveButtonsGroup = () => { + const primaryButton = ( + + ) + + const secondaryButton = ( + + ) + + return ( + + + {primaryButton} + + + {}}> + + + {secondaryButton} + + + + Item 1 + Item 2 + + ) } diff --git a/packages/react/src/ButtonGroup/ButtonGroup.module.css b/packages/react/src/ButtonGroup/ButtonGroup.module.css index e6ae5017e69..7c289b69544 100644 --- a/packages/react/src/ButtonGroup/ButtonGroup.module.css +++ b/packages/react/src/ButtonGroup/ButtonGroup.module.css @@ -3,31 +3,17 @@ vertical-align: middle; isolation: isolate; - & > *:not([data-loading-wrapper]):is(button, a) { + & > *:not([data-loading-wrapper]) { /* stylelint-disable-next-line primer/spacing */ margin-inline-end: -1px; position: relative; - border-radius: 0; - &:first-of-type { - border-top-left-radius: var(--borderRadius-medium); - border-bottom-left-radius: var(--borderRadius-medium); + /* reset border-radius */ + button, + a { + border-radius: 0; } - &:last-of-type { - border-top-right-radius: var(--borderRadius-medium); - border-bottom-right-radius: var(--borderRadius-medium); - } - - &:focus, - &:active, - &:hover { - z-index: 1; - } - } - - /* if child is loading button */ - [data-loading-wrapper] { &:first-child { button, a { @@ -43,18 +29,54 @@ border-bottom-right-radius: var(--borderRadius-medium); } } + + &:focus, + &:active, + &:hover { + z-index: 1; + } + } + + /* this is a workaround until portal based tooltips are fully removed from dotcom */ + &:has(div:last-child:empty) { + button, + a { + border-radius: var(--borderRadius-medium); + } } - [data-loading-wrapper] > * { + /* if child is loading button */ + & > *[data-loading-wrapper] { /* stylelint-disable-next-line primer/spacing */ margin-inline-end: -1px; position: relative; - border-radius: 0; + + /* reset border-radius */ + button, + a { + border-radius: 0; + } &:focus, &:active, &:hover { z-index: 1; } + + &:first-child { + button, + a { + border-top-left-radius: var(--borderRadius-medium); + border-bottom-left-radius: var(--borderRadius-medium); + } + } + + &:last-child { + button, + a { + border-top-right-radius: var(--borderRadius-medium); + border-bottom-right-radius: var(--borderRadius-medium); + } + } } } diff --git a/packages/react/src/ButtonGroup/ButtonGroup.tsx b/packages/react/src/ButtonGroup/ButtonGroup.tsx index b3d59baacb6..1d678904fd9 100644 --- a/packages/react/src/ButtonGroup/ButtonGroup.tsx +++ b/packages/react/src/ButtonGroup/ButtonGroup.tsx @@ -1,4 +1,4 @@ -import React from 'react' +import React, {type ComponentPropsWithRef} from 'react' import classes from './ButtonGroup.module.css' import {clsx} from 'clsx' import {FocusKeys, useFocusZone} from '../hooks/useFocusZone' @@ -13,13 +13,15 @@ export type ButtonGroupProps = { role?: string /** className passed in for styling */ className?: string -} & SxProp +} & SxProp & + ComponentPropsWithRef<'div'> const ButtonGroup = React.forwardRef(function ButtonGroup( - {className, role, sx, ...rest}, + {className, role, sx, children, ...rest}, forwardRef, ) { const buttonRef = useProvidedRefOrCreate(forwardRef as React.RefObject) + const buttons = React.Children.map(children, (child, index) =>
{child}
) useFocusZone({ containerRef: buttonRef, @@ -30,11 +32,17 @@ const ButtonGroup = React.forwardRef(function But if (sx !== defaultSxProp) { return ( - + + {buttons} + ) } - return
+ return ( +
+ {buttons} +
+ ) }) as PolymorphicForwardRefComponent<'div', ButtonGroupProps> ButtonGroup.displayName = 'ButtonGroup'