@xaypay/tui 0.0.3 → 0.0.4
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/.idea/misc.xml +6 -0
- package/.idea/modules.xml +8 -0
- package/.idea/tui.iml +12 -0
- package/.idea/vcs.xml +6 -0
- package/.idea/workspace.xml +1755 -0
- package/.storybook/main.js +1 -1
- package/dist/index.es.js +866 -15
- package/dist/index.js +903 -14
- package/package.json +8 -4
- package/src/assets/heart-filled.svg +17 -0
- package/src/assets/heart-outline.svg +14 -0
- package/src/assets/like-filled.svg +21 -0
- package/src/assets/like-outline.svg +21 -0
- package/src/assets/star-filled.svg +21 -0
- package/src/assets/star-outline.svg +5 -0
- package/src/assets_old/icons/Read Me.txt +7 -0
- package/src/assets_old/icons/demo-files/demo.css +152 -0
- package/src/assets_old/icons/demo-files/demo.js +30 -0
- package/src/assets_old/icons/demo.html +150 -0
- package/src/assets_old/icons/fonts/icomoon.eot +0 -0
- package/src/assets_old/icons/fonts/icomoon.svg +18 -0
- package/src/assets_old/icons/fonts/icomoon.ttf +0 -0
- package/src/assets_old/icons/fonts/icomoon.woff +0 -0
- package/src/assets_old/icons/selection.json +1 -0
- package/src/assets_old/icons/style.css +51 -0
- package/src/components/autocomplate/autocomplate.module.css +74 -0
- package/src/components/autocomplate/autocomplate.stories.js +11 -0
- package/src/components/autocomplate/index.js +117 -0
- package/src/components/button/button.module.css +63 -1
- package/src/components/button/button.stories.js +10 -10
- package/src/components/button/index.js +12 -9
- package/src/components/captcha/blue.png +0 -0
- package/src/components/captcha/captcha.module.css +66 -0
- package/src/components/captcha/captcha.stories.js +17 -0
- package/src/components/captcha/green.png +0 -0
- package/src/components/captcha/index.js +63 -0
- package/src/components/captcha/red.png +0 -0
- package/src/components/checkbox/checkbox.module.css +57 -0
- package/src/components/checkbox/checkbox.stories.js +10 -0
- package/src/components/checkbox/index.js +87 -0
- package/src/components/icon/HeartFilled.js +26 -0
- package/src/components/icon/HeartOutline.js +25 -0
- package/src/components/icon/Icon.js +6 -0
- package/src/components/icon/LikeFilled.js +24 -0
- package/src/components/icon/LikeOutline.js +24 -0
- package/src/components/icon/StarFilled.js +24 -0
- package/src/components/icon/StarOutline.js +24 -0
- package/src/components/icon/index.js +6 -0
- package/src/components/input/index.js +90 -0
- package/src/components/input/input.module.css +89 -0
- package/src/components/input/input.stories.js +38 -0
- package/src/components/modal/index.js +24 -0
- package/src/components/modal/modal.module.css +35 -0
- package/src/components/modal/modal.stories.js +29 -0
- package/src/components/multiselect/index.js +76 -0
- package/src/components/multiselect/multiselect.module.css +137 -0
- package/src/components/multiselect/multiselect.stories.js +19 -0
- package/src/components/pagination/index.js +119 -0
- package/src/components/pagination/pagination.module.css +80 -0
- package/src/components/pagination/pagination.stories.js +371 -0
- package/src/components/pagination/paginationRange.js +70 -0
- package/src/components/radio/index.js +68 -0
- package/src/components/radio/radio.module.css +59 -0
- package/src/components/radio/radio.stories.js +10 -0
- package/src/components/select/index.js +130 -0
- package/src/components/select/select.module.css +100 -0
- package/src/components/select/select.stories.js +21 -0
- package/src/components/typography/index.js +53 -0
- package/src/components/typography/typography.module.css +60 -0
- package/src/components/typography/typography.stories.js +29 -0
- package/src/index.js +10 -1
- package/storybook-static/favicon.ico +0 -0
|
@@ -0,0 +1,74 @@
|
|
|
1
|
+
.autocomplate-content {
|
|
2
|
+
display: flex;
|
|
3
|
+
flex-direction: column;
|
|
4
|
+
}
|
|
5
|
+
.autocomplate-content-top {
|
|
6
|
+
display: flex;
|
|
7
|
+
flex-direction: row;
|
|
8
|
+
max-width: 400px;
|
|
9
|
+
height: 46px;
|
|
10
|
+
padding: 0 15px;
|
|
11
|
+
font-size: 16px;
|
|
12
|
+
color: #3C393E;
|
|
13
|
+
line-height: 22px;
|
|
14
|
+
font-weight: 500;
|
|
15
|
+
border: 2px solid #D1D1D1;
|
|
16
|
+
border-radius: 6px;
|
|
17
|
+
transition: border-color 240ms;
|
|
18
|
+
box-sizing: border-box;
|
|
19
|
+
cursor: pointer;
|
|
20
|
+
}
|
|
21
|
+
.autocomplate-content-top.active {
|
|
22
|
+
border-color: #00236A;
|
|
23
|
+
}
|
|
24
|
+
.autocomplate-content-top:hover {
|
|
25
|
+
border-color: #3C393E;
|
|
26
|
+
}
|
|
27
|
+
.autocomplate-content-bottom {
|
|
28
|
+
position: relative;
|
|
29
|
+
top: 6px;
|
|
30
|
+
overflow: hidden;
|
|
31
|
+
max-width: 400px;
|
|
32
|
+
background: #FBFBFB;
|
|
33
|
+
box-shadow: 0 0 10px rgba(60, 57, 62, 0.08);
|
|
34
|
+
border-radius: 6px;
|
|
35
|
+
animation: select-show 640ms linear forwards;
|
|
36
|
+
max-height: 0;
|
|
37
|
+
}
|
|
38
|
+
.autocomplate-content-bottom-inner {
|
|
39
|
+
display: flex;
|
|
40
|
+
flex-direction: column;
|
|
41
|
+
overflow-y: auto;
|
|
42
|
+
overflow-x: hidden;
|
|
43
|
+
max-height: 234px;
|
|
44
|
+
}
|
|
45
|
+
@keyframes select-show {
|
|
46
|
+
100% {
|
|
47
|
+
max-height: 400px;
|
|
48
|
+
}
|
|
49
|
+
}
|
|
50
|
+
.autocomplate-content-bottom-row {
|
|
51
|
+
display: flex;
|
|
52
|
+
align-items: center;
|
|
53
|
+
background: #ffffff;
|
|
54
|
+
padding: 0 15px;
|
|
55
|
+
height: 46px;
|
|
56
|
+
font-size: 16px;
|
|
57
|
+
color: #3C393E;
|
|
58
|
+
line-height: 22px;
|
|
59
|
+
font-weight: 500;
|
|
60
|
+
margin-bottom: 2px;
|
|
61
|
+
box-sizing: border-box;
|
|
62
|
+
transition: background 240ms, color 240ms;
|
|
63
|
+
cursor: pointer;
|
|
64
|
+
}
|
|
65
|
+
.autocomplate-content-bottom-row .no-option {
|
|
66
|
+
color: #ff0000;
|
|
67
|
+
}
|
|
68
|
+
.autocomplate-content-bottom-row:hover {
|
|
69
|
+
background: unset;
|
|
70
|
+
color: #00236A;
|
|
71
|
+
}
|
|
72
|
+
.option-active .autocomplate-content-bottom-row {
|
|
73
|
+
color: #00236A;
|
|
74
|
+
}
|
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
import React from "react";
|
|
2
|
+
import { Autocomplate } from "./index";
|
|
3
|
+
|
|
4
|
+
export default {
|
|
5
|
+
component: Autocomplate,
|
|
6
|
+
title: "Components/Autocomplate",
|
|
7
|
+
};
|
|
8
|
+
|
|
9
|
+
const Template = (args) => <Autocomplate {...args} />;
|
|
10
|
+
|
|
11
|
+
export const Default = Template.bind({});
|
|
@@ -0,0 +1,117 @@
|
|
|
1
|
+
import React, { useState } from "react";
|
|
2
|
+
import PropTypes from "prop-types";
|
|
3
|
+
import classnames from "classnames";
|
|
4
|
+
import styles from "./autocomplate.module.css";
|
|
5
|
+
|
|
6
|
+
export const Autocomplate = ({
|
|
7
|
+
className,
|
|
8
|
+
label,
|
|
9
|
+
required,
|
|
10
|
+
disabled,
|
|
11
|
+
jsonOptionsData,
|
|
12
|
+
onChange,
|
|
13
|
+
value,
|
|
14
|
+
searchCount,
|
|
15
|
+
...props
|
|
16
|
+
}) => {
|
|
17
|
+
const classProps = classnames(styles.searchBox, className);
|
|
18
|
+
const [inputValue, setInputValue] = useState("");
|
|
19
|
+
const [activeOption, setActiveOption] = useState(0);
|
|
20
|
+
const [filteredOptions, setFilteredOptions] = useState([]);
|
|
21
|
+
const [showOptions, setShowOptions] = useState(false);
|
|
22
|
+
|
|
23
|
+
const parseOptionsData =
|
|
24
|
+
jsonOptionsData.length !== 0 ? JSON.parse(jsonOptionsData).sort() : [];
|
|
25
|
+
const handleChange = (e) => {
|
|
26
|
+
const currentInputValue = e.currentTarget.value;
|
|
27
|
+
|
|
28
|
+
const filteredOptions = parseOptionsData.filter(
|
|
29
|
+
(optionName) =>
|
|
30
|
+
optionName.toLowerCase().indexOf(currentInputValue.toLowerCase()) > -1
|
|
31
|
+
);
|
|
32
|
+
|
|
33
|
+
setInputValue(currentInputValue);
|
|
34
|
+
setActiveOption(0);
|
|
35
|
+
setFilteredOptions(filteredOptions);
|
|
36
|
+
setShowOptions(true);
|
|
37
|
+
};
|
|
38
|
+
const handleClick = (e) => {
|
|
39
|
+
setInputValue(e.currentTarget.innerText);
|
|
40
|
+
setActiveOption(0);
|
|
41
|
+
setFilteredOptions([]);
|
|
42
|
+
setShowOptions(false);
|
|
43
|
+
};
|
|
44
|
+
let optionList;
|
|
45
|
+
if (showOptions && inputValue) {
|
|
46
|
+
if (filteredOptions.length && inputValue.length >= searchCount) {
|
|
47
|
+
optionList = (
|
|
48
|
+
<div className={styles['autocomplate-content-bottom']}>
|
|
49
|
+
<div className={styles['autocomplate-content-bottom-inner']}>
|
|
50
|
+
{filteredOptions.map((optionName, index) => {
|
|
51
|
+
let className;
|
|
52
|
+
if (index === activeOption) {
|
|
53
|
+
className = "option-active";
|
|
54
|
+
}
|
|
55
|
+
return (
|
|
56
|
+
<div
|
|
57
|
+
className={styles[className]}
|
|
58
|
+
key={optionName}
|
|
59
|
+
onClick={handleClick}
|
|
60
|
+
>
|
|
61
|
+
<div className={styles['autocomplate-content-bottom-row']}>{optionName}</div>
|
|
62
|
+
</div>
|
|
63
|
+
);
|
|
64
|
+
})}
|
|
65
|
+
</div>
|
|
66
|
+
</div>
|
|
67
|
+
|
|
68
|
+
|
|
69
|
+
);
|
|
70
|
+
} else {
|
|
71
|
+
optionList = (
|
|
72
|
+
<div className={styles['autocomplate-content-bottom']}>
|
|
73
|
+
<div className={styles['autocomplate-content-bottom-inner']}>
|
|
74
|
+
<div className={styles['autocomplate-content-bottom-row']}>
|
|
75
|
+
<div className={styles['no-option']}>No Option!</div>
|
|
76
|
+
</div>
|
|
77
|
+
</div>
|
|
78
|
+
</div>
|
|
79
|
+
);
|
|
80
|
+
}
|
|
81
|
+
}
|
|
82
|
+
|
|
83
|
+
return (
|
|
84
|
+
<>
|
|
85
|
+
{label ? <label className={styles.labelInput}>{label}</label> : ""}
|
|
86
|
+
<div className={styles['autocomplate-content']}>
|
|
87
|
+
<input
|
|
88
|
+
type="text"
|
|
89
|
+
className={styles['autocomplate-content-top']}
|
|
90
|
+
required={required}
|
|
91
|
+
disabled={disabled}
|
|
92
|
+
onChange={handleChange}
|
|
93
|
+
value={inputValue}
|
|
94
|
+
placeholder="Write..."
|
|
95
|
+
{...props}
|
|
96
|
+
/>
|
|
97
|
+
{optionList}
|
|
98
|
+
</div>
|
|
99
|
+
</>
|
|
100
|
+
);
|
|
101
|
+
};
|
|
102
|
+
|
|
103
|
+
Autocomplate.propTypes = {
|
|
104
|
+
className: PropTypes.string,
|
|
105
|
+
label: PropTypes.string,
|
|
106
|
+
required: PropTypes.bool,
|
|
107
|
+
disabled: PropTypes.bool,
|
|
108
|
+
jsonOptionsData: PropTypes.string,
|
|
109
|
+
onChange: PropTypes.func,
|
|
110
|
+
value: PropTypes.string,
|
|
111
|
+
searchCount: PropTypes.number,
|
|
112
|
+
};
|
|
113
|
+
|
|
114
|
+
Autocomplate.defaultProps = {
|
|
115
|
+
jsonOptionsData: '["Tigran", "Tigran Aleksanyan", "Tigarn Aleksanyan Yerevan"]',
|
|
116
|
+
searchCount: 2,
|
|
117
|
+
};
|
|
@@ -1,3 +1,65 @@
|
|
|
1
1
|
.btn {
|
|
2
|
-
|
|
2
|
+
text-transform: capitalize;
|
|
3
|
+
font-size: 16px;
|
|
4
|
+
line-height: 20px;
|
|
5
|
+
padding: 12px 20px;
|
|
6
|
+
border-radius: 6px;
|
|
7
|
+
border: none;
|
|
8
|
+
outline: none;
|
|
9
|
+
box-sizing: border-box;
|
|
10
|
+
transition: background-color 240ms, color 240ms;
|
|
11
|
+
overflow: hidden;
|
|
12
|
+
cursor: pointer;
|
|
13
|
+
min-height: 46px;
|
|
14
|
+
}
|
|
15
|
+
|
|
16
|
+
.btn.full-size {
|
|
17
|
+
width: 100%;
|
|
18
|
+
}
|
|
19
|
+
|
|
20
|
+
.btn.content-size {
|
|
21
|
+
width: auto;
|
|
22
|
+
}
|
|
23
|
+
|
|
24
|
+
.btn.size-default {
|
|
25
|
+
|
|
26
|
+
}
|
|
27
|
+
|
|
28
|
+
.btn.type-filled {
|
|
29
|
+
background-color: rgba(0, 35, 106, 1);
|
|
30
|
+
color: rgba(255, 255, 255, 1);
|
|
31
|
+
}
|
|
32
|
+
|
|
33
|
+
.btn.type-filled:hover {
|
|
34
|
+
background-color: rgba(0, 23, 69, 1);
|
|
35
|
+
}
|
|
36
|
+
|
|
37
|
+
.btn.type-filled:disabled {
|
|
38
|
+
background-color: rgba(238, 238, 238, 1);
|
|
39
|
+
color: rgba(60, 57, 62, 1);
|
|
40
|
+
pointer-events: none;
|
|
41
|
+
}
|
|
42
|
+
|
|
43
|
+
.btn.type-filled.with-icon {
|
|
44
|
+
|
|
45
|
+
}
|
|
46
|
+
|
|
47
|
+
.btn.type-outline {
|
|
48
|
+
background-color: rgba(255, 255, 255, 1);
|
|
49
|
+
box-shadow: 0 0 0 2px rgba(0, 35, 106, 1) inset;
|
|
50
|
+
}
|
|
51
|
+
|
|
52
|
+
.btn.type-outline:hover {
|
|
53
|
+
color: rgba(255, 255, 255, 1);
|
|
54
|
+
background-color: rgba(0, 23, 69, 1);
|
|
55
|
+
}
|
|
56
|
+
|
|
57
|
+
.btn.type-outline:disabled {
|
|
58
|
+
color: rgba(60, 57, 62, 1);
|
|
59
|
+
box-shadow: 0 0 0 2px rgba(238, 238, 238, 1) inset;
|
|
60
|
+
pointer-events: none;
|
|
61
|
+
}
|
|
62
|
+
|
|
63
|
+
.btn.type-outline.with-icon {
|
|
64
|
+
|
|
3
65
|
}
|
|
@@ -2,31 +2,31 @@ import React from 'react';
|
|
|
2
2
|
import {Button, ButtonSize, ButtonTheme} from './index';
|
|
3
3
|
|
|
4
4
|
export default {
|
|
5
|
-
|
|
6
|
-
|
|
5
|
+
component: Button,
|
|
6
|
+
title: 'Components/Button',
|
|
7
7
|
};
|
|
8
8
|
|
|
9
|
-
const Template = (args) => <Button label='Button'
|
|
9
|
+
const Template = (args) => <Button label='Button' {...args} > Default</Button>;
|
|
10
10
|
|
|
11
11
|
export const Default = Template.bind({});
|
|
12
12
|
Default.args = {
|
|
13
|
-
|
|
13
|
+
theme: ButtonTheme.DEFAULT,
|
|
14
14
|
};
|
|
15
15
|
|
|
16
16
|
export const Primary = Template.bind({});
|
|
17
17
|
Primary.args = {
|
|
18
|
-
|
|
18
|
+
theme: ButtonTheme.PRIMARY,
|
|
19
19
|
};
|
|
20
20
|
|
|
21
21
|
export const Large = Template.bind({});
|
|
22
22
|
Large.args = {
|
|
23
|
-
|
|
24
|
-
|
|
23
|
+
size: ButtonSize.LARGE,
|
|
24
|
+
theme: ButtonTheme.DEFAULT,
|
|
25
25
|
};
|
|
26
26
|
|
|
27
27
|
export const Small = Template.bind({});
|
|
28
28
|
Small.args = {
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
29
|
+
size: ButtonSize.SMALL,
|
|
30
|
+
backgroundColor: '#ff0000',
|
|
31
|
+
theme: ButtonTheme.DEFAULT,
|
|
32
32
|
};
|
|
@@ -14,39 +14,40 @@ export const ButtonType = {
|
|
|
14
14
|
};
|
|
15
15
|
|
|
16
16
|
export const ButtonTheme = {
|
|
17
|
-
DEFAULT: '
|
|
18
|
-
PRIMARY: '
|
|
17
|
+
DEFAULT: 'content-size',
|
|
18
|
+
PRIMARY: 'full-size',
|
|
19
19
|
SUCCESS: 'btn-success',
|
|
20
20
|
INFO: 'btn-info',
|
|
21
21
|
WARNING: 'btn-warning',
|
|
22
22
|
DANGER: 'btn-danger',
|
|
23
|
-
LINK: 'btn-link'
|
|
23
|
+
LINK: 'btn-link',
|
|
24
24
|
};
|
|
25
25
|
|
|
26
26
|
export const ButtonSize = {
|
|
27
27
|
SMALL: 'small',
|
|
28
28
|
MEDIUM: 'medium',
|
|
29
|
-
LARGE: 'large'
|
|
29
|
+
LARGE: 'large',
|
|
30
30
|
};
|
|
31
31
|
|
|
32
|
-
export const Button = ({ primary, backgroundColor, theme, size, className, disabled, label, ...props }) => {
|
|
32
|
+
export const Button = ({ primary, backgroundColor, theme, size, className, disabled, label, outline, ...props }) => {
|
|
33
33
|
|
|
34
34
|
console.log(styles);
|
|
35
|
+
console.log(backgroundColor);
|
|
35
36
|
const classProps = classnames(
|
|
36
37
|
styles.btn,
|
|
37
38
|
styles[theme],
|
|
38
39
|
styles[size],
|
|
39
|
-
'
|
|
40
|
-
{
|
|
41
|
-
[styles.disabled]: disabled,
|
|
42
|
-
},
|
|
40
|
+
outline ? styles['type-outline'] : styles['type-filled'],
|
|
43
41
|
className
|
|
44
42
|
);
|
|
43
|
+
// className='btn type-outline size-default'
|
|
44
|
+
console.log(classProps);
|
|
45
45
|
return (
|
|
46
46
|
<button
|
|
47
47
|
type="button"
|
|
48
48
|
className={classProps}
|
|
49
49
|
style={backgroundColor && { backgroundColor }}
|
|
50
|
+
disabled={disabled ? 'disabled': ''}
|
|
50
51
|
{...props}
|
|
51
52
|
>
|
|
52
53
|
{label}
|
|
@@ -80,6 +81,7 @@ Button.propTypes = {
|
|
|
80
81
|
*/
|
|
81
82
|
disabled: PropTypes.bool,
|
|
82
83
|
className: PropTypes.string,
|
|
84
|
+
outline: PropTypes.bool,
|
|
83
85
|
};
|
|
84
86
|
|
|
85
87
|
Button.defaultProps = {
|
|
@@ -87,4 +89,5 @@ Button.defaultProps = {
|
|
|
87
89
|
primary: false,
|
|
88
90
|
size: 'medium',
|
|
89
91
|
onClick: undefined,
|
|
92
|
+
outline: false,
|
|
90
93
|
};
|
|
Binary file
|
|
@@ -0,0 +1,66 @@
|
|
|
1
|
+
* {
|
|
2
|
+
margin: 0;
|
|
3
|
+
padding: 0;
|
|
4
|
+
}
|
|
5
|
+
|
|
6
|
+
.main {
|
|
7
|
+
width: 40%;
|
|
8
|
+
position: relative;
|
|
9
|
+
margin: 0;
|
|
10
|
+
padding: 0;
|
|
11
|
+
}
|
|
12
|
+
|
|
13
|
+
.slider {
|
|
14
|
+
-webkit-appearance: none;
|
|
15
|
+
width: 100%;
|
|
16
|
+
height: 7px;
|
|
17
|
+
outline: none;
|
|
18
|
+
border: 0.1px solid rgba(150, 149, 149, 0.432);
|
|
19
|
+
background-color: rgba(255, 255, 255, 0.575);
|
|
20
|
+
}
|
|
21
|
+
|
|
22
|
+
.slider::-webkit-slider-thumb {
|
|
23
|
+
-webkit-appearance: none;
|
|
24
|
+
width: 48px;
|
|
25
|
+
height: 48px;
|
|
26
|
+
z-index: 3;
|
|
27
|
+
position: relative;
|
|
28
|
+
}
|
|
29
|
+
|
|
30
|
+
.selector {
|
|
31
|
+
height: 48px;
|
|
32
|
+
width: 48px;
|
|
33
|
+
position: absolute;
|
|
34
|
+
bottom: -20px;
|
|
35
|
+
left: 50%;
|
|
36
|
+
z-index: 2;
|
|
37
|
+
}
|
|
38
|
+
|
|
39
|
+
.selectBtn {
|
|
40
|
+
height: 40px;
|
|
41
|
+
width: 40px;
|
|
42
|
+
background-image: url('https://i.ibb.co/rQZNNzN/blue.png');
|
|
43
|
+
background-size: cover;
|
|
44
|
+
background-position: center;
|
|
45
|
+
border-radius: 50%;
|
|
46
|
+
position: absolute;
|
|
47
|
+
bottom: 40px;
|
|
48
|
+
right: 30px;
|
|
49
|
+
}
|
|
50
|
+
|
|
51
|
+
.progressBar {
|
|
52
|
+
width: 50%;
|
|
53
|
+
height: 7px;
|
|
54
|
+
background: rgb(112, 112, 238);
|
|
55
|
+
position: absolute;
|
|
56
|
+
bottom: 38px;
|
|
57
|
+
left: 0;
|
|
58
|
+
margin: 0;
|
|
59
|
+
padding: 0;
|
|
60
|
+
}
|
|
61
|
+
|
|
62
|
+
.range {
|
|
63
|
+
color: blue;
|
|
64
|
+
margin-bottom: 15px;
|
|
65
|
+
margin-top: 15px;
|
|
66
|
+
}
|
|
@@ -0,0 +1,17 @@
|
|
|
1
|
+
import React from 'react';
|
|
2
|
+
import { Captcha, ButtonTheme } from './index';
|
|
3
|
+
|
|
4
|
+
export default {
|
|
5
|
+
component: Captcha,
|
|
6
|
+
title: 'Components/Captcha',
|
|
7
|
+
};
|
|
8
|
+
|
|
9
|
+
const Template = (args) => <Captcha className='captcha type-outline size-default' label='Captcha' {...args} > Default</Captcha>;
|
|
10
|
+
|
|
11
|
+
export const Default = Template.bind({});
|
|
12
|
+
Default.args = {
|
|
13
|
+
rangeCount: 20,
|
|
14
|
+
onclick: (e) => {
|
|
15
|
+
console.log(e.target.value);
|
|
16
|
+
}
|
|
17
|
+
};
|
|
Binary file
|
|
@@ -0,0 +1,63 @@
|
|
|
1
|
+
import React, { useEffect, useState } from 'react';
|
|
2
|
+
import PropTypes from 'prop-types';
|
|
3
|
+
import styles from './captcha.module.css';
|
|
4
|
+
|
|
5
|
+
|
|
6
|
+
export const Captcha = ({ onclick, rangeCount }) => {
|
|
7
|
+
const [data, setData] = useState("");
|
|
8
|
+
const [right, setRight] = useState(false);
|
|
9
|
+
let range = rangeCount <= 100 ? rangeCount : 0;
|
|
10
|
+
let rangeElement = document.getElementsByClassName(styles.range);
|
|
11
|
+
useEffect(() => {
|
|
12
|
+
for (let element of rangeElement) {
|
|
13
|
+
element.style.marginLeft = `${range - 3}%`;
|
|
14
|
+
element.style.color = data;
|
|
15
|
+
}
|
|
16
|
+
}, [range, data])
|
|
17
|
+
|
|
18
|
+
function sliderInput(event) {
|
|
19
|
+
setData(rangeCount == event.target.value ? 'green' : 'indianred');
|
|
20
|
+
let selector = document.getElementsByClassName(styles.selector);
|
|
21
|
+
let selectBtn = document.getElementsByClassName(styles.selectBtn);
|
|
22
|
+
let progressBar = document.getElementsByClassName(styles.progressBar);
|
|
23
|
+
|
|
24
|
+
selector[0].style.left = event.target.value + '%';
|
|
25
|
+
progressBar[0].style.width = event.target.value + '%';
|
|
26
|
+
|
|
27
|
+
if (rangeCount == event.target.value) {
|
|
28
|
+
selectBtn[0].style.backgroundImage = "url('https://i.ibb.co/b1HDRtd/green.png')";
|
|
29
|
+
}
|
|
30
|
+
else {
|
|
31
|
+
selectBtn[0].style.backgroundImage = "url('https://i.ibb.co/QvXjjLM/red.png')";
|
|
32
|
+
}
|
|
33
|
+
}
|
|
34
|
+
|
|
35
|
+
function sliderChange(e) {
|
|
36
|
+
setRight(rangeCount == e.target.value ? true : false);
|
|
37
|
+
}
|
|
38
|
+
|
|
39
|
+
return (
|
|
40
|
+
<>
|
|
41
|
+
<div className={styles.main}>
|
|
42
|
+
<div className={styles.range}>▼</div>
|
|
43
|
+
<input type='range' className={styles.slider} onClick={right ? onclick : null} onInput={sliderInput} onMouseUp={sliderChange} />
|
|
44
|
+
<div className={styles.selector} >
|
|
45
|
+
<div className={styles.selectBtn}></div>
|
|
46
|
+
</div>
|
|
47
|
+
<div className={styles.progressBar}></div>
|
|
48
|
+
<div className={styles.range} >▲</div>
|
|
49
|
+
</div>
|
|
50
|
+
|
|
51
|
+
</>
|
|
52
|
+
);
|
|
53
|
+
};
|
|
54
|
+
|
|
55
|
+
Captcha.propTypes = {
|
|
56
|
+
onclick: PropTypes.func,
|
|
57
|
+
className: PropTypes.string,
|
|
58
|
+
rangeCount: PropTypes.number
|
|
59
|
+
};
|
|
60
|
+
|
|
61
|
+
Captcha.defaultProps = {
|
|
62
|
+
onclick: undefined
|
|
63
|
+
};
|
|
Binary file
|
|
@@ -0,0 +1,57 @@
|
|
|
1
|
+
.checkbox-wrap {
|
|
2
|
+
position: relative;
|
|
3
|
+
display: inline-flex;
|
|
4
|
+
flex-direction: row;
|
|
5
|
+
flex-wrap: nowrap;
|
|
6
|
+
align-items: center;
|
|
7
|
+
margin: 0 6px;
|
|
8
|
+
padding-left: 24px;
|
|
9
|
+
cursor: pointer;
|
|
10
|
+
}
|
|
11
|
+
.checkbox-wrap > input {
|
|
12
|
+
position: absolute;
|
|
13
|
+
opacity: 0;
|
|
14
|
+
height: 0;
|
|
15
|
+
width: 0;
|
|
16
|
+
}
|
|
17
|
+
|
|
18
|
+
.checkbox-wrap .checkmark {
|
|
19
|
+
position: absolute;
|
|
20
|
+
top: 0;
|
|
21
|
+
left: 0;
|
|
22
|
+
display: inline-block;
|
|
23
|
+
vertical-align: top;
|
|
24
|
+
width: 14px;
|
|
25
|
+
height: 14px;
|
|
26
|
+
border: 1px solid #d9d9d9;
|
|
27
|
+
border-radius: 3px;
|
|
28
|
+
margin-right: 4px;
|
|
29
|
+
transition: border-color 240ms;
|
|
30
|
+
}
|
|
31
|
+
|
|
32
|
+
.checkbox-wrap > .checkmark:after {
|
|
33
|
+
position: absolute;
|
|
34
|
+
content: '';
|
|
35
|
+
display: block;
|
|
36
|
+
left: 4px;
|
|
37
|
+
top: 1px;
|
|
38
|
+
width: 4px;
|
|
39
|
+
height: 8px;
|
|
40
|
+
border: solid #1890ff;
|
|
41
|
+
border-width: 0 2px 2px 0;
|
|
42
|
+
transform: rotate(45deg);
|
|
43
|
+
opacity: 0;
|
|
44
|
+
transition: opacity 240ms;
|
|
45
|
+
}
|
|
46
|
+
|
|
47
|
+
.checkbox-wrap input:checked ~ .checkmark:after {
|
|
48
|
+
opacity: 1;
|
|
49
|
+
}
|
|
50
|
+
|
|
51
|
+
.checkbox-wrap input:checked ~ .checkmark {
|
|
52
|
+
border-color: #1890ff;
|
|
53
|
+
}
|
|
54
|
+
|
|
55
|
+
.checkbox-wrap:hover input ~ .checkmark {
|
|
56
|
+
border-color: #1890ff;
|
|
57
|
+
}
|
|
@@ -0,0 +1,87 @@
|
|
|
1
|
+
import React, { useState } from "react";
|
|
2
|
+
import PropTypes from "prop-types";
|
|
3
|
+
import classNames from "classnames";
|
|
4
|
+
import styles from "./checkbox.module.css";
|
|
5
|
+
|
|
6
|
+
export const Checkbox = ({
|
|
7
|
+
disabled,
|
|
8
|
+
required,
|
|
9
|
+
className,
|
|
10
|
+
name,
|
|
11
|
+
value,
|
|
12
|
+
jsonData,
|
|
13
|
+
onChange,
|
|
14
|
+
label,
|
|
15
|
+
keyNames,
|
|
16
|
+
...props
|
|
17
|
+
}) => {
|
|
18
|
+
const classProps = classNames(styles.checkbox, className);
|
|
19
|
+
const parseData = jsonData.length !== 0 ? JSON.parse(jsonData) : [];
|
|
20
|
+
const [data, setData] = useState(parseData);
|
|
21
|
+
|
|
22
|
+
const handleChange = (e) => {
|
|
23
|
+
if (e.target.checked) {
|
|
24
|
+
data.forEach((item) => {
|
|
25
|
+
if (item.value === e.target.value) {
|
|
26
|
+
item.checked = true;
|
|
27
|
+
setData([...data]);
|
|
28
|
+
}
|
|
29
|
+
});
|
|
30
|
+
} else if (e.target.checked === false) {
|
|
31
|
+
data.forEach((item) => {
|
|
32
|
+
if (item.checked && item.value === e.target.value) {
|
|
33
|
+
delete item.checked;
|
|
34
|
+
setData([...data]);
|
|
35
|
+
}
|
|
36
|
+
});
|
|
37
|
+
}
|
|
38
|
+
};
|
|
39
|
+
|
|
40
|
+
return (
|
|
41
|
+
<>
|
|
42
|
+
{data.map((element) => {
|
|
43
|
+
return (
|
|
44
|
+
<label className={styles["checkbox-wrap"]} key={element.value}>
|
|
45
|
+
<input
|
|
46
|
+
type="checkbox"
|
|
47
|
+
className={classProps}
|
|
48
|
+
disabled={disabled}
|
|
49
|
+
required={required}
|
|
50
|
+
value={value ? value : element.value}
|
|
51
|
+
name={name ? name : element.name}
|
|
52
|
+
onChange={handleChange}
|
|
53
|
+
{...props}
|
|
54
|
+
/>
|
|
55
|
+
<span className={styles["checkmark"]}/>
|
|
56
|
+
{element.label ? (
|
|
57
|
+
<span className={styles.labelRadio}>
|
|
58
|
+
{label ? label : element.label}
|
|
59
|
+
</span>
|
|
60
|
+
) : (
|
|
61
|
+
""
|
|
62
|
+
)}
|
|
63
|
+
</label>
|
|
64
|
+
);
|
|
65
|
+
})}
|
|
66
|
+
</>
|
|
67
|
+
);
|
|
68
|
+
};
|
|
69
|
+
|
|
70
|
+
Checkbox.propTypes = {
|
|
71
|
+
className: PropTypes.string,
|
|
72
|
+
onChange: PropTypes.func,
|
|
73
|
+
required: PropTypes.bool,
|
|
74
|
+
disabled: PropTypes.bool,
|
|
75
|
+
name: PropTypes.string,
|
|
76
|
+
value: PropTypes.string,
|
|
77
|
+
jsonData: PropTypes.string,
|
|
78
|
+
label: PropTypes.string,
|
|
79
|
+
onChange: PropTypes.func,
|
|
80
|
+
keyNames: PropTypes.object,
|
|
81
|
+
};
|
|
82
|
+
|
|
83
|
+
Checkbox.defaultProps = {
|
|
84
|
+
onChange: undefined,
|
|
85
|
+
jsonData:
|
|
86
|
+
'[{"value":"email", "name":"contact1", "label":"Email", "id":"contactChoice1"}, {"value":"phone", "name":"contact2", "label":"Phone", "id":"contactChoice2"}]',
|
|
87
|
+
};
|