Comprehensive collection of business-ready web components for modern web applications
Layout components provide the structural foundation for organizing and arranging content in Vaadin applications. These components handle responsive behavior, flexible layouts, and application structure.
Main application layout component providing navigation drawer, header, and content areas with responsive behavior.
/**
* Main application layout with drawer navigation and header
* Provides responsive navigation patterns for web applications
*/
interface AppLayout extends HTMLElement {
/** Controls drawer visibility (open/closed) */
drawerOpened: boolean;
/** Overlay mode for mobile responsive behavior */
overlay: boolean;
/** Primary section placement: navbar or drawer */
primarySection: 'navbar' | 'drawer';
/** Open the navigation drawer */
openDrawer(): void;
/** Close the navigation drawer */
closeDrawer(): void;
}
/**
* Toggle button for opening/closing drawer navigation
* Usually placed in the application header
*/
interface DrawerToggle extends HTMLElement {
/** Accessibility label for the toggle button */
ariaLabel: string;
}Usage Examples:
import '@vaadin/app-layout';
import '@vaadin/app-layout/vaadin-drawer-toggle';
// Create app layout structure
const layout = document.createElement('vaadin-app-layout');
// Add navigation drawer toggle
const toggle = document.createElement('vaadin-drawer-toggle');
toggle.slot = 'navbar touch-optimized';
layout.appendChild(toggle);
// Add drawer content
const nav = document.createElement('nav');
nav.slot = 'drawer';
nav.innerHTML = `
<ul>
<li><a href="/dashboard">Dashboard</a></li>
<li><a href="/users">Users</a></li>
</ul>
`;
layout.appendChild(nav);
// Add main content
const main = document.createElement('main');
main.slot = 'content';
main.innerHTML = '<h1>Welcome to Dashboard</h1>';
layout.appendChild(main);
// Control drawer programmatically
layout.drawerOpened = true; // Open drawer
layout.closeDrawer(); // Close drawerFlexbox-based horizontal layout component for arranging items in a row.
/**
* Horizontal flexbox layout container
* Arranges children in a horizontal row with flex properties
*/
interface HorizontalLayout extends HTMLElement {
/** Theme variant for spacing and alignment */
theme: string;
}Usage Examples:
import '@vaadin/horizontal-layout';
const horizontalLayout = document.createElement('vaadin-horizontal-layout');
horizontalLayout.theme = 'spacing padding';
// Add items to horizontal layout
const button1 = document.createElement('vaadin-button');
button1.textContent = 'First';
const button2 = document.createElement('vaadin-button');
button2.textContent = 'Second';
horizontalLayout.appendChild(button1);
horizontalLayout.appendChild(button2);Flexbox-based vertical layout component for arranging items in a column.
/**
* Vertical flexbox layout container
* Arranges children in a vertical column with flex properties
*/
interface VerticalLayout extends HTMLElement {
/** Theme variant for spacing and alignment */
theme: string;
}Responsive form layout that automatically adjusts field arrangement based on viewport size.
/**
* Responsive form layout with configurable breakpoints
* Automatically arranges form fields based on screen size
*/
interface FormLayout extends HTMLElement {
/** Array of responsive step configurations */
responsiveSteps: FormLayoutResponsiveStep[];
}
/**
* Individual form item container within FormLayout
* Provides consistent spacing and alignment for form fields
*/
interface FormItem extends HTMLElement {
/** Number of columns this item should span */
colspan: number;
}
/**
* Configuration for responsive form layout behavior
*/
interface FormLayoutResponsiveStep {
/** Minimum viewport width for this step */
minWidth?: string;
/** Number of columns at this breakpoint */
columns: number;
/** Label positioning: beside fields or above */
labelsPosition?: 'aside' | 'top';
}Usage Examples:
import '@vaadin/form-layout';
const formLayout = document.createElement('vaadin-form-layout');
// Configure responsive steps
formLayout.responsiveSteps = [
{ columns: 1 }, // Mobile: single column
{ minWidth: '500px', columns: 2 }, // Tablet: two columns
{ minWidth: '800px', columns: 3, labelsPosition: 'top' } // Desktop: three columns
];
// Add form fields
const firstName = document.createElement('vaadin-text-field');
firstName.label = 'First Name';
const lastName = document.createElement('vaadin-text-field');
lastName.label = 'Last Name';
const email = document.createElement('vaadin-email-field');
email.label = 'Email';
formLayout.appendChild(firstName);
formLayout.appendChild(lastName);
formLayout.appendChild(email);Resizable split layout for dividing content areas with user-adjustable splitter.
/**
* Resizable split layout component
* Divides content into two panes with adjustable splitter
*/
interface SplitLayout extends HTMLElement {
/** Split orientation: horizontal or vertical */
orientation: 'horizontal' | 'vertical';
/** Splitter position as percentage (0-100) */
splitterPosition: number;
/** Set splitter position programmatically */
setSplitterPosition(position: number, resize?: boolean): void;
}Usage Examples:
import '@vaadin/split-layout';
const splitLayout = document.createElement('vaadin-split-layout');
splitLayout.orientation = 'horizontal';
splitLayout.splitterPosition = 30; // 30% for first pane
// Add content to split panes
const leftPanel = document.createElement('div');
leftPanel.innerHTML = '<h3>Navigation</h3><ul><li>Item 1</li></ul>';
const rightPanel = document.createElement('div');
rightPanel.innerHTML = '<h3>Content</h3><p>Main content area</p>';
splitLayout.appendChild(leftPanel);
splitLayout.appendChild(rightPanel);
// Listen for splitter changes
splitLayout.addEventListener('splitter-dragend', (e) => {
console.log('New position:', splitLayout.splitterPosition);
});Custom scrollable container with enhanced scroll behavior and virtual scrolling support.
/**
* Enhanced scrollable container
* Provides custom scrolling behavior and virtual scrolling
*/
interface Scroller extends HTMLElement {
/** Scroll direction restriction */
scrollDirection: 'vertical' | 'horizontal' | 'both';
/** Scroll to specific element or index */
scrollToIndex(index: number): void;
/** Scroll to specific element */
scrollToElement(element: Element): void;
}// Complete app layout structure
const createAppShell = () => {
const layout = document.createElement('vaadin-app-layout');
// Header with navigation toggle
const header = document.createElement('header');
header.slot = 'navbar';
const toggle = document.createElement('vaadin-drawer-toggle');
toggle.setAttribute('aria-label', 'Menu toggle');
header.appendChild(toggle);
const title = document.createElement('h1');
title.textContent = 'My Application';
header.appendChild(title);
layout.appendChild(header);
// Navigation drawer
const nav = document.createElement('nav');
nav.slot = 'drawer';
// Add navigation items...
layout.appendChild(nav);
return layout;
};// Form with responsive layout and validation
const createResponsiveForm = () => {
const formLayout = document.createElement('vaadin-form-layout');
formLayout.responsiveSteps = [
{ columns: 1 },
{ minWidth: '600px', columns: 2 },
{ minWidth: '900px', columns: 3 }
];
// Add form fields with proper validation
const fields = [
{ type: 'text-field', label: 'First Name', required: true },
{ type: 'text-field', label: 'Last Name', required: true },
{ type: 'email-field', label: 'Email', required: true },
{ type: 'tel-field', label: 'Phone' },
{ type: 'date-picker', label: 'Date of Birth' }
];
fields.forEach(fieldConfig => {
const field = document.createElement(`vaadin-${fieldConfig.type}`);
field.label = fieldConfig.label;
if (fieldConfig.required) field.required = true;
formLayout.appendChild(field);
});
return formLayout;
};Install with Tessl CLI
npx tessl i tessl/npm-vaadin--vaadin