diff --git a/CHANGELOG.md b/CHANGELOG.md index 45f40029eb3..301aa72a64f 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,6 +1,12 @@ ## [`main`](https://github.com/elastic/eui/tree/main) + - Updated `testenv` mock for `EuiFlyout` to include default `aria-label` on the close button ([#5702](https://github.com/elastic/eui/pull/5702)) +**Breaking changes** + +- Changed the I18n token `euiDataGridToolbar.fullScreenButton` to `euiFullscreenSelector.fullscreenButton`, and its text to `Enter fullscreen` (with no space) ([#5680](https://github.com/elastic/eui/pull/5680)) +- Changed the I18n token `euiDataGridToolbar.fullScreenButtonActive` to `euiFullscreenSelector.fullscreenButtonActive`, and its text to `Exit fullscreen` (with no space) ([#5680](https://github.com/elastic/eui/pull/5680)) + ## [`51.0.0`](https://github.com/elastic/eui/tree/v51.0.0) - Enhanced `EuiSuggest` to fire the `onItemClick` callback on Enter key press as well as clicks ([#5693](https://github.com/elastic/eui/pull/5693)) diff --git a/src-docs/src/components/guide_page/_guide_page.scss b/src-docs/src/components/guide_page/_guide_page.scss index a9eebb6ec9c..1344b4409f9 100644 --- a/src-docs/src/components/guide_page/_guide_page.scss +++ b/src-docs/src/components/guide_page/_guide_page.scss @@ -22,7 +22,7 @@ $guideSideNavWidth: 240px; } .euiHeader:not(.euiHeader--fixed) { - // Force headers below the full screen. + // Force headers below the fullscreen. // This shouldn't be necessary in consuming applications because headers should always be at the top of the page z-index: 0; } diff --git a/src-docs/src/components/guide_section/guide_section.tsx b/src-docs/src/components/guide_section/guide_section.tsx index 873ebfd8d92..9e405b42fb5 100644 --- a/src-docs/src/components/guide_section/guide_section.tsx +++ b/src-docs/src/components/guide_section/guide_section.tsx @@ -206,7 +206,7 @@ export const GuideSection: FunctionComponent = ({ iconType="fullScreen" href={`#${path}/${fullScreen.slug}`} > - Full screen demo + Fullscreen demo ) : ( demo diff --git a/src-docs/src/views/code/code_example.js b/src-docs/src/views/code/code_example.js index ab534b01b43..d15fa5c4d1e 100644 --- a/src-docs/src/views/code/code_example.js +++ b/src-docs/src/views/code/code_example.js @@ -172,7 +172,7 @@ export const CodeExample = {

For long content, you can set an overflowHeight{' '} which will scroll if the text exceeds that height, and allows users to - view the code in full-screen mode. + view the code in fullscreen mode.

), source: [ diff --git a/src-docs/src/views/collapsible_nav/collapsible_nav_all.tsx b/src-docs/src/views/collapsible_nav/collapsible_nav_all.tsx index fbbfb17f840..55610dc1f22 100644 --- a/src-docs/src/views/collapsible_nav/collapsible_nav_all.tsx +++ b/src-docs/src/views/collapsible_nav/collapsible_nav_all.tsx @@ -289,7 +289,7 @@ const CollapsibleNavAll = () => { { items: [ - Exit full screen + Exit fullscreen , ], }, diff --git a/src-docs/src/views/collapsible_nav/collapsible_nav_example.js b/src-docs/src/views/collapsible_nav/collapsible_nav_example.js index 19e82b26e33..d40e9d4258f 100644 --- a/src-docs/src/views/collapsible_nav/collapsible_nav_example.js +++ b/src-docs/src/views/collapsible_nav/collapsible_nav_example.js @@ -179,7 +179,7 @@ export const CollapsibleNavExample = { <>

Putting it all together

- The button below will launch a full screen example that includes{' '} + The button below will launch a fullscreen example that includes{' '} EuiHeader {' '} diff --git a/src-docs/src/views/context_menu/context_menu_with_content.js b/src-docs/src/views/context_menu/context_menu_with_content.js index 61042fd1694..db18ad83718 100644 --- a/src-docs/src/views/context_menu/context_menu_with_content.js +++ b/src-docs/src/views/context_menu/context_menu_with_content.js @@ -60,7 +60,7 @@ export default () => { title: 'View options', items: [ { - name: 'Show full screen', + name: 'Show fullscreen', icon: , onClick: () => { closePopover(); diff --git a/src-docs/src/views/datagrid/datagrid.js b/src-docs/src/views/datagrid/datagrid.js index 70e0c508fd0..9dfdc24fc8c 100644 --- a/src-docs/src/views/datagrid/datagrid.js +++ b/src-docs/src/views/datagrid/datagrid.js @@ -256,7 +256,7 @@ const trailingControlColumns = [ EuiModal {' '} components have a higher z-index than{' '} - EuiDataGrid components, even in full screen + EuiDataGrid components, even in fullscreen mode. This ensures that modals will never appear behind the data grid.

@@ -305,7 +305,7 @@ const trailingControlColumns = [ EuiFlyout {' '} components have a higher z-index than{' '} - EuiDataGrid components, even in full screen + EuiDataGrid components, even in fullscreen mode. This ensures that flyouts will never appear behind the data grid.

@@ -313,7 +313,7 @@ const trailingControlColumns = [

Flyouts are also styled with a vertical offset that accounts for the presence of fixed headers. However, when the data grid - is in full screen mode, these offset styles are ignored to + is in fullscreen mode, these offset styles are ignored to allow the flyout to correctly appear at the top of the viewport.

diff --git a/src-docs/src/views/datagrid/datagrid_ref_example.js b/src-docs/src/views/datagrid/datagrid_ref_example.js index 66795c4e25b..2b7066b3937 100644 --- a/src-docs/src/views/datagrid/datagrid_ref_example.js +++ b/src-docs/src/views/datagrid/datagrid_ref_example.js @@ -9,10 +9,10 @@ const dataGridRefSource = require('!!raw-loader!./ref'); const dataGridRefSnippet = `const dataGridRef = useRef(); -// Mnaually toggle the data grid's full screen state +// Manually toggle the data grid's fullscreen state dataGridRef.current.setIsFullScreen(true); -// Mnaually focus a specific cell within the data grid +// Manually focus a specific cell within the data grid dataGridRef.current.setFocusedCell({ rowIndex, colIndex }); // Manually opens the popover of a specified cell within the data grid @@ -45,7 +45,7 @@ export const DataGridRefExample = {
  • setIsFullScreen(isFullScreen) - controls the - full screen state of the data grid. Accepts a true/false boolean + fullscreen state of the data grid. Accepts a true/false boolean flag.

  • diff --git a/src-docs/src/views/datagrid/ref.tsx b/src-docs/src/views/datagrid/ref.tsx index 267892df41e..e6924988845 100644 --- a/src-docs/src/views/datagrid/ref.tsx +++ b/src-docs/src/views/datagrid/ref.tsx @@ -179,7 +179,7 @@ export default () => { size="s" onClick={() => dataGridRef.current!.setIsFullScreen(true)} > - Set grid to full screen + Set grid to fullscreen diff --git a/src-docs/src/views/datagrid/styling.js b/src-docs/src/views/datagrid/styling.js index addddfae77d..af221cd621f 100644 --- a/src-docs/src/views/datagrid/styling.js +++ b/src-docs/src/views/datagrid/styling.js @@ -678,12 +678,12 @@ const DataGrid = () => { { color="primary" href={`#${parentPath}`} > - Exit full screen + Exit fullscreen )} diff --git a/src-docs/src/views/header/header_example.js b/src-docs/src/views/header/header_example.js index 66125b1a85f..99fb2852c26 100644 --- a/src-docs/src/views/header/header_example.js +++ b/src-docs/src/views/header/header_example.js @@ -477,7 +477,7 @@ export const HeaderExample = { <>

    Putting it all together

    - The button below will launch a full screen example that includes two{' '} + The button below will launch a fullscreen example that includes two{' '} EuiHeaders with all the appropriate navigation pieces including{' '} diff --git a/src-docs/src/views/image/image_example.js b/src-docs/src/views/image/image_example.js index ab8025e570e..ee7cbe6c1b8 100644 --- a/src-docs/src/views/image/image_example.js +++ b/src-docs/src/views/image/image_example.js @@ -67,7 +67,7 @@ export const ImageExample = { playground: imageConfig, }, { - title: 'Click an image for a full screen version', + title: 'Click an image for a fullscreen version', source: [ { type: GuideSectionTypes.JS, @@ -77,7 +77,7 @@ export const ImageExample = { text: (

    Apply the allowFullScreen prop to make the image - clickable and show a full screen version. Note that the second image + clickable and show a fullscreen version. Note that the second image also passes{' '} fullScreenIconColor="dark"{' '} to change icon color to better contrast against the light background diff --git a/src-docs/src/views/loading/loading_example.js b/src-docs/src/views/loading/loading_example.js index 4f638c43d9c..5a20c55f077 100644 --- a/src-docs/src/views/loading/loading_example.js +++ b/src-docs/src/views/loading/loading_example.js @@ -82,7 +82,7 @@ export const LoadingExample = { EuiIcon {' '} - logos. It should only be used in very large panels, like full screen + logos. It should only be used in very large panels, like fullscreen pages.

    ), diff --git a/src-docs/src/views/page/_page_demo.tsx b/src-docs/src/views/page/_page_demo.tsx index a507ed5bafe..f1b0a8d4d90 100644 --- a/src-docs/src/views/page/_page_demo.tsx +++ b/src-docs/src/views/page/_page_demo.tsx @@ -22,7 +22,7 @@ const ExitFullscreenDemoButton = () => { const exitPath = useExitPath(); return ( - Exit full screen + Exit fullscreen ); }; @@ -69,7 +69,7 @@ export const PageDemo: FunctionComponent<{ ) : ( - Go full screen + Go fullscreen ); diff --git a/src-docs/src/views/page/page_example.js b/src-docs/src/views/page/page_example.js index 3271025bba2..e558da87f76 100644 --- a/src-docs/src/views/page/page_example.js +++ b/src-docs/src/views/page/page_example.js @@ -93,8 +93,8 @@ export const PageExample = { >

    You'll find the code for each in their own tab and if you go to - full screen, you can see how they would behave in a typical - application layout. + fullscreen, you can see how they would behave in a typical application + layout.

    diff --git a/src-docs/src/views/tour/fullscreen.js b/src-docs/src/views/tour/fullscreen.js index ead276d6793..9ab80fd5a30 100644 --- a/src-docs/src/views/tour/fullscreen.js +++ b/src-docs/src/views/tour/fullscreen.js @@ -173,7 +173,7 @@ export default () => { {({ parentPath }) => ( - Exit full screen demo + Exit fullscreen demo )} , diff --git a/src-docs/src/views/tour/tour_example.js b/src-docs/src/views/tour/tour_example.js index 5f75a683fd5..4cf03579c08 100644 --- a/src-docs/src/views/tour/tour_example.js +++ b/src-docs/src/views/tour/tour_example.js @@ -149,7 +149,7 @@ export const TourExample = { demo: , }, { - title: 'Full screen demo', + title: 'Fullscreen demo', source: [ { type: GuideSectionTypes.JS, @@ -163,7 +163,7 @@ export const TourExample = {

    ), fullScreen: { - slug: 'full-screen', + slug: 'fullscreen', demo: , }, }, diff --git a/src/components/code/__snapshots__/code_block.test.tsx.snap b/src/components/code/__snapshots__/code_block.test.tsx.snap index bb7b7cf094b..e642da216f7 100644 --- a/src/components/code/__snapshots__/code_block.test.tsx.snap +++ b/src/components/code/__snapshots__/code_block.test.tsx.snap @@ -40,7 +40,7 @@ exports[`EuiCodeBlock dynamic content updates DOM when input changes 2`] = ` `; -exports[`EuiCodeBlock full screen displays content in fullscreen mode 1`] = ` +exports[`EuiCodeBlock fullscreen displays content in fullscreen mode 1`] = `
    diff --git a/src/components/code/code_block.test.tsx b/src/components/code/code_block.test.tsx index 87967d9e011..ea96d2a0e52 100644 --- a/src/components/code/code_block.test.tsx +++ b/src/components/code/code_block.test.tsx @@ -146,7 +146,7 @@ describe('EuiCodeBlock', () => { }); }); - describe('full screen', () => { + describe('fullscreen', () => { it('displays content in fullscreen mode', () => { const component = mount( = ({ FullScreenDisplay, } = useFullScreen({ overflowHeight }); - // Classes used in both full-screen and non-full-screen mode + // Classes used in both fullscreen and non-fullscreen mode const wrapperClasses = classNames(className, 'euiCodeBlock', { 'euiCodeBlock--hasControl': showCopyButton || showFullScreenButton, 'euiCodeBlock--hasBothControls': showCopyButton && showFullScreenButton, 'euiCodeBlock--hasLineNumbers': lineNumbersConfig.show, }); - // Classes used in non-full-screen mode only + // Classes used in non-fullscreen mode only const classes = classNames( wrapperClasses, fontSizeToClassNameMap[fontSize], diff --git a/src/components/datagrid/__snapshots__/data_grid.test.tsx.snap b/src/components/datagrid/__snapshots__/data_grid.test.tsx.snap index 256b4cf0579..b310ff8a31b 100644 --- a/src/components/datagrid/__snapshots__/data_grid.test.tsx.snap +++ b/src/components/datagrid/__snapshots__/data_grid.test.tsx.snap @@ -1012,7 +1012,7 @@ Array [ class="euiToolTipAnchor" >
    `); @@ -131,29 +118,6 @@ describe('EuiDataGridToolbar', () => { `); }); - - it('handles full screen toggling', () => { - const component = shallow(); - component.setProps({ - setIsFullScreen: () => component.setProps({ isFullScreen: true }), - }); - - component - .find('[data-test-subj="dataGridFullScreenButton"]') - .simulate('click'); - - expect(component.find('[data-test-subj="dataGridFullScreenButton"]')) - .toMatchInlineSnapshot(` - - `); - }); }); describe('checkOrDefaultToolBarDisplayOptions', () => { diff --git a/src/components/datagrid/controls/data_grid_toolbar.tsx b/src/components/datagrid/controls/data_grid_toolbar.tsx index 7182c3cb4e2..1cf496c1aaa 100644 --- a/src/components/datagrid/controls/data_grid_toolbar.tsx +++ b/src/components/datagrid/controls/data_grid_toolbar.tsx @@ -6,10 +6,7 @@ * Side Public License, v 1. */ -import React, { useEffect } from 'react'; -import { EuiToolTip } from '../../tool_tip'; -import { EuiButtonIcon } from '../../button'; -import { useEuiI18n } from '../../i18n'; +import React from 'react'; import { EuiDataGridProps, EuiDataGridToolbarProps, @@ -19,71 +16,24 @@ import { } from '../data_grid_types'; import { IS_JEST_ENVIRONMENT } from '../../../utils'; -// When below this number the grid only shows the full screen button +// When below this number the grid only shows the right control icon buttons const MINIMUM_WIDTH_FOR_GRID_CONTROLS = 479; -// When data grid is full screen, we add a class to the body to remove the extra scrollbar -const GRID_IS_FULLSCREEN_CLASSNAME = 'euiDataGrid__restrictBody'; - export const EuiDataGridToolbar = ({ gridWidth, minSizeForControls = MINIMUM_WIDTH_FOR_GRID_CONTROLS, toolbarVisibility, isFullScreen, - controlBtnClasses, + fullScreenSelector, displaySelector, columnSelector, columnSorting, - setIsFullScreen, }: EuiDataGridToolbarProps) => { - const [fullScreenButton, fullScreenButtonActive] = useEuiI18n( - [ - 'euiDataGridToolbar.fullScreenButton', - 'euiDataGridToolbar.fullScreenButtonActive', - ], - ['Full screen', 'Exit full screen'] - ); // Enables/disables grid controls based on available width const hasRoomForGridControls = IS_JEST_ENVIRONMENT ? true : gridWidth > minSizeForControls || isFullScreen; - useEffect(() => { - // When data grid is full screen, we add a class to the body to remove the extra scrollbar and stay above any fixed headers - if (isFullScreen) { - document.body.classList.add(GRID_IS_FULLSCREEN_CLASSNAME); - - return () => { - document.body.classList.remove(GRID_IS_FULLSCREEN_CLASSNAME); - }; - } - }, [isFullScreen]); - - const fullScreenSelector = ( - - {fullScreenButtonActive} (esc) - - ) : ( - fullScreenButton - ) - } - delay="long" - > - setIsFullScreen(!isFullScreen)} - aria-label={isFullScreen ? fullScreenButtonActive : fullScreenButton} - /> - - ); - return (
    {hasRoomForGridControls && ( diff --git a/src/components/datagrid/controls/fullscreen_selector.test.tsx b/src/components/datagrid/controls/fullscreen_selector.test.tsx new file mode 100644 index 00000000000..54c901b1c2a --- /dev/null +++ b/src/components/datagrid/controls/fullscreen_selector.test.tsx @@ -0,0 +1,178 @@ +/* + * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one + * or more contributor license agreements. Licensed under the Elastic License + * 2.0 and the Server Side Public License, v 1; you may not use this file except + * in compliance with, at your election, the Elastic License 2.0 or the Server + * Side Public License, v 1. + */ + +import React from 'react'; +import { act } from 'react-dom/test-utils'; +import { shallow } from 'enzyme'; +import { keys } from '../../../services'; +import { testCustomHook } from '../../../test/test_custom_hook.test_helper'; +import { useDataGridFullScreenSelector } from './fullscreen_selector'; + +describe('useDataGridFullScreenSelector', () => { + type ReturnedValues = ReturnType; + + describe('isFullScreen state', () => { + test('setFullScreen toggles isFullScreen', () => { + const { + return: { isFullScreen, setIsFullScreen }, + getUpdatedState, + } = testCustomHook(() => useDataGridFullScreenSelector()); + + expect(isFullScreen).toEqual(false); + act(() => setIsFullScreen(true)); + expect(getUpdatedState().isFullScreen).toEqual(true); + }); + }); + + describe('fullScreenSelector', () => { + it('renders a button that toggles entering fullscreen', () => { + const { + return: { fullScreenSelector }, + } = testCustomHook(() => useDataGridFullScreenSelector()); + const component = shallow(
    {fullScreenSelector}
    ); + + expect(component).toMatchInlineSnapshot(` +
    + + + +
    + `); + }); + + it('renders a button that toggles exiting fullscreen', () => { + const { + return: { setIsFullScreen }, + getUpdatedState, + } = testCustomHook(() => useDataGridFullScreenSelector()); + act(() => setIsFullScreen(true)); + + const { fullScreenSelector } = getUpdatedState(); + const component = shallow(
    {fullScreenSelector}
    ); + + expect(component).toMatchInlineSnapshot(` +
    + + Exit fullscreen + ( + + esc + + ) + + } + delay="long" + display="inlineBlock" + position="top" + > + + +
    + `); + }); + + it('toggles fullscreen mode on button click', () => { + const { + return: { fullScreenSelector, isFullScreen }, + getUpdatedState, + } = testCustomHook(() => useDataGridFullScreenSelector()); + expect(isFullScreen).toEqual(false); + const component = shallow(
    {fullScreenSelector}
    ); + + act(() => { + component + .find('[data-test-subj="dataGridFullScreenButton"]') + .simulate('click'); + }); + expect(getUpdatedState().isFullScreen).toEqual(true); + }); + }); + + describe('handleGridKeyDown', () => { + it('exits fullscreen mode when the Escape key is pressed', () => { + const { + return: { setIsFullScreen }, + getUpdatedState, + } = testCustomHook(() => useDataGridFullScreenSelector()); + act(() => setIsFullScreen(true)); + const { handleGridKeyDown } = getUpdatedState(); + + const preventDefault = jest.fn(); + act(() => handleGridKeyDown({ key: keys.ESCAPE, preventDefault } as any)); + + expect(preventDefault).toHaveBeenCalled(); + expect(getUpdatedState().isFullScreen).toEqual(false); + }); + + it('does nothing if fullscreen is not open', () => { + const { + return: { handleGridKeyDown }, + getUpdatedState, + } = testCustomHook(() => useDataGridFullScreenSelector()); + + const preventDefault = jest.fn(); + act(() => handleGridKeyDown({ key: keys.ESCAPE, preventDefault } as any)); + + expect(preventDefault).not.toHaveBeenCalled(); + expect(getUpdatedState().isFullScreen).toEqual(false); + }); + + it('does nothing if other keys are pressed or fullscreen is not open', () => { + const { + return: { handleGridKeyDown }, + getUpdatedState, + } = testCustomHook(() => useDataGridFullScreenSelector()); + + const preventDefault = jest.fn(); + act(() => handleGridKeyDown({ key: keys.ENTER, preventDefault } as any)); + + expect(preventDefault).not.toHaveBeenCalled(); + expect(getUpdatedState().isFullScreen).toEqual(false); + }); + }); + + describe('body classes', () => { + it('adds and removes a fullscreen class to the document body when fullscreen opens/closes', () => { + const { + return: { setIsFullScreen }, + } = testCustomHook(() => useDataGridFullScreenSelector()); + act(() => setIsFullScreen(true)); + expect( + document.body.classList.contains('euiDataGrid__restrictBody') + ).toBe(true); + + act(() => setIsFullScreen(false)); + expect( + document.body.classList.contains('euiDataGrid__restrictBody') + ).toBe(false); + }); + }); +}); diff --git a/src/components/datagrid/controls/fullscreen_selector.tsx b/src/components/datagrid/controls/fullscreen_selector.tsx new file mode 100644 index 00000000000..c76ba9931ee --- /dev/null +++ b/src/components/datagrid/controls/fullscreen_selector.tsx @@ -0,0 +1,103 @@ +/* + * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one + * or more contributor license agreements. Licensed under the Elastic License + * 2.0 and the Server Side Public License, v 1; you may not use this file except + * in compliance with, at your election, the Elastic License 2.0 or the Server + * Side Public License, v 1. + */ + +import React, { + useState, + useEffect, + useMemo, + useCallback, + ReactNode, + KeyboardEvent, + KeyboardEventHandler, +} from 'react'; +import classNames from 'classnames'; +import { keys } from '../../../services'; +import { EuiToolTip } from '../../tool_tip'; +import { EuiButtonIcon } from '../../button'; +import { useEuiI18n } from '../../i18n'; + +const GRID_IS_FULLSCREEN_CLASSNAME = 'euiDataGrid__restrictBody'; + +export const useDataGridFullScreenSelector = (): { + isFullScreen: boolean; + setIsFullScreen: (isFullScreen: boolean) => void; + fullScreenSelector: ReactNode; + handleGridKeyDown: KeyboardEventHandler; +} => { + const [isFullScreen, setIsFullScreen] = useState(false); + + const [fullScreenButton, fullScreenButtonActive] = useEuiI18n( + [ + 'euiFullscreenSelector.fullscreenButton', + 'euiFullscreenSelector.fullscreenButtonActive', + ], + ['Enter fullscreen', 'Exit fullscreen'] + ); + const controlBtnClasses = classNames('euiDataGrid__controlBtn', { + 'euiDataGrid__controlBtn--active': isFullScreen, + }); + const fullScreenSelector = useMemo( + () => ( + + {fullScreenButtonActive} (esc) + + ) : ( + fullScreenButton + ) + } + delay="long" + > + setIsFullScreen(!isFullScreen)} + aria-label={isFullScreen ? fullScreenButtonActive : fullScreenButton} + /> + + ), + [isFullScreen, controlBtnClasses, fullScreenButton, fullScreenButtonActive] + ); + + const handleGridKeyDown = useCallback( + (event: KeyboardEvent) => { + switch (event.key) { + case keys.ESCAPE: + if (isFullScreen) { + event.preventDefault(); + setIsFullScreen(false); + } + break; + } + }, + [isFullScreen] + ); + + useEffect(() => { + // When the data grid is fullscreen, we add a class to the body to remove the extra scrollbar and stay above any fixed headers + if (isFullScreen) { + document.body.classList.add(GRID_IS_FULLSCREEN_CLASSNAME); + + return () => { + document.body.classList.remove(GRID_IS_FULLSCREEN_CLASSNAME); + }; + } + }, [isFullScreen]); + + return { + isFullScreen, + setIsFullScreen, + fullScreenSelector, + handleGridKeyDown, + }; +}; diff --git a/src/components/datagrid/controls/index.ts b/src/components/datagrid/controls/index.ts index 0c0ca128208..62f5a1435b4 100644 --- a/src/components/datagrid/controls/index.ts +++ b/src/components/datagrid/controls/index.ts @@ -9,6 +9,7 @@ export { useDataGridColumnSelector } from './column_selector'; export { useDataGridColumnSorting } from './column_sorting'; export { useDataGridDisplaySelector, startingStyles } from './display_selector'; +export { useDataGridFullScreenSelector } from './fullscreen_selector'; export { checkOrDefaultToolBarDisplayOptions, EuiDataGridToolbar, diff --git a/src/components/datagrid/data_grid.test.tsx b/src/components/datagrid/data_grid.test.tsx index fbb30353353..2f03c240189 100644 --- a/src/components/datagrid/data_grid.test.tsx +++ b/src/components/datagrid/data_grid.test.tsx @@ -786,9 +786,9 @@ describe('EuiDataGrid', () => { }); // fullscreen selector - expect(findTestSubject(component, 'dataGridFullScrenButton').length).toBe( - 0 - ); + expect( + findTestSubject(component, 'dataGridFullScreenButton').length + ).toBe(0); // sort selector expect( diff --git a/src/components/datagrid/data_grid.tsx b/src/components/datagrid/data_grid.tsx index bdc4ac6e9a0..6c105fccee8 100644 --- a/src/components/datagrid/data_grid.tsx +++ b/src/components/datagrid/data_grid.tsx @@ -7,18 +7,12 @@ */ import classNames from 'classnames'; -import React, { - forwardRef, - KeyboardEvent, - useMemo, - useRef, - useState, -} from 'react'; +import React, { forwardRef, useMemo, useRef, useState } from 'react'; import { VariableSizeGrid as Grid, GridOnItemsRenderedProps, } from 'react-window'; -import { useGeneratedHtmlId, keys } from '../../services'; +import { useGeneratedHtmlId } from '../../services'; import { EuiFocusTrap } from '../focus_trap'; import { EuiI18n, useEuiI18n } from '../i18n'; import { useMutationObserver } from '../observer/mutation_observer'; @@ -29,6 +23,7 @@ import { useDataGridColumnSorting, useDataGridDisplaySelector, startingStyles, + useDataGridFullScreenSelector, checkOrDefaultToolBarDisplayOptions, EuiDataGridToolbar, } from './controls'; @@ -276,21 +271,16 @@ export const EuiDataGrid = forwardRef( const { cellPopoverContext, cellPopover } = useCellPopover(); /** - * Toolbar & full-screen + * Toolbar & fullscreen */ const showToolbar = !!toolbarVisibility; - const [isFullScreen, setIsFullScreen] = useState(false); - const handleGridKeyDown = (event: KeyboardEvent) => { - switch (event.key) { - case keys.ESCAPE: - if (isFullScreen) { - event.preventDefault(); - setIsFullScreen(false); - } - break; - } - }; + const { + isFullScreen, + setIsFullScreen, + fullScreenSelector, + handleGridKeyDown, + } = useDataGridFullScreenSelector(); /** * Expose certain internal APIs as ref to consumer @@ -333,10 +323,6 @@ export const EuiDataGrid = forwardRef( className ); - const controlBtnClasses = classNames('euiDataGrid__controlBtn', { - 'euiDataGrid__controlBtn--active': isFullScreen, - }); - /** * Accessibility */ @@ -395,10 +381,9 @@ export const EuiDataGrid = forwardRef( gridWidth={gridWidth} minSizeForControls={minSizeForControls} toolbarVisibility={toolbarVisibility} - displaySelector={displaySelector} isFullScreen={isFullScreen} - setIsFullScreen={setIsFullScreen} - controlBtnClasses={controlBtnClasses} + fullScreenSelector={fullScreenSelector} + displaySelector={displaySelector} columnSelector={columnSelector} columnSorting={columnSorting} /> diff --git a/src/components/datagrid/data_grid_types.ts b/src/components/datagrid/data_grid_types.ts index fc09d3e50d3..9d5e7855f7a 100644 --- a/src/components/datagrid/data_grid_types.ts +++ b/src/components/datagrid/data_grid_types.ts @@ -14,8 +14,6 @@ import { CSSProperties, ReactElement, AriaAttributes, - Dispatch, - SetStateAction, MutableRefObject, } from 'react'; import { @@ -34,12 +32,11 @@ export interface EuiDataGridToolbarProps { gridWidth: number; minSizeForControls?: number; toolbarVisibility: boolean | EuiDataGridToolBarVisibilityOptions; - displaySelector: ReactNode; isFullScreen: boolean; - controlBtnClasses: string; + fullScreenSelector: ReactNode; + displaySelector: ReactNode; columnSelector: ReactNode; columnSorting: ReactNode; - setIsFullScreen: Dispatch>; } export interface EuiDataGridPaginationRendererProps @@ -310,7 +307,7 @@ export type EuiDataGridProps = OneOf< export interface EuiDataGridRefProps { /** - * Allows manually controlling the full-screen state of the grid. + * Allows manually controlling the fullscreen state of the grid. */ setIsFullScreen: (isFullScreen: boolean) => void; /** @@ -727,7 +724,7 @@ export interface EuiDataGridToolBarVisibilityOptions { */ showSortSelector?: boolean; /** - * Allows user to be able to full screen the data grid. If set to `false` make sure your grid fits within a large enough panel to still show the other controls. + * Allows user to be able to fullscreen the data grid. If set to `false` make sure your grid fits within a large enough panel to still show the other controls. */ showFullScreenSelector?: boolean; /** @@ -745,7 +742,7 @@ export interface EuiDataGridToolBarAdditionalControlsOptions { */ left?: ReactNode | EuiDataGridToolBarAdditionalControlsLeftOptions; /** - * Will prepend the passed node into the right side of the toolbar, **before** the density & full screen controls. + * Will prepend the passed node into the right side of the toolbar, **before** the density & fullscreen controls. * We recommend using `` to match the existing controls on the right. */ right?: ReactNode; diff --git a/src/components/datagrid/utils/grid_height_width.ts b/src/components/datagrid/utils/grid_height_width.ts index 02458020d3f..0b901720515 100644 --- a/src/components/datagrid/utils/grid_height_width.ts +++ b/src/components/datagrid/utils/grid_height_width.ts @@ -32,7 +32,7 @@ export const useFinalGridDimensions = ({ // Used if the grid needs to scroll const [height, setHeight] = useState(undefined); const [width, setWidth] = useState(undefined); - // Tracking full screen height separately is necessary to correctly restore the grid back to non-full-screen height + // Tracking fullscreen height separately is necessary to correctly restore the grid back to non-fullscreen height const [fullScreenHeight, setFullScreenHeight] = useState(0); // Set the wrapper height on load, whenever the grid wrapper resizes, and whenever rowCount changes diff --git a/src/components/datagrid/utils/ref.spec.tsx b/src/components/datagrid/utils/ref.spec.tsx index d4fb589a4bc..a9e6fc22123 100644 --- a/src/components/datagrid/utils/ref.spec.tsx +++ b/src/components/datagrid/utils/ref.spec.tsx @@ -65,7 +65,7 @@ describe('useImperativeGridRef', () => { }); describe('setIsFullScreen', () => { - it('allows the consumer to manually toggle full screen mode', () => { + it('allows the consumer to manually toggle fullscreen mode', () => { ref.current.setIsFullScreen(true); cy.get('[data-test-subj="euiDataGrid"]').should( 'have.class', diff --git a/src/components/image/__snapshots__/image.test.tsx.snap b/src/components/image/__snapshots__/image.test.tsx.snap index 73854978772..f62eaa00b62 100644 --- a/src/components/image/__snapshots__/image.test.tsx.snap +++ b/src/components/image/__snapshots__/image.test.tsx.snap @@ -14,12 +14,12 @@ exports[`EuiImage is rendered 1`] = ` `; -exports[`EuiImage is rendered and allows full screen 1`] = ` +exports[`EuiImage is rendered and allows fullscreen 1`] = `