"use strict";
const vue = require("vue");
const index = require("./index-C_bsiScj.js");
const useDefaults = require("./useDefaults-YXpmugKp.js");
const stringUtils = require("./stringUtils-DVq7fDaW.js");
const useId = require("./useId-Dl8Hi5_U.js");
const BCloseButton_vue_vue_type_script_setup_true_lang = require("./BCloseButton.vue_vue_type_script_setup_true_lang-CbUMoMu7.js");
const useColorVariantClasses = require("./useColorVariantClasses-BjkZZDqD.js");
const useStateClass = require("./useStateClass-Bk6-veG2.js");
const index$1 = require("./index-JJEBhaXq.js");
const _hoisted_1$1 = ["id"];
const _sfc_main$1 = /* @__PURE__ */ 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 = __props;
    const props = useDefaults.useDefaults(_props, "BFormTag");
    const emit = __emit;
    const slots = vue.useSlots();
    const computedId = useId.useId(() => props.id);
    const tagText = vue.computed(
      () => ((slots.default?.({})[0].children ?? "").toString() || props.title) ?? ""
    );
    const taglabelId = vue.computed(() => `${computedId.value}taglabel__`);
    const colorClasses = useColorVariantClasses.useColorVariantClasses(props);
    const computedClasses = vue.computed(() => [
      colorClasses.value,
      {
        "rounded-pill": props.pill,
        "disabled": props.disabled
      }
    ]);
    return (_ctx, _cache) => {
      return vue.openBlock(), vue.createBlock(vue.resolveDynamicComponent(vue.unref(props).tag), {
        id: vue.unref(computedId),
        title: tagText.value,
        class: vue.normalizeClass(["badge b-form-tag d-inline-flex align-items-center mw-100", computedClasses.value]),
        "aria-labelledby": taglabelId.value
      }, {
        default: vue.withCtx(() => [
          vue.createElementVNode("span", {
            id: taglabelId.value,
            class: "b-form-tag-content flex-grow-1 text-truncate"
          }, [
            vue.renderSlot(_ctx.$slots, "default", {}, () => [
              vue.createTextVNode(vue.toDisplayString(tagText.value), 1)
            ])
          ], 8, _hoisted_1$1),
          !vue.unref(props).disabled && !vue.unref(props).noRemove ? (vue.openBlock(), vue.createBlock(BCloseButton_vue_vue_type_script_setup_true_lang._sfc_main, {
            key: 0,
            "aria-keyshortcuts": "Delete",
            "aria-label": vue.unref(props).removeLabel,
            class: "b-form-tag-remove",
            "aria-describedby": taglabelId.value,
            "aria-controls": vue.unref(props).id,
            onClick: _cache[0] || (_cache[0] = ($event) => emit("remove", tagText.value))
          }, null, 8, ["aria-label", "aria-describedby", "aria-controls"])) : vue.createCommentVNode("", true)
        ]),
        _: 3
      }, 8, ["id", "title", "class", "aria-labelledby"]);
    };
  }
});
const _hoisted_1 = ["id"];
const _hoisted_2 = ["id", "for", "aria-live"];
const _hoisted_3 = ["id", "aria-live"];
const _hoisted_4 = ["id"];
const _hoisted_5 = ["aria-controls"];
const _hoisted_6 = {
  role: "group",
  class: "d-flex"
};
const _hoisted_7 = ["id", "disabled", "value", "type", "placeholder", "form", "required", "aria-required"];
const _hoisted_8 = ["disabled"];
const _hoisted_9 = ["aria-live"];
const _hoisted_10 = {
  key: 0,
  class: "d-block invalid-feedback"
};
const _hoisted_11 = {
  key: 1,
  class: "form-text text-body-secondary"
};
const _hoisted_12 = {
  key: 2,
  class: "form-text text-body-secondary"
};
const _hoisted_13 = ["name", "value"];
const _sfc_main = /* @__PURE__ */ vue.defineComponent({
  __name: "BFormTags",
  props: /* @__PURE__ */ 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__ */ vue.mergeModels(["blur", "focus", "focusin", "focusout", "tag-state"], ["update:modelValue"]),
  setup(__props, { expose: __expose, emit: __emit }) {
    const _props = __props;
    const props = useDefaults.useDefaults(_props, "BFormTags");
    const emit = __emit;
    const modelValue = vue.useModel(__props, "modelValue");
    const computedId = useId.useId();
    const limitNumber = index$1.useToNumber(() => props.limit ?? Number.NaN);
    const stateClass = useStateClass.useStateClass(() => props.state);
    const input = vue.useTemplateRef("_input");
    const { focused } = index.useFocus(input, {
      initialValue: props.autofocus
    });
    const _inputId = vue.computed(() => props.inputId || `${computedId.value}input__`);
    const tags = vue.ref([...modelValue.value]);
    const inputValue = vue.ref("");
    const shouldRemoveOnDelete = vue.ref(modelValue.value.length > 0);
    const lastRemovedTag = vue.ref("");
    const validTags = vue.ref([]);
    const invalidTags = vue.ref([]);
    const duplicateTags = vue.ref([]);
    index$1.syncRef(modelValue, tags, {
      direction: "ltr",
      transform: {
        ltr: (v) => [...v]
      }
    });
    const computedClasses = vue.computed(() => [
      stateClass.value,
      {
        [`form-control-${props.size}`]: props.size !== "md",
        disabled: props.disabled,
        focus: focused.value
      }
    ]);
    const isDuplicate = vue.computed(() => tags.value.includes(inputValue.value));
    const isInvalid = vue.computed(
      () => inputValue.value === "" ? false : !props.tagValidator(inputValue.value)
    );
    const isLimitReached = vue.computed(() => tags.value.length === limitNumber.value);
    const disableAddButton = vue.computed(() => !isInvalid.value && !isDuplicate.value);
    const onFocusin = (e) => {
      if (props.disabled) {
        const target = e.target;
        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;
      }
    };
    index.onKeyStroke(onKeydown, { target: input });
    const separator = vue.computed(() => {
      if (!props.separator) {
        return;
      }
      return typeof props.separator === "string" ? props.separator : props.separator.join("");
    });
    const separatorRegExp = vue.computed(() => {
      if (!separator.value) {
        return;
      }
      return new RegExp(`[${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 validTags2 = [];
      for (const newTag of newTags) {
        if (newTag === "" || isDuplicate.value || !props.tagValidator(newTag)) {
          continue;
        }
        if (limitNumber.value && isLimitReached.value) {
          break;
        }
        validTags2.push(newTag);
      }
      const newValue = [...modelValue.value, ...validTags2];
      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 vue.openBlock(), vue.createElementBlock("div", {
        id: vue.unref(computedId),
        class: 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))
      }, [
        vue.createElementVNode("output", {
          id: `${vue.unref(computedId)}selected_tags__`,
          class: "visually-hidden",
          for: _inputId.value,
          "aria-live": vue.unref(focused) ? "polite" : "off",
          "aria-atomic": "true",
          "aria-relevant": "additions text"
        }, vue.toDisplayString(tags.value.join(", ")), 9, _hoisted_2),
        vue.createElementVNode("div", {
          id: `${vue.unref(computedId)}removed_tags__`,
          role: "status",
          "aria-live": vue.unref(focused) ? "assertive" : "off",
          "aria-atomic": "true",
          class: "visually-hidden"
        }, " (" + vue.toDisplayString(vue.unref(props).tagRemovedLabel) + ") " + vue.toDisplayString(lastRemovedTag.value), 9, _hoisted_3),
        vue.renderSlot(_ctx.$slots, "default", {
          addButtonText: vue.unref(props).addButtonText,
          addButtonVariant: vue.unref(props).addButtonVariant,
          addTag,
          disableAddButton: disableAddButton.value,
          disabled: vue.unref(props).disabled,
          duplicateTagText: vue.unref(props).duplicateTagText,
          duplicateTags: duplicateTags.value,
          form: vue.unref(props).form,
          inputAttrs: {
            ...vue.unref(props).inputAttrs,
            disabled: vue.unref(props).disabled,
            form: vue.unref(props).form,
            id: _inputId.value,
            value: inputValue.value
          },
          inputClass: vue.unref(props).inputClass,
          inputHandlers: {
            input: onInput,
            keydown: onKeydown,
            change: onChange
          },
          inputId: _inputId.value,
          inputType: vue.unref(props).inputType,
          invalidTagText: vue.unref(props).invalidTagText,
          invalidTags: invalidTags.value,
          isDuplicate: isDuplicate.value,
          isInvalid: isInvalid.value,
          isLimitReached: isLimitReached.value,
          limitTagsText: vue.unref(props).limitTagsText,
          limit: vue.unref(limitNumber),
          noTagRemove: vue.unref(props).noTagRemove,
          placeholder: vue.unref(props).placeholder,
          removeTag,
          required: vue.unref(props).required,
          separator: vue.unref(props).separator,
          size: vue.unref(props).size,
          state: vue.unref(props).state,
          tagClass: vue.unref(props).tagClass,
          tagPills: vue.unref(props).tagPills,
          tagRemoveLabel: vue.unref(props).tagRemoveLabel,
          tagVariant: vue.unref(props).tagVariant,
          tags: tags.value
        }, () => [
          vue.createElementVNode("ul", {
            id: `${vue.unref(computedId)}tag_list__`,
            class: "b-form-tags-list list-unstyled mb-0 d-flex flex-wrap align-items-center"
          }, [
            (vue.openBlock(true), vue.createElementBlock(vue.Fragment, null, vue.renderList(tags.value, (tag, index2) => {
              return vue.renderSlot(_ctx.$slots, "tag", {
                key: index2,
                tag,
                tagClass: vue.unref(props).tagClass,
                tagVariant: vue.unref(props).tagVariant,
                tagPills: vue.unref(props).tagPills,
                removeTag
              }, () => [
                (vue.openBlock(), vue.createBlock(_sfc_main$1, {
                  key: tag,
                  class: vue.normalizeClass(vue.unref(props).tagClass),
                  tag: "li",
                  variant: vue.unref(props).tagVariant,
                  pill: vue.unref(props).tagPills,
                  "no-remove": vue.unref(props).noTagRemove,
                  disabled: vue.unref(props).disabled,
                  onRemove: removeTag
                }, {
                  default: vue.withCtx(() => [
                    vue.createTextVNode(vue.toDisplayString(tag), 1)
                  ]),
                  _: 2
                }, 1032, ["class", "variant", "pill", "no-remove", "disabled"]))
              ]);
            }), 128)),
            vue.createElementVNode("li", {
              role: "none",
              "aria-live": "off",
              class: "b-from-tags-field flex-grow-1",
              "aria-controls": `${vue.unref(computedId)}tag_list__`
            }, [
              vue.createElementVNode("div", _hoisted_6, [
                vue.createElementVNode("input", vue.mergeProps({
                  id: _inputId.value,
                  ref: "_input",
                  disabled: vue.unref(props).disabled,
                  value: inputValue.value,
                  type: vue.unref(props).inputType,
                  placeholder: 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" }
                }, vue.unref(props).inputAttrs, {
                  form: vue.unref(props).form,
                  required: vue.unref(props).required || void 0,
                  "aria-required": vue.unref(props).required || void 0,
                  onInput,
                  onChange,
                  onFocus,
                  onBlur
                }), null, 16, _hoisted_7),
                disableAddButton.value ? (vue.openBlock(), vue.createElementBlock("button", {
                  key: 0,
                  type: "button",
                  class: vue.normalizeClass(["btn b-form-tags-button py-0", [
                    __props.inputClass,
                    {
                      [`btn-${vue.unref(props).addButtonVariant}`]: vue.unref(props).addButtonVariant !== null,
                      "disabled invisible": inputValue.value.length === 0
                    }
                  ]]),
                  style: { "font-size": "90%" },
                  disabled: vue.unref(props).disabled || inputValue.value.length === 0 || isLimitReached.value,
                  onClick: _cache[0] || (_cache[0] = ($event) => addTag(inputValue.value))
                }, [
                  vue.renderSlot(_ctx.$slots, "add-button-text", {}, () => [
                    vue.createTextVNode(vue.toDisplayString(vue.unref(props).addButtonText), 1)
                  ])
                ], 10, _hoisted_8)) : vue.createCommentVNode("", true)
              ])
            ], 8, _hoisted_5)
          ], 8, _hoisted_4),
          vue.createElementVNode("div", {
            "aria-live": vue.unref(props).feedbackAriaLive,
            "aria-atomic": "true"
          }, [
            isInvalid.value ? (vue.openBlock(), vue.createElementBlock("div", _hoisted_10, vue.toDisplayString(vue.unref(props).invalidTagText) + ": " + vue.toDisplayString(inputValue.value), 1)) : vue.createCommentVNode("", true),
            isDuplicate.value ? (vue.openBlock(), vue.createElementBlock("small", _hoisted_11, vue.toDisplayString(vue.unref(props).duplicateTagText) + ": " + vue.toDisplayString(inputValue.value), 1)) : vue.createCommentVNode("", true),
            tags.value.length === vue.unref(props).limit ? (vue.openBlock(), vue.createElementBlock("small", _hoisted_12, vue.toDisplayString(vue.unref(props).limitTagsText), 1)) : vue.createCommentVNode("", true)
          ], 8, _hoisted_9)
        ]),
        vue.unref(props).name ? (vue.openBlock(true), vue.createElementBlock(vue.Fragment, { key: 0 }, vue.renderList(tags.value, (tag, index2) => {
          return vue.openBlock(), vue.createElementBlock("input", {
            key: index2,
            type: "hidden",
            name: vue.unref(props).name,
            value: tag
          }, null, 8, _hoisted_13);
        }), 128)) : vue.createCommentVNode("", true)
      ], 42, _hoisted_1);
    };
  }
});
exports._sfc_main = _sfc_main;
exports._sfc_main$1 = _sfc_main$1;
//# sourceMappingURL=BFormTags.vue_vue_type_script_setup_true_lang-BykPa-UG.js.map
