Compose Web HTML library for building reactive web user interfaces using Kotlin with type-safe HTML DSL, CSS styling, and event 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.
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
)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
)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)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
)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
)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>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)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