-
Notifications
You must be signed in to change notification settings - Fork 536
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Explore wrapping button group items with a div to simplify css selection
- Loading branch information
1 parent
5c7571c
commit 784d775
Showing
3 changed files
with
185 additions
and
20 deletions.
There are no files selected for viewing
119 changes: 119 additions & 0 deletions
119
packages/react/src/ButtonGroup/ButtonGroup.dev.stories.tsx
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,119 @@ | ||
import React from 'react' | ||
import type {Meta} from '@storybook/react' | ||
import ButtonGroup from './ButtonGroup' | ||
import {Button, IconButton} from '../Button' | ||
import {PlusIcon, DashIcon, CopilotIcon} from '@primer/octicons-react' | ||
import {Tooltip as TooltipV2} from '../drafts' | ||
import {Box, Tooltip, ThemeProvider, BaseStyles} from '..' | ||
|
||
const meta: Meta<typeof ButtonGroup> = { | ||
title: 'Components/ButtonGroup/DevOnly', | ||
component: ButtonGroup, | ||
decorators: [ | ||
Story => { | ||
// Add some padding to the wrapper box to make sure tooltip v1 is always in the viewport | ||
return ( | ||
<ThemeProvider> | ||
<BaseStyles> | ||
<Box padding={5}>{Story()}</Box> | ||
</BaseStyles> | ||
</ThemeProvider> | ||
) | ||
}, | ||
], | ||
} | ||
|
||
export default meta | ||
|
||
export const IconButtonsWithTooltip1 = () => ( | ||
<ButtonGroup> | ||
<Tooltip text="Add" direction="s"> | ||
<IconButton icon={PlusIcon} aria-label="Add" /> | ||
</Tooltip> | ||
<Tooltip text="Subtract" direction="s"> | ||
<IconButton icon={DashIcon} aria-label="Subtract" /> | ||
</Tooltip> | ||
</ButtonGroup> | ||
) | ||
|
||
export const LinksWithTooltip1 = () => ( | ||
<ButtonGroup> | ||
<Tooltip text="Additonal text for link 1" direction="s"> | ||
<Button as="a" href="https://primer.style"> | ||
Sample Link 1 | ||
</Button> | ||
</Tooltip> | ||
<Tooltip text="Additonal text for link 2" direction="s"> | ||
<Button as="a" href="https://primer.style"> | ||
Sample Link 2 | ||
</Button> | ||
</Tooltip> | ||
</ButtonGroup> | ||
) | ||
|
||
export const LinksWithTooltip2 = () => ( | ||
<ButtonGroup> | ||
<TooltipV2 text="Additonal text for link 1" direction="s"> | ||
<Button as="a" href="https://primer.style"> | ||
Sample Link 1 | ||
</Button> | ||
</TooltipV2> | ||
<TooltipV2 text="Additonal text for link 2" direction="s"> | ||
<Button as="a" href="https://primer.style"> | ||
Sample Link 2 | ||
</Button> | ||
</TooltipV2> | ||
</ButtonGroup> | ||
) | ||
|
||
export const LinkAndButtonWithTooltip1 = () => ( | ||
<ButtonGroup sx={{pl: 2}}> | ||
<Tooltip text="Additional info about the link"> | ||
<Button as="a" href="https://primer.style"> | ||
Link | ||
</Button> | ||
</Tooltip> | ||
<Tooltip text="Open GitHub Copilot chat" direction="s"> | ||
<IconButton icon={CopilotIcon} aria-label="Open GitHub Copilot chat" /> | ||
</Tooltip> | ||
</ButtonGroup> | ||
) | ||
|
||
export const ButtonAndLinkWithTooltip1 = () => ( | ||
<ButtonGroup sx={{pl: 2}}> | ||
<Tooltip text="Open GitHub Copilot chat" direction="se"> | ||
<IconButton icon={CopilotIcon} aria-label="Open GitHub Copilot chat" /> | ||
</Tooltip> | ||
<Tooltip text="Additional info about the link"> | ||
<Button as="a" href="https://primer.style"> | ||
Link | ||
</Button> | ||
</Tooltip> | ||
</ButtonGroup> | ||
) | ||
|
||
export const LinkAndButtonWithTooltip2 = () => ( | ||
<ButtonGroup sx={{pl: 2}}> | ||
<TooltipV2 text="Additional info about the link"> | ||
<Button as="a" href="https://primer.style"> | ||
Link | ||
</Button> | ||
</TooltipV2> | ||
<TooltipV2 text="Open GitHub Copilot chat" direction="s"> | ||
<IconButton icon={CopilotIcon} aria-label="Open GitHub Copilot chat" /> | ||
</TooltipV2> | ||
</ButtonGroup> | ||
) | ||
|
||
export const ButtonAndLinkWithTooltip2 = () => ( | ||
<ButtonGroup sx={{pl: 2}}> | ||
<TooltipV2 text="Open GitHub Copilot chat" direction="s"> | ||
<IconButton icon={CopilotIcon} aria-label="Open GitHub Copilot chat" /> | ||
</TooltipV2> | ||
<TooltipV2 text="Additional info about the link"> | ||
<Button as="a" href="https://primer.style"> | ||
Link | ||
</Button> | ||
</TooltipV2> | ||
</ButtonGroup> | ||
) |
43 changes: 39 additions & 4 deletions
43
packages/react/src/ButtonGroup/ButtonGroup.features.stories.tsx
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,17 +1,52 @@ | ||
import React from 'react' | ||
import type {ComponentMeta} from '@storybook/react' | ||
import type {Meta} from '@storybook/react' | ||
import ButtonGroup from './ButtonGroup' | ||
import {IconButton} from '../Button' | ||
import {Button, IconButton} from '../Button' | ||
import {PlusIcon, DashIcon} from '@primer/octicons-react' | ||
import {Tooltip} from '../next' | ||
import {Box, ThemeProvider, BaseStyles} from '..' | ||
|
||
export default { | ||
const meta: Meta<typeof ButtonGroup> = { | ||
title: 'Components/ButtonGroup/Features', | ||
component: ButtonGroup, | ||
} as ComponentMeta<typeof ButtonGroup> | ||
decorators: [ | ||
Story => { | ||
// Add some padding to the wrapper box to make sure tooltip v1 is always in the viewport | ||
return ( | ||
<ThemeProvider> | ||
<BaseStyles> | ||
<Box padding={5}>{Story()}</Box> | ||
</BaseStyles> | ||
</ThemeProvider> | ||
) | ||
}, | ||
], | ||
} | ||
|
||
export default meta | ||
|
||
export const IconButtons = () => ( | ||
<ButtonGroup> | ||
<IconButton icon={PlusIcon} aria-label="Add" /> | ||
<IconButton icon={DashIcon} aria-label="Subtract" /> | ||
</ButtonGroup> | ||
) | ||
|
||
export const IconButtonsWithTooltip = () => ( | ||
<ButtonGroup> | ||
<Tooltip text="Add" type="label"> | ||
<IconButton icon={PlusIcon} aria-label="Add" /> | ||
</Tooltip> | ||
<Tooltip text="Subtract" type="label"> | ||
<IconButton icon={DashIcon} aria-label="Subtract" /> | ||
</Tooltip> | ||
</ButtonGroup> | ||
) | ||
export const ButtonAndLink = () => ( | ||
<ButtonGroup> | ||
<Button>Button</Button> | ||
<Button as="a" href="https://primer.style"> | ||
Link | ||
</Button> | ||
</ButtonGroup> | ||
) |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,37 +1,48 @@ | ||
import styled from 'styled-components' | ||
import {get} from '../constants' | ||
import sx from '../sx' | ||
import type {ComponentProps} from '../utils/types' | ||
import {type SxProp} from '../sx' | ||
import React from 'react' | ||
import Box from '../Box' | ||
import {defaultSxProp} from '../utils/defaultSxProp' | ||
|
||
const ButtonGroup = styled.div` | ||
export type ButtonGroupProps = SxProp & React.ComponentPropsWithoutRef<'div'> | ||
|
||
function ButtonGroup({children, sx = defaultSxProp, ...rest}: React.PropsWithChildren<ButtonGroupProps>) { | ||
const buttons = React.Children.map(children, (child, index) => ( | ||
<Box key={index} {...rest}> | ||
{child} | ||
</Box> | ||
)) | ||
|
||
return <StyledButtonGroup sx={sx}>{buttons}</StyledButtonGroup> | ||
} | ||
|
||
const StyledButtonGroup = styled.div` | ||
display: inline-flex; | ||
vertical-align: middle; | ||
isolation: isolate; | ||
&& > * { | ||
&& :is(button, a) { | ||
margin-inline-end: -1px; | ||
position: relative; | ||
border-radius: 0; | ||
:first-child { | ||
border-top-left-radius: ${get('radii.2')}; | ||
border-bottom-left-radius: ${get('radii.2')}; | ||
} | ||
:last-child { | ||
border-top-right-radius: ${get('radii.2')}; | ||
border-bottom-right-radius: ${get('radii.2')}; | ||
} | ||
:focus, | ||
:active, | ||
:hover { | ||
z-index: 1; | ||
} | ||
} | ||
${sx}; | ||
&& > :first-child :is(button, a) { | ||
border-top-left-radius: ${get('radii.2')}; | ||
border-bottom-left-radius: ${get('radii.2')}; | ||
} | ||
&& > :last-child :is(button, a) { | ||
border-top-right-radius: ${get('radii.2')}; | ||
border-bottom-right-radius: ${get('radii.2')}; | ||
} | ||
` | ||
|
||
export type ButtonGroupProps = ComponentProps<typeof ButtonGroup> | ||
export default ButtonGroup |