import { zodResolver } from "@hookform/resolvers/zod" import type { Meta, StoryObj } from "@storybook/nextjs-vite" import { useEffect } from "react" import { FormProvider, useForm } from "react-hook-form" import { z } from "zod" import { FormTextArea } from "../Form/FormTextArea" import type { MaterialIconProps } from "../Icons/MaterialIcon" interface FormTextAreaStoryProps { label?: string placeholder?: string description?: string descriptionIcon?: MaterialIconProps["icon"] disabled?: boolean readOnly?: boolean required?: boolean showLabel?: boolean showDescription?: boolean showDescriptionIcon?: boolean filled?: boolean defaultValue?: string errorMessage?: string name?: string } function FormTextAreaComponent({ label, placeholder, description, descriptionIcon = "info", disabled = false, readOnly = false, required = false, showLabel = true, showDescription = true, showDescriptionIcon = true, filled = false, defaultValue = "", errorMessage, name = "textarea", }: FormTextAreaStoryProps) { const schema = z.object({ [name]: errorMessage ? z.string().min(1, errorMessage) : required ? z.string().min(1, "This field is required") : z.string().optional(), }) const methods = useForm<{ [key: string]: string }>({ resolver: zodResolver(schema), defaultValues: { [name]: filled ? defaultValue : "", }, mode: "onChange", }) useEffect(() => { if (errorMessage) { // Set error manually if errorMessage is provided methods.setError(name, { type: "manual", message: errorMessage, }) // Trigger validation to show the error immediately methods.trigger(name) } else { // Clear errors if errorMessage is removed methods.clearErrors(name) } }, [errorMessage, methods, name]) return (
) } const meta: Meta = { title: "Core Components/TextArea", component: FormTextAreaComponent, argTypes: { label: { control: "text", description: "The label text displayed above the textarea field", table: { type: { summary: "string" }, }, }, placeholder: { control: "text", description: "Placeholder text shown when textarea is empty", table: { type: { summary: "string" }, defaultValue: { summary: "undefined" }, }, }, description: { control: "text", description: "Supporting text displayed below the textarea", table: { type: { summary: "string" }, defaultValue: { summary: "undefined" }, }, }, disabled: { control: "boolean", description: "Whether the textarea is disabled", table: { type: { summary: "boolean" }, defaultValue: { summary: "false" }, }, }, readOnly: { control: "boolean", description: "Whether the textarea is read-only", table: { type: { summary: "boolean" }, defaultValue: { summary: "false" }, }, }, required: { control: "boolean", description: "Whether the textarea is required", table: { type: { summary: "boolean" }, defaultValue: { summary: "false" }, }, }, showLabel: { control: "boolean", description: "Whether to show the label", table: { type: { summary: "boolean" }, defaultValue: { summary: "true" }, }, }, showDescription: { control: "boolean", description: "Whether to show the description/supporting text", table: { type: { summary: "boolean" }, defaultValue: { summary: "true" }, }, }, defaultValue: { control: "text", description: "Default value when filled is true", table: { type: { summary: "string" }, defaultValue: { summary: "" }, }, }, errorMessage: { control: "text", description: "Error message to display (triggers error state)", table: { type: { summary: "string" }, defaultValue: { summary: "undefined" }, }, }, }, } export default meta type Story = StoryObj export const Default: Story = { args: { label: "Label", placeholder: "Placeholder", description: "Supporting text", disabled: false, readOnly: false, required: false, showLabel: true, showDescription: true, defaultValue: "", errorMessage: undefined, }, }