@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,87 @@
1
+ // Copyright (c) 2026 Roku, Inc.
2
+ // SPDX-License-Identifier: MIT
3
+
4
+ import type { ITimeGridProps } from "./time-grid.props";
5
+ import { Component } from "./types";
6
+ export type {
7
+ TimeGridItemPosition,
8
+ TimeGridItemEventHandler,
9
+ ITimeGridGeneralProps,
10
+ ITimeGridChannelProps,
11
+ ITimeGridChannelInfoProps,
12
+ ITimeGridProgramFocusedDetails,
13
+ ITimeGridProgramGridProps,
14
+ ITimeGridPastTimeScreenProps,
15
+ ITimeGridTimeBarProps,
16
+ ITimeGridNowBarProps,
17
+ ITimeGridNowNextModeProps,
18
+ ITimeGridProps
19
+ } from "./time-grid.props";
20
+
21
+ // ─────────────────────────────────────────────────────────────────────────────
22
+ // TimeGrid Types
23
+ // ─────────────────────────────────────────────────────────────────────────────
24
+
25
+ // ─────────────────────────────────────────────────────────────────────────────
26
+ // TimeGrid Sub-Interface: General Settings
27
+ // ─────────────────────────────────────────────────────────────────────────────
28
+
29
+ // ─────────────────────────────────────────────────────────────────────────────
30
+ // TimeGrid Sub-Interface: Channel Navigation / Focus / Selection
31
+ // ─────────────────────────────────────────────────────────────────────────────
32
+
33
+ // ─────────────────────────────────────────────────────────────────────────────
34
+ // TimeGrid Sub-Interface: Channel Information Column
35
+ // ─────────────────────────────────────────────────────────────────────────────
36
+
37
+ // ─────────────────────────────────────────────────────────────────────────────
38
+ // TimeGrid Sub-Interface: Program Grid
39
+ // ─────────────────────────────────────────────────────────────────────────────
40
+
41
+ // ─────────────────────────────────────────────────────────────────────────────
42
+ // TimeGrid Sub-Interface: Past Time Screen
43
+ // ─────────────────────────────────────────────────────────────────────────────
44
+
45
+ // ─────────────────────────────────────────────────────────────────────────────
46
+ // TimeGrid Sub-Interface: Time Bar
47
+ // ─────────────────────────────────────────────────────────────────────────────
48
+
49
+ // ─────────────────────────────────────────────────────────────────────────────
50
+ // TimeGrid Sub-Interface: Now Bar
51
+ // ─────────────────────────────────────────────────────────────────────────────
52
+
53
+ // ─────────────────────────────────────────────────────────────────────────────
54
+ // TimeGrid Sub-Interface: Now/Next Mode
55
+ // ─────────────────────────────────────────────────────────────────────────────
56
+
57
+ // ─────────────────────────────────────────────────────────────────────────────
58
+ // TimeGrid Composed Properties
59
+ // ─────────────────────────────────────────────────────────────────────────────
60
+
61
+ /**
62
+ * TimeGrid is an EPG (Electronic Program Guide) component that displays a
63
+ * scrollable, time-based grid of TV channels and their programs.
64
+ *
65
+ * Each row represents a channel with a customizable info column on the left.
66
+ * Programs are laid out horizontally according to their `playStart` and
67
+ * `playDuration` content metadata. A time bar and optional "now" indicator
68
+ * provide temporal context.
69
+ *
70
+ * @see {@link https://developer.roku.com/dev/docs/timegrid}
71
+ *
72
+ * @example
73
+ * ```tsx
74
+ * <timeGrid
75
+ * numRows={7}
76
+ * duration={7200}
77
+ * contentStartTime={startTime}
78
+ * leftEdgeTargetTime={now}
79
+ * channelInfoComponentName={channelItem}
80
+ * content={epgContent}
81
+ * onProgramSelected={(index) => handleSelection(index)}
82
+ * />
83
+ * ```
84
+ */
85
+ export const TimeGrid: Component<ITimeGridProps> = props => {
86
+ return <timeGrid {...props}></timeGrid>;
87
+ };
@@ -0,0 +1,115 @@
1
+ // Copyright (c) 2026 Roku, Inc.
2
+ // SPDX-License-Identifier: MIT
3
+
4
+ import type { DomNode } from "@roku-sdk/interfaces";
5
+
6
+ import type { AnimationControl, AnimationState, EaseFunction } from "./animation.props";
7
+ import type { INodeProps } from "./node";
8
+ import type { Vector2D } from "./types";
9
+
10
+ /**
11
+ * Properties for the Tween node — the unified declarative animation primitive.
12
+ *
13
+ * A `<tween>` animates a single field on a target node. On Roku it is a native node, which
14
+ * supersedes the earlier BrightScript/XML tween components and takes the interpreter out of the
15
+ * animation hot path. Application source writes `<tween>` and gets render-thread animation without
16
+ * branching on where it runs.
17
+ *
18
+ * The portable subset of the fields below — the properties every renderer honours, and the ones
19
+ * portable code may rely on — is frozen as {@link ITweenCoreProps} in `core-props.ts`. This
20
+ * interface is the full SceneGraph surface and is a superset of that base.
21
+ *
22
+ * @example
23
+ * // Slide a node to x=480 over the default duration
24
+ * <tween targetNode={ref} field="translation" targetVector={[480, 0]} />
25
+ */
26
+ export interface ITweenProps extends INodeProps {
27
+ /**
28
+ * The node whose field is animated. If you render `<tween>` directly, clear `targetNode`
29
+ * before removing it: a shim removed while idle or paused otherwise leaves its Animation in the
30
+ * parent. The `Tween` wrapper does this for you.
31
+ */
32
+ targetNode?: DomNode;
33
+
34
+ /**
35
+ * Field on {@link targetNode} to animate.
36
+ * @default "translation"
37
+ */
38
+ field?: string;
39
+
40
+ /**
41
+ * Float target. Writing it starts the animation. A scalar written against a vector2d field
42
+ * auto-expands to `[v, v]` on `axis="all"`; documented sugar for a uniform scale, not the
43
+ * canonical form. There is no separate Y target, so use {@link targetVector} for an
44
+ * `[x, y]` move; a vector target on a vector field is the plain way to say "all".
45
+ * @see [Tween value-shape contract](../../../../documentation/core-concepts/tween.md)
46
+ */
47
+ targetValue?: number;
48
+
49
+ /**
50
+ * Vector2d target `[x, y]`. Writing it starts the animation.
51
+ *
52
+ * @see [Tween value-shape contract](../../../../documentation/core-concepts/tween.md)
53
+ */
54
+ targetVector?: [number, number];
55
+
56
+ /**
57
+ * Duration in seconds. `0` is an instant snap with no animation artifacts.
58
+ * @default 0.333
59
+ */
60
+ duration?: number;
61
+
62
+ /**
63
+ * Named easing function.
64
+ * @default "linear"
65
+ */
66
+ easeFunction?: EaseFunction;
67
+
68
+ /**
69
+ * For vector fields, which axis to animate. `"x"` and `"y"` animate one component and hold
70
+ * the other at {@link preserveOther} to avoid stale mid-flight reads; `"all"` animates the
71
+ * whole vector.
72
+ *
73
+ * @default "all"
74
+ * @see [Tween value-shape contract](../../../../documentation/core-concepts/tween.md)
75
+ */
76
+ axis?: "x" | "y" | "all";
77
+
78
+ /** Value held on the non-animated axis for single-axis vector animation. */
79
+ preserveOther?: number;
80
+
81
+ /**
82
+ * Candidate snap positions for velocity-preserving settle. Empty means no settle.
83
+ * Float fields and single-axis vector motion take scalar candidates; whole-vector motion
84
+ * takes `[x, y]` pairs. Wrong-shaped entries are skipped and logged, and reported indices
85
+ * refer to the original list. A list with no usable candidates does not settle.
86
+ * @see [Tween value-shape contract](../../../../documentation/core-concepts/tween.md)
87
+ */
88
+ proposedStops?: number[] | [number, number][];
89
+
90
+ /** Optional explicit playback control (`start`/`stop`/`pause`/`resume`/`finish`). */
91
+ control?: AnimationControl;
92
+
93
+ /** Output: `[second, millisecond]` render-thread timestamp at animation start. */
94
+ onAnimationStart?: (t: [second: number, millisecond: number]) => void;
95
+
96
+ /**
97
+ * Output: `[index, position, [second, millisecond]]` after a settle re-arm — which
98
+ * `proposedStops` candidate was chosen, the coordinate it settles to, and the render-thread
99
+ * timestamp the settle is expected to finish at. On a vector field `position` is a scalar:
100
+ * the owned coordinate under `"x"`/`"y"`, and under `"all"` the coordinate of the chosen
101
+ * point that travels further. Read the full point from `proposedStops[index]`.
102
+ *
103
+ * Note this is NOT the plain `<animation>` node's `[second, millisecond]` stop timestamp.
104
+ * A tween's stop event is only interesting for what it settled on, so the chosen index and
105
+ * position lead and the timestamp is nested last.
106
+ */
107
+ onAnimationStop?: (t: [index: number, position: number, stopTime: [second: number, millisecond: number]]) => void;
108
+
109
+ /**
110
+ * Output: `[state, value]` on each animation state transition, where `value` is the target
111
+ * field's current value: a `number` for a float field, a `Vector2D` (`[x, y]`) for a vector2d field such as
112
+ * the default `translation`. Delivered as one array, like the other outputs.
113
+ */
114
+ onAnimationState?: (t: [state: AnimationState, value: number | Vector2D]) => void;
115
+ }
@@ -0,0 +1,150 @@
1
+ // Copyright (c) 2026 Roku, Inc.
2
+ // SPDX-License-Identifier: MIT
3
+
4
+ import type { Component, JSX } from "@roku-sdk/solid";
5
+ import { children, mergeProps, splitProps } from "@roku-sdk/solid"; // NOTE: update this if we switch to different framework
6
+
7
+ export type ResObject<T> = { hd: T; fhd: T };
8
+ export type ResType<T> = T | ResObject<T>;
9
+ export type IsResObjType = <T>(value: ResType<T> | undefined) => value is ResObject<T>;
10
+ /**
11
+ * URI type for referencing resources in Roku SceneGraph.
12
+ * Can be a simple string or resolution-specific object with separate URIs for HD and FHD.
13
+ *
14
+ * Supported URI schemes:
15
+ * - `pkg:/`: Package resources (files within the application package)
16
+ * - `http://` or `https://`: Remote resources loaded from the internet
17
+ * - `theme:`: Theme-specific resources
18
+ *
19
+ * URIs can also be imported from TypeScript using the image import plugin, which automatically
20
+ * generates resolution-specific URIs and copies assets to the build output.
21
+ *
22
+ * @example
23
+ * // Simple string URI
24
+ * uri="pkg:/images/icon.png"
25
+ *
26
+ * @example
27
+ * // Resolution-specific URIs
28
+ * uri={{ hd: "pkg:/images/icon-hd.png", fhd: "pkg:/images/icon-fhd.png" }}
29
+ *
30
+ * @example
31
+ * // TypeScript import (generates resolution-specific URIs automatically)
32
+ * import { uri as logo } from "./images/roku-logo-*.png";
33
+ * <Poster uri={logo} />
34
+ */
35
+ export type Uri = ResType<string>;
36
+
37
+ export type Vector2D = [number, number];
38
+ export type Rect2D = [number, number, number, number];
39
+ export type HorizAlign = "left" | "center" | "right";
40
+ export type VertAlign = "top" | "center" | "bottom";
41
+ export type LayoutGroupHorizAlign = HorizAlign | "custom";
42
+ export type LayoutGroupVertAlign = VertAlign | "custom";
43
+ export type LayoutDirection = "vert" | "horiz";
44
+ export type VideoMode = "hd" | "fhd";
45
+
46
+ /**
47
+ * System font names available in RokuOS.
48
+ *
49
+ * System fonts are built-in fonts provided by the Roku platform that automatically
50
+ * adapt to the user's language and accessibility settings. They are referenced using
51
+ * the `font:` URI scheme and are case-sensitive.
52
+ *
53
+ * **Why use system fonts?**
54
+ * - Consistent appearance across all Roku devices
55
+ * - Automatic localization support for international characters
56
+ * - Respect user accessibility preferences (e.g., larger text settings)
57
+ * - No need to bundle font files in your application package
58
+ *
59
+ * @example
60
+ * // Using with Label component
61
+ * <Label text="Hello World" font={SystemFont.Medium} />
62
+ *
63
+ * @example
64
+ * // Using with custom font string for specific size
65
+ * <Label text="Custom" font="font:MediumSystemFont" />
66
+ */
67
+ export enum SystemFont {
68
+ // ─────────────────────────────────────────────────────────────────────────
69
+ // Regular fonts (standard weight, size-based)
70
+ // ─────────────────────────────────────────────────────────────────────────
71
+ Largest = "font:LargestSystemFont",
72
+ UltraLarge = "font:UltraLargeSystemFont",
73
+ ExtraLarge = "font:ExtraLargeSystemFont",
74
+ Large = "font:LargeSystemFont",
75
+ Medium = "font:MediumSystemFont",
76
+ Small = "font:SmallSystemFont",
77
+ Smaller = "font:SmallerSystemFont",
78
+ Smallest = "font:SmallestSystemFont",
79
+ Tiny = "font:TinySystemFont",
80
+
81
+ // ─────────────────────────────────────────────────────────────────────────
82
+ // Bold fonts (bold weight, size-based)
83
+ // ─────────────────────────────────────────────────────────────────────────
84
+ UltraLargeBold = "font:UltraLargeBoldSystemFont",
85
+ ExtraLargeBold = "font:ExtraLargeBoldSystemFont",
86
+ LargeBold = "font:LargeBoldSystemFont",
87
+ MediumBold = "font:MediumBoldSystemFont",
88
+ SmallBold = "font:SmallBoldSystemFont",
89
+ SmallerBold = "font:SmallerBoldSystemFont",
90
+ SmallestBold = "font:SmallestBoldSystemFont",
91
+ TinyBold = "font:TinyBoldSystemFont",
92
+ /** Use for badge/pill UI elements (e.g., "NEW", "HD") */
93
+ Badge = "font:BadgeSystemFont",
94
+
95
+ // ─────────────────────────────────────────────────────────────────────────
96
+ // Semantic fonts for specific UI elements
97
+ // ─────────────────────────────────────────────────────────────────────────
98
+ /** Default font for label components */
99
+ DefaultLabel = "font:DefaultLabelFont",
100
+ /** Use for header/title text in sections */
101
+ Header = "font:HeaderFont",
102
+ /** Use for EPG (Electronic Program Guide) title text */
103
+ EPGInfoTitle = "font:EPGInfoTitleFont",
104
+ /** Use for overhang/top navigation titles */
105
+ OverhangTitle = "font:OverhangTitleFont",
106
+ /** Use for poster labels in settings screens */
107
+ SettingsPosterLabel = "font:SettingsPosterLabelFont",
108
+
109
+ // ─────────────────────────────────────────────────────────────────────────
110
+ // OSD (On-Screen Display) fonts
111
+ // ─────────────────────────────────────────────────────────────────────────
112
+ /** Use for on-screen display buttons */
113
+ OSDButton = "font:OSDButtonFont",
114
+ /** Use for focused on-screen display buttons */
115
+ OSDFocusedButton = "font:OSDFocusedButtonFont",
116
+
117
+ // ─────────────────────────────────────────────────────────────────────────
118
+ // Specialized/system-specific fonts
119
+ // ─────────────────────────────────────────────────────────────────────────
120
+ /** Use for link panel player number display */
121
+ LinkPanelPlayerNumber = "font:LinkPanelPlayerNumberFont",
122
+ /** Use for TV input status indicators */
123
+ TvInputStatus = "font:TvInputStatusFont",
124
+ /** Use for relink screen headers */
125
+ RelinkHeader = "font:RelinkHeaderFont",
126
+
127
+ // ─────────────────────────────────────────────────────────────────────────
128
+ // Caption and accessibility fonts
129
+ // ─────────────────────────────────────────────────────────────────────────
130
+ /** Use for video captions/subtitles */
131
+ Caption = "font:CaptionFont",
132
+ /** Use for closed captioning (accessibility) */
133
+ ClosedCaption = "font:ClosedCaptionFont",
134
+
135
+ // ─────────────────────────────────────────────────────────────────────────
136
+ // Theme font
137
+ // ─────────────────────────────────────────────────────────────────────────
138
+ /** Theme-defined font that respects channel theming settings */
139
+ Theme = "font:ThemeFont"
140
+ }
141
+
142
+ /**
143
+ * Font value type that accepts system fonts or custom font strings.
144
+ * Use this for properties that accept a font specification.
145
+ */
146
+ export type FontValue = SystemFont | `font:${string}` | JSX.Element;
147
+
148
+ export { children, Component, JSX, mergeProps, splitProps };
149
+
150
+ export type EventHandler<T> = (event: T) => void;