mirror of https://git.lenooby09.tech/LeNooby09/social-app.git
at verify-code 214 lines 5.2 kB view raw
1import React from 'react' 2import {GestureResponderEvent, View} from 'react-native' 3import {msg} from '@lingui/macro' 4import {useLingui} from '@lingui/react' 5 6import {atoms as a, useBreakpoints, useTheme} from '#/alf' 7import {Button, ButtonColor, ButtonProps, ButtonText} from '#/components/Button' 8import * as Dialog from '#/components/Dialog' 9import {Text} from '#/components/Typography' 10 11export { 12 type DialogControlProps as PromptControlProps, 13 useDialogControl as usePromptControl, 14} from '#/components/Dialog' 15 16const Context = React.createContext<{ 17 titleId: string 18 descriptionId: string 19}>({ 20 titleId: '', 21 descriptionId: '', 22}) 23 24export function Outer({ 25 children, 26 control, 27 testID, 28}: React.PropsWithChildren<{ 29 control: Dialog.DialogControlProps 30 testID?: string 31}>) { 32 const {gtMobile} = useBreakpoints() 33 const titleId = React.useId() 34 const descriptionId = React.useId() 35 36 const context = React.useMemo( 37 () => ({titleId, descriptionId}), 38 [titleId, descriptionId], 39 ) 40 41 return ( 42 <Dialog.Outer control={control} testID={testID}> 43 <Context.Provider value={context}> 44 <Dialog.Handle /> 45 46 <Dialog.ScrollableInner 47 accessibilityLabelledBy={titleId} 48 accessibilityDescribedBy={descriptionId} 49 style={[ 50 gtMobile ? {width: 'auto', maxWidth: 400, minWidth: 200} : a.w_full, 51 ]}> 52 {children} 53 </Dialog.ScrollableInner> 54 </Context.Provider> 55 </Dialog.Outer> 56 ) 57} 58 59export function TitleText({children}: React.PropsWithChildren<{}>) { 60 const {titleId} = React.useContext(Context) 61 return ( 62 <Text nativeID={titleId} style={[a.text_2xl, a.font_bold, a.pb_sm]}> 63 {children} 64 </Text> 65 ) 66} 67 68export function DescriptionText({ 69 children, 70 selectable, 71}: React.PropsWithChildren<{selectable?: boolean}>) { 72 const t = useTheme() 73 const {descriptionId} = React.useContext(Context) 74 return ( 75 <Text 76 nativeID={descriptionId} 77 selectable={selectable} 78 style={[a.text_md, a.leading_snug, t.atoms.text_contrast_high, a.pb_lg]}> 79 {children} 80 </Text> 81 ) 82} 83 84export function Actions({children}: React.PropsWithChildren<{}>) { 85 const {gtMobile} = useBreakpoints() 86 87 return ( 88 <View 89 style={[ 90 a.w_full, 91 a.gap_md, 92 a.justify_end, 93 gtMobile 94 ? [a.flex_row, a.flex_row_reverse, a.justify_start] 95 : [a.flex_col], 96 ]}> 97 {children} 98 </View> 99 ) 100} 101 102export function Cancel({ 103 cta, 104}: { 105 /** 106 * Optional i18n string. If undefined, it will default to "Cancel". 107 */ 108 cta?: string 109}) { 110 const {_} = useLingui() 111 const {gtMobile} = useBreakpoints() 112 const {close} = Dialog.useDialogContext() 113 const onPress = React.useCallback(() => { 114 close() 115 }, [close]) 116 117 return ( 118 <Button 119 variant="solid" 120 color="secondary" 121 size={gtMobile ? 'small' : 'medium'} 122 label={cta || _(msg`Cancel`)} 123 onPress={onPress}> 124 <ButtonText>{cta || _(msg`Cancel`)}</ButtonText> 125 </Button> 126 ) 127} 128 129export function Action({ 130 onPress, 131 color = 'primary', 132 cta, 133 testID, 134}: { 135 /** 136 * Callback to run when the action is pressed. The method is called _after_ 137 * the dialog closes. 138 * 139 * Note: The dialog will close automatically when the action is pressed, you 140 * should NOT close the dialog as a side effect of this method. 141 */ 142 onPress: ButtonProps['onPress'] 143 color?: ButtonColor 144 /** 145 * Optional i18n string. If undefined, it will default to "Confirm". 146 */ 147 cta?: string 148 testID?: string 149}) { 150 const {_} = useLingui() 151 const {gtMobile} = useBreakpoints() 152 const {close} = Dialog.useDialogContext() 153 const handleOnPress = React.useCallback( 154 (e: GestureResponderEvent) => { 155 close(() => onPress?.(e)) 156 }, 157 [close, onPress], 158 ) 159 160 return ( 161 <Button 162 variant="solid" 163 color={color} 164 size={gtMobile ? 'small' : 'medium'} 165 label={cta || _(msg`Confirm`)} 166 onPress={handleOnPress} 167 testID={testID}> 168 <ButtonText>{cta || _(msg`Confirm`)}</ButtonText> 169 </Button> 170 ) 171} 172 173export function Basic({ 174 control, 175 title, 176 description, 177 cancelButtonCta, 178 confirmButtonCta, 179 onConfirm, 180 confirmButtonColor, 181 showCancel = true, 182}: React.PropsWithChildren<{ 183 control: Dialog.DialogOuterProps['control'] 184 title: string 185 description: string 186 cancelButtonCta?: string 187 confirmButtonCta?: string 188 /** 189 * Callback to run when the Confirm button is pressed. The method is called 190 * _after_ the dialog closes. 191 * 192 * Note: The dialog will close automatically when the action is pressed, you 193 * should NOT close the dialog as a side effect of this method. 194 */ 195 onConfirm: ButtonProps['onPress'] 196 confirmButtonColor?: ButtonColor 197 showCancel?: boolean 198}>) { 199 return ( 200 <Outer control={control} testID="confirmModal"> 201 <TitleText>{title}</TitleText> 202 <DescriptionText>{description}</DescriptionText> 203 <Actions> 204 <Action 205 cta={confirmButtonCta} 206 onPress={onConfirm} 207 color={confirmButtonColor} 208 testID="confirmBtn" 209 /> 210 {showCancel && <Cancel cta={cancelButtonCta} />} 211 </Actions> 212 </Outer> 213 ) 214}