@dvrd/dvr-controls 1.1.33 → 1.1.35
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/index.ts +1 -0
- package/package.json +6 -5
- package/src/js/date/dvrdDatePicker.tsx +78 -85
package/index.ts
CHANGED
|
@@ -132,6 +132,7 @@ export * from './src/js/util/jwtUtil';
|
|
|
132
132
|
export * from './src/js/util/responsiveUtil';
|
|
133
133
|
export * from './src/js/util/validationUtil';
|
|
134
134
|
export * from './src/js/util/interfaces';
|
|
135
|
+
export * from './src/js/util/types';
|
|
135
136
|
export * from './src/js/util/requestUtil';
|
|
136
137
|
export * from './src/js/util/constants';
|
|
137
138
|
export * from './src/js/util/cookieUtil';
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@dvrd/dvr-controls",
|
|
3
|
-
"version": "1.1.
|
|
3
|
+
"version": "1.1.35",
|
|
4
4
|
"description": "Custom web controls",
|
|
5
5
|
"main": "index.ts",
|
|
6
6
|
"files": [
|
|
@@ -39,6 +39,7 @@
|
|
|
39
39
|
"react": "*",
|
|
40
40
|
"react-color": "^2.19.3",
|
|
41
41
|
"react-dom": "*",
|
|
42
|
+
"typescript": "5.9.3",
|
|
42
43
|
"uuid": "*"
|
|
43
44
|
},
|
|
44
45
|
"dependencies": {
|
|
@@ -59,14 +60,14 @@
|
|
|
59
60
|
"@fortawesome/free-solid-svg-icons": "*",
|
|
60
61
|
"@fortawesome/react-fontawesome": "*",
|
|
61
62
|
"@types/react": "*",
|
|
63
|
+
"@types/react-color": "^3.0.13",
|
|
62
64
|
"@types/react-dom": "*",
|
|
63
65
|
"@types/react-router": "*",
|
|
64
|
-
"@types/react-color": "^3.0.13",
|
|
65
66
|
"react": "*",
|
|
66
67
|
"react-color": "^2.19.3",
|
|
67
68
|
"react-dom": "*",
|
|
68
69
|
"react-router": "*",
|
|
69
|
-
"
|
|
70
|
-
"
|
|
70
|
+
"typescript": "*",
|
|
71
|
+
"uuid": "*"
|
|
71
72
|
}
|
|
72
|
-
}
|
|
73
|
+
}
|
|
@@ -5,15 +5,7 @@ import './style/dvrdDatePicker.scss';
|
|
|
5
5
|
|
|
6
6
|
import classNames from 'classnames';
|
|
7
7
|
import React, {
|
|
8
|
-
ForwardedRef,
|
|
9
|
-
forwardRef,
|
|
10
|
-
Fragment,
|
|
11
|
-
MouseEventHandler,
|
|
12
|
-
useEffect,
|
|
13
|
-
useImperativeHandle,
|
|
14
|
-
useMemo,
|
|
15
|
-
useRef,
|
|
16
|
-
useState
|
|
8
|
+
ForwardedRef, forwardRef, Fragment, MouseEventHandler, useEffect, useImperativeHandle, useMemo, useRef, useState
|
|
17
9
|
} from 'react';
|
|
18
10
|
import {ChangeFunction, DatePickerTimeMode, ErrorType} from '../util/interfaces';
|
|
19
11
|
import AwesomeIcon from '../icon/awesomeIcon';
|
|
@@ -21,7 +13,7 @@ import WithBackground from '../popup/withBackground';
|
|
|
21
13
|
import DvrdButton from '../button/dvrdButton';
|
|
22
14
|
import {generateComponentId} from '../util/componentUtil';
|
|
23
15
|
import IDate from '@dvrd/idate';
|
|
24
|
-
import {pad} from '../util/controlUtil';
|
|
16
|
+
import {pad, padNum} from '../util/controlUtil';
|
|
25
17
|
import {Swiper, SwiperClass, SwiperSlide} from 'swiper/react';
|
|
26
18
|
import {FreeMode, Mousewheel} from 'swiper/modules';
|
|
27
19
|
import 'swiper/css';
|
|
@@ -45,7 +37,7 @@ interface Props {
|
|
|
45
37
|
pickersOnly?: boolean;
|
|
46
38
|
}
|
|
47
39
|
|
|
48
|
-
export type DVRDDatePickerRef = {
|
|
40
|
+
export type DVRDDatePickerRef = {onOpen: VoidFunction; onClose: VoidFunction;}
|
|
49
41
|
|
|
50
42
|
function DvrdDatePicker(props: Props, ref: ForwardedRef<DVRDDatePickerRef>) {
|
|
51
43
|
const {
|
|
@@ -138,38 +130,72 @@ interface DatePickerProps {
|
|
|
138
130
|
min?: IDate | string;
|
|
139
131
|
}
|
|
140
132
|
|
|
133
|
+
type Day = {
|
|
134
|
+
number: number;
|
|
135
|
+
value: IDate;
|
|
136
|
+
currentMonth: boolean;
|
|
137
|
+
}
|
|
138
|
+
|
|
139
|
+
const beforePadDays = [6, 0, 1, 2, 3, 4, 5];
|
|
140
|
+
|
|
141
|
+
function buildFirstDaysRow(firstDay: IDate): [Array<Day> | null, IDate] {
|
|
142
|
+
const padBeforeDays = beforePadDays[firstDay.weekday()];
|
|
143
|
+
if (!padBeforeDays) return [null, firstDay];
|
|
144
|
+
const firstRow: Array<Day> = [];
|
|
145
|
+
for (let offset = padBeforeDays; offset >= 1; offset -= 1) {
|
|
146
|
+
const dayValue = firstDay.subtract(offset, 'days');
|
|
147
|
+
firstRow.push({
|
|
148
|
+
number: dayValue.day(),
|
|
149
|
+
value: dayValue,
|
|
150
|
+
currentMonth: false
|
|
151
|
+
});
|
|
152
|
+
}
|
|
153
|
+
let secondRowFirstDay = firstDay.clone();
|
|
154
|
+
while (firstRow.length < 7) {
|
|
155
|
+
firstRow.push({
|
|
156
|
+
number: secondRowFirstDay.day(),
|
|
157
|
+
value: secondRowFirstDay,
|
|
158
|
+
currentMonth: true
|
|
159
|
+
});
|
|
160
|
+
secondRowFirstDay = secondRowFirstDay.add(1, 'day');
|
|
161
|
+
}
|
|
162
|
+
return [firstRow, secondRowFirstDay];
|
|
163
|
+
}
|
|
164
|
+
|
|
165
|
+
function buildDay(value: IDate, year: number, month: number): Day {
|
|
166
|
+
return {
|
|
167
|
+
number: value.day(),
|
|
168
|
+
value,
|
|
169
|
+
currentMonth: value.year() === year && value.month() === month
|
|
170
|
+
};
|
|
171
|
+
}
|
|
172
|
+
|
|
173
|
+
const daysToRender = 42; // Always render 6 rows of days
|
|
174
|
+
|
|
141
175
|
function DatePicker(props: DatePickerProps) {
|
|
142
176
|
const {min, max, alwaysShowArrows, open, onClose, value, onChange} = props;
|
|
143
177
|
const divRef = useRef<HTMLDivElement>(null);
|
|
144
178
|
const pickerValue = useMemo(() => value?.clone() ?? IDate.now(), [value]);
|
|
145
|
-
const
|
|
146
|
-
const
|
|
147
|
-
const
|
|
148
|
-
const
|
|
149
|
-
|
|
150
|
-
|
|
151
|
-
|
|
152
|
-
|
|
153
|
-
|
|
154
|
-
|
|
155
|
-
|
|
156
|
-
|
|
157
|
-
|
|
158
|
-
const lastWeekDay = pickerValue.day(daysInMonth).weekday();
|
|
159
|
-
const padDaysAfter = 7 - lastWeekDay;
|
|
160
|
-
for (let i = 0; i < padDaysAfter; i++)
|
|
161
|
-
padAfterDays.push(i + 1);
|
|
162
|
-
|
|
163
|
-
if (Math.ceil(padAfterDays.concat(days).concat(padBeforeDays).length / 7) < 6) {
|
|
164
|
-
let dayAfter = padAfterDays[padAfterDays.length - 1] + 1;
|
|
165
|
-
for (let i = 0; i < 7; i++)
|
|
166
|
-
padAfterDays.push(dayAfter++);
|
|
179
|
+
const days: Array<Day> = useMemo(() => {
|
|
180
|
+
const month = pickerValue.month();
|
|
181
|
+
const year = pickerValue.year();
|
|
182
|
+
const days: Array<Day> = [];
|
|
183
|
+
let firstDay = new IDate(`${year}-${padNum(month)}-01`);
|
|
184
|
+
const [firstRow, nextFirstDay] = buildFirstDaysRow(firstDay);
|
|
185
|
+
if (firstRow) days.push(...firstRow);
|
|
186
|
+
firstDay = nextFirstDay;
|
|
187
|
+
while (days.length < daysToRender) {
|
|
188
|
+
for (let ix = 0; ix < 7; ix++) {
|
|
189
|
+
days.push(buildDay(firstDay, year, month));
|
|
190
|
+
firstDay = firstDay.add(1, 'day');
|
|
191
|
+
}
|
|
167
192
|
}
|
|
168
|
-
|
|
193
|
+
|
|
194
|
+
return days;
|
|
169
195
|
}, [pickerValue]);
|
|
170
196
|
|
|
171
197
|
function onReduce(key: 'year' | 'month') {
|
|
172
|
-
return function
|
|
198
|
+
return function() {
|
|
173
199
|
let value = pickerValue.clone();
|
|
174
200
|
value = value.add(-1, key);
|
|
175
201
|
value = value.day(Math.min(value.daysInMonth(), value.day()));
|
|
@@ -178,7 +204,7 @@ function DatePicker(props: DatePickerProps) {
|
|
|
178
204
|
}
|
|
179
205
|
|
|
180
206
|
function onAdd(key: 'year' | 'month') {
|
|
181
|
-
return function
|
|
207
|
+
return function() {
|
|
182
208
|
let value = pickerValue.clone();
|
|
183
209
|
value = value.add(1, key);
|
|
184
210
|
value = value.day(Math.min(value.daysInMonth(), value.day()));
|
|
@@ -187,7 +213,7 @@ function DatePicker(props: DatePickerProps) {
|
|
|
187
213
|
}
|
|
188
214
|
|
|
189
215
|
function onResetSwitcher(key: 'year' | 'month') {
|
|
190
|
-
return function
|
|
216
|
+
return function() {
|
|
191
217
|
let value = pickerValue.clone();
|
|
192
218
|
if (key === 'year') value = value.year(IDate.now().year());
|
|
193
219
|
else value = value.month(IDate.now().month());
|
|
@@ -200,25 +226,9 @@ function DatePicker(props: DatePickerProps) {
|
|
|
200
226
|
onChange(true)(IDate.now());
|
|
201
227
|
}
|
|
202
228
|
|
|
203
|
-
function onSelectDay(day:
|
|
204
|
-
return function
|
|
205
|
-
|
|
206
|
-
if (day || value === null) {
|
|
207
|
-
pickValue = pickValue.day(day);
|
|
208
|
-
if (month !== undefined) pickValue = pickValue.month(month);
|
|
209
|
-
if (year !== undefined) pickValue = pickValue.year(year);
|
|
210
|
-
onChange(true)(pickValue);
|
|
211
|
-
}
|
|
212
|
-
};
|
|
213
|
-
}
|
|
214
|
-
|
|
215
|
-
function onSelectPadDay(day: number, kind: 'prev' | 'next') {
|
|
216
|
-
return function () {
|
|
217
|
-
let value = pickerValue.clone();
|
|
218
|
-
if (kind === 'prev') value = value.add(-1, 'month');
|
|
219
|
-
else value = value.add(1, 'month');
|
|
220
|
-
value = value.day(day);
|
|
221
|
-
onChange(true)(value);
|
|
229
|
+
function onSelectDay(day: Day) {
|
|
230
|
+
return function() {
|
|
231
|
+
onChange(true)(day.value);
|
|
222
232
|
};
|
|
223
233
|
}
|
|
224
234
|
|
|
@@ -267,14 +277,10 @@ function DatePicker(props: DatePickerProps) {
|
|
|
267
277
|
divRef.current?.classList.remove('switch-mount');
|
|
268
278
|
}
|
|
269
279
|
|
|
270
|
-
function dateIsDisabled(day:
|
|
280
|
+
function dateIsDisabled(day: Day) {
|
|
271
281
|
if (!min && !max) return false;
|
|
272
|
-
|
|
273
|
-
|
|
274
|
-
if (month !== undefined) pickValue = pickValue.month(month);
|
|
275
|
-
if (year !== undefined) pickValue = pickValue.year(year);
|
|
276
|
-
if (min && new IDate(min).isAfter(pickValue, 'day')) return true;
|
|
277
|
-
else if (max && new IDate(max).isBefore(pickValue, 'day')) return true;
|
|
282
|
+
if (min && new IDate(min).isAfter(day.value, 'day')) return true;
|
|
283
|
+
else if (max && new IDate(max).isBefore(day.value, 'day')) return true;
|
|
278
284
|
return false;
|
|
279
285
|
}
|
|
280
286
|
|
|
@@ -356,25 +362,17 @@ function DatePicker(props: DatePickerProps) {
|
|
|
356
362
|
} else {
|
|
357
363
|
document.removeEventListener('keydown', keyListener);
|
|
358
364
|
}
|
|
359
|
-
return function
|
|
365
|
+
return function() {
|
|
360
366
|
document.removeEventListener('keydown', keyListener);
|
|
361
367
|
};
|
|
362
368
|
}, [open]);
|
|
363
369
|
|
|
364
|
-
function renderDay(day:
|
|
365
|
-
|
|
366
|
-
let pickValue = pickerValue.clone();
|
|
367
|
-
if (type === 'prev')
|
|
368
|
-
pickValue = pickValue.subtract(1, 'month');
|
|
369
|
-
else if (type === 'next')
|
|
370
|
-
pickValue = pickValue.add(1, 'month');
|
|
371
|
-
const month = pickValue.month();
|
|
372
|
-
const year = pickValue.year();
|
|
373
|
-
const disabled = dateIsDisabled(day, month, year);
|
|
370
|
+
function renderDay(day: Day, index: number, onClick: MouseEventHandler, className?: string) {
|
|
371
|
+
const disabled = dateIsDisabled(day);
|
|
374
372
|
return (
|
|
375
373
|
<div className={classNames('day', disabled && 'disabled', className)}
|
|
376
374
|
onClick={disabled ? undefined : onClick} key={index}>
|
|
377
|
-
<span className='day-label'>{day}</span>
|
|
375
|
+
<span className='day-label'>{day.number}</span>
|
|
378
376
|
</div>
|
|
379
377
|
);
|
|
380
378
|
}
|
|
@@ -420,16 +418,11 @@ function DatePicker(props: DatePickerProps) {
|
|
|
420
418
|
<div className='day no-select'>
|
|
421
419
|
<span className='day-label'>Zo</span>
|
|
422
420
|
</div>
|
|
423
|
-
{
|
|
424
|
-
|
|
425
|
-
})}
|
|
426
|
-
{days.map((day: number, index: number) => {
|
|
427
|
-
const isSelected = day === pickerValue.day();
|
|
421
|
+
{days.map((day: Day, index: number) => {
|
|
422
|
+
const isSelected = day.value.isAt(pickerValue, 'day');
|
|
428
423
|
return renderDay(day, index, onSelectDay(day),
|
|
429
|
-
classNames(isSelected && 'selected', day === 0 && 'hide'
|
|
430
|
-
|
|
431
|
-
{padAfterDays.map((day: number, index: number) => {
|
|
432
|
-
return renderDay(day, index, onSelectPadDay(day, 'next'), 'pad', 'next');
|
|
424
|
+
classNames(isSelected && 'selected', day.number === 0 && 'hide',
|
|
425
|
+
!day.currentMonth && 'pad'));
|
|
433
426
|
})}
|
|
434
427
|
</div>
|
|
435
428
|
<div className='actions-container'>
|
|
@@ -461,7 +454,7 @@ function TimePicker(props: TimePickerProps) {
|
|
|
461
454
|
}
|
|
462
455
|
|
|
463
456
|
function onSlideChange(key: 'hour' | 'minute' | 'second') {
|
|
464
|
-
return function
|
|
457
|
+
return function(swiper: SwiperClass) {
|
|
465
458
|
if (key === 'hour') internalValue.current = internalValue.current.hours(swiper.realIndex);
|
|
466
459
|
if (key === 'minute') internalValue.current = internalValue.current.minutes(swiper.realIndex);
|
|
467
460
|
if (key === 'second') internalValue.current = internalValue.current.seconds(swiper.realIndex);
|