Movatterモバイル変換


[0]ホーム

URL:


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

Commitb06b99d

Browse files
committed
feat(CDropdown): add reference prop for custom positioning targets
1 parent9a8af53 commitb06b99d

File tree

4 files changed

+94
-16
lines changed

4 files changed

+94
-16
lines changed

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

Lines changed: 38 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -21,7 +21,7 @@ import type { Placements } from '../../types'
2121
import{getNextActiveElement,isRTL}from'../../utils'
2222

2323
importtype{Alignments,Directions}from'./types'
24-
import{getPlacement}from'./utils'
24+
import{getPlacement,getReferenceElement}from'./utils'
2525
import{CFocusTrap}from'../focus-trap'
2626

2727
exportinterfaceCDropdownPropsextendsHTMLAttributes<HTMLDivElement|HTMLLIElement>{
@@ -161,6 +161,27 @@ export interface CDropdownProps extends HTMLAttributes<HTMLDivElement | HTMLLIEl
161161
*/
162162
portal?:boolean
163163

164+
/**
165+
* Sets the reference element for positioning the React Dropdown Menu.
166+
* - `toggle` - The React Dropdown Toggle button (default).
167+
* - `parent` - The React Dropdown wrapper element.
168+
* - `HTMLElement` - A custom HTML element.
169+
* - `React.RefObject` - A custom reference element.
170+
*
171+
*@example
172+
* // Use the parent element as reference for positioning
173+
* <CDropdown reference="parent">
174+
* <CDropdownToggle>Toggle dropdown</CDropdownToggle>
175+
* <CDropdownMenu>
176+
* <CDropdownItem>Action</CDropdownItem>
177+
* <CDropdownItem>Another Action</CDropdownItem>
178+
* </CDropdownMenu>
179+
* </CDropdown>
180+
*
181+
*@since 5.9.0
182+
*/
183+
reference?:'parent'|'toggle'|HTMLElement|React.RefObject<HTMLElement|null>
184+
164185
/**
165186
* Defines the visual variant of the React Dropdown
166187
*/
@@ -204,6 +225,7 @@ export const CDropdown: PolymorphicRefForwardingComponent<'div', CDropdownProps>
204225
popper=true,
205226
popperConfig,
206227
portal=false,
228+
reference='toggle',
207229
variant='btn-group',
208230
visible=false,
209231
...rest
@@ -255,12 +277,12 @@ export const CDropdown: PolymorphicRefForwardingComponent<'div', CDropdownProps>
255277
},[visible])
256278

257279
useEffect(()=>{
258-
consttoggleElement=dropdownToggleElement
280+
constreferenceElement=getReferenceElement(reference,dropdownToggleElement,dropdownRef)
259281
constmenuElement=dropdownMenuRef.current
260-
if(allowPopperUse&&menuElement&&toggleElement&&_visible){
261-
initPopper(toggleElement,menuElement,computedPopperConfig)
282+
if(allowPopperUse&&menuElement&&referenceElement&&_visible){
283+
initPopper(referenceElement,menuElement,computedPopperConfig)
262284
}
263-
},[dropdownToggleElement])
285+
},[dropdownToggleElement,reference])
264286

265287
useEffect(()=>{
266288
if(pendingKeyDownEvent!==null){
@@ -272,21 +294,21 @@ export const CDropdown: PolymorphicRefForwardingComponent<'div', CDropdownProps>
272294
consthandleHide=useCallback(()=>{
273295
setVisible(false)
274296

275-
consttoggleElement=dropdownToggleElement
276297
constmenuElement=dropdownMenuRef.current
298+
consttoggleElement=dropdownToggleElement
277299

278300
if(allowPopperUse){
279301
destroyPopper()
280302
}
281303

282-
toggleElement?.removeEventListener('keydown',handleKeydown)
283304
menuElement?.removeEventListener('keydown',handleKeydown)
305+
toggleElement?.removeEventListener('keydown',handleKeydown)
284306

285307
window.removeEventListener('click',handleClick)
286308
window.removeEventListener('keyup',handleKeyup)
287309

288310
onHide?.()
289-
},[dropdownToggleElement,allowPopperUse,destroyPopper,onHide])
311+
},[allowPopperUse,dropdownToggleElement,destroyPopper,onHide])
290312

291313
consthandleKeydown=useCallback((event:KeyboardEvent)=>{
292314
if(!dropdownMenuRef.current){
@@ -316,7 +338,7 @@ export const CDropdown: PolymorphicRefForwardingComponent<'div', CDropdownProps>
316338
dropdownToggleElement?.focus()
317339
}
318340
},
319-
[autoClose,handleHide]
341+
[autoClose,dropdownToggleElement,handleHide]
320342
)
321343

322344
consthandleClick=useCallback(
@@ -357,14 +379,15 @@ export const CDropdown: PolymorphicRefForwardingComponent<'div', CDropdownProps>
357379

358380
consthandleShow=useCallback(
359381
(event?:KeyboardEvent)=>{
360-
consttoggleElement=dropdownToggleElement
361382
constmenuElement=dropdownMenuRef.current
383+
constreferenceElement=getReferenceElement(reference,dropdownToggleElement,dropdownRef)
384+
consttoggleElement=dropdownToggleElement
362385

363-
if(toggleElement&&menuElement){
386+
if(menuElement&&referenceElement&&toggleElement){
364387
setVisible(true)
365388

366389
if(allowPopperUse){
367-
initPopper(toggleElement,menuElement,computedPopperConfig)
390+
initPopper(referenceElement,menuElement,computedPopperConfig)
368391
}
369392

370393
toggleElement.focus()
@@ -382,13 +405,14 @@ export const CDropdown: PolymorphicRefForwardingComponent<'div', CDropdownProps>
382405
}
383406
},
384407
[
385-
dropdownToggleElement,
386408
allowPopperUse,
387-
initPopper,
388409
computedPopperConfig,
410+
dropdownToggleElement,
411+
reference,
389412
handleClick,
390413
handleKeydown,
391414
handleKeyup,
415+
initPopper,
392416
onShow,
393417
]
394418
)

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

Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,4 @@
1+
importReactfrom'react'
12
importtype{Placement}from'@popperjs/core'
23
importtype{Placements}from'../../types'
34
importtype{Alignments,Breakpoints}from'./types'
@@ -49,3 +50,23 @@ export const getPlacement = (
4950

5051
return_placement
5152
}
53+
54+
exportconstgetReferenceElement=(
55+
reference:'parent'|'toggle'|React.RefObject<HTMLElement|null>|HTMLElement,
56+
dropdownToggleElement:HTMLElement|null,
57+
dropdownRef:React.RefObject<HTMLElement|null>
58+
):HTMLElement|null=>{
59+
if(reference==='parent'){
60+
returndropdownRef.current
61+
}
62+
63+
if(referenceinstanceofHTMLElement){
64+
returnreference
65+
}
66+
67+
if(referenceinstanceofObject&&'current'inreference){
68+
returnreference.current
69+
}
70+
71+
returndropdownToggleElement
72+
}

‎packages/docs/content/api/CDropdown.api.mdx‎

Lines changed: 24 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -190,6 +190,30 @@ const myContainer = document.getElementById('my-container')
190190
<p>Renders the React Dropdown Menu using a React Portal, allowing it to escape the DOM hierarchy for improved positioning.</p>
191191
</td>
192192
</tr>
193+
<trid="cdropdown-reference">
194+
<tdclassName="text-primary fw-semibold">reference<ahref="#cdropdown-reference"aria-label="CDropdown reference permalink"className="anchor-link after">#</a><spanclassName="badge bg-success">5.9.0+</span></td>
195+
<td><code>{`toggle`}</code></td>
196+
<td><code>{`HTMLElement`}</code>, <code>{`'parent'`}</code>, <code>{`'toggle'`}</code>, <code>{`RefObject\<HTMLElement>`}</code></td>
197+
</tr>
198+
<tr>
199+
<tdcolSpan="3">
200+
<p>Sets the reference element for positioning the React Dropdown Menu.</p>
201+
<ul>
202+
<li><code>{`toggle`}</code> - The React Dropdown Toggle button (default).</li>
203+
<li><code>{`parent`}</code> - The React Dropdown wrapper element.</li>
204+
<li><code>{`HTMLElement`}</code> - A custom HTML element.</li>
205+
<li><code>{`React.RefObject`}</code> - A custom reference element.</li>
206+
</ul>
207+
<JSXDocscode={`// Use the parent element as reference for positioning
208+
<CDropdown reference="parent">
209+
<CDropdownToggle>Toggle dropdown</CDropdownToggle>
210+
<CDropdownMenu>
211+
<CDropdownItem>Action</CDropdownItem>
212+
<CDropdownItem>Another Action</CDropdownItem>
213+
</CDropdownMenu>
214+
</CDropdown>`} />
215+
</td>
216+
</tr>
193217
<trid="cdropdown-variant">
194218
<tdclassName="text-primary fw-semibold">variant<ahref="#cdropdown-variant"aria-label="CDropdown variant permalink"className="anchor-link after">#</a></td>
195219
<td><code>{`btn-group`}</code></td>

‎packages/docs/content/components/dropdown/examples/DropdownOptionsExample.tsx‎

Lines changed: 11 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
importReactfrom'react'
2-
import{CDropdown,CDropdownItem,CDropdownMenu,CDropdownToggle}from'@coreui/react'
2+
import{CButton,CDropdown,CDropdownItem,CDropdownMenu,CDropdownToggle}from'@coreui/react'
33

44
exportconstDropdownOptionsExample=()=>{
55
return(
@@ -12,7 +12,7 @@ export const DropdownOptionsExample = () => {
1212
<CDropdownItemhref="#">Something else here</CDropdownItem>
1313
</CDropdownMenu>
1414
</CDropdown>
15-
<CDropdownportalvariant="input-group">
15+
<CDropdownportal>
1616
<CDropdownTogglecolor="secondary"aria-controls="dropdownMenuInPortal">
1717
Portal
1818
</CDropdownToggle>
@@ -22,6 +22,15 @@ export const DropdownOptionsExample = () => {
2222
<CDropdownItemhref="#">Something else here</CDropdownItem>
2323
</CDropdownMenu>
2424
</CDropdown>
25+
<CDropdownreference="parent">
26+
<CButtoncolor="secondary">Reference</CButton>
27+
<CDropdownTogglecolor="secondary"split/>
28+
<CDropdownMenu>
29+
<CDropdownItemhref="#">Action</CDropdownItem>
30+
<CDropdownItemhref="#">Another action</CDropdownItem>
31+
<CDropdownItemhref="#">Something else here</CDropdownItem>
32+
</CDropdownMenu>
33+
</CDropdown>
2534
</div>
2635
)
2736
}

0 commit comments

Comments
 (0)

[8]ページ先頭

©2009-2025 Movatter.jp