@luminati-io/uikit 1.3.0 → 1.5.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/assets/fonts/Inter-Regular.ttf +0 -0
- package/assets/fonts/Inter-SemiBold.ttf +0 -0
- package/assets/icons/account.svg +1 -8
- package/assets/icons/adapt.svg +1 -4
- package/assets/icons/add.svg +1 -3
- package/assets/icons/add_circle.svg +1 -5
- package/assets/icons/add_funds.svg +1 -7
- package/assets/icons/attach.svg +1 -3
- package/assets/icons/book_help.svg +1 -4
- package/assets/icons/building.svg +1 -3
- package/assets/icons/calendar.svg +1 -13
- package/assets/icons/calendar_graph.svg +1 -14
- package/assets/icons/call.svg +1 -5
- package/assets/icons/camera.svg +1 -5
- package/assets/icons/cart.svg +1 -3
- package/assets/icons/close.svg +1 -3
- package/assets/icons/close_circle.svg +1 -3
- package/assets/icons/close_small.svg +1 -5
- package/assets/icons/collapse.svg +1 -4
- package/assets/icons/column.svg +1 -22
- package/assets/icons/columns.svg +1 -10
- package/assets/icons/connect.svg +1 -3
- package/assets/icons/contact_support.svg +1 -3
- package/assets/icons/copy.svg +1 -3
- package/assets/icons/copy_small.svg +1 -3
- package/assets/icons/customize.svg +1 -6
- package/assets/icons/maximize.svg +1 -1
- package/dist/uikit.umd.js +1 -1
- package/package.json +6 -3
- package/src/button/button.js +121 -0
- package/src/button/index.js +6 -0
- package/src/button/loading_icon.js +46 -0
- package/src/icon.js +1 -5
- package/src/icon_button.js +25 -21
- package/src/index.js +32 -10
- package/src/input/index.js +6 -0
- package/src/input/toggle.js +105 -0
- package/src/layout/flex.js +19 -1
- package/src/link/index.js +6 -0
- package/src/link/link.js +84 -0
- package/src/progress/index.js +1 -1
- package/src/tooltip.js +99 -0
- package/src/utils.js +135 -1
- package/webpack.common.js +2 -4
- package/webpack.shared.js +11 -0
- package/src/button.js +0 -180
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@luminati-io/uikit",
|
|
3
|
-
"version": "1.
|
|
3
|
+
"version": "1.5.0",
|
|
4
4
|
"author": "Bright Data (http://brightdata.com)",
|
|
5
5
|
"license": "ISC",
|
|
6
6
|
"description": "brightdata's design system",
|
|
@@ -12,9 +12,11 @@
|
|
|
12
12
|
"webpack.*.js"
|
|
13
13
|
],
|
|
14
14
|
"dependencies": {
|
|
15
|
-
"
|
|
15
|
+
"@popperjs/core": "^2.11.6",
|
|
16
|
+
"lodash": "^4.17.21",
|
|
16
17
|
"prop-types": "^15.8.1",
|
|
17
|
-
"
|
|
18
|
+
"react-popper": "^2.3.0",
|
|
19
|
+
"styled-components": "^5.3.6"
|
|
18
20
|
},
|
|
19
21
|
"peerDependencies": {
|
|
20
22
|
"react": ">=16.9.0",
|
|
@@ -30,6 +32,7 @@
|
|
|
30
32
|
"@storybook/addon-links": "^6.5.15",
|
|
31
33
|
"@storybook/builder-webpack4": "^6.5.15",
|
|
32
34
|
"@storybook/builder-webpack5": "^6.5.15",
|
|
35
|
+
"@storybook/jest": "0.0.10",
|
|
33
36
|
"@storybook/manager-webpack4": "^6.5.15",
|
|
34
37
|
"@storybook/manager-webpack5": "^6.5.15",
|
|
35
38
|
"@storybook/react": "^6.5.15",
|
|
@@ -0,0 +1,121 @@
|
|
|
1
|
+
// LICENSE_CODE ZON
|
|
2
|
+
'use strict'; /*jslint react:true*/
|
|
3
|
+
|
|
4
|
+
import React from 'react';
|
|
5
|
+
import styled, {css} from 'styled-components';
|
|
6
|
+
import PT from 'prop-types';
|
|
7
|
+
import {
|
|
8
|
+
iconNames,
|
|
9
|
+
toPixel,
|
|
10
|
+
toButtonSize,
|
|
11
|
+
getCommonProps,
|
|
12
|
+
getButtonColors,
|
|
13
|
+
getIconProps,
|
|
14
|
+
} from '../utils';
|
|
15
|
+
import typography from '../Typography';
|
|
16
|
+
import Icon from '../icon';
|
|
17
|
+
import LoadingIcon from './loading_icon';
|
|
18
|
+
|
|
19
|
+
const {Typography, Label} = typography;
|
|
20
|
+
|
|
21
|
+
const Button = React.forwardRef((props, ref)=>{
|
|
22
|
+
const {
|
|
23
|
+
text,
|
|
24
|
+
variant,
|
|
25
|
+
size,
|
|
26
|
+
disabled,
|
|
27
|
+
loading,
|
|
28
|
+
loadingText,
|
|
29
|
+
} = props;
|
|
30
|
+
const {isLeft, isRight, ...iconProps} = getIconProps('Button', props);
|
|
31
|
+
return <StyledButton
|
|
32
|
+
ref={ref}
|
|
33
|
+
type="button"
|
|
34
|
+
{...getCommonProps(props)}
|
|
35
|
+
variant={variant}
|
|
36
|
+
size={size}
|
|
37
|
+
disabled={loading||disabled}
|
|
38
|
+
iconPlacement={isLeft||loading?'left':isRight?'right':''}
|
|
39
|
+
>
|
|
40
|
+
{loading&&<LoadingIcon size={iconProps.size}/>}
|
|
41
|
+
{isLeft&&!loading&&<Icon {...iconProps}/>}
|
|
42
|
+
<Label variant={size=='xs'?'sm':'lg'} no_wrap>
|
|
43
|
+
{loading?loadingText:text}
|
|
44
|
+
</Label>
|
|
45
|
+
{isRight&&!loading&&<Icon {...iconProps}/>}
|
|
46
|
+
</StyledButton>;
|
|
47
|
+
});
|
|
48
|
+
Button.displayName = 'Button';
|
|
49
|
+
Button.defaultProps = {
|
|
50
|
+
variant: 'primary',
|
|
51
|
+
size: 'md',
|
|
52
|
+
iconPlacement: 'left',
|
|
53
|
+
loadingText: 'Loading...',
|
|
54
|
+
};
|
|
55
|
+
Button.propTypes = {
|
|
56
|
+
text: PT.string.isRequired,
|
|
57
|
+
variant: PT.oneOf(['primary', 'secondary', 'negative',
|
|
58
|
+
'negative_secondary', 'positive', 'white']),
|
|
59
|
+
size: PT.oneOf(['xs', 'sm', 'md', 'lg']),
|
|
60
|
+
icon: PT.oneOf(iconNames),
|
|
61
|
+
iconPlacement: PT.oneOf(['left', 'right']),
|
|
62
|
+
disabled: PT.bool,
|
|
63
|
+
loading: PT.bool,
|
|
64
|
+
loadingText: PT.string,
|
|
65
|
+
};
|
|
66
|
+
|
|
67
|
+
const StyledButton = styled.button`
|
|
68
|
+
display: inline-flex;
|
|
69
|
+
align-items: center;
|
|
70
|
+
justify-content: center;
|
|
71
|
+
border-radius: 4px;
|
|
72
|
+
cursor: pointer;
|
|
73
|
+
&:disabled { cursor: not-allowed; }
|
|
74
|
+
text-decoration: none;
|
|
75
|
+
&:hover, &:visited, :focus { text-decoration: none; }
|
|
76
|
+
${props=>{
|
|
77
|
+
let gap = 4;
|
|
78
|
+
let paddingLeft = 16;
|
|
79
|
+
let paddingRight = 16;
|
|
80
|
+
if (props.iconPlacement=='left')
|
|
81
|
+
paddingLeft = 12;
|
|
82
|
+
else if (props.iconPlacement=='right')
|
|
83
|
+
paddingRight = 12;
|
|
84
|
+
if (props.size=='xs')
|
|
85
|
+
{
|
|
86
|
+
gap = 2;
|
|
87
|
+
paddingLeft = paddingRight = 8;
|
|
88
|
+
}
|
|
89
|
+
return css`
|
|
90
|
+
gap: ${toPixel(gap)};
|
|
91
|
+
padding-left: ${toPixel(paddingLeft)};
|
|
92
|
+
padding-right: ${toPixel(paddingRight)};
|
|
93
|
+
`;
|
|
94
|
+
}}
|
|
95
|
+
${props=>{
|
|
96
|
+
const colors = getButtonColors(props);
|
|
97
|
+
return css`
|
|
98
|
+
background-color: ${colors.backColor};
|
|
99
|
+
border: ${colors.border||'0 none'};
|
|
100
|
+
${Typography} { color: ${colors.color}; }
|
|
101
|
+
[data-icon] {
|
|
102
|
+
color: ${colors.iconColor||colors.color};
|
|
103
|
+
}
|
|
104
|
+
${colors.hover&&`&:hover {
|
|
105
|
+
background-color: ${colors.hover.backColor};
|
|
106
|
+
}`}
|
|
107
|
+
${colors.active&&`&:active {
|
|
108
|
+
background-color: ${colors.active.backColor};
|
|
109
|
+
border: ${colors.active.border};
|
|
110
|
+
box-shadow: ${colors.active.boxShadow};
|
|
111
|
+
${colors.active.iconColor&&`[data-icon] {
|
|
112
|
+
color: ${colors.active.iconColor};
|
|
113
|
+
}`}
|
|
114
|
+
}`}
|
|
115
|
+
`;
|
|
116
|
+
}}
|
|
117
|
+
${props=>toButtonSize(props.size)}
|
|
118
|
+
`;
|
|
119
|
+
StyledButton.displayName = 'StyledButton';
|
|
120
|
+
|
|
121
|
+
export default Button;
|
|
@@ -0,0 +1,46 @@
|
|
|
1
|
+
// LICENSE_CODE ZON
|
|
2
|
+
'use strict'; /*jslint react:true*/
|
|
3
|
+
|
|
4
|
+
import React from 'react';
|
|
5
|
+
import styled from 'styled-components';
|
|
6
|
+
import {toIconSize} from '../utils';
|
|
7
|
+
|
|
8
|
+
const LoadingIcon = props=>
|
|
9
|
+
<Spinner stroke="rgba(0,106,220,1)" viewBox="0 0 24 24" {...props}>
|
|
10
|
+
<g className="spinner_V8m1">
|
|
11
|
+
<circle cx="12" cy="12" r="9.5" fill="none" strokeWidth="3"/>
|
|
12
|
+
</g>
|
|
13
|
+
</Spinner>;
|
|
14
|
+
|
|
15
|
+
const Spinner = styled.svg`
|
|
16
|
+
${props=>toIconSize(props.size)}
|
|
17
|
+
.spinner_V8m1 {
|
|
18
|
+
transform-origin: center;
|
|
19
|
+
animation: spinner_zKoa 2s linear infinite
|
|
20
|
+
}
|
|
21
|
+
.spinner_V8m1 circle {
|
|
22
|
+
stroke-linecap: round;
|
|
23
|
+
animation: spinner_YpZS 1.5s ease-in-out infinite
|
|
24
|
+
}
|
|
25
|
+
@keyframes spinner_zKoa {
|
|
26
|
+
100% {
|
|
27
|
+
transform: rotate(360deg)
|
|
28
|
+
}
|
|
29
|
+
}
|
|
30
|
+
@keyframes spinner_YpZS {
|
|
31
|
+
0% {
|
|
32
|
+
stroke-dasharray: 0 150;
|
|
33
|
+
stroke-dashoffset: 0
|
|
34
|
+
}
|
|
35
|
+
47.5% {
|
|
36
|
+
stroke-dasharray: 42 150;
|
|
37
|
+
stroke-dashoffset: -16
|
|
38
|
+
}
|
|
39
|
+
95%, 100% {
|
|
40
|
+
stroke-dasharray: 42 150;
|
|
41
|
+
stroke-dashoffset: -59
|
|
42
|
+
}
|
|
43
|
+
}
|
|
44
|
+
`;
|
|
45
|
+
|
|
46
|
+
export default LoadingIcon;
|
package/src/icon.js
CHANGED
|
@@ -36,6 +36,7 @@ const Icon = React.forwardRef((props, ref)=>{
|
|
|
36
36
|
size={size}
|
|
37
37
|
viewBox={ic.viewBox}
|
|
38
38
|
color={theme.color[color]}
|
|
39
|
+
data-icon={name}
|
|
39
40
|
>
|
|
40
41
|
<use href={`#${ic.id}`}/>
|
|
41
42
|
</StyledSvg>;
|
|
@@ -48,11 +49,6 @@ Icon.propTypes = {
|
|
|
48
49
|
size: PT.oneOf(['xxs', 'xs', 'sm', 'md', 'lg', 'xl']),
|
|
49
50
|
};
|
|
50
51
|
|
|
51
|
-
export const IconColorComp = styled.rect.attrs({
|
|
52
|
-
width: '100%',
|
|
53
|
-
height: '100%',
|
|
54
|
-
})``;
|
|
55
|
-
|
|
56
52
|
const StyledSvg = styled.svg`
|
|
57
53
|
color: ${props=>props.color};
|
|
58
54
|
${props=>toIconSize(props.size)}
|
package/src/icon_button.js
CHANGED
|
@@ -5,16 +5,24 @@ import React from 'react';
|
|
|
5
5
|
import styled, {css} from 'styled-components';
|
|
6
6
|
import PT from 'prop-types';
|
|
7
7
|
import utils from './utils';
|
|
8
|
-
import Icon
|
|
8
|
+
import Icon from './icon';
|
|
9
|
+
import Tooltip from './tooltip';
|
|
9
10
|
|
|
10
|
-
const {theme, toPixel, getCommonProps, iconNames} = utils;
|
|
11
|
+
const {theme, toPixel, getCommonProps, iconNames, tooltipPlacements} = utils;
|
|
11
12
|
|
|
12
13
|
const IconButton = React.forwardRef((props, ref)=>{
|
|
13
|
-
const {variant
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
14
|
+
const {variant, disabled, icon, tooltip, tooltipPlacement} = props;
|
|
15
|
+
return <Tooltip tooltip={tooltip} placement={tooltipPlacement}>
|
|
16
|
+
<StyledIconButton
|
|
17
|
+
ref={ref}
|
|
18
|
+
{...getCommonProps(props)}
|
|
19
|
+
variant={variant}
|
|
20
|
+
disabled={disabled}
|
|
21
|
+
data-testid="icon_button"
|
|
22
|
+
>
|
|
23
|
+
<Icon name={icon} size="sm" />
|
|
24
|
+
</StyledIconButton>
|
|
25
|
+
</Tooltip>;
|
|
18
26
|
});
|
|
19
27
|
IconButton.displayName = 'IconButton';
|
|
20
28
|
IconButton.defaultProps = {variant: 'icon-button'};
|
|
@@ -22,6 +30,8 @@ IconButton.propTypes = {
|
|
|
22
30
|
variant: PT.oneOf(['icon', 'icon-button']),
|
|
23
31
|
icon: PT.oneOf(iconNames).isRequired,
|
|
24
32
|
disabled: PT.bool,
|
|
33
|
+
tooltip: PT.node,
|
|
34
|
+
tooltipPlacement: PT.oneOf(tooltipPlacements),
|
|
25
35
|
};
|
|
26
36
|
|
|
27
37
|
const StyledIconButton = styled.button`
|
|
@@ -34,36 +44,30 @@ const StyledIconButton = styled.button`
|
|
|
34
44
|
${props=>{
|
|
35
45
|
return css`
|
|
36
46
|
background-color: ${theme.color.white};
|
|
37
|
-
border: ${props
|
|
47
|
+
border: ${props.variant=='icon'?'0 none;':
|
|
38
48
|
`1px solid ${theme.color.gray_6}`};
|
|
39
|
-
${
|
|
40
|
-
fill: ${theme.color.gray_9};
|
|
41
|
-
}
|
|
49
|
+
[data-icon] { color: ${theme.color.gray_9}; }
|
|
42
50
|
`;
|
|
43
51
|
}}
|
|
44
52
|
&:hover:not(:disabled) {
|
|
45
53
|
background-color: ${theme.color.gray_2};
|
|
46
|
-
border: ${props=>props
|
|
54
|
+
border: ${props=>props.variant=='icon'?'0 none;':
|
|
47
55
|
`1px solid ${theme.color.gray_8}`};
|
|
48
56
|
}
|
|
49
57
|
&:active:not(:disabled) {
|
|
50
58
|
background-color: ${theme.color.blue_4};
|
|
51
|
-
border: ${props=>props
|
|
59
|
+
border: ${props=>props.variant=='icon'?'0 none;':
|
|
52
60
|
`1px solid ${theme.color.blue_4}`};
|
|
53
|
-
${
|
|
54
|
-
fill: ${theme.color.blue_11};
|
|
55
|
-
}
|
|
61
|
+
[data-icon] { color: ${theme.color.blue_11}; }
|
|
56
62
|
}
|
|
57
63
|
&:disabled {
|
|
58
|
-
border: ${props=>props
|
|
64
|
+
border: ${props=>props.variant=='icon'?'0 none;':
|
|
59
65
|
`1px solid ${theme.color.gray_7}`};
|
|
60
|
-
${
|
|
61
|
-
fill: ${theme.color.gray_7};
|
|
62
|
-
}
|
|
66
|
+
[data-icon] { color: ${theme.color.gray_7}; }
|
|
63
67
|
cursor: not-allowed;
|
|
64
68
|
}
|
|
65
69
|
${props=>{
|
|
66
|
-
let w = props
|
|
70
|
+
let w = props.variant=='icon'?24:36;
|
|
67
71
|
return css`
|
|
68
72
|
width: ${toPixel(w)};
|
|
69
73
|
height: ${toPixel(w)};
|
package/src/index.js
CHANGED
|
@@ -1,22 +1,44 @@
|
|
|
1
1
|
// LICENSE_CODE ZON
|
|
2
2
|
'use strict'; /*jslint react:true*/
|
|
3
|
-
import Button from './button';
|
|
4
|
-
import
|
|
3
|
+
import {Button} from './button';
|
|
4
|
+
import Input from './input';
|
|
5
|
+
import Typography from './Typography';
|
|
5
6
|
import InfoChip from './infochip';
|
|
6
|
-
import
|
|
7
|
-
import
|
|
7
|
+
import Layout from './layout';
|
|
8
|
+
import {Link} from './link';
|
|
9
|
+
import {Progress, ProgressBar} from './progress';
|
|
8
10
|
import Icon from './icon';
|
|
9
11
|
import IconButton from './icon_button';
|
|
12
|
+
import Tooltip, {withTooltip} from './tooltip';
|
|
10
13
|
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
+
export {
|
|
15
|
+
Layout,
|
|
16
|
+
Link,
|
|
17
|
+
Typography,
|
|
18
|
+
Button,
|
|
19
|
+
Input,
|
|
20
|
+
InfoChip,
|
|
21
|
+
Progress,
|
|
22
|
+
ProgressBar,
|
|
23
|
+
Icon,
|
|
24
|
+
IconButton,
|
|
25
|
+
Tooltip,
|
|
26
|
+
withTooltip,
|
|
27
|
+
};
|
|
14
28
|
|
|
15
|
-
export const Layout = {Box, Flex};
|
|
16
|
-
export const Typography = {Header, Label, Hyperlink, Paragraph};
|
|
17
29
|
const UIKit = {
|
|
18
30
|
Layout,
|
|
31
|
+
Link,
|
|
19
32
|
Typography,
|
|
20
|
-
Button,
|
|
33
|
+
Button,
|
|
34
|
+
Input,
|
|
35
|
+
InfoChip,
|
|
36
|
+
Progress,
|
|
37
|
+
ProgressBar,
|
|
38
|
+
Icon,
|
|
39
|
+
IconButton,
|
|
40
|
+
Tooltip,
|
|
41
|
+
withTooltip,
|
|
21
42
|
};
|
|
43
|
+
|
|
22
44
|
export default UIKit;
|
|
@@ -0,0 +1,105 @@
|
|
|
1
|
+
// LICENSE_CODE ZON
|
|
2
|
+
'use strict'; /*jslint react:true*/
|
|
3
|
+
|
|
4
|
+
import React, {useCallback} from 'react';
|
|
5
|
+
import styled from 'styled-components';
|
|
6
|
+
import PT from 'prop-types';
|
|
7
|
+
import {theme, toPixel, getCommonProps} from '../utils';
|
|
8
|
+
import typography from '../Typography';
|
|
9
|
+
|
|
10
|
+
const {Label} = typography;
|
|
11
|
+
|
|
12
|
+
const Toggle = props=>{
|
|
13
|
+
const {value, label, disabled, size, onChange} = props;
|
|
14
|
+
const handleChange = useCallback(evt=>{
|
|
15
|
+
const {checked} = evt.target;
|
|
16
|
+
onChange?.(checked, evt);
|
|
17
|
+
}, [onChange]);
|
|
18
|
+
const color = disabled?value?'gray-11':'gray-9':
|
|
19
|
+
value?'gray-11-50':'gray-11';
|
|
20
|
+
return <ToggleLabel {...getCommonProps(props)} $size={size}>
|
|
21
|
+
<ToggleInput $size={size} checked={value} onChange={handleChange}
|
|
22
|
+
disabled={disabled} />
|
|
23
|
+
{label&&<Label variant="sm" tag="span" color={color} no_wrap>
|
|
24
|
+
{label}
|
|
25
|
+
</Label>}
|
|
26
|
+
</ToggleLabel>;
|
|
27
|
+
};
|
|
28
|
+
Toggle.displayName = 'Toggle';
|
|
29
|
+
Toggle.defaultProps = {size: 'sm'};
|
|
30
|
+
Toggle.propTypes = {
|
|
31
|
+
value: PT.bool,
|
|
32
|
+
label: PT.string,
|
|
33
|
+
disabled: PT.bool,
|
|
34
|
+
size: PT.oneOf(['xs', 'sm']),
|
|
35
|
+
onChange: PT.func,
|
|
36
|
+
};
|
|
37
|
+
|
|
38
|
+
const ToggleLabel = styled.label`
|
|
39
|
+
cursor: pointer;
|
|
40
|
+
display: flex;
|
|
41
|
+
align-items: center;
|
|
42
|
+
gap: 4px;
|
|
43
|
+
margin: 0;
|
|
44
|
+
`;
|
|
45
|
+
ToggleLabel.displayName = 'ToggleLabel';
|
|
46
|
+
|
|
47
|
+
const ToggleInput = styled.input.attrs({type: 'checkbox'})`
|
|
48
|
+
&& {
|
|
49
|
+
box-sizing: border-box;
|
|
50
|
+
width: ${props=>toPixel(props.$size=='xs'?32:44)};
|
|
51
|
+
height: ${props=>toPixel(props.$size=='xs'?16:20)};
|
|
52
|
+
display: flex;
|
|
53
|
+
align-items: center;
|
|
54
|
+
margin: 0;
|
|
55
|
+
padding: 0 1px;
|
|
56
|
+
vertical-align: top;
|
|
57
|
+
background-color: ${theme.color.gray_5};
|
|
58
|
+
border: 1px solid ${theme.color.gray_7};
|
|
59
|
+
border-radius: 25px;
|
|
60
|
+
outline: none;
|
|
61
|
+
outline-offset: 0;
|
|
62
|
+
cursor: pointer;
|
|
63
|
+
appearance: none;
|
|
64
|
+
transition: all 0.3s cubic-bezier(0.2, 0.85, 0.32, 1.2);
|
|
65
|
+
&:hover {
|
|
66
|
+
background-color: ${theme.color.gray_7};
|
|
67
|
+
border-color: ${theme.color.gray_8};
|
|
68
|
+
}
|
|
69
|
+
&:focus {
|
|
70
|
+
outline: none;
|
|
71
|
+
outline-offset: 0;
|
|
72
|
+
background-color: ${theme.color.gray_9};
|
|
73
|
+
border-color: ${theme.color.gray_9};
|
|
74
|
+
}
|
|
75
|
+
&:checked {
|
|
76
|
+
background-color: ${theme.color.blue_11};
|
|
77
|
+
border-color: ${theme.color.blue_11};
|
|
78
|
+
&:hover {
|
|
79
|
+
background-color: ${theme.color.blue_10};
|
|
80
|
+
border-color: ${theme.color.blue_10};
|
|
81
|
+
}
|
|
82
|
+
&:focus {
|
|
83
|
+
background-color: ${theme.color.blue_11};
|
|
84
|
+
border-color: ${theme.color.blue_11};
|
|
85
|
+
outline: 3px solid ${theme.color.blue_5};
|
|
86
|
+
}
|
|
87
|
+
}
|
|
88
|
+
}
|
|
89
|
+
&::after {
|
|
90
|
+
content: "";
|
|
91
|
+
display: block;
|
|
92
|
+
width: ${props=>toPixel(props.$size=='xs'?12:16)};
|
|
93
|
+
height: ${props=>toPixel(props.$size=='xs'?12:16)};
|
|
94
|
+
border-radius: 50%;
|
|
95
|
+
background-color: ${theme.color.white};
|
|
96
|
+
box-shadow: 0 2px 2px rgba(0, 0, 0, 0.1);
|
|
97
|
+
transition: all 0.3s cubic-bezier(0.2, 0.85, 0.32, 1.2);
|
|
98
|
+
}
|
|
99
|
+
&:checked::after {
|
|
100
|
+
transform: translateX(${props=>toPixel(props.$size=='xs'?15:23)});
|
|
101
|
+
}
|
|
102
|
+
`;
|
|
103
|
+
ToggleInput.displayName = 'ToggleInput';
|
|
104
|
+
|
|
105
|
+
export default Toggle;
|
package/src/layout/flex.js
CHANGED
|
@@ -1,11 +1,13 @@
|
|
|
1
1
|
// LICENSE_CODE ZON
|
|
2
2
|
'use strict'; /*jslint react:true*/
|
|
3
3
|
|
|
4
|
+
import React from 'react';
|
|
4
5
|
import styled from 'styled-components';
|
|
6
|
+
import PT from 'prop-types';
|
|
5
7
|
|
|
6
8
|
import Box from './box';
|
|
7
9
|
|
|
8
|
-
const
|
|
10
|
+
const StyledFlex = styled(Box)`
|
|
9
11
|
display: ${props=>props.inline ? 'inline-flex' : 'flex'};
|
|
10
12
|
align-items: ${props=>props.align_items};
|
|
11
13
|
align-content: ${props=>props.align_content};
|
|
@@ -17,7 +19,23 @@ const Flex = styled(Box)`
|
|
|
17
19
|
row-gap: ${props=>props.row_gap};
|
|
18
20
|
column-gap: ${props=>props.column_gap};
|
|
19
21
|
`;
|
|
22
|
+
const Flex = props=>{
|
|
23
|
+
return <StyledFlex {...props}/>;
|
|
24
|
+
};
|
|
20
25
|
Flex.displayName = 'Flex';
|
|
21
26
|
Flex.defaultProps = {flex_direction: 'row'};
|
|
27
|
+
Flex.propTypes = {
|
|
28
|
+
inline: PT.bool,
|
|
29
|
+
align_items: PT.oneOf(['flex-start', 'center']),
|
|
30
|
+
align_content: PT.string,
|
|
31
|
+
justify_items: PT.string,
|
|
32
|
+
justify_content: PT.string,
|
|
33
|
+
flex_wrap: PT.string,
|
|
34
|
+
flex_direction: PT.oneOf(['row', 'row-reverse', 'column',
|
|
35
|
+
'column-reverse']),
|
|
36
|
+
gap: PT.string,
|
|
37
|
+
row_gap: PT.string,
|
|
38
|
+
column_gap: PT.string,
|
|
39
|
+
};
|
|
22
40
|
|
|
23
41
|
export default Flex;
|
package/src/link/link.js
ADDED
|
@@ -0,0 +1,84 @@
|
|
|
1
|
+
// LICENSE_CODE ZON
|
|
2
|
+
'use strict'; /*jslint react:true*/
|
|
3
|
+
|
|
4
|
+
import React from 'react';
|
|
5
|
+
import styled from 'styled-components';
|
|
6
|
+
import PT from 'prop-types';
|
|
7
|
+
import {
|
|
8
|
+
theme,
|
|
9
|
+
iconNames,
|
|
10
|
+
toPixel,
|
|
11
|
+
getCommonProps,
|
|
12
|
+
getIconProps,
|
|
13
|
+
getLinkProps,
|
|
14
|
+
} from '../utils';
|
|
15
|
+
import typography from '../Typography';
|
|
16
|
+
import Icon from '../icon';
|
|
17
|
+
|
|
18
|
+
const {Typography, Label} = typography;
|
|
19
|
+
|
|
20
|
+
const Link = React.forwardRef((props, ref)=>{
|
|
21
|
+
const {text, variant, size, icon} = props;
|
|
22
|
+
const {isLeft, isRight, ...iconProps} = getIconProps('Link', props);
|
|
23
|
+
const labelVariant = {lg: 'lg', sm: 'xs'}[size]||'base';
|
|
24
|
+
return <StyledLink
|
|
25
|
+
ref={ref}
|
|
26
|
+
{...getCommonProps(props)}
|
|
27
|
+
{...getLinkProps(props)}
|
|
28
|
+
variant={variant}
|
|
29
|
+
size={size}
|
|
30
|
+
noIcon={!icon}
|
|
31
|
+
>
|
|
32
|
+
{isLeft&&<Icon {...iconProps}/>}
|
|
33
|
+
<Label variant={labelVariant} no_wrap>{text}</Label>
|
|
34
|
+
{isRight&&<Icon {...iconProps}/>}
|
|
35
|
+
</StyledLink>;
|
|
36
|
+
});
|
|
37
|
+
Link.displayName = 'Link';
|
|
38
|
+
Link.defaultProps = {
|
|
39
|
+
variant: 'primary',
|
|
40
|
+
size: 'md',
|
|
41
|
+
iconPlacement: 'left',
|
|
42
|
+
};
|
|
43
|
+
Link.propTypes = {
|
|
44
|
+
text: PT.string.isRequired,
|
|
45
|
+
variant: PT.oneOf(['primary', 'secondary']),
|
|
46
|
+
size: PT.oneOf(['sm', 'md', 'lg']),
|
|
47
|
+
icon: PT.oneOf(iconNames),
|
|
48
|
+
iconPlacement: PT.oneOf(['left', 'right']),
|
|
49
|
+
href: PT.string,
|
|
50
|
+
newTab: PT.bool,
|
|
51
|
+
};
|
|
52
|
+
|
|
53
|
+
const StyledLink = styled.a`
|
|
54
|
+
display: inline-flex;
|
|
55
|
+
align-items: center;
|
|
56
|
+
justify-content: center;
|
|
57
|
+
text-decoration: none;
|
|
58
|
+
background: 0 none;
|
|
59
|
+
border: 0 none;
|
|
60
|
+
padding: 0;
|
|
61
|
+
gap: ${props=>toPixel(props.size=='lg'?8:4)};
|
|
62
|
+
${Typography} {
|
|
63
|
+
color: ${props=>props.variant=='primary'?
|
|
64
|
+
theme.color.blue_11:theme.color.gray_11_50};
|
|
65
|
+
text-decoration: ${props=>props.variant=='secondary'&&
|
|
66
|
+
props.noIcon?'underline':'none'};
|
|
67
|
+
}
|
|
68
|
+
[data-icon] {
|
|
69
|
+
color: ${props=>props.variant=='primary'?
|
|
70
|
+
theme.color.blue_11:theme.color.gray_11_50};
|
|
71
|
+
}
|
|
72
|
+
&:hover {
|
|
73
|
+
${Typography} {
|
|
74
|
+
color: ${theme.color.blue_11};
|
|
75
|
+
text-decoration: ${props=>props.variant=='secondary'&&
|
|
76
|
+
props.noIcon?'underline':'none'};
|
|
77
|
+
}
|
|
78
|
+
[data-icon] { color: ${theme.color.blue_11}; }
|
|
79
|
+
}
|
|
80
|
+
&:hover, :visited, :focus { text-decoration: none; }
|
|
81
|
+
`;
|
|
82
|
+
StyledLink.displayName = 'StyledLink';
|
|
83
|
+
|
|
84
|
+
export default Link;
|
package/src/progress/index.js
CHANGED