@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.
Files changed (48) hide show
  1. package/README.md +1 -1
  2. package/dist/components/calendar/CCalendar.d.ts +106 -0
  3. package/dist/components/calendar/CCalendar.utils.d.ts +21 -0
  4. package/dist/components/datepicker/CDatePicker.d.ts +13 -0
  5. package/dist/components/daterangepicker/CDateRangePicker.d.ts +65 -0
  6. package/dist/components/dropdown/CDropdown.d.ts +10 -1
  7. package/dist/components/dropdown/CDropdownToggle.d.ts +4 -0
  8. package/dist/components/dropdown/CDropdownToggleCustom.d.ts +15 -0
  9. package/dist/components/picker/CPicker.d.ts +78 -0
  10. package/dist/components/smart-table/CSmartTableInterface.d.ts +0 -9
  11. package/dist/components/timepicker/CTimePicker.d.ts +45 -0
  12. package/dist/components/timepicker/CTimePicker.utils.d.ts +17 -0
  13. package/dist/components/timepicker/CTimePickerRollCol.d.ts +11 -0
  14. package/dist/index.d.ts +5 -1
  15. package/dist/index.es.js +2568 -718
  16. package/dist/index.es.js.map +1 -1
  17. package/dist/index.js +2849 -995
  18. package/dist/index.js.map +1 -1
  19. package/dist/utils/calendar.d.ts +21 -0
  20. package/dist/utils/time.d.ts +17 -0
  21. package/package.json +11 -8
  22. package/src/components/accordion/CAccordionButton.tsx +2 -1
  23. package/src/components/accordion/__tests__/__snapshots__/CAccordionButton.spec.tsx.snap +2 -0
  24. package/src/components/accordion/__tests__/__snapshots__/CAccordionHeader.spec.tsx.snap +2 -0
  25. package/src/components/calendar/CCalendar.tsx +528 -0
  26. package/src/components/calendar/__tests__/CCalendar.spec.tsx +9 -0
  27. package/src/components/calendar/__tests__/__snapshots__/CCalendar.spec.tsx.snap +573 -0
  28. package/src/components/datepicker/CDatePicker.tsx +50 -0
  29. package/src/components/datepicker/__tests__/CDatePicker.spec.tsx +9 -0
  30. package/src/components/datepicker/__tests__/__snapshots__/CDatePicker.spec.tsx.snap +617 -0
  31. package/src/components/daterangepicker/CDateRangePicker.tsx +427 -0
  32. package/src/components/daterangepicker/__tests__/CDateRangePicker.spec.tsx +9 -0
  33. package/src/components/daterangepicker/__tests__/__snapshots__/CDateRangePicker.spec.tsx.snap +1201 -0
  34. package/src/components/dropdown/CDropdown.tsx +19 -24
  35. package/src/components/dropdown/CDropdownMenu.tsx +57 -3
  36. package/src/components/dropdown/CDropdownToggle.tsx +28 -5
  37. package/src/components/picker/CPicker.tsx +207 -0
  38. package/src/components/picker/__tests__/CPicker.spec.tsx +9 -0
  39. package/src/components/picker/__tests__/__snapshots__/CPicker.spec.tsx.snap +23 -0
  40. package/src/components/smart-table/CSmartTable.tsx +44 -96
  41. package/src/components/smart-table/CSmartTableCleaner.tsx +3 -16
  42. package/src/components/smart-table/CSmartTableInterface.tsx +0 -9
  43. package/src/components/timepicker/CTimePicker.tsx +320 -0
  44. package/src/components/timepicker/CTimePickerRollCol.tsx +63 -0
  45. package/src/components/timepicker/__tests__/CTimePicker.spec.tsx +9 -0
  46. package/src/index.ts +8 -0
  47. package/src/utils/calendar.ts +193 -0
  48. 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",
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
- "@popperjs/core": "^2.11.0",
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.1",
42
+ "@rollup/plugin-node-resolve": "^13.1.3",
41
43
  "@rollup/plugin-typescript": "^8.3.0",
42
- "@testing-library/jest-dom": "^5.16.1",
44
+ "@testing-library/jest-dom": "^5.16.2",
43
45
  "@testing-library/react": "^12.1.2",
44
- "@types/react": "^17.0.38",
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.0",
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.62.0",
56
+ "rollup": "^2.67.1",
54
57
  "rollup-plugin-peer-deps-external": "^2.2.4",
55
- "typescript": "^4.5.4"
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
+ })