import {createContext, useCallback, useContext, useId, useMemo} from 'react' import {type GestureResponderEvent, View} from 'react-native' import {msg} from '@lingui/core/macro' import {useLingui} from '@lingui/react' import {useEnableSquareButtons} from '#/state/preferences/enable-square-buttons' import {atoms as a, useTheme, type ViewStyleProp, web} from '#/alf' import { Button, type ButtonColor, ButtonIcon, ButtonText, } from '#/components/Button' import * as Dialog from '#/components/Dialog' import {type Props as SVGIconProps} from '#/components/icons/common' import {Text} from '#/components/Typography' import {type BottomSheetViewProps} from '../../modules/bottom-sheet' export { type DialogControlProps as PromptControlProps, useDialogControl as usePromptControl, } from '#/components/Dialog' const Context = createContext<{ titleId: string descriptionId: string }>({ titleId: '', descriptionId: '', }) Context.displayName = 'PromptContext' export function Outer({ children, control, testID, nativeOptions, }: React.PropsWithChildren<{ control: Dialog.DialogControlProps testID?: string /** * Native-specific options for the prompt. Extends `BottomSheetViewProps` */ nativeOptions?: Omit }>) { const titleId = useId() const descriptionId = useId() const context = useMemo( () => ({titleId, descriptionId}), [titleId, descriptionId], ) const enableSquareButtons = useEnableSquareButtons() return ( {children} ) } export function TitleText({ children, style, }: React.PropsWithChildren) { const {titleId} = useContext(Context) return ( {children} ) } export function DescriptionText({ children, selectable, }: React.PropsWithChildren<{selectable?: boolean}>) { const t = useTheme() const {descriptionId} = useContext(Context) return ( {children} ) } export function Actions({children}: {children: React.ReactNode}) { return {children} } export function Content({children}: {children: React.ReactNode}) { return {children} } export function Cancel({ cta, }: { /** * Optional i18n string. If undefined, it will default to "Cancel". */ cta?: string }) { const {_} = useLingui() const {close} = Dialog.useDialogContext() const onPress = useCallback(() => { close() }, [close]) return ( ) } export function Action({ onPress, color = 'primary', cta, disabled = false, icon, shouldCloseOnPress = true, testID, }: { /** * Callback to run when the action is pressed. The method is called _after_ * the dialog closes. * * Note: The dialog will close automatically when the action is pressed, you * should NOT close the dialog as a side effect of this method. */ onPress: (e: GestureResponderEvent) => void color?: ButtonColor /** * Optional i18n string. If undefined, it will default to "Confirm". */ cta?: string /** * If undefined, it will default to false. */ disabled?: boolean icon?: React.ComponentType /** * Optionally close dialog automatically on press. If undefined, it will * default to true. */ shouldCloseOnPress?: boolean testID?: string }) { const {_} = useLingui() const {close} = Dialog.useDialogContext() const handleOnPress = useCallback( (e: GestureResponderEvent) => { if (shouldCloseOnPress) { close(() => onPress?.(e)) } else { onPress?.(e) } }, [close, onPress, shouldCloseOnPress], ) return ( ) } export function Basic({ control, title, description, cancelButtonCta, confirmButtonCta, onConfirm, confirmButtonColor, showCancel = true, }: React.PropsWithChildren<{ control: Dialog.DialogOuterProps['control'] title: string description?: string cancelButtonCta?: string confirmButtonCta?: string /** * Callback to run when the Confirm button is pressed. The method is called * _after_ the dialog closes. * * Note: The dialog will close automatically when the action is pressed, you * should NOT close the dialog as a side effect of this method. */ onConfirm: (e: GestureResponderEvent) => void confirmButtonColor?: ButtonColor showCancel?: boolean }>) { return ( {title} {description && {description}} {showCancel && } ) }