Material Next
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.

Each card hosts a sample screen with ScreenHost; the toggles report events that the page applies.
<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&amp;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 the mnw-mount--fill rule that installHubStyles() adds; ScreenHost sets that class when fill is 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.

<mnw-screen-card> properties
PropertyAttributeTypeDefaultDescription
headingheadingstring''The screen's title, linked to href.
descriptiondescriptionstring''One or two sentences under the title.
tagtagstring''Short category label.
hrefhrefstring''The prototype page for this screen.
framedframedbooleanfalseThe preview is inside a device frame.
darkdarkbooleanfalseState of the dark theme toggle.
threeButtonthree-buttonbooleanfalseState of the 3-button navigation toggle.
<mnw-screen-card> events
EventDescription
card-theme-toggle{selected}: dark theme on this card only.
card-nav-toggle{selected}: 3-button navigation on this card only.
<mnw-screen-card> slots
SlotDescription
DefaultThe screen's mount element.
<mnw-screen-card> CSS custom properties
Custom propertyDescription
--mnw-card-preview-heightHeight of a frameless preview. Default clamp(560px, 75dvh, 760px).
--mnw-card-device-zoomScale of a framed preview. Default 0.66.
--mnw-card-indexPosition 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 href there is no Open button and the heading is plain text.
  • The toggles only report; nothing changes until you set dark or three-button and update the screen.
mail