Add subtle web hover to interactive rows (#5989)

* Add subtle web hover to interactive rows

* Adjust numbers

* Ignore touch devices
This commit is contained in:
dan
2024-10-29 21:42:37 +00:00
committed by GitHub
parent c8f264b78b
commit ba802eb0f2
8 changed files with 152 additions and 43 deletions
+11 -1
View File
@@ -51,6 +51,7 @@ import {Link as NewLink} from '#/components/Link'
import * as MediaPreview from '#/components/MediaPreview'
import {ProfileHoverCard} from '#/components/ProfileHoverCard'
import {Notification as StarterPackCard} from '#/components/StarterPack/StarterPackCard'
import {SubtleWebHover} from '#/components/SubtleWebHover'
import {FeedSourceCard} from '../feeds/FeedSourceCard'
import {Post} from '../post/Post'
import {Link, TextLink} from '../util/Link'
@@ -129,6 +130,8 @@ let FeedItem = ({
]
}, [item, moderationOpts])
const [hover, setHover] = React.useState(false)
if (item.subjectUri && !item.subject && item.type !== 'feedgen-like') {
// don't render anything if the target post was deleted or unfindable
return <View />
@@ -285,7 +288,14 @@ let FeedItem = ({
onToggleAuthorsExpanded()
}
}}
onBeforePress={onBeforePress}>
onBeforePress={onBeforePress}
onPointerEnter={() => {
setHover(true)
}}
onPointerLeave={() => {
setHover(false)
}}>
<SubtleWebHover hover={hover} />
<View style={[styles.layoutIcon, a.pr_sm]}>
{/* TODO: Prevent conditional rendering and move toward composable
notifications for clearer accessibility labeling */}
+16 -1
View File
@@ -31,6 +31,7 @@ import {PostThreadFollowBtn} from '#/view/com/post-thread/PostThreadFollowBtn'
import {atoms as a, useTheme} from '#/alf'
import {AppModerationCause} from '#/components/Pills'
import {RichText} from '#/components/RichText'
import {SubtleWebHover} from '#/components/SubtleWebHover'
import {Text as NewText} from '#/components/Typography'
import {ContentHider} from '../../../components/moderation/ContentHider'
import {LabelsOnMyPost} from '../../../components/moderation/LabelsOnMe'
@@ -649,6 +650,7 @@ function PostOuterWrapper({
hideTopBorder?: boolean
}>) {
const t = useTheme()
const [hover, setHover] = React.useState(false)
if (treeView && depth > 0) {
return (
<View
@@ -661,7 +663,13 @@ function PostOuterWrapper({
flexDirection: 'row',
borderTopWidth: depth === 1 ? a.border_t.borderTopWidth : 0,
},
]}>
]}
onPointerEnter={() => {
setHover(true)
}}
onPointerLeave={() => {
setHover(false)
}}>
{Array.from(Array(depth - 1)).map((_, n: number) => (
<View
key={`${post.uri}-padding-${n}`}
@@ -681,6 +689,12 @@ function PostOuterWrapper({
}
return (
<View
onPointerEnter={() => {
setHover(true)
}}
onPointerLeave={() => {
setHover(false)
}}
style={[
a.border_t,
a.px_sm,
@@ -689,6 +703,7 @@ function PostOuterWrapper({
hideTopBorder && styles.noTopBorder,
styles.cursor,
]}>
<SubtleWebHover hover={hover} />
{children}
</View>
)
+10 -1
View File
@@ -27,6 +27,7 @@ import {AviFollowButton} from '#/view/com/posts/AviFollowButton'
import {atoms as a} from '#/alf'
import {ProfileHoverCard} from '#/components/ProfileHoverCard'
import {RichText} from '#/components/RichText'
import {SubtleWebHover} from '#/components/SubtleWebHover'
import {ContentHider} from '../../../components/moderation/ContentHider'
import {LabelsOnMyPost} from '../../../components/moderation/LabelsOnMe'
import {PostAlerts} from '../../../components/moderation/PostAlerts'
@@ -148,6 +149,7 @@ function PostInner({
const {currentAccount} = useSession()
const isMe = replyAuthorDid === currentAccount?.did
const [hover, setHover] = React.useState(false)
return (
<Link
href={itemHref}
@@ -157,7 +159,14 @@ function PostInner({
!hideTopBorder && {borderTopWidth: StyleSheet.hairlineWidth},
style,
]}
onBeforePress={onBeforePress}>
onBeforePress={onBeforePress}
onPointerEnter={() => {
setHover(true)
}}
onPointerLeave={() => {
setHover(false)
}}>
<SubtleWebHover hover={hover} />
{showReplyLine && <View style={styles.replyLine} />}
<View style={styles.layout}>
<View style={styles.layoutAvi}>
+10 -1
View File
@@ -46,6 +46,7 @@ import {PostAlerts} from '#/components/moderation/PostAlerts'
import {AppModerationCause} from '#/components/Pills'
import {ProfileHoverCard} from '#/components/ProfileHoverCard'
import {RichText} from '#/components/RichText'
import {SubtleWebHover} from '#/components/SubtleWebHover'
import {Link, TextLink, TextLinkOnWebOnly} from '../util/Link'
import {AviFollowButton} from './AviFollowButton'
@@ -237,6 +238,7 @@ let FeedItemInner = ({
? rootPost.threadgate.record
: undefined
const [hover, setHover] = useState(false)
return (
<Link
testID={`feedItem-by-${post.author.handle}`}
@@ -245,7 +247,14 @@ let FeedItemInner = ({
noFeedback
accessible={false}
onBeforePress={onBeforePress}
dataSet={{feedContext}}>
dataSet={{feedContext}}
onPointerEnter={() => {
setHover(true)
}}
onPointerLeave={() => {
setHover(false)
}}>
<SubtleWebHover hover={hover} />
<View style={{flexDirection: 'row', gap: 10, paddingLeft: 8}}>
<View style={{width: 42}}>
{isThreadChild && (
+1
View File
@@ -49,6 +49,7 @@ interface Props extends ComponentProps<typeof TouchableOpacity> {
anchorNoUnderline?: boolean
navigationAction?: 'push' | 'replace' | 'navigate'
onPointerEnter?: () => void
onPointerLeave?: () => void
onBeforePress?: () => void
}
+53 -39
View File
@@ -35,6 +35,7 @@ import {useResolveLinkQuery} from '#/state/queries/resolve-link'
import {useSession} from '#/state/session'
import {atoms as a, useTheme} from '#/alf'
import {RichText} from '#/components/RichText'
import {SubtleWebHover} from '#/components/SubtleWebHover'
import {ContentHider} from '../../../../components/moderation/ContentHider'
import {PostAlerts} from '../../../../components/moderation/PostAlerts'
import {Link} from '../Link'
@@ -209,46 +210,59 @@ export function QuoteEmbed({
onOpen?.()
}, [queryClient, quote.author, onOpen])
const [hover, setHover] = React.useState(false)
return (
<ContentHider
modui={moderation?.ui('contentList')}
style={[
a.rounded_md,
a.p_md,
a.mt_sm,
a.border,
t.atoms.border_contrast_low,
style,
]}
childContainerStyle={[a.pt_sm]}>
<Link
hoverStyle={{borderColor: pal.colors.borderLinkHover}}
href={itemHref}
title={itemTitle}
onBeforePress={onBeforePress}>
<View pointerEvents="none">
<PostMeta
author={quote.author}
moderation={moderation}
showAvatar
postHref={itemHref}
timestamp={quote.indexedAt}
/>
</View>
{moderation ? (
<PostAlerts modui={moderation.ui('contentView')} style={[a.py_xs]} />
) : null}
{richText ? (
<RichText
value={richText}
style={a.text_md}
numberOfLines={20}
disableLinks
/>
) : null}
{embed && <PostEmbeds embed={embed} moderation={moderation} />}
</Link>
</ContentHider>
<View
onPointerEnter={() => {
setHover(true)
}}
onPointerLeave={() => {
setHover(false)
}}>
<ContentHider
modui={moderation?.ui('contentList')}
style={[
a.rounded_md,
a.p_md,
a.mt_sm,
a.border,
t.atoms.border_contrast_low,
style,
]}
childContainerStyle={[a.pt_sm]}>
<SubtleWebHover hover={hover} />
<Link
hoverStyle={{borderColor: pal.colors.borderLinkHover}}
href={itemHref}
title={itemTitle}
onBeforePress={onBeforePress}>
<View pointerEvents="none">
<PostMeta
author={quote.author}
moderation={moderation}
showAvatar
postHref={itemHref}
timestamp={quote.indexedAt}
/>
</View>
{moderation ? (
<PostAlerts
modui={moderation.ui('contentView')}
style={[a.py_xs]}
/>
) : null}
{richText ? (
<RichText
value={richText}
style={a.text_md}
numberOfLines={20}
disableLinks
/>
) : null}
{embed && <PostEmbeds embed={embed} moderation={moderation} />}
</Link>
</ContentHider>
</View>
)
}