Add light dom styles; reset duration on mouse move

pull/224/head
Cory LaViska 2020-09-16 11:10:25 -04:00
rodzic 017e6db629
commit dbb1a69e67
5 zmienionych plików z 47 dodań i 80 usunięć

4
src/components.d.ts vendored
Wyświetl plik

@ -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;
/**

Wyświetl plik

@ -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;
}

Wyświetl plik

@ -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 {

Wyświetl plik

@ -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">

Wyświetl plik

@ -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';