# Vaadin Component Design

> Design Vaadin UI components with proper lifecycle, data binding, and responsive layouts for CIA platform Use when this capability is needed.

- Skill: `tomevault-io/vaadin-component-design` (Agent Skill, multi-file: 2 files)
- Install (CLI): `npx skillmds@latest add tomevault-io/vaadin-component-design`
- Raw SKILL.md: https://api.skillmd.com/api/skills/tomevault-io/vaadin-component-design/raw
- Safety review: pending (external: skill-scanner PASS, skillspector PASS)
- Works with: Claude Code, Claude.ai, OpenAI Codex
- Category: Web & Frontend
- Author: tomevault-io (https://skillmd.com/u/tomevault-io)
- Updated: 2026-09-17
- Page: https://skillmd.com/skills/tomevault-io/vaadin-component-design

---


# 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
```java
@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
```java
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
- Vaadin: https://vaadin.com/docs
- citizen-intelligence-agency/src/main/java/com/hack23/cia/web/

---
> Converted and distributed by [TomeVault](https://tomevault.io/claim/hack23) — claim your Tome and manage your conversions.
<!-- tomevault:4.0:skill_md:2026-04-11 -->

