Skip to content

Commit 784d775

Browse files
Explore wrapping button group items with a div to simplify css selection
1 parent 5c7571c commit 784d775

File tree

3 files changed

+185
-20
lines changed

3 files changed

+185
-20
lines changed
Lines changed: 119 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,119 @@
1+
import React from 'react'
2+
import type {Meta} from '@storybook/react'
3+
import ButtonGroup from './ButtonGroup'
4+
import {Button, IconButton} from '../Button'
5+
import {PlusIcon, DashIcon, CopilotIcon} from '@primer/octicons-react'
6+
import {Tooltip as TooltipV2} from '../drafts'
7+
import {Box, Tooltip, ThemeProvider, BaseStyles} from '..'
8+
9+
const meta: Meta<typeof ButtonGroup> = {
10+
title: 'Components/ButtonGroup/DevOnly',
11+
component: ButtonGroup,
12+
decorators: [
13+
Story => {
14+
// Add some padding to the wrapper box to make sure tooltip v1 is always in the viewport
15+
return (
16+
<ThemeProvider>
17+
<BaseStyles>
18+
<Box padding={5}>{Story()}</Box>
19+
</BaseStyles>
20+
</ThemeProvider>
21+
)
22+
},
23+
],
24+
}
25+
26+
export default meta
27+
28+
export const IconButtonsWithTooltip1 = () => (
29+
<ButtonGroup>
30+
<Tooltip text="Add" direction="s">
31+
<IconButton icon={PlusIcon} aria-label="Add" />
32+
</Tooltip>
33+
<Tooltip text="Subtract" direction="s">
34+
<IconButton icon={DashIcon} aria-label="Subtract" />
35+
</Tooltip>
36+
</ButtonGroup>
37+
)
38+
39+
export const LinksWithTooltip1 = () => (
40+
<ButtonGroup>
41+
<Tooltip text="Additonal text for link 1" direction="s">
42+
<Button as="a" href="https://primer.style">
43+
Sample Link 1
44+
</Button>
45+
</Tooltip>
46+
<Tooltip text="Additonal text for link 2" direction="s">
47+
<Button as="a" href="https://primer.style">
48+
Sample Link 2
49+
</Button>
50+
</Tooltip>
51+
</ButtonGroup>
52+
)
53+
54+
export const LinksWithTooltip2 = () => (
55+
<ButtonGroup>
56+
<TooltipV2 text="Additonal text for link 1" direction="s">
57+
<Button as="a" href="https://primer.style">
58+
Sample Link 1
59+
</Button>
60+
</TooltipV2>
61+
<TooltipV2 text="Additonal text for link 2" direction="s">
62+
<Button as="a" href="https://primer.style">
63+
Sample Link 2
64+
</Button>
65+
</TooltipV2>
66+
</ButtonGroup>
67+
)
68+
69+
export const LinkAndButtonWithTooltip1 = () => (
70+
<ButtonGroup sx={{pl: 2}}>
71+
<Tooltip text="Additional info about the link">
72+
<Button as="a" href="https://primer.style">
73+
Link
74+
</Button>
75+
</Tooltip>
76+
<Tooltip text="Open GitHub Copilot chat" direction="s">
77+
<IconButton icon={CopilotIcon} aria-label="Open GitHub Copilot chat" />
78+
</Tooltip>
79+
</ButtonGroup>
80+
)
81+
82+
export const ButtonAndLinkWithTooltip1 = () => (
83+
<ButtonGroup sx={{pl: 2}}>
84+
<Tooltip text="Open GitHub Copilot chat" direction="se">
85+
<IconButton icon={CopilotIcon} aria-label="Open GitHub Copilot chat" />
86+
</Tooltip>
87+
<Tooltip text="Additional info about the link">
88+
<Button as="a" href="https://primer.style">
89+
Link
90+
</Button>
91+
</Tooltip>
92+
</ButtonGroup>
93+
)
94+
95+
export const LinkAndButtonWithTooltip2 = () => (
96+
<ButtonGroup sx={{pl: 2}}>
97+
<TooltipV2 text="Additional info about the link">
98+
<Button as="a" href="https://primer.style">
99+
Link
100+
</Button>
101+
</TooltipV2>
102+
<TooltipV2 text="Open GitHub Copilot chat" direction="s">
103+
<IconButton icon={CopilotIcon} aria-label="Open GitHub Copilot chat" />
104+
</TooltipV2>
105+
</ButtonGroup>
106+
)
107+
108+
export const ButtonAndLinkWithTooltip2 = () => (
109+
<ButtonGroup sx={{pl: 2}}>
110+
<TooltipV2 text="Open GitHub Copilot chat" direction="s">
111+
<IconButton icon={CopilotIcon} aria-label="Open GitHub Copilot chat" />
112+
</TooltipV2>
113+
<TooltipV2 text="Additional info about the link">
114+
<Button as="a" href="https://primer.style">
115+
Link
116+
</Button>
117+
</TooltipV2>
118+
</ButtonGroup>
119+
)
Lines changed: 39 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,17 +1,52 @@
11
import React from 'react'
2-
import type {ComponentMeta} from '@storybook/react'
2+
import type {Meta} from '@storybook/react'
33
import ButtonGroup from './ButtonGroup'
4-
import {IconButton} from '../Button'
4+
import {Button, IconButton} from '../Button'
55
import {PlusIcon, DashIcon} from '@primer/octicons-react'
6+
import {Tooltip} from '../next'
7+
import {Box, ThemeProvider, BaseStyles} from '..'
68

7-
export default {
9+
const meta: Meta<typeof ButtonGroup> = {
810
title: 'Components/ButtonGroup/Features',
911
component: ButtonGroup,
10-
} as ComponentMeta<typeof ButtonGroup>
12+
decorators: [
13+
Story => {
14+
// Add some padding to the wrapper box to make sure tooltip v1 is always in the viewport
15+
return (
16+
<ThemeProvider>
17+
<BaseStyles>
18+
<Box padding={5}>{Story()}</Box>
19+
</BaseStyles>
20+
</ThemeProvider>
21+
)
22+
},
23+
],
24+
}
25+
26+
export default meta
1127

1228
export const IconButtons = () => (
1329
<ButtonGroup>
1430
<IconButton icon={PlusIcon} aria-label="Add" />
1531
<IconButton icon={DashIcon} aria-label="Subtract" />
1632
</ButtonGroup>
1733
)
34+
35+
export const IconButtonsWithTooltip = () => (
36+
<ButtonGroup>
37+
<Tooltip text="Add" type="label">
38+
<IconButton icon={PlusIcon} aria-label="Add" />
39+
</Tooltip>
40+
<Tooltip text="Subtract" type="label">
41+
<IconButton icon={DashIcon} aria-label="Subtract" />
42+
</Tooltip>
43+
</ButtonGroup>
44+
)
45+
export const ButtonAndLink = () => (
46+
<ButtonGroup>
47+
<Button>Button</Button>
48+
<Button as="a" href="https://primer.style">
49+
Link
50+
</Button>
51+
</ButtonGroup>
52+
)
Lines changed: 27 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -1,37 +1,48 @@
11
import styled from 'styled-components'
22
import {get} from '../constants'
3-
import sx from '../sx'
4-
import type {ComponentProps} from '../utils/types'
3+
import {type SxProp} from '../sx'
4+
import React from 'react'
5+
import Box from '../Box'
6+
import {defaultSxProp} from '../utils/defaultSxProp'
57

6-
const ButtonGroup = styled.div`
8+
export type ButtonGroupProps = SxProp & React.ComponentPropsWithoutRef<'div'>
9+
10+
function ButtonGroup({children, sx = defaultSxProp, ...rest}: React.PropsWithChildren<ButtonGroupProps>) {
11+
const buttons = React.Children.map(children, (child, index) => (
12+
<Box key={index} {...rest}>
13+
{child}
14+
</Box>
15+
))
16+
17+
return <StyledButtonGroup sx={sx}>{buttons}</StyledButtonGroup>
18+
}
19+
20+
const StyledButtonGroup = styled.div`
721
display: inline-flex;
822
vertical-align: middle;
923
isolation: isolate;
1024
11-
&& > * {
25+
&& :is(button, a) {
1226
margin-inline-end: -1px;
1327
position: relative;
1428
border-radius: 0;
1529
16-
:first-child {
17-
border-top-left-radius: ${get('radii.2')};
18-
border-bottom-left-radius: ${get('radii.2')};
19-
}
20-
21-
:last-child {
22-
border-top-right-radius: ${get('radii.2')};
23-
border-bottom-right-radius: ${get('radii.2')};
24-
}
25-
2630
:focus,
2731
:active,
2832
:hover {
2933
z-index: 1;
3034
}
3135
}
3236
33-
${sx};
37+
&& > :first-child :is(button, a) {
38+
border-top-left-radius: ${get('radii.2')};
39+
border-bottom-left-radius: ${get('radii.2')};
40+
}
41+
42+
&& > :last-child :is(button, a) {
43+
border-top-right-radius: ${get('radii.2')};
44+
border-bottom-right-radius: ${get('radii.2')};
45+
}
3446
`
3547

36-
export type ButtonGroupProps = ComponentProps<typeof ButtonGroup>
3748
export default ButtonGroup

0 commit comments

Comments
 (0)