@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,106 @@
1
+ // Copyright (c) 2026 Roku, Inc.
2
+ // SPDX-License-Identifier: MIT
3
+
4
+ import type { IGroupProps } from "./group.props";
5
+ import type { FontValue, HorizAlign, ResType, VertAlign } from "./types";
6
+
7
+ /**
8
+ * Properties for the ScrollingLabel node.
9
+ *
10
+ * ScrollingLabel displays a string of text that automatically scrolls horizontally
11
+ * if the text length exceeds the specified maximum width.
12
+ *
13
+ * **Scrolling Behavior:**
14
+ * - If the text fits within `maxWidth`, it is simply drawn without scrolling
15
+ * - If the text exceeds `maxWidth`, it is initially drawn with an ellipsis (...),
16
+ * then transitions to the full string and scrolls left to right, returning
17
+ * to the ellipsized state after scrolling completes
18
+ *
19
+ * @extends Group
20
+ * @see {@link https://developer.roku.com/dev/docs/scrollinglabel}
21
+ */
22
+ export interface IScrollingLabelProps extends IGroupProps {
23
+ /**
24
+ * Specifies the text string to be displayed.
25
+ *
26
+ * @default ""
27
+ */
28
+ text?: string;
29
+
30
+ /**
31
+ * Specifies the text color as a hex value (e.g., `0xRRGGBBAA`).
32
+ *
33
+ * @default 0xddddddff
34
+ */
35
+ color?: string;
36
+
37
+ /**
38
+ * Specifies the Font node to use for rendering the text.
39
+ * Can be a system font enum value or a custom font URI string.
40
+ *
41
+ * @example
42
+ * // Using system font
43
+ * font={SystemFont.Medium}
44
+ *
45
+ * @example
46
+ * // Using custom font URI
47
+ * font="pkg:/fonts/custom.ttf"
48
+ *
49
+ * @default system default font
50
+ */
51
+ font?: FontValue;
52
+
53
+ /**
54
+ * Specifies the maximum width of the rendered text in local coordinates.
55
+ * If the rendered text width exceeds this value, the scrolling behavior
56
+ * is automatically triggered.
57
+ *
58
+ * @default 500
59
+ */
60
+ maxWidth?: ResType<number>;
61
+
62
+ /**
63
+ * Specifies the height of the label in local coordinates.
64
+ * If set to 0, the actual height is determined by the font metrics.
65
+ *
66
+ * @default 0
67
+ */
68
+ height?: ResType<number>;
69
+
70
+ /**
71
+ * Specifies the horizontal scrolling speed in pixels per second.
72
+ *
73
+ * @default 100
74
+ */
75
+ scrollSpeed?: number;
76
+
77
+ /**
78
+ * Controls the scrolling repeat behavior:
79
+ * - `-1`: Scrolls continuously (default)
80
+ * - `0`: Text remains ellipsized and never scrolls
81
+ * - `> 0`: Scrolls the specified number of times, then shows ellipsis
82
+ *
83
+ * @default -1
84
+ */
85
+ repeatCount?: number;
86
+
87
+ /**
88
+ * Specifies the horizontal alignment of the text within the label bounds.
89
+ * - `"left"`: Left edge of the text is drawn at the 0 x-coordinate
90
+ * - `"center"`: Horizontal center of the text is drawn at half the computed width
91
+ * - `"right"`: Right edge of the text is drawn at the computed width
92
+ *
93
+ * @default "left"
94
+ */
95
+ horizAlign?: HorizAlign;
96
+
97
+ /**
98
+ * Specifies the vertical alignment of the text within the label bounds.
99
+ * - `"top"`: Top edge of the text is drawn at the 0 y-coordinate
100
+ * - `"center"`: Vertical center of the text is drawn at half the computed height
101
+ * - `"bottom"`: Bottom edge of the text is drawn at the computed height
102
+ *
103
+ * @default "top"
104
+ */
105
+ vertAlign?: VertAlign;
106
+ }
@@ -0,0 +1,42 @@
1
+ // Copyright (c) 2026 Roku, Inc.
2
+ // SPDX-License-Identifier: MIT
3
+
4
+ import type { IScrollingLabelProps } from "./scrolling-label.props";
5
+ import { Component } from "./types";
6
+ export type { IScrollingLabelProps } from "./scrolling-label.props";
7
+
8
+ /**
9
+ * ScrollingLabel component for displaying horizontally scrolling text.
10
+ *
11
+ * Use ScrollingLabel when you need to display text that may exceed a fixed width
12
+ * and should scroll to reveal the full content. This is commonly used for titles,
13
+ * descriptions, or any text that may be truncated.
14
+ *
15
+ * @example
16
+ * ```tsx
17
+ * import { SystemFont } from "@roku-sdk/components";
18
+ *
19
+ * <scrollingLabel
20
+ * text="This is a long text that will scroll if it exceeds maxWidth"
21
+ * maxWidth={400}
22
+ * scrollSpeed={80}
23
+ * font={SystemFont.Medium}
24
+ * color="0xFFFFFFFF"
25
+ * />
26
+ * ```
27
+ *
28
+ * @example
29
+ * ```tsx
30
+ * // Scroll only 3 times then show ellipsis
31
+ * <scrollingLabel
32
+ * text="Limited scroll text"
33
+ * maxWidth={200}
34
+ * repeatCount={3}
35
+ * />
36
+ * ```
37
+ *
38
+ * @see {@link https://developer.roku.com/dev/docs/scrollinglabel}
39
+ */
40
+ export const ScrollingLabel: Component<IScrollingLabelProps> = props => {
41
+ return <scrollingLabel {...props}></scrollingLabel>;
42
+ };
@@ -0,0 +1,156 @@
1
+ // Copyright (c) 2026 Roku, Inc.
2
+ // SPDX-License-Identifier: MIT
3
+
4
+ import type { IGroupProps } from "./group.props";
5
+ import type { HorizAlign } from "./types";
6
+
7
+ /**
8
+ * Horizontal origin options for SimpleLabel positioning.
9
+ * Controls the x=0 position of the SimpleLabel node's local coordinate system.
10
+ */
11
+ export type HorizOrigin = HorizAlign;
12
+
13
+ /**
14
+ * Vertical origin options for SimpleLabel positioning.
15
+ * Controls the y=0 position of the SimpleLabel node's local coordinate system.
16
+ *
17
+ * - `"top"`: Top edge of the text is at the 0 y-coordinate
18
+ * - `"center"`: Vertical center of the text is at the 0 y-coordinate
19
+ * - `"baseline"`: Baseline of the text is at the 0 y-coordinate
20
+ * - `"bottom"`: Bottom edge of the text is at the 0 y-coordinate
21
+ */
22
+ export type VertOrigin = "top" | "center" | "baseline" | "bottom";
23
+
24
+ /**
25
+ * Font URI options for SimpleLabel.
26
+ *
27
+ * Can be either:
28
+ * - A path to a TrueType or OpenType font file (e.g., `pkg:/fonts/MyFont.ttf`)
29
+ * - A built-in system font name using the `font:` prefix
30
+ *
31
+ * **Built-in System Fonts (Fixed Size):**
32
+ * - `font:SmallestSystemFont`
33
+ * - `font:SmallSystemFont`
34
+ * - `font:MediumSystemFont`
35
+ * - `font:LargeSystemFont`
36
+ * - `font:SmallestBoldSystemFont`
37
+ * - `font:SmallBoldSystemFont`
38
+ * - `font:MediumBoldSystemFont`
39
+ * - `font:LargeBoldSystemFont`
40
+ *
41
+ * **Built-in System Fonts (Variable Size - respects fontSize):**
42
+ * - `font:SystemFontFile`
43
+ * - `font:BoldSystemFontFile`
44
+ */
45
+ export type SimpleLabelFontUri = string;
46
+
47
+ /**
48
+ * Properties for the SimpleLabel node.
49
+ *
50
+ * SimpleLabel is a lightweight component for displaying a single line of text.
51
+ * It is more memory efficient than the Label node and supports simplified font
52
+ * style specification.
53
+ *
54
+ * **Features:**
55
+ * - Built-in system fonts or TrueType/OpenType font files
56
+ * - Customizable text color
57
+ * - Flexible horizontal and vertical origin positioning
58
+ * - Rotation support (center of rotation determined by origin point)
59
+ *
60
+ * @extends Group
61
+ * @see {@link https://developer.roku.com/dev/docs/simplelabel}
62
+ *
63
+ * @example
64
+ * <SimpleLabel
65
+ * text="Hello World"
66
+ * fontUri="font:MediumBoldSystemFont"
67
+ * color="#FFFFFFFF"
68
+ * horizOrigin="center"
69
+ * vertOrigin="baseline"
70
+ * />
71
+ */
72
+ export interface ISimpleLabelProps extends IGroupProps {
73
+ /**
74
+ * Specifies the text string to be displayed.
75
+ *
76
+ * @default ""
77
+ */
78
+ text?: string;
79
+
80
+ /**
81
+ * Specifies the text color as a hex value (e.g., `0xRRGGBBAA` or `#RRGGBBAA`).
82
+ *
83
+ * @default 0xddddddff
84
+ */
85
+ color?: string;
86
+
87
+ /**
88
+ * Specifies either a path to a TrueType/OpenType font file or a built-in
89
+ * system font name.
90
+ *
91
+ * For TrueType or OpenType font files, the file must be included with the
92
+ * application (e.g., `pkg:/fonts/SomeFontFile.ttf`). If no fontUri is
93
+ * specified, the System Default font is used.
94
+ *
95
+ * **Fixed Size System Fonts** (fontSize field is ignored):
96
+ * - `font:SmallestSystemFont`
97
+ * - `font:SmallSystemFont`
98
+ * - `font:MediumSystemFont`
99
+ * - `font:LargeSystemFont`
100
+ * - `font:SmallestBoldSystemFont`
101
+ * - `font:SmallBoldSystemFont`
102
+ * - `font:MediumBoldSystemFont`
103
+ * - `font:LargeBoldSystemFont`
104
+ *
105
+ * **Variable Size System Fonts** (fontSize field is respected):
106
+ * - `font:SystemFontFile`
107
+ * - `font:BoldSystemFontFile`
108
+ *
109
+ * @example
110
+ * // Using a built-in system font
111
+ * fontUri="font:MediumBoldSystemFont"
112
+ *
113
+ * @example
114
+ * // Using a custom TrueType font
115
+ * fontUri="pkg:/fonts/CustomFont.ttf"
116
+ *
117
+ * @default system default
118
+ */
119
+ fontUri?: SimpleLabelFontUri;
120
+
121
+ /**
122
+ * Specifies the size of the font in points.
123
+ *
124
+ * **Note:** This field is only respected when using variable size system fonts
125
+ * (`font:SystemFontFile` or `font:BoldSystemFontFile`) or custom font files.
126
+ * Fixed size system fonts ignore this value.
127
+ *
128
+ * @default system default
129
+ */
130
+ fontSize?: number;
131
+
132
+ /**
133
+ * Controls the horizontal origin (x=0 position) of the SimpleLabel's local
134
+ * coordinate system.
135
+ *
136
+ * - `"left"`: Left edge of text is at x=0
137
+ * - `"center"`: Horizontal center of text is at x=0
138
+ * - `"right"`: Right edge of text is at x=0
139
+ *
140
+ * @default "left"
141
+ */
142
+ horizOrigin?: HorizOrigin;
143
+
144
+ /**
145
+ * Controls the vertical origin (y=0 position) of the SimpleLabel's local
146
+ * coordinate system.
147
+ *
148
+ * - `"top"`: Top edge of text is at y=0
149
+ * - `"center"`: Vertical center of text is at y=0
150
+ * - `"baseline"`: Text baseline is at y=0
151
+ * - `"bottom"`: Bottom edge of text is at y=0
152
+ *
153
+ * @default "top"
154
+ */
155
+ vertOrigin?: VertOrigin;
156
+ }
@@ -0,0 +1,59 @@
1
+ // Copyright (c) 2026 Roku, Inc.
2
+ // SPDX-License-Identifier: MIT
3
+
4
+ import type { ISimpleLabelProps } from "./simple-label.props";
5
+ import { Component } from "./types";
6
+ export type { HorizOrigin, VertOrigin, SimpleLabelFontUri, ISimpleLabelProps } from "./simple-label.props";
7
+
8
+ /**
9
+ * SimpleLabel component for displaying a single line of text.
10
+ *
11
+ * SimpleLabel is a lightweight complement to the Label node. It supports simplified
12
+ * font style specification and is more memory efficient than the Label node.
13
+ *
14
+ * Use SimpleLabel when you need basic text rendering without the advanced features
15
+ * of the Label node (such as multi-line text, wrapping, or truncation).
16
+ *
17
+ * **Origin-based Positioning:**
18
+ * Unlike most nodes where translation moves the top-left corner, SimpleLabel uses
19
+ * origin-based positioning. The `horizOrigin` and `vertOrigin` fields determine
20
+ * which part of the text is positioned at the translation point.
21
+ *
22
+ * @example
23
+ * ```tsx
24
+ * // Basic usage with system font
25
+ * <simpleLabel
26
+ * text="Hello World"
27
+ * fontUri="font:MediumBoldSystemFont"
28
+ * translation={[100, 100]}
29
+ * />
30
+ * ```
31
+ *
32
+ * @example
33
+ * ```tsx
34
+ * // Centered text at a specific position
35
+ * <simpleLabel
36
+ * text="Centered Text"
37
+ * fontUri="font:LargeSystemFont"
38
+ * horizOrigin="center"
39
+ * vertOrigin="center"
40
+ * translation={[960, 540]}
41
+ * />
42
+ * ```
43
+ *
44
+ * @example
45
+ * ```tsx
46
+ * // Custom font with specific size
47
+ * <simpleLabel
48
+ * text="Custom Font"
49
+ * fontUri="font:SystemFontFile"
50
+ * fontSize={24}
51
+ * color="#FF6B6BFF"
52
+ * />
53
+ * ```
54
+ *
55
+ * @see {@link https://developer.roku.com/dev/docs/simplelabel}
56
+ */
57
+ export const SimpleLabel: Component<ISimpleLabelProps> = props => {
58
+ return <simpleLabel {...props}></simpleLabel>;
59
+ };
@@ -0,0 +1,130 @@
1
+ // Copyright (c) 2026 Roku, Inc.
2
+ // SPDX-License-Identifier: MIT
3
+
4
+ import type { ComponentRef } from "@roku-sdk/interfaces";
5
+
6
+ import type { INodeProps } from "./node";
7
+ import type { EventHandler } from "./types";
8
+
9
+ /**
10
+ * Control values for the SoundEffect `control` field.
11
+ *
12
+ * @see {@link https://developer.roku.com/dev/docs/soundeffect}
13
+ */
14
+ export enum SoundEffectControl {
15
+ None = "none",
16
+ Play = "play",
17
+ Stop = "stop"
18
+ }
19
+
20
+ /**
21
+ * Playback state values reported by the SoundEffect `state` field.
22
+ *
23
+ * @see {@link https://developer.roku.com/dev/docs/soundeffect}
24
+ */
25
+ export enum SoundEffectState {
26
+ None = "none",
27
+ Playing = "playing",
28
+ Stopped = "stopped",
29
+ Finished = "finished",
30
+ TooManySounds = "toomanysounds",
31
+ NotReady = "notready"
32
+ }
33
+
34
+ /**
35
+ * Load status values reported by the SoundEffect `loadStatus` field.
36
+ *
37
+ * @see {@link https://developer.roku.com/dev/docs/soundeffect}
38
+ */
39
+ export enum SoundEffectLoadStatus {
40
+ None = "none",
41
+ Loading = "loading",
42
+ Ready = "ready",
43
+ Failed = "failed",
44
+ Flushed = "flushed"
45
+ }
46
+
47
+ /**
48
+ * Properties for the SoundEffect node.
49
+ *
50
+ * The SoundEffect node plays short audio sound effects triggered from UI events.
51
+ * Up to four simultaneous sounds can play at any time, in addition to audio from
52
+ * streaming content and TextToSpeech audio. All files must be WAV (PCM) format.
53
+ *
54
+ * @see {@link https://developer.roku.com/dev/docs/soundeffect}
55
+ */
56
+ export interface ISoundEffectProps extends INodeProps {
57
+ /**
58
+ * Specifies the URI of the WAV file. Sounds included as part of the application
59
+ * package can be referenced using the `pkg:/sounds` prefix. This may also specify
60
+ * the location of a WAV file on a remote server.
61
+ * @see {@link https://developer.roku.com/dev/docs/soundeffect | SoundEffect Fields}
62
+ */
63
+ uri?: string;
64
+ /**
65
+ * Controls the audio playback. Getting the value returns the most recent value set,
66
+ * or `"none"` if no value has been set.
67
+ *
68
+ * - `"none"` -- No effect.
69
+ * - `"play"` -- Start playing the audio. Restarts if already playing. If `loadStatus`
70
+ * is not `"ready"`, the sound will not play and `state` becomes `"notready"`.
71
+ * - `"stop"` -- Stop playing the audio if it is currently playing.
72
+ *
73
+ * @default "none"
74
+ * @see {@link https://developer.roku.com/dev/docs/soundeffect | SoundEffect Fields}
75
+ */
76
+ control?: SoundEffectControl;
77
+ /**
78
+ * The volume as a percentage of full volume (0--100). Use 50 for normal volume.
79
+ * @default 50
80
+ * @see {@link https://developer.roku.com/dev/docs/soundeffect | SoundEffect Fields}
81
+ */
82
+ volume?: number;
83
+ /**
84
+ * Fired when the playback state changes.
85
+ *
86
+ * Possible values: `"none"`, `"playing"`, `"stopped"`, `"finished"`,
87
+ * `"toomanysounds"`, `"notready"`.
88
+ */
89
+ onState?: EventHandler<SoundEffectState>;
90
+ /**
91
+ * Fired when the load status of the sound file changes.
92
+ *
93
+ * Possible values: `"none"`, `"loading"`, `"ready"`, `"failed"`, `"flushed"`.
94
+ */
95
+ onLoadStatus?: EventHandler<SoundEffectLoadStatus>;
96
+ }
97
+
98
+ /**
99
+ * Handle for imperative control of a {@link SoundEffect} component, obtained via the `ref` prop.
100
+ *
101
+ * Extends {@link ComponentRef} with convenience methods that map to
102
+ * {@link SoundEffectControl} values, so you can drive playback without manually
103
+ * setting the `control` prop.
104
+ *
105
+ * Unlike {@link import("./video").VideoRef | VideoRef} and
106
+ * {@link import("./audio").AudioRef | AudioRef}, SoundEffect only supports
107
+ * `play` and `stop` — there is no pause, resume, or skip.
108
+ *
109
+ * @example
110
+ * ```tsx
111
+ * import { SoundEffect, SoundEffectRef, Button } from "@roku-sdk/components";
112
+ *
113
+ * const ClickSound = () => {
114
+ * let sfxRef!: SoundEffectRef;
115
+ *
116
+ * return (
117
+ * <>
118
+ * <Button text="Play" onButtonSelected={() => sfxRef.play()} />
119
+ * <SoundEffect ref={sfxRef} uri="pkg:/sounds/click.wav" volume={50} />
120
+ * </>
121
+ * );
122
+ * };
123
+ * ```
124
+ *
125
+ * @see {@link https://developer.roku.com/dev/docs/soundeffect}
126
+ */
127
+ export interface SoundEffectRef extends ComponentRef<ISoundEffectProps> {
128
+ play: () => void;
129
+ stop: () => void;
130
+ }
@@ -0,0 +1,65 @@
1
+ // Copyright (c) 2026 Roku, Inc.
2
+ // SPDX-License-Identifier: MIT
3
+
4
+ import { registerImperativeMethods, setPropMethod } from "@roku-sdk/solid";
5
+
6
+ import type { ISoundEffectProps } from "./sound-effect.props";
7
+ export { SoundEffectControl, SoundEffectState, SoundEffectLoadStatus } from "./sound-effect.props";
8
+
9
+ export type { ISoundEffectProps, SoundEffectRef } from "./sound-effect.props";
10
+
11
+ import { Component } from "./types";
12
+
13
+ registerImperativeMethods("soundEffect", {
14
+ play: setPropMethod("control", "play"),
15
+ stop: setPropMethod("control", "stop")
16
+ });
17
+
18
+ /**
19
+ * SoundEffect plays short audio sound effects that can be triggered from UI events.
20
+ * Files can be installed locally as part of the package or dynamically downloaded from
21
+ * the network. All files must be WAV (PCM) format. Up to four simultaneous sounds can
22
+ * play at any time.
23
+ *
24
+ * For local files, the convention is to include WAV files in a directory named `sounds`.
25
+ * For downloaded files, a least-recently-used (LRU) mechanism keeps the most recently
26
+ * played sounds in temporary storage on the device.
27
+ *
28
+ * Playback can be controlled declaratively via the `control` prop or imperatively
29
+ * via a {@link SoundEffectRef} obtained through the `ref` prop.
30
+ *
31
+ * @example
32
+ * ```tsx
33
+ * // Declarative control via the control prop
34
+ * <soundEffect
35
+ * uri="pkg:/sounds/click.wav"
36
+ * control={SoundEffectControl.Play}
37
+ * volume={50}
38
+ * onState={(state) => console.log("SoundEffect state:", state)}
39
+ * />
40
+ * ```
41
+ *
42
+ * @example
43
+ * ```tsx
44
+ * // Imperative control via ref
45
+ * let sfxRef!: SoundEffectRef;
46
+ * <soundEffect ref={sfxRef} uri="pkg:/sounds/click.wav" volume={50} />
47
+ * // Then trigger playback: sfxRef.play()
48
+ * ```
49
+ *
50
+ * @example
51
+ * ```tsx
52
+ * // Network-hosted sound with load status monitoring
53
+ * <soundEffect
54
+ * uri="https://example.com/sounds/alert.wav"
55
+ * onLoadStatus={(status) => {
56
+ * if (status === SoundEffectLoadStatus.Ready) console.log("Sound ready to play");
57
+ * }}
58
+ * />
59
+ * ```
60
+ *
61
+ * @see {@link https://developer.roku.com/dev/docs/soundeffect}
62
+ */
63
+ export const SoundEffect: Component<ISoundEffectProps> = props => {
64
+ return <soundEffect {...props} />;
65
+ };