kopia lustrzana https://github.com/shoelace-style/shoelace
Rework alert show/hide logic; #247
rodzic
4f7496b6be
commit
5e8db633b9
|
@ -11,6 +11,8 @@ Alerts are used to display important messages either inline or as toast notifica
|
|||
</sl-alert>
|
||||
```
|
||||
|
||||
?> Alerts will not be visible if the `open` attribute is not present.
|
||||
|
||||
## Examples
|
||||
|
||||
### Types
|
||||
|
@ -93,7 +95,7 @@ Set the `duration` prop to automatically hide an alert after a period of time. T
|
|||
<div class="alert-duration">
|
||||
<sl-button type="primary">Show Alert</sl-button>
|
||||
|
||||
<sl-alert type="primary" duration="3000" closable style="margin-top: var(--sl-spacing-medium);">
|
||||
<sl-alert type="primary" duration="3000" closable>
|
||||
<sl-icon slot="icon" name="info-circle"></sl-icon>
|
||||
This alert will automatically hide itself after three seconds, unless you interact with it.
|
||||
</sl-alert>
|
||||
|
@ -106,6 +108,12 @@ Set the `duration` prop to automatically hide an alert after a period of time. T
|
|||
|
||||
button.addEventListener('click', () => alert.show());
|
||||
</script>
|
||||
|
||||
<style>
|
||||
.alert-duration sl-alert {
|
||||
margin-top: var(--sl-spacing-medium);
|
||||
}
|
||||
</style>
|
||||
```
|
||||
|
||||
### Toast Notifications
|
||||
|
|
|
@ -10,6 +10,7 @@ _During the beta period, these restrictions may be relaxed in the event of a mis
|
|||
|
||||
- Fixed a bug where initial transitions didn't show in `sl-dialog` and `sl-drawer` [#247](https://github.com/shoelace-style/shoelace/issues/247)
|
||||
- Improved `sl-color-picker` grid and slider handles [#246](https://github.com/shoelace-style/shoelace/issues/246)
|
||||
- Reworked show/hide logic in `sl-alert`, `sl-dialog`, and `sl-drawer` to not use reflow hacks and the `hidden` attribute
|
||||
- Updated to Popper 2.5.3 to address a fixed position bug in Firefox
|
||||
|
||||
## 2.0.0-beta.20
|
||||
|
|
|
@ -1,16 +1,14 @@
|
|||
@import 'component';
|
||||
@import 'mixins/visually-hidden';
|
||||
|
||||
/**
|
||||
* @prop --box-shadow: The alert's box shadow.
|
||||
*/
|
||||
:host {
|
||||
--box-shadow: none;
|
||||
display: contents;
|
||||
|
||||
display: block;
|
||||
|
||||
&[hidden] {
|
||||
display: none;
|
||||
}
|
||||
// For better DX, we'll reset the margin here so the base part can inherit it
|
||||
margin: 0;
|
||||
}
|
||||
|
||||
.alert {
|
||||
|
@ -30,6 +28,11 @@
|
|||
opacity: 0;
|
||||
transform: scale(0.9);
|
||||
transition: var(--sl-transition-medium) opacity ease, var(--sl-transition-medium) transform ease;
|
||||
margin: inherit;
|
||||
|
||||
&:not(.alert--visible) {
|
||||
@include visually-hidden;
|
||||
}
|
||||
}
|
||||
|
||||
.alert--open {
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
import { Component, Element, Event, EventEmitter, Host, Method, Prop, Watch, h } from '@stencil/core';
|
||||
import { Component, Element, Event, EventEmitter, Method, Prop, State, Watch, h } from '@stencil/core';
|
||||
|
||||
const toastStack = Object.assign(document.createElement('div'), { className: 'sl-toast-stack' });
|
||||
|
||||
|
@ -23,10 +23,11 @@ const toastStack = Object.assign(document.createElement('div'), { className: 'sl
|
|||
export class Alert {
|
||||
alert: HTMLElement;
|
||||
autoHideTimeout: any;
|
||||
isVisible = false;
|
||||
|
||||
@Element() host: HTMLSlAlertElement;
|
||||
|
||||
@State() isVisible = false;
|
||||
|
||||
/** Indicates whether or not the alert is open. You can use this in lieu of the show/hide methods. */
|
||||
@Prop({ mutable: true, reflect: true }) open = false;
|
||||
|
||||
|
@ -91,8 +92,6 @@ export class Alert {
|
|||
return;
|
||||
}
|
||||
|
||||
this.host.hidden = false;
|
||||
this.host.clientWidth; // force a reflow
|
||||
this.isVisible = true;
|
||||
this.open = true;
|
||||
|
||||
|
@ -116,7 +115,6 @@ export class Alert {
|
|||
}
|
||||
|
||||
clearTimeout(this.autoHideTimeout);
|
||||
this.isVisible = false;
|
||||
this.open = false;
|
||||
}
|
||||
|
||||
|
@ -133,7 +131,7 @@ export class Alert {
|
|||
}
|
||||
|
||||
toastStack.append(this.host);
|
||||
this.show();
|
||||
requestAnimationFrame(() => this.show());
|
||||
|
||||
this.host.addEventListener(
|
||||
'sl-after-hide',
|
||||
|
@ -164,7 +162,7 @@ export class Alert {
|
|||
|
||||
// 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.isVisible = this.open;
|
||||
this.open ? this.slAfterShow.emit() : this.slAfterHide.emit();
|
||||
}
|
||||
}
|
||||
|
@ -178,42 +176,41 @@ export class Alert {
|
|||
|
||||
render() {
|
||||
return (
|
||||
<Host hidden>
|
||||
<div
|
||||
ref={el => (this.alert = el)}
|
||||
part="base"
|
||||
class={{
|
||||
alert: true,
|
||||
'alert--open': this.open,
|
||||
'alert--closable': this.closable,
|
||||
'alert--primary': this.type === 'primary',
|
||||
'alert--success': this.type === 'success',
|
||||
'alert--info': this.type === 'info',
|
||||
'alert--warning': this.type === 'warning',
|
||||
'alert--danger': this.type === 'danger'
|
||||
}}
|
||||
role="alert"
|
||||
aria-live="assertive"
|
||||
aria-atomic="true"
|
||||
aria-hidden={!this.open}
|
||||
onMouseMove={this.handleMouseMove}
|
||||
onTransitionEnd={this.handleTransitionEnd}
|
||||
>
|
||||
<span part="icon" class="alert__icon">
|
||||
<slot name="icon" />
|
||||
</span>
|
||||
<div
|
||||
ref={el => (this.alert = el)}
|
||||
part="base"
|
||||
class={{
|
||||
alert: true,
|
||||
'alert--open': this.open,
|
||||
'alert--visible': this.isVisible,
|
||||
'alert--closable': this.closable,
|
||||
'alert--primary': this.type === 'primary',
|
||||
'alert--success': this.type === 'success',
|
||||
'alert--info': this.type === 'info',
|
||||
'alert--warning': this.type === 'warning',
|
||||
'alert--danger': this.type === 'danger'
|
||||
}}
|
||||
role="alert"
|
||||
aria-live="assertive"
|
||||
aria-atomic="true"
|
||||
aria-hidden={!this.open}
|
||||
onMouseMove={this.handleMouseMove}
|
||||
onTransitionEnd={this.handleTransitionEnd}
|
||||
>
|
||||
<span part="icon" class="alert__icon">
|
||||
<slot name="icon" />
|
||||
</span>
|
||||
|
||||
<span part="message" class="alert__message">
|
||||
<slot />
|
||||
</span>
|
||||
<span part="message" class="alert__message">
|
||||
<slot />
|
||||
</span>
|
||||
|
||||
{this.closable && (
|
||||
<span class="alert__close">
|
||||
<sl-icon-button part="close-button" name="x" onClick={this.handleCloseClick} />
|
||||
</span>
|
||||
)}
|
||||
</div>
|
||||
</Host>
|
||||
{this.closable && (
|
||||
<span class="alert__close">
|
||||
<sl-icon-button part="close-button" name="x" onClick={this.handleCloseClick} />
|
||||
</span>
|
||||
)}
|
||||
</div>
|
||||
);
|
||||
}
|
||||
}
|
||||
|
|
Ładowanie…
Reference in New Issue