Screen card
A catalog card with a live app screen as its media, per-card theme and navigation toggles, and an Open action.
import 'material-next-web-components/marketing.js';On this page
Overview
<mnw-screen-card> presents one app screen in a catalog: the running screen fills the card's media area (or sits in a device frame), with the title, a category tag, a description, toggles for dark theme and 3-button navigation on that card only, and an Open button to the prototype page.
The card does not render the screen. Its default slot takes the element your screen renders into, usually through a ScreenHost. The slot stays in light DOM, so the app's own CSS and palettes reach the screen.
Live demo
Toggle a card's theme or navigation.
<mnw-screen-card
heading="Notes"
description="The home screen: every note, with a Pinned filter."
tag="Notes"
href="../../demos/marketing-hub/screen.html?id=notes"
style="--mnw-card-preview-height: 620px"
><div class="card-screen" data-screen="notes"></div></mnw-screen-card>
<mnw-screen-card
heading="Focus timer"
description="Framed: the screen inside the Pixel 9 Pro XL."
tag="Focus"
href="../../demos/marketing-hub/screen.html?id=focus&frame=device"
framed
><div class="card-screen" data-screen="focus"></div></mnw-screen-card>
<p class="demo-log" aria-live="polite">Toggle a card's theme or navigation.</p>import {ScreenHost, createScreenRegistry} from 'material-next-web-components/marketing.js';
import type {MaterialNextScreenCard} from 'material-next-web-components/marketing.js';
import {SCREENS} from '../sample-app/screens.js';
const registry = createScreenRegistry(SCREENS);
export default (root: HTMLElement) => {
const log = root.querySelector('.demo-log')!;
const hosts: ScreenHost[] = [];
for (const card of root.querySelectorAll<MaterialNextScreenCard>(
'mnw-screen-card'
)) {
const el = card.querySelector<HTMLElement>('.card-screen')!;
// The card is only the frame around the preview: the app's screen renders
// into the slotted element, here through a ScreenHost.
const host = new ScreenHost(el, {
registry,
id: el.dataset.screen!,
frame: card.framed,
fill: !card.framed,
});
hosts.push(host);
card.addEventListener('card-theme-toggle', (event) => {
card.dark = event.detail.selected;
host.setOptions({theme: card.dark ? 'dark' : 'light'});
log.textContent = `card-theme-toggle: ${card.heading} dark = ${card.dark}`;
});
card.addEventListener('card-nav-toggle', (event) => {
card.threeButton = event.detail.selected;
host.setOptions({navType: card.threeButton ? 'buttons' : 'gesture'});
log.textContent = `card-nav-toggle: ${card.heading} 3-button = ${card.threeButton}`;
});
}
return () => hosts.forEach((host) => host.destroy());
};Usage
The card is controlled: the toggles fire card-theme-toggle and card-nav-toggle with {selected}, and you set dark or three-button and update the screen. mountMarketingGallery() does all of this for every card.
- Frameless (default): the slotted element fills the media area. Its height is
--mnw-card-preview-height. For the screen inside to fill it too, the element needs themnw-mount--fillrule thatinstallHubStyles()adds;ScreenHostsets that class whenfillis on. framed: the slotted element (a device frame) is centred on a pedestal and scaled by--mnw-card-device-zoom.
API
One screen in the catalog. The live screen goes in the default slot and stays in light DOM, so the app's own CSS and palette reach it.
| Property | Attribute | Type | Default | Description |
|---|---|---|---|---|
heading | heading | string | '' | The screen's title, linked to href. |
description | description | string | '' | One or two sentences under the title. |
tag | tag | string | '' | Short category label. |
href | href | string | '' | The prototype page for this screen. |
framed | framed | boolean | false | The preview is inside a device frame. |
dark | dark | boolean | false | State of the dark theme toggle. |
threeButton | three-button | boolean | false | State of the 3-button navigation toggle. |
| Event | Description |
|---|---|
card-theme-toggle | {selected}: dark theme on this card only. |
card-nav-toggle | {selected}: 3-button navigation on this card only. |
| Slot | Description |
|---|---|
| Default | The screen's mount element. |
| Custom property | Description |
|---|---|
--mnw-card-preview-height | Height of a frameless preview. Default clamp(560px, 75dvh, 760px). |
--mnw-card-device-zoom | Scale of a framed preview. Default 0.66. |
--mnw-card-index | Position in the grid, staggering the entrance animation (capped at 6). |
Accessibility
- The media area is a group named "heading live preview"; the screen inside stays interactive.
- The heading links to
href, as does the Open button; both are keyboard reachable. - Each toggle has its own name ("Dark theme for Notes"); the selected state uses a filled icon, not colour alone.
Limitations
- Without
hrefthere is no Open button and the heading is plain text. - The toggles only report; nothing changes until you set
darkorthree-buttonand update the screen.