Skip to content

Commit ba2656c

Browse files
committed
feat: support INVALIDATE
1 parent 1137080 commit ba2656c

File tree

4 files changed

+105
-3
lines changed

4 files changed

+105
-3
lines changed

src/Item.tsx

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -16,11 +16,13 @@ export interface ItemProps<ItemType> extends React.HTMLAttributes<any> {
1616
display: boolean;
1717
order: number;
1818
component?: ComponentType;
19+
invalidate?: boolean;
1920
}
2021

2122
export default function Item<ItemType>(props: ItemProps<ItemType>) {
2223
const {
2324
prefixCls,
25+
invalidate,
2426
item,
2527
renderItem,
2628
responsive,
@@ -55,7 +57,7 @@ export default function Item<ItemType>(props: ItemProps<ItemType>) {
5557

5658
let itemNode = (
5759
<Component
58-
className={classNames(prefixCls, className)}
60+
className={classNames(!invalidate && prefixCls, className)}
5961
style={{
6062
opacity: mergedHidden ? 0 : 1,
6163
height: mergedHidden ? 0 : undefined,

src/Overflow.tsx

Lines changed: 13 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -13,6 +13,8 @@ export const OverflowContext = React.createContext<{
1313
registerSize: (key: React.Key, width: number | null) => void;
1414
display: boolean;
1515

16+
invalidate: boolean;
17+
1618
// Item Usage
1719
item?: any;
1820
itemKey?: React.Key;
@@ -22,6 +24,7 @@ export const OverflowContext = React.createContext<{
2224
}>(null);
2325

2426
const RESPONSIVE = 'responsive' as const;
27+
const INVALIDATE = 'invalidate' as const;
2528

2629
export type ComponentType =
2730
| React.ComponentType<any>
@@ -40,7 +43,7 @@ export interface OverflowProps<ItemType> extends React.HTMLAttributes<any> {
4043
renderItem?: (item: ItemType) => React.ReactNode;
4144
/** @private Do not use in your production. Render raw node that need wrap Item by developer self */
4245
renderRawItem?: (item: ItemType, index: number) => React.ReactElement;
43-
maxCount?: number | typeof RESPONSIVE;
46+
maxCount?: number | typeof RESPONSIVE | typeof INVALIDATE;
4447
renderRest?:
4548
| React.ReactNode
4649
| ((omittedItems: ItemType[]) => React.ReactNode);
@@ -104,6 +107,7 @@ function Overflow<ItemType = any>(
104107

105108
// ================================= Data =================================
106109
const isResponsive = data.length && maxCount === RESPONSIVE;
110+
const invalidate = maxCount === INVALIDATE;
107111

108112
/**
109113
* When is `responsive`, we will always render rest node to get the real width of it for calculation
@@ -258,6 +262,7 @@ function Overflow<ItemType = any>(
258262
prefixCls: itemPrefixCls,
259263
responsive: isResponsive,
260264
component: itemComponent,
265+
invalidate,
261266
};
262267

263268
// >>>>> Choice render fun by `renderRawItem`
@@ -336,7 +341,7 @@ function Overflow<ItemType = any>(
336341

337342
let overflowNode = (
338343
<Component
339-
className={classNames(prefixCls, className)}
344+
className={classNames(!invalidate && prefixCls, className)}
340345
style={style}
341346
ref={ref}
342347
{...restProps}
@@ -383,10 +388,16 @@ type ForwardOverflowType = <ItemType = any>(
383388

384389
type FilledOverflowType = ForwardOverflowType & {
385390
Item: typeof RawItem;
391+
RESPONSIVE: typeof RESPONSIVE;
392+
/** Will work as normal `component`. Skip patch props like `prefixCls`. */
393+
INVALIDATE: typeof INVALIDATE;
386394
};
387395

388396
ForwardOverflow.displayName = 'Overflow';
397+
389398
((ForwardOverflow as unknown) as FilledOverflowType).Item = RawItem;
399+
((ForwardOverflow as unknown) as FilledOverflowType).RESPONSIVE = RESPONSIVE;
400+
((ForwardOverflow as unknown) as FilledOverflowType).INVALIDATE = INVALIDATE;
390401

391402
// Convert to generic type
392403
export default (ForwardOverflow as unknown) as FilledOverflowType;
Lines changed: 39 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,39 @@
1+
// Jest Snapshot v1, https://goo.gl/fbAQLP
2+
3+
exports[`Overflow.Invalidate render item 1`] = `
4+
<ul
5+
class=""
6+
>
7+
<li
8+
class=""
9+
style="opacity: 1;"
10+
>
11+
Label 0
12+
</li>
13+
<li
14+
class=""
15+
style="opacity: 1;"
16+
>
17+
Label 1
18+
</li>
19+
</ul>
20+
`;
21+
22+
exports[`Overflow.Invalidate render raw 1`] = `
23+
<ul
24+
class=""
25+
>
26+
<li
27+
class=""
28+
style="opacity: 1;"
29+
>
30+
Label 0
31+
</li>
32+
<li
33+
class=""
34+
style="opacity: 1;"
35+
>
36+
Label 1
37+
</li>
38+
</ul>
39+
`;

tests/invalidate.spec.tsx

Lines changed: 50 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,50 @@
1+
import React from 'react';
2+
import Overflow from '../src';
3+
import { mount } from './wrapper';
4+
5+
interface ItemType {
6+
label: React.ReactNode;
7+
key: React.Key;
8+
}
9+
10+
describe('Overflow.Invalidate', () => {
11+
function getData(count: number) {
12+
return new Array(count).fill(undefined).map((_, index) => ({
13+
label: `Label ${index}`,
14+
key: `k-${index}`,
15+
}));
16+
}
17+
18+
it('render item', () => {
19+
const wrapper = mount(
20+
<Overflow<ItemType>
21+
data={getData(2)}
22+
renderItem={item => {
23+
return item.label;
24+
}}
25+
itemKey={item => `bamboo-${item.key}`}
26+
itemComponent="li"
27+
component="ul"
28+
maxCount={Overflow.INVALIDATE}
29+
/>,
30+
);
31+
32+
expect(wrapper.render()).toMatchSnapshot();
33+
});
34+
35+
it('render raw', () => {
36+
const wrapper = mount(
37+
<Overflow<ItemType>
38+
data={getData(2)}
39+
renderRawItem={item => {
40+
return <Overflow.Item component="li">{item.label}</Overflow.Item>;
41+
}}
42+
itemKey={item => `bamboo-${item.key}`}
43+
component="ul"
44+
maxCount={Overflow.INVALIDATE}
45+
/>,
46+
);
47+
48+
expect(wrapper.render()).toMatchSnapshot();
49+
});
50+
});

0 commit comments

Comments
 (0)