@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,428 @@
1
+ // Copyright (c) 2026 Roku, Inc.
2
+ // SPDX-License-Identifier: MIT
3
+
4
+ import { Modal, modalPropKeys } from "../modal-dialog";
5
+ import { retainAsset } from "../retain-asset";
6
+ import StandardDialogExtXML from "../xml-components/modal/StandardDialogExt.xml";
7
+ import type {
8
+ IStandardDialogProps,
9
+ IStandardDialogRSGPaletteNodeProps,
10
+ IStdDlgActionCardItemProps,
11
+ IStdDlgBulletTextItemProps,
12
+ IStdDlgButtonAreaProps,
13
+ IStdDlgButtonProps,
14
+ IStdDlgContentAreaProps,
15
+ IStdDlgCustomItemProps,
16
+ IStdDlgDeterminateProgressItemProps,
17
+ IStdDlgGraphicItemProps,
18
+ IStdDlgItemGroupProps,
19
+ IStdDlgKeyboardItemProps,
20
+ IStdDlgMultiStyleTextItemProps,
21
+ IStdDlgProgressItemProps,
22
+ IStdDlgSideCardAreaProps,
23
+ IStdDlgTextItemProps,
24
+ IStdDlgTitleAreaProps
25
+ } from "./standard-dialog.props";
26
+ import { Component, splitProps } from "./types";
27
+ export { StdDlgKeyboardLayoutType } from "./standard-dialog.props";
28
+
29
+ export type {
30
+ IStandardDialogRSGPaletteNodeProps,
31
+ IStandardDialogProps,
32
+ IStdDlgAreaBaseProps,
33
+ IStdDlgTitleAreaProps,
34
+ IStdDlgContentAreaProps,
35
+ IStdDlgButtonAreaProps,
36
+ IStdDlgSideCardAreaProps,
37
+ IStdDlgButtonProps,
38
+ IStdDlgItemBaseProps,
39
+ IStdDlgItemGroupProps,
40
+ IStdDlgActionIconType,
41
+ IStdDlgActionCardItemProps,
42
+ IStdDialogBulletType,
43
+ IStdDlgBulletTextItemProps,
44
+ IStdDlgDeterminateProgressItemProps,
45
+ IStdDlgGraphicAlign,
46
+ IStdDlgGraphicItemProps,
47
+ IStdDlgKeyboardItemProps,
48
+ IStdDlgDrawingStyle,
49
+ IStdDlgMultiStyleTextItemProps,
50
+ IStdDlgProgressItemProps,
51
+ INamedTextStyles,
52
+ IStdDlgTextItemProps,
53
+ IStdDlgCustomItemProps
54
+ } from "./standard-dialog.props";
55
+
56
+ // ──────────────────────────────────────────────────────────────────────────────
57
+ // RSGPalette
58
+ // ──────────────────────────────────────────────────────────────────────────────
59
+
60
+ /**
61
+ * Sets the color palette used by a {@link StandardDialog} and its child elements.
62
+ *
63
+ * The RSGPalette node defines 10 color values that control the appearance of dialog backgrounds,
64
+ * text, buttons, focus indicators, keyboards, and other elements. By default, dialogs inherit
65
+ * their palette from ancestor nodes in the scene graph (typically from the Scene node).
66
+ *
67
+ * @example
68
+ * ```tsx
69
+ * <StandardDialog>
70
+ * <rsgPalette colors={{
71
+ * dialogBackgroundColor: "0x1E1E1EFF",
72
+ * dialogTextColor: "0xFFFFFFFF",
73
+ * dialogFocusColor: "0x0066FFFF",
74
+ * }} />
75
+ * <stdDlgTitleArea primaryTitle="Settings" />
76
+ * <stdDlgContentArea>
77
+ * <stdDlgTextItem text="Choose an option below." />
78
+ * </stdDlgContentArea>
79
+ * </StandardDialog>
80
+ * ```
81
+ *
82
+ * @see {@link https://developer.roku.com/dev/docs/standard-dialog | StandardDialog palette field}
83
+ */
84
+ export const RsgPalette: Component<IStandardDialogRSGPaletteNodeProps> = props => {
85
+ return <rsgPalette {...props}></rsgPalette>;
86
+ };
87
+
88
+ /**
89
+ * @deprecated Renamed to {@link RsgPalette}. Use `RsgPalette` instead — `RSGPalette` will be removed in a future release.
90
+ */
91
+ export const RSGPalette = RsgPalette;
92
+
93
+ // ──────────────────────────────────────────────────────────────────────────────
94
+ // StandardDialog
95
+ // ──────────────────────────────────────────────────────────────────────────────
96
+
97
+ /**
98
+ * Base dialog node for the Roku standard dialog framework.
99
+ *
100
+ * `StandardDialog` provides a structured dialog layout with optional title, content, button,
101
+ * and side-card areas. Use the StdDlg* area and item components as children to compose the
102
+ * dialog's UI.
103
+ *
104
+ * @example
105
+ * ```tsx
106
+ * const [showDialog, setShowDialog] = createSignal(false);
107
+ *
108
+ * {showDialog() && (
109
+ * <StandardDialog
110
+ * onButtonSelected={(index) => {
111
+ * console.log(`Button ${index} selected`);
112
+ * setShowDialog(false);
113
+ * }}
114
+ * onWasClosed={() => setShowDialog(false)}
115
+ * >
116
+ * <stdDlgTitleArea primaryTitle="Confirm Action" />
117
+ * <stdDlgContentArea>
118
+ * <stdDlgTextItem text="Are you sure you want to continue?" />
119
+ * </stdDlgContentArea>
120
+ * <stdDlgButtonArea>
121
+ * <stdDlgButton text="OK" />
122
+ * <stdDlgButton text="Cancel" />
123
+ * </stdDlgButtonArea>
124
+ * </StandardDialog>
125
+ * )}
126
+ * ```
127
+ *
128
+ * @see {@link https://developer.roku.com/dev/docs/standard-dialog}
129
+ */
130
+ export const StandardDialog: Component<IStandardDialogProps> = props => {
131
+ retainAsset(StandardDialogExtXML);
132
+ const [local, rest] = splitProps(props, modalPropKeys);
133
+ return <Modal {...local} dialog={<standardDialogExt {...rest} />} />;
134
+ };
135
+
136
+ // ──────────────────────────────────────────────────────────────────────────────
137
+ // Area nodes
138
+ // ──────────────────────────────────────────────────────────────────────────────
139
+
140
+ /**
141
+ * Title area component displayed at the top of a {@link StandardDialog}.
142
+ *
143
+ * A dialog may contain a single optional title area. Use it to display a title string
144
+ * with optional primary (left) and secondary (right) icons.
145
+ *
146
+ * @example
147
+ * ```tsx
148
+ * <stdDlgTitleArea
149
+ * primaryTitle="Settings"
150
+ * primaryIcon="pkg:/images/settings-icon.png"
151
+ * />
152
+ * ```
153
+ *
154
+ * @see {@link https://developer.roku.com/dev/docs/std-dlg-title-area}
155
+ */
156
+ export const StdDlgTitleArea: Component<IStdDlgTitleAreaProps> = props => {
157
+ return <stdDlgTitleArea {...props}></stdDlgTitleArea>;
158
+ };
159
+
160
+ /**
161
+ * Content area containing the main body of a {@link StandardDialog}.
162
+ *
163
+ * Positioned between the title area and button area. Add StdDlg*Item child nodes
164
+ * (e.g., {@link StdDlgTextItem}, {@link StdDlgGraphicItem}) which are arranged vertically.
165
+ *
166
+ * @example
167
+ * ```tsx
168
+ * <stdDlgContentArea>
169
+ * <stdDlgTextItem text="Welcome to the app." />
170
+ * <stdDlgTextItem text="Please review the following:" namedTextStyle="secondary" />
171
+ * <stdDlgBulletTextItem bulletText={["Item A", "Item B", "Item C"]} />
172
+ * </stdDlgContentArea>
173
+ * ```
174
+ *
175
+ * @see {@link https://developer.roku.com/dev/docs/std-dlg-content-area}
176
+ */
177
+ export const StdDlgContentArea: Component<IStdDlgContentAreaProps> = props => {
178
+ return <stdDlgContentArea {...props}></stdDlgContentArea>;
179
+ };
180
+
181
+ /**
182
+ * Button area positioned at the bottom of a {@link StandardDialog}.
183
+ *
184
+ * Contains zero or more {@link StdDlgButton} children arranged vertically. A dialog
185
+ * may have a single optional button area.
186
+ *
187
+ * @example
188
+ * ```tsx
189
+ * <stdDlgButtonArea>
190
+ * <stdDlgButton text="Accept" />
191
+ * <stdDlgButton text="Decline" />
192
+ * <stdDlgButton text="More Info" disabled={true} />
193
+ * </stdDlgButtonArea>
194
+ * ```
195
+ *
196
+ * @see {@link https://developer.roku.com/dev/docs/std-dlg-button-area}
197
+ */
198
+ export const StdDlgButtonArea: Component<IStdDlgButtonAreaProps> = props => {
199
+ return <stdDlgButtonArea {...props}></stdDlgButtonArea>;
200
+ };
201
+
202
+ /**
203
+ * Freeform side card area on the left or right side of a {@link StandardDialog}.
204
+ *
205
+ * Use for decorative images or annotative text. The side card area never gains key focus.
206
+ * A dialog may contain only a single side card area.
207
+ *
208
+ * @example
209
+ * ```tsx
210
+ * <stdDlgSideCardArea width={300} horizAlign="right" showDivider={true}>
211
+ * <poster uri="pkg:/images/promo.jpg" width={280} height={400} />
212
+ * </stdDlgSideCardArea>
213
+ * ```
214
+ *
215
+ * @see {@link https://developer.roku.com/dev/docs/std-dlg-side-card-area}
216
+ */
217
+ export const StdDlgSideCardArea: Component<IStdDlgSideCardAreaProps> = props => {
218
+ return <stdDlgSideCardArea {...props}></stdDlgSideCardArea>;
219
+ };
220
+
221
+ // ──────────────────────────────────────────────────────────────────────────────
222
+ // Button & item structural nodes
223
+ // ──────────────────────────────────────────────────────────────────────────────
224
+
225
+ /**
226
+ * A button in a {@link StdDlgButtonArea}. Should only be a direct child of StdDlgButtonArea.
227
+ *
228
+ * @example
229
+ * ```tsx
230
+ * <stdDlgButtonArea>
231
+ * <stdDlgButton text="OK" />
232
+ * <stdDlgButton text="Cancel" />
233
+ * </stdDlgButtonArea>
234
+ * ```
235
+ *
236
+ * @see {@link https://developer.roku.com/dev/docs/std-dlg-button}
237
+ */
238
+ export const StdDlgButton: Component<IStdDlgButtonProps> = props => {
239
+ return <stdDlgButton {...props}></stdDlgButton>;
240
+ };
241
+
242
+ /**
243
+ * Groups StdDlg item nodes with reduced spacing and optional radio-button exclusivity.
244
+ *
245
+ * Attach `onSelected` to each {@link StdDlgActionCardItem} to handle selection changes.
246
+ *
247
+ * @example
248
+ * ```tsx
249
+ * const [selectedOption, setSelectedOption] = createSignal(0);
250
+ *
251
+ * <stdDlgItemGroup selectedIndex={selectedOption()}>
252
+ * <stdDlgActionCardItem iconType="radiobutton" onSelected={() => setSelectedOption(0)}>
253
+ * <stdDlgTextItem text="Option A" />
254
+ * </stdDlgActionCardItem>
255
+ * <stdDlgActionCardItem iconType="radiobutton" onSelected={() => setSelectedOption(1)}>
256
+ * <stdDlgTextItem text="Option B" />
257
+ * </stdDlgActionCardItem>
258
+ * <stdDlgActionCardItem iconType="radiobutton" onSelected={() => setSelectedOption(2)}>
259
+ * <stdDlgTextItem text="Option C" />
260
+ * </stdDlgActionCardItem>
261
+ * </stdDlgItemGroup>
262
+ * ```
263
+ *
264
+ * @see {@link https://developer.roku.com/dev/docs/std-dlg-item-group}
265
+ */
266
+ export const StdDlgItemGroup: Component<IStdDlgItemGroupProps> = props => {
267
+ return <stdDlgItemGroup {...props}></stdDlgItemGroup>;
268
+ };
269
+
270
+ // ──────────────────────────────────────────────────────────────────────────────
271
+ // Content item nodes
272
+ // ──────────────────────────────────────────────────────────────────────────────
273
+
274
+ /**
275
+ * Focusable action card that highlights child items with optional icons.
276
+ *
277
+ * @example
278
+ * ```tsx
279
+ * <stdDlgActionCardItem iconType="checkbox" iconStatus={isChecked()}>
280
+ * <stdDlgTextItem text="Enable notifications" />
281
+ * </stdDlgActionCardItem>
282
+ * ```
283
+ *
284
+ * @see {@link https://developer.roku.com/dev/docs/std-dlg-action-card-item}
285
+ */
286
+ export const StdDlgActionCardItem: Component<IStdDlgActionCardItemProps> = props => {
287
+ return <stdDlgActionCardItem {...props}></stdDlgActionCardItem>;
288
+ };
289
+
290
+ /**
291
+ * Displays a bulleted list of text in a {@link StdDlgContentArea}.
292
+ *
293
+ * @example
294
+ * ```tsx
295
+ * <stdDlgBulletTextItem
296
+ * bulletType="numbered"
297
+ * bulletText={["Connect to Wi-Fi", "Sign in to your account", "Start streaming"]}
298
+ * />
299
+ * ```
300
+ *
301
+ * @see {@link https://developer.roku.com/dev/docs/std-dlg-bullet-text-item}
302
+ */
303
+ export const StdDlgBulletTextItem: Component<IStdDlgBulletTextItemProps> = props => {
304
+ return <stdDlgBulletTextItem {...props}></stdDlgBulletTextItem>;
305
+ };
306
+
307
+ /**
308
+ * Displays a determinate progress indicator for tasks with a known duration.
309
+ *
310
+ * @example
311
+ * ```tsx
312
+ * <stdDlgDeterminateProgressItem percent={65} text="Downloading update…" />
313
+ * ```
314
+ *
315
+ * @see {@link https://developer.roku.com/dev/docs/std-dlg-determinate-progress-item}
316
+ */
317
+ export const StdDlgDeterminateProgressItem: Component<IStdDlgDeterminateProgressItemProps> = props => {
318
+ return <stdDlgDeterminateProgressItem {...props}></stdDlgDeterminateProgressItem>;
319
+ };
320
+
321
+ /**
322
+ * Displays an image with optional text in a {@link StdDlgContentArea}.
323
+ *
324
+ * @example
325
+ * ```tsx
326
+ * <stdDlgGraphicItem
327
+ * graphicUri="pkg:/images/info-icon.png"
328
+ * graphicWidth={48}
329
+ * graphicHeight={48}
330
+ * graphicAlign="left"
331
+ * text="Your device is up to date."
332
+ * />
333
+ * ```
334
+ *
335
+ * @see {@link https://developer.roku.com/dev/docs/std-dlg-graphic-item}
336
+ */
337
+ export const StdDlgGraphicItem: Component<IStdDlgGraphicItemProps> = props => {
338
+ return <stdDlgGraphicItem {...props}></stdDlgGraphicItem>;
339
+ };
340
+
341
+ /**
342
+ * Displays a keyboard or PIN pad in a {@link StdDlgContentArea}.
343
+ *
344
+ * @example
345
+ * ```tsx
346
+ * <stdDlgKeyboardItem keyLayoutType={StdDlgKeyboardLayoutType.Keyboard} text="" />
347
+ * ```
348
+ *
349
+ * @see {@link https://developer.roku.com/dev/docs/std-dlg-keyboard-item}
350
+ */
351
+ export const StdDlgKeyboardItem: Component<IStdDlgKeyboardItemProps> = props => {
352
+ return <stdDlgKeyboardItem {...props}></stdDlgKeyboardItem>;
353
+ };
354
+
355
+ /**
356
+ * Displays text with multiple styles in a {@link StdDlgContentArea}.
357
+ *
358
+ * Define named drawing styles and reference them as markup tags in the text content.
359
+ *
360
+ * @example
361
+ * ```tsx
362
+ * <stdDlgMultiStyleTextItem
363
+ * text="Press <key>OK</key> to <action>confirm</action>."
364
+ * drawingStyles={{
365
+ * key: { fontUri: "font:MediumBoldSystemFont", color: "0xFFFF00FF" },
366
+ * action: { fontUri: "font:MediumSystemFont", color: "0x00FF00FF" }
367
+ * }}
368
+ * audioGuideText="Press OK to confirm."
369
+ * />
370
+ * ```
371
+ *
372
+ * @see {@link https://developer.roku.com/dev/docs/std-dlg-multi-style-text-item}
373
+ */
374
+ export const StdDlgMultiStyleTextItem: Component<IStdDlgMultiStyleTextItemProps> = props => {
375
+ return <stdDlgMultiStyleTextItem {...props}></stdDlgMultiStyleTextItem>;
376
+ };
377
+
378
+ /**
379
+ * Displays an indeterminate spinning progress indicator in a {@link StdDlgContentArea}.
380
+ *
381
+ * @example
382
+ * ```tsx
383
+ * <stdDlgProgressItem text="Loading, please wait…" />
384
+ * ```
385
+ *
386
+ * @see {@link https://developer.roku.com/dev/docs/std-dlg-progress-item}
387
+ */
388
+ export const StdDlgProgressItem: Component<IStdDlgProgressItemProps> = props => {
389
+ return <stdDlgProgressItem {...props}></stdDlgProgressItem>;
390
+ };
391
+
392
+ /**
393
+ * Displays a block of text in a {@link StdDlgContentArea}.
394
+ *
395
+ * @example
396
+ * ```tsx
397
+ * <stdDlgTextItem text="Your account has been updated." />
398
+ * <stdDlgTextItem text="Contact support if you have questions." namedTextStyle="secondary" />
399
+ * ```
400
+ *
401
+ * @see {@link https://developer.roku.com/dev/docs/std-dlg-text-item}
402
+ */
403
+ export const StdDlgTextItem: Component<IStdDlgTextItemProps> = props => {
404
+ return <stdDlgTextItem {...props}></stdDlgTextItem>;
405
+ };
406
+
407
+ /**
408
+ * Free-form custom item in a {@link StdDlgContentArea} for content requiring custom layout.
409
+ *
410
+ * @example
411
+ * ```tsx
412
+ * <stdDlgCustomItem fixedWidthField={600}>
413
+ * <rectangle width={600} height={200} color="0x333333FF" />
414
+ * </stdDlgCustomItem>
415
+ * ```
416
+ *
417
+ * @see {@link https://developer.roku.com/dev/docs/std-dlg-custom-item}
418
+ */
419
+ export const StdDlgCustomItem: Component<IStdDlgCustomItemProps> = props => {
420
+ return <stdDlgCustomItem {...props}></stdDlgCustomItem>;
421
+ };
422
+
423
+ // ──────────────────────────────────────────────────────────────────────────────
424
+ // Pre-built Dialog Nodes
425
+ // ──────────────────────────────────────────────────────────────────────────────
426
+ // StandardMessageDialog, StandardKeyboardDialog, StandardPinPadDialog, and
427
+ // StandardProgressDialog live in their own modules so unused dialogs and their XML
428
+ // assets tree-shake out of consuming apps. They are re-exported from the package barrel.
@@ -0,0 +1,84 @@
1
+ // Copyright (c) 2026 Roku, Inc.
2
+ // SPDX-License-Identifier: MIT
3
+
4
+ import type { IStandardDialogProps } from "./standard-dialog.props";
5
+ import type { EventHandler } from "./types";
6
+
7
+ /** Keyboard input domain type for {@link StandardKeyboardDialog}. */
8
+ export type IKeyboardDomain = "email" | "numeric" | "alphanumeric" | "generic" | "password";
9
+
10
+ /**
11
+ * Properties for the {@link StandardKeyboardDialog} component.
12
+ *
13
+ * Extends {@link IStandardDialogProps} with keyboard-specific fields for text entry.
14
+ *
15
+ * @see {@link https://developer.roku.com/dev/docs/standard-keyboard-dialog}
16
+ */
17
+ export interface IStandardKeyboardDialogProps extends IStandardDialogProps {
18
+ /**
19
+ * The title displayed at the top of the dialog.
20
+ * @default ""
21
+ */
22
+ title?: string;
23
+ /**
24
+ * One or more blocks of text describing the data to be entered.
25
+ * Each string in the array is displayed as a separate block of text.
26
+ * Minimize message length to avoid automatic scrollbar.
27
+ * @default []
28
+ */
29
+ message?: string[];
30
+ /**
31
+ * List of button labels to display in the button area at the bottom of the dialog.
32
+ * Minimize the number of buttons to ensure visibility without scrolling.
33
+ * @default []
34
+ */
35
+ buttons?: string[];
36
+ /**
37
+ * The type of text to be entered. Used by the keyboard to modify voice entry method
38
+ * and determine when a valid string has been entered.
39
+ * - `"email"`: letter-by-letter dictation for emails
40
+ * - `"numeric"`: letter-by-letter dictation for PIN codes, zip codes
41
+ * - `"alphanumeric"`: letter-by-letter dictation for addresses
42
+ * - `"generic"`: full word input for search queries (default)
43
+ * - `"password"`: letter-by-letter dictation for passwords
44
+ * @default "generic"
45
+ */
46
+ keyboardDomain?: IKeyboardDomain;
47
+ /**
48
+ * The default string displayed in the keyboard's text edit box.
49
+ * Updated with the currently entered string as the user types.
50
+ *
51
+ * @note Reactivity on this field has been intentionally removed. Binding a signal directly
52
+ * to `text` would cause an infinite loop: the user types → `onText` fires → signal updates →
53
+ * `text` prop changes → the keyboard resets the field → cursor jumps back. Use `onText` to
54
+ * track the live value and only set `text` as an initial/default value.
55
+ * @default ""
56
+ */
57
+ text?: string;
58
+ /**
59
+ * Fired whenever the text in the keyboard's text edit box changes (on each keystroke).
60
+ * The handler receives the full current string entered by the user.
61
+ *
62
+ * Use this to react to live input — for example to validate input, update a search
63
+ * suggestion list, or enable/disable action buttons based on what the user has typed so far.
64
+ *
65
+ * @example
66
+ * ```tsx
67
+ * const [inputText, setInputText] = createSignal("");
68
+ *
69
+ * <StandardKeyboardDialog
70
+ * title="Search"
71
+ * keyboardDomain="generic"
72
+ * text={inputText()}
73
+ * onText={(text) => {
74
+ * // Called on every keystroke with the full current text
75
+ * setInputText(text);
76
+ * console.log("User is typing:", text);
77
+ * }}
78
+ * buttons={["Search", "Cancel"]}
79
+ * onButtonSelected={(index) => console.log("Button:", index)}
80
+ * />
81
+ * ```
82
+ */
83
+ onText?: EventHandler<string>;
84
+ }
@@ -0,0 +1,58 @@
1
+ // Copyright (c) 2026 Roku, Inc.
2
+ // SPDX-License-Identifier: MIT
3
+
4
+ import { Modal, modalPropKeys } from "../modal-dialog";
5
+ import { retainAsset } from "../retain-asset";
6
+ import StandardKeyboardDialogExtXML from "../xml-components/modal/StandardKeyboardDialogExt.xml";
7
+ import type { IStandardKeyboardDialogProps } from "./standard-keyboard-dialog.props";
8
+ import { Component, splitProps } from "./types";
9
+ export type { IKeyboardDomain, IStandardKeyboardDialogProps } from "./standard-keyboard-dialog.props";
10
+
11
+ /**
12
+ * Displays a keyboard dialog for text and voice entry of alphanumeric characters and symbols.
13
+ *
14
+ * StandardKeyboardDialog is a pre-built dialog similar to the legacy KeyboardDialog node, but includes voice entry functionality through its internal DynamicKeyboard node.
15
+ *
16
+ * The {@link IStandardKeyboardDialogProps.keyboardDomain | keyboardDomain} property controls
17
+ * how voice input is processed:
18
+ * - `"generic"`: full word input for search queries
19
+ * - `"email"`: letter-by-letter for email addresses
20
+ * - `"password"`: letter-by-letter for passwords
21
+ * - `"numeric"`: letter-by-letter for PINs and zip codes
22
+ * - `"alphanumeric"`: letter-by-letter for street addresses
23
+ *
24
+ * @example
25
+ * ```tsx
26
+ * const [showKeyboard, setShowKeyboard] = createSignal(false);
27
+ * const [searchText, setSearchText] = createSignal("");
28
+ *
29
+ * {showKeyboard() && (
30
+ * <StandardKeyboardDialog
31
+ * title="Search"
32
+ * message={["Enter your search query:"]}
33
+ * keyboardDomain="generic"
34
+ * text={searchText()}
35
+ * buttons={["Search", "Cancel"]}
36
+ * // onText fires on every keystroke with the full current string
37
+ * onText={(text) => {
38
+ * setSearchText(text);
39
+ * console.log("Live input:", text);
40
+ * }}
41
+ * onButtonSelected={(index) => {
42
+ * if (index === 0) {
43
+ * console.log("Searching for:", searchText());
44
+ * }
45
+ * setShowKeyboard(false);
46
+ * }}
47
+ * onWasClosed={() => setShowKeyboard(false)}
48
+ * />
49
+ * )}
50
+ * ```
51
+ *
52
+ * @see {@link https://developer.roku.com/dev/docs/standard-keyboard-dialog}
53
+ */
54
+ export const StandardKeyboardDialog: Component<IStandardKeyboardDialogProps> = props => {
55
+ retainAsset(StandardKeyboardDialogExtXML);
56
+ const [local, rest] = splitProps(props, modalPropKeys);
57
+ return <Modal {...local} dialog={<standardKeyboardDialogExt {...rest} />} />;
58
+ };
@@ -0,0 +1,56 @@
1
+ // Copyright (c) 2026 Roku, Inc.
2
+ // SPDX-License-Identifier: MIT
3
+
4
+ import type { IStandardDialogProps } from "./standard-dialog.props";
5
+
6
+ /** Bullet list delimiter type for {@link StandardMessageDialog}. */
7
+ export type IStandardBulletType = "bullet" | "numbered" | "lettered";
8
+
9
+ /**
10
+ * Properties for the {@link StandardMessageDialog} component.
11
+ *
12
+ * Extends {@link IStandardDialogProps} with message-specific fields for displaying
13
+ * informational text blocks and bulleted lists.
14
+ *
15
+ * @see {@link https://developer.roku.com/dev/docs/standard-message-dialog}
16
+ */
17
+ export interface IStandardMessageDialogProps extends IStandardDialogProps {
18
+ /**
19
+ * The title displayed at the top of the dialog.
20
+ * @default ""
21
+ */
22
+ title?: string;
23
+ /**
24
+ * One or more blocks of informational text displayed at the top of the dialog's content area.
25
+ * Each string in the array is displayed as a separate block of text with standard spacing.
26
+ * To separate lines of text, add each line as an element in the array (do not use newline characters).
27
+ * @default []
28
+ */
29
+ message?: string[];
30
+ /**
31
+ * An array of strings displayed as a bulleted or numbered list in the content area,
32
+ * below the message and above the bottom message.
33
+ * @default []
34
+ */
35
+ bulletText?: string[];
36
+ /**
37
+ * Specifies the type of list item delimiter when {@link bulletText} is set.
38
+ * - `"bullet"`: bullet points (default)
39
+ * - `"numbered"`: numbered list (1, 2, 3...)
40
+ * - `"lettered"`: lettered list (a, b, c...)
41
+ * @default "bullet"
42
+ */
43
+ bulletType?: IStandardBulletType;
44
+ /**
45
+ * One or more blocks of informational text displayed at the bottom of the dialog's content area.
46
+ * Each string in the array is displayed as a separate block of text with standard spacing.
47
+ * @default []
48
+ */
49
+ bottomMessage?: string[];
50
+ /**
51
+ * List of button labels to display in the button area at the bottom of the dialog.
52
+ * Each string adds a new button. Minimize the number of buttons to ensure visibility.
53
+ * @default []
54
+ */
55
+ buttons?: string[];
56
+ }
@@ -0,0 +1,47 @@
1
+ // Copyright (c) 2026 Roku, Inc.
2
+ // SPDX-License-Identifier: MIT
3
+
4
+ import { Modal, modalPropKeys } from "../modal-dialog";
5
+ import { retainAsset } from "../retain-asset";
6
+ import StandardMessageDialogExtXML from "../xml-components/modal/StandardMessageDialogExt.xml";
7
+ import type { IStandardMessageDialogProps } from "./standard-message-dialog.props";
8
+ import { Component, splitProps } from "./types";
9
+ export type { IStandardBulletType, IStandardMessageDialogProps } from "./standard-message-dialog.props";
10
+
11
+ /**
12
+ * Displays a message dialog with optional title, text blocks, bulleted list, and buttons.
13
+ *
14
+ * StandardMessageDialog is a pre-built dialog similar to the legacy Dialog node. It provides a convenient way to display informational messages with:
15
+ * - One or more text blocks at the top ({@link IStandardMessageDialogProps.message | message})
16
+ * - An optional bulleted/numbered/lettered list ({@link IStandardMessageDialogProps.bulletText | bulletText})
17
+ * - One or more text blocks at the bottom ({@link IStandardMessageDialogProps.bottomMessage | bottomMessage})
18
+ * - A row of buttons ({@link IStandardMessageDialogProps.buttons | buttons})
19
+ *
20
+ * @example
21
+ * ```tsx
22
+ * const [showDialog, setShowDialog] = createSignal(false);
23
+ *
24
+ * {showDialog() && (
25
+ * <StandardMessageDialog
26
+ * title="Terms of Service"
27
+ * message={["Please review the following terms:"]}
28
+ * bulletText={["You must be 18 or older", "Content is for personal use only", "Subscription auto-renews monthly"]}
29
+ * bulletType="numbered"
30
+ * bottomMessage={["By continuing, you agree to these terms."]}
31
+ * buttons={["Accept", "Decline"]}
32
+ * onButtonSelected={(index) => {
33
+ * console.log(index === 0 ? "Accepted" : "Declined");
34
+ * setShowDialog(false);
35
+ * }}
36
+ * onWasClosed={() => setShowDialog(false)}
37
+ * />
38
+ * )}
39
+ * ```
40
+ *
41
+ * @see {@link https://developer.roku.com/dev/docs/standard-message-dialog}
42
+ */
43
+ export const StandardMessageDialog: Component<IStandardMessageDialogProps> = props => {
44
+ retainAsset(StandardMessageDialogExtXML);
45
+ const [local, rest] = splitProps(props, modalPropKeys);
46
+ return <Modal {...local} dialog={<standardMessageDialogExt {...rest} />} />;
47
+ };