11import React , { forwardRef } from 'react'
2- import { IconProps , TriangleDownIcon } from '@primer/octicons-react'
2+ import { IconProps } from '@primer/octicons-react'
33import Box from '../Box'
44import { fontSize , FontSizeProps , variant as variantFn } from 'styled-system'
5- import styled from 'styled-components'
5+ import styled , { css } from 'styled-components'
66import sx , { SxProp } from '../sx'
77import { get } from '../constants'
88import buttonBaseStyles from './buttonStyles'
99import { Theme } from '../ThemeProvider'
10- import Counter from './counter'
1110import { ComponentProps } from '../utils/types'
1211
1312const sizes = variantFn ( {
@@ -27,114 +26,114 @@ const sizes = variantFn({
2726type VariantType = 'default' | 'primary' | 'invisible' | 'danger'
2827
2928export type ButtonBaseProps = {
30- caret ?: boolean
3129 variant ?: VariantType
3230 size ?: 'small' | 'medium' | 'large'
3331 icon ?: React . FunctionComponent < IconProps >
34- as ?: 'button' | 'a' | 'summary' | 'input' | string | React . ReactType
32+ leadingIcon ?:React . FunctionComponent < IconProps >
33+ trailingIcon ?: React . FunctionComponent < IconProps >
3534} & SxProp &
3635 FontSizeProps
3736
3837const getVariantStyles = ( theme : Theme , variant : VariantType = 'default' ) => {
3938 const style = {
40- default : `
41- color: ${ get ( 'colors.btn.text' ) ( { theme } ) } ;
42- background-color: ${ get ( 'colors.btn.bg' ) ( { theme } ) } ;
39+ default : css `
40+ color : ${ get ( 'colors.btn.text' ) } ;
41+ background-color : ${ get ( 'colors.btn.bg' ) } ;
4342 border-width : 1px ;
4443 border-style : solid;
45- border-color: ${ get ( 'colors.btn.border' ) ( { theme } ) } ;
46- box-shadow: ${ ( get ( 'shadows.btn.shadow' ) ( { theme } ) , get ( 'shadows.btn.insetShadow' ) ( { theme } ) ) } ;
44+ border-color : ${ get ( 'colors.btn.border' ) } ;
45+ box-shadow : ${ ( get ( 'shadows.btn.shadow' ) , get ( 'shadows.btn.insetShadow' ) ) } ;
4746 & : hover : not ([disabled ]) {
48- background-color: ${ get ( 'colors.btn.hoverBg' ) ( { theme } ) } ;
47+ background-color : ${ get ( 'colors.btn.hoverBg' ) } ;
4948 }
5049 // focus must come before :active so that the active box shadow overrides
5150 & : focus : not ([disabled ]) {
52- box-shadow: ${ get ( 'shadows.btn.focusShadow' ) ( { theme } ) } ;
51+ box-shadow : ${ get ( 'shadows.btn.focusShadow' ) } ;
5352 }
5453 & : active : not ([disabled ]) {
55- background-color: ${ get ( 'colors.btn.selectedBg' ) ( { theme } ) } ;
56- box-shadow: ${ get ( 'shadows.btn.shadowActive' ) ( { theme } ) } ;
54+ background-color : ${ get ( 'colors.btn.selectedBg' ) } ;
55+ box-shadow : ${ get ( 'shadows.btn.shadowActive' ) } ;
5756 }
5857 & : disabled {
59- color: ${ get ( 'colors.primer.fg.disabled' ) ( { theme } ) } ;
60- background-color: ${ get ( 'colors.btn.disabledBg' ) ( { theme } ) } ;
58+ color : ${ get ( 'colors.primer.fg.disabled' ) } ;
59+ background-color : ${ get ( 'colors.btn.disabledBg' ) } ;
6160 }
6261 ` ,
63- primary : `
64- color: ${ get ( 'colors.btn.primary.text' ) ( { theme } ) } ;
65- background-color: ${ get ( 'colors.btn.primary.bg' ) ( { theme } ) } ;
62+ primary : css `
63+ color : ${ get ( 'colors.btn.primary.text' ) } ;
64+ background-color : ${ get ( 'colors.btn.primary.bg' ) } ;
6665 border-width : 1px ;
6766 border-style : solid;
68- border-color: ${ get ( 'colors.border.subtle' ) ( { theme } ) } ;
69- box-shadow: ${ get ( 'shadows.btn.primary.shadow' ) ( { theme } ) } ;
67+ border-color : ${ get ( 'colors.border.subtle' ) } ;
68+ box-shadow : ${ get ( 'shadows.btn.primary.shadow' ) } ;
7069
7170 & : hover : not ([disabled ]) {
72- color: ${ get ( 'colors.btn.primary.hoverText' ) ( { theme } ) } ;
73- background-color: ${ get ( 'colors.btn.primary.hoverBg' ) ( { theme } ) } ;
71+ color : ${ get ( 'colors.btn.primary.hoverText' ) } ;
72+ background-color : ${ get ( 'colors.btn.primary.hoverBg' ) } ;
7473 }
7574 // focus must come before :active so that the active box shadow overrides
7675 & : focus : not ([disabled ]) {
77- box-shadow: ${ get ( 'shadows.btn.primary.focusShadow' ) ( { theme } ) } ;
76+ box-shadow : ${ get ( 'shadows.btn.primary.focusShadow' ) } ;
7877 }
7978
8079 & : active : not ([disabled ]) {
81- background-color: ${ get ( 'colors.btn.primary.selectedBg' ) ( { theme } ) } ;
82- box-shadow: ${ get ( 'shadows.btn.primary.selectedShadow' ) ( { theme } ) } ;
80+ background-color : ${ get ( 'colors.btn.primary.selectedBg' ) } ;
81+ box-shadow : ${ get ( 'shadows.btn.primary.selectedShadow' ) } ;
8382 }
8483
8584 & : disabled {
86- color: ${ get ( 'colors.btn.primary.disabledText' ) ( { theme } ) } ;
87- background-color: ${ get ( 'colors.btn.primary.disabledBg' ) ( { theme } ) } ;
85+ color : ${ get ( 'colors.btn.primary.disabledText' ) } ;
86+ background-color : ${ get ( 'colors.btn.primary.disabledBg' ) } ;
8887 }` ,
89- danger : `
90- color: ${ get ( 'colors.btn.danger.text' ) ( { theme } ) } ;
91- border: 1px solid ${ get ( 'colors.btn.border' ) ( { theme } ) } ;
92- background-color: ${ get ( 'colors.btn.bg' ) ( { theme } ) } ;
93- box-shadow: ${ get ( 'shadows.btn.shadow' ) ( { theme } ) } ;
88+ danger : css `
89+ color : ${ get ( 'colors.btn.danger.text' ) } ;
90+ border : 1px solid ${ get ( 'colors.btn.border' ) } ;
91+ background-color : ${ get ( 'colors.btn.bg' ) } ;
92+ box-shadow : ${ get ( 'shadows.btn.shadow' ) } ;
9493
9594 & : hover : not ([disabled ]) {
96- color: ${ get ( 'colors.btn.danger.hoverText' ) ( { theme } ) } ;
97- background-color: ${ get ( 'colors.btn.danger.hoverBg' ) ( { theme } ) } ;
98- border-color: ${ get ( 'colors.btn.danger.hoverBorder' ) ( { theme } ) } ;
99- box-shadow: ${ get ( 'shadows.btn.danger.hoverShadow' ) ( { theme } ) } ;
95+ color : ${ get ( 'colors.btn.danger.hoverText' ) } ;
96+ background-color : ${ get ( 'colors.btn.danger.hoverBg' ) } ;
97+ border-color : ${ get ( 'colors.btn.danger.hoverBorder' ) } ;
98+ box-shadow : ${ get ( 'shadows.btn.danger.hoverShadow' ) } ;
10099 }
101100 // focus must come before :active so that the active box shadow overrides
102101 & : focus : not ([disabled ]) {
103- border-color: ${ get ( 'colors.btn.danger.focusBorder' ) ( { theme } ) } ;
104- box-shadow: ${ get ( 'shadows.btn.danger.focusShadow' ) ( { theme } ) } ;
102+ border-color : ${ get ( 'colors.btn.danger.focusBorder' ) } ;
103+ box-shadow : ${ get ( 'shadows.btn.danger.focusShadow' ) } ;
105104 }
106105
107106 & : active : not ([disabled ]) {
108- color: ${ get ( 'colors.btn.danger.selectedText' ) ( { theme } ) } ;
109- background-color: ${ get ( 'colors.btn.danger.selectedBg' ) ( { theme } ) } ;
110- box-shadow: ${ get ( 'shadows.btn.danger.selectedShadow' ) ( { theme } ) } ;
111- border-color: ${ get ( 'colors.btn.danger.selectedBorder' ) ( { theme } ) } ;
107+ color : ${ get ( 'colors.btn.danger.selectedText' ) } ;
108+ background-color : ${ get ( 'colors.btn.danger.selectedBg' ) } ;
109+ box-shadow : ${ get ( 'shadows.btn.danger.selectedShadow' ) } ;
110+ border-color : ${ get ( 'colors.btn.danger.selectedBorder' ) } ;
112111 }
113112
114113 & : disabled {
115- color: ${ get ( 'colors.btn.danger.disabledText' ) ( { theme } ) } ;
116- background-color: ${ get ( 'colors.btn.danger.disabledBg' ) ( { theme } ) } ;
117- border-color: ${ get ( 'colors.btn.danger.disabledBorder' ) ( { theme } ) } ;
114+ color : ${ get ( 'colors.btn.danger.disabledText' ) } ;
115+ background-color : ${ get ( 'colors.btn.danger.disabledBg' ) } ;
116+ border-color : ${ get ( 'colors.btn.danger.disabledBorder' ) } ;
118117 }
119118 ` ,
120- invisible : `
121- color: ${ get ( 'colors.accent.fg' ) ( { theme } ) } ;
119+ invisible : css `
120+ color : ${ get ( 'colors.accent.fg' ) } ;
122121 background-color : transparent;
123122 border : 0 ;
124- border-radius: ${ get ( 'radii.2' ) ( { theme } ) } ;
123+ border-radius : ${ get ( 'radii.2' ) } ;
125124 box-shadow : none;
126125
127126 & : disabled {
128- color: ${ get ( 'colors.primer.fg.disabled' ) ( { theme } ) } ;
127+ color : ${ get ( 'colors.primer.fg.disabled' ) } ;
129128 }
130129 & : focus : not ([disabled ]) {
131- box-shadow: ${ get ( 'shadows.btn.focusShadow' ) ( { theme } ) } ;
130+ box-shadow : ${ get ( 'shadows.btn.focusShadow' ) } ;
132131 }
133132 & : hover : not ([disabled ]) {
134- background-color: ${ get ( 'colors.btn.hoverBg' ) ( { theme } ) } ;
133+ background-color : ${ get ( 'colors.btn.hoverBg' ) } ;
135134 }
136135 & : active : not ([disabled ]) {
137- background-color: ${ get ( 'colors.btn.selectedBg' ) ( { theme } ) } ;
136+ background-color : ${ get ( 'colors.btn.selectedBg' ) } ;
138137 }
139138 `
140139 }
@@ -178,26 +177,25 @@ const ButtonBase = styled.button<ButtonBaseProps & {iconOnly: boolean}>`
178177
179178const Button = forwardRef < HTMLAnchorElement | HTMLButtonElement , ComponentProps < typeof ButtonBase > > (
180179 ( { children, ...props } , forwardedRef ) => {
181- const { icon : Icon , caret, size} = props
182- let iconOnly = false
183- if ( Icon && ! children ) {
184- iconOnly = true
185- }
180+ const { icon : Icon , leadingIcon : LeadingIcon , trailingIcon : TrailingIcon } = props
181+ let iconOnly = ! ! Icon ;
186182 const iconWrapStyles = {
187183 display : 'inline-block' ,
188- ...( ! iconOnly ? { mr : 2 } : { } )
189184 }
190185 return (
191186 < ButtonBase ref = { forwardedRef } { ...props } iconOnly = { iconOnly } >
192- { Icon && (
193- < Box sx = { iconWrapStyles } aria-hidden = { ! iconOnly } >
194- < Icon size = { size } />
187+ { LeadingIcon && (
188+ < Box as = 'span' data-component = 'leadingIcon' sx = { iconWrapStyles } aria-hidden = { ! iconOnly } >
189+ < LeadingIcon />
195190 </ Box >
196191 ) }
197- { children }
198- { caret && (
199- < Box sx = { { display : 'inline-block' , pl : 3 } } aria-hidden = { true } >
200- < TriangleDownIcon size = { size } />
192+ { Icon && < Box as = 'span' sx = { { display :'inline-block' } } aria-hidden = { ! iconOnly } >
193+ < Icon />
194+ </ Box > }
195+ < span data-component = 'text' hidden = { Icon ? true :false } > { children } </ span >
196+ { TrailingIcon && (
197+ < Box as = 'span' data-component = 'trailingIcon' sx = { iconWrapStyles } aria-hidden = { ! iconOnly } >
198+ < TrailingIcon />
201199 </ Box >
202200 ) }
203201 </ ButtonBase >
@@ -212,9 +210,6 @@ Button.defaultProps = {
212210 variant : 'default'
213211}
214212
215- const NewButton = Object . assign ( Button , {
216- Counter
217- } )
218213
219- export type NewButtonProps = ComponentProps < typeof Button >
220- export default NewButton
214+ export type ButtonProps = ComponentProps < typeof Button >
215+ export default Button
0 commit comments