Skip to content
This repository was archived by the owner on Feb 27, 2024. It is now read-only.

Commit 217fb4e

Browse files
committed
Adding Twitter and Video Embed block components
1 parent 62f42ae commit 217fb4e

File tree

12 files changed

+193
-82
lines changed

12 files changed

+193
-82
lines changed
Lines changed: 58 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,58 @@
1+
import cn from 'classnames'
2+
import PropTypes from 'prop-types'
3+
import styles from './TwitterEmbed.module.css'
4+
import {useEffect, useRef} from 'react'
5+
import RichText from '@/components/atoms/RichText'
6+
7+
/**
8+
* TwitterEmbed Block
9+
*
10+
* @author WebDevStudios
11+
* @param {object} props TwitterEmbed component props.
12+
* @param {string} props.className Optional className.
13+
* @param {string} props.caption Optional caption.
14+
* @param {string} props.url The full URL to the video.
15+
* @return {Element} The TwitterEmbed component.
16+
*/
17+
export default function TwitterEmbed({className, caption, url}) {
18+
const tweetRef = useRef(null)
19+
20+
useEffect(() => {
21+
if (url === '') {
22+
return
23+
}
24+
// @see https://stackoverflow.com/a/43268098/921927
25+
const proxyUrl = 'https://cors-anywhere.herokuapp.com/',
26+
targetUrl = `https://publish.twitter.com/oembed?url=${url}`
27+
fetch(proxyUrl + targetUrl)
28+
.then((response) => response.json())
29+
.then((data) => {
30+
if (data && data.html) {
31+
// @see https://stackoverflow.com/a/43268098/921927
32+
// Create slot for executing a script file.
33+
const slotHtml = document
34+
.createRange()
35+
.createContextualFragment(data.html) // Create a 'tiny' document and parse the html string.
36+
tweetRef.current.innerHTML = '' // Clear the container.
37+
tweetRef.current.appendChild(slotHtml) // Append the new content.
38+
}
39+
})
40+
}, [])
41+
42+
return (
43+
<div className={cn(styles.twitterEmbed, className)}>
44+
<div ref={tweetRef}></div>
45+
{!!caption && (
46+
<div className={styles.caption}>
47+
<RichText tag="span">{caption}</RichText>
48+
</div>
49+
)}
50+
</div>
51+
)
52+
}
53+
54+
TwitterEmbed.propTypes = {
55+
className: PropTypes.string,
56+
caption: PropTypes.string,
57+
url: PropTypes.string.isRequired
58+
}
Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,7 @@
1+
.twitterEmbed {
2+
@apply block;
3+
4+
& .caption {
5+
@apply text-center font-secondary text-xs pt-12;
6+
}
7+
}
Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,18 @@
1+
import {Meta, Story, Canvas} from '@storybook/addon-docs/blocks'
2+
3+
import TwitterEmbed from '.'
4+
5+
<Meta title="Components/Atoms/TwitterEmbed" component={TwitterEmbed} />
6+
7+
# Twitter Embed
8+
9+
Use this to display a tweet from a timeline
10+
11+
<Canvas>
12+
<Story name="Component">
13+
<TwitterEmbed
14+
url="https://twitter.com/webdevstudios/status/1351167649418514432"
15+
caption="This is an optional caption"
16+
/>
17+
</Story>
18+
</Canvas>
Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
export {default} from './TwitterEmbed'
Lines changed: 70 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,70 @@
1+
import cn from 'classnames'
2+
import PropTypes from 'prop-types'
3+
import React from 'react'
4+
import RichText from '@/components/atoms/RichText'
5+
import styles from './VideoEmbed.module.css'
6+
7+
/**
8+
* VideoEmbed Block
9+
*
10+
* @author WebDevStudios
11+
* @param {object} props VideoEmbed component props.
12+
* @param {string} props.className Optional className.
13+
* @param {string} props.url The full URL to the video.
14+
* @param {string} props.type The type of video (youtube, vimeo).
15+
* @param {string} props.caption Optional caption.
16+
* @return {Element} The VideoEmbed component.
17+
*/
18+
export default function VideoEmbed({className, url, type, caption}) {
19+
/**
20+
* Create URL embed for YouTube or Vimeo videos.
21+
*
22+
* @param {string} url The video URL.
23+
*/
24+
function createVideoUrl(url) {
25+
if (!url) {
26+
return false
27+
}
28+
29+
let videoUrl, videoId
30+
31+
videoId = url.indexOf('v=') !== -1 ? url.split('v=') : url.split('/')
32+
videoId = videoId[videoId.length - 1]
33+
34+
videoUrl = url.includes('vimeo')
35+
? `//player.vimeo.com/video/${videoId}`
36+
: `//youtube.com/embed/${videoId}`
37+
38+
return videoUrl
39+
}
40+
41+
return (
42+
<div className={cn(styles.videoEmbed, className)}>
43+
<div className={styles.wrapper}>
44+
<iframe
45+
allow="accelerometer; autoplay; clipboard-write; encrypted-media; gyroscope; picture-in-picture"
46+
allowFullScreen
47+
frameBorder="0"
48+
height="315"
49+
loading="lazy"
50+
src={createVideoUrl(url)}
51+
width="560"
52+
title={`Embedded content from ${type}`}
53+
className={className}
54+
></iframe>
55+
</div>
56+
{!!caption && (
57+
<div className={styles.caption}>
58+
<RichText tag="span">{caption}</RichText>
59+
</div>
60+
)}
61+
</div>
62+
)
63+
}
64+
65+
VideoEmbed.propTypes = {
66+
className: PropTypes.string,
67+
caption: PropTypes.string,
68+
type: PropTypes.string,
69+
url: PropTypes.string.isRequired
70+
}
Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,17 @@
1+
.videoEmbed {
2+
@apply mb-24;
3+
4+
& .wrapper {
5+
@apply w-full relative overflow-hidden;
6+
7+
padding-top: 56.25%;
8+
}
9+
10+
& iframe {
11+
@apply absolute w-full h-full inset-0;
12+
}
13+
14+
& .caption {
15+
@apply text-center font-secondary text-xs pt-12;
16+
}
17+
}

components/molecules/VideoEmbed/VideoEmbed.stories.mdx renamed to components/atoms/VideoEmbed/VideoEmbed.stories.mdx

Lines changed: 5 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -2,15 +2,18 @@ import {Meta, Story, Canvas} from '@storybook/addon-docs/blocks'
22

33
import VideoEmbed from '.'
44

5-
<Meta title="Design System/Organisms/VideoEmbed" component={VideoEmbed} />
5+
<Meta title="Components/Atoms/VideoEmbed" component={VideoEmbed} />
66

77
# Video Embed
88

99
Use this to display a video in iFrame, pass the YouTube video ID to the `VideoEmbed` component.
1010

1111
<Canvas>
1212
<Story name="Component">
13-
<VideoEmbed url="https://www.youtube.com/watch?v=ebQbQufIb0E" />
13+
<VideoEmbed
14+
url="https://www.youtube.com/watch?v=ebQbQufIb0E"
15+
caption="This is an optional caption"
16+
/>
1417
</Story>
1518
</Canvas>
1619

components/blocks/BlockEmbed/BlockEmbed.js

Lines changed: 17 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -1,42 +1,41 @@
1-
import VideoEmbed from '@/components/molecules/VideoEmbed'
1+
import TwitterEmbed from '@/components/atoms/TwitterEmbed'
2+
import VideoEmbed from '@/components/atoms/VideoEmbed'
23
import PropTypes from 'prop-types'
3-
import React, {useState, useEffect} from 'react'
4+
import React from 'react'
45

56
/**
67
* Embed Block
78
*
89
* The core Embed block from Gutenberg.
910
*
1011
* @author WebDevStudios
11-
* @param {string} className Optional classnames.
12-
* @param {string} align Optional alignment style.
13-
* @param {string} anchor Optional anchor/id.
14-
* @param {string} content The content of the block.
15-
* @param {string} level The heading level.
16-
* @return {Element} The component to embed.
12+
* @param {string} className Optional classnames.
13+
* @param {string} url The URL of the video.
14+
* @param {string} caption Optional caption.
15+
* @param {string} align Block alignment caption.
16+
* @param {string} providerNameSlug The type of embed.
17+
* @return {Element} The component to embed.
1718
*/
1819
export default function BlockEmbed({
1920
className,
2021
url,
2122
caption,
2223
providerNameSlug
2324
}) {
24-
if (providerNameSlug === 'twitter') {
25-
fetch(
26-
'https://publish.twitter.com/oembed?url=https://twitter.com/Interior/status/463440424141459456'
27-
)
28-
.then((response) => response.json())
29-
.then((data) => console.log(data))
30-
}
31-
3225
return (
3326
<>
3427
{!!url && (
3528
<>
3629
{providerNameSlug === 'twitter' ? (
37-
<div></div>
30+
<TwitterEmbed className={className} url={url} caption={caption} />
3831
) : (
39-
<VideoEmbed className={className} url={url} caption={caption} />
32+
// <div dangerouslySetInnerHTML={{__html: tweetContent}} />
33+
<VideoEmbed
34+
className={className}
35+
url={url}
36+
caption={caption}
37+
type={providerNameSlug}
38+
/>
4039
)}
4140
</>
4241
)}

components/molecules/VideoEmbed/VideoEmbed.js

Lines changed: 0 additions & 52 deletions
This file was deleted.

0 commit comments

Comments
 (0)