TextArea
A multi-line plain-text editing control, useful when you want to allow users to enter a sizeable amount of free-form text, for example a comment on a review or feedback form.
import { TextArea } from "@ngrok/mantle/text-area";
<TextArea placeholder="Tell us about your experience…" />
<TextArea appearance="monospaced" placeholder="Tell us about your experience…" />
<TextArea placeholder="Tell us about your experience…" validation="error" />
Examples
TextArea in a form with client-side validation
In this example, the TextArea
is used in a form with client-side validation. The form is built using @tanstack/react-form
and zod
for validation. The form accepts user feedback and validates the input before submission.
import { Button } from "@ngrok/mantle/button";
import { Label } from "@ngrok/mantle/label";
import { TextArea } from "@ngrok/mantle/text-area";
import { useForm } from "@tanstack/react-form";
import { z } from "zod";
import { useSubmit } from "react-router";
const formSchema = z.object({
feedback: z.string().trim().min(1, "Please enter your feedback."),
});
type FormValues = z.infer<typeof formSchema>;
function FormExample() {
const submit = useSubmit();
const form = useForm({
defaultValues: {
feedback: "",
} satisfies FormValues,
validators: {
onSubmit: formSchema,
},
onSubmit: ({ value }) => {
// Handle form submission here
submit(value, {
method: "post",
});
},
});
return (
<form
className="space-y-4"
onSubmit={(event) => {
event.preventDefault();
event.stopPropagation();
void form.handleSubmit();
}}
>
<div className="space-y-1">
<Label htmlFor="feedback" className="block">
Feedback:
</Label>
<form.Field name="feedback">
{(field) => (
<TextArea
id={field.name}
name={field.name}
onBlur={field.handleBlur}
onChange={(event) => field.handleChange(event.target.value)}
placeholder="Tell us about your experience…"
validation={field.state.meta.errors.length > 0 && "error"}
value={field.state.value}
/>
)}
</form.Field>
<form.Field name="feedback">
{(field) =>
field.state.meta.errors.map((error) => (
<p
key={error?.message}
className="text-sm leading-4 text-danger-600"
>
{error?.message}
</p>
))
}
</form.Field>
</div>
<form.Subscribe selector={(state) => state.isDirty}>
{(isDirty) => (
<Button type="submit" appearance="filled" disabled={!isDirty}>
Submit
</Button>
)}
</form.Subscribe>
</form>
);
}
API Reference
The TextArea
accepts the following props in addition to the standard HTML textarea attributes.