diff --git a/docs/components/alert.md b/docs/components/alert.md index 976e1a517..9972f7e29 100644 --- a/docs/components/alert.md +++ b/docs/components/alert.md @@ -11,6 +11,8 @@ Alerts are used to display important messages either inline or as toast notifica ``` +?> 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
Show Alert - + This alert will automatically hide itself after three seconds, unless you interact with it. @@ -106,6 +108,12 @@ Set the `duration` prop to automatically hide an alert after a period of time. T button.addEventListener('click', () => alert.show()); + + ``` ### Toast Notifications diff --git a/docs/getting-started/changelog.md b/docs/getting-started/changelog.md index b72a02281..eef5388af 100644 --- a/docs/getting-started/changelog.md +++ b/docs/getting-started/changelog.md @@ -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 diff --git a/src/components/alert/alert.scss b/src/components/alert/alert.scss index d060ef768..3789ff6ed 100644 --- a/src/components/alert/alert.scss +++ b/src/components/alert/alert.scss @@ -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 { diff --git a/src/components/alert/alert.tsx b/src/components/alert/alert.tsx index 5dad701a4..c4108a572 100644 --- a/src/components/alert/alert.tsx +++ b/src/components/alert/alert.tsx @@ -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 ( -