kopia lustrzana https://github.com/shoelace-style/shoelace
Add light dom styles; reset duration on mouse move
rodzic
017e6db629
commit
dbb1a69e67
|
@ -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;
|
||||
/**
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
|
|
|
@ -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 {
|
||||
|
|
|
@ -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">
|
||||
|
|
|
@ -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';
|
||||
|
|
Ładowanie…
Reference in New Issue