Keyboard shortcuts

Press ← or → to navigate between chapters

Press S or / to search in the book

Press ? to show this help

Press Esc to hide this help

The catalogue

Every widget in Goldberry is a Java record, a KDL node and a CSS type, and this part documents each one under the name it has in markup.

By the end of this page you know what every widget shares, how a name in markup finds the thing it refers to, and which chapter holds the widget you are looking for. The chapters that follow show each widget three ways: a markup sample, the Java that builds the same tree, and the stylesheet rules that reach it.

Three ways to say one widget

A button is a Button record in Java, a button node in KDL and a button type in CSS. A test builds the same widget both ways and asserts the two values are equal, so the forms cannot drift (ADR-0059).

column {
    text "Delete this file?"
    row {
        spacer
        button press="dismiss" "Cancel"
        button class="danger" press="delete" "Delete"
    }
}
new Column(
        new Text("Delete this file?"),
        new Row(
                new Spacer(),
                new Button("Cancel", this::dismiss),
                new Button("Delete", this::delete).styled("danger")
        )
);

Variants are classes. danger is class="danger" in markup, .styled("danger") in Java and button.danger in a stylesheet, because a class is the one spelling all three can use. styled, tooltip, contextMenu and withAttributes are on Attributed, which every widget in the catalogue implements. Nothing visual lives in a record. The metrics are in controls.css and the colours are the theme’s tokens, so a theme restyles a control whose rule never names one.

What every widget carries

Every widget holds an Attributes value. The inflater reads five properties off any node, and the same five have Java withers on Attributes.NONE.

AttributeTypeDefaultWhat it does
idstringnoneThe node’s id for #id rules. It doubles as the reconciler’s key, so a node with an id keeps its state and focus across a rebuild that reorders it
classstringnoneSpace-separated classes, for .name rules and variants
tooltipstringnoneText shown on hover, on any widget (ADR-0105)
context-menustringnoneThe name of the menu a right-click opens, resolved by the application (ADR-0108)
namestringnoneThe accessible name, which wins over any name the widget derives (ADR-0260)
var attributes = Attributes.NONE.id("save").classes("primary").tooltip("Ctrl+S");
new Button("Save", this::save).withAttributes(attributes);

In Java a key may differ from the id. Attributes.NONE.key(row) keys a list item by its model row. The two hover hooks, onPointerEnter and onPointerExit, are Java only, because a Runnable is not a KDL value (ADR-0327).

Controls that can be disabled read disabled=#true. A disabled container disables every descendant for input: nothing inside it is clicked, focused or hovered (ADR-0077). The cascade sees it too, so a rule can style a disabled subtree, while the fade stays on the node that declared it (ADR-0379).

What a name resolves against

Markup names things and cannot build them. Each kind of name has a registry, and Widgets.inflater(named, icons, models) assembles all of them from a model’s annotations.

AttributeRegistryWhat the name is
press=, change=, link=, task=ActionRegistryA method. press names an action with no argument, the others one that is handed a value
bind=BindingRegistryA value to follow, read-only. The widget subscribes and rebuilds when it changes (ADR-0062)
icon=IconsAn icon the application built and will close (ADR-0043)
controller=, validator=, player=, renderer=, images=NamedAn object that neither changes nor needs closing (ADR-0170)

A registry is strict by default, so press="delte" fails at inflation rather than producing a button that does nothing. Widgets.inflater() with no arguments binds nothing and complains about nothing, which is what a preview wants. A value is named once, in its @Bind annotation, and a widget built in Java follows it by the same path (ADR-0129). Data flows down through bind= and events flow up through actions. A widget is handed an Observable with no set on it, so a control built from markup cannot write the model (ADR-0063).

Parts are not widgets

A checkbox’s glyph, a chart’s plot and a legend’s swatch are parts. Each is a CSS type a stylesheet can reach, check-indicator or chart-legend-swatch, and none is a node a document can create (ADR-0065). A part outside its widget means nothing, so the inflater does not know its name. Each chapter’s Styling section lists the parts a widget has.

The chapters

Every markup name

The 79 names the inflater knows, and where each is documented. The layout widgets have a part of their own.

NameChapter
actionOverlays
affixLayout
area-chartCharts
audio-playerAudio and video
badgeButtons, badges and chips
bar-chartCharts
breadcrumbsNavigation
buttonButtons, badges and chips
canvasCanvas, images and QR codes
canvas3dThe GPU canvas
cardPanels
carouselPanels
checkboxChoices
chipButtons, badges and chips
code-inputFields and forms
collapsePanels
color-pickerFields and forms
columnLayout
crumbNavigation
date-pickerFields and forms
dialogOverlays
donut-chartCharts
entryPanels
fieldFields and forms
formFields and forms
group-boxPanels
html-viewMarkdown, HTML and the web
hudOverlays
imageCanvas, images and QR codes
itemMenus and the tray
knobValues and progress
line-chartCharts
linkText and links
listCollections
markdown-viewMarkdown, HTML and the web
markerPanels
masonryLayout
media-controlsAudio and video
media-playerAudio and video
menuMenus and the tray
menubarMenus and the tray
messageOverlays
optionChoices
pageNavigation
panelPanels
pointCharts
popoverOverlays
progressValues and progress
qr-codeCanvas, images and QR codes
radioChoices
radio-groupChoices
rowLayout
scrollLayout
segmentedChoices
selectChoices
separatorMenus and the tray
seriesCharts
skeletonPanels
sliderValues and progress
spacerLayout
sparklineCharts
spinnerValues and progress
split-paneLayout
stackLayout
statisticPanels
stepNavigation
stepsNavigation
tabPanels
tableCollections
tabsPanels
textText and links
text-areaFields and forms
text-inputFields and forms
time-pickerFields and forms
timelinePanels
toggleChoices
treeCollections
video-viewAudio and video
wizardNavigation

Java only

Four widgets have no markup name, because each holds something a document cannot describe: a queue, a sequence of steps, a platform handle or a page.