@coreui/react 4.9.0-beta.0 → 4.9.0-beta.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 (44) hide show
  1. package/README.md +1 -1
  2. package/dist/components/dropdown/CDropdown.d.ts +8 -1
  3. package/dist/components/dropdown/CDropdownMenu.d.ts +3 -4
  4. package/dist/components/dropdown copy/CDropdown.d.ts +89 -0
  5. package/dist/components/dropdown copy/CDropdownDivider.d.ts +8 -0
  6. package/dist/components/dropdown copy/CDropdownHeader.d.ts +12 -0
  7. package/dist/components/dropdown copy/CDropdownItem.d.ts +13 -0
  8. package/dist/components/dropdown copy/CDropdownItemPlain.d.ts +12 -0
  9. package/dist/components/dropdown copy/CDropdownMenu.d.ts +13 -0
  10. package/dist/components/dropdown copy/CDropdownToggle.d.ts +24 -0
  11. package/dist/components/dropdown copy/index.d.ts +8 -0
  12. package/dist/components/popover/CPopover.d.ts +22 -1
  13. package/dist/components/progress/CProgress.d.ts +6 -0
  14. package/dist/components/progress/CProgressStacked.d.ts +12 -0
  15. package/dist/components/progress/index.d.ts +2 -1
  16. package/dist/components/tooltip/CTooltip.d.ts +22 -1
  17. package/dist/hooks/index.d.ts +2 -1
  18. package/dist/hooks/useColorModes.d.ts +4 -2
  19. package/dist/hooks/usePopper.d.ts +8 -0
  20. package/dist/index.es.js +1527 -1915
  21. package/dist/index.es.js.map +1 -1
  22. package/dist/index.js +1312 -1716
  23. package/dist/index.js.map +1 -1
  24. package/dist/props.d.ts +1 -0
  25. package/dist/utils/getRTLPlacement.d.ts +3 -0
  26. package/dist/utils/index.d.ts +2 -1
  27. package/package.json +5 -5
  28. package/src/components/dropdown/CDropdown.tsx +130 -45
  29. package/src/components/dropdown/CDropdownMenu.tsx +41 -138
  30. package/src/components/dropdown/CDropdownToggle.tsx +6 -15
  31. package/src/components/dropdown/__tests__/__snapshots__/CDropdownMenu.spec.tsx.snap +0 -1
  32. package/src/components/popover/CPopover.tsx +76 -51
  33. package/src/components/popover/__tests__/__snapshots__/CPopover.spec.tsx.snap +0 -21
  34. package/src/components/progress/CProgress.tsx +43 -8
  35. package/src/components/progress/CProgressBar.tsx +5 -6
  36. package/src/components/progress/CProgressStacked.tsx +39 -0
  37. package/src/components/progress/index.ts +2 -1
  38. package/src/components/tooltip/CTooltip.tsx +77 -52
  39. package/src/hooks/index.ts +2 -1
  40. package/src/hooks/useColorModes.ts +23 -11
  41. package/src/hooks/usePopper.ts +31 -0
  42. package/src/props.ts +5 -0
  43. package/src/utils/getRTLPlacement.ts +18 -0
  44. package/src/utils/index.ts +2 -1
@@ -3,13 +3,19 @@ import { createPortal } from 'react-dom'
3
3
  import classNames from 'classnames'
4
4
  import PropTypes from 'prop-types'
5
5
  import { Transition } from 'react-transition-group'
6
- import { createPopper, Instance, Placement } from '@popperjs/core'
7
6
 
8
- import { triggerPropType } from '../../props'
9
- import type { Triggers } from '../../types'
10
- import { isRTL } from '../../utils'
7
+ import { usePopper } from '../../hooks'
8
+ import { fallbackPlacementsPropType, triggerPropType } from '../../props'
9
+ import type { Placements, Triggers } from '../../types'
10
+ import { getRTLPlacement } from '../../utils'
11
11
 
12
12
  export interface CPopoverProps extends Omit<HTMLAttributes<HTMLDivElement>, 'title' | 'content'> {
13
+ /**
14
+ * Apply a CSS fade transition to the popover.
15
+ *
16
+ * @since 4.9.0-beta.2
17
+ */
18
+ animation?: boolean
13
19
  /**
14
20
  * A string of all className you want applied to the component.
15
21
  */
@@ -22,6 +28,18 @@ export interface CPopoverProps extends Omit<HTMLAttributes<HTMLDivElement>, 'tit
22
28
  * Offset of the popover relative to its target.
23
29
  */
24
30
  offset?: [number, number]
31
+ /**
32
+ * The delay for displaying and hiding the popover (in milliseconds). When a numerical value is provided, the delay applies to both the hide and show actions. The object structure for specifying the delay is as follows: delay: `{ 'show': 500, 'hide': 100 }`.
33
+ *
34
+ * @since 4.9.0-beta.2
35
+ */
36
+ delay?: number | { show: number; hide: number }
37
+ /**
38
+ * Specify the desired order of fallback placements by providing a list of placements as an array. The placements should be prioritized based on preference.
39
+ *
40
+ * @since 4.9.0-beta.2
41
+ */
42
+ fallbackPlacements?: Placements | Placements[]
25
43
  /**
26
44
  * Callback fired when the component requests to be hidden.
27
45
  */
@@ -50,24 +68,13 @@ export interface CPopoverProps extends Omit<HTMLAttributes<HTMLDivElement>, 'tit
50
68
  visible?: boolean
51
69
  }
52
70
 
53
- const getPlacement = (placement: string, element: HTMLDivElement | null): Placement => {
54
- switch (placement) {
55
- case 'right': {
56
- return isRTL(element) ? 'left' : 'right'
57
- }
58
- case 'left': {
59
- return isRTL(element) ? 'right' : 'left'
60
- }
61
- default: {
62
- return placement as Placement
63
- }
64
- }
65
- }
66
-
67
71
  export const CPopover: FC<CPopoverProps> = ({
68
72
  children,
73
+ animation = true,
69
74
  className,
70
75
  content,
76
+ delay = 0,
77
+ fallbackPlacements = ['top', 'right', 'bottom', 'left'],
71
78
  offset = [0, 8],
72
79
  onHide,
73
80
  onShow,
@@ -79,16 +86,42 @@ export const CPopover: FC<CPopoverProps> = ({
79
86
  }) => {
80
87
  const popoverRef = useRef(null)
81
88
  const togglerRef = useRef(null)
82
- const popper = useRef<Instance>()
89
+ const { initPopper, destroyPopper } = usePopper()
83
90
  const [_visible, setVisible] = useState(visible)
84
91
 
92
+ const _delay = typeof delay === 'number' ? { show: delay, hide: delay } : delay
93
+
94
+ const popperConfig = {
95
+ modifiers: [
96
+ {
97
+ name: 'arrow',
98
+ options: {
99
+ element: '.popover-arrow',
100
+ },
101
+ },
102
+ {
103
+ name: 'flip',
104
+ options: {
105
+ fallbackPlacements: fallbackPlacements,
106
+ },
107
+ },
108
+ {
109
+ name: 'offset',
110
+ options: {
111
+ offset: offset,
112
+ },
113
+ },
114
+ ],
115
+ placement: getRTLPlacement(placement, togglerRef.current),
116
+ }
117
+
85
118
  useEffect(() => {
86
119
  setVisible(visible)
87
120
  }, [visible])
88
121
 
89
122
  useEffect(() => {
90
- if (_visible) {
91
- initPopper()
123
+ if (_visible && togglerRef.current && popoverRef.current) {
124
+ initPopper(togglerRef.current, popoverRef.current, popperConfig)
92
125
  }
93
126
 
94
127
  return () => {
@@ -96,28 +129,13 @@ export const CPopover: FC<CPopoverProps> = ({
96
129
  }
97
130
  }, [_visible])
98
131
 
99
- const initPopper = () => {
100
- if (togglerRef.current && popoverRef.current) {
101
- popper.current = createPopper(togglerRef.current, popoverRef.current, {
102
- modifiers: [
103
- {
104
- name: 'offset',
105
- options: {
106
- offset: offset,
107
- },
108
- },
109
- ],
110
- placement: getPlacement(placement, togglerRef.current),
111
- })
112
- }
113
- }
114
-
115
- const destroyPopper = () => {
116
- if (popper.current) {
117
- popper.current.destroy()
132
+ const toggleVisible = (visible: boolean) => {
133
+ if (visible) {
134
+ setTimeout(() => setVisible(true), _delay.show)
135
+ return
118
136
  }
119
137
 
120
- popper.current = undefined
138
+ setTimeout(() => setVisible(false), _delay.hide)
121
139
  }
122
140
 
123
141
  return (
@@ -125,15 +143,15 @@ export const CPopover: FC<CPopoverProps> = ({
125
143
  {React.cloneElement(children as React.ReactElement<any>, {
126
144
  ref: togglerRef,
127
145
  ...((trigger === 'click' || trigger.includes('click')) && {
128
- onClick: () => setVisible(!_visible),
146
+ onClick: () => toggleVisible(!_visible),
129
147
  }),
130
148
  ...((trigger === 'focus' || trigger.includes('focus')) && {
131
- onFocus: () => setVisible(true),
132
- onBlur: () => setVisible(false),
149
+ onFocus: () => toggleVisible(true),
150
+ onBlur: () => toggleVisible(false),
133
151
  }),
134
152
  ...((trigger === 'hover' || trigger.includes('hover')) && {
135
- onMouseEnter: () => setVisible(true),
136
- onMouseLeave: () => setVisible(false),
153
+ onMouseEnter: () => toggleVisible(true),
154
+ onMouseLeave: () => toggleVisible(false),
137
155
  }),
138
156
  })}
139
157
  {typeof window !== 'undefined' &&
@@ -154,11 +172,9 @@ export const CPopover: FC<CPopoverProps> = ({
154
172
  <div
155
173
  className={classNames(
156
174
  'popover',
157
- `bs-popover-${getPlacement(placement, togglerRef.current)
158
- .replace('left', 'start')
159
- .replace('right', 'end')}`,
160
- 'fade',
175
+ 'bs-popover-auto',
161
176
  {
177
+ fade: animation,
162
178
  show: state === 'entered',
163
179
  },
164
180
  className,
@@ -167,7 +183,7 @@ export const CPopover: FC<CPopoverProps> = ({
167
183
  role="tooltip"
168
184
  {...rest}
169
185
  >
170
- <div data-popper-arrow className="popover-arrow"></div>
186
+ <div className="popover-arrow"></div>
171
187
  <div className="popover-header">{title}</div>
172
188
  <div className="popover-body">{content}</div>
173
189
  </div>
@@ -180,9 +196,18 @@ export const CPopover: FC<CPopoverProps> = ({
180
196
  }
181
197
 
182
198
  CPopover.propTypes = {
199
+ animation: PropTypes.bool,
183
200
  children: PropTypes.node,
184
201
  className: PropTypes.string,
185
202
  content: PropTypes.oneOfType([PropTypes.string, PropTypes.node]),
203
+ delay: PropTypes.oneOfType([
204
+ PropTypes.number,
205
+ PropTypes.shape({
206
+ show: PropTypes.number.isRequired,
207
+ hide: PropTypes.number.isRequired,
208
+ }),
209
+ ]),
210
+ fallbackPlacements: fallbackPlacementsPropType,
186
211
  offset: PropTypes.any, // TODO: find good proptype
187
212
  onHide: PropTypes.func,
188
213
  onShow: PropTypes.func,
@@ -8,27 +8,6 @@ exports[`CPopover customize 1`] = `
8
8
  >
9
9
  Test
10
10
  </button>
11
- <div
12
- class="popover bs-popover-end fade"
13
- role="tooltip"
14
- style="position: absolute; left: 0px; top: 0px; margin: 0px;"
15
- >
16
- <div
17
- class="popover-arrow"
18
- data-popper-arrow="true"
19
- style="position: absolute;"
20
- />
21
- <div
22
- class="popover-header"
23
- >
24
- title
25
- </div>
26
- <div
27
- class="popover-body"
28
- >
29
- content
30
- </div>
31
- </div>
32
11
  </body>
33
12
  `;
34
13
 
@@ -1,7 +1,8 @@
1
- import React, { forwardRef, HTMLAttributes } from 'react'
1
+ import React, { forwardRef, HTMLAttributes, useContext } from 'react'
2
2
  import PropTypes from 'prop-types'
3
3
  import classNames from 'classnames'
4
4
 
5
+ import { CProgressStackedContext } from './CProgressStacked'
5
6
  import { CProgressBar, CProgressBarProps } from './CProgressBar'
6
7
 
7
8
  export interface CProgressProps
@@ -15,6 +16,12 @@ export interface CProgressProps
15
16
  * Sets the height of the component. If you set that value the inner `<CProgressBar>` will automatically resize accordingly.
16
17
  */
17
18
  height?: number
19
+ /**
20
+ * A string of all className you want applied to the <CProgressBar/> component.
21
+ *
22
+ * @since 4.9.0
23
+ */
24
+ progressBarClassName?: string
18
25
  /**
19
26
  * Makes progress bar thinner.
20
27
  */
@@ -29,9 +36,10 @@ export interface CProgressProps
29
36
  white?: boolean
30
37
  }
31
38
 
32
- // TODO: update markup and add '.progress-stacked' in v5
33
39
  export const CProgress = forwardRef<HTMLDivElement, CProgressProps>(
34
- ({ children, className, height, thin, value = 0, white, ...rest }, ref) => {
40
+ ({ children, className, height, progressBarClassName, thin, value, white, ...rest }, ref) => {
41
+ const { stacked } = useContext(CProgressStackedContext)
42
+
35
43
  return (
36
44
  <div
37
45
  className={classNames(
@@ -42,15 +50,41 @@ export const CProgress = forwardRef<HTMLDivElement, CProgressProps>(
42
50
  },
43
51
  className,
44
52
  )}
45
- style={height ? { height: `${height}px` } : {}}
53
+ {...(value !== undefined && {
54
+ role: 'progressbar',
55
+ 'aria-valuenow': value,
56
+ 'aria-valuemin': 0,
57
+ 'aria-valuemax': 100,
58
+ })}
59
+ style={{
60
+ ...(height ? { height: `${height}px` } : {}),
61
+ ...(stacked ? { width: `${value}%` } : {}),
62
+ }}
46
63
  ref={ref}
47
64
  >
48
- {value ? (
49
- <CProgressBar value={value} {...rest}>
65
+ {React.Children.toArray(children).some(
66
+ // @ts-expect-error displayName is set in the CProgressBar component
67
+ (child) => child.type && child.type.displayName === 'CProgressBar',
68
+ ) ? (
69
+ React.Children.map(children, (child) => {
70
+ // @ts-expect-error displayName is set in the CProgressBar component
71
+ if (React.isValidElement(child) && child.type.displayName === 'CProgressBar') {
72
+ return React.cloneElement(child, {
73
+ ...(value && { value: value }),
74
+ ...rest,
75
+ })
76
+ }
77
+
78
+ return
79
+ })
80
+ ) : (
81
+ <CProgressBar
82
+ {...(progressBarClassName && { className: progressBarClassName })}
83
+ value={value}
84
+ {...rest}
85
+ >
50
86
  {children}
51
87
  </CProgressBar>
52
- ) : (
53
- children
54
88
  )}
55
89
  </div>
56
90
  )
@@ -61,6 +95,7 @@ CProgress.propTypes = {
61
95
  children: PropTypes.node,
62
96
  className: PropTypes.string,
63
97
  height: PropTypes.number,
98
+ progressBarClassName: PropTypes.string,
64
99
  thin: PropTypes.bool,
65
100
  value: PropTypes.number,
66
101
  white: PropTypes.bool,
@@ -1,7 +1,8 @@
1
- import React, { forwardRef, HTMLAttributes } from 'react'
1
+ import React, { forwardRef, HTMLAttributes, useContext } from 'react'
2
2
  import PropTypes from 'prop-types'
3
3
  import classNames from 'classnames'
4
4
 
5
+ import { CProgressStackedContext } from './CProgressStacked'
5
6
  import { colorPropType } from '../../props'
6
7
  import type { Colors } from '../../types'
7
8
 
@@ -32,6 +33,8 @@ export interface CProgressBarProps extends HTMLAttributes<HTMLDivElement> {
32
33
 
33
34
  export const CProgressBar = forwardRef<HTMLDivElement, CProgressBarProps>(
34
35
  ({ children, animated, className, color, value = 0, variant, ...rest }, ref) => {
36
+ const { stacked } = useContext(CProgressStackedContext)
37
+
35
38
  return (
36
39
  <div
37
40
  className={classNames(
@@ -43,11 +46,7 @@ export const CProgressBar = forwardRef<HTMLDivElement, CProgressBarProps>(
43
46
  },
44
47
  className,
45
48
  )}
46
- role="progressbar"
47
- style={{ width: `${value}%` }}
48
- aria-valuenow={value}
49
- aria-valuemin={0}
50
- aria-valuemax={100}
49
+ {...(!stacked && { style: { width: `${value}%` } })}
51
50
  {...rest}
52
51
  ref={ref}
53
52
  >
@@ -0,0 +1,39 @@
1
+ import React, { createContext, forwardRef, HTMLAttributes } from 'react'
2
+ import PropTypes from 'prop-types'
3
+ import classNames from 'classnames'
4
+
5
+ export interface CProgressStackedProps extends HTMLAttributes<HTMLDivElement> {
6
+ /**
7
+ * A string of all className you want applied to the component.
8
+ */
9
+ className?: string
10
+ }
11
+
12
+ export interface CProgressStackedContextProps {
13
+ stacked?: boolean
14
+ }
15
+
16
+ export const CProgressStackedContext = createContext({} as CProgressStackedContextProps)
17
+
18
+ export const CProgressStacked = forwardRef<HTMLDivElement, CProgressStackedProps>(
19
+ ({ children, className, ...rest }, ref) => {
20
+ return (
21
+ <div className={classNames('progress-stacked', className)} ref={ref} {...rest}>
22
+ <CProgressStackedContext.Provider
23
+ value={{
24
+ stacked: true,
25
+ }}
26
+ >
27
+ {children}
28
+ </CProgressStackedContext.Provider>
29
+ </div>
30
+ )
31
+ },
32
+ )
33
+
34
+ CProgressStacked.propTypes = {
35
+ children: PropTypes.node,
36
+ className: PropTypes.string,
37
+ }
38
+
39
+ CProgressStacked.displayName = 'CProgressStacked'
@@ -1,4 +1,5 @@
1
1
  import { CProgress } from './CProgress'
2
2
  import { CProgressBar } from './CProgressBar'
3
+ import { CProgressStacked } from './CProgressStacked'
3
4
 
4
- export { CProgress, CProgressBar }
5
+ export { CProgress, CProgressBar, CProgressStacked }
@@ -3,13 +3,19 @@ import { createPortal } from 'react-dom'
3
3
  import classNames from 'classnames'
4
4
  import PropTypes from 'prop-types'
5
5
  import { Transition } from 'react-transition-group'
6
- import { createPopper, Instance, Placement } from '@popperjs/core'
7
6
 
8
- import { triggerPropType } from '../../props'
9
- import type { Triggers } from '../../types'
10
- import { isRTL } from '../../utils'
7
+ import { usePopper } from '../../hooks'
8
+ import { fallbackPlacementsPropType, triggerPropType } from '../../props'
9
+ import type { Placements, Triggers } from '../../types'
10
+ import { getRTLPlacement } from '../../utils'
11
11
 
12
12
  export interface CTooltipProps extends Omit<HTMLAttributes<HTMLDivElement>, 'content'> {
13
+ /**
14
+ * Apply a CSS fade transition to the tooltip.
15
+ *
16
+ * @since 4.9.0-beta.2
17
+ */
18
+ animation?: boolean
13
19
  /**
14
20
  * A string of all className you want applied to the component.
15
21
  */
@@ -18,6 +24,18 @@ export interface CTooltipProps extends Omit<HTMLAttributes<HTMLDivElement>, 'con
18
24
  * Content node for your component.
19
25
  */
20
26
  content: ReactNode | string
27
+ /**
28
+ * The delay for displaying and hiding the tooltip (in milliseconds). When a numerical value is provided, the delay applies to both the hide and show actions. The object structure for specifying the delay is as follows: delay: `{ 'show': 500, 'hide': 100 }`.
29
+ *
30
+ * @since 4.9.0-beta.2
31
+ */
32
+ delay?: number | { show: number; hide: number }
33
+ /**
34
+ * Specify the desired order of fallback placements by providing a list of placements as an array. The placements should be prioritized based on preference.
35
+ *
36
+ * @since 4.9.0-beta.2
37
+ */
38
+ fallbackPlacements?: Placements | Placements[]
21
39
  /**
22
40
  * Offset of the tooltip relative to its target.
23
41
  */
@@ -46,44 +64,59 @@ export interface CTooltipProps extends Omit<HTMLAttributes<HTMLDivElement>, 'con
46
64
  visible?: boolean
47
65
  }
48
66
 
49
- const getPlacement = (placement: string, element: HTMLDivElement | null): Placement => {
50
- switch (placement) {
51
- case 'right': {
52
- return isRTL(element) ? 'left' : 'right'
53
- }
54
- case 'left': {
55
- return isRTL(element) ? 'right' : 'left'
56
- }
57
- default: {
58
- return placement as Placement
59
- }
60
- }
61
- }
62
-
63
67
  export const CTooltip: FC<CTooltipProps> = ({
64
68
  children,
69
+ animation = true,
65
70
  className,
66
71
  content,
72
+ delay = 0,
73
+ fallbackPlacements = ['top', 'right', 'bottom', 'left'],
67
74
  offset = [0, 6],
68
75
  onHide,
69
76
  onShow,
70
77
  placement = 'top',
71
- trigger = 'hover',
78
+ trigger = ['hover', 'focus'],
72
79
  visible,
73
80
  ...rest
74
81
  }) => {
75
82
  const tooltipRef = useRef(null)
76
83
  const togglerRef = useRef(null)
77
- const popper = useRef<Instance>()
84
+ const { initPopper, destroyPopper } = usePopper()
78
85
  const [_visible, setVisible] = useState(visible)
79
86
 
87
+ const _delay = typeof delay === 'number' ? { show: delay, hide: delay } : delay
88
+
89
+ const popperConfig = {
90
+ modifiers: [
91
+ {
92
+ name: 'arrow',
93
+ options: {
94
+ element: '.tooltip-arrow',
95
+ },
96
+ },
97
+ {
98
+ name: 'flip',
99
+ options: {
100
+ fallbackPlacements: fallbackPlacements,
101
+ },
102
+ },
103
+ {
104
+ name: 'offset',
105
+ options: {
106
+ offset: offset,
107
+ },
108
+ },
109
+ ],
110
+ placement: getRTLPlacement(placement, togglerRef.current),
111
+ }
112
+
80
113
  useEffect(() => {
81
114
  setVisible(visible)
82
115
  }, [visible])
83
116
 
84
117
  useEffect(() => {
85
- if (_visible) {
86
- initPopper()
118
+ if (_visible && togglerRef.current && tooltipRef.current) {
119
+ initPopper(togglerRef.current, tooltipRef.current, popperConfig)
87
120
  }
88
121
 
89
122
  return () => {
@@ -91,28 +124,13 @@ export const CTooltip: FC<CTooltipProps> = ({
91
124
  }
92
125
  }, [_visible])
93
126
 
94
- const initPopper = () => {
95
- if (togglerRef.current && tooltipRef.current) {
96
- popper.current = createPopper(togglerRef.current, tooltipRef.current, {
97
- modifiers: [
98
- {
99
- name: 'offset',
100
- options: {
101
- offset: offset,
102
- },
103
- },
104
- ],
105
- placement: getPlacement(placement, togglerRef.current),
106
- })
107
- }
108
- }
109
-
110
- const destroyPopper = () => {
111
- if (popper.current) {
112
- popper.current.destroy()
127
+ const toggleVisible = (visible: boolean) => {
128
+ if (visible) {
129
+ setTimeout(() => setVisible(true), _delay.show)
130
+ return
113
131
  }
114
132
 
115
- popper.current = undefined
133
+ setTimeout(() => setVisible(false), _delay.hide)
116
134
  }
117
135
 
118
136
  return (
@@ -120,15 +138,15 @@ export const CTooltip: FC<CTooltipProps> = ({
120
138
  {React.cloneElement(children as React.ReactElement<any>, {
121
139
  ref: togglerRef,
122
140
  ...((trigger === 'click' || trigger.includes('click')) && {
123
- onClick: () => setVisible(!_visible),
141
+ onClick: () => toggleVisible(!_visible),
124
142
  }),
125
143
  ...((trigger === 'focus' || trigger.includes('focus')) && {
126
- onFocus: () => setVisible(true),
127
- onBlur: () => setVisible(false),
144
+ onFocus: () => toggleVisible(true),
145
+ onBlur: () => toggleVisible(false),
128
146
  }),
129
147
  ...((trigger === 'hover' || trigger.includes('hover')) && {
130
- onMouseEnter: () => setVisible(true),
131
- onMouseLeave: () => setVisible(false),
148
+ onMouseEnter: () => toggleVisible(true),
149
+ onMouseLeave: () => toggleVisible(false),
132
150
  }),
133
151
  })}
134
152
  {typeof window !== 'undefined' &&
@@ -148,11 +166,9 @@ export const CTooltip: FC<CTooltipProps> = ({
148
166
  <div
149
167
  className={classNames(
150
168
  'tooltip',
151
- `bs-tooltip-${getPlacement(placement, togglerRef.current)
152
- .replace('left', 'start')
153
- .replace('right', 'end')}`,
154
- 'fade',
169
+ 'bs-tooltip-auto',
155
170
  {
171
+ fade: animation,
156
172
  show: state === 'entered',
157
173
  },
158
174
  className,
@@ -161,7 +177,7 @@ export const CTooltip: FC<CTooltipProps> = ({
161
177
  role="tooltip"
162
178
  {...rest}
163
179
  >
164
- <div data-popper-arrow className="tooltip-arrow"></div>
180
+ <div className="tooltip-arrow"></div>
165
181
  <div className="tooltip-inner">{content}</div>
166
182
  </div>
167
183
  )}
@@ -173,8 +189,17 @@ export const CTooltip: FC<CTooltipProps> = ({
173
189
  }
174
190
 
175
191
  CTooltip.propTypes = {
192
+ animation: PropTypes.bool,
176
193
  children: PropTypes.node,
177
194
  content: PropTypes.oneOfType([PropTypes.string, PropTypes.node]),
195
+ delay: PropTypes.oneOfType([
196
+ PropTypes.number,
197
+ PropTypes.shape({
198
+ show: PropTypes.number.isRequired,
199
+ hide: PropTypes.number.isRequired,
200
+ }),
201
+ ]),
202
+ fallbackPlacements: fallbackPlacementsPropType,
178
203
  offset: PropTypes.any, // TODO: find good proptype
179
204
  onHide: PropTypes.func,
180
205
  onShow: PropTypes.func,
@@ -1,4 +1,5 @@
1
1
  import { useColorModes } from './useColorModes'
2
2
  import { useForkedRef } from './useForkedRef'
3
+ import { usePopper } from './usePopper'
3
4
 
4
- export { useColorModes, useForkedRef }
5
+ export { useColorModes, useForkedRef, usePopper }