diff --git a/packages/docs-app/src/examples/select-examples/multiSelectExample.tsx b/packages/docs-app/src/examples/select-examples/multiSelectExample.tsx index ff5d0129c2..502f4ad7da 100644 --- a/packages/docs-app/src/examples/select-examples/multiSelectExample.tsx +++ b/packages/docs-app/src/examples/select-examples/multiSelectExample.tsx @@ -251,7 +251,9 @@ export class MultiSelectExample extends React.PureComponent ; + private renderCustomTarget = (selectedItems: readonly Film[]) => ( + + ); private renderTag = (film: Film) => film.title; @@ -287,7 +289,7 @@ export class MultiSelectExample extends React.PureComponent { let nextCreatedItems = createdItems.slice(); let nextFilms = films.slice(); @@ -336,7 +338,7 @@ export class MultiSelectExample extends React.PureComponent { + private handleFilmsPaste = (films: readonly Film[]) => { // On paste, don't bother with deselecting already selected values, just // add the new ones. this.selectFilms(films); diff --git a/packages/docs-app/src/examples/select-examples/selectExample.tsx b/packages/docs-app/src/examples/select-examples/selectExample.tsx index 18759c67f5..e9fab83d2d 100644 --- a/packages/docs-app/src/examples/select-examples/selectExample.tsx +++ b/packages/docs-app/src/examples/select-examples/selectExample.tsx @@ -169,7 +169,7 @@ export class SelectExample extends React.PureComponent { + private getGroupedItems = (filteredItems: readonly Film[]) => { return filteredItems.reduce>( (acc, item, index) => { const group = this.getGroup(item); @@ -193,7 +193,7 @@ export class SelectExample extends React.PureComponent { + private groupedItemListPredicate = (query: string, items: readonly Film[]) => { return items .filter((item, index) => filterFilm(query, item, index)) .sort((a, b) => this.getGroup(a).localeCompare(this.getGroup(b))); diff --git a/packages/docs-theme/src/components/navigator.tsx b/packages/docs-theme/src/components/navigator.tsx index c6e69faf93..0c7eabdc3d 100644 --- a/packages/docs-theme/src/components/navigator.tsx +++ b/packages/docs-theme/src/components/navigator.tsx @@ -84,7 +84,7 @@ export class Navigator extends React.PureComponent { } private filterMatches: ItemListPredicate = (query, items) => - filter(items, query, { + filter(items.slice(), query, { key: "route", maxInners: items.length / 5, maxResults: 10, diff --git a/packages/select/src/common/itemListRenderer.ts b/packages/select/src/common/itemListRenderer.ts index 180f762fad..89c75aa580 100644 --- a/packages/select/src/common/itemListRenderer.ts +++ b/packages/select/src/common/itemListRenderer.ts @@ -35,13 +35,13 @@ export interface ItemListRendererProps { * map each item in this array through `renderItem`, with support for * optional `noResults` and `initialContent` states. */ - filteredItems: T[]; + filteredItems: readonly T[]; /** * Array of all items in the list. * See `filteredItems` for a filtered array based on `query` and predicate props. */ - items: T[]; + items: readonly T[]; /** * The current query string. diff --git a/packages/select/src/common/listItemsProps.ts b/packages/select/src/common/listItemsProps.ts index 2beb4431b3..433bd5cd17 100644 --- a/packages/select/src/common/listItemsProps.ts +++ b/packages/select/src/common/listItemsProps.ts @@ -44,7 +44,7 @@ export interface ListItemsProps extends Props { activeItem?: T | CreateNewItem | null; /** Array of items in the list. */ - items: T[]; + items: readonly T[]; /** * Specifies how to test if two items are equal. By default, simple strict @@ -157,7 +157,7 @@ export interface ListItemsProps extends Props { /** * Callback invoked when multiple items are selected at once via pasting. */ - onItemsPaste?: (items: T[]) => void; + onItemsPaste?: (items: readonly T[]) => void; /** * Callback invoked when the query string changes. diff --git a/packages/select/src/common/predicate.ts b/packages/select/src/common/predicate.ts index 8011cbe033..af16229b71 100644 --- a/packages/select/src/common/predicate.ts +++ b/packages/select/src/common/predicate.ts @@ -18,7 +18,7 @@ * A custom predicate for returning an entirely new `items` array based on the provided query. * See usage sites in `ListItemsProps`. */ -export type ItemListPredicate = (query: string, items: T[]) => T[]; +export type ItemListPredicate = (query: string, items: readonly T[]) => readonly T[]; /** * A custom predicate for filtering items based on the provided query. diff --git a/packages/select/src/components/multi-select/multiSelect.tsx b/packages/select/src/components/multi-select/multiSelect.tsx index c1be8deeae..bd4e933ac1 100644 --- a/packages/select/src/components/multi-select/multiSelect.tsx +++ b/packages/select/src/components/multi-select/multiSelect.tsx @@ -44,7 +44,7 @@ export interface MultiSelectProps extends ListItemsProps, SelectPopoverPro * Element which triggers the multiselect popover. Providing this prop will replace the default TagInput * target thats rendered and move the search functionality to within the Popover. */ - customTarget?: (selectedItems: T[], isOpen: boolean) => React.ReactNode; + customTarget?: (selectedItems: readonly T[], isOpen: boolean) => React.ReactNode; /** * Whether the component is non-interactive. @@ -104,7 +104,7 @@ export interface MultiSelectProps extends ListItemsProps, SelectPopoverPro placeholder?: string; /** Controlled selected values. */ - selectedItems: T[]; + selectedItems: readonly T[]; /** * Props to pass to the [TagInput component](##core/components/tag-input). diff --git a/packages/select/src/components/query-list/queryList.tsx b/packages/select/src/components/query-list/queryList.tsx index e326843711..a6ff0bc87f 100644 --- a/packages/select/src/components/query-list/queryList.tsx +++ b/packages/select/src/components/query-list/queryList.tsx @@ -137,7 +137,7 @@ export interface QueryListState { createNewItem: T | T[] | undefined; /** The original `items` array filtered by `itemListPredicate` or `itemPredicate`. */ - filteredItems: T[]; + filteredItems: readonly T[]; /** The current query string. */ query: string; @@ -676,7 +676,7 @@ function isItemDisabled(item: T | null, index: number, itemDisabled?: ListIte * @param startIndex which index to begin moving from */ export function getFirstEnabledItem( - items: T[], + items: readonly T[], itemDisabled?: keyof T | ((item: T, index: number) => boolean), direction = 1, startIndex = items.length - 1, diff --git a/packages/select/test/queryListTests.tsx b/packages/select/test/queryListTests.tsx index 87dccf112d..4783606988 100644 --- a/packages/select/test/queryListTests.tsx +++ b/packages/select/test/queryListTests.tsx @@ -82,7 +82,9 @@ describe("", () => { }); it("itemListPredicate filters entire list by query", () => { - const predicate = sinon.spy((query: string, films: Film[]) => films.filter(f => f.year === +query)); + const predicate = sinon.spy((query: string, films: readonly Film[]) => + films.filter(f => f.year === +query), + ); shallow( {...testProps} itemListPredicate={predicate} query="1994" />); assert.equal(predicate.callCount, 1, "called once for entire list");