@coreui/react-pro 4.1.3 → 4.2.0-beta.1
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/README.md +1 -1
- package/dist/components/calendar/CCalendar.d.ts +106 -0
- package/dist/components/calendar/CCalendar.utils.d.ts +21 -0
- package/dist/components/datepicker/CDatePicker.d.ts +13 -0
- package/dist/components/daterangepicker/CDateRangePicker.d.ts +65 -0
- package/dist/components/dropdown/CDropdown.d.ts +10 -1
- package/dist/components/dropdown/CDropdownToggle.d.ts +4 -0
- package/dist/components/dropdown/CDropdownToggleCustom.d.ts +15 -0
- package/dist/components/picker/CPicker.d.ts +78 -0
- package/dist/components/smart-table/CSmartTableInterface.d.ts +0 -9
- package/dist/components/timepicker/CTimePicker.d.ts +45 -0
- package/dist/components/timepicker/CTimePicker.utils.d.ts +17 -0
- package/dist/components/timepicker/CTimePickerRollCol.d.ts +11 -0
- package/dist/index.d.ts +5 -1
- package/dist/index.es.js +2568 -718
- package/dist/index.es.js.map +1 -1
- package/dist/index.js +2849 -995
- package/dist/index.js.map +1 -1
- package/dist/utils/calendar.d.ts +21 -0
- package/dist/utils/time.d.ts +17 -0
- package/package.json +11 -8
- package/src/components/accordion/CAccordionButton.tsx +2 -1
- package/src/components/accordion/__tests__/__snapshots__/CAccordionButton.spec.tsx.snap +2 -0
- package/src/components/accordion/__tests__/__snapshots__/CAccordionHeader.spec.tsx.snap +2 -0
- package/src/components/calendar/CCalendar.tsx +528 -0
- package/src/components/calendar/__tests__/CCalendar.spec.tsx +9 -0
- package/src/components/calendar/__tests__/__snapshots__/CCalendar.spec.tsx.snap +573 -0
- package/src/components/datepicker/CDatePicker.tsx +50 -0
- package/src/components/datepicker/__tests__/CDatePicker.spec.tsx +9 -0
- package/src/components/datepicker/__tests__/__snapshots__/CDatePicker.spec.tsx.snap +617 -0
- package/src/components/daterangepicker/CDateRangePicker.tsx +427 -0
- package/src/components/daterangepicker/__tests__/CDateRangePicker.spec.tsx +9 -0
- package/src/components/daterangepicker/__tests__/__snapshots__/CDateRangePicker.spec.tsx.snap +1201 -0
- package/src/components/dropdown/CDropdown.tsx +19 -24
- package/src/components/dropdown/CDropdownMenu.tsx +57 -3
- package/src/components/dropdown/CDropdownToggle.tsx +28 -5
- package/src/components/picker/CPicker.tsx +207 -0
- package/src/components/picker/__tests__/CPicker.spec.tsx +9 -0
- package/src/components/picker/__tests__/__snapshots__/CPicker.spec.tsx.snap +23 -0
- package/src/components/smart-table/CSmartTable.tsx +44 -96
- package/src/components/smart-table/CSmartTableCleaner.tsx +3 -16
- package/src/components/smart-table/CSmartTableInterface.tsx +0 -9
- package/src/components/timepicker/CTimePicker.tsx +320 -0
- package/src/components/timepicker/CTimePickerRollCol.tsx +63 -0
- package/src/components/timepicker/__tests__/CTimePicker.spec.tsx +9 -0
- package/src/index.ts +8 -0
- package/src/utils/calendar.ts +193 -0
- package/src/utils/time.ts +58 -0
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
export declare const convertToLocalDate: (d: Date, locale: string, options?: {}) => string;
|
|
2
|
+
export declare const convertToLocalTime: (d: Date, locale: string, options?: {}) => string;
|
|
3
|
+
export declare const createGroupsInArray: (arr: any[], numberOfGroups: number) => any[][];
|
|
4
|
+
export declare const getCurrentYear: () => number;
|
|
5
|
+
export declare const getCurrentMonth: () => number;
|
|
6
|
+
export declare const getMonthName: (month: number, locale: string) => string;
|
|
7
|
+
export declare const getMonthsNames: (locale: string) => string[];
|
|
8
|
+
export declare const getYears: (year: number) => number[];
|
|
9
|
+
export declare const getMonthDetails: (year: number, month: number, firstDayOfWeek: number) => {
|
|
10
|
+
date: Date;
|
|
11
|
+
month: string;
|
|
12
|
+
}[][];
|
|
13
|
+
export declare const isDateDisabled: (date: Date, min?: Date | null | undefined, max?: Date | null | undefined, dates?: Date[] | Date[][] | undefined) => boolean | undefined;
|
|
14
|
+
export declare const isDateInRange: (date: Date, start: Date | null, end: Date | null) => boolean | null;
|
|
15
|
+
export declare const isDateSelected: (date: Date, start: Date | null, end: Date | null) => boolean | null;
|
|
16
|
+
export declare const isEndDate: (date: Date, start: Date | null, end: Date | null) => boolean | null;
|
|
17
|
+
export declare const isLastDayOfMonth: (date: Date) => boolean;
|
|
18
|
+
export declare const isSameDateAs: (date: Date, date2: Date) => boolean;
|
|
19
|
+
export declare const isStartDate: (date: Date, start: Date | null, end: Date | null) => boolean | null;
|
|
20
|
+
export declare const isToday: (date: Date) => boolean;
|
|
21
|
+
export declare const isValidDate: (date: string) => number | false;
|
|
@@ -0,0 +1,17 @@
|
|
|
1
|
+
export declare const convert12hTo24h: (abbr: 'am' | 'pm', hour: number) => number;
|
|
2
|
+
export declare const convert24hTo12h: (hour: number) => number;
|
|
3
|
+
export declare const convertTimeToDate: (time: Date | string | null | undefined) => Date | null;
|
|
4
|
+
export declare const getAmPm: (date: Date, locale: string) => "am" | "pm";
|
|
5
|
+
export declare const getListOfHours: (locale: string) => {
|
|
6
|
+
value: number;
|
|
7
|
+
label: string;
|
|
8
|
+
}[];
|
|
9
|
+
export declare const getMinutesOrSeconds: (locale: string) => {
|
|
10
|
+
value: number;
|
|
11
|
+
label: string;
|
|
12
|
+
}[];
|
|
13
|
+
export declare const getSelectedHour: (date: Date | null, locale: string) => number | "";
|
|
14
|
+
export declare const getSelectedMinutes: (date: Date | null) => number | "";
|
|
15
|
+
export declare const getSelectedSeconds: (date: Date | null) => number | "";
|
|
16
|
+
export declare const isAmPm: (locale: string) => boolean;
|
|
17
|
+
export declare const isValidTime: (time: string) => number | false;
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@coreui/react-pro",
|
|
3
|
-
"version": "4.1
|
|
3
|
+
"version": "4.2.0-beta.1",
|
|
4
4
|
"description": "UI Components Library for React.js",
|
|
5
5
|
"keywords": [
|
|
6
6
|
"react",
|
|
@@ -35,24 +35,27 @@
|
|
|
35
35
|
"build": "rollup -c"
|
|
36
36
|
},
|
|
37
37
|
"devDependencies": {
|
|
38
|
-
"@
|
|
38
|
+
"@coreui/icons-pro": "^3.0.0-0",
|
|
39
|
+
"@coreui/icons-react": "^2.0.0",
|
|
40
|
+
"@popperjs/core": "^2.11.2",
|
|
39
41
|
"@rollup/plugin-commonjs": "^21.0.1",
|
|
40
|
-
"@rollup/plugin-node-resolve": "^13.1.
|
|
42
|
+
"@rollup/plugin-node-resolve": "^13.1.3",
|
|
41
43
|
"@rollup/plugin-typescript": "^8.3.0",
|
|
42
|
-
"@testing-library/jest-dom": "^5.16.
|
|
44
|
+
"@testing-library/jest-dom": "^5.16.2",
|
|
43
45
|
"@testing-library/react": "^12.1.2",
|
|
44
|
-
"@types/react": "^17.0.
|
|
46
|
+
"@types/react": "^17.0.39",
|
|
45
47
|
"@types/react-dom": "^17.0.11",
|
|
46
48
|
"@types/react-transition-group": "^4.4.4",
|
|
47
49
|
"classnames": "^2.3.1",
|
|
48
|
-
"prop-types": "^15.8.
|
|
50
|
+
"prop-types": "^15.8.1",
|
|
49
51
|
"react": "^17.0.2",
|
|
52
|
+
"react-device-detect": "^2.1.2",
|
|
50
53
|
"react-dom": "^17.0.2",
|
|
51
54
|
"react-popper": "^2.2.5",
|
|
52
55
|
"react-transition-group": "^4.4.2",
|
|
53
|
-
"rollup": "^2.
|
|
56
|
+
"rollup": "^2.67.1",
|
|
54
57
|
"rollup-plugin-peer-deps-external": "^2.2.4",
|
|
55
|
-
"typescript": "^4.5.
|
|
58
|
+
"typescript": "^4.5.5"
|
|
56
59
|
},
|
|
57
60
|
"peerDependencies": {
|
|
58
61
|
"react": "^17",
|
|
@@ -19,10 +19,11 @@ export const CAccordionButton = forwardRef<HTMLButtonElement, CAccordionButtonPr
|
|
|
19
19
|
|
|
20
20
|
return (
|
|
21
21
|
<button
|
|
22
|
+
type="button"
|
|
22
23
|
className={_className}
|
|
23
|
-
{...rest}
|
|
24
24
|
aria-expanded={!visible}
|
|
25
25
|
onClick={() => setVisible(!visible)}
|
|
26
|
+
{...rest}
|
|
26
27
|
ref={ref}
|
|
27
28
|
>
|
|
28
29
|
{children}
|
|
@@ -5,6 +5,7 @@ exports[`CAccordionButton customize 1`] = `
|
|
|
5
5
|
<button
|
|
6
6
|
aria-expanded="true"
|
|
7
7
|
class="accordion-button collapsed bazinga"
|
|
8
|
+
type="button"
|
|
8
9
|
>
|
|
9
10
|
Test
|
|
10
11
|
</button>
|
|
@@ -16,6 +17,7 @@ exports[`loads and displays CAccordionButton component 1`] = `
|
|
|
16
17
|
<button
|
|
17
18
|
aria-expanded="true"
|
|
18
19
|
class="accordion-button collapsed"
|
|
20
|
+
type="button"
|
|
19
21
|
>
|
|
20
22
|
Test
|
|
21
23
|
</button>
|
|
@@ -8,6 +8,7 @@ exports[`CAccordionHeader customize 1`] = `
|
|
|
8
8
|
<button
|
|
9
9
|
aria-expanded="true"
|
|
10
10
|
class="accordion-button collapsed"
|
|
11
|
+
type="button"
|
|
11
12
|
>
|
|
12
13
|
Test
|
|
13
14
|
</button>
|
|
@@ -23,6 +24,7 @@ exports[`loads and displays CAccordionHeader component 1`] = `
|
|
|
23
24
|
<button
|
|
24
25
|
aria-expanded="true"
|
|
25
26
|
class="accordion-button collapsed"
|
|
27
|
+
type="button"
|
|
26
28
|
>
|
|
27
29
|
Test
|
|
28
30
|
</button>
|
|
@@ -0,0 +1,528 @@
|
|
|
1
|
+
import React, { forwardRef, ReactNode, useEffect, useState } from 'react'
|
|
2
|
+
import PropTypes from 'prop-types'
|
|
3
|
+
import classNames from 'classnames'
|
|
4
|
+
|
|
5
|
+
import { CButton } from '../button/CButton'
|
|
6
|
+
|
|
7
|
+
import {
|
|
8
|
+
createGroupsInArray,
|
|
9
|
+
getMonthDetails,
|
|
10
|
+
getMonthsNames,
|
|
11
|
+
getYears,
|
|
12
|
+
isDateDisabled,
|
|
13
|
+
isDateInRange,
|
|
14
|
+
isDateSelected,
|
|
15
|
+
isLastDayOfMonth,
|
|
16
|
+
isSameDateAs,
|
|
17
|
+
isToday,
|
|
18
|
+
isStartDate,
|
|
19
|
+
isEndDate,
|
|
20
|
+
} from '../../utils/calendar'
|
|
21
|
+
|
|
22
|
+
export interface CCalendarProps {
|
|
23
|
+
/**
|
|
24
|
+
* Default date of the component
|
|
25
|
+
*/
|
|
26
|
+
calendarDate?: Date | string
|
|
27
|
+
/**
|
|
28
|
+
* A string of all className you want applied to the component.
|
|
29
|
+
*/
|
|
30
|
+
className?: string
|
|
31
|
+
/**
|
|
32
|
+
* Specify the list of dates that cannot be selected.
|
|
33
|
+
*/
|
|
34
|
+
disabledDates?: Date[] | Date[][]
|
|
35
|
+
/**
|
|
36
|
+
* Initial selected to date (range).
|
|
37
|
+
*/
|
|
38
|
+
endDate?: Date | string | null
|
|
39
|
+
/**
|
|
40
|
+
* Sets the day of start week.
|
|
41
|
+
* - 0 - Sunday,
|
|
42
|
+
* - 1 - Monday,
|
|
43
|
+
* - 2 - Tuesday,
|
|
44
|
+
* - 3 - Wednesday,
|
|
45
|
+
* - 4 - Thursday,
|
|
46
|
+
* - 5 - Friday,
|
|
47
|
+
* - 6 - Saturday,
|
|
48
|
+
* - 7 - Sunday
|
|
49
|
+
*
|
|
50
|
+
* @default 1
|
|
51
|
+
*/
|
|
52
|
+
firstDayOfWeek?: number
|
|
53
|
+
/**
|
|
54
|
+
* Sets the default locale for components. If not set, it is inherited from the browser.
|
|
55
|
+
*
|
|
56
|
+
* @default 'default'
|
|
57
|
+
*/
|
|
58
|
+
locale?: string
|
|
59
|
+
/**
|
|
60
|
+
* Max selectable date.
|
|
61
|
+
*/
|
|
62
|
+
maxDate?: Date | string
|
|
63
|
+
/**
|
|
64
|
+
* Min selectable date.
|
|
65
|
+
*/
|
|
66
|
+
minDate?: Date | string
|
|
67
|
+
/**
|
|
68
|
+
* Show arrows navigation.
|
|
69
|
+
*/
|
|
70
|
+
navigation?: boolean
|
|
71
|
+
/**
|
|
72
|
+
* The custom next icon.
|
|
73
|
+
*/
|
|
74
|
+
navNextIcon?: ReactNode
|
|
75
|
+
/**
|
|
76
|
+
* The custom next double icon.
|
|
77
|
+
*/
|
|
78
|
+
navNextDoubleIcon?: ReactNode
|
|
79
|
+
/**
|
|
80
|
+
* The custom prev icon.
|
|
81
|
+
*/
|
|
82
|
+
navPrevIcon?: ReactNode
|
|
83
|
+
/**
|
|
84
|
+
* The custom prev double icon.
|
|
85
|
+
*/
|
|
86
|
+
navPrevDoubleIcon?: ReactNode
|
|
87
|
+
/**
|
|
88
|
+
* Allow range selection.
|
|
89
|
+
*/
|
|
90
|
+
range?: boolean
|
|
91
|
+
/**
|
|
92
|
+
* Toggle select mode between start and end date.
|
|
93
|
+
*/
|
|
94
|
+
selectEndDate?: boolean
|
|
95
|
+
/**
|
|
96
|
+
* Initial selected date.
|
|
97
|
+
*/
|
|
98
|
+
startDate?: Date | string | null
|
|
99
|
+
/**
|
|
100
|
+
* Set length or format of day name.
|
|
101
|
+
*
|
|
102
|
+
* @default 2
|
|
103
|
+
*/
|
|
104
|
+
weekdayFormat?: number | 'long' | 'narrow' | 'short'
|
|
105
|
+
/**
|
|
106
|
+
* Callback fired when the user hovers over the calendar cell.
|
|
107
|
+
*/
|
|
108
|
+
onCalendarCellHover?: (date: Date | null) => void
|
|
109
|
+
/**
|
|
110
|
+
* Callback fired when the calendar date changed.
|
|
111
|
+
*/
|
|
112
|
+
onCalendarDateChange?: (date: Date) => void
|
|
113
|
+
/**
|
|
114
|
+
* Callback fired when the start date changed.
|
|
115
|
+
*/
|
|
116
|
+
onStartDateChange?: (date: Date | null) => void
|
|
117
|
+
/**
|
|
118
|
+
* Callback fired when the end date changed.
|
|
119
|
+
*/
|
|
120
|
+
onEndDateChange?: (date: Date | null) => void
|
|
121
|
+
/**
|
|
122
|
+
* Callback fired when the view type of calendar changed.
|
|
123
|
+
*/
|
|
124
|
+
onViewChanged?: (view: string) => void
|
|
125
|
+
}
|
|
126
|
+
|
|
127
|
+
export const CCalendar = forwardRef<HTMLDivElement, CCalendarProps>(
|
|
128
|
+
(
|
|
129
|
+
{
|
|
130
|
+
calendarDate,
|
|
131
|
+
disabledDates,
|
|
132
|
+
endDate,
|
|
133
|
+
firstDayOfWeek = 1,
|
|
134
|
+
locale = 'default',
|
|
135
|
+
maxDate,
|
|
136
|
+
minDate,
|
|
137
|
+
navigation = true,
|
|
138
|
+
navNextIcon,
|
|
139
|
+
navNextDoubleIcon,
|
|
140
|
+
navPrevIcon,
|
|
141
|
+
navPrevDoubleIcon,
|
|
142
|
+
range,
|
|
143
|
+
selectEndDate,
|
|
144
|
+
startDate,
|
|
145
|
+
weekdayFormat = 2,
|
|
146
|
+
onCalendarDateChange,
|
|
147
|
+
onStartDateChange,
|
|
148
|
+
onEndDateChange,
|
|
149
|
+
onCalendarCellHover,
|
|
150
|
+
onViewChanged,
|
|
151
|
+
},
|
|
152
|
+
ref,
|
|
153
|
+
) => {
|
|
154
|
+
const [_calendarDate, setCalendarDate] = useState<Date>(
|
|
155
|
+
calendarDate ? new Date(calendarDate) : new Date(),
|
|
156
|
+
)
|
|
157
|
+
const [_startDate, setStartDate] = useState<Date | null>(startDate ? new Date(startDate) : null)
|
|
158
|
+
const [_endDate, setEndDate] = useState<Date | null>(endDate ? new Date(endDate) : null)
|
|
159
|
+
const [_selectEndDate, setSelectEndDate] = useState(selectEndDate)
|
|
160
|
+
const [view, setView] = useState('days')
|
|
161
|
+
|
|
162
|
+
const _maxDate = maxDate ? new Date(maxDate) : null
|
|
163
|
+
const _minDate = minDate ? new Date(minDate) : null
|
|
164
|
+
|
|
165
|
+
useEffect(() => {
|
|
166
|
+
if (calendarDate) {
|
|
167
|
+
const d = new Date(calendarDate)
|
|
168
|
+
!isSameDateAs(_calendarDate, d) && setCalendarDate(d)
|
|
169
|
+
}
|
|
170
|
+
}, [calendarDate])
|
|
171
|
+
|
|
172
|
+
useEffect(() => {
|
|
173
|
+
if (startDate === null) {
|
|
174
|
+
setStartDate(null)
|
|
175
|
+
return
|
|
176
|
+
}
|
|
177
|
+
|
|
178
|
+
if (startDate) {
|
|
179
|
+
const d = new Date(startDate)
|
|
180
|
+
if (_startDate === null) {
|
|
181
|
+
setStartDate(d)
|
|
182
|
+
return
|
|
183
|
+
}
|
|
184
|
+
|
|
185
|
+
if (_startDate && !isSameDateAs(d, _startDate)) {
|
|
186
|
+
setStartDate(d)
|
|
187
|
+
}
|
|
188
|
+
}
|
|
189
|
+
}, [startDate])
|
|
190
|
+
|
|
191
|
+
useEffect(() => {
|
|
192
|
+
if (endDate === null) {
|
|
193
|
+
setEndDate(null)
|
|
194
|
+
return
|
|
195
|
+
}
|
|
196
|
+
|
|
197
|
+
if (endDate) {
|
|
198
|
+
const d = new Date(endDate)
|
|
199
|
+
if (_endDate === null) {
|
|
200
|
+
setEndDate(d)
|
|
201
|
+
return
|
|
202
|
+
}
|
|
203
|
+
|
|
204
|
+
if (_endDate && !isSameDateAs(d, _endDate)) {
|
|
205
|
+
setEndDate(d)
|
|
206
|
+
}
|
|
207
|
+
}
|
|
208
|
+
}, [endDate])
|
|
209
|
+
|
|
210
|
+
useEffect(() => {
|
|
211
|
+
_startDate && onStartDateChange && onStartDateChange(_startDate)
|
|
212
|
+
}, [_startDate])
|
|
213
|
+
|
|
214
|
+
useEffect(() => {
|
|
215
|
+
_endDate && onEndDateChange && onEndDateChange(_endDate)
|
|
216
|
+
}, [_endDate])
|
|
217
|
+
|
|
218
|
+
useEffect(() => {
|
|
219
|
+
setSelectEndDate(selectEndDate)
|
|
220
|
+
}, [selectEndDate])
|
|
221
|
+
|
|
222
|
+
useEffect(() => {
|
|
223
|
+
onViewChanged && onViewChanged(view)
|
|
224
|
+
}, [view])
|
|
225
|
+
|
|
226
|
+
const setCalendarPage = (years: number, months = 0, setMonth?: number) => {
|
|
227
|
+
const year = _calendarDate.getFullYear()
|
|
228
|
+
const month = _calendarDate.getMonth()
|
|
229
|
+
const d = new Date(year, month, 1)
|
|
230
|
+
|
|
231
|
+
years && d.setFullYear(d.getFullYear() + years)
|
|
232
|
+
months && d.setMonth(d.getMonth() + months)
|
|
233
|
+
setMonth && d.setMonth(setMonth)
|
|
234
|
+
|
|
235
|
+
setCalendarDate(d)
|
|
236
|
+
onCalendarDateChange && onCalendarDateChange(d)
|
|
237
|
+
}
|
|
238
|
+
|
|
239
|
+
const handleCellOnClick = (date: Date) => {
|
|
240
|
+
if (isDateDisabled(date, _minDate, _maxDate, disabledDates)) {
|
|
241
|
+
return
|
|
242
|
+
}
|
|
243
|
+
|
|
244
|
+
if (range) {
|
|
245
|
+
if (_selectEndDate) {
|
|
246
|
+
if (_startDate && _startDate > date) {
|
|
247
|
+
setEndDate(_startDate)
|
|
248
|
+
setStartDate(date)
|
|
249
|
+
} else {
|
|
250
|
+
setEndDate(date)
|
|
251
|
+
}
|
|
252
|
+
setSelectEndDate(false)
|
|
253
|
+
} else {
|
|
254
|
+
setStartDate(date)
|
|
255
|
+
setSelectEndDate(true)
|
|
256
|
+
}
|
|
257
|
+
} else {
|
|
258
|
+
setStartDate(date)
|
|
259
|
+
}
|
|
260
|
+
}
|
|
261
|
+
|
|
262
|
+
const handleCellMouseEnter = (date: Date) => {
|
|
263
|
+
if (isDateDisabled(date, _minDate, _maxDate, disabledDates)) {
|
|
264
|
+
return
|
|
265
|
+
}
|
|
266
|
+
onCalendarCellHover && onCalendarCellHover(date)
|
|
267
|
+
}
|
|
268
|
+
|
|
269
|
+
const handleCellMouseLeave = () => {
|
|
270
|
+
onCalendarCellHover && onCalendarCellHover(null)
|
|
271
|
+
}
|
|
272
|
+
|
|
273
|
+
const handleNavigationOnClick = (direction: string, double = false) => {
|
|
274
|
+
if (direction === 'prev') {
|
|
275
|
+
if (double) {
|
|
276
|
+
setCalendarPage(view === 'years' ? -10 : -1)
|
|
277
|
+
return
|
|
278
|
+
}
|
|
279
|
+
|
|
280
|
+
if (view !== 'days') {
|
|
281
|
+
setCalendarPage(-1)
|
|
282
|
+
return
|
|
283
|
+
}
|
|
284
|
+
|
|
285
|
+
setCalendarPage(0, -1)
|
|
286
|
+
return
|
|
287
|
+
}
|
|
288
|
+
if (direction === 'next') {
|
|
289
|
+
if (double) {
|
|
290
|
+
setCalendarPage(view === 'years' ? 10 : 1)
|
|
291
|
+
return
|
|
292
|
+
}
|
|
293
|
+
|
|
294
|
+
if (view !== 'days') {
|
|
295
|
+
setCalendarPage(1)
|
|
296
|
+
return
|
|
297
|
+
}
|
|
298
|
+
|
|
299
|
+
setCalendarPage(0, 1)
|
|
300
|
+
return
|
|
301
|
+
}
|
|
302
|
+
}
|
|
303
|
+
|
|
304
|
+
const Calendar = () => {
|
|
305
|
+
const monthDetails = getMonthDetails(
|
|
306
|
+
_calendarDate.getFullYear(),
|
|
307
|
+
_calendarDate.getMonth(),
|
|
308
|
+
firstDayOfWeek,
|
|
309
|
+
)
|
|
310
|
+
const listOfMonths = createGroupsInArray(getMonthsNames(locale), 4)
|
|
311
|
+
const listOfYears = createGroupsInArray(getYears(_calendarDate.getFullYear()), 4)
|
|
312
|
+
const weekDays = monthDetails[0]
|
|
313
|
+
return (
|
|
314
|
+
<table>
|
|
315
|
+
{view === 'days' && (
|
|
316
|
+
<thead>
|
|
317
|
+
<tr>
|
|
318
|
+
{weekDays.map(({ date }: { date: Date }, idx: number) => (
|
|
319
|
+
<th key={idx} className="calendar-cell">
|
|
320
|
+
<div className="calendar-header-cell-inner">
|
|
321
|
+
{typeof weekdayFormat === 'string'
|
|
322
|
+
? date.toLocaleDateString(locale, { weekday: weekdayFormat })
|
|
323
|
+
: date
|
|
324
|
+
.toLocaleDateString(locale, { weekday: 'long' })
|
|
325
|
+
.slice(0, weekdayFormat)}
|
|
326
|
+
</div>
|
|
327
|
+
</th>
|
|
328
|
+
))}
|
|
329
|
+
</tr>
|
|
330
|
+
</thead>
|
|
331
|
+
)}
|
|
332
|
+
<tbody onMouseLeave={() => handleCellMouseLeave()}>
|
|
333
|
+
{view === 'days' &&
|
|
334
|
+
monthDetails.map((week, index) => {
|
|
335
|
+
return (
|
|
336
|
+
<tr key={index}>
|
|
337
|
+
{week.map(({ date, month }: { date: Date; month: string }, idx: number) => (
|
|
338
|
+
<td
|
|
339
|
+
className={classNames('calendar-cell', {
|
|
340
|
+
today: isToday(date),
|
|
341
|
+
disabled: isDateDisabled(date, _minDate, _maxDate, disabledDates),
|
|
342
|
+
next: month === 'next',
|
|
343
|
+
previous: month === 'previous',
|
|
344
|
+
last: isLastDayOfMonth(date),
|
|
345
|
+
range: month === 'current' && isDateInRange(date, _startDate, _endDate),
|
|
346
|
+
selected: isDateSelected(date, _startDate, _endDate),
|
|
347
|
+
start: isStartDate(date, _startDate, _endDate),
|
|
348
|
+
end: isEndDate(date, _startDate, _endDate),
|
|
349
|
+
})}
|
|
350
|
+
key={idx}
|
|
351
|
+
title={date.toLocaleDateString(locale)}
|
|
352
|
+
onClick={() => handleCellOnClick(date)}
|
|
353
|
+
onMouseEnter={() => handleCellMouseEnter(date)}
|
|
354
|
+
>
|
|
355
|
+
<div className="calendar-cell-inner">
|
|
356
|
+
{date.toLocaleDateString(locale, { day: 'numeric' })}
|
|
357
|
+
</div>
|
|
358
|
+
</td>
|
|
359
|
+
))}
|
|
360
|
+
</tr>
|
|
361
|
+
)
|
|
362
|
+
})}
|
|
363
|
+
{view === 'months' &&
|
|
364
|
+
listOfMonths.map((row, index) => {
|
|
365
|
+
return (
|
|
366
|
+
<tr key={index}>
|
|
367
|
+
{row.map((month, idx) => {
|
|
368
|
+
return (
|
|
369
|
+
<td
|
|
370
|
+
key={idx}
|
|
371
|
+
className="calendar-cell month"
|
|
372
|
+
onClick={() => {
|
|
373
|
+
setCalendarPage(0, 0, index * 3 + idx)
|
|
374
|
+
setView('days')
|
|
375
|
+
}}
|
|
376
|
+
>
|
|
377
|
+
<div className="calendar-cell-inner">{month}</div>
|
|
378
|
+
</td>
|
|
379
|
+
)
|
|
380
|
+
})}
|
|
381
|
+
</tr>
|
|
382
|
+
)
|
|
383
|
+
})}
|
|
384
|
+
{view === 'years' &&
|
|
385
|
+
listOfYears.map((row, index) => {
|
|
386
|
+
return (
|
|
387
|
+
<tr key={index}>
|
|
388
|
+
{row.map((year, idx) => {
|
|
389
|
+
return (
|
|
390
|
+
<td
|
|
391
|
+
key={idx}
|
|
392
|
+
className="calendar-cell year"
|
|
393
|
+
onClick={() => {
|
|
394
|
+
setCalendarDate(
|
|
395
|
+
new Date(year, _calendarDate.getMonth(), _calendarDate.getDate()),
|
|
396
|
+
)
|
|
397
|
+
setView('months')
|
|
398
|
+
}}
|
|
399
|
+
>
|
|
400
|
+
<div className="calendar-cell-inner">
|
|
401
|
+
{new Date(year, 0, 1).toLocaleDateString(locale, { year: 'numeric' })}
|
|
402
|
+
</div>
|
|
403
|
+
</td>
|
|
404
|
+
)
|
|
405
|
+
})}
|
|
406
|
+
</tr>
|
|
407
|
+
)
|
|
408
|
+
})}
|
|
409
|
+
</tbody>
|
|
410
|
+
</table>
|
|
411
|
+
)
|
|
412
|
+
}
|
|
413
|
+
|
|
414
|
+
const Navigation = () => {
|
|
415
|
+
return (
|
|
416
|
+
<div className="calendar-nav">
|
|
417
|
+
{navigation && (
|
|
418
|
+
<div className="calendar-nav-prev">
|
|
419
|
+
<CButton
|
|
420
|
+
color="transparent"
|
|
421
|
+
size="sm"
|
|
422
|
+
onClick={() => handleNavigationOnClick('prev', true)}
|
|
423
|
+
>
|
|
424
|
+
{navPrevDoubleIcon ? (
|
|
425
|
+
navPrevDoubleIcon
|
|
426
|
+
) : (
|
|
427
|
+
<span className="calendar-nav-icon calendar-nav-icon-double-prev" />
|
|
428
|
+
)}
|
|
429
|
+
</CButton>
|
|
430
|
+
{view === 'days' && (
|
|
431
|
+
<CButton
|
|
432
|
+
color="transparent"
|
|
433
|
+
size="sm"
|
|
434
|
+
onClick={() => handleNavigationOnClick('prev')}
|
|
435
|
+
>
|
|
436
|
+
{navPrevIcon ? (
|
|
437
|
+
navPrevIcon
|
|
438
|
+
) : (
|
|
439
|
+
<span className="calendar-nav-icon calendar-nav-icon-prev" />
|
|
440
|
+
)}
|
|
441
|
+
</CButton>
|
|
442
|
+
)}
|
|
443
|
+
</div>
|
|
444
|
+
)}
|
|
445
|
+
<div className="calendar-nav-date">
|
|
446
|
+
{view === 'days' && (
|
|
447
|
+
<CButton
|
|
448
|
+
color="transparent"
|
|
449
|
+
size="sm"
|
|
450
|
+
onClick={() => navigation && setView('months')}
|
|
451
|
+
>
|
|
452
|
+
{_calendarDate.toLocaleDateString(locale, { month: 'long' })}
|
|
453
|
+
</CButton>
|
|
454
|
+
)}
|
|
455
|
+
<CButton color="transparent" size="sm" onClick={() => navigation && setView('years')}>
|
|
456
|
+
{_calendarDate.toLocaleDateString(locale, { year: 'numeric' })}
|
|
457
|
+
</CButton>
|
|
458
|
+
</div>
|
|
459
|
+
{navigation && (
|
|
460
|
+
<div className="calendar-nav-next">
|
|
461
|
+
{view === 'days' && (
|
|
462
|
+
<CButton
|
|
463
|
+
color="transparent"
|
|
464
|
+
size="sm"
|
|
465
|
+
onClick={() => handleNavigationOnClick('next')}
|
|
466
|
+
>
|
|
467
|
+
{navNextIcon ? (
|
|
468
|
+
navNextIcon
|
|
469
|
+
) : (
|
|
470
|
+
<span className="calendar-nav-icon calendar-nav-icon-next" />
|
|
471
|
+
)}
|
|
472
|
+
</CButton>
|
|
473
|
+
)}
|
|
474
|
+
<CButton
|
|
475
|
+
color="transparent"
|
|
476
|
+
size="sm"
|
|
477
|
+
onClick={() => handleNavigationOnClick('next', true)}
|
|
478
|
+
>
|
|
479
|
+
{navNextDoubleIcon ? (
|
|
480
|
+
navNextDoubleIcon
|
|
481
|
+
) : (
|
|
482
|
+
<span className="calendar-nav-icon calendar-nav-icon-double-next" />
|
|
483
|
+
)}
|
|
484
|
+
</CButton>
|
|
485
|
+
</div>
|
|
486
|
+
)}
|
|
487
|
+
</div>
|
|
488
|
+
)
|
|
489
|
+
}
|
|
490
|
+
|
|
491
|
+
return (
|
|
492
|
+
<div className={classNames('calendar', view)} ref={ref}>
|
|
493
|
+
<Navigation />
|
|
494
|
+
<Calendar />
|
|
495
|
+
</div>
|
|
496
|
+
)
|
|
497
|
+
},
|
|
498
|
+
)
|
|
499
|
+
|
|
500
|
+
CCalendar.propTypes = {
|
|
501
|
+
className: PropTypes.string,
|
|
502
|
+
calendarDate: PropTypes.oneOfType([PropTypes.instanceOf(Date), PropTypes.string]),
|
|
503
|
+
disabledDates: PropTypes.array,
|
|
504
|
+
endDate: PropTypes.oneOfType([PropTypes.instanceOf(Date), PropTypes.string]),
|
|
505
|
+
firstDayOfWeek: PropTypes.number,
|
|
506
|
+
locale: PropTypes.string,
|
|
507
|
+
maxDate: PropTypes.oneOfType([PropTypes.instanceOf(Date), PropTypes.string]),
|
|
508
|
+
minDate: PropTypes.oneOfType([PropTypes.instanceOf(Date), PropTypes.string]),
|
|
509
|
+
navigation: PropTypes.bool,
|
|
510
|
+
navNextIcon: PropTypes.node,
|
|
511
|
+
navNextDoubleIcon: PropTypes.node,
|
|
512
|
+
navPrevIcon: PropTypes.node,
|
|
513
|
+
navPrevDoubleIcon: PropTypes.node,
|
|
514
|
+
range: PropTypes.bool,
|
|
515
|
+
selectEndDate: PropTypes.bool,
|
|
516
|
+
startDate: PropTypes.oneOfType([PropTypes.instanceOf(Date), PropTypes.string]),
|
|
517
|
+
weekdayFormat: PropTypes.oneOfType([
|
|
518
|
+
PropTypes.number,
|
|
519
|
+
PropTypes.oneOf<'long' | 'narrow' | 'short'>(['long', 'narrow', 'short']),
|
|
520
|
+
]),
|
|
521
|
+
onCalendarCellHover: PropTypes.func,
|
|
522
|
+
onCalendarDateChange: PropTypes.func,
|
|
523
|
+
onStartDateChange: PropTypes.func,
|
|
524
|
+
onEndDateChange: PropTypes.func,
|
|
525
|
+
onViewChanged: PropTypes.func,
|
|
526
|
+
}
|
|
527
|
+
|
|
528
|
+
CCalendar.displayName = 'CCalendar'
|
|
@@ -0,0 +1,9 @@
|
|
|
1
|
+
import * as React from 'react'
|
|
2
|
+
import { render } from '@testing-library/react'
|
|
3
|
+
import '@testing-library/jest-dom/extend-expect'
|
|
4
|
+
import { CCalendar } from '../CCalendar'
|
|
5
|
+
|
|
6
|
+
test('loads and displays CCalendar component', async () => {
|
|
7
|
+
const { container } = render(<CCalendar />)
|
|
8
|
+
expect(container).toMatchSnapshot()
|
|
9
|
+
})
|