import { cva } from 'class-variance-authority' import React from 'react' import { FormDescription_Shadcn_, FormLabel_Shadcn_, FormMessage_Shadcn_, Label_Shadcn_, cn, } from 'ui' import { SIZE } from 'ui/src/lib/constants' type Props = { align?: 'left' | 'right' description?: string | React.ReactNode error?: string | React.ReactNode label?: string | React.ReactNode labelOptional?: string | React.ReactNode layout?: 'horizontal' | 'vertical' | 'flex' size?: 'tiny' | 'small' | 'medium' | 'large' | 'xlarge' beforeLabel?: string | React.ReactNode afterLabel?: string | React.ReactNode nonBoxInput?: boolean labelLayout?: 'horizontal' | 'vertical' isReactForm?: boolean hideMessage?: boolean name?: string } const ContainerVariants = cva('grid gap-2', { variants: { size: { tiny: 'text-xs', small: 'text-sm leading-4', medium: 'text-sm', large: 'text-base', xlarge: 'text-base', }, align: { left: '', right: '' }, responsive: { true: '', false: '', }, layout: { horizontal: 'grid grid-cols-12', vertical: 'flex flex-col gap-3', flex: 'flex flex-row gap-3', }, flex: { true: '', false: '', }, }, compoundVariants: [ { layout: 'flex', align: 'right', className: 'justify-between', }, ], defaultVariants: {}, }) const LabelContainerVariants = cva('', { variants: { flex: { true: '', false: '', }, align: { left: '', right: '', }, layout: { horizontal: 'flex flex-col gap-2 col-span-4', vertical: 'flex flex-row gap-2 justify-between', flex: 'flex flex-col gap-0', }, labelLayout: { horizontal: '', vertical: '', ['']: '', }, }, compoundVariants: [ { flex: true, align: 'left', className: 'order-2', }, { flex: true, align: 'right', className: 'order-1', }, { layout: 'vertical' || 'flex', labelLayout: undefined, flex: false, className: 'flex flex-row gap-2 justify-between', }, { layout: 'horizontal', className: 'flex flex-col gap-2', }, ], defaultVariants: {}, }) const DataContainerVariants = cva('', { variants: { flex: { true: '', false: '', }, align: { left: 'order-1', right: 'order-2', }, layout: { horizontal: '', vertical: '', flex: '', }, }, compoundVariants: [ { flex: true, align: 'left', className: 'order-1', }, { flex: true, align: 'right', className: 'order-2', }, { layout: 'vertical' || 'flex', className: 'col-span-12', }, { layout: 'horizontal', align: 'left', className: 'col-span-8', }, { layout: 'horizontal', align: 'right', className: 'text-right', }, ], defaultVariants: {}, }) const DescriptionVariants = cva('text-foreground-lighter leading-normal', { variants: { size: { ...SIZE.text, }, layout: { vertical: 'mt-2', horizontal: 'mt-2', flex: '', }, }, defaultVariants: {}, }) const LabelBeforeVariants = cva('text-foreground-muted', { variants: { size: { ...SIZE.text, }, }, defaultVariants: {}, }) const LabelAfterVariants = cva('text-foreground-muted', { variants: { size: { ...SIZE.text, }, }, defaultVariants: {}, }) const LabelOptionalVariants = cva('text-foreground-muted', { variants: { size: { ...SIZE.text, }, }, defaultVariants: {}, }) const FlexContainer = cva('', { variants: { flex: { true: '', false: '', }, align: { left: '', right: '', }, }, compoundVariants: [ { flex: true, align: 'left', className: '', }, { flex: true, align: 'right', className: 'order-last', }, ], }) const NonBoxInputContainer = cva('', { variants: { nonBoxInput: { true: '', false: '', }, label: { true: '', false: '', }, layout: { vertical: '', horizontal: '', }, }, compoundVariants: [ { nonBoxInput: true, label: true, layout: 'vertical', className: 'my-3', }, { nonBoxInput: true, label: true, layout: 'horizontal', className: 'my-3 md:mt-0 mb-3', }, ], defaultVariants: {}, }) export const FormLayout = React.forwardRef< HTMLDivElement, React.ComponentPropsWithoutRef<'div'> & Props >( ( { align = 'left', className, description, id, label, labelOptional, layout = 'vertical', style, labelLayout, size = 'medium', beforeLabel, afterLabel, nonBoxInput = label ? false : true, hideMessage = false, isReactForm, ...props }, ref ) => { const flex = layout === 'flex' const hasLabel = Boolean(label || beforeLabel || afterLabel) const renderError = isReactForm && !hideMessage && ( ) const renderDescription = description && isReactForm ? ( {description} ) : (

{description}

) const LabelContents = () => ( <> {beforeLabel && ( {beforeLabel} )} {label} {afterLabel && ( {afterLabel} )} ) return (
{flex &&
{props.children}
} {hasLabel || labelOptional || layout === 'horizontal' ? ( <>
{hasLabel && isReactForm ? ( ) : ( )} {labelOptional && ( {labelOptional} )} {flex && ( <> {renderDescription} {renderError} )}
) : null} {!flex && (
<>
{props.children}
{renderError} {renderDescription}
)}
) } )