Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Added side property to 'EuiGlobalToastList' #3600

Merged
merged 8 commits into from
Jun 15, 2020
Merged
Show file tree
Hide file tree
Changes from all 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 CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@
- Added `BREAKPOINTS` and `getBreakpoint` utilities [#3578](https://github.com/elastic/eui/pull/3578))
- Added `'any'` option to the `step` prop of the `EuiFieldNumber` ([#3562](https://github.com/elastic/eui/pull/3562))
- Moved all `EuiHeader` SASS variables to `global_styles` ([#3592](https://github.com/elastic/eui/pull/3592))
- Added `side` prop to `EuiGlobalToastList` for choosing which window side to display toasts ([#3600](https://github.com/elastic/eui/pull/3600))
- Default `titleSize` get's implicitly set to 'm' for `EuiEmptyPrompt` ([#3598](https://github.com/elastic/eui/pull/3598))

**Bug fixes**
Expand Down
99 changes: 97 additions & 2 deletions src/components/toast/__snapshots__/global_toast_list.test.tsx.snap
Original file line number Diff line number Diff line change
Expand Up @@ -4,16 +4,111 @@ exports[`EuiGlobalToastList is rendered 1`] = `
<div
aria-label="aria-label"
aria-live="polite"
class="euiGlobalToastList testClass1 testClass2"
class="euiGlobalToastList euiGlobalToastList--right testClass1 testClass2"
data-test-subj="test subject string"
role="region"
/>
`;

exports[`EuiGlobalToastList props side can be changed to left 1`] = `
<div
aria-live="polite"
class="euiGlobalToastList euiGlobalToastList--left"
role="region"
>
<div
class="euiToast euiToast--success euiGlobalToastListItem"
data-test-subj="a"
id="a"
>
<p
class="euiScreenReaderOnly"
>
A new notification appears
</p>
<div
aria-label="Notification"
class="euiToastHeader euiToastHeader--withBody"
data-test-subj="euiToastHeader"
>
<div
aria-hidden="true"
class="euiToastHeader__icon"
data-euiicon-type="check"
/>
<span
class="euiToastHeader__title"
>
A
</span>
</div>
<button
aria-label="Dismiss toast"
class="euiToast__closeButton"
data-test-subj="toastCloseButton"
type="button"
>
<div
aria-hidden="true"
data-euiicon-type="cross"
/>
</button>
<div
class="euiText euiText--small euiToastBody"
>
a
</div>
</div>
<div
class="euiToast euiToast--danger euiGlobalToastListItem"
data-test-subj="b"
id="b"
>
<p
class="euiScreenReaderOnly"
>
A new notification appears
</p>
<div
aria-label="Notification"
class="euiToastHeader euiToastHeader--withBody"
data-test-subj="euiToastHeader"
>
<div
aria-hidden="true"
class="euiToastHeader__icon"
data-euiicon-type="alert"
/>
<span
class="euiToastHeader__title"
>
B
</span>
</div>
<button
aria-label="Dismiss toast"
class="euiToast__closeButton"
data-test-subj="toastCloseButton"
type="button"
>
<div
aria-hidden="true"
data-euiicon-type="cross"
/>
</button>
<div
class="euiText euiText--small euiToastBody"
>
b
</div>
</div>
</div>
`;

exports[`EuiGlobalToastList props toasts is rendered 1`] = `
<div
aria-live="polite"
class="euiGlobalToastList"
class="euiGlobalToastList euiGlobalToastList--right"
role="region"
>
<div
Expand Down
45 changes: 34 additions & 11 deletions src/components/toast/_global_toast_list.scss
Original file line number Diff line number Diff line change
@@ -1,31 +1,49 @@
/**
* 1. Allow list to expand as items are added, but cap it at the screen height.
* 2. Only show the scroll on hover. Generally, scrolling is bad for toasts.
* 3. Allow some padding if a scroll shows up.
* 2. Allow some padding for shadow
*/
.euiGlobalToastList {
@include euiScrollBar;

display: flex;
flex-direction: column;
align-items: stretch;
position: fixed;
z-index: $euiZToastList;
bottom: 0;
right: 0;
width: $euiToastWidth + $euiSize + $euiSizeXL; /* 3 */
padding-right: $euiSize;
padding-left: $euiSizeXL;
width: $euiToastWidth + ($euiSize * 5); /* 2 */
max-height: 100vh; /* 1 */
overflow-y: auto;

// Hide the scrollbar entirely
// sass-lint:disable-block no-misspelled-properties
scrollbar-width: none;

&:hover {
overflow-y: auto; /* 2 */
// sass-lint:disable-block no-vendor-prefixes
&::-webkit-scrollbar {
width: 0;
height: 0;
}

// The top and bottom padding give heighto to the list creating a dead-zone effect
// when there's no toasts in the list, meaning you can't click anything beneath it.
// Only add the padding if there's content.
&:not(:empty) {
padding: $euiSize;
}
}

.euiGlobalToastList--right:not(:empty) {
right: 0;
padding-left: $euiSize * 4; /* 2 */
}

.euiGlobalToastList--left:not(:empty) {
left: 0;
padding-right: $euiSize * 4; /* 2 */
}

.euiGlobalToastListItem {
margin-bottom: $euiSize;
margin-right: $euiSize;
animation: $euiAnimSpeedNormal euiShowToast $euiAnimSlightResistance;
opacity: 1;

Expand All @@ -37,6 +55,10 @@
margin-top: auto; /* 1 */
}

&:last-child {
margin-bottom: 0;
}

&.euiGlobalToastListItem-isDismissed {
transition: opacity $euiAnimSpeedNormal;
opacity: 0;
Expand All @@ -59,9 +81,10 @@
/**
* 1. Mobile we make these 100%. Matching change happens on the item as well.
*/
.euiGlobalToastList {
.euiGlobalToastList:not(:empty) {
left: 0;
padding-left: $euiSize;
padding-right: $euiSize;
width: 100%; /* 1 */
}
}
33 changes: 33 additions & 0 deletions src/components/toast/global_toast_list.test.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -76,6 +76,39 @@ describe('EuiGlobalToastList', () => {
});
});

describe('side', () => {
test('can be changed to left', () => {
const toasts: Toast[] = [
{
title: 'A',
text: 'a',
color: 'success',
iconType: 'check',
'data-test-subj': 'a',
id: 'a',
},
{
title: 'B',
text: 'b',
color: 'danger',
iconType: 'alert',
'data-test-subj': 'b',
id: 'b',
},
];

const component = render(
<EuiGlobalToastList
toasts={toasts}
dismissToast={() => {}}
toastLifeTimeMs={5}
side="left"
/>
);
expect(component).toMatchSnapshot();
});
});

describe('dismissToast', () => {
test('is called when a toast is clicked', () => {
const dismissToastSpy = jest.fn();
Expand Down
24 changes: 21 additions & 3 deletions src/components/toast/global_toast_list.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -20,11 +20,20 @@
import React, { Component, ReactChild } from 'react';
import classNames from 'classnames';

import { CommonProps } from '../common';
import { CommonProps, keysOf } from '../common';
import { Timer } from '../../services/time';
import { EuiGlobalToastListItem } from './global_toast_list_item';
import { EuiToast, EuiToastProps } from './toast';

type ToastSide = 'right' | 'left';

const sideToClassNameMap: { [side in ToastSide]: string } = {
left: 'euiGlobalToastList--left',
right: 'euiGlobalToastList--right',
};

export const SIDES = keysOf(sideToClassNameMap);
cchaos marked this conversation as resolved.
Show resolved Hide resolved

export const TOAST_FADE_OUT_MS = 250;

export interface Toast extends EuiToastProps {
Expand All @@ -37,6 +46,10 @@ export interface EuiGlobalToastListProps extends CommonProps {
toasts: Toast[];
dismissToast: (this: EuiGlobalToastList, toast: Toast) => void;
toastLifeTimeMs: number;
/**
* Determines which side of the browser window the toasts should appear
*/
side?: ToastSide;
}

interface State {
Expand Down Expand Up @@ -69,6 +82,7 @@ export class EuiGlobalToastList extends Component<

static defaultProps = {
toasts: [],
side: 'right',
};

startScrollingToBottom() {
Expand Down Expand Up @@ -247,6 +261,7 @@ export class EuiGlobalToastList extends Component<
toasts,
dismissToast,
toastLifeTimeMs,
side,
...rest
} = this.props;

Expand All @@ -267,8 +282,11 @@ export class EuiGlobalToastList extends Component<
</EuiGlobalToastListItem>
);
});

const classes = classNames('euiGlobalToastList', className);
const classes = classNames(
'euiGlobalToastList',
side ? sideToClassNameMap[side] : null,
className
);

return (
<div
Expand Down