fix: select keyboard position error
parent
656d14fc4e
commit
604372ff2d
|
@ -0,0 +1,16 @@
|
|||
import { Ref, ref, watch } from 'vue';
|
||||
|
||||
export default function useMemo<T>(
|
||||
getValue: () => T,
|
||||
condition: any[],
|
||||
shouldUpdate: (prev: any[], next: any[]) => boolean,
|
||||
) {
|
||||
const cacheRef: Ref<T> = ref(getValue() as any);
|
||||
watch(condition, (pre, next) => {
|
||||
if (shouldUpdate(pre, next)) {
|
||||
cacheRef.value = getValue();
|
||||
}
|
||||
});
|
||||
|
||||
return cacheRef;
|
||||
}
|
|
@ -14,6 +14,7 @@ import {
|
|||
OnActiveValue,
|
||||
} from './interface';
|
||||
import { RawValueType, FlattenOptionsType } from './interface/generator';
|
||||
import useMemo from '../_util/hooks/useMemo';
|
||||
export interface OptionListProps {
|
||||
prefixCls: string;
|
||||
id: string;
|
||||
|
@ -78,6 +79,12 @@ const OptionList = defineComponent<OptionListProps, { state?: any }>({
|
|||
setup(props) {
|
||||
const itemPrefixCls = computed(() => `${props.prefixCls}-item`);
|
||||
|
||||
const memoFlattenOptions = useMemo(
|
||||
() => props.flattenOptions,
|
||||
[() => props.open, () => props.flattenOptions],
|
||||
(prev, next) => next[0] && prev[1] !== next[1],
|
||||
);
|
||||
|
||||
// =========================== List ===========================
|
||||
const listRef = createRef();
|
||||
|
||||
|
@ -93,12 +100,12 @@ const OptionList = defineComponent<OptionListProps, { state?: any }>({
|
|||
|
||||
// ========================== Active ==========================
|
||||
const getEnabledActiveIndex = (index: number, offset = 1) => {
|
||||
const len = props.flattenOptions.length;
|
||||
const len = memoFlattenOptions.value.length;
|
||||
|
||||
for (let i = 0; i < len; i += 1) {
|
||||
const current = (index + i * offset + len) % len;
|
||||
|
||||
const { group, data } = props.flattenOptions[current];
|
||||
const { group, data } = memoFlattenOptions.value[current];
|
||||
if (!group && !(data as OptionData).disabled) {
|
||||
return current;
|
||||
}
|
||||
|
@ -115,7 +122,7 @@ const OptionList = defineComponent<OptionListProps, { state?: any }>({
|
|||
const info = { source: fromKeyboard ? ('keyboard' as const) : ('mouse' as const) };
|
||||
|
||||
// Trigger active event
|
||||
const flattenItem = props.flattenOptions[index];
|
||||
const flattenItem = memoFlattenOptions.value[index];
|
||||
if (!flattenItem) {
|
||||
props.onActiveValue(null, -1, info);
|
||||
return;
|
||||
|
@ -127,7 +134,7 @@ const OptionList = defineComponent<OptionListProps, { state?: any }>({
|
|||
// Auto active first item when list length or searchValue changed
|
||||
|
||||
watch(
|
||||
computed(() => [props.flattenOptions.length, props.searchValue]),
|
||||
[() => memoFlattenOptions.value.length, () => props.searchValue],
|
||||
() => {
|
||||
setActive(props.defaultActiveFirstOption !== false ? getEnabledActiveIndex(0) : -1);
|
||||
},
|
||||
|
@ -136,11 +143,11 @@ const OptionList = defineComponent<OptionListProps, { state?: any }>({
|
|||
// Auto scroll to item position in single mode
|
||||
|
||||
watch(
|
||||
computed(() => props.open),
|
||||
() => props.open,
|
||||
() => {
|
||||
if (!props.multiple && props.open && props.values.size === 1) {
|
||||
const value = Array.from(props.values)[0];
|
||||
const index = props.flattenOptions.findIndex(({ data }) => data.value === value);
|
||||
const index = memoFlattenOptions.value.findIndex(({ data }) => data.value === value);
|
||||
setActive(index);
|
||||
scrollIntoView(index);
|
||||
}
|
||||
|
@ -167,7 +174,7 @@ const OptionList = defineComponent<OptionListProps, { state?: any }>({
|
|||
};
|
||||
|
||||
function renderItem(index: number) {
|
||||
const item = props.flattenOptions[index];
|
||||
const item = memoFlattenOptions.value[index];
|
||||
if (!item) return null;
|
||||
|
||||
const itemData = (item.data || {}) as OptionData;
|
||||
|
@ -188,6 +195,7 @@ const OptionList = defineComponent<OptionListProps, { state?: any }>({
|
|||
) : null;
|
||||
}
|
||||
return {
|
||||
memoFlattenOptions,
|
||||
renderItem,
|
||||
listRef,
|
||||
state,
|
||||
|
@ -220,7 +228,7 @@ const OptionList = defineComponent<OptionListProps, { state?: any }>({
|
|||
// >>> Select
|
||||
case KeyCode.ENTER: {
|
||||
// value
|
||||
const item = props.flattenOptions[state.activeIndex];
|
||||
const item = memoFlattenOptions.value[state.activeIndex];
|
||||
if (item && !item.data.disabled) {
|
||||
onSelectValue(item.data.value);
|
||||
} else {
|
||||
|
@ -258,6 +266,7 @@ const OptionList = defineComponent<OptionListProps, { state?: any }>({
|
|||
itemPrefixCls,
|
||||
setActive,
|
||||
onSelectValue,
|
||||
memoFlattenOptions,
|
||||
} = this as any;
|
||||
const {
|
||||
id,
|
||||
|
@ -265,7 +274,6 @@ const OptionList = defineComponent<OptionListProps, { state?: any }>({
|
|||
values,
|
||||
height,
|
||||
itemHeight,
|
||||
flattenOptions,
|
||||
menuItemSelectedIcon,
|
||||
notFoundContent,
|
||||
virtual,
|
||||
|
@ -274,7 +282,7 @@ const OptionList = defineComponent<OptionListProps, { state?: any }>({
|
|||
} = this.$props as OptionListProps;
|
||||
const { activeIndex } = this.state;
|
||||
// ========================== Render ==========================
|
||||
if (flattenOptions.length === 0) {
|
||||
if (memoFlattenOptions.length === 0) {
|
||||
return (
|
||||
<div
|
||||
role="listbox"
|
||||
|
@ -296,7 +304,7 @@ const OptionList = defineComponent<OptionListProps, { state?: any }>({
|
|||
<List
|
||||
itemKey="key"
|
||||
ref={listRef}
|
||||
data={flattenOptions}
|
||||
data={memoFlattenOptions}
|
||||
height={height}
|
||||
itemHeight={itemHeight}
|
||||
fullHeight={false}
|
||||
|
|
|
@ -11,7 +11,7 @@ import {
|
|||
import PropTypes from '../../_util/vue-types';
|
||||
import { RefObject } from '../../_util/createRef';
|
||||
import antInput from '../../_util/antInputDirective';
|
||||
import classNames from 'ant-design-vue/es/_util/classNames';
|
||||
import classNames from '../../_util/classNames';
|
||||
|
||||
interface InputProps {
|
||||
prefixCls: string;
|
||||
|
|
|
@ -50,7 +50,7 @@ const SingleSelector = defineComponent<SelectorProps>({
|
|||
return inputValue;
|
||||
});
|
||||
watch(
|
||||
computed(() => [combobox.value, props.activeValue]),
|
||||
[combobox, () => props.activeValue],
|
||||
() => {
|
||||
if (combobox.value) {
|
||||
inputChanged.value = false;
|
||||
|
|
|
@ -397,9 +397,9 @@ export default function generateSelector<
|
|||
// ============================== Ref ===============================
|
||||
const selectorDomRef = createRef();
|
||||
|
||||
const mergedValue = ref(undefined);
|
||||
const mergedValue = ref();
|
||||
watch(
|
||||
computed(() => [props.value, props.defaultValue]),
|
||||
() => props.value,
|
||||
() => {
|
||||
mergedValue.value = props.value !== undefined ? props.value : props.defaultValue;
|
||||
},
|
||||
|
@ -801,7 +801,7 @@ export default function generateSelector<
|
|||
// Close dropdown when disabled change
|
||||
|
||||
watch(
|
||||
computed(() => props.disabled),
|
||||
() => props.disabled,
|
||||
() => {
|
||||
if (innerOpen.value && !!props.disabled) {
|
||||
setInnerOpen(false);
|
||||
|
@ -1355,7 +1355,6 @@ export default function generateSelector<
|
|||
);
|
||||
},
|
||||
});
|
||||
Select.inheritAttrs = false;
|
||||
Select.props = initDefaultProps(BaseProps(), {});
|
||||
return Select;
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue