@coreui/react-pro 5.0.0-alpha.0 → 5.0.0-alpha.2

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 (92) hide show
  1. package/README.md +1 -1
  2. package/dist/components/avatar/CAvatar.d.ts +1 -1
  3. package/dist/components/badge/CBadge.d.ts +1 -1
  4. package/dist/components/calendar/CCalendar.d.ts +25 -7
  5. package/dist/components/calendar/utils.d.ts +12 -3
  6. package/dist/components/card/CCard.d.ts +1 -1
  7. package/dist/components/close-button/CCloseButton.d.ts +6 -0
  8. package/dist/components/dropdown/CDropdown.d.ts +1 -0
  9. package/dist/components/modal/CModal.d.ts +6 -0
  10. package/dist/components/multi-select/types.d.ts +2 -2
  11. package/dist/components/multi-select/utils.d.ts +2 -2
  12. package/dist/components/nav/CNav.d.ts +1 -1
  13. package/dist/components/navbar/CNavbar.d.ts +1 -1
  14. package/dist/components/offcanvas/COffcanvas.d.ts +4 -0
  15. package/dist/components/smart-table/CSmartTableBody.d.ts +2 -1
  16. package/dist/components/smart-table/CSmartTableHead.d.ts +1 -1
  17. package/dist/components/smart-table/CSmartTableInterface.d.ts +1 -3
  18. package/dist/components/smart-table/types.d.ts +2 -2
  19. package/dist/components/smart-table/utils.d.ts +3 -1
  20. package/dist/index.es.js +1468 -1130
  21. package/dist/index.es.js.map +1 -1
  22. package/dist/index.js +1468 -1130
  23. package/dist/index.js.map +1 -1
  24. package/dist/types.d.ts +1 -1
  25. package/dist/utils/executeAfterTransition.d.ts +2 -0
  26. package/dist/utils/getTransitionDurationFromElement.d.ts +2 -0
  27. package/dist/utils/index.d.ts +3 -1
  28. package/package.json +2 -2
  29. package/src/components/avatar/CAvatar.tsx +1 -1
  30. package/src/components/badge/CBadge.tsx +1 -1
  31. package/src/components/button/CButton.tsx +1 -1
  32. package/src/components/button/__tests__/__snapshots__/CButton.spec.tsx.snap +0 -1
  33. package/src/components/calendar/CCalendar.tsx +396 -193
  34. package/src/components/calendar/utils.ts +91 -4
  35. package/src/components/card/CCard.tsx +1 -1
  36. package/src/components/carousel/CCarousel.tsx +9 -5
  37. package/src/components/carousel/__tests__/__snapshots__/CCarousel.spec.tsx.snap +9 -5
  38. package/src/components/close-button/CCloseButton.tsx +9 -1
  39. package/src/components/date-range-picker/CDateRangePicker.tsx +49 -45
  40. package/src/components/dropdown/CDropdown.tsx +43 -1
  41. package/src/components/dropdown/CDropdownMenu.tsx +1 -1
  42. package/src/components/dropdown/CDropdownToggle.tsx +3 -12
  43. package/src/components/modal/CModal.tsx +25 -9
  44. package/src/components/multi-select/CMultiSelect.tsx +3 -3
  45. package/src/components/multi-select/CMultiSelectNativeSelect.tsx +1 -1
  46. package/src/components/multi-select/CMultiSelectOptions.tsx +1 -1
  47. package/src/components/multi-select/CMultiSelectSelection.tsx +3 -3
  48. package/src/components/multi-select/types.ts +2 -2
  49. package/src/components/multi-select/utils.ts +5 -5
  50. package/src/components/nav/CNav.tsx +2 -2
  51. package/src/components/nav/CNavGroup.tsx +9 -2
  52. package/src/components/nav/__tests__/__snapshots__/CNav.spec.tsx.snap +5 -4
  53. package/src/components/navbar/CNavbar.tsx +2 -2
  54. package/src/components/navbar/__tests__/CNavbar.spec.tsx +1 -1
  55. package/src/components/navbar/__tests__/__snapshots__/CNavbar.spec.tsx.snap +2 -1
  56. package/src/components/offcanvas/COffcanvas.tsx +8 -1
  57. package/src/components/popover/CPopover.tsx +2 -2
  58. package/src/components/progress/__tests__/__snapshots__/CProgress.spec.tsx.snap +10 -5
  59. package/src/components/progress/__tests__/__snapshots__/CProgressBar.spec.tsx.snap +0 -8
  60. package/src/components/sidebar/CSidebar.tsx +1 -1
  61. package/src/components/smart-table/CSmartTable.tsx +13 -6
  62. package/src/components/smart-table/CSmartTableBody.tsx +11 -5
  63. package/src/components/smart-table/CSmartTableHead.tsx +31 -11
  64. package/src/components/smart-table/CSmartTableInterface.tsx +1 -3
  65. package/src/components/smart-table/types.ts +2 -2
  66. package/src/components/smart-table/utils.ts +40 -5
  67. package/src/components/time-picker/CTimePicker.tsx +2 -2
  68. package/src/components/time-picker/utils.ts +5 -1
  69. package/src/components/tooltip/CTooltip.tsx +2 -2
  70. package/src/components/widgets/CWidgetStatsA.tsx +1 -1
  71. package/src/components/widgets/CWidgetStatsB.tsx +2 -2
  72. package/src/components/widgets/CWidgetStatsC.tsx +4 -12
  73. package/src/components/widgets/CWidgetStatsD.tsx +1 -1
  74. package/src/components/widgets/CWidgetStatsE.tsx +1 -1
  75. package/src/components/widgets/CWidgetStatsF.tsx +1 -1
  76. package/src/components/widgets/__tests__/CWidgetStatsA.spec.tsx +1 -1
  77. package/src/components/widgets/__tests__/CWidgetStatsB.spec.tsx +1 -1
  78. package/src/components/widgets/__tests__/CWidgetStatsC.spec.tsx +1 -1
  79. package/src/components/widgets/__tests__/CWidgetStatsD.spec.tsx +1 -1
  80. package/src/components/widgets/__tests__/CWidgetStatsE.spec.tsx +1 -1
  81. package/src/components/widgets/__tests__/CWidgetStatsF.spec.tsx +1 -1
  82. package/src/components/widgets/__tests__/__snapshots__/CWidgetStatsA.spec.tsx.snap +1 -1
  83. package/src/components/widgets/__tests__/__snapshots__/CWidgetStatsB.spec.tsx.snap +12 -7
  84. package/src/components/widgets/__tests__/__snapshots__/CWidgetStatsC.spec.tsx.snap +14 -9
  85. package/src/components/widgets/__tests__/__snapshots__/CWidgetStatsD.spec.tsx.snap +2 -2
  86. package/src/components/widgets/__tests__/__snapshots__/CWidgetStatsE.spec.tsx.snap +1 -1
  87. package/src/components/widgets/__tests__/__snapshots__/CWidgetStatsF.spec.tsx.snap +2 -2
  88. package/src/hooks/usePopper.ts +10 -2
  89. package/src/types.ts +14 -7
  90. package/src/utils/executeAfterTransition.ts +46 -0
  91. package/src/utils/getTransitionDurationFromElement.ts +24 -0
  92. package/src/utils/index.ts +10 -1
@@ -1,3 +1,31 @@
1
+ export const convertIsoWeekToDate = (isoWeek: string) => {
2
+ const [year, week] = isoWeek.split(/w/i)
3
+ // Get date for 4th of January for year
4
+ const date = new Date(Number(year), 0, 4)
5
+ // Get previous Monday, add 7 days for each week after first
6
+ date.setDate(date.getDate() - (date.getDay() || 7) + 1 + (Number(week) - 1) * 7)
7
+ return date
8
+ }
9
+
10
+ export const convertToDateObject = (
11
+ date: Date | string | null,
12
+ selectionType?: 'day' | 'week' | 'month' | 'year',
13
+ ) => {
14
+ // if (date === null) {
15
+ // return null
16
+ // }
17
+
18
+ if (date instanceof Date) {
19
+ return date
20
+ }
21
+
22
+ if (selectionType === 'week') {
23
+ return convertIsoWeekToDate(date as string)
24
+ }
25
+
26
+ return new Date(Date.parse(date))
27
+ }
28
+
1
29
  export const convertToLocalDate = (d: Date, locale: string, options = {}) =>
2
30
  d.toLocaleDateString(locale, options)
3
31
 
@@ -11,10 +39,50 @@ export const createGroupsInArray = <T>(arr: T[], numberOfGroups: number): T[][]
11
39
  .map((_, i) => arr.slice(i * perGroup, (i + 1) * perGroup))
12
40
  }
13
41
 
42
+ export const getCalendarDate = (calendarDate: Date, order: number, view: 'days' | 'months' | 'years') => {
43
+ if (order !== 0 && view === 'days') {
44
+ return new Date(Date.UTC(calendarDate.getFullYear(), calendarDate.getMonth() + order, 1))
45
+ }
46
+
47
+ if (order !== 0 && view === 'months') {
48
+ return new Date(Date.UTC(calendarDate.getFullYear() + order, calendarDate.getMonth(), 1))
49
+ }
50
+
51
+ if (order !== 0 && view === 'years') {
52
+ return new Date(Date.UTC(calendarDate.getFullYear() + (12 * order), calendarDate.getMonth(), 1))
53
+ }
54
+
55
+ return calendarDate
56
+ }
57
+
14
58
  export const getCurrentYear = () => new Date().getFullYear()
15
59
 
16
60
  export const getCurrentMonth = () => new Date().getMonth()
17
61
 
62
+ export const getDateBySelectionType = (
63
+ date: Date | null,
64
+ selectionType: 'day' | 'week' | 'month' | 'year',
65
+ ) => {
66
+ if (date === null) {
67
+ return null
68
+ }
69
+
70
+ if (selectionType === 'week') {
71
+ return `${date.getFullYear()}W${getWeekNumber(date)}`
72
+ }
73
+
74
+ if (selectionType === 'month') {
75
+ const monthNumber = `0${date.getMonth() + 1}`.slice(-2)
76
+ return `${date.getFullYear()}-${monthNumber}`
77
+ }
78
+
79
+ if (selectionType === 'year') {
80
+ return `${date.getFullYear()}`
81
+ }
82
+
83
+ return date
84
+ }
85
+
18
86
  export const getMonthName = (month: number, locale: string) => {
19
87
  const d = new Date()
20
88
  d.setDate(1)
@@ -77,6 +145,7 @@ const getMonthDays = (year: number, month: number) => {
77
145
  month: 'current',
78
146
  })
79
147
  }
148
+
80
149
  return dates
81
150
  }
82
151
 
@@ -94,22 +163,40 @@ const getTrailingDays = (
94
163
  month: 'next',
95
164
  })
96
165
  }
166
+
97
167
  return dates
98
168
  }
99
169
 
170
+ export const getDayNumber = (date: Date) =>
171
+ Math.ceil((Number(date) - Number(new Date(date.getFullYear(), 0, 0))) / 1000 / 60 / 60 / 24)
172
+
173
+ export const getWeekNumber = (date: Date) => {
174
+ const week1 = new Date(date.getFullYear(), 0, 4)
175
+ return (
176
+ 1 +
177
+ Math.round(((date.getTime() - week1.getTime()) / 86400000 - 3 + ((week1.getDay() + 6) % 7)) / 7)
178
+ )
179
+ }
180
+
100
181
  export const getMonthDetails = (year: number, month: number, firstDayOfWeek: number) => {
101
182
  const daysPrevMonth = getLeadingDays(year, month, firstDayOfWeek)
102
183
  const daysThisMonth = getMonthDays(year, month)
103
184
  const daysNextMonth = getTrailingDays(year, month, daysPrevMonth, daysThisMonth)
104
185
  const days = [...daysPrevMonth, ...daysThisMonth, ...daysNextMonth]
105
-
106
- const weeks: { date: Date; month: string }[][] = []
186
+ const weeks: { weekNumber?: number; days: { date: Date; month: string }[] }[] = []
107
187
 
108
188
  days.forEach((day, index) => {
109
189
  if (index % 7 === 0 || weeks.length === 0) {
110
- weeks.push([])
190
+ weeks.push({
191
+ days: [],
192
+ })
111
193
  }
112
- weeks[weeks.length - 1].push(day)
194
+
195
+ if ((index + 1) % 7 === 0) {
196
+ weeks[weeks.length - 1].weekNumber = getWeekNumber(day.date)
197
+ }
198
+
199
+ weeks[weeks.length - 1].days.push(day)
113
200
  })
114
201
 
115
202
  return weeks
@@ -19,7 +19,7 @@ export interface CCardProps extends HTMLAttributes<HTMLDivElement> {
19
19
  /**
20
20
  * Sets the text color context of the component to one of CoreUI’s themed colors.
21
21
  *
22
- * @type 'primary' | 'secondary' | 'success' | 'danger' | 'warning' | 'info' | 'dark' | 'light' | 'white' | 'muted' | 'high-emphasis' | 'medium-emphasis' | 'disabled' | 'high-emphasis-inverse' | 'medium-emphasis-inverse' | 'disabled-inverse' | string
22
+ * @type 'primary' | 'secondary' | 'success' | 'danger' | 'warning' | 'info' | 'dark' | 'light' | 'primary-emphasis' | 'secondary-emphasis' | 'success-emphasis' | 'danger-emphasis' | 'warning-emphasis' | 'info-emphasis' | 'light-emphasis' | 'body' | 'body-emphasis' | 'body-secondary' | 'body-tertiary' | 'black' | 'black-50' | 'white' | 'white-50' | string
23
23
  */
24
24
  textColor?: string
25
25
  }
@@ -226,11 +226,11 @@ export const CCarousel = forwardRef<HTMLDivElement, CCarouselProps>(
226
226
  className={classNames(
227
227
  'carousel slide',
228
228
  {
229
- 'carousel-dark': dark,
230
229
  'carousel-fade': transition === 'crossfade',
231
230
  },
232
231
  className,
233
232
  )}
233
+ {...(dark && { 'data-coreui-theme': 'dark' })}
234
234
  onMouseEnter={_pause}
235
235
  onMouseLeave={cycle}
236
236
  {...(touch && { onTouchStart: handleTouchStart, onTouchMove: handleTouchMove })}
@@ -244,20 +244,24 @@ export const CCarousel = forwardRef<HTMLDivElement, CCarouselProps>(
244
244
  }}
245
245
  >
246
246
  {indicators && (
247
- <ol className="carousel-indicators">
247
+ <div className="carousel-indicators">
248
248
  {Array.from({ length: itemsNumber }, (_, i) => i).map((index) => {
249
249
  return (
250
- <li
250
+ <button
251
251
  key={`indicator${index}`}
252
252
  onClick={() => {
253
253
  !animating && handleIndicatorClick(index)
254
254
  }}
255
- className={active === index ? 'active' : ''}
255
+ className={classNames({
256
+ active: active === index
257
+ })}
256
258
  data-coreui-target=""
259
+ {...(active === index && { 'aria-current': true })}
260
+ aria-label={`Slide ${index + 1}`}
257
261
  />
258
262
  )
259
263
  })}
260
- </ol>
264
+ </div>
261
265
  )}
262
266
  <div className="carousel-inner">
263
267
  {Children.map(children, (child, index) => {
@@ -5,22 +5,26 @@ exports[`loads and displays CCarousel component 1`] = `
5
5
  <div
6
6
  class="carousel slide"
7
7
  >
8
- <ol
8
+ <div
9
9
  class="carousel-indicators"
10
10
  >
11
- <li
11
+ <button
12
+ aria-current="true"
13
+ aria-label="Slide 1"
12
14
  class="active"
13
15
  data-coreui-target=""
14
16
  />
15
- <li
17
+ <button
18
+ aria-label="Slide 2"
16
19
  class=""
17
20
  data-coreui-target=""
18
21
  />
19
- <li
22
+ <button
23
+ aria-label="Slide 3"
20
24
  class=""
21
25
  data-coreui-target=""
22
26
  />
23
- </ol>
27
+ </div>
24
28
  <div
25
29
  class="carousel-inner"
26
30
  >
@@ -7,18 +7,24 @@ export interface CCloseButtonProps extends HTMLAttributes<HTMLButtonElement> {
7
7
  * A string of all className you want applied to the base component.
8
8
  */
9
9
  className?: string
10
+ /**
11
+ * Invert the default color.
12
+ */
13
+ dark?: boolean
10
14
  /**
11
15
  * Toggle the disabled state for the component.
12
16
  */
13
17
  disabled?: boolean
14
18
  /**
15
19
  * Change the default color to white.
20
+ *
21
+ * @deprecated 5.0.0
16
22
  */
17
23
  white?: boolean
18
24
  }
19
25
 
20
26
  export const CCloseButton = forwardRef<HTMLButtonElement, CCloseButtonProps>(
21
- ({ className, disabled, white, ...rest }, ref) => {
27
+ ({ className, dark, disabled, white, ...rest }, ref) => {
22
28
  return (
23
29
  <button
24
30
  type="button"
@@ -33,6 +39,7 @@ export const CCloseButton = forwardRef<HTMLButtonElement, CCloseButtonProps>(
33
39
  )}
34
40
  aria-label="Close"
35
41
  disabled={disabled}
42
+ {...(dark && { 'data-coreui-theme': 'dark' })}
36
43
  {...rest}
37
44
  ref={ref}
38
45
  />
@@ -42,6 +49,7 @@ export const CCloseButton = forwardRef<HTMLButtonElement, CCloseButtonProps>(
42
49
 
43
50
  CCloseButton.propTypes = {
44
51
  className: PropTypes.string,
52
+ dark: PropTypes.bool,
45
53
  disabled: PropTypes.bool,
46
54
  white: PropTypes.bool,
47
55
  }
@@ -223,7 +223,9 @@ export const CDateRangePicker = forwardRef<HTMLDivElement | HTMLLIElement, CDate
223
223
  required,
224
224
  separator = true,
225
225
  selectAdjacementDays,
226
+ selectionType = 'day',
226
227
  showAdjacementDays,
228
+ showWeekNumber,
227
229
  size,
228
230
  startDate,
229
231
  text,
@@ -245,50 +247,46 @@ export const CDateRangePicker = forwardRef<HTMLDivElement | HTMLLIElement, CDate
245
247
  const inputStartRef = useRef<HTMLInputElement>(null)
246
248
  const formRef = useRef<HTMLFormElement>()
247
249
 
248
- const [_calendarDate, setCalendarDate] = useState<Date>(
249
- calendarDate ? new Date(calendarDate) : new Date(),
250
- )
251
- const [_endDate, setEndDate] = useState<Date | null>(endDate ? new Date(endDate) : null)
252
- const [_maxDate, setMaxDate] = useState<Date | null>(maxDate ? new Date(maxDate) : null)
253
- const [_minDate, setMinDate] = useState<Date | null>(minDate ? new Date(minDate) : null)
254
- const [_startDate, setStartDate] = useState<Date | null>(startDate ? new Date(startDate) : null)
250
+ const [_calendarDate, setCalendarDate] = useState<Date | string | null>(calendarDate ?? null)
251
+ const [_endDate, setEndDate] = useState<Date | string | null>(endDate ?? null)
252
+ const [_maxDate, setMaxDate] = useState<Date | string | null>(maxDate ?? null)
253
+ const [_minDate, setMinDate] = useState<Date | string | null>(minDate ?? null)
254
+ const [_startDate, setStartDate] = useState<Date | string | null>(startDate ?? null)
255
255
  const [_visible, setVisible] = useState(visible)
256
256
 
257
- const [initialStartDate, setInitialStartDate] = useState<Date | null>(
258
- startDate ? new Date(startDate) : null,
259
- )
260
- const [initialEndDate, setInitialEndDate] = useState<Date | null>(
261
- endDate ? new Date(endDate) : null,
257
+ const [initialStartDate, setInitialStartDate] = useState<Date | string | null>(
258
+ startDate ?? null,
262
259
  )
263
- const [inputStartHoverValue, setInputStartHoverValue] = useState<Date | null>(null)
264
- const [inputEndHoverValue, setInputEndHoverValue] = useState<Date | null>(null)
265
- const [isValid, setIsValid] = useState(valid || (invalid && false))
260
+ const [initialEndDate, setInitialEndDate] = useState<Date | string | null>(endDate ?? null)
261
+ const [inputStartHoverValue, setInputStartHoverValue] = useState<Date | string | null>(null)
262
+ const [inputEndHoverValue, setInputEndHoverValue] = useState<Date | string | null>(null)
263
+ const [isValid, setIsValid] = useState(valid ?? (invalid === true ? false : undefined))
266
264
  const [selectEndDate, setSelectEndDate] = useState(false)
267
265
 
268
266
  useEffect(() => {
269
- setIsValid(valid || (invalid && false))
267
+ setIsValid(valid ?? (invalid === true ? false : undefined))
270
268
  }, [valid, invalid])
271
269
 
272
270
  useEffect(() => {
273
271
  if (startDate) {
274
- setStartDate(new Date(startDate))
275
- setCalendarDate(new Date(startDate))
272
+ setStartDate(startDate)
273
+ setCalendarDate(startDate)
276
274
  }
277
275
  }, [startDate])
278
276
 
279
277
  useEffect(() => {
280
278
  if (endDate) {
281
- setEndDate(new Date(endDate))
282
- setCalendarDate(new Date(endDate))
279
+ setEndDate(endDate)
280
+ setCalendarDate(endDate)
283
281
  }
284
282
  }, [endDate])
285
283
 
286
284
  useEffect(() => {
287
- maxDate && setMaxDate(new Date(maxDate))
285
+ maxDate && setMaxDate(maxDate)
288
286
  }, [maxDate])
289
287
 
290
288
  useEffect(() => {
291
- minDate && setMinDate(new Date(minDate))
289
+ minDate && setMinDate(minDate)
292
290
  }, [minDate])
293
291
 
294
292
  useEffect(() => {
@@ -325,15 +323,21 @@ export const CDateRangePicker = forwardRef<HTMLDivElement | HTMLLIElement, CDate
325
323
  }
326
324
  }, [formRef, _startDate, _endDate])
327
325
 
328
- const formatDate = (date: Date) => {
329
- return format
330
- ? dateFormat(date, format)
331
- : timepicker
332
- ? date.toLocaleString(locale)
333
- : date.toLocaleDateString(locale)
326
+ const formatDate = (date: Date | string) => {
327
+ if (selectionType !== 'day') {
328
+ return date
329
+ }
330
+
331
+ const _date = new Date(date)
332
+
333
+ return format ?
334
+ dateFormat(_date, format) :
335
+ timepicker ?
336
+ _date.toLocaleString(locale) :
337
+ _date.toLocaleDateString(locale)
334
338
  }
335
339
 
336
- const setInputValue = (el: HTMLInputElement | null, date: Date | null) => {
340
+ const setInputValue = (el: HTMLInputElement | null, date: Date | string | null) => {
337
341
  if (!el) {
338
342
  return
339
343
  }
@@ -346,23 +350,17 @@ export const CDateRangePicker = forwardRef<HTMLDivElement | HTMLLIElement, CDate
346
350
  el.value = ''
347
351
  }
348
352
 
349
- const handleDayHover = (date: Date | null) => {
353
+ const handleDateHover = (date: Date | string | null) => {
350
354
  selectEndDate ? setInputEndHoverValue(date) : setInputStartHoverValue(date)
351
355
  }
352
356
 
353
- const handleCalendarDateChange = (date: Date, difference?: number) => {
354
- difference
355
- ? setCalendarDate(new Date(date.getFullYear(), date.getMonth() - difference, 1))
356
- : setCalendarDate(date)
357
- }
358
-
359
357
  const handleClear = (event: React.MouseEvent<HTMLElement>) => {
360
358
  event.stopPropagation()
361
359
  setStartDate(null)
362
360
  setEndDate(null)
363
361
  }
364
362
 
365
- const handleEndDateChange = (date: Date | null) => {
363
+ const handleEndDateChange = (date: Date | string | null) => {
366
364
  setEndDate(date)
367
365
  setInputEndHoverValue(null)
368
366
  onEndDateChange && onEndDateChange(date, date ? formatDate(date) : undefined)
@@ -388,7 +386,7 @@ export const CDateRangePicker = forwardRef<HTMLDivElement | HTMLLIElement, CDate
388
386
  setIsValid(false)
389
387
  }
390
388
 
391
- const handleStartDateChange = (date: Date | null) => {
389
+ const handleStartDateChange = (date: Date | string | null) => {
392
390
  setStartDate(date)
393
391
  setInputStartHoverValue(null)
394
392
  onStartDateChange && onStartDateChange(date, date ? formatDate(date) : undefined)
@@ -409,7 +407,7 @@ export const CDateRangePicker = forwardRef<HTMLDivElement | HTMLLIElement, CDate
409
407
  className={classNames('date-picker-input', {
410
408
  hover: inputStartHoverValue,
411
409
  })}
412
- // delay={true}
410
+ // delay={true} TODO
413
411
  disabled={disabled}
414
412
  {...(id && { name: range ? `${id}-start-date` : `${id}-date` })}
415
413
  placeholder={Array.isArray(placeholder) ? placeholder[0] : placeholder}
@@ -432,7 +430,7 @@ export const CDateRangePicker = forwardRef<HTMLDivElement | HTMLLIElement, CDate
432
430
  className={classNames('date-picker-input', {
433
431
  hover: inputEndHoverValue,
434
432
  })}
435
- // delay={true}
433
+ // delay={true} TODO
436
434
  disabled={disabled}
437
435
  {...(id && { name: `${id}-end-date` })}
438
436
  placeholder={placeholder[1]}
@@ -588,10 +586,12 @@ export const CDateRangePicker = forwardRef<HTMLDivElement | HTMLLIElement, CDate
588
586
  range={range}
589
587
  selectAdjacementDays={selectAdjacementDays}
590
588
  selectEndDate={selectEndDate}
589
+ selectionType={selectionType}
591
590
  showAdjacementDays={showAdjacementDays}
591
+ showWeekNumber={showWeekNumber}
592
592
  startDate={_startDate}
593
- onDayHover={(date) => handleDayHover(date)}
594
- onCalendarDateChange={(date) => handleCalendarDateChange(date)}
593
+ onDateHover={(date) => handleDateHover(date)}
594
+ onCalendarDateChange={(date) => setCalendarDate(date)}
595
595
  onStartDateChange={(date) => handleStartDateChange(date)}
596
596
  onEndDateChange={(date) => handleEndDateChange(date)}
597
597
  onSelectEndChange={(value) => setSelectEndDate(value)}
@@ -606,7 +606,7 @@ export const CDateRangePicker = forwardRef<HTMLDivElement | HTMLLIElement, CDate
606
606
  disabled={_startDate === null ? true : false}
607
607
  locale={locale}
608
608
  onTimeChange={(_, __, date) => date && handleStartDateChange(date)}
609
- time={_startDate}
609
+ time={_startDate && new Date(_startDate)}
610
610
  variant="select"
611
611
  />
612
612
  <CTimePicker
@@ -614,7 +614,7 @@ export const CDateRangePicker = forwardRef<HTMLDivElement | HTMLLIElement, CDate
614
614
  disabled={_endDate === null ? true : false}
615
615
  locale={locale}
616
616
  onTimeChange={(_, __, date) => date && handleEndDateChange(date)}
617
- time={_endDate}
617
+ time={_endDate && new Date(_endDate)}
618
618
  variant="select"
619
619
  />
620
620
  </>
@@ -638,7 +638,11 @@ export const CDateRangePicker = forwardRef<HTMLDivElement | HTMLLIElement, CDate
638
638
  ? date && handleStartDateChange(date)
639
639
  : date && handleEndDateChange(date)
640
640
  }
641
- time={index === 0 ? _startDate : _endDate}
641
+ time={
642
+ index === 0
643
+ ? _startDate && new Date(_startDate)
644
+ : _endDate && new Date(_endDate)
645
+ }
642
646
  variant="select"
643
647
  />
644
648
  ))
@@ -107,6 +107,28 @@ interface ContextProps extends CDropdownProps {
107
107
  portal: boolean
108
108
  }
109
109
 
110
+ export const getNextActiveElement = (
111
+ list: HTMLElement[],
112
+ activeElement: HTMLElement,
113
+ shouldGetNext: boolean,
114
+ isCycleAllowed: boolean,
115
+ ) => {
116
+ const listLength = list.length
117
+ let index = list.indexOf(activeElement)
118
+
119
+ if (index === -1) {
120
+ return !shouldGetNext && isCycleAllowed ? list[listLength - 1] : list[0]
121
+ }
122
+
123
+ index += shouldGetNext ? 1 : -1
124
+
125
+ if (isCycleAllowed) {
126
+ index = (index + listLength) % listLength
127
+ }
128
+
129
+ return list[Math.max(0, Math.min(index, listLength - 1))]
130
+ }
131
+
110
132
  const getPlacement = (
111
133
  placement: Placements,
112
134
  direction: CDropdownProps['direction'],
@@ -207,9 +229,12 @@ export const CDropdown = forwardRef<HTMLDivElement | HTMLLIElement, CDropdownPro
207
229
 
208
230
  useEffect(() => {
209
231
  if (_visible && dropdownToggleRef.current && dropdownMenuRef.current) {
232
+ dropdownToggleRef.current.focus()
210
233
  popper && initPopper(dropdownToggleRef.current, dropdownMenuRef.current, popperConfig)
211
234
  window.addEventListener('mouseup', handleMouseUp)
212
235
  window.addEventListener('keyup', handleKeyup)
236
+ dropdownToggleRef.current.addEventListener('keydown', handleKeydown)
237
+ dropdownMenuRef.current.addEventListener('keydown', handleKeydown)
213
238
  onShow && onShow()
214
239
  }
215
240
 
@@ -217,10 +242,28 @@ export const CDropdown = forwardRef<HTMLDivElement | HTMLLIElement, CDropdownPro
217
242
  popper && destroyPopper()
218
243
  window.removeEventListener('mouseup', handleMouseUp)
219
244
  window.removeEventListener('keyup', handleKeyup)
245
+ dropdownToggleRef.current &&
246
+ dropdownToggleRef.current.removeEventListener('keydown', handleKeydown)
247
+ dropdownMenuRef.current &&
248
+ dropdownMenuRef.current.removeEventListener('keydown', handleKeydown)
220
249
  onHide && onHide()
221
250
  }
222
251
  }, [_visible])
223
252
 
253
+ const handleKeydown = (event: KeyboardEvent) => {
254
+ if (_visible && (event.key === 'ArrowDown' || event.key === 'ArrowUp')) {
255
+ const target = event.target as HTMLElement
256
+ event.preventDefault()
257
+ const items = [].concat(
258
+ ...Element.prototype.querySelectorAll.call(
259
+ dropdownMenuRef.current,
260
+ '.dropdown-item:not(.disabled):not(:disabled)',
261
+ ),
262
+ )
263
+ getNextActiveElement(items, target, event.key === 'ArrowDown', true).focus()
264
+ }
265
+ }
266
+
224
267
  const handleKeyup = (event: KeyboardEvent) => {
225
268
  if (autoClose === false) {
226
269
  return
@@ -263,7 +306,6 @@ export const CDropdown = forwardRef<HTMLDivElement | HTMLLIElement, CDropdownPro
263
306
  'dropup dropup-center': direction === 'dropup-center',
264
307
  [`${direction}`]:
265
308
  direction && direction !== 'center' && direction !== 'dropup-center',
266
- show: _visible,
267
309
  },
268
310
  className,
269
311
  )}
@@ -46,7 +46,6 @@ export const CDropdownMenu = forwardRef<HTMLDivElement | HTMLUListElement, CDrop
46
46
  className={classNames(
47
47
  'dropdown-menu',
48
48
  {
49
- 'dropdown-menu-dark': dark,
50
49
  show: visible,
51
50
  },
52
51
  alignment && alignmentClassNames(alignment),
@@ -56,6 +55,7 @@ export const CDropdownMenu = forwardRef<HTMLDivElement | HTMLUListElement, CDrop
56
55
  role="menu"
57
56
  aria-hidden={!visible}
58
57
  {...(!popper && { 'data-coreui-popper': 'static' })}
58
+ {...(dark && { 'data-coreui-theme': 'dark' })}
59
59
  {...rest}
60
60
  >
61
61
  {Component === 'ul'
@@ -39,7 +39,7 @@ export const CDropdownToggle: FC<CDropdownToggleProps> = ({
39
39
  trigger = 'click',
40
40
  ...rest
41
41
  }) => {
42
- const { dropdownToggleRef, variant, visible, setVisible } = useContext(CDropdownContext)
42
+ const { dropdownToggleRef, visible, setVisible } = useContext(CDropdownContext)
43
43
 
44
44
  const triggers = {
45
45
  ...((trigger === 'click' || trigger.includes('click')) && {
@@ -59,7 +59,7 @@ export const CDropdownToggle: FC<CDropdownToggleProps> = ({
59
59
  {
60
60
  'dropdown-toggle': caret,
61
61
  'dropdown-toggle-split': split,
62
- 'nav-link': variant === 'nav-item',
62
+ show: visible,
63
63
  },
64
64
  className,
65
65
  ),
@@ -67,7 +67,6 @@ export const CDropdownToggle: FC<CDropdownToggleProps> = ({
67
67
  ...(!rest.disabled && { ...triggers }),
68
68
  }
69
69
 
70
- // We use any because Toggler can be `a` as well as `button`.
71
70
  const Toggler = () => {
72
71
  if (custom && React.isValidElement(children)) {
73
72
  return (
@@ -81,16 +80,8 @@ export const CDropdownToggle: FC<CDropdownToggleProps> = ({
81
80
  )
82
81
  }
83
82
 
84
- if (variant === 'nav-item') {
85
- return (
86
- <a href="#" {...togglerProps} ref={dropdownToggleRef}>
87
- {children}
88
- </a>
89
- )
90
- }
91
-
92
83
  return (
93
- <CButton type="button" {...togglerProps} tabIndex={0} {...rest} ref={dropdownToggleRef}>
84
+ <CButton {...togglerProps} tabIndex={0} {...rest} ref={dropdownToggleRef}>
94
85
  {children}
95
86
  {split && <span className="visually-hidden">Toggle Dropdown</span>}
96
87
  </CButton>