@roku-sdk/components 0.0.0-stage → 2.18.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/BREAKING_CHANGES.md +84 -0
- package/LICENSE +21 -0
- package/README.md +19 -2
- package/core-jsx.d.ts +53 -0
- package/eslint.config.mjs +3 -0
- package/jsx.d.ts +273 -0
- package/package.json +84 -3
- package/src/__tests__/container.test.tsx +150 -0
- package/src/__tests__/glyphs.test.ts +202 -0
- package/src/__tests__/modal-boundary-export.test.ts +12 -0
- package/src/__tests__/native-modal.test.tsx +224 -0
- package/src/__tests__/tween-release.test.tsx +125 -0
- package/src/__tests__/tween-stops-shape.test.tsx +165 -0
- package/src/__tests__/tween-without-compat.test.tsx +64 -0
- package/src/__tests__/tween.test.tsx +195 -0
- package/src/blended-busy-spinner.props.ts +37 -0
- package/src/blended-busy-spinner.tsx +13 -0
- package/src/bounding-tracker.props.ts +18 -0
- package/src/bounding-tracker.tsx +13 -0
- package/src/button-row.tsx +126 -0
- package/src/channel-store.props.ts +425 -0
- package/src/channel-store.tsx +76 -0
- package/src/container.tsx +130 -0
- package/src/core/jsx-runtime.ts +39 -0
- package/src/focusable-group.props.ts +8 -0
- package/src/focusable-group.tsx +17 -0
- package/src/focusable.props.ts +14 -0
- package/src/focusable.tsx +17 -0
- package/src/glyphs.ts +116 -0
- package/src/helpers/index.tsx +4 -0
- package/src/helpers/resolution-context.tsx +68 -0
- package/src/helpers/scale-for-device-resolution.ts +31 -0
- package/src/index.tsx +70 -0
- package/src/jsx-props.ts +87 -0
- package/src/kdfs.d.ts +14 -0
- package/src/kdfs.ts +15 -0
- package/src/key-handler.props.ts +33 -0
- package/src/key-handler.tsx +24 -0
- package/src/modal-dialog.props.ts +38 -0
- package/src/modal-dialog.tsx +41 -0
- package/src/retain-asset.ts +24 -0
- package/src/sg-intrinsics.json +1153 -0
- package/src/sg-nodes/__tests__/__snapshots__/font.test.tsx.snap +13 -0
- package/src/sg-nodes/__tests__/__snapshots__/prop-forwarding.test.tsx.snap +4409 -0
- package/src/sg-nodes/__tests__/core-props.test.ts +301 -0
- package/src/sg-nodes/__tests__/font.test.tsx +141 -0
- package/src/sg-nodes/__tests__/imperative-methods.test.ts +268 -0
- package/src/sg-nodes/__tests__/prop-forwarding.test.tsx +1049 -0
- package/src/sg-nodes/__tests__/solid-integration.test.tsx +719 -0
- package/src/sg-nodes/animated-image.props.ts +64 -0
- package/src/sg-nodes/animated-image.tsx +23 -0
- package/src/sg-nodes/animation.props.ts +292 -0
- package/src/sg-nodes/animation.tsx +190 -0
- package/src/sg-nodes/array-grid.ts +602 -0
- package/src/sg-nodes/audio.props.ts +302 -0
- package/src/sg-nodes/audio.tsx +57 -0
- package/src/sg-nodes/busy-spinner.props.ts +59 -0
- package/src/sg-nodes/busy-spinner.tsx +84 -0
- package/src/sg-nodes/button-group.props.ts +141 -0
- package/src/sg-nodes/button-group.tsx +30 -0
- package/src/sg-nodes/button.props.ts +119 -0
- package/src/sg-nodes/button.tsx +31 -0
- package/src/sg-nodes/check-list.props.ts +71 -0
- package/src/sg-nodes/check-list.tsx +55 -0
- package/src/sg-nodes/content-node.props.ts +1316 -0
- package/src/sg-nodes/content-node.tsx +153 -0
- package/src/sg-nodes/core-props.ts +197 -0
- package/src/sg-nodes/custom-keyboard.props.ts +108 -0
- package/src/sg-nodes/custom-keyboard.tsx +48 -0
- package/src/sg-nodes/dialog.props.ts +159 -0
- package/src/sg-nodes/dialog.tsx +36 -0
- package/src/sg-nodes/dynamic-key-grid.props.ts +22 -0
- package/src/sg-nodes/dynamic-key-grid.tsx +16 -0
- package/src/sg-nodes/dynamic-keyboard.props.ts +30 -0
- package/src/sg-nodes/dynamic-keyboard.tsx +18 -0
- package/src/sg-nodes/dynamic-mini-keyboard.props.ts +22 -0
- package/src/sg-nodes/dynamic-mini-keyboard.tsx +18 -0
- package/src/sg-nodes/dynamic-pinpad.props.ts +57 -0
- package/src/sg-nodes/dynamic-pinpad.tsx +18 -0
- package/src/sg-nodes/effect.props.ts +116 -0
- package/src/sg-nodes/effect.tsx +39 -0
- package/src/sg-nodes/font.props.ts +45 -0
- package/src/sg-nodes/font.tsx +80 -0
- package/src/sg-nodes/group.props.ts +105 -0
- package/src/sg-nodes/group.tsx +30 -0
- package/src/sg-nodes/label-list.props.ts +86 -0
- package/src/sg-nodes/label-list.tsx +64 -0
- package/src/sg-nodes/label.props.ts +207 -0
- package/src/sg-nodes/label.tsx +56 -0
- package/src/sg-nodes/layout-group.props.ts +69 -0
- package/src/sg-nodes/layout-group.tsx +75 -0
- package/src/sg-nodes/list-panel.props.ts +104 -0
- package/src/sg-nodes/list-panel.tsx +49 -0
- package/src/sg-nodes/markup-grid.props.ts +78 -0
- package/src/sg-nodes/markup-grid.tsx +38 -0
- package/src/sg-nodes/markup-list.props.ts +68 -0
- package/src/sg-nodes/markup-list.tsx +38 -0
- package/src/sg-nodes/mask-group.props.ts +78 -0
- package/src/sg-nodes/mask-group.tsx +59 -0
- package/src/sg-nodes/media-playback-methods.ts +20 -0
- package/src/sg-nodes/node.ts +77 -0
- package/src/sg-nodes/overhang.props.ts +169 -0
- package/src/sg-nodes/overhang.tsx +29 -0
- package/src/sg-nodes/panel-set.props.ts +71 -0
- package/src/sg-nodes/panel-set.tsx +53 -0
- package/src/sg-nodes/panel.props.ts +176 -0
- package/src/sg-nodes/panel.tsx +56 -0
- package/src/sg-nodes/poster-grid.props.ts +277 -0
- package/src/sg-nodes/poster-grid.tsx +45 -0
- package/src/sg-nodes/poster.props.ts +125 -0
- package/src/sg-nodes/poster.tsx +44 -0
- package/src/sg-nodes/radio-button-list.props.ts +59 -0
- package/src/sg-nodes/radio-button-list.tsx +68 -0
- package/src/sg-nodes/rectangle.props.ts +29 -0
- package/src/sg-nodes/rectangle.tsx +27 -0
- package/src/sg-nodes/row-list.props.ts +288 -0
- package/src/sg-nodes/row-list.tsx +47 -0
- package/src/sg-nodes/scene.props.ts +65 -0
- package/src/sg-nodes/scene.tsx +15 -0
- package/src/sg-nodes/scrollable-text.props.ts +133 -0
- package/src/sg-nodes/scrollable-text.tsx +64 -0
- package/src/sg-nodes/scrolling-label.props.ts +106 -0
- package/src/sg-nodes/scrolling-label.tsx +42 -0
- package/src/sg-nodes/simple-label.props.ts +156 -0
- package/src/sg-nodes/simple-label.tsx +59 -0
- package/src/sg-nodes/sound-effect.props.ts +130 -0
- package/src/sg-nodes/sound-effect.tsx +65 -0
- package/src/sg-nodes/standard-dialog.props.ts +520 -0
- package/src/sg-nodes/standard-dialog.tsx +428 -0
- package/src/sg-nodes/standard-keyboard-dialog.props.ts +84 -0
- package/src/sg-nodes/standard-keyboard-dialog.tsx +59 -0
- package/src/sg-nodes/standard-message-dialog.props.ts +56 -0
- package/src/sg-nodes/standard-message-dialog.tsx +48 -0
- package/src/sg-nodes/standard-pinpad-dialog.props.ts +64 -0
- package/src/sg-nodes/standard-pinpad-dialog.tsx +46 -0
- package/src/sg-nodes/standard-progress-dialog.props.ts +30 -0
- package/src/sg-nodes/standard-progress-dialog.tsx +43 -0
- package/src/sg-nodes/target-group.props.ts +278 -0
- package/src/sg-nodes/target-group.tsx +63 -0
- package/src/sg-nodes/target-list.props.ts +128 -0
- package/src/sg-nodes/target-list.tsx +66 -0
- package/src/sg-nodes/target-set.props.ts +63 -0
- package/src/sg-nodes/target-set.tsx +42 -0
- package/src/sg-nodes/time-grid.props.ts +646 -0
- package/src/sg-nodes/time-grid.tsx +87 -0
- package/src/sg-nodes/tween.props.ts +115 -0
- package/src/sg-nodes/types.ts +150 -0
- package/src/sg-nodes/video.props.ts +573 -0
- package/src/sg-nodes/video.tsx +73 -0
- package/src/sg-nodes/voice-text-edit-box.props.ts +91 -0
- package/src/sg-nodes/voice-text-edit-box.tsx +15 -0
- package/src/sg-nodes/zoom-row-list.props.ts +416 -0
- package/src/sg-nodes/zoom-row-list.tsx +42 -0
- package/src/standard-dialog-next/__tests__/standard-dialog-next.test.tsx +186 -0
- package/src/standard-dialog-next/index.ts +5 -0
- package/src/standard-dialog-next/standard-dialog-next.props.ts +80 -0
- package/src/standard-dialog-next/standard-dialog-next.tsx +326 -0
- package/src/test-helpers/tween-test-setup.ts +78 -0
- package/src/tween.tsx +173 -0
- package/src/types.ts +8 -0
- package/src/xml-components/blended-busy-spinner/BlendedBusySpinner.brs +13 -0
- package/src/xml-components/blended-busy-spinner/BlendedBusySpinner.xml +10 -0
- package/src/xml-components/blended-busy-spinner/BlendedBusySpinner.xml.d.ts +42 -0
- package/src/xml-components/bounding-tracker/BoundingTracker.brs +26 -0
- package/src/xml-components/bounding-tracker/BoundingTracker.xml +14 -0
- package/src/xml-components/bounding-tracker/BoundingTracker.xml.d.ts +42 -0
- package/src/xml-components/channel-store/channelStoreExt.brs +159 -0
- package/src/xml-components/channel-store/channelStoreExt.xml +29 -0
- package/src/xml-components/channel-store/channelStoreExt.xml.d.ts +57 -0
- package/src/xml-components/focus/focusable-group.brs +251 -0
- package/src/xml-components/focus/focusable-group.xml +15 -0
- package/src/xml-components/focus/focusable-group.xml.d.ts +42 -0
- package/src/xml-components/focus/focusable.xml +18 -0
- package/src/xml-components/focus/focusable.xml.d.ts +48 -0
- package/src/xml-components/keyboards/CustomAddressKDF.keyboard.json +547 -0
- package/src/xml-components/keyboards/CustomKeyboard.brs +322 -0
- package/src/xml-components/keyboards/CustomKeyboard.xml +45 -0
- package/src/xml-components/keyboards/CustomKeyboard.xml.d.ts +73 -0
- package/src/xml-components/keyboards/KeyGridExt.xml +4 -0
- package/src/xml-components/keyboards/KeyGridExt.xml.d.ts +37 -0
- package/src/xml-components/keyboards/KeyboardExt.xml +4 -0
- package/src/xml-components/keyboards/KeyboardExt.xml.d.ts +37 -0
- package/src/xml-components/keyboards/MOPPinPadCustomKDF.keyboard.json +151 -0
- package/src/xml-components/keyboards/MiniKeyboardExt.xml +4 -0
- package/src/xml-components/keyboards/MiniKeyboardExt.xml.d.ts +37 -0
- package/src/xml-components/keyboards/PhonePadCustomKDF.keyboard.json +42 -0
- package/src/xml-components/keyboards/PinPadExt.brs +102 -0
- package/src/xml-components/keyboards/PinPadExt.xml +17 -0
- package/src/xml-components/keyboards/PinPadExt.xml.d.ts +49 -0
- package/src/xml-components/keyboards/WifiCustomKDF.keyboard.json +1242 -0
- package/src/xml-components/keyhandler/KeyHandler.brs +30 -0
- package/src/xml-components/keyhandler/KeyHandler.xml +16 -0
- package/src/xml-components/keyhandler/KeyHandler.xml.d.ts +45 -0
- package/src/xml-components/managed-list-panel/ManagedListPanel.brs +137 -0
- package/src/xml-components/managed-list-panel/ManagedListPanel.xml +10 -0
- package/src/xml-components/managed-list-panel/ManagedListPanel.xml.d.ts +37 -0
- package/src/xml-components/modal/Modal.brs +105 -0
- package/src/xml-components/modal/Modal.xml +22 -0
- package/src/xml-components/modal/Modal.xml.d.ts +54 -0
- package/src/xml-components/modal/StandardDialogExt.xml +10 -0
- package/src/xml-components/modal/StandardDialogExt.xml.d.ts +37 -0
- package/src/xml-components/modal/StandardKeyboardDialogExt.xml +10 -0
- package/src/xml-components/modal/StandardKeyboardDialogExt.xml.d.ts +37 -0
- package/src/xml-components/modal/StandardMessageDialogExt.xml +10 -0
- package/src/xml-components/modal/StandardMessageDialogExt.xml.d.ts +37 -0
- package/src/xml-components/modal/StandardPinPadDialogExt.xml +10 -0
- package/src/xml-components/modal/StandardPinPadDialogExt.xml.d.ts +37 -0
- package/src/xml-components/modal/StandardProgressDialogExt.xml +10 -0
- package/src/xml-components/modal/StandardProgressDialogExt.xml.d.ts +37 -0
- package/src/xml-components/modal/tests/Modal.test.brs +195 -0
- package/tsconfig.json +10 -0
|
@@ -0,0 +1,573 @@
|
|
|
1
|
+
// Copyright (c) 2026 Roku, Inc.
|
|
2
|
+
// SPDX-License-Identifier: MIT
|
|
3
|
+
|
|
4
|
+
import type { ComponentRef } from "@roku-sdk/interfaces";
|
|
5
|
+
|
|
6
|
+
import type { MediaControl, MediaState } from "../types";
|
|
7
|
+
import type { IGroupProps } from "./group.props";
|
|
8
|
+
import type { INodeProps } from "./node";
|
|
9
|
+
import type { EventHandler, JSX, Uri, Vector2D } from "./types";
|
|
10
|
+
|
|
11
|
+
/**
|
|
12
|
+
* Seek accuracy for the Video node `seekMode` field.
|
|
13
|
+
*
|
|
14
|
+
* @see {@link https://developer.roku.com/dev/docs/video}
|
|
15
|
+
*/
|
|
16
|
+
export enum VideoSeekMode {
|
|
17
|
+
Default = "default",
|
|
18
|
+
Accurate = "accurate"
|
|
19
|
+
}
|
|
20
|
+
|
|
21
|
+
/**
|
|
22
|
+
* HDR mode reported on `streamingSegment` (HLS/DASH).
|
|
23
|
+
*
|
|
24
|
+
* @see {@link https://developer.roku.com/dev/docs/video}
|
|
25
|
+
*/
|
|
26
|
+
export enum StreamingSegmentHdrMode {
|
|
27
|
+
Invalid = "invalid",
|
|
28
|
+
Unknown = "unknown",
|
|
29
|
+
None = "none",
|
|
30
|
+
Hdr10 = "hdr10",
|
|
31
|
+
DolbyVision = "dolby_vision",
|
|
32
|
+
Hlg10 = "hlg10",
|
|
33
|
+
SlHdr2 = "sl-hdr2"
|
|
34
|
+
}
|
|
35
|
+
|
|
36
|
+
/**
|
|
37
|
+
* Segment payload type from `streamingSegment.segTypeStr`.
|
|
38
|
+
*
|
|
39
|
+
* @see {@link https://developer.roku.com/dev/docs/video}
|
|
40
|
+
*/
|
|
41
|
+
export enum StreamingSegmentType {
|
|
42
|
+
Audio = "audio",
|
|
43
|
+
Video = "video",
|
|
44
|
+
Captions = "captions",
|
|
45
|
+
Mux = "mux"
|
|
46
|
+
}
|
|
47
|
+
|
|
48
|
+
/** HDR mode enum for `downloadedSegment` info. */
|
|
49
|
+
export const enum DownloadedSegmentHdrMode {
|
|
50
|
+
Unknown = 0,
|
|
51
|
+
None = 1,
|
|
52
|
+
Hdr10 = 2,
|
|
53
|
+
DolbyVision = 3,
|
|
54
|
+
Hlg10 = 4,
|
|
55
|
+
Hdr10Plus = 5,
|
|
56
|
+
SlHdr2 = 6
|
|
57
|
+
}
|
|
58
|
+
|
|
59
|
+
/**
|
|
60
|
+
* Global Roku closed-caption mode for the Video `globalCaptionMode` field.
|
|
61
|
+
*
|
|
62
|
+
* @see {@link https://developer.roku.com/dev/docs/video}
|
|
63
|
+
*/
|
|
64
|
+
export enum GlobalCaptionMode {
|
|
65
|
+
Off = "Off",
|
|
66
|
+
On = "On",
|
|
67
|
+
InstantReplay = "Instant replay",
|
|
68
|
+
WhenMute = "When mute"
|
|
69
|
+
}
|
|
70
|
+
|
|
71
|
+
/**
|
|
72
|
+
* Timing measurements related to the start of video playback (seconds unless noted).
|
|
73
|
+
*
|
|
74
|
+
* @see {@link https://developer.roku.com/dev/docs/video}
|
|
75
|
+
*/
|
|
76
|
+
export interface IPlayStartInfo {
|
|
77
|
+
total_dur: number;
|
|
78
|
+
manifest_dur: number;
|
|
79
|
+
drm_load_dur: number;
|
|
80
|
+
drm_lic_acq_dur: number;
|
|
81
|
+
prebuf_dur: number;
|
|
82
|
+
manifest_start: number;
|
|
83
|
+
drm_load_start: number;
|
|
84
|
+
drm_lic_acq_start: number;
|
|
85
|
+
prebuf_start: number;
|
|
86
|
+
}
|
|
87
|
+
|
|
88
|
+
/**
|
|
89
|
+
* DRM license acquisition status from the Video node.
|
|
90
|
+
*
|
|
91
|
+
* @see {@link https://developer.roku.com/dev/docs/video}
|
|
92
|
+
*/
|
|
93
|
+
export interface ILicenseStatus {
|
|
94
|
+
response: string;
|
|
95
|
+
status: string;
|
|
96
|
+
keysystem: string;
|
|
97
|
+
duration: string;
|
|
98
|
+
}
|
|
99
|
+
|
|
100
|
+
/** Alias for {@link MediaControl} used by the Video node `control` field. */
|
|
101
|
+
export type VideoControl = MediaControl;
|
|
102
|
+
|
|
103
|
+
/** Alias for {@link MediaState} from the Video node `state` field. */
|
|
104
|
+
export type VideoState = MediaState;
|
|
105
|
+
|
|
106
|
+
/**
|
|
107
|
+
* Structured error information from the Video node `errorInfo` field.
|
|
108
|
+
*
|
|
109
|
+
* @see {@link https://developer.roku.com/dev/docs/video}
|
|
110
|
+
*/
|
|
111
|
+
export interface VideoErrorInfo {
|
|
112
|
+
clipId: number;
|
|
113
|
+
ignored: number;
|
|
114
|
+
source: string;
|
|
115
|
+
category: string;
|
|
116
|
+
errcode: number;
|
|
117
|
+
dbgmsg: string;
|
|
118
|
+
drmerrcode: number;
|
|
119
|
+
}
|
|
120
|
+
|
|
121
|
+
/**
|
|
122
|
+
* Video decoder statistics when {@link IVideoPlaybackProps.enableDecoderStats} is true.
|
|
123
|
+
*
|
|
124
|
+
* @see {@link https://developer.roku.com/dev/docs/video}
|
|
125
|
+
*/
|
|
126
|
+
export interface IDecoderStats {
|
|
127
|
+
renderCount: number;
|
|
128
|
+
repeatCount: number;
|
|
129
|
+
frameDropCount: number;
|
|
130
|
+
streamErrorCount: number;
|
|
131
|
+
}
|
|
132
|
+
|
|
133
|
+
/**
|
|
134
|
+
* One playback action button on the pause screen.
|
|
135
|
+
*
|
|
136
|
+
* @see {@link https://developer.roku.com/dev/docs/video}
|
|
137
|
+
*/
|
|
138
|
+
export interface IPlaybackActionButton {
|
|
139
|
+
text?: string;
|
|
140
|
+
icon?: Uri;
|
|
141
|
+
focusIcon?: Uri;
|
|
142
|
+
buttonIsDisabled?: boolean;
|
|
143
|
+
}
|
|
144
|
+
|
|
145
|
+
/**
|
|
146
|
+
* One rule object in subtitle selection preferences (ordered highest to lowest significance).
|
|
147
|
+
*
|
|
148
|
+
* @see {@link https://developer.roku.com/dev/docs/video}
|
|
149
|
+
*/
|
|
150
|
+
export type SubtitleSelectionPreferenceRule =
|
|
151
|
+
{ language: string[] } | { caption: string } | { descriptive: string | string[] } | { easyReader: string };
|
|
152
|
+
|
|
153
|
+
/**
|
|
154
|
+
* Subtitle track selection preferences (Roku OS 12.5+).
|
|
155
|
+
*
|
|
156
|
+
* @see {@link https://developer.roku.com/dev/docs/video}
|
|
157
|
+
*/
|
|
158
|
+
export interface ISubtitleSelectionPreferences {
|
|
159
|
+
values: SubtitleSelectionPreferenceRule[];
|
|
160
|
+
overrideSystem: boolean;
|
|
161
|
+
}
|
|
162
|
+
|
|
163
|
+
/**
|
|
164
|
+
* One rule object in audio selection preferences (ordered highest to lowest significance).
|
|
165
|
+
*
|
|
166
|
+
* @see {@link https://developer.roku.com/dev/docs/video}
|
|
167
|
+
*/
|
|
168
|
+
export type AudioSelectionPreferenceRule = { language: string[] } | { descriptive: string | string[] };
|
|
169
|
+
|
|
170
|
+
/**
|
|
171
|
+
* Audio track selection preferences (Roku OS 12.5+).
|
|
172
|
+
*
|
|
173
|
+
* @see {@link https://developer.roku.com/dev/docs/video}
|
|
174
|
+
*/
|
|
175
|
+
export interface IAudioSelectionPreferences {
|
|
176
|
+
values: AudioSelectionPreferenceRule[];
|
|
177
|
+
overrideSystem: boolean;
|
|
178
|
+
}
|
|
179
|
+
|
|
180
|
+
/**
|
|
181
|
+
* Playback-related fields for the Video node: content, control, errors, and DRM.
|
|
182
|
+
*
|
|
183
|
+
* @see {@link https://developer.roku.com/dev/docs/video}
|
|
184
|
+
*/
|
|
185
|
+
export interface IVideoPlaybackProps {
|
|
186
|
+
/** ContentNode (or playlist parent) with content metadata for playback. */
|
|
187
|
+
content?: JSX.Element;
|
|
188
|
+
/** Fired when play-start timing info is updated. */
|
|
189
|
+
onPlayStartInfo?: EventHandler<IPlayStartInfo>;
|
|
190
|
+
/** Fired when DRM license status changes. */
|
|
191
|
+
onLicenseStatus?: EventHandler<ILicenseStatus>;
|
|
192
|
+
/** When true, children of `content` form a video playlist. */
|
|
193
|
+
contentIsPlaylist?: boolean;
|
|
194
|
+
/** Index of the current item in a playlist (or 0 for single content). */
|
|
195
|
+
onContentIndex?: EventHandler<number>;
|
|
196
|
+
/** Next playlist index to play after the current item ends or is skipped. */
|
|
197
|
+
nextContentIndex?: number;
|
|
198
|
+
/** Play state command (play, pause, stop, prebuffer, etc.). */
|
|
199
|
+
control?: VideoControl;
|
|
200
|
+
/**
|
|
201
|
+
* When true, STOP runs asynchronously (Roku OS 12.5+). `state` becomes `stopping` then `stopped`.
|
|
202
|
+
*/
|
|
203
|
+
asyncStopSemantics?: boolean;
|
|
204
|
+
/** Fired when playback state changes (buffering, playing, error, etc.). */
|
|
205
|
+
onState?: EventHandler<VideoState>;
|
|
206
|
+
/** Fired when `errorCode` changes after an error state. */
|
|
207
|
+
onErrorCode?: EventHandler<number>;
|
|
208
|
+
/** Fired when `errorMsg` changes. */
|
|
209
|
+
onErrorMsg?: EventHandler<string>;
|
|
210
|
+
/** Fired when `errorStr` changes. */
|
|
211
|
+
onErrorStr?: EventHandler<string>;
|
|
212
|
+
/** Fired when structured `errorInfo` is updated. */
|
|
213
|
+
onErrorInfo?: EventHandler<VideoErrorInfo>;
|
|
214
|
+
/** Fired when decoder statistics are updated (requires `enableDecoderStats`). */
|
|
215
|
+
onDecoderStats?: EventHandler<IDecoderStats>;
|
|
216
|
+
/** When true, `decoderStats` is populated and updated. */
|
|
217
|
+
enableDecoderStats?: boolean;
|
|
218
|
+
/** Buttons and UI on the pause screen at start of playback. */
|
|
219
|
+
playbackActionButtons?: IPlaybackActionButton[];
|
|
220
|
+
/** Selected index in `playbackActionButtons`. */
|
|
221
|
+
playbackActionButtonSelected?: number;
|
|
222
|
+
/** Focused index in `playbackActionButtons`. */
|
|
223
|
+
playbackActionButtonFocused?: number;
|
|
224
|
+
/** Font for the focused playback action button label. */
|
|
225
|
+
playbackActionButtonFocusedTextFont?: string;
|
|
226
|
+
/** Font for unfocused playback action button labels. */
|
|
227
|
+
playbackActionButtonUnfocusedTextFont?: string;
|
|
228
|
+
/** Text color when the playback action button has focus. */
|
|
229
|
+
playbackActionButtonFocusedTextColor?: string;
|
|
230
|
+
/** Text color when the playback action button does not have focus. */
|
|
231
|
+
playbackActionButtonUnfocusedTextColor?: string;
|
|
232
|
+
/** Background blend color when the playback action button has focus. */
|
|
233
|
+
playbackActionButtonFocusIndicatorBlendColor?: string;
|
|
234
|
+
/** Subtitle track selection priority (write-only configuration). */
|
|
235
|
+
subtitleSelectionPreferences?: ISubtitleSelectionPreferences;
|
|
236
|
+
/** Audio track selection priority (write-only configuration). */
|
|
237
|
+
audioSelectionPreferences?: IAudioSelectionPreferences;
|
|
238
|
+
}
|
|
239
|
+
|
|
240
|
+
/**
|
|
241
|
+
* Position info for last rendered audio/video samples.
|
|
242
|
+
*
|
|
243
|
+
* @see {@link https://developer.roku.com/dev/docs/video}
|
|
244
|
+
*/
|
|
245
|
+
export interface IPositionInfo {
|
|
246
|
+
audio: number;
|
|
247
|
+
clip_id: number;
|
|
248
|
+
epoch: number;
|
|
249
|
+
video: number;
|
|
250
|
+
}
|
|
251
|
+
|
|
252
|
+
/**
|
|
253
|
+
* Information about the video segment currently streaming (HLS/DASH).
|
|
254
|
+
*
|
|
255
|
+
* @see {@link https://developer.roku.com/dev/docs/video}
|
|
256
|
+
*/
|
|
257
|
+
export interface IStreamingSegmentInfo {
|
|
258
|
+
hdrModeStr: StreamingSegmentHdrMode;
|
|
259
|
+
segBitrateBps: number;
|
|
260
|
+
segSequence: number;
|
|
261
|
+
segStart: number;
|
|
262
|
+
segUrl: string;
|
|
263
|
+
segType: number;
|
|
264
|
+
segTypeStr: StreamingSegmentType;
|
|
265
|
+
latency: number;
|
|
266
|
+
path: string;
|
|
267
|
+
width: number;
|
|
268
|
+
height: number;
|
|
269
|
+
}
|
|
270
|
+
|
|
271
|
+
/**
|
|
272
|
+
* Information about a segment that was just downloaded.
|
|
273
|
+
*
|
|
274
|
+
* @see {@link https://developer.roku.com/dev/docs/video}
|
|
275
|
+
*/
|
|
276
|
+
export interface IDownloadedSegmentInfo {
|
|
277
|
+
status: number;
|
|
278
|
+
segSequence: number;
|
|
279
|
+
segUrl: string;
|
|
280
|
+
downloadDuration: number;
|
|
281
|
+
segSize: number;
|
|
282
|
+
segType: number;
|
|
283
|
+
bitrateBPS: number;
|
|
284
|
+
segStart: number;
|
|
285
|
+
segDuration: string;
|
|
286
|
+
path: string;
|
|
287
|
+
width: number;
|
|
288
|
+
height: number;
|
|
289
|
+
hdrMode: DownloadedSegmentHdrMode;
|
|
290
|
+
}
|
|
291
|
+
|
|
292
|
+
/**
|
|
293
|
+
* Trick play, seek, segments, and related timing fields.
|
|
294
|
+
*
|
|
295
|
+
* @see {@link https://developer.roku.com/dev/docs/video}
|
|
296
|
+
*/
|
|
297
|
+
export interface ITrickPlayProps {
|
|
298
|
+
/** Fired when stream duration is known or changes. */
|
|
299
|
+
onDuration?: EventHandler<number>;
|
|
300
|
+
/** When true, restarts playlist or single content after the end. */
|
|
301
|
+
loop?: boolean;
|
|
302
|
+
/** Fired on position updates (interval from `notificationInterval`). */
|
|
303
|
+
onPosition?: EventHandler<number>;
|
|
304
|
+
/** Fired with last rendered sample positions. */
|
|
305
|
+
onPositionInfo?: EventHandler<IPositionInfo>;
|
|
306
|
+
/** Fired when the current clip ID changes. */
|
|
307
|
+
onClipId?: EventHandler<number>;
|
|
308
|
+
/** Seconds between `position` observer notifications; 0 disables notifications. */
|
|
309
|
+
notificationInterval?: number;
|
|
310
|
+
/** Seek target in seconds from stream start (write-only). */
|
|
311
|
+
seek?: number;
|
|
312
|
+
/** Seek accuracy: default (keyframe) vs accurate (if supported). */
|
|
313
|
+
seekMode?: VideoSeekMode;
|
|
314
|
+
/** When false, disables auto-play after rebuffer following a seek. */
|
|
315
|
+
autoplayAfterSeek?: boolean;
|
|
316
|
+
/** Fired with info about the segment currently being streamed. */
|
|
317
|
+
onStreamingSegment?: EventHandler<IStreamingSegmentInfo>;
|
|
318
|
+
/** Fired when a segment download completes. */
|
|
319
|
+
onDownloadedSegment?: EventHandler<IDownloadedSegmentInfo>;
|
|
320
|
+
/**
|
|
321
|
+
* Keys for timed metadata (e.g. ID3); matching tags populate `timedMetaData` / `timedMetaData2`.
|
|
322
|
+
*/
|
|
323
|
+
timedMetaDataSelectionKeys?: string[];
|
|
324
|
+
/** Enables trick play bar scrubbing within the live availability window. */
|
|
325
|
+
enableLiveAvailabilityWindow?: boolean;
|
|
326
|
+
/** When true, `thumbnailTiles` updates during live HLS/DASH with thumbnails. */
|
|
327
|
+
enableThumbnailTilesDuringLive?: boolean;
|
|
328
|
+
/**
|
|
329
|
+
* Thumbnail tile sets from the manifest (structure varies by OS version).
|
|
330
|
+
*/
|
|
331
|
+
thumbnailTiles?: Record<string, unknown>;
|
|
332
|
+
/** Background overlay URI while playback UI is visible. */
|
|
333
|
+
trickPlayBackgroundOverlay?: Uri;
|
|
334
|
+
}
|
|
335
|
+
|
|
336
|
+
/**
|
|
337
|
+
* Built-in Video UI: dimensions, toggles, and internal bar/BIF/pivot nodes.
|
|
338
|
+
*
|
|
339
|
+
* @see {@link https://developer.roku.com/dev/docs/video}
|
|
340
|
+
*/
|
|
341
|
+
export interface IVideoUiProps {
|
|
342
|
+
/** Video window width in pixels; 0 uses full display width. */
|
|
343
|
+
width?: number;
|
|
344
|
+
/** Video window height in pixels; 0 uses full display height. */
|
|
345
|
+
height?: number;
|
|
346
|
+
/** When false, hides most built-in UI (app implements custom UI). */
|
|
347
|
+
enableUI?: boolean;
|
|
348
|
+
/** When false, remote trick play keys have no effect (requires `enableUI`). */
|
|
349
|
+
enableTrickPlay?: boolean;
|
|
350
|
+
/** BIF display sub-node instance. */
|
|
351
|
+
bifDisplay?: JSX.Element;
|
|
352
|
+
/** Trick play bar sub-node instance. */
|
|
353
|
+
trickPlayBar?: JSX.Element;
|
|
354
|
+
/** Buffering progress bar sub-node instance. */
|
|
355
|
+
bufferingBar?: JSX.Element;
|
|
356
|
+
/** Text color near the buffering bar (0 = system default). */
|
|
357
|
+
bufferingTextColor?: string;
|
|
358
|
+
/** Initial retrieve progress bar sub-node instance. */
|
|
359
|
+
retrievingBar?: JSX.Element;
|
|
360
|
+
/** Text color near the retrieving bar (0 = system default). */
|
|
361
|
+
retrievingTextColor?: string;
|
|
362
|
+
/** Pivot renderable shown when video is paused. */
|
|
363
|
+
pivotNode?: JSX.Element;
|
|
364
|
+
}
|
|
365
|
+
|
|
366
|
+
/**
|
|
367
|
+
* Closed caption and subtitle styling fields.
|
|
368
|
+
*
|
|
369
|
+
* @see {@link https://developer.roku.com/dev/docs/video}
|
|
370
|
+
*/
|
|
371
|
+
export interface IVideoCaptionProps {
|
|
372
|
+
/** Global caption mode; app should still set `subtitleTrack` as needed. */
|
|
373
|
+
globalCaptionMode?: GlobalCaptionMode;
|
|
374
|
+
/** Suppresses captions when resolving UI overlap conflicts. */
|
|
375
|
+
suppressCaptions?: boolean;
|
|
376
|
+
/** Selected subtitle track identifier (read/write). */
|
|
377
|
+
subtitleTrack?: string;
|
|
378
|
+
/**
|
|
379
|
+
* Caption styling keys (Text/Font, Text/Size, Background/Color, etc.) per Roku docs.
|
|
380
|
+
*/
|
|
381
|
+
captionStyle?: Record<string, string>;
|
|
382
|
+
}
|
|
383
|
+
|
|
384
|
+
/**
|
|
385
|
+
* Audio output and track selection fields.
|
|
386
|
+
*
|
|
387
|
+
* @see {@link https://developer.roku.com/dev/docs/video}
|
|
388
|
+
*/
|
|
389
|
+
export interface IVideoAudioProps {
|
|
390
|
+
/** Mutes or restores audio for the current stream. */
|
|
391
|
+
mute?: boolean;
|
|
392
|
+
/** Selected audio track identifier (prefer platform selection when possible). */
|
|
393
|
+
audioTrack?: string;
|
|
394
|
+
/**
|
|
395
|
+
* When true, continues video on audio track switch (HLS only; set before any control command).
|
|
396
|
+
*/
|
|
397
|
+
seamlessAudioTrackSelection?: boolean;
|
|
398
|
+
/** Description track volume vs main audio (0–100). */
|
|
399
|
+
supplementaryAudioVolume?: number;
|
|
400
|
+
}
|
|
401
|
+
|
|
402
|
+
/**
|
|
403
|
+
* Decode resolution, output protection, and screensaver behavior.
|
|
404
|
+
*
|
|
405
|
+
* @see {@link https://developer.roku.com/dev/docs/video}
|
|
406
|
+
*/
|
|
407
|
+
export interface IVideoMiscProps {
|
|
408
|
+
/**
|
|
409
|
+
* Max decode resolution [width, height]; [0,0] means unlimited per axis.
|
|
410
|
+
*/
|
|
411
|
+
maxVideoDecodeResolution?: Vector2D;
|
|
412
|
+
/** CGMS level for analog outputs (0–3 per Roku docs). */
|
|
413
|
+
cgms?: number;
|
|
414
|
+
/** Allows screensaver when video covers less than half the screen. */
|
|
415
|
+
enableScreenSaverWhilePlaying?: boolean;
|
|
416
|
+
/** Suppresses screensaver (e.g. audio-only). */
|
|
417
|
+
disableScreenSaver?: boolean;
|
|
418
|
+
}
|
|
419
|
+
|
|
420
|
+
/**
|
|
421
|
+
* All Video node props: extends Group with playback, trick play, UI, captions, audio, and misc fields.
|
|
422
|
+
*
|
|
423
|
+
* @see {@link https://developer.roku.com/dev/docs/video}
|
|
424
|
+
*/
|
|
425
|
+
export interface IVideoProps
|
|
426
|
+
extends
|
|
427
|
+
IGroupProps,
|
|
428
|
+
IVideoPlaybackProps,
|
|
429
|
+
ITrickPlayProps,
|
|
430
|
+
IVideoUiProps,
|
|
431
|
+
IVideoCaptionProps,
|
|
432
|
+
IVideoAudioProps,
|
|
433
|
+
IVideoMiscProps {}
|
|
434
|
+
|
|
435
|
+
/**
|
|
436
|
+
* Handle for imperative control of a {@link Video} component, obtained via the `ref` prop.
|
|
437
|
+
*
|
|
438
|
+
* Extends {@link ComponentRef} with convenience methods that map to
|
|
439
|
+
* {@link VideoControl} values, so you can drive playback without manually
|
|
440
|
+
* setting the `control` prop.
|
|
441
|
+
*
|
|
442
|
+
* @example
|
|
443
|
+
* ```tsx
|
|
444
|
+
* import { Button, Video, VideoRef } from "@roku-sdk/components";
|
|
445
|
+
*
|
|
446
|
+
* const Player = () => {
|
|
447
|
+
* let videoRef!: VideoRef;
|
|
448
|
+
*
|
|
449
|
+
* return (
|
|
450
|
+
* <>
|
|
451
|
+
* <Button text="Play" onButtonSelected={() => videoRef.play()} />
|
|
452
|
+
* <Video
|
|
453
|
+
* ref={videoRef}
|
|
454
|
+
* width={1920}
|
|
455
|
+
* height={1080}
|
|
456
|
+
* content={<ContentNode url="https://example.com/stream.m3u8" />}
|
|
457
|
+
* />
|
|
458
|
+
* </>
|
|
459
|
+
* );
|
|
460
|
+
* };
|
|
461
|
+
* ```
|
|
462
|
+
*
|
|
463
|
+
* @see {@link https://developer.roku.com/dev/docs/video}
|
|
464
|
+
*/
|
|
465
|
+
export interface VideoRef extends ComponentRef<IVideoProps> {
|
|
466
|
+
/**
|
|
467
|
+
* Begin playback of the video specified by `content`. Equivalent to setting
|
|
468
|
+
* `control="play"`. The node transitions through `buffering` to `playing`,
|
|
469
|
+
* which is observable via {@link IVideoPlaybackProps.onState}.
|
|
470
|
+
*/
|
|
471
|
+
play: () => void;
|
|
472
|
+
/**
|
|
473
|
+
* Pause playback while preserving the current position. Equivalent to setting
|
|
474
|
+
* `control="pause"`. Use {@link VideoRef.resume} to continue from where it
|
|
475
|
+
* paused. Has no effect when not currently `playing`.
|
|
476
|
+
*/
|
|
477
|
+
pause: () => void;
|
|
478
|
+
/**
|
|
479
|
+
* Stop playback and release the video stream. Equivalent to setting
|
|
480
|
+
* `control="stop"`. With {@link IVideoPlaybackProps.asyncStopSemantics} true
|
|
481
|
+
* (Roku OS 12.5+) the state transitions through `stopping` to `stopped`;
|
|
482
|
+
* otherwise the transition to `stopped` is synchronous.
|
|
483
|
+
*/
|
|
484
|
+
stop: () => void;
|
|
485
|
+
/**
|
|
486
|
+
* Resume playback after a {@link VideoRef.pause}. Equivalent to setting
|
|
487
|
+
* `control="resume"`. Has no effect when the node is not in the `paused`
|
|
488
|
+
* state.
|
|
489
|
+
*/
|
|
490
|
+
resume: () => void;
|
|
491
|
+
/**
|
|
492
|
+
* Restart the current video (or playlist) from the beginning. Equivalent to
|
|
493
|
+
* setting `control="replay"`.
|
|
494
|
+
*/
|
|
495
|
+
replay: () => void;
|
|
496
|
+
/**
|
|
497
|
+
* Pre-buffer the video without starting playback. Equivalent to setting
|
|
498
|
+
* `control="prebuffer"`. Useful to reduce time-to-first-frame when playback
|
|
499
|
+
* is started later via {@link VideoRef.play}.
|
|
500
|
+
*/
|
|
501
|
+
prebuffer: () => void;
|
|
502
|
+
/**
|
|
503
|
+
* Skip to the next item in a playlist. Equivalent to setting
|
|
504
|
+
* `control="skipcontent"`. Only meaningful when
|
|
505
|
+
* {@link IVideoPlaybackProps.contentIsPlaylist} is true.
|
|
506
|
+
*/
|
|
507
|
+
skipcontent: () => void;
|
|
508
|
+
/**
|
|
509
|
+
* Seek to a specific position in the current video. Equivalent to setting
|
|
510
|
+
* the {@link ITrickPlayProps.seek} prop. Seek accuracy is governed by
|
|
511
|
+
* {@link ITrickPlayProps.seekMode}, and auto-play after rebuffer can be
|
|
512
|
+
* disabled via {@link ITrickPlayProps.autoplayAfterSeek}.
|
|
513
|
+
*
|
|
514
|
+
* @param position Target position in seconds from the start of the stream.
|
|
515
|
+
*/
|
|
516
|
+
seekTo: (position: number) => void;
|
|
517
|
+
/**
|
|
518
|
+
* Set the index of the next video in the playlist to be played.
|
|
519
|
+
* @param index The index of the next video in the playlist.
|
|
520
|
+
*/
|
|
521
|
+
setNextContentIndex: (index: number) => void;
|
|
522
|
+
}
|
|
523
|
+
|
|
524
|
+
/**
|
|
525
|
+
* BIF (trick play image) display sub-component fields on Video.
|
|
526
|
+
*
|
|
527
|
+
* @see {@link https://developer.roku.com/dev/docs/video}
|
|
528
|
+
*/
|
|
529
|
+
export interface IBifDisplayProps extends INodeProps {
|
|
530
|
+
/** Blend color for the frame background behind BIF images. */
|
|
531
|
+
frameBgBlendColor?: string;
|
|
532
|
+
/** URI of image behind individual BIF frames. */
|
|
533
|
+
frameBgImageUri?: Uri;
|
|
534
|
+
/**
|
|
535
|
+
* Request nearest BIF to this time offset (seconds); write-only.
|
|
536
|
+
*/
|
|
537
|
+
getNearestFrame?: number;
|
|
538
|
+
/** URI of the requested BIF (e.g. memory://BIF_…). */
|
|
539
|
+
onNearestFrame?: EventHandler<string>;
|
|
540
|
+
}
|
|
541
|
+
|
|
542
|
+
/**
|
|
543
|
+
* Trick play bar appearance fields.
|
|
544
|
+
*
|
|
545
|
+
* @see {@link https://developer.roku.com/dev/docs/video}
|
|
546
|
+
*/
|
|
547
|
+
export interface ITrickPlayBarProps extends INodeProps {
|
|
548
|
+
currentTimeMarkerBlendColor?: string;
|
|
549
|
+
textColor?: string;
|
|
550
|
+
thumbBlendColor?: string;
|
|
551
|
+
filledBarBlendColor?: string;
|
|
552
|
+
liveFilledBarBlendColor?: string;
|
|
553
|
+
filledBarImageUri?: Uri;
|
|
554
|
+
trackBlendColor?: string;
|
|
555
|
+
trackImageUri?: Uri;
|
|
556
|
+
}
|
|
557
|
+
|
|
558
|
+
/**
|
|
559
|
+
* Progress bar fields used for buffering and retrieving indicators on Video.
|
|
560
|
+
*
|
|
561
|
+
* @see {@link https://developer.roku.com/dev/docs/video}
|
|
562
|
+
*/
|
|
563
|
+
export interface IProgressBarProps extends INodeProps {
|
|
564
|
+
width?: number;
|
|
565
|
+
height?: number;
|
|
566
|
+
emptyBarBlendColor?: string;
|
|
567
|
+
emptyBarImageUri?: Uri;
|
|
568
|
+
filledBarBlendColor?: string;
|
|
569
|
+
filledBarImageUri?: Uri;
|
|
570
|
+
trackBlendColor?: string;
|
|
571
|
+
trackImageUri?: Uri;
|
|
572
|
+
percentage?: number;
|
|
573
|
+
}
|
|
@@ -0,0 +1,73 @@
|
|
|
1
|
+
// Copyright (c) 2026 Roku, Inc.
|
|
2
|
+
// SPDX-License-Identifier: MIT
|
|
3
|
+
|
|
4
|
+
import { registerImperativeMethods } from "@roku-sdk/solid";
|
|
5
|
+
|
|
6
|
+
import type { IBifDisplayProps, IProgressBarProps, ITrickPlayBarProps, IVideoProps } from "./video.props";
|
|
7
|
+
export { VideoSeekMode, StreamingSegmentHdrMode, StreamingSegmentType, GlobalCaptionMode } from "./video.props";
|
|
8
|
+
|
|
9
|
+
export type {
|
|
10
|
+
IPlayStartInfo,
|
|
11
|
+
ILicenseStatus,
|
|
12
|
+
VideoControl,
|
|
13
|
+
VideoState,
|
|
14
|
+
VideoErrorInfo,
|
|
15
|
+
IDecoderStats,
|
|
16
|
+
IPlaybackActionButton,
|
|
17
|
+
SubtitleSelectionPreferenceRule,
|
|
18
|
+
ISubtitleSelectionPreferences,
|
|
19
|
+
AudioSelectionPreferenceRule,
|
|
20
|
+
IAudioSelectionPreferences,
|
|
21
|
+
IVideoPlaybackProps,
|
|
22
|
+
IPositionInfo,
|
|
23
|
+
IStreamingSegmentInfo,
|
|
24
|
+
IDownloadedSegmentInfo,
|
|
25
|
+
ITrickPlayProps,
|
|
26
|
+
IVideoUiProps,
|
|
27
|
+
IVideoCaptionProps,
|
|
28
|
+
IVideoAudioProps,
|
|
29
|
+
IVideoMiscProps,
|
|
30
|
+
IVideoProps,
|
|
31
|
+
VideoRef,
|
|
32
|
+
IBifDisplayProps,
|
|
33
|
+
ITrickPlayBarProps,
|
|
34
|
+
IProgressBarProps
|
|
35
|
+
} from "./video.props";
|
|
36
|
+
|
|
37
|
+
import { mediaPlaybackMethods } from "./media-playback-methods";
|
|
38
|
+
import { Component } from "./types";
|
|
39
|
+
|
|
40
|
+
export { DownloadedSegmentHdrMode } from "./video.props";
|
|
41
|
+
|
|
42
|
+
registerImperativeMethods("video", mediaPlaybackMethods);
|
|
43
|
+
|
|
44
|
+
/**
|
|
45
|
+
* Video provides controlled playback of live or VOD content with optional built-in UI, trick play,
|
|
46
|
+
* and captions.
|
|
47
|
+
*
|
|
48
|
+
* @see {@link https://developer.roku.com/dev/docs/video}
|
|
49
|
+
*
|
|
50
|
+
* @example
|
|
51
|
+
* <video
|
|
52
|
+
* width={1280}
|
|
53
|
+
* height={720}
|
|
54
|
+
* content={<VideoContentNode url={url} />}
|
|
55
|
+
* control="play"
|
|
56
|
+
* onState={state => console.log(state)}
|
|
57
|
+
* />
|
|
58
|
+
*/
|
|
59
|
+
export const Video: Component<IVideoProps> = props => {
|
|
60
|
+
return <video {...props}></video>;
|
|
61
|
+
};
|
|
62
|
+
|
|
63
|
+
export const BifDisplay: Component<IBifDisplayProps> = props => {
|
|
64
|
+
return <bifDisplay {...props}></bifDisplay>;
|
|
65
|
+
};
|
|
66
|
+
|
|
67
|
+
export const TrickPlayBar: Component<ITrickPlayBarProps> = props => {
|
|
68
|
+
return <trickPlayBar {...props}></trickPlayBar>;
|
|
69
|
+
};
|
|
70
|
+
|
|
71
|
+
export const ProgressBar: Component<IProgressBarProps> = props => {
|
|
72
|
+
return <progressBar {...props}></progressBar>;
|
|
73
|
+
};
|