From 44306be23af80d1e08e22f516ed0dd044ba8880b Mon Sep 17 00:00:00 2001 From: Quinton Wehby Date: Wed, 14 Jan 2026 15:17:03 -0500 Subject: [PATCH 1/2] expose onUserAction via ref in UiContainer --- .../components/uicontroller/UiContainer.tsx | 26 ++++++++++++++++--- 1 file changed, 23 insertions(+), 3 deletions(-) diff --git a/src/ui/components/uicontroller/UiContainer.tsx b/src/ui/components/uicontroller/UiContainer.tsx index b7fabe2..ba591b8 100644 --- a/src/ui/components/uicontroller/UiContainer.tsx +++ b/src/ui/components/uicontroller/UiContainer.tsx @@ -1,4 +1,4 @@ -import React, { ReactNode, useCallback, useEffect, useRef, useState } from 'react'; +import React, { ReactNode, useCallback, useEffect, useRef, useState, useImperativeHandle, forwardRef } from 'react'; import { Animated, AppState, Platform, StyleProp, View, ViewStyle } from 'react-native'; import { PlayerContext } from '../util/PlayerContext'; import { type TVOSEvent, useTVOSEventHandler } from '../util/TVUtils'; @@ -93,6 +93,17 @@ export interface UiContainerProps { children?: never; } +/** + * Ref interface for UiContainer, exposing methods to interact with the UI from parent components. + */ +export interface UiContainerRef { + /** + * Programmatically triggers the UI fade-in animation. + * Useful for showing the UI in response to external events (e.g., keyboard shortcuts). + */ + onUserAction: () => void; +} + /** * The default style for a fullscreen centered view. */ @@ -176,7 +187,7 @@ const WEB_POINTER_MOVE_THROTTLE = 500; * - It provides slots for UI components to be places in the top/center/bottom positions. * - It uses animations to fade the UI in and out when applicable. */ -export const UiContainer = (props: UiContainerProps) => { +export const UiContainer = forwardRef((props, ref) => { const _currentFadeOutTimeout = useRef(undefined); const fadeAnimation = useRef(new Animated.Value(1)).current; const [currentMenu, setCurrentMenu] = useState(undefined); @@ -372,6 +383,15 @@ export const UiContainer = (props: UiContainerProps) => { fadeInUI_(); }, [fadeInUI_, didPlay]); + // Expose onUserAction_ to parent components via ref + useImperativeHandle( + ref, + () => ({ + onUserAction: onUserAction_, + }), + [onUserAction_], + ); + /** * On Web platform, use (throttled) pointer moves on the root container to enable showing/hiding instead of the UI container. * If an ad is playing, the UI should pass through all pointer events ("box-none") in order for ad clickThrough to work. @@ -473,4 +493,4 @@ export const UiContainer = (props: UiContainerProps) => { ); -}; +}); From 225caefe245066be867b318c62970a10272c5c0f Mon Sep 17 00:00:00 2001 From: Tom Van Laerhoven Date: Mon, 26 Jan 2026 10:57:04 +0100 Subject: [PATCH 2/2] Add changeset entry --- .changeset/chatty-teams-open.md | 5 +++++ 1 file changed, 5 insertions(+) create mode 100644 .changeset/chatty-teams-open.md diff --git a/.changeset/chatty-teams-open.md b/.changeset/chatty-teams-open.md new file mode 100644 index 0000000..7c022ad --- /dev/null +++ b/.changeset/chatty-teams-open.md @@ -0,0 +1,5 @@ +--- +'@theoplayer/react-native-ui': minor +--- + +Exposed `onUserAction()` via a ref in `UiContainer`, enabling parent components to programmatically trigger the UI fade-in animation.