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