wini-web-components 0.3.1 → 0.4.0
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/dist/index.js +1 -0
- package/package.json +23 -14
- package/src/component/calendar/calendar.css +0 -133
- package/src/component/calendar/calendar.tsx +0 -448
- package/src/component/checkbox/checkbox.css +0 -46
- package/src/component/checkbox/checkbox.tsx +0 -59
- package/src/component/component-status.tsx +0 -53
- package/src/component/date-picker/date-picker.css +0 -114
- package/src/component/date-picker/date-picker.tsx +0 -363
- package/src/component/dialog/dialog.css +0 -125
- package/src/component/dialog/dialog.tsx +0 -91
- package/src/component/import-file/import-file.css +0 -86
- package/src/component/import-file/import-file.tsx +0 -154
- package/src/component/infinite-scroll/infinite-scroll.css +0 -37
- package/src/component/infinite-scroll/infinite-scroll.tsx +0 -33
- package/src/component/input-multi-select/input-multi-select.css +0 -127
- package/src/component/input-multi-select/input-multi-select.tsx +0 -261
- package/src/component/pagination/pagination.css +0 -69
- package/src/component/pagination/pagination.tsx +0 -65
- package/src/component/popup/popup.css +0 -90
- package/src/component/popup/popup.tsx +0 -105
- package/src/component/progress-bar/progress-bar.css +0 -47
- package/src/component/progress-bar/progress-bar.tsx +0 -34
- package/src/component/progress-circle/progress-circle.css +0 -47
- package/src/component/progress-circle/progress-circle.tsx +0 -24
- package/src/component/radio-button/radio-button.css +0 -49
- package/src/component/radio-button/radio-button.tsx +0 -59
- package/src/component/rating/rating.css +0 -11
- package/src/component/rating/rating.tsx +0 -65
- package/src/component/select1/select1.css +0 -155
- package/src/component/select1/select1.tsx +0 -241
- package/src/component/slider/slider.css +0 -16
- package/src/component/slider/slider.tsx +0 -87
- package/src/component/switch/switch.css +0 -53
- package/src/component/switch/switch.tsx +0 -67
- package/src/component/table/table.css +0 -74
- package/src/component/table/table.tsx +0 -99
- package/src/component/text/text.css +0 -16
- package/src/component/text/text.tsx +0 -21
- package/src/component/text-area/text-area.css +0 -63
- package/src/component/text-area/text-area.tsx +0 -55
- package/src/component/text-field/text-field.css +0 -64
- package/src/component/text-field/text-field.tsx +0 -63
- package/src/component/toast-noti/toast-noti.css +0 -0
- package/src/component/toast-noti/toast-noti.tsx +0 -21
- package/src/index.js +0 -51
- package/src/logo.svg +0 -1
- package/src/skin/color.css +0 -17
- package/src/skin/layout.css +0 -601
- package/src/skin/typography.css +0 -378
- package/webpack.config.js +0 -25
|
@@ -1,59 +0,0 @@
|
|
|
1
|
-
import React, { CSSProperties } from 'react';
|
|
2
|
-
import './checkbox.css';
|
|
3
|
-
|
|
4
|
-
interface CheckboxProps {
|
|
5
|
-
onChange?: (value: boolean) => void,
|
|
6
|
-
value?: boolean,
|
|
7
|
-
checkColor?: string,
|
|
8
|
-
disabled?: false,
|
|
9
|
-
style?: CSSProperties,
|
|
10
|
-
/** default 2.4rem **/
|
|
11
|
-
size?: number | string,
|
|
12
|
-
}
|
|
13
|
-
|
|
14
|
-
interface CheckboxState {
|
|
15
|
-
value?: boolean,
|
|
16
|
-
}
|
|
17
|
-
|
|
18
|
-
export class Checkbox extends React.Component<CheckboxProps, CheckboxState> {
|
|
19
|
-
state: Readonly<CheckboxState> = {
|
|
20
|
-
value: this.props.value ?? false
|
|
21
|
-
}
|
|
22
|
-
|
|
23
|
-
componentDidUpdate(prevProps: Readonly<CheckboxProps>): void {
|
|
24
|
-
if (prevProps.value !== this.props.value) {
|
|
25
|
-
this.setState({ value: this.props.value })
|
|
26
|
-
}
|
|
27
|
-
}
|
|
28
|
-
|
|
29
|
-
render() {
|
|
30
|
-
let convertStyle: CSSProperties = {
|
|
31
|
-
width: this.props.size ?? '2.4rem',
|
|
32
|
-
height: this.props.size ?? '2.4rem',
|
|
33
|
-
}
|
|
34
|
-
if (this.props.style) {
|
|
35
|
-
delete this.props.style.width
|
|
36
|
-
delete this.props.style.minWidth
|
|
37
|
-
delete this.props.style.maxWidth
|
|
38
|
-
delete this.props.style.height
|
|
39
|
-
delete this.props.style.minHeight
|
|
40
|
-
delete this.props.style.maxHeight
|
|
41
|
-
convertStyle = {
|
|
42
|
-
...this.props.style,
|
|
43
|
-
...convertStyle
|
|
44
|
-
}
|
|
45
|
-
}
|
|
46
|
-
return <label className="checkbox-container row" style={convertStyle} >
|
|
47
|
-
<input type="checkbox" checked={this.state.value} disabled={this.props.disabled}
|
|
48
|
-
onChange={() => {
|
|
49
|
-
const newValue = !this.state.value
|
|
50
|
-
this.setState({ value: newValue })
|
|
51
|
-
if (this.props.onChange) this.props.onChange(newValue)
|
|
52
|
-
}}
|
|
53
|
-
/>
|
|
54
|
-
<svg width="24" height="24" viewBox="0 0 24 24" xmlns="http://www.w3.org/2000/svg" >
|
|
55
|
-
<path d="M6.72 11.52 L10.8 15.6 L18 7.2" fill="none" strokeLinecap="round" stroke={this.props.checkColor ?? '#ffffff'} />
|
|
56
|
-
</svg>
|
|
57
|
-
</label>
|
|
58
|
-
}
|
|
59
|
-
}
|
|
@@ -1,53 +0,0 @@
|
|
|
1
|
-
import React from "react"
|
|
2
|
-
|
|
3
|
-
export const enum ComponentStatus {
|
|
4
|
-
INFOR = 1,
|
|
5
|
-
ERROR = 2,
|
|
6
|
-
WARNING = 3,
|
|
7
|
-
SUCCSESS = 4,
|
|
8
|
-
}
|
|
9
|
-
|
|
10
|
-
export const getStatusIcon = (status: ComponentStatus) => {
|
|
11
|
-
switch (status) {
|
|
12
|
-
case ComponentStatus.ERROR:
|
|
13
|
-
return errorSvg
|
|
14
|
-
case ComponentStatus.WARNING:
|
|
15
|
-
return warningSvg
|
|
16
|
-
case ComponentStatus.SUCCSESS:
|
|
17
|
-
return successSvg
|
|
18
|
-
default:
|
|
19
|
-
return inforSvg
|
|
20
|
-
}
|
|
21
|
-
}
|
|
22
|
-
|
|
23
|
-
const inforSvg = (
|
|
24
|
-
<div style={{ width: '3.6rem', height: '3.6rem' }}>
|
|
25
|
-
<svg width='100%' height='100%' viewBox='0 0 36 36' fill='none' xmlns='http://www.w3.org/2000/svg' >
|
|
26
|
-
<path d='M18.0003 3.41669C15.116 3.41669 12.2965 4.27198 9.89826 5.87442C7.50005 7.47686 5.63087 9.75446 4.52709 12.4192C3.42331 15.084 3.13451 18.0162 3.69721 20.8451C4.25991 23.674 5.64884 26.2725 7.68836 28.312C9.72787 30.3515 12.3264 31.7404 15.1553 32.3031C17.9842 32.8658 20.9164 32.577 23.5811 31.4733C26.2459 30.3695 28.5235 28.5003 30.1259 26.1021C31.7284 23.7039 32.5837 20.8843 32.5837 18C32.5795 14.1336 31.0417 10.4267 28.3077 7.69266C25.5737 4.95867 21.8668 3.42087 18.0003 3.41669V3.41669ZM19.2496 26.1715H16.7401V15.5695H19.2496V26.1715ZM19.0418 12.2384C18.9034 12.3653 18.7407 12.463 18.5637 12.5256C18.3866 12.5883 18.1987 12.6146 18.0113 12.603C17.8204 12.6157 17.6289 12.5899 17.4481 12.5273C17.2673 12.4647 17.101 12.3664 16.9588 12.2384C16.8333 12.1032 16.7363 11.9441 16.6737 11.7706C16.611 11.5971 16.584 11.4127 16.5943 11.2285C16.5815 11.04 16.6073 10.8509 16.67 10.6727C16.7327 10.4945 16.8309 10.3309 16.9588 10.1919C17.1013 10.0644 17.2678 9.96649 17.4484 9.9039C17.6291 9.84131 17.8204 9.81526 18.0113 9.82728C18.1987 9.81637 18.3864 9.843 18.5633 9.90561C18.7403 9.96822 18.903 10.0655 19.0418 10.1919C19.1697 10.3309 19.268 10.4945 19.3307 10.6727C19.3934 10.8509 19.4191 11.04 19.4064 11.2285C19.4166 11.4127 19.3896 11.5971 19.327 11.7706C19.2644 11.9441 19.1674 12.1032 19.0418 12.2384Z' fill='#366AE2' />
|
|
27
|
-
</svg>
|
|
28
|
-
</div>
|
|
29
|
-
)
|
|
30
|
-
|
|
31
|
-
const errorSvg = (
|
|
32
|
-
<div style={{ width: '3.6rem', height: '3.6rem' }}>
|
|
33
|
-
<svg width='100%' height='100%' viewBox='0 0 36 36' fill='none' xmlns='http://www.w3.org/2000/svg' >
|
|
34
|
-
<path d='M18.0003 3.41669C15.116 3.41669 12.2965 4.27198 9.89826 5.87442C7.50005 7.47686 5.63087 9.75446 4.52709 12.4192C3.42331 15.084 3.13451 18.0162 3.69721 20.8451C4.25991 23.674 5.64884 26.2725 7.68836 28.312C9.72787 30.3515 12.3264 31.7404 15.1553 32.3031C17.9842 32.8658 20.9164 32.577 23.5811 31.4733C26.2459 30.3695 28.5235 28.5003 30.1259 26.1021C31.7284 23.7039 32.5837 20.8843 32.5837 18C32.5724 14.1357 31.0324 10.4329 28.2999 7.70044C25.5674 4.96797 21.8646 3.42791 18.0003 3.41669V3.41669ZM24.016 22.2972L22.2976 24.0156L18.0003 19.7184L13.7031 24.0156L11.9847 22.2972L16.2819 18L11.9847 13.7028L13.7031 11.9844L18.0003 16.2816L22.2976 11.9844L24.016 13.7028L19.7187 18L24.016 22.2972Z' fill='#E14337' />
|
|
35
|
-
</svg>
|
|
36
|
-
</div>
|
|
37
|
-
)
|
|
38
|
-
|
|
39
|
-
const warningSvg = (
|
|
40
|
-
<div style={{ width: '3.6rem', height: '3.6rem' }}>
|
|
41
|
-
<svg width='100%' height='100%' viewBox='0 0 36 36' fill='none' xmlns='http://www.w3.org/2000/svg' >
|
|
42
|
-
<path d='M32.1516 25.8877L21.3215 5.41379C21.0014 4.81074 20.5231 4.30622 19.938 3.95437C19.3529 3.60252 18.6831 3.41663 18.0003 3.41663C17.3176 3.41663 16.6477 3.60252 16.0626 3.95437C15.4775 4.30622 14.9993 4.81074 14.6792 5.41379L3.84901 25.8877C3.54781 26.459 3.39954 27.0984 3.41863 27.744C3.43771 28.3895 3.6235 29.0191 3.95793 29.5716C4.29235 30.1241 4.76404 30.5806 5.32713 30.8969C5.89022 31.2131 6.52555 31.3783 7.17136 31.3763H28.8293C29.4751 31.3783 30.1104 31.2131 30.6735 30.8969C31.2366 30.5806 31.7083 30.1241 32.0427 29.5716C32.3771 29.0191 32.5629 28.3895 32.582 27.744C32.6011 27.0984 32.4528 26.459 32.1516 25.8877ZM18.0003 27.7294C17.6397 27.7294 17.2871 27.6224 16.9873 27.4221C16.6874 27.2217 16.4537 26.9369 16.3157 26.6037C16.1776 26.2705 16.1415 25.9039 16.2119 25.5502C16.2823 25.1965 16.4559 24.8715 16.7109 24.6165C16.966 24.3615 17.2909 24.1878 17.6446 24.1175C17.9983 24.0471 18.3649 24.0832 18.6981 24.2212C19.0313 24.3593 19.3161 24.593 19.5165 24.8928C19.7168 25.1927 19.8238 25.5453 19.8238 25.9059C19.8238 26.3895 19.6317 26.8533 19.2897 27.1953C18.9477 27.5373 18.4839 27.7294 18.0003 27.7294ZM19.216 21.6512H16.7847L16.1769 11.926H19.8238L19.216 21.6512Z' fill='#FC6B03' />
|
|
43
|
-
</svg>
|
|
44
|
-
</div>
|
|
45
|
-
)
|
|
46
|
-
|
|
47
|
-
const successSvg = (
|
|
48
|
-
<div style={{ width: '3.6rem', height: '3.6rem' }}>
|
|
49
|
-
<svg width='100%' height='100%' viewBox='0 0 36 36' fill='none' xmlns='http://www.w3.org/2000/svg' >
|
|
50
|
-
<path d='M18.0003 3.41669C15.116 3.41669 12.2965 4.27198 9.89826 5.87442C7.50005 7.47686 5.63087 9.75446 4.52709 12.4192C3.42331 15.084 3.13451 18.0162 3.69721 20.8451C4.25991 23.674 5.64884 26.2725 7.68836 28.312C9.72787 30.3515 12.3264 31.7404 15.1553 32.3031C17.9842 32.8658 20.9164 32.577 23.5811 31.4733C26.2459 30.3695 28.5235 28.5003 30.1259 26.1021C31.7284 23.7039 32.5837 20.8843 32.5837 18C32.5724 14.1357 31.0324 10.4329 28.2999 7.70044C25.5674 4.96797 21.8646 3.42791 18.0003 3.41669V3.41669ZM15.5698 24.5795L8.99026 18L10.7087 16.2816L15.5698 21.1427L25.292 11.4205L27.0104 13.1389L15.5698 24.5795Z' fill='#39AC6D' />
|
|
51
|
-
</svg>
|
|
52
|
-
</div>
|
|
53
|
-
)
|
|
@@ -1,114 +0,0 @@
|
|
|
1
|
-
.date-picker-container {
|
|
2
|
-
border-radius: 0.4rem;
|
|
3
|
-
justify-content: start;
|
|
4
|
-
width: 100%;
|
|
5
|
-
height: 4rem;
|
|
6
|
-
max-height: 100%;
|
|
7
|
-
box-sizing: border-box;
|
|
8
|
-
padding: 0.8rem;
|
|
9
|
-
column-gap: 6px;
|
|
10
|
-
width: 16rem;
|
|
11
|
-
position: relative;
|
|
12
|
-
border: 0.5px solid #00358033;
|
|
13
|
-
border-radius: 4px;
|
|
14
|
-
}
|
|
15
|
-
|
|
16
|
-
.date-picker-container>.input-field-value {
|
|
17
|
-
width: 100% !important;
|
|
18
|
-
flex: 1;
|
|
19
|
-
display: flex;
|
|
20
|
-
font: inherit;
|
|
21
|
-
color: inherit;
|
|
22
|
-
font-size: inherit;
|
|
23
|
-
font-family: inherit;
|
|
24
|
-
font-weight: inherit;
|
|
25
|
-
line-height: inherit;
|
|
26
|
-
text-align: inherit;
|
|
27
|
-
text-overflow: inherit;
|
|
28
|
-
}
|
|
29
|
-
|
|
30
|
-
.date-picker-container.disabled {
|
|
31
|
-
background-color: var(--disabled-background) !important;
|
|
32
|
-
pointer-events: none !important;
|
|
33
|
-
}
|
|
34
|
-
|
|
35
|
-
.date-picker-container.helper-text {
|
|
36
|
-
overflow: visible !important;
|
|
37
|
-
border-color: var(--helper-text-color) !important;
|
|
38
|
-
}
|
|
39
|
-
|
|
40
|
-
.date-picker-container.helper-text::after {
|
|
41
|
-
content: attr(helper-text);
|
|
42
|
-
color: #e14337;
|
|
43
|
-
position: absolute;
|
|
44
|
-
left: 0;
|
|
45
|
-
bottom: 0;
|
|
46
|
-
width: max-content;
|
|
47
|
-
font-size: inherit;
|
|
48
|
-
line-height: inherit;
|
|
49
|
-
font-family: inherit;
|
|
50
|
-
font-weight: inherit;
|
|
51
|
-
transform: translate(-7.5%, 92.5%) scale(0.85);
|
|
52
|
-
}
|
|
53
|
-
|
|
54
|
-
.date-picker-container .input-field-value {
|
|
55
|
-
flex: 1;
|
|
56
|
-
width: 100%;
|
|
57
|
-
background-color: transparent !important;
|
|
58
|
-
font: inherit;
|
|
59
|
-
color: inherit;
|
|
60
|
-
font-size: inherit;
|
|
61
|
-
font-family: inherit;
|
|
62
|
-
font-weight: inherit;
|
|
63
|
-
line-height: inherit;
|
|
64
|
-
text-align: inherit;
|
|
65
|
-
text-overflow: inherit;
|
|
66
|
-
}
|
|
67
|
-
|
|
68
|
-
.date-picker-container .input-field-value>input {
|
|
69
|
-
border: none;
|
|
70
|
-
outline: none;
|
|
71
|
-
transition: 0.4s;
|
|
72
|
-
background-color: transparent;
|
|
73
|
-
padding: 0;
|
|
74
|
-
min-width: 0;
|
|
75
|
-
width: 100%;
|
|
76
|
-
font: inherit;
|
|
77
|
-
color: inherit;
|
|
78
|
-
font-size: inherit;
|
|
79
|
-
font-family: inherit;
|
|
80
|
-
font-weight: inherit;
|
|
81
|
-
line-height: inherit;
|
|
82
|
-
text-align: inherit;
|
|
83
|
-
text-overflow: inherit;
|
|
84
|
-
}
|
|
85
|
-
|
|
86
|
-
.date-picker-container .input-field-value>input::placeholder {
|
|
87
|
-
opacity: 0.6;
|
|
88
|
-
}
|
|
89
|
-
|
|
90
|
-
.date-picker-popup-container {
|
|
91
|
-
position: absolute;
|
|
92
|
-
}
|
|
93
|
-
|
|
94
|
-
.date-picker-popup-container .picker-popup-footer {
|
|
95
|
-
justify-content: center;
|
|
96
|
-
gap: 0.8rem;
|
|
97
|
-
padding: 1.6rem;
|
|
98
|
-
}
|
|
99
|
-
|
|
100
|
-
.date-picker-popup-container .reset-value-button {
|
|
101
|
-
color: #00204D99;
|
|
102
|
-
background-color: #F2F5F8;
|
|
103
|
-
padding: 0.6rem 1.2rem;
|
|
104
|
-
border-radius: 2.4rem;
|
|
105
|
-
width: fit-content;
|
|
106
|
-
}
|
|
107
|
-
|
|
108
|
-
.date-picker-popup-container .apply-value-button {
|
|
109
|
-
color: #ffffff;
|
|
110
|
-
background-color: var(--infor-color);
|
|
111
|
-
padding: 0.6rem 1.2rem;
|
|
112
|
-
border-radius: 2.4rem;
|
|
113
|
-
width: fit-content;
|
|
114
|
-
}
|
|
@@ -1,363 +0,0 @@
|
|
|
1
|
-
/* eslint-disable react-hooks/exhaustive-deps */
|
|
2
|
-
import React, { CSSProperties } from 'react'
|
|
3
|
-
import ReactDOM from 'react-dom'
|
|
4
|
-
import './date-picker.css'
|
|
5
|
-
import { CalendarType, Calendar } from '../export-component'
|
|
6
|
-
import { endDate, inRangeTime, startDate, today } from '../calendar/calendar'
|
|
7
|
-
import { differenceInCalendarDays } from 'date-fns'
|
|
8
|
-
|
|
9
|
-
const CalendarIcon = ({ color = '#00204D99', width = '1.6rem', height = '1.6rem' }: { color?: string, width?: string | number, height?: string | number }) => (
|
|
10
|
-
<svg xmlns='http://www.w3.org/2000/svg' width='100%' height='100%' viewBox='0 0 17 16' fill='none' style={{ width: width, height: height }}>
|
|
11
|
-
<path d='M12.3876 2.99967V1.88856C12.3876 1.74122 12.3291 1.59991 12.2249 1.49573C12.1207 1.39154 11.9794 1.33301 11.832 1.33301C11.6847 1.33301 11.5434 1.39154 11.4392 1.49573C11.335 1.59991 11.2765 1.74122 11.2765 1.88856V2.99967H12.3876Z' fill={color} />
|
|
12
|
-
<path d='M5.72092 2.99967V1.88856C5.72092 1.74122 5.66239 1.59991 5.5582 1.49573C5.45401 1.39154 5.31271 1.33301 5.16536 1.33301C5.01802 1.33301 4.87671 1.39154 4.77253 1.49573C4.66834 1.59991 4.60981 1.74122 4.60981 1.88856V2.99967H5.72092Z' fill={color} />
|
|
13
|
-
<path d='M13.4987 14.1108H3.4987C3.05667 14.1108 2.63275 13.9352 2.32019 13.6226C2.00763 13.3101 1.83203 12.8861 1.83203 12.4441V5.2219C1.83203 4.77987 2.00763 4.35595 2.32019 4.04339C2.63275 3.73082 3.05667 3.55523 3.4987 3.55523H13.4987C13.9407 3.55523 14.3646 3.73082 14.6772 4.04339C14.9898 4.35595 15.1654 4.77987 15.1654 5.2219V12.4441C15.1654 12.8861 14.9898 13.3101 14.6772 13.6226C14.3646 13.9352 13.9407 14.1108 13.4987 14.1108ZM14.0543 6.33301H2.94314V12.4441C2.94314 12.5915 3.00167 12.7328 3.10586 12.837C3.21005 12.9411 3.35136 12.9997 3.4987 12.9997H13.4987C13.646 12.9997 13.7873 12.9411 13.8915 12.837C13.9957 12.7328 14.0543 12.5915 14.0543 12.4441V6.33301Z' fill={color} />
|
|
14
|
-
<path d='M6.27648 7.44412H4.05425V9.11079H6.27648V7.44412Z' fill={color} />
|
|
15
|
-
<path d='M9.60981 7.44412H7.38759V9.11079H9.60981V7.44412Z' fill={color} />
|
|
16
|
-
<path d='M6.27648 10.2219H4.05425V11.8886H6.27648V10.2219Z' fill={color} />
|
|
17
|
-
<path d='M9.60981 10.2219H7.38759V11.8886H9.60981V10.2219Z' fill={color} />
|
|
18
|
-
<path d='M12.9431 7.44412H10.7209V9.11079H12.9431V7.44412Z' fill={color} />
|
|
19
|
-
</svg>
|
|
20
|
-
)
|
|
21
|
-
|
|
22
|
-
const dateToString = (x: Date, y: string = "dd/mm/yyyy") => {
|
|
23
|
-
let splitDateTime: Array<string> = y.split(" ");
|
|
24
|
-
let dateFormat = splitDateTime[0]
|
|
25
|
-
let timeFormat = splitDateTime[1]
|
|
26
|
-
if (dateFormat.includes('hh')) {
|
|
27
|
-
dateFormat = splitDateTime[1]
|
|
28
|
-
timeFormat = splitDateTime[0]
|
|
29
|
-
}
|
|
30
|
-
let dateConvert: string = dateFormat.split(y.includes("/") ? "/" : "-").map(type => {
|
|
31
|
-
switch (type.toLowerCase()) {
|
|
32
|
-
case "dd":
|
|
33
|
-
return x.getDate() < 10 ? `0${x.getDate()}` : `${x.getDate()}`;
|
|
34
|
-
case "mm":
|
|
35
|
-
return (x.getMonth() + 1) < 10 ? `0${(x.getMonth() + 1)}` : `${(x.getMonth() + 1)}`;
|
|
36
|
-
case "yyyy":
|
|
37
|
-
return `${x.getFullYear()}`;
|
|
38
|
-
default:
|
|
39
|
-
return ''
|
|
40
|
-
}
|
|
41
|
-
}).join(y.includes("/") ? "/" : "-");
|
|
42
|
-
if (timeFormat) {
|
|
43
|
-
let timeConvert = timeFormat.split(":").map(type => {
|
|
44
|
-
switch (type) {
|
|
45
|
-
case "hh":
|
|
46
|
-
return x.getHours() < 10 ? `0${x.getHours()}` : `${x.getHours()}`;
|
|
47
|
-
case "mm":
|
|
48
|
-
return x.getMinutes() < 10 ? `0${x.getMinutes()}` : `${x.getMinutes()}`;
|
|
49
|
-
case "ss":
|
|
50
|
-
return x.getSeconds() < 10 ? `0${x.getSeconds()}` : `${x.getSeconds()}`;
|
|
51
|
-
default:
|
|
52
|
-
return 'D'
|
|
53
|
-
}
|
|
54
|
-
}).join(":")
|
|
55
|
-
return dateConvert + " " + timeConvert;
|
|
56
|
-
}
|
|
57
|
-
return dateConvert;
|
|
58
|
-
}
|
|
59
|
-
|
|
60
|
-
const stringToDate = (_date: string, _format: string = "dd/MM/yyyy", _delimiter: string = "/") => {
|
|
61
|
-
let dayformat: string = _format;
|
|
62
|
-
let hourformat: string = '';
|
|
63
|
-
let day: string = _date;
|
|
64
|
-
let hours: string = '';
|
|
65
|
-
let isHour: boolean = false;
|
|
66
|
-
if (_format.trim().indexOf(" ") > -1) {
|
|
67
|
-
dayformat = _format.trim().split(" ")[0];
|
|
68
|
-
hourformat = _format.trim().split(" ")[1];
|
|
69
|
-
day = _date.trim().split(" ")[0];
|
|
70
|
-
hours = _date.trim().split(" ")[1] ?? '00:00:00';
|
|
71
|
-
isHour = true;
|
|
72
|
-
}
|
|
73
|
-
let formatLowerCase: string = dayformat.toLowerCase();
|
|
74
|
-
let formatItems: Array<string> = formatLowerCase.split(_delimiter);
|
|
75
|
-
let dateItems: Array<string> = day.split(_delimiter);
|
|
76
|
-
let monthIndex: number = formatItems.indexOf("mm");
|
|
77
|
-
let dayIndex: number = formatItems.indexOf("dd");
|
|
78
|
-
let yearIndex: number = formatItems.indexOf("yyyy");
|
|
79
|
-
let hour: number = 0;
|
|
80
|
-
let min: number = 0;
|
|
81
|
-
let sec: number = 0;
|
|
82
|
-
if (isHour) {
|
|
83
|
-
let tmpHour: Array<string> = hourformat.split(":");
|
|
84
|
-
let hourindex: number = tmpHour.indexOf("HH");
|
|
85
|
-
if (hourindex < 0) {
|
|
86
|
-
hourindex = tmpHour.indexOf("hh");
|
|
87
|
-
}
|
|
88
|
-
let mmindex: number = tmpHour.indexOf("mm");
|
|
89
|
-
let ssindex: number = tmpHour.indexOf("ss");
|
|
90
|
-
let time: Array<string> = hours.split(":");
|
|
91
|
-
hour = parseInt(time[hourindex] ?? '0'); min = parseInt(time[mmindex] ?? '0'); sec = parseInt(time[ssindex] ?? '0');
|
|
92
|
-
}
|
|
93
|
-
let month: number = parseInt(dateItems[monthIndex]);
|
|
94
|
-
month -= 1;
|
|
95
|
-
var formatedDate = new Date(parseInt(dateItems[yearIndex]), month, parseInt(dateItems[dayIndex] ?? '0'), hour, min, sec);
|
|
96
|
-
return formatedDate;
|
|
97
|
-
}
|
|
98
|
-
|
|
99
|
-
interface DatePickerProps {
|
|
100
|
-
value?: string,
|
|
101
|
-
min: Date,
|
|
102
|
-
max: Date,
|
|
103
|
-
onChange?: (e?: string) => void,
|
|
104
|
-
disabled?: boolean,
|
|
105
|
-
helperText?: string,
|
|
106
|
-
helperTextColor?: string,
|
|
107
|
-
placeholder?: string,
|
|
108
|
-
className?: string,
|
|
109
|
-
hideButtonToday?: boolean,
|
|
110
|
-
style?: CSSProperties,
|
|
111
|
-
/* default: DATE */
|
|
112
|
-
pickerType?: CalendarType,
|
|
113
|
-
/* y: dd/mm/yyy || dd/mm/yyyy hh:mm:ss || hh:mm:ss dd/mm/yyyy, default: dd/mm/yyyy */
|
|
114
|
-
formatDate?: string
|
|
115
|
-
}
|
|
116
|
-
|
|
117
|
-
interface DatePickerState {
|
|
118
|
-
value?: string,
|
|
119
|
-
offset: DOMRect,
|
|
120
|
-
isOpen: boolean,
|
|
121
|
-
style?: Object
|
|
122
|
-
}
|
|
123
|
-
|
|
124
|
-
|
|
125
|
-
export class DatePicker extends React.Component<DatePickerProps, DatePickerState> {
|
|
126
|
-
constructor(props: DatePickerProps) {
|
|
127
|
-
super(props)
|
|
128
|
-
this.state = {
|
|
129
|
-
value: props.value,
|
|
130
|
-
offset: {
|
|
131
|
-
x: 0,
|
|
132
|
-
y: 0,
|
|
133
|
-
height: 0,
|
|
134
|
-
width: 0,
|
|
135
|
-
bottom: 0,
|
|
136
|
-
left: 0,
|
|
137
|
-
right: 0,
|
|
138
|
-
top: 0,
|
|
139
|
-
toJSON: function () {
|
|
140
|
-
throw new Error('Function not implemented.')
|
|
141
|
-
}
|
|
142
|
-
},
|
|
143
|
-
isOpen: false,
|
|
144
|
-
}
|
|
145
|
-
}
|
|
146
|
-
|
|
147
|
-
getNewValue = (value?: string) => {
|
|
148
|
-
const params: string = value ?? this.state?.value ?? ''
|
|
149
|
-
if (params.trim()?.length) {
|
|
150
|
-
switch (this.props.pickerType) {
|
|
151
|
-
case CalendarType.YEAR:
|
|
152
|
-
return new Date(parseInt(params), 1, 1)
|
|
153
|
-
case CalendarType.MONTH:
|
|
154
|
-
let splitParams: Array<string> = params.includes('/') ? params.split('/') : params.split('-')
|
|
155
|
-
return new Date(parseInt(splitParams[1] ?? `${today.getFullYear()}`), parseInt(splitParams[0] ?? `${today.getMonth()}`), 1)
|
|
156
|
-
case CalendarType.DATETIME:
|
|
157
|
-
return stringToDate(params, this.props.formatDate ?? 'dd/mm/yyyy hh:mm')
|
|
158
|
-
default:
|
|
159
|
-
return stringToDate(params)
|
|
160
|
-
}
|
|
161
|
-
}
|
|
162
|
-
return undefined
|
|
163
|
-
}
|
|
164
|
-
|
|
165
|
-
componentDidUpdate(prevProps: DatePickerProps, prevState: DatePickerState) {
|
|
166
|
-
if (prevProps.value !== this.props.value) {
|
|
167
|
-
this.setState({
|
|
168
|
-
...this.state,
|
|
169
|
-
value: this.props.value,
|
|
170
|
-
})
|
|
171
|
-
}
|
|
172
|
-
if (prevState.isOpen !== this.state.isOpen && this.state.isOpen) {
|
|
173
|
-
const thisPopupRect = document.body.querySelector('.date-picker-popup-container')?.getBoundingClientRect()
|
|
174
|
-
if (thisPopupRect) {
|
|
175
|
-
let style: { top?: string, left?: string, right?: string, bottom?: string, width?: string, height?: string } | undefined;
|
|
176
|
-
if (thisPopupRect.right > document.body.offsetWidth) {
|
|
177
|
-
style = {
|
|
178
|
-
top: this.state.offset.y + this.state.offset.height + 2 + 'px',
|
|
179
|
-
right: document.body.offsetWidth - this.state.offset.left + 'px'
|
|
180
|
-
}
|
|
181
|
-
}
|
|
182
|
-
if ((thisPopupRect.bottom - 20) > document.body.offsetHeight) {
|
|
183
|
-
style = style ? {
|
|
184
|
-
...style,
|
|
185
|
-
top: undefined,
|
|
186
|
-
bottom: document.body.offsetHeight - this.state.offset.top + 'px'
|
|
187
|
-
} : {
|
|
188
|
-
left: this.state.offset.x + 'px',
|
|
189
|
-
bottom: document.body.offsetHeight - this.state.offset.top + 'px'
|
|
190
|
-
}
|
|
191
|
-
}
|
|
192
|
-
if (style) this.setState({ ...this.state, style: style })
|
|
193
|
-
}
|
|
194
|
-
}
|
|
195
|
-
}
|
|
196
|
-
|
|
197
|
-
render() {
|
|
198
|
-
let maxLength = 10
|
|
199
|
-
switch (this.props.pickerType) {
|
|
200
|
-
case CalendarType.YEAR:
|
|
201
|
-
maxLength = 4
|
|
202
|
-
break;
|
|
203
|
-
case CalendarType.MONTH:
|
|
204
|
-
maxLength = 7
|
|
205
|
-
break;
|
|
206
|
-
case CalendarType.DATETIME:
|
|
207
|
-
maxLength = 19
|
|
208
|
-
break;
|
|
209
|
-
default:
|
|
210
|
-
break;
|
|
211
|
-
}
|
|
212
|
-
return <label className={`date-picker-container row ${this.props.className ?? 'placeholder-2'} ${this.props.disabled ? 'disabled' : ''} ${this.props.helperText?.length && 'helper-text'}`}
|
|
213
|
-
helper-text={this.props.helperText}
|
|
214
|
-
style={this.props.style ? { ...({ '--helper-text-color': this.props.helperTextColor ?? '#e14337' } as CSSProperties), ...this.props.style } : ({ '--helper-text-color': this.props.helperTextColor ?? '#e14337' } as CSSProperties)}
|
|
215
|
-
>
|
|
216
|
-
<div className='input-field-value row' style={{ height: '4rem' }}>
|
|
217
|
-
<input
|
|
218
|
-
autoComplete='off'
|
|
219
|
-
value={this.state.value ?? ''}
|
|
220
|
-
onChange={(ev) => this.setState({ ...this.state, value: ev.target.value })}
|
|
221
|
-
placeholder={this.props.placeholder}
|
|
222
|
-
maxLength={maxLength}
|
|
223
|
-
onBlur={ev => {
|
|
224
|
-
const inputValue = ev.target.value.trim()
|
|
225
|
-
switch (this.props.pickerType) {
|
|
226
|
-
case CalendarType.YEAR:
|
|
227
|
-
let minYear = (this.props.min ?? startDate).getFullYear()
|
|
228
|
-
let maxYear = (this.props.min ?? endDate).getFullYear()
|
|
229
|
-
if (!isNaN(parseInt(inputValue)) && parseInt(inputValue) <= maxYear && parseInt(inputValue) >= minYear) {
|
|
230
|
-
this.setState({ ...this.state, isOpen: false, value: inputValue })
|
|
231
|
-
if (this.props.onChange) this.props.onChange(inputValue)
|
|
232
|
-
} else {
|
|
233
|
-
this.setState({ ...this.state, isOpen: false, value: undefined })
|
|
234
|
-
if (this.props.onChange) this.props.onChange(undefined)
|
|
235
|
-
}
|
|
236
|
-
break
|
|
237
|
-
case CalendarType.MONTH:
|
|
238
|
-
if (inputValue.match(/[0-9]{1,2}(\/|-)[0-9]{4}/g)) {
|
|
239
|
-
let dateValue = stringToDate(`1/${inputValue}`, 'dd/MM/yyyy', '/')
|
|
240
|
-
if (inRangeTime(dateValue, this.props.min ?? startDate ?? startDate, this.props.min ?? endDate ?? endDate)) {
|
|
241
|
-
this.setState({ ...this.state, isOpen: false, value: dateToString(dateValue) })
|
|
242
|
-
if (this.props.onChange) this.props.onChange(dateToString(dateValue))
|
|
243
|
-
} else {
|
|
244
|
-
this.setState({ ...this.state, isOpen: false, value: undefined })
|
|
245
|
-
if (this.props.onChange) this.props.onChange(undefined)
|
|
246
|
-
}
|
|
247
|
-
} else {
|
|
248
|
-
this.setState({ ...this.state, isOpen: false, value: undefined })
|
|
249
|
-
if (this.props.onChange) this.props.onChange(undefined)
|
|
250
|
-
}
|
|
251
|
-
break
|
|
252
|
-
case CalendarType.DATETIME:
|
|
253
|
-
let dateTimeValue: Date | undefined = undefined
|
|
254
|
-
if (inputValue.match(/[0-9]{1,2}(\/|-)[0-9]{1,2}(\/|-)[0-9]{4}/g)) {
|
|
255
|
-
dateTimeValue = stringToDate(inputValue, this.props.formatDate ?? 'dd/mm/yyyy hh:mm', '/')
|
|
256
|
-
if (inRangeTime(dateTimeValue, this.props.min ?? startDate, this.props.min ?? endDate)) {
|
|
257
|
-
} else if (differenceInCalendarDays(this.props.min ?? startDate, dateTimeValue) > -1) {
|
|
258
|
-
dateTimeValue = this.props.min ?? startDate
|
|
259
|
-
} else if (differenceInCalendarDays(dateTimeValue, this.props.min ?? endDate) > -1) {
|
|
260
|
-
dateTimeValue = this.props.min ?? startDate
|
|
261
|
-
} else {
|
|
262
|
-
dateTimeValue = undefined
|
|
263
|
-
}
|
|
264
|
-
}
|
|
265
|
-
const stateDateTimeValue = dateTimeValue ? dateToString(dateTimeValue, this.props.formatDate ?? 'dd/mm/yyyy hh:mm') : dateTimeValue
|
|
266
|
-
this.setState({ ...this.state, isOpen: false, value: stateDateTimeValue })
|
|
267
|
-
if (this.props.onChange) this.props.onChange(stateDateTimeValue)
|
|
268
|
-
break;
|
|
269
|
-
default:
|
|
270
|
-
let dateValue: Date | undefined = undefined
|
|
271
|
-
if (inputValue.match(/[0-9]{1,2}(\/|-)[0-9]{1,2}(\/|-)[0-9]{4}/g)) {
|
|
272
|
-
dateValue = stringToDate(inputValue, 'dd/MM/yyyy', '/')
|
|
273
|
-
if (inRangeTime(dateValue, this.props.min ?? startDate, this.props.min ?? endDate)) {
|
|
274
|
-
} else if (differenceInCalendarDays(this.props.min ?? startDate, dateValue) > -1) {
|
|
275
|
-
dateValue = this.props.min ?? startDate
|
|
276
|
-
} else if (differenceInCalendarDays(dateValue, this.props.min ?? endDate) > -1) {
|
|
277
|
-
dateValue = this.props.max ?? endDate
|
|
278
|
-
} else {
|
|
279
|
-
dateValue = undefined
|
|
280
|
-
}
|
|
281
|
-
}
|
|
282
|
-
const stateDateValue = dateValue ? dateToString(dateValue) : dateValue
|
|
283
|
-
this.setState({ ...this.state, isOpen: false, value: stateDateValue })
|
|
284
|
-
if (this.props.onChange) this.props.onChange(stateDateValue)
|
|
285
|
-
break;
|
|
286
|
-
}
|
|
287
|
-
}}
|
|
288
|
-
/>
|
|
289
|
-
</div>
|
|
290
|
-
<button type='button' onClick={(ev) => {
|
|
291
|
-
if (!this.state.isOpen) {
|
|
292
|
-
this.setState({
|
|
293
|
-
...this.state,
|
|
294
|
-
isOpen: true,
|
|
295
|
-
style: undefined,
|
|
296
|
-
offset: ((ev.target as HTMLElement).closest('.date-picker-container') ?? (ev.target as HTMLElement)).getBoundingClientRect()
|
|
297
|
-
})
|
|
298
|
-
}
|
|
299
|
-
}} className='row' style={{ padding: '0.4rem' }}><CalendarIcon /></button>
|
|
300
|
-
{this.state.isOpen &&
|
|
301
|
-
ReactDOM.createPortal(
|
|
302
|
-
<div className={`popup-overlay hidden-overlay`} onClick={(ev) => {
|
|
303
|
-
if ((ev.target as HTMLElement).classList.contains('popup-overlay'))
|
|
304
|
-
this.setState({ ...this.state, isOpen: false })
|
|
305
|
-
}}>
|
|
306
|
-
<Calendar
|
|
307
|
-
value={this.getNewValue()}
|
|
308
|
-
type={this.props.pickerType ?? CalendarType.DATE}
|
|
309
|
-
className='date-picker-popup-container'
|
|
310
|
-
style={this.state.style ?? { top: this.state.offset.y + this.state.offset.height + 2 + 'px', left: this.state.offset.x + 'px', border: 'none', boxShadow: '-20px 20px 40px -4px rgba(145, 158, 171, 0.24), 0px 0px 2px 0px rgba(145, 158, 171, 0.24)' }}
|
|
311
|
-
onSelect={(dateValue: Date) => {
|
|
312
|
-
switch (this.props.pickerType) {
|
|
313
|
-
case CalendarType.YEAR:
|
|
314
|
-
this.setState({ ...this.state, value: dateValue.getFullYear().toString(), isOpen: false })
|
|
315
|
-
if (this.props.onChange) this.props.onChange(dateValue.getFullYear().toString())
|
|
316
|
-
break;
|
|
317
|
-
case CalendarType.MONTH:
|
|
318
|
-
var newValue = dateToString(dateValue)
|
|
319
|
-
this.setState({ ...this.state, value: newValue.split('/').slice(1).join('/'), isOpen: false })
|
|
320
|
-
if (this.props.onChange) this.props.onChange(newValue.split('/').slice(1).join('/'))
|
|
321
|
-
break;
|
|
322
|
-
case CalendarType.DATETIME:
|
|
323
|
-
var newValue = dateToString(dateValue, this.props.formatDate ?? 'dd/mm/yyyy hh:mm')
|
|
324
|
-
this.setState({ ...this.state, value: newValue })
|
|
325
|
-
break;
|
|
326
|
-
default:
|
|
327
|
-
var newValue = dateToString(dateValue)
|
|
328
|
-
this.setState({ ...this.state, value: newValue, isOpen: false })
|
|
329
|
-
if (this.props.onChange) this.props.onChange(newValue)
|
|
330
|
-
break;
|
|
331
|
-
}
|
|
332
|
-
}}
|
|
333
|
-
footer={(this.props.pickerType === CalendarType.DATETIME || !this.props.hideButtonToday) && <div className='row picker-popup-footer' >
|
|
334
|
-
{this.props.pickerType === undefined || this.props.pickerType === CalendarType.DATE || this.props.pickerType === CalendarType.DATETIME ?
|
|
335
|
-
<button
|
|
336
|
-
type='button'
|
|
337
|
-
className='row button-text-3'
|
|
338
|
-
style={{ color: 'var(--infor-color)', width: 'fit-content' }}
|
|
339
|
-
onClick={() => {
|
|
340
|
-
let format = this.props.formatDate ?? (this.props.pickerType === CalendarType.DATETIME ? 'dd/mm/yyyy hh:mm' : 'dd/mm/yyyy')
|
|
341
|
-
this.setState({ ...this.state, isOpen: false, value: dateToString(today, format) })
|
|
342
|
-
if (this.props.onChange) this.props.onChange(dateToString(today, format))
|
|
343
|
-
}}
|
|
344
|
-
>
|
|
345
|
-
Today
|
|
346
|
-
</button> : null}
|
|
347
|
-
{this.props.pickerType === CalendarType.DATETIME ? <>
|
|
348
|
-
<div style={{ flex: 1 }}></div>
|
|
349
|
-
<button type='button' className='row button-primary' style={{ padding: '0.6rem 0.8rem' }} onClick={() => {
|
|
350
|
-
this.setState({ ...this.state, isOpen: false })
|
|
351
|
-
if (this.props.onChange) this.props.onChange(this.state.value)
|
|
352
|
-
}} >
|
|
353
|
-
<div className='button-text-3'>Submit</div>
|
|
354
|
-
</button>
|
|
355
|
-
</> : null}
|
|
356
|
-
</div>}
|
|
357
|
-
/>
|
|
358
|
-
</div>,
|
|
359
|
-
document.body
|
|
360
|
-
)}
|
|
361
|
-
</label>
|
|
362
|
-
}
|
|
363
|
-
}
|