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.
1import { TextArea } from "@ngrok/mantle/text-area";2 3<TextArea placeholder="Tell us about your experience…" />4<TextArea appearance="monospaced" placeholder="Tell us about your experience…" />5<TextArea placeholder="Tell us about your experience…" validation="error" />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.
1import { Button } from "@ngrok/mantle/button";2import { Label } from "@ngrok/mantle/label";3import { TextArea } from "@ngrok/mantle/text-area";4import { useForm } from "@tanstack/react-form";5import { z } from "zod";6import { useSubmit } from "react-router";7 8const formSchema = z.object({9 feedback: z.string().trim().min(1, "Please enter your feedback."),10});11 12type FormValues = z.infer<typeof formSchema>;13 14function FormExample() {15 const submit = useSubmit();16 const form = useForm({17 defaultValues: {18 feedback: "",19 } satisfies FormValues,20 validators: {21 onSubmit: formSchema,22 },23 onSubmit: ({ value }) => {24 // Handle form submission here25 submit(value, {26 method: "post",27 });28 },29 });30 31 return (32 <form33 className="space-y-4"34 onSubmit={(event) => {35 event.preventDefault();36 event.stopPropagation();37 void form.handleSubmit();38 }}39 >40 <div className="space-y-1">41 <Label htmlFor="feedback" className="block">42 Feedback:43 </Label>44 <form.Field name="feedback">45 {(field) => (46 <TextArea47 id={field.name}48 name={field.name}49 onBlur={field.handleBlur}50 onChange={(event) => field.handleChange(event.target.value)}51 placeholder="Tell us about your experience…"52 validation={field.state.meta.errors.length > 0 && "error"}53 value={field.state.value}54 />55 )}56 </form.Field>57 <form.Field name="feedback">58 {(field) =>59 field.state.meta.errors.map((error) => (60 <p key={error?.message} className="text-sm leading-4 text-danger-600">61 {error?.message}62 </p>63 ))64 }65 </form.Field>66 </div>67 <form.Subscribe selector={(state) => state.isDirty}>68 {(isDirty) => (69 <Button type="submit" appearance="filled" disabled={!isDirty}>70 Submit71 </Button>72 )}73 </form.Subscribe>74 </form>75 );76}A multi-line plain-text editing control.
All props from textarea, plus: