UNPKG

bootstrap-vue-next

Version:

Seamless integration of Vue 3, Bootstrap 5, and TypeScript for modern, type-safe UI development

501 lines (500 loc) 18.5 kB
require("./chunk-CoQrYLCe.js"); const require_dist = require("./dist-B_c893QG.js"); const require_useDefaults = require("./useDefaults-DsLf4iRY.js"); const require_useId = require("./useId-DHrBgM7P.js"); const require_useColorVariantClasses = require("./useColorVariantClasses-CEfOwjPv.js"); const require_stringUtils = require("./stringUtils-BwKOASdU.js"); const require_BCloseButton = require("./BCloseButton-CN__Jjcj.js"); const require_useStateClass = require("./useStateClass-0b-hPufa.js"); let vue = require("vue"); //#region src/components/BFormTags/BFormTag.vue?vue&type=script&setup=true&lang.ts var _hoisted_1$1 = ["id"]; //#endregion //#region src/components/BFormTags/BFormTag.vue var BFormTag_default = /* @__PURE__ */ (0, vue.defineComponent)({ __name: "BFormTag", props: { disabled: { type: Boolean, default: false }, id: { default: void 0 }, noRemove: { type: Boolean, default: false }, pill: { type: Boolean, default: false }, removeLabel: { default: "Remove tag" }, tag: { default: "span" }, title: { default: void 0 }, variant: { default: "secondary" } }, emits: ["remove"], setup(__props, { emit: __emit }) { const props = require_useDefaults.useDefaults(__props, "BFormTag"); const emit = __emit; const slots = (0, vue.useSlots)(); const computedId = require_useId.useId(() => props.id); const tagText = (0, vue.computed)(() => ((slots.default?.({})[0].children ?? "").toString() || props.title) ?? ""); const taglabelId = (0, vue.computed)(() => `${computedId.value}taglabel__`); const colorClasses = require_useColorVariantClasses.useColorVariantClasses(props); const computedClasses = (0, vue.computed)(() => [colorClasses.value, { "rounded-pill": props.pill, "disabled": props.disabled }]); return (_ctx, _cache) => { return (0, vue.openBlock)(), (0, vue.createBlock)((0, vue.resolveDynamicComponent)((0, vue.unref)(props).tag), { id: (0, vue.unref)(computedId), title: tagText.value, class: (0, vue.normalizeClass)(["badge b-form-tag d-inline-flex align-items-center mw-100", computedClasses.value]), "aria-labelledby": taglabelId.value }, { default: (0, vue.withCtx)(() => [(0, vue.createElementVNode)("span", { id: taglabelId.value, class: "b-form-tag-content flex-grow-1 text-truncate" }, [(0, vue.renderSlot)(_ctx.$slots, "default", {}, () => [(0, vue.createTextVNode)((0, vue.toDisplayString)(tagText.value), 1)])], 8, _hoisted_1$1), !(0, vue.unref)(props).disabled && !(0, vue.unref)(props).noRemove ? ((0, vue.openBlock)(), (0, vue.createBlock)(require_BCloseButton.BCloseButton_default, { key: 0, "aria-keyshortcuts": "Delete", "aria-label": (0, vue.unref)(props).removeLabel, class: "b-form-tag-remove", "aria-describedby": taglabelId.value, "aria-controls": (0, vue.unref)(props).id, onClick: _cache[0] || (_cache[0] = ($event) => emit("remove", tagText.value)) }, null, 8, [ "aria-label", "aria-describedby", "aria-controls" ])) : (0, vue.createCommentVNode)("", true)]), _: 3 }, 8, [ "id", "title", "class", "aria-labelledby" ]); }; } }); //#endregion //#region src/components/BFormTags/BFormTags.vue?vue&type=script&setup=true&lang.ts var _hoisted_1 = ["id"]; var _hoisted_2 = [ "id", "for", "aria-live" ]; var _hoisted_3 = ["id", "aria-live"]; var _hoisted_4 = ["id"]; var _hoisted_5 = ["aria-controls"]; var _hoisted_6 = { role: "group", class: "d-flex" }; var _hoisted_7 = [ "id", "disabled", "value", "type", "placeholder", "form", "required", "aria-required" ]; var _hoisted_8 = ["disabled"]; var _hoisted_9 = ["aria-live"]; var _hoisted_10 = { key: 0, class: "d-block invalid-feedback" }; var _hoisted_11 = { key: 1, class: "form-text text-body-secondary" }; var _hoisted_12 = { key: 2, class: "form-text text-body-secondary" }; var _hoisted_13 = ["name", "value"]; //#endregion //#region src/components/BFormTags/BFormTags.vue var BFormTags_default = /* @__PURE__ */ (0, vue.defineComponent)({ __name: "BFormTags", props: /* @__PURE__ */ (0, vue.mergeModels)({ addButtonText: { default: "Add" }, addButtonVariant: { default: "outline-secondary" }, addOnChange: { type: Boolean, default: false }, autofocus: { type: Boolean, default: false }, disabled: { type: Boolean, default: false }, duplicateTagText: { default: "Duplicate tag(s)" }, feedbackAriaLive: { default: "assertive" }, form: { default: void 0 }, ignoreInputFocusSelector: { default: () => [ ".b-form-tag", "button", "input", "select" ] }, inputAttrs: { default: void 0 }, inputClass: { default: void 0 }, inputId: { default: void 0 }, inputType: { default: "text" }, invalidTagText: { default: "Invalid tag(s)" }, limit: { default: void 0 }, limitTagsText: { default: "Tag limit reached" }, name: { default: void 0 }, noAddOnEnter: { type: Boolean, default: false }, noOuterFocus: { type: Boolean, default: false }, noTagRemove: { type: Boolean, default: false }, placeholder: { default: "Add tag..." }, removeOnDelete: { type: Boolean, default: false }, required: { type: Boolean, default: false }, separator: { default: void 0 }, size: { default: "md" }, state: { type: [Boolean, null], default: null }, tagClass: { default: void 0 }, tagPills: { type: Boolean, default: false }, tagRemoveLabel: { default: void 0 }, tagRemovedLabel: { default: "Tag removed" }, tagValidator: { type: Function, default: () => true }, tagVariant: { default: "secondary" } }, { "modelValue": { default: () => [] }, "modelModifiers": {} }), emits: /* @__PURE__ */ (0, vue.mergeModels)([ "blur", "focus", "focusin", "focusout", "tag-state" ], ["update:modelValue"]), setup(__props, { expose: __expose, emit: __emit }) { const props = require_useDefaults.useDefaults(__props, "BFormTags"); const emit = __emit; const modelValue = (0, vue.useModel)(__props, "modelValue"); const computedId = require_useId.useId(); const limitNumber = require_dist.useToNumber(() => props.limit ?? NaN); const stateClass = require_useStateClass.useStateClass(() => props.state); const input = (0, vue.useTemplateRef)("_input"); const { focused } = require_dist.useFocus(input, { initialValue: props.autofocus }); const _inputId = (0, vue.computed)(() => props.inputId || `${computedId.value}input__`); const tags = (0, vue.ref)([...modelValue.value]); const inputValue = (0, vue.ref)(""); const shouldRemoveOnDelete = (0, vue.ref)(modelValue.value.length > 0); const lastRemovedTag = (0, vue.ref)(""); const validTags = (0, vue.ref)([]); const invalidTags = (0, vue.ref)([]); const duplicateTags = (0, vue.ref)([]); require_dist.syncRef(modelValue, tags, { direction: "ltr", transform: { ltr: (v) => [...v] } }); const computedClasses = (0, vue.computed)(() => [stateClass.value, { [`form-control-${props.size}`]: props.size !== "md", disabled: props.disabled, focus: focused.value }]); const isDuplicate = (0, vue.computed)(() => tags.value.includes(inputValue.value)); const isInvalid = (0, vue.computed)(() => inputValue.value === "" ? false : !props.tagValidator(inputValue.value)); const isLimitReached = (0, vue.computed)(() => tags.value.length === limitNumber.value); const disableAddButton = (0, vue.computed)(() => !isInvalid.value && !isDuplicate.value); const onFocusin = (e) => { if (props.disabled) { e.target.blur(); return; } emit("focusin", e); }; const onClick = (e) => { if (props.disabled || props.noOuterFocus) return; const { target } = e; const ignoreSelectors = props.ignoreInputFocusSelector; if (ignoreSelectors && target instanceof Element) { const selector = typeof ignoreSelectors === "string" ? ignoreSelectors : ignoreSelectors.join(","); if (selector && target.closest(selector)) return; } focused.value = true; }; const onFocus = (e) => { if (props.disabled || props.noOuterFocus) return; focused.value = true; emit("focus", e); }; const onBlur = (e) => { focused.value = false; emit("blur", e); }; const onInput = (e) => { const value = typeof e === "string" ? e : e.target.value; shouldRemoveOnDelete.value = false; if (props.separator?.includes(value.charAt(0)) && value.length > 0) { if (input.value) input.value.value = ""; return; } inputValue.value = value; if (props.separator?.includes(value.charAt(value.length - 1))) { addTag(value.slice(0, value.length - 1)); return; } validTags.value = props.tagValidator(value) && !isDuplicate.value ? [value] : []; invalidTags.value = props.tagValidator(value) ? [] : [value]; duplicateTags.value = isDuplicate.value ? [value] : []; emit("tag-state", validTags.value, invalidTags.value, duplicateTags.value); }; const onChange = (e) => { if (props.addOnChange) { onInput(e); if (!isDuplicate.value) addTag(inputValue.value); } }; const onKeydown = (e) => { if ((e.key === "Enter" || e.code === "NumpadEnter") && !props.noAddOnEnter) { addTag(inputValue.value); return; } if ((e.key === "Backspace" || e.key === "Delete") && props.removeOnDelete && inputValue.value === "" && shouldRemoveOnDelete.value && tags.value.length > 0) removeTag(tags.value[tags.value.length - 1]); else shouldRemoveOnDelete.value = true; }; require_dist.onKeyStroke(onKeydown, { target: input }); const separator = (0, vue.computed)(() => { if (!props.separator) return; return typeof props.separator === "string" ? props.separator : props.separator.join(""); }); const separatorRegExp = (0, vue.computed)(() => { if (!separator.value) return; return new RegExp(`[${require_stringUtils.escapeRegExpChars(separator.value)}]+`); }); const addTag = (tag) => { tag = (tag ?? inputValue.value).trim(); const newTags = separatorRegExp.value ? tag.split(separatorRegExp.value).map((t) => t.trim()) : [tag]; const validTags = []; for (const newTag of newTags) { if (newTag === "" || isDuplicate.value || !props.tagValidator(newTag)) continue; if (limitNumber.value && isLimitReached.value) break; validTags.push(newTag); } const newValue = [...modelValue.value, ...validTags]; inputValue.value = ""; shouldRemoveOnDelete.value = true; modelValue.value = newValue; focused.value = true; }; const removeTag = (tag) => { const tagIndex = tags.value.indexOf(tag?.toString() ?? ""); if (tagIndex === -1) return; lastRemovedTag.value = tags.value.splice(tagIndex, 1).toString(); modelValue.value = tags.value; }; __expose({ blur: () => { focused.value = false; }, element: input, focus: () => { focused.value = true; }, inputValue }); return (_ctx, _cache) => { return (0, vue.openBlock)(), (0, vue.createElementBlock)("div", { id: (0, vue.unref)(computedId), class: (0, vue.normalizeClass)(["b-form-tags form-control h-auto", computedClasses.value]), role: "group", tabindex: "-1", onClick, onFocusin, onFocusout: _cache[1] || (_cache[1] = ($event) => emit("focusout", $event)) }, [ (0, vue.createElementVNode)("output", { id: `${(0, vue.unref)(computedId)}selected_tags__`, class: "visually-hidden", for: _inputId.value, "aria-live": (0, vue.unref)(focused) ? "polite" : "off", "aria-atomic": "true", "aria-relevant": "additions text" }, (0, vue.toDisplayString)(tags.value.join(", ")), 9, _hoisted_2), (0, vue.createElementVNode)("div", { id: `${(0, vue.unref)(computedId)}removed_tags__`, role: "status", "aria-live": (0, vue.unref)(focused) ? "assertive" : "off", "aria-atomic": "true", class: "visually-hidden" }, " (" + (0, vue.toDisplayString)((0, vue.unref)(props).tagRemovedLabel) + ") " + (0, vue.toDisplayString)(lastRemovedTag.value), 9, _hoisted_3), (0, vue.renderSlot)(_ctx.$slots, "default", { addButtonText: (0, vue.unref)(props).addButtonText, addButtonVariant: (0, vue.unref)(props).addButtonVariant, addTag, disableAddButton: disableAddButton.value, disabled: (0, vue.unref)(props).disabled, duplicateTagText: (0, vue.unref)(props).duplicateTagText, duplicateTags: duplicateTags.value, form: (0, vue.unref)(props).form, inputAttrs: { ...(0, vue.unref)(props).inputAttrs, disabled: (0, vue.unref)(props).disabled, form: (0, vue.unref)(props).form, id: _inputId.value, value: inputValue.value }, inputClass: (0, vue.unref)(props).inputClass, inputHandlers: { input: onInput, keydown: onKeydown, change: onChange }, inputId: _inputId.value, inputType: (0, vue.unref)(props).inputType, invalidTagText: (0, vue.unref)(props).invalidTagText, invalidTags: invalidTags.value, isDuplicate: isDuplicate.value, isInvalid: isInvalid.value, isLimitReached: isLimitReached.value, limitTagsText: (0, vue.unref)(props).limitTagsText, limit: (0, vue.unref)(limitNumber), noTagRemove: (0, vue.unref)(props).noTagRemove, placeholder: (0, vue.unref)(props).placeholder, removeTag, required: (0, vue.unref)(props).required, separator: (0, vue.unref)(props).separator, size: (0, vue.unref)(props).size, state: (0, vue.unref)(props).state, tagClass: (0, vue.unref)(props).tagClass, tagPills: (0, vue.unref)(props).tagPills, tagRemoveLabel: (0, vue.unref)(props).tagRemoveLabel, tagVariant: (0, vue.unref)(props).tagVariant, tags: tags.value }, () => [(0, vue.createElementVNode)("ul", { id: `${(0, vue.unref)(computedId)}tag_list__`, class: "b-form-tags-list list-unstyled mb-0 d-flex flex-wrap align-items-center" }, [((0, vue.openBlock)(true), (0, vue.createElementBlock)(vue.Fragment, null, (0, vue.renderList)(tags.value, (tag, index) => { return (0, vue.renderSlot)(_ctx.$slots, "tag", { key: index, tag, tagClass: (0, vue.unref)(props).tagClass, tagVariant: (0, vue.unref)(props).tagVariant, tagPills: (0, vue.unref)(props).tagPills, removeTag }, () => [((0, vue.openBlock)(), (0, vue.createBlock)(BFormTag_default, { key: tag, class: (0, vue.normalizeClass)((0, vue.unref)(props).tagClass), tag: "li", variant: (0, vue.unref)(props).tagVariant, pill: (0, vue.unref)(props).tagPills, "no-remove": (0, vue.unref)(props).noTagRemove, disabled: (0, vue.unref)(props).disabled, onRemove: removeTag }, { default: (0, vue.withCtx)(() => [(0, vue.createTextVNode)((0, vue.toDisplayString)(tag), 1)]), _: 2 }, 1032, [ "class", "variant", "pill", "no-remove", "disabled" ]))]); }), 128)), (0, vue.createElementVNode)("li", { role: "none", "aria-live": "off", class: "b-from-tags-field flex-grow-1", "aria-controls": `${(0, vue.unref)(computedId)}tag_list__` }, [(0, vue.createElementVNode)("div", _hoisted_6, [(0, vue.createElementVNode)("input", (0, vue.mergeProps)({ id: _inputId.value, ref: "_input", disabled: (0, vue.unref)(props).disabled, value: inputValue.value, type: (0, vue.unref)(props).inputType, placeholder: (0, vue.unref)(props).placeholder, class: "b-form-tags-input w-100 flex-grow-1 p-0 m-0 bg-transparent border-0", style: { "outline": "currentcolor none 0px", "min-width": "5rem" } }, (0, vue.unref)(props).inputAttrs, { form: (0, vue.unref)(props).form, required: (0, vue.unref)(props).required || void 0, "aria-required": (0, vue.unref)(props).required || void 0, onInput, onChange, onFocus, onBlur }), null, 16, _hoisted_7), disableAddButton.value ? ((0, vue.openBlock)(), (0, vue.createElementBlock)("button", { key: 0, type: "button", class: (0, vue.normalizeClass)(["btn b-form-tags-button py-0", [__props.inputClass, { [`btn-${(0, vue.unref)(props).addButtonVariant}`]: (0, vue.unref)(props).addButtonVariant !== null, "disabled invisible": inputValue.value.length === 0 }]]), style: { "font-size": "90%" }, disabled: (0, vue.unref)(props).disabled || inputValue.value.length === 0 || isLimitReached.value, onClick: _cache[0] || (_cache[0] = ($event) => addTag(inputValue.value)) }, [(0, vue.renderSlot)(_ctx.$slots, "add-button-text", {}, () => [(0, vue.createTextVNode)((0, vue.toDisplayString)((0, vue.unref)(props).addButtonText), 1)])], 10, _hoisted_8)) : (0, vue.createCommentVNode)("", true)])], 8, _hoisted_5)], 8, _hoisted_4), (0, vue.createElementVNode)("div", { "aria-live": (0, vue.unref)(props).feedbackAriaLive, "aria-atomic": "true" }, [ isInvalid.value ? ((0, vue.openBlock)(), (0, vue.createElementBlock)("div", _hoisted_10, (0, vue.toDisplayString)((0, vue.unref)(props).invalidTagText) + ": " + (0, vue.toDisplayString)(inputValue.value), 1)) : (0, vue.createCommentVNode)("", true), isDuplicate.value ? ((0, vue.openBlock)(), (0, vue.createElementBlock)("small", _hoisted_11, (0, vue.toDisplayString)((0, vue.unref)(props).duplicateTagText) + ": " + (0, vue.toDisplayString)(inputValue.value), 1)) : (0, vue.createCommentVNode)("", true), tags.value.length === (0, vue.unref)(props).limit ? ((0, vue.openBlock)(), (0, vue.createElementBlock)("small", _hoisted_12, (0, vue.toDisplayString)((0, vue.unref)(props).limitTagsText), 1)) : (0, vue.createCommentVNode)("", true) ], 8, _hoisted_9)]), (0, vue.unref)(props).name ? ((0, vue.openBlock)(true), (0, vue.createElementBlock)(vue.Fragment, { key: 0 }, (0, vue.renderList)(tags.value, (tag, index) => { return (0, vue.openBlock)(), (0, vue.createElementBlock)("input", { key: index, type: "hidden", name: (0, vue.unref)(props).name, value: tag }, null, 8, _hoisted_13); }), 128)) : (0, vue.createCommentVNode)("", true) ], 42, _hoisted_1); }; } }); //#endregion Object.defineProperty(exports, "BFormTag_default", { enumerable: true, get: function() { return BFormTag_default; } }); Object.defineProperty(exports, "BFormTags_default", { enumerable: true, get: function() { return BFormTags_default; } }); //# sourceMappingURL=BFormTags-BUoQXBA9.js.map