@@ -10,6 +10,7 @@ import {
10
10
import { computed , nextTick } from ' vue'
11
11
import { useKbd } from ' @/shared'
12
12
import { getDaysInMonth , toDate } from ' @/date'
13
+ import { getSelectableCells } from ' ./utils'
13
14
14
15
export interface CalendarCellTriggerProps extends PrimitiveProps {
15
16
/** The date value provided to the cell trigger */
@@ -83,9 +84,6 @@ const isFocusedDate = computed(() => {
83
84
})
84
85
const isSelectedDate = computed (() => rootContext .isDateSelected (props .day ))
85
86
86
- const SELECTOR
87
- = ' [data-reka-calendar-cell-trigger]:not([data-outside-view]):not([data-outside-visible-view])'
88
-
89
87
function changeDate(date : DateValue ) {
90
88
if (rootContext .readonly .value )
91
89
return
@@ -103,82 +101,105 @@ function handleArrowKey(e: KeyboardEvent) {
103
101
e .preventDefault ()
104
102
e .stopPropagation ()
105
103
const parentElement = rootContext .parentElement .value !
106
- const allCollectionItems: HTMLElement [] = parentElement
107
- ? Array .from (parentElement .querySelectorAll (SELECTOR ))
108
- : []
109
- const index = allCollectionItems .indexOf (currentElement .value )
110
- let newIndex = index
111
104
const indexIncrementation = 7
112
105
const sign = rootContext .dir .value === ' rtl' ? - 1 : 1
113
106
switch (e .code ) {
114
107
case kbd .ARROW_RIGHT :
115
- newIndex += sign
108
+ shiftFocus ( currentElement . value , sign )
116
109
break
117
110
case kbd .ARROW_LEFT :
118
- newIndex -= sign
111
+ shiftFocus ( currentElement . value , - sign )
119
112
break
120
113
case kbd .ARROW_UP :
121
- newIndex -= indexIncrementation
114
+ shiftFocus ( currentElement . value , - indexIncrementation )
122
115
break
123
116
case kbd .ARROW_DOWN :
124
- newIndex += indexIncrementation
117
+ shiftFocus ( currentElement . value , indexIncrementation )
125
118
break
126
119
case kbd .ENTER :
127
120
case kbd .SPACE_CODE :
128
121
changeDate (props .day )
129
- return
130
- default :
131
- return
132
122
}
133
123
134
- if (newIndex >= 0 && newIndex < allCollectionItems .length ) {
135
- allCollectionItems [newIndex ].focus ()
136
- return
137
- }
124
+ function shiftFocus(node : HTMLElement , add : number ) {
125
+ const allCollectionItems: HTMLElement [] = getSelectableCells (parentElement )
126
+ if (! allCollectionItems .length )
127
+ return
128
+
129
+ const index = allCollectionItems .indexOf (node )
130
+ const newIndex = index + add
138
131
139
- if (newIndex < 0 ) {
140
- if (rootContext .isPrevButtonDisabled ())
132
+ if (newIndex >= 0 && newIndex < allCollectionItems .length ) {
133
+ if (allCollectionItems [newIndex ].hasAttribute (' data-disabled' )) {
134
+ shiftFocus (allCollectionItems [newIndex ], add )
135
+ }
136
+ allCollectionItems [newIndex ].focus ()
141
137
return
142
- rootContext .prevPage ()
143
- nextTick (() => {
144
- const newCollectionItems: HTMLElement [] = parentElement
145
- ? Array .from (parentElement .querySelectorAll (SELECTOR ))
146
- : []
147
- if (! rootContext .pagedNavigation .value && rootContext .numberOfMonths .value > 1 ) {
138
+ }
139
+
140
+ if (newIndex < 0 ) {
141
+ if (rootContext .isPrevButtonDisabled ())
142
+ return
143
+ rootContext .prevPage ()
144
+ nextTick (() => {
145
+ const newCollectionItems: HTMLElement [] = getSelectableCells (parentElement )
146
+ if (! newCollectionItems .length )
147
+ return
148
+ if (! rootContext .pagedNavigation .value && rootContext .numberOfMonths .value > 1 ) {
148
149
// Placeholder is set to first month of the new page
149
- const numberOfDays = getDaysInMonth (rootContext .placeholder .value )
150
+ const numberOfDays = getDaysInMonth (rootContext .placeholder .value )
151
+ const computedIndex = numberOfDays - Math .abs (newIndex )
152
+ if (newCollectionItems [computedIndex ].hasAttribute (' data-disabled' )) {
153
+ shiftFocus (newCollectionItems [computedIndex ], add )
154
+ }
155
+ newCollectionItems [
156
+ computedIndex
157
+ ].focus ()
158
+ return
159
+ }
160
+ const computedIndex = newCollectionItems .length - Math .abs (newIndex )
161
+ if (newCollectionItems [computedIndex ].hasAttribute (' data-disabled' )) {
162
+ shiftFocus (newCollectionItems [computedIndex ], add )
163
+ }
150
164
newCollectionItems [
151
- numberOfDays - Math . abs ( newIndex )
165
+ computedIndex
152
166
].focus ()
153
- return
154
- }
155
- newCollectionItems [
156
- newCollectionItems .length - Math .abs (newIndex )
157
- ].focus ()
158
- })
159
- return
160
- }
161
-
162
- if (newIndex >= allCollectionItems .length ) {
163
- if (rootContext .isNextButtonDisabled ())
167
+ })
164
168
return
165
- rootContext .nextPage ()
166
- nextTick (() => {
167
- const newCollectionItems: HTMLElement [] = parentElement
168
- ? Array .from (parentElement .querySelectorAll (SELECTOR ))
169
- : []
169
+ }
170
170
171
- if (! rootContext .pagedNavigation .value && rootContext .numberOfMonths .value > 1 ) {
172
- // Placeholder is set to first month of the new page
173
- const numberOfDays = getDaysInMonth (
174
- rootContext .placeholder .value .add ({ months: rootContext .numberOfMonths .value - 1 }),
175
- )
176
- newCollectionItems [newIndex - allCollectionItems .length + (newCollectionItems .length - numberOfDays )].focus ()
171
+ if (newIndex >= allCollectionItems .length ) {
172
+ if (rootContext .isNextButtonDisabled ())
177
173
return
178
- }
174
+ rootContext .nextPage ()
175
+ nextTick (() => {
176
+ const newCollectionItems: HTMLElement [] = getSelectableCells (parentElement )
177
+ if (! newCollectionItems .length )
178
+ return
179
179
180
- newCollectionItems [newIndex - allCollectionItems .length ].focus ()
181
- })
180
+ if (! rootContext .pagedNavigation .value && rootContext .numberOfMonths .value > 1 ) {
181
+ // Placeholder is set to first month of the new page
182
+ const numberOfDays = getDaysInMonth (
183
+ rootContext .placeholder .value .add ({ months: rootContext .numberOfMonths .value - 1 }),
184
+ )
185
+
186
+ const computedIndex = newIndex - allCollectionItems .length + (newCollectionItems .length - numberOfDays )
187
+
188
+ if (newCollectionItems [computedIndex ].hasAttribute (' data-disabled' )) {
189
+ shiftFocus (newCollectionItems [computedIndex ], add )
190
+ }
191
+ newCollectionItems [computedIndex ].focus ()
192
+ return
193
+ }
194
+
195
+ const computedIndex = newIndex - allCollectionItems .length
196
+ if (newCollectionItems [computedIndex ].hasAttribute (' data-disabled' )) {
197
+ shiftFocus (newCollectionItems [computedIndex ], add )
198
+ }
199
+
200
+ newCollectionItems [computedIndex ].focus ()
201
+ })
202
+ }
182
203
}
183
204
}
184
205
</script >
0 commit comments