Skip to content

Commit 0ce5cb4

Browse files
authored
Merge pull request sumcumo#188 from mst101/fix/web-components
Allow datepicker to be used in a web component
2 parents 184b557 + 5a7be1e commit 0ce5cb4

File tree

3 files changed

+37
-17
lines changed

3 files changed

+37
-17
lines changed

src/components/Datepicker.vue

Lines changed: 4 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -531,7 +531,7 @@ export default {
531531
handlePageChange({ focusRefs, pageDate }) {
532532
this.setPageDate(pageDate)
533533
this.focus.refs = focusRefs
534-
this.focus.delay = this.slideDuration
534+
this.focus.delay = this.slideDuration || 250
535535
this.reviewFocus()
536536
this.$emit(`changed-${this.nextView.up}`, pageDate)
537537
},
@@ -658,9 +658,10 @@ export default {
658658
return false
659659
}
660660
661+
const activeElement = this.getActiveElement()
661662
const isOpenCellFocused =
662-
this.hasClass(document.activeElement, 'cell') &&
663-
!this.hasClass(document.activeElement, 'open')
663+
this.hasClass(activeElement, 'cell') &&
664+
!this.hasClass(activeElement, 'open')
664665
665666
return !this.isMinimumView || isOpenCellFocused
666667
},

src/mixins/navMixin.vue

Lines changed: 24 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -112,15 +112,24 @@ export default {
112112
* Returns the currently focused cell element, if there is one...
113113
*/
114114
getActiveCell() {
115-
const isActiveElementACell = this.hasClass(document.activeElement, 'cell')
116-
const isOnSameView = this.hasClass(document.activeElement, this.view)
115+
const activeElement = this.getActiveElement()
116+
const isActiveElementACell = this.hasClass(activeElement, 'cell')
117+
const isOnSameView = this.hasClass(activeElement, this.view)
117118
118119
if (isActiveElementACell && isOnSameView && !this.resetTabbableCell) {
119-
return document.activeElement
120+
return activeElement
120121
}
121122
122123
return null
123124
},
125+
/**
126+
* Returns the currently focused element, using shadowRoot for web-components...
127+
*/
128+
getActiveElement() {
129+
return document.activeElement.shadowRoot
130+
? document.activeElement.shadowRoot.activeElement
131+
: document.activeElement
132+
},
124133
/**
125134
* Returns the `cellId` for a given a date
126135
* @param {Date} date The date for which we need the cellId
@@ -333,9 +342,10 @@ export default {
333342
return false
334343
}
335344
345+
const activeElement = this.getActiveElement()
336346
const firstNavElement = this.navElements[0]
337347
338-
return document.activeElement === firstNavElement
348+
return activeElement === firstNavElement
339349
},
340350
/**
341351
* Used for inline calendars; returns true if the user tabs forwards from the last focusable element
@@ -347,9 +357,10 @@ export default {
347357
return false
348358
}
349359
360+
const activeElement = this.getActiveElement()
350361
const lastNavElement = this.navElements[this.navElements.length - 1]
351362
352-
return document.activeElement === lastNavElement
363+
return activeElement === lastNavElement
353364
},
354365
/**
355366
* Resets the focus to the open date
@@ -453,8 +464,10 @@ export default {
453464
* Keeps track of the currently focused index in the navElements array
454465
*/
455466
setNavElementsFocusedIndex() {
467+
const activeElement = this.getActiveElement()
468+
456469
for (let i = 0; i < this.navElements.length; i += 1) {
457-
if (document.activeElement === this.navElements[i]) {
470+
if (activeElement === this.navElements[i]) {
458471
this.navElementsFocusedIndex = i
459472
return
460473
}
@@ -575,7 +588,8 @@ export default {
575588
tabToCorrectInlineCell() {
576589
const lastElement = this.getLastInlineFocusableElement()
577590
const isACell = this.hasClass(lastElement, 'cell')
578-
const isLastElementFocused = document.activeElement === lastElement
591+
const activeElement = this.getActiveElement()
592+
const isLastElementFocused = activeElement === lastElement
579593
580594
// If there are no focusable elements in the footer slots and the inline datepicker has been tabbed to (backwards)
581595
if (isACell && isLastElementFocused) {
@@ -585,8 +599,7 @@ export default {
585599
586600
// If `show-header` is false and the inline datepicker has been tabbed to (forwards)
587601
this.$nextTick(() => {
588-
const isFirstCell =
589-
document.activeElement.getAttribute('data-id') === '0'
602+
const isFirstCell = activeElement.getAttribute('data-id') === '0'
590603
591604
if (isFirstCell) {
592605
this.focusInlineTabbableCell()
@@ -597,7 +610,8 @@ export default {
597610
* Update which cell in the picker should be focus-trapped
598611
*/
599612
updateTabbableCell() {
600-
const isActiveElementACell = this.hasClass(document.activeElement, 'cell')
613+
const activeElement = this.getActiveElement()
614+
const isActiveElementACell = this.hasClass(activeElement, 'cell')
601615
const needToUpdate = !this.tabbableCell || isActiveElementACell
602616
603617
if (needToUpdate) {

src/mixins/pickerMixin.vue

Lines changed: 9 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -262,9 +262,12 @@ export default {
262262
* @param {Object}
263263
*/
264264
handleArrow({ delta }) {
265+
const activeElement = document.activeElement.shadowRoot
266+
? document.activeElement.shadowRoot.activeElement
267+
: document.activeElement
265268
const stepsRemaining = Math.abs(delta)
266269
const options = {
267-
currentElement: document.activeElement,
270+
currentElement: activeElement,
268271
delta,
269272
stepsRemaining,
270273
}
@@ -334,35 +337,37 @@ export default {
334337
* Sets the focus on the correct cell following a page change
335338
* @param {Object} options
336339
*/
340+
// eslint-disable-next-line max-statements
337341
setFocusOnNewPage({ delta, stepsRemaining }) {
338342
const currentElement = this.getFirstOrLastElement(delta)
339343
const options = {
340344
currentElement,
341345
delta,
342346
stepsRemaining,
343347
}
348+
const delay = this.slideDuration || 250
344349
345350
if (stepsRemaining <= 0) {
346351
if (this.isMutedOrDisabled(currentElement)) {
347352
options.stepsRemaining = Math.abs(options.delta)
348353
349354
setTimeout(() => {
350355
this.setFocusToAvailableCell(options)
351-
}, this.slideDuration)
356+
}, delay)
352357
353358
return
354359
}
355360
356361
setTimeout(() => {
357362
currentElement.focus()
358-
}, this.slideDuration)
363+
}, delay)
359364
360365
return
361366
}
362367
363368
setTimeout(() => {
364369
this.setFocusToAvailableCell(options)
365-
}, this.slideDuration)
370+
}, delay)
366371
},
367372
/**
368373
* Sets the focus on the next focusable cell when an arrow key is pressed

0 commit comments

Comments
 (0)