{"version":3,"file":"TagsInputRoot.cjs","sources":["../../src/TagsInput/TagsInputRoot.vue"],"sourcesContent":["<script lang=\"ts\">\nimport type { PrimitiveProps } from '@/Primitive'\nimport { createContext, useArrowNavigation, useDirection, useFormControl, useForwardExpose } from '@/shared'\nimport type { Direction, FormFieldProps } from '@/shared/types'\nimport { type Ref, computed, ref, toRefs } from 'vue'\n\nexport type AcceptableInputValue = string | Record<string, any>\n\nexport interface TagsInputRootProps<T = AcceptableInputValue> extends PrimitiveProps, FormFieldProps {\n  /** The controlled value of the tags input. Can be bind as `v-model`. */\n  modelValue?: Array<T> | null\n  /** The value of the tags that should be added. Use when you do not need to control the state of the tags input */\n  defaultValue?: Array<T>\n  /** When `true`, allow adding tags on paste. Work in conjunction with delimiter prop. */\n  addOnPaste?: boolean\n  /** When `true` allow adding tags on tab keydown */\n  addOnTab?: boolean\n  /** When `true` allow adding tags blur input */\n  addOnBlur?: boolean\n  /** When `true`, allow duplicated tags. */\n  duplicate?: boolean\n  /** When `true`, prevents the user from interacting with the tags input. */\n  disabled?: boolean\n  /** The character or regular expression to trigger the addition of a new tag. Also used to split tags for `@paste` event */\n  delimiter?: string | RegExp\n  /** The reading direction of the combobox when applicable. <br> If omitted, inherits globally from `ConfigProvider` or assumes LTR (left-to-right) reading mode. */\n  dir?: Direction\n  /** Maximum number of tags. */\n  max?: number\n  id?: string\n  /** Convert the input value to the desired type. Mandatory when using objects as values and using `TagsInputInput` */\n  convertValue?: (value: string) => T\n  /** Display the value of the tag. Useful when you want to apply modifications to the value like adding a suffix or when using object as values */\n  displayValue?: (value: T) => string\n}\n\nexport type TagsInputRootEmits<T = AcceptableInputValue> = {\n  /** Event handler called when the value changes */\n  'update:modelValue': [payload: Array<T>]\n  /** Event handler called when the value is invalid */\n  'invalid': [payload: T]\n  /** Event handler called when tag is added */\n  'addTag': [payload: T]\n  /** Event handler called when tag is removed */\n  'removeTag': [payload: T]\n}\n\nexport interface TagsInputRootContext<T = AcceptableInputValue> {\n  modelValue: Ref<Array<T>>\n  onAddValue: (payload: string) => boolean\n  onRemoveValue: (index: number) => void\n  onInputKeydown: (event: KeyboardEvent) => void\n  selectedElement: Ref<HTMLElement | undefined>\n  isInvalidInput: Ref<boolean>\n  addOnPaste: Ref<boolean>\n  addOnTab: Ref<boolean>\n  addOnBlur: Ref<boolean>\n  disabled: Ref<boolean>\n  delimiter: Ref<string | RegExp>\n  dir: Ref<Direction>\n  max: Ref<number>\n  id: Ref<string | undefined> | undefined\n  displayValue: (value: T) => string\n}\n\nexport const [injectTagsInputRootContext, provideTagsInputRootContext]\n  = createContext<TagsInputRootContext>('TagsInputRoot')\n</script>\n\n<script setup lang=\"ts\" generic=\"T extends AcceptableInputValue = string\">\nimport { Primitive } from '@/Primitive'\nimport { useCollection } from '@/Collection'\nimport { useFocusWithin, useVModel } from '@vueuse/core'\nimport { VisuallyHiddenInput } from '@/VisuallyHidden'\n\nconst props = withDefaults(defineProps<TagsInputRootProps<T>>(), {\n  defaultValue: () => [],\n  delimiter: ',',\n  max: 0,\n  displayValue: (value: T) => value.toString(),\n})\nconst emits = defineEmits<TagsInputRootEmits<T>>()\n\ndefineSlots<{\n  default: (props: {\n    /** Current input values */\n    modelValue: typeof modelValue.value\n  }) => any\n}>()\n\nconst { addOnPaste, disabled, delimiter, max, id, dir: propDir, addOnBlur, addOnTab } = toRefs(props)\nconst dir = useDirection(propDir)\n\nconst modelValue = useVModel(props, 'modelValue', emits, {\n  defaultValue: props.defaultValue,\n  passive: true,\n  deep: true,\n}) as Ref<Array<AcceptableInputValue>>\n\nconst { forwardRef, currentElement } = useForwardExpose()\nconst { focused } = useFocusWithin(currentElement)\nconst isFormControl = useFormControl(currentElement)\n\nconst { getItems, CollectionSlot } = useCollection({ isProvider: true })\n\nconst selectedElement = ref<HTMLElement>()\nconst isInvalidInput = ref(false)\n\nconst currentModelValue = computed(() => Array.isArray(modelValue.value) ? [...modelValue.value] : [])\n\nfunction handleRemoveTag(index: number) {\n  if (index !== -1) {\n    const collection = getItems().filter(i => i.ref.dataset.disabled !== '')\n    modelValue.value = modelValue.value.filter((_, i) => i !== index)\n    emits('removeTag', collection[index].value)\n  }\n}\n\nprovideTagsInputRootContext({\n  modelValue,\n  onAddValue: (_payload) => {\n    const array = [...currentModelValue.value]\n    const modelValueIsObject = array.length > 0 && typeof array[0] === 'object'\n    const defaultValueIsObject = array.length > 0 && typeof props.defaultValue[0] === 'object'\n\n    // Check if the value is an object and if the convertValue function is provided. We don't check this a type level because the use\n    // of `TagsInputInput` is optional.\n    if ((modelValueIsObject || defaultValueIsObject) && typeof props.convertValue !== 'function')\n      throw new Error('You must provide a `convertValue` function when using objects as values.')\n    const payload = props.convertValue ? props.convertValue(_payload) : _payload as T\n\n    if ((array.length >= max.value) && !!max.value) {\n      emits('invalid', payload)\n      return false\n    }\n\n    if (props.duplicate) {\n      modelValue.value = [...array, payload]\n      emits('addTag', payload)\n      return true\n    }\n    else {\n      const exist = array.includes(payload)\n      if (!exist) {\n        modelValue.value = [...array, payload]\n        emits('addTag', payload)\n        return true\n      }\n      else {\n        isInvalidInput.value = true\n      }\n    }\n    emits('invalid', payload)\n    return false\n  },\n  onRemoveValue: handleRemoveTag,\n  onInputKeydown: (event) => {\n    const target = event.target as HTMLInputElement\n    const collection = getItems().map(i => i.ref).filter(i => i.dataset.disabled !== '')\n    if (!collection.length)\n      return\n    const lastTag = collection.at(-1)\n    switch (event.key) {\n      case 'Delete':\n      case 'Backspace': {\n        if (target.selectionStart !== 0 || target.selectionEnd !== 0)\n          break\n\n        if (selectedElement.value) {\n          const index = collection.findIndex(i => i === selectedElement.value)\n          handleRemoveTag(index)\n          selectedElement.value = selectedElement.value === lastTag ? collection.at(index - 1) : collection.at(index + 1)\n          event.preventDefault()\n        }\n        else if (event.key === 'Backspace') {\n          selectedElement.value = lastTag\n          event.preventDefault()\n        }\n        break\n      }\n      case 'Home':\n      case 'End':\n      case 'ArrowRight':\n      case 'ArrowLeft': {\n        const isArrowRight = (event.key === 'ArrowRight' && dir.value === 'ltr') || (event.key === 'ArrowLeft' && dir.value === 'rtl')\n        const isArrowLeft = !isArrowRight\n        // only focus on tags when cursor is at the first position\n        if (target.selectionStart !== 0 || target.selectionEnd !== 0)\n          break\n\n        // if you press ArrowLeft, then we last tag\n        if (isArrowLeft && !selectedElement.value) {\n          selectedElement.value = lastTag\n          event.preventDefault()\n        }\n        // if you press ArrowRight on last tag, you deselect\n        else if (isArrowRight && lastTag && selectedElement.value === lastTag) {\n          selectedElement.value = undefined\n          event.preventDefault()\n        }\n        else if (selectedElement.value) {\n          const el = useArrowNavigation(event, selectedElement.value, undefined, {\n            itemsArray: collection,\n            loop: false,\n            dir: dir.value,\n          })\n          if (el)\n            selectedElement.value = el\n          event.preventDefault()\n        }\n        break\n      }\n      case 'ArrowUp':\n      case 'ArrowDown': {\n        if (selectedElement.value)\n          event.preventDefault()\n        break\n      }\n      default: {\n        selectedElement.value = undefined\n      }\n    }\n  },\n  selectedElement,\n  isInvalidInput,\n  addOnPaste,\n  addOnBlur,\n  addOnTab,\n  dir,\n  disabled,\n  delimiter,\n  max,\n  id,\n  displayValue: props.displayValue as (value: AcceptableInputValue) => string,\n})\n</script>\n\n<template>\n  <CollectionSlot>\n    <Primitive\n      :ref=\"forwardRef\"\n      :dir=\"dir\"\n      :as=\"as\"\n      :as-child=\"asChild\"\n      :data-invalid=\"isInvalidInput ? '' : undefined\"\n      :data-disabled=\"disabled ? '' : undefined\"\n      :data-focused=\"focused ? '' : undefined\"\n    >\n      <slot :model-value=\"modelValue\" />\n\n      <VisuallyHiddenInput\n        v-if=\"isFormControl && name\"\n        :name=\"name\"\n        :value=\"modelValue\"\n        :required=\"required\"\n        :disabled=\"disabled\"\n      />\n    </Primitive>\n  </CollectionSlot>\n</template>\n"],"names":["createContext","toRefs","useDirection","useVModel","useForwardExpose","useFocusWithin","useFormControl","useCollection","ref","computed","useArrowNavigation"],"mappings":"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"}