forked from
jollywhoppers.com/witchsky.app
fork
Configure Feed
Select the types of activity you want to include in your feed.
Bluesky app fork with some witchin' additions 馃挮
fork
Configure Feed
Select the types of activity you want to include in your feed.
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}