Bluesky app fork with some witchin' additions 馃挮
fork

Configure Feed

Select the types of activity you want to include in your feed.

at twelve 112 lines 2.8 kB view raw
1import React from 'react' 2import {type StyleProp, type TextStyle, type ViewStyle} from 'react-native' 3import {View} from 'react-native' 4 5import {usePalette} from '#/lib/hooks/usePalette' 6import {useWebMediaQueries} from '#/lib/hooks/useWebMediaQueries' 7import {atoms as a, useBreakpoints, useTheme} from '#/alf' 8import {Button, type ButtonProps, ButtonText} from '#/components/Button' 9import {EditBig_Stroke1_Corner0_Rounded as EditIcon} from '#/components/icons/EditBig' 10import {Text} from '#/components/Typography' 11 12export type EmptyStateButtonProps = Omit<ButtonProps, 'children' | 'label'> & { 13 label: string 14 text: string 15} 16 17export function EmptyState({ 18 testID, 19 icon, 20 iconSize = '3xl', 21 message, 22 style, 23 textStyle, 24 button, 25}: { 26 testID?: string 27 icon?: React.ComponentType<any> | React.ReactElement 28 iconSize?: 'xs' | 'sm' | 'md' | 'lg' | 'xl' | '2xl' | '3xl' 29 message: string 30 style?: StyleProp<ViewStyle> 31 textStyle?: StyleProp<TextStyle> 32 button?: EmptyStateButtonProps 33}) { 34 const pal = usePalette('default') 35 const {isTabletOrDesktop} = useWebMediaQueries() 36 const t = useTheme() 37 const {gtMobile} = useBreakpoints() 38 39 const placeholderIcon = ( 40 <EditIcon size="2xl" fill={t.atoms.text_contrast_medium.color} /> 41 ) 42 43 const renderIcon = () => { 44 if (!icon) { 45 return placeholderIcon 46 } 47 48 if (React.isValidElement(icon)) { 49 return icon 50 } 51 52 if ( 53 typeof icon === 'function' || 54 (typeof icon === 'object' && icon && 'render' in icon) 55 ) { 56 const IconComponent = icon 57 return ( 58 <IconComponent 59 size={iconSize} 60 fill={t.atoms.text_contrast_medium.color} 61 style={{color: t.atoms.text_contrast_low.color}} 62 /> 63 ) 64 } 65 66 return placeholderIcon 67 } 68 69 return ( 70 <View testID={testID} style={style}> 71 <View 72 style={[ 73 a.flex_row, 74 a.align_center, 75 a.justify_center, 76 a.self_center, 77 a.rounded_full, 78 a.mt_5xl, 79 {height: 64, width: 64}, 80 React.isValidElement(icon) 81 ? a.bg_transparent 82 : [isTabletOrDesktop && {marginTop: 50}], 83 ]}> 84 {renderIcon()} 85 </View> 86 <Text 87 style={[ 88 { 89 color: pal.colors.textLight, 90 maxWidth: gtMobile ? '40%' : '60%', 91 }, 92 a.pt_xs, 93 a.font_medium, 94 a.text_md, 95 a.leading_snug, 96 a.text_center, 97 a.self_center, 98 !button && a.mb_5xl, 99 textStyle, 100 ]}> 101 {message} 102 </Text> 103 {button && ( 104 <View style={[a.flex_shrink, a.mt_xl, a.self_center, a.mb_5xl]}> 105 <Button {...button}> 106 <ButtonText>{button.text}</ButtonText> 107 </Button> 108 </View> 109 )} 110 </View> 111 ) 112}