@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,105 @@
1
+ // Copyright (c) 2026 Roku, Inc.
2
+ // SPDX-License-Identifier: MIT
3
+
4
+ import type { INodeProps } from "./node";
5
+ import type { EventHandler, Rect2D, ResType, Vector2D } from "./types";
6
+
7
+ /**
8
+ * Properties for the Group node.
9
+ *
10
+ * Group is a layout container node that serves as the base class for organizing and positioning
11
+ * child nodes in the SceneGraph. It provides transformation, rendering, and clipping capabilities
12
+ * for managing visual hierarchies.
13
+ *
14
+ * @see {@link https://developer.roku.com/dev/docs/group}
15
+ */
16
+ export interface IGroupProps extends INodeProps {
17
+ /** If true, the node and its children are rendered. If false, the node and its children do not render. */
18
+ visible?: boolean;
19
+ /** Defines the origin of the node local coordinate system relative to its parent node. */
20
+ translation?: ResType<Vector2D>;
21
+ /**
22
+ * Sets the opacity of the node and its children. Opacity is the opposite of transparency.
23
+ * Opacity values range from 0.0 (fully transparent) to 1.0 (fully opaque). As the SceneGraph
24
+ * is traversed, the opacity values are combined by multiplying the current accumulated opacity
25
+ * with the node opacity, so that if the accumulated opacity of a node ancestors is 0.25 (75%
26
+ * transparent), the node will have opacity of 0.25 or less. This allows entire branches of the
27
+ * SceneGraph to fade in and out by animating the opacity of the node at the root of the branch.
28
+ */
29
+ opacity?: number;
30
+ /**
31
+ * Defines the rotation angle about the scaleRotateCenter point (in radians) of the node local
32
+ * coordinate system. Positive values specify a counterclockwise rotation, negative values specify
33
+ * a clockwise rotation. For some Roku Player hardware, specifically Roku Players without OpenGL
34
+ * graphics support, only rotations of 0, 90, 180 and 270 degrees (in equivalent radians) are supported.
35
+ */
36
+ rotation?: number;
37
+ /** Defines the scale factor to be applied to the node local coordinate. */
38
+ scale?: Vector2D;
39
+ /** Describes the location of a point in the node local coordinate that serves as the center of the scale and rotation operations. */
40
+ scaleRotateCenter?: ResType<Vector2D>;
41
+ /**
42
+ * Controls the rendering order of the node relative to its children.
43
+ * - "renderFirst": any drawing done by this node will be done before the node children are rendered
44
+ * - "renderLast": any drawing done by this node will be done after the node children are rendered (default)
45
+ */
46
+ childRenderOrder?: "renderFirst" | "renderLast";
47
+ /**
48
+ * If true, the node overall transformation is determined by combining the accumulated transformation
49
+ * matrix of all of its ancestors in the SceneGraph with the node local 2D transformation matrix
50
+ * described by its translation, rotation, scale and scaleRotateCenter fields. If false, the accumulated
51
+ * transformation of all of its ancestors in the SceneGraph is ignored and only the node local
52
+ * transformation matrix is used. This causes the node to be transformed relative to the root of the
53
+ * SceneGraph (that is, the Scene component).
54
+ */
55
+ inheritParentTransform?: boolean;
56
+ /**
57
+ * If true, the node opacity is determined by multiplying opacity attribute of the node by the opacity
58
+ * of the parent node, which may have been determined by multiplying the opacity of its ancestor nodes.
59
+ * If false, the node opacity is determined by the opacity attribute set for the node or the default
60
+ * opacity attribute value.
61
+ */
62
+ inheritParentOpacity?: boolean;
63
+ /**
64
+ * Specifies a rectangle in the node local coordinate system that is used to limit the region where
65
+ * this node and its children can render. If a non-empty rectangle is specified, then all drawing by
66
+ * this node and its children will be limited to that rectangular area.
67
+ * ClippingRects can be specified by the node or by any of its ancestors in the SceneGraph.
68
+ * ClippingRects are automatically set by some nodes such as lists and grids.
69
+ * ClippingRects are always clipped to the screen boundaries, so if a clippingRect is specified that
70
+ * is partially or completely offscreen, it will be clipped to the screen boundaries. With respect to
71
+ * render tracking, although the node could be completely within the bounds of the specified clippingRect,
72
+ * it's renderTracking field could be set to "none" if the portion of the clippingRect it occupies is
73
+ * completely offscreen.
74
+ */
75
+ clippingRect?: ResType<Rect2D>;
76
+ /**
77
+ * Used in combination with the numRenderPasses field of nodes extended from the ArrayGrid abstract
78
+ * node class, to optimize rendering of lists and grids. This should never be set to a non-zero value
79
+ * unless you are optimizing the performance of a list or grid rendering by specifying the sequence of
80
+ * rendering operations for sub-elements of the list or grid items, and have set the numRenderPasses
81
+ * field value for the list or grid to a value greater than 1. If the numRenderPasses field value for
82
+ * the list or grid is set to a value greater than 1, you must set this field to a value greater than 0
83
+ * for all sub-elements of the list or grid items, and not greater than the numRenderPasses field value.
84
+ * If the numRenderPasses field is set to a value greater than 1, and you set this field for a list or
85
+ * grid item sub-element to 0 (the default), or a value greater than the numRenderPasses field value,
86
+ * the list or grid item sub-element will not render.
87
+ */
88
+ renderPass?: number;
89
+ /** Set to true to suppress the default CVAA text to speech. This allows apps to provide their own custom implementation. */
90
+ muteAudioGuide?: boolean;
91
+ /** If true, renderTracking will be set to a string describing how much of the node is rendered on screen. */
92
+ enableRenderTracking?: boolean;
93
+ /**
94
+ * Event fired when the render tracking state changes. The value is set to "disabled" when enableRenderTracking
95
+ * is set to false. The following options are only available when enableRenderTracking is set to true:
96
+ * - "disabled": Set when enableRenderTracking is false.
97
+ * - "none": Set when the node's visible field is false, opacity is 0.0, the node is completely offscreen,
98
+ * or lies completely outside the clippingRect's coordinates.
99
+ * - "partial": Set when the node is visible with opacity > 0.0 and is partially offscreen or lies partially
100
+ * inside the clippingRect's coordinates.
101
+ * - "full": Set when the node is visible with opacity > 0.0 and is completely onscreen or lies completely
102
+ * inside the clippingRect's coordinates.
103
+ */
104
+ onRenderTracking?: EventHandler<"disabled" | "none" | "partial" | "full">;
105
+ }
@@ -0,0 +1,30 @@
1
+ // Copyright (c) 2026 Roku, Inc.
2
+ // SPDX-License-Identifier: MIT
3
+
4
+ import type { IGroupProps } from "./group.props";
5
+ import { Component } from "./types";
6
+ export type { IGroupProps } from "./group.props";
7
+
8
+ /**
9
+ * Group component - a layout container for organizing and positioning child nodes.
10
+ *
11
+ * Group is a layout container node that serves as the base class for organizing and positioning
12
+ * child nodes in the SceneGraph. It provides transformation, rendering, and clipping capabilities
13
+ * for managing visual hierarchies.
14
+ *
15
+ * @example
16
+ * ```tsx
17
+ * <group
18
+ * translation={[100, 50]}
19
+ * opacity={0.8}
20
+ * >
21
+ * <rectangle width={200} height={100} color="#0000FFFF" />
22
+ * <label text="Hello World" />
23
+ * </group>
24
+ * ```
25
+ *
26
+ * @see {@link https://developer.roku.com/dev/docs/group}
27
+ */
28
+ export const Group: Component<IGroupProps> = (props: IGroupProps) => {
29
+ return <group {...props}></group>;
30
+ };
@@ -0,0 +1,86 @@
1
+ // Copyright (c) 2026 Roku, Inc.
2
+ // SPDX-License-Identifier: MIT
3
+
4
+ import type { IArrayGridProps } from "./array-grid";
5
+ import type { FontValue, HorizAlign, ResType, Vector2D } from "./types";
6
+
7
+ /**
8
+ * Properties for the LabelList component.
9
+ *
10
+ * Extends {@link IArrayGridProps} with text styling and alignment options
11
+ * specific to label-based list items.
12
+ *
13
+ * @see {@link https://developer.roku.com/dev/docs/labellist}
14
+ */
15
+ export interface ILabelListProps extends IArrayGridProps {
16
+ /**
17
+ * Specifies the horizontal alignment of the text in the list item area
18
+ * specified by the `itemSize` field value. The text is always centered
19
+ * vertically in the list item area.
20
+ *
21
+ * @default "left"
22
+ * @see {@link https://developer.roku.com/dev/docs/labellist | LabelList textHorizAlign}
23
+ */
24
+ textHorizAlign?: HorizAlign;
25
+
26
+ /**
27
+ * Specifies the text color for unfocused list items.
28
+ *
29
+ * @default "0xddddddff"
30
+ * @example "0xFFFFFFFF"
31
+ */
32
+ color?: string;
33
+
34
+ /**
35
+ * Specifies the text color for focused list items.
36
+ *
37
+ * @default "0x262626ff"
38
+ * @example "0x000000FF"
39
+ */
40
+ focusedColor?: string;
41
+
42
+ /**
43
+ * Specifies the font for unfocused list items.
44
+ * Can be a SystemFont enum, registry font string, or Font component.
45
+ *
46
+ * @default system default
47
+ * @example
48
+ * ```tsx
49
+ * // Using SystemFont enum (recommended)
50
+ * font={SystemFont.Medium}
51
+ *
52
+ * // Using registry font string
53
+ * font="font:MediumSystemFont"
54
+ *
55
+ * // Using Font component for custom size
56
+ * font={<Font uri="pkg:/fonts/MyFont.ttf" size={24} />}
57
+ * ```
58
+ */
59
+ font?: FontValue;
60
+
61
+ /**
62
+ * Specifies the font for focused list items.
63
+ * Can be a SystemFont enum, registry font string, or Font component.
64
+ *
65
+ * @default system default
66
+ * @example
67
+ * ```tsx
68
+ * // Using SystemFont enum (recommended)
69
+ * focusedFont={SystemFont.MediumBold}
70
+ *
71
+ * // Using registry font string
72
+ * focusedFont="font:MediumBoldSystemFont"
73
+ *
74
+ * // Using Font component for custom size
75
+ * focusedFont={<Font uri="pkg:/fonts/MyFontBold.ttf" size={24} />}
76
+ * ```
77
+ */
78
+ focusedFont?: FontValue;
79
+
80
+ /**
81
+ * Specifies the width and height of each item in the list.
82
+ *
83
+ * @default [ 510, 72 ] for FHD mode, [ 340, 48 ] for HD mode
84
+ */
85
+ itemSize?: ResType<Vector2D>;
86
+ }
@@ -0,0 +1,64 @@
1
+ // Copyright (c) 2026 Roku, Inc.
2
+ // SPDX-License-Identifier: MIT
3
+
4
+ import type { ILabelListProps } from "./label-list.props";
5
+ import { Component } from "./types";
6
+ export type { ILabelListProps } from "./label-list.props";
7
+
8
+ // ─────────────────────────────────────────────────────────────────────────────
9
+ // LabelList Properties
10
+ // ─────────────────────────────────────────────────────────────────────────────
11
+
12
+ /**
13
+ * LabelList is a simple list class that displays a list of text items.
14
+ *
15
+ * Each item can include a text string and an optional icon positioned to the left
16
+ * of the text string. List items can be organized into sections demarcated by
17
+ * labelled horizontal divider lines.
18
+ *
19
+ * Default value for `itemSize` is `[510, 72]` for FHD mode, and `[340, 48]` for HD mode.
20
+ *
21
+ * @example Basic usage
22
+ * ```tsx
23
+ * <labelList
24
+ * itemSize={[440, 48]}
25
+ * textHorizAlign="left"
26
+ * color="0xddddddff"
27
+ * focusedColor="0x262626ff"
28
+ * content={
29
+ * <contentNode>
30
+ * <contentNode title="Drama" />
31
+ * <contentNode title="Action" />
32
+ * <contentNode title="Horror" />
33
+ * <contentNode title="Comedy" />
34
+ * </contentNode>
35
+ * }
36
+ * onItemSelected={(index) => console.log(`Selected: ${index}`)}
37
+ * />
38
+ * ```
39
+ *
40
+ * @example With sections
41
+ * ```tsx
42
+ * <labelList
43
+ * itemSize={[440, 48]}
44
+ * content={
45
+ * <contentNode>
46
+ * <contentNode CONTENTTYPE="SECTION" title="Movies">
47
+ * <contentNode title="Drama" />
48
+ * <contentNode title="Action" />
49
+ * </contentNode>
50
+ * <contentNode CONTENTTYPE="SECTION" title="TV Shows">
51
+ * <contentNode title="Comedy" />
52
+ * <contentNode title="Drama" />
53
+ * </contentNode>
54
+ * </contentNode>
55
+ * }
56
+ * />
57
+ * ```
58
+ *
59
+ * @see {@link https://developer.roku.com/dev/docs/labellist}
60
+ * @see {@link https://github.com/rokudev/samples/tree/master/ux%20components/lists%20and%20grids/LabelListExample | Sample App}
61
+ */
62
+ export const LabelList: Component<ILabelListProps> = props => {
63
+ return <labelList {...props}></labelList>;
64
+ };
@@ -0,0 +1,207 @@
1
+ // Copyright (c) 2026 Roku, Inc.
2
+ // SPDX-License-Identifier: MIT
3
+
4
+ import type { EventHandler, FontValue, HorizAlign, ResType, VertAlign } from "../types";
5
+ import type { IGroupProps } from "./group.props";
6
+
7
+ /**
8
+ * Properties for the LabelBase node.
9
+ *
10
+ * LabelBase is an abstract base class for the Label and MultiStyleLabel nodes. It provides
11
+ * common text rendering properties including alignment, line wrapping, and ellipsization.
12
+ *
13
+ * @see {@link https://developer.roku.com/dev/docs/label-base}
14
+ */
15
+ export interface ILabelBaseProps extends IGroupProps {
16
+ /** Specifies the text to be displayed. */
17
+ text?: string;
18
+ /**
19
+ * Specifies the width of the label. If set to zero, the text is always displayed as a single line,
20
+ * and the actual width is determined by the rendered width of the text.
21
+ */
22
+ width?: ResType<number>;
23
+ /**
24
+ * Specifies the height of the label. If set to zero, the actual height is determined by the value
25
+ * of the numLines field if it is greater than zero, or by the actual height of the text.
26
+ */
27
+ height?: ResType<number>;
28
+ /**
29
+ * Font to use for rendering text. Can be a system font or custom font path.
30
+ *
31
+ * **System Fonts (use SystemFont enum or strings):**
32
+ *
33
+ * Regular fonts:
34
+ * - `SystemFont.Small` or `"font:SmallSystemFont"`
35
+ * - `SystemFont.Medium` or `"font:MediumSystemFont"`
36
+ * - `SystemFont.Large` or `"font:LargeSystemFont"`
37
+ * - `SystemFont.ExtraLarge` or `"font:ExtraLargeSystemFont"`
38
+ *
39
+ * Bold fonts:
40
+ * - `SystemFont.SmallBold` or `"font:SmallBoldSystemFont"`
41
+ * - `SystemFont.MediumBold` or `"font:MediumBoldSystemFont"`
42
+ * - `SystemFont.LargeBold` or `"font:LargeBoldSystemFont"`
43
+ * - `SystemFont.ExtraLargeBold` or `"font:ExtraLargeBoldSystemFont"`
44
+ *
45
+ * Other:
46
+ * - `SystemFont.Caption` or `"font:CaptionFont"`
47
+ * - `SystemFont.ClosedCaption` or `"font:ClosedCaptionFont"`
48
+ * - `SystemFont.Theme` or `"font:ThemeFont"`
49
+ *
50
+ * @example
51
+ * ```tsx
52
+ * // Using system font enum (recommended)
53
+ * <Label font={SystemFont.Large} text="Large text" />
54
+ *
55
+ * // Using registry font string
56
+ * <Label font="font:LargeSystemFont" text="Large text" />
57
+ *
58
+ * // Using Font component for custom size
59
+ * <Label font={<Font uri="pkg:/fonts/CustomFont.ttf" size={32} />} text="Custom sized font" />
60
+ * ```
61
+ */
62
+ font?: FontValue;
63
+ /** Specifies the text color. Default is 0xddddddff. */
64
+ color?: string;
65
+ /**
66
+ * Specifies the horizontal alignment of the text. Positions text relative to the computed width of the label.
67
+ * - "left": Aligns text to the left edge
68
+ * - "center": Centers text horizontally
69
+ * - "right": Aligns text to the right edge
70
+ */
71
+ horizAlign?: HorizAlign;
72
+ /**
73
+ * Specifies the vertical alignment of the text. Positions text relative to the computed height of the label.
74
+ * - "top": Aligns text to the top edge
75
+ * - "center": Centers text vertically
76
+ * - "bottom": Aligns text to the bottom edge
77
+ */
78
+ vertAlign?: VertAlign;
79
+ /**
80
+ * Renders numeric values using tabular (fixed-width) fonts, ensuring digits align vertically
81
+ * across multiple lines of text.
82
+ * @since Roku OS 14.0
83
+ */
84
+ monospacedDigits?: boolean;
85
+ /**
86
+ * If the height field value is zero, provides an alternate way to specify the height of the bounding
87
+ * rectangle of the label by specifying the number of lines of text to display.
88
+ */
89
+ numLines?: number;
90
+ /**
91
+ * If both height and numLines field values are zero, specifies the maximum number of lines of text
92
+ * to be displayed. If the text requires more lines than maxLines, the last line will be ellipsized.
93
+ */
94
+ maxLines?: number;
95
+ /**
96
+ * Controls how text is broken into multiple lines. When true and width is greater than zero,
97
+ * text is broken into lines at natural word boundaries. When false, only a single line is displayed.
98
+ */
99
+ wrap?: boolean;
100
+ /**
101
+ * If the height field value is greater than zero, determines whether the last line of visible text
102
+ * is displayed if it would be clipped vertically. When true, partially visible lines are shown.
103
+ */
104
+ displayPartialLines?: boolean;
105
+ /**
106
+ * Controls whether the last line of text should be ellipsized by whole words or by characters.
107
+ * When true, text is ellipsized by whole words (e.g., "This is the last line of...").
108
+ * When false, text is ellipsized by characters (e.g., "This is the last line of tex...").
109
+ */
110
+ ellipsizeOnBoundary?: boolean;
111
+ /**
112
+ * Specifies additional characters (beyond space and hyphen) to be used to determine where text
113
+ * can be broken into lines when wrapping.
114
+ */
115
+ wordBreakChars?: string;
116
+ /** Specifies alternate characters to display when the last line of text is ellipsized. Default is "...". */
117
+ ellipsisText?: string;
118
+ /**
119
+ * Event fired when the isTextEllipsized state changes. The handler receives a boolean indicating
120
+ * whether the last line of text has been ellipsized.
121
+ */
122
+ onIsTextEllipsized?: EventHandler<boolean>;
123
+ }
124
+
125
+ /**
126
+ * Properties for the Label node.
127
+ *
128
+ * Label is used to display a string of text with a single style. It extends LabelBase
129
+ * with additional properties for line spacing and text truncation control.
130
+ *
131
+ * @see {@link https://developer.roku.com/dev/docs/label}
132
+ */
133
+ export interface ILabelProps extends ILabelBaseProps {
134
+ /**
135
+ * If the text is displayed on more than one line, specifies the amount of additional space
136
+ * added between lines (in pixels).
137
+ */
138
+ lineSpacing?: number;
139
+ /**
140
+ * If the width field value is greater than zero, provides a set of characters used to determine
141
+ * how to truncate the last line of text that extends beyond the specified width. If none of the
142
+ * characters in the last line of text are included in the truncateOnDelimiter field value string,
143
+ * the entire last line is not displayed. When set to a non-empty string, the ellipsizeOnBoundary
144
+ * field value is ignored.
145
+ */
146
+ truncateOnDelimiter?: string;
147
+ /**
148
+ * Specifies whether to display the end or beginning of text that overflows its available width.
149
+ * When true, the end of the text is shown with leading ellipsis (e.g., "...jumps over the lazy dog").
150
+ * When false, the start of the text is shown with trailing ellipsis (e.g., "the quick brown fox jumps...").
151
+ */
152
+ leadingEllipsis?: boolean;
153
+ /**
154
+ * Event fired when the wrappedLines value changes. The handler receives the number of wrapped
155
+ * lines currently displayed in the label.
156
+ */
157
+ onWrappedLines?: EventHandler<number>;
158
+ }
159
+
160
+ /**
161
+ * Defines the font styling properties for a named style in MultiStyleLabel.
162
+ *
163
+ * DrawingStyle specifies the size, URI, and color of a font style that can be
164
+ * referenced by name in the MultiStyleLabel's text content using markup tags.
165
+ */
166
+ export interface DrawingStyle {
167
+ /**
168
+ * Specifies the size of the font in points.
169
+ * Note: This value is ignored when using system fonts.
170
+ */
171
+ fontSize?: number;
172
+ /**
173
+ * Specifies a TrueType/OpenType font file (e.g., "pkg:/fonts/font.ttf")
174
+ * or a system font URI (e.g., "font:MediumBoldSystemFont").
175
+ */
176
+ fontUri?: string;
177
+ /** Specifies the text color in hex format (e.g., "#FF0000FF" for red). */
178
+ color?: string;
179
+ }
180
+
181
+ /**
182
+ * Properties for the MultiStyleLabel node.
183
+ *
184
+ * MultiStyleLabel is used to create labels with mixed styles, allowing different fonts,
185
+ * sizes, and colors within the same text block. Styles are defined in the drawingStyles
186
+ * property and applied using markup tags in the text content.
187
+ *
188
+ * @see {@link https://developer.roku.com/dev/docs/multi-style-label}
189
+ */
190
+ export interface IMultiStyleLabelProps extends ILabelBaseProps {
191
+ /**
192
+ * Defines named font styles that can be applied to portions of the text.
193
+ * Each key becomes a markup tag name that can be used in the text property.
194
+ *
195
+ * @example
196
+ * ```tsx
197
+ * drawingStyles={{
198
+ * bold: { fontUri: "font:MediumBoldSystemFont", color: "#FFFFFFFF" },
199
+ * highlight: { fontUri: "font:MediumSystemFont", color: "#FFFF00FF" }
200
+ * }}
201
+ * // Then use in text: "Normal <bold>bold text</bold> and <highlight>highlighted</highlight>"
202
+ * ```
203
+ */
204
+ drawingStyles?: {
205
+ [key: string]: DrawingStyle;
206
+ };
207
+ }
@@ -0,0 +1,56 @@
1
+ // Copyright (c) 2026 Roku, Inc.
2
+ // SPDX-License-Identifier: MIT
3
+
4
+ import { Component } from "../types";
5
+ import type { ILabelProps, IMultiStyleLabelProps } from "./label.props";
6
+ export type { ILabelBaseProps, ILabelProps, DrawingStyle, IMultiStyleLabelProps } from "./label.props";
7
+
8
+ /**
9
+ * Label component for displaying single-style text.
10
+ *
11
+ * The Label node is used to display a string of text with a single font, size, and color.
12
+ * It provides extensive control over text layout, wrapping, and ellipsization.
13
+ *
14
+ * @example
15
+ * ```tsx
16
+ * <label
17
+ * text="Hello, World!"
18
+ * font={SystemFont.Large}
19
+ * color="#FFFFFFFF"
20
+ * width={400}
21
+ * wrap={true}
22
+ * horizAlign="center"
23
+ * />
24
+ * ```
25
+ *
26
+ * @see {@link https://developer.roku.com/dev/docs/label}
27
+ */
28
+ export const Label: Component<ILabelProps> = props => {
29
+ return <label {...props}></label>;
30
+ };
31
+
32
+ /**
33
+ * MultiStyleLabel component for displaying text with mixed styles.
34
+ *
35
+ * The MultiStyleLabel node allows different fonts, sizes, and colors to be combined
36
+ * within the same text block using simple markup syntax. Define styles in drawingStyles
37
+ * and reference them by name as XML-like tags in the text content.
38
+ *
39
+ * @example
40
+ * ```tsx
41
+ * <multiStyleLabel
42
+ * text="Welcome to <appName>My App</appName>! Press <key>OK</key> to continue."
43
+ * width={600}
44
+ * wrap={true}
45
+ * drawingStyles={{
46
+ * appName: { fontUri: "font:LargeBoldSystemFont", color: "#00FF00FF" },
47
+ * key: { fontUri: "font:MediumBoldSystemFont", color: "#FFFF00FF" }
48
+ * }}
49
+ * />
50
+ * ```
51
+ *
52
+ * @see {@link https://developer.roku.com/dev/docs/multi-style-label}
53
+ */
54
+ export const MultiStyleLabel: Component<IMultiStyleLabelProps> = props => {
55
+ return <multiStyleLabel {...props}></multiStyleLabel>;
56
+ };
@@ -0,0 +1,69 @@
1
+ // Copyright (c) 2026 Roku, Inc.
2
+ // SPDX-License-Identifier: MIT
3
+
4
+ import type { IGroupProps } from "./group.props";
5
+ import type { LayoutDirection, LayoutGroupHorizAlign, LayoutGroupVertAlign } from "./types";
6
+
7
+ /**
8
+ * Props for the LayoutGroup component.
9
+ * @extends IGroupProps
10
+ */
11
+ export interface ILayoutGroupProps extends IGroupProps {
12
+ /**
13
+ * Specifies whether the children of the LayoutGroup are arranged
14
+ * vertically or horizontally.
15
+ * - `"vert"`: Children are arranged vertically in a column
16
+ * - `"horiz"`: Children are arranged horizontally in a row
17
+ * @default "vert"
18
+ */
19
+ layoutDirection?: LayoutDirection;
20
+
21
+ /**
22
+ * Specifies the horizontal alignment of the children of the LayoutGroup.
23
+ * - `"left"`: Children are left-aligned
24
+ * - `"center"`: Children are centered horizontally
25
+ * - `"right"`: Children are right-aligned
26
+ * - `"custom"`: Explicitly set the x translation of each child of the LayoutGroup. If the layoutDirection is "horiz", custom will not be a valid setting. Instead, "left" will be used to do the child layout.
27
+ *
28
+ * **Important**: Alignment is relative to the LayoutGroup's `translation` point.
29
+ * The default translation is `[0, 0]` (top-left corner). To center children
30
+ * on screen, set `translation` to the screen center (e.g., `[960, 540]` for FHD).
31
+ *
32
+ * @default "left"
33
+ */
34
+ horizAlignment?: LayoutGroupHorizAlign;
35
+
36
+ /**
37
+ * Specifies the vertical alignment of the children of the LayoutGroup.
38
+ * - `"top"`: Children are top-aligned
39
+ * - `"center"`: Children are centered vertically
40
+ * - `"bottom"`: Children are bottom-aligned
41
+ * - `"custom"`: Explicitly set the y translation of each child of the LayoutGroup. If the layoutDirection is "vert", custom will not be a valid setting. Instead, "top" will be used to do the child layout.
42
+ *
43
+ * **Important**: Alignment is relative to the LayoutGroup's `translation` point.
44
+ * The default translation is `[0, 0]` (top-left corner). To center children
45
+ * on screen, set `translation` to the screen center (e.g., `[960, 540]` for FHD).
46
+ *
47
+ * @default "top"
48
+ */
49
+ vertAlignment?: LayoutGroupVertAlign;
50
+
51
+ /**
52
+ * Specifies the spacing between children of the LayoutGroup.
53
+ * The array contains spacing values where each element corresponds
54
+ * to the space after the child at that index. If the array has fewer
55
+ * elements than children, the last value is used for remaining spaces.
56
+ * If empty, no spacing is applied between children.
57
+ * @default []
58
+ */
59
+ itemSpacings?: number[];
60
+
61
+ /**
62
+ * When set to `true`, adds spacing after the last child node.
63
+ * When set to `false`, no spacing is added after the last child.
64
+ * This is useful for controlling the total height/width of the LayoutGroup
65
+ * when `itemSpacings` is specified.
66
+ * @default true
67
+ */
68
+ addItemSpacingAfterChild?: boolean;
69
+ }