import * as React from 'react'; import { ViewProps as RNViewProps } from 'react-native'; import { createComponent, createElement, createHook, useUniqueId } from 'bumbag/utils'; import { Box, BoxProps } from '../Box'; import { Flex } from '../Flex'; import * as styles from './FieldWrapper.styles'; export type LocalFieldWrapperProps = { children?: (({ elementProps }: { elementProps: FieldElementProps }) => React.ReactNode) | React.ReactElement; /** Sets the description text of the field wrapper. */ description?: string | React.ReactElement; /** Sets the bottom hint text of the field wrapper. */ hint?: string | React.ReactElement; /** Sets the optional flag (and displays optional text) on the field wrapper. */ isOptional?: boolean; /** Sets the required flag (and a required astrix) on the field wrapper. */ isRequired?: boolean; /** Sets the label on the field wrapper. */ label?: string | React.ReactElement; /** Sets the label type on the field wrapper. */ labelType?: 'legend' | 'label'; /** Sets the state of the field wrapper. */ state?: 'success' | 'danger' | 'warning'; /** Sets the tooltip of the field wrapper. Can be either a string, or a React component. */ tooltip?: string | React.ReactElement; /** Sets the tooltip trigger component. */ tooltipTriggerComponent?: React.ReactElement; /** Sets the bottom validation text of the field wrapper. */ validationText?: string; }; export type FieldWrapperProps = BoxProps & RNViewProps & LocalFieldWrapperProps; export type FieldElementProps = { id?: string; state?: LocalFieldWrapperProps['state']; }; const useProps = createHook( (props) => { const { children, description, hint, isOptional, label, labelType, isRequired, overrides, state, validationText, variant, ...restProps } = props; const boxProps = Box.useProps(restProps); const uid = useUniqueId(); const elementProps = { accessibilityLabelledBy: uid, variant, state }; return { ...boxProps, children: ( {label && ( <> {typeof label === 'string' ? ( {label} ) : ( label )} )} {isOptional && OPTIONAL} {isRequired && *} {description && {description}} {typeof children === 'function' ? /* // @ts-ignore */ children({ elementProps }) : /* // @ts-ignore */ React.cloneElement(children as React.ReactElement, elementProps)} {hint && ( {typeof hint === 'string' ? {hint} : hint} )} {validationText && ( {validationText} )} ), }; }, { defaultProps: { variant: 'bordered' }, themeKey: 'native.FieldWrapper' } ); export const FieldWrapper = createComponent( (props) => { const htmlProps = useProps(props); return createElement({ children: props.children, component: styles.FieldWrapper, htmlProps, }); }, { attach: { useProps, displayName: 'native.FieldWrapper', }, themeKey: 'native.FieldWrapper', } );