Skip to content

Commit 6d9926b

Browse files
committed
refactor(CTooltip, CPopover): update popper syntax
1 parent 4744b88 commit 6d9926b

File tree

2 files changed

+158
-154
lines changed

2 files changed

+158
-154
lines changed

packages/coreui-react/src/components/popover/CPopover.tsx

+76-83
Original file line numberDiff line numberDiff line change
@@ -1,11 +1,11 @@
11
import React, { FC, ReactNode, useRef, useState } from 'react'
22
import { createPortal } from 'react-dom'
3-
import PropTypes from 'prop-types'
3+
44
import classNames from 'classnames'
5-
import { Manager, Popper, Reference } from 'react-popper'
5+
import PropTypes from 'prop-types'
6+
import { usePopper } from 'react-popper'
67
import { Transition } from 'react-transition-group'
78

8-
// import { CPopoverContent } from './CPopoverContent'
99
import { Triggers, triggerPropType } from '../Types'
1010

1111
export interface CPopoverProps {
@@ -50,10 +50,10 @@ export interface CPopoverProps {
5050
export const CPopover: FC<CPopoverProps> = ({
5151
children,
5252
content,
53-
placement = 'top',
5453
offset = [0, 8],
5554
onHide,
5655
onShow,
56+
placement = 'top',
5757
title,
5858
trigger = 'click',
5959
visible,
@@ -62,6 +62,22 @@ export const CPopover: FC<CPopoverProps> = ({
6262
const [_visible, setVisible] = useState(visible)
6363
const popoverRef = useRef()
6464

65+
const [referenceElement, setReferenceElement] = useState(null)
66+
const [popperElement, setPopperElement] = useState<HTMLDivElement | null>(null)
67+
const [arrowElement, setArrowElement] = useState<HTMLDivElement | null>(null)
68+
const { styles, attributes } = usePopper(referenceElement, popperElement, {
69+
modifiers: [
70+
{ name: 'arrow', options: { element: arrowElement } },
71+
{
72+
name: 'offset',
73+
options: {
74+
offset: offset,
75+
},
76+
},
77+
],
78+
placement: placement,
79+
})
80+
6581
const getTransitionClass = (state: string) => {
6682
return state === 'entering'
6783
? 'fade'
@@ -73,94 +89,71 @@ export const CPopover: FC<CPopoverProps> = ({
7389
}
7490

7591
return (
76-
<Manager>
77-
<>
78-
<Reference>
79-
{({ ref }) =>
80-
React.cloneElement(children, {
81-
ref: ref,
82-
...((trigger === 'click' || trigger.includes('click')) && {
83-
onClick: () => setVisible(!_visible),
84-
}),
85-
...((trigger === 'focus' || trigger.includes('focus')) && {
86-
onFocus: () => setVisible(true),
87-
onBlur: () => setVisible(false),
88-
}),
89-
...((trigger === 'hover' || trigger.includes('hover')) && {
90-
onMouseEnter: () => setVisible(true),
91-
onMouseLeave: () => setVisible(false),
92-
}),
93-
})
94-
}
95-
</Reference>
96-
{typeof window !== 'undefined' &&
97-
createPortal(
98-
<Transition
99-
in={_visible}
100-
mountOnEnter
101-
nodeRef={popoverRef}
102-
onEnter={onShow}
103-
onExit={onHide}
104-
timeout={{
105-
enter: 0,
106-
exit: 200,
107-
}}
108-
unmountOnExit
109-
>
110-
{(state) => {
111-
const transitionClass = getTransitionClass(state)
112-
return (
113-
<Popper
114-
placement={placement}
115-
modifiers={[
116-
{
117-
name: 'offset',
118-
options: {
119-
offset: offset,
120-
},
121-
},
122-
]}
123-
>
124-
{({ arrowProps, style, ref }) => (
125-
<div
126-
className={classNames(
127-
`popover bs-popover-${
128-
placement === 'left'
129-
? 'start'
130-
: placement === 'right'
131-
? 'end'
132-
: placement
133-
}`,
134-
transitionClass,
135-
)}
136-
ref={ref}
137-
role="tooltip"
138-
style={style}
139-
{...rest}
140-
>
141-
<div className="popover-arrow" {...arrowProps}></div>
142-
<div className="popover-header">{title}</div>
143-
<div className="popover-body">{content}</div>
144-
</div>
145-
)}
146-
</Popper>
147-
)
148-
}}
149-
</Transition>,
150-
document.body,
151-
)}
152-
</>
153-
</Manager>
92+
<>
93+
{React.cloneElement(children, {
94+
ref: setReferenceElement,
95+
...((trigger === 'click' || trigger.includes('click')) && {
96+
onClick: () => setVisible(!_visible),
97+
}),
98+
...((trigger === 'focus' || trigger.includes('focus')) && {
99+
onFocus: () => setVisible(true),
100+
onBlur: () => setVisible(false),
101+
}),
102+
...((trigger === 'hover' || trigger.includes('hover')) && {
103+
onMouseEnter: () => setVisible(true),
104+
onMouseLeave: () => setVisible(false),
105+
}),
106+
})}
107+
{typeof window !== 'undefined' &&
108+
createPortal(
109+
<Transition
110+
in={_visible}
111+
mountOnEnter
112+
nodeRef={popoverRef}
113+
onEnter={onShow}
114+
onExit={onHide}
115+
timeout={{
116+
enter: 0,
117+
exit: 200,
118+
}}
119+
unmountOnExit
120+
>
121+
{(state) => {
122+
const transitionClass = getTransitionClass(state)
123+
return (
124+
<div
125+
className={classNames(
126+
`popover bs-popover-${
127+
placement === 'left' ? 'start' : placement === 'right' ? 'end' : placement
128+
}`,
129+
transitionClass,
130+
)}
131+
ref={setPopperElement}
132+
role="tooltip"
133+
style={styles.popper}
134+
{...attributes.popper}
135+
{...rest}
136+
>
137+
<div className="popover-arrow" style={styles.arrow} ref={setArrowElement}></div>
138+
<div className="popover-header">{title}</div>
139+
<div className="popover-body">{content}</div>
140+
</div>
141+
)
142+
}}
143+
</Transition>,
144+
document.body,
145+
)}
146+
</>
154147
)
155148
}
156149

157150
CPopover.propTypes = {
158151
children: PropTypes.any,
159152
content: PropTypes.oneOfType([PropTypes.string, PropTypes.node]),
160-
placement: PropTypes.oneOf(['auto', 'top', 'right', 'bottom', 'left']),
161153
offset: PropTypes.any, // TODO: find good proptype
162154
onHide: PropTypes.func,
163155
onShow: PropTypes.func,
156+
placement: PropTypes.oneOf(['auto', 'top', 'right', 'bottom', 'left']),
164157
title: PropTypes.oneOfType([PropTypes.string, PropTypes.node]),
165158
trigger: triggerPropType,
166159
visible: PropTypes.bool,

0 commit comments

Comments
 (0)