diff --git a/labs/layout/supportingpane/internal/_supporting-pane.scss b/labs/layout/supportingpane/internal/_supporting-pane.scss new file mode 100644 index 0000000000..776f55ea02 --- /dev/null +++ b/labs/layout/supportingpane/internal/_supporting-pane.scss @@ -0,0 +1,61 @@ +// +// Copyright 2023 Google LLC +// SPDX-License-Identifier: Apache-2.0 +// + +// go/keep-sorted start +@use 'sass:list'; +// go/keep-sorted end + +@mixin styles() { + .host { + display: flex; + flex-direction: column; + height: 100%; + width: 100%; + } + + slot { + width: 100%; + height: 100%; + } + + :host([variant='expanded']) { + flex-direction: row; + } + + :host([variant='expanded']) slot[name='supporting'] { + max-width: var(--md-supporting-pane-width, 360px); + margin-left: 24px; + } + + :host([variant='expanded'][left]) slot[name='supporting'] { + margin-right: 24px; + } + + :host([variant='medium']) slot, + :host([variant='compact']) slot { + position: absolute; + left: 0; + right: 0; + bottom: 0; + top: 0; + } + + :host([variant='medium']) slot:not([name='supporting']) { + // max-height: calc(100% - (100% / 3)); + bottom: calc(100% - (100% / 3)); + } + + :host([variant='medium']) slot[name='supporting'] { + top: calc(100% / 3); + } + + :host([variant='compact']) slot:not([name='supporting']) { + bottom: calc(100% / 2); + } + + :host([variant='compact']) slot[name='supporting'] { + top: calc(100% / 2); + } +} diff --git a/labs/layout/supportingpane/internal/supporting-pane-styles.scss b/labs/layout/supportingpane/internal/supporting-pane-styles.scss new file mode 100644 index 0000000000..231e96566e --- /dev/null +++ b/labs/layout/supportingpane/internal/supporting-pane-styles.scss @@ -0,0 +1,10 @@ +// +// Copyright 2023 Google LLC +// SPDX-License-Identifier: Apache-2.0 +// + +// go/keep-sorted start +@use './supporting-pane'; +// go/keep-sorted end + +@include supporting-pane.styles; diff --git a/labs/layout/supportingpane/internal/supporting-pane.ts b/labs/layout/supportingpane/internal/supporting-pane.ts new file mode 100644 index 0000000000..a187a80f54 --- /dev/null +++ b/labs/layout/supportingpane/internal/supporting-pane.ts @@ -0,0 +1,74 @@ +/** + * @license + * Copyright 2023 Google LLC + * SPDX-License-Identifier: Apache-2.0 + */ + +import { html, LitElement, PropertyValueMap } from 'lit'; +import { property } from 'lit/decorators'; + +/** + * The Supporting Pane Layout. + */ +export class SupportingPane extends LitElement { + @property({ type: String, reflect: true }) + variant: 'compact' | 'medium' | 'expanded' = 'compact'; + + @property({ type: Boolean, reflect: true }) + left: boolean = false; + + @property() + mediumQuery: string = '(min-width: 600px)'; + + @property() + expandedQuery: string = '(min-width: 840px)'; + + mediumMediaQuery: MediaQueryList; + + expandedMediaQuery: MediaQueryList; + + private _handleMediumChange({ + matches, + }: MediaQueryList | MediaQueryListEvent) { + if (matches) this.variant = 'medium'; + } + + private _handleExpandedChange({ + matches, + }: MediaQueryList | MediaQueryListEvent) { + if (matches) this.variant = 'expanded'; + } + + protected override firstUpdated() { + this.mediumMediaQuery = window.matchMedia(this.mediumQuery); + this.mediumMediaQuery.addEventListener('change', this._handleMediumChange); + this._handleMediumChange(this.mediumMediaQuery); + + this.expandedMediaQuery = window.matchMedia(this.expandedQuery); + this.expandedMediaQuery.addEventListener( + 'change', + this._handleExpandedChange + ); + this._handleExpandedChange(this.expandedMediaQuery); + } + + override disconnectedCallback() { + super.disconnectedCallback(); + this.mediumMediaQuery.removeEventListener( + 'change', + this._handleMediumChange + ); + + this.expandedMediaQuery.removeEventListener( + 'change', + this._handleExpandedChange + ); + } + + protected override render() { + return html` + + + `; + } +} diff --git a/labs/layout/supportingpane/supporting-pane.ts b/labs/layout/supportingpane/supporting-pane.ts new file mode 100644 index 0000000000..e943937593 --- /dev/null +++ b/labs/layout/supportingpane/supporting-pane.ts @@ -0,0 +1,25 @@ +/** + * @license + * Copyright 2023 Google LLC + * SPDX-License-Identifier: Apache-2.0 + */ + +import { customElement } from 'lit/decorators.js'; + +import { SupportingPane } from './internal/supporting-pane.js'; +import { styles } from './internal/supporting-pane-styles.css.js'; + +declare global { + interface HTMLElementTagNameMap { + 'md-supporting-pane': MDSupportingPane; + } +} + +/** + * @final + * @suppress {visibility} + */ +@customElement('md-supporting-pane') +export class MDSupportingPane extends SupportingPane { + static override styles = [styles]; +}