Skip to content

Commit

Permalink
fix: select keyboard position error
Browse files Browse the repository at this point in the history
  • Loading branch information
tangjinzhou committed Jun 22, 2021
1 parent 656d14f commit 604372f
Show file tree
Hide file tree
Showing 5 changed files with 40 additions and 17 deletions.
16 changes: 16 additions & 0 deletions components/_util/hooks/useMemo.ts
Original file line number Diff line number Diff line change
@@ -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;
}
30 changes: 19 additions & 11 deletions components/vc-select/OptionList.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -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;
Expand Down Expand Up @@ -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();

Expand All @@ -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;
}
Expand All @@ -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;
Expand All @@ -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);
},
Expand All @@ -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);
}
Expand All @@ -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;
Expand All @@ -188,6 +195,7 @@ const OptionList = defineComponent<OptionListProps, { state?: any }>({
) : null;
}
return {
memoFlattenOptions,
renderItem,
listRef,
state,
Expand Down Expand Up @@ -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 {
Expand Down Expand Up @@ -258,14 +266,14 @@ const OptionList = defineComponent<OptionListProps, { state?: any }>({
itemPrefixCls,
setActive,
onSelectValue,
memoFlattenOptions,
} = this as any;
const {
id,
childrenAsData,
values,
height,
itemHeight,
flattenOptions,
menuItemSelectedIcon,
notFoundContent,
virtual,
Expand All @@ -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"
Expand All @@ -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}
Expand Down
2 changes: 1 addition & 1 deletion components/vc-select/Selector/Input.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -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;
Expand Down
2 changes: 1 addition & 1 deletion components/vc-select/Selector/SingleSelector.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -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;
Expand Down
7 changes: 3 additions & 4 deletions components/vc-select/generate.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -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;
},
Expand Down Expand Up @@ -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);
Expand Down Expand Up @@ -1355,7 +1355,6 @@ export default function generateSelector<
);
},
});
Select.inheritAttrs = false;
Select.props = initDefaultProps(BaseProps(), {});
return Select;
}

0 comments on commit 604372f

Please sign in to comment.