Namespaced builders for native GPUI controls, collection primitives, and renderer-independent UI composition.
Components are controlled by Elixir assigns and require a stable :id so
native focus, animation, and interaction state survives rerenders. Builders
reject unsupported options and validate schema-backed attribute and event
types before snapshots reach a display. Editable controlled components
require phx-change; invalid contracts raise ArgumentError with the
component, attribute, expectation, and received value.
Summary
Types
Options accepted by accordion_item/1.
Options accepted by accordion/1.
Options accepted by button/1.
Options accepted by checkbox/1.
Options accepted by code_line/1.
Options accepted by code_viewer/1.
Options accepted by combobox/1.
Options accepted by data_table/1.
Options accepted by drop_target/1.
Options accepted by edge_fade/1.
Options accepted by frost/1.
Options accepted by input/1.
Options accepted by paint/1.
Options accepted by progress/1.
Options accepted by radio_group/1.
Options accepted by rich_text/1.
Options accepted by select/1.
Options accepted by separator/1.
Options accepted by sidebar_group/1.
Options accepted by sidebar_header/1.
Options accepted by sidebar_item/1.
Options accepted by sidebar_menu/1.
Options accepted by sidebar/1.
Options accepted by slider/1.
Options accepted by split/1.
Options accepted by status_bar/1.
Options accepted by status_item/1.
Options accepted by switch/1.
Options accepted by table_column/1.
Options accepted by table_row/1.
Options accepted by tabs/1.
Options accepted by tree_item/1.
Options accepted by tree/1.
Options accepted by virtual_collection/1.
Options accepted by virtual_item/1.
Options accepted by virtual_list_item/1.
Options accepted by virtual_list/1.
Functions
Builds a controlled GPUI Component accordion from accordion_item/1 children.
Builds an item for accordion/1.
Builds a native button.
Builds a labeled controlled checkbox using boolean checked and required phx-change.
Builds one native line for code_viewer/1.
Builds a source-backed monospaced code or unified-diff viewer.
Builds a persistent searchable GPUI Component combobox.
Builds an accessible source-backed data grid with fixed column definitions.
Builds a neutral operating-system external-path drop target.
Builds a neutral bounded edge-fade overlay around arbitrary child content.
Builds a renderer-independent field containing one control, its visible label, and optional help or error feedback.
Builds a declarative frosted surface with an explicit fallback contract.
Builds a persistent labeled controlled string input using value and required phx-change.
Builds a bounded serializable custom-paint display list.
Builds an accessible controlled progress indicator.
Builds a controlled GPUI Component radio group.
Builds immutable, selectable, natively shaped rich text.
Builds a persistent native GPUI Component select.
Builds a horizontal or vertical themed separator.
Builds a themed GPUI Component sidebar.
Builds a labelled sidebar item group.
Builds the header region of a sidebar.
Builds a left-aligned sidebar navigation item.
Builds a sidebar menu containing sidebar items.
Builds a persistent controlled GPUI Component slider.
Builds a persistent controlled two-pane native resizable split.
Builds a themed bottom status bar.
Places children in a named status-bar region.
Builds a controlled boolean switch.
Builds one fixed column definition for data_table/1.
Builds one stable, uniform-height row for data_table/1.
Builds a controlled GPUI Component tab bar.
Builds an accessible source-backed tree.
Builds one accessible row for tree/1.
Builds a variable-height virtual collection from stable virtual_item/1 children.
Builds one stable, variable-height item for virtual_collection/1.
Builds a controlled, virtualized list of uniform-height virtual_list_item/1 children.
Builds a stable row for virtual_list/1.
Types
@type accordion_item_options() :: %{ :id => String.t(), :title => String.t(), optional(:disabled) => boolean(), optional(:class) => String.t(), optional(:style) => keyword() | map(), optional(:children) => [GPUI.Element.child()] }
Options accepted by accordion_item/1.
@type accordion_options() :: %{ :id => String.t(), optional(:expanded) => [String.t()], optional(:multiple) => boolean(), optional(:bordered) => boolean(), optional(:size) => String.t(), optional(:disabled) => boolean(), :"phx-change" => String.t(), optional(:class) => String.t(), optional(:style) => keyword() | map(), optional(:children) => [GPUI.Element.child()] }
Options accepted by accordion/1.
@type button_options() :: %{ :id => String.t(), :label => String.t(), optional(:clipboard_text) => String.t(), optional(:file_prompt) => String.t(), optional(:file_max_bytes) => pos_integer(), optional(:variant) => String.t(), optional(:size) => String.t(), optional(:disabled) => boolean(), optional(:selected) => boolean(), optional(:loading) => boolean(), optional(:outline) => boolean(), optional(:compact) => boolean(), optional(:"phx-click") => String.t(), optional(:"phx-clipboard-read") => String.t(), optional(:"phx-clipboard-write") => String.t(), optional(:"phx-file-read") => String.t(), optional(:class) => String.t(), optional(:style) => keyword() | map(), optional(:children) => [GPUI.Element.child()] }
Options accepted by button/1.
@type checkbox_options() :: %{ :id => String.t(), :label => String.t(), optional(:size) => String.t(), optional(:checked) => boolean(), optional(:disabled) => boolean(), :"phx-change" => String.t(), optional(:class) => String.t(), optional(:style) => keyword() | map(), optional(:children) => [GPUI.Element.child()] }
Options accepted by checkbox/1.
@type code_line_options() :: %{ :id => String.t(), :text => String.t(), optional(:number) => non_neg_integer(), optional(:kind) => String.t(), optional(:disabled) => boolean(), optional(:class) => String.t(), optional(:style) => keyword() | map() }
Options accepted by code_line/1.
@type code_viewer_options() :: %{ :id => String.t(), :label => String.t(), optional(:mode) => String.t(), optional(:selected) => String.t(), optional(:selected_index) => non_neg_integer(), optional(:reveal) => String.t(), optional(:reveal_index) => non_neg_integer(), optional(:reveal_strategy) => String.t(), optional(:total_count) => non_neg_integer(), optional(:offset) => non_neg_integer(), optional(:overscan) => non_neg_integer(), optional(:item_height) => number(), optional(:max_columns) => non_neg_integer(), optional(:tab_width) => pos_integer(), optional(:show_line_numbers) => boolean(), optional(:disabled) => boolean(), optional(:"phx-change") => String.t(), optional(:"phx-range") => String.t(), optional(:"phx-copy") => String.t(), optional(:class) => String.t(), optional(:style) => keyword() | map(), optional(:children) => [GPUI.Element.child()] }
Options accepted by code_viewer/1.
@type combobox_options() :: %{ :id => String.t(), :label => String.t(), optional(:value) => String.t(), :options => [select_option()], optional(:placeholder) => String.t(), optional(:search_placeholder) => String.t(), optional(:size) => String.t(), optional(:disabled) => boolean(), optional(:cleanable) => boolean(), optional(:loading) => boolean(), :"phx-change" => String.t(), optional(:"phx-search") => String.t(), optional(:class) => String.t(), optional(:style) => keyword() | map() }
Options accepted by combobox/1.
@type data_table_options() :: %{ :id => String.t(), :label => String.t(), optional(:selected) => String.t(), optional(:selected_index) => non_neg_integer(), optional(:selected_column) => String.t(), optional(:reveal) => String.t(), optional(:reveal_index) => non_neg_integer(), optional(:reveal_strategy) => String.t(), optional(:sort_column) => String.t(), optional(:sort_direction) => String.t(), optional(:total_count) => non_neg_integer(), optional(:offset) => non_neg_integer(), optional(:overscan) => non_neg_integer(), optional(:item_height) => number(), optional(:header_height) => number(), optional(:disabled) => boolean(), optional(:"phx-change") => String.t(), optional(:"phx-cell-change") => String.t(), optional(:"phx-sort") => String.t(), optional(:"phx-range") => String.t(), optional(:class) => String.t(), optional(:style) => keyword() | map(), optional(:children) => [GPUI.Element.child()] }
Options accepted by data_table/1.
@type drop_target_options() :: %{ :id => String.t(), optional(:"phx-drag-enter") => String.t(), optional(:"phx-drag-move") => String.t(), optional(:"phx-drag-leave") => String.t(), optional(:"phx-drop") => String.t(), optional(:class) => String.t(), optional(:style) => keyword() | map(), optional(:children) => [GPUI.Element.child()] }
Options accepted by drop_target/1.
@type edge_fade_options() :: %{ :id => String.t(), optional(:edges) => [String.t() | atom()], optional(:size) => number(), optional(:opacity) => number(), optional(:class) => String.t(), optional(:style) => keyword() | map(), optional(:children) => [GPUI.Element.child()] }
Options accepted by edge_fade/1.
@type file_read_value() :: %{ operation_id: non_neg_integer(), status: :selected, name: String.t(), size: non_neg_integer(), data: binary() } | %{operation_id: non_neg_integer(), status: :cancelled} | %{operation_id: non_neg_integer(), status: :error, reason: String.t()}
@type frost_options() :: %{ :id => String.t(), optional(:fallback) => String.t(), optional(:opacity) => number(), optional(:reduced_transparency) => boolean(), optional(:class) => String.t(), optional(:style) => keyword() | map(), optional(:children) => [GPUI.Element.child()] }
Options accepted by frost/1.
@type input_options() :: %{ :id => String.t(), :label => String.t(), optional(:value) => String.t(), optional(:focus_request) => non_neg_integer(), optional(:placeholder) => String.t(), optional(:size) => String.t(), optional(:disabled) => boolean(), optional(:cleanable) => boolean(), optional(:masked) => boolean(), optional(:loading) => boolean(), :"phx-change" => String.t(), optional(:"phx-submit") => String.t(), optional(:"phx-focus") => String.t(), optional(:"phx-blur") => String.t(), optional(:class) => String.t(), optional(:style) => keyword() | map() }
Options accepted by input/1.
@type paint_options() :: %{ :id => String.t(), optional(:commands) => [map()], optional(:class) => String.t(), optional(:style) => keyword() | map() }
Options accepted by paint/1.
@type progress_options() :: %{ :id => String.t(), :label => String.t(), optional(:value) => number(), optional(:max) => number(), optional(:indeterminate) => boolean(), optional(:class) => String.t(), optional(:style) => keyword() | map() }
Options accepted by progress/1.
@type radio_group_options() :: %{ :id => String.t(), :label => String.t(), :value => String.t(), :options => [radio_option()], optional(:orientation) => String.t(), optional(:size) => String.t(), optional(:disabled) => boolean(), :"phx-change" => String.t(), optional(:class) => String.t(), optional(:style) => keyword() | map() }
Options accepted by radio_group/1.
@type radio_option() :: select_option() | %{ :label => String.t(), :value => String.t(), optional(:disabled) => boolean() }
@type rich_text_options() :: %{ :id => String.t(), :label => String.t(), :text => String.t(), optional(:runs) => [GPUI.Text.RichRun.t()], optional(:selectable) => boolean(), optional(:"phx-link") => String.t(), optional(:class) => String.t(), optional(:style) => keyword() | map() }
Options accepted by rich_text/1.
@type select_options() :: %{ :id => String.t(), :label => String.t(), optional(:value) => String.t(), :options => [select_option()], optional(:placeholder) => String.t(), optional(:size) => String.t(), optional(:disabled) => boolean(), optional(:cleanable) => boolean(), :"phx-change" => String.t(), optional(:class) => String.t(), optional(:style) => keyword() | map() }
Options accepted by select/1.
@type separator_options() :: %{ :id => String.t(), optional(:orientation) => String.t(), optional(:dashed) => boolean(), optional(:label) => String.t(), optional(:class) => String.t(), optional(:style) => keyword() | map() }
Options accepted by separator/1.
@type sidebar_group_options() :: %{ :id => String.t(), :label => String.t(), optional(:class) => String.t(), optional(:style) => keyword() | map(), optional(:children) => [GPUI.Element.child()] }
Options accepted by sidebar_group/1.
@type sidebar_header_options() :: %{ :id => String.t(), optional(:class) => String.t(), optional(:style) => keyword() | map(), optional(:children) => [GPUI.Element.child()] }
Options accepted by sidebar_header/1.
@type sidebar_item_options() :: %{ :id => String.t(), :label => String.t(), optional(:active) => boolean(), optional(:disabled) => boolean(), optional(:"phx-click") => String.t(), optional(:class) => String.t(), optional(:style) => keyword() | map() }
Options accepted by sidebar_item/1.
@type sidebar_options() :: %{ :id => String.t(), optional(:side) => String.t(), optional(:collapsed) => boolean(), optional(:collapsible) => String.t(), optional(:class) => String.t(), optional(:style) => keyword() | map(), optional(:children) => [GPUI.Element.child()] }
Options accepted by sidebar/1.
@type slider_options() :: %{ :id => String.t(), :label => String.t(), optional(:value) => number(), optional(:min) => number(), optional(:max) => number(), optional(:step) => number(), optional(:orientation) => String.t(), optional(:scale) => String.t(), optional(:disabled) => boolean(), optional(:reverse) => boolean(), :"phx-change" => String.t(), optional(:"phx-release") => String.t(), optional(:class) => String.t(), optional(:style) => keyword() | map() }
Options accepted by slider/1.
@type split_options() :: %{ :id => String.t(), optional(:orientation) => String.t(), optional(:sizes) => [number()], optional(:min_sizes) => [number()], optional(:max_sizes) => [number()], optional(:resize_request) => non_neg_integer(), :"phx-change" => String.t(), optional(:class) => String.t(), optional(:style) => keyword() | map(), optional(:children) => [GPUI.Element.child()] }
Options accepted by split/1.
@type status_bar_options() :: %{ :id => String.t(), optional(:class) => String.t(), optional(:style) => keyword() | map(), optional(:children) => [GPUI.Element.child()] }
Options accepted by status_bar/1.
@type status_item_options() :: %{ :id => String.t(), optional(:side) => String.t(), optional(:class) => String.t(), optional(:style) => keyword() | map(), optional(:children) => [GPUI.Element.child()] }
Options accepted by status_item/1.
@type switch_options() :: %{ :id => String.t(), optional(:checked) => boolean(), :label => String.t(), optional(:size) => String.t(), optional(:disabled) => boolean(), optional(:loading) => boolean(), :"phx-change" => String.t(), optional(:class) => String.t(), optional(:style) => keyword() | map() }
Options accepted by switch/1.
@type table_column_options() :: %{ :id => String.t(), :label => String.t(), optional(:width) => number(), optional(:align) => String.t(), optional(:sortable) => boolean(), optional(:class) => String.t(), optional(:style) => keyword() | map() }
Options accepted by table_column/1.
@type table_row_options() :: %{ :id => String.t(), optional(:disabled) => boolean(), optional(:class) => String.t(), optional(:style) => keyword() | map(), optional(:children) => [GPUI.Element.child()] }
Options accepted by table_row/1.
@type tabs_options() :: %{ :id => String.t(), :value => String.t(), :options => [select_option()], optional(:variant) => String.t(), optional(:size) => String.t(), optional(:disabled) => boolean(), optional(:menu) => boolean(), :"phx-change" => String.t(), optional(:class) => String.t(), optional(:style) => keyword() | map() }
Options accepted by tabs/1.
@type tree_item_options() :: %{ :id => String.t(), optional(:parent_id) => String.t(), optional(:level) => pos_integer(), optional(:branch) => boolean(), optional(:expanded) => boolean(), optional(:position) => pos_integer(), optional(:set_size) => pos_integer(), optional(:disabled) => boolean(), optional(:class) => String.t(), optional(:style) => keyword() | map(), optional(:children) => [GPUI.Element.child()] }
Options accepted by tree_item/1.
@type tree_options() :: %{ :id => String.t(), :label => String.t(), optional(:selected) => String.t(), optional(:selected_index) => non_neg_integer(), optional(:reveal) => String.t(), optional(:reveal_index) => non_neg_integer(), optional(:reveal_strategy) => String.t(), optional(:total_count) => non_neg_integer(), optional(:offset) => non_neg_integer(), optional(:overscan) => non_neg_integer(), optional(:item_height) => number(), optional(:disabled) => boolean(), optional(:"phx-change") => String.t(), optional(:"phx-toggle") => String.t(), optional(:"phx-range") => String.t(), optional(:class) => String.t(), optional(:style) => keyword() | map(), optional(:children) => [GPUI.Element.child()] }
Options accepted by tree/1.
@type virtual_collection_options() :: %{ :id => String.t(), :label => String.t(), optional(:alignment) => String.t(), optional(:overdraw) => number(), optional(:reveal) => String.t(), optional(:reveal_request) => non_neg_integer(), optional(:reveal_strategy) => String.t(), optional(:follow) => String.t(), optional(:follow_request) => non_neg_integer(), optional(:"phx-range") => String.t(), optional(:class) => String.t(), optional(:style) => keyword() | map(), optional(:children) => [GPUI.Element.child()] }
Options accepted by virtual_collection/1.
@type virtual_item_options() :: %{ :id => String.t(), optional(:revision) => non_neg_integer(), optional(:class) => String.t(), optional(:style) => keyword() | map(), optional(:children) => [GPUI.Element.child()] }
Options accepted by virtual_item/1.
@type virtual_list_item_options() :: %{ :id => String.t(), optional(:disabled) => boolean(), optional(:class) => String.t(), optional(:style) => keyword() | map(), optional(:children) => [GPUI.Element.child()] }
Options accepted by virtual_list_item/1.
@type virtual_list_options() :: %{ :id => String.t(), :label => String.t(), optional(:selected) => String.t(), optional(:selected_index) => non_neg_integer(), optional(:reveal) => String.t(), optional(:reveal_index) => non_neg_integer(), optional(:reveal_strategy) => String.t(), optional(:total_count) => non_neg_integer(), optional(:offset) => non_neg_integer(), optional(:overscan) => non_neg_integer(), optional(:item_height) => number(), optional(:disabled) => boolean(), optional(:"phx-change") => String.t(), optional(:"phx-range") => String.t(), optional(:class) => String.t(), optional(:style) => keyword() | map(), optional(:children) => [GPUI.Element.child()] }
Options accepted by virtual_list/1.
Functions
@spec accordion(accordion_options()) :: GPUI.Element.t()
Builds a controlled GPUI Component accordion from accordion_item/1 children.
expanded contains the stable item IDs currently open. Changes emit the new
list through phx-change.
Options
| Option | Type | Required | Default |
|---|---|---|---|
:id | String.t() | yes | — |
:expanded | list of String.t() | no | [] |
:multiple | boolean() | no | false |
:bordered | boolean() | no | true |
:size | "xs", "sm", "md", "lg" | no | — |
:disabled | boolean() | no | false |
:"phx-change" | non-empty event name | yes | — |
:class | String.t() | no | — |
:style | keyword() or map() | no | — |
:children | list of GPUI.Element.child/0 | no | [] |
@spec accordion_item(accordion_item_options()) :: GPUI.Element.t()
Builds an item for accordion/1.
Options
| Option | Type | Required | Default |
|---|---|---|---|
:id | String.t() | yes | — |
:title | String.t() | yes | — |
:disabled | boolean() | no | false |
:class | String.t() | no | — |
:style | keyword() or map() | no | — |
:children | list of GPUI.Element.child/0 | no | [] |
@spec button(button_options()) :: GPUI.Element.t()
Builds a native button.
phx-clipboard-write writes bounded clipboard_text to the display-side
clipboard on activation. phx-clipboard-read reads bounded display-side text
and emits it as GPUI.Transfer.Payload. When clipboard and click events are
combined, the clipboard operation is performed first.
phx-file-read opens a display-side file picker, reads one bounded file, and
emits file_read_value/0. file_max_bytes defaults to 10 MiB and may not
exceed 25 MiB. Clipboard operations run before file reads, and file reads run
before an ordinary click event.
Options
| Option | Type | Required | Default |
|---|---|---|---|
:id | String.t() | yes | — |
:label | non-empty String.t() | yes | — |
:clipboard_text | String.t() | no | — |
:file_prompt | String.t() | no | — |
:file_max_bytes | pos_integer() | no | 10485760 |
:variant | "default", "primary", "secondary", "danger", "warning", "success", "info", "ghost", "link", "text" | no | — |
:size | "xs", "sm", "md", "lg" | no | — |
:disabled | boolean() | no | false |
:selected | boolean() | no | false |
:loading | boolean() | no | false |
:outline | boolean() | no | false |
:compact | boolean() | no | false |
:"phx-click" | non-empty event name | no | — |
:"phx-clipboard-read" | non-empty event name | no | — |
:"phx-clipboard-write" | non-empty event name | no | — |
:"phx-file-read" | non-empty event name | no | — |
:class | String.t() | no | — |
:style | keyword() or map() | no | — |
:children | list of GPUI.Element.child/0 | no | [] |
@spec checkbox(checkbox_options()) :: GPUI.Element.t()
Builds a labeled controlled checkbox using boolean checked and required phx-change.
Options
| Option | Type | Required | Default |
|---|---|---|---|
:id | String.t() | yes | — |
:label | non-empty String.t() | yes | — |
:size | "xs", "sm", "md", "lg" | no | — |
:checked | boolean() | no | false |
:disabled | boolean() | no | false |
:"phx-change" | non-empty event name | yes | — |
:class | String.t() | no | — |
:style | keyword() or map() | no | — |
:children | list of GPUI.Element.child/0 | no | [] |
@spec code_line(code_line_options()) :: GPUI.Element.t()
Builds one native line for code_viewer/1.
Options
| Option | Type | Required | Default |
|---|---|---|---|
:id | String.t() | yes | — |
:text | String.t() | yes | — |
:number | non_neg_integer() | no | — |
:kind | "context", "addition", "deletion", "hunk", "debug", "info", "warning", "error" | no | "context" |
:disabled | boolean() | no | false |
:class | String.t() | no | — |
:style | keyword() or map() | no | — |
@spec code_viewer(code_viewer_options()) :: GPUI.Element.t()
Builds a source-backed monospaced code or unified-diff viewer.
Lines are uniform-height code_line/1 children. The viewer shares the
selection, reveal, overscan, and exclusive phx-range contract used by
virtual_list/1. max_columns preserves stable horizontal geometry for
unloaded lines; Ctrl/Cmd+C copies the selected loaded line on the display
machine and acknowledges phx-copy when configured.
Options
| Option | Type | Required | Default |
|---|---|---|---|
:id | String.t() | yes | — |
:label | String.t() | yes | — |
:mode | "plain", "diff" | no | "plain" |
:selected | String.t() | no | — |
:selected_index | non_neg_integer() | no | — |
:reveal | String.t() | no | — |
:reveal_index | non_neg_integer() | no | — |
:reveal_strategy | "nearest", "top", "center", "bottom" | no | "nearest" |
:total_count | non_neg_integer() | no | 0 |
:offset | non_neg_integer() | no | 0 |
:overscan | non_neg_integer() | no | 12 |
:item_height | positive number() | no | 24.0 |
:max_columns | non_neg_integer() | no | 0 |
:tab_width | pos_integer() | no | 4 |
:show_line_numbers | boolean() | no | true |
:disabled | boolean() | no | false |
:"phx-change" | non-empty event name | no | — |
:"phx-range" | non-empty event name | no | — |
:"phx-copy" | non-empty event name | no | — |
:class | String.t() | no | — |
:style | keyword() or map() | no | — |
:children | list of GPUI.Element.child/0 | no | [] |
@spec combobox(combobox_options()) :: GPUI.Element.t()
Builds a persistent searchable GPUI Component combobox.
A non-empty label names the searchable control. Selection changes use
phx-change; search text changes use phx-search. Options use the same
format as select/1.
Options
| Option | Type | Required | Default |
|---|---|---|---|
:id | String.t() | yes | — |
:label | non-empty String.t() | yes | — |
:value | String.t() | no | — |
:options | list of GPUI.UI.select_option/0 | yes | — |
:placeholder | String.t() | no | — |
:search_placeholder | String.t() | no | — |
:size | "xs", "sm", "md", "lg" | no | — |
:disabled | boolean() | no | false |
:cleanable | boolean() | no | false |
:loading | boolean() | no | false |
:"phx-change" | non-empty event name | yes | — |
:"phx-search" | non-empty event name | no | — |
:class | String.t() | no | — |
:style | keyword() or map() | no | — |
@spec data_table(data_table_options()) :: GPUI.Element.t()
Builds an accessible source-backed data grid with fixed column definitions.
table_column/1 children define stable columns and must precede table_row/1
children. Rows use the same controlled selection, reveal, overscan, and
exclusive phx-range contract as virtual_list/1. phx-sort receives a
sortable column ID, while phx-cell-change receives [row_id, column_id].
Options
| Option | Type | Required | Default |
|---|---|---|---|
:id | String.t() | yes | — |
:label | String.t() | yes | — |
:selected | String.t() | no | — |
:selected_index | non_neg_integer() | no | — |
:selected_column | String.t() | no | — |
:reveal | String.t() | no | — |
:reveal_index | non_neg_integer() | no | — |
:reveal_strategy | "nearest", "top", "center", "bottom" | no | "nearest" |
:sort_column | String.t() | no | — |
:sort_direction | "none", "ascending", "descending" | no | "none" |
:total_count | non_neg_integer() | no | 0 |
:offset | non_neg_integer() | no | 0 |
:overscan | non_neg_integer() | no | 8 |
:item_height | positive number() | no | 44.0 |
:header_height | positive number() | no | 40.0 |
:disabled | boolean() | no | false |
:"phx-change" | non-empty event name | no | — |
:"phx-cell-change" | non-empty event name | no | — |
:"phx-sort" | non-empty event name | no | — |
:"phx-range" | non-empty event name | no | — |
:class | String.t() | no | — |
:style | keyword() or map() | no | — |
:children | list of GPUI.Element.child/0 | no | [] |
@spec drop_target(drop_target_options()) :: GPUI.Element.t()
Builds a neutral operating-system external-path drop target.
Paths always refer to the display machine. The renderer bounds and validates paths before emitting typed drag events and never reads dropped files.
Options
| Option | Type | Required | Default |
|---|---|---|---|
:id | non-empty String.t() | yes | — |
:"phx-drag-enter" | non-empty event name | no | — |
:"phx-drag-move" | non-empty event name | no | — |
:"phx-drag-leave" | non-empty event name | no | — |
:"phx-drop" | non-empty event name | no | — |
:class | String.t() | no | — |
:style | keyword() or map() | no | — |
:children | list of GPUI.Element.child/0 | no | [] |
@spec edge_fade(edge_fade_options()) :: GPUI.Element.t()
Builds a neutral bounded edge-fade overlay around arbitrary child content.
edges is a unique subset of :top, :right, :bottom, and :left.
size is bounded to 1–256 native pixels and opacity to 0–1.
Options
| Option | Type | Required | Default |
|---|---|---|---|
:id | String.t() | yes | — |
:edges | unique list of "top", "right", "bottom", "left" | no | [] |
:size | number() from 1 through 256 | no | 24.0 |
:opacity | number() from zero through one | no | 1.0 |
:class | String.t() | no | — |
:style | keyword() or map() | no | — |
:children | list of GPUI.Element.child/0 | no | [] |
@spec field(map()) :: GPUI.Element.t()
Builds a renderer-independent field containing one control, its visible label, and optional help or error feedback.
Error feedback replaces help text and is prefixed with Error:. Set
required: true to mark the visible label; validation and error state remain
controlled by the owning view.
@spec frost(frost_options()) :: GPUI.Element.t()
Builds a declarative frosted surface with an explicit fallback contract.
Set reduced_transparency: true from application accessibility policy to
force an opaque surface. fallback controls unsupported-platform behavior.
Options
| Option | Type | Required | Default |
|---|---|---|---|
:id | String.t() | yes | — |
:fallback | "solid", "translucent" | no | "solid" |
:opacity | number() from zero through one | no | 0.82 |
:reduced_transparency | boolean() | no | false |
:class | String.t() | no | — |
:style | keyword() or map() | no | — |
:children | list of GPUI.Element.child/0 | no | [] |
@spec input(input_options()) :: GPUI.Element.t()
Builds a persistent labeled controlled string input using value and required phx-change.
phx-submit optionally receives Enter activation with the current value.
Increment focus_request to request native focus after validation or another
application-owned transition.
Options
| Option | Type | Required | Default |
|---|---|---|---|
:id | String.t() | yes | — |
:label | non-empty String.t() | yes | — |
:value | String.t() | no | "" |
:focus_request | non_neg_integer() | no | 0 |
:placeholder | String.t() | no | — |
:size | "xs", "sm", "md", "lg" | no | — |
:disabled | boolean() | no | false |
:cleanable | boolean() | no | false |
:masked | boolean() | no | false |
:loading | boolean() | no | false |
:"phx-change" | non-empty event name | yes | — |
:"phx-submit" | non-empty event name | no | — |
:"phx-focus" | non-empty event name | no | — |
:"phx-blur" | non-empty event name | no | — |
:class | String.t() | no | — |
:style | keyword() or map() | no | — |
@spec paint(paint_options()) :: GPUI.Element.t()
Builds a bounded serializable custom-paint display list.
Commands are closed rectangle and line maps. The schema accepts at most 256 commands with bounded coordinates, dimensions, stroke widths, and RGBA colors.
Options
| Option | Type | Required | Default |
|---|---|---|---|
:id | String.t() | yes | — |
:commands | at most 256 bounded rectangle or line commands | no | [] |
:class | String.t() | no | — |
:style | keyword() or map() | no | — |
@spec progress(progress_options()) :: GPUI.Element.t()
Builds an accessible controlled progress indicator.
value defaults to zero, max defaults to 100, and indeterminate enables
native loading animation while preserving the textual accessibility label.
Options
| Option | Type | Required | Default |
|---|---|---|---|
:id | String.t() | yes | — |
:label | String.t() | yes | — |
:value | number() | no | 0.0 |
:max | positive number() | no | 100.0 |
:indeterminate | boolean() | no | false |
:class | String.t() | no | — |
:style | keyword() or map() | no | — |
@spec radio_group(radio_group_options()) :: GPUI.Element.t()
Builds a controlled GPUI Component radio group.
A non-empty label names the radio group for assistive technology. Options
accept the same forms as select/1; maps may additionally set disabled: true.
Options
| Option | Type | Required | Default |
|---|---|---|---|
:id | String.t() | yes | — |
:label | non-empty String.t() | yes | — |
:value | String.t() | yes | — |
:options | list of GPUI.UI.radio_option/0 | yes | — |
:orientation | "horizontal", "vertical" | no | — |
:size | "xs", "sm", "md", "lg" | no | — |
:disabled | boolean() | no | false |
:"phx-change" | non-empty event name | yes | — |
:class | String.t() | no | — |
:style | keyword() or map() | no | — |
@spec rich_text(rich_text_options()) :: GPUI.Element.t()
Builds immutable, selectable, natively shaped rich text.
Elixir supplies plain UTF-8 text and bounded GPUI.Text.RichRun renderer
facts. Runs use zero-based UTF-16 document positions and must be sorted,
non-overlapping, non-empty, and within the supplied text. Unstyled gaps inherit
the component's ordinary text style.
Native state owns transient selection and system copy. Link runs require
phx-link; activation emits the run's opaque link value through the ordinary
controlled event path. This component does not parse Markdown or HTML.
Options
| Option | Type | Required | Default |
|---|---|---|---|
:id | String.t() | yes | — |
:label | String.t() | yes | — |
:text | String.t() | yes | — |
:runs | list of GPUI.Text.RichRun.t/0 | no | — |
:selectable | boolean() | no | true |
:"phx-link" | non-empty event name | no | — |
:class | String.t() | no | — |
:style | keyword() or map() | no | — |
@spec select(select_options()) :: GPUI.Element.t()
Builds a persistent native GPUI Component select.
A non-empty label names the control for assistive technology. Options may be
strings, {label, value} tuples, or maps with string :label and :value
fields.
Options
| Option | Type | Required | Default |
|---|---|---|---|
:id | String.t() | yes | — |
:label | non-empty String.t() | yes | — |
:value | String.t() | no | — |
:options | list of GPUI.UI.select_option/0 | yes | — |
:placeholder | String.t() | no | — |
:size | "xs", "sm", "md", "lg" | no | — |
:disabled | boolean() | no | false |
:cleanable | boolean() | no | false |
:"phx-change" | non-empty event name | yes | — |
:class | String.t() | no | — |
:style | keyword() or map() | no | — |
@spec separator(separator_options()) :: GPUI.Element.t()
Builds a horizontal or vertical themed separator.
@spec sidebar(sidebar_options()) :: GPUI.Element.t()
Builds a themed GPUI Component sidebar.
@spec sidebar_group(sidebar_group_options()) :: GPUI.Element.t()
Builds a labelled sidebar item group.
@spec sidebar_header(sidebar_header_options()) :: GPUI.Element.t()
Builds the header region of a sidebar.
@spec sidebar_item(sidebar_item_options()) :: GPUI.Element.t()
Builds a left-aligned sidebar navigation item.
@spec slider(slider_options()) :: GPUI.Element.t()
Builds a persistent controlled GPUI Component slider.
A non-empty label names the slider's native accessibility group.
phx-change is emitted continuously during pointer interaction and
phx-release is emitted once interaction finishes.
Options
| Option | Type | Required | Default |
|---|---|---|---|
:id | String.t() | yes | — |
:label | non-empty String.t() | yes | — |
:value | number() | no | 0.0 |
:min | number() | no | 0.0 |
:max | number() | no | 100.0 |
:step | number() | no | 1.0 |
:orientation | "horizontal", "vertical" | no | "horizontal" |
:scale | "linear", "logarithmic" | no | "linear" |
:disabled | boolean() | no | false |
:reverse | boolean() | no | false |
:"phx-change" | non-empty event name | yes | — |
:"phx-release" | non-empty event name | no | — |
:class | String.t() | no | — |
:style | keyword() or map() | no | — |
@spec split(split_options()) :: GPUI.Element.t()
Builds a persistent controlled two-pane native resizable split.
sizes, min_sizes, and max_sizes are two-element pixel lists. The native
display owns transient drag mechanics and emits the resulting sizes through
phx-change; the authoritative sizes remain in Elixir assigns.
Options
| Option | Type | Required | Default |
|---|---|---|---|
:id | String.t() | yes | — |
:orientation | "horizontal", "vertical" | no | "horizontal" |
:sizes | two-element list of number() | no | — |
:min_sizes | two-element list of number() | no | [100.0, 100.0] |
:max_sizes | two-element list of number() | no | [100000.0, 100000.0] |
:resize_request | non_neg_integer() | no | 0 |
:"phx-change" | non-empty event name | yes | — |
:class | String.t() | no | — |
:style | keyword() or map() | no | — |
:children | list of GPUI.Element.child/0 | no | [] |
@spec status_bar(status_bar_options()) :: GPUI.Element.t()
Builds a themed bottom status bar.
@spec status_item(status_item_options()) :: GPUI.Element.t()
Places children in a named status-bar region.
@spec switch(switch_options()) :: GPUI.Element.t()
Builds a controlled boolean switch.
A non-empty label provides both the visible and native accessibility name;
phx-change owns changes to boolean checked state.
Options
| Option | Type | Required | Default |
|---|---|---|---|
:id | String.t() | yes | — |
:checked | boolean() | no | false |
:label | non-empty String.t() | yes | — |
:size | "xs", "sm", "md", "lg" | no | — |
:disabled | boolean() | no | false |
:loading | boolean() | no | false |
:"phx-change" | non-empty event name | yes | — |
:class | String.t() | no | — |
:style | keyword() or map() | no | — |
@spec table_column(table_column_options()) :: GPUI.Element.t()
Builds one fixed column definition for data_table/1.
Options
| Option | Type | Required | Default |
|---|---|---|---|
:id | String.t() | yes | — |
:label | String.t() | yes | — |
:width | positive number() | no | 160.0 |
:align | "left", "center", "right" | no | "left" |
:sortable | boolean() | no | false |
:class | String.t() | no | — |
:style | keyword() or map() | no | — |
@spec table_row(table_row_options()) :: GPUI.Element.t()
Builds one stable, uniform-height row for data_table/1.
Options
| Option | Type | Required | Default |
|---|---|---|---|
:id | String.t() | yes | — |
:disabled | boolean() | no | false |
:class | String.t() | no | — |
:style | keyword() or map() | no | — |
:children | list of GPUI.Element.child/0 | no | [] |
@spec tabs(tabs_options()) :: GPUI.Element.t()
Builds a controlled GPUI Component tab bar.
Options use the same label/value format as select/1; value identifies the
selected tab and changes are emitted through phx-change.
Options
| Option | Type | Required | Default |
|---|---|---|---|
:id | String.t() | yes | — |
:value | String.t() | yes | — |
:options | list of GPUI.UI.select_option/0 | yes | — |
:variant | "tab", "outline", "pill", "segmented", "underline" | no | — |
:size | "xs", "sm", "md", "lg" | no | — |
:disabled | boolean() | no | false |
:menu | boolean() | no | false |
:"phx-change" | non-empty event name | yes | — |
:class | String.t() | no | — |
:style | keyword() or map() | no | — |
@spec tree(tree_options()) :: GPUI.Element.t()
Builds an accessible source-backed tree.
phx-change receives selection and phx-toggle receives the stable ID whose
expansion should change. Source-backed ranges follow the same exclusive
phx-range contract as virtual_list/1.
Options
| Option | Type | Required | Default |
|---|---|---|---|
:id | String.t() | yes | — |
:label | String.t() | yes | — |
:selected | String.t() | no | — |
:selected_index | non_neg_integer() | no | — |
:reveal | String.t() | no | — |
:reveal_index | non_neg_integer() | no | — |
:reveal_strategy | "nearest", "top", "center", "bottom" | no | "nearest" |
:total_count | non_neg_integer() | no | 0 |
:offset | non_neg_integer() | no | 0 |
:overscan | non_neg_integer() | no | 8 |
:item_height | positive number() | no | 40.0 |
:disabled | boolean() | no | false |
:"phx-change" | non-empty event name | no | — |
:"phx-toggle" | non-empty event name | no | — |
:"phx-range" | non-empty event name | no | — |
:class | String.t() | no | — |
:style | keyword() or map() | no | — |
:children | list of GPUI.Element.child/0 | no | [] |
@spec tree_item(tree_item_options()) :: GPUI.Element.t()
Builds one accessible row for tree/1.
Options
| Option | Type | Required | Default |
|---|---|---|---|
:id | String.t() | yes | — |
:parent_id | String.t() | no | — |
:level | pos_integer() | no | 1 |
:branch | boolean() | no | false |
:expanded | boolean() | no | false |
:position | pos_integer() | no | — |
:set_size | pos_integer() | no | — |
:disabled | boolean() | no | false |
:class | String.t() | no | — |
:style | keyword() or map() | no | — |
:children | list of GPUI.Element.child/0 | no | [] |
@spec virtual_collection(virtual_collection_options()) :: GPUI.Element.t()
Builds a variable-height virtual collection from stable virtual_item/1 children.
The complete logical collection remains in the renderer-independent snapshot, while the native display measures and renders only the visible region. Items may have different heights and may change height between snapshots.
alignment controls the initial edge, follow enables native tail-following,
and incrementing follow_request explicitly returns to the tail. Increment
reveal_request to repeat a reveal of the same item. phx-range, when set,
receives deduplicated %{first: first, last: last} visible ranges where
last is exclusive.
Source-backed slices are intentionally unsupported until unloaded variable heights have an explicit estimation contract.
Options
| Option | Type | Required | Default |
|---|---|---|---|
:id | String.t() | yes | — |
:label | String.t() | yes | — |
:alignment | "top", "bottom" | no | "top" |
:overdraw | number() | no | 256.0 |
:reveal | String.t() | no | — |
:reveal_request | non_neg_integer() | no | 0 |
:reveal_strategy | "nearest", "top" | no | "nearest" |
:follow | "none", "tail" | no | "none" |
:follow_request | non_neg_integer() | no | 0 |
:"phx-range" | non-empty event name | no | — |
:class | String.t() | no | — |
:style | keyword() or map() | no | — |
:children | list of GPUI.Element.child/0 | no | [] |
@spec virtual_item(virtual_item_options()) :: GPUI.Element.t()
Builds one stable, variable-height item for virtual_collection/1.
IDs are renderer identity and must be non-empty UTF-8 strings no larger than
128 bytes. Increment revision whenever a retained item's content can change
its measured height; unchanged revisions preserve the native height cache.
Options
| Option | Type | Required | Default |
|---|---|---|---|
:id | String.t() | yes | — |
:revision | non_neg_integer() | no | 0 |
:class | String.t() | no | — |
:style | keyword() or map() | no | — |
:children | list of GPUI.Element.child/0 | no | [] |
@spec virtual_list(virtual_list_options()) :: GPUI.Element.t()
Builds a controlled, virtualized list of uniform-height virtual_list_item/1 children.
Only the visible item range is rendered natively. selected identifies the
controlled selection, while reveal requests that an item be scrolled into
view using reveal_strategy. Selection changes are emitted through
phx-change.
Source-backed lists set total_count, offset, and phx-range. Their
children are a contiguous loaded slice beginning at offset; native scroll
and resize changes emit an overscanned %{first: first, last: last} range,
where last is exclusive. selected_index and reveal_index preserve
controlled identity and scrolling when those rows are not currently loaded.
Options
| Option | Type | Required | Default |
|---|---|---|---|
:id | String.t() | yes | — |
:label | String.t() | yes | — |
:selected | String.t() | no | — |
:selected_index | non_neg_integer() | no | — |
:reveal | String.t() | no | — |
:reveal_index | non_neg_integer() | no | — |
:reveal_strategy | "nearest", "top", "center", "bottom" | no | "nearest" |
:total_count | non_neg_integer() | no | 0 |
:offset | non_neg_integer() | no | 0 |
:overscan | non_neg_integer() | no | 8 |
:item_height | positive number() | no | 40.0 |
:disabled | boolean() | no | false |
:"phx-change" | non-empty event name | no | — |
:"phx-range" | non-empty event name | no | — |
:class | String.t() | no | — |
:style | keyword() or map() | no | — |
:children | list of GPUI.Element.child/0 | no | [] |
@spec virtual_list_item(virtual_list_item_options()) :: GPUI.Element.t()
Builds a stable row for virtual_list/1.
Options
| Option | Type | Required | Default |
|---|---|---|---|
:id | String.t() | yes | — |
:disabled | boolean() | no | false |
:class | String.t() | no | — |
:style | keyword() or map() | no | — |
:children | list of GPUI.Element.child/0 | no | [] |