Skip to content

Commit

Permalink
fix(ListPicker): 修改默认值的选择 (#2227)
Browse files Browse the repository at this point in the history
* fix(ListPicker): 修改默认值的选择

* fix(ListPicker): onMultipleChange 的调用方法

* fix(ListPicker): 删除无用的代码

---------

Co-authored-by: Zhang Rui <zhangrui@growingio.com>
  • Loading branch information
Quesle and Zhang Rui authored Mar 18, 2024
1 parent bce8789 commit 5854657
Show file tree
Hide file tree
Showing 4 changed files with 39 additions and 32 deletions.
5 changes: 4 additions & 1 deletion src/list-picker/interface.ts
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,10 @@ import { Placement, TriggerAction } from '../popover/interface';
import { ListProps } from '../list';

export interface ListPickerProps
extends Pick<ListProps, 'model' | 'empty' | 'needEmpty' | 'max' | 'valueSeparator' | 'onMultipleOverflow'> {
extends Pick<
ListProps,
'model' | 'empty' | 'needEmpty' | 'max' | 'valueSeparator' | 'onMultipleOverflow' | 'onMultipleChange'
> {
size?: 'small' | 'normal';
/**
* 触发方式
Expand Down
42 changes: 22 additions & 20 deletions src/list-picker/listPicker.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -16,8 +16,6 @@ import { callbackOnOverflow } from '../list/util';

const DEFAULT_DATA_TESTID = 'list-picker';



export const ListPicker: React.FC<ListPickerProps> = (props) => {
const localeTextObject: typeof defaultLocaleTextObject = useLocale('ListPicker') || defaultLocaleTextObject;
const {
Expand All @@ -32,6 +30,7 @@ export const ListPicker: React.FC<ListPickerProps> = (props) => {
onVisibleChange,
onChange,
onMultipleOverflow,
onMultipleChange,
customTrigger: propsRenderTrigger,
prefixCls = 'list-picker',
getContainer,
Expand Down Expand Up @@ -68,18 +67,18 @@ export const ListPicker: React.FC<ListPickerProps> = (props) => {
const [visible, setVisible] = useControlledState(controlledVisible, false);
const [value, setValue] = useState(defaultValue);
// use multiple and needConfirm, listPicker use prevValue instead of value
const [prevValue, setPrevValue] = useState(
model === 'multiple' && needConfirm ? defaultValue || [] : undefined
);
const { options, setOptions, getOptionByValue, getLabelByValue, getOptionTreeByValue, getOptionsByValue } = useCacheOptions();
const [prevValue, setPrevValue] = useState(model === 'multiple' && needConfirm ? defaultValue || [] : undefined);

const { options, setOptions, getOptionByValue, getLabelByValue, getOptionTreeByValue, getOptionsByValue } =
useCacheOptions();
const triggerRef = useRef<HTMLInputElement | undefined>(undefined);
// ========== control ==========
useEffect(() => {
setValue(controlledValue);
}, [controlledValue, setValue]);

// when controlledValue, use multiple and needConfirm
// update prevValue,
// when controlledValue, use multiple and needConfirm
// update prevValue,
// prevValue and value are in sync
useEffect(() => {
if (model === 'multiple' && needConfirm && Array.isArray(controlledValue) && !isEqual(controlledValue, prevValue)) {
Expand All @@ -91,19 +90,22 @@ export const ListPicker: React.FC<ListPickerProps> = (props) => {
// use confirm,when without onconfirm click, return prevValue
if (needConfirm && !visible && !isEqual(controlledValue, value)) {
setValue(prevValue);
if (model === 'multiple') {
onMultipleChange?.(prevValue as any[]);
}
}
// eslint-disable-next-line react-hooks/exhaustive-deps
}, [visible]);
}, [visible, needConfirm, controlledValue, value, model]);

// recent
const setRecentValue = (val?:string |string[])=>{
const setRecentValue = (val?: string | string[]) => {
const localKey = isNil(propsRecentId) ? ITEM_KEY : `${ITEM_KEY}_${propsRecentId}`;
const localStorageValue = localStorage?.getItem(localKey);
const recentKey: string[] = (JSON.parse(isNil(localStorageValue) ? '[]' : localStorageValue) || []).filter(
(v: string) => v !== val
);
localStorage?.setItem(localKey, JSON.stringify([val, ...recentKey].slice(0, 50)));
}
const localStorageValue = localStorage?.getItem(localKey);
const recentKey: string[] = (JSON.parse(isNil(localStorageValue) ? '[]' : localStorageValue) || []).filter(
(v: string) => v !== val
);
localStorage?.setItem(localKey, JSON.stringify([val, ...recentKey].slice(0, 50)));
};

// methods
const handVisibleChange = (vis: boolean) => {
Expand All @@ -113,7 +115,7 @@ export const ListPicker: React.FC<ListPickerProps> = (props) => {

const handleConfim = () => {
handVisibleChange(false);

// 非受控模式,将value更新至PrevValue
if (model === 'multiple' && needConfirm && typeof controlledValue === 'undefined') {
setPrevValue(value);
Expand All @@ -124,13 +126,13 @@ export const ListPicker: React.FC<ListPickerProps> = (props) => {
const handleChange = (val?: string | string[], opts?: OptionProps | OptionProps[]) => {
if (model !== 'multiple') {
setRecentValue(val);
if(typeof controlledValue === 'undefined'){
if (typeof controlledValue === 'undefined') {
setValue(val);
}
onChange?.(val, opts);
handVisibleChange(false);
} else {
callbackOnOverflow({ max, model, onMultipleOverflow, value: val });
callbackOnOverflow({ max, model, onMultipleOverflow, onMultipleChange, value: val });
setValue(val);
}
};
Expand Down Expand Up @@ -183,7 +185,7 @@ export const ListPicker: React.FC<ListPickerProps> = (props) => {
</Trigger>
);
};

// render
const renderOverlay = () => (
<div
Expand Down
4 changes: 4 additions & 0 deletions src/list/interface.ts
Original file line number Diff line number Diff line change
Expand Up @@ -74,6 +74,10 @@ export interface ListProps {
* 当多选达到 max 时,触发该方法 并 抛出内部的 value
*/
onMultipleOverflow?: (value?: Key[]) => void;
/**
* 当多选有值修改时,触发此功能
*/
onMultipleChange?: (value?: Key[]) => void;
/**
* 仅支持options 形式。自定义 item render 自定义render时会劫持onClick方法提供给List来使用
*/
Expand Down
20 changes: 9 additions & 11 deletions src/list/util.ts
Original file line number Diff line number Diff line change
Expand Up @@ -158,16 +158,14 @@ export const collectOptions = (childs?: React.ReactNode | OptionProps): OptionPr
/**
* 多选模式下,如果用户选择超出了定义的最大可选值,将会触发 onMultipleOverflow 回调函数
*/
export const callbackOnOverflow = (params: Pick<ListProps, 'model' | 'max' | 'value' | 'onMultipleOverflow'>): void => {
const { max, model, value, onMultipleOverflow } = params;
// prettier-ignore
if (
model === 'multiple' &&
Array.isArray(value) &&
max !== undefined &&
value.length >= max &&
onMultipleOverflow
) {
onMultipleOverflow(value);
export const callbackOnOverflow = (
params: Pick<ListProps, 'model' | 'max' | 'value' | 'onMultipleOverflow' | 'onMultipleChange'>
): void => {
const { max, model, value, onMultipleOverflow, onMultipleChange } = params;
if (model === 'multiple' && Array.isArray(value)) {
onMultipleChange?.(value);
if (Array.isArray(value) && max !== undefined && value.length >= max) {
onMultipleOverflow?.(value);
}
}
};

0 comments on commit 5854657

Please sign in to comment.