diff --git a/CHANGELOG.md b/CHANGELOG.md index 7cfebdaca1e..2875cb088c7 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,6 +1,7 @@ ## [`master`](https://github.com/elastic/eui/tree/master) -No public interface changes since `40.1.0`. +- Added `EuiAutoSizer` component for setting dimensions on virtualized lists ([#5278](https://github.com/elastic/eui/pull/5278)) +- Added `testenv` mock for `EuiAutoSizer` ([#5278](https://github.com/elastic/eui/pull/5278)) ## [`40.1.0`](https://github.com/elastic/eui/tree/v40.1.0) diff --git a/scripts/babel/react-docgen-typescript.js b/scripts/babel/react-docgen-typescript.js index e241e06035e..28998f8f684 100644 --- a/scripts/babel/react-docgen-typescript.js +++ b/scripts/babel/react-docgen-typescript.js @@ -63,6 +63,7 @@ module.exports = function ({ types }) { // external modules whose props must be whitelisted const whiteListedParent = [ + 'AutoSizerProps', 'DragDropContextProps', 'DraggableProps', 'DroppableProps', diff --git a/scripts/jest/setup/mocks.js b/scripts/jest/setup/mocks.js index 8a19548f404..40ef676c97e 100644 --- a/scripts/jest/setup/mocks.js +++ b/scripts/jest/setup/mocks.js @@ -1,3 +1,8 @@ +jest.mock('./../../../src/components/auto_sizer', () => { + const { EuiAutoSizer } = require('./../../../src/components/auto_sizer/auto_sizer.testenv'); + return { EuiAutoSizer }; +}); + jest.mock('./../../../src/components/icon', () => { const { EuiIcon } = require('./../../../src/components/icon/icon.testenv'); return { EuiIcon }; diff --git a/src-docs/src/routes.js b/src-docs/src/routes.js index 8a53aa6ba3f..e536b900e17 100644 --- a/src-docs/src/routes.js +++ b/src-docs/src/routes.js @@ -38,6 +38,8 @@ import { AccordionExample } from './views/accordion/accordion_example'; import { AspectRatioExample } from './views/aspect_ratio/aspect_ratio_example'; +import { AutoSizerExample } from './views/auto_sizer/auto_sizer_example'; + import { AvatarExample } from './views/avatar/avatar_example'; import { BadgeExample } from './views/badge/badge_example'; @@ -491,6 +493,7 @@ const navigation = [ name: 'Utilities', items: [ AccessibilityExample, + AutoSizerExample, BeaconExample, ColorExample, ColorPaletteExample, diff --git a/src-docs/src/views/auto_sizer/auto_sizer.tsx b/src-docs/src/views/auto_sizer/auto_sizer.tsx new file mode 100644 index 00000000000..87c053cfc13 --- /dev/null +++ b/src-docs/src/views/auto_sizer/auto_sizer.tsx @@ -0,0 +1,30 @@ +import React from 'react'; +import { css } from '@emotion/react'; + +import { EuiAutoSizer, EuiCode, EuiPanel } from '../../../../src/components'; + +export default () => { + const containerStyles = css` + height: 200px; + width: 100%; + `; + + const panelStyles = css` + position: absolute; + display: flex; + align-items: center; + justify-content: center; + `; + + return ( +
+ + {({ height, width }) => ( + + {`height: ${height}, width: ${width}`} + + )} + +
+ ); +}; diff --git a/src-docs/src/views/auto_sizer/auto_sizer_example.js b/src-docs/src/views/auto_sizer/auto_sizer_example.js new file mode 100644 index 00000000000..d5402a70c6e --- /dev/null +++ b/src-docs/src/views/auto_sizer/auto_sizer_example.js @@ -0,0 +1,42 @@ +import React from 'react'; + +import { GuideSectionTypes } from '../../components'; +import { EuiLink, EuiAutoSizer } from '../../../../src/components'; + +import AutoSizer from './auto_sizer'; +const autoSizerSource = require('!!raw-loader!./auto_sizer'); + +const autoSizerSnippet = ` + {({height, width}) => + () + } +`; + +export const AutoSizerExample = { + title: 'Auto sizer', + sections: [ + { + source: [ + { + type: GuideSectionTypes.JS, + code: autoSizerSource, + }, + ], + text: ( +

+ EuiAutoSizer helps components that use virtualized + rendering and/or require explicit dimensions to fill all available + space in the parent container. See the{' '} + + react-virtualized-auto-sizer + {' '} + documentation as EuiAutoSizer is a passthrough + component for AutoSizer. +

+ ), + props: { EuiAutoSizer }, + demo: , + snippet: autoSizerSnippet, + }, + ], +}; diff --git a/src/components/auto_sizer/auto_sizer.testenv.tsx b/src/components/auto_sizer/auto_sizer.testenv.tsx new file mode 100644 index 00000000000..12d86eaa1f3 --- /dev/null +++ b/src/components/auto_sizer/auto_sizer.testenv.tsx @@ -0,0 +1,21 @@ +/* + * 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'; + +export const EuiAutoSizer = ({ + children, + defaultHeight, + defaultWidth, +}: any) => { + const childrenParams = { + height: defaultHeight ?? 600, + width: defaultWidth ?? 600, + }; + return
{children(childrenParams)}
; +}; diff --git a/src/components/auto_sizer/auto_sizer.tsx b/src/components/auto_sizer/auto_sizer.tsx new file mode 100644 index 00000000000..b1ce97b3f51 --- /dev/null +++ b/src/components/auto_sizer/auto_sizer.tsx @@ -0,0 +1,13 @@ +/* + * 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 AutoSizer, { AutoSizerProps } from 'react-virtualized-auto-sizer'; + +export interface EuiAutoSizerProps extends AutoSizerProps {} + +export class EuiAutoSizer extends AutoSizer {} diff --git a/src/components/auto_sizer/index.ts b/src/components/auto_sizer/index.ts new file mode 100644 index 00000000000..60d0bc66cac --- /dev/null +++ b/src/components/auto_sizer/index.ts @@ -0,0 +1,9 @@ +/* + * 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. + */ + +export { EuiAutoSizer, EuiAutoSizerProps } from './auto_sizer'; diff --git a/src/components/code/__snapshots__/_code_block.test.tsx.snap b/src/components/code/__snapshots__/_code_block.test.tsx.snap index d81ff99f035..87b636f6e33 100644 --- a/src/components/code/__snapshots__/_code_block.test.tsx.snap +++ b/src/components/code/__snapshots__/_code_block.test.tsx.snap @@ -79,8 +79,33 @@ exports[`EuiCodeBlockImpl block renders a virtualized code block 1`] = ` style="max-height:300px" >
+ data-eui="EuiAutoSizer" + > +
+      
+        
+          var some = 'code';
+
+        
+        
+          console.log(some);
+        
+      
+    
+
diff --git a/src/components/code/__snapshots__/code_block.test.tsx.snap b/src/components/code/__snapshots__/code_block.test.tsx.snap index 2d52ec41355..159dfe7daaf 100644 --- a/src/components/code/__snapshots__/code_block.test.tsx.snap +++ b/src/components/code/__snapshots__/code_block.test.tsx.snap @@ -6,8 +6,33 @@ exports[`EuiCodeBlock dynamic content renders a virtualized code block 1`] = ` style="height:50%" >
+ data-eui="EuiAutoSizer" + > +
+      
+        
+          var some = 'code';
+
+        
+        
+          console.log(some);
+        
+      
+    
+
diff --git a/src/components/code/_code_block.tsx b/src/components/code/_code_block.tsx index f4065d4e73e..672ab627062 100644 --- a/src/components/code/_code_block.tsx +++ b/src/components/code/_code_block.tsx @@ -22,8 +22,8 @@ import React, { import classNames from 'classnames'; import { highlight, RefractorNode, listLanguages } from 'refractor'; import { FixedSizeList, ListChildComponentProps } from 'react-window'; -import AutoSizer from 'react-virtualized-auto-sizer'; import { keys, useCombinedRefs } from '../../services'; +import { EuiAutoSizer } from '../auto_sizer'; import { EuiButtonIcon } from '../button'; import { keysOf, CommonProps, ExclusiveUnion } from '../common'; import { EuiCopy } from '../copy'; @@ -394,7 +394,7 @@ export const EuiCodeBlockImpl: FunctionComponent = ({
{isVirtualized ? ( - + {({ height, width }) => ( = ({ {ListRow} )} - + ) : (
                   
@@ -436,7 +436,7 @@ export const EuiCodeBlockImpl: FunctionComponent = ({
   return (
     
{isVirtualized ? ( - + {({ height, width }) => ( = ({ {ListRow} )} - + ) : (
   
+ data-eui="EuiAutoSizer" + > +
+
    +
  • + + + + + Titan + + + +
  • +
  • + + + + + Enceladus + + + +
  • +
  • + + + + + Mimas + + + +
  • +
  • + + + + + Pandora is one of Saturn's moons, named for a Titaness of Greek mythology + + + +
  • +
  • + + + + + Tethys + + + +
  • +
  • + + + + + Hyperion + + + +
  • +
+
+
`; @@ -17,8 +184,194 @@ exports[`EuiSelectableListItem props activeOptionIndex 1`] = ` data-test-subj="test subject string" >
+ data-eui="EuiAutoSizer" + > +
+
    +
  • + + + + + Titan + + + +
  • +
  • + + + + + Enceladus + + + +
  • +
  • + + + + + Mimas + + + + + + +
  • +
  • + + + + + Pandora is one of Saturn's moons, named for a Titaness of Greek mythology + + + +
  • +
  • + + + + + Tethys + + + +
  • +
  • + + + + + Hyperion + + + +
  • +
+
+
`; @@ -28,8 +381,175 @@ exports[`EuiSelectableListItem props allowExclusions 1`] = ` data-test-subj="test subject string" >
+ data-eui="EuiAutoSizer" + > +
+
    +
  • + + + + + Titan + + + +
  • +
  • + + + + + Enceladus + + + +
  • +
  • + + + + + Mimas + + + +
  • +
  • + + + + + Pandora is one of Saturn's moons, named for a Titaness of Greek mythology + + + +
  • +
  • + + + + + Tethys + + + +
  • +
  • + + + + + Hyperion + + + +
  • +
+
+
`; @@ -39,8 +559,175 @@ exports[`EuiSelectableListItem props bordered 1`] = ` data-test-subj="test subject string" >
+ data-eui="EuiAutoSizer" + > +
+
    +
  • + + + + + Titan + + + +
  • +
  • + + + + + Enceladus + + + +
  • +
  • + + + + + Mimas + + + +
  • +
  • + + + + + Pandora is one of Saturn's moons, named for a Titaness of Greek mythology + + + +
  • +
  • + + + + + Tethys + + + +
  • +
  • + + + + + Hyperion + + + +
  • +
+
+
`; @@ -50,8 +737,175 @@ exports[`EuiSelectableListItem props height is forced 1`] = ` data-test-subj="test subject string" >
+ data-eui="EuiAutoSizer" + > +
+
    +
  • + + + + + Titan + + + +
  • +
  • + + + + + Enceladus + + + +
  • +
  • + + + + + Mimas + + + +
  • +
  • + + + + + Pandora is one of Saturn's moons, named for a Titaness of Greek mythology + + + +
  • +
  • + + + + + Tethys + + + +
  • +
  • + + + + + Hyperion + + + +
  • +
+
+
`; @@ -61,8 +915,175 @@ exports[`EuiSelectableListItem props height is full 1`] = ` data-test-subj="test subject string" >
+ data-eui="EuiAutoSizer" + > +
+
    +
  • + + + + + Titan + + + +
  • +
  • + + + + + Enceladus + + + +
  • +
  • + + + + + Mimas + + + +
  • +
  • + + + + + Pandora is one of Saturn's moons, named for a Titaness of Greek mythology + + + +
  • +
  • + + + + + Tethys + + + +
  • +
  • + + + + + Hyperion + + + +
  • +
+
+
`; @@ -72,8 +1093,175 @@ exports[`EuiSelectableListItem props renderOption 1`] = ` data-test-subj="test subject string" >
+ data-eui="EuiAutoSizer" + > +
+
    +
  • + + + + + => Titan + + + +
  • +
  • + + + + + => Enceladus + + + +
  • +
  • + + + + + => Mimas + + + +
  • +
  • + + + + + => Pandora is one of Saturn's moons, named for a Titaness of Greek mythology + + + +
  • +
  • + + + + + => Tethys + + + +
  • +
  • + + + + + => Hyperion + + + +
  • +
+
+
`; @@ -83,8 +1271,175 @@ exports[`EuiSelectableListItem props rowHeight 1`] = ` data-test-subj="test subject string" >
+ data-eui="EuiAutoSizer" + > +
+
    +
  • + + + + + Titan + + + +
  • +
  • + + + + + Enceladus + + + +
  • +
  • + + + + + Mimas + + + +
  • +
  • + + + + + Pandora is one of Saturn's moons, named for a Titaness of Greek mythology + + + +
  • +
  • + + + + + Tethys + + + +
  • +
  • + + + + + Hyperion + + + +
  • +
+
+
`; @@ -94,8 +1449,180 @@ exports[`EuiSelectableListItem props searchValue 1`] = ` data-test-subj="test subject string" >
+ data-eui="EuiAutoSizer" + > +
+
    +
  • + + + + + Titan + + + +
  • +
  • + + + + + Enceladus + + + +
  • +
  • + + + + + + Mi + + mas + + + +
  • +
  • + + + + + Pandora is one of Saturn's moons, named for a Titaness of Greek mythology + + + +
  • +
  • + + + + + Tethys + + + +
  • +
  • + + + + + Hyperion + + + +
  • +
+
+
`; @@ -105,8 +1632,180 @@ exports[`EuiSelectableListItem props searchValue 2`] = ` data-test-subj="test subject string" >
+ data-eui="EuiAutoSizer" + > +
+
    +
  • + + + + + Titan + + + +
  • +
  • + + + + + Enceladus + + + +
  • +
  • + + + + + + Mi + + mas + + + +
  • +
  • + + + + + Pandora is one of Saturn's moons, named for a Titaness of Greek mythology + + + +
  • +
  • + + + + + Tethys + + + +
  • +
  • + + + + + Hyperion + + + +
  • +
+
+
`; @@ -116,8 +1815,151 @@ exports[`EuiSelectableListItem props showIcons can be turned off 1`] = ` data-test-subj="test subject string" >
+ data-eui="EuiAutoSizer" + > +
+
    +
  • + + + + Titan + + + +
  • +
  • + + + + Enceladus + + + +
  • +
  • + + + + Mimas + + + +
  • +
  • + + + + Pandora is one of Saturn's moons, named for a Titaness of Greek mythology + + + +
  • +
  • + + + + Tethys + + + +
  • +
  • + + + + Hyperion + + + +
  • +
+
+
`; @@ -127,8 +1969,175 @@ exports[`EuiSelectableListItem props singleSelection can be forced so that at le data-test-subj="test subject string" >
+ data-eui="EuiAutoSizer" + > +
+
    +
  • + + + + + Titan + + + +
  • +
  • + + + + + Enceladus + + + +
  • +
  • + + + + + Mimas + + + +
  • +
  • + + + + + Pandora is one of Saturn's moons, named for a Titaness of Greek mythology + + + +
  • +
  • + + + + + Tethys + + + +
  • +
  • + + + + + Hyperion + + + +
  • +
+
+
`; @@ -138,8 +2147,175 @@ exports[`EuiSelectableListItem props singleSelection can be turned on 1`] = ` data-test-subj="test subject string" >
+ data-eui="EuiAutoSizer" + > +
+
    +
  • + + + + + Titan + + + +
  • +
  • + + + + + Enceladus + + + +
  • +
  • + + + + + Mimas + + + +
  • +
  • + + + + + Pandora is one of Saturn's moons, named for a Titaness of Greek mythology + + + +
  • +
  • + + + + + Tethys + + + +
  • +
  • + + + + + Hyperion + + + +
  • +
+
+
`; @@ -149,7 +2325,121 @@ exports[`EuiSelectableListItem props visibleOptions 1`] = ` data-test-subj="test subject string" >
+ data-eui="EuiAutoSizer" + > +
+
    +
  • + + + + + Mimas + + + +
  • +
  • + + + + + Pandora is one of Saturn's moons, named for a Titaness of Greek mythology + + + +
  • +
  • + + + + + Tethys + + + +
  • +
  • + + + + + Hyperion + + + +
  • +
+
+
`; diff --git a/src/components/selectable/selectable_list/selectable_list.tsx b/src/components/selectable/selectable_list/selectable_list.tsx index 6c6d41276d1..a4cd93b029c 100644 --- a/src/components/selectable/selectable_list/selectable_list.tsx +++ b/src/components/selectable/selectable_list/selectable_list.tsx @@ -8,20 +8,20 @@ import React, { Component, HTMLAttributes, ReactNode, memo } from 'react'; import classNames from 'classnames'; -import { CommonProps } from '../../common'; -import { - EuiSelectableListItem, - EuiSelectableListItemProps, -} from './selectable_list_item'; -import { EuiHighlight } from '../../highlight'; -import { EuiSelectableOption } from '../selectable_option'; -import AutoSizer from 'react-virtualized-auto-sizer'; import { FixedSizeList, ListProps, ListChildComponentProps as ReactWindowListChildComponentProps, areEqual, } from 'react-window'; +import { CommonProps } from '../../common'; +import { EuiAutoSizer } from '../../auto_sizer'; +import { EuiHighlight } from '../../highlight'; +import { EuiSelectableOption } from '../selectable_option'; +import { + EuiSelectableListItem, + EuiSelectableListItemProps, +} from './selectable_list_item'; interface ListChildComponentProps extends ReactWindowListChildComponentProps { @@ -310,7 +310,7 @@ export class EuiSelectableList extends Component> { return (
- + {({ width, height }) => ( extends Component> { {this.ListRow} )} - +
); }