Displays a form textarea or a component that looks like a textarea.
Installation
npx shadcn@latest add @caprice/textareapnpm dlx shadcn@latest add @caprice/textareayarn dlx shadcn@latest add @caprice/textareabunx shadcn@latest add @caprice/textareanpm install @caprice-ui/reactpnpm add @caprice-ui/reactyarn add @caprice-ui/reactbun add @caprice-ui/reactInstall the following dependencies:
npm install @base-ui/react lucide-reactpnpm add @base-ui/react lucide-reactyarn add @base-ui/react lucide-reactbun add @base-ui/react lucide-reactAdd a cn helper
import { cn as merge } from 'cn';
import type { VariantProps } from 'cva';
import { defineConfig } from 'cva/config';
import { getSchema } from 'cva/tools';
export const { cva, cx: cn } = defineConfig({
cx: merge,
});
export type { VariantProps };
export { getSchema };
Copy and paste the following code into your project.
'use client';
import { mergeProps, useRender } from '@base-ui/react';
import { type PressEvents, useFocusRing, usePress } from 'react-aria';
import { cva, type VariantProps } 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 placeholder:text-muted-foreground',
// Transition
'transition-[color,background-color,border-color,box-shadow]',
// 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 focus:placeholder:text-current',
// Real "focus-visible", only visible when interacting with a keyboard.
// ref: https://react-spectrum.adobe.com/react-aria/useFocusRing.html
'data-focus-visible:outline-2 data-focus-visible:outline-primary data-focus-visible:outline-solid data-focus-visible:outline-offset-2 data-focus-visible:ring-transparent dark:data-focus-visible:outline-primary/64',
// Disabled state
'disabled:cursor-not-allowed disabled:opacity-50',
// Invalid state
'aria-invalid:border-destructive aria-invalid:ring-destructive/20 aria-invalid:data-focus-visible:outline-destructive/80 dark:aria-invalid:data-focus-visible:outline-destructive/48',
],
variants: {
variant: {
outline: [
'bg-transparent',
// Hover state
'not-disabled:hover:not-focus-within:bg-input/32 not-disabled:hover:not-focus-within:placeholder:text-current dark:not-disabled:hover:not-focus-within:bg-input/72',
// Pressed state
'data-pressed:bg-input/48 dark:data-pressed:bg-input/84',
],
},
},
defaultVariants: {
variant: 'outline',
},
});
/**
* 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 Variants = {
/**
* Variant
* @default 'outline'
*/
variant?: VariantProps<typeof textareaVariants>['variant'];
};
export type State = {
/**
* Whether the textarea is focused using a keyboard
*/
isFocusVisible: boolean;
/**
* Whether the textarea is being pressed
*/
isPressed: boolean;
};
export type Props = useRender.ComponentProps<'textarea', Textarea.State> &
PressEvents &
Textarea.Variants;
}
export function Textarea({
className,
variant,
render,
// PressEvents
onPress,
onPressStart,
onPressChange,
onPressEnd,
onPressUp,
onClick,
...props
}: Textarea.Props) {
const { isFocusVisible, focusProps } = useFocusRing({ isTextInput: true });
const { pressProps, isPressed } = usePress({
onPress,
onPressStart,
onPressChange,
onPressEnd,
onPressUp,
onClick,
isDisabled: props.disabled,
});
const defaultProps: useRender.ElementProps<'textarea'> & { 'data-slot'?: string } = {
'data-slot': 'textarea',
className: textareaVariants({ variant, className }),
};
return useRender({
defaultTagName: 'textarea',
render,
state: {
isFocusVisible,
isPressed,
},
stateAttributesMapping: {
isFocusVisible: (value) => (value ? { 'data-focus-visible': '' } : null),
isPressed: (value) => (value ? { 'data-pressed': '' } : null),
},
props: mergeProps<'textarea'>(defaultProps, pressProps, 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"<Textarea />Examples
Default
Disabled
Invalid
With Label
With Text
With Button
API Reference
State
Prop
Type
Default
Props
Prop
Type
Default
Last updated on