@@ -10,7 +10,9 @@ import BaseComponent from './base-component.js'
10
10
import EventHandler from './dom/event-handler.js'
11
11
import Manipulator from './dom/manipulator.js'
12
12
import SelectorEngine from './dom/selector-engine.js'
13
- import { defineJQueryPlugin , getElement , isRTL } from './util/index.js'
13
+ import {
14
+ defineJQueryPlugin , getElement , getNextActiveElement , isRTL
15
+ } from './util/index.js'
14
16
import {
15
17
convert12hTo24h ,
16
18
convert24hTo12h ,
@@ -33,9 +35,14 @@ const ENTER_KEY = 'Enter'
33
35
const ESCAPE_KEY = 'Escape'
34
36
const SPACE_KEY = 'Space'
35
37
const TAB_KEY = 'Tab'
38
+ const ARROW_UP_KEY = 'ArrowUp'
39
+ const ARROW_DOWN_KEY = 'ArrowDown'
40
+ const ARROW_LEFT_KEY = 'ArrowLeft'
41
+ const ARROW_RIGHT_KEY = 'ArrowRight'
36
42
const RIGHT_MOUSE_BUTTON = 2
37
43
38
44
const EVENT_CLICK = `click${ EVENT_KEY } `
45
+ const EVENT_FOCUSOUT = `focusout${ EVENT_KEY } `
39
46
const EVENT_HIDE = `hide${ EVENT_KEY } `
40
47
const EVENT_HIDDEN = `hidden${ EVENT_KEY } `
41
48
const EVENT_INPUT = 'input'
@@ -71,6 +78,9 @@ const CLASS_NAME_WAS_VALIDATED = 'was-validated'
71
78
const SELECTOR_DATA_TOGGLE =
72
79
'[data-coreui-toggle="time-picker"]:not(.disabled):not(:disabled)'
73
80
const SELECTOR_DATA_TOGGLE_SHOWN = `${ SELECTOR_DATA_TOGGLE } .${ CLASS_NAME_SHOW } `
81
+ const SELECTOR_ROLL_CELL = '.time-picker-roll-cell'
82
+ const SELECTOR_ROLL_CELL_SELECTED = '.time-picker-roll-cell.selected'
83
+ const SELECTOR_ROLL_COL = '.time-picker-roll-col'
74
84
const SELECTOR_WAS_VALIDATED = 'form.was-validated'
75
85
76
86
const Default = {
@@ -294,6 +304,58 @@ class TimePicker extends BaseComponent {
294
304
}
295
305
} )
296
306
307
+ if ( this . _config . variant === 'roll' ) {
308
+ EventHandler . on ( this . _timePickerBody , EVENT_FOCUSOUT , SELECTOR_ROLL_COL , ( ) => {
309
+ this . _setUpRolls ( false )
310
+ } )
311
+
312
+ EventHandler . on ( this . _timePickerBody , EVENT_KEYDOWN , SELECTOR_ROLL_CELL , event => {
313
+ if ( event . key === ARROW_DOWN_KEY || event . key === ARROW_UP_KEY ) {
314
+ event . preventDefault ( )
315
+ const { key, target } = event
316
+ const items = SelectorEngine . find ( SELECTOR_ROLL_CELL , target . parentElement )
317
+
318
+ if ( ! items . length ) {
319
+ return
320
+ }
321
+
322
+ getNextActiveElement ( items , target , key === ARROW_DOWN_KEY , ! items . includes ( target ) ) . focus ( )
323
+ }
324
+
325
+ if ( event . key === ARROW_LEFT_KEY || event . key === ARROW_RIGHT_KEY ) {
326
+ event . preventDefault ( )
327
+ const { key, target } = event
328
+ const columnElement = target . parentElement
329
+
330
+ if ( this . _timePickerBody ) {
331
+ const columns = SelectorEngine . find ( SELECTOR_ROLL_COL , this . _timePickerBody )
332
+ const currentColumnIndex = columns . indexOf ( columnElement )
333
+
334
+ let targetColumnIndex
335
+ const isRtl = isRTL ( )
336
+ const shouldGoLeft = ( key === ARROW_LEFT_KEY && ! isRtl ) || ( key === ARROW_RIGHT_KEY && isRtl )
337
+ if ( shouldGoLeft ) {
338
+ targetColumnIndex = currentColumnIndex > 0 ? currentColumnIndex - 1 : columns . length - 1
339
+ } else {
340
+ targetColumnIndex = currentColumnIndex < columns . length - 1 ? currentColumnIndex + 1 : 0
341
+ }
342
+
343
+ const targetColumn = columns [ targetColumnIndex ]
344
+ const selectedCell = SelectorEngine . findOne ( SELECTOR_ROLL_CELL_SELECTED , targetColumn )
345
+
346
+ if ( selectedCell ) {
347
+ selectedCell . focus ( )
348
+ return
349
+ }
350
+
351
+ const firstFocusableCell = SelectorEngine . findOne ( SELECTOR_ROLL_CELL , targetColumn )
352
+
353
+ firstFocusableCell . focus ( )
354
+ }
355
+ }
356
+ } )
357
+ }
358
+
297
359
EventHandler . on ( this . _element , EVENT_KEYDOWN , event => {
298
360
if ( event . key === ESCAPE_KEY ) {
299
361
this . hide ( )
0 commit comments