UNPKG

bootstrap-vue-next

Version:

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

1 lines 37 kB
{"version":3,"file":"BFormTags-Cobh04P9.mjs","names":[],"sources":["../src/components/BFormTags/BFormTag.vue","../src/components/BFormTags/BFormTag.vue","../src/components/BFormTags/BFormTags.vue","../src/components/BFormTags/BFormTags.vue"],"sourcesContent":["<template>\n <component\n :is=\"props.tag\"\n :id=\"computedId\"\n :title=\"tagText\"\n class=\"badge b-form-tag d-inline-flex align-items-center mw-100\"\n :class=\"computedClasses\"\n :aria-labelledby=\"taglabelId\"\n >\n <span :id=\"taglabelId\" class=\"b-form-tag-content flex-grow-1 text-truncate\">\n <slot>{{ tagText }}</slot>\n </span>\n <BCloseButton\n v-if=\"!props.disabled && !props.noRemove\"\n aria-keyshortcuts=\"Delete\"\n :aria-label=\"props.removeLabel\"\n class=\"b-form-tag-remove\"\n :aria-describedby=\"taglabelId\"\n :aria-controls=\"props.id\"\n @click=\"emit('remove', tagText)\"\n />\n </component>\n</template>\n\n<script setup lang=\"ts\">\nimport {computed} from 'vue'\nimport {useDefaults} from '../../composables/useDefaults'\nimport {useId} from '../../composables/useId'\nimport type {BFormTagProps} from '../../types/ComponentProps'\nimport BCloseButton from '../BButton/BCloseButton.vue'\nimport {useColorVariantClasses} from '../../composables/useColorVariantClasses'\nimport type {BFormTagEmits, BFormTagSlots} from '../../types'\n\nconst _props = withDefaults(defineProps<BFormTagProps>(), {\n disabled: false,\n id: undefined,\n noRemove: false,\n pill: false,\n removeLabel: 'Remove tag',\n tag: 'span',\n title: undefined,\n variant: 'secondary',\n})\nconst props = useDefaults(_props, 'BFormTag')\nconst emit = defineEmits<BFormTagEmits>()\nconst slots = defineSlots<BFormTagSlots>()\n\nconst computedId = useId(() => props.id)\n\nconst tagText = computed(\n () => ((slots.default?.({})[0].children ?? '').toString() || props.title) ?? ''\n)\nconst taglabelId = computed(() => `${computedId.value}taglabel__`)\n\nconst colorClasses = useColorVariantClasses(props)\nconst computedClasses = computed(() => [\n colorClasses.value,\n {\n 'rounded-pill': props.pill,\n 'disabled': props.disabled,\n },\n])\n</script>\n","<template>\n <component\n :is=\"props.tag\"\n :id=\"computedId\"\n :title=\"tagText\"\n class=\"badge b-form-tag d-inline-flex align-items-center mw-100\"\n :class=\"computedClasses\"\n :aria-labelledby=\"taglabelId\"\n >\n <span :id=\"taglabelId\" class=\"b-form-tag-content flex-grow-1 text-truncate\">\n <slot>{{ tagText }}</slot>\n </span>\n <BCloseButton\n v-if=\"!props.disabled && !props.noRemove\"\n aria-keyshortcuts=\"Delete\"\n :aria-label=\"props.removeLabel\"\n class=\"b-form-tag-remove\"\n :aria-describedby=\"taglabelId\"\n :aria-controls=\"props.id\"\n @click=\"emit('remove', tagText)\"\n />\n </component>\n</template>\n\n<script setup lang=\"ts\">\nimport {computed} from 'vue'\nimport {useDefaults} from '../../composables/useDefaults'\nimport {useId} from '../../composables/useId'\nimport type {BFormTagProps} from '../../types/ComponentProps'\nimport BCloseButton from '../BButton/BCloseButton.vue'\nimport {useColorVariantClasses} from '../../composables/useColorVariantClasses'\nimport type {BFormTagEmits, BFormTagSlots} from '../../types'\n\nconst _props = withDefaults(defineProps<BFormTagProps>(), {\n disabled: false,\n id: undefined,\n noRemove: false,\n pill: false,\n removeLabel: 'Remove tag',\n tag: 'span',\n title: undefined,\n variant: 'secondary',\n})\nconst props = useDefaults(_props, 'BFormTag')\nconst emit = defineEmits<BFormTagEmits>()\nconst slots = defineSlots<BFormTagSlots>()\n\nconst computedId = useId(() => props.id)\n\nconst tagText = computed(\n () => ((slots.default?.({})[0].children ?? '').toString() || props.title) ?? ''\n)\nconst taglabelId = computed(() => `${computedId.value}taglabel__`)\n\nconst colorClasses = useColorVariantClasses(props)\nconst computedClasses = computed(() => [\n colorClasses.value,\n {\n 'rounded-pill': props.pill,\n 'disabled': props.disabled,\n },\n])\n</script>\n","<template>\n <div\n :id=\"computedId\"\n class=\"b-form-tags form-control h-auto\"\n :class=\"computedClasses\"\n role=\"group\"\n tabindex=\"-1\"\n @click=\"onClick\"\n @focusin=\"onFocusin\"\n @focusout=\"emit('focusout', $event)\"\n >\n <output\n :id=\"`${computedId}selected_tags__`\"\n class=\"visually-hidden\"\n :for=\"_inputId\"\n :aria-live=\"focused ? 'polite' : 'off'\"\n aria-atomic=\"true\"\n aria-relevant=\"additions text\"\n >{{ tags.join(', ') }}</output\n >\n <div\n :id=\"`${computedId}removed_tags__`\"\n role=\"status\"\n :aria-live=\"focused ? 'assertive' : 'off'\"\n aria-atomic=\"true\"\n class=\"visually-hidden\"\n >\n ({{ props.tagRemovedLabel }}) {{ lastRemovedTag }}\n </div>\n\n <slot\n :add-button-text=\"props.addButtonText\"\n :add-button-variant=\"props.addButtonVariant\"\n :add-tag\n :disable-add-button=\"disableAddButton\"\n :disabled=\"props.disabled\"\n :duplicate-tag-text=\"props.duplicateTagText\"\n :duplicate-tags=\"duplicateTags\"\n :form=\"props.form\"\n :input-attrs=\"{\n ...props.inputAttrs,\n disabled: props.disabled,\n form: props.form,\n id: _inputId,\n value: inputValue,\n }\"\n :input-class=\"props.inputClass\"\n :input-handlers=\"{\n input: onInput,\n keydown: onKeydown,\n change: onChange,\n }\"\n :input-id=\"_inputId\"\n :input-type=\"props.inputType\"\n :invalid-tag-text=\"props.invalidTagText\"\n :invalid-tags\n :is-duplicate\n :is-invalid\n :is-limit-reached=\"isLimitReached\"\n :limit-tags-text=\"props.limitTagsText\"\n :limit=\"limitNumber\"\n :no-tag-remove=\"props.noTagRemove\"\n :placeholder=\"props.placeholder\"\n :remove-tag\n :required=\"props.required\"\n :separator=\"props.separator\"\n :size=\"props.size\"\n :state=\"props.state\"\n :tag-class=\"props.tagClass\"\n :tag-pills=\"props.tagPills\"\n :tag-remove-label=\"props.tagRemoveLabel\"\n :tag-variant=\"props.tagVariant\"\n :tags\n >\n <ul\n :id=\"`${computedId}tag_list__`\"\n class=\"b-form-tags-list list-unstyled mb-0 d-flex flex-wrap align-items-center\"\n >\n <template v-for=\"(tag, index) in tags\" :key=\"index\">\n <slot\n name=\"tag\"\n :tag=\"tag\"\n :tag-class=\"props.tagClass\"\n :tag-variant=\"props.tagVariant\"\n :tag-pills=\"props.tagPills\"\n :remove-tag=\"removeTag\"\n >\n <BFormTag\n :key=\"tag\"\n :class=\"props.tagClass\"\n tag=\"li\"\n :variant=\"props.tagVariant\"\n :pill=\"props.tagPills\"\n :no-remove=\"props.noTagRemove\"\n :disabled=\"props.disabled\"\n @remove=\"removeTag\"\n >{{ tag }}</BFormTag\n >\n </slot>\n </template>\n <li\n role=\"none\"\n aria-live=\"off\"\n class=\"b-from-tags-field flex-grow-1\"\n :aria-controls=\"`${computedId}tag_list__`\"\n >\n <div role=\"group\" class=\"d-flex\">\n <input\n :id=\"_inputId\"\n ref=\"_input\"\n :disabled=\"props.disabled\"\n :value=\"inputValue\"\n :type=\"props.inputType\"\n :placeholder=\"props.placeholder\"\n class=\"b-form-tags-input w-100 flex-grow-1 p-0 m-0 bg-transparent border-0\"\n style=\"outline: currentcolor none 0px; min-width: 5rem\"\n v-bind=\"props.inputAttrs\"\n :form=\"props.form\"\n :required=\"props.required || undefined\"\n :aria-required=\"props.required || undefined\"\n @input=\"onInput\"\n @change=\"onChange\"\n @focus=\"onFocus\"\n @blur=\"onBlur\"\n />\n <button\n v-if=\"disableAddButton\"\n type=\"button\"\n class=\"btn b-form-tags-button py-0\"\n :class=\"[\n inputClass,\n {\n [`btn-${props.addButtonVariant}`]: props.addButtonVariant !== null,\n 'disabled invisible': inputValue.length === 0,\n },\n ]\"\n style=\"font-size: 90%\"\n :disabled=\"props.disabled || inputValue.length === 0 || isLimitReached\"\n @click=\"addTag(inputValue)\"\n >\n <slot name=\"add-button-text\">{{ props.addButtonText }}</slot>\n </button>\n </div>\n </li>\n </ul>\n <div :aria-live=\"props.feedbackAriaLive\" aria-atomic=\"true\">\n <div v-if=\"isInvalid\" class=\"d-block invalid-feedback\">\n {{ props.invalidTagText }}: {{ inputValue }}\n </div>\n <small v-if=\"isDuplicate\" class=\"form-text text-body-secondary\"\n >{{ props.duplicateTagText }}: {{ inputValue }}</small\n >\n <small v-if=\"tags.length === props.limit\" class=\"form-text text-body-secondary\">\n {{ props.limitTagsText }}</small\n >\n </div>\n </slot>\n <template v-if=\"props.name\">\n <input\n v-for=\"(tag, index) in tags\"\n :key=\"index\"\n type=\"hidden\"\n :name=\"props.name\"\n :value=\"tag\"\n />\n </template>\n </div>\n</template>\n\n<script setup lang=\"ts\">\nimport {onKeyStroke, syncRef, useFocus, useToNumber} from '@vueuse/core'\nimport {computed, ref, useTemplateRef} from 'vue'\nimport {useDefaults} from '../../composables/useDefaults'\nimport type {BFormTagsProps} from '../../types/ComponentProps'\nimport {escapeRegExpChars} from '../../utils/stringUtils'\nimport BFormTag from './BFormTag.vue'\nimport {useId} from '../../composables/useId'\nimport {useStateClass} from '../../composables/useStateClass'\nimport type {BFormTagsEmits, BFormTagsSlots} from '../../types'\n\nconst _props = withDefaults(defineProps<Omit<BFormTagsProps, 'modelValue'>>(), {\n addButtonText: 'Add',\n addButtonVariant: 'outline-secondary',\n addOnChange: false,\n autofocus: false,\n disabled: false,\n duplicateTagText: 'Duplicate tag(s)',\n feedbackAriaLive: 'assertive',\n form: undefined,\n ignoreInputFocusSelector: () => ['.b-form-tag', 'button', 'input', 'select'],\n inputAttrs: undefined,\n inputClass: undefined,\n inputId: undefined,\n inputType: 'text',\n invalidTagText: 'Invalid tag(s)',\n limit: undefined,\n limitTagsText: 'Tag limit reached',\n name: undefined,\n noAddOnEnter: false,\n noOuterFocus: false,\n noTagRemove: false,\n placeholder: 'Add tag...',\n removeOnDelete: false,\n required: false,\n separator: undefined,\n size: 'md',\n state: null,\n tagClass: undefined,\n tagPills: false,\n tagRemoveLabel: undefined,\n tagRemovedLabel: 'Tag removed',\n tagValidator: () => true,\n tagVariant: 'secondary',\n})\nconst props = useDefaults(_props, 'BFormTags')\nconst emit = defineEmits<BFormTagsEmits>()\ndefineSlots<BFormTagsSlots>()\n\nconst modelValue = defineModel<Exclude<BFormTagsProps['modelValue'], undefined>>({\n default: () => [],\n})\n\nconst computedId = useId()\n\nconst limitNumber = useToNumber(() => props.limit ?? Number.NaN)\n\nconst stateClass = useStateClass(() => props.state)\n\nconst input = useTemplateRef('_input')\n\nconst {focused} = useFocus(input, {\n initialValue: props.autofocus,\n})\n\nconst _inputId = computed(() => props.inputId || `${computedId.value}input__`)\nconst tags = ref<string[]>([...modelValue.value])\nconst inputValue = ref<string>('')\nconst shouldRemoveOnDelete = ref<boolean>(modelValue.value.length > 0)\nconst lastRemovedTag = ref<string>('')\nconst validTags = ref<string[]>([])\nconst invalidTags = ref<string[]>([])\nconst duplicateTags = ref<string[]>([])\n\nsyncRef(modelValue, tags, {\n direction: 'ltr',\n transform: {\n ltr: (v) => [...v],\n },\n})\n\nconst computedClasses = computed(() => [\n stateClass.value,\n {\n [`form-control-${props.size}`]: props.size !== 'md',\n disabled: props.disabled,\n focus: focused.value,\n },\n])\n\nconst isDuplicate = computed(() => tags.value.includes(inputValue.value))\nconst isInvalid = computed(() =>\n inputValue.value === '' ? false : !props.tagValidator(inputValue.value)\n)\nconst isLimitReached = computed(() => tags.value.length === limitNumber.value)\nconst disableAddButton = computed(() => !isInvalid.value && !isDuplicate.value)\n\nconst onFocusin = (e: Readonly<FocusEvent>): void => {\n if (props.disabled) {\n const target = e.target as HTMLDivElement\n target.blur()\n return\n }\n\n emit('focusin', e)\n}\n\nconst onClick = (e: Readonly<MouseEvent>): void => {\n if (props.disabled || props.noOuterFocus) {\n return\n }\n\n const {target} = e\n const ignoreSelectors = props.ignoreInputFocusSelector\n if (ignoreSelectors && target instanceof Element) {\n const selector =\n typeof ignoreSelectors === 'string' ? ignoreSelectors : ignoreSelectors.join(',')\n\n if (selector && target.closest(selector)) {\n return\n }\n }\n\n focused.value = true\n}\n\nconst onFocus = (e: Readonly<FocusEvent>): void => {\n if (props.disabled || props.noOuterFocus) {\n return\n }\n\n focused.value = true\n emit('focus', e)\n}\n\nconst onBlur = (e: Readonly<FocusEvent>): void => {\n focused.value = false\n emit('blur', e)\n}\n\nconst onInput = (e: Readonly<Event> | string): void => {\n const value = typeof e === 'string' ? e : (e.target as HTMLInputElement).value\n\n shouldRemoveOnDelete.value = false\n\n if (props.separator?.includes(value.charAt(0)) && value.length > 0) {\n if (input.value) {\n input.value.value = ''\n }\n return\n }\n\n inputValue.value = value\n\n if (props.separator?.includes(value.charAt(value.length - 1))) {\n addTag(value.slice(0, value.length - 1))\n return\n }\n\n validTags.value = props.tagValidator(value) && !isDuplicate.value ? [value] : []\n invalidTags.value = props.tagValidator(value) ? [] : [value]\n duplicateTags.value = isDuplicate.value ? [value] : []\n\n emit('tag-state', validTags.value, invalidTags.value, duplicateTags.value)\n}\n\nconst onChange = (e: Readonly<Event>): void => {\n if (props.addOnChange) {\n onInput(e)\n\n if (!isDuplicate.value) {\n addTag(inputValue.value)\n }\n }\n}\n\nconst onKeydown = (e: Readonly<KeyboardEvent>): void => {\n if ((e.key === 'Enter' || e.code === 'NumpadEnter') && !props.noAddOnEnter) {\n addTag(inputValue.value)\n return\n }\n\n if (\n (e.key === 'Backspace' || e.key === 'Delete') &&\n props.removeOnDelete &&\n inputValue.value === '' &&\n shouldRemoveOnDelete.value &&\n tags.value.length > 0\n ) {\n removeTag(tags.value[tags.value.length - 1])\n } else {\n shouldRemoveOnDelete.value = true\n }\n}\n\nonKeyStroke(onKeydown, {target: input})\n\nconst separator = computed(() => {\n if (!props.separator) {\n return\n }\n\n return typeof props.separator === 'string' ? props.separator : props.separator.join('')\n})\n\nconst separatorRegExp = computed(() => {\n if (!separator.value) {\n return\n }\n\n return new RegExp(`[${escapeRegExpChars(separator.value)}]+`)\n})\n\nconst addTag = (tag?: string): void => {\n tag = (tag ?? inputValue.value).trim()\n\n const newTags = separatorRegExp.value\n ? tag.split(separatorRegExp.value).map((t) => t.trim())\n : [tag]\n const validTags: string[] = []\n\n for (const newTag of newTags) {\n if (newTag === '' || isDuplicate.value || !props.tagValidator(newTag)) {\n continue\n }\n\n if (limitNumber.value && isLimitReached.value) {\n break\n }\n\n validTags.push(newTag)\n }\n\n const newValue = [...modelValue.value, ...validTags]\n inputValue.value = ''\n shouldRemoveOnDelete.value = true\n modelValue.value = newValue\n focused.value = true\n}\n\nconst removeTag = (tag?: string): void => {\n const tagIndex = tags.value.indexOf(tag?.toString() ?? '')\n if (tagIndex === -1) return\n lastRemovedTag.value = tags.value.splice(tagIndex, 1).toString()\n modelValue.value = tags.value\n}\n\ndefineExpose({\n blur: () => {\n focused.value = false\n },\n element: input,\n focus: () => {\n focused.value = true\n },\n inputValue,\n})\n</script>\n","<template>\n <div\n :id=\"computedId\"\n class=\"b-form-tags form-control h-auto\"\n :class=\"computedClasses\"\n role=\"group\"\n tabindex=\"-1\"\n @click=\"onClick\"\n @focusin=\"onFocusin\"\n @focusout=\"emit('focusout', $event)\"\n >\n <output\n :id=\"`${computedId}selected_tags__`\"\n class=\"visually-hidden\"\n :for=\"_inputId\"\n :aria-live=\"focused ? 'polite' : 'off'\"\n aria-atomic=\"true\"\n aria-relevant=\"additions text\"\n >{{ tags.join(', ') }}</output\n >\n <div\n :id=\"`${computedId}removed_tags__`\"\n role=\"status\"\n :aria-live=\"focused ? 'assertive' : 'off'\"\n aria-atomic=\"true\"\n class=\"visually-hidden\"\n >\n ({{ props.tagRemovedLabel }}) {{ lastRemovedTag }}\n </div>\n\n <slot\n :add-button-text=\"props.addButtonText\"\n :add-button-variant=\"props.addButtonVariant\"\n :add-tag\n :disable-add-button=\"disableAddButton\"\n :disabled=\"props.disabled\"\n :duplicate-tag-text=\"props.duplicateTagText\"\n :duplicate-tags=\"duplicateTags\"\n :form=\"props.form\"\n :input-attrs=\"{\n ...props.inputAttrs,\n disabled: props.disabled,\n form: props.form,\n id: _inputId,\n value: inputValue,\n }\"\n :input-class=\"props.inputClass\"\n :input-handlers=\"{\n input: onInput,\n keydown: onKeydown,\n change: onChange,\n }\"\n :input-id=\"_inputId\"\n :input-type=\"props.inputType\"\n :invalid-tag-text=\"props.invalidTagText\"\n :invalid-tags\n :is-duplicate\n :is-invalid\n :is-limit-reached=\"isLimitReached\"\n :limit-tags-text=\"props.limitTagsText\"\n :limit=\"limitNumber\"\n :no-tag-remove=\"props.noTagRemove\"\n :placeholder=\"props.placeholder\"\n :remove-tag\n :required=\"props.required\"\n :separator=\"props.separator\"\n :size=\"props.size\"\n :state=\"props.state\"\n :tag-class=\"props.tagClass\"\n :tag-pills=\"props.tagPills\"\n :tag-remove-label=\"props.tagRemoveLabel\"\n :tag-variant=\"props.tagVariant\"\n :tags\n >\n <ul\n :id=\"`${computedId}tag_list__`\"\n class=\"b-form-tags-list list-unstyled mb-0 d-flex flex-wrap align-items-center\"\n >\n <template v-for=\"(tag, index) in tags\" :key=\"index\">\n <slot\n name=\"tag\"\n :tag=\"tag\"\n :tag-class=\"props.tagClass\"\n :tag-variant=\"props.tagVariant\"\n :tag-pills=\"props.tagPills\"\n :remove-tag=\"removeTag\"\n >\n <BFormTag\n :key=\"tag\"\n :class=\"props.tagClass\"\n tag=\"li\"\n :variant=\"props.tagVariant\"\n :pill=\"props.tagPills\"\n :no-remove=\"props.noTagRemove\"\n :disabled=\"props.disabled\"\n @remove=\"removeTag\"\n >{{ tag }}</BFormTag\n >\n </slot>\n </template>\n <li\n role=\"none\"\n aria-live=\"off\"\n class=\"b-from-tags-field flex-grow-1\"\n :aria-controls=\"`${computedId}tag_list__`\"\n >\n <div role=\"group\" class=\"d-flex\">\n <input\n :id=\"_inputId\"\n ref=\"_input\"\n :disabled=\"props.disabled\"\n :value=\"inputValue\"\n :type=\"props.inputType\"\n :placeholder=\"props.placeholder\"\n class=\"b-form-tags-input w-100 flex-grow-1 p-0 m-0 bg-transparent border-0\"\n style=\"outline: currentcolor none 0px; min-width: 5rem\"\n v-bind=\"props.inputAttrs\"\n :form=\"props.form\"\n :required=\"props.required || undefined\"\n :aria-required=\"props.required || undefined\"\n @input=\"onInput\"\n @change=\"onChange\"\n @focus=\"onFocus\"\n @blur=\"onBlur\"\n />\n <button\n v-if=\"disableAddButton\"\n type=\"button\"\n class=\"btn b-form-tags-button py-0\"\n :class=\"[\n inputClass,\n {\n [`btn-${props.addButtonVariant}`]: props.addButtonVariant !== null,\n 'disabled invisible': inputValue.length === 0,\n },\n ]\"\n style=\"font-size: 90%\"\n :disabled=\"props.disabled || inputValue.length === 0 || isLimitReached\"\n @click=\"addTag(inputValue)\"\n >\n <slot name=\"add-button-text\">{{ props.addButtonText }}</slot>\n </button>\n </div>\n </li>\n </ul>\n <div :aria-live=\"props.feedbackAriaLive\" aria-atomic=\"true\">\n <div v-if=\"isInvalid\" class=\"d-block invalid-feedback\">\n {{ props.invalidTagText }}: {{ inputValue }}\n </div>\n <small v-if=\"isDuplicate\" class=\"form-text text-body-secondary\"\n >{{ props.duplicateTagText }}: {{ inputValue }}</small\n >\n <small v-if=\"tags.length === props.limit\" class=\"form-text text-body-secondary\">\n {{ props.limitTagsText }}</small\n >\n </div>\n </slot>\n <template v-if=\"props.name\">\n <input\n v-for=\"(tag, index) in tags\"\n :key=\"index\"\n type=\"hidden\"\n :name=\"props.name\"\n :value=\"tag\"\n />\n </template>\n </div>\n</template>\n\n<script setup lang=\"ts\">\nimport {onKeyStroke, syncRef, useFocus, useToNumber} from '@vueuse/core'\nimport {computed, ref, useTemplateRef} from 'vue'\nimport {useDefaults} from '../../composables/useDefaults'\nimport type {BFormTagsProps} from '../../types/ComponentProps'\nimport {escapeRegExpChars} from '../../utils/stringUtils'\nimport BFormTag from './BFormTag.vue'\nimport {useId} from '../../composables/useId'\nimport {useStateClass} from '../../composables/useStateClass'\nimport type {BFormTagsEmits, BFormTagsSlots} from '../../types'\n\nconst _props = withDefaults(defineProps<Omit<BFormTagsProps, 'modelValue'>>(), {\n addButtonText: 'Add',\n addButtonVariant: 'outline-secondary',\n addOnChange: false,\n autofocus: false,\n disabled: false,\n duplicateTagText: 'Duplicate tag(s)',\n feedbackAriaLive: 'assertive',\n form: undefined,\n ignoreInputFocusSelector: () => ['.b-form-tag', 'button', 'input', 'select'],\n inputAttrs: undefined,\n inputClass: undefined,\n inputId: undefined,\n inputType: 'text',\n invalidTagText: 'Invalid tag(s)',\n limit: undefined,\n limitTagsText: 'Tag limit reached',\n name: undefined,\n noAddOnEnter: false,\n noOuterFocus: false,\n noTagRemove: false,\n placeholder: 'Add tag...',\n removeOnDelete: false,\n required: false,\n separator: undefined,\n size: 'md',\n state: null,\n tagClass: undefined,\n tagPills: false,\n tagRemoveLabel: undefined,\n tagRemovedLabel: 'Tag removed',\n tagValidator: () => true,\n tagVariant: 'secondary',\n})\nconst props = useDefaults(_props, 'BFormTags')\nconst emit = defineEmits<BFormTagsEmits>()\ndefineSlots<BFormTagsSlots>()\n\nconst modelValue = defineModel<Exclude<BFormTagsProps['modelValue'], undefined>>({\n default: () => [],\n})\n\nconst computedId = useId()\n\nconst limitNumber = useToNumber(() => props.limit ?? Number.NaN)\n\nconst stateClass = useStateClass(() => props.state)\n\nconst input = useTemplateRef('_input')\n\nconst {focused} = useFocus(input, {\n initialValue: props.autofocus,\n})\n\nconst _inputId = computed(() => props.inputId || `${computedId.value}input__`)\nconst tags = ref<string[]>([...modelValue.value])\nconst inputValue = ref<string>('')\nconst shouldRemoveOnDelete = ref<boolean>(modelValue.value.length > 0)\nconst lastRemovedTag = ref<string>('')\nconst validTags = ref<string[]>([])\nconst invalidTags = ref<string[]>([])\nconst duplicateTags = ref<string[]>([])\n\nsyncRef(modelValue, tags, {\n direction: 'ltr',\n transform: {\n ltr: (v) => [...v],\n },\n})\n\nconst computedClasses = computed(() => [\n stateClass.value,\n {\n [`form-control-${props.size}`]: props.size !== 'md',\n disabled: props.disabled,\n focus: focused.value,\n },\n])\n\nconst isDuplicate = computed(() => tags.value.includes(inputValue.value))\nconst isInvalid = computed(() =>\n inputValue.value === '' ? false : !props.tagValidator(inputValue.value)\n)\nconst isLimitReached = computed(() => tags.value.length === limitNumber.value)\nconst disableAddButton = computed(() => !isInvalid.value && !isDuplicate.value)\n\nconst onFocusin = (e: Readonly<FocusEvent>): void => {\n if (props.disabled) {\n const target = e.target as HTMLDivElement\n target.blur()\n return\n }\n\n emit('focusin', e)\n}\n\nconst onClick = (e: Readonly<MouseEvent>): void => {\n if (props.disabled || props.noOuterFocus) {\n return\n }\n\n const {target} = e\n const ignoreSelectors = props.ignoreInputFocusSelector\n if (ignoreSelectors && target instanceof Element) {\n const selector =\n typeof ignoreSelectors === 'string' ? ignoreSelectors : ignoreSelectors.join(',')\n\n if (selector && target.closest(selector)) {\n return\n }\n }\n\n focused.value = true\n}\n\nconst onFocus = (e: Readonly<FocusEvent>): void => {\n if (props.disabled || props.noOuterFocus) {\n return\n }\n\n focused.value = true\n emit('focus', e)\n}\n\nconst onBlur = (e: Readonly<FocusEvent>): void => {\n focused.value = false\n emit('blur', e)\n}\n\nconst onInput = (e: Readonly<Event> | string): void => {\n const value = typeof e === 'string' ? e : (e.target as HTMLInputElement).value\n\n shouldRemoveOnDelete.value = false\n\n if (props.separator?.includes(value.charAt(0)) && value.length > 0) {\n if (input.value) {\n input.value.value = ''\n }\n return\n }\n\n inputValue.value = value\n\n if (props.separator?.includes(value.charAt(value.length - 1))) {\n addTag(value.slice(0, value.length - 1))\n return\n }\n\n validTags.value = props.tagValidator(value) && !isDuplicate.value ? [value] : []\n invalidTags.value = props.tagValidator(value) ? [] : [value]\n duplicateTags.value = isDuplicate.value ? [value] : []\n\n emit('tag-state', validTags.value, invalidTags.value, duplicateTags.value)\n}\n\nconst onChange = (e: Readonly<Event>): void => {\n if (props.addOnChange) {\n onInput(e)\n\n if (!isDuplicate.value) {\n addTag(inputValue.value)\n }\n }\n}\n\nconst onKeydown = (e: Readonly<KeyboardEvent>): void => {\n if ((e.key === 'Enter' || e.code === 'NumpadEnter') && !props.noAddOnEnter) {\n addTag(inputValue.value)\n return\n }\n\n if (\n (e.key === 'Backspace' || e.key === 'Delete') &&\n props.removeOnDelete &&\n inputValue.value === '' &&\n shouldRemoveOnDelete.value &&\n tags.value.length > 0\n ) {\n removeTag(tags.value[tags.value.length - 1])\n } else {\n shouldRemoveOnDelete.value = true\n }\n}\n\nonKeyStroke(onKeydown, {target: input})\n\nconst separator = computed(() => {\n if (!props.separator) {\n return\n }\n\n return typeof props.separator === 'string' ? props.separator : props.separator.join('')\n})\n\nconst separatorRegExp = computed(() => {\n if (!separator.value) {\n return\n }\n\n return new RegExp(`[${escapeRegExpChars(separator.value)}]+`)\n})\n\nconst addTag = (tag?: string): void => {\n tag = (tag ?? inputValue.value).trim()\n\n const newTags = separatorRegExp.value\n ? tag.split(separatorRegExp.value).map((t) => t.trim())\n : [tag]\n const validTags: string[] = []\n\n for (const newTag of newTags) {\n if (newTag === '' || isDuplicate.value || !props.tagValidator(newTag)) {\n continue\n }\n\n if (limitNumber.value && isLimitReached.value) {\n break\n }\n\n validTags.push(newTag)\n }\n\n const newValue = [...modelValue.value, ...validTags]\n inputValue.value = ''\n shouldRemoveOnDelete.value = true\n modelValue.value = newValue\n focused.value = true\n}\n\nconst removeTag = (tag?: string): void => {\n const tagIndex = tags.value.indexOf(tag?.toString() ?? '')\n if (tagIndex === -1) return\n lastRemovedTag.value = tags.value.splice(tagIndex, 1).toString()\n modelValue.value = tags.value\n}\n\ndefineExpose({\n blur: () => {\n focused.value = false\n },\n element: input,\n focus: () => {\n focused.value = true\n },\n inputValue,\n})\n</script>\n"],"mappings":"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"}