@coreui/react-pro 4.9.0-next.1 → 4.9.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 (171) hide show
  1. package/README.md +1 -1
  2. package/dist/components/conditional-portal/CConditionalPortal.d.ts +12 -0
  3. package/dist/components/conditional-portal/index.d.ts +2 -0
  4. package/dist/components/form/CFormCheck.d.ts +7 -1
  5. package/dist/components/form/CFormSwitch.d.ts +6 -0
  6. package/dist/components/index.d.ts +1 -0
  7. package/dist/components/table/CTableResponsiveWrapper.d.ts +0 -1
  8. package/dist/index.es.js +498 -720
  9. package/dist/index.es.js.map +1 -1
  10. package/dist/index.js +497 -718
  11. package/dist/index.js.map +1 -1
  12. package/package.json +11 -6
  13. package/src/components/accordion/CAccordion.tsx +7 -3
  14. package/src/components/accordion/CAccordionBody.tsx +1 -2
  15. package/src/components/accordion/CAccordionButton.tsx +1 -3
  16. package/src/components/accordion/CAccordionHeader.tsx +1 -3
  17. package/src/components/accordion/CAccordionItem.tsx +2 -4
  18. package/src/components/accordion/__tests__/__snapshots__/CAccordionBody.spec.tsx.snap +2 -2
  19. package/src/components/alert/CAlert.tsx +19 -27
  20. package/src/components/alert/CAlertHeading.tsx +1 -3
  21. package/src/components/alert/CAlertLink.tsx +1 -3
  22. package/src/components/alert/__tests__/__snapshots__/CAlert.spec.tsx.snap +1 -1
  23. package/src/components/avatar/CAvatar.tsx +14 -11
  24. package/src/components/backdrop/CBackdrop.tsx +9 -12
  25. package/src/components/badge/CBadge.tsx +19 -17
  26. package/src/components/breadcrumb/CBreadcrumb.tsx +1 -2
  27. package/src/components/breadcrumb/CBreadcrumbItem.tsx +12 -8
  28. package/src/components/button/CButton.tsx +7 -9
  29. package/src/components/button-group/CButtonGroup.tsx +9 -7
  30. package/src/components/button-group/CButtonToolbar.tsx +1 -3
  31. package/src/components/calendar/utils.ts +7 -9
  32. package/src/components/callout/CCallout.tsx +11 -9
  33. package/src/components/card/CCard.tsx +12 -10
  34. package/src/components/card/CCardBody.tsx +1 -3
  35. package/src/components/card/CCardFooter.tsx +1 -3
  36. package/src/components/card/CCardGroup.tsx +1 -3
  37. package/src/components/card/CCardHeader.tsx +1 -3
  38. package/src/components/card/CCardImage.tsx +5 -3
  39. package/src/components/card/CCardImageOverlay.tsx +1 -3
  40. package/src/components/card/CCardLink.tsx +1 -3
  41. package/src/components/card/CCardSubtitle.tsx +1 -3
  42. package/src/components/card/CCardText.tsx +1 -3
  43. package/src/components/card/CCardTitle.tsx +1 -3
  44. package/src/components/carousel/CCarousel.tsx +8 -8
  45. package/src/components/carousel/CCarouselCaption.tsx +1 -3
  46. package/src/components/carousel/CCarouselItem.tsx +11 -9
  47. package/src/components/close-button/CCloseButton.tsx +9 -10
  48. package/src/components/collapse/CCollapse.tsx +8 -20
  49. package/src/components/collapse/__tests__/CCollapse.spec.tsx +2 -3
  50. package/src/components/conditional-portal/CConditionalPortal.tsx +29 -0
  51. package/src/components/conditional-portal/index.ts +3 -0
  52. package/src/components/date-range-picker/CDateRangePicker.tsx +9 -11
  53. package/src/components/date-range-picker/utils.ts +2 -2
  54. package/src/components/dropdown/CDropdown.tsx +24 -22
  55. package/src/components/dropdown/CDropdownDivider.tsx +1 -3
  56. package/src/components/dropdown/CDropdownHeader.tsx +1 -3
  57. package/src/components/dropdown/CDropdownItem.tsx +6 -3
  58. package/src/components/dropdown/CDropdownItemPlain.tsx +1 -3
  59. package/src/components/dropdown/CDropdownMenu.tsx +27 -31
  60. package/src/components/dropdown/CDropdownToggle.tsx +29 -23
  61. package/src/components/dropdown/__tests__/CDropdown.spec.tsx +2 -4
  62. package/src/components/dropdown/__tests__/__snapshots__/CDropdown.spec.tsx.snap +1 -1
  63. package/src/components/footer/CFooter.tsx +5 -3
  64. package/src/components/form/CForm.tsx +5 -2
  65. package/src/components/form/CFormCheck.tsx +87 -63
  66. package/src/components/form/CFormControlWrapper.tsx +3 -3
  67. package/src/components/form/CFormFeedback.tsx +11 -8
  68. package/src/components/form/CFormFloating.tsx +1 -2
  69. package/src/components/form/CFormInput.tsx +10 -12
  70. package/src/components/form/CFormLabel.tsx +1 -2
  71. package/src/components/form/CFormRange.tsx +1 -2
  72. package/src/components/form/CFormSelect.tsx +15 -10
  73. package/src/components/form/CFormSwitch.tsx +31 -20
  74. package/src/components/form/CFormText.tsx +1 -2
  75. package/src/components/form/CFormTextarea.tsx +13 -9
  76. package/src/components/form/CInputGroup.tsx +11 -8
  77. package/src/components/form/CInputGroupText.tsx +1 -2
  78. package/src/components/form/__tests__/CFormRange.spec.tsx +1 -1
  79. package/src/components/form/__tests__/__snapshots__/CForm.spec.tsx.snap +2 -6
  80. package/src/components/form/__tests__/__snapshots__/CFormRange.spec.tsx.snap +2 -2
  81. package/src/components/grid/CCol.tsx +8 -6
  82. package/src/components/grid/CContainer.tsx +8 -6
  83. package/src/components/grid/CRow.tsx +4 -3
  84. package/src/components/header/CHeader.tsx +12 -13
  85. package/src/components/header/CHeaderBrand.tsx +1 -3
  86. package/src/components/header/CHeaderBrand.tsx~HEAD +1 -3
  87. package/src/components/header/CHeaderDivider.tsx +1 -3
  88. package/src/components/header/CHeaderNav.tsx +6 -3
  89. package/src/components/header/CHeaderText.tsx +1 -3
  90. package/src/components/header/CHeaderToggler.tsx +2 -4
  91. package/src/components/image/CImage.tsx +17 -10
  92. package/src/components/image/__tests__/__snapshots__/CImage.spec.tsx.snap +1 -3
  93. package/src/components/index.ts +1 -0
  94. package/src/components/link/CLink.tsx +2 -4
  95. package/src/components/list-group/CListGroup.tsx +11 -10
  96. package/src/components/list-group/CListGroupItem.tsx +13 -12
  97. package/src/components/loading-button/CLoadingButton.tsx +1 -3
  98. package/src/components/modal/CModal.tsx +55 -70
  99. package/src/components/modal/CModalBody.tsx +1 -3
  100. package/src/components/modal/CModalContent.tsx +1 -3
  101. package/src/components/modal/CModalDialog.tsx +16 -14
  102. package/src/components/modal/CModalFooter.tsx +1 -3
  103. package/src/components/modal/CModalHeader.tsx +1 -2
  104. package/src/components/modal/CModalTitle.tsx +1 -3
  105. package/src/components/modal/__tests__/CModal.spec.tsx +19 -20
  106. package/src/components/multi-select/CMultiSelect.tsx +19 -19
  107. package/src/components/multi-select/utils.ts +3 -3
  108. package/src/components/nav/CNav.tsx +13 -10
  109. package/src/components/nav/CNavGroup.tsx +1 -3
  110. package/src/components/nav/CNavGroupItems.tsx +1 -2
  111. package/src/components/nav/CNavItem.tsx +8 -10
  112. package/src/components/nav/CNavLink.tsx +1 -2
  113. package/src/components/nav/CNavTitle.tsx +1 -2
  114. package/src/components/navbar/CNavbar.tsx +21 -22
  115. package/src/components/navbar/CNavbarBrand.tsx +2 -3
  116. package/src/components/navbar/CNavbarNav.tsx +6 -3
  117. package/src/components/navbar/CNavbarText.tsx +1 -3
  118. package/src/components/navbar/CNavbarToggler.tsx +2 -4
  119. package/src/components/offcanvas/COffcanvas.tsx +39 -66
  120. package/src/components/offcanvas/COffcanvasBody.tsx +1 -3
  121. package/src/components/offcanvas/COffcanvasHeader.tsx +1 -3
  122. package/src/components/offcanvas/COffcanvasTitle.tsx +1 -3
  123. package/src/components/offcanvas/__tests__/COffcanvas.spec.tsx +7 -2
  124. package/src/components/offcanvas/__tests__/__snapshots__/COffcanvas.spec.tsx.snap +9 -4
  125. package/src/components/pagination/CPagination.tsx +12 -9
  126. package/src/components/pagination/CPaginationItem.tsx +12 -11
  127. package/src/components/pagination/__tests__/CPagination.spec.tsx +3 -3
  128. package/src/components/pagination/__tests__/CPaginationItem.spec.tsx +3 -3
  129. package/src/components/picker/CPicker.tsx +6 -6
  130. package/src/components/placeholder/CPlaceholder.tsx +13 -11
  131. package/src/components/popover/CPopover.tsx +22 -33
  132. package/src/components/progress/CProgress.tsx +12 -10
  133. package/src/components/progress/CProgressBar.tsx +9 -11
  134. package/src/components/sidebar/CSidebar.tsx +20 -18
  135. package/src/components/sidebar/CSidebarBrand.tsx +1 -2
  136. package/src/components/sidebar/CSidebarFooter.tsx +1 -2
  137. package/src/components/sidebar/CSidebarHeader.tsx +1 -2
  138. package/src/components/sidebar/CSidebarNav.tsx +2 -2
  139. package/src/components/sidebar/CSidebarToggler.tsx +1 -2
  140. package/src/components/smart-pagination/CSmartPagination.tsx +22 -20
  141. package/src/components/smart-table/CSmartTable.tsx +4 -8
  142. package/src/components/smart-table/utils.ts +3 -4
  143. package/src/components/spinner/CSpinner.tsx +11 -8
  144. package/src/components/table/CTable.tsx +20 -18
  145. package/src/components/table/CTableBody.tsx +12 -8
  146. package/src/components/table/CTableDataCell.tsx +14 -10
  147. package/src/components/table/CTableFoot.tsx +12 -8
  148. package/src/components/table/CTableHead.tsx +12 -8
  149. package/src/components/table/CTableHeaderCell.tsx +12 -8
  150. package/src/components/table/CTableResponsiveWrapper.tsx +2 -3
  151. package/src/components/table/CTableRow.tsx +14 -10
  152. package/src/components/table/__tests__/__snapshots__/CTable.spec.tsx.snap +1 -5
  153. package/src/components/table/utils.ts +2 -7
  154. package/src/components/tabs/CTabContent.tsx +1 -2
  155. package/src/components/tabs/CTabPane.tsx +17 -20
  156. package/src/components/tabs/__tests__/CTabPane.spec.tsx +2 -5
  157. package/src/components/tabs/__tests__/__snapshots__/CTabPane.spec.tsx.snap +1 -1
  158. package/src/components/time-picker/CTimePicker.tsx +12 -14
  159. package/src/components/toast/CToast.tsx +29 -42
  160. package/src/components/toast/CToastBody.tsx +1 -2
  161. package/src/components/toast/CToastClose.tsx +3 -1
  162. package/src/components/toast/CToastHeader.tsx +1 -2
  163. package/src/components/toast/CToaster.tsx +26 -26
  164. package/src/components/toast/__tests__/CToast.spec.tsx +2 -1
  165. package/src/components/toast/__tests__/__snapshots__/CToast.spec.tsx.snap +1 -66
  166. package/src/components/tooltip/CTooltip.tsx +21 -32
  167. package/src/components/virtual-scroller/CVirtualScroller.tsx +4 -6
  168. package/src/components/widgets/CWidgetStatsA.tsx +8 -6
  169. package/src/components/widgets/CWidgetStatsD.tsx +9 -10
  170. package/src/components/widgets/CWidgetStatsE.tsx +1 -3
  171. package/src/components/widgets/CWidgetStatsF.tsx +1 -4
@@ -8,7 +8,6 @@ exports[`CTable customize 1`] = `
8
8
  <table
9
9
  class="table align-middle border-primary caption-top table-bordered table-borderless table-info table-hover table-sm table-striped bazinga"
10
10
  >
11
- <tbody />
12
11
  <tbody>
13
12
  <tr>
14
13
  <td>
@@ -26,7 +25,6 @@ exports[`CTable full example test 1`] = `
26
25
  <table
27
26
  class="table caption-top"
28
27
  >
29
- <tbody />
30
28
  <caption>
31
29
  List of users
32
30
  </caption>
@@ -194,8 +192,6 @@ exports[`loads and displays CTable component 1`] = `
194
192
  <div>
195
193
  <table
196
194
  class="table"
197
- >
198
- <tbody />
199
- </table>
195
+ />
200
196
  </div>
201
197
  `;
@@ -11,17 +11,12 @@ export const pretifyName = (name: string) => {
11
11
  }
12
12
 
13
13
  export const getColumnLabel = (column: Column | string) =>
14
- typeof column === 'object'
15
- ? column.label !== undefined
16
- ? column.label
17
- : pretifyName(column.key)
18
- : pretifyName(column)
14
+ typeof column === 'object' ? column.label ?? pretifyName(column.key) : pretifyName(column)
19
15
 
20
16
  export const getColumnNames = (columns: (string | Column)[] | undefined, items?: Item[]) =>
21
17
  columns
22
18
  ? columns.map((column: Column | string) => {
23
- if (typeof column === 'object') return column.key
24
- else return column
19
+ return typeof column === 'object' ? column.key : column
25
20
  })
26
21
  : items && getColumnNamesFromItems(items)
27
22
 
@@ -11,9 +11,8 @@ export interface CTabContentProps extends HTMLAttributes<HTMLDivElement> {
11
11
 
12
12
  export const CTabContent = forwardRef<HTMLDivElement, CTabContentProps>(
13
13
  ({ children, className, ...rest }, ref) => {
14
- const _className = classNames('tab-content', className)
15
14
  return (
16
- <div className={_className} {...rest} ref={ref}>
15
+ <div className={classNames('tab-content', className)} {...rest} ref={ref}>
17
16
  {children}
18
17
  </div>
19
18
  )
@@ -29,28 +29,25 @@ export const CTabPane = forwardRef<HTMLDivElement, CTabPaneProps>(
29
29
  const tabPaneRef = useRef()
30
30
  const forkedRef = useForkedRef(ref, tabPaneRef)
31
31
 
32
- const getTransitionClass = (state: string) => {
33
- return state === 'entered' && 'show'
34
- }
35
-
36
- const _className = classNames(
37
- 'tab-pane',
38
- 'fade',
39
- {
40
- active: visible,
41
- },
42
- className,
43
- )
44
32
  return (
45
33
  <Transition in={visible} nodeRef={tabPaneRef} onEnter={onShow} onExit={onHide} timeout={150}>
46
- {(state) => {
47
- const transitionClass = getTransitionClass(state)
48
- return (
49
- <div className={classNames(_className, transitionClass)} {...rest} ref={forkedRef}>
50
- {children}
51
- </div>
52
- )
53
- }}
34
+ {(state) => (
35
+ <div
36
+ className={classNames(
37
+ 'tab-pane',
38
+ 'fade',
39
+ {
40
+ active: visible,
41
+ show: state === 'entered',
42
+ },
43
+ className,
44
+ )}
45
+ {...rest}
46
+ ref={forkedRef}
47
+ >
48
+ {children}
49
+ </div>
50
+ )}
54
51
  </Transition>
55
52
  )
56
53
  },
@@ -18,7 +18,6 @@ test('CTabPane customize', async () => {
18
18
  })
19
19
 
20
20
  test('CTabContent use case test', async () => {
21
- jest.useFakeTimers()
22
21
  const { rerender } = render(
23
22
  <CTabContent>
24
23
  <CTabPane visible={false}>Test</CTabPane>
@@ -33,7 +32,7 @@ test('CTabContent use case test', async () => {
33
32
  )
34
33
  expect(screen.getByText('Test')).not.toHaveClass('show')
35
34
  expect(screen.getByText('Test')).toHaveClass('active')
36
- jest.runAllTimers()
35
+ await new Promise((r) => setTimeout(r, 1000))
37
36
  expect(screen.getByText('Test')).toHaveClass('show')
38
37
  expect(screen.getByText('Test')).toHaveClass('active')
39
38
  rerender(
@@ -43,9 +42,7 @@ test('CTabContent use case test', async () => {
43
42
  )
44
43
  expect(screen.getByText('Test')).not.toHaveClass('show')
45
44
  expect(screen.getByText('Test')).not.toHaveClass('active')
46
- jest.runAllTimers()
45
+ await new Promise((r) => setTimeout(r, 1000))
47
46
  expect(screen.getByText('Test')).not.toHaveClass('show')
48
47
  expect(screen.getByText('Test')).not.toHaveClass('active')
49
- jest.runAllTimers()
50
- jest.useRealTimers()
51
48
  })
@@ -3,7 +3,7 @@
3
3
  exports[`CTabPane customize 1`] = `
4
4
  <div>
5
5
  <div
6
- class="tab-pane fade active bazinga show"
6
+ class="tab-pane fade active show bazinga"
7
7
  >
8
8
  Test
9
9
  </div>
@@ -166,18 +166,18 @@ export const CTimePicker = forwardRef<HTMLDivElement | HTMLLIElement, CTimePicke
166
166
 
167
167
  if (set === 'hours') {
168
168
  if (localizedTimePartials && localizedTimePartials.hour12) {
169
- _date.setHours(convert12hTo24h(_ampm, parseInt(value)))
169
+ _date.setHours(convert12hTo24h(_ampm, Number.parseInt(value)))
170
170
  } else {
171
- _date.setHours(parseInt(value))
171
+ _date.setHours(Number.parseInt(value))
172
172
  }
173
173
  }
174
174
 
175
175
  if (set === 'minutes') {
176
- _date.setMinutes(parseInt(value))
176
+ _date.setMinutes(Number.parseInt(value))
177
177
  }
178
178
 
179
179
  if (set === 'seconds') {
180
- _date.setSeconds(parseInt(value))
180
+ _date.setSeconds(Number.parseInt(value))
181
181
  }
182
182
 
183
183
  setDate(new Date(_date))
@@ -333,15 +333,6 @@ export const CTimePicker = forwardRef<HTMLDivElement | HTMLLIElement, CTimePicke
333
333
  </>
334
334
  )
335
335
 
336
- const _className = classNames(
337
- 'time-picker',
338
- {
339
- 'is-invalid': invalid,
340
- 'is-valid': valid,
341
- },
342
- className,
343
- )
344
-
345
336
  return (
346
337
  <CFormControlWrapper
347
338
  describedby={rest['aria-describedby']}
@@ -356,7 +347,14 @@ export const CTimePicker = forwardRef<HTMLDivElement | HTMLLIElement, CTimePicke
356
347
  valid={valid}
357
348
  >
358
349
  <CPicker
359
- className={_className}
350
+ className={classNames(
351
+ 'time-picker',
352
+ {
353
+ 'is-invalid': invalid,
354
+ 'is-valid': valid,
355
+ },
356
+ className,
357
+ )}
360
358
  container={container}
361
359
  disabled={disabled}
362
360
  footer={footer}
@@ -114,55 +114,42 @@ export const CToast = forwardRef<HTMLDivElement, CToastProps>(
114
114
  }
115
115
  }
116
116
 
117
- const _className = classNames(
118
- 'toast',
119
- {
120
- fade: animation,
121
- [`bg-${color}`]: color,
122
- 'border-0': color,
123
- },
124
- className,
125
- )
126
-
127
- const getTransitionClass = (state: string) => {
128
- return state === 'entering'
129
- ? 'showing'
130
- : state === 'entered'
131
- ? 'show'
132
- : state === 'exiting'
133
- ? 'showing'
134
- : 'fade'
135
- }
136
-
137
117
  return (
138
118
  <Transition
139
119
  in={_visible}
140
120
  nodeRef={toastRef}
141
- onEnter={() => onShow && onShow(index ? index : null)}
142
- onExited={() => onClose && onClose(index ? index : null)}
121
+ onEnter={() => onShow && onShow(index ?? null)}
122
+ onExited={() => onClose && onClose(index ?? null)}
143
123
  timeout={250}
144
124
  unmountOnExit
145
125
  >
146
- {(state) => {
147
- const transitionClass = getTransitionClass(state)
148
- return (
149
- <CToastContext.Provider value={contextValues}>
150
- <div
151
- className={classNames(_className, transitionClass)}
152
- aria-live="assertive"
153
- aria-atomic="true"
154
- role="alert"
155
- onMouseEnter={() => clearTimeout(timeout.current)}
156
- onMouseLeave={() => _autohide()}
157
- {...rest}
158
- key={key}
159
- ref={forkedRef}
160
- >
161
- {children}
162
- </div>
163
- </CToastContext.Provider>
164
- )
165
- }}
126
+ {(state) => (
127
+ <CToastContext.Provider value={contextValues}>
128
+ <div
129
+ className={classNames(
130
+ 'toast',
131
+ {
132
+ fade: animation,
133
+ [`bg-${color}`]: color,
134
+ 'border-0': color,
135
+ 'show showing': state === 'entering' || state === 'exiting',
136
+ show: state === 'entered',
137
+ },
138
+ className,
139
+ )}
140
+ aria-live="assertive"
141
+ aria-atomic="true"
142
+ role="alert"
143
+ onMouseEnter={() => clearTimeout(timeout.current)}
144
+ onMouseLeave={() => _autohide()}
145
+ {...rest}
146
+ key={key}
147
+ ref={forkedRef}
148
+ >
149
+ {children}
150
+ </div>
151
+ </CToastContext.Provider>
152
+ )}
166
153
  </Transition>
167
154
  )
168
155
  },
@@ -11,9 +11,8 @@ export interface CToastBodyProps extends HTMLAttributes<HTMLDivElement> {
11
11
 
12
12
  export const CToastBody = forwardRef<HTMLDivElement, CToastBodyProps>(
13
13
  ({ children, className, ...rest }, ref) => {
14
- const _className = classNames('toast-body', className)
15
14
  return (
16
- <div className={_className} {...rest} ref={ref}>
15
+ <div className={classNames('toast-body', className)} {...rest} ref={ref}>
17
16
  {children}
18
17
  </div>
19
18
  )
@@ -1,11 +1,13 @@
1
1
  import React, { ElementType, forwardRef, useContext } from 'react'
2
2
  import PropTypes from 'prop-types'
3
- import { CToastContext } from './CToast'
4
3
 
5
4
  import { CButtonProps } from '../button/CButton'
6
5
  import { CCloseButton, CCloseButtonProps } from '../close-button/CCloseButton'
7
6
 
7
+ import { CToastContext } from './CToast'
8
+
8
9
  type CombineButtonProps = CCloseButtonProps & CButtonProps
10
+
9
11
  export interface CToastCloseProps extends CombineButtonProps {
10
12
  /**
11
13
  * Component used for the root node. Either a string to use a HTML element or a component.
@@ -17,9 +17,8 @@ export interface CToastHeaderProps extends Omit<HTMLAttributes<HTMLDivElement>,
17
17
 
18
18
  export const CToastHeader = forwardRef<HTMLDivElement, CToastHeaderProps>(
19
19
  ({ children, className, closeButton, ...rest }, ref) => {
20
- const _className = classNames('toast-header', className)
21
20
  return (
22
- <div className={_className} {...rest} ref={ref}>
21
+ <div className={classNames('toast-header', className)} {...rest} ref={ref}>
23
22
  {children}
24
23
  {closeButton && <CToastClose />}
25
24
  </div>
@@ -1,7 +1,7 @@
1
1
  import React, { forwardRef, HTMLAttributes, useEffect, useState, useRef, ReactElement } from 'react'
2
- import { createPortal } from 'react-dom'
3
2
  import PropTypes from 'prop-types'
4
3
  import classNames from 'classnames'
4
+ import { CConditionalPortal } from '../conditional-portal'
5
5
 
6
6
  export interface CToasterProps extends HTMLAttributes<HTMLDivElement> {
7
7
  /**
@@ -52,32 +52,32 @@ export const CToaster = forwardRef<HTMLDivElement, CToasterProps>(
52
52
  ])
53
53
  }
54
54
 
55
- const _className = classNames(
56
- 'toaster toast-container p-3',
57
- {
58
- 'position-fixed': placement,
59
- 'top-0': placement && placement.includes('top'),
60
- 'top-50 translate-middle-y': placement && placement.includes('middle'),
61
- 'bottom-0': placement && placement.includes('bottom'),
62
- 'start-0': placement && placement.includes('start'),
63
- 'start-50 translate-middle-x': placement && placement.includes('center'),
64
- 'end-0': placement && placement.includes('end'),
65
- },
66
- className,
55
+ return (
56
+ <CConditionalPortal portal={typeof placement === 'string'}>
57
+ {toasts.length > 0 || children ? (
58
+ <div
59
+ className={classNames(
60
+ 'toaster toast-container p-3',
61
+ {
62
+ 'position-fixed': placement,
63
+ 'top-0': placement && placement.includes('top'),
64
+ 'top-50 translate-middle-y': placement && placement.includes('middle'),
65
+ 'bottom-0': placement && placement.includes('bottom'),
66
+ 'start-0': placement && placement.includes('start'),
67
+ 'start-50 translate-middle-x': placement && placement.includes('center'),
68
+ 'end-0': placement && placement.includes('end'),
69
+ },
70
+ className,
71
+ )}
72
+ {...rest}
73
+ ref={ref}
74
+ >
75
+ {children}
76
+ {toasts.map((toast) => React.cloneElement(toast, { visible: true }))}
77
+ </div>
78
+ ) : null}
79
+ </CConditionalPortal>
67
80
  )
68
-
69
- const toaster = (ref?: React.Ref<HTMLDivElement>) => {
70
- return toasts.length > 0 || children ? (
71
- <div className={_className} {...rest} ref={ref}>
72
- {children}
73
- {toasts.map((toast) => React.cloneElement(toast, { visible: true }))}
74
- </div>
75
- ) : null
76
- }
77
-
78
- return typeof window !== 'undefined' && placement
79
- ? createPortal(toaster(ref), document.body)
80
- : toaster(ref)
81
81
  },
82
82
  )
83
83
 
@@ -32,7 +32,7 @@ test('CToast customize', async () => {
32
32
  })
33
33
 
34
34
  test('CToast click on dismiss button', async () => {
35
- jest.useFakeTimers()
35
+ // jest.useFakeTimers()
36
36
  const onClose = jest.fn()
37
37
  const { container } = render(
38
38
  <CToast
@@ -71,6 +71,7 @@ test('CToast click on dismiss button', async () => {
71
71
  fireEvent.click(btn)
72
72
  }
73
73
  jest.runAllTimers()
74
+ await new Promise((r) => setTimeout(r, 1000))
74
75
  expect(onClose).toHaveBeenCalledTimes(1)
75
76
  expect(container.firstChild).toBeNull()
76
77
  jest.useRealTimers()
@@ -5,72 +5,7 @@ exports[`CToast customize 1`] = `
5
5
  <div
6
6
  aria-atomic="true"
7
7
  aria-live="assertive"
8
- class="toast fade bg-warning border-0 bazinga showing"
9
- role="alert"
10
- >
11
- Test
12
- </div>
13
- </div>
14
- `;
15
-
16
- exports[`CToast customize 2`] = `
17
- <div>
18
- <div
19
- aria-atomic="true"
20
- aria-live="assertive"
21
- class="toast fade bg-warning border-0 bazinga showing"
22
- role="alert"
23
- >
24
- Test
25
- </div>
26
- </div>
27
- `;
28
-
29
- exports[`CToast customize 3`] = `
30
- <div>
31
- <div
32
- aria-atomic="true"
33
- aria-live="assertive"
34
- class="toast fade bg-warning border-0 bazinga showing"
35
- role="alert"
36
- >
37
- Test
38
- </div>
39
- </div>
40
- `;
41
-
42
- exports[`CToast customize 4`] = `
43
- <div>
44
- <div
45
- aria-atomic="true"
46
- aria-live="assertive"
47
- class="toast fade bg-warning border-0 bazinga showing"
48
- role="alert"
49
- >
50
- Test
51
- </div>
52
- </div>
53
- `;
54
-
55
- exports[`CToast customize 5`] = `
56
- <div>
57
- <div
58
- aria-atomic="true"
59
- aria-live="assertive"
60
- class="toast fade bg-warning border-0 bazinga showing"
61
- role="alert"
62
- >
63
- Test
64
- </div>
65
- </div>
66
- `;
67
-
68
- exports[`CToast customize 6`] = `
69
- <div>
70
- <div
71
- aria-atomic="true"
72
- aria-live="assertive"
73
- class="toast fade bg-warning border-0 bazinga show"
8
+ class="toast fade bg-warning border-0 show showing bazinga"
74
9
  role="alert"
75
10
  >
76
11
  Test
@@ -80,16 +80,6 @@ export const CTooltip: FC<CTooltipProps> = ({
80
80
  setVisible(visible)
81
81
  }, [visible])
82
82
 
83
- const getTransitionClass = (state: string) => {
84
- return state === 'entering'
85
- ? 'fade'
86
- : state === 'entered'
87
- ? 'fade show'
88
- : state === 'exiting'
89
- ? 'fade'
90
- : 'fade'
91
- }
92
-
93
83
  return (
94
84
  <>
95
85
  {React.cloneElement(children as React.ReactElement<any>, {
@@ -120,28 +110,27 @@ export const CTooltip: FC<CTooltipProps> = ({
120
110
  }}
121
111
  unmountOnExit
122
112
  >
123
- {(state) => {
124
- const transitionClass = getTransitionClass(state)
125
- return (
126
- <div
127
- className={classNames(
128
- `tooltip bs-tooltip-${
129
- placement === 'left' ? 'start' : placement === 'right' ? 'end' : placement
130
- }`,
131
- className,
132
- transitionClass,
133
- )}
134
- ref={setPopperElement}
135
- role="tooltip"
136
- style={styles.popper}
137
- {...attributes.popper}
138
- {...rest}
139
- >
140
- <div className="tooltip-arrow" style={styles.arrow} ref={setArrowElement}></div>
141
- <div className="tooltip-inner">{content}</div>
142
- </div>
143
- )
144
- }}
113
+ {(state) => (
114
+ <div
115
+ className={classNames(
116
+ 'tooltip',
117
+ `bs-popover-${placement.replace('left', 'start').replace('right', 'end')}`,
118
+ 'fade',
119
+ {
120
+ show: state === 'entered',
121
+ },
122
+ className,
123
+ )}
124
+ ref={setPopperElement}
125
+ role="tooltip"
126
+ style={styles.popper}
127
+ {...attributes.popper}
128
+ {...rest}
129
+ >
130
+ <div className="tooltip-arrow" style={styles.arrow} ref={setArrowElement}></div>
131
+ <div className="tooltip-inner">{content}</div>
132
+ </div>
133
+ )}
145
134
  </Transition>,
146
135
  document.body,
147
136
  )}
@@ -39,7 +39,7 @@ export const CVirtualScroller = forwardRef<HTMLDivElement, CVirtualScrollerProps
39
39
  virtualScrollRef.current && virtualScrollRef.current.scrollTop
40
40
 
41
41
  virtualScrollRef.current &&
42
- setViewportPadding(parseFloat(getComputedStyle(virtualScrollRef.current).paddingTop))
42
+ setViewportPadding(Number.parseFloat(getComputedStyle(virtualScrollRef.current).paddingTop))
43
43
  })
44
44
 
45
45
  useEffect(() => {
@@ -65,11 +65,9 @@ export const CVirtualScroller = forwardRef<HTMLDivElement, CVirtualScrollerProps
65
65
  onScroll && onScroll(_currentItemIndex)
66
66
  }
67
67
 
68
- const _className = classNames('virtual-scroller', className)
69
-
70
68
  return (
71
69
  <div
72
- className={_className}
70
+ className={classNames('virtual-scroller', className)}
73
71
  onScroll={(event: UIEvent<HTMLDivElement>) =>
74
72
  handleScroll((event.target as HTMLDivElement).scrollTop)
75
73
  }
@@ -108,8 +106,8 @@ export const CVirtualScroller = forwardRef<HTMLDivElement, CVirtualScrollerProps
108
106
  node.offsetHeight &&
109
107
  setItemHeight(
110
108
  node.offsetHeight +
111
- parseFloat(getComputedStyle(node).marginTop) +
112
- parseFloat(getComputedStyle(node).marginBottom),
109
+ Number.parseFloat(getComputedStyle(node).marginTop) +
110
+ Number.parseFloat(getComputedStyle(node).marginBottom),
113
111
  ),
114
112
  })
115
113
  }
@@ -38,13 +38,15 @@ export interface CWidgetStatsAProps extends Omit<HTMLAttributes<HTMLDivElement>,
38
38
 
39
39
  export const CWidgetStatsA = forwardRef<HTMLDivElement, CWidgetStatsAProps>(
40
40
  ({ action, chart, className, color, title, value, ...rest }, ref) => {
41
- const _className = classNames(
42
- { [`bg-${color}`]: color, 'text-high-emphasis-inverse': color },
43
- className,
44
- )
45
-
46
41
  return (
47
- <CCard className={_className} {...rest} ref={ref}>
42
+ <CCard
43
+ className={classNames(
44
+ { [`bg-${color}`]: color, 'text-high-emphasis-inverse': color },
45
+ className,
46
+ )}
47
+ {...rest}
48
+ ref={ref}
49
+ >
48
50
  <CCardBody className="pb-0 d-flex justify-content-between align-items-start">
49
51
  <div>
50
52
  {value && <div className="fs-4 fw-semibold">{value}</div>}
@@ -40,17 +40,16 @@ export interface CWidgetStatsDProps extends HTMLAttributes<HTMLDivElement> {
40
40
 
41
41
  export const CWidgetStatsD = forwardRef<HTMLDivElement, CWidgetStatsDProps>(
42
42
  ({ className, chart, color, icon, values, ...rest }, ref) => {
43
- const _className = classNames(className)
44
- const classNameHeader = classNames(
45
- 'position-relative d-flex justify-content-center align-items-center',
46
- {
47
- [`bg-${color}`]: color,
48
- },
49
- )
50
-
51
43
  return (
52
- <CCard className={_className} {...rest} ref={ref}>
53
- <CCardHeader className={classNameHeader}>
44
+ <CCard className={className} {...rest} ref={ref}>
45
+ <CCardHeader
46
+ className={classNames(
47
+ 'position-relative d-flex justify-content-center align-items-center',
48
+ {
49
+ [`bg-${color}`]: color,
50
+ },
51
+ )}
52
+ >
54
53
  {icon}
55
54
  {chart}
56
55
  </CCardHeader>
@@ -25,10 +25,8 @@ export interface CWidgetStatsEProps extends Omit<HTMLAttributes<HTMLDivElement>,
25
25
 
26
26
  export const CWidgetStatsE = forwardRef<HTMLDivElement, CWidgetStatsEProps>(
27
27
  ({ chart, className, title, value, ...rest }, ref) => {
28
- const _className = classNames(className)
29
-
30
28
  return (
31
- <CCard className={_className} {...rest} ref={ref}>
29
+ <CCard className={classNames(className)} {...rest} ref={ref}>
32
30
  <CCardBody className="text-center">
33
31
  {title && (
34
32
  <div className="text-medium-emphasis small text-uppercase fw-semibold">{title}</div>
@@ -1,6 +1,5 @@
1
1
  import React, { forwardRef, HTMLAttributes, ReactNode } from 'react'
2
2
  import PropTypes from 'prop-types'
3
- import classNames from 'classnames'
4
3
 
5
4
  import { CCard, CCardBody, CCardFooter } from '../card'
6
5
 
@@ -42,10 +41,8 @@ export interface CWidgetStatsFProps extends Omit<HTMLAttributes<HTMLDivElement>,
42
41
 
43
42
  export const CWidgetStatsF = forwardRef<HTMLDivElement, CWidgetStatsFProps>(
44
43
  ({ className, color, footer, icon, padding = true, title, value, ...rest }, ref) => {
45
- const _className = classNames(className)
46
-
47
44
  return (
48
- <CCard className={_className} {...rest} ref={ref}>
45
+ <CCard className={className} {...rest} ref={ref}>
49
46
  <CCardBody className={`d-flex align-items-center ${padding === false && 'p-0'}`}>
50
47
  <div className={`me-3 text-white bg-${color} ${padding ? 'p-3' : 'p-4'}`}>{icon}</div>
51
48
  <div>