Something went wrong. Try again.
Bluesky app fork with some witchin' additions 💫 forked from jollywhoppers.com/witchsky.app
Something went wrong. Try again.
2.8 kB · 120 lines
TSX
at main
123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121import {createContext, useContext} from 'react'import {View, type ViewStyle} from 'react-native'
import {atoms as a, tokens, useTheme} from '#/alf'import {type Props as SVGIconProps} from '#/components/icons/common'import {Text} from '#/components/Typography'
const PanelContext = createContext<{active: boolean}>({active: false})
/** * A nice container for Toggles. See the Threadgate dialog for an example. */export function Panel({ children, active = false, adjacent,}: { children: React.ReactNode active?: boolean adjacent?: 'leading' | 'trailing' | 'both'}) { const t = useTheme()
const leading = adjacent === 'leading' || adjacent === 'both' const trailing = adjacent === 'trailing' || adjacent === 'both' const rounding = { borderTopLeftRadius: leading ? tokens.borderRadius.xs : tokens.borderRadius.md, borderTopRightRadius: leading ? tokens.borderRadius.xs : tokens.borderRadius.md, borderBottomLeftRadius: trailing ? tokens.borderRadius.xs : tokens.borderRadius.md, borderBottomRightRadius: trailing ? tokens.borderRadius.xs : tokens.borderRadius.md, } satisfies ViewStyle
return ( <View style={[ a.w_full, a.flex_row, a.align_center, a.gap_sm, a.px_md, a.py_md, {minHeight: tokens.space._2xl + tokens.space.md * 2}, rounding, active ? {backgroundColor: t.palette.primary_50} : t.atoms.bg_contrast_50, ]}> <PanelContext value={{active}}>{children}</PanelContext> </View> )}
export function PanelText({ children, icon,}: { children: React.ReactNode icon?: React.ComponentType<SVGIconProps>}) { const t = useTheme() const ctx = useContext(PanelContext)
const text = ( <Text style={[ a.text_md, a.flex_1, ctx.active ? [a.font_medium, t.atoms.text] : [t.atoms.text_contrast_medium], ]}> {children} </Text> )
if (icon) { // eslint-disable-next-line bsky-internal/avoid-unwrapped-text return ( <View style={[a.flex_row, a.align_center, a.gap_xs, a.flex_1]}> <PanelIcon icon={icon} /> {text} </View> ) }
return text}
export function PanelIcon({ icon: Icon,}: { icon: React.ComponentType<SVGIconProps>}) { const t = useTheme() const ctx = useContext(PanelContext) return ( <Icon style={[ ctx.active ? t.atoms.text : t.atoms.text_contrast_medium, a.flex_shrink_0, ]} size="md" /> )}
/** * A group of panels. TODO: auto-leading/trailing */export function PanelGroup({children}: {children: React.ReactNode}) { return <View style={[a.w_full, a.gap_2xs]}>{children}</View>}