diff --git a/src/components/drawer.ts b/src/components/drawer.ts index c296dffb..a969664c 100644 --- a/src/components/drawer.ts +++ b/src/components/drawer.ts @@ -36,6 +36,9 @@ export class AdvancedCameraCardDrawer extends LitElement { @property({ type: Boolean, reflect: true, attribute: true }) public open = false; + @property({ type: Boolean, reflect: true, attribute: true }) + public locked?: boolean; + @property({ attribute: false, hasChanged: contentsChanged }) public icons?: DrawerIcons; @@ -68,6 +71,12 @@ export class AdvancedCameraCardDrawer extends LitElement { this._refDrawer.value?.shadowRoot?.appendChild(style); } + protected willUpdate(): void { + if (this.locked && this.open) { + this.open = false; + } + } + private _slotChanged(): void { const children = this._refSlot.value ? getChildrenFromElement(this._refSlot.value) @@ -113,6 +122,13 @@ export class AdvancedCameraCardDrawer extends LitElement {
{ + // While locked the drawer must not open. Return before + // `stopEventFromActivatingCardWideActions` so a click on the + // padded control wrapper is not swallowed and can still fall + // through to card-wide actions. + if (this.locked) { + return; + } stopEventFromActivatingCardWideActions(ev); this.open = !this.open; }} diff --git a/src/components/surround-basic.ts b/src/components/surround-basic.ts index cd24168f..97fb15e1 100644 --- a/src/components/surround-basic.ts +++ b/src/components/surround-basic.ts @@ -18,6 +18,9 @@ export class AdvancedCameraCardSurroundBasic extends LitElement { right?: DrawerIcons; }; + @property({ attribute: false }) + public locked?: boolean; + private _refDrawerLeft: Ref = createRef(); private _refDrawerRight: Ref = createRef(); private _boundDrawerHandler = this._drawerHandler.bind(this); @@ -57,6 +60,7 @@ export class AdvancedCameraCardSurroundBasic extends LitElement { ${ref(this._refDrawerLeft)} location="left" .icons=${this.drawerIcons?.left} + .locked=${this.locked} > @@ -64,6 +68,7 @@ export class AdvancedCameraCardSurroundBasic extends LitElement { ${ref(this._refDrawerRight)} location="right" .icons=${this.drawerIcons?.right} + .locked=${this.locked} > diff --git a/src/components/surround.ts b/src/components/surround.ts index 8b6616eb..6018f144 100644 --- a/src/components/surround.ts +++ b/src/components/surround.ts @@ -90,6 +90,7 @@ export class AdvancedCameraCardSurround extends LitElement { }; return html` changeDrawer(ev, 'close')} > diff --git a/src/scss/drawer.scss b/src/scss/drawer.scss index dde60307..703b0a74 100644 --- a/src/scss/drawer.scss +++ b/src/scss/drawer.scss @@ -1,3 +1,5 @@ +@use 'locked.scss'; + $drawer-icon-size: 20px; $drawer-padding-extend: 20px; @@ -47,6 +49,12 @@ advanced-camera-card-icon.control { transition: opacity 0.5s ease; } +// While locked, the control is dimmed and non-interactive. Applied to the +// control rather than `:host` so the drawer's slotted content is unaffected. +:host([locked]) advanced-camera-card-icon.control { + @include locked.style; +} + :host([location='left']) advanced-camera-card-icon.control { border-top-right-radius: $drawer-icon-size; border-bottom-right-radius: $drawer-icon-size; diff --git a/src/scss/locked.scss b/src/scss/locked.scss index 6e69aba3..dd0c0f7f 100644 --- a/src/scss/locked.scss +++ b/src/scss/locked.scss @@ -1,8 +1,7 @@ -// Shared styling for components that reflect a `locked` host attribute (set by -// Lit when the consumer-facing `locked` property is true). Dims the host and -// disables pointer interaction without removing it from layout, so the element -// stays in place during mic mute/unmute transitions. -:host([locked]) { +// The shared definition of the "locked" appearance: dimmed and +// non-interactive, without removing the element from layout (so it holds its +// place during lock/unlock transitions). +@mixin style { opacity: 0.4; pointer-events: none; } diff --git a/src/scss/next-previous-control.scss b/src/scss/next-previous-control.scss index 3afd6b36..ec7d84d2 100644 --- a/src/scss/next-previous-control.scss +++ b/src/scss/next-previous-control.scss @@ -1,4 +1,5 @@ @use './button.scss'; +@use './locked.scss'; :host { --advanced-camera-card-next-prev-size: 48px; @@ -23,15 +24,14 @@ right: var(--advanced-camera-card-right-position); } -// Dim while locked. Deliberately applied to `.controls` rather than `:host` -// (as the shared `locked.scss` does): `opacity` on the host would create a -// stacking context that traps `.controls`'s `z-index`, dropping the control -// behind the media whenever it is DOM-ordered before it (the left control). -// `.controls` is already positioned and z-indexed, so dimming it here leaves -// its stacking context intact. +// Dim while locked. Deliberately applied to `.controls` rather than `:host`: +// `opacity` on the host would create a stacking context that traps +// `.controls`'s `z-index`, dropping the control behind the media whenever it +// is DOM-ordered before it (the left control). `.controls` is already +// positioned and z-indexed, so dimming it here leaves its stacking context +// intact. :host([locked]) .controls { - opacity: 0.4; - pointer-events: none; + @include locked.style; } .controls.icons { diff --git a/src/scss/thumbnail-carousel.scss b/src/scss/thumbnail-carousel.scss index 95e9d5a8..b89a6d16 100644 --- a/src/scss/thumbnail-carousel.scss +++ b/src/scss/thumbnail-carousel.scss @@ -1,6 +1,10 @@ @use 'const.scss'; @use 'locked.scss'; +:host([locked]) { + @include locked.style; +} + :host { display: block; width: 100%; diff --git a/src/scss/timeline-core.scss b/src/scss/timeline-core.scss index 1bf0d3e1..48e98846 100644 --- a/src/scss/timeline-core.scss +++ b/src/scss/timeline-core.scss @@ -3,6 +3,10 @@ @use 'const.scss'; @use 'locked.scss'; +:host([locked]) { + @include locked.style; +} + :host { width: 100%; // Share the screen space with thumbnails that may be above/below.