Skip to content

Forms & Input

Keep field values in signals and write accepted changes back from callbacks.

#Text input

ui.Input and ui.TextArea are native text editors. Bind Value and update it from OnInput. OnSubmit handles Return in a single-line input.

func InputExample() *ui.Element {
	value, setValue := ui.CreateSignal("")
	return ui.Input().
		Value(value()).
		Placeholder("Write here").
		OnInputEvent(func(event *native.Event) { setValue(event.Value) }).
		Width(320).Height(32)
}

#Fields

Field groups a label, control, description, and error. Drive Required, Invalid, and ValidationMessage from your own state.

func FieldExample() *ui.Element {
	email, setEmail := ui.CreateSignal("")
	field := ui.NewField(ui.FieldRootProps{
		Required: true,
		Filled:   func() bool { return email() != "" },
	})
	return field.Root().FlexCol().Gap(6).Children(
		field.Label().Child("Email"),
		field.Control(ui.FieldControlProps{
			InputPartProps: ui.InputPartProps{
				Value:       email,
				Placeholder: "you@example.com",
				OnInput:     func(event *native.Event) { setEmail(event.Value) },
			},
		}),
		field.Description().Child("Used for receipts"),
		field.Error().Child("Enter a valid email address"),
	)
}

See Field for validation modes.

#Choices

Checkboxes accept bool or mixed state. Radio groups keep one value; checkbox and toggle groups can keep several. Disabled and read-only are separate.

func CheckboxGroupExample() *ui.Element {
	values, setValues := ui.CreateSignal([]string{"email"})
	group := ui.NewCheckboxGroup(ui.CheckboxGroupProps{
		AllValues: []string{"email", "push"},
		Value:     values,
		OnValueChange: func(next []string, _ *native.Event) {
			setValues(next)
		},
	})
	email := ui.NewCheckbox(ui.CheckboxProps{Value: "email"})
	push := ui.NewCheckbox(ui.CheckboxProps{Value: "push"})
	return group.Root().FlexCol().Gap(8).Children(
		email.Root().Child("Email"),
		push.Root().Child("Push"),
	)
}

#Select

Select chooses from a list. Combobox mixes typing and selection. Autocomplete accepts free-form input. Multiple selection uses Values and OnValuesChange.

func SelectExample() *ui.Element {
	value, setValue := ui.CreateSignal[*string](nil)
	picker := ui.NewSelect(ui.SelectRootProps{
		PickerSourceProps: ui.PickerSourceProps{
			Items: func() []ui.OptionDeclaration {
				return []ui.OptionDeclaration{
					{Value: "go", Label: "Go"},
					{Value: "swift", Label: "Swift"},
				}
			},
		},
		Value: value,
		OnValueChange: func(next *string, _ *native.Event) {
			setValue(next)
		},
	})
	return picker.Root().Children(
		picker.Value(),
		picker.Icon().Child("▾"),
	)
}

#Events

Buttons take OnClick(func() { ... }). Use OnClickEvent when you need *native.Event. Compound callbacks include the typed value and, when relevant, the event. Keep UI updates on the UI goroutine; use ui.Async for background work.