wini-web-components 0.1.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.
Files changed (62) hide show
  1. package/README.md +70 -0
  2. package/package.json +62 -0
  3. package/public/favicon.ico +0 -0
  4. package/public/index.html +43 -0
  5. package/public/logo192.png +0 -0
  6. package/public/logo512.png +0 -0
  7. package/public/manifest.json +25 -0
  8. package/public/robots.txt +3 -0
  9. package/src/App.css +38 -0
  10. package/src/App.js +25 -0
  11. package/src/App.test.js +8 -0
  12. package/src/component/calendar/calendar.css +133 -0
  13. package/src/component/calendar/calendar.tsx +448 -0
  14. package/src/component/checkbox/checkbox.css +46 -0
  15. package/src/component/checkbox/checkbox.tsx +59 -0
  16. package/src/component/component-status.tsx +53 -0
  17. package/src/component/date-picker/date-picker.css +114 -0
  18. package/src/component/date-picker/date-picker.tsx +363 -0
  19. package/src/component/dialog/dialog.css +125 -0
  20. package/src/component/dialog/dialog.tsx +91 -0
  21. package/src/component/export-component.js +48 -0
  22. package/src/component/import-file/import-file.css +86 -0
  23. package/src/component/import-file/import-file.tsx +154 -0
  24. package/src/component/infinite-scroll/infinite-scroll.css +37 -0
  25. package/src/component/infinite-scroll/infinite-scroll.tsx +33 -0
  26. package/src/component/input-multi-select/input-multi-select.css +127 -0
  27. package/src/component/input-multi-select/input-multi-select.tsx +261 -0
  28. package/src/component/pagination/pagination.css +69 -0
  29. package/src/component/pagination/pagination.tsx +65 -0
  30. package/src/component/popup/popup.css +90 -0
  31. package/src/component/popup/popup.tsx +105 -0
  32. package/src/component/progress-bar/progress-bar.css +47 -0
  33. package/src/component/progress-bar/progress-bar.tsx +34 -0
  34. package/src/component/progress-circle/progress-circle.css +47 -0
  35. package/src/component/progress-circle/progress-circle.tsx +24 -0
  36. package/src/component/radio-button/radio-button.css +49 -0
  37. package/src/component/radio-button/radio-button.tsx +59 -0
  38. package/src/component/rating/rating.css +11 -0
  39. package/src/component/rating/rating.tsx +65 -0
  40. package/src/component/select1/select1.css +155 -0
  41. package/src/component/select1/select1.tsx +241 -0
  42. package/src/component/slider/slider.css +16 -0
  43. package/src/component/slider/slider.tsx +87 -0
  44. package/src/component/switch/switch.css +53 -0
  45. package/src/component/switch/switch.tsx +67 -0
  46. package/src/component/table/table.css +74 -0
  47. package/src/component/table/table.tsx +99 -0
  48. package/src/component/text/text.css +16 -0
  49. package/src/component/text/text.tsx +21 -0
  50. package/src/component/text-area/text-area.css +63 -0
  51. package/src/component/text-area/text-area.tsx +55 -0
  52. package/src/component/text-field/text-field.css +64 -0
  53. package/src/component/text-field/text-field.tsx +63 -0
  54. package/src/component/toast-noti/toast-noti.css +0 -0
  55. package/src/component/toast-noti/toast-noti.tsx +21 -0
  56. package/src/index.css +13 -0
  57. package/src/index.js +17 -0
  58. package/src/logo.svg +1 -0
  59. package/src/reportWebVitals.js +13 -0
  60. package/src/setupTests.js +5 -0
  61. package/src/skin/color.css +17 -0
  62. package/src/skin/typography.css +378 -0
@@ -0,0 +1,114 @@
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
+ }
@@ -0,0 +1,363 @@
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
+ }
@@ -0,0 +1,125 @@
1
+ .dialog-overlay {
2
+ position: fixed;
3
+ top: 0;
4
+ left: 0;
5
+ width: 100%;
6
+ height: 100%;
7
+ background-color: rgba(0, 0, 0, 0.5);
8
+ display: flex;
9
+ justify-content: center;
10
+ align-items: center;
11
+ z-index: 10;
12
+ }
13
+
14
+ .dialog-container {
15
+ position: relative;
16
+ background-color: #ffffff;
17
+ padding: 2.4rem;
18
+ border-radius: 8px;
19
+ box-shadow: 0 2px 8px rgba(0, 0, 0, 0.25);
20
+ row-gap: 2.4rem;
21
+ overflow: visible;
22
+ }
23
+
24
+ .dialog-container button {
25
+ outline: none;
26
+ padding: 0;
27
+ border: none;
28
+ }
29
+
30
+ .dialog-body {
31
+ row-gap: 1.6rem;
32
+ }
33
+
34
+ .dialog-body>.dialog-status {
35
+ width: 5.6rem;
36
+ height: 5.6rem;
37
+ border-radius: 50%;
38
+ align-items: center;
39
+ justify-content: center;
40
+ }
41
+
42
+ .dialog-body>.dialog-title {
43
+ font: 600 2rem/2.8rem 'Inter';
44
+ color: #00204D;
45
+ }
46
+
47
+ .dialog-body>.dialog-content {
48
+ font: 400 1.4rem/2.2rem 'Inter';
49
+ color: #00204DCC;
50
+ }
51
+
52
+ .dialog-footer {
53
+ gap: 0.8rem;
54
+ justify-content: end;
55
+ width: 100%;
56
+ }
57
+
58
+ .dialog-footer>.dialog-action {
59
+ display: flex;
60
+ height: 4rem;
61
+ justify-content: center;
62
+ padding: 0 1.6rem;
63
+ border-radius: 0.8rem;
64
+ background-color: #F2F5F8;
65
+ align-items: center;
66
+ font: 500 1.4rem/2.2rem 'Inter';
67
+ color: #00204D99;
68
+ }
69
+
70
+ .dialog-footer>.dialog-submit {
71
+ color: #ffffff;
72
+ }
73
+
74
+ /*
75
+ INFOR = 1
76
+ ERROR = 2
77
+ WARNING = 3
78
+ SUCCSESS = 4
79
+ */
80
+
81
+ .dialog-container[dialog-type="1"] .dialog-status {
82
+ background-color: #EDF2FD;
83
+ }
84
+
85
+ .dialog-container[dialog-type="2"] .dialog-status {
86
+ background-color: #FCEEED;
87
+ }
88
+
89
+ .dialog-container[dialog-type="3"] .dialog-status {
90
+ background-color: #FFF3EB;
91
+ }
92
+
93
+ .dialog-container[dialog-type="4"] .dialog-status {
94
+ background-color: #E8F7EF;
95
+ }
96
+
97
+ .dialog-container[dialog-type="1"] .dialog-footer>.dialog-submit {
98
+ background-color: #366AE2;
99
+ }
100
+
101
+ .dialog-container[dialog-type="2"] .dialog-footer>.dialog-submit {
102
+ background-color: #E14337;
103
+ }
104
+
105
+ .dialog-container[dialog-type="3"] .dialog-footer>.dialog-submit {
106
+ background-color: #FC6B03;
107
+ }
108
+
109
+ .dialog-container[dialog-type="4"] .dialog-footer>.dialog-submit {
110
+ background-color: #39AC6D;
111
+ }
112
+
113
+ .dialog-container>.dialog-close-btn {
114
+ position: absolute;
115
+ right: 0;
116
+ top: 0;
117
+ transform: translate(50%, -50%);
118
+ width: 3.2rem;
119
+ height: 3.2rem;
120
+ border-radius: 50%;
121
+ align-items: center;
122
+ justify-content: center;
123
+ background-color: #FFFFFF;
124
+ box-shadow: 0px 1px 6px 0px #2D32390F;
125
+ }