-
Notifications
You must be signed in to change notification settings - Fork 7
Expand file tree
/
Copy pathButton.tsx
More file actions
117 lines (106 loc) · 2.57 KB
/
Button.tsx
File metadata and controls
117 lines (106 loc) · 2.57 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
import { ComponentType, PropsWithChildren } from 'react';
import styled from 'styled-components';
import { getMargin } from '../../theme/utils';
import { Icon } from '../Icon';
export type ButtonVariant =
| 'primary'
| 'secondary'
| 'tertiary'
| 'inline'
| 'special';
enum IconPosition {
Left = 'left',
Right = 'right',
}
export type ButtonProps = PropsWithChildren<{
variant: ButtonVariant;
margin?: string;
id?: string;
type?: 'submit' | 'reset' | 'button';
size?: 's' | 'm' | 'l';
disabled?: boolean;
icon?: ComponentType;
fillIcon?: boolean,
iconPosition?: 'left' | 'right';
onClick?: () => void;
width?: string;
}>;
const sizeMap: Record<string, Record<string, string>> = {
s: {
padding: '4px 16px',
},
m: {
padding: '8px 16px',
},
l: {
padding: '12px 16px',
},
};
const Component = styled.button<ButtonProps>(
({ theme, variant, margin, size, width }) => {
return {
...(theme.BUTTON[variant] || {}),
...(size ? sizeMap[size] : {}),
margin: getMargin({ theme, margin }),
...(width && {width: width})
};
},
);
const IconContainer = styled.span<any>(({ iconPosition }) => ({
display: 'inline-block',
...(iconPosition === IconPosition.Left && { marginRight: '12px' }),
...(iconPosition === IconPosition.Right && { marginLeft: '12px' }),
lineHeight: '24px',
fontSize: '19px',
}));
const StyledIcon = styled(Icon)<any>(({ theme, themeVariant, fillIcon }) => {
return {
color: theme.BUTTON[themeVariant].color,
...(fillIcon && {
svg: {
path: {
fill: theme.BUTTON[themeVariant].color,
},
}
}),
};
});
const renderIconContainer = (
icon: ComponentType,
variant: ButtonVariant,
iconPosition: string = IconPosition.Left,
fillIcon: boolean
) => (
<IconContainer iconPosition={iconPosition}>
<StyledIcon
themeVariant={variant}
icon={icon}
variant="basic"
size="14px"
fillIcon={fillIcon}
/>
</IconContainer>
);
export function Button(buttonProps: ButtonProps) {
const {
type = 'button',
size = 'm',
icon,
iconPosition,
fillIcon = true,
children,
variant,
...props
} = buttonProps;
return (
<Component size={size} type={type} variant={variant} {...props}>
{icon &&
(!iconPosition || iconPosition === IconPosition.Left) &&
renderIconContainer(icon, variant, iconPosition, fillIcon)}
{children}
{icon &&
iconPosition === IconPosition.Right &&
renderIconContainer(icon, variant, iconPosition, fillIcon)}
</Component>
);
}