Skip to content

Commit

Permalink
Add EUI error messaging + styling to playground errors (elastic#6464)
Browse files Browse the repository at this point in the history
  • Loading branch information
Cee authored Dec 8, 2022
1 parent 46ec00f commit a6f24d1
Show file tree
Hide file tree
Showing 2 changed files with 52 additions and 37 deletions.
13 changes: 12 additions & 1 deletion src-docs/src/services/playground/playground.js
Original file line number Diff line number Diff line change
Expand Up @@ -5,12 +5,15 @@ import format from 'html-format';
import { useView, Compiler, Placeholder } from 'react-view';
import {
EuiCodeBlock,
EuiErrorBoundary,
EuiFlyoutBody,
EuiFlyoutHeader,
EuiPanel,
useEuiTheme,
} from '../../../../src';
import {
EuiErrorMessage,
EuiErrorBoundary,
} from '../../../../src/components/error_boundary/error_boundary';
import Knobs from './knobs';
import { GuideSectionPropsDescription } from '../../components/guide_section/guide_section_parts/guide_section_props_description';

Expand Down Expand Up @@ -68,6 +71,10 @@ export default ({
}
}, [params.knobProps]);

// react-view swallows errors thrown in the Compiler, so we need to grab
// them via errorProps and pass them to our own EUI component
const thrownError = params.errorProps.msg; // string or null

return (
<>
<EuiFlyoutHeader hasBorder>
Expand All @@ -86,13 +93,17 @@ export default ({
guideDemo__ghostBackground: isGhost,
})}
{...playgroundPanelProps}
paddingSize={
thrownError ? 'none' : playgroundPanelProps?.paddingSize
}
>
<Compiler
css={playgroundCssStyles?.(euiTheme)}
{...params.compilerProps}
placeholder={Placeholder}
className={classNames('playground__demo', playgroundClassName)}
/>
{thrownError && <EuiErrorMessage errorMessage={thrownError} />}
</EuiPanel>
</EuiFlyoutHeader>
<EuiFlyoutHeader className="playground__codeWrapper" hasBorder>
Expand Down
76 changes: 40 additions & 36 deletions src/components/error_boundary/error_boundary.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -6,14 +6,19 @@
* Side Public License, v 1.
*/

import React, { Component, HTMLAttributes, ReactNode } from 'react';
import React, {
Component,
FunctionComponent,
HTMLAttributes,
ReactNode,
} from 'react';
import classNames from 'classnames';
import { CommonProps } from '../common';

import { EuiTitle } from '../title';
import { EuiCodeBlock } from '../code';
import { EuiI18n } from '../i18n';
import { withEuiTheme, WithEuiThemeProps } from '../../services';
import { useEuiTheme } from '../../services';

import { euiErrorBoundaryStyles } from './error_boundary.styles';

Expand All @@ -30,13 +35,11 @@ export type EuiErrorBoundaryProps = CommonProps &
children: ReactNode;
};

type EuiErrorBoundaryExtendedProps = EuiErrorBoundaryProps & WithEuiThemeProps;

export class _EuiErrorBoundary extends Component<
EuiErrorBoundaryExtendedProps,
export class EuiErrorBoundary extends Component<
EuiErrorBoundaryProps,
EuiErrorBoundaryState
> {
constructor(props: EuiErrorBoundaryExtendedProps) {
constructor(props: EuiErrorBoundaryProps) {
super(props);

const errorState: EuiErrorBoundaryState = {
Expand All @@ -62,41 +65,42 @@ ${stackStr}`;
}

render() {
const {
className,
children,
'data-test-subj': _dataTestSubj,
theme,
...rest
} = this.props;
const dataTestSubj = classNames('euiErrorBoundary', _dataTestSubj);
const styles = euiErrorBoundaryStyles(theme);
const { children, ...rest } = this.props;

if (this.state.hasError) {
// You can render any custom fallback UI
return (
<div
css={styles.euiErrorBoundary}
className={classNames('euiErrorBoundary', className)}
data-test-subj={dataTestSubj}
{...rest}
>
<EuiCodeBlock>
<EuiTitle size="xs">
<p>
<EuiI18n token="euiErrorBoundary.error" default="Error" />
</p>
</EuiTitle>
{this.state.error}
</EuiCodeBlock>
</div>
);
return <EuiErrorMessage {...rest} errorMessage={this.state.error} />;
}

return children;
}
}

export const EuiErrorBoundary = withEuiTheme<EuiErrorBoundaryProps>(
_EuiErrorBoundary
);
/**
* Split out into a separate styling-only component for easier use of hooks,
* and also for internal re-use by EUI's docs/playgrounds
*/
export const EuiErrorMessage: FunctionComponent<
CommonProps & { errorMessage?: string }
> = ({ errorMessage, className, 'data-test-subj': dataTestSubj, ...rest }) => {
const euiTheme = useEuiTheme();
const styles = euiErrorBoundaryStyles(euiTheme);

return (
<div
css={styles.euiErrorBoundary}
className={classNames('euiErrorBoundary', className)}
data-test-subj={classNames('euiErrorBoundary', dataTestSubj)}
{...rest}
>
<EuiCodeBlock>
<EuiTitle size="xs">
<p>
<EuiI18n token="euiErrorBoundary.error" default="Error" />
</p>
</EuiTitle>
{errorMessage}
</EuiCodeBlock>
</div>
);
};

0 comments on commit a6f24d1

Please sign in to comment.