@coreui/vue-pro
Version:
UI Components Library for Vue.js
136 lines (133 loc) • 5.43 kB
JavaScript
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