@imposium-hub/components 1.38.16 → 1.39.0
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/Entry.ts +2 -0
- package/components/assets/AssetsTablePreviewCell.tsx +113 -0
- package/components/button-menu/ButtonMenu.tsx +11 -7
- package/components/dropdown/dropdown.tsx +5 -7
- package/components/players/ImagePreview.tsx +29 -3
- package/components/players/VideoPreview.tsx +28 -1
- package/dist/components.js +2 -2
- package/dist/components.js.map +1 -1
- package/dist/styles.css +1 -1
- package/dist/styles.css.map +1 -1
- package/dist/styles.less +14 -2
- package/dist/styles.less.map +1 -1
- package/less/components/assets.less +14 -2
- package/package.json +1 -1
package/Entry.ts
CHANGED
|
@@ -33,6 +33,7 @@ import NoAccess from './components/no-access/NoAccess';
|
|
|
33
33
|
import ServiceIcon from './components/service-icon/ServiceIcon';
|
|
34
34
|
import DeterminateLoader from './components/determinate-loader/DeterminateLoader';
|
|
35
35
|
import AssetsTableDateCell from './components/assets/AssetsTableDateCell';
|
|
36
|
+
import AssetsTablePreviewCell from './components/assets/AssetsTablePreviewCell';
|
|
36
37
|
import AssetsTableDurationCell from './components/assets/AssetsTableDurationCell';
|
|
37
38
|
import AssetField from './components/assets/AssetField';
|
|
38
39
|
import AssetsTableDropzone from './components/assets/AssetsTableDropzone';
|
|
@@ -163,6 +164,7 @@ export {
|
|
|
163
164
|
AssetsTypeIcon,
|
|
164
165
|
AssetsTableDateCell,
|
|
165
166
|
AssetsTableDropzone,
|
|
167
|
+
AssetsTablePreviewCell,
|
|
166
168
|
AssetsTableSelectFilter,
|
|
167
169
|
AssetsTableSelectCell,
|
|
168
170
|
AssetsTableTypeFilter,
|
|
@@ -0,0 +1,113 @@
|
|
|
1
|
+
import * as React from 'react';
|
|
2
|
+
import {ASSET_TYPES, VideoPreview, AssetsTypeIcon, ImagePreview} from '../../Entry';
|
|
3
|
+
export const PREVIEW_MAX_WIDTH : number = 400;
|
|
4
|
+
export const PREVIEW_MAX_HEIGHT : number = 400;
|
|
5
|
+
export const HEADER_HEIGHT : number = 30;
|
|
6
|
+
|
|
7
|
+
interface IAssetsTablePreviewCell {
|
|
8
|
+
cell : any;
|
|
9
|
+
showMedia : boolean;
|
|
10
|
+
onClick() : void;
|
|
11
|
+
onRequestClose() : void;
|
|
12
|
+
}
|
|
13
|
+
|
|
14
|
+
class AssetsTablePreviewCell extends React.PureComponent<IAssetsTablePreviewCell> {
|
|
15
|
+
private iconRef : any = React.createRef<HTMLDivElement>();
|
|
16
|
+
private evtHandlers : any;
|
|
17
|
+
constructor(props) {
|
|
18
|
+
super(props);
|
|
19
|
+
this.evtHandlers = {
|
|
20
|
+
onClose: () => this.handleClose(),
|
|
21
|
+
onClick: () => this.handlePreviewClick()
|
|
22
|
+
};
|
|
23
|
+
}
|
|
24
|
+
|
|
25
|
+
private handleClose() {
|
|
26
|
+
const {onRequestClose} = this.props;
|
|
27
|
+
onRequestClose();
|
|
28
|
+
}
|
|
29
|
+
|
|
30
|
+
private handlePreviewClick() {
|
|
31
|
+
const {onClick, showMedia} = this.props;
|
|
32
|
+
if (!showMedia) {
|
|
33
|
+
onClick();
|
|
34
|
+
return;
|
|
35
|
+
}
|
|
36
|
+
return;
|
|
37
|
+
}
|
|
38
|
+
|
|
39
|
+
public render() {
|
|
40
|
+
|
|
41
|
+
const getMediaPreviewStyle = (mediaWidth : number, mediaHeight : number) => {
|
|
42
|
+
|
|
43
|
+
if (!this.iconRef.current) {
|
|
44
|
+
return;
|
|
45
|
+
}
|
|
46
|
+
if (!mediaWidth) {
|
|
47
|
+
mediaWidth = PREVIEW_MAX_WIDTH;
|
|
48
|
+
}
|
|
49
|
+
if (!mediaHeight) {
|
|
50
|
+
mediaHeight = PREVIEW_MAX_HEIGHT;
|
|
51
|
+
}
|
|
52
|
+
const icon = this.iconRef.current;
|
|
53
|
+
const iconRect = icon.getBoundingClientRect();
|
|
54
|
+
const aspect = mediaWidth / mediaHeight;
|
|
55
|
+
let width = PREVIEW_MAX_WIDTH;
|
|
56
|
+
let height = width / aspect;
|
|
57
|
+
|
|
58
|
+
if (height > PREVIEW_MAX_HEIGHT) {
|
|
59
|
+
height = PREVIEW_MAX_HEIGHT;
|
|
60
|
+
width = height * aspect;
|
|
61
|
+
}
|
|
62
|
+
|
|
63
|
+
// try top left
|
|
64
|
+
let left = iconRect.x + iconRect.width - width;
|
|
65
|
+
let top = iconRect.y + iconRect.height - height - 20;
|
|
66
|
+
// if the preview is off on the left, switch to the right of the icon
|
|
67
|
+
if (left < 0) {
|
|
68
|
+
left = iconRect.x ;
|
|
69
|
+
}
|
|
70
|
+
// if the preview is off on the top, switch to bottom of the icon
|
|
71
|
+
if (top < HEADER_HEIGHT) {
|
|
72
|
+
top = iconRect.y + 20;
|
|
73
|
+
}
|
|
74
|
+
|
|
75
|
+
return {top, left, width, height, position: 'absolute', zIndex: 9000} as React.CSSProperties;
|
|
76
|
+
};
|
|
77
|
+
|
|
78
|
+
const {cell, showMedia} = this.props;
|
|
79
|
+
const playbackSettings = {
|
|
80
|
+
autoPlay: true,
|
|
81
|
+
loop: false
|
|
82
|
+
};
|
|
83
|
+
|
|
84
|
+
return(
|
|
85
|
+
<div ref = {this.iconRef} className = 'asset-type-cell' onClick={this.evtHandlers.onClick} >
|
|
86
|
+
<AssetsTypeIcon type = {cell.row.values.type} />
|
|
87
|
+
{cell.row.values.type === ASSET_TYPES.IMAGE &&
|
|
88
|
+
(
|
|
89
|
+
<ImagePreview
|
|
90
|
+
style={{...getMediaPreviewStyle(cell.row.original.width, cell.row.original.height)}}
|
|
91
|
+
showMedia={showMedia}
|
|
92
|
+
url={cell.row.original.url}
|
|
93
|
+
onRequestClose={this.evtHandlers.onClose}
|
|
94
|
+
/>
|
|
95
|
+
)
|
|
96
|
+
}
|
|
97
|
+
{cell.row.values.type === ASSET_TYPES.VIDEO &&
|
|
98
|
+
(<VideoPreview
|
|
99
|
+
playbackSettings={playbackSettings}
|
|
100
|
+
style={getMediaPreviewStyle(cell.row.original.width, cell.row.original.height)}
|
|
101
|
+
showMedia={showMedia}
|
|
102
|
+
url={cell.row.original.url}
|
|
103
|
+
onRequestClose={this.evtHandlers.onClose}
|
|
104
|
+
/>
|
|
105
|
+
)
|
|
106
|
+
}
|
|
107
|
+
</div>
|
|
108
|
+
);
|
|
109
|
+
}
|
|
110
|
+
}
|
|
111
|
+
|
|
112
|
+
const AssetsTablePreviewCellMemoized = React.memo(AssetsTablePreviewCell);
|
|
113
|
+
export default AssetsTablePreviewCellMemoized;
|
|
@@ -14,6 +14,7 @@ interface IButtonMenuState {
|
|
|
14
14
|
class ButtonMenu extends React.PureComponent<IButtonMenuProps, IButtonMenuState> {
|
|
15
15
|
|
|
16
16
|
private evtHandlers : any;
|
|
17
|
+
private toggleRef : any;
|
|
17
18
|
|
|
18
19
|
constructor(props) {
|
|
19
20
|
|
|
@@ -26,15 +27,20 @@ class ButtonMenu extends React.PureComponent<IButtonMenuProps, IButtonMenuState>
|
|
|
26
27
|
toggleMenu: (e) => this.toggleMenu(e),
|
|
27
28
|
clickOutside: (e) => this.handleClickOutside(e)
|
|
28
29
|
};
|
|
30
|
+
|
|
31
|
+
this.toggleRef = React.createRef();
|
|
29
32
|
}
|
|
30
33
|
|
|
31
34
|
private handleClickOutside(e) {
|
|
32
35
|
|
|
33
|
-
|
|
36
|
+
const clickOnToggle = (this.toggleRef && this.toggleRef.current && this.toggleRef.current.contains(e.target)) ? true : false;
|
|
34
37
|
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
+
if (!clickOnToggle) {
|
|
39
|
+
document.removeEventListener('click', this.evtHandlers.clickOutside);
|
|
40
|
+
this.setState({
|
|
41
|
+
open: false
|
|
42
|
+
});
|
|
43
|
+
}
|
|
38
44
|
}
|
|
39
45
|
|
|
40
46
|
public componentWillUnmount() {
|
|
@@ -44,9 +50,6 @@ class ButtonMenu extends React.PureComponent<IButtonMenuProps, IButtonMenuState>
|
|
|
44
50
|
|
|
45
51
|
public toggleMenu(e) {
|
|
46
52
|
|
|
47
|
-
e.preventDefault();
|
|
48
|
-
e.stopPropagation();
|
|
49
|
-
|
|
50
53
|
const newState = !this.state.open;
|
|
51
54
|
|
|
52
55
|
this.setState({
|
|
@@ -106,6 +109,7 @@ class ButtonMenu extends React.PureComponent<IButtonMenuProps, IButtonMenuState>
|
|
|
106
109
|
|
|
107
110
|
// Clone the trigger button passed in and add an onClick listener
|
|
108
111
|
const trigger = React.cloneElement(button, {
|
|
112
|
+
buttonRef: this.toggleRef,
|
|
109
113
|
onClick: this.evtHandlers.toggleMenu,
|
|
110
114
|
active: open
|
|
111
115
|
});
|
|
@@ -71,7 +71,6 @@ export default class ImposiumDropdown extends React.PureComponent<IDropdownMenuP
|
|
|
71
71
|
}
|
|
72
72
|
|
|
73
73
|
private onEsc = (e : any) : void => {
|
|
74
|
-
const {onOutsideClick} = this.props;
|
|
75
74
|
|
|
76
75
|
if (e.keyCode === ImposiumDropdown.ESC_CODE) {
|
|
77
76
|
this.cancelRender(true);
|
|
@@ -79,14 +78,13 @@ export default class ImposiumDropdown extends React.PureComponent<IDropdownMenuP
|
|
|
79
78
|
}
|
|
80
79
|
|
|
81
80
|
private detectOutsideClick = (e : any) : void => {
|
|
82
|
-
const {toggleRef
|
|
81
|
+
const {toggleRef} = this.props;
|
|
83
82
|
const {target} = e;
|
|
84
83
|
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
) {
|
|
84
|
+
const clickInside = (this.dropdownRef.current && this.dropdownRef.current.contains(target)) ? true : false;
|
|
85
|
+
const clickOnToggle = (toggleRef && toggleRef.current && toggleRef.current.contains(target)) ? true : false;
|
|
86
|
+
|
|
87
|
+
if (!clickInside && !clickOnToggle) {
|
|
90
88
|
this.cancelRender(true);
|
|
91
89
|
}
|
|
92
90
|
}
|
|
@@ -1,29 +1,55 @@
|
|
|
1
1
|
import * as React from 'react';
|
|
2
2
|
import Portal from '../portal/Portal';
|
|
3
|
-
|
|
3
|
+
import {ICON_TIMES} from '../../constants/icons';
|
|
4
|
+
import Button from '../button/Button';
|
|
5
|
+
import {assets as copy} from '../../constants/copy';
|
|
4
6
|
interface IVideoPreviewProps {
|
|
5
7
|
showMedia : boolean;
|
|
6
8
|
url : string;
|
|
7
9
|
playbackSettings? : any;
|
|
8
10
|
style? : React.CSSProperties | any;
|
|
11
|
+
onRequestClose?(e) : void;
|
|
9
12
|
}
|
|
10
13
|
|
|
11
14
|
class ImagePreview extends React.PureComponent<IVideoPreviewProps> {
|
|
12
15
|
private imageNode : any = null;
|
|
16
|
+
private evtHandlers : any;
|
|
13
17
|
constructor(props) {
|
|
14
18
|
super(props);
|
|
15
19
|
this.imageNode = React.createRef();
|
|
20
|
+
this.evtHandlers = {
|
|
21
|
+
onClose: (e) => this.onClose(e)
|
|
22
|
+
};
|
|
23
|
+
}
|
|
24
|
+
|
|
25
|
+
private onClose(e) {
|
|
26
|
+
|
|
27
|
+
const {onRequestClose} = this.props;
|
|
28
|
+
|
|
29
|
+
onRequestClose(e);
|
|
16
30
|
}
|
|
17
31
|
public render() {
|
|
18
32
|
const {showMedia, url, style} = this.props;
|
|
19
33
|
if (showMedia) {
|
|
20
34
|
return (
|
|
21
35
|
<Portal id='portal-root'>
|
|
36
|
+
<div style={{...style}} className={'close-icon-preview'}>
|
|
37
|
+
<Button
|
|
38
|
+
key = 'btn-filter'
|
|
39
|
+
onClick = {this.evtHandlers.onClose}
|
|
40
|
+
size={'large'}
|
|
41
|
+
style = 'subtle'
|
|
42
|
+
tooltip = {copy.field.tooltipFilter}
|
|
43
|
+
>
|
|
44
|
+
{ICON_TIMES}
|
|
45
|
+
</Button>
|
|
46
|
+
</div>
|
|
22
47
|
<img
|
|
23
48
|
src={url}
|
|
24
49
|
ref={this.imageNode}
|
|
25
|
-
className='
|
|
26
|
-
style={style}
|
|
50
|
+
className='asset-preview-background'
|
|
51
|
+
style={style}
|
|
52
|
+
/>
|
|
27
53
|
</Portal>
|
|
28
54
|
);
|
|
29
55
|
} else {
|
|
@@ -1,24 +1,50 @@
|
|
|
1
1
|
import * as React from 'react';
|
|
2
2
|
import Portal from '../portal/Portal';
|
|
3
|
+
import Button from '../button/Button';
|
|
4
|
+
import {assets as copy} from '../../constants/copy';
|
|
5
|
+
import {ICON_TIMES} from '../../constants/icons';
|
|
3
6
|
|
|
4
7
|
interface IVideoPreviewProps {
|
|
5
8
|
showMedia : boolean;
|
|
6
9
|
url : string;
|
|
7
10
|
playbackSettings? : any;
|
|
8
11
|
style? : React.CSSProperties | {};
|
|
12
|
+
onRequestClose?(e) : void;
|
|
9
13
|
}
|
|
10
14
|
|
|
11
15
|
class VideoPreview extends React.PureComponent<IVideoPreviewProps> {
|
|
12
16
|
private videoNode : any = null;
|
|
17
|
+
private evtHandlers : any;
|
|
13
18
|
constructor(props) {
|
|
14
19
|
super(props);
|
|
15
20
|
this.videoNode = React.createRef();
|
|
21
|
+
this.evtHandlers = {
|
|
22
|
+
onClose: (e) => this.onClose(e)
|
|
23
|
+
};
|
|
24
|
+
}
|
|
25
|
+
|
|
26
|
+
private onClose(e) {
|
|
27
|
+
|
|
28
|
+
const {onRequestClose} = this.props;
|
|
29
|
+
|
|
30
|
+
onRequestClose(e);
|
|
16
31
|
}
|
|
17
32
|
public render() {
|
|
18
33
|
const {showMedia, url, playbackSettings, style} = this.props;
|
|
19
34
|
if (showMedia) {
|
|
20
35
|
return (
|
|
21
36
|
<Portal id='portal-root'>
|
|
37
|
+
<div style={{...style}} className={'close-icon-preview'}>
|
|
38
|
+
<Button
|
|
39
|
+
key = 'btn-filter'
|
|
40
|
+
onClick = {this.evtHandlers.onClose}
|
|
41
|
+
size={'large'}
|
|
42
|
+
style = 'subtle'
|
|
43
|
+
tooltip = {copy.field.tooltipFilter}
|
|
44
|
+
>
|
|
45
|
+
{ICON_TIMES}
|
|
46
|
+
</Button>
|
|
47
|
+
</div>
|
|
22
48
|
<video
|
|
23
49
|
style = {style}
|
|
24
50
|
muted
|
|
@@ -28,7 +54,8 @@ class VideoPreview extends React.PureComponent<IVideoPreviewProps> {
|
|
|
28
54
|
controls
|
|
29
55
|
preload = 'preload'
|
|
30
56
|
src={url}
|
|
31
|
-
className='
|
|
57
|
+
className='asset-preview-background'
|
|
58
|
+
/>
|
|
32
59
|
</Portal>
|
|
33
60
|
);
|
|
34
61
|
} else {
|