@performant-software/semantic-components 0.5.16-beta.0 → 0.5.16-beta.3
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/build/index.js +1 -1
- package/build/index.js.map +1 -1
- package/build/main.css +8 -0
- package/package.json +4 -6
- package/src/components/AudioPlayer.js +40 -22
- package/src/components/DownloadButton.js +63 -12
- package/src/components/IIIFModal.js +26 -0
- package/src/components/LazyAudio.js +31 -4
- package/src/components/LazyDocument.js +20 -6
- package/src/components/LazyIIIF.js +44 -0
- package/src/components/LazyImage.js +32 -5
- package/src/components/LazyLoader.css +7 -0
- package/src/components/LazyLoader.js +28 -0
- package/src/components/LazyMedia.js +243 -0
- package/src/components/LazyVideo.js +40 -5
- package/src/components/PhotoViewer.js +38 -25
- package/src/components/VideoPlayer.js +23 -2
- package/src/i18n/en.json +33 -6
- package/src/index.js +3 -0
- package/types/components/AudioPlayer.js.flow +40 -22
- package/types/components/DownloadButton.js.flow +63 -12
- package/types/components/IIIFModal.js.flow +26 -0
- package/types/components/LazyAudio.js.flow +31 -4
- package/types/components/LazyDocument.js.flow +20 -6
- package/types/components/LazyIIIF.js.flow +44 -0
- package/types/components/LazyImage.js.flow +32 -5
- package/types/components/LazyLoader.js.flow +28 -0
- package/types/components/LazyMedia.js.flow +243 -0
- package/types/components/LazyVideo.js.flow +40 -5
- package/types/components/PhotoViewer.js.flow +38 -25
- package/types/components/VideoPlayer.js.flow +23 -2
- package/types/index.js.flow +3 -0
package/build/main.css
CHANGED
|
@@ -422,6 +422,14 @@ div.react-calendar {
|
|
|
422
422
|
left: 4px;
|
|
423
423
|
}
|
|
424
424
|
|
|
425
|
+
.lazy-loader {
|
|
426
|
+
background-color: #f9fafb;
|
|
427
|
+
box-shadow: 0 1px 3px 0 #d4d4d5, 0 0 0 1px #d4d4d5;
|
|
428
|
+
padding-top: 20%;
|
|
429
|
+
padding-bottom: 20%;
|
|
430
|
+
text-align: center;
|
|
431
|
+
}
|
|
432
|
+
|
|
425
433
|
.lazy-audio.ui.segment {
|
|
426
434
|
display: inline-block !important;
|
|
427
435
|
max-width: 100%;
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@performant-software/semantic-components",
|
|
3
|
-
"version": "0.5.16-beta.
|
|
3
|
+
"version": "0.5.16-beta.3",
|
|
4
4
|
"description": "A package of shared components based on the Semantic UI Framework.",
|
|
5
5
|
"license": "MIT",
|
|
6
6
|
"main": "./build/index.js",
|
|
@@ -9,12 +9,10 @@
|
|
|
9
9
|
"./build/semantic-ui.css"
|
|
10
10
|
],
|
|
11
11
|
"scripts": {
|
|
12
|
-
"build": "webpack --mode production && flow-copy-source -v src types"
|
|
13
|
-
"publish": "npm publish",
|
|
14
|
-
"publish-beta": "npm publish --tag beta"
|
|
12
|
+
"build": "webpack --mode production && flow-copy-source -v src types"
|
|
15
13
|
},
|
|
16
14
|
"dependencies": {
|
|
17
|
-
"@performant-software/shared-components": "^0.5.16-beta.
|
|
15
|
+
"@performant-software/shared-components": "^0.5.16-beta.3",
|
|
18
16
|
"@react-google-maps/api": "^2.8.1",
|
|
19
17
|
"axios": "^0.26.1",
|
|
20
18
|
"i18next": "^19.4.4",
|
|
@@ -35,7 +33,7 @@
|
|
|
35
33
|
"react-dom": ">= 16.13.1 < 18.0.0"
|
|
36
34
|
},
|
|
37
35
|
"devDependencies": {
|
|
38
|
-
"@performant-software/webpack-config": "^0.5.16-beta.
|
|
36
|
+
"@performant-software/webpack-config": "^0.5.16-beta.3",
|
|
39
37
|
"flow-copy-source": "^2.0.9",
|
|
40
38
|
"less": "^4.1.2",
|
|
41
39
|
"less-loader": "^11.0.0",
|
|
@@ -1,8 +1,9 @@
|
|
|
1
1
|
// @flow
|
|
2
2
|
|
|
3
|
-
import React from 'react';
|
|
4
|
-
import { Button, Modal } from 'semantic-ui-react';
|
|
3
|
+
import React, { useState } from 'react';
|
|
4
|
+
import { Button, Message, Modal } from 'semantic-ui-react';
|
|
5
5
|
import i18n from '../i18n/i18n';
|
|
6
|
+
import ModalContext from '../context/ModalContext';
|
|
6
7
|
import './AudioPlayer.css';
|
|
7
8
|
|
|
8
9
|
type Props = {
|
|
@@ -12,25 +13,42 @@ type Props = {
|
|
|
12
13
|
src: string
|
|
13
14
|
};
|
|
14
15
|
|
|
15
|
-
const AudioPlayer = (props: Props) =>
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
)
|
|
16
|
+
const AudioPlayer = (props: Props) => {
|
|
17
|
+
const [error, setError] = useState(false);
|
|
18
|
+
|
|
19
|
+
return (
|
|
20
|
+
<ModalContext.Consumer>
|
|
21
|
+
{(mountNode) => (
|
|
22
|
+
<Modal
|
|
23
|
+
centered={props.centered}
|
|
24
|
+
className='audio-player'
|
|
25
|
+
mountNode={mountNode}
|
|
26
|
+
open={props.open}
|
|
27
|
+
>
|
|
28
|
+
<Modal.Content>
|
|
29
|
+
{ error && (
|
|
30
|
+
<Message
|
|
31
|
+
content={i18n.t('AudioPlayer.errors.path.content', { path: props.src })}
|
|
32
|
+
header={i18n.t('AudioPlayer.errors.path.header')}
|
|
33
|
+
icon='exclamation circle'
|
|
34
|
+
/>
|
|
35
|
+
)}
|
|
36
|
+
<audio
|
|
37
|
+
controls
|
|
38
|
+
onError={() => setError(true)}
|
|
39
|
+
src={props.src}
|
|
40
|
+
/>
|
|
41
|
+
</Modal.Content>
|
|
42
|
+
<Modal.Actions>
|
|
43
|
+
<Button
|
|
44
|
+
content={i18n.t('Common.buttons.close')}
|
|
45
|
+
onClick={props.onClose}
|
|
46
|
+
/>
|
|
47
|
+
</Modal.Actions>
|
|
48
|
+
</Modal>
|
|
49
|
+
)}
|
|
50
|
+
</ModalContext.Consumer>
|
|
51
|
+
);
|
|
52
|
+
};
|
|
35
53
|
|
|
36
54
|
export default AudioPlayer;
|
|
@@ -1,23 +1,74 @@
|
|
|
1
1
|
// @flow
|
|
2
2
|
|
|
3
|
-
import React from 'react';
|
|
3
|
+
import React, { useMemo } from 'react';
|
|
4
4
|
import uuid from 'react-uuid';
|
|
5
|
-
import {
|
|
5
|
+
import { Icon } from 'semantic-ui-react';
|
|
6
|
+
import i18n from '../i18n/i18n';
|
|
6
7
|
|
|
7
8
|
type Props = {
|
|
9
|
+
basic?: boolean,
|
|
10
|
+
className?: string,
|
|
11
|
+
color?: string,
|
|
12
|
+
compact?: boolean,
|
|
8
13
|
filename?: string,
|
|
14
|
+
primary?: boolean,
|
|
15
|
+
size?: string,
|
|
16
|
+
secondary?: boolean,
|
|
9
17
|
url: string
|
|
10
18
|
};
|
|
11
19
|
|
|
12
|
-
const DownloadButton = (
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
)
|
|
20
|
+
const DownloadButton = (props: Props) => {
|
|
21
|
+
/**
|
|
22
|
+
* Sets the appropriate class names based on the formatting props.
|
|
23
|
+
*
|
|
24
|
+
* @type {string}
|
|
25
|
+
*/
|
|
26
|
+
const className = useMemo(() => {
|
|
27
|
+
const classNames = ['ui', 'button'];
|
|
28
|
+
|
|
29
|
+
if (props.basic) {
|
|
30
|
+
classNames.push('basic');
|
|
31
|
+
}
|
|
32
|
+
|
|
33
|
+
if (props.className) {
|
|
34
|
+
classNames.push(...props.className.split(' '));
|
|
35
|
+
}
|
|
36
|
+
|
|
37
|
+
if (props.color) {
|
|
38
|
+
classNames.push(props.color);
|
|
39
|
+
}
|
|
40
|
+
|
|
41
|
+
if (props.compact) {
|
|
42
|
+
classNames.push('compact');
|
|
43
|
+
}
|
|
44
|
+
|
|
45
|
+
if (props.primary) {
|
|
46
|
+
classNames.push('primary');
|
|
47
|
+
}
|
|
48
|
+
|
|
49
|
+
if (props.secondary) {
|
|
50
|
+
classNames.push('secondary');
|
|
51
|
+
}
|
|
52
|
+
|
|
53
|
+
if (props.size) {
|
|
54
|
+
classNames.push(props.size);
|
|
55
|
+
}
|
|
56
|
+
|
|
57
|
+
return classNames.join(' ');
|
|
58
|
+
}, [props.basic, props.color]);
|
|
59
|
+
|
|
60
|
+
return (
|
|
61
|
+
<a
|
|
62
|
+
className={className}
|
|
63
|
+
download={props.filename || uuid()}
|
|
64
|
+
href={props.url}
|
|
65
|
+
>
|
|
66
|
+
<Icon
|
|
67
|
+
name='cloud download'
|
|
68
|
+
/>
|
|
69
|
+
{ i18n.t('Common.buttons.download') }
|
|
70
|
+
</a>
|
|
71
|
+
);
|
|
72
|
+
};
|
|
22
73
|
|
|
23
74
|
export default DownloadButton;
|
|
@@ -0,0 +1,26 @@
|
|
|
1
|
+
// @flow
|
|
2
|
+
|
|
3
|
+
import React from 'react';
|
|
4
|
+
import { Modal } from 'semantic-ui-react';
|
|
5
|
+
import { IIIFViewer } from '@performant-software/shared-components';
|
|
6
|
+
|
|
7
|
+
type Props = {
|
|
8
|
+
onClose: () => void
|
|
9
|
+
};
|
|
10
|
+
|
|
11
|
+
const IIIFModal = ({ onClose, ...props }: Props) => (
|
|
12
|
+
<Modal
|
|
13
|
+
centered={false}
|
|
14
|
+
closeIcon
|
|
15
|
+
onClose={onClose}
|
|
16
|
+
open
|
|
17
|
+
>
|
|
18
|
+
<Modal.Content>
|
|
19
|
+
<IIIFViewer
|
|
20
|
+
{...props}
|
|
21
|
+
/>
|
|
22
|
+
</Modal.Content>
|
|
23
|
+
</Modal>
|
|
24
|
+
);
|
|
25
|
+
|
|
26
|
+
export default IIIFModal;
|
|
@@ -13,22 +13,28 @@ import {
|
|
|
13
13
|
} from 'semantic-ui-react';
|
|
14
14
|
import i18n from '../i18n/i18n';
|
|
15
15
|
import AudioPlayer from './AudioPlayer';
|
|
16
|
+
import DownloadButton from './DownloadButton';
|
|
17
|
+
import LazyLoader from './LazyLoader';
|
|
16
18
|
import './LazyAudio.css';
|
|
17
19
|
|
|
18
20
|
type Props = {
|
|
19
21
|
children?: Node,
|
|
20
22
|
dimmable: boolean,
|
|
23
|
+
download?: string,
|
|
21
24
|
duration?: number,
|
|
22
25
|
image?: any,
|
|
26
|
+
name?: string,
|
|
23
27
|
preview?: string,
|
|
24
28
|
size?: string,
|
|
25
29
|
src?: string
|
|
26
30
|
};
|
|
27
31
|
|
|
28
32
|
const LazyAudio = (props: Props) => {
|
|
29
|
-
const [visible, setVisible] = useState(false);
|
|
30
|
-
const [modal, setModal] = useState(false);
|
|
31
33
|
const [dimmer, setDimmer] = useState(false);
|
|
34
|
+
const [error, setError] = useState(false);
|
|
35
|
+
const [loaded, setLoaded] = useState(!props.preview);
|
|
36
|
+
const [modal, setModal] = useState(false);
|
|
37
|
+
const [visible, setVisible] = useState(false);
|
|
32
38
|
|
|
33
39
|
if (!visible) {
|
|
34
40
|
return (
|
|
@@ -60,14 +66,28 @@ const LazyAudio = (props: Props) => {
|
|
|
60
66
|
onMouseEnter={() => setDimmer(true)}
|
|
61
67
|
onMouseLeave={() => setDimmer(false)}
|
|
62
68
|
>
|
|
63
|
-
{
|
|
69
|
+
{ !loaded && (
|
|
70
|
+
<LazyLoader
|
|
71
|
+
active
|
|
72
|
+
size={props.size}
|
|
73
|
+
/>
|
|
74
|
+
)}
|
|
75
|
+
{ !error && props.preview && (
|
|
64
76
|
<Image
|
|
65
77
|
{...props.image}
|
|
78
|
+
onError={() => {
|
|
79
|
+
setError(true);
|
|
80
|
+
setLoaded(true);
|
|
81
|
+
}}
|
|
82
|
+
onLoad={() => {
|
|
83
|
+
setError(false);
|
|
84
|
+
setLoaded(true);
|
|
85
|
+
}}
|
|
66
86
|
size={props.size}
|
|
67
87
|
src={props.preview}
|
|
68
88
|
/>
|
|
69
89
|
)}
|
|
70
|
-
{ !props.preview && (
|
|
90
|
+
{ (error || !props.preview) && (
|
|
71
91
|
<Image
|
|
72
92
|
{...props.image}
|
|
73
93
|
className='placeholder-image'
|
|
@@ -94,6 +114,13 @@ const LazyAudio = (props: Props) => {
|
|
|
94
114
|
primary
|
|
95
115
|
/>
|
|
96
116
|
)}
|
|
117
|
+
{ props.download && (
|
|
118
|
+
<DownloadButton
|
|
119
|
+
color='green'
|
|
120
|
+
filename={props.name}
|
|
121
|
+
url={props.download}
|
|
122
|
+
/>
|
|
123
|
+
)}
|
|
97
124
|
{ props.children }
|
|
98
125
|
</div>
|
|
99
126
|
</Dimmer>
|
|
@@ -11,8 +11,8 @@ import {
|
|
|
11
11
|
Transition,
|
|
12
12
|
Visibility
|
|
13
13
|
} from 'semantic-ui-react';
|
|
14
|
-
import i18n from '../i18n/i18n';
|
|
15
14
|
import DownloadButton from './DownloadButton';
|
|
15
|
+
import LazyLoader from './LazyLoader';
|
|
16
16
|
import './LazyDocument.css';
|
|
17
17
|
|
|
18
18
|
type Props = {
|
|
@@ -27,8 +27,10 @@ type Props = {
|
|
|
27
27
|
};
|
|
28
28
|
|
|
29
29
|
const LazyDocument = (props: Props) => {
|
|
30
|
-
const [visible, setVisible] = useState(false);
|
|
31
30
|
const [dimmer, setDimmer] = useState(false);
|
|
31
|
+
const [error, setError] = useState(false);
|
|
32
|
+
const [loaded, setLoaded] = useState(!props.preview);
|
|
33
|
+
const [visible, setVisible] = useState(false);
|
|
32
34
|
|
|
33
35
|
if (!visible) {
|
|
34
36
|
return (
|
|
@@ -60,9 +62,23 @@ const LazyDocument = (props: Props) => {
|
|
|
60
62
|
onMouseEnter={() => setDimmer(true)}
|
|
61
63
|
onMouseLeave={() => setDimmer(false)}
|
|
62
64
|
>
|
|
63
|
-
{
|
|
65
|
+
{ !loaded && (
|
|
66
|
+
<LazyLoader
|
|
67
|
+
active
|
|
68
|
+
size={props.size}
|
|
69
|
+
/>
|
|
70
|
+
)}
|
|
71
|
+
{ !error && props.preview && (
|
|
64
72
|
<Image
|
|
65
73
|
{...props.image}
|
|
74
|
+
onError={() => {
|
|
75
|
+
setError(true);
|
|
76
|
+
setLoaded(true);
|
|
77
|
+
}}
|
|
78
|
+
onLoad={() => {
|
|
79
|
+
setError(false);
|
|
80
|
+
setLoaded(true);
|
|
81
|
+
}}
|
|
66
82
|
src={props.preview}
|
|
67
83
|
size={props.size}
|
|
68
84
|
/>
|
|
@@ -81,7 +97,7 @@ const LazyDocument = (props: Props) => {
|
|
|
81
97
|
</Document>
|
|
82
98
|
</Image>
|
|
83
99
|
)}
|
|
84
|
-
{ !props.preview && !(props.src && props.pdf) && (
|
|
100
|
+
{ (error || (!props.preview && !(props.src && props.pdf))) && (
|
|
85
101
|
<Image
|
|
86
102
|
{...props.image}
|
|
87
103
|
className='placeholder-image'
|
|
@@ -102,8 +118,6 @@ const LazyDocument = (props: Props) => {
|
|
|
102
118
|
>
|
|
103
119
|
{ props.src && (
|
|
104
120
|
<DownloadButton
|
|
105
|
-
content={i18n.t('LazyDocument.buttons.download')}
|
|
106
|
-
icon='cloud download'
|
|
107
121
|
primary
|
|
108
122
|
url={props.src}
|
|
109
123
|
/>
|
|
@@ -0,0 +1,44 @@
|
|
|
1
|
+
// @flow
|
|
2
|
+
|
|
3
|
+
import React, { useState, type Node } from 'react';
|
|
4
|
+
import { Button } from 'semantic-ui-react';
|
|
5
|
+
import i18n from '../i18n/i18n';
|
|
6
|
+
import IIIFModal from './IIIFModal';
|
|
7
|
+
import LazyMedia from './LazyMedia';
|
|
8
|
+
|
|
9
|
+
type Props = {
|
|
10
|
+
children?: Node,
|
|
11
|
+
manifest?: string
|
|
12
|
+
};
|
|
13
|
+
|
|
14
|
+
const LazyIIIF = (props: Props) => {
|
|
15
|
+
const [modal, setModal] = useState(false);
|
|
16
|
+
|
|
17
|
+
return (
|
|
18
|
+
<>
|
|
19
|
+
<LazyMedia
|
|
20
|
+
{...props}
|
|
21
|
+
>
|
|
22
|
+
{ props.manifest && (
|
|
23
|
+
<Button
|
|
24
|
+
content={i18n.t('Common.buttons.open')}
|
|
25
|
+
icon='images outline'
|
|
26
|
+
onClick={() => setModal(true)}
|
|
27
|
+
/>
|
|
28
|
+
)}
|
|
29
|
+
{ props.children }
|
|
30
|
+
</LazyMedia>
|
|
31
|
+
{ modal && (
|
|
32
|
+
<IIIFModal
|
|
33
|
+
manifestId={props.manifest}
|
|
34
|
+
onClose={() => setModal(false)}
|
|
35
|
+
options={{
|
|
36
|
+
showIIIFBadge: false
|
|
37
|
+
}}
|
|
38
|
+
/>
|
|
39
|
+
)}
|
|
40
|
+
</>
|
|
41
|
+
);
|
|
42
|
+
};
|
|
43
|
+
|
|
44
|
+
export default LazyIIIF;
|
|
@@ -12,23 +12,29 @@ import {
|
|
|
12
12
|
Visibility
|
|
13
13
|
} from 'semantic-ui-react';
|
|
14
14
|
import i18n from '../i18n/i18n';
|
|
15
|
+
import DownloadButton from './DownloadButton';
|
|
16
|
+
import LazyLoader from './LazyLoader';
|
|
15
17
|
import PhotoViewer from './PhotoViewer';
|
|
16
18
|
import './LazyImage.css';
|
|
17
19
|
|
|
18
20
|
type Props = {
|
|
19
21
|
children?: Node,
|
|
20
22
|
dimmable: boolean,
|
|
23
|
+
download?: string,
|
|
21
24
|
duration?: number,
|
|
22
25
|
image?: any,
|
|
26
|
+
name?: string,
|
|
23
27
|
preview?: string,
|
|
24
28
|
size?: string,
|
|
25
29
|
src?: string
|
|
26
30
|
};
|
|
27
31
|
|
|
28
32
|
const LazyImage = (props: Props) => {
|
|
29
|
-
const [visible, setVisible] = useState(false);
|
|
30
|
-
const [modal, setModal] = useState(false);
|
|
31
33
|
const [dimmer, setDimmer] = useState(false);
|
|
34
|
+
const [error, setError] = useState(false);
|
|
35
|
+
const [loaded, setLoaded] = useState(!(props.src || props.preview));
|
|
36
|
+
const [modal, setModal] = useState(false);
|
|
37
|
+
const [visible, setVisible] = useState(false);
|
|
32
38
|
|
|
33
39
|
if (!visible) {
|
|
34
40
|
return (
|
|
@@ -60,14 +66,28 @@ const LazyImage = (props: Props) => {
|
|
|
60
66
|
onMouseEnter={() => setDimmer(true)}
|
|
61
67
|
onMouseLeave={() => setDimmer(false)}
|
|
62
68
|
>
|
|
63
|
-
{
|
|
69
|
+
{ !loaded && (
|
|
70
|
+
<LazyLoader
|
|
71
|
+
active
|
|
72
|
+
size={props.size}
|
|
73
|
+
/>
|
|
74
|
+
)}
|
|
75
|
+
{ !error && (props.preview || props.src) && (
|
|
64
76
|
<Image
|
|
65
77
|
{...props.image}
|
|
78
|
+
onError={() => {
|
|
79
|
+
setError(true);
|
|
80
|
+
setLoaded(true);
|
|
81
|
+
}}
|
|
82
|
+
onLoad={() => {
|
|
83
|
+
setError(false);
|
|
84
|
+
setLoaded(true);
|
|
85
|
+
}}
|
|
66
86
|
size={props.size}
|
|
67
87
|
src={props.preview || props.src}
|
|
68
88
|
/>
|
|
69
89
|
)}
|
|
70
|
-
{ !(props.preview || props.src) && (
|
|
90
|
+
{ (error || !(props.preview || props.src)) && (
|
|
71
91
|
<Image
|
|
72
92
|
{...props.image}
|
|
73
93
|
className='placeholder-image'
|
|
@@ -79,7 +99,7 @@ const LazyImage = (props: Props) => {
|
|
|
79
99
|
/>
|
|
80
100
|
</Image>
|
|
81
101
|
)}
|
|
82
|
-
{ (props.src || props.children) && props.dimmable && (
|
|
102
|
+
{ !error && (props.src || props.children) && props.dimmable && (
|
|
83
103
|
<Dimmer
|
|
84
104
|
active={dimmer}
|
|
85
105
|
>
|
|
@@ -94,6 +114,13 @@ const LazyImage = (props: Props) => {
|
|
|
94
114
|
primary
|
|
95
115
|
/>
|
|
96
116
|
)}
|
|
117
|
+
{ props.download && (
|
|
118
|
+
<DownloadButton
|
|
119
|
+
color='green'
|
|
120
|
+
filename={props.name}
|
|
121
|
+
url={props.download}
|
|
122
|
+
/>
|
|
123
|
+
)}
|
|
97
124
|
{ props.children }
|
|
98
125
|
</div>
|
|
99
126
|
</Dimmer>
|
|
@@ -0,0 +1,28 @@
|
|
|
1
|
+
// @flow
|
|
2
|
+
|
|
3
|
+
import React from 'react';
|
|
4
|
+
import { Image, Loader } from 'semantic-ui-react';
|
|
5
|
+
import './LazyLoader.css';
|
|
6
|
+
|
|
7
|
+
type Props = {
|
|
8
|
+
active: boolean,
|
|
9
|
+
size: string
|
|
10
|
+
};
|
|
11
|
+
|
|
12
|
+
const LazyLoader = (props: Props) => (
|
|
13
|
+
<Image
|
|
14
|
+
className='lazy-loader'
|
|
15
|
+
size={props.size}
|
|
16
|
+
>
|
|
17
|
+
<Loader
|
|
18
|
+
active={props.active}
|
|
19
|
+
/>
|
|
20
|
+
</Image>
|
|
21
|
+
);
|
|
22
|
+
|
|
23
|
+
LazyLoader.defaultProps = {
|
|
24
|
+
active: false,
|
|
25
|
+
size: 'small'
|
|
26
|
+
};
|
|
27
|
+
|
|
28
|
+
export default LazyLoader;
|