Skip to content

Instantly share code, notes, and snippets.

@pedronauck pedronauck/Button.tsx

Last active Apr 15, 2019
Embed
What would you like to do?
Beauty Button
import * as t from 'PRIVATE_PACKAGE'
import { css } from 'styled-components'
const hover = (content: any) => css`
&:not(:disabled):hover,
&:not(:disabled):focus,
&:not(:disabled):active,
&:not(:disabled).active {
${content};
}
`
export const base = css`
${hover(css`
background: ${t.neutrals('N2')};
`)}
`
export const filled = css`
${hover(css`
background: ${t.brighten(t.intentBase, 0.4)};
`)}
`
export const ghost = css`
${hover(css`
background: ${t.intentBase};
color: ${t.intentLight};
`)}
`
export const link = css`
${hover(css`
background: transparent;
`)}
`
import * as React from 'react'
import rem from 'polished/lib/helpers/rem'
import styled from 'styled-components'
import * as t from 'PRIVATE_PACKAGE'
import { Icon } from '../Icon'
import { useSpinner } from '../hooks/useSpinner'
import * as appearances from './appearances'
export const scales = {
xs: rem(24),
sm: rem(32),
md: rem(44),
lg: rem(60),
}
const Wrapper = styled.button<t.WithDirectionProp & t.WithLoadingProp>`
${t.centerAlign};
${t.withAppearance};
${t.switchProp('appearance', appearances)};
${t.withDisabled};
${t.withScale};
${t.withSpace};
${t.withLoading};
${t.withRadius};
${t.withShadow};
padding-top: 0;
padding-bottom: 0;
overflow: hidden;
position: relative;
appearance: none;
cursor: pointer;
flex: none;
user-select: none;
white-space: nowrap;
text-decoration: none;
outline: none;
height: ${t.switchProp('scale', scales)};
transition: all 0.2s;
${t.classOf('Icon')} {
transition: fill 0.3s;
transform: scale(0.7);
}
`
const ButtonContent = styled.div<t.WithDirectionProp & t.WithScaleProp>`
${t.centerAlign};
${t.withDirection};
transform: translateY(5%);
`
export type ButtonRef = HTMLButtonElement
export type ButtonProps = t.WithAppearanceProps &
t.WithDisabledProp &
t.WithIconProps &
t.WithScaleProp &
t.WithShadowProp &
t.WithLoadingProp &
t.WithRadiusProp &
t.WithSpaceProps &
React.ButtonHTMLAttributes<ButtonRef>
export const Button = React.forwardRef<ButtonRef, ButtonProps>(
({ icon, iconPosition = 'left', loading, ...props }, ref) => {
const withSpinner = useSpinner(Boolean(loading))
const position = iconPosition as t.Directions
return (
<Wrapper {...props} ref={ref} loading={loading} direction={position}>
{withSpinner(
<ButtonContent direction={position}>
{icon && <Icon name={icon} />}
{props.children}
</ButtonContent>
)}
</Wrapper>
)
}
)
Button.displayName = 'Button'
Button.defaultProps = {
appearance: 'base',
intent: 'info',
radius: 'round',
scale: 'md',
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
You can’t perform that action at this time.