@imposium-hub/components 1.63.0 → 2.0.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.
Files changed (81) hide show
  1. package/dist/cjs/components/assets/AssetsTablePreviewCell.js +3 -3
  2. package/dist/cjs/components/assets/AssetsTablePreviewCell.js.map +1 -1
  3. package/dist/cjs/components/button/Button.stories.d.ts +0 -1
  4. package/dist/cjs/components/button-group-field/ButtonGroupField.stories.d.ts +0 -1
  5. package/dist/cjs/components/button-menu/ButtonMenu.stories.d.ts +0 -1
  6. package/dist/cjs/components/card/Card.stories.d.ts +0 -1
  7. package/dist/cjs/components/checkbox-field/CheckboxField.stories.d.ts +0 -1
  8. package/dist/cjs/components/color-field/ColorFiled.stories.d.ts +0 -1
  9. package/dist/cjs/components/controlled-list/ControlledList.stories.d.ts +0 -1
  10. package/dist/cjs/components/error-message-preview/ErrorMessagePreview.d.ts +15 -0
  11. package/dist/cjs/components/error-message-preview/ErrorMessagePreview.js +91 -0
  12. package/dist/cjs/components/error-message-preview/ErrorMessagePreview.js.map +1 -0
  13. package/dist/cjs/components/field-wrapper/FieldWrapper.stories.d.ts +0 -1
  14. package/dist/cjs/components/h-rule/HRule.d.ts +0 -1
  15. package/dist/cjs/components/h-rule/HRule.stories.d.ts +0 -1
  16. package/dist/cjs/components/list-field/ListField.stories.d.ts +0 -1
  17. package/dist/cjs/components/modal/Modal.stories.d.ts +0 -1
  18. package/dist/cjs/components/number-field/NumberField.stories.d.ts +0 -1
  19. package/dist/cjs/components/players/AudioPreview.d.ts +12 -3
  20. package/dist/cjs/components/players/AudioPreview.js +32 -9
  21. package/dist/cjs/components/players/AudioPreview.js.map +1 -1
  22. package/dist/cjs/components/players/ImagePreview.d.ts +7 -1
  23. package/dist/cjs/components/players/ImagePreview.js +28 -10
  24. package/dist/cjs/components/players/ImagePreview.js.map +1 -1
  25. package/dist/cjs/components/players/VideoPreview.d.ts +11 -2
  26. package/dist/cjs/components/players/VideoPreview.js +32 -9
  27. package/dist/cjs/components/players/VideoPreview.js.map +1 -1
  28. package/dist/cjs/components/section/Section.d.ts +0 -1
  29. package/dist/cjs/components/section/Section.stories.d.ts +0 -1
  30. package/dist/cjs/components/select-field/SelectField.stories.d.ts +0 -1
  31. package/dist/cjs/components/slider-field/SliderField.stories.d.ts +0 -1
  32. package/dist/cjs/components/text-area-field/TextAreaField.stories.d.ts +0 -1
  33. package/dist/cjs/components/text-field/TextField.stories.d.ts +0 -1
  34. package/dist/cjs/utils/assets.d.ts +1 -1
  35. package/dist/cjs/utils/assets.js +7 -4
  36. package/dist/cjs/utils/assets.js.map +1 -1
  37. package/dist/esm/components/assets/AssetsTablePreviewCell.js +4 -4
  38. package/dist/esm/components/assets/AssetsTablePreviewCell.js.map +1 -1
  39. package/dist/esm/components/button/Button.stories.d.ts +0 -1
  40. package/dist/esm/components/button-group-field/ButtonGroupField.stories.d.ts +0 -1
  41. package/dist/esm/components/button-menu/ButtonMenu.stories.d.ts +0 -1
  42. package/dist/esm/components/card/Card.stories.d.ts +0 -1
  43. package/dist/esm/components/checkbox-field/CheckboxField.stories.d.ts +0 -1
  44. package/dist/esm/components/color-field/ColorFiled.stories.d.ts +0 -1
  45. package/dist/esm/components/controlled-list/ControlledList.stories.d.ts +0 -1
  46. package/dist/esm/components/error-message-preview/ErrorMessagePreview.d.ts +15 -0
  47. package/dist/esm/components/error-message-preview/ErrorMessagePreview.js +35 -0
  48. package/dist/esm/components/error-message-preview/ErrorMessagePreview.js.map +1 -0
  49. package/dist/esm/components/field-wrapper/FieldWrapper.stories.d.ts +0 -1
  50. package/dist/esm/components/h-rule/HRule.d.ts +0 -1
  51. package/dist/esm/components/h-rule/HRule.stories.d.ts +0 -1
  52. package/dist/esm/components/list-field/ListField.stories.d.ts +0 -1
  53. package/dist/esm/components/modal/Modal.stories.d.ts +0 -1
  54. package/dist/esm/components/number-field/NumberField.stories.d.ts +0 -1
  55. package/dist/esm/components/players/AudioPreview.d.ts +12 -3
  56. package/dist/esm/components/players/AudioPreview.js +31 -9
  57. package/dist/esm/components/players/AudioPreview.js.map +1 -1
  58. package/dist/esm/components/players/ImagePreview.d.ts +7 -1
  59. package/dist/esm/components/players/ImagePreview.js +28 -10
  60. package/dist/esm/components/players/ImagePreview.js.map +1 -1
  61. package/dist/esm/components/players/VideoPreview.d.ts +11 -2
  62. package/dist/esm/components/players/VideoPreview.js +31 -9
  63. package/dist/esm/components/players/VideoPreview.js.map +1 -1
  64. package/dist/esm/components/section/Section.d.ts +0 -1
  65. package/dist/esm/components/section/Section.stories.d.ts +0 -1
  66. package/dist/esm/components/select-field/SelectField.stories.d.ts +0 -1
  67. package/dist/esm/components/slider-field/SliderField.stories.d.ts +0 -1
  68. package/dist/esm/components/text-area-field/TextAreaField.stories.d.ts +0 -1
  69. package/dist/esm/components/text-field/TextField.stories.d.ts +0 -1
  70. package/dist/esm/utils/assets.d.ts +1 -1
  71. package/dist/esm/utils/assets.js +7 -4
  72. package/dist/esm/utils/assets.js.map +1 -1
  73. package/dist/styles.css +8 -0
  74. package/dist/styles.less +9 -0
  75. package/less/components/assets.less +10 -0
  76. package/package.json +1 -1
  77. package/src/components/assets/AssetsTablePreviewCell.tsx +3 -6
  78. package/src/components/players/AudioPreview.tsx +58 -13
  79. package/src/components/players/ImagePreview.tsx +47 -15
  80. package/src/components/players/VideoPreview.tsx +58 -12
  81. package/src/utils/assets.ts +8 -4
@@ -55,7 +55,7 @@ class AssetsTablePreviewCell extends React.PureComponent<IAssetsTablePreviewCell
55
55
  className='asset-type-cell'
56
56
  onClick={this.evtHandlers.onClick}>
57
57
  <AssetsTypeIcon type={cell.row.values.type} />
58
- {cell.row.values.type === ASSET_TYPES.IMAGE && (
58
+ {cell.row.values.type === ASSET_TYPES.IMAGE && showMedia && (
59
59
  <ImagePreview
60
60
  style={{
61
61
  ...getMediaPreviewStyle(
@@ -64,12 +64,11 @@ class AssetsTablePreviewCell extends React.PureComponent<IAssetsTablePreviewCell
64
64
  this.iconRef
65
65
  )
66
66
  }}
67
- showMedia={showMedia}
68
67
  url={cell.row.original.url}
69
68
  onRequestClose={this.evtHandlers.onClose}
70
69
  />
71
70
  )}
72
- {cell.row.values.type === ASSET_TYPES.VIDEO && (
71
+ {cell.row.values.type === ASSET_TYPES.VIDEO && showMedia && (
73
72
  <VideoPreview
74
73
  playbackSettings={playbackSettings}
75
74
  style={getMediaPreviewStyle(
@@ -77,16 +76,14 @@ class AssetsTablePreviewCell extends React.PureComponent<IAssetsTablePreviewCell
77
76
  cell.row.original.height,
78
77
  this.iconRef
79
78
  )}
80
- showMedia={showMedia}
81
79
  url={cell.row.original.url}
82
80
  onRequestClose={this.evtHandlers.onClose}
83
81
  />
84
82
  )}
85
- {cell.row.values.type === ASSET_TYPES.AUDIO && (
83
+ {cell.row.values.type === ASSET_TYPES.AUDIO && showMedia && (
86
84
  <AudioPreview
87
85
  playbackSettings={playbackSettings}
88
86
  style={getMediaPreviewStyle(5, 1, this.iconRef)}
89
- showMedia={showMedia}
90
87
  url={cell.row.original.url}
91
88
  onRequestClose={this.evtHandlers.onClose}
92
89
  />
@@ -4,38 +4,76 @@ import Button from '../button/Button';
4
4
  import { assets as copy } from '../../constants/copy';
5
5
  import { ICON_TIMES } from '../../constants/icons';
6
6
 
7
- interface IVideoPreviewProps {
8
- showMedia: boolean;
7
+ interface IAudioPreviewProps {
9
8
  url: string;
10
9
  playbackSettings?: any;
11
10
  style?: React.CSSProperties | any;
12
11
  onRequestClose?(): void;
13
12
  }
14
13
 
15
- class AudioPreview extends React.PureComponent<IVideoPreviewProps> {
14
+ interface IAudioPreviewState {
15
+ error: boolean;
16
+ loaded: boolean;
17
+ }
18
+
19
+ class AudioPreview extends React.PureComponent<IAudioPreviewProps, IAudioPreviewState> {
16
20
  private audioNode: any = null;
17
21
 
22
+ private audioRef: any = null;
23
+
18
24
  private evtHandlers: any;
19
25
 
26
+ private clickHandler: any = (e) => this.detectOutsideClick(e);
27
+
28
+ private clickOutsideTimeout: any;
29
+
20
30
  constructor(props) {
21
31
  super(props);
22
32
  this.audioNode = React.createRef();
33
+ this.audioRef = React.createRef();
23
34
  this.evtHandlers = {
24
35
  onClose: (e) => this.onClose(e)
25
36
  };
37
+ this.state = {
38
+ error: false,
39
+ loaded: false
40
+ };
41
+ }
42
+
43
+ public componentDidMount() {
44
+ clearTimeout(this.clickOutsideTimeout);
45
+ this.clickOutsideTimeout = setTimeout(() => {
46
+ window.addEventListener('click', this.clickHandler);
47
+ }, 25);
26
48
  }
27
49
 
50
+ public componentWillUnmount(): void {
51
+ clearTimeout(this.clickOutsideTimeout);
52
+ window.removeEventListener('click', this.clickHandler);
53
+ }
54
+
55
+ private detectOutsideClick = (e: any): void => {
56
+ const { target } = e;
57
+
58
+ const clickInside =
59
+ this.audioRef.current && this.audioRef.current.contains(target) ? true : false;
60
+
61
+ if (!clickInside) {
62
+ this.onClose(e);
63
+ }
64
+ };
65
+
28
66
  private onClose(e) {
29
67
  const { onRequestClose } = this.props;
30
- e.stopPropagation();
31
68
  onRequestClose();
32
69
  }
33
70
 
34
71
  public render() {
35
- const { showMedia, url, playbackSettings, style } = this.props;
36
- if (showMedia) {
37
- return (
38
- <Portal id='portal-root'>
72
+ const { url, playbackSettings, style } = this.props;
73
+ const { error } = this.state;
74
+ return (
75
+ <Portal id='portal-root'>
76
+ <div ref={this.audioRef}>
39
77
  <div
40
78
  style={{ ...style }}
41
79
  className={'close-icon-preview'}>
@@ -50,6 +88,8 @@ class AudioPreview extends React.PureComponent<IVideoPreviewProps> {
50
88
  </div>
51
89
  <audio
52
90
  style={style}
91
+ onError={() => this.setState({ loaded: true, error: true })}
92
+ onCanPlayThrough={() => this.setState({ loaded: true })}
53
93
  ref={this.audioNode}
54
94
  autoPlay={playbackSettings.autoPlay}
55
95
  loop={playbackSettings.loop}
@@ -57,11 +97,16 @@ class AudioPreview extends React.PureComponent<IVideoPreviewProps> {
57
97
  src={url}
58
98
  className='asset-preview-background media-preview'
59
99
  />
60
- </Portal>
61
- );
62
- } else {
63
- return null;
64
- }
100
+ {error ? (
101
+ <div
102
+ className='error-preview audio'
103
+ style={style}>
104
+ Audio not found
105
+ </div>
106
+ ) : null}
107
+ </div>
108
+ </Portal>
109
+ );
65
110
  }
66
111
  }
67
112
 
@@ -4,7 +4,6 @@ import { ICON_TIMES } from '../../constants/icons';
4
4
  import Button from '../button/Button';
5
5
  import { assets as copy } from '../../constants/copy';
6
6
  interface IImagePreviewProps {
7
- showMedia: boolean;
8
7
  url: string;
9
8
  playbackSettings?: any;
10
9
  style?: React.CSSProperties | any;
@@ -12,37 +11,66 @@ interface IImagePreviewProps {
12
11
  }
13
12
 
14
13
  interface IImagePreviewState {
14
+ error: boolean;
15
15
  loaded: boolean;
16
16
  }
17
17
 
18
18
  class ImagePreview extends React.PureComponent<IImagePreviewProps, IImagePreviewState> {
19
19
  private imageNode: any = null;
20
20
 
21
+ private imageRef: any = null;
22
+
21
23
  private evtHandlers: any;
22
24
 
25
+ private clickHandler: any = (e) => this.detectOutsideClick(e);
26
+
27
+ private clickOutsideTimeout: any;
28
+
23
29
  constructor(props) {
24
30
  super(props);
25
31
  this.imageNode = React.createRef();
32
+ this.imageRef = React.createRef();
26
33
  this.evtHandlers = {
27
34
  onClose: (e) => this.onClose(e)
28
35
  };
29
36
  this.state = {
37
+ error: false,
30
38
  loaded: false
31
39
  };
32
40
  }
33
41
 
42
+ public componentDidMount() {
43
+ clearTimeout(this.clickOutsideTimeout);
44
+ this.clickOutsideTimeout = setTimeout(() => {
45
+ window.addEventListener('click', this.clickHandler);
46
+ }, 25);
47
+ }
48
+
49
+ public componentWillUnmount(): void {
50
+ clearTimeout(this.clickOutsideTimeout);
51
+ window.removeEventListener('click', this.clickHandler);
52
+ }
53
+
54
+ private detectOutsideClick = (e: any): void => {
55
+ const { target } = e;
56
+ const clickInside =
57
+ this.imageRef.current && this.imageRef.current.contains(target) ? true : false;
58
+ if (!clickInside) {
59
+ this.onClose(e);
60
+ }
61
+ };
62
+
34
63
  private onClose(e) {
35
64
  const { onRequestClose } = this.props;
36
- e.stopPropagation();
37
65
  onRequestClose();
38
66
  }
39
67
 
40
68
  public render() {
41
- const { showMedia, url, style } = this.props;
42
- const { loaded } = this.state;
43
- if (showMedia) {
44
- return (
45
- <Portal id='portal-root'>
69
+ const { url, style } = this.props;
70
+ const { error } = this.state;
71
+ return (
72
+ <Portal id='portal-root'>
73
+ <div ref={this.imageRef}>
46
74
  <div
47
75
  style={{ ...style }}
48
76
  className={'close-icon-preview'}>
@@ -56,19 +84,23 @@ class ImagePreview extends React.PureComponent<IImagePreviewProps, IImagePreview
56
84
  </Button>
57
85
  </div>
58
86
  <img
87
+ onError={() => this.setState({ error: true, loaded: true })}
59
88
  onLoad={() => this.setState({ loaded: true })}
60
89
  src={url}
61
90
  ref={this.imageNode}
62
- className={`asset-preview-background media-preview ${
63
- !loaded ? 'hidden' : ''
64
- }`}
91
+ className={`asset-preview-background media-preview`}
65
92
  style={style}
66
93
  />
67
- </Portal>
68
- );
69
- } else {
70
- return null;
71
- }
94
+ {error ? (
95
+ <div
96
+ className='error-preview'
97
+ style={style}>
98
+ Image not found
99
+ </div>
100
+ ) : null}
101
+ </div>
102
+ </Portal>
103
+ );
72
104
  }
73
105
  }
74
106
 
@@ -5,37 +5,76 @@ import { assets as copy } from '../../constants/copy';
5
5
  import { ICON_TIMES } from '../../constants/icons';
6
6
 
7
7
  interface IVideoPreviewProps {
8
- showMedia: boolean;
9
8
  url: string;
10
9
  playbackSettings?: any;
11
10
  style?: React.CSSProperties | any;
12
11
  onRequestClose?(): void;
13
12
  }
14
13
 
15
- class VideoPreview extends React.PureComponent<IVideoPreviewProps> {
14
+ interface IVideoPreviewState {
15
+ error: boolean;
16
+ loaded: boolean;
17
+ }
18
+
19
+ class VideoPreview extends React.PureComponent<IVideoPreviewProps, IVideoPreviewState> {
16
20
  private videoNode: any = null;
17
21
 
22
+ private videoRef: any = null;
23
+
18
24
  private evtHandlers: any;
19
25
 
26
+ private clickHandler: any = (e) => this.detectOutsideClick(e);
27
+
28
+ private clickOutsideTimeout: any;
29
+
20
30
  constructor(props) {
21
31
  super(props);
22
32
  this.videoNode = React.createRef();
33
+ this.videoRef = React.createRef();
23
34
  this.evtHandlers = {
24
35
  onClose: (e) => this.onClose(e)
25
36
  };
37
+
38
+ this.state = {
39
+ error: false,
40
+ loaded: false
41
+ };
42
+ }
43
+
44
+ public componentDidMount() {
45
+ clearTimeout(this.clickOutsideTimeout);
46
+ this.clickOutsideTimeout = setTimeout(() => {
47
+ window.addEventListener('click', this.clickHandler);
48
+ }, 25);
49
+ }
50
+
51
+ public componentWillUnmount(): void {
52
+ clearTimeout(this.clickOutsideTimeout);
53
+ window.removeEventListener('click', this.clickHandler);
26
54
  }
27
55
 
56
+ private detectOutsideClick = (e: any): void => {
57
+ const { target } = e;
58
+
59
+ const clickInside =
60
+ this.videoRef.current && this.videoRef.current.contains(target) ? true : false;
61
+
62
+ if (!clickInside) {
63
+ this.onClose(e);
64
+ }
65
+ };
66
+
28
67
  private onClose(e) {
29
68
  const { onRequestClose } = this.props;
30
- e.stopPropagation();
31
69
  onRequestClose();
32
70
  }
33
71
 
34
72
  public render() {
35
- const { showMedia, url, playbackSettings, style } = this.props;
36
- if (showMedia) {
37
- return (
38
- <Portal id='portal-root'>
73
+ const { url, playbackSettings, style } = this.props;
74
+ const { error } = this.state;
75
+ return (
76
+ <Portal id='portal-root'>
77
+ <div ref={this.videoRef}>
39
78
  <div
40
79
  style={{ ...style }}
41
80
  className={'close-icon-preview'}>
@@ -49,6 +88,8 @@ class VideoPreview extends React.PureComponent<IVideoPreviewProps> {
49
88
  </Button>
50
89
  </div>
51
90
  <video
91
+ onError={() => this.setState({ error: true, loaded: true })}
92
+ onCanPlayThrough={() => this.setState({ loaded: true })}
52
93
  style={style}
53
94
  muted
54
95
  ref={this.videoNode}
@@ -60,11 +101,16 @@ class VideoPreview extends React.PureComponent<IVideoPreviewProps> {
60
101
  src={url}
61
102
  className='asset-preview-background media-preview'
62
103
  />
63
- </Portal>
64
- );
65
- } else {
66
- return null;
67
- }
104
+ {error ? (
105
+ <div
106
+ className='error-preview'
107
+ style={style}>
108
+ Video not found
109
+ </div>
110
+ ) : null}
111
+ </div>
112
+ </Portal>
113
+ );
68
114
  }
69
115
  }
70
116
 
@@ -4,9 +4,9 @@ import { CSSProperties } from 'react';
4
4
  export const getMediaPreviewStyle = (
5
5
  mediaWidth: number,
6
6
  mediaHeight: number,
7
- ref: any
7
+ element: any
8
8
  ): CSSProperties => {
9
- if (!ref.current) {
9
+ if (!element) {
10
10
  return;
11
11
  }
12
12
  if (!mediaWidth) {
@@ -15,8 +15,12 @@ export const getMediaPreviewStyle = (
15
15
  if (!mediaHeight) {
16
16
  mediaHeight = PREVIEW_MAX_HEIGHT;
17
17
  }
18
- const icon = ref.current;
19
- const iconRect = icon.getBoundingClientRect();
18
+
19
+ const elementDiv = element.current !== undefined ? element.current : element;
20
+ if (!elementDiv) {
21
+ return;
22
+ }
23
+ const iconRect = elementDiv.getBoundingClientRect();
20
24
  const aspect: number = mediaWidth / mediaHeight;
21
25
  let width: number = PREVIEW_MAX_WIDTH;
22
26
  let height: number = width / aspect;