Add light dom styles; reset duration on mouse move

This commit is contained in:
Cory LaViska
2020-09-16 11:10:25 -04:00
parent 017e6db629
commit dbb1a69e67
5 changed files with 47 additions and 80 deletions

4
src/components.d.ts vendored
View File

@@ -12,7 +12,7 @@ export namespace Components {
*/
"closable": boolean;
/**
* The length of time, in milliseconds, the alert will show before closing itself.
* The length of time, in milliseconds, the alert will show before closing itself. If the user interacts with the alert before it closes (e.g. moves the mouse over it), the duration will restart.
*/
"duration": number;
/**
@@ -1427,7 +1427,7 @@ declare namespace LocalJSX {
*/
"closable"?: boolean;
/**
* The length of time, in milliseconds, the alert will show before closing itself.
* The length of time, in milliseconds, the alert will show before closing itself. If the user interacts with the alert before it closes (e.g. moves the mouse over it), the duration will restart.
*/
"duration"?: number;
/**

View File

@@ -1,49 +1,9 @@
// :root {
// --width: 28rem;
// --spacing: var(--sl-spacing-medium);
// }
// .sl-alert-stack {
// position: fixed;
// z-index: var(--sl-z-index-toast);
// width: var(--width);
// max-width: 100%;
// max-height: 100%;
// overflow: auto;
// padding: 0 var(--spacing);
// sl-alert {
// --box-shadow: var(--sl-shadow-large);
// margin: var(--spacing) 0;
// }
// }
// .sl-alert-stack[data-placement='top-start'] {
// top: 0;
// left: 0;
// }
// .sl-alert-stack[data-placement='top'] {
// top: 0;
// left: calc(50% - var(--width) / 2);
// }
// .sl-alert-stack[data-placement='top-end'] {
// top: 0;
// right: 0;
// }
// .sl-alert-stack[data-placement='bottom-start'] {
// bottom: 0;
// left: 0;
// }
// .sl-alert-stack[data-placement='bottom'] {
// bottom: 0;
// left: calc(50% - var(--width) / 2);
// }
// .sl-alert-stack[data-placement='bottom-end'] {
// bottom: 0;
// right: 0;
// }
.sl-toast-stack {
position: fixed;
top: 0;
right: 0;
z-index: var(--sl-z-index-toast);
max-width: 100%;
max-height: 100%;
overflow: auto;
}

View File

@@ -2,11 +2,13 @@
/**
* @prop --box-shadow: The alert's box shadow.
* @prop --toast-spacing: The spacing to use when alerts are stacked as "toast" notifications.
* @prop --toast-spacing: The spacing to use when the alert is shown as a toast notification.
* @prop --toast-width: The width of the alert when shown as a toast notification.
*/
:host {
--box-shadow: none;
--stack-spacing: var(--sl-spacing-medium);
--toast-spacing: var(--sl-spacing-medium);
--toast-width: 28rem;
display: block;
@@ -35,10 +37,10 @@
}
.alert--toast {
width: 28rem;
max-width: calc(100% - var(--stack-spacing) * 2);
width: var(--toast-width);
max-width: calc(100% - var(--toast-spacing) * 2);
box-shadow: var(--sl-shadow-large);
margin: var(--stack-spacing);
margin: var(--toast-spacing);
}
.alert--open {

View File

@@ -13,7 +13,8 @@ import { Component, Element, Event, EventEmitter, Host, Method, Prop, Watch, h }
* @part close-button - The close button.
*/
const stack = Object.assign(document.createElement('div'), { className: 'sl-alert-stack' });
const stack = Object.assign(document.createElement('div'), { className: 'sl-toast-stack' });
stack.dataset.placement = 'top';
@Component({
tag: 'sl-alert',
@@ -43,7 +44,10 @@ export class Alert {
*/
@Prop() toast = false;
/** The length of time, in milliseconds, the alert will show before closing itself. */
/**
* The length of time, in milliseconds, the alert will show before closing itself. If the user interacts with the
* alert before it closes (e.g. moves the mouse over it), the duration will restart.
*/
@Prop() duration = Infinity;
@Watch('open')
@@ -53,12 +57,7 @@ export class Alert {
@Watch('duration')
handleDurationChange() {
clearTimeout(this.autoHideTimeout);
// Restart the timeout if the duration changes and the alert is open
if (this.open && this.duration < Infinity) {
this.autoHideTimeout = setTimeout(() => this.hide(), this.duration);
}
this.restartAutoHide();
}
/** Emitted when the alert opens. Calling `event.preventDefault()` will prevent it from being opened. */
@@ -75,6 +74,7 @@ export class Alert {
connectedCallback() {
this.handleCloseClick = this.handleCloseClick.bind(this);
this.handleMouseMove = this.handleMouseMove.bind(this);
this.handleTransitionEnd = this.handleTransitionEnd.bind(this);
}
@@ -93,9 +93,16 @@ export class Alert {
return;
}
if (this.toast) {
this.appendToStack();
}
const slShow = this.slShow.emit();
if (slShow.defaultPrevented) {
this.open = false;
if (this.toast) {
this.removeFromStack();
}
return;
}
@@ -104,10 +111,6 @@ export class Alert {
this.isShowing = true;
this.open = true;
if (this.toast) {
this.appendToStack();
}
if (this.duration < Infinity) {
this.autoHideTimeout = setTimeout(() => this.hide(), this.duration);
}
@@ -136,18 +139,21 @@ export class Alert {
this.hide();
}
handleMouseMove() {
this.restartAutoHide();
}
handleTransitionEnd(event: TransitionEvent) {
const target = event.target as HTMLElement;
// Ensure we only emit one event when the target element is no longer visible
if (event.propertyName === 'opacity' && target.classList.contains('alert')) {
this.host.hidden = !this.open;
this.open ? this.slAfterShow.emit() : this.slAfterHide.emit();
if (this.toast && !this.open) {
this.removeFromStack();
}
this.open ? this.slAfterShow.emit() : this.slAfterHide.emit();
}
}
@@ -156,16 +162,6 @@ export class Alert {
document.body.append(stack);
}
Object.assign(stack.style, {
position: 'fixed',
top: '0',
right: '0',
zIndex: 'var(--sl-z-index-toast)',
maxWidth: '100%',
maxHeight: '100%',
overflow: 'auto'
});
stack.clientWidth; // force a reflow
stack.append(this.host);
}
@@ -180,6 +176,13 @@ export class Alert {
}
}
restartAutoHide() {
clearTimeout(this.autoHideTimeout);
if (this.open && this.duration < Infinity) {
this.autoHideTimeout = setTimeout(() => this.hide(), this.duration);
}
}
render() {
return (
<Host hidden>
@@ -201,6 +204,7 @@ export class Alert {
}}
role="alert"
aria-hidden={!this.open}
onMouseMove={this.handleMouseMove}
onTransitionEnd={this.handleTransitionEnd}
>
<span part="icon" class="alert__icon">

View File

@@ -269,4 +269,5 @@
// Component light DOM styles - only follow this pattern when absolutely necessary!
////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
@import '../components/alert/alert.light-dom';
@import '../components/button-group/button-group.light-dom';