Skip to content
Merged
Show file tree
Hide file tree
Changes from 5 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
1 change: 1 addition & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
## [`master`](https://github.com/elastic/eui/tree/master)

- Added `prepend` and `append` ability to `EuiComboBox` ([#3003](https://github.com/elastic/eui/pull/3003))
Comment thread
ashikmeerankutty marked this conversation as resolved.
Outdated
- Added `EuiDataGrid`'s default sort order property ([#2987](https://github.com/elastic/eui/pull/2987))
- Fixed `EuiDataGrid`'s pagination visibility when changing rows per page ([#2978](https://github.com/elastic/eui/pull/2978))
- Added `highlightAll` prop to `EuiHighlight` to highlight all matches ([#2957](https://github.com/elastic/eui/pull/2957))
Expand Down
93 changes: 93 additions & 0 deletions src/components/combo_box/_combo_box.scss
Original file line number Diff line number Diff line change
Expand Up @@ -101,4 +101,97 @@
}
}
}

&.euiComboBox--group {
display: flex;
align-items: stretch;
padding: 1px;


> *,
.euiPopover__anchor,
.euiButtonEmpty,
.euiText,
.euiFormLabel,
.euiButtonIcon {
height: 100%;
}

.euiComboBox__prepend,
.euiComboBox__append {
@include euiTextTruncate;
flex-shrink: 0;
height: 100%;
border-radius: 0;
max-width: 50%;

// ICONS

&.euiIcon,
.euiIcon {
padding: 0 $euiSizeS;
width: $euiSizeXL;
border-radius: 0;
background-color: $euiFormInputGroupLabelBackground;
}

&.euiButtonIcon,
&.euiButtonEmpty,
.euiButtonIcon,
.euiButtonEmpty {
transform: none !important;

// Undo sizing from icons inside buttons
.euiIcon {
background: none !important;
padding: 0;
width: $euiSize;
}
}
}

.euiButtonIcon {
padding: 0 $euiSizeS;
width: $euiSizeXL;
border-radius: 0;
background-color: $euiFormInputGroupLabelBackground;

&:focus {
box-shadow: inset 0 0 0 2px $euiFocusRingColor;
}
}

.euiToolTipAnchor > .euiIcon {
height: 100%;
background-color: $euiFormInputGroupLabelBackground;
padding: 0 $euiSizeS;
width: $euiSizeXL;
border-radius: 0;
}

> .euiComboBox__prepend,
> .euiComboBox__append {
max-width: 50%; // Make sure max-width only applies to the outer most append/prepend element
}

// sass-lint:disable-block no-important
// This is the only way to target specific components to override styling

// TEXT

.euiFormLabel,
.euiText {
background-color: $euiFormInputGroupLabelBackground;
padding: $euiFormControlPadding;
line-height: $euiFontSize !important;
cursor: default !important; // pointer cursor on some form labels but not others is confusing
}

//
// BORDERS on buttons only

.euiButtonEmpty {
border-right: $euiFormInputGroupBorder;
}
}
}
59 changes: 58 additions & 1 deletion src/components/combo_box/combo_box.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,8 @@ import React, {
HTMLAttributes,
KeyboardEventHandler,
RefCallback,
ReactElement,
cloneElement,
} from 'react';
import classNames from 'classnames';

Expand Down Expand Up @@ -39,10 +41,12 @@ import {
EuiComboBoxOptionOption,
EuiComboBoxOptionsListPosition,
EuiComboBoxSingleSelectionShape,
EuiComboBoxAppendPrepend,
} from './types';
import { EuiFilterSelectItem } from '../filter_group';
import AutosizeInput from 'react-input-autosize';
import { CommonProps } from '../common';
import { EuiFormLabel } from '../form';

type DrillProps<T> = Pick<
EuiComboBoxOptionsListProps<T>,
Expand Down Expand Up @@ -73,6 +77,8 @@ interface _EuiComboBoxProps<T>
placeholder?: string;
rowHeight?: number;
singleSelection: boolean | EuiComboBoxSingleSelectionShape;
prepend?: EuiComboBoxAppendPrepend;
append?: EuiComboBoxAppendPrepend;
}

/**
Expand Down Expand Up @@ -121,6 +127,8 @@ export class EuiComboBox<T> extends Component<
options: [],
selectedOptions: [],
singleSelection: false,
prepend: null,
append: null,
};

state: EuiComboBoxState<T> = {
Expand Down Expand Up @@ -790,6 +798,8 @@ export class EuiComboBox<T> extends Component<
rowHeight,
selectedOptions,
singleSelection,
prepend,
append,
...rest
} = this.props;
const {
Expand All @@ -811,6 +821,7 @@ export class EuiComboBox<T> extends Component<
const classes = classNames('euiComboBox', className, {
'euiComboBox--compressed': compressed,
'euiComboBox--fullWidth': fullWidth,
'euiComboBox--group': prepend || append,
'euiComboBox-isDisabled': isDisabled,
'euiComboBox-isInvalid': markAsInvalid,
'euiComboBox-isOpen': isListOpen,
Expand Down Expand Up @@ -859,6 +870,9 @@ export class EuiComboBox<T> extends Component<
);
}

const prependNodes = this.renderSideNode('prepend', prepend, id);
const appendNodes = this.renderSideNode('append', append, id);

return (
/**
* Re: jsx-a11y/interactive-supports-focus
Expand All @@ -880,6 +894,7 @@ export class EuiComboBox<T> extends Component<
onKeyDown={this.onKeyDown}
ref={this.comboBoxRefCallback}
role="combobox">
{singleSelection && prependNodes}
<EuiComboBoxInput
autoSizeInputRef={this.autoSizeInputRefCallback}
compressed={compressed}
Expand Down Expand Up @@ -913,9 +928,51 @@ export class EuiComboBox<T> extends Component<
updatePosition={this.updatePosition}
value={value}
/>

{singleSelection && appendNodes}
{optionsList}
</div>
);
}
renderSideNode(
side: 'append' | 'prepend',
nodes?: EuiComboBoxAppendPrepend,
inputId?: string
) {
if (!nodes) {
return;
}

if (typeof nodes === 'string') {
return this.createFormLabel(side, nodes, inputId);
}

const appendNodes = React.Children.map(nodes, (item, index) =>
typeof item === 'string'
? this.createFormLabel(side, item, inputId)
: this.createSideNode(side, item, index)
);

return appendNodes;
}
createFormLabel(
side: 'append' | 'prepend',
string: string,
inputId?: string
) {
return (
<EuiFormLabel htmlFor={inputId} className={`euiComboBox__${side}`}>
{string}
</EuiFormLabel>
);
}
createSideNode(
side: 'append' | 'prepend',
node: ReactElement,
key: React.Key
) {
return cloneElement(node, {
className: classNames(`euiComboBox__${side}`, node.props.className),
key: key,
});
}
}
8 changes: 7 additions & 1 deletion src/components/combo_box/types.ts
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
import { ButtonHTMLAttributes } from 'react';
import { ButtonHTMLAttributes, ReactElement } from 'react';
import { CommonProps } from '../common';

// note similarity to `Option` in `components/selectable/types.tsx`
Expand All @@ -24,3 +24,9 @@ export type EuiComboBoxOptionsListPosition = 'top' | 'bottom';
export interface EuiComboBoxSingleSelectionShape {
asPlainText?: boolean;
}

type StringOrReactElement = string | ReactElement;

export type EuiComboBoxAppendPrepend =
| StringOrReactElement
| StringOrReactElement[];