mirror of
https://github.com/element-plus/element-plus.git
synced 2026-03-13 07:51:17 +08:00
* chore: remove ts-nocheck comments in select-v2 * take the review comments * improve emits type * the keys of emits use camelCase instead of kebab-case * apply suggestions from code review Co-authored-by: btea <2356281422@qq.com> * reduce duplicate ESLint comments * use more succinct syntax to define props * revert emits to kebab-case * fix: type checking failed * chore: illustrate why return early in validateIcon * fix: signature with duplicate parameter names Co-authored-by: qiang <qw13131wang@gmail.com> --------- Co-authored-by: btea <2356281422@qq.com> Co-authored-by: qiang <qw13131wang@gmail.com>
100 lines
2.6 KiB
TypeScript
100 lines
2.6 KiB
TypeScript
import { computed, ref } from 'vue'
|
|
import { useProps } from './useProps'
|
|
import type { ISelectV2Props } from './token'
|
|
import type { Option, SelectStates } from './select.types'
|
|
|
|
export function useAllowCreate(props: ISelectV2Props, states: SelectStates) {
|
|
const { aliasProps, getLabel, getValue } = useProps(props)
|
|
|
|
const createOptionCount = ref(0)
|
|
const cachedSelectedOption = ref<Option>()
|
|
|
|
const enableAllowCreateMode = computed(() => {
|
|
return props.allowCreate && props.filterable
|
|
})
|
|
|
|
function hasExistingOption(query: string) {
|
|
const hasOption = (option: Option) => getLabel(option) === query
|
|
return (
|
|
(props.options && props.options.some(hasOption)) ||
|
|
states.createdOptions.some(hasOption)
|
|
)
|
|
}
|
|
|
|
function selectNewOption(option: Option) {
|
|
if (!enableAllowCreateMode.value) {
|
|
return
|
|
}
|
|
if (props.multiple && option.created) {
|
|
createOptionCount.value++
|
|
} else {
|
|
cachedSelectedOption.value = option
|
|
}
|
|
}
|
|
|
|
function createNewOption(query: string) {
|
|
if (enableAllowCreateMode.value) {
|
|
if (query && query.length > 0) {
|
|
if (hasExistingOption(query)) {
|
|
return
|
|
}
|
|
const newOption = {
|
|
[aliasProps.value.value]: query,
|
|
[aliasProps.value.label]: query,
|
|
created: true,
|
|
[aliasProps.value.disabled]: false,
|
|
}
|
|
if (states.createdOptions.length >= createOptionCount.value) {
|
|
states.createdOptions[createOptionCount.value] = newOption
|
|
} else {
|
|
states.createdOptions.push(newOption)
|
|
}
|
|
} else {
|
|
if (props.multiple) {
|
|
states.createdOptions.length = createOptionCount.value
|
|
} else {
|
|
const selectedOption = cachedSelectedOption.value
|
|
states.createdOptions.length = 0
|
|
if (selectedOption && selectedOption.created) {
|
|
states.createdOptions.push(selectedOption)
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
function removeNewOption(option: Option) {
|
|
if (
|
|
!enableAllowCreateMode.value ||
|
|
!option ||
|
|
!option.created ||
|
|
(option.created &&
|
|
props.reserveKeyword &&
|
|
states.inputValue === getLabel(option))
|
|
) {
|
|
return
|
|
}
|
|
const idx = states.createdOptions.findIndex(
|
|
(it) => getValue(it) === getValue(option)
|
|
)
|
|
if (~idx) {
|
|
states.createdOptions.splice(idx, 1)
|
|
createOptionCount.value--
|
|
}
|
|
}
|
|
|
|
function clearAllNewOption() {
|
|
if (enableAllowCreateMode.value) {
|
|
states.createdOptions.length = 0
|
|
createOptionCount.value = 0
|
|
}
|
|
}
|
|
|
|
return {
|
|
createNewOption,
|
|
removeNewOption,
|
|
selectNewOption,
|
|
clearAllNewOption,
|
|
}
|
|
}
|