Hack23

vaadin-component-design

This skill provides guidance for designing Vaadin UI components with proper lifecycle management, data binding, and responsive layouts for the CIA platform. It helps developers create maintainable forms, grids, and views by following established patterns for component configuration, event handling, and data integration. Use this skill when building new UI views, designing data-driven forms, or implementing interactive components that require structured data presentation and user input handling within a Vaadin-based application.

Hack23 242 56 Updated 8mo ago
GitHub

Install

npx skillscat add hack23/cia/vaadin-component-design

Install via the SkillsCat registry.

About this skill

This skill provides guidance for designing Vaadin UI components with proper lifecycle management, data binding, and responsive layouts for the CIA platform. It helps developers create maintainable forms, grids, and views by following established patterns for component configuration, event handling, and data integration. Use this skill when building new UI views, designing data-driven forms, or implementing interactive components that require structured data presentation and user input handling within a Vaadin-based application.

SKILL.md

Vaadin Component Design Skill

Purpose

Create maintainable, responsive Vaadin UI components with proper lifecycle and data binding.

When to Use

  • ✅ Creating new UI views
  • ✅ Designing forms and data grids
  • ✅ Implementing user interactions
  • ✅ Building responsive layouts

Component Patterns

@SpringView(name = PoliticianView.NAME)
@Secured({"ROLE_USER", "ROLE_ADMIN"})
public class PoliticianView extends VerticalLayout implements View {
    public static final String NAME = "politicians";
    
    private final PoliticianService service;
    private final Grid<Politician> grid = new Grid<>(Politician.class);
    
    public PoliticianView(PoliticianService service) {
        this.service = service;
        setSizeFull();
        configureGrid();
        add(createToolbar(), grid);
        updateList();
    }
    
    private void configureGrid() {
        grid.setSizeFull();
        grid.setColumns("firstName", "lastName", "party", "district");
        grid.addColumn(p -> p.getVotingRecords().size())
            .setCaption("Total Votes");
        grid.getColumns().forEach(col -> col.setExpandRatio(1));
    }
    
    private Component createToolbar() {
        TextField searchField = new TextField();
        searchField.setPlaceholder("Search...");
        searchField.addValueChangeListener(e -> updateList());
        
        Button addButton = new Button("Add Politician");
        addButton.addClickListener(e -> addPolitician());
        
        return new HorizontalLayout(searchField, addButton);
    }
}

Data Binding

public class PoliticianForm extends FormLayout {
    TextField firstName = new TextField("First Name");
    TextField lastName = new TextField("Last Name");
    ComboBox<Party> party = new ComboBox<>("Party");
    
    Binder<Politician> binder = new Binder<>(Politician.class);
    
    public PoliticianForm() {
        binder.forField(firstName)
            .asRequired("First name is required")
            .withValidator(name -> name.length() >= 2, "Name too short")
            .bind(Politician::getFirstName, Politician::setFirstName);
        
        add(firstName, lastName, party);
    }
}

References