@24i/bigscreen-sdk 1.1.0 → 2.1.1-alpha.2133

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 (256) hide show
  1. package/README.md +1 -1
  2. package/package.json +34 -53
  3. package/packages/adobe-heartbeat/src/AdobeHeartbeat.ts +9 -9
  4. package/packages/async-image/src/AsyncImage.tsx +10 -15
  5. package/packages/developer-tools/PlayerDebugWindow/README.md +1 -1
  6. package/packages/developer-tools/src/DeveloperToolsService/DeveloperToolsList.tsx +0 -11
  7. package/packages/developer-tools/src/PlayerDebugWindow/PlayerDebugWindow.tsx +5 -5
  8. package/packages/developer-tools/src/PlayerDebugWindow/constants.ts +0 -15
  9. package/packages/developer-tools/src/TechnicalInfo/TechnicalInfoDetail.tsx +1 -2
  10. package/packages/developer-tools/src/TechnicalInfo/TechnicalInfoProvider.ts +3 -34
  11. package/packages/developer-tools/src/TechnicalInfo/__mocks__/Device.ts +0 -4
  12. package/packages/developer-tools/src/TechnicalInfo/translations.ts +0 -4
  13. package/packages/device/src/getKeyDigit.ts +2 -2
  14. package/packages/device/src/resolver/resolver.ts +5 -18
  15. package/packages/digital-clock/src/DigitalClock.tsx +4 -15
  16. package/packages/driver-androidtv/src/DeviceAndroidTV.ts +9 -54
  17. package/packages/driver-androidtv/src/__mocks__/javaScriptBridge.ts +5 -29
  18. package/packages/driver-androidtv/src/keymap.ts +0 -18
  19. package/packages/driver-androidtv/src/types.ts +16 -102
  20. package/packages/driver-base/src/DeviceBase.ts +2 -61
  21. package/packages/driver-base/src/KeyMap/Key.ts +1 -8
  22. package/packages/driver-base/src/KeyMap/KeyMap.ts +0 -4
  23. package/packages/driver-base/src/KeyMap/interface.ts +0 -1
  24. package/packages/driver-base/src/KeyMap/overrideValues.ts +1 -2
  25. package/packages/driver-base/src/__mocks__/keyMap.ts +0 -1
  26. package/packages/driver-base/src/types/DeviceEvent.ts +0 -2
  27. package/packages/driver-base/src/types/KeycodeKeyMap.ts +0 -1
  28. package/packages/driver-browser/src/keymap.ts +0 -8
  29. package/packages/driver-entone/src/keymap.ts +0 -1
  30. package/packages/driver-tizen/src/TizenKeys.ts +0 -2
  31. package/packages/driver-vidaa/src/DeviceVidaa.ts +2 -3
  32. package/packages/driver-vidaa/src/__mocks__/vidaa.ts +1 -1
  33. package/packages/driver-vidaa/src/keymap.ts +0 -2
  34. package/packages/driver-webos/src/DeviceWebos.ts +0 -8
  35. package/packages/driver-webos/src/keymap.ts +1 -2
  36. package/packages/driver-xbox/src/keymap.ts +1 -1
  37. package/packages/epg/README.md +1 -3
  38. package/packages/epg/src/v2/Cell.tsx +2 -16
  39. package/packages/epg/src/v2/DataManager.ts +41 -112
  40. package/packages/epg/src/v2/DatePicker.tsx +3 -9
  41. package/packages/epg/src/v2/DateToast/DateToast.tsx +9 -12
  42. package/packages/epg/src/v2/Day.tsx +3 -6
  43. package/packages/epg/src/v2/Epg.tsx +5 -5
  44. package/packages/epg/src/v2/MockGenerator/generator.ts +2 -3
  45. package/packages/epg/src/v2/ProgramInfo/utils.ts +3 -4
  46. package/packages/epg/src/v2/Row.tsx +1 -3
  47. package/packages/epg/src/v2/TimelineSection.tsx +1 -4
  48. package/packages/epg/src/v2/basic/CellsManager.tsx +2 -7
  49. package/packages/epg/src/v2/basic/RowsManager.tsx +1 -3
  50. package/packages/epg/src/v2/interface.ts +0 -13
  51. package/packages/events-manager/src/EventsManager.ts +56 -1
  52. package/packages/focus/README.md +0 -33
  53. package/packages/focus/src/IFocusable.ts +0 -1
  54. package/packages/focus/src/Layout/Base.tsx +6 -41
  55. package/packages/focus/src/Layout/Matrix.tsx +19 -51
  56. package/packages/focus/src/Layout/__test__/Base.spec.ts +180 -0
  57. package/packages/focus/src/Layout/__test__/Horizontal.spec.ts +94 -0
  58. package/packages/focus/src/Layout/__test__/Matrix.spec.ts +261 -0
  59. package/packages/focus/src/Layout/__test__/Vertical.spec.ts +46 -0
  60. package/packages/focus/src/Layout/__test__/isRtl.spec.ts +23 -0
  61. package/packages/focus/src/Layout/__test__/shared.ts +19 -0
  62. package/packages/focus/src/focusFirstExisting.ts +1 -7
  63. package/packages/focus/src/index.ts +1 -2
  64. package/packages/gallup/src/Gallup.ts +3 -3
  65. package/packages/grid/src/Base/Base.tsx +10 -15
  66. package/packages/grid/src/FirstOnlyGrid/FirstOnlyGrid.tsx +2 -4
  67. package/packages/icon/src/Icon.tsx +5 -27
  68. package/packages/input/README.md +1 -4
  69. package/packages/input/src/Input.tsx +29 -65
  70. package/packages/input/src/handleOverflow.ts +29 -0
  71. package/packages/interactable/README.md +1 -2
  72. package/packages/interactable/src/Interactable.tsx +3 -9
  73. package/packages/interactable/src/interface.ts +0 -1
  74. package/packages/jsx/src/index.ts +1 -1
  75. package/packages/jsx/src/test-utils/index.ts +0 -1
  76. package/packages/keyboard/src/Backdrop/Backdrop.scss +0 -2
  77. package/packages/keyboard/src/KeyboardBase.tsx +4 -16
  78. package/packages/keyboard/src/WhitelabelKeyboard/Keyboard.scss +0 -4
  79. package/packages/keyboard/src/WhitelabelKeyboard/Keyboard.tsx +20 -28
  80. package/packages/keyboard/src/WhitelabelKeyboard/_sizes.1080.scss +0 -1
  81. package/packages/keyboard/src/WhitelabelKeyboard/_sizes.scss +0 -1
  82. package/packages/keyboard/src/WhitelabelKeyboard/layouts/index.ts +0 -11
  83. package/packages/keyboard/src/WhitelabelKeyboard/types.ts +0 -1
  84. package/packages/l10n/README.md +0 -18
  85. package/packages/l10n/src/date/common.ts +6 -18
  86. package/packages/l10n/src/date/cs.ts +8 -2
  87. package/packages/l10n/src/date/en-001.ts +3 -3
  88. package/packages/l10n/src/date/en-common.ts +4 -5
  89. package/packages/l10n/src/date/en-us.ts +3 -3
  90. package/packages/l10n/src/date/iso.ts +13 -12
  91. package/packages/l10n/src/date/types.ts +0 -9
  92. package/packages/l10n/src/l10n.ts +3 -61
  93. package/packages/list/src/Base/Base.tsx +9 -19
  94. package/packages/list/src/Base/interface.ts +2 -2
  95. package/packages/list/src/CenteredList/controller.ts +1 -0
  96. package/packages/list/src/EdgeOffsetList/EdgeOffsetList.tsx +3 -3
  97. package/packages/list/src/UnifiedListController/UnifiedListController.ts +2 -6
  98. package/packages/logger/src/loggers/SentryLogger/Sentry.ts +0 -1
  99. package/packages/logger/src/loggers/SentryLogger/SentryLogger.ts +2 -2
  100. package/packages/menu/src/MenuAndContentContainer/MenuAndContentContainer.tsx +3 -31
  101. package/packages/menu/src/MenuAndContentContainer/interface.ts +0 -8
  102. package/packages/modal-service/README.md +1 -4
  103. package/packages/modal-service/src/ModalService.tsx +5 -29
  104. package/packages/perf-utils/README.md +120 -1
  105. package/packages/perf-utils/src/array/filter.ts +54 -1
  106. package/packages/perf-utils/src/array/find.ts +43 -1
  107. package/packages/perf-utils/src/array/findIndex.ts +43 -1
  108. package/packages/perf-utils/src/array/forEach.ts +48 -1
  109. package/packages/perf-utils/src/array/includes.ts +41 -1
  110. package/packages/perf-utils/src/array/includesNaN.ts +32 -1
  111. package/packages/perf-utils/src/array/index.ts +7 -1
  112. package/packages/perf-utils/src/array/map.ts +52 -1
  113. package/packages/player-ui/README.md +1 -1
  114. package/packages/player-ui/src/CurrentTime.tsx +2 -2
  115. package/packages/player-ui/src/Duration.tsx +2 -2
  116. package/packages/player-ui/src/PauseButton.tsx +0 -8
  117. package/packages/player-ui/src/PlayerInteractable.tsx +0 -1
  118. package/packages/player-ui/src/PlayerTime.tsx +1 -3
  119. package/packages/player-ui/src/PlayerUI.tsx +35 -68
  120. package/packages/player-ui/src/RemainingTime.tsx +2 -2
  121. package/packages/player-ui/src/Seekbar.tsx +18 -110
  122. package/packages/player-ui/src/Seeking.ts +16 -57
  123. package/packages/player-ui/src/Subtitles.tsx +2 -2
  124. package/packages/player-ui/src/index.ts +0 -1
  125. package/packages/player-ui/src/mocks.ts +8 -32
  126. package/packages/player-ui/src/timeUtils.ts +3 -3
  127. package/packages/player-ui/src/types.ts +3 -9
  128. package/packages/router/src/Route.tsx +27 -61
  129. package/packages/router/src/Router.tsx +13 -59
  130. package/packages/router/src/history.ts +1 -8
  131. package/packages/router/src/index.ts +1 -1
  132. package/packages/router/src/utils.ts +4 -9
  133. package/packages/sass-utils/src/linear-gradient.scss +4 -9
  134. package/packages/sass-utils/src/scale.1080.scss +1 -3
  135. package/packages/sass-utils/src/scale.720.scss +1 -1
  136. package/packages/time/README.md +1 -4
  137. package/packages/time/src/Time.ts +13 -35
  138. package/packages/time/src/constants.ts +0 -1
  139. package/packages/toast/src/ToastService.tsx +5 -16
  140. package/packages/types-bigscreen-jsx/README.md +4 -5
  141. package/packages/types-bigscreen-jsx/index.d.ts +67 -72
  142. package/packages/utils/README.md +0 -27
  143. package/packages/utils/src/elementUtils.ts +0 -25
  144. package/packages/utils/src/index.ts +0 -8
  145. package/packages/utils/src/scaledImage.ts +3 -6
  146. package/packages/utils/src/textUtils.ts +14 -46
  147. package/packages/utils/src/wait.ts +1 -3
  148. package/packages/utils/src/xhr/xhrSend.ts +1 -3
  149. package/packages/utils/src/xhr/xhrSendRetry.ts +1 -3
  150. package/packages/zapping/src/ChannelZapping.ts +0 -9
  151. package/packages/zapping/src/Zapping.tsx +0 -10
  152. package/.vscode/settings.json +0 -6
  153. package/packages/analytics/README.md +0 -8
  154. package/packages/analytics/src/A.ts +0 -1
  155. package/packages/analytics/src/Analytics.ts +0 -1
  156. package/packages/analytics/src/analyticsOnScroll.ts +0 -1
  157. package/packages/analytics/src/clients/ConsoleAnalytics/ConsoleAnalytics.ts +0 -1
  158. package/packages/analytics/src/clients/ConsoleAnalytics/index.ts +0 -1
  159. package/packages/analytics/src/clients/GoogleAnalytics/GoogleAnalytics.ts +0 -200
  160. package/packages/analytics/src/clients/GoogleAnalytics/constants.ts +0 -118
  161. package/packages/analytics/src/clients/GoogleAnalytics/getUrl.ts +0 -17
  162. package/packages/analytics/src/clients/GoogleAnalytics/index.ts +0 -2
  163. package/packages/analytics/src/clients/GoogleAnalytics/interface.ts +0 -77
  164. package/packages/analytics/src/clients/GoogleAnalytics/mapPayload.ts +0 -50
  165. package/packages/analytics/src/clients/GoogleAnalytics/prepareBody.ts +0 -14
  166. package/packages/analytics/src/clients/TealiumAnalytics/TealiumAnalytics.ts +0 -169
  167. package/packages/analytics/src/clients/TealiumAnalytics/constants.ts +0 -102
  168. package/packages/analytics/src/clients/TealiumAnalytics/findIdForLanguage.ts +0 -9
  169. package/packages/analytics/src/clients/TealiumAnalytics/index.ts +0 -4
  170. package/packages/analytics/src/clients/TealiumAnalytics/interface.ts +0 -33
  171. package/packages/analytics/src/clients/TealiumAnalytics/mappers/__mocks__/mediaPayload.ts +0 -70
  172. package/packages/analytics/src/clients/TealiumAnalytics/mappers/helper.ts +0 -36
  173. package/packages/analytics/src/clients/TealiumAnalytics/mappers/mapAppError.ts +0 -13
  174. package/packages/analytics/src/clients/TealiumAnalytics/mappers/mapFavoriteAdd.ts +0 -11
  175. package/packages/analytics/src/clients/TealiumAnalytics/mappers/mapFavoriteRemove.ts +0 -11
  176. package/packages/analytics/src/clients/TealiumAnalytics/mappers/mapPlayerClose.ts +0 -15
  177. package/packages/analytics/src/clients/TealiumAnalytics/mappers/mapPlayerOpen.ts +0 -15
  178. package/packages/analytics/src/clients/TealiumAnalytics/mappers/mapSceneView.ts +0 -18
  179. package/packages/analytics/src/clients/TealiumAnalytics/mappers/mapSearch.ts +0 -18
  180. package/packages/analytics/src/clients/TealiumAnalytics/mappers/mapSearchFailed.ts +0 -8
  181. package/packages/analytics/src/clients/TealiumAnalytics/mappers/mapSearchSuccess.ts +0 -8
  182. package/packages/analytics/src/clients/TealiumAnalytics/mappers/mapVideoPause.ts +0 -15
  183. package/packages/analytics/src/clients/TealiumAnalytics/mappers/mapVideoProgress.ts +0 -18
  184. package/packages/analytics/src/clients/TealiumAnalytics/mappers/mapVideoResume.ts +0 -15
  185. package/packages/analytics/src/clients/TealiumAnalytics/mappers/mapVideoStart.ts +0 -15
  186. package/packages/analytics/src/clients/TealiumAnalytics/mappers/mapVideoStop.ts +0 -15
  187. package/packages/analytics/src/clients/TealiumAnalytics/types.ts +0 -156
  188. package/packages/analytics/src/clients/TwentyFourIQ/TwentyFourIQClient.ts +0 -116
  189. package/packages/analytics/src/clients/TwentyFourIQ/constants.ts +0 -99
  190. package/packages/analytics/src/clients/TwentyFourIQ/helper.ts +0 -34
  191. package/packages/analytics/src/clients/TwentyFourIQ/index.ts +0 -2
  192. package/packages/analytics/src/clients/TwentyFourIQ/interface.ts +0 -31
  193. package/packages/analytics/src/clients/TwentyFourIQ/mappers/mapAdLoaded.ts +0 -13
  194. package/packages/analytics/src/clients/TwentyFourIQ/mappers/mapAdSkipped.ts +0 -16
  195. package/packages/analytics/src/clients/TwentyFourIQ/mappers/mapBase.ts +0 -21
  196. package/packages/analytics/src/clients/TwentyFourIQ/mappers/mapBuffering.ts +0 -15
  197. package/packages/analytics/src/clients/TwentyFourIQ/mappers/mapPlayerClose.ts +0 -24
  198. package/packages/analytics/src/clients/TwentyFourIQ/mappers/mapPlayerOpen.ts +0 -18
  199. package/packages/analytics/src/clients/TwentyFourIQ/mappers/mapSceneView.ts +0 -15
  200. package/packages/analytics/src/clients/TwentyFourIQ/mappers/mapScroll.ts +0 -17
  201. package/packages/analytics/src/clients/TwentyFourIQ/mappers/mapVideoComplete.ts +0 -21
  202. package/packages/analytics/src/clients/TwentyFourIQ/mappers/mapVideoPause.ts +0 -24
  203. package/packages/analytics/src/clients/TwentyFourIQ/mappers/mapVideoProgress.ts +0 -24
  204. package/packages/analytics/src/clients/TwentyFourIQ/mappers/mapVideoStart.ts +0 -34
  205. package/packages/analytics/src/clients/TwentyFourIQ/mappers/mapVideoStop.ts +0 -32
  206. package/packages/analytics/src/clients/TwentyFourIQ/types.ts +0 -115
  207. package/packages/analytics/src/constants.ts +0 -1
  208. package/packages/analytics/src/index.ts +0 -3
  209. package/packages/analytics/src/interface.ts +0 -1
  210. package/packages/analytics/src/utils/generateSessionId.ts +0 -8
  211. package/packages/create-package/dist/createPackage.js +0 -66
  212. package/packages/create-package/dist/createPackage.js.map +0 -1
  213. package/packages/create-package/dist/index.js +0 -5
  214. package/packages/create-package/dist/index.js.map +0 -1
  215. package/packages/create-package/dist/questionnaire/questions.js +0 -35
  216. package/packages/create-package/dist/questionnaire/questions.js.map +0 -1
  217. package/packages/create-package/dist/settings/Settings.js +0 -10
  218. package/packages/create-package/dist/settings/Settings.js.map +0 -1
  219. package/packages/create-package/dist/types.js +0 -3
  220. package/packages/create-package/dist/types.js.map +0 -1
  221. package/packages/device/src/driver/index.firetv.ts +0 -1
  222. package/packages/device/src/driver/index.smartcast.tv.ts +0 -1
  223. package/packages/driver-firetv/src/DeviceFireTV.ts +0 -18
  224. package/packages/driver-firetv/src/__mocks__/javaScriptBridge.ts +0 -36
  225. package/packages/driver-firetv/src/index.ts +0 -1
  226. package/packages/driver-smartcast/src/DeviceSmartCast.ts +0 -317
  227. package/packages/driver-smartcast/src/__mocks__/api.ts +0 -49
  228. package/packages/driver-smartcast/src/index.ts +0 -1
  229. package/packages/driver-smartcast/src/keymap.ts +0 -9
  230. package/packages/driver-smartcast/src/types.ts +0 -65
  231. package/packages/focus/src/hasFocus.ts +0 -36
  232. package/packages/input/src/utils.ts +0 -71
  233. package/packages/jsx/src/test-utils/keyup.ts +0 -27
  234. package/packages/keyboard/src/WhitelabelKeyboard/layouts/arabic.ts +0 -27
  235. package/packages/keyboard/src/WhitelabelKeyboard/layouts/burmese.ts +0 -27
  236. package/packages/keyboard/src/WhitelabelKeyboard/layouts/dari.ts +0 -28
  237. package/packages/keyboard/src/WhitelabelKeyboard/layouts/korean.ts +0 -26
  238. package/packages/keyboard/src/WhitelabelKeyboard/layouts/pashto.ts +0 -27
  239. package/packages/keyboard/src/WhitelabelKeyboard/layouts/persian.ts +0 -27
  240. package/packages/keyboard/src/WhitelabelKeyboard/layouts/russian.ts +0 -27
  241. package/packages/keyboard/src/WhitelabelKeyboard/layouts/tibetan.ts +0 -26
  242. package/packages/keyboard/src/WhitelabelKeyboard/layouts/turkish.ts +0 -26
  243. package/packages/keyboard/src/WhitelabelKeyboard/layouts/ukrainian.ts +0 -27
  244. package/packages/keyboard/src/WhitelabelKeyboard/layouts/urdu.ts +0 -26
  245. package/packages/l10n/src/date/de.ts +0 -97
  246. package/packages/l10n/src/date/es.ts +0 -71
  247. package/packages/l10n/src/date/fr.ts +0 -94
  248. package/packages/l10n/src/date/he.ts +0 -101
  249. package/packages/time/src/adapters/24iMediaTimeApi.ts +0 -47
  250. package/packages/time/src/services/24iMediaTimeApi/24iMediaTimeApi.ts +0 -43
  251. package/packages/time/src/services/24iMediaTimeApi/index.ts +0 -6
  252. package/packages/utils/src/forceReflow.ts +0 -14
  253. package/packages/utils/src/keyPress/index.ts +0 -6
  254. package/packages/utils/src/keyPress/keyPressSimulator.ts +0 -74
  255. package/packages/utils/src/keyPress/simulateKeyPress.ts +0 -25
  256. package/utils/release/release.ts +0 -154
@@ -0,0 +1,261 @@
1
+ import { createRef } from '@24i/bigscreen-sdk/jsx';
2
+ import { LEFT, RIGHT, UP, DOWN, Key } from '@24i/bigscreen-sdk/device/keymap';
3
+ import { Matrix, CircularDirection } from '../Matrix';
4
+
5
+ const simulateKey = (key: Key): KeyboardEvent => ({
6
+ code: key.code,
7
+ preventDefault: jest.fn(),
8
+ stopPropagation: jest.fn(),
9
+ } as unknown as KeyboardEvent);
10
+
11
+ const getFocusable = () => ({
12
+ focus: jest.fn(),
13
+ });
14
+
15
+ const domRef = createRef(document.createElement('div'));
16
+
17
+ const A1 = createRef(getFocusable());
18
+ const A2 = createRef(getFocusable());
19
+ const A3 = createRef(getFocusable());
20
+ const B1 = createRef(getFocusable());
21
+ const C1 = createRef(getFocusable());
22
+ const C2 = createRef(getFocusable());
23
+ const C3 = createRef(getFocusable());
24
+ const D1 = createRef(getFocusable());
25
+ const D2 = createRef(getFocusable());
26
+
27
+ const MATRIX = [
28
+ [A1, B1, C1, D1],
29
+ [A2, B1, C2, C2],
30
+ [A3, B1, C3, D2],
31
+ ];
32
+
33
+ describe('Matrix focus', () => {
34
+ let matrix: Matrix;
35
+
36
+ beforeEach(() => {
37
+ matrix = new Matrix({ ...Matrix.defaultProps, matrix: MATRIX, domRef, children: [] });
38
+ });
39
+
40
+ it('should have default index at 0, 0', () => {
41
+ expect(matrix.index).toStrictEqual({ x: 0, y: 0 });
42
+ });
43
+
44
+ it('should go A1 -> RIGHT -> B1', () => {
45
+ matrix.index = { x: 0, y: 0 };
46
+ const event = simulateKey(RIGHT);
47
+ matrix.onKeyDown(event);
48
+ expect(B1.current!.focus).toHaveBeenCalled();
49
+ expect(event.preventDefault).toHaveBeenCalled();
50
+ expect(event.stopPropagation).toHaveBeenCalled();
51
+ B1.current!.focus.mockClear();
52
+ });
53
+
54
+ it('should go A1 -> DOWN -> A2', () => {
55
+ matrix.index = { x: 0, y: 0 };
56
+ const event = simulateKey(DOWN);
57
+ matrix.onKeyDown(event);
58
+ expect(A2.current!.focus).toHaveBeenCalled();
59
+ expect(event.preventDefault).toHaveBeenCalled();
60
+ expect(event.stopPropagation).toHaveBeenCalled();
61
+ A2.current!.focus.mockClear();
62
+ });
63
+
64
+ it('should go D2 -> LEFT -> C3', () => {
65
+ matrix.index = { x: 3, y: 2 };
66
+ const event = simulateKey(LEFT);
67
+ matrix.onKeyDown(event);
68
+ expect(C3.current!.focus).toHaveBeenCalled();
69
+ expect(event.preventDefault).toHaveBeenCalled();
70
+ expect(event.stopPropagation).toHaveBeenCalled();
71
+ C3.current!.focus.mockClear();
72
+ });
73
+
74
+ it('should go D2 -> UP -> C2', () => {
75
+ matrix.index = { x: 3, y: 2 };
76
+ const event = simulateKey(UP);
77
+ matrix.onKeyDown(event);
78
+ expect(C2.current!.focus).toHaveBeenCalled();
79
+ expect(event.preventDefault).toHaveBeenCalled();
80
+ expect(event.stopPropagation).toHaveBeenCalled();
81
+ C2.current!.focus.mockClear();
82
+ });
83
+
84
+ it('should not leave left boundary', () => {
85
+ matrix.index = { x: 0, y: 0 };
86
+ const event = simulateKey(LEFT);
87
+ matrix.onKeyDown(event);
88
+ expect(matrix.index).toStrictEqual({ x: 0, y: 0 });
89
+ expect(event.preventDefault).not.toHaveBeenCalled();
90
+ expect(event.stopPropagation).not.toHaveBeenCalled();
91
+ });
92
+
93
+ it('should not leave top boundary', () => {
94
+ matrix.index = { x: 1, y: 2 };
95
+ const event = simulateKey(UP);
96
+ matrix.onKeyDown(event);
97
+ expect(matrix.index).toStrictEqual({ x: 1, y: 2 });
98
+ expect(event.preventDefault).not.toHaveBeenCalled();
99
+ expect(event.stopPropagation).not.toHaveBeenCalled();
100
+ });
101
+
102
+ it('should not leave right boundary', () => {
103
+ matrix.index = { x: 2, y: 1 };
104
+ const event = simulateKey(RIGHT);
105
+ matrix.onKeyDown(event);
106
+ expect(matrix.index).toStrictEqual({ x: 2, y: 1 });
107
+ expect(event.preventDefault).not.toHaveBeenCalled();
108
+ expect(event.stopPropagation).not.toHaveBeenCalled();
109
+ });
110
+
111
+ it('should not leave bottom boundary', () => {
112
+ matrix.index = { x: 3, y: 2 };
113
+ const event = simulateKey(DOWN);
114
+ matrix.onKeyDown(event);
115
+ expect(matrix.index).toStrictEqual({ x: 3, y: 2 });
116
+ expect(event.preventDefault).not.toHaveBeenCalled();
117
+ expect(event.stopPropagation).not.toHaveBeenCalled();
118
+ });
119
+
120
+ it('should keep row (Ax -> RIGHT -> B1 -> RIGHT -> Cx)', () => {
121
+ const event = simulateKey(RIGHT);
122
+ matrix.index = { x: 0, y: 0 };
123
+ matrix.onKeyDown(event);
124
+ matrix.onKeyDown(event);
125
+ expect(C1.current!.focus).toHaveBeenCalled();
126
+ matrix.index = { x: 0, y: 1 };
127
+ matrix.onKeyDown(event);
128
+ matrix.onKeyDown(event);
129
+ expect(C2.current!.focus).toHaveBeenCalled();
130
+ matrix.index = { x: 0, y: 2 };
131
+ matrix.onKeyDown(event);
132
+ matrix.onKeyDown(event);
133
+ expect(C3.current!.focus).toHaveBeenCalled();
134
+ C1.current!.focus.mockClear();
135
+ C2.current!.focus.mockClear();
136
+ C3.current!.focus.mockClear();
137
+ });
138
+
139
+ it('should keep column (C3/D2 -> UP -> C2 -> UP -> C1/D1)', () => {
140
+ const event = simulateKey(UP);
141
+ matrix.index = { x: 2, y: 2 };
142
+ matrix.onKeyDown(event);
143
+ matrix.onKeyDown(event);
144
+ expect(C1.current!.focus).toHaveBeenCalled();
145
+ matrix.index = { x: 3, y: 2 };
146
+ matrix.onKeyDown(event);
147
+ matrix.onKeyDown(event);
148
+ expect(D1.current!.focus).toHaveBeenCalled();
149
+ C1.current!.focus.mockClear();
150
+ D1.current!.focus.mockClear();
151
+ });
152
+
153
+ it('should skip same and focus next (C2 -> LEFT -> C2 -> B1)', () => {
154
+ matrix.index = { x: 3, y: 1 };
155
+ matrix.onKeyDown(simulateKey(LEFT));
156
+ expect(B1.current!.focus).toHaveBeenCalled();
157
+ B1.current!.focus.mockClear();
158
+ });
159
+
160
+ describe('circular focus', () => {
161
+ const commonProps = {
162
+ ...Matrix.defaultProps,
163
+ matrix: MATRIX,
164
+ domRef,
165
+ children: null as any,
166
+ };
167
+ it('should circle to the left (A1 -> left -> D1)', () => {
168
+ matrix = new Matrix({ ...commonProps, circular: CircularDirection.HORIZONTAL });
169
+ matrix.index = { x: 0, y: 0 };
170
+ const event = simulateKey(LEFT);
171
+ matrix.onKeyDown(event);
172
+ expect(D1.current!.focus).toHaveBeenCalled();
173
+ expect(matrix.index).toEqual({ x: 3, y: 0 });
174
+ D1.current!.focus.mockClear();
175
+ });
176
+
177
+ it('should circle to the right (A1 -> right -> D1)', () => {
178
+ matrix = new Matrix({ ...commonProps, circular: CircularDirection.HORIZONTAL });
179
+ matrix.index = { x: 3, y: 0 };
180
+ const event = simulateKey(RIGHT);
181
+ matrix.onKeyDown(event);
182
+ expect(A1.current!.focus).toHaveBeenCalled();
183
+ expect(matrix.index).toEqual({ x: 0, y: 0 });
184
+ A1.current!.focus.mockClear();
185
+ });
186
+
187
+ it('should circle to upwards (A1 -> up -> A3)', () => {
188
+ matrix = new Matrix({ ...commonProps, circular: CircularDirection.VERTICAL });
189
+ matrix.index = { x: 0, y: 0 };
190
+ const event = simulateKey(UP);
191
+ matrix.onKeyDown(event);
192
+ expect(A3.current!.focus).toHaveBeenCalled();
193
+ expect(matrix.index).toEqual({ x: 0, y: 2 });
194
+ A3.current!.focus.mockClear();
195
+ });
196
+
197
+ it('should circle to downwards (A3 -> down -> A1)', () => {
198
+ matrix = new Matrix({ ...commonProps, circular: CircularDirection.VERTICAL });
199
+ matrix.index = { x: 0, y: 2 };
200
+ const event = simulateKey(DOWN);
201
+ matrix.onKeyDown(event);
202
+ expect(A1.current!.focus).toHaveBeenCalled();
203
+ expect(matrix.index).toEqual({ x: 0, y: 0 });
204
+ A1.current!.focus.mockClear();
205
+ });
206
+
207
+ it('should circle horizontally and vertically (A3 -> down -> A1 -> left -> D1)', () => {
208
+ matrix = new Matrix({ ...commonProps, circular: CircularDirection.ALL });
209
+ matrix.index = { x: 0, y: 2 };
210
+ let event = simulateKey(DOWN);
211
+ matrix.onKeyDown(event);
212
+ expect(matrix.index).toEqual({ x: 0, y: 0 });
213
+
214
+ event = simulateKey(LEFT);
215
+ matrix.onKeyDown(event);
216
+ expect(matrix.index).toEqual({ x: 3, y: 0 });
217
+ A1.current!.focus.mockClear();
218
+ D1.current!.focus.mockClear();
219
+ });
220
+
221
+ it('given vertical should not circle to horizontally (A1 -> left -> A1)', () => {
222
+ matrix = new Matrix({ ...commonProps, circular: CircularDirection.VERTICAL });
223
+ matrix.index = { x: 0, y: 0 };
224
+ const event = simulateKey(LEFT);
225
+ matrix.onKeyDown(event);
226
+ expect(matrix.index).toEqual({ x: 0, y: 0 });
227
+ });
228
+
229
+ it('given horizontal should not circle to vertically (A1 -> up -> A1)', () => {
230
+ matrix = new Matrix({ ...commonProps, circular: CircularDirection.HORIZONTAL });
231
+ matrix.index = { x: 0, y: 0 };
232
+ const event = simulateKey(UP);
233
+ matrix.onKeyDown(event);
234
+ expect(matrix.index).toEqual({ x: 0, y: 0 });
235
+ });
236
+
237
+ it('given 1 vertical key should not loop infinitely', () => {
238
+ matrix = new Matrix({ ...commonProps, circular: CircularDirection.VERTICAL });
239
+ matrix.index = { x: 1, y: 0 };
240
+ const event = simulateKey(UP);
241
+ matrix.onKeyDown(event);
242
+ expect(matrix.index).toEqual({ x: 1, y: 0 });
243
+ });
244
+
245
+ it('given 1 horizontal key should not loop infinitely', () => {
246
+ const keyMatrix = [
247
+ [A1, B1, C1, D1],
248
+ [C2, C2, C2, C2],
249
+ ];
250
+ matrix = new Matrix({
251
+ ...commonProps,
252
+ matrix: keyMatrix,
253
+ circular: CircularDirection.VERTICAL,
254
+ });
255
+ matrix.index = { x: 0, y: 1 };
256
+ const event = simulateKey(LEFT);
257
+ matrix.onKeyDown(event);
258
+ expect(matrix.index).toEqual({ x: 0, y: 1 });
259
+ });
260
+ });
261
+ });
@@ -0,0 +1,46 @@
1
+ import { Vertical } from '../Vertical';
2
+ import { rootRef, refChildA, refChildB, refChildC } from './shared';
3
+
4
+ const mockEvent = {
5
+ target: false,
6
+ preventDefault: jest.fn(),
7
+ stopPropagation: jest.fn(),
8
+ };
9
+ const mockUPEvent = {
10
+ code: 'ArrowUp',
11
+ ...mockEvent,
12
+ };
13
+ const mockDOWNEvent = {
14
+ code: 'ArrowDown',
15
+ ...mockEvent,
16
+ };
17
+
18
+ describe('Vertical Focus Layout', () => {
19
+ let vertical: any;
20
+ beforeEach(() => {
21
+ vertical = new Vertical({
22
+ domRef: rootRef,
23
+ children: 'children',
24
+ focusableChildren: [refChildA, refChildB, refChildC],
25
+ onFocusChanged: jest.fn(),
26
+ onBeforeFocusChange: jest.fn(),
27
+ });
28
+ vertical.forward = jest.fn();
29
+ vertical.backward = jest.fn();
30
+ });
31
+
32
+ it('should be a class component', () => {
33
+ expect(Vertical.isClass).toBe(true);
34
+ });
35
+
36
+ it('should call forward on DOWN', () => {
37
+ vertical.onKeyDown(mockDOWNEvent);
38
+ expect(vertical.forward).toHaveBeenCalled();
39
+ });
40
+
41
+ it('should call forward on UP', () => {
42
+ vertical.setIndex(1);
43
+ vertical.onKeyDown(mockUPEvent);
44
+ expect(vertical.backward).toHaveBeenCalled();
45
+ });
46
+ });
@@ -0,0 +1,23 @@
1
+ import * as i18n from '@24i/bigscreen-sdk/i18n';
2
+ import { isRtl } from '../isRtl';
3
+ import { SharedProps } from '../types';
4
+
5
+ describe('isRtl', () => {
6
+ const mockIsRtl = jest.spyOn(i18n, 'isRtl');
7
+
8
+ it.each([
9
+ { focusDir: 'ltr', langDir: 'ltr', expectedIsRtl: false },
10
+ { focusDir: 'rtl', langDir: 'ltr', expectedIsRtl: true },
11
+ { focusDir: 'auto', langDir: 'ltr', expectedIsRtl: false },
12
+ { focusDir: undefined, langDir: 'ltr', expectedIsRtl: false },
13
+ { focusDir: 'ltr', langDir: 'rtl', expectedIsRtl: false },
14
+ { focusDir: 'rtl', langDir: 'rtl', expectedIsRtl: true },
15
+ { focusDir: 'auto', langDir: 'rtl', expectedIsRtl: true },
16
+ { focusDir: undefined, langDir: 'rtl', expectedIsRtl: true },
17
+ ])('should for $focusDir focus and $langDir language return $expectedIsRtl', ({
18
+ focusDir, langDir, expectedIsRtl,
19
+ }) => {
20
+ mockIsRtl.mockReturnValue(langDir === 'rtl');
21
+ expect(isRtl(focusDir as SharedProps['dir'])).toBe(expectedIsRtl);
22
+ });
23
+ });
@@ -0,0 +1,19 @@
1
+ import { createRef } from '@24i/bigscreen-sdk/jsx';
2
+ import { IFocusable } from '../../IFocusable';
3
+
4
+ class ChildMock {
5
+ focus = jest.fn();
6
+ }
7
+
8
+ const root = document.createElement('div');
9
+ export const rootRef = createRef(root);
10
+
11
+ const childA = new ChildMock();
12
+ const childB = new ChildMock();
13
+ const childC = new ChildMock();
14
+ const childD = new ChildMock();
15
+ (childD as IFocusable).hasDom = jest.fn().mockReturnValue(false);
16
+ export const refChildA = createRef(childA);
17
+ export const refChildB = createRef(childB);
18
+ export const refChildC = createRef(childC);
19
+ export const refChildD = createRef(childD);
@@ -1,12 +1,6 @@
1
- import { createRef, Reference } from '@24i/bigscreen-sdk/jsx';
1
+ import { Reference } from '@24i/bigscreen-sdk/jsx';
2
2
  import { IFocusable } from './IFocusable';
3
3
 
4
- export const preventScrollOnFocus = (ref: Reference<IFocusable>) => (
5
- createRef<IFocusable>({
6
- focus: () => ref.current?.focus({ preventScroll: true }),
7
- })
8
- );
9
-
10
4
  export const focusFirstExisting = (...toFocus: Reference<IFocusable>[]) => (
11
5
  () => {
12
6
  for (let i = 0; i < toFocus.length; i++) {
@@ -11,6 +11,5 @@ export {
11
11
  setNextFocusCandidate,
12
12
  focusCandidate,
13
13
  } from './candidate';
14
- export { focusFirstExisting, preventScrollOnFocus } from './focusFirstExisting';
14
+ export { focusFirstExisting } from './focusFirstExisting';
15
15
  export { refocusAfterHashChange } from './refocusAfterHashChange';
16
- export { hasFocus, isFocused } from './hasFocus';
@@ -1,4 +1,4 @@
1
- import { PlayerBase } from '@24i/bigscreen-players-engine-base';
1
+ import { PlayerBase } from '@24i/player-base';
2
2
  import './__external__/SpringStreams';
3
3
 
4
4
  const SECOND_IN_MS = 1000;
@@ -16,7 +16,7 @@ export class Gallup {
16
16
  */
17
17
  constructor(
18
18
  siteCode: string,
19
- private readonly player: PlayerBase,
19
+ private readonly player: PlayerBase<any>,
20
20
  private readonly playerName: string,
21
21
  ) {
22
22
  this.sensors = new SpringStreams(siteCode);
@@ -67,7 +67,7 @@ export class Gallup {
67
67
  getPosition: () => Math.floor(player.currentTime / SECOND_IN_MS),
68
68
  getMeta: () => {
69
69
  const { width, height } = window.screen;
70
- const { playerVersion } = player.mediaInfo;
70
+ const { playerVersion } = player.getMediaInfo();
71
71
  return {
72
72
  pl: playerName,
73
73
  plv: playerVersion || '',
@@ -111,13 +111,11 @@ export class GridBase<T extends Item<U>, U>
111
111
  componentDidMount() {
112
112
  this.scrollerDom.current!.addEventListener('wheel', this.onWheel);
113
113
  this.scroller.current!.wrapRef.current!.addEventListener('keyup', this.onKeyUp);
114
- window.document.addEventListener('keyup', this.onGlobalKeyUp, true);
115
114
  }
116
115
 
117
116
  componentWillUnmount() {
118
117
  this.scrollerDom.current!.removeEventListener('wheel', this.onWheel);
119
118
  this.scroller.current!.wrapRef.current!.removeEventListener('keyup', this.onKeyUp);
120
- window.document.removeEventListener('keyup', this.onGlobalKeyUp, true);
121
119
  }
122
120
 
123
121
  // eslint-disable-next-line sonarjs/cognitive-complexity
@@ -157,9 +155,6 @@ export class GridBase<T extends Item<U>, U>
157
155
  onKeyUp = () => {
158
156
  this.stopFastScrolling();
159
157
  this.fastFocusingOptimizer.stop();
160
- };
161
-
162
- onGlobalKeyUp = () => {
163
158
  this.preventBlurCounter = 0;
164
159
  };
165
160
 
@@ -183,6 +178,16 @@ export class GridBase<T extends Item<U>, U>
183
178
  }
184
179
  };
185
180
 
181
+ shouldPreventBlur(event: KeyboardEvent) {
182
+ const { horizontal, preventBlurOnLongPress } = this.props;
183
+ return (this.preventBlurCounter >= PREVENT_BLUR_ON_LONG_PRESS_KEYDOWNS && (
184
+ (preventBlurOnLongPress.forward && isForward(event, horizontal))
185
+ || (preventBlurOnLongPress.backward && isBackward(event, horizontal))
186
+ || (preventBlurOnLongPress.forwardGroup && isFwGroup(event, horizontal))
187
+ || (preventBlurOnLongPress.backwardGroup && isBwGroup(event, horizontal))
188
+ ));
189
+ }
190
+
186
191
  getRefAtIndex(i: number): Reference<T> {
187
192
  const ref = this.itemRefs[i];
188
193
  if (!ref) {
@@ -248,16 +253,6 @@ export class GridBase<T extends Item<U>, U>
248
253
  this.fastScrollingCounter.reset();
249
254
  };
250
255
 
251
- shouldPreventBlur(event: KeyboardEvent) {
252
- const { horizontal, preventBlurOnLongPress } = this.props;
253
- return (this.preventBlurCounter >= PREVENT_BLUR_ON_LONG_PRESS_KEYDOWNS && (
254
- (preventBlurOnLongPress.forward && isForward(event, horizontal))
255
- || (preventBlurOnLongPress.backward && isBackward(event, horizontal))
256
- || (preventBlurOnLongPress.forwardGroup && isFwGroup(event, horizontal))
257
- || (preventBlurOnLongPress.backwardGroup && isBwGroup(event, horizontal))
258
- ));
259
- }
260
-
261
256
  animatedScrollStarted() {
262
257
  this.isAnimatedScrollRunning = true;
263
258
  }
@@ -61,8 +61,6 @@ export class FirstOnlyGrid<T extends Item<U>, U>
61
61
  const linesDiff = Math.floor(grid.index / itemsInGroup) - oldLine;
62
62
  if (linesDiff > 0) {
63
63
  this.scrollForward(linesDiff);
64
- } else if (linesDiff < 0) {
65
- this.scrollBackward(Math.abs(linesDiff));
66
64
  }
67
65
  };
68
66
 
@@ -79,8 +77,8 @@ export class FirstOnlyGrid<T extends Item<U>, U>
79
77
  this.controller.scroll(targetScrollIndex);
80
78
  }
81
79
 
82
- scrollBackward(diff = 1) {
83
- const targetScrollIndex = this.controller.scrollIndex - diff;
80
+ scrollBackward() {
81
+ const targetScrollIndex = this.controller.scrollIndex - 1;
84
82
  this.controller.scroll(targetScrollIndex);
85
83
  }
86
84
 
@@ -1,19 +1,12 @@
1
1
  import { createRef, Reference, Component } from '@24i/bigscreen-sdk/jsx';
2
- import {
3
- getDisplayToggler,
4
- IDisplayToggler,
5
- removeClass,
6
- addClass,
7
- DISPLAY_NONE,
8
- } from '@24i/bigscreen-sdk/utils';
2
+ import { addClass } from '@24i/bigscreen-sdk/utils/addClass';
3
+ import { removeClass } from '@24i/bigscreen-sdk/utils/removeClass';
9
4
 
10
5
  const ICON_PREFIX = 'icon-';
11
6
 
12
7
  type Props<SpritesJSON> = {
13
8
  icon?: keyof SpritesJSON,
14
- domRef?: Reference<HTMLDivElement>,
15
- className?: string,
16
- initialIsHidden?: boolean,
9
+ domRef?: Reference<HTMLDivElement>;
17
10
  };
18
11
 
19
12
  export class Icon<T> extends Component<Props<T>> {
@@ -21,13 +14,10 @@ export class Icon<T> extends Component<Props<T>> {
21
14
 
22
15
  currentIcon: keyof T | undefined;
23
16
 
24
- iconDisplay: IDisplayToggler;
25
-
26
17
  constructor(props: Props<T>) {
27
18
  super(props);
28
19
  this.ref = props.domRef || createRef();
29
20
  this.currentIcon = props.icon;
30
- this.iconDisplay = getDisplayToggler(this.ref, props.initialIsHidden);
31
21
  }
32
22
 
33
23
  getClass(icon: keyof T): string {
@@ -41,16 +31,6 @@ export class Icon<T> extends Component<Props<T>> {
41
31
  this.currentIcon = icon;
42
32
  }
43
33
 
44
- show() {
45
- if (!this.currentIcon) return;
46
- this.iconDisplay.show();
47
- }
48
-
49
- hide() {
50
- if (!this.currentIcon) return;
51
- this.iconDisplay.hide();
52
- }
53
-
54
34
  clearIcon() {
55
35
  if (!this.currentIcon) return;
56
36
  removeClass(this.ref, this.getClass(this.currentIcon));
@@ -58,13 +38,11 @@ export class Icon<T> extends Component<Props<T>> {
58
38
  }
59
39
 
60
40
  render() {
61
- const { icon, className, initialIsHidden } = this.props;
41
+ const { icon } = this.props;
62
42
  return (
63
43
  <div
64
44
  ref={this.ref}
65
- className={`${className || ''} icon ${icon
66
- ? this.getClass(icon) : ''} ${initialIsHidden
67
- ? DISPLAY_NONE : ''}`}
45
+ className={`icon ${icon ? this.getClass(icon) : ''}`}
68
46
  />
69
47
  );
70
48
  }
@@ -16,9 +16,9 @@ It is connected through ime package to either system or virtual keyboard.
16
16
  - `passwordChar` - optional string which replaces password characters (default: `'●'`)
17
17
  - `shouldHandleOverflow` - optional flag which enables overflow handling by moving text to the left when caret should get out of its container (default: `false`)
18
18
  - `maxLength` - optional number to limit value length (default: `Infinity`)
19
+ - `onChange` - optional callback with new value `(newValue: string) => void`
19
20
  - `onFocus` - optional callback which is called when input gets focus
20
21
  - `onBlur` - optional callback which is called when input loses focus
21
- - `onChange` - optional callback with new value `(newValue: string) => void`
22
22
  - `onFinish` - optional callback which is called when input is finished, its only argument is a boolean to determine if input was cancelled or not `(wasCancelled: boolean) => void`
23
23
 
24
24
  ## Usage
@@ -60,6 +60,3 @@ The reason for no styling is to limit unnecessary CSS code that would be overrid
60
60
  `.native-input-wrap` is set to `display: none`. This is the native input used on the background.
61
61
 
62
62
  `.input-field` is a custom component that should look like input field with possibility of custom styling.
63
-
64
- `.caret` position is counted from the left side of the input in LTR layout and from the right side of the
65
- input in RTL layout.