UNPKG

@oruga-ui/oruga-next

Version:

UI components for Vue.js and CSS framework agnostic

342 lines (341 loc) 14.5 kB
/*! Oruga v0.11.0 | MIT License | github.com/oruga-ui/oruga */ import { defineComponent, mergeModels, useTemplateRef, ref, useModel, computed, useId, watchEffect, useAttrs, createElementBlock, openBlock, normalizeClass, unref, createElementVNode, createCommentVNode, renderSlot, withDirectives, Fragment, renderList, createBlock, createVNode, mergeProps, withKeys, createSlots, withCtx, vShow, createTextVNode, toDisplayString } from "vue"; import { _ as _sfc_main$2 } from "./Autocomplete.vue_vue_type_script_setup_true_lang-C72gQKZg.mjs"; import { _ as _sfc_main$1 } from "./Tag.vue_vue_type_script_setup_true_lang-CmhSwLnP.mjs"; import { g as getDefault, b as registerComponent } from "./config-Dl7tu_Ly.mjs"; import { d as defineClasses, g as getActiveClasses } from "./defineClasses-CWB9NuS-.mjs"; import { u as useInputHandler } from "./useInputHandler-Cv7NmM5J.mjs"; import { n as normalizeOptions, t as toOptionsGroup, b as findOption } from "./useOptions-eabMIWNM.mjs"; import { u as useSequentialId } from "./useSequentialId-BpzOPIdj.mjs"; const _sfc_main = /* @__PURE__ */ defineComponent({ ...{ isOruga: true, name: "OTaginput", configField: "taginput", inheritAttrs: false }, __name: "Taginput", props: /* @__PURE__ */ mergeModels({ override: { type: Boolean, default: void 0 }, modelValue: { default: void 0 }, input: { default: "" }, options: { default: void 0 }, filter: { type: Function, default: void 0 }, size: { default: () => getDefault("taginput.size") }, variant: { default: () => getDefault("taginput.variant") }, maxitems: { default: void 0 }, maxlength: { default: void 0 }, counter: { type: Boolean, default: () => getDefault("taginput.counter", true) }, openOnFocus: { type: Boolean, default: () => getDefault("taginput.openOnFocus", true) }, keepOpen: { type: Boolean, default: () => getDefault("taginput.keepOpen", false) }, placeholder: { default: void 0 }, expanded: { type: Boolean, default: false }, disabled: { type: Boolean, default: false }, keepFirst: { type: Boolean, default: () => getDefault("taginput.keepFirst", false) }, allowNew: { type: Boolean, default: () => getDefault("taginput.allowNew", false) }, allowDuplicates: { type: Boolean, default: () => getDefault("taginput.allowDuplicates", false) }, validateItem: { type: Function, default: () => true }, createItem: { type: Function, default: (item) => item }, checkScroll: { type: Boolean, default: () => getDefault("taginput.checkScroll", false) }, closeable: { type: Boolean, default: () => getDefault("taginput.closeable", true) }, iconPack: { default: () => getDefault("taginput.iconPack") }, icon: { default: () => getDefault("taginput.icon") }, closeIcon: { default: () => getDefault("taginput.closeIcon", "close") }, ariaCloseLabel: { default: () => getDefault("taginput.ariaCloseLabel", "Remove") }, autocomplete: { default: () => getDefault("taginput.autocomplete", "off") }, useHtml5Validation: { type: Boolean, default: () => getDefault("useHtml5Validation", true) }, customValidity: { type: [String, Function], default: void 0 }, teleport: { type: [Boolean, String, Object], default: () => getDefault("taginput.teleport", false) }, rootClass: {}, expandedClass: {}, disabledClass: {}, sizeClass: {}, variantClass: {}, containerClass: {}, itemClass: {}, counterClass: {}, autocompleteClasses: { default: () => getDefault("taginput.autocompleteClasses", {}) } }, { "modelValue": { default: void 0 }, "modelModifiers": {}, "input": { default: "" }, "inputModifiers": {} }), emits: /* @__PURE__ */ mergeModels(["update:model-value", "update:input", "input", "add", "remove", "focus", "blur", "invalid", "icon-click", "icon-right-click", "scroll-start", "scroll-end"], ["update:modelValue", "update:input"]), setup(__props, { expose: __expose, emit: __emit }) { const props = __props; const emits = __emit; const autocompleteRef = useTemplateRef("autocompleteComponent"); const { checkHtml5Validity, setFocus, onFocus, onBlur, onInvalid } = useInputHandler(autocompleteRef, emits, props); const isDropdownActive = ref(false); const selectedItems = useModel(__props, "modelValue"); const inputValue = useModel(__props, "input"); const inputLength = computed(() => inputValue.value.trim().length); const itemsLength = computed(() => { var _a; return ((_a = selectedItems.value) == null ? void 0 : _a.length) || 0; }); const { nextSequence } = useSequentialId(); const groupedOptions = computed(() => { const normalizedOptions = normalizeOptions(props.options, nextSequence); const groupedOptions2 = toOptionsGroup(normalizedOptions, nextSequence()); return groupedOptions2; }); const selectedOptions = computed(() => { if (!selectedItems.value) return []; return selectedItems.value.map((value) => { const option = findOption(groupedOptions, value); if (option) return option; else return { label: String(value), value, key: useId() }; }); }); const hasInput = computed( () => props.maxitems == null || itemsLength.value < Number(props.maxitems) ); watchEffect(() => { if (!hasInput.value) onBlur(new Event("blur")); }); function addItem(item) { var _a; item = item || inputValue.value.trim(); if (item) { const itemToAdd = props.createItem(item); if (!((_a = selectedItems.value) == null ? void 0 : _a.length)) { if (props.validateItem(item)) { selectedItems.value = [itemToAdd]; emits("add", itemToAdd); } } else { const add = !props.allowDuplicates ? !selectedItems.value.includes(itemToAdd) : true; if (add && props.validateItem(item)) { selectedItems.value = [...selectedItems.value, itemToAdd]; emits("add", itemToAdd); } } } requestAnimationFrame(() => { inputValue.value = ""; emits("input", "", new Event("input")); }); } function removeItem(index2, event) { var _a; if (!((_a = selectedItems.value) == null ? void 0 : _a.length)) return; const item = selectedItems.value.at(index2); if (!item) return; selectedItems.value = selectedItems.value.toSpliced(index2, 1); emits("remove", item); if (event) event.stopPropagation(); if (props.openOnFocus && autocompleteRef.value) setFocus(); } function onSelect(option) { if (!option) return; addItem(option); } function onInput(value, event) { emits("input", value == null ? void 0 : value.trim(), event); } function onBackspace() { var _a; if (!((_a = inputValue.value) == null ? void 0 : _a.length) && itemsLength.value > 0) removeItem(itemsLength.value - 1); } function onEnter() { if (props.allowNew && !isDropdownActive.value) addItem(); } const rootClasses = defineClasses( ["rootClass", "o-taginput"], [ "sizeClass", "o-taginput--", computed(() => props.size), computed(() => !!props.size) ], [ "variantClass", "o-taginput--", computed(() => props.variant), computed(() => !!props.variant) ], [ "expandedClass", "o-taginput--expanded", null, computed(() => props.expanded) ], [ "disabledClass", "o-taginput--disabled", null, computed(() => props.disabled) ] ); const containerClasses = defineClasses([ "containerClass", "o-taginput__container" ]); const itemClasses = defineClasses( ["itemClass", "o-taginput__item"], [ "variantClass", "o-taginput__item--", computed(() => props.variant), computed(() => !!props.variant) ] ); const counterClasses = defineClasses(["counterClass", "o-taginput__counter"]); const autocompleteRootClasses = defineClasses([ "autocompleteClasses.rootClass", "o-taginput__autocomplete" ]); const autocompleteInputClasses = defineClasses([ "autocompleteClasses.inputClasses.inputClass", "o-taginput__input" ]); const attrs = useAttrs(); const autocompleteBind = computed(() => ({ ...attrs, "root-class": getActiveClasses(autocompleteRootClasses), "input-classes": { "input-class": getActiveClasses(autocompleteInputClasses) }, ...props.autocompleteClasses })); __expose({ checkHtml5Validity, focus: setFocus, value: selectedItems }); return (_ctx, _cache) => { return openBlock(), createElementBlock("div", { "data-oruga": "taginput", class: normalizeClass(unref(rootClasses)) }, [ createElementVNode("div", { class: normalizeClass(unref(containerClasses)), onFocus: _cache[6] || (_cache[6] = //@ts-ignore (...args) => unref(onFocus) && unref(onFocus)(...args)), onBlur: _cache[7] || (_cache[7] = //@ts-ignore (...args) => unref(onBlur) && unref(onBlur)(...args)) }, [ renderSlot(_ctx.$slots, "selected", { items: selectedItems.value, options: selectedOptions.value, removeItem }, () => [ (openBlock(true), createElementBlock(Fragment, null, renderList(selectedOptions.value, (option, index2) => { return openBlock(), createBlock(_sfc_main$1, { key: option.key, label: option.label, class: normalizeClass(unref(itemClasses)), closeable: _ctx.closeable && !_ctx.disabled, "close-icon": _ctx.closeIcon, "close-icon-pack": _ctx.iconPack, "aria-close-label": _ctx.ariaCloseLabel, onClose: ($event) => removeItem(index2, $event) }, null, 8, ["label", "class", "closeable", "close-icon", "close-icon-pack", "aria-close-label", "onClose"]); }), 128)) ]), withDirectives(createVNode(_sfc_main$2, mergeProps({ ref: "autocompleteComponent", active: isDropdownActive.value, "onUpdate:active": _cache[0] || (_cache[0] = ($event) => isDropdownActive.value = $event), input: inputValue.value, "onUpdate:input": _cache[1] || (_cache[1] = ($event) => inputValue.value = $event) }, autocompleteBind.value, { options: _ctx.options, filter: _ctx.filter, placeholder: _ctx.placeholder, icon: _ctx.icon, "icon-pack": _ctx.iconPack, maxlength: _ctx.maxlength, size: _ctx.size, disabled: _ctx.disabled, autocomplete: _ctx.autocomplete, "open-on-focus": _ctx.openOnFocus, "keep-first": _ctx.keepFirst, "keep-open": _ctx.keepOpen, "check-scroll": _ctx.checkScroll, teleport: _ctx.teleport, "has-counter": false, "use-html5-validation": false, expanded: "", onInput, onFocus: unref(onFocus), onBlur: unref(onBlur), onInvalid: unref(onInvalid), onKeydown: [ withKeys(onEnter, ["enter"]), withKeys(onEnter, ["tab"]), withKeys(onBackspace, ["backspace"]) ], onSelect, onScrollStart: _cache[2] || (_cache[2] = ($event) => _ctx.$emit("scroll-start")), onScrollEnd: _cache[3] || (_cache[3] = ($event) => _ctx.$emit("scroll-end")), onIconClick: _cache[4] || (_cache[4] = ($event) => _ctx.$emit("icon-click", $event)), onIconRightClick: _cache[5] || (_cache[5] = ($event) => _ctx.$emit("icon-right-click", $event)) }), createSlots({ _: 2 }, [ _ctx.$slots.header ? { name: "header", fn: withCtx(() => [ renderSlot(_ctx.$slots, "header") ]), key: "0" } : void 0, _ctx.$slots.default ? { name: "default", fn: withCtx(({ option, index: index2, value }) => [ renderSlot(_ctx.$slots, "default", { option, index: index2, value }) ]), key: "1" } : void 0, _ctx.$slots.empty ? { name: "empty", fn: withCtx(() => [ renderSlot(_ctx.$slots, "empty") ]), key: "2" } : void 0, _ctx.$slots.footer ? { name: "footer", fn: withCtx(() => [ renderSlot(_ctx.$slots, "footer") ]), key: "3" } : void 0 ]), 1040, ["active", "input", "options", "filter", "placeholder", "icon", "icon-pack", "maxlength", "size", "disabled", "autocomplete", "open-on-focus", "keep-first", "keep-open", "check-scroll", "teleport", "onFocus", "onBlur", "onInvalid"]), [ [vShow, hasInput.value] ]) ], 34), _ctx.counter && (_ctx.maxitems || _ctx.maxlength) ? (openBlock(), createElementBlock("small", { key: 0, class: normalizeClass(unref(counterClasses)) }, [ _ctx.maxlength && inputLength.value > 0 ? renderSlot(_ctx.$slots, "counter", { key: 0, items: inputLength.value, total: _ctx.maxlength }, () => [ createTextVNode(toDisplayString(inputLength.value) + " / " + toDisplayString(_ctx.maxlength), 1) ]) : _ctx.maxitems ? renderSlot(_ctx.$slots, "counter", { key: 1, items: itemsLength.value, total: _ctx.maxitems }, () => [ createTextVNode(toDisplayString(itemsLength.value) + " / " + toDisplayString(_ctx.maxitems), 1) ]) : createCommentVNode("", true) ], 2)) : createCommentVNode("", true) ], 2); }; } }); const index = { install(Vue) { registerComponent(Vue, _sfc_main); } }; export { _sfc_main as OTaginput, index as default }; //# sourceMappingURL=taginput.mjs.map