Textarea component
Installation
npx shadcn@latest add @caprice/textareanpm install @caprice-ui/reactInstall the following dependencies:
npm install @base-ui/react lucide-reactAdd a cn helper
import { defineConfig, type VariantProps } from 'cva';import { twMerge } from 'tailwind-merge';export const { compose, cva, cx: cn,} = defineConfig({ hooks: { onComplete: (className: string) => twMerge(className), },});export type { VariantProps };Copy and paste the following code into your project.
'use client';import { mergePropsN, useRender } from '@base-ui/react';import { useFocusRing } from 'react-aria';import { cva } from '@/lib/utils';const textareaVariants = cva({ base: [ 'field-sizing-content flex min-h-16 w-full rounded-md border border-input bg-transparent px-3 py-2 text-base shadow-xs outline-none transition-[color,box-shadow] placeholder:text-muted-foreground', // Focus state, using focus instead of focus-visible to avoid confusion with data-focus-visible 'focus:border-ring focus:ring-[3px] focus:ring-ring/50', // Real "focus-visible", only visible when interacting with a keyboard. // ref: https://react-spectrum.adobe.com/react-aria/useFocusRing.html 'data-focus-visible:ring-2 data-focus-visible:ring-foreground data-focus-visible:ring-offset-2', // Disabled state 'disabled:cursor-not-allowed disabled:opacity-50', // Invalid state 'aria-invalid:border-destructive aria-invalid:ring-destructive/20 md:text-sm dark:bg-input/30 dark:aria-invalid:ring-destructive/40', ],});/** * A multi-line text input. * Renders a `<textarea>` element. * * Documentation: [Caprice UI Textarea](https://caprice-ui.com/docs/components/textarea) */export namespace Textarea { export type State = { /** * Whether the textarea is focused using a keyboard */ isFocusVisible: boolean; }; export type Props = useRender.ComponentProps<'textarea', Textarea.State>;}export function Textarea({ className, render, ...props }: Textarea.Props) { const { isFocusVisible, focusProps } = useFocusRing({ isTextInput: true }); const defaultProps: useRender.ElementProps<'textarea'> & { 'data-slot'?: string } = { 'data-slot': 'textarea', className: textareaVariants({ className }), }; return useRender({ defaultTagName: 'textarea', render, state: { isFocusVisible, }, stateAttributesMapping: { isFocusVisible: (value) => (value ? { 'data-focus-visible': '' } : null), }, props: mergePropsN<'textarea'>([defaultProps, focusProps, props]), });}Update the import paths to match your project setup.
Usage
import { Textarea } from "@/components/caprice-ui/textarea"import { Textarea } from "@caprice-ui/react/textarea"Examples
API Reference
Prop
Type