-
Notifications
You must be signed in to change notification settings - Fork 100
Expand file tree
/
Copy pathVideoButtonWithModal.tsx
More file actions
142 lines (131 loc) · 4.4 KB
/
VideoButtonWithModal.tsx
File metadata and controls
142 lines (131 loc) · 4.4 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
import { useState } from "react";
import { Dialog } from "@headlessui/react";
import getVideoEmbedURL from "./util";
// https://www.tailwind-variants.org/docs
import { tv } from "tailwind-variants";
import VideoIcon from "../svg/VideoIcon";
import VideoIconDark from "../svg/VideoIconDark";
type VideoButtonModalProps = {
src: string;
title?: string;
showThumbnail?: boolean;
};
const PLAY_BUTTON_BASE_CLASS =
"nx-flex nx-items-center nx-px-2 nx-py-1 nx-text-xs nx-font-semibold nx-text-purple140 nx-shadow-sm focus-visible:nx-outline focus-visible:nx-outline-2 focus-visible:nx-outline-offset-2 focus-visible:nx-outline-purple140";
function getLoomShareURL(embedURL: string): string | null {
if (!embedURL.includes("loom.com")) {
return null;
}
// Convert loom.com/embed/VIDEO_ID to loom.com/share/VIDEO_ID
return embedURL.replace("/embed/", "/share/");
}
export default function VideoButtonWithModal({
title = "Video about this feature",
showThumbnail = true,
...props
}: VideoButtonModalProps) {
const embedURL = getVideoEmbedURL(props.src);
let [isOpen, setIsOpen] = useState(false);
// If it's a Loom URL, return a simple link instead of the modal
const loomShareURL = getLoomShareURL(embedURL);
if (loomShareURL) {
return (
<p style={{ marginTop: "1.5rem" }}>
<a
href={loomShareURL}
target="_blank"
rel="noopener noreferrer"
className="nextra-focus _text-primary-600 _underline hover:_no-underline _decoration-from-font [text-underline-position:from-font]"
>
Link to Demo
</a>
</p>
);
}
// TODO: update this style and abstract it as time allows to a single button component
// https://www.figma.com/design/8kiticjQNChvsP9y7s9SRf/Product-Releases-(Copy)?node-id=982-75355&node-type=frame&t=O7vwnwoAoOx42stw-0
const playButtonClass = showThumbnail
? `thumbnailPlayButton ${PLAY_BUTTON_BASE_CLASS}`
: `playButton ${PLAY_BUTTON_BASE_CLASS}`;
const playButtonWrapperClass = showThumbnail
? `thumbnailPlayButtonWrapper`
: `playButtonWrapper`;
const playButton = tv({
base: playButtonClass,
variants: {
showThumbnail: {
true: "nx-rounded-2xl nx-px-4 nx-py-4 nx-relative",
false:
"nx-border-2 nx-border-purple140 nx-rounded-full hover:nx-rounded-lg",
},
},
});
const buttonWrapper = tv({
base: playButtonWrapperClass,
variants: {
showThumbnail: {
true: "nx-relative nx-z-0 nx-w-fit nx-rounded-2xl nx-mt-10 nx-mb-10",
},
},
});
return (
<div className={buttonWrapper({ showThumbnail: showThumbnail })}>
<button
type="button"
className={playButton({ showThumbnail: showThumbnail })}
onClick={() => setIsOpen(true)}
>
{showThumbnail ? (
<iframe
src={embedURL}
style={{
width: "170px",
aspectRatio: 16 / 9,
height: "auto",
borderRadius: "8px",
marginRight: "16px",
zIndex: "-1",
}}
allow="accelerometer; clipboard-write; encrypted-media; gyroscope; picture-in-picture"
title={title}
onClick={(e) => {
e.preventDefault();
}}
></iframe>
) : (
<span className={"videoIconWrapper"}>
<span className={"videoIconLight"}>
<VideoIcon />
</span>
<span className={"videoIconDark"}>
<VideoIconDark />
</span>
</span>
)}
{`Watch the video ${showThumbnail ? `→` : ``}`}
</button>
<Dialog
open={isOpen}
onClose={() => setIsOpen(false)}
className="relative z-50"
>
<div className="nx-fixed nx-inset-0 nx-flex nx-w-screen nx-items-center nx-justify-center nx-p-4 nx-bg-black nx-bg-opacity-80 nx-z-20">
<Dialog.Panel className="nx-w-full nx-max-w-6xl">
<iframe
src={embedURL}
style={{
width: "100%",
aspectRatio: 16 / 9,
height: "auto",
borderRadius: "16px",
}}
allow="accelerometer; clipboard-write; encrypted-media; gyroscope; picture-in-picture"
title={title}
allowFullScreen
></iframe>
</Dialog.Panel>
</div>
</Dialog>
</div>
);
}