UNPKG

primevue

Version:

[![License: MIT](https://img.shields.io/badge/License-MIT-yellow.svg)](https://opensource.org/licenses/MIT) [![npm version](https://badge.fury.io/js/primevue.svg)](https://badge.fury.io/js/primevue)

328 lines (295 loc) 11.5 kB
import { ObjectUtils, DomHandler } from 'primevue/utils'; import Ripple from 'primevue/ripple'; import { resolveDirective, openBlock, createBlock, createVNode, withDirectives, vModelText, createCommentVNode, Fragment, renderList, renderSlot, createTextVNode, toDisplayString } from 'vue'; var script = { emits: ['update:modelValue', 'change', 'filter'], props: { modelValue: null, options: Array, optionLabel: null, optionValue: null, optionDisabled: null, listStyle: null, disabled: Boolean, dataKey: null, multiple: Boolean, metaKeySelection: Boolean, filter: Boolean, filterPlaceholder: String, filterLocale: String, emptyFilterMessage: { type: String, default: 'No results found' } }, optionTouched: false, data() { return { filterValue: null }; }, methods: { getOptionLabel(option) { return this.optionLabel ? ObjectUtils.resolveFieldData(option, this.optionLabel) : option; }, getOptionValue(option) { return this.optionValue ? ObjectUtils.resolveFieldData(option, this.optionValue) : option; }, getOptionRenderKey(option) { return this.dataKey ? ObjectUtils.resolveFieldData(option, this.dataKey) : this.getOptionLabel(option); }, isOptionDisabled(option) { return this.optionDisabled ? ObjectUtils.resolveFieldData(option, this.optionDisabled) : false; }, onOptionSelect(event, option) { if (this.disabled || this.isOptionDisabled(option)) { return; } if(this.multiple) this.onOptionSelectMultiple(event, option); else this.onOptionSelectSingle(event, option); this.optionTouched = false; }, onOptionTouchEnd() { if (this.disabled) { return; } this.optionTouched = true; }, onOptionSelectSingle(event, option) { let selected = this.isSelected(option); let valueChanged = false; let value = null; let metaSelection = this.optionTouched ? false : this.metaKeySelection; if (metaSelection) { let metaKey = (event.metaKey || event.ctrlKey); if (selected) { if (metaKey) { value = null; valueChanged = true; } } else { value = this.getOptionValue(option); valueChanged = true; } } else { value = selected ? null : this.getOptionValue(option); valueChanged = true; } if (valueChanged) { this.updateModel(event, value); } }, onOptionSelectMultiple(event, option) { let selected = this.isSelected(option); let valueChanged = false; let value = null; let metaSelection = this.optionTouched ? false : this.metaKeySelection; if (metaSelection) { let metaKey = (event.metaKey || event.ctrlKey); if (selected) { if(metaKey) value = this.removeOption(option); else value = [this.getOptionValue(option)]; valueChanged = true; } else { value = (metaKey) ? this.modelValue || [] : []; value = [...value, this.getOptionValue(option)]; valueChanged = true; } } else { if (selected) value = this.removeOption(option); else value = [...this.modelValue || [], this.getOptionValue(option)]; valueChanged = true; } if(valueChanged) { this.updateModel(event, value); } }, isSelected(option) { let selected = false; let optionValue = this.getOptionValue(option); if (this.multiple) { if (this.modelValue) { for (let val of this.modelValue) { if (ObjectUtils.equals(val, optionValue, this.equalityKey)) { selected = true; break; } } } } else { selected = ObjectUtils.equals(this.modelValue, optionValue, this.equalityKey); } return selected; }, removeOption(option) { return this.modelValue.filter(val => !ObjectUtils.equals(val, this.getOptionValue(option), this.equalityKey)); }, updateModel(event, value) { this.$emit('update:modelValue', value); this.$emit('change', {originalEvent: event, value: value}); }, onOptionKeyDown(event, option) { let item = event.currentTarget; switch (event.which) { //down case 40: var nextItem = this.findNextItem(item); if(nextItem) { nextItem.focus(); } event.preventDefault(); break; //up case 38: var prevItem = this.findPrevItem(item); if(prevItem) { prevItem.focus(); } event.preventDefault(); break; //enter case 13: this.onOptionSelect(event, option); event.preventDefault(); break; } }, findNextItem(item) { let nextItem = item.nextElementSibling; if (nextItem) return DomHandler.hasClass(nextItem, 'p-disabled') ? this.findNextOption(nextItem) : nextItem; else return null; }, findPrevItem(item) { let prevItem = item.previousElementSibling; if (prevItem) return DomHandler.hasClass(prevItem, 'p-disabled') ? this.findPrevItem(prevItem) : prevItem; else return null; }, onFilterChange(event) { this.$emit('filter', {originalEvent: event, value: event.target.value}); } }, computed: { visibleOptions() { if (this.filterValue) return this.options.filter(option => this.getOptionLabel(option).toLocaleLowerCase(this.filterLocale).indexOf(this.filterValue.toLocaleLowerCase(this.filterLocale)) > -1); else return this.options; }, equalityKey() { return this.optionValue ? null : this.dataKey; } }, directives: { 'ripple': Ripple } }; const _hoisted_1 = { class: "p-listbox p-component" }; const _hoisted_2 = { key: 0, class: "p-listbox-header" }; const _hoisted_3 = { class: "p-listbox-filter-container" }; const _hoisted_4 = /*#__PURE__*/createVNode("span", { class: "p-listbox-filter-icon pi pi-search" }, null, -1); const _hoisted_5 = { class: "p-listbox-list", role: "listbox", "aria-multiselectable": "multiple" }; const _hoisted_6 = { key: 0, class: "p-listbox-empty-message" }; function render(_ctx, _cache, $props, $setup, $data, $options) { const _directive_ripple = resolveDirective("ripple"); return (openBlock(), createBlock("div", _hoisted_1, [ ($props.filter) ? (openBlock(), createBlock("div", _hoisted_2, [ createVNode("div", _hoisted_3, [ withDirectives(createVNode("input", { type: "text", class: "p-listbox-filter p-inputtext p-component", "onUpdate:modelValue": _cache[1] || (_cache[1] = $event => ($data.filterValue = $event)), placeholder: $props.filterPlaceholder, onInput: _cache[2] || (_cache[2] = (...args) => ($options.onFilterChange && $options.onFilterChange(...args))) }, null, 40, ["placeholder"]), [ [vModelText, $data.filterValue] ]), _hoisted_4 ]) ])) : createCommentVNode("", true), createVNode("div", { class: "p-listbox-list-wrapper", style: $props.listStyle }, [ createVNode("ul", _hoisted_5, [ (openBlock(true), createBlock(Fragment, null, renderList($options.visibleOptions, (option, i) => { return withDirectives((openBlock(), createBlock("li", { tabindex: $options.isOptionDisabled(option) ? null : '0', class: ['p-listbox-item', {'p-highlight': $options.isSelected(option), 'p-disabled': $options.isOptionDisabled(option)}], "aria-label": $options.getOptionLabel(option), key: $options.getOptionRenderKey(option), onClick: $event => ($options.onOptionSelect($event, option)), onTouchend: _cache[3] || (_cache[3] = $event => ($options.onOptionTouchEnd())), onKeydown: $event => ($options.onOptionKeyDown($event, option)), role: "option", "aria-selected": $options.isSelected(option) }, [ renderSlot(_ctx.$slots, "option", { option: option, index: i }, () => [ createTextVNode(toDisplayString($options.getOptionLabel(option)), 1) ]) ], 42, ["tabindex", "aria-label", "onClick", "onKeydown", "aria-selected"])), [ [_directive_ripple] ]) }), 128)), ($data.filterValue && (!$options.visibleOptions || ($options.visibleOptions && $options.visibleOptions.length === 0))) ? (openBlock(), createBlock("li", _hoisted_6, toDisplayString($props.emptyFilterMessage), 1)) : createCommentVNode("", true) ]) ], 4) ])) } function styleInject(css, ref) { if ( ref === void 0 ) ref = {}; var insertAt = ref.insertAt; if (!css || typeof document === 'undefined') { return; } var head = document.head || document.getElementsByTagName('head')[0]; var style = document.createElement('style'); style.type = 'text/css'; if (insertAt === 'top') { if (head.firstChild) { head.insertBefore(style, head.firstChild); } else { head.appendChild(style); } } else { head.appendChild(style); } if (style.styleSheet) { style.styleSheet.cssText = css; } else { style.appendChild(document.createTextNode(css)); } } var css_248z = "\n.p-listbox-list-wrapper {\n overflow: auto;\n}\n.p-listbox-list {\n list-style-type: none;\n margin: 0;\n padding: 0;\n}\n.p-listbox-item {\n cursor: pointer;\n position: relative;\n overflow: hidden;\n}\n.p-listbox-filter-container {\n position: relative;\n}\n.p-listbox-filter-icon {\n position: absolute;\n top: 50%;\n margin-top: -.5rem;\n}\n.p-listbox-filter {\n width: 100%;\n}\n"; styleInject(css_248z); script.render = render; export default script;