mirror of
https://github.com/bitsocialnet/5chan.git
synced 2026-08-03 07:41:04 +02:00
fix(react): address Doctor findings (#1143)
Accessibility/semantics pass aligned with React Doctor: role-based spans/divs become real buttons, role=status becomes <output>, modals use native <dialog>, author/peer flags render as <img>, and embed/challenge iframes are sandboxed. Includes review follow-ups: correct button chrome/centering/themed dialog colors and focus rings, the missing aria-label i18n keys (all languages), the Yandex image-search URL, clearer .bso setup steps, a keyboard-accessible image-search dropdown, and removal of the post-edit ('comment edited') display (mod edits unchanged).
This commit is contained in:
@@ -70,8 +70,8 @@ const CopyLinkButton = ({ cid, communityAddress, linkType, onClose }: CopyLinkBu
|
||||
onClose();
|
||||
};
|
||||
return (
|
||||
<div
|
||||
role='button'
|
||||
<button
|
||||
type='button'
|
||||
tabIndex={0}
|
||||
onClick={copyDirectLink}
|
||||
onKeyDown={(e) => {
|
||||
@@ -82,7 +82,7 @@ const CopyLinkButton = ({ cid, communityAddress, linkType, onClose }: CopyLinkBu
|
||||
}}
|
||||
>
|
||||
<div className={styles.postMenuItem}>{t('copy_direct_link')}</div>
|
||||
</div>
|
||||
</button>
|
||||
);
|
||||
};
|
||||
|
||||
@@ -93,8 +93,8 @@ const CopyContentIdButton = ({ cid, onClose }: { cid: string; onClose: () => voi
|
||||
onClose();
|
||||
};
|
||||
return (
|
||||
<div
|
||||
role='button'
|
||||
<button
|
||||
type='button'
|
||||
tabIndex={0}
|
||||
onClick={copyContentId}
|
||||
onKeyDown={(e) => {
|
||||
@@ -105,7 +105,7 @@ const CopyContentIdButton = ({ cid, onClose }: { cid: string; onClose: () => voi
|
||||
}}
|
||||
>
|
||||
<div className={styles.postMenuItem}>{t('copy_content_id')}</div>
|
||||
</div>
|
||||
</button>
|
||||
);
|
||||
};
|
||||
|
||||
@@ -116,8 +116,8 @@ const CopyUserIdButton = ({ address, onClose }: { address: string; onClose: () =
|
||||
onClose();
|
||||
};
|
||||
return (
|
||||
<div
|
||||
role='button'
|
||||
<button
|
||||
type='button'
|
||||
tabIndex={0}
|
||||
onClick={copyUserId}
|
||||
onKeyDown={(e) => {
|
||||
@@ -128,7 +128,7 @@ const CopyUserIdButton = ({ address, onClose }: { address: string; onClose: () =
|
||||
}}
|
||||
>
|
||||
<div className={styles.postMenuItem}>{t('copy_user_id')}</div>
|
||||
</div>
|
||||
</button>
|
||||
);
|
||||
};
|
||||
|
||||
@@ -136,32 +136,20 @@ const ImageSearchButtons = ({ url, onClose }: { url: string; onClose: () => void
|
||||
const { t } = useTranslation();
|
||||
const encodedUrl = encodeURIComponent(url);
|
||||
return (
|
||||
<div
|
||||
role='button'
|
||||
tabIndex={0}
|
||||
onClick={onClose}
|
||||
onKeyDown={(e) => {
|
||||
if (e.key === 'Enter' || e.key === ' ') {
|
||||
e.preventDefault();
|
||||
onClose();
|
||||
}
|
||||
}}
|
||||
>
|
||||
<a href={`https://lens.google.com/uploadbyurl?url=${encodedUrl}`} target='_blank' rel='noopener noreferrer'>
|
||||
<div>
|
||||
<a href={`https://lens.google.com/uploadbyurl?url=${encodedUrl}`} target='_blank' rel='noopener noreferrer' onClick={onClose}>
|
||||
<div className={styles.postMenuItem}>{t('search_image_on_google')}</div>
|
||||
</a>
|
||||
<a href={`https://www.yandex.com/images/search?img_url=${encodedUrl}&rpt=imageview`} target='_blank' rel='noopener noreferrer'>
|
||||
<a href={`https://www.yandex.com/images/search?url=${encodedUrl}&rpt=imageview`} target='_blank' rel='noopener noreferrer' onClick={onClose}>
|
||||
<div className={styles.postMenuItem}>{t('search_image_on_yandex')}</div>
|
||||
</a>
|
||||
<a href={`https://saucenao.com/search.php?url=${encodedUrl}`} target='_blank' rel='noopener noreferrer'>
|
||||
<a href={`https://saucenao.com/search.php?url=${encodedUrl}`} target='_blank' rel='noopener noreferrer' onClick={onClose}>
|
||||
<div className={styles.postMenuItem}>{t('search_image_on_saucenao')}</div>
|
||||
</a>
|
||||
</div>
|
||||
);
|
||||
};
|
||||
|
||||
const { addChallenge } = useChallengesStore.getState();
|
||||
|
||||
const ReportPostButton = ({ onClose }: { onClose: () => void }) => {
|
||||
const { t } = useTranslation();
|
||||
const reportPost = () => {
|
||||
@@ -169,8 +157,8 @@ const ReportPostButton = ({ onClose }: { onClose: () => void }) => {
|
||||
onClose();
|
||||
};
|
||||
return (
|
||||
<div
|
||||
role='button'
|
||||
<button
|
||||
type='button'
|
||||
tabIndex={0}
|
||||
onClick={reportPost}
|
||||
onKeyDown={(e) => {
|
||||
@@ -181,7 +169,7 @@ const ReportPostButton = ({ onClose }: { onClose: () => void }) => {
|
||||
}}
|
||||
>
|
||||
<div className={styles.postMenuItem}>{t('report_post')}</div>
|
||||
</div>
|
||||
</button>
|
||||
);
|
||||
};
|
||||
|
||||
@@ -208,7 +196,7 @@ const DeletePostButton = ({ post, onClose }: DeletePostButtonProps) => {
|
||||
latestPostRef.current = resolvedPost;
|
||||
}, [resolvedPost]);
|
||||
const onChallenge = useCallback(async (...args: unknown[]) => {
|
||||
addChallenge([...args, latestPostRef.current]);
|
||||
useChallengesStore.getState().addChallenge([...args, latestPostRef.current]);
|
||||
}, []);
|
||||
|
||||
const deleteOptions = useMemo(
|
||||
@@ -252,8 +240,8 @@ const DeletePostButton = ({ post, onClose }: DeletePostButtonProps) => {
|
||||
};
|
||||
|
||||
return (
|
||||
<div
|
||||
role='button'
|
||||
<button
|
||||
type='button'
|
||||
tabIndex={0}
|
||||
onClick={deletePost}
|
||||
onKeyDown={(e) => {
|
||||
@@ -264,7 +252,7 @@ const DeletePostButton = ({ post, onClose }: DeletePostButtonProps) => {
|
||||
}}
|
||||
>
|
||||
<div className={styles.postMenuItem}>{t('delete_post')}</div>
|
||||
</div>
|
||||
</button>
|
||||
);
|
||||
};
|
||||
|
||||
@@ -283,8 +271,8 @@ const HidePostButton = ({ cid, comment, isReply, onClose, postCid }: HideButtonP
|
||||
};
|
||||
return (
|
||||
(!isInPostView || isReply) && (
|
||||
<div
|
||||
role='button'
|
||||
<button
|
||||
type='button'
|
||||
tabIndex={0}
|
||||
onClick={togglePostHidden}
|
||||
onKeyDown={(e) => {
|
||||
@@ -297,7 +285,7 @@ const HidePostButton = ({ cid, comment, isReply, onClose, postCid }: HideButtonP
|
||||
<div className={styles.postMenuItem}>
|
||||
{hidden ? (postCid === cid ? t('unhide_thread') : t('unhide_post')) : postCid === cid ? t('hide_thread') : t('hide_post')}
|
||||
</div>
|
||||
</div>
|
||||
</button>
|
||||
)
|
||||
);
|
||||
};
|
||||
@@ -343,10 +331,10 @@ const PostMenuMobile = ({ postMenu, editMenuPost }: PostMenuMobileProps) => {
|
||||
<>
|
||||
{!(deleted || removed) && (
|
||||
<>
|
||||
<span
|
||||
<button
|
||||
type='button'
|
||||
className={styles.postMenuBtn}
|
||||
title='Post menu'
|
||||
role='button'
|
||||
tabIndex={0}
|
||||
onClick={handleMenuClick}
|
||||
onKeyDown={(e) => {
|
||||
@@ -359,7 +347,7 @@ const PostMenuMobile = ({ postMenu, editMenuPost }: PostMenuMobileProps) => {
|
||||
{...getReferenceProps()}
|
||||
>
|
||||
...
|
||||
</span>
|
||||
</button>
|
||||
{isMenuOpen &&
|
||||
cid &&
|
||||
createPortal(
|
||||
|
||||
Reference in New Issue
Block a user