Skip to content

ZEROZ4J UI COMPONENTS

This document outlines the UI component library in the zerozstack-ui-components module. It covers how layouts and views work, the optional HTML layout system, data binding, and a comprehensive list of all components categorized by their purpose.

Building Views with Layouts

In zeroz4j, views are built programmatically using Layout components. Layouts act as containers that implement the HasComponents interface, allowing you to nest components hierarchically. By adding child components to these layouts, developers can compose complex UIs purely in Java without writing custom CSS or HTML. The layout classes internally manage standard layout paradigms like Flexbox and CSS Grid.

Common layouts include VerticalLayout (stacking children vertically), HorizontalLayout (stacking horizontally), and FormLayout for structured input forms.

Code Example: Basic Layouts

Here is a simple example showing how to create layouts and attach components to them:

// Create a main vertical layout
VerticalLayout mainLayout = new VerticalLayout();

// Create a title and add it to the main layout
CardTitle title = new CardTitle("User Registration");
mainLayout.add(title);

// Create a form layout for inputs
FormLayout formLayout = new FormLayout();
TextField nameField = new TextField("Name");
TextField emailField = new TextField("Email");

// Add components to the form layout
formLayout.add(nameField, emailField);

// Create a horizontal layout for actions
HorizontalLayout actionsLayout = new HorizontalLayout();
Button submitButton = new Button("Submit");
Button cancelButton = new Button("Cancel");

// Add buttons to the horizontal layout
actionsLayout.add(submitButton, cancelButton);

// Attach the nested layouts to the main layout
mainLayout.add(formLayout, actionsLayout);

Optional HTML Layout Feature

While programmatic layouts are powerful, there are times when declaring a layout in HTML is more convenient. ZeroZ Stack provides an optional HTML layout feature via the FlavourWrapper component, leveraging TeaVM Flavour templates. By passing a Flavour template object to the FlavourWrapper, the framework binds the template to a host div element (Templates.bind(flavourTemplateObj, getElement())). This allows developers to seamlessly mix declarative HTML templates for complex visual structures with programmatic component logic, without sacrificing type safety or data binding.

Data Binding to POJOs

Input components (those implementing HasValue) can be directly bound to data POJOs using the Binder<BEAN> class. The Binder facilitates a two-way data flow between your UI components and your Java model.

To use the Binder: 1. Instantiate a Binder<MyPojo>. 2. Bind components to specific fields using the builder pattern, providing a getter and setter:

binder.forField(myTextField)
      .withValidator(...)
      .asRequired("This field is required")
      .bind(MyPojo::getName, MyPojo::setName);
3. Load a bean into the UI with binder.setBean(myBean). 4. The Binder automatically reads from the bean into the fields. Upon a value change in the UI, it validates the input. If validation passes, it writes changes back from the fields into the bean. It also handles rendering error states directly onto the components (e.g., adding input-error classes).

DOM Events and Server Communication

You can easily attach DOM event listeners to components to handle user interaction. In zeroz4j (which compiles to WebAssembly via TeaVM), network calls to the server (via RPC stubs) are synchronous and blocking from the developer's perspective.

To prevent these blocking calls from freezing the browser's main UI thread, zeroz4j automatically wraps standard component event listeners (like button clicks or text input) in a TeaVM virtual thread. This allows you to write simple, sequential code: the thread is suspended during the network call and automatically resumed when the response arrives, all without any callbacks, CompletableFuture, or manual new Thread() boilerplate!

Code Example: Button Click to Server Call

Here is an example showing how to attach a click listener to a button and make a server call. Notice how the RMI call looks completely synchronous!

Button saveButton = new Button("Save Profile");

saveButton.addClickListener(event -> {
    // 1. DOM Event listener triggered on click. 
    // This is already running inside a TeaVM virtual thread!
    saveButton.setEnabled(false);
    saveButton.setText("Saving...");

    try {
        // 2. Call server method synchronously via an RPC stub.
        // The virtual thread will safely suspend here without freezing the UI!
        boolean success = userService.saveUserProfile(profile);

        // 3. Resumes execution here once the server responds
        if (success) {
            saveButton.setText("Saved Successfully!");
        } else {
            saveButton.setText("Save Failed");
        }

    } catch (Exception e) {
        // Handle network or server errors
        saveButton.setText("Error Occurred");
    } finally {
        saveButton.setEnabled(true);
    }
});

When building your own custom components that hook into low-level DOM events via element.addEventListener, be sure to use the addDomEventListener() helper or Component.threaded() from the base Component class to ensure your listeners execute in a safe, suspendable context.


Component Reference

The framework provides a rich set of 87 UI components, broken down into the following functional categories:

Layout Components

Used for structuring the application and organizing other components. - Div: A generic block-level container. - Span: A generic inline container. - VerticalLayout: Arranges child components in a vertical column. - HorizontalLayout: Arranges child components in a horizontal row. - FlexLayout: A generic flexbox container with customizable flex properties. - GridLayout: A CSS grid container for two-dimensional layouts. - FormLayout: A responsive layout optimized for aligning form fields and labels. - Scroller: A container that provides scrollbars when its content exceeds its bounds. - FlavourWrapper: A host container that binds TeaVM Flavour HTML templates. - FlexComponent: Base layout class for flexbox-based containers.

Input & Data-Backed Components

Components that accept user input and can be bound to data models (implementing HasValue). - TextField: Standard single-line text input. - TextArea: Multi-line text input area. - Checkbox: A standard boolean toggle for individual options. - RadioButtonGroup: A set of mutually exclusive radio options. - Select: A dropdown list for selecting a single item from a collection. - Range: A slider for selecting numeric values within a defined range. - Rating: An interactive star-based rating selector. - Toggle: A switch component, often used as an alternative to a checkbox. - FileInput: A control for selecting files from the user's system.

Buttons & Navigation

Components that trigger actions or navigate between views. - Button: A standard clickable button. - BottomNavigation: A mobile-friendly navigation bar fixed to the bottom of the screen. - Breadcrumbs: Displays the current navigational hierarchy and path. - Dropdown: A contextual overlay menu triggered by an anchor element. - Menu: A list of navigational or action items, often placed in sidebars or dropdowns. - Navbar: A standard top navigation header. - Pagination: Controls for navigating through paginated datasets. - Swap: A component that toggles between two different states or icons on click. - Tab: Represents individual selectable sections in a tabbed interface. - Link: A standard hyperlink for navigation. - Steps: A wizard-like component showing progression through a sequence of steps.

Data Display & Content

Components used to present data, alerts, and content to the user. - Accordion: An expandable/collapsible list of panels for dense content. - Alert: A distinct message banner to convey important information or warnings. - Avatar: Represents a user or entity with an image or initials. - Badge: A small label or indicator, often used for counts or status. - Card: A bounded container for grouping related content and actions. - CardTitle / CardActions: Sub-components for structuring content within a Card. - Carousel: A slideshow component for cycling through elements like images. - ChatBubble: Displays a single message within a conversational UI. - CodeBlock: A styled container for displaying formatted source code. - Collapse: A generic expand/collapse container. - ContextMenu: A popup menu triggered by a right-click or long-press. - Countdown: Displays a timer counting down to a specific event. - Dialog: A modal overlay that interrupts the user workflow for critical interaction. - Diff / DiffView: Components for displaying file or text differences side-by-side. - Divider: A visual separator between content sections. - Drawer: A sliding side panel for navigation or secondary content. - EmptyState: A placeholder view shown when there is no data to display. - Footer: A standard page footer element. - Hero: A large, prominent banner often used at the top of landing pages. - Icon: A scalable vector icon component. - Indicator: A visual marker, often attached to other elements (like badges on icons). - Join: A layout utility for seamlessly connecting grouped elements. - Js: A component wrapper for embedding custom JavaScript execution. - Kbd: Represents keyboard input visually (e.g., styling for Ctrl+C). - KeyedList: An optimized list component that efficiently manages DOM nodes based on keys. - KpiTile: A dashboard tile for displaying Key Performance Indicators. - LaneTimeline: A timeline view segmented into multiple lanes. - Loading: A spinner or indicator signifying a background process is running. - MarkdownView: Renders Markdown text safely into HTML. - Mask: A component for shaping or clipping elements (e.g., circular images). - PhoneMockup / BrowserMockup / WindowMockup / CodeMockup: Decorative containers that frame content within stylized device or window borders. - Progress / RadialProgress: Linear and circular progress bars to indicate completion percentage. - PropertyGrid: A structured grid for displaying key-value pairs or object properties. - Resizer: A drag handle component for resizable containers. - Skeleton: A placeholder skeleton screen shown while data is loading. - Sparkline: A small, inline chart used to show data trends over time. - SplitPane: A container with two resizable panels separated by a divider. - Stack: A layout utility for overlapping components. - Stat: A component optimized for displaying a prominent statistic or metric. - StatusDot: A small colored indicator representing a status (e.g., online/offline). - StreamingText: A component for displaying text that streams in dynamically (e.g., LLM responses). - SvgCanvas: A container for drawing and displaying SVG graphics. - Table: A structured grid for displaying tabular data. - ThemeController: A component for managing and switching application themes (e.g., light/dark mode). - Timeline: A linear representation of events ordered by time. - Toast: A brief, auto-expiring notification message overlaid on the screen. - TokenMeter: A specialized visualization component (e.g., for showing API token usage). - Tooltip: A small informational popup shown when hovering over an element. - VirtualScroller: An optimized list container that only renders visible items for high performance with large datasets.

Base Classes & Interfaces

Core building blocks that other components extend or implement. - Component: The base class for all UI elements, wrapping a DOM node. - AbstractField: The foundational class for input components. - HasComponents: Interface for containers that can hold child components. - HasValue: Interface for components that handle data binding. - HasSize / HasStyle / HasText / HasEnabled: Mixin interfaces for standard component properties. - DomListenerRegistration / EventListener / ComponentEvent / ClickEvent: Infrastructure for DOM event handling and custom component events. - Focusable: Interface for components that can receive keyboard focus.