Bluesky app fork with some witchin' additions 馃挮 witchsky.app
bluesky fork client
at main 139 lines 3.8 kB view raw
1import {type ReactNode} from 'react' 2import {ScrollView, View} from 'react-native' 3import { 4 useSafeAreaFrame, 5 useSafeAreaInsets, 6} from 'react-native-safe-area-context' 7import {LinearGradient} from 'expo-linear-gradient' 8import {utils} from '@bsky.app/alf' 9 10import {useA11y} from '#/state/a11y' 11import {atoms as a, useBreakpoints, useTheme, web} from '#/alf' 12import {FocusScope} from '#/components/FocusScope' 13import {LockScroll} from '#/components/LockScroll' 14import {IS_ANDROID, IS_NATIVE} from '#/env' 15 16const GUTTER = 24 17 18export function Overlay({ 19 children, 20 label, 21}: { 22 children: ReactNode 23 label: string 24}) { 25 const t = useTheme() 26 const {gtPhone} = useBreakpoints() 27 const {reduceMotionEnabled} = useA11y() 28 const insets = useSafeAreaInsets() 29 const frame = useSafeAreaFrame() 30 31 return ( 32 <> 33 <LockScroll /> 34 35 <View style={[a.fixed, a.inset_0, !reduceMotionEnabled && a.fade_in]}> 36 {gtPhone ? ( 37 <View style={[a.absolute, a.inset_0, {opacity: 0.8}]}> 38 <View 39 style={[ 40 a.fixed, 41 a.inset_0, 42 {backgroundColor: t.palette.black}, 43 !reduceMotionEnabled && a.fade_in, 44 ]} 45 /> 46 </View> 47 ) : ( 48 <LinearGradient 49 colors={[ 50 utils.alpha(t.atoms.bg.backgroundColor, 0), 51 t.atoms.bg.backgroundColor, 52 t.atoms.bg.backgroundColor, 53 ]} 54 start={[0.5, 0]} 55 end={[0.5, 1]} 56 style={[a.absolute, a.inset_0]} 57 /> 58 )} 59 </View> 60 61 <ScrollView 62 showsVerticalScrollIndicator={false} 63 style={[ 64 a.z_10, 65 gtPhone && 66 web({ 67 paddingHorizontal: GUTTER, 68 paddingVertical: '10vh', 69 }), 70 ]} 71 contentContainerStyle={[a.align_center]}> 72 {/** 73 * This is needed to prevent centered dialogs from overflowing 74 * above the screen, and provides a "natural" centering so that 75 * stacked dialogs appear relatively aligned. 76 */} 77 <View 78 style={[ 79 a.w_full, 80 a.z_20, 81 a.align_center, 82 !gtPhone && [a.justify_end, {minHeight: frame.height}], 83 IS_NATIVE && [ 84 { 85 paddingBottom: Math.max(insets.bottom, a.p_2xl.padding), 86 }, 87 ], 88 ]}> 89 {!gtPhone && ( 90 <View 91 style={[ 92 a.flex_1, 93 a.w_full, 94 { 95 minHeight: Math.max(insets.top, a.p_2xl.padding), 96 }, 97 ]}> 98 <LinearGradient 99 colors={[ 100 utils.alpha(t.atoms.bg.backgroundColor, 0), 101 t.atoms.bg.backgroundColor, 102 ]} 103 start={[0.5, 0]} 104 end={[0.5, 1]} 105 style={[a.absolute, a.inset_0]} 106 /> 107 </View> 108 )} 109 110 <FocusScope> 111 <View 112 accessible={IS_ANDROID} 113 role="dialog" 114 aria-role="dialog" 115 aria-label={label} 116 style={[ 117 a.relative, 118 a.w_full, 119 a.p_2xl, 120 t.atoms.bg, 121 !reduceMotionEnabled && a.zoom_fade_in, 122 gtPhone && [ 123 a.rounded_md, 124 a.border, 125 t.atoms.shadow_lg, 126 t.atoms.border_contrast_low, 127 web({ 128 maxWidth: 420, 129 }), 130 ], 131 ]}> 132 {children} 133 </View> 134 </FocusScope> 135 </View> 136 </ScrollView> 137 </> 138 ) 139}