Emails
1 month ago
EngagementChart
1 month ago
MediaHub
1 month ago
Onboarding
1 month ago
Popup
1 month ago
Skeletons
1 week ago
WhatsNew
1 month ago
charts
1 month ago
test
1 month ago
AdminMenuSync.js
1 month ago
ChartEmptyState.js
1 month ago
ChooseDate.js
1 month ago
ColorPicker.js
1 month ago
ExtendPlugins.js
1 month ago
Filters.js
1 month ago
Link.js
1 month ago
Navbar.js
1 week ago
NoFound.js
1 month ago
PageHeader.js
1 month ago
PluginRecommendations.js
1 month ago
PostScheduleField.js
1 month ago
PrestoPlayerIcon.js
1 month ago
ProGateOverlay.js
1 month ago
QuickAccess.js
1 month ago
RankedTable.js
1 month ago
StatCard.js
1 month ago
TopMedia.js
1 month ago
TopPerformingMedia.js
1 month ago
TopUsers.js
1 month ago
TruncatedTitle.js
1 month ago
UpgradeNotice.js
1 month ago
UpgradeToPro.js
1 month ago
VideoModal.js
1 month ago
WelcomeBanner.js
1 month ago
VideoModal.js
73 lines
| 1 | import React, { useEffect, useRef } from "react"; |
| 2 | import { __ } from "@wordpress/i18n"; |
| 3 | import { Dialog, Text, Button } from "@bsf/force-ui"; |
| 4 | import { X } from "lucide-react"; |
| 5 | |
| 6 | const YOUTUBE_EMBED_URL = |
| 7 | "https://www.youtube-nocookie.com/embed/7ibtk_KTgCw?si=f0atBqLnA_6gxXC6&autoplay=1&enablejsapi=1"; |
| 8 | |
| 9 | const VideoModal = ({ isOpen, onClose, triggerRef }) => { |
| 10 | const closeRef = useRef(null); |
| 11 | const wasOpenRef = useRef(false); |
| 12 | |
| 13 | // Restore focus to the trigger element only when modal transitions from open to closed |
| 14 | useEffect(() => { |
| 15 | if (wasOpenRef.current && !isOpen) { |
| 16 | triggerRef?.current?.focus(); |
| 17 | } |
| 18 | wasOpenRef.current = isOpen; |
| 19 | }, [isOpen, triggerRef]); |
| 20 | |
| 21 | // Move focus to the close button when the modal opens |
| 22 | useEffect(() => { |
| 23 | if (isOpen) { |
| 24 | // Small delay to let Dialog render before focusing |
| 25 | const id = requestAnimationFrame(() => closeRef.current?.focus()); |
| 26 | return () => cancelAnimationFrame(id); |
| 27 | } |
| 28 | }, [isOpen]); |
| 29 | |
| 30 | return ( |
| 31 | <Dialog |
| 32 | design="simple" |
| 33 | exitOnClickOutside |
| 34 | exitOnEsc |
| 35 | scrollLock |
| 36 | open={isOpen} |
| 37 | setOpen={(open) => { |
| 38 | if (!open) onClose(); |
| 39 | }} |
| 40 | > |
| 41 | <Dialog.Backdrop className="bg-black bg-opacity-70" /> |
| 42 | <Dialog.Panel |
| 43 | className="bg-transparent shadow-none border-none max-w-[80vw] w-full p-0 overflow-visible gap-2" |
| 44 | aria-label={__("Introduction video", "presto-player")} |
| 45 | > |
| 46 | <div className="flex justify-end items-center gap-2 text-text-inverse"> |
| 47 | <Text as="span" size="sm" weight="medium" className="text-text-inverse"> |
| 48 | {__("Esc", "presto-player")} |
| 49 | </Text> |
| 50 | <Button |
| 51 | ref={closeRef} |
| 52 | variant="ghost" |
| 53 | size="sm" |
| 54 | className="cursor-pointer bg-transparent border-none text-text-inverse hover:bg-transparent focus-visible:ring-2 focus-visible:ring-white focus-visible:ring-offset-2 focus-visible:ring-offset-transparent min-w-6 min-h-6" |
| 55 | onClick={onClose} |
| 56 | aria-label={__("Close video (Esc)", "presto-player")} |
| 57 | icon={<X size={20} />} |
| 58 | /> |
| 59 | </div> |
| 60 | <iframe |
| 61 | className="w-full lg:h-188 sm:h-120 h-60 rounded-lg border-0" |
| 62 | src={isOpen ? YOUTUBE_EMBED_URL : undefined} |
| 63 | title={__("Presto Player introduction video", "presto-player")} |
| 64 | allow="autoplay; encrypted-media" |
| 65 | allowFullScreen |
| 66 | /> |
| 67 | </Dialog.Panel> |
| 68 | </Dialog> |
| 69 | ); |
| 70 | }; |
| 71 | |
| 72 | export default VideoModal; |
| 73 |