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.