UNPKG

@coreui/vue-pro

Version:

UI Components Library for Vue.js

136 lines (133 loc) 5.43 kB
import { defineComponent, ref, watch, onUpdated, h } from 'vue'; import '@popperjs/core'; import getNextActiveElement from '../../utils/getNextActiveElement.js'; import isRTL from '../../utils/isRTL.js'; import { useIsVisible } from '../../composables/useIsVisible.js'; const CTimePickerRollCol = defineComponent({ name: 'CTimePickerRollCol', props: { ariaLabel: String, columnIndex: Number, columnRefs: { type: Array, default: () => [], }, elements: { type: Array, required: true, }, selected: [Number, String, null], setColumnRef: Function, }, emits: ['click'], setup(props, { emit }) { const init = ref(true); const colRef = ref(); const isVisible = useIsVisible(colRef); const scrollToSelectedElement = () => { const nodeEl = colRef.value?.querySelector('.selected'); if (isVisible.value && nodeEl && nodeEl instanceof HTMLElement) { colRef.value?.scrollTo({ top: nodeEl.offsetTop, behavior: init.value ? 'instant' : 'smooth', }); } }; watch(isVisible, () => { scrollToSelectedElement(); if (isVisible.value) { init.value = false; } }); watch(colRef, () => { if (props.columnIndex !== undefined && props.setColumnRef) { props.setColumnRef(props.columnIndex, colRef.value || null); } }, { immediate: true }); onUpdated(() => { scrollToSelectedElement(); }); const moveFocusToNextColumn = () => { if (!props.columnRefs || props.columnIndex === undefined) return; if (props.columnIndex < props.columnRefs.length - 1) { const column = props.columnRefs[props.columnIndex + 1]; const focusableCell = column?.querySelector('.time-picker-roll-cell[tabindex="0"]'); focusableCell?.focus(); } }; const moveFocusToPreviousColumn = () => { if (!props.columnRefs || props.columnIndex === undefined) return; if (props.columnIndex > 0) { const column = props.columnRefs[props.columnIndex - 1]; const focusableCell = column?.querySelector('.time-picker-roll-cell[tabindex="0"]'); focusableCell?.focus(); } }; const handleKeyDown = (event, value) => { if (event.code === 'Space' || event.key === 'Enter') { event.preventDefault(); emit('click', value); moveFocusToNextColumn(); return; } if (colRef.value && (event.key === 'ArrowDown' || event.key === 'ArrowUp')) { event.preventDefault(); const target = event.target; const items = [...colRef.value.querySelectorAll('.time-picker-roll-cell')]; getNextActiveElement(items, target, event.key === 'ArrowDown', true).focus(); return; } if (colRef.value && (event.key === 'Home' || event.key === 'End')) { event.preventDefault(); const items = [...colRef.value.querySelectorAll('.time-picker-roll-cell')]; const index = event.key === 'Home' ? 0 : items.length - 1; items[index]?.focus(); return; } if (colRef.value && (event.key === 'ArrowLeft' || event.key === 'ArrowRight')) { event.preventDefault(); const rtl = isRTL(colRef.value); const shouldGoLeft = (event.key === 'ArrowLeft' && !rtl) || (event.key === 'ArrowRight' && rtl); if (shouldGoLeft) { moveFocusToPreviousColumn(); } else { moveFocusToNextColumn(); } } }; return () => h('div', { class: 'time-picker-roll-col', onFocusout: (event) => { const currentTarget = event.currentTarget; const relatedTarget = event.relatedTarget; if (currentTarget && (!relatedTarget || !currentTarget.contains(relatedTarget))) { scrollToSelectedElement(); } }, ref: colRef, role: 'listbox', 'aria-label': props.ariaLabel, }, props.elements.map((element, index) => { const isSelected = element.value === props.selected; return h('div', { class: [ 'time-picker-roll-cell', { selected: isSelected, }, ], onClick: () => emit('click', element.value), onKeydown: (event) => handleKeyDown(event, element.value), role: 'option', tabindex: isSelected ? 0 : props.selected ? -1 : index === 0 ? 0 : -1, 'aria-label': element.label.toString(), 'aria-selected': isSelected, }, element.label); })); }, }); export { CTimePickerRollCol }; //# sourceMappingURL=CTimePickerRollCol.js.map