@playkit-js/transcript 2.1.5-canary.1-4d8d855 → 2.1.5-canary.16-1ac3e09

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 (61) hide show
  1. package/CHANGELOG.md +8 -1
  2. package/LICENSE +5 -5
  3. package/README.md +122 -24
  4. package/dist/1501adfdf5c835667ce7.svg +9 -0
  5. package/dist/301e7a199b2cd06c2edf.svg +9 -0
  6. package/dist/33bce27c0f546e80478c.svg +36 -0
  7. package/dist/6a4867d3d9170cc2a24d.svg +9 -0
  8. package/dist/73bab0af28a1c7aed29f.svg +9 -0
  9. package/dist/84087eb1cff72e5e6bd3.svg +9 -0
  10. package/dist/95d7192dc427afb678d0.svg +9 -0
  11. package/dist/cea5d6a7f050cbd199a1.svg +9 -0
  12. package/dist/d93f06ff32cdfcd016df.svg +9 -0
  13. package/dist/e5496f4c01207db44ffc.svg +9 -0
  14. package/dist/playkit-transcript.js +1 -31
  15. package/dist/playkit-transcript.js.map +1 -1
  16. package/package.json +53 -50
  17. package/src/components/a11y-wrapper/a11y-wrapper.ts +26 -0
  18. package/src/components/a11y-wrapper/index.ts +1 -0
  19. package/src/components/caption/caption.scss +1 -1
  20. package/src/components/caption/caption.tsx +118 -140
  21. package/src/components/caption/index.ts +1 -1
  22. package/src/components/caption-list/captionList.scss +8 -8
  23. package/src/components/caption-list/captionList.tsx +115 -117
  24. package/src/components/caption-list/index.ts +1 -1
  25. package/src/components/close-button/close-button.scss +11 -0
  26. package/src/components/close-button/index.tsx +23 -0
  27. package/src/components/download-print-menu/download-print-menu.scss +49 -48
  28. package/src/components/download-print-menu/download-print-menu.tsx +147 -125
  29. package/src/components/download-print-menu/index.ts +1 -1
  30. package/src/components/icons/index.ts +11 -0
  31. package/src/components/plugin-button/plugin-button.scss +26 -0
  32. package/src/components/plugin-button/plugin-button.tsx +29 -0
  33. package/src/components/popover-menu/index.ts +1 -1
  34. package/src/components/popover-menu/popover-menu.scss +3 -3
  35. package/src/components/popover-menu/popover-menu.tsx +25 -25
  36. package/src/components/search/index.ts +1 -1
  37. package/src/components/search/search.scss +1 -1
  38. package/src/components/search/search.tsx +137 -144
  39. package/src/components/spinner/index.ts +1 -1
  40. package/src/components/spinner/spinner.scss +58 -50
  41. package/src/components/spinner/spinner.tsx +9 -9
  42. package/src/components/transcript/index.ts +1 -1
  43. package/src/components/transcript/transcript.scss +9 -33
  44. package/src/components/transcript/transcript.tsx +333 -454
  45. package/src/global.d.ts +6 -6
  46. package/src/index.ts +13 -1
  47. package/src/transcript-plugin.scss +3 -3
  48. package/src/transcript-plugin.tsx +210 -391
  49. package/src/types/index.ts +3 -0
  50. package/src/types/transcript-config.ts +11 -0
  51. package/src/types/transcript-item-data.ts +29 -0
  52. package/src/types/types-ui.ts +11 -0
  53. package/src/utils/debounce.ts +36 -0
  54. package/src/utils/index.ts +4 -0
  55. package/src/utils/object-utils.ts +34 -0
  56. package/src/utils/popover/popover.scss +30 -0
  57. package/src/utils/popover/popover.tsx +178 -0
  58. package/src/utils/utils.ts +86 -0
  59. package/src/variables.scss +14 -0
  60. package/src/assets/close.svg +0 -10
  61. package/src/utils.ts +0 -192
@@ -1,144 +1,166 @@
1
- import { h, Component, ComponentChild } from "preact";
2
- import {
3
- Popover,
4
- PopoverHorizontalPositions,
5
- PopoverVerticalPositions,
6
- KeyboardKeys
7
- } from "@playkit-js-contrib/ui";
8
- import { PopoverMenu, PopoverMenuItem } from "../popover-menu";
9
- import * as styles from "./download-print-menu.scss";
1
+ import {h, Component, ComponentChild} from 'preact';
2
+ import {Popover, PopoverHorizontalPositions, PopoverVerticalPositions} from '../../utils';
3
+ import {PopoverMenu, PopoverMenuItem} from '../popover-menu';
4
+ import * as styles from './download-print-menu.scss';
5
+
6
+ const {ENTER, Esc} = KalturaPlayer.ui.utils.KeyMap;
7
+
8
+ export function downloadContent(content: string, name: string): void {
9
+ const blob = new Blob([content], {type: 'text/plain;charset=utf-8;'});
10
+ const anchor = document.createElement('a');
11
+ const {navigator} = window as any;
12
+
13
+ if (navigator.msSaveBlob) {
14
+ // IE
15
+ navigator.msSaveOrOpenBlob(blob, name);
16
+ return;
17
+ }
18
+ if (navigator.userAgent.search('Firefox') !== -1) {
19
+ // Firefox
20
+ anchor.style.display = 'none';
21
+ anchor.setAttribute('href', 'data:text/plain;charset=utf-8,' + encodeURIComponent(content));
22
+ } else {
23
+ // Chrome
24
+ anchor.setAttribute('href', URL.createObjectURL(blob));
25
+ }
26
+ anchor.setAttribute('target', '_blank');
27
+ anchor.setAttribute('download', name);
28
+ anchor.click();
29
+ anchor.remove();
30
+ }
31
+
32
+ export function printContent(content: string): void {
33
+ const printWindow = window.open('', '', 'width=400,height=600');
34
+ if (printWindow) {
35
+ printWindow.document.write(content);
36
+ printWindow.document.close();
37
+ printWindow.focus();
38
+ printWindow.print();
39
+ printWindow.close();
40
+ }
41
+ }
10
42
 
11
43
  interface DownloadPrintMenuProps {
12
- dropdownAriaLabel: string;
13
- printButtonAriaLabel: string;
14
- downloadButtonAriaLabel: string;
15
- onDownload: () => void;
16
- onPrint: () => void;
17
- downloadDisabled: boolean;
18
- printDisabled: boolean;
44
+ dropdownAriaLabel: string;
45
+ printButtonAriaLabel: string;
46
+ downloadButtonAriaLabel: string;
47
+ onDownload: () => void;
48
+ onPrint: () => void;
49
+ downloadDisabled: boolean;
50
+ printDisabled: boolean;
19
51
  }
20
52
 
21
53
  interface ButtonProperties {
22
- ["aria-label"]: string;
23
- buttonStyles: string;
24
- onClick?: () => void;
25
- tabIndex?: number;
26
- iconStyles: string;
54
+ ['aria-label']: string;
55
+ buttonStyles: string;
56
+ onClick?: () => void;
57
+ tabIndex?: number;
58
+ iconStyles: string;
27
59
  }
28
60
 
29
61
  interface DownloadPrintMenuState {
30
- popoverOpen: boolean;
62
+ popoverOpen: boolean;
31
63
  }
32
64
 
33
65
  export class DownloadPrintMenu extends Component<DownloadPrintMenuProps, DownloadPrintMenuState> {
34
- static defaultProps = {
35
- dropdownAriaLabel: "Download or print current transcript",
36
- printButtonAriaLabel: "Print current transcript",
37
- downloadButtonAriaLabel: "Download current transcript"
38
- };
39
- state: DownloadPrintMenuState = {
40
- popoverOpen: false
41
- };
66
+ static defaultProps = {
67
+ dropdownAriaLabel: 'Download or print current transcript',
68
+ printButtonAriaLabel: 'Print current transcript',
69
+ downloadButtonAriaLabel: 'Download current transcript'
70
+ };
71
+ state: DownloadPrintMenuState = {
72
+ popoverOpen: false
73
+ };
42
74
 
43
- private _onDownloadClicked = () => {
44
- this.props.onDownload();
45
- };
75
+ private _onDownloadClicked = () => {
76
+ this.props.onDownload();
77
+ };
46
78
 
47
- private _onPrintClicked = () => {
48
- this.props.onPrint();
49
- };
50
- private _onKeyDown = (e: KeyboardEvent, callBack: Function) => {
51
- if (e.keyCode !== KeyboardKeys.Enter && e.keyCode !== KeyboardKeys.Esc) {
52
- // don't stopPropagation on ESC and Enter pressed as it prevent the popup closing
53
- e.stopPropagation();
54
- }
55
- switch (e.keyCode) {
56
- case 13: // Enter pressed
57
- callBack();
58
- break;
59
- }
60
- };
61
- private _popoverMenuItemRenderer = (el: PopoverMenuItem) => (
62
- <div
63
- tabIndex={1}
64
- role="button"
65
- onClick={() => el.onMenuChosen()}
66
- onKeyDown={(e: KeyboardEvent) => this._onKeyDown(e, el.onMenuChosen)}
67
- className={styles.popoverMenuItem}
68
- >
69
- {el.label}
70
- </div>
71
- );
79
+ private _onPrintClicked = () => {
80
+ this.props.onPrint();
81
+ };
82
+ private _onKeyDown = (e: KeyboardEvent, callBack: Function) => {
83
+ if (e.keyCode !== ENTER && e.keyCode !== Esc) {
84
+ // don't stopPropagation on ESC and Enter pressed as it prevent the popup closing
85
+ e.stopPropagation();
86
+ }
87
+ switch (e.keyCode) {
88
+ case 13: // Enter pressed
89
+ callBack();
90
+ break;
91
+ }
92
+ };
93
+ private _popoverMenuItemRenderer = (el: PopoverMenuItem) => (
94
+ <div
95
+ tabIndex={1}
96
+ role="button"
97
+ onClick={() => el.onMenuChosen()}
98
+ onKeyDown={(e: KeyboardEvent) => this._onKeyDown(e, el.onMenuChosen)}
99
+ className={styles.popoverMenuItem}
100
+ >
101
+ {el.label}
102
+ </div>
103
+ );
72
104
 
73
- private _getPopoverMenuOptions = () => {
74
- return [
75
- {
76
- label: this.props.downloadButtonAriaLabel,
77
- onMenuChosen: this._onDownloadClicked
78
- },
79
- {
80
- label: this.props.printButtonAriaLabel,
81
- onMenuChosen: this._onPrintClicked
82
- }
83
- ];
84
- };
105
+ private _getPopoverMenuOptions = () => {
106
+ return [
107
+ {
108
+ label: this.props.downloadButtonAriaLabel,
109
+ onMenuChosen: this._onDownloadClicked
110
+ },
111
+ {
112
+ label: this.props.printButtonAriaLabel,
113
+ onMenuChosen: this._onPrintClicked
114
+ }
115
+ ];
116
+ };
85
117
 
86
- private _renderIcon = ({
87
- buttonStyles,
88
- tabIndex = 1,
89
- iconStyles,
90
- ...props
91
- }: ButtonProperties): ComponentChild => {
92
- return (
93
- <button className={buttonStyles} tabIndex={tabIndex} {...props}>
94
- <div className={iconStyles} />
95
- </button>
96
- );
97
- };
118
+ private _renderIcon = ({buttonStyles, tabIndex = 0, iconStyles, ...props}: ButtonProperties): ComponentChild => {
119
+ return (
120
+ <button className={buttonStyles} tabIndex={tabIndex} {...props}>
121
+ <div className={iconStyles} />
122
+ </button>
123
+ );
124
+ };
98
125
 
99
- private _popoverContent = () => {
100
- return (
101
- <PopoverMenu
102
- itemRenderer={this._popoverMenuItemRenderer}
103
- options={this._getPopoverMenuOptions()}
104
- />
105
- );
106
- };
126
+ private _popoverContent = () => {
127
+ return <PopoverMenu itemRenderer={this._popoverMenuItemRenderer} options={this._getPopoverMenuOptions()} />;
128
+ };
107
129
 
108
- render(props: DownloadPrintMenuProps) {
109
- const { downloadDisabled, printDisabled } = props;
110
- if (!downloadDisabled && !printDisabled) {
111
- return (
112
- <Popover
113
- className="download-print-popover"
114
- verticalPosition={PopoverVerticalPositions.Bottom}
115
- horizontalPosition={PopoverHorizontalPositions.Left}
116
- content={this._popoverContent()}
117
- >
118
- {this._renderIcon({
119
- ["aria-label"]: props.dropdownAriaLabel,
120
- buttonStyles: styles.downloadPrintButton,
121
- iconStyles: [styles.icon, styles.downloadIcon].join(" ")
122
- })}
123
- </Popover>
124
- );
125
- }
126
- if (!downloadDisabled && printDisabled) {
127
- return this._renderIcon({
128
- ["aria-label"]: props.downloadButtonAriaLabel,
129
- buttonStyles: styles.downloadPrintButton,
130
- iconStyles: [styles.icon, styles.downloadIcon].join(" "),
131
- onClick: this._onDownloadClicked
132
- });
133
- }
134
- if (downloadDisabled && !printDisabled) {
135
- return this._renderIcon({
136
- ["aria-label"]: props.printButtonAriaLabel,
137
- buttonStyles: styles.downloadPrintButton,
138
- iconStyles: [styles.icon, styles.printIcon].join(" "),
139
- onClick: this._onPrintClicked
140
- });
141
- }
142
- return null;
130
+ render(props: DownloadPrintMenuProps) {
131
+ const {downloadDisabled, printDisabled} = props;
132
+ if (!downloadDisabled && !printDisabled) {
133
+ return (
134
+ <Popover
135
+ className="download-print-popover"
136
+ verticalPosition={PopoverVerticalPositions.Bottom}
137
+ horizontalPosition={PopoverHorizontalPositions.Left}
138
+ content={this._popoverContent()}
139
+ >
140
+ {this._renderIcon({
141
+ ['aria-label']: props.dropdownAriaLabel,
142
+ buttonStyles: styles.downloadPrintButton,
143
+ iconStyles: [styles.icon, styles.downloadIcon].join(' ')
144
+ })}
145
+ </Popover>
146
+ );
147
+ }
148
+ if (!downloadDisabled && printDisabled) {
149
+ return this._renderIcon({
150
+ ['aria-label']: props.downloadButtonAriaLabel,
151
+ buttonStyles: styles.downloadPrintButton,
152
+ iconStyles: [styles.icon, styles.downloadIcon].join(' '),
153
+ onClick: this._onDownloadClicked
154
+ });
155
+ }
156
+ if (downloadDisabled && !printDisabled) {
157
+ return this._renderIcon({
158
+ ['aria-label']: props.printButtonAriaLabel,
159
+ buttonStyles: styles.downloadPrintButton,
160
+ iconStyles: [styles.icon, styles.printIcon].join(' '),
161
+ onClick: this._onPrintClicked
162
+ });
143
163
  }
164
+ return null;
165
+ }
144
166
  }
@@ -1 +1 @@
1
- export * from './download-print-menu';
1
+ export * from './download-print-menu';
@@ -0,0 +1,11 @@
1
+ export namespace icons {
2
+ export const PLUGIN_ICON =
3
+ 'M23.1111111,19 C23.6020309,19 24,19.4477153 24,20 C24,20.5522847 23.6020309,21 23.1111111,21 L8.88888889,21 C8.39796911,21 8,20.5522847 8,20 C8,19.4477153 8.39796911,19 8.88888889,19 L23.1111111,19 Z M24.8695652,3 C26.5984566,3 28,4.24720677 28,5.78571429 L28,26.2142857 C28,27.7527932 26.5984566,29 24.8695652,29 L7.13043478,29 C5.40154339,29 4,27.7527932 4,26.2142857 L4,5.78571429 C4,4.24720677 5.40154339,3 7.13043478,3 L24.8695652,3 Z M26,17 L6,17 L6,26.0833333 C6,26.5895944 6.47127921,27 7.05263158,27 L24.9473684,27 C25.5287208,27 26,26.5895944 26,26.0833333 L26,17 Z M8.88888889,23 L23.1111111,23 C23.6020309,23 24,23.4477153 24,24 C24,24.5128358 23.6568532,24.9355072 23.2147743,24.9932723 L23.1111111,25 L8.88888889,25 C8.39796911,25 8,24.5522847 8,24 C8,23.4871642 8.34314684,23.0644928 8.78522567,23.0067277 L8.88888889,23 L23.1111111,23 L8.88888889,23 Z M24.9473684,5 L7.05263158,5 C6.47127921,5 6,5.41040565 6,5.91666667 L6,15 L26,15 L26,5.91666667 C26,5.41040565 25.5287208,5 24.9473684,5 Z';
4
+ export const CLOSE_ICON =
5
+ 'M17.9113162,16 L24.6072325,9.30408374 C25.1313645,8.77995172 25.1287183,7.92687249 24.6009229,7.3990771 C24.0694478,6.86760201 23.220227,6.86845682 22.6959163,7.39276754 L16,14.0886838 L9.30408374,7.39276754 C8.77995172,6.86863552 7.92687249,6.8712817 7.3990771,7.3990771 C6.86760201,7.93055219 6.86845682,8.77977302 7.39276754,9.30408374 L14.0886838,16 L7.39276754,22.6959163 C6.86863552,23.2200483 6.8712817,24.0731275 7.3990771,24.6009229 C7.93055219,25.132398 8.77977302,25.1315432 9.30408374,24.6072325 L16,17.9113162 L22.6959163,24.6072325 C23.2200483,25.1313645 24.0731275,25.1287183 24.6009229,24.6009229 C25.132398,24.0694478 25.1315432,23.220227 24.6072325,22.6959163 L17.9113162,16 Z';
6
+ export const SCROLL_ICON =
7
+ 'M11.7071 6.70711C11.3466 7.06759 10.7794 7.09532 10.3871 6.7903L10.2929 6.70711L6 2.415L1.70711 6.70711C1.34662 7.06759 0.779391 7.09532 0.3871 6.79029L0.292893 6.70711C-0.0675907 6.34662 -0.0953206 5.77939 0.209705 5.3871L0.292894 5.29289L5.29289 0.292893C5.65338 -0.0675913 6.22061 -0.0953212 6.6129 0.209704L6.70711 0.292893L11.7071 5.29289C12.0976 5.68342 12.0976 6.31658 11.7071 6.70711Z';
8
+ export const BigSize = 32;
9
+ export const MediumSize = 24;
10
+ export const SmallSize = 16;
11
+ }
@@ -0,0 +1,26 @@
1
+ @import '../../variables.scss';
2
+
3
+ .navigationPluginButton,
4
+ .navigationPluginIcon {
5
+ min-height: 36px;
6
+ min-width: 36px;
7
+ }
8
+
9
+ .pluginButton {
10
+ display: flex;
11
+ width: 36px;
12
+ height: 36px;
13
+ padding: 0;
14
+ background: transparent;
15
+ border: none;
16
+ border-radius: 4px;
17
+ cursor: pointer;
18
+ &.active {
19
+ background-color: $darken-gray;
20
+ }
21
+ }
22
+
23
+ // TODO: remove once core team fix alignment of plugin icons
24
+ :global(.playkit-player .playkit-top-bar .playkit-right-controls) {
25
+ display: flex;
26
+ }
@@ -0,0 +1,29 @@
1
+ import {h} from 'preact';
2
+ import * as styles from './plugin-button.scss';
3
+ import {icons} from '../icons';
4
+ import {A11yWrapper, OnClick} from '../a11y-wrapper';
5
+ const {Tooltip, Icon} = KalturaPlayer.ui.components;
6
+
7
+ interface PluginButtonProps {
8
+ isActive: boolean;
9
+ onClick: OnClick;
10
+ label?: string;
11
+ }
12
+
13
+ export const PluginButton = ({isActive, onClick, label}: PluginButtonProps) => {
14
+ return (
15
+ <Tooltip label={label} type="bottom">
16
+ <A11yWrapper onClick={onClick}>
17
+ <button aria-label={label} className={[styles.pluginButton, isActive ? styles.active : ''].join(' ')}>
18
+ <Icon
19
+ id="transcript-plugin-button"
20
+ height={icons.BigSize}
21
+ width={icons.BigSize}
22
+ viewBox={`0 0 ${icons.BigSize} ${icons.BigSize}`}
23
+ path={icons.PLUGIN_ICON}
24
+ />
25
+ </button>
26
+ </A11yWrapper>
27
+ </Tooltip>
28
+ );
29
+ };
@@ -1 +1 @@
1
- export * from './popover-menu';
1
+ export * from './popover-menu';
@@ -1,6 +1,6 @@
1
1
  @import '../../variables.scss';
2
2
 
3
3
  .popover-menu {
4
- padding-top: 6px;
5
- padding-bottom: 6px;
6
- }
4
+ padding-top: 6px;
5
+ padding-bottom: 6px;
6
+ }
@@ -1,15 +1,15 @@
1
- import { h, Component, ComponentChild } from "preact";
2
- import * as styles from "./popover-menu.scss";
1
+ import {h, Component, ComponentChild} from 'preact';
2
+ import * as styles from './popover-menu.scss';
3
3
 
4
4
  export interface PopoverMenuItem {
5
- label: string;
6
- onMenuChosen: Function;
7
- customRenderer?: (el: PopoverMenuItem) => ComponentChild;
5
+ label: string;
6
+ onMenuChosen: Function;
7
+ customRenderer?: (el: PopoverMenuItem) => ComponentChild;
8
8
  }
9
9
 
10
10
  interface PopoverMenuProps {
11
- options: Array<PopoverMenuItem>;
12
- itemRenderer?: (el: PopoverMenuItem) => ComponentChild;
11
+ options: Array<PopoverMenuItem>;
12
+ itemRenderer?: (el: PopoverMenuItem) => ComponentChild;
13
13
  }
14
14
 
15
15
  /**
@@ -30,23 +30,23 @@ interface PopoverMenuProps {
30
30
  */
31
31
 
32
32
  export class PopoverMenu extends Component<PopoverMenuProps> {
33
- render(props: any) {
34
- return (
35
- <div className={styles.popoverMenu}>
36
- {props.options.map((el: PopoverMenuItem) => {
37
- if (el.customRenderer) {
38
- return el.customRenderer(el);
39
- }
40
- if (props.itemRenderer) {
41
- return props.itemRenderer(el);
42
- }
43
- return (
44
- <div className="popover-menu-item" onClick={() => el.onMenuChosen(el)}>
45
- {el.label}
46
- </div>
47
- );
48
- })}
33
+ render(props: any) {
34
+ return (
35
+ <div className={styles.popoverMenu}>
36
+ {props.options.map((el: PopoverMenuItem) => {
37
+ if (el.customRenderer) {
38
+ return el.customRenderer(el);
39
+ }
40
+ if (props.itemRenderer) {
41
+ return props.itemRenderer(el);
42
+ }
43
+ return (
44
+ <div className="popover-menu-item" onClick={() => el.onMenuChosen(el)}>
45
+ {el.label}
49
46
  </div>
50
- );
51
- }
47
+ );
48
+ })}
49
+ </div>
50
+ );
51
+ }
52
52
  }
@@ -1 +1 @@
1
- export * from "./search";
1
+ export * from './search';
@@ -2,7 +2,7 @@
2
2
 
3
3
  .search-wrapper {
4
4
  ::-moz-placeholder {
5
- opacity: 1
5
+ opacity: 1;
6
6
  }
7
7
 
8
8
  display: flex;