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 && (
{description}
) const LabelContents = () => ( <> {beforeLabel && ( {beforeLabel} )} {label} {afterLabel && ( {afterLabel} )} > ) return (