Skip to content

Commit

Permalink
[select] standardize shared popover props (#5347)
Browse files Browse the repository at this point in the history
  • Loading branch information
adidahiya authored Jun 3, 2022
1 parent 2f76b9f commit 8db76e5
Show file tree
Hide file tree
Showing 6 changed files with 63 additions and 42 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -117,7 +117,8 @@ export class MultiSelectExample extends React.PureComponent<IExampleProps, IMult
noResults={<MenuItem disabled={true} text="No results." />}
onItemSelect={this.handleFilmSelect}
onItemsPaste={this.handleFilmsPaste}
popoverProps={{ minimal: popoverMinimal, ref: this.popoverRef }}
popoverProps={{ minimal: popoverMinimal }}
popoverRef={this.popoverRef}
tagRenderer={this.renderTag}
tagInputProps={{
onRemove: this.handleTagRemove,
Expand Down
1 change: 1 addition & 0 deletions packages/select/src/common/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -22,3 +22,4 @@ export * from "./itemRenderer";
export * from "./listItemsProps";
export * from "./listItemsUtils";
export * from "./predicate";
export type { SelectPopoverProps } from "./selectPopoverProps";
38 changes: 38 additions & 0 deletions packages/select/src/common/selectPopoverProps.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,38 @@
/*
* Copyright 2022 Palantir Technologies, Inc. All rights reserved.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/

import type { Popover2, Popover2Props } from "@blueprintjs/popover2";

/**
* Reusable collection of props for components in this package which render a `Popover2`
* and need to provide some degree of customization for that popover.
*/
export interface SelectPopoverProps {
/** Props to spread to `Popover2` content wrapper eleemnt. */
popoverContentProps?: React.HTMLAttributes<HTMLDivElement>;

/**
* Props to spread to `Popover2`.
* Note that `content` cannot be changed aside from utilizing `popoverContentProps`.
*/
popoverProps?: Partial<Omit<Popover2Props, "content">>;

/**
* Optional ref for the Popover2 component instance.
* This is sometimes useful to reposition the popover.
*/
popoverRef?: React.RefObject<Popover2<React.HTMLProps<HTMLDivElement>>>;
}
25 changes: 6 additions & 19 deletions packages/select/src/components/multi-select/multiSelect2.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -28,14 +28,14 @@ import {
TagInputAddMethod,
TagInputProps,
} from "@blueprintjs/core";
import { Popover2, Popover2Props } from "@blueprintjs/popover2";
import { Popover2 } from "@blueprintjs/popover2";

import { Classes, IListItemsProps } from "../../common";
import { Classes, IListItemsProps, SelectPopoverProps } from "../../common";
import { IQueryListRendererProps, QueryList } from "../query-list/queryList";

// N.B. selectedItems should really be a required prop, but is left optional for backwards compatibility

export interface MultiSelect2Props<T> extends IListItemsProps<T> {
export interface MultiSelect2Props<T> extends IListItemsProps<T>, SelectPopoverProps {
/**
* Whether the component should take up the full width of its container.
* This overrides `popoverProps.fill` and `tagInputProps.fill`.
Expand Down Expand Up @@ -73,20 +73,6 @@ export interface MultiSelect2Props<T> extends IListItemsProps<T> {
*/
placeholder?: string;

/** Props to spread to `Popover2` popover content. */
popoverContentProps?: React.HTMLAttributes<HTMLDivElement>;

/**
* Props to spread to `Popover2`.
*
* Note that `content` cannot be changed aside from utilizing `popoverContentProps`, but we do support
* attaching a ref to the Popover2 component instance (sometimes useful to reposition the popover after
* updating `selectedItems` in reaction to a change external to this component).
*/
popoverProps?: Partial<
Omit<Popover2Props, "content"> & { ref: React.RefObject<Popover2<React.HTMLProps<HTMLDivElement>>> }
>;

/** Controlled selected values. */
selectedItems?: T[];

Expand Down Expand Up @@ -163,6 +149,7 @@ export class MultiSelect2<T> extends AbstractPureComponent2<MultiSelect2Props<T>
tagInputProps = {},
popoverContentProps = {},
popoverProps = {},
popoverRef,
selectedItems = [],
placeholder,
} = this.props;
Expand Down Expand Up @@ -204,9 +191,9 @@ export class MultiSelect2<T> extends AbstractPureComponent2<MultiSelect2Props<T>
onOpened={this.handlePopoverOpened}
popoverClassName={classNames(Classes.MULTISELECT_POPOVER, popoverProps.popoverClassName)}
ref={
popoverProps.ref === undefined
popoverRef === undefined
? this.refHandlers.popover
: mergeRefs(this.refHandlers.popover, popoverProps.ref)
: mergeRefs(this.refHandlers.popover, popoverRef)
}
>
<div
Expand Down
20 changes: 8 additions & 12 deletions packages/select/src/components/select/select2.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -31,12 +31,12 @@ import {
refHandler,
setRef,
} from "@blueprintjs/core";
import { Popover2, Popover2Props } from "@blueprintjs/popover2";
import { Popover2 } from "@blueprintjs/popover2";

import { Classes, IListItemsProps } from "../../common";
import { Classes, IListItemsProps, SelectPopoverProps } from "../../common";
import { IQueryListRendererProps, QueryList } from "../query-list/queryList";

export interface Select2Props<T> extends IListItemsProps<T> {
export interface Select2Props<T> extends IListItemsProps<T>, SelectPopoverProps {
children?: React.ReactNode;

/**
Expand Down Expand Up @@ -70,12 +70,6 @@ export interface Select2Props<T> extends IListItemsProps<T> {
*/
inputProps?: InputGroupProps2;

/** Props to spread to `Popover2` popover content. */
popoverContentProps?: React.HTMLAttributes<HTMLDivElement>;

/** Props to spread to `Popover2`. Note that `content` cannot be changed aside from utilizing `popoverContentProps`. */
popoverProps?: Partial<Omit<Popover2Props, "content">>;

/**
* Whether the active item should be reset to the first matching item _when
* the popover closes_. The query will also be reset to the empty string.
Expand Down Expand Up @@ -145,6 +139,7 @@ export class Select2<T> extends AbstractPureComponent2<Select2Props<T>, Select2S
inputProps = {},
popoverContentProps = {},
popoverProps = {},
popoverRef,
} = this.props;

if (fill) {
Expand Down Expand Up @@ -179,11 +174,12 @@ export class Select2<T> extends AbstractPureComponent2<Select2Props<T>, Select2S
{listProps.itemList}
</div>
}
onClosing={this.handlePopoverClosing}
onInteraction={this.handlePopoverInteraction}
popoverClassName={classNames(Classes.SELECT_POPOVER, popoverProps.popoverClassName)}
onOpening={this.handlePopoverOpening}
onOpened={this.handlePopoverOpened}
onClosing={this.handlePopoverClosing}
onOpening={this.handlePopoverOpening}
popoverClassName={classNames(Classes.SELECT_POPOVER, popoverProps.popoverClassName)}
ref={popoverRef}
>
<div
onKeyDown={this.state.isOpen ? handleKeyDown : this.handleTargetKeyDown}
Expand Down
18 changes: 8 additions & 10 deletions packages/select/src/components/suggest/suggest2.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -30,12 +30,12 @@ import {
refHandler,
setRef,
} from "@blueprintjs/core";
import { Popover2, Popover2Props } from "@blueprintjs/popover2";
import { Popover2 } from "@blueprintjs/popover2";

import { Classes, IListItemsProps } from "../../common";
import { Classes, IListItemsProps, SelectPopoverProps } from "../../common";
import { IQueryListRendererProps, QueryList } from "../query-list/queryList";

export interface Suggest2Props<T> extends IListItemsProps<T> {
export interface Suggest2Props<T> extends IListItemsProps<T>, SelectPopoverProps {
/**
* Whether the popover should close after selecting an item.
*
Expand Down Expand Up @@ -86,9 +86,6 @@ export interface Suggest2Props<T> extends IListItemsProps<T> {
*/
openOnKeyDown?: boolean;

/** Props to spread to `Popover2`. Note that `content` cannot be changed. */
popoverProps?: Partial<Omit<Popover2Props, "content">>;

/**
* Whether the active item should be reset to the first matching item _when
* the popover closes_. The query will also be reset to the empty string.
Expand Down Expand Up @@ -172,7 +169,7 @@ export class Suggest2<T> extends AbstractPureComponent2<Suggest2Props<T>, Sugges
}

private renderQueryList = (listProps: IQueryListRendererProps<T>) => {
const { fill, inputProps = {}, popoverProps = {} } = this.props;
const { fill, inputProps = {}, popoverContentProps = {}, popoverProps = {}, popoverRef } = this.props;
const { isOpen, selectedItem } = this.state;
const { handleKeyDown, handleKeyUp } = listProps;
const { autoComplete = "off", placeholder = "Search..." } = inputProps;
Expand Down Expand Up @@ -200,15 +197,16 @@ export class Suggest2<T> extends AbstractPureComponent2<Suggest2Props<T>, Sugges
{...popoverProps}
className={classNames(listProps.className, popoverProps.className)}
content={
<div onKeyDown={handleKeyDown} onKeyUp={handleKeyUp}>
<div {...popoverContentProps} onKeyDown={handleKeyDown} onKeyUp={handleKeyUp}>
{listProps.itemList}
</div>
}
interactionKind="click"
onInteraction={this.handlePopoverInteraction}
popoverClassName={classNames(Classes.SELECT_POPOVER, popoverProps.popoverClassName)}
onOpening={this.handlePopoverOpening}
onOpened={this.handlePopoverOpened}
onOpening={this.handlePopoverOpening}
popoverClassName={classNames(Classes.SELECT_POPOVER, popoverProps.popoverClassName)}
ref={popoverRef}
>
<InputGroup
autoComplete={autoComplete}
Expand Down

1 comment on commit 8db76e5

@blueprint-bot
Copy link

Choose a reason for hiding this comment

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

[select] standardize shared popover props (#5347)

Previews: documentation | landing | table | demo

Please sign in to comment.