@tachui/data 0.8.0-alpha

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/README.md ADDED
@@ -0,0 +1,486 @@
1
+ # @tachui/data
2
+
3
+ > Data display and organization components for tachUI framework
4
+
5
+ [![npm version](https://img.shields.io/npm/v/@tachui/data.svg)](https://www.npmjs.com/package/@tachui/data)
6
+ [![License: MPL-2.0](https://img.shields.io/badge/License-MPL--2.0-blue.svg)](https://opensource.org/licenses/MPL-2.0)
7
+
8
+ ## Overview
9
+
10
+ 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.
11
+
12
+ ## Features
13
+
14
+ - 📋 **Advanced Lists** - Virtual scrolling, sectioned data, selection modes, swipe actions
15
+ - 🎯 **Contextual Menus** - Dropdowns, positioning, keyboard navigation, nested submenus
16
+ - âš¡ **Performance Optimized** - Virtual scrolling for large datasets, efficient updates
17
+ - 🎨 **SwiftUI-inspired API** - Familiar component patterns and modifiers
18
+ - 🔧 **TypeScript-first** - Complete type safety with comprehensive interfaces
19
+ - 📱 **Responsive Design** - Adapts to different screen sizes and interaction patterns
20
+
21
+ ## Installation
22
+
23
+ ```bash
24
+ npm install @tachui/core@0.8.0-alpha @tachui/data@0.8.0-alpha
25
+ # or
26
+ pnpm add @tachui/core@0.8.0-alpha @tachui/data@0.8.0-alpha
27
+ ```
28
+
29
+ ## Quick Start
30
+
31
+ ### Basic List
32
+
33
+ ```typescript
34
+ import { VStack, Text } from '@tachui/primitives'
35
+ import { List } from '@tachui/data'
36
+
37
+ const items = [
38
+ { id: 1, name: 'Item 1', category: 'A' },
39
+ { id: 2, name: 'Item 2', category: 'A' },
40
+ { id: 3, name: 'Item 3', category: 'B' },
41
+ ]
42
+
43
+ const app = VStack({
44
+ children: [
45
+ List({
46
+ data: items,
47
+ renderItem: item => Text(item.name),
48
+ })
49
+ .modifier.padding(16)
50
+ .build(),
51
+ ],
52
+ })
53
+ ```
54
+
55
+ ### Sectioned List with Headers
56
+
57
+ ```typescript
58
+ import { List } from '@tachui/data'
59
+
60
+ const sectionedList = List({
61
+ sections: [
62
+ {
63
+ id: 'favorites',
64
+ header: 'Favorites',
65
+ items: favoriteItems,
66
+ },
67
+ {
68
+ id: 'recent',
69
+ header: 'Recent',
70
+ items: recentItems,
71
+ },
72
+ ],
73
+ renderItem: item => Text(item.name),
74
+ renderSectionHeader: section =>
75
+ Text(section.header).modifier.fontWeight('bold'),
76
+ }).build()
77
+ ```
78
+
79
+ ### Contextual Menu
80
+
81
+ ```typescript
82
+ import { Menu } from '@tachui/data'
83
+
84
+ const menuItems = [
85
+ { id: 'edit', title: 'Edit', action: () => console.log('Edit') },
86
+ {
87
+ id: 'duplicate',
88
+ title: 'Duplicate',
89
+ action: () => console.log('Duplicate'),
90
+ },
91
+ {
92
+ id: 'delete',
93
+ title: 'Delete',
94
+ role: 'destructive',
95
+ action: () => console.log('Delete'),
96
+ },
97
+ ]
98
+
99
+ const menu = Menu({
100
+ items: menuItems,
101
+ placement: 'bottom-start',
102
+ }).build()
103
+ ```
104
+
105
+ ## Components
106
+
107
+ ### List Component
108
+
109
+ Advanced list component with virtual scrolling, selection, and swipe actions.
110
+
111
+ #### Basic Usage
112
+
113
+ ```typescript
114
+ import { List } from '@tachui/data'
115
+
116
+ const list = List({
117
+ data: items,
118
+ renderItem: (item, index) => Text(`${index + 1}. ${item.name}`),
119
+ }).build()
120
+ ```
121
+
122
+ #### Virtual Scrolling
123
+
124
+ ```typescript
125
+ const virtualList = List({
126
+ data: largeDataset,
127
+ renderItem: item => Text(item.name),
128
+ virtualScrolling: {
129
+ enabled: true,
130
+ itemHeight: 50, // Fixed height for performance
131
+ overscan: 5, // Extra items to render
132
+ },
133
+ }).build()
134
+ ```
135
+
136
+ #### Sectioned List
137
+
138
+ ```typescript
139
+ const sectionedList = List({
140
+ sections: [
141
+ {
142
+ id: 'group1',
143
+ header: 'Group 1',
144
+ footer: '3 items',
145
+ items: group1Items,
146
+ },
147
+ {
148
+ id: 'group2',
149
+ header: 'Group 2',
150
+ items: group2Items,
151
+ },
152
+ ],
153
+ renderItem: item => Text(item.name),
154
+ renderSectionHeader: section =>
155
+ Text(section.header).modifier.fontWeight('bold'),
156
+ renderSectionFooter: section =>
157
+ section.footer ? Text(section.footer).modifier.fontSize(12) : undefined,
158
+ }).build()
159
+ ```
160
+
161
+ #### Selection Modes
162
+
163
+ ```typescript
164
+ const selectableList = List({
165
+ data: items,
166
+ renderItem: (item, index) => Text(item.name),
167
+ selectionMode: 'multiple', // 'none' | 'single' | 'multiple'
168
+ selectedItems: selectedItemsSignal,
169
+ onSelectionChange: selected => {
170
+ console.log('Selected items:', selected)
171
+ },
172
+ }).build()
173
+ ```
174
+
175
+ #### Swipe Actions
176
+
177
+ ```typescript
178
+ const swipeableList = List({
179
+ data: items,
180
+ renderItem: item => Text(item.name),
181
+ leadingSwipeActions: item => [
182
+ {
183
+ id: 'favorite',
184
+ title: 'Favorite',
185
+ backgroundColor: '#FFD700',
186
+ icon: 'star',
187
+ onTap: () => favoriteItem(item),
188
+ },
189
+ ],
190
+ trailingSwipeActions: item => [
191
+ {
192
+ id: 'delete',
193
+ title: 'Delete',
194
+ backgroundColor: '#FF3B30',
195
+ destructive: true,
196
+ onTap: () => deleteItem(item),
197
+ },
198
+ ],
199
+ }).build()
200
+ ```
201
+
202
+ ### Menu Component
203
+
204
+ Contextual menu component with positioning and keyboard navigation.
205
+
206
+ #### Basic Dropdown Menu
207
+
208
+ ```typescript
209
+ import { Menu } from '@tachui/data'
210
+
211
+ const dropdownMenu = Menu({
212
+ items: [
213
+ { id: 'new', title: 'New Document', action: () => createNew() },
214
+ { id: 'open', title: 'Open...', action: () => openFile() },
215
+ { id: 'separator', title: '' }, // Visual separator
216
+ { id: 'exit', title: 'Exit', action: () => exitApp() },
217
+ ],
218
+ placement: 'bottom-start',
219
+ }).build()
220
+ ```
221
+
222
+ #### Nested Submenus
223
+
224
+ ```typescript
225
+ const nestedMenu = Menu({
226
+ items: [
227
+ {
228
+ id: 'file',
229
+ title: 'File',
230
+ submenu: [
231
+ { id: 'new', title: 'New', action: () => createNew() },
232
+ { id: 'open', title: 'Open', action: () => openFile() },
233
+ { id: 'save', title: 'Save', action: () => saveFile() },
234
+ ],
235
+ },
236
+ {
237
+ id: 'edit',
238
+ title: 'Edit',
239
+ submenu: [
240
+ { id: 'undo', title: 'Undo', action: () => undo() },
241
+ { id: 'redo', title: 'Redo', action: () => redo() },
242
+ ],
243
+ },
244
+ ],
245
+ }).build()
246
+ ```
247
+
248
+ #### Menu with Icons and Shortcuts
249
+
250
+ ```typescript
251
+ const advancedMenu = Menu({
252
+ items: [
253
+ {
254
+ id: 'save',
255
+ title: 'Save',
256
+ systemImage: 'square.and.arrow.down',
257
+ shortcut: '⌘S',
258
+ action: () => save(),
259
+ },
260
+ {
261
+ id: 'export',
262
+ title: 'Export...',
263
+ systemImage: 'arrow.up.doc',
264
+ submenu: [
265
+ { id: 'pdf', title: 'PDF', action: () => exportPDF() },
266
+ { id: 'png', title: 'PNG', action: () => exportPNG() },
267
+ ],
268
+ },
269
+ ],
270
+ placement: 'bottom-end',
271
+ }).build()
272
+ ```
273
+
274
+ ## Advanced Features
275
+
276
+ ### Virtual Scrolling
277
+
278
+ For large datasets, enable virtual scrolling to maintain performance:
279
+
280
+ ```typescript
281
+ const virtualList = List({
282
+ data: largeDataset, // 10,000+ items
283
+ renderItem: item => Text(item.name),
284
+ virtualScrolling: {
285
+ enabled: true,
286
+ itemHeight: 44, // Fixed height for performance
287
+ estimatedItemHeight: 44,
288
+ overscan: 10, // Extra items to render
289
+ threshold: 100, // Distance from viewport to trigger loading
290
+ },
291
+ }).build()
292
+ ```
293
+
294
+ ### Infinite Scrolling
295
+
296
+ Load data progressively as the user scrolls:
297
+
298
+ ```typescript
299
+ const [data, setData] = createSignal(initialData)
300
+ const [hasMore, setHasMore] = createSignal(true)
301
+
302
+ const infiniteList = List({
303
+ data,
304
+ renderItem: item => Text(item.name),
305
+ infiniteScrolling: {
306
+ enabled: true,
307
+ hasMore,
308
+ onLoadMore: async () => {
309
+ const newData = await loadMoreData()
310
+ setData([...data(), ...newData])
311
+ setHasMore(newData.length > 0)
312
+ },
313
+ },
314
+ }).build()
315
+ ```
316
+
317
+ ### Reactive Data
318
+
319
+ Lists automatically update when reactive data changes:
320
+
321
+ ```typescript
322
+ const [items, setItems] = createSignal([
323
+ { id: 1, name: 'Item 1' },
324
+ { id: 2, name: 'Item 2' },
325
+ ])
326
+
327
+ const reactiveList = List({
328
+ data: items, // Signal-based data
329
+ renderItem: item => Text(item.name),
330
+ }).build()
331
+
332
+ // Update data reactively
333
+ setItems([...items(), { id: 3, name: 'Item 3' }])
334
+ ```
335
+
336
+ ### Custom Item IDs
337
+
338
+ For better performance with large datasets:
339
+
340
+ ```typescript
341
+ const listWithIds = List({
342
+ data: items,
343
+ renderItem: item => Text(item.name),
344
+ getItemId: (item, index) => item.id || `item-${index}`,
345
+ }).build()
346
+ ```
347
+
348
+ ## Performance Optimization
349
+
350
+ ### Bundle Size Optimization
351
+
352
+ Import only what you need for smaller bundles:
353
+
354
+ ```typescript
355
+ // Import specific components
356
+ import { List } from '@tachui/data/list'
357
+ import { Menu } from '@tachui/data/menu'
358
+
359
+ // Or import everything
360
+ import { List, Menu } from '@tachui/data'
361
+ ```
362
+
363
+ ### Memory Management
364
+
365
+ The components automatically handle cleanup:
366
+
367
+ - Event listeners are properly removed
368
+ - Reactive effects are disposed
369
+ - Virtual scrolling caches are cleared
370
+ - DOM nodes are efficiently updated
371
+
372
+ ### Rendering Performance
373
+
374
+ - **Virtual scrolling** for large lists
375
+ - **Reactive updates** only re-render changed items
376
+ - **Efficient diffing** for minimal DOM updates
377
+ - **Lazy loading** for images and content
378
+
379
+ ## Accessibility
380
+
381
+ All components include comprehensive accessibility features:
382
+
383
+ - **ARIA labels** and descriptions
384
+ - **Keyboard navigation** support
385
+ - **Screen reader** compatibility
386
+ - **Focus management** for modals and menus
387
+ - **Semantic HTML** structure
388
+
389
+ ## TypeScript Support
390
+
391
+ Full TypeScript support with comprehensive type definitions:
392
+
393
+ ```typescript
394
+ interface CustomItem {
395
+ id: number
396
+ name: string
397
+ category: string
398
+ completed: boolean
399
+ }
400
+
401
+ const typedList = List<CustomItem>({
402
+ data: items,
403
+ renderItem: item => Text(item.name),
404
+ // TypeScript knows item is CustomItem
405
+ }).build()
406
+ ```
407
+
408
+ ## Browser Support
409
+
410
+ - **Modern browsers** (Chrome, Firefox, Safari, Edge)
411
+ - **ES2020+** features supported
412
+ - **CSS Grid** and **Flexbox** required
413
+ - **Intersection Observer** for virtual scrolling
414
+
415
+ ## API Reference
416
+
417
+ ### List Props
418
+
419
+ ```typescript
420
+ interface ListProps<T = any> {
421
+ // Data
422
+ data?: T[] | Signal<T[]>
423
+ sections?: ListSection<T>[] | Signal<ListSection<T>[]>
424
+
425
+ // Rendering
426
+ renderItem: (item: T, index: number) => ComponentInstance
427
+ renderSectionHeader?: (
428
+ section: ListSection<T>,
429
+ index: number
430
+ ) => ComponentInstance
431
+ renderSectionFooter?: (
432
+ section: ListSection<T>,
433
+ index: number
434
+ ) => ComponentInstance
435
+
436
+ // Appearance
437
+ style?: ListStyle
438
+ separator?: boolean | ComponentInstance
439
+
440
+ // Selection
441
+ selectionMode?: SelectionMode
442
+ selectedItems?: Signal<Set<string | number>>
443
+ onSelectionChange?: (selectedItems: Set<string | number>) => void
444
+
445
+ // Item actions
446
+ leadingSwipeActions?: (item: T, index: number) => SwipeAction[]
447
+ trailingSwipeActions?: (item: T, index: number) => SwipeAction[]
448
+ onItemTap?: (item: T, index: number) => void
449
+ onItemLongPress?: (item: T, index: number) => void
450
+
451
+ // Virtual scrolling
452
+ virtualScrolling?: VirtualScrollConfig
453
+
454
+ // Infinite scrolling
455
+ infiniteScrolling?: InfiniteScrollConfig
456
+
457
+ // Performance
458
+ getItemId?: (item: T, index: number) => string | number
459
+
460
+ // Empty state
461
+ emptyState?: ComponentInstance
462
+ }
463
+ ```
464
+
465
+ ### Menu Props
466
+
467
+ ```typescript
468
+ interface MenuProps {
469
+ items: MenuItem[]
470
+ placement?: MenuPlacement
471
+ trigger?: ComponentInstance
472
+ isOpen?: Signal<boolean>
473
+ onOpenChange?: (isOpen: boolean) => void
474
+ keyboardNavigation?: boolean
475
+ closeOnSelect?: boolean
476
+ }
477
+ ```
478
+
479
+ ## Contributing
480
+
481
+ See the main [Contributing Guide](https://github.com/tach-UI/tachUI/blob/main/CONTRIBUTING.md) for information on contributing to tachUI data components.
482
+
483
+ ## License
484
+
485
+ Mozilla Public License 2.0 - see [LICENSE](https://github.com/tach-UI/tachUI/blob/main/LICENSE) for details.</content>
486
+ </xai:function_call: write_file>./tachUI/packages/data/README.md