@playkit-js/transcript 3.7.3 → 3.7.4-canary.0-b1de1de

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/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@playkit-js/transcript",
3
- "version": "3.7.3",
3
+ "version": "3.7.4-canary.0-b1de1de",
4
4
  "main": "dist/playkit-transcript.js",
5
5
  "license": "AGPL-3.0",
6
6
  "private": false,
@@ -13,7 +13,7 @@
13
13
  "url": "git+https://github.com/kaltura/playkit-js-transcript.git"
14
14
  },
15
15
  "devDependencies": {
16
- "@playkit-js/kaltura-player-js": "3.17.9",
16
+ "@playkit-js/kaltura-player-js": "3.17.56",
17
17
  "@playkit-js/playkit-js-ui": "0.79.13",
18
18
  "@playkit-js/ui-managers": "1.6.2-canary.0-9634d47",
19
19
  "@types/sanitize-html": "^2.9.3",
@@ -21,7 +21,7 @@
21
21
  "copyfiles": "^2.4.1",
22
22
  "cross-env": "^7.0.3",
23
23
  "css-loader": "^6.7.1",
24
- "cypress": "13.13.1",
24
+ "cypress": "14.1.0",
25
25
  "playwright-webkit": "^1.33.0",
26
26
  "prettier": "^2.6.2",
27
27
  "rimraf": "^5.0.5",
@@ -37,6 +37,8 @@ interface ExtendedCaptionProps extends CaptionProps {
37
37
  activeSearchIndex: number;
38
38
  longerThanHour: boolean;
39
39
  isAutoScrollEnabled: boolean;
40
+ onUpKeyPressed?: (e: KeyboardEvent) => void;
41
+ onDownKeyPressed?: (e: KeyboardEvent) => void;
40
42
  }
41
43
 
42
44
  const translates = {
@@ -174,7 +176,11 @@ export class Caption extends Component<ExtendedCaptionProps> {
174
176
  };
175
177
 
176
178
  return (
177
- <A11yWrapper onClick={this._handleClick}>
179
+ <A11yWrapper
180
+ onClick={this._handleClick}
181
+ onUpKeyPressed={(e: KeyboardEvent) => this.props.onUpKeyPressed?.(e)}
182
+ onDownKeyPressed={(e: KeyboardEvent) => this.props.onDownKeyPressed?.(e)}
183
+ >
178
184
  <div
179
185
  className={styles.caption}
180
186
  ref={node => {
@@ -33,6 +33,40 @@ export class CaptionList extends Component<Props> {
33
33
  private _currentCaptionRef: any = null;
34
34
  private _firstCaptionRef: any = null;
35
35
  private _lastCaptionRef: any = null;
36
+ private _captionRefs: Map<number, HTMLElement | null> = new Map();
37
+
38
+ private _setCaptionRef = (index: number, ref: HTMLElement | null) => {
39
+ this._captionRefs.set(index, ref);
40
+ };
41
+
42
+ private _getCaptionRef = (index: number) => {
43
+ return this._captionRefs.get(index);
44
+ };
45
+
46
+ private _focusPrevCaption = (currentIndex: number) => {
47
+ const { data } = this.props;
48
+ if (!data.length) return;
49
+
50
+ let prevIndex = currentIndex - 1;
51
+ if (prevIndex < 0) {
52
+ prevIndex = data.length - 1;
53
+ }
54
+
55
+ this._getCaptionRef(prevIndex)?.focus();
56
+ };
57
+
58
+ private _focusNextCaption = (currentIndex: number) => {
59
+ const { data } = this.props;
60
+ if (!data.length) return;
61
+
62
+ let nextIndex = currentIndex + 1;
63
+ if (nextIndex >= data.length) {
64
+ nextIndex = 0;
65
+ }
66
+
67
+ this._getCaptionRef(nextIndex)?.focus();
68
+ };
69
+
36
70
  shouldComponentUpdate(nextProps: Readonly<Props>) {
37
71
  const {highlightedMap, data, searchMap, activeSearchIndex, isAutoScrollEnabled, captionProps} = this.props;
38
72
  if (
@@ -122,6 +156,7 @@ export class CaptionList extends Component<Props> {
122
156
  <Caption
123
157
  setTextToRead={setTextToRead}
124
158
  ref={node => {
159
+ this._setCaptionRef(index, node?.base ?? null);
125
160
  if (index === 0) {
126
161
  this._firstCaptionRef = node;
127
162
  } else if (index === data.length - 1) {
@@ -131,6 +166,8 @@ export class CaptionList extends Component<Props> {
131
166
  this._currentCaptionRef = node;
132
167
  }
133
168
  }}
169
+ onUpKeyPressed={() => this._focusPrevCaption(index)}
170
+ onDownKeyPressed={() => this._focusNextCaption(index)}
134
171
  {...captionProps}
135
172
  />
136
173
  );
@@ -1,6 +1,6 @@
1
1
  import {A11yWrapper, OnClickEvent} from '@playkit-js/common/dist/hoc/a11y-wrapper';
2
2
  import {h} from 'preact';
3
- import {useState} from 'preact/hooks';
3
+ import {useState, useRef} from 'preact/hooks';
4
4
  import {Icon} from '@playkit-js/common/dist/icon';
5
5
 
6
6
  import * as styles from './popover-menu.scss';
@@ -21,12 +21,16 @@ interface PopoverMenuItemProps {
21
21
  onKeyUp: (index: number) => void;
22
22
  onKeyDown: (index: number) => void;
23
23
  onClick?: () => void;
24
+ onLeftKeyPressed?: () => void;
25
+ onRightKeyPressed?: () => void;
24
26
  }
25
27
 
26
28
  export const PopoverMenuItem = (props: PopoverMenuItemProps) => {
27
29
  const {item, index, setRef, onKeyUp, onKeyDown, onClick} = props;
28
30
  const {isDisabled, isSelected, items, testId, label} = item;
29
31
  const [isChildOpen, setIsChildOpen] = useState(false);
32
+ const parentRef = useRef<HTMLDivElement | null>(null);
33
+ const childRefs = useRef<Map<number, HTMLDivElement | null>>(new Map());
30
34
 
31
35
  const getAddonAfter = () => {
32
36
  if (items) {
@@ -50,6 +54,41 @@ export const PopoverMenuItem = (props: PopoverMenuItemProps) => {
50
54
  onClick?.();
51
55
  };
52
56
 
57
+ const focusChild = (i: number) => {
58
+ const node = childRefs.current.get(i);
59
+ node?.focus();
60
+ };
61
+
62
+ const handleChildUp = (currentIndex: number) => {
63
+ if (!items?.length) return;
64
+
65
+ let prevIndex = currentIndex - 1;
66
+ if (prevIndex < 0) {
67
+ prevIndex = items.length - 1;
68
+ }
69
+
70
+ while (items[prevIndex].isDisabled) {
71
+ prevIndex = prevIndex - 1 < 0 ? items.length - 1 : prevIndex - 1;
72
+ }
73
+
74
+ focusChild(prevIndex);
75
+ };
76
+
77
+ const handleChildDown = (currentIndex: number) => {
78
+ if (!items?.length) return;
79
+
80
+ let nextIndex = currentIndex + 1;
81
+ if (nextIndex >= items.length) {
82
+ nextIndex = 0;
83
+ }
84
+
85
+ while (items[nextIndex].isDisabled) {
86
+ nextIndex = nextIndex + 1 >= items.length ? 0 : nextIndex + 1;
87
+ }
88
+
89
+ focusChild(nextIndex);
90
+ };
91
+
53
92
  const renderChildItems = () => {
54
93
  if (!items) {
55
94
  return null;
@@ -62,13 +101,22 @@ export const PopoverMenuItem = (props: PopoverMenuItemProps) => {
62
101
  key={index}
63
102
  item={item}
64
103
  index={index}
65
- onKeyDown={() => {}}
66
- onKeyUp={() => {}}
104
+ onKeyDown={() => handleChildDown(index)}
105
+ onKeyUp={() => handleChildUp(index)}
106
+ setRef={(i, node) => childRefs.current.set(i, node)}
67
107
  onClick={() => {
68
108
  item.onClick?.();
69
109
  onClick?.();
70
110
  setIsChildOpen(false);
71
111
  }}
112
+ onLeftKeyPressed={() => {
113
+ setIsChildOpen(false);
114
+ parentRef.current?.focus();
115
+ }}
116
+ onRightKeyPressed={() => {
117
+ setIsChildOpen(false);
118
+ parentRef.current?.focus();
119
+ }}
72
120
  />
73
121
  ))
74
122
  : null}
@@ -89,7 +137,25 @@ export const PopoverMenuItem = (props: PopoverMenuItemProps) => {
89
137
  if (!isDisabled) {
90
138
  onKeyUp(index);
91
139
  }
92
- }}>
140
+ }}
141
+ onRightKeyPressed={() => {
142
+ if (items && !isDisabled) {
143
+ if (!isChildOpen) {
144
+ setIsChildOpen(true);
145
+ }
146
+ childRefs.current.get(0)?.focus();
147
+ } else {
148
+ props.onRightKeyPressed?.();
149
+ }
150
+ }}
151
+ onLeftKeyPressed={() => {
152
+ if (isChildOpen) {
153
+ childRefs.current.get(0)?.focus();
154
+ } else {
155
+ props.onRightKeyPressed?.();
156
+ }
157
+ }}
158
+ >
93
159
  <div
94
160
  tabIndex={isDisabled ? -1 : 0}
95
161
  role="menuitem"
@@ -97,8 +163,10 @@ export const PopoverMenuItem = (props: PopoverMenuItemProps) => {
97
163
  className={`${styles.popoverMenuItem} ${isDisabled ? styles.popoverMenuItemDisabled : ''}`}
98
164
  data-testid={testId}
99
165
  ref={node => {
166
+ parentRef.current = node;
100
167
  setRef?.(index, node);
101
- }}>
168
+ }}
169
+ >
102
170
  {label}
103
171
  {getAddonAfter()}
104
172
  {renderChildItems()}
@@ -70,11 +70,27 @@ class PopoverMenu extends Component<PopoverMenuProps, PopoverMenuState> {
70
70
  };
71
71
 
72
72
  private _handleUpKeyPressed = (currentIndex: number) => () => {
73
- this._getItemRef(currentIndex - 1)?.focus();
73
+ const { items } = this.props;
74
+ if (!items.length) return;
75
+
76
+ let prevIndex = currentIndex - 1;
77
+ if (prevIndex < 0) {
78
+ prevIndex = items.length - 1;
79
+ }
80
+
81
+ this._getItemRef(prevIndex)?.focus();
74
82
  };
75
83
 
76
84
  private _handleDownKeyPressed = (currentIndex: number) => () => {
77
- this._getItemRef(currentIndex + 1)?.focus();
85
+ const { items } = this.props;
86
+ if (!items.length) return;
87
+
88
+ let nextIndex = currentIndex + 1;
89
+ if (nextIndex >= items.length) {
90
+ nextIndex = 0;
91
+ }
92
+
93
+ this._getItemRef(nextIndex)?.focus();
78
94
  };
79
95
 
80
96
  private _closePopover() {
@@ -86,15 +102,10 @@ class PopoverMenu extends Component<PopoverMenuProps, PopoverMenuState> {
86
102
 
87
103
  this.setState({isOpen}, () => {
88
104
  if (isOpen) {
89
- this._controlElementRef?.focus();
90
- this.props.eventManager?.listen(this._controlElementRef, 'keydown', (event: KeyboardEvent) => {
91
- if (event.keyCode === TAB) {
92
- const firstNonDisabledItem = this.props.items.findIndex((item: PopoverMenuItemData) => !item.isDisabled);
93
- if (firstNonDisabledItem !== -1) {
94
- this._getItemRef(firstNonDisabledItem - 1)?.focus();
95
- }
96
- }
97
- });
105
+ const firstNonDisabledItem = this.props.items.findIndex((item: PopoverMenuItemData) => !item.isDisabled);
106
+ if (firstNonDisabledItem !== -1) {
107
+ this._getItemRef(firstNonDisabledItem)?.focus();
108
+ }
98
109
  }
99
110
  });
100
111
  };
@@ -154,8 +165,12 @@ class PopoverMenu extends Component<PopoverMenuProps, PopoverMenuState> {
154
165
  key={index}
155
166
  item={item}
156
167
  index={index}
157
- onKeyDown={this._handleDownKeyPressed}
158
- onKeyUp={this._handleUpKeyPressed}
168
+ onKeyDown={(currentIndex: number) => {
169
+ this._handleDownKeyPressed(currentIndex)();
170
+ }}
171
+ onKeyUp={(currentIndex: number) => {
172
+ this._handleUpKeyPressed(currentIndex)();
173
+ }}
159
174
  setRef={this._setItemRef}
160
175
  onClick={() => {
161
176
  this._closePopover();
@@ -354,7 +354,6 @@ export class TranscriptPlugin extends KalturaPlayer.core.BasePlugin {
354
354
  ) as any;
355
355
  },
356
356
  // eslint-disable-next-line @typescript-eslint/ban-ts-comment
357
- // @ts-expect-error - Property 'MiniAudioUI' does not exist
358
357
  presets: [ReservedPresetNames.Playback, ReservedPresetNames.Live, ReservedPresetNames.Ads, ReservedPresetNames.MiniAudioUI],
359
358
  position: position,
360
359
  expandMode: expandMode === SidePanelModes.ALONGSIDE ? SidePanelModes.ALONGSIDE : SidePanelModes.OVER
@@ -365,7 +364,6 @@ export class TranscriptPlugin extends KalturaPlayer.core.BasePlugin {
365
364
  transcript: <Text id="transcript.transcript">Transcript</Text>
366
365
  };
367
366
  // eslint-disable-next-line @typescript-eslint/ban-ts-comment
368
- // @ts-expect-error - Property 'MiniAudioUI' does not exist
369
367
  if (this._state.shell['activePresetName'] !== ReservedPresetNames.MiniAudioUI) {
370
368
  this._transcriptIcon = this.upperBarManager!.add({
371
369
  displayName: 'Transcript',