diff --git a/CHANGELOG.md b/CHANGELOG.md index f21962dc428..7a63d27adbe 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,6 +1,10 @@ ## [`master`](https://github.com/elastic/eui/tree/master) -No public interface changes since `30.1.1`. +- Added `labelWidth` and `descriptionDisplay` props to `EuiSuggestItem` ([#4180](https://github.com/elastic/eui/pull/4180)) + +**Bug fixes** + +- Fixed issue with `labelDisplay` not being passed to `EuiSuggestItem` ([#4180](https://github.com/elastic/eui/pull/4180)) ## [`30.1.1`](https://github.com/elastic/eui/tree/v30.1.1) diff --git a/src-docs/src/views/suggest/suggest_example.js b/src-docs/src/views/suggest/suggest_example.js index 25ed77def89..55f1d3d3ef5 100644 --- a/src-docs/src/views/suggest/suggest_example.js +++ b/src-docs/src/views/suggest/suggest_example.js @@ -35,6 +35,18 @@ const suggestItemSnippet = [ label={sampleItem.label} description={sampleItem.description} labelDisplay="expand" +/>`, + ``, + ``, ]; @@ -106,7 +118,11 @@ export const SuggestExample = { EuiSuggestItem is a list item component to display suggestions when typing queries in EuiSuggest. Use{' '} labelDisplay to set whether the{' '} - label has a fixed width or not. + label has a fixed width or not. By default, fixed + labels will have a width of 50%, you can adjust this by setting{' '} + labelWidth. Use{' '} + descriptionDisplay to set whether the{' '} + description truncates or wraps.

), diff --git a/src-docs/src/views/suggest/suggest_item.js b/src-docs/src/views/suggest/suggest_item.js index 981fc66c0f5..fd624a84324 100644 --- a/src-docs/src/views/suggest/suggest_item.js +++ b/src-docs/src/views/suggest/suggest_item.js @@ -4,6 +4,9 @@ import { EuiSuggestItem, EuiSpacer } from '../../../../src/components'; const shortDescription = 'This is the description'; +const longDescription = + 'This is a long description. Fusce euismod dui eu metus sagittis molestie.'; + const sampleItems = [ { type: { iconType: 'kqlField', color: 'tint5' }, @@ -35,13 +38,34 @@ const sampleItems = [ }, ]; +const sampleItems2 = [ + { + type: { iconType: 'kqlField', color: 'tint5' }, + label: 'Field sample with label at 30%', + labelWidth: 30, + description: shortDescription, + }, + { + type: { iconType: 'kqlField', color: 'tint5' }, + label: 'Field sample with label at 50%', + labelWidth: 50, + description: shortDescription, + }, + { + type: { iconType: 'kqlField', color: 'tint5' }, + label: 'Field sample with label at 80%', + labelWidth: 80, + description: shortDescription, + }, +]; + const typeObj = { iconType: 'kqlValue', color: 'tint0' }; const longLabel = - 'Lorem ipsum dolor sit amet, consectetur adipiscing elit. Nullam ut quam eget augue pulvinar.'; + 'Lorem ipsum dolor sit amet, consectetur adipiscing elit. Nullam ut quam.'; export default () => ( -
+
{sampleItems.map((item, index) => ( ( type={{ iconType: 'search', color: 'tint10' }} label="Items with no description will expand their label" /> + + {sampleItems2.map((item, index) => ( + + ))} + + +
); diff --git a/src/components/suggest/__snapshots__/suggest_item.test.tsx.snap b/src/components/suggest/__snapshots__/suggest_item.test.tsx.snap index 257e231306d..df2c7e9e403 100644 --- a/src/components/suggest/__snapshots__/suggest_item.test.tsx.snap +++ b/src/components/suggest/__snapshots__/suggest_item.test.tsx.snap @@ -14,17 +14,14 @@ exports[`EuiSuggestItem is rendered 1`] = ` /> Test label -
`; -exports[`props item with no description has expanded label is rendered 1`] = ` +exports[`props descriptionDisplay as wrap is rendered 1`] = `
@@ -36,13 +33,34 @@ exports[`props item with no description has expanded label is rendered 1`] = ` /> + This is the description + + This is the description +
+`; + +exports[`props item with no description has expanded label is rendered 1`] = ` +
+ + + + class="euiSuggestItem__label euiSuggestItem__labelDisplay--expand euiSuggestItem__label--width50" + > + Charles de Gaulle International Airport +
`; @@ -63,7 +81,31 @@ exports[`props labelDisplay as expand is rendered 1`] = ` This is the description + This is the description + + +`; + +exports[`props labelWidth is 30% is rendered 1`] = ` +
+ + + + + This is the description + + This is the description diff --git a/src/components/suggest/_suggest_item.scss b/src/components/suggest/_suggest_item.scss index 5d2dfdb8278..16769a6aa54 100644 --- a/src/components/suggest/_suggest_item.scss +++ b/src/components/suggest/_suggest_item.scss @@ -50,13 +50,22 @@ } .euiSuggestItem__label { - flex-basis: 50%; - min-width: 50%; + @include euiTextTruncate; font-family: $euiCodeFontFamily; overflow: hidden; text-overflow: ellipsis; padding: $euiSizeXS $euiSizeS; color: $euiTextColor; + display: block; + + // Sets labelWidth from 20% to 90% in increments of 10% + @for $i from 20 through 90 { + &.euiSuggestItem__label--width#{$i} { + flex-basis: $i * 1%; + min-width: $i * 1%; + $i: $i + 10; + } + } &.euiSuggestItem__labelDisplay--expand { flex-basis: auto; @@ -64,16 +73,22 @@ } } - .euiSuggestItem__description, - .euiSuggestItem__label { - @include euiTextTruncate; - display: block; - } - .euiSuggestItem__description { color: $euiColorDarkShade; flex-basis: auto; padding-top: $euiSizeXS * .5; + display: block; + + &.euiSuggestItem__description--wrap { + @include euiTextBreakWord; + white-space: normal; + line-height: $euiSizeM + 2px; + } + + &.euiSuggestItem__description--truncate { + @include euiTextTruncate; + line-height: $euiLineHeight; + } &:empty { flex-grow: 0; diff --git a/src/components/suggest/suggest.tsx b/src/components/suggest/suggest.tsx index 3d47b9c1a16..6a98a86cffc 100644 --- a/src/components/suggest/suggest.tsx +++ b/src/components/suggest/suggest.tsx @@ -54,15 +54,13 @@ export const EuiSuggest: FunctionComponent = ( onInputChange ? onInputChange(e.target) : null; }; - const suggestionList = suggestions.map((item: EuiSuggestItemProps, index) => ( - onItemClick(item) : undefined} - description={item.description} - /> - )); + const suggestionList = suggestions.map((item: EuiSuggestItemProps, index) => { + const props = { ...item }; + if (onItemClick) { + props.onClick = () => onItemClick(item); + } + return ; + }); const suggestInput = ( { }); }); + describe('descriptionDisplay as wrap', () => { + test('is rendered', () => { + const component = render( + + ); + expect(component).toMatchSnapshot(); + }); + }); + + describe('labelWidth is 30%', () => { + test('is rendered', () => { + const component = render( + + ); + expect(component).toMatchSnapshot(); + }); + }); + describe('item with no description has expanded label', () => { test('is rendered', () => { const component = render( - + ); expect(component).toMatchSnapshot(); }); diff --git a/src/components/suggest/suggest_item.tsx b/src/components/suggest/suggest_item.tsx index 36bffa87680..292b53595b2 100644 --- a/src/components/suggest/suggest_item.tsx +++ b/src/components/suggest/suggest_item.tsx @@ -52,6 +52,17 @@ interface EuiSuggestItemPropsBase { * Label display is 'fixed' by default. Label will increase its width beyond 50% if needed with 'expand'. */ labelDisplay?: keyof typeof labelDisplayToClassMap; + + /** + * Width of 'label' when 'labelDisplay' is set to 'fixed'. + * Accepts multiples of 10, from 20 to 90. Defaults to 50. + */ + labelWidth?: LabelWidthSize; + + /** + * Set the way in which 'description' is displayed, defaults to 'truncate'. + */ + descriptionDisplay?: keyof typeof descriptionDisplayToClassMap; } type PropsForDiv = Omit, 'onClick'>; @@ -81,6 +92,8 @@ interface ColorToClassMap { [key: string]: string; } +type LabelWidthSize = '20' | '30' | '40' | '50' | '60' | '70' | '80' | '90'; + const colorToClassNameMap: ColorToClassMap = { tint0: 'euiSuggestItem__type--tint0', tint1: 'euiSuggestItem__type--tint1', @@ -102,6 +115,11 @@ const labelDisplayToClassMap = { expand: 'euiSuggestItem__labelDisplay--expand', }; +const descriptionDisplayToClassMap = { + truncate: 'euiSuggestItem__description--truncate', + wrap: 'euiSuggestItem__description--wrap', +}; + export const DISPLAYS = keysOf(labelDisplayToClassMap); export const EuiSuggestItem: FunctionComponent = ({ @@ -109,7 +127,9 @@ export const EuiSuggestItem: FunctionComponent = ({ label, type, labelDisplay = 'fixed', + labelWidth = '50', description, + descriptionDisplay = 'truncate', onClick, ...rest }) => { @@ -123,14 +143,21 @@ export const EuiSuggestItem: FunctionComponent = ({ let colorClass = ''; - const labelDisplayClass = classNames( + const labelDisplayCalculated = !description ? 'expand' : labelDisplay; + + const labelClassNames = classNames( 'euiSuggestItem__label', - labelDisplayToClassMap[labelDisplay], + labelDisplayToClassMap[labelDisplayCalculated], { - 'euiSuggestItem__labelDisplay--expand': !description, + [`euiSuggestItem__label--width${labelWidth}`]: labelDisplay === 'fixed', } ); + const descriptionClassNames = classNames( + 'euiSuggestItem__description', + descriptionDisplayToClassMap[descriptionDisplay] + ); + if (type && type.color) { if (COLORS.indexOf(type.color as string) > -1) { colorClass = colorToClassNameMap[type.color]; @@ -142,8 +169,10 @@ export const EuiSuggestItem: FunctionComponent = ({ - {label} - {description} + {label} + {description && ( + {description} + )} );