@playkit-js/transcript 3.4.1-canary.1-d2c93cc → 3.4.1-canary.8-b84ee42

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.4.1-canary.1-d2c93cc",
3
+ "version": "3.4.1-canary.8-b84ee42",
4
4
  "main": "dist/playkit-transcript.js",
5
5
  "license": "AGPL-3.0",
6
6
  "private": false,
@@ -2,7 +2,6 @@
2
2
 
3
3
  .popover-anchor-container {
4
4
  cursor: pointer;
5
- margin-left: 8px;
6
5
  border-radius: $roundness-1;
7
6
 
8
7
  &:hover {
@@ -54,8 +53,12 @@
54
53
  padding: 9px 24px 9px 16px;
55
54
  white-space: nowrap;
56
55
  margin: 4px;
56
+
57
+ &.popover-menu-item-disabled {
58
+ color: $tone-4-color;
59
+ }
57
60
 
58
- &:hover {
61
+ &:hover :not(.popover-menu-item-disabled) {
59
62
  background-color: $tone-6-color;
60
63
  border-radius: $roundness-1;
61
64
  cursor: pointer;
@@ -1,8 +1,10 @@
1
1
  import {A11yWrapper} from '@playkit-js/common/dist/hoc/a11y-wrapper';
2
2
  import {h, Component, VNode} from 'preact';
3
3
 
4
+ const {Tooltip} = KalturaPlayer.ui.components;
5
+
4
6
  const {withEventManager} = KalturaPlayer.ui.Event;
5
- const {ENTER, ESC, SPACE} = KalturaPlayer.ui.utils.KeyMap;
7
+ const {TAB} = KalturaPlayer.ui.utils.KeyMap;
6
8
 
7
9
  import * as styles from './popover-menu.scss';
8
10
 
@@ -10,9 +12,11 @@ interface PopoverMenuItemData {
10
12
  testId: string;
11
13
  label: string;
12
14
  onClick: () => void;
15
+ isDisabled?: boolean;
13
16
  }
14
17
 
15
18
  interface PopoverMenuProps {
19
+ label: string;
16
20
  eventManager?: any;
17
21
  children?: VNode;
18
22
  items: Array<PopoverMenuItemData>;
@@ -26,6 +30,7 @@ interface PopoverMenuState {
26
30
  class PopoverMenu extends Component<PopoverMenuProps, PopoverMenuState> {
27
31
  private _controlElementRef: HTMLDivElement | null = null;
28
32
  private _popoverElementRef: HTMLDivElement | null = null;
33
+ private _itemsRefMap: Map<number, HTMLDivElement | null> = new Map();
29
34
 
30
35
  eventManager: any;
31
36
 
@@ -34,7 +39,11 @@ class PopoverMenu extends Component<PopoverMenuProps, PopoverMenuState> {
34
39
  this.state = {isOpen: false};
35
40
 
36
41
  this.props.eventManager?.listen(document, 'click', this.handleMouseEvent);
37
- this.props.eventManager?.listen(document, 'keydown', this.handleKeyboardEvent);
42
+ this.props.eventManager?.listen(document, 'keydown', this.handleKeydownEvent);
43
+ }
44
+
45
+ componentWillUnmount() {
46
+ this._itemsRefMap = new Map();
38
47
  }
39
48
 
40
49
  private handleMouseEvent = (event: MouseEvent) => {
@@ -43,33 +52,57 @@ class PopoverMenu extends Component<PopoverMenuProps, PopoverMenuState> {
43
52
  }
44
53
  };
45
54
 
46
- private handleKeyboardEvent = (event: KeyboardEvent) => {
47
- if (this._controlElementRef?.contains(event.target as Node | null) && [ENTER, SPACE].includes(event.keyCode)) {
48
- // use handler of control element
49
- event.preventDefault();
50
- return;
51
- }
52
- if (this._popoverElementRef?.contains(event.target as Node | null) && event.keyCode !== ESC) {
53
- // use handler of popover element
54
- return;
55
+ private handleKeydownEvent = (event: KeyboardEvent) => {
56
+ const eventTarget = event.target as Node | null;
57
+ if (
58
+ this.state.isOpen &&
59
+ event.keyCode === TAB &&
60
+ !this._controlElementRef?.contains(eventTarget) &&
61
+ !this._popoverElementRef?.contains(eventTarget)
62
+ ) {
63
+ this.closePopover();
55
64
  }
56
- this.closePopover();
65
+ };
66
+
67
+ private _handleUpKeyPressed = (currentIndex: number) => () => {
68
+ this._getItemRef(currentIndex - 1)?.focus();
69
+ };
70
+
71
+ private _handleDownKeyPressed = (currentIndex: number) => () => {
72
+ this._getItemRef(currentIndex + 1)?.focus();
57
73
  };
58
74
 
59
75
  private closePopover() {
60
76
  this.setState({isOpen: false});
61
77
  }
62
78
 
63
- private togglePopover = () => {
64
- this.setState({isOpen: !this.state.isOpen});
79
+ private togglePopover = (focusFirstItem: boolean) => {
80
+ const isOpen = !this.state.isOpen;
81
+
82
+ this.setState({isOpen}, () => {
83
+ if (isOpen && focusFirstItem) {
84
+ const firstNonDisabledItem = this.props.items.findIndex((item: PopoverMenuItemData) => !item.isDisabled);
85
+ if (firstNonDisabledItem !== -1) {
86
+ this._getItemRef(firstNonDisabledItem)?.focus();
87
+ }
88
+ }
89
+ });
90
+ };
91
+
92
+ private _getItemRef = (index: number) => {
93
+ return this._itemsRefMap.get(index);
94
+ };
95
+
96
+ private _setItemRef = (index: number, ref: HTMLDivElement | null) => {
97
+ return this._itemsRefMap.set(index, ref);
65
98
  };
66
99
 
67
100
  render() {
68
- const {children, items} = this.props;
101
+ const {label, children, items} = this.props;
69
102
 
70
- return (
103
+ const popoverMenuContent = (
71
104
  <div className={styles.popoverContainer}>
72
- <A11yWrapper onClick={this.togglePopover}>
105
+ <A11yWrapper onClick={() => this.togglePopover(true)}>
73
106
  <div
74
107
  data-testid="popover-anchor-container"
75
108
  className={`${styles.popoverAnchorContainer} ${this.state.isOpen ? styles.active : ''}`}
@@ -80,17 +113,42 @@ class PopoverMenu extends Component<PopoverMenuProps, PopoverMenuState> {
80
113
  </div>
81
114
  </A11yWrapper>
82
115
 
83
- <div className={styles.popoverComponent} role="menu" aria-expanded={this.state.isOpen}>
116
+ <div
117
+ className={styles.popoverComponent}
118
+ role="menu"
119
+ aria-expanded={this.state.isOpen}
120
+ ref={node => {
121
+ this._popoverElementRef = node;
122
+ }}>
84
123
  {this.state.isOpen
85
- ? items.map(({label, onClick, testId}) => {
124
+ ? items.map(({label, onClick, testId, isDisabled}, index) => {
86
125
  return (
87
126
  <A11yWrapper
88
127
  onClick={() => {
89
- this.closePopover();
90
- onClick();
128
+ if (!isDisabled) {
129
+ this.closePopover();
130
+ onClick();
131
+ }
132
+ }}
133
+ onDownKeyPressed={() => {
134
+ if (!isDisabled) {
135
+ this._handleDownKeyPressed(index);
136
+ }
137
+ }}
138
+ onUpKeyPressed={() => {
139
+ if (!isDisabled) {
140
+ this._handleUpKeyPressed(index);
141
+ }
91
142
  }}>
92
143
  {
93
- <div tabIndex={0} role="menuitem" className={styles.popoverMenuItem} data-testid={testId}>
144
+ <div
145
+ tabIndex={isDisabled ? -1 : 0}
146
+ role="menuitem"
147
+ className={`${styles.popoverMenuItem} ${isDisabled ? styles.popoverMenuItemDisabled : ''}`}
148
+ data-testid={testId}
149
+ ref={node => {
150
+ this._setItemRef(index, node);
151
+ }}>
94
152
  {label}
95
153
  </div>
96
154
  }
@@ -101,6 +159,14 @@ class PopoverMenu extends Component<PopoverMenuProps, PopoverMenuState> {
101
159
  </div>
102
160
  </div>
103
161
  );
162
+
163
+ return this.state.isOpen ? (
164
+ popoverMenuContent
165
+ ) : (
166
+ <div>
167
+ <Tooltip label={label}>{popoverMenuContent}</Tooltip>
168
+ </div>
169
+ );
104
170
  }
105
171
  }
106
172
 
@@ -61,6 +61,8 @@
61
61
  padding-left: 16px;
62
62
  font-size: 16px;
63
63
  padding-right: 16px;
64
+ gap: 8px;
65
+ z-index: 2;
64
66
  }
65
67
 
66
68
  .body {
@@ -183,7 +183,7 @@ export class Transcript extends Component<TranscriptProps, TranscriptState> {
183
183
  };
184
184
 
185
185
  private _renderHeader = () => {
186
- const {toggledWithEnter, kitchenSinkActive, downloadDisabled, onDownload, printDisabled, onPrint} = this.props;
186
+ const {toggledWithEnter, kitchenSinkActive, downloadDisabled, onDownload, printDisabled, onPrint, isLoading} = this.props;
187
187
  const {search, activeSearchIndex, totalSearchResults} = this.state;
188
188
  return (
189
189
  <div className={[styles.header, this._getHeaderStyles()].join(' ')} data-testid="transcript_header">
@@ -196,13 +196,14 @@ export class Transcript extends Component<TranscriptProps, TranscriptState> {
196
196
  toggledWithEnter={toggledWithEnter}
197
197
  kitchenSinkActive={kitchenSinkActive}
198
198
  />
199
- <TranscriptMenu {...{downloadDisabled, onDownload, printDisabled, onPrint}} />
199
+ <TranscriptMenu {...{downloadDisabled, onDownload, printDisabled, onPrint, isLoading}} />
200
200
  <div data-testid="transcriptCloseButton">
201
201
  <Button
202
202
  type={ButtonType.borderless}
203
203
  size={ButtonSize.medium}
204
204
  disabled={false}
205
205
  onClick={this.props.onClose}
206
+ ariaLabel={'Hide Transcript'}
206
207
  tooltip={{label: 'Hide Transcript'}}
207
208
  icon={'close'}></Button>
208
209
  </div>
@@ -12,10 +12,10 @@ interface TranscriptMenuProps {
12
12
  onPrint: () => void;
13
13
  downloadDisabled?: boolean;
14
14
  printDisabled?: boolean;
15
+ isLoading?: boolean;
15
16
  }
16
17
 
17
18
  interface TranscriptMenuState {
18
- isOpen: boolean;
19
19
  items: Array<PopoverMenuItemData>;
20
20
  }
21
21
 
@@ -23,13 +23,14 @@ class TranscriptMenu extends Component<TranscriptMenuProps, TranscriptMenuState>
23
23
  constructor(props: TranscriptMenuProps) {
24
24
  super();
25
25
 
26
- const {downloadDisabled, onDownload, printDisabled, onPrint, printDownloadAreaLabel, printTranscript, downloadTranscript} = props;
26
+ const {downloadDisabled, onDownload, printDisabled, onPrint, printDownloadAreaLabel, printTranscript, downloadTranscript, isLoading} = props;
27
27
  const items = [];
28
28
  if (!downloadDisabled) {
29
29
  items.push({
30
30
  testId: 'download-menu-item',
31
31
  label: 'Download transcript',
32
- onClick: onDownload
32
+ onClick: onDownload,
33
+ isDisabled: isLoading
33
34
  });
34
35
  }
35
36
 
@@ -37,16 +38,17 @@ class TranscriptMenu extends Component<TranscriptMenuProps, TranscriptMenuState>
37
38
  items.push({
38
39
  testId: 'print-menu-item',
39
40
  label: 'Print transcript',
40
- onClick: onPrint
41
+ onClick: onPrint,
42
+ isDisabled: isLoading
41
43
  });
42
44
  }
43
45
 
44
- this.state = {isOpen: false, items};
46
+ this.state = {items};
45
47
  }
46
48
 
47
49
  render() {
48
50
  return this.state.items.length ? (
49
- <PopoverMenu items={this.state.items}>
51
+ <PopoverMenu label={'More'} items={this.state.items}>
50
52
  <Button type={ButtonType.borderless} icon={'more'}></Button>
51
53
  </PopoverMenu>
52
54
  ) : null;
@@ -0,0 +1,7 @@
1
+ {
2
+ "ar": {
3
+ "transcript": {
4
+
5
+ }
6
+ }
7
+ }
@@ -0,0 +1,20 @@
1
+ {
2
+ "de": {
3
+ "transcript": {
4
+ "hide_plugin": "Transkript ausblenden",
5
+ "show_plugin": "Transkript anzeigen",
6
+ "print_download_area_label": "Aktuelle Abschrift herunterladen oder drucken",
7
+ "print_transcript": "Aktuelles Transkript drucken",
8
+ "download_transcript": "Aktuelles Transkript herunterladen",
9
+ "search": "Suche im Transkript",
10
+ "clear_search": "Suche leeren",
11
+ "next_search_match": "Weiter",
12
+ "prev_search_match": "Vorherige",
13
+ "search_results": "Ergebnis {{current}} von {{total}}",
14
+ "auto_scroll": "AutoScroll fortsetzen",
15
+ "whoops": "Hoppla!",
16
+ "load_failed": "Transkript konnte nicht geladen werden",
17
+ "skip_transcript": "Transkript überspringen"
18
+ }
19
+ }
20
+ }
@@ -0,0 +1,20 @@
1
+ {
2
+ "fi": {
3
+ "transcript": {
4
+ "hide_plugin": "Piilota tekstitallenne",
5
+ "show_plugin": "Näytä tekstitallenne",
6
+ "print_download_area_label": "Lataa tai tulosta nykyinen tekstitallenne",
7
+ "print_transcript": "Tulosta nykyinen tekstitallenne",
8
+ "download_transcript": "Lataa nykyinen tekstitallenne",
9
+ "search": "Hae tekstitallenteesta",
10
+ "clear_search": "Tyhjennä haku",
11
+ "next_search_match": "Seuraava",
12
+ "prev_search_match": "Edellinen",
13
+ "search_results": "Tulos {{current}}/{{total}}",
14
+ "auto_scroll": "Jatka automaattista vieritystä",
15
+ "whoops": "Ups!",
16
+ "load_failed": "Tekstitallenteen lataaminen epäonnistui",
17
+ "skip_transcript": "Ohita tekstitallenne"
18
+ }
19
+ }
20
+ }
@@ -0,0 +1,20 @@
1
+ {
2
+ "fr": {
3
+ "transcript": {
4
+ "hide_plugin": "Cacher le relevé",
5
+ "show_plugin": "Afficher le relevé",
6
+ "print_download_area_label": "Télécharger ou imprimer le relevé actuel",
7
+ "print_transcript": "Imprimer le relevé actuel",
8
+ "download_transcript": "Télécharger le relevé actuel",
9
+ "search": "Rechercher dans le relevé",
10
+ "clear_search": "Effacer la recherche",
11
+ "next_search_match": "Suivant",
12
+ "prev_search_match": "Précédent",
13
+ "search_results": "Résultat {{current}} de {{total}}",
14
+ "auto_scroll": "Reprendre AutoScroll",
15
+ "whoops": "Oups !",
16
+ "load_failed": "Échec de chargement du relevé",
17
+ "skip_transcript": "Sauter le relevé"
18
+ }
19
+ }
20
+ }
@@ -0,0 +1,20 @@
1
+ {
2
+ "fr_ca": {
3
+ "transcript": {
4
+ "hide_plugin": "Masquer la transcription",
5
+ "show_plugin": "Afficher la transcription",
6
+ "print_download_area_label": "Téléverser ou imprimer la transcription actuelle",
7
+ "print_transcript": "Imprimer la transcription actuelle",
8
+ "download_transcript": "Téléverser la transcription actuelle",
9
+ "search": "Recherche dans la transcription",
10
+ "clear_search": "Effacer la recherche",
11
+ "next_search_match": "Suivant",
12
+ "prev_search_match": "Précédent",
13
+ "search_results": "Résultat {{current}} de {{total}}",
14
+ "auto_scroll": "Reprendre AutoScroll",
15
+ "whoops": "Oups!",
16
+ "load_failed": "Échec du chargement de la transcription",
17
+ "skip_transcript": "Passer la transcription"
18
+ }
19
+ }
20
+ }
@@ -0,0 +1,7 @@
1
+ {
2
+ "he": {
3
+ "transcript": {
4
+
5
+ }
6
+ }
7
+ }
@@ -0,0 +1,7 @@
1
+ {
2
+ "hi_in": {
3
+ "transcript": {
4
+
5
+ }
6
+ }
7
+ }
@@ -0,0 +1,20 @@
1
+ {
2
+ "it": {
3
+ "transcript": {
4
+ "hide_plugin": "Nascondi trascrizione",
5
+ "show_plugin": "Mostra trascrizione",
6
+ "print_download_area_label": "Scarica o stampa trascrizione corrente",
7
+ "print_transcript": "Stampa trascrizione corrente",
8
+ "download_transcript": "Scarica trascrizione corrente",
9
+ "search": "Cerca in Trascrizione",
10
+ "clear_search": "Cancella ricerca",
11
+ "next_search_match": "Successivo",
12
+ "prev_search_match": "Precedente",
13
+ "search_results": "Risultato {{current}} di {{total}}",
14
+ "auto_scroll": "Riprendi Scorrimento automatico",
15
+ "whoops": "Operazione non riuscita!",
16
+ "load_failed": "Impossibile caricare la trascrizione",
17
+ "skip_transcript": "Salta trascrizione"
18
+ }
19
+ }
20
+ }
@@ -0,0 +1,20 @@
1
+ {
2
+ "ja": {
3
+ "transcript": {
4
+ "hide_plugin": "複写を非表示にする",
5
+ "show_plugin": "複写を表示する",
6
+ "print_download_area_label": "現在の複写をダウンロードまたは印刷する",
7
+ "print_transcript": "現在の複写を印刷する",
8
+ "download_transcript": "現在の複写をダウンロードする",
9
+ "search": "複写で検索",
10
+ "clear_search": "検索をクリア",
11
+ "next_search_match": "次",
12
+ "prev_search_match": "前へ",
13
+ "search_results": "{{total}} の結果 {{current}} ",
14
+ "auto_scroll": "AutoScrollを再開",
15
+ "whoops": "おっと!",
16
+ "load_failed": "複写のロードに失敗した",
17
+ "skip_transcript": "複写をスキップ"
18
+ }
19
+ }
20
+ }
@@ -0,0 +1,20 @@
1
+ {
2
+ "ko": {
3
+ "transcript": {
4
+ "hide_plugin": "기록 숨기기",
5
+ "show_plugin": "기록 보기",
6
+ "print_download_area_label": "현재 기록 다운로드 또는 인쇄",
7
+ "print_transcript": "현재 기록 인쇄",
8
+ "download_transcript": "현재 기록 다운로드",
9
+ "search": "기록 검색",
10
+ "clear_search": "검색 지우기",
11
+ "next_search_match": "다음",
12
+ "prev_search_match": "이전",
13
+ "search_results": "{{total}}의 {{current}} 결과",
14
+ "auto_scroll": "자동 스크롤 다시 시작",
15
+ "whoops": "죄송합니다.",
16
+ "load_failed": "기록을 로드하는 데 실패했습니다",
17
+ "skip_transcript": "기록 스킵하기"
18
+ }
19
+ }
20
+ }
@@ -0,0 +1,20 @@
1
+ {
2
+ "nl": {
3
+ "transcript": {
4
+ "hide_plugin": "Transcriptie verbergen",
5
+ "show_plugin": "Transcriptie tonen",
6
+ "print_download_area_label": "Huidige transcriptie afdrukken of downloaden",
7
+ "print_transcript": "Huidige transcriptie afdrukken",
8
+ "download_transcript": "Huidige transcriptie downloaden",
9
+ "search": "In transcriptie zoeken",
10
+ "clear_search": "Zoekopdracht wissen",
11
+ "next_search_match": "Volgende",
12
+ "prev_search_match": "Vorige",
13
+ "search_results": "Resultaat {{current}} van {{total}}",
14
+ "auto_scroll": "AutoScroll hervatten",
15
+ "whoops": "Oeps!",
16
+ "load_failed": "Laden transcriptie mislukt",
17
+ "skip_transcript": "Transcriptie overslaan"
18
+ }
19
+ }
20
+ }
@@ -0,0 +1,20 @@
1
+ {
2
+ "pt_br": {
3
+ "transcript": {
4
+ "hide_plugin": "Ocultar transcrição",
5
+ "show_plugin": "Mostrar transcrição",
6
+ "print_download_area_label": "Baixar ou imprimir transcrição atual",
7
+ "print_transcript": "Imprimir transcrição atual",
8
+ "download_transcript": "Baixar transcrição atual",
9
+ "search": "Buscar na transcrição",
10
+ "clear_search": "Limpar pesquisa",
11
+ "next_search_match": "Próximo",
12
+ "prev_search_match": "Anterior",
13
+ "search_results": "Resultado {{current}} de {{total}}",
14
+ "auto_scroll": "Retomar rolagem automática",
15
+ "whoops": "Ops!",
16
+ "load_failed": "Falha ao carregar a transcrição",
17
+ "skip_transcript": "Ignorar transcrição"
18
+ }
19
+ }
20
+ }
@@ -0,0 +1,20 @@
1
+ {
2
+ "ru": {
3
+ "transcript": {
4
+ "hide_plugin": "Скрыть текстовую расшифровку",
5
+ "show_plugin": "Показать текстовую расшифровку",
6
+ "print_download_area_label": "Скачать или распечатать текущую текстовую расшифровку",
7
+ "print_transcript": "Распечатать текущую текстовую расшифровку",
8
+ "download_transcript": "Скачать текущую текстовую расшифровку",
9
+ "search": "Искать в текстовой расшифровке",
10
+ "clear_search": "Очистить результаты поиска",
11
+ "next_search_match": "Далее",
12
+ "prev_search_match": "Предыдущий",
13
+ "search_results": "Результат {{текущий}} из {{общий}}",
14
+ "auto_scroll": "Возобновить автоматическую прокрутку",
15
+ "whoops": "Ой!",
16
+ "load_failed": "Не удалось загрузить текстовую расшифровку",
17
+ "skip_transcript": "Пропустить текстовую расшифровку"
18
+ }
19
+ }
20
+ }
@@ -0,0 +1,20 @@
1
+ {
2
+ "zh_cn": {
3
+ "transcript": {
4
+ "hide_plugin": "隐藏转录文字",
5
+ "show_plugin": "显示转录文字",
6
+ "print_download_area_label": "加载或打印当前转录文字",
7
+ "print_transcript": "打印当前转录文字",
8
+ "download_transcript": "加载当前转录文字",
9
+ "search": "在转录文字中搜索",
10
+ "clear_search": "清除搜索",
11
+ "next_search_match": "下一个",
12
+ "prev_search_match": "上一个",
13
+ "search_results": "第{{current}} 结果,共 {{total}}个结果",
14
+ "auto_scroll": "恢复自动滚动",
15
+ "whoops": "哎呀!",
16
+ "load_failed": "成绩单加载失败",
17
+ "skip_transcript": "跳过成绩单"
18
+ }
19
+ }
20
+ }
@@ -0,0 +1,20 @@
1
+ {
2
+ "zh_tw": {
3
+ "transcript": {
4
+ "hide_plugin": "隱藏文字記錄",
5
+ "show_plugin": "顯示文字記錄",
6
+ "print_download_area_label": "下載或列印目前文字記錄",
7
+ "print_transcript": "列印目前文字記錄",
8
+ "download_transcript": "下載目前文字記錄",
9
+ "search": "在文字記錄中搜尋",
10
+ "clear_search": "清除搜尋",
11
+ "next_search_match": "下一個",
12
+ "prev_search_match": "前一個",
13
+ "search_results": "{{total}} 的結果 {{current}}",
14
+ "auto_scroll": "恢復自動捲動",
15
+ "whoops": "糟糕!",
16
+ "load_failed": "無法載入文字紀錄",
17
+ "skip_transcript": "略過文字記錄"
18
+ }
19
+ }
20
+ }