@capillarytech/blaze-ui 0.1.4-alpha.6 → 0.1.5
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/CapInput/index.js +3 -4
- package/CapInput/loadable.js +1 -1
- package/CapTable/CapTable.js +95 -111
- package/CapTable/index.js +3 -1
- package/CapTable/loadable.js +13 -0
- package/CapTable/styles.js +60 -20
- package/CapUnifiedSelect/CapUnifiedSelect.js +159 -0
- package/CapUnifiedSelect/index.js +4 -0
- package/CapUnifiedSelect/loadable.js +3 -0
- package/CapUnifiedSelect/messages.js +24 -0
- package/CapUnifiedSelect/styles.js +182 -0
- package/LocaleHoc/index.js +38 -0
- package/dist/235.index.js +2 -0
- package/dist/235.index.js.LICENSE.txt +29 -0
- package/dist/603.index.js +1 -0
- package/dist/esm/CapInput/index.js +2 -4
- package/dist/esm/CapInput/loadable.js +1 -1
- package/dist/esm/CapTable/CapTable.js +93 -78
- package/dist/esm/CapTable/index.js +2 -1
- package/dist/esm/CapTable/loadable.js +12 -0
- package/dist/esm/CapTable/styles.js +17 -2
- package/dist/esm/CapUnifiedSelect/CapUnifiedSelect.js +151 -0
- package/dist/esm/CapUnifiedSelect/index.js +3 -0
- package/dist/esm/CapUnifiedSelect/loadable.js +4 -0
- package/dist/esm/CapUnifiedSelect/messages.js +23 -0
- package/dist/esm/CapUnifiedSelect/styles.js +3 -0
- package/dist/esm/LocaleHoc/index.js +31 -0
- package/dist/esm/index.js +4 -0
- package/dist/esm/translations/en.js +329 -0
- package/dist/index.js +1 -1
- package/dist/index.js.LICENSE.txt +0 -10
- package/index.js +4 -0
- package/package.json +1 -1
- package/translations/en.js +331 -0
package/CapInput/index.js
CHANGED
|
@@ -1,11 +1,10 @@
|
|
|
1
1
|
import CapInput from './CapInput';
|
|
2
|
+
import Number from './Number';
|
|
2
3
|
import Search from './Search';
|
|
3
4
|
import TextArea from './TextArea';
|
|
4
|
-
import Number from './Number';
|
|
5
5
|
|
|
6
|
-
|
|
6
|
+
CapInput.Number = Number;
|
|
7
7
|
CapInput.Search = Search;
|
|
8
8
|
CapInput.TextArea = TextArea;
|
|
9
|
-
CapInput.Number = Number;
|
|
10
9
|
|
|
11
|
-
export default CapInput;
|
|
10
|
+
export default CapInput;
|
package/CapInput/loadable.js
CHANGED
package/CapTable/CapTable.js
CHANGED
|
@@ -1,44 +1,28 @@
|
|
|
1
1
|
/**
|
|
2
2
|
* CapTable - Migrated to Ant Design v5
|
|
3
|
+
* A table component that supports:
|
|
4
|
+
* - Infinite scrolling with virtualization
|
|
5
|
+
* - Sequential data loading
|
|
6
|
+
* - Optimized scroll performance
|
|
3
7
|
*/
|
|
4
|
-
import React, { useEffect,
|
|
8
|
+
import React, { useEffect, useCallback, useState, useRef } from 'react';
|
|
5
9
|
import PropTypes from 'prop-types';
|
|
6
|
-
import {
|
|
7
|
-
import { Table } from 'antd';
|
|
8
|
-
import styled from 'styled-components';
|
|
10
|
+
import { debounce } from 'lodash';
|
|
9
11
|
import classNames from 'classnames';
|
|
10
|
-
import {
|
|
12
|
+
import { withStyles } from '@capillarytech/vulcan-react-sdk/utils';
|
|
13
|
+
import styles, { StyledTable } from './styles';
|
|
11
14
|
import LocaleHoc from '../LocaleHoc';
|
|
12
15
|
|
|
13
|
-
const
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
}
|
|
18
|
-
}
|
|
19
|
-
|
|
20
|
-
&.show-loader {
|
|
21
|
-
.ant-table-body > table > tbody::after {
|
|
22
|
-
content: '${(props) => props.loadMoreData}';
|
|
23
|
-
display: flex;
|
|
24
|
-
justify-content: center;
|
|
25
|
-
position: absolute;
|
|
26
|
-
width: 100%;
|
|
27
|
-
align-items: center;
|
|
28
|
-
height: 60px;
|
|
29
|
-
text-align: center;
|
|
30
|
-
font-size: 16px;
|
|
31
|
-
color: gray;
|
|
32
|
-
border-top: 1px solid ${CAP_G07};
|
|
33
|
-
}
|
|
34
|
-
}
|
|
35
|
-
`;
|
|
16
|
+
const SCROLL_THRESHOLD = 80; // Percentage of scroll to trigger load
|
|
17
|
+
const DEBOUNCE_DELAY = 250; // ms to wait between scroll events
|
|
18
|
+
const DEFAULT_ROW_HEIGHT = 54;
|
|
19
|
+
const DEFAULT_SCROLL_HEIGHT = 400;
|
|
36
20
|
|
|
37
21
|
const CapTable = ({
|
|
38
22
|
id,
|
|
39
23
|
className,
|
|
40
24
|
children,
|
|
41
|
-
|
|
25
|
+
infiniteScroll,
|
|
42
26
|
pagination,
|
|
43
27
|
dataSource,
|
|
44
28
|
offset_limit,
|
|
@@ -47,91 +31,103 @@ const CapTable = ({
|
|
|
47
31
|
showLoader,
|
|
48
32
|
...rest
|
|
49
33
|
}) => {
|
|
50
|
-
const
|
|
51
|
-
const
|
|
52
|
-
|
|
53
|
-
const maxScroll = event.target.scrollHeight - event.target.clientHeight;
|
|
54
|
-
const currentScroll = event.target.scrollTop;
|
|
55
|
-
|
|
56
|
-
if (currentScroll >= maxScroll - 10 && !showLoader) {
|
|
57
|
-
const offsetLimit = { ...offset_limit };
|
|
58
|
-
offsetLimit.offset += offsetLimit.limit;
|
|
59
|
-
setPagination?.(offsetLimit);
|
|
60
|
-
}
|
|
61
|
-
}, 50),
|
|
62
|
-
).current;
|
|
34
|
+
const scrollRef = useRef(null);
|
|
35
|
+
const [hasMore, setHasMore] = useState(true);
|
|
36
|
+
const currentOffsetRef = useRef(0);
|
|
63
37
|
|
|
64
|
-
const
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
38
|
+
const loadMore = useCallback(() => {
|
|
39
|
+
if (!showLoader && hasMore) {
|
|
40
|
+
const nextOffset = currentOffsetRef.current + 1;
|
|
41
|
+
const newOffsetLimit = {
|
|
42
|
+
...offset_limit,
|
|
43
|
+
offset: nextOffset
|
|
44
|
+
};
|
|
45
|
+
|
|
46
|
+
currentOffsetRef.current = nextOffset;
|
|
47
|
+
setPagination(newOffsetLimit);
|
|
68
48
|
}
|
|
69
|
-
}, [
|
|
49
|
+
}, [showLoader, hasMore, setPagination, offset_limit]);
|
|
70
50
|
|
|
71
|
-
const
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
51
|
+
const handleScroll = useCallback(
|
|
52
|
+
debounce((event) => {
|
|
53
|
+
const target = event.target;
|
|
54
|
+
if (!target || !infiniteScroll || !hasMore || showLoader) return;
|
|
75
55
|
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
|
|
56
|
+
const scrollTop = Math.ceil(target.scrollTop);
|
|
57
|
+
const visibleHeight = target.clientHeight;
|
|
58
|
+
const totalHeight = target.scrollHeight;
|
|
59
|
+
|
|
60
|
+
const scrolledPercentage = (scrollTop + visibleHeight) / totalHeight * 100;
|
|
79
61
|
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
}, [id, scroll?.y, setPagination, dataSource, offset_limit]);
|
|
62
|
+
if (scrolledPercentage >= SCROLL_THRESHOLD) {
|
|
63
|
+
loadMore();
|
|
64
|
+
}
|
|
65
|
+
}, DEBOUNCE_DELAY),
|
|
66
|
+
[infiniteScroll, showLoader, hasMore, loadMore]
|
|
67
|
+
);
|
|
87
68
|
|
|
69
|
+
// Setup scroll listener and handle initial load
|
|
88
70
|
useEffect(() => {
|
|
89
|
-
const
|
|
90
|
-
if (
|
|
91
|
-
|
|
92
|
-
|
|
93
|
-
|
|
94
|
-
|
|
71
|
+
const tableBody = document.querySelector(`#${id} .ant-table-body`);
|
|
72
|
+
if (!tableBody) return;
|
|
73
|
+
|
|
74
|
+
scrollRef.current = tableBody;
|
|
75
|
+
tableBody.addEventListener('scroll', handleScroll, { passive: true });
|
|
76
|
+
|
|
77
|
+
// Check if initial load needed
|
|
78
|
+
const shouldLoadInitially = tableBody.scrollHeight <= tableBody.clientHeight
|
|
79
|
+
&& !showLoader
|
|
80
|
+
&& hasMore;
|
|
81
|
+
|
|
82
|
+
if (shouldLoadInitially) {
|
|
83
|
+
currentOffsetRef.current = 0;
|
|
84
|
+
loadMore();
|
|
95
85
|
}
|
|
96
86
|
|
|
87
|
+
// Cleanup
|
|
97
88
|
return () => {
|
|
98
|
-
|
|
99
|
-
|
|
100
|
-
listTable.removeEventListener('scroll', onScrollThrottle);
|
|
101
|
-
}
|
|
89
|
+
scrollRef.current?.removeEventListener('scroll', handleScroll);
|
|
90
|
+
handleScroll.cancel();
|
|
102
91
|
};
|
|
103
|
-
}, [
|
|
104
|
-
infinteScroll,
|
|
105
|
-
dataSource,
|
|
106
|
-
offset_limit,
|
|
107
|
-
addScrollEventListener,
|
|
108
|
-
callSetPaginationIfNotOverflow,
|
|
109
|
-
id,
|
|
110
|
-
onScrollThrottle,
|
|
111
|
-
]);
|
|
92
|
+
}, [id, handleScroll, showLoader, hasMore, loadMore]);
|
|
112
93
|
|
|
94
|
+
// Handle data changes
|
|
113
95
|
useEffect(() => {
|
|
114
|
-
|
|
115
|
-
|
|
116
|
-
|
|
117
|
-
|
|
118
|
-
|
|
119
|
-
|
|
120
|
-
|
|
96
|
+
if (!dataSource?.length) {
|
|
97
|
+
currentOffsetRef.current = 0;
|
|
98
|
+
setHasMore(true);
|
|
99
|
+
} else {
|
|
100
|
+
setHasMore(true);
|
|
101
|
+
}
|
|
102
|
+
}, [dataSource]);
|
|
103
|
+
|
|
104
|
+
const tableClassName = classNames(
|
|
105
|
+
'cap-table-v2',
|
|
106
|
+
className,
|
|
107
|
+
{
|
|
108
|
+
'show-loader': showLoader,
|
|
109
|
+
'infinite-scroll': infiniteScroll,
|
|
110
|
+
'has-more': hasMore
|
|
121
111
|
}
|
|
122
|
-
|
|
112
|
+
);
|
|
123
113
|
|
|
124
114
|
return (
|
|
125
115
|
<StyledTable
|
|
126
|
-
{...rest}
|
|
127
116
|
id={id}
|
|
117
|
+
className={tableClassName}
|
|
128
118
|
dataSource={dataSource}
|
|
129
|
-
|
|
130
|
-
|
|
131
|
-
|
|
132
|
-
|
|
133
|
-
|
|
134
|
-
|
|
119
|
+
pagination={false}
|
|
120
|
+
scroll={{
|
|
121
|
+
x: scroll?.x,
|
|
122
|
+
y: scroll?.y || DEFAULT_SCROLL_HEIGHT,
|
|
123
|
+
scrollToFirstRowOnChange: false
|
|
124
|
+
}}
|
|
125
|
+
virtual={infiniteScroll}
|
|
126
|
+
rowHeight={DEFAULT_ROW_HEIGHT}
|
|
127
|
+
{...rest}
|
|
128
|
+
>
|
|
129
|
+
{children}
|
|
130
|
+
</StyledTable>
|
|
135
131
|
);
|
|
136
132
|
};
|
|
137
133
|
|
|
@@ -139,25 +135,13 @@ CapTable.propTypes = {
|
|
|
139
135
|
id: PropTypes.string.isRequired,
|
|
140
136
|
className: PropTypes.string,
|
|
141
137
|
children: PropTypes.node,
|
|
142
|
-
|
|
143
|
-
pagination: PropTypes.oneOfType([PropTypes.
|
|
138
|
+
infiniteScroll: PropTypes.bool,
|
|
139
|
+
pagination: PropTypes.oneOfType([PropTypes.object, PropTypes.bool]),
|
|
144
140
|
dataSource: PropTypes.array,
|
|
145
|
-
offset_limit: PropTypes.
|
|
146
|
-
offset: PropTypes.number,
|
|
147
|
-
limit: PropTypes.number,
|
|
148
|
-
}),
|
|
141
|
+
offset_limit: PropTypes.object,
|
|
149
142
|
setPagination: PropTypes.func,
|
|
150
143
|
scroll: PropTypes.object,
|
|
151
144
|
showLoader: PropTypes.bool,
|
|
152
145
|
};
|
|
153
146
|
|
|
154
|
-
CapTable
|
|
155
|
-
infinteScroll: false,
|
|
156
|
-
showLoader: false,
|
|
157
|
-
offset_limit: {
|
|
158
|
-
offset: 0,
|
|
159
|
-
limit: 10,
|
|
160
|
-
},
|
|
161
|
-
};
|
|
162
|
-
|
|
163
|
-
export default LocaleHoc(CapTable, { key: 'CapTable' });
|
|
147
|
+
export default LocaleHoc(withStyles(CapTable, styles), { key: 'CapTable' });
|
package/CapTable/index.js
CHANGED
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
import CapSpin from '@capillarytech/cap-ui-library/CapSpin';
|
|
2
|
+
import { loadable } from '@capillarytech/cap-ui-utils';
|
|
3
|
+
import React, { Suspense } from 'react';
|
|
4
|
+
|
|
5
|
+
const LoadableComponent = loadable(() => import('./CapTable'));
|
|
6
|
+
|
|
7
|
+
const CapTableLoadable = () => (
|
|
8
|
+
<Suspense fallback={<CapSpin />}>
|
|
9
|
+
<LoadableComponent />
|
|
10
|
+
</Suspense>
|
|
11
|
+
);
|
|
12
|
+
|
|
13
|
+
export default CapTableLoadable;
|
package/CapTable/styles.js
CHANGED
|
@@ -1,25 +1,61 @@
|
|
|
1
|
-
import {
|
|
1
|
+
import { Table } from 'antd';
|
|
2
|
+
import styled, { css } from 'styled-components';
|
|
3
|
+
|
|
2
4
|
import * as styledVars from '../styled/variables';
|
|
3
5
|
|
|
4
|
-
|
|
6
|
+
const {
|
|
7
|
+
CAP_G09,
|
|
8
|
+
CAP_G01,
|
|
9
|
+
CAP_G06,
|
|
10
|
+
CAP_G07,
|
|
11
|
+
CAP_G10,
|
|
12
|
+
SPACING_16,
|
|
13
|
+
SPACING_24,
|
|
14
|
+
FONT_SIZE_S,
|
|
15
|
+
} = styledVars;
|
|
16
|
+
|
|
17
|
+
export const StyledTable = styled(Table)`
|
|
18
|
+
&.cap-table-v2 {
|
|
19
|
+
.ant-table {
|
|
20
|
+
border: 1px solid ${CAP_G07};
|
|
21
|
+
}
|
|
22
|
+
}
|
|
23
|
+
|
|
24
|
+
&.show-loader {
|
|
25
|
+
.ant-table-body > table > tbody::after {
|
|
26
|
+
content: '${(props) => props.loadMoreData}';
|
|
27
|
+
display: flex;
|
|
28
|
+
justify-content: center;
|
|
29
|
+
position: absolute;
|
|
30
|
+
width: 100%;
|
|
31
|
+
align-items: center;
|
|
32
|
+
height: 60px;
|
|
33
|
+
text-align: center;
|
|
34
|
+
font-size: 16px;
|
|
35
|
+
color: gray;
|
|
36
|
+
border-top: 1px solid ${CAP_G07};
|
|
37
|
+
}
|
|
38
|
+
}
|
|
39
|
+
`;
|
|
40
|
+
export default css`
|
|
5
41
|
.ant-table {
|
|
6
|
-
border: 1px solid ${
|
|
42
|
+
border: 1px solid ${CAP_G07};
|
|
7
43
|
|
|
8
44
|
.ant-table-thead > tr > th {
|
|
9
|
-
color: ${
|
|
10
|
-
font-size: ${
|
|
11
|
-
line-height: ${
|
|
12
|
-
background-color: ${
|
|
45
|
+
color: ${CAP_G01};
|
|
46
|
+
font-size: ${FONT_SIZE_S};
|
|
47
|
+
line-height: ${SPACING_16};
|
|
48
|
+
background-color: ${CAP_G10};
|
|
13
49
|
text-align: left;
|
|
14
50
|
}
|
|
15
51
|
|
|
16
52
|
.ant-table-thead > tr > th,
|
|
17
53
|
.ant-table-tbody > tr > td {
|
|
18
|
-
padding: ${
|
|
54
|
+
padding: ${SPACING_16} ${SPACING_24};
|
|
19
55
|
}
|
|
20
56
|
|
|
21
57
|
.ant-table-tbody > tr > td {
|
|
22
|
-
border-bottom: 1px solid ${
|
|
58
|
+
border-bottom: 1px solid ${CAP_G07};
|
|
23
59
|
}
|
|
24
60
|
|
|
25
61
|
.ant-table-tbody > tr:last-child > td {
|
|
@@ -30,37 +66,37 @@ export const tableStyles = css`
|
|
|
30
66
|
.ant-table-tbody > tr.ant-table-row-hover:not(.ant-table-expanded-row) > td,
|
|
31
67
|
.ant-table-thead > tr:hover:not(.ant-table-expanded-row) > td,
|
|
32
68
|
.ant-table-tbody > tr:hover:not(.ant-table-expanded-row) > td {
|
|
33
|
-
background-color: ${
|
|
69
|
+
background-color: ${CAP_G09};
|
|
34
70
|
}
|
|
35
71
|
|
|
36
72
|
.ant-table-thead > tr > th .ant-table-column-sorter-up,
|
|
37
73
|
.ant-table-thead > tr > th .ant-table-column-sorter-down {
|
|
38
74
|
&.active {
|
|
39
|
-
color: ${
|
|
75
|
+
color: ${CAP_G01};
|
|
40
76
|
}
|
|
41
77
|
&:not(.active) {
|
|
42
|
-
color: ${
|
|
78
|
+
color: ${CAP_G06};
|
|
43
79
|
}
|
|
44
80
|
}
|
|
45
81
|
|
|
46
82
|
.ant-table-thead {
|
|
47
83
|
.table-children {
|
|
48
|
-
padding: 6px ${
|
|
84
|
+
padding: 6px ${SPACING_24} 16px;
|
|
49
85
|
position: relative;
|
|
50
86
|
}
|
|
51
87
|
|
|
52
88
|
.table-parent {
|
|
53
89
|
padding-bottom: 0;
|
|
54
|
-
padding-left: ${
|
|
90
|
+
padding-left: ${SPACING_24};
|
|
55
91
|
}
|
|
56
92
|
|
|
57
93
|
.table-children.show-separator:not(:last-child)::after {
|
|
58
|
-
content:
|
|
94
|
+
content: '';
|
|
59
95
|
height: 8px;
|
|
60
96
|
width: 1px;
|
|
61
97
|
right: 0;
|
|
62
98
|
top: 30%;
|
|
63
|
-
background-color: ${
|
|
99
|
+
background-color: ${CAP_G07};
|
|
64
100
|
position: absolute;
|
|
65
101
|
}
|
|
66
102
|
}
|
|
@@ -85,8 +121,12 @@ export const tableStyles = css`
|
|
|
85
121
|
|
|
86
122
|
&.hide-hover {
|
|
87
123
|
.ant-table {
|
|
88
|
-
.ant-table-thead
|
|
89
|
-
|
|
124
|
+
.ant-table-thead
|
|
125
|
+
> tr.ant-table-row-hover:not(.ant-table-expanded-row)
|
|
126
|
+
> td,
|
|
127
|
+
.ant-table-tbody
|
|
128
|
+
> tr.ant-table-row-hover:not(.ant-table-expanded-row)
|
|
129
|
+
> td,
|
|
90
130
|
.ant-table-thead > tr:hover:not(.ant-table-expanded-row) > td,
|
|
91
131
|
.ant-table-tbody > tr:hover:not(.ant-table-expanded-row) > td {
|
|
92
132
|
background: none;
|
|
@@ -95,6 +135,6 @@ export const tableStyles = css`
|
|
|
95
135
|
}
|
|
96
136
|
|
|
97
137
|
a {
|
|
98
|
-
color: ${
|
|
138
|
+
color: ${CAP_G01};
|
|
99
139
|
}
|
|
100
|
-
`;
|
|
140
|
+
`;
|
|
@@ -0,0 +1,159 @@
|
|
|
1
|
+
import React, { useMemo, useCallback } from 'react';
|
|
2
|
+
import PropTypes from 'prop-types';
|
|
3
|
+
import { Select, TreeSelect } from 'antd';
|
|
4
|
+
import styled from 'styled-components';
|
|
5
|
+
import { selectStyles } from './styles';
|
|
6
|
+
import { useIntl } from 'react-intl';
|
|
7
|
+
import messages from './messages';
|
|
8
|
+
|
|
9
|
+
const StyledSelect = styled(Select)`${selectStyles}`;
|
|
10
|
+
const StyledTreeSelect = styled(TreeSelect)`${selectStyles}`;
|
|
11
|
+
|
|
12
|
+
const CapUnifiedSelect = ({
|
|
13
|
+
type,
|
|
14
|
+
options,
|
|
15
|
+
treeData,
|
|
16
|
+
value,
|
|
17
|
+
onChange,
|
|
18
|
+
onSearch,
|
|
19
|
+
placeholder,
|
|
20
|
+
disabled,
|
|
21
|
+
loading,
|
|
22
|
+
allowClear,
|
|
23
|
+
enableSearch,
|
|
24
|
+
maxTagCount,
|
|
25
|
+
size,
|
|
26
|
+
status,
|
|
27
|
+
className,
|
|
28
|
+
style,
|
|
29
|
+
rightSlotContent,
|
|
30
|
+
virtualized,
|
|
31
|
+
...restProps
|
|
32
|
+
}) => {
|
|
33
|
+
const intl = useIntl();
|
|
34
|
+
|
|
35
|
+
const handleChange = useCallback((newValue, option) => {
|
|
36
|
+
if (onChange) {
|
|
37
|
+
onChange(newValue, option);
|
|
38
|
+
}
|
|
39
|
+
}, [onChange]);
|
|
40
|
+
|
|
41
|
+
const handleSearch = useCallback((searchText) => {
|
|
42
|
+
if (onSearch) {
|
|
43
|
+
onSearch(searchText);
|
|
44
|
+
}
|
|
45
|
+
}, [onSearch]);
|
|
46
|
+
|
|
47
|
+
const mergedClassName = useMemo(() => {
|
|
48
|
+
const classes = ['cap-unified-select'];
|
|
49
|
+
if (className) classes.push(className);
|
|
50
|
+
return classes.join(' ');
|
|
51
|
+
}, [className]);
|
|
52
|
+
|
|
53
|
+
// Common props for both Select and TreeSelect
|
|
54
|
+
const commonProps = {
|
|
55
|
+
value,
|
|
56
|
+
onChange: handleChange,
|
|
57
|
+
onSearch: enableSearch ? handleSearch : undefined,
|
|
58
|
+
placeholder: placeholder || intl.formatMessage(messages.selectPlaceholder),
|
|
59
|
+
disabled,
|
|
60
|
+
loading,
|
|
61
|
+
allowClear,
|
|
62
|
+
showSearch: enableSearch,
|
|
63
|
+
maxTagCount,
|
|
64
|
+
size,
|
|
65
|
+
status,
|
|
66
|
+
className: mergedClassName,
|
|
67
|
+
style,
|
|
68
|
+
virtual: virtualized,
|
|
69
|
+
notFoundContent: loading
|
|
70
|
+
? intl.formatMessage(messages.loading)
|
|
71
|
+
: intl.formatMessage(messages.noData),
|
|
72
|
+
...restProps
|
|
73
|
+
};
|
|
74
|
+
|
|
75
|
+
// Render right slot content if provided
|
|
76
|
+
const suffixIcon = rightSlotContent && (
|
|
77
|
+
<div className="cap-unified-select-right-slot">
|
|
78
|
+
{rightSlotContent}
|
|
79
|
+
</div>
|
|
80
|
+
);
|
|
81
|
+
|
|
82
|
+
// For tree-based selects
|
|
83
|
+
if (type === 'treeSelect' || type === 'multiTreeSelect') {
|
|
84
|
+
return (
|
|
85
|
+
<StyledTreeSelect
|
|
86
|
+
{...commonProps}
|
|
87
|
+
treeData={treeData}
|
|
88
|
+
multiple={type === 'multiTreeSelect'}
|
|
89
|
+
suffixIcon={suffixIcon}
|
|
90
|
+
/>
|
|
91
|
+
);
|
|
92
|
+
}
|
|
93
|
+
|
|
94
|
+
// For regular selects
|
|
95
|
+
return (
|
|
96
|
+
<StyledSelect
|
|
97
|
+
{...commonProps}
|
|
98
|
+
mode={type === 'multiSelect' ? 'multiple' : undefined}
|
|
99
|
+
options={options}
|
|
100
|
+
suffixIcon={suffixIcon}
|
|
101
|
+
/>
|
|
102
|
+
);
|
|
103
|
+
};
|
|
104
|
+
|
|
105
|
+
CapUnifiedSelect.propTypes = {
|
|
106
|
+
type: PropTypes.oneOf(['select', 'multiSelect', 'treeSelect', 'multiTreeSelect']).isRequired,
|
|
107
|
+
options: PropTypes.arrayOf(
|
|
108
|
+
PropTypes.shape({
|
|
109
|
+
label: PropTypes.node,
|
|
110
|
+
value: PropTypes.any,
|
|
111
|
+
disabled: PropTypes.bool,
|
|
112
|
+
})
|
|
113
|
+
),
|
|
114
|
+
treeData: PropTypes.arrayOf(
|
|
115
|
+
PropTypes.shape({
|
|
116
|
+
title: PropTypes.node,
|
|
117
|
+
value: PropTypes.any,
|
|
118
|
+
children: PropTypes.array,
|
|
119
|
+
disabled: PropTypes.bool,
|
|
120
|
+
})
|
|
121
|
+
),
|
|
122
|
+
value: PropTypes.any,
|
|
123
|
+
onChange: PropTypes.func,
|
|
124
|
+
onSearch: PropTypes.func,
|
|
125
|
+
placeholder: PropTypes.string,
|
|
126
|
+
disabled: PropTypes.bool,
|
|
127
|
+
loading: PropTypes.bool,
|
|
128
|
+
allowClear: PropTypes.bool,
|
|
129
|
+
enableSearch: PropTypes.bool,
|
|
130
|
+
maxTagCount: PropTypes.number,
|
|
131
|
+
size: PropTypes.oneOf(['small', 'middle', 'large']),
|
|
132
|
+
status: PropTypes.oneOf(['error', 'warning']),
|
|
133
|
+
className: PropTypes.string,
|
|
134
|
+
style: PropTypes.object,
|
|
135
|
+
rightSlotContent: PropTypes.node,
|
|
136
|
+
virtualized: PropTypes.bool,
|
|
137
|
+
};
|
|
138
|
+
|
|
139
|
+
CapUnifiedSelect.defaultProps = {
|
|
140
|
+
options: [],
|
|
141
|
+
treeData: [],
|
|
142
|
+
value: undefined,
|
|
143
|
+
onChange: undefined,
|
|
144
|
+
onSearch: undefined,
|
|
145
|
+
placeholder: '',
|
|
146
|
+
disabled: false,
|
|
147
|
+
loading: false,
|
|
148
|
+
allowClear: true,
|
|
149
|
+
enableSearch: false,
|
|
150
|
+
maxTagCount: undefined,
|
|
151
|
+
size: 'middle',
|
|
152
|
+
status: undefined,
|
|
153
|
+
className: '',
|
|
154
|
+
style: {},
|
|
155
|
+
rightSlotContent: null,
|
|
156
|
+
virtualized: true,
|
|
157
|
+
};
|
|
158
|
+
|
|
159
|
+
export default CapUnifiedSelect;
|
|
@@ -0,0 +1,24 @@
|
|
|
1
|
+
import { defineMessages } from 'react-intl';
|
|
2
|
+
|
|
3
|
+
export default defineMessages({
|
|
4
|
+
selectPlaceholder: {
|
|
5
|
+
id: 'cap.unified.select.placeholder',
|
|
6
|
+
defaultMessage: 'Select an option',
|
|
7
|
+
},
|
|
8
|
+
searchPlaceholder: {
|
|
9
|
+
id: 'cap.unified.select.search.placeholder',
|
|
10
|
+
defaultMessage: 'Search...',
|
|
11
|
+
},
|
|
12
|
+
noData: {
|
|
13
|
+
id: 'cap.unified.select.no.data',
|
|
14
|
+
defaultMessage: 'No data',
|
|
15
|
+
},
|
|
16
|
+
loading: {
|
|
17
|
+
id: 'cap.unified.select.loading',
|
|
18
|
+
defaultMessage: 'Loading...',
|
|
19
|
+
},
|
|
20
|
+
selected: {
|
|
21
|
+
id: 'cap.unified.select.selected',
|
|
22
|
+
defaultMessage: '{count} items selected',
|
|
23
|
+
},
|
|
24
|
+
});
|