Ad: dismiss the infobox when clicked outside
This commit is contained in:
parent
c0f4130edf
commit
01bddbce4d
|
@ -1,4 +1,4 @@
|
||||||
import React, { useState, useEffect } from 'react';
|
import React, { useState, useEffect, useRef } from 'react';
|
||||||
import { FormattedMessage } from 'react-intl';
|
import { FormattedMessage } from 'react-intl';
|
||||||
|
|
||||||
import { Stack, HStack, Card, Avatar, Text, Icon } from 'soapbox/components/ui';
|
import { Stack, HStack, Card, Avatar, Text, Icon } from 'soapbox/components/ui';
|
||||||
|
@ -19,8 +19,30 @@ interface IAd {
|
||||||
const Ad: React.FC<IAd> = ({ card, impression }) => {
|
const Ad: React.FC<IAd> = ({ card, impression }) => {
|
||||||
const instance = useAppSelector(state => state.instance);
|
const instance = useAppSelector(state => state.instance);
|
||||||
|
|
||||||
|
const infobox = useRef<HTMLDivElement>(null);
|
||||||
const [showInfo, setShowInfo] = useState(false);
|
const [showInfo, setShowInfo] = useState(false);
|
||||||
|
|
||||||
|
/** Toggle the info box on click. */
|
||||||
|
const handleInfoButtonClick: React.MouseEventHandler = () => {
|
||||||
|
setShowInfo(!showInfo);
|
||||||
|
};
|
||||||
|
|
||||||
|
/** Hide the info box when clicked outside. */
|
||||||
|
const handleClickOutside = (event: MouseEvent) => {
|
||||||
|
if (event.target && infobox.current && !infobox.current.contains(event.target as any)) {
|
||||||
|
setShowInfo(false);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
// Hide the info box when clicked outside.
|
||||||
|
// https://stackoverflow.com/a/42234988
|
||||||
|
useEffect(() => {
|
||||||
|
document.addEventListener('mousedown', handleClickOutside);
|
||||||
|
return () => {
|
||||||
|
document.removeEventListener('mousedown', handleClickOutside);
|
||||||
|
};
|
||||||
|
}, [infobox]);
|
||||||
|
|
||||||
// Fetch the impression URL (if any) upon displaying the ad.
|
// Fetch the impression URL (if any) upon displaying the ad.
|
||||||
// It's common for ad providers to provide this.
|
// It's common for ad providers to provide this.
|
||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
|
@ -29,11 +51,6 @@ const Ad: React.FC<IAd> = ({ card, impression }) => {
|
||||||
}
|
}
|
||||||
}, [impression]);
|
}, [impression]);
|
||||||
|
|
||||||
/** Toggle the info box on click. */
|
|
||||||
const handleInfoButtonClick: React.MouseEventHandler = () => {
|
|
||||||
setShowInfo(!showInfo);
|
|
||||||
};
|
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<div className='relative'>
|
<div className='relative'>
|
||||||
<Card className='p-5' variant='rounded'>
|
<Card className='p-5' variant='rounded'>
|
||||||
|
@ -76,7 +93,7 @@ const Ad: React.FC<IAd> = ({ card, impression }) => {
|
||||||
</Card>
|
</Card>
|
||||||
|
|
||||||
{showInfo && (
|
{showInfo && (
|
||||||
<div className='absolute top-5 right-5 max-w-xs'>
|
<div ref={infobox} className='absolute top-5 right-5 max-w-[234px]'>
|
||||||
<Card variant='rounded'>
|
<Card variant='rounded'>
|
||||||
<Stack space={2}>
|
<Stack space={2}>
|
||||||
<Text size='sm' weight='bold'>
|
<Text size='sm' weight='bold'>
|
||||||
|
|
Loading…
Reference in New Issue