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

Improve EuiGlobalToastList #370

Merged
merged 3 commits into from
Feb 7, 2018
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
8 changes: 7 additions & 1 deletion CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -1,11 +1,17 @@
# [`master`](https://github.com/elastic/eui/tree/master)

- `EuiGlobalToastList` now prevents toasts from disappearing while the user's mouse is over the list. Added `timer/Timer` service ([#370](https://github.com/elastic/eui/pull/370))

**Bug fixes**

- `EuiTableOfRecords` selection bugs ([#365](https://github.com/elastic/eui/pull/365))
- Deleting selected items now resets the select all checkbox to an unchecked state
- The select all checkbox only becomes checked when all selectable rows are checked, not just some of them

**Breaking changes**

- Changed `EuiGlobalToastList` to be responsible for instantiating toasts, tracking their lifetimes, and dismissing them. It now acepts `toasts`, `dismissToast`, and `toastLifeTimeMs` props. It no longer accepts `children`. ([#370](https://github.com/elastic/eui/pull/370))

# [`0.0.18`](https://github.com/elastic/eui/tree/v0.0.18)

**Bug fixes**
Expand All @@ -21,7 +27,7 @@
# [`0.0.16`](https://github.com/elastic/eui/tree/v0.0.16)

- `EuiRadio` now supports the `input` tag's `name` attribute. `EuiRadioGroup` accepts a `name` prop that will propagate to its `EuiRadio`s. ([#348](https://github.com/elastic/eui/pull/348))
- Machine Learning create jobs icon set. ([#338](https://github.com/elastic/eui/pull/338))
- Added Machine Learning create jobs icon set. ([#338](https://github.com/elastic/eui/pull/338))
- Added `EuiTableOfRecords`, a higher level table component to take away all your table listings frustrations. ([#250](https://github.com/elastic/eui/pull/250))

**Bug fixes**
Expand Down
147 changes: 48 additions & 99 deletions src-docs/src/views/toast/toast_list.js
Original file line number Diff line number Diff line change
@@ -1,22 +1,16 @@
import React, {
cloneElement,
Component,
Fragment,
} from 'react';

import {
EuiGlobalToastList,
EuiGlobalToastListItem,
EuiLink,
EuiToast,
} from '../../../../src/components';

const TOAST_LIFE_TIME_MS = 4000;
const TOAST_FADE_OUT_MS = 250;
let toastIdCounter = 0;
const timeoutIds = [];

let addToastHandler;
let removeAllToastsHandler;
let toastId = 0;

export function addToast() {
addToastHandler();
Expand All @@ -39,130 +33,85 @@ export default class extends Component {
}

addToast = () => {
const {
toast,
toastId,
} = this.renderRandomToast();
const toast = this.getRandomToast();

this.setState({
toasts: this.state.toasts.concat(toast),
});

this.scheduleToastForDismissal(toastId);
};

scheduleToastForDismissal = (toastId, isImmediate = false) => {
const lifeTime = isImmediate ? TOAST_FADE_OUT_MS : TOAST_LIFE_TIME_MS;

timeoutIds.push(setTimeout(() => {
this.dismissToast(toastId);
}, lifeTime));

timeoutIds.push(setTimeout(() => {
this.startDismissingToast(toastId);
}, lifeTime - TOAST_FADE_OUT_MS));
removeToast = (removedToast) => {
this.setState(prevState => ({
toasts: prevState.toasts.filter(toast => toast.id !== removedToast.id),
}));
};

startDismissingToast(toastId) {
this.setState({
toasts: this.state.toasts.map(toast => {
if (toast.key === toastId) {
return cloneElement(toast, {
isDismissed: true,
});
}

return toast;
}),
});
}

dismissToast(toastId) {
this.setState({
toasts: this.state.toasts.filter(toast => toast.key !== toastId),
});
}

removeAllToasts = () => {
this.setState({
toasts: [],
});
};

componentWillUnmount() {
timeoutIds.forEach(timeoutId => clearTimeout(timeoutId));
}

renderRandomToast = () => {
const toastId = (toastIdCounter++).toString();
const dismissToast = () => this.scheduleToastForDismissal(toastId, true);

const toasts = [
(
<EuiToast
title="Check it out, here's a really long title that will wrap within a narrower browser"
onClose={dismissToast}
>
getRandomToast = () => {
const toasts = [{
title: `Check it out, here's a really long title that will wrap within a narrower browser`,
text: (
<Fragment>
<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>
And some other stuff on another line, just for kicks. And <EuiLink href="#">here&rsquo;s a link</EuiLink>.
</p>
</EuiToast>
), (
<EuiToast
title="Download complete!"
color="success"
onClose={dismissToast}
>
<p>
Thanks for your patience!
</p>
</EuiToast>
), (
<EuiToast
title="Logging you out soon, due to inactivity"
color="warning"
iconType="user"
onClose={dismissToast}
>
</Fragment>
),
}, {
title: 'Download complete!',
color: 'success',
text: (
<p>
Thanks for your patience!
</p>
),
}, {
title: 'Logging you out soon, due to inactivity',
color: 'warning',
iconType: 'user',
text: (
<Fragment>
<p>
This is a security measure.
</p>
<p>
Please move your mouse to show that you&rsquo;re still using Kibana.
</p>
</EuiToast>
), (
<EuiToast
title="Oops, there was an error"
color="danger"
iconType="help"
onClose={dismissToast}
>
<p>
Sorry. We&rsquo;ll try not to let it happen it again.
</p>
</EuiToast>
</Fragment>
),
];

const toast = (
<EuiGlobalToastListItem key={toastId}>
{toasts[Math.floor(Math.random() * toasts.length)]}
</EuiGlobalToastListItem>
);
}, {
title: 'Oops, there was an error',
color: 'danger',
iconType: 'help',
text: (
<p>
Sorry. We&rsquo;ll try not to let it happen it again.
</p>
),
}];

return { toast, toastId };
return {
id: toastId++,
...toasts[Math.floor(Math.random() * toasts.length)],
};
};

render() {
return (
<EuiGlobalToastList>
{this.state.toasts}
</EuiGlobalToastList>
<EuiGlobalToastList
toasts={this.state.toasts}
dismissToast={this.removeToast}
toastLifeTimeMs={6000}
/>
);
}
}
139 changes: 137 additions & 2 deletions src/components/toast/__snapshots__/global_toast_list.test.js.snap
Original file line number Diff line number Diff line change
Expand Up @@ -5,9 +5,144 @@ exports[`EuiGlobalToastList is rendered 1`] = `
aria-label="aria-label"
class="euiGlobalToastList testClass1 testClass2"
data-test-subj="test subject string"
/>
`;

exports[`EuiGlobalToastList props toasts is rendered 1`] = `
<div
class="euiGlobalToastList"
>
<div>
hi
<div
class="euiToast euiToast--success euiGlobalToastListItem"
data-test-subj="a"
id="a"
>
<div
class="euiToastHeader euiToastHeader--withBody"
>
<svg
aria-hidden="true"
class="euiIcon euiToastHeader__icon euiIcon--medium"
height="16"
viewBox="0 0 16 16"
width="16"
xlink="http://www.w3.org/1999/xlink"
xmlns="http://www.w3.org/2000/svg"
>
<defs>
<path
d="M6.5 12a.502.502 0 0 1-.354-.146l-4-4a.502.502 0 0 1 .708-.708L6.5 10.793l6.646-6.647a.502.502 0 0 1 .708.708l-7 7A.502.502 0 0 1 6.5 12"
id="check-a"
/>
</defs>
<use
href="#check-a"
/>
</svg>
<span
class="euiToastHeader__title"
>
A
</span>
</div>
<button
aria-label="Dismiss toast"
class="euiToast__closeButton"
data-test-subj="toastCloseButton"
type="button"
>
<svg
aria-hidden="true"
class="euiIcon euiIcon--medium"
height="16"
viewBox="0 0 16 16"
width="16"
xlink="http://www.w3.org/1999/xlink"
xmlns="http://www.w3.org/2000/svg"
>
<defs>
<path
d="M7.293 8l-4.147 4.146a.5.5 0 0 0 .708.708L8 8.707l4.146 4.147a.5.5 0 0 0 .708-.708L8.707 8l4.147-4.146a.5.5 0 0 0-.708-.708L8 7.293 3.854 3.146a.5.5 0 1 0-.708.708L7.293 8z"
id="cross-a"
/>
</defs>
<use
fill-rule="nonzero"
href="#cross-a"
/>
</svg>
</button>
<div
class="euiText euiText--small"
>
a
</div>
</div>
<div
class="euiToast euiToast--danger euiGlobalToastListItem"
data-test-subj="b"
id="b"
>
<div
class="euiToastHeader euiToastHeader--withBody"
>
<svg
aria-hidden="true"
class="euiIcon euiToastHeader__icon euiIcon--medium"
height="16"
viewBox="0 0 16 16"
width="16"
xmlns="http://www.w3.org/2000/svg"
>
<g
fill-rule="evenodd"
>
<path
d="M7.5 2.236L1.618 14h11.764L7.5 2.236zm.894-.447l5.882 11.764A1 1 0 0 1 13.382 15H1.618a1 1 0 0 1-.894-1.447L6.606 1.789a1 1 0 0 1 1.788 0z"
/>
<path
d="M7 6h1v5H7zM7 12h1v1H7z"
/>
</g>
</svg>
<span
class="euiToastHeader__title"
>
B
</span>
</div>
<button
aria-label="Dismiss toast"
class="euiToast__closeButton"
data-test-subj="toastCloseButton"
type="button"
>
<svg
aria-hidden="true"
class="euiIcon euiIcon--medium"
height="16"
viewBox="0 0 16 16"
width="16"
xlink="http://www.w3.org/1999/xlink"
xmlns="http://www.w3.org/2000/svg"
>
<defs>
<path
d="M7.293 8l-4.147 4.146a.5.5 0 0 0 .708.708L8 8.707l4.146 4.147a.5.5 0 0 0 .708-.708L8.707 8l4.147-4.146a.5.5 0 0 0-.708-.708L8 7.293 3.854 3.146a.5.5 0 1 0-.708.708L7.293 8z"
id="cross-a"
/>
</defs>
<use
fill-rule="nonzero"
href="#cross-a"
/>
</svg>
</button>
<div
class="euiText euiText--small"
>
b
</div>
</div>
</div>
`;
Loading