import * as React from 'react'; import * as PropTypes from 'prop-types'; import { FieldProps as ReakitFieldProps } from 'reakit/ts/Field/Field'; // @ts-ignore import _omit from 'lodash/omit'; // @ts-ignore import _get from 'lodash/get'; import { Box, Flex } from '../primitives'; import Hidden from '../Hidden'; import Icon from '../Icon'; import Text from '../Text'; import { LocalPopoverProps, popoverPropTypes } from '../Popover/Popover'; import { useUniqueId } from '../uniqueId'; import VisuallyHidden from '../VisuallyHidden'; import OutsideClickHandler from '../_utils/OutsideClickHandler'; import { withTheme } from '../styled'; import { Omit } from '../types'; import _FieldWrapper, { Label, DescriptionText, HintText, OptionalText, RequiredText, TooltipButton, TooltipPopover, ValidationText } from './styled'; export type LocalFieldWrapperProps = { a11yId?: string; children: (({ elementProps }: { elementProps: FieldElementProps }) => React.ReactNode) | React.ReactElement; className?: string; description?: string | React.ReactElement; hint?: string | React.ReactElement; isOptional?: boolean; isRequired?: boolean; label?: string | React.ReactElement; state?: string; tooltip?: string | React.ReactElement; tooltipPopoverProps?: Omit, 'content'>; tooltipTrigger?: React.ReactElement; validationText?: string; }; export type FieldWrapperProps = Omit & LocalFieldWrapperProps; export type FieldElementProps = { a11yId?: LocalFieldWrapperProps['a11yId']; isRequired?: LocalFieldWrapperProps['isRequired']; state?: LocalFieldWrapperProps['state']; marginTop?: string; }; export const FieldWrapper: React.FunctionComponent = ({ a11yId: _a11yId, children, description, hint, isOptional, isRequired, label, state, tooltip, tooltipPopoverProps: _tooltipPopoverProps, tooltipTrigger: _tooltipTrigger, validationText, ...props }) => { const tooltipPopoverProps = _get( props, 'theme.fannypack.FieldWrapper.defaultProps.tooltipPopoverProps', _tooltipPopoverProps ); const tooltipTrigger = _get(props, 'theme.fannypack.FieldWrapper.defaultProps.tooltipTrigger', _tooltipTrigger); const uid = useUniqueId('FieldWrapper'); const a11yId = _a11yId || uid; const elementProps: FieldElementProps = { isRequired, a11yId, state }; return ( <_FieldWrapper {...props}> {label && ( {typeof label === 'string' ? : label} {isOptional && OPTIONAL} {isRequired && *} {tooltip && ( {hidden => ( // @ts-ignore {tooltipTrigger ? ( // @ts-ignore React.cloneElement(tooltipTrigger, { onClick: hidden.toggle }) ) : ( // @ts-ignore Toggle tooltip )} {hidden.isVisible && ( {typeof tooltip === 'string' ? {tooltip} : tooltip} )} )} )} {typeof description === 'string' ? ( {description} ) : (
{description}
)}
)} {typeof children === 'function' ? children({ elementProps }) : React.cloneElement(children as React.ReactElement, elementProps)} {typeof hint === 'string' ? {hint} :
{hint}
} {validationText && {validationText}} ); }; export const fieldWrapperPropTypes = { a11yId: PropTypes.string, children: PropTypes.oneOfType([PropTypes.element, PropTypes.func]).isRequired, className: PropTypes.string, description: PropTypes.oneOfType([PropTypes.string, PropTypes.element]), hint: PropTypes.oneOfType([PropTypes.string, PropTypes.element]), isOptional: PropTypes.bool, isRequired: PropTypes.bool, label: PropTypes.oneOfType([PropTypes.string, PropTypes.element]), state: PropTypes.string, tooltip: PropTypes.oneOfType([PropTypes.string, PropTypes.element]), tooltipPopoverProps: PropTypes.shape(_omit(popoverPropTypes, 'children', 'content')), tooltipTrigger: PropTypes.element, validationText: PropTypes.string }; FieldWrapper.propTypes = fieldWrapperPropTypes; export const fieldWrapperDefaultProps = { a11yId: undefined, className: undefined, description: undefined, hint: undefined, isOptional: undefined, isRequired: undefined, label: undefined, state: undefined, tooltip: undefined, tooltipPopoverProps: undefined, tooltipTrigger: undefined, validationText: undefined }; FieldWrapper.defaultProps = fieldWrapperDefaultProps; // @ts-ignore const C: React.FunctionComponent = withTheme(FieldWrapper); export default C;