// Styled Input/TextArea = the unstyled @tamagui/ui Input/TextArea behavior // primitives + the default v2-look skin (theme palette, border, background, font // family, hover/focus color styling, and the size table), layered here in // `tamagui`. The behavior primitives keep only structural resets. Single skin // definition; the shadcn registry item is generated from this file. import { type ComponentSize, createStyledHOC, type GetProps, isWeb, styled, Theme, type ThemeProps, } from '@tamagui/core' import { Input as UiInput, TextArea as UiTextArea } from '@tamagui/input' export type InputSize = ComponentSize | boolean const inputSize = { xs: { paddingInline: '2', paddingBlock: '1', borderRadius: 'sm', fontSize: 'xs' }, sm: { paddingInline: '3', paddingBlock: '1.5', borderRadius: 'md', fontSize: 'sm' }, md: { paddingInline: '4', paddingBlock: '2', borderRadius: 'md', fontSize: 'sm' }, lg: { paddingInline: '6', paddingBlock: '2', borderRadius: 'md', fontSize: 'base' }, xl: { paddingInline: '8', paddingBlock: '2.5', borderRadius: 'lg', fontSize: 'lg' }, } as const const inputLineHeight = { xs: 'xs', sm: 'sm', md: 'sm', lg: 'base', xl: 'lg', } as const const resolveInputSize = (size: InputSize | undefined): keyof typeof inputSize => typeof size === 'string' && size in inputSize ? (size as keyof typeof inputSize) : 'md' // line height ships only on web: on native the platform default applies, so an // input's height stays padding plus line height on both platforms const resolveInputLineHeight = (props: { size?: InputSize; lineHeight?: unknown }) => { if (!isWeb || props.lineHeight != null) return const lineHeight = inputLineHeight[resolveInputSize(props.size)] if (lineHeight) return { lineHeight } } const inputSkin = { fontFamily: 'body', color: 'color', backgroundColor: 'background', borderColor: 'border-color hover:border-color-hover focus:border-color-focus', borderWidth: 1, outlineColor: 'focus-visible:outline-color', outlineWidth: 'focus-visible:2px', outlineStyle: 'focus-visible:solid', } as const const InputFrame = styled(UiInput, { displayName: 'Input', className: 'is_Input', ...inputSkin, variants: { size: { ...inputSize, true: inputSize.md, }, } as const, defaultVariants: { size: 'md', }, }).resolve((props) => resolveInputLineHeight(props as any)) const TextAreaFrame = styled(UiTextArea, { displayName: 'TextArea', className: 'is_TextArea', ...inputSkin, variants: { size: { ...inputSize, true: inputSize.md, }, } as const, defaultVariants: { size: 'md', }, }).resolve((props) => resolveInputLineHeight(props as any)) export const Input = createStyledHOC( InputFrame, function Input({ theme, ...props }, ref) { const input = ( ) return theme ? {input} : input }, { disableTheme: true } ) export const TextArea = createStyledHOC( TextAreaFrame, function TextArea({ theme, ...props }, ref) { const textArea = ( ) return theme ? {textArea} : textArea }, { disableTheme: true } ) export type InputProps = GetProps export type TextAreaProps = GetProps