diff --git a/package.json b/package.json index 410dffca4b7ef2..f67fead47293dd 100644 --- a/package.json +++ b/package.json @@ -102,7 +102,7 @@ "@elastic/datemath": "5.0.3", "@elastic/elasticsearch": "npm:@elastic/elasticsearch-canary@8.9.1-canary.1", "@elastic/ems-client": "8.5.1", - "@elastic/eui": "92.0.0-backport.0", + "@elastic/eui": "92.1.1", "@elastic/filesaver": "1.1.2", "@elastic/node-crypto": "1.2.1", "@elastic/numeral": "^2.5.1", diff --git a/packages/core/i18n/core-i18n-browser-internal/src/__snapshots__/i18n_service.test.tsx.snap b/packages/core/i18n/core-i18n-browser-internal/src/__snapshots__/i18n_service.test.tsx.snap index c1f33ec2f18c67..78bb5d5d7ea713 100644 --- a/packages/core/i18n/core-i18n-browser-internal/src/__snapshots__/i18n_service.test.tsx.snap +++ b/packages/core/i18n/core-i18n-browser-internal/src/__snapshots__/i18n_service.test.tsx.snap @@ -83,6 +83,8 @@ exports[`#start() returns \`Context\` component 1`] = ` "euiDataGrid.ariaLabel": [Function], "euiDataGrid.ariaLabelledBy": [Function], "euiDataGrid.screenReaderNotice": "Cell contains interactive content.", + "euiDataGridCell.expansionEnterPrompt": "Press the Enter key to expand this cell.", + "euiDataGridCell.focusTrapEnterPrompt": "Press the Enter key to interact with this cell's contents.", "euiDataGridCell.position": [Function], "euiDataGridCellActions.expandButtonTitle": "Click or hit enter to interact with cell content", "euiDataGridHeaderCell.actionsPopoverScreenReaderText": "To navigate through the list of column actions, press the Tab or Up and Down arrow keys.", diff --git a/packages/core/i18n/core-i18n-browser-internal/src/i18n_eui_mapping.tsx b/packages/core/i18n/core-i18n-browser-internal/src/i18n_eui_mapping.tsx index 6f6a29e1a52559..8710a8640d747b 100644 --- a/packages/core/i18n/core-i18n-browser-internal/src/i18n_eui_mapping.tsx +++ b/packages/core/i18n/core-i18n-browser-internal/src/i18n_eui_mapping.tsx @@ -523,6 +523,14 @@ export const getEuiContextMapping = (): EuiTokensObject => { defaultMessage: '{columnId}, column {col}, row {row}', values: { columnId, row, col }, }), + 'euiDataGridCell.expansionEnterPrompt': i18n.translate( + 'core.euiDataGridCell.expansionEnterPrompt', + { defaultMessage: 'Press the Enter key to expand this cell.' } + ), + 'euiDataGridCell.focusTrapEnterPrompt': i18n.translate( + 'core.euiDataGridCell.focusTrapEnterPrompt', + { defaultMessage: "Press the Enter key to interact with this cell's contents." } + ), 'euiDataGridCellActions.expandButtonTitle': i18n.translate( 'core.euiDataGridCellActions.expandButtonTitle', { diff --git a/packages/kbn-resizable-layout/src/panels_resizable.tsx b/packages/kbn-resizable-layout/src/panels_resizable.tsx index 300c9130b8100c..6c9bd12674b20f 100644 --- a/packages/kbn-resizable-layout/src/panels_resizable.tsx +++ b/packages/kbn-resizable-layout/src/panels_resizable.tsx @@ -6,12 +6,19 @@ * Side Public License, v 1. */ -import { EuiResizableContainer, useGeneratedHtmlId, useResizeObserver } from '@elastic/eui'; +import { + EuiResizableContainer, + useGeneratedHtmlId, + useResizeObserver, + useEuiTheme, + mathWithUnits, +} from '@elastic/eui'; import type { ResizeTrigger } from '@elastic/eui/src/components/resizable_container/types'; import { css } from '@emotion/react'; import { isEqual, round } from 'lodash'; import type { ReactElement } from 'react'; import React, { useCallback, useEffect, useState } from 'react'; +import useLatest from 'react-use/lib/useLatest'; import { ResizableLayoutDirection } from '../types'; import { getContainerSize, percentToPixels, pixelsToPercent } from './utils'; @@ -47,41 +54,30 @@ export const PanelsResizable = ({ onFixedPanelSizeChange?: (fixedPanelSize: number) => void; setPanelSizes: (panelSizes: { fixedPanelSizePct: number; flexPanelSizePct: number }) => void; }) => { + const { euiTheme } = useEuiTheme(); const fixedPanelId = useGeneratedHtmlId({ prefix: 'fixedPanel' }); const { height: containerHeight, width: containerWidth } = useResizeObserver(container); const containerSize = getContainerSize(direction, containerWidth, containerHeight); - // EuiResizableContainer doesn't work properly when used with react-reverse-portal and - // will cancel the resize. To work around this we keep track of when resizes start and - // end to toggle the rendering of a transparent overlay which prevents the cancellation. - // EUI issue: https://github.com/elastic/eui/issues/6199 - const [resizeWithPortalsHackIsResizing, setResizeWithPortalsHackIsResizing] = useState(false); - const enableResizeWithPortalsHack = useCallback( - () => setResizeWithPortalsHackIsResizing(true), - [] - ); - const disableResizeWithPortalsHack = useCallback( - () => setResizeWithPortalsHackIsResizing(false), - [] - ); - const baseButtonCss = css` - background-color: transparent !important; - gap: 0 !important; - - &:not(:hover):not(:focus) { - &:before, - &:after { - width: 0; - } - } + // The resize overlay makes it so that other mouse events (e.g. tooltip hovers, etc) + // don't occur when mouse dragging + const [isResizing, setIsResizing] = useState(false); + + // Align the resizable button border to overlap exactly over existing panel/layout borders + const buttonBorderCss = css` + position: relative; + inset-${direction === 'horizontal' ? 'inline-start' : 'block-end'}: -${mathWithUnits( + euiTheme.border.width.thin, + (x) => x / 2 + )}; `; const defaultButtonCss = css` z-index: 3; `; - const resizeWithPortalsHackButtonCss = css` + const resizingButtonCss = css` z-index: 4; `; - const resizeWithPortalsHackOverlayCss = css` + const resizingOverlayCss = css` position: absolute; top: 0; left: 0; @@ -158,34 +154,35 @@ export const PanelsResizable = ({ setPanelSizes, ]); - const onResizeStart = useCallback( - (trigger: ResizeTrigger) => { - if (trigger !== 'pointer') { - return; - } - - enableResizeWithPortalsHack(); - }, - [enableResizeWithPortalsHack] - ); - - const onResizeEnd = useCallback(() => { - if (!resizeWithPortalsHackIsResizing) { + const onResizeStart = useCallback((trigger: ResizeTrigger) => { + if (trigger !== 'pointer') { return; } + setIsResizing(true); + }, []); + + // EUI will call an outdated version of this callback when the resize ends, + // so we need to make sure on our end that the latest version is called. + const onResizeEndStable = useLatest(() => { + setIsResizing((_isResizing) => { + // We don't want the resize button to retain focus after the resize is complete, + // but EuiResizableContainer will force focus it onClick. To work around this we + // use setTimeout to wait until after onClick has been called before blurring. + if (_isResizing) { + if (document.activeElement instanceof HTMLElement) { + const button = document.activeElement; + setTimeout(() => { + button.blur(); + }); + } + } + return false; + }); + }); - // We don't want the resize button to retain focus after the resize is complete, - // but EuiResizableContainer will force focus it onClick. To work around this we - // use setTimeout to wait until after onClick has been called before blurring. - if (document.activeElement instanceof HTMLElement) { - const button = document.activeElement; - setTimeout(() => { - button.blur(); - }); - } - - disableResizeWithPortalsHack(); - }, [disableResizeWithPortalsHack, resizeWithPortalsHackIsResizing]); + const onResizeEnd = useCallback(() => { + onResizeEndStable.current(); + }, [onResizeEndStable]); // Don't render EuiResizableContainer until we have have valid // panel sizes or it can cause the resize functionality to break. @@ -218,10 +215,8 @@ export const PanelsResizable = ({ {flexPanel} - {resizeWithPortalsHackIsResizing ?
: <>} + {isResizing ?
: <>} )} diff --git a/src/dev/license_checker/config.ts b/src/dev/license_checker/config.ts index 2846992840a59e..e171747874c2e3 100644 --- a/src/dev/license_checker/config.ts +++ b/src/dev/license_checker/config.ts @@ -85,7 +85,7 @@ export const LICENSE_OVERRIDES = { 'jsts@1.6.2': ['Eclipse Distribution License - v 1.0'], // cf. https://github.com/bjornharrtell/jsts '@mapbox/jsonlint-lines-primitives@2.0.2': ['MIT'], // license in readme https://github.com/tmcw/jsonlint '@elastic/ems-client@8.5.1': ['Elastic License 2.0'], - '@elastic/eui@92.0.0-backport.0': ['SSPL-1.0 OR Elastic License 2.0'], + '@elastic/eui@92.1.1': ['SSPL-1.0 OR Elastic License 2.0'], 'language-subtag-registry@0.3.21': ['CC-BY-4.0'], // retired ODC‑By license https://github.com/mattcg/language-subtag-registry 'buffers@0.1.1': ['MIT'], // license in importing module https://www.npmjs.com/package/binary '@bufbuild/protobuf@1.2.1': ['Apache-2.0'], // license (Apache-2.0 AND BSD-3-Clause) diff --git a/src/plugins/vis_default_editor/public/_default.scss b/src/plugins/vis_default_editor/public/_default.scss index 56c6a0f0f63f6c..2949712f6347e4 100644 --- a/src/plugins/vis_default_editor/public/_default.scss +++ b/src/plugins/vis_default_editor/public/_default.scss @@ -32,6 +32,10 @@ * Resizer */ +.visEditor__resizer { + height: auto; +} + .visEditor__resizer-isHidden { display: none; } diff --git a/src/plugins/vis_default_editor/public/default_editor.tsx b/src/plugins/vis_default_editor/public/default_editor.tsx index fdfcf5bd7d7cc7..2f6757a96d252d 100644 --- a/src/plugins/vis_default_editor/public/default_editor.tsx +++ b/src/plugins/vis_default_editor/public/default_editor.tsx @@ -109,6 +109,7 @@ function DefaultEditor({ diff --git a/x-pack/plugins/lens/public/visualizations/datatable/components/table_basic.test.tsx b/x-pack/plugins/lens/public/visualizations/datatable/components/table_basic.test.tsx index d99f62fcb9219c..7e7a18a94ac9c9 100644 --- a/x-pack/plugins/lens/public/visualizations/datatable/components/table_basic.test.tsx +++ b/x-pack/plugins/lens/public/visualizations/datatable/components/table_basic.test.tsx @@ -207,7 +207,7 @@ describe('DatatableComponent', () => { /> ); - wrapper.find('[data-test-subj="dataGridRowCell"]').first().simulate('focus'); + wrapper.find('[data-test-subj="dataGridRowCell"]').first().simulate('mouseEnter'); await waitForWrapperUpdate(wrapper); @@ -248,7 +248,7 @@ describe('DatatableComponent', () => { /> ); - wrapper.find('[data-test-subj="dataGridRowCell"]').at(1).simulate('focus'); + wrapper.find('[data-test-subj="dataGridRowCell"]').at(1).simulate('mouseEnter'); await waitForWrapperUpdate(wrapper); @@ -324,7 +324,7 @@ describe('DatatableComponent', () => { /> ); - wrapper.find('[data-test-subj="dataGridRowCell"]').at(0).simulate('focus'); + wrapper.find('[data-test-subj="dataGridRowCell"]').at(0).simulate('mouseEnter'); await waitForWrapperUpdate(wrapper); @@ -365,7 +365,7 @@ describe('DatatableComponent', () => { /> ); - wrapper.find('[data-test-subj="dataGridRowCell"]').first().simulate('focus'); + wrapper.find('[data-test-subj="dataGridRowCell"]').first().simulate('mouseEnter'); await waitForWrapperUpdate(wrapper); diff --git a/x-pack/plugins/osquery/cypress/e2e/all/live_query.cy.ts b/x-pack/plugins/osquery/cypress/e2e/all/live_query.cy.ts index 04a3a24fbabb56..8351e9df4728c6 100644 --- a/x-pack/plugins/osquery/cypress/e2e/all/live_query.cy.ts +++ b/x-pack/plugins/osquery/cypress/e2e/all/live_query.cy.ts @@ -58,10 +58,9 @@ describe('ALL - Live Query', { tags: ['@ess', '@serverless'] }, () => { expect(interception.response?.body.data.queries[0]).to.have.property('timeout', 890); }); checkResults(); - cy.get('[data-gridcell-column-index="0"][data-gridcell-row-index="0"]').should('exist'); - cy.get( - '[data-gridcell-column-index="0"][data-gridcell-row-index="0"] [data-datagrid-interactable="true"]' - ).click(); + const firstCell = '[data-gridcell-column-index="0"][data-gridcell-row-index="0"]'; + cy.get(firstCell).should('exist'); + cy.get(firstCell).find('[data-euigrid-tab-managed="true"]').click(); cy.url().should('include', 'app/fleet/agents/'); }); diff --git a/x-pack/plugins/osquery/cypress/tasks/saved_queries.ts b/x-pack/plugins/osquery/cypress/tasks/saved_queries.ts index 0ff06beed1d796..568649572ae994 100644 --- a/x-pack/plugins/osquery/cypress/tasks/saved_queries.ts +++ b/x-pack/plugins/osquery/cypress/tasks/saved_queries.ts @@ -52,15 +52,17 @@ export const getSavedQueriesComplexTest = () => // hidden columns cy.getBySel(RESULTS_TABLE_COLUMNS_BUTTON).should('have.text', 'Columns35'); - cy.getBySel('dataGridHeaderCell-osquery.cmdline').click(); - cy.contains(/Hide column$/).click(); - cy.getBySel('dataGridHeaderCell-osquery.cwd').click(); - - cy.contains(/Hide column$/).click(); - cy.getBySel('dataGridHeaderCell-osquery.disk_bytes_written.number').click(); - - cy.contains(/Hide column$/).click(); + cy.getBySel('dataGridColumnSelectorButton').click(); + cy.get('[data-popover-open="true"]').should('be.visible'); + cy.getBySel('dataGridColumnSelectorToggleColumnVisibility-osquery.cmdline').click(); + cy.getBySel('dataGridColumnSelectorToggleColumnVisibility-osquery.cwd').click(); + cy.getBySel( + 'dataGridColumnSelectorToggleColumnVisibility-osquery.disk_bytes_written.number' + ).click(); + cy.getBySel('dataGridColumnSelectorButton').click(); + cy.get('[data-popover-open="true"]').should('not.exist'); cy.getBySel(RESULTS_TABLE_COLUMNS_BUTTON).should('have.text', 'Columns32/35'); + // change pagination cy.getBySel('pagination-button-next').click().wait(500).click(); cy.getBySel(RESULTS_TABLE_COLUMNS_BUTTON).should('have.text', 'Columns32/35'); @@ -72,8 +74,7 @@ export const getSavedQueriesComplexTest = () => cy.getBySel(RESULTS_TABLE_BUTTON).click(); // sorting - cy.getBySel('dataGridHeaderCell-osquery.egid').click(); - + cy.getBySel('dataGridHeaderCellActionButton-osquery.egid').click({ force: true }); cy.contains(/Sort A-Z$/).click(); cy.getBySel(RESULTS_TABLE_COLUMNS_BUTTON).should('have.text', 'Columns32/35'); cy.getBySel(RESULTS_TABLE_BUTTON).trigger('mouseover'); diff --git a/x-pack/test/security_solution_cypress/cypress/tasks/alerts.ts b/x-pack/test/security_solution_cypress/cypress/tasks/alerts.ts index d75d94ed519d64..dfedc68af89851 100644 --- a/x-pack/test/security_solution_cypress/cypress/tasks/alerts.ts +++ b/x-pack/test/security_solution_cypress/cypress/tasks/alerts.ts @@ -143,8 +143,9 @@ export const expandFirstAlertActions = () => { }; export const expandFirstAlert = () => { - cy.get(EXPAND_ALERT_BTN).should('be.visible'); - cy.get(EXPAND_ALERT_BTN).first().click(); + cy.get(EXPAND_ALERT_BTN).first().should('be.visible'); + // Cypress is flaky on clicking this button despite production not having that issue + cy.get(EXPAND_ALERT_BTN).first().trigger('click'); }; export const hideMessageTooltip = () => { diff --git a/x-pack/test/security_solution_cypress/cypress/tasks/asset_criticality/common.ts b/x-pack/test/security_solution_cypress/cypress/tasks/asset_criticality/common.ts index 515bd4061365af..f867efc80f8b37 100644 --- a/x-pack/test/security_solution_cypress/cypress/tasks/asset_criticality/common.ts +++ b/x-pack/test/security_solution_cypress/cypress/tasks/asset_criticality/common.ts @@ -21,7 +21,9 @@ import { scrollAlertTableColumnIntoView } from '../alerts'; * Find the first alert row in the alerts table then click on the host name to open the flyout */ export const expandFirstAlertHostFlyout = () => { - cy.get(OPEN_HOST_FLYOUT_BUTTON).first().click(); + // Cypress is flaky on clicking this button despite production not having that issue + // eslint-disable-next-line cypress/no-force + cy.get(OPEN_HOST_FLYOUT_BUTTON).first().click({ force: true }); }; /** diff --git a/yarn.lock b/yarn.lock index 50ea6503d5906d..1ef4d6d6e968f3 100644 --- a/yarn.lock +++ b/yarn.lock @@ -1740,10 +1740,10 @@ resolved "https://registry.yarnpkg.com/@elastic/eslint-plugin-eui/-/eslint-plugin-eui-0.0.2.tgz#56b9ef03984a05cc213772ae3713ea8ef47b0314" integrity sha512-IoxURM5zraoQ7C8f+mJb9HYSENiZGgRVcG4tLQxE61yHNNRDXtGDWTZh8N1KIHcsqN1CEPETjuzBXkJYF/fDiQ== -"@elastic/eui@92.0.0-backport.0": - version "92.0.0-backport.0" - resolved "https://registry.yarnpkg.com/@elastic/eui/-/eui-92.0.0-backport.0.tgz#201757bef89141dad6f8f719976fa2a0b52be86a" - integrity sha512-ZliSke0YehCbCuHvYkY0BIMg32QeqTMZy+qgGYsh+Bp0UZ4CZn9j5e7LWavfal3+t8HMFCHTk0RUFFXrcepplA== +"@elastic/eui@92.1.1": + version "92.1.1" + resolved "https://registry.yarnpkg.com/@elastic/eui/-/eui-92.1.1.tgz#f5713bfa12733a2c62df365e37f7983a7c08411e" + integrity sha512-kjUP+IewVcoJ59e84lHwtdy5OvGNSmlHvzn5uUmGTKnBGOxoYv5K9pyGujVWpxSCG9MNr3anMsNE7EX6usj37A== dependencies: "@hello-pangea/dnd" "^16.3.0" "@types/lodash" "^4.14.198"