skills/hack23/cia/vaadin-component-design

vaadin-component-design

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

Weekly Installs
5
Repository
hack23/cia
GitHub Stars
213
First Seen
12 days ago
Installed on
opencode6
gemini-cli6
github-copilot6
codex6
amp6
cline6