@24i/bigscreen-sdk 1.0.4 → 1.0.5-4.alpha-2832
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.
- package/README.md +2 -3
- package/ci/is_ci_job_skippable.sh +153 -0
- package/package.json +55 -34
- package/packages/adobe-heartbeat/src/AdobeHeartbeat.ts +9 -9
- package/packages/analytics/README.md +8 -0
- package/packages/analytics/src/A.ts +1 -0
- package/packages/analytics/src/Analytics.ts +1 -0
- package/packages/analytics/src/analyticsOnScroll.ts +1 -0
- package/packages/analytics/src/clients/ConsoleAnalytics/ConsoleAnalytics.ts +1 -0
- package/packages/analytics/src/clients/ConsoleAnalytics/index.ts +1 -0
- package/packages/analytics/src/clients/GoogleAnalytics/GoogleAnalytics.ts +196 -0
- package/packages/analytics/src/clients/GoogleAnalytics/constants.ts +126 -0
- package/packages/analytics/src/clients/GoogleAnalytics/getUrl.ts +17 -0
- package/packages/analytics/src/clients/GoogleAnalytics/index.ts +2 -0
- package/packages/analytics/src/clients/GoogleAnalytics/interface.ts +82 -0
- package/packages/analytics/src/clients/GoogleAnalytics/mapPayload.ts +51 -0
- package/packages/analytics/src/clients/GoogleAnalytics/prepareBody.ts +14 -0
- package/packages/analytics/src/clients/TealiumAnalytics/TealiumAnalytics.ts +181 -0
- package/packages/analytics/src/clients/TealiumAnalytics/constants.ts +106 -0
- package/packages/analytics/src/clients/TealiumAnalytics/findForLanguage.ts +9 -0
- package/packages/analytics/src/clients/TealiumAnalytics/index.ts +4 -0
- package/packages/analytics/src/clients/TealiumAnalytics/interface.ts +35 -0
- package/packages/analytics/src/clients/TealiumAnalytics/mappers/__mocks__/mediaPayload.ts +72 -0
- package/packages/analytics/src/clients/TealiumAnalytics/mappers/helper.ts +36 -0
- package/packages/analytics/src/clients/TealiumAnalytics/mappers/mapAppError.ts +13 -0
- package/packages/analytics/src/clients/TealiumAnalytics/mappers/mapAppOpen.ts +13 -0
- package/packages/analytics/src/clients/TealiumAnalytics/mappers/mapFavoriteAdd.ts +11 -0
- package/packages/analytics/src/clients/TealiumAnalytics/mappers/mapFavoriteRemove.ts +11 -0
- package/packages/analytics/src/clients/TealiumAnalytics/mappers/mapPlayerClose.ts +15 -0
- package/packages/analytics/src/clients/TealiumAnalytics/mappers/mapPlayerOpen.ts +15 -0
- package/packages/analytics/src/clients/TealiumAnalytics/mappers/mapSceneView.ts +18 -0
- package/packages/analytics/src/clients/TealiumAnalytics/mappers/mapSearch.ts +18 -0
- package/packages/analytics/src/clients/TealiumAnalytics/mappers/mapSearchFailed.ts +8 -0
- package/packages/analytics/src/clients/TealiumAnalytics/mappers/mapSearchSuccess.ts +8 -0
- package/packages/analytics/src/clients/TealiumAnalytics/mappers/mapVideoPause.ts +15 -0
- package/packages/analytics/src/clients/TealiumAnalytics/mappers/mapVideoProgress.ts +18 -0
- package/packages/analytics/src/clients/TealiumAnalytics/mappers/mapVideoResume.ts +15 -0
- package/packages/analytics/src/clients/TealiumAnalytics/mappers/mapVideoStart.ts +15 -0
- package/packages/analytics/src/clients/TealiumAnalytics/mappers/mapVideoStop.ts +15 -0
- package/packages/analytics/src/clients/TealiumAnalytics/types.ts +161 -0
- package/packages/analytics/src/clients/TwentyFourIQ/TwentyFourIQClient.ts +107 -0
- package/packages/analytics/src/clients/TwentyFourIQ/constants.ts +111 -0
- package/packages/analytics/src/clients/TwentyFourIQ/helper.ts +34 -0
- package/packages/analytics/src/clients/TwentyFourIQ/index.ts +2 -0
- package/packages/analytics/src/clients/TwentyFourIQ/interface.ts +34 -0
- package/packages/analytics/src/clients/TwentyFourIQ/mappers/mapAdEvent.ts +20 -0
- package/packages/analytics/src/clients/TwentyFourIQ/mappers/mapBase.ts +24 -0
- package/packages/analytics/src/clients/TwentyFourIQ/mappers/mapBuffering.ts +15 -0
- package/packages/analytics/src/clients/TwentyFourIQ/mappers/mapPlayerClose.ts +25 -0
- package/packages/analytics/src/clients/TwentyFourIQ/mappers/mapPlayerOpen.ts +17 -0
- package/packages/analytics/src/clients/TwentyFourIQ/mappers/mapSceneView.ts +15 -0
- package/packages/analytics/src/clients/TwentyFourIQ/mappers/mapScroll.ts +17 -0
- package/packages/analytics/src/clients/TwentyFourIQ/mappers/mapVideoComplete.ts +22 -0
- package/packages/analytics/src/clients/TwentyFourIQ/mappers/mapVideoPause.ts +25 -0
- package/packages/analytics/src/clients/TwentyFourIQ/mappers/mapVideoProgress.ts +25 -0
- package/packages/analytics/src/clients/TwentyFourIQ/mappers/mapVideoStart.ts +34 -0
- package/packages/analytics/src/clients/TwentyFourIQ/mappers/mapVideoStop.ts +32 -0
- package/packages/analytics/src/clients/TwentyFourIQ/types.ts +132 -0
- package/packages/analytics/src/constants.ts +1 -0
- package/packages/analytics/src/index.ts +3 -0
- package/packages/analytics/src/interface.ts +1 -0
- package/packages/analytics/src/utils/generateSessionId.ts +8 -0
- package/packages/async-image/src/AsyncImage.tsx +15 -10
- package/packages/developer-tools/PlayerDebugWindow/README.md +1 -1
- package/packages/developer-tools/src/DeveloperConsole/DeveloperConsole.tsx +1 -0
- package/packages/developer-tools/src/DeveloperToolsService/DeveloperToolsList.tsx +11 -0
- package/packages/developer-tools/src/PlayerDebugWindow/PlayerDebugWindow.tsx +5 -5
- package/packages/developer-tools/src/PlayerDebugWindow/constants.ts +15 -0
- package/packages/developer-tools/src/TechnicalInfo/TechnicalInfo.tsx +2 -0
- package/packages/developer-tools/src/TechnicalInfo/TechnicalInfoDetail.tsx +2 -1
- package/packages/developer-tools/src/TechnicalInfo/TechnicalInfoProvider.ts +57 -5
- package/packages/developer-tools/src/TechnicalInfo/__mocks__/Device.ts +12 -0
- package/packages/developer-tools/src/TechnicalInfo/translations.ts +8 -0
- package/packages/device/src/driver/index.android.tv.ts +1 -0
- package/packages/device/src/driver/index.firetv.ts +1 -0
- package/packages/device/src/driver/index.smartcast.tv.ts +1 -0
- package/packages/device/src/getKeyDigit.ts +2 -2
- package/packages/device/src/resolver/resolver.ts +19 -0
- package/packages/digital-clock/src/DigitalClock.tsx +15 -4
- package/packages/driver-androidtv/src/DeviceAndroidTV.ts +262 -0
- package/packages/driver-androidtv/src/__mocks__/javaScriptBridge.ts +45 -0
- package/packages/driver-androidtv/src/formatUserAgent.ts +11 -0
- package/packages/driver-androidtv/src/index.ts +2 -0
- package/packages/driver-androidtv/src/keymap.ts +27 -0
- package/packages/driver-androidtv/src/types.ts +155 -0
- package/packages/driver-base/src/DeviceBase.ts +73 -2
- package/packages/driver-base/src/KeyMap/Key.ts +8 -1
- package/packages/driver-base/src/KeyMap/KeyMap.ts +4 -0
- package/packages/driver-base/src/KeyMap/interface.ts +1 -0
- package/packages/driver-base/src/KeyMap/overrideValues.ts +2 -1
- package/packages/driver-base/src/__mocks__/DeviceBase.ts +24 -0
- package/packages/driver-base/src/__mocks__/keyMap.ts +1 -0
- package/packages/driver-base/src/index.ts +3 -0
- package/packages/driver-base/src/types/AdInfo.ts +5 -0
- package/packages/driver-base/src/types/DeviceEvent.ts +2 -0
- package/packages/driver-base/src/types/InAppPurchase.ts +20 -0
- package/packages/driver-base/src/types/KeycodeKeyMap.ts +1 -0
- package/packages/driver-browser/src/DeviceBrowser.ts +26 -0
- package/packages/driver-browser/src/keymap.ts +8 -0
- package/packages/driver-entone/src/DeviceEntone.ts +31 -1
- package/packages/driver-entone/src/keymap.ts +1 -0
- package/packages/driver-firetv/src/DeviceFireTV.ts +86 -0
- package/packages/driver-firetv/src/__mocks__/javaScriptBridge.ts +45 -0
- package/packages/driver-firetv/src/index.ts +1 -0
- package/packages/driver-firetv/src/types.ts +1 -0
- package/packages/driver-hbbtv/src/DeviceHbbTV.ts +26 -0
- package/packages/driver-kreatv/src/DeviceKreaTV.ts +26 -0
- package/packages/driver-saphi/src/DeviceSaphi.ts +26 -0
- package/packages/driver-smartcast/src/DeviceSmartCast.ts +380 -0
- package/packages/driver-smartcast/src/__mocks__/api.ts +69 -0
- package/packages/driver-smartcast/src/index.ts +1 -0
- package/packages/driver-smartcast/src/keymap.ts +9 -0
- package/packages/driver-smartcast/src/types.ts +102 -0
- package/packages/driver-tizen/src/DeviceTizen.ts +121 -7
- package/packages/driver-tizen/src/ITizen.ts +15116 -202
- package/packages/driver-tizen/src/IWebapis.ts +8643 -87
- package/packages/driver-tizen/src/TizenKeys.ts +4 -2
- package/packages/driver-tizen/src/__mocks__/tizen.ts +7 -8
- package/packages/driver-tizen/src/constants.ts +1 -195
- package/packages/driver-vidaa/src/DeviceVidaa.ts +29 -2
- package/packages/driver-vidaa/src/__mocks__/vidaa.ts +1 -1
- package/packages/driver-vidaa/src/keymap.ts +2 -0
- package/packages/driver-webos/src/DeviceWebos.ts +55 -0
- package/packages/driver-webos/src/__mocks__/webos.ts +33 -0
- package/packages/driver-webos/src/constants.ts +1 -0
- package/packages/driver-webos/src/keymap.ts +2 -1
- package/packages/driver-webos/src/types.ts +30 -0
- package/packages/driver-xbox/src/DeviceXbox.ts +30 -1
- package/packages/driver-xbox/src/keymap.ts +1 -1
- package/packages/epg/README.md +3 -1
- package/packages/epg/src/v2/Cell.tsx +16 -2
- package/packages/epg/src/v2/DataManager.ts +112 -41
- package/packages/epg/src/v2/DatePicker.tsx +9 -3
- package/packages/epg/src/v2/DateToast/DateToast.tsx +12 -9
- package/packages/epg/src/v2/Day.tsx +6 -3
- package/packages/epg/src/v2/Epg.tsx +5 -5
- package/packages/epg/src/v2/MockGenerator/generator.ts +3 -2
- package/packages/epg/src/v2/ProgramInfo/utils.ts +4 -3
- package/packages/epg/src/v2/Row.tsx +3 -1
- package/packages/epg/src/v2/TimelineSection.tsx +4 -1
- package/packages/epg/src/v2/basic/CellsManager.tsx +7 -2
- package/packages/epg/src/v2/basic/RowsManager.tsx +3 -1
- package/packages/epg/src/v2/interface.ts +13 -0
- package/packages/events-manager/src/EventsManager.ts +1 -56
- package/packages/focus/README.md +33 -0
- package/packages/focus/src/IFocusable.ts +1 -0
- package/packages/focus/src/Layout/Base.tsx +41 -6
- package/packages/focus/src/Layout/Matrix.tsx +51 -19
- package/packages/focus/src/focusFirstExisting.ts +7 -1
- package/packages/focus/src/hasFocus.ts +36 -0
- package/packages/focus/src/index.ts +2 -1
- package/packages/gallup/src/Gallup.ts +3 -3
- package/packages/grid/src/Base/Base.tsx +15 -10
- package/packages/grid/src/FirstOnlyGrid/FirstOnlyGrid.tsx +4 -2
- package/packages/grid/src/UnifiedGridController/UnifiedGridController.ts +6 -6
- package/packages/icon/src/Icon.tsx +27 -5
- package/packages/input/README.md +1 -1
- package/packages/input/src/Input.tsx +10 -10
- package/packages/interactable/README.md +2 -1
- package/packages/interactable/src/Interactable.tsx +9 -3
- package/packages/interactable/src/interface.ts +1 -0
- package/packages/jsx/src/index.ts +1 -1
- package/packages/jsx/src/test-utils/index.ts +1 -0
- package/packages/jsx/src/test-utils/keyup.ts +27 -0
- package/packages/keyboard/README.md +2 -0
- package/packages/keyboard/src/Backdrop/Backdrop.scss +2 -0
- package/packages/keyboard/src/KeyboardBase.tsx +16 -4
- package/packages/keyboard/src/WhitelabelKeyboard/Keyboard.scss +10 -0
- package/packages/keyboard/src/WhitelabelKeyboard/Keyboard.tsx +128 -142
- package/packages/keyboard/src/WhitelabelKeyboard/WhitelabelStyles/whitelabel.scss +4 -0
- package/packages/keyboard/src/WhitelabelKeyboard/_sizes.1080.scss +1 -0
- package/packages/keyboard/src/WhitelabelKeyboard/_sizes.scss +1 -0
- package/packages/keyboard/src/WhitelabelKeyboard/icons/key_language.svg +20 -0
- package/packages/keyboard/src/WhitelabelKeyboard/index.ts +1 -1
- package/packages/keyboard/src/WhitelabelKeyboard/layouts/arabic.ts +27 -0
- package/packages/keyboard/src/WhitelabelKeyboard/layouts/burmese.ts +27 -0
- package/packages/keyboard/src/WhitelabelKeyboard/layouts/dari.ts +28 -0
- package/packages/keyboard/src/WhitelabelKeyboard/layouts/hebrew.ts +28 -0
- package/packages/keyboard/src/WhitelabelKeyboard/layouts/index.ts +15 -0
- package/packages/keyboard/src/WhitelabelKeyboard/layouts/korean.ts +26 -0
- package/packages/keyboard/src/WhitelabelKeyboard/layouts/latin.ts +26 -0
- package/packages/keyboard/src/WhitelabelKeyboard/layouts/pashto.ts +27 -0
- package/packages/keyboard/src/WhitelabelKeyboard/layouts/persian.ts +27 -0
- package/packages/keyboard/src/WhitelabelKeyboard/layouts/russian.ts +27 -0
- package/packages/keyboard/src/WhitelabelKeyboard/layouts/spanish.ts +26 -0
- package/packages/keyboard/src/WhitelabelKeyboard/layouts/special.ts +28 -0
- package/packages/keyboard/src/WhitelabelKeyboard/layouts/tibetan.ts +26 -0
- package/packages/keyboard/src/WhitelabelKeyboard/layouts/turkish.ts +26 -0
- package/packages/keyboard/src/WhitelabelKeyboard/layouts/ukrainian.ts +27 -0
- package/packages/keyboard/src/WhitelabelKeyboard/layouts/urdu.ts +26 -0
- package/packages/keyboard/src/WhitelabelKeyboard/types.ts +22 -2
- package/packages/keyboard/src/types/index.ts +1 -1
- package/packages/keyboard/src/utils/caret.ts +5 -8
- package/packages/keyboard/src/utils/input.ts +5 -6
- package/packages/keyboard/src/utils/setInputSelectionRange.ts +10 -0
- package/packages/l10n/README.md +18 -0
- package/packages/l10n/src/date/common.ts +18 -6
- package/packages/l10n/src/date/cs.ts +2 -8
- package/packages/l10n/src/date/de.ts +97 -0
- package/packages/l10n/src/date/en-001.ts +3 -3
- package/packages/l10n/src/date/en-common.ts +5 -4
- package/packages/l10n/src/date/en-us.ts +3 -3
- package/packages/l10n/src/date/es.ts +71 -0
- package/packages/l10n/src/date/fr.ts +94 -0
- package/packages/l10n/src/date/he.ts +101 -0
- package/packages/l10n/src/date/iso.ts +12 -13
- package/packages/l10n/src/date/types.ts +9 -0
- package/packages/l10n/src/l10n.ts +61 -3
- package/packages/list/src/Base/Base.tsx +19 -9
- package/packages/list/src/Base/interface.ts +2 -2
- package/packages/list/src/BasicList/BasicList.tsx +7 -7
- package/packages/list/src/CenteredList/CenteredList.tsx +2 -2
- package/packages/list/src/CenteredList/controller.ts +0 -1
- package/packages/list/src/EdgeOffsetList/EdgeOffsetList.tsx +10 -10
- package/packages/list/src/FirstOnlyList/FirstOnlyList.tsx +2 -2
- package/packages/list/src/FirstOnlyVariedList/FirstOnlyVariedList.tsx +2 -2
- package/packages/list/src/FixedToEndList/FixedToEndList.tsx +2 -2
- package/packages/list/src/UnifiedListController/UnifiedListController.ts +6 -2
- package/packages/list/src/interface.ts +2 -2
- package/packages/logger/src/loggers/ConsoleLogger/ConsoleLogger.ts +7 -1
- package/packages/logger/src/loggers/SentryLogger/Sentry.ts +1 -0
- package/packages/logger/src/loggers/SentryLogger/SentryLogger.ts +5 -3
- package/packages/menu/src/MenuAndContentContainer/MenuAndContentContainer.tsx +31 -3
- package/packages/menu/src/MenuAndContentContainer/interface.ts +8 -0
- package/packages/modal-service/README.md +4 -1
- package/packages/modal-service/src/ModalService.tsx +29 -5
- package/packages/perf-utils/README.md +1 -120
- package/packages/perf-utils/src/array/filter.ts +1 -54
- package/packages/perf-utils/src/array/find.ts +1 -43
- package/packages/perf-utils/src/array/findIndex.ts +1 -43
- package/packages/perf-utils/src/array/forEach.ts +1 -48
- package/packages/perf-utils/src/array/includes.ts +1 -41
- package/packages/perf-utils/src/array/includesNaN.ts +1 -32
- package/packages/perf-utils/src/array/index.ts +1 -7
- package/packages/perf-utils/src/array/map.ts +1 -52
- package/packages/player-ui/README.md +1 -1
- package/packages/player-ui/src/CurrentTime.tsx +2 -2
- package/packages/player-ui/src/Duration.tsx +2 -2
- package/packages/player-ui/src/PauseButton.tsx +8 -0
- package/packages/player-ui/src/PlayerInteractable.tsx +1 -0
- package/packages/player-ui/src/PlayerTime.tsx +3 -1
- package/packages/player-ui/src/PlayerUI.tsx +68 -35
- package/packages/player-ui/src/RemainingTime.tsx +2 -2
- package/packages/player-ui/src/Seekbar.tsx +110 -18
- package/packages/player-ui/src/Seeking.ts +57 -16
- package/packages/player-ui/src/Subtitles.tsx +2 -2
- package/packages/player-ui/src/index.ts +1 -0
- package/packages/player-ui/src/mocks.ts +32 -8
- package/packages/player-ui/src/timeUtils.ts +3 -3
- package/packages/player-ui/src/types.ts +9 -3
- package/packages/router/README.md +1 -0
- package/packages/router/src/Route.tsx +61 -27
- package/packages/router/src/Router.tsx +63 -14
- package/packages/router/src/history.ts +8 -1
- package/packages/router/src/index.ts +1 -1
- package/packages/router/src/utils.ts +9 -4
- package/packages/sass-utils/src/linear-gradient.scss +9 -4
- package/packages/sass-utils/src/scale.1080.scss +3 -1
- package/packages/sass-utils/src/scale.720.scss +1 -1
- package/packages/time/README.md +4 -1
- package/packages/time/src/Time.ts +35 -13
- package/packages/time/src/adapters/24iMediaTimeApi.ts +47 -0
- package/packages/time/src/constants.ts +1 -0
- package/packages/time/src/services/24iMediaTimeApi/24iMediaTimeApi.ts +43 -0
- package/packages/time/src/services/24iMediaTimeApi/index.ts +6 -0
- package/packages/toast/src/ToastService.scss +1 -0
- package/packages/toast/src/ToastService.tsx +16 -5
- package/packages/types-bigscreen-jsx/README.md +5 -4
- package/packages/types-bigscreen-jsx/index.d.ts +72 -67
- package/packages/utils/README.md +27 -0
- package/packages/utils/src/elementUtils.ts +25 -0
- package/packages/utils/src/forceReflow.ts +14 -0
- package/packages/utils/src/index.ts +8 -0
- package/packages/utils/src/keyPress/index.ts +6 -0
- package/packages/utils/src/keyPress/keyPressSimulator.ts +74 -0
- package/packages/utils/src/keyPress/simulateKeyPress.ts +25 -0
- package/packages/utils/src/scaledImage.ts +6 -3
- package/packages/utils/src/textUtils.ts +46 -14
- package/packages/utils/src/wait.ts +3 -1
- package/packages/utils/src/xhr/xhrSend.ts +3 -1
- package/packages/utils/src/xhr/xhrSendRetry.ts +3 -1
- package/packages/zapping/src/ChannelZapping.ts +9 -0
- package/packages/zapping/src/Zapping.tsx +10 -0
- package/utils/release/release.ts +156 -0
- package/packages/driver-tizen/src/types.ts +0 -14
- package/packages/focus/src/Layout/__test__/Base.spec.ts +0 -180
- package/packages/focus/src/Layout/__test__/Horizontal.spec.ts +0 -94
- package/packages/focus/src/Layout/__test__/Matrix.spec.ts +0 -261
- package/packages/focus/src/Layout/__test__/Vertical.spec.ts +0 -46
- package/packages/focus/src/Layout/__test__/isRtl.spec.ts +0 -23
- package/packages/focus/src/Layout/__test__/shared.ts +0 -19
- package/packages/keyboard/src/WhitelabelKeyboard/focusMatrix.ts +0 -19
|
@@ -1,14 +1,22 @@
|
|
|
1
1
|
import { Component, DeclareProps, Reference } from '@24i/bigscreen-sdk/jsx';
|
|
2
2
|
import { noop } from '@24i/bigscreen-sdk/utils/noop';
|
|
3
|
+
import { stopEvent } from '@24i/bigscreen-sdk/utils/stopEvent';
|
|
3
4
|
import { IFocusable } from '../IFocusable';
|
|
4
5
|
import { Errors, hasValidDomRef } from './constants';
|
|
5
6
|
import { SharedProps } from './types';
|
|
6
7
|
|
|
8
|
+
const PREVENT_BLUR_ON_LONG_PRESS_KEYDOWNS = 2;
|
|
9
|
+
|
|
7
10
|
export type Props = SharedProps & {
|
|
8
11
|
focusOptions?: FocusOptions;
|
|
9
12
|
focusableChildren: Array<Reference>,
|
|
10
13
|
onFocusChanged?: (focused: Reference, index: number) => any,
|
|
11
14
|
onBeforeFocusChange?: (focused: Reference, index: number) => any,
|
|
15
|
+
circular?: boolean,
|
|
16
|
+
preventBlurOnLongPress?: {
|
|
17
|
+
forward?: boolean,
|
|
18
|
+
backward?: boolean,
|
|
19
|
+
}
|
|
12
20
|
};
|
|
13
21
|
|
|
14
22
|
export interface ILayout {
|
|
@@ -25,12 +33,16 @@ export const getLayoutBase = (onKeyDown: (event: KeyboardEvent, layout: ILayout)
|
|
|
25
33
|
class Layout extends Component<Props> implements ILayout, IFocusable {
|
|
26
34
|
index = 0;
|
|
27
35
|
|
|
36
|
+
preventBlurCounter = 0;
|
|
37
|
+
|
|
28
38
|
static defaultProps = {
|
|
29
39
|
onFocusChanged: noop,
|
|
30
40
|
onBeforeFocusChange: noop,
|
|
31
41
|
focusOptions: { preventScroll: true },
|
|
32
42
|
dir: 'auto',
|
|
33
|
-
|
|
43
|
+
circular: false,
|
|
44
|
+
preventBlurOnLongPress: {},
|
|
45
|
+
} as const;
|
|
34
46
|
|
|
35
47
|
declare props: DeclareProps<Props, typeof Layout.defaultProps>;
|
|
36
48
|
|
|
@@ -40,6 +52,7 @@ export const getLayoutBase = (onKeyDown: (event: KeyboardEvent, layout: ILayout)
|
|
|
40
52
|
throw new Error(Errors.DOM_REF_ERROR);
|
|
41
53
|
}
|
|
42
54
|
domRef.current!.addEventListener('keydown', this.onKeyDown, false);
|
|
55
|
+
window.document.addEventListener('keyup', this.onGlobalKeyUp, true);
|
|
43
56
|
}
|
|
44
57
|
|
|
45
58
|
componentWillUnmount() {
|
|
@@ -48,12 +61,17 @@ export const getLayoutBase = (onKeyDown: (event: KeyboardEvent, layout: ILayout)
|
|
|
48
61
|
throw new Error(Errors.DOM_REF_ERROR);
|
|
49
62
|
}
|
|
50
63
|
domRef.current!.removeEventListener('keydown', this.onKeyDown, false);
|
|
64
|
+
window.document.removeEventListener('keyup', this.onGlobalKeyUp, true);
|
|
51
65
|
}
|
|
52
66
|
|
|
53
67
|
onKeyDown = (e: KeyboardEvent) => {
|
|
54
68
|
onKeyDown(e, this);
|
|
55
69
|
};
|
|
56
70
|
|
|
71
|
+
onGlobalKeyUp = () => {
|
|
72
|
+
this.preventBlurCounter = 0;
|
|
73
|
+
};
|
|
74
|
+
|
|
57
75
|
getFromIndex(target: HTMLElement) {
|
|
58
76
|
const { focusableChildren } = this.props;
|
|
59
77
|
if (
|
|
@@ -78,25 +96,42 @@ export const getLayoutBase = (onKeyDown: (event: KeyboardEvent, layout: ILayout)
|
|
|
78
96
|
}
|
|
79
97
|
|
|
80
98
|
backward(e: KeyboardEvent) {
|
|
99
|
+
const { focusableChildren, preventBlurOnLongPress, circular } = this.props;
|
|
81
100
|
const { target } = e;
|
|
82
101
|
const fromIndex = this.getFromIndex(target as HTMLElement);
|
|
102
|
+
if (preventBlurOnLongPress.backward) {
|
|
103
|
+
this.preventBlurCounter += 1;
|
|
104
|
+
}
|
|
83
105
|
if (fromIndex > 0) {
|
|
84
106
|
this.setIndex(fromIndex - 1);
|
|
85
107
|
this.focusCurrentIndex();
|
|
86
|
-
e
|
|
87
|
-
|
|
108
|
+
stopEvent(e);
|
|
109
|
+
} else if (circular) {
|
|
110
|
+
this.setIndex(focusableChildren.length - 1);
|
|
111
|
+
this.focusCurrentIndex();
|
|
112
|
+
stopEvent(e);
|
|
113
|
+
} else if (this.preventBlurCounter >= PREVENT_BLUR_ON_LONG_PRESS_KEYDOWNS) {
|
|
114
|
+
stopEvent(e);
|
|
88
115
|
}
|
|
89
116
|
}
|
|
90
117
|
|
|
91
118
|
forward(e: KeyboardEvent) {
|
|
92
|
-
const { focusableChildren } = this.props;
|
|
119
|
+
const { focusableChildren, preventBlurOnLongPress, circular } = this.props;
|
|
93
120
|
const { target } = e;
|
|
94
121
|
const fromIndex = this.getFromIndex(target as HTMLElement);
|
|
122
|
+
if (preventBlurOnLongPress.forward) {
|
|
123
|
+
this.preventBlurCounter += 1;
|
|
124
|
+
}
|
|
95
125
|
if (fromIndex < focusableChildren.length - 1) {
|
|
96
126
|
this.setIndex(fromIndex + 1);
|
|
97
127
|
this.focusCurrentIndex();
|
|
98
|
-
e
|
|
99
|
-
|
|
128
|
+
stopEvent(e);
|
|
129
|
+
} else if (circular) {
|
|
130
|
+
this.setIndex(0);
|
|
131
|
+
this.focusCurrentIndex();
|
|
132
|
+
stopEvent(e);
|
|
133
|
+
} else if (this.preventBlurCounter >= PREVENT_BLUR_ON_LONG_PRESS_KEYDOWNS) {
|
|
134
|
+
stopEvent(e);
|
|
100
135
|
}
|
|
101
136
|
}
|
|
102
137
|
|
|
@@ -8,6 +8,8 @@ import { isRtl } from './isRtl';
|
|
|
8
8
|
import { Errors, hasValidDomRef } from './constants';
|
|
9
9
|
import { SharedProps } from './types';
|
|
10
10
|
|
|
11
|
+
const PREVENT_BLUR_ON_LONG_PRESS_KEYDOWNS = 2;
|
|
12
|
+
|
|
11
13
|
// Used in binary operations for shorter checks
|
|
12
14
|
export enum CircularDirection {
|
|
13
15
|
NONE = 0,
|
|
@@ -21,7 +23,13 @@ export type Props = SharedProps & {
|
|
|
21
23
|
matrix: Array<Array<Reference>>,
|
|
22
24
|
onFocusChanged?: (focused: Reference, index: Index2D) => any,
|
|
23
25
|
onBeforeFocusChange?: (focused: Reference, index: Index2D) => any,
|
|
24
|
-
circular?: CircularDirection
|
|
26
|
+
circular?: CircularDirection,
|
|
27
|
+
preventBlurOnLongPress?: {
|
|
28
|
+
left?: boolean,
|
|
29
|
+
right?: boolean,
|
|
30
|
+
up?: boolean,
|
|
31
|
+
down?: boolean,
|
|
32
|
+
},
|
|
25
33
|
};
|
|
26
34
|
|
|
27
35
|
export type Index2D = {
|
|
@@ -32,11 +40,14 @@ export type Index2D = {
|
|
|
32
40
|
export class Matrix extends Component<Props> implements IFocusable {
|
|
33
41
|
index: Index2D = { x: 0, y: 0 };
|
|
34
42
|
|
|
43
|
+
preventBlurCounter = 0;
|
|
44
|
+
|
|
35
45
|
static defaultProps = {
|
|
36
46
|
onFocusChanged: noop,
|
|
37
47
|
onBeforeFocusChange: noop,
|
|
38
48
|
circular: CircularDirection.NONE,
|
|
39
49
|
dir: 'auto',
|
|
50
|
+
preventBlurOnLongPress: {},
|
|
40
51
|
} as const;
|
|
41
52
|
|
|
42
53
|
declare props: DeclareProps<Props, typeof Matrix.defaultProps>;
|
|
@@ -47,6 +58,7 @@ export class Matrix extends Component<Props> implements IFocusable {
|
|
|
47
58
|
throw new Error(Errors.DOM_REF_ERROR);
|
|
48
59
|
}
|
|
49
60
|
domRef.current!.addEventListener('keydown', this.onKeyDown, false);
|
|
61
|
+
window.document.addEventListener('keyup', this.onGlobalKeyUp, true);
|
|
50
62
|
}
|
|
51
63
|
|
|
52
64
|
componentWillUnmount() {
|
|
@@ -55,26 +67,46 @@ export class Matrix extends Component<Props> implements IFocusable {
|
|
|
55
67
|
throw new Error(Errors.DOM_REF_ERROR);
|
|
56
68
|
}
|
|
57
69
|
domRef.current!.removeEventListener('keydown', this.onKeyDown, false);
|
|
70
|
+
window.document.removeEventListener('keyup', this.onGlobalKeyUp, true);
|
|
58
71
|
}
|
|
59
72
|
|
|
60
73
|
onKeyDown = (e: KeyboardEvent) => {
|
|
74
|
+
const { preventBlurOnLongPress } = this.props;
|
|
61
75
|
let newIndex: Index2D | null = null;
|
|
62
76
|
if (this.isDirectionLeft(e)) {
|
|
63
77
|
newIndex = this.moveHorizontaly('left');
|
|
78
|
+
if (preventBlurOnLongPress.left) {
|
|
79
|
+
this.preventBlurCounter += 1;
|
|
80
|
+
}
|
|
64
81
|
} else if (this.isDirectionRight(e)) {
|
|
65
82
|
newIndex = this.moveHorizontaly('right');
|
|
83
|
+
if (preventBlurOnLongPress.right) {
|
|
84
|
+
this.preventBlurCounter += 1;
|
|
85
|
+
}
|
|
66
86
|
} else if (device.isDirectionUp(e)) {
|
|
67
87
|
newIndex = this.moveVerticaly('up');
|
|
88
|
+
if (preventBlurOnLongPress.up) {
|
|
89
|
+
this.preventBlurCounter += 1;
|
|
90
|
+
}
|
|
68
91
|
} else if (device.isDirectionDown(e)) {
|
|
69
92
|
newIndex = this.moveVerticaly('down');
|
|
93
|
+
if (preventBlurOnLongPress.down) {
|
|
94
|
+
this.preventBlurCounter += 1;
|
|
95
|
+
}
|
|
70
96
|
}
|
|
71
97
|
if (newIndex) {
|
|
72
98
|
stopEvent(e);
|
|
73
99
|
this.index = newIndex;
|
|
74
100
|
this.focusCurrentIndex();
|
|
101
|
+
} else if (this.preventBlurCounter >= PREVENT_BLUR_ON_LONG_PRESS_KEYDOWNS) {
|
|
102
|
+
stopEvent(e);
|
|
75
103
|
}
|
|
76
104
|
};
|
|
77
105
|
|
|
106
|
+
onGlobalKeyUp = () => {
|
|
107
|
+
this.preventBlurCounter = 0;
|
|
108
|
+
};
|
|
109
|
+
|
|
78
110
|
getRefAt({ x, y }: Index2D): Reference {
|
|
79
111
|
const { matrix } = this.props;
|
|
80
112
|
if (matrix[y] && matrix[y][x]) return matrix[y][x];
|
|
@@ -112,24 +144,6 @@ export class Matrix extends Component<Props> implements IFocusable {
|
|
|
112
144
|
return false;
|
|
113
145
|
}
|
|
114
146
|
|
|
115
|
-
isDirectionLeft(event: KeyboardEvent) {
|
|
116
|
-
const { dir } = this.props;
|
|
117
|
-
const rtl = isRtl(dir);
|
|
118
|
-
return (
|
|
119
|
-
(!rtl && LEFT.is(event))
|
|
120
|
-
|| (rtl && RIGHT.is(event))
|
|
121
|
-
);
|
|
122
|
-
}
|
|
123
|
-
|
|
124
|
-
isDirectionRight(event: KeyboardEvent) {
|
|
125
|
-
const { dir } = this.props;
|
|
126
|
-
const rtl = isRtl(dir);
|
|
127
|
-
return (
|
|
128
|
-
(!rtl && RIGHT.is(event))
|
|
129
|
-
|| (rtl && LEFT.is(event))
|
|
130
|
-
);
|
|
131
|
-
}
|
|
132
|
-
|
|
133
147
|
moveForwards = (isCircular: boolean) => (x: number, length: number) => {
|
|
134
148
|
if (x === length - 1) {
|
|
135
149
|
return isCircular ? 0 : length - 1;
|
|
@@ -172,6 +186,24 @@ export class Matrix extends Component<Props> implements IFocusable {
|
|
|
172
186
|
return this.searchVertical(column, fromY, this.moveForwards(!!isCircular));
|
|
173
187
|
};
|
|
174
188
|
|
|
189
|
+
isDirectionLeft(event: KeyboardEvent) {
|
|
190
|
+
const { dir } = this.props;
|
|
191
|
+
const rtl = isRtl(dir);
|
|
192
|
+
return (
|
|
193
|
+
(!rtl && LEFT.is(event))
|
|
194
|
+
|| (rtl && RIGHT.is(event))
|
|
195
|
+
);
|
|
196
|
+
}
|
|
197
|
+
|
|
198
|
+
isDirectionRight(event: KeyboardEvent) {
|
|
199
|
+
const { dir } = this.props;
|
|
200
|
+
const rtl = isRtl(dir);
|
|
201
|
+
return (
|
|
202
|
+
(!rtl && RIGHT.is(event))
|
|
203
|
+
|| (rtl && LEFT.is(event))
|
|
204
|
+
);
|
|
205
|
+
}
|
|
206
|
+
|
|
175
207
|
isDifferentReferenceFromCurrent(index: Index2D): boolean {
|
|
176
208
|
const { current } = this.getRefAt(this.index);
|
|
177
209
|
const { current: searched } = this.getRefAt(index);
|
|
@@ -1,6 +1,12 @@
|
|
|
1
|
-
import { Reference } from '@24i/bigscreen-sdk/jsx';
|
|
1
|
+
import { createRef, 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
|
+
|
|
4
10
|
export const focusFirstExisting = (...toFocus: Reference<IFocusable>[]) => (
|
|
5
11
|
() => {
|
|
6
12
|
for (let i = 0; i < toFocus.length; i++) {
|
|
@@ -0,0 +1,36 @@
|
|
|
1
|
+
import { Reference, unwrapReference } from '@24i/bigscreen-sdk/jsx';
|
|
2
|
+
import { isElementWrappedBy } from '@24i/bigscreen-sdk/utils/elementUtils';
|
|
3
|
+
|
|
4
|
+
/**
|
|
5
|
+
* Test if the element (or element in the reference) has the `activeElement` inside or optionally,
|
|
6
|
+
* if the element itself is the `activeElement`.
|
|
7
|
+
* @param elementOrReference DOM element or reference to element on which we test focus
|
|
8
|
+
* @param includeElementItself if true, active element is also tested with the provided element.
|
|
9
|
+
* Default is true
|
|
10
|
+
* @returns true if the element has focused element inside or is itself focused
|
|
11
|
+
*/
|
|
12
|
+
export const hasFocus = (
|
|
13
|
+
elementOrReference: HTMLElement | Reference<HTMLElement>,
|
|
14
|
+
includeElementItself = true,
|
|
15
|
+
) => {
|
|
16
|
+
const element = unwrapReference(elementOrReference);
|
|
17
|
+
if (!element) return false;
|
|
18
|
+
return isElementWrappedBy(
|
|
19
|
+
document.activeElement as HTMLElement,
|
|
20
|
+
element,
|
|
21
|
+
includeElementItself,
|
|
22
|
+
);
|
|
23
|
+
};
|
|
24
|
+
|
|
25
|
+
/**
|
|
26
|
+
* Test if the element (or element in the reference) is the `activeElement`.
|
|
27
|
+
* @param elementOrReference DOM element or reference to element on which we test focus
|
|
28
|
+
* @returns true if the element is focused
|
|
29
|
+
*/
|
|
30
|
+
export const isFocused = (
|
|
31
|
+
elementOrReference: HTMLElement | Reference<HTMLElement>,
|
|
32
|
+
) => {
|
|
33
|
+
const element = unwrapReference(elementOrReference);
|
|
34
|
+
if (!element) return false;
|
|
35
|
+
return document.activeElement === element;
|
|
36
|
+
};
|
|
@@ -11,5 +11,6 @@ export {
|
|
|
11
11
|
setNextFocusCandidate,
|
|
12
12
|
focusCandidate,
|
|
13
13
|
} from './candidate';
|
|
14
|
-
export { focusFirstExisting } from './focusFirstExisting';
|
|
14
|
+
export { focusFirstExisting, preventScrollOnFocus } from './focusFirstExisting';
|
|
15
15
|
export { refocusAfterHashChange } from './refocusAfterHashChange';
|
|
16
|
+
export { hasFocus, isFocused } from './hasFocus';
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { PlayerBase } from '@24i/
|
|
1
|
+
import { PlayerBase } from '@24i/bigscreen-players-engine-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,
|
|
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.
|
|
70
|
+
const { playerVersion } = player.mediaInfo;
|
|
71
71
|
return {
|
|
72
72
|
pl: playerName,
|
|
73
73
|
plv: playerVersion || '',
|
|
@@ -111,11 +111,13 @@ 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);
|
|
114
115
|
}
|
|
115
116
|
|
|
116
117
|
componentWillUnmount() {
|
|
117
118
|
this.scrollerDom.current!.removeEventListener('wheel', this.onWheel);
|
|
118
119
|
this.scroller.current!.wrapRef.current!.removeEventListener('keyup', this.onKeyUp);
|
|
120
|
+
window.document.removeEventListener('keyup', this.onGlobalKeyUp, true);
|
|
119
121
|
}
|
|
120
122
|
|
|
121
123
|
// eslint-disable-next-line sonarjs/cognitive-complexity
|
|
@@ -155,6 +157,9 @@ export class GridBase<T extends Item<U>, U>
|
|
|
155
157
|
onKeyUp = () => {
|
|
156
158
|
this.stopFastScrolling();
|
|
157
159
|
this.fastFocusingOptimizer.stop();
|
|
160
|
+
};
|
|
161
|
+
|
|
162
|
+
onGlobalKeyUp = () => {
|
|
158
163
|
this.preventBlurCounter = 0;
|
|
159
164
|
};
|
|
160
165
|
|
|
@@ -178,16 +183,6 @@ export class GridBase<T extends Item<U>, U>
|
|
|
178
183
|
}
|
|
179
184
|
};
|
|
180
185
|
|
|
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
|
-
|
|
191
186
|
getRefAtIndex(i: number): Reference<T> {
|
|
192
187
|
const ref = this.itemRefs[i];
|
|
193
188
|
if (!ref) {
|
|
@@ -253,6 +248,16 @@ export class GridBase<T extends Item<U>, U>
|
|
|
253
248
|
this.fastScrollingCounter.reset();
|
|
254
249
|
};
|
|
255
250
|
|
|
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
|
+
|
|
256
261
|
animatedScrollStarted() {
|
|
257
262
|
this.isAnimatedScrollRunning = true;
|
|
258
263
|
}
|
|
@@ -61,6 +61,8 @@ 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));
|
|
64
66
|
}
|
|
65
67
|
};
|
|
66
68
|
|
|
@@ -77,8 +79,8 @@ export class FirstOnlyGrid<T extends Item<U>, U>
|
|
|
77
79
|
this.controller.scroll(targetScrollIndex);
|
|
78
80
|
}
|
|
79
81
|
|
|
80
|
-
scrollBackward() {
|
|
81
|
-
const targetScrollIndex = this.controller.scrollIndex -
|
|
82
|
+
scrollBackward(diff = 1) {
|
|
83
|
+
const targetScrollIndex = this.controller.scrollIndex - diff;
|
|
82
84
|
this.controller.scroll(targetScrollIndex);
|
|
83
85
|
}
|
|
84
86
|
|
|
@@ -298,13 +298,13 @@ export class UnifiedGridController<T> implements IUnifiedGridController<T> {
|
|
|
298
298
|
const { grid } = this;
|
|
299
299
|
const base = grid.base.current!;
|
|
300
300
|
const targetScrollIndex = this.itemIndexToScrollIndex(dataIndex);
|
|
301
|
-
if (targetScrollIndex > this.scrollIndex) {
|
|
302
|
-
this.adjustGroupsOffsetsForward(targetScrollIndex);
|
|
303
|
-
} else if (targetScrollIndex < this.scrollIndex) {
|
|
304
|
-
this.adjustGroupsOffsetsBackward(targetScrollIndex);
|
|
305
|
-
}
|
|
306
301
|
if (targetScrollIndex !== this.scrollIndex) {
|
|
307
|
-
this.
|
|
302
|
+
const backwards = targetScrollIndex < this.scrollIndex;
|
|
303
|
+
const lastScrollIndex = this.scrollIndex;
|
|
304
|
+
const scrollToIndex = Math.abs(targetScrollIndex - this.scrollIndex);
|
|
305
|
+
for (let i = 1; i <= scrollToIndex; i++) {
|
|
306
|
+
this.scroll(backwards ? lastScrollIndex - i : lastScrollIndex + i, animate);
|
|
307
|
+
}
|
|
308
308
|
}
|
|
309
309
|
base.index = dataIndex;
|
|
310
310
|
this.focusCurrentItem();
|
|
@@ -1,12 +1,19 @@
|
|
|
1
1
|
import { createRef, Reference, Component } from '@24i/bigscreen-sdk/jsx';
|
|
2
|
-
import {
|
|
3
|
-
|
|
2
|
+
import {
|
|
3
|
+
getDisplayToggler,
|
|
4
|
+
IDisplayToggler,
|
|
5
|
+
removeClass,
|
|
6
|
+
addClass,
|
|
7
|
+
DISPLAY_NONE,
|
|
8
|
+
} from '@24i/bigscreen-sdk/utils';
|
|
4
9
|
|
|
5
10
|
const ICON_PREFIX = 'icon-';
|
|
6
11
|
|
|
7
12
|
type Props<SpritesJSON> = {
|
|
8
13
|
icon?: keyof SpritesJSON,
|
|
9
|
-
domRef?: Reference<HTMLDivElement
|
|
14
|
+
domRef?: Reference<HTMLDivElement>,
|
|
15
|
+
className?: string,
|
|
16
|
+
initialIsHidden?: boolean,
|
|
10
17
|
};
|
|
11
18
|
|
|
12
19
|
export class Icon<T> extends Component<Props<T>> {
|
|
@@ -14,10 +21,13 @@ export class Icon<T> extends Component<Props<T>> {
|
|
|
14
21
|
|
|
15
22
|
currentIcon: keyof T | undefined;
|
|
16
23
|
|
|
24
|
+
iconDisplay: IDisplayToggler;
|
|
25
|
+
|
|
17
26
|
constructor(props: Props<T>) {
|
|
18
27
|
super(props);
|
|
19
28
|
this.ref = props.domRef || createRef();
|
|
20
29
|
this.currentIcon = props.icon;
|
|
30
|
+
this.iconDisplay = getDisplayToggler(this.ref, props.initialIsHidden);
|
|
21
31
|
}
|
|
22
32
|
|
|
23
33
|
getClass(icon: keyof T): string {
|
|
@@ -31,6 +41,16 @@ export class Icon<T> extends Component<Props<T>> {
|
|
|
31
41
|
this.currentIcon = icon;
|
|
32
42
|
}
|
|
33
43
|
|
|
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
|
+
|
|
34
54
|
clearIcon() {
|
|
35
55
|
if (!this.currentIcon) return;
|
|
36
56
|
removeClass(this.ref, this.getClass(this.currentIcon));
|
|
@@ -38,11 +58,13 @@ export class Icon<T> extends Component<Props<T>> {
|
|
|
38
58
|
}
|
|
39
59
|
|
|
40
60
|
render() {
|
|
41
|
-
const { icon } = this.props;
|
|
61
|
+
const { icon, className, initialIsHidden } = this.props;
|
|
42
62
|
return (
|
|
43
63
|
<div
|
|
44
64
|
ref={this.ref}
|
|
45
|
-
className={
|
|
65
|
+
className={`${className || ''} icon ${icon
|
|
66
|
+
? this.getClass(icon) : ''} ${initialIsHidden
|
|
67
|
+
? DISPLAY_NONE : ''}`}
|
|
46
68
|
/>
|
|
47
69
|
);
|
|
48
70
|
}
|
package/packages/input/README.md
CHANGED
|
@@ -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`
|
|
20
19
|
- `onFocus` - optional callback which is called when input gets focus
|
|
21
20
|
- `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
|
|
@@ -19,13 +19,11 @@ type Props = {
|
|
|
19
19
|
passwordChar?: string,
|
|
20
20
|
/** Moves text to the left (with negative margin-left) when caret overflows */
|
|
21
21
|
shouldHandleOverflow?: boolean,
|
|
22
|
-
onChange?: (newValue: string) => void,
|
|
23
|
-
onFocus?: () => void,
|
|
24
|
-
onBlur?: () => void,
|
|
25
|
-
// eslint-disable-next-line react/no-unused-prop-types
|
|
26
22
|
maxLength?: number,
|
|
27
|
-
|
|
23
|
+
onFocus?: (event: FocusEvent) => void,
|
|
24
|
+
onBlur?: (event: FocusEvent) => void,
|
|
28
25
|
onFinish?: (wasCancelled?: boolean) => void,
|
|
26
|
+
onChange?: (newValue: string) => void,
|
|
29
27
|
};
|
|
30
28
|
|
|
31
29
|
const ACTIVE = 'active';
|
|
@@ -126,12 +124,14 @@ export class Input extends Component<Props> implements IFocusable {
|
|
|
126
124
|
const range = new Range();
|
|
127
125
|
range.selectNode(textNode);
|
|
128
126
|
const wholeText = range.getBoundingClientRect();
|
|
129
|
-
range.setStart(textNode,
|
|
127
|
+
range.setStart(textNode, 0);
|
|
130
128
|
range.setEnd(textNode, position);
|
|
131
129
|
const caretText = range.getBoundingClientRect();
|
|
132
|
-
const
|
|
133
|
-
? wholeText.
|
|
134
|
-
: wholeText.left
|
|
130
|
+
const [initialCaretPosition, currentCarretPosition, offsetBase] = isRtl()
|
|
131
|
+
? [wholeText.right, caretText.left, wholeText.left]
|
|
132
|
+
: [wholeText.left, caretText.right, wholeText.right];
|
|
133
|
+
const caretPos = position === 0 ? initialCaretPosition : currentCarretPosition;
|
|
134
|
+
const offset = offsetBase - caretPos;
|
|
135
135
|
offsetPosition(this.caret, { x: -offset }, false);
|
|
136
136
|
}
|
|
137
137
|
|
|
@@ -220,7 +220,7 @@ export class Input extends Component<Props> implements IFocusable {
|
|
|
220
220
|
>
|
|
221
221
|
{placeholder}
|
|
222
222
|
</div>
|
|
223
|
-
<div ref={this.text} className="text"
|
|
223
|
+
<div ref={this.text} className="text">
|
|
224
224
|
{this.filterText(value)}
|
|
225
225
|
</div>
|
|
226
226
|
<div ref={this.caret} className="caret" />
|
|
@@ -12,6 +12,7 @@ It provides common functionality for you.
|
|
|
12
12
|
## Props
|
|
13
13
|
- `onPress` - called for onClick and onKeyDown
|
|
14
14
|
- `ref` is forwarded to underlying `div`
|
|
15
|
+
- `blockRepeatedKeyDown` - interactable must suppress repeated onPress calls, until the key is released. This is because because keyDown event is repeatedly fired when user holds key on webTv and Adrodid Tv. This may lead to unpredictable behavior.
|
|
15
16
|
- other `div` props
|
|
16
17
|
|
|
17
18
|
## Provided functionality
|
|
@@ -34,4 +35,4 @@ renders
|
|
|
34
35
|
<div class="btn btn-primary" tabindex="0">
|
|
35
36
|
Play video
|
|
36
37
|
</div>
|
|
37
|
-
```
|
|
38
|
+
```
|
|
@@ -3,14 +3,20 @@ import { isClickOrEnter } from '@24i/bigscreen-sdk/device';
|
|
|
3
3
|
import { Props } from './interface';
|
|
4
4
|
|
|
5
5
|
export const Interactable = forwardRef<Props>(
|
|
6
|
-
({ children, onPress, ...otherProps },
|
|
6
|
+
({ children, onPress, blockRepeatedKeyDown, ...otherProps },
|
|
7
|
+
ref: Reference<HTMLDivElement> | null) => {
|
|
7
8
|
const domRef = ref || createRef<HTMLDivElement>();
|
|
8
|
-
|
|
9
|
-
|
|
9
|
+
|
|
10
|
+
const onPressProxy = (e: MouseEvent | KeyboardEvent) => {
|
|
11
|
+
if (typeof onPress === 'function' && isClickOrEnter(e)) {
|
|
12
|
+
onPress(e);
|
|
13
|
+
}
|
|
10
14
|
};
|
|
15
|
+
|
|
11
16
|
const onMouseEnter = () => {
|
|
12
17
|
domRef.current!.focus({ preventScroll: true });
|
|
13
18
|
};
|
|
19
|
+
|
|
14
20
|
return (
|
|
15
21
|
<div
|
|
16
22
|
{...otherProps}
|
|
@@ -27,5 +27,5 @@ export type {
|
|
|
27
27
|
ClassComponentInterface,
|
|
28
28
|
DeclareProps,
|
|
29
29
|
} from './types';
|
|
30
|
-
// eslint-disable-next-line import/no-default-export
|
|
30
|
+
// eslint-disable-next-line import/no-default-export, no-restricted-exports
|
|
31
31
|
export { createElement as default } from './virtualDOM';
|
|
@@ -0,0 +1,27 @@
|
|
|
1
|
+
import { Reference, Component } from '../index';
|
|
2
|
+
import { unwrapReference } from '../utils';
|
|
3
|
+
|
|
4
|
+
type ToPress = Reference<HTMLElement> | HTMLElement | Window | Document | Component<any>;
|
|
5
|
+
|
|
6
|
+
interface Key {
|
|
7
|
+
keyCode: number,
|
|
8
|
+
code: string,
|
|
9
|
+
key?: string,
|
|
10
|
+
}
|
|
11
|
+
|
|
12
|
+
export const keyup = (toPress: ToPress, keyOrKeyCode: number | Key) => {
|
|
13
|
+
const element = unwrapReference<ToPress>(toPress);
|
|
14
|
+
let kbEventOptions: KeyboardEventInit;
|
|
15
|
+
if (typeof keyOrKeyCode === 'number') {
|
|
16
|
+
kbEventOptions = { keyCode: keyOrKeyCode };
|
|
17
|
+
} else {
|
|
18
|
+
const { keyCode, code, key } = keyOrKeyCode;
|
|
19
|
+
kbEventOptions = { keyCode, code, key };
|
|
20
|
+
}
|
|
21
|
+
const event = new KeyboardEvent('keyup', kbEventOptions);
|
|
22
|
+
if ((element as any).onKeyUp) {
|
|
23
|
+
(element as any).onKeyUp(event);
|
|
24
|
+
} else if ((element as any).dispatchEvent) {
|
|
25
|
+
(element as Element).dispatchEvent(event);
|
|
26
|
+
}
|
|
27
|
+
};
|