@performant-software/semantic-components 1.0.16 → 1.0.17
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 +40 -0
- package/package.json +2 -2
- package/src/components/ImageCarousel.css +36 -0
- package/src/components/ImageCarousel.js +154 -0
- package/src/components/LazyDocument.css +4 -0
- package/src/components/LazyDocument.js +23 -2
- package/src/components/LazyImage.css +4 -0
- package/src/components/LazyImage.js +22 -2
- package/src/components/LazyVideo.css +4 -0
- package/src/components/LazyVideo.js +28 -2
- package/src/index.js +1 -0
- package/types/components/LazyDocument.js.flow +23 -2
- package/types/components/LazyImage.js.flow +22 -2
- package/types/components/LazyVideo.js.flow +28 -2
- package/types/index.js.flow +1 -0
package/build/main.css
CHANGED
|
@@ -601,6 +601,37 @@ div.react-calendar {
|
|
|
601
601
|
aspect-ratio: 1;
|
|
602
602
|
}
|
|
603
603
|
|
|
604
|
+
.image-carousel > .content {
|
|
605
|
+
height: 100%;
|
|
606
|
+
width: 100%;
|
|
607
|
+
}
|
|
608
|
+
.image-carousel > .content > .ui.grid {
|
|
609
|
+
height: 100%;
|
|
610
|
+
}
|
|
611
|
+
.image-carousel > .content > .ui.grid > .row.image-content {
|
|
612
|
+
flex-grow: 1;
|
|
613
|
+
}
|
|
614
|
+
.image-carousel > .content > .ui.grid > .row.image-content > .column {
|
|
615
|
+
display: flex;
|
|
616
|
+
justify-content: center;
|
|
617
|
+
align-items: center;
|
|
618
|
+
}
|
|
619
|
+
.image-carousel > .content > .ui.grid > .row.image-content > .column.image-container {
|
|
620
|
+
flex-grow: 1;
|
|
621
|
+
}
|
|
622
|
+
.image-carousel > .content > .ui.grid > .row.image-content > .column.image-container img {
|
|
623
|
+
width: 100%;
|
|
624
|
+
height: auto;
|
|
625
|
+
max-height: 70vh;
|
|
626
|
+
object-fit: contain;
|
|
627
|
+
}
|
|
628
|
+
.image-carousel .ui.button,
|
|
629
|
+
.image-carousel .ui.button:hover {
|
|
630
|
+
border: none;
|
|
631
|
+
background: none;
|
|
632
|
+
color: #FFFFFF;
|
|
633
|
+
}
|
|
634
|
+
|
|
604
635
|
.item-list {
|
|
605
636
|
margin: 1em 0em 1em 0em;
|
|
606
637
|
}
|
|
@@ -685,6 +716,9 @@ div.react-calendar {
|
|
|
685
716
|
width: 100% !important;
|
|
686
717
|
height: 100% !important;
|
|
687
718
|
}
|
|
719
|
+
.lazy-document > .image.hidden {
|
|
720
|
+
display: none;
|
|
721
|
+
}
|
|
688
722
|
|
|
689
723
|
.photo-viewer {
|
|
690
724
|
padding: 30px;
|
|
@@ -713,6 +747,9 @@ div.react-calendar {
|
|
|
713
747
|
padding-bottom: 20%;
|
|
714
748
|
text-align: center;
|
|
715
749
|
}
|
|
750
|
+
.lazy-image > .image.hidden {
|
|
751
|
+
display: none;
|
|
752
|
+
}
|
|
716
753
|
|
|
717
754
|
.video-player video {
|
|
718
755
|
width: 100%;
|
|
@@ -745,6 +782,9 @@ div.react-calendar {
|
|
|
745
782
|
display: table;
|
|
746
783
|
width: 100%;
|
|
747
784
|
}
|
|
785
|
+
.lazy-video > .image.hidden {
|
|
786
|
+
display: none;
|
|
787
|
+
}
|
|
748
788
|
|
|
749
789
|
.listLoader.ui.segment {
|
|
750
790
|
position: absolute;
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@performant-software/semantic-components",
|
|
3
|
-
"version": "1.0.
|
|
3
|
+
"version": "1.0.17",
|
|
4
4
|
"description": "A package of shared components based on the Semantic UI Framework.",
|
|
5
5
|
"license": "MIT",
|
|
6
6
|
"main": "./build/index.js",
|
|
@@ -12,7 +12,7 @@
|
|
|
12
12
|
"build": "webpack --mode production && flow-copy-source -v src types"
|
|
13
13
|
},
|
|
14
14
|
"dependencies": {
|
|
15
|
-
"@performant-software/shared-components": "^1.0.
|
|
15
|
+
"@performant-software/shared-components": "^1.0.17",
|
|
16
16
|
"@react-google-maps/api": "^2.8.1",
|
|
17
17
|
"axios": "^0.26.1",
|
|
18
18
|
"i18next": "^19.4.4",
|
|
@@ -0,0 +1,36 @@
|
|
|
1
|
+
.image-carousel > .content {
|
|
2
|
+
height: 100%;
|
|
3
|
+
width: 100%;
|
|
4
|
+
}
|
|
5
|
+
|
|
6
|
+
.image-carousel > .content > .ui.grid {
|
|
7
|
+
height: 100%;
|
|
8
|
+
}
|
|
9
|
+
|
|
10
|
+
.image-carousel > .content > .ui.grid > .row.image-content {
|
|
11
|
+
flex-grow: 1;
|
|
12
|
+
}
|
|
13
|
+
|
|
14
|
+
.image-carousel > .content > .ui.grid > .row.image-content > .column {
|
|
15
|
+
display: flex;
|
|
16
|
+
justify-content: center;
|
|
17
|
+
align-items: center;
|
|
18
|
+
}
|
|
19
|
+
|
|
20
|
+
.image-carousel > .content > .ui.grid > .row.image-content > .column.image-container {
|
|
21
|
+
flex-grow: 1;
|
|
22
|
+
}
|
|
23
|
+
|
|
24
|
+
.image-carousel > .content > .ui.grid > .row.image-content > .column.image-container img {
|
|
25
|
+
width: 100%;
|
|
26
|
+
height: auto;
|
|
27
|
+
max-height: 70vh;
|
|
28
|
+
object-fit: contain;
|
|
29
|
+
}
|
|
30
|
+
|
|
31
|
+
.image-carousel .ui.button,
|
|
32
|
+
.image-carousel .ui.button:hover {
|
|
33
|
+
border: none;
|
|
34
|
+
background: none;
|
|
35
|
+
color: #FFFFFF;
|
|
36
|
+
}
|
|
@@ -0,0 +1,154 @@
|
|
|
1
|
+
// @flow
|
|
2
|
+
|
|
3
|
+
import React, {
|
|
4
|
+
useCallback,
|
|
5
|
+
useEffect,
|
|
6
|
+
useMemo,
|
|
7
|
+
useState
|
|
8
|
+
} from 'react';
|
|
9
|
+
import {
|
|
10
|
+
Button,
|
|
11
|
+
Dimmer,
|
|
12
|
+
Grid,
|
|
13
|
+
Image,
|
|
14
|
+
Loader,
|
|
15
|
+
Transition
|
|
16
|
+
} from 'semantic-ui-react';
|
|
17
|
+
import './ImageCarousel.css';
|
|
18
|
+
|
|
19
|
+
type ImageType = {
|
|
20
|
+
caption?: string,
|
|
21
|
+
src: string
|
|
22
|
+
};
|
|
23
|
+
|
|
24
|
+
type Props = {
|
|
25
|
+
images: Array<ImageType>,
|
|
26
|
+
onClose: () => void
|
|
27
|
+
};
|
|
28
|
+
|
|
29
|
+
const ImageCarousel = (props: Props) => {
|
|
30
|
+
const [currentIndex, setCurrentIndex] = useState(0);
|
|
31
|
+
const [visible, setVisible] = useState(true);
|
|
32
|
+
|
|
33
|
+
/**
|
|
34
|
+
* Sets the current image based on the current index.
|
|
35
|
+
*
|
|
36
|
+
* @type {*}
|
|
37
|
+
*/
|
|
38
|
+
const image = useMemo(() => {
|
|
39
|
+
let value;
|
|
40
|
+
|
|
41
|
+
if (props.images && props.images.length > currentIndex) {
|
|
42
|
+
value = props.images[currentIndex];
|
|
43
|
+
}
|
|
44
|
+
|
|
45
|
+
return value;
|
|
46
|
+
}, [currentIndex, props.images]);
|
|
47
|
+
|
|
48
|
+
/**
|
|
49
|
+
* Sets the new index value.
|
|
50
|
+
*
|
|
51
|
+
* @type {(function(*): void)|*}
|
|
52
|
+
*/
|
|
53
|
+
const onIndexChange = useCallback((increment) => {
|
|
54
|
+
const newIndex = currentIndex + increment;
|
|
55
|
+
|
|
56
|
+
if (newIndex >= 0 && newIndex < props.images.length) {
|
|
57
|
+
setCurrentIndex(newIndex);
|
|
58
|
+
setVisible(false);
|
|
59
|
+
}
|
|
60
|
+
}, [currentIndex, props.images]);
|
|
61
|
+
|
|
62
|
+
/**
|
|
63
|
+
* Sets up the component when initially mounted.
|
|
64
|
+
*/
|
|
65
|
+
useEffect(() => {
|
|
66
|
+
// Disabled scrolling on the page when carousel is visible.
|
|
67
|
+
if (document.body) {
|
|
68
|
+
document.body.style.overflow = 'hidden';
|
|
69
|
+
}
|
|
70
|
+
|
|
71
|
+
return () => {
|
|
72
|
+
// Re-enable scrolling
|
|
73
|
+
if (document.body) {
|
|
74
|
+
document.body.style.overflow = 'auto';
|
|
75
|
+
}
|
|
76
|
+
};
|
|
77
|
+
}, []);
|
|
78
|
+
|
|
79
|
+
return (
|
|
80
|
+
<Dimmer
|
|
81
|
+
active
|
|
82
|
+
className='image-carousel'
|
|
83
|
+
page
|
|
84
|
+
>
|
|
85
|
+
<Grid
|
|
86
|
+
padded
|
|
87
|
+
>
|
|
88
|
+
<Grid.Row>
|
|
89
|
+
<Grid.Column
|
|
90
|
+
textAlign='right'
|
|
91
|
+
>
|
|
92
|
+
<Button
|
|
93
|
+
icon='times'
|
|
94
|
+
onClick={props.onClose}
|
|
95
|
+
size='huge'
|
|
96
|
+
/>
|
|
97
|
+
</Grid.Column>
|
|
98
|
+
</Grid.Row>
|
|
99
|
+
<Grid.Row
|
|
100
|
+
className='image-content'
|
|
101
|
+
>
|
|
102
|
+
<Grid.Column>
|
|
103
|
+
{ props.images && props.images.length > 1 && (
|
|
104
|
+
<Button
|
|
105
|
+
disabled={currentIndex === 0}
|
|
106
|
+
icon='chevron left'
|
|
107
|
+
onClick={() => onIndexChange(-1)}
|
|
108
|
+
size='massive'
|
|
109
|
+
/>
|
|
110
|
+
)}
|
|
111
|
+
</Grid.Column>
|
|
112
|
+
<Grid.Column
|
|
113
|
+
className='image-container'
|
|
114
|
+
>
|
|
115
|
+
{ !visible && (
|
|
116
|
+
<Loader
|
|
117
|
+
active
|
|
118
|
+
/>
|
|
119
|
+
)}
|
|
120
|
+
<Transition
|
|
121
|
+
animation='fade'
|
|
122
|
+
duration={500}
|
|
123
|
+
visible={visible}
|
|
124
|
+
>
|
|
125
|
+
<Image
|
|
126
|
+
src={image?.src}
|
|
127
|
+
onLoad={() => setVisible(true)}
|
|
128
|
+
/>
|
|
129
|
+
</Transition>
|
|
130
|
+
</Grid.Column>
|
|
131
|
+
<Grid.Column>
|
|
132
|
+
{ props.images && props.images.length > 1 && (
|
|
133
|
+
<Button
|
|
134
|
+
disabled={currentIndex === props.images.length - 1}
|
|
135
|
+
icon='chevron right'
|
|
136
|
+
onClick={() => onIndexChange(1)}
|
|
137
|
+
size='massive'
|
|
138
|
+
/>
|
|
139
|
+
)}
|
|
140
|
+
</Grid.Column>
|
|
141
|
+
</Grid.Row>
|
|
142
|
+
<Grid.Row>
|
|
143
|
+
<Grid.Column
|
|
144
|
+
textAlign='center'
|
|
145
|
+
>
|
|
146
|
+
{ image?.caption }
|
|
147
|
+
</Grid.Column>
|
|
148
|
+
</Grid.Row>
|
|
149
|
+
</Grid>
|
|
150
|
+
</Dimmer>
|
|
151
|
+
);
|
|
152
|
+
};
|
|
153
|
+
|
|
154
|
+
export default ImageCarousel;
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
// @flow
|
|
2
2
|
|
|
3
|
-
import React, { useState, type Node } from 'react';
|
|
3
|
+
import React, { useCallback, useState, type Node } from 'react';
|
|
4
4
|
import { pdfjs, Document, Page } from 'react-pdf';
|
|
5
5
|
import {
|
|
6
6
|
Dimmer,
|
|
@@ -38,6 +38,25 @@ const LazyDocument = (props: Props) => {
|
|
|
38
38
|
const [loaded, setLoaded] = useState(!props.preview);
|
|
39
39
|
const [visible, setVisible] = useState(false);
|
|
40
40
|
|
|
41
|
+
/**
|
|
42
|
+
* Returns the list of class names for the image component.
|
|
43
|
+
*
|
|
44
|
+
* @type {function(*=): []}
|
|
45
|
+
*/
|
|
46
|
+
const getClassNames = useCallback((defaultClass = null) => {
|
|
47
|
+
const classNames = [];
|
|
48
|
+
|
|
49
|
+
if (defaultClass) {
|
|
50
|
+
classNames.push(defaultClass);
|
|
51
|
+
}
|
|
52
|
+
|
|
53
|
+
if (!loaded) {
|
|
54
|
+
classNames.push('hidden');
|
|
55
|
+
}
|
|
56
|
+
|
|
57
|
+
return classNames.join(' ');
|
|
58
|
+
}, [loaded]);
|
|
59
|
+
|
|
41
60
|
if (!visible) {
|
|
42
61
|
return (
|
|
43
62
|
<Visibility
|
|
@@ -77,6 +96,7 @@ const LazyDocument = (props: Props) => {
|
|
|
77
96
|
{ !error && props.preview && (
|
|
78
97
|
<Image
|
|
79
98
|
{...props.image}
|
|
99
|
+
className={getClassNames()}
|
|
80
100
|
onError={() => {
|
|
81
101
|
setError(true);
|
|
82
102
|
setLoaded(true);
|
|
@@ -92,6 +112,7 @@ const LazyDocument = (props: Props) => {
|
|
|
92
112
|
{ !error && loaded && !props.preview && props.src && props.pdf && (
|
|
93
113
|
<Image
|
|
94
114
|
{...props.image}
|
|
115
|
+
className={getClassNames()}
|
|
95
116
|
size={props.size}
|
|
96
117
|
>
|
|
97
118
|
<Document
|
|
@@ -107,7 +128,7 @@ const LazyDocument = (props: Props) => {
|
|
|
107
128
|
{ (error || (!props.preview && !(props.src && props.pdf))) && (
|
|
108
129
|
<Image
|
|
109
130
|
{...props.image}
|
|
110
|
-
className='placeholder-image'
|
|
131
|
+
className={getClassNames('placeholder-image')}
|
|
111
132
|
size={props.size}
|
|
112
133
|
>
|
|
113
134
|
<Icon
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
// @flow
|
|
2
2
|
|
|
3
|
-
import React, { useState, type Node } from 'react';
|
|
3
|
+
import React, { useCallback, useState, type Node } from 'react';
|
|
4
4
|
import {
|
|
5
5
|
Button,
|
|
6
6
|
Dimmer,
|
|
@@ -36,6 +36,25 @@ const LazyImage = (props: Props) => {
|
|
|
36
36
|
const [modal, setModal] = useState(false);
|
|
37
37
|
const [visible, setVisible] = useState(false);
|
|
38
38
|
|
|
39
|
+
/**
|
|
40
|
+
* Returns the list of class names for the image component.
|
|
41
|
+
*
|
|
42
|
+
* @type {function(*=): []}
|
|
43
|
+
*/
|
|
44
|
+
const getClassNames = useCallback((defaultClass = null) => {
|
|
45
|
+
const classNames = [];
|
|
46
|
+
|
|
47
|
+
if (defaultClass) {
|
|
48
|
+
classNames.push(defaultClass);
|
|
49
|
+
}
|
|
50
|
+
|
|
51
|
+
if (!loaded) {
|
|
52
|
+
classNames.push('hidden');
|
|
53
|
+
}
|
|
54
|
+
|
|
55
|
+
return classNames.join(' ');
|
|
56
|
+
}, [loaded]);
|
|
57
|
+
|
|
39
58
|
if (!visible) {
|
|
40
59
|
return (
|
|
41
60
|
<Visibility
|
|
@@ -75,6 +94,7 @@ const LazyImage = (props: Props) => {
|
|
|
75
94
|
{ !error && (props.preview || props.src) && (
|
|
76
95
|
<Image
|
|
77
96
|
{...props.image}
|
|
97
|
+
className={getClassNames()}
|
|
78
98
|
onError={() => {
|
|
79
99
|
setError(true);
|
|
80
100
|
setLoaded(true);
|
|
@@ -90,7 +110,7 @@ const LazyImage = (props: Props) => {
|
|
|
90
110
|
{ (error || !(props.preview || props.src)) && (
|
|
91
111
|
<Image
|
|
92
112
|
{...props.image}
|
|
93
|
-
className='placeholder-image'
|
|
113
|
+
className={getClassNames('placeholder-image')}
|
|
94
114
|
size={props.size}
|
|
95
115
|
>
|
|
96
116
|
<Icon
|
|
@@ -1,6 +1,11 @@
|
|
|
1
1
|
// @flow
|
|
2
2
|
|
|
3
|
-
import React, {
|
|
3
|
+
import React, {
|
|
4
|
+
useCallback,
|
|
5
|
+
useState,
|
|
6
|
+
type Element,
|
|
7
|
+
type Node
|
|
8
|
+
} from 'react';
|
|
4
9
|
import {
|
|
5
10
|
Button,
|
|
6
11
|
Dimmer,
|
|
@@ -39,6 +44,25 @@ const LazyVideo = (props: Props) => {
|
|
|
39
44
|
const [modal, setModal] = useState(false);
|
|
40
45
|
const [visible, setVisible] = useState(false);
|
|
41
46
|
|
|
47
|
+
/**
|
|
48
|
+
* Returns the list of class names for the image component.
|
|
49
|
+
*
|
|
50
|
+
* @type {function(*=): []}
|
|
51
|
+
*/
|
|
52
|
+
const getClassNames = useCallback((defaultClass = null) => {
|
|
53
|
+
const classNames = [];
|
|
54
|
+
|
|
55
|
+
if (defaultClass) {
|
|
56
|
+
classNames.push(defaultClass);
|
|
57
|
+
}
|
|
58
|
+
|
|
59
|
+
if (!loaded) {
|
|
60
|
+
classNames.push('hidden');
|
|
61
|
+
}
|
|
62
|
+
|
|
63
|
+
return classNames.join(' ');
|
|
64
|
+
}, [loaded]);
|
|
65
|
+
|
|
42
66
|
if (!visible) {
|
|
43
67
|
return (
|
|
44
68
|
<Visibility
|
|
@@ -78,6 +102,7 @@ const LazyVideo = (props: Props) => {
|
|
|
78
102
|
{ !error && props.preview && (
|
|
79
103
|
<Image
|
|
80
104
|
{...props.image}
|
|
105
|
+
className={getClassNames()}
|
|
81
106
|
onError={() => {
|
|
82
107
|
setError(true);
|
|
83
108
|
setLoaded(true);
|
|
@@ -93,6 +118,7 @@ const LazyVideo = (props: Props) => {
|
|
|
93
118
|
{ !error && !props.preview && props.src && (
|
|
94
119
|
<Image
|
|
95
120
|
{...props.image}
|
|
121
|
+
className={getClassNames()}
|
|
96
122
|
size={props.size}
|
|
97
123
|
>
|
|
98
124
|
<video
|
|
@@ -111,7 +137,7 @@ const LazyVideo = (props: Props) => {
|
|
|
111
137
|
{ (error || (!props.preview && !props.src)) && (
|
|
112
138
|
<Image
|
|
113
139
|
{...props.image}
|
|
114
|
-
className='placeholder-image'
|
|
140
|
+
className={getClassNames('placeholder-image')}
|
|
115
141
|
size={props.size}
|
|
116
142
|
>
|
|
117
143
|
<Icon
|
package/src/index.js
CHANGED
|
@@ -45,6 +45,7 @@ export { default as GoogleMap } from './components/GoogleMap';
|
|
|
45
45
|
export { default as GooglePlacesSearch } from './components/GooglePlacesSearch';
|
|
46
46
|
export { default as HorizontalCards } from './components/HorizontalCards';
|
|
47
47
|
export { default as IIIFModal } from './components/IIIFModal';
|
|
48
|
+
export { default as ImageCarousel } from './components/ImageCarousel';
|
|
48
49
|
export { default as ItemCollection } from './components/ItemCollection';
|
|
49
50
|
export { default as ItemList } from './components/ItemList';
|
|
50
51
|
export { default as Items } from './components/Items';
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
// @flow
|
|
2
2
|
|
|
3
|
-
import React, { useState, type Node } from 'react';
|
|
3
|
+
import React, { useCallback, useState, type Node } from 'react';
|
|
4
4
|
import { pdfjs, Document, Page } from 'react-pdf';
|
|
5
5
|
import {
|
|
6
6
|
Dimmer,
|
|
@@ -38,6 +38,25 @@ const LazyDocument = (props: Props) => {
|
|
|
38
38
|
const [loaded, setLoaded] = useState(!props.preview);
|
|
39
39
|
const [visible, setVisible] = useState(false);
|
|
40
40
|
|
|
41
|
+
/**
|
|
42
|
+
* Returns the list of class names for the image component.
|
|
43
|
+
*
|
|
44
|
+
* @type {function(*=): []}
|
|
45
|
+
*/
|
|
46
|
+
const getClassNames = useCallback((defaultClass = null) => {
|
|
47
|
+
const classNames = [];
|
|
48
|
+
|
|
49
|
+
if (defaultClass) {
|
|
50
|
+
classNames.push(defaultClass);
|
|
51
|
+
}
|
|
52
|
+
|
|
53
|
+
if (!loaded) {
|
|
54
|
+
classNames.push('hidden');
|
|
55
|
+
}
|
|
56
|
+
|
|
57
|
+
return classNames.join(' ');
|
|
58
|
+
}, [loaded]);
|
|
59
|
+
|
|
41
60
|
if (!visible) {
|
|
42
61
|
return (
|
|
43
62
|
<Visibility
|
|
@@ -77,6 +96,7 @@ const LazyDocument = (props: Props) => {
|
|
|
77
96
|
{ !error && props.preview && (
|
|
78
97
|
<Image
|
|
79
98
|
{...props.image}
|
|
99
|
+
className={getClassNames()}
|
|
80
100
|
onError={() => {
|
|
81
101
|
setError(true);
|
|
82
102
|
setLoaded(true);
|
|
@@ -92,6 +112,7 @@ const LazyDocument = (props: Props) => {
|
|
|
92
112
|
{ !error && loaded && !props.preview && props.src && props.pdf && (
|
|
93
113
|
<Image
|
|
94
114
|
{...props.image}
|
|
115
|
+
className={getClassNames()}
|
|
95
116
|
size={props.size}
|
|
96
117
|
>
|
|
97
118
|
<Document
|
|
@@ -107,7 +128,7 @@ const LazyDocument = (props: Props) => {
|
|
|
107
128
|
{ (error || (!props.preview && !(props.src && props.pdf))) && (
|
|
108
129
|
<Image
|
|
109
130
|
{...props.image}
|
|
110
|
-
className='placeholder-image'
|
|
131
|
+
className={getClassNames('placeholder-image')}
|
|
111
132
|
size={props.size}
|
|
112
133
|
>
|
|
113
134
|
<Icon
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
// @flow
|
|
2
2
|
|
|
3
|
-
import React, { useState, type Node } from 'react';
|
|
3
|
+
import React, { useCallback, useState, type Node } from 'react';
|
|
4
4
|
import {
|
|
5
5
|
Button,
|
|
6
6
|
Dimmer,
|
|
@@ -36,6 +36,25 @@ const LazyImage = (props: Props) => {
|
|
|
36
36
|
const [modal, setModal] = useState(false);
|
|
37
37
|
const [visible, setVisible] = useState(false);
|
|
38
38
|
|
|
39
|
+
/**
|
|
40
|
+
* Returns the list of class names for the image component.
|
|
41
|
+
*
|
|
42
|
+
* @type {function(*=): []}
|
|
43
|
+
*/
|
|
44
|
+
const getClassNames = useCallback((defaultClass = null) => {
|
|
45
|
+
const classNames = [];
|
|
46
|
+
|
|
47
|
+
if (defaultClass) {
|
|
48
|
+
classNames.push(defaultClass);
|
|
49
|
+
}
|
|
50
|
+
|
|
51
|
+
if (!loaded) {
|
|
52
|
+
classNames.push('hidden');
|
|
53
|
+
}
|
|
54
|
+
|
|
55
|
+
return classNames.join(' ');
|
|
56
|
+
}, [loaded]);
|
|
57
|
+
|
|
39
58
|
if (!visible) {
|
|
40
59
|
return (
|
|
41
60
|
<Visibility
|
|
@@ -75,6 +94,7 @@ const LazyImage = (props: Props) => {
|
|
|
75
94
|
{ !error && (props.preview || props.src) && (
|
|
76
95
|
<Image
|
|
77
96
|
{...props.image}
|
|
97
|
+
className={getClassNames()}
|
|
78
98
|
onError={() => {
|
|
79
99
|
setError(true);
|
|
80
100
|
setLoaded(true);
|
|
@@ -90,7 +110,7 @@ const LazyImage = (props: Props) => {
|
|
|
90
110
|
{ (error || !(props.preview || props.src)) && (
|
|
91
111
|
<Image
|
|
92
112
|
{...props.image}
|
|
93
|
-
className='placeholder-image'
|
|
113
|
+
className={getClassNames('placeholder-image')}
|
|
94
114
|
size={props.size}
|
|
95
115
|
>
|
|
96
116
|
<Icon
|
|
@@ -1,6 +1,11 @@
|
|
|
1
1
|
// @flow
|
|
2
2
|
|
|
3
|
-
import React, {
|
|
3
|
+
import React, {
|
|
4
|
+
useCallback,
|
|
5
|
+
useState,
|
|
6
|
+
type Element,
|
|
7
|
+
type Node
|
|
8
|
+
} from 'react';
|
|
4
9
|
import {
|
|
5
10
|
Button,
|
|
6
11
|
Dimmer,
|
|
@@ -39,6 +44,25 @@ const LazyVideo = (props: Props) => {
|
|
|
39
44
|
const [modal, setModal] = useState(false);
|
|
40
45
|
const [visible, setVisible] = useState(false);
|
|
41
46
|
|
|
47
|
+
/**
|
|
48
|
+
* Returns the list of class names for the image component.
|
|
49
|
+
*
|
|
50
|
+
* @type {function(*=): []}
|
|
51
|
+
*/
|
|
52
|
+
const getClassNames = useCallback((defaultClass = null) => {
|
|
53
|
+
const classNames = [];
|
|
54
|
+
|
|
55
|
+
if (defaultClass) {
|
|
56
|
+
classNames.push(defaultClass);
|
|
57
|
+
}
|
|
58
|
+
|
|
59
|
+
if (!loaded) {
|
|
60
|
+
classNames.push('hidden');
|
|
61
|
+
}
|
|
62
|
+
|
|
63
|
+
return classNames.join(' ');
|
|
64
|
+
}, [loaded]);
|
|
65
|
+
|
|
42
66
|
if (!visible) {
|
|
43
67
|
return (
|
|
44
68
|
<Visibility
|
|
@@ -78,6 +102,7 @@ const LazyVideo = (props: Props) => {
|
|
|
78
102
|
{ !error && props.preview && (
|
|
79
103
|
<Image
|
|
80
104
|
{...props.image}
|
|
105
|
+
className={getClassNames()}
|
|
81
106
|
onError={() => {
|
|
82
107
|
setError(true);
|
|
83
108
|
setLoaded(true);
|
|
@@ -93,6 +118,7 @@ const LazyVideo = (props: Props) => {
|
|
|
93
118
|
{ !error && !props.preview && props.src && (
|
|
94
119
|
<Image
|
|
95
120
|
{...props.image}
|
|
121
|
+
className={getClassNames()}
|
|
96
122
|
size={props.size}
|
|
97
123
|
>
|
|
98
124
|
<video
|
|
@@ -111,7 +137,7 @@ const LazyVideo = (props: Props) => {
|
|
|
111
137
|
{ (error || (!props.preview && !props.src)) && (
|
|
112
138
|
<Image
|
|
113
139
|
{...props.image}
|
|
114
|
-
className='placeholder-image'
|
|
140
|
+
className={getClassNames('placeholder-image')}
|
|
115
141
|
size={props.size}
|
|
116
142
|
>
|
|
117
143
|
<Icon
|
package/types/index.js.flow
CHANGED
|
@@ -45,6 +45,7 @@ export { default as GoogleMap } from './components/GoogleMap';
|
|
|
45
45
|
export { default as GooglePlacesSearch } from './components/GooglePlacesSearch';
|
|
46
46
|
export { default as HorizontalCards } from './components/HorizontalCards';
|
|
47
47
|
export { default as IIIFModal } from './components/IIIFModal';
|
|
48
|
+
export { default as ImageCarousel } from './components/ImageCarousel';
|
|
48
49
|
export { default as ItemCollection } from './components/ItemCollection';
|
|
49
50
|
export { default as ItemList } from './components/ItemList';
|
|
50
51
|
export { default as Items } from './components/Items';
|