Make footer slot existence automatic (dialog, drawer)

pull/146/head
Cory LaViska 2020-07-24 08:38:00 -04:00
rodzic 60e8e4579a
commit a220b694ef
5 zmienionych plików z 50 dodań i 38 usunięć

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

@ -203,10 +203,6 @@ export namespace Components {
* The dialog's label as displayed in the header. You should always include a relevant label even when using `no-header`, as it is required for proper accessibility.
*/
"label": string;
/**
* Set to true to disable the footer.
*/
"noFooter": boolean;
/**
* Set to true to disable the header. This will also remove the default close button, so please ensure you provide an easy, accessible way for users to dismiss the dialog.
*/
@ -233,10 +229,6 @@ export namespace Components {
* The drawer's label as displayed in the header. You should always include a relevant label even when using `no-header`, as it is required for proper accessibility.
*/
"label": string;
/**
* Removes the footer.
*/
"noFooter": boolean;
/**
* Removes the header. This will also remove the default close button, so please ensure you provide an easy, accessible way for users to dismiss the drawer.
*/
@ -1343,10 +1335,6 @@ declare namespace LocalJSX {
* The dialog's label as displayed in the header. You should always include a relevant label even when using `no-header`, as it is required for proper accessibility.
*/
"label"?: string;
/**
* Set to true to disable the footer.
*/
"noFooter"?: boolean;
/**
* Set to true to disable the header. This will also remove the default close button, so please ensure you provide an easy, accessible way for users to dismiss the dialog.
*/
@ -1385,10 +1373,6 @@ declare namespace LocalJSX {
* The drawer's label as displayed in the header. You should always include a relevant label even when using `no-header`, as it is required for proper accessibility.
*/
"label"?: string;
/**
* Removes the footer.
*/
"noFooter"?: boolean;
/**
* Removes the header. This will also remove the default close button, so please ensure you provide an easy, accessible way for users to dismiss the drawer.
*/
@ -1406,7 +1390,7 @@ declare namespace LocalJSX {
*/
"onSlHide"?: (event: CustomEvent<any>) => void;
/**
* Emitted when the overlay is clicked. Calling `event.preventDefault()` will prevent the dialog from closing.
* Emitted when the overlay is clicked. Calling `event.preventDefault()` will prevent the drawer from closing.
*/
"onSlOverlayDismiss"?: (event: CustomEvent<any>) => void;
/**

Wyświetl plik

@ -114,6 +114,10 @@
}
}
.dialog:not(.dialog--has-footer) .dialog__footer {
display: none;
}
.dialog__overlay {
position: fixed;
top: 0;

Wyświetl plik

@ -1,6 +1,7 @@
import { Component, Element, Event, EventEmitter, Method, Prop, Watch, h } from '@stencil/core';
import { Component, Element, Event, EventEmitter, Method, Prop, State, Watch, h } from '@stencil/core';
import { lockBodyScrolling, unlockBodyScrolling } from '../../utilities/scroll';
import { focusVisible } from '../../utilities/focus-visible';
import { hasSlot } from '../../utilities/slot';
let id = 0;
@ -33,6 +34,8 @@ export class Dialog {
@Element() host: HTMLSlDialogElement;
@State() hasFooter = false;
/** Indicates whether or not the dialog is open. You can use this in lieu of the show/hide methods. */
@Prop({ mutable: true, reflect: true }) open = false;
@ -48,9 +51,6 @@ export class Dialog {
*/
@Prop() noHeader = false;
/** Set to true to disable the footer. */
@Prop() noFooter = false;
@Watch('open')
handleOpenChange() {
this.open ? this.show() : this.hide();
@ -79,6 +79,11 @@ export class Dialog {
this.handleOverlayClick = this.handleOverlayClick.bind(this);
}
componentWillLoad() {
this.updateSlots();
this.host.shadowRoot.addEventListener('slotchange', this.updateSlots);
}
componentDidLoad() {
focusVisible.observe(this.dialog);
@ -91,6 +96,8 @@ export class Dialog {
componentDidUnload() {
focusVisible.unobserve(this.dialog);
unlockBodyScrolling(this.host);
this.host.shadowRoot.removeEventListener('slotchange', this.updateSlots);
}
/** Shows the dialog */
@ -165,6 +172,10 @@ export class Dialog {
}
}
updateSlots() {
this.hasFooter = hasSlot(this.host, 'footer');
}
render() {
return (
<div
@ -172,7 +183,8 @@ export class Dialog {
part="base"
class={{
dialog: true,
'dialog--open': this.open
'dialog--open': this.open,
'dialog--has-footer': this.hasFooter
}}
onKeyDown={this.handleKeyDown}
onTransitionEnd={this.handleTransitionEnd}
@ -207,11 +219,9 @@ export class Dialog {
<slot />
</div>
{!this.noFooter && (
<footer part="footer" class="dialog__footer">
<slot name="footer" />
</footer>
)}
<footer part="footer" class="dialog__footer">
<slot name="footer" />
</footer>
</div>
</div>
);

Wyświetl plik

@ -153,6 +153,10 @@
}
}
.drawer:not(.drawer--has-footer) .drawer__footer {
display: none;
}
.drawer__overlay {
display: block;
position: fixed;

Wyświetl plik

@ -1,6 +1,7 @@
import { Component, Element, Event, EventEmitter, Method, Prop, Watch, h } from '@stencil/core';
import { Component, Element, Event, EventEmitter, Method, Prop, State, Watch, h } from '@stencil/core';
import { lockBodyScrolling, unlockBodyScrolling } from '../../utilities/scroll';
import { focusVisible } from '../../utilities/focus-visible';
import { hasSlot } from '../../utilities/slot';
let id = 0;
@ -32,6 +33,8 @@ export class Drawer {
@Element() host: HTMLSlDrawerElement;
@State() hasFooter = false;
/** Indicates whether or not the drawer is open. You can use this in lieu of the show/hide methods. */
@Prop({ mutable: true, reflect: true }) open = false;
@ -56,9 +59,6 @@ export class Drawer {
*/
@Prop() noHeader = false;
/** Removes the footer. */
@Prop() noFooter = false;
@Watch('open')
handleOpenChange() {
this.open ? this.show() : this.hide();
@ -76,7 +76,7 @@ export class Drawer {
/** Emitted after the drawer closes and all transitions are complete. */
@Event() slAfterHide: EventEmitter;
/** Emitted when the overlay is clicked. Calling `event.preventDefault()` will prevent the dialog from closing. */
/** Emitted when the overlay is clicked. Calling `event.preventDefault()` will prevent the drawer from closing. */
@Event() slOverlayDismiss: EventEmitter;
connectedCallback() {
@ -87,6 +87,11 @@ export class Drawer {
this.handleOverlayClick = this.handleOverlayClick.bind(this);
}
componentWillLoad() {
this.updateSlots();
this.host.shadowRoot.addEventListener('slotchange', this.updateSlots);
}
componentDidLoad() {
focusVisible.observe(this.drawer);
@ -99,6 +104,8 @@ export class Drawer {
componentDidUnload() {
focusVisible.unobserve(this.drawer);
unlockBodyScrolling(this.host);
this.host.shadowRoot.removeEventListener('slotchange', this.updateSlots);
}
/** Shows the drawer */
@ -179,6 +186,10 @@ export class Drawer {
}
}
updateSlots() {
this.hasFooter = hasSlot(this.host, 'footer');
}
render() {
return (
<div
@ -192,7 +203,8 @@ export class Drawer {
'drawer--bottom': this.placement === 'bottom',
'drawer--left': this.placement === 'left',
'drawer--contained': this.contained,
'drawer--fixed': !this.contained
'drawer--fixed': !this.contained,
'drawer--has-footer': this.hasFooter
}}
onKeyDown={this.handleKeyDown}
onTransitionEnd={this.handleTransitionEnd}
@ -227,11 +239,9 @@ export class Drawer {
<slot />
</div>
{!this.noFooter && (
<footer part="footer" class="drawer__footer">
<slot name="footer" />
</footer>
)}
<footer part="footer" class="drawer__footer">
<slot name="footer" />
</footer>
</div>
</div>
);