Thanks to visit codestin.com
Credit goes to github.com

Skip to content

fix(studio): support web-component refs in useTimelinePlayer - #245

Merged
miguel-heygen merged 2 commits into
mainfrom
fix/timeline-seek-web-component
Apr 13, 2026
Merged

miguel-heygen merged 2 commits into
mainfrom
fix/timeline-seek-web-component

Conversation

@miguel-heygen

@miguel-heygen miguel-heygen commented Apr 13, 2026

Copy link
Copy Markdown
Collaborator

Problem

The studio's useTimelinePlayer hook returns an iframeRef that consumers attach to an <iframe> element. When consumers wrap the iframe in a custom element (e.g. <hyperframes-player>) that puts the iframe inside its shadow DOM, every iframeRef.current.contentWindow access returned null and getAdapter() silently failed — meaning timeline seek, play, pause, and refreshPlayer all became no-ops.

Solution

  • Add resolveIframe(el) helper that returns the underlying iframe whether the host is:
    • The iframe element itself (existing behavior)
    • A custom element with a shadow-DOM iframe
    • A wrapper element with a descendant iframe
  • Export resolveIframe from the studio so consumers can pre-resolve the iframe before assigning to iframeRef.
  • Internal useTimelinePlayer code keeps the strict HTMLIFrameElement ref type — no breaking change.

Docs

  • docs/packages/player.mdx — new "Advanced: iframe access" section showing the resolveIframe pattern + a <Warning> callout for the silent-no-op gotcha.
  • packages/player/README.md — same content for the npm package page.
  • packages/player/src/hyperframes-player.ts — JSDoc on the iframeElement getter so IDE hover surfaces the correct vs incorrect usage.

Type-safety housekeeping

  • .oxlintrc.json — enable no-explicit-any, no-unnecessary-type-assertion, prefer-as-const (error) and no-non-null-assertion, no-confusing-non-null-assertion (warn).
  • CONTRIBUTING.md — new "Type-safety conventions" subsection codifying the project's stance on as casts and ! non-null assertions.

Backward compatibility

Fully backward compatible — existing code attaching the ref to a regular <iframe> (App.tsx, NLELayout.tsx) continues to work unchanged.

Test plan

  • pnpm build succeeds for studio package
  • Existing studio (App.tsx, NLELayout.tsx) still compiles
  • oxlint passes on the changed files
  • Verify timeline seek drives the player when consumed via <hyperframes-player> JSX ref

@miguel-heygen
miguel-heygen force-pushed the fix/timeline-seek-web-component branch 6 times, most recently from 4348e11 to 866abf0 Compare April 13, 2026 15:12
The studio's `useTimelinePlayer` hook returns an `iframeRef` that
consumers attach to an `<iframe>` element. When consumers wrap the
iframe in a custom element (e.g. `<hyperframes-player>`) that puts
the iframe inside its shadow DOM, every `iframeRef.current.contentWindow`
access returned `null` and `getAdapter()` silently failed — meaning
timeline seek, play, pause, and `refreshPlayer` all became no-ops.

Changes:
- Add `resolveIframe(el)` helper that returns the underlying iframe
  whether the host is the iframe itself, a custom element with a
  shadow-DOM iframe, or a wrapper with a descendant iframe.
- Export `resolveIframe` from the studio so consumers can pre-resolve
  the iframe before assigning it to `iframeRef`.
- Internal `useTimelinePlayer` keeps the strict `HTMLIFrameElement`
  ref type, so existing consumers attaching directly to an `<iframe>`
  are unaffected.

Also adds:
- JSDoc on the player's `iframeElement` getter.
- "Advanced: iframe access" docs section in `packages/player/README.md`
  and `docs/packages/player.mdx`.
- Type-safety lint rules in `.oxlintrc.json` and a "Type-safety
  conventions" section in `CONTRIBUTING.md`.

Backward compatible — App.tsx and NLELayout.tsx continue to work
unchanged.
@miguel-heygen
miguel-heygen force-pushed the fix/timeline-seek-web-component branch from 866abf0 to 04db9f0 Compare April 13, 2026 15:15
The new rules added 37 errors across 32 existing files — mostly
legitimate `window as any` casts at browser-global and test-mock
boundaries. Enabling them without fixing all violations breaks CI.

Revert the `.oxlintrc.json` additions and soften the CONTRIBUTING.md
wording to describe the convention without claiming lint enforcement
(that enforcement will come in a follow-up PR that fixes all sites).
@miguel-heygen
miguel-heygen merged commit 1149602 into main Apr 13, 2026
14 checks passed
@miguel-heygen
miguel-heygen deleted the fix/timeline-seek-web-component branch April 13, 2026 15:53
dahans-msft2 pushed a commit to dahans-msft2/hyperframes that referenced this pull request Aug 6, 2026
…com#245)

* fix(studio): support web-component refs in useTimelinePlayer

The studio's `useTimelinePlayer` hook returns an `iframeRef` that
consumers attach to an `<iframe>` element. When consumers wrap the
iframe in a custom element (e.g. `<hyperframes-player>`) that puts
the iframe inside its shadow DOM, every `iframeRef.current.contentWindow`
access returned `null` and `getAdapter()` silently failed — meaning
timeline seek, play, pause, and `refreshPlayer` all became no-ops.

Changes:
- Add `resolveIframe(el)` helper that returns the underlying iframe
  whether the host is the iframe itself, a custom element with a
  shadow-DOM iframe, or a wrapper with a descendant iframe.
- Export `resolveIframe` from the studio so consumers can pre-resolve
  the iframe before assigning it to `iframeRef`.
- Internal `useTimelinePlayer` keeps the strict `HTMLIFrameElement`
  ref type, so existing consumers attaching directly to an `<iframe>`
  are unaffected.

Also adds:
- JSDoc on the player's `iframeElement` getter.
- "Advanced: iframe access" docs section in `packages/player/README.md`
  and `docs/packages/player.mdx`.
- Type-safety lint rules in `.oxlintrc.json` and a "Type-safety
  conventions" section in `CONTRIBUTING.md`.

Backward compatible — App.tsx and NLELayout.tsx continue to work
unchanged.

* chore(lint): defer no-explicit-any rule; it broke existing codebase

The new rules added 37 errors across 32 existing files — mostly
legitimate `window as any` casts at browser-global and test-mock
boundaries. Enabling them without fixing all violations breaks CI.

Revert the `.oxlintrc.json` additions and soften the CONTRIBUTING.md
wording to describe the convention without claiming lint enforcement
(that enforcement will come in a follow-up PR that fixes all sites).
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant