Skip to content

Commit

Permalink
[core] feat(OverflowList): alwaysRenderOverflow prop (#4648)
Browse files Browse the repository at this point in the history
Co-authored-by: Rhys Brett-Bowen <[email protected]>
  • Loading branch information
adidahiya and Rhys Brett-Bowen authored Apr 19, 2021
1 parent 63d5de4 commit 4ff6cf1
Show file tree
Hide file tree
Showing 4 changed files with 41 additions and 5 deletions.
8 changes: 6 additions & 2 deletions packages/core/src/components/breadcrumbs/breadcrumbs.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -117,9 +117,13 @@ export class Breadcrumbs extends AbstractPureComponent2<BreadcrumbsProps> {
/* eslint-disable deprecation/deprecation */
return (
<li>
<Popover position={position} {...this.props.popoverProps}>
<Popover
position={position}
disabled={orderedItems.length === 0}
content={<Menu>{orderedItems.map(this.renderOverflowBreadcrumb)}</Menu>}
{...this.props.popoverProps}
>
<span className={Classes.BREADCRUMBS_COLLAPSED} />
<Menu>{orderedItems.map(this.renderOverflowBreadcrumb)}</Menu>
</Popover>
</li>
);
Expand Down
13 changes: 12 additions & 1 deletion packages/core/src/components/overflow-list/overflowList.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -36,6 +36,15 @@ export enum OverflowDirection {
export type OverflowListProps<T> = IOverflowListProps<T>;
/** @deprecated use OverflowListProps */
export interface IOverflowListProps<T> extends Props {
/**
* Whether to force the overflowRenderer to always be called, even if there are zero items
* overflowing. This may be useful, for example, if your overflow renderer contains a Popover
* which you do not want to close as the list is resized.
*
* @default false
*/
alwaysRenderOverflow?: boolean;

/**
* Which direction the items should collapse from: start or end of the
* children. This also determines whether `overflowRenderer` appears before
Expand Down Expand Up @@ -123,6 +132,7 @@ export class OverflowList<T> extends React.Component<OverflowListProps<T>, IOver
public static displayName = `${DISPLAYNAME_PREFIX}.OverflowList`;

public static defaultProps: Partial<OverflowListProps<any>> = {
alwaysRenderOverflow: false,
collapseFrom: Boundary.START,
minVisibleItems: 0,
};
Expand Down Expand Up @@ -166,6 +176,7 @@ export class OverflowList<T> extends React.Component<OverflowListProps<T>, IOver
prevProps.items !== this.props.items ||
prevProps.minVisibleItems !== this.props.minVisibleItems ||
prevProps.overflowRenderer !== this.props.overflowRenderer ||
prevProps.alwaysRenderOverflow !== this.props.alwaysRenderOverflow ||
prevProps.visibleItemRenderer !== this.props.visibleItemRenderer
) {
// reset visible state if the above props change.
Expand Down Expand Up @@ -215,7 +226,7 @@ export class OverflowList<T> extends React.Component<OverflowListProps<T>, IOver

private maybeRenderOverflow() {
const { overflow } = this.state;
if (overflow.length === 0) {
if (overflow.length === 0 && !this.props.alwaysRenderOverflow) {
return null;
}
return this.props.overflowRenderer(overflow);
Expand Down
4 changes: 4 additions & 0 deletions packages/core/test/overflow-list/overflowListTests.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -104,6 +104,10 @@ describe("<OverflowList>", function (this) {
overflowList().assertHasOverflow(true);
});

it("should render overflow if alwaysRenderOverflow props is true", () => {
overflowList(200, { alwaysRenderOverflow: true }).assertHasOverflow(true);
});

it("renders overflow items in the correct order (collapse from start)", () => {
overflowList(45, { collapseFrom: "start" }).assertOverflowItems(0, 1);
});
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -35,6 +35,7 @@ import { Example, handleStringChange, IExampleProps } from "@blueprintjs/docs-th
export interface IBreadcrumbsExampleState {
collapseFrom: Boundary;
renderCurrentAsInput: boolean;
alwaysRenderOverflow: boolean;
width: number;
}

Expand All @@ -51,9 +52,15 @@ const ITEMS: BreadcrumbProps[] = [
{ href: "#", icon: "folder-close", text: "Wednesday" },
{ icon: "document", text: "image.jpg", current: true },
];
// Show less items for always redner example so we can see when everything fits
const ITEMS_FOR_ALWAYS_RENDER: BreadcrumbProps[] = [
{ href: "#", icon: "folder-close", text: "Root" },
{ icon: "document", text: "image.jpg", current: true },
];

export class BreadcrumbsExample extends React.PureComponent<IExampleProps, IBreadcrumbsExampleState> {
public state: IBreadcrumbsExampleState = {
alwaysRenderOverflow: false,
collapseFrom: Boundary.START,
renderCurrentAsInput: false,
width: 50,
Expand All @@ -75,6 +82,12 @@ export class BreadcrumbsExample extends React.PureComponent<IExampleProps, IBrea
options={COLLAPSE_FROM_RADIOS}
selectedValue={this.state.collapseFrom.toString()}
/>
<Checkbox
name="alwaysRenderOverflow"
label="Always render overflow"
onChange={this.handleChangeAlwaysRenderOverflow}
checked={this.state.alwaysRenderOverflow}
/>
<Checkbox
name="renderCurrent"
label="Render current breadcrumb as input"
Expand All @@ -94,14 +107,15 @@ export class BreadcrumbsExample extends React.PureComponent<IExampleProps, IBrea
</>
);

const { collapseFrom, renderCurrentAsInput, width } = this.state;
const { collapseFrom, renderCurrentAsInput, width, alwaysRenderOverflow } = this.state;
return (
<Example options={options} {...this.props}>
<Card elevation={0} style={{ width: `${width}%` }}>
<Breadcrumbs
collapseFrom={collapseFrom}
items={ITEMS}
items={alwaysRenderOverflow ? ITEMS_FOR_ALWAYS_RENDER : ITEMS}
currentBreadcrumbRenderer={renderCurrentAsInput ? this.renderBreadcrumbInput : undefined}
overflowListProps={{ alwaysRenderOverflow }}
/>
</Card>
</Example>
Expand All @@ -117,6 +131,9 @@ export class BreadcrumbsExample extends React.PureComponent<IExampleProps, IBrea
private handleChangeRenderCurrentAsInput = () =>
this.setState({ renderCurrentAsInput: !this.state.renderCurrentAsInput });

private handleChangeAlwaysRenderOverflow = () =>
this.setState({ alwaysRenderOverflow: !this.state.alwaysRenderOverflow });

private renderBreadcrumbInput = ({ text }: BreadcrumbProps) => {
return <BreadcrumbInput defaultValue={typeof text === "string" ? text : undefined} />;
};
Expand Down

1 comment on commit 4ff6cf1

@blueprint-bot
Copy link

Choose a reason for hiding this comment

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

[core] feat(OverflowList): alwaysRenderOverflow prop (#4648)

Previews: documentation | landing | table

Please sign in to comment.