@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,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
+ }
@@ -0,0 +1,75 @@
1
+ // Copyright (c) 2026 Roku, Inc.
2
+ // SPDX-License-Identifier: MIT
3
+
4
+ import { JSX } from "@roku-sdk/solid";
5
+
6
+ import type { ILayoutGroupProps } from "./layout-group.props";
7
+ export type { ILayoutGroupProps } from "./layout-group.props";
8
+
9
+ // Re-export types for convenience
10
+ export type { LayoutGroupHorizAlign, LayoutDirection, LayoutGroupVertAlign } from "./types";
11
+
12
+ /**
13
+ * A container node that automatically positions its child nodes in either
14
+ * a horizontal row or vertical column layout with configurable alignment
15
+ * and spacing.
16
+ *
17
+ * LayoutGroup simplifies the task of positioning nodes by automatically
18
+ * calculating and applying the proper translation to each child node
19
+ * based on the `layoutDirection`, alignment settings, and `itemSpacings`.
20
+ *
21
+ * **Alignment and Translation**:
22
+ * The `horizAlignment` and `vertAlignment` properties align children relative
23
+ * to the LayoutGroup's `translation` point (default `[0, 0]`). To center
24
+ * the LayoutGroup and its content on screen, you must set the `translation`
25
+ * to the desired center point.
26
+ *
27
+ * For FHD (1920×1080) resolution:
28
+ * - Horizontal center: `1920 / 2 = 960`
29
+ * - Vertical center: `1080 / 2 = 540`
30
+ *
31
+ * @see https://developer.roku.com/dev/docs/layoutgroup
32
+ *
33
+ * @example
34
+ * // Vertical layout with left-aligned children (default)
35
+ * <layoutGroup
36
+ * layoutDirection="vert"
37
+ * itemSpacings={[20, 20, 20]}
38
+ * >
39
+ * <label text="Item 1" />
40
+ * <label text="Item 2" />
41
+ * <label text="Item 3" />
42
+ * </layoutGroup>
43
+ *
44
+ * @example
45
+ * // Center a vertical layout on screen (FHD 1920×1080)
46
+ * // translation must be set to screen center for alignment to work as expected
47
+ * <layoutGroup
48
+ * translation={[960, 540]}
49
+ * layoutDirection="vert"
50
+ * horizAlignment="center"
51
+ * vertAlignment="center"
52
+ * itemSpacings={[20, 20]}
53
+ * >
54
+ * <label text="Centered Item 1" />
55
+ * <label text="Centered Item 2" />
56
+ * <label text="Centered Item 3" />
57
+ * </layoutGroup>
58
+ *
59
+ * @example
60
+ * // Horizontal layout centered at bottom of screen (FHD)
61
+ * <layoutGroup
62
+ * translation={[960, 980]}
63
+ * layoutDirection="horiz"
64
+ * horizAlignment="center"
65
+ * vertAlignment="bottom"
66
+ * itemSpacings={[30, 30]}
67
+ * >
68
+ * <poster width={100} height={100} />
69
+ * <poster width={100} height={100} />
70
+ * <poster width={100} height={100} />
71
+ * </layoutGroup>
72
+ */
73
+ export function LayoutGroup(props: ILayoutGroupProps): JSX.Element {
74
+ return <layoutGroup {...props}></layoutGroup>;
75
+ }
@@ -0,0 +1,104 @@
1
+ // Copyright (c) 2026 Roku, Inc.
2
+ // SPDX-License-Identifier: MIT
3
+
4
+ import type { EventHandler, JSX } from "../types";
5
+ import type { IPanelProps } from "./panel.props";
6
+
7
+ /**
8
+ * Properties for the ListPanel component.
9
+ *
10
+ * ListPanel extends Panel to add a list of items that can be used to navigate
11
+ * to other panels using the Roku Sliding Panels pattern. The list can be a
12
+ * LabelList or MarkupList node, and supports the "Create Next Panel" mechanism
13
+ * for dynamic panel creation.
14
+ *
15
+ * @see {@link https://developer.roku.com/dev/docs/listpanel | Roku ListPanel Documentation}
16
+ */
17
+ export interface IListPanelProps extends IPanelProps {
18
+ /**
19
+ * A Label node to be displayed just above the upper-left corner of the list.
20
+ * Typically used to show a title or category name.
21
+ *
22
+ * @default Label node
23
+ */
24
+ leftLabel?: JSX.Element;
25
+
26
+ /**
27
+ * A Label node to be displayed just above the upper-right corner of the list.
28
+ * Typically used to show "N of M" item count information.
29
+ *
30
+ * @default Label node
31
+ */
32
+ rightLabel?: JSX.Element;
33
+
34
+ /**
35
+ * If set to true and the list is a MarkupList with sections, the section
36
+ * title for the currently focused section will be displayed as the `leftLabel`.
37
+ *
38
+ * @default false
39
+ */
40
+ showSectionLabels?: boolean;
41
+
42
+ /**
43
+ * Fired when the "Create Next Panel" mechanism is triggered. The event value
44
+ * contains the index of the list item that triggered the panel creation.
45
+ *
46
+ * This is the READ_ONLY `createNextPanelIndex` field from the SceneGraph ListPanel,
47
+ * exposed as an event handler for reactive usage.
48
+ *
49
+ * @see {@link https://developer.roku.com/dev/docs/listpanel#createNextPanelIndex | createNextPanelIndex Field}
50
+ */
51
+ onCreateNextPanelIndex?: EventHandler<number>;
52
+
53
+ /**
54
+ * A Panel node to be added to the parent PanelSet as the next panel.
55
+ * Setting this field adds the panel to the right of the current ListPanel.
56
+ *
57
+ * When using the managed `ListPanel` component, children extending Panel
58
+ * are automatically assigned to this field.
59
+ *
60
+ * @default false
61
+ */
62
+ nextPanel?: JSX.Element;
63
+
64
+ /**
65
+ * Controls whether the "Create Next Panel" mechanism is enabled.
66
+ * When true, navigating to a list item triggers the `onCreateNextPanelIndex` event.
67
+ * Set to false to disable dynamic panel creation.
68
+ *
69
+ * @default true
70
+ */
71
+ createNextPanelOnItemFocus?: boolean;
72
+ }
73
+
74
+ /**
75
+ * Properties for the unmanaged SceneGraph ListPanel component.
76
+ *
77
+ * This interface represents the raw ListPanel properties without the automatic
78
+ * child management provided by the managed `ListPanel` component. It is used
79
+ * internally and is not exposed to developers.
80
+ *
81
+ * @internal
82
+ */
83
+ export interface IFullPanelProps extends IListPanelProps {
84
+ /**
85
+ * A LabelList or MarkupList node to be displayed in the ListPanel.
86
+ * The list provides the navigation items for the panel.
87
+ *
88
+ * When using the managed `ListPanel` component, children extending ArrayGrid
89
+ * are automatically assigned to this field.
90
+ *
91
+ * @default null
92
+ */
93
+ list?: JSX.Element;
94
+ /**
95
+ * A Panel node to be added to the parent PanelSet as the next panel.
96
+ * Setting this field adds the panel to the right of the current ListPanel.
97
+ *
98
+ * When using the managed `ListPanel` component, children extending Panel
99
+ * are automatically assigned to this field.
100
+ *
101
+ * @default false
102
+ */
103
+ nextPanel?: JSX.Element;
104
+ }