@capillarytech/blaze-ui 0.1.6-alpha.41 → 0.1.6-alpha.42

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.
@@ -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);
@@ -0,0 +1,3 @@
1
+ import CapIcon from './CapIcon';
2
+
3
+ export default CapIcon;
@@ -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,3 @@
1
+ import CapLabel from './CapLabel';
2
+
3
+ export default CapLabel;
@@ -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
+ `;
@@ -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);
@@ -0,0 +1,3 @@
1
+ import CapRow from './CapRow';
2
+
3
+ export default CapRow;
@@ -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,3 @@
1
+ import CapTooltip from './CapTooltip';
2
+
3
+ export default CapTooltip;
@@ -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
+ `;
@@ -2,15 +2,12 @@
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, Tooltip, Input, Button } from 'antd-v5';
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 uploadIcon from '../assets/upload.svg';
9
-
10
- import { InfoCircleOutlined, SearchOutlined, WarningFilled, DownOutlined } from '@ant-design/icons';
11
-
8
+ import { CapLabel, CapTooltip, CapRow, CapIcon } from '../';
12
9
  import withStyles from '../utils/withStyles';
13
- import { SelectWrapper, HeaderWrapper, selectStyles } from './styles';
10
+ import { SelectWrapper, selectStyles } from './styles';
14
11
 
15
12
  const StyledTreeSelect = styled(TreeSelect)`
16
13
  ${selectStyles}
@@ -57,10 +54,14 @@ const CapUnifiedSelect = ({
57
54
  };
58
55
 
59
56
  const NoResult = memo(({ noResultText, className }) => (
60
- <div className={classnames(className, "cap-unified-select-no-result")}>
61
- <WarningFilled className="cap-unified-select-no-result-icon" />
62
- <div className="cap-unified-select-no-result-text">{noResultText}</div>
63
- </div>
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 <DownOutlined /></span>
141
+ <span>+{value.length - 1} more <CapIcon type="down" size="s" /></span>
141
142
  </>
142
143
  ) : (
143
- <DownOutlined />
144
+ <CapIcon type="down" size="s" />
144
145
  );
145
146
  }, [isMulti, value]);
146
147
 
@@ -156,16 +157,20 @@ const CapUnifiedSelect = ({
156
157
  if (!headerLabel && !tooltip) return null;
157
158
  return (
158
159
  <>
159
- <HeaderWrapper className={classnames(disabled ? 'disabled' : '', 'cap-unified-select-header')}>
160
- {headerLabel && <label type="label16" className={classnames(disabled ? 'disabled' : '', 'cap-unified-select-header-label')}>{headerLabel}</label>}
160
+ <CapRow
161
+ className={classnames(disabled ? 'disabled' : '', 'cap-unified-select-header')}
162
+ align="middle"
163
+ gap={8}
164
+ >
165
+ {headerLabel && <CapLabel type="label16" className={classnames(disabled ? 'disabled' : '', 'cap-unified-select-header-label')}>{headerLabel}</CapLabel>}
161
166
  {tooltip && (
162
- <Tooltip title={tooltip} rootClassName="cap-unified-tooltip" className={classnames(disabled ? 'disabled' : '', 'cap-unified-select-header-tooltip')}>
163
- <InfoCircleOutlined />
164
- </Tooltip>
167
+ <CapTooltip title={tooltip} className={classnames(disabled ? 'disabled' : '', 'cap-unified-select-header-tooltip')}>
168
+ <CapIcon type="info-circle" size="s" />
169
+ </CapTooltip>
165
170
  )}
166
- </HeaderWrapper>
171
+ </CapRow>
167
172
  <div className="cap-unified-select-header-byline-text">
168
- {bylineText && <label className={classnames(disabled ? 'disabled' : '', 'cap-unified-select-header-byline-text')}>{bylineText}</label>}
173
+ {bylineText && <CapLabel className={classnames(disabled ? 'disabled' : '', 'cap-unified-select-header-byline-text')}>{bylineText}</CapLabel>}
169
174
  </div>
170
175
  </>
171
176
  );
@@ -185,46 +190,55 @@ const CapUnifiedSelect = ({
185
190
  return (
186
191
  <div className={classnames(popupClassName, `${type}-popup-container`)}>
187
192
  {showSearch && (
188
- <div className={classnames("cap-unified-select-search-container")}>
193
+ <CapRow className={classnames("cap-unified-select-search-container")} align="middle">
189
194
  <Input
190
- prefix={<SearchOutlined style={{ color: styledVars.CAP_G06 }} />}
195
+ prefix={<CapIcon type="search" size="s" style={{ color: styledVars.CAP_G06 }} />}
191
196
  placeholder="Search"
192
197
  variant="borderless"
193
198
  value={searchText}
194
199
  onChange={e => setSearchText(e.target.value)}
195
200
  onKeyDown={e => e.stopPropagation()}
196
201
  />
197
- </div>
202
+ </CapRow>
198
203
  )}
199
204
  {isMulti && showUpload && (
200
- <div className={classnames("cap-unified-select-upload-container")}>
205
+ <CapRow className={classnames("cap-unified-select-upload-container")} align="middle">
201
206
  <Button
202
207
  type="link"
203
- icon={<img src={uploadIcon} alt="upload" />}
208
+ icon={<CapIcon type="upload" size="s" />}
204
209
  onClick={() => {}}
205
210
  className={classnames("cap-unified-select-upload-button")}
206
211
  >
207
212
  Upload
208
213
  </Button>
209
- </div>
214
+ </CapRow>
210
215
  )}
211
216
  {isMulti && currentItems.length > 0 && (
212
- <div className={classnames("cap-unified-select-select-all-container")} onClick={e => { e.stopPropagation(); handleSelectAll(); }}>
213
- <input type="checkbox" checked={allSelected} className={classnames("cap-unified-select-select-all-checkbox")} onClick={e => e.stopPropagation()} />
214
- <label className={classnames("cap-unified-select-select-all-label")}>Select all</label>
215
- </div>
217
+ <CapRow
218
+ className={classnames("cap-unified-select-select-all-container")}
219
+ onClick={e => { e.stopPropagation(); handleSelectAll(); }}
220
+ align="middle"
221
+ gap={8}
222
+ >
223
+ <input type="checkbox" checked={allSelected} className={classnames("cap-unified-select-select-all-checkbox")} onClick={e => e.stopPropagation()} />
224
+ <CapLabel className={classnames("cap-unified-select-select-all-label")}>Select all</CapLabel>
225
+ </CapRow>
216
226
  )}
217
227
 
218
228
  {currentItems.length === 0 ? <NoResult noResultText={noResultText} className={classnames(className, "cap-unified-select-no-result")}/> : menu}
219
229
 
220
230
  {currentItems.length > 0 && isMulti && (
221
- <div className={classnames("cap-unified-select-confirm-container")}>
222
- <div>
231
+ <CapRow
232
+ className={classnames("cap-unified-select-confirm-container")}
233
+ justify="space-between"
234
+ align="middle"
235
+ >
236
+ <CapRow gap={8}>
223
237
  <Button type="primary" size="small" className={classnames("cap-unified-select-confirm-button")} onClick={e => { e.stopPropagation(); handleConfirm(); }}>Confirm</Button>
224
238
  <Button type="text" size="small" onClick={e => { e.stopPropagation(); handleCancel(); }}>Cancel</Button>
225
- </div>
226
- {selectedCount > 0 && <span className={classnames("cap-unified-select-selected-count")}>{selectedCount} selected</span>}
227
- </div>
239
+ </CapRow>
240
+ {selectedCount > 0 && <CapLabel className={classnames("cap-unified-select-selected-count")}>{selectedCount} selected</CapLabel>}
241
+ </CapRow>
228
242
  )}
229
243
  </div>
230
244
  );
@@ -257,7 +271,7 @@ const CapUnifiedSelect = ({
257
271
  {...treeSelectVirtualizationProps}
258
272
  popupRender={renderCustomDropdown}
259
273
  />
260
- {isError && <div className={classnames("cap-unified-select-status")}>{errorMessage}</div>}
274
+ {isError && <CapLabel className={classnames("cap-unified-select-status")} style={{ color: 'red' }}>{errorMessage}</CapLabel>}
261
275
  </>
262
276
  );
263
277
  };
package/index.js CHANGED
@@ -1,8 +1,12 @@
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';
6
10
  export { default as CapUnifiedSelect } from './CapUnifiedSelect';
7
11
 
8
12
  // Export utilities
package/package.json CHANGED
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "name": "@capillarytech/blaze-ui",
3
3
  "author": "Capillary Technologies",
4
- "version": "0.1.6-alpha.41",
4
+ "version": "0.1.6-alpha.42",
5
5
  "description": "Capillary UI component library with Ant Design v5",
6
6
  "main": "./index.js",
7
7
  "sideEffects": [