@roku-sdk/components 0.0.0-stage → 2.19.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 (212) 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 +85 -3
  8. package/src/__tests__/container.test.tsx +150 -0
  9. package/src/__tests__/effect-gradient-validation.test.tsx +133 -0
  10. package/src/__tests__/glyphs.test.ts +202 -0
  11. package/src/__tests__/modal-boundary-export.test.ts +12 -0
  12. package/src/__tests__/native-modal.test.tsx +224 -0
  13. package/src/__tests__/tween-release.test.tsx +125 -0
  14. package/src/__tests__/tween-stops-shape.test.tsx +165 -0
  15. package/src/__tests__/tween-without-compat.test.tsx +64 -0
  16. package/src/__tests__/tween.test.tsx +195 -0
  17. package/src/blended-busy-spinner.props.ts +37 -0
  18. package/src/blended-busy-spinner.tsx +13 -0
  19. package/src/bounding-tracker.props.ts +18 -0
  20. package/src/bounding-tracker.tsx +13 -0
  21. package/src/button-row.tsx +126 -0
  22. package/src/channel-store.props.ts +425 -0
  23. package/src/channel-store.tsx +76 -0
  24. package/src/container.tsx +130 -0
  25. package/src/core/jsx-runtime.ts +39 -0
  26. package/src/focusable-group.props.ts +8 -0
  27. package/src/focusable-group.tsx +17 -0
  28. package/src/focusable.props.ts +14 -0
  29. package/src/focusable.tsx +17 -0
  30. package/src/glyphs.ts +116 -0
  31. package/src/helpers/index.tsx +4 -0
  32. package/src/helpers/resolution-context.tsx +68 -0
  33. package/src/helpers/scale-for-device-resolution.ts +31 -0
  34. package/src/index.tsx +70 -0
  35. package/src/jsx-props.ts +87 -0
  36. package/src/kdfs.d.ts +14 -0
  37. package/src/kdfs.ts +15 -0
  38. package/src/key-handler.props.ts +33 -0
  39. package/src/key-handler.tsx +24 -0
  40. package/src/modal-dialog.props.ts +38 -0
  41. package/src/modal-dialog.tsx +41 -0
  42. package/src/retain-asset.ts +24 -0
  43. package/src/sg-intrinsics.json +1153 -0
  44. package/src/sg-nodes/__tests__/__snapshots__/font.test.tsx.snap +13 -0
  45. package/src/sg-nodes/__tests__/__snapshots__/prop-forwarding.test.tsx.snap +4409 -0
  46. package/src/sg-nodes/__tests__/core-props.test.ts +301 -0
  47. package/src/sg-nodes/__tests__/font.test.tsx +141 -0
  48. package/src/sg-nodes/__tests__/imperative-methods.test.ts +276 -0
  49. package/src/sg-nodes/__tests__/prop-forwarding.test.tsx +1049 -0
  50. package/src/sg-nodes/__tests__/solid-integration.test.tsx +719 -0
  51. package/src/sg-nodes/animated-image.props.ts +64 -0
  52. package/src/sg-nodes/animated-image.tsx +23 -0
  53. package/src/sg-nodes/animation.props.ts +292 -0
  54. package/src/sg-nodes/animation.tsx +190 -0
  55. package/src/sg-nodes/array-grid.ts +602 -0
  56. package/src/sg-nodes/audio.props.ts +302 -0
  57. package/src/sg-nodes/audio.tsx +57 -0
  58. package/src/sg-nodes/busy-spinner.props.ts +59 -0
  59. package/src/sg-nodes/busy-spinner.tsx +84 -0
  60. package/src/sg-nodes/button-group.props.ts +141 -0
  61. package/src/sg-nodes/button-group.tsx +30 -0
  62. package/src/sg-nodes/button.props.ts +119 -0
  63. package/src/sg-nodes/button.tsx +31 -0
  64. package/src/sg-nodes/check-list.props.ts +71 -0
  65. package/src/sg-nodes/check-list.tsx +55 -0
  66. package/src/sg-nodes/content-node.props.ts +1316 -0
  67. package/src/sg-nodes/content-node.tsx +153 -0
  68. package/src/sg-nodes/core-props.ts +197 -0
  69. package/src/sg-nodes/custom-keyboard.props.ts +108 -0
  70. package/src/sg-nodes/custom-keyboard.tsx +48 -0
  71. package/src/sg-nodes/dialog.props.ts +159 -0
  72. package/src/sg-nodes/dialog.tsx +36 -0
  73. package/src/sg-nodes/dynamic-key-grid.props.ts +22 -0
  74. package/src/sg-nodes/dynamic-key-grid.tsx +16 -0
  75. package/src/sg-nodes/dynamic-keyboard.props.ts +30 -0
  76. package/src/sg-nodes/dynamic-keyboard.tsx +18 -0
  77. package/src/sg-nodes/dynamic-mini-keyboard.props.ts +22 -0
  78. package/src/sg-nodes/dynamic-mini-keyboard.tsx +18 -0
  79. package/src/sg-nodes/dynamic-pinpad.props.ts +57 -0
  80. package/src/sg-nodes/dynamic-pinpad.tsx +18 -0
  81. package/src/sg-nodes/effect.props.ts +119 -0
  82. package/src/sg-nodes/effect.tsx +167 -0
  83. package/src/sg-nodes/font.props.ts +45 -0
  84. package/src/sg-nodes/font.tsx +80 -0
  85. package/src/sg-nodes/group.props.ts +105 -0
  86. package/src/sg-nodes/group.tsx +30 -0
  87. package/src/sg-nodes/label-list.props.ts +86 -0
  88. package/src/sg-nodes/label-list.tsx +64 -0
  89. package/src/sg-nodes/label.props.ts +207 -0
  90. package/src/sg-nodes/label.tsx +56 -0
  91. package/src/sg-nodes/layout-group.props.ts +69 -0
  92. package/src/sg-nodes/layout-group.tsx +75 -0
  93. package/src/sg-nodes/list-panel.props.ts +103 -0
  94. package/src/sg-nodes/list-panel.tsx +49 -0
  95. package/src/sg-nodes/markup-grid.props.ts +78 -0
  96. package/src/sg-nodes/markup-grid.tsx +38 -0
  97. package/src/sg-nodes/markup-list.props.ts +66 -0
  98. package/src/sg-nodes/markup-list.tsx +38 -0
  99. package/src/sg-nodes/mask-group.props.ts +78 -0
  100. package/src/sg-nodes/mask-group.tsx +59 -0
  101. package/src/sg-nodes/media-playback-methods.ts +20 -0
  102. package/src/sg-nodes/node.ts +77 -0
  103. package/src/sg-nodes/overhang.props.ts +169 -0
  104. package/src/sg-nodes/overhang.tsx +29 -0
  105. package/src/sg-nodes/panel-set.props.ts +71 -0
  106. package/src/sg-nodes/panel-set.tsx +53 -0
  107. package/src/sg-nodes/panel.props.ts +176 -0
  108. package/src/sg-nodes/panel.tsx +56 -0
  109. package/src/sg-nodes/poster-grid.props.ts +277 -0
  110. package/src/sg-nodes/poster-grid.tsx +45 -0
  111. package/src/sg-nodes/poster.props.ts +125 -0
  112. package/src/sg-nodes/poster.tsx +44 -0
  113. package/src/sg-nodes/radio-button-list.props.ts +59 -0
  114. package/src/sg-nodes/radio-button-list.tsx +68 -0
  115. package/src/sg-nodes/rectangle.props.ts +29 -0
  116. package/src/sg-nodes/rectangle.tsx +27 -0
  117. package/src/sg-nodes/row-list.props.ts +288 -0
  118. package/src/sg-nodes/row-list.tsx +47 -0
  119. package/src/sg-nodes/scene.props.ts +65 -0
  120. package/src/sg-nodes/scene.tsx +15 -0
  121. package/src/sg-nodes/scrollable-text.props.ts +133 -0
  122. package/src/sg-nodes/scrollable-text.tsx +64 -0
  123. package/src/sg-nodes/scrolling-label.props.ts +106 -0
  124. package/src/sg-nodes/scrolling-label.tsx +42 -0
  125. package/src/sg-nodes/simple-label.props.ts +156 -0
  126. package/src/sg-nodes/simple-label.tsx +59 -0
  127. package/src/sg-nodes/sound-effect.props.ts +130 -0
  128. package/src/sg-nodes/sound-effect.tsx +65 -0
  129. package/src/sg-nodes/standard-dialog.props.ts +520 -0
  130. package/src/sg-nodes/standard-dialog.tsx +428 -0
  131. package/src/sg-nodes/standard-keyboard-dialog.props.ts +84 -0
  132. package/src/sg-nodes/standard-keyboard-dialog.tsx +58 -0
  133. package/src/sg-nodes/standard-message-dialog.props.ts +56 -0
  134. package/src/sg-nodes/standard-message-dialog.tsx +47 -0
  135. package/src/sg-nodes/standard-pinpad-dialog.props.ts +64 -0
  136. package/src/sg-nodes/standard-pinpad-dialog.tsx +44 -0
  137. package/src/sg-nodes/standard-progress-dialog.props.ts +30 -0
  138. package/src/sg-nodes/standard-progress-dialog.tsx +40 -0
  139. package/src/sg-nodes/target-group.props.ts +278 -0
  140. package/src/sg-nodes/target-group.tsx +63 -0
  141. package/src/sg-nodes/target-list.props.ts +128 -0
  142. package/src/sg-nodes/target-list.tsx +66 -0
  143. package/src/sg-nodes/target-set.props.ts +63 -0
  144. package/src/sg-nodes/target-set.tsx +42 -0
  145. package/src/sg-nodes/time-grid.props.ts +646 -0
  146. package/src/sg-nodes/time-grid.tsx +87 -0
  147. package/src/sg-nodes/tween.props.ts +115 -0
  148. package/src/sg-nodes/types.ts +150 -0
  149. package/src/sg-nodes/video.props.ts +642 -0
  150. package/src/sg-nodes/video.tsx +75 -0
  151. package/src/sg-nodes/voice-text-edit-box.props.ts +91 -0
  152. package/src/sg-nodes/voice-text-edit-box.tsx +15 -0
  153. package/src/sg-nodes/zoom-row-list.props.ts +416 -0
  154. package/src/sg-nodes/zoom-row-list.tsx +42 -0
  155. package/src/standard-dialog-next/__tests__/standard-dialog-next.test.tsx +186 -0
  156. package/src/standard-dialog-next/index.ts +5 -0
  157. package/src/standard-dialog-next/standard-dialog-next.props.ts +80 -0
  158. package/src/standard-dialog-next/standard-dialog-next.tsx +326 -0
  159. package/src/test-helpers/tween-test-setup.ts +78 -0
  160. package/src/tween.tsx +173 -0
  161. package/src/types.ts +8 -0
  162. package/src/xml-components/blended-busy-spinner/BlendedBusySpinner.brs +13 -0
  163. package/src/xml-components/blended-busy-spinner/BlendedBusySpinner.xml +10 -0
  164. package/src/xml-components/blended-busy-spinner/BlendedBusySpinner.xml.d.ts +42 -0
  165. package/src/xml-components/bounding-tracker/BoundingTracker.brs +26 -0
  166. package/src/xml-components/bounding-tracker/BoundingTracker.xml +14 -0
  167. package/src/xml-components/bounding-tracker/BoundingTracker.xml.d.ts +42 -0
  168. package/src/xml-components/channel-store/channelStoreExt.brs +159 -0
  169. package/src/xml-components/channel-store/channelStoreExt.xml +29 -0
  170. package/src/xml-components/channel-store/channelStoreExt.xml.d.ts +57 -0
  171. package/src/xml-components/focus/focusable-group.brs +251 -0
  172. package/src/xml-components/focus/focusable-group.xml +15 -0
  173. package/src/xml-components/focus/focusable-group.xml.d.ts +42 -0
  174. package/src/xml-components/focus/focusable.xml +18 -0
  175. package/src/xml-components/focus/focusable.xml.d.ts +48 -0
  176. package/src/xml-components/keyboards/CustomAddressKDF.keyboard.json +547 -0
  177. package/src/xml-components/keyboards/CustomKeyboard.brs +322 -0
  178. package/src/xml-components/keyboards/CustomKeyboard.xml +45 -0
  179. package/src/xml-components/keyboards/CustomKeyboard.xml.d.ts +73 -0
  180. package/src/xml-components/keyboards/KeyGridExt.xml +4 -0
  181. package/src/xml-components/keyboards/KeyGridExt.xml.d.ts +37 -0
  182. package/src/xml-components/keyboards/KeyboardExt.xml +4 -0
  183. package/src/xml-components/keyboards/KeyboardExt.xml.d.ts +37 -0
  184. package/src/xml-components/keyboards/MOPPinPadCustomKDF.keyboard.json +151 -0
  185. package/src/xml-components/keyboards/MiniKeyboardExt.xml +4 -0
  186. package/src/xml-components/keyboards/MiniKeyboardExt.xml.d.ts +37 -0
  187. package/src/xml-components/keyboards/PhonePadCustomKDF.keyboard.json +42 -0
  188. package/src/xml-components/keyboards/PinPadExt.brs +102 -0
  189. package/src/xml-components/keyboards/PinPadExt.xml +17 -0
  190. package/src/xml-components/keyboards/PinPadExt.xml.d.ts +49 -0
  191. package/src/xml-components/keyboards/WifiCustomKDF.keyboard.json +1242 -0
  192. package/src/xml-components/keyhandler/KeyHandler.brs +30 -0
  193. package/src/xml-components/keyhandler/KeyHandler.xml +16 -0
  194. package/src/xml-components/keyhandler/KeyHandler.xml.d.ts +45 -0
  195. package/src/xml-components/managed-list-panel/ManagedListPanel.brs +137 -0
  196. package/src/xml-components/managed-list-panel/ManagedListPanel.xml +10 -0
  197. package/src/xml-components/managed-list-panel/ManagedListPanel.xml.d.ts +37 -0
  198. package/src/xml-components/modal/Modal.brs +105 -0
  199. package/src/xml-components/modal/Modal.xml +22 -0
  200. package/src/xml-components/modal/Modal.xml.d.ts +54 -0
  201. package/src/xml-components/modal/StandardDialogExt.xml +10 -0
  202. package/src/xml-components/modal/StandardDialogExt.xml.d.ts +37 -0
  203. package/src/xml-components/modal/StandardKeyboardDialogExt.xml +10 -0
  204. package/src/xml-components/modal/StandardKeyboardDialogExt.xml.d.ts +37 -0
  205. package/src/xml-components/modal/StandardMessageDialogExt.xml +10 -0
  206. package/src/xml-components/modal/StandardMessageDialogExt.xml.d.ts +37 -0
  207. package/src/xml-components/modal/StandardPinPadDialogExt.xml +10 -0
  208. package/src/xml-components/modal/StandardPinPadDialogExt.xml.d.ts +37 -0
  209. package/src/xml-components/modal/StandardProgressDialogExt.xml +10 -0
  210. package/src/xml-components/modal/StandardProgressDialogExt.xml.d.ts +37 -0
  211. package/src/xml-components/modal/tests/Modal.test.brs +195 -0
  212. package/tsconfig.json +10 -0
@@ -0,0 +1,288 @@
1
+ // Copyright (c) 2026 Roku, Inc.
2
+ // SPDX-License-Identifier: MIT
3
+
4
+ import type { IArrayGridProps, VertFocusAnimationStyle } from "./array-grid";
5
+ import type { EventHandler, JSX, Uri, Vector2D } from "./types";
6
+
7
+ /**
8
+ * A tuple of `[rowIndex, itemIndex]` identifying a specific item within a RowList.
9
+ */
10
+ export type RowItemPosition = [number, number];
11
+
12
+ /**
13
+ * Event handler for RowList item events, receiving the `[rowIndex, itemIndex]`
14
+ * of the item that triggered the event.
15
+ */
16
+ export type RowListItemEventHandler = EventHandler<RowItemPosition>;
17
+
18
+ /**
19
+ * Properties for the RowList node.
20
+ *
21
+ * RowList displays a vertical list of rows, where each row scrolls horizontally
22
+ * through its items. The content of each item is rendered by a compiled component
23
+ * specified via `itemComponentName`. Row titles can also be rendered by a compiled
24
+ * component via `rowTitleComponentName`.
25
+ *
26
+ * Each row's size, spacing, label visibility, and focus animation can be
27
+ * configured independently using per-row array fields.
28
+ *
29
+ * @see {@link https://developer.roku.com/dev/docs/rowlist}
30
+ *
31
+ * @example
32
+ * ```tsx
33
+ * // Register compiled components by importing their XML files
34
+ * import "./compiled-components/MyRowItem.xml";
35
+ * import "./compiled-components/MyRowTitle.xml";
36
+ *
37
+ * <RowList
38
+ * itemComponentName="MyRowItem"
39
+ * rowTitleComponentName="MyRowTitle"
40
+ * itemSize={[1920, 200]}
41
+ * rowItemSize={[[300, 160]]}
42
+ * numRows={4}
43
+ * content={listContent}
44
+ * onRowItemFocused={([row, col]) => setFocus(row, col)}
45
+ * onRowItemSelected={([row, col]) => navigate(row, col)}
46
+ * />
47
+ * ```
48
+ */
49
+ export interface IRowListProps extends IArrayGridProps {
50
+ // ─────────────────────────────────────────────────────────────────────────
51
+ // Content
52
+ // ─────────────────────────────────────────────────────────────────────────
53
+
54
+ /**
55
+ * Specifies the content for the RowList.
56
+ *
57
+ * The root `ContentNode` should have one child per row. Each row child should
58
+ * have one child `ContentNode` per item in that row.
59
+ *
60
+ * @see {@link https://developer.roku.com/dev/docs/rowlist | RowList content}
61
+ */
62
+ content: JSX.Element;
63
+
64
+ // ─────────────────────────────────────────────────────────────────────────
65
+ // Item Components
66
+ // ─────────────────────────────────────────────────────────────────────────
67
+
68
+ /**
69
+ * Specifies the name of the compiled component used to render each row item.
70
+ *
71
+ * Register the compiled component by importing its XML file before use:
72
+ * ```ts
73
+ * import "./compiled-components/MyRowItem.xml";
74
+ * ```
75
+ *
76
+ * The compiled component may define interface fields that RowList will
77
+ * automatically update: `width`, `height`, `index`, `listHasFocus`,
78
+ * `itemContent`, `focusPercent`, and `itemHasFocus`.
79
+ *
80
+ * @example "MyRowItem"
81
+ * @see {@link https://developer.roku.com/dev/docs/rowlist | RowList itemComponentName}
82
+ */
83
+ itemComponentName?: string;
84
+
85
+ /**
86
+ * Specifies the name of the compiled component used to render row titles,
87
+ * replacing the default text row label.
88
+ *
89
+ * Register the compiled component by importing its XML file before use:
90
+ * ```ts
91
+ * import "./compiled-components/MyRowTitle.xml";
92
+ * ```
93
+ *
94
+ * @example "MyRowTitle"
95
+ */
96
+ rowTitleComponentName?: string;
97
+
98
+ // ─────────────────────────────────────────────────────────────────────────
99
+ // Row Layout
100
+ // ─────────────────────────────────────────────────────────────────────────
101
+
102
+ /**
103
+ * Specifies the width and height of items in each row.
104
+ *
105
+ * Each element corresponds to a row. If the array has fewer elements than
106
+ * the number of rows, the last value is repeated for the remaining rows.
107
+ *
108
+ * @example [[300, 160], [200, 120]]
109
+ */
110
+ rowItemSize?: Vector2D[];
111
+
112
+ /**
113
+ * Specifies the horizontal spacing between items in each row.
114
+ *
115
+ * Each element corresponds to a row. If the array has fewer elements than
116
+ * the number of rows, the last value is repeated.
117
+ *
118
+ * @example [[20, 0]]
119
+ */
120
+ rowItemSpacing?: Vector2D[];
121
+
122
+ /**
123
+ * Specifies the X-offset from the left edge to the first fully visible item
124
+ * for each row when that row has focus.
125
+ *
126
+ * @example [40, 40]
127
+ */
128
+ focusXOffset?: number[];
129
+
130
+ // ─────────────────────────────────────────────────────────────────────────
131
+ // Row Labels
132
+ // ─────────────────────────────────────────────────────────────────────────
133
+
134
+ /**
135
+ * Specifies the offset of the row label for each row.
136
+ *
137
+ * The x-value is the horizontal offset; the y-value is the vertical spacing
138
+ * between the label and the row items.
139
+ *
140
+ * @default [[0, 0]]
141
+ */
142
+ rowLabelOffset?: Vector2D[];
143
+
144
+ /**
145
+ * Controls whether the left-edge row label is shown for each row.
146
+ *
147
+ * @example [true, false, true]
148
+ */
149
+ showRowLabel?: boolean[];
150
+
151
+ /**
152
+ * Controls whether the "item N of M" counter is shown for each row.
153
+ * The counter is only displayed on the focused row.
154
+ *
155
+ * @example [true, true]
156
+ */
157
+ showRowCounter?: boolean[];
158
+
159
+ /**
160
+ * When `true` for a row, appends "+" to the total item count in that row's
161
+ * counter, indicating the count may be indefinite.
162
+ *
163
+ * @example [false, true]
164
+ */
165
+ indefiniteRowItemCount?: boolean[];
166
+
167
+ /**
168
+ * When `true` for a row, enables variable-width items for that row.
169
+ * Only supported with `rowFocusAnimationStyle` set to `fixedFocusWrap`.
170
+ *
171
+ * Item widths are read from `SDItemWidth`, `HDItemWidth`, or `FHDItemWidth`
172
+ * attributes on each item's ContentNode.
173
+ *
174
+ * @example [false, true]
175
+ */
176
+ variableWidthItems?: boolean[];
177
+
178
+ /**
179
+ * Specifies the horizontal focus movement animation style for all rows.
180
+ *
181
+ * - `floatingFocus`: focus indicator moves with the focused item
182
+ * - `fixedFocusWrap`: focus stays fixed; items wrap around
183
+ * - `fixedFocus`: focus stays fixed; items scroll without wrapping
184
+ *
185
+ * @default "floatingFocus"
186
+ * @see {@link https://developer.roku.com/dev/docs/rowlist | RowList rowFocusAnimationStyle}
187
+ */
188
+ rowFocusAnimationStyle?: VertFocusAnimationStyle | `${VertFocusAnimationStyle}`;
189
+
190
+ /**
191
+ * Specifies the color of row and counter labels.
192
+ *
193
+ * @default "0xffffffff"
194
+ * @example "0xddddddff"
195
+ */
196
+ rowLabelColor?: string;
197
+
198
+ /**
199
+ * Specifies the font for row and counter labels.
200
+ *
201
+ * @default system default
202
+ */
203
+ rowLabelFont?: string;
204
+
205
+ /**
206
+ * Specifies the offset of the right edge of the row counter relative to the
207
+ * right edge of the clipping rectangle.
208
+ */
209
+ rowCounterRightOffset?: number;
210
+
211
+ /**
212
+ * When `false`, the row counter is hidden for rows where all items fit
213
+ * on screen at once.
214
+ *
215
+ * @default true
216
+ */
217
+ showRowCounterForShortRows?: boolean;
218
+
219
+ // ─────────────────────────────────────────────────────────────────────────
220
+ // Bitmaps
221
+ // ─────────────────────────────────────────────────────────────────────────
222
+
223
+ /**
224
+ * Specifies the bitmap file to display as a placeholder where images would
225
+ * appear in empty rows.
226
+ *
227
+ * Only set to specify a custom bitmap that differs from the default.
228
+ *
229
+ * @example "pkg:/images/image-well.png"
230
+ */
231
+ imageWellBitmapUri?: Uri;
232
+
233
+ /**
234
+ * Specifies the bitmap file shown while a row item's image is loading.
235
+ *
236
+ * @example "pkg:/images/loading.png"
237
+ */
238
+ loadingBitmapUri?: Uri;
239
+
240
+ /**
241
+ * Specifies the opacity of the loading bitmap.
242
+ *
243
+ * @default 1.0
244
+ */
245
+ loadingBitmapOpacity?: number;
246
+
247
+ /**
248
+ * Specifies the bitmap file shown when a row item's image fails to load.
249
+ *
250
+ * @example "pkg:/images/error.png"
251
+ */
252
+ failedBitmapUri?: Uri;
253
+
254
+ /**
255
+ * Specifies the opacity of the failed bitmap.
256
+ *
257
+ * @default 1.0
258
+ */
259
+ failedBitmapOpacity?: number;
260
+
261
+ // ─────────────────────────────────────────────────────────────────────────
262
+ // Navigation
263
+ // ─────────────────────────────────────────────────────────────────────────
264
+
265
+ /**
266
+ * When set to a valid `[rowIndex, itemIndex]`, immediately moves focus to
267
+ * the specified item without animation.
268
+ *
269
+ * @example [2, 0]
270
+ */
271
+ jumpToRowItem?: RowItemPosition;
272
+
273
+ // ─────────────────────────────────────────────────────────────────────────
274
+ // Events
275
+ // ─────────────────────────────────────────────────────────────────────────
276
+
277
+ /**
278
+ * Fired when a row item is selected (OK pressed).
279
+ * Receives `[rowIndex, itemIndex]` of the selected item.
280
+ */
281
+ onRowItemSelected?: RowListItemEventHandler;
282
+
283
+ /**
284
+ * Fired when a row item gains focus.
285
+ * Receives `[rowIndex, itemIndex]` of the newly focused item.
286
+ */
287
+ onRowItemFocused?: RowListItemEventHandler;
288
+ }
@@ -0,0 +1,47 @@
1
+ // Copyright (c) 2026 Roku, Inc.
2
+ // SPDX-License-Identifier: MIT
3
+
4
+ import type { IRowListProps } from "./row-list.props";
5
+ import { Component } from "./types";
6
+ export type { RowItemPosition, RowListItemEventHandler, IRowListProps } from "./row-list.props";
7
+
8
+ // ─────────────────────────────────────────────────────────────────────────────
9
+ // RowList Types
10
+ // ─────────────────────────────────────────────────────────────────────────────
11
+
12
+ // ─────────────────────────────────────────────────────────────────────────────
13
+ // RowList Properties
14
+ // ─────────────────────────────────────────────────────────────────────────────
15
+
16
+ /**
17
+ * RowList displays a vertical list of rows, where each row scrolls horizontally
18
+ * through its items. Item rendering is delegated to compiled components specified
19
+ * by `itemComponentName`.
20
+ *
21
+ * Each row can have independent size, spacing, label, counter, and focus behavior
22
+ * via per-row array fields. Row titles can be rendered by a separate compiled
23
+ * component via `rowTitleComponentName`.
24
+ *
25
+ * @see {@link https://developer.roku.com/dev/docs/rowlist}
26
+ *
27
+ * @example
28
+ * ```tsx
29
+ * // Register compiled components by importing their XML files
30
+ * import "./compiled-components/MyRowItem.xml";
31
+ *
32
+ * <rowList
33
+ * itemComponentName="MyRowItem"
34
+ * itemSize={[1920, 200]}
35
+ * rowItemSize={[[300, 160]]}
36
+ * numRows={4}
37
+ * showRowLabel={[true]}
38
+ * rowLabelColor="0xffffffff"
39
+ * content={listContent}
40
+ * onRowItemFocused={([row, col]) => setFocus(row, col)}
41
+ * onRowItemSelected={([row, col]) => navigate(row, col)}
42
+ * />
43
+ * ```
44
+ */
45
+ export const RowList: Component<IRowListProps> = props => {
46
+ return <rowList {...props}></rowList>;
47
+ };
@@ -0,0 +1,65 @@
1
+ // Copyright (c) 2026 Roku, Inc.
2
+ // SPDX-License-Identifier: MIT
3
+
4
+ import type { IGroupProps } from "./group.props";
5
+ import type { EventHandler, JSX, Uri } from "./types";
6
+
7
+ /**
8
+ * Represents the current design resolution of the scene.
9
+ */
10
+ export interface DesignResolution {
11
+ /** The width of the design resolution in pixels. */
12
+ width: number;
13
+ /** The height of the design resolution in pixels. */
14
+ height: number;
15
+ /** The resolution mode. */
16
+ resolution: "HD" | "FHD" | "SD";
17
+ }
18
+
19
+ /**
20
+ * Properties for the Scene node.
21
+ *
22
+ * Scene is the root node of a SceneGraph application. Every roSGScreen object must have
23
+ * exactly one Scene node as its root. The Scene node provides background rendering,
24
+ * dialog management, and design resolution information.
25
+ *
26
+ * @see {@link https://developer.roku.com/dev/docs/scene}
27
+ */
28
+ export interface ISceneProps extends IGroupProps {
29
+ /** Specifies a graphic image file to be used for the Scene node background. */
30
+ backgroundURI?: Uri;
31
+ /**
32
+ * If true, the backgroundURI image is limited to the current screen size after being loaded.
33
+ * If false, no scaling is applied.
34
+ * @default true
35
+ */
36
+ limitBackgroundToUIResolution?: boolean;
37
+ /**
38
+ * Specifies a background color for the scene as a hex string (e.g., "0x000000FF").
39
+ * Only used if backgroundURI is set to an empty string.
40
+ * @default "0x000000FF"
41
+ */
42
+ backgroundColor?: string;
43
+ /**
44
+ * If true, a Back key press causes the scene to exit.
45
+ * If false, Back key doesn't exit the scene.
46
+ * Requires focus to be set on the scene or a child node.
47
+ * @default true
48
+ */
49
+ backExitsScene?: boolean;
50
+ /**
51
+ * Setting this field to a node extended from Dialog causes the dialog to be displayed.
52
+ * Set to invalid to dismiss the dialog.
53
+ */
54
+ dialog?: JSX.Element;
55
+ /**
56
+ * Defines the default color palette used by nodes that have a palette field,
57
+ * such as standard dialogs and keyboards.
58
+ */
59
+ palette?: JSX.Element;
60
+ /**
61
+ * Event fired when the current design resolution changes.
62
+ * Returns the width, height, and resolution mode ("HD", "FHD", or "SD").
63
+ */
64
+ onCurrentDesignResolution?: EventHandler<DesignResolution>;
65
+ }
@@ -0,0 +1,15 @@
1
+ // Copyright (c) 2026 Roku, Inc.
2
+ // SPDX-License-Identifier: MIT
3
+
4
+ import type { ISceneProps } from "./scene.props";
5
+ import { Component } from "./types";
6
+ export type { DesignResolution, ISceneProps } from "./scene.props";
7
+
8
+ /**
9
+ * Scene component - the root node of a SceneGraph application.
10
+ *
11
+ * @see {@link https://developer.roku.com/dev/docs/scene}
12
+ */
13
+ export const Scene: Component<ISceneProps> = props => {
14
+ return <scene {...props}></scene>;
15
+ };
@@ -0,0 +1,133 @@
1
+ // Copyright (c) 2026 Roku, Inc.
2
+ // SPDX-License-Identifier: MIT
3
+
4
+ import type { IGroupProps } from "./group.props";
5
+ import type { FontValue, HorizAlign, Uri, VertAlign } from "./types";
6
+
7
+ /**
8
+ * Properties for the ScrollableText node.
9
+ *
10
+ * ScrollableText provides an interactive, vertically scrolling pane of text.
11
+ * This is typically used to display several paragraphs of text that are too
12
+ * long to fit onto the display, such as license agreements or detailed descriptions.
13
+ *
14
+ * **Key Features:**
15
+ * - Automatic scrollbar when text exceeds the specified height
16
+ * - User can scroll using remote's up/down arrow keys
17
+ * - Customizable scrollbar appearance
18
+ * - Text alignment control (horizontal and vertical)
19
+ *
20
+ * @extends Group
21
+ * @see {@link https://developer.roku.com/dev/docs/scrollabletext}
22
+ *
23
+ * @example
24
+ * <ScrollableText
25
+ * text="Long text content here..."
26
+ * width={800}
27
+ * height={400}
28
+ * font={SystemFont.Medium}
29
+ * />
30
+ */
31
+ export interface IScrollableTextProps extends IGroupProps {
32
+ /**
33
+ * Specifies the text to be displayed.
34
+ *
35
+ * @default ""
36
+ */
37
+ text?: string;
38
+
39
+ /**
40
+ * Specifies the text color as a hex value (e.g., `0xRRGGBBAA` or `#RRGGBBAA`).
41
+ *
42
+ * @default 0xddddddff
43
+ */
44
+ color?: string;
45
+
46
+ /**
47
+ * Specifies the Font node to be used for rendering the text.
48
+ * Can be a system font enum value or a custom font URI string.
49
+ *
50
+ * @example
51
+ * // Using system font
52
+ * font={SystemFont.Medium}
53
+ *
54
+ * @example
55
+ * // Using custom font URI
56
+ * font="pkg:/fonts/custom.ttf"
57
+ *
58
+ * @default system default font
59
+ */
60
+ font?: FontValue;
61
+
62
+ /**
63
+ * Specifies the width of the node in local coordinates.
64
+ * This includes both the area where the text is rendered and the
65
+ * scrollbar on the right.
66
+ *
67
+ * @default 0.0
68
+ */
69
+ width?: number;
70
+
71
+ /**
72
+ * Specifies the height of the node in local coordinates.
73
+ * If the text to be displayed is larger than this height, a scrollbar
74
+ * is automatically added on the right, allowing users to scroll up and
75
+ * down using the remote's arrow keys.
76
+ *
77
+ * @default 0.0
78
+ */
79
+ height?: number;
80
+
81
+ /**
82
+ * If the text is displayed on more than one line, specifies the amount
83
+ * of additional space added between lines (in pixels).
84
+ *
85
+ * @default 8
86
+ */
87
+ lineSpacing?: number;
88
+
89
+ /**
90
+ * Specifies the horizontal alignment of the text within the computed width.
91
+ * The computed width is the `width` field value minus the scrollbar width.
92
+ *
93
+ * - `"left"`: Left edge of text is drawn at x=0
94
+ * - `"center"`: Horizontal center of each line is at half the computed width
95
+ * - `"right"`: Right edge of each line is at the computed width
96
+ *
97
+ * In most cases, this should remain set to `"left"`.
98
+ *
99
+ * @default "left"
100
+ */
101
+ horizAlign?: HorizAlign;
102
+
103
+ /**
104
+ * Specifies the vertical alignment of the text within the specified height.
105
+ *
106
+ * - `"top"`: Top edge of text is drawn at y=0
107
+ * - `"center"`: Vertical center of text is at half the height
108
+ * - `"bottom"`: Bottom edge of text is at the height
109
+ *
110
+ * In most cases, this should remain set to `"top"`.
111
+ *
112
+ * @default "top"
113
+ */
114
+ vertAlign?: VertAlign;
115
+
116
+ /**
117
+ * Specifies the URI of an image file to replace the default scrollbar track.
118
+ * This should be a 9-patch image so that it can be stretched to the
119
+ * appropriate height specified by the `height` field.
120
+ *
121
+ * @default ""
122
+ */
123
+ scrollbarTrackBitmapUri?: Uri;
124
+
125
+ /**
126
+ * Specifies the URI of an image file to replace the default scrollbar thumb.
127
+ * This should be a 9-patch image so that it can be stretched to the
128
+ * appropriate size based on content length.
129
+ *
130
+ * @default ""
131
+ */
132
+ scrollbarThumbBitmapUri?: Uri;
133
+ }
@@ -0,0 +1,64 @@
1
+ // Copyright (c) 2026 Roku, Inc.
2
+ // SPDX-License-Identifier: MIT
3
+
4
+ import type { IScrollableTextProps } from "./scrollable-text.props";
5
+ import { Component } from "./types";
6
+ export type { IScrollableTextProps } from "./scrollable-text.props";
7
+
8
+ /**
9
+ * ScrollableText component for displaying vertically scrolling text content.
10
+ *
11
+ * Use ScrollableText when you need to display large amounts of text that may
12
+ * not fit within the visible area, such as:
13
+ * - License agreements
14
+ * - Terms of service
15
+ * - Long descriptions
16
+ * - Help documentation
17
+ *
18
+ * The component automatically shows a scrollbar when the text exceeds the
19
+ * specified height, and users can scroll using the remote's up/down arrow keys.
20
+ *
21
+ * @example
22
+ * ```tsx
23
+ * import { SystemFont } from "@roku-sdk/components";
24
+ *
25
+ * // Basic scrollable text panel
26
+ * <scrollableText
27
+ * text="This is a very long piece of text that will scroll..."
28
+ * width={800}
29
+ * height={400}
30
+ * font={SystemFont.Medium}
31
+ * color="#FFFFFFFF"
32
+ * />
33
+ * ```
34
+ *
35
+ * @example
36
+ * ```tsx
37
+ * // With custom scrollbar appearance
38
+ * <scrollableText
39
+ * text={licenseText}
40
+ * width={1000}
41
+ * height={500}
42
+ * lineSpacing={12}
43
+ * scrollbarTrackBitmapUri="pkg:/images/scrollbar-track.9.png"
44
+ * scrollbarThumbBitmapUri="pkg:/images/scrollbar-thumb.9.png"
45
+ * />
46
+ * ```
47
+ *
48
+ * @example
49
+ * ```tsx
50
+ * // Centered text alignment
51
+ * <scrollableText
52
+ * text="Centered scrollable content"
53
+ * width={600}
54
+ * height={300}
55
+ * horizAlign="center"
56
+ * vertAlign="top"
57
+ * />
58
+ * ```
59
+ *
60
+ * @see {@link https://developer.roku.com/dev/docs/scrollabletext}
61
+ */
62
+ export const ScrollableText: Component<IScrollableTextProps> = props => {
63
+ return <scrollableText {...props}></scrollableText>;
64
+ };