npm package discovery and stats viewer.

Discover Tips

  • General search

    [free text search, go nuts!]

  • Package details

    pkg:[package-name]

  • User packages

    @[username]

Sponsor

Optimize Toolset

I’ve always been into building performant and accessible sites, but lately I’ve been taking it extremely seriously. So much so that I’ve been building a tool to help me optimize and monitor the sites that I build to make sure that I’m making an attempt to offer the best experience to those who visit them. If you’re into performant, accessible and SEO friendly sites, you might like it too! You can check it out at Optimize Toolset.

About

Hi, 👋, I’m Ryan Hefner  and I built this site for me, and you! The goal of this site was to provide an easy way for me to check the stats on my npm packages, both for prioritizing issues and updates, and to give me a little kick in the pants to keep up on stuff.

As I was building it, I realized that I was actually using the tool to build the tool, and figured I might as well put this out there and hopefully others will find it to be a fast and useful way to search and browse npm packages as I have.

If you’re interested in other things I’m working on, follow me on Twitter or check out the open source projects I’ve been publishing on GitHub.

I am also working on a Twitter bot for this site to tweet the most popular, newest, random packages from npm. Please follow that account now and it will start sending out packages soon–ish.

Open Software & Tools

This site wouldn’t be possible without the immense generosity and tireless efforts from the people who make contributions to the world and share their work via open source initiatives. Thank you 🙏

© 2025 – Pkg Stats / Ryan Hefner

@tachui/data

v0.8.1-alpha

Published

Data display and organization components for tachUI framework

Downloads

6

Readme

@tachui/data

Data display and organization components for tachUI framework

npm version License: MPL-2.0

Overview

The tachUI data package provides essential components for displaying and organizing data including lists and menus with advanced features like virtual scrolling, contextual menus, and flexible content organization.

Features

  • 📋 Advanced Lists - Virtual scrolling, sectioned data, selection modes, swipe actions
  • 🎯 Contextual Menus - Dropdowns, positioning, keyboard navigation, nested submenus
  • Performance Optimized - Virtual scrolling for large datasets, efficient updates
  • 🎨 SwiftUI-inspired API - Familiar component patterns and modifiers
  • 🔧 TypeScript-first - Complete type safety with comprehensive interfaces
  • 📱 Responsive Design - Adapts to different screen sizes and interaction patterns

Installation

npm install @tachui/[email protected] @tachui/[email protected]
# or
pnpm add @tachui/[email protected] @tachui/[email protected]

Quick Start

Basic List

import { VStack, Text } from '@tachui/primitives'
import { List } from '@tachui/data'

const items = [
  { id: 1, name: 'Item 1', category: 'A' },
  { id: 2, name: 'Item 2', category: 'A' },
  { id: 3, name: 'Item 3', category: 'B' },
]

const app = VStack({
  children: [
    List({
      data: items,
      renderItem: item => Text(item.name),
    })
      .modifier.padding(16)
      .build(),
  ],
})

Sectioned List with Headers

import { List } from '@tachui/data'

const sectionedList = List({
  sections: [
    {
      id: 'favorites',
      header: 'Favorites',
      items: favoriteItems,
    },
    {
      id: 'recent',
      header: 'Recent',
      items: recentItems,
    },
  ],
  renderItem: item => Text(item.name),
  renderSectionHeader: section =>
    Text(section.header).modifier.fontWeight('bold'),
}).build()

Contextual Menu

import { Menu } from '@tachui/data'

const menuItems = [
  { id: 'edit', title: 'Edit', action: () => console.log('Edit') },
  {
    id: 'duplicate',
    title: 'Duplicate',
    action: () => console.log('Duplicate'),
  },
  {
    id: 'delete',
    title: 'Delete',
    role: 'destructive',
    action: () => console.log('Delete'),
  },
]

const menu = Menu({
  items: menuItems,
  placement: 'bottom-start',
}).build()

Components

List Component

Advanced list component with virtual scrolling, selection, and swipe actions.

Basic Usage

import { List } from '@tachui/data'

const list = List({
  data: items,
  renderItem: (item, index) => Text(`${index + 1}. ${item.name}`),
}).build()

Virtual Scrolling

const virtualList = List({
  data: largeDataset,
  renderItem: item => Text(item.name),
  virtualScrolling: {
    enabled: true,
    itemHeight: 50, // Fixed height for performance
    overscan: 5, // Extra items to render
  },
}).build()

Sectioned List

const sectionedList = List({
  sections: [
    {
      id: 'group1',
      header: 'Group 1',
      footer: '3 items',
      items: group1Items,
    },
    {
      id: 'group2',
      header: 'Group 2',
      items: group2Items,
    },
  ],
  renderItem: item => Text(item.name),
  renderSectionHeader: section =>
    Text(section.header).modifier.fontWeight('bold'),
  renderSectionFooter: section =>
    section.footer ? Text(section.footer).modifier.fontSize(12) : undefined,
}).build()

Selection Modes

const selectableList = List({
  data: items,
  renderItem: (item, index) => Text(item.name),
  selectionMode: 'multiple', // 'none' | 'single' | 'multiple'
  selectedItems: selectedItemsSignal,
  onSelectionChange: selected => {
    console.log('Selected items:', selected)
  },
}).build()

Swipe Actions

const swipeableList = List({
  data: items,
  renderItem: item => Text(item.name),
  leadingSwipeActions: item => [
    {
      id: 'favorite',
      title: 'Favorite',
      backgroundColor: '#FFD700',
      icon: 'star',
      onTap: () => favoriteItem(item),
    },
  ],
  trailingSwipeActions: item => [
    {
      id: 'delete',
      title: 'Delete',
      backgroundColor: '#FF3B30',
      destructive: true,
      onTap: () => deleteItem(item),
    },
  ],
}).build()

Menu Component

Contextual menu component with positioning and keyboard navigation.

Basic Dropdown Menu

import { Menu } from '@tachui/data'

const dropdownMenu = Menu({
  items: [
    { id: 'new', title: 'New Document', action: () => createNew() },
    { id: 'open', title: 'Open...', action: () => openFile() },
    { id: 'separator', title: '' }, // Visual separator
    { id: 'exit', title: 'Exit', action: () => exitApp() },
  ],
  placement: 'bottom-start',
}).build()

Nested Submenus

const nestedMenu = Menu({
  items: [
    {
      id: 'file',
      title: 'File',
      submenu: [
        { id: 'new', title: 'New', action: () => createNew() },
        { id: 'open', title: 'Open', action: () => openFile() },
        { id: 'save', title: 'Save', action: () => saveFile() },
      ],
    },
    {
      id: 'edit',
      title: 'Edit',
      submenu: [
        { id: 'undo', title: 'Undo', action: () => undo() },
        { id: 'redo', title: 'Redo', action: () => redo() },
      ],
    },
  ],
}).build()

Menu with Icons and Shortcuts

const advancedMenu = Menu({
  items: [
    {
      id: 'save',
      title: 'Save',
      systemImage: 'square.and.arrow.down',
      shortcut: '⌘S',
      action: () => save(),
    },
    {
      id: 'export',
      title: 'Export...',
      systemImage: 'arrow.up.doc',
      submenu: [
        { id: 'pdf', title: 'PDF', action: () => exportPDF() },
        { id: 'png', title: 'PNG', action: () => exportPNG() },
      ],
    },
  ],
  placement: 'bottom-end',
}).build()

Advanced Features

Virtual Scrolling

For large datasets, enable virtual scrolling to maintain performance:

const virtualList = List({
  data: largeDataset, // 10,000+ items
  renderItem: item => Text(item.name),
  virtualScrolling: {
    enabled: true,
    itemHeight: 44, // Fixed height for performance
    estimatedItemHeight: 44,
    overscan: 10, // Extra items to render
    threshold: 100, // Distance from viewport to trigger loading
  },
}).build()

Infinite Scrolling

Load data progressively as the user scrolls:

const [data, setData] = createSignal(initialData)
const [hasMore, setHasMore] = createSignal(true)

const infiniteList = List({
  data,
  renderItem: item => Text(item.name),
  infiniteScrolling: {
    enabled: true,
    hasMore,
    onLoadMore: async () => {
      const newData = await loadMoreData()
      setData([...data(), ...newData])
      setHasMore(newData.length > 0)
    },
  },
}).build()

Reactive Data

Lists automatically update when reactive data changes:

const [items, setItems] = createSignal([
  { id: 1, name: 'Item 1' },
  { id: 2, name: 'Item 2' },
])

const reactiveList = List({
  data: items, // Signal-based data
  renderItem: item => Text(item.name),
}).build()

// Update data reactively
setItems([...items(), { id: 3, name: 'Item 3' }])

Custom Item IDs

For better performance with large datasets:

const listWithIds = List({
  data: items,
  renderItem: item => Text(item.name),
  getItemId: (item, index) => item.id || `item-${index}`,
}).build()

Performance Optimization

Bundle Size Optimization

Import only what you need for smaller bundles:

// Import specific components
import { List } from '@tachui/data/list'
import { Menu } from '@tachui/data/menu'

// Or import everything
import { List, Menu } from '@tachui/data'

Memory Management

The components automatically handle cleanup:

  • Event listeners are properly removed
  • Reactive effects are disposed
  • Virtual scrolling caches are cleared
  • DOM nodes are efficiently updated

Rendering Performance

  • Virtual scrolling for large lists
  • Reactive updates only re-render changed items
  • Efficient diffing for minimal DOM updates
  • Lazy loading for images and content

Accessibility

All components include comprehensive accessibility features:

  • ARIA labels and descriptions
  • Keyboard navigation support
  • Screen reader compatibility
  • Focus management for modals and menus
  • Semantic HTML structure

TypeScript Support

Full TypeScript support with comprehensive type definitions:

interface CustomItem {
  id: number
  name: string
  category: string
  completed: boolean
}

const typedList = List<CustomItem>({
  data: items,
  renderItem: item => Text(item.name),
  // TypeScript knows item is CustomItem
}).build()

Browser Support

  • Modern browsers (Chrome, Firefox, Safari, Edge)
  • ES2020+ features supported
  • CSS Grid and Flexbox required
  • Intersection Observer for virtual scrolling

API Reference

List Props

interface ListProps<T = any> {
  // Data
  data?: T[] | Signal<T[]>
  sections?: ListSection<T>[] | Signal<ListSection<T>[]>

  // Rendering
  renderItem: (item: T, index: number) => ComponentInstance
  renderSectionHeader?: (
    section: ListSection<T>,
    index: number
  ) => ComponentInstance
  renderSectionFooter?: (
    section: ListSection<T>,
    index: number
  ) => ComponentInstance

  // Appearance
  style?: ListStyle
  separator?: boolean | ComponentInstance

  // Selection
  selectionMode?: SelectionMode
  selectedItems?: Signal<Set<string | number>>
  onSelectionChange?: (selectedItems: Set<string | number>) => void

  // Item actions
  leadingSwipeActions?: (item: T, index: number) => SwipeAction[]
  trailingSwipeActions?: (item: T, index: number) => SwipeAction[]
  onItemTap?: (item: T, index: number) => void
  onItemLongPress?: (item: T, index: number) => void

  // Virtual scrolling
  virtualScrolling?: VirtualScrollConfig

  // Infinite scrolling
  infiniteScrolling?: InfiniteScrollConfig

  // Performance
  getItemId?: (item: T, index: number) => string | number

  // Empty state
  emptyState?: ComponentInstance
}

Menu Props

interface MenuProps {
  items: MenuItem[]
  placement?: MenuPlacement
  trigger?: ComponentInstance
  isOpen?: Signal<boolean>
  onOpenChange?: (isOpen: boolean) => void
  keyboardNavigation?: boolean
  closeOnSelect?: boolean
}

Contributing

See the main Contributing Guide for information on contributing to tachUI data components.

License

Mozilla Public License 2.0 - see LICENSE for details. </xai:function_call: write_file>./tachUI/packages/data/README.md