Built-in types

v0.0.1

Gervaz resolves a type name in the DSL to a module. This page lists the built-in column, filter, action and field types, and the ui.extra keys each column type reads. A module that implements the matching behaviour also works as a column type or an action type, with no registration. A custom filter or field module is used only to parse, validate and query. Gervaz returns a name it does not know unchanged, so a misspelled ui do type :imagee end does not fail at compile time. The schema also accepts :currency, :percentage, :time, :image, :avatar, :progress, :json and :custom as column types. No module draws them, so they raise when the cell is drawn. To write your own, see Write a custom type.

Column types

Set a column type with ui do type :badge end. A column without a type takes one from its Ash attribute when the attribute type is in the last column of this table, and :text otherwise.

TypeDrawsInferred from
:textPlain text, with optional truncation. The default.anything else
:booleanA check or a cross icon, or a text label.Ash.Type.Boolean
:numberA number with optional prefix, suffix and separators.Ash.Type.Integer, Ash.Type.Float, Ash.Type.Decimal
:dateA date in a format you choose.Ash.Type.Date
:datetimeA date and time in a format you choose, or a relative time.Ash.Type.DateTime, Ash.Type.UtcDatetime, Ash.Type.UtcDatetimeUsec
:uuidA UUID cut to its first characters.Ash.Type.UUID, Ash.Type.UUIDv7
:arrayThe items of a list, joined or drawn as badges.array attributes
:badgeA status badge whose color and label come from the value.never inferred
:barsA small numeric value as filled bars beside the number.never inferred
:tagsA list value as chips, with a +N chip that expands the rest in place.never inferred
:avatarsRelated people as an overlapping avatar stack, with a +N disc that expands the rest.never inferred
:linkA clickable link.never inferred

Options in ui.extra

Each type reads its options from the extra map of the column's ui block.

TypeKeyMeaning
:text:max_lengthTruncates the text after this many characters. Not set by default.
:text:truncate_suffixThe suffix of truncated text. Default "...".
:text:dir"ltr", "rtl" or "auto". Without it, a value of printable ASCII with no space, such as an email, a URL or an ID, reads left to right, and any other value follows the page.
:boolean:true_icon, :false_iconThe icons. Defaults "hero-check" and "hero-x-mark".
:boolean:true_class, :false_classThe icon classes. The UI adapter supplies the defaults, which are "size-5 text-[#177a53]" and "size-5 text-[#c0473d]" in the Tailwind adapter. A value you set replaces the whole string, size-5 included.
:boolean:true_label, :false_labelText labels, as an alternative to the icons.
:number:precisionDecimal precision. It applies to floats and decimals, and integers ignore it. Not set by default, so the number shows as it is.
:number:prefix, :suffixStrings placed before and after the number, such as "$" or " kg".
:number:thousands_separator, :decimal_separatorSeparators. Defaults "," and ".".
:date:formatA date format string. Default "%Y-%m-%d".
:datetime:formatA format string. Default "%Y-%m-%d %H:%M".
:datetime:relativeShows a relative time such as "2 hours ago". Default false.
:uuid:show_fullShows the whole UUID. Default false.
:uuid:prefix_length, :suffix_lengthCharacters shown at the start and the end. Defaults 8 and 0.
:array:separatorThe separator between items. Default ", ".
:array:max_itemsThe most items to show. Not set by default, so all show.
:array:as_badges, :badge_classDraws each item as a badge, and the badge class. Default false.
:badge:colorsA map of value to color class. Keys match the string form of the value first, then its existing atom.
:badge:labelsA map of value to label, translated in the reader's locale. A value without one falls back to its humanized form.
:badge:dotsA map of value to dot class, for the :pill variant.
:badge:variant:tag (the default) or :pill, which has a leading dot.
:badge:default_colorThe color class for a value that is not in :colors.
:bars:maxThe number of bars. Default 4.
:bars:percentSet true when the value is a 0 to 100 weight. The bars fill in proportion, and the color follows the percentage band.
:bars:ceilingAn explicit denominator for proportional fill. percent: true is shorthand for ceiling: 100. Without either, the lit count is min(max, value + 1).
:bars:scaleAn ordered list of {max_value_inclusive, hex} tuples ending in {:default, hex}. The first entry whose threshold is at least the value wins.
:tags:max_itemsChips shown before the +N chip. Default 2.
:tags:badge_class, :emptyThe chip class, and the text for an empty list. An item is a string, or %{label:, class:, title:} for a chip styled on its own.
:avatars:max_itemsFaces shown before the +N disc. Default 3.
:avatars:image_field, :label_fieldThe fields of the related record that hold the image URL and the name. Defaults :avatar_url and :name.
:avatars:tints, :size, :emptyDisc classes cycled by position for entries with no image, the disc size class (default "size-[26px]"), and the text for an empty list.
:link:path_fnA function of the record that returns the path. Needed for navigation.
:link:externalOpens the link in a new tab. Default false.
:link:class, :label_fnThe link class, and a function that returns the label. Without a label function the column value is the label.

Filter types

Set a filter type as the second argument: filter :status, :select. A filter without a type is a :text filter.

TypeDraws
:textA text input. It matches part of a value without regard to case. A % or _ in the term is that character. The fields option searches several fields at once.
:selectA dropdown. Options come from options.
:booleanA checkbox.
:numberThe built-in table template draws it as a plain text input. Filter.Number.render_input/3 exists, and the template does not call it.
:dateThe built-in table template draws it as a plain text input.
:date_rangeTwo date inputs. Use source when the field has another name.
:relationA select over related records. mode sets how the options load. With options and no resource, it is a searchable list the database does not hold as rows, and its values are strings.

Action types

Set an action type with the type option of a row action. A bulk action accepts only :event, :destroy, :update, :unarchive and :permanent_destroy, and no custom module. :link, :edit, :row_click and :accordion are for row actions only.

TypeDraws or does
:linkA navigation link to path, which is a string used as written or a function of the record. An action named :show or :show_link goes to {route}/{id}, and one named :edit or :edit_link to {route}/{id}/edit, even when a string path is set. Only a function path takes precedence over the name. A :link action with no path is reported when you compile.
:eventA button that fires an event. The default. The payload is %{id: record.id} unless you set payload.
:editA button that sends the record to the form component, which reads it again even when it is already open. A js function runs first, so it can open a modal.
:destroyA delete button with confirmation.
:updateA button that runs an Ash update action, named by action.
:unarchiveA restore button for archived records.
:permanent_destroyA button that permanently deletes an archived record.
:row_clickDeclares a clickable row, by path or event. It draws nothing, and the built-in templates do not call its click handler.
:accordionAn expand and collapse toggle. It draws nothing unless the :expand feature is on. It sends {:expand_row, id} to the parent LiveView, which answers with expanded_html.

The schema also lists :modal as a row action type, but the built-in registry has no entry for it.

Field types

Set a field type as the second argument: field :body, :textarea. A field without a type takes one from its Ash attribute, as the table on Form fields DSL shows.

TypeDraws
:textThe default text input. It strips HTML tags and trims whitespace. The input follows what is typed. Set ui do extra %{dir: "ltr"} end for a value always written left to right.
:passwordA masked input. It trims only the surrounding whitespace.
:textareaA multi-line input. It keeps newlines and markup.
:numberA numeric input. It checks that the value is a number. The field options min and max and ui step are accepted, and the Standard form template does not pass them to the input.
:checkboxA checkbox.
:toggleA boolean switch.
:dateA date picker. It checks for an ISO 8601 date.
:datetimeA date and time picker. It accepts ISO 8601 values, and the minutes-only value a browser sends.
:rangeA range slider from 0 to 100 in steps of 1. The options min, max and ui step do not change it.
:selectA single-select dropdown. An empty choice comes before the options, labeled with ui placeholder when you set one and "Select..." otherwise. A required field or one with a default has no empty choice.
:multi_selectA multi-select dropdown.
:comboboxA text input with a list of suggestions. The reader can type any value. The options load once, when the form starts.
:relationA picker for related records, in the four modes of mode.
:jsonA JSON editor. It decodes JSON strings and checks that the value is valid JSON.
:key_mapA map whose keys you declare, drawn as one control per key.
:key_listA list of maps whose keys you declare, with rows the reader adds and removes.
:nestedAn embedded form for an embedded resource or a constrained map attribute, built from nested_field entities.
:array_of_mapsThe schema accepts it, and the Standard form template draws it as a plain text input. Use :nested or :key_list for repeatable groups.
:string_listA list of text inputs with add and remove buttons, for {:array, :string} attributes. It drops empty strings.
:fileA file input.
:uploadA position for an upload declared in the uploads section. Gervaz marks such a field virtual.
:hiddenA hidden input.