@capillarytech/blaze-ui 0.1.6-alpha.33 → 0.1.6-alpha.34
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/CapInput.js +67 -0
- package/CapInput/Number.js +38 -0
- package/CapInput/Search.js +32 -0
- package/CapInput/TextArea.js +45 -0
- package/{dist/esm/CapInput → CapInput}/index.js +3 -1
- package/CapInput/messages.js +27 -0
- package/CapInput/styles.js +81 -0
- package/CapSkeleton/CapSkeleton.js +17 -0
- package/CapSpin/CapSpin.js +23 -0
- package/CapTable/CapTable.js +146 -0
- package/{dist/esm/CapTable → CapTable}/index.js +2 -1
- package/CapTable/loadable.js +13 -0
- package/CapTable/styles.js +134 -0
- package/CapTestSelect/CapTestSelect.js +47 -0
- package/CapTestSelect/index.js +1 -0
- package/CapUnifiedSelect/CapUnifiedSelect.js +299 -0
- package/CapUnifiedSelect/index.js +1 -0
- package/{dist/esm/CapUnifiedSelect → CapUnifiedSelect}/messages.js +8 -7
- package/CapUnifiedSelect/styles.js +452 -0
- package/LocaleHoc/index.js +38 -0
- package/assets/Images/Upload.png +0 -0
- package/components/index.js +5 -16
- package/index.js +15 -0
- package/package.json +2 -2
- package/{dist/esm/styled → styled}/index.js +2 -1
- package/styled/variables.js +89 -0
- package/{dist/esm/translations → translations}/en.js +34 -32
- package/dist/CapInput/CapInput.js +0 -66
- package/dist/CapInput/Number.js +0 -42
- package/dist/CapInput/Search.js +0 -35
- package/dist/CapInput/TextArea.js +0 -42
- package/dist/CapInput/index.js +0 -15
- package/dist/CapInput/messages.js +0 -32
- package/dist/CapInput/styles.js +0 -11
- package/dist/CapSkeleton/CapSkeleton.js +0 -29
- package/dist/CapSkeleton/index.js +0 -13
- package/dist/CapSpin/CapSpin.js +0 -35
- package/dist/CapSpin/index.js +0 -13
- package/dist/CapTable/CapTable.js +0 -148
- package/dist/CapTable/index.js +0 -9
- package/dist/CapTable/loadable.js +0 -23
- package/dist/CapTable/styles.js +0 -26
- package/dist/CapUnifiedSelect/CapUnifiedSelect.js +0 -405
- package/dist/CapUnifiedSelect/index.js +0 -13
- package/dist/CapUnifiedSelect/messages.js +0 -29
- package/dist/CapUnifiedSelect/styles.js +0 -39
- package/dist/LocaleHoc/index.js +0 -40
- package/dist/esm/CapInput/CapInput.js +0 -57
- package/dist/esm/CapInput/Number.js +0 -35
- package/dist/esm/CapInput/Search.js +0 -28
- package/dist/esm/CapInput/TextArea.js +0 -35
- package/dist/esm/CapInput/messages.js +0 -25
- package/dist/esm/CapInput/styles.js +0 -3
- package/dist/esm/CapSkeleton/CapSkeleton.js +0 -22
- package/dist/esm/CapSpin/CapSpin.js +0 -28
- package/dist/esm/CapTable/CapTable.js +0 -140
- package/dist/esm/CapTable/loadable.js +0 -12
- package/dist/esm/CapTable/styles.js +0 -17
- package/dist/esm/CapUnifiedSelect/CapUnifiedSelect.js +0 -398
- package/dist/esm/CapUnifiedSelect/index.js +0 -1
- package/dist/esm/CapUnifiedSelect/styles.js +0 -31
- package/dist/esm/LocaleHoc/index.js +0 -31
- package/dist/esm/index.js +0 -11
- package/dist/esm/styled/variables.js +0 -88
- package/dist/index.js +0 -39
- package/dist/styled/index.js +0 -22
- package/dist/styled/variables.js +0 -94
- package/dist/translations/en.js +0 -335
- /package/{dist/esm/CapSkeleton → CapSkeleton}/index.js +0 -0
- /package/{dist/esm/CapSpin → CapSpin}/index.js +0 -0
|
@@ -0,0 +1,67 @@
|
|
|
1
|
+
import React, { useRef, useEffect } from 'react';
|
|
2
|
+
import PropTypes from 'prop-types';
|
|
3
|
+
import { Input } from 'antd';
|
|
4
|
+
import { WarningOutlined, CheckCircleOutlined } from '@ant-design/icons';
|
|
5
|
+
import styled from 'styled-components';
|
|
6
|
+
import * as styledVars from '../styled/variables';
|
|
7
|
+
|
|
8
|
+
const StyledIcon = styled.span`
|
|
9
|
+
color: ${(props) => props.status === "error" && styledVars.CAP_RED};
|
|
10
|
+
color: ${(props) => props.status === "success" && styledVars.CAP_PRIMARY.base};
|
|
11
|
+
`;
|
|
12
|
+
|
|
13
|
+
const CapInput = React.forwardRef((props, ref) => {
|
|
14
|
+
const {
|
|
15
|
+
alwaysShowFocus,
|
|
16
|
+
errorMessage,
|
|
17
|
+
isVerified,
|
|
18
|
+
suffix,
|
|
19
|
+
showSuffix = true,
|
|
20
|
+
...rest
|
|
21
|
+
} = props;
|
|
22
|
+
|
|
23
|
+
const inputRef = useRef(null);
|
|
24
|
+
|
|
25
|
+
useEffect(() => {
|
|
26
|
+
if (alwaysShowFocus && inputRef.current) {
|
|
27
|
+
inputRef.current.focus();
|
|
28
|
+
}
|
|
29
|
+
}, [alwaysShowFocus]);
|
|
30
|
+
|
|
31
|
+
const inputSuffix = (errorMessage && (
|
|
32
|
+
<StyledIcon status="error">
|
|
33
|
+
<WarningOutlined />
|
|
34
|
+
</StyledIcon>
|
|
35
|
+
)) || (isVerified && (
|
|
36
|
+
<StyledIcon status="success">
|
|
37
|
+
<CheckCircleOutlined />
|
|
38
|
+
</StyledIcon>
|
|
39
|
+
)) || suffix || null;
|
|
40
|
+
|
|
41
|
+
return (
|
|
42
|
+
<Input
|
|
43
|
+
{...rest}
|
|
44
|
+
ref={ref || inputRef}
|
|
45
|
+
suffix={showSuffix === false ? null : inputSuffix}
|
|
46
|
+
status={errorMessage ? 'error' : undefined}
|
|
47
|
+
/>
|
|
48
|
+
);
|
|
49
|
+
});
|
|
50
|
+
|
|
51
|
+
CapInput.displayName = 'CapInput';
|
|
52
|
+
|
|
53
|
+
CapInput.propTypes = {
|
|
54
|
+
alwaysShowFocus: PropTypes.bool,
|
|
55
|
+
errorMessage: PropTypes.oneOfType([PropTypes.string, PropTypes.node]),
|
|
56
|
+
isVerified: PropTypes.bool,
|
|
57
|
+
size: PropTypes.oneOf(['large', 'middle', 'small']),
|
|
58
|
+
suffix: PropTypes.node,
|
|
59
|
+
showSuffix: PropTypes.bool,
|
|
60
|
+
};
|
|
61
|
+
|
|
62
|
+
CapInput.defaultProps = {
|
|
63
|
+
size: 'large',
|
|
64
|
+
showSuffix: true,
|
|
65
|
+
};
|
|
66
|
+
|
|
67
|
+
export default CapInput;
|
|
@@ -0,0 +1,38 @@
|
|
|
1
|
+
import React from 'react';
|
|
2
|
+
import PropTypes from 'prop-types';
|
|
3
|
+
import { InputNumber } from 'antd';
|
|
4
|
+
|
|
5
|
+
const CapInputNumber = React.forwardRef((props, ref) => {
|
|
6
|
+
const { size = 'large', ...rest } = props;
|
|
7
|
+
|
|
8
|
+
return (
|
|
9
|
+
<InputNumber
|
|
10
|
+
{...rest}
|
|
11
|
+
ref={ref}
|
|
12
|
+
size={size}
|
|
13
|
+
/>
|
|
14
|
+
);
|
|
15
|
+
});
|
|
16
|
+
|
|
17
|
+
CapInputNumber.displayName = 'CapInputNumber';
|
|
18
|
+
|
|
19
|
+
CapInputNumber.propTypes = {
|
|
20
|
+
size: PropTypes.oneOf(['large', 'middle', 'small']),
|
|
21
|
+
min: PropTypes.number,
|
|
22
|
+
max: PropTypes.number,
|
|
23
|
+
step: PropTypes.oneOfType([PropTypes.number, PropTypes.string]),
|
|
24
|
+
precision: PropTypes.number,
|
|
25
|
+
decimalSeparator: PropTypes.string,
|
|
26
|
+
formatter: PropTypes.func,
|
|
27
|
+
parser: PropTypes.func,
|
|
28
|
+
controls: PropTypes.oneOfType([PropTypes.bool, PropTypes.object]),
|
|
29
|
+
keyboard: PropTypes.bool,
|
|
30
|
+
stringMode: PropTypes.bool,
|
|
31
|
+
};
|
|
32
|
+
|
|
33
|
+
CapInputNumber.defaultProps = {
|
|
34
|
+
size: 'large',
|
|
35
|
+
keyboard: true,
|
|
36
|
+
};
|
|
37
|
+
|
|
38
|
+
export default CapInputNumber;
|
|
@@ -0,0 +1,32 @@
|
|
|
1
|
+
import React from 'react';
|
|
2
|
+
import PropTypes from 'prop-types';
|
|
3
|
+
import { Input } from 'antd';
|
|
4
|
+
|
|
5
|
+
const { Search } = Input;
|
|
6
|
+
|
|
7
|
+
const CapInputSearch = React.forwardRef((props, ref) => {
|
|
8
|
+
const { size = 'large', ...rest } = props;
|
|
9
|
+
|
|
10
|
+
return (
|
|
11
|
+
<Search
|
|
12
|
+
{...rest}
|
|
13
|
+
ref={ref}
|
|
14
|
+
size={size}
|
|
15
|
+
/>
|
|
16
|
+
);
|
|
17
|
+
});
|
|
18
|
+
|
|
19
|
+
CapInputSearch.displayName = 'CapInputSearch';
|
|
20
|
+
|
|
21
|
+
CapInputSearch.propTypes = {
|
|
22
|
+
size: PropTypes.oneOf(['large', 'middle', 'small']),
|
|
23
|
+
enterButton: PropTypes.oneOfType([PropTypes.bool, PropTypes.node]),
|
|
24
|
+
loading: PropTypes.bool,
|
|
25
|
+
onSearch: PropTypes.func,
|
|
26
|
+
};
|
|
27
|
+
|
|
28
|
+
CapInputSearch.defaultProps = {
|
|
29
|
+
size: 'large',
|
|
30
|
+
};
|
|
31
|
+
|
|
32
|
+
export default CapInputSearch;
|
|
@@ -0,0 +1,45 @@
|
|
|
1
|
+
import React from 'react';
|
|
2
|
+
import PropTypes from 'prop-types';
|
|
3
|
+
import { Input } from 'antd';
|
|
4
|
+
|
|
5
|
+
const { TextArea } = Input;
|
|
6
|
+
|
|
7
|
+
const CapInputTextArea = React.forwardRef((props, ref) => {
|
|
8
|
+
const { size = 'large', ...rest } = props;
|
|
9
|
+
|
|
10
|
+
return (
|
|
11
|
+
<TextArea
|
|
12
|
+
{...rest}
|
|
13
|
+
ref={ref}
|
|
14
|
+
size={size}
|
|
15
|
+
/>
|
|
16
|
+
);
|
|
17
|
+
});
|
|
18
|
+
|
|
19
|
+
CapInputTextArea.displayName = 'CapInputTextArea';
|
|
20
|
+
|
|
21
|
+
CapInputTextArea.propTypes = {
|
|
22
|
+
size: PropTypes.oneOf(['large', 'middle', 'small']),
|
|
23
|
+
autoSize: PropTypes.oneOfType([
|
|
24
|
+
PropTypes.bool,
|
|
25
|
+
PropTypes.shape({
|
|
26
|
+
minRows: PropTypes.number,
|
|
27
|
+
maxRows: PropTypes.number,
|
|
28
|
+
}),
|
|
29
|
+
]),
|
|
30
|
+
rows: PropTypes.number,
|
|
31
|
+
maxLength: PropTypes.number,
|
|
32
|
+
showCount: PropTypes.oneOfType([
|
|
33
|
+
PropTypes.bool,
|
|
34
|
+
PropTypes.shape({
|
|
35
|
+
formatter: PropTypes.func,
|
|
36
|
+
}),
|
|
37
|
+
]),
|
|
38
|
+
};
|
|
39
|
+
|
|
40
|
+
CapInputTextArea.defaultProps = {
|
|
41
|
+
size: 'large',
|
|
42
|
+
rows: 4,
|
|
43
|
+
};
|
|
44
|
+
|
|
45
|
+
export default CapInputTextArea;
|
|
@@ -2,7 +2,9 @@ import CapInput from './CapInput';
|
|
|
2
2
|
import Number from './Number';
|
|
3
3
|
import Search from './Search';
|
|
4
4
|
import TextArea from './TextArea';
|
|
5
|
+
|
|
5
6
|
CapInput.Number = Number;
|
|
6
7
|
CapInput.Search = Search;
|
|
7
8
|
CapInput.TextArea = TextArea;
|
|
8
|
-
|
|
9
|
+
|
|
10
|
+
export default CapInput;
|
|
@@ -0,0 +1,27 @@
|
|
|
1
|
+
/*
|
|
2
|
+
* CapInput Messages
|
|
3
|
+
*
|
|
4
|
+
* This contains all the text for the CapInput component.
|
|
5
|
+
*/
|
|
6
|
+
import { defineMessages } from 'react-intl';
|
|
7
|
+
|
|
8
|
+
const scope = 'blaze.components.CapInput';
|
|
9
|
+
|
|
10
|
+
export default defineMessages({
|
|
11
|
+
placeholder: {
|
|
12
|
+
id: `${scope}.placeholder`,
|
|
13
|
+
defaultMessage: 'Enter text...',
|
|
14
|
+
},
|
|
15
|
+
searchPlaceholder: {
|
|
16
|
+
id: `${scope}.searchPlaceholder`,
|
|
17
|
+
defaultMessage: 'Search...',
|
|
18
|
+
},
|
|
19
|
+
textAreaPlaceholder: {
|
|
20
|
+
id: `${scope}.textAreaPlaceholder`,
|
|
21
|
+
defaultMessage: 'Enter your text here...',
|
|
22
|
+
},
|
|
23
|
+
numberPlaceholder: {
|
|
24
|
+
id: `${scope}.numberPlaceholder`,
|
|
25
|
+
defaultMessage: 'Enter number...',
|
|
26
|
+
},
|
|
27
|
+
});
|
|
@@ -0,0 +1,81 @@
|
|
|
1
|
+
import { css } from 'styled-components';
|
|
2
|
+
import * as styledVars from '../styled/variables';
|
|
3
|
+
|
|
4
|
+
export const inputStyles = css`
|
|
5
|
+
&.ant-input,
|
|
6
|
+
&.ant-input-affix-wrapper,
|
|
7
|
+
&.ant-input-number,
|
|
8
|
+
&.ant-input-textarea {
|
|
9
|
+
font-family: ${styledVars.FONT_FAMILY};
|
|
10
|
+
border-radius: ${styledVars.RADIUS_04};
|
|
11
|
+
transition: ${styledVars.TRANSITION_ALL};
|
|
12
|
+
|
|
13
|
+
&:hover {
|
|
14
|
+
border-color: ${styledVars.CAP_G11};
|
|
15
|
+
}
|
|
16
|
+
|
|
17
|
+
&:focus,
|
|
18
|
+
&.ant-input-affix-wrapper-focused {
|
|
19
|
+
border-color: ${styledVars.CAP_G01};
|
|
20
|
+
box-shadow: none;
|
|
21
|
+
}
|
|
22
|
+
|
|
23
|
+
&.ant-input-status-error,
|
|
24
|
+
&.ant-input-affix-wrapper-status-error,
|
|
25
|
+
&.ant-input-number-status-error {
|
|
26
|
+
border-color: ${styledVars.CAP_RED};
|
|
27
|
+
|
|
28
|
+
&:hover {
|
|
29
|
+
border-color: ${styledVars.CAP_RED};
|
|
30
|
+
}
|
|
31
|
+
|
|
32
|
+
&:focus,
|
|
33
|
+
&.ant-input-affix-wrapper-focused {
|
|
34
|
+
border-color: ${styledVars.CAP_RED};
|
|
35
|
+
box-shadow: none;
|
|
36
|
+
}
|
|
37
|
+
}
|
|
38
|
+
|
|
39
|
+
&.ant-input-disabled,
|
|
40
|
+
&.ant-input-affix-wrapper-disabled {
|
|
41
|
+
background-color: ${styledVars.CAP_G08};
|
|
42
|
+
cursor: not-allowed;
|
|
43
|
+
}
|
|
44
|
+
}
|
|
45
|
+
|
|
46
|
+
/* Size variations */
|
|
47
|
+
&.ant-input-lg,
|
|
48
|
+
&.ant-input-affix-wrapper-lg {
|
|
49
|
+
font-size: 14px;
|
|
50
|
+
padding: 10px 12px;
|
|
51
|
+
}
|
|
52
|
+
|
|
53
|
+
/* TextArea specific */
|
|
54
|
+
&.ant-input-textarea {
|
|
55
|
+
.ant-input {
|
|
56
|
+
font-family: ${styledVars.FONT_FAMILY};
|
|
57
|
+
}
|
|
58
|
+
}
|
|
59
|
+
|
|
60
|
+
/* Number input specific */
|
|
61
|
+
&.ant-input-number {
|
|
62
|
+
width: 100%;
|
|
63
|
+
|
|
64
|
+
.ant-input-number-handler-wrap {
|
|
65
|
+
opacity: 1;
|
|
66
|
+
}
|
|
67
|
+
}
|
|
68
|
+
|
|
69
|
+
/* Search input specific */
|
|
70
|
+
&.ant-input-search {
|
|
71
|
+
.ant-input-search-button {
|
|
72
|
+
background-color: ${styledVars.CAP_PRIMARY.base};
|
|
73
|
+
border-color: ${styledVars.CAP_PRIMARY.base};
|
|
74
|
+
|
|
75
|
+
&:hover {
|
|
76
|
+
background-color: ${styledVars.CAP_PRIMARY.hover};
|
|
77
|
+
border-color: ${styledVars.CAP_PRIMARY.hover};
|
|
78
|
+
}
|
|
79
|
+
}
|
|
80
|
+
}
|
|
81
|
+
`;
|
|
@@ -0,0 +1,17 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* CapSkeleton - Migrated to Ant Design v5
|
|
3
|
+
*/
|
|
4
|
+
import React from 'react';
|
|
5
|
+
import PropTypes from 'prop-types';
|
|
6
|
+
import { Skeleton } from 'antd';
|
|
7
|
+
|
|
8
|
+
const CapSkeleton = ({ className, ...rest }) => {
|
|
9
|
+
const combinedClassName = `cap-skeleton-v2 ${className || ''}`.trim();
|
|
10
|
+
return <Skeleton className={combinedClassName} {...rest} />;
|
|
11
|
+
};
|
|
12
|
+
|
|
13
|
+
CapSkeleton.propTypes = {
|
|
14
|
+
className: PropTypes.string
|
|
15
|
+
};
|
|
16
|
+
|
|
17
|
+
export default CapSkeleton;
|
|
@@ -0,0 +1,23 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* CapSpin - Migrated to Ant Design v5
|
|
3
|
+
*/
|
|
4
|
+
import React from 'react';
|
|
5
|
+
import PropTypes from 'prop-types';
|
|
6
|
+
import { Spin } from 'antd';
|
|
7
|
+
|
|
8
|
+
const CapSpin = ({ className, ...rest }) => (
|
|
9
|
+
<Spin className={className} {...rest} />
|
|
10
|
+
);
|
|
11
|
+
|
|
12
|
+
CapSpin.propTypes = {
|
|
13
|
+
className: PropTypes.string,
|
|
14
|
+
size: PropTypes.oneOf(['small', 'default', 'large']),
|
|
15
|
+
spinning: PropTypes.bool,
|
|
16
|
+
tip: PropTypes.string,
|
|
17
|
+
delay: PropTypes.number,
|
|
18
|
+
indicator: PropTypes.node,
|
|
19
|
+
fullscreen: PropTypes.bool,
|
|
20
|
+
wrapperClassName: PropTypes.string
|
|
21
|
+
};
|
|
22
|
+
|
|
23
|
+
export default CapSpin;
|
|
@@ -0,0 +1,146 @@
|
|
|
1
|
+
/**
|
|
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
|
|
7
|
+
*/
|
|
8
|
+
import React, { useEffect, useCallback, useState, useRef } from 'react';
|
|
9
|
+
import PropTypes from 'prop-types';
|
|
10
|
+
import { debounce } from 'lodash';
|
|
11
|
+
import classNames from 'classnames';
|
|
12
|
+
import { StyledTable } from './styles';
|
|
13
|
+
import LocaleHoc from '../LocaleHoc';
|
|
14
|
+
|
|
15
|
+
const SCROLL_THRESHOLD = 80; // Percentage of scroll to trigger load
|
|
16
|
+
const DEBOUNCE_DELAY = 250; // ms to wait between scroll events
|
|
17
|
+
const DEFAULT_ROW_HEIGHT = 54;
|
|
18
|
+
const DEFAULT_SCROLL_HEIGHT = 400;
|
|
19
|
+
|
|
20
|
+
const CapTable = ({
|
|
21
|
+
id,
|
|
22
|
+
className,
|
|
23
|
+
children,
|
|
24
|
+
infiniteScroll,
|
|
25
|
+
pagination,
|
|
26
|
+
dataSource,
|
|
27
|
+
offset_limit,
|
|
28
|
+
setPagination,
|
|
29
|
+
scroll,
|
|
30
|
+
showLoader,
|
|
31
|
+
...rest
|
|
32
|
+
}) => {
|
|
33
|
+
const scrollRef = useRef(null);
|
|
34
|
+
const [hasMore, setHasMore] = useState(true);
|
|
35
|
+
const currentOffsetRef = useRef(0);
|
|
36
|
+
|
|
37
|
+
const loadMore = useCallback(() => {
|
|
38
|
+
if (!showLoader && hasMore) {
|
|
39
|
+
const nextOffset = currentOffsetRef.current + 1;
|
|
40
|
+
const newOffsetLimit = {
|
|
41
|
+
...offset_limit,
|
|
42
|
+
offset: nextOffset
|
|
43
|
+
};
|
|
44
|
+
|
|
45
|
+
currentOffsetRef.current = nextOffset;
|
|
46
|
+
setPagination(newOffsetLimit);
|
|
47
|
+
}
|
|
48
|
+
}, [showLoader, hasMore, setPagination, offset_limit]);
|
|
49
|
+
|
|
50
|
+
const handleScroll = useCallback(
|
|
51
|
+
debounce((event) => {
|
|
52
|
+
const target = event.target;
|
|
53
|
+
if (!target || !infiniteScroll || !hasMore || showLoader) return;
|
|
54
|
+
|
|
55
|
+
const scrollTop = Math.ceil(target.scrollTop);
|
|
56
|
+
const visibleHeight = target.clientHeight;
|
|
57
|
+
const totalHeight = target.scrollHeight;
|
|
58
|
+
|
|
59
|
+
const scrolledPercentage = (scrollTop + visibleHeight) / totalHeight * 100;
|
|
60
|
+
|
|
61
|
+
if (scrolledPercentage >= SCROLL_THRESHOLD) {
|
|
62
|
+
loadMore();
|
|
63
|
+
}
|
|
64
|
+
}, DEBOUNCE_DELAY),
|
|
65
|
+
[infiniteScroll, showLoader, hasMore, loadMore]
|
|
66
|
+
);
|
|
67
|
+
|
|
68
|
+
// Setup scroll listener and handle initial load
|
|
69
|
+
useEffect(() => {
|
|
70
|
+
const tableBody = document.querySelector(`#${id} .ant-table-body`);
|
|
71
|
+
if (!tableBody) return;
|
|
72
|
+
|
|
73
|
+
scrollRef.current = tableBody;
|
|
74
|
+
tableBody.addEventListener('scroll', handleScroll, { passive: true });
|
|
75
|
+
|
|
76
|
+
// Check if initial load needed
|
|
77
|
+
const shouldLoadInitially = tableBody.scrollHeight <= tableBody.clientHeight
|
|
78
|
+
&& !showLoader
|
|
79
|
+
&& hasMore;
|
|
80
|
+
|
|
81
|
+
if (shouldLoadInitially) {
|
|
82
|
+
currentOffsetRef.current = 0;
|
|
83
|
+
loadMore();
|
|
84
|
+
}
|
|
85
|
+
|
|
86
|
+
// Cleanup
|
|
87
|
+
return () => {
|
|
88
|
+
scrollRef.current?.removeEventListener('scroll', handleScroll);
|
|
89
|
+
handleScroll.cancel();
|
|
90
|
+
};
|
|
91
|
+
}, [id, handleScroll, showLoader, hasMore, loadMore]);
|
|
92
|
+
|
|
93
|
+
// Handle data changes
|
|
94
|
+
useEffect(() => {
|
|
95
|
+
if (!dataSource?.length) {
|
|
96
|
+
currentOffsetRef.current = 0;
|
|
97
|
+
setHasMore(true);
|
|
98
|
+
} else {
|
|
99
|
+
setHasMore(true);
|
|
100
|
+
}
|
|
101
|
+
}, [dataSource]);
|
|
102
|
+
|
|
103
|
+
const tableClassName = classNames(
|
|
104
|
+
'cap-table-v2',
|
|
105
|
+
className,
|
|
106
|
+
{
|
|
107
|
+
'show-loader': showLoader,
|
|
108
|
+
'infinite-scroll': infiniteScroll,
|
|
109
|
+
'has-more': hasMore
|
|
110
|
+
}
|
|
111
|
+
);
|
|
112
|
+
|
|
113
|
+
return (
|
|
114
|
+
<StyledTable
|
|
115
|
+
id={id}
|
|
116
|
+
className={tableClassName}
|
|
117
|
+
dataSource={dataSource}
|
|
118
|
+
pagination={false}
|
|
119
|
+
scroll={{
|
|
120
|
+
x: scroll?.x,
|
|
121
|
+
y: scroll?.y || DEFAULT_SCROLL_HEIGHT,
|
|
122
|
+
scrollToFirstRowOnChange: false
|
|
123
|
+
}}
|
|
124
|
+
virtual={infiniteScroll}
|
|
125
|
+
rowHeight={DEFAULT_ROW_HEIGHT}
|
|
126
|
+
{...rest}
|
|
127
|
+
>
|
|
128
|
+
{children}
|
|
129
|
+
</StyledTable>
|
|
130
|
+
);
|
|
131
|
+
};
|
|
132
|
+
|
|
133
|
+
CapTable.propTypes = {
|
|
134
|
+
id: PropTypes.string.isRequired,
|
|
135
|
+
className: PropTypes.string,
|
|
136
|
+
children: PropTypes.node,
|
|
137
|
+
infiniteScroll: PropTypes.bool,
|
|
138
|
+
pagination: PropTypes.oneOfType([PropTypes.object, PropTypes.bool]),
|
|
139
|
+
dataSource: PropTypes.array,
|
|
140
|
+
offset_limit: PropTypes.object,
|
|
141
|
+
setPagination: PropTypes.func,
|
|
142
|
+
scroll: PropTypes.object,
|
|
143
|
+
showLoader: PropTypes.bool,
|
|
144
|
+
};
|
|
145
|
+
|
|
146
|
+
export default LocaleHoc(CapTable, { key: 'CapTable' });
|
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
import CapSkeleton from '../CapSkeleton';
|
|
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 = (props) => (
|
|
8
|
+
<Suspense fallback={<CapSkeleton />}>
|
|
9
|
+
<LoadableComponent {...props} />
|
|
10
|
+
</Suspense>
|
|
11
|
+
);
|
|
12
|
+
|
|
13
|
+
export default CapTableLoadable;
|
|
@@ -0,0 +1,134 @@
|
|
|
1
|
+
import { Table } from 'antd';
|
|
2
|
+
import styled from 'styled-components';
|
|
3
|
+
import * as styledVars from '../styled/variables';
|
|
4
|
+
|
|
5
|
+
const {
|
|
6
|
+
CAP_G09,
|
|
7
|
+
CAP_G01,
|
|
8
|
+
CAP_G06,
|
|
9
|
+
CAP_G07,
|
|
10
|
+
CAP_G10,
|
|
11
|
+
SPACING_16,
|
|
12
|
+
SPACING_24,
|
|
13
|
+
FONT_SIZE_S,
|
|
14
|
+
} = styledVars;
|
|
15
|
+
|
|
16
|
+
export const StyledTable = styled(Table)`
|
|
17
|
+
&.cap-table-v2 {
|
|
18
|
+
.ant-table {
|
|
19
|
+
border: 1px solid ${CAP_G07};
|
|
20
|
+
}
|
|
21
|
+
}
|
|
22
|
+
|
|
23
|
+
&.show-loader {
|
|
24
|
+
.ant-table-body > table > tbody::after {
|
|
25
|
+
content: '${(props) => props.loadMoreData}';
|
|
26
|
+
display: flex;
|
|
27
|
+
justify-content: center;
|
|
28
|
+
position: absolute;
|
|
29
|
+
width: 100%;
|
|
30
|
+
align-items: center;
|
|
31
|
+
height: 60px;
|
|
32
|
+
text-align: center;
|
|
33
|
+
font-size: 16px;
|
|
34
|
+
color: gray;
|
|
35
|
+
border-top: 1px solid ${CAP_G07};
|
|
36
|
+
}
|
|
37
|
+
}
|
|
38
|
+
|
|
39
|
+
.ant-table {
|
|
40
|
+
border: 1px solid ${CAP_G07};
|
|
41
|
+
|
|
42
|
+
.ant-table-thead > tr > th {
|
|
43
|
+
color: ${CAP_G01};
|
|
44
|
+
font-size: ${FONT_SIZE_S};
|
|
45
|
+
line-height: ${SPACING_16};
|
|
46
|
+
background-color: ${CAP_G10};
|
|
47
|
+
text-align: left;
|
|
48
|
+
}
|
|
49
|
+
|
|
50
|
+
.ant-table-thead > tr > th,
|
|
51
|
+
.ant-table-tbody > tr > td {
|
|
52
|
+
padding: ${SPACING_16} ${SPACING_24};
|
|
53
|
+
}
|
|
54
|
+
|
|
55
|
+
.ant-table-tbody > tr > td {
|
|
56
|
+
border-bottom: 1px solid ${CAP_G07};
|
|
57
|
+
}
|
|
58
|
+
|
|
59
|
+
.ant-table-tbody > tr:last-child > td {
|
|
60
|
+
border-bottom: none;
|
|
61
|
+
}
|
|
62
|
+
|
|
63
|
+
.ant-table-thead > tr.ant-table-row-hover:not(.ant-table-expanded-row) > td,
|
|
64
|
+
.ant-table-tbody > tr.ant-table-row-hover:not(.ant-table-expanded-row) > td,
|
|
65
|
+
.ant-table-thead > tr:hover:not(.ant-table-expanded-row) > td,
|
|
66
|
+
.ant-table-tbody > tr:hover:not(.ant-table-expanded-row) > td {
|
|
67
|
+
background-color: ${CAP_G09};
|
|
68
|
+
}
|
|
69
|
+
|
|
70
|
+
.ant-table-thead > tr > th .ant-table-column-sorter-up,
|
|
71
|
+
.ant-table-thead > tr > th .ant-table-column-sorter-down {
|
|
72
|
+
&.active {
|
|
73
|
+
color: ${CAP_G01};
|
|
74
|
+
}
|
|
75
|
+
&:not(.active) {
|
|
76
|
+
color: ${CAP_G06};
|
|
77
|
+
}
|
|
78
|
+
}
|
|
79
|
+
|
|
80
|
+
.ant-table-thead {
|
|
81
|
+
.table-children {
|
|
82
|
+
padding: 6px ${SPACING_24} 16px;
|
|
83
|
+
position: relative;
|
|
84
|
+
}
|
|
85
|
+
|
|
86
|
+
.table-parent {
|
|
87
|
+
padding-bottom: 0;
|
|
88
|
+
padding-left: ${SPACING_24};
|
|
89
|
+
}
|
|
90
|
+
|
|
91
|
+
.table-children.show-separator:not(:last-child)::after {
|
|
92
|
+
content: '';
|
|
93
|
+
height: 8px;
|
|
94
|
+
width: 1px;
|
|
95
|
+
right: 0;
|
|
96
|
+
top: 30%;
|
|
97
|
+
background-color: ${CAP_G07};
|
|
98
|
+
position: absolute;
|
|
99
|
+
}
|
|
100
|
+
}
|
|
101
|
+
|
|
102
|
+
.ant-table-thead > tr > th .ant-table-column-sorter {
|
|
103
|
+
vertical-align: unset;
|
|
104
|
+
}
|
|
105
|
+
|
|
106
|
+
.ant-table-body table {
|
|
107
|
+
table-layout: fixed;
|
|
108
|
+
width: 100%;
|
|
109
|
+
}
|
|
110
|
+
}
|
|
111
|
+
|
|
112
|
+
&.no-pagination-loader {
|
|
113
|
+
.ant-table-body > table > tbody::after {
|
|
114
|
+
content: '';
|
|
115
|
+
height: unset;
|
|
116
|
+
display: none;
|
|
117
|
+
}
|
|
118
|
+
}
|
|
119
|
+
|
|
120
|
+
&.hide-hover {
|
|
121
|
+
.ant-table {
|
|
122
|
+
.ant-table-thead > tr.ant-table-row-hover:not(.ant-table-expanded-row) > td,
|
|
123
|
+
.ant-table-tbody > tr.ant-table-row-hover:not(.ant-table-expanded-row) > td,
|
|
124
|
+
.ant-table-thead > tr:hover:not(.ant-table-expanded-row) > td,
|
|
125
|
+
.ant-table-tbody > tr:hover:not(.ant-table-expanded-row) > td {
|
|
126
|
+
background: none;
|
|
127
|
+
}
|
|
128
|
+
}
|
|
129
|
+
}
|
|
130
|
+
|
|
131
|
+
a {
|
|
132
|
+
color: ${CAP_G01};
|
|
133
|
+
}
|
|
134
|
+
`;
|
|
@@ -0,0 +1,47 @@
|
|
|
1
|
+
import React from 'react';
|
|
2
|
+
import PropTypes from 'prop-types';
|
|
3
|
+
import { Select } from 'antd';
|
|
4
|
+
|
|
5
|
+
/**
|
|
6
|
+
* Test component to verify Ant Design v5 Select integration
|
|
7
|
+
* This is a simple wrapper for testing purposes only
|
|
8
|
+
*/
|
|
9
|
+
const CapTestSelect = (props) => {
|
|
10
|
+
return <Select {...props} />;
|
|
11
|
+
};
|
|
12
|
+
|
|
13
|
+
CapTestSelect.propTypes = {
|
|
14
|
+
// Common Select props from antd
|
|
15
|
+
allowClear: PropTypes.bool,
|
|
16
|
+
defaultValue: PropTypes.oneOfType([
|
|
17
|
+
PropTypes.string,
|
|
18
|
+
PropTypes.number,
|
|
19
|
+
PropTypes.arrayOf(PropTypes.oneOfType([PropTypes.string, PropTypes.number]))
|
|
20
|
+
]),
|
|
21
|
+
disabled: PropTypes.bool,
|
|
22
|
+
loading: PropTypes.bool,
|
|
23
|
+
mode: PropTypes.oneOf(['multiple', 'tags']),
|
|
24
|
+
placeholder: PropTypes.string,
|
|
25
|
+
showSearch: PropTypes.bool,
|
|
26
|
+
value: PropTypes.oneOfType([
|
|
27
|
+
PropTypes.string,
|
|
28
|
+
PropTypes.number,
|
|
29
|
+
PropTypes.arrayOf(PropTypes.oneOfType([PropTypes.string, PropTypes.number]))
|
|
30
|
+
]),
|
|
31
|
+
options: PropTypes.arrayOf(
|
|
32
|
+
PropTypes.shape({
|
|
33
|
+
label: PropTypes.node,
|
|
34
|
+
value: PropTypes.oneOfType([PropTypes.string, PropTypes.number]),
|
|
35
|
+
disabled: PropTypes.bool
|
|
36
|
+
})
|
|
37
|
+
)
|
|
38
|
+
};
|
|
39
|
+
|
|
40
|
+
CapTestSelect.defaultProps = {
|
|
41
|
+
allowClear: false,
|
|
42
|
+
disabled: false,
|
|
43
|
+
loading: false,
|
|
44
|
+
showSearch: false
|
|
45
|
+
};
|
|
46
|
+
|
|
47
|
+
export default CapTestSelect;
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export { default } from './CapTestSelect';
|