Skip to content

feat: Add Fullscreen API wrapping the browser Fullscreen API#24326

Open
Artur- wants to merge 5 commits into
mainfrom
feature/fullscreen
Open

feat: Add Fullscreen API wrapping the browser Fullscreen API#24326
Artur- wants to merge 5 commits into
mainfrom
feature/fullscreen

Conversation

@Artur-
Copy link
Copy Markdown
Member

@Artur- Artur- commented May 12, 2026

Adds Component.requestFullscreen() that uses a wrapper approach to handle
Vaadin theming and overlay components correctly, along with
Page.requestFullscreen() for whole-page fullscreen, Page.exitFullscreen(),
and Page.fullscreenSignal() for reactive observation of the fullscreen
state (FULLSCREEN, NOT_FULLSCREEN, UNSUPPORTED, UNKNOWN).

The signal is seeded from the initial client bootstrap (v-fs parameter)
and updated via a vaadin-fullscreen-change DOM event, mirroring the
page-visibility wiring.

Artur- added 3 commits May 11, 2026 09:06
Adds Component.requestFullscreen() that uses a wrapper approach to handle
Vaadin theming and overlay components correctly, along with
Page.requestFullscreen() for whole-page fullscreen, Page.exitFullscreen(),
and Page.fullscreenSignal() for reactive observation of the fullscreen
state (FULLSCREEN, NOT_FULLSCREEN, UNSUPPORTED, UNKNOWN).

The signal is seeded from the initial client bootstrap (v-fs parameter)
and updated via a vaadin-fullscreen-change DOM event, mirroring the
page-visibility wiring. The client-side bridge lives in
flow-client/src/main/frontend/Fullscreen.ts, imported from Flow.ts the
same way Geolocation.ts is.

Fixes #21902
The file already has an exported function (currentFullscreenState), so
the trailing `export {}` is flagged by
@typescript-eslint/no-useless-empty-export and breaks the flow-client
build.
Reworks the Fullscreen API based on API-GAPS feedback:

- Page.requestFullscreen() and Component.requestFullscreen() now return
  a FullscreenSession with a state signal carrying PENDING / ACTIVE /
  REJECTED / EXITED_BY_USER / EXITED_BY_CODE. This covers three gaps in
  one shape: which component is fullscreen (session.owner()), how the
  session ended (terminal state), and whether the browser accepted the
  request (PENDING -> ACTIVE or REJECTED).

- The JS connector now returns { ok, error? } from each request so
  rejections (no user activation, permissions policy, document detached,
  fullscreen unsupported) reach the server and are logged at WARN level
  with the browser-provided message.

- Page#requestFullscreen(Component) overload lets code that already
  holds a Page reference start a component session without reaching
  through the component.

- Component#exitFullscreen() restores symmetry with requestFullscreen(),
  delegating to Page#exitFullscreen() so component code does not need
  to reach for getUI().getPage().

- Page#simulateFullscreenChange(FullscreenState) exposes a public
  test-only seam so downstream tests no longer have to reflect into the
  package-private setter.

- Javadoc on Page#fullscreenSignal() and Page#requestFullscreen() now
  carries worked binding / lifecycle examples.

The page-level Page#fullscreenSignal() is unchanged: it answers the
broad "is anything fullscreen right now" question across sessions.
@github-actions
Copy link
Copy Markdown

github-actions Bot commented May 12, 2026

Test Results

 1 408 files  + 2   1 408 suites  +2   1h 21m 45s ⏱️ -44s
10 159 tests +20  10 089 ✅ +20  70 💤 ±0  0 ❌ ±0 
10 634 runs  +20  10 555 ✅ +20  79 💤 ±0  0 ❌ ±0 

Results for commit b65531b. ± Comparison against base commit 32183d1.

♻️ This comment has been updated with latest results.

Artur- added 2 commits May 12, 2026 16:59
Javadoc rejects H2 inside a method comment because the surrounding
context already uses H3, breaking attach-javadocs in the unit-tests (3)
shard. Switch to the <p><b>...</b></p> pattern Geolocation uses, which
renders the same in javadoc output.
Replaces the toggle-button example on Page#fullscreenSignal() with the
two patterns most useful in practice — bindClassName for declarative CSS
toggling while fullscreen, and Signal.effect for side-effecting reactions
such as hiding a button when fullscreen is UNSUPPORTED. The toggle-button
example was correct but covered three patterns at once; downstream use
cases (chart card expand, "fullscreen unavailable" empty states) needed
the focused shapes instead.
@sonarqubecloud
Copy link
Copy Markdown

Artur- added a commit to vaadin/use-cases that referenced this pull request May 13, 2026
Adds a sibling `fullscreen` module mirroring `geolocation` and
`page-visibility`, demonstrating Component#requestFullscreen(),
Page#requestFullscreen(), Page#fullscreenSignal(), FullscreenSession
and Component#exitFullscreen() across six self-contained views:
- image lightbox using per-component fullscreen (UC1)
- slideshow / presentation via Page#requestFullscreen() (UC2)
- distraction-free editor exiting through Component#exitFullscreen() (UC3)
- reactive layout bound directly to fullscreenSignal() (UC4)
- kiosk exit detection via FullscreenSession state (UC5)
- chart expand using session.owner() to scope the active card (UC6)

Pinned to flow 25.2.fullscreen-SNAPSHOT (vaadin/flow#24326) until the
API lands in mainline. Remaining API gaps surfaced during the work are
recorded in fullscreen/API-GAPS.md.
@Artur-
Copy link
Copy Markdown
Member Author

Artur- commented May 15, 2026

This should be based on trigger/action type API

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

Projects

Status: 🔎Iteration reviews

Development

Successfully merging this pull request may close these issues.

2 participants