Skip to content

Commit ec178b8

Browse files
committed
feat: add components prop
+ Add new prop for injecting custom loading component + Update stories
1 parent 166b379 commit ec178b8

File tree

4 files changed

+34
-10
lines changed

4 files changed

+34
-10
lines changed

packages/react/src/components/Card/CardEmpty.js

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -7,13 +7,13 @@ import { emptyStateAnimation, emptyStateImageAnimation } from './CardAnimation'
77
import CardImage from './CardMedia/Image'
88
import { Content } from './CardContent'
99
import { GlobalContext } from '../../context/GlobalState'
10-
import { isLarge, isSmall } from '../../utils'
10+
import { classNames, isLarge, isSmall } from '../../utils'
1111

1212
const Placeholder = styled.span.attrs({
13-
className: 'microlink_card_placeholder'
13+
className: classNames.placeholderContent
1414
})``
1515

16-
const MediaEmpty = styled(CardImage)`
16+
const MediaEmpty = styled(CardImage).attrs({ className: classNames.placeholderMedia })`
1717
${emptyStateImageAnimation};
1818
`
1919

packages/react/src/index.js

Lines changed: 15 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -32,14 +32,14 @@ import { useIntersectionObserver } from './utils/hooks'
3232
const Card = props => {
3333
const {
3434
className,
35+
components,
3536
fetchData,
3637
lazy,
3738
loading,
3839
media: mediaProp,
3940
setData,
4041
url,
4142
apiKey, // destructuring to avoid pass it
42-
placeholderComponent: CardEmpty,
4343
...restProps
4444
} = props
4545

@@ -54,6 +54,10 @@ const Card = props => {
5454
[mediaProps, props]
5555
)
5656

57+
const { PlaceholderComponent = CardEmpty } = components
58+
59+
const isLoading = isLoadingUndefined ? loadingState : loading
60+
5761
const isLazyEnabled = useMemo(
5862
() => isLazySupported && (lazy === true || isObject(lazy)),
5963
[lazy]
@@ -69,6 +73,12 @@ const Card = props => {
6973
[isLazyEnabled, hasIntersected]
7074
)
7175

76+
const cardWrapClassName = useMemo(() => {
77+
const base = `${classNames.main} ${isLoading ? classNames.placeholder : ''}`.trim()
78+
79+
return `${base} ${className}`.trim()
80+
}, [className, isLoading])
81+
7282
const toFetchData = useCallback(() => {
7383
if (canFetchData) {
7484
setLoading(true)
@@ -167,8 +177,6 @@ microlink.io/${error.code.toLowerCase()}
167177

168178
useEffect(toFetchData, [url, setData, hasIntersected])
169179

170-
const isLoading = isLoadingUndefined ? loadingState : loading
171-
172180
if (isError) {
173181
return (
174182
<a href={url} {...restProps}>
@@ -200,14 +208,14 @@ microlink.io/${error.code.toLowerCase()}
200208

201209
return (
202210
<CardWrap
203-
className={`${classNames.main} ${className}`.trim()}
211+
className={cardWrapClassName}
204212
href={url}
205213
isLoading={isLoading}
206214
ref={cardRef}
207215
{...restProps}
208216
>
209217
{isLoading ? (
210-
<CardEmpty />
218+
<PlaceholderComponent />
211219
) : (
212220
<>
213221
<CardMedia />
@@ -225,8 +233,8 @@ const Microlink = props => (
225233
Microlink.defaultProps = {
226234
className: '',
227235
apiKey: undefined,
228-
placeholderComponent: CardEmpty,
229236
autoPlay: true,
237+
components: { PlaceholderComponent: CardEmpty },
230238
controls: true,
231239
direction: 'ltr',
232240
lazy: true,
@@ -241,6 +249,7 @@ Microlink.defaultProps = {
241249
Microlink.propTypes = {
242250
apiKey: PropTypes.string,
243251
autoPlay: PropTypes.bool,
252+
components: PropTypes.shape({ PlaceholderComponent: PropTypes.elementType }),
244253
contrast: PropTypes.oneOfType([PropTypes.string, PropTypes.bool]),
245254
controls: PropTypes.bool,
246255
direction: PropTypes.string,

packages/react/src/utils/index.js

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -114,6 +114,7 @@ const BASE_CLASSNAME = 'microlink_card'
114114
const CONTENT_BASE_CLASSNAME = `${BASE_CLASSNAME}__content`
115115
const MEDIA_BASE_CLASSNAME = `${BASE_CLASSNAME}__media`
116116
const CONTROLS_BASE_CLASSNAME = `${MEDIA_BASE_CLASSNAME}__controls`
117+
const PLACEHOLDER_BASE_CLASSNAME = `${BASE_CLASSNAME}__placeholder`
117118

118119
export const classNames = {
119120
main: BASE_CLASSNAME,
@@ -137,5 +138,8 @@ export const classNames = {
137138
progressBar: `${CONTROLS_BASE_CLASSNAME}_progress_bar`,
138139
progressTime: `${CONTROLS_BASE_CLASSNAME}_progress_time`,
139140
spinner: `${CONTROLS_BASE_CLASSNAME}_spinner`,
140-
iframe: `${BASE_CLASSNAME}__iframe`
141+
iframe: `${BASE_CLASSNAME}__iframe`,
142+
placeholder: PLACEHOLDER_BASE_CLASSNAME,
143+
placeholderMedia: `${PLACEHOLDER_BASE_CLASSNAME}_media`,
144+
placeholderContent: `${PLACEHOLDER_BASE_CLASSNAME}_content`
141145
}

packages/react/stories/index.js

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,6 @@
11
import 'unfetch/polyfill'
22

3+
import React from 'react'
34
import { storiesOf } from '@storybook/react'
45

56
import { urls, urlsVideo, urlsAudio, urlsIframe } from './data'
@@ -207,3 +208,13 @@ storiesOf('style', module)
207208
})
208209
)
209210
)
211+
212+
const PlaceholderComponent = () => <strong style={{ height: '100%', width: '100%', display: 'flex', alignItems: 'center', justifyContent: 'center' }}>loading...</strong>
213+
214+
storiesOf('components', module)
215+
.add('PlaceholderComponent', () =>
216+
createStoryEntry({
217+
loading: true,
218+
fetchData: false,
219+
components: { PlaceholderComponent }
220+
}))

0 commit comments

Comments
 (0)