@coreui/react-pro 5.21.0 → 5.23.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +1 -1
- package/dist/cjs/components/autocomplete/CAutocomplete.js +2 -2
- package/dist/cjs/components/autocomplete/CAutocomplete.js.map +1 -1
- package/dist/cjs/components/calendar/CCalendarNavigation.js +6 -6
- package/dist/cjs/components/calendar/CCalendarNavigation.js.map +1 -1
- package/dist/cjs/components/date-range-picker/CDateRangePicker.js +1 -1
- package/dist/cjs/components/date-range-picker/CDateRangePicker.js.map +1 -1
- package/dist/cjs/components/dropdown/CDropdown.d.ts +21 -1
- package/dist/cjs/components/dropdown/CDropdown.js +67 -33
- package/dist/cjs/components/dropdown/CDropdown.js.map +1 -1
- package/dist/cjs/components/dropdown/CDropdownHeader.js.map +1 -1
- package/dist/cjs/components/dropdown/CDropdownItemPlain.js.map +1 -1
- package/dist/cjs/components/dropdown/CDropdownMenu.js.map +1 -1
- package/dist/cjs/components/dropdown/CDropdownToggle.d.ts +7 -0
- package/dist/cjs/components/dropdown/CDropdownToggle.js +3 -2
- package/dist/cjs/components/dropdown/CDropdownToggle.js.map +1 -1
- package/dist/cjs/components/dropdown/utils.d.ts +2 -0
- package/dist/cjs/components/dropdown/utils.js +13 -0
- package/dist/cjs/components/dropdown/utils.js.map +1 -1
- package/dist/cjs/components/focus-trap/utils.js +0 -5
- package/dist/cjs/components/focus-trap/utils.js.map +1 -1
- package/dist/cjs/components/index.d.ts +1 -0
- package/dist/cjs/components/one-time-password-input/COneTimePassword.d.ts +73 -0
- package/dist/cjs/components/one-time-password-input/COneTimePassword.js +178 -0
- package/dist/cjs/components/one-time-password-input/COneTimePassword.js.map +1 -0
- package/dist/cjs/components/one-time-password-input/COneTimePasswordInput.d.ts +8 -0
- package/dist/cjs/components/one-time-password-input/COneTimePasswordInput.js +14 -0
- package/dist/cjs/components/one-time-password-input/COneTimePasswordInput.js.map +1 -0
- package/dist/cjs/components/one-time-password-input/index.d.ts +5 -0
- package/dist/cjs/components/one-time-password-input/utils.d.ts +2 -0
- package/dist/cjs/components/one-time-password-input/utils.js +28 -0
- package/dist/cjs/components/one-time-password-input/utils.js.map +1 -0
- package/dist/cjs/components/time-picker/CTimePicker.d.ts +24 -0
- package/dist/cjs/components/time-picker/CTimePicker.js +37 -18
- package/dist/cjs/components/time-picker/CTimePicker.js.map +1 -1
- package/dist/cjs/components/time-picker/CTimePickerRollCol.d.ts +3 -0
- package/dist/cjs/components/time-picker/CTimePickerRollCol.js +74 -13
- package/dist/cjs/components/time-picker/CTimePickerRollCol.js.map +1 -1
- package/dist/cjs/index.js +4 -0
- package/dist/cjs/index.js.map +1 -1
- package/dist/esm/components/autocomplete/CAutocomplete.js +2 -2
- package/dist/esm/components/autocomplete/CAutocomplete.js.map +1 -1
- package/dist/esm/components/calendar/CCalendarNavigation.js +6 -6
- package/dist/esm/components/calendar/CCalendarNavigation.js.map +1 -1
- package/dist/esm/components/date-range-picker/CDateRangePicker.js +1 -1
- package/dist/esm/components/date-range-picker/CDateRangePicker.js.map +1 -1
- package/dist/esm/components/dropdown/CDropdown.d.ts +21 -1
- package/dist/esm/components/dropdown/CDropdown.js +68 -34
- package/dist/esm/components/dropdown/CDropdown.js.map +1 -1
- package/dist/esm/components/dropdown/CDropdownHeader.js.map +1 -1
- package/dist/esm/components/dropdown/CDropdownItemPlain.js.map +1 -1
- package/dist/esm/components/dropdown/CDropdownMenu.js.map +1 -1
- package/dist/esm/components/dropdown/CDropdownToggle.d.ts +7 -0
- package/dist/esm/components/dropdown/CDropdownToggle.js +3 -2
- package/dist/esm/components/dropdown/CDropdownToggle.js.map +1 -1
- package/dist/esm/components/dropdown/utils.d.ts +2 -0
- package/dist/esm/components/dropdown/utils.js +13 -1
- package/dist/esm/components/dropdown/utils.js.map +1 -1
- package/dist/esm/components/focus-trap/utils.js +0 -5
- package/dist/esm/components/focus-trap/utils.js.map +1 -1
- package/dist/esm/components/index.d.ts +1 -0
- package/dist/esm/components/one-time-password-input/COneTimePassword.d.ts +73 -0
- package/dist/esm/components/one-time-password-input/COneTimePassword.js +176 -0
- package/dist/esm/components/one-time-password-input/COneTimePassword.js.map +1 -0
- package/dist/esm/components/one-time-password-input/COneTimePasswordInput.d.ts +8 -0
- package/dist/esm/components/one-time-password-input/COneTimePasswordInput.js +12 -0
- package/dist/esm/components/one-time-password-input/COneTimePasswordInput.js.map +1 -0
- package/dist/esm/components/one-time-password-input/index.d.ts +5 -0
- package/dist/esm/components/one-time-password-input/utils.d.ts +2 -0
- package/dist/esm/components/one-time-password-input/utils.js +25 -0
- package/dist/esm/components/one-time-password-input/utils.js.map +1 -0
- package/dist/esm/components/time-picker/CTimePicker.d.ts +24 -0
- package/dist/esm/components/time-picker/CTimePicker.js +37 -18
- package/dist/esm/components/time-picker/CTimePicker.js.map +1 -1
- package/dist/esm/components/time-picker/CTimePickerRollCol.d.ts +3 -0
- package/dist/esm/components/time-picker/CTimePickerRollCol.js +75 -14
- package/dist/esm/components/time-picker/CTimePickerRollCol.js.map +1 -1
- package/dist/esm/index.js +2 -0
- package/dist/esm/index.js.map +1 -1
- package/package.json +10 -10
- package/src/components/autocomplete/CAutocomplete.tsx +18 -16
- package/src/components/calendar/CCalendarNavigation.tsx +10 -1
- package/src/components/date-range-picker/CDateRangePicker.tsx +1 -1
- package/src/components/dropdown/CDropdown.tsx +126 -60
- package/src/components/dropdown/CDropdownHeader.tsx +1 -0
- package/src/components/dropdown/CDropdownItemPlain.tsx +1 -0
- package/src/components/dropdown/CDropdownMenu.tsx +1 -0
- package/src/components/dropdown/CDropdownToggle.tsx +15 -1
- package/src/components/dropdown/utils.ts +21 -0
- package/src/components/focus-trap/utils.ts +0 -6
- package/src/components/index.ts +1 -0
- package/src/components/one-time-password-input/COneTimePassword.tsx +462 -0
- package/src/components/one-time-password-input/COneTimePasswordInput.tsx +25 -0
- package/src/components/one-time-password-input/__tests__/COneTimePassword.spec.tsx +361 -0
- package/src/components/one-time-password-input/__tests__/__snapshots__/COneTimePassword.spec.tsx.snap +130 -0
- package/src/components/one-time-password-input/index.ts +6 -0
- package/src/components/one-time-password-input/utils.ts +23 -0
- package/src/components/time-picker/CTimePicker.tsx +81 -10
- package/src/components/time-picker/CTimePickerRollCol.tsx +103 -20
|
@@ -31,8 +31,32 @@ export interface CTimePickerProps
|
|
|
31
31
|
* @since 4.8.0
|
|
32
32
|
*/
|
|
33
33
|
ampm?: 'auto' | boolean
|
|
34
|
+
/**
|
|
35
|
+
* Accessible label for the hours selection element.
|
|
36
|
+
*/
|
|
37
|
+
ariaSelectHoursLabel?: string
|
|
38
|
+
/**
|
|
39
|
+
* Accessible label for the AM/PM selection element.
|
|
40
|
+
*
|
|
41
|
+
* @since 5.22.0
|
|
42
|
+
*/
|
|
43
|
+
ariaSelectMeridiemLabel?: string
|
|
44
|
+
/**
|
|
45
|
+
* Accessible label for the minutes selection element.
|
|
46
|
+
*
|
|
47
|
+
* @since 5.22.0
|
|
48
|
+
*/
|
|
49
|
+
ariaSelectMinutesLabel?: string
|
|
50
|
+
/**
|
|
51
|
+
* Accessible label for the seconds selection element.
|
|
52
|
+
*
|
|
53
|
+
* @since 5.22.0
|
|
54
|
+
*/
|
|
55
|
+
ariaSelectSecondsLabel?: string
|
|
34
56
|
/**
|
|
35
57
|
* A string of all className you want applied to the component.
|
|
58
|
+
*
|
|
59
|
+
* @since 5.22.0
|
|
36
60
|
*/
|
|
37
61
|
className?: string
|
|
38
62
|
/**
|
|
@@ -158,6 +182,10 @@ export const CTimePicker = forwardRef<HTMLDivElement | HTMLLIElement, CTimePicke
|
|
|
158
182
|
(
|
|
159
183
|
{
|
|
160
184
|
ampm = 'auto',
|
|
185
|
+
ariaSelectHoursLabel = 'Select hours',
|
|
186
|
+
ariaSelectMeridiemLabel = 'Select AM/PM',
|
|
187
|
+
ariaSelectMinutesLabel = 'Select minutes',
|
|
188
|
+
ariaSelectSecondsLabel = 'Select seconds',
|
|
161
189
|
cancelButton = 'Cancel',
|
|
162
190
|
cancelButtonColor = 'primary',
|
|
163
191
|
cancelButtonSize = 'sm',
|
|
@@ -204,11 +232,13 @@ export const CTimePicker = forwardRef<HTMLDivElement | HTMLLIElement, CTimePicke
|
|
|
204
232
|
) => {
|
|
205
233
|
const formRef = useRef<HTMLFormElement>(null)
|
|
206
234
|
const inputRef = useRef<HTMLInputElement>(null)
|
|
235
|
+
const timePickerBodyRef = useRef<HTMLDivElement>(null)
|
|
236
|
+
const columnRefs = useRef<(HTMLDivElement | null)[]>([])
|
|
207
237
|
|
|
208
238
|
const [date, setDate] = useState<Date | null>(convertTimeToDate(time))
|
|
209
239
|
const [initialDate, setInitialDate] = useState<Date | null>(null)
|
|
210
240
|
const [isValid, setIsValid] = useState(valid ?? (invalid === true ? false : undefined))
|
|
211
|
-
const [_ampm, setAmPm] = useState<AmPm>(date ? getAmPm(new Date(date), locale) :
|
|
241
|
+
const [_ampm, setAmPm] = useState<AmPm | null>(date ? getAmPm(new Date(date), locale) : null)
|
|
212
242
|
const [_visible, setVisible] = useState(visible)
|
|
213
243
|
|
|
214
244
|
const [localizedTimePartials, setLocalizedTimePartials] = useState<LocalizedTimePartials>({
|
|
@@ -293,21 +323,32 @@ export const CTimePicker = forwardRef<HTMLDivElement | HTMLLIElement, CTimePicke
|
|
|
293
323
|
}
|
|
294
324
|
}, inputOnChangeDelay)
|
|
295
325
|
|
|
296
|
-
const handleTimeChange = (set: 'hours' | 'minutes' | 'seconds' | '
|
|
326
|
+
const handleTimeChange = (set: 'hours' | 'minutes' | 'seconds' | 'meridiem', value: string) => {
|
|
297
327
|
const _date = date || new Date('1970-01-01')
|
|
298
328
|
|
|
299
|
-
if (set === '
|
|
329
|
+
if (set === 'meridiem') {
|
|
330
|
+
const currentHours = _date.getHours()
|
|
331
|
+
|
|
300
332
|
if (value === 'am') {
|
|
301
|
-
|
|
333
|
+
setAmPm('am')
|
|
334
|
+
// Convert PM hours (12-23) to AM hours (0-11)
|
|
335
|
+
if (currentHours >= 12) {
|
|
336
|
+
_date.setHours(currentHours - 12)
|
|
337
|
+
}
|
|
302
338
|
}
|
|
339
|
+
|
|
303
340
|
if (value === 'pm') {
|
|
304
|
-
|
|
341
|
+
setAmPm('pm')
|
|
342
|
+
// Convert AM hours (0-11) to PM hours (12-23)
|
|
343
|
+
if (currentHours < 12) {
|
|
344
|
+
_date.setHours(currentHours + 12)
|
|
345
|
+
}
|
|
305
346
|
}
|
|
306
347
|
}
|
|
307
348
|
|
|
308
349
|
if (set === 'hours') {
|
|
309
350
|
if (localizedTimePartials && localizedTimePartials.hour12) {
|
|
310
|
-
_date.setHours(convert12hTo24h(_ampm, Number.parseInt(value)))
|
|
351
|
+
_date.setHours(convert12hTo24h(_ampm ?? 'am', Number.parseInt(value)))
|
|
311
352
|
} else {
|
|
312
353
|
_date.setHours(Number.parseInt(value))
|
|
313
354
|
}
|
|
@@ -343,7 +384,7 @@ export const CTimePicker = forwardRef<HTMLDivElement | HTMLLIElement, CTimePicke
|
|
|
343
384
|
(typeof indicator === 'boolean' ? (
|
|
344
385
|
<div
|
|
345
386
|
className="time-picker-indicator"
|
|
346
|
-
{...(disabled
|
|
387
|
+
{...(!disabled && {
|
|
347
388
|
onClick: () => setVisible(!_visible),
|
|
348
389
|
onKeyDown: (event) => {
|
|
349
390
|
if (event.key === 'Enter') {
|
|
@@ -380,6 +421,7 @@ export const CTimePicker = forwardRef<HTMLDivElement | HTMLLIElement, CTimePicke
|
|
|
380
421
|
handleTimeChange('hours', event.target.value)
|
|
381
422
|
}
|
|
382
423
|
value={getSelectedHour(date, locale)}
|
|
424
|
+
aria-label={ariaSelectHoursLabel}
|
|
383
425
|
>
|
|
384
426
|
{localizedTimePartials &&
|
|
385
427
|
localizedTimePartials.listOfHours.map((option, index) => (
|
|
@@ -398,6 +440,7 @@ export const CTimePicker = forwardRef<HTMLDivElement | HTMLLIElement, CTimePicke
|
|
|
398
440
|
handleTimeChange('minutes', event.target.value)
|
|
399
441
|
}
|
|
400
442
|
value={getSelectedMinutes(date)}
|
|
443
|
+
aria-label={ariaSelectMinutesLabel}
|
|
401
444
|
>
|
|
402
445
|
{localizedTimePartials &&
|
|
403
446
|
localizedTimePartials.listOfMinutes.map((option, index) => (
|
|
@@ -418,6 +461,7 @@ export const CTimePicker = forwardRef<HTMLDivElement | HTMLLIElement, CTimePicke
|
|
|
418
461
|
handleTimeChange('seconds', event.target.value)
|
|
419
462
|
}
|
|
420
463
|
value={getSelectedSeconds(date)}
|
|
464
|
+
aria-label={ariaSelectSecondsLabel}
|
|
421
465
|
>
|
|
422
466
|
{localizedTimePartials &&
|
|
423
467
|
localizedTimePartials.listOfSeconds.map((option, index) => (
|
|
@@ -433,9 +477,10 @@ export const CTimePicker = forwardRef<HTMLDivElement | HTMLLIElement, CTimePicke
|
|
|
433
477
|
className="time-picker-inline-select"
|
|
434
478
|
disabled={disabled}
|
|
435
479
|
onChange={(event: React.ChangeEvent<HTMLSelectElement>) =>
|
|
436
|
-
handleTimeChange('
|
|
480
|
+
handleTimeChange('meridiem', event.target.value)
|
|
437
481
|
}
|
|
438
|
-
value={_ampm}
|
|
482
|
+
value={_ampm ?? 'am'}
|
|
483
|
+
aria-label={ariaSelectMeridiemLabel}
|
|
439
484
|
>
|
|
440
485
|
<option value="am">AM</option>
|
|
441
486
|
<option value="pm">PM</option>
|
|
@@ -527,38 +572,64 @@ export const CTimePicker = forwardRef<HTMLDivElement | HTMLLIElement, CTimePicke
|
|
|
527
572
|
className={classNames('time-picker-body', {
|
|
528
573
|
['time-picker-roll']: variant === 'roll',
|
|
529
574
|
})}
|
|
575
|
+
{...(variant !== 'select' && { role: 'group' })}
|
|
576
|
+
ref={timePickerBodyRef}
|
|
530
577
|
>
|
|
531
578
|
{variant === 'select' ? (
|
|
532
579
|
<TimePickerSelect />
|
|
533
580
|
) : (
|
|
534
581
|
<>
|
|
535
582
|
<CTimePickerRollCol
|
|
583
|
+
ariaLabel={ariaSelectHoursLabel}
|
|
584
|
+
columnIndex={0}
|
|
585
|
+
columnRefs={columnRefs.current}
|
|
536
586
|
elements={localizedTimePartials && localizedTimePartials.listOfHours}
|
|
537
587
|
onClick={(index: number) => handleTimeChange('hours', index.toString())}
|
|
538
588
|
selected={getSelectedHour(date, locale, ampm)}
|
|
589
|
+
ref={(node: HTMLDivElement | null) => {
|
|
590
|
+
columnRefs.current[0] = node
|
|
591
|
+
}}
|
|
539
592
|
/>
|
|
540
593
|
{minutes && (
|
|
541
594
|
<CTimePickerRollCol
|
|
595
|
+
ariaLabel={ariaSelectMinutesLabel}
|
|
596
|
+
columnIndex={1}
|
|
597
|
+
columnRefs={columnRefs.current}
|
|
542
598
|
elements={localizedTimePartials && localizedTimePartials.listOfMinutes}
|
|
543
599
|
onClick={(index: number) => handleTimeChange('minutes', index.toString())}
|
|
544
600
|
selected={getSelectedMinutes(date)}
|
|
601
|
+
ref={(node: HTMLDivElement | null) => {
|
|
602
|
+
columnRefs.current[1] = node
|
|
603
|
+
}}
|
|
545
604
|
/>
|
|
546
605
|
)}
|
|
547
606
|
{seconds && (
|
|
548
607
|
<CTimePickerRollCol
|
|
608
|
+
ariaLabel={ariaSelectSecondsLabel}
|
|
609
|
+
columnIndex={minutes ? 2 : 1}
|
|
610
|
+
columnRefs={columnRefs.current}
|
|
549
611
|
elements={localizedTimePartials && localizedTimePartials.listOfSeconds}
|
|
550
612
|
onClick={(index: number) => handleTimeChange('seconds', index.toString())}
|
|
551
613
|
selected={getSelectedSeconds(date)}
|
|
614
|
+
ref={(node: HTMLDivElement | null) => {
|
|
615
|
+
columnRefs.current[minutes ? 2 : 1] = node
|
|
616
|
+
}}
|
|
552
617
|
/>
|
|
553
618
|
)}
|
|
554
619
|
{localizedTimePartials && localizedTimePartials.hour12 && (
|
|
555
620
|
<CTimePickerRollCol
|
|
621
|
+
ariaLabel={ariaSelectMeridiemLabel}
|
|
622
|
+
columnIndex={(minutes ? 1 : 0) + (seconds ? 1 : 0) + 1}
|
|
623
|
+
columnRefs={columnRefs.current}
|
|
556
624
|
elements={[
|
|
557
625
|
{ value: 'am', label: 'AM' },
|
|
558
626
|
{ value: 'pm', label: 'PM' },
|
|
559
627
|
]}
|
|
560
|
-
onClick={(value: string) => handleTimeChange('
|
|
628
|
+
onClick={(value: string) => handleTimeChange('meridiem', value)}
|
|
561
629
|
selected={_ampm}
|
|
630
|
+
ref={(node: HTMLDivElement | null) => {
|
|
631
|
+
columnRefs.current[(minutes ? 1 : 0) + (seconds ? 1 : 0) + 1] = node
|
|
632
|
+
}}
|
|
562
633
|
/>
|
|
563
634
|
)}
|
|
564
635
|
</>
|
|
@@ -1,8 +1,9 @@
|
|
|
1
|
-
import React, { forwardRef, useEffect, useRef } from 'react'
|
|
1
|
+
import React, { forwardRef, useCallback, useEffect, useRef } from 'react'
|
|
2
2
|
import PropTypes from 'prop-types'
|
|
3
3
|
import classNames from 'classnames'
|
|
4
4
|
|
|
5
5
|
import { useForkedRef, useIsVisible } from '../../hooks'
|
|
6
|
+
import { getNextActiveElement, isRTL } from '../../utils'
|
|
6
7
|
|
|
7
8
|
export interface Element {
|
|
8
9
|
value: number | string
|
|
@@ -10,52 +11,134 @@ export interface Element {
|
|
|
10
11
|
}
|
|
11
12
|
|
|
12
13
|
export interface CTimePickerRollColProps {
|
|
14
|
+
ariaLabel?: string
|
|
15
|
+
columnIndex: number
|
|
16
|
+
columnRefs: (HTMLDivElement | null)[]
|
|
13
17
|
elements: Element[]
|
|
14
18
|
onClick?: (value: number | string) => void
|
|
15
19
|
selected?: number | string | null
|
|
16
20
|
}
|
|
17
21
|
|
|
18
22
|
export const CTimePickerRollCol = forwardRef<HTMLDivElement, CTimePickerRollColProps>(
|
|
19
|
-
({ elements, onClick, selected }, ref) => {
|
|
20
|
-
const init = useRef(true)
|
|
23
|
+
({ ariaLabel, columnIndex, columnRefs, elements, onClick, selected }, ref) => {
|
|
21
24
|
const colRef = useRef<HTMLDivElement>(null)
|
|
25
|
+
const firstRender = useRef(true)
|
|
22
26
|
const forkedRef = useForkedRef(ref, colRef)
|
|
23
27
|
const isVisible = useIsVisible(colRef)
|
|
24
28
|
|
|
25
29
|
useEffect(() => {
|
|
30
|
+
if (isVisible) {
|
|
31
|
+
setRoll(firstRender.current ? 'instant' : 'smooth')
|
|
32
|
+
|
|
33
|
+
firstRender.current = false
|
|
34
|
+
}
|
|
35
|
+
}, [isVisible, selected])
|
|
36
|
+
|
|
37
|
+
const moveFocusToNextColumn = useCallback(() => {
|
|
38
|
+
const columns = columnRefs
|
|
39
|
+
if (columns?.length === 0) {
|
|
40
|
+
return
|
|
41
|
+
}
|
|
42
|
+
|
|
43
|
+
if (columnIndex < columns.length - 1) {
|
|
44
|
+
const column = columns[columnIndex + 1]
|
|
45
|
+
;(column?.querySelector('.time-picker-roll-cell[tabindex="0"') as HTMLElement).focus()
|
|
46
|
+
}
|
|
47
|
+
}, [columnIndex, columnRefs])
|
|
48
|
+
|
|
49
|
+
const moveFocusToPreviousColumn = useCallback(() => {
|
|
50
|
+
const columns = columnRefs
|
|
51
|
+
if (columns?.length === 0) {
|
|
52
|
+
return
|
|
53
|
+
}
|
|
54
|
+
|
|
55
|
+
if (columnIndex > 0) {
|
|
56
|
+
const column = columns[columnIndex - 1]
|
|
57
|
+
;(column?.querySelector('.time-picker-roll-cell[tabindex="0"') as HTMLElement).focus()
|
|
58
|
+
}
|
|
59
|
+
}, [columnIndex, columnRefs])
|
|
60
|
+
|
|
61
|
+
const setRoll = useCallback((behavior: 'instant' | 'smooth') => {
|
|
26
62
|
const nodeEl = colRef.current?.querySelector('.selected')
|
|
27
|
-
if (
|
|
63
|
+
if (nodeEl && nodeEl instanceof HTMLElement) {
|
|
28
64
|
colRef.current?.scrollTo({
|
|
29
65
|
top: nodeEl.offsetTop,
|
|
30
|
-
behavior:
|
|
66
|
+
behavior: behavior,
|
|
31
67
|
})
|
|
32
68
|
}
|
|
69
|
+
}, [])
|
|
33
70
|
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
71
|
+
const handleKeyDown = useCallback(
|
|
72
|
+
(event: React.KeyboardEvent<HTMLDivElement>, value: number | string) => {
|
|
73
|
+
if (event.code === 'Space' || event.key === 'Enter') {
|
|
74
|
+
event.preventDefault()
|
|
75
|
+
onClick?.(value)
|
|
76
|
+
moveFocusToNextColumn()
|
|
77
|
+
return
|
|
78
|
+
}
|
|
38
79
|
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
80
|
+
if (colRef.current && (event.key === 'ArrowDown' || event.key === 'ArrowUp')) {
|
|
81
|
+
event.preventDefault()
|
|
82
|
+
const target = event.target as HTMLElement
|
|
83
|
+
const items = [
|
|
84
|
+
...colRef.current.querySelectorAll('.time-picker-roll-cell'),
|
|
85
|
+
] as HTMLElement[]
|
|
86
|
+
|
|
87
|
+
getNextActiveElement(items, target, event.key === 'ArrowDown', true).focus()
|
|
88
|
+
return
|
|
89
|
+
}
|
|
90
|
+
|
|
91
|
+
if (colRef.current && (event.key === 'Home' || event.key === 'End')) {
|
|
92
|
+
event.preventDefault()
|
|
93
|
+
const items = [
|
|
94
|
+
...colRef.current.querySelectorAll('.time-picker-roll-cell'),
|
|
95
|
+
] as HTMLElement[]
|
|
96
|
+
const index = event.key === 'Home' ? 0 : items.length - 1
|
|
97
|
+
items[index].focus()
|
|
98
|
+
return
|
|
99
|
+
}
|
|
100
|
+
|
|
101
|
+
if (colRef.current && (event.key === 'ArrowLeft' || event.key === 'ArrowRight')) {
|
|
102
|
+
event.preventDefault()
|
|
103
|
+
const rtl = isRTL(colRef.current)
|
|
104
|
+
const shouldGoLeft =
|
|
105
|
+
(event.key === 'ArrowLeft' && !rtl) || (event.key === 'ArrowRight' && rtl)
|
|
106
|
+
if (shouldGoLeft) {
|
|
107
|
+
moveFocusToPreviousColumn()
|
|
108
|
+
} else {
|
|
109
|
+
moveFocusToNextColumn()
|
|
110
|
+
}
|
|
111
|
+
}
|
|
112
|
+
},
|
|
113
|
+
[onClick, moveFocusToNextColumn, moveFocusToPreviousColumn]
|
|
114
|
+
)
|
|
45
115
|
|
|
46
116
|
return (
|
|
47
|
-
<div
|
|
117
|
+
<div
|
|
118
|
+
className="time-picker-roll-col"
|
|
119
|
+
onBlur={(event) => {
|
|
120
|
+
if (!event.currentTarget.contains(event.relatedTarget)) {
|
|
121
|
+
setRoll('smooth')
|
|
122
|
+
}
|
|
123
|
+
}}
|
|
124
|
+
role="listbox"
|
|
125
|
+
aria-label={ariaLabel}
|
|
126
|
+
ref={forkedRef}
|
|
127
|
+
>
|
|
48
128
|
{elements.map((element, index) => {
|
|
129
|
+
const isSelected = element.value === selected
|
|
49
130
|
return (
|
|
50
131
|
<div
|
|
51
132
|
className={classNames('time-picker-roll-cell', {
|
|
52
|
-
selected:
|
|
133
|
+
selected: isSelected,
|
|
53
134
|
})}
|
|
54
135
|
key={index}
|
|
55
136
|
onClick={() => onClick?.(element.value)}
|
|
56
137
|
onKeyDown={(event) => handleKeyDown(event, element.value)}
|
|
57
|
-
role="
|
|
58
|
-
tabIndex={0}
|
|
138
|
+
role="option"
|
|
139
|
+
tabIndex={isSelected ? 0 : selected ? -1 : index === 0 ? 0 : -1}
|
|
140
|
+
aria-label={element.label.toString()}
|
|
141
|
+
aria-selected={isSelected}
|
|
59
142
|
>
|
|
60
143
|
{element.label}
|
|
61
144
|
</div>
|
|
@@ -63,7 +146,7 @@ export const CTimePickerRollCol = forwardRef<HTMLDivElement, CTimePickerRollColP
|
|
|
63
146
|
})}
|
|
64
147
|
</div>
|
|
65
148
|
)
|
|
66
|
-
}
|
|
149
|
+
}
|
|
67
150
|
)
|
|
68
151
|
|
|
69
152
|
CTimePickerRollCol.propTypes = {
|