@page "/components/form"

<PageTitle>Form — Lumeo</PageTitle>

<PageHeader Title="Form" Description="Structured form layout with labels, descriptions, and validation messages." />

<div class="mt-10 space-y-3">
    <Heading Id="when-to-use" Level="2" Class="scroll-mt-20">When to Use</Heading>
    <ul class="list-disc list-inside space-y-1 text-muted-foreground text-sm">
        <li>Data collection forms such as registration, contact, or feedback forms</li>
        <li>Settings pages with multiple fields that need labels and validation</li>
        <li>Multi-field validation workflows like password changes or profile updates</li>
        <li>Any form requiring consistent layout with labels, descriptions, and error messages</li>
    </ul>
</div>

<div class="mt-10 space-y-3">
    <Heading Id="validation-pattern" Level="2" Class="scroll-mt-20">Validation Pattern</Heading>
    <p class="text-sm text-muted-foreground">
        Lumeo form inputs (<code class="font-mono text-xs">Input</code>, <code class="font-mono text-xs">Select</code>, <code class="font-mono text-xs">Checkbox</code>, <code class="font-mono text-xs">Switch</code>, <code class="font-mono text-xs">Textarea</code>, and others) do not carry
        <code class="font-mono text-xs">Label</code>, <code class="font-mono text-xs">Required</code>, <code class="font-mono text-xs">Error</code>, or <code class="font-mono text-xs">HelpText</code> props directly.
        Instead, wrap any input in <code class="font-mono text-xs">&lt;FormField&gt;</code> to attach a label, helper text, required marker, and inline error message.
        The <code class="font-mono text-xs">FormField</code> cascades a <code class="font-mono text-xs">FormFieldContext</code> so that child <code class="font-mono text-xs">&lt;FormLabel&gt;</code> and <code class="font-mono text-xs">&lt;FormMessage&gt;</code>
        components automatically reflect the error state without any extra wiring.
    </p>
</div>

<Stack Gap="8" Class="mt-8">
    <ComponentDemo Title="Input with Validation" Code="@_validationInputCode">
        <Stack Gap="4" Class="w-full max-w-sm">
            <FormField Name="email" Label="Email" Required="true" Error="@_emailError" HelpText="We will never share your email.">
                <Input Type="email" Placeholder="you@example.com" @bind-Value="_emailValue" />
            </FormField>
            <Button OnClick="ValidateEmail">Validate</Button>
        </Stack>
    </ComponentDemo>

    <ComponentDemo Title="Select with Validation" Code="@_validationSelectCode">
        <Stack Gap="4" Class="w-full max-w-sm">
            <FormField Name="role" Label="Role" Required="true" Error="@_roleError">
                <Select @bind-Value="_roleValue">
                    <SelectTrigger>
                        <Text As="span" Class="@(_roleValue == null ? "text-muted-foreground" : "")">
                            @(_roleValue ?? "Select a role")
                        </Text>
                    </SelectTrigger>
                    <SelectContent>
                        <SelectItem Value="admin">Admin</SelectItem>
                        <SelectItem Value="editor">Editor</SelectItem>
                        <SelectItem Value="viewer">Viewer</SelectItem>
                    </SelectContent>
                </Select>
            </FormField>
            <Button OnClick="ValidateRole">Validate</Button>
        </Stack>
    </ComponentDemo>

    <ComponentDemo Title="Checkbox and Switch with Validation" Code="@_validationToggleCode">
        <Stack Gap="4" Class="w-full max-w-sm">
            <FormField Name="terms" Error="@_termsError">
                <Flex Gap="2" Align="center">
                    <Checkbox @bind-Checked="_termsChecked" />
                    <Label>I accept the terms and conditions</Label>
                </Flex>
            </FormField>
            <FormField Name="notifications" Label="Email Notifications" HelpText="Receive updates about your account.">
                <Switch @bind-Checked="_notifChecked" />
            </FormField>
            <Button OnClick="ValidateTerms">Submit</Button>
        </Stack>
    </ComponentDemo>
</Stack>

<div class="mt-10 space-y-3">
    <Heading Id="demos" Level="2" Class="scroll-mt-20">Examples</Heading>
</div>

<Stack Gap="8" Class="mt-8">
    <ComponentDemo Title="Default" Code="@_defaultCode">
        <Stack Gap="4" Class="w-full max-w-sm">
            <FormField Name="username">
                <FormItem>
                    <FormLabel>Username</FormLabel>
                    <Input Placeholder="Enter your username" />
                    <FormDescription>This is your public display name.</FormDescription>
                </FormItem>
            </FormField>

            <FormField Name="email">
                <FormItem>
                    <FormLabel>Email</FormLabel>
                    <Input Type="email" Placeholder="you@example.com" />
                    <FormDescription>We will never share your email.</FormDescription>
                </FormItem>
            </FormField>

            <Button>Submit</Button>
        </Stack>
    </ComponentDemo>

    <ComponentDemo Title="With Validation Error" Code="@_errorCode">
        <Stack Gap="4" Class="w-full max-w-sm">
            <FormField Name="email" Error="Please enter a valid email address.">
                <FormItem>
                    <FormLabel>Email</FormLabel>
                    <Input Type="email" Placeholder="you@example.com" />
                    <FormDescription>Enter your email address.</FormDescription>
                    <FormMessage />
                </FormItem>
            </FormField>
        </Stack>
    </ComponentDemo>

    <ComponentDemo Title="Password Change" Code="@_passwordCode">
        <Stack Gap="4" Class="w-full max-w-sm">
            <FormField Name="current">
                <FormItem>
                    <FormLabel>Current Password</FormLabel>
                    <Input Type="password" Placeholder="Enter current password" />
                </FormItem>
            </FormField>
            <FormField Name="new-password" Error="@_pwError">
                <FormItem>
                    <FormLabel>New Password</FormLabel>
                    <Input Type="password" Placeholder="Enter new password" @bind-Value="_newPassword" />
                    <FormDescription>At least 8 characters.</FormDescription>
                    <FormMessage />
                </FormItem>
            </FormField>
            <FormField Name="confirm">
                <FormItem>
                    <FormLabel>Confirm Password</FormLabel>
                    <Input Type="password" Placeholder="Confirm new password" @bind-Value="_confirmPassword" />
                </FormItem>
            </FormField>
            <Button OnClick="ValidatePasswords">Update Password</Button>
        </Stack>
    </ComponentDemo>
</Stack>

<div class="mt-16">
    <Heading Id="api-reference" Level="2" Class="scroll-mt-20">API Reference</Heading>

    <Heading Id="form" Level="3" Class="mt-8 scroll-mt-20">Form&lt;TModel&gt;</Heading>
    <div class="overflow-x-auto mt-4">
        <Table>
            <TableHeader>
                <TableRow>
                    <TableHead Class="w-[180px]">Prop</TableHead>
                    <TableHead Class="w-[180px]">Type</TableHead>
                    <TableHead Class="w-[120px]">Default</TableHead>
                    <TableHead>Description</TableHead>
                </TableRow>
            </TableHeader>
            <TableBody>
                <TableRow><TableCell Class="font-mono text-xs">Model</TableCell><TableCell Class="font-mono text-xs">TModel?</TableCell><TableCell Class="font-mono text-xs">null</TableCell><TableCell>The form model object to validate.</TableCell></TableRow>
                <TableRow><TableCell Class="font-mono text-xs">ChildContent</TableCell><TableCell Class="font-mono text-xs">RenderFragment?</TableCell><TableCell Class="font-mono text-xs">null</TableCell><TableCell>Form fields and submit button.</TableCell></TableRow>
                <TableRow><TableCell Class="font-mono text-xs">OnValidSubmit</TableCell><TableCell Class="font-mono text-xs">EventCallback&lt;TModel&gt;</TableCell><TableCell Class="font-mono text-xs">—</TableCell><TableCell>Callback invoked when the form is submitted and validation passes.</TableCell></TableRow>
                <TableRow><TableCell Class="font-mono text-xs">OnInvalidSubmit</TableCell><TableCell Class="font-mono text-xs">EventCallback&lt;TModel&gt;</TableCell><TableCell Class="font-mono text-xs">—</TableCell><TableCell>Callback invoked when the form is submitted and validation fails.</TableCell></TableRow>
                <TableRow><TableCell Class="font-mono text-xs">Validator</TableCell><TableCell Class="font-mono text-xs">IFormValidator?</TableCell><TableCell Class="font-mono text-xs">null</TableCell><TableCell>Custom validator implementation for the form model.</TableCell></TableRow>
                <TableRow><TableCell Class="font-mono text-xs">Class</TableCell><TableCell Class="font-mono text-xs">string?</TableCell><TableCell Class="font-mono text-xs">null</TableCell><TableCell>Additional CSS classes.</TableCell></TableRow>
                <TableRow><TableCell Class="font-mono text-xs">AdditionalAttributes</TableCell><TableCell Class="font-mono text-xs">Dictionary&lt;string, object&gt;?</TableCell><TableCell Class="font-mono text-xs">null</TableCell><TableCell>Additional HTML attributes.</TableCell></TableRow>
            </TableBody>
        </Table>
    </div>

    <Heading Id="formfield" Level="3" Class="mt-8 scroll-mt-20">FormField</Heading>
    <div class="overflow-x-auto mt-4">
        <Table>
            <TableHeader>
                <TableRow>
                    <TableHead Class="w-[180px]">Prop</TableHead>
                    <TableHead Class="w-[180px]">Type</TableHead>
                    <TableHead Class="w-[120px]">Default</TableHead>
                    <TableHead>Description</TableHead>
                </TableRow>
            </TableHeader>
            <TableBody>
                <TableRow><TableCell Class="font-mono text-xs">Label</TableCell><TableCell Class="font-mono text-xs">string?</TableCell><TableCell Class="font-mono text-xs">null</TableCell><TableCell>Label text for the field.</TableCell></TableRow>
                <TableRow><TableCell Class="font-mono text-xs">HelpText</TableCell><TableCell Class="font-mono text-xs">string?</TableCell><TableCell Class="font-mono text-xs">null</TableCell><TableCell>Helper text shown below the input when there is no error.</TableCell></TableRow>
                <TableRow><TableCell Class="font-mono text-xs">Error</TableCell><TableCell Class="font-mono text-xs">string?</TableCell><TableCell Class="font-mono text-xs">null</TableCell><TableCell>Error message. Turns the label red and displays below the input.</TableCell></TableRow>
                <TableRow><TableCell Class="font-mono text-xs">Required</TableCell><TableCell Class="font-mono text-xs">bool</TableCell><TableCell Class="font-mono text-xs">false</TableCell><TableCell>Shows a red asterisk next to the label.</TableCell></TableRow>
                <TableRow><TableCell Class="font-mono text-xs">Orientation</TableCell><TableCell Class="font-mono text-xs">FormFieldOrientation</TableCell><TableCell Class="font-mono text-xs">Vertical</TableCell><TableCell>Layout orientation. Values: Vertical, Horizontal.</TableCell></TableRow>
                <TableRow><TableCell Class="font-mono text-xs">LabelWidth</TableCell><TableCell Class="font-mono text-xs">string?</TableCell><TableCell Class="font-mono text-xs">null</TableCell><TableCell>Width of the label column in horizontal orientation.</TableCell></TableRow>
                <TableRow><TableCell Class="font-mono text-xs">Name</TableCell><TableCell Class="font-mono text-xs">string?</TableCell><TableCell Class="font-mono text-xs">null</TableCell><TableCell>Field name identifier for validation.</TableCell></TableRow>
                <TableRow><TableCell Class="font-mono text-xs">ChildContent</TableCell><TableCell Class="font-mono text-xs">RenderFragment?</TableCell><TableCell Class="font-mono text-xs">null</TableCell><TableCell>Input elements for the field.</TableCell></TableRow>
                <TableRow><TableCell Class="font-mono text-xs">Class</TableCell><TableCell Class="font-mono text-xs">string?</TableCell><TableCell Class="font-mono text-xs">null</TableCell><TableCell>Additional CSS classes.</TableCell></TableRow>
                <TableRow><TableCell Class="font-mono text-xs">AdditionalAttributes</TableCell><TableCell Class="font-mono text-xs">Dictionary&lt;string, object&gt;?</TableCell><TableCell Class="font-mono text-xs">null</TableCell><TableCell>Additional HTML attributes.</TableCell></TableRow>
            </TableBody>
        </Table>
    </div>

    <Heading Id="formitem" Level="3" Class="mt-8 scroll-mt-20">FormItem</Heading>
    <div class="overflow-x-auto mt-4">
        <Table>
            <TableHeader>
                <TableRow>
                    <TableHead Class="w-[180px]">Prop</TableHead>
                    <TableHead Class="w-[180px]">Type</TableHead>
                    <TableHead Class="w-[120px]">Default</TableHead>
                    <TableHead>Description</TableHead>
                </TableRow>
            </TableHeader>
            <TableBody>
                <TableRow><TableCell Class="font-mono text-xs">ChildContent</TableCell><TableCell Class="font-mono text-xs">RenderFragment?</TableCell><TableCell Class="font-mono text-xs">null</TableCell><TableCell>Form item content (label, input, description, message).</TableCell></TableRow>
                <TableRow><TableCell Class="font-mono text-xs">Class</TableCell><TableCell Class="font-mono text-xs">string?</TableCell><TableCell Class="font-mono text-xs">null</TableCell><TableCell>Additional CSS classes.</TableCell></TableRow>
                <TableRow><TableCell Class="font-mono text-xs">AdditionalAttributes</TableCell><TableCell Class="font-mono text-xs">Dictionary&lt;string, object&gt;?</TableCell><TableCell Class="font-mono text-xs">null</TableCell><TableCell>Additional HTML attributes.</TableCell></TableRow>
            </TableBody>
        </Table>
    </div>

    <Heading Id="formlabel" Level="3" Class="mt-8 scroll-mt-20">FormLabel</Heading>
    <div class="overflow-x-auto mt-4">
        <Table>
            <TableHeader>
                <TableRow>
                    <TableHead Class="w-[180px]">Prop</TableHead>
                    <TableHead Class="w-[180px]">Type</TableHead>
                    <TableHead Class="w-[120px]">Default</TableHead>
                    <TableHead>Description</TableHead>
                </TableRow>
            </TableHeader>
            <TableBody>
                <TableRow><TableCell Class="font-mono text-xs">ChildContent</TableCell><TableCell Class="font-mono text-xs">RenderFragment?</TableCell><TableCell Class="font-mono text-xs">null</TableCell><TableCell>Label text. Turns red when the parent FormField has an error.</TableCell></TableRow>
                <TableRow><TableCell Class="font-mono text-xs">Class</TableCell><TableCell Class="font-mono text-xs">string?</TableCell><TableCell Class="font-mono text-xs">null</TableCell><TableCell>Additional CSS classes.</TableCell></TableRow>
                <TableRow><TableCell Class="font-mono text-xs">AdditionalAttributes</TableCell><TableCell Class="font-mono text-xs">Dictionary&lt;string, object&gt;?</TableCell><TableCell Class="font-mono text-xs">null</TableCell><TableCell>Additional HTML attributes.</TableCell></TableRow>
            </TableBody>
        </Table>
    </div>

    <Heading Id="formdescription" Level="3" Class="mt-8 scroll-mt-20">FormDescription</Heading>
    <div class="overflow-x-auto mt-4">
        <Table>
            <TableHeader>
                <TableRow>
                    <TableHead Class="w-[180px]">Prop</TableHead>
                    <TableHead Class="w-[180px]">Type</TableHead>
                    <TableHead Class="w-[120px]">Default</TableHead>
                    <TableHead>Description</TableHead>
                </TableRow>
            </TableHeader>
            <TableBody>
                <TableRow><TableCell Class="font-mono text-xs">ChildContent</TableCell><TableCell Class="font-mono text-xs">RenderFragment?</TableCell><TableCell Class="font-mono text-xs">null</TableCell><TableCell>Helper description text.</TableCell></TableRow>
                <TableRow><TableCell Class="font-mono text-xs">Class</TableCell><TableCell Class="font-mono text-xs">string?</TableCell><TableCell Class="font-mono text-xs">null</TableCell><TableCell>Additional CSS classes.</TableCell></TableRow>
                <TableRow><TableCell Class="font-mono text-xs">AdditionalAttributes</TableCell><TableCell Class="font-mono text-xs">Dictionary&lt;string, object&gt;?</TableCell><TableCell Class="font-mono text-xs">null</TableCell><TableCell>Additional HTML attributes.</TableCell></TableRow>
            </TableBody>
        </Table>
    </div>

    <Heading Id="formmessage" Level="3" Class="mt-8 scroll-mt-20">FormMessage</Heading>
    <div class="overflow-x-auto mt-4">
        <Table>
            <TableHeader>
                <TableRow>
                    <TableHead Class="w-[180px]">Prop</TableHead>
                    <TableHead Class="w-[180px]">Type</TableHead>
                    <TableHead Class="w-[120px]">Default</TableHead>
                    <TableHead>Description</TableHead>
                </TableRow>
            </TableHeader>
            <TableBody>
                <TableRow><TableCell Class="font-mono text-xs">Class</TableCell><TableCell Class="font-mono text-xs">string?</TableCell><TableCell Class="font-mono text-xs">null</TableCell><TableCell>Additional CSS classes.</TableCell></TableRow>
                <TableRow><TableCell Class="font-mono text-xs">AdditionalAttributes</TableCell><TableCell Class="font-mono text-xs">Dictionary&lt;string, object&gt;?</TableCell><TableCell Class="font-mono text-xs">null</TableCell><TableCell>Additional HTML attributes. Automatically displays the error from the parent FormField.</TableCell></TableRow>
            </TableBody>
        </Table>
    </div>
</div>

<div class="mt-12">
    <Heading Id="related" Level="2" Class="scroll-mt-20">Related Components</Heading>
    <ul class="mt-4 space-y-2 text-sm">
        <li><a href="/components/input" class="text-primary hover:underline">Input</a> — For individual text input fields used within form fields</li>
        <li><a href="/components/select" class="text-primary hover:underline">Select</a> — For dropdown selection fields within forms</li>
        <li><a href="/components/checkbox" class="text-primary hover:underline">Checkbox</a> — For boolean or multi-select options in forms</li>
        <li><a href="/components/button" class="text-primary hover:underline">Button</a> — For form submission and cancel actions</li>
    </ul>
</div>

@code {
    // Validation pattern demos
    private string? _emailValue;
    private string? _emailError;
    private string? _roleValue;
    private string? _roleError;
    private bool _termsChecked;
    private bool _notifChecked = true;
    private string? _termsError;

    private void ValidateEmail()
    {
        if (string.IsNullOrWhiteSpace(_emailValue) || !_emailValue.Contains('@'))
            _emailError = "Please enter a valid email address.";
        else
            _emailError = null;
    }

    private void ValidateRole()
    {
        if (string.IsNullOrEmpty(_roleValue))
            _roleError = "Please select a role.";
        else
            _roleError = null;
    }

    private void ValidateTerms()
    {
        _termsError = _termsChecked ? null : "You must accept the terms to continue.";
    }

    private string _validationInputCode = @"<FormField Name=""email"" Label=""Email"" Required=""true"" Error=""@_emailError"" HelpText=""We will never share your email."">
    <Input Type=""email"" Placeholder=""you@example.com"" @bind-Value=""_emailValue"" />
</FormField>
<Button OnClick=""ValidateEmail"">Validate</Button>

@code {
    private string? _emailValue;
    private string? _emailError;

    private void ValidateEmail()
    {
        if (string.IsNullOrWhiteSpace(_emailValue) || !_emailValue.Contains('@'))
            _emailError = ""Please enter a valid email address."";
        else
            _emailError = null;
    }
}";

    private string _validationSelectCode = @"<FormField Name=""role"" Label=""Role"" Required=""true"" Error=""@_roleError"">
    <Select @bind-Value=""_roleValue"">
        <SelectTrigger>
            <Text As=""span"" Class=""@(_roleValue == null ? \""text-muted-foreground\"" : """")"">
                @(_roleValue ?? ""Select a role"")
            </Text>
        </SelectTrigger>
        <SelectContent>
            <SelectItem Value=""admin"">Admin</SelectItem>
            <SelectItem Value=""editor"">Editor</SelectItem>
            <SelectItem Value=""viewer"">Viewer</SelectItem>
        </SelectContent>
    </Select>
</FormField>
<Button OnClick=""ValidateRole"">Validate</Button>

@code {
    private string? _roleValue;
    private string? _roleError;

    private void ValidateRole()
    {
        if (string.IsNullOrEmpty(_roleValue))
            _roleError = ""Please select a role."";
        else
            _roleError = null;
    }
}";

    private string _validationToggleCode = @"<FormField Name=""terms"" Error=""@_termsError"">
    <Flex Gap=""2"" Align=""center"">
        <Checkbox @bind-Checked=""_termsChecked"" />
        <Label>I accept the terms and conditions</Label>
    </Flex>
</FormField>
<FormField Name=""notifications"" Label=""Email Notifications"" HelpText=""Receive updates about your account."">
    <Switch @bind-Checked=""_notifChecked"" />
</FormField>
<Button OnClick=""ValidateTerms"">Submit</Button>

@code {
    private bool _termsChecked;
    private bool _notifChecked = true;
    private string? _termsError;

    private void ValidateTerms()
    {
        _termsError = _termsChecked ? null : ""You must accept the terms to continue."";
    }
}";

    private string _defaultCode = @"<FormField Name=""username"">
    <FormItem>
        <FormLabel>Username</FormLabel>
        <Input Placeholder=""Enter your username"" />
        <FormDescription>This is your public display name.</FormDescription>
    </FormItem>
</FormField>";

    private string _errorCode = @"<FormField Name=""email"" Error=""Please enter a valid email address."">
    <FormItem>
        <FormLabel>Email</FormLabel>
        <Input Type=""email"" Placeholder=""you@example.com"" />
        <FormDescription>Enter your email address.</FormDescription>
        <FormMessage />
    </FormItem>
</FormField>";

    private string? _newPassword;
    private string? _confirmPassword;
    private string? _pwError;

    private void ValidatePasswords()
    {
        if (_newPassword != _confirmPassword)
            _pwError = "Passwords do not match.";
        else if ((_newPassword?.Length ?? 0) < 8)
            _pwError = "Password must be at least 8 characters.";
        else
            _pwError = null;
    }

    private string _passwordCode = @"<FormField Name=""current"">
    <FormItem>
        <FormLabel>Current Password</FormLabel>
        <Input Type=""password"" Placeholder=""Enter current password"" />
    </FormItem>
</FormField>
<FormField Name=""new-password"" Error=""@_pwError"">
    <FormItem>
        <FormLabel>New Password</FormLabel>
        <Input Type=""password"" Placeholder=""Enter new password"" @bind-Value=""_newPassword"" />
        <FormDescription>At least 8 characters.</FormDescription>
        <FormMessage />
    </FormItem>
</FormField>
<FormField Name=""confirm"">
    <FormItem>
        <FormLabel>Confirm Password</FormLabel>
        <Input Type=""password"" Placeholder=""Confirm new password"" @bind-Value=""_confirmPassword"" />
    </FormItem>
</FormField>
<Button OnClick=""ValidatePasswords"">Update Password</Button>";
}
