Skip to content

Commit

Permalink
feat: textinput validation
Browse files Browse the repository at this point in the history
  • Loading branch information
abretonc7s committed Sep 13, 2024
1 parent f780996 commit e6affd5
Show file tree
Hide file tree
Showing 5 changed files with 100 additions and 68 deletions.
83 changes: 81 additions & 2 deletions examples/designdemo/src/app/(tabs)/bug.tsx
Original file line number Diff line number Diff line change
@@ -1,16 +1,21 @@
import { FontAwesome } from "@expo/vector-icons";
import {
BottomSheetBackdrop,
BottomSheetFooter,
BottomSheetModal,
BottomSheetView,
} from "@gorhom/bottom-sheet";
import {
Accordion,
AccordionItemProps,
TextInput,
ThemeConfig,
useModal,
useThemePreferences,
} from "@siteed/design-system/src";
import React, { useMemo, useRef, useState } from "react";
import { StyleSheet, View } from "react-native";
import { useNavigation } from "expo-router";
import React, { useEffect, useMemo, useRef, useState } from "react";
import { Pressable, StyleSheet, View } from "react-native";
import { Button, Text } from "react-native-paper";

import { Form1 } from "../../components/form1";
Expand All @@ -21,9 +26,33 @@ const getStyles = () => {
});
};

const renderMany = () => {
const items = [];
for (let i = 0; i < 100; i++) {
items.push(<Text key={i}>Item {i}</Text>);
}
return items;
};

const accordionData: AccordionItemProps[] = [
{
title: "Accordion Item 1",
children: <Text>Content 1</Text>,
},
{
title: "Accordion Item 2",
children: <View>{renderMany()}</View>,
},
{
title: "Accordion Item 3",
children: <Text>Content 3</Text>,
},
];

export const Bug = () => {
const styles = useMemo(() => getStyles(), []);
const { theme } = useThemePreferences();
const navigation = useNavigation();
const colors = [
theme.colors.primary,
theme.colors.secondary,
Expand All @@ -34,9 +63,59 @@ export const Bug = () => {
const [viewType, setViewType] = useState<"view" | "scroll">("view");
const bottomSheetModalRef = useRef<BottomSheetModal>(null);

useEffect(() => {
// Set navbar title
navigation.setOptions({
headerShow: true,
// headerTitle: "Recording",
headerTitle: ({ tintColor }: { tintColor: string }) => {
return (
<Text style={{ fontSize: 16, fontWeight: "bold", color: tintColor }}>
Recording
</Text>
);
},
headerRight: () => (
<Pressable
style={{ padding: 10 }}
onPress={async () => {
await openDrawer({
bottomSheetProps: {
enableDynamicSizing: true,
snapPoints: [],
},
render: () => <Accordion data={accordionData} />,
});
}}
>
<FontAwesome name="cog" size={24} color={theme.colors.text} />
</Pressable>
),
});
}, [navigation, openDrawer]);

const openAccordion = async () => {
try {
await openDrawer({
bottomSheetProps: {
enableDynamicSizing: true,
snapPoints: [],
},
render: () => (
<View>
<TextInput label="Name" />
<Accordion data={accordionData} />
</View>
),
});
} catch (error) {
console.log(error);
}
};
return (
<View style={styles.container}>
<ThemeConfig colors={colors} />
<Button onPress={openAccordion}>Open Accordion</Button>
<Button
onPress={() => {
setViewType(viewType === "view" ? "scroll" : "view");
Expand Down
1 change: 0 additions & 1 deletion examples/designdemo/src/app/(tabs)/modals.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -229,7 +229,6 @@ export const TestModals = () => {
inputType="text"
autoFocus
showFooter
withinBottomSheet
onCancel={() => {
console.log("onCancel");
bottomSheetModalRef.current?.close();
Expand Down
4 changes: 0 additions & 4 deletions packages/design-system/src/components/DynInput/DynInput.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -49,7 +49,6 @@ export interface DynInputProps {
showFooter?: boolean;
autoFocus?: boolean;
label?: string;
withinBottomSheet?: boolean;
numberOfLines?: number;
useFlatList?: boolean;
customRender?: (
Expand Down Expand Up @@ -92,7 +91,6 @@ export const DynInput = ({
inputType,
showSearch,
showFooter = true,
withinBottomSheet = false,
autoFocus,
label,
numberOfLines,
Expand Down Expand Up @@ -181,7 +179,6 @@ export const DynInput = ({
ref={inputRef}
inputMode="numeric"
onFocus={handleFocus}
withinBottomSheet={withinBottomSheet}
onBlur={handleBlur}
value={temp as string}
onChangeText={handleChange}
Expand All @@ -201,7 +198,6 @@ export const DynInput = ({
multiline={!!(numberOfLines && numberOfLines > 0)}
numberOfLines={numberOfLines}
label={label}
withinBottomSheet={withinBottomSheet}
value={temp as string}
onChangeText={handleChange}
selectTextOnFocus={selectTextOnFocus}
Expand Down
78 changes: 19 additions & 59 deletions packages/design-system/src/components/TextInput/TextInput.tsx
Original file line number Diff line number Diff line change
@@ -1,74 +1,39 @@
import { BottomSheetTextInput } from '@gorhom/bottom-sheet';
import { useBottomSheetInternal } from '@gorhom/bottom-sheet';
import React, {
forwardRef,
useCallback,
useEffect,
useImperativeHandle,
useMemo,
useRef,
} from 'react';
import {
NativeSyntheticEvent,
TextInput as RNTextInput,
StyleSheet,
TextInputFocusEventData,
} from 'react-native';
import { TextInput as GHTextInput } from 'react-native-gesture-handler';
import {
TextInput as PTextInput,
TextInputProps as PTextInputProps,
Text,
} from 'react-native-paper';
import { AppTheme } from '../../hooks/_useAppThemeSetup';
import { useTheme } from '../../providers/ThemeProvider';

export interface TextInputProps extends PTextInputProps {
mandatory?: boolean;
withinBottomSheet?: boolean;
}

export interface InputRefMethods {
focus: () => void;
blur: () => void;
}

const getStyles = ({ theme }: { theme: AppTheme }) =>
StyleSheet.create({
bottomSheetInput: {
fontSize: 16,
color: theme.colors.text,
paddingVertical: 12,
paddingHorizontal: 16,
backgroundColor: theme.colors.background,
borderBottomWidth: 1,
borderBottomColor: theme.colors.surfaceDisabled,
minHeight: 48, // Ensure a minimum height
width: '100%',
borderWidth: 1,
},
});

export const TextInput = forwardRef<InputRefMethods, TextInputProps>(
({ mandatory, label, withinBottomSheet, onFocus, onBlur, ...rest }, ref) => {
const theme = useTheme();
const styles = useMemo(() => getStyles({ theme }), [theme]);
({ mandatory, label, onFocus, onBlur, ...rest }, ref) => {
const inputRef = useRef<RNTextInput>(null);
const bottomSheetInputRef = useRef<GHTextInput>(null);
const { shouldHandleKeyboardEvents } = useBottomSheetInternal();

useImperativeHandle(ref, () => ({
focus: () => {
if (withinBottomSheet) {
bottomSheetInputRef.current?.focus();
} else {
inputRef.current?.focus();
}
},
blur: () => {
if (withinBottomSheet) {
bottomSheetInputRef.current?.blur();
} else {
inputRef.current?.blur();
}
},
focus: () => inputRef.current?.focus(),
blur: () => inputRef.current?.blur(),
}));

const renderLabel = () => {
Expand All @@ -83,40 +48,35 @@ export const TextInput = forwardRef<InputRefMethods, TextInputProps>(
return label;
};

const handleFocus = useCallback(
const handleOnFocus = useCallback(
(event: NativeSyntheticEvent<TextInputFocusEventData>) => {
shouldHandleKeyboardEvents.value = true;
onFocus?.(event);
},
[onFocus]
[onFocus, shouldHandleKeyboardEvents]
);

const handleBlur = useCallback(
const handleOnBlur = useCallback(
(event: NativeSyntheticEvent<TextInputFocusEventData>) => {
shouldHandleKeyboardEvents.value = false;
onBlur?.(event);
},
[onBlur]
[onBlur, shouldHandleKeyboardEvents]
);

if (withinBottomSheet) {
return (
<BottomSheetTextInput
{...rest}
ref={bottomSheetInputRef}
style={styles.bottomSheetInput}
placeholder={label as string}
onFocus={handleFocus}
onBlur={handleBlur}
/>
);
}
useEffect(() => {
return () => {
shouldHandleKeyboardEvents.value = false;
};
}, [shouldHandleKeyboardEvents]);

return (
<PTextInput
{...rest}
ref={inputRef}
label={renderLabel()}
onFocus={handleFocus}
onBlur={handleBlur}
onFocus={handleOnFocus}
onBlur={handleOnBlur}
/>
);
}
Expand Down
2 changes: 0 additions & 2 deletions packages/design-system/src/hooks/useModal.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -53,7 +53,6 @@ export const useModal = () => {
autoFocus={true}
finishOnEnter={true}
selectTextOnFocus={true}
withinBottomSheet={false}
onCancel={() => {
resolve(data);
}}
Expand All @@ -80,7 +79,6 @@ export const useModal = () => {
data={data}
useFlatList={false}
autoFocus={true}
withinBottomSheet={true}
selectTextOnFocus={true}
finishOnEnter={true}
onCancel={() => {
Expand Down

0 comments on commit e6affd5

Please sign in to comment.