Stories viewer <l-stories-viewer>
The fullscreen modal that plays a sequence of <l-story> videos. Linked to one or more <l-stories> rows via matching id ↔ for. See Stories for the full composition pattern, examples, and accessibility notes.
HTML tag
<l-stories-viewer>⏣Native
⬡Progressive
◇Plain
⬢Shadow-DOM
Shadow-DOM Custom Element
API reference
Importing
js
import 'luxen-ui/stories-viewer';Attributes & Properties
openbooleandefault:falseProperty- Whether the viewer is open.
indexnumberdefault:0Property- Active story index (0-based).
mutedbooleandefault:trueProperty- Whether playback is muted. so autoplay always succeeds across browsers. The user can unmute via the dedicated button or the
mkeyboard shortcut. loopbooleandefault:falseProperty- Loop the active story instead of advancing.
auto-advancebooleandefault:trueProperty- Move to the next story when the current one ends; close after the last story.
light-dismissbooleandefault:trueProperty- Close when the backdrop is clicked.
chapternumberdefault:0Property- Active chapter index within the current story. Reflected.
storiesLuxenStory[]default:[]Property- Internal: the playlist set by the source
<l-stories>. sourceLuxenStories | nulldefault:nullProperty- Internal: the source
<l-stories>element that opened the viewer.
Methods
openAt(stories: LuxenStory[], index: unknown, source: LuxenStories | null)Method- Open the viewer at the given index with an explicit playlist.
close()Methodnext()Method- Advance one chapter, or to the next story at the chapter boundary.
previous()Method- Retreat one chapter, restart the current chapter past 1s in, or cross into the previous story.
nextStory()Method- Jump to the next story, skipping any remaining chapters in the current story.
previousStory()Method- Jump to the previous story regardless of current chapter. Lands on chapter 0 of the previous story.
play()Methodpause()Method
Events
showcancelableEvent- Fired when the viewer is about to open. Cancelable — call
event.preventDefault()to keep it closed. after-showEvent- Fired after the open transition completes. Not cancelable.
hidecancelableEvent- Fired when the viewer is about to close. Cancelable.
after-hideEvent- Fired after the close transition completes. Not cancelable.
story-changeEvent- Fired when the active story changes. Properties:
index: number,story: LuxenStory. story-endEvent- Fired when the active story finishes playback. Properties:
index: number. chapter-changeEvent- Fired when the active chapter (within a story) changes. Properties:
chapter: number,story: LuxenStory. mute-changeEvent- Fired when the mute state changes. Properties:
muted: boolean.
Slots
ctaSlot- Default CTA overlay (e.g. shoppable card). Per-story
slot="cta"inside<l-story>overrides this when that story is active. headerSlot- Default header overlay (e.g. avatar + author). Per-story override available the same way.
closeSlot- Override the default close button.
CSS parts
dialogPart- The native
<dialog>element. framePart- The aspect-ratio video frame.
progressPart- The progress bar wrapper.
progress-segmentPart- A single progress segment.
progress-fillPart- The fill element inside an active segment.
videoPart- The
<video>element. overlayPart- The overlay wrapper that hosts CTA/header slots.
headerPart- The top-left header area (story thumbnail + label fallback, or consumer-supplied content via the
headerslot). header-labelPart- The default story label inside the header.
actionsPart- The top-right vertical button stack (close, play/pause, mute).
button-closePart- The close button.
button-pausePart- The play/pause toggle.
button-mutePart- The mute toggle.
button-previousPart- The previous story button.
button-nextPart- The next story button.
spinnerPart- The loading spinner shown while the current video is buffering.
CSS custom properties
--widthdefault:min(420px, 100vw)Custom property- Frame width.
--progress-colordefault:whiteCustom property- Active progress fill color.
--progress-bgdefault:rgb(255 255 255 / 35%)Custom property- Inactive progress segment background.
--progress-gapdefault:4pxCustom property- Gap between segments.
--show-durationdefault:200msCustom property- Open transition duration.
--hide-durationdefault:200msCustom property- Close transition duration.
--backdropdefault:var(--l-backdrop-strong)Custom property- Backdrop color. — darker than
--l-backdropto focus attention on the immersive frame, but still translucent so the page stays perceptible.
To change the frame ratio (e.g. 4/5 or 1/1), target the frame part:
css
l-stories-viewer::part(frame) {
aspect-ratio: 4/5;
}The <video> defaults to object-fit: cover so portrait videos fill the 9/16 frame edge-to-edge. For mixed catalogs with landscape or square videos, switch to contain to letterbox instead of cropping:
css
l-stories-viewer::part(video) {
object-fit: contain;
}