-
Notifications
You must be signed in to change notification settings - Fork 2.2k
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
[OverflowList] add onOverflow callback prop #2975
Changes from all commits
38fdb92
3702889
b4c3d4e
a335135
52a45f1
b243222
51f4d26
f6ee5cc
4b14ed4
5f0aa57
17e4af9
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -11,8 +11,16 @@ import { Boundary } from "../../common/boundary"; | |
import * as Classes from "../../common/classes"; | ||
import { OVERFLOW_LIST_OBSERVE_PARENTS_CHANGED } from "../../common/errors"; | ||
import { DISPLAYNAME_PREFIX, IProps } from "../../common/props"; | ||
import { safeInvoke } from "../../common/utils"; | ||
import { IResizeEntry, ResizeSensor } from "../resize-sensor/resizeSensor"; | ||
|
||
/** @internal - do not expose this type */ | ||
export enum OverflowDirection { | ||
NONE, | ||
GROW, | ||
SHRINK, | ||
} | ||
|
||
export interface IOverflowListProps<T> extends IProps { | ||
/** | ||
* Which direction the items should collapse from: start or end of the | ||
|
@@ -47,6 +55,13 @@ export interface IOverflowListProps<T> extends IProps { | |
*/ | ||
observeParents?: boolean; | ||
|
||
/** | ||
* Callback invoked when the overflowed items change. This is called once | ||
* after the DOM has settled, rather that on every intermediate change. It | ||
* is not invoked if resizing produces an unchanged overflow state. | ||
*/ | ||
onOverflow?: (overflowItems: T[]) => void; | ||
|
||
/** | ||
* Callback invoked to render the overflowed items. Unlike | ||
* `visibleItemRenderer`, this prop is invoked once with all items that do | ||
|
@@ -68,6 +83,13 @@ export interface IOverflowListProps<T> extends IProps { | |
} | ||
|
||
export interface IOverflowListState<T> { | ||
/** | ||
* Direction of current overflow operation. An overflow can take several frames to settle. | ||
* @internal don't expose the type | ||
*/ | ||
direction: OverflowDirection; | ||
/** Length of last overflow to dedupe `onOverflow` calls during smooth resizing. */ | ||
lastOverflowCount: number; | ||
overflow: T[]; | ||
visible: T[]; | ||
} | ||
|
@@ -85,6 +107,8 @@ export class OverflowList<T> extends React.PureComponent<IOverflowListProps<T>, | |
} | ||
|
||
public state: IOverflowListState<T> = { | ||
direction: OverflowDirection.NONE, | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. We initially call repartition in shrinking mode, so maybe this should be There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. i changed to |
||
lastOverflowCount: 0, | ||
overflow: [], | ||
visible: this.props.items, | ||
}; | ||
|
@@ -118,14 +142,25 @@ export class OverflowList<T> extends React.PureComponent<IOverflowListProps<T>, | |
) { | ||
// reset visible state if the above props change. | ||
this.setState({ | ||
direction: OverflowDirection.GROW, | ||
giladgray marked this conversation as resolved.
Show resolved
Hide resolved
|
||
lastOverflowCount: 0, | ||
overflow: [], | ||
visible: nextProps.items, | ||
}); | ||
} | ||
} | ||
|
||
public componentDidUpdate() { | ||
public componentDidUpdate(_prevProps: IOverflowListProps<T>, prevState: IOverflowListState<T>) { | ||
this.repartition(false); | ||
giladgray marked this conversation as resolved.
Show resolved
Hide resolved
|
||
const { direction, overflow, lastOverflowCount } = this.state; | ||
if ( | ||
// if a resize operation has just completed (transition to NONE) | ||
direction === OverflowDirection.NONE && | ||
direction !== prevState.direction && | ||
overflow.length !== lastOverflowCount | ||
) { | ||
safeInvoke(this.props.onOverflow, overflow); | ||
} | ||
} | ||
|
||
public render() { | ||
|
@@ -166,10 +201,14 @@ export class OverflowList<T> extends React.PureComponent<IOverflowListProps<T>, | |
return; | ||
} | ||
if (growing) { | ||
this.setState({ | ||
this.setState(state => ({ | ||
direction: OverflowDirection.GROW, | ||
// store last overflow if this is the beginning of a resize (for check in componentDidUpdate). | ||
lastOverflowCount: | ||
state.direction === OverflowDirection.NONE ? state.overflow.length : state.lastOverflowCount, | ||
overflow: [], | ||
visible: this.props.items, | ||
}); | ||
})); | ||
} else if (this.spacer.getBoundingClientRect().width < 0.9) { | ||
// spacer has flex-shrink and width 1px so if it's much smaller then we know to shrink | ||
this.setState(state => { | ||
|
@@ -184,10 +223,17 @@ export class OverflowList<T> extends React.PureComponent<IOverflowListProps<T>, | |
} | ||
const overflow = collapseFromStart ? [...state.overflow, next] : [next, ...state.overflow]; | ||
return { | ||
// set SHRINK mode unless a GROW is already in progress. | ||
giladgray marked this conversation as resolved.
Show resolved
Hide resolved
|
||
// GROW shows all items then shrinks until it settles, so we | ||
// preserve the fact that the original trigger was a GROW. | ||
direction: state.direction === OverflowDirection.NONE ? OverflowDirection.SHRINK : state.direction, | ||
overflow, | ||
visible, | ||
}; | ||
}); | ||
} else { | ||
// repartition complete! | ||
this.setState({ direction: OverflowDirection.NONE }); | ||
} | ||
} | ||
} |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
thoughts on doing this to reduce the exported surface area? it excludes it from the
.d.ts
files and required marking the state field similarly (line 84).There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
🆒