Skip to content

Navigation Menu

Sign in
Appearance settings

Search code, repositories, users, issues, pull requests...

Provide feedback

We read every piece of feedback, and take your input very seriously.

Saved searches

Use saved searches to filter your results more quickly

Sign up
Appearance settings

Commit 5688b61

Browse files
committed
refactor(CDropdown): optimize menu visibility toggling
1 parent a2d3eb5 commit 5688b61

File tree

3 files changed

+60
-33
lines changed

3 files changed

+60
-33
lines changed

‎packages/coreui-react/src/components/dropdown/CDropdown.tsx

Lines changed: 48 additions & 28 deletions
Original file line numberDiff line numberDiff line change
@@ -214,19 +214,6 @@ export const CDropdown: PolymorphicRefForwardingComponent<'div', CDropdownProps>
214214
const allowPopperUse = popper && typeof alignment !== 'object'
215215
const Component = variant === 'nav-item' ? 'li' : as
216216

217-
const contextValues = {
218-
alignment,
219-
container,
220-
dark,
221-
dropdownMenuRef,
222-
dropdownToggleRef,
223-
popper: allowPopperUse,
224-
portal,
225-
variant,
226-
visible: _visible,
227-
setVisible,
228-
}
229-
230217
const computedPopperConfig: Partial<Options> = useMemo(() => {
231218
const defaultPopperConfig = {
232219
modifiers: [
@@ -247,14 +234,28 @@ export const CDropdown: PolymorphicRefForwardingComponent<'div', CDropdownProps>
247234
}, [offset, placement, direction, alignment, popperConfig])
248235

249236
useEffect(() => {
250-
setVisible(visible)
237+
if (visible) {
238+
handleShow()
239+
} else {
240+
handleHide()
241+
}
251242
}, [visible])
252243

253244
useEffect(() => {
254245
const toggleElement = dropdownToggleElement
255246
const menuElement = dropdownMenuRef.current
247+
if (allowPopperUse && menuElement && toggleElement && _visible) {
248+
initPopper(toggleElement, menuElement, computedPopperConfig)
249+
}
250+
}, [dropdownToggleElement])
251+
252+
const handleShow = () => {
253+
const toggleElement = dropdownToggleElement
254+
const menuElement = dropdownMenuRef.current
255+
256+
if (toggleElement && menuElement) {
257+
setVisible(true)
256258

257-
if (_visible && toggleElement && menuElement) {
258259
if (allowPopperUse) {
259260
initPopper(toggleElement, menuElement, computedPopperConfig)
260261
}
@@ -268,21 +269,26 @@ export const CDropdown: PolymorphicRefForwardingComponent<'div', CDropdownProps>
268269

269270
onShow?.()
270271
}
272+
}
271273

272-
return () => {
273-
if (allowPopperUse) {
274-
destroyPopper()
275-
}
276-
277-
toggleElement?.removeEventListener('keydown', handleKeydown)
278-
menuElement?.removeEventListener('keydown', handleKeydown)
274+
const handleHide = () => {
275+
setVisible(false)
279276

280-
window.removeEventListener('mouseup',handleMouseUp)
281-
window.removeEventListener('keyup',handleKeyup)
277+
consttoggleElement=dropdownToggleElement
278+
constmenuElement=dropdownMenuRef.current
282279

283-
onHide?.()
280+
if (allowPopperUse) {
281+
destroyPopper()
284282
}
285-
}, [dropdownToggleElement, _visible])
283+
284+
toggleElement?.removeEventListener('keydown', handleKeydown)
285+
menuElement?.removeEventListener('keydown', handleKeydown)
286+
287+
window.removeEventListener('mouseup', handleMouseUp)
288+
window.removeEventListener('keyup', handleKeyup)
289+
290+
onHide?.()
291+
}
286292

287293
const handleKeydown = (event: KeyboardEvent) => {
288294
if (
@@ -305,7 +311,7 @@ export const CDropdown: PolymorphicRefForwardingComponent<'div', CDropdownProps>
305311
}
306312

307313
if (event.key === 'Escape') {
308-
setVisible(false)
314+
handleHide()
309315
}
310316
}
311317

@@ -323,11 +329,25 @@ export const CDropdown: PolymorphicRefForwardingComponent<'div', CDropdownProps>
323329
(autoClose === 'inside' && dropdownMenuRef.current.contains(event.target as HTMLElement)) ||
324330
(autoClose === 'outside' && !dropdownMenuRef.current.contains(event.target as HTMLElement))
325331
) {
326-
setTimeout(() => setVisible(false), 1)
332+
setTimeout(() => handleHide(), 1)
327333
return
328334
}
329335
}
330336

337+
const contextValues = {
338+
alignment,
339+
container,
340+
dark,
341+
dropdownMenuRef,
342+
dropdownToggleRef,
343+
handleHide,
344+
handleShow,
345+
popper: allowPopperUse,
346+
portal,
347+
variant,
348+
visible: _visible,
349+
}
350+
331351
return (
332352
<CDropdownContext.Provider value={contextValues}>
333353
{variant === 'input-group' ? (

‎packages/coreui-react/src/components/dropdown/CDropdownContext.ts

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,8 @@ export interface CDropdownContextProps {
77
dark?: boolean
88
dropdownMenuRef: RefObject<HTMLDivElement | HTMLUListElement | null>
99
dropdownToggleRef: (node: HTMLElement | null) => void
10-
setVisible: React.Dispatch<React.SetStateAction<boolean | undefined>>
10+
handleHide?: () => void
11+
handleShow?: () => void
1112
popper?: boolean
1213
portal?: boolean
1314
variant?: 'btn-group' | 'dropdown' | 'input-group' | 'nav-item'

‎packages/coreui-react/src/components/dropdown/CDropdownToggle.tsx

Lines changed: 10 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -45,18 +45,24 @@ export const CDropdownToggle: FC<CDropdownToggleProps> = ({
4545
trigger = 'click',
4646
...rest
4747
}) => {
48-
const { dropdownToggleRef, variant, visible, setVisible } = useContext(CDropdownContext)
48+
const { dropdownToggleRef, handleHide, handleShow, variant, visible } =
49+
useContext(CDropdownContext)
4950

5051
const triggers = {
5152
...((trigger === 'click' || trigger.includes('click')) && {
5253
onClick: (event: React.MouseEvent<HTMLElement>) => {
5354
event.preventDefault()
54-
setVisible(!visible)
55+
56+
if (visible) {
57+
handleHide?.()
58+
} else {
59+
handleShow?.()
60+
}
5561
},
5662
}),
5763
...((trigger === 'focus' || trigger.includes('focus')) && {
58-
onFocus: () => setVisible(true),
59-
onBlur: () => setVisible(false),
64+
onFocus: () => handleShow?.(),
65+
onBlur: () => handleHide?.(),
6066
}),
6167
}
6268

0 commit comments

Comments
(0)

AltStyle によって変換されたページ (->オリジナル) /