form

package
v0.0.7 Latest Latest
Warning

This package is not in the latest version of its module.

Go to latest
Published: Jan 17, 2026 License: MIT Imports: 9 Imported by: 0

README

Form Components

Complete form system with validation, error handling, and accessibility features.

Components

  • Form - Form wrapper with action and method
  • Field - Complete form field with label, control, error, and description
  • Error - Standalone error message component
  • Description - Standalone helper text component
  • Validators - Validation helper functions

Installation

import (
    "github.com/xraph/forgeui/components/form"
    "github.com/xraph/forgeui/components/input"
)

Basic Usage

Simple Form
myForm := form.Form(
    []form.Option{
        form.WithAction("/submit"),
        form.WithMethod("POST"),
    },
    form.Field(
        "Email",
        input.Input(
            input.WithType("email"),
            input.WithName("email"),
        ),
    ),
    button.Button(
        g.Text("Submit"),
        button.WithType("submit"),
    ),
)
Form Field with All Features
field := form.Field(
    "Email Address",
    input.Input(
        input.WithType("email"),
        input.WithID("email"),
        input.WithName("email"),
        input.WithPlaceholder("you@example.com"),
    ),
    form.WithID("email"),
    form.WithName("email"),
    form.WithRequired(),
    form.WithDescription("We'll never share your email with anyone else."),
    form.WithError("Please enter a valid email address"),
)

Form Component

Props
  • Action - Form action URL
  • Method - HTTP method (default: "POST")
  • Class - Custom CSS classes
  • Attrs - Additional HTML attributes
Options
form.WithAction(action string)
form.WithMethod(method string)
form.WithClass(class string)
form.WithAttrs(attrs ...g.Node)
Example
loginForm := form.Form(
    []form.Option{
        form.WithAction("/auth/login"),
        form.WithMethod("POST"),
        form.WithClass("max-w-md mx-auto"),
    },
    // Form fields...
)

Field Component

Props
  • ID - Field ID (for label association)
  • Name - Field name
  • Required - Mark as required (adds asterisk)
  • Disabled - Mark as disabled
  • Error - Error message to display
  • Description - Helper text to display
  • Class - Custom CSS classes
Options
form.WithID(id string)
form.WithName(name string)
form.WithRequired()
form.WithDisabled()
form.WithError(err string)
form.WithDescription(desc string)
form.WithFieldClass(class string)
Example
emailField := form.Field(
    "Email Address",
    input.Input(
        input.WithType("email"),
        input.WithID("email"),
        input.WithName("email"),
    ),
    form.WithID("email"),
    form.WithRequired(),
    form.WithDescription("Enter your work email"),
)

Error Component

Standalone error message component with ARIA attributes.

Options
form.WithErrorClass(class string)
form.WithErrorAttrs(attrs ...g.Node)
Example
errorMsg := form.Error(
    "Invalid email address",
    form.WithErrorClass("mt-2"),
)

Description Component

Standalone helper text component.

Options
form.WithDescriptionClass(class string)
form.WithDescriptionAttrs(attrs ...g.Node)
Example
helpText := form.Description(
    "Password must be at least 8 characters",
    form.WithDescriptionClass("mt-2"),
)

Validation

Built-in Validators
form.Required()                          // Field is required
form.RequiredWithMessage(msg string)     // Required with custom message
form.Email()                             // Valid email address
form.MinLength(min int)                  // Minimum length
form.MaxLength(max int)                  // Maximum length
form.Pattern(regex, msg string)          // Regex pattern match
form.URL()                               // Valid URL
form.Numeric()                           // Only numbers
form.Alpha()                             // Only letters
form.AlphaNumeric()                      // Letters and numbers
form.In(allowed []string)                // Value in list
Combining Validators
validator := form.Combine(
    form.Required(),
    form.Email(),
    form.MaxLength(100),
)

if err := validator("user@example.com"); err != nil {
    // Handle validation error
}
Validating Fields
// Validate with field name for better errors
err := form.ValidateField(
    "email",
    "user@example.com",
    form.Required(),
    form.Email(),
)

if err != nil {
    // Error includes field name: "email: Invalid email address"
}
Server-Side Validation Example
func handleSubmit(ctx *router.PageContext) g.Node {
    email := ctx.FormValue("email")
    password := ctx.FormValue("password")

    // Validate email
    if err := form.ValidateField("email", email, form.Required(), form.Email()); err != nil {
        return renderForm(err.Error(), "")
    }

    // Validate password
    if err := form.ValidateField("password", password, form.Required(), form.MinLength(8)); err != nil {
        return renderForm("", err.Error())
    }

    // Process form...
}

func renderForm(emailErr, passwordErr string) g.Node {
    return form.Form(
        []form.Option{form.WithAction("/submit")},
        form.Field(
            "Email",
            input.Input(input.WithType("email"), input.WithName("email")),
            form.WithError(emailErr),
        ),
        form.Field(
            "Password",
            input.Input(input.WithType("password"), input.WithName("password")),
            form.WithError(passwordErr),
        ),
    )
}

Complete Form Example

func RegistrationForm() g.Node {
    return form.Form(
        []form.Option{
            form.WithAction("/auth/register"),
            form.WithMethod("POST"),
            form.WithClass("space-y-6 max-w-md mx-auto"),
        },
        // Name field
        form.Field(
            "Full Name",
            input.Input(
                input.WithType("text"),
                input.WithID("name"),
                input.WithName("name"),
                input.WithPlaceholder("John Doe"),
            ),
            form.WithID("name"),
            form.WithRequired(),
        ),
        
        // Email field
        form.Field(
            "Email Address",
            input.Input(
                input.WithType("email"),
                input.WithID("email"),
                input.WithName("email"),
                input.WithPlaceholder("you@example.com"),
            ),
            form.WithID("email"),
            form.WithRequired(),
            form.WithDescription("We'll never share your email."),
        ),
        
        // Password field
        form.Field(
            "Password",
            input.Input(
                input.WithType("password"),
                input.WithID("password"),
                input.WithName("password"),
            ),
            form.WithID("password"),
            form.WithRequired(),
            form.WithDescription("Must be at least 8 characters."),
        ),
        
        // Submit button
        button.Button(
            g.Text("Create Account"),
            button.WithType("submit"),
            button.WithVariant(forgeui.VariantDefault),
            button.WithClass("w-full"),
        ),
    )
}

Accessibility

The form components include proper ARIA attributes:

  • Field: Proper label association with for attribute
  • Error: role="alert" and aria-live="polite" for screen readers
  • Required: Visual indicator (asterisk) and semantic HTML
  • Description: Associated with input via aria-describedby

Styling

All components use Tailwind CSS classes and support dark mode:

  • Error: text-destructive color
  • Description: text-muted-foreground color
  • Field: space-y-2 spacing between elements
  • Form: space-y-6 spacing between fields

Custom Validators

Create custom validators for your specific needs:

func CustomValidator(message string) form.Validator {
    return func(value string) error {
        if !myCustomLogic(value) {
            return form.NewValidationError("", message)
        }
        return nil
    }
}

// Usage
validator := form.Combine(
    form.Required(),
    CustomValidator("Custom validation failed"),
)

Documentation

Overview

Package form provides form wrapper and validation helpers.

Index

Constants

This section is empty.

Variables

This section is empty.

Functions

func Description

func Description(text string, opts ...DescriptionOption) g.Node

Description creates a standalone helper text component

Example:

desc := form.Description(
    "Enter your email address for password reset",
    form.WithDescriptionClass("mt-2"),
)

func Error

func Error(text string, opts ...ErrorOption) g.Node

Error creates a standalone error message component

Example:

err := form.Error(
    "Invalid email address",
    form.WithErrorClass("mt-2"),
)

func Field

func Field(labelText string, control g.Node, opts ...FieldOption) g.Node

Field creates a complete form field with label, control, error, and description

Example:

field := form.Field(
    "Email",
    input.Input(
        input.WithType("email"),
        input.WithPlaceholder("you@example.com"),
    ),
    form.WithID("email"),
    form.WithRequired(),
    form.WithDescription("We'll never share your email."),
)

func FieldControl

func FieldControl(control g.Node) g.Node

FieldControl is a simple wrapper for form controls (for API consistency)

func FieldDescription

func FieldDescription(text string) g.Node

FieldDescription creates a form field description/helper text

func FieldError

func FieldError(text string) g.Node

FieldError creates a form field error message

func FieldLabel

func FieldLabel(text, htmlFor string, required bool) g.Node

FieldLabel creates a form field label

func Form

func Form(opts []Option, children ...g.Node) g.Node

Form creates a form wrapper

func NewValidationError

func NewValidationError(field, message string) error

NewValidationError creates a new validation error

func Validate

func Validate(value string, validators ...Validator) error

Validate validates a value against multiple validators

func ValidateField

func ValidateField(field, value string, validators ...Validator) error

ValidateField validates a field with a name for better error messages

Types

type DescriptionOption

type DescriptionOption func(*DescriptionProps)

DescriptionOption is a functional option for configuring descriptions

func WithDescriptionAttrs

func WithDescriptionAttrs(attrs ...g.Node) DescriptionOption

WithDescriptionAttrs adds custom attributes

func WithDescriptionClass

func WithDescriptionClass(class string) DescriptionOption

WithDescriptionClass adds custom classes

type DescriptionProps

type DescriptionProps struct {
	Class string
	Attrs []g.Node
}

DescriptionProps defines description configuration

type ErrorOption

type ErrorOption func(*ErrorProps)

ErrorOption is a functional option for configuring error messages

func WithErrorAttrs

func WithErrorAttrs(attrs ...g.Node) ErrorOption

WithErrorAttrs adds custom attributes

func WithErrorClass

func WithErrorClass(class string) ErrorOption

WithErrorClass adds custom classes

type ErrorProps

type ErrorProps struct {
	Class string
	Attrs []g.Node
}

ErrorProps defines error message configuration

type FieldOption

type FieldOption func(*FieldProps)

FieldOption is a functional option for configuring form fields

func WithDescription

func WithDescription(desc string) FieldOption

WithDescription sets helper text

func WithDisabled

func WithDisabled() FieldOption

WithDisabled marks the field as disabled

func WithError

func WithError(err string) FieldOption

WithError sets an error message

func WithFieldClass

func WithFieldClass(class string) FieldOption

WithFieldClass adds custom classes

func WithID

func WithID(id string) FieldOption

WithID sets the field ID

func WithName

func WithName(name string) FieldOption

WithName sets the field name

func WithRequired

func WithRequired() FieldOption

WithRequired marks the field as required

type FieldProps

type FieldProps struct {
	ID          string
	Name        string
	Required    bool
	Disabled    bool
	Error       string
	Description string
	Class       string
}

FieldProps defines form field configuration

type Option

type Option func(*Props)

func WithAction

func WithAction(action string) Option

func WithAttrs

func WithAttrs(attrs ...g.Node) Option

func WithClass

func WithClass(class string) Option

func WithMethod

func WithMethod(method string) Option

type Props

type Props struct {
	Action string
	Method string
	Class  string
	Attrs  []g.Node
}

type ValidationError

type ValidationError struct {
	Field   string
	Message string
}

ValidationError represents a validation error

func (*ValidationError) Error

func (e *ValidationError) Error() string

type Validator

type Validator func(value string) error

Validator is a function that validates a value and returns an error if invalid

func Alpha

func Alpha() Validator

Alpha validates that a value contains only alphabetic characters

Example:

validator := form.Alpha()
if err := validator("abc"); err != nil {
    // Handle error: "Must contain only letters"
}

func AlphaNumeric

func AlphaNumeric() Validator

AlphaNumeric validates that a value contains only alphanumeric characters

Example:

validator := form.AlphaNumeric()
if err := validator("abc123"); err != nil {
    // Handle error: "Must contain only letters and numbers"
}

func Combine

func Combine(validators ...Validator) Validator

Combine combines multiple validators into one

Example:

validator := form.Combine(
    form.Required(),
    form.Email(),
    form.MaxLength(100),
)
if err := validator("user@example.com"); err != nil {
    // Handle first validation error
}

func Email

func Email() Validator

Email validates that a value is a valid email address

Example:

validator := form.Email()
if err := validator("invalid-email"); err != nil {
    // Handle error: "Invalid email address"
}

func In

func In(allowed []string) Validator

In validates that a value is in the specified list

Example:

validator := form.In([]string{"small", "medium", "large"})
if err := validator("xlarge"); err != nil {
    // Handle error: "Must be one of: small, medium, large"
}

func MaxLength

func MaxLength(maxLen int) Validator

MaxLength validates that a value does not exceed the specified length

Example:

validator := form.MaxLength(100)
if err := validator("very long text..."); err != nil {
    // Handle error: "Must not exceed 100 characters"
}

func MinLength

func MinLength(minLen int) Validator

MinLength validates that a value has at least the specified length

Example:

validator := form.MinLength(8)
if err := validator("short"); err != nil {
    // Handle error: "Must be at least 8 characters"
}

func Numeric

func Numeric() Validator

Numeric validates that a value contains only numeric characters

Example:

validator := form.Numeric()
if err := validator("12345"); err != nil {
    // Handle error: "Must contain only numbers"
}

func Pattern

func Pattern(pattern, message string) Validator

Pattern validates that a value matches the specified regex pattern

Example:

validator := form.Pattern(`^\d{3}-\d{3}-\d{4}$`, "Invalid phone number format")
if err := validator("123-456-7890"); err != nil {
    // Handle error
}

func Required

func Required() Validator

Required validates that a value is not empty

Example:

validator := form.Required()
if err := validator(""); err != nil {
    // Handle error: "This field is required"
}

func RequiredWithMessage

func RequiredWithMessage(message string) Validator

RequiredWithMessage validates that a value is not empty with a custom message

func URL

func URL() Validator

URL validates that a value is a valid URL

Example:

validator := form.URL()
if err := validator("https://example.com"); err != nil {
    // Handle error: "Invalid URL"
}

Jump to

Keyboard shortcuts

? : This menu
/ : Search site
f or F : Jump to
y or Y : Canonical URL