|
|
@@ -0,0 +1,635 @@
|
|
|
+import {ElTooltip, useFocusController, useFormItem, useFormItemInputId, useNamespace} from "element-plus";
|
|
|
+import {useCompRef} from "@/utils/useCompRef";
|
|
|
+import XEUtils, {filter, isArray, isEqual, isFunction, isNumber, isObject, isString} from "xe-utils";
|
|
|
+import type {CyComboGridOptions} from './CyComboGrid.vue'
|
|
|
+import {useResizeObserver} from "@vueuse/core";
|
|
|
+import {stringNotBlank} from "@/utils/blank-utils";
|
|
|
+import {listFilter} from "@/utils/list-utlis";
|
|
|
+//@ts-ignore
|
|
|
+import Sortable from 'sortablejs'
|
|
|
+import {WritableComputedRef} from "vue";
|
|
|
+
|
|
|
+const isPromise = (val: Promise<any | unknown>) => {
|
|
|
+ if (val === null || typeof val === 'undefined') {
|
|
|
+ return false
|
|
|
+ }
|
|
|
+ return isObject(val) && isFunction(val.then) && isFunction(val.catch);
|
|
|
+};
|
|
|
+
|
|
|
+const isKorean = (text: string) =>
|
|
|
+ /([\uAC00-\uD7AF\u3130-\u318F])+/gi.test(text)
|
|
|
+
|
|
|
+export function useInputV2(handleInput: (event: InputEvent) => void) {
|
|
|
+ const isComposing = ref(false)
|
|
|
+ const handleCompositionStart = () => {
|
|
|
+ isComposing.value = true
|
|
|
+ }
|
|
|
+ const handleCompositionUpdate = (event: any) => {
|
|
|
+ const text = event.target.value
|
|
|
+ const lastCharacter = text[text.length - 1] || ''
|
|
|
+ isComposing.value = !isKorean(lastCharacter)
|
|
|
+ }
|
|
|
+
|
|
|
+ const handleCompositionEnd = (event: any) => {
|
|
|
+ if (isComposing.value) {
|
|
|
+ isComposing.value = false
|
|
|
+ if (isFunction(handleInput)) {
|
|
|
+ handleInput(event)
|
|
|
+ }
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+ return {
|
|
|
+ handleCompositionStart,
|
|
|
+ handleCompositionUpdate,
|
|
|
+ handleCompositionEnd,
|
|
|
+ isComposing
|
|
|
+ }
|
|
|
+}
|
|
|
+
|
|
|
+declare type CyComboGridOptionsV2 = Readonly<Required<CyComboGridOptions>>
|
|
|
+
|
|
|
+declare type ValueLabel = { value: string, label: string, [key: string]: any }
|
|
|
+
|
|
|
+const prefix = ref('cy')
|
|
|
+
|
|
|
+export default function UesComboGrid(props: CyComboGridOptionsV2, emits: any) {
|
|
|
+ const nsSelect = useNamespace('combo-grid', prefix)
|
|
|
+ const inputRef = ref<HTMLInputElement | null>(null)
|
|
|
+ const tooltipRef = useCompRef(ElTooltip)
|
|
|
+ const expanded = ref(false)
|
|
|
+ const tableRef = ref(null)
|
|
|
+ const calculatorRef = ref<HTMLElement | null>(null)
|
|
|
+ const selectionRef = ref<HTMLElement | null>(null)
|
|
|
+ const collapseItemRef = ref<HTMLElement | null>(null)
|
|
|
+ const detailsTableRaf = ref(null)
|
|
|
+ const localSearchData = ref<any[]>([])
|
|
|
+ const internalData = isFunction(props.remoteMethod) && typeof props.data === 'undefined'
|
|
|
+ const wrapperHeightGoBeyond = ref(false)
|
|
|
+
|
|
|
+ const {form, formItem} = useFormItem()
|
|
|
+ const {inputId} = useFormItemInputId(props, {
|
|
|
+ formItemContext: formItem,
|
|
|
+ })
|
|
|
+
|
|
|
+ const selectDisabled = computed(() => props.disabled || form?.disabled)
|
|
|
+
|
|
|
+ const propsData: WritableComputedRef<ValueLabel[]> = computed({
|
|
|
+ get() {
|
|
|
+ return internalData ? states.data : props.data
|
|
|
+ },
|
|
|
+ set(val) {
|
|
|
+ if (internalData) {
|
|
|
+ states.data = val
|
|
|
+ } else {
|
|
|
+ emits('update:data', val)
|
|
|
+ }
|
|
|
+ }
|
|
|
+ })
|
|
|
+
|
|
|
+ const dropdownMenuVisible = computed({
|
|
|
+ get() {
|
|
|
+ return expanded.value
|
|
|
+ },
|
|
|
+ set(val: boolean) {
|
|
|
+ expanded.value = val
|
|
|
+ },
|
|
|
+ })
|
|
|
+
|
|
|
+ const states = reactive({
|
|
|
+ menuVisibleOnFocus: false,
|
|
|
+ inputValue: '',
|
|
|
+ selectedLabel: '',
|
|
|
+ inputHovering: false,
|
|
|
+ selectionWidth: 0,
|
|
|
+ calculatorWidth: 0,
|
|
|
+ collapseItemWidth: 0,
|
|
|
+ previousQuery: '',
|
|
|
+ data: [],
|
|
|
+ // 缓存点击的选项
|
|
|
+ selected: props.multiple ? ([] as ValueLabel[]) : ({} as any),
|
|
|
+ })
|
|
|
+
|
|
|
+ const popperRef = computed(() => {
|
|
|
+ return tooltipRef.value?.popperRef?.contentRef
|
|
|
+ })
|
|
|
+
|
|
|
+ const {wrapperRef, isFocused, handleFocus, handleBlur} = useFocusController(
|
|
|
+ // @ts-ignore
|
|
|
+ inputRef, {
|
|
|
+ afterFocus() {
|
|
|
+ expanded.value = true
|
|
|
+ states.menuVisibleOnFocus = true
|
|
|
+ },
|
|
|
+ beforeBlur(event) {
|
|
|
+ return (tooltipRef.value?.isFocusInsideContent(event))
|
|
|
+ },
|
|
|
+ afterBlur() {
|
|
|
+ expanded.value = false
|
|
|
+ states.menuVisibleOnFocus = false
|
|
|
+ formItem?.validate('blur').catch((err) => console.warn(err))
|
|
|
+ }
|
|
|
+ })
|
|
|
+
|
|
|
+ function handleClickOutside(event: Event) {
|
|
|
+ expanded.value = false
|
|
|
+ if (isFocused.value) {
|
|
|
+ const _event = new FocusEvent('focus', event)
|
|
|
+ nextTick().then(r => {
|
|
|
+ handleBlur(_event)
|
|
|
+ })
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+ const tableData = computed(() => {
|
|
|
+ return localSearchData.value.length > 0 ? localSearchData.value : propsData.value;
|
|
|
+ })
|
|
|
+
|
|
|
+ function localSearch() {
|
|
|
+ localSearchData.value = listFilter(propsData.value, states.inputValue)
|
|
|
+ }
|
|
|
+
|
|
|
+ function handleQueryChange(val: string) {
|
|
|
+ if (states.previousQuery === val) {
|
|
|
+ return
|
|
|
+ }
|
|
|
+ if (isComposing.value) {
|
|
|
+ return;
|
|
|
+ }
|
|
|
+ if (val === '') {
|
|
|
+ localSearchData.value = []
|
|
|
+ return;
|
|
|
+ }
|
|
|
+ states.previousQuery = val
|
|
|
+ if (isFunction(props.remoteMethod)) {
|
|
|
+ const remoteMethod = props.remoteMethod(val)
|
|
|
+ if (remoteMethod != null && isPromise(remoteMethod)) {
|
|
|
+ remoteMethod.then(data => {
|
|
|
+ propsData.value = data as any
|
|
|
+ })
|
|
|
+ }
|
|
|
+ return;
|
|
|
+ }
|
|
|
+
|
|
|
+ // 本地搜索
|
|
|
+ localSearch()
|
|
|
+ }
|
|
|
+
|
|
|
+ const onInputChange = () => {
|
|
|
+ if (states.inputValue.length > 0 && !expanded.value) {
|
|
|
+ expanded.value = true
|
|
|
+ }
|
|
|
+ handleQueryChange(states.inputValue)
|
|
|
+ }
|
|
|
+
|
|
|
+ const onInput = (event: any) => {
|
|
|
+ states.inputValue = event.target.value
|
|
|
+ debouncedOnInputChange()
|
|
|
+ }
|
|
|
+
|
|
|
+ const debouncedOnInputChange = XEUtils.debounce(() => {
|
|
|
+ onInputChange()
|
|
|
+ }, props.debounce)
|
|
|
+
|
|
|
+ const {
|
|
|
+ handleCompositionStart,
|
|
|
+ handleCompositionUpdate,
|
|
|
+ handleCompositionEnd,
|
|
|
+ isComposing
|
|
|
+ } = useInputV2((e) => onInput(e))
|
|
|
+
|
|
|
+ const iconReverse = computed(() => {
|
|
|
+ return dropdownMenuVisible.value
|
|
|
+ })
|
|
|
+
|
|
|
+ const showClear = computed(() => {
|
|
|
+ return props.clearable && hasModelValue.value && states.inputHovering
|
|
|
+ })
|
|
|
+
|
|
|
+ const bindObj = computed(() => {
|
|
|
+ return (stringNotBlank(props.value) && stringNotBlank(props.label)) || stringNotBlank(props.valueLabel)
|
|
|
+ })
|
|
|
+
|
|
|
+ const updateModel = (val: any) => {
|
|
|
+ localSearchData.value = []
|
|
|
+ states.inputValue = ''
|
|
|
+ const select = {
|
|
|
+ value: val.value,
|
|
|
+ label: val.label,
|
|
|
+ }
|
|
|
+
|
|
|
+ if (props.multiple) {
|
|
|
+ let index = -1
|
|
|
+ if (props.keys) {
|
|
|
+ index = (props.modelValue as string[]).indexOf(select.value)
|
|
|
+ } else {
|
|
|
+ index = (props.modelValue as any[]).findIndex(item => {
|
|
|
+ return item.value === val.value
|
|
|
+ })
|
|
|
+ }
|
|
|
+ if (index > -1) {
|
|
|
+ (props.modelValue as any[]).splice(index, 1)
|
|
|
+ states.selected.splice(index, 1)
|
|
|
+ } else {
|
|
|
+ (props.modelValue as any[]).push(props.keys ? select.value : select)
|
|
|
+ states.selected.push(select)
|
|
|
+ }
|
|
|
+
|
|
|
+ } else {
|
|
|
+ states.selected = select
|
|
|
+ }
|
|
|
+
|
|
|
+ if (bindObj.value) {
|
|
|
+ // @ts-ignore
|
|
|
+ props.modelValue[props.value] = val.value
|
|
|
+ // @ts-ignore
|
|
|
+ props.modelValue[props.label] = val.label
|
|
|
+ states.selectedLabel = val.label
|
|
|
+ return
|
|
|
+ }
|
|
|
+
|
|
|
+ if (isString(props.modelValue)) {
|
|
|
+ emits('update:modelValue', val.value)
|
|
|
+ states.selectedLabel = val.label
|
|
|
+ return
|
|
|
+ }
|
|
|
+ if (isNumber(props.modelValue)) {
|
|
|
+ emits('update:modelValue', val.value)
|
|
|
+ states.selectedLabel = val.label
|
|
|
+ return
|
|
|
+ }
|
|
|
+
|
|
|
+
|
|
|
+ }
|
|
|
+
|
|
|
+ const handleClearClick = () => {
|
|
|
+ states.selectedLabel = ''
|
|
|
+ states.selected = props.multiple ? [] : ({} as any)
|
|
|
+ if (props.multiple) {
|
|
|
+ emits('update:modelValue', [])
|
|
|
+ return;
|
|
|
+ }
|
|
|
+
|
|
|
+ if (bindObj.value) {
|
|
|
+ // @ts-ignore
|
|
|
+ props.modelValue[props.value] = ''
|
|
|
+ // @ts-ignore
|
|
|
+ props.modelValue[props.label] = ''
|
|
|
+ return;
|
|
|
+ }
|
|
|
+ if (isString(props.modelValue)) {
|
|
|
+ emits('update:modelValue', '')
|
|
|
+ return
|
|
|
+ }
|
|
|
+ if (isNumber(props.modelValue)) {
|
|
|
+ emits('update:modelValue', null)
|
|
|
+ return
|
|
|
+ }
|
|
|
+
|
|
|
+ }
|
|
|
+
|
|
|
+ const handleTableClick = (val: any) => {
|
|
|
+ updateModel(val.row)
|
|
|
+ if (!props.multiple)
|
|
|
+ toggleMenu()
|
|
|
+ }
|
|
|
+
|
|
|
+ function toggleMenu() {
|
|
|
+ if (props.disabled) return
|
|
|
+ if (states.menuVisibleOnFocus) {
|
|
|
+ // controlled by automaticDropdown
|
|
|
+ states.menuVisibleOnFocus = false
|
|
|
+ } else {
|
|
|
+ expanded.value = !expanded.value
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+ const getGapWidth = () => {
|
|
|
+ if (!selectionRef.value) return 0
|
|
|
+ const style = window.getComputedStyle(selectionRef.value)
|
|
|
+ return Number.parseFloat(style.gap || '6px')
|
|
|
+ }
|
|
|
+
|
|
|
+ const inputStyle = computed(() => ({
|
|
|
+ width: `${Math.max(states.calculatorWidth, 11)}px`
|
|
|
+ }))
|
|
|
+
|
|
|
+ const collapseTagStyle = computed(() => {
|
|
|
+ return {maxWidth: `${states.selectionWidth}px`}
|
|
|
+ })
|
|
|
+
|
|
|
+ // computed style
|
|
|
+ const tagStyle = computed(() => {
|
|
|
+ const gapWidth = getGapWidth()
|
|
|
+ const maxWidth =
|
|
|
+ collapseItemRef.value && props.maxCollapseTags === 1
|
|
|
+ ? states.selectionWidth - states.collapseItemWidth - gapWidth
|
|
|
+ : states.selectionWidth
|
|
|
+ return {maxWidth: `${maxWidth}px`}
|
|
|
+ })
|
|
|
+
|
|
|
+ const hasModelValue = computed(() => {
|
|
|
+ if (isString(props.modelValue) && stringNotBlank(props.modelValue)) {
|
|
|
+ return true
|
|
|
+ }
|
|
|
+ if (isNumber(props.modelValue) && stringNotBlank(props.modelValue)) {
|
|
|
+ return true
|
|
|
+ }
|
|
|
+ // @ts-ignore
|
|
|
+ if (bindObj.value && stringNotBlank(props.modelValue[props!.value])) {
|
|
|
+ return true
|
|
|
+ }
|
|
|
+ return isArray(props.modelValue) && props.modelValue.length > 0;
|
|
|
+ })
|
|
|
+
|
|
|
+ const shouldShowPlaceholder = computed(() => {
|
|
|
+ return !states.inputValue
|
|
|
+ })
|
|
|
+
|
|
|
+ const currentPlaceholder = computed(() => {
|
|
|
+ if (props.multiple) {
|
|
|
+ return (props.modelValue as any[]).length > 0 ? '' : props.placeholder;
|
|
|
+ }
|
|
|
+ return states.selectedLabel || props.placeholder
|
|
|
+ })
|
|
|
+
|
|
|
+
|
|
|
+ const isTransparent = computed(() => {
|
|
|
+ return !hasModelValue.value || (expanded.value && !states.inputValue)
|
|
|
+ })
|
|
|
+
|
|
|
+ const showTagList = computed(() => {
|
|
|
+ if (props.multiple) {
|
|
|
+ const temp = states.selected.length > 0 ? [states.selected[0]] : []
|
|
|
+ return props.collapseTags ? temp : states.selected
|
|
|
+ }
|
|
|
+ return []
|
|
|
+ })
|
|
|
+
|
|
|
+ const deleteTag = (item: any, index: number) => {
|
|
|
+ (props.modelValue as ValueLabel[]).splice(index, 1)
|
|
|
+ states.selected.splice(index, 1)
|
|
|
+ }
|
|
|
+
|
|
|
+ function getObjValue(): string {
|
|
|
+ // @ts-ignore
|
|
|
+ return props.modelValue[props.value]
|
|
|
+ }
|
|
|
+
|
|
|
+ function getObjLabel(): string {
|
|
|
+ // @ts-ignore
|
|
|
+ return props.modelValue[props.label]
|
|
|
+ }
|
|
|
+
|
|
|
+ function getModelArr() {
|
|
|
+ return (props.modelValue as ValueLabel[])
|
|
|
+ }
|
|
|
+
|
|
|
+ function handleObj() {
|
|
|
+ states.selected = {
|
|
|
+ value: getObjValue(),
|
|
|
+ label: getObjLabel(),
|
|
|
+ }
|
|
|
+ states.selectedLabel = getObjLabel()
|
|
|
+ }
|
|
|
+
|
|
|
+ function handleSelect() {
|
|
|
+ if (props.modelValue === states.selected.value) {
|
|
|
+ states.selectedLabel = states.selected.label
|
|
|
+ return
|
|
|
+ }
|
|
|
+
|
|
|
+ const data = filter(propsData.value, (item) => {
|
|
|
+ return item.value === props.modelValue
|
|
|
+ })
|
|
|
+ if (data.length > 0) {
|
|
|
+ states.selected = {
|
|
|
+ value: data[0].value,
|
|
|
+ label: data[0].label,
|
|
|
+ }
|
|
|
+ states.selectedLabel = states.selected.label
|
|
|
+ return
|
|
|
+ }
|
|
|
+ states.selectedLabel = XEUtils.toString(props.modelValue)
|
|
|
+ }
|
|
|
+
|
|
|
+ function handleMultiple() {
|
|
|
+ let completelyEqualTo = true
|
|
|
+ if (states.selected.length === getModelArr().length) {
|
|
|
+ for (let i = 0, len = states.selected.length; i < len; i++) {
|
|
|
+ const item = states.selected[i];
|
|
|
+ const modItem = getModelArr()[i];
|
|
|
+ if (item.value !== modItem.value) {
|
|
|
+ completelyEqualTo = false
|
|
|
+ break;
|
|
|
+ }
|
|
|
+ }
|
|
|
+ } else {
|
|
|
+ completelyEqualTo = false
|
|
|
+ }
|
|
|
+
|
|
|
+ if (!completelyEqualTo) {
|
|
|
+ states.selected = XEUtils.clone(getModelArr(), true)
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+ function handleKeys() {
|
|
|
+ let completelyEqualTo = true
|
|
|
+
|
|
|
+ if (getModelArr().length !== states.selected.length) {
|
|
|
+ completelyEqualTo = false
|
|
|
+ } else {
|
|
|
+ for (let i = 0; i < states.selected.length; i++) {
|
|
|
+ const item = states.selected[i];
|
|
|
+ if (!getModelArr().includes(item.value)) {
|
|
|
+ completelyEqualTo = false
|
|
|
+ break;
|
|
|
+ }
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+ if (completelyEqualTo) {
|
|
|
+ return;
|
|
|
+ }
|
|
|
+
|
|
|
+ const tempKey = []
|
|
|
+ const data: {
|
|
|
+ [key: number]: ValueLabel
|
|
|
+ } = {};
|
|
|
+
|
|
|
+ for (let i = 0, len = propsData.value.length; i < len; i++) {
|
|
|
+ const item = propsData.value[i];
|
|
|
+ // @ts-ignore
|
|
|
+ const index = (getModelArr() as string[]).indexOf(item.value);
|
|
|
+ if (index > -1) {
|
|
|
+ tempKey.push(item.value)
|
|
|
+ data[index] = {
|
|
|
+ value: item.value,
|
|
|
+ label: item.label
|
|
|
+ }
|
|
|
+ }
|
|
|
+ if (tempKey.length === getModelArr().length) {
|
|
|
+ break;
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+ if (tempKey.length > 0) {
|
|
|
+ states.selected = XEUtils.toArray(data)
|
|
|
+ if (tempKey.length !== getModelArr().length) {
|
|
|
+ const selectedLength = states.selected.length
|
|
|
+ // @ts-ignore
|
|
|
+ for (let i = selectedLength; i < (getModelArr() as string[]).length; i++) {
|
|
|
+ const item = getModelArr()[i]
|
|
|
+ states.selected.push({
|
|
|
+ value: item,
|
|
|
+ label: item,
|
|
|
+ })
|
|
|
+ }
|
|
|
+ }
|
|
|
+ } else {
|
|
|
+ states.selected = []
|
|
|
+ // @ts-ignore
|
|
|
+ for (let i = 0; i < (getModelArr() as string[]).length; i++) {
|
|
|
+ const item = getModelArr()[i]
|
|
|
+ states.selected.push({
|
|
|
+ value: item,
|
|
|
+ label: item,
|
|
|
+ })
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+ }
|
|
|
+
|
|
|
+
|
|
|
+ function handleChangeModel() {
|
|
|
+ if (bindObj.value) {
|
|
|
+ handleObj()
|
|
|
+ } else if (props.multiple) {
|
|
|
+ if (props.keys) {
|
|
|
+ handleKeys()
|
|
|
+ } else {
|
|
|
+ handleMultiple()
|
|
|
+ }
|
|
|
+ } else {
|
|
|
+ handleSelect()
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+
|
|
|
+ watch(
|
|
|
+ () => props.modelValue,
|
|
|
+ (val, oldVal) => {
|
|
|
+ handleChangeModel()
|
|
|
+ if (!isEqual(val, oldVal)) {
|
|
|
+ formItem?.validate('change').then(r => console.log(r)).catch((err) => console.error(err))
|
|
|
+ }
|
|
|
+ }, {
|
|
|
+ flush: 'post',
|
|
|
+ deep: true,
|
|
|
+ }
|
|
|
+ )
|
|
|
+
|
|
|
+ watch(
|
|
|
+ () => expanded.value,
|
|
|
+ (val) => {
|
|
|
+ if (val) {
|
|
|
+ handleQueryChange(states.inputValue)
|
|
|
+ } else {
|
|
|
+ states.inputValue = ''
|
|
|
+ states.previousQuery = ''
|
|
|
+ }
|
|
|
+ emits('visible-change', val)
|
|
|
+ }
|
|
|
+ )
|
|
|
+
|
|
|
+ const resetCalculatorWidth = () => {
|
|
|
+ states.calculatorWidth = calculatorRef.value!.getBoundingClientRect().width
|
|
|
+ }
|
|
|
+
|
|
|
+ const updateTooltip = () => {
|
|
|
+ tooltipRef.value?.updatePopper?.()
|
|
|
+ }
|
|
|
+
|
|
|
+ const resetSelectionWidth = () => {
|
|
|
+ states.selectionWidth = selectionRef.value!.getBoundingClientRect().width
|
|
|
+ }
|
|
|
+
|
|
|
+ const resetCollapseItemWidth = () => {
|
|
|
+ states.collapseItemWidth =
|
|
|
+ collapseItemRef.value!.getBoundingClientRect().width
|
|
|
+ }
|
|
|
+
|
|
|
+ function columnsTableSortable() {
|
|
|
+ const el = (detailsTableRaf.value!['$el'] as HTMLDivElement).querySelector('.vxe-table--body tbody')
|
|
|
+ const ops = {
|
|
|
+ handle: '.vxe-body--row',
|
|
|
+ onEnd: function ({newIndex, oldIndex}: { newIndex: number, oldIndex: number }) {
|
|
|
+ const currRow = getModelArr().splice(oldIndex, 1)[0];
|
|
|
+ getModelArr().splice(newIndex, 0, currRow);
|
|
|
+
|
|
|
+ const currRow2 = states.selected.splice(oldIndex, 1)[0];
|
|
|
+ states.selected.splice(newIndex, 0, currRow2);
|
|
|
+ }
|
|
|
+ }
|
|
|
+ Sortable.create(el, ops)
|
|
|
+ }
|
|
|
+
|
|
|
+ useResizeObserver(calculatorRef, resetCalculatorWidth)
|
|
|
+ useResizeObserver(wrapperRef, () => {
|
|
|
+ updateTooltip()
|
|
|
+ wrapperHeightGoBeyond.value = wrapperRef.value!.getBoundingClientRect().height > 28
|
|
|
+ })
|
|
|
+ useResizeObserver(selectionRef, resetSelectionWidth)
|
|
|
+ useResizeObserver(collapseItemRef, resetCollapseItemWidth)
|
|
|
+
|
|
|
+ onMounted(() => {
|
|
|
+ if (props.multiple) {
|
|
|
+ if (!isArray(props.modelValue)) {
|
|
|
+ emits('update:modelValue', [])
|
|
|
+ }
|
|
|
+ props.sortable && columnsTableSortable()
|
|
|
+ }
|
|
|
+ })
|
|
|
+
|
|
|
+ return {
|
|
|
+ inputId,
|
|
|
+ nsSelect,
|
|
|
+ handleFocus,
|
|
|
+ inputRef,
|
|
|
+ handleBlur,
|
|
|
+ isFocused,
|
|
|
+ handleClickOutside,
|
|
|
+ tooltipRef,
|
|
|
+ popperRef,
|
|
|
+ dropdownMenuVisible,
|
|
|
+ tableRef,
|
|
|
+ states,
|
|
|
+ onInput,
|
|
|
+ handleCompositionStart,
|
|
|
+ handleCompositionUpdate,
|
|
|
+ handleCompositionEnd,
|
|
|
+ toggleMenu,
|
|
|
+ iconReverse,
|
|
|
+ showClear,
|
|
|
+ handleClearClick,
|
|
|
+ handleTableClick,
|
|
|
+ wrapperRef,
|
|
|
+ currentPlaceholder,
|
|
|
+ calculatorRef,
|
|
|
+ shouldShowPlaceholder,
|
|
|
+ isTransparent,
|
|
|
+ selectionRef,
|
|
|
+ collapseItemRef,
|
|
|
+ deleteTag,
|
|
|
+ showTagList,
|
|
|
+ detailsTableRaf,
|
|
|
+ tableData,
|
|
|
+ wrapperHeightGoBeyond,
|
|
|
+ selectDisabled,
|
|
|
+
|
|
|
+ inputStyle,
|
|
|
+ tagStyle,
|
|
|
+ collapseTagStyle,
|
|
|
+ }
|
|
|
+}
|
|
|
+
|