@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.
Files changed (211) hide show
  1. package/BREAKING_CHANGES.md +84 -0
  2. package/LICENSE +21 -0
  3. package/README.md +19 -2
  4. package/core-jsx.d.ts +53 -0
  5. package/eslint.config.mjs +3 -0
  6. package/jsx.d.ts +273 -0
  7. package/package.json +84 -3
  8. package/src/__tests__/container.test.tsx +150 -0
  9. package/src/__tests__/glyphs.test.ts +202 -0
  10. package/src/__tests__/modal-boundary-export.test.ts +12 -0
  11. package/src/__tests__/native-modal.test.tsx +224 -0
  12. package/src/__tests__/tween-release.test.tsx +125 -0
  13. package/src/__tests__/tween-stops-shape.test.tsx +165 -0
  14. package/src/__tests__/tween-without-compat.test.tsx +64 -0
  15. package/src/__tests__/tween.test.tsx +195 -0
  16. package/src/blended-busy-spinner.props.ts +37 -0
  17. package/src/blended-busy-spinner.tsx +13 -0
  18. package/src/bounding-tracker.props.ts +18 -0
  19. package/src/bounding-tracker.tsx +13 -0
  20. package/src/button-row.tsx +126 -0
  21. package/src/channel-store.props.ts +425 -0
  22. package/src/channel-store.tsx +76 -0
  23. package/src/container.tsx +130 -0
  24. package/src/core/jsx-runtime.ts +39 -0
  25. package/src/focusable-group.props.ts +8 -0
  26. package/src/focusable-group.tsx +17 -0
  27. package/src/focusable.props.ts +14 -0
  28. package/src/focusable.tsx +17 -0
  29. package/src/glyphs.ts +116 -0
  30. package/src/helpers/index.tsx +4 -0
  31. package/src/helpers/resolution-context.tsx +68 -0
  32. package/src/helpers/scale-for-device-resolution.ts +31 -0
  33. package/src/index.tsx +70 -0
  34. package/src/jsx-props.ts +87 -0
  35. package/src/kdfs.d.ts +14 -0
  36. package/src/kdfs.ts +15 -0
  37. package/src/key-handler.props.ts +33 -0
  38. package/src/key-handler.tsx +24 -0
  39. package/src/modal-dialog.props.ts +38 -0
  40. package/src/modal-dialog.tsx +41 -0
  41. package/src/retain-asset.ts +24 -0
  42. package/src/sg-intrinsics.json +1153 -0
  43. package/src/sg-nodes/__tests__/__snapshots__/font.test.tsx.snap +13 -0
  44. package/src/sg-nodes/__tests__/__snapshots__/prop-forwarding.test.tsx.snap +4409 -0
  45. package/src/sg-nodes/__tests__/core-props.test.ts +301 -0
  46. package/src/sg-nodes/__tests__/font.test.tsx +141 -0
  47. package/src/sg-nodes/__tests__/imperative-methods.test.ts +268 -0
  48. package/src/sg-nodes/__tests__/prop-forwarding.test.tsx +1049 -0
  49. package/src/sg-nodes/__tests__/solid-integration.test.tsx +719 -0
  50. package/src/sg-nodes/animated-image.props.ts +64 -0
  51. package/src/sg-nodes/animated-image.tsx +23 -0
  52. package/src/sg-nodes/animation.props.ts +292 -0
  53. package/src/sg-nodes/animation.tsx +190 -0
  54. package/src/sg-nodes/array-grid.ts +602 -0
  55. package/src/sg-nodes/audio.props.ts +302 -0
  56. package/src/sg-nodes/audio.tsx +57 -0
  57. package/src/sg-nodes/busy-spinner.props.ts +59 -0
  58. package/src/sg-nodes/busy-spinner.tsx +84 -0
  59. package/src/sg-nodes/button-group.props.ts +141 -0
  60. package/src/sg-nodes/button-group.tsx +30 -0
  61. package/src/sg-nodes/button.props.ts +119 -0
  62. package/src/sg-nodes/button.tsx +31 -0
  63. package/src/sg-nodes/check-list.props.ts +71 -0
  64. package/src/sg-nodes/check-list.tsx +55 -0
  65. package/src/sg-nodes/content-node.props.ts +1316 -0
  66. package/src/sg-nodes/content-node.tsx +153 -0
  67. package/src/sg-nodes/core-props.ts +197 -0
  68. package/src/sg-nodes/custom-keyboard.props.ts +108 -0
  69. package/src/sg-nodes/custom-keyboard.tsx +48 -0
  70. package/src/sg-nodes/dialog.props.ts +159 -0
  71. package/src/sg-nodes/dialog.tsx +36 -0
  72. package/src/sg-nodes/dynamic-key-grid.props.ts +22 -0
  73. package/src/sg-nodes/dynamic-key-grid.tsx +16 -0
  74. package/src/sg-nodes/dynamic-keyboard.props.ts +30 -0
  75. package/src/sg-nodes/dynamic-keyboard.tsx +18 -0
  76. package/src/sg-nodes/dynamic-mini-keyboard.props.ts +22 -0
  77. package/src/sg-nodes/dynamic-mini-keyboard.tsx +18 -0
  78. package/src/sg-nodes/dynamic-pinpad.props.ts +57 -0
  79. package/src/sg-nodes/dynamic-pinpad.tsx +18 -0
  80. package/src/sg-nodes/effect.props.ts +116 -0
  81. package/src/sg-nodes/effect.tsx +39 -0
  82. package/src/sg-nodes/font.props.ts +45 -0
  83. package/src/sg-nodes/font.tsx +80 -0
  84. package/src/sg-nodes/group.props.ts +105 -0
  85. package/src/sg-nodes/group.tsx +30 -0
  86. package/src/sg-nodes/label-list.props.ts +86 -0
  87. package/src/sg-nodes/label-list.tsx +64 -0
  88. package/src/sg-nodes/label.props.ts +207 -0
  89. package/src/sg-nodes/label.tsx +56 -0
  90. package/src/sg-nodes/layout-group.props.ts +69 -0
  91. package/src/sg-nodes/layout-group.tsx +75 -0
  92. package/src/sg-nodes/list-panel.props.ts +104 -0
  93. package/src/sg-nodes/list-panel.tsx +49 -0
  94. package/src/sg-nodes/markup-grid.props.ts +78 -0
  95. package/src/sg-nodes/markup-grid.tsx +38 -0
  96. package/src/sg-nodes/markup-list.props.ts +68 -0
  97. package/src/sg-nodes/markup-list.tsx +38 -0
  98. package/src/sg-nodes/mask-group.props.ts +78 -0
  99. package/src/sg-nodes/mask-group.tsx +59 -0
  100. package/src/sg-nodes/media-playback-methods.ts +20 -0
  101. package/src/sg-nodes/node.ts +77 -0
  102. package/src/sg-nodes/overhang.props.ts +169 -0
  103. package/src/sg-nodes/overhang.tsx +29 -0
  104. package/src/sg-nodes/panel-set.props.ts +71 -0
  105. package/src/sg-nodes/panel-set.tsx +53 -0
  106. package/src/sg-nodes/panel.props.ts +176 -0
  107. package/src/sg-nodes/panel.tsx +56 -0
  108. package/src/sg-nodes/poster-grid.props.ts +277 -0
  109. package/src/sg-nodes/poster-grid.tsx +45 -0
  110. package/src/sg-nodes/poster.props.ts +125 -0
  111. package/src/sg-nodes/poster.tsx +44 -0
  112. package/src/sg-nodes/radio-button-list.props.ts +59 -0
  113. package/src/sg-nodes/radio-button-list.tsx +68 -0
  114. package/src/sg-nodes/rectangle.props.ts +29 -0
  115. package/src/sg-nodes/rectangle.tsx +27 -0
  116. package/src/sg-nodes/row-list.props.ts +288 -0
  117. package/src/sg-nodes/row-list.tsx +47 -0
  118. package/src/sg-nodes/scene.props.ts +65 -0
  119. package/src/sg-nodes/scene.tsx +15 -0
  120. package/src/sg-nodes/scrollable-text.props.ts +133 -0
  121. package/src/sg-nodes/scrollable-text.tsx +64 -0
  122. package/src/sg-nodes/scrolling-label.props.ts +106 -0
  123. package/src/sg-nodes/scrolling-label.tsx +42 -0
  124. package/src/sg-nodes/simple-label.props.ts +156 -0
  125. package/src/sg-nodes/simple-label.tsx +59 -0
  126. package/src/sg-nodes/sound-effect.props.ts +130 -0
  127. package/src/sg-nodes/sound-effect.tsx +65 -0
  128. package/src/sg-nodes/standard-dialog.props.ts +520 -0
  129. package/src/sg-nodes/standard-dialog.tsx +428 -0
  130. package/src/sg-nodes/standard-keyboard-dialog.props.ts +84 -0
  131. package/src/sg-nodes/standard-keyboard-dialog.tsx +59 -0
  132. package/src/sg-nodes/standard-message-dialog.props.ts +56 -0
  133. package/src/sg-nodes/standard-message-dialog.tsx +48 -0
  134. package/src/sg-nodes/standard-pinpad-dialog.props.ts +64 -0
  135. package/src/sg-nodes/standard-pinpad-dialog.tsx +46 -0
  136. package/src/sg-nodes/standard-progress-dialog.props.ts +30 -0
  137. package/src/sg-nodes/standard-progress-dialog.tsx +43 -0
  138. package/src/sg-nodes/target-group.props.ts +278 -0
  139. package/src/sg-nodes/target-group.tsx +63 -0
  140. package/src/sg-nodes/target-list.props.ts +128 -0
  141. package/src/sg-nodes/target-list.tsx +66 -0
  142. package/src/sg-nodes/target-set.props.ts +63 -0
  143. package/src/sg-nodes/target-set.tsx +42 -0
  144. package/src/sg-nodes/time-grid.props.ts +646 -0
  145. package/src/sg-nodes/time-grid.tsx +87 -0
  146. package/src/sg-nodes/tween.props.ts +115 -0
  147. package/src/sg-nodes/types.ts +150 -0
  148. package/src/sg-nodes/video.props.ts +573 -0
  149. package/src/sg-nodes/video.tsx +73 -0
  150. package/src/sg-nodes/voice-text-edit-box.props.ts +91 -0
  151. package/src/sg-nodes/voice-text-edit-box.tsx +15 -0
  152. package/src/sg-nodes/zoom-row-list.props.ts +416 -0
  153. package/src/sg-nodes/zoom-row-list.tsx +42 -0
  154. package/src/standard-dialog-next/__tests__/standard-dialog-next.test.tsx +186 -0
  155. package/src/standard-dialog-next/index.ts +5 -0
  156. package/src/standard-dialog-next/standard-dialog-next.props.ts +80 -0
  157. package/src/standard-dialog-next/standard-dialog-next.tsx +326 -0
  158. package/src/test-helpers/tween-test-setup.ts +78 -0
  159. package/src/tween.tsx +173 -0
  160. package/src/types.ts +8 -0
  161. package/src/xml-components/blended-busy-spinner/BlendedBusySpinner.brs +13 -0
  162. package/src/xml-components/blended-busy-spinner/BlendedBusySpinner.xml +10 -0
  163. package/src/xml-components/blended-busy-spinner/BlendedBusySpinner.xml.d.ts +42 -0
  164. package/src/xml-components/bounding-tracker/BoundingTracker.brs +26 -0
  165. package/src/xml-components/bounding-tracker/BoundingTracker.xml +14 -0
  166. package/src/xml-components/bounding-tracker/BoundingTracker.xml.d.ts +42 -0
  167. package/src/xml-components/channel-store/channelStoreExt.brs +159 -0
  168. package/src/xml-components/channel-store/channelStoreExt.xml +29 -0
  169. package/src/xml-components/channel-store/channelStoreExt.xml.d.ts +57 -0
  170. package/src/xml-components/focus/focusable-group.brs +251 -0
  171. package/src/xml-components/focus/focusable-group.xml +15 -0
  172. package/src/xml-components/focus/focusable-group.xml.d.ts +42 -0
  173. package/src/xml-components/focus/focusable.xml +18 -0
  174. package/src/xml-components/focus/focusable.xml.d.ts +48 -0
  175. package/src/xml-components/keyboards/CustomAddressKDF.keyboard.json +547 -0
  176. package/src/xml-components/keyboards/CustomKeyboard.brs +322 -0
  177. package/src/xml-components/keyboards/CustomKeyboard.xml +45 -0
  178. package/src/xml-components/keyboards/CustomKeyboard.xml.d.ts +73 -0
  179. package/src/xml-components/keyboards/KeyGridExt.xml +4 -0
  180. package/src/xml-components/keyboards/KeyGridExt.xml.d.ts +37 -0
  181. package/src/xml-components/keyboards/KeyboardExt.xml +4 -0
  182. package/src/xml-components/keyboards/KeyboardExt.xml.d.ts +37 -0
  183. package/src/xml-components/keyboards/MOPPinPadCustomKDF.keyboard.json +151 -0
  184. package/src/xml-components/keyboards/MiniKeyboardExt.xml +4 -0
  185. package/src/xml-components/keyboards/MiniKeyboardExt.xml.d.ts +37 -0
  186. package/src/xml-components/keyboards/PhonePadCustomKDF.keyboard.json +42 -0
  187. package/src/xml-components/keyboards/PinPadExt.brs +102 -0
  188. package/src/xml-components/keyboards/PinPadExt.xml +17 -0
  189. package/src/xml-components/keyboards/PinPadExt.xml.d.ts +49 -0
  190. package/src/xml-components/keyboards/WifiCustomKDF.keyboard.json +1242 -0
  191. package/src/xml-components/keyhandler/KeyHandler.brs +30 -0
  192. package/src/xml-components/keyhandler/KeyHandler.xml +16 -0
  193. package/src/xml-components/keyhandler/KeyHandler.xml.d.ts +45 -0
  194. package/src/xml-components/managed-list-panel/ManagedListPanel.brs +137 -0
  195. package/src/xml-components/managed-list-panel/ManagedListPanel.xml +10 -0
  196. package/src/xml-components/managed-list-panel/ManagedListPanel.xml.d.ts +37 -0
  197. package/src/xml-components/modal/Modal.brs +105 -0
  198. package/src/xml-components/modal/Modal.xml +22 -0
  199. package/src/xml-components/modal/Modal.xml.d.ts +54 -0
  200. package/src/xml-components/modal/StandardDialogExt.xml +10 -0
  201. package/src/xml-components/modal/StandardDialogExt.xml.d.ts +37 -0
  202. package/src/xml-components/modal/StandardKeyboardDialogExt.xml +10 -0
  203. package/src/xml-components/modal/StandardKeyboardDialogExt.xml.d.ts +37 -0
  204. package/src/xml-components/modal/StandardMessageDialogExt.xml +10 -0
  205. package/src/xml-components/modal/StandardMessageDialogExt.xml.d.ts +37 -0
  206. package/src/xml-components/modal/StandardPinPadDialogExt.xml +10 -0
  207. package/src/xml-components/modal/StandardPinPadDialogExt.xml.d.ts +37 -0
  208. package/src/xml-components/modal/StandardProgressDialogExt.xml +10 -0
  209. package/src/xml-components/modal/StandardProgressDialogExt.xml.d.ts +37 -0
  210. package/src/xml-components/modal/tests/Modal.test.brs +195 -0
  211. package/tsconfig.json +10 -0
@@ -0,0 +1,646 @@
1
+ // Copyright (c) 2026 Roku, Inc.
2
+ // SPDX-License-Identifier: MIT
3
+
4
+ import type { IArrayGridProps } from "./array-grid";
5
+ import type { EventHandler, FontValue, Uri } from "./types";
6
+
7
+ /**
8
+ * A tuple of `[channelIndex, programIndex]` identifying a specific program within a TimeGrid.
9
+ */
10
+ export type TimeGridItemPosition = [number, number];
11
+
12
+ /**
13
+ * Event handler for TimeGrid item events, receiving the `[channelIndex, programIndex]`
14
+ * of the item that triggered the event.
15
+ */
16
+ export type TimeGridItemEventHandler = EventHandler<TimeGridItemPosition>;
17
+
18
+ /**
19
+ * General TimeGrid settings that configure the overall time range,
20
+ * scrollable extent, and overlay appearance.
21
+ *
22
+ * @see {@link https://developer.roku.com/dev/docs/timegrid#general-timegrid-settings}
23
+ */
24
+ export interface ITimeGridGeneralProps {
25
+ /**
26
+ * The earliest time (in epoch seconds) that the TimeGrid can be scrolled to.
27
+ * The scrollable range is defined by the sum of `contentStartTime` and `maxDays`.
28
+ *
29
+ * @default 0
30
+ */
31
+ contentStartTime?: number;
32
+
33
+ /**
34
+ * Width (in seconds) of the visible section of the time grid.
35
+ * For example, 10800 displays a 3-hour window (10,800 = 3 * 3,600).
36
+ *
37
+ * @default 9000
38
+ */
39
+ duration?: number;
40
+
41
+ /**
42
+ * The total width of the TimeGrid in days.
43
+ *
44
+ * @default 7
45
+ */
46
+ maxDays?: number;
47
+
48
+ /**
49
+ * Time (in seconds) before the TimeGrid is automatically hidden.
50
+ * Setting to 0 prevents auto-hiding.
51
+ *
52
+ * @default 0
53
+ */
54
+ autoDismissTime?: number;
55
+
56
+ /**
57
+ * When true, ignores fast forward, rewind, and instant replay key events.
58
+ * FF/RW normally page the grid up/down; instant replay jumps to the current time.
59
+ *
60
+ * @default false
61
+ */
62
+ ignoreTrickPlayKeys?: boolean;
63
+
64
+ /**
65
+ * Bitmap URI for an overlay drawn on top of the entire time grid.
66
+ * Used by default to make bottom rows appear to fade out.
67
+ * In most cases, use a 9-patch image that specifies expandable regions.
68
+ *
69
+ * The overlay is drawn at full grid width with its bottom aligned to the grid bottom.
70
+ * If `overlayHeight` is greater than 0, the image is stretched to that height.
71
+ */
72
+ overlayBitmapUri?: Uri;
73
+
74
+ /**
75
+ * Height of the overlay image. If 0, the overlay is drawn at its default height.
76
+ *
77
+ * @default 0
78
+ */
79
+ overlayHeight?: number;
80
+ }
81
+
82
+ /**
83
+ * Channel-level navigation, focus, and selection settings.
84
+ *
85
+ * @see {@link https://developer.roku.com/dev/docs/timegrid#app-settings}
86
+ */
87
+ export interface ITimeGridChannelProps {
88
+ /**
89
+ * When explicitly set, triggers a horizontal scrolling animation so that the
90
+ * specified time is displayed at the left edge of the program grid.
91
+ *
92
+ * Also set by the firmware in response to remote control key presses that
93
+ * cause horizontal scrolling.
94
+ */
95
+ leftEdgeTargetTime?: number;
96
+
97
+ /**
98
+ * Write-only. Jumps the grid so the row corresponding to the specified
99
+ * channel index is on screen. The program in that row at the current
100
+ * focus time will have focus.
101
+ *
102
+ * @writeonly
103
+ */
104
+ jumpToChannel?: number;
105
+
106
+ /**
107
+ * Write-only. Scrolls the grid with animation so the row corresponding
108
+ * to the specified channel index is on screen. When scrolling ends,
109
+ * the program in that row at the current focus time will have focus.
110
+ *
111
+ * @writeonly
112
+ */
113
+ animateToChannel?: number;
114
+
115
+ /**
116
+ * Write-only. Jumps the grid to the program at the specified time (in UTC format).
117
+ * After the jump, the time will be visible and the program on the currently
118
+ * focused channel will have focus.
119
+ *
120
+ * @writeonly
121
+ */
122
+ jumpToTime?: string;
123
+
124
+ /**
125
+ * Index of the selected channel (read-only, set on program selection).
126
+ *
127
+ * @readonly
128
+ */
129
+ channelSelected?: number;
130
+
131
+ /** Fired when a channel is selected. */
132
+ onChannelSelected?: EventHandler<number>;
133
+
134
+ /**
135
+ * Index of the focused channel when a program in the channel's row gains focus.
136
+ *
137
+ * @readonly
138
+ */
139
+ channelFocused?: number;
140
+
141
+ /** Fired when the focused channel changes. */
142
+ onChannelFocused?: EventHandler<number>;
143
+
144
+ /**
145
+ * Index of the focused channel when a program in the channel's row loses focus.
146
+ *
147
+ * @readonly
148
+ */
149
+ channelUnfocused?: number;
150
+
151
+ /** Fired when a channel loses focus. */
152
+ onChannelUnfocused?: EventHandler<number>;
153
+ }
154
+
155
+ /**
156
+ * Configuration for the channel information column displayed on the left
157
+ * (or right) side of the EPG that lists channel names/logos.
158
+ *
159
+ * @see {@link https://developer.roku.com/dev/docs/timegrid#channel-information-column}
160
+ */
161
+ export interface ITimeGridChannelInfoProps {
162
+ /**
163
+ * Name of the compiled component used to render each channel info cell.
164
+ * The component's `content` field receives channel data.
165
+ *
166
+ * If not specified, the default channel info is displayed (optional icon + label).
167
+ */
168
+ channelInfoComponentName?: string;
169
+
170
+ /**
171
+ * Name of the compiled component shown when a channel has no program data.
172
+ */
173
+ channelNoDataComponentName?: string;
174
+
175
+ /**
176
+ * Width of the channel info column, in pixels.
177
+ */
178
+ channelInfoWidth?: number;
179
+
180
+ /**
181
+ * Spacing between the channel information column and the main grid.
182
+ *
183
+ * @default 0
184
+ */
185
+ infoGridGap?: number;
186
+
187
+ /**
188
+ * Text used as a label for the header of the channel information column.
189
+ * If not specified, the label shows the day of the week at the left edge.
190
+ */
191
+ channelInfoColumnLabel?: string;
192
+
193
+ /**
194
+ * Text color for channel names when `channelInfoComponentName` is not specified.
195
+ */
196
+ channelInfoTextColor?: string;
197
+
198
+ /**
199
+ * Font for channel names when `channelInfoComponentName` is not specified.
200
+ */
201
+ channelInfoFont?: FontValue;
202
+
203
+ /**
204
+ * Bitmap file used as the background for channel names when
205
+ * `channelInfoComponentName` is not specified.
206
+ * In most cases, use a 9-patch image that specifies expandable regions.
207
+ */
208
+ channelInfoBackgroundBitmapUri?: Uri;
209
+
210
+ /**
211
+ * Controls the position of the channel info column.
212
+ *
213
+ * @default "left"
214
+ */
215
+ channelInfoAlignment?: "left" | "right";
216
+
217
+ /**
218
+ * Whether the user can move focus into the channel information column.
219
+ * If false, the column is non-interactive.
220
+ *
221
+ * @default false
222
+ */
223
+ channelInfoFocusable?: boolean;
224
+
225
+ /**
226
+ * Write-only. Jumps the grid to the channel info box of the specified
227
+ * channel index. Ignored if `channelInfoFocusable` is false.
228
+ *
229
+ * @writeonly
230
+ */
231
+ jumpToChannelInfo?: number;
232
+
233
+ /**
234
+ * Bitmap displayed behind the focused channel info item.
235
+ */
236
+ channelFocusedBitmapUri?: Uri;
237
+
238
+ /**
239
+ * Bitmap displayed behind unfocused channel info items.
240
+ */
241
+ channelUnFocusedBitmapUri?: Uri;
242
+
243
+ /**
244
+ * Index of the selected channel in the channel information column.
245
+ *
246
+ * @readonly
247
+ */
248
+ channelInfoSelected?: number;
249
+
250
+ /** Fired when a channel info item is selected. */
251
+ onChannelInfoSelected?: EventHandler<number>;
252
+
253
+ /**
254
+ * Index of the channel when a channel info item gains focus.
255
+ *
256
+ * @readonly
257
+ */
258
+ channelInfoFocused?: number;
259
+
260
+ /** Fired when a channel info item gains focus. */
261
+ onChannelInfoFocused?: EventHandler<number>;
262
+
263
+ /**
264
+ * Index of the channel when a channel info item loses focus.
265
+ *
266
+ * @readonly
267
+ */
268
+ channelInfoUnfocused?: number;
269
+
270
+ /** Fired when a channel info item loses focus. */
271
+ onChannelInfoUnfocused?: EventHandler<number>;
272
+ }
273
+
274
+ /**
275
+ * Focused details for a program in the TimeGrid, combining the channel
276
+ * index and program index into a single object.
277
+ */
278
+ export interface ITimeGridProgramFocusedDetails {
279
+ focusChannelIndex: number;
280
+ focusIndex: number;
281
+ }
282
+
283
+ /**
284
+ * Configuration for program titles, cells, data loading, and program
285
+ * focus/selection events in the EPG grid.
286
+ *
287
+ * @see {@link https://developer.roku.com/dev/docs/timegrid#program-grid}
288
+ */
289
+ export interface ITimeGridProgramGridProps {
290
+ /**
291
+ * Name of the compiled component used to render focused program details.
292
+ */
293
+ programInfoComponentName?: string;
294
+
295
+ /**
296
+ * Text color for unfocused program titles.
297
+ *
298
+ * @example "0xFFFFFFFF"
299
+ */
300
+ programTitleColor?: string;
301
+
302
+ /**
303
+ * Text color for the focused program title.
304
+ *
305
+ * @example "0x000000FF"
306
+ */
307
+ programTitleFocusedColor?: string;
308
+
309
+ /**
310
+ * Font for program titles.
311
+ */
312
+ programTitleFont?: FontValue;
313
+
314
+ /**
315
+ * Bitmap file used as the background for program cells.
316
+ * In most cases, use a 9-patch image that specifies expandable regions.
317
+ */
318
+ programBackgroundBitmapUri?: Uri;
319
+
320
+ /**
321
+ * Width of the left and right margins of program cell text, in pixels.
322
+ *
323
+ * @default 14
324
+ */
325
+ programHorizMargin?: number;
326
+
327
+ /**
328
+ * When true, inserts a placeholder cell with the "No Data Available" label
329
+ * if there is a gap between a program's start time and the previous program's end time.
330
+ *
331
+ * @default false
332
+ */
333
+ fillProgramGaps?: boolean;
334
+
335
+ /**
336
+ * When true, the program data region is automatically replaced with the
337
+ * loading message whenever content has not been set or the user scrolls
338
+ * to a time where content has not yet been loaded.
339
+ *
340
+ * @default true
341
+ */
342
+ automaticLoadingDataFeedback?: boolean;
343
+
344
+ /**
345
+ * When true, replaces the program data region with the loading message.
346
+ * Enables explicit control over when the loading message is displayed.
347
+ * Ignored if `automaticLoadingDataFeedback` is true.
348
+ *
349
+ * @default false
350
+ */
351
+ showLoadingDataFeedback?: boolean;
352
+
353
+ /**
354
+ * Text displayed over the program grid when the loading message is shown.
355
+ *
356
+ * @default "Loading Data..."
357
+ */
358
+ loadingDataText?: string;
359
+
360
+ /**
361
+ * Text displayed on each channel row when no data exists for a specific time.
362
+ *
363
+ * @default "No Data Available"
364
+ */
365
+ channelNoDataText?: string;
366
+
367
+ /**
368
+ * Write-only. Jumps the grid to the program at the specified index
369
+ * for the currently focused row.
370
+ *
371
+ * @writeonly
372
+ */
373
+ jumpToProgram?: number;
374
+
375
+ /**
376
+ * Index of the selected program in the currently focused channel row (read-only, set on OK press).
377
+ *
378
+ * @readonly
379
+ */
380
+ programSelected?: number;
381
+
382
+ /** Fired when a program is selected. */
383
+ onProgramSelected?: EventHandler<number>;
384
+
385
+ /**
386
+ * Index of the focused program in the currently focused channel row.
387
+ *
388
+ * @readonly
389
+ */
390
+ programFocused?: number;
391
+
392
+ /** Fired when the focused program changes. */
393
+ onProgramFocused?: EventHandler<number>;
394
+
395
+ /**
396
+ * Index of the program in the currently focused channel row when it loses focus.
397
+ *
398
+ * @readonly
399
+ */
400
+ programUnfocused?: number;
401
+
402
+ /** Fired when a program loses focus. */
403
+ onProgramUnfocused?: EventHandler<number>;
404
+
405
+ /**
406
+ * Combined channel index and program index when a program gains focus.
407
+ * Provides the same values as `channelFocused` and `programFocused` in a single object.
408
+ *
409
+ * @readonly
410
+ */
411
+ programFocusedDetails?: ITimeGridProgramFocusedDetails;
412
+
413
+ /** Fired when program focused details change. */
414
+ onProgramFocusedDetails?: EventHandler<ITimeGridProgramFocusedDetails>;
415
+ }
416
+
417
+ /**
418
+ * Configuration for the solid color background drawn behind all programs
419
+ * airing before the current time.
420
+ *
421
+ * @see {@link https://developer.roku.com/dev/docs/timegrid#past-time-screen}
422
+ */
423
+ export interface ITimeGridPastTimeScreenProps {
424
+ /**
425
+ * When true, draws a solid color background behind all programs
426
+ * airing before the current time.
427
+ *
428
+ * @default true
429
+ */
430
+ showPastTimeScreen?: boolean;
431
+
432
+ /**
433
+ * Tints the past time screen by multiplying each pixel by this color.
434
+ * No blending is performed if set to the default value.
435
+ *
436
+ * @default "0xFFFFFFFF"
437
+ */
438
+ pastTimeScreenBlendColor?: string;
439
+
440
+ /**
441
+ * Bitmap file displayed in the background of the past time screen.
442
+ */
443
+ pastTimeScreenBitmapUri?: Uri;
444
+ }
445
+
446
+ /**
447
+ * Configuration for the time bar displayed horizontally above the program cells.
448
+ *
449
+ * @see {@link https://developer.roku.com/dev/docs/timegrid#time-bar}
450
+ */
451
+ export interface ITimeGridTimeBarProps {
452
+ /**
453
+ * Height of the time bar region above the channel grid, in pixels.
454
+ *
455
+ * @default 50
456
+ */
457
+ timeBarHeight?: number;
458
+
459
+ /**
460
+ * Background color for the time bar.
461
+ *
462
+ * @example "0x111111FF"
463
+ */
464
+ timeBarBackgroundColor?: string;
465
+
466
+ /**
467
+ * Bitmap file used as the background of the time bar.
468
+ * In most cases, use a 9-patch image that specifies expandable regions.
469
+ */
470
+ timeBarBitmapUri?: Uri;
471
+
472
+ /**
473
+ * Text color for the time labels displayed in the time bar.
474
+ *
475
+ * @default "0xffffff99"
476
+ */
477
+ timeLabelColor?: string;
478
+
479
+ /**
480
+ * Font for the time labels displayed in the time bar.
481
+ */
482
+ timeLabelFont?: FontValue;
483
+
484
+ /**
485
+ * Offset from the edge of the grid of the leftmost time label, in pixels.
486
+ *
487
+ * @default 14
488
+ */
489
+ timeLabelOffset?: number;
490
+ }
491
+
492
+ /**
493
+ * Configuration for the thin vertical bar displayed at the current time.
494
+ *
495
+ * @see {@link https://developer.roku.com/dev/docs/timegrid#now-bar}
496
+ */
497
+ export interface ITimeGridNowBarProps {
498
+ /**
499
+ * Width of the Now Bar, in pixels.
500
+ */
501
+ nowBarWidth?: number;
502
+
503
+ /**
504
+ * Height of the Now Bar, in pixels.
505
+ */
506
+ nowBarHeight?: number;
507
+
508
+ /**
509
+ * Bitmap file used for the Now Bar.
510
+ * In most cases, use a 9-patch image that specifies expandable regions.
511
+ */
512
+ nowBarBitmapUri?: Uri;
513
+
514
+ /**
515
+ * Tints the Now Bar by multiplying each pixel by this color.
516
+ * No blending is performed if set to the default value.
517
+ *
518
+ * @example "0x6600FFFF"
519
+ */
520
+ nowBarBlendColor?: string;
521
+
522
+ /**
523
+ * Number of pixels the left edge of the Now Bar is offset from the current time.
524
+ *
525
+ * @default 0
526
+ */
527
+ nowBarOffset?: number;
528
+
529
+ /**
530
+ * The nearest (in seconds) that the Now Bar can be to the left edge of the time grid.
531
+ * If the Now Bar advances to this value plus 30 minutes, the grid auto-scrolls right 30 minutes.
532
+ *
533
+ * @default 300
534
+ */
535
+ minimumNowBarOffset?: number;
536
+ }
537
+
538
+ /**
539
+ * Configuration for Now/Next mode, where the program grid only shows
540
+ * "Now" and "Next" columns listing current and subsequent programs.
541
+ *
542
+ * @see {@link https://developer.roku.com/dev/docs/timegrid#nownext-mode}
543
+ */
544
+ export interface ITimeGridNowNextModeProps {
545
+ /**
546
+ * When true, the time grid displays two vertical columns showing
547
+ * Now and Next programs for each channel.
548
+ *
549
+ * @default false
550
+ */
551
+ nowNextMode?: boolean;
552
+
553
+ /**
554
+ * Bitmap file displayed in the background of the Now column.
555
+ */
556
+ nowBackgroundBitmapUri?: Uri;
557
+
558
+ /**
559
+ * Bitmap file displayed in the background of the Next column.
560
+ */
561
+ nextBackgroundBitmapUri?: Uri;
562
+
563
+ /**
564
+ * When true, hides the AM/PM abbreviation next to times in Now/Next mode.
565
+ *
566
+ * @default false
567
+ */
568
+ nowNextHideAmPm?: boolean;
569
+
570
+ /**
571
+ * Text color for program times in Now/Next cells when unfocused.
572
+ *
573
+ * @default "0xffffff99"
574
+ */
575
+ programNowNextTimeColor?: string;
576
+
577
+ /**
578
+ * Text color for program times in Now/Next cells when focused.
579
+ *
580
+ * @default "0x000000FF"
581
+ */
582
+ programNowNextTimeFocusedColor?: string;
583
+
584
+ /**
585
+ * Width of the left and right margins of program cell text in Now/Next mode, in pixels.
586
+ *
587
+ * @default 14
588
+ */
589
+ programNowNextHorizMargin?: number;
590
+
591
+ /**
592
+ * Gap between the Now and Next entries, in pixels.
593
+ *
594
+ * @default 15
595
+ */
596
+ programNowNextTimeTitleGap?: number;
597
+ }
598
+
599
+ /**
600
+ * Properties for the TimeGrid node.
601
+ *
602
+ * TimeGrid is an EPG (Electronic Program Guide) component that displays a
603
+ * time-based grid of channels and programs. Each row represents a channel,
604
+ * and each cell within a row represents a program with its time slot.
605
+ *
606
+ * The content tree structure is:
607
+ * - Root `ContentNode`
608
+ * - Channel `ContentNode` per row (with `title`, `hdPosterUrl` for logo)
609
+ * - Program `ContentNode` per cell (with `title`, `description`, `playStart`, `playDuration`)
610
+ *
611
+ * Program nodes use `playStart` (epoch seconds) and `playDuration` (seconds)
612
+ * to determine their horizontal position and width in the grid.
613
+ *
614
+ * @see {@link https://developer.roku.com/dev/docs/timegrid}
615
+ *
616
+ * @example Basic TimeGrid
617
+ * ```tsx
618
+ * <TimeGrid
619
+ * numRows={7}
620
+ * duration={7200}
621
+ * contentStartTime={startTime}
622
+ * leftEdgeTargetTime={now}
623
+ * channelInfoComponentName={channelItem}
624
+ * content={epgContent}
625
+ * onProgramSelected={(index) => console.log(`Selected program: ${index}`)}
626
+ * />
627
+ * ```
628
+ */
629
+ export interface ITimeGridProps
630
+ extends
631
+ IArrayGridProps,
632
+ ITimeGridGeneralProps,
633
+ ITimeGridChannelProps,
634
+ ITimeGridChannelInfoProps,
635
+ ITimeGridProgramGridProps,
636
+ ITimeGridPastTimeScreenProps,
637
+ ITimeGridTimeBarProps,
638
+ ITimeGridNowBarProps,
639
+ ITimeGridNowNextModeProps {
640
+ /**
641
+ * Speed of horizontal scrolling through the time axis.
642
+ *
643
+ * @default 3
644
+ */
645
+ scrollSpeed?: number;
646
+ }