Skip to content
Merged
Show file tree
Hide file tree
Changes from 7 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 packages/eui/changelogs/upcoming/9228.md
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
- Updated `EuiFlexItem` to fall back to `grow={true}` if invalid values for `grow` are passed
28 changes: 16 additions & 12 deletions packages/eui/src/components/flex/flex_item.test.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -12,13 +12,10 @@ import {
startThrowingReactWarnings,
stopThrowingReactWarnings,
} from '../../test';
import {
shouldRenderCustomStyles,
testOnReactVersion,
} from '../../test/internal';
import { shouldRenderCustomStyles } from '../../test/internal';
import { render } from '../../test/rtl';

import { EuiFlexItem } from './flex_item';
import { EuiFlexItem, EuiFlexItemProps } from './flex_item';

beforeAll(startThrowingReactWarnings);
afterAll(stopThrowingReactWarnings);
Expand Down Expand Up @@ -94,13 +91,20 @@ describe('EuiFlexItem', () => {
});
});

// React 18 throws a false error on test unmount for components w/ ref callbacks
// that throw in a `useEffect`. Note: This only affects the test env, not prod
// @see https://github.com/facebook/react/issues/25675#issuecomment-1363957941
// TODO: Remove `testOnReactVersion` once the above bug is fixed
testOnReactVersion('17')(`invalid component types throw an error`, () => {
// @ts-expect-error intentionally passing an invalid value
expect(() => render(<EuiFlexItem grow={11} />)).toThrow();
describe('invalid values', () => {
const INVALID_VALUES = [
(3 / 0) as EuiFlexItemProps['grow'],
Infinity as EuiFlexItemProps['grow'],
-Infinity as EuiFlexItemProps['grow'],
11 as EuiFlexItemProps['grow'],
];

INVALID_VALUES.forEach((value) => {
test(`${value} generates a flex-grow of the default value \`true\``, () => {
render(<EuiFlexItem grow={value} />);
assertClassName('grow-1');
});
});
});
});
});
22 changes: 16 additions & 6 deletions packages/eui/src/components/flex/flex_item.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,7 @@ import React, {
Ref,
ReactElement,
FunctionComponent,
useState,
} from 'react';
import classNames from 'classnames';
import { CommonProps } from '../common';
Expand Down Expand Up @@ -69,19 +70,28 @@ const EuiFlexItemInternal = <TComponent extends ElementType>(
{
children,
className,
grow = true,
grow: _grow = true,
component = 'div' as TComponent,
...rest
}: EuiFlexItemProps<TComponent>,
ref: ForwardedRef<TComponent>
): ReactElement<EuiFlexItemProps<TComponent>, TComponent> => {
const [grow, setGrow] = useState(_grow);
Comment thread
mgadewoll marked this conversation as resolved.
Outdated
Comment thread
mgadewoll marked this conversation as resolved.
Outdated

useEffect(() => {
if (VALID_GROW_VALUES.indexOf(grow) === -1) {
throw new Error(
`Prop \`grow\` passed to \`EuiFlexItem\` must be a boolean or an integer between 0 and 10, received \`${grow}\``
);
if (VALID_GROW_VALUES.indexOf(_grow) === -1) {
if (process.env.NODE_ENV === 'development') {
console.warn(
`Prop \`grow\` passed to \`EuiFlexItem\` must be a boolean or an integer between 0 and 10, received \`${_grow}\`. Defaulting to \`true\`.`
);
}

// reset `grow` to the default value when the passed value is invalid
setGrow(true);
} else {
setGrow(_grow);
}
}, [grow]);
}, [_grow]);

const cssStyles = [
styles.euiFlexItem,
Expand Down