CtrlK
BlogDocsLog inGet started
Tessl Logo

tessl/maven-org-jetbrains-compose-html--core

Compose Web HTML library for building reactive web user interfaces using Kotlin with type-safe HTML DSL, CSS styling, and event handling

Pending
Overview
Eval results
Files

forms-inputs.mddocs/

Forms and Input Handling

Comprehensive form elements and input handling with support for both controlled (Compose-managed) and uncontrolled (browser-managed) modes. All input elements are type-safe and support extensive validation attributes.

Capabilities

Form Container

Form element for grouping form controls with submission handling.

/**
 * Form container element
 * @param action Form submission URL
 * @param attrs Additional attributes including method, encType, target
 * @param content Form content builder
 */
fun Form(
    action: String? = null,
    attrs: AttrBuilderContext<HTMLFormElement>? = null,
    content: ContentBuilder<HTMLFormElement>? = null
)

Generic Input Element

Base input element with type-safe input type specification.

/**
 * Generic input element
 * @param type Input type specification (determines value type)
 * @param attrs Additional attributes for input configuration
 */
fun Input(
    type: InputType<String>,
    attrs: AttrBuilderContext<HTMLInputElement>? = null
)

Specialized Input Elements

Type-specific input elements with appropriate value types and attributes.

/**
 * Text input for single-line text entry
 * @param value Current text value (controlled mode) or null (uncontrolled)
 * @param attrs Additional attributes
 */
fun TextInput(
    value: String? = null,
    attrs: AttrBuilderContext<HTMLInputElement>? = null
)

/**
 * Password input with masked text entry
 * @param value Current password value or null
 * @param attrs Additional attributes
 */
fun PasswordInput(
    value: String? = null,
    attrs: AttrBuilderContext<HTMLInputElement>? = null
)

/**
 * Number input for numeric values
 * @param value Current numeric value or null
 * @param min Minimum allowed value
 * @param max Maximum allowed value
 * @param attrs Additional attributes
 */
fun NumberInput(
    value: Number? = null,
    min: Number? = null,
    max: Number? = null,
    attrs: AttrBuilderContext<HTMLInputElement>? = null
)

/**
 * Range slider input
 * @param value Current range value or null
 * @param min Minimum value (default 0)
 * @param max Maximum value (default 100)
 * @param step Step increment (default 1)
 * @param attrs Additional attributes
 */
fun RangeInput(
    value: Number? = null,
    min: Number? = null,
    max: Number? = null,
    step: Number? = null,
    attrs: AttrBuilderContext<HTMLInputElement>? = null
)

/**
 * Email input with built-in email validation
 * @param value Current email value or null
 * @param attrs Additional attributes
 */
fun EmailInput(
    value: String? = null,
    attrs: AttrBuilderContext<HTMLInputElement>? = null
)

/**
 * URL input with built-in URL validation
 * @param value Current URL value or null
 * @param attrs Additional attributes
 */
fun UrlInput(
    value: String? = null,
    attrs: AttrBuilderContext<HTMLInputElement>? = null
)

/**
 * Telephone input for phone numbers
 * @param value Current phone value or null
 * @param attrs Additional attributes
 */
fun TelInput(
    value: String? = null,
    attrs: AttrBuilderContext<HTMLInputElement>? = null
)

/**
 * Search input with search-specific styling
 * @param value Current search value or null
 * @param attrs Additional attributes
 */
fun SearchInput(
    value: String? = null,
    attrs: AttrBuilderContext<HTMLInputElement>? = null
)

/**
 * Checkbox input for boolean values
 * @param checked Current checked state or null
 * @param attrs Additional attributes
 */
fun CheckboxInput(
    checked: Boolean? = null,
    attrs: AttrBuilderContext<HTMLInputElement>? = null
)

/**
 * Radio button input for exclusive selection
 * @param checked Current checked state or null
 * @param attrs Additional attributes (name attribute required for grouping)
 */
fun RadioInput(
    checked: Boolean? = null,
    attrs: AttrBuilderContext<HTMLInputElement>? = null
)

/**
 * File upload input
 * @param value Current file path or null
 * @param attrs Additional attributes including accept, multiple
 */
fun FileInput(
    value: String? = null,
    attrs: AttrBuilderContext<HTMLInputElement>? = null
)

/**
 * Hidden input for storing form data
 * @param attrs Attributes including value
 */
fun HiddenInput(attrs: AttrBuilderContext<HTMLInputElement>? = null)

/**
 * Submit button input
 * @param attrs Additional attributes including value (button text)
 */
fun SubmitInput(attrs: AttrBuilderContext<HTMLInputElement>? = null)

Date and Time Inputs

Specialized inputs for date and time selection.

/**
 * Date picker input
 * @param value Current date value (YYYY-MM-DD format) or null
 * @param attrs Additional attributes
 */
fun DateInput(
    value: String? = null,
    attrs: AttrBuilderContext<HTMLInputElement>? = null
)

/**
 * Time picker input
 * @param value Current time value (HH:MM format) or null
 * @param attrs Additional attributes
 */
fun TimeInput(
    value: String? = null,
    attrs: AttrBuilderContext<HTMLInputElement>? = null
)

/**
 * Date and time picker input
 * @param value Current datetime value (YYYY-MM-DDTHH:MM format) or null
 * @param attrs Additional attributes
 */
fun DateTimeLocalInput(
    value: String? = null,
    attrs: AttrBuilderContext<HTMLInputElement>? = null
)

/**
 * Month picker input
 * @param value Current month value (YYYY-MM format) or null
 * @param attrs Additional attributes
 */
fun MonthInput(
    value: String? = null,
    attrs: AttrBuilderContext<HTMLInputElement>? = null
)

/**
 * Week picker input
 * @param value Current week value (YYYY-WNN format) or null
 * @param attrs Additional attributes
 */
fun WeekInput(
    value: String? = null,
    attrs: AttrBuilderContext<HTMLInputElement>? = null
)

Form Controls

Additional form control elements.

/**
 * Multi-line text input
 * @param value Current text value or null
 * @param attrs Additional attributes including rows, cols, wrap
 */
fun TextArea(
    value: String? = null,
    attrs: AttrBuilderContext<HTMLTextAreaElement>? = null
)

/**
 * Button element
 * @param attrs Additional attributes including type (button, submit, reset)
 * @param content Button content
 */
fun Button(
    attrs: AttrBuilderContext<HTMLButtonElement>? = null,
    content: ContentBuilder<HTMLButtonElement>? = null
)

/**
 * Select dropdown element
 * @param attrs Additional attributes
 * @param multiple Allow multiple selections
 * @param content Option elements
 */
fun Select(
    attrs: AttrBuilderContext<HTMLSelectElement>? = null,
    multiple: Boolean = false,
    content: ContentBuilder<HTMLSelectElement>? = null
)

/**
 * Option element for select dropdowns
 * @param value Option value
 * @param attrs Additional attributes including selected
 * @param content Option display text
 */
fun Option(
    value: String,
    attrs: AttrBuilderContext<HTMLOptionElement>? = null,
    content: ContentBuilder<HTMLOptionElement>? = null
)

/**
 * Option group for organizing select options
 * @param label Group label
 * @param attrs Additional attributes
 * @param content Option elements
 */
fun OptGroup(
    label: String,
    attrs: AttrBuilderContext<HTMLOptGroupElement>? = null,
    content: ContentBuilder<HTMLOptGroupElement>? = null
)

/**
 * Label element for form controls
 * @param forId ID of associated form control
 * @param attrs Additional attributes
 * @param content Label text or content
 */
fun Label(
    forId: String? = null,
    attrs: AttrBuilderContext<HTMLLabelElement>? = null,
    content: ContentBuilder<HTMLLabelElement>? = null
)

/**
 * Fieldset for grouping form controls
 * @param attrs Additional attributes
 * @param content Fieldset content including legend
 */
fun Fieldset(
    attrs: AttrBuilderContext<HTMLFieldSetElement>? = null,
    content: ContentBuilder<HTMLFieldSetElement>? = null
)

/**
 * Legend element for fieldset caption
 * @param attrs Additional attributes
 * @param content Legend text
 */
fun Legend(
    attrs: AttrBuilderContext<HTMLLegendElement>? = null,
    content: ContentBuilder<HTMLLegendElement>? = null
)

/**
 * Data list for input suggestions
 * @param attrs Additional attributes including id
 * @param content Option elements
 */
fun Datalist(
    attrs: AttrBuilderContext<HTMLDataListElement>? = null,
    content: ContentBuilder<HTMLDataListElement>? = null
)

Input Types

Type-safe input type hierarchy for the generic Input element.

/**
 * Base input type class
 * @param T Value type for the input
 */
sealed class InputType<T>

// Text-based input types
object InputType.Text : InputType<String>
object InputType.Password : InputType<String>
object InputType.Email : InputType<String>
object InputType.Url : InputType<String>
object InputType.Tel : InputType<String>
object InputType.Search : InputType<String>

// Numeric input types  
object InputType.Number : InputType<String>
object InputType.Range : InputType<String>

// Boolean input types
object InputType.Checkbox : InputType<Boolean>
object InputType.Radio : InputType<Boolean>

// Date/time input types
object InputType.Date : InputType<String>
object InputType.Time : InputType<String>
object InputType.DateTimeLocal : InputType<String>
object InputType.Month : InputType<String>
object InputType.Week : InputType<String>

// File input type
object InputType.File : InputType<String>

// Button input types
object InputType.Submit : InputType<String>
object InputType.Button : InputType<String>
object InputType.Reset : InputType<String>

// Hidden input type
object InputType.Hidden : InputType<String>

// Color input type
object InputType.Color : InputType<String>

Form Attributes

Comprehensive form-related attributes for validation and behavior control.

/**
 * Form-specific attributes (available on AttrsScope)
 */

// Input value attributes
fun AttrsScope<HTMLInputElement>.value(value: String)
fun AttrsScope<HTMLInputElement>.defaultValue(value: String)
fun AttrsScope<HTMLTextAreaElement>.value(value: String)
fun AttrsScope<HTMLTextAreaElement>.defaultValue(value: String)

// Input configuration
fun AttrsScope<HTMLInputElement>.placeholder(value: String)
fun AttrsScope<HTMLTextAreaElement>.placeholder(value: String)
fun AttrsScope<*>.name(value: String)
fun AttrsScope<*>.required()
fun AttrsScope<*>.disabled()
fun AttrsScope<*>.readOnly()
fun AttrsScope<*>.autoFocus()

// Validation attributes
fun AttrsScope<HTMLInputElement>.minLength(value: Int)
fun AttrsScope<HTMLInputElement>.maxLength(value: Int)
fun AttrsScope<HTMLTextAreaElement>.minLength(value: Int)
fun AttrsScope<HTMLTextAreaElement>.maxLength(value: Int)
fun AttrsScope<HTMLInputElement>.min(value: String)
fun AttrsScope<HTMLInputElement>.max(value: String)
fun AttrsScope<HTMLInputElement>.step(value: Number)
fun AttrsScope<HTMLInputElement>.pattern(value: String)

// File input attributes
fun AttrsScope<HTMLInputElement>.accept(value: String)
fun AttrsScope<HTMLInputElement>.multiple()
fun AttrsScope<HTMLSelectElement>.multiple()

// Form behavior attributes
fun AttrsScope<HTMLInputElement>.autoComplete(value: AutoComplete)
fun AttrsScope<HTMLFormElement>.action(value: String)
fun AttrsScope<HTMLFormElement>.method(value: FormMethod)
fun AttrsScope<HTMLFormElement>.encType(value: FormEncType)
fun AttrsScope<HTMLFormElement>.target(value: FormTarget)
fun AttrsScope<HTMLFormElement>.noValidate()

// TextArea specific attributes
fun AttrsScope<HTMLTextAreaElement>.rows(value: Int)
fun AttrsScope<HTMLTextAreaElement>.cols(value: Int)
fun AttrsScope<HTMLTextAreaElement>.wrap(value: TextAreaWrap)

// Button attributes
fun AttrsScope<HTMLButtonElement>.type(value: ButtonType)

// Select attributes
fun AttrsScope<HTMLOptionElement>.selected()
fun AttrsScope<HTMLOptionElement>.value(value: String)

// Label attributes
fun AttrsScope<HTMLLabelElement>.forId(value: String)

Form Enums and Constants

Type-safe enums for form-related attribute values.

// Form methods
enum class FormMethod { Get, Post, Dialog }

// Form encoding types
enum class FormEncType { 
    ApplicationXWwwFormUrlencoded,
    MultipartFormData,
    TextPlain
}

// Form and link targets
enum class FormTarget { Blank, Self, Parent, Top }
enum class ATarget { Blank, Self, Parent, Top }

// Button types
enum class ButtonType { Button, Submit, Reset }

// Text area wrapping
enum class TextAreaWrap { Hard, Soft, Off }

// Auto-completion values
enum class AutoComplete {
    On, Off, Name, Email, Username, NewPassword, CurrentPassword,
    OneTimeCode, Organization, StreetAddress, AddressLine1,
    AddressLine2, AddressLevel1, AddressLevel2, Country,
    CountryName, PostalCode, CcName, CcGivenName, CcFamilyName,
    CcNumber, CcExp, CcExpMonth, CcExpYear, CcCsc, CcType,
    TransactionCurrency, TransactionAmount, Language, Bday,
    BdayDay, BdayMonth, BdayYear, Sex, Tel, TelCountryCode,
    TelNational, TelAreaCode, TelLocal, TelExtension, Impp, Url,
    Photo, Webauthn
}

Usage Examples:

import org.jetbrains.compose.web.dom.*
import org.jetbrains.compose.web.attributes.*

// Controlled input with state management
var username by remember { mutableStateOf("") }
var password by remember { mutableStateOf("") }
var rememberMe by remember { mutableStateOf(false) }

Form({
    onSubmit { event ->
        event.preventDefault()
        console.log("Login attempt: $username")
    }
}) {
    Fieldset {
        Legend { Text("Login Form") }
        
        // Text input with validation
        Label(forId = "username") { Text("Username:") }
        TextInput(value = username, {
            id("username")
            placeholder("Enter your username")
            required()
            minLength(3)
            maxLength(20)
            pattern("[a-zA-Z0-9_]+")
            autoComplete(AutoComplete.Username)
            
            onInput { event ->
                username = (event.target as HTMLInputElement).value
            }
        })
        
        // Password input
        Label(forId = "password") { Text("Password:") }
        PasswordInput(value = password, {
            id("password")
            placeholder("Enter your password")
            required()
            minLength(8)
            autoComplete(AutoComplete.CurrentPassword)
            
            onInput { event ->
                password = (event.target as HTMLInputElement).value
            }
        })
        
        // Checkbox input
        Label {
            CheckboxInput(checked = rememberMe, {
                onChange { event ->
                    rememberMe = (event.target as HTMLInputElement).checked
                }
            })
            Text(" Remember me")
        }
        
        // Submit button
        Button({ type(ButtonType.Submit) }) {
            Text("Login")
        }
    }
}

// Uncontrolled form with default values
Form({
    action("/submit")
    method(FormMethod.Post)
    encType(FormEncType.MultipartFormData)
}) {
    // Form will manage its own state
    TextInput({
        name("fullName")
        defaultValue("John Doe")
        placeholder("Full Name")
        required()
    })
    
    EmailInput({
        name("email")
        placeholder("Email Address")
        required()
    })
    
    Select({
        name("country")
        required()
    }) {
        Option("", { selected() }) { Text("Select Country") }
        Option("us") { Text("United States") }
        Option("ca") { Text("Canada") }
        Option("uk") { Text("United Kingdom") }
    }
    
    SubmitInput({ value("Submit") })
}

// Advanced form with file upload and validation
var selectedFile by remember { mutableStateOf<File?>(null) }
var description by remember { mutableStateOf("") }

Form({
    onSubmit { event ->
        event.preventDefault()
        
        if (selectedFile != null && description.isNotBlank()) {
            // Handle file upload
            console.log("Uploading file: ${selectedFile?.name}")
        }
    }
}) {
    Label(forId = "file") { Text("Select File:") }
    FileInput({
        id("file")
        accept("image/*,.pdf,.doc,.docx")
        required()
        
        onChange { event ->
            val input = event.target as HTMLInputElement
            selectedFile = input.files?.get(0)
        }
    })
    
    Label(forId = "description") { Text("Description:") }
    TextArea(value = description, {
        id("description")
        rows(4)
        cols(50)
        placeholder("Describe the file...")
        required()
        maxLength(500)
        
        onInput { event ->
            description = (event.target as HTMLTextAreaElement).value
        }
    })
    
    Button({ type(ButtonType.Submit) }) {
        Text("Upload File")
    }
}

// Radio button group
var selectedOption by remember { mutableStateOf("") }

Fieldset {
    Legend { Text("Choose an option:") }
    
    listOf("option1" to "First Option", "option2" to "Second Option", "option3" to "Third Option").forEach { (value, label) ->
        Label {
            RadioInput(checked = selectedOption == value, {
                name("radioGroup")
                value(value)
                onChange { event ->
                    if ((event.target as HTMLInputElement).checked) {
                        selectedOption = value
                    }
                }
            })
            Text(" $label")
        }
        Br()
    }
}

// Number and range inputs with validation
var quantity by remember { mutableStateOf(1) }
var rating by remember { mutableStateOf(5) }

Label(forId = "quantity") { Text("Quantity:") }
NumberInput(value = quantity, min = 1, max = 100, {
    id("quantity")
    step(1)
    required()
    
    onInput { event ->
        val value = (event.target as HTMLInputElement).value.toIntOrNull()
        if (value != null) quantity = value
    }
})

Label(forId = "rating") { Text("Rating: $rating") }
RangeInput(value = rating, min = 1, max = 10, step = 1, {
    id("rating")
    
    onInput { event ->
        rating = (event.target as HTMLInputElement).value.toInt()
    }
})

// Date and time inputs
var selectedDate by remember { mutableStateOf("") }
var selectedTime by remember { mutableStateOf("") }

Label(forId = "date") { Text("Select Date:") }
DateInput(value = selectedDate, {
    id("date")
    min("2024-01-01")
    max("2024-12-31")
    
    onChange { event ->
        selectedDate = (event.target as HTMLInputElement).value
    }
})

Label(forId = "time") { Text("Select Time:") }
TimeInput(value = selectedTime, {
    id("time")
    step(900) // 15-minute increments
    
    onChange { event ->
        selectedTime = (event.target as HTMLInputElement).value
    }
})

Install with Tessl CLI

npx tessl i tessl/maven-org-jetbrains-compose-html--core

docs

css-styling.md

event-handling.md

forms-inputs.md

html-elements.md

index.md

svg-support.md

tile.json