UNPKG

@coreui/vue-pro

Version:

UI Components Library for Vue.js

115 lines (112 loc) 4.78 kB
import { defineComponent, h } from 'vue'; import { CElementCover } from '../element-cover/CElementCover.js'; import { CVirtualScroller } from '../virtual-scroller/CVirtualScroller.js'; import { getNextSibling } from '../../utils/getNextSibling.js'; import getPreviousSibling from '../../utils/getPreviousSibling.js'; import { highlightSubstring, isOptionSelected, isOptionDisabled, getOptionLabel } from './utils.js'; const CAutocompleteOptions = defineComponent({ name: 'CAutocompleteOptions', props: { highlightOptionsOnSearch: Boolean, loading: Boolean, options: { type: Array, required: true, }, optionsMaxHeight: [Number, String], scopedSlots: Object, searchNoResultsLabel: [Boolean, String], searchValue: String, selected: [Object, String, null], virtualScroller: Boolean, visible: Boolean, visibleItems: { type: Number, default: 10, }, }, emits: ['optionClick'], setup(props, { emit }) { const handleKeyDown = (event, option) => { if (event.code === 'Space' || event.key === 'Enter') { event.preventDefault(); emit('optionClick', option); } if (event.key === 'Down' || event.key === 'ArrowDown') { event.preventDefault(); const target = event.target; const next = getNextSibling(target, '.autocomplete-option:not(.disabled):not(:disabled)'); if (next) { next.focus(); } } if (event.key === 'Up' || event.key === 'ArrowUp') { event.preventDefault(); const target = event.target; const prev = getPreviousSibling(target, '.autocomplete-option:not(.disabled):not(:disabled)'); if (prev) { prev.focus(); } } }; const createOption = (option, index) => h('div', { class: [ 'autocomplete-option', { disabled: isOptionDisabled(option), selected: isOptionSelected(option, props.selected || null), }, ], key: index, onClick: () => emit('optionClick', option), onKeydown: (event) => handleKeyDown(event, option), tabindex: 0, ...(props.highlightOptionsOnSearch && !props.scopedSlots?.['options'] && { innerHTML: highlightSubstring(getOptionLabel(option), props.searchValue), }), }, !props.highlightOptionsOnSearch ? props.scopedSlots && props.scopedSlots['options'] ? h(props.scopedSlots['options'], { option: option }) : getOptionLabel(option) : undefined); const createOptions = (options) => { if (options.length === 0 && props.searchNoResultsLabel) { return h('div', { class: 'autocomplete-options-empty' }, props.searchNoResultsLabel); } return options.map((option, index) => { if (typeof option !== 'string' && 'options' in option) { return h('div', { key: index }, [ h('div', { class: 'autocomplete-optgroup-label' }, [ props.scopedSlots && props.scopedSlots['options-groups'] ? h(props.scopedSlots['options-groups'], { option: option }) : option.label, ]), ...(option.options?.map((opt, idx) => createOption(opt, idx)) || []), ]); } return createOption(option, index); }); }; return () => [ props.visible && props.virtualScroller && props.options.length > 0 ? h(CVirtualScroller, { class: 'autocomplete-options', visibleItems: props.visibleItems, role: 'listbox', }, { default: () => createOptions(props.options), }) : h('div', { class: 'autocomplete-options', ...(props.optionsMaxHeight !== 'auto' && { style: { maxHeight: props.optionsMaxHeight, overflow: 'scroll' }, }), role: 'listbox', }, createOptions(props.options)), props.loading && h(CElementCover), ]; }, }); export { CAutocompleteOptions }; //# sourceMappingURL=CAutocompleteOptions.js.map