UNPKG

@coreui/vue-pro

Version:

UI Components Library for Vue.js

138 lines (134 loc) 5.49 kB
'use strict'; var vue = require('vue'); require('@popperjs/core'); var getNextActiveElement = require('../../utils/getNextActiveElement.js'); var isRTL = require('../../utils/isRTL.js'); var useIsVisible = require('../../composables/useIsVisible.js'); const CTimePickerRollCol = vue.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 = vue.ref(true); const colRef = vue.ref(); const isVisible = useIsVisible.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', }); } }; vue.watch(isVisible, () => { scrollToSelectedElement(); if (isVisible.value) { init.value = false; } }); vue.watch(colRef, () => { if (props.columnIndex !== undefined && props.setColumnRef) { props.setColumnRef(props.columnIndex, colRef.value || null); } }, { immediate: true }); vue.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.default(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.default(colRef.value); const shouldGoLeft = (event.key === 'ArrowLeft' && !rtl) || (event.key === 'ArrowRight' && rtl); if (shouldGoLeft) { moveFocusToPreviousColumn(); } else { moveFocusToNextColumn(); } } }; return () => vue.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 vue.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); })); }, }); exports.CTimePickerRollCol = CTimePickerRollCol; //# sourceMappingURL=CTimePickerRollCol.js.map