UNPKG

primevue

Version:

PrimeVue is an open source UI library for Vue featuring a rich set of 80+ components, a theme designer, various theme alternatives such as Material, Bootstrap, Tailwind, premium templates and professional support. In addition, it integrates with PrimeBloc

1 lines 71.8 kB
{"version":3,"file":"index.mjs","sources":["../../src/treeselect/BaseTreeSelect.vue","../../src/treeselect/TreeSelect.vue","../../src/treeselect/TreeSelect.vue?vue&type=template&id=1632c8a0&lang.js"],"sourcesContent":["<script>\nimport BaseComponent from '@primevue/core/basecomponent';\nimport TreeSelectStyle from 'primevue/treeselect/style';\n\nexport default {\n name: 'BaseTreeSelect',\n extends: BaseComponent,\n props: {\n modelValue: null,\n options: Array,\n scrollHeight: {\n type: String,\n default: '20rem'\n },\n placeholder: {\n type: String,\n default: null\n },\n invalid: {\n type: Boolean,\n default: false\n },\n variant: {\n type: String,\n default: null\n },\n disabled: {\n type: Boolean,\n default: false\n },\n tabindex: {\n type: Number,\n default: null\n },\n selectionMode: {\n type: String,\n default: 'single'\n },\n appendTo: {\n type: [String, Object],\n default: 'body'\n },\n emptyMessage: {\n type: String,\n default: null\n },\n display: {\n type: String,\n default: 'comma'\n },\n metaKeySelection: {\n type: Boolean,\n default: false\n },\n fluid: {\n type: Boolean,\n default: null\n },\n inputId: {\n type: String,\n default: null\n },\n inputClass: {\n type: [String, Object],\n default: null\n },\n inputStyle: {\n type: Object,\n default: null\n },\n inputProps: {\n type: null,\n default: null\n },\n panelClass: {\n type: [String, Object],\n default: null\n },\n panelProps: {\n type: null,\n default: null\n },\n ariaLabelledby: {\n type: String,\n default: null\n },\n ariaLabel: {\n type: String,\n default: null\n }\n },\n style: TreeSelectStyle,\n provide() {\n return {\n $pcTreeSelect: this,\n $parentInstance: this\n };\n }\n};\n</script>\n","<template>\n <div ref=\"container\" :class=\"cx('root')\" :style=\"sx('root')\" @click=\"onClick\" v-bind=\"ptmi('root')\">\n <div class=\"p-hidden-accessible\" v-bind=\"ptm('hiddenInputContainer')\" :data-p-hidden-accessible=\"true\">\n <input\n ref=\"focusInput\"\n :id=\"inputId\"\n type=\"text\"\n role=\"combobox\"\n :class=\"inputClass\"\n :style=\"inputStyle\"\n readonly\n :disabled=\"disabled\"\n :tabindex=\"!disabled ? tabindex : -1\"\n :aria-labelledby=\"ariaLabelledby\"\n :aria-label=\"ariaLabel\"\n aria-haspopup=\"tree\"\n :aria-expanded=\"overlayVisible\"\n :aria-controls=\"listId\"\n @focus=\"onFocus($event)\"\n @blur=\"onBlur($event)\"\n @keydown=\"onKeyDown($event)\"\n v-bind=\"{ ...inputProps, ...ptm('hiddenInput') }\"\n />\n </div>\n <div :class=\"cx('labelContainer')\" v-bind=\"ptm('labelContainer')\">\n <div :class=\"cx('label')\" v-bind=\"ptm('label')\">\n <slot name=\"value\" :value=\"selectedNodes\" :placeholder=\"placeholder\">\n <template v-if=\"display === 'comma'\">\n {{ label || 'empty' }}\n </template>\n <template v-else-if=\"display === 'chip'\">\n <div v-for=\"node of selectedNodes\" :key=\"node.key\" :class=\"cx('chipItem')\" v-bind=\"ptm('chipItem')\">\n <Chip :class=\"cx('pcChip')\" :label=\"node.label\" :unstyled=\"unstyled\" :pt=\"ptm('pcChip')\" />\n </div>\n <template v-if=\"emptyValue\">{{ placeholder || 'empty' }}</template>\n </template>\n </slot>\n </div>\n </div>\n <div :class=\"cx('dropdown')\" role=\"button\" aria-haspopup=\"tree\" :aria-expanded=\"overlayVisible\" v-bind=\"ptm('dropdown')\">\n <!-- TODO: triggericon is deprecated since v4.0 -->\n <slot :name=\"$slots.dropdownicon ? 'dropdownicon' : 'triggericon'\" :class=\"cx('dropdownIcon')\">\n <component :is=\"'ChevronDownIcon'\" :class=\"cx('dropdownIcon')\" v-bind=\"ptm('dropdownIcon')\" />\n </slot>\n </div>\n <Portal :appendTo=\"appendTo\">\n <transition name=\"p-connected-overlay\" @enter=\"onOverlayEnter\" @after-enter=\"onOverlayAfterEnter\" @leave=\"onOverlayLeave\" @after-leave=\"onOverlayAfterLeave\" v-bind=\"ptm('transition')\">\n <div v-if=\"overlayVisible\" :ref=\"overlayRef\" @click=\"onOverlayClick\" :class=\"[cx('panel'), panelClass]\" @keydown=\"onOverlayKeydown\" v-bind=\"{ ...panelProps, ...ptm('panel') }\">\n <span\n ref=\"firstHiddenFocusableElementOnOverlay\"\n role=\"presentation\"\n aria-hidden=\"true\"\n class=\"p-hidden-accessible p-hidden-focusable\"\n :tabindex=\"0\"\n @focus=\"onFirstHiddenFocus\"\n v-bind=\"ptm('hiddenFirstFocusableEl')\"\n :data-p-hidden-accessible=\"true\"\n :data-p-hidden-focusable=\"true\"\n ></span>\n <slot name=\"header\" :value=\"modelValue\" :options=\"options\"></slot>\n <div :class=\"cx('treeContainer')\" :style=\"{ 'max-height': scrollHeight }\" v-bind=\"ptm('treeContainer')\">\n <TSTree\n ref=\"tree\"\n :id=\"listId\"\n :value=\"options\"\n :selectionMode=\"selectionMode\"\n @update:selectionKeys=\"onSelectionChange\"\n :selectionKeys=\"modelValue\"\n :expandedKeys=\"expandedKeys\"\n @update:expandedKeys=\"onNodeToggle\"\n :metaKeySelection=\"metaKeySelection\"\n @node-expand=\"$emit('node-expand', $event)\"\n @node-collapse=\"$emit('node-collapse', $event)\"\n @node-select=\"onNodeSelect\"\n @node-unselect=\"onNodeUnselect\"\n :level=\"0\"\n :unstyled=\"unstyled\"\n :pt=\"ptm('pcTree')\"\n >\n <template v-if=\"$slots.itemtoggleicon\" #toggleicon=\"iconProps\">\n <slot name=\"itemtoggleicon\" :node=\"iconProps.node\" :expanded=\"iconProps.expanded\" :class=\"iconProps.class\" />\n </template>\n <!--TODO: itemtogglericon deprecated since v4.0-->\n <template v-else-if=\"$slots.itemtogglericon\" #togglericon=\"iconProps\">\n <slot name=\"itemtogglericon\" :node=\"iconProps.node\" :expanded=\"iconProps.expanded\" :class=\"iconProps.class\" />\n </template>\n <template v-if=\"$slots.itemcheckboxicon\" #checkboxicon=\"iconProps\">\n <slot name=\"itemcheckboxicon\" :checked=\"iconProps.checked\" :partialChecked=\"iconProps.partialChecked\" :class=\"iconProps.class\" />\n </template>\n </TSTree>\n <div v-if=\"emptyOptions\" :class=\"cx('emptyMessage')\" v-bind=\"ptm('emptyMessage')\">\n <slot name=\"empty\">{{ emptyMessageText }}</slot>\n </div>\n </div>\n <slot name=\"footer\" :value=\"modelValue\" :options=\"options\"></slot>\n <span\n ref=\"lastHiddenFocusableElementOnOverlay\"\n role=\"presentation\"\n aria-hidden=\"true\"\n class=\"p-hidden-accessible p-hidden-focusable\"\n :tabindex=\"0\"\n @focus=\"onLastHiddenFocus\"\n v-bind=\"ptm('hiddenLastFocusableEl')\"\n :data-p-hidden-accessible=\"true\"\n :data-p-hidden-focusable=\"true\"\n ></span>\n </div>\n </transition>\n </Portal>\n </div>\n</template>\n\n<script>\nimport { absolutePosition, addStyle, find, findSingle, focus, getFirstFocusableElement, getFocusableElements, getLastFocusableElement, getOuterWidth, isTouchDevice, relativePosition } from '@primeuix/utils/dom';\nimport { isEmpty } from '@primeuix/utils/object';\nimport { ZIndex } from '@primeuix/utils/zindex';\nimport { ConnectedOverlayScrollHandler, UniqueComponentId } from '@primevue/core/utils';\nimport ChevronDownIcon from '@primevue/icons/chevrondown';\nimport Chip from 'primevue/chip';\nimport OverlayEventBus from 'primevue/overlayeventbus';\nimport Portal from 'primevue/portal';\nimport Ripple from 'primevue/ripple';\nimport Tree from 'primevue/tree';\nimport BaseTreeSelect from './BaseTreeSelect.vue';\n\nexport default {\n name: 'TreeSelect',\n extends: BaseTreeSelect,\n inheritAttrs: false,\n emits: ['update:modelValue', 'before-show', 'before-hide', 'change', 'show', 'hide', 'node-select', 'node-unselect', 'node-expand', 'node-collapse', 'focus', 'blur'],\n inject: {\n $pcFluid: { default: null }\n },\n data() {\n return {\n id: this.$attrs.id,\n focused: false,\n overlayVisible: false,\n expandedKeys: {}\n };\n },\n watch: {\n '$attrs.id': function (newValue) {\n this.id = newValue || UniqueComponentId();\n },\n modelValue: {\n handler: function () {\n if (!this.selfChange) {\n this.updateTreeState();\n }\n\n this.selfChange = false;\n },\n immediate: true\n },\n options() {\n this.updateTreeState();\n }\n },\n outsideClickListener: null,\n resizeListener: null,\n scrollHandler: null,\n overlay: null,\n selfChange: false,\n selfClick: false,\n beforeUnmount() {\n this.unbindOutsideClickListener();\n this.unbindResizeListener();\n\n if (this.scrollHandler) {\n this.scrollHandler.destroy();\n this.scrollHandler = null;\n }\n\n if (this.overlay) {\n ZIndex.clear(this.overlay);\n this.overlay = null;\n }\n },\n mounted() {\n this.id = this.id || UniqueComponentId();\n this.updateTreeState();\n },\n methods: {\n show() {\n this.$emit('before-show');\n this.overlayVisible = true;\n },\n hide() {\n this.$emit('before-hide');\n this.overlayVisible = false;\n this.$refs.focusInput.focus();\n },\n onFocus(event) {\n this.focused = true;\n this.$emit('focus', event);\n },\n onBlur(event) {\n this.focused = false;\n this.$emit('blur', event);\n },\n onClick(event) {\n if (this.disabled) {\n return;\n }\n\n if (!this.disabled && (!this.overlay || !this.overlay.contains(event.target))) {\n if (this.overlayVisible) this.hide();\n else this.show();\n\n focus(this.$refs.focusInput);\n }\n },\n onSelectionChange(keys) {\n this.selfChange = true;\n this.$emit('update:modelValue', keys);\n this.$emit('change', keys);\n },\n onNodeSelect(node) {\n this.$emit('node-select', node);\n\n if (this.selectionMode === 'single') {\n this.hide();\n }\n },\n onNodeUnselect(node) {\n this.$emit('node-unselect', node);\n },\n onNodeToggle(keys) {\n this.expandedKeys = keys;\n },\n onFirstHiddenFocus(event) {\n const focusableEl = event.relatedTarget === this.$refs.focusInput ? getFirstFocusableElement(this.overlay, ':not([data-p-hidden-focusable=\"true\"])') : this.$refs.focusInput;\n\n focus(focusableEl);\n },\n onLastHiddenFocus(event) {\n const focusableEl = event.relatedTarget === this.$refs.focusInput ? getLastFocusableElement(this.overlay, ':not([data-p-hidden-focusable=\"true\"])') : this.$refs.focusInput;\n\n focus(focusableEl);\n },\n onKeyDown(event) {\n switch (event.code) {\n case 'ArrowDown':\n this.onArrowDownKey(event);\n break;\n\n case 'Space':\n case 'Enter':\n case 'NumpadEnter':\n this.onEnterKey(event);\n break;\n\n case 'Escape':\n this.onEscapeKey(event);\n break;\n\n case 'Tab':\n this.onTabKey(event);\n break;\n\n default:\n break;\n }\n },\n onArrowDownKey(event) {\n if (this.overlayVisible) return;\n\n this.show();\n\n this.$nextTick(() => {\n const treeNodeEl = find(this.$refs.tree.$el, '[data-pc-section=\"treeitem\"]');\n const focusedElement = [...treeNodeEl].find((item) => item.getAttribute('tabindex') === '0');\n\n focus(focusedElement);\n });\n\n event.preventDefault();\n },\n onEnterKey(event) {\n if (this.overlayVisible) {\n this.hide();\n } else {\n this.onArrowDownKey(event);\n }\n\n event.preventDefault();\n },\n onEscapeKey(event) {\n if (this.overlayVisible) {\n this.hide();\n event.preventDefault();\n }\n },\n onTabKey(event, pressedInInputText = false) {\n if (!pressedInInputText) {\n if (this.overlayVisible && this.hasFocusableElements()) {\n focus(this.$refs.firstHiddenFocusableElementOnOverlay);\n\n event.preventDefault();\n }\n }\n },\n hasFocusableElements() {\n return getFocusableElements(this.overlay, ':not([data-p-hidden-focusable=\"true\"])').length > 0;\n },\n onOverlayEnter(el) {\n ZIndex.set('overlay', el, this.$primevue.config.zIndex.overlay);\n\n addStyle(el, { position: 'absolute', top: '0', left: '0' });\n this.alignOverlay();\n this.focus();\n },\n onOverlayAfterEnter() {\n this.bindOutsideClickListener();\n this.bindScrollListener();\n this.bindResizeListener();\n this.scrollValueInView();\n this.$emit('show');\n },\n onOverlayLeave() {\n this.unbindOutsideClickListener();\n this.unbindScrollListener();\n this.unbindResizeListener();\n this.$emit('hide');\n this.overlay = null;\n },\n onOverlayAfterLeave(el) {\n ZIndex.clear(el);\n },\n focus() {\n let focusableElements = getFocusableElements(this.overlay);\n\n if (focusableElements && focusableElements.length > 0) {\n focusableElements[0].focus();\n }\n },\n alignOverlay() {\n if (this.appendTo === 'self') {\n relativePosition(this.overlay, this.$el);\n } else {\n this.overlay.style.minWidth = getOuterWidth(this.$el) + 'px';\n absolutePosition(this.overlay, this.$el);\n }\n },\n bindOutsideClickListener() {\n if (!this.outsideClickListener) {\n this.outsideClickListener = (event) => {\n if (this.overlayVisible && !this.selfClick && this.isOutsideClicked(event)) {\n this.hide();\n }\n\n this.selfClick = false;\n };\n\n document.addEventListener('click', this.outsideClickListener);\n }\n },\n unbindOutsideClickListener() {\n if (this.outsideClickListener) {\n document.removeEventListener('click', this.outsideClickListener);\n this.outsideClickListener = null;\n }\n },\n bindScrollListener() {\n if (!this.scrollHandler) {\n this.scrollHandler = new ConnectedOverlayScrollHandler(this.$refs.container, () => {\n if (this.overlayVisible) {\n this.hide();\n }\n });\n }\n\n this.scrollHandler.bindScrollListener();\n },\n unbindScrollListener() {\n if (this.scrollHandler) {\n this.scrollHandler.unbindScrollListener();\n }\n },\n bindResizeListener() {\n if (!this.resizeListener) {\n this.resizeListener = () => {\n if (this.overlayVisible && !isTouchDevice()) {\n this.hide();\n }\n };\n\n window.addEventListener('resize', this.resizeListener);\n }\n },\n unbindResizeListener() {\n if (this.resizeListener) {\n window.removeEventListener('resize', this.resizeListener);\n this.resizeListener = null;\n }\n },\n isOutsideClicked(event) {\n return !(this.$el.isSameNode(event.target) || this.$el.contains(event.target) || (this.overlay && this.overlay.contains(event.target)));\n },\n overlayRef(el) {\n this.overlay = el;\n },\n onOverlayClick(event) {\n OverlayEventBus.emit('overlay-click', {\n originalEvent: event,\n target: this.$el\n });\n\n this.selfClick = true;\n },\n onOverlayKeydown(event) {\n if (event.code === 'Escape') this.hide();\n },\n findSelectedNodes(node, keys, selectedNodes) {\n if (node) {\n if (this.isSelected(node, keys)) {\n selectedNodes.push(node);\n delete keys[node.key];\n }\n\n if (Object.keys(keys).length && node.children) {\n for (let childNode of node.children) {\n this.findSelectedNodes(childNode, keys, selectedNodes);\n }\n }\n } else {\n for (let childNode of this.options) {\n this.findSelectedNodes(childNode, keys, selectedNodes);\n }\n }\n },\n isSelected(node, keys) {\n return this.selectionMode === 'checkbox' ? keys[node.key] && keys[node.key].checked : keys[node.key];\n },\n updateTreeState() {\n let keys = { ...this.modelValue };\n\n this.expandedKeys = {};\n\n if (keys && this.options) {\n this.updateTreeBranchState(null, null, keys);\n }\n },\n updateTreeBranchState(node, path, keys) {\n if (node) {\n if (this.isSelected(node, keys)) {\n this.expandPath(path);\n delete keys[node.key];\n }\n\n if (Object.keys(keys).length && node.children) {\n for (let childNode of node.children) {\n path.push(node.key);\n this.updateTreeBranchState(childNode, path, keys);\n }\n }\n } else {\n for (let childNode of this.options) {\n this.updateTreeBranchState(childNode, [], keys);\n }\n }\n },\n expandPath(path) {\n if (path.length > 0) {\n for (let key of path) {\n this.expandedKeys[key] = true;\n }\n }\n },\n scrollValueInView() {\n if (this.overlay) {\n let selectedItem = findSingle(this.overlay, '[data-p-selected=\"true\"]');\n\n if (selectedItem) {\n selectedItem.scrollIntoView({ block: 'nearest', inline: 'start' });\n }\n }\n }\n },\n computed: {\n selectedNodes() {\n let selectedNodes = [];\n\n if (this.modelValue && this.options) {\n let keys = { ...this.modelValue };\n\n this.findSelectedNodes(null, keys, selectedNodes);\n }\n\n return selectedNodes;\n },\n label() {\n let value = this.selectedNodes;\n\n return value.length ? value.map((node) => node.label).join(', ') : this.placeholder;\n },\n emptyMessageText() {\n return this.emptyMessage || this.$primevue.config.locale.emptyMessage;\n },\n emptyValue() {\n return !this.modelValue || Object.keys(this.modelValue).length === 0;\n },\n emptyOptions() {\n return !this.options || this.options.length === 0;\n },\n listId() {\n return this.id + '_list';\n },\n hasFluid() {\n return isEmpty(this.fluid) ? !!this.$pcFluid : this.fluid;\n }\n },\n components: {\n TSTree: Tree,\n Chip,\n Portal: Portal,\n ChevronDownIcon: ChevronDownIcon\n },\n directives: {\n ripple: Ripple\n }\n};\n</script>\n","<template>\n <div ref=\"container\" :class=\"cx('root')\" :style=\"sx('root')\" @click=\"onClick\" v-bind=\"ptmi('root')\">\n <div class=\"p-hidden-accessible\" v-bind=\"ptm('hiddenInputContainer')\" :data-p-hidden-accessible=\"true\">\n <input\n ref=\"focusInput\"\n :id=\"inputId\"\n type=\"text\"\n role=\"combobox\"\n :class=\"inputClass\"\n :style=\"inputStyle\"\n readonly\n :disabled=\"disabled\"\n :tabindex=\"!disabled ? tabindex : -1\"\n :aria-labelledby=\"ariaLabelledby\"\n :aria-label=\"ariaLabel\"\n aria-haspopup=\"tree\"\n :aria-expanded=\"overlayVisible\"\n :aria-controls=\"listId\"\n @focus=\"onFocus($event)\"\n @blur=\"onBlur($event)\"\n @keydown=\"onKeyDown($event)\"\n v-bind=\"{ ...inputProps, ...ptm('hiddenInput') }\"\n />\n </div>\n <div :class=\"cx('labelContainer')\" v-bind=\"ptm('labelContainer')\">\n <div :class=\"cx('label')\" v-bind=\"ptm('label')\">\n <slot name=\"value\" :value=\"selectedNodes\" :placeholder=\"placeholder\">\n <template v-if=\"display === 'comma'\">\n {{ label || 'empty' }}\n </template>\n <template v-else-if=\"display === 'chip'\">\n <div v-for=\"node of selectedNodes\" :key=\"node.key\" :class=\"cx('chipItem')\" v-bind=\"ptm('chipItem')\">\n <Chip :class=\"cx('pcChip')\" :label=\"node.label\" :unstyled=\"unstyled\" :pt=\"ptm('pcChip')\" />\n </div>\n <template v-if=\"emptyValue\">{{ placeholder || 'empty' }}</template>\n </template>\n </slot>\n </div>\n </div>\n <div :class=\"cx('dropdown')\" role=\"button\" aria-haspopup=\"tree\" :aria-expanded=\"overlayVisible\" v-bind=\"ptm('dropdown')\">\n <!-- TODO: triggericon is deprecated since v4.0 -->\n <slot :name=\"$slots.dropdownicon ? 'dropdownicon' : 'triggericon'\" :class=\"cx('dropdownIcon')\">\n <component :is=\"'ChevronDownIcon'\" :class=\"cx('dropdownIcon')\" v-bind=\"ptm('dropdownIcon')\" />\n </slot>\n </div>\n <Portal :appendTo=\"appendTo\">\n <transition name=\"p-connected-overlay\" @enter=\"onOverlayEnter\" @after-enter=\"onOverlayAfterEnter\" @leave=\"onOverlayLeave\" @after-leave=\"onOverlayAfterLeave\" v-bind=\"ptm('transition')\">\n <div v-if=\"overlayVisible\" :ref=\"overlayRef\" @click=\"onOverlayClick\" :class=\"[cx('panel'), panelClass]\" @keydown=\"onOverlayKeydown\" v-bind=\"{ ...panelProps, ...ptm('panel') }\">\n <span\n ref=\"firstHiddenFocusableElementOnOverlay\"\n role=\"presentation\"\n aria-hidden=\"true\"\n class=\"p-hidden-accessible p-hidden-focusable\"\n :tabindex=\"0\"\n @focus=\"onFirstHiddenFocus\"\n v-bind=\"ptm('hiddenFirstFocusableEl')\"\n :data-p-hidden-accessible=\"true\"\n :data-p-hidden-focusable=\"true\"\n ></span>\n <slot name=\"header\" :value=\"modelValue\" :options=\"options\"></slot>\n <div :class=\"cx('treeContainer')\" :style=\"{ 'max-height': scrollHeight }\" v-bind=\"ptm('treeContainer')\">\n <TSTree\n ref=\"tree\"\n :id=\"listId\"\n :value=\"options\"\n :selectionMode=\"selectionMode\"\n @update:selectionKeys=\"onSelectionChange\"\n :selectionKeys=\"modelValue\"\n :expandedKeys=\"expandedKeys\"\n @update:expandedKeys=\"onNodeToggle\"\n :metaKeySelection=\"metaKeySelection\"\n @node-expand=\"$emit('node-expand', $event)\"\n @node-collapse=\"$emit('node-collapse', $event)\"\n @node-select=\"onNodeSelect\"\n @node-unselect=\"onNodeUnselect\"\n :level=\"0\"\n :unstyled=\"unstyled\"\n :pt=\"ptm('pcTree')\"\n >\n <template v-if=\"$slots.itemtoggleicon\" #toggleicon=\"iconProps\">\n <slot name=\"itemtoggleicon\" :node=\"iconProps.node\" :expanded=\"iconProps.expanded\" :class=\"iconProps.class\" />\n </template>\n <!--TODO: itemtogglericon deprecated since v4.0-->\n <template v-else-if=\"$slots.itemtogglericon\" #togglericon=\"iconProps\">\n <slot name=\"itemtogglericon\" :node=\"iconProps.node\" :expanded=\"iconProps.expanded\" :class=\"iconProps.class\" />\n </template>\n <template v-if=\"$slots.itemcheckboxicon\" #checkboxicon=\"iconProps\">\n <slot name=\"itemcheckboxicon\" :checked=\"iconProps.checked\" :partialChecked=\"iconProps.partialChecked\" :class=\"iconProps.class\" />\n </template>\n </TSTree>\n <div v-if=\"emptyOptions\" :class=\"cx('emptyMessage')\" v-bind=\"ptm('emptyMessage')\">\n <slot name=\"empty\">{{ emptyMessageText }}</slot>\n </div>\n </div>\n <slot name=\"footer\" :value=\"modelValue\" :options=\"options\"></slot>\n <span\n ref=\"lastHiddenFocusableElementOnOverlay\"\n role=\"presentation\"\n aria-hidden=\"true\"\n class=\"p-hidden-accessible p-hidden-focusable\"\n :tabindex=\"0\"\n @focus=\"onLastHiddenFocus\"\n v-bind=\"ptm('hiddenLastFocusableEl')\"\n :data-p-hidden-accessible=\"true\"\n :data-p-hidden-focusable=\"true\"\n ></span>\n </div>\n </transition>\n </Portal>\n </div>\n</template>\n\n<script>\nimport { absolutePosition, addStyle, find, findSingle, focus, getFirstFocusableElement, getFocusableElements, getLastFocusableElement, getOuterWidth, isTouchDevice, relativePosition } from '@primeuix/utils/dom';\nimport { isEmpty } from '@primeuix/utils/object';\nimport { ZIndex } from '@primeuix/utils/zindex';\nimport { ConnectedOverlayScrollHandler, UniqueComponentId } from '@primevue/core/utils';\nimport ChevronDownIcon from '@primevue/icons/chevrondown';\nimport Chip from 'primevue/chip';\nimport OverlayEventBus from 'primevue/overlayeventbus';\nimport Portal from 'primevue/portal';\nimport Ripple from 'primevue/ripple';\nimport Tree from 'primevue/tree';\nimport BaseTreeSelect from './BaseTreeSelect.vue';\n\nexport default {\n name: 'TreeSelect',\n extends: BaseTreeSelect,\n inheritAttrs: false,\n emits: ['update:modelValue', 'before-show', 'before-hide', 'change', 'show', 'hide', 'node-select', 'node-unselect', 'node-expand', 'node-collapse', 'focus', 'blur'],\n inject: {\n $pcFluid: { default: null }\n },\n data() {\n return {\n id: this.$attrs.id,\n focused: false,\n overlayVisible: false,\n expandedKeys: {}\n };\n },\n watch: {\n '$attrs.id': function (newValue) {\n this.id = newValue || UniqueComponentId();\n },\n modelValue: {\n handler: function () {\n if (!this.selfChange) {\n this.updateTreeState();\n }\n\n this.selfChange = false;\n },\n immediate: true\n },\n options() {\n this.updateTreeState();\n }\n },\n outsideClickListener: null,\n resizeListener: null,\n scrollHandler: null,\n overlay: null,\n selfChange: false,\n selfClick: false,\n beforeUnmount() {\n this.unbindOutsideClickListener();\n this.unbindResizeListener();\n\n if (this.scrollHandler) {\n this.scrollHandler.destroy();\n this.scrollHandler = null;\n }\n\n if (this.overlay) {\n ZIndex.clear(this.overlay);\n this.overlay = null;\n }\n },\n mounted() {\n this.id = this.id || UniqueComponentId();\n this.updateTreeState();\n },\n methods: {\n show() {\n this.$emit('before-show');\n this.overlayVisible = true;\n },\n hide() {\n this.$emit('before-hide');\n this.overlayVisible = false;\n this.$refs.focusInput.focus();\n },\n onFocus(event) {\n this.focused = true;\n this.$emit('focus', event);\n },\n onBlur(event) {\n this.focused = false;\n this.$emit('blur', event);\n },\n onClick(event) {\n if (this.disabled) {\n return;\n }\n\n if (!this.disabled && (!this.overlay || !this.overlay.contains(event.target))) {\n if (this.overlayVisible) this.hide();\n else this.show();\n\n focus(this.$refs.focusInput);\n }\n },\n onSelectionChange(keys) {\n this.selfChange = true;\n this.$emit('update:modelValue', keys);\n this.$emit('change', keys);\n },\n onNodeSelect(node) {\n this.$emit('node-select', node);\n\n if (this.selectionMode === 'single') {\n this.hide();\n }\n },\n onNodeUnselect(node) {\n this.$emit('node-unselect', node);\n },\n onNodeToggle(keys) {\n this.expandedKeys = keys;\n },\n onFirstHiddenFocus(event) {\n const focusableEl = event.relatedTarget === this.$refs.focusInput ? getFirstFocusableElement(this.overlay, ':not([data-p-hidden-focusable=\"true\"])') : this.$refs.focusInput;\n\n focus(focusableEl);\n },\n onLastHiddenFocus(event) {\n const focusableEl = event.relatedTarget === this.$refs.focusInput ? getLastFocusableElement(this.overlay, ':not([data-p-hidden-focusable=\"true\"])') : this.$refs.focusInput;\n\n focus(focusableEl);\n },\n onKeyDown(event) {\n switch (event.code) {\n case 'ArrowDown':\n this.onArrowDownKey(event);\n break;\n\n case 'Space':\n case 'Enter':\n case 'NumpadEnter':\n this.onEnterKey(event);\n break;\n\n case 'Escape':\n this.onEscapeKey(event);\n break;\n\n case 'Tab':\n this.onTabKey(event);\n break;\n\n default:\n break;\n }\n },\n onArrowDownKey(event) {\n if (this.overlayVisible) return;\n\n this.show();\n\n this.$nextTick(() => {\n const treeNodeEl = find(this.$refs.tree.$el, '[data-pc-section=\"treeitem\"]');\n const focusedElement = [...treeNodeEl].find((item) => item.getAttribute('tabindex') === '0');\n\n focus(focusedElement);\n });\n\n event.preventDefault();\n },\n onEnterKey(event) {\n if (this.overlayVisible) {\n this.hide();\n } else {\n this.onArrowDownKey(event);\n }\n\n event.preventDefault();\n },\n onEscapeKey(event) {\n if (this.overlayVisible) {\n this.hide();\n event.preventDefault();\n }\n },\n onTabKey(event, pressedInInputText = false) {\n if (!pressedInInputText) {\n if (this.overlayVisible && this.hasFocusableElements()) {\n focus(this.$refs.firstHiddenFocusableElementOnOverlay);\n\n event.preventDefault();\n }\n }\n },\n hasFocusableElements() {\n return getFocusableElements(this.overlay, ':not([data-p-hidden-focusable=\"true\"])').length > 0;\n },\n onOverlayEnter(el) {\n ZIndex.set('overlay', el, this.$primevue.config.zIndex.overlay);\n\n addStyle(el, { position: 'absolute', top: '0', left: '0' });\n this.alignOverlay();\n this.focus();\n },\n onOverlayAfterEnter() {\n this.bindOutsideClickListener();\n this.bindScrollListener();\n this.bindResizeListener();\n this.scrollValueInView();\n this.$emit('show');\n },\n onOverlayLeave() {\n this.unbindOutsideClickListener();\n this.unbindScrollListener();\n this.unbindResizeListener();\n this.$emit('hide');\n this.overlay = null;\n },\n onOverlayAfterLeave(el) {\n ZIndex.clear(el);\n },\n focus() {\n let focusableElements = getFocusableElements(this.overlay);\n\n if (focusableElements && focusableElements.length > 0) {\n focusableElements[0].focus();\n }\n },\n alignOverlay() {\n if (this.appendTo === 'self') {\n relativePosition(this.overlay, this.$el);\n } else {\n this.overlay.style.minWidth = getOuterWidth(this.$el) + 'px';\n absolutePosition(this.overlay, this.$el);\n }\n },\n bindOutsideClickListener() {\n if (!this.outsideClickListener) {\n this.outsideClickListener = (event) => {\n if (this.overlayVisible && !this.selfClick && this.isOutsideClicked(event)) {\n this.hide();\n }\n\n this.selfClick = false;\n };\n\n document.addEventListener('click', this.outsideClickListener);\n }\n },\n unbindOutsideClickListener() {\n if (this.outsideClickListener) {\n document.removeEventListener('click', this.outsideClickListener);\n this.outsideClickListener = null;\n }\n },\n bindScrollListener() {\n if (!this.scrollHandler) {\n this.scrollHandler = new ConnectedOverlayScrollHandler(this.$refs.container, () => {\n if (this.overlayVisible) {\n this.hide();\n }\n });\n }\n\n this.scrollHandler.bindScrollListener();\n },\n unbindScrollListener() {\n if (this.scrollHandler) {\n this.scrollHandler.unbindScrollListener();\n }\n },\n bindResizeListener() {\n if (!this.resizeListener) {\n this.resizeListener = () => {\n if (this.overlayVisible && !isTouchDevice()) {\n this.hide();\n }\n };\n\n window.addEventListener('resize', this.resizeListener);\n }\n },\n unbindResizeListener() {\n if (this.resizeListener) {\n window.removeEventListener('resize', this.resizeListener);\n this.resizeListener = null;\n }\n },\n isOutsideClicked(event) {\n return !(this.$el.isSameNode(event.target) || this.$el.contains(event.target) || (this.overlay && this.overlay.contains(event.target)));\n },\n overlayRef(el) {\n this.overlay = el;\n },\n onOverlayClick(event) {\n OverlayEventBus.emit('overlay-click', {\n originalEvent: event,\n target: this.$el\n });\n\n this.selfClick = true;\n },\n onOverlayKeydown(event) {\n if (event.code === 'Escape') this.hide();\n },\n findSelectedNodes(node, keys, selectedNodes) {\n if (node) {\n if (this.isSelected(node, keys)) {\n selectedNodes.push(node);\n delete keys[node.key];\n }\n\n if (Object.keys(keys).length && node.children) {\n for (let childNode of node.children) {\n this.findSelectedNodes(childNode, keys, selectedNodes);\n }\n }\n } else {\n for (let childNode of this.options) {\n this.findSelectedNodes(childNode, keys, selectedNodes);\n }\n }\n },\n isSelected(node, keys) {\n return this.selectionMode === 'checkbox' ? keys[node.key] && keys[node.key].checked : keys[node.key];\n },\n updateTreeState() {\n let keys = { ...this.modelValue };\n\n this.expandedKeys = {};\n\n if (keys && this.options) {\n this.updateTreeBranchState(null, null, keys);\n }\n },\n updateTreeBranchState(node, path, keys) {\n if (node) {\n if (this.isSelected(node, keys)) {\n this.expandPath(path);\n delete keys[node.key];\n }\n\n if (Object.keys(keys).length && node.children) {\n for (let childNode of node.children) {\n path.push(node.key);\n this.updateTreeBranchState(childNode, path, keys);\n }\n }\n } else {\n for (let childNode of this.options) {\n this.updateTreeBranchState(childNode, [], keys);\n }\n }\n },\n expandPath(path) {\n if (path.length > 0) {\n for (let key of path) {\n this.expandedKeys[key] = true;\n }\n }\n },\n scrollValueInView() {\n if (this.overlay) {\n let selectedItem = findSingle(this.overlay, '[data-p-selected=\"true\"]');\n\n if (selectedItem) {\n selectedItem.scrollIntoView({ block: 'nearest', inline: 'start' });\n }\n }\n }\n },\n computed: {\n selectedNodes() {\n let selectedNodes = [];\n\n if (this.modelValue && this.options) {\n let keys = { ...this.modelValue };\n\n this.findSelectedNodes(null, keys, selectedNodes);\n }\n\n return selectedNodes;\n },\n label() {\n let value = this.selectedNodes;\n\n return value.length ? value.map((node) => node.label).join(', ') : this.placeholder;\n },\n emptyMessageText() {\n return this.emptyMessage || this.$primevue.config.locale.emptyMessage;\n },\n emptyValue() {\n return !this.modelValue || Object.keys(this.modelValue).length === 0;\n },\n emptyOptions() {\n return !this.options || this.options.length === 0;\n },\n listId() {\n return this.id + '_list';\n },\n hasFluid() {\n return isEmpty(this.fluid) ? !!this.$pcFluid : this.fluid;\n }\n },\n components: {\n TSTree: Tree,\n Chip,\n Portal: Portal,\n ChevronDownIcon: ChevronDownIcon\n },\n directives: {\n ripple: Ripple\n }\n};\n</script>\n"],"names":["name","BaseComponent","props","modelValue","options","Array","scrollHeight","type","String","placeholder","invalid","Boolean","variant","disabled","tabindex","Number","selectionMode","appendTo","Object","emptyMessage","display","metaKeySelection","fluid","inputId","inputClass","inputStyle","inputProps","panelClass","panelProps","ariaLabelledby","ariaLabel","style","TreeSelectStyle","provide","$pcTreeSelect","$parentInstance","BaseTreeSelect","inheritAttrs","emits","inject","$pcFluid","data","id","$attrs","focused","overlayVisible","expandedKeys","watch","$attrsId","newValue","UniqueComponentId","handler","selfChange","updateTreeState","immediate","outsideClickListener","resizeListener","scrollHandler","overlay","selfClick","beforeUnmount","unbindOutsideClickListener","unbindResizeListener","destroy","ZIndex","clear","mounted","methods","show","$emit","hide","$refs","focusInput","focus","onFocus","event","onBlur","onClick","contains","target","onSelectionChange","keys","onNodeSelect","node","onNodeUnselect","onNodeToggle","onFirstHiddenFocus","focusableEl","relatedTarget","getFirstFocusableElement","onLastHiddenFocus","getLastFocusableElement","onKeyDown","code","onArrowDownKey","onEnterKey","onEscapeKey","onTabKey","_this","$nextTick","treeNodeEl","find","tree","$el","focusedElement","_toConsumableArray","item","getAttribute","preventDefault","pressedInInputText","hasFocusableElements","firstHiddenFocusableElementOnOverlay","getFocusableElements","length","onOverlayEnter","el","set","$primevue","config","zIndex","addStyle","position","top","left","alignOverlay","onOverlayAfterEnter","bindOutsideClickListener","bindScrollListener","bindResizeListener","scrollValueInView","onOverlayLeave","unbindScrollListener","onOverlayAfterLeave","focusableElements","relativePosition","minWidth","getOuterWidth","absolutePosition","_this2","isOutsideClicked","document","addEventListener","removeEventListener","_this3","ConnectedOverlayScrollHandler","container","_this4","isTouchDevice","window","isSameNode","overlayRef","onOverlayClick","OverlayEventBus","emit","originalEvent","onOverlayKeydown","findSelectedNodes","selectedNodes","isSelected","push","key","children","_iterator","_createForOfIteratorHelper","_step","s","n","done","childNode","value","err","e","f","_iterator2","_step2","checked","_objectSpread","updateTreeBranchState","path","expandPath","_iterator3","_step3","_iterator4","_step4","_iterator5","_step5","selectedItem","findSingle","scrollIntoView","block","inline","computed","label","map","join","emptyMessageText","locale","emptyValue","emptyOptions","listId","hasFluid","isEmpty","components","TSTree","Tree","Chip","Portal","ChevronDownIcon","directives","ripple","Ripple","_openBlock","_createElementBlock","_mergeProps","ref","_ctx","cx","sx","$options","apply","arguments","ptmi","_createElementVNode","ptm","role","readonly","$data","_cache","$event","onKeydown","_hoisted_1","_renderSlot","$slots","_Fragment","_renderList","_createVNode","_component_Chip","unstyled","pt","dropdownicon","_createBlock","_resolveDynamicComponent","_component_Portal","_Transition","onEnter","onAfterEnter","onLeave","onAfterLeave","_component_TSTree","selectionKeys","onNodeExpand","onNodeCollapse","level","itemtoggleicon","fn","_withCtx","iconProps","expanded","_normalizeClass","itemtogglericon","itemcheckboxicon","partialChecked"],"mappings":";;;;;;;;;;;;;;AAIA,eAAe;AACXA,EAAAA,IAAI,EAAE,gBAAgB;AACtB,EAAA,SAAA,EAASC,aAAa;AACtBC,EAAAA,KAAK,EAAE;AACHC,IAAAA,UAAU,EAAE,IAAI;AAChBC,IAAAA,OAAO,EAAEC,KAAK;AACdC,IAAAA,YAAY,EAAE;AACVC,MAAAA,IAAI,EAAEC,MAAM;MACZ,SAAS,EAAA,OAAA;KACZ;AACDC,IAAAA,WAAW,EAAE;AACTF,MAAAA,IAAI,EAAEC,MAAM;MACZ,SAAS,EAAA,IAAA;KACZ;AACDE,IAAAA,OAAO,EAAE;AACLH,MAAAA,IAAI,EAAEI,OAAO;MACb,SAAS,EAAA,KAAA;KACZ;AACDC,IAAAA,OAAO,EAAE;AACLL,MAAAA,IAAI,EAAEC,MAAM;MACZ,SAAS,EAAA,IAAA;KACZ;AACDK,IAAAA,QAAQ,EAAE;AACNN,MAAAA,IAAI,EAAEI,OAAO;MACb,SAAS,EAAA,KAAA;KACZ;AACDG,IAAAA,QAAQ,EAAE;AACNP,MAAAA,IAAI,EAAEQ,MAAM;MACZ,SAAS,EAAA,IAAA;KACZ;AACDC,IAAAA,aAAa,EAAE;AACXT,MAAAA,IAAI,EAAEC,MAAM;MACZ,SAAS,EAAA,QAAA;KACZ;AACDS,IAAAA,QAAQ,EAAE;AACNV,MAAAA,IAAI,EAAE,CAACC,MAAM,EAAEU,MAAM,CAAC;MACtB,SAAS,EAAA,MAAA;KACZ;AACDC,IAAAA,YAAY,EAAE;AACVZ,MAAAA,IAAI,EAAEC,MAAM;MACZ,SAAS,EAAA,IAAA;KACZ;AACDY,IAAAA,OAAO,EAAE;AACLb,MAAAA,IAAI,EAAEC,MAAM;MACZ,SAAS,EAAA,OAAA;KACZ;AACDa,IAAAA,gBAAgB,EAAE;AACdd,MAAAA,IAAI,EAAEI,OAAO;MACb,SAAS,EAAA,KAAA;KACZ;AACDW,IAAAA,KAAK,EAAE;AACHf,MAAAA,IAAI,EAAEI,OAAO;MACb,SAAS,EAAA,IAAA;KACZ;AACDY,IAAAA,OAAO,EAAE;AACLhB,MAAAA,IAAI,EAAEC,MAAM;MACZ,SAAS,EAAA,IAAA;KACZ;AACDgB,IAAAA,UAAU,EAAE;AACRjB,MAAAA,IAAI,EAAE,CAACC,MAAM,EAAEU,MAAM,CAAC;MACtB,SAAS,EAAA,IAAA;KACZ;AACDO,IAAAA,UAAU,EAAE;AACRlB,MAAAA,IAAI,EAAEW,MAAM;MACZ,SAAS,EAAA,IAAA;KACZ;AACDQ,IAAAA,UAAU,EAAE;AACRnB,MAAAA,IAAI,EAAE,IAAI;MACV,SAAS,EAAA,IAAA;KACZ;AACDoB,IAAAA,UAAU,EAAE;AACRpB,MAAAA,IAAI,EAAE,CAACC,MAAM,EAAEU,MAAM,CAAC;MACtB,SAAS,EAAA,IAAA;KACZ;AACDU,IAAAA,UAAU,EAAE;AACRrB,MAAAA,IAAI,EAAE,IAAI;MACV,SAAS,EAAA,IAAA;KACZ;AACDsB,IAAAA,cAAc,EAAE;AACZtB,MAAAA,IAAI,EAAEC,MAAM;MACZ,SAAS,EAAA,IAAA;KACZ;AACDsB,IAAAA,SAAS,EAAE;AACPvB,MAAAA,IAAI,EAAEC,MAAM;MACZ,SAAS,EAAA,IAAA;AACb,KAAA;GACH;AACDuB,EAAAA,KAAK,EAAEC,eAAe;EACtBC,OAAO,EAAA,SAAPA,OAAOA,GAAG;IACN,OAAO;AACHC,MAAAA,aAAa,EAAE,IAAI;AACnBC,MAAAA,eAAe,EAAE,IAAA;KACpB,CAAA;AACL,GAAA;AACJ,CAAC;;;;;;;;;;;;;;;AC2BD,aAAe;AACXnC,EAAAA,IAAI,EAAE,YAAY;AAClB,EAAA,SAAA,EAASoC,QAAc;AACvBC,EAAAA,YAAY,EAAE,KAAK;EACnBC,KAAK,EAAE,CAAC,mBAAmB,EAAE,aAAa,EAAE,aAAa,EAAE,QAAQ,EAAE,MAAM,EAAE,MAAM,EAAE,aAAa,EAAE,eAAe,EAAE,aAAa,EAAE,eAAe,EAAE,OAAO,EAAE,MAAM,CAAC;AACrKC,EAAAA,MAAM,EAAE;AACJC,IAAAA,QAAQ,EAAE;MAAE,SAAS,EAAA,IAAA;AAAK,KAAA;GAC7B;EACDC,IAAI,EAAA,SAAJA,IAAIA,GAAG;IACH,OAAO;AACHC,MAAAA,EAAE,EAAE,IAAI,CAACC,MAAM,CAACD,EAAE;AAClBE,MAAAA,OAAO,EAAE,KAAK;AACdC,MAAAA,cAAc,EAAE,KAAK;AACrBC,MAAAA,YAAY,EAAE,EAAC;KAClB,CAAA;GACJ;AACDC,EAAAA,KAAK,EAAE;AACH,IAAA,WAAW,EAAE,SAAbC,QAAWA,CAAYC,QAAQ,EAAE;AAC7B,MAAA,IAAI,CAACP,EAAG,GAAEO,YAAYC,iBAAiB,EAAE,CAAA;KAC5C;AACD/C,IAAAA,UAAU,EAAE;AACRgD,MAAAA,OAAO,EAAE,SAATA,OAAOA,GAAc;AACjB,QAAA,IAAI,CAAC,IAAI,CAACC,UAAU,EAAE;UAClB,IAAI,CAACC,eAAe,EAAE,CAAA;AAC1B,SAAA;QAEA,IAAI,CAACD,UAAW,GAAE,KAAK,CAAA;OAC1B;AACDE,MAAAA,SAAS,EAAE,IAAA;KACd;IACDlD,OAAO,EAAA,SAAPA,OAAOA,GAAG;MACN,IAAI,CAACiD,eAAe,EAAE,CAAA;AAC1B,KAAA;GACH;AACDE,EAAAA,oBAAoB,EAAE,IAAI;AAC1BC,EAAAA,cAAc,EAAE,IAAI;AACpBC,EAAAA,aAAa,EAAE,IAAI;AACnBC,EAAAA,OAAO,EAAE,IAAI;AACbN,EAAAA,UAAU,EAAE,KAAK;AACjBO,EAAAA,SAAS,EAAE,KAAK;EAChBC,aAAa,EAAA,SAAbA,aAAaA,GAAG;IACZ,IAAI,CAACC,0BAA0B,EAAE,CAAA;IACjC,IAAI,CAACC,oBAAoB,EAAE,CAAA;IAE3B,IAAI,IAAI,CAACL,aAAa,EAA