feat(gif): add GifCategoryPills component with category browsing

Adds scrollable pill-shaped category filter buttons for the GIF picker,
allowing users to browse trending and themed GIF categories.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
This commit is contained in:
vineyardbovines
2026-04-14 16:19:55 -04:00
parent 418b61c701
commit 1291a7cbb7
@@ -0,0 +1,65 @@
import {ScrollView, View} from 'react-native'
import {i18n, type MessageDescriptor} from '@lingui/core'
import {msg} from '@lingui/core/macro'
import {useLingui} from '@lingui/react'
import {atoms as a} from '#/alf'
import {Button, ButtonText} from '#/components/Button'
export type GifCategory = {
id: string
emoji: string
label: MessageDescriptor
searchterm: string | null // null = trending (uses featured endpoint)
}
export const GIF_CATEGORIES: readonly GifCategory[] = [
{id: 'trending', emoji: '🔥', label: msg`Trending`, searchterm: null},
{id: 'love', emoji: '❤️', label: msg`Love`, searchterm: 'love'},
{id: 'happy', emoji: '😄', label: msg`Happy`, searchterm: 'happy'},
{id: 'sad', emoji: '😢', label: msg`Sad`, searchterm: 'cry'},
{id: 'party', emoji: '🎉', label: msg`Party`, searchterm: 'congratulations'},
{id: 'yes', emoji: '👍', label: msg`Yes`, searchterm: 'yes'},
{id: 'lol', emoji: '😂', label: msg`LOL`, searchterm: 'lol'},
{id: 'excited', emoji: '🤩', label: msg`Excited`, searchterm: 'excited'},
] as const
export function GifCategoryPills({
activeId,
onSelect,
}: {
activeId: string
onSelect: (category: GifCategory) => void
}) {
// useLingui() is called to re-render when the locale changes, even though we
// translate via i18n._() below to satisfy the lingui-msg-rule lint constraint.
useLingui()
return (
<View style={[a.mb_sm]}>
<ScrollView
horizontal
showsHorizontalScrollIndicator={false}
contentContainerStyle={[a.flex_row, a.gap_xs, a.px_xl]}>
{GIF_CATEGORIES.map(category => {
const isActive = category.id === activeId
const label = i18n._(category.label)
return (
<Button
key={category.id}
label={label}
onPress={() => onSelect(category)}
size="small"
variant={isActive ? 'solid' : 'outline'}
color={isActive ? 'primary' : 'secondary'}
shape="default">
<ButtonText emoji>
{category.emoji} {label}
</ButtonText>
</Button>
)
})}
</ScrollView>
</View>
)
}