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

Commit61ee9b7

Browse files
committed
refactor(CDropdown): improve arrow keys handling
1 parent67b6f9a commit61ee9b7

File tree

2 files changed

+42
-25
lines changed

2 files changed

+42
-25
lines changed

‎packages/coreui-vue/src/components/dropdown/CDropdown.ts‎

Lines changed: 34 additions & 23 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
import{defineComponent,h,ref,provide,watch,PropType}from'vue'
1+
import{defineComponent,h,ref,provide,watch,PropType,onUnmounted,nextTick}from'vue'
22
importtype{Placement}from'@popperjs/core'
33

44
import{usePopper}from'../../composables'
@@ -158,6 +158,7 @@ const CDropdown = defineComponent({
158158
setup(props,{ slots, emit}){
159159
constdropdownToggleRef=ref()
160160
constdropdownMenuRef=ref()
161+
constpendingKeyDownEventRef=ref<KeyboardEvent|null>(null)
161162
constpopper=ref(typeofprops.alignment==='object' ?false :props.popper)
162163
constvisible=ref(props.visible)
163164

@@ -176,35 +177,50 @@ const CDropdown = defineComponent({
176177
props.placement,
177178
props.direction,
178179
props.alignment,
179-
isRTL(dropdownMenuRef.value),
180+
isRTL(dropdownMenuRef.value)
180181
)asPlacement,
181182
}
182183

183184
watch(
184185
()=>props.visible,
185186
()=>{
186187
visible.value=props.visible
187-
},
188+
}
188189
)
189190

190191
watch(visible,()=>{
191192
if(visible.value&&dropdownToggleRef.value&&dropdownMenuRef.value){
192-
popper.value&&initPopper(dropdownToggleRef.value,dropdownMenuRef.value,popperConfig)
193+
if(popper.value){
194+
initPopper(dropdownToggleRef.value,dropdownMenuRef.value,popperConfig)
195+
}
196+
193197
window.addEventListener('mouseup',handleMouseUp)
194198
window.addEventListener('keyup',handleKeyup)
195199
dropdownToggleRef.value.addEventListener('keydown',handleKeydown)
196200
dropdownMenuRef.value.addEventListener('keydown',handleKeydown)
201+
202+
if(pendingKeyDownEventRef.value){
203+
nextTick(()=>{
204+
handleKeydown(pendingKeyDownEventRef.valueasKeyboardEvent)
205+
pendingKeyDownEventRef.value=null
206+
})
207+
}
208+
197209
emit('show')
198210
return
199211
}
200212

201213
popper.value&&destroyPopper()
202214
window.removeEventListener('mouseup',handleMouseUp)
203215
window.removeEventListener('keyup',handleKeyup)
216+
dropdownMenuRef.value&&dropdownMenuRef.value.removeEventListener('keydown',handleKeydown)
217+
emit('hide')
218+
})
219+
220+
onUnmounted(()=>{
204221
dropdownToggleRef.value&&
205222
dropdownToggleRef.value.removeEventListener('keydown',handleKeydown)
206223
dropdownMenuRef.value&&dropdownMenuRef.value.removeEventListener('keydown',handleKeydown)
207-
emit('hide')
208224
})
209225

210226
provide('config',{
@@ -219,18 +235,14 @@ const CDropdown = defineComponent({
219235
provide('visible',visible)
220236
provide('dropdownToggleRef',dropdownToggleRef)
221237
provide('dropdownMenuRef',dropdownMenuRef)
238+
provide('pendingKeyDownEventRef',pendingKeyDownEventRef)
222239

223240
consthandleKeydown=(event:KeyboardEvent)=>{
224-
if(
225-
visible.value&&
226-
dropdownMenuRef.value&&
227-
(event.key==='ArrowDown'||event.key==='ArrowUp')
228-
){
241+
if(dropdownMenuRef.value&&(event.key==='ArrowDown'||event.key==='ArrowUp')){
229242
event.preventDefault()
230243
consttarget=event.targetasHTMLElement
231-
// eslint-disable-next-line unicorn/prefer-spread
232244
constitems:HTMLElement[]=Array.from(
233-
dropdownMenuRef.value.querySelectorAll('.dropdown-item:not(.disabled):not(:disabled)'),
245+
dropdownMenuRef.value.querySelectorAll('.dropdown-item:not(.disabled):not(:disabled)')
234246
)
235247
getNextActiveElement(items,target,event.key==='ArrowDown',true).focus()
236248
}
@@ -243,6 +255,7 @@ const CDropdown = defineComponent({
243255

244256
if(event.key==='Escape'){
245257
setVisible(false)
258+
dropdownToggleRef.value?.focus()
246259
}
247260
}
248261

@@ -267,22 +280,20 @@ const CDropdown = defineComponent({
267280
}
268281
}
269282

270-
constsetVisible=(_visible?:boolean)=>{
283+
constsetVisible=(_visible?:boolean,event?:KeyboardEvent)=>{
271284
if(props.disabled){
272285
return
273286
}
274287

275-
if(typeof_visible=='boolean'){
288+
if(typeof_visible==='boolean'){
289+
if(event){
290+
pendingKeyDownEventRef.value=event||null
291+
}
292+
276293
visible.value=_visible
277-
return
278-
}
279294

280-
if(visible.value===true){
281-
visible.value=false
282295
return
283296
}
284-
285-
visible.value=true
286297
}
287298

288299
provide('setVisible',setVisible)
@@ -298,11 +309,11 @@ const CDropdown = defineComponent({
298309
props.direction==='center'
299310
?'dropdown-center'
300311
:props.direction==='dropup-center'
301-
?'dropup dropup-center'
302-
:props.direction,
312+
?'dropup dropup-center'
313+
:props.direction,
303314
],
304315
},
305-
slots.default&&slots.default(),
316+
slots.default&&slots.default()
306317
)
307318
},
308319
})

‎packages/coreui-vue/src/components/dropdown/CDropdownToggle.ts‎

Lines changed: 8 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -100,7 +100,7 @@ const CDropdownToggle = defineComponent({
100100
constdropdownToggleRef=inject('dropdownToggleRef')asRef<HTMLElement>
101101
constdropdownVariant=inject('variant')asstring
102102
constvisible=inject('visible')asRef<boolean>
103-
constsetVisible=inject('setVisible')as(_visible?:boolean)=>void
103+
constsetVisible=inject('setVisible')as(_visible?:boolean,event?:KeyboardEvent)=>void
104104

105105
consttriggers={
106106
...((props.trigger==='click'||props.trigger.includes('click'))&&{
@@ -110,7 +110,7 @@ const CDropdownToggle = defineComponent({
110110
return
111111
}
112112

113-
setVisible()
113+
setVisible(!visible.value)
114114
},
115115
}),
116116
...((props.trigger==='focus'||props.trigger.includes('focus'))&&{
@@ -128,6 +128,12 @@ const CDropdownToggle = defineComponent({
128128
setVisible(false)
129129
},
130130
}),
131+
onkeydown:(event:KeyboardEvent)=>{
132+
if(event.key==='ArrowDown'||event.key==='ArrowUp'){
133+
event.preventDefault()
134+
setVisible(true,event)
135+
}
136+
}
131137
}
132138

133139
consttogglerProps=computed(()=>{

0 commit comments

Comments
 (0)

[8]ページ先頭

©2009-2025 Movatter.jp