Vaadin version: 25.0.6
Components: 50+ implemented (all Vaadin 25 UI components)
Lines of code: ~19,700 (core src/), ~58,000 (total with demo + tests)
Test structure: tests/unit/ (2636 unit tests, default pytest) + tests/ui/ (465 Playwright, run explicitly)
Tests: 2636 unit + 465 UI (Playwright)
Last updated: 2026-04-23
- StateTree - Node management, change tracking
- StateNode - Features, attach/put/splice
- Element - Properties, attributes, styles (set/get/remove), events
- Component - Base class with element attachment,
_BufferedStyle, deferred execute_js
- Event hashes - Dynamically computed via
compute_event_hash(config)usingbase64(sha256(BOM + json.encode('utf-16-be'))[:8])for exact Java Flow compatibility - contextRootUrl - Uses
"./"matching Java Flow - Execute commands - document.title, invalid property, serverConnected (always last), component-queued (
queue_execute) - FlowComponentHost - Virtual children renderer for Dialog/Overlay components
- publishedEventHandler - Client-callable methods via Feature 19 (
CLIENT_DELEGATE_HANDLERS) - Server-client state sync -
_pending_server_changeflag absorbs echoes from server-initiated property changes - Overlay auto-add - Dialog, ConfirmDialog auto-attach to UI container on
open(), auto-remove on close (Java'sOverlayAutoAddController) - Client-side validation - Field components use native web component validation (pattern, allowedCharPattern, required);
manualValidationremoved - Grid connector protocol -
gridConnector.initLazy,$connector.set/updateSize/confirm,setHeaderRenderer,setFooterRenderer - Grid header rows -
prepend_header_row(),HeaderRow.join()creates<vaadin-grid-column-group>for spanning headers - Grid column footers -
Column.set_footer_text()renders footer viasetFooterRenderer - Grid Editor -
EditorImpl(buffered/unbuffered),_EditorRendererwith virtual container + JS renderer patching,Column.set_editor_component(), Binder integration - TreeGrid - Hierarchical Grid with expand/collapse, inline treeGridConnector overrides (no bundle rebuild)
- Select connector protocol -
selectConnector.initLazy,requestContentUpdate - ComboBox connector protocol -
comboBoxConnector.initLazy,$connector.set/updateSize/confirm, filtering - MultiSelectComboBox connector - Reuses
comboBoxConnector.initLazy, multi-select withselectedItemsarray - VirtualList connector protocol -
virtualListConnector.initLazy,$connector.set/updateSize, LitRenderer/ComponentRenderer - DatePicker connector protocol -
datepickerConnector.initLazy - TimePicker connector protocol -
timepickerConnector.initLazy - MenuBar connector protocol -
menubarConnector.initLazy,contextMenuConnector.generateItemsTree - ContextMenu connector protocol -
contextMenuConnector.initLazy,$connector.generateItems
- Button - Text, click listener, icon (prefix slot),
set_disable_on_click - Checkbox - Label, checked, indeterminate, value change
- IntegerField - Integer input with min/max/step
- NumberField - Numeric input with min/max/step, ValueChangeMode
- TextArea - Multi-line text input with placeholder, ValueChangeMode
- TextField - Label, value, change event, mSync, clearButtonVisible, placeholder, prefix component slot, errorMessage, pattern, allowedCharPattern, ValueChangeMode
- Span - Text content
- Div - Simple
<div>with text content (extends HtmlContainer) - Header - HTML
<header>container (extends HtmlContainer) - Footer - HTML
<footer>container (extends HtmlContainer) - VerticalLayout - Theme, add/remove/remove_all children, padding/spacing/margin, expand, horizontal component alignment, get_flex_grow, add_and_expand
- HorizontalLayout - Theme, add/remove/remove_all children, margin/spacing, expand, vertical component alignment, get_flex_grow, add_and_expand, set_wrap
- FlexLayout - Pure CSS Flexbox
<div>: flex-direction, flex-wrap, justify-content, align-items/self/content, flex-grow/shrink/basis, order, expand, remove_all - SplitLayout - Horizontal/vertical split with primary/secondary slots, splitter position, orientation
- Dialog - Header title, modal, draggable, resizable, FlowComponentHost renderer, publishedEventHandler close,
get_header()/get_footer()sections, set_top/set_left positioning, resize/dragged listeners - Notification - Position, duration, theme variants, open/close, static show(), body attachment
- PasswordField - Password input with reveal button, ValueChangeMode
- EmailField - Email input with validation, ValueChangeMode
- ProgressBar - Determinate/indeterminate progress
- Select - Dropdown single selection,
selectConnector.initLazyoverlay renderer, empty selection allowed - RadioButtonGroup - Radio button selection
- CheckboxGroup - Multiple checkbox selection
- FormLayout - Responsive steps, colspan, FormItem (label slot), FormRow, auto-responsive, CSS custom properties
- Grid - Columns (path, header, width, flexGrow, autoWidth, resizable, sortable, textAlign), in-memory data push, single/multi selection, sorting, lazy loading/DataProvider, column reordering, LitRenderer, ComponentRenderer, header rows (column groups), column footers, item click listeners, scroll_to_item, remove_column, set_rows_draggable, set_drop_mode, set_empty_state_text, set_details_visible_on_click, programmatic selection push to client, inline editor (buffered/unbuffered, Binder integration, EditorRenderer with virtual containers, open/close/save/cancel events)
- ConfirmDialog - Confirm/cancel/reject actions, header/message/button text, theme, cancelable/rejectable
- ComboBox - Filtered dropdown, data push protocol, item label generator, custom value support, class name generator, prefix component, overlay width
- DatePicker - Date selection with calendar overlay, min/max, connector init, i18n, week numbers, initial position, open/close, opened-change listener
- TimePicker - Time selection with dropdown, step, min/max, connector init, i18n
- Tabs - Tab container with selected index, orientation, selection change events
- Tab - Individual tab with label text
- TabSheet - Tabs + content panels with slot-based association
- MenuBar - Hierarchical menus with connector protocol, submenu support, click listeners, keep-open, disable-on-click, aria-label, separator, submenu remove/remove_all
- Upload - File upload via multipart HTTP POST, receiver callback, file reject/success/error events, max files/size, accepted types, auto-upload, drop zone, i18n
- Icon -
vaadin-icon, auto-prefixvaadin:, color (CSS fill), size - DrawerToggle - Hamburger button for AppLayout drawer, extends Button
- SideNav / SideNavItem - Navigation items with path, prefix icon slot, nested items via children slot, collapsible, label span
- AppLayout - Navbar/drawer/content slots, drawerOpened, primarySection, RouterLayout interface
- Details - Expandable panel, summary (text or Component), opened-changed sync
- Accordion / AccordionPanel - Vertically stacked expandable panels, single-open, opened index sync
- ContextMenu - Right-click/long-press menu, contextMenuConnector, hierarchical items, separators
- DateTimePicker - Combined date+time, datepickerConnector + timepickerConnector, min/max/step, i18n
- Markdown - Renders markdown as HTML,
contentproperty, new in Vaadin 25 - Avatar - Name, abbreviation, image, color index
- AvatarGroup - Item list (JSON property), max items visible
- Scroller - Scrollable container, scroll direction (vertical/horizontal/both/none)
- Card - Multi-slot container (title, subtitle, media, header-prefix/suffix, footer, content). New in v25
- Popover - Overlay anchored to target, FlowComponentHost renderer, position, trigger config, open/close/modal
- MasterDetailLayout - Master/detail slots, size property. New in v25
- MessageInput - Submit event with message text, i18n
- MessageList - Items JSON property (text, time, userName, userAbbr, userImg, userColorIndex), markdown rendering
- ListBox - Items as
vaadin-itemchildren, selected index, value change - MultiSelectListBox - Items as children, selectedValues array, multi-select
- CustomField - Composite field wrapper, children contribute to combined value
- LoginForm - Login event (username/password), forgot-password event, error property, i18n
- LoginOverlay - Login form in overlay, opened/title/description properties, i18n
- MultiSelectComboBox - Multi-select with chips, comboBoxConnector, data provider, filtering, auto-expand, selected-items-on-top, keep-filter
- VirtualList - Scrollable list, virtualListConnector, LitRenderer/ComponentRenderer support
-
setVisible()/isVisible()- Show/hide components -
setEnabled()/isEnabled()- Enable/disable components -
addClassName()/removeClassName()- CSS class management -
setId()/getId()- Component id attribute -
focus()/blur()- Focus management via execute commands -
setHelperText()/getHelperText()- Helper text below fields -
setTooltipText()/getTooltipText()- Tooltips via<vaadin-tooltip>child -
addClickShortcut(Key)- Keyboard shortcuts (keydown->click dispatch) with specific key matching (e.g., only Escape triggers Cancel) -
get_style()- Returns_BufferedStylethat works before and after attach (set/get/remove buffered pre-attach, delegates to realStylepost-attach) -
set_aria_label()/get_aria_label()- ARIA label (HasAriaLabel) -
set_aria_labelled_by()/get_aria_labelled_by()- ARIA labelled-by reference -
add_focus_listener()/add_blur_listener()- Focus/blur events (FocusNotifier/BlurNotifier) -
ValueChangeMode- Controls when text fields sync to server (EAGER/LAZY/TIMEOUT/ON_BLUR/ON_CHANGE). Applied to TextField, TextArea, EmailField, PasswordField, NumberField -
set_i18n(dict)/get_i18n()- Localization via dict-based approach on 7 components (Upload, DatePicker, TimePicker, DateTimePicker, LoginForm, LoginOverlay, MessageInput) -
DragSource- Mixin/factory for HTML5 drag:configure(component),set_draggable,set_drag_data,set_effect_allowed,set_drag_image(custom ghost), drag start/end listeners, deferred attach with_pending_drag_imagecross-component resolution -
DropTarget- Mixin/factory for HTML5 drop:configure(component),set_active,set_drop_effect, drop listener withget_drag_source_component()/get_drag_data(), active drag source tracking via UI
-
components/constants.py- Central enum file with all 34 theme variant enums, layout enums, field enums, GridDropMode, AutoExpandMode - Theme variant enums —
add_theme_variants()/remove_theme_variants()on 34 components (Button, Grid, TextField, Dialog, etc.) -
ColumnTextAlign— START/CENTER/END enum for Grid column text alignment -
Autocomplete— ~50 HTML autocomplete values for TextField, PasswordField, EmailField -
Key— Keyboard constants (ENTER, ESCAPE, TAB, Arrow keys, F1-F12) re-exported fromcore/,components/ - All enums importable from
components/package and fromcomponents/constantsmodule
-
HasReadOnlymixin -set_read_only(),is_read_only()on all 16 field components + Checkbox + ListBox + MultiSelectListBox (18 total) -
HasValidationmixin -set_invalid(),is_invalid(),set_error_message(),get_error_message()on all 14 field components + CustomField -
HasRequiredmixin -set_required_indicator_visible(),is_required_indicator_visible()on all 14 field components + CustomField + Checkbox - Deferred buffering - Values set before attach are buffered in
_pending_propertiesand flushed on attach -
set_value()fires change listeners — All 18 field components fire{"value": ..., "from_client": False}on server-side value changes, matching Java Flow'sAbstractFieldSupport.setValue()behavior
- Binder - Fluent API (
for_field().with_validator().with_converter().bind()),read_bean,write_bean,set_bean(auto two-way sync),is_dirty()dirty tracking with mSync-safe Select handling - Validators -
required,min_length,max_length,pattern,value_range,positive,email - Converters -
string_to_int,string_to_float, customConverter(to_model, to_presentation) - ValidationError - Raised by
write_bean()with error results - Bean-level validators - Cross-field validation via
binder.with_validator(predicate, message) - Field error display - Sets
invalid/errorMessageproperties on Vaadin web components
- HTTP Server (aiohttp) - Sessions, static files
- Request / Response context API -
Request.get_current()/Response.get_current()viacontextvars, read cookies/headers, set response cookies/headers from views and event handlers - UIDL Handler - Init, navigation, events, mSync (two-pass: mSync before events, matching Java Flow)
- Page reload support - State reset on init
- Multiple UIs per session - Each browser tab gets independent StateTree/UidlHandler keyed by
v-uiId, shared CSRF token per session - UI singleton per tab - UI instance persists across navigations (like Java Flow), preserving theme state and other UI-level settings
- Serves index.html from bundle (Vaadin-generated)
- Lumo/Aura theme CSS - Extracted from JARs, served at
/lumo/*and/aura/*, loaded via@StyleSheeton layout -
@StyleSheetdecorator - Load custom CSS via UIDL EAGER dependencies, served from app'sstyles/directory - Dev mode (
--dev) - Auto-reload on Python file changes via watchfiles, socket-in-parent architecture (no EADDRINUSE on reload), file change logging, mtime-based dedup (ignores macOS metadata-only events) - WebSocket Push - Atmosphere protocol,
GET /VAADIN/pushendpoint, push sender coroutine,UI.access()/UI.push()API, reconnect resilience (pending message buffer) - Heartbeat handler (
v-r=heartbeat) — keeps session alive, prevents 403 after idle - Session timeout / cleanup (30min idle, background sweep every 60s)
- Error handling — Per-RPC try/except, error Notification to user, navigation error feedback, push sender broad catch
- Missing bundle file logging —
[404] /VAADIN/{path}printed to server console for easier debugging
- CSRF token validation — constant-time comparison (
hmac.compare_digest) matching Java Flow'sMessageDigest.isEqual() - ClientId validation (duplicate detection, replays last response)
- SyncId validation (out-of-sync detection)
- Resynchronize flag support
- Return channels — used by Grid and VirtualList ComponentRenderer
- Multi-UI session routing —
v-uiIdquery param routes UIDL/push to correct UI; invalid UI returns session-expired - RPC node validation — All RPC handlers check: node exists, node is attached, component is enabled (matching Java Flow's
AbstractRpcInvocationHandler) - mSync property whitelist — Per-component
_v_sync_propertiesfrozenset, default deny. Forbidden properties (textContent,innerHTML, etc.) always blocked (matching Java Flow'sElementPropertyMap.allowUpdateFromClient()) - DisabledUpdateMode —
ALWAYSvsONLY_WHEN_ENABLEDper property/method. Dialogopened, LoginFormdisabledsync even when disabled (matching Java Flow'sDisabledUpdateModeenum) - publishedEventHandler security — Method registration check (Feature 19), argument count validation, UI attachment check, disabled bypass (matching Java Flow's
PublishedServerEventHandlerRpcHandler) - XSS response wrapping —
for(;;);[{...}]prefix on UIDL responses - Dialog close race condition fix —
_handle_opened_changedno longer calls_auto_remove();handle_client_closeis the sole client close handler with_close_pendingflag for two-pass RPC safety
- Lumo/Aura theme support —
@StyleSheet("lumo/lumo.css")or@StyleSheet("aura/aura.css")on layout - Runtime theme switching —
UI.set_theme(theme, variant)/UI.get_theme()/UI.get_theme_variant()— full get/set API - Theme-agnostic CSS — Demo styles use
--vaadin-*base properties with--lumo-*fallbacks -
@ColorSchemedecorator — Set initial color scheme on@AppShell(dark/light/system), modifies<html>attributes at bootstrap (no flash) -
UI.set_color_scheme(value)— Runtime color scheme switching (dark/light/system/normal)
- Init response - appConfig, pushScript, CSRF, constants (Java-compatible hashes)
- UIDL response - syncId, changes, execute
- Push response -
meta.async, Atmosphere length-prefix format - RPC: event - click, change, input, blur, ui-navigate, keydown
- RPC: mSync - Property sync from client
- RPC: publishedEventHandler - Generic dispatch to any component method (Dialog close, Grid select/deselect)
- UIDL compatibility verified - Matches Java Flow exactly:
- Same constants keys (Base64 hashes)
- Same execute commands format
- Same number of changes (27 for HelloWorldView)
- Same change types (5 attach, 17 put, 1 clear, 4 splice)
-
@Routedecorator - Path registration - Multiple views - HelloWorldView, AboutView
- Page title - Explicit or auto-generated from class name
- Route parameters (
/users/:id) - Required and optional (:param?) syntax - Wildcard route parameters (
:path*) - Match 0+ remaining segments,RouteParameters.get_wildcard() - Mid-position optional params (
user/:id?/contact) - Optional segments anywhere in path - Query parameters -
QueryParametersclass, parsed from URL viaBeforeEnterEvent.location.query_parameters -
BeforeEnterEvent- Full navigation context (location, route params, query params), dict-compatible for backward compat - Navigation data classes -
QueryParameters,RouteParameters,Location,BeforeEnterEvent - Re-navigation - Navigate between views without page reload
- Navigation guards -
before_leave(),before_enter(event),after_navigation() - RouterLink component -
<a>tag withrouter-linkattribute for client-side navigation -
@PageTitledecorator - Alternative topage_titleparam, supportsget_page_title()for dynamic titles -
@Route(layout=...)- RouterLayout support, layout chain in navigation, layout reuse on same-layout routes - View reuse on same-route-pattern - Navigating within same
@Routepattern reuses view instance (callsbefore_enterwith new params, preserves DOM for animations) -
@Menu(title, order, icon)- Decorator for automatic menu generation -
get_menu_entries()- Collects @Menu routes, filters required params, sorts by order/path -
@AppShell- Global app configuration class (single place for @Push, @StyleSheet) -
@Push- Opt-in WebSocket push (conditional pushScript, push nodes in init) -
@ColorScheme- Initial color scheme (dark/light/system) applied to<html>at bootstrap - AppShell
@StyleSheet- Stylesheets loaded in init response (before any navigation) - Route not found - Shows "Could not navigate to '...'" view for unregistered routes
- Dev mode route list - In
--devmode, not-found view shows clickable RouterLinks to all registered routes
For the detailed per-component API inventory (every method, [x]/[ ]), see
STATUS.API.md.API coverage: ~490 methods implemented, ~30 missing (~94% complete).
| Feature | Priority | Description |
|---|---|---|
@PWA annotation |
Medium | Activate sw.js from bundle, serve manifest.json with configurable app name/icons |
Security (--secure) |
Medium | Login screen from local config, restrict interfaces (localhost vs 0.0.0.0), HTTPS/TLS. Note: RPC-level security (CSRF, property whitelist, node validation) is already implemented |
| Inert state (modal dialogs) | Medium | Block RPCs on elements outside a modal dialog when one is open (Java Flow's isInert() check) |
| Session expired dialog | Low | Show "Session Expired" overlay instead of silent page reload (set sessExpMsg.caption in init) |
| Session persistence | Low | Serialize sessions to disk/Redis to survive server restarts. Challenge: Python callbacks are not serializable |
| Form state preservation | Low | Save form values in localStorage before session timeout, restore after reload |
| Rate limiting | Low | Per-session RPC rate limiting to prevent DoS. Typically handled by reverse proxy (nginx) |
get_editor(), EditorImpl (buffered/unbuffered), Column.set_editor_component(), _EditorRenderer with virtual containers, Binder integration, open/close/save/cancel events |
||
HasErrorParameter error views |
Medium | Navigate to error view on unhandled exceptions (Java's DefaultErrorHandler + ErrorHandlerUtil). Currently shows Notification instead. |
| Grid Drag/Drop listeners | Low | Drag start/end/drop event listeners (rows draggable & drop mode already implemented) |
| Grid item details renderer | Low | Expandable row details via set_item_details_renderer (set_details_visible_on_click already implemented) |
| Specialized renderers | Low | NumberRenderer, LocalDateRenderer, LocalDateTimeRenderer, NativeButtonRenderer, IconRenderer |
| ConfigurableFilterDataProvider | Low | Advanced filtering for DataProvider |
AppShell @Meta |
Low | Inject <meta> tags into index.html (Java's @Meta(name, content)) |
AppShell @Viewport |
Low | Set viewport meta tag (Java's @Viewport("width=device-width, initial-scale=1")) |
AppShell @BodySize |
Low | Configure body height/width CSS (Java's @BodySize(height, width)) |
AppShell @Inline |
Low | Inline static resources (JS/CSS/HTML) into index.html (Java's @Inline("file.js")) |
AppShell @PageTitle |
Low | Set default page title at AppShell level (currently only per-route via @Route(page_title=)) |
AppShell configurePage() |
Low | Programmatic page config method (Java's AppShellConfigurator.configurePage(AppShellSettings)) |
| Component | Missing Methods | Priority |
|---|---|---|
| Grid | add_component_column, set_item_details_renderer, Drag/Drop listeners |
Medium |
| ComboBox | set_renderer |
Low |
| MultiSelectComboBox | set_renderer |
Low |
| MenuBar | add_item(Component), close |
Low |
| DatePicker | set_locale |
Low |
| FlexLayout | replace/add_component_at_index |
Low |
| Select | set_renderer, set_item_enabled_provider |
Low |
| CheckboxGroup/RadioButtonGroup | set_item_enabled_provider, set_renderer |
Low |
| ListBox/MultiSelectListBox | set_renderer, add_components (dividers) |
Low |
| Button | click (server-side) |
Low |
| Other | Various minor methods across Tabs, Details, ContextMenu, Upload, LoginOverlay, Popover, etc. | Low |
| Category | Coverage | Details |
|---|---|---|
| Unit tests | 2602 passing | Good coverage of all 50+ components + core + data layer + server utilities. Located in tests/unit/ |
| UI tests | 456 passed | All 33 test views (in tests/views/) with shared SideNav layout and single browser session. UI tests in tests/ui/. |
All 12 implementation phases are complete:
Core + basic components✓Component features (setVisible, setEnabled, addClassName)✓Routing (@Route, multiple views, parameters)✓Feedback (Dialog, Notification)✓Lumo/Aura theme loading✓Grid (basic)✓Grid (advanced: lazy loading, sorting, multi-select, renderers)✓AppLayout & Prerequisites (Icon, DrawerToggle, SideNav, RouterLayout)✓Menu System + High-Value Components (@Menu, Details, Accordion, ContextMenu, DateTimePicker, Markdown)✓Visual & Layout Components (Avatar, Card, Scroller, Popover, MasterDetailLayout)✓Data & Specialized Components (ListBox, MultiSelectComboBox, VirtualList, MessageInput/List, Login, CustomField)✓WebSocket Push (Atmosphere protocol, UI.access, push sender)✓
Plus: @ClientCallable, @ColorScheme, runtime theme switching, field mixins, Binder, pyxflow --bundle.
- PyPI-ready wheel —
pip install pyxflow - Bundle inside package —
src/pyxflow/bundle/ships in wheel (1.5 MB compressed) - CLI entry point —
pyxflow [app_module] [--dev] [--debug] [--port N] -
pyxflow --bundle— Auto-generate bundle from_v_fqcncomponent registry -
pyxflow <app> --bundle— User projects can generate their own bundle - Bundle discovery priority — app-dir bundle > package-internal > cwd fallback
- Apache 2.0 LICENSE file