mirror of
https://github.com/element-plus/element-plus.git
synced 2024-11-21 01:02:59 +08:00
chore(components): [select-v2] remove ts-nocheck comments in select-v2 (#16746)
* 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>
This commit is contained in:
parent
6f1f506bcb
commit
cd517d6743
@ -4,7 +4,13 @@ import {
|
||||
useEmptyValuesProps,
|
||||
useSizeProp,
|
||||
} from '@element-plus/hooks'
|
||||
import { buildProps, definePropType, iconPropType } from '@element-plus/utils'
|
||||
import {
|
||||
buildProps,
|
||||
definePropType,
|
||||
iconPropType,
|
||||
isNumber,
|
||||
} from '@element-plus/utils'
|
||||
import { CHANGE_EVENT, UPDATE_MODEL_EVENT } from '@element-plus/constants'
|
||||
import { useTooltipContentProps } from '@element-plus/components/tooltip'
|
||||
import { CircleClose } from '@element-plus/icons-vue'
|
||||
import { tagProps } from '../../tag'
|
||||
@ -12,6 +18,8 @@ import { defaultProps } from './useProps'
|
||||
|
||||
import type { Option, OptionType } from './select.types'
|
||||
import type { Props } from './useProps'
|
||||
import type { EmitFn } from '@element-plus/utils/vue/typescript'
|
||||
import type { ExtractPropTypes } from 'vue'
|
||||
import type {
|
||||
Options,
|
||||
Placement,
|
||||
@ -269,3 +277,24 @@ export const OptionProps = buildProps({
|
||||
selected: Boolean,
|
||||
created: Boolean,
|
||||
} as const)
|
||||
|
||||
/* eslint-disable @typescript-eslint/no-unused-vars */
|
||||
export const selectEmits = {
|
||||
[UPDATE_MODEL_EVENT]: (val: ISelectV2Props['modelValue']) => true,
|
||||
[CHANGE_EVENT]: (val: ISelectV2Props['modelValue']) => true,
|
||||
'remove-tag': (val: unknown) => true,
|
||||
'visible-change': (visible: boolean) => true,
|
||||
focus: (evt: FocusEvent) => evt instanceof FocusEvent,
|
||||
blur: (evt: FocusEvent) => evt instanceof FocusEvent,
|
||||
clear: () => true,
|
||||
}
|
||||
export const optionEmits = {
|
||||
hover: (index?: number) => isNumber(index),
|
||||
select: (val: Option, index?: number) => true,
|
||||
}
|
||||
/* eslint-enable @typescript-eslint/no-unused-vars */
|
||||
|
||||
export type ISelectV2Props = ExtractPropTypes<typeof SelectProps>
|
||||
export type IOptionV2Props = ExtractPropTypes<typeof OptionProps>
|
||||
export type SelectEmitFn = EmitFn<typeof selectEmits>
|
||||
export type OptionEmitFn = EmitFn<typeof optionEmits>
|
||||
|
@ -1,16 +1,16 @@
|
||||
<template>
|
||||
<div
|
||||
:class="ns.be('group', 'title')"
|
||||
:style="[style, { lineHeight: `${height}px` }]"
|
||||
:style="{ ...style, lineHeight: `${height}px` }"
|
||||
>
|
||||
{{ item.label }}
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script lang="ts">
|
||||
// @ts-nocheck
|
||||
import { defineComponent } from 'vue'
|
||||
import { useNamespace } from '@element-plus/hooks'
|
||||
import type { CSSProperties, PropType } from 'vue'
|
||||
|
||||
export default defineComponent({
|
||||
props: {
|
||||
@ -18,7 +18,9 @@ export default defineComponent({
|
||||
type: Object,
|
||||
required: true,
|
||||
},
|
||||
style: Object,
|
||||
style: {
|
||||
type: Object as PropType<CSSProperties>,
|
||||
},
|
||||
height: Number,
|
||||
},
|
||||
setup() {
|
||||
|
@ -23,12 +23,12 @@ import { defineComponent, inject } from 'vue'
|
||||
import { useNamespace } from '@element-plus/hooks'
|
||||
import { useOption } from './useOption'
|
||||
import { useProps } from './useProps'
|
||||
import { OptionProps } from './defaults'
|
||||
import { OptionProps, optionEmits } from './defaults'
|
||||
import { selectV2InjectionKey } from './token'
|
||||
|
||||
export default defineComponent({
|
||||
props: OptionProps,
|
||||
emits: ['select', 'hover'],
|
||||
emits: optionEmits,
|
||||
setup(props, { emit }) {
|
||||
const select = inject(selectV2InjectionKey)!
|
||||
const ns = useNamespace('select')
|
||||
|
@ -21,21 +21,44 @@ import { useProps } from './useProps'
|
||||
|
||||
import { selectV2InjectionKey } from './token'
|
||||
|
||||
import type { ItemProps } from '@element-plus/components/virtual-list'
|
||||
import type {
|
||||
DynamicSizeListInstance,
|
||||
FixedSizeListInstance,
|
||||
ItemProps,
|
||||
} from '@element-plus/components/virtual-list'
|
||||
import type { Option, OptionItemProps } from './select.types'
|
||||
import type {
|
||||
ComponentPublicInstance,
|
||||
ComputedRef,
|
||||
ExtractPropTypes,
|
||||
Ref,
|
||||
} from 'vue'
|
||||
|
||||
const props = {
|
||||
loading: Boolean,
|
||||
data: {
|
||||
type: Array,
|
||||
required: true as const,
|
||||
},
|
||||
hoveringIndex: Number,
|
||||
width: Number,
|
||||
}
|
||||
interface SelectDropdownExposed {
|
||||
listRef: Ref<FixedSizeListInstance | DynamicSizeListInstance | undefined>
|
||||
isSized: ComputedRef<boolean>
|
||||
isItemDisabled: (modelValue: any[] | any, selected: boolean) => boolean
|
||||
isItemHovering: (target: number) => boolean
|
||||
isItemSelected: (modelValue: any[] | any, target: Option) => boolean
|
||||
scrollToItem: (index: number) => void
|
||||
resetScrollTop: () => void
|
||||
}
|
||||
export type SelectDropdownInstance = ComponentPublicInstance<
|
||||
ExtractPropTypes<typeof props>,
|
||||
SelectDropdownExposed
|
||||
>
|
||||
export default defineComponent({
|
||||
name: 'ElSelectDropdown',
|
||||
|
||||
props: {
|
||||
loading: Boolean,
|
||||
data: {
|
||||
type: Array,
|
||||
required: true,
|
||||
},
|
||||
hoveringIndex: Number,
|
||||
width: Number,
|
||||
},
|
||||
props,
|
||||
setup(props, { slots, expose }) {
|
||||
const select = inject(selectV2InjectionKey)!
|
||||
const ns = useNamespace('select')
|
||||
@ -43,13 +66,13 @@ export default defineComponent({
|
||||
|
||||
const cachedHeights = ref<Array<number>>([])
|
||||
|
||||
const listRef = ref()
|
||||
const listRef = ref<FixedSizeListInstance | DynamicSizeListInstance>()
|
||||
|
||||
const size = computed(() => props.data.length)
|
||||
watch(
|
||||
() => size.value,
|
||||
() => {
|
||||
select.tooltipRef.value.updatePopper?.()
|
||||
select.tooltipRef.value!.updatePopper?.()
|
||||
}
|
||||
)
|
||||
|
||||
@ -94,14 +117,20 @@ export default defineComponent({
|
||||
}
|
||||
}
|
||||
|
||||
const isItemSelected = (modelValue: any[] | any, target: Option) => {
|
||||
const isItemSelected: SelectDropdownExposed['isItemSelected'] = (
|
||||
modelValue,
|
||||
target
|
||||
) => {
|
||||
if (select.props.multiple) {
|
||||
return contains(modelValue, getValue(target))
|
||||
}
|
||||
return isEqual(modelValue, getValue(target))
|
||||
}
|
||||
|
||||
const isItemDisabled = (modelValue: any[] | any, selected: boolean) => {
|
||||
const isItemDisabled: SelectDropdownExposed['isItemDisabled'] = (
|
||||
modelValue,
|
||||
selected
|
||||
) => {
|
||||
const { disabled, multiple, multipleLimit } = select.props
|
||||
return (
|
||||
disabled ||
|
||||
@ -112,23 +141,23 @@ export default defineComponent({
|
||||
)
|
||||
}
|
||||
|
||||
const isItemHovering = (target: number) => props.hoveringIndex === target
|
||||
const isItemHovering: SelectDropdownExposed['isItemHovering'] = (target) =>
|
||||
props.hoveringIndex === target
|
||||
|
||||
const scrollToItem = (index: number) => {
|
||||
const list = listRef.value as any
|
||||
const scrollToItem: SelectDropdownExposed['scrollToItem'] = (index) => {
|
||||
const list = listRef.value
|
||||
if (list) {
|
||||
list.scrollToItem(index)
|
||||
}
|
||||
}
|
||||
|
||||
const resetScrollTop = () => {
|
||||
const list = listRef.value as any
|
||||
const resetScrollTop: SelectDropdownExposed['resetScrollTop'] = () => {
|
||||
const list = listRef.value
|
||||
if (list) {
|
||||
list.resetScrollTop()
|
||||
}
|
||||
}
|
||||
|
||||
expose({
|
||||
const exposed: SelectDropdownExposed = {
|
||||
listRef,
|
||||
isSized,
|
||||
|
||||
@ -137,7 +166,8 @@ export default defineComponent({
|
||||
isItemSelected,
|
||||
scrollToItem,
|
||||
resetScrollTop,
|
||||
})
|
||||
}
|
||||
expose(exposed)
|
||||
|
||||
const Item = (itemProps: ItemProps<any>) => {
|
||||
const { index, data, style } = itemProps
|
||||
@ -151,7 +181,7 @@ export default defineComponent({
|
||||
<GroupItem
|
||||
item={item}
|
||||
style={style}
|
||||
height={(sized ? itemSize : estimatedSize) as number}
|
||||
height={sized ? (itemSize as number) : estimatedSize}
|
||||
/>
|
||||
)
|
||||
}
|
||||
@ -190,7 +220,8 @@ export default defineComponent({
|
||||
}
|
||||
|
||||
const onEscOrTab = () => {
|
||||
select.expanded = false
|
||||
// The following line actually doesn't work. Fixing it may introduce a small breaking change for some users, so just comment it out for now.
|
||||
// select.expanded = false
|
||||
}
|
||||
|
||||
const onKeydown = (e: KeyboardEvent) => {
|
||||
|
@ -13,3 +13,18 @@ export type OptionItemProps = {
|
||||
index: number
|
||||
disabled: boolean
|
||||
}
|
||||
export type SelectStates = {
|
||||
inputValue: string
|
||||
cachedOptions: Option[]
|
||||
createdOptions: Option[]
|
||||
hoveringIndex: number
|
||||
inputHovering: boolean
|
||||
selectionWidth: number
|
||||
calculatorWidth: number
|
||||
collapseItemWidth: number
|
||||
previousQuery: string | null
|
||||
previousValue: unknown
|
||||
selectedLabel: string
|
||||
menuVisibleOnFocus: boolean
|
||||
isBeforeHide: boolean
|
||||
}
|
||||
|
@ -280,10 +280,9 @@ import { ClickOutside } from '@element-plus/directives'
|
||||
import ElTooltip from '@element-plus/components/tooltip'
|
||||
import ElTag from '@element-plus/components/tag'
|
||||
import ElIcon from '@element-plus/components/icon'
|
||||
import { CHANGE_EVENT, UPDATE_MODEL_EVENT } from '@element-plus/constants'
|
||||
import ElSelectMenu from './select-dropdown'
|
||||
import useSelect from './useSelect'
|
||||
import { SelectProps } from './defaults'
|
||||
import { SelectProps, selectEmits } from './defaults'
|
||||
import { selectV2InjectionKey } from './token'
|
||||
|
||||
export default defineComponent({
|
||||
@ -296,16 +295,7 @@ export default defineComponent({
|
||||
},
|
||||
directives: { ClickOutside },
|
||||
props: SelectProps,
|
||||
emits: [
|
||||
UPDATE_MODEL_EVENT,
|
||||
CHANGE_EVENT,
|
||||
'remove-tag',
|
||||
'clear',
|
||||
'visible-change',
|
||||
'focus',
|
||||
'blur',
|
||||
],
|
||||
|
||||
emits: selectEmits,
|
||||
setup(props, { emit }) {
|
||||
const modelValue = computed(() => {
|
||||
const { modelValue: rawModelValue, multiple } = props
|
||||
@ -325,19 +315,19 @@ export default defineComponent({
|
||||
}),
|
||||
emit
|
||||
)
|
||||
// TODO, remove the any cast to align the actual API.
|
||||
provide(selectV2InjectionKey, {
|
||||
props: reactive({
|
||||
...toRefs(props),
|
||||
height: API.popupHeight,
|
||||
modelValue,
|
||||
}),
|
||||
expanded: API.expanded,
|
||||
tooltipRef: API.tooltipRef,
|
||||
onSelect: API.onSelect,
|
||||
onHover: API.onHover,
|
||||
onKeyboardNavigate: API.onKeyboardNavigate,
|
||||
onKeyboardSelect: API.onKeyboardSelect,
|
||||
} as any)
|
||||
})
|
||||
|
||||
return {
|
||||
...API,
|
||||
|
@ -1,14 +1,14 @@
|
||||
import type { OptionProps, SelectProps } from './defaults'
|
||||
import type { ExtractPropTypes, InjectionKey, Ref } from 'vue'
|
||||
import type { IOptionV2Props, ISelectV2Props } from './defaults'
|
||||
import type { InjectionKey, Ref } from 'vue'
|
||||
import type { Option } from './select.types'
|
||||
import type { TooltipInstance } from '@element-plus/components/tooltip'
|
||||
|
||||
export interface SelectV2Context {
|
||||
props: ExtractPropTypes<typeof SelectProps>
|
||||
expanded: boolean
|
||||
tooltipRef: Ref<TooltipInstance>
|
||||
props: ISelectV2Props
|
||||
expanded: Ref<boolean>
|
||||
tooltipRef: Ref<TooltipInstance | undefined>
|
||||
onSelect: (option: Option) => void
|
||||
onHover: (idx: number) => void
|
||||
onHover: (idx?: number) => void
|
||||
onKeyboardNavigate: (direction: 'forward' | 'backward') => void
|
||||
onKeyboardSelect: () => void
|
||||
}
|
||||
@ -16,5 +16,4 @@ export interface SelectV2Context {
|
||||
export const selectV2InjectionKey: InjectionKey<SelectV2Context> = Symbol(
|
||||
'ElSelectV2Injection'
|
||||
)
|
||||
export type IOptionV2Props = ExtractPropTypes<typeof OptionProps>
|
||||
export type ISelectV2Props = ExtractPropTypes<typeof SelectProps>
|
||||
export type { ISelectV2Props, IOptionV2Props }
|
||||
|
@ -1,21 +1,20 @@
|
||||
// @ts-nocheck
|
||||
import { computed, ref } from 'vue'
|
||||
import { useProps } from './useProps'
|
||||
import type { ISelectV2Props } from './token'
|
||||
import type { Option } from './select.types'
|
||||
import type { Option, SelectStates } from './select.types'
|
||||
|
||||
export function useAllowCreate(props: ISelectV2Props, states) {
|
||||
export function useAllowCreate(props: ISelectV2Props, states: SelectStates) {
|
||||
const { aliasProps, getLabel, getValue } = useProps(props)
|
||||
|
||||
const createOptionCount = ref(0)
|
||||
const cachedSelectedOption = ref<Option>(null)
|
||||
const cachedSelectedOption = ref<Option>()
|
||||
|
||||
const enableAllowCreateMode = computed(() => {
|
||||
return props.allowCreate && props.filterable
|
||||
})
|
||||
|
||||
function hasExistingOption(query: string) {
|
||||
const hasOption = (option) => getLabel(option) === query
|
||||
const hasOption = (option: Option) => getLabel(option) === query
|
||||
return (
|
||||
(props.options && props.options.some(hasOption)) ||
|
||||
states.createdOptions.some(hasOption)
|
||||
|
@ -1,7 +1,10 @@
|
||||
// @ts-nocheck
|
||||
import type { IOptionV2Props } from './token'
|
||||
import type { OptionEmitFn } from './defaults'
|
||||
|
||||
export function useOption(props: IOptionV2Props, { emit }) {
|
||||
export function useOption(
|
||||
props: IOptionV2Props,
|
||||
{ emit }: { emit: OptionEmitFn }
|
||||
) {
|
||||
return {
|
||||
hoverItem: () => {
|
||||
if (!props.disabled) {
|
||||
|
@ -1,4 +1,3 @@
|
||||
// @ts-nocheck
|
||||
import {
|
||||
computed,
|
||||
nextTick,
|
||||
@ -45,13 +44,15 @@ import { ArrowDown } from '@element-plus/icons-vue'
|
||||
import { useAllowCreate } from './useAllowCreate'
|
||||
import { useProps } from './useProps'
|
||||
|
||||
import type ElTooltip from '@element-plus/components/tooltip'
|
||||
import type { Option, OptionType } from './select.types'
|
||||
import type { Option, OptionType, SelectStates } from './select.types'
|
||||
import type { ISelectV2Props } from './token'
|
||||
import type { SelectEmitFn } from './defaults'
|
||||
import type { TooltipInstance } from '@element-plus/components/tooltip'
|
||||
import type { SelectDropdownInstance } from './select-dropdown'
|
||||
|
||||
const MINIMUM_INPUT_WIDTH = 11
|
||||
|
||||
const useSelect = (props: ISelectV2Props, emit) => {
|
||||
const useSelect = (props: ISelectV2Props, emit: SelectEmitFn) => {
|
||||
// inject
|
||||
const { t } = useLocale()
|
||||
const nsSelect = useNamespace('select')
|
||||
@ -64,10 +65,10 @@ const useSelect = (props: ISelectV2Props, emit) => {
|
||||
useProps(props)
|
||||
const { valueOnClear, isEmptyValue } = useEmptyValues(props)
|
||||
|
||||
const states = reactive({
|
||||
const states: SelectStates = reactive({
|
||||
inputValue: '',
|
||||
cachedOptions: [] as Option[],
|
||||
createdOptions: [] as Option[],
|
||||
cachedOptions: [],
|
||||
createdOptions: [],
|
||||
hoveringIndex: -1,
|
||||
inputHovering: false,
|
||||
selectionWidth: 0,
|
||||
@ -84,17 +85,17 @@ const useSelect = (props: ISelectV2Props, emit) => {
|
||||
const popperSize = ref(-1)
|
||||
|
||||
// DOM & Component refs
|
||||
const selectRef = ref<HTMLElement>(null)
|
||||
const selectionRef = ref<HTMLElement>(null)
|
||||
const tooltipRef = ref<InstanceType<typeof ElTooltip> | null>(null)
|
||||
const tagTooltipRef = ref<InstanceType<typeof ElTooltip> | null>(null)
|
||||
const inputRef = ref<HTMLElement>(null)
|
||||
const calculatorRef = ref<HTMLElement>(null)
|
||||
const prefixRef = ref<HTMLElement>(null)
|
||||
const suffixRef = ref<HTMLElement>(null)
|
||||
const menuRef = ref<HTMLElement>(null)
|
||||
const tagMenuRef = ref<HTMLElement>(null)
|
||||
const collapseItemRef = ref<HTMLElement>(null)
|
||||
const selectRef = ref<HTMLElement>()
|
||||
const selectionRef = ref<HTMLElement>()
|
||||
const tooltipRef = ref<TooltipInstance>()
|
||||
const tagTooltipRef = ref<TooltipInstance>()
|
||||
const inputRef = ref<HTMLElement>()
|
||||
const calculatorRef = ref<HTMLElement>()
|
||||
const prefixRef = ref<HTMLElement>()
|
||||
const suffixRef = ref<HTMLElement>()
|
||||
const menuRef = ref<SelectDropdownInstance>()
|
||||
const tagMenuRef = ref<HTMLElement>()
|
||||
const collapseItemRef = ref<HTMLElement>()
|
||||
|
||||
const {
|
||||
isComposing,
|
||||
@ -127,8 +128,8 @@ const useSelect = (props: ISelectV2Props, emit) => {
|
||||
},
|
||||
})
|
||||
|
||||
const allOptions = ref([])
|
||||
const filteredOptions = ref([])
|
||||
const allOptions = ref<OptionType[]>([])
|
||||
const filteredOptions = ref<OptionType[]>([])
|
||||
// the controller of the expanded popup
|
||||
const expanded = ref(false)
|
||||
|
||||
@ -163,9 +164,13 @@ const useSelect = (props: ISelectV2Props, emit) => {
|
||||
)
|
||||
|
||||
const validateState = computed(() => elFormItem?.validateState || '')
|
||||
const validateIcon = computed(
|
||||
() => ValidateComponentsMap[validateState.value]
|
||||
)
|
||||
const validateIcon = computed(() => {
|
||||
// When we use indexed access to get the type of an undeclared property,
|
||||
// the unsafe type `any` will be inferred, which TypeScript throws an error to emphasize it.
|
||||
// To avoid TypeScript complaining about it, we use truthiness narrowing to narrow the type of validateState.
|
||||
if (!validateState.value) return
|
||||
return ValidateComponentsMap[validateState.value]
|
||||
})
|
||||
|
||||
const debounce = computed(() => (props.remote ? 300 : 0))
|
||||
|
||||
@ -191,7 +196,7 @@ const useSelect = (props: ISelectV2Props, emit) => {
|
||||
return null
|
||||
})
|
||||
|
||||
const filterOptions = (query) => {
|
||||
const filterOptions = (query: string) => {
|
||||
const isValidOption = (o: Option): boolean => {
|
||||
if (props.filterable && isFunction(props.filterMethod)) return true
|
||||
if (props.filterable && props.remote && isFunction(props.remoteMethod))
|
||||
@ -228,8 +233,8 @@ const useSelect = (props: ISelectV2Props, emit) => {
|
||||
}
|
||||
|
||||
const updateOptions = () => {
|
||||
allOptions.value = filterOptions('') as OptionType[]
|
||||
filteredOptions.value = filterOptions(states.inputValue) as OptionType[]
|
||||
allOptions.value = filterOptions('')
|
||||
filteredOptions.value = filterOptions(states.inputValue)
|
||||
}
|
||||
|
||||
const allOptionsValueMap = computed(() => {
|
||||
@ -449,7 +454,7 @@ const useSelect = (props: ISelectV2Props, emit) => {
|
||||
states.previousValue = props.multiple ? String(val) : val
|
||||
}
|
||||
|
||||
const getValueIndex = (arr = [], value: unknown) => {
|
||||
const getValueIndex = (arr: unknown[] = [], value: unknown) => {
|
||||
if (!isObject(value)) {
|
||||
return arr.indexOf(value)
|
||||
}
|
||||
@ -474,16 +479,16 @@ const useSelect = (props: ISelectV2Props, emit) => {
|
||||
}
|
||||
|
||||
const resetSelectionWidth = () => {
|
||||
states.selectionWidth = selectionRef.value.getBoundingClientRect().width
|
||||
states.selectionWidth = selectionRef.value!.getBoundingClientRect().width
|
||||
}
|
||||
|
||||
const resetCalculatorWidth = () => {
|
||||
states.calculatorWidth = calculatorRef.value.getBoundingClientRect().width
|
||||
states.calculatorWidth = calculatorRef.value!.getBoundingClientRect().width
|
||||
}
|
||||
|
||||
const resetCollapseItemWidth = () => {
|
||||
states.collapseItemWidth =
|
||||
collapseItemRef.value.getBoundingClientRect().width
|
||||
collapseItemRef.value!.getBoundingClientRect().width
|
||||
}
|
||||
|
||||
const updateTooltip = () => {
|
||||
@ -569,7 +574,7 @@ const useSelect = (props: ISelectV2Props, emit) => {
|
||||
}
|
||||
}
|
||||
|
||||
const getLastNotDisabledIndex = (value) =>
|
||||
const getLastNotDisabledIndex = (value: unknown[]) =>
|
||||
findLastIndex(
|
||||
value,
|
||||
(it) =>
|
||||
@ -618,8 +623,8 @@ const useSelect = (props: ISelectV2Props, emit) => {
|
||||
|
||||
const onKeyboardNavigate = (
|
||||
direction: 'forward' | 'backward',
|
||||
hoveringIndex: number = undefined
|
||||
) => {
|
||||
hoveringIndex: number | undefined = undefined
|
||||
): void => {
|
||||
const options = filteredOptions.value
|
||||
if (
|
||||
!['forward', 'backward'].includes(direction) ||
|
||||
@ -671,8 +676,8 @@ const useSelect = (props: ISelectV2Props, emit) => {
|
||||
}
|
||||
}
|
||||
|
||||
const onHoverOption = (idx: number) => {
|
||||
states.hoveringIndex = idx
|
||||
const onHoverOption = (idx?: number) => {
|
||||
states.hoveringIndex = idx ?? -1
|
||||
}
|
||||
|
||||
const updateHoveringIndex = () => {
|
||||
@ -683,14 +688,14 @@ const useSelect = (props: ISelectV2Props, emit) => {
|
||||
} else {
|
||||
states.hoveringIndex = filteredOptions.value.findIndex((item) =>
|
||||
props.modelValue.some(
|
||||
(modelValue) => getValueKey(modelValue) === getValueKey(item)
|
||||
(modelValue: unknown) => getValueKey(modelValue) === getValueKey(item)
|
||||
)
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
const onInput = (event) => {
|
||||
states.inputValue = event.target.value
|
||||
const onInput = (event: Event) => {
|
||||
states.inputValue = (event.target as HTMLInputElement).value
|
||||
if (props.remote) {
|
||||
debouncedOnInputChange()
|
||||
} else {
|
||||
@ -713,10 +718,10 @@ const useSelect = (props: ISelectV2Props, emit) => {
|
||||
}
|
||||
|
||||
const scrollToItem = (index: number) => {
|
||||
menuRef.value.scrollToItem(index)
|
||||
menuRef.value!.scrollToItem(index)
|
||||
}
|
||||
|
||||
const getOption = (value: any, cachedOptions?: Option[]) => {
|
||||
const getOption = (value: unknown, cachedOptions?: Option[]) => {
|
||||
// match the option with the given value, if not found, create a new option
|
||||
const selectValue = getValueKey(value)
|
||||
|
||||
|
@ -4,6 +4,8 @@ export { default as FixedSizeGrid } from './src/components/fixed-size-grid'
|
||||
export { default as DynamicSizeGrid } from './src/components/dynamic-size-grid'
|
||||
export * from './src/props'
|
||||
|
||||
export type { FixedSizeListInstance } from './src/components/fixed-size-list'
|
||||
export type { DynamicSizeListInstance } from './src/components/dynamic-size-list'
|
||||
export type { GridInstance } from './src/builders/build-grid'
|
||||
export type {
|
||||
DynamicSizeGridInstance,
|
||||
|
@ -1,4 +1,3 @@
|
||||
// @ts-nocheck
|
||||
import {
|
||||
Fragment,
|
||||
computed,
|
||||
@ -62,7 +61,7 @@ const createList = ({
|
||||
|
||||
const dynamicSizeCache = ref(initCache(props, instance))
|
||||
|
||||
const getItemStyleCache = useCache()
|
||||
const getItemStyleCache = useCache<CSSProperties>()
|
||||
// refs
|
||||
// here windowRef and innerRef can be type of HTMLElement
|
||||
// or user defined component type, depends on the type passed
|
||||
@ -418,7 +417,7 @@ const createList = ({
|
||||
})
|
||||
|
||||
onActivated(() => {
|
||||
unref(windowRef).scrollTop = unref(states).scrollOffset
|
||||
unref(windowRef)!.scrollTop = unref(states).scrollOffset
|
||||
})
|
||||
|
||||
const api = {
|
||||
|
@ -254,4 +254,5 @@ const DynamicSizeList = createList({
|
||||
},
|
||||
})
|
||||
|
||||
export type DynamicSizeListInstance = InstanceType<typeof DynamicSizeList>
|
||||
export default DynamicSizeList
|
||||
|
@ -125,4 +125,5 @@ const FixedSizeList = buildList({
|
||||
},
|
||||
})
|
||||
|
||||
export type FixedSizeListInstance = InstanceType<typeof FixedSizeList>
|
||||
export default FixedSizeList
|
||||
|
@ -4,14 +4,15 @@ import memoOne from 'memoize-one'
|
||||
|
||||
import type { VirtualizedProps } from '../props'
|
||||
|
||||
export const useCache = () => {
|
||||
export const useCache = <T>() => {
|
||||
const vm = getCurrentInstance()!
|
||||
|
||||
const props = vm.proxy!.$props as VirtualizedProps
|
||||
|
||||
return computed(() => {
|
||||
// eslint-disable-next-line @typescript-eslint/no-unused-vars
|
||||
const _getItemStyleCache = (_: any, __: any, ___: any) => ({})
|
||||
const _getItemStyleCache = (_: any, __: any, ___: any) =>
|
||||
({} as Record<string, T>)
|
||||
return props.perfMode
|
||||
? memoize(_getItemStyleCache)
|
||||
: memoOne(_getItemStyleCache)
|
||||
|
@ -1,7 +1,9 @@
|
||||
import type { AppContext, Plugin } from 'vue'
|
||||
import type { AppContext, EmitsOptions, Plugin, SetupContext } from 'vue'
|
||||
|
||||
export type SFCWithInstall<T> = T & Plugin
|
||||
|
||||
export type SFCInstallWithContext<T> = SFCWithInstall<T> & {
|
||||
_context: AppContext | null
|
||||
}
|
||||
|
||||
export type EmitFn<E extends EmitsOptions> = SetupContext<E>['emit']
|
||||
|
4
typings/env.d.ts
vendored
4
typings/env.d.ts
vendored
@ -10,8 +10,8 @@ declare global {
|
||||
|
||||
namespace JSX {
|
||||
interface IntrinsicAttributes {
|
||||
class?: any
|
||||
style?: any
|
||||
class?: unknown
|
||||
style?: unknown
|
||||
}
|
||||
}
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user