From d82c5f791be1226b939425899a553d21a2d8a68e Mon Sep 17 00:00:00 2001
From: cchaos
Date: Tue, 18 Feb 2020 18:07:36 -0500
Subject: [PATCH 1/7] [EuiSelectable] Better export and display of props
- Also added `id` to the `Option` type
- Setting `searchable` to required but adding a default of false
---
src-docs/src/views/selectable/props.tsx | 13 +++++
.../views/selectable/selectable_example.js | 48 ++++------------
src/components/selectable/index.ts | 12 +++-
src/components/selectable/selectable.tsx | 17 +++---
.../selectable/selectable_list/index.ts | 5 +-
.../selectable_list/selectable_list.tsx | 56 +++++++++----------
src/components/selectable/types.tsx | 1 +
7 files changed, 76 insertions(+), 76 deletions(-)
create mode 100644 src-docs/src/views/selectable/props.tsx
diff --git a/src-docs/src/views/selectable/props.tsx b/src-docs/src/views/selectable/props.tsx
new file mode 100644
index 00000000000..c65e09c79c1
--- /dev/null
+++ b/src-docs/src/views/selectable/props.tsx
@@ -0,0 +1,13 @@
+import React, { FunctionComponent } from 'react';
+import {
+ EuiSelectableOptionProp,
+ EuiSelectableOptionsListProps,
+} from '../../../../src/components/selectable';
+
+export const EuiSelectableOption: FunctionComponent<
+ EuiSelectableOptionProp
+> = () => ;
+
+export const EuiSelectableOptionsList: FunctionComponent<
+ EuiSelectableOptionsListProps
+> = () => ;
diff --git a/src-docs/src/views/selectable/selectable_example.js b/src-docs/src/views/selectable/selectable_example.js
index 8ea2c1f8ee6..9be861ccd7e 100644
--- a/src-docs/src/views/selectable/selectable_example.js
+++ b/src-docs/src/views/selectable/selectable_example.js
@@ -8,12 +8,13 @@ import { GuideSectionTypes } from '../../components';
import {
EuiCode,
EuiSelectable,
- EuiSelectableList,
EuiSelectableMessage,
EuiText,
EuiSpacer,
} from '../../../../src/components';
+import { EuiSelectableOption, EuiSelectableOptionsList } from './props';
+
import Selectable from './selectable';
const selectableSource = require('!!raw-loader!./selectable');
const selectableHtml = renderToHtml(Selectable);
@@ -83,46 +84,17 @@ export const SelectableExample = {
At its simplest, EuiSelectable requires an array of{' '}
options and an onChange{' '}
handler which passes back the altered{' '}
- selectedOptions array.
+ selectedOptions array. The{' '}
+ children is a function that return the{' '}
+ list and search nodes.
-
- The Option props
-
-
- -
- label: string required Must be
- unique across items if key is not passed
-
- -
- key?: string Must be unique across items
-
- -
- checked?: 'on' | 'off'{' '}
- Leave off to indicate not selected, 'on' to indicate
- inclusion and 'off' to indicate exclusion
-
- -
- disabled?: boolean
-
- -
- isGroupLabel?: boolean Set to true to indicate
- object is just a grouping label, not a selectable item
-
- -
- prepend?: React.ReactNode Node to add between
- the selection icon and the label
-
- -
- append?: React.ReactNode Node to add to the far
- right of the item
-
- -
- ref?: () => void
-
-
),
- props: { EuiSelectable, EuiSelectableList },
+ props: {
+ EuiSelectable,
+ EuiSelectableOption,
+ EuiSelectableOptionsList,
+ },
demo: ,
snippet: `;
+export type EuiSelectableOptionProp = Option;
+
export type EuiSelectableProps = Omit<
HTMLAttributes,
'children' | 'onChange'
@@ -67,9 +69,9 @@ export type EuiSelectableProps = Omit<
search: ReactElement | undefined
) => ReactNode;
/**
- * Array or Option objects, see docs for props
+ * Array of Option objects. See #EuiSelectableOption
*/
- options: Option[];
+ options: EuiSelectableOptionProp[];
/**
* Passes back the altered `options` array with selected options as
*/
@@ -82,7 +84,7 @@ export type EuiSelectableProps = Omit<
*/
singleSelection?: EuiSelectableSingleOptionProps;
/**
- * Allows marking options as checked = 'off' as well as 'on'
+ * Allows marking options as `checked='off'` as well as `'on'`
*/
allowExclusions?: boolean;
/**
@@ -96,12 +98,12 @@ export type EuiSelectableProps = Omit<
*/
height?: number | 'full';
/**
- * See `EuiSelectableList`
+ * See #EuiSelectableOptionsList
*/
listProps?: EuiSelectableOptionsListPropsWithDefaults;
/**
* Custom render function for each option.
- * Returns (option, searchValue)
+ * Returns `(option, searchValue)`
*/
renderOption?: (option: Option, searchValue: string) => {};
};
@@ -119,6 +121,7 @@ export class EuiSelectable extends Component<
static defaultProps = {
options: [],
singleSelection: false,
+ searchable: false,
};
private optionsListRef = createRef();
diff --git a/src/components/selectable/selectable_list/index.ts b/src/components/selectable/selectable_list/index.ts
index bc9f38b88b7..2259f87a3e7 100644
--- a/src/components/selectable/selectable_list/index.ts
+++ b/src/components/selectable/selectable_list/index.ts
@@ -1,2 +1,5 @@
-export { EuiSelectableList } from './selectable_list';
+export {
+ EuiSelectableList,
+ EuiSelectableOptionsListProps,
+} from './selectable_list';
export { EuiSelectableListItem } from './selectable_list_item';
diff --git a/src/components/selectable/selectable_list/selectable_list.tsx b/src/components/selectable/selectable_list/selectable_list.tsx
index 00a81431a82..e53e6fa45a4 100644
--- a/src/components/selectable/selectable_list/selectable_list.tsx
+++ b/src/components/selectable/selectable_list/selectable_list.tsx
@@ -5,40 +5,40 @@ import { CommonProps } from '../../common';
import { List, AutoSizer, ListProps } from 'react-virtualized';
import { htmlIdGenerator } from '../../../services';
import { EuiSelectableListItem } from './selectable_list_item';
-// @ts-ignore
import { EuiHighlight } from '../../highlight';
import { Option } from '../types';
export type EuiSelectableSingleOptionProps = 'always' | boolean;
// Consumer Configurable Props via `EuiSelectable.listProps`
-export type EuiSelectableOptionsListProps = HTMLAttributes &
- CommonProps & {
- /**
- * The index of the option to be highlighted as pseudo-focused;
- * Good for use when only one selection is allowed and needing to open
- * directly to that option
- */
- activeOptionIndex?: number;
- /**
- * The height of each option in pixels. Defaults to `32`
- */
- rowHeight: number;
- /**
- * Show the check/cross selection indicator icons
- */
- showIcons?: boolean;
- singleSelection?: EuiSelectableSingleOptionProps;
- /**
- * Any props to send specifically to the react-virtualized `List`
- */
- virtualizedProps?: ListProps;
- /**
- * Adds a border around the list to indicate the bounds;
- * Useful when the list scrolls, otherwise use your own container
- */
- bordered?: boolean;
- };
+export interface EuiSelectableOptionsListProps
+ extends CommonProps,
+ HTMLAttributes {
+ /**
+ * The index of the option to be highlighted as pseudo-focused;
+ * Good for use when only one selection is allowed and needing to open
+ * directly to that option
+ */
+ activeOptionIndex?: number;
+ /**
+ * The height of each option in pixels. Defaults to `32`
+ */
+ rowHeight: number;
+ /**
+ * Show the check/cross selection indicator icons
+ */
+ showIcons?: boolean;
+ singleSelection?: EuiSelectableSingleOptionProps;
+ /**
+ * Any props to send specifically to the react-virtualized `List`
+ */
+ virtualizedProps?: ListProps;
+ /**
+ * Adds a border around the list to indicate the bounds;
+ * Useful when the list scrolls, otherwise use your own container
+ */
+ bordered?: boolean;
+}
export type EuiSelectableListProps = EuiSelectableOptionsListProps & {
/**
diff --git a/src/components/selectable/types.tsx b/src/components/selectable/types.tsx
index c74da637b95..850b5fa51d9 100644
--- a/src/components/selectable/types.tsx
+++ b/src/components/selectable/types.tsx
@@ -12,6 +12,7 @@ export interface Option extends CommonProps {
* Must be unique across items
*/
key?: string;
+ id?: string;
/**
* Leave off to indicate not selected,
* 'on' to indicate inclusion and
From c854dfbfa9288d75ce09d32a53ceefb6a0743506 Mon Sep 17 00:00:00 2001
From: cchaos
Date: Tue, 18 Feb 2020 18:38:23 -0500
Subject: [PATCH 2/7] [EuiListGroup] Exporting props at top level
---
src/components/list_group/index.ts | 4 ++--
src/components/list_group/list_group.tsx | 4 ++--
2 files changed, 4 insertions(+), 4 deletions(-)
diff --git a/src/components/list_group/index.ts b/src/components/list_group/index.ts
index 69dca4816b4..a82a234ef34 100644
--- a/src/components/list_group/index.ts
+++ b/src/components/list_group/index.ts
@@ -1,2 +1,2 @@
-export { EuiListGroup } from './list_group';
-export { EuiListGroupItem } from './list_group_item';
+export { EuiListGroup, EuiListGroupProps } from './list_group';
+export { EuiListGroupItem, EuiListGroupItemProps } from './list_group_item';
diff --git a/src/components/list_group/list_group.tsx b/src/components/list_group/list_group.tsx
index 9f4e3c7de44..1d6354f8867 100644
--- a/src/components/list_group/list_group.tsx
+++ b/src/components/list_group/list_group.tsx
@@ -4,7 +4,7 @@ import classNames from 'classnames';
import { EuiListGroupItem, EuiListGroupItemProps } from './list_group_item';
import { CommonProps } from '../common';
-type EuiListGroupProps = CommonProps &
+export type EuiListGroupProps = CommonProps &
HTMLAttributes & {
/**
* Add a border to the list container
@@ -17,7 +17,7 @@ type EuiListGroupProps = CommonProps &
flush?: boolean;
/**
- * Items to display in this group
+ * Items to display in this group. See #EuiListGroupItem
*/
listItems?: EuiListGroupItemProps[];
From c7961b3ac1a42ef44722550e16cdc19f3c9b9dc3 Mon Sep 17 00:00:00 2001
From: cchaos
Date: Tue, 18 Feb 2020 18:48:22 -0500
Subject: [PATCH 3/7] Reverting to `type` instead of `interface`
---
.../selectable_list/selectable_list.tsx | 55 +++++++++----------
1 file changed, 27 insertions(+), 28 deletions(-)
diff --git a/src/components/selectable/selectable_list/selectable_list.tsx b/src/components/selectable/selectable_list/selectable_list.tsx
index e53e6fa45a4..ce0d7b1be2c 100644
--- a/src/components/selectable/selectable_list/selectable_list.tsx
+++ b/src/components/selectable/selectable_list/selectable_list.tsx
@@ -11,34 +11,33 @@ import { Option } from '../types';
export type EuiSelectableSingleOptionProps = 'always' | boolean;
// Consumer Configurable Props via `EuiSelectable.listProps`
-export interface EuiSelectableOptionsListProps
- extends CommonProps,
- HTMLAttributes {
- /**
- * The index of the option to be highlighted as pseudo-focused;
- * Good for use when only one selection is allowed and needing to open
- * directly to that option
- */
- activeOptionIndex?: number;
- /**
- * The height of each option in pixels. Defaults to `32`
- */
- rowHeight: number;
- /**
- * Show the check/cross selection indicator icons
- */
- showIcons?: boolean;
- singleSelection?: EuiSelectableSingleOptionProps;
- /**
- * Any props to send specifically to the react-virtualized `List`
- */
- virtualizedProps?: ListProps;
- /**
- * Adds a border around the list to indicate the bounds;
- * Useful when the list scrolls, otherwise use your own container
- */
- bordered?: boolean;
-}
+export type EuiSelectableOptionsListProps = CommonProps &
+ HTMLAttributes & {
+ /**
+ * The index of the option to be highlighted as pseudo-focused;
+ * Good for use when only one selection is allowed and needing to open
+ * directly to that option
+ */
+ activeOptionIndex?: number;
+ /**
+ * The height of each option in pixels. Defaults to `32`
+ */
+ rowHeight: number;
+ /**
+ * Show the check/cross selection indicator icons
+ */
+ showIcons?: boolean;
+ singleSelection?: EuiSelectableSingleOptionProps;
+ /**
+ * Any props to send specifically to the react-virtualized `List`
+ */
+ virtualizedProps?: ListProps;
+ /**
+ * Adds a border around the list to indicate the bounds;
+ * Useful when the list scrolls, otherwise use your own container
+ */
+ bordered?: boolean;
+ };
export type EuiSelectableListProps = EuiSelectableOptionsListProps & {
/**
From 5abe13b3c7ce539f0b306b3fb09b482c0693af74 Mon Sep 17 00:00:00 2001
From: cchaos
Date: Tue, 18 Feb 2020 19:05:28 -0500
Subject: [PATCH 4/7] cl
---
CHANGELOG.md | 2 ++
src/components/accordion/accordion.tsx | 8 +++++---
2 files changed, 7 insertions(+), 3 deletions(-)
diff --git a/CHANGELOG.md b/CHANGELOG.md
index fd58c908825..32bf6317433 100644
--- a/CHANGELOG.md
+++ b/CHANGELOG.md
@@ -4,6 +4,8 @@
- Exported `EuiSelectOptionProps` type ([#2830](https://github.com/elastic/eui/pull/2830))
- Added `paperClip` glyph to `EuiIcon` ([#2845](https://github.com/elastic/eui/pull/2845))
- Added `banner` prop to `EuiFlyoutBody` and updated `euiOverflowShadow` mixin ([#2837](https://github.com/elastic/eui/pull/2837))
+- Exporting TS props from top level `EuiListGroupProps`, `EuiListGroupItemProps`, `EuiSelectableProps`, `EuiSelectableOptionProp`, `EuiSelectableOptionsListProps` ([#2869](https://github.com/elastic/eui/pull/2869))
+- Added `id` prop to `EuiSelectable[options]` option ([#2869](https://github.com/elastic/eui/pull/2869))
**Bug fixes**
diff --git a/src/components/accordion/accordion.tsx b/src/components/accordion/accordion.tsx
index 25745fdc4ea..6d6df43a694 100644
--- a/src/components/accordion/accordion.tsx
+++ b/src/components/accordion/accordion.tsx
@@ -10,7 +10,7 @@ import { getDurationAndPerformOnFrame } from '../../services';
const MUTATION_ATTRIBUTE_FILTER = ['style'];
const paddingSizeToClassNameMap = {
- none: null,
+ none: '',
xs: 'euiAccordion__padding--xs',
s: 'euiAccordion__padding--s',
m: 'euiAccordion__padding--m',
@@ -51,7 +51,7 @@ export type EuiAccordionProps = HTMLAttributes &
/**
* The padding around the exposed accordion content.
*/
- paddingSize: EuiAccordionSize;
+ paddingSize?: EuiAccordionSize;
};
export class EuiAccordion extends Component<
@@ -139,7 +139,9 @@ export class EuiAccordion extends Component<
className
);
- const paddingClass = classNames(paddingSizeToClassNameMap[paddingSize]);
+ const paddingClass = paddingSize
+ ? classNames(paddingSizeToClassNameMap[paddingSize])
+ : undefined;
const buttonClasses = classNames('euiAccordion__button', buttonClassName);
From c88e8f7bf3e66261e73d7ae3e91e308ff8414f17 Mon Sep 17 00:00:00 2001
From: cchaos
Date: Tue, 18 Feb 2020 19:05:52 -0500
Subject: [PATCH 5/7] cl
---
CHANGELOG.md | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/CHANGELOG.md b/CHANGELOG.md
index 32bf6317433..aebb4472823 100644
--- a/CHANGELOG.md
+++ b/CHANGELOG.md
@@ -4,7 +4,7 @@
- Exported `EuiSelectOptionProps` type ([#2830](https://github.com/elastic/eui/pull/2830))
- Added `paperClip` glyph to `EuiIcon` ([#2845](https://github.com/elastic/eui/pull/2845))
- Added `banner` prop to `EuiFlyoutBody` and updated `euiOverflowShadow` mixin ([#2837](https://github.com/elastic/eui/pull/2837))
-- Exporting TS props from top level `EuiListGroupProps`, `EuiListGroupItemProps`, `EuiSelectableProps`, `EuiSelectableOptionProp`, `EuiSelectableOptionsListProps` ([#2869](https://github.com/elastic/eui/pull/2869))
+- Exported TS props from top level `EuiListGroupProps`, `EuiListGroupItemProps`, `EuiSelectableProps`, `EuiSelectableOptionProp`, `EuiSelectableOptionsListProps` ([#2869](https://github.com/elastic/eui/pull/2869))
- Added `id` prop to `EuiSelectable[options]` option ([#2869](https://github.com/elastic/eui/pull/2869))
**Bug fixes**
From 16f29fc704d00529c2903de83cba98eeadcdca01 Mon Sep 17 00:00:00 2001
From: Chandler Prall
Date: Thu, 20 Feb 2020 13:40:17 -0700
Subject: [PATCH 6/7] Updated selectable's Option type to reflect div vs button
realities
---
.../selectable_list/selectable_list.tsx | 9 +++++---
src/components/selectable/types.tsx | 22 ++++++++++++++-----
2 files changed, 23 insertions(+), 8 deletions(-)
diff --git a/src/components/selectable/selectable_list/selectable_list.tsx b/src/components/selectable/selectable_list/selectable_list.tsx
index ce0d7b1be2c..808dc6a15e1 100644
--- a/src/components/selectable/selectable_list/selectable_list.tsx
+++ b/src/components/selectable/selectable_list/selectable_list.tsx
@@ -4,7 +4,10 @@ import { CommonProps } from '../../common';
// eslint-disable-next-line import/named
import { List, AutoSizer, ListProps } from 'react-virtualized';
import { htmlIdGenerator } from '../../../services';
-import { EuiSelectableListItem } from './selectable_list_item';
+import {
+ EuiSelectableListItem,
+ EuiSelectableListItemProps,
+} from './selectable_list_item';
import { EuiHighlight } from '../../highlight';
import { Option } from '../types';
@@ -172,7 +175,7 @@ export class EuiSelectableList extends Component {
className="euiSelectableList__groupLabel"
key={rowKey}
style={style}
- {...optionRest}>
+ {...optionRest as HTMLAttributes}>
{prepend}
{label}
{append}
@@ -193,7 +196,7 @@ export class EuiSelectableList extends Component {
disabled={disabled}
prepend={prepend}
append={append}
- {...optionRest}>
+ {...optionRest as EuiSelectableListItemProps}>
{renderOption ? (
renderOption(option, searchValue)
) : (
diff --git a/src/components/selectable/types.tsx b/src/components/selectable/types.tsx
index 850b5fa51d9..8e64e3a4c34 100644
--- a/src/components/selectable/types.tsx
+++ b/src/components/selectable/types.tsx
@@ -1,9 +1,9 @@
-import React from 'react';
-import { CommonProps } from '../common';
+import React, { ButtonHTMLAttributes, HTMLAttributes } from 'react';
+import { CommonProps, ExclusiveUnion } from '../common';
export type OptionCheckedType = 'on' | 'off' | undefined;
-export interface Option extends CommonProps {
+export interface BaseOption extends CommonProps {
/**
* Visible label of option. Must be unique across items if `key` is not supplied
*/
@@ -21,9 +21,9 @@ export interface Option extends CommonProps {
checked?: OptionCheckedType;
disabled?: boolean;
/**
- * Set to true to indicate object is just a grouping label, not a selectable item
+ * Optional boolean. Set to true to indicate object is just a grouping label, not a selectable item
*/
- isGroupLabel?: boolean;
+ isGroupLabel?: false;
/**
* Node to add between the selection icon and the label
*/
@@ -34,3 +34,15 @@ export interface Option extends CommonProps {
append?: React.ReactNode;
ref?: (optionIndex: number) => void;
}
+
+export interface GroupLabelOption
+ extends Omit,
+ HTMLAttributes {
+ isGroupLabel: true;
+}
+
+export interface SelectableOption
+ extends BaseOption,
+ ButtonHTMLAttributes {}
+
+export type Option = ExclusiveUnion;
From 5e1723b2106098466f32cff372fb35b4a9afeb48 Mon Sep 17 00:00:00 2001
From: cchaos
Date: Thu, 20 Feb 2020 16:39:12 -0500
Subject: [PATCH 7/7] Renaming mroe option ts types and updating some doc
example files
---
src-docs/src/views/selectable/data.ts | 5 +-
src-docs/src/views/selectable/props.tsx | 6 +-
src-docs/src/views/selectable/selectable.tsx | 41 +++-------
.../views/selectable/selectable_example.js | 4 +-
.../views/selectable/selectable_exclusion.tsx | 38 +++-------
.../views/selectable/selectable_messages.js | 63 ----------------
.../views/selectable/selectable_messages.tsx | 38 ++++++++++
.../views/selectable/selectable_search.tsx | 74 ++++++-------------
.../views/selectable/selectable_single.tsx | 51 +++++--------
src/components/selectable/index.ts | 7 +-
src/components/selectable/matching_options.ts | 16 ++--
src/components/selectable/selectable.test.tsx | 6 +-
src/components/selectable/selectable.tsx | 21 +++---
.../selectable_list/selectable_list.test.tsx | 6 +-
.../selectable_list/selectable_list.tsx | 21 +++---
.../selectable_list/selectable_list_item.tsx | 6 +-
.../selectable/selectable_option.tsx | 53 +++++++++++++
.../selectable_search/selectable_search.tsx | 11 ++-
src/components/selectable/types.tsx | 48 ------------
19 files changed, 213 insertions(+), 302 deletions(-)
delete mode 100644 src-docs/src/views/selectable/selectable_messages.js
create mode 100644 src-docs/src/views/selectable/selectable_messages.tsx
create mode 100644 src/components/selectable/selectable_option.tsx
delete mode 100644 src/components/selectable/types.tsx
diff --git a/src-docs/src/views/selectable/data.ts b/src-docs/src/views/selectable/data.ts
index b07a24156e0..85b0bda4ad9 100644
--- a/src-docs/src/views/selectable/data.ts
+++ b/src-docs/src/views/selectable/data.ts
@@ -1,4 +1,6 @@
-export const Options = [
+import { EuiSelectableOption } from '../../../../src/components/selectable/selectable_option';
+
+export const Options: EuiSelectableOption[] = [
{
label: 'Titan',
'data-test-subj': 'titanOption',
@@ -13,6 +15,7 @@ export const Options = [
},
{
label: 'Dione',
+ id: 'id_dione',
},
{
label: 'Iapetus',
diff --git a/src-docs/src/views/selectable/props.tsx b/src-docs/src/views/selectable/props.tsx
index c65e09c79c1..294a3cc1fe5 100644
--- a/src-docs/src/views/selectable/props.tsx
+++ b/src-docs/src/views/selectable/props.tsx
@@ -1,11 +1,11 @@
import React, { FunctionComponent } from 'react';
import {
- EuiSelectableOptionProp,
+ EuiSelectableOption,
EuiSelectableOptionsListProps,
} from '../../../../src/components/selectable';
-export const EuiSelectableOption: FunctionComponent<
- EuiSelectableOptionProp
+export const EuiSelectableOptionProps: FunctionComponent<
+ EuiSelectableOption
> = () => ;
export const EuiSelectableOptionsList: FunctionComponent<
diff --git a/src-docs/src/views/selectable/selectable.tsx b/src-docs/src/views/selectable/selectable.tsx
index 6171a206e71..29993c2bb17 100644
--- a/src-docs/src/views/selectable/selectable.tsx
+++ b/src-docs/src/views/selectable/selectable.tsx
@@ -1,34 +1,17 @@
-import React, { Component } from 'react';
+import React, { useState } from 'react';
import { EuiSelectable } from '../../../../src/components/selectable';
-import { Option } from '../../../../src/components/selectable/types';
import { Options } from './data';
-export default class extends Component<{}, { options: Option[] }> {
- constructor(props: any) {
- super(props);
+export default () => {
+ const [options, setOptions] = useState(Options);
- this.state = {
- options: Options as Option[],
- };
- }
-
- onChange = (options: Option[]) => {
- this.setState({
- options,
- });
- };
-
- render() {
- const { options } = this.state;
-
- return (
-
- {list => list}
-
- );
- }
-}
+ return (
+ setOptions(newOptions)}>
+ {list => list}
+
+ );
+};
diff --git a/src-docs/src/views/selectable/selectable_example.js b/src-docs/src/views/selectable/selectable_example.js
index 9be861ccd7e..8fded936382 100644
--- a/src-docs/src/views/selectable/selectable_example.js
+++ b/src-docs/src/views/selectable/selectable_example.js
@@ -13,7 +13,7 @@ import {
EuiSpacer,
} from '../../../../src/components';
-import { EuiSelectableOption, EuiSelectableOptionsList } from './props';
+import { EuiSelectableOptionProps, EuiSelectableOptionsList } from './props';
import Selectable from './selectable';
const selectableSource = require('!!raw-loader!./selectable');
@@ -92,7 +92,7 @@ export const SelectableExample = {
),
props: {
EuiSelectable,
- EuiSelectableOption,
+ EuiSelectableOptionProps,
EuiSelectableOptionsList,
},
demo: ,
diff --git a/src-docs/src/views/selectable/selectable_exclusion.tsx b/src-docs/src/views/selectable/selectable_exclusion.tsx
index 39d6f796740..1a4c87d27b1 100644
--- a/src-docs/src/views/selectable/selectable_exclusion.tsx
+++ b/src-docs/src/views/selectable/selectable_exclusion.tsx
@@ -1,31 +1,17 @@
-import React, { Component } from 'react';
+import React, { useState } from 'react';
import { EuiSelectable } from '../../../../src/components/selectable';
-import { Option } from '../../../../src/components/selectable/types';
import { Options } from './data';
-export default class extends Component<{}, { options: Option[] }> {
- constructor(props: any) {
- super(props);
+export default () => {
+ const [options, setOptions] = useState(Options);
- this.state = {
- options: Options as Option[],
- };
- }
-
- onChange = (options: Option[]) => {
- this.setState({
- options,
- });
- };
-
- render() {
- const { options } = this.state;
-
- return (
-
- {list => list}
-
- );
- }
-}
+ return (
+ setOptions(newOptions)}>
+ {list => list}
+
+ );
+};
diff --git a/src-docs/src/views/selectable/selectable_messages.js b/src-docs/src/views/selectable/selectable_messages.js
deleted file mode 100644
index cbf1de14f1b..00000000000
--- a/src-docs/src/views/selectable/selectable_messages.js
+++ /dev/null
@@ -1,63 +0,0 @@
-import React, { Component, Fragment } from 'react';
-
-import {
- EuiSelectable,
- EuiSwitch,
- EuiSelectableMessage,
- EuiSpacer,
-} from '../../../../src/components';
-
-export default class extends Component {
- constructor(props) {
- super(props);
-
- this.state = {
- useCustomMessage: false,
- isLoading: false,
- };
- }
-
- onSwitch = e => {
- this.setState({
- useCustomMessage: e.target.checked,
- });
- };
-
- onLoading = e => {
- this.setState({
- isLoading: e.target.checked,
- });
- };
-
- render() {
- const { useCustomMessage, isLoading } = this.state;
-
- const customMessage = (
- You have no spice
- );
-
- return (
-
-
-
-
-
-
- {list => (useCustomMessage && !isLoading ? customMessage : list)}
-
-
- );
- }
-}
diff --git a/src-docs/src/views/selectable/selectable_messages.tsx b/src-docs/src/views/selectable/selectable_messages.tsx
new file mode 100644
index 00000000000..95ec006c00a
--- /dev/null
+++ b/src-docs/src/views/selectable/selectable_messages.tsx
@@ -0,0 +1,38 @@
+import React, { useState, Fragment } from 'react';
+
+import {
+ EuiSelectable,
+ EuiSelectableMessage,
+} from '../../../../src/components/selectable';
+import { EuiSwitch } from '../../../../src/components/form/switch';
+import { EuiSpacer } from '../../../../src/components/spacer';
+
+export default () => {
+ const [useCustomMessage, setUseCustomMessage] = useState(false);
+ const [isLoading, setIsLoading] = useState(false);
+
+ const customMessage = (
+ You have no spice
+ );
+
+ return (
+
+ setUseCustomMessage(e.target.checked)}
+ checked={!isLoading && useCustomMessage}
+ disabled={isLoading}
+ />
+
+ setIsLoading(e.target.checked)}
+ checked={isLoading}
+ />
+
+
+ {list => (useCustomMessage && !isLoading ? customMessage : list)}
+
+
+ );
+};
diff --git a/src-docs/src/views/selectable/selectable_search.tsx b/src-docs/src/views/selectable/selectable_search.tsx
index e94c755e1c3..4566e56ab71 100644
--- a/src-docs/src/views/selectable/selectable_search.tsx
+++ b/src-docs/src/views/selectable/selectable_search.tsx
@@ -1,57 +1,27 @@
-import React, { Component, Fragment } from 'react';
-
-import { EuiButtonEmpty } from '../../../../src/components/button';
+import React, { useState, Fragment } from 'react';
import { EuiSelectable } from '../../../../src/components/selectable';
-import { Option } from '../../../../src/components/selectable/types';
import { Options } from './data';
-export default class extends Component<{}, { options: Option[] }> {
- constructor(props: any) {
- super(props);
-
- this.state = {
- options: Options as Option[],
- };
- }
-
- onChange = (options: Option[]) => {
- this.setState({
- options,
- });
- };
-
- render() {
- const { options } = this.state;
+export default () => {
+ const [options, setOptions] = useState(Options);
- return (
-
- {
- this.setState({
- options: Options.map(option => ({
- ...option,
- checked: undefined,
- })),
- });
- }}>
- Deselect all
-
-
- {(list, search) => (
-
- {search}
- {list}
-
- )}
-
-
- );
- }
-}
+ return (
+
+ setOptions(newOptions)}>
+ {(list, search) => (
+
+ {search}
+ {list}
+
+ )}
+
+
+ );
+};
diff --git a/src-docs/src/views/selectable/selectable_single.tsx b/src-docs/src/views/selectable/selectable_single.tsx
index bcb4a80a238..fb884cf08ee 100644
--- a/src-docs/src/views/selectable/selectable_single.tsx
+++ b/src-docs/src/views/selectable/selectable_single.tsx
@@ -1,38 +1,23 @@
-import React, { Component } from 'react';
+import React, { useState } from 'react';
import { EuiSelectable } from '../../../../src/components/selectable';
-import { Option } from '../../../../src/components/selectable/types';
import { Options } from './data';
-export default class extends Component<{}, { options: Option[] }> {
- constructor(props: any) {
- super(props);
+export default () => {
+ const [options, setOptions] = useState(
+ Options.map(option => {
+ const { checked, ...checklessOption } = option;
+ return { ...checklessOption };
+ })
+ );
- this.state = {
- options: Options.map(option => {
- const { checked, ...checklessOption } = option;
- return { ...checklessOption };
- }) as Option[],
- };
- }
-
- onChange = (options: Option[]) => {
- this.setState({
- options,
- });
- };
-
- render() {
- const { options } = this.state;
-
- return (
-
- {list => list}
-
- );
- }
-}
+ return (
+ setOptions(newOptions)}
+ singleSelection={true}
+ listProps={{ bordered: true }}>
+ {list => list}
+
+ );
+};
diff --git a/src/components/selectable/index.ts b/src/components/selectable/index.ts
index bb047845b88..b31a0b48a54 100644
--- a/src/components/selectable/index.ts
+++ b/src/components/selectable/index.ts
@@ -1,12 +1,9 @@
-export {
- EuiSelectable,
- EuiSelectableProps,
- EuiSelectableOptionProp,
-} from './selectable';
+export { EuiSelectable, EuiSelectableProps } from './selectable';
export {
EuiSelectableList,
EuiSelectableListItem,
EuiSelectableOptionsListProps,
} from './selectable_list';
export { EuiSelectableMessage } from './selectable_message';
+export { EuiSelectableOption } from './selectable_option';
export { EuiSelectableSearch } from './selectable_search';
diff --git a/src/components/selectable/matching_options.ts b/src/components/selectable/matching_options.ts
index b5fb9faca4e..502d1aa0ddc 100644
--- a/src/components/selectable/matching_options.ts
+++ b/src/components/selectable/matching_options.ts
@@ -1,8 +1,8 @@
-import { Option } from './types';
+import { EuiSelectableOption } from './selectable_option';
const getSelectedOptionForSearchValue = (
searchValue: string,
- selectedOptions: Option[]
+ selectedOptions: EuiSelectableOption[]
) => {
const normalizedSearchValue = searchValue.toLowerCase();
return selectedOptions.find(
@@ -11,11 +11,11 @@ const getSelectedOptionForSearchValue = (
};
const collectMatchingOption = (
- accumulator: Option[],
- option: Option,
+ accumulator: EuiSelectableOption[],
+ option: EuiSelectableOption,
normalizedSearchValue: string,
isPreFiltered?: boolean,
- selectedOptions?: Option[]
+ selectedOptions?: EuiSelectableOption[]
) => {
// Don't show options that have already been requested if
// the selectedOptions list exists
@@ -51,7 +51,7 @@ export const getMatchingOptions = (
/**
* All available options to match against
*/
- options: Option[],
+ options: EuiSelectableOption[],
/**
* String to match option.label against
*/
@@ -64,10 +64,10 @@ export const getMatchingOptions = (
* To exclude selected options from the search list,
* pass the array of selected options
*/
- selectedOptions?: Option[]
+ selectedOptions?: EuiSelectableOption[]
) => {
const normalizedSearchValue = searchValue.trim().toLowerCase();
- const matchingOptions: Option[] = [];
+ const matchingOptions: EuiSelectableOption[] = [];
options.forEach(option => {
collectMatchingOption(
diff --git a/src/components/selectable/selectable.test.tsx b/src/components/selectable/selectable.test.tsx
index 8fbe405bb33..0a886af1047 100644
--- a/src/components/selectable/selectable.test.tsx
+++ b/src/components/selectable/selectable.test.tsx
@@ -3,9 +3,9 @@ import { render } from 'enzyme';
import { requiredProps } from '../../test/required_props';
import { EuiSelectable } from './selectable';
-import { Option } from './types';
+import { EuiSelectableOption } from './selectable_option';
-const options: Option[] = [
+const options: EuiSelectableOption[] = [
{
label: 'Titan',
'data-test-subj': 'titanOption',
@@ -77,7 +77,7 @@ describe('EuiSelectable', () => {
const component = render(
{
+ renderOption={(option: EuiSelectableOption, searchValue?: string) => {
return (
{searchValue} => {option.label}
diff --git a/src/components/selectable/selectable.tsx b/src/components/selectable/selectable.tsx
index 76782b9852f..00073a95f6c 100644
--- a/src/components/selectable/selectable.tsx
+++ b/src/components/selectable/selectable.tsx
@@ -16,7 +16,7 @@ import { getMatchingOptions } from './matching_options';
import { comboBoxKeyCodes } from '../../services';
import { TAB } from '../../services/key_codes';
import { EuiI18n } from '../i18n';
-import { Option } from './types';
+import { EuiSelectableOption } from './selectable_option';
import {
EuiSelectableOptionsListProps,
EuiSelectableSingleOptionProps,
@@ -50,8 +50,6 @@ type EuiSelectableSearchableProps = ExclusiveUnion<
}
>;
-export type EuiSelectableOptionProp = Option;
-
export type EuiSelectableProps = Omit<
HTMLAttributes,
'children' | 'onChange'
@@ -69,13 +67,13 @@ export type EuiSelectableProps = Omit<
search: ReactElement | undefined
) => ReactNode;
/**
- * Array of Option objects. See #EuiSelectableOption
+ * Array of EuiSelectableOption objects. See #EuiSelectableOptionProps
*/
- options: EuiSelectableOptionProp[];
+ options: EuiSelectableOption[];
/**
* Passes back the altered `options` array with selected options as
*/
- onChange?: (options: Option[]) => void;
+ onChange?: (options: EuiSelectableOption[]) => void;
/**
* Sets the single selection policy of
* `false`: allows multiple selection
@@ -105,13 +103,13 @@ export type EuiSelectableProps = Omit<
* Custom render function for each option.
* Returns `(option, searchValue)`
*/
- renderOption?: (option: Option, searchValue: string) => {};
+ renderOption?: (option: EuiSelectableOption, searchValue: string) => {};
};
export interface EuiSelectableState {
activeOptionIndex?: number;
searchValue: string;
- visibleOptions: Option[];
+ visibleOptions: EuiSelectableOption[];
}
export class EuiSelectable extends Component<
@@ -264,7 +262,10 @@ export class EuiSelectable extends Component<
});
};
- onSearchChange = (visibleOptions: Option[], searchValue: string) => {
+ onSearchChange = (
+ visibleOptions: EuiSelectableOption[],
+ searchValue: string
+ ) => {
this.setState({
visibleOptions,
searchValue,
@@ -275,7 +276,7 @@ export class EuiSelectable extends Component<
this.clearActiveOption();
};
- onOptionClick = (options: Option[]) => {
+ onOptionClick = (options: EuiSelectableOption[]) => {
this.setState(state => ({
visibleOptions: getMatchingOptions(options, state.searchValue),
}));
diff --git a/src/components/selectable/selectable_list/selectable_list.test.tsx b/src/components/selectable/selectable_list/selectable_list.test.tsx
index 88a5cc23ab6..e3438063e7a 100644
--- a/src/components/selectable/selectable_list/selectable_list.test.tsx
+++ b/src/components/selectable/selectable_list/selectable_list.test.tsx
@@ -3,14 +3,14 @@ import { render } from 'enzyme';
import { requiredProps } from '../../../test/required_props';
import { EuiSelectableList } from './selectable_list';
-import { Option } from '../types';
+import { EuiSelectableOption } from '../selectable_option';
// Mock the htmlIdGenerator to generate predictable ids for snapshot tests
jest.mock('../../../services/accessibility/html_id_generator', () => ({
htmlIdGenerator: () => () => 'htmlId',
}));
-const options: Option[] = [
+const options: EuiSelectableOption[] = [
{
label: 'Titan',
'data-test-subj': 'titanOption',
@@ -87,7 +87,7 @@ describe('EuiSelectableListItem', () => {
const component = render(
{
+ renderOption={(option: EuiSelectableOption, searchValue?: string) => {
return (
{searchValue} => {option.label}
diff --git a/src/components/selectable/selectable_list/selectable_list.tsx b/src/components/selectable/selectable_list/selectable_list.tsx
index 808dc6a15e1..bb5440c295b 100644
--- a/src/components/selectable/selectable_list/selectable_list.tsx
+++ b/src/components/selectable/selectable_list/selectable_list.tsx
@@ -9,7 +9,7 @@ import {
EuiSelectableListItemProps,
} from './selectable_list_item';
import { EuiHighlight } from '../../highlight';
-import { Option } from '../types';
+import { EuiSelectableOption } from '../selectable_option';
export type EuiSelectableSingleOptionProps = 'always' | boolean;
@@ -46,11 +46,11 @@ export type EuiSelectableListProps = EuiSelectableOptionsListProps & {
/**
* All possible options
*/
- options: Option[];
+ options: EuiSelectableOption[];
/**
* Filtered options list (if applicable)
*/
- visibleOptions?: Option[];
+ visibleOptions?: EuiSelectableOption[];
/**
* Search value to highlight on the option render
*/
@@ -58,12 +58,15 @@ export type EuiSelectableListProps = EuiSelectableOptionsListProps & {
/**
* Returns the array of options with altered checked state
*/
- onOptionClick: (options: Option[]) => void;
+ onOptionClick: (options: EuiSelectableOption[]) => void;
/**
* Custom render for the label portion of the option;
* Takes (option, searchValue), returns ReactNode
*/
- renderOption?: (option: Option, searchValue: string) => ReactNode;
+ renderOption?: (
+ option: EuiSelectableOption,
+ searchValue: string
+ ) => ReactNode;
/**
* Sets the max height in pixels or pass `full` to allow
* the whole group to fill the height of its container and
@@ -212,7 +215,7 @@ export class EuiSelectableList extends Component {
);
}
- onAddOrRemoveOption = (option: Option) => {
+ onAddOrRemoveOption = (option: EuiSelectableOption) => {
if (option.disabled) {
return;
}
@@ -228,7 +231,7 @@ export class EuiSelectableList extends Component {
}
};
- private onAddOption = (addedOption: Option) => {
+ private onAddOption = (addedOption: EuiSelectableOption) => {
const { onOptionClick, options, singleSelection } = this.props;
const updatedOptions = options.map(option => {
@@ -249,7 +252,7 @@ export class EuiSelectableList extends Component {
onOptionClick(updatedOptions);
};
- private onRemoveOption = (removedOption: Option) => {
+ private onRemoveOption = (removedOption: EuiSelectableOption) => {
const { onOptionClick, singleSelection, options } = this.props;
const updatedOptions = options.map(option => {
@@ -265,7 +268,7 @@ export class EuiSelectableList extends Component {
onOptionClick(updatedOptions);
};
- private onExcludeOption = (excludedOption: Option) => {
+ private onExcludeOption = (excludedOption: EuiSelectableOption) => {
const { onOptionClick, options } = this.props;
excludedOption.checked = 'off';
diff --git a/src/components/selectable/selectable_list/selectable_list_item.tsx b/src/components/selectable/selectable_list/selectable_list_item.tsx
index c88be3fd61a..efb76779ef7 100644
--- a/src/components/selectable/selectable_list/selectable_list_item.tsx
+++ b/src/components/selectable/selectable_list/selectable_list_item.tsx
@@ -2,10 +2,10 @@ import React, { Component, ButtonHTMLAttributes } from 'react';
import classNames from 'classnames';
import { CommonProps } from '../../common';
import { EuiIcon, IconType, IconColor } from '../../icon';
-import { OptionCheckedType } from '../types';
+import { EuiSelectableOptionCheckedType } from '../selectable_option';
function resolveIconAndColor(
- checked: OptionCheckedType
+ checked: EuiSelectableOptionCheckedType
): { icon: IconType; color?: IconColor } {
if (!checked) {
return { icon: 'empty' };
@@ -23,7 +23,7 @@ export type EuiSelectableListItemProps = ButtonHTMLAttributes<
/**
* Applies an icon and visual styling to activated items
*/
- checked?: OptionCheckedType;
+ checked?: EuiSelectableOptionCheckedType;
/**
* Shows icons based on `checked` type
*/
diff --git a/src/components/selectable/selectable_option.tsx b/src/components/selectable/selectable_option.tsx
new file mode 100644
index 00000000000..e9d0ff3a7cd
--- /dev/null
+++ b/src/components/selectable/selectable_option.tsx
@@ -0,0 +1,53 @@
+import React, { ButtonHTMLAttributes, HTMLAttributes } from 'react';
+import { CommonProps, ExclusiveUnion } from '../common';
+
+export type EuiSelectableOptionCheckedType = 'on' | 'off' | undefined;
+
+export interface EuiSelectableOptionBase extends CommonProps {
+ /**
+ * Visible label of option.
+ * Must be unique across items if `key` is not supplied
+ */
+ label: string;
+ /**
+ * Must be unique across items.
+ * Will be used to match options instead of `label`
+ */
+ key?: string;
+ /**
+ * Leave `undefined` to indicate not selected,
+ * 'on' to indicate inclusion and
+ * 'off' to indicate exclusion
+ */
+ checked?: EuiSelectableOptionCheckedType;
+ disabled?: boolean;
+ /**
+ * Optional `boolean`.
+ * Set to `true` to indicate object is just a grouping label, not a selectable item
+ */
+ isGroupLabel?: false;
+ /**
+ * Node to add between the selection icon and the label
+ */
+ prepend?: React.ReactNode;
+ /**
+ * Node to add to the far right of the item
+ */
+ append?: React.ReactNode;
+ ref?: (optionIndex: number) => void;
+}
+
+export interface EuiSelectableGroupLabelOption
+ extends Omit,
+ HTMLAttributes {
+ isGroupLabel: true;
+}
+
+export interface EuiSelectableButtonOption
+ extends EuiSelectableOptionBase,
+ ButtonHTMLAttributes {}
+
+export type EuiSelectableOption = ExclusiveUnion<
+ EuiSelectableGroupLabelOption,
+ EuiSelectableButtonOption
+>;
diff --git a/src/components/selectable/selectable_search/selectable_search.tsx b/src/components/selectable/selectable_search/selectable_search.tsx
index d6eedc5ee99..3721e1bd570 100644
--- a/src/components/selectable/selectable_search/selectable_search.tsx
+++ b/src/components/selectable/selectable_search/selectable_search.tsx
@@ -3,7 +3,7 @@ import classNames from 'classnames';
import { CommonProps } from '../../common';
import { EuiFieldSearch, EuiFieldSearchProps } from '../../form/field_search';
import { getMatchingOptions } from '../matching_options';
-import { Option } from '../types';
+import { EuiSelectableOption } from '../selectable_option';
export type EuiSelectableSearchProps = Omit<
InputHTMLAttributes & EuiFieldSearchProps,
@@ -13,8 +13,11 @@ export type EuiSelectableSearchProps = Omit<
/**
* Passes back (matchingOptions, searchValue)
*/
- onChange?: (matchingOptions: Option[], searchValue: string) => void;
- options: Option[];
+ onChange?: (
+ matchingOptions: EuiSelectableOption[],
+ searchValue: string
+ ) => void;
+ options: EuiSelectableOption[];
defaultValue: string;
};
@@ -52,7 +55,7 @@ export class EuiSelectableSearch extends Component<
this.passUpMatches(matchingOptions, value);
};
- passUpMatches = (matches: Option[], searchValue: string) => {
+ passUpMatches = (matches: EuiSelectableOption[], searchValue: string) => {
if (this.props.onChange) {
this.props.onChange(matches, searchValue);
}
diff --git a/src/components/selectable/types.tsx b/src/components/selectable/types.tsx
deleted file mode 100644
index 8e64e3a4c34..00000000000
--- a/src/components/selectable/types.tsx
+++ /dev/null
@@ -1,48 +0,0 @@
-import React, { ButtonHTMLAttributes, HTMLAttributes } from 'react';
-import { CommonProps, ExclusiveUnion } from '../common';
-
-export type OptionCheckedType = 'on' | 'off' | undefined;
-
-export interface BaseOption extends CommonProps {
- /**
- * Visible label of option. Must be unique across items if `key` is not supplied
- */
- label: string;
- /**
- * Must be unique across items
- */
- key?: string;
- id?: string;
- /**
- * Leave off to indicate not selected,
- * 'on' to indicate inclusion and
- * 'off' to indicate exclusion
- */
- checked?: OptionCheckedType;
- disabled?: boolean;
- /**
- * Optional boolean. Set to true to indicate object is just a grouping label, not a selectable item
- */
- isGroupLabel?: false;
- /**
- * Node to add between the selection icon and the label
- */
- prepend?: React.ReactNode;
- /**
- * Node to add to the far right of the item
- */
- append?: React.ReactNode;
- ref?: (optionIndex: number) => void;
-}
-
-export interface GroupLabelOption
- extends Omit,
- HTMLAttributes {
- isGroupLabel: true;
-}
-
-export interface SelectableOption
- extends BaseOption,
- ButtonHTMLAttributes {}
-
-export type Option = ExclusiveUnion;