UNPKG

element-plus

Version:

A Component Library for Vue 3

1 lines 10.9 kB
{"version":3,"file":"use-input-tag.mjs","names":[],"sources":["../../../../../../../packages/components/input-tag/src/composables/use-input-tag.ts"],"sourcesContent":["import { computed, ref, shallowRef, watch } from 'vue'\nimport {\n CHANGE_EVENT,\n EVENT_CODE,\n INPUT_EVENT,\n UPDATE_MODEL_EVENT,\n} from '@element-plus/constants'\nimport {\n debugWarn,\n ensureArray,\n getEventCode,\n isAndroid,\n isUndefined,\n} from '@element-plus/utils'\nimport { useComposition, useFocusController } from '@element-plus/hooks'\nimport { useFormDisabled, useFormSize } from '@element-plus/components/form'\n\nimport type { TooltipInstance } from '@element-plus/components/tooltip'\nimport type { EmitFn } from '@element-plus/utils'\nimport type { FormItemContext } from '@element-plus/components/form'\nimport type { InputTagEmits, InputTagProps } from '../input-tag'\n\ninterface UseInputTagOptions {\n props: InputTagProps\n emit: EmitFn<InputTagEmits>\n formItem?: FormItemContext\n}\n\nexport function useInputTag({ props, emit, formItem }: UseInputTagOptions) {\n const disabled = useFormDisabled()\n const size = useFormSize()\n\n const inputRef = shallowRef<HTMLInputElement>()\n const inputValue = ref<string>()\n const tagTooltipRef = ref<TooltipInstance>()\n\n const tagSize = computed(() => {\n return ['small'].includes(size.value) ? 'small' : 'default'\n })\n const placeholder = computed(() => {\n return props.modelValue?.length ? undefined : props.placeholder\n })\n const closable = computed(() => !(props.readonly || disabled.value))\n const inputLimit = computed(() => {\n return isUndefined(props.max)\n ? false\n : (props.modelValue?.length ?? 0) >= props.max\n })\n const showTagList = computed(() => {\n return props.collapseTags\n ? props.modelValue?.slice(0, props.maxCollapseTags)\n : props.modelValue\n })\n const collapseTagList = computed(() => {\n return props.collapseTags\n ? props.modelValue?.slice(props.maxCollapseTags)\n : []\n })\n\n const addTagsEmit = (value: string | string[]) => {\n const list = [...(props.modelValue ?? []), ...ensureArray(value)]\n\n emit(UPDATE_MODEL_EVENT, list)\n emit(CHANGE_EVENT, list)\n emit('add-tag', value)\n inputValue.value = undefined\n }\n\n const getDelimitedTags = (input: string) => {\n const parts = input.split(props.delimiter!)\n const tags =\n parts.length > 1 ? parts.map((val) => val.trim()).filter(Boolean) : []\n if (props.max) {\n const maxInsert = props.max - (props.modelValue?.length ?? 0)\n tags.splice(maxInsert)\n }\n return tags.length === 1 ? tags[0] : tags\n }\n\n const handlePaste = (event: ClipboardEvent) => {\n const pasted = event.clipboardData?.getData('text')\n if (props.readonly || inputLimit.value || !props.delimiter || !pasted) {\n return\n }\n const {\n selectionStart = 0,\n selectionEnd = 0,\n value,\n } = event.target as HTMLInputElement\n const nextValue =\n value.slice(0, selectionStart!) + pasted + value.slice(selectionEnd!)\n const tags = getDelimitedTags(nextValue)\n if (tags.length) {\n addTagsEmit(tags)\n emit(INPUT_EVENT, nextValue)\n event.preventDefault()\n }\n }\n\n const handleInput = (event: Event) => {\n if (inputLimit.value) {\n inputValue.value = undefined\n return\n }\n\n if (isComposing.value) return\n if (props.delimiter && inputValue.value) {\n const tags = getDelimitedTags(inputValue.value)\n if (tags.length) {\n addTagsEmit(tags)\n }\n }\n emit(INPUT_EVENT, (event.target as HTMLInputElement).value)\n }\n\n const handleKeydown = (event: KeyboardEvent) => {\n if (isComposing.value) return\n const code = getEventCode(event)\n\n switch (code) {\n case props.trigger:\n event.preventDefault()\n event.stopPropagation()\n handleAddTag()\n break\n case EVENT_CODE.numpadEnter:\n if (props.trigger === EVENT_CODE.enter) {\n event.preventDefault()\n event.stopPropagation()\n handleAddTag()\n }\n break\n case EVENT_CODE.backspace:\n if (!inputValue.value && props.modelValue?.length) {\n event.preventDefault()\n event.stopPropagation()\n handleRemoveTag(props.modelValue.length - 1)\n }\n break\n }\n }\n\n const handleKeyup = (event: KeyboardEvent) => {\n if (isComposing.value || !isAndroid()) return\n const code = getEventCode(event)\n\n switch (code) {\n case EVENT_CODE.space:\n if (props.trigger === EVENT_CODE.space) {\n event.preventDefault()\n event.stopPropagation()\n handleAddTag()\n }\n break\n }\n }\n\n const handleAddTag = () => {\n const value = inputValue.value?.trim()\n if (!value || inputLimit.value) return\n addTagsEmit(value)\n }\n\n const handleRemoveTag = (index: number) => {\n const value = (props.modelValue ?? []).slice()\n const [item] = value.splice(index, 1)\n\n emit(UPDATE_MODEL_EVENT, value)\n emit(CHANGE_EVENT, value)\n emit('remove-tag', item, index)\n }\n\n const handleClear = () => {\n inputValue.value = undefined\n emit(UPDATE_MODEL_EVENT, undefined)\n emit(CHANGE_EVENT, undefined)\n emit('clear')\n }\n\n const handleDragged = (\n draggingIndex: number,\n dropIndex: number,\n type: 'before' | 'after'\n ) => {\n const value = (props.modelValue ?? []).slice()\n const [draggedItem] = value.splice(draggingIndex, 1)\n const step =\n dropIndex > draggingIndex && type === 'before'\n ? -1\n : dropIndex < draggingIndex && type === 'after'\n ? 1\n : 0\n\n value.splice(dropIndex + step, 0, draggedItem)\n emit(UPDATE_MODEL_EVENT, value)\n emit(CHANGE_EVENT, value)\n emit('drag-tag', draggingIndex, dropIndex + step, draggedItem)\n }\n\n const focus = () => {\n inputRef.value?.focus()\n }\n\n const blur = () => {\n inputRef.value?.blur()\n }\n\n const { wrapperRef, isFocused } = useFocusController(inputRef, {\n disabled,\n beforeBlur(event) {\n return tagTooltipRef.value?.isFocusInsideContent(event)\n },\n afterBlur() {\n if (props.saveOnBlur) {\n handleAddTag()\n } else {\n inputValue.value = undefined\n }\n\n if (props.validateEvent) {\n formItem?.validate?.('blur').catch((err) => debugWarn(err))\n }\n },\n })\n\n const {\n isComposing,\n handleCompositionStart,\n handleCompositionUpdate,\n handleCompositionEnd,\n } = useComposition({ afterComposition: handleInput })\n\n watch(\n () => props.modelValue,\n () => {\n if (props.validateEvent) {\n formItem?.validate?.(CHANGE_EVENT).catch((err) => debugWarn(err))\n }\n }\n )\n\n return {\n inputRef,\n wrapperRef,\n tagTooltipRef,\n isFocused,\n isComposing,\n inputValue,\n size,\n tagSize,\n placeholder,\n closable,\n disabled,\n inputLimit,\n showTagList,\n collapseTagList,\n handleDragged,\n handlePaste,\n handleInput,\n handleKeydown,\n handleKeyup,\n handleAddTag,\n handleRemoveTag,\n handleClear,\n handleCompositionStart,\n handleCompositionUpdate,\n handleCompositionEnd,\n focus,\n blur,\n }\n}\n"],"mappings":"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"}