intelicoreact 0.0.86 → 0.0.92
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/Atomic/FormElements/Dropdown/Dropdown.js +44 -19
- package/dist/Atomic/FormElements/Dropdown/Dropdown.scss +12 -0
- package/dist/Atomic/FormElements/Dropdown/Dropdown.stories.js +35 -7
- package/dist/Atomic/FormElements/Dropdown/components/DropdownLoader.js +24 -0
- package/dist/Atomic/FormElements/Dropdown/components/Loader.scss +57 -0
- package/dist/Atomic/FormElements/Input/Input.js +30 -10
- package/dist/Atomic/FormElements/InputCalendar/InputCalendar.js +6 -4
- package/dist/Atomic/FormElements/InputCalendar/InputCalendar.stories.js +3 -2
- package/dist/Atomic/FormElements/InputDateRange/InputDateRange.js +8 -2
- package/dist/Atomic/FormElements/InputDateRange/InputDateRange.stories.js +2 -0
- package/dist/Atomic/FormElements/InputDateRange/components/Datepicker.js +35 -20
- package/dist/Atomic/FormElements/InputDateRange/components/OpenedPart.js +8 -2
- package/dist/Atomic/FormElements/InputDateRange/dependencies.js +1 -1
- package/dist/Atomic/FormElements/NumericInput/NumericInput.js +1 -0
- package/dist/Atomic/UI/Calendar/Calendar.js +89 -15
- package/dist/Atomic/UI/Calendar/Calendar.scss +52 -5
- package/dist/Atomic/UI/Calendar/Calendar.stories.js +20 -3
- package/package.json +1 -2
- package/src/Atomic/FormElements/Dropdown/Dropdown.js +72 -35
- package/src/Atomic/FormElements/Dropdown/Dropdown.scss +12 -0
- package/src/Atomic/FormElements/Dropdown/Dropdown.stories.js +23 -8
- package/src/Atomic/FormElements/Dropdown/components/DropdownLoader.js +17 -0
- package/src/Atomic/FormElements/Dropdown/components/Loader.scss +57 -0
- package/src/Atomic/FormElements/Input/Input.js +46 -33
- package/src/Atomic/FormElements/InputCalendar/InputCalendar.js +14 -8
- package/src/Atomic/FormElements/InputCalendar/InputCalendar.stories.js +7 -8
- package/src/Atomic/FormElements/InputDateRange/InputDateRange.js +5 -0
- package/src/Atomic/FormElements/InputDateRange/InputDateRange.stories.js +2 -0
- package/src/Atomic/FormElements/InputDateRange/components/Datepicker.js +41 -20
- package/src/Atomic/FormElements/InputDateRange/components/OpenedPart.js +5 -1
- package/src/Atomic/FormElements/InputDateRange/dependencies.js +1 -1
- package/src/Atomic/FormElements/NumericInput/NumericInput.js +1 -0
- package/src/Atomic/UI/Calendar/Calendar.js +80 -11
- package/src/Atomic/UI/Calendar/Calendar.scss +52 -5
- package/src/Atomic/UI/Calendar/Calendar.stories.js +9 -7
|
@@ -29,7 +29,7 @@ const Input = ({
|
|
|
29
29
|
icon,
|
|
30
30
|
symbolsLimit,
|
|
31
31
|
blinkTime,
|
|
32
|
-
isFocusDefault = false
|
|
32
|
+
isFocusDefault = false,
|
|
33
33
|
}) => {
|
|
34
34
|
const DEFAULT_BLINK_TIME = 100;
|
|
35
35
|
// STATES
|
|
@@ -42,6 +42,8 @@ const Input = ({
|
|
|
42
42
|
|
|
43
43
|
const { onlyNumbers, onlyString } = formatInput;
|
|
44
44
|
const { addCommas, removeComma } = formatInput.priceInput;
|
|
45
|
+
const isUseErrorsBlink = !isNotBlinkErrors && !mask;
|
|
46
|
+
|
|
45
47
|
// HANDLES
|
|
46
48
|
const handle = {
|
|
47
49
|
change: (e) => {
|
|
@@ -50,8 +52,7 @@ const Input = ({
|
|
|
50
52
|
inputValue = inputValue.substring(0, +symbolsLimit);
|
|
51
53
|
}
|
|
52
54
|
|
|
53
|
-
if (isOnlyNumber && !isTwoDigitAfterDot)
|
|
54
|
-
inputValue = onlyNumbers(inputValue);
|
|
55
|
+
if (isOnlyNumber && !isTwoDigitAfterDot) inputValue = onlyNumbers(inputValue);
|
|
55
56
|
if (isTwoDigitAfterDot) inputValue = onlyNumbers(inputValue, true);
|
|
56
57
|
if (isOnlyString) inputValue = onlyString(inputValue);
|
|
57
58
|
|
|
@@ -79,28 +80,47 @@ const Input = ({
|
|
|
79
80
|
if (onBlur) onBlur(e);
|
|
80
81
|
},
|
|
81
82
|
keyUp: (e) => {
|
|
82
|
-
if (
|
|
83
|
+
if (isUseErrorsBlink) {
|
|
83
84
|
const changedValue = '' + (value ?? '');
|
|
84
85
|
const previousValue = '' + (previousValueRef.current ?? '');
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
|
|
93
|
-
|
|
94
|
-
|
|
95
|
-
|
|
96
|
-
|
|
97
|
-
|
|
98
|
-
|
|
99
|
-
|
|
86
|
+
|
|
87
|
+
const short = previousValue.length <= changedValue.length ? previousValue : changedValue;
|
|
88
|
+
const long = previousValue.length > changedValue.length ? previousValue : changedValue;
|
|
89
|
+
|
|
90
|
+
const infoAboutDifferencesSameness = short.split('').reduce(
|
|
91
|
+
(acc, symbol, idx) => {
|
|
92
|
+
if (acc.countOn && symbol === long[idx]) acc.same.push(symbol);
|
|
93
|
+
else {
|
|
94
|
+
acc.countOn = false;
|
|
95
|
+
acc.differences.push([idx, symbol]);
|
|
96
|
+
}
|
|
97
|
+
return acc;
|
|
98
|
+
},
|
|
99
|
+
{ same: [], countOn: true, differences: [] }
|
|
100
|
+
);
|
|
101
|
+
|
|
102
|
+
const samePart = infoAboutDifferencesSameness.same.join('');
|
|
103
|
+
const differencesLength = infoAboutDifferencesSameness.differences.length;
|
|
104
|
+
const currentSet = changedValue.replace(samePart, '');
|
|
105
|
+
|
|
106
|
+
const getNext = (inputPartToAdd, correctedSamePart) => {
|
|
107
|
+
const partToAdd = inputPartToAdd || currentSet;
|
|
108
|
+
const currentSamePart = correctedSamePart || samePart;
|
|
109
|
+
return changedValue.includes(e.key) && e.key !== changedValue[changedValue.length - 1]
|
|
110
|
+
? currentSamePart + (partToAdd[0] || '')
|
|
111
|
+
: changedValue;
|
|
112
|
+
};
|
|
113
|
+
|
|
114
|
+
if (!KEYBOARD_SERVICE_KEYS.includes(e.key) && changedValue === previousValue)
|
|
115
|
+
setIsAttemptToChange(!(!differencesLength && e.key === changedValue[changedValue.length - 2]));
|
|
116
|
+
|
|
117
|
+
if (!previousValueRef.current || KEYBOARD_SERVICE_KEYS.includes(e.key)) previousValueRef.current = getNext();
|
|
118
|
+
else if (changedValue === samePart) previousValueRef.current = getNext(changedValue, changedValue.slice(0, -1));
|
|
119
|
+
else previousValueRef.current = getNext();
|
|
100
120
|
}
|
|
101
121
|
|
|
102
122
|
if (onKeyUp) onKeyUp(e.keyCode, e);
|
|
103
|
-
}
|
|
123
|
+
},
|
|
104
124
|
};
|
|
105
125
|
|
|
106
126
|
function cutOffsingleDot(value) {
|
|
@@ -121,7 +141,7 @@ const Input = ({
|
|
|
121
141
|
onBlur: handle.blur,
|
|
122
142
|
onKeyUp: handle.keyUp,
|
|
123
143
|
...(maskChar ? { maskChar } : {}),
|
|
124
|
-
...(formatChars ? { formatChars } : {})
|
|
144
|
+
...(formatChars ? { formatChars } : {}),
|
|
125
145
|
};
|
|
126
146
|
|
|
127
147
|
function renderInput() {
|
|
@@ -129,13 +149,11 @@ const Input = ({
|
|
|
129
149
|
return <InputMask {...uniProps} ref={inputRef} mask={mask} />;
|
|
130
150
|
}
|
|
131
151
|
|
|
132
|
-
return
|
|
133
|
-
<input {...uniProps} ref={inputRef} type={isPriceInput ? 'text' : type} />
|
|
134
|
-
);
|
|
152
|
+
return <input {...uniProps} ref={inputRef} type={isPriceInput ? 'text' : type} />;
|
|
135
153
|
}
|
|
136
154
|
|
|
137
155
|
useEffect(() => {
|
|
138
|
-
if (
|
|
156
|
+
if (isUseErrorsBlink && isAttemptToChange) {
|
|
139
157
|
setIsAttemptToChange(null);
|
|
140
158
|
setIsToHighlightError(true);
|
|
141
159
|
setTimeout(() => {
|
|
@@ -145,8 +163,8 @@ const Input = ({
|
|
|
145
163
|
}, [isAttemptToChange]);
|
|
146
164
|
|
|
147
165
|
useEffect(() => {
|
|
148
|
-
if (inputRef?.current && typeof isFocusDefault === 'boolean')
|
|
149
|
-
|
|
166
|
+
if (inputRef?.current && typeof isFocusDefault === 'boolean') setIsFocused(isFocusDefault);
|
|
167
|
+
setEditing(isFocusDefault);
|
|
150
168
|
}, [inputRef, isFocusDefault]);
|
|
151
169
|
|
|
152
170
|
return (
|
|
@@ -160,12 +178,7 @@ const Input = ({
|
|
|
160
178
|
>
|
|
161
179
|
{renderInput()}
|
|
162
180
|
{icon}
|
|
163
|
-
{withDelete && (
|
|
164
|
-
<span
|
|
165
|
-
className={cn(`input__close`, { hidden: !value })}
|
|
166
|
-
onClick={handle.toggleEdit}
|
|
167
|
-
/>
|
|
168
|
-
)}
|
|
181
|
+
{withDelete && <span className={cn(`input__close`, { hidden: !value })} onClick={handle.toggleEdit} />}
|
|
169
182
|
</div>
|
|
170
183
|
);
|
|
171
184
|
};
|
|
@@ -4,27 +4,27 @@ import InputMask from 'react-input-mask';
|
|
|
4
4
|
import Calendar from '../../UI/Calendar/Calendar';
|
|
5
5
|
import { useClickOutside } from '../../../Functions/useClickOutside';
|
|
6
6
|
|
|
7
|
-
const InputCalendar = ({ value, minDate, maxDate, onChange, className = '', placeholder = 'mm/dd/yyyy', mask = '99/99/9999' }) => {
|
|
7
|
+
const InputCalendar = ({ value, minDate, maxDate, onChange, className = '', placeholder = 'mm/dd/yyyy', mask = '99/99/9999', dontLimitFuture }) => {
|
|
8
8
|
const [isOpened, setIsOpened] = useState(false);
|
|
9
9
|
const calendarRef = useRef(null);
|
|
10
10
|
|
|
11
11
|
useClickOutside(calendarRef, () => setIsOpened(false));
|
|
12
12
|
|
|
13
|
-
const changeInputValue = val => {
|
|
13
|
+
const changeInputValue = (val) => {
|
|
14
14
|
if (onChange) onChange(val);
|
|
15
15
|
};
|
|
16
16
|
|
|
17
|
-
const changeCalendarDay = val => {
|
|
17
|
+
const changeCalendarDay = (val) => {
|
|
18
18
|
if (onChange) onChange(val);
|
|
19
19
|
};
|
|
20
20
|
|
|
21
21
|
const getCalendarValue = (value) => {
|
|
22
22
|
const date = moment(value).format('L');
|
|
23
23
|
|
|
24
|
-
if(date !==
|
|
24
|
+
if (date !== 'Invalid date') return date;
|
|
25
25
|
|
|
26
26
|
return moment(new Date()).format('L');
|
|
27
|
-
}
|
|
27
|
+
};
|
|
28
28
|
|
|
29
29
|
return (
|
|
30
30
|
<div className={`input__wrap calendar-container ${className}`} ref={calendarRef}>
|
|
@@ -32,12 +32,18 @@ const InputCalendar = ({ value, minDate, maxDate, onChange, className = '', plac
|
|
|
32
32
|
mask={mask}
|
|
33
33
|
placeholder={placeholder}
|
|
34
34
|
value={value}
|
|
35
|
-
onChange={e => changeInputValue(e.target.value)}
|
|
35
|
+
onChange={(e) => changeInputValue(e.target.value)}
|
|
36
36
|
className="calendar-dropdown"
|
|
37
37
|
onFocus={() => setIsOpened(!isOpened)}
|
|
38
38
|
/>
|
|
39
|
-
{
|
|
40
|
-
|
|
39
|
+
{isOpened ? (
|
|
40
|
+
<Calendar
|
|
41
|
+
date={getCalendarValue(value)}
|
|
42
|
+
setDate={(newDate) => changeCalendarDay(newDate)}
|
|
43
|
+
params={{ minDate, maxDate }}
|
|
44
|
+
dontLimitFuture={dontLimitFuture}
|
|
45
|
+
/>
|
|
46
|
+
) : null}
|
|
41
47
|
</div>
|
|
42
48
|
);
|
|
43
49
|
};
|
|
@@ -3,28 +3,27 @@ import InputCalendar from './InputCalendar';
|
|
|
3
3
|
|
|
4
4
|
global.lng = 'en';
|
|
5
5
|
|
|
6
|
-
|
|
7
6
|
export default {
|
|
8
7
|
title: 'Form Elements/Input Calendar',
|
|
9
8
|
component: InputCalendar,
|
|
10
9
|
argTypes: {
|
|
11
10
|
value: {
|
|
12
|
-
description: 'string (mm.dd.yyyy)'
|
|
11
|
+
description: 'string (mm.dd.yyyy)',
|
|
13
12
|
},
|
|
14
|
-
}
|
|
13
|
+
},
|
|
15
14
|
};
|
|
16
15
|
|
|
17
|
-
const Template = args => {
|
|
16
|
+
const Template = (args) => {
|
|
18
17
|
const [date, setDate] = useState('');
|
|
19
18
|
|
|
20
|
-
return <InputCalendar {...args} value={date} onChange={val => setDate(val)} />;
|
|
19
|
+
return <InputCalendar {...args} value={date} onChange={(val) => setDate(val)} />;
|
|
21
20
|
};
|
|
22
21
|
|
|
23
22
|
export const CalendarTemplate = Template.bind({});
|
|
24
23
|
|
|
25
24
|
CalendarTemplate.args = {
|
|
26
25
|
value: '',
|
|
27
|
-
minDate: '10/14/2020',
|
|
28
|
-
maxDate: '10/14/2022',
|
|
29
|
-
|
|
26
|
+
// minDate: '10/14/2020',
|
|
27
|
+
// maxDate: '10/14/2022',
|
|
28
|
+
dontLimitFuture: true,
|
|
30
29
|
};
|
|
@@ -24,6 +24,8 @@ const InputDateRange = props => {
|
|
|
24
24
|
hideArrows = false,
|
|
25
25
|
isOptionsRight,
|
|
26
26
|
isUseAbs,
|
|
27
|
+
minDate = null,
|
|
28
|
+
maxDate = null,
|
|
27
29
|
} = props;
|
|
28
30
|
|
|
29
31
|
const actualValues = getActualDateRange(value);
|
|
@@ -35,6 +37,7 @@ const InputDateRange = props => {
|
|
|
35
37
|
const internalContainerRef = useRef(null);
|
|
36
38
|
|
|
37
39
|
const handleChange = input => {
|
|
40
|
+
|
|
38
41
|
const newValue = getActualDateRange(input);
|
|
39
42
|
const formatedValue = {
|
|
40
43
|
intervalKey: newValue.intervalKey,
|
|
@@ -202,6 +205,8 @@ const InputDateRange = props => {
|
|
|
202
205
|
setIsCompare={setIsCompare}
|
|
203
206
|
toggleOff={toggleOff}
|
|
204
207
|
onChange={handleChange}
|
|
208
|
+
minDate={minDate ? moment(minDate) : null}
|
|
209
|
+
maxDate={maxDate ? moment(maxDate) : null}
|
|
205
210
|
/>
|
|
206
211
|
)}
|
|
207
212
|
</div>
|
|
@@ -41,7 +41,9 @@ const Datepicker = props => {
|
|
|
41
41
|
limitRange,
|
|
42
42
|
handleItemClick,
|
|
43
43
|
setActiveInterval,
|
|
44
|
-
isShortWeekNames
|
|
44
|
+
isShortWeekNames,
|
|
45
|
+
minDate = null,
|
|
46
|
+
maxDate = null
|
|
45
47
|
} = props;
|
|
46
48
|
const { start = null, end = null, compare = false } = values;
|
|
47
49
|
const startDateInputRef = useRef(null);
|
|
@@ -191,7 +193,7 @@ const Datepicker = props => {
|
|
|
191
193
|
const handleChangeStartHour = val => {
|
|
192
194
|
setStartHour(+val);
|
|
193
195
|
setStartDate(
|
|
194
|
-
moment(startDate)
|
|
196
|
+
moment(startDate || moment())
|
|
195
197
|
.set('hour', +val)
|
|
196
198
|
.toDate(),
|
|
197
199
|
);
|
|
@@ -200,14 +202,16 @@ const Datepicker = props => {
|
|
|
200
202
|
const handleChangeEndHour = val => {
|
|
201
203
|
const newHour = +val;
|
|
202
204
|
setEndHour(newHour);
|
|
203
|
-
let newEndDate;
|
|
204
|
-
|
|
205
|
-
|
|
206
|
-
|
|
207
|
-
|
|
208
|
-
|
|
209
|
-
|
|
205
|
+
let newEndDate = moment();
|
|
206
|
+
|
|
207
|
+
if(endDate){
|
|
208
|
+
if (prevEndHour.current === 0 && newHour !== 0) {
|
|
209
|
+
newEndDate = moment(endDate).subtract(1, 'days');
|
|
210
|
+
} else if (prevEndHour.current !== 0 && newHour === 0) {
|
|
211
|
+
newEndDate = moment(endDate).add(1, 'days');
|
|
212
|
+
}
|
|
210
213
|
}
|
|
214
|
+
|
|
211
215
|
prevEndHour.current = newHour;
|
|
212
216
|
setEndDate(moment(newEndDate).set('hour', newHour).toDate());
|
|
213
217
|
};
|
|
@@ -256,13 +260,22 @@ const Datepicker = props => {
|
|
|
256
260
|
|
|
257
261
|
const handleStartDateBlur = e => {
|
|
258
262
|
let newDate;
|
|
259
|
-
|
|
260
|
-
|
|
261
|
-
|
|
263
|
+
|
|
264
|
+
if(!moment(startDateInput).isValid()){
|
|
265
|
+
newDate = startDate;
|
|
262
266
|
} else {
|
|
263
|
-
|
|
264
|
-
|
|
267
|
+
if(minDate && !moment(startDateInput).isSameOrAfter(minDate)){
|
|
268
|
+
newDate = minDate;
|
|
269
|
+
} else if(maxDate && !moment(startDateInput).isSameOrBefore(maxDate)){
|
|
270
|
+
newDate = maxDate;
|
|
271
|
+
} else {
|
|
272
|
+
newDate = moment(startDateInput);
|
|
273
|
+
}
|
|
265
274
|
}
|
|
275
|
+
|
|
276
|
+
setStartDateInput(newDate);
|
|
277
|
+
setStartDate(newDate.set('hour', parseInt(startHour, 10)).toDate());
|
|
278
|
+
|
|
266
279
|
doBlur('start', e);
|
|
267
280
|
setDate1(
|
|
268
281
|
moment(newDate).isSameOrAfter(moment(date2), 'month') ? moment(date2).subtract(1, 'month') : moment(newDate),
|
|
@@ -277,16 +290,24 @@ const Datepicker = props => {
|
|
|
277
290
|
|
|
278
291
|
const handleEndDateBlur = e => {
|
|
279
292
|
let newDate;
|
|
280
|
-
|
|
281
|
-
|
|
282
|
-
|
|
293
|
+
|
|
294
|
+
if(!moment(endDateInput).isValid()){
|
|
295
|
+
newDate = endDate;
|
|
283
296
|
} else {
|
|
284
|
-
|
|
285
|
-
|
|
297
|
+
if(minDate && !moment(endDateInput).isSameOrAfter(minDate)){
|
|
298
|
+
newDate = minDate;
|
|
299
|
+
} else if(maxDate && !moment(endDateInput).isSameOrBefore(maxDate)){
|
|
300
|
+
newDate = maxDate;
|
|
301
|
+
} else {
|
|
302
|
+
newDate = moment(endDateInput);
|
|
303
|
+
}
|
|
286
304
|
}
|
|
305
|
+
|
|
306
|
+
setEndDate(addDay(newDate.set('hour', parseInt(endHour, 10)).toDate()));
|
|
307
|
+
setEndDateInput(newDate);
|
|
308
|
+
|
|
287
309
|
doBlur('end', e);
|
|
288
310
|
setDate2(newDate);
|
|
289
|
-
setEndDateInput();
|
|
290
311
|
};
|
|
291
312
|
|
|
292
313
|
const handleKeyPressed = (code, e, type) => {
|
|
@@ -25,7 +25,9 @@ const OpenedPart = React.forwardRef((props, ref) => {
|
|
|
25
25
|
isCompare,
|
|
26
26
|
setIsCompare,
|
|
27
27
|
toggleOff,
|
|
28
|
-
isShortWeekNames
|
|
28
|
+
isShortWeekNames,
|
|
29
|
+
minDate = null,
|
|
30
|
+
maxDate = null
|
|
29
31
|
} = props;
|
|
30
32
|
|
|
31
33
|
const items = isCompact ? [...Object.keys(intervals)] : [...Object.keys(intervals), customKey];
|
|
@@ -105,6 +107,8 @@ const OpenedPart = React.forwardRef((props, ref) => {
|
|
|
105
107
|
limitRange={limitRange}
|
|
106
108
|
setActiveInterval={setActiveInterval}
|
|
107
109
|
isShortWeekNames={isShortWeekNames}
|
|
110
|
+
minDate={minDate}
|
|
111
|
+
maxDate={maxDate}
|
|
108
112
|
/>
|
|
109
113
|
)}
|
|
110
114
|
</div>
|
|
@@ -1,22 +1,34 @@
|
|
|
1
|
+
import React, { useEffect, useMemo, useState, useRef } from 'react';
|
|
1
2
|
import cn from 'classnames';
|
|
2
|
-
import React, { useEffect, useMemo, useState } from 'react';
|
|
3
3
|
import moment from 'moment';
|
|
4
|
+
import InputMask from 'react-input-mask';
|
|
4
5
|
import { ChevronLeft, ChevronRight } from 'react-feather';
|
|
5
6
|
import './Calendar.scss';
|
|
6
7
|
|
|
7
8
|
export default function (props) {
|
|
8
|
-
const { date, setDate, allowPrev = true, allowNext = true, params, className } = props;
|
|
9
|
-
const { minDate = '01/01/1900', maxDate = moment().format('MM/DD/YYYY') } = params;
|
|
9
|
+
const { date, setDate, allowPrev = true, allowNext = true, params, className, dontLimitFuture } = props;
|
|
10
|
+
// const { minDate = '01/01/1900', maxDate = moment().format('MM/DD/YYYY') } = params;
|
|
11
|
+
const { minDate, maxDate } = params;
|
|
10
12
|
const [days, setDays] = useState({});
|
|
11
13
|
const [showDate, setShowDate] = useState(date);
|
|
14
|
+
const [isChangeYear, setIsChangeYear] = useState(false);
|
|
15
|
+
const [inputYearValue, setInputYearValue] = useState(moment(showDate).format('YYYY'));
|
|
16
|
+
const yearInputRef = useRef(null);
|
|
12
17
|
|
|
13
18
|
const selectedDay = moment(showDate);
|
|
14
19
|
const isError = 'Invalid date';
|
|
15
20
|
|
|
16
|
-
const title = useMemo(
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
);
|
|
21
|
+
// const title = useMemo(
|
|
22
|
+
// () => (selectedDay.format('MMM') === isError ? isError : `${selectedDay.format('MMM')} ${moment(showDate).format('YYYY')}`),
|
|
23
|
+
// [date, showDate]
|
|
24
|
+
// );
|
|
25
|
+
|
|
26
|
+
const showMonth = useMemo(() => moment(showDate).format('MMM'), [date, showDate]);
|
|
27
|
+
const showYear = useMemo(() => moment(showDate).format('YYYY'), [date, showDate]);
|
|
28
|
+
|
|
29
|
+
console.log('date - ', date);
|
|
30
|
+
console.log('showDate - ', showDate);
|
|
31
|
+
|
|
20
32
|
useEffect(() => {
|
|
21
33
|
const result = {};
|
|
22
34
|
const day = selectedDay.startOf('month');
|
|
@@ -40,10 +52,13 @@ export default function (props) {
|
|
|
40
52
|
const isFutureDay = day && maxDate ? moment(day.date).isAfter(moment(maxDate || ''), 'day') : moment(day.date).isAfter(moment(), 'day');
|
|
41
53
|
const isBeforeDay = day && moment(day.date).isBefore(moment(minDate || ''), 'day');
|
|
42
54
|
|
|
55
|
+
console.log('isFutureDay - ', isFutureDay);
|
|
56
|
+
console.log('isBeforeDay - ', isBeforeDay);
|
|
57
|
+
|
|
43
58
|
const classNames = cn(
|
|
44
59
|
'calendar__day',
|
|
45
60
|
{ 'calendar__day--clickable': day },
|
|
46
|
-
{ 'calendar__day--disabled': isFutureDay },
|
|
61
|
+
{ 'calendar__day--disabled': !dontLimitFuture && isFutureDay },
|
|
47
62
|
{ 'calendar__day--disabled': isBeforeDay },
|
|
48
63
|
{ 'calendar__day--selected': moment(date).format() === moment(day.date).format() }
|
|
49
64
|
);
|
|
@@ -52,7 +67,7 @@ export default function (props) {
|
|
|
52
67
|
<div
|
|
53
68
|
key={`${week}_${dayOfWeek}`}
|
|
54
69
|
className={classNames}
|
|
55
|
-
onClick={day && !isFutureDay ? () => setDate(moment(day.date).format('L')) : null}
|
|
70
|
+
onClick={day && (dontLimitFuture || !isFutureDay) ? () => setDate(moment(day.date).format('L')) : null}
|
|
56
71
|
// onMouseOver={day && !isFutureDay ? () => onHover(day.date) : null}
|
|
57
72
|
// onMouseLeave={() => onHover(null)}
|
|
58
73
|
>
|
|
@@ -69,8 +84,35 @@ export default function (props) {
|
|
|
69
84
|
setShowDate(moment(showDate).add(1, 'month').format('L'));
|
|
70
85
|
};
|
|
71
86
|
|
|
87
|
+
const closeYearInput = () => {
|
|
88
|
+
const newDate = (() => {
|
|
89
|
+
const dateArr = showDate.split('/');
|
|
90
|
+
const oldYear = dateArr[2];
|
|
91
|
+
dateArr[2] = inputYearValue;
|
|
92
|
+
return moment(dateArr.join('/')).format('MM/DD/YYYY') === isError ? showDate : moment(dateArr.join('/')).format('MM/DD/YYYY');
|
|
93
|
+
})();
|
|
94
|
+
let resultDate = newDate;
|
|
95
|
+
if (minDate && moment(minDate) > moment(newDate)) resultDate = moment(showDate).format('MM/DD/YYYY');
|
|
96
|
+
else if (maxDate && moment(maxDate) < moment(newDate)) resultDate = moment(showDate).format('MM/DD/YYYY');
|
|
97
|
+
|
|
98
|
+
setIsChangeYear(false);
|
|
99
|
+
setShowDate(resultDate);
|
|
100
|
+
setInputYearValue(resultDate);
|
|
101
|
+
};
|
|
102
|
+
|
|
103
|
+
useEffect(() => {
|
|
104
|
+
if (isChangeYear && yearInputRef.current) {
|
|
105
|
+
const input = yearInputRef.current.getElementsByTagName('input')[0];
|
|
106
|
+
setInputYearValue(showYear);
|
|
107
|
+
setTimeout(() => {
|
|
108
|
+
input.focus();
|
|
109
|
+
input.select();
|
|
110
|
+
}, 0);
|
|
111
|
+
}
|
|
112
|
+
}, [isChangeYear]);
|
|
113
|
+
|
|
72
114
|
return (
|
|
73
|
-
<div className={`calendar ${className ? className :
|
|
115
|
+
<div className={`calendar ${className ? className : ''}`}>
|
|
74
116
|
<div className="calendar-header">
|
|
75
117
|
<div className="calendar-header__prev">
|
|
76
118
|
{allowPrev && (
|
|
@@ -79,7 +121,34 @@ export default function (props) {
|
|
|
79
121
|
</div>
|
|
80
122
|
)}
|
|
81
123
|
</div>
|
|
82
|
-
<div className=
|
|
124
|
+
<div className={cn('calendar-header__title')} ref={yearInputRef}>
|
|
125
|
+
<span className="calendar-header__title-month">{`${showMonth} `}</span>
|
|
126
|
+
<span
|
|
127
|
+
className={cn('calendar-header__title-year', {
|
|
128
|
+
'calendar-header__title-year_change-mode': isChangeYear,
|
|
129
|
+
})}
|
|
130
|
+
onClick={() => setIsChangeYear(true)}
|
|
131
|
+
>
|
|
132
|
+
{isChangeYear ? (
|
|
133
|
+
<InputMask
|
|
134
|
+
className="calendar-header__title-year-change-input"
|
|
135
|
+
value={inputYearValue}
|
|
136
|
+
mask="9999"
|
|
137
|
+
onBlur={(e) => closeYearInput()}
|
|
138
|
+
onKeyUp={(e) => {
|
|
139
|
+
if (e.key === 'Escape') setIsChangeYear(false);
|
|
140
|
+
if (e.key === 'Enter') closeYearInput();
|
|
141
|
+
}}
|
|
142
|
+
onChange={(e) => {
|
|
143
|
+
console.log(e.target.value);
|
|
144
|
+
setInputYearValue(e.target.value);
|
|
145
|
+
}}
|
|
146
|
+
/>
|
|
147
|
+
) : (
|
|
148
|
+
`${showYear}`
|
|
149
|
+
)}
|
|
150
|
+
</span>
|
|
151
|
+
</div>
|
|
83
152
|
<div className="calendar-header__next">
|
|
84
153
|
{allowNext && (
|
|
85
154
|
<div onClick={handleNext}>
|
|
@@ -431,17 +431,18 @@
|
|
|
431
431
|
align-items: center;
|
|
432
432
|
|
|
433
433
|
&__prev,
|
|
434
|
-
&__next{
|
|
434
|
+
&__next {
|
|
435
435
|
display: flex;
|
|
436
436
|
height: auto;
|
|
437
|
+
cursor: pointer;
|
|
437
438
|
}
|
|
438
439
|
}
|
|
439
440
|
.calendar {
|
|
440
441
|
background: #ffffff;
|
|
441
|
-
|
|
442
|
-
|
|
443
|
-
|
|
444
|
-
|
|
442
|
+
border: 1px solid #e2e5ec;
|
|
443
|
+
box-shadow: 0 5px 20px rgb(0 0 0 / 15%);
|
|
444
|
+
margin-top: 4px;
|
|
445
|
+
padding: 5px 0;
|
|
445
446
|
|
|
446
447
|
min-height: 195px;
|
|
447
448
|
width: 260px;
|
|
@@ -449,6 +450,52 @@
|
|
|
449
450
|
flex-direction: column;
|
|
450
451
|
user-select: none;
|
|
451
452
|
|
|
453
|
+
&-header {
|
|
454
|
+
box-sizing: border-box;
|
|
455
|
+
&__title {
|
|
456
|
+
&-month {
|
|
457
|
+
margin-right: 5px;
|
|
458
|
+
}
|
|
459
|
+
&-year {
|
|
460
|
+
box-sizing: border-box;
|
|
461
|
+
width: 45px;
|
|
462
|
+
height: 100%;
|
|
463
|
+
padding: 0 5px;
|
|
464
|
+
cursor: pointer;
|
|
465
|
+
display: flex;
|
|
466
|
+
flex-flow: row nowrap;
|
|
467
|
+
justify-content: center;
|
|
468
|
+
align-items: center;
|
|
469
|
+
|
|
470
|
+
&:hover:not(.calendar-header__title-year_change-mode) {
|
|
471
|
+
text-decoration: underline;
|
|
472
|
+
}
|
|
473
|
+
|
|
474
|
+
&.calendar-header__title-year_change-mode {
|
|
475
|
+
height: 24px;
|
|
476
|
+
padding: 0 3px;
|
|
477
|
+
border-style: solid;
|
|
478
|
+
border-width: 1px;
|
|
479
|
+
border-color: inherit;
|
|
480
|
+
border-radius: var(--border-radius);
|
|
481
|
+
}
|
|
482
|
+
|
|
483
|
+
&-change-input {
|
|
484
|
+
box-sizing: border-box;
|
|
485
|
+
width: 100%;
|
|
486
|
+
border: none;
|
|
487
|
+
outline: none;
|
|
488
|
+
margin: 0;
|
|
489
|
+
padding: 0;
|
|
490
|
+
display: inline;
|
|
491
|
+
font-size: inherit;
|
|
492
|
+
line-height: inherit;
|
|
493
|
+
font-weight: inherit;
|
|
494
|
+
}
|
|
495
|
+
}
|
|
496
|
+
}
|
|
497
|
+
}
|
|
498
|
+
|
|
452
499
|
&__week {
|
|
453
500
|
display: flex;
|
|
454
501
|
}
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import React from 'react';
|
|
1
|
+
import React, { useState } from 'react';
|
|
2
2
|
import Calendar from './Calendar';
|
|
3
3
|
|
|
4
4
|
global.lng = 'en';
|
|
@@ -8,16 +8,18 @@ export default {
|
|
|
8
8
|
component: Calendar,
|
|
9
9
|
};
|
|
10
10
|
|
|
11
|
-
const Template = args =>
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
11
|
+
const Template = args => {
|
|
12
|
+
const [date, setDate] = useState('12/03/2021');
|
|
13
|
+
return (
|
|
14
|
+
<div style={{ width: '320px' }}>
|
|
15
|
+
<Calendar {...args} date={date} setDate={setDate} />
|
|
16
|
+
</div>
|
|
17
|
+
);
|
|
18
|
+
};
|
|
16
19
|
|
|
17
20
|
export const CalendarTemplate = Template.bind({});
|
|
18
21
|
|
|
19
22
|
CalendarTemplate.args = {
|
|
20
|
-
date: '12/03/2021',
|
|
21
23
|
params: {},
|
|
22
24
|
setDate: () => null,
|
|
23
25
|
className: ''
|