Files

118 lines
3.2 KiB
TypeScript

import * as React from 'react';
import { Platform, View, ViewProps, ViewStyle } from 'react-native';
import { Text } from '@components/nativewindui/Text';
import { cn } from '@lib/cn';
import { useColorScheme } from '@hooks/useColorScheme';
const Form = React.forwardRef<View, ViewProps>(({ className, ...props }, ref) => {
return <View ref={ref} className={cn('flex-1 gap-9', className)} {...props} />;
});
// Add as class when possible: https://github.com/marklawlor/nativewind/issues/522
const BORDER_CURVE: ViewStyle = {
borderCurve: 'continuous',
};
type FormSectionProps = ViewProps & {
rootClassName?: string;
footnote?: string;
footnoteClassName?: string;
ios?: {
title: string;
titleClassName?: string;
};
};
const FormSection = React.forwardRef<React.ElementRef<typeof View>, FormSectionProps>(
(
{
rootClassName,
className,
footnote,
footnoteClassName,
ios,
style = BORDER_CURVE,
children: childrenProps,
...props
},
ref
) => {
const { colors } = useColorScheme();
const children = React.useMemo(() => {
if (Platform.OS !== 'ios') return childrenProps;
const childrenArray = React.Children.toArray(childrenProps);
// Add isLast prop to last child
return React.Children.map(childrenArray, (child, index) => {
if (!React.isValidElement(child)) return child;
const isLast = index === childrenArray.length - 1;
if (typeof child === 'string') {
}
return React.cloneElement<ViewProps & { isLast?: boolean }, View>(
typeof child === 'string' ? <></> : child,
{ isLast }
);
});
}, [childrenProps]);
return (
<View
className={cn(
'relative',
Platform.OS !== 'ios' && 'flex-row gap-4',
rootClassName
)}>
{Platform.OS === 'ios' && !!ios?.title && (
<Text
variant="footnote"
className={cn('text-muted-foreground pb-1 pl-3 uppercase', ios?.titleClassName)}>
{ios.title}
</Text>
)}
<View className="flex-1">
<View
ref={ref}
className={cn(
'ios:rounded-lg ios:bg-background ios:gap-0 ios:pl-1 gap-4',
className
)}
style={style}
children={children}
{...props}
/>
{!!footnote && (
<Text
className={cn(
'ios:pl-3 ios:pt-1 text-muted-foreground pl-3 pt-0.5',
footnoteClassName
)}
variant="footnote">
{footnote}
</Text>
)}
</View>
</View>
);
}
);
const FormItem = React.forwardRef<
View,
ViewProps & {
isLast?: boolean;
iosSeparatorClassName?: string;
}
>(({ className, isLast, iosSeparatorClassName, ...props }, ref) => {
return (
<>
<View ref={ref} className={cn('ios:pr-1', className)} {...props} />
{Platform.OS === 'ios' && !isLast && (
<View className={cn('bg-border ml-2 h-px flex-1', iosSeparatorClassName)} />
)}
</>
);
});
export { Form, FormItem, FormSection };