require('../assets/NcSelect-GdIw6cIy.css'); "use strict"; const vueSelect = require("@nextcloud/vue-select"); const dom = require("@floating-ui/dom"); const Vue = require("vue"); const _l10n = require("./_l10n-CjO_W5Dt.cjs"); const ChevronDown = require("./ChevronDown-BlfyuflD.cjs"); const Close = require("./Close-CqmXxEKi.cjs"); const Components_NcEllipsisedOption = require("../Components/NcEllipsisedOption.cjs"); const NcListItemIcon = require("./NcListItemIcon-pOj8Vr2H.cjs"); const Components_NcLoadingIcon = require("../Components/NcLoadingIcon.cjs"); const GenRandomId = require("./GenRandomId-BQDud3d4.cjs"); const useModelMigration = require("./useModelMigration-D5zhrNXr.cjs"); require("@nextcloud/vue-select/dist/vue-select.css"); const _pluginVue2_normalizer = require("./_plugin-vue2_normalizer-V0q-tHlQ.cjs"); const _interopDefault = (e) => e && e.__esModule ? e : { default: e }; const Vue__default = /* @__PURE__ */ _interopDefault(Vue); _l10n.register(_l10n.t15); const _sfc_main = { name: "NcSelect", components: { ChevronDown: ChevronDown.ChevronDown, NcEllipsisedOption: Components_NcEllipsisedOption, NcListItemIcon: NcListItemIcon.NcListItemIcon, NcLoadingIcon: Components_NcLoadingIcon, VueSelect: vueSelect.VueSelect }, model: { prop: "modelValue", event: "update:modelValue" }, props: { // Add VueSelect props to $props ...vueSelect.VueSelect.props, ...vueSelect.VueSelect.mixins.reduce((allProps, mixin) => ({ ...allProps, ...mixin.props }), {}), /** * `aria-label` for the clear input button */ ariaLabelClearSelected: { type: String, default: _l10n.t("Clear selected") }, /** * `aria-label` for the search input * * A descriptive `inputLabel` is preferred as this is not visible. */ ariaLabelCombobox: { type: String, default: null }, /** * `aria-label` for the listbox element */ ariaLabelListbox: { type: String, default: _l10n.t("Options") }, /** * Allows to customize the `aria-label` for the deselect-option button * The default is "Deselect " + optionLabel * @type {(optionLabel: string) => string} */ ariaLabelDeselectOption: { type: Function, default: (optionLabel) => _l10n.t("Deselect {option}", { option: optionLabel }) }, /** * Append the dropdown element to the end of the body * and size/position it dynamically. * * @see https://vue-select.org/api/props.html#appendtobody */ appendToBody: { type: Boolean, default: true }, /** * When `appendToBody` is true, this function is responsible for * positioning the drop down list. * * If a function is returned from `calculatePosition`, it will * be called when the drop down list is removed from the DOM. * This allows for any garbage collection you may need to do. * * @see https://vue-select.org/api/props.html#calculateposition */ calculatePosition: { type: Function, default: null }, /** * Close the dropdown when selecting an option * * @see https://vue-select.org/api/props.html#closeonselect */ closeOnSelect: { type: Boolean, default: true }, /** * Replace default vue-select components * * @see https://vue-select.org/api/props.html#components */ components: { type: Object, default: () => ({ Deselect: { render: (createElement) => createElement(Close.Close, { props: { size: 20, fillColor: "var(--vs-controls-color)" }, style: { cursor: "pointer" } }) } }) }, /** * Sets the maximum number of options to display in the dropdown list */ limit: { type: Number, default: null }, /** * Disable the component * * @see https://vue-select.org/api/props.html#disabled */ disabled: { type: Boolean, default: false }, /** * Determines whether the dropdown should be open. * Receives the component instance as the only argument. * * @see https://vue-select.org/api/props.html#dropdownshouldopen */ dropdownShouldOpen: { type: Function, default: ({ noDrop, open }) => { return noDrop ? false : open; } }, /** * Callback to determine if the provided option should * match the current search text. Used to determine * if the option should be displayed. * * Defaults to the internal vue-select function documented at the link * below * * Enabling `userSelect` will automatically set this to filter by the * `displayName` and `subname` properties of the user option object * unless this prop is set explicitly * * @see https://vue-select.org/api/props.html#filterby */ filterBy: { type: Function, default: null }, /** * Class for the `input` * * Necessary for use in NcActionInput */ inputClass: { type: [String, Object], default: null }, /** * Input element id */ inputId: { type: String, default: () => `select-input-${GenRandomId.GenRandomId()}` }, /** * Visible label for the input element * * @todo Set default for @nextcloud/vue 9 */ inputLabel: { type: String, default: null }, /** * Pass true if you are using an external label */ labelOutside: { type: Boolean, default: false }, /** * Display a visible border around dropdown options * which have keyboard focus */ keyboardFocusBorder: { type: Boolean, default: true }, /** * Key of the displayed label for object options * * Defaults to the internal vue-select string documented at the link * below * * Enabling `userSelect` will automatically set this to `'displayName'` * unless this prop is set explicitly * * @see https://vue-select.org/api/props.html#label */ label: { type: String, default: null }, /** * Show the loading icon * * @see https://vue-select.org/api/props.html#loading */ loading: { type: Boolean, default: false }, /** * Allow selection of multiple options * * @see https://vue-select.org/api/props.html#multiple */ multiple: { type: Boolean, default: false }, /** * Disable automatic wrapping when selected options overflow the width */ noWrap: { type: Boolean, default: false }, /** * Array of options * * @type {Array>} * * @see https://vue-select.org/api/props.html#options */ options: { type: Array, default: () => [] }, /** * Placeholder text * * @see https://vue-select.org/api/props.html#placeholder */ placeholder: { type: String, default: "" }, /** * Customized component's response to keydown events while the search input has focus * * @see https://vue-select.org/guide/keydown.html#mapkeydown */ mapKeydown: { type: Function, /** * Patched Vue-Select keydown events handlers map to stop Escape propagation in open select * * @param {Record} map - Mapped keyCode to handlers { : } * @param {import('@nextcloud/vue-select').VueSelect} vm - VueSelect instance * @return {Record} patched keydown event handlers */ default(map, vm) { return { ...map, /** * Patched Escape handler to stop propagation from open select * * @param {KeyboardEvent} event - default keydown event handler */ 27: (event) => { if (vm.open) { event.stopPropagation(); } map[27](event); } }; } }, /** * A unique identifier used to generate IDs and DOM attributes. Must be unique for every instance of the component. * * @see https://vue-select.org/api/props.html#uid */ uid: { type: String, default: () => GenRandomId.GenRandomId() }, /** * When `appendToBody` is true, this sets the placement of the dropdown * * @type {'bottom' | 'top'} */ placement: { type: String, default: "bottom" }, /** * If false, the focused dropdown option will not be reset when filtered * options change */ resetFocusOnOptionsChange: { type: Boolean, default: true }, /** * Enable the user selector with avatars * * Objects must contain the data expected by the * [NcListItemIcon](#/Components/NcListItemIcon) and * [NcAvatar](#/Components/NcAvatar) components */ userSelect: { type: Boolean, default: false }, /** * Removed in v9 - use `modelValue` (`v-model`) instead * @deprecated */ value: { type: [String, Number, Object, Array], default: void 0 }, /** * Currently selected value * * The `v-model` directive may be used for two-way data binding * * @type {string | number | Record | Array} * * @see https://vue-select.org/api/props.html#value */ modelValue: { type: [String, Number, Object, Array], default: null }, /** * Enable if a value is required for native form validation */ required: { type: Boolean, default: false }, /** * Any available prop * * @see https://vue-select.org/api/props.html */ // Not an actual prop but needed to show in vue-styleguidist docs // eslint-disable-next-line " ": {} }, emits: [ /** * All events from https://vue-select.org/api/events.html */ // Not an actual event but needed to show in vue-styleguidist docs " ", /** * Removed in v9 - use `update:modelValue` (`v-model`) instead * @deprecated */ "input", "update:modelValue", /** Same as update:modelValue for Vue 2 compatibility */ "update:model-value" ], setup() { const clickableArea = Number.parseInt(window.getComputedStyle(document.body).getPropertyValue("--default-clickable-area")); const gridBaseLine = Number.parseInt(window.getComputedStyle(document.body).getPropertyValue("--default-grid-baseline")); const avatarSize = clickableArea - 2 * gridBaseLine; const model = useModelMigration.useModelMigration("value", "input"); return { avatarSize, model }; }, data() { return { search: "" }; }, computed: { inputRequired() { if (!this.required) { return null; } return this.model === null || Array.isArray(this.model) && this.model.length === 0; }, localCalculatePosition() { if (this.calculatePosition !== null) { return this.calculatePosition; } return (dropdownMenu, component, { width }) => { dropdownMenu.style.width = width; const addClass = { name: "addClass", fn(_middlewareArgs) { dropdownMenu.classList.add("vs__dropdown-menu--floating"); return {}; } }; const togglePlacementClass = { name: "togglePlacementClass", fn({ placement }) { component.$el.classList.toggle( "select--drop-up", placement === "top" ); dropdownMenu.classList.toggle( "vs__dropdown-menu--floating-placement-top", placement === "top" ); return {}; } }; const updatePosition = () => { dom.computePosition(component.$refs.toggle, dropdownMenu, { placement: this.placement, middleware: [ dom.offset(-1), addClass, togglePlacementClass, // Match popperjs default collision prevention behavior by appending the following middleware in order dom.flip(), dom.shift({ limiter: dom.limitShift() }) ] }).then(({ x, y }) => { Object.assign(dropdownMenu.style, { left: `${x}px`, top: `${y}px`, width: `${component.$refs.toggle.getBoundingClientRect().width}px` }); }); }; const cleanup = dom.autoUpdate( component.$refs.toggle, dropdownMenu, updatePosition ); return cleanup; }; }, localFilterBy() { const EMAIL_NOTATION = /[^<]*<([^>]+)/; if (this.filterBy !== null) { return this.filterBy; } if (this.userSelect) { return (option, label, search) => { const match = search.match(EMAIL_NOTATION); return match && option.subname?.toLocaleLowerCase?.()?.indexOf(match[1].toLocaleLowerCase()) > -1 || `${label} ${option.subname}`.toLocaleLowerCase().indexOf(search.toLocaleLowerCase()) > -1; }; } return vueSelect.VueSelect.props.filterBy.default; }, localLabel() { if (this.label !== null) { return this.label; } if (this.userSelect) { return "displayName"; } return vueSelect.VueSelect.props.label.default; }, propsToForward() { const vueSelectKeys = [ ...Object.keys(vueSelect.VueSelect.props), ...vueSelect.VueSelect.mixins.flatMap((mixin) => Object.keys(mixin.props ?? {})) ]; const initialPropsToForward = Object.fromEntries( Object.entries(this.$props).filter(([key, _value]) => vueSelectKeys.includes(key)) ); const propsToForward = { ...initialPropsToForward, // Custom overrides of vue-select props value: this.model, calculatePosition: this.localCalculatePosition, filterBy: this.localFilterBy, label: this.localLabel }; return propsToForward; }, listenersToForward() { return { ...this.$listeners, input: ($event) => { this.model = $event; } }; } }, mounted() { if (!this.labelOutside && !this.inputLabel && !this.ariaLabelCombobox) { Vue__default.default.util.warn("[NcSelect] An `inputLabel` or `ariaLabelCombobox` should be set. If an external label is used, `labelOutside` should be set to `true`."); } if (this.inputLabel && this.ariaLabelCombobox) { Vue__default.default.util.warn("[NcSelect] Only one of `inputLabel` or `ariaLabelCombobox` should to be set."); } }, methods: { t: _l10n.t } }; var _sfc_render = function render() { var _vm = this, _c = _vm._self._c; return _c("VueSelect", _vm._g(_vm._b({ staticClass: "select", class: { "select--no-wrap": _vm.noWrap, "user-select": _vm.userSelect }, on: { "search": (searchString) => _vm.search = searchString }, scopedSlots: _vm._u([!_vm.labelOutside && _vm.inputLabel ? { key: "header", fn: function() { return [_c("label", { staticClass: "select__label", attrs: { "for": _vm.inputId } }, [_vm._v(" " + _vm._s(_vm.inputLabel) + " ")])]; }, proxy: true } : null, { key: "search", fn: function({ attributes, events }) { return [_c("input", _vm._g(_vm._b({ class: ["vs__search", _vm.inputClass], attrs: { "required": _vm.inputRequired, "dir": "auto" } }, "input", attributes, false), events))]; } }, { key: "open-indicator", fn: function({ attributes }) { return [_c("ChevronDown", _vm._b({ style: { cursor: !_vm.disabled ? "pointer" : null }, attrs: { "fill-color": "var(--vs-controls-color)", "size": 26 } }, "ChevronDown", attributes, false))]; } }, { key: "option", fn: function(option) { return [_vm.userSelect ? _c("NcListItemIcon", _vm._b({ attrs: { "avatar-size": 32, "name": option[_vm.localLabel], "search": _vm.search } }, "NcListItemIcon", option, false)) : _c("NcEllipsisedOption", { attrs: { "name": String(option[_vm.localLabel]), "search": _vm.search } })]; } }, { key: "selected-option", fn: function(selectedOption) { return [_vm.userSelect ? _c("NcListItemIcon", _vm._b({ attrs: { "avatar-size": _vm.avatarSize, "name": selectedOption[_vm.localLabel], "no-margin": "", "search": _vm.search } }, "NcListItemIcon", selectedOption, false)) : _c("NcEllipsisedOption", { attrs: { "name": String(selectedOption[_vm.localLabel]), "search": _vm.search } })]; } }, { key: "spinner", fn: function(spinner) { return [spinner.loading ? _c("NcLoadingIcon") : _vm._e()]; } }, { key: "no-options", fn: function() { return [_vm._v(" " + _vm._s(_vm.t("No results")) + " ")]; }, proxy: true }, _vm._l(_vm.$scopedSlots, function(_, name) { return { key: name, fn: function(data) { return [_vm._t(name, null, null, data)]; } }; })], null, true) }, "VueSelect", _vm.propsToForward, false), _vm.listenersToForward)); }; var _sfc_staticRenderFns = []; var __component__ = /* @__PURE__ */ _pluginVue2_normalizer.normalizeComponent( _sfc_main, _sfc_render, _sfc_staticRenderFns, false, null, null ); const NcSelect = __component__.exports; exports.NcSelect = NcSelect;