0
Fork 0
mirror of https://github.com/TryGhost/Ghost.git synced 2025-02-10 23:36:14 -05:00

Fixed comments dropdown menu being cutoff by iframe (#21555)

REF https://linear.app/ghost/issue/PLG-255/dropdown-cut-off-by-iframe
- Avoided menu cutoff by positioning the dropdown of the last comment
above the MoreButton
This commit is contained in:
Sanne de Vries 2024-11-07 11:39:52 +01:00 committed by GitHub
parent 274f2aa8d3
commit 5f7734bf36
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
3 changed files with 27 additions and 15 deletions

View file

@ -63,7 +63,7 @@ const Content = () => {
</span> </span>
</div> </div>
)} )}
<div className={!pagination ? 'z-10 mt-4' : 'z-10'} data-test="comment-elements"> <div className="z-10" data-test="comment-elements">
{commentsElements} {commentsElements}
</div> </div>
<Pagination /> <Pagination />

View file

@ -10,7 +10,7 @@ type Props = {
const MoreButton: React.FC<Props> = ({comment, toggleEdit}) => { const MoreButton: React.FC<Props> = ({comment, toggleEdit}) => {
const [isContextMenuOpen, setIsContextMenuOpen] = useState(false); const [isContextMenuOpen, setIsContextMenuOpen] = useState(false);
const {member, admin} = useAppContext(); const {member, admin, pagination, comments} = useAppContext();
const isAdmin = !!admin; const isAdmin = !!admin;
const toggleContextMenu = () => { const toggleContextMenu = () => {
@ -21,10 +21,10 @@ const MoreButton: React.FC<Props> = ({comment, toggleEdit}) => {
setIsContextMenuOpen(false); setIsContextMenuOpen(false);
}; };
/* // Check if this is the last comment and there's no more pagination
* Whether we have at least one action inside the context menu const isLastComment = (!pagination || pagination.total <= pagination.page * pagination.limit) &&
* (to hide the 'more' icon if we don't have any actions) comments[comments.length - 1]?.id === comment.id;
*/
const show = (!!member && comment.status === 'published') || isAdmin; const show = (!!member && comment.status === 'published') || isAdmin;
if (!show) { if (!show) {
@ -33,8 +33,10 @@ const MoreButton: React.FC<Props> = ({comment, toggleEdit}) => {
return ( return (
<div data-testid="more-button"> <div data-testid="more-button">
<button className="outline-0" type="button" onClick={toggleContextMenu}><MoreIcon className={`duration-50 gh-comments-icon gh-comments-icon-more outline-0 transition ease-linear hover:fill-black/75 dark:hover:fill-white/75 ${isContextMenuOpen ? 'fill-black/75 dark:fill-white/75' : 'fill-black/50 dark:fill-white/60'}`} /></button> <button className="outline-0" type="button" onClick={toggleContextMenu}>
{isContextMenuOpen ? <CommentContextMenu close={closeContextMenu} comment={comment} toggleEdit={toggleEdit} /> : null} <MoreIcon className={`duration-50 gh-comments-icon gh-comments-icon-more outline-0 transition ease-linear hover:fill-black/75 dark:hover:fill-white/75 ${isContextMenuOpen ? 'fill-black/75 dark:fill-white/75' : 'fill-black/50 dark:fill-white/60'}`} />
</button>
{isContextMenuOpen ? <CommentContextMenu close={closeContextMenu} comment={comment} isLastComment={isLastComment} toggleEdit={toggleEdit} /> : null}
</div> </div>
); );
}; };

View file

@ -1,20 +1,22 @@
import AdminContextMenu from './AdminContextMenu'; import AdminContextMenu from './AdminContextMenu';
import AuthorContextMenu from './AuthorContextMenu'; import AuthorContextMenu from './AuthorContextMenu';
import NotAuthorContextMenu from './NotAuthorContextMenu'; import NotAuthorContextMenu from './NotAuthorContextMenu';
import {Comment, useAppContext} from '../../../AppContext'; import {Comment, useAppContext, useLabs} from '../../../AppContext';
import {useEffect, useRef} from 'react'; import {useEffect, useRef} from 'react';
type Props = { type Props = {
comment: Comment; comment: Comment;
close: () => void; close: () => void;
toggleEdit: () => void; toggleEdit: () => void;
isLastComment?: boolean;
}; };
const CommentContextMenu: React.FC<Props> = ({comment, close, toggleEdit}) => { const CommentContextMenu: React.FC<Props> = ({comment, close, toggleEdit, isLastComment}) => {
const {member, admin} = useAppContext(); const {member, admin} = useAppContext();
const isAuthor = member && comment.member?.uuid === member?.uuid; const isAuthor = member && comment.member?.uuid === member?.uuid;
const isAdmin = !!admin; const isAdmin = !!admin;
const element = useRef<HTMLDivElement>(null); const element = useRef<HTMLDivElement>(null);
const labs = useLabs();
useEffect(() => { useEffect(() => {
const listener = () => { const listener = () => {
close(); close();
@ -76,11 +78,19 @@ const CommentContextMenu: React.FC<Props> = ({comment, close, toggleEdit}) => {
} }
return ( return (
<div ref={element} onClick={stopPropagation}> labs.commentImprovements ? (
<div className="absolute z-10 min-w-min whitespace-nowrap rounded bg-white py-3 pl-4 pr-8 font-sans text-sm shadow-lg outline-0 sm:min-w-36 dark:bg-neutral-800 dark:text-white"> <div ref={element} className="relative" onClick={stopPropagation}>
{contextMenu} <div className={`absolute z-10 min-w-min whitespace-nowrap rounded bg-white py-3 pl-4 pr-8 font-sans text-sm shadow-lg outline-0 sm:min-w-36 dark:bg-neutral-800 dark:text-white ${isLastComment ? 'bottom-full mb-6' : 'top-0'}`}>
{contextMenu}
</div>
</div> </div>
</div> ) : (
<div ref={element} onClick={stopPropagation}>
<div className="absolute z-10 min-w-min whitespace-nowrap rounded bg-white py-3 pl-4 pr-8 font-sans text-sm shadow-lg outline-0 sm:min-w-36 dark:bg-neutral-800 dark:text-white">
{contextMenu}
</div>
</div>
)
); );
}; };