@capillarytech/blaze-ui 0.1.6-alpha.41 → 0.1.6-alpha.43
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/CapIcon/CapIcon.js +183 -0
- package/CapIcon/index.js +3 -0
- package/CapIcon/styles.js +76 -0
- package/CapLabel/CapLabel.js +126 -0
- package/CapLabel/index.js +3 -0
- package/CapLabel/styles.js +259 -0
- package/CapRow/CapRow.js +123 -0
- package/CapRow/index.js +3 -0
- package/CapRow/styles.js +50 -0
- package/CapTooltip/CapTooltip.js +98 -0
- package/CapTooltip/index.js +3 -0
- package/CapTooltip/styles.js +34 -0
- package/CapTooltipWithInfo/CapTooltipWithInfo.js +82 -0
- package/CapTooltipWithInfo/index.js +3 -0
- package/CapTooltipWithInfo/styles.js +22 -0
- package/CapUnifiedSelect/CapUnifiedSelect.js +44 -32
- package/index.js +5 -0
- package/package.json +1 -1
|
@@ -0,0 +1,183 @@
|
|
|
1
|
+
import React from 'react';
|
|
2
|
+
import PropTypes from 'prop-types';
|
|
3
|
+
import classnames from 'classnames';
|
|
4
|
+
import styled from 'styled-components';
|
|
5
|
+
import * as AntdIcons from '@ant-design/icons';
|
|
6
|
+
import { IconWrapper, BackgroundWrapper, iconStyles } from './styles';
|
|
7
|
+
import withStyles from '../utils/withStyles';
|
|
8
|
+
|
|
9
|
+
const StyledIcon = styled.span`
|
|
10
|
+
${iconStyles}
|
|
11
|
+
`;
|
|
12
|
+
|
|
13
|
+
const getSvgIcon = (type, svgProps = {}) => {
|
|
14
|
+
const icons = {
|
|
15
|
+
// Add your SVG icons here if needed
|
|
16
|
+
};
|
|
17
|
+
|
|
18
|
+
const IconComponent = icons[type];
|
|
19
|
+
return IconComponent ? <IconComponent {...svgProps} /> : null;
|
|
20
|
+
};
|
|
21
|
+
|
|
22
|
+
const getAntIcon = (type) => {
|
|
23
|
+
// Convert kebab-case to PascalCase for Ant Design icon naming
|
|
24
|
+
const pascalCase = type
|
|
25
|
+
.split('-')
|
|
26
|
+
.map(part => part.charAt(0).toUpperCase() + part.slice(1))
|
|
27
|
+
.join('');
|
|
28
|
+
|
|
29
|
+
// Try different naming conventions
|
|
30
|
+
const iconName = `${pascalCase}Outlined`;
|
|
31
|
+
const iconNameFilled = `${pascalCase}Filled`;
|
|
32
|
+
const iconNameTwoTone = `${pascalCase}TwoTone`;
|
|
33
|
+
|
|
34
|
+
return AntdIcons[iconName] || AntdIcons[iconNameFilled] || AntdIcons[iconNameTwoTone];
|
|
35
|
+
};
|
|
36
|
+
|
|
37
|
+
const CapIcon = ({
|
|
38
|
+
type,
|
|
39
|
+
size = 'm',
|
|
40
|
+
style = {},
|
|
41
|
+
className = '',
|
|
42
|
+
disabled = false,
|
|
43
|
+
spin = false,
|
|
44
|
+
rotate,
|
|
45
|
+
withBackground = false,
|
|
46
|
+
backgroundProps = {},
|
|
47
|
+
onClick,
|
|
48
|
+
textLabel,
|
|
49
|
+
component,
|
|
50
|
+
svgProps = {},
|
|
51
|
+
allowSvg = true,
|
|
52
|
+
...rest
|
|
53
|
+
}) => {
|
|
54
|
+
const handleClick = (e) => {
|
|
55
|
+
if (!disabled && onClick) {
|
|
56
|
+
onClick(e);
|
|
57
|
+
}
|
|
58
|
+
};
|
|
59
|
+
|
|
60
|
+
// Render custom component if provided
|
|
61
|
+
if (component) {
|
|
62
|
+
return (
|
|
63
|
+
<IconWrapper
|
|
64
|
+
className={classnames('cap-icon', size, { 'with-text-label': textLabel }, className)}
|
|
65
|
+
style={style}
|
|
66
|
+
disabled={disabled}
|
|
67
|
+
onClick={handleClick}
|
|
68
|
+
{...rest}
|
|
69
|
+
>
|
|
70
|
+
{component}
|
|
71
|
+
{textLabel}
|
|
72
|
+
</IconWrapper>
|
|
73
|
+
);
|
|
74
|
+
}
|
|
75
|
+
|
|
76
|
+
// Try to get SVG icon if allowSvg is true
|
|
77
|
+
const svgIcon = allowSvg && type ? getSvgIcon(type, svgProps) : null;
|
|
78
|
+
|
|
79
|
+
// If SVG icon exists and allowSvg is true, use it
|
|
80
|
+
if (svgIcon) {
|
|
81
|
+
const iconComponent = (
|
|
82
|
+
<IconWrapper
|
|
83
|
+
className={classnames('cap-icon', size, { spin }, { 'with-text-label': textLabel }, className)}
|
|
84
|
+
style={{
|
|
85
|
+
...style,
|
|
86
|
+
transform: rotate ? `rotate(${rotate}deg)` : undefined
|
|
87
|
+
}}
|
|
88
|
+
disabled={disabled}
|
|
89
|
+
onClick={handleClick}
|
|
90
|
+
{...rest}
|
|
91
|
+
>
|
|
92
|
+
{svgIcon}
|
|
93
|
+
{textLabel}
|
|
94
|
+
</IconWrapper>
|
|
95
|
+
);
|
|
96
|
+
|
|
97
|
+
return withBackground ? (
|
|
98
|
+
<BackgroundWrapper size={size} {...backgroundProps}>
|
|
99
|
+
{iconComponent}
|
|
100
|
+
</BackgroundWrapper>
|
|
101
|
+
) : iconComponent;
|
|
102
|
+
}
|
|
103
|
+
|
|
104
|
+
// Try to get Ant Design icon
|
|
105
|
+
const AntIcon = type ? getAntIcon(type) : null;
|
|
106
|
+
|
|
107
|
+
if (AntIcon) {
|
|
108
|
+
const iconComponent = (
|
|
109
|
+
<IconWrapper
|
|
110
|
+
className={classnames('cap-icon', size, { 'with-text-label': textLabel }, className)}
|
|
111
|
+
style={style}
|
|
112
|
+
disabled={disabled}
|
|
113
|
+
onClick={handleClick}
|
|
114
|
+
{...rest}
|
|
115
|
+
>
|
|
116
|
+
<AntIcon
|
|
117
|
+
spin={spin}
|
|
118
|
+
rotate={rotate}
|
|
119
|
+
/>
|
|
120
|
+
{textLabel}
|
|
121
|
+
</IconWrapper>
|
|
122
|
+
);
|
|
123
|
+
|
|
124
|
+
return withBackground ? (
|
|
125
|
+
<BackgroundWrapper size={size} {...backgroundProps}>
|
|
126
|
+
{iconComponent}
|
|
127
|
+
</BackgroundWrapper>
|
|
128
|
+
) : iconComponent;
|
|
129
|
+
}
|
|
130
|
+
|
|
131
|
+
// Fallback: render an empty icon container
|
|
132
|
+
return (
|
|
133
|
+
<IconWrapper
|
|
134
|
+
className={classnames('cap-icon', size, { 'with-text-label': textLabel }, className)}
|
|
135
|
+
style={style}
|
|
136
|
+
disabled={disabled}
|
|
137
|
+
onClick={handleClick}
|
|
138
|
+
{...rest}
|
|
139
|
+
>
|
|
140
|
+
{textLabel}
|
|
141
|
+
</IconWrapper>
|
|
142
|
+
);
|
|
143
|
+
};
|
|
144
|
+
|
|
145
|
+
CapIcon.propTypes = {
|
|
146
|
+
type: PropTypes.string,
|
|
147
|
+
size: PropTypes.oneOf(['xs', 's', 'm', 'l']),
|
|
148
|
+
style: PropTypes.object,
|
|
149
|
+
className: PropTypes.string,
|
|
150
|
+
disabled: PropTypes.bool,
|
|
151
|
+
spin: PropTypes.bool,
|
|
152
|
+
rotate: PropTypes.number,
|
|
153
|
+
withBackground: PropTypes.bool,
|
|
154
|
+
backgroundProps: PropTypes.object,
|
|
155
|
+
onClick: PropTypes.func,
|
|
156
|
+
textLabel: PropTypes.node,
|
|
157
|
+
component: PropTypes.node,
|
|
158
|
+
svgProps: PropTypes.object,
|
|
159
|
+
allowSvg: PropTypes.bool,
|
|
160
|
+
};
|
|
161
|
+
|
|
162
|
+
CapIcon.defaultProps = {
|
|
163
|
+
size: 'm',
|
|
164
|
+
style: {},
|
|
165
|
+
className: '',
|
|
166
|
+
disabled: false,
|
|
167
|
+
spin: false,
|
|
168
|
+
withBackground: false,
|
|
169
|
+
backgroundProps: {},
|
|
170
|
+
svgProps: {},
|
|
171
|
+
allowSvg: true,
|
|
172
|
+
};
|
|
173
|
+
|
|
174
|
+
// Create AntIcon subcomponent for backward compatibility
|
|
175
|
+
const AntIcon = styled.i`
|
|
176
|
+
display: inline-flex;
|
|
177
|
+
align-items: center;
|
|
178
|
+
justify-content: center;
|
|
179
|
+
`;
|
|
180
|
+
|
|
181
|
+
CapIcon.AntIcon = AntIcon;
|
|
182
|
+
|
|
183
|
+
export default withStyles(CapIcon, iconStyles);
|
package/CapIcon/index.js
ADDED
|
@@ -0,0 +1,76 @@
|
|
|
1
|
+
import styled, { css } from 'styled-components';
|
|
2
|
+
import * as styledVars from '../styled/variables';
|
|
3
|
+
|
|
4
|
+
export const IconWrapper = styled.span`
|
|
5
|
+
display: inline-flex;
|
|
6
|
+
align-items: center;
|
|
7
|
+
justify-content: center;
|
|
8
|
+
cursor: ${({ disabled }) => (disabled ? 'not-allowed' : 'pointer')};
|
|
9
|
+
opacity: ${({ disabled }) => (disabled ? 0.5 : 1)};
|
|
10
|
+
|
|
11
|
+
&.xs {
|
|
12
|
+
font-size: 12px;
|
|
13
|
+
width: 12px;
|
|
14
|
+
height: 12px;
|
|
15
|
+
}
|
|
16
|
+
|
|
17
|
+
&.s {
|
|
18
|
+
font-size: 16px;
|
|
19
|
+
width: 16px;
|
|
20
|
+
height: 16px;
|
|
21
|
+
}
|
|
22
|
+
|
|
23
|
+
&.m {
|
|
24
|
+
font-size: 24px;
|
|
25
|
+
width: 24px;
|
|
26
|
+
height: 24px;
|
|
27
|
+
}
|
|
28
|
+
|
|
29
|
+
&.l {
|
|
30
|
+
font-size: 32px;
|
|
31
|
+
width: 32px;
|
|
32
|
+
height: 32px;
|
|
33
|
+
}
|
|
34
|
+
|
|
35
|
+
&.with-text-label {
|
|
36
|
+
display: inline-flex;
|
|
37
|
+
align-items: center;
|
|
38
|
+
gap: 8px;
|
|
39
|
+
}
|
|
40
|
+
`;
|
|
41
|
+
|
|
42
|
+
export const BackgroundWrapper = styled.span`
|
|
43
|
+
display: inline-flex;
|
|
44
|
+
align-items: center;
|
|
45
|
+
justify-content: center;
|
|
46
|
+
border-radius: 50%;
|
|
47
|
+
background-color: ${({ bgColor }) => bgColor || styledVars.CAP_G09};
|
|
48
|
+
width: ${({ size }) => (size === 'xs' ? '20px' : size === 's' ? '24px' : size === 'l' ? '48px' : '36px')};
|
|
49
|
+
height: ${({ size }) => (size === 'xs' ? '20px' : size === 's' ? '24px' : size === 'l' ? '48px' : '36px')};
|
|
50
|
+
`;
|
|
51
|
+
|
|
52
|
+
export const iconStyles = css`
|
|
53
|
+
&.cap-icon {
|
|
54
|
+
display: inline-flex;
|
|
55
|
+
align-items: center;
|
|
56
|
+
|
|
57
|
+
.anticon {
|
|
58
|
+
display: flex;
|
|
59
|
+
align-items: center;
|
|
60
|
+
justify-content: center;
|
|
61
|
+
}
|
|
62
|
+
|
|
63
|
+
&.spin {
|
|
64
|
+
animation: rotate 2s linear infinite;
|
|
65
|
+
}
|
|
66
|
+
}
|
|
67
|
+
|
|
68
|
+
@keyframes rotate {
|
|
69
|
+
from {
|
|
70
|
+
transform: rotate(0deg);
|
|
71
|
+
}
|
|
72
|
+
to {
|
|
73
|
+
transform: rotate(360deg);
|
|
74
|
+
}
|
|
75
|
+
}
|
|
76
|
+
`;
|
|
@@ -0,0 +1,126 @@
|
|
|
1
|
+
import React from 'react';
|
|
2
|
+
import PropTypes from 'prop-types';
|
|
3
|
+
import classnames from 'classnames';
|
|
4
|
+
import styled from 'styled-components';
|
|
5
|
+
import { StyledLabelDiv, StyledLabelSpan, labelStyles } from './styles';
|
|
6
|
+
import withStyles from '../utils/withStyles';
|
|
7
|
+
|
|
8
|
+
const getLabelTypeStyles = (type) => {
|
|
9
|
+
const types = {
|
|
10
|
+
label1: { fontSize: '12px', color: '#5e6c84', fontWeight: 'normal', lineHeight: 'normal' },
|
|
11
|
+
label2: { fontSize: '12px', color: '#091e42', fontWeight: 'normal', lineHeight: 'normal' },
|
|
12
|
+
label3: { fontSize: '12px', color: '#97a0af', fontWeight: 'normal', lineHeight: 'normal' },
|
|
13
|
+
label4: { fontSize: '12px', color: '#091e42', fontWeight: '500', lineHeight: 'normal' },
|
|
14
|
+
label5: { fontSize: '10px', color: '#091e42', fontWeight: 'normal', lineHeight: 'normal' },
|
|
15
|
+
label6: { fontSize: '12px', color: '#b3bac5', fontWeight: 'normal', lineHeight: 'normal' },
|
|
16
|
+
label7: { fontSize: '14px', color: '#5e6c84', fontWeight: '500', lineHeight: 'normal' },
|
|
17
|
+
label8: { fontSize: '12px', color: '#091e42', fontWeight: '500', lineHeight: 'normal' },
|
|
18
|
+
label9: { fontSize: '12px', color: '#091e42', lineHeight: '16px', fontWeight: 'normal' },
|
|
19
|
+
label10: { fontSize: '12px', color: '#ffffff', lineHeight: '16px', fontWeight: 'normal' },
|
|
20
|
+
label11: { fontSize: '10px', color: '#5e6c84', fontWeight: 'normal', lineHeight: 'normal' },
|
|
21
|
+
label12: { fontSize: '12px', color: '#ffffff', fontWeight: 'normal', lineHeight: 'normal' },
|
|
22
|
+
label13: { fontSize: '10px', color: '#97a0af', fontWeight: 'normal', lineHeight: 'normal' },
|
|
23
|
+
label14: { fontSize: '14px', color: '#676e7c', fontWeight: 'normal', lineHeight: 'normal' },
|
|
24
|
+
label15: { fontSize: '14px', color: '#091e42', fontWeight: 'normal', lineHeight: 'normal' },
|
|
25
|
+
label16: { fontSize: '14px', color: '#091e42', fontWeight: '500', lineHeight: 'normal' },
|
|
26
|
+
label17: { fontSize: '16px', color: '#091e42', fontWeight: '500', lineHeight: 'normal' },
|
|
27
|
+
label18: { fontSize: '14px', color: '#5e6c84', fontWeight: 'normal', lineHeight: 'normal' },
|
|
28
|
+
label19: { fontSize: '12px', lineHeight: '16px', fontWeight: 'normal', color: 'rgba(0, 0, 0, 0.87)' },
|
|
29
|
+
label20: { fontSize: '14px', color: '#2466ea', fontWeight: '500', lineHeight: 'normal' },
|
|
30
|
+
label21: { fontSize: '12px', color: '#2466ea', fontWeight: 'normal', lineHeight: 'normal' },
|
|
31
|
+
label22: { fontSize: '24px', color: '#5f6d85', lineHeight: '28px', fontWeight: 'normal' },
|
|
32
|
+
label23: { fontSize: '14px', color: '#ffffff', fontWeight: 'normal', lineHeight: 'normal' },
|
|
33
|
+
label24: { fontSize: '14px', color: '#5e6c84', fontWeight: '400', lineHeight: '20px' },
|
|
34
|
+
label25: { fontSize: '14px', color: '#5e6c84', fontWeight: '500', lineHeight: '20px' },
|
|
35
|
+
label26: { fontSize: '10px', color: '#091E42', fontWeight: '400', lineHeight: '12px' },
|
|
36
|
+
label27: { fontSize: '12px', color: '#2466EA', fontWeight: '500', lineHeight: '16px' },
|
|
37
|
+
label28: { color: '#FFF', fontSize: '12px', fontWeight: '500', lineHeight: '16px' },
|
|
38
|
+
label29: { color: '#FFF', fontSize: '10px', fontWeight: '400', lineHeight: '12px' },
|
|
39
|
+
label30: { color: '#FFF', fontSize: '10px', fontWeight: '400', lineHeight: '12px' },
|
|
40
|
+
label31: { fontSize: '12px', color: '#091E42', fontWeight: '400', lineHeight: '16px' },
|
|
41
|
+
label32: { lineHeight: '20px', fontSize: '14px', color: '#ffffff', fontWeight: '500' },
|
|
42
|
+
label33: { fontSize: '14px', color: '#2466EA', fontWeight: '500', lineHeight: '20px' },
|
|
43
|
+
};
|
|
44
|
+
|
|
45
|
+
return types[type] || types.label1;
|
|
46
|
+
};
|
|
47
|
+
|
|
48
|
+
const CapLabel = ({
|
|
49
|
+
children,
|
|
50
|
+
type = 'label1',
|
|
51
|
+
className = '',
|
|
52
|
+
style = {},
|
|
53
|
+
fontWeight,
|
|
54
|
+
lineHeight,
|
|
55
|
+
...rest
|
|
56
|
+
}) => {
|
|
57
|
+
const typeStyles = getLabelTypeStyles(type);
|
|
58
|
+
|
|
59
|
+
return (
|
|
60
|
+
<StyledLabelDiv
|
|
61
|
+
className={classnames('cap-label', type, className)}
|
|
62
|
+
style={style}
|
|
63
|
+
typeStyles={typeStyles}
|
|
64
|
+
fontWeight={fontWeight}
|
|
65
|
+
lineHeight={lineHeight}
|
|
66
|
+
{...rest}
|
|
67
|
+
>
|
|
68
|
+
{children}
|
|
69
|
+
</StyledLabelDiv>
|
|
70
|
+
);
|
|
71
|
+
};
|
|
72
|
+
|
|
73
|
+
CapLabel.propTypes = {
|
|
74
|
+
children: PropTypes.node,
|
|
75
|
+
type: PropTypes.string,
|
|
76
|
+
className: PropTypes.string,
|
|
77
|
+
style: PropTypes.object,
|
|
78
|
+
fontWeight: PropTypes.oneOfType([PropTypes.string, PropTypes.number]),
|
|
79
|
+
lineHeight: PropTypes.string,
|
|
80
|
+
};
|
|
81
|
+
|
|
82
|
+
CapLabel.defaultProps = {
|
|
83
|
+
type: 'label1',
|
|
84
|
+
className: '',
|
|
85
|
+
style: {},
|
|
86
|
+
};
|
|
87
|
+
|
|
88
|
+
// Static method for inline label
|
|
89
|
+
const CapLabelInline = styled(({ children, type = 'label1', className = '', style = {}, fontWeight, lineHeight, ...rest }) => {
|
|
90
|
+
const typeStyles = getLabelTypeStyles(type);
|
|
91
|
+
|
|
92
|
+
return (
|
|
93
|
+
<StyledLabelSpan
|
|
94
|
+
className={classnames('cap-label', type, className)}
|
|
95
|
+
style={style}
|
|
96
|
+
typeStyles={typeStyles}
|
|
97
|
+
fontWeight={fontWeight}
|
|
98
|
+
lineHeight={lineHeight}
|
|
99
|
+
{...rest}
|
|
100
|
+
>
|
|
101
|
+
{children}
|
|
102
|
+
</StyledLabelSpan>
|
|
103
|
+
);
|
|
104
|
+
})`
|
|
105
|
+
${labelStyles}
|
|
106
|
+
`;
|
|
107
|
+
|
|
108
|
+
CapLabelInline.propTypes = {
|
|
109
|
+
children: PropTypes.node,
|
|
110
|
+
type: PropTypes.string,
|
|
111
|
+
className: PropTypes.string,
|
|
112
|
+
style: PropTypes.object,
|
|
113
|
+
fontWeight: PropTypes.oneOfType([PropTypes.string, PropTypes.number]),
|
|
114
|
+
lineHeight: PropTypes.string,
|
|
115
|
+
};
|
|
116
|
+
|
|
117
|
+
CapLabelInline.defaultProps = {
|
|
118
|
+
type: 'label1',
|
|
119
|
+
className: '',
|
|
120
|
+
style: {},
|
|
121
|
+
};
|
|
122
|
+
|
|
123
|
+
// Attach the static method
|
|
124
|
+
CapLabel.CapLabelInline = CapLabelInline;
|
|
125
|
+
|
|
126
|
+
export default withStyles(CapLabel, labelStyles);
|
|
@@ -0,0 +1,259 @@
|
|
|
1
|
+
import styled, { css } from 'styled-components';
|
|
2
|
+
import * as styledVars from '../styled/variables';
|
|
3
|
+
|
|
4
|
+
export const StyledLabelDiv = styled.div`
|
|
5
|
+
font-family: ${styledVars.FONT_FAMILY};
|
|
6
|
+
font-size: ${({ typeStyles }) => typeStyles?.fontSize || '12px'};
|
|
7
|
+
font-weight: ${({ typeStyles, fontWeight }) => fontWeight || typeStyles?.fontWeight || 'normal'};
|
|
8
|
+
color: ${({ typeStyles }) => typeStyles?.color || styledVars.CAP_G04};
|
|
9
|
+
line-height: ${({ typeStyles, lineHeight }) => lineHeight || typeStyles?.lineHeight || 'normal'};
|
|
10
|
+
margin: 0;
|
|
11
|
+
padding: 0;
|
|
12
|
+
`;
|
|
13
|
+
|
|
14
|
+
export const StyledLabelSpan = styled.span`
|
|
15
|
+
font-family: ${styledVars.FONT_FAMILY};
|
|
16
|
+
font-size: ${({ typeStyles }) => typeStyles?.fontSize || '12px'};
|
|
17
|
+
font-weight: ${({ typeStyles, fontWeight }) => fontWeight || typeStyles?.fontWeight || 'normal'};
|
|
18
|
+
color: ${({ typeStyles }) => typeStyles?.color || styledVars.CAP_G04};
|
|
19
|
+
line-height: ${({ typeStyles, lineHeight }) => lineHeight || typeStyles?.lineHeight || 'normal'};
|
|
20
|
+
margin: 0;
|
|
21
|
+
padding: 0;
|
|
22
|
+
`;
|
|
23
|
+
|
|
24
|
+
export const labelStyles = css`
|
|
25
|
+
&.cap-label {
|
|
26
|
+
font-family: ${styledVars.FONT_FAMILY};
|
|
27
|
+
|
|
28
|
+
&.label1 {
|
|
29
|
+
font-size: 12px;
|
|
30
|
+
color: ${styledVars.CAP_G04};
|
|
31
|
+
font-weight: normal;
|
|
32
|
+
line-height: normal;
|
|
33
|
+
}
|
|
34
|
+
|
|
35
|
+
&.label2 {
|
|
36
|
+
font-size: 12px;
|
|
37
|
+
color: ${styledVars.CAP_G01};
|
|
38
|
+
font-weight: normal;
|
|
39
|
+
line-height: normal;
|
|
40
|
+
}
|
|
41
|
+
|
|
42
|
+
&.label3 {
|
|
43
|
+
font-size: 12px;
|
|
44
|
+
color: ${styledVars.CAP_G05};
|
|
45
|
+
font-weight: normal;
|
|
46
|
+
line-height: normal;
|
|
47
|
+
}
|
|
48
|
+
|
|
49
|
+
&.label4 {
|
|
50
|
+
font-size: 12px;
|
|
51
|
+
color: ${styledVars.CAP_G01};
|
|
52
|
+
font-weight: 500;
|
|
53
|
+
line-height: normal;
|
|
54
|
+
}
|
|
55
|
+
|
|
56
|
+
&.label5 {
|
|
57
|
+
font-size: 10px;
|
|
58
|
+
color: ${styledVars.CAP_G01};
|
|
59
|
+
font-weight: normal;
|
|
60
|
+
line-height: normal;
|
|
61
|
+
}
|
|
62
|
+
|
|
63
|
+
&.label6 {
|
|
64
|
+
font-size: 12px;
|
|
65
|
+
color: ${styledVars.CAP_G06};
|
|
66
|
+
font-weight: normal;
|
|
67
|
+
line-height: normal;
|
|
68
|
+
}
|
|
69
|
+
|
|
70
|
+
&.label7 {
|
|
71
|
+
font-size: 14px;
|
|
72
|
+
color: ${styledVars.CAP_G04};
|
|
73
|
+
font-weight: 500;
|
|
74
|
+
line-height: normal;
|
|
75
|
+
}
|
|
76
|
+
|
|
77
|
+
&.label8 {
|
|
78
|
+
font-size: 12px;
|
|
79
|
+
color: ${styledVars.CAP_G01};
|
|
80
|
+
font-weight: 500;
|
|
81
|
+
line-height: normal;
|
|
82
|
+
}
|
|
83
|
+
|
|
84
|
+
&.label9 {
|
|
85
|
+
font-size: 12px;
|
|
86
|
+
color: ${styledVars.CAP_G01};
|
|
87
|
+
line-height: 16px;
|
|
88
|
+
font-weight: normal;
|
|
89
|
+
}
|
|
90
|
+
|
|
91
|
+
&.label10 {
|
|
92
|
+
font-size: 12px;
|
|
93
|
+
color: ${styledVars.CAP_WHITE};
|
|
94
|
+
line-height: 16px;
|
|
95
|
+
font-weight: normal;
|
|
96
|
+
}
|
|
97
|
+
|
|
98
|
+
&.label11 {
|
|
99
|
+
font-size: 10px;
|
|
100
|
+
color: ${styledVars.CAP_G04};
|
|
101
|
+
font-weight: normal;
|
|
102
|
+
line-height: normal;
|
|
103
|
+
}
|
|
104
|
+
|
|
105
|
+
&.label12 {
|
|
106
|
+
font-size: 12px;
|
|
107
|
+
color: ${styledVars.CAP_WHITE};
|
|
108
|
+
font-weight: normal;
|
|
109
|
+
line-height: normal;
|
|
110
|
+
}
|
|
111
|
+
|
|
112
|
+
&.label13 {
|
|
113
|
+
font-size: 10px;
|
|
114
|
+
color: ${styledVars.CAP_G05};
|
|
115
|
+
font-weight: normal;
|
|
116
|
+
line-height: normal;
|
|
117
|
+
}
|
|
118
|
+
|
|
119
|
+
&.label14 {
|
|
120
|
+
font-size: 14px;
|
|
121
|
+
color: #676e7c;
|
|
122
|
+
font-weight: normal;
|
|
123
|
+
line-height: normal;
|
|
124
|
+
}
|
|
125
|
+
|
|
126
|
+
&.label15 {
|
|
127
|
+
font-size: 14px;
|
|
128
|
+
color: ${styledVars.CAP_G01};
|
|
129
|
+
font-weight: normal;
|
|
130
|
+
line-height: normal;
|
|
131
|
+
}
|
|
132
|
+
|
|
133
|
+
&.label16 {
|
|
134
|
+
font-size: 14px;
|
|
135
|
+
color: ${styledVars.CAP_G01};
|
|
136
|
+
font-weight: 500;
|
|
137
|
+
line-height: normal;
|
|
138
|
+
}
|
|
139
|
+
|
|
140
|
+
&.label17 {
|
|
141
|
+
font-size: 16px;
|
|
142
|
+
color: ${styledVars.CAP_G01};
|
|
143
|
+
font-weight: 500;
|
|
144
|
+
line-height: normal;
|
|
145
|
+
}
|
|
146
|
+
|
|
147
|
+
&.label18 {
|
|
148
|
+
font-size: 14px;
|
|
149
|
+
color: ${styledVars.CAP_G04};
|
|
150
|
+
font-weight: normal;
|
|
151
|
+
line-height: normal;
|
|
152
|
+
}
|
|
153
|
+
|
|
154
|
+
&.label19 {
|
|
155
|
+
font-size: 12px;
|
|
156
|
+
line-height: 16px;
|
|
157
|
+
font-weight: normal;
|
|
158
|
+
color: rgba(0, 0, 0, 0.87);
|
|
159
|
+
}
|
|
160
|
+
|
|
161
|
+
&.label20 {
|
|
162
|
+
font-size: 14px;
|
|
163
|
+
color: ${styledVars.CAP_BLUE01};
|
|
164
|
+
font-weight: 500;
|
|
165
|
+
line-height: normal;
|
|
166
|
+
}
|
|
167
|
+
|
|
168
|
+
&.label21 {
|
|
169
|
+
font-size: 12px;
|
|
170
|
+
color: ${styledVars.CAP_BLUE01};
|
|
171
|
+
font-weight: normal;
|
|
172
|
+
line-height: normal;
|
|
173
|
+
}
|
|
174
|
+
|
|
175
|
+
&.label22 {
|
|
176
|
+
font-size: 24px;
|
|
177
|
+
color: ${styledVars.CAP_G04};
|
|
178
|
+
line-height: 28px;
|
|
179
|
+
font-weight: normal;
|
|
180
|
+
}
|
|
181
|
+
|
|
182
|
+
&.label23 {
|
|
183
|
+
font-size: 14px;
|
|
184
|
+
color: ${styledVars.CAP_WHITE};
|
|
185
|
+
font-weight: normal;
|
|
186
|
+
line-height: normal;
|
|
187
|
+
}
|
|
188
|
+
|
|
189
|
+
&.label24 {
|
|
190
|
+
font-size: 14px;
|
|
191
|
+
color: ${styledVars.CAP_G04};
|
|
192
|
+
font-weight: 400;
|
|
193
|
+
line-height: 20px;
|
|
194
|
+
}
|
|
195
|
+
|
|
196
|
+
&.label25 {
|
|
197
|
+
font-size: 14px;
|
|
198
|
+
color: ${styledVars.CAP_G04};
|
|
199
|
+
font-weight: 500;
|
|
200
|
+
line-height: 20px;
|
|
201
|
+
}
|
|
202
|
+
|
|
203
|
+
&.label26 {
|
|
204
|
+
font-size: 10px;
|
|
205
|
+
color: ${styledVars.CAP_G01};
|
|
206
|
+
font-weight: 400;
|
|
207
|
+
line-height: 12px;
|
|
208
|
+
}
|
|
209
|
+
|
|
210
|
+
&.label27 {
|
|
211
|
+
font-size: 12px;
|
|
212
|
+
color: ${styledVars.CAP_BLUE01};
|
|
213
|
+
font-weight: 500;
|
|
214
|
+
line-height: 16px;
|
|
215
|
+
}
|
|
216
|
+
|
|
217
|
+
&.label28 {
|
|
218
|
+
color: ${styledVars.CAP_WHITE};
|
|
219
|
+
font-size: 12px;
|
|
220
|
+
font-weight: 500;
|
|
221
|
+
line-height: 16px;
|
|
222
|
+
}
|
|
223
|
+
|
|
224
|
+
&.label29 {
|
|
225
|
+
color: ${styledVars.CAP_WHITE};
|
|
226
|
+
font-size: 10px;
|
|
227
|
+
font-weight: 400;
|
|
228
|
+
line-height: 12px;
|
|
229
|
+
}
|
|
230
|
+
|
|
231
|
+
&.label30 {
|
|
232
|
+
color: ${styledVars.CAP_WHITE};
|
|
233
|
+
font-size: 10px;
|
|
234
|
+
font-weight: 400;
|
|
235
|
+
line-height: 12px;
|
|
236
|
+
}
|
|
237
|
+
|
|
238
|
+
&.label31 {
|
|
239
|
+
font-size: 12px;
|
|
240
|
+
color: ${styledVars.CAP_G01};
|
|
241
|
+
font-weight: 400;
|
|
242
|
+
line-height: 16px;
|
|
243
|
+
}
|
|
244
|
+
|
|
245
|
+
&.label32 {
|
|
246
|
+
line-height: 20px;
|
|
247
|
+
font-size: 14px;
|
|
248
|
+
color: ${styledVars.CAP_WHITE};
|
|
249
|
+
font-weight: 500;
|
|
250
|
+
}
|
|
251
|
+
|
|
252
|
+
&.label33 {
|
|
253
|
+
font-size: 14px;
|
|
254
|
+
color: ${styledVars.CAP_BLUE01};
|
|
255
|
+
font-weight: 500;
|
|
256
|
+
line-height: 20px;
|
|
257
|
+
}
|
|
258
|
+
}
|
|
259
|
+
`;
|
package/CapRow/CapRow.js
ADDED
|
@@ -0,0 +1,123 @@
|
|
|
1
|
+
import React from 'react';
|
|
2
|
+
import PropTypes from 'prop-types';
|
|
3
|
+
import classnames from 'classnames';
|
|
4
|
+
import styled from 'styled-components';
|
|
5
|
+
import { StyledRow, rowStyles } from './styles';
|
|
6
|
+
import withStyles from '../utils/withStyles';
|
|
7
|
+
|
|
8
|
+
const CapRow = ({
|
|
9
|
+
children,
|
|
10
|
+
className = '',
|
|
11
|
+
style = {},
|
|
12
|
+
justify = 'start',
|
|
13
|
+
align = 'top',
|
|
14
|
+
gutter = 0,
|
|
15
|
+
wrap = true,
|
|
16
|
+
type,
|
|
17
|
+
width,
|
|
18
|
+
height,
|
|
19
|
+
margin,
|
|
20
|
+
padding,
|
|
21
|
+
prefixCls = 'ant-row',
|
|
22
|
+
fullWidth = false,
|
|
23
|
+
fullHeight = false,
|
|
24
|
+
fillSpace = false,
|
|
25
|
+
responsive = true,
|
|
26
|
+
vertical = false,
|
|
27
|
+
noWrap = false,
|
|
28
|
+
gap = null,
|
|
29
|
+
...rest
|
|
30
|
+
}) => {
|
|
31
|
+
// Use either the gap property or gutter for spacing
|
|
32
|
+
const gutterValue = gap !== null ? null : gutter;
|
|
33
|
+
const wrapValue = noWrap ? false : wrap;
|
|
34
|
+
|
|
35
|
+
return (
|
|
36
|
+
<StyledRow
|
|
37
|
+
className={classnames(
|
|
38
|
+
'cap-row-v2',
|
|
39
|
+
{
|
|
40
|
+
'with-custom-width': width,
|
|
41
|
+
'with-custom-height': height,
|
|
42
|
+
'fill-space': fillSpace,
|
|
43
|
+
'full-width': fullWidth,
|
|
44
|
+
'full-height': fullHeight,
|
|
45
|
+
'ant-row-no-wrap': noWrap,
|
|
46
|
+
'with-gap': gap !== null,
|
|
47
|
+
},
|
|
48
|
+
className
|
|
49
|
+
)}
|
|
50
|
+
style={{
|
|
51
|
+
...(gap !== null ? { gap: typeof gap === 'number' ? `${gap}px` : gap } : {}),
|
|
52
|
+
...style,
|
|
53
|
+
}}
|
|
54
|
+
justify={justify}
|
|
55
|
+
align={align}
|
|
56
|
+
gutter={gutterValue}
|
|
57
|
+
wrap={wrapValue}
|
|
58
|
+
type={type}
|
|
59
|
+
width={width}
|
|
60
|
+
height={height}
|
|
61
|
+
margin={margin}
|
|
62
|
+
padding={padding}
|
|
63
|
+
prefixCls={prefixCls}
|
|
64
|
+
fullWidth={fullWidth}
|
|
65
|
+
fullHeight={fullHeight}
|
|
66
|
+
fillSpace={fillSpace}
|
|
67
|
+
responsive={responsive}
|
|
68
|
+
vertical={vertical}
|
|
69
|
+
{...rest}
|
|
70
|
+
>
|
|
71
|
+
{children}
|
|
72
|
+
</StyledRow>
|
|
73
|
+
);
|
|
74
|
+
};
|
|
75
|
+
|
|
76
|
+
CapRow.propTypes = {
|
|
77
|
+
children: PropTypes.node,
|
|
78
|
+
className: PropTypes.string,
|
|
79
|
+
style: PropTypes.object,
|
|
80
|
+
justify: PropTypes.oneOf(['start', 'end', 'center', 'space-around', 'space-between', 'space-evenly']),
|
|
81
|
+
align: PropTypes.oneOf(['top', 'middle', 'bottom', 'stretch']),
|
|
82
|
+
gutter: PropTypes.oneOfType([
|
|
83
|
+
PropTypes.number,
|
|
84
|
+
PropTypes.object,
|
|
85
|
+
PropTypes.arrayOf(PropTypes.number),
|
|
86
|
+
]),
|
|
87
|
+
wrap: PropTypes.bool,
|
|
88
|
+
type: PropTypes.string,
|
|
89
|
+
width: PropTypes.oneOfType([PropTypes.string, PropTypes.number]),
|
|
90
|
+
height: PropTypes.oneOfType([PropTypes.string, PropTypes.number]),
|
|
91
|
+
margin: PropTypes.oneOfType([PropTypes.string, PropTypes.number]),
|
|
92
|
+
padding: PropTypes.oneOfType([PropTypes.string, PropTypes.number]),
|
|
93
|
+
prefixCls: PropTypes.string,
|
|
94
|
+
fullWidth: PropTypes.bool,
|
|
95
|
+
fullHeight: PropTypes.bool,
|
|
96
|
+
fillSpace: PropTypes.bool,
|
|
97
|
+
responsive: PropTypes.bool,
|
|
98
|
+
vertical: PropTypes.bool,
|
|
99
|
+
noWrap: PropTypes.bool,
|
|
100
|
+
gap: PropTypes.oneOfType([
|
|
101
|
+
PropTypes.number,
|
|
102
|
+
PropTypes.arrayOf(PropTypes.number),
|
|
103
|
+
PropTypes.string,
|
|
104
|
+
]),
|
|
105
|
+
};
|
|
106
|
+
|
|
107
|
+
CapRow.defaultProps = {
|
|
108
|
+
className: '',
|
|
109
|
+
style: {},
|
|
110
|
+
justify: 'start',
|
|
111
|
+
align: 'top',
|
|
112
|
+
gutter: 0,
|
|
113
|
+
wrap: true,
|
|
114
|
+
prefixCls: 'ant-row',
|
|
115
|
+
fullWidth: false,
|
|
116
|
+
fullHeight: false,
|
|
117
|
+
fillSpace: false,
|
|
118
|
+
responsive: true,
|
|
119
|
+
vertical: false,
|
|
120
|
+
noWrap: false,
|
|
121
|
+
};
|
|
122
|
+
|
|
123
|
+
export default withStyles(CapRow, rowStyles);
|
package/CapRow/index.js
ADDED
package/CapRow/styles.js
ADDED
|
@@ -0,0 +1,50 @@
|
|
|
1
|
+
import styled, { css } from 'styled-components';
|
|
2
|
+
import { Row } from 'antd-v5';
|
|
3
|
+
import * as styledVars from '../styled/variables';
|
|
4
|
+
|
|
5
|
+
export const StyledRow = styled(Row)`
|
|
6
|
+
width: ${({ width, fullWidth }) => (fullWidth ? '100%' : width || 'auto')};
|
|
7
|
+
height: ${({ height, fullHeight }) => (fullHeight ? '100%' : height || 'auto')};
|
|
8
|
+
margin: ${({ margin }) => margin || 'inherit'};
|
|
9
|
+
padding: ${({ padding }) => padding || 'inherit'};
|
|
10
|
+
${({ responsive }) => !responsive && css`
|
|
11
|
+
display: flex;
|
|
12
|
+
flex-wrap: wrap;
|
|
13
|
+
`};
|
|
14
|
+
${({ fillSpace }) => fillSpace && css`
|
|
15
|
+
flex: 1;
|
|
16
|
+
`};
|
|
17
|
+
`;
|
|
18
|
+
|
|
19
|
+
export const rowStyles = css`
|
|
20
|
+
&.cap-row-v2 {
|
|
21
|
+
&.with-custom-width {
|
|
22
|
+
width: auto;
|
|
23
|
+
}
|
|
24
|
+
|
|
25
|
+
&.with-custom-height {
|
|
26
|
+
height: auto;
|
|
27
|
+
}
|
|
28
|
+
|
|
29
|
+
&.fill-space {
|
|
30
|
+
flex: 1;
|
|
31
|
+
}
|
|
32
|
+
|
|
33
|
+
&.full-width {
|
|
34
|
+
width: 100%;
|
|
35
|
+
}
|
|
36
|
+
|
|
37
|
+
&.full-height {
|
|
38
|
+
height: 100%;
|
|
39
|
+
}
|
|
40
|
+
|
|
41
|
+
&.ant-row-no-wrap {
|
|
42
|
+
flex-wrap: nowrap;
|
|
43
|
+
}
|
|
44
|
+
|
|
45
|
+
&.with-gap {
|
|
46
|
+
display: grid;
|
|
47
|
+
grid-template-columns: repeat(auto-fit, minmax(0, 1fr));
|
|
48
|
+
}
|
|
49
|
+
}
|
|
50
|
+
`;
|
|
@@ -0,0 +1,98 @@
|
|
|
1
|
+
import React from 'react';
|
|
2
|
+
import PropTypes from 'prop-types';
|
|
3
|
+
import { Tooltip } from 'antd-v5';
|
|
4
|
+
import classnames from 'classnames';
|
|
5
|
+
import styled from 'styled-components';
|
|
6
|
+
import { tooltipStyles } from './styles';
|
|
7
|
+
import withStyles from '../utils/withStyles';
|
|
8
|
+
|
|
9
|
+
const StyledTooltip = styled(Tooltip)`
|
|
10
|
+
${tooltipStyles}
|
|
11
|
+
`;
|
|
12
|
+
|
|
13
|
+
const CapTooltip = ({
|
|
14
|
+
title,
|
|
15
|
+
children,
|
|
16
|
+
placement = 'top',
|
|
17
|
+
visible,
|
|
18
|
+
defaultVisible = false,
|
|
19
|
+
trigger = 'hover',
|
|
20
|
+
destroyTooltipOnHide = false,
|
|
21
|
+
mouseEnterDelay = 0.1,
|
|
22
|
+
mouseLeaveDelay = 0.1,
|
|
23
|
+
overlayClassName = '',
|
|
24
|
+
overlayStyle,
|
|
25
|
+
onVisibleChange,
|
|
26
|
+
align,
|
|
27
|
+
arrowPointAtCenter = false,
|
|
28
|
+
autoAdjustOverflow = true,
|
|
29
|
+
getPopupContainer,
|
|
30
|
+
className = '',
|
|
31
|
+
...rest
|
|
32
|
+
}) => {
|
|
33
|
+
return (
|
|
34
|
+
<StyledTooltip
|
|
35
|
+
title={title}
|
|
36
|
+
placement={placement}
|
|
37
|
+
open={visible}
|
|
38
|
+
defaultOpen={defaultVisible}
|
|
39
|
+
trigger={trigger}
|
|
40
|
+
destroyTooltipOnHide={destroyTooltipOnHide}
|
|
41
|
+
mouseEnterDelay={mouseEnterDelay}
|
|
42
|
+
mouseLeaveDelay={mouseLeaveDelay}
|
|
43
|
+
overlayClassName={classnames('cap-tooltip-overlay-v2', overlayClassName)}
|
|
44
|
+
overlayStyle={overlayStyle}
|
|
45
|
+
onOpenChange={onVisibleChange}
|
|
46
|
+
align={align}
|
|
47
|
+
arrow={{ pointAtCenter: arrowPointAtCenter }}
|
|
48
|
+
autoAdjustOverflow={autoAdjustOverflow}
|
|
49
|
+
getPopupContainer={getPopupContainer}
|
|
50
|
+
className={classnames('cap-tooltip-v2', className)}
|
|
51
|
+
{...rest}
|
|
52
|
+
>
|
|
53
|
+
{children}
|
|
54
|
+
</StyledTooltip>
|
|
55
|
+
);
|
|
56
|
+
};
|
|
57
|
+
|
|
58
|
+
CapTooltip.propTypes = {
|
|
59
|
+
title: PropTypes.oneOfType([PropTypes.string, PropTypes.node]),
|
|
60
|
+
children: PropTypes.node,
|
|
61
|
+
placement: PropTypes.oneOf([
|
|
62
|
+
'top', 'left', 'right', 'bottom',
|
|
63
|
+
'topLeft', 'topRight', 'bottomLeft', 'bottomRight',
|
|
64
|
+
'leftTop', 'leftBottom', 'rightTop', 'rightBottom',
|
|
65
|
+
]),
|
|
66
|
+
visible: PropTypes.bool,
|
|
67
|
+
defaultVisible: PropTypes.bool,
|
|
68
|
+
trigger: PropTypes.oneOfType([
|
|
69
|
+
PropTypes.string,
|
|
70
|
+
PropTypes.arrayOf(PropTypes.string),
|
|
71
|
+
]),
|
|
72
|
+
destroyTooltipOnHide: PropTypes.bool,
|
|
73
|
+
mouseEnterDelay: PropTypes.number,
|
|
74
|
+
mouseLeaveDelay: PropTypes.number,
|
|
75
|
+
overlayClassName: PropTypes.string,
|
|
76
|
+
overlayStyle: PropTypes.object,
|
|
77
|
+
onVisibleChange: PropTypes.func,
|
|
78
|
+
align: PropTypes.object,
|
|
79
|
+
arrowPointAtCenter: PropTypes.bool,
|
|
80
|
+
autoAdjustOverflow: PropTypes.bool,
|
|
81
|
+
getPopupContainer: PropTypes.func,
|
|
82
|
+
className: PropTypes.string,
|
|
83
|
+
};
|
|
84
|
+
|
|
85
|
+
CapTooltip.defaultProps = {
|
|
86
|
+
placement: 'top',
|
|
87
|
+
defaultVisible: false,
|
|
88
|
+
trigger: 'hover',
|
|
89
|
+
destroyTooltipOnHide: false,
|
|
90
|
+
mouseEnterDelay: 0.1,
|
|
91
|
+
mouseLeaveDelay: 0.1,
|
|
92
|
+
overlayClassName: '',
|
|
93
|
+
arrowPointAtCenter: false,
|
|
94
|
+
autoAdjustOverflow: true,
|
|
95
|
+
className: '',
|
|
96
|
+
};
|
|
97
|
+
|
|
98
|
+
export default withStyles(CapTooltip, tooltipStyles);
|
|
@@ -0,0 +1,34 @@
|
|
|
1
|
+
import styled, { css } from 'styled-components';
|
|
2
|
+
import * as styledVars from '../styled/variables';
|
|
3
|
+
|
|
4
|
+
export const tooltipStyles = css`
|
|
5
|
+
&.cap-tooltip-overlay-v2 {
|
|
6
|
+
.ant-tooltip-inner {
|
|
7
|
+
background-color: ${styledVars.CAP_G01};
|
|
8
|
+
color: ${styledVars.CAP_WHITE};
|
|
9
|
+
padding: 8px 12px;
|
|
10
|
+
font-size: 14px;
|
|
11
|
+
line-height: 20px;
|
|
12
|
+
border-radius: ${styledVars.RADIUS_04};
|
|
13
|
+
max-width: 300px;
|
|
14
|
+
word-wrap: break-word;
|
|
15
|
+
}
|
|
16
|
+
|
|
17
|
+
.ant-tooltip-arrow::before {
|
|
18
|
+
background-color: ${styledVars.CAP_G01};
|
|
19
|
+
}
|
|
20
|
+
}
|
|
21
|
+
|
|
22
|
+
.button-disabled-tooltip-wrapper {
|
|
23
|
+
display: inline-block;
|
|
24
|
+
cursor: not-allowed;
|
|
25
|
+
|
|
26
|
+
.ant-btn[disabled] {
|
|
27
|
+
pointer-events: none;
|
|
28
|
+
}
|
|
29
|
+
}
|
|
30
|
+
`;
|
|
31
|
+
|
|
32
|
+
export const StyledTooltipWrapper = styled.div`
|
|
33
|
+
display: inline-block;
|
|
34
|
+
`;
|
|
@@ -0,0 +1,82 @@
|
|
|
1
|
+
import React from 'react';
|
|
2
|
+
import PropTypes from 'prop-types';
|
|
3
|
+
import classnames from 'classnames';
|
|
4
|
+
import { CapTooltip, CapIcon } from '../';
|
|
5
|
+
import withStyles from '../utils/withStyles';
|
|
6
|
+
import { tooltipWithInfoStyles } from './styles';
|
|
7
|
+
|
|
8
|
+
/**
|
|
9
|
+
* CapTooltipWithInfo - A component that combines an info icon with a tooltip
|
|
10
|
+
* for displaying additional information on hover or other trigger events.
|
|
11
|
+
*/
|
|
12
|
+
const CapTooltipWithInfo = ({
|
|
13
|
+
title,
|
|
14
|
+
iconSize = 's',
|
|
15
|
+
iconType = 'info-circle',
|
|
16
|
+
placement = 'top',
|
|
17
|
+
trigger = 'hover',
|
|
18
|
+
className = '',
|
|
19
|
+
tooltipProps = {},
|
|
20
|
+
iconProps = {},
|
|
21
|
+
...rest
|
|
22
|
+
}) => {
|
|
23
|
+
return (
|
|
24
|
+
<span
|
|
25
|
+
className={classnames('cap-tooltip-with-info', className)}
|
|
26
|
+
{...rest}
|
|
27
|
+
>
|
|
28
|
+
<CapTooltip
|
|
29
|
+
title={title}
|
|
30
|
+
placement={placement}
|
|
31
|
+
trigger={trigger}
|
|
32
|
+
{...tooltipProps}
|
|
33
|
+
>
|
|
34
|
+
<span className="cap-tooltip-with-info-icon">
|
|
35
|
+
<CapIcon
|
|
36
|
+
type={iconType}
|
|
37
|
+
size={iconSize}
|
|
38
|
+
{...iconProps}
|
|
39
|
+
/>
|
|
40
|
+
</span>
|
|
41
|
+
</CapTooltip>
|
|
42
|
+
</span>
|
|
43
|
+
);
|
|
44
|
+
};
|
|
45
|
+
|
|
46
|
+
CapTooltipWithInfo.propTypes = {
|
|
47
|
+
/** Content to display in the tooltip */
|
|
48
|
+
title: PropTypes.oneOfType([PropTypes.string, PropTypes.node]).isRequired,
|
|
49
|
+
/** Size of the info icon */
|
|
50
|
+
iconSize: PropTypes.oneOf(['xs', 's', 'm', 'l']),
|
|
51
|
+
/** Type of icon to display */
|
|
52
|
+
iconType: PropTypes.string,
|
|
53
|
+
/** Placement of the tooltip relative to the icon */
|
|
54
|
+
placement: PropTypes.oneOf([
|
|
55
|
+
'top', 'left', 'right', 'bottom',
|
|
56
|
+
'topLeft', 'topRight', 'bottomLeft', 'bottomRight',
|
|
57
|
+
'leftTop', 'leftBottom', 'rightTop', 'rightBottom',
|
|
58
|
+
]),
|
|
59
|
+
/** How the tooltip is triggered */
|
|
60
|
+
trigger: PropTypes.oneOfType([
|
|
61
|
+
PropTypes.string,
|
|
62
|
+
PropTypes.arrayOf(PropTypes.string),
|
|
63
|
+
]),
|
|
64
|
+
/** Additional class name */
|
|
65
|
+
className: PropTypes.string,
|
|
66
|
+
/** Additional props passed to the CapTooltip component */
|
|
67
|
+
tooltipProps: PropTypes.object,
|
|
68
|
+
/** Additional props passed to the CapIcon component */
|
|
69
|
+
iconProps: PropTypes.object,
|
|
70
|
+
};
|
|
71
|
+
|
|
72
|
+
CapTooltipWithInfo.defaultProps = {
|
|
73
|
+
iconSize: 's',
|
|
74
|
+
iconType: 'info-circle',
|
|
75
|
+
placement: 'top',
|
|
76
|
+
trigger: 'hover',
|
|
77
|
+
className: '',
|
|
78
|
+
tooltipProps: {},
|
|
79
|
+
iconProps: {},
|
|
80
|
+
};
|
|
81
|
+
|
|
82
|
+
export default withStyles(CapTooltipWithInfo, tooltipWithInfoStyles);
|
|
@@ -0,0 +1,22 @@
|
|
|
1
|
+
import { css } from 'styled-components';
|
|
2
|
+
import * as styledVars from '../styled/variables';
|
|
3
|
+
|
|
4
|
+
export const tooltipWithInfoStyles = css`
|
|
5
|
+
&.cap-tooltip-with-info {
|
|
6
|
+
display: inline-flex;
|
|
7
|
+
align-items: center;
|
|
8
|
+
cursor: default;
|
|
9
|
+
|
|
10
|
+
.cap-tooltip-with-info-icon {
|
|
11
|
+
color: ${styledVars.CAP_G06};
|
|
12
|
+
margin-left: 4px;
|
|
13
|
+
cursor: help;
|
|
14
|
+
|
|
15
|
+
&:hover {
|
|
16
|
+
color: ${styledVars.CAP_G07};
|
|
17
|
+
}
|
|
18
|
+
}
|
|
19
|
+
}
|
|
20
|
+
`;
|
|
21
|
+
|
|
22
|
+
export default tooltipWithInfoStyles;
|
|
@@ -2,13 +2,10 @@
|
|
|
2
2
|
import React, { useState, useEffect, useMemo, useCallback, memo } from 'react';
|
|
3
3
|
import PropTypes from 'prop-types';
|
|
4
4
|
import classnames from 'classnames';
|
|
5
|
-
import { TreeSelect,
|
|
5
|
+
import { TreeSelect, Input, Button } from 'antd-v5';
|
|
6
6
|
import styled from 'styled-components';
|
|
7
7
|
import * as styledVars from '../styled/variables';
|
|
8
|
-
import
|
|
9
|
-
|
|
10
|
-
import { InfoCircleOutlined, SearchOutlined, WarningFilled, DownOutlined } from '@ant-design/icons';
|
|
11
|
-
|
|
8
|
+
import { CapLabel, CapTooltipWithInfo, CapRow, CapIcon } from '../';
|
|
12
9
|
import withStyles from '../utils/withStyles';
|
|
13
10
|
import { SelectWrapper, HeaderWrapper, selectStyles } from './styles';
|
|
14
11
|
|
|
@@ -57,10 +54,14 @@ const CapUnifiedSelect = ({
|
|
|
57
54
|
};
|
|
58
55
|
|
|
59
56
|
const NoResult = memo(({ noResultText, className }) => (
|
|
60
|
-
<
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
57
|
+
<CapRow
|
|
58
|
+
className={classnames(className, "cap-unified-select-no-result")}
|
|
59
|
+
align="middle"
|
|
60
|
+
gap={8}
|
|
61
|
+
>
|
|
62
|
+
<CapIcon type="warning" size="s" />
|
|
63
|
+
<CapLabel className="cap-unified-select-no-result-text">{noResultText}</CapLabel>
|
|
64
|
+
</CapRow>
|
|
64
65
|
));
|
|
65
66
|
|
|
66
67
|
const getFilteredTreeData = useCallback((data, search) => {
|
|
@@ -137,10 +138,10 @@ const CapUnifiedSelect = ({
|
|
|
137
138
|
const suffix = useMemo(() => {
|
|
138
139
|
return isMulti && Array.isArray(value) && value?.length > 1 ? (
|
|
139
140
|
<>
|
|
140
|
-
<span>+{value.length - 1} more <
|
|
141
|
+
<span>+{value.length - 1} more <CapIcon type="down" size="s" /></span>
|
|
141
142
|
</>
|
|
142
143
|
) : (
|
|
143
|
-
<
|
|
144
|
+
<CapIcon type="down" size="s" />
|
|
144
145
|
);
|
|
145
146
|
}, [isMulti, value]);
|
|
146
147
|
|
|
@@ -157,15 +158,17 @@ const CapUnifiedSelect = ({
|
|
|
157
158
|
return (
|
|
158
159
|
<>
|
|
159
160
|
<HeaderWrapper className={classnames(disabled ? 'disabled' : '', 'cap-unified-select-header')}>
|
|
160
|
-
{headerLabel && <
|
|
161
|
+
{headerLabel && <CapLabel type="label16" className={classnames(disabled ? 'disabled' : '', 'cap-unified-select-header-label')}>{headerLabel}</CapLabel>}
|
|
161
162
|
{tooltip && (
|
|
162
|
-
<
|
|
163
|
-
|
|
164
|
-
|
|
163
|
+
<CapTooltipWithInfo
|
|
164
|
+
title={tooltip}
|
|
165
|
+
className={classnames(disabled ? 'disabled' : '', 'cap-unified-select-header-tooltip')}
|
|
166
|
+
iconProps={{ disabled }}
|
|
167
|
+
/>
|
|
165
168
|
)}
|
|
166
169
|
</HeaderWrapper>
|
|
167
170
|
<div className="cap-unified-select-header-byline-text">
|
|
168
|
-
{bylineText && <
|
|
171
|
+
{bylineText && <CapLabel className={classnames(disabled ? 'disabled' : '', 'cap-unified-select-header-byline-text')}>{bylineText}</CapLabel>}
|
|
169
172
|
</div>
|
|
170
173
|
</>
|
|
171
174
|
);
|
|
@@ -185,46 +188,55 @@ const CapUnifiedSelect = ({
|
|
|
185
188
|
return (
|
|
186
189
|
<div className={classnames(popupClassName, `${type}-popup-container`)}>
|
|
187
190
|
{showSearch && (
|
|
188
|
-
<
|
|
191
|
+
<CapRow className={classnames("cap-unified-select-search-container")} align="middle">
|
|
189
192
|
<Input
|
|
190
|
-
prefix={<
|
|
193
|
+
prefix={<CapIcon type="search" size="s" style={{ color: styledVars.CAP_G06 }} />}
|
|
191
194
|
placeholder="Search"
|
|
192
195
|
variant="borderless"
|
|
193
196
|
value={searchText}
|
|
194
197
|
onChange={e => setSearchText(e.target.value)}
|
|
195
198
|
onKeyDown={e => e.stopPropagation()}
|
|
196
199
|
/>
|
|
197
|
-
</
|
|
200
|
+
</CapRow>
|
|
198
201
|
)}
|
|
199
202
|
{isMulti && showUpload && (
|
|
200
|
-
<
|
|
203
|
+
<CapRow className={classnames("cap-unified-select-upload-container")} align="middle">
|
|
201
204
|
<Button
|
|
202
205
|
type="link"
|
|
203
|
-
icon={<
|
|
206
|
+
icon={<CapIcon type="upload" size="s" />}
|
|
204
207
|
onClick={() => {}}
|
|
205
208
|
className={classnames("cap-unified-select-upload-button")}
|
|
206
209
|
>
|
|
207
210
|
Upload
|
|
208
211
|
</Button>
|
|
209
|
-
</
|
|
212
|
+
</CapRow>
|
|
210
213
|
)}
|
|
211
214
|
{isMulti && currentItems.length > 0 && (
|
|
212
|
-
<
|
|
213
|
-
|
|
214
|
-
|
|
215
|
-
|
|
215
|
+
<CapRow
|
|
216
|
+
className={classnames("cap-unified-select-select-all-container")}
|
|
217
|
+
onClick={e => { e.stopPropagation(); handleSelectAll(); }}
|
|
218
|
+
align="middle"
|
|
219
|
+
gap={8}
|
|
220
|
+
>
|
|
221
|
+
<input type="checkbox" checked={allSelected} className={classnames("cap-unified-select-select-all-checkbox")} onClick={e => e.stopPropagation()} />
|
|
222
|
+
<CapLabel className={classnames("cap-unified-select-select-all-label")}>Select all</CapLabel>
|
|
223
|
+
</CapRow>
|
|
216
224
|
)}
|
|
217
225
|
|
|
218
226
|
{currentItems.length === 0 ? <NoResult noResultText={noResultText} className={classnames(className, "cap-unified-select-no-result")}/> : menu}
|
|
219
227
|
|
|
220
228
|
{currentItems.length > 0 && isMulti && (
|
|
221
|
-
<
|
|
222
|
-
|
|
229
|
+
<CapRow
|
|
230
|
+
className={classnames("cap-unified-select-confirm-container")}
|
|
231
|
+
justify="space-between"
|
|
232
|
+
align="middle"
|
|
233
|
+
>
|
|
234
|
+
<CapRow gap={8}>
|
|
223
235
|
<Button type="primary" size="small" className={classnames("cap-unified-select-confirm-button")} onClick={e => { e.stopPropagation(); handleConfirm(); }}>Confirm</Button>
|
|
224
236
|
<Button type="text" size="small" onClick={e => { e.stopPropagation(); handleCancel(); }}>Cancel</Button>
|
|
225
|
-
</
|
|
226
|
-
{selectedCount > 0 && <
|
|
227
|
-
</
|
|
237
|
+
</CapRow>
|
|
238
|
+
{selectedCount > 0 && <CapLabel className={classnames("cap-unified-select-selected-count")}>{selectedCount} selected</CapLabel>}
|
|
239
|
+
</CapRow>
|
|
228
240
|
)}
|
|
229
241
|
</div>
|
|
230
242
|
);
|
|
@@ -257,7 +269,7 @@ const CapUnifiedSelect = ({
|
|
|
257
269
|
{...treeSelectVirtualizationProps}
|
|
258
270
|
popupRender={renderCustomDropdown}
|
|
259
271
|
/>
|
|
260
|
-
{isError && <
|
|
272
|
+
{isError && <CapLabel className={classnames("cap-unified-select-status")} style={{ color: 'red' }}>{errorMessage}</CapLabel>}
|
|
261
273
|
</>
|
|
262
274
|
);
|
|
263
275
|
};
|
package/index.js
CHANGED
|
@@ -1,8 +1,13 @@
|
|
|
1
1
|
// Import and export all components
|
|
2
|
+
export { default as CapIcon } from './CapIcon';
|
|
2
3
|
export { default as CapInput } from './CapInput';
|
|
4
|
+
export { default as CapLabel } from './CapLabel';
|
|
5
|
+
export { default as CapRow } from './CapRow';
|
|
3
6
|
export { default as CapSkeleton } from './CapSkeleton';
|
|
4
7
|
export { default as CapSpin } from './CapSpin';
|
|
5
8
|
export { default as CapTable } from './CapTable';
|
|
9
|
+
export { default as CapTooltip } from './CapTooltip';
|
|
10
|
+
export { default as CapTooltipWithInfo } from './CapTooltipWithInfo';
|
|
6
11
|
export { default as CapUnifiedSelect } from './CapUnifiedSelect';
|
|
7
12
|
|
|
8
13
|
// Export utilities
|
package/package.json
CHANGED