1
+ import React from 'react' ;
1
2
import { css } from '@emotion/react' ;
2
3
import styled from '@emotion/styled' ;
3
4
@@ -13,85 +14,87 @@ interface ButtonBarProps extends Omit<React.HTMLAttributes<HTMLDivElement>, 'cla
13
14
14
15
export function ButtonBar ( { children, merged = false , gap = 0 , ...props } : ButtonBarProps ) {
15
16
return (
16
- < StyledButtonBar merged = { merged } gap = { gap } { ...props } >
17
+ < StyledButtonBar
18
+ merged = { merged }
19
+ gap = { gap }
20
+ { ...props }
21
+ listSize = { React . Children . count ( children ) }
22
+ >
17
23
{ children }
18
24
</ StyledButtonBar >
19
25
) ;
20
26
}
21
27
22
- const StyledButtonBar = styled ( 'div' ) < { gap : ValidSize | 0 ; merged : boolean } > `
28
+ const getChildTransforms = ( count : number ) => {
29
+ return Array . from (
30
+ { length : count } ,
31
+ ( _ , index ) => css `
32
+ > * : nth-child (${ index + 1 } ),
33
+ > * : nth-child (${ index + 1 } ) > button {
34
+ transform : translateX (-${ index } px);
35
+ }
36
+ `
37
+ ) ;
38
+ } ;
39
+
40
+ const StyledButtonBar = styled ( 'div' ) < {
41
+ gap : ValidSize | 0 ;
42
+ listSize : number ;
43
+ merged : boolean ;
44
+ } > `
23
45
display: grid;
24
46
grid-auto-flow: column;
25
47
grid-column-gap: ${ p => ( p . gap === 0 ? '0' : space ( p . gap ) ) } ;
26
48
align-items: center;
27
49
28
- ${ p => p . merged && MergedButtonBarStyles }
29
- ` ;
30
-
31
- const MergedButtonBarStyles = ( ) => css `
32
- /* Raised buttons show borders on both sides. Useful to create pill bars */
33
- & > .active {
34
- z-index : 2 ;
35
- }
36
-
37
- & > .dropdown ,
38
- & > button ,
39
- & > input ,
40
- & > a {
41
- position : relative;
50
+ ${ p => getChildTransforms ( p . listSize ) }
42
51
43
- /* First button is square on the right side */
44
- & : first-child : not ( : last-child ) {
45
- border-top-right-radius : 0 ;
46
- border-bottom-right-radius : 0 ;
47
-
48
- & > . dropdown-actor > ${ StyledButton } {
49
- border-top-right-radius : 0 ;
50
- border-bottom-right-radius : 0 ;
52
+ ${ p =>
53
+ p . merged &&
54
+ css `
55
+ /* Raised buttons show borders on both sides. Useful to create pill bars */
56
+ & > . active ,
57
+ & > * : focus-within ,
58
+ & > * : focus-within > * {
59
+ z-index : 2 ;
51
60
}
52
- }
53
61
54
- /* Middle buttons are square */
55
- & : not (: last-child ): not (: first-child ) {
56
- border-radius : 0 ;
62
+ & > * {
63
+ position : relative;
57
64
58
- & > .dropdown-actor > ${ StyledButton } {
59
- border-radius : 0 ;
60
- }
61
- }
65
+ /* First button is square on the right side */
66
+ & : first-child : not (: last-child ),
67
+ & : first-child : not (: last-child ) > button {
68
+ border-top-right-radius : 0 ;
69
+ border-bottom-right-radius : 0 ;
62
70
63
- /* Middle buttons only need one border so we don't get a double line */
64
- & : first-child {
65
- & + .dropdown : not (: last-child ),
66
- & + a : not (: last-child ),
67
- & + input : not (: last-child ),
68
- & + button : not (: last-child ) {
69
- margin-left : -1px ;
70
- }
71
- }
71
+ & > .dropdown-actor > ${ StyledButton } {
72
+ border-top-right-radius : 0 ;
73
+ border-bottom-right-radius : 0 ;
74
+ }
75
+ }
72
76
73
- /* Middle buttons only need one border so we don't get a double line */
74
- /* stylelint-disable-next-line no-duplicate-selectors */
75
- & : not (: last-child ): not (: first-child ) {
76
- & + .dropdown ,
77
- & + button ,
78
- & + input ,
79
- & + a {
80
- margin-left : -1px ;
81
- }
82
- }
77
+ /* Middle buttons are square */
78
+ & : not (: last-child ): not (: first-child ),
79
+ & : not (: last-child ): not (: first-child ) > button {
80
+ border-radius : 0 ;
81
+
82
+ & > .dropdown-actor > ${ StyledButton } {
83
+ border-radius : 0 ;
84
+ }
85
+ }
83
86
84
- /* Last button is square on the left side */
85
- & : last-child : not (: first-child ) {
86
- border-top-left-radius : 0 ;
87
- border-bottom-left-radius : 0 ;
88
- margin-left : -1px ;
87
+ /* Last button is square on the left side */
88
+ & : last-child : not (: first-child ) {
89
+ border-top-left-radius : 0 ;
90
+ border-bottom-left-radius : 0 ;
89
91
90
- & > .dropdown-actor > ${ StyledButton } {
91
- border-top-left-radius : 0 ;
92
- border-bottom-left-radius : 0 ;
93
- margin-left : -1px ;
92
+ & > button ,
93
+ & > .dropdown-actor > ${ StyledButton } {
94
+ border-top-left-radius : 0 ;
95
+ border-bottom-left-radius : 0 ;
96
+ }
97
+ }
94
98
}
95
- }
96
- }
99
+ ` }
97
100
` ;
0 commit comments