Skip to content

Commit

Permalink
matching_options code review fixes for EuiComboBoxOptionProps
Browse files Browse the repository at this point in the history
  • Loading branch information
Theo committed Apr 15, 2019
1 parent f781507 commit a596d18
Show file tree
Hide file tree
Showing 3 changed files with 90 additions and 77 deletions.
119 changes: 65 additions & 54 deletions src/components/combo_box/index.d.ts
Original file line number Diff line number Diff line change
Expand Up @@ -6,73 +6,84 @@ import {
EuiComboBoxOptionsListPosition,
EuiComboBoxOptionsListProps,
} from '@elastic/eui';
import { RefCallback } from '../common';
import { RefCallback, CommonProps } from '../common';

declare module '@elastic/eui' {
export type EuiComboBoxOptionProps = ButtonHTMLAttributes<HTMLButtonElement> & {
label: string,
isGroupLabelOption?: boolean,
}
export type EuiComboBoxOptionProps = CommonProps &
ButtonHTMLAttributes<HTMLButtonElement> & {
label: string;
isGroupLabelOption?: boolean;
options?: EuiComboBoxOptionProps[];
};

export type EuiComboBoxOptionsListPosition = 'top' | 'bottom'
export type EuiComboBoxOptionsListPosition = 'top' | 'bottom';

export interface EuiComboBoxOption {
option: EuiComboBoxOptionProps,
children?: ReactNode,
className?: string,
optionRef?: RefCallback<HTMLButtonElement>,
onClick: (option: EuiComboBoxOptionProps) => any,
onEnterKey: (option: EuiComboBoxOptionProps) => any,
disabled?: boolean,
option: EuiComboBoxOptionProps;
children?: ReactNode;
className?: string;
optionRef?: RefCallback<HTMLButtonElement>;
onClick: (option: EuiComboBoxOptionProps) => any;
onEnterKey: (option: EuiComboBoxOptionProps) => any;
disabled?: boolean;
}

export interface EuiComboBoxOptionsListProps {
options?: Array<EuiComboBoxOptionProps>,
isLoading?: boolean,
selectedOptions?: Array<any>,
onCreateOption?: any,
searchValue?: string,
matchingOptions?: Array<EuiComboBoxOptionProps>,
optionRef?: EuiComboBoxOption['optionRef'],
onOptionClick?: EuiComboBoxOption['onClick'],
onOptionEnterKey?: EuiComboBoxOption['onEnterKey'],
areAllOptionsSelected?: boolean,
getSelectedOptionForSearchValue?: (searchValue: string, selectedOptions: Array<any>) => EuiComboBoxOptionProps,
updatePosition: (parameter?: UIEvent | EuiPanelProps['panelRef']) => any,
position?: EuiComboBoxOptionsListPosition,
listRef: EuiPanelProps['panelRef'],
renderOption?: (option: EuiComboBoxOptionProps, searchValue: string, OPTION_CONTENT_CLASSNAME: string) => ReactNode,
width?: number,
scrollToIndex?: number,
onScroll?: ListProps['onScroll'],
rowHeight?: number,
fullWidth?: boolean,
options?: EuiComboBoxOptionProps[];
isLoading?: boolean;
selectedOptions?: any[];
onCreateOption?: any;
searchValue?: string;
matchingOptions?: EuiComboBoxOptionProps[];
optionRef?: EuiComboBoxOption['optionRef'];
onOptionClick?: EuiComboBoxOption['onClick'];
onOptionEnterKey?: EuiComboBoxOption['onEnterKey'];
areAllOptionsSelected?: boolean;
getSelectedOptionForSearchValue?: (
searchValue: string,
selectedOptions: any[]
) => EuiComboBoxOptionProps;
updatePosition: (parameter?: UIEvent | EuiPanelProps['panelRef']) => any;
position?: EuiComboBoxOptionsListPosition;
listRef: EuiPanelProps['panelRef'];
renderOption?: (
option: EuiComboBoxOptionProps,
searchValue: string,
OPTION_CONTENT_CLASSNAME: string
) => ReactNode;
width?: number;
scrollToIndex?: number;
onScroll?: ListProps['onScroll'];
rowHeight?: number;
fullWidth?: boolean;
}
export const EuiComboBoxOptionsList: FunctionComponent<EuiComboBoxOptionsListProps>;
export const EuiComboBoxOptionsList: FunctionComponent<
EuiComboBoxOptionsListProps
>;

export type EuiComboBoxSingleSelectionShape = { asPlainText?: boolean; };

export interface EuiComboBoxProps {
id?: string,
isDisabled?: boolean,
className?: string,
placeholder?: string,
isLoading?: boolean,
async?: boolean,
singleSelection?: EuiComboBoxSingleSelectionShape | boolean,
noSuggestions?: boolean,
options?: EuiComboBoxOptionsListProps['options'],
selectedOptions?: EuiComboBoxOptionsListProps['selectedOptions'],
onBlur?: FocusEventHandler<HTMLInputElement>,
onChange?: (options: Array<EuiComboBoxOptionProps>) => any,
onFocus?: FocusEventHandler<HTMLInputElement>,
onSearchChange?: (searchValue: string) => any,
onCreateOption?: EuiComboBoxOptionsListProps['onCreateOption'],
renderOption?: EuiComboBoxOptionsListProps['renderOption'],
isInvalid?: boolean,
rowHeight?: number,
isClearable?: boolean,
fullWidth?: boolean,
id?: string;
isDisabled?: boolean;
className?: string;
placeholder?: string;
isLoading?: boolean;
async?: boolean;
singleSelection?: EuiComboBoxSingleSelectionShape | boolean;
noSuggestions?: boolean;
options?: EuiComboBoxOptionsListProps['options'];
selectedOptions?: EuiComboBoxOptionsListProps['selectedOptions'];
onBlur?: FocusEventHandler<HTMLInputElement>;
onChange?: (options: Array<EuiComboBoxOptionProps>) => any;
onFocus?: FocusEventHandler<HTMLInputElement>;
onSearchChange?: (searchValue: string) => any;
onCreateOption?: EuiComboBoxOptionsListProps['onCreateOption'];
renderOption?: EuiComboBoxOptionsListProps['renderOption'];
isInvalid?: boolean;
rowHeight?: number;
isClearable?: boolean;
fullWidth?: boolean;
inputRef?: (element: HTMLInputElement) => void;
}
export const EuiComboBox: FunctionComponent<EuiComboBoxProps>;
Expand Down
14 changes: 7 additions & 7 deletions src/components/combo_box/matching_options.test.ts
Original file line number Diff line number Diff line change
@@ -1,11 +1,11 @@
import { EuiComboBoxOptionProps } from '@elastic/eui';
import {
EuiComboBoxOption,
flattenOptionGroups,
getSelectedOptionForSearchValue,
getMatchingOptions,
} from './matching_options';

const options: EuiComboBoxOption[] = [
const options: EuiComboBoxOptionProps[] = [
{
label: 'Titan',
'data-test-subj': 'titanOption',
Expand Down Expand Up @@ -51,7 +51,7 @@ describe('flattenOptionGroups', () => {
describe('getSelectedOptionForSearchValue', () => {
test('gets the first matching selected option for search value', () => {
// Assemble
const expected: EuiComboBoxOption = {
const expected: EuiComboBoxOptionProps = {
label: 'Saturn',
'data-test-subj': 'saturnOption',
};
Expand All @@ -71,7 +71,7 @@ describe('getSelectedOptionForSearchValue', () => {
});
test('gets the first matching selected option for search value', () => {
// Assemble
const expected: EuiComboBoxOption = {
const expected: EuiComboBoxOptionProps = {
label: 'Saturn',
'data-test-subj': 'saturnOption',
};
Expand All @@ -83,12 +83,12 @@ describe('getSelectedOptionForSearchValue', () => {
});

interface GetMatchingOptionsTestCase {
options: EuiComboBoxOption[];
selectedOptions: EuiComboBoxOption[];
options: EuiComboBoxOptionProps[];
selectedOptions: EuiComboBoxOptionProps[];
searchValue: string;
isPreFiltered: boolean;
showPrevSelected: boolean;
expected: EuiComboBoxOption[];
expected: EuiComboBoxOptionProps[];
}

const testCases: GetMatchingOptionsTestCase[] = [
Expand Down
34 changes: 18 additions & 16 deletions src/components/combo_box/matching_options.ts
Original file line number Diff line number Diff line change
@@ -1,11 +1,13 @@
export interface EuiComboBoxOption {
label: string;
[prop: string]: any;
}
import { EuiComboBoxOptionProps } from '@elastic/eui';

export const flattenOptionGroups = (optionsOrGroups: EuiComboBoxOption[]) => {
export const flattenOptionGroups = (
optionsOrGroups: EuiComboBoxOptionProps[]
) => {
return optionsOrGroups.reduce(
(options: EuiComboBoxOption[], optionOrGroup: EuiComboBoxOption) => {
(
options: EuiComboBoxOptionProps[],
optionOrGroup: EuiComboBoxOptionProps
) => {
if (optionOrGroup.options) {
options.push(...optionOrGroup.options);
} else {
Expand All @@ -19,18 +21,18 @@ export const flattenOptionGroups = (optionsOrGroups: EuiComboBoxOption[]) => {

export const getSelectedOptionForSearchValue = (
searchValue: string,
selectedOptions: EuiComboBoxOption[]
selectedOptions: EuiComboBoxOptionProps[]
) => {
const normalizedSearchValue = searchValue.toLowerCase();
return selectedOptions.find(
(option: any) => option.label.toLowerCase() === normalizedSearchValue
option => option.label.toLowerCase() === normalizedSearchValue
);
};

const collectMatchingOption = (
accumulator: EuiComboBoxOption[],
option: EuiComboBoxOption,
selectedOptions: EuiComboBoxOption[],
accumulator: EuiComboBoxOptionProps[],
option: EuiComboBoxOptionProps,
selectedOptions: EuiComboBoxOptionProps[],
normalizedSearchValue: string,
isPreFiltered: boolean,
showPrevSelected: boolean
Expand Down Expand Up @@ -62,19 +64,19 @@ const collectMatchingOption = (
};

export const getMatchingOptions = (
options: EuiComboBoxOption[],
selectedOptions: EuiComboBoxOption[],
options: EuiComboBoxOptionProps[],
selectedOptions: EuiComboBoxOptionProps[],
searchValue: string,
isPreFiltered: boolean,
showPrevSelected: boolean
) => {
const normalizedSearchValue = searchValue.trim().toLowerCase();
const matchingOptions: EuiComboBoxOption[] = [];
const matchingOptions: EuiComboBoxOptionProps[] = [];

options.forEach(option => {
if (option.options) {
const matchingOptionsForGroup: EuiComboBoxOption[] = [];
option.options.forEach((groupOption: EuiComboBoxOption) => {
const matchingOptionsForGroup: EuiComboBoxOptionProps[] = [];
option.options.forEach((groupOption: EuiComboBoxOptionProps) => {
collectMatchingOption(
matchingOptionsForGroup,
groupOption,
Expand Down

0 comments on commit a596d18

Please sign in to comment.