@24i/bigscreen-sdk 1.0.0 → 1.0.1-alpha.2074

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 (54) hide show
  1. package/package.json +12 -11
  2. package/packages/developer-tools/src/EnvironmentSelection/styles/EnvironmentSelection.scss +1 -1
  3. package/packages/device/src/driver/index.vidaa.tv.ts +1 -0
  4. package/packages/device/src/resolver/resolver.ts +5 -0
  5. package/packages/driver-vidaa/src/DeviceVidaa.ts +134 -0
  6. package/packages/driver-vidaa/src/__mocks__/vidaa.ts +20 -0
  7. package/packages/driver-vidaa/src/formatUserAgent.ts +16 -0
  8. package/packages/driver-vidaa/src/index.ts +1 -0
  9. package/packages/driver-vidaa/src/keymap.ts +54 -0
  10. package/packages/driver-vidaa/src/types.ts +82 -0
  11. package/packages/grid/src/Base/Base.tsx +25 -6
  12. package/packages/grid/src/Base/MouseNavigation/MouseNavigation.tsx +58 -0
  13. package/packages/grid/src/Base/MouseNavigation/MouseNavigationFallback.ts +4 -0
  14. package/packages/grid/src/Base/MouseNavigation/index.tizen.tv.ts +1 -0
  15. package/packages/grid/src/Base/MouseNavigation/index.ts +1 -0
  16. package/packages/grid/src/Base/MouseNavigation/index.webos.tv.ts +1 -0
  17. package/packages/grid/src/Base/MouseNavigation/index.webtv.ts +1 -0
  18. package/packages/grid/src/Base/interface.ts +47 -0
  19. package/packages/grid/src/UnifiedGridController/UnifiedGridController.ts +4 -1
  20. package/packages/list/src/Base/Base.tsx +16 -5
  21. package/packages/list/src/Base/MouseNavigation/MouseNavigation.tsx +58 -0
  22. package/packages/list/src/Base/MouseNavigation/MouseNavigationFallback.ts +4 -0
  23. package/packages/list/src/Base/MouseNavigation/index.tizen.tv.ts +1 -0
  24. package/packages/list/src/Base/MouseNavigation/index.ts +1 -0
  25. package/packages/list/src/Base/MouseNavigation/index.webos.tv.ts +1 -0
  26. package/packages/list/src/Base/MouseNavigation/index.webtv.ts +1 -0
  27. package/packages/list/src/Base/interface.ts +39 -0
  28. package/packages/list/src/BasicList/BasicList.tsx +4 -1
  29. package/packages/list/src/EdgeOffsetList/EdgeOffsetList.tsx +4 -3
  30. package/packages/list/src/FirstOnlyList/FirstOnlyList.tsx +2 -2
  31. package/packages/list/src/FirstOnlyVariedList/FirstOnlyVariedList.tsx +2 -2
  32. package/packages/list/src/FixedToEndList/FixedToEndList.tsx +2 -2
  33. package/packages/list/src/interface.ts +2 -0
  34. package/packages/logger/README.md +1 -1
  35. package/packages/menu/src/MenuAndContentContainer/MenuAndContentContainer.tsx +3 -1
  36. package/packages/menu/src/MenuAndContentContainer/interface.ts +1 -1
  37. package/packages/mouse-navigation/src/MouseNavigation.tsx +2 -2
  38. package/packages/scroll-text/src/Base.tsx +5 -0
  39. package/utils/create-export-maps/src/__tests__/createExportMaps.spec.ts +2 -2
  40. package/utils/create-export-maps/src/createExportMaps.ts +1 -1
  41. package/packages/focus/src/__test__/candidate.spec.tsx +0 -245
  42. package/packages/focus/src/__test__/focusFirstExisting.spec.tsx +0 -21
  43. package/packages/focus/src/__test__/refocusAfterHashChange.spec.tsx +0 -41
  44. package/packages/focus/src/__test__/safeFocus.spec.tsx +0 -41
  45. package/packages/grid/src/Base/Base.mouse.tsx +0 -24
  46. package/packages/grid/src/Base/index.tizen.tv.ts +0 -1
  47. package/packages/grid/src/Base/index.webos.tv.ts +0 -1
  48. package/packages/grid/src/Base/index.webtv.ts +0 -1
  49. package/packages/list/src/Base/Base.mouse.tsx +0 -28
  50. package/packages/list/src/Base/index.tizen.tv.ts +0 -1
  51. package/packages/list/src/Base/index.webos.tv.ts +0 -1
  52. package/packages/list/src/Base/index.webtv.ts +0 -1
  53. package/packages/mouse-navigation/src/__test__/MouseElementWrapper.spec.tsx +0 -61
  54. package/packages/mouse-navigation/src/__test__/MouseNavigation.spec.tsx +0 -107
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@24i/bigscreen-sdk",
3
- "version": "1.0.0",
3
+ "version": "1.0.1-alpha.2074",
4
4
  "description": "SmartApps BIGscreen SDK monorepo",
5
5
  "main": "index.js",
6
6
  "scripts": {
@@ -38,8 +38,8 @@
38
38
  "homepage": "https://github.com/24i/smartapps-bigscreen-sdk#readme",
39
39
  "dependencies": {
40
40
  "@24i/player-base": "6.10.0",
41
- "@24i/smartapps-datalayer": "2.3.0-beta.1",
42
- "@sentry/browser": "^7.6.0",
41
+ "@24i/smartapps-datalayer": "2.3.2",
42
+ "@sentry/browser": "^7.8.0",
43
43
  "@types/prop-types": "^15.7.5",
44
44
  "@types/scheduler": "^0.16.1",
45
45
  "csstype": "^3.1.0",
@@ -50,13 +50,13 @@
50
50
  "@24i/bigscreen-sdk": "file:.",
51
51
  "@24i/eslint-config-smartapps-bigscreen-linters": "file:./libs/linters",
52
52
  "@24i/smartapps-bigscreen-changelog-generator": "0.17.0",
53
- "@babel/core": "^7.18.6",
54
- "@babel/preset-env": "^7.18.6",
53
+ "@babel/core": "^7.18.9",
54
+ "@babel/preset-env": "^7.18.9",
55
55
  "@types/fs-extra": "^9.0.13",
56
56
  "@types/inquirer": "^8.2.1",
57
- "@types/jest": "^28.1.5",
57
+ "@types/jest": "^28.1.6",
58
58
  "@types/minimist": "^1.2.2",
59
- "@types/node": "^17.0.43",
59
+ "@types/node": "^18.6.3",
60
60
  "@types/react": "^18.0.15",
61
61
  "babel-jest": "^28.1.2",
62
62
  "chalk": "^4.1.2",
@@ -65,15 +65,15 @@
65
65
  "fs-extra": "^10.1.0",
66
66
  "full-icu": "^1.4.0",
67
67
  "identity-obj-proxy": "^3.0.0",
68
- "inquirer": "^9.0.0",
68
+ "inquirer": "^9.0.2",
69
69
  "jest": "^28.1.2",
70
70
  "jest-canvas-mock": "^2.4.0",
71
71
  "jest-environment-jsdom": "^28.1.2",
72
72
  "minimist": "^1.2.6",
73
73
  "patch-package": "^6.2.1",
74
- "sass": "^1.53.0",
74
+ "sass": "^1.54.0",
75
75
  "sass-true": "^6.1.0",
76
- "ts-jest": "^28.0.4",
76
+ "ts-jest": "^28.0.7",
77
77
  "ts-node": "^10.8.2",
78
78
  "tsconfig-paths-jest": "0.0.1",
79
79
  "typescript": "^4.7.2"
@@ -111,6 +111,7 @@
111
111
  "./driver-kreatv": "./packages/driver-kreatv/src/index.ts",
112
112
  "./driver-saphi": "./packages/driver-saphi/src/index.ts",
113
113
  "./driver-tizen": "./packages/driver-tizen/src/index.ts",
114
+ "./driver-vidaa": "./packages/driver-vidaa/src/index.ts",
114
115
  "./driver-webos/scripts/template": "./packages/driver-webos/scripts/template.ts",
115
116
  "./driver-webos/scripts/exportWebOSTVjs": "./packages/driver-webos/scripts/exportWebOSTVjs.ts",
116
117
  "./driver-webos": "./packages/driver-webos/src/index.ts",
@@ -270,4 +271,4 @@
270
271
  "./zapping/interface": "./packages/zapping/src/interface.ts",
271
272
  "./zapping": "./packages/zapping/src/index.ts"
272
273
  }
273
- }
274
+ }
@@ -111,7 +111,7 @@
111
111
  }
112
112
 
113
113
  .leading-ellipses-list-item {
114
- height: fit-content;
114
+ height: auto;
115
115
  }
116
116
  }
117
117
  }
@@ -0,0 +1 @@
1
+ export { DeviceVidaa as Device } from '@24i/bigscreen-sdk/driver-vidaa';
@@ -5,6 +5,7 @@ import { DeviceHbbTV } from '@24i/bigscreen-sdk/driver-hbbtv';
5
5
  import { DeviceKreaTV } from '@24i/bigscreen-sdk/driver-kreatv';
6
6
  import { DeviceSaphi } from '@24i/bigscreen-sdk/driver-saphi';
7
7
  import { DeviceTizen } from '@24i/bigscreen-sdk/driver-tizen';
8
+ import { DeviceVidaa } from '@24i/bigscreen-sdk/driver-vidaa';
8
9
  import { DeviceWebos } from '@24i/bigscreen-sdk/driver-webos';
9
10
  import { DeviceXbox } from '@24i/bigscreen-sdk/driver-xbox';
10
11
 
@@ -30,6 +31,10 @@ const getDevice = () => {
30
31
  info('Saphi');
31
32
  return new DeviceSaphi();
32
33
  }
34
+ if (userAgent.match(/Hisense/)) {
35
+ info('VIDAA');
36
+ return new DeviceVidaa();
37
+ }
33
38
  if (userAgent.match(/Ekioh/)) {
34
39
  info('KreaTV');
35
40
  return new DeviceKreaTV();
@@ -0,0 +1,134 @@
1
+ import {
2
+ DeviceBase,
3
+ ConnectionType,
4
+ ScreenSaverStatus,
5
+ VolumeRange,
6
+ } from '@24i/bigscreen-sdk/driver-base';
7
+ import { getPlatformInfo } from './formatUserAgent';
8
+ import { HisenseVidaaApi } from './types';
9
+ import { getKeyMap } from './keymap';
10
+
11
+ declare global {
12
+ interface Window extends HisenseVidaaApi {}
13
+ }
14
+
15
+ export class DeviceVidaa extends DeviceBase {
16
+ keyMap = getKeyMap();
17
+
18
+ platformInfo = getPlatformInfo(navigator.userAgent);
19
+
20
+ async initDevice(): Promise<void> {
21
+ this.initNetworkChangeListener();
22
+ }
23
+
24
+ initNetworkChangeListener() {
25
+ window.addEventListener('online', () => {
26
+ this.triggerEvent('networkchange', { isConnected: true });
27
+ });
28
+ window.addEventListener('offline', () => {
29
+ this.triggerEvent('networkchange', { isConnected: false });
30
+ });
31
+ }
32
+
33
+ reboot(): void {
34
+ let rootPath = '';
35
+ const splitUrl = window.location.href.split('#');
36
+ if (splitUrl.length > 1) rootPath = splitUrl[0];
37
+ window.location.href = rootPath;
38
+ }
39
+
40
+ exit(): void {
41
+ window.close();
42
+ }
43
+
44
+ async getManufacturerName(): Promise<string> {
45
+ return 'Hisense';
46
+ }
47
+
48
+ async getPlatformName(): Promise<string> {
49
+ return 'VIDAA';
50
+ }
51
+
52
+ async getPlatformVersion(): Promise<string> {
53
+ // platform version of Hisense VIDAA is defined on TV 2020 or later
54
+ return this.platformInfo.platformVersion || '';
55
+ }
56
+
57
+ async getDeviceName(): Promise<string> {
58
+ return `Hisense VIDAA ${await this.getModelName()}`.trim();
59
+ }
60
+
61
+ async getModelName(): Promise<string> {
62
+ return window.Hisense_GetModelName() || '';
63
+ }
64
+
65
+ async getFirmware(): Promise<string> {
66
+ return window.Hisense_GetFirmWareVersion() || '';
67
+ }
68
+
69
+ async is4KSupported(): Promise<boolean> {
70
+ return window.Hisense_Get4KSupportState() || false;
71
+ }
72
+
73
+ async is8KSupported(): Promise<boolean> {
74
+ return false;
75
+ }
76
+
77
+ async getUuid(): Promise<string> {
78
+ return window.Hisense_GetDeviceID() || '';
79
+ }
80
+
81
+ async getVolume(): Promise<number> {
82
+ return VolumeRange.UNSUPPORTED;
83
+ }
84
+
85
+ // eslint-disable-next-line @typescript-eslint/no-unused-vars
86
+ async setVolume(volumePercentage: number): Promise<void> {
87
+ // not supported on Hisense VIDAA platform
88
+ }
89
+
90
+ // eslint-disable-next-line @typescript-eslint/no-unused-vars
91
+ async mute(mute: boolean): Promise<void> {
92
+ // not supported on Hisense VIDAA platform
93
+ }
94
+
95
+ async isMute(): Promise<boolean> {
96
+ // not supported on Hisense VIDAA platform
97
+ return false;
98
+ }
99
+
100
+ async getScreenSaver(): Promise<ScreenSaverStatus> {
101
+ // not supported on Hisense VIDAA platform
102
+ return { enabled: false };
103
+ }
104
+
105
+ // eslint-disable-next-line @typescript-eslint/no-unused-vars
106
+ async setScreenSaver(status: ScreenSaverStatus): Promise<void> {
107
+ // not supported on Hisense VIDAA platform
108
+ }
109
+
110
+ // eslint-disable-next-line @typescript-eslint/no-unused-vars
111
+ async setUserAgent(userAgent: string): Promise<boolean> {
112
+ // not supported on Hisense VIDAA platform
113
+ return false;
114
+ }
115
+
116
+ async isNetworkConnected(): Promise<boolean> {
117
+ return window.navigator.onLine;
118
+ }
119
+
120
+ async getConnectionType(): Promise<ConnectionType> {
121
+ // not supported on Hisense VIDAA platform
122
+ return 'unknown';
123
+ }
124
+
125
+ async getLocalIP(): Promise<string> {
126
+ // not supported on Hisense VIDAA platform
127
+ return '';
128
+ }
129
+
130
+ async getMacAddress(): Promise<string> {
131
+ // not supported on Hisense VIDAA platform
132
+ return '';
133
+ }
134
+ }
@@ -0,0 +1,20 @@
1
+ import { HisenseVidaaApi, HisenseVidaaKeys } from '../types';
2
+
3
+ export const mockHisenseVidaaApi: HisenseVidaaApi = {
4
+ Hisense_GetBrand: () => 'hisense',
5
+ Hisense_GetModelName: () => '5U61FQEVS',
6
+ Hisense_GetFirmWareVersion: () => 'V0000.01.00Q.L0301',
7
+ Hisense_Get4KSupportState: () => true,
8
+ Hisense_GetDeviceID: () => '861003009000001000000641123456789012',
9
+ };
10
+
11
+ // Key constants are set to random number values
12
+ export const mockHisenseVidaaKeys = {
13
+ VK_LEFT: 0,
14
+ VK_RIGHT: 1,
15
+ VK_UP: 2,
16
+ VK_DOWN: 3,
17
+ VK_ENTER: 4,
18
+ VK_BACK_SPACE: 5,
19
+ // the rest of key constants is not needed for testing
20
+ } as HisenseVidaaKeys;
@@ -0,0 +1,16 @@
1
+ /**
2
+ * Parses platform info of VIDAA from user agent string.
3
+ * NOTE: Platform info of VIDAA is available in user agent of TVs 2020 or later.
4
+ *
5
+ * @param userAgent User agent string
6
+ * @returns object with platform info like platform name and platform version.
7
+ * If values are not not available, values of keys are set to undefined.
8
+ * Ex. for VIDAA platform string like "VIDAA/4.0" in user agent string , it returns
9
+ * object { platformName: "VIDAA", platformVersion: "4.0" }
10
+ */
11
+ export const getPlatformInfo = (userAgent: string) => {
12
+ const [
13
+ , platformName, platformVersion,
14
+ ] = userAgent.match(/(VIDAA)\/([\d.]+)/) || [] as Array<undefined>;
15
+ return { platformName, platformVersion };
16
+ };
@@ -0,0 +1 @@
1
+ export { DeviceVidaa } from './DeviceVidaa';
@@ -0,0 +1,54 @@
1
+ /* eslint-disable no-magic-numbers */
2
+ import { KeyMap } from '@24i/bigscreen-sdk/driver-base';
3
+ import { HisenseVidaaKeys } from './types';
4
+
5
+ declare const window: Window & HisenseVidaaKeys;
6
+
7
+ export const getKeyMap = () => {
8
+ KeyMap.overrideValues({
9
+ LEFT: { keyCode: window.VK_LEFT },
10
+ RIGHT: { keyCode: window.VK_RIGHT },
11
+ UP: { keyCode: window.VK_UP },
12
+ DOWN: { keyCode: window.VK_DOWN },
13
+ ENTER: { keyCode: window.VK_ENTER },
14
+ BACK: { keyCode: window.VK_BACK_SPACE },
15
+
16
+ RED: { keyCode: window.VK_RED },
17
+ GREEN: { keyCode: window.VK_GREEN },
18
+ YELLOW: { keyCode: window.VK_YELLOW },
19
+ BLUE: { keyCode: window.VK_BLUE },
20
+
21
+ PLAY: { keyCode: window.VK_PLAY },
22
+ PAUSE: { keyCode: window.VK_PAUSE },
23
+ PLAYPAUSE: { keyCode: window.VK_PLAY_PAUSE },
24
+ STOP: { keyCode: window.VK_STOP },
25
+ FF: { keyCode: window.VK_FAST_FWD },
26
+ REW: { keyCode: window.VK_REWIND },
27
+
28
+ NUM_0: { keyCode: window.VK_0 },
29
+ NUM_1: { keyCode: window.VK_1 },
30
+ NUM_2: { keyCode: window.VK_2 },
31
+ NUM_3: { keyCode: window.VK_3 },
32
+ NUM_4: { keyCode: window.VK_4 },
33
+ NUM_5: { keyCode: window.VK_5 },
34
+ NUM_6: { keyCode: window.VK_6 },
35
+ NUM_7: { keyCode: window.VK_7 },
36
+ NUM_8: { keyCode: window.VK_8 },
37
+ NUM_9: { keyCode: window.VK_9 },
38
+ KP_0: { keyCode: window.VK_NUMPAD0 },
39
+ KP_1: { keyCode: window.VK_NUMPAD1 },
40
+ KP_2: { keyCode: window.VK_NUMPAD2 },
41
+ KP_3: { keyCode: window.VK_NUMPAD3 },
42
+ KP_4: { keyCode: window.VK_NUMPAD4 },
43
+ KP_5: { keyCode: window.VK_NUMPAD5 },
44
+ KP_6: { keyCode: window.VK_NUMPAD6 },
45
+ KP_7: { keyCode: window.VK_NUMPAD7 },
46
+ KP_8: { keyCode: window.VK_NUMPAD8 },
47
+ KP_9: { keyCode: window.VK_NUMPAD9 },
48
+
49
+ CHANNEL_UP: { keyCode: window.VK_CHANNEL_UP || 427 },
50
+ CHANNEL_DOWN: { keyCode: window.VK_CHANNEL_DOWN || 428 },
51
+ INFO: { keyCode: window.VK_INFO },
52
+ });
53
+ return KeyMap.generateKeyCodeKeyMap();
54
+ };
@@ -0,0 +1,82 @@
1
+ export interface HisenseVidaaApi {
2
+ /**
3
+ * This interface will retrieve Hisense Unique ID for the device.
4
+ * @return a 32bytes string that represents the device id.
5
+ * Example: 861003009000001000000641123456789012
6
+ */
7
+ Hisense_GetDeviceID: () => string,
8
+ /**
9
+ * This interface will retrieve the firmware version for the device.
10
+ * @return a string that represents the firmware version.
11
+ * Example: V00.01.00a.F0116
12
+ */
13
+ Hisense_GetFirmWareVersion: () => string,
14
+ /**
15
+ * This will retrieve the 4K support status for the device.
16
+ * @return true if 4K is supported otherwise returns false.
17
+ */
18
+ Hisense_Get4KSupportState: () => boolean,
19
+ /**
20
+ * This will retrieve the TV brand for the device.
21
+ * @return a brand full name string that represents the TV brand.
22
+ * Example: hisense, sharp
23
+ */
24
+ Hisense_GetBrand: () => string,
25
+ /**
26
+ * This will retrieve the TV model name (hardware version) for the device.
27
+ * @return a string that represents the TV model name.
28
+ */
29
+ Hisense_GetModelName: () => string,
30
+ }
31
+
32
+ export type HisenseVidaaKeys = {
33
+ readonly VK_UP: number,
34
+ readonly VK_RIGHT: number,
35
+ readonly VK_DOWN: number,
36
+ readonly VK_LEFT: number,
37
+ readonly VK_ENTER: number,
38
+ readonly VK_BACK_SPACE: number,
39
+
40
+ readonly VK_BLUE: number,
41
+ readonly VK_RED: number,
42
+ readonly VK_GREEN: number,
43
+ readonly VK_YELLOW: number,
44
+
45
+ readonly VK_MENU: number,
46
+
47
+ readonly VK_0: number,
48
+ readonly VK_1: number,
49
+ readonly VK_2: number,
50
+ readonly VK_3: number,
51
+ readonly VK_4: number,
52
+ readonly VK_5: number,
53
+ readonly VK_6: number,
54
+ readonly VK_7: number,
55
+ readonly VK_8: number,
56
+ readonly VK_9: number,
57
+ // keys VK_NUMPAD{X} are not introduced in Hisense VIDAA spec but exist in global scope
58
+ readonly VK_NUMPAD0: number,
59
+ readonly VK_NUMPAD1: number,
60
+ readonly VK_NUMPAD2: number,
61
+ readonly VK_NUMPAD3: number,
62
+ readonly VK_NUMPAD4: number,
63
+ readonly VK_NUMPAD5: number,
64
+ readonly VK_NUMPAD6: number,
65
+ readonly VK_NUMPAD7: number,
66
+ readonly VK_NUMPAD8: number,
67
+ readonly VK_NUMPAD9: number,
68
+
69
+ readonly VK_PLAY: number,
70
+ readonly VK_PAUSE: number,
71
+ readonly VK_PLAY_PAUSE: number,
72
+ readonly VK_STOP: number,
73
+ readonly VK_TRACK_NEXT: number,
74
+ readonly VK_TRACK_PREV: number,
75
+ readonly VK_FAST_FWD: number,
76
+ readonly VK_REWIND: number,
77
+ readonly VK_SUBTITLE: number,
78
+ readonly VK_INFO: number,
79
+ // VK_CHANNEL_{UP/DOWN} not introduced in Hisense VIDAA spec but exists in global scope
80
+ readonly VK_CHANNEL_UP: number,
81
+ readonly VK_CHANNEL_DOWN: number,
82
+ };
@@ -1,13 +1,14 @@
1
1
  import { createRef, Component, Reference, DeclareProps } from '@24i/bigscreen-sdk/jsx';
2
2
  import { device } from '@24i/bigscreen-sdk/device';
3
- import { MouseNavigation } from '@24i/bigscreen-sdk/mouse-navigation';
4
3
  import { Scroller } from '@24i/bigscreen-sdk/scroller';
5
4
  import { stopEvent } from '@24i/bigscreen-sdk/utils/stopEvent';
6
5
  import { noop } from '@24i/bigscreen-sdk/utils/noop';
7
6
  import { forEach } from '@24i/bigscreen-sdk/perf-utils/array';
8
7
  import { createTimeout, createCounter, ICounter } from '@24i/bigscreen-sdk/utils';
8
+ import { MouseNavigation } from './MouseNavigation';
9
9
  import { FastFocusingOptimizer } from '../FastFocusingOptimizer/FastFocusingOptimizer';
10
10
  import { SharedProps, Item } from '../types';
11
+ import { MouseNavigation as IMouseNavigation } from './interface';
11
12
 
12
13
  export type Props<T extends Item<U>, U> = Omit<SharedProps<T, U>, 'scrollStep'> & {
13
14
  forward: () => boolean,
@@ -21,7 +22,6 @@ export type Props<T extends Item<U>, U> = Omit<SharedProps<T, U>, 'scrollStep'>
21
22
  adjustFocusFromTarget?: (itemRefIndex: number, groupRefIndex: number) => void,
22
23
  horizontal?: boolean,
23
24
  limit?: number,
24
- mrcuRef?: Reference<MouseNavigation>;
25
25
  shouldApplySlowdown?: () => boolean,
26
26
  };
27
27
 
@@ -55,6 +55,8 @@ export class GridBase<T extends Item<U>, U>
55
55
 
56
56
  scrollerDom = createRef<HTMLDivElement>();
57
57
 
58
+ mrcuRef = createRef<IMouseNavigation>();
59
+
58
60
  itemRefs: Reference<T>[] = [];
59
61
 
60
62
  groupRefs: Reference<HTMLDivElement>[] = [];
@@ -151,14 +153,13 @@ export class GridBase<T extends Item<U>, U>
151
153
  onWheel = (event: WheelEvent) => {
152
154
  const {
153
155
  forwardGroup, backwardGroup, shouldApplySlowdown,
154
- mrcuRef,
155
156
  } = this.props;
156
157
  let processed;
157
158
  if (event.deltaY > 0) processed = shouldApplySlowdown() || forwardGroup();
158
159
  else if (event.deltaY < 0) processed = shouldApplySlowdown() || backwardGroup();
159
160
  if (processed) {
160
161
  stopEvent(event);
161
- mrcuRef?.current?.handleArrowState();
162
+ this.mrcuRef.current?.handleArrowState();
162
163
  if (this.fastScrollingCounter) {
163
164
  this.fastScrollingCounter.add();
164
165
  this.fakeWheelStop();
@@ -434,7 +435,15 @@ export class GridBase<T extends Item<U>, U>
434
435
  }
435
436
 
436
437
  render() {
437
- const { horizontal, className } = this.props;
438
+ const {
439
+ horizontal,
440
+ className,
441
+ forwardGroup,
442
+ backwardGroup,
443
+ shouldShowMrcuForward,
444
+ shouldShowMrcuBackward,
445
+ } = this.props;
446
+
438
447
  return (
439
448
  <Scroller
440
449
  className={className}
@@ -443,7 +452,17 @@ export class GridBase<T extends Item<U>, U>
443
452
  onKeyDown={this.onKeyDown}
444
453
  horizontal={horizontal}
445
454
  >
446
- {this.renderData()}
455
+ <>{this.renderData()}</>
456
+ <MouseNavigation
457
+ // @ts-ignore - needed to convert fallback (false) to interface
458
+ ref={this.mrcuRef}
459
+ getMountingPoint={() => this.scroller.current!.wrapRef}
460
+ horizontal={horizontal}
461
+ forward={forwardGroup}
462
+ backward={backwardGroup}
463
+ shouldShowMrcuForward={shouldShowMrcuForward}
464
+ shouldShowMrcuBackward={shouldShowMrcuBackward}
465
+ />
447
466
  </Scroller>
448
467
  );
449
468
  }
@@ -0,0 +1,58 @@
1
+ import { Component, createRef } from '@24i/bigscreen-sdk/jsx';
2
+ import { MouseNavigation as MouseNavigationBase } from '@24i/bigscreen-sdk/mouse-navigation';
3
+ import { device } from '@24i/bigscreen-sdk/device';
4
+ import {
5
+ MouseNavigationProps as Props,
6
+ MouseNavigation as IMouseNavigation,
7
+ } from '../interface';
8
+
9
+ export class MouseNavigation extends Component<Props> implements IMouseNavigation {
10
+ private readonly div = createRef<HTMLDivElement>();
11
+
12
+ private readonly base = createRef<MouseNavigationBase>();
13
+
14
+ componentDidMount() {
15
+ if (device.isMouseUsed()) {
16
+ this.renderArrows();
17
+ }
18
+ }
19
+
20
+ handleArrowState() {
21
+ this.base?.current?.handleArrowState();
22
+ }
23
+
24
+ renderArrows() {
25
+ const {
26
+ horizontal,
27
+ forward,
28
+ backward,
29
+ shouldShowMrcuForward,
30
+ shouldShowMrcuBackward,
31
+ getMountingPoint,
32
+ } = this.props;
33
+
34
+ const direction = horizontal ? 'horizontal' : 'vertical';
35
+
36
+ this.appendMount(
37
+ <div ref={this.div} className="mouse-navigation">
38
+ <MouseNavigationBase
39
+ // @ts-ignore - needed to convert fallback (false) to interface
40
+ ref={this.base}
41
+ getMountingPoint={() => this.div}
42
+ direction={direction}
43
+ forward={forward}
44
+ backward={backward}
45
+ shouldShowMrcuForward={shouldShowMrcuForward}
46
+ shouldShowMrcuBackward={shouldShowMrcuBackward}
47
+ >
48
+ {null as unknown as JSX.Element}
49
+ </MouseNavigationBase>
50
+ </div>,
51
+ getMountingPoint(),
52
+ );
53
+ }
54
+
55
+ render() {
56
+ return null;
57
+ }
58
+ }
@@ -0,0 +1,4 @@
1
+ import { MouseNavigationProps as Props } from '../interface';
2
+
3
+ // eslint-disable-next-line @typescript-eslint/no-unused-vars
4
+ export const MouseNavigation = (props: Props) => false as unknown as JSX.Element;
@@ -0,0 +1 @@
1
+ export { MouseNavigation } from './MouseNavigation';
@@ -0,0 +1 @@
1
+ export { MouseNavigation } from './MouseNavigationFallback';
@@ -0,0 +1 @@
1
+ export { MouseNavigation } from './MouseNavigation';
@@ -0,0 +1 @@
1
+ export { MouseNavigation } from './MouseNavigation';
@@ -0,0 +1,47 @@
1
+ import { Reference, Component } from '@24i/bigscreen-sdk/jsx';
2
+
3
+ export type MouseNavigationProps = {
4
+ /**
5
+ * Function to call on the press of the right arrow.
6
+ */
7
+ forward(): boolean,
8
+ /**
9
+ * Function to call on the press of the left arrow.
10
+ */
11
+ backward(): boolean,
12
+ /**
13
+ * Function to call on the press of the down arrow.
14
+ */
15
+ forwardGroup?(): boolean,
16
+ /**
17
+ * Function to call on the press of the up arrow.
18
+ */
19
+ backwardGroup?(): boolean,
20
+ /**
21
+ * Function which determines whether to show the forward arrow.
22
+ */
23
+ shouldShowMrcuForward?(): boolean,
24
+ /**
25
+ * Function which determines whether to show the backward arrow.
26
+ */
27
+ shouldShowMrcuBackward?(): boolean,
28
+ /**
29
+ * Returns a reference to the element where your `children` should be rendered.
30
+ */
31
+ getMountingPoint(): Reference<HTMLElement>;
32
+ /**
33
+ * Property determines whether navigation is horizontal.
34
+ */
35
+ horizontal?: boolean,
36
+ };
37
+
38
+ export interface MouseNavigation extends Component<MouseNavigationProps> {
39
+ /**
40
+ * Function to disable showing an arrow in the given direction.
41
+ */
42
+ handleArrowState(): void,
43
+ }
44
+
45
+ export interface MouseNavigationComponent {
46
+ new (props: MouseNavigationProps): MouseNavigation,
47
+ }
@@ -295,6 +295,8 @@ export class UnifiedGridController<T> implements IUnifiedGridController<T> {
295
295
  }
296
296
 
297
297
  focusToIndex(dataIndex: number, animate = false) {
298
+ const { grid } = this;
299
+ const base = grid.base.current!;
298
300
  const targetScrollIndex = this.itemIndexToScrollIndex(dataIndex);
299
301
  if (targetScrollIndex > this.scrollIndex) {
300
302
  this.adjustGroupsOffsetsForward(targetScrollIndex);
@@ -304,8 +306,9 @@ export class UnifiedGridController<T> implements IUnifiedGridController<T> {
304
306
  if (targetScrollIndex !== this.scrollIndex) {
305
307
  this.scroll(targetScrollIndex, animate);
306
308
  }
307
- this.grid.base.current!.index = dataIndex;
309
+ base.index = dataIndex;
308
310
  this.focusCurrentItem();
311
+ base.mrcuRef.current?.handleArrowState();
309
312
  }
310
313
 
311
314
  protected focusScrollWrap() {