Skip to content

Commit a8f4fda

Browse files
committed
feat(usePopper): add a new hook
1 parent c35daab commit a8f4fda

File tree

4 files changed

+67
-57
lines changed

4 files changed

+67
-57
lines changed

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

Lines changed: 17 additions & 28 deletions
Original file line numberDiff line numberDiff line change
@@ -3,8 +3,9 @@ import { createPortal } from 'react-dom'
33
import classNames from 'classnames'
44
import PropTypes from 'prop-types'
55
import { Transition } from 'react-transition-group'
6-
import { createPopper, Instance, Placement } from '@popperjs/core'
6+
import { Placement } from '@popperjs/core'
77

8+
import { usePopper } from '../../hooks'
89
import { triggerPropType } from '../../props'
910
import type { Triggers } from '../../types'
1011
import { isRTL } from '../../utils'
@@ -79,47 +80,35 @@ export const CPopover: FC<CPopoverProps> = ({
7980
}) => {
8081
const popoverRef = useRef(null)
8182
const togglerRef = useRef(null)
82-
const popper = useRef<Instance>()
83+
const { initPopper, destroyPopper } = usePopper()
8384
const [_visible, setVisible] = useState(visible)
8485

86+
const popperConfig = {
87+
modifiers: [
88+
{
89+
name: 'offset',
90+
options: {
91+
offset: offset,
92+
},
93+
},
94+
],
95+
placement: getPlacement(placement, togglerRef.current),
96+
}
97+
8598
useEffect(() => {
8699
setVisible(visible)
87100
}, [visible])
88101

89102
useEffect(() => {
90-
if (_visible) {
91-
initPopper()
103+
if (_visible && togglerRef.current && popoverRef.current) {
104+
initPopper(togglerRef.current, popoverRef.current, popperConfig)
92105
}
93106

94107
return () => {
95108
destroyPopper()
96109
}
97110
}, [_visible])
98111

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()
118-
}
119-
120-
popper.current = undefined
121-
}
122-
123112
return (
124113
<>
125114
{React.cloneElement(children as React.ReactElement<any>, {

packages/coreui-react/src/components/tooltip/CTooltip.tsx

Lines changed: 17 additions & 28 deletions
Original file line numberDiff line numberDiff line change
@@ -3,8 +3,9 @@ import { createPortal } from 'react-dom'
33
import classNames from 'classnames'
44
import PropTypes from 'prop-types'
55
import { Transition } from 'react-transition-group'
6-
import { createPopper, Instance, Placement } from '@popperjs/core'
6+
import { Placement } from '@popperjs/core'
77

8+
import { usePopper } from '../../hooks'
89
import { triggerPropType } from '../../props'
910
import type { Triggers } from '../../types'
1011
import { isRTL } from '../../utils'
@@ -74,47 +75,35 @@ export const CTooltip: FC<CTooltipProps> = ({
7475
}) => {
7576
const tooltipRef = useRef(null)
7677
const togglerRef = useRef(null)
77-
const popper = useRef<Instance>()
78+
const { initPopper, destroyPopper } = usePopper()
7879
const [_visible, setVisible] = useState(visible)
7980

81+
const popperConfig = {
82+
modifiers: [
83+
{
84+
name: 'offset',
85+
options: {
86+
offset: offset,
87+
},
88+
},
89+
],
90+
placement: getPlacement(placement, togglerRef.current),
91+
}
92+
8093
useEffect(() => {
8194
setVisible(visible)
8295
}, [visible])
8396

8497
useEffect(() => {
85-
if (_visible) {
86-
initPopper()
98+
if (_visible && togglerRef.current && tooltipRef.current) {
99+
initPopper(togglerRef.current, tooltipRef.current, popperConfig)
87100
}
88101

89102
return () => {
90103
destroyPopper()
91104
}
92105
}, [_visible])
93106

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()
113-
}
114-
115-
popper.current = undefined
116-
}
117-
118107
return (
119108
<>
120109
{React.cloneElement(children as React.ReactElement<any>, {
Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,5 @@
11
import { useColorModes } from './useColorModes'
22
import { useForkedRef } from './useForkedRef'
3+
import { usePopper } from './usePopper'
34

4-
export { useColorModes, useForkedRef }
5+
export { useColorModes, useForkedRef, usePopper }
Lines changed: 31 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,31 @@
1+
import { useRef } from 'react'
2+
import { createPopper } from '@popperjs/core'
3+
import type { Instance, Options } from '@popperjs/core'
4+
5+
interface UsePopperOutput {
6+
popper: Instance | undefined
7+
initPopper: (reference: HTMLElement, popper: HTMLElement, options: Partial<Options>) => void
8+
destroyPopper: () => void
9+
}
10+
11+
export const usePopper = (): UsePopperOutput => {
12+
const _popper = useRef<Instance>()
13+
14+
const initPopper = (reference: HTMLElement, popper: HTMLElement, options: Partial<Options>) => {
15+
_popper.current = createPopper(reference, popper, options)
16+
}
17+
18+
const destroyPopper = () => {
19+
if (_popper.current) {
20+
_popper.current.destroy()
21+
}
22+
23+
_popper.current = undefined
24+
}
25+
26+
return {
27+
popper: _popper.current,
28+
initPopper,
29+
destroyPopper,
30+
}
31+
}

0 commit comments

Comments
 (0)