CtrlK
BlogDocsLog inGet started
Tessl Logo

tessl/npm-vaadin--vaadin

Comprehensive collection of business-ready web components for modern web applications

Overview
Eval results
Files

data.mddocs/

Data Components

Data components provide high-performance display and manipulation of large datasets. These components support virtualization, sorting, filtering, and advanced interactions for handling complex data scenarios.

Capabilities

Grid

Advanced data grid with comprehensive features for displaying and manipulating tabular data.

/**
 * High-performance data grid component
 * Supports large datasets with virtual scrolling and advanced features
 */
interface Grid extends HTMLElement {
  /** Array of data items to display */
  items: object[];
  /** Array of currently selected items */
  selectedItems: object[];
  /** Currently active (focused) item */
  activeItem: object | null;
  /** Array of items with expanded details */
  detailsOpenedItems: object[];
  /** Enable column reordering */
  columnReorderingAllowed: boolean;
  /** Enable multi-column sorting */
  multiSort: boolean;
  /** Height of each row in pixels */
  itemHeight: number;
  /** Enable all rows selection */
  allRowsSelected: boolean;

  /** Select a specific item */
  selectItem(item: object): void;
  /** Deselect a specific item */
  deselectItem(item: object): void;
  /** Select all visible items */
  selectAll(): void;
  /** Deselect all items */
  deselectAll(): void;
  /** Expand item details */
  expandItem(item: object): void;
  /** Collapse item details */
  collapseItem(item: object): void;
  /** Clear internal data cache */
  clearCache(): void;
  /** Scroll to specific item */
  scrollToIndex(index: number): void;
  /** Recalculate column widths */
  recalculateColumnWidths(): void;
}

/**
 * Grid column definition
 * Defines display and behavior for a data column
 */
interface GridColumn extends HTMLElement {
  /** Property path in data items */
  path: string;
  /** Column header text */
  header: string;
  /** Column width */
  width: string;
  /** Minimum column width */
  minWidth: string;
  /** Maximum column width */
  maxWidth: string;
  /** Column can be resized */
  resizable: boolean;
  /** Column is frozen (always visible) */
  frozen: boolean;
  /** Column is hidden */
  hidden: boolean;
  /** Text alignment */
  textAlign: 'start' | 'center' | 'end';
  /** Custom renderer function */
  renderer: (root: HTMLElement, column: GridColumn, model: GridItemModel) => void;
}

/**
 * Grid item model for renderers
 */
interface GridItemModel {
  index: number;
  item: object;
  selected: boolean;
  expanded: boolean;
  level: number;
}

/**
 * Sortable grid column
 */
interface GridSortColumn extends GridColumn {
  /** Sort direction */
  direction: 'asc' | 'desc' | null;
  /** Sort priority for multi-sort */
  sortPriority: number;
}

/**
 * Selection column for row selection
 */
interface GridSelectionColumn extends GridColumn {
  /** Auto-select rows on click */
  autoSelect: boolean;
  /** Show select all checkbox in header */
  selectAll: boolean;
}

/**
 * Tree column for hierarchical data
 */
interface GridTreeColumn extends GridColumn {
  /** Path to child items property */
  itemHasChildrenPath: string;
  /** Path to expanded state property */
  itemExpandedPath: string;
}

Usage Examples:

import '@vaadin/grid';
import '@vaadin/grid/vaadin-grid-column';
import '@vaadin/grid/vaadin-grid-selection-column';

// Basic grid setup
const grid = document.createElement('vaadin-grid');
grid.items = [
  { name: 'John Doe', email: 'john@example.com', age: 30 },
  { name: 'Jane Smith', email: 'jane@example.com', age: 25 },
  { name: 'Bob Johnson', email: 'bob@example.com', age: 35 }
];

// Add selection column
const selectionColumn = document.createElement('vaadin-grid-selection-column');
selectionColumn.autoSelect = true;
grid.appendChild(selectionColumn);

// Add data columns
const nameColumn = document.createElement('vaadin-grid-column');
nameColumn.path = 'name';
nameColumn.header = 'Name';
nameColumn.width = '200px';
grid.appendChild(nameColumn);

const emailColumn = document.createElement('vaadin-grid-column');
emailColumn.path = 'email';
emailColumn.header = 'Email';
grid.appendChild(emailColumn);

// Custom renderer for actions
const actionColumn = document.createElement('vaadin-grid-column');
actionColumn.header = 'Actions';
actionColumn.renderer = (root, column, model) => {
  if (!root.firstElementChild) {
    const button = document.createElement('vaadin-button');
    button.textContent = 'Edit';
    button.addEventListener('click', () => {
      console.log('Edit user:', model.item);
    });
    root.appendChild(button);
  }
};
grid.appendChild(actionColumn);

// Handle selection changes
grid.addEventListener('active-item-changed', (e) => {
  console.log('Active item:', e.detail.value);
});

Virtual List

High-performance list component with virtual scrolling for large datasets.

/**
 * Virtualized list component for rendering large datasets
 * Only renders visible items for optimal performance
 */
interface VirtualList extends HTMLElement {
  /** Array of data items */
  items: object[];
  /** Custom renderer function for items */
  renderer: (root: HTMLElement, list: VirtualList, index: number, item: object) => void;
  /** Height of each list item */
  itemHeight: number;
  /** Number of items to render outside viewport */
  overscan: number;

  /** Scroll to specific item index */
  scrollToIndex(index: number): void;
  /** Get first visible item index */
  getFirstVisibleIndex(): number;
  /** Get last visible item index */
  getLastVisibleIndex(): number;
}

Usage Examples:

import '@vaadin/virtual-list';

// Large dataset virtual list
const virtualList = document.createElement('vaadin-virtual-list');

// Generate large dataset
const items = Array.from({ length: 100000 }, (_, index) => ({
  id: index,
  name: `Item ${index}`,
  description: `Description for item ${index}`
}));

virtualList.items = items;

// Custom item renderer
virtualList.renderer = (root, list, index, item) => {
  if (!root.firstElementChild) {
    root.innerHTML = `
      <div class="item">
        <div class="name"></div>
        <div class="description"></div>
      </div>
    `;
  }

  const nameEl = root.querySelector('.name');
  const descEl = root.querySelector('.description');

  nameEl.textContent = item.name;
  descEl.textContent = item.description;
};

// Scroll to specific item
setTimeout(() => {
  virtualList.scrollToIndex(50000); // Scroll to middle
}, 1000);

Advanced Data Patterns

Grid with Lazy Loading

// Grid with server-side data loading
const setupLazyGrid = (grid: Grid) => {
  let cachedItems: Map<number, object> = new Map();
  let totalItems = 0;

  // Set up data provider
  grid.dataProvider = (params, callback) => {
    const { page, pageSize, sortOrders, filters } = params;

    // Check cache first
    const cacheKey = `${page}-${pageSize}`;
    if (cachedItems.has(cacheKey)) {
      callback(cachedItems.get(cacheKey), totalItems);
      return;
    }

    // Load from server
    const queryParams = new URLSearchParams({
      page: page.toString(),
      size: pageSize.toString(),
      sort: sortOrders.map(s => `${s.path},${s.direction}`).join(';'),
      filter: JSON.stringify(filters)
    });

    fetch(`/api/data?${queryParams}`)
      .then(response => response.json())
      .then(data => {
        cachedItems.set(cacheKey, data.items);
        totalItems = data.totalCount;
        callback(data.items, data.totalCount);
      })
      .catch(error => {
        console.error('Failed to load data:', error);
        callback([], 0);
      });
  };
};

Grid with Custom Cell Editors

// Grid with inline editing capabilities
const setupEditableGrid = (grid: Grid) => {
  // Add edit column with custom renderer
  const editColumn = document.createElement('vaadin-grid-column');
  editColumn.header = 'Name (Editable)';
  editColumn.renderer = (root, column, model) => {
    if (!root.firstElementChild) {
      const textField = document.createElement('vaadin-text-field');
      textField.style.width = '100%';

      textField.addEventListener('change', (e) => {
        // Update the item
        model.item[column.path] = e.target.value;

        // Trigger update event
        grid.dispatchEvent(new CustomEvent('item-changed', {
          detail: { item: model.item, path: column.path, value: e.target.value }
        }));
      });

      root.appendChild(textField);
    }

    const textField = root.firstElementChild as any;
    textField.value = model.item[column.path] || '';
  };

  grid.appendChild(editColumn);
};

Tree Grid Implementation

// Hierarchical data grid
const setupTreeGrid = () => {
  const grid = document.createElement('vaadin-grid');

  // Hierarchical data
  const treeData = [
    {
      name: 'Frontend',
      children: [
        { name: 'React', size: '2.1MB' },
        { name: 'Vue', size: '1.8MB' },
        { name: 'Angular', size: '4.2MB' }
      ]
    },
    {
      name: 'Backend',
      children: [
        { name: 'Node.js', size: '15MB' },
        { name: 'Python', size: '25MB' }
      ]
    }
  ];

  // Flatten tree data for grid
  const flattenTree = (items: any[], level = 0): any[] => {
    return items.reduce((acc, item) => {
      acc.push({ ...item, level, expanded: false });
      if (item.children) {
        acc.push(...flattenTree(item.children, level + 1));
      }
      return acc;
    }, []);
  };

  grid.items = flattenTree(treeData);

  // Tree column with expand/collapse
  const treeColumn = document.createElement('vaadin-grid-tree-column');
  treeColumn.path = 'name';
  treeColumn.header = 'Name';
  treeColumn.itemHasChildrenPath = 'children';
  grid.appendChild(treeColumn);

  const sizeColumn = document.createElement('vaadin-grid-column');
  sizeColumn.path = 'size';
  sizeColumn.header = 'Size';
  grid.appendChild(sizeColumn);

  return grid;
};

Data Export Functionality

// Export grid data to various formats
const addExportCapability = (grid: Grid) => {
  // Export to CSV
  const exportToCsv = () => {
    const columns = Array.from(grid.querySelectorAll('vaadin-grid-column'));
    const headers = columns.map(col => col.header).join(',');

    const rows = grid.items.map(item =>
      columns.map(col => item[col.path] || '').join(',')
    );

    const csv = [headers, ...rows].join('\n');

    const blob = new Blob([csv], { type: 'text/csv' });
    const url = URL.createObjectURL(blob);

    const a = document.createElement('a');
    a.href = url;
    a.download = 'data.csv';
    a.click();

    URL.revokeObjectURL(url);
  };

  // Export to JSON
  const exportToJson = () => {
    const data = JSON.stringify(grid.items, null, 2);
    const blob = new Blob([data], { type: 'application/json' });
    const url = URL.createObjectURL(blob);

    const a = document.createElement('a');
    a.href = url;
    a.download = 'data.json';
    a.click();

    URL.revokeObjectURL(url);
  };

  // Add export buttons
  const toolbar = document.createElement('div');
  toolbar.className = 'grid-toolbar';

  const csvButton = document.createElement('vaadin-button');
  csvButton.textContent = 'Export CSV';
  csvButton.addEventListener('click', exportToCsv);

  const jsonButton = document.createElement('vaadin-button');
  jsonButton.textContent = 'Export JSON';
  jsonButton.addEventListener('click', exportToJson);

  toolbar.appendChild(csvButton);
  toolbar.appendChild(jsonButton);

  grid.parentElement?.insertBefore(toolbar, grid);
};

Install with Tessl CLI

npx tessl i tessl/npm-vaadin--vaadin

docs

content.md

data.md

datetime.md

dialogs.md

index.md

input.md

layout.md

navigation.md

pro.md

selection.md

tile.json