Ad: dismiss the infobox when clicked outside
This commit is contained in:
parent
c0f4130edf
commit
01bddbce4d
1 changed files with 24 additions and 7 deletions
|
@ -1,4 +1,4 @@
|
|||
import React, { useState, useEffect } from 'react';
|
||||
import React, { useState, useEffect, useRef } from 'react';
|
||||
import { FormattedMessage } from 'react-intl';
|
||||
|
||||
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 instance = useAppSelector(state => state.instance);
|
||||
|
||||
const infobox = useRef<HTMLDivElement>(null);
|
||||
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.
|
||||
// It's common for ad providers to provide this.
|
||||
useEffect(() => {
|
||||
|
@ -29,11 +51,6 @@ const Ad: React.FC<IAd> = ({ card, impression }) => {
|
|||
}
|
||||
}, [impression]);
|
||||
|
||||
/** Toggle the info box on click. */
|
||||
const handleInfoButtonClick: React.MouseEventHandler = () => {
|
||||
setShowInfo(!showInfo);
|
||||
};
|
||||
|
||||
return (
|
||||
<div className='relative'>
|
||||
<Card className='p-5' variant='rounded'>
|
||||
|
@ -76,7 +93,7 @@ const Ad: React.FC<IAd> = ({ card, impression }) => {
|
|||
</Card>
|
||||
|
||||
{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'>
|
||||
<Stack space={2}>
|
||||
<Text size='sm' weight='bold'>
|
||||
|
|
Loading…
Reference in a new issue