Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

chore(modal): spike implementation of <dialog> element #851

Draft
wants to merge 1 commit into
base: develop
Choose a base branch
from
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
15 changes: 3 additions & 12 deletions packages/pharos/src/components/modal/pharos-modal.scss
Original file line number Diff line number Diff line change
Expand Up @@ -9,18 +9,9 @@
contain: layout size style;
}

.modal__overlay {
display: flex;
justify-content: center;
align-items: center;
position: fixed;
left: 0;
top: 0;
width: 100vw;
height: 100vh;
.modal__dialog::backdrop {
background-color: rgb(0 0 0 / 0);
visibility: hidden;
overflow-y: scroll;
transition:
visibility var(--pharos-transition-duration-default) ease-in-out,
background-color var(--pharos-transition-duration-default) ease-in-out;
Expand Down Expand Up @@ -49,7 +40,7 @@
:host([open]) {
pointer-events: auto;

.modal__overlay {
.modal__dialog::backdrop {
background-color: rgb(0 0 0 / 0.5);
visibility: visible;
}
Expand All @@ -60,7 +51,7 @@
}

@media only screen and (width <= 570px) {
.modal__overlay {
.modal__dialog::backdrop {
display: block;
overflow-y: visible;
transition-duration: var(--pharos-transition-duration-long);
Expand Down
76 changes: 37 additions & 39 deletions packages/pharos/src/components/modal/pharos-modal.ts
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
import { PharosElement } from '../base/pharos-element';
import { html, nothing } from 'lit';
import { property, state } from 'lit/decorators.js';
import { property, state, query } from 'lit/decorators.js';
import type { TemplateResult, CSSResultArray, PropertyValues } from 'lit';
import { classMap } from 'lit/directives/class-map.js';
import { ifDefined } from 'lit/directives/if-defined.js';
Expand All @@ -10,7 +10,6 @@ import focusable from '../../utils/focusable';
import ScopedRegistryMixin from '../../utils/mixins/scoped-registry';
import { PharosButton } from '../button/pharos-button';
import { PharosHeading } from '../heading/pharos-heading';
import { FocusTrap } from '@ithaka/focus-trap';

const CLOSE_BUTTONS = `[data-modal-close],[data-pharos-component="PharosButton"]#close-button`;
const FOCUS_ELEMENT = `[data-modal-focus]`;
Expand Down Expand Up @@ -38,7 +37,6 @@ export class PharosModal extends ScopedRegistryMixin(PharosElement) {
static elementDefinitions = {
'pharos-button': PharosButton,
'pharos-heading': PharosHeading,
'focus-trap': FocusTrap,
};

/**
Expand Down Expand Up @@ -73,6 +71,9 @@ export class PharosModal extends ScopedRegistryMixin(PharosElement) {

private _triggers!: NodeListOf<HTMLElement>;

@query('.modal__dialog')
private _dialog!: HTMLDialogElement;

@state()
private _isFooterEmpty = true;

Expand Down Expand Up @@ -157,6 +158,7 @@ export class PharosModal extends ScopedRegistryMixin(PharosElement) {
)
) {
this.open = false;
this._dialog.close();
}
}
}
Expand All @@ -173,6 +175,7 @@ export class PharosModal extends ScopedRegistryMixin(PharosElement) {
this.dispatchEvent(new CustomEvent('pharos-modal-open', { ...details, cancelable: true }))
) {
this.open = true;
this._dialog.showModal();
}
}
}
Expand Down Expand Up @@ -252,43 +255,38 @@ export class PharosModal extends ScopedRegistryMixin(PharosElement) {

protected override render(): TemplateResult {
return html`
<div class="modal__overlay">
<div
role="dialog"
class=${classMap({
[`modal__dialog`]: true,
[`modal__dialog--${this.size}`]: this.size,
})}
aria-modal="true"
aria-labelledby="modal-header"
aria-describedby="${ifDefined(this.descriptionId)}"
@click=${this._handleDialogClick}
>
<focus-trap>
<div class="modal__content">
<div class="modal__header">
<pharos-heading id="modal-header" level="2" preset="5" no-margin
>${this.header}</pharos-heading
>
<pharos-button
id="close-button"
type="button"
variant="subtle"
icon="close"
a11y-label="Close modal"
></pharos-button>
</div>
<div class="modal__body">
${this.descriptionContent}
<slot></slot>
</div>
<div class="modal__footer${this._isFooterEmpty ? '--empty' : ''}">
<slot @slotchange=${this._handleFooterSlotchange} name="footer"></slot>
</div>
</div>
</focus-trap>
<dialog
class=${classMap({
[`modal__dialog`]: true,
[`modal__dialog--${this.size}`]: this.size,
})}
aria-modal="true"
aria-labelledby="modal-header"
aria-describedby="${ifDefined(this.descriptionId)}"
@click=${this._handleDialogClick}
>
<div class="modal__content">
<div class="modal__header">
<pharos-heading id="modal-header" level="2" preset="5" no-margin
>${this.header}</pharos-heading
>
<pharos-button
id="close-button"
type="button"
variant="subtle"
icon="close"
a11y-label="Close modal"
></pharos-button>
</div>
<div class="modal__body">
${this.descriptionContent}
<slot></slot>
</div>
<div class="modal__footer${this._isFooterEmpty ? '--empty' : ''}">
<slot @slotchange=${this._handleFooterSlotchange} name="footer"></slot>
</div>
</div>
</div>
</dialog>
`;
}
}
Loading