feat: add bottom sheet modal for agent creation UI
This commit is contained in:
Generated
+40
@@ -4335,6 +4335,45 @@
|
|||||||
"js-yaml": "bin/js-yaml.js"
|
"js-yaml": "bin/js-yaml.js"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
"node_modules/@gorhom/bottom-sheet": {
|
||||||
|
"version": "5.2.6",
|
||||||
|
"resolved": "https://registry.npmjs.org/@gorhom/bottom-sheet/-/bottom-sheet-5.2.6.tgz",
|
||||||
|
"integrity": "sha512-vmruJxdiUGDg+ZYcDmS30XDhq/h/+QkINOI5LY/uGjx8cPGwgJW0H6AB902gNTKtccbiKe/rr94EwdmIEz+LAQ==",
|
||||||
|
"license": "MIT",
|
||||||
|
"dependencies": {
|
||||||
|
"@gorhom/portal": "1.0.14",
|
||||||
|
"invariant": "^2.2.4"
|
||||||
|
},
|
||||||
|
"peerDependencies": {
|
||||||
|
"@types/react": "*",
|
||||||
|
"@types/react-native": "*",
|
||||||
|
"react": "*",
|
||||||
|
"react-native": "*",
|
||||||
|
"react-native-gesture-handler": ">=2.16.1",
|
||||||
|
"react-native-reanimated": ">=3.16.0 || >=4.0.0-"
|
||||||
|
},
|
||||||
|
"peerDependenciesMeta": {
|
||||||
|
"@types/react": {
|
||||||
|
"optional": true
|
||||||
|
},
|
||||||
|
"@types/react-native": {
|
||||||
|
"optional": true
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"node_modules/@gorhom/portal": {
|
||||||
|
"version": "1.0.14",
|
||||||
|
"resolved": "https://registry.npmjs.org/@gorhom/portal/-/portal-1.0.14.tgz",
|
||||||
|
"integrity": "sha512-MXyL4xvCjmgaORr/rtryDNFy3kU4qUbKlwtQqqsygd0xX3mhKjOLn6mQK8wfu0RkoE0pBE0nAasRoHua+/QZ7A==",
|
||||||
|
"license": "MIT",
|
||||||
|
"dependencies": {
|
||||||
|
"nanoid": "^3.3.1"
|
||||||
|
},
|
||||||
|
"peerDependencies": {
|
||||||
|
"react": "*",
|
||||||
|
"react-native": "*"
|
||||||
|
}
|
||||||
|
},
|
||||||
"node_modules/@hapi/hoek": {
|
"node_modules/@hapi/hoek": {
|
||||||
"version": "9.3.0",
|
"version": "9.3.0",
|
||||||
"resolved": "https://registry.npmjs.org/@hapi/hoek/-/hoek-9.3.0.tgz",
|
"resolved": "https://registry.npmjs.org/@hapi/hoek/-/hoek-9.3.0.tgz",
|
||||||
@@ -20485,6 +20524,7 @@
|
|||||||
"version": "1.0.0",
|
"version": "1.0.0",
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"@expo/vector-icons": "^15.0.2",
|
"@expo/vector-icons": "^15.0.2",
|
||||||
|
"@gorhom/bottom-sheet": "^5.2.6",
|
||||||
"@react-native-async-storage/async-storage": "2.2.0",
|
"@react-native-async-storage/async-storage": "2.2.0",
|
||||||
"@react-navigation/bottom-tabs": "^7.4.0",
|
"@react-navigation/bottom-tabs": "^7.4.0",
|
||||||
"@react-navigation/elements": "^2.6.3",
|
"@react-navigation/elements": "^2.6.3",
|
||||||
|
|||||||
@@ -12,6 +12,7 @@
|
|||||||
},
|
},
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"@expo/vector-icons": "^15.0.2",
|
"@expo/vector-icons": "^15.0.2",
|
||||||
|
"@gorhom/bottom-sheet": "^5.2.6",
|
||||||
"@react-native-async-storage/async-storage": "2.2.0",
|
"@react-native-async-storage/async-storage": "2.2.0",
|
||||||
"@react-navigation/bottom-tabs": "^7.4.0",
|
"@react-navigation/bottom-tabs": "^7.4.0",
|
||||||
"@react-navigation/elements": "^2.6.3",
|
"@react-navigation/elements": "^2.6.3",
|
||||||
|
|||||||
@@ -2,6 +2,7 @@ import { Stack } from "expo-router";
|
|||||||
import { SafeAreaProvider } from "react-native-safe-area-context";
|
import { SafeAreaProvider } from "react-native-safe-area-context";
|
||||||
import { KeyboardProvider } from "react-native-keyboard-controller";
|
import { KeyboardProvider } from "react-native-keyboard-controller";
|
||||||
import { GestureHandlerRootView } from "react-native-gesture-handler";
|
import { GestureHandlerRootView } from "react-native-gesture-handler";
|
||||||
|
import { BottomSheetModalProvider } from "@gorhom/bottom-sheet";
|
||||||
import { SessionProvider } from "@/contexts/session-context";
|
import { SessionProvider } from "@/contexts/session-context";
|
||||||
import { RealtimeProvider } from "@/contexts/realtime-context";
|
import { RealtimeProvider } from "@/contexts/realtime-context";
|
||||||
import { useSettings } from "@/hooks/use-settings";
|
import { useSettings } from "@/hooks/use-settings";
|
||||||
@@ -37,25 +38,27 @@ export default function RootLayout() {
|
|||||||
<GestureHandlerRootView style={{ flex: 1 }}>
|
<GestureHandlerRootView style={{ flex: 1 }}>
|
||||||
<SafeAreaProvider>
|
<SafeAreaProvider>
|
||||||
<KeyboardProvider>
|
<KeyboardProvider>
|
||||||
<ProvidersWrapper>
|
<BottomSheetModalProvider>
|
||||||
<Stack
|
<ProvidersWrapper>
|
||||||
screenOptions={{
|
<Stack
|
||||||
headerShown: false,
|
screenOptions={{
|
||||||
animation: "slide_from_right",
|
headerShown: false,
|
||||||
animationDuration: 250,
|
animation: "slide_from_right",
|
||||||
gestureEnabled: true,
|
animationDuration: 250,
|
||||||
gestureDirection: "horizontal",
|
gestureEnabled: true,
|
||||||
fullScreenGestureEnabled: true,
|
gestureDirection: "horizontal",
|
||||||
animationMatchesGesture: true,
|
fullScreenGestureEnabled: true,
|
||||||
}}
|
animationMatchesGesture: true,
|
||||||
>
|
}}
|
||||||
<Stack.Screen name="index" />
|
>
|
||||||
<Stack.Screen name="orchestrator" />
|
<Stack.Screen name="index" />
|
||||||
<Stack.Screen name="agent/[id]" />
|
<Stack.Screen name="orchestrator" />
|
||||||
<Stack.Screen name="settings" />
|
<Stack.Screen name="agent/[id]" />
|
||||||
<Stack.Screen name="audio-test" />
|
<Stack.Screen name="settings" />
|
||||||
</Stack>
|
<Stack.Screen name="audio-test" />
|
||||||
</ProvidersWrapper>
|
</Stack>
|
||||||
|
</ProvidersWrapper>
|
||||||
|
</BottomSheetModalProvider>
|
||||||
</KeyboardProvider>
|
</KeyboardProvider>
|
||||||
</SafeAreaProvider>
|
</SafeAreaProvider>
|
||||||
</GestureHandlerRootView>
|
</GestureHandlerRootView>
|
||||||
|
|||||||
@@ -1,16 +1,20 @@
|
|||||||
import { useState } from "react";
|
import { useState, useRef, useEffect, useMemo, useCallback } from "react";
|
||||||
import {
|
import { View, Text, Pressable, ScrollView } from "react-native";
|
||||||
Modal,
|
|
||||||
View,
|
|
||||||
Text,
|
|
||||||
Pressable,
|
|
||||||
TextInput,
|
|
||||||
ScrollView,
|
|
||||||
} from "react-native";
|
|
||||||
import { useReanimatedKeyboardAnimation } from "react-native-keyboard-controller";
|
|
||||||
import ReanimatedAnimated, { useAnimatedStyle } from "react-native-reanimated";
|
|
||||||
import { useSafeAreaInsets } from "react-native-safe-area-context";
|
import { useSafeAreaInsets } from "react-native-safe-area-context";
|
||||||
import { X } from "lucide-react-native";
|
import { useReanimatedKeyboardAnimation } from "react-native-keyboard-controller";
|
||||||
|
import Animated, { useAnimatedStyle } from "react-native-reanimated";
|
||||||
|
import {
|
||||||
|
BottomSheetModal,
|
||||||
|
BottomSheetBackdrop,
|
||||||
|
BottomSheetView,
|
||||||
|
BottomSheetScrollView,
|
||||||
|
BottomSheetTextInput,
|
||||||
|
BottomSheetFooter,
|
||||||
|
} from "@gorhom/bottom-sheet";
|
||||||
|
import type {
|
||||||
|
BottomSheetBackdropProps,
|
||||||
|
BottomSheetFooterProps,
|
||||||
|
} from "@gorhom/bottom-sheet";
|
||||||
import { StyleSheet } from "react-native-unistyles";
|
import { StyleSheet } from "react-native-unistyles";
|
||||||
import { theme as defaultTheme } from "@/styles/theme";
|
import { theme as defaultTheme } from "@/styles/theme";
|
||||||
import { useRecentPaths } from "@/hooks/use-recent-paths";
|
import { useRecentPaths } from "@/hooks/use-recent-paths";
|
||||||
@@ -39,25 +43,68 @@ export function CreateAgentModal({
|
|||||||
onClose,
|
onClose,
|
||||||
onCreateAgent,
|
onCreateAgent,
|
||||||
}: CreateAgentModalProps) {
|
}: CreateAgentModalProps) {
|
||||||
|
const bottomSheetRef = useRef<BottomSheetModal>(null);
|
||||||
const insets = useSafeAreaInsets();
|
const insets = useSafeAreaInsets();
|
||||||
const { height: keyboardHeight } = useReanimatedKeyboardAnimation();
|
|
||||||
const { recentPaths, addRecentPath } = useRecentPaths();
|
const { recentPaths, addRecentPath } = useRecentPaths();
|
||||||
|
const { height: keyboardHeight } = useReanimatedKeyboardAnimation();
|
||||||
|
|
||||||
const [workingDir, setWorkingDir] = useState("");
|
const [workingDir, setWorkingDir] = useState("");
|
||||||
const [selectedMode, setSelectedMode] = useState("plan");
|
const [selectedMode, setSelectedMode] = useState("plan");
|
||||||
const [errorMessage, setErrorMessage] = useState("");
|
const [errorMessage, setErrorMessage] = useState("");
|
||||||
|
|
||||||
// Keyboard animation
|
const snapPoints = useMemo(() => ["90%"], []);
|
||||||
const bottomInset = insets.bottom;
|
|
||||||
const animatedKeyboardStyle = useAnimatedStyle(() => {
|
// Keyboard animation for footer
|
||||||
|
const animatedFooterStyle = useAnimatedStyle(() => {
|
||||||
"worklet";
|
"worklet";
|
||||||
const absoluteHeight = Math.abs(keyboardHeight.value);
|
const absoluteHeight = Math.abs(keyboardHeight.value);
|
||||||
const padding = Math.max(0, absoluteHeight - bottomInset);
|
const padding = Math.max(0, absoluteHeight - insets.bottom);
|
||||||
return {
|
return {
|
||||||
paddingBottom: padding,
|
paddingBottom: padding,
|
||||||
};
|
};
|
||||||
});
|
});
|
||||||
|
|
||||||
|
const renderBackdrop = useMemo(
|
||||||
|
() => (props: BottomSheetBackdropProps) =>
|
||||||
|
(
|
||||||
|
<BottomSheetBackdrop
|
||||||
|
{...props}
|
||||||
|
disappearsOnIndex={-1}
|
||||||
|
appearsOnIndex={0}
|
||||||
|
opacity={0.5}
|
||||||
|
/>
|
||||||
|
),
|
||||||
|
[]
|
||||||
|
);
|
||||||
|
|
||||||
|
const renderFooter = useCallback(
|
||||||
|
(props: BottomSheetFooterProps) => (
|
||||||
|
<BottomSheetFooter {...props} style={animatedFooterStyle}>
|
||||||
|
<Animated.View
|
||||||
|
style={[styles.footer, { paddingBottom: insets.bottom }]}
|
||||||
|
>
|
||||||
|
<Pressable
|
||||||
|
style={[
|
||||||
|
styles.createButton,
|
||||||
|
!workingDir.trim() && styles.createButtonDisabled,
|
||||||
|
]}
|
||||||
|
onPress={handleCreate}
|
||||||
|
disabled={!workingDir.trim()}
|
||||||
|
>
|
||||||
|
<Text style={styles.createButtonText}>Create Agent</Text>
|
||||||
|
</Pressable>
|
||||||
|
</Animated.View>
|
||||||
|
</BottomSheetFooter>
|
||||||
|
),
|
||||||
|
[insets.bottom, workingDir, animatedFooterStyle]
|
||||||
|
);
|
||||||
|
|
||||||
|
useEffect(() => {
|
||||||
|
if (isVisible) {
|
||||||
|
bottomSheetRef.current?.present();
|
||||||
|
}
|
||||||
|
}, [isVisible]);
|
||||||
|
|
||||||
async function handleCreate() {
|
async function handleCreate() {
|
||||||
if (!workingDir.trim()) {
|
if (!workingDir.trim()) {
|
||||||
setErrorMessage("Working directory is required");
|
setErrorMessage("Working directory is required");
|
||||||
@@ -79,6 +126,10 @@ export function CreateAgentModal({
|
|||||||
}
|
}
|
||||||
|
|
||||||
function handleClose() {
|
function handleClose() {
|
||||||
|
bottomSheetRef.current?.dismiss();
|
||||||
|
}
|
||||||
|
|
||||||
|
function handleDismiss() {
|
||||||
setWorkingDir("");
|
setWorkingDir("");
|
||||||
setSelectedMode("plan");
|
setSelectedMode("plan");
|
||||||
setErrorMessage("");
|
setErrorMessage("");
|
||||||
@@ -86,174 +137,131 @@ export function CreateAgentModal({
|
|||||||
}
|
}
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<Modal
|
<BottomSheetModal
|
||||||
visible={isVisible}
|
ref={bottomSheetRef}
|
||||||
animationType="slide"
|
snapPoints={snapPoints}
|
||||||
transparent={true}
|
enableDynamicSizing={false}
|
||||||
onRequestClose={handleClose}
|
enablePanDownToClose={true}
|
||||||
|
onDismiss={handleDismiss}
|
||||||
|
backgroundStyle={styles.sheetBackground}
|
||||||
|
handleIndicatorStyle={styles.handleIndicator}
|
||||||
|
backdropComponent={renderBackdrop}
|
||||||
|
footerComponent={renderFooter}
|
||||||
|
keyboardBehavior="interactive"
|
||||||
|
keyboardBlurBehavior="restore"
|
||||||
|
android_keyboardInputMode="adjustResize"
|
||||||
|
topInset={insets.top}
|
||||||
>
|
>
|
||||||
<View style={styles.modalOverlay}>
|
<BottomSheetView style={styles.sheetContent}>
|
||||||
<Pressable style={styles.modalBackdrop} onPress={handleClose} />
|
{/* Header */}
|
||||||
<ReanimatedAnimated.View
|
<View style={styles.header}>
|
||||||
style={[styles.modalContent, animatedKeyboardStyle]}
|
<Text style={styles.headerTitle}>Create New Agent</Text>
|
||||||
|
</View>
|
||||||
|
|
||||||
|
{/* Form */}
|
||||||
|
<BottomSheetScrollView
|
||||||
|
style={styles.scrollView}
|
||||||
|
contentContainerStyle={styles.scrollContent}
|
||||||
|
keyboardShouldPersistTaps="handled"
|
||||||
>
|
>
|
||||||
<View style={styles.modalInner}>
|
{/* Working Directory Input */}
|
||||||
{/* Header */}
|
<View style={styles.formSection}>
|
||||||
<View style={styles.header}>
|
<Text style={styles.label}>Working Directory</Text>
|
||||||
<Text style={styles.headerTitle}>Create New Agent</Text>
|
<BottomSheetTextInput
|
||||||
<Pressable onPress={handleClose}>
|
style={styles.input}
|
||||||
<X size={24} color="white" />
|
placeholder="/path/to/project"
|
||||||
</Pressable>
|
placeholderTextColor={defaultTheme.colors.mutedForeground}
|
||||||
</View>
|
value={workingDir}
|
||||||
|
onChangeText={(text) => {
|
||||||
|
setWorkingDir(text);
|
||||||
|
setErrorMessage("");
|
||||||
|
}}
|
||||||
|
autoCapitalize="none"
|
||||||
|
autoCorrect={false}
|
||||||
|
/>
|
||||||
|
{errorMessage && (
|
||||||
|
<Text style={styles.errorText}>{errorMessage}</Text>
|
||||||
|
)}
|
||||||
|
|
||||||
{/* Form */}
|
{/* Recent Paths Chips */}
|
||||||
<ScrollView
|
{recentPaths.length > 0 && (
|
||||||
style={styles.scrollView}
|
<ScrollView
|
||||||
contentContainerStyle={styles.scrollContent}
|
horizontal
|
||||||
keyboardShouldPersistTaps="handled"
|
showsHorizontalScrollIndicator={false}
|
||||||
keyboardDismissMode="on-drag"
|
contentContainerStyle={styles.recentPathsContainer}
|
||||||
>
|
keyboardShouldPersistTaps="handled"
|
||||||
{/* Working Directory Input */}
|
>
|
||||||
<View style={styles.formSection}>
|
{recentPaths.map((path) => (
|
||||||
<Text style={styles.label}>Working Directory</Text>
|
<Pressable
|
||||||
<TextInput
|
key={path}
|
||||||
style={styles.input}
|
style={styles.recentPathChip}
|
||||||
placeholder="/path/to/project"
|
onPress={() => setWorkingDir(path)}
|
||||||
placeholderTextColor={defaultTheme.colors.mutedForeground}
|
|
||||||
value={workingDir}
|
|
||||||
onChangeText={(text) => {
|
|
||||||
setWorkingDir(text);
|
|
||||||
setErrorMessage("");
|
|
||||||
}}
|
|
||||||
autoCapitalize="none"
|
|
||||||
autoCorrect={false}
|
|
||||||
/>
|
|
||||||
{errorMessage ? (
|
|
||||||
<Text style={styles.errorText}>{errorMessage}</Text>
|
|
||||||
) : (
|
|
||||||
<Text style={styles.helperText}>
|
|
||||||
Absolute path to the project directory
|
|
||||||
</Text>
|
|
||||||
)}
|
|
||||||
|
|
||||||
{/* Recent Paths Chips */}
|
|
||||||
{recentPaths.length > 0 && (
|
|
||||||
<ScrollView
|
|
||||||
horizontal
|
|
||||||
showsHorizontalScrollIndicator={false}
|
|
||||||
contentContainerStyle={styles.recentPathsContainer}
|
|
||||||
keyboardShouldPersistTaps="handled"
|
|
||||||
>
|
>
|
||||||
{recentPaths.map((path) => (
|
<Text style={styles.recentPathChipText} numberOfLines={1}>
|
||||||
<Pressable
|
{path}
|
||||||
key={path}
|
</Text>
|
||||||
style={styles.recentPathChip}
|
</Pressable>
|
||||||
onPress={() => setWorkingDir(path)}
|
))}
|
||||||
>
|
</ScrollView>
|
||||||
<Text style={styles.recentPathChipText} numberOfLines={1}>
|
)}
|
||||||
{path}
|
</View>
|
||||||
</Text>
|
|
||||||
</Pressable>
|
|
||||||
))}
|
|
||||||
</ScrollView>
|
|
||||||
)}
|
|
||||||
</View>
|
|
||||||
|
|
||||||
{/* Mode Selector */}
|
{/* Mode Selector */}
|
||||||
<View style={styles.formSection}>
|
<View style={styles.formSection}>
|
||||||
<Text style={styles.label}>Mode</Text>
|
<Text style={styles.label}>Mode</Text>
|
||||||
<View style={styles.modeContainer}>
|
<View style={styles.modeContainer}>
|
||||||
{MODES.map((mode) => (
|
{MODES.map((mode) => (
|
||||||
<Pressable
|
<Pressable
|
||||||
key={mode.value}
|
key={mode.value}
|
||||||
onPress={() => setSelectedMode(mode.value)}
|
onPress={() => setSelectedMode(mode.value)}
|
||||||
|
style={[
|
||||||
|
styles.modeOption,
|
||||||
|
selectedMode === mode.value && styles.modeOptionSelected,
|
||||||
|
]}
|
||||||
|
>
|
||||||
|
<View style={styles.modeOptionContent}>
|
||||||
|
<View
|
||||||
style={[
|
style={[
|
||||||
styles.modeOption,
|
styles.radioOuter,
|
||||||
selectedMode === mode.value &&
|
selectedMode === mode.value
|
||||||
styles.modeOptionSelected,
|
? styles.radioOuterSelected
|
||||||
|
: styles.radioOuterUnselected,
|
||||||
]}
|
]}
|
||||||
>
|
>
|
||||||
<View style={styles.modeOptionContent}>
|
{selectedMode === mode.value && (
|
||||||
<View
|
<View style={styles.radioInner} />
|
||||||
style={[
|
)}
|
||||||
styles.radioOuter,
|
</View>
|
||||||
selectedMode === mode.value
|
<View style={styles.modeTextContainer}>
|
||||||
? styles.radioOuterSelected
|
<Text style={styles.modeLabel}>{mode.label}</Text>
|
||||||
: styles.radioOuterUnselected,
|
<Text style={styles.modeDescription}>
|
||||||
]}
|
{mode.description}
|
||||||
>
|
</Text>
|
||||||
{selectedMode === mode.value && (
|
</View>
|
||||||
<View style={styles.radioInner} />
|
</View>
|
||||||
)}
|
</Pressable>
|
||||||
</View>
|
))}
|
||||||
<View style={styles.modeTextContainer}>
|
|
||||||
<Text style={styles.modeLabel}>{mode.label}</Text>
|
|
||||||
<Text style={styles.modeDescription}>
|
|
||||||
{mode.description}
|
|
||||||
</Text>
|
|
||||||
</View>
|
|
||||||
</View>
|
|
||||||
</Pressable>
|
|
||||||
))}
|
|
||||||
</View>
|
|
||||||
</View>
|
|
||||||
</ScrollView>
|
|
||||||
|
|
||||||
{/* Fixed Footer with Create Button */}
|
|
||||||
<View
|
|
||||||
style={[
|
|
||||||
styles.footer,
|
|
||||||
{ paddingBottom: Math.max(insets.bottom, 16) },
|
|
||||||
]}
|
|
||||||
>
|
|
||||||
<Pressable
|
|
||||||
style={[
|
|
||||||
styles.createButton,
|
|
||||||
!workingDir.trim() && styles.createButtonDisabled,
|
|
||||||
]}
|
|
||||||
onPress={handleCreate}
|
|
||||||
disabled={!workingDir.trim()}
|
|
||||||
>
|
|
||||||
<Text style={styles.createButtonText}>Create Agent</Text>
|
|
||||||
</Pressable>
|
|
||||||
</View>
|
</View>
|
||||||
</View>
|
</View>
|
||||||
</ReanimatedAnimated.View>
|
</BottomSheetScrollView>
|
||||||
</View>
|
</BottomSheetView>
|
||||||
</Modal>
|
</BottomSheetModal>
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
const styles = StyleSheet.create((theme) => ({
|
const styles = StyleSheet.create((theme) => ({
|
||||||
modalOverlay: {
|
sheetBackground: {
|
||||||
flex: 1,
|
|
||||||
justifyContent: "flex-end",
|
|
||||||
},
|
|
||||||
modalBackdrop: {
|
|
||||||
position: "absolute",
|
|
||||||
top: 0,
|
|
||||||
left: 0,
|
|
||||||
right: 0,
|
|
||||||
bottom: 0,
|
|
||||||
backgroundColor: "rgba(0,0,0,0.5)",
|
|
||||||
zIndex: 1,
|
|
||||||
},
|
|
||||||
modalContent: {
|
|
||||||
backgroundColor: theme.colors.card,
|
backgroundColor: theme.colors.card,
|
||||||
borderTopLeftRadius: theme.spacing[6],
|
|
||||||
borderTopRightRadius: theme.spacing[6],
|
|
||||||
minHeight: "80%",
|
|
||||||
zIndex: 2,
|
|
||||||
elevation: 5,
|
|
||||||
},
|
},
|
||||||
modalInner: {
|
handleIndicator: {
|
||||||
|
backgroundColor: theme.colors.border,
|
||||||
|
},
|
||||||
|
sheetContent: {
|
||||||
flex: 1,
|
flex: 1,
|
||||||
minHeight: 0,
|
|
||||||
},
|
},
|
||||||
header: {
|
header: {
|
||||||
flexDirection: "row",
|
|
||||||
alignItems: "center",
|
alignItems: "center",
|
||||||
justifyContent: "space-between",
|
justifyContent: "center",
|
||||||
padding: theme.spacing[6],
|
padding: theme.spacing[6],
|
||||||
borderBottomWidth: theme.borderWidth[1],
|
borderBottomWidth: theme.borderWidth[1],
|
||||||
borderBottomColor: theme.colors.border,
|
borderBottomColor: theme.colors.border,
|
||||||
@@ -268,7 +276,7 @@ const styles = StyleSheet.create((theme) => ({
|
|||||||
},
|
},
|
||||||
scrollContent: {
|
scrollContent: {
|
||||||
padding: theme.spacing[6],
|
padding: theme.spacing[6],
|
||||||
paddingBottom: theme.spacing[4],
|
paddingBottom: theme.spacing[6],
|
||||||
},
|
},
|
||||||
formSection: {
|
formSection: {
|
||||||
marginBottom: theme.spacing[6],
|
marginBottom: theme.spacing[6],
|
||||||
|
|||||||
Reference in New Issue
Block a user