@playkit-js/transcript 3.4.1-canary.1-d2c93cc → 3.4.1-canary.5-8a9a5ea
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/CHANGELOG.md +2 -1
- package/dist/playkit-transcript.js +1 -1
- package/dist/playkit-transcript.js.map +1 -1
- package/package.json +1 -1
- package/src/components/popover-menu/popover-menu.scss +5 -2
- package/src/components/popover-menu/popover-menu.tsx +88 -22
- package/src/components/transcript/transcript.scss +2 -0
- package/src/components/transcript/transcript.tsx +3 -2
- package/src/components/transcript-menu/transcript-menu.tsx +8 -6
package/package.json
CHANGED
|
@@ -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 {
|
|
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.
|
|
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
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
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
|
-
|
|
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
|
-
|
|
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
|
-
|
|
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
|
|
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
|
-
|
|
90
|
-
|
|
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
|
|
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
|
|
|
@@ -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 = {
|
|
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;
|