Skip to content

Commit

Permalink
Add dismissible prop to OuiCallOut (#985)
Browse files Browse the repository at this point in the history
* add dismissible prop to OuiCallOut

Signed-off-by: abbyhu2000 <[email protected]>

* changelog

Signed-off-by: abbyhu2000 <[email protected]>

* fix some nits

Signed-off-by: abbyhu2000 <[email protected]>

* change size to oui size

Signed-off-by: abbyhu2000 <[email protected]>

* no state management in oui

Signed-off-by: abbyhu2000 <[email protected]>

---------

Signed-off-by: abbyhu2000 <[email protected]>
(cherry picked from commit 53ad3e7)
Signed-off-by: github-actions[bot] <github-actions[bot]@users.noreply.github.com>

# Conflicts:
#	CHANGELOG.md
  • Loading branch information
github-actions[bot] committed Aug 29, 2023
1 parent 3dc2f2e commit e02efcc
Show file tree
Hide file tree
Showing 5 changed files with 221 additions and 37 deletions.
95 changes: 59 additions & 36 deletions src-docs/src/views/call_out/info.js
Original file line number Diff line number Diff line change
Expand Up @@ -9,42 +9,65 @@
* GitHub history for details.
*/

import React from 'react';
import React, { useState } from 'react';

import { OuiCallOut, OuiLink, OuiSpacer } from '../../../../src/components';

export default () => (
<div>
<OuiCallOut
title="Check it out, here's a really long title that will wrap within a narrower browser"
iconType="search">
<p>
Here&rsquo;s some stuff that you need to know. We can make this text
really long so that, when viewed within a browser that&rsquo;s fairly
narrow, it will wrap, too.
</p>
<p>
When possible, its recommended to include links to product{' '}
<OuiLink href="https://opensearch.org/docs/latest/">
documentation
</OuiLink>
.
</p>
</OuiCallOut>

<OuiSpacer size="m" />

<OuiCallOut
title="Callouts can exist as just a title. Simply omit the child content."
iconType="visVisualBuilder"
/>

<OuiSpacer size="m" />

<OuiCallOut
size="s"
title="This is a small callout for more unintrusive but constant messages."
iconType="pin"
/>
</div>
);
export default () => {
const [isCallOutVisible, setIsCallOutVisible] = useState(true);

const closeCallOut = () => setIsCallOutVisible(false);

let callOut;

if (isCallOutVisible) {
callOut = (
<OuiCallOut
title="Callouts can be dismissed when dismissible is set to true unless the color is danger or warning. "
iconType="wrench"
dismissible
onDismissible={closeCallOut}
/>
);
}

return (
<div>
<OuiCallOut
title="Check it out, here's a really long title that will wrap within a narrower browser"
iconType="search">
<p>
Here&rsquo;s some stuff that you need to know. We can make this text
really long so that, when viewed within a browser that&rsquo;s fairly
narrow, it will wrap, too.
</p>
<p>
When possible, its recommended to include links to product{' '}
<OuiLink href="https://opensearch.org/docs/latest/">
documentation
</OuiLink>
.
</p>
</OuiCallOut>

<OuiSpacer size="m" />

<OuiCallOut
title="Callouts can exist as just a title. Simply omit the child content."
iconType="visVisualBuilder"
/>

<OuiSpacer size="m" />

{callOut}

<OuiSpacer size="m" />

<OuiCallOut
size="s"
title="This is a small callout for more unintrusive but constant messages."
iconType="pin"
/>
</div>
);
};
86 changes: 86 additions & 0 deletions src/components/call_out/__snapshots__/call_out.test.tsx.snap
Original file line number Diff line number Diff line change
Expand Up @@ -42,6 +42,92 @@ exports[`OuiCallOut props color warning is rendered 1`] = `
/>
`;

exports[`OuiCallOut props dismissible close callout after click 1`] = `
<OuiCallOut
dismissible={true}
onDismissible={[MockFunction]}
title="This is a callout"
>
<div
className="ouiCallOut ouiCallOut--primary"
>
<div
className="ouiCallOutHeader"
>
<span
className="ouiCallOutHeader__title"
>
This is a callout
</span>
</div>
<OuiButtonIcon
aria-label="dismissible_icon"
className="ouiCallOut__closeIcon"
data-test-subj="closeCallOutButton"
iconType="cross"
onClick={[MockFunction]}
>
<button
aria-label="dismissible_icon"
className="ouiButtonIcon ouiButtonIcon--primary ouiButtonIcon--empty ouiButtonIcon--xSmall ouiCallOut__closeIcon"
data-test-subj="closeCallOutButton"
disabled={false}
onClick={[MockFunction]}
type="button"
>
<OuiIcon
aria-hidden="true"
className="ouiButtonIcon__icon"
color="inherit"
size="m"
type="cross"
>
<span
aria-hidden="true"
className="ouiButtonIcon__icon"
color="inherit"
data-ouiicon-type="cross"
size="m"
/>
</OuiIcon>
</button>
</OuiButtonIcon>
</div>
</OuiCallOut>
`;

exports[`OuiCallOut props dismissible is not rendered when in danger color 1`] = `
<div
class="ouiCallOut ouiCallOut--danger"
/>
`;

exports[`OuiCallOut props dismissible is not rendered when in warning color 1`] = `
<div
class="ouiCallOut ouiCallOut--warning"
/>
`;

exports[`OuiCallOut props dismissible is rendered when set to true 1`] = `
<div
class="ouiCallOut ouiCallOut--primary"
>
<button
aria-label="dismissible_icon"
class="ouiButtonIcon ouiButtonIcon--primary ouiButtonIcon--empty ouiButtonIcon--xSmall ouiCallOut__closeIcon"
data-test-subj="closeCallOutButton"
type="button"
>
<span
aria-hidden="true"
class="ouiButtonIcon__icon"
color="inherit"
data-ouiicon-type="cross"
/>
</button>
</div>
`;

exports[`OuiCallOut props heading h1 is rendered 1`] = `
<div
class="ouiCallOut ouiCallOut--primary"
Expand Down
11 changes: 11 additions & 0 deletions src/components/call_out/_call_out.scss
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,7 @@
.ouiCallOut {
padding: $ouiSize;
border-left: $ouiSizeXS / 2 solid transparent;
position: relative;

&.ouiCallOut--small {
padding: $ouiSizeS;
Expand All @@ -27,6 +28,12 @@
@include ouiCallOutTitle;
margin-bottom: 0; // In case it's nested inside OuiText
}

.ouiCallOut__closeIcon {
position: absolute;
right: $ouiSizeS / 2;
top: 0;
}
}

// smaller font size for headers in small callout
Expand All @@ -47,6 +54,10 @@
.ouiCallOutHeader__title {
color: ouiCallOutColor($name, 'foreground');
}

.ouiCallOut__closeIcon {
fill: ouiCallOutColor($name, 'foreground');
}
}
}

Expand Down
41 changes: 40 additions & 1 deletion src/components/call_out/call_out.test.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -29,10 +29,11 @@
*/

import React from 'react';
import { render } from 'enzyme';
import { mount, render } from 'enzyme';
import { requiredProps } from '../../test/required_props';

import { OuiCallOut, COLORS, HEADINGS } from './call_out';
import { findTestSubject } from '../../test';

describe('OuiCallOut', () => {
test('is rendered', () => {
Expand Down Expand Up @@ -81,5 +82,43 @@ describe('OuiCallOut', () => {
});
});
});

describe('dismissible', () => {
it('is rendered when set to true', () => {
const component = render(<OuiCallOut dismissible={true} />);

expect(component).toMatchSnapshot();
});

it('is not rendered when in warning color', () => {
const component = render(
<OuiCallOut dismissible={true} color={'warning'} />
);

expect(component).toMatchSnapshot();
});

it('is not rendered when in danger color', () => {
const component = render(
<OuiCallOut dismissible={true} color={'danger'} />
);

expect(component).toMatchSnapshot();
});

it('close callout after click', () => {
const onDismissible = jest.fn();
const component = mount(
<OuiCallOut
dismissible={true}
onDismissible={onDismissible}
title="This is a callout"
/>
);
expect(component).toMatchSnapshot();
findTestSubject(component, 'closeCallOutButton').simulate('click');
expect(onDismissible).toBeCalled();
});
});
});
});
25 changes: 25 additions & 0 deletions src/components/call_out/call_out.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -36,6 +36,7 @@ import { CommonProps, keysOf } from '../common';
import { IconType, OuiIcon } from '../icon';

import { OuiText } from '../text';
import { OuiButtonIcon } from '../button';

type Color = 'primary' | 'success' | 'warning' | 'danger';
type Size = 's' | 'm';
Expand All @@ -48,6 +49,12 @@ export type OuiCallOutProps = CommonProps &
color?: Color;
size?: Size;
heading?: Heading;
dismissible?: boolean;
onDismissible?: (
event?:
| React.KeyboardEvent<HTMLDivElement>
| React.MouseEvent<HTMLButtonElement>
) => void;
};

const colorToClassNameMap: { [color in Color]: string } = {
Expand Down Expand Up @@ -75,6 +82,8 @@ export const OuiCallOut = forwardRef<HTMLDivElement, OuiCallOutProps>(
children,
className,
heading,
dismissible = false,
onDismissible = () => {},
...rest
},
ref: Ref<HTMLDivElement>
Expand All @@ -100,6 +109,19 @@ export const OuiCallOut = forwardRef<HTMLDivElement, OuiCallOutProps>(
);
}

let dismissibleIcon;
if (dismissible && color !== 'warning' && color !== 'danger') {
dismissibleIcon = (
<OuiButtonIcon
iconType="cross"
onClick={onDismissible}
className="ouiCallOut__closeIcon"
aria-label="dismissible_icon"
data-test-subj="closeCallOutButton"
/>
);
}

let optionalChildren;
if (children && size === 's') {
optionalChildren = (
Expand All @@ -126,10 +148,13 @@ export const OuiCallOut = forwardRef<HTMLDivElement, OuiCallOutProps>(
</div>
);
}

return (
<div className={classes} ref={ref} {...rest}>
{header}

{dismissibleIcon}

{optionalChildren}
</div>
);
Expand Down

0 comments on commit e02efcc

Please sign in to comment.