Skip to content

Commit 1e95a21

Browse files
authored
feat: support option render (#470)
* feat: support option render * feat: test * feat: test * feat: add option * feat: 优化示例 * feat: 优化类型 * feat: review * feat: review * feat: 添加 level index * feat: 删除 level index * feat: disaled * feat: opeion
1 parent f31fa63 commit 1e95a21

File tree

6 files changed

+113
-1
lines changed

6 files changed

+113
-1
lines changed

docs/demo/option-render.md

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,8 @@
1+
---
2+
title: option-render
3+
nav:
4+
title: Demo
5+
path: /demo
6+
---
7+
8+
<code src="../../examples/option-render.tsx"></code>

examples/option-render.tsx

Lines changed: 74 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,74 @@
1+
import React from 'react';
2+
import '../assets/index.less';
3+
import Cascader from '../src';
4+
5+
const addressOptions = [
6+
{
7+
label: '福建',
8+
title: '福建-fj',
9+
value: 'fj',
10+
children: [
11+
{
12+
label: '福州',
13+
value: 'fuzhou',
14+
children: [
15+
{
16+
label: '马尾',
17+
value: 'mawei',
18+
},
19+
],
20+
},
21+
{
22+
label: '泉州',
23+
value: 'quanzhou',
24+
},
25+
],
26+
},
27+
{
28+
label: '浙江',
29+
value: 'zj',
30+
title: '浙江-zj',
31+
children: [
32+
{
33+
label: '杭州',
34+
value: 'hangzhou',
35+
children: [
36+
{
37+
label: '余杭',
38+
value: 'yuhang',
39+
},
40+
],
41+
},
42+
],
43+
},
44+
{
45+
label: '北京',
46+
value: 'bj',
47+
title: '北京-bj',
48+
children: [
49+
{
50+
label: '朝阳区',
51+
value: 'chaoyang',
52+
},
53+
{
54+
label: '海淀区',
55+
value: 'haidian',
56+
},
57+
],
58+
},
59+
];
60+
61+
const Demo = () => {
62+
return (
63+
<div>
64+
<Cascader
65+
options={addressOptions}
66+
optionRender={option => {
67+
return <label title={option.title}>{option.label}</label>;
68+
}}
69+
/>
70+
</div>
71+
);
72+
};
73+
74+
export default Demo;

src/Cascader.tsx

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -74,6 +74,7 @@ interface BaseCascaderProps<OptionType extends BaseOptionType = DefaultOptionTyp
7474
id?: string;
7575
prefixCls?: string;
7676
fieldNames?: FieldNames;
77+
optionRender?: (option: OptionType) => React.ReactNode;
7778
children?: React.ReactElement;
7879

7980
// Value
@@ -210,6 +211,7 @@ const Cascader = React.forwardRef<CascaderRef, InternalCascaderProps>((props, re
210211
children,
211212
dropdownMatchSelectWidth = false,
212213
showCheckedStrategy = SHOW_PARENT,
214+
optionRender,
213215
...restProps
214216
} = props;
215217

@@ -384,6 +386,7 @@ const Cascader = React.forwardRef<CascaderRef, InternalCascaderProps>((props, re
384386
expandIcon,
385387
loadingIcon,
386388
dropdownMenuColumnStyle,
389+
optionRender,
387390
}),
388391
[
389392
mergedOptions,
@@ -400,6 +403,7 @@ const Cascader = React.forwardRef<CascaderRef, InternalCascaderProps>((props, re
400403
expandIcon,
401404
loadingIcon,
402405
dropdownMenuColumnStyle,
406+
optionRender,
403407
],
404408
);
405409

src/OptionList/Column.tsx

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -51,6 +51,7 @@ export default function Column({
5151
expandIcon,
5252
loadingIcon,
5353
dropdownMenuColumnStyle,
54+
optionRender,
5455
} = React.useContext(CascaderContext);
5556

5657
const hoverOpen = expandTrigger === 'hover';
@@ -197,7 +198,9 @@ export default function Column({
197198
}}
198199
/>
199200
)}
200-
<div className={`${menuItemPrefixCls}-content`}>{label}</div>
201+
<div className={`${menuItemPrefixCls}-content`}>
202+
{optionRender ? optionRender(option) : label}
203+
</div>
201204
{!isLoading && expandIcon && !isMergedLeaf && (
202205
<div className={`${menuItemPrefixCls}-expand-icon`}>{expandIcon}</div>
203206
)}

src/context.ts

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -21,6 +21,7 @@ export interface CascaderContextProps {
2121
expandIcon?: React.ReactNode;
2222
loadingIcon?: React.ReactNode;
2323
dropdownMenuColumnStyle?: React.CSSProperties;
24+
optionRender?: CascaderProps['optionRender'];
2425
}
2526

2627
const CascaderContext = React.createContext<CascaderContextProps>(null);

tests/search.spec.tsx

Lines changed: 22 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -305,4 +305,26 @@ describe('Cascader.Search', () => {
305305
'bamboo / little',
306306
);
307307
});
308+
it('Should optionRender work', () => {
309+
const { container, rerender } = render(
310+
<Cascader
311+
open
312+
options={[{ label: 'bamboo', value: 'bamboo' }]}
313+
optionRender={option => `${option.label} - test`}
314+
/>,
315+
);
316+
expect(container.querySelector('.rc-cascader-menu-item-content').innerHTML).toEqual(
317+
'bamboo - test',
318+
);
319+
rerender(
320+
<Cascader
321+
open
322+
options={[{ label: 'bamboo', disabled: true, value: 'bamboo' }]}
323+
optionRender={option => JSON.stringify(option)}
324+
/>,
325+
);
326+
expect(container.querySelector('.rc-cascader-menu-item-content').innerHTML).toEqual(
327+
'{"label":"bamboo","disabled":true,"value":"bamboo"}',
328+
);
329+
});
308330
});

0 commit comments

Comments
 (0)