Snack: sub-message, close button and duration setting
- Add close button to allow immediate dismissal. - Add ability to support sub messages. Will be typically used for error codes, etc. - Add ability to define 'long' auto-dismiss duration (15s) vs. the default of 5s. - I didn't add 'off' because there is a comment saying that this scenario should use the Error Modal instead, so respecting that for now.
This commit is contained in:
parent
d1d9b116d4
commit
9482a7f986
3 changed files with 35 additions and 17 deletions
4
flow-typed/notification.js
vendored
4
flow-typed/notification.js
vendored
|
@ -11,10 +11,12 @@ import * as ACTIONS from 'constants/action_types';
|
||||||
*/
|
*/
|
||||||
declare type ToastParams = {
|
declare type ToastParams = {
|
||||||
message: string,
|
message: string,
|
||||||
title?: string,
|
subMessage?: string,
|
||||||
|
// title?: string,
|
||||||
linkText?: string,
|
linkText?: string,
|
||||||
linkTarget?: string,
|
linkTarget?: string,
|
||||||
isError?: boolean,
|
isError?: boolean,
|
||||||
|
duration?: 'default' | 'long',
|
||||||
};
|
};
|
||||||
|
|
||||||
declare type Toast = {
|
declare type Toast = {
|
||||||
|
|
|
@ -8,24 +8,16 @@ import LbcMessage from 'component/common/lbc-message';
|
||||||
|
|
||||||
type Props = {
|
type Props = {
|
||||||
removeSnack: (any) => void,
|
removeSnack: (any) => void,
|
||||||
snack: ?{
|
snack: ?ToastParams,
|
||||||
linkTarget: ?string,
|
|
||||||
linkText: ?string,
|
|
||||||
message: string,
|
|
||||||
isError: boolean,
|
|
||||||
},
|
|
||||||
};
|
};
|
||||||
|
|
||||||
class SnackBar extends React.PureComponent<Props> {
|
class SnackBar extends React.PureComponent<Props> {
|
||||||
constructor(props: Props) {
|
constructor(props: Props) {
|
||||||
super(props);
|
super(props);
|
||||||
|
|
||||||
this.displayTime = 5; // in seconds
|
|
||||||
this.hideTimeout = null;
|
this.hideTimeout = null;
|
||||||
}
|
}
|
||||||
|
|
||||||
hideTimeout: ?TimeoutID;
|
hideTimeout: ?TimeoutID;
|
||||||
displayTime: number;
|
|
||||||
|
|
||||||
render() {
|
render() {
|
||||||
const { snack, removeSnack } = this.props;
|
const { snack, removeSnack } = this.props;
|
||||||
|
@ -35,13 +27,16 @@ class SnackBar extends React.PureComponent<Props> {
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
|
|
||||||
const { message, linkText, linkTarget, isError } = snack;
|
const { message, subMessage, duration, linkText, linkTarget, isError } = snack;
|
||||||
|
|
||||||
if (this.hideTimeout === null) {
|
if (this.hideTimeout === null) {
|
||||||
this.hideTimeout = setTimeout(() => {
|
this.hideTimeout = setTimeout(
|
||||||
|
() => {
|
||||||
this.hideTimeout = null;
|
this.hideTimeout = null;
|
||||||
removeSnack();
|
removeSnack();
|
||||||
}, this.displayTime * 1000);
|
},
|
||||||
|
duration === 'long' ? 15000 : 5000
|
||||||
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
return (
|
return (
|
||||||
|
@ -52,10 +47,20 @@ class SnackBar extends React.PureComponent<Props> {
|
||||||
>
|
>
|
||||||
<div className="snack-bar__message">
|
<div className="snack-bar__message">
|
||||||
<Icon icon={isError ? ICONS.ALERT : ICONS.COMPLETED} size={18} />
|
<Icon icon={isError ? ICONS.ALERT : ICONS.COMPLETED} size={18} />
|
||||||
|
|
||||||
<p className="snack-bar__messageText">
|
<p className="snack-bar__messageText">
|
||||||
<LbcMessage>{message}</LbcMessage>
|
<LbcMessage>{message}</LbcMessage>
|
||||||
|
{subMessage && (
|
||||||
|
<p className="snack-bar__messageText snack-bar__messageText--sub">
|
||||||
|
<LbcMessage>{subMessage}</LbcMessage>
|
||||||
</p>
|
</p>
|
||||||
|
)}
|
||||||
|
</p>
|
||||||
|
<Button
|
||||||
|
className="snack-bar__close"
|
||||||
|
icon={ICONS.REMOVE}
|
||||||
|
title={__('Dismiss')}
|
||||||
|
onClick={() => removeSnack()}
|
||||||
|
/>
|
||||||
</div>
|
</div>
|
||||||
{linkText && linkTarget && (
|
{linkText && linkTarget && (
|
||||||
// This is a little weird because of `linkTarget` code in `lbry-redux`
|
// This is a little weird because of `linkTarget` code in `lbry-redux`
|
||||||
|
|
|
@ -5,7 +5,7 @@
|
||||||
background-color: var(--color-primary);
|
background-color: var(--color-primary);
|
||||||
color: var(--color-primary-contrast);
|
color: var(--color-primary-contrast);
|
||||||
border-radius: var(--border-radius);
|
border-radius: var(--border-radius);
|
||||||
padding: var(--spacing-s) var(--spacing-l) var(--spacing-s) var(--spacing-m);
|
padding: var(--spacing-s) var(--spacing-m) var(--spacing-s) var(--spacing-m);
|
||||||
position: fixed;
|
position: fixed;
|
||||||
transition: all var(--transition-duration) var(--transition-type);
|
transition: all var(--transition-duration) var(--transition-type);
|
||||||
z-index: 10000; // hack to get it over react modal
|
z-index: 10000; // hack to get it over react modal
|
||||||
|
@ -71,8 +71,19 @@
|
||||||
min-width: 1rem;
|
min-width: 1rem;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
.snack-bar__messageText {
|
.snack-bar__messageText {
|
||||||
min-width: 0;
|
min-width: 0;
|
||||||
text-overflow: ellipsis;
|
text-overflow: ellipsis;
|
||||||
overflow: hidden;
|
overflow: hidden;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
.snack-bar__messageText--sub {
|
||||||
|
font-size: var(--font-small);
|
||||||
|
color: var(--color-text-subtitle);
|
||||||
|
}
|
||||||
|
|
||||||
|
.snack-bar__close {
|
||||||
|
color: var(--color-primary-contrast);
|
||||||
|
margin-left: var(--spacing-m);
|
||||||
|
}
|
||||||
|
|
Loading…
Reference in a new issue