Skip to content
Draft
Show file tree
Hide file tree
Changes from all 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
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
2 changes: 2 additions & 0 deletions packages/eui/changelogs/upcoming/9532.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
- Updated `EuiSelectableListItem` to use the shared `EuiListItemLayout` component to align layout and styles between list components
- Updated `EuiSelectableTemplateSitewide` option text spacing from `4px` to `2px`
6 changes: 6 additions & 0 deletions packages/eui/changelogs/upcoming/9538.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
- Updated `EuiComboBox`'s listbox and list item styles by using `EuiListItemLayout`
- Updated the rendered output element of `EuiComboBoxOptionsList`'s list items from `button` to `li`
- Updated `EuiComboBox` to exclude disabled options from list navigation (aligning with native `<select>` behavior)
- Updated `EuiComboBoxOptionsList` to use `VariableSizeList` instead of `FixedSizeList` from `react-window`
- Added opt-in `onFocusBadge` prop on `EuiComboBox` and `EuiComboBoxOptionsList`. By default the "Enter" badge is not shown anymore.
- Updated `EuiComboBoxOptionsList`'s list item `id` to use a stable array index to ensure `aria-activedescendant` isn't stale.

Large diffs are not rendered by default.

10 changes: 5 additions & 5 deletions packages/eui/src/components/combo_box/combo_box.a11y.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -105,7 +105,7 @@ describe('EuiComboBox', () => {
it('has zero violations when the combobox is expanded', () => {
cy.realMount(<ComboBox rowHeight={rowHeight} />);
cy.get('input[data-test-subj="comboBoxSearchInput"]').realClick();
cy.get('button[data-test-subj="titanOption"]').should('exist');
cy.get('[data-test-subj="titanOption"]').should('exist');
cy.checkAxe();
});

Expand All @@ -115,7 +115,7 @@ describe('EuiComboBox', () => {
cy.get('input[data-test-subj="comboBoxSearchInput"]').should(
'have.focus'
);
cy.get('button[data-test-subj="titanOption"]').should('exist');
cy.get('[data-test-subj="titanOption"]').should('exist');
cy.repeatRealPress('ArrowDown');
cy.realPress('Enter');
cy.repeatRealPress('ArrowDown');
Expand Down Expand Up @@ -150,7 +150,7 @@ describe('EuiComboBox', () => {
cy.get('input[data-test-subj="comboBoxSearchInput"]').should(
'have.focus'
);
cy.get('button[data-test-subj="titanOption"]').should('exist');
cy.get('[data-test-subj="titanOption"]').should('exist');
cy.realPress('ArrowDown');
cy.realPress('ArrowDown');
cy.realPress('ArrowDown');
Expand All @@ -164,7 +164,7 @@ describe('EuiComboBox', () => {

cy.get('input[data-test-subj="comboBoxSearchInput"]')
.invoke('attr', 'aria-activedescendant')
.should('include', 'option-3');
.should('include', 'option-4');
});

it('sets the correct aria-activedescendant id with custom option ids', () => {
Expand Down Expand Up @@ -206,7 +206,7 @@ describe('EuiComboBox', () => {
cy.get('input[data-test-subj="comboBoxSearchInput"]').should(
'have.focus'
);
cy.get('button[data-test-subj="titanOption"]').should('exist');
cy.get('[data-test-subj="titanOption"]').should('exist');
cy.realPress('ArrowDown');
cy.realPress('ArrowDown');
cy.realPress('ArrowDown');
Expand Down
17 changes: 7 additions & 10 deletions packages/eui/src/components/combo_box/combo_box.spec.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -81,13 +81,10 @@ describe('EuiComboBox', () => {
]}
/>
);

cy.get(
'[data-test-subj=combobox] [data-test-subj=comboBoxSearchInput]'
).realClick();

cy.get('span').contains('Item 2').realClick();

cy.focused().should('have.attr', 'data-test-subj', 'comboBoxSearchInput');
});
});
Expand Down Expand Up @@ -314,7 +311,7 @@ describe('EuiComboBox', () => {
cy.get('.euiTextTruncate').should('exist');
cy.get('[data-test-subj="truncatedText"]').should(
'have.text',
'Lorem ipsum …iscing elit.'
'Lorem ipsum…iscing elit.'
);
});

Expand All @@ -334,7 +331,7 @@ describe('EuiComboBox', () => {
cy.get('[data-test-subj="comboBoxInput"]').realClick();
cy.get('[data-test-subj="truncatedText"]').should(
'have.text',
'Lorem…tur adipiscing elit.'
'Lorem…ur adipiscing elit.'
);
});

Expand All @@ -345,7 +342,7 @@ describe('EuiComboBox', () => {
cy.realType('sit');
cy.get('[data-test-subj="truncatedText"]').should(
'have.text',
'…sum dolor sit amet, co…'
'…um dolor sit amet, co…'
);
});

Expand All @@ -365,15 +362,15 @@ describe('EuiComboBox', () => {
cy.realType('eli');
cy.get('[data-test-subj="truncatedText"]').should(
'have.text',
'…nsectetur adipiscing elit.'
'…sectetur adipiscing elit.'
);
});

it('marks the full available text if the search input is longer than the truncated text', () => {
cy.realMount(<EuiComboBox {...sharedProps} />);
cy.get('[data-test-subj="comboBoxInput"]').realClick();
cy.realType('Lorem ipsum dolor sit amet');
cy.get('.euiMark').should('have.text', '…rem ipsum dolor sit am…');
cy.get('.euiMark').should('have.text', '…em ipsum dolor sit a…');
});
});
});
Expand Down Expand Up @@ -461,7 +458,7 @@ describe('EuiComboBox', () => {
cy.get('[data-test-subj="comboBoxInput"]').click();

cy.get('[data-test-subj="comboBoxOptionsList"]')
.find('button')
.find('[role="option"]')
.first()
.click();
cy.get('[data-test-subj="comboBoxOptionsList"]').should('not.exist');
Expand All @@ -483,7 +480,7 @@ describe('EuiComboBox', () => {
cy.get('[data-test-subj="comboBoxSearchInput"]').click();

cy.get('[data-test-subj="comboBoxOptionsList"]')
.find('button')
.find('[role="option"]')
.first()
.click();
cy.get('[data-test-subj="comboBoxOptionsList"]').should('not.exist');
Expand Down
51 changes: 50 additions & 1 deletion packages/eui/src/components/combo_box/combo_box.stories.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -69,6 +69,8 @@ const meta: Meta<EuiComboBoxProps<{}>> = {
compressed: false,
fullWidth: false,
onCreateOption: undefined, // Override Storybook's default callback
onFocusBadge: false,
'aria-label': 'Select an item',
},
};
enableFunctionToggleControls(meta, ['onChange', 'onCreateOption']);
Expand Down Expand Up @@ -180,7 +182,7 @@ export const WithTooltip: Story = {
toolTipContent: 'This is a tooltip!',
toolTipProps: {
position: 'left' as const,
['data-test-subj']: 'tooltip',
['data-test-subj']: `tooltip-${idx}`,
},
value: idx,
})),
Expand Down Expand Up @@ -283,10 +285,57 @@ export const NestedOptionsGroups: Story = {
render: (args) => <StatefulComboBox {...args} />,
};

export const CustomTruncation: Story = {
name: 'truncationProps',
parameters: {
controls: {
include: ['options', 'truncationProps'],
},
loki: {
chromeSelector: LOKI_SELECTORS.portal,
},
},
args: {
options: [
options[0],
{ label: 'Item 2 with a long label that should truncation by default' },
{
label: 'Lorem ipsum dolor sit amet, consectetur adipiscing elit.',
truncationProps: { truncation: 'start', truncationOffset: 5 },
},
...options.slice(3, options.length),
],
style: { width: 200 },
truncationProps: {
truncation: 'middle',
},
autoFocus: true,
},
render: (args) => <StatefulComboBox {...args} />,
};

/**
* VRT only
*/

export const DefaultTruncation: Story = {
tags: ['vrt-only'],
parameters: {
loki: {
chromeSelector: LOKI_SELECTORS.portal,
},
},
args: {
options: [
options[0],
{ label: 'Item 2 with a long label that should truncation by default' },
...options.slice(2, options.length),
],
autoFocus: true,
},
render: (args) => <StatefulComboBox {...args} />,
};

export const IconsAndManyOptionsSelected: Story = {
tags: ['vrt-only'],
args: {
Expand Down
27 changes: 23 additions & 4 deletions packages/eui/src/components/combo_box/combo_box.test.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -231,6 +231,9 @@ describe('EuiComboBox', () => {
toolTipContent: 'I am a tooltip!',
toolTipProps: {
'data-test-subj': 'optionToolTip',
anchorProps: {
'data-test-subj': 'optionToolTipAnchor',
},
},
},
{
Expand All @@ -245,7 +248,7 @@ describe('EuiComboBox', () => {

await showEuiComboBoxOptions();

fireEvent.mouseOver(getByTestSubject('titanOption'));
fireEvent.mouseOver(getByTestSubject('optionToolTipAnchor'));
await waitForEuiToolTipVisible();

expect(getByTestSubject('optionToolTip')).toBeInTheDocument();
Expand Down Expand Up @@ -436,9 +439,8 @@ describe('EuiComboBox', () => {
);
await showEuiComboBoxOptions();

const dropdownOptions = baseElement.querySelectorAll(
'.euiFilterSelectItem'
);
const dropdownOptions =
baseElement.querySelectorAll('.euiComboBoxOption');
expect(
dropdownOptions[0]!.querySelector('[data-euiicon-type="check"]')
).toBeFalsy();
Expand All @@ -447,6 +449,23 @@ describe('EuiComboBox', () => {
).toBeTruthy();
});

it('it renders a badge when onFocusBadge is `true`', async () => {
const { getByTestSubject, getAllByRole } = render(
<EuiComboBox options={options} onFocusBadge />
);

await showEuiComboBoxOptions();

// Navigate to an option (2 arrow downs: -1 -> 0 -> 1, so focused option is index 1)
const input = getByTestSubject('comboBoxSearchInput');
fireEvent.keyDown(input, { key: keys.ARROW_DOWN });

const focusedOption = getAllByRole('option')[0];
expect(
focusedOption.querySelector('.euiComboBoxOption__enterBadge')
).toBeInTheDocument();
});

describe('behavior', () => {
describe('hitting "Enter"', () => {
describe('when the search input matches a value', () => {
Expand Down
Loading