Skip to content
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

[QueryList] Initialize activeItem state correctly based on prop. #3290

Merged
merged 3 commits into from
Jan 18, 2019
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
9 changes: 8 additions & 1 deletion packages/select/src/components/query-list/queryList.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -109,7 +109,14 @@ export class QueryList<T> extends React.Component<IQueryListProps<T>, IQueryList
super(props, context);
const { query = "" } = this.props;
const filteredItems = getFilteredItems(query, this.props);
this.state = { activeItem: getFirstEnabledItem(filteredItems, this.props.itemDisabled), filteredItems, query };
this.state = {
activeItem:
this.props.activeItem !== undefined
? this.props.activeItem
: getFirstEnabledItem(filteredItems, this.props.itemDisabled),
filteredItems,
query,
};
}

public render() {
Expand Down
41 changes: 37 additions & 4 deletions packages/select/test/queryListTests.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,8 @@ import { IQueryListProps } from "@blueprintjs/select";
import { IFilm, renderFilm, TOP_100_FILMS } from "../../docs-app/src/examples/select-examples/films";
import { IQueryListRendererProps, IQueryListState, ItemListPredicate, ItemListRenderer, QueryList } from "../src/index";

type FilmQueryListWrapper = ReactWrapper<IQueryListProps<IFilm>, IQueryListState<IFilm>>;

describe("<QueryList>", () => {
const FilmQueryList = QueryList.ofType<IFilm>();
const testProps = {
Expand Down Expand Up @@ -99,7 +101,7 @@ describe("<QueryList>", () => {
items: [myItem],
query: "",
};
const filmQueryList: ReactWrapper<IQueryListProps<IFilm>> = mount(<FilmQueryList {...props} />);
const filmQueryList: FilmQueryListWrapper = mount(<FilmQueryList {...props} />);
filmQueryList.setProps(props);
assert.equal(testProps.onActiveItemChange.callCount, 0);
});
Expand All @@ -110,9 +112,7 @@ describe("<QueryList>", () => {
items: [TOP_100_FILMS[0]],
query: "abc",
};
const filmQueryList: ReactWrapper<IQueryListProps<IFilm>, IQueryListState<IFilm>> = mount(
<FilmQueryList {...props} />,
);
const filmQueryList: FilmQueryListWrapper = mount(<FilmQueryList {...props} />);
assert.deepEqual(filmQueryList.state().activeItem, TOP_100_FILMS[0]);
filmQueryList.setProps({
items: [TOP_100_FILMS[1]],
Expand All @@ -122,6 +122,39 @@ describe("<QueryList>", () => {
});
});

describe("activeItem state initialization", () => {
it("initializes to first filtered item when uncontrolled", () => {
const props: IQueryListProps<IFilm> = {
...testProps,
// Filter down to only item at index 11, so item at index 11 should be
// chosen as default activeItem
itemPredicate: (_query, item) => item === TOP_100_FILMS[11],
query: "123",
};
const filmQueryList: FilmQueryListWrapper = mount(<FilmQueryList {...props} />);
assert(filmQueryList.state().activeItem === TOP_100_FILMS[11]);
});

it("initializes to controlled activeItem prop (non-null)", () => {
const props: IQueryListProps<IFilm> = {
...testProps,
// List is not filtered, and item at index 11 is explicitly chosen as activeItem
activeItem: TOP_100_FILMS[11],
};
const filmQueryList: FilmQueryListWrapper = mount(<FilmQueryList {...props} />);
assert(filmQueryList.state().activeItem === TOP_100_FILMS[11]);
});

it("initializes to controlled activeItem prop (null)", () => {
const props: IQueryListProps<IFilm> = {
...testProps,
activeItem: null,
};
const filmQueryList: FilmQueryListWrapper = mount(<FilmQueryList {...props} />);
assert(filmQueryList.state().activeItem === null);
});
});

describe("scrolling", () => {
it("brings active item into view");
});
Expand Down