Skip to content

Commit

Permalink
fix(list-picker): 优化list-picker、cascader性能 (#1579)
Browse files Browse the repository at this point in the history
  • Loading branch information
berber1016 committed Dec 2, 2021
1 parent 22992ba commit 3c893f8
Show file tree
Hide file tree
Showing 18 changed files with 302 additions and 249 deletions.
5 changes: 4 additions & 1 deletion src/cascader/Cascader.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -79,7 +79,10 @@ export const Cascader: React.FC<CascaderProps> = ({
if (typeof propsRenderTrigger === 'function') {
const node = propsRenderTrigger?.();
return React.cloneElement(node, {
onClick: triggerClick,
onClick: (e: MouseEvent) => {
node?.props?.onClick?.(e);
triggerClick();
},
});
}
return (
Expand Down
4 changes: 2 additions & 2 deletions src/cascader/demos/Cascader.stories.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -82,7 +82,7 @@ const demoTemplate: Story<CascaderProps> = (props) => (
<Cascader
onChange={(val: any, opt: any) => console.log('val', val, opt)}
options={defaultOptions}
placeholder="请选择"
placeholder="haha"
size="normal"
{...props}
/>
Expand Down Expand Up @@ -159,6 +159,6 @@ export const Demo = demoTemplate.bind({
},
});
export const Default: Story<CascaderProps> = (args) => (
<Cascader {...args} options={defaultOptions} placeholder="请选择" size="normal" />
<Cascader {...args} value="apple.cut.bad" options={defaultOptions} placeholder="请选择" size="normal" />
);
Default.args = {};
30 changes: 23 additions & 7 deletions src/list-picker/Recent.tsx
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
import { slice } from 'lodash';
import React, { useContext } from 'react';
import React, { useContext, useEffect, useMemo, useState } from 'react';
import { List, OptionProps } from '../list';
import { ListContext } from '../list/context';

Expand All @@ -12,18 +12,34 @@ interface RecentProps {

const Recent: React.FC<RecentProps> & { isRecent: boolean } = (props) => {
const { max = 5, title = '最近使用' } = props;
const [mayBeArray, setMayBearray] = useState<Map<string, OptionProps> | undefined>(new Map());
const context = useContext(ListContext);
const { options } = context;
const localStorageValue = window?.localStorage?.getItem(ITEM_KEY) || '[]';
const matchValue = JSON.parse(localStorageValue); // localStorage.getItem('__GIO_SELECTION_KEY')
const mayBeArray = Array.from((context?.options ?? new Map())?.values());
const options = slice(
mayBeArray?.filter((value?: OptionProps) => matchValue?.includes(value?.value)),
0,
max
useEffect(() => {
setTimeout(() => {
setMayBearray(options);
}, 0);
}, [options]);
const listOptions: OptionProps[] = useMemo(
() =>
slice(
matchValue?.reduce((prev: OptionProps[], curr: string) => {
if (mayBeArray?.has(curr)) {
return [...prev, mayBeArray?.get(curr)];
}
return [...prev];
}, []),
0,
max
),

[matchValue, max, mayBeArray]
);
const handleOnChange = (value?: string | string[], opts?: OptionProps | OptionProps[]) =>
context?.onChange?.(value, opts);
return <List title={title} id={ITEM_KEY} options={options} value="" onChange={handleOnChange} />;
return <List title={title} id={ITEM_KEY} options={listOptions} value="" onChange={handleOnChange} />;
};
Recent.isRecent = true;
export default Recent;
43 changes: 22 additions & 21 deletions src/list-picker/demos/List-picker.stories.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -237,27 +237,24 @@ const Template: Story<ListPickerProps> = () => {
<Tabs value={activeTab} defaultValue="tab1" onChange={(key: string) => setActiveTab(key)}>
<Tab label="tab1" value="tab1">
<List.Selection>
{(context) => {
const isEqualValue = context.value.length === 2;
return (
<>
<CheckboxItem
selected={isEqualValue}
onClick={() => {
if (isEqualValue) {
context.onChange([]);
} else {
context.onChange(Array.from(context.options.keys()));
}
}}
label="全部"
value="all"
/>
{(context) => (
<>
<CheckboxItem
selected={context?.value?.length === 2}
onClick={() => {
if (context?.value?.length === 2) {
context?.onChange([]);
} else {
context?.onChange(Array.from(context?.options.keys()));
}
}}
label="全部"
value="all"
/>

<List options={multipleOptions} id="id" title="有item" />
</>
);
}}
<List options={multipleOptions} id="id" title="有item" />
</>
)}
</List.Selection>
</Tab>
<Tab label="tab2" value="tab2">
Expand Down Expand Up @@ -366,7 +363,11 @@ const Template: Story<ListPickerProps> = () => {
<List.Selection options={largeOptions} />
</ListPicker>
</div>
<div className="demo-box" />
<div className="demo-box">
<ListPicker value="1.2" model="cascader">
<List options={[{ label: '1', value: '1', childrens: [{ label: '2', value: '2' }] }]} />
</ListPicker>
</div>
</div>
</div>
);
Expand Down
4 changes: 4 additions & 0 deletions src/list-picker/style/index.less
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@
@list-picker-prefix-cls: ~'@{component-prefix}-list-picker';
@selection-prefix-cls: ~'@{component-prefix}-list--selection';
@tab-panel-cls: ~'@{component-prefix}-tabs-tabpanel';
@cascader-prefix-cls: ~'@{component-prefix}-cascader';

@list-prefix-cls: ~'@{component-prefix}-list';
.@{list-picker-prefix-cls} {
Expand All @@ -29,6 +30,9 @@
padding: 0;
.scrollbar(@x: hidden, @y: initial);
}
& .@{cascader-prefix-cls}--list {
padding: 8px;
}
& .@{selection-prefix-cls} {
height: auto;
max-height: 360px;
Expand Down
10 changes: 8 additions & 2 deletions src/list/DragItem.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -57,12 +57,18 @@ const DragItem: React.FC<DragItemProps> = (props) => {
return (
<div
className={classNames(`${prefixCls}--item`, `${prefixCls}--item--drag`, {
[`${prefixCls}--item--drag--disabled`]: disabled,
[`${prefixCls}--item--disabled`]: disabled,
})}
ref={ref}
data-handler-id={handlerId}
>
<MoveOutlined className={`${prefixCls}--item--drag--icon`} color="#ADB2C2" size="14px" />
<MoveOutlined
className={classNames(`${prefixCls}--item--drag--icon`, {
[`${prefixCls}--item--drag--icon--disabled`]: disabled,
})}
color="#ADB2C2"
size="14px"
/>
<Item label={label} value={value} disabled={disabled} {...rest} />
</div>
);
Expand Down
34 changes: 12 additions & 22 deletions src/list/Item.tsx
Original file line number Diff line number Diff line change
@@ -1,31 +1,21 @@
import React from 'react';
import React, { useContext } from 'react';
import { ItemProps } from './interfance';
import BaseItem from './inner/baseItem';
import CheckboxItem from './inner/CheckboxItem';
import CalcaderItem from './inner/CascaderItem';
import WithRef from '../utils/withRef';
import { ListContext } from './context';

export const Item = WithRef<HTMLLIElement, ItemProps & { isMultiple?: boolean; isCascader?: boolean }>(
(props, ref?) => {
const { label, value, disabled, isMultiple = false, isCascader, selectValue, ...rest } = props;

if (isMultiple) {
return <CheckboxItem ref={ref} label={label} value={value} disabled={disabled} {...rest} />;
}
if (isCascader) {
return (
<CalcaderItem
ref={ref}
label={label as string}
value={value as string}
selectValue={selectValue as string}
disabled={disabled}
{...rest}
/>
);
}
return <BaseItem ref={ref} label={label} value={value} disabled={disabled} {...rest} />;
export const Item = WithRef<HTMLLIElement, ItemProps>((props, ref?) => {
const { label, value, disabled, ...rest } = props;
const { model } = useContext(ListContext);
if (model === 'multiple') {
return <CheckboxItem ref={ref} label={label} value={value} disabled={disabled} {...rest} />;
}
if (model === 'cascader') {
return <CalcaderItem ref={ref} label={label as string} value={value as string} disabled={disabled} {...rest} />;
}
);
return <BaseItem ref={ref} label={label} value={value} disabled={disabled} {...rest} />;
});

export default Item;

1 comment on commit 3c893f8

@vercel
Copy link

@vercel vercel bot commented on 3c893f8 Dec 2, 2021

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Please sign in to comment.