1import {
2 AlertDialog,
3 Host,
4 OutlinedTextField,
5 Text,
6 TextButton,
7 useNativeState,
8} from "@expo/ui/jetpack-compose";
9
10import { useAppearancePreferences } from "../features/settings/appearance/AppearancePreferencesProvider";
11import { useScaledTextRole } from "../features/settings/appearance/useScaledTextRole";
12import type { MaterialConfirmDialogProps } from "./MaterialConfirmDialog";
13
14export function MaterialConfirmDialog(props: MaterialConfirmDialogProps) {
15 const { themeAppearance, themeVariables: colors } = useAppearancePreferences();
16 const titleTypography = useScaledTextRole("title");
17 const bodyTypography = useScaledTextRole("footnote");
18 const inputTypography = useScaledTextRole("body");
19 const inputState = useNativeState(props.inputInitialValue ?? "");
20 const inputSelection = useNativeState({ start: 0, end: props.inputInitialValue?.length ?? 0 });
21 const confirm = () => {
22 if (props.confirmDisabled) return;
23 const value = props.inputInitialValue === undefined ? undefined : inputState.get();
24 if (value !== undefined && !value.trim()) return;
25 props.onConfirm(value);
26 };
27 return (
28 <Host
29 colorScheme={themeAppearance}
30 ignoreSafeAreaKeyboardInsets
31 style={{ height: 0, width: 0 }}
32 >
33 <AlertDialog
34 onDismissRequest={props.onCancel}
35 tonalElevation={0}
36 colors={{
37 containerColor: colors["--color-card-alt"],
38 titleContentColor: colors["--color-foreground"],
39 textContentColor: colors["--color-foreground-secondary"],
40 }}
41 >
42 <AlertDialog.Title>
43 <Text style={titleTypography}>{props.request.title}</Text>
44 </AlertDialog.Title>
45 {props.inputInitialValue !== undefined ? (
46 <AlertDialog.Text>
47 <OutlinedTextField
48 autoFocus
49 singleLine
50 value={inputState}
51 selection={inputSelection}
52 onValueChange={props.onInputChange}
53 textStyle={inputTypography}
54 keyboardOptions={{ imeAction: "done" }}
55 keyboardActions={{
56 onDone: confirm,
57 }}
58 colors={{
59 focusedTextColor: colors["--color-foreground"],
60 unfocusedTextColor: colors["--color-foreground"],
61 focusedIndicatorColor: colors["--color-focus"],
62 unfocusedIndicatorColor: colors["--color-border"],
63 cursorColor: colors["--color-focus"],
64 }}
65 >
66 <OutlinedTextField.Label>
67 <Text style={bodyTypography}>{props.request.title}</Text>
68 </OutlinedTextField.Label>
69 </OutlinedTextField>
70 </AlertDialog.Text>
71 ) : props.request.message ? (
72 <AlertDialog.Text>
73 <Text style={bodyTypography}>{props.request.message}</Text>
74 </AlertDialog.Text>
75 ) : null}
76 <AlertDialog.DismissButton>
77 <TextButton
78 onClick={props.onCancel}
79 colors={{ contentColor: colors["--color-primary-text"] }}
80 >
81 <Text style={bodyTypography}>{props.request.cancelText ?? "Cancel"}</Text>
82 </TextButton>
83 </AlertDialog.DismissButton>
84 <AlertDialog.ConfirmButton>
85 <TextButton
86 onClick={confirm}
87 enabled={!props.confirmDisabled}
88 colors={{
89 contentColor:
90 colors[
91 props.request.destructive ? "--color-danger-foreground" : "--color-primary-text"
92 ],
93 }}
94 >
95 <Text style={bodyTypography}>{props.request.confirmText}</Text>
96 </TextButton>
97 </AlertDialog.ConfirmButton>
98 </AlertDialog>
99 </Host>
100 );
101}